From 786bf7fdaca4c75e7eba6e9aa3a8b5775fd21186 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Mon, 21 Mar 2022 01:16:48 +0000 Subject: kernel: delete Linux 5.4 config and patches As the upcoming release will be based on Linux 5.10 only, remove all kernel configuration as well as patches for Linux 5.4. There were no targets still actively using Linux 5.4. Signed-off-by: Daniel Golle (cherry picked from commit 3a14580411adfb75f9a44eded9f41245b9e44606) --- target/linux/layerscape/armv7/config-5.4 | 673 - target/linux/layerscape/armv8_64b/config-5.4 | 881 - ...rm-kernel-utilize-hrtimer-based-broadcast.patch | 33 - ...upport-to-remap-kernel-cacheable-memory-t.patch | 25 - ...le-add-support-to-map-cacheable-and-non-s.patch | 22 - ...oremap-for-normal-cacheable-non-shareable.patch | 33 - ...d-ARM-specific-fucntions-required-for-ehc.patch | 79 - .../301-arch-0006-export-arch_setup_dma_ops.patch | 17 - ...arm-dma-mapping-export-arch_setup_dma_ops.patch | 23 - ...ch-0008-arm-add-new-non-shareable-ioremap.patch | 95 - ...gprot_cached-and-pgprot_cached_ns-support.patch | 26 - ...tage-2-cache-able-non-shareable-page-type.patch | 20 - ...rch-0011-drivers-soc-fsl-add-qixis-driver.patch | 152 - ...-soc-fsl-select-MFD_CORE-for-qixis-driver.patch | 22 - ...ts-add-update-DPAA1-include-files-for-SDK.patch | 550 - ...-arm64-dts-add-DPAA1-SDK-flavor-dts-files.patch | 626 - ...-ls1012a-Add-LS1012A-2G5RDB-board-support.patch | 114 - ...s1012a-Add-more-nodes-to-LS1012A-FRWY-boa.patch | 149 - ...s2081ardb-Add-DTS-support-for-NXP-LS2081A.patch | 164 - ...s1012a-accumulated-change-for-ls1012a-boa.patch | 461 - ...s1043a-accumulated-change-for-ls1043a-boa.patch | 574 - ...s1046a-accumulated-change-to-ls1046a-boar.patch | 366 - ...s1088a-accumulated-change-to-ls1088a-boar.patch | 540 - ...s208xa-accumulated-change-to-ls208xa-boar.patch | 959 - .../302-dts-0011-ARM-dts-accumulated-change.patch | 156 - ...-dts-0012-arm64-dts-ls1046a-add-smmu-node.patch | 63 - ...-dts-0013-arm64-dts-ls1043a-add-smmu-node.patch | 63 - ...s104xa-set-mask-to-drop-TBU-ID-from-Strea.patch | 38 - ...ts-ls104x-add-missing-dma-ranges-property.patch | 35 - ...s-ls104x-add-iommu-map-to-pci-controllers.patch | 67 - ...s104x-make-dma-coherent-global-to-the-SoC.patch | 67 - ...s104x-use-a-pseudo-bus-to-constrain-usb-d.patch | 193 - ...s104x-drop-smmu-from-the-sdk-device-trees.patch | 60 - ...64-dts-lx2160a-add-MDIO-device-tree-nodes.patch | 41 - ...x2160a-rdb-Add-RGMII-PHY-nodes-for-dpmac-.patch | 44 - ...64-dts-lx2160a-correct-scl-gpios-property.patch | 30 - ...-dts-lx2160a-add-dspi-controller-DT-nodes.patch | 62 - ...x2160a-add-DT-node-for-all-DSPI-controlle.patch | 59 - ...nxp-ls208xa-add-more-thermal-zone-support.patch | 745 - ...m64-dts-nxp-add-more-thermal-zone-support.patch | 314 - ...-arm64-dts-lx2160a-rdb-Add-Inphi-PHY-node.patch | 40 - ...64-dts-lx2160a-rdb-Add-Aquantia-PHY-nodes.patch | 51 - ...x2160-Add-all-pcs-mdio-definitions-accord.patch | 107 - ...x2160-PCS-PHY-definitions-for-10GBase-KR-.patch | 57 - ...x2160-DPMAC-connections-to-backplane-PHYs.patch | 39 - ...dded-endianness-information-to-dts-serdes.patch | 53 - ...4-dts-freescale-lx2160a-add-pcie-DT-nodes.patch | 183 - ...reescale-lx2160a-Inphi-in112525_s03-mdio-.patch | 29 - ...-0035-arm64-dts-lx2160a-add-optee-tz-node.patch | 24 - ...ts-ls104x-constrain-sata-dma-address-size.patch | 86 - ...m64-dts-lx2160a-qds-add-sata-node-support.patch | 37 - ...s1012a-use-phy-handle-to-handle-phy-param.patch | 242 - ...64-dts-ls1012a-remove-unused-gemac-bus-id.patch | 98 - ...rm64-dts-ls1012a-reorganize-pfe_mac-nodes.patch | 132 - ...04x-drop-smmu-from-the-qds-and-usdpaa-sdk.patch | 109 - ...4-dts-fix-the-LS104x-QDS-mdio-mux-support.patch | 42 - ...3-arm64-dts-lx2160aqds-Add-mdio-mux-nodes.patch | 247 - ...ts-reduce-usdpaa-memory-to-4K-for-LS1046-.patch | 56 - ...ix-DWC3-IP-VBUS-glitch-issue-on-Layerscap.patch | 134 - ...-Fix-DWC3-IP-VBUS-glitch-issue-on-LS1021A.patch | 20 - ...RM-dts-ls1021aqds-enable-esdhc-controller.patch | 25 - ...reescale-lx2160a-add-pcie-EP-mode-DT-node.patch | 112 - ...04x-move-dma-coherent-from-soc-to-its-chi.patch | 879 - ...x2160a-add-interrupt-property-for-aquanti.patch | 32 - ...sl-layerscape-fix-warnings-when-compiling.patch | 292 - ...sl-layerscape-fix-warnings-when-compiling.patch | 114 - ...64-dts-nxp-add-DPAA1-SDK-flavor-dts-files.patch | 187 - ...xp-frwy-ls1046a-add-support-for-micron-no.patch | 40 - ...-dts-ls1028a-Add-PCIe-controller-DT-nodes.patch | 71 - ...x2160a-Enable-usb3-lpm-capable-for-usb3-n.patch | 34 - ...57-arm64-dts-fsl-lx2160a-add-flexcan-node.patch | 103 - ...58-arm64-dts-fsl-ls1028a-add-flexcan-node.patch | 87 - ...sl-ls1046-Modify-the-qspi-flash-frequency.patch | 55 - ...-0060-arm64-dts-ls1028a-add-flexspi-nodes.patch | 87 - ...-ls1046-drop-smmu-from-the-frwy-sdk-dtses.patch | 61 - ...046frwy-move-dma-coherent-from-soc-to-its.patch | 235 - ...63-arm64-dts-fsl-remove-backplane-support.patch | 574 - ...x2160a-update-interrupt-property-for-Aqua.patch | 31 - ...64-dts-ls1028a-Update-fspi-reg-properties.patch | 21 - ...2-dts-0066-arm64-dts-ls1028a-add-gpu-node.patch | 31 - ...7-arm64-dts-fsl-add-optee-node-for-ls1028.patch | 29 - ...lx2160a-Update-phy-mode-for-Aquantia-PHYs.patch | 30 - ...-arm64-dts-ls1028a-Add-ftm_alarm0-DT-node.patch | 46 - ...s1012a-ls1043a-ls1046a-ls1088a-ls208xa-re.patch | 297 - ...021a-replace-ftm0-with-ftm_alarm0-DT-node.patch | 63 - ...8ardb-Add-support-DP-nodes-for-LS1028ARDB.patch | 31 - ...8aqds-Add-support-DP-nodes-for-LS1028AQDS.patch | 31 - ...fsl-ls1028a-Add-Felix-switch-port-DT-node.patch | 102 - ...dts-fsl-ls1028a-Enable-switch-PHYs-on-RDB.patch | 62 - ...-ls1028a-support-Felix-PF5-INTB-interrupt.patch | 34 - ...s1028a-Add-ethernet-property-for-l2switch.patch | 33 - ...dts-0078-arm64-dts-fix-endianness-of-rcpm.patch | 44 - ...s1028a-Fix-interrupt-map-property-of-PCIe.patch | 45 - ...64-dts-ls1028a-rdb-enable-emmc-hs400-mode.patch | 23 - ...-arm64-dts-lx2160a-add-ftm_alarm0-DT-node.patch | 47 - ...082-arm64-dts-lx2160a-add-tmu-device-node.patch | 293 - ...ls1028a-define-networking-options-for-QDS.patch | 355 - ...able-otg-mode-for-dwc3-usb-ip-on-layersca.patch | 53 - ...021a-fix-that-FlexTimer-cannot-wakeup-sys.patch | 29 - ...8-arm64-dts-ls1028a-fix-dwc-pci-over-smmu.patch | 34 - ...s1028a-Update-the-clock-providers-for-the.patch | 55 - ...-ls1028a-Update-clock-cells-of-dpclk-node.patch | 35 - ...s1028a-Add-properties-for-HD-Display-cont.patch | 43 - ...ts-0092-arm64-dts-ls1028a-Add-DP-DT-nodes.patch | 49 - ...64-dts-fsl-Specify-phy-mode-for-CPU-ports.patch | 35 - ...sl-Drop-compatible-string-from-Felix-swit.patch | 24 - ...sl-ls1028a-Specify-that-the-Felix-port-4-.patch | 33 - ...sl-ls1028a-Disable-eno3-and-make-swp5-the.patch | 63 - ...m64-dts-layerscape-add-chip-specific-comp.patch | 150 - ...4-dts-fsl-Add-clock-names-mclk0-for-SAI-n.patch | 105 - ...ayerscape-apply-dma-coherent-for-dwc3-nod.patch | 150 - ...s208xa-Update-qspi-node-properties-for-LS.patch | 64 - ...s208xa-Remove-dma-coherent-from-dwc3-node.patch | 36 - ...64-dts-ls1012ardb-Update-qspi-node-dts-pr.patch | 60 - ...s1028a-Update-edma-compatible-to-fit-eDMA.patch | 25 - ...x2160a-add-iommu-map-property-to-pci-node.patch | 65 - ...64-dts-ls1088ardb-Update-qspi-dts-node-pr.patch | 67 - ...64-dts-ls1046ardb-Update-qspi-node-dts-pr.patch | 52 - ...-dts-ls1012ardb-Update-qspi-node-property.patch | 43 - ...s1028a-rdb-Enable-SGMII-AN-for-the-QSGMII.patch | 46 - ...arm64-dts-ls1028a-Disable-swp5-by-default.patch | 22 - ...fsl-ls1028a-rdb-fix-QSGMII-PHY-node-names.patch | 38 - ...4-dts-fsl-ls1028a-prepare-dts-for-overlay.patch | 452 - ...sl-ls1028a-qds-Add-overlays-for-various-s.patch | 893 - ...sl-ls1028a-add-labels-to-Ethernet-switch-.patch | 41 - ...m64-dts-add-overlay-support-for-ls1028a-q.patch | 36 - ...-LF-881-arm64-dts-add-a-dts-file-for-dpdk.patch | 119 - ...dts-ls1021a-Add-LS1021A-IOT-board-support.patch | 291 - ...s-0118-add-DTS-for-Traverse-LS1043-Boards.patch | 96 - ...dts-lx2160a-add-more-thermal-zone-support.patch | 184 - ...-ls1046a-fix-ippdexpcr-offset-not-correct.patch | 25 - ...s1043a-update-USB-nodes-status-to-match-b.patch | 78 - ...ts-ls1043a-remove-thermal-zone-5-from-dts.patch | 24 - ...-dts-ls1043a-rdb-add-compatible-for-board.patch | 23 - .../303-core-0001-net-readd-skb_recycle.patch | 59 - ...e-add-sysfs-entries-for-suppliers-and-con.patch | 99 - ...a-symlink-too-be-created-with-a-cftype-fi.patch | 112 - ...roup-bfq-revert-bfq.weight-symlink-change.patch | 114 - ...nd-raw-workaround-for-EDO-high-speed-mode.patch | 25 - ...core-0006-mm-Re-export-ioremap_page_range.patch | 21 - ...ved_mem-Ensure-cma-reserved-region-not-cr.patch | 85 - ...0-ubi-attach-do-not-return-EINVAL-if-the-.patch | 46 - ...elfcorehdr-reservation-early-for-crash-du.patch | 34 - ...efile-Enable-creation-of-_symbols_-DT-nod.patch | 28 - ...4-crash_core-Export-TCR_EL1.T1SZ-in-vmcor.patch | 97 - ...vert-scripts-Makefile-Enable-creation-of-.patch | 58 - ...fsl-qman-fixup-liodns-only-on-ppc-targets.patch | 32 - ...2-soc-fsl-bman-map-FBPR-area-in-the-iommu.patch | 47 - ...-qman-map-FQD-and-PFDR-areas-in-the-iommu.patch | 52 - ...sl-qman-portal-map-CENA-area-in-the-iommu.patch | 54 - ...an_portals-add-APIs-to-retrieve-the-probi.patch | 71 - ...-fsl-bqman-page-align-iommu-mapping-sizes.patch | 58 - ...0007-fsl_qbman-SDK-DPAA-1.x-QBMan-drivers.patch | 24880 ---- ...701-net-0008-fmd-SDK-DPAA-1.x-FMan-driver.patch | 116456 ------------------ ...net-0009-dpa-SDK-DPAA-1.x-Ethernet-driver.patch | 12966 -- ...1043a-errata-check-if-the-skb-is-linear-a.patch | 31 - ..._eth-ceetm-adapt-to-net-sched-API-changes.patch | 24 - ...eth-ceetm-adapt-to-the-new-gnet-stats-API.patch | 22 - ...ceetm-update-include-paths-for-tc-filters.patch | 22 - .../701-net-0014-dpa_eth-remove-unused-code.patch | 87 - ...-fmd-use-ptp-timer-for-Fman-RTC-node-name.patch | 28 - ...e-ptp-timer-phandle-instead-of-ptimer-han.patch | 34 - ...ve-global-variable-clock-into-ptp_priv_s-.patch | 52 - ...aa-use-new-api-ethtool_ksettings_-get-set.patch | 65 - ...1-net-0019-sdk_dpaa-fix-dpa_set_ksettings.patch | 21 - ...mac-set-adjust_link-callback-for-fixed-li.patch | 28 - ...ls1043a-errata-resplit-the-skb-after-copy.patch | 31 - ...1043a-errata-realign-and-linearize-egress.patch | 205 - ...1043a-errata-realign-skb-in-place-if-need.patch | 34 - ...1043a-errata-verify-and-resize-headroom-a.patch | 106 - ...1043a-errata-do-not-recycle-the-realigned.patch | 61 - ...6-sdk_dpaa-ls1043a-errata-fix-arm32-build.patch | 39 - ...ging-fsl_qbman-Fix-SWP-Mask-in-Error-Hand.patch | 25 - ...1-net-0028-sdk_dpaa-avoid-crashing-on-OOM.patch | 27 - ...date-the-xmit-timestamp-to-avoid-watchdog.patch | 75 - ...solve-arm32-compilation-issues-for-linux-.patch | 81 - ...aa-ls1043a-errata-maintain-timestamp-info.patch | 101 - ..._dpaa-ls1043a-errata-restrict-the-max-mtu.patch | 33 - ...dpaa-adapt-to-the-new-API-for-MTU-changes.patch | 86 - ...AC-Statistics-with-frame-size-counters-re.patch | 406 - ...cept-frames-on-RX-even-if-larger-than-MTU.patch | 64 - ...36-sdk-dpa-use-netdev-dev-for-DMA-mapping.patch | 121 - ...7-Added-MII-IOCTL-support-for-SIOCGMIIREG.patch | 35 - ...1043a-errata-stop-advertising-S-G-and-GSO.patch | 52 - ...-fsl_qbman-Calculate-valid-bit-from-MC-RR.patch | 47 - ...sdpaa-Invalidate-software-portals-before-.patch | 64 - ...rnet-Rename-PHY_INTERFACE_MODE_SGMII_2500.patch | 34 - ...etm-add-independent-CEETM-congestion-thre.patch | 61 - ...etm-stop-transmitting-frames-when-the-CQ-.patch | 100 - ...etm-coding-style-fixes-and-added-comments.patch | 91 - ...etm-increment-the-interface-s-ern-counter.patch | 21 - ...k_dpaa-update-buffer-recycling-conditions.patch | 31 - ...date-comments-about-recycling-and-back-po.patch | 67 - ...etm-pass-extended-ACK-struct-to-parsing-f.patch | 40 - ..._dpaa-ceetm-adapt-to-new-tcf-classify-API.patch | 21 - ...paa-ceetm-introduce-a-TRAP-control-action.patch | 20 - ...aa-ceetm-use-the-tcf-block-infrastructure.patch | 126 - ...-ceetm-remove-tc-class-reference-counting.patch | 106 - ...ceetm-store-Qdisc-pointer-in-struct-block.patch | 30 - ...et-0054-dpaa_eth-workaround-for-ERR010022.patch | 299 - ...AA-dTSEC-ports-fail-to-work-when-link-cha.patch | 131 - ...pt-compatibles-to-upstream-binding-docume.patch | 25 - ...dk_fman-fix-probing-of-10G-ports-on-T102x.patch | 87 - ...1-net-0058-sdk_fman-probe-OH-ports-on-PPC.patch | 38 - ...-P-series-platforms-the-OH-ports-start-at.patch | 33 - .../701-net-0060-sdk_fman-disable-timer-code.patch | 32 - ...1-sdk_fman-disable-timer-code-in-arm-code.patch | 32 - ...dk_dpa-adapt-ceetm-code-to-new-kernel-API.patch | 108 - ...a-propagate-the-skb-ownership-information.patch | 33 - ...phy-RGMII-fixed-link-pass-adjust_link-cal.patch | 85 - ...dpaa-ceetm-avoid-use-after-free-scenarios.patch | 67 - ...etm-stop-the-netdev-queues-when-switching.patch | 23 - ...ceetm-export-the-qman_ceetm_query_cq-call.patch | 31 - ...etm-propagate-the-ceetm-channel-through-t.patch | 298 - ...etm-reset-the-wbfs-groups-and-priorities-.patch | 24 - ...aa-ceetm-WQ-CEETM-mode-switchover-cleanup.patch | 54 - ...dpaa-ceetm-drain-the-ceetm-CQs-on-destroy.patch | 116 - ...-ls1043a-errata-adapt-to-new-skb-copy-API.patch | 21 - ...a_eth-ERR010022-adapt-to-new-skb-copy-API.patch | 21 - ...paa-enable-Jumbo-frame-support-on-LS1043A.patch | 154 - ..._dpaa-reserve-256-bytes-for-the-SGT-on-TX.patch | 57 - ...sdpaa-change-to-debug-print-in-interrupt-.patch | 21 - ..._qbman-Consume-all-frames-in-DQRR-during-.patch | 23 - ..._qbman-Recalcuate-cursor-after-consuming-.patch | 26 - ...l-fman-ptp-timer-compatible-for-ptp-probe.patch | 38 - ...ore-the-skb-backpointer-in-the-skb-headro.patch | 84 - ...-sdk_dpaa-ls1043a-errata-align-skb_shinfo.patch | 27 - ...0082-sdk_dpaa-ls1043a-errata-move-comment.patch | 35 - ...etm-lower-the-default-congestion-threshol.patch | 39 - ...4-staging-fsl_qbman-remove-bootmem-header.patch | 25 - ...-fsl_qbman-stop-using-current_kernel_time.patch | 40 - ...a-ceetm-avoid-double-frees-on-error-paths.patch | 334 - ...a-ceetm-rename-qdisc_destroy-to-qdisc_put.patch | 48 - ...-remove-FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE.patch | 127 - ...sl-fman-backup-and-restore-ICID-registers.patch | 116 - ...d-API-to-get-the-device-behind-a-fman-por.patch | 48 - ...t-0091-dpaa_eth-defer-probing-after-qbman.patch | 57 - ...eth-base-dma-mappings-on-the-fman-rx-port.patch | 60 - ...h-fix-iova-handling-for-contiguous-frames.patch | 129 - ...-dpaa_eth-fix-iova-handling-for-sg-frames.patch | 126 - ...etm-guard-against-an-out-of-bounds-queue-.patch | 34 - ...uard-against-an-out-of-bounds-queue-index.patch | 34 - ...aa-set-the-skb-queue-mapping-when-looping.patch | 26 - ...net-0098-sdk_dpaa-remove-ptp-clock-driver.patch | 392 - ...uspend-the-FMan-to-Deep-Sleep-on-PPC-only.patch | 56 - ...net-0100-sdk_fman-disable-ptp-timer-probe.patch | 36 - ...add-the-get_ts_info-interface-for-ethtool.patch | 79 - ...t-0102-sdk_fman-share-the-event-interrupt.patch | 24 - ...103-sdk_dpaa-fix-hardware-timestamp-value.patch | 37 - ...dpaa-remove-useless-1588-timer-enablement.patch | 33 - ...k-qbman-fix-issue-in-qman_delete_cgr_safe.patch | 60 - ...oid-array-overflow-error-in-fman-port-ini.patch | 26 - ...djust-platform-device-creation-for-QMan-p.patch | 103 - ...1043a-errata-impose-S-G-frame-realignment.patch | 81 - ...a-remove-the-QM_FQCTRL_PREFERINCACHE-flag.patch | 24 - ...t-0110-sdk_dpaa-adapt-to-kernel-5.1.0-rc1.patch | 165 - ...man-Avoid-variable-length-array-in-USDPAA.patch | 100 - ...112-sdk_dpaa-Rework-QBMan-portal-mappings.patch | 65 - ...qbman-Fix-error-in-IP-revision-comparison.patch | 28 - ...114-sdk_dpaa-SGMII-2500-needs-AN-disabled.patch | 58 - ...pdate-cpus_allowed-to-cpus_mask-to-cope-w.patch | 39 - ..._dpaa-ceetm-align-to-upstream-API-changes.patch | 61 - ...-0117-dpaa_eth-ERR010022-align-skb_shinfo.patch | 23 - ...-dpaa_eth-ERR010022-preserve-timestamping.patch | 31 - ...etm-update-Makefile-to-use-absolute-inclu.patch | 25 - ...dpaa-net-Rename-skb_frag_t-size-to-bv_len.patch | 38 - ...dpaa_eth-Rename-skb_frag_t-size-to-bv_len.patch | 21 - ...01-net-0122-config-enable-SDK-FMan-driver.patch | 20 - ...01-net-0123-config-enable-SDK-DPAA-driver.patch | 21 - .../701-net-0124-config-enable-SDK-QBMan.patch | 21 - .../701-net-0125-config-add-SDK-QBMan-driver.patch | 19 - ...0126-net-Makefile-re-add-DPAA-SDK-drivers.patch | 22 - ...t-0127-ptp-support-ptp_qoriq-for-sdk-dpaa.patch | 25 - ...x-build-failure-due-to-skb_frag_t-struct-.patch | 40 - ..._dpa-align-to-upstream-PHY_INTERFACE_MODE.patch | 30 - ...move-fsl_mc_command-struct-in-a-uapi-head.patch | 86 - ...1-bus-fsl-mc-add-fsl-mc-userspace-support.patch | 371 - ...bus-fsl-mc-add-root-dprc-rescan-attribute.patch | 100 - ...-0133-bus-fsl-mc-add-bus-rescan-attribute.patch | 115 - ...s-fsl-mc-Add-dprc-reset-container-support.patch | 99 - ...Propagate-driver_override-for-a-child-DPR.patch | 196 - ...c-add-device-binding-path-driver_override.patch | 106 - ...move-fsl_mc_device_remove-to-common-heade.patch | 37 - ...increase-MC_CMD_COMPLETION_TIMEOUT_MS-val.patch | 27 - ...added-missing-fields-to-dprc_rsp_get_obj_.patch | 46 - ...define-macros-for-iommu-enablement-for-fs.patch | 29 - ...l-mc-Extend-ICID-size-from-16bit-to-32bit.patch | 73 - ...fsl-mc-Some-apis-are-made-public-for-vfio.patch | 960 - ...fsl-mc-add-support-for-dpdmux-device-type.patch | 54 - ...fsl-mc-add-support-for-dpdcei-device-type.patch | 54 - ...add-support-for-dpaiop-dpci-and-dpdmai-de.patch | 77 - ...DMA-configure-to-have-force-dma-as-defaul.patch | 27 - ...Allocate-mc-portal-from-root-dprc-contain.patch | 45 - ...mc-use-raw-spin-lock-to-serialize-mc-cmds.patch | 58 - ...fsl-dpio-change-CENA-regs-to-be-cacheable.patch | 61 - ...io-enable-qbman-CENA-portal-memory-access.patch | 110 - ...1-soc-fsl-dpio-Prefer-the-CPU-affine-DPIO.patch | 35 - ...sl-dpio-Add-Support-for-Order-Restoration.patch | 214 - ...o-Fix-order-restoration-API-for-QBMan-5.0.patch | 144 - ...net-0154-soc-fsl-dpio-add-support-for-opr.patch | 100 - ...o-aligned-access-of-qbman-cacheable-regio.patch | 73 - ...-fsl-dpaa2-mac-Add-APIs-for-DPMAC-objects.patch | 1162 - ...-dpaa2-mac-Add-Freescale-DPAA2-mac-driver.patch | 765 - ...-dpaa2-mac-Remove-link-type-from-phy-sel-.patch | 40 - ...-staging-fsl-dpaa2-mac-Update-ethtool-ops.patch | 55 - ...-dpaa2-mac-Comply-with-mc-bus-header-upda.patch | 36 - ...-dpaa2-mac-Request-atomic-context-MC-port.patch | 28 - ...aging-fsl-dpaa2-mac-Remove-redundant-free.patch | 24 - ...t-0163-staging-fsl-dpaa2-mac-Cleanup-code.patch | 89 - ...aging-fsl-dpaa2-mac-Free-phydev-on-unbind.patch | 31 - ...-dpaa2-mac-defer-probe-if-no-mc-portal-is.patch | 23 - ...-dpaa2-mac-make-compatible-with-upstream-.patch | 180 - ...-dpaa2-mac-probe-phy-as-fixed-link-based-.patch | 35 - ...-fsl-dpaa2-mac-Fix-uninitialized-variable.patch | 23 - ...-dpaa2-mac-read-phy-mode-from-device-tree.patch | 49 - ...-staging-fsl-dpaa2-mac-Add-more-PHY-modes.patch | 26 - ...staging-fsl-dpaa2-mac-Check-DPMAC-version.patch | 99 - ...-dpaa2-mac-Fix-dpmac_set_link_state-comma.patch | 24 - ...-dpaa2-mac-Add-support-for-new-link-state.patch | 235 - ...staging-fsl-dpaa2-mac-Add-autoneg-support.patch | 132 - ...ng-fsl-dpaa2-mac-connect-to-the-fixed-phy.patch | 92 - ...-dpaa2-mac-add-pause-frames-support-for-m.patch | 51 - ...ing-dpaa2-mac-Update-interface-mode-array.patch | 32 - ...aa2-mac-add-link-up-down-events-for-dpmac.patch | 91 - ...-dpaa2-evb-Add-Edge-Virtual-Bridge-driver.patch | 3182 - ...t-0180-staging-dpaa2-evb-Fix-W-1-warnings.patch | 41 - ...staging-dpaa2-evb-Improve-ethtool-support.patch | 153 - ...ing-dpaa2-evb-Update-MTU-update-procedure.patch | 57 - ...aa2-evb-Update-netlink-parsing-parameters.patch | 32 - ...a2-evb-Update-netdev_master_upper_dev_lin.patch | 22 - ...dpaa2-evb-Use-MC-portal-in-atomic-context.patch | 25 - ...a2-evb-change-mc_command-in-fsl_mc_comman.patch | 284 - ...0187-staging-dpaa2-evb-Fix-MC-bus-include.patch | 35 - ...a2-evb-Defer-probe-if-no-mc-portal-is-fou.patch | 29 - ...g-dpaa2-evb-Update-netlink-attributes-API.patch | 53 - .../701-net-0190-dpaa2-eth-Cleanup-dead-code.patch | 35 - ...191-dpaa2-eth-Avoid-unbounded-while-loops.patch | 160 - ...a2-eth-Add-support-for-Rx-traffic-classes.patch | 263 - ...-net-0193-dpaa2-eth-Trim-debugfs-FQ-stats.patch | 28 - ...istribute-ingress-frames-based-on-VLAN-pr.patch | 397 - ...1-net-0195-dpaa2-eth-Add-helper-functions.patch | 61 - ...inor-cleanup-in-dpaa2_eth_set_rx_taildrop.patch | 92 - ...7-dpaa2-eth-Add-congestion-group-taildrop.patch | 64 - ...pdate-FQ-taildrop-threshold-and-buffer-po.patch | 77 - .../701-net-0199-dpaa2-eth-Add-DCB-ops.patch | 154 - .../701-net-0200-dpaa2-eth-Enable-Rx-PFC.patch | 86 - .../701-net-0201-dpaa2-eth-Enable-Tx-PFC.patch | 263 - ...eep-congestion-group-taildrop-enabled-whe.patch | 138 - ...701-net-0203-dpaa2-eth-Add-Tx-shaping-API.patch | 94 - ...net-0204-dpaa2-eth-Add-Tx-shaping-support.patch | 142 - ...701-net-0205-dpaa2-eth-Add-Rx-error-queue.patch | 202 - ...0206-dpaa2-eth-Add-API-for-counters-reset.patch | 70 - ...-eth-Add-reset-controls-for-debugfs-stats.patch | 92 - .../701-net-0208-dpaa2-eth-Add-channel-stat.patch | 73 - ...-eth-Update-dpni_set_tx_shaping-cmd-to-v2.patch | 147 - ...-dpaa2-eth-Add-dpni_set_tx_priorities-API.patch | 158 - ...0211-dpaa2-eth-Update-dpni_get_statistics.patch | 95 - ...Add-API-for-ceetm_id-tc-in-set-congestion.patch | 64 - ...et-0213-dpaa2-eth-Add-CEETM-qdisc-support.patch | 1619 - ...-eth-Re-add-get_link_ksettings-ethtool-op.patch | 83 - ...2-eth-Add-support-for-new-link-state-APIs.patch | 229 - ...01-net-0216-dpaa2-eth-Add-autoneg-support.patch | 129 - ...on-t-use-netif_receive_skb_list-for-TCP-f.patch | 125 - ...Add-a-new-parameter-to-dprc_scan_objects-.patch | 127 - ...Extend-functions-from-the-bus-driver-to-b.patch | 49 - ...bus-fsl-mc-Set-the-QMAN-BMAN-region-flags.patch | 30 - ...io-Adding-QMAN-multiple-enqueue-interface.patch | 304 - ...o-QMAN-performance-improvement.-Function-.patch | 789 - ...o-Replace-QMAN-array-mode-by-ring-mode-en.patch | 649 - ...-net-0224-bus-fsl-mc-add-autorescan-sysfs.patch | 157 - ...gure-the-Time-Aware-Scheduler-via-tc-tapr.patch | 378 - ...e-TSN-Qbv-PSPEED-set-according-to-adjust-.patch | 171 - ...701-net-0227-enetc-Fix-if_mode-extraction.patch | 46 - ...28-enetc-Make-mdio-accessors-more-generic.patch | 221 - ...alize-SerDes-for-SGMII-and-SXGMII-protoco.patch | 169 - ...30-enetc-Drop-redundant-device-node-check.patch | 27 - ...T-protocol-information-to-set-up-the-port.patch | 195 - ...01-net-0232-enetc-Handle-USXGMII-protocol.patch | 45 - ...-enetc-Enable-live-mac-addr-change-for-PF.patch | 27 - ...4-enetc-WA-for-MDIO-register-access-issue.patch | 409 - ...t-0235-enetc-Clean-up-of-ehtool-stats-len.patch | 44 - ...ce-enetc_gregs-with-a-readers-writer-lock.patch | 385 - ...tc-Remove-mdio-bus-on-PF-probe-error-path.patch | 58 - ...ocelot-break-apart-ocelot_vlan_port_apply.patch | 314 - ...elot-break-apart-vlan-operations-into-oce.patch | 108 - ...elot-break-out-fdb-operations-into-abstra.patch | 251 - ...elot-change-prototypes-of-hwtstamping-ioc.patch | 83 - ...elot-change-prototypes-of-switchdev-port-.patch | 192 - ...elot-refactor-struct-ocelot_port-out-of-f.patch | 388 - ...elot-separate-net_device-related-items-ou.patch | 1171 - ...et-mscc-ocelot-refactor-ethtool-callbacks.patch | 133 - ...elot-limit-vlan-ingress-filtering-to-actu.patch | 28 - ...elot-move-port-initialization-into-separa.patch | 89 - ...elot-separate-the-common-implementation-o.patch | 86 - ...elot-initialize-list-of-multicast-address.patch | 37 - ...elot-refactor-adjust_link-into-a-netdev-i.patch | 72 - ...elot-split-assignment-of-the-cpu-port-int.patch | 163 - ...elot-don-t-hardcode-the-number-of-the-CPU.patch | 63 - ...elot-move-resource-ioremap-and-regmap-ini.patch | 101 - ...elot-filter-out-ocelot-SoC-specific-PCS-c.patch | 147 - ...elot-move-invariant-configs-out-of-adjust.patch | 154 - ...elot-create-a-helper-for-changing-the-por.patch | 87 - ...elot-export-a-constant-for-the-tag-length.patch | 73 - ...elot-adjust-MTU-on-the-CPU-port-in-NPI-mo.patch | 54 - ...elot-separate-the-implementation-of-switc.patch | 109 - ...elot-publish-structure-definitions-to-inc.patch | 1414 - ...elot-publish-ocelot_sys.h-to-include-soc-.patch | 344 - ...elot-add-tagger-for-Ocelot-Felix-switches.patch | 331 - ...ocelot-add-driver-for-Felix-switch-family.patch | 1163 - ...ix-Fix-CPU-port-assignment-when-not-last-.patch | 53 - ...elot-export-ocelot_hwstamp_get-set-functi.patch | 57 - ...ocelot-convert-to-use-ocelot_get_txtstamp.patch | 202 - ...elot-convert-to-use-ocelot_port_add_txtst.patch | 93 - ...lot-define-PTP-registers-for-felix_vsc995.patch | 53 - ...lot-add-hardware-timestamping-support-for.patch | 186 - ...elot-avoid-incorrect-consuming-in-skbs-li.patch | 25 - ...ocelot-use-skb-queue-instead-of-skbs-list.patch | 158 - ...net-mscc-ocelot-tsn-configuration-support.patch | 1986 - ...a-ocelot-add-tsn-support-for-felix-switch.patch | 671 - ...elot-alloc-memory-for-dsa-switch-instance.patch | 25 - ...et-0284-net-fsl_ppfe-dts-binding-for-ppfe.patch | 188 - ...-fsl_ppfe-eth-header-files-for-pfe-driver.patch | 2622 - ...staging-fsl_ppfe-eth-introduce-pfe-driver.patch | 7994 -- ...ing-fsl_ppfe-eth-fix-RGMII-tx-delay-issue.patch | 30 - ...ging-fsl_ppfe-eth-remove-unused-functions.patch | 96 - ...fsl_ppfe-eth-fix-read-write-ack-idx-issue.patch | 77 - ..._ppfe-eth-Make-phy_ethtool_ksettings_get-.patch | 26 - ..._ppfe-eth-add-function-to-update-tmu-cred.patch | 68 - ..._ppfe-eth-Avoid-packet-drop-at-TMU-queues.patch | 87 - ...fsl_ppfe-eth-Enable-PFE-in-clause-45-mode.patch | 77 - ..._ppfe-eth-Disable-autonegotiation-for-2.5.patch | 42 - ..._ppfe-eth-calculate-PFE_PKT_SIZE-with-SKB.patch | 30 - ..._ppfe-eth-support-for-userspace-networkin.patch | 155 - ..._ppfe-eth-unregister-netdev-after-pfe_phy.patch | 44 - ...ng-fsl_ppfe-eth-HW-parse-results-for-DPDK.patch | 47 - ...ng-fsl_ppfe-eth-reorganize-pfe_netdev_ops.patch | 30 - ...sl_ppfe-eth-use-mask-for-rx-max-frame-len.patch | 46 - ..._ppfe-eth-define-pfe-ndo_change_mtu-funct.patch | 73 - ..._ppfe-eth-remove-jumbo-frame-enable-from-.patch | 46 - ...-staging-fsl_ppfe-eth-disable-CRC-removal.patch | 28 - ...sl_ppfe-eth-handle-ls1012a-errata_a010897.patch | 107 - ...taging-fsl_ppfe-eth-replace-magic-numbers.patch | 142 - ...-fsl_ppfe-eth-resolve-indentation-warning.patch | 45 - ...aging-fsl_ppfe-eth-add-fixed-link-support.patch | 110 - ..._ppfe-add-support-for-a-char-dev-for-link.patch | 364 - ...-fsl_ppfe-enable-hif-event-from-userspace.patch | 118 - ...sl_ppfe-performance-tuning-for-user-space.patch | 47 - ...l_ppfe-eth-Update-to-use-SPDX-identifiers.patch | 563 - ...t-0312-staging-fsl_ppfe-eth-misc-clean-up.patch | 52 - ..._ppfe-eth-reorganize-platform-phy-paramet.patch | 156 - ..._ppfe-eth-support-single-interface-initia.patch | 271 - ...et-fsl_ppfe-update-dts-properties-for-phy.patch | 101 - ...6-staging-fsl_ppfe-eth-remove-unused-code.patch | 51 - ..._ppfe-eth-separate-mdio-init-from-mac-ini.patch | 650 - ..._ppfe-eth-adapt-to-link-mode-based-phydev.patch | 56 - ..._ppfe-eth-use-generic-soc_device-infra-in.patch | 50 - ..._ppfe-eth-use-memremap-to-map-RAM-area-us.patch | 49 - ..._ppfe-eth-remove-fallback-argument-from-d.patch | 25 - ..._ppfe-eth-prefix-header-search-paths-with.patch | 31 - ..._ppfe-eth-add-pfe-support-to-Kconfig-and-.patch | 48 - ...l_ppfe-eth-Disable-termination-of-CRC-fwd.patch | 34 - ...t-0325-net-phy-add-10G-fixed-link-support.patch | 20 - ...et-0326-phy-Add-2.5G-SGMII-interface-mode.patch | 32 - ...ess-packet-drops-at-low-traffic-rate-due-.patch | 83 - ...et-phy-Inphi-IN112525_s03-retimer-support.patch | 620 - ...et-phy-Inphi-IN112525_s03-retimer-updates.patch | 74 - ...03x-add-vddio-1v8-and-eee-disable-support.patch | 140 - ...net-phy-aquantia-enable-AQR112-and-AQR412.patch | 140 - ...-phy-aquantia-fix-system-side-protocol-mi.patch | 34 - ...-phy-aquantia-enable-USX-AN-for-USXGMII-p.patch | 37 - ...link-interface-for-APP-layer-to-config-TS.patch | 5113 - ...et-tsn-fix-headfile-voliates-the-new-rule.patch | 22 - ...upport-Credit-Based-Shaper-CBS-for-hardwa.patch | 231 - ...-support-tsn-capabilities-qbv-qci-qbu-cbs.patch | 2911 - ...ix-Fix-probing-allocation-and-cleanup-pat.patch | 123 - ...mscc-ocelot-hard-code-VCAP_PORT_CNT-for-F.patch | 26 - ...mscc-ocelot-make-ocelot_ace_rule-support-.patch | 123 - ...mscc-ocelot-add-VCAP-IS2-rule-to-trap-PTP.patch | 60 - ...-376-enetc-disable-EEE-autoneg-by-default.patch | 38 - ...-dpaa2-ethsw-move-port-notifier-per-ethsw.patch | 80 - ...a2-ethsw-move-port-switchdev-notifier-per.patch | 68 - ...a2-ethsw-move-port-switchdev-blocking-not.patch | 60 - ...a2-ethsw-ordered-workqueue-should-be-per-.patch | 90 - ...-dpaa2-mac-do-not-call-dpmac_set_link_sta.patch | 45 - ...-dpaa2-mac-reverse-order-of-handling-stop.patch | 37 - ...dd-dummy-functions-for-probe-deferal-APIs.patch | 34 - ...x-identation-causing-compilation-warnings.patch | 34 - ...0351-sdk_fman-address-compilation-warning.patch | 32 - ...dpio-Enable-ACP-port-in-Linux-QMAN-driver.patch | 37 - ...-dpaa2-mac-do-not-stop-MAC-when-the-net_d.patch | 65 - ...0354-bus-fsl-mc-add-the-dpdbg-device-type.patch | 35 - ...355-sdk_fman-decrease-log-severity-levels.patch | 41 - ...356-sdk_dpaa-ethtool-drop-unused-variable.patch | 31 - ..._dpaa-ls1043a-errata-memory-related-fixes.patch | 107 - ...1043a-errata-update-and-optimize-the-rest.patch | 252 - ...1043a-errata-re-enable-SG-support-and-rec.patch | 71 - ...k_fman-ls1043a-errata-detect-based-on-DTB.patch | 297 - ...k_fman-ls1034a-errata-update-number-to-A0.patch | 259 - ...a-ceetm-remove-references-to-qdisc_lookup.patch | 111 - ...sdk_dpaa-ceetm-export-the-ceetm_tx-symbol.patch | 23 - ...dk_dpaa-ceetm-enable-building-as-a-module.patch | 40 - ...-0365-sdk_dpaa-ceetm-coding-style-cleanup.patch | 431 - ...ethernet-freescale-sdk_fman-fix-the-build.patch | 280 - ...elot-Workaround-to-allow-traffic-to-CPU-i.patch | 149 - ...celot-add-NET_VENDOR_MICROSEMI-dependency.patch | 41 - ...elpers-for-parsing-SGMII-auto-negotiation.patch | 105 - ...-make-QSGMII-a-valid-PHY-mode-for-in-band.patch | 30 - ...t-phylink-add-support-for-polling-MAC-PCS.patch | 74 - ...Pass-pcs_poll-flag-from-driver-to-PHYLINK.patch | 48 - ...MDIO-accessors-more-generic-and-export-to.patch | 446 - ...DIO_CFG_HOLD-to-the-recommended-value-of-.patch | 58 - ...elot-make-phy_mode-a-member-of-the-common.patch | 85 - ...elot-export-ANA-DEV-and-QSYS-registers-to.patch | 2457 - ...-dsa-felix-Add-PCS-operations-for-PHYLINK.patch | 1087 - ...8514-enable-in-band-SGMII-auto-negotiatio.patch | 56 - ...drivers-net-phy-aquantia-Add-XFI-counters.patch | 96 - ...-net-felix-set-link-based-on-BMSR-not-LPA.patch | 23 - ...rivers-net-phylink-in-band-AN-for-USXGMII.patch | 35 - ...-phy-don-t-crash-in-phy_read-_write_mmd-w.patch | 35 - ...-dsa-felix-Allow-PHY-to-AN-10-100-1000-wi.patch | 34 - ...-dsa-felix-Handle-PAUSE-Rx-regardless-of-.patch | 35 - ...-mscc_ocelot-don-t-flood-unicast-traffic-.patch | 39 - ...fman-add-an-option-for-RTC-1588-timer-ini.patch | 215 - ...depend-on-FSL_SDK_FMAN_RTC_API-for-ptp_qo.patch | 27 - ...sdk_dpaa-ceetm-fix-recursive-dependencies.patch | 132 - ...etc-add-ioctl-support-for-PHY-related-ops.patch | 30 - ..._ppfe-eth-Enhance-error-checking-in-platf.patch | 28 - ...ging-fsl_qbman-Disable-Portal-Channel-IRQ.patch | 31 - ...ramework-for-enabling-Link-status-notific.patch | 385 - ...-dsa-felix-don-t-restart-PCS-SGMII-AN-if-.patch | 41 - ...ix-Don-t-error-out-on-disabled-ports-with.patch | 31 - ...ocelot-tsn-clean-preempt-interrupt-status.patch | 61 - ...nly-create-debugfs-entries-when-QBMan-is-.patch | 69 - ...enetc-Set-MAC-Rx-FIFO-to-recommended-valu.patch | 43 - ...x-CONFIG_COMPAT-leak-during-headers-insta.patch | 516 - ...rt-ASoC-fsl_sai-Fix-noise-when-using-EDMA.patch | 76 - ...ert-ASoC-fsl_sai-Implement-set_bclk_ratio.patch | 65 - ...evert-ASoC-fsl_sai-Add-support-for-imx8qm.patch | 32 - ...oC-fsl_sai-Add-support-for-imx7ulp-imx8mq.patch | 37 - ...C-fsl_sai-Add-support-for-SAI-new-version.patch | 605 - ...-fsl_sai-Update-Tx-Rx-channel-enable-mask.patch | 43 - ...-fsl_sai-Add-registers-definition-for-mul.patch | 184 - ...-Remove-dev_err-usage-after-platform_get_.patch | 467 - ...evert-ASoC-fsl_sai-mark-regmap-as-fast_io.patch | 20 - ...-fsl_sai-derive-TX-FIFO-watermark-from-FI.patch | 46 - ...011-Revert-ASoC-fsl_sai-add-of_match-data.patch | 96 - ...oC-fsl_sai-There-is-underrun-detected-in-.patch | 39 - ...-ASoC-fsl-sai-Just-one-device-can-playbac.patch | 51 - ...SoC-fsl_sai-add-initial-value-for-is_slav.patch | 25 - ...sai-set-xCR4-xCR5-xMR-for-SAI-master-mode.patch | 56 - ...SoC-fsl_sai-Change-the-dev_warn-to-dev_db.patch | 27 - ...-ASoC-fsl_sai-correct-the-clock-source-fo.patch | 25 - ...-ASoC-fsl_sai-refine-driver-for-ip-upgrad.patch | 423 - ...609-ASoC-fsl_sai-fix-for-synchronize-mode.patch | 56 - ...-sai-introduce-shared-interrupt-DT-flag-p.patch | 42 - ...sai-handle-slave-mode-per-TX-RX-direction.patch | 118 - ...SoC-fsl_sai-set-specific-fmt-for-I2S-XTOR.patch | 62 - ...evert-ASoC-fsl-sai-set-xCR4-xCR5-xMR-for-.patch | 59 - ...0-ASoC-fsl_sai-Remove-support-for-S20_3LE.patch | 30 - ...SoC-fsl_sai-Fix-mixing-initialization-dat.patch | 36 - ...-1-ASoC-fsl_sai-support-latest-sai-module.patch | 701 - ...-1-ASoC-fsl_sai-Fix-noise-when-using-EDMA.patch | 107 - ...-ASoC-fsl_sai-update-fifo_depth-for-diffe.patch | 51 - ...-ASoC-fsl_sai-refine-the-pm-runtime-funct.patch | 36 - ...-ASoC-fsl_sai-Refine-master-flag-handling.patch | 80 - ...-ASoC-fsl_sai-enable-TCE-RCE-according-to.patch | 72 - ...-13946-3-ASoC-fsl_sai-fix-the-xMR-setting.patch | 108 - ...-ASoC-fsl_sai-use-min-channels-slots-for-.patch | 28 - ...-MLK-16929-1-ASoC-fsl_sai-add-bitclk_freq.patch | 55 - ...4-ASoC-fsl_sai-support-multi-fifo-and-DSD.patch | 326 - ...K-17467-ASoC-fsl_sai-fix-typo-for-fsl_sai.patch | 36 - ...224-6-ASoC-fsl_sai-fix-DSD-suspend-resume.patch | 49 - ...8-ASoC-fsl_sai-support-768KHz-sample-rate.patch | 42 - ...SoC-fsl_sai-Specify-supported-rate_min-an.patch | 38 - ...7566-ASoC-fsl_sai-fix-register-definition.patch | 97 - ...-ASoC-fsl_sai-Introduce-FSL_SAI_CLK_BIT-c.patch | 42 - ...-ASoC-fsl_sai-Set-clock-rate-in-set_syscl.patch | 44 - ...-ASoC-fsl_sai-update-register-offset-for-.patch | 26 - ...c-fsl-Set-SAI-Channel-Mode-to-Output-Mode.patch | 72 - ...580-ASoC-fsl-dsd-Add-DSD-utilities-helper.patch | 76 - ...048-MLK-17580-ASoC-fsl-sai-Use-DSD-helper.patch | 96 - ...580-ASoC-fsl-sai-check-for-pinctrl-status.patch | 60 - ...-1-ASoC-fsl-sai-add-support-for-SAI-v3.01.patch | 250 - ...-ASoC-fsl-sai-introduce-1-1-bclk-mclk-rat.patch | 135 - ...-ASoC-fsl-sai-use-set_bclk_ratio-to-calcu.patch | 98 - ...-ASoC-fsl-sai-allow-dynamic-pll-switching.patch | 121 - ...-18947-ASoC-fsl_sai-fix-volatile-function.patch | 30 - ...-ASoC-fsl_sai-select-pinctrl-state-as-fun.patch | 100 - ...-ASoC-fsl-dsd-make-fsl_get_pins_state-inl.patch | 24 - ...-ASoC-fsl_sai-The-offset-of-fifo_off-is-c.patch | 41 - ...8-ASoC-fsl_sai-use-signed-offset-variable.patch | 53 - ...-ASoC-fsl_sai-map-number-of-pins-to-datal.patch | 373 - ...io-0060-ASoC-fsl_sai-Support-EPROBE_DEFER.patch | 23 - ...1-ASoC-fsl_sai-support-multi-power-domain.patch | 55 - ...i-fix-build-failture-due-to-5.1-RC7-upgra.patch | 42 - ...-ASoC-fsl-sai-fix-build-for-next-20190524.patch | 68 - ...4-ASoC-fsl_sai-Mark-cache-dirty-at-resume.patch | 28 - ...F-106-ASoC-fsl_sai-request-BUS_FREQ_AUDIO.patch | 40 - ...-ASoC-dmaengine_pcm-add-fifo_num-to-snd_d.patch | 28 - ...-ASoC-fsl_sai-ensure-clk-not-in-use-prior.patch | 79 - ...-ASoC-fsl_sai-remove-reset-code-from-dai_.patch | 30 - ...-ASoC-fsl_sai-read-SAI-version-and-params.patch | 92 - ...SoC-fsl_sai-fix-stack-out-of-bounds-KASAN.patch | 78 - ...-ASoC-fsl_sai-add-bitcount-and-timestamp-.patch | 164 - ...i-fix-build-issue-of-incomplete-parenthes.patch | 24 - ...-can-0001-imx-busfreq-Add-API-header-file.patch | 95 - ...02-can-0002-can-rx-offload-fix-long-lines.patch | 120 - ...x-offload-can_rx_offload_compare-fix-typo.patch | 23 - ...oad-can_rx_offload_irq_offload_timestamp-.patch | 26 - ...oad-can_rx_offload_reset-remove-no-op-fun.patch | 52 - ...can-rx-offload-Prepare-for-CAN-FD-support.patch | 206 - ...-use-devm_platform_ioremap_resource-to-si.patch | 41 - ...-flexcan_irq_state-only-read-timestamp-if.patch | 38 - ...-rename-macro-FLEXCAN_IFLAG_MB-FLEXCAN_IF.patch | 61 - ...-flexcan_irq-rename-variable-reg_iflag-re.patch | 35 - ...-rename-struct-flexcan_priv-reg_imask-1-2.patch | 101 - ...-remove-TX-mailbox-bit-from-struct-flexca.patch | 71 - ...-convert-struct-flexcan_priv-rx_mask-1-2-.patch | 107 - ...-introduce-struct-flexcan_priv-tx_mask-an.patch | 90 - ...-flexcan_read_reg_iflag_rx-optimize-readi.patch | 68 - ...-flexcan_irq-add-support-for-TX-mailbox-i.patch | 73 - ...-flexcan_mailbox_read-make-use-of-flexcan.patch | 37 - ...-use-struct-canfd_frame-for-CAN-classic-f.patch | 115 - ...-0019-can-flexcan-add-CAN-FD-mode-support.patch | 397 - ...n-0020-can-flexcan-add-CAN-FD-BRS-support.patch | 40 - ...an-flexcan-add-ISO-CAN-FD-feature-support.patch | 65 - ...-add-Transceiver-Delay-Compensation-suopp.patch | 70 - ...2-can-0023-can-flexcan-add-imx8qm-support.patch | 62 - ...an-0024-can-flexcan-add-lx2160ar1-support.patch | 45 - ...-flexcan-add-LPSR-mode-support-for-i.MX7D.patch | 52 - ...excan-fix-deadlock-when-using-self-wakeup.patch | 62 - ...flexcan-add-CAN-wakeup-function-for-i.MX8.patch | 193 - ...can-Add-S32V234-support-to-FlexCAN-driver.patch | 47 - ...-Add-clock-driver-for-Display-output-inte.patch | 351 - ...add-support-for-TLS-1.0-record-encryption.patch | 1205 - ...rypto-0002-crypto-tcrypt-include-rsa-test.patch | 36 - ...-use-mapped_-src-dst-_nents-for-descripto.patch | 227 - ...04-crypto-caam-use-devres-to-unmap-memory.patch | 109 - ...-crypto-caam-use-devres-to-remove-debugfs.patch | 88 - ...-caam-use-devres-to-de-initialize-the-RNG.patch | 179 - ...rypto-caam-use-devres-to-de-initialize-QI.patch | 114 - ...m-use-devres-to-populate-platform-devices.patch | 96 - ...rypto-caam-populate-platform-devices-last.patch | 56 - ...crypto-caam-jr-remove-incorrect-comment-f.patch | 39 - ...rypto-caam-remove-deadcode-on-32-bit-plat.patch | 42 - ...12-MLK-19053-crypto-caam-RNG4-TRNG-errata.patch | 63 - ...crypto-caam-adjust-RNG-timing-to-support-.patch | 36 - ...9769-8-crypto-caam-add-a-test-for-the-RNG.patch | 108 - ...-1-crypto-caam-add-support-for-i.mx8mm-mn.patch | 47 - ...crypto-caam-reduce-page-0-regs-access-to-.patch | 294 - ...KU-114-2-crypto-caam-SCU-firmware-support.patch | 137 - ...114-3-crypto-caam-OP-TEE-firmware-support.patch | 117 - ...-38-3-crypto-caam-add-SNVS-SECVIO-support.patch | 784 - ...5-3-crypto-caam-add-Secure-Memory-support.patch | 2503 - ...19801-1-crypto-caam-add-tag-functionality.patch | 439 - ...-crypto-caam-add-support-of-tagged-keys-i.patch | 304 - ...rypto-caam-add-support-for-DSM-with-Mega-.patch | 81 - ...rypto-caam-Change-structure-type-represen.patch | 45 - ...025-crypto-caam-qi2-add-unused-dpseci-API.patch | 561 - ...am-qi2-add-OPR-Order-Preservation-support.patch | 246 - ...crypto-caam-add-support-for-MOVEB-command.patch | 38 - ...to-caam-qi-add-support-for-TLS-1.0-record.patch | 1048 - ...o-caam-qi2-add-support-for-TLS-1.0-record.patch | 545 - ...-add-functionality-used-by-the-caam_dma-d.patch | 122 - ...to-caam-add-caam_dma-device-on-caam_probe.patch | 67 - ...crypto-caam-add-CAAM-job-ring-UIO-support.patch | 337 - ...crypto-caam-fix-Secure-Memory-driver-init.patch | 274 - ...0034-LF-63-1-crypto-caam-fix-SM-test-init.patch | 80 - ...5-crypto-caam-qi-use-QBMan-NXP-SDK-driver.patch | 342 - ...F-933-crypto-caam-fix-iosource-busy-issue.patch | 38 - ...to-caam-increase-the-domain-of-write-memo.patch | 44 - ...1-crypto-caam-refactor-RNG-initialization.patch | 248 - ...LF-292-2-crypto-caam-add-power-management.patch | 570 - ...i-dp-Add-display-QoS-interface-configurat.patch | 85 - ...p-prepare-common-code-for-cdns-and-rk-dpi.patch | 1943 - ...3-drm-bridge-add-Cadence-MHDP-HDMI-DP-API.patch | 4241 - ...rm-bridge-Add-Cadence-DP-HDMI-core-driver.patch | 1417 - ...0005-gpu-drm-Add-imx8qm-mq-DP-HDMI-driver.patch | 2307 - ...-drm-bridge-cadence-Add-new-api-functions.patch | 864 - ...-drm-bridge-cadence-Add-mhdp-audio-driver.patch | 715 - ...cadence-Add-CEC-driver-for-cdns-mhdp-hdmi.patch | 474 - ...-0009-drm-rockchip-Fix-build-failed-issue.patch | 24 - ...cadence-move-struct-imx_mhdp_device-to-dr.patch | 1096 - ...play-0011-drm-imx-add-imx8mq-hdmi-support.patch | 1169 - ...p-change-base-address-name-from-regs-to-r.patch | 29 - ...e-cadence-Add-power_on-to-__cdns_dp_probe.patch | 94 - ...ls1028a-Add-DP-driver-support-for-LS1028A.patch | 186 - ...cadence-Add-support-for-periodically-poll.patch | 148 - ...ay-0016-drm-imx-hdmi-support-arc-function.patch | 87 - ...cadence-Fix-return-value-for-set-log-addr.patch | 36 - ...cdns-dp-Remove-link-rate-lanes-set-by-dev.patch | 251 - ...imx-mhdp-add-dual-mode-support-for-imx8qm.patch | 192 - ...m-bridge-cdns-cec-fix-LA-failed-set-issue.patch | 129 - ...RM-mhdp-HDMI-skip-scdc-write-return-check.patch | 29 - ...d-mutex-lock-to-mhdp-register-access-func.patch | 83 - ...set-video-mode-after-hdmi-dp-cable-plugin.patch | 236 - ...e-cadence-hdmi-remove-video-mode-limition.patch | 27 - ...5-drm-imx-hdp-add-hdr10-metadata-property.patch | 173 - ...-0026-drm-imx-hdp-add-colorspace-property.patch | 39 - ...-force-a-mode-set-when-colorspace-is-chan.patch | 34 - ...dp-handle-the-various-deep-color-settings.patch | 187 - ...p-Adjustment-core-rate-of-DP-TX-CTRL-for-.patch | 59 - ...x8-fix-wrong-hdmi-type-with-non-SCDC-HDMI.patch | 41 - ...dmi-imx-Add-hdmi-phy-video-mode-valid-fun.patch | 135 - ...-bus-format-Add-RGB888_1X30_PADLO-support.patch | 22 - ...-bus-format-Add-RGB666_1X30_PADLO-support.patch | 22 - ...ormat-Add-RGB101010_1X7X5_SPWG-JEIDA-supp.patch | 34 - ...-drm-fourcc-Add-Amphion-tiled-layout-form.patch | 44 - ...rm-Add-drm_of_component_probe_with_match-.patch | 114 - ...-drm-add-fourcc-codes-for-Verisilicon-til.patch | 58 - ...add-modifier-for-vivante-compressed-tiled.patch | 33 - ...add-a-10bits-fully-packed-variant-of-NV12.patch | 45 - ...y-0045-drm-imx-Add-DPU-KMS-support-part-2.patch | 34 - ...rm-imx-Avoid-leaking-dangling-pointer-dev.patch | 37 - ...LK-18535-6-drm-imx-core-add-LCDIF-support.patch | 43 - ...mhdp-build-mhdp-sub-modules-into-one-driv.patch | 75 - ...m-bridge-cdns-move-link-training-to-bridg.patch | 74 - ...m-bridge-cdns-enhance-link-training-stabi.patch | 36 - ...m-bridge-cdns-dp-change-bridge_enable-dis.patch | 45 - ...m-gpu-bridge-cdns-Add-force-mode-set-flag.patch | 107 - ...u-cdn-imx8qm-Add-firmware-loading-support.patch | 268 - ...u-cdn-mhdp-common-Increase-the-check-aliv.patch | 29 - ...sl-dpaa2-qdma-Add-the-DPDMAI-Data-Path-DM.patch | 593 - ...sl-dpaa2-qdma-Add-NXP-dpaa2-qDMA-controll.patch | 1061 - ...0-DMA-fsl-edma-v3-add-fsl-edma-v3-support.patch | 1008 - ...-DMA-fsl-edma-v3-add-one-more-parameter-f.patch | 53 - ...03-2-Document-fsl_edma_v3-update-document.patch | 50 - ...ma-fsl-edma-v3-clear-DONE-before-E_SG-ena.patch | 30 - ...-dma-fsl-edma-v3-combine-two-cells-into-o.patch | 88 - ...0-3-dma-fsl-edma-v3-add-dual-fifo-support.patch | 106 - ...-dma-fsl-edma-v3-make-exclusive-channel-n.patch | 128 - ...ma-fsl-edma-v3-fix-kernel-crash-while-edm.patch | 42 - ...ma-fsl-edma-v3-Fix-RCU-issue-while-playin.patch | 65 - ...ma-fsl-edma-v3-add-suspend-resume-to-rest.patch | 192 - ...ma-fsl-edma-v3-fix-issue-reported-by-Cove.patch | 41 - ...ma-fsl-edma-v3-avoid-touch-unused-edma-ch.patch | 77 - ...-dmaengine-fsl-edma-v3-add-device_synchro.patch | 41 - ...-dmaengine-fsl-edma-v3-fix-potential-kern.patch | 33 - ...-dmaengine-fsl-edma-v3-fix-NULL-pointer-d.patch | 26 - ...0018-dma-imx-add-the-32bit-dma-limitation.patch | 38 - ...sl-edma-calculate-the-real-count-for-slav.patch | 70 - ...-dmaengine-fsl-edma-v3-do-not-enable-inte.patch | 42 - ...maengine-fsl-edma-v3-clear-pending-irq-be.patch | 124 - ...-dmaengine-fsl-edma-v3-add-power-domains-.patch | 170 - ...-dmaengine-fsl-edma-v3-check-dma-descript.patch | 47 - ...-dmaengine-fsl-edma-v3-fix-build-warning-.patch | 39 - ...maengine-fsl-edma-v3-clear-interrupt-comi.patch | 43 - ...6-dma-0026-dma-caam-add-dma-memcpy-driver.patch | 538 - ...6-dma-0027-dma-caam-fix-compilation-error.patch | 30 - ...sl-edma-Add-eDMA-support-for-QorIQ-LS1028.patch | 94 - ...x-change-irq-handler-from-chained-to-norm.patch | 80 - ...x-ls1088a-ls1028a-edge-detection-mode-bug.patch | 24 - ...1-i2c-mux-pca954x-add-i2c-bus-switch-PCA9.patch | 52 - ...002-MLK-10893-i2c-imx-add-irqf_no_suspend.patch | 29 - ...11403-I2C-imx-restore-pin-setting-for-i2c.patch | 57 - ...nable-runtime-pm-of-i2c-temporary-when-do.patch | 58 - ...2c-imx-add-a-limit-of-maximum-transfer-sp.patch | 94 - ...2c-imx-Coverity-fix-divide-by-zero-warnin.patch | 99 - ...-imx-add-workaround-for-erratum-ERR010027.patch | 34 - ...lement-bus-recovery-with-gpio-for-Layersc.patch | 268 - ...i2c-imx-get-rid-of-CONFIG_ARCH_LAYERSCAPE.patch | 36 - ...-system-hang-due-to-access-i2c-registers-.patch | 52 - ...imx-support-slave-mode-for-imx-I2C-driver.patch | 282 - ...rect-code-of-errata-A-010650-for-layersca.patch | 92 - ...mx-fix-the-judgement-of-slave-mode-in-isr.patch | 46 - ...c-mux-pca954x-support-property-idle-state.patch | 165 - ...c-imx-increase-PM-timeout-to-avoid-operat.patch | 27 - ...c-imx-Defer-probing-if-EDMA-not-available.patch | 70 - ...-net-virtual-network-device-for-Jailhouse.patch | 960 - ...-0002-ivshmem-net-Map-shmem-region-as-RAM.patch | 26 - ...003-ivshmem-net-fix-race-in-state-machine.patch | 136 - ...e-0004-ivshmem-net-Remove-unused-variable.patch | 24 - ...09-jailhouse-0005-ivshmem-net-Enable-INTx.patch | 51 - ...m-net-Improve-identification-of-resources.patch | 55 - ...-Switch-to-reset-state-on-each-net-stop-a.patch | 43 - ...008-ivshmem-net-Add-ethtool-register-dump.patch | 57 - ...-net-Fix-stuck-state-machine-during-setup.patch | 26 - ...t-Switch-to-relative-descriptor-addresses.patch | 45 - ...shmem-net-Switch-to-pci_alloc_irq_vectors.patch | 143 - ...-fill-in-and-check-used-descriptor-chain-.patch | 65 - ...ivshmem-net-slightly-improve-debug-output.patch | 25 - ...vshmem-net-set-and-check-descriptor-flags.patch | 39 - ...15-ivshmem-net-add-MAC-changing-interface.patch | 37 - ...0016-ivshmem-net-Silence-compiler-warning.patch | 24 - ...m-net-Fix-bogus-transition-to-RESET-state.patch | 27 - ...-Refactor-and-comment-ivshm_net_state_cha.patch | 63 - ...mem-net-Switch-to-netdev_xmit_more-helper.patch | 55 - ...dd-simple-debug-console-via-the-hyperviso.patch | 164 - ...ouse-0021-arm64-export-__hyp_stub_vectors.patch | 35 - ...ys-secure_key-Adds-the-secure-key-support.patch | 1285 - ...eys-Adds-support-for-secure-key-type-as-m.patch | 162 - ...ys-secure_key-Fix-the-path-of-included-he.patch | 38 - ...-arm64-KVM-support-flushing-device-memory.patch | 42 - ...VM-allow-specifying-s2-prot-bits-when-map.patch | 87 - ...KVM-drop-qman-mmio-cacheable-mapping-hack.patch | 132 - ...t-vgic-Increase-number-of-DeviceIDs-to-17.patch | 26 - ...e-0001-PCI-layerscape-Add-LS1028a-support.patch | 23 - ...se-interrupt-disabling-instead-of-masking.patch | 60 - ...c-fix-the-msi-failure-after-pm-operations.patch | 32 - ...port-aer-pme-interrupts-with-none-MSI-MSI.patch | 239 - ...CI-Disable-MSI-on-CYW4356-and-CYW4359-chi.patch | 30 - ...CI-add-quirk-for-cyw4356-to-disable-D3-mo.patch | 30 - ...e-MSI-on-marvel-88w9098-and-88w8997-chips.patch | 26 - ...I-mobiveil-Fix-csr_read-write-build-issue.patch | 286 - ...l-Refactor-Mobiveil-PCIe-Host-Bridge-IP-d.patch | 2184 - ...l-Make-mobiveil_host_init-can-be-used-to-.patch | 152 - ...l-Add-8-bit-and-16-bit-CSR-register-acces.patch | 47 - ...l-Add-PCIe-Gen4-RC-driver-for-NXP-Layersc.patch | 355 - ...il-ls_pcie_g4-add-Workaround-for-A-011577.patch | 150 - ...il-ls_pcie_g4-add-Workaround-for-A-011451.patch | 73 - .../812-pcie-0015-PCI-ls_gen4-WA-for-SERROR.patch | 28 - ...16-PCI-mobiveil-Add-the-EP-driver-support.patch | 889 - ...l-Add-PCIe-Gen4-EP-driver-for-NXP-Layersc.patch | 217 - ...l-Add-workaround-for-unsupported-request-.patch | 51 - ...dpoint_test-Add-the-layerscape-PCIe-GEN4-.patch | 32 - .../813-pm-0001-soc-fsl-add-RCPM-driver.patch | 201 - ...13-pm-0002-fsl_pmc-update-device-bindings.patch | 98 - ...-fsl-add-EPU-FSM-configuration-for-deep-s.patch | 464 - ...dd-routine-to-help-fetch-wakeup-source-ob.patch | 108 - ...andle-RCPM-errata-A-008646-on-SoC-LS1021A.patch | 100 - ...pm-0006-soc-fsl-rcpm-remove-build-warning.patch | 39 - ...c-move-qeic-driver-from-drivers-soc-fsl-q.patch | 1243 - ...c-merge-qeic-init-code-from-platforms-to-.patch | 40 - ...p-qeic-merge-qeic_of_init-into-qe_ic_init.patch | 173 - ...0004-irqchip-qeic-remove-PPCisms-for-QEIC.patch | 453 - .../814-qe-0005-QE-remove-PPCisms-for-QE.patch | 547 - ...14-qe-0006-config-qe-add-irq-qeic-support.patch | 61 - ...-enable-acpi-support-in-qoriq-ahci-driver.patch | 83 - ...workaround-for-errata-A-379364-on-lx2160a.patch | 191 - ...sata-0003-ahci_qoriq-bug-fix-for-ecc_addr.patch | 31 - ...f-esdhc-poll-ESDHC_FLUSH_ASYNC_FIFO-bit-u.patch | 72 - ...sdhci-of-esdhc-convert-to-use-esdhc_tunin.patch | 77 - ...sdhci-of-esdhc-update-tuning-erratum-A-00.patch | 90 - ...-qspi-dynamically-alloc-AHB-memory-for-QS.patch | 139 - ...-qspi-Introduce-variable-to-fix-different.patch | 108 - ...-spi-fspi-enable-fspi-on-imx8qxp-and-imx8.patch | 46 - ...0-2-spi-fspi-dynamically-alloc-AHB-memory.patch | 100 - ...pi-nxp-fspi-Enable-the-Octal-Mode-in-MCR0.patch | 26 - ...-spi-nor-Use-1-bit-mode-of-spansion-s25fs.patch | 22 - ...-fsl-qspi-Allocate-AHB-memory-dynamically.patch | 187 - ...hermal-Add-generic-device-cooling-support.patch | 253 - ...-thermal-qoriq-Add-device-cooling-support.patch | 145 - ...iq-add-thermal-monitor-unit-version-2-sup.patch | 211 - ...ermal-qoriq-Update-the-settings-for-TMUv2.patch | 80 - ...ty-serial-lpuart-add-power-domain-support.patch | 95 - ...-serial-fsl_lpuart-add-modem-device-reset.patch | 40 - ...serial-fsl_lpuart-add-magic-SysRq-support.patch | 28 - ...al-fsl_lpuart-enable-dma-mode-for-imx8qxp.patch | 558 - ...ty-serial-fsl_lpuart-enable-loopback-mode.patch | 29 - ...ty-serial-fsl_lpuart-check-dma_tx_in_prog.patch | 29 - ...erial-fsl_lpuart-do-HW-reset-for-communic.patch | 127 - ...2-tty-serial-lpuart-add-runtime-pm-suppor.patch | 199 - ...al-lpuart-enable-wakeup-source-for-lpuart.patch | 392 - ...11-serial-fsl_lpuart-enable-two-stop-bits.patch | 49 - ...serial-lpuart-support-UPIO_MEM32-for-lpua.patch | 37 - ...6-usb-phy-add-notify-suspend-and-resume-c.patch | 53 - ...-14285-1-usb-phy-add-usb-mode-for-usb_phy.patch | 59 - ...03-usb-phy-show-USB-charger-type-for-user.patch | 49 - ...e-suspend-clock-from-dt-to-set-power-down.patch | 62 - ...b-0005-usb-dwc3-add-otg-properties-update.patch | 67 - ...d-add-usb-role-switch-class-support-for-d.patch | 103 - ...-0008-usb-dwc3-set-fwnode-for-role-switch.patch | 33 - ...d-workaround-for-host-mode-VBUS-glitch-wh.patch | 130 - ...MLK-22675-usb-dwc3-host-disable-park-mode.patch | 88 - ...dwc3-Add-cache-type-configuration-support.patch | 151 - ...0-usb-whitelist-update-otg-eh-s-TPL-for-f.patch | 117 - ...9785-1-usb-host-ehci-hcd-enable-park-mode.patch | 38 - ...-usb-move-EH-SINGLE_STEP_SET_FEATURE-impl.patch | 364 - ...-usb-host-xhci-add-EH-SINGLE_STEP_SET_FEA.patch | 203 - ...LK-16735-usb-host-add-XHCI_CDNS_HOST-flag.patch | 42 - ...-usb-host-xhci-do-not-return-error-status.patch | 39 - ...1-usb-host-xhci-add-.bus_suspend-override.patch | 45 - ...b-core-print-suggested-message-if-failed-.patch | 32 - ...-usb-host-xhci-plat-add-XHCI_MISSING_CAS-.patch | 29 - ...sb-host-xhci-do-warm-reset-for-link-state.patch | 28 - ...0-usb-0022-usb-fsl-Remove-unused-variable.patch | 44 - ...Correct-NULL-pointer-checking-in-fsl-gadg.patch | 31 - ...vert-usb-dwc3-Add-cache-type-configuratio.patch | 123 - ...b-dwc3-Add-cache-type-configuration-suppo.patch | 157 - ...-Add-VFIO-framework-skeleton-for-fsl-mc-d.patch | 252 - ...-Scan-DPRC-objects-on-vfio-fsl-mc-driver-.patch | 140 - ...l-mc-Implement-VFIO_DEVICE_GET_INFO-ioctl.patch | 48 - ...-Implement-VFIO_DEVICE_GET_REGION_INFO-io.patch | 153 - ...-Allow-userspace-to-MMAP-fsl-mc-device-MM.patch | 99 - ...-Added-lock-support-in-preparation-for-in.patch | 193 - ...-Add-irq-infrastructure-for-fsl-mc-device.patch | 192 - ...o-fsl-mc-trigger-an-interrupt-via-eventfd.patch | 268 - ...-Add-read-write-support-for-fsl-mc-device.patch | 183 - ...-Map-the-VFIO-region-according-to-the-fla.patch | 38 - ...900-layerscape_fix_support_of_LS1012A-RDB.patch | 107 - .../patches-5.4/901-fix_irq_type_of_pca953x.patch | 28 - ...ayerscape_improve_support_of_LS1012A-FRDM.patch | 58 - 892 files changed, 311507 deletions(-) delete mode 100644 target/linux/layerscape/armv7/config-5.4 delete mode 100644 target/linux/layerscape/armv8_64b/config-5.4 delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0001-arm-kernel-utilize-hrtimer-based-broadcast.patch delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0002-arm64-add-support-to-remap-kernel-cacheable-memory-t.patch delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0003-arm64-pgtable-add-support-to-map-cacheable-and-non-s.patch delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0004-arm64-add-ioremap-for-normal-cacheable-non-shareable.patch delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0005-arch-arm-add-ARM-specific-fucntions-required-for-ehc.patch delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0006-export-arch_setup_dma_ops.patch delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0007-arm-dma-mapping-export-arch_setup_dma_ops.patch delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0008-arm-add-new-non-shareable-ioremap.patch delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0009-arm-add-pgprot_cached-and-pgprot_cached_ns-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0010-arm64-add-stage-2-cache-able-non-shareable-page-type.patch delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0011-drivers-soc-fsl-add-qixis-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/301-arch-0012-soc-fsl-select-MFD_CORE-for-qixis-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0001-sdk-arm64-dts-add-update-DPAA1-include-files-for-SDK.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0002-sdk-arm64-dts-add-DPAA1-SDK-flavor-dts-files.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0003-arm64-dts-ls1012a-Add-LS1012A-2G5RDB-board-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0004-arm64-dts-ls1012a-Add-more-nodes-to-LS1012A-FRWY-boa.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0005-arm64-dts-ls2081ardb-Add-DTS-support-for-NXP-LS2081A.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0006-arm64-dts-ls1012a-accumulated-change-for-ls1012a-boa.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0007-arm64-dts-ls1043a-accumulated-change-for-ls1043a-boa.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0008-arm64-dts-ls1046a-accumulated-change-to-ls1046a-boar.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0009-arm64-dts-ls1088a-accumulated-change-to-ls1088a-boar.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0010-arm64-dts-ls208xa-accumulated-change-to-ls208xa-boar.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0011-ARM-dts-accumulated-change.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0012-arm64-dts-ls1046a-add-smmu-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0013-arm64-dts-ls1043a-add-smmu-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0014-arm64-dts-ls104xa-set-mask-to-drop-TBU-ID-from-Strea.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0015-arm64-dts-ls104x-add-missing-dma-ranges-property.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0016-arm64-dts-ls104x-add-iommu-map-to-pci-controllers.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0017-arm64-dts-ls104x-make-dma-coherent-global-to-the-SoC.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0018-arm64-dts-ls104x-use-a-pseudo-bus-to-constrain-usb-d.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0019-sdk-dts-ls104x-drop-smmu-from-the-sdk-device-trees.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0020-arm64-dts-lx2160a-add-MDIO-device-tree-nodes.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0021-arm64-dts-lx2160a-rdb-Add-RGMII-PHY-nodes-for-dpmac-.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0022-arm64-dts-lx2160a-correct-scl-gpios-property.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0023-arm64-dts-lx2160a-add-dspi-controller-DT-nodes.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0024-arm64-dts-lx2160a-add-DT-node-for-all-DSPI-controlle.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0025-arm64-dts-nxp-ls208xa-add-more-thermal-zone-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0026-arm64-dts-nxp-add-more-thermal-zone-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0027-arm64-dts-lx2160a-rdb-Add-Inphi-PHY-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0028-arm64-dts-lx2160a-rdb-Add-Aquantia-PHY-nodes.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0029-arm64-dts-lx2160-Add-all-pcs-mdio-definitions-accord.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0030-arm64-dts-lx2160-PCS-PHY-definitions-for-10GBase-KR-.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0031-arm64-dts-lx2160-DPMAC-connections-to-backplane-PHYs.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0032-arm64-dts-Added-endianness-information-to-dts-serdes.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0033-arm64-dts-freescale-lx2160a-add-pcie-DT-nodes.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0034-arm64-dts-freescale-lx2160a-Inphi-in112525_s03-mdio-.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0035-arm64-dts-lx2160a-add-optee-tz-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0036-arm64-dts-ls104x-constrain-sata-dma-address-size.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0037-arm64-dts-lx2160a-qds-add-sata-node-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0038-arm64-dts-ls1012a-use-phy-handle-to-handle-phy-param.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0039-arm64-dts-ls1012a-remove-unused-gemac-bus-id.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0040-arm64-dts-ls1012a-reorganize-pfe_mac-nodes.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0041-sdk-dts-ls104x-drop-smmu-from-the-qds-and-usdpaa-sdk.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0042-arm64-dts-fix-the-LS104x-QDS-mdio-mux-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0043-arm64-dts-lx2160aqds-Add-mdio-mux-nodes.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0044-sdk-arm64-dts-reduce-usdpaa-memory-to-4K-for-LS1046-.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0045-arm64-dts-Fix-DWC3-IP-VBUS-glitch-issue-on-Layerscap.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0046-ARM-dts-Fix-DWC3-IP-VBUS-glitch-issue-on-LS1021A.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0047-ARM-dts-ls1021aqds-enable-esdhc-controller.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0048-arm64-dts-freescale-lx2160a-add-pcie-EP-mode-DT-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0049-sdk-dts-ls104x-move-dma-coherent-from-soc-to-its-chi.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0050-arm64-dts-lx2160a-add-interrupt-property-for-aquanti.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0051-arm64-dts-fsl-layerscape-fix-warnings-when-compiling.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0052-arm64-dts-fsl-layerscape-fix-warnings-when-compiling.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0053-sdk-arm64-dts-nxp-add-DPAA1-SDK-flavor-dts-files.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0054-arm64-dts-nxp-frwy-ls1046a-add-support-for-micron-no.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0055-arm64-dts-ls1028a-Add-PCIe-controller-DT-nodes.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0056-arm64-dts-lx2160a-Enable-usb3-lpm-capable-for-usb3-n.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0057-arm64-dts-fsl-lx2160a-add-flexcan-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0058-arm64-dts-fsl-ls1028a-add-flexcan-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0059-arm64-dts-fsl-ls1046-Modify-the-qspi-flash-frequency.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0060-arm64-dts-ls1028a-add-flexspi-nodes.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0061-sdk-dts-ls1046-drop-smmu-from-the-frwy-sdk-dtses.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0062-sdk-dts-ls1046frwy-move-dma-coherent-from-soc-to-its.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0063-arm64-dts-fsl-remove-backplane-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0064-arm64-dts-lx2160a-update-interrupt-property-for-Aqua.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0065-arm64-dts-ls1028a-Update-fspi-reg-properties.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0066-arm64-dts-ls1028a-add-gpu-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0067-arm64-dts-fsl-add-optee-node-for-ls1028.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0068-arm64-dts-lx2160a-Update-phy-mode-for-Aquantia-PHYs.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0069-arm64-dts-ls1028a-Add-ftm_alarm0-DT-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0070-arm64-dts-ls1012a-ls1043a-ls1046a-ls1088a-ls208xa-re.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0071-arm-dts-ls1021a-replace-ftm0-with-ftm_alarm0-DT-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0072-arm64-ls1028ardb-Add-support-DP-nodes-for-LS1028ARDB.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0073-arm64-ls1028aqds-Add-support-DP-nodes-for-LS1028AQDS.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0074-arm64-dts-fsl-ls1028a-Add-Felix-switch-port-DT-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0075-arm64-dts-fsl-ls1028a-Enable-switch-PHYs-on-RDB.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0076-arm64-dts-ls1028a-support-Felix-PF5-INTB-interrupt.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0077-arm64-dts-ls1028a-Add-ethernet-property-for-l2switch.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0078-arm64-dts-fix-endianness-of-rcpm.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0079-arm64-dts-ls1028a-Fix-interrupt-map-property-of-PCIe.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0080-arm64-dts-ls1028a-rdb-enable-emmc-hs400-mode.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0081-arm64-dts-lx2160a-add-ftm_alarm0-DT-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0082-arm64-dts-lx2160a-add-tmu-device-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0084-arm64-dts-ls1028a-define-networking-options-for-QDS.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0086-usb-dwc3-enable-otg-mode-for-dwc3-usb-ip-on-layersca.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0087-arm-dts-ls1021a-fix-that-FlexTimer-cannot-wakeup-sys.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0088-arm64-dts-ls1028a-fix-dwc-pci-over-smmu.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0089-arm64-dts-ls1028a-Update-the-clock-providers-for-the.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0090-arm64-dts-ls1028a-Update-clock-cells-of-dpclk-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0091-arm64-dts-ls1028a-Add-properties-for-HD-Display-cont.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0092-arm64-dts-ls1028a-Add-DP-DT-nodes.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0093-arm64-dts-fsl-Specify-phy-mode-for-CPU-ports.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0094-arm64-dts-fsl-Drop-compatible-string-from-Felix-swit.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0095-arm64-dts-fsl-ls1028a-Specify-that-the-Felix-port-4-.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0096-arm64-dts-fsl-ls1028a-Disable-eno3-and-make-swp5-the.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0097-LF-387-5-arm64-dts-layerscape-add-chip-specific-comp.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0098-LF-403-ARM64-dts-fsl-Add-clock-names-mclk0-for-SAI-n.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0099-arm64-dts-layerscape-apply-dma-coherent-for-dwc3-nod.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0100-arm64-dts-ls208xa-Update-qspi-node-properties-for-LS.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0101-arm64-dts-ls208xa-Remove-dma-coherent-from-dwc3-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0102-LF-20-1-arm64-dts-ls1012ardb-Update-qspi-node-dts-pr.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0103-arm64-dts-ls1028a-Update-edma-compatible-to-fit-eDMA.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0104-arm64-dts-lx2160a-add-iommu-map-property-to-pci-node.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0105-LF-18-1-arm64-dts-ls1088ardb-Update-qspi-dts-node-pr.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0106-LF-18-2-arm64-dts-ls1046ardb-Update-qspi-node-dts-pr.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0107-arm64-dts-ls1012ardb-Update-qspi-node-property.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0109-arm64-dts-ls1028a-rdb-Enable-SGMII-AN-for-the-QSGMII.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0110-arm64-dts-ls1028a-Disable-swp5-by-default.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0111-arm64-dts-fsl-ls1028a-rdb-fix-QSGMII-PHY-node-names.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0112-arm64-dts-fsl-ls1028a-prepare-dts-for-overlay.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0113-arm64-dts-fsl-ls1028a-qds-Add-overlays-for-various-s.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0114-arm64-dts-fsl-ls1028a-add-labels-to-Ethernet-switch-.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0115-LF-789-2-arm64-dts-add-overlay-support-for-ls1028a-q.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0116-LF-881-arm64-dts-add-a-dts-file-for-dpdk.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0117-arm-dts-ls1021a-Add-LS1021A-IOT-board-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0118-add-DTS-for-Traverse-LS1043-Boards.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0119-arm64-dts-lx2160a-add-more-thermal-zone-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0120-arm64-dts-ls1046a-fix-ippdexpcr-offset-not-correct.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0121-arm64-dts-ls1043a-update-USB-nodes-status-to-match-b.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-dts-0122-arm64-dts-ls1043a-remove-thermal-zone-5-from-dts.patch delete mode 100644 target/linux/layerscape/patches-5.4/302-v5.7-dts-0119-arm64-dts-ls1043a-rdb-add-compatible-for-board.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0001-net-readd-skb_recycle.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0002-drivers-base-add-sysfs-entries-for-suppliers-and-con.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0003-cgroup-let-a-symlink-too-be-created-with-a-cftype-fi.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0004-cgroup-bfq-revert-bfq.weight-symlink-change.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0005-nand-raw-workaround-for-EDO-high-speed-mode.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0006-mm-Re-export-ioremap_page_range.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0007-of-of_reserved_mem-Ensure-cma-reserved-region-not-cr.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0008-ENGR00279980-ubi-attach-do-not-return-EINVAL-if-the-.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0009-arm64-move-elfcorehdr-reservation-early-for-crash-du.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0010-scripts-Makefile-Enable-creation-of-_symbols_-DT-nod.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0011-LF-419-arm64-crash_core-Export-TCR_EL1.T1SZ-in-vmcor.patch delete mode 100644 target/linux/layerscape/patches-5.4/303-core-0012-LF-789-1-Revert-scripts-Makefile-Enable-creation-of-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0001-soc-fsl-qman-fixup-liodns-only-on-ppc-targets.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0002-soc-fsl-bman-map-FBPR-area-in-the-iommu.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0003-soc-fsl-qman-map-FQD-and-PFDR-areas-in-the-iommu.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0004-soc-fsl-qman-portal-map-CENA-area-in-the-iommu.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0005-soc-fsl-qbman_portals-add-APIs-to-retrieve-the-probi.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0006-soc-fsl-bqman-page-align-iommu-mapping-sizes.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0007-fsl_qbman-SDK-DPAA-1.x-QBMan-drivers.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0008-fmd-SDK-DPAA-1.x-FMan-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0009-dpa-SDK-DPAA-1.x-Ethernet-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0010-dpaa_eth-ls1043a-errata-check-if-the-skb-is-linear-a.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0011-dpaa_eth-ceetm-adapt-to-net-sched-API-changes.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0012-dpaa_eth-ceetm-adapt-to-the-new-gnet-stats-API.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0013-dpaa_eth-ceetm-update-include-paths-for-tc-filters.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0014-dpa_eth-remove-unused-code.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0015-fmd-use-ptp-timer-for-Fman-RTC-node-name.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0016-dpaa_eth-use-ptp-timer-phandle-instead-of-ptimer-han.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0017-dpaa_eth-move-global-variable-clock-into-ptp_priv_s-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0018-sdk_dpaa-use-new-api-ethtool_ksettings_-get-set.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0019-sdk_dpaa-fix-dpa_set_ksettings.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0020-dpaa_eth-memac-set-adjust_link-callback-for-fixed-li.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0021-sdk_dpaa-ls1043a-errata-resplit-the-skb-after-copy.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0022-sdk_dpaa-ls1043a-errata-realign-and-linearize-egress.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0023-sdk_dpaa-ls1043a-errata-realign-skb-in-place-if-need.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0024-sdk_dpaa-ls1043a-errata-verify-and-resize-headroom-a.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0025-sdk_dpaa-ls1043a-errata-do-not-recycle-the-realigned.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0026-sdk_dpaa-ls1043a-errata-fix-arm32-build.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0027-drivers-staging-fsl_qbman-Fix-SWP-Mask-in-Error-Hand.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0028-sdk_dpaa-avoid-crashing-on-OOM.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0029-sdk_dpaa-update-the-xmit-timestamp-to-avoid-watchdog.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0030-sdk_fman-resolve-arm32-compilation-issues-for-linux-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0031-sdk_dpaa-ls1043a-errata-maintain-timestamp-info.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0032-sdk_dpaa-ls1043a-errata-restrict-the-max-mtu.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0033-sdk_dpaa-adapt-to-the-new-API-for-MTU-changes.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0034-Extend-FM-MAC-Statistics-with-frame-size-counters-re.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0035-sdk_dpaa-accept-frames-on-RX-even-if-larger-than-MTU.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0036-sdk-dpa-use-netdev-dev-for-DMA-mapping.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0037-Added-MII-IOCTL-support-for-SIOCGMIIREG.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0038-sdk_dpaa-ls1043a-errata-stop-advertising-S-G-and-GSO.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0039-staging-fsl_qbman-Calculate-valid-bit-from-MC-RR.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0040-fsl_qbman-usdpaa-Invalidate-software-portals-before-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0041-net-ethernet-Rename-PHY_INTERFACE_MODE_SGMII_2500.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0042-sdk_dpaa-ceetm-add-independent-CEETM-congestion-thre.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0043-sdk_dpaa-ceetm-stop-transmitting-frames-when-the-CQ-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0044-sdk_dpaa-ceetm-coding-style-fixes-and-added-comments.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0045-sdk_dpaa-ceetm-increment-the-interface-s-ern-counter.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0046-sdk_dpaa-update-buffer-recycling-conditions.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0047-sdk_dpaa-update-comments-about-recycling-and-back-po.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0048-sdk_dpaa-ceetm-pass-extended-ACK-struct-to-parsing-f.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0049-sdk_dpaa-ceetm-adapt-to-new-tcf-classify-API.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0050-sdk_dpaa-ceetm-introduce-a-TRAP-control-action.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0051-sdk_dpaa-ceetm-use-the-tcf-block-infrastructure.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0052-sdk_dpaa-ceetm-remove-tc-class-reference-counting.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0053-sdk_dpaa-ceetm-store-Qdisc-pointer-in-struct-block.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0054-dpaa_eth-workaround-for-ERR010022.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0055-sdk_fman-DPAA-dTSEC-ports-fail-to-work-when-link-cha.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0056-sdk-dpa-adapt-compatibles-to-upstream-binding-docume.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0057-sdk_fman-fix-probing-of-10G-ports-on-T102x.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0058-sdk_fman-probe-OH-ports-on-PPC.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0059-sdk_fman-on-P-series-platforms-the-OH-ports-start-at.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0060-sdk_fman-disable-timer-code.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0061-sdk_fman-disable-timer-code-in-arm-code.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0062-sdk_dpa-adapt-ceetm-code-to-new-kernel-API.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0063-sdk_dpaa-propagate-the-skb-ownership-information.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0064-memac_init_phy-RGMII-fixed-link-pass-adjust_link-cal.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0065-sdk_dpaa-ceetm-avoid-use-after-free-scenarios.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0066-sdk_dpaa-ceetm-stop-the-netdev-queues-when-switching.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0067-fsl_qbman-ceetm-export-the-qman_ceetm_query_cq-call.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0068-sdk_dpaa-ceetm-propagate-the-ceetm-channel-through-t.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0069-sdk_dpaa-ceetm-reset-the-wbfs-groups-and-priorities-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0070-sdk_dpaa-ceetm-WQ-CEETM-mode-switchover-cleanup.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0071-sdk_dpaa-ceetm-drain-the-ceetm-CQs-on-destroy.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0072-sdk_dpaa-ls1043a-errata-adapt-to-new-skb-copy-API.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0073-dpaa_eth-ERR010022-adapt-to-new-skb-copy-API.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0074-sdk_dpaa-enable-Jumbo-frame-support-on-LS1043A.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0075-sdk_dpaa-reserve-256-bytes-for-the-SGT-on-TX.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0076-fsl_qbman-usdpaa-change-to-debug-print-in-interrupt-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0077-staging-fsl_qbman-Consume-all-frames-in-DQRR-during-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0078-staging-fsl_qbman-Recalcuate-cursor-after-consuming-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0079-fmd-use-fsl-fman-ptp-timer-compatible-for-ptp-probe.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0080-sdk_dpaa-store-the-skb-backpointer-in-the-skb-headro.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0081-sdk_dpaa-ls1043a-errata-align-skb_shinfo.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0082-sdk_dpaa-ls1043a-errata-move-comment.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0083-sdk_dpaa-ceetm-lower-the-default-congestion-threshol.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0084-staging-fsl_qbman-remove-bootmem-header.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0085-staging-fsl_qbman-stop-using-current_kernel_time.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0086-sdk_dpaa-ceetm-avoid-double-frees-on-error-paths.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0087-sdk_dpaa-ceetm-rename-qdisc_destroy-to-qdisc_put.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0088-sdk_dpaa-remove-FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0089-fsl-fman-backup-and-restore-ICID-registers.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0090-fsl-fman-add-API-to-get-the-device-behind-a-fman-por.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0091-dpaa_eth-defer-probing-after-qbman.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0092-dpaa_eth-base-dma-mappings-on-the-fman-rx-port.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0093-dpaa_eth-fix-iova-handling-for-contiguous-frames.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0094-dpaa_eth-fix-iova-handling-for-sg-frames.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0095-sdk_dpaa-ceetm-guard-against-an-out-of-bounds-queue-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0096-sdk_dpaa-guard-against-an-out-of-bounds-queue-index.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0097-sdk_dpaa-set-the-skb-queue-mapping-when-looping.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0098-sdk_dpaa-remove-ptp-clock-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0099-sdk_fman-suspend-the-FMan-to-Deep-Sleep-on-PPC-only.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0100-sdk_fman-disable-ptp-timer-probe.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0101-sdk_dpaa-add-the-get_ts_info-interface-for-ethtool.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0102-sdk_fman-share-the-event-interrupt.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0103-sdk_dpaa-fix-hardware-timestamp-value.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0104-sdk_dpaa-remove-useless-1588-timer-enablement.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0105-sdk-qbman-fix-issue-in-qman_delete_cgr_safe.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0106-sdk_fman-avoid-array-overflow-error-in-fman-port-ini.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0107-fsl_qbman-Adjust-platform-device-creation-for-QMan-p.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0108-sdk_dpaa-ls1043a-errata-impose-S-G-frame-realignment.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0109-sdk_dpaa-remove-the-QM_FQCTRL_PREFERINCACHE-flag.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0110-sdk_dpaa-adapt-to-kernel-5.1.0-rc1.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0111-sdk_qbman-Avoid-variable-length-array-in-USDPAA.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0112-sdk_dpaa-Rework-QBMan-portal-mappings.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0113-sdk_qbman-Fix-error-in-IP-revision-comparison.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0114-sdk_dpaa-SGMII-2500-needs-AN-disabled.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0115-sdk_qbman-Update-cpus_allowed-to-cpus_mask-to-cope-w.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0116-sdk_dpaa-ceetm-align-to-upstream-API-changes.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0117-dpaa_eth-ERR010022-align-skb_shinfo.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0118-dpaa_eth-ERR010022-preserve-timestamping.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0119-sdk_dpaa-ceetm-update-Makefile-to-use-absolute-inclu.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0120-sdk_dpaa-net-Rename-skb_frag_t-size-to-bv_len.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0121-dpaa_eth-Rename-skb_frag_t-size-to-bv_len.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0122-config-enable-SDK-FMan-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0123-config-enable-SDK-DPAA-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0124-config-enable-SDK-QBMan.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0125-config-add-SDK-QBMan-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0126-net-Makefile-re-add-DPAA-SDK-drivers.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0127-ptp-support-ptp_qoriq-for-sdk-dpaa.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0128-net-dpaa-fix-build-failure-due-to-skb_frag_t-struct-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0129-sdk_dpa-align-to-upstream-PHY_INTERFACE_MODE.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0130-bus-fsl-mc-move-fsl_mc_command-struct-in-a-uapi-head.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0131-bus-fsl-mc-add-fsl-mc-userspace-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0132-bus-fsl-mc-add-root-dprc-rescan-attribute.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0133-bus-fsl-mc-add-bus-rescan-attribute.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0134-bus-fsl-mc-Add-dprc-reset-container-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0135-bus-fsl-mc-Propagate-driver_override-for-a-child-DPR.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0136-bus-fsl-mc-add-device-binding-path-driver_override.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0137-bus-fsl-mc-move-fsl_mc_device_remove-to-common-heade.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0138-bus-fsl-mc-increase-MC_CMD_COMPLETION_TIMEOUT_MS-val.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0139-bus-fsl-mc-added-missing-fields-to-dprc_rsp_get_obj_.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0140-bus-fsl-mc-define-macros-for-iommu-enablement-for-fs.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0141-bus-fsl-mc-Extend-ICID-size-from-16bit-to-32bit.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0142-bus-fsl-mc-Some-apis-are-made-public-for-vfio.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0143-bus-fsl-mc-add-support-for-dpdmux-device-type.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0144-bus-fsl-mc-add-support-for-dpdcei-device-type.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0145-bus-fsl-mc-add-support-for-dpaiop-dpci-and-dpdmai-de.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0146-bus-fsl-mc-DMA-configure-to-have-force-dma-as-defaul.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0147-bus-fsl-mc-Allocate-mc-portal-from-root-dprc-contain.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0148-bus-fsl-mc-use-raw-spin-lock-to-serialize-mc-cmds.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0149-soc-fsl-dpio-change-CENA-regs-to-be-cacheable.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0150-soc-fsl-dpio-enable-qbman-CENA-portal-memory-access.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0151-soc-fsl-dpio-Prefer-the-CPU-affine-DPIO.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0152-soc-fsl-dpio-Add-Support-for-Order-Restoration.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0153-soc-fsl-dpio-Fix-order-restoration-API-for-QBMan-5.0.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0154-soc-fsl-dpio-add-support-for-opr.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0155-soc-fsl-dpio-aligned-access-of-qbman-cacheable-regio.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0156-staging-fsl-dpaa2-mac-Add-APIs-for-DPMAC-objects.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0157-staging-fsl-dpaa2-mac-Add-Freescale-DPAA2-mac-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0158-staging-fsl-dpaa2-mac-Remove-link-type-from-phy-sel-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0159-staging-fsl-dpaa2-mac-Update-ethtool-ops.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0160-staging-fsl-dpaa2-mac-Comply-with-mc-bus-header-upda.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0161-staging-fsl-dpaa2-mac-Request-atomic-context-MC-port.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0162-staging-fsl-dpaa2-mac-Remove-redundant-free.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0163-staging-fsl-dpaa2-mac-Cleanup-code.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0164-staging-fsl-dpaa2-mac-Free-phydev-on-unbind.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0165-staging-fsl-dpaa2-mac-defer-probe-if-no-mc-portal-is.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0166-staging-fsl-dpaa2-mac-make-compatible-with-upstream-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0167-staging-fsl-dpaa2-mac-probe-phy-as-fixed-link-based-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0168-staging-fsl-dpaa2-mac-Fix-uninitialized-variable.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0169-staging-fsl-dpaa2-mac-read-phy-mode-from-device-tree.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0170-staging-fsl-dpaa2-mac-Add-more-PHY-modes.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0171-staging-fsl-dpaa2-mac-Check-DPMAC-version.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0172-staging-fsl-dpaa2-mac-Fix-dpmac_set_link_state-comma.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0173-staging-fsl-dpaa2-mac-Add-support-for-new-link-state.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0174-staging-fsl-dpaa2-mac-Add-autoneg-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0175-staging-fsl-dpaa2-mac-connect-to-the-fixed-phy.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0176-staging-fsl-dpaa2-mac-add-pause-frames-support-for-m.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0177-staging-dpaa2-mac-Update-interface-mode-array.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0178-staging-dpaa2-mac-add-link-up-down-events-for-dpmac.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0179-staging-dpaa2-evb-Add-Edge-Virtual-Bridge-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0180-staging-dpaa2-evb-Fix-W-1-warnings.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0181-staging-dpaa2-evb-Improve-ethtool-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0182-staging-dpaa2-evb-Update-MTU-update-procedure.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0183-staging-dpaa2-evb-Update-netlink-parsing-parameters.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0184-staging-dpaa2-evb-Update-netdev_master_upper_dev_lin.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0185-staging-dpaa2-evb-Use-MC-portal-in-atomic-context.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0186-staging-dpaa2-evb-change-mc_command-in-fsl_mc_comman.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0187-staging-dpaa2-evb-Fix-MC-bus-include.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0188-staging-dpaa2-evb-Defer-probe-if-no-mc-portal-is-fou.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0189-staging-dpaa2-evb-Update-netlink-attributes-API.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0190-dpaa2-eth-Cleanup-dead-code.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0191-dpaa2-eth-Avoid-unbounded-while-loops.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0192-dpaa2-eth-Add-support-for-Rx-traffic-classes.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0193-dpaa2-eth-Trim-debugfs-FQ-stats.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0194-dpaa2-eth-Distribute-ingress-frames-based-on-VLAN-pr.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0195-dpaa2-eth-Add-helper-functions.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0196-dpaa2-eth-Minor-cleanup-in-dpaa2_eth_set_rx_taildrop.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0197-dpaa2-eth-Add-congestion-group-taildrop.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0198-dpaa2-eth-Update-FQ-taildrop-threshold-and-buffer-po.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0199-dpaa2-eth-Add-DCB-ops.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0200-dpaa2-eth-Enable-Rx-PFC.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0201-dpaa2-eth-Enable-Tx-PFC.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0202-dpaa2-eth-Keep-congestion-group-taildrop-enabled-whe.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0203-dpaa2-eth-Add-Tx-shaping-API.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0204-dpaa2-eth-Add-Tx-shaping-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0205-dpaa2-eth-Add-Rx-error-queue.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0206-dpaa2-eth-Add-API-for-counters-reset.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0207-dpaa2-eth-Add-reset-controls-for-debugfs-stats.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0208-dpaa2-eth-Add-channel-stat.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0209-dpaa2-eth-Update-dpni_set_tx_shaping-cmd-to-v2.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0210-dpaa2-eth-Add-dpni_set_tx_priorities-API.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0211-dpaa2-eth-Update-dpni_get_statistics.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0212-dpaa2-eth-Add-API-for-ceetm_id-tc-in-set-congestion.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0213-dpaa2-eth-Add-CEETM-qdisc-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0214-dpaa2-eth-Re-add-get_link_ksettings-ethtool-op.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0215-dpaa2-eth-Add-support-for-new-link-state-APIs.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0216-dpaa2-eth-Add-autoneg-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0217-dpaa2-eth-Don-t-use-netif_receive_skb_list-for-TCP-f.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0218-bus-fsl-mc-Add-a-new-parameter-to-dprc_scan_objects-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0219-bus-fsl-mc-Extend-functions-from-the-bus-driver-to-b.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0220-bus-fsl-mc-Set-the-QMAN-BMAN-region-flags.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0221-soc-fsl-dpio-Adding-QMAN-multiple-enqueue-interface.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0222-soc-fsl-dpio-QMAN-performance-improvement.-Function-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0223-soc-fsl-dpio-Replace-QMAN-array-mode-by-ring-mode-en.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0224-bus-fsl-mc-add-autorescan-sysfs.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0225-enetc-Configure-the-Time-Aware-Scheduler-via-tc-tapr.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0226-enetc-update-TSN-Qbv-PSPEED-set-according-to-adjust-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0227-enetc-Fix-if_mode-extraction.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0228-enetc-Make-mdio-accessors-more-generic.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0229-enetc-Initialize-SerDes-for-SGMII-and-SXGMII-protoco.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0230-enetc-Drop-redundant-device-node-check.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0231-enetc-Use-DT-protocol-information-to-set-up-the-port.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0232-enetc-Handle-USXGMII-protocol.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0233-enetc-Enable-live-mac-addr-change-for-PF.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0234-enetc-WA-for-MDIO-register-access-issue.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0235-enetc-Clean-up-of-ehtool-stats-len.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0236-enetc-Replace-enetc_gregs-with-a-readers-writer-lock.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0237-enetc-Remove-mdio-bus-on-PF-probe-error-path.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0238-net-mscc-ocelot-break-apart-ocelot_vlan_port_apply.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0239-net-mscc-ocelot-break-apart-vlan-operations-into-oce.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0240-net-mscc-ocelot-break-out-fdb-operations-into-abstra.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0241-net-mscc-ocelot-change-prototypes-of-hwtstamping-ioc.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0242-net-mscc-ocelot-change-prototypes-of-switchdev-port-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0243-net-mscc-ocelot-refactor-struct-ocelot_port-out-of-f.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0244-net-mscc-ocelot-separate-net_device-related-items-ou.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0245-net-mscc-ocelot-refactor-ethtool-callbacks.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0246-net-mscc-ocelot-limit-vlan-ingress-filtering-to-actu.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0247-net-mscc-ocelot-move-port-initialization-into-separa.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0248-net-mscc-ocelot-separate-the-common-implementation-o.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0249-net-mscc-ocelot-initialize-list-of-multicast-address.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0250-net-mscc-ocelot-refactor-adjust_link-into-a-netdev-i.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0251-net-mscc-ocelot-split-assignment-of-the-cpu-port-int.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0252-net-mscc-ocelot-don-t-hardcode-the-number-of-the-CPU.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0253-net-mscc-ocelot-move-resource-ioremap-and-regmap-ini.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0254-net-mscc-ocelot-filter-out-ocelot-SoC-specific-PCS-c.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0255-net-mscc-ocelot-move-invariant-configs-out-of-adjust.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0256-net-mscc-ocelot-create-a-helper-for-changing-the-por.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0257-net-mscc-ocelot-export-a-constant-for-the-tag-length.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0258-net-mscc-ocelot-adjust-MTU-on-the-CPU-port-in-NPI-mo.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0259-net-mscc-ocelot-separate-the-implementation-of-switc.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0260-net-mscc-ocelot-publish-structure-definitions-to-inc.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0261-net-mscc-ocelot-publish-ocelot_sys.h-to-include-soc-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0262-net-dsa-ocelot-add-tagger-for-Ocelot-Felix-switches.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0263-net-dsa-ocelot-add-driver-for-Felix-switch-family.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0264-net-dsa-felix-Fix-CPU-port-assignment-when-not-last-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0265-net-mscc-ocelot-export-ocelot_hwstamp_get-set-functi.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0266-net-mscc-ocelot-convert-to-use-ocelot_get_txtstamp.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0267-net-mscc-ocelot-convert-to-use-ocelot_port_add_txtst.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0268-net-dsa-ocelot-define-PTP-registers-for-felix_vsc995.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0269-net-dsa-ocelot-add-hardware-timestamping-support-for.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0270-net-mscc-ocelot-avoid-incorrect-consuming-in-skbs-li.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0271-net-mscc-ocelot-use-skb-queue-instead-of-skbs-list.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0272-net-mscc-ocelot-tsn-configuration-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0273-net-dsa-ocelot-add-tsn-support-for-felix-switch.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0274-net-dsa-ocelot-alloc-memory-for-dsa-switch-instance.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0284-net-fsl_ppfe-dts-binding-for-ppfe.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0285-staging-fsl_ppfe-eth-header-files-for-pfe-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0286-staging-fsl_ppfe-eth-introduce-pfe-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0287-staging-fsl_ppfe-eth-fix-RGMII-tx-delay-issue.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0288-staging-fsl_ppfe-eth-remove-unused-functions.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0289-staging-fsl_ppfe-eth-fix-read-write-ack-idx-issue.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0290-staging-fsl_ppfe-eth-Make-phy_ethtool_ksettings_get-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0291-staging-fsl_ppfe-eth-add-function-to-update-tmu-cred.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0292-staging-fsl_ppfe-eth-Avoid-packet-drop-at-TMU-queues.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0293-staging-fsl_ppfe-eth-Enable-PFE-in-clause-45-mode.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0294-staging-fsl_ppfe-eth-Disable-autonegotiation-for-2.5.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0295-staging-fsl_ppfe-eth-calculate-PFE_PKT_SIZE-with-SKB.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0296-staging-fsl_ppfe-eth-support-for-userspace-networkin.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0297-staging-fsl_ppfe-eth-unregister-netdev-after-pfe_phy.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0298-staging-fsl_ppfe-eth-HW-parse-results-for-DPDK.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0299-staging-fsl_ppfe-eth-reorganize-pfe_netdev_ops.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0300-staging-fsl_ppfe-eth-use-mask-for-rx-max-frame-len.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0301-staging-fsl_ppfe-eth-define-pfe-ndo_change_mtu-funct.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0302-staging-fsl_ppfe-eth-remove-jumbo-frame-enable-from-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0303-staging-fsl_ppfe-eth-disable-CRC-removal.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0304-staging-fsl_ppfe-eth-handle-ls1012a-errata_a010897.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0305-staging-fsl_ppfe-eth-replace-magic-numbers.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0306-staging-fsl_ppfe-eth-resolve-indentation-warning.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0307-staging-fsl_ppfe-eth-add-fixed-link-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0308-staging-fsl_ppfe-add-support-for-a-char-dev-for-link.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0309-staging-fsl_ppfe-enable-hif-event-from-userspace.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0310-staging-fsl_ppfe-performance-tuning-for-user-space.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0311-staging-fsl_ppfe-eth-Update-to-use-SPDX-identifiers.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0312-staging-fsl_ppfe-eth-misc-clean-up.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0313-staging-fsl_ppfe-eth-reorganize-platform-phy-paramet.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0314-staging-fsl_ppfe-eth-support-single-interface-initia.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0315-net-fsl_ppfe-update-dts-properties-for-phy.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0316-staging-fsl_ppfe-eth-remove-unused-code.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0317-staging-fsl_ppfe-eth-separate-mdio-init-from-mac-ini.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0318-staging-fsl_ppfe-eth-adapt-to-link-mode-based-phydev.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0319-staging-fsl_ppfe-eth-use-generic-soc_device-infra-in.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0320-staging-fsl_ppfe-eth-use-memremap-to-map-RAM-area-us.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0321-staging-fsl_ppfe-eth-remove-fallback-argument-from-d.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0322-staging-fsl_ppfe-eth-prefix-header-search-paths-with.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0323-staging-fsl_ppfe-eth-add-pfe-support-to-Kconfig-and-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0324-staging-fsl_ppfe-eth-Disable-termination-of-CRC-fwd.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0325-net-phy-add-10G-fixed-link-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0326-phy-Add-2.5G-SGMII-interface-mode.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0327-at803x-Address-packet-drops-at-low-traffic-rate-due-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0328-net-phy-Inphi-IN112525_s03-retimer-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0329-net-phy-Inphi-IN112525_s03-retimer-updates.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0330-net-phy-at803x-add-vddio-1v8-and-eee-disable-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0331-drivers-net-phy-aquantia-enable-AQR112-and-AQR412.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0332-drivers-net-phy-aquantia-fix-system-side-protocol-mi.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0333-drivers-net-phy-aquantia-enable-USX-AN-for-USXGMII-p.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0334-net-tsn-netlink-interface-for-APP-layer-to-config-TS.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0335-net-tsn-fix-headfile-voliates-the-new-rule.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0336-enetc-add-support-Credit-Based-Shaper-CBS-for-hardwa.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0337-enetc-add-support-tsn-capabilities-qbv-qci-qbu-cbs.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0338-net-dsa-felix-Fix-probing-allocation-and-cleanup-pat.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0339-LF-368-net-mscc-ocelot-hard-code-VCAP_PORT_CNT-for-F.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0340-LF-368-net-mscc-ocelot-make-ocelot_ace_rule-support-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0341-LF-368-net-mscc-ocelot-add-VCAP-IS2-rule-to-trap-PTP.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0342-LF-376-enetc-disable-EEE-autoneg-by-default.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0343-staging-dpaa2-ethsw-move-port-notifier-per-ethsw.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0344-staging-dpaa2-ethsw-move-port-switchdev-notifier-per.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0345-staging-dpaa2-ethsw-move-port-switchdev-blocking-not.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0346-staging-dpaa2-ethsw-ordered-workqueue-should-be-per-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0347-staging-fsl-dpaa2-mac-do-not-call-dpmac_set_link_sta.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0348-staging-fsl-dpaa2-mac-reverse-order-of-handling-stop.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0349-fsl_qbman-add-dummy-functions-for-probe-deferal-APIs.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0350-sdk_fman-fix-identation-causing-compilation-warnings.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0351-sdk_fman-address-compilation-warning.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0352-soc-fsl-dpio-Enable-ACP-port-in-Linux-QMAN-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0353-staging-fsl-dpaa2-mac-do-not-stop-MAC-when-the-net_d.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0354-bus-fsl-mc-add-the-dpdbg-device-type.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0355-sdk_fman-decrease-log-severity-levels.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0356-sdk_dpaa-ethtool-drop-unused-variable.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0357-sdk_dpaa-ls1043a-errata-memory-related-fixes.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0358-sdk_dpaa-ls1043a-errata-update-and-optimize-the-rest.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0359-sdk_dpaa-ls1043a-errata-re-enable-SG-support-and-rec.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0360-sdk_dpaa-sdk_fman-ls1043a-errata-detect-based-on-DTB.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0361-sdk_dpaa-sdk_fman-ls1034a-errata-update-number-to-A0.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0362-sdk_dpaa-ceetm-remove-references-to-qdisc_lookup.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0363-sdk_dpaa-ceetm-export-the-ceetm_tx-symbol.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0364-sdk_dpaa-ceetm-enable-building-as-a-module.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0365-sdk_dpaa-ceetm-coding-style-cleanup.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0366-LF-697-net-ethernet-freescale-sdk_fman-fix-the-build.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0367-net-mscc-ocelot-Workaround-to-allow-traffic-to-CPU-i.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0377-net-dsa-ocelot-add-NET_VENDOR_MICROSEMI-dependency.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0378-mii-Add-helpers-for-parsing-SGMII-auto-negotiation.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0379-net-phylink-make-QSGMII-a-valid-PHY-mode-for-in-band.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0380-net-phylink-add-support-for-polling-MAC-PCS.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0381-net-dsa-Pass-pcs_poll-flag-from-driver-to-PHYLINK.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0383-enetc-Set-MDIO_CFG_HOLD-to-the-recommended-value-of-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0384-net-mscc-ocelot-make-phy_mode-a-member-of-the-common.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0385-net-mscc-ocelot-export-ANA-DEV-and-QSYS-registers-to.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0386-net-dsa-felix-Add-PCS-operations-for-PHYLINK.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0387-net-phy-vsc8514-enable-in-band-SGMII-auto-negotiatio.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0388-drivers-net-phy-aquantia-Add-XFI-counters.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0389-drivers-net-felix-set-link-based-on-BMSR-not-LPA.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0390-drivers-net-phylink-in-band-AN-for-USXGMII.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0391-drivers-net-phy-don-t-crash-in-phy_read-_write_mmd-w.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0392-drivers-net-dsa-felix-Allow-PHY-to-AN-10-100-1000-wi.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0393-drivers-net-dsa-felix-Handle-PAUSE-Rx-regardless-of-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0394-drivers-net-mscc_ocelot-don-t-flood-unicast-traffic-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0395-LF-183-sdk_fman-add-an-option-for-RTC-1588-timer-ini.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0396-LF-183-ptp-depend-on-FSL_SDK_FMAN_RTC_API-for-ptp_qo.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0397-sdk_dpaa-ceetm-fix-recursive-dependencies.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0398-enetc-add-ioctl-support-for-PHY-related-ops.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0399-staging-fsl_ppfe-eth-Enhance-error-checking-in-platf.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0400-drivers-staging-fsl_qbman-Disable-Portal-Channel-IRQ.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0402-drivers-net-dsa-felix-don-t-restart-PCS-SGMII-AN-if-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0403-net-dsa-felix-Don-t-error-out-on-disabled-ports-with.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0404-LF-457-ocelot-tsn-clean-preempt-interrupt-status.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0406-sdk_qbman-Only-create-debugfs-entries-when-QBMan-is-.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0407-LF-924-net-enetc-Set-MAC-Rx-FIFO-to-recommended-valu.patch delete mode 100644 target/linux/layerscape/patches-5.4/701-net-0408-sdk_fman-fix-CONFIG_COMPAT-leak-during-headers-insta.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0001-Revert-ASoC-fsl_sai-Fix-noise-when-using-EDMA.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0002-Revert-ASoC-fsl_sai-Implement-set_bclk_ratio.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0003-Revert-ASoC-fsl_sai-Add-support-for-imx8qm.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0004-Revert-ASoC-fsl_sai-Add-support-for-imx7ulp-imx8mq.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0005-Revert-ASoC-fsl_sai-Add-support-for-SAI-new-version.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0006-Revert-ASoC-fsl_sai-Update-Tx-Rx-channel-enable-mask.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0007-Revert-ASoC-fsl_sai-Add-registers-definition-for-mul.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0008-Revert-ASoC-Remove-dev_err-usage-after-platform_get_.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0009-Revert-ASoC-fsl_sai-mark-regmap-as-fast_io.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0010-Revert-ASoC-fsl_sai-derive-TX-FIFO-watermark-from-FI.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0011-Revert-ASoC-fsl_sai-add-of_match-data.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0012-MLK-9974-ASoC-fsl_sai-There-is-underrun-detected-in-.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0013-MLK-10611-1-ASoC-fsl-sai-Just-one-device-can-playbac.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0014-MLK-11628-ASoC-fsl_sai-add-initial-value-for-is_slav.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0015-ASoC-fsl-sai-set-xCR4-xCR5-xMR-for-SAI-master-mode.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0016-MLK-12374-ASoC-fsl_sai-Change-the-dev_warn-to-dev_db.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0017-MLK-12786-2-ASoC-fsl_sai-correct-the-clock-source-fo.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0018-MLK-13574-2-ASoC-fsl_sai-refine-driver-for-ip-upgrad.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0019-MLK-13609-ASoC-fsl_sai-fix-for-synchronize-mode.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0020-ASoC-fsl_-e-sai-introduce-shared-interrupt-DT-flag-p.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0021-ASoC-fsl_sai-handle-slave-mode-per-TX-RX-direction.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0022-ASoC-fsl_sai-set-specific-fmt-for-I2S-XTOR.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0024-MLK-14847-Revert-ASoC-fsl-sai-set-xCR4-xCR5-xMR-for-.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0025-MLK-14870-ASoC-fsl_sai-Remove-support-for-S20_3LE.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0026-MLK-14935-ASoC-fsl_sai-Fix-mixing-initialization-dat.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0027-MLK-15140-1-ASoC-fsl_sai-support-latest-sai-module.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0028-MLK-15927-1-ASoC-fsl_sai-Fix-noise-when-using-EDMA.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0029-MLK-15960-1-ASoC-fsl_sai-update-fifo_depth-for-diffe.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0030-MLK-15960-2-ASoC-fsl_sai-refine-the-pm-runtime-funct.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0031-MLK-13975-ASoC-fsl_sai-Refine-master-flag-handling.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0032-MLK-16130-1-ASoC-fsl_sai-enable-TCE-RCE-according-to.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0033-MLK-13946-3-ASoC-fsl_sai-fix-the-xMR-setting.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0034-MLK-13946-8-ASoC-fsl_sai-use-min-channels-slots-for-.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0035-MLK-16929-1-ASoC-fsl_sai-add-bitclk_freq.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0037-MLK-16224-4-ASoC-fsl_sai-support-multi-fifo-and-DSD.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0038-MLK-17467-ASoC-fsl_sai-fix-typo-for-fsl_sai.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0039-MLK-16224-6-ASoC-fsl_sai-fix-DSD-suspend-resume.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0040-MLK-17428-8-ASoC-fsl_sai-support-768KHz-sample-rate.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0041-MLK-17485-ASoC-fsl_sai-Specify-supported-rate_min-an.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0042-MLK-17566-ASoC-fsl_sai-fix-register-definition.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0043-MLK-17528-1-ASoC-fsl_sai-Introduce-FSL_SAI_CLK_BIT-c.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0044-MLK-17528-3-ASoC-fsl_sai-Set-clock-rate-in-set_syscl.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0045-MLK-17156-1-ASoC-fsl_sai-update-register-offset-for-.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0046-Sound-Soc-fsl-Set-SAI-Channel-Mode-to-Output-Mode.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0047-MLK-17580-ASoC-fsl-dsd-Add-DSD-utilities-helper.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0048-MLK-17580-ASoC-fsl-sai-Use-DSD-helper.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0049-MLK-17580-ASoC-fsl-sai-check-for-pinctrl-status.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0050-MLK-17531-1-ASoC-fsl-sai-add-support-for-SAI-v3.01.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0051-MLK-18534-1-ASoC-fsl-sai-introduce-1-1-bclk-mclk-rat.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0052-MLK-18682-1-ASoC-fsl-sai-use-set_bclk_ratio-to-calcu.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0053-MLK-18682-2-ASoC-fsl-sai-allow-dynamic-pll-switching.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0054-MLK-18947-ASoC-fsl_sai-fix-volatile-function.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0055-MLK-18898-1-ASoC-fsl_sai-select-pinctrl-state-as-fun.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0056-MLK-19573-1-ASoC-fsl-dsd-make-fsl_get_pins_state-inl.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0057-MLK-15975-3-ASoC-fsl_sai-The-offset-of-fifo_off-is-c.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0058-MLK-20189-8-ASoC-fsl_sai-use-signed-offset-variable.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0059-MLK-20328-1-ASoC-fsl_sai-map-number-of-pins-to-datal.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0060-ASoC-fsl_sai-Support-EPROBE_DEFER.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0061-ASoC-fsl_sai-support-multi-power-domain.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0062-ASoC-fsl-sai-fix-build-failture-due-to-5.1-RC7-upgra.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0063-MLK-21876-4-ASoC-fsl-sai-fix-build-for-next-20190524.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0064-ASoC-fsl_sai-Mark-cache-dirty-at-resume.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0065-LF-106-ASoC-fsl_sai-request-BUS_FREQ_AUDIO.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0066-MLK-16224-2-ASoC-dmaengine_pcm-add-fifo_num-to-snd_d.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0069-MLK-21484-4-ASoC-fsl_sai-ensure-clk-not-in-use-prior.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0070-MLK-21957-1-ASoC-fsl_sai-remove-reset-code-from-dai_.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0071-MLK-21957-2-ASoC-fsl_sai-read-SAI-version-and-params.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0072-MLK-22522-ASoC-fsl_sai-fix-stack-out-of-bounds-KASAN.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0073-MLK-21957-3-ASoC-fsl_sai-add-bitcount-and-timestamp-.patch delete mode 100644 target/linux/layerscape/patches-5.4/801-audio-0074-ASoC-fsl_sai-fix-build-issue-of-incomplete-parenthes.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0001-imx-busfreq-Add-API-header-file.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0002-can-rx-offload-fix-long-lines.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0003-can-rx-offload-can_rx_offload_compare-fix-typo.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0004-can-rx-offload-can_rx_offload_irq_offload_timestamp-.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0005-can-rx-offload-can_rx_offload_reset-remove-no-op-fun.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0006-can-rx-offload-Prepare-for-CAN-FD-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0007-can-flexcan-use-devm_platform_ioremap_resource-to-si.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0008-can-flexcan-flexcan_irq_state-only-read-timestamp-if.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0009-can-flexcan-rename-macro-FLEXCAN_IFLAG_MB-FLEXCAN_IF.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0010-can-flexcan-flexcan_irq-rename-variable-reg_iflag-re.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0011-can-flexcan-rename-struct-flexcan_priv-reg_imask-1-2.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0012-can-flexcan-remove-TX-mailbox-bit-from-struct-flexca.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0013-can-flexcan-convert-struct-flexcan_priv-rx_mask-1-2-.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0014-can-flexcan-introduce-struct-flexcan_priv-tx_mask-an.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0015-can-flexcan-flexcan_read_reg_iflag_rx-optimize-readi.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0016-can-flexcan-flexcan_irq-add-support-for-TX-mailbox-i.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0017-can-flexcan-flexcan_mailbox_read-make-use-of-flexcan.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0018-can-flexcan-use-struct-canfd_frame-for-CAN-classic-f.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0019-can-flexcan-add-CAN-FD-mode-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0020-can-flexcan-add-CAN-FD-BRS-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0021-can-flexcan-add-ISO-CAN-FD-feature-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0022-can-flexcan-add-Transceiver-Delay-Compensation-suopp.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0023-can-flexcan-add-imx8qm-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0024-can-flexcan-add-lx2160ar1-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0025-can-flexcan-add-LPSR-mode-support-for-i.MX7D.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0026-can-flexcan-fix-deadlock-when-using-self-wakeup.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0027-can-flexcan-add-CAN-wakeup-function-for-i.MX8.patch delete mode 100644 target/linux/layerscape/patches-5.4/802-can-0028-can-flexcan-Add-S32V234-support-to-FlexCAN-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/803-clock-0001-clk-ls1028a-Add-clock-driver-for-Display-output-inte.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0001-crypto-add-support-for-TLS-1.0-record-encryption.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0002-crypto-tcrypt-include-rsa-test.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0003-crypto-caam-use-mapped_-src-dst-_nents-for-descripto.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0004-crypto-caam-use-devres-to-unmap-memory.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0005-crypto-caam-use-devres-to-remove-debugfs.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0006-crypto-caam-use-devres-to-de-initialize-the-RNG.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0007-crypto-caam-use-devres-to-de-initialize-QI.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0008-crypto-caam-use-devres-to-populate-platform-devices.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0009-crypto-caam-populate-platform-devices-last.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0010-MLK-9769-1-crypto-caam-jr-remove-incorrect-comment-f.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0011-MLK-20204-crypto-caam-remove-deadcode-on-32-bit-plat.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0012-MLK-19053-crypto-caam-RNG4-TRNG-errata.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0013-MLK-9769-9-crypto-caam-adjust-RNG-timing-to-support-.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0014-MLK-9769-8-crypto-caam-add-a-test-for-the-RNG.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0015-MLKU-123-1-crypto-caam-add-support-for-i.mx8mm-mn.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0016-MLKU-114-1-crypto-caam-reduce-page-0-regs-access-to-.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0017-MLKU-114-2-crypto-caam-SCU-firmware-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0018-MLKU-114-3-crypto-caam-OP-TEE-firmware-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0019-MLKU-38-3-crypto-caam-add-SNVS-SECVIO-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0020-MLKU-25-3-crypto-caam-add-Secure-Memory-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0021-MLK-19801-1-crypto-caam-add-tag-functionality.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0022-MLK-19801-2-crypto-caam-add-support-of-tagged-keys-i.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0023-MLK-10036-crypto-caam-add-support-for-DSM-with-Mega-.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0024-MLK-19449-crypto-caam-Change-structure-type-represen.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0025-crypto-caam-qi2-add-unused-dpseci-API.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0026-crypto-caam-qi2-add-OPR-Order-Preservation-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0027-crypto-caam-add-support-for-MOVEB-command.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0028-crypto-caam-qi-add-support-for-TLS-1.0-record.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0029-crypto-caam-qi2-add-support-for-TLS-1.0-record.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0030-crypto-caam-add-functionality-used-by-the-caam_dma-d.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0031-crypto-caam-add-caam_dma-device-on-caam_probe.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0032-crypto-caam-add-CAAM-job-ring-UIO-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0033-LFV-26-crypto-caam-fix-Secure-Memory-driver-init.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0034-LF-63-1-crypto-caam-fix-SM-test-init.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0035-crypto-caam-qi-use-QBMan-NXP-SDK-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0036-LF-933-crypto-caam-fix-iosource-busy-issue.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0038-LF-838-crypto-caam-increase-the-domain-of-write-memo.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0040-LF-292-1-crypto-caam-refactor-RNG-initialization.patch delete mode 100644 target/linux/layerscape/patches-5.4/804-crypto-0041-LF-292-2-crypto-caam-add-power-management.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0001-drm-arm-mali-dp-Add-display-QoS-interface-configurat.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0002-drm-rockchip-prepare-common-code-for-cdns-and-rk-dpi.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0003-drm-bridge-add-Cadence-MHDP-HDMI-DP-API.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0004-drm-bridge-Add-Cadence-DP-HDMI-core-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0005-gpu-drm-Add-imx8qm-mq-DP-HDMI-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0006-drm-bridge-cadence-Add-new-api-functions.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0007-drm-bridge-cadence-Add-mhdp-audio-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0008-drm-bridge-cadence-Add-CEC-driver-for-cdns-mhdp-hdmi.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0009-drm-rockchip-Fix-build-failed-issue.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0010-drm-bridge-cadence-move-struct-imx_mhdp_device-to-dr.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0011-drm-imx-add-imx8mq-hdmi-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0012-drm-rockchip-change-base-address-name-from-regs-to-r.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0013-drm-bridge-cadence-Add-power_on-to-__cdns_dp_probe.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0014-drm-ls1028a-Add-DP-driver-support-for-LS1028A.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0015-drm-bridge-cadence-Add-support-for-periodically-poll.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0016-drm-imx-hdmi-support-arc-function.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0017-drm-bridge-cadence-Fix-return-value-for-set-log-addr.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0018-drm-bridge-cdns-dp-Remove-link-rate-lanes-set-by-dev.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0019-drm-imx-mhdp-add-dual-mode-support-for-imx8qm.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0020-drm-bridge-cdns-cec-fix-LA-failed-set-issue.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0021-DRM-mhdp-HDMI-skip-scdc-write-return-check.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0022-drm-mhdp-add-mutex-lock-to-mhdp-register-access-func.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0023-drm-mhdp-reset-video-mode-after-hdmi-dp-cable-plugin.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0024-drm-bridge-cadence-hdmi-remove-video-mode-limition.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0025-drm-imx-hdp-add-hdr10-metadata-property.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0026-drm-imx-hdp-add-colorspace-property.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0027-drm-imx-hdp-force-a-mode-set-when-colorspace-is-chan.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0028-drm-imx-hdp-handle-the-various-deep-color-settings.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0029-drm-imx-mhdp-Adjustment-core-rate-of-DP-TX-CTRL-for-.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0032-drm-hdmi-imx8-fix-wrong-hdmi-type-with-non-SCDC-HDMI.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0033-LF-94-drm-hdmi-imx-Add-hdmi-phy-video-mode-valid-fun.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0034-media-bus-format-Add-RGB888_1X30_PADLO-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0035-media-bus-format-Add-RGB666_1X30_PADLO-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0036-media-bus-format-Add-RGB101010_1X7X5_SPWG-JEIDA-supp.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0037-MLK-15110-1-drm-fourcc-Add-Amphion-tiled-layout-form.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0038-MLK-16290-drm-Add-drm_of_component_probe_with_match-.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0039-MLK-17368-1-drm-add-fourcc-codes-for-Verisilicon-til.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0040-drm-fourcc-add-modifier-for-vivante-compressed-tiled.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0041-drm-fourcc-add-a-10bits-fully-packed-variant-of-NV12.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0045-drm-imx-Add-DPU-KMS-support-part-2.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0046-MLK-22171-drm-imx-Avoid-leaking-dangling-pointer-dev.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0047-MLK-18535-6-drm-imx-core-add-LCDIF-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0051-LF-296-drm-mhdp-build-mhdp-sub-modules-into-one-driv.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0052-LF-323-1-drm-bridge-cdns-move-link-training-to-bridg.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0053-LF-323-2-drm-bridge-cdns-enhance-link-training-stabi.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0054-LF-568-1-drm-bridge-cdns-dp-change-bridge_enable-dis.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0055-LF-568-2-drm-gpu-bridge-cdns-Add-force-mode-set-flag.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0056-LF-794-3-gpu-cdn-imx8qm-Add-firmware-loading-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/805-display-0057-LF-794-4-gpu-cdn-mhdp-common-Increase-the-check-aliv.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0001-dmaengine-fsl-dpaa2-qdma-Add-the-DPDMAI-Data-Path-DM.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0002-dmaengine-fsl-dpaa2-qdma-Add-NXP-dpaa2-qDMA-controll.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0003-MLK-14610-DMA-fsl-edma-v3-add-fsl-edma-v3-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0004-MLK-15003-1-DMA-fsl-edma-v3-add-one-more-parameter-f.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0005-MLK-15003-2-Document-fsl_edma_v3-update-document.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0006-MLK-15014-dma-fsl-edma-v3-clear-DONE-before-E_SG-ena.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0007-MLK-15330-1-dma-fsl-edma-v3-combine-two-cells-into-o.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0008-MLK-15330-3-dma-fsl-edma-v3-add-dual-fifo-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0009-MLK-16327-1-dma-fsl-edma-v3-make-exclusive-channel-n.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0010-MLK-16437-dma-fsl-edma-v3-fix-kernel-crash-while-edm.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0011-MLK-16482-dma-fsl-edma-v3-Fix-RCU-issue-while-playin.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0012-MLK-17094-dma-fsl-edma-v3-add-suspend-resume-to-rest.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0013-MLK-17782-dma-fsl-edma-v3-fix-issue-reported-by-Cove.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0014-MLK-18248-dma-fsl-edma-v3-avoid-touch-unused-edma-ch.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0015-MLK-19022-2-dmaengine-fsl-edma-v3-add-device_synchro.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0016-MLK-19931-1-dmaengine-fsl-edma-v3-fix-potential-kern.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0017-MLK-20205-1-dmaengine-fsl-edma-v3-fix-NULL-pointer-d.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0018-dma-imx-add-the-32bit-dma-limitation.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0019-dmaengine-fsl-edma-calculate-the-real-count-for-slav.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0020-MLK-22798-1-dmaengine-fsl-edma-v3-do-not-enable-inte.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0021-MLK-21443-dmaengine-fsl-edma-v3-clear-pending-irq-be.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0022-MLK-22284-1-dmaengine-fsl-edma-v3-add-power-domains-.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0023-MLK-22284-2-dmaengine-fsl-edma-v3-check-dma-descript.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0024-MLK-22302-2-dmaengine-fsl-edma-v3-fix-build-warning-.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0025-MLK-22909-dmaengine-fsl-edma-v3-clear-interrupt-comi.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0026-dma-caam-add-dma-memcpy-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0027-dma-caam-fix-compilation-error.patch delete mode 100644 target/linux/layerscape/patches-5.4/806-dma-0028-dmaengine-fsl-edma-Add-eDMA-support-for-QorIQ-LS1028.patch delete mode 100644 target/linux/layerscape/patches-5.4/807-gpio-0001-gpio-mpc8xxx-change-irq-handler-from-chained-to-norm.patch delete mode 100644 target/linux/layerscape/patches-5.4/807-gpio-0002-gpio-mpc8xxx-ls1088a-ls1028a-edge-detection-mode-bug.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0001-MLK-16095-01-i2c-mux-pca954x-add-i2c-bus-switch-PCA9.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0002-MLK-10893-i2c-imx-add-irqf_no_suspend.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0003-MLK-11403-I2C-imx-restore-pin-setting-for-i2c.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0004-MLK-16203-enable-runtime-pm-of-i2c-temporary-when-do.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0005-MLK-20773-i2c-imx-add-a-limit-of-maximum-transfer-sp.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0006-MLK-20368-i2c-imx-Coverity-fix-divide-by-zero-warnin.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0007-i2c-imx-add-workaround-for-erratum-ERR010027.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0008-i2c-imx-implement-bus-recovery-with-gpio-for-Layersc.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0009-i2c-imx-get-rid-of-CONFIG_ARCH_LAYERSCAPE.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0010-i2c-imx-fix-system-hang-due-to-access-i2c-registers-.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0011-i2c-imx-support-slave-mode-for-imx-I2C-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0012-i2c-imx-correct-code-of-errata-A-010650-for-layersca.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0013-LF-98-i2c-imx-fix-the-judgement-of-slave-mode-in-isr.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0014-i2c-mux-pca954x-support-property-idle-state.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0015-LF-263-2-i2c-imx-increase-PM-timeout-to-avoid-operat.patch delete mode 100644 target/linux/layerscape/patches-5.4/808-i2c-0016-LF-162-i2c-imx-Defer-probing-if-EDMA-not-available.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0001-ivshmem-net-virtual-network-device-for-Jailhouse.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0002-ivshmem-net-Map-shmem-region-as-RAM.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0003-ivshmem-net-fix-race-in-state-machine.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0004-ivshmem-net-Remove-unused-variable.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0005-ivshmem-net-Enable-INTx.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0006-ivshmem-net-Improve-identification-of-resources.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0007-ivshmem-net-Switch-to-reset-state-on-each-net-stop-a.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0008-ivshmem-net-Add-ethtool-register-dump.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0009-ivshmem-net-Fix-stuck-state-machine-during-setup.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0010-ivshmem-net-Switch-to-relative-descriptor-addresses.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0011-ivshmem-net-Switch-to-pci_alloc_irq_vectors.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0012-ivshmem-net-fill-in-and-check-used-descriptor-chain-.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0013-ivshmem-net-slightly-improve-debug-output.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0014-ivshmem-net-set-and-check-descriptor-flags.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0015-ivshmem-net-add-MAC-changing-interface.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0016-ivshmem-net-Silence-compiler-warning.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0017-ivshmem-net-Fix-bogus-transition-to-RESET-state.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0018-ivshmem-net-Refactor-and-comment-ivshm_net_state_cha.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0019-ivshmem-net-Switch-to-netdev_xmit_more-helper.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0020-jailhouse-Add-simple-debug-console-via-the-hyperviso.patch delete mode 100644 target/linux/layerscape/patches-5.4/809-jailhouse-0021-arm64-export-__hyp_stub_vectors.patch delete mode 100644 target/linux/layerscape/patches-5.4/810-keys-0001-security-keys-secure_key-Adds-the-secure-key-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/810-keys-0002-encrypted_keys-Adds-support-for-secure-key-type-as-m.patch delete mode 100644 target/linux/layerscape/patches-5.4/810-keys-0003-security-keys-secure_key-Fix-the-path-of-included-he.patch delete mode 100644 target/linux/layerscape/patches-5.4/811-kvm-0001-arm64-KVM-support-flushing-device-memory.patch delete mode 100644 target/linux/layerscape/patches-5.4/811-kvm-0002-arm-arm64-KVM-allow-specifying-s2-prot-bits-when-map.patch delete mode 100644 target/linux/layerscape/patches-5.4/811-kvm-0003-arm-arm64-KVM-drop-qman-mmio-cacheable-mapping-hack.patch delete mode 100644 target/linux/layerscape/patches-5.4/811-kvm-0004-virt-vgic-Increase-number-of-DeviceIDs-to-17.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0001-PCI-layerscape-Add-LS1028a-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0002-PCI-dwc-Use-interrupt-disabling-instead-of-masking.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0003-PCI-dwc-fix-the-msi-failure-after-pm-operations.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0004-pci-add-support-aer-pme-interrupts-with-none-MSI-MSI.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0005-MLK-20684-PCI-Disable-MSI-on-CYW4356-and-CYW4359-chi.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0006-MLK-20716-PCI-add-quirk-for-cyw4356-to-disable-D3-mo.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0007-PCI-Disable-MSI-on-marvel-88w9098-and-88w8997-chips.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0008-Revert-PCI-mobiveil-Fix-csr_read-write-build-issue.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0009-PCI-mobiveil-Refactor-Mobiveil-PCIe-Host-Bridge-IP-d.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0010-PCI-mobiveil-Make-mobiveil_host_init-can-be-used-to-.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0011-PCI-mobiveil-Add-8-bit-and-16-bit-CSR-register-acces.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0012-PCI-mobiveil-Add-PCIe-Gen4-RC-driver-for-NXP-Layersc.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0013-PCI-mobiveil-ls_pcie_g4-add-Workaround-for-A-011577.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0014-PCI-mobiveil-ls_pcie_g4-add-Workaround-for-A-011451.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0015-PCI-ls_gen4-WA-for-SERROR.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0016-PCI-mobiveil-Add-the-EP-driver-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0017-PCI-mobiveil-Add-PCIe-Gen4-EP-driver-for-NXP-Layersc.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0018-PCI-mobiveil-Add-workaround-for-unsupported-request-.patch delete mode 100644 target/linux/layerscape/patches-5.4/812-pcie-0019-misc-pci_endpoint_test-Add-the-layerscape-PCIe-GEN4-.patch delete mode 100644 target/linux/layerscape/patches-5.4/813-pm-0001-soc-fsl-add-RCPM-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/813-pm-0002-fsl_pmc-update-device-bindings.patch delete mode 100644 target/linux/layerscape/patches-5.4/813-pm-0003-drivers-soc-fsl-add-EPU-FSM-configuration-for-deep-s.patch delete mode 100644 target/linux/layerscape/patches-5.4/813-pm-0004-PM-wakeup-Add-routine-to-help-fetch-wakeup-source-ob.patch delete mode 100644 target/linux/layerscape/patches-5.4/813-pm-0005-soc-fsl-handle-RCPM-errata-A-008646-on-SoC-LS1021A.patch delete mode 100644 target/linux/layerscape/patches-5.4/813-pm-0006-soc-fsl-rcpm-remove-build-warning.patch delete mode 100644 target/linux/layerscape/patches-5.4/814-qe-0001-irqchip-qeic-move-qeic-driver-from-drivers-soc-fsl-q.patch delete mode 100644 target/linux/layerscape/patches-5.4/814-qe-0002-irqchip-qeic-merge-qeic-init-code-from-platforms-to-.patch delete mode 100644 target/linux/layerscape/patches-5.4/814-qe-0003-irqchip-qeic-merge-qeic_of_init-into-qe_ic_init.patch delete mode 100644 target/linux/layerscape/patches-5.4/814-qe-0004-irqchip-qeic-remove-PPCisms-for-QEIC.patch delete mode 100644 target/linux/layerscape/patches-5.4/814-qe-0005-QE-remove-PPCisms-for-QE.patch delete mode 100644 target/linux/layerscape/patches-5.4/814-qe-0006-config-qe-add-irq-qeic-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/815-sata-0001-ahci-qoriq-enable-acpi-support-in-qoriq-ahci-driver.patch delete mode 100644 target/linux/layerscape/patches-5.4/815-sata-0002-ahci-qoriq-workaround-for-errata-A-379364-on-lx2160a.patch delete mode 100644 target/linux/layerscape/patches-5.4/815-sata-0003-ahci_qoriq-bug-fix-for-ecc_addr.patch delete mode 100644 target/linux/layerscape/patches-5.4/816-sdhc-0001-mmc-sdhci-of-esdhc-poll-ESDHC_FLUSH_ASYNC_FIFO-bit-u.patch delete mode 100644 target/linux/layerscape/patches-5.4/816-sdhc-0002-LF-605-mmc-sdhci-of-esdhc-convert-to-use-esdhc_tunin.patch delete mode 100644 target/linux/layerscape/patches-5.4/816-sdhc-0003-LF-605-mmc-sdhci-of-esdhc-update-tuning-erratum-A-00.patch delete mode 100644 target/linux/layerscape/patches-5.4/817-spi-0001-spi-spi-fsl-qspi-dynamically-alloc-AHB-memory-for-QS.patch delete mode 100644 target/linux/layerscape/patches-5.4/817-spi-0002-spi-spi-fsl-qspi-Introduce-variable-to-fix-different.patch delete mode 100644 target/linux/layerscape/patches-5.4/817-spi-0003-MLK-21960-1-spi-fspi-enable-fspi-on-imx8qxp-and-imx8.patch delete mode 100644 target/linux/layerscape/patches-5.4/817-spi-0004-MLK-21960-2-spi-fspi-dynamically-alloc-AHB-memory.patch delete mode 100644 target/linux/layerscape/patches-5.4/817-spi-0005-spi-spi-nxp-fspi-Enable-the-Octal-Mode-in-MCR0.patch delete mode 100644 target/linux/layerscape/patches-5.4/817-spi-0006-LF-20-2-mtd-spi-nor-Use-1-bit-mode-of-spansion-s25fs.patch delete mode 100644 target/linux/layerscape/patches-5.4/817-spi-0007-LF-18-3-spi-fsl-qspi-Allocate-AHB-memory-dynamically.patch delete mode 100644 target/linux/layerscape/patches-5.4/818-thermal-0001-thermal-Add-generic-device-cooling-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/818-thermal-0002-thermal-qoriq-Add-device-cooling-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/818-thermal-0003-thermal-qoriq-add-thermal-monitor-unit-version-2-sup.patch delete mode 100644 target/linux/layerscape/patches-5.4/818-thermal-0004-thermal-qoriq-Update-the-settings-for-TMUv2.patch delete mode 100644 target/linux/layerscape/patches-5.4/819-uart-0001-tty-serial-lpuart-add-power-domain-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/819-uart-0002-tty-serial-fsl_lpuart-add-modem-device-reset.patch delete mode 100644 target/linux/layerscape/patches-5.4/819-uart-0003-tty-serial-fsl_lpuart-add-magic-SysRq-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/819-uart-0005-tty-serial-fsl_lpuart-enable-dma-mode-for-imx8qxp.patch delete mode 100644 target/linux/layerscape/patches-5.4/819-uart-0006-tty-serial-fsl_lpuart-enable-loopback-mode.patch delete mode 100644 target/linux/layerscape/patches-5.4/819-uart-0007-MLK-15094-tty-serial-fsl_lpuart-check-dma_tx_in_prog.patch delete mode 100644 target/linux/layerscape/patches-5.4/819-uart-0008-MLK-21445-serial-fsl_lpuart-do-HW-reset-for-communic.patch delete mode 100644 target/linux/layerscape/patches-5.4/819-uart-0009-MLK-17133-02-tty-serial-lpuart-add-runtime-pm-suppor.patch delete mode 100644 target/linux/layerscape/patches-5.4/819-uart-0010-tty-serial-lpuart-enable-wakeup-source-for-lpuart.patch delete mode 100644 target/linux/layerscape/patches-5.4/819-uart-0011-serial-fsl_lpuart-enable-two-stop-bits.patch delete mode 100644 target/linux/layerscape/patches-5.4/819-uart-0013-LF-484-tty-serial-lpuart-support-UPIO_MEM32-for-lpua.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0001-MLK-11340-26-usb-phy-add-notify-suspend-and-resume-c.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0002-MLK-14285-1-usb-phy-add-usb-mode-for-usb_phy.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0003-usb-phy-show-USB-charger-type-for-user.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0004-usb-dwc3-use-suspend-clock-from-dt-to-set-power-down.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0005-usb-dwc3-add-otg-properties-update.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0006-usb-dwc3-drd-add-usb-role-switch-class-support-for-d.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0008-usb-dwc3-set-fwnode-for-role-switch.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0009-usb-dwc3-Add-workaround-for-host-mode-VBUS-glitch-wh.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0010-MLK-22675-usb-dwc3-host-disable-park-mode.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0011-usb-dwc3-Add-cache-type-configuration-support.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0012-MLK-11340-40-usb-whitelist-update-otg-eh-s-TPL-for-f.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0013-MLK-9785-1-usb-host-ehci-hcd-enable-park-mode.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0014-MLK-17380-3-usb-move-EH-SINGLE_STEP_SET_FEATURE-impl.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0015-MLK-17380-4-usb-host-xhci-add-EH-SINGLE_STEP_SET_FEA.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0016-MLK-16735-usb-host-add-XHCI_CDNS_HOST-flag.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0017-MLK-19153-2-usb-host-xhci-do-not-return-error-status.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0018-MLK-18794-1-usb-host-xhci-add-.bus_suspend-override.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0019-MLK-9829-usb-core-print-suggested-message-if-failed-.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0020-MLK-16604-1-usb-host-xhci-plat-add-XHCI_MISSING_CAS-.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0021-MLK-22099-usb-host-xhci-do-warm-reset-for-link-state.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0022-usb-fsl-Remove-unused-variable.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0023-usb-gadget-Correct-NULL-pointer-checking-in-fsl-gadg.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0024-LF-387-1-Revert-usb-dwc3-Add-cache-type-configuratio.patch delete mode 100644 target/linux/layerscape/patches-5.4/820-usb-0025-LF-387-4-usb-dwc3-Add-cache-type-configuration-suppo.patch delete mode 100644 target/linux/layerscape/patches-5.4/821-vfio-0001-vfio-fsl-mc-Add-VFIO-framework-skeleton-for-fsl-mc-d.patch delete mode 100644 target/linux/layerscape/patches-5.4/821-vfio-0002-vfio-fsl-mc-Scan-DPRC-objects-on-vfio-fsl-mc-driver-.patch delete mode 100644 target/linux/layerscape/patches-5.4/821-vfio-0003-vfio-fsl-mc-Implement-VFIO_DEVICE_GET_INFO-ioctl.patch delete mode 100644 target/linux/layerscape/patches-5.4/821-vfio-0004-vfio-fsl-mc-Implement-VFIO_DEVICE_GET_REGION_INFO-io.patch delete mode 100644 target/linux/layerscape/patches-5.4/821-vfio-0005-vfio-fsl-mc-Allow-userspace-to-MMAP-fsl-mc-device-MM.patch delete mode 100644 target/linux/layerscape/patches-5.4/821-vfio-0006-vfio-fsl-mc-Added-lock-support-in-preparation-for-in.patch delete mode 100644 target/linux/layerscape/patches-5.4/821-vfio-0007-vfio-fsl-mc-Add-irq-infrastructure-for-fsl-mc-device.patch delete mode 100644 target/linux/layerscape/patches-5.4/821-vfio-0008-vfio-fsl-mc-trigger-an-interrupt-via-eventfd.patch delete mode 100644 target/linux/layerscape/patches-5.4/821-vfio-0009-vfio-fsl-mc-Add-read-write-support-for-fsl-mc-device.patch delete mode 100644 target/linux/layerscape/patches-5.4/821-vfio-0010-vfio-fsl-mc-Map-the-VFIO-region-according-to-the-fla.patch delete mode 100644 target/linux/layerscape/patches-5.4/900-layerscape_fix_support_of_LS1012A-RDB.patch delete mode 100644 target/linux/layerscape/patches-5.4/901-fix_irq_type_of_pca953x.patch delete mode 100644 target/linux/layerscape/patches-5.4/902-layerscape_improve_support_of_LS1012A-FRDM.patch (limited to 'target/linux/layerscape') diff --git a/target/linux/layerscape/armv7/config-5.4 b/target/linux/layerscape/armv7/config-5.4 deleted file mode 100644 index d1577e9bbe..0000000000 --- a/target/linux/layerscape/armv7/config-5.4 +++ /dev/null @@ -1,673 +0,0 @@ -CONFIG_AD525X_DPOT=y -CONFIG_AD525X_DPOT_I2C=y -# CONFIG_AD525X_DPOT_SPI is not set -CONFIG_ALIGNMENT_TRAP=y -CONFIG_APDS9802ALS=y -CONFIG_AQUANTIA_PHY=y -CONFIG_ARCH_32BIT_OFF_T=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y -CONFIG_ARCH_MULTIPLATFORM=y -CONFIG_ARCH_MULTI_V6_V7=y -CONFIG_ARCH_MULTI_V7=y -CONFIG_ARCH_MXC=y -CONFIG_ARCH_NR_GPIO=0 -CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y -CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARM=y -CONFIG_ARM_APPENDED_DTB=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_ATAG_DTB_COMPAT=y -CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y -CONFIG_ARM_CPUIDLE=y -CONFIG_ARM_CPU_SUSPEND=y -CONFIG_ARM_ERRATA_430973=y -CONFIG_ARM_ERRATA_643719=y -CONFIG_ARM_ERRATA_720789=y -CONFIG_ARM_ERRATA_754322=y -CONFIG_ARM_ERRATA_754327=y -CONFIG_ARM_ERRATA_764369=y -CONFIG_ARM_ERRATA_775420=y -CONFIG_ARM_ERRATA_798181=y -CONFIG_ARM_GIC=y -CONFIG_ARM_HAS_SG_CHAIN=y -CONFIG_ARM_HEAVY_MB=y -# CONFIG_ARM_HIGHBANK_CPUIDLE is not set -# CONFIG_ARM_IMX_CPUFREQ_DT is not set -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_L1_CACHE_SHIFT_6=y -CONFIG_ARM_LPAE=y -CONFIG_ARM_PATCH_IDIV=y -CONFIG_ARM_PATCH_PHYS_VIRT=y -CONFIG_ARM_PSCI=y -CONFIG_ARM_PSCI_FW=y -# CONFIG_ARM_SMMU is not set -CONFIG_ARM_THUMB=y -CONFIG_ARM_THUMBEE=y -CONFIG_ARM_UNWIND=y -CONFIG_ARM_VIRT_EXT=y -CONFIG_AT803X_PHY=y -# CONFIG_AT803X_PHY_SMART_EEE is not set -CONFIG_ATAGS=y -CONFIG_AUTOFS4_FS=y -CONFIG_AUTOFS_FS=y -CONFIG_AUTO_ZRELADDR=y -CONFIG_BATTERY_SBS=y -CONFIG_BCM_NET_PHYLIB=y -CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y -CONFIG_BLK_CMDLINE_PARSER=y -CONFIG_BLK_DEV_BSG=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=262144 -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_MQ_VIRTIO=y -CONFIG_BLK_PM=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -CONFIG_BOUNCE=y -CONFIG_BRCMSTB_GISB_ARB=y -CONFIG_BROADCOM_PHY=y -CONFIG_CACHE_L2X0=y -CONFIG_CDROM=y -CONFIG_CHECKPOINT_RESTORE=y -CONFIG_CHR_DEV_SG=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLKSRC_IMX_GPT=y -CONFIG_CLKSRC_MMIO=y -CONFIG_CLK_QORIQ=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=8 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=64 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -CONFIG_CMDLINE_PARTITION=y -CONFIG_COMMON_CLK=y -CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CONFIGFS_FS=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_CONTIG_ALLOC=y -CONFIG_COREDUMP=y -CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_SPECTRE=y -CONFIG_CPU_THERMAL=y -CONFIG_CPU_THUMB_CAPABLE=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_V7=y -CONFIG_CRASH_CORE=y -CONFIG_CRC16=y -# CONFIG_CRC32_SARWATE is not set -CONFIG_CRC32_SLICEBY8=y -CONFIG_CROSS_MEMORY_ATTACH=y -CONFIG_CRYPTO_ACOMP2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_RNG2=y -# CONFIG_CRYPTO_TLS is not set -CONFIG_CRYPTO_ZSTD=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" -CONFIG_DECOMPRESS_BZIP2=y -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_LZMA=y -CONFIG_DECOMPRESS_LZO=y -CONFIG_DECOMPRESS_XZ=y -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_DEVFREQ_GOV_PASSIVE is not set -# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set -# CONFIG_DEVFREQ_GOV_POWERSAVE is not set -# CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set -# CONFIG_DEVFREQ_GOV_USERSPACE is not set -# CONFIG_DEVFREQ_THERMAL is not set -# CONFIG_DEVICE_THERMAL is not set -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_DMADEVICES=y -CONFIG_DMA_CMA=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_OF=y -CONFIG_DMA_REMAP=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -CONFIG_DNOTIFY=y -CONFIG_DTC=y -CONFIG_DT_IDLE_STATES=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_DW_DMAC=y -CONFIG_DW_DMAC_CORE=y -CONFIG_DW_WATCHDOG=y -CONFIG_EDAC_ATOMIC_SCRUB=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EEPROM_93CX6=y -CONFIG_EEPROM_AT24=y -CONFIG_ELF_CORE=y -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -CONFIG_F2FS_FS=y -CONFIG_FAILOVER=y -CONFIG_FAT_FS=y -# CONFIG_FEC is not set -CONFIG_FHANDLE=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FORCE_MAX_ZONEORDER=12 -CONFIG_FREEZER=y -CONFIG_FSL_EDMA=y -# CONFIG_FSL_EDMA_V3 is not set -CONFIG_FSL_GUTS=y -CONFIG_FSL_IFC=y -# CONFIG_FSL_PPFE is not set -CONFIG_FSL_PQ_MDIO=y -# CONFIG_FSL_QIXIS is not set -CONFIG_FSL_RCPM=y -# CONFIG_FSL_SDK_DPA is not set -CONFIG_FSL_XGMAC_MDIO=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FS_POSIX_ACL=y -CONFIG_FTRACE=y -# CONFIG_FTRACE_SYSCALLS is not set -CONFIG_FUSE_FS=y -CONFIG_FW_LOADER_PAGED_BUF=y -# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_CHIP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_PINCONF=y -CONFIG_GENERIC_PINCTRL_GROUPS=y -CONFIG_GENERIC_PINMUX_FUNCTIONS=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -CONFIG_GIANFAR=y -CONFIG_GLOB=y -CONFIG_GPIOLIB=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_GENERIC_PLATFORM=y -CONFIG_GPIO_MPC8XXX=y -CONFIG_GPIO_MXC=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HAVE_SMP=y -CONFIG_HID=y -CONFIG_HID_GENERIC=y -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -CONFIG_HOTPLUG_CPU=y -CONFIG_HVC_DRIVER=y -CONFIG_HW_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_IMX_RNGC=y -CONFIG_HZ_FIXED=0 -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_DEMUX_PINCTRL=y -CONFIG_I2C_DESIGNWARE_CORE=y -CONFIG_I2C_DESIGNWARE_PLATFORM=y -# CONFIG_I2C_DESIGNWARE_SLAVE is not set -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_IMX=y -# CONFIG_I2C_IMX_LPI2C is not set -CONFIG_I2C_MUX=y -CONFIG_I2C_MUX_PCA954x=y -CONFIG_I2C_MUX_PINCTRL=y -CONFIG_I2C_RK3X=y -CONFIG_I2C_SLAVE=y -CONFIG_I2C_SLAVE_EEPROM=y -CONFIG_I2C_XILINX=y -CONFIG_ICPLUS_PHY=y -CONFIG_ICS932S401=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_IMX2_WDT=y -# CONFIG_IMX7ULP_WDT is not set -CONFIG_IMX_DMA=y -# CONFIG_IMX_GPCV2_PM_DOMAINS is not set -# CONFIG_IMX_IRQSTEER is not set -CONFIG_IMX_SDMA=y -# CONFIG_IMX_WEIM is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_INPHI_PHY is not set -CONFIG_INPUT=y -# CONFIG_INPUT_MISC is not set -# CONFIG_IOMMU_DEBUGFS is not set -# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set -# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set -CONFIG_IOMMU_SUPPORT=y -CONFIG_IPC_NS=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_WORK=y -# CONFIG_ISDN is not set -CONFIG_ISL29003=y -# CONFIG_IVSHMEM_NET is not set -CONFIG_JBD2=y -CONFIG_KALLSYMS=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_XZ is not set -CONFIG_KEXEC=y -CONFIG_KEXEC_CORE=y -CONFIG_LIBFDT=y -CONFIG_LOCALVERSION_AUTO=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LS_SCFG_MSI=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MANDATORY_FILE_LOCKING=y -CONFIG_MARVELL_PHY=y -CONFIG_MCPM=y -CONFIG_MDIO_BITBANG=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_DEVICE=y -# CONFIG_MDIO_GPIO is not set -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_MFD_SYSCON=y -# CONFIG_MFD_VEXPRESS_SYSREG is not set -CONFIG_MICREL_PHY=y -CONFIG_MIGHT_HAVE_CACHE_L2X0=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=16 -# CONFIG_MMC_MXC is not set -CONFIG_MMC_SDHCI=y -# CONFIG_MMC_SDHCI_ESDHC_IMX is not set -CONFIG_MMC_SDHCI_IO_ACCESSORS=y -CONFIG_MMC_SDHCI_OF_ESDHC=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MODULES_USE_ELF_REL=y -CONFIG_MSDOS_FS=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_DATAFLASH=y -# CONFIG_MTD_DATAFLASH_OTP is not set -# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set -CONFIG_MTD_NAND_CORE=y -CONFIG_MTD_NAND_ECC_SW_HAMMING=y -CONFIG_MTD_NAND_FSL_IFC=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_RAW_NAND=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y -CONFIG_MTD_SST25L=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -# CONFIG_MTD_UBI_BLOCK is not set -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MUTEX_SPIN_ON_OWNER=y -CONFIG_MX3_IPU=y -CONFIG_MX3_IPU_IRQS=4 -CONFIG_MXC_CLK=y -# CONFIG_MXS_DMA is not set -CONFIG_NAMESPACES=y -CONFIG_NATIONAL_PHY=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEON=y -CONFIG_NET_FAILOVER=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_NS=y -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NLS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_UTF8=y -CONFIG_NO_HZ=y -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=16 -CONFIG_NTFS_FS=y -CONFIG_NVMEM=y -# CONFIG_NVMEM_IMX_IIM is not set -# CONFIG_NVMEM_SNVS_LPGPR is not set -CONFIG_NVMEM_SYSFS=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_DYNAMIC=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_OF_NET=y -CONFIG_OLD_SIGACTION=y -CONFIG_OLD_SIGSUSPEND3=y -CONFIG_OUTER_CACHE=y -CONFIG_OUTER_CACHE_SYNC=y -CONFIG_PACKET_DIAG=y -CONFIG_PADATA=y -CONFIG_PAGE_OFFSET=0xC0000000 -# CONFIG_PANIC_ON_OOPS is not set -CONFIG_PANIC_ON_OOPS_VALUE=0 -CONFIG_PANIC_TIMEOUT=0 -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEASPM=y -# CONFIG_PCIEASPM_DEBUG is not set -CONFIG_PCIEASPM_DEFAULT=y -# CONFIG_PCIEASPM_PERFORMANCE is not set -# CONFIG_PCIEASPM_POWERSAVE is not set -# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_DW=y -CONFIG_PCIE_DW_HOST=y -CONFIG_PCIE_PME=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_ECAM=y -CONFIG_PCI_HOST_COMMON=y -CONFIG_PCI_HOST_GENERIC=y -# CONFIG_PCI_IMX6 is not set -CONFIG_PCI_LAYERSCAPE=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PERF_USE_VMALLOC=y -CONFIG_PGTABLE_LEVELS=3 -CONFIG_PHYLIB=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_PID_NS=y -CONFIG_PINCTRL=y -CONFIG_PL310_ERRATA_588369=y -CONFIG_PL310_ERRATA_727915=y -CONFIG_PL310_ERRATA_753970=y -CONFIG_PL310_ERRATA_769419=y -CONFIG_PM=y -CONFIG_PM_CLK=y -CONFIG_PM_DEVFREQ=y -# CONFIG_PM_DEVFREQ_EVENT is not set -CONFIG_PM_OPP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_BRCMKONA=y -CONFIG_POWER_RESET_BRCMSTB=y -CONFIG_POWER_RESET_GPIO=y -CONFIG_POWER_RESET_GPIO_RESTART=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_POWER_RESET_SYSCON_POWEROFF=y -CONFIG_POWER_RESET_VEXPRESS=y -CONFIG_POWER_SUPPLY=y -CONFIG_PPS=y -CONFIG_PRINTK_TIME=y -CONFIG_PROC_CHILDREN=y -CONFIG_PROC_PAGE_MONITOR=y -CONFIG_PSTORE=y -# CONFIG_PSTORE_842_COMPRESS is not set -CONFIG_PSTORE_COMPRESS=y -CONFIG_PSTORE_COMPRESS_DEFAULT="deflate" -CONFIG_PSTORE_CONSOLE=y -CONFIG_PSTORE_DEFLATE_COMPRESS=y -CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT=y -# CONFIG_PSTORE_LZ4HC_COMPRESS is not set -# CONFIG_PSTORE_LZ4_COMPRESS is not set -# CONFIG_PSTORE_LZO_COMPRESS is not set -CONFIG_PSTORE_PMSG=y -CONFIG_PSTORE_RAM=y -# CONFIG_PSTORE_ZSTD_COMPRESS is not set -CONFIG_PTP_1588_CLOCK=y -CONFIG_PTP_1588_CLOCK_QORIQ=y -CONFIG_QORIQ_CPUFREQ=y -# CONFIG_QUICC_ENGINE is not set -CONFIG_RAS=y -CONFIG_RATIONAL=y -CONFIG_RD_BZIP2=y -CONFIG_RD_GZIP=y -CONFIG_RD_LZMA=y -CONFIG_RD_LZO=y -CONFIG_RD_XZ=y -CONFIG_REALTEK_PHY=y -CONFIG_REED_SOLOMON=y -CONFIG_REED_SOLOMON_DEC8=y -CONFIG_REED_SOLOMON_ENC8=y -CONFIG_REFCOUNT_FULL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RPS=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_DRV_CMOS is not set -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_DS3232=y -CONFIG_RTC_DRV_EM3027=y -CONFIG_RTC_DRV_FSL_FTM_ALARM=y -# CONFIG_RTC_DRV_IMXDI is not set -# CONFIG_RTC_DRV_MXC is not set -# CONFIG_RTC_DRV_MXC_V2 is not set -CONFIG_RTC_DRV_PCF2127=y -CONFIG_RTC_I2C_AND_SPI=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_SCHED_DEBUG=y -CONFIG_SCSI=y -CONFIG_SECCOMP=y -CONFIG_SECCOMP_FILTER=y -# CONFIG_SECURITY_DMESG_RESTRICT is not set -CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_8250_DWLIB=y -CONFIG_SERIAL_8250_EM=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_BCM63XX=y -CONFIG_SERIAL_BCM63XX_CONSOLE=y -CONFIG_SERIAL_CONEXANT_DIGICOLOR=y -CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE=y -CONFIG_SERIAL_FSL_LPUART=y -CONFIG_SERIAL_FSL_LPUART_CONSOLE=y -CONFIG_SERIAL_IMX=y -CONFIG_SERIAL_IMX_CONSOLE=y -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SERIAL_ST_ASC=y -CONFIG_SERIAL_ST_ASC_CONSOLE=y -CONFIG_SERIAL_XILINX_PS_UART=y -CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y -CONFIG_SGL_ALLOC=y -CONFIG_SG_POOL=y -CONFIG_SLUB_DEBUG=y -CONFIG_SMP=y -CONFIG_SMP_ON_UP=y -CONFIG_SMSC_PHY=y -CONFIG_SOCK_DIAG=y -CONFIG_SOC_BRCMSTB=y -CONFIG_SOC_BUS=y -# CONFIG_SOC_IMX50 is not set -# CONFIG_SOC_IMX51 is not set -# CONFIG_SOC_IMX53 is not set -# CONFIG_SOC_IMX6Q is not set -# CONFIG_SOC_IMX6SL is not set -# CONFIG_SOC_IMX6SLL is not set -# CONFIG_SOC_IMX6SX is not set -# CONFIG_SOC_IMX6UL is not set -# CONFIG_SOC_IMX7D is not set -# CONFIG_SOC_IMX7ULP is not set -CONFIG_SOC_LS1021A=y -# CONFIG_SOC_VF610 is not set -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -CONFIG_SPI_BITBANG=y -CONFIG_SPI_CADENCE=y -CONFIG_SPI_DYNAMIC=y -# CONFIG_SPI_FSL_LPSPI is not set -# CONFIG_SPI_FSL_QUADSPI is not set -# CONFIG_SPI_IMX is not set -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SPI_SPIDEV=y -CONFIG_SPI_XILINX=y -CONFIG_SPMI=y -# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set -CONFIG_SQUASHFS_DECOMP_SINGLE=y -CONFIG_SQUASHFS_FILE_CACHE=y -# CONFIG_SQUASHFS_FILE_DIRECT is not set -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_ZLIB=y -CONFIG_SRAM=y -CONFIG_SRAM_EXEC=y -CONFIG_SRCU=y -CONFIG_STACKTRACE=y -CONFIG_STAGING_BOARD=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWIOTLB=y -CONFIG_SWPHY=y -CONFIG_SWP_EMULATE=y -CONFIG_SYNC_FILE=y -CONFIG_SYSFS_SYSCALL=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_SYS_SUPPORTS_HUGETLBFS=y -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TREE_RCU=y -CONFIG_TREE_SRCU=y -# CONFIG_TSN is not set -CONFIG_UBIFS_FS=y -# CONFIG_UCLAMP_TASK is not set -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" -CONFIG_UNIX_DIAG=y -CONFIG_UNWINDER_ARM=y -CONFIG_USB_SUPPORT=y -CONFIG_USER_NS=y -CONFIG_USE_OF=y -CONFIG_UTS_NS=y -CONFIG_VEXPRESS_CONFIG=y -CONFIG_VEXPRESS_SYSCFG=y -CONFIG_VFAT_FS=y -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_VIRTIO=y -CONFIG_VIRTIO_BLK=y -CONFIG_VIRTIO_CONSOLE=y -CONFIG_VIRTIO_MMIO=y -CONFIG_VIRTIO_NET=y -CONFIG_VIRTIO_PCI=y -CONFIG_VIRTIO_PCI_LEGACY=y -CONFIG_VITESSE_PHY=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -CONFIG_XILINX_WATCHDOG=y -CONFIG_XPS=y -CONFIG_XXHASH=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_ARMTHUMB=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_XZ_DEC_IA64=y -CONFIG_XZ_DEC_POWERPC=y -CONFIG_XZ_DEC_SPARC=y -CONFIG_XZ_DEC_X86=y -CONFIG_ZBOOT_ROM_BSS=0 -CONFIG_ZBOOT_ROM_TEXT=0 -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/layerscape/armv8_64b/config-5.4 b/target/linux/layerscape/armv8_64b/config-5.4 deleted file mode 100644 index 2d717434d1..0000000000 --- a/target/linux/layerscape/armv8_64b/config-5.4 +++ /dev/null @@ -1,881 +0,0 @@ -CONFIG_64BIT=y -CONFIG_AQUANTIA_PHY=y -CONFIG_ARCH_CLOCKSOURCE_DATA=y -CONFIG_ARCH_DMA_ADDR_T_64BIT=y -CONFIG_ARCH_HIBERNATION_HEADER=y -CONFIG_ARCH_HIBERNATION_POSSIBLE=y -CONFIG_ARCH_KEEP_MEMBLOCK=y -CONFIG_ARCH_LAYERSCAPE=y -CONFIG_ARCH_MMAP_RND_BITS=18 -CONFIG_ARCH_MMAP_RND_BITS_MAX=33 -CONFIG_ARCH_MMAP_RND_BITS_MIN=18 -CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 -CONFIG_ARCH_PROC_KCORE_TEXT=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_ARM64=y -CONFIG_ARM64_4K_PAGES=y -CONFIG_ARM64_CNP=y -CONFIG_ARM64_CONT_SHIFT=4 -CONFIG_ARM64_ERRATUM_1165522=y -CONFIG_ARM64_ERRATUM_1286807=y -CONFIG_ARM64_ERRATUM_819472=y -CONFIG_ARM64_ERRATUM_824069=y -CONFIG_ARM64_ERRATUM_826319=y -CONFIG_ARM64_ERRATUM_827319=y -CONFIG_ARM64_ERRATUM_832075=y -CONFIG_ARM64_ERRATUM_843419=y -CONFIG_ARM64_HW_AFDBM=y -CONFIG_ARM64_MODULE_PLTS=y -CONFIG_ARM64_PAGE_SHIFT=12 -CONFIG_ARM64_PAN=y -CONFIG_ARM64_PA_BITS=48 -CONFIG_ARM64_PA_BITS_48=y -CONFIG_ARM64_PTR_AUTH=y -CONFIG_ARM64_SSBD=y -CONFIG_ARM64_SVE=y -CONFIG_ARM64_TAGGED_ADDR_ABI=y -CONFIG_ARM64_UAO=y -CONFIG_ARM64_VA_BITS=48 -# CONFIG_ARM64_VA_BITS_39 is not set -CONFIG_ARM64_VA_BITS_48=y -CONFIG_ARM64_VHE=y -CONFIG_ARM64_WORKAROUND_CLEAN_CACHE=y -CONFIG_ARM64_WORKAROUND_REPEAT_TLBI=y -CONFIG_ARM_AMBA=y -CONFIG_ARM_ARCH_TIMER=y -CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y -CONFIG_ARM_CPUIDLE=y -CONFIG_ARM_GIC=y -CONFIG_ARM_GIC_V2M=y -CONFIG_ARM_GIC_V3=y -CONFIG_ARM_GIC_V3_ITS=y -CONFIG_ARM_GIC_V3_ITS_FSL_MC=y -CONFIG_ARM_GIC_V3_ITS_PCI=y -# CONFIG_ARM_PL172_MPMC is not set -CONFIG_ARM_PSCI_CPUIDLE=y -CONFIG_ARM_PSCI_FW=y -CONFIG_ARM_SMMU=y -# CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT is not set -CONFIG_ARM_SMMU_V3=y -CONFIG_ARM_SP805_WATCHDOG=y -CONFIG_ASM_MODVERSIONS=y -CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y -CONFIG_ATA=y -CONFIG_AUDIT=y -CONFIG_AUDITSYSCALL=y -CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y -CONFIG_AUDIT_GENERIC=y -CONFIG_AUTOFS4_FS=y -CONFIG_AUTOFS_FS=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_BALLOON_COMPACTION=y -CONFIG_BATTERY_BQ27XXX=y -# CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM is not set -CONFIG_BATTERY_BQ27XXX_I2C=y -CONFIG_BLK_DEV_BSG=y -CONFIG_BLK_DEV_BSGLIB=y -CONFIG_BLK_DEV_INTEGRITY=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=262144 -CONFIG_BLK_DEV_SD=y -CONFIG_BLK_MQ_PCI=y -CONFIG_BLK_MQ_VIRTIO=y -CONFIG_BLK_PM=y -CONFIG_BLK_SCSI_REQUEST=y -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_BTRFS_FS=y -# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set -CONFIG_BTRFS_FS_POSIX_ACL=y -CONFIG_CAVIUM_ERRATUM_22375=y -CONFIG_CAVIUM_ERRATUM_23144=y -CONFIG_CAVIUM_ERRATUM_23154=y -CONFIG_CAVIUM_ERRATUM_27456=y -CONFIG_CHECKPOINT_RESTORE=y -CONFIG_CHROME_PLATFORMS=y -CONFIG_CLKDEV_LOOKUP=y -CONFIG_CLK_LS1028A_PLLDIG=y -CONFIG_CLK_QORIQ=y -CONFIG_CLK_SP810=y -CONFIG_CLK_VEXPRESS_OSC=y -CONFIG_CLONE_BACKWARDS=y -CONFIG_CMA=y -CONFIG_CMA_ALIGNMENT=8 -CONFIG_CMA_AREAS=7 -# CONFIG_CMA_DEBUG is not set -# CONFIG_CMA_DEBUGFS is not set -CONFIG_CMA_SIZE_MBYTES=16 -# CONFIG_CMA_SIZE_SEL_MAX is not set -CONFIG_CMA_SIZE_SEL_MBYTES=y -# CONFIG_CMA_SIZE_SEL_MIN is not set -# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set -CONFIG_COMMON_CLK=y -CONFIG_COMMON_CLK_CS2000_CP=y -CONFIG_COMMON_CLK_VERSATILE=y -CONFIG_COMMON_CLK_XGENE=y -CONFIG_CONFIGFS_FS=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_CONTIG_ALLOC=y -CONFIG_COREDUMP=y -CONFIG_CPUFREQ_DT=y -CONFIG_CPUFREQ_DT_PLATDEV=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_ATTR_SET=y -CONFIG_CPU_FREQ_GOV_COMMON=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_MENU=y -CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y -CONFIG_CPU_PM=y -CONFIG_CPU_RMAP=y -CONFIG_CPU_THERMAL=y -CONFIG_CRASH_CORE=y -CONFIG_CRC16=y -# CONFIG_CRC32_SARWATE is not set -CONFIG_CRC32_SLICEBY8=y -CONFIG_CRC7=y -CONFIG_CRC_ITU_T=y -CONFIG_CRC_T10DIF=y -CONFIG_CROSS_MEMORY_ATTACH=y -# CONFIG_CROS_EC is not set -CONFIG_CRYPTO_ACOMP2=y -CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_CRC32=y -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_CRCT10DIF=y -CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM is not set -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_HASH_INFO=y -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y -CONFIG_CRYPTO_NULL2=y -CONFIG_CRYPTO_RNG2=y -# CONFIG_CRYPTO_TLS is not set -CONFIG_CRYPTO_ZSTD=y -CONFIG_DCACHE_WORD_ACCESS=y -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_INFO_REDUCED is not set -CONFIG_DEBUG_MEMORY_INIT=y -CONFIG_DECOMPRESS_BZIP2=y -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_LZMA=y -CONFIG_DECOMPRESS_LZO=y -CONFIG_DECOMPRESS_XZ=y -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_DEVICE_THERMAL is not set -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_DMADEVICES=y -CONFIG_DMATEST=y -CONFIG_DMA_CMA=y -CONFIG_DMA_DIRECT_REMAP=y -CONFIG_DMA_ENGINE=y -CONFIG_DMA_ENGINE_RAID=y -CONFIG_DMA_OF=y -CONFIG_DMA_REMAP=y -CONFIG_DMA_SHARED_BUFFER=y -CONFIG_DMA_VIRTUAL_CHANNELS=y -CONFIG_DNOTIFY=y -CONFIG_DPAA2_CONSOLE=y -# CONFIG_DRM_CDNS_MHDP is not set -CONFIG_DRM_RCAR_WRITEBACK=y -CONFIG_DTC=y -CONFIG_DT_IDLE_STATES=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_EDAC_SUPPORT=y -CONFIG_EEPROM_AT24=y -CONFIG_ELF_CORE=y -# CONFIG_EMBEDDED is not set -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_ENETC_TSN=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -CONFIG_EXTCON=y -CONFIG_EXTCON_USB_GPIO=y -CONFIG_F2FS_FS=y -CONFIG_FAILOVER=y -CONFIG_FANOTIFY=y -CONFIG_FAT_FS=y -CONFIG_FB=y -CONFIG_FB_ARMCLCD=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_CMDLINE=y -CONFIG_FB_DEFERRED_IO=y -CONFIG_FB_MODE_HELPERS=y -CONFIG_FB_SYS_COPYAREA=y -CONFIG_FB_SYS_FILLRECT=y -CONFIG_FB_SYS_FOPS=y -CONFIG_FB_SYS_IMAGEBLIT=y -CONFIG_FHANDLE=y -CONFIG_FIXED_PHY=y -CONFIG_FIX_EARLYCON_MEM=y -CONFIG_FMAN_ARM=y -# CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN is not set -# CONFIG_FMAN_P1023 is not set -# CONFIG_FMAN_P3040_P4080_P5020 is not set -# CONFIG_FMAN_PFC is not set -# CONFIG_FMAN_V3H is not set -# CONFIG_FMAN_V3L is not set -CONFIG_FONT_8x16=y -CONFIG_FONT_8x8=y -CONFIG_FONT_SUPPORT=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -CONFIG_FRAME_POINTER=y -CONFIG_FRAME_WARN=2048 -CONFIG_FREEZER=y -CONFIG_FSL_BMAN_CONFIG=y -CONFIG_FSL_BMAN_DEBUGFS=y -# CONFIG_FSL_BMAN_TEST is not set -# CONFIG_FSL_DPAA is not set -CONFIG_FSL_DPAA2=y -CONFIG_FSL_DPAA2_ETH=y -CONFIG_FSL_DPAA2_ETHSW=y -# CONFIG_FSL_DPAA2_ETH_CEETM is not set -# CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE is not set -CONFIG_FSL_DPAA2_EVB=y -CONFIG_FSL_DPAA2_MAC=y -# CONFIG_FSL_DPAA2_MAC_NETDEVS is not set -CONFIG_FSL_DPAA2_PTP_CLOCK=y -# CONFIG_FSL_DPAA2_QDMA is not set -# CONFIG_FSL_DPAA_1588 is not set -CONFIG_FSL_DPAA_ADVANCED_DRIVERS=y -# CONFIG_FSL_DPAA_CEETM is not set -CONFIG_FSL_DPAA_CS_THRESHOLD_10G=0x10000000 -CONFIG_FSL_DPAA_CS_THRESHOLD_1G=0x06000000 -# CONFIG_FSL_DPAA_DBG_LOOP is not set -# CONFIG_FSL_DPAA_ETH_DEBUG is not set -CONFIG_FSL_DPAA_ETH_DEBUGFS=y -# CONFIG_FSL_DPAA_ETH_JUMBO_FRAME is not set -CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT=128 -CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD=80 -# CONFIG_FSL_DPAA_HOOKS is not set -CONFIG_FSL_DPAA_INGRESS_CS_THRESHOLD=0x10000000 -CONFIG_FSL_DPAA_OFFLINE_PORTS=y -# CONFIG_FSL_DPAA_TS is not set -CONFIG_FSL_DPA_CAN_WAIT=y -CONFIG_FSL_DPA_CAN_WAIT_SYNC=y -# CONFIG_FSL_DPA_CHECKING is not set -CONFIG_FSL_DPA_PIRQ_FAST=y -CONFIG_FSL_DPA_PIRQ_SLOW=y -CONFIG_FSL_DPA_PORTAL_SHARE=y -CONFIG_FSL_EDMA=y -# CONFIG_FSL_EDMA_V3 is not set -CONFIG_FSL_ENETC=y -CONFIG_FSL_ENETC_HW_TIMESTAMPING=y -CONFIG_FSL_ENETC_MDIO=y -CONFIG_FSL_ENETC_PTP_CLOCK=y -CONFIG_FSL_ENETC_VF=y -CONFIG_FSL_ERRATUM_A008585=y -# CONFIG_FSL_FMAN is not set -CONFIG_FSL_FM_MAX_FRAME_SIZE=1522 -CONFIG_FSL_FM_RX_EXTRA_HEADROOM=64 -CONFIG_FSL_GUTS=y -CONFIG_FSL_IFC=y -CONFIG_FSL_MC_BUS=y -CONFIG_FSL_MC_DPIO=y -CONFIG_FSL_MC_UAPI_SUPPORT=y -CONFIG_FSL_PPFE=y -CONFIG_FSL_PPFE_UTIL_DISABLED=y -CONFIG_FSL_QIXIS=y -CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W=2 -CONFIG_FSL_QMAN_CI_SCHED_CFG_RW_W=2 -CONFIG_FSL_QMAN_CI_SCHED_CFG_SRCCIV=4 -CONFIG_FSL_QMAN_CI_SCHED_CFG_SRQ_W=3 -CONFIG_FSL_QMAN_CONFIG=y -CONFIG_FSL_QMAN_DEBUGFS=y -CONFIG_FSL_QMAN_FQD_SZ=10 -CONFIG_FSL_QMAN_FQ_LOOKUP=y -CONFIG_FSL_QMAN_INIT_TIMEOUT=10 -CONFIG_FSL_QMAN_PFDR_SZ=13 -CONFIG_FSL_QMAN_PIRQ_DQRR_ITHRESH=12 -CONFIG_FSL_QMAN_PIRQ_IPERIOD=100 -CONFIG_FSL_QMAN_PIRQ_MR_ITHRESH=4 -CONFIG_FSL_QMAN_POLL_LIMIT=32 -# CONFIG_FSL_QMAN_TEST is not set -CONFIG_FSL_RCPM=y -CONFIG_FSL_SDK_BMAN=y -CONFIG_FSL_SDK_DPA=y -CONFIG_FSL_SDK_DPAA_ETH=y -CONFIG_FSL_SDK_FMAN=y -# CONFIG_FSL_SDK_FMAN_RTC_API is not set -# CONFIG_FSL_SDK_FMAN_TEST is not set -CONFIG_FSL_SDK_QMAN=y -CONFIG_FSL_USDPAA=y -CONFIG_FSL_XGMAC_MDIO=y -CONFIG_FS_IOMAP=y -CONFIG_FS_MBCACHE=y -CONFIG_FS_POSIX_ACL=y -CONFIG_FUSE_FS=y -CONFIG_FW_LOADER_PAGED_BUF=y -# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set -CONFIG_GARP=y -CONFIG_GENERIC_ALLOCATOR=y -CONFIG_GENERIC_ARCH_TOPOLOGY=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y -CONFIG_GENERIC_CPU_AUTOPROBE=y -CONFIG_GENERIC_CPU_VULNERABILITIES=y -CONFIG_GENERIC_CSUM=y -CONFIG_GENERIC_EARLY_IOREMAP=y -CONFIG_GENERIC_GETTIMEOFDAY=y -CONFIG_GENERIC_IDLE_POLL_SETUP=y -CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y -CONFIG_GENERIC_IRQ_MIGRATION=y -CONFIG_GENERIC_IRQ_MULTI_HANDLER=y -CONFIG_GENERIC_IRQ_SHOW=y -CONFIG_GENERIC_IRQ_SHOW_LEVEL=y -CONFIG_GENERIC_MSI_IRQ=y -CONFIG_GENERIC_MSI_IRQ_DOMAIN=y -CONFIG_GENERIC_PCI_IOMAP=y -CONFIG_GENERIC_PHY=y -CONFIG_GENERIC_SCHED_CLOCK=y -CONFIG_GENERIC_SMP_IDLE_THREAD=y -CONFIG_GENERIC_STRNCPY_FROM_USER=y -CONFIG_GENERIC_STRNLEN_USER=y -CONFIG_GENERIC_TIME_VSYSCALL=y -# CONFIG_GIANFAR is not set -CONFIG_GLOB=y -CONFIG_GPIOLIB=y -CONFIG_GPIOLIB_IRQCHIP=y -CONFIG_GPIO_GENERIC=y -CONFIG_GPIO_GENERIC_PLATFORM=y -CONFIG_GPIO_MPC8XXX=y -CONFIG_GPIO_PCA953X=y -CONFIG_GPIO_PCA953X_IRQ=y -CONFIG_HANDLE_DOMAIN_IRQ=y -CONFIG_HARDEN_BRANCH_PREDICTOR=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_HAS_DMA=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT_MAP=y -CONFIG_HIBERNATE_CALLBACKS=y -CONFIG_HIBERNATION=y -CONFIG_HID=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GENERIC=y -CONFIG_HID_KENSINGTON=y -CONFIG_HID_LOGITECH=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HOLES_IN_ZONE=y -CONFIG_HOTPLUG_CPU=y -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -CONFIG_HVC_DRIVER=y -CONFIG_HVC_IRQ=y -CONFIG_HVC_XEN=y -CONFIG_HVC_XEN_FRONTEND=y -CONFIG_HW_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_DESIGNWARE_CORE=y -CONFIG_I2C_DESIGNWARE_PLATFORM=y -# CONFIG_I2C_DESIGNWARE_SLAVE is not set -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_IMX=y -CONFIG_I2C_MUX=y -CONFIG_I2C_MUX_PCA954x=y -CONFIG_I2C_RK3X=y -CONFIG_I2C_SLAVE=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 -CONFIG_IMX2_WDT=y -CONFIG_INET_DIAG=y -# CONFIG_INET_DIAG_DESTROY is not set -# CONFIG_INET_RAW_DIAG is not set -CONFIG_INET_TCP_DIAG=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_INPHI_PHY=y -CONFIG_INPUT=y -CONFIG_INPUT_EVDEV=y -CONFIG_INPUT_FF_MEMLESS=y -CONFIG_INPUT_KEYBOARD=y -CONFIG_INPUT_MOUSE=y -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y -CONFIG_IOMMU_API=y -# CONFIG_IOMMU_DEBUGFS is not set -CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y -CONFIG_IOMMU_DMA=y -CONFIG_IOMMU_IOVA=y -CONFIG_IOMMU_IO_PGTABLE=y -# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set -CONFIG_IOMMU_IO_PGTABLE_LPAE=y -# CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST is not set -CONFIG_IOMMU_SUPPORT=y -CONFIG_IPC_NS=y -CONFIG_IRQCHIP=y -CONFIG_IRQ_BYPASS_MANAGER=y -CONFIG_IRQ_DOMAIN=y -CONFIG_IRQ_DOMAIN_HIERARCHY=y -CONFIG_IRQ_FORCED_THREADING=y -CONFIG_IRQ_MSI_IOMMU=y -CONFIG_IRQ_WORK=y -# CONFIG_ISDN is not set -# CONFIG_IVSHMEM_NET is not set -CONFIG_JBD2=y -CONFIG_JUMP_LABEL=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -CONFIG_KEXEC=y -CONFIG_KEXEC_CORE=y -CONFIG_KEYBOARD_ATKBD=y -CONFIG_KEYBOARD_GPIO=y -# CONFIG_KPC2000 is not set -CONFIG_KSM=y -CONFIG_LIBCRC32C=y -CONFIG_LIBFDT=y -CONFIG_LOCALVERSION_AUTO=y -CONFIG_LOCK_DEBUGGING_SUPPORT=y -CONFIG_LOCK_SPIN_ON_OWNER=y -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_LS_SCFG_MSI=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_MANDATORY_FILE_LOCKING=y -CONFIG_MDIO_BITBANG=y -CONFIG_MDIO_BUS=y -CONFIG_MDIO_BUS_MUX=y -CONFIG_MDIO_BUS_MUX_MMIOREG=y -CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y -CONFIG_MDIO_DEVICE=y -# CONFIG_MDIO_GPIO is not set -CONFIG_MEMFD_CREATE=y -CONFIG_MEMORY=y -CONFIG_MEMORY_BALLOON=y -CONFIG_MEMORY_ISOLATION=y -CONFIG_MEMTEST=y -CONFIG_MFD_CORE=y -CONFIG_MFD_SYSCON=y -# CONFIG_MFD_VEXPRESS_SYSREG is not set -CONFIG_MICREL_PHY=y -CONFIG_MICROSEMI_PHY=y -CONFIG_MIGRATION=y -CONFIG_MMC=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=32 -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_IO_ACCESSORS=y -CONFIG_MMC_SDHCI_OF_ESDHC=y -# CONFIG_MMC_SDHCI_PCI is not set -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MMU_NOTIFIER=y -CONFIG_MODULES_USE_ELF_RELA=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODVERSIONS=y -# CONFIG_MOUSE_BCM5974 is not set -# CONFIG_MOUSE_CYAPA is not set -CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_BYD=y -CONFIG_MOUSE_PS2_CYPRESS=y -# CONFIG_MOUSE_PS2_ELANTECH is not set -CONFIG_MOUSE_PS2_FOCALTECH=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SMBUS=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -CONFIG_MRP=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -# CONFIG_MTD_CFI_GEOMETRY is not set -CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_DATAFLASH=y -# CONFIG_MTD_DATAFLASH_OTP is not set -# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set -CONFIG_MTD_NAND_CORE=y -CONFIG_MTD_NAND_ECC_SW_HAMMING=y -CONFIG_MTD_NAND_FSL_IFC=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_RAW_NAND=y -CONFIG_MTD_SPI_NOR=y -CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y -CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384 -CONFIG_MTD_SPLIT_FIRMWARE=y -CONFIG_MTD_SPLIT_FIT_FW=y -CONFIG_MTD_SST25L=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_BEB_LIMIT=20 -# CONFIG_MTD_UBI_BLOCK is not set -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MULTIPLEXER=y -CONFIG_MUTEX_SPIN_ON_OWNER=y -# CONFIG_MUX_ADG792A is not set -# CONFIG_MUX_ADGS1408 is not set -# CONFIG_MUX_GPIO is not set -CONFIG_MUX_MMIO=y -CONFIG_MV_XOR_V2=y -CONFIG_NAMESPACES=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_NEED_MULTIPLE_NODES=y -CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y -CONFIG_NEED_SG_DMA_LENGTH=y -CONFIG_NET_FAILOVER=y -CONFIG_NET_FLOW_LIMIT=y -CONFIG_NET_NS=y -CONFIG_NET_PTP_CLASSIFY=y -CONFIG_NET_SWITCHDEV=y -CONFIG_NLS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NODES_SHIFT=2 -CONFIG_NO_HZ_COMMON=y -CONFIG_NO_HZ_IDLE=y -CONFIG_NR_CPUS=64 -CONFIG_NUMA=y -CONFIG_NUMA_BALANCING=y -CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y -CONFIG_NVMEM=y -CONFIG_NVMEM_SYSFS=y -CONFIG_OF=y -CONFIG_OF_ADDRESS=y -CONFIG_OF_EARLY_FLATTREE=y -CONFIG_OF_FLATTREE=y -CONFIG_OF_GPIO=y -CONFIG_OF_IOMMU=y -CONFIG_OF_IRQ=y -CONFIG_OF_KOBJ=y -CONFIG_OF_MDIO=y -CONFIG_OF_NET=y -CONFIG_OF_NUMA=y -CONFIG_PACKET_DIAG=y -CONFIG_PADATA=y -# CONFIG_PANIC_ON_OOPS is not set -CONFIG_PANIC_ON_OOPS_VALUE=0 -CONFIG_PANIC_TIMEOUT=0 -CONFIG_PARAVIRT=y -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_PARTITION_PERCPU=y -CONFIG_PCI=y -CONFIG_PCIEAER=y -CONFIG_PCIEASPM=y -# CONFIG_PCIEASPM_DEBUG is not set -CONFIG_PCIEASPM_DEFAULT=y -# CONFIG_PCIEASPM_PERFORMANCE is not set -# CONFIG_PCIEASPM_POWERSAVE is not set -# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set -CONFIG_PCIEPORTBUS=y -CONFIG_PCIE_DW=y -CONFIG_PCIE_DW_HOST=y -CONFIG_PCIE_LAYERSCAPE_GEN4=y -CONFIG_PCIE_MOBIVEIL=y -CONFIG_PCIE_MOBIVEIL_HOST=y -CONFIG_PCIE_PME=y -CONFIG_PCI_ATS=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_DOMAINS_GENERIC=y -CONFIG_PCI_ECAM=y -CONFIG_PCI_HISI=y -CONFIG_PCI_HOST_COMMON=y -CONFIG_PCI_HOST_GENERIC=y -CONFIG_PCI_IOV=y -CONFIG_PCI_LAYERSCAPE=y -CONFIG_PCI_MSI=y -CONFIG_PCI_MSI_IRQ_DOMAIN=y -CONFIG_PGTABLE_LEVELS=4 -CONFIG_PHYLIB=y -CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_PHY_XGENE=y -CONFIG_PID_IN_CONTEXTIDR=y -CONFIG_PID_NS=y -CONFIG_PL330_DMA=y -CONFIG_PM=y -CONFIG_PM_CLK=y -CONFIG_PM_OPP=y -CONFIG_PM_SLEEP=y -CONFIG_PM_SLEEP_SMP=y -CONFIG_PM_STD_PARTITION="" -CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_POWER_RESET_VEXPRESS=y -CONFIG_POWER_RESET_XGENE=y -CONFIG_POWER_SUPPLY=y -CONFIG_PPS=y -CONFIG_PREEMPT=y -CONFIG_PREEMPTION=y -CONFIG_PREEMPT_COUNT=y -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_RCU=y -CONFIG_PRINTK_TIME=y -CONFIG_PRINT_QUOTA_WARNING=y -CONFIG_PROC_CHILDREN=y -CONFIG_PROFILING=y -CONFIG_PTP_1588_CLOCK=y -CONFIG_PTP_1588_CLOCK_QORIQ=y -CONFIG_QCOM_HIDMA=y -CONFIG_QCOM_HIDMA_MGMT=y -CONFIG_QCOM_QDF2400_ERRATUM_0065=y -# CONFIG_QFMT_V1 is not set -# CONFIG_QFMT_V2 is not set -CONFIG_QMAN_CEETM_UPDATE_PERIOD=1000 -CONFIG_QORIQ_CPUFREQ=y -CONFIG_QUEUED_RWLOCKS=y -CONFIG_QUEUED_SPINLOCKS=y -# CONFIG_QUICC_ENGINE is not set -CONFIG_QUOTA=y -CONFIG_QUOTACTL=y -# CONFIG_QUOTA_NETLINK_INTERFACE is not set -CONFIG_RAID6_PQ=y -CONFIG_RAS=y -CONFIG_RATIONAL=y -CONFIG_RD_BZIP2=y -CONFIG_RD_GZIP=y -CONFIG_RD_LZMA=y -CONFIG_RD_LZO=y -CONFIG_RD_XZ=y -CONFIG_REALTEK_PHY=y -CONFIG_REFCOUNT_FULL=y -CONFIG_REGMAP=y -CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_MMIO=y -CONFIG_REGMAP_SPI=y -CONFIG_RESET_CONTROLLER=y -CONFIG_RFS_ACCEL=y -CONFIG_RODATA_FULL_DEFAULT_ENABLED=y -CONFIG_RPS=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_DS3232=y -CONFIG_RTC_DRV_FSL_FTM_ALARM=y -CONFIG_RTC_DRV_PCF2127=y -CONFIG_RTC_DRV_PL031=y -CONFIG_RTC_I2C_AND_SPI=y -CONFIG_RWSEM_SPIN_ON_OWNER=y -CONFIG_SCHED_INFO=y -CONFIG_SCHED_MC=y -CONFIG_SCSI=y -# CONFIG_SCSI_PROC_FS is not set -# CONFIG_SCSI_SAS_ATA is not set -CONFIG_SCSI_SAS_ATTRS=y -CONFIG_SCSI_SAS_HOST_SMP=y -CONFIG_SCSI_SAS_LIBSAS=y -CONFIG_SECCOMP=y -CONFIG_SECCOMP_FILTER=y -CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_8250_DWLIB=y -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_FSL=y -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_PCI=y -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_SERIAL_FSL_LPUART=y -CONFIG_SERIAL_FSL_LPUART_CONSOLE=y -CONFIG_SERIAL_MCTRL_GPIO=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SERIAL_SC16IS7XX=y -CONFIG_SERIAL_SC16IS7XX_CORE=y -# CONFIG_SERIAL_SC16IS7XX_I2C is not set -CONFIG_SERIAL_SC16IS7XX_SPI=y -CONFIG_SERIAL_XILINX_PS_UART=y -CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y -CONFIG_SERIO=y -CONFIG_SERIO_AMBAKMI=y -CONFIG_SERIO_LIBPS2=y -CONFIG_SGL_ALLOC=y -CONFIG_SG_POOL=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -CONFIG_SMP=y -CONFIG_SOCK_DIAG=y -CONFIG_SOC_BUS=y -CONFIG_SPARSEMEM=y -CONFIG_SPARSEMEM_EXTREME=y -CONFIG_SPARSEMEM_MANUAL=y -CONFIG_SPARSEMEM_VMEMMAP=y -CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y -CONFIG_SPARSE_IRQ=y -CONFIG_SPI=y -CONFIG_SPI_FSL_DSPI=y -CONFIG_SPI_FSL_QUADSPI=y -CONFIG_SPI_MASTER=y -CONFIG_SPI_MEM=y -CONFIG_SPI_NXP_FLEXSPI=y -CONFIG_SPI_PL022=y -CONFIG_SPMI=y -# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set -CONFIG_SQUASHFS_DECOMP_SINGLE=y -CONFIG_SQUASHFS_FILE_CACHE=y -# CONFIG_SQUASHFS_FILE_DIRECT is not set -# CONFIG_SQUASHFS_XZ is not set -CONFIG_SQUASHFS_ZLIB=y -CONFIG_SRAM=y -CONFIG_SRCU=y -# CONFIG_STRIP_ASM_SYMS is not set -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_SWIOTLB=y -CONFIG_SWIOTLB_XEN=y -CONFIG_SWPHY=y -CONFIG_SYNC_FILE=y -CONFIG_SYSCTL_EXCEPTION_TRACE=y -CONFIG_SYSFS_SYSCALL=y -CONFIG_SYS_HYPERVISOR=y -CONFIG_SYS_SUPPORTS_HUGETLBFS=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -CONFIG_TASK_IO_ACCOUNTING=y -CONFIG_TASK_XACCT=y -CONFIG_THERMAL=y -CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y -CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 -CONFIG_THERMAL_EMULATION=y -CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y -CONFIG_THERMAL_GOV_STEP_WISE=y -CONFIG_THERMAL_OF=y -CONFIG_THREAD_INFO_IN_TASK=y -CONFIG_TICK_CPU_ACCOUNTING=y -CONFIG_TIMER_OF=y -CONFIG_TIMER_PROBE=y -CONFIG_TMPFS_POSIX_ACL=y -CONFIG_TRANSPARENT_HUGEPAGE=y -CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y -# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set -CONFIG_TRANSPARENT_HUGE_PAGECACHE=y -CONFIG_TREE_SRCU=y -CONFIG_TSN=y -CONFIG_UBIFS_FS=y -CONFIG_UIO=y -CONFIG_UIO_AEC=y -CONFIG_UIO_CIF=y -CONFIG_UIO_DMEM_GENIRQ=y -CONFIG_UIO_MF624=y -CONFIG_UIO_NETX=y -CONFIG_UIO_PCI_GENERIC=y -CONFIG_UIO_PDRV_GENIRQ=y -# CONFIG_UIO_PRUSS is not set -CONFIG_UIO_SERCOS3=y -CONFIG_UNINLINE_SPIN_UNLOCK=y -CONFIG_UNIX_DIAG=y -CONFIG_UNMAP_KERNEL_AT_EL0=y -CONFIG_USB_SUPPORT=y -CONFIG_USER_NS=y -CONFIG_USE_PERCPU_NUMA_NODE_ID=y -CONFIG_UTS_NS=y -CONFIG_VEXPRESS_CONFIG=y -CONFIG_VEXPRESS_SYSCFG=y -CONFIG_VFAT_FS=y -CONFIG_VFIO=y -CONFIG_VFIO_FSL_MC=y -CONFIG_VFIO_IOMMU_TYPE1=y -# CONFIG_VFIO_MDEV is not set -# CONFIG_VFIO_NOIOMMU is not set -CONFIG_VFIO_PCI=y -CONFIG_VFIO_PCI_INTX=y -CONFIG_VFIO_PCI_MMAP=y -# CONFIG_VFIO_PLATFORM is not set -CONFIG_VFIO_VIRQFD=y -CONFIG_VGA_ARB=y -CONFIG_VGA_ARB_MAX_GPUS=16 -CONFIG_VIDEOMODE_HELPERS=y -CONFIG_VIRTIO=y -CONFIG_VIRTIO_BALLOON=y -CONFIG_VIRTIO_BLK=y -CONFIG_VIRTIO_CONSOLE=y -# CONFIG_VIRTIO_IOMMU is not set -CONFIG_VIRTIO_MMIO=y -CONFIG_VIRTIO_NET=y -CONFIG_VIRTIO_PCI=y -CONFIG_VIRTIO_PCI_LEGACY=y -CONFIG_VITESSE_PHY=y -CONFIG_VLAN_8021Q_GVRP=y -CONFIG_VLAN_8021Q_MVRP=y -CONFIG_VMAP_STACK=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_VT_CONSOLE_SLEEP=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_WATCHDOG_CORE=y -# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set -CONFIG_XARRAY_MULTI=y -CONFIG_XEN=y -CONFIG_XENFS=y -CONFIG_XEN_AUTO_XLATE=y -CONFIG_XEN_BACKEND=y -CONFIG_XEN_BALLOON=y -# CONFIG_XEN_BLKDEV_BACKEND is not set -CONFIG_XEN_BLKDEV_FRONTEND=y -CONFIG_XEN_COMPAT_XENFS=y -CONFIG_XEN_DEV_EVTCHN=y -CONFIG_XEN_DOM0=y -CONFIG_XEN_FBDEV_FRONTEND=y -CONFIG_XEN_GNTDEV=y -CONFIG_XEN_GRANT_DEV_ALLOC=y -# CONFIG_XEN_NETDEV_BACKEND is not set -CONFIG_XEN_NETDEV_FRONTEND=y -CONFIG_XEN_PRIVCMD=y -# CONFIG_XEN_PVCALLS_BACKEND is not set -# CONFIG_XEN_SCSI_FRONTEND is not set -CONFIG_XEN_SYS_HYPERVISOR=y -# CONFIG_XEN_WDT is not set -CONFIG_XEN_XENBUS_FRONTEND=y -CONFIG_XFS_FS=y -CONFIG_XFS_POSIX_ACL=y -CONFIG_XFS_RT=y -CONFIG_XOR_BLOCKS=y -CONFIG_XPS=y -CONFIG_XXHASH=y -CONFIG_XZ_DEC_ARM=y -CONFIG_XZ_DEC_ARMTHUMB=y -CONFIG_XZ_DEC_BCJ=y -CONFIG_XZ_DEC_IA64=y -CONFIG_XZ_DEC_POWERPC=y -CONFIG_XZ_DEC_SPARC=y -CONFIG_XZ_DEC_X86=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZONE_DMA32=y -CONFIG_ZSTD_COMPRESS=y -CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/layerscape/patches-5.4/301-arch-0001-arm-kernel-utilize-hrtimer-based-broadcast.patch b/target/linux/layerscape/patches-5.4/301-arch-0001-arm-kernel-utilize-hrtimer-based-broadcast.patch deleted file mode 100644 index 8b9c25d0dc..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0001-arm-kernel-utilize-hrtimer-based-broadcast.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0f87c1dd8f10958121e10219c89e8d710babd1ce Mon Sep 17 00:00:00 2001 -From: Alison Wang -Date: Fri, 17 Jul 2015 17:11:52 +0800 -Subject: [PATCH] arm: kernel: utilize hrtimer based broadcast - -Hrtimer based broadcast is used on ARM platform. It can be -registered as the tick broadcast device in the absence of -a real external clock device. - -Signed-off-by: Alison Wang -Acked-by: Mark Rutland ---- - arch/arm/kernel/time.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/arch/arm/kernel/time.c -+++ b/arch/arm/kernel/time.c -@@ -9,6 +9,7 @@ - * reading the RTC at bootup, etc... - */ - #include -+#include - #include - #include - #include -@@ -107,5 +108,7 @@ void __init time_init(void) - of_clk_init(NULL); - #endif - timer_probe(); -+ -+ tick_setup_hrtimer_broadcast(); - } - } diff --git a/target/linux/layerscape/patches-5.4/301-arch-0002-arm64-add-support-to-remap-kernel-cacheable-memory-t.patch b/target/linux/layerscape/patches-5.4/301-arch-0002-arm64-add-support-to-remap-kernel-cacheable-memory-t.patch deleted file mode 100644 index e6c96a052a..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0002-arm64-add-support-to-remap-kernel-cacheable-memory-t.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0f90f5d6b3097fd6e7dea3389dc3d8f8894b345c Mon Sep 17 00:00:00 2001 -From: Haiying Wang -Date: Wed, 22 Apr 2015 13:09:47 -0400 -Subject: [PATCH] arm64: add support to remap kernel cacheable memory to - userspace - -Signed-off-by: Haiying Wang -Reviewed-by: Roy Pledge -Reviewed-by: Stuart Yoder ---- - arch/arm64/include/asm/pgtable.h | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/arch/arm64/include/asm/pgtable.h -+++ b/arch/arm64/include/asm/pgtable.h -@@ -428,6 +428,9 @@ static inline pmd_t pmd_mkdevmap(pmd_t p - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE) | PTE_PXN | PTE_UXN) - #define pgprot_writecombine(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN) -+#define pgprot_cached(prot) \ -+ __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL) | \ -+ PTE_PXN | PTE_UXN) - #define pgprot_device(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN) - /* diff --git a/target/linux/layerscape/patches-5.4/301-arch-0003-arm64-pgtable-add-support-to-map-cacheable-and-non-s.patch b/target/linux/layerscape/patches-5.4/301-arch-0003-arm64-pgtable-add-support-to-map-cacheable-and-non-s.patch deleted file mode 100644 index bd39eb7e14..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0003-arm64-pgtable-add-support-to-map-cacheable-and-non-s.patch +++ /dev/null @@ -1,22 +0,0 @@ -From d59be41c014e2e17ea0aaa37d42f36548ad063b5 Mon Sep 17 00:00:00 2001 -From: Haiying Wang -Date: Sat, 8 Aug 2015 07:25:02 -0400 -Subject: [PATCH] arm64/pgtable: add support to map cacheable and non shareable - memory - -Signed-off-by: Haiying Wang ---- - arch/arm64/include/asm/pgtable.h | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/arm64/include/asm/pgtable.h -+++ b/arch/arm64/include/asm/pgtable.h -@@ -431,6 +431,8 @@ static inline pmd_t pmd_mkdevmap(pmd_t p - #define pgprot_cached(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL) | \ - PTE_PXN | PTE_UXN) -+#define pgprot_cached_ns(prot) \ -+ __pgprot(pgprot_val(pgprot_cached(prot)) ^ PTE_SHARED) - #define pgprot_device(prot) \ - __pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_PXN | PTE_UXN) - /* diff --git a/target/linux/layerscape/patches-5.4/301-arch-0004-arm64-add-ioremap-for-normal-cacheable-non-shareable.patch b/target/linux/layerscape/patches-5.4/301-arch-0004-arm64-add-ioremap-for-normal-cacheable-non-shareable.patch deleted file mode 100644 index ca55e532ac..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0004-arm64-add-ioremap-for-normal-cacheable-non-shareable.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 120c8f221cb18f6630d5cb954484bac88288cced Mon Sep 17 00:00:00 2001 -From: Haiying Wang -Date: Wed, 22 Apr 2015 13:07:25 -0400 -Subject: [PATCH] arm64: add ioremap for normal cacheable non-shareable memory - -Signed-off-by: Haiying Wang -Reviewed-by: Roy Pledge -Reviewed-by: Stuart Yoder ---- - arch/arm64/include/asm/io.h | 1 + - arch/arm64/include/asm/pgtable-prot.h | 1 + - 2 files changed, 2 insertions(+) - ---- a/arch/arm64/include/asm/io.h -+++ b/arch/arm64/include/asm/io.h -@@ -170,6 +170,7 @@ extern void __iomem *ioremap_cache(phys_ - #define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) - #define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC)) - #define ioremap_wt(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) -+#define ioremap_cache_ns(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NS)) - - /* - * PCI configuration space mapping function. ---- a/arch/arm64/include/asm/pgtable-prot.h -+++ b/arch/arm64/include/asm/pgtable-prot.h -@@ -37,6 +37,7 @@ - #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_NC)) - #define PROT_NORMAL_WT (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL_WT)) - #define PROT_NORMAL (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL)) -+#define PROT_NORMAL_NS (PTE_TYPE_PAGE | PTE_AF | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL)) - - #define PROT_SECT_DEVICE_nGnRE (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_nGnRE)) - #define PROT_SECT_NORMAL (PROT_SECT_DEFAULT | PMD_SECT_PXN | PMD_SECT_UXN | PMD_ATTRINDX(MT_NORMAL)) diff --git a/target/linux/layerscape/patches-5.4/301-arch-0005-arch-arm-add-ARM-specific-fucntions-required-for-ehc.patch b/target/linux/layerscape/patches-5.4/301-arch-0005-arch-arm-add-ARM-specific-fucntions-required-for-ehc.patch deleted file mode 100644 index ddb77d438b..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0005-arch-arm-add-ARM-specific-fucntions-required-for-ehc.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 3bc37b0ee99b9d66ac47aea02784242cb3224366 Mon Sep 17 00:00:00 2001 -From: Zhao Qiang -Date: Fri, 10 Oct 2014 10:38:48 +0800 -Subject: [PATCH] arch: arm: add ARM specific fucntions required for ehci fsl - driver - -Add below functions for ARM platform which are used by ehci fsl driver: -1. spin_event_timeout function -2. set/clear bits functions - -Signed-off-by: Zhao Qiang -Signed-off-by: Rajesh Bhagat ---- - arch/arm/include/asm/delay.h | 16 ++++++++++++++++ - arch/arm/include/asm/io.h | 28 ++++++++++++++++++++++++++++ - 2 files changed, 44 insertions(+) - ---- a/arch/arm/include/asm/delay.h -+++ b/arch/arm/include/asm/delay.h -@@ -85,6 +85,22 @@ extern void __bad_udelay(void); - __const_udelay((n) * UDELAY_MULT)) : \ - __udelay(n)) - -+#define spin_event_timeout(condition, timeout, delay) \ -+({ \ -+ typeof(condition) __ret; \ -+ int i = 0; \ -+ while (!(__ret = (condition)) && (i++ < timeout)) { \ -+ if (delay) \ -+ udelay(delay); \ -+ else \ -+ cpu_relax(); \ -+ udelay(1); \ -+ } \ -+ if (!__ret) \ -+ __ret = (condition); \ -+ __ret; \ -+}) -+ - /* Loop-based definitions for assembly code. */ - extern void __loop_delay(unsigned long loops); - extern void __loop_udelay(unsigned long usecs); ---- a/arch/arm/include/asm/io.h -+++ b/arch/arm/include/asm/io.h -@@ -224,6 +224,34 @@ void __iomem *pci_remap_cfgspace(resourc - #endif - #endif - -+/* access ports */ -+#define setbits32(_addr, _v) iowrite32be(ioread32be(_addr) | (_v), (_addr)) -+#define clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr)) -+ -+#define setbits16(_addr, _v) iowrite16be(ioread16be(_addr) | (_v), (_addr)) -+#define clrbits16(_addr, _v) iowrite16be(ioread16be(_addr) & ~(_v), (_addr)) -+ -+#define setbits8(_addr, _v) iowrite8(ioread8(_addr) | (_v), (_addr)) -+#define clrbits8(_addr, _v) iowrite8(ioread8(_addr) & ~(_v), (_addr)) -+ -+/* Clear and set bits in one shot. These macros can be used to clear and -+ * set multiple bits in a register using a single read-modify-write. These -+ * macros can also be used to set a multiple-bit bit pattern using a mask, -+ * by specifying the mask in the 'clear' parameter and the new bit pattern -+ * in the 'set' parameter. -+ */ -+ -+#define clrsetbits_be32(addr, clear, set) \ -+ iowrite32be((ioread32be(addr) & ~(clear)) | (set), (addr)) -+#define clrsetbits_le32(addr, clear, set) \ -+ iowrite32le((ioread32le(addr) & ~(clear)) | (set), (addr)) -+#define clrsetbits_be16(addr, clear, set) \ -+ iowrite16be((ioread16be(addr) & ~(clear)) | (set), (addr)) -+#define clrsetbits_le16(addr, clear, set) \ -+ iowrite16le((ioread16le(addr) & ~(clear)) | (set), (addr)) -+#define clrsetbits_8(addr, clear, set) \ -+ iowrite8((ioread8(addr) & ~(clear)) | (set), (addr)) -+ - /* - * IO port access primitives - * ------------------------- diff --git a/target/linux/layerscape/patches-5.4/301-arch-0006-export-arch_setup_dma_ops.patch b/target/linux/layerscape/patches-5.4/301-arch-0006-export-arch_setup_dma_ops.patch deleted file mode 100644 index 92b748074c..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0006-export-arch_setup_dma_ops.patch +++ /dev/null @@ -1,17 +0,0 @@ -From 1c86c2f332b3aafb119c4d1ef981cd2a44286a81 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Wed, 7 Jun 2017 17:54:10 +0300 -Subject: [PATCH] export arch_setup_dma_ops() - -Signed-off-by: Madalin Bucur ---- - arch/arm64/mm/dma-mapping.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm64/mm/dma-mapping.c -+++ b/arch/arm64/mm/dma-mapping.c -@@ -57,3 +57,4 @@ void arch_setup_dma_ops(struct device *d - dev->dma_ops = &xen_swiotlb_dma_ops; - #endif - } -+EXPORT_SYMBOL(arch_setup_dma_ops); diff --git a/target/linux/layerscape/patches-5.4/301-arch-0007-arm-dma-mapping-export-arch_setup_dma_ops.patch b/target/linux/layerscape/patches-5.4/301-arch-0007-arm-dma-mapping-export-arch_setup_dma_ops.patch deleted file mode 100644 index c05b99be3a..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0007-arm-dma-mapping-export-arch_setup_dma_ops.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 5f1b16ecaac2e891c43a9bbce0f5ee1c18e5aba7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Mon, 19 Jun 2017 16:38:59 +0300 -Subject: [PATCH] arm: dma-mapping: export arch_setup_dma_ops() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Horia Geantă ---- - arch/arm/mm/dma-mapping.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/mm/dma-mapping.c -+++ b/arch/arm/mm/dma-mapping.c -@@ -2320,6 +2320,7 @@ void arch_setup_dma_ops(struct device *d - #endif - dev->archdata.dma_ops_setup = true; - } -+EXPORT_SYMBOL(arch_setup_dma_ops); - - void arch_teardown_dma_ops(struct device *dev) - { diff --git a/target/linux/layerscape/patches-5.4/301-arch-0008-arm-add-new-non-shareable-ioremap.patch b/target/linux/layerscape/patches-5.4/301-arch-0008-arm-add-new-non-shareable-ioremap.patch deleted file mode 100644 index c09efca570..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0008-arm-add-new-non-shareable-ioremap.patch +++ /dev/null @@ -1,95 +0,0 @@ -From e5bf75ca33946d81c82014168042a64db7c81551 Mon Sep 17 00:00:00 2001 -From: Pan Jiafei -Date: Thu, 17 Mar 2016 02:01:03 +0000 -Subject: [PATCH] arm: add new non-shareable ioremap - -Signed-off-by: Pan Jiafei -Signed-off-by: Roy Pledge ---- - arch/arm/include/asm/io.h | 3 +++ - arch/arm/include/asm/mach/map.h | 4 ++-- - arch/arm/mm/ioremap.c | 7 +++++++ - arch/arm/mm/mmu.c | 9 +++++++++ - 4 files changed, 21 insertions(+), 2 deletions(-) - ---- a/arch/arm/include/asm/io.h -+++ b/arch/arm/include/asm/io.h -@@ -123,6 +123,7 @@ static inline u32 __raw_readl(const vola - #define MT_DEVICE_NONSHARED 1 - #define MT_DEVICE_CACHED 2 - #define MT_DEVICE_WC 3 -+#define MT_MEMORY_RW_NS 4 - /* - * types 4 onwards can be found in asm/mach/map.h and are undefined - * for ioremap -@@ -438,6 +439,8 @@ void __iomem *ioremap_wc(resource_size_t - #define ioremap_wc ioremap_wc - #define ioremap_wt ioremap_wc - -+void __iomem *ioremap_cache_ns(resource_size_t res_cookie, size_t size); -+ - void iounmap(volatile void __iomem *iomem_cookie); - #define iounmap iounmap - ---- a/arch/arm/include/asm/mach/map.h -+++ b/arch/arm/include/asm/mach/map.h -@@ -18,9 +18,9 @@ struct map_desc { - unsigned int type; - }; - --/* types 0-3 are defined in asm/io.h */ -+/* types 0-4 are defined in asm/io.h */ - enum { -- MT_UNCACHED = 4, -+ MT_UNCACHED = 5, - MT_CACHECLEAN, - MT_MINICLEAN, - MT_LOW_VECTORS, ---- a/arch/arm/mm/ioremap.c -+++ b/arch/arm/mm/ioremap.c -@@ -401,6 +401,13 @@ void __iomem *ioremap_wc(resource_size_t - } - EXPORT_SYMBOL(ioremap_wc); - -+void __iomem *ioremap_cache_ns(resource_size_t res_cookie, size_t size) -+{ -+ return arch_ioremap_caller(res_cookie, size, MT_MEMORY_RW_NS, -+ __builtin_return_address(0)); -+} -+EXPORT_SYMBOL(ioremap_cache_ns); -+ - /* - * Remap an arbitrary physical address space into the kernel virtual - * address space as memory. Needed when the kernel wants to execute ---- a/arch/arm/mm/mmu.c -+++ b/arch/arm/mm/mmu.c -@@ -314,6 +314,13 @@ static struct mem_type mem_types[] __ro_ - .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, - .domain = DOMAIN_KERNEL, - }, -+ [MT_MEMORY_RW_NS] = { -+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | -+ L_PTE_XN, -+ .prot_l1 = PMD_TYPE_TABLE, -+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_XN, -+ .domain = DOMAIN_KERNEL, -+ }, - [MT_ROM] = { - .prot_sect = PMD_TYPE_SECT, - .domain = DOMAIN_KERNEL, -@@ -650,6 +657,7 @@ static void __init build_mem_type_table( - } - kern_pgprot |= PTE_EXT_AF; - vecs_pgprot |= PTE_EXT_AF; -+ mem_types[MT_MEMORY_RW_NS].prot_pte |= PTE_EXT_AF | cp->pte; - - /* - * Set PXN for user mappings -@@ -678,6 +686,7 @@ static void __init build_mem_type_table( - mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot; - mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd; - mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot; -+ mem_types[MT_MEMORY_RW_NS].prot_sect |= ecc_mask | cp->pmd; - mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot; - mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask; - mem_types[MT_ROM].prot_sect |= cp->pmd; diff --git a/target/linux/layerscape/patches-5.4/301-arch-0009-arm-add-pgprot_cached-and-pgprot_cached_ns-support.patch b/target/linux/layerscape/patches-5.4/301-arch-0009-arm-add-pgprot_cached-and-pgprot_cached_ns-support.patch deleted file mode 100644 index 1f990734c8..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0009-arm-add-pgprot_cached-and-pgprot_cached_ns-support.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 395718e9f6445369089dba16fa50182c5e0528f5 Mon Sep 17 00:00:00 2001 -From: Jianhua Xie -Date: Fri, 29 Jan 2016 16:40:46 +0800 -Subject: [PATCH] arm: add pgprot_cached and pgprot_cached_ns support - -Signed-off-by: Jianhua Xie ---- - arch/arm/include/asm/pgtable.h | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/arch/arm/include/asm/pgtable.h -+++ b/arch/arm/include/asm/pgtable.h -@@ -116,6 +116,13 @@ extern pgprot_t pgprot_s2_device; - #define pgprot_noncached(prot) \ - __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED) - -+#define pgprot_cached(prot) \ -+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_DEV_CACHED) -+ -+#define pgprot_cached_ns(prot) \ -+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_DEV_CACHED | \ -+ L_PTE_MT_DEV_NONSHARED) -+ - #define pgprot_writecombine(prot) \ - __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE) - diff --git a/target/linux/layerscape/patches-5.4/301-arch-0010-arm64-add-stage-2-cache-able-non-shareable-page-type.patch b/target/linux/layerscape/patches-5.4/301-arch-0010-arm64-add-stage-2-cache-able-non-shareable-page-type.patch deleted file mode 100644 index 66fd76066a..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0010-arm64-add-stage-2-cache-able-non-shareable-page-type.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 73b06aca47caafdce7bff2c7b27a070d5a8d8172 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 5 Dec 2017 15:24:05 +0200 -Subject: [PATCH] arm64: add stage-2 cache-able non-shareable page type - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/include/asm/pgtable-prot.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm64/include/asm/pgtable-prot.h -+++ b/arch/arm64/include/asm/pgtable-prot.h -@@ -78,6 +78,7 @@ - }) - - #define PAGE_S2 __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(NORMAL) | PTE_S2_RDONLY | PAGE_S2_XN) -+#define PAGE_S2_NS __pgprot(PAGE_S2_MEMATTR(NORMAL) | PTE_S2_RDWR | PTE_TYPE_PAGE | PTE_AF) - #define PAGE_S2_DEVICE __pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_S2_XN) - - #define PAGE_NONE __pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN) diff --git a/target/linux/layerscape/patches-5.4/301-arch-0011-drivers-soc-fsl-add-qixis-driver.patch b/target/linux/layerscape/patches-5.4/301-arch-0011-drivers-soc-fsl-add-qixis-driver.patch deleted file mode 100644 index bd82274be2..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0011-drivers-soc-fsl-add-qixis-driver.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 68e332146b6f0a1d2a4514810986a7cf3c3117e3 Mon Sep 17 00:00:00 2001 -From: Pankaj Bansal -Date: Thu, 28 Feb 2019 17:22:28 +0530 -Subject: [PATCH] drivers: soc: fsl: add qixis driver - -FPGA on LX2160AQDS/LX2160ARDB connected on I2C bus, so add qixis driver -which is basically an i2c client driver to control FPGA. - -Signed-off-by: Pankaj Bansal ---- - drivers/soc/fsl/Kconfig | 11 +++++ - drivers/soc/fsl/Makefile | 1 + - drivers/soc/fsl/qixis_ctrl.c | 105 +++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 117 insertions(+) - create mode 100644 drivers/soc/fsl/qixis_ctrl.c - ---- a/drivers/soc/fsl/Kconfig -+++ b/drivers/soc/fsl/Kconfig -@@ -40,4 +40,15 @@ config DPAA2_CONSOLE - /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console, - which can be used to dump the Management Complex and AIOP - firmware logs. -+ -+config FSL_QIXIS -+ tristate "QIXIS system controller driver" -+ depends on OF -+ select REGMAP_I2C -+ select REGMAP_MMIO -+ default n -+ help -+ Say y here to enable QIXIS system controller api. The qixis driver -+ provides FPGA functions to control system. -+ - endmenu ---- a/drivers/soc/fsl/Makefile -+++ b/drivers/soc/fsl/Makefile -@@ -6,6 +6,7 @@ - obj-$(CONFIG_FSL_DPAA) += qbman/ - obj-$(CONFIG_QUICC_ENGINE) += qe/ - obj-$(CONFIG_CPM) += qe/ -+obj-$(CONFIG_FSL_QIXIS) += qixis_ctrl.o - obj-$(CONFIG_FSL_GUTS) += guts.o - obj-$(CONFIG_FSL_MC_DPIO) += dpio/ - obj-$(CONFIG_DPAA2_CONSOLE) += dpaa2-console.o ---- /dev/null -+++ b/drivers/soc/fsl/qixis_ctrl.c -@@ -0,0 +1,105 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+ -+/* Freescale QIXIS system controller driver. -+ * -+ * Copyright 2015 Freescale Semiconductor, Inc. -+ * Copyright 2018-2019 NXP -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* QIXIS MAP */ -+struct fsl_qixis_regs { -+ u8 id; /* Identification Registers */ -+ u8 version; /* Version Register */ -+ u8 qixis_ver; /* QIXIS Version Register */ -+ u8 reserved1[0x1f]; -+}; -+ -+struct qixis_priv { -+ struct regmap *regmap; -+}; -+ -+static struct regmap_config qixis_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+}; -+ -+static const struct mfd_cell fsl_qixis_devs[] = { -+ { -+ .name = "reg-mux", -+ .of_compatible = "reg-mux", -+ }, -+}; -+ -+static int fsl_qixis_i2c_probe(struct i2c_client *client) -+{ -+ struct qixis_priv *priv; -+ int ret = 0; -+ u32 qver; -+ -+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) -+ return -EOPNOTSUPP; -+ -+ priv = devm_kzalloc(&client->dev, sizeof(struct qixis_priv), -+ GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ -+ priv->regmap = regmap_init_i2c(client, &qixis_regmap_config); -+ regmap_read(priv->regmap, offsetof(struct fsl_qixis_regs, qixis_ver), -+ &qver); -+ pr_info("Freescale QIXIS Version: 0x%08x\n", qver); -+ -+ i2c_set_clientdata(client, priv); -+ -+ if (of_device_is_compatible(client->dev.of_node, "simple-mfd")) -+ ret = devm_mfd_add_devices(&client->dev, -1, fsl_qixis_devs, -+ ARRAY_SIZE(fsl_qixis_devs), NULL, 0, -+ NULL); -+ if (ret) -+ goto error; -+ -+ return ret; -+error: -+ regmap_exit(priv->regmap); -+ -+ return ret; -+} -+ -+static int fsl_qixis_i2c_remove(struct i2c_client *client) -+{ -+ struct qixis_priv *priv; -+ -+ priv = i2c_get_clientdata(client); -+ regmap_exit(priv->regmap); -+ -+ return 0; -+} -+ -+static const struct of_device_id fsl_qixis_i2c_of_match[] = { -+ { .compatible = "fsl,fpga-qixis-i2c" }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, fsl_qixis_i2c_of_match); -+ -+static struct i2c_driver fsl_qixis_i2c_driver = { -+ .driver = { -+ .name = "qixis_ctrl_i2c", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(fsl_qixis_i2c_of_match), -+ }, -+ .probe_new = fsl_qixis_i2c_probe, -+ .remove = fsl_qixis_i2c_remove, -+}; -+module_i2c_driver(fsl_qixis_i2c_driver); -+ -+MODULE_AUTHOR("Wang Dongsheng "); -+MODULE_DESCRIPTION("Freescale QIXIS system controller driver"); -+MODULE_LICENSE("GPL"); -+ diff --git a/target/linux/layerscape/patches-5.4/301-arch-0012-soc-fsl-select-MFD_CORE-for-qixis-driver.patch b/target/linux/layerscape/patches-5.4/301-arch-0012-soc-fsl-select-MFD_CORE-for-qixis-driver.patch deleted file mode 100644 index aefae7c6c2..0000000000 --- a/target/linux/layerscape/patches-5.4/301-arch-0012-soc-fsl-select-MFD_CORE-for-qixis-driver.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 5451ebbfc7e8ba51bceb12ee5409364000e6475b Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Thu, 9 Apr 2020 18:24:07 +0800 -Subject: [PATCH] soc: fsl: select MFD_CORE for qixis driver - -The QIXIS driver should select MFD_CORE option. - -Signed-off-by: Yangbo Lu ---- - drivers/soc/fsl/Kconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/soc/fsl/Kconfig -+++ b/drivers/soc/fsl/Kconfig -@@ -46,6 +46,7 @@ config FSL_QIXIS - depends on OF - select REGMAP_I2C - select REGMAP_MMIO -+ select MFD_CORE - default n - help - Say y here to enable QIXIS system controller api. The qixis driver diff --git a/target/linux/layerscape/patches-5.4/302-dts-0001-sdk-arm64-dts-add-update-DPAA1-include-files-for-SDK.patch b/target/linux/layerscape/patches-5.4/302-dts-0001-sdk-arm64-dts-add-update-DPAA1-include-files-for-SDK.patch deleted file mode 100644 index cdded8a844..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0001-sdk-arm64-dts-add-update-DPAA1-include-files-for-SDK.patch +++ /dev/null @@ -1,550 +0,0 @@ -From fd5901a48f68c74f074ea5c490377b7c9f3899f5 Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Fri, 5 Oct 2018 17:52:23 -0500 -Subject: [PATCH] sdk: arm64: dts: add/update DPAA1 include files for SDK - flavor - -Signed-off-by: Camelia Groza -Signed-off-by: Madalin Bucur -Signed-off-by: Li Yang ---- - .../boot/dts/freescale/qoriq-bman-portals-sdk.dtsi | 55 +++++++++++++++++ - arch/arm64/boot/dts/freescale/qoriq-dpaa-eth.dtsi | 72 ++++++++++++++++++++++ - .../boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi | 9 +-- - .../boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi | 9 +-- - .../boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi | 5 +- - .../boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi | 5 +- - .../boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi | 5 +- - .../boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi | 5 +- - .../boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi | 5 +- - .../boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi | 5 +- - .../boot/dts/freescale/qoriq-fman3-0-6oh.dtsi | 47 ++++++++++++++ - arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi | 52 +++++++++++++++- - .../boot/dts/freescale/qoriq-qman-portals-sdk.dtsi | 38 ++++++++++++ - 13 files changed, 291 insertions(+), 21 deletions(-) - create mode 100644 arch/arm64/boot/dts/freescale/qoriq-bman-portals-sdk.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/qoriq-dpaa-eth.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/qoriq-fman3-0-6oh.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/qoriq-qman-portals-sdk.dtsi - ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/qoriq-bman-portals-sdk.dtsi -@@ -0,0 +1,55 @@ -+/* -+ * QorIQ BMan SDK Portals device tree nodes -+ * -+ * Copyright 2011-2016 Freescale Semiconductor Inc. -+ * Copyright 2017 NXP -+ * -+ * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+ */ -+ -+&bportals { -+ bman-portal@0 { -+ cell-index = <0>; -+ }; -+ -+ bman-portal@10000 { -+ cell-index = <1>; -+ }; -+ -+ bman-portal@20000 { -+ cell-index = <2>; -+ }; -+ -+ bman-portal@30000 { -+ cell-index = <3>; -+ }; -+ -+ bman-portal@40000 { -+ cell-index = <4>; -+ }; -+ -+ bman-portal@50000 { -+ cell-index = <5>; -+ }; -+ -+ bman-portal@60000 { -+ cell-index = <6>; -+ }; -+ -+ bman-portal@70000 { -+ cell-index = <7>; -+ }; -+ -+ bman-portal@80000 { -+ cell-index = <8>; -+ }; -+ -+ bman-portal@90000 { -+ cell-index = <9>; -+ }; -+ -+ bman-bpids@0 { -+ compatible = "fsl,bpid-range"; -+ fsl,bpid-range = <32 32>; -+ }; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/qoriq-dpaa-eth.dtsi -@@ -0,0 +1,72 @@ -+/* -+ * QorIQ FMan v3 10g port #1 device tree stub [ controller @ offset 0x400000 ] -+ * -+ * Copyright 2012 - 2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+fsldpaa: fsl,dpaa { -+ compatible = "fsl,ls1043a-dpaa", "simple-bus", "fsl,dpaa"; -+ ethernet@0 { -+ compatible = "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet0>; -+ dma-coherent; -+ }; -+ ethernet@1 { -+ compatible = "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet1>; -+ dma-coherent; -+ }; -+ ethernet@2 { -+ compatible = "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet2>; -+ dma-coherent; -+ }; -+ ethernet@3 { -+ compatible = "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet3>; -+ dma-coherent; -+ }; -+ ethernet@4 { -+ compatible = "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet4>; -+ dma-coherent; -+ }; -+ ethernet@5 { -+ compatible = "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet5>; -+ dma-coherent; -+ }; -+ ethernet@8 { -+ compatible = "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet6>; -+ dma-coherent; -+ }; -+}; ---- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi -@@ -9,19 +9,20 @@ - fman@1a00000 { - fman0_rx_0x10: port@90000 { - cell-index = <0x10>; -- compatible = "fsl,fman-v3-port-rx"; -+ compatible = "fsl,fman-v3-port-rx", "fsl,fman-port-10g-rx"; - reg = <0x90000 0x1000>; - fsl,fman-10g-port; - }; - - fman0_tx_0x30: port@b0000 { - cell-index = <0x30>; -- compatible = "fsl,fman-v3-port-tx"; -+ compatible = "fsl,fman-v3-port-tx", "fsl,fman-port-10g-tx"; - reg = <0xb0000 0x1000>; - fsl,fman-10g-port; -+ fsl,qman-channel-id = <0x800>; - }; - -- ethernet@f0000 { -+ mac9: ethernet@f0000 { - cell-index = <0x8>; - compatible = "fsl,fman-memac"; - reg = <0xf0000 0x1000>; -@@ -29,7 +30,7 @@ fman@1a00000 { - pcsphy-handle = <&pcsphy6>; - }; - -- mdio@f1000 { -+ mdio9: mdio@f1000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; ---- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi -@@ -9,19 +9,20 @@ - fman@1a00000 { - fman0_rx_0x11: port@91000 { - cell-index = <0x11>; -- compatible = "fsl,fman-v3-port-rx"; -+ compatible = "fsl,fman-v3-port-rx", "fsl,fman-port-10g-rx"; - reg = <0x91000 0x1000>; - fsl,fman-10g-port; - }; - - fman0_tx_0x31: port@b1000 { - cell-index = <0x31>; -- compatible = "fsl,fman-v3-port-tx"; -+ compatible = "fsl,fman-v3-port-tx", "fsl,fman-port-10g-tx"; - reg = <0xb1000 0x1000>; - fsl,fman-10g-port; -+ fsl,qman-channel-id = <0x801>; - }; - -- ethernet@f2000 { -+ mac10: ethernet@f2000 { - cell-index = <0x9>; - compatible = "fsl,fman-memac"; - reg = <0xf2000 0x1000>; -@@ -29,7 +30,7 @@ fman@1a00000 { - pcsphy-handle = <&pcsphy7>; - }; - -- mdio@f3000 { -+ mdio10: mdio@f3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; ---- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-0.dtsi -@@ -9,14 +9,15 @@ - fman@1a00000 { - fman0_rx_0x08: port@88000 { - cell-index = <0x8>; -- compatible = "fsl,fman-v3-port-rx"; -+ compatible = "fsl,fman-v3-port-rx", "fsl,fman-port-1g-rx"; - reg = <0x88000 0x1000>; - }; - - fman0_tx_0x28: port@a8000 { - cell-index = <0x28>; -- compatible = "fsl,fman-v3-port-tx"; -+ compatible = "fsl,fman-v3-port-tx", "fsl,fman-port-1g-tx"; - reg = <0xa8000 0x1000>; -+ fsl,qman-channel-id = <0x802>; - }; - - ethernet@e0000 { ---- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-1.dtsi -@@ -9,14 +9,15 @@ - fman@1a00000 { - fman0_rx_0x09: port@89000 { - cell-index = <0x9>; -- compatible = "fsl,fman-v3-port-rx"; -+ compatible = "fsl,fman-v3-port-rx", "fsl,fman-port-1g-rx"; - reg = <0x89000 0x1000>; - }; - - fman0_tx_0x29: port@a9000 { - cell-index = <0x29>; -- compatible = "fsl,fman-v3-port-tx"; -+ compatible = "fsl,fman-v3-port-tx", "fsl,fman-port-1g-tx"; - reg = <0xa9000 0x1000>; -+ fsl,qman-channel-id = <0x803>; - }; - - ethernet@e2000 { ---- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-2.dtsi -@@ -9,14 +9,15 @@ - fman@1a00000 { - fman0_rx_0x0a: port@8a000 { - cell-index = <0xa>; -- compatible = "fsl,fman-v3-port-rx"; -+ compatible = "fsl,fman-v3-port-rx", "fsl,fman-port-1g-rx"; - reg = <0x8a000 0x1000>; - }; - - fman0_tx_0x2a: port@aa000 { - cell-index = <0x2a>; -- compatible = "fsl,fman-v3-port-tx"; -+ compatible = "fsl,fman-v3-port-tx", "fsl,fman-port-1g-tx"; - reg = <0xaa000 0x1000>; -+ fsl,qman-channel-id = <0x804>; - }; - - ethernet@e4000 { ---- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-3.dtsi -@@ -9,14 +9,15 @@ - fman@1a00000 { - fman0_rx_0x0b: port@8b000 { - cell-index = <0xb>; -- compatible = "fsl,fman-v3-port-rx"; -+ compatible = "fsl,fman-v3-port-rx", "fsl,fman-port-1g-rx"; - reg = <0x8b000 0x1000>; - }; - - fman0_tx_0x2b: port@ab000 { - cell-index = <0x2b>; -- compatible = "fsl,fman-v3-port-tx"; -+ compatible = "fsl,fman-v3-port-tx", "fsl,fman-port-1g-tx"; - reg = <0xab000 0x1000>; -+ fsl,qman-channel-id = <0x805>; - }; - - ethernet@e6000 { ---- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-4.dtsi -@@ -9,14 +9,15 @@ - fman@1a00000 { - fman0_rx_0x0c: port@8c000 { - cell-index = <0xc>; -- compatible = "fsl,fman-v3-port-rx"; -+ compatible = "fsl,fman-v3-port-rx", "fsl,fman-port-1g-rx"; - reg = <0x8c000 0x1000>; - }; - - fman0_tx_0x2c: port@ac000 { - cell-index = <0x2c>; -- compatible = "fsl,fman-v3-port-tx"; -+ compatible = "fsl,fman-v3-port-tx", "fsl,fman-port-1g-tx"; - reg = <0xac000 0x1000>; -+ fsl,qman-channel-id = <0x806>; - }; - - ethernet@e8000 { ---- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-1g-5.dtsi -@@ -9,14 +9,15 @@ - fman@1a00000 { - fman0_rx_0x0d: port@8d000 { - cell-index = <0xd>; -- compatible = "fsl,fman-v3-port-rx"; -+ compatible = "fsl,fman-v3-port-rx", "fsl,fman-port-1g-rx"; - reg = <0x8d000 0x1000>; - }; - - fman0_tx_0x2d: port@ad000 { - cell-index = <0x2d>; -- compatible = "fsl,fman-v3-port-tx"; -+ compatible = "fsl,fman-v3-port-tx", "fsl,fman-port-1g-tx"; - reg = <0xad000 0x1000>; -+ fsl,qman-channel-id = <0x807>; - }; - - ethernet@ea000 { ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-6oh.dtsi -@@ -0,0 +1,47 @@ -+/* -+ * QorIQ FMan v3 OH ports device tree -+ * -+ * Copyright 2012-2015 Freescale Semiconductor Inc. -+ * -+ * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+ */ -+ -+fman@1a00000 { -+ -+ fman0_oh1: port@82000 { -+ cell-index = <0>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x82000 0x1000>; -+ }; -+ -+ fman0_oh2: port@83000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x83000 0x1000>; -+ }; -+ -+ fman0_oh3: port@84000 { -+ cell-index = <2>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x84000 0x1000>; -+ }; -+ -+ fman0_oh4: port@85000 { -+ cell-index = <3>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x85000 0x1000>; -+ }; -+ -+ fman0_oh5: port@86000 { -+ cell-index = <4>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x86000 0x1000>; -+ }; -+ -+ fman0_oh6: port@87000 { -+ cell-index = <5>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x87000 0x1000>; -+ }; -+ -+}; ---- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0.dtsi -@@ -20,45 +20,95 @@ fman0: fman@1a00000 { - fsl,qman-channel-range = <0x800 0x10>; - ptimer-handle = <&ptp_timer0>; - -+ cc { -+ compatible = "fsl,fman-cc"; -+ }; -+ - muram@0 { - compatible = "fsl,fman-muram"; - reg = <0x0 0x60000>; - }; - -+ bmi@80000 { -+ compatible = "fsl,fman-bmi"; -+ reg = <0x80000 0x400>; -+ }; -+ -+ qmi@80400 { -+ compatible = "fsl,fman-qmi"; -+ reg = <0x80400 0x400>; -+ }; -+ - fman0_oh_0x2: port@82000 { - cell-index = <0x2>; - compatible = "fsl,fman-v3-port-oh"; - reg = <0x82000 0x1000>; -+ fsl,qman-channel-id = <0x809>; - }; - - fman0_oh_0x3: port@83000 { - cell-index = <0x3>; - compatible = "fsl,fman-v3-port-oh"; - reg = <0x83000 0x1000>; -+ fsl,qman-channel-id = <0x80a>; - }; - - fman0_oh_0x4: port@84000 { - cell-index = <0x4>; - compatible = "fsl,fman-v3-port-oh"; - reg = <0x84000 0x1000>; -+ fsl,qman-channel-id = <0x80b>; - }; - - fman0_oh_0x5: port@85000 { - cell-index = <0x5>; - compatible = "fsl,fman-v3-port-oh"; - reg = <0x85000 0x1000>; -+ fsl,qman-channel-id = <0x80c>; - }; - - fman0_oh_0x6: port@86000 { - cell-index = <0x6>; - compatible = "fsl,fman-v3-port-oh"; - reg = <0x86000 0x1000>; -+ fsl,qman-channel-id = <0x80d>; - }; - - fman0_oh_0x7: port@87000 { - cell-index = <0x7>; - compatible = "fsl,fman-v3-port-oh"; - reg = <0x87000 0x1000>; -+ fsl,qman-channel-id = <0x80e>; -+ }; -+ -+ policer@c0000 { -+ compatible = "fsl,fman-policer"; -+ reg = <0xc0000 0x1000>; -+ }; -+ -+ keygen@c1000 { -+ compatible = "fsl,fman-keygen"; -+ reg = <0xc1000 0x1000>; -+ }; -+ -+ dma@c2000 { -+ compatible = "fsl,fman-dma"; -+ reg = <0xc2000 0x1000>; -+ }; -+ -+ fpm@c3000 { -+ compatible = "fsl,fman-fpm"; -+ reg = <0xc3000 0x1000>; -+ }; -+ -+ parser@c7000 { -+ compatible = "fsl,fman-parser"; -+ reg = <0xc7000 0x1000>; -+ }; -+ -+ vsps@dc000 { -+ compatible = "fsl,fman-vsps"; -+ reg = <0xdc000 0x1000>; - }; - - mdio0: mdio@fc000 { -@@ -77,7 +127,7 @@ fman0: fman@1a00000 { - }; - - ptp_timer0: ptp-timer@1afe000 { -- compatible = "fsl,fman-ptp-timer"; -+ compatible = "fsl,fman-ptp-timer", "fsl,fman-rtc"; - reg = <0x0 0x1afe000 0x0 0x1000>; - interrupts = ; - clocks = <&clockgen 3 0>; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/qoriq-qman-portals-sdk.dtsi -@@ -0,0 +1,38 @@ -+/* -+ * QorIQ QMan SDK Portals device tree nodes -+ * -+ * Copyright 2011-2016 Freescale Semiconductor Inc. -+ * Copyright 2017 NXP -+ * -+ * SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+ */ -+ -+&qportals { -+ qman-fqids@0 { -+ compatible = "fsl,fqid-range"; -+ fsl,fqid-range = <256 256>; -+ }; -+ -+ qman-fqids@1 { -+ compatible = "fsl,fqid-range"; -+ fsl,fqid-range = <32768 32768>; -+ }; -+ -+ qman-pools@0 { -+ compatible = "fsl,pool-channel-range"; -+ fsl,pool-channel-range = <0x401 0xf>; -+ }; -+ -+ qman-cgrids@0 { -+ compatible = "fsl,cgrid-range"; -+ fsl,cgrid-range = <0 256>; -+ }; -+ -+ qman-ceetm@0 { -+ compatible = "fsl,qman-ceetm"; -+ fsl,ceetm-lfqid-range = <0xf00000 0x1000>; -+ fsl,ceetm-sp-range = <0 16>; -+ fsl,ceetm-lni-range = <0 8>; -+ fsl,ceetm-channel-range = <0 32>; -+ }; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0002-sdk-arm64-dts-add-DPAA1-SDK-flavor-dts-files.patch b/target/linux/layerscape/patches-5.4/302-dts-0002-sdk-arm64-dts-add-DPAA1-SDK-flavor-dts-files.patch deleted file mode 100644 index 8a53e9278c..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0002-sdk-arm64-dts-add-DPAA1-SDK-flavor-dts-files.patch +++ /dev/null @@ -1,626 +0,0 @@ -From 7f3b260e937238632e523306089e856d0db1a4f9 Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Fri, 5 Oct 2018 18:03:25 -0500 -Subject: [PATCH] sdk: arm64: dts: add DPAA1 SDK flavor dts files - -Signed-off-by: Camelia Groza -Signed-off-by: Madalin Bucur -Signed-off-by: Iordache Florinel-R70177 -Signed-off-by: Roy Pledge -Signed-off-by: Li Yang ---- - arch/arm64/boot/dts/freescale/Makefile | 6 ++ - .../boot/dts/freescale/fsl-ls1043a-qds-sdk.dts | 71 +++++++++++++ - .../boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts | 71 +++++++++++++ - .../boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts | 117 +++++++++++++++++++++ - .../boot/dts/freescale/fsl-ls1046a-qds-sdk.dts | 79 ++++++++++++++ - .../boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts | 115 ++++++++++++++++++++ - .../boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts | 110 +++++++++++++++++++ - 7 files changed, 569 insertions(+) - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1043a-qds-sdk.dts - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1046a-qds-sdk.dts - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts - ---- a/arch/arm64/boot/dts/freescale/Makefile -+++ b/arch/arm64/boot/dts/freescale/Makefile -@@ -7,10 +7,16 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1 - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds-sdk.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb-sdk.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb-usdpaa.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-frwy.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-qds.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-qds-sdk.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-rdb.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-rdb-sdk.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-rdb-usdpaa.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-qds.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-rdb.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-qds.dtb ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds-sdk.dts -@@ -0,0 +1,71 @@ -+/* -+ * Device Tree Include file for Freescale Layerscape-1043A family SoC. -+ * -+ * Copyright 2014-2015 Freescale Semiconductor, Inc. -+ * -+ * Mingkai Hu -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPLv2 or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include "fsl-ls1043a-qds.dts" -+#include "qoriq-qman-portals-sdk.dtsi" -+#include "qoriq-bman-portals-sdk.dtsi" -+ -+&bman_fbpr { -+ compatible = "fsl,bman-fbpr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_fqd { -+ compatible = "fsl,qman-fqd"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_pfdr { -+ compatible = "fsl,qman-pfdr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+ -+&soc { -+#include "qoriq-dpaa-eth.dtsi" -+#include "qoriq-fman3-0-6oh.dtsi" -+}; -+ -+&fman0 { -+ compatible = "fsl,fman", "simple-bus"; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts -@@ -0,0 +1,71 @@ -+/* -+ * Device Tree Include file for Freescale Layerscape-1043A family SoC. -+ * -+ * Copyright 2014-2015 Freescale Semiconductor, Inc. -+ * -+ * Mingkai Hu -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPLv2 or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include "fsl-ls1043a-rdb.dts" -+#include "qoriq-qman-portals-sdk.dtsi" -+#include "qoriq-bman-portals-sdk.dtsi" -+ -+&bman_fbpr { -+ compatible = "fsl,bman-fbpr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_fqd { -+ compatible = "fsl,qman-fqd"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_pfdr { -+ compatible = "fsl,qman-pfdr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+ -+&soc { -+#include "qoriq-dpaa-eth.dtsi" -+#include "qoriq-fman3-0-6oh.dtsi" -+}; -+ -+&fman0 { -+ compatible = "fsl,fman", "simple-bus"; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts -@@ -0,0 +1,117 @@ -+/* -+ * Device Tree Include file for Freescale Layerscape-1043A family SoC. -+ * -+ * Copyright (C) 2014-2015, Freescale Semiconductor -+ * -+ * This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without any -+ * warranty of any kind, whether express or implied. -+ */ -+ -+#include "fsl-ls1043a-rdb-sdk.dts" -+ -+&soc { -+ bp7: buffer-pool@7 { -+ compatible = "fsl,p4080-bpool", "fsl,bpool"; -+ fsl,bpid = <7>; -+ fsl,bpool-ethernet-cfg = <0 0 0 192 0 0xdeadbeef>; -+ fsl,bpool-thresholds = <0x400 0xc00 0x0 0x0>; -+ }; -+ -+ bp8: buffer-pool@8 { -+ compatible = "fsl,p4080-bpool", "fsl,bpool"; -+ fsl,bpid = <8>; -+ fsl,bpool-ethernet-cfg = <0 0 0 576 0 0xabbaf00d>; -+ fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ }; -+ -+ bp9: buffer-pool@9 { -+ compatible = "fsl,p4080-bpool", "fsl,bpool"; -+ fsl,bpid = <9>; -+ fsl,bpool-ethernet-cfg = <0 0 0 2048 0 0xfeedabba>; -+ fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ }; -+ -+ fsl,dpaa { -+ compatible = "fsl,ls1043a", "fsl,dpaa", "simple-bus"; -+ -+ ethernet@0 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x50 1 0x51 1>; -+ fsl,qman-frame-queues-tx = <0x70 1 0x71 1>; -+ }; -+ -+ ethernet@1 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x52 1 0x53 1>; -+ fsl,qman-frame-queues-tx = <0x72 1 0x73 1>; -+ }; -+ -+ ethernet@2 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x54 1 0x55 1>; -+ fsl,qman-frame-queues-tx = <0x74 1 0x75 1>; -+ }; -+ -+ ethernet@3 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x56 1 0x57 1>; -+ fsl,qman-frame-queues-tx = <0x76 1 0x77 1>; -+ }; -+ -+ ethernet@4 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x58 1 0x59 1>; -+ fsl,qman-frame-queues-tx = <0x78 1 0x79 1>; -+ }; -+ -+ ethernet@5 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x60 1 0x61 1>; -+ fsl,qman-frame-queues-tx = <0x80 1 0x81 1>; -+ }; -+ -+ ethernet@8 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x5c 1 0x5d 1>; -+ fsl,qman-frame-queues-tx = <0x7c 1 0x7d 1>; -+ -+ }; -+ dpa-fman0-oh@2 { -+ compatible = "fsl,dpa-oh"; -+ /* Define frame queues for the OH port*/ -+ /* */ -+ fsl,qman-frame-queues-oh = <0x5a 1 0x5b 1>; -+ fsl,fman-oh-port = <&fman0_oh2>; -+ }; -+ }; -+}; -+/ { -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ usdpaa_mem: usdpaa_mem { -+ compatible = "fsl,usdpaa-mem"; -+ alloc-ranges = <0 0 0x10000 0>; -+ size = <0 0x10000000>; -+ alignment = <0 0x10000000>; -+ }; -+ }; -+}; -+ -+&fman0 { -+ fman0_oh2: port@83000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x83000 0x1000>; -+ }; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds-sdk.dts -@@ -0,0 +1,79 @@ -+/* -+ * Device Tree Include file for Freescale Layerscape-1046A family SoC. -+ * -+ * Copyright 2014-2015 Freescale Semiconductor, Inc. -+ * -+ * Mingkai Hu -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPLv2 or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include "fsl-ls1046a-qds.dts" -+#include "qoriq-qman-portals-sdk.dtsi" -+#include "qoriq-bman-portals-sdk.dtsi" -+ -+&bman_fbpr { -+ compatible = "fsl,bman-fbpr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_fqd { -+ compatible = "fsl,qman-fqd"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_pfdr { -+ compatible = "fsl,qman-pfdr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+ -+&soc { -+#include "qoriq-dpaa-eth.dtsi" -+#include "qoriq-fman3-0-6oh.dtsi" -+}; -+ -+&fsldpaa { -+ ethernet@9 { -+ compatible = "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet7>; -+ dma-coherent; -+ }; -+}; -+ -+&fman0 { -+ compatible = "fsl,fman", "simple-bus"; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts -@@ -0,0 +1,115 @@ -+/* -+ * Device Tree Include file for Freescale Layerscape-1046A family SoC. -+ * -+ * Copyright 2014-2015 Freescale Semiconductor, Inc. -+ * -+ * Mingkai Hu -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPLv2 or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include "fsl-ls1046a-rdb.dts" -+#include "qoriq-qman-portals-sdk.dtsi" -+#include "qoriq-bman-portals-sdk.dtsi" -+ -+&bman_fbpr { -+ compatible = "fsl,bman-fbpr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_fqd { -+ compatible = "fsl,qman-fqd"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_pfdr { -+ compatible = "fsl,qman-pfdr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+ -+&soc { -+#include "qoriq-dpaa-eth.dtsi" -+#include "qoriq-fman3-0-6oh.dtsi" -+}; -+ -+&fsldpaa { -+ ethernet@0 { -+ status = "disabled"; -+ }; -+ ethernet@1 { -+ status = "disabled"; -+ }; -+ ethernet@9 { -+ compatible = "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet7>; -+ dma-coherent; -+ }; -+}; -+ -+&fman0 { -+ compatible = "fsl,fman", "simple-bus"; -+}; -+ -+&mdio9 { -+ pcsphy6: ethernet-phy@0 { -+ backplane-mode = "10gbase-kr"; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0x8C0 0x40>; /* lane D */ -+ }; -+}; -+ -+&mdio10 { -+ pcsphy7: ethernet-phy@0 { -+ backplane-mode = "10gbase-kr"; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0x880 0x40>; /* lane C */ -+ }; -+}; -+ -+/* Update MAC connections to backplane PHYs -+ * &mac9 { -+ * phy-handle = <&pcsphy6>; -+ *}; -+ * -+ *&mac10 { -+ * phy-handle = <&pcsphy7>; -+ *}; -+*/ ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts -@@ -0,0 +1,110 @@ -+/* -+ * Device Tree Include file for Freescale Layerscape-1046A family SoC. -+ * -+ * Copyright (C) 2016, Freescale Semiconductor -+ * -+ * This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without any -+ * warranty of any kind, whether express or implied. -+ */ -+ -+#include "fsl-ls1046a-rdb-sdk.dts" -+ -+&soc { -+ bp7: buffer-pool@7 { -+ compatible = "fsl,ls1046a-bpool", "fsl,bpool"; -+ fsl,bpid = <7>; -+ fsl,bpool-ethernet-cfg = <0 0 0 192 0 0xdeadbeef>; -+ fsl,bpool-thresholds = <0x400 0xc00 0x0 0x0>; -+ }; -+ -+ bp8: buffer-pool@8 { -+ compatible = "fsl,ls1046a-bpool", "fsl,bpool"; -+ fsl,bpid = <8>; -+ fsl,bpool-ethernet-cfg = <0 0 0 576 0 0xabbaf00d>; -+ fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ }; -+ -+ bp9: buffer-pool@9 { -+ compatible = "fsl,ls1046a-bpool", "fsl,bpool"; -+ fsl,bpid = <9>; -+ fsl,bpool-ethernet-cfg = <0 0 0 2048 0 0xfeedabba>; -+ fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ }; -+ -+ fsl,dpaa { -+ compatible = "fsl,ls1046a", "fsl,dpaa", "simple-bus"; -+ -+ ethernet@2 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x54 1 0x55 1>; -+ fsl,qman-frame-queues-tx = <0x74 1 0x75 1>; -+ }; -+ -+ ethernet@3 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x56 1 0x57 1>; -+ fsl,qman-frame-queues-tx = <0x76 1 0x77 1>; -+ }; -+ -+ ethernet@4 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x58 1 0x59 1>; -+ fsl,qman-frame-queues-tx = <0x78 1 0x79 1>; -+ }; -+ -+ ethernet@5 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x5a 1 0x5b 1>; -+ fsl,qman-frame-queues-tx = <0x7a 1 0x7b 1>; -+ }; -+ -+ ethernet@8 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x5c 1 0x5d 1>; -+ fsl,qman-frame-queues-tx = <0x7c 1 0x7d 1>; -+ }; -+ -+ ethernet@9 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x5e 1 0x5f 1>; -+ fsl,qman-frame-queues-tx = <0x7e 1 0x7f 1>; -+ }; -+ -+ dpa-fman0-oh@2 { -+ compatible = "fsl,dpa-oh"; -+ /* Define frame queues for the OH port*/ -+ /* */ -+ fsl,qman-frame-queues-oh = <0x60 1 0x61 1>; -+ fsl,fman-oh-port = <&fman0_oh2>; -+ }; -+ }; -+}; -+/ { -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ usdpaa_mem: usdpaa_mem { -+ compatible = "fsl,usdpaa-mem"; -+ alloc-ranges = <0 0 0x10000 0>; -+ size = <0 0x10000000>; -+ alignment = <0 0x10000000>; -+ }; -+ }; -+}; -+ -+&fman0 { -+ fman0_oh2: port@83000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x83000 0x1000>; -+ }; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0003-arm64-dts-ls1012a-Add-LS1012A-2G5RDB-board-support.patch b/target/linux/layerscape/patches-5.4/302-dts-0003-arm64-dts-ls1012a-Add-LS1012A-2G5RDB-board-support.patch deleted file mode 100644 index 56501c39c8..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0003-arm64-dts-ls1012a-Add-LS1012A-2G5RDB-board-support.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 3261cabf5607c9f434faa4930ab5c2b0150579c4 Mon Sep 17 00:00:00 2001 -From: Bhaskar Upadhaya -Date: Wed, 29 Nov 2017 06:23:14 +0530 -Subject: [PATCH] arm64: dts: ls1012a: Add LS1012A-2G5RDB board support - -LS1012A-2G5RDB is a different design from LS1012ARDB, -but has some common SoC features. Key feature on this -board is 2.5Gbps SGMII. - -Signed-off-by: Bhaskar Upadhaya -Signed-off-by: Li Yang ---- - arch/arm64/boot/dts/freescale/Makefile | 1 + - .../boot/dts/freescale/fsl-ls1012a-2g5rdb.dts | 86 ++++++++++++++++++++++ - 2 files changed, 87 insertions(+) - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1012a-2g5rdb.dts - ---- a/arch/arm64/boot/dts/freescale/Makefile -+++ b/arch/arm64/boot/dts/freescale/Makefile -@@ -1,4 +1,5 @@ - # SPDX-License-Identifier: GPL-2.0 -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-2g5rdb.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frdm.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frwy.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-oxalis.dtb ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-2g5rdb.dts -@@ -0,0 +1,86 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree file for NXP LS1012A 2G5RDB Board. -+ * -+ * Copyright 2017 NXP -+ * -+ * Bhaskar Upadhaya -+ */ -+/dts-v1/; -+ -+#include "fsl-ls1012a.dtsi" -+ -+/ { -+ model = "LS1012A 2G5RDB Board"; -+ compatible = "fsl,ls1012a-rdb", "fsl,ls1012a"; -+ -+ aliases { -+ ethernet0 = &pfe_mac0; -+ ethernet1 = &pfe_mac1; -+ }; -+}; -+ -+&duart0 { -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+}; -+ -+&qspi { -+ num-cs = <2>; -+ bus-num = <0>; -+ status = "okay"; -+ -+ qflash0: s25fs512s@0 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <20000000>; -+ m25p,fast-read; -+ reg = <0>; -+ }; -+}; -+ -+&sata { -+ status = "okay"; -+}; -+ -+&pfe { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethernet@0 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0>; /* GEM_ID */ -+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -+ fsl,gemac-phy-id = <0x1>; /* PHY_ID */ -+ fsl,mdio-mux-val = <0x0>; -+ phy-mode = "sgmii-2500"; -+ fsl,pfe-phy-if-flags = <0x0>; -+ -+ mdio@0 { -+ reg = <0x1>; /* enabled/disabled */ -+ }; -+ }; -+ -+ ethernet@1 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x1>; /* GEM_ID */ -+ fsl,gemac-bus-id = < 0x0>; /* BUS_ID */ -+ fsl,gemac-phy-id = < 0x2>; /* PHY_ID */ -+ fsl,mdio-mux-val = <0x0>; -+ phy-mode = "sgmii-2500"; -+ fsl,pfe-phy-if-flags = <0x0>; -+ -+ mdio@0 { -+ reg = <0x0>; /* enabled/disabled */ -+ }; -+ }; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0004-arm64-dts-ls1012a-Add-more-nodes-to-LS1012A-FRWY-boa.patch b/target/linux/layerscape/patches-5.4/302-dts-0004-arm64-dts-ls1012a-Add-more-nodes-to-LS1012A-FRWY-boa.patch deleted file mode 100644 index 97348131ef..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0004-arm64-dts-ls1012a-Add-more-nodes-to-LS1012A-FRWY-boa.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 9ba5a56b7241c46aa47544f8414ad1f3d445f3c1 Mon Sep 17 00:00:00 2001 -From: Bhaskar Upadhaya -Date: Mon, 7 May 2018 11:52:04 +0530 -Subject: [PATCH] arm64: dts: ls1012a: Add more nodes to LS1012A-FRWY board - support - -LS1012A-FRWY is a different design from LS1012A-FRDM, -but has some common SoC features. Key feature on this -board is 2x1G SGMII PFE MAC, Micro SD, USB 3.0, DDR, -QuadSPI, Audio, UART. - -Signed-off-by: Bhaskar Upadhaya -Signed-off-by: Li Yang ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts | 118 +++++++++++++++++++++ - 1 file changed, 118 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts -@@ -14,6 +14,58 @@ - / { - model = "LS1012A FRWY Board"; - compatible = "fsl,ls1012a-frwy", "fsl,ls1012a"; -+ -+ aliases { -+ ethernet0 = &pfe_mac0; -+ ethernet1 = &pfe_mac1; -+ }; -+ -+ sys_mclk: clock-mclk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <25000000>; -+ }; -+ -+ reg_1p8v: regulator-1p8v { -+ compatible = "regulator-fixed"; -+ regulator-name = "1P8V"; -+ regulator-min-microvolt = <1800000>; -+ regulator-max-microvolt = <1800000>; -+ regulator-always-on; -+ }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,widgets = -+ "Microphone", "Microphone Jack", -+ "Headphone", "Headphone Jack", -+ "Speaker", "Speaker Ext", -+ "Line", "Line In Jack"; -+ simple-audio-card,routing = -+ "MIC_IN", "Microphone Jack", -+ "Microphone Jack", "Mic Bias", -+ "LINE_IN", "Line In Jack", -+ "Headphone Jack", "HP_OUT", -+ "Speaker Ext", "LINE_OUT"; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&sai2>; -+ frame-master; -+ bitclock-master; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&codec>; -+ frame-master; -+ bitclock-master; -+ system-clock-frequency = <25000000>; -+ }; -+ }; -+}; -+ -+&pcie { -+ status = "okay"; - }; - - &duart0 { -@@ -22,4 +74,70 @@ - - &i2c0 { - status = "okay"; -+ -+ codec: sgtl5000@a { -+ compatible = "fsl,sgtl5000"; -+ #sound-dai-cells = <0>; -+ reg = <0xa>; -+ VDDA-supply = <®_1p8v>; -+ VDDIO-supply = <®_1p8v>; -+ clocks = <&sys_mclk>; -+ }; -+}; -+ -+&qspi { -+ num-cs = <1>; -+ bus-num = <0>; -+ status = "okay"; -+ -+ qflash0: w25q16dw@0 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ m25p,fast-read; -+ spi-max-frequency = <20000000>; -+ reg = <0>; -+ }; -+}; -+ -+&pfe { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethernet@0 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0>; /* GEM_ID */ -+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */ -+ fsl,mdio-mux-val = <0x0>; -+ phy-mode = "sgmii"; -+ fsl,pfe-phy-if-flags = <0x0>; -+ -+ mdio@0 { -+ reg = <0x1>; /* enabled/disabled */ -+ }; -+ }; -+ -+ ethernet@1 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x1>; /* GEM_ID */ -+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */ -+ fsl,gemac-phy-id = <0x1>; /* PHY_ID */ -+ fsl,mdio-mux-val = <0x0>; -+ phy-mode = "sgmii"; -+ fsl,pfe-phy-if-flags = <0x0>; -+ -+ mdio@0 { -+ reg = <0x0>; /* enabled/disabled */ -+ }; -+ }; -+}; -+ -+&sai2 { -+ status = "okay"; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0005-arm64-dts-ls2081ardb-Add-DTS-support-for-NXP-LS2081A.patch b/target/linux/layerscape/patches-5.4/302-dts-0005-arm64-dts-ls2081ardb-Add-DTS-support-for-NXP-LS2081A.patch deleted file mode 100644 index 38941722ff..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0005-arm64-dts-ls2081ardb-Add-DTS-support-for-NXP-LS2081A.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 5508bc9764760ca32990d5f7fa494be78e711ff6 Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Fri, 5 Oct 2018 18:22:46 -0500 -Subject: [PATCH] arm64: dts: ls2081ardb: Add DTS support for NXP LS2081ARDB - -This patch add support for NXP LS2081ARDB board which has -LS2081A SoC. - -LS2081A SoC is 40-pin derivative of LS2088A SoC -So, from functional perspective both are same. -Hence,ls2088a SoC dtsi files are included from ls2081ARDB dts - -Signed-off-by: Priyanka Jain -Signed-off-by: Santan Kumar -Signed-off-by: Tao Yang -Signed-off-by: Yogesh Gaur -Signed-off-by: Abhimanyu Saini -Signed-off-by: Li Yang ---- - arch/arm64/boot/dts/freescale/Makefile | 1 + - arch/arm64/boot/dts/freescale/fsl-ls2081a-rdb.dts | 127 ++++++++++++++++++++++ - 2 files changed, 128 insertions(+) - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls2081a-rdb.dts - ---- a/arch/arm64/boot/dts/freescale/Makefile -+++ b/arch/arm64/boot/dts/freescale/Makefile -@@ -22,6 +22,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1 - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-rdb.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-qds.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-rdb.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2081a-rdb.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-qds.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-rdb.dtb ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls2081a-rdb.dts -@@ -0,0 +1,127 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree file for NXP LS2081A RDB Board. -+ * -+ * Copyright 2017 NXP -+ * -+ * Priyanka Jain -+ * -+ */ -+ -+/dts-v1/; -+ -+#include "fsl-ls2088a.dtsi" -+ -+/ { -+ model = "NXP Layerscape 2081A RDB Board"; -+ compatible = "fsl,ls2081a-rdb", "fsl,ls2081a"; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ }; -+ -+ chosen { -+ stdout-path = "serial1:115200n8"; -+ }; -+}; -+ -+&esdhc { -+ status = "okay"; -+}; -+ -+&ifc { -+ status = "disabled"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ pca9547@75 { -+ compatible = "nxp,pca9547"; -+ reg = <0x75>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ i2c@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x01>; -+ rtc@51 { -+ compatible = "nxp,pcf2129"; -+ reg = <0x51>; -+ }; -+ }; -+ -+ i2c@2 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x02>; -+ -+ ina220@40 { -+ compatible = "ti,ina220"; -+ reg = <0x40>; -+ shunt-resistor = <500>; -+ }; -+ }; -+ -+ i2c@3 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x3>; -+ -+ adt7481@4c { -+ compatible = "adi,adt7461"; -+ reg = <0x4c>; -+ }; -+ }; -+ }; -+}; -+ -+&dspi { -+ status = "okay"; -+ dflash0: n25q512a@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "st,m25p80"; -+ spi-max-frequency = <3000000>; -+ reg = <0>; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ fsl,qspi-has-second-chip; -+ flash0: s25fs512s@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "spansion,m25p80"; -+ spi-rx-bus-width = <4>; -+ spi-tx-bus-width = <4>; -+ spi-max-frequency = <20000000>; -+ reg = <0>; -+ }; -+ flash1: s25fs512s@1 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-rx-bus-width = <4>; -+ spi-tx-bus-width = <4>; -+ compatible = "spansion,m25p80"; -+ spi-max-frequency = <20000000>; -+ reg = <1>; -+ }; -+}; -+ -+&sata0 { -+ status = "okay"; -+}; -+ -+&sata1 { -+ status = "okay"; -+}; -+ -+&usb0 { -+ status = "okay"; -+}; -+ -+&usb1 { -+ status = "okay"; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0006-arm64-dts-ls1012a-accumulated-change-for-ls1012a-boa.patch b/target/linux/layerscape/patches-5.4/302-dts-0006-arm64-dts-ls1012a-accumulated-change-for-ls1012a-boa.patch deleted file mode 100644 index 413fcaf120..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0006-arm64-dts-ls1012a-accumulated-change-for-ls1012a-boa.patch +++ /dev/null @@ -1,461 +0,0 @@ -From 8fd1ab38e922383fa87db60c48c44ab0d5e6f1c1 Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Thu, 2 May 2019 15:52:49 -0500 -Subject: [PATCH] arm64: dts: ls1012a: accumulated change for ls1012a boards - -commit 65c558ec270003e8e99cb58c940d3b913d08fa39 -Author: Zhang Ying-22455 -Date: Tue May 15 08:47:19 2018 +0800 - - arm64: dts: ls1012a: correct the register range of dcfg - - Signed-off-by: Zhang Ying-22455 - -commit 8f7b4cded4ea1fca53516ae8f5d5bc89af291f26 -Author: Bhaskar Upadhaya -Date: Mon May 7 11:52:04 2018 +0530 - - arm64: dts: ls1012a: Add LS1012A-FRWY board support - - LS1012A-FRWY is a different design from LS1012A-FRDM, - but has some common SoC features. Key feature on this - board is 2x1G SGMII PFE MAC, Micro SD, USB 3.0, DDR, - QuadSPI, Audio, UART. - - Signed-off-by: Bhaskar Upadhaya - -commit 94fc77837b3b6f4213a49b29ddc3e09e38ae5fbb -Author: Zhang Ying-22455 -Date: Mon Apr 2 16:16:47 2018 +0800 - - arm64: dts: ls1012a: add dts entry for A-010650 - - Signed-off-by: Zhang Ying-22455 - -commit d4164a6d8cffd8f09c451073754834d58b7ace19 -Author: Suresh Gupta -Date: Thu Feb 1 23:44:15 2018 +0530 - - arm64: dts: freescale: ls1012a: Add DT nodes for qspi - - Signed-off-by: Abhimanyu Saini - Signed-off-by: Suresh Gupta - -commit 4fdc98a03492b732a48426a4180f7d6a36847e71 -Author: Zhang Ying-22455 -Date: Wed Nov 1 10:31:47 2017 +0800 - - arm64: dts: ls1012a: correct the i2c clock to 1/4 platform pll - - Signed-off-by: Zhang Ying-22455 - -commit bb534725996b92aff853a4dee43738629fd4ac08 -Author: Bhaskar Upadhaya -Date: Wed Nov 29 06:31:23 2017 +0530 - - arm64: dts: freescale: ls1012a: Disable PCIe node as default - - Keep PCIe node in "disabled" status as SoC default. - Only enable it for boards with PCIe circuit designed, - such as LS1012ARDB and LS1012AQDS. - - Signed-off-by: Bhaskar Upadhaya - -commit 6b9a3244baba2c5126f349800ecaad83ba97ee47 -Author: Calvin Johnson -Date: Mon Oct 16 12:25:19 2017 +0530 - - arm64: dts: freescale: ls1012a: fix RGMII tx delay issue - - Recently logic to enable RGMII tx delay was changed by - below patch. - - https://patchwork.kernel.org/patch/9447581/ - - Based on the patch, enabling tx delay again using rgmii-txid. - - Signed-off-by: Calvin Johnson - Signed-off-by: Anjaneyulu Jagarlmudi - -commit 1e17e247088f6e2c08041559e38053b70a9d2bbe -Author: Calvin Johnson -Date: Sat Sep 16 14:20:23 2017 +0530 - - arm64: dts: freescale: ls1012a: update with pppfe support - - Update ls1012a dtsi and platform dts files with - support for ppfe. - - Signed-off-by: Calvin Johnson - Signed-off-by: Anjaneyulu Jagarlmudi - -commit e9661ed864d2a9d437057f97729410bb9af994f2 -Author: Suresh Gupta -Date: Tue May 16 17:17:21 2017 +0530 - - arm64: dts: ls1012a: add the DTS node for QSPI support - - There is a s25fs512s qspi flash on QDS, RDB and FRDM board. - - Signed-off-by: Yuan Yao - -commit ed9c51239461fe0322da2e93f50033ea0d05bc4f -Author: Chenhui Zhao -Date: Fri May 5 17:45:15 2017 +0800 - - arm64: dts: ls1012a: add ftm0 node - - Signed-off-by: Zhang Ying-22455 ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts | 58 ++++++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts | 62 ++++++++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 62 ++++++++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 68 +++++++++++++++++++++- - 4 files changed, 248 insertions(+), 2 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts -@@ -13,6 +13,11 @@ - model = "LS1012A Freedom Board"; - compatible = "fsl,ls1012a-frdm", "fsl,ls1012a"; - -+ aliases { -+ ethernet0 = &pfe_mac0; -+ ethernet1 = &pfe_mac1; -+ }; -+ - sys_mclk: clock-mclk { - compatible = "fixed-clock"; - #clock-cells = <0>; -@@ -74,6 +79,44 @@ - }; - }; - -+&pfe { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethernet@0 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0>; /* GEM_ID */ -+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */ -+ fsl,mdio-mux-val = <0x0>; -+ phy-mode = "sgmii"; -+ fsl,pfe-phy-if-flags = <0x0>; -+ -+ mdio@0 { -+ reg = <0x1>; /* enabled/disabled */ -+ }; -+ }; -+ -+ ethernet@1 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x1>; /* GEM_ID */ -+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */ -+ fsl,gemac-phy-id = <0x1>; /* PHY_ID */ -+ fsl,mdio-mux-val = <0x0>; -+ phy-mode = "sgmii"; -+ fsl,pfe-phy-if-flags = <0x0>; -+ -+ mdio@0 { -+ reg = <0x0>; /* enabled/disabled */ -+ }; -+ }; -+}; -+ - &sai2 { - status = "okay"; - }; -@@ -81,3 +124,18 @@ - &sata { - status = "okay"; - }; -+ -+&qspi { -+ status = "okay"; -+ qflash0: s25fs512s@0 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <20000000>; -+ m25p,fast-read; -+ reg = <0>; -+ spi-rx-bus-width = <2>; -+ spi-tx-bus-width = <2>; -+ }; -+ -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts -@@ -13,6 +13,11 @@ - model = "LS1012A QDS Board"; - compatible = "fsl,ls1012a-qds", "fsl,ls1012a"; - -+ aliases { -+ ethernet0 = &pfe_mac0; -+ ethernet1 = &pfe_mac1; -+ }; -+ - sys_mclk: clock-mclk { - compatible = "fixed-clock"; - #clock-cells = <0>; -@@ -57,6 +62,10 @@ - }; - }; - -+&pcie { -+ status = "okay"; -+}; -+ - &dspi { - bus-num = <0>; - status = "okay"; -@@ -128,6 +137,44 @@ - }; - }; - -+&pfe { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethernet@0 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0>; /* GEM_ID */ -+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -+ fsl,gemac-phy-id = <0x1>; /* PHY_ID */ -+ fsl,mdio-mux-val = <0x2>; -+ phy-mode = "sgmii-2500"; -+ fsl,pfe-phy-if-flags = <0x0>; -+ -+ mdio@0 { -+ reg = <0x1>; /* enabled/disabled */ -+ }; -+ }; -+ -+ ethernet@1 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x1>; /* GEM_ID */ -+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */ -+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */ -+ fsl,mdio-mux-val = <0x3>; -+ phy-mode = "sgmii-2500"; -+ fsl,pfe-phy-if-flags = <0x0>; -+ -+ mdio@0 { -+ reg = <0x0>; /* enabled/disabled */ -+ }; -+ }; -+}; -+ - &sai2 { - status = "okay"; - }; -@@ -135,3 +182,18 @@ - &sata { - status = "okay"; - }; -+ -+&qspi { -+ status = "okay"; -+ qflash0: s25fs512s@0 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <20000000>; -+ m25p,fast-read; -+ reg = <0>; -+ spi-rx-bus-width = <2>; -+ spi-tx-bus-width = <2>; -+ }; -+ -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -@@ -12,6 +12,15 @@ - / { - model = "LS1012A RDB Board"; - compatible = "fsl,ls1012a-rdb", "fsl,ls1012a"; -+ -+ aliases { -+ ethernet0 = &pfe_mac0; -+ ethernet1 = &pfe_mac1; -+ }; -+}; -+ -+&pcie { -+ status = "okay"; - }; - - &duart0 { -@@ -38,3 +47,56 @@ - &sata { - status = "okay"; - }; -+ -+&pfe { -+ status = "okay"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ethernet@0 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0>; /* GEM_ID */ -+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */ -+ fsl,mdio-mux-val = <0x0>; -+ phy-mode = "sgmii"; -+ fsl,pfe-phy-if-flags = <0x0>; -+ -+ mdio@0 { -+ reg = <0x1>; /* enabled/disabled */ -+ }; -+ }; -+ -+ ethernet@1 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x1>; /* GEM_ID */ -+ fsl,gemac-bus-id = < 0x1 >; /* BUS_ID */ -+ fsl,gemac-phy-id = < 0x1 >; /* PHY_ID */ -+ fsl,mdio-mux-val = <0x0>; -+ phy-mode = "rgmii-txid"; -+ fsl,pfe-phy-if-flags = <0x0>; -+ -+ mdio@0 { -+ reg = <0x0>; /* enabled/disabled */ -+ }; -+ }; -+}; -+ -+&qspi { -+ status = "okay"; -+ qflash0: s25fs512s@0 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <20000000>; -+ m25p,fast-read; -+ reg = <0>; -+ spi-rx-bus-width = <2>; -+ spi-tx-bus-width = <2>; -+ }; -+ -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -261,7 +261,7 @@ - dcfg: dcfg@1ee0000 { - compatible = "fsl,ls1012a-dcfg", - "syscon"; -- reg = <0x0 0x1ee0000 0x0 0x10000>; -+ reg = <0x0 0x1ee0000 0x0 0x1000>; - big-endian; - }; - -@@ -318,13 +318,23 @@ - #thermal-sensor-cells = <1>; - }; - -+ ftm0: ftm0@29d0000 { -+ compatible = "fsl,ftm-alarm"; -+ reg = <0x0 0x29d0000 0x0 0x10000>, -+ <0x0 0x1ee2140 0x0 0x4>; -+ reg-names = "ftm", "FlexTimer1"; -+ interrupts = <0 86 0x4>; -+ big-endian; -+ }; -+ - i2c0: i2c@2180000 { -- compatible = "fsl,vf610-i2c"; -+ compatible = "fsl,vf610-i2c", "fsl,ls1012a-vf610-i2c"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0 0x2180000 0x0 0x10000>; - interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clockgen 4 3>; -+ scl-gpios = <&gpio0 13 0>; - status = "disabled"; - }; - -@@ -396,6 +406,20 @@ - big-endian; - }; - -+ qspi: spi@1550000 { -+ compatible = "fsl,ls1012a-qspi", "fsl,ls1021a-qspi"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0 0x1550000 0x0 0x10000>, -+ <0x0 0x40000000 0x0 0x10000000>; -+ reg-names = "QuadSPI", "QuadSPI-memory"; -+ interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>; -+ clock-names = "qspi_en", "qspi"; -+ clocks = <&clockgen 4 0>, <&clockgen 4 0>; -+ big-endian; -+ status = "disabled"; -+ }; -+ - sai1: sai@2b50000 { - #sound-dai-cells = <0>; - compatible = "fsl,vf610-sai"; -@@ -500,6 +524,46 @@ - <0000 0 0 4 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - }; -+ -+ rcpm: rcpm@1ee2000 { -+ compatible = "fsl,ls1012a-rcpm", "fsl,qoriq-rcpm-2.1"; -+ reg = <0x0 0x1ee2000 0x0 0x1000>; -+ fsl,#rcpm-wakeup-cells = <1>; -+ }; -+ }; -+ -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ -+ pfe_reserved: packetbuffer@83400000 { -+ reg = <0 0x83400000 0 0xc00000>; -+ }; -+ }; -+ -+ pfe: pfe@04000000 { -+ compatible = "fsl,pfe"; -+ reg = <0x0 0x04000000 0x0 0xc00000>, /* AXI 16M */ -+ <0x0 0x83400000 0x0 0xc00000>; /* PFE DDR 12M */ -+ reg-names = "pfe", "pfe-ddr"; -+ fsl,pfe-num-interfaces = <0x2>; -+ interrupts = <0 172 0x4>, /* HIF interrupt */ -+ <0 173 0x4>, /*HIF_NOCPY interrupt */ -+ <0 174 0x4>; /* WoL interrupt */ -+ interrupt-names = "pfe_hif", "pfe_hif_nocpy", "pfe_wol"; -+ memory-region = <&pfe_reserved>; -+ fsl,pfe-scfg = <&scfg 0>; -+ fsl,rcpm-wakeup = <&rcpm 0xf0000020>; -+ clocks = <&clockgen 4 0>; -+ clock-names = "pfe"; -+ -+ status = "okay"; -+ pfe_mac0: ethernet@0 { -+ }; -+ -+ pfe_mac1: ethernet@1 { -+ }; - }; - - firmware { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0007-arm64-dts-ls1043a-accumulated-change-for-ls1043a-boa.patch b/target/linux/layerscape/patches-5.4/302-dts-0007-arm64-dts-ls1043a-accumulated-change-for-ls1043a-boa.patch deleted file mode 100644 index 91f789af13..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0007-arm64-dts-ls1043a-accumulated-change-for-ls1043a-boa.patch +++ /dev/null @@ -1,574 +0,0 @@ -From 794b9e55c77bf0ef34dfdb3b151a845c004b3ce3 Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Thu, 2 May 2019 16:01:01 -0500 -Subject: [PATCH] arm64: dts: ls1043a: accumulated change for ls1043a boards - -commit 118e2f48ee8da3f5547c24888bd6fdb78f03b7ce -Author: Peng Ma -Date: Wed Jul 25 08:53:07 2018 +0000 - - dts: fsl-ls1021a, fsl-ls1043a, fsl-ls1046a: add multi block node -support - - add block-offset to support different virtual block offset for qdma - base on soc; - the interrupt named "qdma-queueN(N:0,1,2,3)" correspond to a virtual - block,N based on block number of qdma; - - Signed-off-by: Peng Ma - -Author: Zhang Ying-22455 -Date: Mon Apr 2 16:22:40 2018 +0800 - - arm64: dts: ls1043a: add dts entry for A-010650 - - Signed-off-by: Zhang Ying-22455 - -commit a47e4bd0b5d076feb6d81601c16d5b79e53a92c8 -Author: Rajesh Bhagat -Date: Wed Jan 27 11:37:25 2016 +0530 - - arm64: dts: ls1043a: Add configure-gfladj property to USB3 node - - Add "configure-gfladj" boolean property to USB3 node. This property - is used to determine whether frame length adjustent is required - or not - - Signed-off-by: Rajesh Bhagat - Signed-off-by: Ran Wang - -commit 38566bbd5ca6747b30d2f0c251bbcfe0723df8c6 -Author: Changming Huang -Date: Wed Apr 19 12:49:50 2017 +0800 - - arm/arm64: dts: Add property snps incr burst type adjustment for -INCR burst type for dwc3 - - Signed-off-by: yinbo.zhu - Signed-off-by: Ran Wang - -commit 8632d84e0fe187aa023a24f0dad0040c53e12450 -Author: Abhimanyu Saini -Date: Thu Jan 25 11:31:13 2018 +0530 - - arm64: dts: freescale: ls1043a: Modify DT nodes for qspi - - Signed-off-by: Abhimanyu Saini - -commit b1dc1ebed79e9aaab75fd06837d794ec2f1b624d -Author: Ran Wang -Date: Fri Jan 5 15:14:48 2018 +0800 - - arm64: dts: ls1043a: Enable usb3-lpm-capable for usb3 node - - Enable USB3 HW LPM feature for ls1043a and active patch for - snps erratum A-010131. It will disable U1/U2 temperary when - initiate U3 request. - - Signed-off-by: Ran Wang - -commit 9b17a5fcf8da5656ff99ebef3d63ba040e9f676d -Author: Zhang Ying-22455 -Date: Tue Jun 13 13:14:26 2017 +0800 - - arm64: dts: correct the register range of dcfg - - Signed-off-by: Zhang Ying-22455 - -commit f60e39fd51ad702e3a2613faaca40871a4763735 -Author: Zhang Ying-22455 -Date: Tue Aug 22 18:04:02 2017 +0800 - - arm64: dts: ls1043a: add pcf85263 rtc nodes - - Signed-off-by: Zhang Ying-22455 - -commit 67c82e3c7b376139d7cee624589bedbc311f8868 -Author: jiaheng.fan -Date: Thu May 11 17:36:33 2017 +0800 - - arm64: dts: ls1021/ls1043/ls1046: add qdma nodes - Signed-off-by: jiaheng.fan - -commit c6d9c2498ee83669f9853100301edff9a5905caf -Author: Wang Dongsheng -Date: Fri Apr 21 13:26:07 2017 +0800 - - arm64: dts: ls1043a: add ftm0 nodes - - Add rcpm and ftm0 nodes. The Power Management related features - need these nodes. - - Signed-off-by: Zhang Ying-22455 - -commit 3bcdc4de0a1c9e6f4a4ddc916e8efe8044d8bbfd -Author: Po Liu -Date: Fri Sep 30 17:11:36 2016 +0800 - - arm64: dts: ls1043/ls2080: add pcie aer/pme interrupt-name property - - Some platforms(NXP Layerscape for example) aer/pme interrupts was -not - MSI/MSI-X/INTx but using interrupt line independently. This patch - add "aer", "pme" interrupt-names for aer/pme interrupt. - - With the interrupt-names "aer", "pme" code could probe aer/pme -interrupt - line for pcie root port, replace the aer/pme interrupt service irqs. - - This is intend to fixup the Layerscape platforms which aer/pmes -interrupts - was not MSI/MSI-X/INTx, but using interrupt line independently. - - Since the interrupt-names "intr" never been used. Remove it. - - Signed-off-by: Po Liu - Signed-off-by: Hou Zhiqiang - -commit 4d20ecf029f1255520b30c103e1724c618b981c7 -Author: Zhao Qiang -Date: Sun Jun 12 15:51:44 2016 +0800 - - arm64: dts: ls1043ardb: add ds26522 node - - add ds26522 node to fsl-ls1043a-rdb.dts - - Signed-off-by: Zhao Qiang - -commit ca470562646ab058814fc4a1195016fb3266cdf5 -Author: Zhao Qiang -Date: Sun Jun 12 15:44:11 2016 +0800 - - arm64: dts: ls1043ardb: add qe node - - Signed-off-by: Zhao Qiang ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts | 162 ++++++++++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts | 36 +++++ - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 108 +++++++++++++-- - 3 files changed, 295 insertions(+), 11 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts -@@ -24,6 +24,22 @@ - serial1 = &duart1; - serial2 = &duart2; - serial3 = &duart3; -+ sgmii_riser_s1_p1 = &sgmii_phy_s1_p1; -+ sgmii_riser_s2_p1 = &sgmii_phy_s2_p1; -+ sgmii_riser_s3_p1 = &sgmii_phy_s3_p1; -+ sgmii_riser_s4_p1 = &sgmii_phy_s4_p1; -+ qsgmii_s1_p1 = &qsgmii_phy_s1_p1; -+ qsgmii_s1_p2 = &qsgmii_phy_s1_p2; -+ qsgmii_s1_p3 = &qsgmii_phy_s1_p3; -+ qsgmii_s1_p4 = &qsgmii_phy_s1_p4; -+ qsgmii_s2_p1 = &qsgmii_phy_s2_p1; -+ qsgmii_s2_p2 = &qsgmii_phy_s2_p2; -+ qsgmii_s2_p3 = &qsgmii_phy_s2_p3; -+ qsgmii_s2_p4 = &qsgmii_phy_s2_p4; -+ emi1_slot1 = &ls1043mdio_s1; -+ emi1_slot2 = &ls1043mdio_s2; -+ emi1_slot3 = &ls1043mdio_s3; -+ emi1_slot4 = &ls1043mdio_s4; - }; - - chosen { -@@ -64,6 +80,8 @@ - fpga: board-control@2,0 { - compatible = "fsl,ls1043aqds-fpga", "fsl,fpga-qixis"; - reg = <0x2 0x0 0x0000100>; -+ #address-cells = <1>; -+ #size-cells = <1>; - }; - }; - -@@ -149,3 +167,147 @@ - }; - - #include "fsl-ls1043-post.dtsi" -+ -+&fman0 { -+ ethernet@e0000 { -+ phy-handle = <&qsgmii_phy_s2_p1>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ ethernet@e2000 { -+ phy-handle = <&qsgmii_phy_s2_p2>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ ethernet@e4000 { -+ phy-handle = <&rgmii_phy1>; -+ phy-connection-type = "rgmii"; -+ }; -+ -+ ethernet@e6000 { -+ phy-handle = <&rgmii_phy2>; -+ phy-connection-type = "rgmii"; -+ }; -+ -+ ethernet@e8000 { -+ phy-handle = <&qsgmii_phy_s2_p3>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ ethernet@ea000 { -+ phy-handle = <&qsgmii_phy_s2_p4>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ ethernet@f0000 { /* DTSEC9/10GEC1 */ -+ fixed-link = <1 1 10000 0 0>; -+ phy-connection-type = "xgmii"; -+ }; -+}; -+ -+&fpga { -+ mdio-mux-emi1 { -+ compatible = "mdio-mux-mmioreg", "mdio-mux"; -+ mdio-parent-bus = <&mdio0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x54 1>; /* BRDCFG4 */ -+ mux-mask = <0xe0>; /* EMI1 */ -+ -+ /* On-board RGMII1 PHY */ -+ ls1043mdio0: mdio@0 { -+ reg = <0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rgmii_phy1: ethernet-phy@1 { /* MAC3 */ -+ reg = <0x1>; -+ }; -+ }; -+ -+ /* On-board RGMII2 PHY */ -+ ls1043mdio1: mdio@1 { -+ reg = <0x20>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rgmii_phy2: ethernet-phy@2 { /* MAC4 */ -+ reg = <0x2>; -+ }; -+ }; -+ -+ /* Slot 1 */ -+ ls1043mdio_s1: mdio@2 { -+ reg = <0x40>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ qsgmii_phy_s1_p1: ethernet-phy@4 { -+ reg = <0x4>; -+ }; -+ qsgmii_phy_s1_p2: ethernet-phy@5 { -+ reg = <0x5>; -+ }; -+ qsgmii_phy_s1_p3: ethernet-phy@6 { -+ reg = <0x6>; -+ }; -+ qsgmii_phy_s1_p4: ethernet-phy@7 { -+ reg = <0x7>; -+ }; -+ -+ sgmii_phy_s1_p1: ethernet-phy@1c { -+ reg = <0x1c>; -+ }; -+ }; -+ -+ /* Slot 2 */ -+ ls1043mdio_s2: mdio@3 { -+ reg = <0x60>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ qsgmii_phy_s2_p1: ethernet-phy@8 { -+ reg = <0x8>; -+ }; -+ qsgmii_phy_s2_p2: ethernet-phy@9 { -+ reg = <0x9>; -+ }; -+ qsgmii_phy_s2_p3: ethernet-phy@a { -+ reg = <0xa>; -+ }; -+ qsgmii_phy_s2_p4: ethernet-phy@b { -+ reg = <0xb>; -+ }; -+ -+ sgmii_phy_s2_p1: ethernet-phy@1c { -+ reg = <0x1c>; -+ }; -+ }; -+ -+ /* Slot 3 */ -+ ls1043mdio_s3: mdio@4 { -+ reg = <0x80>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ sgmii_phy_s3_p1: ethernet-phy@1c { -+ reg = <0x1c>; -+ }; -+ }; -+ -+ /* Slot 4 */ -+ ls1043mdio_s4: mdio@5 { -+ reg = <0xa0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ sgmii_phy_s4_p1: ethernet-phy@1c { -+ reg = <0x1c>; -+ }; -+ }; -+ }; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts -@@ -49,6 +49,10 @@ - compatible = "pericom,pt7c4338"; - reg = <0x68>; - }; -+ rtc@51 { -+ compatible = "nxp,pcf85263"; -+ reg = <0x51>; -+ }; - }; - - &ifc { -@@ -94,6 +98,38 @@ - reg = <0>; - spi-max-frequency = <1000000>; /* input clock */ - }; -+ -+ slic@2 { -+ compatible = "maxim,ds26522"; -+ reg = <2>; -+ spi-max-frequency = <2000000>; -+ fsl,spi-cs-sck-delay = <100>; -+ fsl,spi-sck-cs-delay = <50>; -+ }; -+ -+ slic@3 { -+ compatible = "maxim,ds26522"; -+ reg = <3>; -+ spi-max-frequency = <2000000>; -+ fsl,spi-cs-sck-delay = <100>; -+ fsl,spi-sck-cs-delay = <50>; -+ }; -+}; -+ -+&uqe { -+ ucc_hdlc: ucc@2000 { -+ compatible = "fsl,ucc-hdlc"; -+ rx-clock-name = "clk8"; -+ tx-clock-name = "clk9"; -+ fsl,rx-sync-clock = "rsync_pin"; -+ fsl,tx-sync-clock = "tsync_pin"; -+ fsl,tx-timeslot-mask = <0xfffffffe>; -+ fsl,rx-timeslot-mask = <0xfffffffe>; -+ fsl,tdm-framer-type = "e1"; -+ fsl,tdm-id = <0>; -+ fsl,siram-entry-id = <0>; -+ fsl,tdm-interface; -+ }; - }; - - &duart0 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -278,7 +278,7 @@ - - dcfg: dcfg@1ee0000 { - compatible = "fsl,ls1043a-dcfg", "syscon"; -- reg = <0x0 0x1ee0000 0x0 0x10000>; -+ reg = <0x0 0x1ee0000 0x0 0x1000>; - big-endian; - }; - -@@ -412,7 +412,7 @@ - }; - - i2c0: i2c@2180000 { -- compatible = "fsl,vf610-i2c"; -+ compatible = "fsl,vf610-i2c", "fsl,ls1043a-vf610-i2c"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0 0x2180000 0x0 0x10000>; -@@ -422,6 +422,7 @@ - dmas = <&edma0 1 39>, - <&edma0 1 38>; - dma-names = "tx", "rx"; -+ scl-gpios = <&gpio4 12 0>; - status = "disabled"; - }; - -@@ -526,6 +527,72 @@ - #interrupt-cells = <2>; - }; - -+ uqe: uqe@2400000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "qe"; -+ compatible = "fsl,qe", "simple-bus"; -+ ranges = <0x0 0x0 0x2400000 0x40000>; -+ reg = <0x0 0x2400000 0x0 0x480>; -+ brg-frequency = <100000000>; -+ bus-frequency = <200000000>; -+ -+ fsl,qe-num-riscs = <1>; -+ fsl,qe-num-snums = <28>; -+ -+ qeic: qeic@80 { -+ compatible = "fsl,qe-ic"; -+ reg = <0x80 0x80>; -+ #address-cells = <0>; -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ interrupts = <0 77 0x04 0 77 0x04>; -+ }; -+ -+ si1: si@700 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,ls1043-qe-si", -+ "fsl,t1040-qe-si"; -+ reg = <0x700 0x80>; -+ }; -+ -+ siram1: siram@1000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,ls1043-qe-siram", -+ "fsl,t1040-qe-siram"; -+ reg = <0x1000 0x800>; -+ }; -+ -+ ucc@2000 { -+ cell-index = <1>; -+ reg = <0x2000 0x200>; -+ interrupts = <32>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ ucc@2200 { -+ cell-index = <3>; -+ reg = <0x2200 0x200>; -+ interrupts = <34>; -+ interrupt-parent = <&qeic>; -+ }; -+ -+ muram@10000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,qe-muram", "fsl,cpm-muram"; -+ ranges = <0x0 0x10000 0x6000>; -+ -+ data-only@0 { -+ compatible = "fsl,qe-muram-data", -+ "fsl,cpm-muram-data"; -+ reg = <0x0 0x6000>; -+ }; -+ }; -+ }; -+ - lpuart0: serial@2950000 { - compatible = "fsl,ls1021a-lpuart"; - reg = <0x0 0x2950000 0x0 0x1000>; -@@ -580,6 +647,16 @@ - status = "disabled"; - }; - -+ ftm0: ftm0@29d0000 { -+ compatible = "fsl,ftm-alarm"; -+ reg = <0x0 0x29d0000 0x0 0x10000>, -+ <0x0 0x1ee2140 0x0 0x4>; -+ reg-names = "ftm", "FlexTimer1"; -+ interrupts = <0 86 0x4>; -+ big-endian; -+ status = "okay"; -+ }; -+ - wdog0: wdog@2ad0000 { - compatible = "fsl,ls1043a-wdt", "fsl,imx21-wdt"; - reg = <0x0 0x2ad0000 0x0 0x10000>; -@@ -612,7 +689,10 @@ - dr_mode = "host"; - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ configure-gfladj; - }; - - usb1: usb3@3000000 { -@@ -622,7 +702,10 @@ - dr_mode = "host"; - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ configure-gfladj; - }; - - usb2: usb3@3100000 { -@@ -632,7 +715,10 @@ - dr_mode = "host"; - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ configure-gfladj; - }; - - sata: sata@3200000 { -@@ -671,9 +757,9 @@ - reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ - 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ - reg-names = "regs", "config"; -- interrupts = <0 118 0x4>, /* controller interrupt */ -- <0 117 0x4>; /* PME interrupt */ -- interrupt-names = "intr", "pme"; -+ interrupts = <0 117 0x4>, /* PME interrupt */ -+ <0 118 0x4>; /* aer interrupt */ -+ interrupt-names = "pme", "aer"; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; -@@ -697,9 +783,9 @@ - reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ - 0x48 0x00000000 0x0 0x00002000>; /* configuration space */ - reg-names = "regs", "config"; -- interrupts = <0 128 0x4>, -- <0 127 0x4>; -- interrupt-names = "intr", "pme"; -+ interrupts = <0 127 0x4>, -+ <0 128 0x4>; -+ interrupt-names = "pme", "aer"; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; -@@ -723,9 +809,9 @@ - reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ - 0x50 0x00000000 0x0 0x00002000>; /* configuration space */ - reg-names = "regs", "config"; -- interrupts = <0 162 0x4>, -- <0 161 0x4>; -- interrupt-names = "intr", "pme"; -+ interrupts = <0 161 0x4>, -+ <0 162 0x4>; -+ interrupt-names = "pme", "aer"; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0008-arm64-dts-ls1046a-accumulated-change-to-ls1046a-boar.patch b/target/linux/layerscape/patches-5.4/302-dts-0008-arm64-dts-ls1046a-accumulated-change-to-ls1046a-boar.patch deleted file mode 100644 index 91e930768d..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0008-arm64-dts-ls1046a-accumulated-change-to-ls1046a-boar.patch +++ /dev/null @@ -1,366 +0,0 @@ -From 229d32330c7d941b8e04501ad75bc527f6cf1b1c Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Thu, 2 May 2019 16:06:42 -0500 -Subject: [PATCH] arm64: dts: ls1046a: accumulated change to ls1046a boards - -commit 118e2f48ee8da3f5547c24888bd6fdb78f03b7ce -Author: Peng Ma -Date: Wed Jul 25 08:53:07 2018 +0000 - - dts: fsl-ls1021a, fsl-ls1043a, fsl-ls1046a: add multi block node -support - - add block-offset to support different virtual block offset for qdma - base on soc; - the interrupt named "qdma-queueN(N:0,1,2,3)" correspond to a virtual - block,N based on block number of qdma; - - Signed-off-by: Peng Ma - -commit 46123df3a174f0d76c8b954a0386e64841453836 -Author: Florinel Iordache -Date: Thu Aug 9 12:29:18 2018 +0300 - - arm64: dts: updates for Unified Backplane driver - - Signed-off-by: Florinel Iordache - -commit c08136017e8b18eb58b153129487c5dc760afd20 -Author: Florinel Iordache -Date: Thu Aug 9 12:23:42 2018 +0300 - - arm64: dts: ls1046: add support for 10GBase-KR - - Signed-off-by: Florinel Iordache - -commit 8473f478783f6f601e1c6d7e6afba49a13f3a6a3 -Author: Zhang Ying-22455 -Date: Mon Apr 2 16:24:33 2018 +0800 - - arm64: dts: ls1046a: add dts entry for A-010650 - - Signed-off-by: Zhang Ying-22455 - -commit 3159fe9263fb145601ccb07fcb9336a68fba4e08 -Author: Bao Xiaowei -Date: Fri Oct 13 11:04:39 2017 +0800 - - arm64: dts: ls1046a: add the property of IB and OB - - Add the property of inbound and outbound windows number for ep - driver. - - Signed-off-by: Bao Xiaowei - - Acked-by: Minghuan Lian - Signed-off-by: Hou Zhiqiang - -commit c8fed58f3c9a0219fda0467791f61abd86eb97f3 -Author: Abhimanyu Saini -Date: Wed Jan 24 22:56:48 2018 +0530 - - arm64: dts: freescale: ls1046a: Modify DT nodes for qspi - - Signed-off-by: Abhimanyu Saini - -commit 96558859ea3a4af44c0b25441f7574ae6222509a -Author: Ran Wang -Date: Fri Jan 5 15:17:23 2018 +0800 - - arm64: dts: ls1046a: Enable usb3-lpm-capable for usb3 node - - Enable USB3 HW LPM feature for ls1046a and active patch for - snps erratum A-010131. It will disable U1/U2 temperary when - initiate U3 request. - - Signed-off-by: Ran Wang - -commit 9b17a5fcf8da5656ff99ebef3d63ba040e9f676d -Author: Zhang Ying-22455 -Date: Tue Jun 13 13:14:26 2017 +0800 - - arm64: dts: correct the register range of dcfg - - Signed-off-by: Zhang Ying-22455 - -commit 67c82e3c7b376139d7cee624589bedbc311f8868 -Author: jiaheng.fan -Date: Thu May 11 17:36:33 2017 +0800 - - arm64: dts: ls1021/ls1043/ls1046: add qdma nodes - - Signed-off-by: jiaheng.fan - -commit 4a6cef0c83748ee4f6641489fc324bd64095485d -Author: Chenhui Zhao -Date: Fri May 5 17:53:27 2017 +0800 - - arm64: dts: ls1046a: add ftm0 node - - Signed-off-by: Zhang Ying-22455 ---- - arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts | 148 ++++++++++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 1 + - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 28 +++- - 3 files changed, 174 insertions(+), 3 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts -@@ -25,6 +25,20 @@ - serial1 = &duart1; - serial2 = &duart2; - serial3 = &duart3; -+ -+ emi1_slot1 = &ls1046mdio_s1; -+ emi1_slot2 = &ls1046mdio_s2; -+ emi1_slot4 = &ls1046mdio_s4; -+ -+ sgmii_s1_p1 = &sgmii_phy_s1_p1; -+ sgmii_s1_p2 = &sgmii_phy_s1_p2; -+ sgmii_s1_p3 = &sgmii_phy_s1_p3; -+ sgmii_s1_p4 = &sgmii_phy_s1_p4; -+ sgmii_s4_p1 = &sgmii_phy_s4_p1; -+ qsgmii_s2_p1 = &qsgmii_phy_s2_p1; -+ qsgmii_s2_p2 = &qsgmii_phy_s2_p2; -+ qsgmii_s2_p3 = &qsgmii_phy_s2_p3; -+ qsgmii_s2_p4 = &qsgmii_phy_s2_p4; - }; - - chosen { -@@ -177,3 +191,137 @@ - }; - - #include "fsl-ls1046-post.dtsi" -+ -+&fman0 { -+ ethernet@e0000 { -+ phy-handle = <&qsgmii_phy_s2_p1>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ ethernet@e2000 { -+ phy-handle = <&sgmii_phy_s4_p1>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ ethernet@e4000 { -+ phy-handle = <&rgmii_phy1>; -+ phy-connection-type = "rgmii"; -+ }; -+ -+ ethernet@e6000 { -+ phy-handle = <&rgmii_phy2>; -+ phy-connection-type = "rgmii"; -+ }; -+ -+ ethernet@e8000 { -+ phy-handle = <&sgmii_phy_s1_p3>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ ethernet@ea000 { -+ phy-handle = <&sgmii_phy_s1_p4>; -+ phy-connection-type = "sgmii"; -+ }; -+ -+ ethernet@f0000 { /* DTSEC9/10GEC1 */ -+ phy-handle = <&sgmii_phy_s1_p1>; -+ phy-connection-type = "xgmii"; -+ }; -+ -+ ethernet@f2000 { /* DTSEC10/10GEC2 */ -+ phy-handle = <&sgmii_phy_s1_p2>; -+ phy-connection-type = "xgmii"; -+ }; -+}; -+ -+&fpga { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ mdio-mux-emi1 { -+ compatible = "mdio-mux-mmioreg", "mdio-mux"; -+ mdio-parent-bus = <&mdio0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x54 1>; /* BRDCFG4 */ -+ mux-mask = <0xe0>; /* EMI1 */ -+ -+ /* On-board RGMII1 PHY */ -+ ls1046mdio0: mdio@0 { -+ reg = <0>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rgmii_phy1: ethernet-phy@1 { /* MAC3 */ -+ reg = <0x1>; -+ }; -+ }; -+ -+ /* On-board RGMII2 PHY */ -+ ls1046mdio1: mdio@1 { -+ reg = <0x20>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rgmii_phy2: ethernet-phy@2 { /* MAC4 */ -+ reg = <0x2>; -+ }; -+ }; -+ -+ /* Slot 1 */ -+ ls1046mdio_s1: mdio@2 { -+ reg = <0x40>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ sgmii_phy_s1_p1: ethernet-phy@1c { -+ reg = <0x1c>; -+ }; -+ -+ sgmii_phy_s1_p2: ethernet-phy@1d { -+ reg = <0x1d>; -+ }; -+ -+ sgmii_phy_s1_p3: ethernet-phy@1e { -+ reg = <0x1e>; -+ }; -+ -+ sgmii_phy_s1_p4: ethernet-phy@1f { -+ reg = <0x1f>; -+ }; -+ }; -+ -+ /* Slot 2 */ -+ ls1046mdio_s2: mdio@3 { -+ reg = <0x60>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ qsgmii_phy_s2_p1: ethernet-phy@8 { -+ reg = <0x8>; -+ }; -+ qsgmii_phy_s2_p2: ethernet-phy@9 { -+ reg = <0x9>; -+ }; -+ qsgmii_phy_s2_p3: ethernet-phy@a { -+ reg = <0xa>; -+ }; -+ qsgmii_phy_s2_p4: ethernet-phy@b { -+ reg = <0xb>; -+ }; -+ }; -+ -+ /* Slot 4 */ -+ ls1046mdio_s4: mdio@5 { -+ reg = <0x80>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ -+ sgmii_phy_s4_p1: ethernet-phy@1c { -+ reg = <0x1c>; -+ }; -+ }; -+ }; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts -@@ -95,6 +95,7 @@ - - &qspi { - status = "okay"; -+ fsl,qspi-has-second-chip; - - qflash0: flash@0 { - compatible = "spansion,m25p80"; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -377,7 +377,7 @@ - }; - - i2c0: i2c@2180000 { -- compatible = "fsl,vf610-i2c"; -+ compatible = "fsl,vf610-i2c", "fsl,ls1046a-vf610-i2c"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0 0x2180000 0x0 0x10000>; -@@ -386,6 +386,7 @@ - dmas = <&edma0 1 39>, - <&edma0 1 38>; - dma-names = "tx", "rx"; -+ scl-gpios = <&gpio3 12 0>; - status = "disabled"; - }; - -@@ -410,12 +411,13 @@ - }; - - i2c3: i2c@21b0000 { -- compatible = "fsl,vf610-i2c"; -+ compatible = "fsl,vf610-i2c", "fsl,ls1046a-vf610-i2c"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0 0x21b0000 0x0 0x10000>; - interrupts = ; - clocks = <&clockgen 4 1>; -+ scl-gpios = <&gpio3 12 0>; - status = "disabled"; - }; - -@@ -545,6 +547,15 @@ - status = "disabled"; - }; - -+ ftm0: ftm0@29d0000 { -+ compatible = "fsl,ftm-alarm"; -+ reg = <0x0 0x29d0000 0x0 0x10000>, -+ <0x0 0x1ee2140 0x0 0x4>; -+ reg-names = "ftm", "FlexTimer1"; -+ interrupts = ; -+ big-endian; -+ }; -+ - wdog0: watchdog@2ad0000 { - compatible = "fsl,imx21-wdt"; - reg = <0x0 0x2ad0000 0x0 0x10000>; -@@ -577,6 +588,8 @@ - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; - }; - - usb1: usb@3000000 { -@@ -587,6 +600,8 @@ - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; - }; - - usb2: usb@3100000 { -@@ -597,6 +612,8 @@ - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; - }; - - sata: sata@3200000 { -@@ -638,6 +655,11 @@ - ; - }; - -+ serdes1: serdes@1ea0000 { -+ reg = <0x0 0x1ea0000 0 0x00002000>; -+ compatible = "fsl,serdes-10g"; -+ }; -+ - pcie@3400000 { - compatible = "fsl,ls1046a-pcie"; - reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ diff --git a/target/linux/layerscape/patches-5.4/302-dts-0009-arm64-dts-ls1088a-accumulated-change-to-ls1088a-boar.patch b/target/linux/layerscape/patches-5.4/302-dts-0009-arm64-dts-ls1088a-accumulated-change-to-ls1088a-boar.patch deleted file mode 100644 index 48fbfa746a..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0009-arm64-dts-ls1088a-accumulated-change-to-ls1088a-boar.patch +++ /dev/null @@ -1,540 +0,0 @@ -From 2790ba4aa3e487ac29d6027eb226ed986f0e2769 Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Thu, 2 May 2019 16:10:03 -0500 -Subject: [PATCH] arm64: dts: ls1088a: accumulated change to ls1088a boards - -commit f967940f2fb73bc7ec676dbad9f32fbf4e7fea2b -Author: Pengbo Mu -Date: Fri Jul 13 16:19:36 2018 +0800 - - arm64: dts: ls1088a: add snps incr burst type adjustment in usb0 & -usb1 - - This property could fix the defect that external usb device always - prints this error log --- 'reset SuperSpeed USB device number n -using - xhci_hcd' when system power on. - - Signed-off-by: Pengbo Mu - -commit 46123df3a174f0d76c8b954a0386e64841453836 -Author: Florinel Iordache -Date: Thu Aug 9 12:29:18 2018 +0300 - - arm64: dts: updates for Unified Backplane driver - - Signed-off-by: Florinel Iordache - -commit 3b214bd42d47ebe7b6af925a3ffcf09aaaaabfb9 -Author: Nipun Gupta -Date: Sat Apr 28 00:20:48 2018 +0530 - - arm64: dts: ls1088: add dma-cohernet property in fsl-mc node - - Signed-off-by: Nipun Gupta - -commit 240b04a98171f6774d1c3c498f8cb21f4411ac5f -Author: Laurentiu Tudor -Date: Thu Apr 26 12:26:54 2018 +0300 - - arm64: dts: ls1088a: move fsl-mc node as a child of soc - - Move the fsl-mc hardware manager node in the soc node because all -the - soc settings (such as 'dma-ranges') also apply to the fsl-mc and -need - to be propagated to it. - - Signed-off-by: Laurentiu Tudor - -commit 3f2f50950f763d1335181ce374a11ed118abf0fa -Author: Nipun Gupta -Date: Wed Apr 25 09:43:47 2018 +0530 - - arm64: dts: ls1088: add dma ranges property - - Signed-off-by: Nipun Gupta - -commit 6afd0157e8fa2510790537855c86f8a7c1431abe -Author: Zhang Ying-22455 -Date: Mon Apr 2 16:25:38 2018 +0800 - - arm64: dts: ls1088a: add dts entry for A-010650 - - Signed-off-by: Zhang Ying-22455 - -commit 0f8432c30c44771f9180aa7bf7580ad1d7e7c9d3 -Author: Nipun Gupta -Date: Mon Feb 26 10:40:37 2018 +0530 - - arm64: dts: ls1088a: add dma coherent property in smmu node - - Signed-off-by: Nipun Gupta - -commit 6417c66b823ab380cf73ee252a998d98b28f0180 -Author: Suresh Gupta -Date: Fri Feb 2 00:04:41 2018 +0530 - - arm64: dts: freescale: ls1088a: Modify DT nodes for qspi - - Signed-off-by: Suresh Gupta - Signed-off-by: Yogesh Gaur - -commit 01a1ea9e781d307ab87da95043ec898736495fff -Author: Zhang Ying-22455 -Date: Thu Nov 2 10:36:48 2017 +0800 - - arm64: dts: ls1088a: correct the i2c clock to 1/8 platform pll - - Signed-off-by: Zhang Ying-22455 - -commit 60122f1192e1cc23e5952468cc5a884287d64907 -Author: Bharat Bhushan -Date: Thu Sep 7 10:08:31 2017 +0530 - - arm64: dts: ls1088a: Add iommu-map property for pci - - This patch adds iommu-map property for PCIe, which enables - SMMU for these devices on LS1088. - - Signed-off-by: Bharat Bhushan - -commit 43c4d0cf074106b411280c5b2be75d5d6e63fb01 -Author: Iordache Florinel-R70177 -Date: Mon Aug 21 11:43:07 2017 +0300 - - arm64: dts: ls1088a: add backplane support - - Signed-off-by: Iordache Florinel-R70177 - -commit 57d49424694f72adbf7cf1dbeff38704f0d65359 -Author: Ashish Kumar -Date: Mon Jun 19 18:32:13 2017 +0530 - - arm64: dts: ls1088: Add Reboot node in dtsi - - Signed-off-by: Ashish Kumar - -commit ee950989a7babc240153a20fe468573e13d61f98 -Author: Zhang Ying-22455 -Date: Thu May 11 14:59:28 2017 +0800 - - arm64: dts: ls1088a: add ftm0 nodes - - Signed-off-by: Zhang Ying-22455 - -commit 6d3a96446a7ffccb0b9936b616d855c8d5572bce -Author: Bogdan Purcareata -Date: Wed May 3 14:26:35 2017 +0000 - - arm64: dts: fsl/ls1088,ls208x: Add mdio and phy nodes - - Add mdio and phy nodes for the following FSL platforms: - - LS1088A RDB - - LS2080A QDS & RDB - - LS2088A QDS, RDB & simu - - Contains contributions from patches by the following authors: - Signed-off-by: Shaohui Xie - Signed-off-by: Rai Harninder - Signed-off-by: Pratiyush Mohan Srivastava - - Signed-off-by: Raghav Dogra - Signed-off-by: Santan Kumar - Signed-off-by: Priyanka Jain - Signed-off-by: Ashish Kumar - Signed-off-by: Abhimanyu Saini - Signed-off-by: Ioana Radulescu - Signed-off-by: Bogdan Purcareata - -commit 971ff2e74cfebb84286ec3e191f5910dded4bd41 -Author: Suresh Gupta -Date: Thu May 4 18:04:44 2017 +0530 - - arm64: dts: ls1088a: Add QSPI node for QDS, RDB - - This is temporary patch, will rewrite for open source - - Signed-off-by: Prabhakar Kushwaha - Signed-off-by: Suresh Gupta - -commit c61036e6dfe264d61cc213293040d873d863e8ac -Author: Nipun Gupta -Date: Thu Apr 27 23:35:15 2017 +0530 - - arm64: dts: add iommu-map property in fsl-mc node - - Signed-off-by: Nipun Gupta - -commit a4412cc510162a900d10c8ca4add71defb3f2d97 -Author: Nipun Gupta -Date: Wed Apr 19 22:26:15 2017 +0530 - - arm64: dts: add smmu device node in LS1088 devicetree - - Signed-off-by: Nipun Gupta ---- - arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts | 50 ++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts | 104 +++++++++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 108 +++++++++++++++++++++- - 3 files changed, 261 insertions(+), 1 deletion(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts -@@ -131,6 +131,30 @@ - }; - }; - -+&qspi { -+ status = "okay"; -+ fsl,qspi-has-second-chip; -+ qflash0: s25fs512s@0 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <20000000>; -+ reg = <0>; -+ spi-rx-bus-width = <4>; -+ spi-tx-bus-width = <4>; -+ }; -+ -+ qflash1: s25fs512s@1 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <20000000>; -+ reg = <1>; -+ spi-rx-bus-width = <4>; -+ spi-tx-bus-width = <4>; -+ }; -+}; -+ - &duart0 { - status = "okay"; - }; -@@ -146,3 +170,29 @@ - &sata { - status = "okay"; - }; -+ -+&pcs_mdio1 { -+ pcs_phy1: ethernet-phy@0 { -+ backplane-mode = "10gbase-kr"; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0x840 0x40>;/* lane B */ -+ }; -+}; -+ -+&pcs_mdio2 { -+ pcs_phy2: ethernet-phy@0 { -+ backplane-mode = "10gbase-kr"; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0x800 0x40>;/* lane A */ -+ }; -+}; -+ -+/* Update DPMAC connections to backplane PHYs, under SerDes 0x1D_0xXX. -+ * &dpmac1 { -+ * phy-handle = <&pcs_phy1>; -+ * }; -+ */ ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts -@@ -74,6 +74,31 @@ - }; - }; - -+&qspi { -+ status = "okay"; -+ fsl,qspi-has-second-chip; -+ qflash0: s25fs512s@0 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <20000000>; -+ reg = <0>; -+ spi-rx-bus-width = <4>; -+ spi-tx-bus-width = <4>; -+ }; -+ -+ qflash1: s25fs512s@1 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <20000000>; -+ reg = <1>; -+ spi-rx-bus-width = <4>; -+ spi-tx-bus-width = <4>; -+ }; -+ -+}; -+ - &duart0 { - status = "okay"; - }; -@@ -97,3 +122,82 @@ - &usb1 { - status = "okay"; - }; -+ -+&emdio1 { -+ /* Freescale F104 PHY1 */ -+ mdio1_phy1: emdio1_phy@1 { -+ reg = <0x1c>; -+ phy-connection-type = "qsgmii"; -+ }; -+ mdio1_phy2: emdio1_phy@2 { -+ reg = <0x1d>; -+ phy-connection-type = "qsgmii"; -+ }; -+ mdio1_phy3: emdio1_phy@3 { -+ reg = <0x1e>; -+ phy-connection-type = "qsgmii"; -+ }; -+ mdio1_phy4: emdio1_phy@4 { -+ reg = <0x1f>; -+ phy-connection-type = "qsgmii"; -+ }; -+ /* F104 PHY2 */ -+ mdio1_phy5: emdio1_phy@5 { -+ reg = <0x0c>; -+ phy-connection-type = "qsgmii"; -+ }; -+ mdio1_phy6: emdio1_phy@6 { -+ reg = <0x0d>; -+ phy-connection-type = "qsgmii"; -+ }; -+ mdio1_phy7: emdio1_phy@7 { -+ reg = <0x0e>; -+ phy-connection-type = "qsgmii"; -+ }; -+ mdio1_phy8: emdio1_phy@8 { -+ reg = <0x0f>; -+ phy-connection-type = "qsgmii"; -+ }; -+}; -+ -+&emdio2 { -+ /* Aquantia AQR105 10G PHY */ -+ mdio2_phy1: emdio2_phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ interrupts = <0 2 0x4>; -+ reg = <0x0>; -+ phy-connection-type = "xfi"; -+ }; -+}; -+ -+/* DPMAC connections to external PHYs -+ * based on LS1088A RM RevC - $24.1.2 SerDes Options -+ */ -+/* DPMAC1 is 10G SFP+, fixed link */ -+&dpmac2 { -+ phy-handle = <&mdio2_phy1>; -+}; -+&dpmac3 { -+ phy-handle = <&mdio1_phy5>; -+}; -+&dpmac4 { -+ phy-handle = <&mdio1_phy6>; -+}; -+&dpmac5 { -+ phy-handle = <&mdio1_phy7>; -+}; -+&dpmac6 { -+ phy-handle = <&mdio1_phy8>; -+}; -+&dpmac7 { -+ phy-handle = <&mdio1_phy1>; -+}; -+&dpmac8 { -+ phy-handle = <&mdio1_phy2>; -+}; -+&dpmac9 { -+ phy-handle = <&mdio1_phy3>; -+}; -+&dpmac10 { -+ phy-handle = <&mdio1_phy4>; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -185,6 +185,19 @@ - clock-output-names = "sysclk"; - }; - -+ rstcr: syscon@1e60000 { -+ compatible = "fsl,ls1088a-rstcr", "syscon"; -+ reg = <0x0 0x1e60000 0x0 0x4>; -+ }; -+ -+ reboot { -+ compatible = "syscon-reboot"; -+ regmap = <&rstcr>; -+ offset = <0x0>; -+ mask = <0x02>; -+ }; -+ -+ - soc { - compatible = "simple-bus"; - #address-cells = <2>; -@@ -205,6 +218,11 @@ - little-endian; - }; - -+ serdes1: serdes@1ea0000 { -+ reg = <0x0 0x1ea0000 0 0x00002000>; -+ compatible = "fsl,serdes-10g"; -+ }; -+ - tmu: tmu@1f80000 { - compatible = "fsl,qoriq-tmu"; - reg = <0x0 0x1f80000 0x0 0x10000>; -@@ -325,6 +343,72 @@ - #interrupt-cells = <2>; - }; - -+ /* TODO: WRIOP (CCSR?) */ -+ emdio1: mdio@0x8B96000 { /* WRIOP0: 0x8B8_0000, -+ * E-MDIO1: 0x1_6000 -+ */ -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8B96000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; /* force the driver in LE mode */ -+ -+ /* Not necessary on the QDS, but needed on the RDB */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ emdio2: mdio@0x8B97000 { /* WRIOP0: 0x8B8_0000, -+ * E-MDIO2: 0x1_7000 -+ */ -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8B97000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; /* force the driver in LE mode */ -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio1: mdio@0x8c07000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c07000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio2: mdio@0x8c0b000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c0b000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio3: mdio@0x8c0f000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c0f000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio4: mdio@0x8c13000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c13000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - ifc: ifc@2240000 { - compatible = "fsl,ifc", "simple-bus"; - reg = <0x0 0x2240000 0x0 0x20000>; -@@ -335,13 +419,20 @@ - status = "disabled"; - }; - -+ ftm0: ftm0@2800000 { -+ compatible = "fsl,ftm-alarm"; -+ reg = <0x0 0x2800000 0x0 0x10000>; -+ interrupts = <0 44 4>; -+ }; -+ - i2c0: i2c@2000000 { -- compatible = "fsl,vf610-i2c"; -+ compatible = "fsl,vf610-i2c", "fsl,ls1088a-vf610-i2c"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0 0x2000000 0x0 0x10000>; - interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clockgen 4 7>; -+ scl-gpios = <&gpio3 30 0>; - status = "disabled"; - }; - -@@ -405,6 +496,7 @@ - dr_mode = "host"; - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; -+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - status = "disabled"; - }; - -@@ -418,6 +510,17 @@ - dma-coherent; - status = "disabled"; - }; -+ qspi: spi@20c0000 { -+ compatible = "fsl,ls2080a-qspi", "fsl,ls1088a-qspi"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0 0x20c0000 0x0 0x10000>, -+ <0x0 0x20000000 0x0 0x10000000>; -+ reg-names = "QuadSPI", "QuadSPI-memory"; -+ interrupts = <0 25 0x4>; /* Level high type */ -+ clocks = <&clockgen 4 3>, <&clockgen 4 3>; -+ clock-names = "qspi_en", "qspi"; -+ }; - - crypto: crypto@8000000 { - compatible = "fsl,sec-v5.0", "fsl,sec-v4.0"; -@@ -474,6 +577,7 @@ - ranges = <0x81000000 0x0 0x00000000 0x20 0x00010000 0x0 0x00010000 /* downstream I/O */ - 0x82000000 0x0 0x40000000 0x20 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 0 109 IRQ_TYPE_LEVEL_HIGH>, -@@ -499,6 +603,7 @@ - ranges = <0x81000000 0x0 0x00000000 0x28 0x00010000 0x0 0x00010000 /* downstream I/O */ - 0x82000000 0x0 0x40000000 0x28 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 0 114 IRQ_TYPE_LEVEL_HIGH>, -@@ -524,6 +629,7 @@ - ranges = <0x81000000 0x0 0x00000000 0x30 0x00010000 0x0 0x00010000 /* downstream I/O */ - 0x82000000 0x0 0x40000000 0x30 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 0 119 IRQ_TYPE_LEVEL_HIGH>, diff --git a/target/linux/layerscape/patches-5.4/302-dts-0010-arm64-dts-ls208xa-accumulated-change-to-ls208xa-boar.patch b/target/linux/layerscape/patches-5.4/302-dts-0010-arm64-dts-ls208xa-accumulated-change-to-ls208xa-boar.patch deleted file mode 100644 index a763e05724..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0010-arm64-dts-ls208xa-accumulated-change-to-ls208xa-boar.patch +++ /dev/null @@ -1,959 +0,0 @@ -From 9d8de47b617baa4fa92d9a1502904c0373f80384 Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Thu, 2 May 2019 16:12:40 -0500 -Subject: [PATCH] arm64: dts: ls208xa: accumulated change to ls208xa boards - -commit 46123df3a174f0d76c8b954a0386e64841453836 -Author: Florinel Iordache -Date: Thu Aug 9 12:29:18 2018 +0300 - - arm64: dts: updates for Unified Backplane driver - - Signed-off-by: Florinel Iordache - -commit 76a741dbb9b93ea9ab2f6122b8df5bc4f0db7676 -Author: Nipun Gupta -Date: Sat Apr 28 00:20:16 2018 +0530 - - arm64: dts: ls208x: add dma-cohernet property in fsl-mc node - - Signed-off-by: Nipun Gupta - -commit f6309e9dc8e0c6171a43fd6759123b5de1c574aa -Author: Zhang Ying-22455 -Date: Mon Apr 2 16:27:23 2018 +0800 - - arm64: dts: ls208xa: add dts entry for A-010650 - - Signed-off-by: Zhang Ying-22455 - -commit 8c37bad2038a210a4f0a369fd946aaae4317eac4 -Author: Nipun Gupta -Date: Fri Apr 20 17:14:10 2018 +0530 - - arm64: dts: ls208x: add dma ranges property - - Signed-off-by: Nipun Gupta - -commit 38566bbd5ca6747b30d2f0c251bbcfe0723df8c6 -Author: Changming Huang -Date: Wed Apr 19 12:49:50 2017 +0800 - - arm/arm64: dts: Add property snps incr burst type adjustment for -INCR burst type for dwc3 - - Signed-off-by: yinbo.zhu - Signed-off-by: Ran Wang - -commit dbb65ea8ee1d46067e756c6d64c7fe66a0058f49 -Author: Pankaj Bansal -Date: Mon Mar 5 12:37:04 2018 +0530 - - arm64: dts: ls208x: remove NXP Erratum A008585 from LS2088A. - - NXP Erratum A008585 affects A57 core cluster used in LS2085rev1. - However this problem has been fixed in A72 core cluster used in -LS2088. - Therefore remove the erratum from LS2088A. Keeping it only in -LS2085. - - Cc: # 4.14 - Signed-off-by: Pankaj Bansal - Reviewed-by: Sandeep Malik - Acked-by: Priyanka Jain - -commit 85f41b0f6abe6b9d7d303790bb3712ed559890e9 -Author: Nipun Gupta -Date: Mon Feb 26 10:39:54 2018 +0530 - - arm64: dts: ls208xa: add dma coherent property in smmu node - - Signed-off-by: Nipun Gupta - -commit e910d8b78b823a625451b1da7ae7499dadde2ae9 -Author: Suresh Gupta -Date: Thu Feb 1 23:49:56 2018 +0530 - - arm64: dts: freescale: ls208xa: Modify DT nodes for qspi - - Signed-off-by: Abhimanyu Saini - -commit 7654ef78c8c85de3a43dfa0dffd572d589ea1332 -Author: Zhang Ying-22455 -Date: Wed Nov 1 10:34:04 2017 +0800 - - arm64: dts: ls208xa: correct the i2c clock to 1/2 platform pll - - Signed-off-by: Zhang Ying-22455 - -commit efdb129228baa6a999c06072338b979d783d7b60 -Author: Bharat Bhushan -Date: Thu Aug 31 14:45:02 2017 +0530 - - arm64: dts: ls208xa: Add iommu-map property for pci - - This patch adds iommu-map property for PCIe, which enables - SMMU for these devices on LS208xA devices. - - Signed-off-by: Bharat Bhushan - -commit 45af5d025eafaf4a85000e16e5f47992de663ff6 -Author: Iordache Florinel-R70177 -Date: Mon Aug 21 11:46:59 2017 +0300 - - arm64: dts: ls2088a: update backplane support with dpmac connections - - Signed-off-by: Iordache Florinel-R70177 - -commit b2ede6c088a883fceb348e8659253b2c7cdeeff8 -Author: Santan Kumar -Date: Thu Jun 22 13:04:00 2017 +0530 - - arm64: dts: ls2088ardb: Update nodes for QSPI - - -As per board design, different QSPI flash is connected on - boards, hence change QSPI flash node from s25fl256s1 to s25fs512ss -in - device tree. - -Enable fast-read support in QSPI node. - - Signed-off-by: Santan Kumar - -commit d5324a75c56e9f9210113e51cffa846a86b50fbd -Author: Santan Kumar -Date: Mon Jun 19 15:26:03 2017 +0530 - - arm64: dts: ls2081ardb: Update nodes for QSPI, SATA, INA220 - - Update ls2081ardb.dts for below nodes: - -As per updated board design, different QSPI flash is connected on - boards, hence change QSPI flash node from n25q512a to s25fs512ss -in - device tree. - -Enable dual flash support in QSPI node. - -Add DTS node for INA220. - -Enable SATA node. - - Signed-off-by: Santan Kumar - Signed-off-by: Tao Yang - Signed-off-by: Yogesh Gaur - -commit 43d506fa19e1e50e4c2e4f9689ad3c60d9a06d71 -Author: Zhang Ying-22455 -Date: Thu May 11 08:42:19 2017 +0800 - - arm64: dts: ls208x: add property for PCA954x Mux device - - PCA954x Mux device should never be turned-off after power-on. if - device tree contians "i2c-mux-never-disable" property for pca954x - device node, it can ensure that skip disabling PCA954x Mux device. - - Signed-off-by: Zhang Ying-22455 - -commit 6d3a96446a7ffccb0b9936b616d855c8d5572bce -Author: Bogdan Purcareata -Date: Wed May 3 14:26:35 2017 +0000 - - arm64: dts: fsl/ls1088,ls208x: Add mdio and phy nodes - - Add mdio and phy nodes for the following FSL platforms: - - LS1088A RDB - - LS2080A QDS & RDB - - LS2088A QDS, RDB & simu - - Contains contributions from patches by the following authors: - Signed-off-by: Shaohui Xie - Signed-off-by: Rai Harninder - Signed-off-by: Pratiyush Mohan Srivastava - - Signed-off-by: Raghav Dogra - Signed-off-by: Santan Kumar - Signed-off-by: Priyanka Jain - Signed-off-by: Ashish Kumar - Signed-off-by: Abhimanyu Saini - Signed-off-by: Ioana Radulescu - Signed-off-by: Bogdan Purcareata - -commit 0443625ea24bc4ea315c30b718712254c588bd18 -Author: Suresh Gupta -Date: Fri May 5 13:54:22 2017 +0530 - - arm64: dts: ls208xa: Add QSPI Flash node for RDB - - This is temporary patch, will rewrite for open source - - Signed-off-by: Suresh Gupta - -commit ed0ce1d49aa72d12ea54f82d3771a377c68af37e -Author: Priyanka Jain -Date: Thu Apr 13 16:49:40 2017 +0530 - - arm64: dts: ls2081ardb: Add DTS support for NXP LS2081ARDB - - This patch add support for NXP LS2081ARDB board which has - LS2081A SoC. - - LS2081A SoC is 40-pin derivative of LS2088A SoC - So, from functional perspective both are same. - Hence,ls2088a SoC dtsi files are included from ls2081ARDB dts - - Signed-off-by: Priyanka Jain - -commit e4fb842554a5e7b8c3f6e3c243222dbe4515aee3 -Author: Zhang Ying-22455 -Date: Thu Apr 27 15:01:54 2017 +0800 - - arm64: dts: ls208xa: add ftm0 nodes - - Signed-off-by: Zhang Ying-22455 - -commit 64c3e2c3a7ddc89c3c23c012ee364f2c014524d2 -Author: costi -Date: Fri Mar 3 18:08:28 2017 +0200 - - arm64: dts: fsl-ls2088: Add mdio/phy devices - - Signed-off-by: Constantin Tudor - -commit 3bcdc4de0a1c9e6f4a4ddc916e8efe8044d8bbfd -Author: Po Liu -Date: Fri Sep 30 17:11:36 2016 +0800 - - arm64: dts: ls1043/ls2080: add pcie aer/pme interrupt-name property - - Some platforms(NXP Layerscape for example) aer/pme interrupts was -not - MSI/MSI-X/INTx but using interrupt line independently. This patch - add "aer", "pme" interrupt-names for aer/pme interrupt. - - With the interrupt-names "aer", "pme" code could probe aer/pme -interrupt - line for pcie root port, replace the aer/pme interrupt service irqs. - - This is intend to fixup the Layerscape platforms which aer/pmes -interrupts - was not MSI/MSI-X/INTx, but using interrupt line independently. - - Since the interrupt-names "intr" never been used. Remove it. - - Signed-off-by: Po Liu - Signed-off-by: Hou Zhiqiang - -commit 64d859836d3d194e8bc926bb951fd21859689824 -Author: Nipun Gupta -Date: Mon Dec 5 05:20:51 2016 +0530 - - arm64: dts: ls208xa: Comply with the new iommu binding for fsl_mc - - fsl-mc bus support the new iommu-map property. Comply to this -binding - for fsl_mc bus. - - Signed-off-by: Nipun Gupta ---- - arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts | 62 +++++++++ - arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts | 80 +++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 12 ++ - arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts | 120 ++++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts | 80 +++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi | 1 + - arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi | 11 +- - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 155 +++++++++++++++++++-- - 8 files changed, 505 insertions(+), 16 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-qds.dts -@@ -23,3 +23,65 @@ - stdout-path = "serial0:115200n8"; - }; - }; -+ -+&ifc { -+ boardctrl: board-control@3,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,tetra-fpga", "fsl,fpga-qixis", "simple-bus"; -+ reg = <3 0 0x300>; /* TODO check address */ -+ ranges = <0 3 0 0x300>; -+ -+ mdio_mux_emi1 { -+ compatible = "mdio-mux-mmioreg", "mdio-mux"; -+ mdio-parent-bus = <&emdio1>; -+ reg = <0x54 1>; /* BRDCFG4 */ -+ mux-mask = <0xe0>; /* EMI1_MDIO */ -+ -+ #address-cells=<1>; -+ #size-cells = <0>; -+ -+ /* Child MDIO buses, one for each riser card: -+ * reg = 0x0, 0x20, 0x40, 0x60, 0x80, 0xa0. -+ * VSC8234 PHYs on the riser cards. -+ */ -+ -+ mdio_mux3: mdio@60 { -+ reg = <0x60>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ mdio0_phy12: mdio_phy0@1c { -+ reg = <0x1c>; -+ phy-connection-type = "sgmii"; -+ }; -+ mdio0_phy13: mdio_phy1@1d { -+ reg = <0x1d>; -+ phy-connection-type = "sgmii"; -+ }; -+ mdio0_phy14: mdio_phy2@1e { -+ reg = <0x1e>; -+ phy-connection-type = "sgmii"; -+ }; -+ mdio0_phy15: mdio_phy3@1f { -+ reg = <0x1f>; -+ phy-connection-type = "sgmii"; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+/* Update DPMAC connections to external PHYs, under SerDes 0x2a_0x49. */ -+&dpmac9 { -+ phy-handle = <&mdio0_phy12>; -+}; -+&dpmac10 { -+ phy-handle = <&mdio0_phy13>; -+}; -+&dpmac11 { -+ phy-handle = <&mdio0_phy14>; -+}; -+&dpmac12 { -+ phy-handle = <&mdio0_phy15>; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a-rdb.dts -@@ -23,3 +23,83 @@ - stdout-path = "serial1:115200n8"; - }; - }; -+ -+&emdio1 { -+ status = "disabled"; -+ /* CS4340 PHYs */ -+ mdio1_phy1: emdio1_phy@1 { -+ reg = <0x10>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio1_phy2: emdio1_phy@2 { -+ reg = <0x11>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio1_phy3: emdio1_phy@3 { -+ reg = <0x12>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio1_phy4: emdio1_phy@4 { -+ reg = <0x13>; -+ phy-connection-type = "xfi"; -+ }; -+}; -+ -+&emdio2 { -+ /* AQR405 PHYs */ -+ mdio2_phy1: emdio2_phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ interrupts = <0 1 0x4>; /* Level high type */ -+ reg = <0x0>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio2_phy2: emdio2_phy@2 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ interrupts = <0 2 0x4>; /* Level high type */ -+ reg = <0x1>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio2_phy3: emdio2_phy@3 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ interrupts = <0 4 0x4>; /* Level high type */ -+ reg = <0x2>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio2_phy4: emdio2_phy@4 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ interrupts = <0 5 0x4>; /* Level high type */ -+ reg = <0x3>; -+ phy-connection-type = "xfi"; -+ }; -+}; -+ -+/* Update DPMAC connections to external PHYs, under the assumption of -+ * SerDes 0x2a_0x41. This is currently the only SerDes supported on the board. -+ */ -+/* Leave Cortina nodes commented out until driver is integrated -+ *&dpmac1 { -+ * phy-handle = <&mdio1_phy1>; -+ *}; -+ *&dpmac2 { -+ * phy-handle = <&mdio1_phy2>; -+ *}; -+ *&dpmac3 { -+ * phy-handle = <&mdio1_phy3>; -+ *}; -+ *&dpmac4 { -+ * phy-handle = <&mdio1_phy4>; -+ *}; -+ */ -+ -+&dpmac5 { -+ phy-handle = <&mdio2_phy1>; -+}; -+&dpmac6 { -+ phy-handle = <&mdio2_phy2>; -+}; -+&dpmac7 { -+ phy-handle = <&mdio2_phy3>; -+}; -+&dpmac8 { -+ phy-handle = <&mdio2_phy4>; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi -@@ -118,6 +118,18 @@ - }; - }; - -+&timer { -+ fsl,erratum-a008585; -+}; -+ -+&usb0 { -+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+}; -+ -+&usb1 { -+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+}; -+ - &pcie1 { - reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ - 0x10 0x00000000 0x0 0x00002000>; /* configuration space */ ---- a/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts -@@ -22,3 +22,123 @@ - stdout-path = "serial0:115200n8"; - }; - }; -+ -+&ifc { -+ boardctrl: board-control@3,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,tetra-fpga", "fsl,fpga-qixis", "simple-bus"; -+ reg = <3 0 0x300>; /* TODO check address */ -+ ranges = <0 3 0 0x300>; -+ -+ mdio_mux_emi1 { -+ compatible = "mdio-mux-mmioreg", "mdio-mux"; -+ mdio-parent-bus = <&emdio1>; -+ reg = <0x54 1>; /* BRDCFG4 */ -+ mux-mask = <0xe0>; /* EMI1_MDIO */ -+ -+ #address-cells=<1>; -+ #size-cells = <0>; -+ -+ /* Child MDIO buses, one for each riser card: -+ * reg = 0x0, 0x20, 0x40, 0x60, 0x80, 0xa0. -+ * VSC8234 PHYs on the riser cards. -+ */ -+ -+ mdio_mux3: mdio@60 { -+ reg = <0x60>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ mdio0_phy12: mdio_phy0@1c { -+ reg = <0x1c>; -+ phy-connection-type = "sgmii"; -+ }; -+ mdio0_phy13: mdio_phy1@1d { -+ reg = <0x1d>; -+ phy-connection-type = "sgmii"; -+ }; -+ mdio0_phy14: mdio_phy2@1e { -+ reg = <0x1e>; -+ phy-connection-type = "sgmii"; -+ }; -+ mdio0_phy15: mdio_phy3@1f { -+ reg = <0x1f>; -+ phy-connection-type = "sgmii"; -+ }; -+ }; -+ }; -+ }; -+}; -+ -+&pcs_mdio1 { -+ pcs_phy1: ethernet-phy@0 { -+ backplane-mode = "10gbase-kr"; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0x9C0 0x40>;/* lane H */ -+ }; -+}; -+ -+&pcs_mdio2 { -+ pcs_phy2: ethernet-phy@0 { -+ backplane-mode = "10gbase-kr"; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0x980 0x40>;/* lane G */ -+ }; -+}; -+ -+&pcs_mdio3 { -+ pcs_phy3: ethernet-phy@0 { -+ backplane-mode = "10gbase-kr"; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0x940 0x40>;/* lane F */ -+ }; -+}; -+ -+&pcs_mdio4 { -+ pcs_phy4: ethernet-phy@0 { -+ backplane-mode = "10gbase-kr"; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0x900 0x40>;/* lane E */ -+ }; -+}; -+ -+/* Update DPMAC connections to backplane PHYs, under SerDes 0x2a_0xXX. -+ * &dpmac1 { -+ * phy-handle = <&pcs_phy1>; -+ * }; -+ * -+ * &dpmac2 { -+ * phy-handle = <&pcs_phy2>; -+ * }; -+ * -+ * &dpmac3 { -+ * phy-handle = <&pcs_phy3>; -+ * }; -+ * -+ * &dpmac4 { -+ * phy-handle = <&pcs_phy4>; -+ * }; -+ */ -+ -+/* Update DPMAC connections to external PHYs, under SerDes 0x2a_0x49. */ -+&dpmac9 { -+ phy-handle = <&mdio0_phy12>; -+}; -+&dpmac10 { -+ phy-handle = <&mdio0_phy13>; -+}; -+&dpmac11 { -+ phy-handle = <&mdio0_phy14>; -+}; -+&dpmac12 { -+ phy-handle = <&mdio0_phy15>; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a-rdb.dts -@@ -22,3 +22,83 @@ - stdout-path = "serial1:115200n8"; - }; - }; -+ -+&emdio1 { -+ status = "disabled"; -+ /* CS4340 PHYs */ -+ mdio1_phy1: emdio1_phy@1 { -+ reg = <0x10>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio1_phy2: emdio1_phy@2 { -+ reg = <0x11>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio1_phy3: emdio1_phy@3 { -+ reg = <0x12>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio1_phy4: emdio1_phy@4 { -+ reg = <0x13>; -+ phy-connection-type = "xfi"; -+ }; -+}; -+ -+&emdio2 { -+ /* AQR405 PHYs */ -+ mdio2_phy1: emdio2_phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ interrupts = <0 1 0x4>; /* Level high type */ -+ reg = <0x0>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio2_phy2: emdio2_phy@2 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ interrupts = <0 2 0x4>; /* Level high type */ -+ reg = <0x1>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio2_phy3: emdio2_phy@3 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ interrupts = <0 4 0x4>; /* Level high type */ -+ reg = <0x2>; -+ phy-connection-type = "xfi"; -+ }; -+ mdio2_phy4: emdio2_phy@4 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ interrupts = <0 5 0x4>; /* Level high type */ -+ reg = <0x3>; -+ phy-connection-type = "xfi"; -+ }; -+}; -+ -+/* Update DPMAC connections to external PHYs, under the assumption of -+ * SerDes 0x2a_0x41. This is currently the only SerDes supported on the board. -+ */ -+/* Leave Cortina PHYs commented out until proper driver is integrated -+ *&dpmac1 { -+ * phy-handle = <&mdio1_phy1>; -+ *}; -+ *&dpmac2 { -+ * phy-handle = <&mdio1_phy2>; -+ *}; -+ *&dpmac3 { -+ * phy-handle = <&mdio1_phy3>; -+ *}; -+ *&dpmac4 { -+ * phy-handle = <&mdio1_phy4>; -+ *}; -+ */ -+ -+&dpmac5 { -+ phy-handle = <&mdio2_phy1>; -+}; -+&dpmac6 { -+ phy-handle = <&mdio2_phy2>; -+}; -+&dpmac7 { -+ phy-handle = <&mdio2_phy3>; -+}; -+&dpmac8 { -+ phy-handle = <&mdio2_phy4>; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi -@@ -129,6 +129,7 @@ - - &qspi { - status = "okay"; -+ fsl,qspi-has-second-chip; - flash0: s25fl256s1@0 { - #address-cells = <1>; - #size-cells = <1>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi -@@ -49,6 +49,7 @@ - reg = <0x75>; - #address-cells = <1>; - #size-cells = <0>; -+ i2c-mux-never-disable; - i2c@1 { - #address-cells = <1>; - #size-cells = <0>; -@@ -108,7 +109,15 @@ - }; - - &qspi { -- status = "disabled"; -+ status = "okay"; -+ flash0: s25fs512s@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "spansion,m25p80"; -+ m25p,fast-read; -+ spi-max-frequency = <20000000>; -+ reg = <0>; -+ }; - }; - - &sata0 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -114,13 +114,12 @@ - }; - }; - -- timer { -+ timer: timer { - compatible = "arm,armv8-timer"; - interrupts = <1 13 4>, /* Physical Secure PPI, active-low */ - <1 14 4>, /* Physical Non-Secure PPI, active-low */ - <1 11 4>, /* Virtual PPI, active-low */ - <1 10 4>; /* Hypervisor PPI, active-low */ -- fsl,erratum-a008585; - }; - - pmu { -@@ -559,15 +558,126 @@ - #interrupt-cells = <2>; - }; - -+ /* TODO: WRIOP (CCSR?) */ -+ emdio1: mdio@0x8B96000 { /* WRIOP0: 0x8B8_0000, -+ * E-MDIO1: 0x1_6000 -+ */ -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8B96000 0x0 0x1000>; -+ device_type = "mdio"; /* TODO: is this necessary? */ -+ little-endian; /* force the driver in LE mode */ -+ -+ /* Not necessary on the QDS, but needed on the RDB */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ emdio2: mdio@0x8B97000 { /* WRIOP0: 0x8B8_0000, -+ * E-MDIO2: 0x1_7000 -+ */ -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8B97000 0x0 0x1000>; -+ device_type = "mdio"; /* TODO: is this necessary? */ -+ little-endian; /* force the driver in LE mode */ -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio1: mdio@0x8c07000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c07000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio2: mdio@0x8c0b000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c0b000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio3: mdio@0x8c0f000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c0f000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio4: mdio@0x8c13000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c13000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio5: mdio@0x8c17000 { -+ status = "disabled"; -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c17000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio6: mdio@0x8c1b000 { -+ status = "disabled"; -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c1b000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio7: mdio@0x8c1f000 { -+ status = "disabled"; -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c1f000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio8: mdio@0x8c23000 { -+ status = "disabled"; -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c23000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - i2c0: i2c@2000000 { - status = "disabled"; -- compatible = "fsl,vf610-i2c"; -+ compatible = "fsl,vf610-i2c", "fsl,ls208xa-vf610-i2c"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0 0x2000000 0x0 0x10000>; - interrupts = <0 34 0x4>; /* Level high type */ - clock-names = "i2c"; -- clocks = <&clockgen 4 3>; -+ clocks = <&clockgen 4 1>; -+ scl-gpios = <&gpio3 10 0>; - }; - - i2c1: i2c@2010000 { -@@ -578,7 +688,7 @@ - reg = <0x0 0x2010000 0x0 0x10000>; - interrupts = <0 34 0x4>; /* Level high type */ - clock-names = "i2c"; -- clocks = <&clockgen 4 3>; -+ clocks = <&clockgen 4 1>; - }; - - i2c2: i2c@2020000 { -@@ -589,7 +699,7 @@ - reg = <0x0 0x2020000 0x0 0x10000>; - interrupts = <0 35 0x4>; /* Level high type */ - clock-names = "i2c"; -- clocks = <&clockgen 4 3>; -+ clocks = <&clockgen 4 1>; - }; - - i2c3: i2c@2030000 { -@@ -600,7 +710,7 @@ - reg = <0x0 0x2030000 0x0 0x10000>; - interrupts = <0 35 0x4>; /* Level high type */ - clock-names = "i2c"; -- clocks = <&clockgen 4 3>; -+ clocks = <&clockgen 4 1>; - }; - - ifc: ifc@2240000 { -@@ -632,8 +742,8 @@ - pcie1: pcie@3400000 { - compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie"; - reg-names = "regs", "config"; -- interrupts = <0 108 0x4>; /* Level high type */ -- interrupt-names = "intr"; -+ interrupts = <0 108 0x4>; /* aer interrupt */ -+ interrupt-names = "aer"; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; -@@ -641,6 +751,7 @@ - num-viewport = <6>; - bus-range = <0x0 0xff>; - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 0 109 4>, -@@ -653,8 +764,8 @@ - pcie2: pcie@3500000 { - compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie"; - reg-names = "regs", "config"; -- interrupts = <0 113 0x4>; /* Level high type */ -- interrupt-names = "intr"; -+ interrupts = <0 113 0x4>; /* aer interrupt */ -+ interrupt-names = "aer"; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; -@@ -662,6 +773,7 @@ - num-viewport = <6>; - bus-range = <0x0 0xff>; - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 0 114 4>, -@@ -674,8 +786,8 @@ - pcie3: pcie@3600000 { - compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie"; - reg-names = "regs", "config"; -- interrupts = <0 118 0x4>; /* Level high type */ -- interrupt-names = "intr"; -+ interrupts = <0 118 0x4>; /* aer interrupt */ -+ interrupt-names = "aer"; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; -@@ -683,6 +795,7 @@ - num-viewport = <256>; - bus-range = <0x0 0xff>; - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 0 119 4>, -@@ -695,8 +808,8 @@ - pcie4: pcie@3700000 { - compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie"; - reg-names = "regs", "config"; -- interrupts = <0 123 0x4>; /* Level high type */ -- interrupt-names = "intr"; -+ interrupts = <0 123 0x4>; /* aer interrupt */ -+ interrupt-names = "aer"; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; -@@ -704,6 +817,7 @@ - num-viewport = <6>; - bus-range = <0x0 0xff>; - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 0 124 4>, -@@ -753,11 +867,22 @@ - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - }; - -+ serdes1: serdes@1ea0000 { -+ reg = <0x0 0x1ea0000 0 0x00002000>; -+ compatible = "fsl,serdes-10g"; -+ }; -+ - ccn@4000000 { - compatible = "arm,ccn-504"; - reg = <0x0 0x04000000 0x0 0x01000000>; - interrupts = <0 12 4>; - }; -+ -+ ftm0: ftm0@2800000 { -+ compatible = "fsl,ftm-alarm"; -+ reg = <0x0 0x2800000 0x0 0x10000>; -+ interrupts = <0 44 4>; -+ }; - }; - - ddr1: memory-controller@1080000 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0011-ARM-dts-accumulated-change.patch b/target/linux/layerscape/patches-5.4/302-dts-0011-ARM-dts-accumulated-change.patch deleted file mode 100644 index 6f3181d65a..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0011-ARM-dts-accumulated-change.patch +++ /dev/null @@ -1,156 +0,0 @@ -From a9f1c1d3e410596d0a39fd92562cc48ef960b1b7 Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Fri, 5 Oct 2018 18:33:49 -0500 -Subject: [PATCH] ARM: dts: accumulated change - -Signed-off-by: Li Yang ---- - arch/arm/boot/dts/ls1021a-qds.dts | 15 +++++++++++++++ - arch/arm/boot/dts/ls1021a-twr.dts | 15 +++++++++++++++ - arch/arm/boot/dts/ls1021a.dtsi | 29 ++++++++++++++++++++++++----- - 3 files changed, 54 insertions(+), 5 deletions(-) - ---- a/arch/arm/boot/dts/ls1021a-qds.dts -+++ b/arch/arm/boot/dts/ls1021a-qds.dts -@@ -126,6 +126,21 @@ - }; - }; - -+&qspi { -+ num-cs = <2>; -+ status = "okay"; -+ -+ qflash0: s25fl128s@0 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <20000000>; -+ reg = <0>; -+ spi-rx-bus-width = <4>; -+ spi-tx-bus-width = <4>; -+ }; -+}; -+ - &enet0 { - tbi-handle = <&tbi0>; - phy-handle = <&sgmii_phy1c>; ---- a/arch/arm/boot/dts/ls1021a-twr.dts -+++ b/arch/arm/boot/dts/ls1021a-twr.dts -@@ -144,6 +144,21 @@ - }; - }; - -+&qspi { -+ num-cs = <2>; -+ status = "okay"; -+ -+ qflash0: n25q128a13@0 { -+ compatible = "n25q128a13", "jedec,spi-nor"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <20000000>; -+ reg = <0>; -+ spi-rx-bus-width = <4>; -+ spi-tx-bus-width = <4>; -+ }; -+}; -+ - &enet0 { - tbi-handle = <&tbi0>; - phy-handle = <&sgmii_phy2>; ---- a/arch/arm/boot/dts/ls1021a.dtsi -+++ b/arch/arm/boot/dts/ls1021a.dtsi -@@ -167,12 +167,13 @@ - ifc: ifc@1530000 { - compatible = "fsl,ifc", "simple-bus"; - reg = <0x0 0x1530000 0x0 0x10000>; -+ big-endian; - interrupts = ; - }; - - dcfg: dcfg@1ee0000 { - compatible = "fsl,ls1021a-dcfg", "syscon"; -- reg = <0x0 0x1ee0000 0x0 0x10000>; -+ reg = <0x0 0x1ee0000 0x0 0x1000>; - big-endian; - }; - -@@ -338,7 +339,7 @@ - }; - - i2c0: i2c@2180000 { -- compatible = "fsl,vf610-i2c"; -+ compatible = "fsl,vf610-i2c", "fsl,ls1021a-vf610-i2c"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0 0x2180000 0x0 0x10000>; -@@ -347,11 +348,12 @@ - clocks = <&clockgen 4 1>; - dma-names = "tx", "rx"; - dmas = <&edma0 1 39>, <&edma0 1 38>; -+ fsl-scl-gpio = <&gpio3 23 0>; - status = "disabled"; - }; - - i2c1: i2c@2190000 { -- compatible = "fsl,vf610-i2c"; -+ compatible = "fsl,vf610-i2c", "fsl,ls1021a-vf610-i2c"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0 0x2190000 0x0 0x10000>; -@@ -360,6 +362,7 @@ - clocks = <&clockgen 4 1>; - dma-names = "tx", "rx"; - dmas = <&edma0 1 37>, <&edma0 1 36>; -+ fsl-scl-gpio = <&gpio3 23 0>; - status = "disabled"; - }; - -@@ -546,6 +549,16 @@ - status = "disabled"; - }; - -+ ftm0: ftm0@29d0000 { -+ compatible = "fsl,ftm-alarm"; -+ reg = <0x0 0x29d0000 0x0 0x10000>, -+ <0x0 0x1ee2140 0x0 0x4>; -+ reg-names = "ftm", "FlexTimer1"; -+ interrupts = ; -+ big-endian; -+ status = "okay"; -+ }; -+ - pwm1: pwm@29e0000 { - compatible = "fsl,vf610-ftm-pwm"; - #pwm-cells = <3>; -@@ -828,6 +841,8 @@ - dr_mode = "host"; - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - }; - -@@ -836,7 +851,9 @@ - reg = <0x00 0x03400000 0x0 0x00010000 /* controller registers */ - 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ - reg-names = "regs", "config"; -- interrupts = ; /* controller interrupt */ -+ interrupts = , -+ ; /* aer interrupt */ -+ interrupt-names = "pme", "aer"; - fsl,pcie-scfg = <&scfg 0>; - #address-cells = <3>; - #size-cells = <2>; -@@ -860,7 +877,9 @@ - reg = <0x00 0x03500000 0x0 0x00010000 /* controller registers */ - 0x48 0x00000000 0x0 0x00002000>; /* configuration space */ - reg-names = "regs", "config"; -- interrupts = ; -+ interrupts = , -+ ; /* aer interrupt */ -+ interrupt-names = "pme", "aer"; - fsl,pcie-scfg = <&scfg 1>; - #address-cells = <3>; - #size-cells = <2>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0012-arm64-dts-ls1046a-add-smmu-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0012-arm64-dts-ls1046a-add-smmu-node.patch deleted file mode 100644 index 17f402448b..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0012-arm64-dts-ls1046a-add-smmu-node.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 233d5936fb01dc7b47641e10354f7cc34124c592 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 6 Feb 2018 14:27:41 +0200 -Subject: [PATCH] arm64: dts: ls1046a: add smmu node - -This allows for the SMMU device to be probed by the SMMU kernel driver. - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 42 ++++++++++++++++++++++++++ - 1 file changed, 42 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -229,6 +229,48 @@ - bus-width = <4>; - }; - -+ smmu: iommu@9000000 { -+ compatible = "arm,mmu-500"; -+ reg = <0 0x9000000 0 0x400000>; -+ dma-coherent; -+ #global-interrupts = <2>; -+ #iommu-cells = <1>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ }; -+ - scfg: scfg@1570000 { - compatible = "fsl,ls1046a-scfg", "syscon"; - reg = <0x0 0x1570000 0x0 0x10000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0013-arm64-dts-ls1043a-add-smmu-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0013-arm64-dts-ls1043a-add-smmu-node.patch deleted file mode 100644 index 19c0bcb0dd..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0013-arm64-dts-ls1043a-add-smmu-node.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 6b81f85d194bf15cf91ed3b4a8aec2d1ed2849a8 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 3 Apr 2018 17:15:44 +0300 -Subject: [PATCH] arm64: dts: ls1043a: add smmu node - -This allows for the SMMU device to be probed by the SMMU kernel driver. - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 42 ++++++++++++++++++++++++++ - 1 file changed, 42 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -226,6 +226,48 @@ - clocks = <&sysclk>; - }; - -+ smmu: iommu@9000000 { -+ compatible = "arm,mmu-500"; -+ reg = <0 0x9000000 0 0x400000>; -+ dma-coherent; -+ #global-interrupts = <2>; -+ #iommu-cells = <1>; -+ interrupts = , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ , -+ ; -+ }; -+ - scfg: scfg@1570000 { - compatible = "fsl,ls1043a-scfg", "syscon"; - reg = <0x0 0x1570000 0x0 0x10000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0014-arm64-dts-ls104xa-set-mask-to-drop-TBU-ID-from-Strea.patch b/target/linux/layerscape/patches-5.4/302-dts-0014-arm64-dts-ls104xa-set-mask-to-drop-TBU-ID-from-Strea.patch deleted file mode 100644 index 212063986b..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0014-arm64-dts-ls104xa-set-mask-to-drop-TBU-ID-from-Strea.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 66307f9e693bd4822a683fac8cf1f63533822c18 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Thu, 3 May 2018 18:05:43 +0300 -Subject: [PATCH] arm64: dts: ls104xa: set mask to drop TBU ID from StreamID - -The StreamID entering the SMMU is actually a concatenation of the -SMMU TBU ID and the ICID configured in software. -Since the TBU ID is internal to the SoC and since we want that the -actual the ICID configured in software to enter the SMMU witout any -additional set bits, mask out the TBU ID bits and leave only the -relevant ICID bits to enter SMMU. - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 1 + - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 1 + - 2 files changed, 2 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -230,6 +230,7 @@ - compatible = "arm,mmu-500"; - reg = <0 0x9000000 0 0x400000>; - dma-coherent; -+ stream-match-mask = <0x7f00>; - #global-interrupts = <2>; - #iommu-cells = <1>; - interrupts = , ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -233,6 +233,7 @@ - compatible = "arm,mmu-500"; - reg = <0 0x9000000 0 0x400000>; - dma-coherent; -+ stream-match-mask = <0x7f00>; - #global-interrupts = <2>; - #iommu-cells = <1>; - interrupts = , diff --git a/target/linux/layerscape/patches-5.4/302-dts-0015-arm64-dts-ls104x-add-missing-dma-ranges-property.patch b/target/linux/layerscape/patches-5.4/302-dts-0015-arm64-dts-ls104x-add-missing-dma-ranges-property.patch deleted file mode 100644 index ebcbf36e75..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0015-arm64-dts-ls104x-add-missing-dma-ranges-property.patch +++ /dev/null @@ -1,35 +0,0 @@ -From f656c67b9522f18e38394fe5b6e00302c0c8ceb8 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Thu, 17 May 2018 11:40:07 +0300 -Subject: [PATCH] arm64: dts: ls104x: add missing dma ranges property - -These chips have a 48-bit address size so make sure that the dma-ranges -reflects this. Otherwise the linux kernel's dma sub-system will set -the default dma masks to full 64-bit, badly breaking dmas. - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 1 + - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 1 + - 2 files changed, 2 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -218,6 +218,7 @@ - #address-cells = <2>; - #size-cells = <2>; - ranges; -+ dma-ranges = <0x0 0x0 0x0 0x0 0x10000 0x00000000>; - - clockgen: clocking@1ee1000 { - compatible = "fsl,ls1043a-clockgen"; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -190,6 +190,7 @@ - #address-cells = <2>; - #size-cells = <2>; - ranges; -+ dma-ranges = <0x0 0x0 0x0 0x0 0x10000 0x00000000>; - - ddr: memory-controller@1080000 { - compatible = "fsl,qoriq-memory-controller"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0016-arm64-dts-ls104x-add-iommu-map-to-pci-controllers.patch b/target/linux/layerscape/patches-5.4/302-dts-0016-arm64-dts-ls104x-add-iommu-map-to-pci-controllers.patch deleted file mode 100644 index 4ca5a87884..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0016-arm64-dts-ls104x-add-iommu-map-to-pci-controllers.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 317d4e577ede33f226d24bd12a8edbaafee22e57 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Thu, 17 May 2018 11:56:27 +0300 -Subject: [PATCH] arm64: dts: ls104x: add iommu-map to pci controllers - -The pci controllers are also behind the smmu so add the iommu-map -property to reflect this. The bootloader needs to patch the stream id -ranges to some sane values. - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 3 +++ - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 3 +++ - 2 files changed, 6 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -808,6 +808,7 @@ - #size-cells = <2>; - device_type = "pci"; - dma-coherent; -+ iommu-map = <0 &smmu 0 1>; /* update by bootloader */ - num-viewport = <6>; - bus-range = <0x0 0xff>; - ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ -@@ -834,6 +835,7 @@ - #size-cells = <2>; - device_type = "pci"; - dma-coherent; -+ iommu-map = <0 &smmu 0 1>; /* update by bootloader */ - num-viewport = <6>; - bus-range = <0x0 0xff>; - ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ -@@ -860,6 +862,7 @@ - #size-cells = <2>; - device_type = "pci"; - dma-coherent; -+ iommu-map = <0 &smmu 0 1>; /* update by bootloader */ - num-viewport = <6>; - bus-range = <0x0 0xff>; - ranges = <0x81000000 0x0 0x00000000 0x50 0x00010000 0x0 0x00010000 /* downstream I/O */ ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -716,6 +716,7 @@ - #size-cells = <2>; - device_type = "pci"; - dma-coherent; -+ iommu-map = <0 &smmu 0 1>; /* update by bootloader */ - num-viewport = <8>; - bus-range = <0x0 0xff>; - ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ -@@ -752,6 +753,7 @@ - #size-cells = <2>; - device_type = "pci"; - dma-coherent; -+ iommu-map = <0 &smmu 0 1>; /* update by bootloader */ - num-viewport = <8>; - bus-range = <0x0 0xff>; - ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ -@@ -788,6 +790,7 @@ - #size-cells = <2>; - device_type = "pci"; - dma-coherent; -+ iommu-map = <0 &smmu 0 1>; /* update by bootloader */ - num-viewport = <8>; - bus-range = <0x0 0xff>; - ranges = <0x81000000 0x0 0x00000000 0x50 0x00010000 0x0 0x00010000 /* downstream I/O */ diff --git a/target/linux/layerscape/patches-5.4/302-dts-0017-arm64-dts-ls104x-make-dma-coherent-global-to-the-SoC.patch b/target/linux/layerscape/patches-5.4/302-dts-0017-arm64-dts-ls104x-make-dma-coherent-global-to-the-SoC.patch deleted file mode 100644 index 6430e6cf33..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0017-arm64-dts-ls104x-make-dma-coherent-global-to-the-SoC.patch +++ /dev/null @@ -1,67 +0,0 @@ -From b1e679aba75e5e137c70bc76169c34835ef0e474 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 24 Jul 2018 13:11:03 +0300 -Subject: [PATCH] arm64: dts: ls104x: make dma-coherent global to the SoC - -These SoCs are really completely dma coherent in their entirety so add -the dma-coherent property at the soc level in the device tree and drop -the instances where it's specifically added to a few select devices. - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 5 +---- - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 1 + - 2 files changed, 2 insertions(+), 4 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -219,6 +219,7 @@ - #size-cells = <2>; - ranges; - dma-ranges = <0x0 0x0 0x0 0x0 0x10000 0x00000000>; -+ dma-coherent; - - clockgen: clocking@1ee1000 { - compatible = "fsl,ls1043a-clockgen"; -@@ -772,7 +773,6 @@ - reg-names = "ahci", "sata-ecc"; - interrupts = <0 69 0x4>; - clocks = <&clockgen 4 0>; -- dma-coherent; - }; - - msi1: msi-controller1@1571000 { -@@ -807,7 +807,6 @@ - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; -- dma-coherent; - iommu-map = <0 &smmu 0 1>; /* update by bootloader */ - num-viewport = <6>; - bus-range = <0x0 0xff>; -@@ -834,7 +833,6 @@ - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; -- dma-coherent; - iommu-map = <0 &smmu 0 1>; /* update by bootloader */ - num-viewport = <6>; - bus-range = <0x0 0xff>; -@@ -861,7 +859,6 @@ - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; -- dma-coherent; - iommu-map = <0 &smmu 0 1>; /* update by bootloader */ - num-viewport = <6>; - bus-range = <0x0 0xff>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -191,6 +191,7 @@ - #size-cells = <2>; - ranges; - dma-ranges = <0x0 0x0 0x0 0x0 0x10000 0x00000000>; -+ dma-coherent; - - ddr: memory-controller@1080000 { - compatible = "fsl,qoriq-memory-controller"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0018-arm64-dts-ls104x-use-a-pseudo-bus-to-constrain-usb-d.patch b/target/linux/layerscape/patches-5.4/302-dts-0018-arm64-dts-ls104x-use-a-pseudo-bus-to-constrain-usb-d.patch deleted file mode 100644 index 81faace4c2..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0018-arm64-dts-ls104x-use-a-pseudo-bus-to-constrain-usb-d.patch +++ /dev/null @@ -1,193 +0,0 @@ -From a6a86473350c7dcbae61afa1e926941d76ca17ed Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Thu, 20 Sep 2018 13:46:54 +0300 -Subject: [PATCH] arm64: dts: ls104x: use a pseudo-bus to constrain usb dma - size - -Wrap the usb controllers in an intermediate simple-bus and use it to -constrain the dma address size of these usb controllers to the 40 bits -that they generate toward the interconnect. -This is required because the SoC uses 48 bits address sizes and this -mismatch would lead to smmu context faults because the usb generates -40-bit addresses while the smmu page tables are populated with 48-bit -wide addresses. - -Suggested-by: Robin Murphy -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 82 ++++++++++++++------------ - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 76 +++++++++++++----------- - 2 files changed, 87 insertions(+), 71 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -727,43 +727,51 @@ - <&clockgen 4 0>; - }; - -- usb0: usb3@2f00000 { -- compatible = "snps,dwc3"; -- reg = <0x0 0x2f00000 0x0 0x10000>; -- interrupts = <0 60 0x4>; -- dr_mode = "host"; -- snps,quirk-frame-length-adjustment = <0x20>; -- snps,dis_rxdet_inp3_quirk; -- usb3-lpm-capable; -- snps,dis-u1u2-when-u3-quirk; -- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -- configure-gfladj; -- }; -+ usb_aux_bus: usb_aux_bus { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ compatible = "simple-bus"; -+ ranges; -+ dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x00000000>; - -- usb1: usb3@3000000 { -- compatible = "snps,dwc3"; -- reg = <0x0 0x3000000 0x0 0x10000>; -- interrupts = <0 61 0x4>; -- dr_mode = "host"; -- snps,quirk-frame-length-adjustment = <0x20>; -- snps,dis_rxdet_inp3_quirk; -- usb3-lpm-capable; -- snps,dis-u1u2-when-u3-quirk; -- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -- configure-gfladj; -- }; -+ usb0: usb3@2f00000 { -+ compatible = "snps,dwc3"; -+ reg = <0x0 0x2f00000 0x0 0x10000>; -+ interrupts = <0 60 0x4>; -+ dr_mode = "host"; -+ snps,quirk-frame-length-adjustment = <0x20>; -+ snps,dis_rxdet_inp3_quirk; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; -+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ configure-gfladj; -+ }; -+ -+ usb1: usb3@3000000 { -+ compatible = "snps,dwc3"; -+ reg = <0x0 0x3000000 0x0 0x10000>; -+ interrupts = <0 61 0x4>; -+ dr_mode = "host"; -+ snps,quirk-frame-length-adjustment = <0x20>; -+ snps,dis_rxdet_inp3_quirk; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; -+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ configure-gfladj; -+ }; - -- usb2: usb3@3100000 { -- compatible = "snps,dwc3"; -- reg = <0x0 0x3100000 0x0 0x10000>; -- interrupts = <0 63 0x4>; -- dr_mode = "host"; -- snps,quirk-frame-length-adjustment = <0x20>; -- snps,dis_rxdet_inp3_quirk; -- usb3-lpm-capable; -- snps,dis-u1u2-when-u3-quirk; -- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -- configure-gfladj; -+ usb2: usb3@3100000 { -+ compatible = "snps,dwc3"; -+ reg = <0x0 0x3100000 0x0 0x10000>; -+ interrupts = <0 63 0x4>; -+ dr_mode = "host"; -+ snps,quirk-frame-length-adjustment = <0x20>; -+ snps,dis_rxdet_inp3_quirk; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; -+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ configure-gfladj; -+ }; - }; - - sata: sata@3200000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -625,40 +625,48 @@ - <&clockgen 4 1>; - }; - -- usb0: usb@2f00000 { -- compatible = "snps,dwc3"; -- reg = <0x0 0x2f00000 0x0 0x10000>; -- interrupts = ; -- dr_mode = "host"; -- snps,quirk-frame-length-adjustment = <0x20>; -- snps,dis_rxdet_inp3_quirk; -- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -- usb3-lpm-capable; -- snps,dis-u1u2-when-u3-quirk; -- }; -+ usb_aux_bus: usb_aux_bus { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ compatible = "simple-bus"; -+ ranges; -+ dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x00000000>; - -- usb1: usb@3000000 { -- compatible = "snps,dwc3"; -- reg = <0x0 0x3000000 0x0 0x10000>; -- interrupts = ; -- dr_mode = "host"; -- snps,quirk-frame-length-adjustment = <0x20>; -- snps,dis_rxdet_inp3_quirk; -- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -- usb3-lpm-capable; -- snps,dis-u1u2-when-u3-quirk; -- }; -+ usb0: usb@2f00000 { -+ compatible = "snps,dwc3"; -+ reg = <0x0 0x2f00000 0x0 0x10000>; -+ interrupts = ; -+ dr_mode = "host"; -+ snps,quirk-frame-length-adjustment = <0x20>; -+ snps,dis_rxdet_inp3_quirk; -+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; -+ }; -+ -+ usb1: usb@3000000 { -+ compatible = "snps,dwc3"; -+ reg = <0x0 0x3000000 0x0 0x10000>; -+ interrupts = ; -+ dr_mode = "host"; -+ snps,quirk-frame-length-adjustment = <0x20>; -+ snps,dis_rxdet_inp3_quirk; -+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; -+ }; - -- usb2: usb@3100000 { -- compatible = "snps,dwc3"; -- reg = <0x0 0x3100000 0x0 0x10000>; -- interrupts = ; -- dr_mode = "host"; -- snps,quirk-frame-length-adjustment = <0x20>; -- snps,dis_rxdet_inp3_quirk; -- snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -- usb3-lpm-capable; -- snps,dis-u1u2-when-u3-quirk; -+ usb2: usb@3100000 { -+ compatible = "snps,dwc3"; -+ reg = <0x0 0x3100000 0x0 0x10000>; -+ interrupts = ; -+ dr_mode = "host"; -+ snps,quirk-frame-length-adjustment = <0x20>; -+ snps,dis_rxdet_inp3_quirk; -+ snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; -+ }; - }; - - sata: sata@3200000 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0019-sdk-dts-ls104x-drop-smmu-from-the-sdk-device-trees.patch b/target/linux/layerscape/patches-5.4/302-dts-0019-sdk-dts-ls104x-drop-smmu-from-the-sdk-device-trees.patch deleted file mode 100644 index bdf69a6523..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0019-sdk-dts-ls104x-drop-smmu-from-the-sdk-device-trees.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 9c0090519c422600596a9d7c1e6e33a5268dfce4 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Thu, 2 Aug 2018 17:54:28 +0300 -Subject: [PATCH] sdk: dts: ls104x: drop smmu from the sdk device trees - -SMMU is not supported for the SDK version of the dpaa ethernet -drivers so remove the SMMU node from the device tree. - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts | 14 ++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts | 14 ++++++++++++++ - 2 files changed, 28 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts -@@ -64,6 +64,20 @@ - &soc { - #include "qoriq-dpaa-eth.dtsi" - #include "qoriq-fman3-0-6oh.dtsi" -+ -+pcie@3400000 { -+ /delete-property/ iommu-map; -+}; -+ -+pcie@3500000 { -+ /delete-property/ iommu-map; -+}; -+ -+pcie@3600000 { -+ /delete-property/ iommu-map; -+}; -+ -+/delete-node/ iommu@9000000; - }; - - &fman0 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts -@@ -64,6 +64,20 @@ - &soc { - #include "qoriq-dpaa-eth.dtsi" - #include "qoriq-fman3-0-6oh.dtsi" -+ -+pcie@3400000 { -+ /delete-property/ iommu-map; -+}; -+ -+pcie@3500000 { -+ /delete-property/ iommu-map; -+}; -+ -+pcie@3600000 { -+ /delete-property/ iommu-map; -+}; -+ -+/delete-node/ iommu@9000000; - }; - - &fsldpaa { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0020-arm64-dts-lx2160a-add-MDIO-device-tree-nodes.patch b/target/linux/layerscape/patches-5.4/302-dts-0020-arm64-dts-lx2160a-add-MDIO-device-tree-nodes.patch deleted file mode 100644 index 0232c40ee3..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0020-arm64-dts-lx2160a-add-MDIO-device-tree-nodes.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 5fb032ca86c078429ecdde3cbd9040702bb86954 Mon Sep 17 00:00:00 2001 -From: Vicentiu Galanopulo -Date: Fri, 20 Apr 2018 11:00:09 +0300 -Subject: [PATCH] arm64: dts: lx2160a: add MDIO device-tree nodes - -Signed-off-by: Vicentiu Galanopulo ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -478,6 +478,28 @@ - little-endian; - }; - -+ /* TODO: WRIOP (CCSR?) */ -+ emdio1: mdio@0x8B96000 { /* WRIOP0: 0x8B8_0000, E-MDIO1: 0x1_6000 */ -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8B96000 0x0 0x1000>; -+ device_type = "mdio"; /* TODO: is this necessary? */ -+ little-endian; /* force the driver in LE mode */ -+ -+ /* Not necessary on the QDS, but needed on the RDB */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ emdio2: mdio@0x8B97000 { /* WRIOP0: 0x8B8_0000, E-MDIO2: 0x1_7000 */ -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8B97000 0x0 0x1000>; -+ device_type = "mdio"; /* TODO: is this necessary? */ -+ little-endian; /* force the driver in LE mode */ -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ - i2c0: i2c@2000000 { - compatible = "fsl,vf610-i2c"; - #address-cells = <1>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0021-arm64-dts-lx2160a-rdb-Add-RGMII-PHY-nodes-for-dpmac-.patch b/target/linux/layerscape/patches-5.4/302-dts-0021-arm64-dts-lx2160a-rdb-Add-RGMII-PHY-nodes-for-dpmac-.patch deleted file mode 100644 index 85fa5b83df..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0021-arm64-dts-lx2160a-rdb-Add-RGMII-PHY-nodes-for-dpmac-.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 08726d24b8552e4a986631090e063d38cd2d82cf Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Tue, 10 Jul 2018 13:56:56 +0300 -Subject: [PATCH] arm64: dts: lx2160a-rdb: Add RGMII PHY nodes for dpmac 17 and - 18 - -* Both are AR8035 chips - -Signed-off-by: Vladimir Oltean ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts | 25 +++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -@@ -159,3 +159,28 @@ - &usb1 { - status = "okay"; - }; -+ -+&emdio1 { -+ rgmii_phy1: ethernet-phy@1 { -+ /* AR8035 PHY - "compatible" property not strictly needed */ -+ compatible = "ethernet-phy-id004d.d072"; -+ reg = <0x1>; -+ /* Poll mode - no "interrupts" property defined */ -+ }; -+ rgmii_phy2: ethernet-phy@2 { -+ /* AR8035 PHY - "compatible" property not strictly needed */ -+ compatible = "ethernet-phy-id004d.d072"; -+ reg = <0x2>; -+ /* Poll mode - no "interrupts" property defined */ -+ }; -+}; -+ -+&dpmac17 { -+ phy-handle = <&rgmii_phy1>; -+ phy-connection-type = "rgmii-id"; -+}; -+ -+&dpmac18 { -+ phy-handle = <&rgmii_phy2>; -+ phy-connection-type = "rgmii-id"; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0022-arm64-dts-lx2160a-correct-scl-gpios-property.patch b/target/linux/layerscape/patches-5.4/302-dts-0022-arm64-dts-lx2160a-correct-scl-gpios-property.patch deleted file mode 100644 index 991c5f5750..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0022-arm64-dts-lx2160a-correct-scl-gpios-property.patch +++ /dev/null @@ -1,30 +0,0 @@ -From a99acc11751ea640c7687155e964612b232bc492 Mon Sep 17 00:00:00 2001 -From: Zhang Ying-22455 -Date: Mon, 29 Oct 2018 10:37:03 +0800 -Subject: [PATCH] arm64: dts: lx2160a: correct scl-gpios property - -Signed-off-by: Zhang Ying-22455 ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -508,7 +508,7 @@ - interrupts = ; - clock-names = "i2c"; - clocks = <&clockgen 4 15>; -- scl-gpio = <&gpio2 15 GPIO_ACTIVE_HIGH>; -+ scl-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>; - status = "disabled"; - }; - -@@ -553,7 +553,7 @@ - interrupts = ; - clock-names = "i2c"; - clocks = <&clockgen 4 15>; -- scl-gpio = <&gpio2 16 GPIO_ACTIVE_HIGH>; -+ scl-gpios = <&gpio2 16 GPIO_ACTIVE_HIGH>; - status = "disabled"; - }; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0023-arm64-dts-lx2160a-add-dspi-controller-DT-nodes.patch b/target/linux/layerscape/patches-5.4/302-dts-0023-arm64-dts-lx2160a-add-dspi-controller-DT-nodes.patch deleted file mode 100644 index 74fe6059dc..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0023-arm64-dts-lx2160a-add-dspi-controller-DT-nodes.patch +++ /dev/null @@ -1,62 +0,0 @@ -From df8cea437a14a4a412a32058ca49a2b30b48cc71 Mon Sep 17 00:00:00 2001 -From: Chuanhua Han -Date: Fri, 26 Oct 2018 12:08:55 +0800 -Subject: [PATCH] arm64: dts: lx2160a: add dspi controller DT nodes - -Add the dspi support on lx2160 - -Signed-off-by: Chuanhua Han -Signed-off-by: Bao Xiaowei -Signed-off-by: Hou Zhiqiang ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 39 ++++++++++++++++++++++++++ - 1 file changed, 39 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -603,6 +603,45 @@ - status = "disabled"; - }; - -+ dspi0: spi@2100000 { -+ compatible = "fsl,lx2160a-dspi", "fsl,ls2085a-dspi"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0 0x2100000 0x0 0x10000>; -+ interrupts = ; -+ clocks = <&clockgen 4 7>; -+ clock-names = "dspi"; -+ spi-num-chipselects = <5>; -+ bus-num = <0>; -+ status = "disabled"; -+ }; -+ -+ dspi1: spi@2110000 { -+ compatible = "fsl,lx2160a-dspi", "fsl,ls2085a-dspi"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0 0x2110000 0x0 0x10000>; -+ interrupts = ; -+ clocks = <&clockgen 4 7>; -+ clock-names = "dspi"; -+ spi-num-chipselects = <5>; -+ bus-num = <1>; -+ status = "disabled"; -+ }; -+ -+ dspi2: spi@2120000 { -+ compatible = "fsl,lx2160a-dspi", "fsl,ls2085a-dspi"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0 0x2120000 0x0 0x10000>; -+ interrupts = ; -+ clocks = <&clockgen 4 7>; -+ clock-names = "dspi"; -+ spi-num-chipselects = <5>; -+ bus-num = <2>; -+ status = "disabled"; -+ }; -+ - esdhc0: esdhc@2140000 { - compatible = "fsl,esdhc"; - reg = <0x0 0x2140000 0x0 0x10000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0024-arm64-dts-lx2160a-add-DT-node-for-all-DSPI-controlle.patch b/target/linux/layerscape/patches-5.4/302-dts-0024-arm64-dts-lx2160a-add-DT-node-for-all-DSPI-controlle.patch deleted file mode 100644 index bb931fb871..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0024-arm64-dts-lx2160a-add-DT-node-for-all-DSPI-controlle.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 3f304579d634bcbef18fec939e407c8e789637c8 Mon Sep 17 00:00:00 2001 -From: Chuanhua Han -Date: Fri, 26 Oct 2018 12:11:25 +0800 -Subject: [PATCH] arm64: dts: lx2160a: add DT node for all DSPI controller - -Add device tree node for first flash (CS0) connected -to all dspi controller. - -Signed-off-by: Chuanhua Han -Signed-off-by: Wasim Khan ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts | 36 +++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -@@ -35,6 +35,42 @@ - status = "okay"; - }; - -+&dspi0 { -+ status = "okay"; -+ -+ dflash0: flash@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <1000000>; -+ }; -+}; -+ -+&dspi1 { -+ status = "okay"; -+ -+ dflash1: flash@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <1000000>; -+ }; -+}; -+ -+&dspi2 { -+ status = "okay"; -+ -+ dflash2: flash@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "jedec,spi-nor"; -+ reg = <0>; -+ spi-max-frequency = <1000000>; -+ }; -+}; -+ - &esdhc0 { - status = "okay"; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0025-arm64-dts-nxp-ls208xa-add-more-thermal-zone-support.patch b/target/linux/layerscape/patches-5.4/302-dts-0025-arm64-dts-nxp-ls208xa-add-more-thermal-zone-support.patch deleted file mode 100644 index 5434e1f913..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0025-arm64-dts-nxp-ls208xa-add-more-thermal-zone-support.patch +++ /dev/null @@ -1,745 +0,0 @@ -From d05cf625f27335320a2ad883b7f7c4cd638dca99 Mon Sep 17 00:00:00 2001 -From: Yuantian Tang -Date: Mon, 5 Nov 2018 17:25:32 +0800 -Subject: [PATCH] arm64: dts: nxp: ls208xa: add more thermal zone support - -Ls208xa has several thermal sensors. Add all the sensor id to dts -to enable them. - -To make the dts cleaner, re-organize the nodes to split out the -common part so that it can be shared with other SoCs. - -Signed-off-by: Yuantian Tang ---- - arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 8 +- - arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi | 8 +- - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 70 ++++--- - arch/arm64/boot/dts/freescale/fsl-tmu-map1.dtsi | 99 ++++++++++ - arch/arm64/boot/dts/freescale/fsl-tmu-map2.dtsi | 99 ++++++++++ - arch/arm64/boot/dts/freescale/fsl-tmu-map3.dtsi | 99 ++++++++++ - arch/arm64/boot/dts/freescale/fsl-tmu.dtsi | 251 ++++++++++++++++++++++++ - 7 files changed, 590 insertions(+), 44 deletions(-) - create mode 100644 arch/arm64/boot/dts/freescale/fsl-tmu-map1.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-tmu-map2.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-tmu-map3.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-tmu.dtsi - ---- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi -@@ -12,7 +12,7 @@ - #include "fsl-ls208xa.dtsi" - - &cpu { -- cpu0: cpu@0 { -+ cooling_map0: cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a57"; - reg = <0x0>; -@@ -32,7 +32,7 @@ - #cooling-cells = <2>; - }; - -- cpu2: cpu@100 { -+ cooling_map1: cpu2: cpu@100 { - device_type = "cpu"; - compatible = "arm,cortex-a57"; - reg = <0x100>; -@@ -52,7 +52,7 @@ - #cooling-cells = <2>; - }; - -- cpu4: cpu@200 { -+ cooling_map2: cpu4: cpu@200 { - device_type = "cpu"; - compatible = "arm,cortex-a57"; - reg = <0x200>; -@@ -72,7 +72,7 @@ - #cooling-cells = <2>; - }; - -- cpu6: cpu@300 { -+ cooling_map3: cpu6: cpu@300 { - device_type = "cpu"; - compatible = "arm,cortex-a57"; - reg = <0x300>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a.dtsi -@@ -12,7 +12,7 @@ - #include "fsl-ls208xa.dtsi" - - &cpu { -- cpu0: cpu@0 { -+ cooling_map0: cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0>; -@@ -32,7 +32,7 @@ - #cooling-cells = <2>; - }; - -- cpu2: cpu@100 { -+ cooling_map1: cpu2: cpu@100 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x100>; -@@ -52,7 +52,7 @@ - #cooling-cells = <2>; - }; - -- cpu4: cpu@200 { -+ cooling_map2: cpu4: cpu@200 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x200>; -@@ -72,7 +72,7 @@ - #cooling-cells = <2>; - }; - -- cpu6: cpu@300 { -+ cooling_map3: cpu6: cpu@300 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x300>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -77,42 +77,7 @@ - mask = <0x2>; - }; - -- thermal-zones { -- cpu_thermal: cpu-thermal { -- polling-delay-passive = <1000>; -- polling-delay = <5000>; -- -- thermal-sensors = <&tmu 4>; -- -- trips { -- cpu_alert: cpu-alert { -- temperature = <75000>; -- hysteresis = <2000>; -- type = "passive"; -- }; -- cpu_crit: cpu-crit { -- temperature = <85000>; -- hysteresis = <2000>; -- type = "critical"; -- }; -- }; -- -- cooling-maps { -- map0 { -- trip = <&cpu_alert>; -- cooling-device = -- <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -- }; -- }; -- }; -- }; -+ #include "fsl-tmu.dtsi" - - timer: timer { - compatible = "arm,armv8-timer"; -@@ -906,3 +871,36 @@ - }; - }; - }; -+ -+#include "fsl-tmu-map1.dtsi" -+#include "fsl-tmu-map2.dtsi" -+#include "fsl-tmu-map3.dtsi" -+&thermal_zones { -+ thermal-zone1 { -+ status = "okay"; -+ }; -+ -+ thermal-zone2{ -+ status = "okay"; -+ }; -+ -+ thermal-zone3{ -+ status = "okay"; -+ }; -+ -+ thermal-zone4{ -+ status = "okay"; -+ }; -+ -+ thermal-zone5{ -+ status = "okay"; -+ }; -+ -+ thermal-zone6{ -+ status = "okay"; -+ }; -+ -+ thermal-zone7 { -+ status = "okay"; -+ }; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-tmu-map1.dtsi -@@ -0,0 +1,99 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for Thermal Monitor Unit. -+ * -+ * Copyright 2018 NXP -+ * -+ * Tang Yuantian -+ * -+ */ -+ -+&thermal_zones { -+ thermal-zone0 { -+ cooling-maps { -+ map1 { -+ trip = <&alert0>; -+ cooling-device = -+ <&cooling_map1 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone1 { -+ cooling-maps { -+ map1 { -+ trip = <&alert1>; -+ cooling-device = -+ <&cooling_map1 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone2 { -+ cooling-maps { -+ map1 { -+ trip = <&alert2>; -+ cooling-device = -+ <&cooling_map1 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone3 { -+ cooling-maps { -+ map1 { -+ trip = <&alert3>; -+ cooling-device = -+ <&cooling_map1 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone4 { -+ cooling-maps { -+ map1 { -+ trip = <&alert4>; -+ cooling-device = -+ <&cooling_map1 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone5 { -+ cooling-maps { -+ map1 { -+ trip = <&alert5>; -+ cooling-device = -+ <&cooling_map1 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone6 { -+ cooling-maps { -+ map1 { -+ trip = <&alert6>; -+ cooling-device = -+ <&cooling_map1 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone7 { -+ cooling-maps { -+ map1 { -+ trip = <&alert7>; -+ cooling-device = -+ <&cooling_map1 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-tmu-map2.dtsi -@@ -0,0 +1,99 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for Thermal Monitor Unit. -+ * -+ * Copyright 2018 NXP -+ * -+ * Tang Yuantian -+ * -+ */ -+ -+&thermal_zones { -+ thermal-zone0 { -+ cooling-maps { -+ map2 { -+ trip = <&alert0>; -+ cooling-device = -+ <&cooling_map2 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone1 { -+ cooling-maps { -+ map2 { -+ trip = <&alert1>; -+ cooling-device = -+ <&cooling_map2 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone2 { -+ cooling-maps { -+ map2 { -+ trip = <&alert2>; -+ cooling-device = -+ <&cooling_map2 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone3 { -+ cooling-maps { -+ map2 { -+ trip = <&alert3>; -+ cooling-device = -+ <&cooling_map2 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone4 { -+ cooling-maps { -+ map2 { -+ trip = <&alert4>; -+ cooling-device = -+ <&cooling_map2 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone5 { -+ cooling-maps { -+ map2 { -+ trip = <&alert5>; -+ cooling-device = -+ <&cooling_map2 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone6 { -+ cooling-maps { -+ map2 { -+ trip = <&alert6>; -+ cooling-device = -+ <&cooling_map2 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone7 { -+ cooling-maps { -+ map2 { -+ trip = <&alert7>; -+ cooling-device = -+ <&cooling_map2 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-tmu-map3.dtsi -@@ -0,0 +1,99 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for Thermal Monitor Unit. -+ * -+ * Copyright 2018 NXP -+ * -+ * Tang Yuantian -+ * -+ */ -+ -+&thermal_zones { -+ thermal-zone0 { -+ cooling-maps { -+ map3 { -+ trip = <&alert0>; -+ cooling-device = -+ <&cooling_map3 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone1 { -+ cooling-maps { -+ map3 { -+ trip = <&alert1>; -+ cooling-device = -+ <&cooling_map3 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone2 { -+ cooling-maps { -+ map3 { -+ trip = <&alert2>; -+ cooling-device = -+ <&cooling_map3 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone3 { -+ cooling-maps { -+ map3 { -+ trip = <&alert3>; -+ cooling-device = -+ <&cooling_map3 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone4 { -+ cooling-maps { -+ map3 { -+ trip = <&alert4>; -+ cooling-device = -+ <&cooling_map3 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone5 { -+ cooling-maps { -+ map3 { -+ trip = <&alert5>; -+ cooling-device = -+ <&cooling_map3 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone6 { -+ cooling-maps { -+ map3 { -+ trip = <&alert6>; -+ cooling-device = -+ <&cooling_map3 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone7 { -+ cooling-maps { -+ map3 { -+ trip = <&alert7>; -+ cooling-device = -+ <&cooling_map3 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-tmu.dtsi -@@ -0,0 +1,251 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for Thermal Monitor Unit. -+ * -+ * Copyright 2018 NXP -+ * -+ * Tang Yuantian -+ * -+ */ -+ -+thermal_zones: thermal-zones { -+ thermal_zone0: thermal-zone0 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 0>; -+ status = "disabled"; -+ -+ trips { -+ alert0: alert0 { -+ temperature = <75000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ crit0: crit0 { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&alert0>; -+ cooling-device = -+ <&cooling_map0 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone1 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 1>; -+ status = "disabled"; -+ -+ trips { -+ alert1: alert1 { -+ temperature = <75000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ crit1: crit1 { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&alert1>; -+ cooling-device = -+ <&cooling_map0 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone2 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 2>; -+ status = "disabled"; -+ -+ trips { -+ alert2: alert2 { -+ temperature = <75000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ crit2: crit2 { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&alert2>; -+ cooling-device = -+ <&cooling_map0 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone3 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 3>; -+ status = "disabled"; -+ -+ trips { -+ alert3: alert3 { -+ temperature = <75000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ crit3: crit3 { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&alert3>; -+ cooling-device = -+ <&cooling_map0 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone4 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 4>; -+ status = "disabled"; -+ -+ trips { -+ alert4: alert4 { -+ temperature = <75000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ crit4: crit4 { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&alert4>; -+ cooling-device = -+ <&cooling_map0 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone5 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 5>; -+ status = "disabled"; -+ -+ trips { -+ alert5: alert5 { -+ temperature = <75000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ crit5: crit5 { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&alert5>; -+ cooling-device = -+ <&cooling_map0 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone6 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 6>; -+ status = "disabled"; -+ -+ trips { -+ alert6: alert6 { -+ temperature = <75000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ crit6: crit6 { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&alert6>; -+ cooling-device = -+ <&cooling_map0 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ -+ thermal-zone7 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 7>; -+ status = "disabled"; -+ -+ trips { -+ alert7: alert7 { -+ temperature = <75000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ crit7: crit7 { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&alert7>; -+ cooling-device = -+ <&cooling_map0 THERMAL_NO_LIMIT -+ THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0026-arm64-dts-nxp-add-more-thermal-zone-support.patch b/target/linux/layerscape/patches-5.4/302-dts-0026-arm64-dts-nxp-add-more-thermal-zone-support.patch deleted file mode 100644 index c9a9b5d271..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0026-arm64-dts-nxp-add-more-thermal-zone-support.patch +++ /dev/null @@ -1,314 +0,0 @@ -From 314a3a062e5e8fe76b3c43a8731ffe4bd58bc1be Mon Sep 17 00:00:00 2001 -From: Yuantian Tang -Date: Mon, 5 Nov 2018 17:40:20 +0800 -Subject: [PATCH] arm64: dts: nxp: add more thermal zone support - -To enable all the supported thermal sensors, add sensor id information -to thermal zone node. -Dts for ls1012a, ls1046a, ls1043a, ls1088a are updated. - -Signed-off-by: Yuantian Tang ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 39 ++++------------ - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 61 ++++++++++++-------------- - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 57 ++++++++++-------------- - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 53 +++++++--------------- - 4 files changed, 75 insertions(+), 135 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -28,7 +28,7 @@ - #address-cells = <1>; - #size-cells = <0>; - -- cpu0: cpu@0 { -+ cooling_map0: cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x0>; -@@ -100,36 +100,7 @@ - mask = <0x02>; - }; - -- thermal-zones { -- cpu_thermal: cpu-thermal { -- polling-delay-passive = <1000>; -- polling-delay = <5000>; -- thermal-sensors = <&tmu 0>; -- -- trips { -- cpu_alert: cpu-alert { -- temperature = <85000>; -- hysteresis = <2000>; -- type = "passive"; -- }; -- -- cpu_crit: cpu-crit { -- temperature = <95000>; -- hysteresis = <2000>; -- type = "critical"; -- }; -- }; -- -- cooling-maps { -- map0 { -- trip = <&cpu_alert>; -- cooling-device = -- <&cpu0 THERMAL_NO_LIMIT -- THERMAL_NO_LIMIT>; -- }; -- }; -- }; -- }; -+ #include "fsl-tmu.dtsi" - - soc { - compatible = "simple-bus"; -@@ -573,3 +544,9 @@ - }; - }; - }; -+ -+&thermal_zones { -+ thermal-zone0 { -+ status = "okay"; -+ }; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -39,7 +39,7 @@ - * - * Currently supported enable-method is psci v0.2 - */ -- cpu0: cpu@0 { -+ cooling_map0: cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x0>; -@@ -148,38 +148,7 @@ - mask = <0x02>; - }; - -- thermal-zones { -- cpu_thermal: cpu-thermal { -- polling-delay-passive = <1000>; -- polling-delay = <5000>; -- -- thermal-sensors = <&tmu 3>; -- -- trips { -- cpu_alert: cpu-alert { -- temperature = <85000>; -- hysteresis = <2000>; -- type = "passive"; -- }; -- cpu_crit: cpu-crit { -- temperature = <95000>; -- hysteresis = <2000>; -- type = "critical"; -- }; -- }; -- -- cooling-maps { -- map0 { -- trip = <&cpu_alert>; -- cooling-device = -- <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -- }; -- }; -- }; -- }; -+ #include "fsl-tmu.dtsi" - - timer { - compatible = "arm,armv8-timer"; -@@ -916,3 +885,29 @@ - - #include "qoriq-qman-portals.dtsi" - #include "qoriq-bman-portals.dtsi" -+ -+&thermal_zones { -+ thermal-zone0 { -+ status = "okay"; -+ }; -+ -+ thermal-zone1 { -+ status = "okay"; -+ }; -+ -+ thermal-zone2 { -+ status = "okay"; -+ }; -+ -+ thermal-zone3 { -+ status = "okay"; -+ }; -+ -+ thermal-zone4 { -+ status = "okay"; -+ }; -+ -+ thermal-zone5 { -+ status = "okay"; -+ }; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -34,7 +34,7 @@ - #address-cells = <1>; - #size-cells = <0>; - -- cpu0: cpu@0 { -+ cooling_map0: cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0>; -@@ -116,38 +116,7 @@ - mask = <0x02>; - }; - -- thermal-zones { -- cpu_thermal: cpu-thermal { -- polling-delay-passive = <1000>; -- polling-delay = <5000>; -- thermal-sensors = <&tmu 3>; -- -- trips { -- cpu_alert: cpu-alert { -- temperature = <85000>; -- hysteresis = <2000>; -- type = "passive"; -- }; -- -- cpu_crit: cpu-crit { -- temperature = <95000>; -- hysteresis = <2000>; -- type = "critical"; -- }; -- }; -- -- cooling-maps { -- map0 { -- trip = <&cpu_alert>; -- cooling-device = -- <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -- }; -- }; -- }; -- }; -+ #include "fsl-tmu.dtsi" - - timer { - compatible = "arm,armv8-timer"; -@@ -883,3 +852,25 @@ - - #include "qoriq-qman-portals.dtsi" - #include "qoriq-bman-portals.dtsi" -+ -+&thermal_zones { -+ thermal-zone0 { -+ status = "okay"; -+ }; -+ -+ thermal-zone1 { -+ status = "okay"; -+ }; -+ -+ thermal-zone2 { -+ status = "okay"; -+ }; -+ -+ thermal-zone3 { -+ status = "okay"; -+ }; -+ -+ thermal-zone4 { -+ status = "okay"; -+ }; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -25,7 +25,7 @@ - #size-cells = <0>; - - /* We have 2 clusters having 4 Cortex-A53 cores each */ -- cpu0: cpu@0 { -+ cooling_map0: cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x0>; -@@ -61,7 +61,7 @@ - #cooling-cells = <2>; - }; - -- cpu4: cpu@100 { -+ cooling_map1: cpu4: cpu@100 { - device_type = "cpu"; - compatible = "arm,cortex-a53"; - reg = <0x100>; -@@ -128,42 +128,7 @@ - }; - }; - -- thermal-zones { -- cpu_thermal: cpu-thermal { -- polling-delay-passive = <1000>; -- polling-delay = <5000>; -- thermal-sensors = <&tmu 0>; -- -- trips { -- cpu_alert: cpu-alert { -- temperature = <85000>; -- hysteresis = <2000>; -- type = "passive"; -- }; -- -- cpu_crit: cpu-crit { -- temperature = <95000>; -- hysteresis = <2000>; -- type = "critical"; -- }; -- }; -- -- cooling-maps { -- map0 { -- trip = <&cpu_alert>; -- cooling-device = -- <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -- <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -- }; -- }; -- }; -- }; -+ #include "fsl-tmu.dtsi" - - timer { - compatible = "arm,armv8-timer"; -@@ -879,3 +844,15 @@ - }; - }; - }; -+ -+#include "fsl-tmu-map1.dtsi" -+ -+&thermal_zones { -+ thermal-zone0 { -+ status = "okay"; -+ }; -+ -+ thermal-zone1 { -+ status = "okay"; -+ }; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0027-arm64-dts-lx2160a-rdb-Add-Inphi-PHY-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0027-arm64-dts-lx2160a-rdb-Add-Inphi-PHY-node.patch deleted file mode 100644 index 90f0e3c0d7..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0027-arm64-dts-lx2160a-rdb-Add-Inphi-PHY-node.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 7ff4d2213c5b21008bebf43ae5a60b4275f91c55 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Mon, 29 Oct 2018 18:41:07 +0200 -Subject: [PATCH] arm64: dts: lx2160a-rdb: Add Inphi PHY node - -DPMAC5 and DPMAC6 are connected to 25G Inphi PHY - -Signed-off-by: Vicentiu Galanopulo -Signed-off-by: Florin Chiculita -Signed-off-by: Ioana Radulescu ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -@@ -175,6 +175,23 @@ - }; - }; - -+&emdio2 { -+ inphi_phy: emdio2_phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x0>; -+ interrupts = <0 9 IRQ_TYPE_EDGE_FALLING>, -+ <0 10 IRQ_TYPE_EDGE_FALLING>; -+ }; -+}; -+ -+&dpmac5 { -+ phy-handle = <&inphi_phy>; -+}; -+ -+&dpmac6 { -+ phy-handle = <&inphi_phy>; -+}; -+ - &dpmac17 { - phy-handle = <&rgmii_phy1>; - phy-connection-type = "rgmii-id"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0028-arm64-dts-lx2160a-rdb-Add-Aquantia-PHY-nodes.patch b/target/linux/layerscape/patches-5.4/302-dts-0028-arm64-dts-lx2160a-rdb-Add-Aquantia-PHY-nodes.patch deleted file mode 100644 index f2d4f49995..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0028-arm64-dts-lx2160a-rdb-Add-Aquantia-PHY-nodes.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 917e2edbf55e5bc6c98802a610d8b7c05c4e9c78 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Mon, 29 Oct 2018 18:54:05 +0200 -Subject: [PATCH] arm64: dts: lx2160a-rdb: Add Aquantia PHY nodes - -DPMAC3 and DPMAC4 are connected to 10G Aquantia PHYs - -Signed-off-by: Catalin Neacsu -Signed-off-by: Ioana Radulescu ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -@@ -173,6 +173,18 @@ - reg = <0x2>; - /* Poll mode - no "interrupts" property defined */ - }; -+ aquantia_phy1: ethernet-phy@4 { -+ /* AQR107 PHY - "compatible" property not strictly needed */ -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x4>; -+ /* Poll mode - no "interrupts" property defined */ -+ }; -+ aquantia_phy2: ethernet-phy@5 { -+ /* AQR107 PHY - "compatible" property not strictly needed */ -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x5>; -+ /* Poll mode - no "interrupts" property defined */ -+ }; - }; - - &emdio2 { -@@ -184,6 +196,16 @@ - }; - }; - -+&dpmac3 { -+ phy-handle = <&aquantia_phy1>; -+ phy-connection-type = "xgmii"; -+}; -+ -+&dpmac4 { -+ phy-handle = <&aquantia_phy2>; -+ phy-connection-type = "xgmii"; -+}; -+ - &dpmac5 { - phy-handle = <&inphi_phy>; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0029-arm64-dts-lx2160-Add-all-pcs-mdio-definitions-accord.patch b/target/linux/layerscape/patches-5.4/302-dts-0029-arm64-dts-lx2160-Add-all-pcs-mdio-definitions-accord.patch deleted file mode 100644 index de1997554e..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0029-arm64-dts-lx2160-Add-all-pcs-mdio-definitions-accord.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 39c8c9b6e4db9694935fe4a856ea66ff36ace7d0 Mon Sep 17 00:00:00 2001 -From: Florinel Iordache -Date: Tue, 30 Oct 2018 09:42:39 +0200 -Subject: [PATCH] arm64: dts: lx2160: Add all pcs mdio definitions according to - RM - -This change is required in preparation for adding 40GBase-KR support in DTS for LX2160 - -Signed-off-by: Florinel Iordache ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 85 ++++++++++++++++++++++++++ - 1 file changed, 85 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -500,6 +500,91 @@ - #size-cells = <0>; - }; - -+ pcs_mdio1: mdio@0x8c07000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c07000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio2: mdio@0x8c0b000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c0b000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio3: mdio@0x8c0f000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c0f000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio4: mdio@0x8c13000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c13000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio5: mdio@0x8c17000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c17000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio6: mdio@0x8c1b000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c1b000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio7: mdio@0x8c1f000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c1f000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ pcs_mdio8: mdio@0x8c23000 { -+ compatible = "fsl,fman-memac-mdio"; -+ reg = <0x0 0x8c23000 0x0 0x1000>; -+ device_type = "mdio"; -+ little-endian; -+ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ serdes1: serdes@1ea0000 { -+ reg = <0x0 0x1ea0000 0 0x00002000>; -+ compatible = "fsl,serdes-28g"; -+ }; -+ - i2c0: i2c@2000000 { - compatible = "fsl,vf610-i2c"; - #address-cells = <1>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0030-arm64-dts-lx2160-PCS-PHY-definitions-for-10GBase-KR-.patch b/target/linux/layerscape/patches-5.4/302-dts-0030-arm64-dts-lx2160-PCS-PHY-definitions-for-10GBase-KR-.patch deleted file mode 100644 index 22b2b64d79..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0030-arm64-dts-lx2160-PCS-PHY-definitions-for-10GBase-KR-.patch +++ /dev/null @@ -1,57 +0,0 @@ -From c1619d9de2da093a585426e9cef353ca1789236d Mon Sep 17 00:00:00 2001 -From: Florinel Iordache -Date: Mon, 5 Nov 2018 17:02:19 +0200 -Subject: [PATCH] arm64: dts: lx2160: PCS PHY definitions for 10GBase-KR and - 40GBase-KR backplane modes - -Signed-off-by: Florinel Iordache ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts | 40 +++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -@@ -162,3 +162,43 @@ - &usb1 { - status = "okay"; - }; -+ -+&pcs_mdio1 { -+ pcs_phy1: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ backplane-mode = "40gbase-kr"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0xF00 0xE00 0xD00 0xC00>; /* lanes H, G, F, E */ -+ }; -+}; -+ -+&pcs_mdio2 { -+ pcs_phy2: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ backplane-mode = "40gbase-kr"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0xB00 0xA00 0x900 0x800>; /* lanes D, C, B, A */ -+ }; -+}; -+ -+&pcs_mdio3 { -+ pcs_phy3: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ backplane-mode = "10gbase-kr"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0xF00 0x100>; /* lane H */ -+ }; -+}; -+ -+&pcs_mdio4 { -+ pcs_phy4: ethernet-phy@0 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ backplane-mode = "10gbase-kr"; -+ reg = <0x0>; -+ fsl,lane-handle = <&serdes1>; -+ fsl,lane-reg = <0xE00 0x100>; /* lane G */ -+ }; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0031-arm64-dts-lx2160-DPMAC-connections-to-backplane-PHYs.patch b/target/linux/layerscape/patches-5.4/302-dts-0031-arm64-dts-lx2160-DPMAC-connections-to-backplane-PHYs.patch deleted file mode 100644 index d054745455..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0031-arm64-dts-lx2160-DPMAC-connections-to-backplane-PHYs.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 01af235657e4d8f5f87b5e06bcf42baf53e1ff8d Mon Sep 17 00:00:00 2001 -From: Florinel Iordache -Date: Mon, 5 Nov 2018 17:03:04 +0200 -Subject: [PATCH] arm64: dts: lx2160: DPMAC connections to backplane PHYs - example - -This is an example of device tree nodes required to enable 10GBase-KR and 40GBase-KR on LX2160 - -Signed-off-by: Florinel Iordache ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -@@ -202,3 +202,23 @@ - fsl,lane-reg = <0xE00 0x100>; /* lane G */ - }; - }; -+ -+/* Update DPMAC connections to 40G backplane PHYs -+ * &dpmac1 { -+ * phy-handle = <&pcs_phy1>; -+ * }; -+ * -+ * &dpmac2 { -+ * phy-handle = <&pcs_phy2>; -+ * }; -+ */ -+ -+/* Update DPMAC connections to 10G backplane PHYs -+ * &dpmac3 { -+ * phy-handle = <&pcs_phy3>; -+ * }; -+ * -+ * &dpmac4 { -+ * phy-handle = <&pcs_phy4>; -+ * }; -+ */ diff --git a/target/linux/layerscape/patches-5.4/302-dts-0032-arm64-dts-Added-endianness-information-to-dts-serdes.patch b/target/linux/layerscape/patches-5.4/302-dts-0032-arm64-dts-Added-endianness-information-to-dts-serdes.patch deleted file mode 100644 index b19431d567..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0032-arm64-dts-Added-endianness-information-to-dts-serdes.patch +++ /dev/null @@ -1,53 +0,0 @@ -From d783144d6738af1d2ef3a91ef3cb2ef8529bb041 Mon Sep 17 00:00:00 2001 -From: Florinel Iordache -Date: Mon, 5 Nov 2018 17:04:05 +0200 -Subject: [PATCH] arm64: dts: Added endianness information to dts serdes node - -This change is required to specify that serdes HW peripheral is little-endian. - -Signed-off-by: Florinel Iordache ---- - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 3 ++- - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 3 ++- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 3 ++- - 3 files changed, 6 insertions(+), 3 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -184,8 +184,9 @@ - }; - - serdes1: serdes@1ea0000 { -- reg = <0x0 0x1ea0000 0 0x00002000>; - compatible = "fsl,serdes-10g"; -+ reg = <0x0 0x1ea0000 0 0x00002000>; -+ little-endian; - }; - - tmu: tmu@1f80000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -833,8 +833,9 @@ - }; - - serdes1: serdes@1ea0000 { -- reg = <0x0 0x1ea0000 0 0x00002000>; - compatible = "fsl,serdes-10g"; -+ reg = <0x0 0x1ea0000 0 0x00002000>; -+ little-endian; - }; - - ccn@4000000 { ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -581,8 +581,9 @@ - }; - - serdes1: serdes@1ea0000 { -- reg = <0x0 0x1ea0000 0 0x00002000>; - compatible = "fsl,serdes-28g"; -+ reg = <0x0 0x1ea0000 0 0x00002000>; -+ little-endian; - }; - - i2c0: i2c@2000000 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0033-arm64-dts-freescale-lx2160a-add-pcie-DT-nodes.patch b/target/linux/layerscape/patches-5.4/302-dts-0033-arm64-dts-freescale-lx2160a-add-pcie-DT-nodes.patch deleted file mode 100644 index 26d484d942..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0033-arm64-dts-freescale-lx2160a-add-pcie-DT-nodes.patch +++ /dev/null @@ -1,183 +0,0 @@ -From 86e03654997db1b70e71f717ab3e74b1df2f402c Mon Sep 17 00:00:00 2001 -From: Hou Zhiqiang -Date: Thu, 13 Jul 2017 18:28:27 +0800 -Subject: [PATCH] arm64: dts: freescale: lx2160a: add pcie DT nodes - -The LX2160A integrated 6 PCIe Gen4 controllers. - -Signed-off-by: Hou Zhiqiang ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 162 +++++++++++++++++++++++++ - 1 file changed, 162 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -903,6 +903,168 @@ - status = "disabled"; - }; - -+ pcie@3400000 { -+ compatible = "fsl,lx2160a-pcie"; -+ reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ -+ 0x80 0x00000000 0x0 0x00001000>; /* configuration space */ -+ reg-names = "csr_axi_slave", "config_axi_slave"; -+ interrupts = , /* AER interrupt */ -+ , /* PME interrupt */ -+ ; /* controller interrupt */ -+ interrupt-names = "aer", "pme", "intr"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ dma-coherent; -+ apio-wins = <8>; -+ ppio-wins = <8>; -+ bus-range = <0x0 0xff>; -+ ranges = <0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ -+ msi-parent = <&its>; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 2 &gic 0 0 GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 3 &gic 0 0 GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 4 &gic 0 0 GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ }; -+ -+ pcie@3500000 { -+ compatible = "fsl,lx2160a-pcie"; -+ reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ -+ 0x88 0x00000000 0x0 0x00001000>; /* configuration space */ -+ reg-names = "csr_axi_slave", "config_axi_slave"; -+ interrupts = , /* AER interrupt */ -+ , /* PME interrupt */ -+ ; /* controller interrupt */ -+ interrupt-names = "aer", "pme", "intr"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ dma-coherent; -+ apio-wins = <8>; -+ ppio-wins = <8>; -+ bus-range = <0x0 0xff>; -+ ranges = <0x82000000 0x0 0x40000000 0x88 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ -+ msi-parent = <&its>; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 2 &gic 0 0 GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 3 &gic 0 0 GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 4 &gic 0 0 GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ }; -+ -+ pcie@3600000 { -+ compatible = "fsl,lx2160a-pcie"; -+ reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ -+ 0x90 0x00000000 0x0 0x00001000>; /* configuration space */ -+ reg-names = "csr_axi_slave", "config_axi_slave"; -+ interrupts = , /* AER interrupt */ -+ , /* PME interrupt */ -+ ; /* controller interrupt */ -+ interrupt-names = "aer", "pme", "intr"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ dma-coherent; -+ apio-wins = <8>; -+ ppio-wins = <8>; -+ bus-range = <0x0 0xff>; -+ ranges = <0x82000000 0x0 0x40000000 0x90 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ -+ msi-parent = <&its>; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 2 &gic 0 0 GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 3 &gic 0 0 GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 4 &gic 0 0 GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ }; -+ -+ pcie@3700000 { -+ compatible = "fsl,lx2160a-pcie"; -+ reg = <0x00 0x03700000 0x0 0x00100000 /* controller registers */ -+ 0x98 0x00000000 0x0 0x00001000>; /* configuration space */ -+ reg-names = "csr_axi_slave", "config_axi_slave"; -+ interrupts = , /* AER interrupt */ -+ , /* PME interrupt */ -+ ; /* controller interrupt */ -+ interrupt-names = "aer", "pme", "intr"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ dma-coherent; -+ apio-wins = <8>; -+ ppio-wins = <8>; -+ bus-range = <0x0 0xff>; -+ ranges = <0x82000000 0x0 0x40000000 0x98 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ -+ msi-parent = <&its>; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 2 &gic 0 0 GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 3 &gic 0 0 GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 4 &gic 0 0 GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ }; -+ -+ pcie@3800000 { -+ compatible = "fsl,lx2160a-pcie"; -+ reg = <0x00 0x03800000 0x0 0x00100000 /* controller registers */ -+ 0xa0 0x00000000 0x0 0x00001000>; /* configuration space */ -+ reg-names = "csr_axi_slave", "config_axi_slave"; -+ interrupts = , /* AER interrupt */ -+ , /* PME interrupt */ -+ ; /* controller interrupt */ -+ interrupt-names = "aer", "pme", "intr"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ dma-coherent; -+ apio-wins = <8>; -+ ppio-wins = <8>; -+ bus-range = <0x0 0xff>; -+ ranges = <0x82000000 0x0 0x40000000 0xa0 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ -+ msi-parent = <&its>; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 2 &gic 0 0 GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 3 &gic 0 0 GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 4 &gic 0 0 GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ }; -+ -+ pcie@3900000 { -+ compatible = "fsl,lx2160a-pcie"; -+ reg = <0x00 0x03900000 0x0 0x00100000 /* controller registers */ -+ 0xa8 0x00000000 0x0 0x00001000>; /* configuration space */ -+ reg-names = "csr_axi_slave", "config_axi_slave"; -+ interrupts = , /* AER interrupt */ -+ , /* PME interrupt */ -+ ; /* controller interrupt */ -+ interrupt-names = "aer", "pme", "intr"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ dma-coherent; -+ apio-wins = <8>; -+ ppio-wins = <8>; -+ bus-range = <0x0 0xff>; -+ ranges = <0x82000000 0x0 0x40000000 0xa8 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ -+ msi-parent = <&its>; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 2 &gic 0 0 GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 3 &gic 0 0 GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 4 &gic 0 0 GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ }; -+ - smmu: iommu@5000000 { - compatible = "arm,mmu-500"; - reg = <0 0x5000000 0 0x800000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0034-arm64-dts-freescale-lx2160a-Inphi-in112525_s03-mdio-.patch b/target/linux/layerscape/patches-5.4/302-dts-0034-arm64-dts-freescale-lx2160a-Inphi-in112525_s03-mdio-.patch deleted file mode 100644 index 7e3cdb663d..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0034-arm64-dts-freescale-lx2160a-Inphi-in112525_s03-mdio-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From fa7b2d215b494f912b591f28c1205593bccfc2cc Mon Sep 17 00:00:00 2001 -From: Florin Chiculita -Date: Sun, 16 Dec 2018 23:05:12 +0200 -Subject: [PATCH] arm64: dts: freescale: lx2160a: Inphi in112525_s03 mdio node - -Add Inphi retimer phyid in the mdio node, solving the probe issue -for this non-standard clause-45 device. - -Signed-off-by: Florin Chiculita ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -@@ -188,11 +188,9 @@ - }; - - &emdio2 { -- inphi_phy: emdio2_phy@0 { -- compatible = "ethernet-phy-ieee802.3-c45"; -+ inphi_phy: ethernet-phy@0 { -+ compatible = "ethernet-phy-id0210.7440"; - reg = <0x0>; -- interrupts = <0 9 IRQ_TYPE_EDGE_FALLING>, -- <0 10 IRQ_TYPE_EDGE_FALLING>; - }; - }; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0035-arm64-dts-lx2160a-add-optee-tz-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0035-arm64-dts-lx2160a-add-optee-tz-node.patch deleted file mode 100644 index da82d44f29..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0035-arm64-dts-lx2160a-add-optee-tz-node.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 9ab6cc70cd84ca4a140b30b8a0a2371a3585a72a Mon Sep 17 00:00:00 2001 -From: Pankaj Gupta -Date: Tue, 27 Nov 2018 15:33:08 +0530 -Subject: [PATCH] arm64: dts: lx2160a: add optee-tz node - -Signed-off-by: Pankaj Gupta ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -1287,4 +1287,11 @@ - }; - }; - }; -+ -+ firmware { -+ optee { -+ compatible = "linaro,optee-tz"; -+ method = "smc"; -+ }; -+ }; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0036-arm64-dts-ls104x-constrain-sata-dma-address-size.patch b/target/linux/layerscape/patches-5.4/302-dts-0036-arm64-dts-ls104x-constrain-sata-dma-address-size.patch deleted file mode 100644 index 486bb23c2a..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0036-arm64-dts-ls104x-constrain-sata-dma-address-size.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 4a7dcac3fd18b182f882b65161267612713f72dc Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 11 Dec 2018 13:32:31 +0200 -Subject: [PATCH] arm64: dts: ls104x: constrain sata dma address size - -Limit the dma mask size for sata to 40 bits to match the actual address -size generated towards the interconnect. Re-use the already existing -auxiliary simple bus meant for usb but drop the usb reference from the -node name. - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 18 +++++++++--------- - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 18 +++++++++--------- - 2 files changed, 18 insertions(+), 18 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -696,7 +696,7 @@ - <&clockgen 4 0>; - }; - -- usb_aux_bus: usb_aux_bus { -+ aux_bus: aux_bus { - #address-cells = <2>; - #size-cells = <2>; - compatible = "simple-bus"; -@@ -741,15 +741,15 @@ - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - configure-gfladj; - }; -- }; - -- sata: sata@3200000 { -- compatible = "fsl,ls1043a-ahci"; -- reg = <0x0 0x3200000 0x0 0x10000>, -- <0x0 0x20140520 0x0 0x4>; -- reg-names = "ahci", "sata-ecc"; -- interrupts = <0 69 0x4>; -- clocks = <&clockgen 4 0>; -+ sata: sata@3200000 { -+ compatible = "fsl,ls1043a-ahci"; -+ reg = <0x0 0x3200000 0x0 0x10000>, -+ <0x0 0x20140520 0x0 0x4>; -+ reg-names = "ahci", "sata-ecc"; -+ interrupts = <0 69 0x4>; -+ clocks = <&clockgen 4 0>; -+ }; - }; - - msi1: msi-controller1@1571000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -594,7 +594,7 @@ - <&clockgen 4 1>; - }; - -- usb_aux_bus: usb_aux_bus { -+ aux_bus: aux_bus { - #address-cells = <2>; - #size-cells = <2>; - compatible = "simple-bus"; -@@ -636,15 +636,15 @@ - usb3-lpm-capable; - snps,dis-u1u2-when-u3-quirk; - }; -- }; - -- sata: sata@3200000 { -- compatible = "fsl,ls1046a-ahci"; -- reg = <0x0 0x3200000 0x0 0x10000>, -- <0x0 0x20140520 0x0 0x4>; -- reg-names = "ahci", "sata-ecc"; -- interrupts = ; -- clocks = <&clockgen 4 1>; -+ sata: sata@3200000 { -+ compatible = "fsl,ls1046a-ahci"; -+ reg = <0x0 0x3200000 0x0 0x10000>, -+ <0x0 0x20140520 0x0 0x4>; -+ reg-names = "ahci", "sata-ecc"; -+ interrupts = ; -+ clocks = <&clockgen 4 1>; -+ }; - }; - - msi1: msi-controller@1580000 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0037-arm64-dts-lx2160a-qds-add-sata-node-support.patch b/target/linux/layerscape/patches-5.4/302-dts-0037-arm64-dts-lx2160a-qds-add-sata-node-support.patch deleted file mode 100644 index b8a44837aa..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0037-arm64-dts-lx2160a-qds-add-sata-node-support.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 4551b9c547f7bf7b40d83f8762c77cee0041f5eb Mon Sep 17 00:00:00 2001 -From: Peng Ma -Date: Mon, 14 Jan 2019 08:26:40 +0000 -Subject: [PATCH] arm64: dts: lx2160a-qds: add sata node support - -Add sata node support and Enable sata support - -Signed-off-by: Peng Ma ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -@@ -203,6 +203,22 @@ - }; - }; - -+&sata0 { -+ status = "okay"; -+}; -+ -+&sata1 { -+ status = "okay"; -+}; -+ -+&sata2 { -+ status = "okay"; -+}; -+ -+&sata3 { -+ status = "okay"; -+}; -+ - /* Update DPMAC connections to 40G backplane PHYs - * &dpmac1 { - * phy-handle = <&pcs_phy1>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0038-arm64-dts-ls1012a-use-phy-handle-to-handle-phy-param.patch b/target/linux/layerscape/patches-5.4/302-dts-0038-arm64-dts-ls1012a-use-phy-handle-to-handle-phy-param.patch deleted file mode 100644 index f6e7bf0b9c..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0038-arm64-dts-ls1012a-use-phy-handle-to-handle-phy-param.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 203a34f815c7e9320140bb2259ae5884575f0658 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Tue, 20 Nov 2018 21:52:03 +0530 -Subject: [PATCH] arm64: dts: ls1012a: use phy-handle to handle phy params - -Replace properties "fsl,gemac-phy-id" and "fsl,pfe-phy-if-flags" -and use phy-handle instead. -Create mdio node with phy-handles defining PHYs available on the -mdio bus. - -Signed-off-by: Calvin Johnson ---- - .../boot/dts/freescale/fsl-ls1012a-2g5rdb.dts | 25 +++++++++++++--------- - arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts | 23 +++++++++++--------- - arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts | 23 +++++++++++--------- - arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts | 25 +++++++++++++--------- - arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 22 ++++++++++--------- - 5 files changed, 68 insertions(+), 50 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-2g5rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-2g5rdb.dts -@@ -58,14 +58,9 @@ - #size-cells = <0>; - reg = <0x0>; /* GEM_ID */ - fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -- fsl,gemac-phy-id = <0x1>; /* PHY_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii-2500"; -- fsl,pfe-phy-if-flags = <0x0>; -- -- mdio@0 { -- reg = <0x1>; /* enabled/disabled */ -- }; -+ phy-handle = <&sgmii_phy1>; - }; - - ethernet@1 { -@@ -74,13 +69,23 @@ - #size-cells = <0>; - reg = <0x1>; /* GEM_ID */ - fsl,gemac-bus-id = < 0x0>; /* BUS_ID */ -- fsl,gemac-phy-id = < 0x2>; /* PHY_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii-2500"; -- fsl,pfe-phy-if-flags = <0x0>; -+ phy-handle = <&sgmii_phy2>; -+ }; -+ -+ mdio@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sgmii_phy1: ethernet-phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x1>; -+ }; - -- mdio@0 { -- reg = <0x0>; /* enabled/disabled */ -+ sgmii_phy2: ethernet-phy@2 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x2>; - }; - }; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts -@@ -90,14 +90,9 @@ - #size-cells = <0>; - reg = <0x0>; /* GEM_ID */ - fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -- fsl,gemac-phy-id = <0x2>; /* PHY_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii"; -- fsl,pfe-phy-if-flags = <0x0>; -- -- mdio@0 { -- reg = <0x1>; /* enabled/disabled */ -- }; -+ phy-handle = <&sgmii_phy1>; - }; - - ethernet@1 { -@@ -106,13 +101,21 @@ - #size-cells = <0>; - reg = <0x1>; /* GEM_ID */ - fsl,gemac-bus-id = <0x1>; /* BUS_ID */ -- fsl,gemac-phy-id = <0x1>; /* PHY_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii"; -- fsl,pfe-phy-if-flags = <0x0>; -+ phy-handle = <&sgmii_phy2>; -+ }; -+ -+ mdio@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sgmii_phy1: ethernet-phy@2 { -+ reg = <0x2>; -+ }; - -- mdio@0 { -- reg = <0x0>; /* enabled/disabled */ -+ sgmii_phy2: ethernet-phy@1 { -+ reg = <0x1>; - }; - }; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts -@@ -111,14 +111,9 @@ - #size-cells = <0>; - reg = <0x0>; /* GEM_ID */ - fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -- fsl,gemac-phy-id = <0x2>; /* PHY_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii"; -- fsl,pfe-phy-if-flags = <0x0>; -- -- mdio@0 { -- reg = <0x1>; /* enabled/disabled */ -- }; -+ phy-handle = <&sgmii_phy1>; - }; - - ethernet@1 { -@@ -127,13 +122,21 @@ - #size-cells = <0>; - reg = <0x1>; /* GEM_ID */ - fsl,gemac-bus-id = <0x1>; /* BUS_ID */ -- fsl,gemac-phy-id = <0x1>; /* PHY_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii"; -- fsl,pfe-phy-if-flags = <0x0>; -+ phy-handle = <&sgmii_phy2>; -+ }; -+ -+ mdio@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sgmii_phy1: ethernet-phy@2 { -+ reg = <0x2>; -+ }; - -- mdio@0 { -- reg = <0x0>; /* enabled/disabled */ -+ sgmii_phy2: ethernet-phy@1 { -+ reg = <0x1>; - }; - }; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts -@@ -148,14 +148,9 @@ - #size-cells = <0>; - reg = <0x0>; /* GEM_ID */ - fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -- fsl,gemac-phy-id = <0x1>; /* PHY_ID */ - fsl,mdio-mux-val = <0x2>; - phy-mode = "sgmii-2500"; -- fsl,pfe-phy-if-flags = <0x0>; -- -- mdio@0 { -- reg = <0x1>; /* enabled/disabled */ -- }; -+ phy-handle = <&sgmii_phy1>; - }; - - ethernet@1 { -@@ -164,13 +159,23 @@ - #size-cells = <0>; - reg = <0x1>; /* GEM_ID */ - fsl,gemac-bus-id = <0x1>; /* BUS_ID */ -- fsl,gemac-phy-id = <0x2>; /* PHY_ID */ - fsl,mdio-mux-val = <0x3>; - phy-mode = "sgmii-2500"; -- fsl,pfe-phy-if-flags = <0x0>; -+ phy-handle = <&sgmii_phy2>; -+ }; -+ -+ mdio@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sgmii_phy1: ethernet-phy@1 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x1>; -+ }; - -- mdio@0 { -- reg = <0x0>; /* enabled/disabled */ -+ sgmii_phy2: ethernet-phy@2 { -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ reg = <0x2>; - }; - }; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -@@ -59,14 +59,9 @@ - #size-cells = <0>; - reg = <0x0>; /* GEM_ID */ - fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -- fsl,gemac-phy-id = <0x2>; /* PHY_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii"; -- fsl,pfe-phy-if-flags = <0x0>; -- -- mdio@0 { -- reg = <0x1>; /* enabled/disabled */ -- }; -+ phy-handle = <&sgmii_phy>; - }; - - ethernet@1 { -@@ -75,13 +70,20 @@ - #size-cells = <0>; - reg = <0x1>; /* GEM_ID */ - fsl,gemac-bus-id = < 0x1 >; /* BUS_ID */ -- fsl,gemac-phy-id = < 0x1 >; /* PHY_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "rgmii-txid"; -- fsl,pfe-phy-if-flags = <0x0>; -+ phy-handle = <&rgmii_phy>; -+ }; -+ mdio@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sgmii_phy: ethernet-phy@2 { -+ reg = <0x2>; -+ }; - -- mdio@0 { -- reg = <0x0>; /* enabled/disabled */ -+ rgmii_phy: ethernet-phy@1 { -+ reg = <0x1>; - }; - }; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0039-arm64-dts-ls1012a-remove-unused-gemac-bus-id.patch b/target/linux/layerscape/patches-5.4/302-dts-0039-arm64-dts-ls1012a-remove-unused-gemac-bus-id.patch deleted file mode 100644 index aaac126346..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0039-arm64-dts-ls1012a-remove-unused-gemac-bus-id.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 4ae484235c6b0994e223e802b7fc465ce3b8c4ba Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Thu, 3 Jan 2019 11:07:24 +0530 -Subject: [PATCH] arm64: dts: ls1012a: remove unused gemac-bus-id - -gemac-bus-id is unused property and is removed. - -Signed-off-by: Calvin Johnson ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a-2g5rdb.dts | 2 -- - arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts | 2 -- - arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts | 1 - - arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts | 2 -- - arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 2 -- - 5 files changed, 9 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-2g5rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-2g5rdb.dts -@@ -57,7 +57,6 @@ - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0>; /* GEM_ID */ -- fsl,gemac-bus-id = <0x0>; /* BUS_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii-2500"; - phy-handle = <&sgmii_phy1>; -@@ -68,7 +67,6 @@ - #address-cells = <1>; - #size-cells = <0>; - reg = <0x1>; /* GEM_ID */ -- fsl,gemac-bus-id = < 0x0>; /* BUS_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii-2500"; - phy-handle = <&sgmii_phy2>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts -@@ -89,7 +89,6 @@ - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0>; /* GEM_ID */ -- fsl,gemac-bus-id = <0x0>; /* BUS_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii"; - phy-handle = <&sgmii_phy1>; -@@ -100,7 +99,6 @@ - #address-cells = <1>; - #size-cells = <0>; - reg = <0x1>; /* GEM_ID */ -- fsl,gemac-bus-id = <0x1>; /* BUS_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii"; - phy-handle = <&sgmii_phy2>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts -@@ -121,7 +121,6 @@ - #address-cells = <1>; - #size-cells = <0>; - reg = <0x1>; /* GEM_ID */ -- fsl,gemac-bus-id = <0x1>; /* BUS_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii"; - phy-handle = <&sgmii_phy2>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts -@@ -147,7 +147,6 @@ - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0>; /* GEM_ID */ -- fsl,gemac-bus-id = <0x0>; /* BUS_ID */ - fsl,mdio-mux-val = <0x2>; - phy-mode = "sgmii-2500"; - phy-handle = <&sgmii_phy1>; -@@ -158,7 +157,6 @@ - #address-cells = <1>; - #size-cells = <0>; - reg = <0x1>; /* GEM_ID */ -- fsl,gemac-bus-id = <0x1>; /* BUS_ID */ - fsl,mdio-mux-val = <0x3>; - phy-mode = "sgmii-2500"; - phy-handle = <&sgmii_phy2>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -@@ -58,7 +58,6 @@ - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0>; /* GEM_ID */ -- fsl,gemac-bus-id = <0x0>; /* BUS_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii"; - phy-handle = <&sgmii_phy>; -@@ -69,7 +68,6 @@ - #address-cells = <1>; - #size-cells = <0>; - reg = <0x1>; /* GEM_ID */ -- fsl,gemac-bus-id = < 0x1 >; /* BUS_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "rgmii-txid"; - phy-handle = <&rgmii_phy>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0040-arm64-dts-ls1012a-reorganize-pfe_mac-nodes.patch b/target/linux/layerscape/patches-5.4/302-dts-0040-arm64-dts-ls1012a-reorganize-pfe_mac-nodes.patch deleted file mode 100644 index 53e8f186c1..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0040-arm64-dts-ls1012a-reorganize-pfe_mac-nodes.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 4ed0fefb58b5788368fea2c69d646ee4f2e9e012 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Mon, 10 Dec 2018 10:03:51 +0530 -Subject: [PATCH] arm64: dts: ls1012a: reorganize pfe_mac nodes - -To keep platform specific properties in the platform dts files, -remove pfe_mac nodes from dtsi and define them in dts files. - -Signed-off-by: Calvin Johnson ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a-2g5rdb.dts | 4 ++-- - arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts | 4 ++-- - arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts | 4 ++-- - arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts | 4 ++-- - arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 4 ++-- - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 5 ----- - 6 files changed, 10 insertions(+), 15 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-2g5rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-2g5rdb.dts -@@ -52,7 +52,7 @@ - #address-cells = <1>; - #size-cells = <0>; - -- ethernet@0 { -+ pfe_mac0: ethernet@0 { - compatible = "fsl,pfe-gemac-port"; - #address-cells = <1>; - #size-cells = <0>; -@@ -62,7 +62,7 @@ - phy-handle = <&sgmii_phy1>; - }; - -- ethernet@1 { -+ pfe_mac1: ethernet@1 { - compatible = "fsl,pfe-gemac-port"; - #address-cells = <1>; - #size-cells = <0>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dts -@@ -84,7 +84,7 @@ - #address-cells = <1>; - #size-cells = <0>; - -- ethernet@0 { -+ pfe_mac0: ethernet@0 { - compatible = "fsl,pfe-gemac-port"; - #address-cells = <1>; - #size-cells = <0>; -@@ -94,7 +94,7 @@ - phy-handle = <&sgmii_phy1>; - }; - -- ethernet@1 { -+ pfe_mac1: ethernet@1 { - compatible = "fsl,pfe-gemac-port"; - #address-cells = <1>; - #size-cells = <0>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts -@@ -105,7 +105,7 @@ - #address-cells = <1>; - #size-cells = <0>; - -- ethernet@0 { -+ pfe_mac0: ethernet@0 { - compatible = "fsl,pfe-gemac-port"; - #address-cells = <1>; - #size-cells = <0>; -@@ -116,7 +116,7 @@ - phy-handle = <&sgmii_phy1>; - }; - -- ethernet@1 { -+ pfe_mac1: ethernet@1 { - compatible = "fsl,pfe-gemac-port"; - #address-cells = <1>; - #size-cells = <0>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts -@@ -142,7 +142,7 @@ - #address-cells = <1>; - #size-cells = <0>; - -- ethernet@0 { -+ pfe_mac0: ethernet@0 { - compatible = "fsl,pfe-gemac-port"; - #address-cells = <1>; - #size-cells = <0>; -@@ -152,7 +152,7 @@ - phy-handle = <&sgmii_phy1>; - }; - -- ethernet@1 { -+ pfe_mac1: ethernet@1 { - compatible = "fsl,pfe-gemac-port"; - #address-cells = <1>; - #size-cells = <0>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -@@ -53,7 +53,7 @@ - #address-cells = <1>; - #size-cells = <0>; - -- ethernet@0 { -+ pfe_mac0: ethernet@0 { - compatible = "fsl,pfe-gemac-port"; - #address-cells = <1>; - #size-cells = <0>; -@@ -63,7 +63,7 @@ - phy-handle = <&sgmii_phy>; - }; - -- ethernet@1 { -+ pfe_mac1: ethernet@1 { - compatible = "fsl,pfe-gemac-port"; - #address-cells = <1>; - #size-cells = <0>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -530,11 +530,6 @@ - clock-names = "pfe"; - - status = "okay"; -- pfe_mac0: ethernet@0 { -- }; -- -- pfe_mac1: ethernet@1 { -- }; - }; - - firmware { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0041-sdk-dts-ls104x-drop-smmu-from-the-qds-and-usdpaa-sdk.patch b/target/linux/layerscape/patches-5.4/302-dts-0041-sdk-dts-ls104x-drop-smmu-from-the-qds-and-usdpaa-sdk.patch deleted file mode 100644 index 8cbb00f0c0..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0041-sdk-dts-ls104x-drop-smmu-from-the-qds-and-usdpaa-sdk.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 6119ca5f113320d848ead38b141238b013f538c6 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Wed, 23 Jan 2019 16:28:36 +0200 -Subject: [PATCH] sdk: dts: ls104x: drop smmu from the qds and usdpaa sdk dts - -Also drop the smmu from the qds and usdpaa versions of the -SDK device trees because SMMU is supported only for the -upstream version of the dpaa ethernet drivers. - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a-qds-sdk.dts | 14 ++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts | 14 ++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1046a-qds-sdk.dts | 14 ++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts | 14 ++++++++++++++ - 4 files changed, 56 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds-sdk.dts -@@ -64,6 +64,20 @@ - &soc { - #include "qoriq-dpaa-eth.dtsi" - #include "qoriq-fman3-0-6oh.dtsi" -+ -+pcie@3400000 { -+ /delete-property/ iommu-map; -+}; -+ -+pcie@3500000 { -+ /delete-property/ iommu-map; -+}; -+ -+pcie@3600000 { -+ /delete-property/ iommu-map; -+}; -+ -+/delete-node/ iommu@9000000; - }; - - &fman0 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts -@@ -92,6 +92,20 @@ - fsl,fman-oh-port = <&fman0_oh2>; - }; - }; -+ -+ pcie@3400000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ pcie@3500000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ pcie@3600000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ /delete-node/ iommu@9000000; - }; - / { - reserved-memory { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds-sdk.dts -@@ -64,6 +64,20 @@ - &soc { - #include "qoriq-dpaa-eth.dtsi" - #include "qoriq-fman3-0-6oh.dtsi" -+ -+pcie@3400000 { -+ /delete-property/ iommu-map; -+}; -+ -+pcie@3500000 { -+ /delete-property/ iommu-map; -+}; -+ -+pcie@3600000 { -+ /delete-property/ iommu-map; -+}; -+ -+/delete-node/ iommu@9000000; - }; - - &fsldpaa { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts -@@ -85,6 +85,20 @@ - fsl,fman-oh-port = <&fman0_oh2>; - }; - }; -+ -+ pcie@3400000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ pcie@3500000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ pcie@3600000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ /delete-node/ iommu@9000000; - }; - / { - reserved-memory { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0042-arm64-dts-fix-the-LS104x-QDS-mdio-mux-support.patch b/target/linux/layerscape/patches-5.4/302-dts-0042-arm64-dts-fix-the-LS104x-QDS-mdio-mux-support.patch deleted file mode 100644 index b8d6c27b1e..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0042-arm64-dts-fix-the-LS104x-QDS-mdio-mux-support.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 3c6ae8f4d45701683e671ea34bdddd0bf3e37a4d Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 13 Feb 2019 17:52:00 +0200 -Subject: [PATCH] arm64: dts: fix the LS104x QDS mdio-mux support - -Set the "simple-bus" compatible and the fpga ranges in order to -successfully probe the mdio-mux-emi1. - -Signed-off-by: Camelia Groza ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts | 3 ++- - arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts | 3 ++- - 2 files changed, 4 insertions(+), 2 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts -@@ -78,10 +78,11 @@ - }; - - fpga: board-control@2,0 { -- compatible = "fsl,ls1043aqds-fpga", "fsl,fpga-qixis"; -+ compatible = "fsl,ls1043aqds-fpga", "fsl,fpga-qixis", "simple-bus"; - reg = <0x2 0x0 0x0000100>; - #address-cells = <1>; - #size-cells = <1>; -+ ranges = <0 2 0 0x100>; - }; - }; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts -@@ -167,8 +167,9 @@ - }; - - fpga: board-control@2,0 { -- compatible = "fsl,ls1046aqds-fpga", "fsl,fpga-qixis"; -+ compatible = "fsl,ls1046aqds-fpga", "fsl,fpga-qixis", "simple-bus"; - reg = <0x2 0x0 0x0000100>; -+ ranges = <0 2 0 0x100>; - }; - }; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0043-arm64-dts-lx2160aqds-Add-mdio-mux-nodes.patch b/target/linux/layerscape/patches-5.4/302-dts-0043-arm64-dts-lx2160aqds-Add-mdio-mux-nodes.patch deleted file mode 100644 index 9a6b32b548..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0043-arm64-dts-lx2160aqds-Add-mdio-mux-nodes.patch +++ /dev/null @@ -1,247 +0,0 @@ -From c9be87f17c64d08c06e4858589a0014f73868867 Mon Sep 17 00:00:00 2001 -From: Pankaj Bansal -Date: Thu, 28 Feb 2019 17:28:36 +0530 -Subject: [PATCH] arm64: dts: lx2160aqds: Add mdio mux nodes - -The two external MDIO buses used to communicate with phy devices that are -external to SOC are muxed in LX2160AQDS board. -These buses can be routed to any one of the eight IO slots on LX2160AQDS -board depending on value in fpga register 0x54. -Additionally the external MDIO1 is used to communicate to the onboard -RGMII phy devices. -The mdio1 is controlled by bits 4-7 of fpga register and mdio2 is -controlled by bits 4-7 of fpga register. - -Signed-off-by: Pankaj Bansal ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts | 145 ++++++++++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts | 8 ++ - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 24 ++-- - 3 files changed, 165 insertions(+), 12 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -@@ -29,6 +29,130 @@ - regulator-boot-on; - regulator-always-on; - }; -+ -+ mdio-mux-1 { -+ compatible = "mdio-mux-multiplexer"; -+ mux-controls = <&mux 0>; -+ mdio-parent-bus = <&emdio1>; -+ #address-cells=<1>; -+ #size-cells = <0>; -+ -+ mdio@0 { /* On-board PHY #1 RGMI1*/ -+ reg = <0x00>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@8 { /* On-board PHY #2 RGMI2*/ -+ reg = <0x8>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@18 { /* Slot #1 */ -+ reg = <0x18>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@19 { /* Slot #2 */ -+ reg = <0x19>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@1a { /* Slot #3 */ -+ reg = <0x1a>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@1b { /* Slot #4 */ -+ reg = <0x1b>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@1c { /* Slot #5 */ -+ reg = <0x1c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@1d { /* Slot #6 */ -+ reg = <0x1d>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@1e { /* Slot #7 */ -+ reg = <0x1e>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@1f { /* Slot #8 */ -+ reg = <0x1f>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; -+ -+ mdio-mux-2 { -+ compatible = "mdio-mux-multiplexer"; -+ mux-controls = <&mux 1>; -+ mdio-parent-bus = <&emdio2>; -+ #address-cells=<1>; -+ #size-cells = <0>; -+ -+ mdio@0 { /* Slot #1 (secondary EMI) */ -+ reg = <0x00>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@1 { /* Slot #2 (secondary EMI) */ -+ reg = <0x01>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@2 { /* Slot #3 (secondary EMI) */ -+ reg = <0x02>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@3 { /* Slot #4 (secondary EMI) */ -+ reg = <0x03>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@4 { /* Slot #5 (secondary EMI) */ -+ reg = <0x04>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@5 { /* Slot #6 (secondary EMI) */ -+ reg = <0x05>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@6 { /* Slot #7 (secondary EMI) */ -+ reg = <0x06>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ -+ mdio@7 { /* Slot #8 (secondary EMI) */ -+ reg = <0x07>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+ }; - }; - - &crypto { -@@ -71,6 +195,14 @@ - }; - }; - -+&emdio1 { -+ status = "okay"; -+}; -+ -+&emdio2 { -+ status = "okay"; -+}; -+ - &esdhc0 { - status = "okay"; - }; -@@ -82,6 +214,19 @@ - &i2c0 { - status = "okay"; - -+ fpga@66 { -+ compatible = "fsl,lx2160aqds-fpga", "fsl,fpga-qixis-i2c", -+ "simple-mfd"; -+ reg = <0x66>; -+ -+ mux: mux-controller { -+ compatible = "reg-mux"; -+ #mux-control-cells = <1>; -+ mux-reg-masks = <0x54 0xf8>, /* 0: reg 0x54, bits 7:3 */ -+ <0x54 0x07>; /* 1: reg 0x54, bit 2:0 */ -+ }; -+ }; -+ - i2c-mux@77 { - compatible = "nxp,pca9547"; - reg = <0x77>; ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -@@ -35,6 +35,14 @@ - status = "okay"; - }; - -+&emdio1 { -+ status = "okay"; -+}; -+ -+&emdio2 { -+ status = "okay"; -+}; -+ - &esdhc0 { - sd-uhs-sdr104; - sd-uhs-sdr50; ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -478,26 +478,26 @@ - little-endian; - }; - -- /* TODO: WRIOP (CCSR?) */ -- emdio1: mdio@0x8B96000 { /* WRIOP0: 0x8B8_0000, E-MDIO1: 0x1_6000 */ -+ /* WRIOP0: 0x8b8_0000, E-MDIO1: 0x1_6000 */ -+ emdio1: mdio@8b96000 { - compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8B96000 0x0 0x1000>; -- device_type = "mdio"; /* TODO: is this necessary? */ -- little-endian; /* force the driver in LE mode */ -- -- /* Not necessary on the QDS, but needed on the RDB */ -+ reg = <0x0 0x8b96000 0x0 0x1000>; -+ interrupts = ; - #address-cells = <1>; - #size-cells = <0>; -+ little-endian; /* force the driver in LE mode */ -+ status = "disabled"; - }; - -- emdio2: mdio@0x8B97000 { /* WRIOP0: 0x8B8_0000, E-MDIO2: 0x1_7000 */ -+ /* WRIOP0: 0x8b8_0000, E-MDIO2: 0x1_7000 */ -+ emdio2: mdio@8b97000 { - compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8B97000 0x0 0x1000>; -- device_type = "mdio"; /* TODO: is this necessary? */ -- little-endian; /* force the driver in LE mode */ -- -+ reg = <0x0 0x8b97000 0x0 0x1000>; -+ interrupts = ; - #address-cells = <1>; - #size-cells = <0>; -+ little-endian; /* force the driver in LE mode */ -+ status = "disabled"; - }; - - pcs_mdio1: mdio@0x8c07000 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0044-sdk-arm64-dts-reduce-usdpaa-memory-to-4K-for-LS1046-.patch b/target/linux/layerscape/patches-5.4/302-dts-0044-sdk-arm64-dts-reduce-usdpaa-memory-to-4K-for-LS1046-.patch deleted file mode 100644 index f8a75d8f84..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0044-sdk-arm64-dts-reduce-usdpaa-memory-to-4K-for-LS1046-.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 97b563d9c0cf09897c1e7b793ef0fe677c66269a Mon Sep 17 00:00:00 2001 -From: Nipun Gupta -Date: Wed, 30 Jan 2019 19:18:13 +0530 -Subject: [PATCH] sdk: arm64: dts: reduce usdpaa memory to 4K for LS1046/43 - -This patch reducing the USDPAA reseved memory to 4K. -In case USDPAA is to be used, 256MB needs to be reserved in the DTS file. - -Signed-off-by: Nipun Gupta ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts | 9 +++++++-- - arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts | 9 +++++++-- - 2 files changed, 14 insertions(+), 4 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts -@@ -113,11 +113,16 @@ - #size-cells = <2>; - ranges; - -+ /* For legacy usdpaa based use-cases, update the size and -+ alignment parameters. e.g. to allocate 256 MB memory: -+ size = <0 0x10000000>; -+ alignment = <0 0x10000000>; -+ */ - usdpaa_mem: usdpaa_mem { - compatible = "fsl,usdpaa-mem"; - alloc-ranges = <0 0 0x10000 0>; -- size = <0 0x10000000>; -- alignment = <0 0x10000000>; -+ size = <0 0x1000>; -+ alignment = <0 0x1000>; - }; - }; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts -@@ -106,11 +106,16 @@ - #size-cells = <2>; - ranges; - -+ /* For legacy usdpaa based use-cases, update the size and -+ alignment parameters. e.g. to allocate 256 MB memory: -+ size = <0 0x10000000>; -+ alignment = <0 0x10000000>; -+ */ - usdpaa_mem: usdpaa_mem { - compatible = "fsl,usdpaa-mem"; - alloc-ranges = <0 0 0x10000 0>; -- size = <0 0x10000000>; -- alignment = <0 0x10000000>; -+ size = <0 0x1000>; -+ alignment = <0 0x1000>; - }; - }; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0045-arm64-dts-Fix-DWC3-IP-VBUS-glitch-issue-on-Layerscap.patch b/target/linux/layerscape/patches-5.4/302-dts-0045-arm64-dts-Fix-DWC3-IP-VBUS-glitch-issue-on-Layerscap.patch deleted file mode 100644 index 10eca4a083..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0045-arm64-dts-Fix-DWC3-IP-VBUS-glitch-issue-on-Layerscap.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 0c7e3f6f557c2a68527980e940e6a605da1f9e12 Mon Sep 17 00:00:00 2001 -From: Ran Wang -Date: Wed, 16 Jan 2019 15:40:33 +0800 -Subject: [PATCH] arm64: dts: Fix DWC3 IP VBUS glitch issue on Layerscape - platforms - -Cover LS1012A, LS1043A, LS1046A, LS1088A, LS208xA, LX2160A - -Signed-off-by: Ran Wang ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 1 + - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 3 +++ - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 3 +++ - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 2 ++ - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 2 ++ - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 2 ++ - 6 files changed, 13 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -443,6 +443,7 @@ - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ snps,host-vbus-glitches; - }; - - sata: sata@3200000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -713,6 +713,7 @@ - usb3-lpm-capable; - snps,dis-u1u2-when-u3-quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ snps,host-vbus-glitches; - configure-gfladj; - }; - -@@ -726,6 +727,7 @@ - usb3-lpm-capable; - snps,dis-u1u2-when-u3-quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ snps,host-vbus-glitches; - configure-gfladj; - }; - -@@ -739,6 +741,7 @@ - usb3-lpm-capable; - snps,dis-u1u2-when-u3-quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ snps,host-vbus-glitches; - configure-gfladj; - }; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -611,6 +611,7 @@ - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - usb3-lpm-capable; - snps,dis-u1u2-when-u3-quirk; -+ snps,host-vbus-glitches; - }; - - usb1: usb@3000000 { -@@ -623,6 +624,7 @@ - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - usb3-lpm-capable; - snps,dis-u1u2-when-u3-quirk; -+ snps,host-vbus-glitches; - }; - - usb2: usb@3100000 { -@@ -635,6 +637,7 @@ - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - usb3-lpm-capable; - snps,dis-u1u2-when-u3-quirk; -+ snps,host-vbus-glitches; - }; - - sata: sata@3200000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -452,6 +452,7 @@ - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ snps,host-vbus-glitches; - status = "disabled"; - }; - -@@ -463,6 +464,7 @@ - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ snps,host-vbus-glitches; - status = "disabled"; - }; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -819,6 +819,7 @@ - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ snps,host-vbus-glitches; - }; - - usb1: usb3@3110000 { -@@ -830,6 +831,7 @@ - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ snps,host-vbus-glitches; - }; - - serdes1: serdes@1ea0000 { ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -845,6 +845,7 @@ - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ snps,host-vbus-glitches; - status = "disabled"; - }; - -@@ -856,6 +857,7 @@ - snps,quirk-frame-length-adjustment = <0x20>; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ snps,host-vbus-glitches; - status = "disabled"; - }; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0046-ARM-dts-Fix-DWC3-IP-VBUS-glitch-issue-on-LS1021A.patch b/target/linux/layerscape/patches-5.4/302-dts-0046-ARM-dts-Fix-DWC3-IP-VBUS-glitch-issue-on-LS1021A.patch deleted file mode 100644 index e80fe0a45e..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0046-ARM-dts-Fix-DWC3-IP-VBUS-glitch-issue-on-LS1021A.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 3c1991fe18bca459d07dd78a2268e26008707f00 Mon Sep 17 00:00:00 2001 -From: Ran Wang -Date: Mon, 25 Feb 2019 13:38:01 +0800 -Subject: [PATCH] ARM: dts: Fix DWC3 IP VBUS glitch issue on LS1021A - -Signed-off-by: Ran Wang ---- - arch/arm/boot/dts/ls1021a.dtsi | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm/boot/dts/ls1021a.dtsi -+++ b/arch/arm/boot/dts/ls1021a.dtsi -@@ -844,6 +844,7 @@ - usb3-lpm-capable; - snps,dis-u1u2-when-u3-quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ snps,host-vbus-glitches; - }; - - pcie@3400000 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0047-ARM-dts-ls1021aqds-enable-esdhc-controller.patch b/target/linux/layerscape/patches-5.4/302-dts-0047-ARM-dts-ls1021aqds-enable-esdhc-controller.patch deleted file mode 100644 index 89f393f344..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0047-ARM-dts-ls1021aqds-enable-esdhc-controller.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 6c3655acaa5766efe81f60ac6d428b0d184daa0d Mon Sep 17 00:00:00 2001 -From: Yinbo Zhu -Date: Fri, 21 Dec 2018 11:38:44 +0800 -Subject: [PATCH] ARM: dts: ls1021aqds: enable esdhc controller - -This patch is to enable esdhc controller in ls1021aqds - -Signed-off-by: Yinbo Zhu ---- - arch/arm/boot/dts/ls1021a-qds.dts | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/arch/arm/boot/dts/ls1021a-qds.dts -+++ b/arch/arm/boot/dts/ls1021a-qds.dts -@@ -165,6 +165,10 @@ - status = "okay"; - }; - -+&esdhc { -+ status = "okay"; -+}; -+ - &i2c0 { - status = "okay"; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0048-arm64-dts-freescale-lx2160a-add-pcie-EP-mode-DT-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0048-arm64-dts-freescale-lx2160a-add-pcie-EP-mode-DT-node.patch deleted file mode 100644 index 5a70597457..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0048-arm64-dts-freescale-lx2160a-add-pcie-EP-mode-DT-node.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 4de7a5e35eff9216fa5e6b138b0ffa75e045e397 Mon Sep 17 00:00:00 2001 -From: Xiaowei Bao -Date: Thu, 28 Feb 2019 14:09:01 +0800 -Subject: [PATCH] arm64: dts: freescale: lx2160a: add pcie EP mode DT nodes - -The LX2160A PCIe EP mode node. - -Signed-off-by: Xiaowei Bao ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 56 ++++++++++++++++++++++++++ - 1 file changed, 56 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -932,6 +932,15 @@ - status = "disabled"; - }; - -+ pcie_ep@3400000 { -+ compatible = "fsl,lx2160a-pcie-ep"; -+ reg = <0x00 0x03400000 0x0 0x00100000 -+ 0x80 0x00000000 0x8 0x00000000>; -+ reg-names = "regs", "addr_space"; -+ num-ob-windows = <256>; -+ status = "disabled"; -+ }; -+ - pcie@3500000 { - compatible = "fsl,lx2160a-pcie"; - reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ -@@ -959,6 +968,15 @@ - status = "disabled"; - }; - -+ pcie_ep@3500000 { -+ compatible = "fsl,lx2160a-pcie-ep"; -+ reg = <0x00 0x03500000 0x0 0x00100000 -+ 0x88 0x00000000 0x8 0x00000000>; -+ reg-names = "regs", "addr_space"; -+ num-ob-windows = <256>; -+ status = "disabled"; -+ }; -+ - pcie@3600000 { - compatible = "fsl,lx2160a-pcie"; - reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ -@@ -986,6 +1004,16 @@ - status = "disabled"; - }; - -+ pcie_ep@3600000 { -+ compatible = "fsl,lx2160a-pcie-ep"; -+ reg = <0x00 0x03600000 0x0 0x00100000 -+ 0x90 0x00000000 0x8 0x00000000>; -+ reg-names = "regs", "addr_space"; -+ num-ob-windows = <256>; -+ max-functions = <2>; -+ status = "disabled"; -+ }; -+ - pcie@3700000 { - compatible = "fsl,lx2160a-pcie"; - reg = <0x00 0x03700000 0x0 0x00100000 /* controller registers */ -@@ -1013,6 +1041,15 @@ - status = "disabled"; - }; - -+ pcie_ep@3700000 { -+ compatible = "fsl,lx2160a-pcie-ep"; -+ reg = <0x00 0x03700000 0x0 0x00100000 -+ 0x98 0x00000000 0x8 0x00000000>; -+ reg-names = "regs", "addr_space"; -+ num-ob-windows = <256>; -+ status = "disabled"; -+ }; -+ - pcie@3800000 { - compatible = "fsl,lx2160a-pcie"; - reg = <0x00 0x03800000 0x0 0x00100000 /* controller registers */ -@@ -1040,6 +1077,16 @@ - status = "disabled"; - }; - -+ pcie_ep@3800000 { -+ compatible = "fsl,lx2160a-pcie-ep"; -+ reg = <0x00 0x03800000 0x0 0x00100000 -+ 0xa0 0x00000000 0x8 0x00000000>; -+ reg-names = "regs", "addr_space"; -+ num-ob-windows = <256>; -+ max-functions = <2>; -+ status = "disabled"; -+ }; -+ - pcie@3900000 { - compatible = "fsl,lx2160a-pcie"; - reg = <0x00 0x03900000 0x0 0x00100000 /* controller registers */ -@@ -1067,6 +1114,15 @@ - status = "disabled"; - }; - -+ pcie_ep@3900000 { -+ compatible = "fsl,lx2160a-pcie-ep"; -+ reg = <0x00 0x03900000 0x0 0x00100000 -+ 0xa8 0x00000000 0x8 0x00000000>; -+ reg-names = "regs", "addr_space"; -+ num-ob-windows = <256>; -+ status = "disabled"; -+ }; -+ - smmu: iommu@5000000 { - compatible = "arm,mmu-500"; - reg = <0 0x5000000 0 0x800000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0049-sdk-dts-ls104x-move-dma-coherent-from-soc-to-its-chi.patch b/target/linux/layerscape/patches-5.4/302-dts-0049-sdk-dts-ls104x-move-dma-coherent-from-soc-to-its-chi.patch deleted file mode 100644 index 838499ae6e..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0049-sdk-dts-ls104x-move-dma-coherent-from-soc-to-its-chi.patch +++ /dev/null @@ -1,879 +0,0 @@ -From 6795bab4281aa9ed8e0ba3fbba06de8dd369b17c Mon Sep 17 00:00:00 2001 -From: Ran Wang -Date: Thu, 21 Feb 2019 13:32:59 +0800 -Subject: [PATCH] sdk: dts: ls104x move dma-coherent from soc to its child - nodes - -Since SMMU is not supported for SDK version, USB function will down if -still apply property 'dma-coherent' in scope of soc (USB driver is not -ready to support it alone) in SDK device trees, decide to remove it. -And add dma-coherent on other non-USB child nodes under soc. - -dma-coherent feature in dts node will cause issue that -QE-HDLC received too little, when a lot of data is transmitted while -just little data received, the Tx buffer will run out. - -Signed-off-by: Ran Wang -Signed-off-by: Zhao Qiang ---- - .../boot/dts/freescale/fsl-ls1043a-qds-sdk.dts | 184 ++++++++++++++++++++- - .../boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts | 177 ++++++++++++++++++++ - .../boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts | 4 + - .../boot/dts/freescale/fsl-ls1046a-qds-sdk.dts | 175 ++++++++++++++++++++ - .../boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts | 178 ++++++++++++++++++++ - .../boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts | 4 + - 6 files changed, 719 insertions(+), 3 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds-sdk.dts -@@ -62,19 +62,24 @@ - }; - - &soc { -+/delete-property/ dma-coherent; -+ - #include "qoriq-dpaa-eth.dtsi" - #include "qoriq-fman3-0-6oh.dtsi" - - pcie@3400000 { -- /delete-property/ iommu-map; -+ /delete-property/ iommu-map; -+ dma-coherent; - }; - - pcie@3500000 { -- /delete-property/ iommu-map; -+ /delete-property/ iommu-map; -+ dma-coherent; - }; - - pcie@3600000 { -- /delete-property/ iommu-map; -+ /delete-property/ iommu-map; -+ dma-coherent; - }; - - /delete-node/ iommu@9000000; -@@ -82,4 +87,177 @@ pcie@3600000 { - - &fman0 { - compatible = "fsl,fman", "simple-bus"; -+ dma-coherent; -+}; -+ -+&clockgen { -+ dma-coherent; -+}; -+ -+&scfg { -+ dma-coherent; -+}; -+ -+&crypto { -+ dma-coherent; -+}; -+ -+&dcfg { -+ dma-coherent; -+}; -+ -+&ifc { -+ dma-coherent; -+}; -+ -+&qspi { -+ dma-coherent; -+}; -+ -+&esdhc { -+ dma-coherent; -+}; -+ -+&ddr { -+ dma-coherent; -+}; -+ -+&tmu { -+ dma-coherent; -+}; -+ -+&qman { -+ dma-coherent; -+}; -+ -+&bman { -+ dma-coherent; -+}; -+ -+&bportals { -+ dma-coherent; -+}; -+ -+&qportals { -+ dma-coherent; -+}; -+ -+&dspi0 { -+ dma-coherent; -+}; -+ -+&dspi1 { -+ dma-coherent; -+}; -+ -+&i2c0 { -+ dma-coherent; -+}; -+ -+&i2c1 { -+ dma-coherent; -+}; -+ -+&i2c2 { -+ dma-coherent; -+}; -+ -+&i2c3 { -+ dma-coherent; -+}; -+ -+&duart0 { -+ dma-coherent; -+}; -+ -+&duart1 { -+ dma-coherent; -+}; -+ -+&duart2 { -+ dma-coherent; -+}; -+ -+&duart3 { -+ dma-coherent; -+}; -+ -+&gpio1 { -+ dma-coherent; -+}; -+ -+&gpio2 { -+ dma-coherent; -+}; -+ -+&gpio3 { -+ dma-coherent; -+}; -+ -+&gpio4 { -+ dma-coherent; -+}; -+ -+&uqe { -+ dma-coherent; -+}; -+ -+&lpuart0 { -+ dma-coherent; -+}; -+ -+&lpuart1 { -+ dma-coherent; -+}; -+ -+&lpuart2 { -+ dma-coherent; -+}; -+ -+&lpuart3 { -+ dma-coherent; -+}; -+ -+&lpuart4 { -+ dma-coherent; -+}; -+ -+&lpuart5 { -+ dma-coherent; -+}; -+ -+&ftm0 { -+ dma-coherent; -+}; -+ -+&wdog0 { -+ dma-coherent; -+}; -+ -+&edma0 { -+ dma-coherent; -+}; -+ -+&qdma { -+ dma-coherent; -+}; -+ -+&msi1 { -+ dma-coherent; -+}; -+ -+&msi2 { -+ dma-coherent; -+}; -+ -+&msi3 { -+ dma-coherent; -+}; -+ -+&ptp_timer0 { -+ dma-coherent; -+}; -+ -+&fsldpaa { -+ dma-coherent; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts -@@ -62,19 +62,24 @@ - }; - - &soc { -+/delete-property/ dma-coherent; -+ - #include "qoriq-dpaa-eth.dtsi" - #include "qoriq-fman3-0-6oh.dtsi" - - pcie@3400000 { - /delete-property/ iommu-map; -+ dma-coherent; - }; - - pcie@3500000 { - /delete-property/ iommu-map; -+ dma-coherent; - }; - - pcie@3600000 { - /delete-property/ iommu-map; -+ dma-coherent; - }; - - /delete-node/ iommu@9000000; -@@ -83,3 +88,175 @@ pcie@3600000 { - &fman0 { - compatible = "fsl,fman", "simple-bus"; - }; -+ -+&clockgen { -+ dma-coherent; -+}; -+ -+&scfg { -+ dma-coherent; -+}; -+ -+&crypto { -+ dma-coherent; -+}; -+ -+&dcfg { -+ dma-coherent; -+}; -+ -+&ifc { -+ dma-coherent; -+}; -+ -+&qspi { -+ dma-coherent; -+}; -+ -+&esdhc { -+ dma-coherent; -+}; -+ -+&ddr { -+ dma-coherent; -+}; -+ -+&tmu { -+ dma-coherent; -+}; -+ -+&qman { -+ dma-coherent; -+}; -+ -+&bman { -+ dma-coherent; -+}; -+ -+&bportals { -+ dma-coherent; -+}; -+ -+&qportals { -+ dma-coherent; -+}; -+ -+&dspi0 { -+ dma-coherent; -+}; -+ -+&dspi1 { -+ dma-coherent; -+}; -+ -+&i2c0 { -+ dma-coherent; -+}; -+ -+&i2c1 { -+ dma-coherent; -+}; -+ -+&i2c2 { -+ dma-coherent; -+}; -+ -+&i2c3 { -+ dma-coherent; -+}; -+ -+&duart0 { -+ dma-coherent; -+}; -+ -+&duart1 { -+ dma-coherent; -+}; -+ -+&duart2 { -+ dma-coherent; -+}; -+ -+&duart3 { -+ dma-coherent; -+}; -+ -+&gpio1 { -+ dma-coherent; -+}; -+ -+&gpio2 { -+ dma-coherent; -+}; -+ -+&gpio3 { -+ dma-coherent; -+}; -+ -+&gpio4 { -+ dma-coherent; -+}; -+ -+&lpuart0 { -+ dma-coherent; -+}; -+ -+&lpuart1 { -+ dma-coherent; -+}; -+ -+&lpuart2 { -+ dma-coherent; -+}; -+ -+&lpuart3 { -+ dma-coherent; -+}; -+ -+&lpuart4 { -+ dma-coherent; -+}; -+ -+&lpuart5 { -+ dma-coherent; -+}; -+ -+&ftm0 { -+ dma-coherent; -+}; -+ -+&wdog0 { -+ dma-coherent; -+}; -+ -+&edma0 { -+ dma-coherent; -+}; -+ -+&qdma { -+ dma-coherent; -+}; -+ -+&msi1 { -+ dma-coherent; -+}; -+ -+&msi2 { -+ dma-coherent; -+}; -+ -+&msi3 { -+ dma-coherent; -+}; -+ -+&fman0 { -+ dma-coherent; -+}; -+ -+&ptp_timer0 { -+ dma-coherent; -+}; -+ -+&fsldpaa { -+ dma-coherent; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-usdpaa.dts -@@ -16,6 +16,7 @@ - fsl,bpid = <7>; - fsl,bpool-ethernet-cfg = <0 0 0 192 0 0xdeadbeef>; - fsl,bpool-thresholds = <0x400 0xc00 0x0 0x0>; -+ dma-coherent; - }; - - bp8: buffer-pool@8 { -@@ -23,6 +24,7 @@ - fsl,bpid = <8>; - fsl,bpool-ethernet-cfg = <0 0 0 576 0 0xabbaf00d>; - fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ dma-coherent; - }; - - bp9: buffer-pool@9 { -@@ -30,10 +32,12 @@ - fsl,bpid = <9>; - fsl,bpool-ethernet-cfg = <0 0 0 2048 0 0xfeedabba>; - fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ dma-coherent; - }; - - fsl,dpaa { - compatible = "fsl,ls1043a", "fsl,dpaa", "simple-bus"; -+ dma-coherent; - - ethernet@0 { - compatible = "fsl,dpa-ethernet-init"; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds-sdk.dts -@@ -62,6 +62,8 @@ - }; - - &soc { -+/delete-property/ dma-coherent; -+ - #include "qoriq-dpaa-eth.dtsi" - #include "qoriq-fman3-0-6oh.dtsi" - -@@ -90,4 +92,177 @@ pcie@3600000 { - - &fman0 { - compatible = "fsl,fman", "simple-bus"; -+ dma-coherent; -+}; -+ -+&clockgen { -+ dma-coherent; -+}; -+ -+&scfg { -+ dma-coherent; -+}; -+ -+&crypto { -+ dma-coherent; -+}; -+ -+&dcfg { -+ dma-coherent; -+}; -+ -+&ifc { -+ dma-coherent; -+}; -+ -+&qspi { -+ dma-coherent; -+}; -+ -+&esdhc { -+ dma-coherent; -+}; -+ -+&ddr { -+ dma-coherent; -+}; -+ -+&tmu { -+ dma-coherent; -+}; -+ -+&qman { -+ dma-coherent; -+}; -+ -+&bman { -+ dma-coherent; -+}; -+ -+&bportals { -+ dma-coherent; -+}; -+ -+&qportals { -+ dma-coherent; -+}; -+ -+&dspi { -+ dma-coherent; -+}; -+ -+&i2c0 { -+ dma-coherent; -+}; -+ -+&i2c1 { -+ dma-coherent; -+}; -+ -+&i2c2 { -+ dma-coherent; -+}; -+ -+&i2c3 { -+ dma-coherent; -+}; -+ -+&duart0 { -+ dma-coherent; -+}; -+ -+&duart1 { -+ dma-coherent; -+}; -+ -+&duart2 { -+ dma-coherent; -+}; -+ -+&duart3 { -+ dma-coherent; -+}; -+ -+&gpio0 { -+ dma-coherent; -+}; -+ -+&gpio1 { -+ dma-coherent; -+}; -+ -+&gpio2 { -+ dma-coherent; -+}; -+ -+&gpio3 { -+ dma-coherent; -+}; -+ -+&lpuart0 { -+ dma-coherent; -+}; -+ -+&lpuart1 { -+ dma-coherent; -+}; -+ -+&lpuart2 { -+ dma-coherent; -+}; -+ -+&lpuart3 { -+ dma-coherent; -+}; -+ -+&lpuart4 { -+ dma-coherent; -+}; -+ -+&lpuart5 { -+ dma-coherent; -+}; -+ -+&ftm0 { -+ dma-coherent; -+}; -+ -+&wdog0 { -+ dma-coherent; -+}; -+ -+&edma0 { -+ dma-coherent; -+}; -+ -+&sata { -+ dma-coherent; -+}; -+ -+&qdma { -+ dma-coherent; -+}; -+ -+&msi1 { -+ dma-coherent; -+}; -+ -+&msi2 { -+ dma-coherent; -+}; -+ -+&msi3 { -+ dma-coherent; -+}; -+ -+&ptp_timer0 { -+ dma-coherent; -+}; -+ -+&serdes1 { -+ dma-coherent; -+}; -+ -+&fsldpaa { -+ dma-coherent; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts -@@ -62,6 +62,8 @@ - }; - - &soc { -+/delete-property/ dma-coherent; -+ - #include "qoriq-dpaa-eth.dtsi" - #include "qoriq-fman3-0-6oh.dtsi" - -@@ -127,3 +129,179 @@ pcie@3600000 { - * phy-handle = <&pcsphy7>; - *}; - */ -+ -+&clockgen { -+ dma-coherent; -+}; -+ -+&scfg { -+ dma-coherent; -+}; -+ -+&crypto { -+ dma-coherent; -+}; -+ -+&dcfg { -+ dma-coherent; -+}; -+ -+&ifc { -+ dma-coherent; -+}; -+ -+&qspi { -+ dma-coherent; -+}; -+ -+&esdhc { -+ dma-coherent; -+}; -+ -+&ddr { -+ dma-coherent; -+}; -+ -+&tmu { -+ dma-coherent; -+}; -+ -+&qman { -+ dma-coherent; -+}; -+ -+&bman { -+ dma-coherent; -+}; -+ -+&bportals { -+ dma-coherent; -+}; -+ -+&qportals { -+ dma-coherent; -+}; -+ -+&dspi { -+ dma-coherent; -+}; -+ -+&i2c0 { -+ dma-coherent; -+}; -+ -+&i2c1 { -+ dma-coherent; -+}; -+ -+&i2c2 { -+ dma-coherent; -+}; -+ -+&i2c3 { -+ dma-coherent; -+}; -+ -+&duart0 { -+ dma-coherent; -+}; -+ -+&duart1 { -+ dma-coherent; -+}; -+ -+&duart2 { -+ dma-coherent; -+}; -+ -+&duart3 { -+ dma-coherent; -+}; -+ -+&gpio0 { -+ dma-coherent; -+}; -+ -+&gpio1 { -+ dma-coherent; -+}; -+ -+&gpio2 { -+ dma-coherent; -+}; -+ -+&gpio3 { -+ dma-coherent; -+}; -+ -+&lpuart0 { -+ dma-coherent; -+}; -+ -+&lpuart1 { -+ dma-coherent; -+}; -+ -+&lpuart2 { -+ dma-coherent; -+}; -+ -+&lpuart3 { -+ dma-coherent; -+}; -+ -+&lpuart4 { -+ dma-coherent; -+}; -+ -+&lpuart5 { -+ dma-coherent; -+}; -+ -+&ftm0 { -+ dma-coherent; -+}; -+ -+&wdog0 { -+ dma-coherent; -+}; -+ -+&edma0 { -+ dma-coherent; -+}; -+ -+&sata { -+ dma-coherent; -+}; -+ -+&qdma { -+ dma-coherent; -+}; -+ -+&msi1 { -+ dma-coherent; -+}; -+ -+&msi2 { -+ dma-coherent; -+}; -+ -+&msi3 { -+ dma-coherent; -+}; -+ -+&fman0 { -+ dma-coherent; -+}; -+ -+&ptp_timer0 { -+ dma-coherent; -+}; -+ -+&serdes1 { -+ dma-coherent; -+}; -+ -+&fsldpaa { -+ dma-coherent; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-usdpaa.dts -@@ -16,6 +16,7 @@ - fsl,bpid = <7>; - fsl,bpool-ethernet-cfg = <0 0 0 192 0 0xdeadbeef>; - fsl,bpool-thresholds = <0x400 0xc00 0x0 0x0>; -+ dma-coherent; - }; - - bp8: buffer-pool@8 { -@@ -23,6 +24,7 @@ - fsl,bpid = <8>; - fsl,bpool-ethernet-cfg = <0 0 0 576 0 0xabbaf00d>; - fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ dma-coherent; - }; - - bp9: buffer-pool@9 { -@@ -30,10 +32,12 @@ - fsl,bpid = <9>; - fsl,bpool-ethernet-cfg = <0 0 0 2048 0 0xfeedabba>; - fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ dma-coherent; - }; - - fsl,dpaa { - compatible = "fsl,ls1046a", "fsl,dpaa", "simple-bus"; -+ dma-coherent; - - ethernet@2 { - compatible = "fsl,dpa-ethernet-init"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0050-arm64-dts-lx2160a-add-interrupt-property-for-aquanti.patch b/target/linux/layerscape/patches-5.4/302-dts-0050-arm64-dts-lx2160a-add-interrupt-property-for-aquanti.patch deleted file mode 100644 index 7725311740..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0050-arm64-dts-lx2160a-add-interrupt-property-for-aquanti.patch +++ /dev/null @@ -1,32 +0,0 @@ -From e260d97c7875d5ef6aca11e49bf2784966a877c2 Mon Sep 17 00:00:00 2001 -From: Florin Chiculita -Date: Thu, 4 Apr 2019 17:44:46 +0300 -Subject: [PATCH] arm64: dts: lx2160a: add interrupt property for aquantia phy - -Add interrupt property for Aquantia AQR107 ethernet phy, currently -working in polling mode. - -Signed-off-by: Florin Chiculita ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -@@ -184,14 +184,14 @@ - aquantia_phy1: ethernet-phy@4 { - /* AQR107 PHY - "compatible" property not strictly needed */ - compatible = "ethernet-phy-ieee802.3-c45"; -+ interrupts = ; - reg = <0x4>; -- /* Poll mode - no "interrupts" property defined */ - }; - aquantia_phy2: ethernet-phy@5 { - /* AQR107 PHY - "compatible" property not strictly needed */ - compatible = "ethernet-phy-ieee802.3-c45"; -+ interrupts = ; - reg = <0x5>; -- /* Poll mode - no "interrupts" property defined */ - }; - }; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0051-arm64-dts-fsl-layerscape-fix-warnings-when-compiling.patch b/target/linux/layerscape/patches-5.4/302-dts-0051-arm64-dts-fsl-layerscape-fix-warnings-when-compiling.patch deleted file mode 100644 index 7ac2f3166b..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0051-arm64-dts-fsl-layerscape-fix-warnings-when-compiling.patch +++ /dev/null @@ -1,292 +0,0 @@ -From d949248dccef18f7257d8de0adfd67244955e7b7 Mon Sep 17 00:00:00 2001 -From: Pankaj Bansal -Date: Mon, 22 Apr 2019 16:22:49 +0530 -Subject: [PATCH] arm64: dts: fsl: layerscape: fix warnings when compiling dts - files - -when compiling dts file using DTC_FLAG='-@', the device tree compiler -reports these warnings: - -Warning (simple_bus_reg): /soc/mdio@0x8c0b000: simple-bus unit address -format error, expected "8c0b000" -Warning (unit_address_format): /pfe@04000000: unit name should not have -leading 0s - -Fixed the node names to silence these warnings. - -Signed-off-by: Pankaj Bansal ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 3 ++- - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 14 +++++++------- - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 22 +++++++++++----------- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 18 +++++++++--------- - 4 files changed, 29 insertions(+), 28 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -3,6 +3,7 @@ - * Device Tree Include file for Freescale Layerscape-1012A family SoC. - * - * Copyright 2016 Freescale Semiconductor, Inc. -+ * Copyright 2019 NXP - * - */ - -@@ -514,7 +515,7 @@ - }; - }; - -- pfe: pfe@04000000 { -+ pfe: pfe@4000000 { - compatible = "fsl,pfe"; - reg = <0x0 0x04000000 0x0 0xc00000>, /* AXI 16M */ - <0x0 0x83400000 0x0 0xc00000>; /* PFE DDR 12M */ ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -2,7 +2,7 @@ - /* - * Device Tree Include file for NXP Layerscape-1088A family SoC. - * -- * Copyright 2017 NXP -+ * Copyright 2017-2019 NXP - * - * Harninder Rai - * -@@ -310,7 +310,7 @@ - }; - - /* TODO: WRIOP (CCSR?) */ -- emdio1: mdio@0x8B96000 { /* WRIOP0: 0x8B8_0000, -+ emdio1: mdio@8B96000 { /* WRIOP0: 0x8B8_0000, - * E-MDIO1: 0x1_6000 - */ - compatible = "fsl,fman-memac-mdio"; -@@ -323,7 +323,7 @@ - #size-cells = <0>; - }; - -- emdio2: mdio@0x8B97000 { /* WRIOP0: 0x8B8_0000, -+ emdio2: mdio@8B97000 { /* WRIOP0: 0x8B8_0000, - * E-MDIO2: 0x1_7000 - */ - compatible = "fsl,fman-memac-mdio"; -@@ -335,7 +335,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio1: mdio@0x8c07000 { -+ pcs_mdio1: mdio@8c07000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c07000 0x0 0x1000>; - device_type = "mdio"; -@@ -345,7 +345,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio2: mdio@0x8c0b000 { -+ pcs_mdio2: mdio@8c0b000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c0b000 0x0 0x1000>; - device_type = "mdio"; -@@ -355,7 +355,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio3: mdio@0x8c0f000 { -+ pcs_mdio3: mdio@8c0f000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c0f000 0x0 0x1000>; - device_type = "mdio"; -@@ -365,7 +365,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio4: mdio@0x8c13000 { -+ pcs_mdio4: mdio@8c13000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c13000 0x0 0x1000>; - device_type = "mdio"; ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -3,7 +3,7 @@ - * Device Tree Include file for Freescale Layerscape-2080A family SoC. - * - * Copyright 2016 Freescale Semiconductor, Inc. -- * Copyright 2017 NXP -+ * Copyright 2017-2019 NXP - * - * Abhimanyu Saini - * -@@ -524,7 +524,7 @@ - }; - - /* TODO: WRIOP (CCSR?) */ -- emdio1: mdio@0x8B96000 { /* WRIOP0: 0x8B8_0000, -+ emdio1: mdio@8B96000 { /* WRIOP0: 0x8B8_0000, - * E-MDIO1: 0x1_6000 - */ - compatible = "fsl,fman-memac-mdio"; -@@ -537,7 +537,7 @@ - #size-cells = <0>; - }; - -- emdio2: mdio@0x8B97000 { /* WRIOP0: 0x8B8_0000, -+ emdio2: mdio@8B97000 { /* WRIOP0: 0x8B8_0000, - * E-MDIO2: 0x1_7000 - */ - compatible = "fsl,fman-memac-mdio"; -@@ -549,7 +549,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio1: mdio@0x8c07000 { -+ pcs_mdio1: mdio@8c07000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c07000 0x0 0x1000>; - device_type = "mdio"; -@@ -559,7 +559,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio2: mdio@0x8c0b000 { -+ pcs_mdio2: mdio@8c0b000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c0b000 0x0 0x1000>; - device_type = "mdio"; -@@ -569,7 +569,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio3: mdio@0x8c0f000 { -+ pcs_mdio3: mdio@8c0f000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c0f000 0x0 0x1000>; - device_type = "mdio"; -@@ -579,7 +579,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio4: mdio@0x8c13000 { -+ pcs_mdio4: mdio@8c13000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c13000 0x0 0x1000>; - device_type = "mdio"; -@@ -589,7 +589,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio5: mdio@0x8c17000 { -+ pcs_mdio5: mdio@8c17000 { - status = "disabled"; - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c17000 0x0 0x1000>; -@@ -600,7 +600,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio6: mdio@0x8c1b000 { -+ pcs_mdio6: mdio@8c1b000 { - status = "disabled"; - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c1b000 0x0 0x1000>; -@@ -611,7 +611,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio7: mdio@0x8c1f000 { -+ pcs_mdio7: mdio@8c1f000 { - status = "disabled"; - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c1f000 0x0 0x1000>; -@@ -622,7 +622,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio8: mdio@0x8c23000 { -+ pcs_mdio8: mdio@8c23000 { - status = "disabled"; - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c23000 0x0 0x1000>; ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -2,7 +2,7 @@ - // - // Device Tree Include file for Layerscape-LX2160A family SoC. - // --// Copyright 2018 NXP -+// Copyright 2018-2019 NXP - - #include - #include -@@ -500,7 +500,7 @@ - status = "disabled"; - }; - -- pcs_mdio1: mdio@0x8c07000 { -+ pcs_mdio1: mdio@8c07000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c07000 0x0 0x1000>; - device_type = "mdio"; -@@ -510,7 +510,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio2: mdio@0x8c0b000 { -+ pcs_mdio2: mdio@8c0b000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c0b000 0x0 0x1000>; - device_type = "mdio"; -@@ -520,7 +520,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio3: mdio@0x8c0f000 { -+ pcs_mdio3: mdio@8c0f000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c0f000 0x0 0x1000>; - device_type = "mdio"; -@@ -530,7 +530,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio4: mdio@0x8c13000 { -+ pcs_mdio4: mdio@8c13000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c13000 0x0 0x1000>; - device_type = "mdio"; -@@ -540,7 +540,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio5: mdio@0x8c17000 { -+ pcs_mdio5: mdio@8c17000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c17000 0x0 0x1000>; - device_type = "mdio"; -@@ -550,7 +550,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio6: mdio@0x8c1b000 { -+ pcs_mdio6: mdio@8c1b000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c1b000 0x0 0x1000>; - device_type = "mdio"; -@@ -560,7 +560,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio7: mdio@0x8c1f000 { -+ pcs_mdio7: mdio@8c1f000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c1f000 0x0 0x1000>; - device_type = "mdio"; -@@ -570,7 +570,7 @@ - #size-cells = <0>; - }; - -- pcs_mdio8: mdio@0x8c23000 { -+ pcs_mdio8: mdio@8c23000 { - compatible = "fsl,fman-memac-mdio"; - reg = <0x0 0x8c23000 0x0 0x1000>; - device_type = "mdio"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0052-arm64-dts-fsl-layerscape-fix-warnings-when-compiling.patch b/target/linux/layerscape/patches-5.4/302-dts-0052-arm64-dts-fsl-layerscape-fix-warnings-when-compiling.patch deleted file mode 100644 index bfe9ce6a45..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0052-arm64-dts-fsl-layerscape-fix-warnings-when-compiling.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 92aff696c8708ff5293eb000e98456e23afe1cb3 Mon Sep 17 00:00:00 2001 -From: Pankaj Bansal -Date: Mon, 22 Apr 2019 16:43:13 +0530 -Subject: [PATCH] arm64: dts: fsl: layerscape: fix warnings when compiling dts - files - -when compiling dts file using DTC_FLAG='-@', the device tree compiler -reports these warnings: - -Warning (alias_paths): /aliases: aliases property name must include -only lowercase and '-' - -Fixed the node aliases to silence these warnings. - -Signed-off-by: Pankaj Bansal ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts | 34 +++++++++++------------ - arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts | 28 +++++++++---------- - 2 files changed, 31 insertions(+), 31 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts -@@ -3,7 +3,7 @@ - * Device Tree Include file for Freescale Layerscape-1043A family SoC. - * - * Copyright 2014-2015 Freescale Semiconductor, Inc. -- * Copyright 2018 NXP -+ * Copyright 2018-2019 NXP - * - * Mingkai Hu - */ -@@ -24,22 +24,22 @@ - serial1 = &duart1; - serial2 = &duart2; - serial3 = &duart3; -- sgmii_riser_s1_p1 = &sgmii_phy_s1_p1; -- sgmii_riser_s2_p1 = &sgmii_phy_s2_p1; -- sgmii_riser_s3_p1 = &sgmii_phy_s3_p1; -- sgmii_riser_s4_p1 = &sgmii_phy_s4_p1; -- qsgmii_s1_p1 = &qsgmii_phy_s1_p1; -- qsgmii_s1_p2 = &qsgmii_phy_s1_p2; -- qsgmii_s1_p3 = &qsgmii_phy_s1_p3; -- qsgmii_s1_p4 = &qsgmii_phy_s1_p4; -- qsgmii_s2_p1 = &qsgmii_phy_s2_p1; -- qsgmii_s2_p2 = &qsgmii_phy_s2_p2; -- qsgmii_s2_p3 = &qsgmii_phy_s2_p3; -- qsgmii_s2_p4 = &qsgmii_phy_s2_p4; -- emi1_slot1 = &ls1043mdio_s1; -- emi1_slot2 = &ls1043mdio_s2; -- emi1_slot3 = &ls1043mdio_s3; -- emi1_slot4 = &ls1043mdio_s4; -+ sgmii-riser-s1-p1 = &sgmii_phy_s1_p1; -+ sgmii-riser-s2-p1 = &sgmii_phy_s2_p1; -+ sgmii-riser-s3-p1 = &sgmii_phy_s3_p1; -+ sgmii-riser-s4-p1 = &sgmii_phy_s4_p1; -+ qsgmii-s1-p1 = &qsgmii_phy_s1_p1; -+ qsgmii-s1-p2 = &qsgmii_phy_s1_p2; -+ qsgmii-s1-p3 = &qsgmii_phy_s1_p3; -+ qsgmii-s1-p4 = &qsgmii_phy_s1_p4; -+ qsgmii-s2-p1 = &qsgmii_phy_s2_p1; -+ qsgmii-s2-p2 = &qsgmii_phy_s2_p2; -+ qsgmii-s2-p3 = &qsgmii_phy_s2_p3; -+ qsgmii-s2-p4 = &qsgmii_phy_s2_p4; -+ emi1-slot1 = &ls1043mdio_s1; -+ emi1-slot2 = &ls1043mdio_s2; -+ emi1-slot3 = &ls1043mdio_s3; -+ emi1-slot4 = &ls1043mdio_s4; - }; - - chosen { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts -@@ -3,7 +3,7 @@ - * Device Tree Include file for Freescale Layerscape-1046A family SoC. - * - * Copyright 2016 Freescale Semiconductor, Inc. -- * Copyright 2018 NXP -+ * Copyright 2018-2019 NXP - * - * Shaohui Xie - */ -@@ -26,19 +26,19 @@ - serial2 = &duart2; - serial3 = &duart3; - -- emi1_slot1 = &ls1046mdio_s1; -- emi1_slot2 = &ls1046mdio_s2; -- emi1_slot4 = &ls1046mdio_s4; -- -- sgmii_s1_p1 = &sgmii_phy_s1_p1; -- sgmii_s1_p2 = &sgmii_phy_s1_p2; -- sgmii_s1_p3 = &sgmii_phy_s1_p3; -- sgmii_s1_p4 = &sgmii_phy_s1_p4; -- sgmii_s4_p1 = &sgmii_phy_s4_p1; -- qsgmii_s2_p1 = &qsgmii_phy_s2_p1; -- qsgmii_s2_p2 = &qsgmii_phy_s2_p2; -- qsgmii_s2_p3 = &qsgmii_phy_s2_p3; -- qsgmii_s2_p4 = &qsgmii_phy_s2_p4; -+ emi1-slot1 = &ls1046mdio_s1; -+ emi1-slot2 = &ls1046mdio_s2; -+ emi1-slot4 = &ls1046mdio_s4; -+ -+ sgmii-s1-p1 = &sgmii_phy_s1_p1; -+ sgmii-s1-p2 = &sgmii_phy_s1_p2; -+ sgmii-s1-p3 = &sgmii_phy_s1_p3; -+ sgmii-s1-p4 = &sgmii_phy_s1_p4; -+ sgmii-s4-p1 = &sgmii_phy_s4_p1; -+ qsgmii-s2-p1 = &qsgmii_phy_s2_p1; -+ qsgmii-s2-p2 = &qsgmii_phy_s2_p2; -+ qsgmii-s2-p3 = &qsgmii_phy_s2_p3; -+ qsgmii-s2-p4 = &qsgmii_phy_s2_p4; - }; - - chosen { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0053-sdk-arm64-dts-nxp-add-DPAA1-SDK-flavor-dts-files.patch b/target/linux/layerscape/patches-5.4/302-dts-0053-sdk-arm64-dts-nxp-add-DPAA1-SDK-flavor-dts-files.patch deleted file mode 100644 index 1e1b805ffb..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0053-sdk-arm64-dts-nxp-add-DPAA1-SDK-flavor-dts-files.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 13fdde4dfdccd567ae459db6e439a53496732748 Mon Sep 17 00:00:00 2001 -From: Pramod Kumar -Date: Wed, 8 May 2019 18:25:16 +0530 -Subject: [PATCH] sdk: arm64: dts: nxp: add DPAA1 SDK flavor dts files - -dts fsl-ls1046a-frwy-sdk.dts which enables sdk specific entries -dts fsl-ls1046a-frwy-usdpaa.dts which enables dpdk - -Signed-off-by: Vabhav Sharma -Signed-off-by: Pramod Kumar ---- - arch/arm64/boot/dts/freescale/Makefile | 2 + - .../boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts | 53 ++++++++++++ - .../boot/dts/freescale/fsl-ls1046a-frwy-usdpaa.dts | 99 ++++++++++++++++++++++ - 3 files changed, 154 insertions(+) - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-usdpaa.dts - ---- a/arch/arm64/boot/dts/freescale/Makefile -+++ b/arch/arm64/boot/dts/freescale/Makefile -@@ -13,6 +13,8 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1 - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb-sdk.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb-usdpaa.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-frwy.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-frwy-sdk.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-frwy-usdpaa.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-qds.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-qds-sdk.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-rdb.dtb ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts -@@ -0,0 +1,53 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for Freescale Layerscape-1046A family SoC. -+ * -+ * Copyright 2019 NXP. -+ * -+ */ -+ -+#include "fsl-ls1046a-frwy.dts" -+#include "qoriq-qman-portals-sdk.dtsi" -+#include "qoriq-bman-portals-sdk.dtsi" -+ -+&bman_fbpr { -+ compatible = "fsl,bman-fbpr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_fqd { -+ compatible = "fsl,qman-fqd"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_pfdr { -+ compatible = "fsl,qman-pfdr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+ -+&soc { -+#include "qoriq-dpaa-eth.dtsi" -+#include "qoriq-fman3-0-6oh.dtsi" -+}; -+ -+&fsldpaa { -+ ethernet@1 { -+ status = "disabled"; -+ }; -+ ethernet@2 { -+ status = "disabled"; -+ }; -+ ethernet@3 { -+ status = "disabled"; -+ }; -+ ethernet@6 { -+ status = "disabled"; -+ }; -+ ethernet@9 { -+ compatible = "fsl,dpa-ethernet"; -+ fsl,fman-mac = <&enet7>; -+ dma-coherent; -+ }; -+}; -+ -+&fman0 { -+ compatible = "fsl,fman", "simple-bus"; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-usdpaa.dts -@@ -0,0 +1,99 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for Freescale Layerscape-1046A family SoC. -+ * -+ * Copyright 2019 NXP. -+ * -+ */ -+ -+#include "fsl-ls1046a-frwy-sdk.dts" -+ -+&soc { -+ bp7: buffer-pool@7 { -+ compatible = "fsl,ls1046a-bpool", "fsl,bpool"; -+ fsl,bpid = <7>; -+ fsl,bpool-ethernet-cfg = <0 0 0 192 0 0xdeadbeef>; -+ fsl,bpool-thresholds = <0x400 0xc00 0x0 0x0>; -+ }; -+ -+ bp8: buffer-pool@8 { -+ compatible = "fsl,ls1046a-bpool", "fsl,bpool"; -+ fsl,bpid = <8>; -+ fsl,bpool-ethernet-cfg = <0 0 0 576 0 0xabbaf00d>; -+ fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ }; -+ -+ bp9: buffer-pool@9 { -+ compatible = "fsl,ls1046a-bpool", "fsl,bpool"; -+ fsl,bpid = <9>; -+ fsl,bpool-ethernet-cfg = <0 0 0 2048 0 0xfeedabba>; -+ fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ }; -+ -+ fsl,dpaa { -+ compatible = "fsl,ls1046a", "fsl,dpaa", "simple-bus"; -+ -+ ethernet@0 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x50 1 0x51 1>; -+ fsl,qman-frame-queues-tx = <0x70 1 0x71 1>; -+ }; -+ -+ ethernet@4 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x52 1 0x53 1>; -+ fsl,qman-frame-queues-tx = <0x72 1 0x73 1>; -+ }; -+ -+ ethernet@5 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x54 1 0x55 1>; -+ fsl,qman-frame-queues-tx = <0x74 1 0x75 1>; -+ }; -+ -+ ethernet@9 { -+ compatible = "fsl,dpa-ethernet-init"; -+ fsl,bman-buffer-pools = <&bp7 &bp8 &bp9>; -+ fsl,qman-frame-queues-rx = <0x56 1 0x57 1>; -+ fsl,qman-frame-queues-tx = <0x76 1 0x77 1>; -+ }; -+ -+ dpa-fman0-oh@2 { -+ compatible = "fsl,dpa-oh"; -+ /* Define frame queues for the OH port*/ -+ /* */ -+ fsl,qman-frame-queues-oh = <0x60 1 0x61 1>; -+ fsl,fman-oh-port = <&fman0_oh2>; -+ }; -+ }; -+}; -+/ { -+ reserved-memory { -+ #address-cells = <2>; -+ #size-cells = <2>; -+ ranges; -+ /* For legacy usdpaa based use-cases, update the size and -+ alignment parameters. e.g. to allocate 256 MB memory: -+ size = <0 0x10000000>; -+ alignment = <0 0x10000000>; -+ */ -+ -+ usdpaa_mem: usdpaa_mem { -+ compatible = "fsl,usdpaa-mem"; -+ alloc-ranges = <0 0 0x10000 0>; -+ size = <0 0x1000>; -+ alignment = <0 0x1000>; -+ }; -+ }; -+}; -+ -+&fman0 { -+ fman0_oh2: port@83000 { -+ cell-index = <1>; -+ compatible = "fsl,fman-port-oh"; -+ reg = <0x83000 0x1000>; -+ }; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0054-arm64-dts-nxp-frwy-ls1046a-add-support-for-micron-no.patch b/target/linux/layerscape/patches-5.4/302-dts-0054-arm64-dts-nxp-frwy-ls1046a-add-support-for-micron-no.patch deleted file mode 100644 index 7050dd3764..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0054-arm64-dts-nxp-frwy-ls1046a-add-support-for-micron-no.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 3c013ab682fe1e6ca0473141f03f26e2f47980ad Mon Sep 17 00:00:00 2001 -From: Pramod Kumar -Date: Fri, 10 May 2019 14:33:37 +0530 -Subject: [PATCH] arm64: dts: nxp: frwy-ls1046a: add support for micron nor - flash - -add micron nor flash support for ls1046a frwy board. - -Signed-off-by: Ashish Kumar -Signed-off-by: Pramod Kumar ---- - arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts -@@ -106,6 +106,23 @@ - - }; - -+ -+&qspi { -+ num-cs = <1>; -+ bus-num = <0>; -+ status = "okay"; -+ -+ qflash0: flash@0 { -+ compatible = "jedec,spi-nor"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <50000000>; -+ reg = <0>; -+ spi-rx-bus-width = <4>; -+ spi-tx-bus-width = <4>; -+ }; -+}; -+ - #include "fsl-ls1046-post.dtsi" - - &fman0 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0055-arm64-dts-ls1028a-Add-PCIe-controller-DT-nodes.patch b/target/linux/layerscape/patches-5.4/302-dts-0055-arm64-dts-ls1028a-Add-PCIe-controller-DT-nodes.patch deleted file mode 100644 index 2543c879a9..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0055-arm64-dts-ls1028a-Add-PCIe-controller-DT-nodes.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 25291f86f449c4488a0a46b1e6b3ce3b83dbf1f9 Mon Sep 17 00:00:00 2001 -From: Xiaowei Bao -Date: Wed, 15 May 2019 10:14:30 +0800 -Subject: [PATCH] arm64: dts: ls1028a: Add PCIe controller DT nodes - -LS1028a implements 2 PCIe 3.0 controllers. - -Signed-off-by: Xiaowei Bao ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 50 ++++++++++++++++++++++++++ - 1 file changed, 50 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -649,6 +649,56 @@ - }; - }; - -+ pcie@3400000 { -+ compatible = "fsl,ls1028a-pcie"; -+ reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ -+ 0x80 0x00000000 0x0 0x00002000>; /* configuration space */ -+ reg-names = "regs", "config"; -+ interrupts = , /* PME interrupt */ -+ ; /* aer interrupt */ -+ interrupt-names = "pme", "aer"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ dma-coherent; -+ bus-range = <0x0 0xff>; -+ ranges = <0x81000000 0x0 0x00000000 0x80 0x00010000 0x0 0x00010000 /* downstream I/O */ -+ 0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ -+ msi-parent = <&its>; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0000 0 0 1 &gic GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 2 &gic GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 3 &gic GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 4 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ }; -+ -+ pcie@3500000 { -+ compatible = "fsl,ls1028a-pcie"; -+ reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ -+ 0x88 0x00000000 0x0 0x00002000>; /* configuration space */ -+ reg-names = "regs", "config"; -+ interrupts = , -+ ; -+ interrupt-names = "pme", "aer"; -+ #address-cells = <3>; -+ #size-cells = <2>; -+ device_type = "pci"; -+ dma-coherent; -+ bus-range = <0x0 0xff>; -+ ranges = <0x81000000 0x0 0x00000000 0x88 0x00010000 0x0 0x00010000 /* downstream I/O */ -+ 0x82000000 0x0 0x40000000 0x88 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ -+ msi-parent = <&its>; -+ #interrupt-cells = <1>; -+ interrupt-map-mask = <0 0 0 7>; -+ interrupt-map = <0000 0 0 1 &gic GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 2 &gic GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 3 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 4 &gic GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; -+ status = "disabled"; -+ }; -+ - pcie@1f0000000 { /* Integrated Endpoint Root Complex */ - compatible = "pci-host-ecam-generic"; - reg = <0x01 0xf0000000 0x0 0x100000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0056-arm64-dts-lx2160a-Enable-usb3-lpm-capable-for-usb3-n.patch b/target/linux/layerscape/patches-5.4/302-dts-0056-arm64-dts-lx2160a-Enable-usb3-lpm-capable-for-usb3-n.patch deleted file mode 100644 index 1f8a9e6630..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0056-arm64-dts-lx2160a-Enable-usb3-lpm-capable-for-usb3-n.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 74f9f7ee3f4b2e88bd29e7ac3dbc6a8ffe2e97f9 Mon Sep 17 00:00:00 2001 -From: Ran Wang -Date: Wed, 15 May 2019 13:33:49 +0800 -Subject: [PATCH] arm64: dts: lx2160a: Enable usb3-lpm-capable for usb3 node - -Enable USB3 HW LPM feature for lx2160a and active patch for -snps erratum A-010131. It will disable U1/U2 temperary when -initiate U3 request. - -Signed-off-by: Ran Wang ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -843,6 +843,8 @@ - interrupts = ; - dr_mode = "host"; - snps,quirk-frame-length-adjustment = <0x20>; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; -@@ -855,6 +857,8 @@ - interrupts = ; - dr_mode = "host"; - snps,quirk-frame-length-adjustment = <0x20>; -+ usb3-lpm-capable; -+ snps,dis-u1u2-when-u3-quirk; - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0057-arm64-dts-fsl-lx2160a-add-flexcan-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0057-arm64-dts-fsl-lx2160a-add-flexcan-node.patch deleted file mode 100644 index c85139f216..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0057-arm64-dts-fsl-lx2160a-add-flexcan-node.patch +++ /dev/null @@ -1,103 +0,0 @@ -From c2046901f933b0e1c87c5cbdab4ba27a3b66317e Mon Sep 17 00:00:00 2001 -From: Pankaj Bansal -Date: Wed, 8 May 2019 17:49:14 +0530 -Subject: [PATCH] arm64: dts: fsl: lx2160a: add flexcan node - -Add flexcan node in LX2160A SOC file as well as in QDS and RDB files. -The device tree bindings used can be referred from -Documentation/devicetree/bindings/net/can/fsl-flexcan.txt - -Signed-off-by: Pankaj Bansal ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts | 10 +++++++++- - arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts | 18 +++++++++++++++++- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 18 ++++++++++++++++++ - 3 files changed, 44 insertions(+), 2 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -@@ -2,7 +2,7 @@ - // - // Device Tree file for LX2160AQDS - // --// Copyright 2018 NXP -+// Copyright 2018-2019 NXP - - /dts-v1/; - -@@ -155,6 +155,14 @@ - }; - }; - -+&can0 { -+ status = "okay"; -+}; -+ -+&can1 { -+ status = "okay"; -+}; -+ - &crypto { - status = "okay"; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -@@ -2,7 +2,7 @@ - // - // Device Tree file for LX2160ARDB - // --// Copyright 2018 NXP -+// Copyright 2018-2019 NXP - - /dts-v1/; - -@@ -31,6 +31,22 @@ - }; - }; - -+&can0 { -+ status = "okay"; -+ -+ can-transceiver { -+ max-bitrate = <5000000>; -+ }; -+}; -+ -+&can1 { -+ status = "okay"; -+ -+ can-transceiver { -+ max-bitrate = <5000000>; -+ }; -+}; -+ - &crypto { - status = "okay"; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -753,6 +753,24 @@ - status = "disabled"; - }; - -+ can0: can@2180000 { -+ compatible = "fsl,lx2160ar1-flexcan"; -+ reg = <0x0 0x2180000 0x0 0x10000>; -+ interrupts = ; -+ clocks = <&sysclk>, <&clockgen 4 7>; -+ clock-names = "ipg", "per"; -+ status = "disabled"; -+ }; -+ -+ can1: can@2190000 { -+ compatible = "fsl,lx2160ar1-flexcan"; -+ reg = <0x0 0x2190000 0x0 0x10000>; -+ interrupts = ; -+ clocks = <&sysclk>, <&clockgen 4 7>; -+ clock-names = "ipg", "per"; -+ status = "disabled"; -+ }; -+ - uart0: serial@21c0000 { - compatible = "arm,sbsa-uart","arm,pl011"; - reg = <0x0 0x21c0000 0x0 0x1000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0058-arm64-dts-fsl-ls1028a-add-flexcan-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0058-arm64-dts-fsl-ls1028a-add-flexcan-node.patch deleted file mode 100644 index 8ca0801422..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0058-arm64-dts-fsl-ls1028a-add-flexcan-node.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 3724107421d95c5a46b19b950b04de2a05c1f757 Mon Sep 17 00:00:00 2001 -From: Pankaj Bansal -Date: Wed, 8 May 2019 17:49:14 +0530 -Subject: [PATCH] arm64: dts: fsl: ls1028a: add flexcan node - -Add flexcan node in LS1028A SOC file as well as in QDS and RDB files. -The device tree bindings used can be referred from -Documentation/devicetree/bindings/net/can/fsl-flexcan.txt - -Signed-off-by: Pankaj Bansal ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 10 +++++++++- - arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts | 18 +++++++++++++++++- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 22 +++++++++++++++++++++- - 3 files changed, 47 insertions(+), 3 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -@@ -2,7 +2,7 @@ - /* - * Device Tree file for NXP LS1028A QDS Board. - * -- * Copyright 2018 NXP -+ * Copyright 2018-2019 NXP - * - * Harninder Rai - * -@@ -107,6 +107,14 @@ - }; - }; - -+&can0 { -+ status = "okay"; -+}; -+ -+&can1 { -+ status = "okay"; -+}; -+ - &duart0 { - status = "okay"; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -@@ -2,7 +2,7 @@ - /* - * Device Tree file for NXP LS1028A RDB Board. - * -- * Copyright 2018 NXP -+ * Copyright 2018-2019 NXP - * - * Harninder Rai - * -@@ -152,6 +152,22 @@ - }; - }; - -+&can0 { -+ status = "okay"; -+ -+ can-transceiver { -+ max-bitrate = <5000000>; -+ }; -+}; -+ -+&can1 { -+ status = "okay"; -+ -+ can-transceiver { -+ max-bitrate = <5000000>; -+ }; -+}; -+ - &duart0 { - status = "okay"; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -2,7 +2,7 @@ - /* - * Device Tree Include file for NXP Layerscape-1028A family SoC. - * -- * Copyright 2018 NXP -+ * Copyright 2018-2019 NXP - * - * Harninder Rai - * diff --git a/target/linux/layerscape/patches-5.4/302-dts-0059-arm64-dts-fsl-ls1046-Modify-the-qspi-flash-frequency.patch b/target/linux/layerscape/patches-5.4/302-dts-0059-arm64-dts-fsl-ls1046-Modify-the-qspi-flash-frequency.patch deleted file mode 100644 index 00aaaee297..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0059-arm64-dts-fsl-ls1046-Modify-the-qspi-flash-frequency.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0a4e4723a1765770bb04ec4a5ad427b2c97627b6 Mon Sep 17 00:00:00 2001 -From: Pankaj Bansal -Date: Tue, 21 May 2019 20:26:29 +0530 -Subject: [PATCH] arm64: dts: fsl: ls1046: Modify the qspi flash frequency - -The qspi flash in ls1046a based QDS and RDB boards can operate -at 50MHz frequency. -Therefore, update the maximum supported freq in their respective -dts files. - -Signed-off-by: Pankaj Bansal ---- - arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts | 2 +- - arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 5 +++-- - 2 files changed, 4 insertions(+), 3 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts -@@ -184,7 +184,7 @@ - compatible = "spansion,m25p80"; - #address-cells = <1>; - #size-cells = <1>; -- spi-max-frequency = <20000000>; -+ spi-max-frequency = <50000000>; - spi-rx-bus-width = <4>; - spi-tx-bus-width = <4>; - reg = <0>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts -@@ -3,6 +3,7 @@ - * Device Tree Include file for Freescale Layerscape-1046A family SoC. - * - * Copyright 2016 Freescale Semiconductor, Inc. -+ * Copyright 2019 NXP - * - * Mingkai Hu - */ -@@ -101,7 +102,7 @@ - compatible = "spansion,m25p80"; - #address-cells = <1>; - #size-cells = <1>; -- spi-max-frequency = <20000000>; -+ spi-max-frequency = <50000000>; - spi-rx-bus-width = <4>; - spi-tx-bus-width = <4>; - reg = <0>; -@@ -111,7 +112,7 @@ - compatible = "spansion,m25p80"; - #address-cells = <1>; - #size-cells = <1>; -- spi-max-frequency = <20000000>; -+ spi-max-frequency = <50000000>; - spi-rx-bus-width = <4>; - spi-tx-bus-width = <4>; - reg = <1>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0060-arm64-dts-ls1028a-add-flexspi-nodes.patch b/target/linux/layerscape/patches-5.4/302-dts-0060-arm64-dts-ls1028a-add-flexspi-nodes.patch deleted file mode 100644 index 84aa2390a8..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0060-arm64-dts-ls1028a-add-flexspi-nodes.patch +++ /dev/null @@ -1,87 +0,0 @@ -From b94cbaaa2facfdc6aa49d6f323da251f9e91d4ba Mon Sep 17 00:00:00 2001 -From: Xiaowei Bao -Date: Tue, 14 May 2019 18:17:31 +0800 -Subject: [PATCH] arm64: dts: ls1028a: add flexspi nodes - -Add fspi node property for LS1028A SoC for FlexSPI driver. -Property added for the FlexSPI controller and for the connected -slave device for the LS1028ARDB and LS1028AQDS target. -This is having one SPI-NOR flash device, mt35xu02g connected at -CS0. - -Signed-off-by: Xiaowei Bao ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 15 +++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts | 15 +++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 12 ++++++++++++ - 3 files changed, 42 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -@@ -226,6 +226,21 @@ - phy-connection-type = "rgmii-id"; - }; - -+&fspi { -+ status = "okay"; -+ mt35xu02g: flash@0 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ m25p,fast-read; -+ spi-max-frequency = <20000000>; -+ reg = <0>; -+ /* The following setting enables 1-1-8 (CMD-ADDR-DATA) mode */ -+ spi-rx-bus-width = <8>; /* 8 SPI Rx lines */ -+ spi-tx-bus-width = <1>; /* 1 SPI Tx line */ -+ }; -+}; -+ - &sai1 { - status = "okay"; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -@@ -168,6 +168,21 @@ - }; - }; - -+&fspi { -+ status = "okay"; -+ mt35xu02g: flash@0 { -+ compatible = "spansion,m25p80"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ m25p,fast-read; -+ spi-max-frequency = <20000000>; -+ reg = <0>; -+ /* The following setting enables 1-1-8 (CMD-ADDR-DATA) mode */ -+ spi-rx-bus-width = <8>; /* 8 SPI Rx lines */ -+ spi-tx-bus-width = <1>; /* 1 SPI Tx line */ -+ }; -+}; -+ - &duart0 { - status = "okay"; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -180,6 +180,18 @@ - clocks = <&sysclk>; - }; - -+ fspi: spi@20c0000 { -+ compatible = "nxp,lx2160a-fspi"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0 0x20c0000 0x0 0x10000>, -+ <0x0 0x20000000 0x0 0x10000000>; -+ reg-names = "FSPI", "FSPI-memory"; -+ interrupts = <0 25 0x4>; /* Level high type */ -+ clocks = <&clockgen 4 3>, <&clockgen 4 3>; -+ clock-names = "fspi_en", "fspi"; -+ }; -+ - i2c0: i2c@2000000 { - compatible = "fsl,vf610-i2c"; - #address-cells = <1>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0061-sdk-dts-ls1046-drop-smmu-from-the-frwy-sdk-dtses.patch b/target/linux/layerscape/patches-5.4/302-dts-0061-sdk-dts-ls1046-drop-smmu-from-the-frwy-sdk-dtses.patch deleted file mode 100644 index a29ca7530b..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0061-sdk-dts-ls1046-drop-smmu-from-the-frwy-sdk-dtses.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 68148cb462754f0f79b77aa56ea0e8ec899ead36 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 28 May 2019 13:35:56 +0300 -Subject: [PATCH] sdk: dts: ls1046: drop smmu from the frwy sdk dtses - -Drop the smmu from the frwy and frwy-usdpaa versions of the SDK device -trees because SMMU is supported only for the upstream version of the -dpaa ethernet drivers. - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts | 14 ++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-usdpaa.dts | 14 ++++++++++++++ - 2 files changed, 28 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts -@@ -26,6 +26,20 @@ - &soc { - #include "qoriq-dpaa-eth.dtsi" - #include "qoriq-fman3-0-6oh.dtsi" -+ -+ pcie@3400000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ pcie@3500000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ pcie@3600000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ /delete-node/ iommu@9000000; - }; - - &fsldpaa { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-usdpaa.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-usdpaa.dts -@@ -69,6 +69,20 @@ - fsl,fman-oh-port = <&fman0_oh2>; - }; - }; -+ -+ pcie@3400000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ pcie@3500000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ pcie@3600000 { -+ /delete-property/ iommu-map; -+ }; -+ -+ /delete-node/ iommu@9000000; - }; - / { - reserved-memory { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0062-sdk-dts-ls1046frwy-move-dma-coherent-from-soc-to-its.patch b/target/linux/layerscape/patches-5.4/302-dts-0062-sdk-dts-ls1046frwy-move-dma-coherent-from-soc-to-its.patch deleted file mode 100644 index c2e08730b2..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0062-sdk-dts-ls1046frwy-move-dma-coherent-from-soc-to-its.patch +++ /dev/null @@ -1,235 +0,0 @@ -From 7d5fcedd45e066db0d2735a753a86af31ba44722 Mon Sep 17 00:00:00 2001 -From: Ran Wang -Date: Wed, 29 May 2019 16:18:06 +0800 -Subject: [PATCH] sdk: dts: ls1046frwy move dma-coherent from soc to its child - nodes - -Since SMMU is not supported for SDK version, USB function will down if -still apply property 'dma-coherent' in scope of soc (USB driver is not -ready to support it alone) in SDK device trees, decide to remove it. -And add dma-coherent on other non-USB child nodes under soc. - -Signed-off-by: Ran Wang ---- - .../boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts | 174 +++++++++++++++++++++ - .../boot/dts/freescale/fsl-ls1046a-frwy-usdpaa.dts | 4 + - 2 files changed, 178 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts -@@ -24,6 +24,8 @@ - }; - - &soc { -+/delete-property/ dma-coherent; -+ - #include "qoriq-dpaa-eth.dtsi" - #include "qoriq-fman3-0-6oh.dtsi" - -@@ -65,3 +67,175 @@ - &fman0 { - compatible = "fsl,fman", "simple-bus"; - }; -+ -+&clockgen { -+ dma-coherent; -+}; -+ -+&scfg { -+ dma-coherent; -+}; -+ -+&crypto { -+ dma-coherent; -+}; -+ -+&dcfg { -+ dma-coherent; -+}; -+ -+&ifc { -+ dma-coherent; -+}; -+ -+&qspi { -+ dma-coherent; -+}; -+ -+&esdhc { -+ dma-coherent; -+}; -+ -+&ddr { -+ dma-coherent; -+}; -+ -+&tmu { -+ dma-coherent; -+}; -+ -+&qman { -+ dma-coherent; -+}; -+ -+&bman { -+ dma-coherent; -+}; -+ -+&bportals { -+ dma-coherent; -+}; -+ -+&qportals { -+ dma-coherent; -+}; -+ -+&dspi { -+ dma-coherent; -+}; -+ -+&i2c0 { -+ dma-coherent; -+}; -+ -+&i2c1 { -+ dma-coherent; -+}; -+ -+&i2c2 { -+ dma-coherent; -+}; -+ -+&i2c3 { -+ dma-coherent; -+}; -+ -+&duart0 { -+ dma-coherent; -+}; -+ -+&duart1 { -+ dma-coherent; -+}; -+ -+&duart2 { -+ dma-coherent; -+}; -+ -+&duart3 { -+ dma-coherent; -+}; -+ -+&gpio0 { -+ dma-coherent; -+}; -+ -+&gpio1 { -+ dma-coherent; -+}; -+ -+&gpio2 { -+ dma-coherent; -+}; -+ -+&gpio3 { -+ dma-coherent; -+}; -+ -+&lpuart0 { -+ dma-coherent; -+}; -+ -+&lpuart1 { -+ dma-coherent; -+}; -+ -+&lpuart2 { -+ dma-coherent; -+}; -+ -+&lpuart3 { -+ dma-coherent; -+}; -+ -+&lpuart4 { -+ dma-coherent; -+}; -+ -+&lpuart5 { -+ dma-coherent; -+}; -+ -+&ftm0 { -+ dma-coherent; -+}; -+ -+&wdog0 { -+ dma-coherent; -+}; -+ -+&edma0 { -+ dma-coherent; -+}; -+ -+&sata { -+ dma-coherent; -+}; -+ -+&qdma { -+ dma-coherent; -+}; -+ -+&msi1 { -+ dma-coherent; -+}; -+ -+&msi2 { -+ dma-coherent; -+}; -+ -+&msi3 { -+ dma-coherent; -+}; -+ -+&fman0 { -+ dma-coherent; -+}; -+ -+&ptp_timer0 { -+ dma-coherent; -+}; -+ -+&fsldpaa { -+ dma-coherent; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-usdpaa.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-usdpaa.dts -@@ -14,6 +14,7 @@ - fsl,bpid = <7>; - fsl,bpool-ethernet-cfg = <0 0 0 192 0 0xdeadbeef>; - fsl,bpool-thresholds = <0x400 0xc00 0x0 0x0>; -+ dma-coherent; - }; - - bp8: buffer-pool@8 { -@@ -21,6 +22,7 @@ - fsl,bpid = <8>; - fsl,bpool-ethernet-cfg = <0 0 0 576 0 0xabbaf00d>; - fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ dma-coherent; - }; - - bp9: buffer-pool@9 { -@@ -28,10 +30,12 @@ - fsl,bpid = <9>; - fsl,bpool-ethernet-cfg = <0 0 0 2048 0 0xfeedabba>; - fsl,bpool-thresholds = <0x100 0x300 0x0 0x0>; -+ dma-coherent; - }; - - fsl,dpaa { - compatible = "fsl,ls1046a", "fsl,dpaa", "simple-bus"; -+ dma-coherent; - - ethernet@0 { - compatible = "fsl,dpa-ethernet-init"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0063-arm64-dts-fsl-remove-backplane-support.patch b/target/linux/layerscape/patches-5.4/302-dts-0063-arm64-dts-fsl-remove-backplane-support.patch deleted file mode 100644 index 749df043e0..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0063-arm64-dts-fsl-remove-backplane-support.patch +++ /dev/null @@ -1,574 +0,0 @@ -From 278bacf54eabe391159cef3112f8e8bf0fa7b891 Mon Sep 17 00:00:00 2001 -From: Florinel Iordache -Date: Mon, 27 May 2019 15:57:05 +0300 -Subject: [PATCH] arm64: dts: fsl: remove backplane support - -Remove entire backplane support from device tree for all supported platforms - -Signed-off-by: Florinel Iordache ---- - .../boot/dts/freescale/fsl-ls1046a-qds-sdk.dts | 4 - - .../boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts | 34 -------- - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 5 -- - arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts | 26 ------- - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 46 ----------- - arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts | 58 -------------- - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 90 ---------------------- - arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts | 60 --------------- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 86 --------------------- - .../boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi | 4 +- - .../boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi | 4 +- - 11 files changed, 4 insertions(+), 413 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds-sdk.dts -@@ -259,10 +259,6 @@ pcie@3600000 { - dma-coherent; - }; - --&serdes1 { -- dma-coherent; --}; -- - &fsldpaa { - dma-coherent; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts -@@ -100,36 +100,6 @@ pcie@3600000 { - compatible = "fsl,fman", "simple-bus"; - }; - --&mdio9 { -- pcsphy6: ethernet-phy@0 { -- backplane-mode = "10gbase-kr"; -- compatible = "ethernet-phy-ieee802.3-c45"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0x8C0 0x40>; /* lane D */ -- }; --}; -- --&mdio10 { -- pcsphy7: ethernet-phy@0 { -- backplane-mode = "10gbase-kr"; -- compatible = "ethernet-phy-ieee802.3-c45"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0x880 0x40>; /* lane C */ -- }; --}; -- --/* Update MAC connections to backplane PHYs -- * &mac9 { -- * phy-handle = <&pcsphy6>; -- *}; -- * -- *&mac10 { -- * phy-handle = <&pcsphy7>; -- *}; --*/ -- - &clockgen { - dma-coherent; - }; -@@ -298,10 +268,6 @@ pcie@3600000 { - dma-coherent; - }; - --&serdes1 { -- dma-coherent; --}; -- - &fsldpaa { - dma-coherent; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -680,11 +680,6 @@ - ; - }; - -- serdes1: serdes@1ea0000 { -- reg = <0x0 0x1ea0000 0 0x00002000>; -- compatible = "fsl,serdes-10g"; -- }; -- - pcie@3400000 { - compatible = "fsl,ls1046a-pcie"; - reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts -@@ -170,29 +170,3 @@ - &sata { - status = "okay"; - }; -- --&pcs_mdio1 { -- pcs_phy1: ethernet-phy@0 { -- backplane-mode = "10gbase-kr"; -- compatible = "ethernet-phy-ieee802.3-c45"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0x840 0x40>;/* lane B */ -- }; --}; -- --&pcs_mdio2 { -- pcs_phy2: ethernet-phy@0 { -- backplane-mode = "10gbase-kr"; -- compatible = "ethernet-phy-ieee802.3-c45"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0x800 0x40>;/* lane A */ -- }; --}; -- --/* Update DPMAC connections to backplane PHYs, under SerDes 0x1D_0xXX. -- * &dpmac1 { -- * phy-handle = <&pcs_phy1>; -- * }; -- */ ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -183,12 +183,6 @@ - little-endian; - }; - -- serdes1: serdes@1ea0000 { -- compatible = "fsl,serdes-10g"; -- reg = <0x0 0x1ea0000 0 0x00002000>; -- little-endian; -- }; -- - tmu: tmu@1f80000 { - compatible = "fsl,qoriq-tmu"; - reg = <0x0 0x1f80000 0x0 0x10000>; -@@ -333,46 +327,6 @@ - - #address-cells = <1>; - #size-cells = <0>; -- }; -- -- pcs_mdio1: mdio@8c07000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c07000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio2: mdio@8c0b000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c0b000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio3: mdio@8c0f000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c0f000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio4: mdio@8c13000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c13000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; - }; - - ifc: ifc@2240000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls2088a-qds.dts -@@ -71,64 +71,6 @@ - }; - }; - --&pcs_mdio1 { -- pcs_phy1: ethernet-phy@0 { -- backplane-mode = "10gbase-kr"; -- compatible = "ethernet-phy-ieee802.3-c45"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0x9C0 0x40>;/* lane H */ -- }; --}; -- --&pcs_mdio2 { -- pcs_phy2: ethernet-phy@0 { -- backplane-mode = "10gbase-kr"; -- compatible = "ethernet-phy-ieee802.3-c45"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0x980 0x40>;/* lane G */ -- }; --}; -- --&pcs_mdio3 { -- pcs_phy3: ethernet-phy@0 { -- backplane-mode = "10gbase-kr"; -- compatible = "ethernet-phy-ieee802.3-c45"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0x940 0x40>;/* lane F */ -- }; --}; -- --&pcs_mdio4 { -- pcs_phy4: ethernet-phy@0 { -- backplane-mode = "10gbase-kr"; -- compatible = "ethernet-phy-ieee802.3-c45"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0x900 0x40>;/* lane E */ -- }; --}; -- --/* Update DPMAC connections to backplane PHYs, under SerDes 0x2a_0xXX. -- * &dpmac1 { -- * phy-handle = <&pcs_phy1>; -- * }; -- * -- * &dpmac2 { -- * phy-handle = <&pcs_phy2>; -- * }; -- * -- * &dpmac3 { -- * phy-handle = <&pcs_phy3>; -- * }; -- * -- * &dpmac4 { -- * phy-handle = <&pcs_phy4>; -- * }; -- */ -- - /* Update DPMAC connections to external PHYs, under SerDes 0x2a_0x49. */ - &dpmac9 { - phy-handle = <&mdio0_phy12>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -549,90 +549,6 @@ - #size-cells = <0>; - }; - -- pcs_mdio1: mdio@8c07000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c07000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio2: mdio@8c0b000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c0b000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio3: mdio@8c0f000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c0f000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio4: mdio@8c13000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c13000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio5: mdio@8c17000 { -- status = "disabled"; -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c17000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio6: mdio@8c1b000 { -- status = "disabled"; -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c1b000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio7: mdio@8c1f000 { -- status = "disabled"; -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c1f000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio8: mdio@8c23000 { -- status = "disabled"; -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c23000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- - i2c0: i2c@2000000 { - status = "disabled"; - compatible = "fsl,vf610-i2c", "fsl,ls208xa-vf610-i2c"; -@@ -834,12 +750,6 @@ - snps,host-vbus-glitches; - }; - -- serdes1: serdes@1ea0000 { -- compatible = "fsl,serdes-10g"; -- reg = <0x0 0x1ea0000 0 0x00002000>; -- little-endian; -- }; -- - ccn@4000000 { - compatible = "arm,ccn-504"; - reg = <0x0 0x04000000 0x0 0x01000000>; ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-qds.dts -@@ -316,46 +316,6 @@ - status = "okay"; - }; - --&pcs_mdio1 { -- pcs_phy1: ethernet-phy@0 { -- compatible = "ethernet-phy-ieee802.3-c45"; -- backplane-mode = "40gbase-kr"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0xF00 0xE00 0xD00 0xC00>; /* lanes H, G, F, E */ -- }; --}; -- --&pcs_mdio2 { -- pcs_phy2: ethernet-phy@0 { -- compatible = "ethernet-phy-ieee802.3-c45"; -- backplane-mode = "40gbase-kr"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0xB00 0xA00 0x900 0x800>; /* lanes D, C, B, A */ -- }; --}; -- --&pcs_mdio3 { -- pcs_phy3: ethernet-phy@0 { -- compatible = "ethernet-phy-ieee802.3-c45"; -- backplane-mode = "10gbase-kr"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0xF00 0x100>; /* lane H */ -- }; --}; -- --&pcs_mdio4 { -- pcs_phy4: ethernet-phy@0 { -- compatible = "ethernet-phy-ieee802.3-c45"; -- backplane-mode = "10gbase-kr"; -- reg = <0x0>; -- fsl,lane-handle = <&serdes1>; -- fsl,lane-reg = <0xE00 0x100>; /* lane G */ -- }; --}; -- - &sata0 { - status = "okay"; - }; -@@ -371,23 +331,3 @@ - &sata3 { - status = "okay"; - }; -- --/* Update DPMAC connections to 40G backplane PHYs -- * &dpmac1 { -- * phy-handle = <&pcs_phy1>; -- * }; -- * -- * &dpmac2 { -- * phy-handle = <&pcs_phy2>; -- * }; -- */ -- --/* Update DPMAC connections to 10G backplane PHYs -- * &dpmac3 { -- * phy-handle = <&pcs_phy3>; -- * }; -- * -- * &dpmac4 { -- * phy-handle = <&pcs_phy4>; -- * }; -- */ ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -500,92 +500,6 @@ - status = "disabled"; - }; - -- pcs_mdio1: mdio@8c07000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c07000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio2: mdio@8c0b000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c0b000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio3: mdio@8c0f000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c0f000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio4: mdio@8c13000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c13000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio5: mdio@8c17000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c17000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio6: mdio@8c1b000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c1b000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio7: mdio@8c1f000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c1f000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- pcs_mdio8: mdio@8c23000 { -- compatible = "fsl,fman-memac-mdio"; -- reg = <0x0 0x8c23000 0x0 0x1000>; -- device_type = "mdio"; -- little-endian; -- -- #address-cells = <1>; -- #size-cells = <0>; -- }; -- -- serdes1: serdes@1ea0000 { -- compatible = "fsl,serdes-28g"; -- reg = <0x0 0x1ea0000 0 0x00002000>; -- little-endian; -- }; -- - i2c0: i2c@2000000 { - compatible = "fsl,vf610-i2c"; - #address-cells = <1>; ---- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-0.dtsi -@@ -22,7 +22,7 @@ fman@1a00000 { - fsl,qman-channel-id = <0x800>; - }; - -- mac9: ethernet@f0000 { -+ ethernet@f0000 { - cell-index = <0x8>; - compatible = "fsl,fman-memac"; - reg = <0xf0000 0x1000>; -@@ -30,7 +30,7 @@ fman@1a00000 { - pcsphy-handle = <&pcsphy6>; - }; - -- mdio9: mdio@f1000 { -+ mdio@f1000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; ---- a/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi -+++ b/arch/arm64/boot/dts/freescale/qoriq-fman3-0-10g-1.dtsi -@@ -22,7 +22,7 @@ fman@1a00000 { - fsl,qman-channel-id = <0x801>; - }; - -- mac10: ethernet@f2000 { -+ ethernet@f2000 { - cell-index = <0x9>; - compatible = "fsl,fman-memac"; - reg = <0xf2000 0x1000>; -@@ -30,7 +30,7 @@ fman@1a00000 { - pcsphy-handle = <&pcsphy7>; - }; - -- mdio10: mdio@f3000 { -+ mdio@f3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0064-arm64-dts-lx2160a-update-interrupt-property-for-Aqua.patch b/target/linux/layerscape/patches-5.4/302-dts-0064-arm64-dts-lx2160a-update-interrupt-property-for-Aqua.patch deleted file mode 100644 index e5abac75a8..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0064-arm64-dts-lx2160a-update-interrupt-property-for-Aqua.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e463f4a9d933d2d62a065bba356a9eb04a9f3ac0 Mon Sep 17 00:00:00 2001 -From: Florin Chiculita -Date: Tue, 11 Jun 2019 23:53:45 +0300 -Subject: [PATCH] arm64: dts: lx2160a: update interrupt property for Aquantia - phy - -Update Aquantia AQR107 nodes interrupt property. - -Signed-off-by: Florin Chiculita ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -@@ -200,13 +200,13 @@ - aquantia_phy1: ethernet-phy@4 { - /* AQR107 PHY - "compatible" property not strictly needed */ - compatible = "ethernet-phy-ieee802.3-c45"; -- interrupts = ; -+ interrupts = ; - reg = <0x4>; - }; - aquantia_phy2: ethernet-phy@5 { - /* AQR107 PHY - "compatible" property not strictly needed */ - compatible = "ethernet-phy-ieee802.3-c45"; -- interrupts = ; -+ interrupts = ; - reg = <0x5>; - }; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0065-arm64-dts-ls1028a-Update-fspi-reg-properties.patch b/target/linux/layerscape/patches-5.4/302-dts-0065-arm64-dts-ls1028a-Update-fspi-reg-properties.patch deleted file mode 100644 index 577dd372e6..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0065-arm64-dts-ls1028a-Update-fspi-reg-properties.patch +++ /dev/null @@ -1,21 +0,0 @@ -From bfd089c26a8b3c1eb83c94dc0f72c0f80fb7e5ef Mon Sep 17 00:00:00 2001 -From: Kuldeep Singh -Date: Fri, 14 Jun 2019 12:34:14 +0530 -Subject: [PATCH] arm64: dts: ls1028a: Update fspi reg properties - -Signed-off-by: Kuldeep Singh ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -186,7 +186,7 @@ - #size-cells = <0>; - reg = <0x0 0x20c0000 0x0 0x10000>, - <0x0 0x20000000 0x0 0x10000000>; -- reg-names = "FSPI", "FSPI-memory"; -+ reg-names = "fspi_base", "fspi_mmap"; - interrupts = <0 25 0x4>; /* Level high type */ - clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "fspi_en", "fspi"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0066-arm64-dts-ls1028a-add-gpu-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0066-arm64-dts-ls1028a-add-gpu-node.patch deleted file mode 100644 index c429b7ca1e..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0066-arm64-dts-ls1028a-add-gpu-node.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 3e04a861ff536927ede8e826b7c4a5bf6a80dda7 Mon Sep 17 00:00:00 2001 -From: Yuantian Tang -Date: Tue, 18 Jun 2019 01:29:49 -0400 -Subject: [PATCH] arm64: dts: ls1028a: add gpu node - -Add GPU dts node to enable GPU feature. - -Signed-off-by: Yuantian Tang ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -536,6 +536,16 @@ - clock-names = "wdog_clk", "apb_pclk"; - }; - -+ gpu@f0c0000 { -+ compatible = "fsl,ls1028a-gpu"; -+ reg = <0x0 0x0f0c0000 0x0 0x10000>, -+ <0x0 0x80000000 0x0 0x80000000>, -+ <0x0 0x0 0x0 0x3000000>; -+ reg-names = "base", "phys_baseaddr", -+ "contiguous_mem"; -+ interrupts = ; -+ }; -+ - sai1: audio-controller@f100000 { - #sound-dai-cells = <0>; - compatible = "fsl,vf610-sai"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0067-arm64-dts-fsl-add-optee-node-for-ls1028.patch b/target/linux/layerscape/patches-5.4/302-dts-0067-arm64-dts-fsl-add-optee-node-for-ls1028.patch deleted file mode 100644 index 570a010bb0..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0067-arm64-dts-fsl-add-optee-node-for-ls1028.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 1021f327657a464fbe8bd9eab927f18b8cf7556e Mon Sep 17 00:00:00 2001 -From: Sahil Malhotra -Date: Sat, 3 Aug 2019 09:45:28 +0530 -Subject: [PATCH] arm64: dts: fsl: add optee node for ls1028 - -For enabling OP-TEE on LS1028, need to add optee node -in DTS - -Signed-off-by: Sahil Malhotra ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -769,6 +769,13 @@ - }; - }; - -+ firmware { -+ optee { -+ compatible = "linaro,optee-tz"; -+ method = "smc"; -+ }; -+ }; -+ - malidp0: display@f080000 { - compatible = "arm,mali-dp500"; - reg = <0x0 0xf080000 0x0 0x10000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0068-arm64-dts-lx2160a-Update-phy-mode-for-Aquantia-PHYs.patch b/target/linux/layerscape/patches-5.4/302-dts-0068-arm64-dts-lx2160a-Update-phy-mode-for-Aquantia-PHYs.patch deleted file mode 100644 index f227f82438..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0068-arm64-dts-lx2160a-Update-phy-mode-for-Aquantia-PHYs.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 6915b8ddc149601e6f0baf4836f0f9f18e3ee25f Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 24 Jul 2019 20:22:57 +0300 -Subject: [PATCH] arm64: dts: lx2160a: Update phy mode for Aquantia PHYs - -The Aquantia driver does not allow xgmii mode anymore for -the AQR107 PHYs. Use the correct usxgmii mode instead. - -Signed-off-by: Ioana Radulescu ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts -@@ -220,12 +220,12 @@ - - &dpmac3 { - phy-handle = <&aquantia_phy1>; -- phy-connection-type = "xgmii"; -+ phy-connection-type = "usxgmii"; - }; - - &dpmac4 { - phy-handle = <&aquantia_phy2>; -- phy-connection-type = "xgmii"; -+ phy-connection-type = "usxgmii"; - }; - - &dpmac5 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0069-arm64-dts-ls1028a-Add-ftm_alarm0-DT-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0069-arm64-dts-ls1028a-Add-ftm_alarm0-DT-node.patch deleted file mode 100644 index b5193a5310..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0069-arm64-dts-ls1028a-Add-ftm_alarm0-DT-node.patch +++ /dev/null @@ -1,46 +0,0 @@ -From cc4f01aa78bfbebd7bdb52b4d873b5c9a332319e Mon Sep 17 00:00:00 2001 -From: Biwen Li -Date: Thu, 27 Jun 2019 14:24:29 +0800 -Subject: [PATCH] arm64: dts: ls1028a: Add ftm_alarm0 DT node - -The patch adds ftm_alarm0 DT node for LS1028ARDB board -FlexTimer1 module is used to wakeup the system - -Signed-off-by: Biwen Li ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -17,6 +17,10 @@ - #address-cells = <2>; - #size-cells = <2>; - -+ aliases { -+ rtc1 = &ftm_alarm0; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -767,6 +771,19 @@ - little-endian; - }; - }; -+ -+ rcpm: rcpm@1e34040 { -+ compatible = "fsl,ls1028a-rcpm", "fsl,qoriq-rcpm-2.1+"; -+ reg = <0x0 0x1e34040 0x0 0x1c>; -+ #fsl,rcpm-wakeup-cells = <7>; -+ }; -+ -+ ftm_alarm0: timer@2800000 { -+ compatible = "fsl,ls1028a-ftm-alarm"; -+ reg = <0x0 0x2800000 0x0 0x10000>; -+ fsl,rcpm-wakeup = <&rcpm 0x0 0x0 0x0 0x0 0x4000 0x0 0x0>; -+ interrupts = ; -+ }; - }; - - firmware { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0070-arm64-dts-ls1012a-ls1043a-ls1046a-ls1088a-ls208xa-re.patch b/target/linux/layerscape/patches-5.4/302-dts-0070-arm64-dts-ls1012a-ls1043a-ls1046a-ls1088a-ls208xa-re.patch deleted file mode 100644 index 78713d778e..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0070-arm64-dts-ls1012a-ls1043a-ls1046a-ls1088a-ls208xa-re.patch +++ /dev/null @@ -1,297 +0,0 @@ -From c97c6ebf6fd6a6ff72bd7d58a12de0c07f14953e Mon Sep 17 00:00:00 2001 -From: Biwen Li -Date: Thu, 27 Jun 2019 15:02:44 +0800 -Subject: [PATCH] arm64: dts: ls1012a/ls1043a/ls1046a/ls1088a/ls208xa: replace - ftm0 with ftm_alarm0 - -The patch replaces ftm0 with ftm_alarm0 DT node - - replace ftm0 with ftm_alarm0 - - add new rcpm node - - remove old rcpm node - - aliases ftm_alarm0 as rtc1 - -Signed-off-by: Biwen Li ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 23 +++++++++++---------- - .../boot/dts/freescale/fsl-ls1043a-qds-sdk.dts | 2 +- - .../boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts | 2 +- - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 24 +++++++++++++--------- - .../boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts | 2 +- - .../boot/dts/freescale/fsl-ls1046a-qds-sdk.dts | 2 +- - .../boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts | 2 +- - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 24 ++++++++++++++-------- - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 20 ++++++++++++------ - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 12 +++++++++-- - 10 files changed, 70 insertions(+), 43 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -23,6 +23,7 @@ - rtic-c = &rtic_c; - rtic-d = &rtic_d; - sec-mon = &sec_mon; -+ rtc1 = &ftm_alarm0; - }; - - cpus { -@@ -290,15 +291,21 @@ - #thermal-sensor-cells = <1>; - }; - -- ftm0: ftm0@29d0000 { -- compatible = "fsl,ftm-alarm"; -- reg = <0x0 0x29d0000 0x0 0x10000>, -- <0x0 0x1ee2140 0x0 0x4>; -- reg-names = "ftm", "FlexTimer1"; -+ rcpm: rcpm@1ee2140 { -+ compatible = "fsl,ls1012a-rcpm", "fsl,qoriq-rcpm-2.1+"; -+ reg = <0x0 0x1ee2140 0x0 0x4>; -+ #fsl,rcpm-wakeup-cells = <1>; -+ }; -+ -+ ftm_alarm0: timer@29d0000 { -+ compatible = "fsl,ls1012a-ftm-alarm"; -+ reg = <0x0 0x29d0000 0x0 0x10000>; -+ fsl,rcpm-wakeup = <&rcpm 0x20000>; - interrupts = <0 86 0x4>; - big-endian; - }; - -+ - i2c0: i2c@2180000 { - compatible = "fsl,vf610-i2c", "fsl,ls1012a-vf610-i2c"; - #address-cells = <1>; -@@ -497,12 +504,6 @@ - <0000 0 0 4 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - }; -- -- rcpm: rcpm@1ee2000 { -- compatible = "fsl,ls1012a-rcpm", "fsl,qoriq-rcpm-2.1"; -- reg = <0x0 0x1ee2000 0x0 0x1000>; -- fsl,#rcpm-wakeup-cells = <1>; -- }; - }; - - reserved-memory { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds-sdk.dts -@@ -226,7 +226,7 @@ pcie@3600000 { - dma-coherent; - }; - --&ftm0 { -+&ftm_alarm0 { - dma-coherent; - }; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb-sdk.dts -@@ -221,7 +221,7 @@ pcie@3600000 { - dma-coherent; - }; - --&ftm0 { -+&ftm_alarm0 { - dma-coherent; - }; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -27,6 +27,7 @@ - ethernet4 = &enet4; - ethernet5 = &enet5; - ethernet6 = &enet6; -+ rtc1 = &ftm_alarm0; - }; - - cpus { -@@ -661,16 +662,6 @@ - status = "disabled"; - }; - -- ftm0: ftm0@29d0000 { -- compatible = "fsl,ftm-alarm"; -- reg = <0x0 0x29d0000 0x0 0x10000>, -- <0x0 0x1ee2140 0x0 0x4>; -- reg-names = "ftm", "FlexTimer1"; -- interrupts = <0 86 0x4>; -- big-endian; -- status = "okay"; -- }; -- - wdog0: wdog@2ad0000 { - compatible = "fsl,ls1043a-wdt", "fsl,imx21-wdt"; - reg = <0x0 0x2ad0000 0x0 0x10000>; -@@ -875,6 +866,19 @@ - big-endian; - }; - -+ rcpm: rcpm@1ee2140 { -+ compatible = "fsl,ls1043a-rcpm", "fsl,qoriq-rcpm-2.1+"; -+ reg = <0x0 0x1ee2140 0x0 0x4>; -+ #fsl,rcpm-wakeup-cells = <1>; -+ }; -+ -+ ftm_alarm0: timer@29d0000 { -+ compatible = "fsl,ls1043a-ftm-alarm"; -+ reg = <0x0 0x29d0000 0x0 0x10000>; -+ fsl,rcpm-wakeup = <&rcpm 0x20000>; -+ interrupts = <0 86 0x4>; -+ big-endian; -+ }; - }; - - firmware { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy-sdk.dts -@@ -196,7 +196,7 @@ - dma-coherent; - }; - --&ftm0 { -+&ftm_alarm0 { - dma-coherent; - }; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds-sdk.dts -@@ -223,7 +223,7 @@ pcie@3600000 { - dma-coherent; - }; - --&ftm0 { -+&ftm_alarm0 { - dma-coherent; - }; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb-sdk.dts -@@ -228,7 +228,7 @@ pcie@3600000 { - dma-coherent; - }; - --&ftm0 { -+&ftm_alarm0 { - dma-coherent; - }; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -28,6 +28,7 @@ - ethernet5 = &enet5; - ethernet6 = &enet6; - ethernet7 = &enet7; -+ rtc1 = &ftm_alarm0; - }; - - cpus { -@@ -561,15 +562,6 @@ - status = "disabled"; - }; - -- ftm0: ftm0@29d0000 { -- compatible = "fsl,ftm-alarm"; -- reg = <0x0 0x29d0000 0x0 0x10000>, -- <0x0 0x1ee2140 0x0 0x4>; -- reg-names = "ftm", "FlexTimer1"; -- interrupts = ; -- big-endian; -- }; -- - wdog0: watchdog@2ad0000 { - compatible = "fsl,imx21-wdt"; - reg = <0x0 0x2ad0000 0x0 0x10000>; -@@ -811,6 +803,20 @@ - queue-sizes = <64 64>; - big-endian; - }; -+ -+ rcpm: rcpm@1ee208c { -+ compatible = "fsl,ls1046a-rcpm", "fsl,qoriq-rcpm-2.1+"; -+ reg = <0x0 0x1ee208c 0x0 0x4>; -+ #fsl,rcpm-wakeup-cells = <1>; -+ }; -+ -+ ftm_alarm0: timer@29d0000 { -+ compatible = "fsl,ls1046a-ftm-alarm"; -+ reg = <0x0 0x29d0000 0x0 0x10000>; -+ fsl,rcpm-wakeup = <&rcpm 0x20000>; -+ interrupts = ; -+ big-endian; -+ }; - }; - - reserved-memory { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -18,6 +18,7 @@ - - aliases { - crypto = &crypto; -+ rtc1 = &ftm_alarm0; - }; - - cpus { -@@ -339,12 +340,6 @@ - status = "disabled"; - }; - -- ftm0: ftm0@2800000 { -- compatible = "fsl,ftm-alarm"; -- reg = <0x0 0x2800000 0x0 0x10000>; -- interrupts = <0 44 4>; -- }; -- - i2c0: i2c@2000000 { - compatible = "fsl,vf610-i2c", "fsl,ls1088a-vf610-i2c"; - #address-cells = <1>; -@@ -792,6 +787,19 @@ - }; - }; - }; -+ -+ rcpm: rcpm@1e34040 { -+ compatible = "fsl,ls1088a-rcpm", "fsl,qoriq-rcpm-2.1+"; -+ reg = <0x0 0x1e34040 0x0 0x18>; -+ #fsl,rcpm-wakeup-cells = <6>; -+ }; -+ -+ ftm_alarm0: timer@2800000 { -+ compatible = "fsl,ls1088a-ftm-alarm"; -+ reg = <0x0 0x2800000 0x0 0x10000>; -+ fsl,rcpm-wakeup = <&rcpm 0x0 0x0 0x0 0x0 0x4000 0x0>; -+ interrupts = <0 44 4>; -+ }; - }; - - firmware { ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -24,6 +24,7 @@ - serial1 = &serial1; - serial2 = &serial2; - serial3 = &serial3; -+ rtc1 = &ftm_alarm0; - }; - - cpu: cpus { -@@ -756,9 +757,16 @@ - interrupts = <0 12 4>; - }; - -- ftm0: ftm0@2800000 { -- compatible = "fsl,ftm-alarm"; -+ rcpm: rcpm@1e34040 { -+ compatible = "fsl,ls208xa-rcpm", "fsl,qoriq-rcpm-2.1+"; -+ reg = <0x0 0x1e34040 0x0 0x18>; -+ #fsl,rcpm-wakeup-cells = <6>; -+ }; -+ -+ ftm_alarm0: timer@2800000 { -+ compatible = "fsl,ls208xa-ftm-alarm"; - reg = <0x0 0x2800000 0x0 0x10000>; -+ fsl,rcpm-wakeup = <&rcpm 0x0 0x0 0x0 0x0 0x4000 0x0>; - interrupts = <0 44 4>; - }; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0071-arm-dts-ls1021a-replace-ftm0-with-ftm_alarm0-DT-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0071-arm-dts-ls1021a-replace-ftm0-with-ftm_alarm0-DT-node.patch deleted file mode 100644 index 2d63cc0b55..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0071-arm-dts-ls1021a-replace-ftm0-with-ftm_alarm0-DT-node.patch +++ /dev/null @@ -1,63 +0,0 @@ -From f3a115bd1372e774979ecb81919664279b81810e Mon Sep 17 00:00:00 2001 -From: Biwen Li -Date: Fri, 28 Jun 2019 16:36:20 +0800 -Subject: [PATCH] arm: dts: ls1021a: replace ftm0 with ftm_alarm0 DT node - -The patch replaces ftm0 with ftm_alarm0 DT node - - remove old ftm0 node - - add rcpm node - - add ftm_alarm0 node - - aliases ftm_alarm0 as rtc1 - -Signed-off-by: Biwen Li ---- - arch/arm/boot/dts/ls1021a.dtsi | 24 ++++++++++++++---------- - 1 file changed, 14 insertions(+), 10 deletions(-) - ---- a/arch/arm/boot/dts/ls1021a.dtsi -+++ b/arch/arm/boot/dts/ls1021a.dtsi -@@ -66,6 +66,7 @@ - serial4 = &lpuart4; - serial5 = &lpuart5; - sysclk = &sysclk; -+ rtc1 = &ftm_alarm0; - }; - - cpus { -@@ -549,16 +550,6 @@ - status = "disabled"; - }; - -- ftm0: ftm0@29d0000 { -- compatible = "fsl,ftm-alarm"; -- reg = <0x0 0x29d0000 0x0 0x10000>, -- <0x0 0x1ee2140 0x0 0x4>; -- reg-names = "ftm", "FlexTimer1"; -- interrupts = ; -- big-endian; -- status = "okay"; -- }; -- - pwm1: pwm@29e0000 { - compatible = "fsl,vf610-ftm-pwm"; - #pwm-cells = <3>; -@@ -970,6 +961,19 @@ - big-endian; - }; - -+ rcpm: rcpm@1ee2140 { -+ compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+"; -+ reg = <0x0 0x1ee2140 0x0 0x8>; -+ #fsl,rcpm-wakeup-cells = <2>; -+ }; -+ -+ ftm_alarm0: timer0@29d0000 { -+ compatible = "fsl,ls1021a-ftm-alarm"; -+ reg = <0x0 0x29d0000 0x0 0x10000>; -+ fsl,rcpm-wakeup = <&rcpm 0x0 0x20000000>; -+ interrupts = ; -+ big-endian; -+ }; - }; - - thermal-zones { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0072-arm64-ls1028ardb-Add-support-DP-nodes-for-LS1028ARDB.patch b/target/linux/layerscape/patches-5.4/302-dts-0072-arm64-ls1028ardb-Add-support-DP-nodes-for-LS1028ARDB.patch deleted file mode 100644 index 2b8564fc14..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0072-arm64-ls1028ardb-Add-support-DP-nodes-for-LS1028ARDB.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b778a15d8781263bb768c404965dd5ec4bbe80c8 Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Wed, 17 Jul 2019 15:04:13 +0800 -Subject: [PATCH] arm64: ls1028ardb: Add support DP nodes for LS1028ARDB - -This patch add HDP PHY Controller related nodes on the LS1028ARDB. - -Signed-off-by: Alison Wang -Signed-off-by: Wen He ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -@@ -215,3 +215,15 @@ - &sata { - status = "okay"; - }; -+ -+&hdptx0 { -+ fsl,no_edid; -+ resolution = "3840x2160@60", -+ "1920x1080@60", -+ "1280x720@60", -+ "720x480@60"; -+ lane_mapping = <0x4e>; -+ edp_link_rate = <0x6>; -+ edp_num_lanes = <0x4>; -+ status = "okay"; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0073-arm64-ls1028aqds-Add-support-DP-nodes-for-LS1028AQDS.patch b/target/linux/layerscape/patches-5.4/302-dts-0073-arm64-ls1028aqds-Add-support-DP-nodes-for-LS1028AQDS.patch deleted file mode 100644 index 3ccd41f57c..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0073-arm64-ls1028aqds-Add-support-DP-nodes-for-LS1028AQDS.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 3e4421bc3d2055d599c65d5519b1eb63c0b9468e Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Wed, 17 Jul 2019 15:06:06 +0800 -Subject: [PATCH] arm64: ls1028aqds: Add support DP nodes for LS1028AQDS - -This patch add HDP PHY Controller related nodes on the LS1028AQDS. - -Signed-off-by: Alison Wang -Signed-off-by: Wen He ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -@@ -248,3 +248,15 @@ - &sata { - status = "okay"; - }; -+ -+&hdptx0 { -+ fsl,no_edid; -+ resolution = "3840x2160@60", -+ "1920x1080@60", -+ "1280x720@60", -+ "720x480@60"; -+ lane_mapping = <0x4e>; -+ edp_link_rate = <0x6>; -+ edp_num_lanes = <0x4>; -+ status = "okay"; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0074-arm64-dts-fsl-ls1028a-Add-Felix-switch-port-DT-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0074-arm64-dts-fsl-ls1028a-Add-Felix-switch-port-DT-node.patch deleted file mode 100644 index 3ed283edfd..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0074-arm64-dts-fsl-ls1028a-Add-Felix-switch-port-DT-node.patch +++ /dev/null @@ -1,102 +0,0 @@ -From f5f011742b6ec9ad1db54de9e8296f1d5a3ede8a Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Fri, 14 Jun 2019 19:24:27 +0300 -Subject: [PATCH] arm64: dts: fsl: ls1028a: Add Felix switch port DT node - -Add the switch device node, available on PF5, so that the -switch port sub-nodes (net devices) can be linked to -corresponding board specific phy nodes (external ports) or -have their link mode defined (internal ports). -The switch device features 6 ports, 4 with external links -and 2 internally facing to the ls1028a SoC and connected via -fixed links to 2 internal enetc ethernet contoller ports. -Add the corresponding enetc internal port device nodes, -mapped to PF2 and PF6 PCIe functions. -And don't forget to enable the 4MB BAR4 in the root complex -ECAM space, where the switch registers are mapped. - -Signed-off-by: Claudiu Manoil ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 58 +++++++++++++++++++++++++- - 1 file changed, 57 insertions(+), 1 deletion(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -748,7 +748,9 @@ - /* PF1: VF0-1 BAR0 - non-prefetchable memory */ - 0x82000000 0x0 0x00000000 0x1 0xf8210000 0x0 0x020000 - /* PF1: VF0-1 BAR2 - prefetchable memory */ -- 0xc2000000 0x0 0x00000000 0x1 0xf8230000 0x0 0x020000>; -+ 0xc2000000 0x0 0x00000000 0x1 0xf8230000 0x0 0x020000 -+ /* BAR4 (PF5) - non-prefetchable memory */ -+ 0x82000000 0x0 0x00000000 0x1 0xfc000000 0x0 0x400000>; - - enetc_port0: ethernet@0,0 { - compatible = "fsl,enetc"; -@@ -764,12 +766,66 @@ - #address-cells = <1>; - #size-cells = <0>; - }; -+ ethernet@0,2 { -+ compatible = "fsl,enetc"; -+ reg = <0x000200 0 0 0 0>; -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; - ethernet@0,4 { - compatible = "fsl,enetc-ptp"; - reg = <0x000400 0 0 0 0>; - clocks = <&clockgen 2 3>; - little-endian; - }; -+ switch@0,5 { -+ compatible = "mscc,felix-switch"; -+ reg = <0x000500 0 0 0 0>; -+ -+ ports { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* external ports */ -+ switch_port0: port@0 { -+ reg = <0>; -+ }; -+ switch_port1: port@1 { -+ reg = <1>; -+ }; -+ switch_port2: port@2 { -+ reg = <2>; -+ }; -+ switch_port3: port@3 { -+ reg = <3>; -+ }; -+ /* internal to-cpu ports */ -+ port@4 { -+ reg = <4>; -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ port@5 { -+ reg = <5>; -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ }; -+ }; -+ ethernet@0,6 { -+ compatible = "fsl,enetc"; -+ reg = <0x000600 0 0 0 0>; -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; - }; - - rcpm: rcpm@1e34040 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0075-arm64-dts-fsl-ls1028a-Enable-switch-PHYs-on-RDB.patch b/target/linux/layerscape/patches-5.4/302-dts-0075-arm64-dts-fsl-ls1028a-Enable-switch-PHYs-on-RDB.patch deleted file mode 100644 index ff8dca6ba6..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0075-arm64-dts-fsl-ls1028a-Enable-switch-PHYs-on-RDB.patch +++ /dev/null @@ -1,62 +0,0 @@ -From aafb63a926b790b64a5ed83377f07b90ec7ba7c0 Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Thu, 20 Jun 2019 19:53:55 +0300 -Subject: [PATCH] arm64: dts: fsl: ls1028a: Enable switch PHYs on RDB - -Just link the switch PHY nodes to the central MDIO -controller PCIe endpoint node on ls1028 (implemented -as PF3) so that PHYs are configurable via MDIO. - -Signed-off-by: Claudiu Manoil ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts | 39 +++++++++++++++++++++++ - 1 file changed, 39 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -@@ -208,6 +208,45 @@ - status = "disabled"; - }; - -+&enetc_mdio_pf3 { -+ qsgmii_phy1: ethernet-phy@4 { -+ reg = <0x10>; -+ }; -+ -+ qsgmii_phy2: ethernet-phy@5 { -+ reg = <0x11>; -+ }; -+ -+ qsgmii_phy3: ethernet-phy@6 { -+ reg = <0x12>; -+ }; -+ -+ qsgmii_phy4: ethernet-phy@7 { -+ reg = <0x13>; -+ }; -+}; -+ -+/* l2switch ports */ -+&switch_port0 { -+ phy-handle = <&qsgmii_phy1>; -+ phy-connection-type = "qsgmii"; -+}; -+ -+&switch_port1 { -+ phy-handle = <&qsgmii_phy2>; -+ phy-connection-type = "qsgmii"; -+}; -+ -+&switch_port2 { -+ phy-handle = <&qsgmii_phy3>; -+ phy-connection-type = "qsgmii"; -+}; -+ -+&switch_port3 { -+ phy-handle = <&qsgmii_phy4>; -+ phy-connection-type = "qsgmii"; -+}; -+ - &sai4 { - status = "okay"; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0076-arm64-dts-ls1028a-support-Felix-PF5-INTB-interrupt.patch b/target/linux/layerscape/patches-5.4/302-dts-0076-arm64-dts-ls1028a-support-Felix-PF5-INTB-interrupt.patch deleted file mode 100644 index 2fd0819014..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0076-arm64-dts-ls1028a-support-Felix-PF5-INTB-interrupt.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 28aa7c7f0da70b7410926ec5f5737e2b78e0cdfa Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Thu, 18 Jul 2019 15:26:03 +0800 -Subject: [PATCH] arm64: dts: ls1028a: support Felix/PF5 INTB interrupt - -The INTB interrupt includes, -- PTP timestamp ready in timestamp FIFO -- TSN Preemption - -Signed-off-by: Alex Marginean -Signed-off-by: Yangbo Lu ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -730,7 +730,6 @@ - reg = <0x01 0xf0000000 0x0 0x100000>; - #address-cells = <3>; - #size-cells = <2>; -- #interrupt-cells = <1>; - msi-parent = <&its>; - device_type = "pci"; - bus-range = <0x0 0x0>; -@@ -783,6 +782,8 @@ - switch@0,5 { - compatible = "mscc,felix-switch"; - reg = <0x000500 0 0 0 0>; -+ /* IEP INT_B */ -+ interrupts = ; - - ports { - #address-cells = <1>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0077-arm64-dts-ls1028a-Add-ethernet-property-for-l2switch.patch b/target/linux/layerscape/patches-5.4/302-dts-0077-arm64-dts-ls1028a-Add-ethernet-property-for-l2switch.patch deleted file mode 100644 index 9589af90ea..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0077-arm64-dts-ls1028a-Add-ethernet-property-for-l2switch.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 51efcd436c30e7085b36264771edce03316013d1 Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Thu, 1 Aug 2019 19:44:00 +0300 -Subject: [PATCH] arm64: dts: ls1028a: Add ethernet property for l2switch CPU - port - -This enables the CPU traffic for the l2 switch (aka the -CPU frame injection/ extraction feature). - -Signed-off-by: Claudiu Manoil ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -812,6 +812,7 @@ - }; - port@5 { - reg = <5>; -+ ethernet = <&enetc_port3>; - fixed-link { - speed = <1000>; - full-duplex; -@@ -819,7 +820,7 @@ - }; - }; - }; -- ethernet@0,6 { -+ enetc_port3: ethernet@0,6 { - compatible = "fsl,enetc"; - reg = <0x000600 0 0 0 0>; - fixed-link { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0078-arm64-dts-fix-endianness-of-rcpm.patch b/target/linux/layerscape/patches-5.4/302-dts-0078-arm64-dts-fix-endianness-of-rcpm.patch deleted file mode 100644 index 0f57b17f3d..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0078-arm64-dts-fix-endianness-of-rcpm.patch +++ /dev/null @@ -1,44 +0,0 @@ -From fdba7c7bc334f72bd8641bbd63f3596ba68650c1 Mon Sep 17 00:00:00 2001 -From: Biwen Li -Date: Thu, 8 Aug 2019 12:13:02 +0800 -Subject: [PATCH] arm64: dts: fix endianness of rcpm - -Add little-endian property of rcpm for ls1028a,ls1088a,ls208xa - -Signed-off-by: Biwen Li ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 1 + - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 1 + - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 1 + - 3 files changed, 3 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -834,6 +834,7 @@ - compatible = "fsl,ls1028a-rcpm", "fsl,qoriq-rcpm-2.1+"; - reg = <0x0 0x1e34040 0x0 0x1c>; - #fsl,rcpm-wakeup-cells = <7>; -+ little-endian; - }; - - ftm_alarm0: timer@2800000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -792,6 +792,7 @@ - compatible = "fsl,ls1088a-rcpm", "fsl,qoriq-rcpm-2.1+"; - reg = <0x0 0x1e34040 0x0 0x18>; - #fsl,rcpm-wakeup-cells = <6>; -+ little-endian; - }; - - ftm_alarm0: timer@2800000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -761,6 +761,7 @@ - compatible = "fsl,ls208xa-rcpm", "fsl,qoriq-rcpm-2.1+"; - reg = <0x0 0x1e34040 0x0 0x18>; - #fsl,rcpm-wakeup-cells = <6>; -+ little-endian; - }; - - ftm_alarm0: timer@2800000 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0079-arm64-dts-ls1028a-Fix-interrupt-map-property-of-PCIe.patch b/target/linux/layerscape/patches-5.4/302-dts-0079-arm64-dts-ls1028a-Fix-interrupt-map-property-of-PCIe.patch deleted file mode 100644 index 9f1fcc6a60..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0079-arm64-dts-ls1028a-Fix-interrupt-map-property-of-PCIe.patch +++ /dev/null @@ -1,45 +0,0 @@ -From e41ad4213ce6742646c9dfed661289e69d5af5c1 Mon Sep 17 00:00:00 2001 -From: Hou Zhiqiang -Date: Fri, 2 Aug 2019 16:42:53 +0800 -Subject: [PATCH] arm64: dts: ls1028a: Fix interrupt-map property of PCIe nodes - -The current interrupt-map entries lost the 'parent unit address', -it will result in fail to allocate legacy INTx interrupts. - -Signed-off-by: Hou Zhiqiang ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -693,10 +693,10 @@ - msi-parent = <&its>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; -- interrupt-map = <0000 0 0 1 &gic GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, -- <0000 0 0 2 &gic GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, -- <0000 0 0 3 &gic GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>, -- <0000 0 0 4 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; -+ interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 2 &gic 0 0 GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 3 &gic 0 0 GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 4 &gic 0 0 GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - }; - -@@ -718,10 +718,10 @@ - msi-parent = <&its>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; -- interrupt-map = <0000 0 0 1 &gic GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>, -- <0000 0 0 2 &gic GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, -- <0000 0 0 3 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, -- <0000 0 0 4 &gic GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; -+ interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 2 &gic 0 0 GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 3 &gic 0 0 GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>, -+ <0000 0 0 4 &gic 0 0 GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - }; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0080-arm64-dts-ls1028a-rdb-enable-emmc-hs400-mode.patch b/target/linux/layerscape/patches-5.4/302-dts-0080-arm64-dts-ls1028a-rdb-enable-emmc-hs400-mode.patch deleted file mode 100644 index 3528fc895e..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0080-arm64-dts-ls1028a-rdb-enable-emmc-hs400-mode.patch +++ /dev/null @@ -1,23 +0,0 @@ -From f1f32315bcb6b50e9af701d4504c2cfa11823c98 Mon Sep 17 00:00:00 2001 -From: Yinbo Zhu -Date: Tue, 13 Aug 2019 17:01:44 +0800 -Subject: [PATCH] arm64: dts: ls1028a-rdb: enable emmc hs400 mode - -This patch is to enable emmc hs400 mode for ls1028ardb - -Signed-off-by: Yinbo Zhu ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -@@ -93,6 +93,8 @@ - - &esdhc1 { - mmc-hs200-1_8v; -+ mmc-hs400-1_8v; -+ bus-width = <8>; - status = "okay"; - }; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0081-arm64-dts-lx2160a-add-ftm_alarm0-DT-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0081-arm64-dts-lx2160a-add-ftm_alarm0-DT-node.patch deleted file mode 100644 index e8db9f32d0..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0081-arm64-dts-lx2160a-add-ftm_alarm0-DT-node.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 31301e26a9d72fe2e4ecdf0999e9fda4c6832188 Mon Sep 17 00:00:00 2001 -From: Biwen Li -Date: Thu, 1 Aug 2019 12:34:33 +0800 -Subject: [PATCH] arm64: dts: lx2160a: add ftm_alarm0 DT node - -The patch adds ftm_alarm0 DT node for Soc LX2160A -FlexTimer1 module is used to wakeup the system in deep sleep - -Signed-off-by: Biwen Li ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -15,6 +15,10 @@ - #address-cells = <2>; - #size-cells = <2>; - -+ aliases { -+ rtc1 = &ftm_alarm0; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -769,6 +773,20 @@ - timeout-sec = <30>; - }; - -+ rcpm: rcpm@1e34040 { -+ compatible = "fsl,lx2160a-rcpm", "fsl,qoriq-rcpm-2.1+"; -+ reg = <0x0 0x1e34040 0x0 0x1c>; -+ #fsl,rcpm-wakeup-cells = <7>; -+ little-endian; -+ }; -+ -+ ftm_alarm0: timer@2800000 { -+ compatible = "fsl,lx2160a-ftm-alarm"; -+ reg = <0x0 0x2800000 0x0 0x10000>; -+ fsl,rcpm-wakeup = <&rcpm 0x0 0x0 0x0 0x0 0x4000 0x0 0x0>; -+ interrupts = <0 44 4>; -+ }; -+ - usb0: usb@3100000 { - compatible = "snps,dwc3"; - reg = <0x0 0x3100000 0x0 0x10000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0082-arm64-dts-lx2160a-add-tmu-device-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0082-arm64-dts-lx2160a-add-tmu-device-node.patch deleted file mode 100644 index 3e3a67919e..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0082-arm64-dts-lx2160a-add-tmu-device-node.patch +++ /dev/null @@ -1,293 +0,0 @@ -From f6233242d21bb4cb973a7dfc61dcfbf6d9a5d22b Mon Sep 17 00:00:00 2001 -From: Yuantian Tang -Date: Mon, 2 Sep 2019 17:45:19 +0800 -Subject: [PATCH] arm64: dts: lx2160a: add tmu device node - -Add the TMU (Thermal Monitoring Unit) device node to enable -TMU feature. - -Signed-off-by: Yuantian Tang ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 108 +++++++++++++++++++++---- - 1 file changed, 92 insertions(+), 16 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -6,6 +6,7 @@ - - #include - #include -+#include - - /memreserve/ 0x80000000 0x00010000; - -@@ -24,7 +25,7 @@ - #size-cells = <0>; - - // 8 clusters having 2 Cortex-A72 cores each -- cpu@0 { -+ cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -38,9 +39,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster0_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@1 { -+ cpu1: cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -54,9 +56,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster0_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@100 { -+ cpu100: cpu@100 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -70,9 +73,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster1_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@101 { -+ cpu101: cpu@101 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -86,9 +90,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster1_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@200 { -+ cpu200: cpu@200 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -102,9 +107,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster2_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@201 { -+ cpu201: cpu@201 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -118,9 +124,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster2_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@300 { -+ cpu300: cpu@300 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -134,9 +141,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster3_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@301 { -+ cpu301: cpu@301 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -150,9 +158,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster3_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@400 { -+ cpu400: cpu@400 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -166,9 +175,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster4_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@401 { -+ cpu401: cpu@401 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -182,9 +192,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster4_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@500 { -+ cpu500: cpu@500 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -198,9 +209,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster5_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@501 { -+ cpu501: cpu@501 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -214,9 +226,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster5_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@600 { -+ cpu600: cpu@600 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -230,9 +243,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster6_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@601 { -+ cpu601: cpu@601 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -246,9 +260,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster6_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@700 { -+ cpu700: cpu@700 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -262,9 +277,10 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster7_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - -- cpu@701 { -+ cpu701: cpu@701 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - enable-method = "psci"; -@@ -278,6 +294,7 @@ - i-cache-sets = <192>; - next-level-cache = <&cluster7_l2>; - cpu-idle-states = <&cpu_pw15>; -+ #cooling-cells = <2>; - }; - - cluster0_l2: l2-cache0 { -@@ -422,6 +439,51 @@ - clock-output-names = "sysclk"; - }; - -+ thermal-zones { -+ core_thermal1: core-thermal1 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 0>; -+ -+ trips { -+ core_cluster_alert: core-cluster-alert { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ core_cluster_crit: core-cluster-crit { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ -+ cooling-maps { -+ map0 { -+ trip = <&core_cluster_alert>; -+ cooling-device = -+ <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu101 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu200 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu201 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu300 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu301 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu400 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu401 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu500 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu501 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu600 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu601 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu700 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -+ <&cpu701 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; -+ }; -+ }; -+ }; -+ }; -+ - soc { - compatible = "simple-bus"; - #address-cells = <2>; -@@ -689,6 +751,20 @@ - status = "disabled"; - }; - -+ tmu: tmu@1f80000 { -+ compatible = "fsl,qoriq-tmu"; -+ reg = <0x0 0x1f80000 0x0 0x10000>; -+ interrupts = <0 23 0x4>; -+ fsl,tmu-range = <0x800000E6 0x8001017D>; -+ fsl,tmu-calibration = -+ /* Calibration data group 1 */ -+ <0x00000000 0x00000035 -+ /* Calibration data group 2 */ -+ 0x00010001 0x00000154>; -+ little-endian; -+ #thermal-sensor-cells = <1>; -+ }; -+ - uart0: serial@21c0000 { - compatible = "arm,sbsa-uart","arm,pl011"; - reg = <0x0 0x21c0000 0x0 0x1000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0084-arm64-dts-ls1028a-define-networking-options-for-QDS.patch b/target/linux/layerscape/patches-5.4/302-dts-0084-arm64-dts-ls1028a-define-networking-options-for-QDS.patch deleted file mode 100644 index 8680f3490b..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0084-arm64-dts-ls1028a-define-networking-options-for-QDS.patch +++ /dev/null @@ -1,355 +0,0 @@ -From 0c767bcfe1b4d940f2889820f12d278cbba764b5 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 27 Aug 2019 15:12:00 +0300 -Subject: [PATCH] arm64: dts: ls1028a: define networking options for QDS - -Defines connectivity for a few serdes protocol combinations (85xx, 65xx, -13xx, 9999, 7777). - -Signed-off-by: Alex Marginean ---- - .../boot/dts/freescale/fsl-ls1028a-qds-1xxx.dtsi | 20 ++++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-6xxx.dtsi | 20 ++++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-7777.dtsi | 56 ++++++++++++++++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-8xxx.dtsi | 19 +++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-9999.dtsi | 60 ++++++++++++++++++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-x3xx.dtsi | 48 +++++++++++++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-x5xx.dtsi | 44 ++++++++++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 27 ++++++++++ - 8 files changed, 294 insertions(+) - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-1xxx.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-6xxx.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-8xxx.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x3xx.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x5xx.dtsi - ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-1xxx.dtsi -@@ -0,0 +1,20 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for LS1028A QDS board, serdes 1xxx -+ * -+ * Copyright 2019 NXP -+ * -+ */ -+ -+&mdio_slot1 { -+ slot1_sgmii: ethernet-phy@2 { -+ /* AQR112 */ -+ reg = <0x2>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+}; -+ -+&enetc_port0 { -+ phy-handle = <&slot1_sgmii>; -+ phy-connection-type = "usxgmii"; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-6xxx.dtsi -@@ -0,0 +1,20 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for LS1028A QDS board, serdes 6xxx -+ * -+ * Copyright 2019 NXP -+ * -+ */ -+ -+&mdio_slot1 { -+ slot1_sgmii: ethernet-phy@2 { -+ /* AQR112 */ -+ reg = <0x2>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+}; -+ -+&enetc_port0 { -+ phy-handle = <&slot1_sgmii>; -+ phy-connection-type = "2500base-x"; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dtsi -@@ -0,0 +1,56 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for LS1028A QDS board, serdes 9999 -+ * -+ * Copyright 2019 NXP -+ * -+ */ -+ -+&mdio_slot1 { -+ /* two ports on AQR412 */ -+ slot1_sxgmii2: ethernet-phy@2 { -+ reg = <0x2>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ slot1_sxgmii3: ethernet-phy@3 { -+ reg = <0x3>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+}; -+ -+&mdio_slot2 { -+ slot2_sxgmii0: ethernet-phy@2 { -+ /* AQR112 */ -+ reg = <0x2>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+}; -+ -+&mdio_slot3 { -+ slot3_sxgmii0: ethernet-phy@2 { -+ /* AQR112 */ -+ reg = <0x2>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+}; -+ -+/* l2switch ports */ -+&switch_port0 { -+ phy-handle = <&slot1_sxgmii2>; -+ phy-connection-type = "2500base-x"; -+}; -+ -+&switch_port1 { -+ phy-handle = <&slot2_sxgmii0>; -+ phy-connection-type = "2500base-x"; -+}; -+ -+&switch_port2 { -+ phy-handle = <&slot3_sxgmii0>; -+ phy-connection-type = "2500base-x"; -+}; -+ -+&switch_port3 { -+ phy-handle = <&slot1_sxgmii3>; -+ phy-connection-type = "2500base-x"; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-8xxx.dtsi -@@ -0,0 +1,19 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for LS1028A QDS board, serdes 8xxx -+ * -+ * Copyright 2019 NXP -+ * -+ */ -+ -+&mdio_slot1 { -+ slot1_sgmii: ethernet-phy@1c { -+ /* 1st port on VSC8234 */ -+ reg = <0x1c>; -+ }; -+}; -+ -+&enetc_port0 { -+ phy-handle = <&slot1_sgmii>; -+ phy-connection-type = "sgmii"; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dtsi -@@ -0,0 +1,60 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for LS1028A QDS board, serdes 9999 -+ * -+ * Copyright 2019 NXP -+ * -+ */ -+ -+&mdio_slot1 { -+ /* VSC8234 */ -+ slot1_sgmii0: ethernet-phy@1c { -+ reg = <0x1c>; -+ }; -+ slot1_sgmii1: ethernet-phy@1d { -+ reg = <0x1d>; -+ }; -+ slot1_sgmii2: ethernet-phy@1e { -+ reg = <0x1e>; -+ }; -+ slot1_sgmii3: ethernet-phy@1f { -+ reg = <0x1f>; -+ }; -+}; -+ -+&mdio_slot2 { -+ /* VSC8234 */ -+ slot2_sgmii0: ethernet-phy@1c { -+ reg = <0x1c>; -+ }; -+ slot2_sgmii1: ethernet-phy@1d { -+ reg = <0x1d>; -+ }; -+ slot2_sgmii2: ethernet-phy@1e { -+ reg = <0x1e>; -+ }; -+ slot2_sgmii3: ethernet-phy@1f { -+ reg = <0x1f>; -+ }; -+}; -+ -+/* l2switch ports */ -+&switch_port0 { -+ phy-handle = <&slot1_sgmii0>; -+ phy-connection-type = "sgmii"; -+}; -+ -+&switch_port1 { -+ phy-handle = <&slot2_sgmii0>; -+ phy-connection-type = "sgmii"; -+}; -+ -+&switch_port2 { -+ phy-handle = <&slot1_sgmii2>; -+ phy-connection-type = "sgmii"; -+}; -+ -+&switch_port3 { -+ phy-handle = <&slot1_sgmii3>; -+ phy-connection-type = "sgmii"; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x3xx.dtsi -@@ -0,0 +1,48 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for LS1028A QDS board, serdes x3xx -+ * -+ * Copyright 2019 NXP -+ * -+ */ -+ -+&mdio_slot2 { -+ /* 4 ports on AQR412 */ -+ slot2_qsgmii0: ethernet-phy@0 { -+ reg = <0x0>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ slot2_qsgmii1: ethernet-phy@1 { -+ reg = <0x1>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ slot2_qsgmii2: ethernet-phy@2 { -+ reg = <0x2>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ slot2_qsgmii3: ethernet-phy@3 { -+ reg = <0x3>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+}; -+ -+/* l2switch ports */ -+&switch_port0 { -+ phy-handle = <&slot2_qsgmii0>; -+ phy-connection-type = "usxgmii"; -+}; -+ -+&switch_port1 { -+ phy-handle = <&slot2_qsgmii1>; -+ phy-connection-type = "usxgmii"; -+}; -+ -+&switch_port2 { -+ phy-handle = <&slot2_qsgmii2>; -+ phy-connection-type = "usxgmii"; -+}; -+ -+&switch_port3 { -+ phy-handle = <&slot2_qsgmii3>; -+ phy-connection-type = "usxgmii"; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x5xx.dtsi -@@ -0,0 +1,44 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree Include file for LS1028A QDS board, serdes x5xx -+ * -+ * Copyright 2019 NXP -+ * -+ */ -+ -+&mdio_slot2 { -+ /* 4 ports on VSC8514 */ -+ slot2_qsgmii0: ethernet-phy@8 { -+ reg = <0x8>; -+ }; -+ slot2_qsgmii1: ethernet-phy@9 { -+ reg = <0x9>; -+ }; -+ slot2_qsgmii2: ethernet-phy@a { -+ reg = <0xa>; -+ }; -+ slot2_qsgmii3: ethernet-phy@b { -+ reg = <0xb>; -+ }; -+}; -+ -+/* l2switch ports */ -+&switch_port0 { -+ phy-handle = <&slot2_qsgmii0>; -+ phy-connection-type = "qsgmii"; -+}; -+ -+&switch_port1 { -+ phy-handle = <&slot2_qsgmii1>; -+ phy-connection-type = "qsgmii"; -+}; -+ -+&switch_port2 { -+ phy-handle = <&slot2_qsgmii2>; -+ phy-connection-type = "qsgmii"; -+}; -+ -+&switch_port3 { -+ phy-handle = <&slot2_qsgmii3>; -+ phy-connection-type = "qsgmii"; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -@@ -104,6 +104,30 @@ - reg = <5>; - }; - }; -+ -+ mdio_slot1: mdio@4 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <4>; -+ }; -+ -+ mdio_slot2: mdio@5 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <5>; -+ }; -+ -+ mdio_slot3: mdio@6 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <6>; -+ }; -+ -+ mdio_slot4: mdio@7 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <7>; -+ }; - }; - }; - -@@ -260,3 +284,6 @@ - edp_num_lanes = <0x4>; - status = "okay"; - }; -+ -+#include "fsl-ls1028a-qds-8xxx.dtsi" -+#include "fsl-ls1028a-qds-x5xx.dtsi" diff --git a/target/linux/layerscape/patches-5.4/302-dts-0086-usb-dwc3-enable-otg-mode-for-dwc3-usb-ip-on-layersca.patch b/target/linux/layerscape/patches-5.4/302-dts-0086-usb-dwc3-enable-otg-mode-for-dwc3-usb-ip-on-layersca.patch deleted file mode 100644 index 050c5d5137..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0086-usb-dwc3-enable-otg-mode-for-dwc3-usb-ip-on-layersca.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 411bee5b3e729e4dd691051e13f77dfb994e0da8 Mon Sep 17 00:00:00 2001 -From: Yinbo Zhu -Date: Mon, 9 Sep 2019 15:57:52 +0800 -Subject: [PATCH] usb: dwc3: enable otg mode for dwc3 usb ip on layerscape - -layerscape otg function should be supported HNP SRP and ADP protocol -accroing to rm doc, but dwc3 code not realize it and use id pin to -detect who is host or device(0 is host 1 is device) this patch is to -enable OTG mode on ls1028ardb ls1088ardb and ls1046ardb in dts - -Signed-off-by: Yinbo Zhu ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts | 4 ++++ - arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 4 ++++ - arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts | 1 + - 3 files changed, 9 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -@@ -98,6 +98,10 @@ - status = "okay"; - }; - -+&usb1 { -+ dr_mode = "otg"; -+}; -+ - &i2c0 { - status = "okay"; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts -@@ -44,6 +44,10 @@ - sd-uhs-sdr12; - }; - -+&usb1 { -+ dr_mode = "otg"; -+}; -+ - &i2c0 { - status = "okay"; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts -@@ -120,6 +120,7 @@ - }; - - &usb1 { -+ dr_mode = "otg"; - status = "okay"; - }; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0087-arm-dts-ls1021a-fix-that-FlexTimer-cannot-wakeup-sys.patch b/target/linux/layerscape/patches-5.4/302-dts-0087-arm-dts-ls1021a-fix-that-FlexTimer-cannot-wakeup-sys.patch deleted file mode 100644 index cebd74524b..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0087-arm-dts-ls1021a-fix-that-FlexTimer-cannot-wakeup-sys.patch +++ /dev/null @@ -1,29 +0,0 @@ -From c221e05b50ca68daf5a20069ee1928171ef43bae Mon Sep 17 00:00:00 2001 -From: Biwen Li -Date: Sat, 14 Sep 2019 12:59:36 +0800 -Subject: [PATCH] arm: dts: ls1021a: fix that FlexTimer cannot wakeup system in - deep sleep - -The patch fixes a bug that FlexTimer cannot -wakeup system in deep sleep. - -Signed-off-by: Biwen Li ---- - arch/arm/boot/dts/ls1021a.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/arch/arm/boot/dts/ls1021a.dtsi -+++ b/arch/arm/boot/dts/ls1021a.dtsi -@@ -965,6 +965,12 @@ - compatible = "fsl,ls1021a-rcpm", "fsl,qoriq-rcpm-2.1+"; - reg = <0x0 0x1ee2140 0x0 0x8>; - #fsl,rcpm-wakeup-cells = <2>; -+ -+ /* -+ * The second and third entry compose an alt offset -+ * address for IPPDEXPCR1(SCFG_SPARECR8) -+ */ -+ fsl,ippdexpcr1-alt-addr = <&scfg 0x0 0x51c>; - }; - - ftm_alarm0: timer0@29d0000 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0088-arm64-dts-ls1028a-fix-dwc-pci-over-smmu.patch b/target/linux/layerscape/patches-5.4/302-dts-0088-arm64-dts-ls1028a-fix-dwc-pci-over-smmu.patch deleted file mode 100644 index 82d6b4c043..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0088-arm64-dts-ls1028a-fix-dwc-pci-over-smmu.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 127b30b66c3b48ee717ed7335987334e8dc769b5 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 1 Oct 2019 13:47:11 +0300 -Subject: [PATCH] arm64: dts: ls1028a: fix dwc pci over smmu - -In order for the dwc controller to work with SMMU it needs the -bootloader to fixup it's iommu-map property. In the current -implementation to bootloader will not perform the fixup if the -property is not already in the device tree with dummy fields. -Add it to fix DWC PCI over SMMU. - -Signed-off-by: Laurentiu Tudor ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -687,6 +687,7 @@ - #size-cells = <2>; - device_type = "pci"; - dma-coherent; -+ iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ - bus-range = <0x0 0xff>; - ranges = <0x81000000 0x0 0x00000000 0x80 0x00010000 0x0 0x00010000 /* downstream I/O */ - 0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ -@@ -712,6 +713,7 @@ - #size-cells = <2>; - device_type = "pci"; - dma-coherent; -+ iommu-map = <0 &smmu 0 1>; /* Fixed-up by bootloader */ - bus-range = <0x0 0xff>; - ranges = <0x81000000 0x0 0x00000000 0x88 0x00010000 0x0 0x00010000 /* downstream I/O */ - 0x82000000 0x0 0x40000000 0x88 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ diff --git a/target/linux/layerscape/patches-5.4/302-dts-0089-arm64-dts-ls1028a-Update-the-clock-providers-for-the.patch b/target/linux/layerscape/patches-5.4/302-dts-0089-arm64-dts-ls1028a-Update-the-clock-providers-for-the.patch deleted file mode 100644 index 8c2d085665..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0089-arm64-dts-ls1028a-Update-the-clock-providers-for-the.patch +++ /dev/null @@ -1,55 +0,0 @@ -From e13c24ef2f068e651b9996922a08843d53513cab Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Fri, 20 Sep 2019 16:34:18 +0800 -Subject: [PATCH] arm64: dts: ls1028a: Update the clock providers for the Mali - DP500 - -In order to maximise performance of the LCD Controller's 64-bit AXI -bus, for any give speed bin of the device, the AXI master interface -clock(ACLK) clock can be up to CPU_frequency/2, which is already -capable of optimal performance. In general, ACLK is always expected -to be equal to CPU_frequency/2. APB slave interface clock(PCLK) and -Main processing clock(PCLK) both are tied to the same clock as ACLK. - -This change followed the LS1028A Architecture Specification Manual. - -Signed-off-by: Wen He -Acked-by: Li Yang -Signed-off-by: Shawn Guo ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 17 ++--------------- - 1 file changed, 2 insertions(+), 15 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -90,20 +90,6 @@ - clocks = <&osc_27m>; - }; - -- aclk: clock-axi { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <650000000>; -- clock-output-names= "aclk"; -- }; -- -- pclk: clock-apb { -- compatible = "fixed-clock"; -- #clock-cells = <0>; -- clock-frequency = <650000000>; -- clock-output-names= "pclk"; -- }; -- - reboot { - compatible ="syscon-reboot"; - regmap = <&rst>; -@@ -860,7 +846,8 @@ - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 223 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "DE", "SE"; -- clocks = <&dpclk 0>, <&aclk>, <&aclk>, <&pclk>; -+ clocks = <&dpclk 0>, <&clockgen 2 2>, <&clockgen 2 2>, -+ <&clockgen 2 2>; - clock-names = "pxlclk", "mclk", "aclk", "pclk"; - arm,malidp-output-port-lines = /bits/ 8 <8 8 8>; - arm,malidp-arqos-value = <0xd000d000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0090-arm64-dts-ls1028a-Update-clock-cells-of-dpclk-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0090-arm64-dts-ls1028a-Update-clock-cells-of-dpclk-node.patch deleted file mode 100644 index b84ba01fb5..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0090-arm64-dts-ls1028a-Update-clock-cells-of-dpclk-node.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 7e64c4e922cddea72dacd3f0d8f395d9182ea5bc Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Mon, 14 Oct 2019 15:13:27 +0800 -Subject: [PATCH] arm64: dts: ls1028a: Update #clock-cells of dpclk node - -Update the property #clock-cells = <1> to #clock-cells = <0> of the -dpclk, since the Display output pixel clock driver provides single -clock output. - -Signed-off-by: Wen He -Signed-off-by: Shawn Guo ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -86,7 +86,7 @@ - dpclk: clock-controller@f1f0000 { - compatible = "fsl,ls1028a-plldig"; - reg = <0x0 0xf1f0000 0x0 0xffff>; -- #clock-cells = <1>; -+ #clock-cells = <0>; - clocks = <&osc_27m>; - }; - -@@ -846,7 +846,7 @@ - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 223 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "DE", "SE"; -- clocks = <&dpclk 0>, <&clockgen 2 2>, <&clockgen 2 2>, -+ clocks = <&dpclk>, <&clockgen 2 2>, <&clockgen 2 2>, - <&clockgen 2 2>; - clock-names = "pxlclk", "mclk", "aclk", "pclk"; - arm,malidp-output-port-lines = /bits/ 8 <8 8 8>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0091-arm64-dts-ls1028a-Add-properties-for-HD-Display-cont.patch b/target/linux/layerscape/patches-5.4/302-dts-0091-arm64-dts-ls1028a-Add-properties-for-HD-Display-cont.patch deleted file mode 100644 index 07620e57c9..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0091-arm64-dts-ls1028a-Add-properties-for-HD-Display-cont.patch +++ /dev/null @@ -1,43 +0,0 @@ -From e0afa16cad94b26e13d673647b781dd336cb30bc Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Mon, 14 Oct 2019 14:25:42 +0800 -Subject: [PATCH] arm64: dts: ls1028a: Add properties for HD Display controller - node - -The HD Display controller includes DP TX CTRL and DPHY, their offers -multi-protocol support of standards such as DisplayPort and eDP, with -one of these standards supported at a time. - -This patch enables the HD Display controller driver on the LS1028A. - -Signed-off-by: Wen He ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -854,7 +854,23 @@ - - port { - dp0_out: endpoint { -+ remote-endpoint = <&dp1_out>; -+ }; -+ }; -+ }; - -+ hdptx0: display@f200000 { -+ compatible = "cdn,ls1028a-dp"; -+ reg = <0x0 0xf200000 0x0 0xfffff>; -+ interrupts = <0 221 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&clockgen 2 2>, <&clockgen 2 2>, <&clockgen 2 2>, -+ <&clockgen 2 2>, <&clockgen 2 2>, <&dpclk>; -+ clock-names = "clk_core", "pclk", "sclk", -+ "cclk", "clk_vif", "clk_pxl"; -+ -+ port { -+ dp1_out: endpoint { -+ remote-endpoint = <&dp0_out>; - }; - }; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0092-arm64-dts-ls1028a-Add-DP-DT-nodes.patch b/target/linux/layerscape/patches-5.4/302-dts-0092-arm64-dts-ls1028a-Add-DP-DT-nodes.patch deleted file mode 100644 index c3b750ee8a..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0092-arm64-dts-ls1028a-Add-DP-DT-nodes.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 4de1f70135fa4b44eb5016e36ba08ffd0bc62414 Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Wed, 27 Nov 2019 17:48:17 +0800 -Subject: [PATCH] arm64: dts: ls1028a: Add DP DT nodes - -Add DP DT nodes for configure and enable the HD Display -controller on LS1028ARDB and LS1028AQDS boards. - -Signed-off-by: Wen He ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 9 +-------- - arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts | 9 +-------- - 2 files changed, 2 insertions(+), 16 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -@@ -274,14 +274,7 @@ - }; - - &hdptx0 { -- fsl,no_edid; -- resolution = "3840x2160@60", -- "1920x1080@60", -- "1280x720@60", -- "720x480@60"; -- lane_mapping = <0x4e>; -- edp_link_rate = <0x6>; -- edp_num_lanes = <0x4>; -+ lane-mapping = <0x4e>; - status = "okay"; - }; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -@@ -262,13 +262,6 @@ - }; - - &hdptx0 { -- fsl,no_edid; -- resolution = "3840x2160@60", -- "1920x1080@60", -- "1280x720@60", -- "720x480@60"; -- lane_mapping = <0x4e>; -- edp_link_rate = <0x6>; -- edp_num_lanes = <0x4>; -+ lane-mapping = <0x4e>; - status = "okay"; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0093-arm64-dts-fsl-Specify-phy-mode-for-CPU-ports.patch b/target/linux/layerscape/patches-5.4/302-dts-0093-arm64-dts-fsl-Specify-phy-mode-for-CPU-ports.patch deleted file mode 100644 index cf99f33251..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0093-arm64-dts-fsl-Specify-phy-mode-for-CPU-ports.patch +++ /dev/null @@ -1,35 +0,0 @@ -From a55a0d71c2b1000c514f30573ced00879754f223 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Fri, 29 Nov 2019 03:07:14 +0200 -Subject: [PATCH] arm64: dts: fsl: Specify phy-mode for CPU ports - -PHYLINK requires that device tree nodes have a phy-mode or -phy-connection-type property. The internal Felix ports really are -connected to the ENETC via 2 back-to-back MACs, so the correct MII type -is GMII (one of which is overclocked at 2.5Gbaud, but still GMII). - -Signed-off-by: Vladimir Oltean ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -793,6 +793,8 @@ - /* internal to-cpu ports */ - port@4 { - reg = <4>; -+ phy-mode = "gmii"; -+ - fixed-link { - speed = <1000>; - full-duplex; -@@ -801,6 +803,8 @@ - port@5 { - reg = <5>; - ethernet = <&enetc_port3>; -+ phy-mode = "gmii"; -+ - fixed-link { - speed = <1000>; - full-duplex; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0094-arm64-dts-fsl-Drop-compatible-string-from-Felix-swit.patch b/target/linux/layerscape/patches-5.4/302-dts-0094-arm64-dts-fsl-Drop-compatible-string-from-Felix-swit.patch deleted file mode 100644 index ff9a05d3cc..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0094-arm64-dts-fsl-Drop-compatible-string-from-Felix-swit.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 21c535326436df93fd61c9bd029b8716d1ab94d0 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Fri, 29 Nov 2019 03:10:23 +0200 -Subject: [PATCH] arm64: dts: fsl: Drop "compatible" string from Felix switch - -Since Felix is not a platform device but a PCI device, the "compatible" -string serves no purpose. The device driver is found by matching the PCI -device/vendor ID to the ENETC PF. - -Signed-off-by: Vladimir Oltean ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 1 - - 1 file changed, 1 deletion(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -768,7 +768,6 @@ - little-endian; - }; - switch@0,5 { -- compatible = "mscc,felix-switch"; - reg = <0x000500 0 0 0 0>; - /* IEP INT_B */ - interrupts = ; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0095-arm64-dts-fsl-ls1028a-Specify-that-the-Felix-port-4-.patch b/target/linux/layerscape/patches-5.4/302-dts-0095-arm64-dts-fsl-ls1028a-Specify-that-the-Felix-port-4-.patch deleted file mode 100644 index 195f28754d..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0095-arm64-dts-fsl-ls1028a-Specify-that-the-Felix-port-4-.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5934fa0a0708b551211f63b8d91676df346e9821 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Fri, 29 Nov 2019 03:13:00 +0200 -Subject: [PATCH] arm64: dts: fsl: ls1028a: Specify that the Felix port 4 runs - at 2.5Gbps - -This is just an informative change, because all Felix MACs inside the -LS1028A are hardwired in gigabit mode anyway. - -Only PHYLINK is able to understand fixed-link speeds higher than 1 Gbps. -With PHYLIB, fixed-link interfaces are emulated as C22 PHYs by the swphy -driver, and C22 does not specify settings for speeds higher than -gigabit. - -This patch brings no functional change except for the messages printed -during driver initialization. - -Signed-off-by: Vladimir Oltean ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -805,7 +805,7 @@ - phy-mode = "gmii"; - - fixed-link { -- speed = <1000>; -+ speed = <2500>; - full-duplex; - }; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0096-arm64-dts-fsl-ls1028a-Disable-eno3-and-make-swp5-the.patch b/target/linux/layerscape/patches-5.4/302-dts-0096-arm64-dts-fsl-ls1028a-Disable-eno3-and-make-swp5-the.patch deleted file mode 100644 index a1c50bcefb..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0096-arm64-dts-fsl-ls1028a-Disable-eno3-and-make-swp5-the.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 9344f58d60a0a53ec39e7c5d75021843e859970f Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Fri, 29 Nov 2019 03:18:32 +0200 -Subject: [PATCH] arm64: dts: fsl: ls1028a: Disable eno3 and make swp5 the - Felix CPU port - -This patch returns to the switch port setup from BSP 0.2, where the -switch only had a single Ethernet connection to the CPU, via a tagging -interface. Choose eno2 for this purpose, as it has higher bandwidth and -also supports TSN offloads. - -The reason is that the switch is not able to do DSA tags on 2 CPU ports -at the same time, and it is confusing to have so many ports with no -clear indication which should be used for what (a "data" port and a -"control" port). - -We don't revert to the BSP 0.2 RCW configuration, however. The ENETC -port 3 is still enabled in the RCW, however it is not probed by Linux by -default, since the large majority of use cases will not need it. For -those that do (like originating 802.1CB traffic from the CPU), it can be -enabled back by simply reverting this device tree change. - -Signed-off-by: Vladimir Oltean ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -753,7 +753,7 @@ - #address-cells = <1>; - #size-cells = <0>; - }; -- ethernet@0,2 { -+ enetc_port2: ethernet@0,2 { - compatible = "fsl,enetc"; - reg = <0x000200 0 0 0 0>; - fixed-link { -@@ -792,6 +792,7 @@ - /* internal to-cpu ports */ - port@4 { - reg = <4>; -+ ethernet = <&enetc_port2>; - phy-mode = "gmii"; - - fixed-link { -@@ -801,7 +802,6 @@ - }; - port@5 { - reg = <5>; -- ethernet = <&enetc_port3>; - phy-mode = "gmii"; - - fixed-link { -@@ -814,6 +814,8 @@ - enetc_port3: ethernet@0,6 { - compatible = "fsl,enetc"; - reg = <0x000600 0 0 0 0>; -+ status = "disabled"; -+ - fixed-link { - speed = <1000>; - full-duplex; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0097-LF-387-5-arm64-dts-layerscape-add-chip-specific-comp.patch b/target/linux/layerscape/patches-5.4/302-dts-0097-LF-387-5-arm64-dts-layerscape-add-chip-specific-comp.patch deleted file mode 100644 index 25d66a4ba6..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0097-LF-387-5-arm64-dts-layerscape-add-chip-specific-comp.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 4cb6a451112308b2679c567ac680bc74ab93a92a Mon Sep 17 00:00:00 2001 -From: Ran Wang -Date: Fri, 22 Nov 2019 14:18:49 +0800 -Subject: [PATCH] LF-387-5 arm64: dts: layerscape: add chip-specific compatible - string to usb nodes - -To allow USB dwc3 driver to conduct some chip-scpeific configuring. -Cover all arm64 based Layerscape SoCs. - -Signed-off-by: Ran Wang -Reviewed-by: Jun Li -Reviewed-by: Leo Li ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 2 +- - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 6 +++--- - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 6 +++--- - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 4 ++-- - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 4 ++-- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 4 ++-- - 6 files changed, 13 insertions(+), 13 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -444,7 +444,7 @@ - }; - - usb0: usb3@2f00000 { -- compatible = "snps,dwc3"; -+ compatible = "fsl,ls1012a-dwc3", "snps,dwc3"; - reg = <0x0 0x2f00000 0x0 0x10000>; - interrupts = <0 60 0x4>; - dr_mode = "host"; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -695,7 +695,7 @@ - dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x00000000>; - - usb0: usb3@2f00000 { -- compatible = "snps,dwc3"; -+ compatible = "fsl,ls1043a-dwc3", "snps,dwc3"; - reg = <0x0 0x2f00000 0x0 0x10000>; - interrupts = <0 60 0x4>; - dr_mode = "host"; -@@ -709,7 +709,7 @@ - }; - - usb1: usb3@3000000 { -- compatible = "snps,dwc3"; -+ compatible = "fsl,ls1043a-dwc3", "snps,dwc3"; - reg = <0x0 0x3000000 0x0 0x10000>; - interrupts = <0 61 0x4>; - dr_mode = "host"; -@@ -723,7 +723,7 @@ - }; - - usb2: usb3@3100000 { -- compatible = "snps,dwc3"; -+ compatible = "fsl,ls1043a-dwc3", "snps,dwc3"; - reg = <0x0 0x3100000 0x0 0x10000>; - interrupts = <0 63 0x4>; - dr_mode = "host"; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -594,7 +594,7 @@ - dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x00000000>; - - usb0: usb@2f00000 { -- compatible = "snps,dwc3"; -+ compatible = "fsl,ls1046a-dwc3", "snps,dwc3"; - reg = <0x0 0x2f00000 0x0 0x10000>; - interrupts = ; - dr_mode = "host"; -@@ -607,7 +607,7 @@ - }; - - usb1: usb@3000000 { -- compatible = "snps,dwc3"; -+ compatible = "fsl,ls1046a-dwc3", "snps,dwc3"; - reg = <0x0 0x3000000 0x0 0x10000>; - interrupts = ; - dr_mode = "host"; -@@ -620,7 +620,7 @@ - }; - - usb2: usb@3100000 { -- compatible = "snps,dwc3"; -+ compatible = "fsl,ls1046a-dwc3", "snps,dwc3"; - reg = <0x0 0x3100000 0x0 0x10000>; - interrupts = ; - dr_mode = "host"; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -394,7 +394,7 @@ - }; - - usb0: usb3@3100000 { -- compatible = "snps,dwc3"; -+ compatible = "fsl,ls1088a-dwc3", "snps,dwc3"; - reg = <0x0 0x3100000 0x0 0x10000>; - interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; - dr_mode = "host"; -@@ -406,7 +406,7 @@ - }; - - usb1: usb3@3110000 { -- compatible = "snps,dwc3"; -+ compatible = "fsl,ls1088a-dwc3", "snps,dwc3"; - reg = <0x0 0x3110000 0x0 0x10000>; - interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>; - dr_mode = "host"; ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -729,7 +729,7 @@ - - usb0: usb3@3100000 { - status = "disabled"; -- compatible = "snps,dwc3"; -+ compatible = "fsl,ls2088a-dwc3", "snps,dwc3"; - reg = <0x0 0x3100000 0x0 0x10000>; - interrupts = <0 80 0x4>; /* Level high type */ - dr_mode = "host"; -@@ -741,7 +741,7 @@ - - usb1: usb3@3110000 { - status = "disabled"; -- compatible = "snps,dwc3"; -+ compatible = "fsl,ls2088a-dwc3", "snps,dwc3"; - reg = <0x0 0x3110000 0x0 0x10000>; - interrupts = <0 81 0x4>; /* Level high type */ - dr_mode = "host"; ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -864,7 +864,7 @@ - }; - - usb0: usb@3100000 { -- compatible = "snps,dwc3"; -+ compatible = "fsl,lx2160a-dwc3", "snps,dwc3"; - reg = <0x0 0x3100000 0x0 0x10000>; - interrupts = ; - dr_mode = "host"; -@@ -878,7 +878,7 @@ - }; - - usb1: usb@3110000 { -- compatible = "snps,dwc3"; -+ compatible = "fsl,lx2160a-dwc3", "snps,dwc3"; - reg = <0x0 0x3110000 0x0 0x10000>; - interrupts = ; - dr_mode = "host"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0098-LF-403-ARM64-dts-fsl-Add-clock-names-mclk0-for-SAI-n.patch b/target/linux/layerscape/patches-5.4/302-dts-0098-LF-403-ARM64-dts-fsl-Add-clock-names-mclk0-for-SAI-n.patch deleted file mode 100644 index 2cb3cfd7d8..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0098-LF-403-ARM64-dts-fsl-Add-clock-names-mclk0-for-SAI-n.patch +++ /dev/null @@ -1,105 +0,0 @@ -From b3e78e4a087922566bc18171190e2eed8a9b7797 Mon Sep 17 00:00:00 2001 -From: Alison Wang -Date: Thu, 12 Dec 2019 15:35:32 +0800 -Subject: [PATCH] LF-403 ARM64: dts: fsl: Add clock-names mclk0 for SAI nodes - -This patch adds clock-names "mclk0" to match with the current SAI -driver. - -Signed-off-by: Alison Wang ---- - arch/arm/boot/dts/ls1021a.dtsi | 10 ++++++---- - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 10 ++++++---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 15 +++++++++------ - 3 files changed, 21 insertions(+), 14 deletions(-) - ---- a/arch/arm/boot/dts/ls1021a.dtsi -+++ b/arch/arm/boot/dts/ls1021a.dtsi -@@ -649,8 +649,9 @@ - reg = <0x0 0x2b50000 0x0 0x10000>; - interrupts = ; - clocks = <&clockgen 4 1>, <&clockgen 4 1>, -- <&clockgen 4 1>, <&clockgen 4 1>; -- clock-names = "bus", "mclk1", "mclk2", "mclk3"; -+ <&clockgen 4 1>, <&clockgen 4 1>, -+ <&clockgen 4 1>; -+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; - dma-names = "tx", "rx"; - dmas = <&edma0 1 47>, - <&edma0 1 46>; -@@ -663,8 +664,9 @@ - reg = <0x0 0x2b60000 0x0 0x10000>; - interrupts = ; - clocks = <&clockgen 4 1>, <&clockgen 4 1>, -- <&clockgen 4 1>, <&clockgen 4 1>; -- clock-names = "bus", "mclk1", "mclk2", "mclk3"; -+ <&clockgen 4 1>, <&clockgen 4 1>, -+ <&clockgen 4 1>; -+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; - dma-names = "tx", "rx"; - dmas = <&edma0 1 45>, - <&edma0 1 44>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -405,8 +405,9 @@ - reg = <0x0 0x2b50000 0x0 0x10000>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>, -- <&clockgen 4 3>, <&clockgen 4 3>; -- clock-names = "bus", "mclk1", "mclk2", "mclk3"; -+ <&clockgen 4 3>, <&clockgen 4 3>, -+ <&clockgen 4 3>; -+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; - dma-names = "tx", "rx"; - dmas = <&edma0 1 47>, - <&edma0 1 46>; -@@ -419,8 +420,9 @@ - reg = <0x0 0x2b60000 0x0 0x10000>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clockgen 4 3>, <&clockgen 4 3>, -- <&clockgen 4 3>, <&clockgen 4 3>; -- clock-names = "bus", "mclk1", "mclk2", "mclk3"; -+ <&clockgen 4 3>, <&clockgen 4 3>, -+ <&clockgen 4 3>; -+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; - dma-names = "tx", "rx"; - dmas = <&edma0 1 45>, - <&edma0 1 44>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -542,8 +542,9 @@ - reg = <0x0 0xf100000 0x0 0x10000>; - interrupts = ; - clocks = <&clockgen 4 1>, <&clockgen 4 1>, -- <&clockgen 4 1>, <&clockgen 4 1>; -- clock-names = "bus", "mclk1", "mclk2", "mclk3"; -+ <&clockgen 4 1>, <&clockgen 4 1>, -+ <&clockgen 4 1>; -+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; - dma-names = "tx", "rx"; - dmas = <&edma0 1 4>, - <&edma0 1 3>; -@@ -556,8 +557,9 @@ - reg = <0x0 0xf110000 0x0 0x10000>; - interrupts = ; - clocks = <&clockgen 4 1>, <&clockgen 4 1>, -- <&clockgen 4 1>, <&clockgen 4 1>; -- clock-names = "bus", "mclk1", "mclk2", "mclk3"; -+ <&clockgen 4 1>, <&clockgen 4 1>, -+ <&clockgen 4 1>; -+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; - dma-names = "tx", "rx"; - dmas = <&edma0 1 6>, - <&edma0 1 5>; -@@ -570,8 +572,9 @@ - reg = <0x0 0xf130000 0x0 0x10000>; - interrupts = ; - clocks = <&clockgen 4 1>, <&clockgen 4 1>, -- <&clockgen 4 1>, <&clockgen 4 1>; -- clock-names = "bus", "mclk1", "mclk2", "mclk3"; -+ <&clockgen 4 1>, <&clockgen 4 1>, -+ <&clockgen 4 1>; -+ clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3"; - dma-names = "tx", "rx"; - dmas = <&edma0 1 10>, - <&edma0 1 9>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0099-arm64-dts-layerscape-apply-dma-coherent-for-dwc3-nod.patch b/target/linux/layerscape/patches-5.4/302-dts-0099-arm64-dts-layerscape-apply-dma-coherent-for-dwc3-nod.patch deleted file mode 100644 index 0db177972f..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0099-arm64-dts-layerscape-apply-dma-coherent-for-dwc3-nod.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 18219eaa3f37f375584789b95876967e97b8da3e Mon Sep 17 00:00:00 2001 -From: Ran Wang -Date: Wed, 25 Dec 2019 14:00:27 +0800 -Subject: [PATCH] arm64: dts: layerscape: apply dma-coherent for dwc3 nodes - -Since dwc3 cache type has been set to cacheable, apply dma-coherent to -all dwc3 nodes accordingly. - -Note: For LS1043A and LS1046A, since QE-HDLC still doesn't support -dma-coherent, we cannot directly revert cd1a4f3c (sdk: dts: ls104x move -dma-coherent from soc to its child nodes) to recover dma-coherent for -soc. - -Signed-off-by: Ran Wang ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 1 + - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 2 ++ - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 3 +++ - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 3 +++ - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 2 ++ - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 2 ++ - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 1 + - 7 files changed, 14 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -454,6 +454,7 @@ - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; -+ dma-coherent; - }; - - sata: sata@3200000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -379,6 +379,7 @@ - snps,dis_rxdet_inp3_quirk; - snps,quirk-frame-length-adjustment = <0x20>; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ dma-coherent; - }; - - usb1: usb@3110000 { -@@ -389,6 +390,7 @@ - snps,dis_rxdet_inp3_quirk; - snps,quirk-frame-length-adjustment = <0x20>; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -+ dma-coherent; - }; - - sata: sata@3200000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -706,6 +706,7 @@ - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; - configure-gfladj; -+ dma-coherent; - }; - - usb1: usb3@3000000 { -@@ -720,6 +721,7 @@ - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; - configure-gfladj; -+ dma-coherent; - }; - - usb2: usb3@3100000 { -@@ -734,6 +736,7 @@ - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; - configure-gfladj; -+ dma-coherent; - }; - - sata: sata@3200000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -604,6 +604,7 @@ - usb3-lpm-capable; - snps,dis-u1u2-when-u3-quirk; - snps,host-vbus-glitches; -+ dma-coherent; - }; - - usb1: usb@3000000 { -@@ -617,6 +618,7 @@ - usb3-lpm-capable; - snps,dis-u1u2-when-u3-quirk; - snps,host-vbus-glitches; -+ dma-coherent; - }; - - usb2: usb@3100000 { -@@ -630,6 +632,7 @@ - usb3-lpm-capable; - snps,dis-u1u2-when-u3-quirk; - snps,host-vbus-glitches; -+ dma-coherent; - }; - - sata: sata@3200000 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -402,6 +402,7 @@ - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; -+ dma-coherent; - status = "disabled"; - }; - -@@ -414,6 +415,7 @@ - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; -+ dma-coherent; - status = "disabled"; - }; - ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -737,6 +737,7 @@ - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; -+ dma-coherent; - }; - - usb1: usb3@3110000 { -@@ -749,6 +750,7 @@ - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; -+ dma-coherent; - }; - - ccn@4000000 { ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -874,6 +874,7 @@ - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; -+ dma-coherent; - status = "disabled"; - }; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0100-arm64-dts-ls208xa-Update-qspi-node-properties-for-LS.patch b/target/linux/layerscape/patches-5.4/302-dts-0100-arm64-dts-ls208xa-Update-qspi-node-properties-for-LS.patch deleted file mode 100644 index 6efbe1ecf1..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0100-arm64-dts-ls208xa-Update-qspi-node-properties-for-LS.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 121cd10d9ec4466b09ac33986c7b4c1f8eff9363 Mon Sep 17 00:00:00 2001 -From: Kuldeep Singh -Date: Wed, 18 Dec 2019 15:09:41 +0530 -Subject: [PATCH] arm64: dts: ls208xa: Update qspi node properties for - LS2088ARDB - -LS2088ADB has one spansion flash s25fs512s of size 64M. - -Update qspi dts entry for the board using compatibles as "jedec,spi-nor" -to probe flash successfully. Also, align properties with other board dts -properties. - -Since device properties are different, so remove fsl, ls1021a-qspi. -ls1021a-qspi is to be used only for Big-endian verion of QSPI -controller. Use dt-bindings constants in interrupts instead of using -numbers. - -Signed-off-by: Kuldeep Singh ---- - arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi | 8 ++++---- - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 6 +++--- - 2 files changed, 7 insertions(+), 7 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi -@@ -110,12 +110,12 @@ - - &qspi { - status = "okay"; -- flash0: s25fs512s@0 { -+ -+ s25fs512s0: flash@0 { - #address-cells = <1>; - #size-cells = <1>; -- compatible = "spansion,m25p80"; -- m25p,fast-read; -- spi-max-frequency = <20000000>; -+ compatible = "jedec,spi-nor"; -+ spi-max-frequency = <50000000>; - reg = <0>; - }; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -609,16 +609,16 @@ - }; - - qspi: spi@20c0000 { -- status = "disabled"; -- compatible = "fsl,ls2080a-qspi", "fsl,ls1021a-qspi"; -+ compatible = "fsl,ls2080a-qspi"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0 0x20c0000 0x0 0x10000>, - <0x0 0x20000000 0x0 0x10000000>; - reg-names = "QuadSPI", "QuadSPI-memory"; -- interrupts = <0 25 0x4>; /* Level high type */ -+ interrupts = ; - clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "qspi_en", "qspi"; -+ status = "disabled"; - }; - - pcie1: pcie@3400000 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0101-arm64-dts-ls208xa-Remove-dma-coherent-from-dwc3-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0101-arm64-dts-ls208xa-Remove-dma-coherent-from-dwc3-node.patch deleted file mode 100644 index dc90175362..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0101-arm64-dts-ls208xa-Remove-dma-coherent-from-dwc3-node.patch +++ /dev/null @@ -1,36 +0,0 @@ -From f12e1e289702b9828a2d7deba8744b212e7a6758 Mon Sep 17 00:00:00 2001 -From: Ran Wang -Date: Fri, 27 Dec 2019 18:20:23 +0800 -Subject: [PATCH] arm64: dts: ls208xa: Remove dma-coherent from dwc3 nodes - -ls208xa encounteded below USB failure when applying dma-coherent, remove it. -[ 11.087839] xhci-hcd xhci-hcd.1.auto: Error while assigning device slot ID -[ 11.094730] xhci-hcd xhci-hcd.1.auto: Max number of devices this xHCI host supports is 127. -[ 11.103103] xhci-hcd xhci-hcd.0.auto: Error while assigning device slot ID -[ 11.109985] xhci-hcd xhci-hcd.0.auto: Max number of devices this xHCI host supports is 127. -[ 11.118348] usb usb2-port1: couldn't allocate usb_device -[ 11.123680] usb usb4-port1: couldn't allocate usb_device - -Signed-off-by: Ran Wang ---- - arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi | 2 -- - 1 file changed, 2 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi -@@ -737,7 +737,6 @@ - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; -- dma-coherent; - }; - - usb1: usb3@3110000 { -@@ -750,7 +749,6 @@ - snps,dis_rxdet_inp3_quirk; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; - snps,host-vbus-glitches; -- dma-coherent; - }; - - ccn@4000000 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0102-LF-20-1-arm64-dts-ls1012ardb-Update-qspi-node-dts-pr.patch b/target/linux/layerscape/patches-5.4/302-dts-0102-LF-20-1-arm64-dts-ls1012ardb-Update-qspi-node-dts-pr.patch deleted file mode 100644 index 284519c6c6..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0102-LF-20-1-arm64-dts-ls1012ardb-Update-qspi-node-dts-pr.patch +++ /dev/null @@ -1,60 +0,0 @@ -From e642e6844bd4e6da28efab377f1a94e0eb9a3532 Mon Sep 17 00:00:00 2001 -From: Kuldeep Singh -Date: Fri, 3 Jan 2020 14:47:59 +0530 -Subject: [PATCH] LF-20-1 arm64: dts: ls1012ardb: Update qspi node dts - properties - -Update rx and tx bus-width to 1. -Use compatibles as "jedec,spi-nor" to probe flash without displaying warning: -found s25fs512s, expected m25p80 - -Remove property 'big-endian' as it is not used by new driver anymore. -Also, update dtsi compatibles to use "fsl,ls1021a-qspi". - -Signed-off-by: Kuldeep Singh ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 8 ++++---- - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 3 +-- - 2 files changed, 5 insertions(+), 6 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -@@ -88,15 +88,15 @@ - - &qspi { - status = "okay"; -+ - qflash0: s25fs512s@0 { -- compatible = "spansion,m25p80"; -+ compatible = "jedec,spi-nor"; - #address-cells = <1>; - #size-cells = <1>; - spi-max-frequency = <20000000>; -- m25p,fast-read; - reg = <0>; -- spi-rx-bus-width = <2>; -- spi-tx-bus-width = <2>; -+ spi-rx-bus-width = <1>; -+ spi-tx-bus-width = <1>; - }; - - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -386,7 +386,7 @@ - }; - - qspi: spi@1550000 { -- compatible = "fsl,ls1012a-qspi", "fsl,ls1021a-qspi"; -+ compatible = "fsl,ls1021a-qspi"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0 0x1550000 0x0 0x10000>, -@@ -395,7 +395,6 @@ - interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>; - clock-names = "qspi_en", "qspi"; - clocks = <&clockgen 4 0>, <&clockgen 4 0>; -- big-endian; - status = "disabled"; - }; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0103-arm64-dts-ls1028a-Update-edma-compatible-to-fit-eDMA.patch b/target/linux/layerscape/patches-5.4/302-dts-0103-arm64-dts-ls1028a-Update-edma-compatible-to-fit-eDMA.patch deleted file mode 100644 index f2dccd7ac4..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0103-arm64-dts-ls1028a-Update-edma-compatible-to-fit-eDMA.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0af4a990ad0ff2bb0df89a68a82023bb94653749 Mon Sep 17 00:00:00 2001 -From: Peng Ma -Date: Thu, 12 Dec 2019 11:13:44 +0800 -Subject: [PATCH] arm64: dts: ls1028a: Update edma compatible to fit eDMA - driver - -The eDMA of LS1028A soc has a little bit different from others, So we -should distinguish them in driver by compatible. - -Signed-off-by: Peng Ma ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -325,7 +325,7 @@ - - edma0: dma-controller@22c0000 { - #dma-cells = <2>; -- compatible = "fsl,vf610-edma"; -+ compatible = "fsl,ls1028a-edma"; - reg = <0x0 0x22c0000 0x0 0x10000>, - <0x0 0x22d0000 0x0 0x10000>, - <0x0 0x22e0000 0x0 0x10000>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0104-arm64-dts-lx2160a-add-iommu-map-property-to-pci-node.patch b/target/linux/layerscape/patches-5.4/302-dts-0104-arm64-dts-lx2160a-add-iommu-map-property-to-pci-node.patch deleted file mode 100644 index 02c46f554a..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0104-arm64-dts-lx2160a-add-iommu-map-property-to-pci-node.patch +++ /dev/null @@ -1,65 +0,0 @@ -From ad5077a8da6e8aad01b7b6ad979b52c39118969d Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 17 Dec 2019 13:26:37 +0200 -Subject: [PATCH] arm64: dts: lx2160a: add iommu-map property to pci nodes - -Add the iommu-map property to the pci nodes so that the firmware -fixes it up with the required values thus enabling iommu for -devices connected over pci. - -Signed-off-by: Laurentiu Tudor -Acked-by: Li Yang ---- - arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -954,6 +954,7 @@ - bus-range = <0x0 0xff>; - ranges = <0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>, -@@ -990,6 +991,7 @@ - bus-range = <0x0 0xff>; - ranges = <0x82000000 0x0 0x40000000 0x88 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>, -@@ -1026,6 +1028,7 @@ - bus-range = <0x0 0xff>; - ranges = <0x82000000 0x0 0x40000000 0x90 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, -@@ -1063,6 +1066,7 @@ - bus-range = <0x0 0xff>; - ranges = <0x82000000 0x0 0x40000000 0x98 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, -@@ -1099,6 +1103,7 @@ - bus-range = <0x0 0xff>; - ranges = <0x82000000 0x0 0x40000000 0xa0 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>, -@@ -1136,6 +1141,7 @@ - bus-range = <0x0 0xff>; - ranges = <0x82000000 0x0 0x40000000 0xa8 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ - msi-parent = <&its>; -+ iommu-map = <0 &smmu 0 1>; /* This is fixed-up by u-boot */ - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0000 0 0 1 &gic 0 0 GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>, diff --git a/target/linux/layerscape/patches-5.4/302-dts-0105-LF-18-1-arm64-dts-ls1088ardb-Update-qspi-dts-node-pr.patch b/target/linux/layerscape/patches-5.4/302-dts-0105-LF-18-1-arm64-dts-ls1088ardb-Update-qspi-dts-node-pr.patch deleted file mode 100644 index bbe452bc73..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0105-LF-18-1-arm64-dts-ls1088ardb-Update-qspi-dts-node-pr.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 8f29fafb9c3b0936fb6f67212057127c13e17c1c Mon Sep 17 00:00:00 2001 -From: Kuldeep Singh -Date: Tue, 7 Jan 2020 17:22:24 +0530 -Subject: [PATCH] LF-18-1 arm64: dts: ls1088ardb: Update qspi dts node - properties - -Use compatibles as "jedec,spi-nor" to probe flash without displaying -warning: found s25fs512s, expected m25p80. -Also remove "fsl,qspi-has-second-chip" property as new driver doesn't use -it anymore. - -Update dtsi compatibles to use "fsl,ls2080a-qspi". - -Signed-off-by: Kuldeep Singh ---- - arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts | 18 +++++++++--------- - arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 2 +- - 2 files changed, 10 insertions(+), 10 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts -@@ -76,25 +76,25 @@ - - &qspi { - status = "okay"; -- fsl,qspi-has-second-chip; -- qflash0: s25fs512s@0 { -- compatible = "spansion,m25p80"; -+ -+ s25fs512s0: flash@0 { -+ compatible = "jedec,spi-nor"; - #address-cells = <1>; - #size-cells = <1>; - spi-max-frequency = <20000000>; - reg = <0>; -- spi-rx-bus-width = <4>; -- spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <1>; -+ spi-tx-bus-width = <1>; - }; - -- qflash1: s25fs512s@1 { -- compatible = "spansion,m25p80"; -+ s25fs512s1: flash@1 { -+ compatible = "jedec,spi-nor"; - #address-cells = <1>; - #size-cells = <1>; - spi-max-frequency = <20000000>; - reg = <1>; -- spi-rx-bus-width = <4>; -- spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <1>; -+ spi-tx-bus-width = <1>; - }; - - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi -@@ -430,7 +430,7 @@ - status = "disabled"; - }; - qspi: spi@20c0000 { -- compatible = "fsl,ls2080a-qspi", "fsl,ls1088a-qspi"; -+ compatible = "fsl,ls2080a-qspi"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x0 0x20c0000 0x0 0x10000>, diff --git a/target/linux/layerscape/patches-5.4/302-dts-0106-LF-18-2-arm64-dts-ls1046ardb-Update-qspi-node-dts-pr.patch b/target/linux/layerscape/patches-5.4/302-dts-0106-LF-18-2-arm64-dts-ls1046ardb-Update-qspi-node-dts-pr.patch deleted file mode 100644 index 66746b0ebc..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0106-LF-18-2-arm64-dts-ls1046ardb-Update-qspi-node-dts-pr.patch +++ /dev/null @@ -1,52 +0,0 @@ -From ae5dad214ec109cdeffd3fac5ce4be6ab59a0283 Mon Sep 17 00:00:00 2001 -From: Kuldeep Singh -Date: Fri, 3 Jan 2020 14:49:07 +0530 -Subject: [PATCH] LF-18-2 arm64: dts: ls1046ardb: Update qspi node dts - properties - -Use compatibles as "jedec,spi-nor" to probe flash without displaying -warning: found s25fs512s, expected m25p80. -Remove "fsl,qspi-has-second-chip" as new driver doesn't use it anymore. -Update rx and tx width to 1. - -Signed-off-by: Kuldeep Singh ---- - arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 17 ++++++++--------- - 1 file changed, 8 insertions(+), 9 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts -@@ -100,25 +100,24 @@ - - &qspi { - status = "okay"; -- fsl,qspi-has-second-chip; - -- qflash0: flash@0 { -- compatible = "spansion,m25p80"; -+ s25fs512s0: flash@0 { -+ compatible = "jedec,spi-nor"; - #address-cells = <1>; - #size-cells = <1>; - spi-max-frequency = <50000000>; -- spi-rx-bus-width = <4>; -- spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <1>; -+ spi-tx-bus-width = <1>; - reg = <0>; - }; - -- qflash1: flash@1 { -- compatible = "spansion,m25p80"; -+ s25fs512s: flash@1 { -+ compatible = "jedec,spi-nor"; - #address-cells = <1>; - #size-cells = <1>; - spi-max-frequency = <50000000>; -- spi-rx-bus-width = <4>; -- spi-tx-bus-width = <4>; -+ spi-rx-bus-width = <1>; -+ spi-tx-bus-width = <1>; - reg = <1>; - }; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0107-arm64-dts-ls1012ardb-Update-qspi-node-property.patch b/target/linux/layerscape/patches-5.4/302-dts-0107-arm64-dts-ls1012ardb-Update-qspi-node-property.patch deleted file mode 100644 index 19f9d80d07..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0107-arm64-dts-ls1012ardb-Update-qspi-node-property.patch +++ /dev/null @@ -1,43 +0,0 @@ -From d870db86f12a69361472fc86bc516b89d9bf468c Mon Sep 17 00:00:00 2001 -From: Kuldeep Singh -Date: Wed, 8 Jan 2020 15:50:44 +0530 -Subject: [PATCH] arm64: dts: ls1012ardb: Update qspi node property - -Use generic node name and specific label name. -Add m25p,fast-read. - -Use dt-bindings constants in interrupts instead of using numbers. - -Signed-off-by: Kuldeep Singh ---- - arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts | 3 ++- - arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi | 2 +- - 2 files changed, 3 insertions(+), 2 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-rdb.dts -@@ -89,11 +89,12 @@ - &qspi { - status = "okay"; - -- qflash0: s25fs512s@0 { -+ s25fs512s0: flash@0 { - compatible = "jedec,spi-nor"; - #address-cells = <1>; - #size-cells = <1>; - spi-max-frequency = <20000000>; -+ m25p,fast-read; - reg = <0>; - spi-rx-bus-width = <1>; - spi-tx-bus-width = <1>; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi -@@ -392,7 +392,7 @@ - reg = <0x0 0x1550000 0x0 0x10000>, - <0x0 0x40000000 0x0 0x10000000>; - reg-names = "QuadSPI", "QuadSPI-memory"; -- interrupts = <0 99 IRQ_TYPE_LEVEL_HIGH>; -+ interrupts = ; - clock-names = "qspi_en", "qspi"; - clocks = <&clockgen 4 0>, <&clockgen 4 0>; - status = "disabled"; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0109-arm64-dts-ls1028a-rdb-Enable-SGMII-AN-for-the-QSGMII.patch b/target/linux/layerscape/patches-5.4/302-dts-0109-arm64-dts-ls1028a-rdb-Enable-SGMII-AN-for-the-QSGMII.patch deleted file mode 100644 index 33d7109740..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0109-arm64-dts-ls1028a-rdb-Enable-SGMII-AN-for-the-QSGMII.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 57c0539d99fed2252364b431de004f9110ac3d3f Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Fri, 6 Dec 2019 13:59:05 +0200 -Subject: [PATCH] arm64: dts: ls1028a-rdb: Enable SGMII AN for the QSGMII - switch ports - -This enables monitoring of link status and AN. It should also physically -enable SGMII AN with the VSC8514 PHY, but in practice that is still -hardcoded as "on" in the PHY driver, at the moment. So since Felix -actually disables SGMII AN when this DT property is absent, this would -result in an in-band AN mismatch between the MAC and the PHY. So this -property is required for the moment for this MAC/PHY combination. - -Signed-off-by: Vladimir Oltean ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -@@ -236,21 +236,25 @@ - &switch_port0 { - phy-handle = <&qsgmii_phy1>; - phy-connection-type = "qsgmii"; -+ managed = "in-band-status"; - }; - - &switch_port1 { - phy-handle = <&qsgmii_phy2>; - phy-connection-type = "qsgmii"; -+ managed = "in-band-status"; - }; - - &switch_port2 { - phy-handle = <&qsgmii_phy3>; - phy-connection-type = "qsgmii"; -+ managed = "in-band-status"; - }; - - &switch_port3 { - phy-handle = <&qsgmii_phy4>; - phy-connection-type = "qsgmii"; -+ managed = "in-band-status"; - }; - - &sai4 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0110-arm64-dts-ls1028a-Disable-swp5-by-default.patch b/target/linux/layerscape/patches-5.4/302-dts-0110-arm64-dts-ls1028a-Disable-swp5-by-default.patch deleted file mode 100644 index 8c81a4560c..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0110-arm64-dts-ls1028a-Disable-swp5-by-default.patch +++ /dev/null @@ -1,22 +0,0 @@ -From fd73bb7cf812fcb96116f70393d3e66aa4ddc1fa Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Fri, 6 Dec 2019 13:56:46 +0200 -Subject: [PATCH] arm64: dts: ls1028a: Disable swp5 by default - -This was missed when moving the CPU port and disabling eno3. - -Signed-off-by: Vladimir Oltean ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -808,6 +808,7 @@ - port@5 { - reg = <5>; - phy-mode = "gmii"; -+ status = "disabled"; - - fixed-link { - speed = <2500>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0111-arm64-dts-fsl-ls1028a-rdb-fix-QSGMII-PHY-node-names.patch b/target/linux/layerscape/patches-5.4/302-dts-0111-arm64-dts-fsl-ls1028a-rdb-fix-QSGMII-PHY-node-names.patch deleted file mode 100644 index dbea8abfb6..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0111-arm64-dts-fsl-ls1028a-rdb-fix-QSGMII-PHY-node-names.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 85252792bc07b398582e8dacf6ec6d09a5075195 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 7 Jan 2020 15:15:29 +0200 -Subject: [PATCH] arm64: dts: fsl-ls1028a-rdb: fix QSGMII PHY node names - -Use ethernet-phy@ADDR, previously the numbers were wrong. - -Signed-off-by: Alex Marginean ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -@@ -215,19 +215,19 @@ - }; - - &enetc_mdio_pf3 { -- qsgmii_phy1: ethernet-phy@4 { -+ qsgmii_phy1: ethernet-phy@10 { - reg = <0x10>; - }; - -- qsgmii_phy2: ethernet-phy@5 { -+ qsgmii_phy2: ethernet-phy@11 { - reg = <0x11>; - }; - -- qsgmii_phy3: ethernet-phy@6 { -+ qsgmii_phy3: ethernet-phy@12 { - reg = <0x12>; - }; - -- qsgmii_phy4: ethernet-phy@7 { -+ qsgmii_phy4: ethernet-phy@13 { - reg = <0x13>; - }; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0112-arm64-dts-fsl-ls1028a-prepare-dts-for-overlay.patch b/target/linux/layerscape/patches-5.4/302-dts-0112-arm64-dts-fsl-ls1028a-prepare-dts-for-overlay.patch deleted file mode 100644 index 4b20e42794..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0112-arm64-dts-fsl-ls1028a-prepare-dts-for-overlay.patch +++ /dev/null @@ -1,452 +0,0 @@ -From a5009b362d65c24e7b2a40824e351903d75a47dc Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Mon, 6 Jan 2020 16:36:44 +0200 -Subject: [PATCH] arm64: dts: fsl-ls1028a: prepare dts for overlay - -Named the ports node of the Felix Eth switch so it can be used in DT -overlays to associate the ports with proper PHYs. -Ports are now by default disabled in dtsi, so if the board dts doesn't -do anything about them they stay disabled. -Updated RDB and QDS dts files to match. -Replaced all 'phy-connection-type' with 'phy-mode'. -The set-up for protocol 7777 on QDS was changed to a single quad port card -in slot 1. This requires a QDS board with no lane B rework and a AQR412 -or similar PHY card without any lane rework done on it. - -Signed-off-by: Alex Marginean ---- - .../boot/dts/freescale/fsl-ls1028a-qds-7777.dtsi | 58 ++++++++++----------- - .../boot/dts/freescale/fsl-ls1028a-qds-9999.dtsi | 59 ++++++++++------------ - .../boot/dts/freescale/fsl-ls1028a-qds-x3xx.dtsi | 51 ++++++++++++------- - .../boot/dts/freescale/fsl-ls1028a-qds-x5xx.dtsi | 43 ++++++++++------ - arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts | 44 +++++++++------- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 27 +++++++--- - 6 files changed, 161 insertions(+), 121 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dtsi -@@ -7,50 +7,50 @@ - */ - - &mdio_slot1 { -- /* two ports on AQR412 */ -- slot1_sxgmii2: ethernet-phy@2 { -- reg = <0x2>; -+ slot1_sxgmii0: ethernet-phy@0 { -+ reg = <0x0>; - compatible = "ethernet-phy-ieee802.3-c45"; - }; -- slot1_sxgmii3: ethernet-phy@3 { -- reg = <0x3>; -+ -+ slot1_sxgmii1: ethernet-phy@1 { -+ reg = <0x1>; - compatible = "ethernet-phy-ieee802.3-c45"; - }; --}; - --&mdio_slot2 { -- slot2_sxgmii0: ethernet-phy@2 { -- /* AQR112 */ -+ slot1_sxgmii2: ethernet-phy@2 { - reg = <0x2>; - compatible = "ethernet-phy-ieee802.3-c45"; - }; --}; - --&mdio_slot3 { -- slot3_sxgmii0: ethernet-phy@2 { -- /* AQR112 */ -- reg = <0x2>; -+ slot1_sxgmii3: ethernet-phy@3 { -+ reg = <0x3>; - compatible = "ethernet-phy-ieee802.3-c45"; - }; - }; - - /* l2switch ports */ --&switch_port0 { -- phy-handle = <&slot1_sxgmii2>; -- phy-connection-type = "2500base-x"; --}; -+&mscc_felix_ports { -+ port@0 { -+ status = "okay"; -+ phy-handle = <&slot1_sxgmii0>; -+ phy-mode = "2500base-x"; -+ }; - --&switch_port1 { -- phy-handle = <&slot2_sxgmii0>; -- phy-connection-type = "2500base-x"; --}; -+ port@1 { -+ status = "okay"; -+ phy-handle = <&slot1_sxgmii1>; -+ phy-mode = "2500base-x"; -+ }; - --&switch_port2 { -- phy-handle = <&slot3_sxgmii0>; -- phy-connection-type = "2500base-x"; --}; -+ port@2 { -+ status = "okay"; -+ phy-handle = <&slot1_sxgmii2>; -+ phy-mode = "2500base-x"; -+ }; - --&switch_port3 { -- phy-handle = <&slot1_sxgmii3>; -- phy-connection-type = "2500base-x"; -+ port@3 { -+ status = "okay"; -+ phy-handle = <&slot1_sxgmii3>; -+ phy-mode = "2500base-x"; -+ }; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dtsi -@@ -11,50 +11,47 @@ - slot1_sgmii0: ethernet-phy@1c { - reg = <0x1c>; - }; -+ - slot1_sgmii1: ethernet-phy@1d { - reg = <0x1d>; - }; -+ - slot1_sgmii2: ethernet-phy@1e { - reg = <0x1e>; - }; -- slot1_sgmii3: ethernet-phy@1f { -- reg = <0x1f>; -- }; --}; - --&mdio_slot2 { -- /* VSC8234 */ -- slot2_sgmii0: ethernet-phy@1c { -- reg = <0x1c>; -- }; -- slot2_sgmii1: ethernet-phy@1d { -- reg = <0x1d>; -- }; -- slot2_sgmii2: ethernet-phy@1e { -- reg = <0x1e>; -- }; -- slot2_sgmii3: ethernet-phy@1f { -+ slot1_sgmii3: ethernet-phy@1f { - reg = <0x1f>; - }; - }; - - /* l2switch ports */ --&switch_port0 { -- phy-handle = <&slot1_sgmii0>; -- phy-connection-type = "sgmii"; --}; -+&mscc_felix_ports { -+ port@0 { -+ status = "okay"; -+ phy-handle = <&slot1_sgmii0>; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port1 { -- phy-handle = <&slot2_sgmii0>; -- phy-connection-type = "sgmii"; --}; -+ port@1 { -+ status = "okay"; -+ phy-handle = <&slot1_sgmii1>; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port2 { -- phy-handle = <&slot1_sgmii2>; -- phy-connection-type = "sgmii"; --}; -+ port@2 { -+ status = "okay"; -+ phy-handle = <&slot1_sgmii2>; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port3 { -- phy-handle = <&slot1_sgmii3>; -- phy-connection-type = "sgmii"; -+ port@3 { -+ status = "okay"; -+ phy-handle = <&slot1_sgmii3>; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ }; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x3xx.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x3xx.dtsi -@@ -8,41 +8,54 @@ - - &mdio_slot2 { - /* 4 ports on AQR412 */ -- slot2_qsgmii0: ethernet-phy@0 { -+ slot2_qxgmii0: ethernet-phy@0 { - reg = <0x0>; - compatible = "ethernet-phy-ieee802.3-c45"; - }; -- slot2_qsgmii1: ethernet-phy@1 { -+ -+ slot2_qxgmii1: ethernet-phy@1 { - reg = <0x1>; - compatible = "ethernet-phy-ieee802.3-c45"; - }; -- slot2_qsgmii2: ethernet-phy@2 { -+ -+ slot2_qxgmii2: ethernet-phy@2 { - reg = <0x2>; - compatible = "ethernet-phy-ieee802.3-c45"; - }; -- slot2_qsgmii3: ethernet-phy@3 { -+ -+ slot2_qxgmii3: ethernet-phy@3 { - reg = <0x3>; - compatible = "ethernet-phy-ieee802.3-c45"; - }; - }; - - /* l2switch ports */ --&switch_port0 { -- phy-handle = <&slot2_qsgmii0>; -- phy-connection-type = "usxgmii"; --}; -+&mscc_felix_ports { -+ port@0 { -+ status = "okay"; -+ phy-handle = <&slot2_qxgmii0>; -+ phy-mode = "usxgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port1 { -- phy-handle = <&slot2_qsgmii1>; -- phy-connection-type = "usxgmii"; --}; -+ port@1 { -+ status = "okay"; -+ phy-handle = <&slot2_qxgmii1>; -+ phy-mode = "usxgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port2 { -- phy-handle = <&slot2_qsgmii2>; -- phy-connection-type = "usxgmii"; --}; -+ port@2 { -+ status = "okay"; -+ phy-handle = <&slot2_qxgmii2>; -+ phy-mode = "usxgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port3 { -- phy-handle = <&slot2_qsgmii3>; -- phy-connection-type = "usxgmii"; -+ port@3 { -+ status = "okay"; -+ phy-handle = <&slot2_qxgmii3>; -+ phy-mode = "usxgmii"; -+ managed = "in-band-status"; -+ }; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x5xx.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x5xx.dtsi -@@ -11,34 +11,47 @@ - slot2_qsgmii0: ethernet-phy@8 { - reg = <0x8>; - }; -+ - slot2_qsgmii1: ethernet-phy@9 { - reg = <0x9>; - }; -+ - slot2_qsgmii2: ethernet-phy@a { - reg = <0xa>; - }; -+ - slot2_qsgmii3: ethernet-phy@b { - reg = <0xb>; - }; - }; - - /* l2switch ports */ --&switch_port0 { -- phy-handle = <&slot2_qsgmii0>; -- phy-connection-type = "qsgmii"; --}; -+&mscc_felix_ports { -+ port@0 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii0>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port1 { -- phy-handle = <&slot2_qsgmii1>; -- phy-connection-type = "qsgmii"; --}; -+ port@1 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii1>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port2 { -- phy-handle = <&slot2_qsgmii2>; -- phy-connection-type = "qsgmii"; --}; -+ port@2 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii2>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port3 { -- phy-handle = <&slot2_qsgmii3>; -- phy-connection-type = "qsgmii"; -+ port@3 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii3>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; - }; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts -@@ -233,28 +233,34 @@ - }; - - /* l2switch ports */ --&switch_port0 { -- phy-handle = <&qsgmii_phy1>; -- phy-connection-type = "qsgmii"; -- managed = "in-band-status"; --}; -+&mscc_felix_ports { -+ port@0 { -+ status = "okay"; -+ phy-handle = <&qsgmii_phy1>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port1 { -- phy-handle = <&qsgmii_phy2>; -- phy-connection-type = "qsgmii"; -- managed = "in-band-status"; --}; -+ port@1 { -+ status = "okay"; -+ phy-handle = <&qsgmii_phy2>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port2 { -- phy-handle = <&qsgmii_phy3>; -- phy-connection-type = "qsgmii"; -- managed = "in-band-status"; --}; -+ port@2 { -+ status = "okay"; -+ phy-handle = <&qsgmii_phy3>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; - --&switch_port3 { -- phy-handle = <&qsgmii_phy4>; -- phy-connection-type = "qsgmii"; -- managed = "in-band-status"; -+ port@3 { -+ status = "okay"; -+ phy-handle = <&qsgmii_phy4>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; - }; - - &sai4 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -772,30 +772,39 @@ - clocks = <&clockgen 2 3>; - little-endian; - }; -- switch@0,5 { -+ -+ ethernet-switch@0,5 { - reg = <0x000500 0 0 0 0>; - /* IEP INT_B */ - interrupts = ; - -- ports { -+ mscc_felix_ports: ports { - #address-cells = <1>; - #size-cells = <0>; - - /* external ports */ -- switch_port0: port@0 { -+ mscc_felix_port0: port@0 { - reg = <0>; -+ status = "disabled"; - }; -- switch_port1: port@1 { -+ -+ mscc_felix_port1: port@1 { - reg = <1>; -+ status = "disabled"; - }; -- switch_port2: port@2 { -+ -+ mscc_felix_port2: port@2 { - reg = <2>; -+ status = "disabled"; - }; -- switch_port3: port@3 { -+ -+ mscc_felix_port3: port@3 { - reg = <3>; -+ status = "disabled"; - }; -+ - /* internal to-cpu ports */ -- port@4 { -+ mscc_felix_port4: port@4 { - reg = <4>; - ethernet = <&enetc_port2>; - phy-mode = "gmii"; -@@ -805,7 +814,8 @@ - full-duplex; - }; - }; -- port@5 { -+ -+ mscc_felix_port5: port@5 { - reg = <5>; - phy-mode = "gmii"; - status = "disabled"; -@@ -817,6 +827,7 @@ - }; - }; - }; -+ - enetc_port3: ethernet@0,6 { - compatible = "fsl,enetc"; - reg = <0x000600 0 0 0 0>; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0113-arm64-dts-fsl-ls1028a-qds-Add-overlays-for-various-s.patch b/target/linux/layerscape/patches-5.4/302-dts-0113-arm64-dts-fsl-ls1028a-qds-Add-overlays-for-various-s.patch deleted file mode 100644 index faa7c58bf1..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0113-arm64-dts-fsl-ls1028a-qds-Add-overlays-for-various-s.patch +++ /dev/null @@ -1,893 +0,0 @@ -From d2333a40b00ba5fb5b9731f96ca663036f781411 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 7 Jan 2020 14:48:20 +0200 -Subject: [PATCH] arm64: dts: fsl-ls1028a-qds: Add overlays for various serdes - protocols - -Adds overlays for various serdes protocols on LS1028A QDS board using -different PHY cards. These should be applied at boot, based on serdes -configuration. If no overlay is applied, only the RGMII interface on -the QDS is available in Linux. - -Signed-off-by: Alex Marginean ---- - arch/arm64/boot/dts/freescale/Makefile | 6 ++ - .../boot/dts/freescale/fsl-ls1028a-qds-13bb.dts | 100 +++++++++++++++++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-1xxx.dtsi | 20 ----- - .../boot/dts/freescale/fsl-ls1028a-qds-65bb.dts | 94 +++++++++++++++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-6xxx.dtsi | 20 ----- - .../boot/dts/freescale/fsl-ls1028a-qds-7777.dts | 73 +++++++++++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-7777.dtsi | 56 ------------ - .../boot/dts/freescale/fsl-ls1028a-qds-85bb.dts | 93 +++++++++++++++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-899b.dts | 66 ++++++++++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-8xxx.dtsi | 19 ---- - .../boot/dts/freescale/fsl-ls1028a-qds-9999.dts | 71 +++++++++++++++ - .../boot/dts/freescale/fsl-ls1028a-qds-9999.dtsi | 57 ------------ - .../boot/dts/freescale/fsl-ls1028a-qds-x3xx.dtsi | 61 ------------- - .../boot/dts/freescale/fsl-ls1028a-qds-x5xx.dtsi | 57 ------------ - arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 3 - - 15 files changed, 503 insertions(+), 293 deletions(-) - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts - delete mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-1xxx.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts - delete mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-6xxx.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts - delete mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts - delete mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-8xxx.dtsi - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts - delete mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dtsi - delete mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x3xx.dtsi - delete mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x5xx.dtsi - ---- a/arch/arm64/boot/dts/freescale/Makefile -+++ b/arch/arm64/boot/dts/freescale/Makefile -@@ -6,6 +6,12 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1 - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-qds.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-rdb.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-13bb.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-65bb.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-7777.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-85bb.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-899b.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-9999.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds-sdk.dtb ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts -@@ -0,0 +1,100 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree fragment for LS1028A QDS board, serdes 13bb -+ * -+ * Copyright 2019 NXP -+ * -+ * Requires a LS1028A QDS board with lane B rework. -+ * Requires a SCH-30841 card with lane A of connector rewired to PHY lane C. -+ * Set-up is a SCH-30842 card in slot 1 and SCH-30841 in slot 2. -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ fragment@0 { -+ target = <&mdio_slot1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ slot1_sgmii: ethernet-phy@2 { -+ /* AQR112 */ -+ reg = <0x2>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&enetc_port0>; -+ __overlay__ { -+ phy-handle = <&slot1_sgmii>; -+ phy-mode = "usxgmii"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&mdio_slot2>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* 4 ports on AQR412 */ -+ slot2_qxgmii0: ethernet-phy@0 { -+ reg = <0x0>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ -+ slot2_qxgmii1: ethernet-phy@1 { -+ reg = <0x1>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ -+ slot2_qxgmii2: ethernet-phy@2 { -+ reg = <0x2>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ -+ slot2_qxgmii3: ethernet-phy@3 { -+ reg = <0x3>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&mscc_felix_ports>; -+ __overlay__ { -+ port@0 { -+ status = "okay"; -+ phy-handle = <&slot2_qxgmii0>; -+ phy-mode = "usxgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@1 { -+ status = "okay"; -+ phy-handle = <&slot2_qxgmii1>; -+ phy-mode = "usxgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@2 { -+ status = "okay"; -+ phy-handle = <&slot2_qxgmii2>; -+ phy-mode = "usxgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@3 { -+ status = "okay"; -+ phy-handle = <&slot2_qxgmii3>; -+ phy-mode = "usxgmii"; -+ managed = "in-band-status"; -+ }; -+ }; -+ }; -+}; -+ ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-1xxx.dtsi -+++ /dev/null -@@ -1,20 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR MIT) --/* -- * Device Tree Include file for LS1028A QDS board, serdes 1xxx -- * -- * Copyright 2019 NXP -- * -- */ -- --&mdio_slot1 { -- slot1_sgmii: ethernet-phy@2 { -- /* AQR112 */ -- reg = <0x2>; -- compatible = "ethernet-phy-ieee802.3-c45"; -- }; --}; -- --&enetc_port0 { -- phy-handle = <&slot1_sgmii>; -- phy-connection-type = "usxgmii"; --}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts -@@ -0,0 +1,94 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree fragment for LS1028A QDS board, serdes 69xx -+ * -+ * Copyright 2019 NXP -+ * -+ * Requires a LS1028A QDS board with lane B rework. -+ * Requires a SCH-30842 card in slot 1 and a SCH-28021 card in slot 2. -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ fragment@0 { -+ target = <&mdio_slot1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ slot1_sgmii: ethernet-phy@2 { -+ /* AQR112 */ -+ reg = <0x2>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&enetc_port0>; -+ __overlay__ { -+ phy-handle = <&slot1_sgmii>; -+ phy-mode = "2500base-x"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&mdio_slot2>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* 4 ports on VSC8514 */ -+ slot2_qsgmii0: ethernet-phy@8 { -+ reg = <0x8>; -+ }; -+ -+ slot2_qsgmii1: ethernet-phy@9 { -+ reg = <0x9>; -+ }; -+ -+ slot2_qsgmii2: ethernet-phy@a { -+ reg = <0xa>; -+ }; -+ -+ slot2_qsgmii3: ethernet-phy@b { -+ reg = <0xb>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&mscc_felix_ports>; -+ __overlay__ { -+ port@0 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii0>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@1 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii1>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@2 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii2>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@3 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii3>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; -+ }; -+ }; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-6xxx.dtsi -+++ /dev/null -@@ -1,20 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR MIT) --/* -- * Device Tree Include file for LS1028A QDS board, serdes 6xxx -- * -- * Copyright 2019 NXP -- * -- */ -- --&mdio_slot1 { -- slot1_sgmii: ethernet-phy@2 { -- /* AQR112 */ -- reg = <0x2>; -- compatible = "ethernet-phy-ieee802.3-c45"; -- }; --}; -- --&enetc_port0 { -- phy-handle = <&slot1_sgmii>; -- phy-connection-type = "2500base-x"; --}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts -@@ -0,0 +1,73 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree fragment for LS1028A QDS board, serdes 7777 -+ * -+ * Copyright 2019 NXP -+ * -+ * Requires a LS1028A QDS board without lane B rework. -+ * Requires a SCH-30841 card without lane A/C rewire and with a FW with muxing -+ * disabled, plugged in slot 1. -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ fragment@0 { -+ target = <&mdio_slot1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* 4 ports on AQR412 */ -+ slot1_sxgmii0: ethernet-phy@0 { -+ reg = <0x0>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ -+ slot1_sxgmii1: ethernet-phy@1 { -+ reg = <0x1>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ -+ slot1_sxgmii2: ethernet-phy@2 { -+ reg = <0x2>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ -+ slot1_sxgmii3: ethernet-phy@3 { -+ reg = <0x3>; -+ compatible = "ethernet-phy-ieee802.3-c45"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&mscc_felix_ports>; -+ __overlay__ { -+ port@0 { -+ status = "okay"; -+ phy-handle = <&slot1_sxgmii0>; -+ phy-mode = "2500base-x"; -+ }; -+ -+ port@1 { -+ status = "okay"; -+ phy-handle = <&slot1_sxgmii1>; -+ phy-mode = "2500base-x"; -+ }; -+ -+ port@2 { -+ status = "okay"; -+ phy-handle = <&slot1_sxgmii2>; -+ phy-mode = "2500base-x"; -+ }; -+ -+ port@3 { -+ status = "okay"; -+ phy-handle = <&slot1_sxgmii3>; -+ phy-mode = "2500base-x"; -+ }; -+ }; -+ }; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dtsi -+++ /dev/null -@@ -1,56 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR MIT) --/* -- * Device Tree Include file for LS1028A QDS board, serdes 9999 -- * -- * Copyright 2019 NXP -- * -- */ -- --&mdio_slot1 { -- slot1_sxgmii0: ethernet-phy@0 { -- reg = <0x0>; -- compatible = "ethernet-phy-ieee802.3-c45"; -- }; -- -- slot1_sxgmii1: ethernet-phy@1 { -- reg = <0x1>; -- compatible = "ethernet-phy-ieee802.3-c45"; -- }; -- -- slot1_sxgmii2: ethernet-phy@2 { -- reg = <0x2>; -- compatible = "ethernet-phy-ieee802.3-c45"; -- }; -- -- slot1_sxgmii3: ethernet-phy@3 { -- reg = <0x3>; -- compatible = "ethernet-phy-ieee802.3-c45"; -- }; --}; -- --/* l2switch ports */ --&mscc_felix_ports { -- port@0 { -- status = "okay"; -- phy-handle = <&slot1_sxgmii0>; -- phy-mode = "2500base-x"; -- }; -- -- port@1 { -- status = "okay"; -- phy-handle = <&slot1_sxgmii1>; -- phy-mode = "2500base-x"; -- }; -- -- port@2 { -- status = "okay"; -- phy-handle = <&slot1_sxgmii2>; -- phy-mode = "2500base-x"; -- }; -- -- port@3 { -- status = "okay"; -- phy-handle = <&slot1_sxgmii3>; -- phy-mode = "2500base-x"; -- }; --}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts -@@ -0,0 +1,93 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree fragment for LS1028A QDS board, serdes 85bb -+ * -+ * Copyright 2019 NXP -+ * -+ * Requires a LS1028A QDS board with lane B rework. -+ * Requires a SCH-24801 card in slot 1 and a SCH-28021 card in slot 2. -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ fragment@0 { -+ target = <&mdio_slot1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ slot1_sgmii: ethernet-phy@1c { -+ /* 1st port on VSC8234 */ -+ reg = <0x1c>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&enetc_port0>; -+ __overlay__ { -+ phy-handle = <&slot1_sgmii>; -+ phy-mode = "sgmii"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&mdio_slot2>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* 4 ports on VSC8514 */ -+ slot2_qsgmii0: ethernet-phy@8 { -+ reg = <0x8>; -+ }; -+ -+ slot2_qsgmii1: ethernet-phy@9 { -+ reg = <0x9>; -+ }; -+ -+ slot2_qsgmii2: ethernet-phy@a { -+ reg = <0xa>; -+ }; -+ -+ slot2_qsgmii3: ethernet-phy@b { -+ reg = <0xb>; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target = <&mscc_felix_ports>; -+ __overlay__ { -+ port@0 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii0>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@1 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii1>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@2 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii2>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@3 { -+ status = "okay"; -+ phy-handle = <&slot2_qsgmii3>; -+ phy-mode = "qsgmii"; -+ managed = "in-band-status"; -+ }; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts -@@ -0,0 +1,66 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree fragment for LS1028A QDS board, serdes 85xx -+ * -+ * Copyright 2019 NXP -+ * -+ * Requires a LS1028A QDS board without lane B rework. -+ * Requires a SCH-24801 card in slot 1. -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ fragment@0 { -+ target = <&mdio_slot1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* VSC8234 */ -+ slot1_sgmii0: ethernet-phy@1c { -+ reg = <0x1c>; -+ }; -+ -+ slot1_sgmii1: ethernet-phy@1d { -+ reg = <0x1d>; -+ }; -+ -+ slot1_sgmii2: ethernet-phy@1e { -+ reg = <0x1e>; -+ }; -+ -+ slot1_sgmii3: ethernet-phy@1f { -+ reg = <0x1f>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&enetc_port0>; -+ __overlay__ { -+ phy-handle = <&slot1_sgmii0>; -+ phy-mode = "sgmii"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&mscc_felix_ports>; -+ __overlay__ { -+ port@1 { -+ status = "okay"; -+ phy-handle = <&slot1_sgmii1>; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@2 { -+ status = "okay"; -+ phy-handle = <&slot1_sgmii2>; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ }; -+ }; -+ }; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-8xxx.dtsi -+++ /dev/null -@@ -1,19 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR MIT) --/* -- * Device Tree Include file for LS1028A QDS board, serdes 8xxx -- * -- * Copyright 2019 NXP -- * -- */ -- --&mdio_slot1 { -- slot1_sgmii: ethernet-phy@1c { -- /* 1st port on VSC8234 */ -- reg = <0x1c>; -- }; --}; -- --&enetc_port0 { -- phy-handle = <&slot1_sgmii>; -- phy-connection-type = "sgmii"; --}; ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts -@@ -0,0 +1,71 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * Device Tree fragment for LS1028A QDS board, serdes 85xx -+ * -+ * Copyright 2019 NXP -+ * -+ * Requires a LS1028A QDS board without lane B rework. -+ * Requires a SCH-24801 card in slot 1. -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ fragment@0 { -+ target = <&mdio_slot1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ /* VSC8234 */ -+ slot1_sgmii0: ethernet-phy@1c { -+ reg = <0x1c>; -+ }; -+ -+ slot1_sgmii1: ethernet-phy@1d { -+ reg = <0x1d>; -+ }; -+ -+ slot1_sgmii2: ethernet-phy@1e { -+ reg = <0x1e>; -+ }; -+ -+ slot1_sgmii3: ethernet-phy@1f { -+ reg = <0x1f>; -+ }; -+ }; -+ }; -+ fragment@1 { -+ target = <&mscc_felix_ports>; -+ __overlay__ { -+ port@0 { -+ status = "okay"; -+ phy-handle = <&slot1_sgmii0>; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@1 { -+ status = "okay"; -+ phy-handle = <&slot1_sgmii1>; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@2 { -+ status = "okay"; -+ phy-handle = <&slot1_sgmii2>; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ }; -+ -+ port@3 { -+ status = "okay"; -+ phy-handle = <&slot1_sgmii3>; -+ phy-mode = "sgmii"; -+ managed = "in-band-status"; -+ }; -+ }; -+ }; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dtsi -+++ /dev/null -@@ -1,57 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR MIT) --/* -- * Device Tree Include file for LS1028A QDS board, serdes 9999 -- * -- * Copyright 2019 NXP -- * -- */ -- --&mdio_slot1 { -- /* VSC8234 */ -- slot1_sgmii0: ethernet-phy@1c { -- reg = <0x1c>; -- }; -- -- slot1_sgmii1: ethernet-phy@1d { -- reg = <0x1d>; -- }; -- -- slot1_sgmii2: ethernet-phy@1e { -- reg = <0x1e>; -- }; -- -- slot1_sgmii3: ethernet-phy@1f { -- reg = <0x1f>; -- }; --}; -- --/* l2switch ports */ --&mscc_felix_ports { -- port@0 { -- status = "okay"; -- phy-handle = <&slot1_sgmii0>; -- phy-mode = "sgmii"; -- managed = "in-band-status"; -- }; -- -- port@1 { -- status = "okay"; -- phy-handle = <&slot1_sgmii1>; -- phy-mode = "sgmii"; -- managed = "in-band-status"; -- }; -- -- port@2 { -- status = "okay"; -- phy-handle = <&slot1_sgmii2>; -- phy-mode = "sgmii"; -- managed = "in-band-status"; -- }; -- -- port@3 { -- status = "okay"; -- phy-handle = <&slot1_sgmii3>; -- phy-mode = "sgmii"; -- managed = "in-band-status"; -- }; --}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x3xx.dtsi -+++ /dev/null -@@ -1,61 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR MIT) --/* -- * Device Tree Include file for LS1028A QDS board, serdes x3xx -- * -- * Copyright 2019 NXP -- * -- */ -- --&mdio_slot2 { -- /* 4 ports on AQR412 */ -- slot2_qxgmii0: ethernet-phy@0 { -- reg = <0x0>; -- compatible = "ethernet-phy-ieee802.3-c45"; -- }; -- -- slot2_qxgmii1: ethernet-phy@1 { -- reg = <0x1>; -- compatible = "ethernet-phy-ieee802.3-c45"; -- }; -- -- slot2_qxgmii2: ethernet-phy@2 { -- reg = <0x2>; -- compatible = "ethernet-phy-ieee802.3-c45"; -- }; -- -- slot2_qxgmii3: ethernet-phy@3 { -- reg = <0x3>; -- compatible = "ethernet-phy-ieee802.3-c45"; -- }; --}; -- --/* l2switch ports */ --&mscc_felix_ports { -- port@0 { -- status = "okay"; -- phy-handle = <&slot2_qxgmii0>; -- phy-mode = "usxgmii"; -- managed = "in-band-status"; -- }; -- -- port@1 { -- status = "okay"; -- phy-handle = <&slot2_qxgmii1>; -- phy-mode = "usxgmii"; -- managed = "in-band-status"; -- }; -- -- port@2 { -- status = "okay"; -- phy-handle = <&slot2_qxgmii2>; -- phy-mode = "usxgmii"; -- managed = "in-band-status"; -- }; -- -- port@3 { -- status = "okay"; -- phy-handle = <&slot2_qxgmii3>; -- phy-mode = "usxgmii"; -- managed = "in-band-status"; -- }; --}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-x5xx.dtsi -+++ /dev/null -@@ -1,57 +0,0 @@ --// SPDX-License-Identifier: (GPL-2.0+ OR MIT) --/* -- * Device Tree Include file for LS1028A QDS board, serdes x5xx -- * -- * Copyright 2019 NXP -- * -- */ -- --&mdio_slot2 { -- /* 4 ports on VSC8514 */ -- slot2_qsgmii0: ethernet-phy@8 { -- reg = <0x8>; -- }; -- -- slot2_qsgmii1: ethernet-phy@9 { -- reg = <0x9>; -- }; -- -- slot2_qsgmii2: ethernet-phy@a { -- reg = <0xa>; -- }; -- -- slot2_qsgmii3: ethernet-phy@b { -- reg = <0xb>; -- }; --}; -- --/* l2switch ports */ --&mscc_felix_ports { -- port@0 { -- status = "okay"; -- phy-handle = <&slot2_qsgmii0>; -- phy-mode = "qsgmii"; -- managed = "in-band-status"; -- }; -- -- port@1 { -- status = "okay"; -- phy-handle = <&slot2_qsgmii1>; -- phy-mode = "qsgmii"; -- managed = "in-band-status"; -- }; -- -- port@2 { -- status = "okay"; -- phy-handle = <&slot2_qsgmii2>; -- phy-mode = "qsgmii"; -- managed = "in-band-status"; -- }; -- -- port@3 { -- status = "okay"; -- phy-handle = <&slot2_qsgmii3>; -- phy-mode = "qsgmii"; -- managed = "in-band-status"; -- }; --}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts -@@ -277,6 +277,3 @@ - lane-mapping = <0x4e>; - status = "okay"; - }; -- --#include "fsl-ls1028a-qds-8xxx.dtsi" --#include "fsl-ls1028a-qds-x5xx.dtsi" diff --git a/target/linux/layerscape/patches-5.4/302-dts-0114-arm64-dts-fsl-ls1028a-add-labels-to-Ethernet-switch-.patch b/target/linux/layerscape/patches-5.4/302-dts-0114-arm64-dts-fsl-ls1028a-add-labels-to-Ethernet-switch-.patch deleted file mode 100644 index e4d5449d08..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0114-arm64-dts-fsl-ls1028a-add-labels-to-Ethernet-switch-.patch +++ /dev/null @@ -1,41 +0,0 @@ -From e8f521154dbf16a91cba229f7514cca8e136702e Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Mon, 6 Jan 2020 11:48:42 +0200 -Subject: [PATCH] arm64: dts: fsl-ls1028a: add labels to Ethernet switch ports - -Labels are used to name switch port net devices in Linux, use more -convenient names to make it simpler for users. - -Signed-off-by: Alex Marginean ---- - arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi -@@ -786,21 +786,25 @@ - mscc_felix_port0: port@0 { - reg = <0>; - status = "disabled"; -+ label = "swp0"; - }; - - mscc_felix_port1: port@1 { - reg = <1>; - status = "disabled"; -+ label = "swp1"; - }; - - mscc_felix_port2: port@2 { - reg = <2>; - status = "disabled"; -+ label = "swp2"; - }; - - mscc_felix_port3: port@3 { - reg = <3>; - status = "disabled"; -+ label = "swp3"; - }; - - /* internal to-cpu ports */ diff --git a/target/linux/layerscape/patches-5.4/302-dts-0115-LF-789-2-arm64-dts-add-overlay-support-for-ls1028a-q.patch b/target/linux/layerscape/patches-5.4/302-dts-0115-LF-789-2-arm64-dts-add-overlay-support-for-ls1028a-q.patch deleted file mode 100644 index 440e5839cd..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0115-LF-789-2-arm64-dts-add-overlay-support-for-ls1028a-q.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 911d3d1ea88ff6d56258d6173be7fc25290948a7 Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Fri, 10 Jan 2020 12:51:49 +0800 -Subject: [PATCH] LF-789-2 arm64: dts: add overlay support for ls1028a-qds - -Now seems only ls1028a-qds using overlay by adding fragment dtbs. -Add their support in Makefile. - -This is one of approach suggested by DT maintainer Rob here: -https://lore.kernel.org/patchwork/patch/821645/ - -Signed-off-by: Dong Aisheng -Signed-off-by: Jason Liu -Reviewed-by: Alex Marginean -Tested-by: Alex Marginean ---- - arch/arm64/boot/dts/freescale/Makefile | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/Makefile -+++ b/arch/arm64/boot/dts/freescale/Makefile -@@ -1,4 +1,14 @@ - # SPDX-License-Identifier: GPL-2.0 -+ -+# required for overlay support -+DTC_FLAGS_fsl-ls1028a-qds := -@ -+DTC_FLAGS_fsl-ls1028a-qds-13bb := -@ -+DTC_FLAGS_fsl-ls1028a-qds-65bb := -@ -+DTC_FLAGS_fsl-ls1028a-qds-7777 := -@ -+DTC_FLAGS_fsl-ls1028a-qds-85bb := -@ -+DTC_FLAGS_fsl-ls1028a-qds-899b := -@ -+DTC_FLAGS_fsl-ls1028a-qds-9999 := -@ -+ - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-2g5rdb.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frdm.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frwy.dtb diff --git a/target/linux/layerscape/patches-5.4/302-dts-0116-LF-881-arm64-dts-add-a-dts-file-for-dpdk.patch b/target/linux/layerscape/patches-5.4/302-dts-0116-LF-881-arm64-dts-add-a-dts-file-for-dpdk.patch deleted file mode 100644 index 311d73b475..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0116-LF-881-arm64-dts-add-a-dts-file-for-dpdk.patch +++ /dev/null @@ -1,119 +0,0 @@ -From f0f46229b2232595a1afde10f6f17e512c004042 Mon Sep 17 00:00:00 2001 -From: Gagandeep Singh -Date: Thu, 6 Feb 2020 13:01:10 +0000 -Subject: [PATCH] LF-881: arm64: dts: add a dts file for dpdk - -A new device tree file fsl-ls1028a-rdb-dpdk.dts is added -for user space networking. - -Signed-off-by: Gagandeep Singh -Reviewed-by: Alex Marginean -Reviewed-by: Li Yang ---- - arch/arm64/boot/dts/freescale/Makefile | 1 + - .../boot/dts/freescale/fsl-ls1028a-rdb-dpdk.dts | 89 ++++++++++++++++++++++ - 2 files changed, 90 insertions(+) - create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb-dpdk.dts - ---- a/arch/arm64/boot/dts/freescale/Makefile -+++ b/arch/arm64/boot/dts/freescale/Makefile -@@ -23,6 +23,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1 - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-899b.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-9999.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb-dpdk.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds-sdk.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb ---- /dev/null -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb-dpdk.dts -@@ -0,0 +1,89 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -+/* -+ * NXP LS1028A RDB Board device tree file for DPDK -+ * -+ * Copyright 2018-2020 NXP -+ */ -+ -+/dts-v1/; -+#include "fsl-ls1028a-rdb.dts" -+ -+&enetc_port0 { -+ status = "okay"; -+ /delete-property/ phy-handle; -+ /delete-property/ phy-connection-type; -+ /delete-node/ mdio; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+}; -+ -+/delete-node/ &enetc_mdio_pf3; -+ -+/* l2switch ports */ -+&mscc_felix_ports { -+ port@0 { -+ status = "okay"; -+ phy-mode = "qsgmii"; -+ /delete-property/ managed; -+ /delete-property/ phy-handle; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ -+ port@1 { -+ status = "okay"; -+ phy-mode = "qsgmii"; -+ /delete-property/ managed; -+ /delete-property/ phy-handle; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ -+ port@2 { -+ status = "okay"; -+ phy-mode = "qsgmii"; -+ /delete-property/ managed; -+ /delete-property/ phy-handle; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ -+ port@3 { -+ status = "okay"; -+ phy-mode = "qsgmii"; -+ /delete-property/ managed; -+ /delete-property/ phy-handle; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+ -+ port@5 { -+ status = "okay"; -+ /delete-property/ managed; -+ /delete-property/ phy-handle; -+ -+ fixed-link { -+ speed = <1000>; -+ full-duplex; -+ }; -+ }; -+}; -+ -+&enetc_port3 { -+ status = "okay"; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0117-arm-dts-ls1021a-Add-LS1021A-IOT-board-support.patch b/target/linux/layerscape/patches-5.4/302-dts-0117-arm-dts-ls1021a-Add-LS1021A-IOT-board-support.patch deleted file mode 100644 index 9963062195..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0117-arm-dts-ls1021a-Add-LS1021A-IOT-board-support.patch +++ /dev/null @@ -1,291 +0,0 @@ -From 55e00e402d6143aeb153761f8144d9fee5f1f009 Mon Sep 17 00:00:00 2001 -From: Biwen Li -Date: Fri, 26 Oct 2018 16:00:37 +0800 -Subject: [PATCH] arm: dts: ls1021a: Add LS1021A-IOT board support - -Signed-off-by: Biwen Li -[rebase] -Signed-off-by: Yangbo Lu ---- - arch/arm/boot/dts/Makefile | 3 +- - arch/arm/boot/dts/ls1021a-iot.dts | 262 ++++++++++++++++++++++++++++++++++++++ - 2 files changed, 264 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/ls1021a-iot.dts - ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -611,7 +611,8 @@ dtb-$(CONFIG_SOC_LS1021A) += \ - ls1021a-moxa-uc-8410a.dtb \ - ls1021a-qds.dtb \ - ls1021a-tsn.dtb \ -- ls1021a-twr.dtb -+ ls1021a-twr.dtb \ -+ ls1021a-iot.dtb - dtb-$(CONFIG_SOC_VF610) += \ - vf500-colibri-eval-v3.dtb \ - vf610-bk4.dtb \ ---- /dev/null -+++ b/arch/arm/boot/dts/ls1021a-iot.dts -@@ -0,0 +1,262 @@ -+/* -+ * Copyright 2013-2016 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+/dts-v1/; -+#include "ls1021a.dtsi" -+ -+/ { -+ model = "LS1021A IOT Board"; -+ -+ sys_mclk: clock-mclk { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <24576000>; -+ }; -+ -+ regulators { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ reg_3p3v: regulator@0 { -+ compatible = "regulator-fixed"; -+ reg = <0>; -+ regulator-name = "3P3V"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ regulator-always-on; -+ }; -+ -+ reg_2p5v: regulator@1 { -+ compatible = "regulator-fixed"; -+ reg = <1>; -+ regulator-name = "2P5V"; -+ regulator-min-microvolt = <2500000>; -+ regulator-max-microvolt = <2500000>; -+ regulator-always-on; -+ }; -+ }; -+ -+ sound { -+ compatible = "simple-audio-card"; -+ simple-audio-card,format = "i2s"; -+ simple-audio-card,widgets = -+ "Microphone", "Microphone Jack", -+ "Headphone", "Headphone Jack", -+ "Speaker", "Speaker Ext", -+ "Line", "Line In Jack"; -+ simple-audio-card,routing = -+ "MIC_IN", "Microphone Jack", -+ "Microphone Jack", "Mic Bias", -+ "LINE_IN", "Line In Jack", -+ "Headphone Jack", "HP_OUT", -+ "Speaker Ext", "LINE_OUT"; -+ -+ simple-audio-card,cpu { -+ sound-dai = <&sai2>; -+ frame-master; -+ bitclock-master; -+ }; -+ -+ simple-audio-card,codec { -+ sound-dai = <&codec>; -+ frame-master; -+ bitclock-master; -+ }; -+ }; -+ -+ firmware { -+ optee { -+ compatible = "linaro,optee-tz"; -+ method = "smc"; -+ }; -+ }; -+}; -+ -+&enet0 { -+ tbi-handle = <&tbi1>; -+ phy-handle = <&phy1>; -+ phy-connection-type = "sgmii"; -+ status = "okay"; -+}; -+ -+&enet1 { -+ tbi-handle = <&tbi1>; -+ phy-handle = <&phy3>; -+ phy-connection-type = "sgmii"; -+ status = "okay"; -+}; -+ -+&enet2 { -+ fixed-link = <0 1 1000 0 0>; -+ phy-connection-type = "rgmii-id"; -+ status = "okay"; -+}; -+ -+&can0{ -+ status = "disabled"; -+}; -+ -+&can1{ -+ status = "disabled"; -+}; -+ -+&can2{ -+ status = "disabled"; -+}; -+ -+&can3{ -+ status = "okay"; -+}; -+ -+&esdhc{ -+ status = "okay"; -+}; -+ -+&i2c0 { -+ status = "okay"; -+ -+ max1239@35 { -+ compatible = "maxim,max1239"; -+ reg = <0x35>; -+ #io-channel-cells = <1>; -+ }; -+ -+ codec: sgtl5000@2a { -+ #sound-dai-cells=<0x0>; -+ compatible = "fsl,sgtl5000"; -+ reg = <0x2a>; -+ VDDA-supply = <®_3p3v>; -+ VDDIO-supply = <®_2p5v>; -+ clocks = <&sys_mclk 1>; -+ }; -+ -+ pca9555: pca9555@23 { -+ compatible = "nxp,pca9555"; -+ /*pinctrl-names = "default";*/ -+ /*interrupt-parent = <&gpio2>; -+ interrupts = <19 0x2>;*/ -+ gpio-controller; -+ #gpio-cells = <2>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0x23>; -+ }; -+ -+ ina220@44 { -+ compatible = "ti,ina220"; -+ reg = <0x44>; -+ shunt-resistor = <1000>; -+ }; -+ -+ ina220@45 { -+ compatible = "ti,ina220"; -+ reg = <0x45>; -+ shunt-resistor = <1000>; -+ }; -+ -+ lm75b@48 { -+ compatible = "nxp,lm75a"; -+ reg = <0x48>; -+ }; -+ -+ adt7461a@4c { -+ compatible = "adt7461a"; -+ reg = <0x4c>; -+ }; -+ -+ hdmi: sii9022a@39 { -+ compatible = "fsl,sii902x"; -+ reg = <0x39>; -+ interrupts = ; -+ }; -+}; -+ -+&i2c1 { -+ status = "disabled"; -+}; -+ -+&ifc { -+ status = "disabled"; -+}; -+ -+&lpuart0 { -+ status = "okay"; -+}; -+ -+&mdio0 { -+ phy0: ethernet-phy@0 { -+ reg = <0x0>; -+ }; -+ phy1: ethernet-phy@1 { -+ reg = <0x1>; -+ }; -+ phy2: ethernet-phy@2 { -+ reg = <0x2>; -+ }; -+ phy3: ethernet-phy@3 { -+ reg = <0x3>; -+ }; -+ tbi1: tbi-phy@1f { -+ reg = <0x1f>; -+ device_type = "tbi-phy"; -+ }; -+}; -+ -+&qspi { -+ num-cs = <2>; -+ status = "okay"; -+ -+ qflash0: s25fl128s@0 { -+ compatible = "spansion,s25fl129p1"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ spi-max-frequency = <20000000>; -+ reg = <0>; -+ }; -+}; -+ -+&sai2 { -+ status = "okay"; -+}; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+&uart1 { -+ status = "okay"; -+}; -+ -+&dcu { -+ display = <&display>; -+ status = "okay"; -+ -+ display: display@0 { -+ bits-per-pixel = <24>; -+ -+ display-timings { -+ native-mode = <&timing0>; -+ -+ timing0: mode0 { -+ clock-frequency = <25000000>; -+ hactive = <640>; -+ vactive = <480>; -+ hback-porch = <80>; -+ hfront-porch = <80>; -+ vback-porch = <16>; -+ vfront-porch = <16>; -+ hsync-len = <12>; -+ vsync-len = <2>; -+ hsync-active = <1>; -+ vsync-active = <1>; -+ }; -+ }; -+ }; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0118-add-DTS-for-Traverse-LS1043-Boards.patch b/target/linux/layerscape/patches-5.4/302-dts-0118-add-DTS-for-Traverse-LS1043-Boards.patch deleted file mode 100644 index 904774d83d..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0118-add-DTS-for-Traverse-LS1043-Boards.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 5b35aae22b4ca2400e49561c9267aa01346f91d4 Mon Sep 17 00:00:00 2001 -From: Mathew McBride -Date: Tue, 17 Apr 2018 10:01:03 +1000 -Subject: [PATCH] add DTS for Traverse LS1043 Boards - -Signed-off-by: Mathew McBride -[rebase] -Signed-off-by: Yangbo Lu ---- - arch/arm64/boot/dts/freescale/Makefile | 3 +++ - arch/arm64/boot/dts/freescale/traverse-ls1043s.dts | 29 ++++++++++++++++++++++ - arch/arm64/boot/dts/freescale/traverse-ls1043v.dts | 29 ++++++++++++++++++++++ - 3 files changed, 61 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/Makefile -+++ b/arch/arm64/boot/dts/freescale/Makefile -@@ -48,6 +48,9 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2 - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb - dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb - -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += traverse-ls1043v.dtb -+dtb-$(CONFIG_ARCH_LAYERSCAPE) += traverse-ls1043s.dtb -+ - dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mn-ddr4-evk.dtb - dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb ---- a/arch/arm64/boot/dts/freescale/traverse-ls1043s.dts -+++ b/arch/arm64/boot/dts/freescale/traverse-ls1043s.dts -@@ -330,3 +330,32 @@ - &sata { - status = "disabled"; - }; -+ -+/* Additions for Layerscape SDK (4.4/4.9) Kernel only -+ * These kernels need additional setup for FMan/QMan DMA shared memory -+ */ -+ -+#include "qoriq-qman-portals-sdk.dtsi" -+#include "qoriq-bman-portals-sdk.dtsi" -+ -+&bman_fbpr { -+ compatible = "fsl,bman-fbpr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_fqd { -+ compatible = "fsl,qman-fqd"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_pfdr { -+ compatible = "fsl,qman-pfdr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+ -+&soc { -+#include "qoriq-dpaa-eth.dtsi" -+#include "qoriq-fman3-0-6oh.dtsi" -+}; -+ -+&fman0 { -+ compatible = "fsl,fman", "simple-bus"; -+}; ---- a/arch/arm64/boot/dts/freescale/traverse-ls1043v.dts -+++ b/arch/arm64/boot/dts/freescale/traverse-ls1043v.dts -@@ -251,3 +251,32 @@ - &sata { - status = "disabled"; - }; -+ -+/* Additions for Layerscape SDK (4.4/4.9) Kernel only -+ * These kernels need additional setup for FMan/QMan DMA shared memory -+ */ -+ -+#include "qoriq-qman-portals-sdk.dtsi" -+#include "qoriq-bman-portals-sdk.dtsi" -+ -+&bman_fbpr { -+ compatible = "fsl,bman-fbpr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_fqd { -+ compatible = "fsl,qman-fqd"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+&qman_pfdr { -+ compatible = "fsl,qman-pfdr"; -+ alloc-ranges = <0 0 0x10000 0>; -+}; -+ -+&soc { -+#include "qoriq-dpaa-eth.dtsi" -+#include "qoriq-fman3-0-6oh.dtsi" -+}; -+ -+&fman0 { -+ compatible = "fsl,fman", "simple-bus"; -+}; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0119-arm64-dts-lx2160a-add-more-thermal-zone-support.patch b/target/linux/layerscape/patches-5.4/302-dts-0119-arm64-dts-lx2160a-add-more-thermal-zone-support.patch deleted file mode 100644 index 5a29451564..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0119-arm64-dts-lx2160a-add-more-thermal-zone-support.patch +++ /dev/null @@ -1,184 +0,0 @@ -From eba73069e7f6ac3bcb3669d980994ec42ddd810a Mon Sep 17 00:00:00 2001 -From: Yuantian Tang -Date: Thu, 16 Apr 2020 17:40:06 +0800 -Subject: [PATCH] arm64: dts: lx2160a: add more thermal zone support - -There are 7 thermal zones in lx2160a soc. Add the -rest thermal zone node to enable them. -Also correct one of the values for tmu-calibration property. - -Signed-off-by: Yuantian Tang ---- - .../arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 130 +++++++++++++++++- - 1 file changed, 125 insertions(+), 5 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi -@@ -440,19 +440,19 @@ - }; - - thermal-zones { -- core_thermal1: core-thermal1 { -+ cluster6-7 { - polling-delay-passive = <1000>; - polling-delay = <5000>; - thermal-sensors = <&tmu 0>; - - trips { -- core_cluster_alert: core-cluster-alert { -+ cluster6_7_alert: cluster6-7-alert { - temperature = <85000>; - hysteresis = <2000>; - type = "passive"; - }; - -- core_cluster_crit: core-cluster-crit { -+ cluster6_7_crit: cluster6-7-crit { - temperature = <95000>; - hysteresis = <2000>; - type = "critical"; -@@ -461,7 +461,7 @@ - - cooling-maps { - map0 { -- trip = <&core_cluster_alert>; -+ trip = <&cluster6_7_alert>; - cooling-device = - <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, -@@ -482,6 +482,126 @@ - }; - }; - }; -+ -+ ddr-cluster5 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 1>; -+ -+ trips { -+ ddr-cluster5-alert { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ ddr-cluster5-crit { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ }; -+ -+ wriop { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 2>; -+ -+ trips { -+ wriop-alert { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ wriop-crit { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ }; -+ -+ dce-qbman-hsio2 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 3>; -+ -+ trips { -+ dce-qbman-alert { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ dce-qbman-crit { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ }; -+ -+ ccn-dpaa-tbu { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 4>; -+ -+ trips { -+ ccn-dpaa-alert { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ ccn-dpaa-crit { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ }; -+ -+ cluster4-hsio3 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 5>; -+ -+ trips { -+ clust4-hsio3-alert { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ clust4-hsio3-crit { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ }; -+ -+ cluster2-3 { -+ polling-delay-passive = <1000>; -+ polling-delay = <5000>; -+ thermal-sensors = <&tmu 6>; -+ -+ trips { -+ cluster2-3-alert { -+ temperature = <85000>; -+ hysteresis = <2000>; -+ type = "passive"; -+ }; -+ -+ cluster2-3-crit { -+ temperature = <95000>; -+ hysteresis = <2000>; -+ type = "critical"; -+ }; -+ }; -+ }; - }; - - soc { -@@ -760,7 +880,7 @@ - /* Calibration data group 1 */ - <0x00000000 0x00000035 - /* Calibration data group 2 */ -- 0x00010001 0x00000154>; -+ 0x00000001 0x00000154>; - little-endian; - #thermal-sensor-cells = <1>; - }; diff --git a/target/linux/layerscape/patches-5.4/302-dts-0120-arm64-dts-ls1046a-fix-ippdexpcr-offset-not-correct.patch b/target/linux/layerscape/patches-5.4/302-dts-0120-arm64-dts-ls1046a-fix-ippdexpcr-offset-not-correct.patch deleted file mode 100644 index 43700b8159..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0120-arm64-dts-ls1046a-fix-ippdexpcr-offset-not-correct.patch +++ /dev/null @@ -1,25 +0,0 @@ -From d589ed7b9aa91de94eb558ae83ccebd59b881d61 Mon Sep 17 00:00:00 2001 -From: Ran Wang -Date: Tue, 10 Mar 2020 21:06:29 +0800 -Subject: [PATCH] arm64: dts: ls1046a: fix ippdexpcr offset not correct - -The wrong offset of ippdexpcr in dtsi causes RCPM driver did not -program ippdexpcr properly, which lead to LPM20 cannot exit by wakeup -source. - -Signed-off-by: Ran Wang ---- - arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi -@@ -809,7 +809,7 @@ - - rcpm: rcpm@1ee208c { - compatible = "fsl,ls1046a-rcpm", "fsl,qoriq-rcpm-2.1+"; -- reg = <0x0 0x1ee208c 0x0 0x4>; -+ reg = <0x0 0x1ee2140 0x0 0x4>; - #fsl,rcpm-wakeup-cells = <1>; - }; - diff --git a/target/linux/layerscape/patches-5.4/302-dts-0121-arm64-dts-ls1043a-update-USB-nodes-status-to-match-b.patch b/target/linux/layerscape/patches-5.4/302-dts-0121-arm64-dts-ls1043a-update-USB-nodes-status-to-match-b.patch deleted file mode 100644 index c83fad33ab..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0121-arm64-dts-ls1043a-update-USB-nodes-status-to-match-b.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 2dfd145470894296d70873942ae056340e3fd78d Mon Sep 17 00:00:00 2001 -From: Ran Wang -Date: Tue, 7 Jul 2020 15:40:31 +0800 -Subject: [PATCH] arm64: dts: ls1043a: update USB nodes status to match board - config -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -ls1043a-rdb and ls1043a-qds board’s default HW config (such as -pin mux selection) would not enable some USB controllers’ -data path, which causing over-current detected on those -controllers. This will hit the case of ‘xhci driver prevent bus suspend -if a root hub port detected over-current condition’, causing system -failed to be suspended. So disable them in device tree to resolve this -issue. - -Signed-off-by: Ran Wang -Signed-off-by: Shawn Guo ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts | 4 ++++ - arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts | 8 ++++++++ - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 3 +++ - 3 files changed, 15 insertions(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts -@@ -167,6 +167,10 @@ - }; - }; - -+&usb0 { -+ status = "okay"; -+}; -+ - #include "fsl-ls1043-post.dtsi" - - &fman0 { ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts -@@ -212,3 +212,11 @@ - }; - }; - }; -+ -+&usb0 { -+ status = "okay"; -+}; -+ -+&usb1 { -+ status = "okay"; -+}; ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -707,6 +707,7 @@ - snps,host-vbus-glitches; - configure-gfladj; - dma-coherent; -+ status = "disabled"; - }; - - usb1: usb3@3000000 { -@@ -722,6 +723,7 @@ - snps,host-vbus-glitches; - configure-gfladj; - dma-coherent; -+ status = "disabled"; - }; - - usb2: usb3@3100000 { -@@ -737,6 +739,7 @@ - snps,host-vbus-glitches; - configure-gfladj; - dma-coherent; -+ status = "disabled"; - }; - - sata: sata@3200000 { diff --git a/target/linux/layerscape/patches-5.4/302-dts-0122-arm64-dts-ls1043a-remove-thermal-zone-5-from-dts.patch b/target/linux/layerscape/patches-5.4/302-dts-0122-arm64-dts-ls1043a-remove-thermal-zone-5-from-dts.patch deleted file mode 100644 index 887844fc0e..0000000000 --- a/target/linux/layerscape/patches-5.4/302-dts-0122-arm64-dts-ls1043a-remove-thermal-zone-5-from-dts.patch +++ /dev/null @@ -1,24 +0,0 @@ -From aa5e9dc53636e5ae40fc1460c7d3897c2d8588fe Mon Sep 17 00:00:00 2001 -From: Yuantian Tang -Date: Mon, 9 Mar 2020 10:44:54 +0800 -Subject: [PATCH] arm64: dts: ls1043a: remove thermal zone 5 from dts - -Thermal monitor zone 5 does not exist. So remove it -from dts. - -Signed-off-by: Yuantian ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi | 4 ---- - 1 file changed, 4 deletions(-) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi -@@ -919,8 +919,4 @@ - thermal-zone4 { - status = "okay"; - }; -- -- thermal-zone5 { -- status = "okay"; -- }; - }; diff --git a/target/linux/layerscape/patches-5.4/302-v5.7-dts-0119-arm64-dts-ls1043a-rdb-add-compatible-for-board.patch b/target/linux/layerscape/patches-5.4/302-v5.7-dts-0119-arm64-dts-ls1043a-rdb-add-compatible-for-board.patch deleted file mode 100644 index 0c6b8e2863..0000000000 --- a/target/linux/layerscape/patches-5.4/302-v5.7-dts-0119-arm64-dts-ls1043a-rdb-add-compatible-for-board.patch +++ /dev/null @@ -1,23 +0,0 @@ -From fa578d4e9fbef8928a45edd904dafb1e3334417e Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Thu, 30 Apr 2020 10:56:46 +0800 -Subject: [PATCH] arm64: dts: ls1043a-rdb: add compatible for board - -Add compatible for board to identify. - -Signed-off-by: Yangbo Lu -Signed-off-by: Shawn Guo ---- - arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts | 1 + - 1 file changed, 1 insertion(+) - ---- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts -+++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts -@@ -13,6 +13,7 @@ - - / { - model = "LS1043A RDB Board"; -+ compatible = "fsl,ls1043a-rdb", "fsl,ls1043a"; - - aliases { - serial0 = &duart0; diff --git a/target/linux/layerscape/patches-5.4/303-core-0001-net-readd-skb_recycle.patch b/target/linux/layerscape/patches-5.4/303-core-0001-net-readd-skb_recycle.patch deleted file mode 100644 index e296df502e..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0001-net-readd-skb_recycle.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 446a17652a69f749dd7a50b28e984c4904dc3aaf Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Tue, 5 Jan 2016 12:12:07 +0200 -Subject: [PATCH] net: readd skb_recycle() - -Adding back skb_recycle() as it's used by the DPAA Ethernet driver. -This was removed from the upstream kernel because it was lacking users. - -Signed-off-by: Madalin Bucur ---- - include/linux/skbuff.h | 1 + - net/core/skbuff.c | 26 ++++++++++++++++++++++++++ - 2 files changed, 27 insertions(+) - ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -1025,6 +1025,7 @@ void skb_dump(const char *level, const s - void skb_tx_error(struct sk_buff *skb); - void consume_skb(struct sk_buff *skb); - void __consume_stateless_skb(struct sk_buff *skb); -+void skb_recycle(struct sk_buff *skb); - void __kfree_skb(struct sk_buff *skb); - extern struct kmem_cache *skbuff_head_cache; - ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -945,6 +945,32 @@ void napi_consume_skb(struct sk_buff *sk - } - EXPORT_SYMBOL(napi_consume_skb); - -+/** -+ * skb_recycle - clean up an skb for reuse -+ * @skb: buffer -+ * -+ * Recycles the skb to be reused as a receive buffer. This -+ * function does any necessary reference count dropping, and -+ * cleans up the skbuff as if it just came from __alloc_skb(). -+ */ -+void skb_recycle(struct sk_buff *skb) -+{ -+ struct skb_shared_info *shinfo; -+ u8 head_frag = skb->head_frag; -+ -+ skb_release_head_state(skb); -+ -+ shinfo = skb_shinfo(skb); -+ memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); -+ atomic_set(&shinfo->dataref, 1); -+ -+ memset(skb, 0, offsetof(struct sk_buff, tail)); -+ skb->data = skb->head + NET_SKB_PAD; -+ skb->head_frag = head_frag; -+ skb_reset_tail_pointer(skb); -+} -+EXPORT_SYMBOL(skb_recycle); -+ - /* Make sure a field is enclosed inside headers_start/headers_end section */ - #define CHECK_SKB_FIELD(field) \ - BUILD_BUG_ON(offsetof(struct sk_buff, field) < \ diff --git a/target/linux/layerscape/patches-5.4/303-core-0002-drivers-base-add-sysfs-entries-for-suppliers-and-con.patch b/target/linux/layerscape/patches-5.4/303-core-0002-drivers-base-add-sysfs-entries-for-suppliers-and-con.patch deleted file mode 100644 index 4cad5e2d13..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0002-drivers-base-add-sysfs-entries-for-suppliers-and-con.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 4a84eacedc55e78c8f64a5a4f9ade6e285844b85 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Mon, 25 Jun 2018 13:19:53 +0300 -Subject: [PATCH] drivers/base: add sysfs entries for suppliers and consumers - -Instead of scraping dmesg for messages such as 'Linked as a consumer to' -or 'Dropping the link to' export two new sysfs entries in the device -folder that list the consumer and supplier devices. - -Signed-off-by: Ioana Ciornei ---- - Documentation/ABI/testing/sysfs-devices-links | 13 +++++++++ - drivers/base/core.c | 42 +++++++++++++++++++++++++++ - 2 files changed, 55 insertions(+) - create mode 100644 Documentation/ABI/testing/sysfs-devices-links - ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-devices-links -@@ -0,0 +1,13 @@ -+What: /sys/devices/.../consumers -+Date: October 2018 -+Contact: Ioana Ciornei -+Description: -+ Read-only attribute that lists the current "consumers" of -+ a specific device. -+ -+What: /sys/devices/.../suppliers -+Date: October 2018 -+Contact: Ioana Ciornei -+Description: -+ Read-only attribute that lists the current "suppliers" of -+ a specific device. ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -1333,6 +1333,34 @@ static ssize_t online_store(struct devic - } - static DEVICE_ATTR_RW(online); - -+static ssize_t suppliers_show(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct device_link *link; -+ size_t count = 0; -+ -+ list_for_each_entry(link, &dev->links.suppliers, c_node) -+ count += scnprintf(buf + count, PAGE_SIZE - count, "%s\n", -+ dev_name(link->supplier)); -+ -+ return count; -+} -+static DEVICE_ATTR_RO(suppliers); -+ -+static ssize_t consumers_show(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct device_link *link; -+ size_t count = 0; -+ -+ list_for_each_entry(link, &dev->links.consumers, s_node) -+ count += scnprintf(buf + count, PAGE_SIZE - count, "%s\n", -+ dev_name(link->consumer)); -+ -+ return count; -+} -+static DEVICE_ATTR_RO(consumers); -+ - int device_add_groups(struct device *dev, const struct attribute_group **groups) - { - return sysfs_create_groups(&dev->kobj, groups); -@@ -1504,8 +1532,20 @@ static int device_add_attrs(struct devic - goto err_remove_dev_groups; - } - -+ error = device_create_file(dev, &dev_attr_suppliers); -+ if (error) -+ goto err_remove_online; -+ -+ error = device_create_file(dev, &dev_attr_consumers); -+ if (error) -+ goto err_remove_suppliers; -+ - return 0; - -+ err_remove_suppliers: -+ device_remove_file(dev, &dev_attr_suppliers); -+ err_remove_online: -+ device_remove_file(dev, &dev_attr_online); - err_remove_dev_groups: - device_remove_groups(dev, dev->groups); - err_remove_type_groups: -@@ -1523,6 +1563,8 @@ static void device_remove_attrs(struct d - struct class *class = dev->class; - const struct device_type *type = dev->type; - -+ device_remove_file(dev, &dev_attr_consumers); -+ device_remove_file(dev, &dev_attr_suppliers); - device_remove_file(dev, &dev_attr_online); - device_remove_groups(dev, dev->groups); - diff --git a/target/linux/layerscape/patches-5.4/303-core-0003-cgroup-let-a-symlink-too-be-created-with-a-cftype-fi.patch b/target/linux/layerscape/patches-5.4/303-core-0003-cgroup-let-a-symlink-too-be-created-with-a-cftype-fi.patch deleted file mode 100644 index f7edb7411d..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0003-cgroup-let-a-symlink-too-be-created-with-a-cftype-fi.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 3b4d888114a5f6c1e848f892a2236db4ccf8345f Mon Sep 17 00:00:00 2001 -From: Angelo Ruocco -Date: Tue, 21 May 2019 10:01:54 +0200 -Subject: [PATCH] cgroup: let a symlink too be created with a cftype file - -This commit enables a cftype to have a symlink (of any name) that -points to the file associated with the cftype. - -Signed-off-by: Angelo Ruocco -Signed-off-by: Paolo Valente -Signed-off-by: Jens Axboe -(cherry picked from commit 54b7b868e826b294687c439b68ec55fe20cafe5b) -Signed-off-by: Li Yang ---- - include/linux/cgroup-defs.h | 3 +++ - kernel/cgroup/cgroup.c | 33 +++++++++++++++++++++++++++++---- - 2 files changed, 32 insertions(+), 4 deletions(-) - ---- a/include/linux/cgroup-defs.h -+++ b/include/linux/cgroup-defs.h -@@ -106,6 +106,8 @@ enum { - CFTYPE_WORLD_WRITABLE = (1 << 4), /* (DON'T USE FOR NEW FILES) S_IWUGO */ - CFTYPE_DEBUG = (1 << 5), /* create when cgroup_debug */ - -+ CFTYPE_SYMLINKED = (1 << 6), /* pointed to by symlink too */ -+ - /* internal flags, do not use outside cgroup core proper */ - __CFTYPE_ONLY_ON_DFL = (1 << 16), /* only on default hierarchy */ - __CFTYPE_NOT_ON_DFL = (1 << 17), /* not on default hierarchy */ -@@ -544,6 +546,7 @@ struct cftype { - * end of cftype array. - */ - char name[MAX_CFTYPE_NAME]; -+ char link_name[MAX_CFTYPE_NAME]; - unsigned long private; - - /* ---- a/kernel/cgroup/cgroup.c -+++ b/kernel/cgroup/cgroup.c -@@ -1465,8 +1465,8 @@ struct cgroup *task_cgroup_from_root(str - - static struct kernfs_syscall_ops cgroup_kf_syscall_ops; - --static char *cgroup_file_name(struct cgroup *cgrp, const struct cftype *cft, -- char *buf) -+static char *cgroup_fill_name(struct cgroup *cgrp, const struct cftype *cft, -+ char *buf, bool write_link_name) - { - struct cgroup_subsys *ss = cft->ss; - -@@ -1476,13 +1476,26 @@ static char *cgroup_file_name(struct cgr - - snprintf(buf, CGROUP_FILE_NAME_MAX, "%s%s.%s", - dbg, cgroup_on_dfl(cgrp) ? ss->name : ss->legacy_name, -- cft->name); -+ write_link_name ? cft->link_name : cft->name); - } else { -- strscpy(buf, cft->name, CGROUP_FILE_NAME_MAX); -+ strscpy(buf, write_link_name ? cft->link_name : cft->name, -+ CGROUP_FILE_NAME_MAX); - } - return buf; - } - -+static char *cgroup_file_name(struct cgroup *cgrp, const struct cftype *cft, -+ char *buf) -+{ -+ return cgroup_fill_name(cgrp, cft, buf, false); -+} -+ -+static char *cgroup_link_name(struct cgroup *cgrp, const struct cftype *cft, -+ char *buf) -+{ -+ return cgroup_fill_name(cgrp, cft, buf, true); -+} -+ - /** - * cgroup_file_mode - deduce file mode of a control file - * @cft: the control file in question -@@ -1641,6 +1654,9 @@ static void cgroup_rm_file(struct cgroup - } - - kernfs_remove_by_name(cgrp->kn, cgroup_file_name(cgrp, cft, name)); -+ if (cft->flags & CFTYPE_SYMLINKED) -+ kernfs_remove_by_name(cgrp->kn, -+ cgroup_link_name(cgrp, cft, name)); - } - - /** -@@ -3896,6 +3912,7 @@ static int cgroup_add_file(struct cgroup - { - char name[CGROUP_FILE_NAME_MAX]; - struct kernfs_node *kn; -+ struct kernfs_node *kn_link; - struct lock_class_key *key = NULL; - int ret; - -@@ -3926,6 +3943,14 @@ static int cgroup_add_file(struct cgroup - spin_unlock_irq(&cgroup_file_kn_lock); - } - -+ if (cft->flags & CFTYPE_SYMLINKED) { -+ kn_link = kernfs_create_link(cgrp->kn, -+ cgroup_link_name(cgrp, cft, name), -+ kn); -+ if (IS_ERR(kn_link)) -+ return PTR_ERR(kn_link); -+ } -+ - return 0; - } - diff --git a/target/linux/layerscape/patches-5.4/303-core-0004-cgroup-bfq-revert-bfq.weight-symlink-change.patch b/target/linux/layerscape/patches-5.4/303-core-0004-cgroup-bfq-revert-bfq.weight-symlink-change.patch deleted file mode 100644 index 469bbfdffa..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0004-cgroup-bfq-revert-bfq.weight-symlink-change.patch +++ /dev/null @@ -1,114 +0,0 @@ -From b7f71899fbdba1cac6773a62ed4ea841b7eda6b0 Mon Sep 17 00:00:00 2001 -From: Jens Axboe -Date: Mon, 10 Jun 2019 03:35:41 -0600 -Subject: [PATCH] cgroup/bfq: revert bfq.weight symlink change - -There's some discussion on how to do this the best, and Tejun prefers -that BFQ just create the file itself instead of having cgroups support -a symlink feature. - -Hence revert commit 54b7b868e826 and 19e9da9e86c4 for 5.2, and this -can be done properly for 5.3. - -Signed-off-by: Jens Axboe -(cherry picked from commit cf8929885de318c0bf73438c9e5dde59d6536f7c) -Signed-off-by: Li Yang ---- - include/linux/cgroup-defs.h | 3 --- - kernel/cgroup/cgroup.c | 33 ++++----------------------------- - 2 files changed, 4 insertions(+), 32 deletions(-) - ---- a/include/linux/cgroup-defs.h -+++ b/include/linux/cgroup-defs.h -@@ -106,8 +106,6 @@ enum { - CFTYPE_WORLD_WRITABLE = (1 << 4), /* (DON'T USE FOR NEW FILES) S_IWUGO */ - CFTYPE_DEBUG = (1 << 5), /* create when cgroup_debug */ - -- CFTYPE_SYMLINKED = (1 << 6), /* pointed to by symlink too */ -- - /* internal flags, do not use outside cgroup core proper */ - __CFTYPE_ONLY_ON_DFL = (1 << 16), /* only on default hierarchy */ - __CFTYPE_NOT_ON_DFL = (1 << 17), /* not on default hierarchy */ -@@ -546,7 +544,6 @@ struct cftype { - * end of cftype array. - */ - char name[MAX_CFTYPE_NAME]; -- char link_name[MAX_CFTYPE_NAME]; - unsigned long private; - - /* ---- a/kernel/cgroup/cgroup.c -+++ b/kernel/cgroup/cgroup.c -@@ -1465,8 +1465,8 @@ struct cgroup *task_cgroup_from_root(str - - static struct kernfs_syscall_ops cgroup_kf_syscall_ops; - --static char *cgroup_fill_name(struct cgroup *cgrp, const struct cftype *cft, -- char *buf, bool write_link_name) -+static char *cgroup_file_name(struct cgroup *cgrp, const struct cftype *cft, -+ char *buf) - { - struct cgroup_subsys *ss = cft->ss; - -@@ -1476,26 +1476,13 @@ static char *cgroup_fill_name(struct cgr - - snprintf(buf, CGROUP_FILE_NAME_MAX, "%s%s.%s", - dbg, cgroup_on_dfl(cgrp) ? ss->name : ss->legacy_name, -- write_link_name ? cft->link_name : cft->name); -+ cft->name); - } else { -- strscpy(buf, write_link_name ? cft->link_name : cft->name, -- CGROUP_FILE_NAME_MAX); -+ strscpy(buf, cft->name, CGROUP_FILE_NAME_MAX); - } - return buf; - } - --static char *cgroup_file_name(struct cgroup *cgrp, const struct cftype *cft, -- char *buf) --{ -- return cgroup_fill_name(cgrp, cft, buf, false); --} -- --static char *cgroup_link_name(struct cgroup *cgrp, const struct cftype *cft, -- char *buf) --{ -- return cgroup_fill_name(cgrp, cft, buf, true); --} -- - /** - * cgroup_file_mode - deduce file mode of a control file - * @cft: the control file in question -@@ -1654,9 +1641,6 @@ static void cgroup_rm_file(struct cgroup - } - - kernfs_remove_by_name(cgrp->kn, cgroup_file_name(cgrp, cft, name)); -- if (cft->flags & CFTYPE_SYMLINKED) -- kernfs_remove_by_name(cgrp->kn, -- cgroup_link_name(cgrp, cft, name)); - } - - /** -@@ -3912,7 +3896,6 @@ static int cgroup_add_file(struct cgroup - { - char name[CGROUP_FILE_NAME_MAX]; - struct kernfs_node *kn; -- struct kernfs_node *kn_link; - struct lock_class_key *key = NULL; - int ret; - -@@ -3943,14 +3926,6 @@ static int cgroup_add_file(struct cgroup - spin_unlock_irq(&cgroup_file_kn_lock); - } - -- if (cft->flags & CFTYPE_SYMLINKED) { -- kn_link = kernfs_create_link(cgrp->kn, -- cgroup_link_name(cgrp, cft, name), -- kn); -- if (IS_ERR(kn_link)) -- return PTR_ERR(kn_link); -- } -- - return 0; - } - diff --git a/target/linux/layerscape/patches-5.4/303-core-0005-nand-raw-workaround-for-EDO-high-speed-mode.patch b/target/linux/layerscape/patches-5.4/303-core-0005-nand-raw-workaround-for-EDO-high-speed-mode.patch deleted file mode 100644 index b2a845683e..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0005-nand-raw-workaround-for-EDO-high-speed-mode.patch +++ /dev/null @@ -1,25 +0,0 @@ -From e2c1ef18cddb426b9eea79599aec892717bead48 Mon Sep 17 00:00:00 2001 -From: Han Xu -Date: Thu, 15 Aug 2019 21:45:50 -0500 -Subject: [PATCH] nand: raw: workaround for EDO high speed mode - -Found issue for EDO high speed mode, set to low speed mode as a -workaround. - -Signed-off-by: Han Xu ---- - drivers/mtd/nand/raw/nand_base.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/mtd/nand/raw/nand_base.c -+++ b/drivers/mtd/nand/raw/nand_base.c -@@ -940,7 +940,8 @@ static int nand_init_data_interface(stru - modes = GENMASK(chip->onfi_timing_mode_default, 0); - } - -- for (mode = fls(modes) - 1; mode >= 0; mode--) { -+ /* for (mode = fls(modes) - 1; mode >= 0; mode--) { */ -+ for (mode = 1; mode >= 0; mode--) { - ret = onfi_fill_data_interface(chip, NAND_SDR_IFACE, mode); - if (ret) - continue; diff --git a/target/linux/layerscape/patches-5.4/303-core-0006-mm-Re-export-ioremap_page_range.patch b/target/linux/layerscape/patches-5.4/303-core-0006-mm-Re-export-ioremap_page_range.patch deleted file mode 100644 index 82e75a4c4b..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0006-mm-Re-export-ioremap_page_range.patch +++ /dev/null @@ -1,21 +0,0 @@ -From ca952acd72964dca53a9f50cf728dd1d31d48117 Mon Sep 17 00:00:00 2001 -From: Jan Kiszka -Date: Tue, 7 Feb 2017 17:52:00 +0100 -Subject: [PATCH] mm: Re-export ioremap_page_range - -We need this in Jailhouse to map at specific virtual addresses, at -least for the moment. - -Signed-off-by: Jan Kiszka -(cherry picked from commit 94bb285491a9a9e15c82c0761505b1073d6b7a47) ---- - lib/ioremap.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/lib/ioremap.c -+++ b/lib/ioremap.c -@@ -231,3 +231,4 @@ int ioremap_page_range(unsigned long add - - return err; - } -+EXPORT_SYMBOL_GPL(ioremap_page_range); diff --git a/target/linux/layerscape/patches-5.4/303-core-0007-of-of_reserved_mem-Ensure-cma-reserved-region-not-cr.patch b/target/linux/layerscape/patches-5.4/303-core-0007-of-of_reserved_mem-Ensure-cma-reserved-region-not-cr.patch deleted file mode 100644 index d95d1f0d53..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0007-of-of_reserved_mem-Ensure-cma-reserved-region-not-cr.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 6973ab95b9e0b0ce7b878c70c301bc5b3d11eca4 Mon Sep 17 00:00:00 2001 -From: Jason Liu -Date: Mon, 11 Nov 2019 17:51:13 +0800 -Subject: [PATCH] of: of_reserved_mem: Ensure cma reserved region not cross the - low/high memory - -Need ensure the cma reserved region not cross the low/high memory boundary -when using the dynamic allocation methond through device-tree, otherwise, -kernel will fail to boot up when cma reserved region cross how/high mem. - -Signed-off-by: Jason Liu -Cc: Laura Abbott -Cc: Frank Rowand -Cc: Rob Herring -Cc: stable@vger.kernel.org -Signed-off-by: Arulpandiyan Vadivel ---- - drivers/of/of_reserved_mem.c | 33 ++++++++++++++++++++++++++------- - 1 file changed, 26 insertions(+), 7 deletions(-) - ---- a/drivers/of/of_reserved_mem.c -+++ b/drivers/of/of_reserved_mem.c -@@ -26,11 +26,12 @@ - static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS]; - static int reserved_mem_count; - --static int __init early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, -- phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap, -- phys_addr_t *res_base) -+static int __init early_init_dt_alloc_reserved_memory_arch(unsigned long node, -+ phys_addr_t size, phys_addr_t align, phys_addr_t start, -+ phys_addr_t end, bool nomap, phys_addr_t *res_base) - { - phys_addr_t base; -+ phys_addr_t highmem_start = __pa(high_memory - 1) + 1; - - end = !end ? MEMBLOCK_ALLOC_ANYWHERE : end; - align = !align ? SMP_CACHE_BYTES : align; -@@ -38,6 +39,24 @@ static int __init early_init_dt_alloc_re - if (!base) - return -ENOMEM; - -+ -+ /* -+ * Sanity check for the cma reserved region:If the reserved region -+ * crosses the low/high memory boundary, try to fix it up and then -+ * fall back to allocate the cma region from the low mememory space. -+ */ -+ -+ if (IS_ENABLED(CONFIG_CMA) -+ && of_flat_dt_is_compatible(node, "shared-dma-pool") -+ && of_get_flat_dt_prop(node, "reusable", NULL) && !nomap) { -+ if (base < highmem_start && (base + size) > highmem_start) { -+ base = memblock_find_in_range(start, highmem_start, -+ size, align); -+ if (!base) -+ return -ENOMEM; -+ } -+ } -+ - *res_base = base; - if (nomap) - return memblock_remove(base, size); -@@ -131,8 +150,8 @@ static int __init __reserved_mem_alloc_s - end = start + dt_mem_next_cell(dt_root_size_cells, - &prop); - -- ret = early_init_dt_alloc_reserved_memory_arch(size, -- align, start, end, nomap, &base); -+ ret = early_init_dt_alloc_reserved_memory_arch(node, -+ size, align, start, end, nomap, &base); - if (ret == 0) { - pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", - uname, &base, -@@ -143,8 +162,8 @@ static int __init __reserved_mem_alloc_s - } - - } else { -- ret = early_init_dt_alloc_reserved_memory_arch(size, align, -- 0, 0, nomap, &base); -+ ret = early_init_dt_alloc_reserved_memory_arch(node, -+ size, align, 0, 0, nomap, &base); - if (ret == 0) - pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", - uname, &base, (unsigned long)(size / SZ_1M)); diff --git a/target/linux/layerscape/patches-5.4/303-core-0008-ENGR00279980-ubi-attach-do-not-return-EINVAL-if-the-.patch b/target/linux/layerscape/patches-5.4/303-core-0008-ENGR00279980-ubi-attach-do-not-return-EINVAL-if-the-.patch deleted file mode 100644 index c67cdb0f82..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0008-ENGR00279980-ubi-attach-do-not-return-EINVAL-if-the-.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 17e6b7bb84649ffcbec11b3e3e933294d8856462 Mon Sep 17 00:00:00 2001 -From: Huang Shijie -Date: Wed, 18 Sep 2013 10:17:39 +0800 -Subject: [PATCH] ENGR00279980 ubi: attach: do not return -EINVAL if the - mtd->numeraseregions is 1 - -If the master mtd does not have any slave mtd partitions, -and its numeraseregions is one(only has one erease block), and -we attach the master mtd with : ubiattach -m 0 -d 0 - -We will meet the error: -------------------------------------------------------- -root@freescale ~$ ubiattach /dev/ubi_ctrl -m 0 -d 0 -UBI: attaching mtd0 to ubi0 -UBI error: io_init: multiple regions, not implemented -ubiattach: error!: cannot attach mtd0 - error 22 (Invalid argument) -------------------------------------------------------- - -In fact, if there is only one "erase block", we should not -prevent the attach. - -This patch fixes it. - -Signed-off-by: Huang Shijie -(cherry picked from commit 361cdc47fc4c4db31c5485560cdabd94f409bd81) -(cherry picked from commit ebee7d74914fad3cf7223af84496811c9d2488a1) - -Signed-off-by: Vipul Kumar - -Signed-off-by: Han Xu ---- - drivers/mtd/ubi/build.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/mtd/ubi/build.c -+++ b/drivers/mtd/ubi/build.c -@@ -576,7 +576,7 @@ static int io_init(struct ubi_device *ub - dbg_gen("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb)); - dbg_gen("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry)); - -- if (ubi->mtd->numeraseregions != 0) { -+ if (ubi->mtd->numeraseregions > 1) { - /* - * Some flashes have several erase regions. Different regions - * may have different eraseblock size and other diff --git a/target/linux/layerscape/patches-5.4/303-core-0009-arm64-move-elfcorehdr-reservation-early-for-crash-du.patch b/target/linux/layerscape/patches-5.4/303-core-0009-arm64-move-elfcorehdr-reservation-early-for-crash-du.patch deleted file mode 100644 index d7149712ad..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0009-arm64-move-elfcorehdr-reservation-early-for-crash-du.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 67349176ca23f7525dee79665a880cde5aeeaf26 Mon Sep 17 00:00:00 2001 -From: Nikhil Gupta -Date: Mon, 30 Dec 2019 15:11:23 +0530 -Subject: [PATCH] arm64:move elfcorehdr reservation early for crash dump kernel - -on some SOCs, elfcorehdr address may overlap with the address of reserved -memory allocated using early_init_fdt_scan_reserved_mem - -Signed-off-by: Nikhil Gupta -Signed-off-by: Poonam Aggrwal ---- - arch/arm64/mm/init.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/arch/arm64/mm/init.c -+++ b/arch/arm64/mm/init.c -@@ -418,6 +418,8 @@ void __init arm64_memblock_init(void) - initrd_end = initrd_start + phys_initrd_size; - } - -+ reserve_elfcorehdr(); -+ - early_init_fdt_scan_reserved_mem(); - - /* 4GB maximum for 32-bit only capable devices */ -@@ -428,8 +430,6 @@ void __init arm64_memblock_init(void) - - reserve_crashkernel(); - -- reserve_elfcorehdr(); -- - high_memory = __va(memblock_end_of_DRAM() - 1) + 1; - - dma_contiguous_reserve(arm64_dma_phys_limit); diff --git a/target/linux/layerscape/patches-5.4/303-core-0010-scripts-Makefile-Enable-creation-of-_symbols_-DT-nod.patch b/target/linux/layerscape/patches-5.4/303-core-0010-scripts-Makefile-Enable-creation-of-_symbols_-DT-nod.patch deleted file mode 100644 index 801bde12fc..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0010-scripts-Makefile-Enable-creation-of-_symbols_-DT-nod.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 71650b18b78f52e96512a7695a0d39762c1ee408 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Mon, 6 Jan 2020 16:35:08 +0200 -Subject: [PATCH] scripts: Makefile: Enable creation of _symbols_ DT node for - overlays - -DT compiler supports -@ flag which indicates that _symbols_ node should be -automatically created during compilation. This node is required for -using DT overlays. The generated DTB is backward compatible, the _symbols_ -node can be safely ignored if overlays are not used. - -Signed-off-by: Alex Marginean ---- - scripts/Makefile.lib | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -255,6 +255,9 @@ endif - - DTC_FLAGS += $(DTC_FLAGS_$(basetarget)) - -+# Enable creation of _symbols_ node for DT overlays -+DTC_FLAGS += -@ -+ - # Generate an assembly file to wrap the output of the device tree compiler - quiet_cmd_dt_S_dtb= DTB $@ - cmd_dt_S_dtb= \ diff --git a/target/linux/layerscape/patches-5.4/303-core-0011-LF-419-arm64-crash_core-Export-TCR_EL1.T1SZ-in-vmcor.patch b/target/linux/layerscape/patches-5.4/303-core-0011-LF-419-arm64-crash_core-Export-TCR_EL1.T1SZ-in-vmcor.patch deleted file mode 100644 index 7bd8df661c..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0011-LF-419-arm64-crash_core-Export-TCR_EL1.T1SZ-in-vmcor.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 2e4c0c429526d88b96319d7bb08c51bfa70f6e27 Mon Sep 17 00:00:00 2001 -From: Bhupesh Sharma -Date: Fri, 29 Nov 2019 01:55:13 +0530 -Subject: [PATCH] LF-419 arm64/crash_core: Export TCR_EL1.T1SZ in vmcoreinfo - -vabits_actual variable on arm64 indicates the actual VA space size, -and allows a single binary to support both 48-bit and 52-bit VA -spaces. - -If the ARMv8.2-LVA optional feature is present, and we are running -with a 64KB page size; then it is possible to use 52-bits of address -space for both userspace and kernel addresses. However, any kernel -binary that supports 52-bit must also be able to fall back to 48-bit -at early boot time if the hardware feature is not present. - -Since TCR_EL1.T1SZ indicates the size offset of the memory region -addressed by TTBR1_EL1 (and hence can be used for determining the -vabits_actual value) it makes more sense to export the same in -vmcoreinfo rather than vabits_actual variable, as the name of the -variable can change in future kernel versions, but the architectural -constructs like TCR_EL1.T1SZ can be used better to indicate intended -specific fields to user-space. - -User-space utilities like makedumpfile and crash-utility, need to -read/write this value from/to vmcoreinfo for determining if a virtual -address lies in the linear map range. - -The user-space computation for determining whether an address lies in -the linear map range is the same as we have in kernel-space: - - #define __is_lm_address(addr) (!(((u64)addr) & BIT(vabits_actual - 1))) - -I have sent out user-space patches for makedumpfile and crash-utility -to add features for obtaining vabits_actual value from TCR_EL1.T1SZ (see -[0] and [1]). - -Akashi reported that he was able to use this patchset and the user-space -changes to get user-space working fine with the 52-bit kernel VA -changes (see [2]). - -[0]. http://lists.infradead.org/pipermail/kexec/2019-November/023966.html -[1]. http://lists.infradead.org/pipermail/kexec/2019-November/024006.html -[2]. http://lists.infradead.org/pipermail/kexec/2019-November/023992.html - -Cc: James Morse -Cc: Mark Rutland -Cc: Will Deacon -Cc: Steve Capper -Cc: Catalin Marinas -Cc: Ard Biesheuvel -Cc: Dave Anderson -Cc: Kazuhito Hagio -Cc: linux-arm-kernel@lists.infradead.org -Cc: linux-kernel@vger.kernel.org -Cc: kexec@lists.infradead.org -Signed-off-by: Bhupesh Sharma -Tested-by: Poonam Aggrwal -Acked-by: Li Yang ---- - arch/arm64/include/asm/pgtable-hwdef.h | 1 + - arch/arm64/kernel/crash_core.c | 9 +++++++++ - 2 files changed, 10 insertions(+) - ---- a/arch/arm64/include/asm/pgtable-hwdef.h -+++ b/arch/arm64/include/asm/pgtable-hwdef.h -@@ -215,6 +215,7 @@ - #define TCR_TxSZ(x) (TCR_T0SZ(x) | TCR_T1SZ(x)) - #define TCR_TxSZ_WIDTH 6 - #define TCR_T0SZ_MASK (((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T0SZ_OFFSET) -+#define TCR_T1SZ_MASK (((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T1SZ_OFFSET) - - #define TCR_EPD0_SHIFT 7 - #define TCR_EPD0_MASK (UL(1) << TCR_EPD0_SHIFT) ---- a/arch/arm64/kernel/crash_core.c -+++ b/arch/arm64/kernel/crash_core.c -@@ -7,6 +7,13 @@ - #include - #include - -+static inline u64 get_tcr_el1_t1sz(void); -+ -+static inline u64 get_tcr_el1_t1sz(void) -+{ -+ return (read_sysreg(tcr_el1) & TCR_T1SZ_MASK) >> TCR_T1SZ_OFFSET; -+} -+ - void arch_crash_save_vmcoreinfo(void) - { - VMCOREINFO_NUMBER(VA_BITS); -@@ -15,5 +22,7 @@ void arch_crash_save_vmcoreinfo(void) - kimage_voffset); - vmcoreinfo_append_str("NUMBER(PHYS_OFFSET)=0x%llx\n", - PHYS_OFFSET); -+ vmcoreinfo_append_str("NUMBER(tcr_el1_t1sz)=0x%llx\n", -+ get_tcr_el1_t1sz()); - vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset()); - } diff --git a/target/linux/layerscape/patches-5.4/303-core-0012-LF-789-1-Revert-scripts-Makefile-Enable-creation-of-.patch b/target/linux/layerscape/patches-5.4/303-core-0012-LF-789-1-Revert-scripts-Makefile-Enable-creation-of-.patch deleted file mode 100644 index 744930c726..0000000000 --- a/target/linux/layerscape/patches-5.4/303-core-0012-LF-789-1-Revert-scripts-Makefile-Enable-creation-of-.patch +++ /dev/null @@ -1,58 +0,0 @@ -From b13487a97b51a619b4e681a6091a1da9d6733058 Mon Sep 17 00:00:00 2001 -From: Jason Liu -Date: Fri, 10 Jan 2020 11:38:05 +0800 -Subject: [PATCH] LF-789-1 Revert "scripts: Makefile: Enable creation of - _symbols_ DT node for overlays" - -This reverts commit 432071b7a106060fa4e451e10249cef021af0b7c. - -commit: 432071b7a106 scripts: Makefile: Enable creation of _symbols_ DT node for overlays -changes the common Makefile and force creation of __symbols__ node on all platforms. - -This is not good and not acceptible under some cases due to this change will increase -the final DTB size a lot and bring big impact for others who does not need creation -of _symbols_ DT node for overlays.For example, on i.MX OP-TEE, the maxsize of DT is 1MB, -this patch will break some of the i.MX6/i.MX7 boards to boot with OP-TEE enabled. - -BTW, community has the similar patch but rejected. The following post discuss about this: -https://lore.kernel.org/patchwork/patch/821645/ - -For specifc plaform/board which need the creation of _symbols_ DT node for overlays, user can -define DTC_FLAGS_target either trough dtc build command line(#1) or with board specific Makefile(#2) - -For example:#1 - -make DTC_FLAGS_fsl-ls1028a-qds=-@ freescale/fsl-ls1028a-qds.dtb - -For example:#2 - -In arch/arm64/boot/dts/freescale/Makefile, - - @@ -1,4 +1,7 @@ - # SPDX-License-Identifier: GPL-2.0 - +# required for overlay support - +#DTC_FLAGS_fsl-ls1028a-qds := -@ - + - -Signed-off-by: Jason Liu -Signed-off-by: Dong Aisheng -Reviewed-by: Alex Marginean -Tested-by: Alex Marginean -[fix commit message] -Signed-off-by: Yangbo Lu ---- - scripts/Makefile.lib | 3 --- - 1 file changed, 3 deletions(-) - ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -255,9 +255,6 @@ endif - - DTC_FLAGS += $(DTC_FLAGS_$(basetarget)) - --# Enable creation of _symbols_ node for DT overlays --DTC_FLAGS += -@ -- - # Generate an assembly file to wrap the output of the device tree compiler - quiet_cmd_dt_S_dtb= DTB $@ - cmd_dt_S_dtb= \ diff --git a/target/linux/layerscape/patches-5.4/701-net-0001-soc-fsl-qman-fixup-liodns-only-on-ppc-targets.patch b/target/linux/layerscape/patches-5.4/701-net-0001-soc-fsl-qman-fixup-liodns-only-on-ppc-targets.patch deleted file mode 100644 index 0ac4bee2b1..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0001-soc-fsl-qman-fixup-liodns-only-on-ppc-targets.patch +++ /dev/null @@ -1,32 +0,0 @@ -From cc0d30fc5931e76e83f5cd1f5c91a9b97abf39b9 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 6 Feb 2018 15:55:56 +0200 -Subject: [PATCH] soc/fsl/qman: fixup liodns only on ppc targets - -ARM SoCs use SMMU so the liodn fixup done in the qman driver is no -longer making sense and it also breaks the ICID settings inherited -from u-boot. Do the fixups only for PPC targets. - -Signed-off-by: Laurentiu Tudor ---- - drivers/soc/fsl/qbman/qman_ccsr.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/soc/fsl/qbman/qman_ccsr.c -+++ b/drivers/soc/fsl/qbman/qman_ccsr.c -@@ -642,6 +642,7 @@ static int qman_init_ccsr(struct device - #define LIO_CFG_LIODN_MASK 0x0fff0000 - void __qman_liodn_fixup(u16 channel) - { -+#ifdef CONFIG_PPC - static int done; - static u32 liodn_offset; - u32 before, after; -@@ -661,6 +662,7 @@ void __qman_liodn_fixup(u16 channel) - qm_ccsr_out(REG_REV3_QCSP_LIO_CFG(idx), after); - else - qm_ccsr_out(REG_QCSP_LIO_CFG(idx), after); -+#endif - } - - #define IO_CFG_SDEST_MASK 0x00ff0000 diff --git a/target/linux/layerscape/patches-5.4/701-net-0002-soc-fsl-bman-map-FBPR-area-in-the-iommu.patch b/target/linux/layerscape/patches-5.4/701-net-0002-soc-fsl-bman-map-FBPR-area-in-the-iommu.patch deleted file mode 100644 index afafe928e4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0002-soc-fsl-bman-map-FBPR-area-in-the-iommu.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 55705ace9136e1c24d92d7ab23e513439eb766e7 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 3 Apr 2018 17:55:00 +0300 -Subject: [PATCH] soc/fsl/bman: map FBPR area in the iommu - -Add a one-to-one iommu mapping for bman private data memory (FBPR). -This is required for BMAN to work without faults behind an iommu. - -Signed-off-by: Laurentiu Tudor ---- - drivers/soc/fsl/qbman/bman_ccsr.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/drivers/soc/fsl/qbman/bman_ccsr.c -+++ b/drivers/soc/fsl/qbman/bman_ccsr.c -@@ -29,6 +29,7 @@ - */ - - #include "bman_priv.h" -+#include - - u16 bman_ip_rev; - EXPORT_SYMBOL(bman_ip_rev); -@@ -210,6 +211,7 @@ static int fsl_bman_probe(struct platfor - int ret, err_irq; - struct device *dev = &pdev->dev; - struct device_node *node = dev->of_node; -+ struct iommu_domain *domain; - struct resource *res; - u16 id, bm_pool_cnt; - u8 major, minor; -@@ -257,6 +259,15 @@ static int fsl_bman_probe(struct platfor - - dev_dbg(dev, "Allocated FBPR 0x%llx 0x%zx\n", fbpr_a, fbpr_sz); - -+ /* Create an 1-to-1 iommu mapping for FBPR area */ -+ domain = iommu_get_domain_for_dev(dev); -+ if (domain) { -+ ret = iommu_map(domain, fbpr_a, fbpr_a, fbpr_sz, -+ IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE); -+ if (ret) -+ dev_warn(dev, "failed to iommu_map() %d\n", ret); -+ } -+ - bm_set_memory(fbpr_a, fbpr_sz); - - err_irq = platform_get_irq(pdev, 0); diff --git a/target/linux/layerscape/patches-5.4/701-net-0003-soc-fsl-qman-map-FQD-and-PFDR-areas-in-the-iommu.patch b/target/linux/layerscape/patches-5.4/701-net-0003-soc-fsl-qman-map-FQD-and-PFDR-areas-in-the-iommu.patch deleted file mode 100644 index 03b8c22465..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0003-soc-fsl-qman-map-FQD-and-PFDR-areas-in-the-iommu.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 02638b2627104cd02aff7484bb250d029e05dc5f Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 3 Apr 2018 18:08:48 +0300 -Subject: [PATCH] soc/fsl/qman: map FQD and PFDR areas in the iommu - -Add a one-to-one iommu mapping for qman private data memory areas -(FQD and PFDR). This is required for QMAN to work without faults -behind an iommu. - -Signed-off-by: Laurentiu Tudor ---- - drivers/soc/fsl/qbman/qman_ccsr.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - ---- a/drivers/soc/fsl/qbman/qman_ccsr.c -+++ b/drivers/soc/fsl/qbman/qman_ccsr.c -@@ -29,6 +29,7 @@ - */ - - #include "qman_priv.h" -+#include - - u16 qman_ip_rev; - EXPORT_SYMBOL(qman_ip_rev); -@@ -755,6 +756,7 @@ static int fsl_qman_probe(struct platfor - { - struct device *dev = &pdev->dev; - struct device_node *node = dev->of_node; -+ struct iommu_domain *domain; - struct resource *res; - int ret, err_irq; - u16 id; -@@ -834,6 +836,19 @@ static int fsl_qman_probe(struct platfor - } - dev_dbg(dev, "Allocated PFDR 0x%llx 0x%zx\n", pfdr_a, pfdr_sz); - -+ /* Create an 1-to-1 iommu mapping for fqd and pfdr areas */ -+ domain = iommu_get_domain_for_dev(dev); -+ if (domain) { -+ ret = iommu_map(domain, fqd_a, fqd_a, fqd_sz, -+ IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE); -+ if (ret) -+ dev_warn(dev, "iommu_map(fqd) failed %d\n", ret); -+ ret = iommu_map(domain, pfdr_a, pfdr_a, pfdr_sz, -+ IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE); -+ if (ret) -+ dev_warn(dev, "iommu_map(pfdr) failed %d\n", ret); -+ } -+ - ret = qman_init_ccsr(dev); - if (ret) { - dev_err(dev, "CCSR setup failed\n"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0004-soc-fsl-qman-portal-map-CENA-area-in-the-iommu.patch b/target/linux/layerscape/patches-5.4/701-net-0004-soc-fsl-qman-portal-map-CENA-area-in-the-iommu.patch deleted file mode 100644 index b29964204d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0004-soc-fsl-qman-portal-map-CENA-area-in-the-iommu.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 488b62aa444440690708e5ea823bb0d54c296c4f Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 3 Apr 2018 18:18:30 +0300 -Subject: [PATCH] soc/fsl/qman-portal: map CENA area in the iommu - -Add a one-to-one iommu mapping for qman portal CENA register area. -This is required for QMAN stashing to work without faults behind -an iommu. - -Signed-off-by: Laurentiu Tudor ---- - drivers/soc/fsl/qbman/qman_portal.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/drivers/soc/fsl/qbman/qman_portal.c -+++ b/drivers/soc/fsl/qbman/qman_portal.c -@@ -29,6 +29,7 @@ - */ - - #include "qman_priv.h" -+#include - - struct qman_portal *qman_dma_portal; - EXPORT_SYMBOL(qman_dma_portal); -@@ -231,6 +232,7 @@ static int qman_portal_probe(struct plat - { - struct device *dev = &pdev->dev; - struct device_node *node = dev->of_node; -+ struct iommu_domain *domain; - struct qm_portal_config *pcfg; - struct resource *addr_phys[2]; - int irq, cpu, err, i; -@@ -294,6 +296,21 @@ static int qman_portal_probe(struct plat - goto err_ioremap2; - } - -+ /* Create an 1-to-1 iommu mapping for cena portal area */ -+ domain = iommu_get_domain_for_dev(dev); -+ if (domain) { -+ /* -+ * Note: not mapping this as cacheable triggers the infamous -+ * QMan CIDE error. -+ */ -+ err = iommu_map(domain, -+ addr_phys[0]->start, addr_phys[0]->start, -+ resource_size(addr_phys[0]), -+ IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE); -+ if (err) -+ dev_warn(dev, "failed to iommu_map() %d\n", err); -+ } -+ - pcfg->pools = qm_get_pools_sdqcr(); - - spin_lock(&qman_lock); diff --git a/target/linux/layerscape/patches-5.4/701-net-0005-soc-fsl-qbman_portals-add-APIs-to-retrieve-the-probi.patch b/target/linux/layerscape/patches-5.4/701-net-0005-soc-fsl-qbman_portals-add-APIs-to-retrieve-the-probi.patch deleted file mode 100644 index a137e55e96..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0005-soc-fsl-qbman_portals-add-APIs-to-retrieve-the-probi.patch +++ /dev/null @@ -1,71 +0,0 @@ -From d43acc10c25f01a461a1cb1c1fd0cc72cd29dd42 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Thu, 2 Aug 2018 16:14:12 +0300 -Subject: [PATCH] soc/fsl/qbman_portals: add APIs to retrieve the probing - status - -Add a couple of new APIs to check the probing status of the required -cpu bound qman and bman portals: - 'int bman_portals_probed()' and 'int qman_portals_probed()'. -They return the following values. - * 1 if qman/bman portals were all probed correctly - * 0 if qman/bman portals were not yet probed - * -1 if probing of qman/bman portals failed -Portals are considered successful probed if no error occurred during -the probing of any of the portals and if enough portals were probed -to have one available for each cpu. -The error handling paths were slightly rearranged in order to fit this -new functionality without being too intrusive. -Drivers that use qman/bman portal driver services are required to use -these APIs before calling any functions exported by these drivers or -otherwise they will crash the kernel. -First user will be the dpaa1 ethernet driver, coming in a subsequent -patch. - -Signed-off-by: Laurentiu Tudor ---- - drivers/soc/fsl/qbman/bman_portal.c | 3 +++ - drivers/soc/fsl/qbman/qman_portal.c | 3 +++ - include/soc/fsl/qman.h | 9 +++++++++ - 3 files changed, 15 insertions(+) - ---- a/drivers/soc/fsl/qbman/bman_portal.c -+++ b/drivers/soc/fsl/qbman/bman_portal.c -@@ -164,6 +164,9 @@ static int bman_portal_probe(struct plat - } - - cpumask_set_cpu(cpu, &portal_cpus); -+ if (!__bman_portals_probed && -+ cpumask_weight(&portal_cpus) == num_online_cpus()) -+ __bman_portals_probed = 1; - spin_unlock(&bman_lock); - pcfg->cpu = cpu; - ---- a/drivers/soc/fsl/qbman/qman_portal.c -+++ b/drivers/soc/fsl/qbman/qman_portal.c -@@ -323,6 +323,9 @@ static int qman_portal_probe(struct plat - } - - cpumask_set_cpu(cpu, &portal_cpus); -+ if (!__qman_portals_probed && -+ cpumask_weight(&portal_cpus) == num_online_cpus()) -+ __qman_portals_probed = 1; - spin_unlock(&qman_lock); - pcfg->cpu = cpu; - ---- a/include/soc/fsl/qman.h -+++ b/include/soc/fsl/qman.h -@@ -1235,4 +1235,13 @@ void qman_portal_get_iperiod(struct qman - */ - int qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod); - -+/** -+ * qman_portals_probed - Check if all cpu bound qman portals are probed -+ * -+ * Returns 1 if all the required cpu bound qman portals successfully probed, -+ * -1 if probe errors appeared or 0 if the qman portals did not yet finished -+ * probing. -+ */ -+int qman_portals_probed(void); -+ - #endif /* __FSL_QMAN_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0006-soc-fsl-bqman-page-align-iommu-mapping-sizes.patch b/target/linux/layerscape/patches-5.4/701-net-0006-soc-fsl-bqman-page-align-iommu-mapping-sizes.patch deleted file mode 100644 index 8e10ef1358..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0006-soc-fsl-bqman-page-align-iommu-mapping-sizes.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 218274ea02e908846fabb5b9a2ab7409da06a85f Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Thu, 22 Nov 2018 12:32:13 +0200 -Subject: [PATCH] soc/fsl/bqman: page align iommu mapping sizes - -Prior to calling iommu_map()/iommu_unmap() page align the size or -failures such as below could happen: - -iommu: unaligned: iova 0x... pa 0x... size 0x4000 min_pagesz 0x10000 -qman_portal 500000000.qman-portal: failed to iommu_map() -22 - -Seen when booted a kernel compiled with 64K page size support. - -Signed-off-by: Laurentiu Tudor ---- - drivers/soc/fsl/qbman/bman_ccsr.c | 2 +- - drivers/soc/fsl/qbman/qman_ccsr.c | 4 ++-- - drivers/soc/fsl/qbman/qman_portal.c | 2 +- - 3 files changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/soc/fsl/qbman/bman_ccsr.c -+++ b/drivers/soc/fsl/qbman/bman_ccsr.c -@@ -262,7 +262,7 @@ static int fsl_bman_probe(struct platfor - /* Create an 1-to-1 iommu mapping for FBPR area */ - domain = iommu_get_domain_for_dev(dev); - if (domain) { -- ret = iommu_map(domain, fbpr_a, fbpr_a, fbpr_sz, -+ ret = iommu_map(domain, fbpr_a, fbpr_a, PAGE_ALIGN(fbpr_sz), - IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE); - if (ret) - dev_warn(dev, "failed to iommu_map() %d\n", ret); ---- a/drivers/soc/fsl/qbman/qman_ccsr.c -+++ b/drivers/soc/fsl/qbman/qman_ccsr.c -@@ -839,11 +839,11 @@ static int fsl_qman_probe(struct platfor - /* Create an 1-to-1 iommu mapping for fqd and pfdr areas */ - domain = iommu_get_domain_for_dev(dev); - if (domain) { -- ret = iommu_map(domain, fqd_a, fqd_a, fqd_sz, -+ ret = iommu_map(domain, fqd_a, fqd_a, PAGE_ALIGN(fqd_sz), - IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE); - if (ret) - dev_warn(dev, "iommu_map(fqd) failed %d\n", ret); -- ret = iommu_map(domain, pfdr_a, pfdr_a, pfdr_sz, -+ ret = iommu_map(domain, pfdr_a, pfdr_a, PAGE_ALIGN(pfdr_sz), - IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE); - if (ret) - dev_warn(dev, "iommu_map(pfdr) failed %d\n", ret); ---- a/drivers/soc/fsl/qbman/qman_portal.c -+++ b/drivers/soc/fsl/qbman/qman_portal.c -@@ -305,7 +305,7 @@ static int qman_portal_probe(struct plat - */ - err = iommu_map(domain, - addr_phys[0]->start, addr_phys[0]->start, -- resource_size(addr_phys[0]), -+ PAGE_ALIGN(resource_size(addr_phys[0])), - IOMMU_READ | IOMMU_WRITE | IOMMU_CACHE); - if (err) - dev_warn(dev, "failed to iommu_map() %d\n", err); diff --git a/target/linux/layerscape/patches-5.4/701-net-0007-fsl_qbman-SDK-DPAA-1.x-QBMan-drivers.patch b/target/linux/layerscape/patches-5.4/701-net-0007-fsl_qbman-SDK-DPAA-1.x-QBMan-drivers.patch deleted file mode 100644 index b9e7667065..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0007-fsl_qbman-SDK-DPAA-1.x-QBMan-drivers.patch +++ /dev/null @@ -1,24880 +0,0 @@ -From 772438d01bf57bc8939f53c3101a323fc774428f Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Wed, 10 May 2017 16:30:12 +0300 -Subject: [PATCH] fsl_qbman: SDK DPAA 1.x QBMan drivers - -Signed-off-by: Roy Pledge -Signed-off-by: Madalin Bucur ---- - drivers/staging/fsl_qbman/Kconfig | 228 + - drivers/staging/fsl_qbman/Makefile | 28 + - drivers/staging/fsl_qbman/bman_config.c | 720 +++ - drivers/staging/fsl_qbman/bman_debugfs.c | 119 + - drivers/staging/fsl_qbman/bman_driver.c | 559 +++ - drivers/staging/fsl_qbman/bman_high.c | 1145 +++++ - drivers/staging/fsl_qbman/bman_low.h | 565 +++ - drivers/staging/fsl_qbman/bman_private.h | 166 + - drivers/staging/fsl_qbman/bman_test.c | 56 + - drivers/staging/fsl_qbman/bman_test.h | 44 + - drivers/staging/fsl_qbman/bman_test_high.c | 183 + - drivers/staging/fsl_qbman/bman_test_thresh.c | 196 + - drivers/staging/fsl_qbman/dpa_alloc.c | 706 +++ - drivers/staging/fsl_qbman/dpa_sys.h | 259 ++ - drivers/staging/fsl_qbman/dpa_sys_arm.h | 95 + - drivers/staging/fsl_qbman/dpa_sys_arm64.h | 102 + - drivers/staging/fsl_qbman/dpa_sys_ppc32.h | 70 + - drivers/staging/fsl_qbman/dpa_sys_ppc64.h | 79 + - drivers/staging/fsl_qbman/fsl_usdpaa.c | 1984 ++++++++ - drivers/staging/fsl_qbman/fsl_usdpaa_irq.c | 289 ++ - drivers/staging/fsl_qbman/qbman_driver.c | 88 + - drivers/staging/fsl_qbman/qman_config.c | 1224 +++++ - drivers/staging/fsl_qbman/qman_debugfs.c | 1594 +++++++ - drivers/staging/fsl_qbman/qman_driver.c | 961 ++++ - drivers/staging/fsl_qbman/qman_high.c | 5669 +++++++++++++++++++++++ - drivers/staging/fsl_qbman/qman_low.h | 1427 ++++++ - drivers/staging/fsl_qbman/qman_private.h | 398 ++ - drivers/staging/fsl_qbman/qman_test.c | 57 + - drivers/staging/fsl_qbman/qman_test.h | 45 + - drivers/staging/fsl_qbman/qman_test_high.c | 216 + - drivers/staging/fsl_qbman/qman_test_hotpotato.c | 502 ++ - drivers/staging/fsl_qbman/qman_utility.c | 129 + - include/linux/fsl_bman.h | 532 +++ - include/linux/fsl_qman.h | 3888 ++++++++++++++++ - include/linux/fsl_usdpaa.h | 372 ++ - 35 files changed, 24695 insertions(+) - create mode 100644 drivers/staging/fsl_qbman/Kconfig - create mode 100644 drivers/staging/fsl_qbman/Makefile - create mode 100644 drivers/staging/fsl_qbman/bman_config.c - create mode 100644 drivers/staging/fsl_qbman/bman_debugfs.c - create mode 100644 drivers/staging/fsl_qbman/bman_driver.c - create mode 100644 drivers/staging/fsl_qbman/bman_high.c - create mode 100644 drivers/staging/fsl_qbman/bman_low.h - create mode 100644 drivers/staging/fsl_qbman/bman_private.h - create mode 100644 drivers/staging/fsl_qbman/bman_test.c - create mode 100644 drivers/staging/fsl_qbman/bman_test.h - create mode 100644 drivers/staging/fsl_qbman/bman_test_high.c - create mode 100644 drivers/staging/fsl_qbman/bman_test_thresh.c - create mode 100644 drivers/staging/fsl_qbman/dpa_alloc.c - create mode 100644 drivers/staging/fsl_qbman/dpa_sys.h - create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm.h - create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm64.h - create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc32.h - create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc64.h - create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa.c - create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c - create mode 100644 drivers/staging/fsl_qbman/qbman_driver.c - create mode 100644 drivers/staging/fsl_qbman/qman_config.c - create mode 100644 drivers/staging/fsl_qbman/qman_debugfs.c - create mode 100644 drivers/staging/fsl_qbman/qman_driver.c - create mode 100644 drivers/staging/fsl_qbman/qman_high.c - create mode 100644 drivers/staging/fsl_qbman/qman_low.h - create mode 100644 drivers/staging/fsl_qbman/qman_private.h - create mode 100644 drivers/staging/fsl_qbman/qman_test.c - create mode 100644 drivers/staging/fsl_qbman/qman_test.h - create mode 100644 drivers/staging/fsl_qbman/qman_test_high.c - create mode 100644 drivers/staging/fsl_qbman/qman_test_hotpotato.c - create mode 100644 drivers/staging/fsl_qbman/qman_utility.c - create mode 100644 include/linux/fsl_bman.h - create mode 100644 include/linux/fsl_qman.h - create mode 100644 include/linux/fsl_usdpaa.h - ---- /dev/null -+++ b/drivers/staging/fsl_qbman/Kconfig -@@ -0,0 +1,228 @@ -+config FSL_SDK_DPA -+ bool "Freescale Datapath Queue and Buffer management" -+ depends on !FSL_DPAA -+ select FSL_QMAN_FQ_LOOKUP if PPC64 -+ select FSL_QMAN_FQ_LOOKUP if ARM64 -+ -+ -+menu "Freescale Datapath QMan/BMan options" -+ depends on FSL_SDK_DPA -+ -+config FSL_DPA_CHECKING -+ bool "additional driver checking" -+ default n -+ ---help--- -+ Compiles in additional checks to sanity-check the drivers and any -+ use of it by other code. Not recommended for performance. -+ -+config FSL_DPA_CAN_WAIT -+ bool -+ default y -+ -+config FSL_DPA_CAN_WAIT_SYNC -+ bool -+ default y -+ -+config FSL_DPA_PIRQ_FAST -+ bool -+ default y -+ -+config FSL_DPA_PIRQ_SLOW -+ bool -+ default y -+ -+config FSL_DPA_PORTAL_SHARE -+ bool -+ default y -+ -+config FSL_SDK_BMAN -+ bool "Freescale Buffer Manager (BMan) support" -+ default y -+ -+if FSL_SDK_BMAN -+ -+config FSL_BMAN_CONFIG -+ bool "BMan device management" -+ default y -+ ---help--- -+ If this linux image is running natively, you need this option. If this -+ linux image is running as a guest OS under the hypervisor, only one -+ guest OS ("the control plane") needs this option. -+ -+config FSL_BMAN_TEST -+ tristate "BMan self-tests" -+ default n -+ ---help--- -+ This option compiles self-test code for BMan. -+ -+config FSL_BMAN_TEST_HIGH -+ bool "BMan high-level self-test" -+ depends on FSL_BMAN_TEST -+ default y -+ ---help--- -+ This requires the presence of cpu-affine portals, and performs -+ high-level API testing with them (whichever portal(s) are affine to -+ the cpu(s) the test executes on). -+ -+config FSL_BMAN_TEST_THRESH -+ bool "BMan threshold test" -+ depends on FSL_BMAN_TEST -+ default y -+ ---help--- -+ Multi-threaded (SMP) test of BMan pool depletion. A pool is seeded -+ before multiple threads (one per cpu) create pool objects to track -+ depletion state changes. The pool is then drained to empty by a -+ "drainer" thread, and the other threads that they observe exactly -+ the depletion state changes that are expected. -+ -+config FSL_BMAN_DEBUGFS -+ tristate "BMan debugfs interface" -+ depends on DEBUG_FS -+ default y -+ ---help--- -+ This option compiles debugfs code for BMan. -+ -+endif # FSL_SDK_BMAN -+ -+config FSL_SDK_QMAN -+ bool "Freescale Queue Manager (QMan) support" -+ default y -+ -+if FSL_SDK_QMAN -+ -+config FSL_QMAN_POLL_LIMIT -+ int -+ default 32 -+ -+config FSL_QMAN_CONFIG -+ bool "QMan device management" -+ default y -+ ---help--- -+ If this linux image is running natively, you need this option. If this -+ linux image is running as a guest OS under the hypervisor, only one -+ guest OS ("the control plane") needs this option. -+ -+config FSL_QMAN_TEST -+ tristate "QMan self-tests" -+ default n -+ ---help--- -+ This option compiles self-test code for QMan. -+ -+config FSL_QMAN_TEST_STASH_POTATO -+ bool "QMan 'hot potato' data-stashing self-test" -+ depends on FSL_QMAN_TEST -+ default y -+ ---help--- -+ This performs a "hot potato" style test enqueuing/dequeuing a frame -+ across a series of FQs scheduled to different portals (and cpus), with -+ DQRR, data and context stashing always on. -+ -+config FSL_QMAN_TEST_HIGH -+ bool "QMan high-level self-test" -+ depends on FSL_QMAN_TEST -+ default y -+ ---help--- -+ This requires the presence of cpu-affine portals, and performs -+ high-level API testing with them (whichever portal(s) are affine to -+ the cpu(s) the test executes on). -+ -+config FSL_QMAN_DEBUGFS -+ tristate "QMan debugfs interface" -+ depends on DEBUG_FS -+ default y -+ ---help--- -+ This option compiles debugfs code for QMan. -+ -+# H/w settings that can be hard-coded for now. -+config FSL_QMAN_FQD_SZ -+ int "size of Frame Queue Descriptor region" -+ default 10 -+ ---help--- -+ This is the size of the FQD region defined as: PAGE_SIZE * (2^value) -+ ex: 10 => PAGE_SIZE * (2^10) -+ Note: Default device-trees now require minimum Kconfig setting of 10. -+ -+config FSL_QMAN_PFDR_SZ -+ int "size of the PFDR pool" -+ default 13 -+ ---help--- -+ This is the size of the PFDR pool defined as: PAGE_SIZE * (2^value) -+ ex: 13 => PAGE_SIZE * (2^13) -+ -+# Corenet initiator settings. Stash request queues are 4-deep to match cores' -+# ability to snart. Stash priority is 3, other priorities are 2. -+config FSL_QMAN_CI_SCHED_CFG_SRCCIV -+ int -+ depends on FSL_QMAN_CONFIG -+ default 4 -+config FSL_QMAN_CI_SCHED_CFG_SRQ_W -+ int -+ depends on FSL_QMAN_CONFIG -+ default 3 -+config FSL_QMAN_CI_SCHED_CFG_RW_W -+ int -+ depends on FSL_QMAN_CONFIG -+ default 2 -+config FSL_QMAN_CI_SCHED_CFG_BMAN_W -+ int -+ depends on FSL_QMAN_CONFIG -+ default 2 -+ -+# portal interrupt settings -+config FSL_QMAN_PIRQ_DQRR_ITHRESH -+ int -+ default 12 -+config FSL_QMAN_PIRQ_MR_ITHRESH -+ int -+ default 4 -+config FSL_QMAN_PIRQ_IPERIOD -+ int -+ default 100 -+ -+# 64 bit kernel support -+config FSL_QMAN_FQ_LOOKUP -+ bool -+ default n -+ -+config QMAN_CEETM_UPDATE_PERIOD -+ int "Token update period for shaping, in nanoseconds" -+ default 1000 -+ ---help--- -+ Traffic shaping works by performing token calculations (using -+ credits) on shaper instances periodically. This update period -+ sets the granularity for how often those token rate credit -+ updates are performed, and thus determines the accuracy and -+ range of traffic rates that can be configured by users. The -+ reference manual recommends a 1 microsecond period as providing -+ a good balance between granularity and range. -+ -+ Unless you know what you are doing, leave this value at its default. -+ -+config FSL_QMAN_INIT_TIMEOUT -+ int "timeout for qman init stage, in seconds" -+ default 10 -+ ---help--- -+ The timeout setting to quit the initialization loop for non-control -+ partition in case the control partition fails to boot-up. -+ -+endif # FSL_SDK_QMAN -+ -+config FSL_USDPAA -+ bool "Freescale USDPAA process driver" -+ depends on FSL_SDK_DPA -+ default y -+ ---help--- -+ This driver provides user-space access to kernel-managed -+ resource interfaces for USDPAA applications, on the assumption -+ that each process will open this device once. Specifically, this -+ device exposes functionality that would be awkward if exposed -+ via the portal devices - ie. this device exposes functionality -+ that is inherently process-wide rather than portal-specific. -+ This device is necessary for obtaining access to DMA memory and -+ for allocation of Qman and Bman resources. In short, if you wish -+ to use USDPAA applications, you need this. -+ -+ If unsure, say Y. -+ -+ -+endmenu ---- /dev/null -+++ b/drivers/staging/fsl_qbman/Makefile -@@ -0,0 +1,28 @@ -+subdir-ccflags-y := -Werror -+ -+# Common -+obj-$(CONFIG_FSL_SDK_DPA) += dpa_alloc.o -+obj-$(CONFIG_FSL_SDK_DPA) += qbman_driver.o -+ -+# Bman -+obj-$(CONFIG_FSL_SDK_BMAN) += bman_high.o -+obj-$(CONFIG_FSL_BMAN_CONFIG) += bman_config.o bman_driver.o -+obj-$(CONFIG_FSL_BMAN_TEST) += bman_tester.o -+obj-$(CONFIG_FSL_BMAN_DEBUGFS) += bman_debugfs_interface.o -+bman_tester-y = bman_test.o -+bman_tester-$(CONFIG_FSL_BMAN_TEST_HIGH) += bman_test_high.o -+bman_tester-$(CONFIG_FSL_BMAN_TEST_THRESH) += bman_test_thresh.o -+bman_debugfs_interface-y = bman_debugfs.o -+ -+# Qman -+obj-$(CONFIG_FSL_SDK_QMAN) += qman_high.o qman_utility.o -+obj-$(CONFIG_FSL_QMAN_CONFIG) += qman_config.o qman_driver.o -+obj-$(CONFIG_FSL_QMAN_TEST) += qman_tester.o -+qman_tester-y = qman_test.o -+qman_tester-$(CONFIG_FSL_QMAN_TEST_STASH_POTATO) += qman_test_hotpotato.o -+qman_tester-$(CONFIG_FSL_QMAN_TEST_HIGH) += qman_test_high.o -+obj-$(CONFIG_FSL_QMAN_DEBUGFS) += qman_debugfs_interface.o -+qman_debugfs_interface-y = qman_debugfs.o -+ -+# USDPAA -+obj-$(CONFIG_FSL_USDPAA) += fsl_usdpaa.o fsl_usdpaa_irq.o ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_config.c -@@ -0,0 +1,720 @@ -+/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include "bman_private.h" -+#include -+ -+/* Last updated for v00.79 of the BG */ -+ -+struct bman; -+ -+/* Register offsets */ -+#define REG_POOL_SWDET(n) (0x0000 + ((n) * 0x04)) -+#define REG_POOL_HWDET(n) (0x0100 + ((n) * 0x04)) -+#define REG_POOL_SWDXT(n) (0x0200 + ((n) * 0x04)) -+#define REG_POOL_HWDXT(n) (0x0300 + ((n) * 0x04)) -+#define REG_POOL_CONTENT(n) (0x0600 + ((n) * 0x04)) -+#define REG_FBPR_FPC 0x0800 -+#define REG_STATE_IDLE 0x960 -+#define REG_STATE_STOP 0x964 -+#define REG_ECSR 0x0a00 -+#define REG_ECIR 0x0a04 -+#define REG_EADR 0x0a08 -+#define REG_EDATA(n) (0x0a10 + ((n) * 0x04)) -+#define REG_SBEC(n) (0x0a80 + ((n) * 0x04)) -+#define REG_IP_REV_1 0x0bf8 -+#define REG_IP_REV_2 0x0bfc -+#define REG_FBPR_BARE 0x0c00 -+#define REG_FBPR_BAR 0x0c04 -+#define REG_FBPR_AR 0x0c10 -+#define REG_SRCIDR 0x0d04 -+#define REG_LIODNR 0x0d08 -+#define REG_ERR_ISR 0x0e00 /* + "enum bm_isr_reg" */ -+ -+/* Used by all error interrupt registers except 'inhibit' */ -+#define BM_EIRQ_IVCI 0x00000010 /* Invalid Command Verb */ -+#define BM_EIRQ_FLWI 0x00000008 /* FBPR Low Watermark */ -+#define BM_EIRQ_MBEI 0x00000004 /* Multi-bit ECC Error */ -+#define BM_EIRQ_SBEI 0x00000002 /* Single-bit ECC Error */ -+#define BM_EIRQ_BSCN 0x00000001 /* pool State Change Notification */ -+ -+/* BMAN_ECIR valid error bit */ -+#define PORTAL_ECSR_ERR (BM_EIRQ_IVCI) -+ -+union bman_ecir { -+ u32 ecir_raw; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 __reserved1:4; -+ u32 portal_num:4; -+ u32 __reserved2:12; -+ u32 numb:4; -+ u32 __reserved3:2; -+ u32 pid:6; -+#else -+ u32 pid:6; -+ u32 __reserved3:2; -+ u32 numb:4; -+ u32 __reserved2:12; -+ u32 portal_num:4; -+ u32 __reserved1:4; -+#endif -+ } __packed info; -+}; -+ -+union bman_eadr { -+ u32 eadr_raw; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 __reserved1:5; -+ u32 memid:3; -+ u32 __reserved2:14; -+ u32 eadr:10; -+#else -+ u32 eadr:10; -+ u32 __reserved2:14; -+ u32 memid:3; -+ u32 __reserved1:5; -+#endif -+ } __packed info; -+}; -+ -+struct bman_hwerr_txt { -+ u32 mask; -+ const char *txt; -+}; -+ -+#define BMAN_HWE_TXT(a, b) { .mask = BM_EIRQ_##a, .txt = b } -+ -+static const struct bman_hwerr_txt bman_hwerr_txts[] = { -+ BMAN_HWE_TXT(IVCI, "Invalid Command Verb"), -+ BMAN_HWE_TXT(FLWI, "FBPR Low Watermark"), -+ BMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"), -+ BMAN_HWE_TXT(SBEI, "Single-bit ECC Error"), -+ BMAN_HWE_TXT(BSCN, "Pool State Change Notification"), -+}; -+#define BMAN_HWE_COUNT (sizeof(bman_hwerr_txts)/sizeof(struct bman_hwerr_txt)) -+ -+struct bman_error_info_mdata { -+ u16 addr_mask; -+ u16 bits; -+ const char *txt; -+}; -+ -+#define BMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c} -+static const struct bman_error_info_mdata error_mdata[] = { -+ BMAN_ERR_MDATA(0x03FF, 192, "Stockpile memory"), -+ BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 1"), -+ BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 2"), -+}; -+#define BMAN_ERR_MDATA_COUNT \ -+ (sizeof(error_mdata)/sizeof(struct bman_error_info_mdata)) -+ -+/* Add this in Kconfig */ -+#define BMAN_ERRS_TO_UNENABLE (BM_EIRQ_FLWI) -+ -+/** -+ * bm_err_isr__ - Manipulate global interrupt registers -+ * @v: for accessors that write values, this is the 32-bit value -+ * -+ * Manipulates BMAN_ERR_ISR, BMAN_ERR_IER, BMAN_ERR_ISDR, BMAN_ERR_IIR. All -+ * manipulations except bm_err_isr_[un]inhibit() use 32-bit masks composed of -+ * the BM_EIRQ_*** definitions. Note that "bm_err_isr_enable_write" means -+ * "write the enable register" rather than "enable the write register"! -+ */ -+#define bm_err_isr_status_read(bm) \ -+ __bm_err_isr_read(bm, bm_isr_status) -+#define bm_err_isr_status_clear(bm, m) \ -+ __bm_err_isr_write(bm, bm_isr_status, m) -+#define bm_err_isr_enable_read(bm) \ -+ __bm_err_isr_read(bm, bm_isr_enable) -+#define bm_err_isr_enable_write(bm, v) \ -+ __bm_err_isr_write(bm, bm_isr_enable, v) -+#define bm_err_isr_disable_read(bm) \ -+ __bm_err_isr_read(bm, bm_isr_disable) -+#define bm_err_isr_disable_write(bm, v) \ -+ __bm_err_isr_write(bm, bm_isr_disable, v) -+#define bm_err_isr_inhibit(bm) \ -+ __bm_err_isr_write(bm, bm_isr_inhibit, 1) -+#define bm_err_isr_uninhibit(bm) \ -+ __bm_err_isr_write(bm, bm_isr_inhibit, 0) -+ -+/* -+ * TODO: unimplemented registers -+ * -+ * BMAN_POOLk_SDCNT, BMAN_POOLk_HDCNT, BMAN_FULT, -+ * BMAN_VLDPL, BMAN_EECC, BMAN_SBET, BMAN_EINJ -+ */ -+ -+/* Encapsulate "struct bman *" as a cast of the register space address. */ -+ -+static struct bman *bm_create(void *regs) -+{ -+ return (struct bman *)regs; -+} -+ -+static inline u32 __bm_in(struct bman *bm, u32 offset) -+{ -+ return in_be32((void *)bm + offset); -+} -+static inline void __bm_out(struct bman *bm, u32 offset, u32 val) -+{ -+ out_be32((void *)bm + offset, val); -+} -+#define bm_in(reg) __bm_in(bm, REG_##reg) -+#define bm_out(reg, val) __bm_out(bm, REG_##reg, val) -+ -+static u32 __bm_err_isr_read(struct bman *bm, enum bm_isr_reg n) -+{ -+ return __bm_in(bm, REG_ERR_ISR + (n << 2)); -+} -+ -+static void __bm_err_isr_write(struct bman *bm, enum bm_isr_reg n, u32 val) -+{ -+ __bm_out(bm, REG_ERR_ISR + (n << 2), val); -+} -+ -+static void bm_get_version(struct bman *bm, u16 *id, u8 *major, u8 *minor) -+{ -+ u32 v = bm_in(IP_REV_1); -+ *id = (v >> 16); -+ *major = (v >> 8) & 0xff; -+ *minor = v & 0xff; -+} -+ -+static u32 __generate_thresh(u32 val, int roundup) -+{ -+ u32 e = 0; /* co-efficient, exponent */ -+ int oddbit = 0; -+ while (val > 0xff) { -+ oddbit = val & 1; -+ val >>= 1; -+ e++; -+ if (roundup && oddbit) -+ val++; -+ } -+ DPA_ASSERT(e < 0x10); -+ return val | (e << 8); -+} -+ -+static void bm_set_pool(struct bman *bm, u8 pool, u32 swdet, u32 swdxt, -+ u32 hwdet, u32 hwdxt) -+{ -+ DPA_ASSERT(pool < bman_pool_max); -+ bm_out(POOL_SWDET(pool), __generate_thresh(swdet, 0)); -+ bm_out(POOL_SWDXT(pool), __generate_thresh(swdxt, 1)); -+ bm_out(POOL_HWDET(pool), __generate_thresh(hwdet, 0)); -+ bm_out(POOL_HWDXT(pool), __generate_thresh(hwdxt, 1)); -+} -+ -+static void bm_set_memory(struct bman *bm, u64 ba, int prio, u32 size) -+{ -+ u32 exp = ilog2(size); -+ /* choke if size isn't within range */ -+ DPA_ASSERT((size >= 4096) && (size <= 1073741824) && -+ is_power_of_2(size)); -+ /* choke if '[e]ba' has lower-alignment than 'size' */ -+ DPA_ASSERT(!(ba & (size - 1))); -+ bm_out(FBPR_BARE, upper_32_bits(ba)); -+ bm_out(FBPR_BAR, lower_32_bits(ba)); -+ bm_out(FBPR_AR, (prio ? 0x40000000 : 0) | (exp - 1)); -+} -+ -+/*****************/ -+/* Config driver */ -+/*****************/ -+ -+/* TODO: Kconfig these? */ -+#define DEFAULT_FBPR_SZ (PAGE_SIZE << 12) -+ -+/* We support only one of these. */ -+static struct bman *bm; -+static struct device_node *bm_node; -+ -+/* And this state belongs to 'bm'. It is set during fsl_bman_init(), but used -+ * during bman_init_ccsr(). */ -+static dma_addr_t fbpr_a; -+static size_t fbpr_sz = DEFAULT_FBPR_SZ; -+ -+static int bman_fbpr(struct reserved_mem *rmem) -+{ -+ fbpr_a = rmem->base; -+ fbpr_sz = rmem->size; -+ -+ WARN_ON(!(fbpr_a && fbpr_sz)); -+ -+ return 0; -+} -+RESERVEDMEM_OF_DECLARE(bman_fbpr, "fsl,bman-fbpr", bman_fbpr); -+ -+static int __init fsl_bman_init(struct device_node *node) -+{ -+ struct resource res; -+ u32 __iomem *regs; -+ const char *s; -+ int ret, standby = 0; -+ u16 id; -+ u8 major, minor; -+ -+ ret = of_address_to_resource(node, 0, &res); -+ if (ret) { -+ pr_err("Can't get %s property 'reg'\n", -+ node->full_name); -+ return ret; -+ } -+ s = of_get_property(node, "fsl,hv-claimable", &ret); -+ if (s && !strcmp(s, "standby")) -+ standby = 1; -+ /* Global configuration */ -+ regs = ioremap(res.start, res.end - res.start + 1); -+ bm = bm_create(regs); -+ BUG_ON(!bm); -+ bm_node = node; -+ bm_get_version(bm, &id, &major, &minor); -+ pr_info("Bman ver:%04x,%02x,%02x\n", id, major, minor); -+ if ((major == 1) && (minor == 0)) { -+ bman_ip_rev = BMAN_REV10; -+ bman_pool_max = 64; -+ } else if ((major == 2) && (minor == 0)) { -+ bman_ip_rev = BMAN_REV20; -+ bman_pool_max = 8; -+ } else if ((major == 2) && (minor == 1)) { -+ bman_ip_rev = BMAN_REV21; -+ bman_pool_max = 64; -+ } else { -+ pr_warn("unknown Bman version, default to rev1.0\n"); -+ } -+ -+ if (standby) { -+ pr_info(" -> in standby mode\n"); -+ return 0; -+ } -+ return 0; -+} -+ -+int bman_have_ccsr(void) -+{ -+ return bm ? 1 : 0; -+} -+ -+int bm_pool_set(u32 bpid, const u32 *thresholds) -+{ -+ if (!bm) -+ return -ENODEV; -+ bm_set_pool(bm, bpid, thresholds[0], -+ thresholds[1], thresholds[2], -+ thresholds[3]); -+ return 0; -+} -+EXPORT_SYMBOL(bm_pool_set); -+ -+__init int bman_init_early(void) -+{ -+ struct device_node *dn; -+ int ret; -+ -+ for_each_compatible_node(dn, NULL, "fsl,bman") { -+ if (bm) -+ pr_err("%s: only one 'fsl,bman' allowed\n", -+ dn->full_name); -+ else { -+ if (!of_device_is_available(dn)) -+ continue; -+ -+ ret = fsl_bman_init(dn); -+ BUG_ON(ret); -+ } -+ } -+ return 0; -+} -+postcore_initcall_sync(bman_init_early); -+ -+ -+static void log_edata_bits(u32 bit_count) -+{ -+ u32 i, j, mask = 0xffffffff; -+ -+ pr_warn("Bman ErrInt, EDATA:\n"); -+ i = bit_count/32; -+ if (bit_count%32) { -+ i++; -+ mask = ~(mask << bit_count%32); -+ } -+ j = 16-i; -+ pr_warn(" 0x%08x\n", bm_in(EDATA(j)) & mask); -+ j++; -+ for (; j < 16; j++) -+ pr_warn(" 0x%08x\n", bm_in(EDATA(j))); -+} -+ -+static void log_additional_error_info(u32 isr_val, u32 ecsr_val) -+{ -+ union bman_ecir ecir_val; -+ union bman_eadr eadr_val; -+ -+ ecir_val.ecir_raw = bm_in(ECIR); -+ /* Is portal info valid */ -+ if (ecsr_val & PORTAL_ECSR_ERR) { -+ pr_warn("Bman ErrInt: SWP id %d, numb %d, pid %d\n", -+ ecir_val.info.portal_num, ecir_val.info.numb, -+ ecir_val.info.pid); -+ } -+ if (ecsr_val & (BM_EIRQ_SBEI|BM_EIRQ_MBEI)) { -+ eadr_val.eadr_raw = bm_in(EADR); -+ pr_warn("Bman ErrInt: EADR Memory: %s, 0x%x\n", -+ error_mdata[eadr_val.info.memid].txt, -+ error_mdata[eadr_val.info.memid].addr_mask -+ & eadr_val.info.eadr); -+ log_edata_bits(error_mdata[eadr_val.info.memid].bits); -+ } -+} -+ -+/* Bman interrupt handler */ -+static irqreturn_t bman_isr(int irq, void *ptr) -+{ -+ u32 isr_val, ier_val, ecsr_val, isr_mask, i; -+ -+ ier_val = bm_err_isr_enable_read(bm); -+ isr_val = bm_err_isr_status_read(bm); -+ ecsr_val = bm_in(ECSR); -+ isr_mask = isr_val & ier_val; -+ -+ if (!isr_mask) -+ return IRQ_NONE; -+ for (i = 0; i < BMAN_HWE_COUNT; i++) { -+ if (bman_hwerr_txts[i].mask & isr_mask) { -+ pr_warn("Bman ErrInt: %s\n", bman_hwerr_txts[i].txt); -+ if (bman_hwerr_txts[i].mask & ecsr_val) { -+ log_additional_error_info(isr_mask, ecsr_val); -+ /* Re-arm error capture registers */ -+ bm_out(ECSR, ecsr_val); -+ } -+ if (bman_hwerr_txts[i].mask & BMAN_ERRS_TO_UNENABLE) { -+ pr_devel("Bman un-enabling error 0x%x\n", -+ bman_hwerr_txts[i].mask); -+ ier_val &= ~bman_hwerr_txts[i].mask; -+ bm_err_isr_enable_write(bm, ier_val); -+ } -+ } -+ } -+ bm_err_isr_status_clear(bm, isr_val); -+ return IRQ_HANDLED; -+} -+ -+static int __bind_irq(void) -+{ -+ int ret, err_irq; -+ -+ err_irq = of_irq_to_resource(bm_node, 0, NULL); -+ if (err_irq == 0) { -+ pr_info("Can't get %s property '%s'\n", bm_node->full_name, -+ "interrupts"); -+ return -ENODEV; -+ } -+ ret = request_irq(err_irq, bman_isr, IRQF_SHARED, "bman-err", bm_node); -+ if (ret) { -+ pr_err("request_irq() failed %d for '%s'\n", ret, -+ bm_node->full_name); -+ return -ENODEV; -+ } -+ /* Disable Buffer Pool State Change */ -+ bm_err_isr_disable_write(bm, BM_EIRQ_BSCN); -+ /* Write-to-clear any stale bits, (eg. starvation being asserted prior -+ * to resource allocation during driver init). */ -+ bm_err_isr_status_clear(bm, 0xffffffff); -+ /* Enable Error Interrupts */ -+ bm_err_isr_enable_write(bm, 0xffffffff); -+ return 0; -+} -+ -+int bman_init_ccsr(struct device_node *node) -+{ -+ int ret; -+ if (!bman_have_ccsr()) -+ return 0; -+ if (node != bm_node) -+ return -EINVAL; -+ /* FBPR memory */ -+ bm_set_memory(bm, fbpr_a, 0, fbpr_sz); -+ pr_info("bman-fbpr addr %pad size 0x%zx\n", &fbpr_a, fbpr_sz); -+ -+ ret = __bind_irq(); -+ if (ret) -+ return ret; -+ return 0; -+} -+ -+u32 bm_pool_free_buffers(u32 bpid) -+{ -+ return bm_in(POOL_CONTENT(bpid)); -+} -+ -+#ifdef CONFIG_SYSFS -+ -+#define DRV_NAME "fsl-bman" -+#define SBEC_MAX_ID 1 -+#define SBEC_MIN_ID 0 -+ -+static ssize_t show_fbpr_fpc(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(FBPR_FPC)); -+}; -+ -+static ssize_t show_pool_count(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ u32 data; -+ int i; -+ -+ if (!sscanf(dev_attr->attr.name, "%d", &i) || (i >= bman_pool_max)) -+ return -EINVAL; -+ data = bm_in(POOL_CONTENT(i)); -+ return snprintf(buf, PAGE_SIZE, "%d\n", data); -+}; -+ -+static ssize_t show_err_isr(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "0x%08x\n", bm_in(ERR_ISR)); -+}; -+ -+static ssize_t show_sbec(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ int i; -+ -+ if (!sscanf(dev_attr->attr.name, "sbec_%d", &i)) -+ return -EINVAL; -+ if (i < SBEC_MIN_ID || i > SBEC_MAX_ID) -+ return -EINVAL; -+ return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(SBEC(i))); -+}; -+ -+static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL); -+static DEVICE_ATTR(fbpr_fpc, S_IRUSR, show_fbpr_fpc, NULL); -+ -+/* Didn't use DEVICE_ATTR as 64 of this would be required. -+ * Initialize them when needed. */ -+static char *name_attrs_pool_count; /* "xx" + null-terminator */ -+static struct device_attribute *dev_attr_buffer_pool_count; -+ -+static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL); -+ -+static struct attribute *bman_dev_attributes[] = { -+ &dev_attr_fbpr_fpc.attr, -+ &dev_attr_err_isr.attr, -+ NULL -+}; -+ -+static struct attribute *bman_dev_ecr_attributes[] = { -+ &dev_attr_sbec_0.attr, -+ &dev_attr_sbec_1.attr, -+ NULL -+}; -+ -+static struct attribute **bman_dev_pool_count_attributes; -+ -+ -+/* root level */ -+static const struct attribute_group bman_dev_attr_grp = { -+ .name = NULL, -+ .attrs = bman_dev_attributes -+}; -+static const struct attribute_group bman_dev_ecr_grp = { -+ .name = "error_capture", -+ .attrs = bman_dev_ecr_attributes -+}; -+static struct attribute_group bman_dev_pool_countent_grp = { -+ .name = "pool_count", -+}; -+ -+static int of_fsl_bman_remove(struct platform_device *ofdev) -+{ -+ sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp); -+ return 0; -+}; -+ -+static int of_fsl_bman_probe(struct platform_device *ofdev) -+{ -+ int ret, i; -+ -+ ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_attr_grp); -+ if (ret) -+ goto done; -+ ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_ecr_grp); -+ if (ret) -+ goto del_group_0; -+ -+ name_attrs_pool_count = kmalloc(sizeof(char) * bman_pool_max * 3, -+ GFP_KERNEL); -+ if (!name_attrs_pool_count) { -+ pr_err("Can't alloc name_attrs_pool_count\n"); -+ goto del_group_1; -+ } -+ -+ dev_attr_buffer_pool_count = kmalloc(sizeof(struct device_attribute) * -+ bman_pool_max, GFP_KERNEL); -+ if (!dev_attr_buffer_pool_count) { -+ pr_err("Can't alloc dev_attr-buffer_pool_count\n"); -+ goto del_group_2; -+ } -+ -+ bman_dev_pool_count_attributes = kmalloc(sizeof(struct attribute *) * -+ (bman_pool_max + 1), GFP_KERNEL); -+ if (!bman_dev_pool_count_attributes) { -+ pr_err("can't alloc bman_dev_pool_count_attributes\n"); -+ goto del_group_3; -+ } -+ -+ for (i = 0; i < bman_pool_max; i++) { -+ ret = scnprintf((name_attrs_pool_count + i * 3), 3, "%d", i); -+ if (!ret) -+ goto del_group_4; -+ dev_attr_buffer_pool_count[i].attr.name = -+ (name_attrs_pool_count + i * 3); -+ dev_attr_buffer_pool_count[i].attr.mode = S_IRUSR; -+ dev_attr_buffer_pool_count[i].show = show_pool_count; -+ bman_dev_pool_count_attributes[i] = -+ &dev_attr_buffer_pool_count[i].attr; -+ sysfs_attr_init(bman_dev_pool_count_attributes[i]); -+ } -+ bman_dev_pool_count_attributes[bman_pool_max] = NULL; -+ -+ bman_dev_pool_countent_grp.attrs = bman_dev_pool_count_attributes; -+ -+ ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_pool_countent_grp); -+ if (ret) -+ goto del_group_4; -+ -+ goto done; -+ -+del_group_4: -+ kfree(bman_dev_pool_count_attributes); -+del_group_3: -+ kfree(dev_attr_buffer_pool_count); -+del_group_2: -+ kfree(name_attrs_pool_count); -+del_group_1: -+ sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_ecr_grp); -+del_group_0: -+ sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp); -+done: -+ if (ret) -+ dev_err(&ofdev->dev, -+ "Cannot create dev attributes ret=%d\n", ret); -+ return ret; -+}; -+ -+static struct of_device_id of_fsl_bman_ids[] = { -+ { -+ .compatible = "fsl,bman", -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, of_fsl_bman_ids); -+ -+#ifdef CONFIG_SUSPEND -+static u32 saved_isdr; -+ -+static int bman_pm_suspend_noirq(struct device *dev) -+{ -+ uint32_t idle_state; -+ -+ suspend_unused_bportal(); -+ /* save isdr, disable all, clear isr */ -+ saved_isdr = bm_err_isr_disable_read(bm); -+ bm_err_isr_disable_write(bm, 0xffffffff); -+ bm_err_isr_status_clear(bm, 0xffffffff); -+ -+ if (bman_ip_rev < BMAN_REV21) { -+#ifdef CONFIG_PM_DEBUG -+ pr_info("Bman version doesn't have STATE_IDLE\n"); -+#endif -+ return 0; -+ } -+ idle_state = bm_in(STATE_IDLE); -+ if (!(idle_state & 0x1)) { -+ pr_err("Bman not idle 0x%x aborting\n", idle_state); -+ bm_err_isr_disable_write(bm, saved_isdr); -+ resume_unused_bportal(); -+ return -EBUSY; -+ } -+#ifdef CONFIG_PM_DEBUG -+ pr_info("Bman suspend code, IDLE_STAT = 0x%x\n", idle_state); -+#endif -+ return 0; -+} -+ -+static int bman_pm_resume_noirq(struct device *dev) -+{ -+ /* restore isdr */ -+ bm_err_isr_disable_write(bm, saved_isdr); -+ resume_unused_bportal(); -+ return 0; -+} -+#else -+#define bman_pm_suspend_noirq NULL -+#define bman_pm_resume_noirq NULL -+#endif -+ -+static const struct dev_pm_ops bman_pm_ops = { -+ .suspend_noirq = bman_pm_suspend_noirq, -+ .resume_noirq = bman_pm_resume_noirq, -+}; -+ -+static struct platform_driver of_fsl_bman_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = DRV_NAME, -+ .of_match_table = of_fsl_bman_ids, -+ .pm = &bman_pm_ops, -+ }, -+ .probe = of_fsl_bman_probe, -+ .remove = of_fsl_bman_remove, -+}; -+ -+static int bman_ctrl_init(void) -+{ -+ return platform_driver_register(&of_fsl_bman_driver); -+} -+ -+static void bman_ctrl_exit(void) -+{ -+ platform_driver_unregister(&of_fsl_bman_driver); -+} -+ -+module_init(bman_ctrl_init); -+module_exit(bman_ctrl_exit); -+ -+#endif /* CONFIG_SYSFS */ ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_debugfs.c -@@ -0,0 +1,119 @@ -+/* Copyright 2010-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+static struct dentry *dfs_root; /* debugfs root directory */ -+ -+/******************************************************************************* -+ * Query Buffer Pool State -+ ******************************************************************************/ -+static int query_bp_state_show(struct seq_file *file, void *offset) -+{ -+ int ret; -+ struct bm_pool_state state; -+ int i, j; -+ u32 mask; -+ -+ memset(&state, 0, sizeof(struct bm_pool_state)); -+ ret = bman_query_pools(&state); -+ if (ret) { -+ seq_printf(file, "Error %d\n", ret); -+ return 0; -+ } -+ seq_puts(file, "bp_id free_buffers_avail bp_depleted\n"); -+ for (i = 0; i < 2; i++) { -+ mask = 0x80000000; -+ for (j = 0; j < 32; j++) { -+ seq_printf(file, -+ " %-2u %-3s %-3s\n", -+ (i*32)+j, -+ (state.as.state.__state[i] & mask) ? "no" : "yes", -+ (state.ds.state.__state[i] & mask) ? "yes" : "no"); -+ mask >>= 1; -+ } -+ } -+ return 0; -+} -+ -+static int query_bp_state_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, query_bp_state_show, NULL); -+} -+ -+static const struct file_operations query_bp_state_fops = { -+ .owner = THIS_MODULE, -+ .open = query_bp_state_open, -+ .read = seq_read, -+ .release = single_release, -+}; -+ -+static int __init bman_debugfs_module_init(void) -+{ -+ int ret = 0; -+ struct dentry *d; -+ -+ dfs_root = debugfs_create_dir("bman", NULL); -+ -+ if (dfs_root == NULL) { -+ ret = -ENOMEM; -+ pr_err("Cannot create bman debugfs dir\n"); -+ goto _return; -+ } -+ d = debugfs_create_file("query_bp_state", -+ S_IRUGO, -+ dfs_root, -+ NULL, -+ &query_bp_state_fops); -+ if (d == NULL) { -+ ret = -ENOMEM; -+ pr_err("Cannot create query_bp_state\n"); -+ goto _return; -+ } -+ return 0; -+ -+_return: -+ debugfs_remove_recursive(dfs_root); -+ return ret; -+} -+ -+static void __exit bman_debugfs_module_exit(void) -+{ -+ debugfs_remove_recursive(dfs_root); -+} -+ -+ -+module_init(bman_debugfs_module_init); -+module_exit(bman_debugfs_module_exit); -+MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_driver.c -@@ -0,0 +1,559 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+#include "bman_low.h" -+#ifdef CONFIG_HOTPLUG_CPU -+#include -+#endif -+/* -+ * Global variables of the max portal/pool number this bman version supported -+ */ -+u16 bman_ip_rev; -+EXPORT_SYMBOL(bman_ip_rev); -+u16 bman_pool_max; -+EXPORT_SYMBOL(bman_pool_max); -+static u16 bman_portal_max; -+ -+/* After initialising cpus that own shared portal configs, we cache the -+ * resulting portals (ie. not just the configs) in this array. Then we -+ * initialise slave cpus that don't have their own portals, redirecting them to -+ * portals from this cache in a round-robin assignment. */ -+static struct bman_portal *shared_portals[NR_CPUS]; -+static int num_shared_portals; -+static int shared_portals_idx; -+static LIST_HEAD(unused_pcfgs); -+static DEFINE_SPINLOCK(unused_pcfgs_lock); -+static void *affine_bportals[NR_CPUS]; -+ -+static int __init fsl_bpool_init(struct device_node *node) -+{ -+ int ret; -+ u32 *thresh, *bpid = (u32 *)of_get_property(node, "fsl,bpid", &ret); -+ if (!bpid || (ret != 4)) { -+ pr_err("Can't get %s property 'fsl,bpid'\n", node->full_name); -+ return -ENODEV; -+ } -+ thresh = (u32 *)of_get_property(node, "fsl,bpool-thresholds", &ret); -+ if (thresh) { -+ if (ret != 16) { -+ pr_err("Invalid %s property '%s'\n", -+ node->full_name, "fsl,bpool-thresholds"); -+ return -ENODEV; -+ } -+ } -+ if (thresh) { -+#ifdef CONFIG_FSL_BMAN_CONFIG -+ ret = bm_pool_set(be32_to_cpu(*bpid), thresh); -+ if (ret) -+ pr_err("No CCSR node for %s property '%s'\n", -+ node->full_name, "fsl,bpool-thresholds"); -+ return ret; -+#else -+ pr_err("Ignoring %s property '%s', no CCSR support\n", -+ node->full_name, "fsl,bpool-thresholds"); -+#endif -+ } -+ return 0; -+} -+ -+static int __init fsl_bpid_range_init(struct device_node *node) -+{ -+ int ret; -+ u32 *range = (u32 *)of_get_property(node, "fsl,bpid-range", &ret); -+ if (!range) { -+ pr_err("No 'fsl,bpid-range' property in node %s\n", -+ node->full_name); -+ return -EINVAL; -+ } -+ if (ret != 8) { -+ pr_err("'fsl,bpid-range' is not a 2-cell range in node %s\n", -+ node->full_name); -+ return -EINVAL; -+ } -+ bman_seed_bpid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ pr_info("Bman: BPID allocator includes range %d:%d\n", -+ be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ return 0; -+} -+ -+static struct bm_portal_config * __init parse_pcfg(struct device_node *node) -+{ -+ struct bm_portal_config *pcfg; -+ const u32 *index; -+ int irq, ret; -+ resource_size_t len; -+ -+ pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL); -+ if (!pcfg) { -+ pr_err("can't allocate portal config"); -+ return NULL; -+ } -+ -+ if (of_device_is_compatible(node, "fsl,bman-portal-1.0") || -+ of_device_is_compatible(node, "fsl,bman-portal-1.0.0")) { -+ bman_ip_rev = BMAN_REV10; -+ bman_pool_max = 64; -+ bman_portal_max = 10; -+ } else if (of_device_is_compatible(node, "fsl,bman-portal-2.0") || -+ of_device_is_compatible(node, "fsl,bman-portal-2.0.8")) { -+ bman_ip_rev = BMAN_REV20; -+ bman_pool_max = 8; -+ bman_portal_max = 3; -+ } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.0")) { -+ bman_ip_rev = BMAN_REV21; -+ bman_pool_max = 64; -+ bman_portal_max = 50; -+ } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.1")) { -+ bman_ip_rev = BMAN_REV21; -+ bman_pool_max = 64; -+ bman_portal_max = 25; -+ } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.2")) { -+ bman_ip_rev = BMAN_REV21; -+ bman_pool_max = 64; -+ bman_portal_max = 18; -+ } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.3")) { -+ bman_ip_rev = BMAN_REV21; -+ bman_pool_max = 64; -+ bman_portal_max = 10; -+ } else { -+ pr_warn("unknown BMan version in portal node," -+ "default to rev1.0\n"); -+ bman_ip_rev = BMAN_REV10; -+ bman_pool_max = 64; -+ bman_portal_max = 10; -+ } -+ -+ ret = of_address_to_resource(node, DPA_PORTAL_CE, -+ &pcfg->addr_phys[DPA_PORTAL_CE]); -+ if (ret) { -+ pr_err("Can't get %s property 'reg::CE'\n", node->full_name); -+ goto err; -+ } -+ ret = of_address_to_resource(node, DPA_PORTAL_CI, -+ &pcfg->addr_phys[DPA_PORTAL_CI]); -+ if (ret) { -+ pr_err("Can't get %s property 'reg::CI'\n", node->full_name); -+ goto err; -+ } -+ -+ index = of_get_property(node, "cell-index", &ret); -+ if (!index || (ret != 4)) { -+ pr_err("Can't get %s property '%s'\n", node->full_name, -+ "cell-index"); -+ goto err; -+ } -+ if (be32_to_cpu(*index) >= bman_portal_max) { -+ pr_err("BMan portal cell index %d out of range, max %d\n", -+ be32_to_cpu(*index), bman_portal_max); -+ goto err; -+ } -+ -+ pcfg->public_cfg.cpu = -1; -+ -+ irq = irq_of_parse_and_map(node, 0); -+ if (irq == 0) { -+ pr_err("Can't get %s property 'interrupts'\n", node->full_name); -+ goto err; -+ } -+ pcfg->public_cfg.irq = irq; -+ pcfg->public_cfg.index = be32_to_cpu(*index); -+ bman_depletion_fill(&pcfg->public_cfg.mask); -+ -+ len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]); -+ if (len != (unsigned long)len) -+ goto err; -+ -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns( -+ pcfg->addr_phys[DPA_PORTAL_CE].start, -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CE])); -+ pcfg->addr_virt[DPA_PORTAL_CI] = ioremap( -+ pcfg->addr_phys[DPA_PORTAL_CI].start, -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CI])); -+ -+#else -+ pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot( -+ pcfg->addr_phys[DPA_PORTAL_CE].start, -+ (unsigned long)len, -+ 0); -+ pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot( -+ pcfg->addr_phys[DPA_PORTAL_CI].start, -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]), -+ _PAGE_GUARDED | _PAGE_NO_CACHE); -+#endif -+ /* disable bp depletion */ -+ __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(0)); -+ __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(1)); -+ return pcfg; -+err: -+ kfree(pcfg); -+ return NULL; -+} -+ -+static struct bm_portal_config *get_pcfg(struct list_head *list) -+{ -+ struct bm_portal_config *pcfg; -+ if (list_empty(list)) -+ return NULL; -+ pcfg = list_entry(list->prev, struct bm_portal_config, list); -+ list_del(&pcfg->list); -+ return pcfg; -+} -+ -+static struct bm_portal_config *get_pcfg_idx(struct list_head *list, -+ uint32_t idx) -+{ -+ struct bm_portal_config *pcfg; -+ if (list_empty(list)) -+ return NULL; -+ list_for_each_entry(pcfg, list, list) { -+ if (pcfg->public_cfg.index == idx) { -+ list_del(&pcfg->list); -+ return pcfg; -+ } -+ } -+ return NULL; -+} -+ -+struct bm_portal_config *bm_get_unused_portal(void) -+{ -+ return bm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX); -+} -+ -+struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx) -+{ -+ struct bm_portal_config *ret; -+ spin_lock(&unused_pcfgs_lock); -+ if (idx == QBMAN_ANY_PORTAL_IDX) -+ ret = get_pcfg(&unused_pcfgs); -+ else -+ ret = get_pcfg_idx(&unused_pcfgs, idx); -+ spin_unlock(&unused_pcfgs_lock); -+ return ret; -+} -+ -+void bm_put_unused_portal(struct bm_portal_config *pcfg) -+{ -+ spin_lock(&unused_pcfgs_lock); -+ list_add(&pcfg->list, &unused_pcfgs); -+ spin_unlock(&unused_pcfgs_lock); -+} -+ -+static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg) -+{ -+ struct bman_portal *p; -+ p = bman_create_affine_portal(pcfg); -+ if (p) { -+#ifdef CONFIG_FSL_DPA_PIRQ_SLOW -+ bman_p_irqsource_add(p, BM_PIRQ_RCRI | BM_PIRQ_BSCN); -+#endif -+ pr_info("Bman portal %sinitialised, cpu %d\n", -+ pcfg->public_cfg.is_shared ? "(shared) " : "", -+ pcfg->public_cfg.cpu); -+ affine_bportals[pcfg->public_cfg.cpu] = p; -+ } else -+ pr_crit("Bman portal failure on cpu %d\n", -+ pcfg->public_cfg.cpu); -+ return p; -+} -+ -+static void init_slave(int cpu) -+{ -+ struct bman_portal *p; -+ p = bman_create_affine_slave(shared_portals[shared_portals_idx++], cpu); -+ if (!p) -+ pr_err("Bman slave portal failure on cpu %d\n", cpu); -+ else -+ pr_info("Bman portal %sinitialised, cpu %d\n", "(slave) ", cpu); -+ if (shared_portals_idx >= num_shared_portals) -+ shared_portals_idx = 0; -+ affine_bportals[cpu] = p; -+} -+ -+/* Bootarg "bportals=[...]" has the same syntax as "qportals=", and so the -+ * parsing is in dpa_sys.h. The syntax is a comma-separated list of indexes -+ * and/or ranges of indexes, with each being optionally prefixed by "s" to -+ * explicitly mark it or them for sharing. -+ * Eg; -+ * bportals=s0,1-3,s4 -+ * means that cpus 1,2,3 get "unshared" portals, cpus 0 and 4 get "shared" -+ * portals, and any remaining cpus share the portals that are assigned to cpus 0 -+ * or 4, selected in a round-robin fashion. (In this example, cpu 5 would share -+ * cpu 0's portal, cpu 6 would share cpu4's portal, and cpu 7 would share cpu -+ * 0's portal.) */ -+static struct cpumask want_unshared __initdata; /* cpus requested without "s" */ -+static struct cpumask want_shared __initdata; /* cpus requested with "s" */ -+ -+static int __init parse_bportals(char *str) -+{ -+ return parse_portals_bootarg(str, &want_shared, &want_unshared, -+ "bportals"); -+} -+__setup("bportals=", parse_bportals); -+ -+static int bman_offline_cpu(unsigned int cpu) -+{ -+ struct bman_portal *p; -+ const struct bm_portal_config *pcfg; -+ p = (struct bman_portal *)affine_bportals[cpu]; -+ if (p) { -+ pcfg = bman_get_bm_portal_config(p); -+ if (pcfg) -+ irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0)); -+ } -+ return 0; -+} -+ -+#ifdef CONFIG_HOTPLUG_CPU -+static int bman_online_cpu(unsigned int cpu) -+{ -+ struct bman_portal *p; -+ const struct bm_portal_config *pcfg; -+ p = (struct bman_portal *)affine_bportals[cpu]; -+ if (p) { -+ pcfg = bman_get_bm_portal_config(p); -+ if (pcfg) -+ irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu)); -+ } -+ return 0; -+} -+#endif /* CONFIG_HOTPLUG_CPU */ -+ -+/* Initialise the Bman driver. The meat of this function deals with portals. The -+ * following describes the flow of portal-handling, the code "steps" refer to -+ * this description; -+ * 1. Portal configs are parsed from the device-tree into 'unused_pcfgs', with -+ * ::cpu==-1. Regions and interrupts are mapped (but interrupts are not -+ * bound). -+ * 2. The "want_shared" and "want_unshared" lists (as filled by the -+ * "bportals=[...]" bootarg) are processed, allocating portals and assigning -+ * them to cpus, placing them in the relevant list and setting ::cpu as -+ * appropriate. If no "bportals" bootarg was present, the defaut is to try to -+ * assign portals to all online cpus at the time of driver initialisation. -+ * Any failure to allocate portals (when parsing the "want" lists or when -+ * using default behaviour) will be silently tolerated (the "fixup" logic in -+ * step 3 will determine what happens in this case). -+ * 3. Do fixups relative to cpu_online_mask(). If no portals are marked for -+ * sharing and sharing is required (because not all cpus have been assigned -+ * portals), then one portal will marked for sharing. Conversely if no -+ * sharing is required, any portals marked for sharing will not be shared. It -+ * may be that sharing occurs when it wasn't expected, if portal allocation -+ * failed to honour all the requested assignments (including the default -+ * assignments if no bootarg is present). -+ * 4. Unshared portals are initialised on their respective cpus. -+ * 5. Shared portals are initialised on their respective cpus. -+ * 6. Each remaining cpu is initialised to slave to one of the shared portals, -+ * which are selected in a round-robin fashion. -+ * Any portal configs left unused are available for USDPAA allocation. -+ */ -+__init int bman_init(void) -+{ -+ struct cpumask slave_cpus; -+ struct cpumask unshared_cpus = *cpu_none_mask; -+ struct cpumask shared_cpus = *cpu_none_mask; -+ LIST_HEAD(unshared_pcfgs); -+ LIST_HEAD(shared_pcfgs); -+ struct device_node *dn; -+ struct bm_portal_config *pcfg; -+ struct bman_portal *p; -+ int cpu, ret; -+ struct cpumask offline_cpus; -+ -+ /* Initialise the Bman (CCSR) device */ -+ for_each_compatible_node(dn, NULL, "fsl,bman") { -+ if (!bman_init_ccsr(dn)) -+ pr_info("Bman err interrupt handler present\n"); -+ else -+ pr_err("Bman CCSR setup failed\n"); -+ } -+ /* Initialise any declared buffer pools */ -+ for_each_compatible_node(dn, NULL, "fsl,bpool") { -+ ret = fsl_bpool_init(dn); -+ if (ret) -+ return ret; -+ } -+ /* Step 1. See comments at the beginning of the file. */ -+ for_each_compatible_node(dn, NULL, "fsl,bman-portal") { -+ if (!of_device_is_available(dn)) -+ continue; -+ pcfg = parse_pcfg(dn); -+ if (pcfg) -+ list_add_tail(&pcfg->list, &unused_pcfgs); -+ } -+ /* Step 2. */ -+ for_each_possible_cpu(cpu) { -+ if (cpumask_test_cpu(cpu, &want_shared)) { -+ pcfg = get_pcfg(&unused_pcfgs); -+ if (!pcfg) -+ break; -+ pcfg->public_cfg.cpu = cpu; -+ list_add_tail(&pcfg->list, &shared_pcfgs); -+ cpumask_set_cpu(cpu, &shared_cpus); -+ } -+ if (cpumask_test_cpu(cpu, &want_unshared)) { -+ if (cpumask_test_cpu(cpu, &shared_cpus)) -+ continue; -+ pcfg = get_pcfg(&unused_pcfgs); -+ if (!pcfg) -+ break; -+ pcfg->public_cfg.cpu = cpu; -+ list_add_tail(&pcfg->list, &unshared_pcfgs); -+ cpumask_set_cpu(cpu, &unshared_cpus); -+ } -+ } -+ if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) { -+ /* Default, give an unshared portal to each online cpu */ -+ for_each_online_cpu(cpu) { -+ pcfg = get_pcfg(&unused_pcfgs); -+ if (!pcfg) -+ break; -+ pcfg->public_cfg.cpu = cpu; -+ list_add_tail(&pcfg->list, &unshared_pcfgs); -+ cpumask_set_cpu(cpu, &unshared_cpus); -+ } -+ } -+ /* Step 3. */ -+ cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus); -+ cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus); -+ if (cpumask_empty(&slave_cpus)) { -+ /* No sharing required */ -+ if (!list_empty(&shared_pcfgs)) { -+ /* Migrate "shared" to "unshared" */ -+ cpumask_or(&unshared_cpus, &unshared_cpus, -+ &shared_cpus); -+ cpumask_clear(&shared_cpus); -+ list_splice_tail(&shared_pcfgs, &unshared_pcfgs); -+ INIT_LIST_HEAD(&shared_pcfgs); -+ } -+ } else { -+ /* Sharing required */ -+ if (list_empty(&shared_pcfgs)) { -+ /* Migrate one "unshared" to "shared" */ -+ pcfg = get_pcfg(&unshared_pcfgs); -+ if (!pcfg) { -+ pr_crit("No BMan portals available!\n"); -+ return 0; -+ } -+ cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus); -+ cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus); -+ list_add_tail(&pcfg->list, &shared_pcfgs); -+ } -+ } -+ /* Step 4. */ -+ list_for_each_entry(pcfg, &unshared_pcfgs, list) { -+ pcfg->public_cfg.is_shared = 0; -+ p = init_pcfg(pcfg); -+ if (!p) { -+ pr_crit("Unable to initialize bman portal\n"); -+ return 0; -+ } -+ } -+ /* Step 5. */ -+ list_for_each_entry(pcfg, &shared_pcfgs, list) { -+ pcfg->public_cfg.is_shared = 1; -+ p = init_pcfg(pcfg); -+ if (p) -+ shared_portals[num_shared_portals++] = p; -+ } -+ /* Step 6. */ -+ if (!cpumask_empty(&slave_cpus)) -+ for_each_cpu(cpu, &slave_cpus) -+ init_slave(cpu); -+ pr_info("Bman portals initialised\n"); -+ cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask); -+ for_each_cpu(cpu, &offline_cpus) -+ bman_offline_cpu(cpu); -+#ifdef CONFIG_HOTPLUG_CPU -+ ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, -+ "soc/qbman_portal:online", -+ bman_online_cpu, bman_offline_cpu); -+ if (ret < 0) { -+ pr_err("bman: failed to register hotplug callbacks.\n"); -+ return 0; -+ } -+#endif -+ return 0; -+} -+ -+__init int bman_resource_init(void) -+{ -+ struct device_node *dn; -+ int ret; -+ -+ /* Initialise BPID allocation ranges */ -+ for_each_compatible_node(dn, NULL, "fsl,bpid-range") { -+ ret = fsl_bpid_range_init(dn); -+ if (ret) -+ return ret; -+ } -+ return 0; -+} -+ -+#ifdef CONFIG_SUSPEND -+void suspend_unused_bportal(void) -+{ -+ struct bm_portal_config *pcfg; -+ -+ if (list_empty(&unused_pcfgs)) -+ return; -+ -+ list_for_each_entry(pcfg, &unused_pcfgs, list) { -+#ifdef CONFIG_PM_DEBUG -+ pr_info("Need to save bportal %d\n", pcfg->public_cfg.index); -+#endif -+ /* save isdr, disable all via isdr, clear isr */ -+ pcfg->saved_isdr = -+ __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08); -+ __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] + -+ 0xe08); -+ __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] + -+ 0xe00); -+ } -+ return; -+} -+ -+void resume_unused_bportal(void) -+{ -+ struct bm_portal_config *pcfg; -+ -+ if (list_empty(&unused_pcfgs)) -+ return; -+ -+ list_for_each_entry(pcfg, &unused_pcfgs, list) { -+#ifdef CONFIG_PM_DEBUG -+ pr_info("Need to resume bportal %d\n", pcfg->public_cfg.index); -+#endif -+ /* restore isdr */ -+ __raw_writel(pcfg->saved_isdr, -+ pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08); -+ } -+ return; -+} -+#endif ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_high.c -@@ -0,0 +1,1145 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "bman_low.h" -+ -+/* Compilation constants */ -+#define RCR_THRESH 2 /* reread h/w CI when running out of space */ -+#define IRQNAME "BMan portal %d" -+#define MAX_IRQNAME 16 /* big enough for "BMan portal %d" */ -+ -+struct bman_portal { -+ struct bm_portal p; -+ /* 2-element array. pools[0] is mask, pools[1] is snapshot. */ -+ struct bman_depletion *pools; -+ int thresh_set; -+ unsigned long irq_sources; -+ u32 slowpoll; /* only used when interrupts are off */ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ struct bman_pool *rcri_owned; /* only 1 release WAIT_SYNC at a time */ -+#endif -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ raw_spinlock_t sharing_lock; /* only used if is_shared */ -+ int is_shared; -+ struct bman_portal *sharing_redirect; -+#endif -+ /* When the cpu-affine portal is activated, this is non-NULL */ -+ const struct bm_portal_config *config; -+ /* This is needed for power management */ -+ struct platform_device *pdev; -+ /* 64-entry hash-table of pool objects that are tracking depletion -+ * entry/exit (ie. BMAN_POOL_FLAG_DEPLETION). This isn't fast-path, so -+ * we're not fussy about cache-misses and so forth - whereas the above -+ * members should all fit in one cacheline. -+ * BTW, with 64 entries in the hash table and 64 buffer pools to track, -+ * you'll never guess the hash-function ... */ -+ struct bman_pool *cb[64]; -+ char irqname[MAX_IRQNAME]; -+ /* Track if the portal was alloced by the driver */ -+ u8 alloced; -+ /* power management data */ -+ u32 save_isdr; -+}; -+ -+/* For an explanation of the locking, redirection, or affine-portal logic, -+ * please consult the Qman driver for details. This is the same, only simpler -+ * (no fiddly Qman-specific bits.) */ -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+#define PORTAL_IRQ_LOCK(p, irqflags) \ -+ do { \ -+ if ((p)->is_shared) \ -+ raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \ -+ else \ -+ local_irq_save(irqflags); \ -+ } while (0) -+#define PORTAL_IRQ_UNLOCK(p, irqflags) \ -+ do { \ -+ if ((p)->is_shared) \ -+ raw_spin_unlock_irqrestore(&(p)->sharing_lock, \ -+ irqflags); \ -+ else \ -+ local_irq_restore(irqflags); \ -+ } while (0) -+#else -+#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags) -+#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags) -+#endif -+ -+static cpumask_t affine_mask; -+static DEFINE_SPINLOCK(affine_mask_lock); -+static DEFINE_PER_CPU(struct bman_portal, bman_affine_portal); -+static inline struct bman_portal *get_raw_affine_portal(void) -+{ -+ return &get_cpu_var(bman_affine_portal); -+} -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+static inline struct bman_portal *get_affine_portal(void) -+{ -+ struct bman_portal *p = get_raw_affine_portal(); -+ if (p->sharing_redirect) -+ return p->sharing_redirect; -+ return p; -+} -+#else -+#define get_affine_portal() get_raw_affine_portal() -+#endif -+static inline void put_affine_portal(void) -+{ -+ put_cpu_var(bman_affine_portal); -+} -+static inline struct bman_portal *get_poll_portal(void) -+{ -+ return &get_cpu_var(bman_affine_portal); -+} -+#define put_poll_portal() -+ -+/* GOTCHA: this object type refers to a pool, it isn't *the* pool. There may be -+ * more than one such object per Bman buffer pool, eg. if different users of the -+ * pool are operating via different portals. */ -+struct bman_pool { -+ struct bman_pool_params params; -+ /* Used for hash-table admin when using depletion notifications. */ -+ struct bman_portal *portal; -+ struct bman_pool *next; -+ /* stockpile state - NULL unless BMAN_POOL_FLAG_STOCKPILE is set */ -+ struct bm_buffer *sp; -+ unsigned int sp_fill; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ atomic_t in_use; -+#endif -+}; -+ -+/* (De)Registration of depletion notification callbacks */ -+static void depletion_link(struct bman_portal *portal, struct bman_pool *pool) -+{ -+ __maybe_unused unsigned long irqflags; -+ pool->portal = portal; -+ PORTAL_IRQ_LOCK(portal, irqflags); -+ pool->next = portal->cb[pool->params.bpid]; -+ portal->cb[pool->params.bpid] = pool; -+ if (!pool->next) -+ /* First object for that bpid on this portal, enable the BSCN -+ * mask bit. */ -+ bm_isr_bscn_mask(&portal->p, pool->params.bpid, 1); -+ PORTAL_IRQ_UNLOCK(portal, irqflags); -+} -+static void depletion_unlink(struct bman_pool *pool) -+{ -+ struct bman_pool *it, *last = NULL; -+ struct bman_pool **base = &pool->portal->cb[pool->params.bpid]; -+ __maybe_unused unsigned long irqflags; -+ PORTAL_IRQ_LOCK(pool->portal, irqflags); -+ it = *base; /* <-- gotcha, don't do this prior to the irq_save */ -+ while (it != pool) { -+ last = it; -+ it = it->next; -+ } -+ if (!last) -+ *base = pool->next; -+ else -+ last->next = pool->next; -+ if (!last && !pool->next) { -+ /* Last object for that bpid on this portal, disable the BSCN -+ * mask bit. */ -+ bm_isr_bscn_mask(&pool->portal->p, pool->params.bpid, 0); -+ /* And "forget" that we last saw this pool as depleted */ -+ bman_depletion_unset(&pool->portal->pools[1], -+ pool->params.bpid); -+ } -+ PORTAL_IRQ_UNLOCK(pool->portal, irqflags); -+} -+ -+/* In the case that the application's core loop calls qman_poll() and -+ * bman_poll(), we ought to balance how often we incur the overheads of the -+ * slow-path poll. We'll use two decrementer sources. The idle decrementer -+ * constant is used when the last slow-poll detected no work to do, and the busy -+ * decrementer constant when the last slow-poll had work to do. */ -+#define SLOW_POLL_IDLE 1000 -+#define SLOW_POLL_BUSY 10 -+static u32 __poll_portal_slow(struct bman_portal *p, u32 is); -+ -+/* Portal interrupt handler */ -+static irqreturn_t portal_isr(__always_unused int irq, void *ptr) -+{ -+ struct bman_portal *p = ptr; -+ u32 clear = p->irq_sources; -+ u32 is = bm_isr_status_read(&p->p) & p->irq_sources; -+ clear |= __poll_portal_slow(p, is); -+ bm_isr_status_clear(&p->p, clear); -+ return IRQ_HANDLED; -+} -+ -+#ifdef CONFIG_SUSPEND -+static int _bman_portal_suspend_noirq(struct device *dev) -+{ -+ struct bman_portal *p = (struct bman_portal *)dev->platform_data; -+#ifdef CONFIG_PM_DEBUG -+ struct platform_device *pdev = to_platform_device(dev); -+#endif -+ p->save_isdr = bm_isr_disable_read(&p->p); -+ bm_isr_disable_write(&p->p, 0xffffffff); -+ bm_isr_status_clear(&p->p, 0xffffffff); -+#ifdef CONFIG_PM_DEBUG -+ pr_info("Suspend for %s\n", pdev->name); -+#endif -+ return 0; -+} -+ -+static int _bman_portal_resume_noirq(struct device *dev) -+{ -+ struct bman_portal *p = (struct bman_portal *)dev->platform_data; -+ -+ /* restore isdr */ -+ bm_isr_disable_write(&p->p, p->save_isdr); -+ return 0; -+} -+#else -+#define _bman_portal_suspend_noirq NULL -+#define _bman_portal_resume_noirq NULL -+#endif -+ -+struct dev_pm_domain bman_portal_device_pm_domain = { -+ .ops = { -+ USE_PLATFORM_PM_SLEEP_OPS -+ .suspend_noirq = _bman_portal_suspend_noirq, -+ .resume_noirq = _bman_portal_resume_noirq, -+ } -+}; -+ -+struct bman_portal *bman_create_portal( -+ struct bman_portal *portal, -+ const struct bm_portal_config *config) -+{ -+ struct bm_portal *__p; -+ const struct bman_depletion *pools = &config->public_cfg.mask; -+ int ret; -+ u8 bpid = 0; -+ char buf[16]; -+ -+ if (!portal) { -+ portal = kmalloc(sizeof(*portal), GFP_KERNEL); -+ if (!portal) -+ return portal; -+ portal->alloced = 1; -+ } else -+ portal->alloced = 0; -+ -+ __p = &portal->p; -+ -+ /* prep the low-level portal struct with the mapped addresses from the -+ * config, everything that follows depends on it and "config" is more -+ * for (de)reference... */ -+ __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE]; -+ __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI]; -+ if (bm_rcr_init(__p, bm_rcr_pvb, bm_rcr_cce)) { -+ pr_err("Bman RCR initialisation failed\n"); -+ goto fail_rcr; -+ } -+ if (bm_mc_init(__p)) { -+ pr_err("Bman MC initialisation failed\n"); -+ goto fail_mc; -+ } -+ if (bm_isr_init(__p)) { -+ pr_err("Bman ISR initialisation failed\n"); -+ goto fail_isr; -+ } -+ portal->pools = kmalloc(2 * sizeof(*pools), GFP_KERNEL); -+ if (!portal->pools) -+ goto fail_pools; -+ portal->pools[0] = *pools; -+ bman_depletion_init(portal->pools + 1); -+ while (bpid < bman_pool_max) { -+ /* Default to all BPIDs disabled, we enable as required at -+ * run-time. */ -+ bm_isr_bscn_mask(__p, bpid, 0); -+ bpid++; -+ } -+ portal->slowpoll = 0; -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ portal->rcri_owned = NULL; -+#endif -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ raw_spin_lock_init(&portal->sharing_lock); -+ portal->is_shared = config->public_cfg.is_shared; -+ portal->sharing_redirect = NULL; -+#endif -+ sprintf(buf, "bportal-%u", config->public_cfg.index); -+ portal->pdev = platform_device_alloc(buf, -1); -+ if (!portal->pdev) -+ goto fail_devalloc; -+ portal->pdev->dev.pm_domain = &bman_portal_device_pm_domain; -+ portal->pdev->dev.platform_data = portal; -+ ret = platform_device_add(portal->pdev); -+ if (ret) -+ goto fail_devadd; -+ memset(&portal->cb, 0, sizeof(portal->cb)); -+ /* Write-to-clear any stale interrupt status bits */ -+ bm_isr_disable_write(__p, 0xffffffff); -+ portal->irq_sources = 0; -+ bm_isr_enable_write(__p, portal->irq_sources); -+ bm_isr_status_clear(__p, 0xffffffff); -+ snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu); -+ if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname, -+ portal)) { -+ pr_err("request_irq() failed\n"); -+ goto fail_irq; -+ } -+ if ((config->public_cfg.cpu != -1) && -+ irq_can_set_affinity(config->public_cfg.irq) && -+ irq_set_affinity(config->public_cfg.irq, -+ cpumask_of(config->public_cfg.cpu))) { -+ pr_err("irq_set_affinity() failed %s\n", portal->irqname); -+ goto fail_affinity; -+ } -+ -+ /* Need RCR to be empty before continuing */ -+ ret = bm_rcr_get_fill(__p); -+ if (ret) { -+ pr_err("Bman RCR unclean\n"); -+ goto fail_rcr_empty; -+ } -+ /* Success */ -+ portal->config = config; -+ -+ bm_isr_disable_write(__p, 0); -+ bm_isr_uninhibit(__p); -+ return portal; -+fail_rcr_empty: -+fail_affinity: -+ free_irq(config->public_cfg.irq, portal); -+fail_irq: -+ platform_device_del(portal->pdev); -+fail_devadd: -+ platform_device_put(portal->pdev); -+fail_devalloc: -+ kfree(portal->pools); -+fail_pools: -+ bm_isr_finish(__p); -+fail_isr: -+ bm_mc_finish(__p); -+fail_mc: -+ bm_rcr_finish(__p); -+fail_rcr: -+ if (portal->alloced) -+ kfree(portal); -+ return NULL; -+} -+ -+struct bman_portal *bman_create_affine_portal( -+ const struct bm_portal_config *config) -+{ -+ struct bman_portal *portal; -+ -+ portal = &per_cpu(bman_affine_portal, config->public_cfg.cpu); -+ portal = bman_create_portal(portal, config); -+ if (portal) { -+ spin_lock(&affine_mask_lock); -+ cpumask_set_cpu(config->public_cfg.cpu, &affine_mask); -+ spin_unlock(&affine_mask_lock); -+ } -+ return portal; -+} -+ -+ -+struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect, -+ int cpu) -+{ -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ struct bman_portal *p; -+ p = &per_cpu(bman_affine_portal, cpu); -+ BUG_ON(p->config); -+ BUG_ON(p->is_shared); -+ BUG_ON(!redirect->config->public_cfg.is_shared); -+ p->irq_sources = 0; -+ p->sharing_redirect = redirect; -+ return p; -+#else -+ BUG(); -+ return NULL; -+#endif -+} -+ -+void bman_destroy_portal(struct bman_portal *bm) -+{ -+ const struct bm_portal_config *pcfg; -+ pcfg = bm->config; -+ bm_rcr_cce_update(&bm->p); -+ bm_rcr_cce_update(&bm->p); -+ -+ free_irq(pcfg->public_cfg.irq, bm); -+ -+ kfree(bm->pools); -+ bm_isr_finish(&bm->p); -+ bm_mc_finish(&bm->p); -+ bm_rcr_finish(&bm->p); -+ bm->config = NULL; -+ if (bm->alloced) -+ kfree(bm); -+} -+ -+const struct bm_portal_config *bman_destroy_affine_portal(void) -+{ -+ struct bman_portal *bm = get_raw_affine_portal(); -+ const struct bm_portal_config *pcfg; -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (bm->sharing_redirect) { -+ bm->sharing_redirect = NULL; -+ put_affine_portal(); -+ return NULL; -+ } -+ bm->is_shared = 0; -+#endif -+ pcfg = bm->config; -+ bman_destroy_portal(bm); -+ spin_lock(&affine_mask_lock); -+ cpumask_clear_cpu(pcfg->public_cfg.cpu, &affine_mask); -+ spin_unlock(&affine_mask_lock); -+ put_affine_portal(); -+ return pcfg; -+} -+ -+/* When release logic waits on available RCR space, we need a global waitqueue -+ * in the case of "affine" use (as the waits wake on different cpus which means -+ * different portals - so we can't wait on any per-portal waitqueue). */ -+static DECLARE_WAIT_QUEUE_HEAD(affine_queue); -+ -+static u32 __poll_portal_slow(struct bman_portal *p, u32 is) -+{ -+ struct bman_depletion tmp; -+ u32 ret = is; -+ -+ /* There is a gotcha to be aware of. If we do the query before clearing -+ * the status register, we may miss state changes that occur between the -+ * two. If we write to clear the status register before the query, the -+ * cache-enabled query command may overtake the status register write -+ * unless we use a heavyweight sync (which we don't want). Instead, we -+ * write-to-clear the status register then *read it back* before doing -+ * the query, hence the odd while loop with the 'is' accumulation. */ -+ if (is & BM_PIRQ_BSCN) { -+ struct bm_mc_result *mcr; -+ __maybe_unused unsigned long irqflags; -+ unsigned int i, j; -+ u32 __is; -+ bm_isr_status_clear(&p->p, BM_PIRQ_BSCN); -+ while ((__is = bm_isr_status_read(&p->p)) & BM_PIRQ_BSCN) { -+ is |= __is; -+ bm_isr_status_clear(&p->p, BM_PIRQ_BSCN); -+ } -+ is &= ~BM_PIRQ_BSCN; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ bm_mc_start(&p->p); -+ bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY); -+ while (!(mcr = bm_mc_result(&p->p))) -+ cpu_relax(); -+ tmp = mcr->query.ds.state; -+ tmp.__state[0] = be32_to_cpu(tmp.__state[0]); -+ tmp.__state[1] = be32_to_cpu(tmp.__state[1]); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ for (i = 0; i < 2; i++) { -+ int idx = i * 32; -+ /* tmp is a mask of currently-depleted pools. -+ * pools[0] is mask of those we care about. -+ * pools[1] is our previous view (we only want to -+ * be told about changes). */ -+ tmp.__state[i] &= p->pools[0].__state[i]; -+ if (tmp.__state[i] == p->pools[1].__state[i]) -+ /* fast-path, nothing to see, move along */ -+ continue; -+ for (j = 0; j <= 31; j++, idx++) { -+ struct bman_pool *pool = p->cb[idx]; -+ int b4 = bman_depletion_get(&p->pools[1], idx); -+ int af = bman_depletion_get(&tmp, idx); -+ if (b4 == af) -+ continue; -+ while (pool) { -+ pool->params.cb(p, pool, -+ pool->params.cb_ctx, af); -+ pool = pool->next; -+ } -+ } -+ } -+ p->pools[1] = tmp; -+ } -+ -+ if (is & BM_PIRQ_RCRI) { -+ __maybe_unused unsigned long irqflags; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ bm_rcr_cce_update(&p->p); -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ /* If waiting for sync, we only cancel the interrupt threshold -+ * when the ring utilisation hits zero. */ -+ if (p->rcri_owned) { -+ if (!bm_rcr_get_fill(&p->p)) { -+ p->rcri_owned = NULL; -+ bm_rcr_set_ithresh(&p->p, 0); -+ } -+ } else -+#endif -+ bm_rcr_set_ithresh(&p->p, 0); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ wake_up(&affine_queue); -+ bm_isr_status_clear(&p->p, BM_PIRQ_RCRI); -+ is &= ~BM_PIRQ_RCRI; -+ } -+ -+ /* There should be no status register bits left undefined */ -+ DPA_ASSERT(!is); -+ return ret; -+} -+ -+const struct bman_portal_config *bman_get_portal_config(void) -+{ -+ struct bman_portal *p = get_affine_portal(); -+ const struct bman_portal_config *ret = &p->config->public_cfg; -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(bman_get_portal_config); -+ -+u32 bman_irqsource_get(void) -+{ -+ struct bman_portal *p = get_raw_affine_portal(); -+ u32 ret = p->irq_sources & BM_PIRQ_VISIBLE; -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(bman_irqsource_get); -+ -+int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits) -+{ -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (p->sharing_redirect) -+ return -EINVAL; -+ else -+#endif -+ { -+ __maybe_unused unsigned long irqflags; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ set_bits(bits & BM_PIRQ_VISIBLE, &p->irq_sources); -+ bm_isr_enable_write(&p->p, p->irq_sources); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ } -+ return 0; -+} -+EXPORT_SYMBOL(bman_p_irqsource_add); -+ -+int bman_irqsource_add(__maybe_unused u32 bits) -+{ -+ struct bman_portal *p = get_raw_affine_portal(); -+ int ret = 0; -+ ret = bman_p_irqsource_add(p, bits); -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(bman_irqsource_add); -+ -+int bman_irqsource_remove(u32 bits) -+{ -+ struct bman_portal *p = get_raw_affine_portal(); -+ __maybe_unused unsigned long irqflags; -+ u32 ier; -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (p->sharing_redirect) { -+ put_affine_portal(); -+ return -EINVAL; -+ } -+#endif -+ /* Our interrupt handler only processes+clears status register bits that -+ * are in p->irq_sources. As we're trimming that mask, if one of them -+ * were to assert in the status register just before we remove it from -+ * the enable register, there would be an interrupt-storm when we -+ * release the IRQ lock. So we wait for the enable register update to -+ * take effect in h/w (by reading it back) and then clear all other bits -+ * in the status register. Ie. we clear them from ISR once it's certain -+ * IER won't allow them to reassert. */ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ bits &= BM_PIRQ_VISIBLE; -+ clear_bits(bits, &p->irq_sources); -+ bm_isr_enable_write(&p->p, p->irq_sources); -+ ier = bm_isr_enable_read(&p->p); -+ /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a -+ * data-dependency, ie. to protect against re-ordering. */ -+ bm_isr_status_clear(&p->p, ~ier); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return 0; -+} -+EXPORT_SYMBOL(bman_irqsource_remove); -+ -+const cpumask_t *bman_affine_cpus(void) -+{ -+ return &affine_mask; -+} -+EXPORT_SYMBOL(bman_affine_cpus); -+ -+u32 bman_poll_slow(void) -+{ -+ struct bman_portal *p = get_poll_portal(); -+ u32 ret; -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (unlikely(p->sharing_redirect)) -+ ret = (u32)-1; -+ else -+#endif -+ { -+ u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources; -+ ret = __poll_portal_slow(p, is); -+ bm_isr_status_clear(&p->p, ret); -+ } -+ put_poll_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(bman_poll_slow); -+ -+/* Legacy wrapper */ -+void bman_poll(void) -+{ -+ struct bman_portal *p = get_poll_portal(); -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (unlikely(p->sharing_redirect)) -+ goto done; -+#endif -+ if (!(p->slowpoll--)) { -+ u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources; -+ u32 active = __poll_portal_slow(p, is); -+ if (active) -+ p->slowpoll = SLOW_POLL_BUSY; -+ else -+ p->slowpoll = SLOW_POLL_IDLE; -+ } -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+done: -+#endif -+ put_poll_portal(); -+} -+EXPORT_SYMBOL(bman_poll); -+ -+static const u32 zero_thresholds[4] = {0, 0, 0, 0}; -+ -+struct bman_pool *bman_new_pool(const struct bman_pool_params *params) -+{ -+ struct bman_pool *pool = NULL; -+ u32 bpid; -+ -+ if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID) { -+ int ret = bman_alloc_bpid(&bpid); -+ if (ret) -+ return NULL; -+ } else { -+ if (params->bpid >= bman_pool_max) -+ return NULL; -+ bpid = params->bpid; -+ } -+#ifdef CONFIG_FSL_BMAN_CONFIG -+ if (params->flags & BMAN_POOL_FLAG_THRESH) { -+ int ret = bm_pool_set(bpid, params->thresholds); -+ if (ret) -+ goto err; -+ } -+#else -+ if (params->flags & BMAN_POOL_FLAG_THRESH) -+ goto err; -+#endif -+ pool = kmalloc(sizeof(*pool), GFP_KERNEL); -+ if (!pool) -+ goto err; -+ pool->sp = NULL; -+ pool->sp_fill = 0; -+ pool->params = *params; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ atomic_set(&pool->in_use, 1); -+#endif -+ if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID) -+ pool->params.bpid = bpid; -+ if (params->flags & BMAN_POOL_FLAG_STOCKPILE) { -+ pool->sp = kmalloc(sizeof(struct bm_buffer) * BMAN_STOCKPILE_SZ, -+ GFP_KERNEL); -+ if (!pool->sp) -+ goto err; -+ } -+ if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION) { -+ struct bman_portal *p = get_affine_portal(); -+ if (!p->pools || !bman_depletion_get(&p->pools[0], bpid)) { -+ pr_err("Depletion events disabled for bpid %d\n", bpid); -+ goto err; -+ } -+ depletion_link(p, pool); -+ put_affine_portal(); -+ } -+ return pool; -+err: -+#ifdef CONFIG_FSL_BMAN_CONFIG -+ if (params->flags & BMAN_POOL_FLAG_THRESH) -+ bm_pool_set(bpid, zero_thresholds); -+#endif -+ if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID) -+ bman_release_bpid(bpid); -+ if (pool) { -+ kfree(pool->sp); -+ kfree(pool); -+ } -+ return NULL; -+} -+EXPORT_SYMBOL(bman_new_pool); -+ -+void bman_free_pool(struct bman_pool *pool) -+{ -+#ifdef CONFIG_FSL_BMAN_CONFIG -+ if (pool->params.flags & BMAN_POOL_FLAG_THRESH) -+ bm_pool_set(pool->params.bpid, zero_thresholds); -+#endif -+ if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION) -+ depletion_unlink(pool); -+ if (pool->params.flags & BMAN_POOL_FLAG_STOCKPILE) { -+ if (pool->sp_fill) -+ pr_err("Stockpile not flushed, has %u in bpid %u.\n", -+ pool->sp_fill, pool->params.bpid); -+ kfree(pool->sp); -+ pool->sp = NULL; -+ pool->params.flags ^= BMAN_POOL_FLAG_STOCKPILE; -+ } -+ if (pool->params.flags & BMAN_POOL_FLAG_DYNAMIC_BPID) -+ bman_release_bpid(pool->params.bpid); -+ kfree(pool); -+} -+EXPORT_SYMBOL(bman_free_pool); -+ -+const struct bman_pool_params *bman_get_params(const struct bman_pool *pool) -+{ -+ return &pool->params; -+} -+EXPORT_SYMBOL(bman_get_params); -+ -+static noinline void update_rcr_ci(struct bman_portal *p, u8 avail) -+{ -+ if (avail) -+ bm_rcr_cce_prefetch(&p->p); -+ else -+ bm_rcr_cce_update(&p->p); -+} -+ -+int bman_rcr_is_empty(void) -+{ -+ __maybe_unused unsigned long irqflags; -+ struct bman_portal *p = get_affine_portal(); -+ u8 avail; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ update_rcr_ci(p, 0); -+ avail = bm_rcr_get_fill(&p->p); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return avail == 0; -+} -+EXPORT_SYMBOL(bman_rcr_is_empty); -+ -+static inline struct bm_rcr_entry *try_rel_start(struct bman_portal **p, -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ __maybe_unused struct bman_pool *pool, -+#endif -+ __maybe_unused unsigned long *irqflags, -+ __maybe_unused u32 flags) -+{ -+ struct bm_rcr_entry *r; -+ u8 avail; -+ -+ *p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(*p, (*irqflags)); -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) && -+ (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) { -+ if ((*p)->rcri_owned) { -+ PORTAL_IRQ_UNLOCK(*p, (*irqflags)); -+ put_affine_portal(); -+ return NULL; -+ } -+ (*p)->rcri_owned = pool; -+ } -+#endif -+ avail = bm_rcr_get_avail(&(*p)->p); -+ if (avail < 2) -+ update_rcr_ci(*p, avail); -+ r = bm_rcr_start(&(*p)->p); -+ if (unlikely(!r)) { -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) && -+ (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) -+ (*p)->rcri_owned = NULL; -+#endif -+ PORTAL_IRQ_UNLOCK(*p, (*irqflags)); -+ put_affine_portal(); -+ } -+ return r; -+} -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+static noinline struct bm_rcr_entry *__wait_rel_start(struct bman_portal **p, -+ struct bman_pool *pool, -+ __maybe_unused unsigned long *irqflags, -+ u32 flags) -+{ -+ struct bm_rcr_entry *rcr = try_rel_start(p, pool, irqflags, flags); -+ if (!rcr) -+ bm_rcr_set_ithresh(&(*p)->p, 1); -+ return rcr; -+} -+ -+static noinline struct bm_rcr_entry *wait_rel_start(struct bman_portal **p, -+ struct bman_pool *pool, -+ __maybe_unused unsigned long *irqflags, -+ u32 flags) -+{ -+ struct bm_rcr_entry *rcr; -+#ifndef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ pool = NULL; -+#endif -+ if (flags & BMAN_RELEASE_FLAG_WAIT_INT) -+ /* NB: return NULL if signal occurs before completion. Signal -+ * can occur during return. Caller must check for signal */ -+ wait_event_interruptible(affine_queue, -+ (rcr = __wait_rel_start(p, pool, irqflags, flags))); -+ else -+ wait_event(affine_queue, -+ (rcr = __wait_rel_start(p, pool, irqflags, flags))); -+ return rcr; -+} -+#endif -+ -+static inline int __bman_release(struct bman_pool *pool, -+ const struct bm_buffer *bufs, u8 num, u32 flags) -+{ -+ struct bman_portal *p; -+ struct bm_rcr_entry *r; -+ __maybe_unused unsigned long irqflags; -+ u32 i = num - 1; -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & BMAN_RELEASE_FLAG_WAIT) -+ r = wait_rel_start(&p, pool, &irqflags, flags); -+ else -+ r = try_rel_start(&p, pool, &irqflags, flags); -+#else -+ r = try_rel_start(&p, &irqflags, flags); -+#endif -+ if (!r) -+ return -EBUSY; -+ /* We can copy all but the first entry, as this can trigger badness -+ * with the valid-bit. Use the overlay to mask the verb byte. */ -+ r->bufs[0].opaque = -+ ((cpu_to_be64((bufs[0].opaque | -+ ((u64)pool->params.bpid<<48)) -+ & 0x00ffffffffffffff))); -+ if (i) { -+ for (i = 1; i < num; i++) -+ r->bufs[i].opaque = -+ cpu_to_be64(bufs[i].opaque); -+ } -+ -+ bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE | -+ (num & BM_RCR_VERB_BUFCOUNT_MASK)); -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ /* if we wish to sync we need to set the threshold after h/w sees the -+ * new ring entry. As we're mixing cache-enabled and cache-inhibited -+ * accesses, this requires a heavy-weight sync. */ -+ if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) && -+ (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) { -+ hwsync(); -+ bm_rcr_set_ithresh(&p->p, 1); -+ } -+#endif -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) && -+ (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) { -+ if (flags & BMAN_RELEASE_FLAG_WAIT_INT) -+ /* NB: return success even if signal occurs before -+ * condition is true. pvb_commit guarantees success */ -+ wait_event_interruptible(affine_queue, -+ (p->rcri_owned != pool)); -+ else -+ wait_event(affine_queue, (p->rcri_owned != pool)); -+ } -+#endif -+ return 0; -+} -+ -+int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num, -+ u32 flags) -+{ -+ int ret; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (!num || (num > 8)) -+ return -EINVAL; -+ if (pool->params.flags & BMAN_POOL_FLAG_NO_RELEASE) -+ return -EINVAL; -+#endif -+ /* Without stockpile, this API is a pass-through to the h/w operation */ -+ if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE)) -+ return __bman_release(pool, bufs, num, flags); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (!atomic_dec_and_test(&pool->in_use)) { -+ pr_crit("Parallel attempts to enter bman_released() detected."); -+ panic("only one instance of bman_released/acquired allowed"); -+ } -+#endif -+ /* Two movements of buffers are possible, and can occur in either order. -+ * A: moving buffers from the caller to the stockpile. -+ * B: moving buffers from the stockpile to hardware. -+ * Order 1: if there is already enough space in the stockpile for A -+ * then we want to do A first, and only do B if we trigger the -+ * stockpile-high threshold. -+ * Order 2: if there is not enough space in the stockpile for A, then -+ * we want to do B first, then do A if B had succeeded. However in this -+ * case B is dependent on how many buffers the user needs to release, -+ * not the stockpile-high threshold. -+ * Due to the different handling of B between the two cases, putting A -+ * and B in a while() loop would require quite obscure logic, so handle -+ * the different sequences explicitly. */ -+ if ((pool->sp_fill + num) <= BMAN_STOCKPILE_SZ) { -+ /* Order 1: do A */ -+ copy_words(pool->sp + pool->sp_fill, bufs, -+ sizeof(struct bm_buffer) * num); -+ pool->sp_fill += num; -+ /* do B relative to STOCKPILE_HIGH */ -+ while (pool->sp_fill >= BMAN_STOCKPILE_HIGH) { -+ ret = __bman_release(pool, -+ pool->sp + (pool->sp_fill - 8), 8, -+ flags); -+ if (ret >= 0) -+ pool->sp_fill -= 8; -+ } -+ } else { -+ /* Order 2: do B relative to 'num' */ -+ do { -+ ret = __bman_release(pool, -+ pool->sp + (pool->sp_fill - 8), 8, -+ flags); -+ if (ret < 0) -+ /* failure */ -+ goto release_done; -+ pool->sp_fill -= 8; -+ } while ((pool->sp_fill + num) > BMAN_STOCKPILE_SZ); -+ /* do A */ -+ copy_words(pool->sp + pool->sp_fill, bufs, -+ sizeof(struct bm_buffer) * num); -+ pool->sp_fill += num; -+ } -+ /* success */ -+ ret = 0; -+release_done: -+#ifdef CONFIG_FSL_DPA_CHECKING -+ atomic_inc(&pool->in_use); -+#endif -+ return ret; -+} -+EXPORT_SYMBOL(bman_release); -+ -+static inline int __bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, -+ u8 num) -+{ -+ struct bman_portal *p = get_affine_portal(); -+ struct bm_mc_command *mcc; -+ struct bm_mc_result *mcr; -+ __maybe_unused unsigned long irqflags; -+ int ret, i; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ mcc = bm_mc_start(&p->p); -+ mcc->acquire.bpid = pool->params.bpid; -+ bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE | -+ (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT)); -+ while (!(mcr = bm_mc_result(&p->p))) -+ cpu_relax(); -+ ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT; -+ if (bufs) { -+ for (i = 0; i < num; i++) -+ bufs[i].opaque = -+ be64_to_cpu(mcr->acquire.bufs[i].opaque); -+ } -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ if (ret != num) -+ ret = -ENOMEM; -+ return ret; -+} -+ -+int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num, -+ u32 flags) -+{ -+ int ret; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (!num || (num > 8)) -+ return -EINVAL; -+ if (pool->params.flags & BMAN_POOL_FLAG_ONLY_RELEASE) -+ return -EINVAL; -+#endif -+ /* Without stockpile, this API is a pass-through to the h/w operation */ -+ if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE)) -+ return __bman_acquire(pool, bufs, num); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (!atomic_dec_and_test(&pool->in_use)) { -+ pr_crit("Parallel attempts to enter bman_acquire() detected."); -+ panic("only one instance of bman_released/acquired allowed"); -+ } -+#endif -+ /* Two movements of buffers are possible, and can occur in either order. -+ * A: moving buffers from stockpile to the caller. -+ * B: moving buffers from hardware to the stockpile. -+ * Order 1: if there are already enough buffers in the stockpile for A -+ * then we want to do A first, and only do B if we trigger the -+ * stockpile-low threshold. -+ * Order 2: if there are not enough buffers in the stockpile for A, -+ * then we want to do B first, then do A if B had succeeded. However in -+ * this case B is dependent on how many buffers the user needs, not the -+ * stockpile-low threshold. -+ * Due to the different handling of B between the two cases, putting A -+ * and B in a while() loop would require quite obscure logic, so handle -+ * the different sequences explicitly. */ -+ if (num <= pool->sp_fill) { -+ /* Order 1: do A */ -+ copy_words(bufs, pool->sp + (pool->sp_fill - num), -+ sizeof(struct bm_buffer) * num); -+ pool->sp_fill -= num; -+ /* do B relative to STOCKPILE_LOW */ -+ while (pool->sp_fill <= BMAN_STOCKPILE_LOW) { -+ ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8); -+ if (ret < 0) -+ ret = __bman_acquire(pool, -+ pool->sp + pool->sp_fill, 1); -+ if (ret < 0) -+ break; -+ pool->sp_fill += ret; -+ } -+ } else { -+ /* Order 2: do B relative to 'num' */ -+ do { -+ ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8); -+ if (ret < 0) -+ ret = __bman_acquire(pool, -+ pool->sp + pool->sp_fill, 1); -+ if (ret < 0) -+ /* failure */ -+ goto acquire_done; -+ pool->sp_fill += ret; -+ } while (pool->sp_fill < num); -+ /* do A */ -+ copy_words(bufs, pool->sp + (pool->sp_fill - num), -+ sizeof(struct bm_buffer) * num); -+ pool->sp_fill -= num; -+ } -+ /* success */ -+ ret = num; -+acquire_done: -+#ifdef CONFIG_FSL_DPA_CHECKING -+ atomic_inc(&pool->in_use); -+#endif -+ return ret; -+} -+EXPORT_SYMBOL(bman_acquire); -+ -+int bman_flush_stockpile(struct bman_pool *pool, u32 flags) -+{ -+ u8 num; -+ int ret; -+ -+ while (pool->sp_fill) { -+ num = ((pool->sp_fill > 8) ? 8 : pool->sp_fill); -+ ret = __bman_release(pool, pool->sp + (pool->sp_fill - num), -+ num, flags); -+ if (ret) -+ return ret; -+ pool->sp_fill -= num; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(bman_flush_stockpile); -+ -+int bman_query_pools(struct bm_pool_state *state) -+{ -+ struct bman_portal *p = get_affine_portal(); -+ struct bm_mc_result *mcr; -+ __maybe_unused unsigned long irqflags; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ bm_mc_start(&p->p); -+ bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY); -+ while (!(mcr = bm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & BM_MCR_VERB_CMD_MASK) == BM_MCR_VERB_CMD_QUERY); -+ *state = mcr->query; -+ state->as.state.__state[0] = be32_to_cpu(state->as.state.__state[0]); -+ state->as.state.__state[1] = be32_to_cpu(state->as.state.__state[1]); -+ state->ds.state.__state[0] = be32_to_cpu(state->ds.state.__state[0]); -+ state->ds.state.__state[1] = be32_to_cpu(state->ds.state.__state[1]); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return 0; -+} -+EXPORT_SYMBOL(bman_query_pools); -+ -+#ifdef CONFIG_FSL_BMAN_CONFIG -+u32 bman_query_free_buffers(struct bman_pool *pool) -+{ -+ return bm_pool_free_buffers(pool->params.bpid); -+} -+EXPORT_SYMBOL(bman_query_free_buffers); -+ -+int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds) -+{ -+ u32 bpid; -+ -+ bpid = bman_get_params(pool)->bpid; -+ -+ return bm_pool_set(bpid, thresholds); -+} -+EXPORT_SYMBOL(bman_update_pool_thresholds); -+#endif -+ -+int bman_shutdown_pool(u32 bpid) -+{ -+ struct bman_portal *p = get_affine_portal(); -+ __maybe_unused unsigned long irqflags; -+ int ret; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ ret = bm_shutdown_pool(&p->p, bpid); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(bman_shutdown_pool); -+ -+const struct bm_portal_config *bman_get_bm_portal_config( -+ struct bman_portal *portal) -+{ -+ return portal->sharing_redirect ? NULL : portal->config; -+} ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_low.h -@@ -0,0 +1,565 @@ -+/* Copyright 2008-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "bman_private.h" -+ -+/***************************/ -+/* Portal register assists */ -+/***************************/ -+ -+#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64) -+ -+/* Cache-inhibited register offsets */ -+#define BM_REG_RCR_PI_CINH 0x0000 -+#define BM_REG_RCR_CI_CINH 0x0004 -+#define BM_REG_RCR_ITR 0x0008 -+#define BM_REG_CFG 0x0100 -+#define BM_REG_SCN(n) (0x0200 + ((n) << 2)) -+#define BM_REG_ISR 0x0e00 -+#define BM_REG_IIR 0x0e0c -+ -+/* Cache-enabled register offsets */ -+#define BM_CL_CR 0x0000 -+#define BM_CL_RR0 0x0100 -+#define BM_CL_RR1 0x0140 -+#define BM_CL_RCR 0x1000 -+#define BM_CL_RCR_PI_CENA 0x3000 -+#define BM_CL_RCR_CI_CENA 0x3100 -+ -+#endif -+ -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ -+/* Cache-inhibited register offsets */ -+#define BM_REG_RCR_PI_CINH 0x3000 -+#define BM_REG_RCR_CI_CINH 0x3100 -+#define BM_REG_RCR_ITR 0x3200 -+#define BM_REG_CFG 0x3300 -+#define BM_REG_SCN(n) (0x3400 + ((n) << 6)) -+#define BM_REG_ISR 0x3e00 -+#define BM_REG_IIR 0x3ec0 -+ -+/* Cache-enabled register offsets */ -+#define BM_CL_CR 0x0000 -+#define BM_CL_RR0 0x0100 -+#define BM_CL_RR1 0x0140 -+#define BM_CL_RCR 0x1000 -+#define BM_CL_RCR_PI_CENA 0x3000 -+#define BM_CL_RCR_CI_CENA 0x3100 -+ -+#endif -+ -+/* BTW, the drivers (and h/w programming model) already obtain the required -+ * synchronisation for portal accesses via lwsync(), hwsync(), and -+ * data-dependencies. Use of barrier()s or other order-preserving primitives -+ * simply degrade performance. Hence the use of the __raw_*() interfaces, which -+ * simply ensure that the compiler treats the portal registers as volatile (ie. -+ * non-coherent). */ -+ -+/* Cache-inhibited register access. */ -+#define __bm_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ci + (o))) -+#define __bm_out(bm, o, val) __raw_writel(cpu_to_be32(val), \ -+ (bm)->addr_ci + (o)); -+#define bm_in(reg) __bm_in(&portal->addr, BM_REG_##reg) -+#define bm_out(reg, val) __bm_out(&portal->addr, BM_REG_##reg, val) -+ -+/* Cache-enabled (index) register access */ -+#define __bm_cl_touch_ro(bm, o) dcbt_ro((bm)->addr_ce + (o)) -+#define __bm_cl_touch_rw(bm, o) dcbt_rw((bm)->addr_ce + (o)) -+#define __bm_cl_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ce + (o))) -+#define __bm_cl_out(bm, o, val) \ -+ do { \ -+ u32 *__tmpclout = (bm)->addr_ce + (o); \ -+ __raw_writel(cpu_to_be32(val), __tmpclout); \ -+ dcbf(__tmpclout); \ -+ } while (0) -+#define __bm_cl_invalidate(bm, o) dcbi((bm)->addr_ce + (o)) -+#define bm_cl_touch_ro(reg) __bm_cl_touch_ro(&portal->addr, BM_CL_##reg##_CENA) -+#define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, BM_CL_##reg##_CENA) -+#define bm_cl_in(reg) __bm_cl_in(&portal->addr, BM_CL_##reg##_CENA) -+#define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, BM_CL_##reg##_CENA, val) -+#define bm_cl_invalidate(reg)\ -+ __bm_cl_invalidate(&portal->addr, BM_CL_##reg##_CENA) -+ -+/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf -+ * analysis, look at using the "extra" bit in the ring index registers to avoid -+ * cyclic issues. */ -+static inline u8 bm_cyc_diff(u8 ringsize, u8 first, u8 last) -+{ -+ /* 'first' is included, 'last' is excluded */ -+ if (first <= last) -+ return last - first; -+ return ringsize + last - first; -+} -+ -+/* Portal modes. -+ * Enum types; -+ * pmode == production mode -+ * cmode == consumption mode, -+ * Enum values use 3 letter codes. First letter matches the portal mode, -+ * remaining two letters indicate; -+ * ci == cache-inhibited portal register -+ * ce == cache-enabled portal register -+ * vb == in-band valid-bit (cache-enabled) -+ */ -+enum bm_rcr_pmode { /* matches BCSP_CFG::RPM */ -+ bm_rcr_pci = 0, /* PI index, cache-inhibited */ -+ bm_rcr_pce = 1, /* PI index, cache-enabled */ -+ bm_rcr_pvb = 2 /* valid-bit */ -+}; -+enum bm_rcr_cmode { /* s/w-only */ -+ bm_rcr_cci, /* CI index, cache-inhibited */ -+ bm_rcr_cce /* CI index, cache-enabled */ -+}; -+ -+ -+/* ------------------------- */ -+/* --- Portal structures --- */ -+ -+#define BM_RCR_SIZE 8 -+ -+struct bm_rcr { -+ struct bm_rcr_entry *ring, *cursor; -+ u8 ci, available, ithresh, vbit; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ u32 busy; -+ enum bm_rcr_pmode pmode; -+ enum bm_rcr_cmode cmode; -+#endif -+}; -+ -+struct bm_mc { -+ struct bm_mc_command *cr; -+ struct bm_mc_result *rr; -+ u8 rridx, vbit; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ enum { -+ /* Can only be _mc_start()ed */ -+ mc_idle, -+ /* Can only be _mc_commit()ed or _mc_abort()ed */ -+ mc_user, -+ /* Can only be _mc_retry()ed */ -+ mc_hw -+ } state; -+#endif -+}; -+ -+struct bm_addr { -+ void __iomem *addr_ce; /* cache-enabled */ -+ void __iomem *addr_ci; /* cache-inhibited */ -+}; -+ -+struct bm_portal { -+ struct bm_addr addr; -+ struct bm_rcr rcr; -+ struct bm_mc mc; -+ struct bm_portal_config config; -+} ____cacheline_aligned; -+ -+ -+/* --------------- */ -+/* --- RCR API --- */ -+ -+/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */ -+#define RCR_CARRYCLEAR(p) \ -+ (void *)((unsigned long)(p) & (~(unsigned long)(BM_RCR_SIZE << 6))) -+ -+/* Bit-wise logic to convert a ring pointer to a ring index */ -+static inline u8 RCR_PTR2IDX(struct bm_rcr_entry *e) -+{ -+ return ((uintptr_t)e >> 6) & (BM_RCR_SIZE - 1); -+} -+ -+/* Increment the 'cursor' ring pointer, taking 'vbit' into account */ -+static inline void RCR_INC(struct bm_rcr *rcr) -+{ -+ /* NB: this is odd-looking, but experiments show that it generates -+ * fast code with essentially no branching overheads. We increment to -+ * the next RCR pointer and handle overflow and 'vbit'. */ -+ struct bm_rcr_entry *partial = rcr->cursor + 1; -+ rcr->cursor = RCR_CARRYCLEAR(partial); -+ if (partial != rcr->cursor) -+ rcr->vbit ^= BM_RCR_VERB_VBIT; -+} -+ -+static inline int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode, -+ __maybe_unused enum bm_rcr_cmode cmode) -+{ -+ /* This use of 'register', as well as all other occurrences, is because -+ * it has been observed to generate much faster code with gcc than is -+ * otherwise the case. */ -+ register struct bm_rcr *rcr = &portal->rcr; -+ u32 cfg; -+ u8 pi; -+ -+ rcr->ring = portal->addr.addr_ce + BM_CL_RCR; -+ rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1); -+ -+ pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1); -+ rcr->cursor = rcr->ring + pi; -+ rcr->vbit = (bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0; -+ rcr->available = BM_RCR_SIZE - 1 -+ - bm_cyc_diff(BM_RCR_SIZE, rcr->ci, pi); -+ rcr->ithresh = bm_in(RCR_ITR); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ rcr->busy = 0; -+ rcr->pmode = pmode; -+ rcr->cmode = cmode; -+#endif -+ cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */ -+ bm_out(CFG, cfg); -+ return 0; -+} -+ -+static inline void bm_rcr_finish(struct bm_portal *portal) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1); -+ u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1); -+ DPA_ASSERT(!rcr->busy); -+ if (pi != RCR_PTR2IDX(rcr->cursor)) -+ pr_crit("losing uncommited RCR entries\n"); -+ if (ci != rcr->ci) -+ pr_crit("missing existing RCR completions\n"); -+ if (rcr->ci != RCR_PTR2IDX(rcr->cursor)) -+ pr_crit("RCR destroyed unquiesced\n"); -+} -+ -+static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ DPA_ASSERT(!rcr->busy); -+ if (!rcr->available) -+ return NULL; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ rcr->busy = 1; -+#endif -+#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64) -+ dcbz_64(rcr->cursor); -+#endif -+ return rcr->cursor; -+} -+ -+static inline void bm_rcr_abort(struct bm_portal *portal) -+{ -+ __maybe_unused register struct bm_rcr *rcr = &portal->rcr; -+ DPA_ASSERT(rcr->busy); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ rcr->busy = 0; -+#endif -+} -+ -+static inline struct bm_rcr_entry *bm_rcr_pend_and_next( -+ struct bm_portal *portal, u8 myverb) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ DPA_ASSERT(rcr->busy); -+ DPA_ASSERT(rcr->pmode != bm_rcr_pvb); -+ if (rcr->available == 1) -+ return NULL; -+ rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit; -+ dcbf_64(rcr->cursor); -+ RCR_INC(rcr); -+ rcr->available--; -+#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64) -+ dcbz_64(rcr->cursor); -+#endif -+ return rcr->cursor; -+} -+ -+static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ DPA_ASSERT(rcr->busy); -+ DPA_ASSERT(rcr->pmode == bm_rcr_pci); -+ rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit; -+ RCR_INC(rcr); -+ rcr->available--; -+ hwsync(); -+ bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor)); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ rcr->busy = 0; -+#endif -+} -+ -+static inline void bm_rcr_pce_prefetch(struct bm_portal *portal) -+{ -+ __maybe_unused register struct bm_rcr *rcr = &portal->rcr; -+ DPA_ASSERT(rcr->pmode == bm_rcr_pce); -+ bm_cl_invalidate(RCR_PI); -+ bm_cl_touch_rw(RCR_PI); -+} -+ -+static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ DPA_ASSERT(rcr->busy); -+ DPA_ASSERT(rcr->pmode == bm_rcr_pce); -+ rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit; -+ RCR_INC(rcr); -+ rcr->available--; -+ lwsync(); -+ bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor)); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ rcr->busy = 0; -+#endif -+} -+ -+static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ struct bm_rcr_entry *rcursor; -+ DPA_ASSERT(rcr->busy); -+ DPA_ASSERT(rcr->pmode == bm_rcr_pvb); -+ lwsync(); -+ rcursor = rcr->cursor; -+ rcursor->__dont_write_directly__verb = myverb | rcr->vbit; -+ dcbf_64(rcursor); -+ RCR_INC(rcr); -+ rcr->available--; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ rcr->busy = 0; -+#endif -+} -+ -+static inline u8 bm_rcr_cci_update(struct bm_portal *portal) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ u8 diff, old_ci = rcr->ci; -+ DPA_ASSERT(rcr->cmode == bm_rcr_cci); -+ rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1); -+ diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci); -+ rcr->available += diff; -+ return diff; -+} -+ -+static inline void bm_rcr_cce_prefetch(struct bm_portal *portal) -+{ -+ __maybe_unused register struct bm_rcr *rcr = &portal->rcr; -+ DPA_ASSERT(rcr->cmode == bm_rcr_cce); -+ bm_cl_touch_ro(RCR_CI); -+} -+ -+static inline u8 bm_rcr_cce_update(struct bm_portal *portal) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ u8 diff, old_ci = rcr->ci; -+ DPA_ASSERT(rcr->cmode == bm_rcr_cce); -+ rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1); -+ bm_cl_invalidate(RCR_CI); -+ diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci); -+ rcr->available += diff; -+ return diff; -+} -+ -+static inline u8 bm_rcr_get_ithresh(struct bm_portal *portal) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ return rcr->ithresh; -+} -+ -+static inline void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ rcr->ithresh = ithresh; -+ bm_out(RCR_ITR, ithresh); -+} -+ -+static inline u8 bm_rcr_get_avail(struct bm_portal *portal) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ return rcr->available; -+} -+ -+static inline u8 bm_rcr_get_fill(struct bm_portal *portal) -+{ -+ register struct bm_rcr *rcr = &portal->rcr; -+ return BM_RCR_SIZE - 1 - rcr->available; -+} -+ -+ -+/* ------------------------------ */ -+/* --- Management command API --- */ -+ -+static inline int bm_mc_init(struct bm_portal *portal) -+{ -+ register struct bm_mc *mc = &portal->mc; -+ mc->cr = portal->addr.addr_ce + BM_CL_CR; -+ mc->rr = portal->addr.addr_ce + BM_CL_RR0; -+ mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) & -+ BM_MCC_VERB_VBIT) ? 0 : 1; -+ mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = mc_idle; -+#endif -+ return 0; -+} -+ -+static inline void bm_mc_finish(struct bm_portal *portal) -+{ -+ __maybe_unused register struct bm_mc *mc = &portal->mc; -+ DPA_ASSERT(mc->state == mc_idle); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (mc->state != mc_idle) -+ pr_crit("Losing incomplete MC command\n"); -+#endif -+} -+ -+static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal) -+{ -+ register struct bm_mc *mc = &portal->mc; -+ DPA_ASSERT(mc->state == mc_idle); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = mc_user; -+#endif -+#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64) -+ dcbz_64(mc->cr); -+#endif -+ return mc->cr; -+} -+ -+static inline void bm_mc_abort(struct bm_portal *portal) -+{ -+ __maybe_unused register struct bm_mc *mc = &portal->mc; -+ DPA_ASSERT(mc->state == mc_user); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = mc_idle; -+#endif -+} -+ -+static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb) -+{ -+ register struct bm_mc *mc = &portal->mc; -+ struct bm_mc_result *rr = mc->rr + mc->rridx; -+ DPA_ASSERT(mc->state == mc_user); -+ lwsync(); -+ mc->cr->__dont_write_directly__verb = myverb | mc->vbit; -+ dcbf(mc->cr); -+ dcbit_ro(rr); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = mc_hw; -+#endif -+} -+ -+static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal) -+{ -+ register struct bm_mc *mc = &portal->mc; -+ struct bm_mc_result *rr = mc->rr + mc->rridx; -+ DPA_ASSERT(mc->state == mc_hw); -+ /* The inactive response register's verb byte always returns zero until -+ * its command is submitted and completed. This includes the valid-bit, -+ * in case you were wondering... */ -+ if (!__raw_readb(&rr->verb)) { -+ dcbit_ro(rr); -+ return NULL; -+ } -+ mc->rridx ^= 1; -+ mc->vbit ^= BM_MCC_VERB_VBIT; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = mc_idle; -+#endif -+ return rr; -+} -+ -+ -+/* ------------------------------------- */ -+/* --- Portal interrupt register API --- */ -+ -+static inline int bm_isr_init(__always_unused struct bm_portal *portal) -+{ -+ return 0; -+} -+ -+static inline void bm_isr_finish(__always_unused struct bm_portal *portal) -+{ -+} -+ -+#define SCN_REG(bpid) BM_REG_SCN((bpid) / 32) -+#define SCN_BIT(bpid) (0x80000000 >> (bpid & 31)) -+static inline void bm_isr_bscn_mask(struct bm_portal *portal, u8 bpid, -+ int enable) -+{ -+ u32 val; -+ DPA_ASSERT(bpid < bman_pool_max); -+ /* REG_SCN for bpid=0..31, REG_SCN+4 for bpid=32..63 */ -+ val = __bm_in(&portal->addr, SCN_REG(bpid)); -+ if (enable) -+ val |= SCN_BIT(bpid); -+ else -+ val &= ~SCN_BIT(bpid); -+ __bm_out(&portal->addr, SCN_REG(bpid), val); -+} -+ -+static inline u32 __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n) -+{ -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ return __bm_in(&portal->addr, BM_REG_ISR + (n << 6)); -+#else -+ return __bm_in(&portal->addr, BM_REG_ISR + (n << 2)); -+#endif -+} -+ -+static inline void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n, -+ u32 val) -+{ -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ __bm_out(&portal->addr, BM_REG_ISR + (n << 6), val); -+#else -+ __bm_out(&portal->addr, BM_REG_ISR + (n << 2), val); -+#endif -+} -+ -+/* Buffer Pool Cleanup */ -+static inline int bm_shutdown_pool(struct bm_portal *p, u32 bpid) -+{ -+ struct bm_mc_command *bm_cmd; -+ struct bm_mc_result *bm_res; -+ -+ int aq_count = 0; -+ bool stop = false; -+ while (!stop) { -+ /* Acquire buffers until empty */ -+ bm_cmd = bm_mc_start(p); -+ bm_cmd->acquire.bpid = bpid; -+ bm_mc_commit(p, BM_MCC_VERB_CMD_ACQUIRE | 1); -+ while (!(bm_res = bm_mc_result(p))) -+ cpu_relax(); -+ if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) { -+ /* Pool is empty */ -+ /* TBD : Should we do a few extra iterations in -+ case some other some blocks keep buffers 'on deck', -+ which may also be problematic */ -+ stop = true; -+ } else -+ ++aq_count; -+ } -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_private.h -@@ -0,0 +1,166 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "dpa_sys.h" -+#include -+ -+/* Revision info (for errata and feature handling) */ -+#define BMAN_REV10 0x0100 -+#define BMAN_REV20 0x0200 -+#define BMAN_REV21 0x0201 -+#define QBMAN_ANY_PORTAL_IDX 0xffffffff -+extern u16 bman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */ -+ -+/* -+ * Global variables of the max portal/pool number this bman version supported -+ */ -+extern u16 bman_pool_max; -+ -+/* used by CCSR and portal interrupt code */ -+enum bm_isr_reg { -+ bm_isr_status = 0, -+ bm_isr_enable = 1, -+ bm_isr_disable = 2, -+ bm_isr_inhibit = 3 -+}; -+ -+struct bm_portal_config { -+ /* Corenet portal addresses; -+ * [0]==cache-enabled, [1]==cache-inhibited. */ -+ __iomem void *addr_virt[2]; -+ struct resource addr_phys[2]; -+ /* Allow these to be joined in lists */ -+ struct list_head list; -+ /* User-visible portal configuration settings */ -+ struct bman_portal_config public_cfg; -+ /* power management saved data */ -+ u32 saved_isdr; -+}; -+ -+#ifdef CONFIG_FSL_BMAN_CONFIG -+/* Hooks from bman_driver.c to bman_config.c */ -+int bman_init_ccsr(struct device_node *node); -+#endif -+ -+/* Hooks from bman_driver.c in to bman_high.c */ -+struct bman_portal *bman_create_portal( -+ struct bman_portal *portal, -+ const struct bm_portal_config *config); -+struct bman_portal *bman_create_affine_portal( -+ const struct bm_portal_config *config); -+struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect, -+ int cpu); -+void bman_destroy_portal(struct bman_portal *bm); -+ -+const struct bm_portal_config *bman_destroy_affine_portal(void); -+ -+/* Hooks from fsl_usdpaa.c to bman_driver.c */ -+struct bm_portal_config *bm_get_unused_portal(void); -+struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx); -+void bm_put_unused_portal(struct bm_portal_config *pcfg); -+void bm_set_liodns(struct bm_portal_config *pcfg); -+ -+/* Pool logic in the portal driver, during initialisation, needs to know if -+ * there's access to CCSR or not (if not, it'll cripple the pool allocator). */ -+#ifdef CONFIG_FSL_BMAN_CONFIG -+int bman_have_ccsr(void); -+#else -+#define bman_have_ccsr() 0 -+#endif -+ -+/* Stockpile build constants. The _LOW value: when bman_acquire() is called and -+ * the stockpile fill-level is <= _LOW, an acquire is attempted from h/w but it -+ * might fail (if the buffer pool is depleted). So this value provides some -+ * "stagger" in that the bman_acquire() function will only fail if lots of bufs -+ * are requested at once or if h/w has been tested a couple of times without -+ * luck. The _HIGH value: when bman_release() is called and the stockpile -+ * fill-level is >= _HIGH, a release is attempted to h/w but it might fail (if -+ * the release ring is full). So this value provides some "stagger" so that -+ * ring-access is retried a couple of times prior to the API returning a -+ * failure. The following *must* be true; -+ * BMAN_STOCKPILE_HIGH-BMAN_STOCKPILE_LOW > 8 -+ * (to avoid thrashing) -+ * BMAN_STOCKPILE_SZ >= 16 -+ * (as the release logic expects to either send 8 buffers to hw prior to -+ * adding the given buffers to the stockpile or add the buffers to the -+ * stockpile before sending 8 to hw, as the API must be an all-or-nothing -+ * success/fail.) -+ */ -+#define BMAN_STOCKPILE_SZ 16u /* number of bufs in per-pool cache */ -+#define BMAN_STOCKPILE_LOW 2u /* when fill is <= this, acquire from hw */ -+#define BMAN_STOCKPILE_HIGH 14u /* when fill is >= this, release to hw */ -+ -+/*************************************************/ -+/* BMan s/w corenet portal, low-level i/face */ -+/*************************************************/ -+ -+/* Used by all portal interrupt registers except 'inhibit' -+ * This mask contains all the "irqsource" bits visible to API users -+ */ -+#define BM_PIRQ_VISIBLE (BM_PIRQ_RCRI | BM_PIRQ_BSCN) -+ -+/* These are bm__(). So for example, bm_disable_write() means "write -+ * the disable register" rather than "disable the ability to write". */ -+#define bm_isr_status_read(bm) __bm_isr_read(bm, bm_isr_status) -+#define bm_isr_status_clear(bm, m) __bm_isr_write(bm, bm_isr_status, m) -+#define bm_isr_enable_read(bm) __bm_isr_read(bm, bm_isr_enable) -+#define bm_isr_enable_write(bm, v) __bm_isr_write(bm, bm_isr_enable, v) -+#define bm_isr_disable_read(bm) __bm_isr_read(bm, bm_isr_disable) -+#define bm_isr_disable_write(bm, v) __bm_isr_write(bm, bm_isr_disable, v) -+#define bm_isr_inhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 1) -+#define bm_isr_uninhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 0) -+ -+#ifdef CONFIG_FSL_BMAN_CONFIG -+/* Set depletion thresholds associated with a buffer pool. Requires that the -+ * operating system have access to Bman CCSR (ie. compiled in support and -+ * run-time access courtesy of the device-tree). */ -+int bm_pool_set(u32 bpid, const u32 *thresholds); -+#define BM_POOL_THRESH_SW_ENTER 0 -+#define BM_POOL_THRESH_SW_EXIT 1 -+#define BM_POOL_THRESH_HW_ENTER 2 -+#define BM_POOL_THRESH_HW_EXIT 3 -+ -+/* Read the free buffer count for a given buffer */ -+u32 bm_pool_free_buffers(u32 bpid); -+ -+__init int bman_init(void); -+__init int bman_resource_init(void); -+ -+const struct bm_portal_config *bman_get_bm_portal_config( -+ struct bman_portal *portal); -+ -+/* power management */ -+#ifdef CONFIG_SUSPEND -+void suspend_unused_bportal(void); -+void resume_unused_bportal(void); -+#endif -+ -+#endif /* CONFIG_FSL_BMAN_CONFIG */ ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_test.c -@@ -0,0 +1,56 @@ -+/* Copyright 2008-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "bman_test.h" -+ -+MODULE_AUTHOR("Geoff Thorpe"); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("Bman testing"); -+ -+static int test_init(void) -+{ -+#ifdef CONFIG_FSL_BMAN_TEST_HIGH -+ int loop = 1; -+ while (loop--) -+ bman_test_high(); -+#endif -+#ifdef CONFIG_FSL_BMAN_TEST_THRESH -+ bman_test_thresh(); -+#endif -+ return 0; -+} -+ -+static void test_exit(void) -+{ -+} -+ -+module_init(test_init); -+module_exit(test_exit); ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_test.h -@@ -0,0 +1,44 @@ -+/* Copyright 2008-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+void bman_test_high(void); -+void bman_test_thresh(void); ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_test_high.c -@@ -0,0 +1,183 @@ -+/* Copyright 2008-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "bman_test.h" -+#include "bman_private.h" -+ -+/*************/ -+/* constants */ -+/*************/ -+ -+#define PORTAL_OPAQUE ((void *)0xf00dbeef) -+#define POOL_OPAQUE ((void *)0xdeadabba) -+#define NUM_BUFS 93 -+#define LOOPS 3 -+#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU -+ -+/***************/ -+/* global vars */ -+/***************/ -+ -+static struct bman_pool *pool; -+static int depleted; -+static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned; -+static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned; -+static int bufs_received; -+ -+/* Predeclare the callback so we can instantiate pool parameters */ -+static void depletion_cb(struct bman_portal *, struct bman_pool *, void *, int); -+ -+/**********************/ -+/* internal functions */ -+/**********************/ -+ -+static void bufs_init(void) -+{ -+ int i; -+ for (i = 0; i < NUM_BUFS; i++) -+ bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i); -+ bufs_received = 0; -+} -+ -+static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b) -+{ -+ if ((bman_ip_rev == BMAN_REV20) || (bman_ip_rev == BMAN_REV21)) { -+ -+ /* On SoCs with Bman revison 2.0, Bman only respects the 40 -+ * LS-bits of buffer addresses, masking off the upper 8-bits on -+ * release commands. The API provides for 48-bit addresses -+ * because some SoCs support all 48-bits. When generating -+ * garbage addresses for testing, we either need to zero the -+ * upper 8-bits when releasing to Bman (otherwise we'll be -+ * disappointed when the buffers we acquire back from Bman -+ * don't match), or we need to mask the upper 8-bits off when -+ * comparing. We do the latter. -+ */ -+ if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK) -+ < (bm_buffer_get64(b) & BMAN_TOKEN_MASK)) -+ return -1; -+ if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK) -+ > (bm_buffer_get64(b) & BMAN_TOKEN_MASK)) -+ return 1; -+ } else { -+ if (bm_buffer_get64(a) < bm_buffer_get64(b)) -+ return -1; -+ if (bm_buffer_get64(a) > bm_buffer_get64(b)) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static void bufs_confirm(void) -+{ -+ int i, j; -+ for (i = 0; i < NUM_BUFS; i++) { -+ int matches = 0; -+ for (j = 0; j < NUM_BUFS; j++) -+ if (!bufs_cmp(&bufs_in[i], &bufs_out[j])) -+ matches++; -+ BUG_ON(matches != 1); -+ } -+} -+ -+/********/ -+/* test */ -+/********/ -+ -+static void depletion_cb(struct bman_portal *__portal, struct bman_pool *__pool, -+ void *pool_ctx, int __depleted) -+{ -+ BUG_ON(__pool != pool); -+ BUG_ON(pool_ctx != POOL_OPAQUE); -+ depleted = __depleted; -+} -+ -+void bman_test_high(void) -+{ -+ struct bman_pool_params pparams = { -+ .flags = BMAN_POOL_FLAG_DEPLETION | BMAN_POOL_FLAG_DYNAMIC_BPID, -+ .cb = depletion_cb, -+ .cb_ctx = POOL_OPAQUE, -+ }; -+ int i, loops = LOOPS; -+ struct bm_buffer tmp_buf; -+ -+ bufs_init(); -+ -+ pr_info("BMAN: --- starting high-level test ---\n"); -+ -+ pool = bman_new_pool(&pparams); -+ BUG_ON(!pool); -+ -+ /*******************/ -+ /* Release buffers */ -+ /*******************/ -+do_loop: -+ i = 0; -+ while (i < NUM_BUFS) { -+ u32 flags = BMAN_RELEASE_FLAG_WAIT; -+ int num = 8; -+ if ((i + num) > NUM_BUFS) -+ num = NUM_BUFS - i; -+ if ((i + num) == NUM_BUFS) -+ flags |= BMAN_RELEASE_FLAG_WAIT_SYNC; -+ if (bman_release(pool, bufs_in + i, num, flags)) -+ panic("bman_release() failed\n"); -+ i += num; -+ } -+ -+ /*******************/ -+ /* Acquire buffers */ -+ /*******************/ -+ while (i > 0) { -+ int tmp, num = 8; -+ if (num > i) -+ num = i; -+ tmp = bman_acquire(pool, bufs_out + i - num, num, 0); -+ BUG_ON(tmp != num); -+ i -= num; -+ } -+ -+ i = bman_acquire(pool, &tmp_buf, 1, 0); -+ BUG_ON(i > 0); -+ -+ bufs_confirm(); -+ -+ if (--loops) -+ goto do_loop; -+ -+ /************/ -+ /* Clean up */ -+ /************/ -+ bman_free_pool(pool); -+ pr_info("BMAN: --- finished high-level test ---\n"); -+} ---- /dev/null -+++ b/drivers/staging/fsl_qbman/bman_test_thresh.c -@@ -0,0 +1,196 @@ -+/* Copyright 2010-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "bman_test.h" -+ -+/* Test constants */ -+#define TEST_NUMBUFS 129728 -+#define TEST_EXIT 129536 -+#define TEST_ENTRY 129024 -+ -+struct affine_test_data { -+ struct task_struct *t; -+ int cpu; -+ int expect_affinity; -+ int drain; -+ int num_enter; -+ int num_exit; -+ struct list_head node; -+ struct completion wakethread; -+ struct completion wakeparent; -+}; -+ -+static void cb_depletion(struct bman_portal *portal, -+ struct bman_pool *pool, -+ void *opaque, -+ int depleted) -+{ -+ struct affine_test_data *data = opaque; -+ int c = smp_processor_id(); -+ pr_info("cb_depletion: bpid=%d, depleted=%d, cpu=%d, original=%d\n", -+ bman_get_params(pool)->bpid, !!depleted, c, data->cpu); -+ /* We should be executing on the CPU of the thread that owns the pool if -+ * and that CPU has an affine portal (ie. it isn't slaved). */ -+ BUG_ON((c != data->cpu) && data->expect_affinity); -+ BUG_ON((c == data->cpu) && !data->expect_affinity); -+ if (depleted) -+ data->num_enter++; -+ else -+ data->num_exit++; -+} -+ -+/* Params used to set up a pool, this also dynamically allocates a BPID */ -+static const struct bman_pool_params params_nocb = { -+ .flags = BMAN_POOL_FLAG_DYNAMIC_BPID | BMAN_POOL_FLAG_THRESH, -+ .thresholds = { TEST_ENTRY, TEST_EXIT, 0, 0 } -+}; -+ -+/* Params used to set up each cpu's pool with callbacks enabled */ -+static struct bman_pool_params params_cb = { -+ .bpid = 0, /* will be replaced to match pool_nocb */ -+ .flags = BMAN_POOL_FLAG_DEPLETION, -+ .cb = cb_depletion -+}; -+ -+static struct bman_pool *pool_nocb; -+static LIST_HEAD(threads); -+ -+static int affine_test(void *__data) -+{ -+ struct bman_pool *pool; -+ struct affine_test_data *data = __data; -+ struct bman_pool_params my_params = params_cb; -+ -+ pr_info("thread %d: starting\n", data->cpu); -+ /* create the pool */ -+ my_params.cb_ctx = data; -+ pool = bman_new_pool(&my_params); -+ BUG_ON(!pool); -+ complete(&data->wakeparent); -+ wait_for_completion(&data->wakethread); -+ init_completion(&data->wakethread); -+ -+ /* if we're the drainer, we get signalled for that */ -+ if (data->drain) { -+ struct bm_buffer buf; -+ int ret; -+ pr_info("thread %d: draining...\n", data->cpu); -+ do { -+ ret = bman_acquire(pool, &buf, 1, 0); -+ } while (ret > 0); -+ pr_info("thread %d: draining done.\n", data->cpu); -+ complete(&data->wakeparent); -+ wait_for_completion(&data->wakethread); -+ init_completion(&data->wakethread); -+ } -+ -+ /* cleanup */ -+ bman_free_pool(pool); -+ while (!kthread_should_stop()) -+ cpu_relax(); -+ pr_info("thread %d: exiting\n", data->cpu); -+ return 0; -+} -+ -+static struct affine_test_data *start_affine_test(int cpu, int drain) -+{ -+ struct affine_test_data *data = kmalloc(sizeof(*data), GFP_KERNEL); -+ -+ if (!data) -+ return NULL; -+ data->cpu = cpu; -+ data->expect_affinity = cpumask_test_cpu(cpu, bman_affine_cpus()); -+ data->drain = drain; -+ data->num_enter = 0; -+ data->num_exit = 0; -+ init_completion(&data->wakethread); -+ init_completion(&data->wakeparent); -+ list_add_tail(&data->node, &threads); -+ data->t = kthread_create(affine_test, data, "threshtest%d", cpu); -+ BUG_ON(IS_ERR(data->t)); -+ kthread_bind(data->t, cpu); -+ wake_up_process(data->t); -+ return data; -+} -+ -+void bman_test_thresh(void) -+{ -+ int loop = TEST_NUMBUFS; -+ int ret, num_cpus = 0; -+ struct affine_test_data *data, *drainer = NULL; -+ -+ pr_info("bman_test_thresh: start\n"); -+ -+ /* allocate a BPID and seed it */ -+ pool_nocb = bman_new_pool(¶ms_nocb); -+ BUG_ON(!pool_nocb); -+ while (loop--) { -+ struct bm_buffer buf; -+ bm_buffer_set64(&buf, 0x0badbeef + loop); -+ ret = bman_release(pool_nocb, &buf, 1, -+ BMAN_RELEASE_FLAG_WAIT); -+ BUG_ON(ret); -+ } -+ while (!bman_rcr_is_empty()) -+ cpu_relax(); -+ pr_info("bman_test_thresh: buffers are in\n"); -+ -+ /* create threads and wait for them to create pools */ -+ params_cb.bpid = bman_get_params(pool_nocb)->bpid; -+ for_each_cpu(loop, cpu_online_mask) { -+ data = start_affine_test(loop, drainer ? 0 : 1); -+ BUG_ON(!data); -+ if (!drainer) -+ drainer = data; -+ num_cpus++; -+ wait_for_completion(&data->wakeparent); -+ } -+ -+ /* signal the drainer to start draining */ -+ complete(&drainer->wakethread); -+ wait_for_completion(&drainer->wakeparent); -+ init_completion(&drainer->wakeparent); -+ -+ /* tear down */ -+ list_for_each_entry_safe(data, drainer, &threads, node) { -+ complete(&data->wakethread); -+ ret = kthread_stop(data->t); -+ BUG_ON(ret); -+ list_del(&data->node); -+ /* check that we get the expected callbacks (and no others) */ -+ BUG_ON(data->num_enter != 1); -+ BUG_ON(data->num_exit != 0); -+ kfree(data); -+ } -+ bman_free_pool(pool_nocb); -+ -+ pr_info("bman_test_thresh: done\n"); -+} ---- /dev/null -+++ b/drivers/staging/fsl_qbman/dpa_alloc.c -@@ -0,0 +1,706 @@ -+/* Copyright 2009-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "dpa_sys.h" -+#include -+#include -+ -+/* Qman and Bman APIs are front-ends to the common code; */ -+ -+static DECLARE_DPA_ALLOC(bpalloc); /* BPID allocator */ -+static DECLARE_DPA_ALLOC(fqalloc); /* FQID allocator */ -+static DECLARE_DPA_ALLOC(qpalloc); /* pool-channel allocator */ -+static DECLARE_DPA_ALLOC(cgralloc); /* CGR ID allocator */ -+static DECLARE_DPA_ALLOC(ceetm0_challoc); /* CEETM Channel ID allocator */ -+static DECLARE_DPA_ALLOC(ceetm0_lfqidalloc); /* CEETM LFQID allocator */ -+static DECLARE_DPA_ALLOC(ceetm1_challoc); /* CEETM Channel ID allocator */ -+static DECLARE_DPA_ALLOC(ceetm1_lfqidalloc); /* CEETM LFQID allocator */ -+ -+/* This is a sort-of-conditional dpa_alloc_free() routine. Eg. when releasing -+ * FQIDs (probably from user-space), it can filter out those that aren't in the -+ * OOS state (better to leak a h/w resource than to crash). This function -+ * returns the number of invalid IDs that were not released. */ -+static u32 release_id_range(struct dpa_alloc *alloc, u32 id, u32 count, -+ int (*is_valid)(u32 id)) -+{ -+ int valid_mode = 0; -+ u32 loop = id, total_invalid = 0; -+ while (loop < (id + count)) { -+ int isvalid = is_valid ? is_valid(loop) : 1; -+ if (!valid_mode) { -+ /* We're looking for a valid ID to terminate an invalid -+ * range */ -+ if (isvalid) { -+ /* We finished a range of invalid IDs, a valid -+ * range is now underway */ -+ valid_mode = 1; -+ count -= (loop - id); -+ id = loop; -+ } else -+ total_invalid++; -+ } else { -+ /* We're looking for an invalid ID to terminate a -+ * valid range */ -+ if (!isvalid) { -+ /* Release the range of valid IDs, an unvalid -+ * range is now underway */ -+ if (loop > id) -+ dpa_alloc_free(alloc, id, loop - id); -+ valid_mode = 0; -+ } -+ } -+ loop++; -+ } -+ /* Release any unterminated range of valid IDs */ -+ if (valid_mode && count) -+ dpa_alloc_free(alloc, id, count); -+ return total_invalid; -+} -+ -+/* BPID allocator front-end */ -+ -+int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial) -+{ -+ return dpa_alloc_new(&bpalloc, result, count, align, partial); -+} -+EXPORT_SYMBOL(bman_alloc_bpid_range); -+ -+static int bp_cleanup(u32 bpid) -+{ -+ return bman_shutdown_pool(bpid) == 0; -+} -+void bman_release_bpid_range(u32 bpid, u32 count) -+{ -+ u32 total_invalid = release_id_range(&bpalloc, bpid, count, bp_cleanup); -+ if (total_invalid) -+ pr_err("BPID range [%d..%d] (%d) had %d leaks\n", -+ bpid, bpid + count - 1, count, total_invalid); -+} -+EXPORT_SYMBOL(bman_release_bpid_range); -+ -+void bman_seed_bpid_range(u32 bpid, u32 count) -+{ -+ dpa_alloc_seed(&bpalloc, bpid, count); -+} -+EXPORT_SYMBOL(bman_seed_bpid_range); -+ -+int bman_reserve_bpid_range(u32 bpid, u32 count) -+{ -+ return dpa_alloc_reserve(&bpalloc, bpid, count); -+} -+EXPORT_SYMBOL(bman_reserve_bpid_range); -+ -+ -+/* FQID allocator front-end */ -+ -+int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial) -+{ -+ return dpa_alloc_new(&fqalloc, result, count, align, partial); -+} -+EXPORT_SYMBOL(qman_alloc_fqid_range); -+ -+static int fq_cleanup(u32 fqid) -+{ -+ return qman_shutdown_fq(fqid) == 0; -+} -+void qman_release_fqid_range(u32 fqid, u32 count) -+{ -+ u32 total_invalid = release_id_range(&fqalloc, fqid, count, fq_cleanup); -+ if (total_invalid) -+ pr_err("FQID range [%d..%d] (%d) had %d leaks\n", -+ fqid, fqid + count - 1, count, total_invalid); -+} -+EXPORT_SYMBOL(qman_release_fqid_range); -+ -+int qman_reserve_fqid_range(u32 fqid, u32 count) -+{ -+ return dpa_alloc_reserve(&fqalloc, fqid, count); -+} -+EXPORT_SYMBOL(qman_reserve_fqid_range); -+ -+void qman_seed_fqid_range(u32 fqid, u32 count) -+{ -+ dpa_alloc_seed(&fqalloc, fqid, count); -+} -+EXPORT_SYMBOL(qman_seed_fqid_range); -+ -+/* Pool-channel allocator front-end */ -+ -+int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial) -+{ -+ return dpa_alloc_new(&qpalloc, result, count, align, partial); -+} -+EXPORT_SYMBOL(qman_alloc_pool_range); -+ -+static int qpool_cleanup(u32 qp) -+{ -+ /* We query all FQDs starting from -+ * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs -+ * whose destination channel is the pool-channel being released. -+ * When a non-OOS FQD is found we attempt to clean it up */ -+ struct qman_fq fq = { -+ .fqid = 1 -+ }; -+ int err; -+ do { -+ struct qm_mcr_queryfq_np np; -+ err = qman_query_fq_np(&fq, &np); -+ if (err) -+ /* FQID range exceeded, found no problems */ -+ return 1; -+ if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) { -+ struct qm_fqd fqd; -+ err = qman_query_fq(&fq, &fqd); -+ BUG_ON(err); -+ if (fqd.dest.channel == qp) { -+ /* The channel is the FQ's target, clean it */ -+ if (qman_shutdown_fq(fq.fqid) != 0) -+ /* Couldn't shut down the FQ -+ so the pool must be leaked */ -+ return 0; -+ } -+ } -+ /* Move to the next FQID */ -+ fq.fqid++; -+ } while (1); -+} -+void qman_release_pool_range(u32 qp, u32 count) -+{ -+ u32 total_invalid = release_id_range(&qpalloc, qp, -+ count, qpool_cleanup); -+ if (total_invalid) { -+ /* Pool channels are almost always used individually */ -+ if (count == 1) -+ pr_err("Pool channel 0x%x had %d leaks\n", -+ qp, total_invalid); -+ else -+ pr_err("Pool channels [%d..%d] (%d) had %d leaks\n", -+ qp, qp + count - 1, count, total_invalid); -+ } -+} -+EXPORT_SYMBOL(qman_release_pool_range); -+ -+ -+void qman_seed_pool_range(u32 poolid, u32 count) -+{ -+ dpa_alloc_seed(&qpalloc, poolid, count); -+ -+} -+EXPORT_SYMBOL(qman_seed_pool_range); -+ -+int qman_reserve_pool_range(u32 poolid, u32 count) -+{ -+ return dpa_alloc_reserve(&qpalloc, poolid, count); -+} -+EXPORT_SYMBOL(qman_reserve_pool_range); -+ -+ -+/* CGR ID allocator front-end */ -+ -+int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial) -+{ -+ return dpa_alloc_new(&cgralloc, result, count, align, partial); -+} -+EXPORT_SYMBOL(qman_alloc_cgrid_range); -+ -+static int cqr_cleanup(u32 cgrid) -+{ -+ /* We query all FQDs starting from -+ * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs -+ * whose CGR is the CGR being released. -+ */ -+ struct qman_fq fq = { -+ .fqid = 1 -+ }; -+ int err; -+ do { -+ struct qm_mcr_queryfq_np np; -+ err = qman_query_fq_np(&fq, &np); -+ if (err) -+ /* FQID range exceeded, found no problems */ -+ return 1; -+ if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) { -+ struct qm_fqd fqd; -+ err = qman_query_fq(&fq, &fqd); -+ BUG_ON(err); -+ if ((fqd.fq_ctrl & QM_FQCTRL_CGE) && -+ (fqd.cgid == cgrid)) { -+ pr_err("CRGID 0x%x is being used by FQID 0x%x," -+ " CGR will be leaked\n", -+ cgrid, fq.fqid); -+ return 1; -+ } -+ } -+ /* Move to the next FQID */ -+ fq.fqid++; -+ } while (1); -+} -+ -+void qman_release_cgrid_range(u32 cgrid, u32 count) -+{ -+ u32 total_invalid = release_id_range(&cgralloc, cgrid, -+ count, cqr_cleanup); -+ if (total_invalid) -+ pr_err("CGRID range [%d..%d] (%d) had %d leaks\n", -+ cgrid, cgrid + count - 1, count, total_invalid); -+} -+EXPORT_SYMBOL(qman_release_cgrid_range); -+ -+void qman_seed_cgrid_range(u32 cgrid, u32 count) -+{ -+ dpa_alloc_seed(&cgralloc, cgrid, count); -+ -+} -+EXPORT_SYMBOL(qman_seed_cgrid_range); -+ -+/* CEETM CHANNEL ID allocator front-end */ -+int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align, -+ int partial) -+{ -+ return dpa_alloc_new(&ceetm0_challoc, result, count, align, partial); -+} -+EXPORT_SYMBOL(qman_alloc_ceetm0_channel_range); -+ -+int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align, -+ int partial) -+{ -+ return dpa_alloc_new(&ceetm1_challoc, result, count, align, partial); -+} -+EXPORT_SYMBOL(qman_alloc_ceetm1_channel_range); -+ -+void qman_release_ceetm0_channel_range(u32 channelid, u32 count) -+{ -+ u32 total_invalid; -+ -+ total_invalid = release_id_range(&ceetm0_challoc, channelid, count, -+ NULL); -+ if (total_invalid) -+ pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n", -+ channelid, channelid + count - 1, count, total_invalid); -+} -+EXPORT_SYMBOL(qman_release_ceetm0_channel_range); -+ -+void qman_seed_ceetm0_channel_range(u32 channelid, u32 count) -+{ -+ dpa_alloc_seed(&ceetm0_challoc, channelid, count); -+ -+} -+EXPORT_SYMBOL(qman_seed_ceetm0_channel_range); -+ -+void qman_release_ceetm1_channel_range(u32 channelid, u32 count) -+{ -+ u32 total_invalid; -+ total_invalid = release_id_range(&ceetm1_challoc, channelid, count, -+ NULL); -+ if (total_invalid) -+ pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n", -+ channelid, channelid + count - 1, count, total_invalid); -+} -+EXPORT_SYMBOL(qman_release_ceetm1_channel_range); -+ -+void qman_seed_ceetm1_channel_range(u32 channelid, u32 count) -+{ -+ dpa_alloc_seed(&ceetm1_challoc, channelid, count); -+ -+} -+EXPORT_SYMBOL(qman_seed_ceetm1_channel_range); -+ -+/* CEETM LFQID allocator front-end */ -+int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align, -+ int partial) -+{ -+ return dpa_alloc_new(&ceetm0_lfqidalloc, result, count, align, partial); -+} -+EXPORT_SYMBOL(qman_alloc_ceetm0_lfqid_range); -+ -+int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align, -+ int partial) -+{ -+ return dpa_alloc_new(&ceetm1_lfqidalloc, result, count, align, partial); -+} -+EXPORT_SYMBOL(qman_alloc_ceetm1_lfqid_range); -+ -+void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count) -+{ -+ u32 total_invalid; -+ -+ total_invalid = release_id_range(&ceetm0_lfqidalloc, lfqid, count, -+ NULL); -+ if (total_invalid) -+ pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n", -+ lfqid, lfqid + count - 1, count, total_invalid); -+} -+EXPORT_SYMBOL(qman_release_ceetm0_lfqid_range); -+ -+void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count) -+{ -+ dpa_alloc_seed(&ceetm0_lfqidalloc, lfqid, count); -+ -+} -+EXPORT_SYMBOL(qman_seed_ceetm0_lfqid_range); -+ -+void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count) -+{ -+ u32 total_invalid; -+ -+ total_invalid = release_id_range(&ceetm1_lfqidalloc, lfqid, count, -+ NULL); -+ if (total_invalid) -+ pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n", -+ lfqid, lfqid + count - 1, count, total_invalid); -+} -+EXPORT_SYMBOL(qman_release_ceetm1_lfqid_range); -+ -+void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count) -+{ -+ dpa_alloc_seed(&ceetm1_lfqidalloc, lfqid, count); -+ -+} -+EXPORT_SYMBOL(qman_seed_ceetm1_lfqid_range); -+ -+ -+/* Everything else is the common backend to all the allocators */ -+ -+/* The allocator is a (possibly-empty) list of these; */ -+struct alloc_node { -+ struct list_head list; -+ u32 base; -+ u32 num; -+ /* refcount and is_alloced are only set -+ when the node is in the used list */ -+ unsigned int refcount; -+ int is_alloced; -+}; -+ -+/* #define DPA_ALLOC_DEBUG */ -+ -+#ifdef DPA_ALLOC_DEBUG -+#define DPRINT pr_info -+static void DUMP(struct dpa_alloc *alloc) -+{ -+ int off = 0; -+ char buf[256]; -+ struct alloc_node *p; -+ pr_info("Free Nodes\n"); -+ list_for_each_entry(p, &alloc->free, list) { -+ if (off < 255) -+ off += snprintf(buf + off, 255-off, "{%d,%d}", -+ p->base, p->base + p->num - 1); -+ } -+ pr_info("%s\n", buf); -+ -+ off = 0; -+ pr_info("Used Nodes\n"); -+ list_for_each_entry(p, &alloc->used, list) { -+ if (off < 255) -+ off += snprintf(buf + off, 255-off, "{%d,%d}", -+ p->base, p->base + p->num - 1); -+ } -+ pr_info("%s\n", buf); -+ -+ -+ -+} -+#else -+#define DPRINT(x...) -+#define DUMP(a) -+#endif -+ -+int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align, -+ int partial) -+{ -+ struct alloc_node *i = NULL, *next_best = NULL, *used_node = NULL; -+ u32 base, next_best_base = 0, num = 0, next_best_num = 0; -+ struct alloc_node *margin_left, *margin_right; -+ -+ *result = (u32)-1; -+ DPRINT("alloc_range(%d,%d,%d)\n", count, align, partial); -+ DUMP(alloc); -+ /* If 'align' is 0, it should behave as though it was 1 */ -+ if (!align) -+ align = 1; -+ margin_left = kmalloc(sizeof(*margin_left), GFP_KERNEL); -+ if (!margin_left) -+ goto err; -+ margin_right = kmalloc(sizeof(*margin_right), GFP_KERNEL); -+ if (!margin_right) { -+ kfree(margin_left); -+ goto err; -+ } -+ spin_lock_irq(&alloc->lock); -+ list_for_each_entry(i, &alloc->free, list) { -+ base = (i->base + align - 1) / align; -+ base *= align; -+ if ((base - i->base) >= i->num) -+ /* alignment is impossible, regardless of count */ -+ continue; -+ num = i->num - (base - i->base); -+ if (num >= count) { -+ /* this one will do nicely */ -+ num = count; -+ goto done; -+ } -+ if (num > next_best_num) { -+ next_best = i; -+ next_best_base = base; -+ next_best_num = num; -+ } -+ } -+ if (partial && next_best) { -+ i = next_best; -+ base = next_best_base; -+ num = next_best_num; -+ } else -+ i = NULL; -+done: -+ if (i) { -+ if (base != i->base) { -+ margin_left->base = i->base; -+ margin_left->num = base - i->base; -+ list_add_tail(&margin_left->list, &i->list); -+ } else -+ kfree(margin_left); -+ if ((base + num) < (i->base + i->num)) { -+ margin_right->base = base + num; -+ margin_right->num = (i->base + i->num) - -+ (base + num); -+ list_add(&margin_right->list, &i->list); -+ } else -+ kfree(margin_right); -+ list_del(&i->list); -+ kfree(i); -+ *result = base; -+ } else { -+ spin_unlock_irq(&alloc->lock); -+ kfree(margin_left); -+ kfree(margin_right); -+ } -+ -+err: -+ DPRINT("returning %d\n", i ? num : -ENOMEM); -+ DUMP(alloc); -+ if (!i) -+ return -ENOMEM; -+ -+ /* Add the allocation to the used list with a refcount of 1 */ -+ used_node = kmalloc(sizeof(*used_node), GFP_KERNEL); -+ if (!used_node) { -+ spin_unlock_irq(&alloc->lock); -+ return -ENOMEM; -+ } -+ used_node->base = *result; -+ used_node->num = num; -+ used_node->refcount = 1; -+ used_node->is_alloced = 1; -+ list_add_tail(&used_node->list, &alloc->used); -+ spin_unlock_irq(&alloc->lock); -+ return (int)num; -+} -+ -+/* Allocate the list node using GFP_ATOMIC, because we *really* want to avoid -+ * forcing error-handling on to users in the deallocation path. */ -+static void _dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count) -+{ -+ struct alloc_node *i, *node = kmalloc(sizeof(*node), GFP_ATOMIC); -+ BUG_ON(!node); -+ DPRINT("release_range(%d,%d)\n", base_id, count); -+ DUMP(alloc); -+ BUG_ON(!count); -+ spin_lock_irq(&alloc->lock); -+ -+ -+ node->base = base_id; -+ node->num = count; -+ list_for_each_entry(i, &alloc->free, list) { -+ if (i->base >= node->base) { -+ /* BUG_ON(any overlapping) */ -+ BUG_ON(i->base < (node->base + node->num)); -+ list_add_tail(&node->list, &i->list); -+ goto done; -+ } -+ } -+ list_add_tail(&node->list, &alloc->free); -+done: -+ /* Merge to the left */ -+ i = list_entry(node->list.prev, struct alloc_node, list); -+ if (node->list.prev != &alloc->free) { -+ BUG_ON((i->base + i->num) > node->base); -+ if ((i->base + i->num) == node->base) { -+ node->base = i->base; -+ node->num += i->num; -+ list_del(&i->list); -+ kfree(i); -+ } -+ } -+ /* Merge to the right */ -+ i = list_entry(node->list.next, struct alloc_node, list); -+ if (node->list.next != &alloc->free) { -+ BUG_ON((node->base + node->num) > i->base); -+ if ((node->base + node->num) == i->base) { -+ node->num += i->num; -+ list_del(&i->list); -+ kfree(i); -+ } -+ } -+ spin_unlock_irq(&alloc->lock); -+ DUMP(alloc); -+} -+ -+ -+void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count) -+{ -+ struct alloc_node *i = NULL; -+ spin_lock_irq(&alloc->lock); -+ -+ /* First find the node in the used list and decrement its ref count */ -+ list_for_each_entry(i, &alloc->used, list) { -+ if (i->base == base_id && i->num == count) { -+ --i->refcount; -+ if (i->refcount == 0) { -+ list_del(&i->list); -+ spin_unlock_irq(&alloc->lock); -+ if (i->is_alloced) -+ _dpa_alloc_free(alloc, base_id, count); -+ kfree(i); -+ return; -+ } -+ spin_unlock_irq(&alloc->lock); -+ return; -+ } -+ } -+ /* Couldn't find the allocation */ -+ pr_err("Attempt to free ID 0x%x COUNT %d that wasn't alloc'd or reserved\n", -+ base_id, count); -+ spin_unlock_irq(&alloc->lock); -+} -+ -+void dpa_alloc_seed(struct dpa_alloc *alloc, u32 base_id, u32 count) -+{ -+ /* Same as free but no previous allocation checking is needed */ -+ _dpa_alloc_free(alloc, base_id, count); -+} -+ -+ -+int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base, u32 num) -+{ -+ struct alloc_node *i = NULL, *used_node; -+ -+ DPRINT("alloc_reserve(%d,%d)\n", base, num); -+ DUMP(alloc); -+ -+ spin_lock_irq(&alloc->lock); -+ -+ /* Check for the node in the used list. -+ If found, increase it's refcount */ -+ list_for_each_entry(i, &alloc->used, list) { -+ if ((i->base == base) && (i->num == num)) { -+ ++i->refcount; -+ spin_unlock_irq(&alloc->lock); -+ return 0; -+ } -+ if ((base >= i->base) && (base < (i->base + i->num))) { -+ /* This is an attempt to reserve a region that was -+ already reserved or alloced with a different -+ base or num */ -+ pr_err("Cannot reserve %d - %d, it overlaps with" -+ " existing reservation from %d - %d\n", -+ base, base + num - 1, i->base, -+ i->base + i->num - 1); -+ spin_unlock_irq(&alloc->lock); -+ return -1; -+ } -+ } -+ /* Check to make sure this ID isn't in the free list */ -+ list_for_each_entry(i, &alloc->free, list) { -+ if ((base >= i->base) && (base < (i->base + i->num))) { -+ /* yep, the reservation is within this node */ -+ pr_err("Cannot reserve %d - %d, it overlaps with" -+ " free range %d - %d and must be alloced\n", -+ base, base + num - 1, -+ i->base, i->base + i->num - 1); -+ spin_unlock_irq(&alloc->lock); -+ return -1; -+ } -+ } -+ /* Add the allocation to the used list with a refcount of 1 */ -+ used_node = kmalloc(sizeof(*used_node), GFP_KERNEL); -+ if (!used_node) { -+ spin_unlock_irq(&alloc->lock); -+ return -ENOMEM; -+ -+ } -+ used_node->base = base; -+ used_node->num = num; -+ used_node->refcount = 1; -+ used_node->is_alloced = 0; -+ list_add_tail(&used_node->list, &alloc->used); -+ spin_unlock_irq(&alloc->lock); -+ return 0; -+} -+ -+ -+int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count) -+{ -+ struct alloc_node *i = NULL; -+ DPRINT("alloc_pop()\n"); -+ DUMP(alloc); -+ spin_lock_irq(&alloc->lock); -+ if (!list_empty(&alloc->free)) { -+ i = list_entry(alloc->free.next, struct alloc_node, list); -+ list_del(&i->list); -+ } -+ spin_unlock_irq(&alloc->lock); -+ DPRINT("returning %d\n", i ? 0 : -ENOMEM); -+ DUMP(alloc); -+ if (!i) -+ return -ENOMEM; -+ *result = i->base; -+ *count = i->num; -+ kfree(i); -+ return 0; -+} -+ -+int dpa_alloc_check(struct dpa_alloc *list_head, u32 item) -+{ -+ struct alloc_node *i = NULL; -+ int res = 0; -+ DPRINT("alloc_check()\n"); -+ spin_lock_irq(&list_head->lock); -+ -+ list_for_each_entry(i, &list_head->free, list) { -+ if ((item >= i->base) && (item < (i->base + i->num))) { -+ res = 1; -+ break; -+ } -+ } -+ spin_unlock_irq(&list_head->lock); -+ return res; -+} ---- /dev/null -+++ b/drivers/staging/fsl_qbman/dpa_sys.h -@@ -0,0 +1,259 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef DPA_SYS_H -+#define DPA_SYS_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+/* When copying aligned words or shorts, try to avoid memcpy() */ -+#define CONFIG_TRY_BETTER_MEMCPY -+ -+/* For 2-element tables related to cache-inhibited and cache-enabled mappings */ -+#define DPA_PORTAL_CE 0 -+#define DPA_PORTAL_CI 1 -+ -+/***********************/ -+/* Misc inline assists */ -+/***********************/ -+ -+#if defined CONFIG_PPC32 -+#include "dpa_sys_ppc32.h" -+#elif defined CONFIG_PPC64 -+#include "dpa_sys_ppc64.h" -+#elif defined CONFIG_ARM -+#include "dpa_sys_arm.h" -+#elif defined CONFIG_ARM64 -+#include "dpa_sys_arm64.h" -+#endif -+ -+ -+#ifdef CONFIG_FSL_DPA_CHECKING -+#define DPA_ASSERT(x) \ -+ do { \ -+ if (!(x)) { \ -+ pr_crit("ASSERT: (%s:%d) %s\n", __FILE__, __LINE__, \ -+ __stringify_1(x)); \ -+ dump_stack(); \ -+ panic("assertion failure"); \ -+ } \ -+ } while (0) -+#else -+#define DPA_ASSERT(x) -+#endif -+ -+/* memcpy() stuff - when you know alignments in advance */ -+#ifdef CONFIG_TRY_BETTER_MEMCPY -+static inline void copy_words(void *dest, const void *src, size_t sz) -+{ -+ u32 *__dest = dest; -+ const u32 *__src = src; -+ size_t __sz = sz >> 2; -+ BUG_ON((unsigned long)dest & 0x3); -+ BUG_ON((unsigned long)src & 0x3); -+ BUG_ON(sz & 0x3); -+ while (__sz--) -+ *(__dest++) = *(__src++); -+} -+static inline void copy_shorts(void *dest, const void *src, size_t sz) -+{ -+ u16 *__dest = dest; -+ const u16 *__src = src; -+ size_t __sz = sz >> 1; -+ BUG_ON((unsigned long)dest & 0x1); -+ BUG_ON((unsigned long)src & 0x1); -+ BUG_ON(sz & 0x1); -+ while (__sz--) -+ *(__dest++) = *(__src++); -+} -+static inline void copy_bytes(void *dest, const void *src, size_t sz) -+{ -+ u8 *__dest = dest; -+ const u8 *__src = src; -+ while (sz--) -+ *(__dest++) = *(__src++); -+} -+#else -+#define copy_words memcpy -+#define copy_shorts memcpy -+#define copy_bytes memcpy -+#endif -+ -+/************/ -+/* RB-trees */ -+/************/ -+ -+/* We encapsulate RB-trees so that its easier to use non-linux forms in -+ * non-linux systems. This also encapsulates the extra plumbing that linux code -+ * usually provides when using RB-trees. This encapsulation assumes that the -+ * data type held by the tree is u32. */ -+ -+struct dpa_rbtree { -+ struct rb_root root; -+}; -+#define DPA_RBTREE { .root = RB_ROOT } -+ -+static inline void dpa_rbtree_init(struct dpa_rbtree *tree) -+{ -+ tree->root = RB_ROOT; -+} -+ -+#define IMPLEMENT_DPA_RBTREE(name, type, node_field, val_field) \ -+static inline int name##_push(struct dpa_rbtree *tree, type *obj) \ -+{ \ -+ struct rb_node *parent = NULL, **p = &tree->root.rb_node; \ -+ while (*p) { \ -+ u32 item; \ -+ parent = *p; \ -+ item = rb_entry(parent, type, node_field)->val_field; \ -+ if (obj->val_field < item) \ -+ p = &parent->rb_left; \ -+ else if (obj->val_field > item) \ -+ p = &parent->rb_right; \ -+ else \ -+ return -EBUSY; \ -+ } \ -+ rb_link_node(&obj->node_field, parent, p); \ -+ rb_insert_color(&obj->node_field, &tree->root); \ -+ return 0; \ -+} \ -+static inline void name##_del(struct dpa_rbtree *tree, type *obj) \ -+{ \ -+ rb_erase(&obj->node_field, &tree->root); \ -+} \ -+static inline type *name##_find(struct dpa_rbtree *tree, u32 val) \ -+{ \ -+ type *ret; \ -+ struct rb_node *p = tree->root.rb_node; \ -+ while (p) { \ -+ ret = rb_entry(p, type, node_field); \ -+ if (val < ret->val_field) \ -+ p = p->rb_left; \ -+ else if (val > ret->val_field) \ -+ p = p->rb_right; \ -+ else \ -+ return ret; \ -+ } \ -+ return NULL; \ -+} -+ -+/************/ -+/* Bootargs */ -+/************/ -+ -+/* Qman has "qportals=" and Bman has "bportals=", they use the same syntax -+ * though; a comma-separated list of items, each item being a cpu index and/or a -+ * range of cpu indices, and each item optionally be prefixed by "s" to indicate -+ * that the portal associated with that cpu should be shared. See bman_driver.c -+ * for more specifics. */ -+static int __parse_portals_cpu(const char **s, unsigned int *cpu) -+{ -+ *cpu = 0; -+ if (!isdigit(**s)) -+ return -EINVAL; -+ while (isdigit(**s)) -+ *cpu = *cpu * 10 + (*((*s)++) - '0'); -+ return 0; -+} -+static inline int parse_portals_bootarg(char *str, struct cpumask *want_shared, -+ struct cpumask *want_unshared, -+ const char *argname) -+{ -+ const char *s = str; -+ unsigned int shared, cpu1, cpu2, loop; -+ -+keep_going: -+ if (*s == 's') { -+ shared = 1; -+ s++; -+ } else -+ shared = 0; -+ if (__parse_portals_cpu(&s, &cpu1)) -+ goto err; -+ if (*s == '-') { -+ s++; -+ if (__parse_portals_cpu(&s, &cpu2)) -+ goto err; -+ if (cpu2 < cpu1) -+ goto err; -+ } else -+ cpu2 = cpu1; -+ for (loop = cpu1; loop <= cpu2; loop++) -+ cpumask_set_cpu(loop, shared ? want_shared : want_unshared); -+ if (*s == ',') { -+ s++; -+ goto keep_going; -+ } else if ((*s == '\0') || isspace(*s)) -+ return 0; -+err: -+ pr_crit("Malformed %s argument: %s, offset: %lu\n", argname, str, -+ (unsigned long)s - (unsigned long)str); -+ return -EINVAL; -+} -+#ifdef CONFIG_FSL_USDPAA -+/* Hooks from fsl_usdpaa_irq.c to fsl_usdpaa.c */ -+int usdpaa_get_portal_config(struct file *filp, void *cinh, -+ enum usdpaa_portal_type ptype, unsigned int *irq, -+ void **iir_reg); -+#endif -+#endif /* DPA_SYS_H */ ---- /dev/null -+++ b/drivers/staging/fsl_qbman/dpa_sys_arm.h -@@ -0,0 +1,95 @@ -+/* Copyright 2016 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef DPA_SYS_ARM_H -+#define DPA_SYS_ARM_H -+ -+#include -+#include -+ -+/* Implementation of ARM specific routines */ -+ -+/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler -+ * barriers and that dcb*() won't fall victim to compiler or execution -+ * reordering with respect to other code/instructions that manipulate the same -+ * cacheline. */ -+#define hwsync() { asm volatile("dmb st" : : : "memory"); } -+#define lwsync() { asm volatile("dmb st" : : : "memory"); } -+#define dcbf(p) { asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r" (p) : "memory"); } -+#define dcbt_ro(p) { asm volatile("pld [%0, #64];": : "r" (p)); } -+#define dcbt_rw(p) { asm volatile("pldw [%0, #64];": : "r" (p)); } -+#define dcbi(p) { asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (p) : "memory"); } -+ -+#define dcbz_64(p) { memset(p, 0, sizeof(*p)); } -+ -+#define dcbf_64(p) \ -+ do { \ -+ dcbf((u32)p); \ -+ } while (0) -+/* Commonly used combo */ -+#define dcbit_ro(p) \ -+ do { \ -+ dcbi((u32)p); \ -+ dcbt_ro((u32)p); \ -+ } while (0) -+ -+static inline u64 mfatb(void) -+{ -+ return get_cycles(); -+} -+ -+static inline u32 in_be32(volatile void *addr) -+{ -+ return be32_to_cpu(*((volatile u32 *) addr)); -+} -+ -+static inline void out_be32(void *addr, u32 val) -+{ -+ *((u32 *) addr) = cpu_to_be32(val); -+} -+ -+ -+static inline void set_bits(unsigned long mask, volatile unsigned long *p) -+{ -+ *p |= mask; -+} -+static inline void clear_bits(unsigned long mask, volatile unsigned long *p) -+{ -+ *p &= ~mask; -+} -+ -+static inline void flush_dcache_range(unsigned long start, unsigned long stop) -+{ -+ __cpuc_flush_dcache_area((void *) start, stop - start); -+} -+ -+#define hard_smp_processor_id() raw_smp_processor_id() -+#endif ---- /dev/null -+++ b/drivers/staging/fsl_qbman/dpa_sys_arm64.h -@@ -0,0 +1,102 @@ -+/* Copyright 2014 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef DPA_SYS_ARM64_H -+#define DPA_SYS_ARM64_H -+ -+#include -+#include -+ -+/* Implementation of ARM 64 bit specific routines */ -+ -+/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler -+ * barriers and that dcb*() won't fall victim to compiler or execution -+ * reordering with respect to other code/instructions that manipulate the same -+ * cacheline. */ -+#define hwsync() { asm volatile("dmb st" : : : "memory"); } -+#define lwsync() { asm volatile("dmb st" : : : "memory"); } -+#define dcbf(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); } -+#define dcbt_ro(p) { asm volatile("prfm pldl1keep, [%0, #0]" : : "r" (p)); } -+#define dcbt_rw(p) { asm volatile("prfm pstl1keep, [%0, #0]" : : "r" (p)); } -+#define dcbi(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); } -+#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); } -+ -+#define dcbz_64(p) \ -+ do { \ -+ dcbz(p); \ -+ } while (0) -+ -+#define dcbf_64(p) \ -+ do { \ -+ dcbf(p); \ -+ } while (0) -+/* Commonly used combo */ -+#define dcbit_ro(p) \ -+ do { \ -+ dcbi(p); \ -+ dcbt_ro(p); \ -+ } while (0) -+ -+static inline u64 mfatb(void) -+{ -+ return get_cycles(); -+} -+ -+static inline u32 in_be32(volatile void *addr) -+{ -+ return be32_to_cpu(*((volatile u32 *) addr)); -+} -+ -+static inline void out_be32(void *addr, u32 val) -+{ -+ *((u32 *) addr) = cpu_to_be32(val); -+} -+ -+ -+static inline void set_bits(unsigned long mask, volatile unsigned long *p) -+{ -+ *p |= mask; -+} -+static inline void clear_bits(unsigned long mask, volatile unsigned long *p) -+{ -+ *p &= ~mask; -+} -+ -+static inline void flush_dcache_range(unsigned long start, unsigned long stop) -+{ -+ __flush_dcache_area((void *) start, stop - start); -+} -+ -+#define hard_smp_processor_id() raw_smp_processor_id() -+ -+ -+ -+#endif ---- /dev/null -+++ b/drivers/staging/fsl_qbman/dpa_sys_ppc32.h -@@ -0,0 +1,70 @@ -+/* Copyright 2014 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef DPA_SYS_PPC32_H -+#define DPA_SYS_PPC32_H -+ -+/* Implementation of PowerPC 32 bit specific routines */ -+ -+/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler -+ * barriers and that dcb*() won't fall victim to compiler or execution -+ * reordering with respect to other code/instructions that manipulate the same -+ * cacheline. */ -+#define hwsync() __asm__ __volatile__ ("sync" : : : "memory") -+#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory") -+#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory") -+#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p)) -+#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p)) -+#define dcbi(p) dcbf(p) -+ -+#define dcbzl(p) __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p)) -+#define dcbz_64(p) dcbzl(p) -+#define dcbf_64(p) dcbf(p) -+ -+/* Commonly used combo */ -+#define dcbit_ro(p) \ -+ do { \ -+ dcbi(p); \ -+ dcbt_ro(p); \ -+ } while (0) -+ -+static inline u64 mfatb(void) -+{ -+ u32 hi, lo, chk; -+ do { -+ hi = mfspr(SPRN_ATBU); -+ lo = mfspr(SPRN_ATBL); -+ chk = mfspr(SPRN_ATBU); -+ } while (unlikely(hi != chk)); -+ return ((u64)hi << 32) | (u64)lo; -+} -+ -+#endif ---- /dev/null -+++ b/drivers/staging/fsl_qbman/dpa_sys_ppc64.h -@@ -0,0 +1,79 @@ -+/* Copyright 2014 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef DPA_SYS_PPC64_H -+#define DPA_SYS_PPC64_H -+ -+/* Implementation of PowerPC 64 bit specific routines */ -+ -+/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler -+ * barriers and that dcb*() won't fall victim to compiler or execution -+ * reordering with respect to other code/instructions that manipulate the same -+ * cacheline. */ -+#define hwsync() __asm__ __volatile__ ("sync" : : : "memory") -+#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory") -+#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory") -+#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p)) -+#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p)) -+#define dcbi(p) dcbf(p) -+ -+#define dcbz(p) __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p)) -+#define dcbz_64(p) \ -+ do { \ -+ dcbz((void*)p + 32); \ -+ dcbz(p); \ -+ } while (0) -+#define dcbf_64(p) \ -+ do { \ -+ dcbf((void*)p + 32); \ -+ dcbf(p); \ -+ } while (0) -+/* Commonly used combo */ -+#define dcbit_ro(p) \ -+ do { \ -+ dcbi(p); \ -+ dcbi((void*)p + 32); \ -+ dcbt_ro(p); \ -+ dcbt_ro((void*)p + 32); \ -+ } while (0) -+ -+static inline u64 mfatb(void) -+{ -+ u32 hi, lo, chk; -+ do { -+ hi = mfspr(SPRN_ATBU); -+ lo = mfspr(SPRN_ATBL); -+ chk = mfspr(SPRN_ATBU); -+ } while (unlikely(hi != chk)); -+ return ((u64)hi << 32) | (u64)lo; -+} -+ -+#endif ---- /dev/null -+++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c -@@ -0,0 +1,1984 @@ -+/* Copyright (C) 2008-2012 Freescale Semiconductor, Inc. -+ * Authors: Andy Fleming -+ * Timur Tabi -+ * Geoff Thorpe -+ * -+ * This file is licensed under the terms of the GNU General Public License -+ * version 2. This program is licensed "as is" without any warranty of any -+ * kind, whether express or implied. -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64)) -+#include -+#endif -+ -+#include "dpa_sys.h" -+#include -+#include "bman_low.h" -+#include "qman_low.h" -+ -+/* Physical address range of the memory reservation, exported for mm/mem.c */ -+static u64 phys_start; -+static u64 phys_size; -+static u64 arg_phys_size; -+ -+/* PFN versions of the above */ -+static unsigned long pfn_start; -+static unsigned long pfn_size; -+ -+/* Memory reservations are manipulated under this spinlock (which is why 'refs' -+ * isn't atomic_t). */ -+static DEFINE_SPINLOCK(mem_lock); -+ -+/* The range of TLB1 indices */ -+static unsigned int first_tlb; -+static unsigned int num_tlb = 1; -+static unsigned int current_tlb; /* loops around for fault handling */ -+ -+/* Memory reservation is represented as a list of 'mem_fragment's, some of which -+ * may be mapped. Unmapped fragments are always merged where possible. */ -+static LIST_HEAD(mem_list); -+ -+struct mem_mapping; -+ -+/* Memory fragments are in 'mem_list'. */ -+struct mem_fragment { -+ u64 base; -+ u64 len; -+ unsigned long pfn_base; /* PFN version of 'base' */ -+ unsigned long pfn_len; /* PFN version of 'len' */ -+ unsigned int refs; /* zero if unmapped */ -+ u64 root_len; /* Size of the orignal fragment */ -+ unsigned long root_pfn; /* PFN of the orignal fragment */ -+ struct list_head list; -+ /* if mapped, flags+name captured at creation time */ -+ u32 flags; -+ char name[USDPAA_DMA_NAME_MAX]; -+ u64 map_len; -+ /* support multi-process locks per-memory-fragment. */ -+ int has_locking; -+ wait_queue_head_t wq; -+ struct mem_mapping *owner; -+}; -+ -+/* Mappings of memory fragments in 'struct ctx'. These are created from -+ * ioctl(USDPAA_IOCTL_DMA_MAP), though the actual mapping then happens via a -+ * mmap(). */ -+struct mem_mapping { -+ struct mem_fragment *root_frag; -+ u32 frag_count; -+ u64 total_size; -+ struct list_head list; -+ int refs; -+ void *virt_addr; -+}; -+ -+struct portal_mapping { -+ struct usdpaa_ioctl_portal_map user; -+ union { -+ struct qm_portal_config *qportal; -+ struct bm_portal_config *bportal; -+ }; -+ /* Declare space for the portals in case the process -+ exits unexpectedly and needs to be cleaned by the kernel */ -+ union { -+ struct qm_portal qman_portal_low; -+ struct bm_portal bman_portal_low; -+ }; -+ struct list_head list; -+ struct resource *phys; -+ struct iommu_domain *iommu_domain; -+}; -+ -+/* Track the DPAA resources the process is using */ -+struct active_resource { -+ struct list_head list; -+ u32 id; -+ u32 num; -+ unsigned int refcount; -+}; -+ -+/* Per-FD state (which should also be per-process but we don't enforce that) */ -+struct ctx { -+ /* Lock to protect the context */ -+ spinlock_t lock; -+ /* Allocated resources get put here for accounting */ -+ struct list_head resources[usdpaa_id_max]; -+ /* list of DMA maps */ -+ struct list_head maps; -+ /* list of portal maps */ -+ struct list_head portals; -+}; -+ -+/* Different resource classes */ -+static const struct alloc_backend { -+ enum usdpaa_id_type id_type; -+ int (*alloc)(u32 *, u32, u32, int); -+ void (*release)(u32 base, unsigned int count); -+ int (*reserve)(u32 base, unsigned int count); -+ const char *acronym; -+} alloc_backends[] = { -+ { -+ .id_type = usdpaa_id_fqid, -+ .alloc = qman_alloc_fqid_range, -+ .release = qman_release_fqid_range, -+ .reserve = qman_reserve_fqid_range, -+ .acronym = "FQID" -+ }, -+ { -+ .id_type = usdpaa_id_bpid, -+ .alloc = bman_alloc_bpid_range, -+ .release = bman_release_bpid_range, -+ .reserve = bman_reserve_bpid_range, -+ .acronym = "BPID" -+ }, -+ { -+ .id_type = usdpaa_id_qpool, -+ .alloc = qman_alloc_pool_range, -+ .release = qman_release_pool_range, -+ .reserve = qman_reserve_pool_range, -+ .acronym = "QPOOL" -+ }, -+ { -+ .id_type = usdpaa_id_cgrid, -+ .alloc = qman_alloc_cgrid_range, -+ .release = qman_release_cgrid_range, -+ .acronym = "CGRID" -+ }, -+ { -+ .id_type = usdpaa_id_ceetm0_lfqid, -+ .alloc = qman_alloc_ceetm0_lfqid_range, -+ .release = qman_release_ceetm0_lfqid_range, -+ .acronym = "CEETM0_LFQID" -+ }, -+ { -+ .id_type = usdpaa_id_ceetm0_channelid, -+ .alloc = qman_alloc_ceetm0_channel_range, -+ .release = qman_release_ceetm0_channel_range, -+ .acronym = "CEETM0_LFQID" -+ }, -+ { -+ .id_type = usdpaa_id_ceetm1_lfqid, -+ .alloc = qman_alloc_ceetm1_lfqid_range, -+ .release = qman_release_ceetm1_lfqid_range, -+ .acronym = "CEETM1_LFQID" -+ }, -+ { -+ .id_type = usdpaa_id_ceetm1_channelid, -+ .alloc = qman_alloc_ceetm1_channel_range, -+ .release = qman_release_ceetm1_channel_range, -+ .acronym = "CEETM1_LFQID" -+ }, -+ { -+ /* This terminates the array */ -+ .id_type = usdpaa_id_max -+ } -+}; -+ -+/* Determines the largest acceptable page size for a given size -+ The sizes are determined by what the TLB1 acceptable page sizes are */ -+static u32 largest_page_size(u32 size) -+{ -+ int shift = 30; /* Start at 1G size */ -+ if (size < 4096) -+ return 0; -+ do { -+ if (size >= (1<= 12); /* Up to 4k */ -+ return 0; -+} -+ -+/* Determine if value is power of 4 */ -+static inline bool is_power_of_4(u64 x) -+{ -+ if (x == 0 || ((x & (x - 1)) != 0)) -+ return false; -+ return !!(x & 0x5555555555555555ull); -+} -+ -+/* Helper for ioctl_dma_map() when we have a larger fragment than we need. This -+ * splits the fragment into 4 and returns the upper-most. (The caller can loop -+ * until it has a suitable fragment size.) */ -+static struct mem_fragment *split_frag(struct mem_fragment *frag) -+{ -+ struct mem_fragment *x[3]; -+ -+ x[0] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC); -+ x[1] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC); -+ x[2] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC); -+ if (!x[0] || !x[1] || !x[2]) { -+ kfree(x[0]); -+ kfree(x[1]); -+ kfree(x[2]); -+ return NULL; -+ } -+ BUG_ON(frag->refs); -+ frag->len >>= 2; -+ frag->pfn_len >>= 2; -+ x[0]->base = frag->base + frag->len; -+ x[1]->base = x[0]->base + frag->len; -+ x[2]->base = x[1]->base + frag->len; -+ x[0]->len = x[1]->len = x[2]->len = frag->len; -+ x[0]->pfn_base = frag->pfn_base + frag->pfn_len; -+ x[1]->pfn_base = x[0]->pfn_base + frag->pfn_len; -+ x[2]->pfn_base = x[1]->pfn_base + frag->pfn_len; -+ x[0]->pfn_len = x[1]->pfn_len = x[2]->pfn_len = frag->pfn_len; -+ x[0]->refs = x[1]->refs = x[2]->refs = 0; -+ x[0]->root_len = x[1]->root_len = x[2]->root_len = frag->root_len; -+ x[0]->root_pfn = x[1]->root_pfn = x[2]->root_pfn = frag->root_pfn; -+ x[0]->name[0] = x[1]->name[0] = x[2]->name[0] = 0; -+ list_add_tail(&x[0]->list, &frag->list); -+ list_add_tail(&x[1]->list, &x[0]->list); -+ list_add_tail(&x[2]->list, &x[1]->list); -+ return x[2]; -+} -+ -+static __maybe_unused void dump_frags(void) -+{ -+ struct mem_fragment *frag; -+ int i = 0; -+ list_for_each_entry(frag, &mem_list, list) { -+ pr_info("FRAG %d: base 0x%llx pfn_base 0x%lx len 0x%llx root_len 0x%llx root_pfn 0x%lx refs %d name %s\n", -+ i, frag->base, frag->pfn_base, -+ frag->len, frag->root_len, frag->root_pfn, -+ frag->refs, frag->name); -+ ++i; -+ } -+} -+ -+/* Walk the list of fragments and adjoin neighbouring segments if possible */ -+static void compress_frags(void) -+{ -+ /* Walk the fragment list and combine fragments */ -+ struct mem_fragment *frag, *nxtfrag; -+ u64 len = 0; -+ -+ int i, numfrags; -+ -+ -+ frag = list_entry(mem_list.next, struct mem_fragment, list); -+ -+ while (&frag->list != &mem_list) { -+ /* Must combine consecutive fragemenst with -+ same root_pfn such that they are power of 4 */ -+ if (frag->refs != 0) { -+ frag = list_entry(frag->list.next, -+ struct mem_fragment, list); -+ continue; /* Not this window */ -+ } -+ len = frag->len; -+ numfrags = 0; -+ nxtfrag = list_entry(frag->list.next, -+ struct mem_fragment, list); -+ while (true) { -+ if (&nxtfrag->list == &mem_list) { -+ numfrags = 0; -+ break; /* End of list */ -+ } -+ if (nxtfrag->refs) { -+ numfrags = 0; -+ break; /* In use still */ -+ } -+ if (nxtfrag->root_pfn != frag->root_pfn) { -+ numfrags = 0; -+ break; /* Crosses root fragment boundary */ -+ } -+ len += nxtfrag->len; -+ numfrags++; -+ if (is_power_of_4(len)) { -+ /* These fragments can be combined */ -+ break; -+ } -+ nxtfrag = list_entry(nxtfrag->list.next, -+ struct mem_fragment, list); -+ } -+ if (numfrags == 0) { -+ frag = list_entry(frag->list.next, -+ struct mem_fragment, list); -+ continue; /* try the next window */ -+ } -+ for (i = 0; i < numfrags; i++) { -+ struct mem_fragment *todel = -+ list_entry(nxtfrag->list.prev, -+ struct mem_fragment, list); -+ nxtfrag->len += todel->len; -+ nxtfrag->pfn_len += todel->pfn_len; -+ list_del(&todel->list); -+ } -+ /* Re evaluate the list, things may merge now */ -+ frag = list_entry(mem_list.next, struct mem_fragment, list); -+ } -+} -+ -+/* Hook from arch/powerpc/mm/mem.c */ -+int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size) -+{ -+ struct mem_fragment *frag; -+ int idx = -1; -+ if ((pfn < pfn_start) || (pfn >= (pfn_start + pfn_size))) -+ return -1; -+ /* It's in-range, we need to find the fragment */ -+ spin_lock(&mem_lock); -+ list_for_each_entry(frag, &mem_list, list) { -+ if ((pfn >= frag->pfn_base) && (pfn < (frag->pfn_base + -+ frag->pfn_len))) { -+ *phys_addr = frag->base; -+ *size = frag->len; -+ idx = current_tlb++; -+ if (current_tlb >= (first_tlb + num_tlb)) -+ current_tlb = first_tlb; -+ break; -+ } -+ } -+ spin_unlock(&mem_lock); -+ return idx; -+} -+ -+static int usdpaa_open(struct inode *inode, struct file *filp) -+{ -+ const struct alloc_backend *backend = &alloc_backends[0]; -+ struct ctx *ctx = kmalloc(sizeof(struct ctx), GFP_KERNEL); -+ if (!ctx) -+ return -ENOMEM; -+ filp->private_data = ctx; -+ -+ while (backend->id_type != usdpaa_id_max) { -+ INIT_LIST_HEAD(&ctx->resources[backend->id_type]); -+ backend++; -+ } -+ -+ INIT_LIST_HEAD(&ctx->maps); -+ INIT_LIST_HEAD(&ctx->portals); -+ spin_lock_init(&ctx->lock); -+ -+ //filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi; -+ -+ return 0; -+} -+ -+#define DQRR_MAXFILL 15 -+ -+/* Reset a QMan portal to its default state */ -+static int init_qm_portal(struct qm_portal_config *config, -+ struct qm_portal *portal) -+{ -+ const struct qm_dqrr_entry *dqrr = NULL; -+ int i; -+ -+ portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE]; -+ portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI]; -+ -+ /* Make sure interrupts are inhibited */ -+ qm_out(IIR, 1); -+ -+ /* Initialize the DQRR. This will stop any dequeue -+ commands that are in progress */ -+ if (qm_dqrr_init(portal, config, qm_dqrr_dpush, qm_dqrr_pvb, -+ qm_dqrr_cdc, DQRR_MAXFILL)) { -+ pr_err("qm_dqrr_init() failed when trying to" -+ " recover portal, portal will be leaked\n"); -+ return 1; -+ } -+ -+ /* Discard any entries on the DQRR */ -+ /* If we consume the ring twice something is wrong */ -+ for (i = 0; i < DQRR_MAXFILL * 2; i++) { -+ qm_dqrr_pvb_update(portal); -+ dqrr = qm_dqrr_current(portal); -+ if (!dqrr) -+ break; -+ qm_dqrr_cdc_consume_1ptr(portal, dqrr, 0); -+ qm_dqrr_pvb_update(portal); -+ qm_dqrr_next(portal); -+ } -+ /* Initialize the EQCR */ -+ if (qm_eqcr_init(portal, qm_eqcr_pvb, -+ qm_eqcr_get_ci_stashing(portal), 1)) { -+ pr_err("Qman EQCR initialisation failed\n"); -+ return 1; -+ } -+ /* initialize the MR */ -+ if (qm_mr_init(portal, qm_mr_pvb, qm_mr_cci)) { -+ pr_err("Qman MR initialisation failed\n"); -+ return 1; -+ } -+ qm_mr_pvb_update(portal); -+ while (qm_mr_current(portal)) { -+ qm_mr_next(portal); -+ qm_mr_cci_consume_to_current(portal); -+ qm_mr_pvb_update(portal); -+ } -+ -+ if (qm_mc_init(portal)) { -+ pr_err("Qman MC initialisation failed\n"); -+ return 1; -+ } -+ return 0; -+} -+ -+static int init_bm_portal(struct bm_portal_config *config, -+ struct bm_portal *portal) -+{ -+ portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE]; -+ portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI]; -+ -+ if (bm_rcr_init(portal, bm_rcr_pvb, bm_rcr_cce)) { -+ pr_err("Bman RCR initialisation failed\n"); -+ return 1; -+ } -+ if (bm_mc_init(portal)) { -+ pr_err("Bman MC initialisation failed\n"); -+ return 1; -+ } -+ return 0; -+} -+ -+/* Function that will scan all FQ's in the system. For each FQ that is not -+ OOS it will call the check_channel helper to determine if the FQ should -+ be torn down. If the check_channel helper returns true the FQ will be -+ transitioned to the OOS state */ -+static int qm_check_and_destroy_fqs(struct qm_portal *portal, void *ctx, -+ bool (*check_channel)(void*, u32)) -+{ -+ u32 fq_id = 0; -+ while (1) { -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ u8 state; -+ u32 channel; -+ -+ /* Determine the channel for the FQID */ -+ mcc = qm_mc_start(portal); -+ mcc->queryfq.fqid = fq_id; -+ qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ); -+ while (!(mcr = qm_mc_result(portal))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) -+ == QM_MCR_VERB_QUERYFQ); -+ if (mcr->result != QM_MCR_RESULT_OK) -+ break; /* End of valid FQIDs */ -+ -+ channel = mcr->queryfq.fqd.dest.channel; -+ /* Determine the state of the FQID */ -+ mcc = qm_mc_start(portal); -+ mcc->queryfq_np.fqid = fq_id; -+ qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ_NP); -+ while (!(mcr = qm_mc_result(portal))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) -+ == QM_MCR_VERB_QUERYFQ_NP); -+ state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK; -+ if (state == QM_MCR_NP_STATE_OOS) -+ /* Already OOS, no need to do anymore checks */ -+ goto next; -+ -+ if (check_channel(ctx, channel)) -+ qm_shutdown_fq(&portal, 1, fq_id); -+ next: -+ ++fq_id; -+ } -+ return 0; -+} -+ -+static bool check_channel_device(void *_ctx, u32 channel) -+{ -+ struct ctx *ctx = _ctx; -+ struct portal_mapping *portal, *tmpportal; -+ struct active_resource *res; -+ -+ /* See if the FQ is destined for one of the portals we're cleaning up */ -+ list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) { -+ if (portal->user.type == usdpaa_portal_qman) { -+ if (portal->qportal->public_cfg.channel == channel) { -+ /* This FQs destination is a portal -+ we're cleaning, send a retire */ -+ return true; -+ } -+ } -+ } -+ -+ /* Check the pool channels that will be released as well */ -+ list_for_each_entry(res, &ctx->resources[usdpaa_id_qpool], list) { -+ if ((res->id >= channel) && -+ ((res->id + res->num - 1) <= channel)) -+ return true; -+ } -+ return false; -+} -+ -+static bool check_portal_channel(void *ctx, u32 channel) -+{ -+ u32 portal_channel = *(u32 *)ctx; -+ if (portal_channel == channel) { -+ /* This FQs destination is a portal -+ we're cleaning, send a retire */ -+ return true; -+ } -+ return false; -+} -+ -+ -+ -+ -+static int usdpaa_release(struct inode *inode, struct file *filp) -+{ -+ struct ctx *ctx = filp->private_data; -+ struct mem_mapping *map, *tmpmap; -+ struct portal_mapping *portal, *tmpportal; -+ const struct alloc_backend *backend = &alloc_backends[0]; -+ struct active_resource *res; -+ struct qm_portal *qm_cleanup_portal = NULL; -+ struct bm_portal *bm_cleanup_portal = NULL; -+ struct qm_portal_config *qm_alloced_portal = NULL; -+ struct bm_portal_config *bm_alloced_portal = NULL; -+ -+ struct qm_portal *portal_array[qman_portal_max]; -+ int portal_count = 0; -+ -+ /* Ensure the release operation cannot be migrated to another -+ CPU as CPU specific variables may be needed during cleanup */ -+#ifdef CONFIG_PREEMPT_RT_FULL -+ migrate_disable(); -+#endif -+ /* The following logic is used to recover resources that were not -+ correctly released by the process that is closing the FD. -+ Step 1: syncronize the HW with the qm_portal/bm_portal structures -+ in the kernel -+ */ -+ -+ list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) { -+ /* Try to recover any portals that weren't shut down */ -+ if (portal->user.type == usdpaa_portal_qman) { -+ portal_array[portal_count] = &portal->qman_portal_low; -+ ++portal_count; -+ init_qm_portal(portal->qportal, -+ &portal->qman_portal_low); -+ if (!qm_cleanup_portal) { -+ qm_cleanup_portal = &portal->qman_portal_low; -+ } else { -+ /* Clean FQs on the dedicated channel */ -+ u32 chan = portal->qportal->public_cfg.channel; -+ qm_check_and_destroy_fqs( -+ &portal->qman_portal_low, &chan, -+ check_portal_channel); -+ } -+ } else { -+ /* BMAN */ -+ init_bm_portal(portal->bportal, -+ &portal->bman_portal_low); -+ if (!bm_cleanup_portal) -+ bm_cleanup_portal = &portal->bman_portal_low; -+ } -+ } -+ /* If no portal was found, allocate one for cleanup */ -+ if (!qm_cleanup_portal) { -+ qm_alloced_portal = qm_get_unused_portal(); -+ if (!qm_alloced_portal) { -+ pr_crit("No QMan portal avalaible for cleanup\n"); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ migrate_enable(); -+#endif -+ return -1; -+ } -+ qm_cleanup_portal = kmalloc(sizeof(struct qm_portal), -+ GFP_KERNEL); -+ if (!qm_cleanup_portal) { -+#ifdef CONFIG_PREEMPT_RT_FULL -+ migrate_enable(); -+#endif -+ return -ENOMEM; -+ } -+ init_qm_portal(qm_alloced_portal, qm_cleanup_portal); -+ portal_array[portal_count] = qm_cleanup_portal; -+ ++portal_count; -+ } -+ if (!bm_cleanup_portal) { -+ bm_alloced_portal = bm_get_unused_portal(); -+ if (!bm_alloced_portal) { -+ pr_crit("No BMan portal avalaible for cleanup\n"); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ migrate_enable(); -+#endif -+ return -1; -+ } -+ bm_cleanup_portal = kmalloc(sizeof(struct bm_portal), -+ GFP_KERNEL); -+ if (!bm_cleanup_portal) { -+#ifdef CONFIG_PREEMPT_RT_FULL -+ migrate_enable(); -+#endif -+ return -ENOMEM; -+ } -+ init_bm_portal(bm_alloced_portal, bm_cleanup_portal); -+ } -+ -+ /* OOS the FQs associated with this process */ -+ qm_check_and_destroy_fqs(qm_cleanup_portal, ctx, check_channel_device); -+ -+ while (backend->id_type != usdpaa_id_max) { -+ int leaks = 0; -+ list_for_each_entry(res, &ctx->resources[backend->id_type], -+ list) { -+ if (backend->id_type == usdpaa_id_fqid) { -+ int i = 0; -+ for (; i < res->num; i++) { -+ /* Clean FQs with the cleanup portal */ -+ qm_shutdown_fq(portal_array, -+ portal_count, -+ res->id + i); -+ } -+ } -+ leaks += res->num; -+ backend->release(res->id, res->num); -+ } -+ if (leaks) -+ pr_crit("USDPAA process leaking %d %s%s\n", leaks, -+ backend->acronym, (leaks > 1) ? "s" : ""); -+ backend++; -+ } -+ /* Release any DMA regions */ -+ spin_lock(&mem_lock); -+ list_for_each_entry_safe(map, tmpmap, &ctx->maps, list) { -+ struct mem_fragment *current_frag = map->root_frag; -+ int i; -+ if (map->root_frag->has_locking && -+ (map->root_frag->owner == map)) { -+ map->root_frag->owner = NULL; -+ wake_up(&map->root_frag->wq); -+ } -+ /* Check each fragment and merge if the ref count is 0 */ -+ for (i = 0; i < map->frag_count; i++) { -+ --current_frag->refs; -+ current_frag = list_entry(current_frag->list.prev, -+ struct mem_fragment, list); -+ } -+ -+ compress_frags(); -+ list_del(&map->list); -+ kfree(map); -+ } -+ spin_unlock(&mem_lock); -+ -+ /* Return portals */ -+ list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) { -+ if (portal->user.type == usdpaa_portal_qman) { -+ /* Give the portal back to the allocator */ -+ init_qm_portal(portal->qportal, -+ &portal->qman_portal_low); -+ qm_put_unused_portal(portal->qportal); -+ } else { -+ init_bm_portal(portal->bportal, -+ &portal->bman_portal_low); -+ bm_put_unused_portal(portal->bportal); -+ } -+ list_del(&portal->list); -+ kfree(portal); -+ } -+ if (qm_alloced_portal) { -+ qm_put_unused_portal(qm_alloced_portal); -+ kfree(qm_cleanup_portal); -+ } -+ if (bm_alloced_portal) { -+ bm_put_unused_portal(bm_alloced_portal); -+ kfree(bm_cleanup_portal); -+ } -+ -+ kfree(ctx); -+#ifdef CONFIG_PREEMPT_RT_FULL -+ migrate_enable(); -+#endif -+ return 0; -+} -+ -+static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma, -+ int *match, unsigned long *pfn) -+{ -+ struct mem_mapping *map; -+ -+ list_for_each_entry(map, &ctx->maps, list) { -+ int i; -+ struct mem_fragment *frag = map->root_frag; -+ -+ for (i = 0; i < map->frag_count; i++) { -+ if (frag->pfn_base == vma->vm_pgoff) { -+ *match = 1; -+ *pfn = frag->pfn_base; -+ return 0; -+ } -+ frag = list_entry(frag->list.next, struct mem_fragment, -+ list); -+ } -+ } -+ *match = 0; -+ return 0; -+} -+ -+static int check_mmap_resource(struct resource *res, struct vm_area_struct *vma, -+ int *match, unsigned long *pfn) -+{ -+ *pfn = res->start >> PAGE_SHIFT; -+ if (*pfn == vma->vm_pgoff) { -+ *match = 1; -+ if ((vma->vm_end - vma->vm_start) != resource_size(res)) -+ return -EINVAL; -+ } else -+ *match = 0; -+ return 0; -+} -+ -+static int check_mmap_portal(struct ctx *ctx, struct vm_area_struct *vma, -+ int *match, unsigned long *pfn) -+{ -+ struct portal_mapping *portal; -+ int ret; -+ -+ list_for_each_entry(portal, &ctx->portals, list) { -+ ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CE], vma, -+ match, pfn); -+ if (*match) { -+ vma->vm_page_prot = -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ pgprot_cached_ns(vma->vm_page_prot); -+#else -+ pgprot_cached_noncoherent(vma->vm_page_prot); -+#endif -+ return ret; -+ } -+ ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CI], vma, -+ match, pfn); -+ if (*match) { -+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -+ return ret; -+ } -+ } -+ *match = 0; -+ return 0; -+} -+ -+static int usdpaa_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+ struct ctx *ctx = filp->private_data; -+ unsigned long pfn = 0; -+ int match, ret; -+ -+ spin_lock(&mem_lock); -+ ret = check_mmap_dma(ctx, vma, &match, &pfn); -+ if (!match) -+ ret = check_mmap_portal(ctx, vma, &match, &pfn); -+ spin_unlock(&mem_lock); -+ if (!match) -+ return -EINVAL; -+ if (!ret) -+ ret = remap_pfn_range(vma, vma->vm_start, pfn, -+ vma->vm_end - vma->vm_start, -+ vma->vm_page_prot); -+ return ret; -+} -+ -+/* Return the nearest rounded-up address >= 'addr' that is 'sz'-aligned. 'sz' -+ * must be a power of 2, but both 'addr' and 'sz' can be expressions. */ -+#define USDPAA_MEM_ROUNDUP(addr, sz) \ -+ ({ \ -+ unsigned long foo_align = (sz) - 1; \ -+ ((addr) + foo_align) & ~foo_align; \ -+ }) -+/* Searching for a size-aligned virtual address range starting from 'addr' */ -+static unsigned long usdpaa_get_unmapped_area(struct file *file, -+ unsigned long addr, -+ unsigned long len, -+ unsigned long pgoff, -+ unsigned long flags) -+{ -+ struct vm_area_struct *vma; -+ -+ if (len % PAGE_SIZE) -+ return -EINVAL; -+ if (!len) -+ return -EINVAL; -+ -+ /* Need to align the address to the largest pagesize of the mapping -+ * because the MMU requires the virtual address to have the same -+ * alignment as the physical address */ -+ addr = USDPAA_MEM_ROUNDUP(addr, largest_page_size(len)); -+ vma = find_vma(current->mm, addr); -+ /* Keep searching until we reach the end of currently-used virtual -+ * address-space or we find a big enough gap. */ -+ while (vma) { -+ if ((addr + len) < vma->vm_start) -+ return addr; -+ -+ addr = USDPAA_MEM_ROUNDUP(vma->vm_end, largest_page_size(len)); -+ vma = vma->vm_next; -+ } -+ if ((TASK_SIZE - len) < addr) -+ return -ENOMEM; -+ return addr; -+} -+ -+static long ioctl_id_alloc(struct ctx *ctx, void __user *arg) -+{ -+ struct usdpaa_ioctl_id_alloc i; -+ const struct alloc_backend *backend; -+ struct active_resource *res; -+ int ret = copy_from_user(&i, arg, sizeof(i)); -+ if (ret) -+ return ret; -+ if ((i.id_type >= usdpaa_id_max) || !i.num) -+ return -EINVAL; -+ backend = &alloc_backends[i.id_type]; -+ /* Allocate the required resource type */ -+ ret = backend->alloc(&i.base, i.num, i.align, i.partial); -+ if (ret < 0) -+ return ret; -+ i.num = ret; -+ /* Copy the result to user-space */ -+ ret = copy_to_user(arg, &i, sizeof(i)); -+ if (ret) { -+ backend->release(i.base, i.num); -+ return ret; -+ } -+ /* Assign the allocated range to the FD accounting */ -+ res = kmalloc(sizeof(*res), GFP_KERNEL); -+ if (!res) { -+ backend->release(i.base, i.num); -+ return -ENOMEM; -+ } -+ spin_lock(&ctx->lock); -+ res->id = i.base; -+ res->num = i.num; -+ res->refcount = 1; -+ list_add(&res->list, &ctx->resources[i.id_type]); -+ spin_unlock(&ctx->lock); -+ return 0; -+} -+ -+static long ioctl_id_release(struct ctx *ctx, void __user *arg) -+{ -+ struct usdpaa_ioctl_id_release i; -+ const struct alloc_backend *backend; -+ struct active_resource *tmp, *pos; -+ -+ int ret = copy_from_user(&i, arg, sizeof(i)); -+ if (ret) -+ return ret; -+ if ((i.id_type >= usdpaa_id_max) || !i.num) -+ return -EINVAL; -+ backend = &alloc_backends[i.id_type]; -+ /* Pull the range out of the FD accounting - the range is valid iff this -+ * succeeds. */ -+ spin_lock(&ctx->lock); -+ list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) { -+ if (pos->id == i.base && pos->num == i.num) { -+ pos->refcount--; -+ if (pos->refcount) { -+ spin_unlock(&ctx->lock); -+ return 0; /* Still being used */ -+ } -+ list_del(&pos->list); -+ kfree(pos); -+ spin_unlock(&ctx->lock); -+ goto found; -+ } -+ } -+ /* Failed to find the resource */ -+ spin_unlock(&ctx->lock); -+ pr_err("Couldn't find resource type %d base 0x%x num %d\n", -+ i.id_type, i.base, i.num); -+ return -EINVAL; -+found: -+ /* Release the resource to the backend */ -+ backend->release(i.base, i.num); -+ return 0; -+} -+ -+static long ioctl_id_reserve(struct ctx *ctx, void __user *arg) -+{ -+ struct usdpaa_ioctl_id_reserve i; -+ const struct alloc_backend *backend; -+ struct active_resource *tmp, *pos; -+ -+ int ret = copy_from_user(&i, arg, sizeof(i)); -+ if (ret) -+ return ret; -+ if ((i.id_type >= usdpaa_id_max) || !i.num) -+ return -EINVAL; -+ backend = &alloc_backends[i.id_type]; -+ if (!backend->reserve) -+ return -EINVAL; -+ /* Pull the range out of the FD accounting - the range is valid iff this -+ * succeeds. */ -+ spin_lock(&ctx->lock); -+ list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) { -+ if (pos->id == i.base && pos->num == i.num) { -+ pos->refcount++; -+ spin_unlock(&ctx->lock); -+ return 0; -+ } -+ } -+ -+ /* Failed to find the resource */ -+ spin_unlock(&ctx->lock); -+ -+ /* Reserve the resource in the backend */ -+ ret = backend->reserve(i.base, i.num); -+ if (ret) -+ return ret; -+ /* Assign the reserved range to the FD accounting */ -+ pos = kmalloc(sizeof(*pos), GFP_KERNEL); -+ if (!pos) { -+ backend->release(i.base, i.num); -+ return -ENOMEM; -+ } -+ spin_lock(&ctx->lock); -+ pos->id = i.base; -+ pos->num = i.num; -+ pos->refcount = 1; -+ list_add(&pos->list, &ctx->resources[i.id_type]); -+ spin_unlock(&ctx->lock); -+ return 0; -+} -+ -+static long ioctl_dma_map(struct file *fp, struct ctx *ctx, -+ struct usdpaa_ioctl_dma_map *i) -+{ -+ struct mem_fragment *frag, *start_frag, *next_frag; -+ struct mem_mapping *map, *tmp; -+ int ret = 0; -+ u32 largest_page, so_far = 0; -+ int frag_count = 0; -+ unsigned long next_addr = PAGE_SIZE, populate; -+ -+ /* error checking to ensure values copied from user space are valid */ -+ if (i->len % PAGE_SIZE) -+ return -EINVAL; -+ -+ map = kmalloc(sizeof(*map), GFP_KERNEL); -+ if (!map) -+ return -ENOMEM; -+ -+ spin_lock(&mem_lock); -+ if (i->flags & USDPAA_DMA_FLAG_SHARE) { -+ list_for_each_entry(frag, &mem_list, list) { -+ if (frag->refs && (frag->flags & -+ USDPAA_DMA_FLAG_SHARE) && -+ !strncmp(i->name, frag->name, -+ USDPAA_DMA_NAME_MAX)) { -+ /* Matching entry */ -+ if ((i->flags & USDPAA_DMA_FLAG_CREATE) && -+ !(i->flags & USDPAA_DMA_FLAG_LAZY)) { -+ ret = -EBUSY; -+ goto out; -+ } -+ -+ /* Check to ensure size matches record */ -+ if (i->len != frag->map_len && i->len) { -+ pr_err("ioctl_dma_map() Size requested does not match %s and is none zero\n", -+ frag->name); -+ return -EINVAL; -+ } -+ -+ /* Check if this has already been mapped -+ to this process */ -+ list_for_each_entry(tmp, &ctx->maps, list) -+ if (tmp->root_frag == frag) { -+ /* Already mapped, just need to -+ inc ref count */ -+ tmp->refs++; -+ kfree(map); -+ i->did_create = 0; -+ i->len = tmp->total_size; -+ i->phys_addr = frag->base; -+ i->ptr = tmp->virt_addr; -+ spin_unlock(&mem_lock); -+ return 0; -+ } -+ /* Matching entry - just need to map */ -+ i->has_locking = frag->has_locking; -+ i->did_create = 0; -+ i->len = frag->map_len; -+ start_frag = frag; -+ goto do_map; -+ } -+ } -+ /* No matching entry */ -+ if (!(i->flags & USDPAA_DMA_FLAG_CREATE)) { -+ pr_err("ioctl_dma_map() No matching entry\n"); -+ ret = -ENOMEM; -+ goto out; -+ } -+ } -+ /* New fragment required, size must be provided. */ -+ if (!i->len) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ /* Find one of more contiguous fragments that satisfy the total length -+ trying to minimize the number of fragments -+ compute the largest page size that the allocation could use */ -+ largest_page = largest_page_size(i->len); -+ start_frag = NULL; -+ while (largest_page && -+ largest_page <= largest_page_size(phys_size) && -+ start_frag == NULL) { -+ /* Search the list for a frag of that size */ -+ list_for_each_entry(frag, &mem_list, list) { -+ if (!frag->refs && (frag->len == largest_page)) { -+ /* See if the next x fragments are free -+ and can accomidate the size */ -+ u32 found_size = largest_page; -+ next_frag = list_entry(frag->list.prev, -+ struct mem_fragment, -+ list); -+ /* If the fragement is too small check -+ if the neighbours cab support it */ -+ while (found_size < i->len) { -+ if (&mem_list == &next_frag->list) -+ break; /* End of list */ -+ if (next_frag->refs != 0 || -+ next_frag->len == 0) -+ break; /* not enough space */ -+ found_size += next_frag->len; -+ next_frag = list_entry( -+ next_frag->list.prev, -+ struct mem_fragment, -+ list); -+ } -+ if (found_size >= i->len) { -+ /* Success! there is enough contigous -+ free space */ -+ start_frag = frag; -+ break; -+ } -+ } -+ } /* next frag loop */ -+ /* Couldn't statisfy the request with this -+ largest page size, try a smaller one */ -+ largest_page <<= 2; -+ } -+ if (start_frag == NULL) { -+ /* Couldn't find proper amount of space */ -+ ret = -ENOMEM; -+ goto out; -+ } -+ i->did_create = 1; -+do_map: -+ /* Verify there is sufficient space to do the mapping */ -+ down_write(¤t->mm->mmap_sem); -+ next_addr = usdpaa_get_unmapped_area(fp, next_addr, i->len, 0, 0); -+ up_write(¤t->mm->mmap_sem); -+ -+ if (next_addr & ~PAGE_MASK) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ /* We may need to divide the final fragment to accomidate the mapping */ -+ next_frag = start_frag; -+ while (so_far != i->len) { -+ BUG_ON(next_frag->len == 0); -+ while ((next_frag->len + so_far) > i->len) { -+ /* Split frag until they match */ -+ split_frag(next_frag); -+ } -+ so_far += next_frag->len; -+ next_frag->refs++; -+ ++frag_count; -+ next_frag = list_entry(next_frag->list.prev, -+ struct mem_fragment, list); -+ } -+ if (i->did_create) { -+ size_t name_len = 0; -+ start_frag->flags = i->flags; -+ strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX); -+ name_len = strnlen(start_frag->name, USDPAA_DMA_NAME_MAX); -+ if (name_len >= USDPAA_DMA_NAME_MAX) { -+ ret = -EFAULT; -+ goto out; -+ } -+ start_frag->map_len = i->len; -+ start_frag->has_locking = i->has_locking; -+ init_waitqueue_head(&start_frag->wq); -+ start_frag->owner = NULL; -+ } -+ -+ /* Setup the map entry */ -+ map->root_frag = start_frag; -+ map->total_size = i->len; -+ map->frag_count = frag_count; -+ map->refs = 1; -+ list_add(&map->list, &ctx->maps); -+ i->phys_addr = start_frag->base; -+out: -+ spin_unlock(&mem_lock); -+ -+ if (!ret) { -+ unsigned long longret; -+ down_write(¤t->mm->mmap_sem); -+ longret = do_mmap_pgoff(fp, next_addr, map->total_size, -+ PROT_READ | -+ (i->flags & -+ USDPAA_DMA_FLAG_RDONLY ? 0 -+ : PROT_WRITE), -+ MAP_SHARED, -+ start_frag->pfn_base, -+ &populate, -+ NULL); -+ up_write(¤t->mm->mmap_sem); -+ if (longret & ~PAGE_MASK) { -+ ret = (int)longret; -+ } else { -+ i->ptr = (void *)longret; -+ map->virt_addr = i->ptr; -+ } -+ } else -+ kfree(map); -+ return ret; -+} -+ -+static long ioctl_dma_unmap(struct ctx *ctx, void __user *arg) -+{ -+ struct mem_mapping *map; -+ struct vm_area_struct *vma; -+ int ret, i; -+ struct mem_fragment *current_frag; -+ size_t sz; -+ unsigned long base; -+ unsigned long vaddr; -+ -+ down_write(¤t->mm->mmap_sem); -+ vma = find_vma(current->mm, (unsigned long)arg); -+ if (!vma || (vma->vm_start > (unsigned long)arg)) { -+ up_write(¤t->mm->mmap_sem); -+ return -EFAULT; -+ } -+ spin_lock(&mem_lock); -+ list_for_each_entry(map, &ctx->maps, list) { -+ if (map->root_frag->pfn_base == vma->vm_pgoff) { -+ /* Drop the map lock if we hold it */ -+ if (map->root_frag->has_locking && -+ (map->root_frag->owner == map)) { -+ map->root_frag->owner = NULL; -+ wake_up(&map->root_frag->wq); -+ } -+ goto map_match; -+ } -+ } -+ /* Failed to find a matching mapping for this process */ -+ ret = -EFAULT; -+ spin_unlock(&mem_lock); -+ goto out; -+map_match: -+ map->refs--; -+ if (map->refs != 0) { -+ /* Another call the dma_map is referencing this */ -+ ret = 0; -+ spin_unlock(&mem_lock); -+ goto out; -+ } -+ -+ current_frag = map->root_frag; -+ vaddr = (unsigned long) map->virt_addr; -+ for (i = 0; i < map->frag_count; i++) { -+ DPA_ASSERT(current_frag->refs > 0); -+ --current_frag->refs; -+#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64)) -+ /* -+ * Make sure we invalidate the TLB entry for -+ * this fragment, otherwise a remap of a different -+ * page to this vaddr would give acces to an -+ * incorrect piece of memory -+ */ -+ cleartlbcam(vaddr, mfspr(SPRN_PID)); -+#endif -+ vaddr += current_frag->len; -+ current_frag = list_entry(current_frag->list.prev, -+ struct mem_fragment, list); -+ } -+ map->root_frag->name[0] = 0; -+ list_del(&map->list); -+ compress_frags(); -+ spin_unlock(&mem_lock); -+ -+ base = vma->vm_start; -+ sz = vma->vm_end - vma->vm_start; -+ do_munmap(current->mm, base, sz, NULL); -+ ret = 0; -+ out: -+ up_write(¤t->mm->mmap_sem); -+ return ret; -+} -+ -+static long ioctl_dma_stats(struct ctx *ctx, void __user *arg) -+{ -+ struct mem_fragment *frag; -+ struct usdpaa_ioctl_dma_used result; -+ -+ result.free_bytes = 0; -+ result.total_bytes = phys_size; -+ -+ list_for_each_entry(frag, &mem_list, list) { -+ if (frag->refs == 0) -+ result.free_bytes += frag->len; -+ } -+ -+ return copy_to_user(arg, &result, sizeof(result)); } -+ -+static int test_lock(struct mem_mapping *map) -+{ -+ int ret = 0; -+ spin_lock(&mem_lock); -+ if (!map->root_frag->owner) { -+ map->root_frag->owner = map; -+ ret = 1; -+ } -+ spin_unlock(&mem_lock); -+ return ret; -+} -+ -+static long ioctl_dma_lock(struct ctx *ctx, void __user *arg) -+{ -+ struct mem_mapping *map; -+ struct vm_area_struct *vma; -+ -+ down_read(¤t->mm->mmap_sem); -+ vma = find_vma(current->mm, (unsigned long)arg); -+ if (!vma || (vma->vm_start > (unsigned long)arg)) { -+ up_read(¤t->mm->mmap_sem); -+ return -EFAULT; -+ } -+ spin_lock(&mem_lock); -+ list_for_each_entry(map, &ctx->maps, list) { -+ if (map->root_frag->pfn_base == vma->vm_pgoff) -+ goto map_match; -+ } -+ map = NULL; -+map_match: -+ spin_unlock(&mem_lock); -+ up_read(¤t->mm->mmap_sem); -+ -+ if (!map) -+ return -EFAULT; -+ if (!map->root_frag->has_locking) -+ return -ENODEV; -+ return wait_event_interruptible(map->root_frag->wq, test_lock(map)); -+} -+ -+static long ioctl_dma_unlock(struct ctx *ctx, void __user *arg) -+{ -+ struct mem_mapping *map; -+ struct vm_area_struct *vma; -+ int ret; -+ -+ down_read(¤t->mm->mmap_sem); -+ vma = find_vma(current->mm, (unsigned long)arg); -+ if (!vma || (vma->vm_start > (unsigned long)arg)) -+ ret = -EFAULT; -+ else { -+ spin_lock(&mem_lock); -+ list_for_each_entry(map, &ctx->maps, list) { -+ if (map->root_frag->pfn_base == vma->vm_pgoff) { -+ if (!map->root_frag->has_locking) -+ ret = -ENODEV; -+ else if (map->root_frag->owner == map) { -+ map->root_frag->owner = NULL; -+ wake_up(&map->root_frag->wq); -+ ret = 0; -+ } else -+ ret = -EBUSY; -+ goto map_match; -+ } -+ } -+ ret = -EINVAL; -+map_match: -+ spin_unlock(&mem_lock); -+ } -+ up_read(¤t->mm->mmap_sem); -+ return ret; -+} -+ -+static int portal_mmap(struct file *fp, struct resource *res, void **ptr) -+{ -+ unsigned long longret = 0, populate; -+ resource_size_t len; -+ -+ down_write(¤t->mm->mmap_sem); -+ len = resource_size(res); -+ if (len != (unsigned long)len) -+ return -EINVAL; -+ longret = do_mmap_pgoff(fp, PAGE_SIZE, (unsigned long)len, -+ PROT_READ | PROT_WRITE, MAP_SHARED, -+ res->start >> PAGE_SHIFT, &populate, NULL); -+ up_write(¤t->mm->mmap_sem); -+ -+ if (longret & ~PAGE_MASK) -+ return (int)longret; -+ -+ *ptr = (void *) longret; -+ return 0; -+} -+ -+static void portal_munmap(struct resource *res, void *ptr) -+{ -+ down_write(¤t->mm->mmap_sem); -+ do_munmap(current->mm, (unsigned long)ptr, resource_size(res), NULL); -+ up_write(¤t->mm->mmap_sem); -+} -+ -+static long ioctl_portal_map(struct file *fp, struct ctx *ctx, -+ struct usdpaa_ioctl_portal_map *arg) -+{ -+ struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); -+ int ret; -+ -+ if (!mapping) -+ return -ENOMEM; -+ -+ mapping->user = *arg; -+ mapping->iommu_domain = NULL; -+ -+ if (mapping->user.type == usdpaa_portal_qman) { -+ mapping->qportal = -+ qm_get_unused_portal_idx(mapping->user.index); -+ if (!mapping->qportal) { -+ ret = -ENODEV; -+ goto err_get_portal; -+ } -+ mapping->phys = &mapping->qportal->addr_phys[0]; -+ mapping->user.channel = mapping->qportal->public_cfg.channel; -+ mapping->user.pools = mapping->qportal->public_cfg.pools; -+ mapping->user.index = mapping->qportal->public_cfg.index; -+ } else if (mapping->user.type == usdpaa_portal_bman) { -+ mapping->bportal = -+ bm_get_unused_portal_idx(mapping->user.index); -+ if (!mapping->bportal) { -+ ret = -ENODEV; -+ goto err_get_portal; -+ } -+ mapping->phys = &mapping->bportal->addr_phys[0]; -+ mapping->user.index = mapping->bportal->public_cfg.index; -+ } else { -+ ret = -EINVAL; -+ goto err_copy_from_user; -+ } -+ /* Need to put pcfg in ctx's list before the mmaps because the mmap -+ * handlers look it up. */ -+ spin_lock(&mem_lock); -+ list_add(&mapping->list, &ctx->portals); -+ spin_unlock(&mem_lock); -+ ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CE], -+ &mapping->user.addr.cena); -+ if (ret) -+ goto err_mmap_cena; -+ ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CI], -+ &mapping->user.addr.cinh); -+ if (ret) -+ goto err_mmap_cinh; -+ *arg = mapping->user; -+ return ret; -+ -+err_mmap_cinh: -+ portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena); -+err_mmap_cena: -+ if ((mapping->user.type == usdpaa_portal_qman) && mapping->qportal) -+ qm_put_unused_portal(mapping->qportal); -+ else if ((mapping->user.type == usdpaa_portal_bman) && mapping->bportal) -+ bm_put_unused_portal(mapping->bportal); -+ spin_lock(&mem_lock); -+ list_del(&mapping->list); -+ spin_unlock(&mem_lock); -+err_get_portal: -+err_copy_from_user: -+ kfree(mapping); -+ return ret; -+} -+ -+static long ioctl_portal_unmap(struct ctx *ctx, struct usdpaa_portal_map *i) -+{ -+ struct portal_mapping *mapping; -+ struct vm_area_struct *vma; -+ unsigned long pfn; -+ u32 channel; -+ -+ /* Get the PFN corresponding to one of the virt addresses */ -+ down_read(¤t->mm->mmap_sem); -+ vma = find_vma(current->mm, (unsigned long)i->cinh); -+ if (!vma || (vma->vm_start > (unsigned long)i->cinh)) { -+ up_read(¤t->mm->mmap_sem); -+ return -EFAULT; -+ } -+ pfn = vma->vm_pgoff; -+ up_read(¤t->mm->mmap_sem); -+ -+ /* Find the corresponding portal */ -+ spin_lock(&mem_lock); -+ list_for_each_entry(mapping, &ctx->portals, list) { -+ if (pfn == (mapping->phys[DPA_PORTAL_CI].start >> PAGE_SHIFT)) -+ goto found; -+ } -+ mapping = NULL; -+found: -+ if (mapping) -+ list_del(&mapping->list); -+ spin_unlock(&mem_lock); -+ if (!mapping) -+ return -ENODEV; -+ portal_munmap(&mapping->phys[DPA_PORTAL_CI], mapping->user.addr.cinh); -+ portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena); -+ if (mapping->user.type == usdpaa_portal_qman) { -+ init_qm_portal(mapping->qportal, -+ &mapping->qman_portal_low); -+ -+ /* Tear down any FQs this portal is referencing */ -+ channel = mapping->qportal->public_cfg.channel; -+ qm_check_and_destroy_fqs(&mapping->qman_portal_low, -+ &channel, -+ check_portal_channel); -+ qm_put_unused_portal(mapping->qportal); -+ } else if (mapping->user.type == usdpaa_portal_bman) { -+ init_bm_portal(mapping->bportal, -+ &mapping->bman_portal_low); -+ bm_put_unused_portal(mapping->bportal); -+ } -+ kfree(mapping); -+ return 0; -+} -+ -+static void portal_config_pamu(struct qm_portal_config *pcfg, uint8_t sdest, -+ uint32_t cpu, uint32_t cache, uint32_t window) -+{ -+#ifdef CONFIG_FSL_PAMU -+ int ret; -+ int window_count = 1; -+ struct iommu_domain_geometry geom_attr; -+ struct pamu_stash_attribute stash_attr; -+ -+ pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type); -+ if (!pcfg->iommu_domain) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed", -+ __func__); -+ goto _no_iommu; -+ } -+ geom_attr.aperture_start = 0; -+ geom_attr.aperture_end = -+ ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1; -+ geom_attr.force_aperture = true; -+ ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY, -+ &geom_attr); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d", -+ __func__, ret); -+ goto _iommu_domain_free; -+ } -+ ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS, -+ &window_count); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d", -+ __func__, ret); -+ goto _iommu_domain_free; -+ } -+ stash_attr.cpu = cpu; -+ stash_attr.cache = cache; -+ /* set stash information for the window */ -+ stash_attr.window = 0; -+ -+ ret = iommu_domain_set_attr(pcfg->iommu_domain, -+ DOMAIN_ATTR_FSL_PAMU_STASH, -+ &stash_attr); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d", -+ __func__, ret); -+ goto _iommu_domain_free; -+ } -+ ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36, -+ IOMMU_READ | IOMMU_WRITE); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d", -+ __func__, ret); -+ goto _iommu_domain_free; -+ } -+ ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d", -+ __func__, ret); -+ goto _iommu_domain_free; -+ } -+ ret = iommu_domain_set_attr(pcfg->iommu_domain, -+ DOMAIN_ATTR_FSL_PAMU_ENABLE, -+ &window_count); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d", -+ __func__, ret); -+ goto _iommu_detach_device; -+ } -+_no_iommu: -+#endif -+ -+#ifdef CONFIG_FSL_QMAN_CONFIG -+ if (qman_set_sdest(pcfg->public_cfg.channel, sdest)) -+#endif -+ pr_warn("Failed to set QMan portal's stash request queue\n"); -+ -+ return; -+ -+#ifdef CONFIG_FSL_PAMU -+_iommu_detach_device: -+ iommu_detach_device(pcfg->iommu_domain, NULL); -+_iommu_domain_free: -+ iommu_domain_free(pcfg->iommu_domain); -+#endif -+} -+ -+static long ioctl_allocate_raw_portal(struct file *fp, struct ctx *ctx, -+ struct usdpaa_ioctl_raw_portal *arg) -+{ -+ struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); -+ int ret; -+ -+ if (!mapping) -+ return -ENOMEM; -+ -+ mapping->user.type = arg->type; -+ mapping->iommu_domain = NULL; -+ if (arg->type == usdpaa_portal_qman) { -+ mapping->qportal = qm_get_unused_portal_idx(arg->index); -+ if (!mapping->qportal) { -+ ret = -ENODEV; -+ goto err; -+ } -+ mapping->phys = &mapping->qportal->addr_phys[0]; -+ arg->index = mapping->qportal->public_cfg.index; -+ arg->cinh = mapping->qportal->addr_phys[DPA_PORTAL_CI].start; -+ arg->cena = mapping->qportal->addr_phys[DPA_PORTAL_CE].start; -+ if (arg->enable_stash) { -+ /* Setup the PAMU with the supplied parameters */ -+ portal_config_pamu(mapping->qportal, arg->sdest, -+ arg->cpu, arg->cache, arg->window); -+ } -+ } else if (mapping->user.type == usdpaa_portal_bman) { -+ mapping->bportal = -+ bm_get_unused_portal_idx(arg->index); -+ if (!mapping->bportal) { -+ ret = -ENODEV; -+ goto err; -+ } -+ mapping->phys = &mapping->bportal->addr_phys[0]; -+ arg->index = mapping->bportal->public_cfg.index; -+ arg->cinh = mapping->bportal->addr_phys[DPA_PORTAL_CI].start; -+ arg->cena = mapping->bportal->addr_phys[DPA_PORTAL_CE].start; -+ } else { -+ ret = -EINVAL; -+ goto err; -+ } -+ /* Need to put pcfg in ctx's list before the mmaps because the mmap -+ * handlers look it up. */ -+ spin_lock(&mem_lock); -+ list_add(&mapping->list, &ctx->portals); -+ spin_unlock(&mem_lock); -+ return 0; -+err: -+ kfree(mapping); -+ return ret; -+} -+ -+static long ioctl_free_raw_portal(struct file *fp, struct ctx *ctx, -+ struct usdpaa_ioctl_raw_portal *arg) -+{ -+ struct portal_mapping *mapping; -+ u32 channel; -+ -+ /* Find the corresponding portal */ -+ spin_lock(&mem_lock); -+ list_for_each_entry(mapping, &ctx->portals, list) { -+ if (mapping->phys[DPA_PORTAL_CI].start == arg->cinh) -+ goto found; -+ } -+ mapping = NULL; -+found: -+ if (mapping) -+ list_del(&mapping->list); -+ spin_unlock(&mem_lock); -+ if (!mapping) -+ return -ENODEV; -+ if (mapping->user.type == usdpaa_portal_qman) { -+ init_qm_portal(mapping->qportal, -+ &mapping->qman_portal_low); -+ -+ /* Tear down any FQs this portal is referencing */ -+ channel = mapping->qportal->public_cfg.channel; -+ qm_check_and_destroy_fqs(&mapping->qman_portal_low, -+ &channel, -+ check_portal_channel); -+ qm_put_unused_portal(mapping->qportal); -+ } else if (mapping->user.type == usdpaa_portal_bman) { -+ init_bm_portal(mapping->bportal, -+ &mapping->bman_portal_low); -+ bm_put_unused_portal(mapping->bportal); -+ } -+ kfree(mapping); -+ return 0; -+} -+ -+static long usdpaa_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) -+{ -+ struct ctx *ctx = fp->private_data; -+ void __user *a = (void __user *)arg; -+ switch (cmd) { -+ case USDPAA_IOCTL_ID_ALLOC: -+ return ioctl_id_alloc(ctx, a); -+ case USDPAA_IOCTL_ID_RELEASE: -+ return ioctl_id_release(ctx, a); -+ case USDPAA_IOCTL_ID_RESERVE: -+ return ioctl_id_reserve(ctx, a); -+ case USDPAA_IOCTL_DMA_MAP: -+ { -+ struct usdpaa_ioctl_dma_map input; -+ int ret; -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ ret = ioctl_dma_map(fp, ctx, &input); -+ if (copy_to_user(a, &input, sizeof(input))) -+ return -EFAULT; -+ return ret; -+ } -+ case USDPAA_IOCTL_DMA_UNMAP: -+ return ioctl_dma_unmap(ctx, a); -+ case USDPAA_IOCTL_DMA_LOCK: -+ return ioctl_dma_lock(ctx, a); -+ case USDPAA_IOCTL_DMA_UNLOCK: -+ return ioctl_dma_unlock(ctx, a); -+ case USDPAA_IOCTL_PORTAL_MAP: -+ { -+ struct usdpaa_ioctl_portal_map input; -+ int ret; -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ ret = ioctl_portal_map(fp, ctx, &input); -+ if (copy_to_user(a, &input, sizeof(input))) -+ return -EFAULT; -+ return ret; -+ } -+ case USDPAA_IOCTL_PORTAL_UNMAP: -+ { -+ struct usdpaa_portal_map input; -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ return ioctl_portal_unmap(ctx, &input); -+ } -+ case USDPAA_IOCTL_DMA_USED: -+ return ioctl_dma_stats(ctx, a); -+ case USDPAA_IOCTL_ALLOC_RAW_PORTAL: -+ { -+ struct usdpaa_ioctl_raw_portal input; -+ int ret; -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ ret = ioctl_allocate_raw_portal(fp, ctx, &input); -+ if (copy_to_user(a, &input, sizeof(input))) -+ return -EFAULT; -+ return ret; -+ } -+ case USDPAA_IOCTL_FREE_RAW_PORTAL: -+ { -+ struct usdpaa_ioctl_raw_portal input; -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ return ioctl_free_raw_portal(fp, ctx, &input); -+ } -+ } -+ return -EINVAL; -+} -+ -+static long usdpaa_ioctl_compat(struct file *fp, unsigned int cmd, -+ unsigned long arg) -+{ -+#ifdef CONFIG_COMPAT -+ struct ctx *ctx = fp->private_data; -+ void __user *a = (void __user *)arg; -+#endif -+ switch (cmd) { -+#ifdef CONFIG_COMPAT -+ case USDPAA_IOCTL_DMA_MAP_COMPAT: -+ { -+ int ret; -+ struct usdpaa_ioctl_dma_map_compat input; -+ struct usdpaa_ioctl_dma_map converted; -+ -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ -+ converted.ptr = compat_ptr(input.ptr); -+ converted.phys_addr = input.phys_addr; -+ converted.len = input.len; -+ converted.flags = input.flags; -+ strncpy(converted.name, input.name, USDPAA_DMA_NAME_MAX); -+ converted.has_locking = input.has_locking; -+ converted.did_create = input.did_create; -+ -+ ret = ioctl_dma_map(fp, ctx, &converted); -+ input.ptr = ptr_to_compat(converted.ptr); -+ input.phys_addr = converted.phys_addr; -+ input.len = converted.len; -+ input.flags = converted.flags; -+ strncpy(input.name, converted.name, USDPAA_DMA_NAME_MAX); -+ input.has_locking = converted.has_locking; -+ input.did_create = converted.did_create; -+ if (copy_to_user(a, &input, sizeof(input))) -+ return -EFAULT; -+ return ret; -+ } -+ case USDPAA_IOCTL_PORTAL_MAP_COMPAT: -+ { -+ int ret; -+ struct compat_usdpaa_ioctl_portal_map input; -+ struct usdpaa_ioctl_portal_map converted; -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ converted.type = input.type; -+ converted.index = input.index; -+ ret = ioctl_portal_map(fp, ctx, &converted); -+ input.addr.cinh = ptr_to_compat(converted.addr.cinh); -+ input.addr.cena = ptr_to_compat(converted.addr.cena); -+ input.channel = converted.channel; -+ input.pools = converted.pools; -+ input.index = converted.index; -+ if (copy_to_user(a, &input, sizeof(input))) -+ return -EFAULT; -+ return ret; -+ } -+ case USDPAA_IOCTL_PORTAL_UNMAP_COMPAT: -+ { -+ struct usdpaa_portal_map_compat input; -+ struct usdpaa_portal_map converted; -+ -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ converted.cinh = compat_ptr(input.cinh); -+ converted.cena = compat_ptr(input.cena); -+ return ioctl_portal_unmap(ctx, &converted); -+ } -+ case USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT: -+ { -+ int ret; -+ struct usdpaa_ioctl_raw_portal converted; -+ struct compat_ioctl_raw_portal input; -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ converted.type = input.type; -+ converted.index = input.index; -+ converted.enable_stash = input.enable_stash; -+ converted.cpu = input.cpu; -+ converted.cache = input.cache; -+ converted.window = input.window; -+ converted.sdest = input.sdest; -+ ret = ioctl_allocate_raw_portal(fp, ctx, &converted); -+ -+ input.cinh = converted.cinh; -+ input.cena = converted.cena; -+ input.index = converted.index; -+ -+ if (copy_to_user(a, &input, sizeof(input))) -+ return -EFAULT; -+ return ret; -+ } -+ case USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT: -+ { -+ struct usdpaa_ioctl_raw_portal converted; -+ struct compat_ioctl_raw_portal input; -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ converted.type = input.type; -+ converted.index = input.index; -+ converted.cinh = input.cinh; -+ converted.cena = input.cena; -+ return ioctl_free_raw_portal(fp, ctx, &converted); -+ } -+#endif -+ default: -+ return usdpaa_ioctl(fp, cmd, arg); -+ } -+ return -EINVAL; -+} -+ -+int usdpaa_get_portal_config(struct file *filp, void *cinh, -+ enum usdpaa_portal_type ptype, unsigned int *irq, -+ void **iir_reg) -+{ -+ /* Walk the list of portals for filp and return the config -+ for the portal that matches the hint */ -+ struct ctx *context; -+ struct portal_mapping *portal; -+ -+ /* First sanitize the filp */ -+ if (filp->f_op->open != usdpaa_open) -+ return -ENODEV; -+ context = filp->private_data; -+ spin_lock(&context->lock); -+ list_for_each_entry(portal, &context->portals, list) { -+ if (portal->user.type == ptype && -+ portal->user.addr.cinh == cinh) { -+ if (ptype == usdpaa_portal_qman) { -+ *irq = portal->qportal->public_cfg.irq; -+ *iir_reg = portal->qportal->addr_virt[1] + -+ QM_REG_IIR; -+ } else { -+ *irq = portal->bportal->public_cfg.irq; -+ *iir_reg = portal->bportal->addr_virt[1] + -+ BM_REG_IIR; -+ } -+ spin_unlock(&context->lock); -+ return 0; -+ } -+ } -+ spin_unlock(&context->lock); -+ return -EINVAL; -+} -+ -+static const struct file_operations usdpaa_fops = { -+ .open = usdpaa_open, -+ .release = usdpaa_release, -+ .mmap = usdpaa_mmap, -+ .get_unmapped_area = usdpaa_get_unmapped_area, -+ .unlocked_ioctl = usdpaa_ioctl, -+ .compat_ioctl = usdpaa_ioctl_compat -+}; -+ -+static struct miscdevice usdpaa_miscdev = { -+ .name = "fsl-usdpaa", -+ .fops = &usdpaa_fops, -+ .minor = MISC_DYNAMIC_MINOR, -+}; -+ -+/* Early-boot memory allocation. The boot-arg "usdpaa_mem=" is used to -+ * indicate how much memory (if any) to allocate during early boot. If the -+ * format "usdpaa_mem=," is used, then will be interpreted as the -+ * number of TLB1 entries to reserve (default is 1). If there are more mappings -+ * than there are TLB1 entries, fault-handling will occur. */ -+ -+static __init int usdpaa_mem(char *arg) -+{ -+ pr_warn("uspdaa_mem argument is depracated\n"); -+ arg_phys_size = memparse(arg, &arg); -+ num_tlb = 1; -+ if (*arg == ',') { -+ unsigned long ul; -+ int err = kstrtoul(arg + 1, 0, &ul); -+ if (err < 0) { -+ num_tlb = 1; -+ pr_warn("ERROR, usdpaa_mem arg is invalid\n"); -+ } else -+ num_tlb = (unsigned int)ul; -+ } -+ return 0; -+} -+early_param("usdpaa_mem", usdpaa_mem); -+ -+static int usdpaa_mem_init(struct reserved_mem *rmem) -+{ -+ phys_start = rmem->base; -+ phys_size = rmem->size; -+ -+ WARN_ON(!(phys_start && phys_size)); -+ -+ return 0; -+} -+RESERVEDMEM_OF_DECLARE(usdpaa_mem_init, "fsl,usdpaa-mem", usdpaa_mem_init); -+ -+__init int fsl_usdpaa_init_early(void) -+{ -+ if (!phys_size || !phys_start) { -+ pr_info("No USDPAA memory, no 'fsl,usdpaa-mem' in device-tree\n"); -+ return 0; -+ } -+ if (phys_size % PAGE_SIZE) { -+ pr_err("'fsl,usdpaa-mem' size must be a multiple of page size\n"); -+ phys_size = 0; -+ return 0; -+ } -+ if (arg_phys_size && phys_size != arg_phys_size) { -+ pr_err("'usdpaa_mem argument size (0x%llx) does not match device tree size (0x%llx)\n", -+ arg_phys_size, phys_size); -+ phys_size = 0; -+ return 0; -+ } -+ pfn_start = phys_start >> PAGE_SHIFT; -+ pfn_size = phys_size >> PAGE_SHIFT; -+#ifdef CONFIG_PPC -+ first_tlb = current_tlb = tlbcam_index; -+ tlbcam_index += num_tlb; -+#endif -+ pr_info("USDPAA region at %llx:%llx(%lx:%lx), %d TLB1 entries)\n", -+ phys_start, phys_size, pfn_start, pfn_size, num_tlb); -+ return 0; -+} -+subsys_initcall(fsl_usdpaa_init_early); -+ -+ -+static int __init usdpaa_init(void) -+{ -+ struct mem_fragment *frag; -+ int ret; -+ u64 tmp_size = phys_size; -+ u64 tmp_start = phys_start; -+ u64 tmp_pfn_size = pfn_size; -+ u64 tmp_pfn_start = pfn_start; -+ -+ pr_info("Freescale USDPAA process driver\n"); -+ if (!phys_start) { -+ pr_warn("fsl-usdpaa: no region found\n"); -+ return 0; -+ } -+ -+ while (tmp_size != 0) { -+ u32 frag_size = largest_page_size(tmp_size); -+ frag = kmalloc(sizeof(*frag), GFP_KERNEL); -+ if (!frag) { -+ pr_err("Failed to setup USDPAA memory accounting\n"); -+ return -ENOMEM; -+ } -+ frag->base = tmp_start; -+ frag->len = frag->root_len = frag_size; -+ frag->root_pfn = tmp_pfn_start; -+ frag->pfn_base = tmp_pfn_start; -+ frag->pfn_len = frag_size / PAGE_SIZE; -+ frag->refs = 0; -+ init_waitqueue_head(&frag->wq); -+ frag->owner = NULL; -+ list_add(&frag->list, &mem_list); -+ -+ /* Adjust for this frag */ -+ tmp_start += frag_size; -+ tmp_size -= frag_size; -+ tmp_pfn_start += frag_size / PAGE_SIZE; -+ tmp_pfn_size -= frag_size / PAGE_SIZE; -+ } -+ ret = misc_register(&usdpaa_miscdev); -+ if (ret) -+ pr_err("fsl-usdpaa: failed to register misc device\n"); -+ return ret; -+} -+ -+static void __exit usdpaa_exit(void) -+{ -+ misc_deregister(&usdpaa_miscdev); -+} -+ -+module_init(usdpaa_init); -+module_exit(usdpaa_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Freescale Semiconductor"); -+MODULE_DESCRIPTION("Freescale USDPAA process driver"); ---- /dev/null -+++ b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c -@@ -0,0 +1,289 @@ -+/* Copyright (c) 2013 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* define a device that allows USPDAA processes to open a file -+ descriptor and specify which IRQ it wants to montior using an ioctl() -+ When an IRQ is received, the device becomes readable so that a process -+ can use read() or select() type calls to monitor for IRQs */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "qman_low.h" -+#include "bman_low.h" -+ -+struct usdpaa_irq_ctx { -+ int irq_set; /* Set to true once the irq is set via ioctl */ -+ unsigned int irq_num; -+ u32 last_irq_count; /* Last value returned from read */ -+ u32 irq_count; /* Number of irqs since last read */ -+ wait_queue_head_t wait_queue; /* Waiting processes */ -+ spinlock_t lock; -+ void *inhibit_addr; /* inhibit register address */ -+ struct file *usdpaa_filp; -+ char irq_name[128]; -+}; -+ -+static int usdpaa_irq_open(struct inode *inode, struct file *filp) -+{ -+ struct usdpaa_irq_ctx *ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); -+ if (!ctx) -+ return -ENOMEM; -+ ctx->irq_set = 0; -+ ctx->irq_count = 0; -+ ctx->last_irq_count = 0; -+ init_waitqueue_head(&ctx->wait_queue); -+ spin_lock_init(&ctx->lock); -+ filp->private_data = ctx; -+ return 0; -+} -+ -+static int usdpaa_irq_release(struct inode *inode, struct file *filp) -+{ -+ struct usdpaa_irq_ctx *ctx = filp->private_data; -+ if (ctx->irq_set) { -+ /* Inhibit the IRQ */ -+ out_be32(ctx->inhibit_addr, 0x1); -+ irq_set_affinity_hint(ctx->irq_num, NULL); -+ free_irq(ctx->irq_num, ctx); -+ ctx->irq_set = 0; -+ fput(ctx->usdpaa_filp); -+ } -+ kfree(filp->private_data); -+ return 0; -+} -+ -+static irqreturn_t usdpaa_irq_handler(int irq, void *_ctx) -+{ -+ unsigned long flags; -+ struct usdpaa_irq_ctx *ctx = _ctx; -+ spin_lock_irqsave(&ctx->lock, flags); -+ ++ctx->irq_count; -+ spin_unlock_irqrestore(&ctx->lock, flags); -+ wake_up_all(&ctx->wait_queue); -+ /* Set the inhibit register. This will be reenabled -+ once the USDPAA code handles the IRQ */ -+ out_be32(ctx->inhibit_addr, 0x1); -+ pr_info("Inhibit at %p count %d", ctx->inhibit_addr, ctx->irq_count); -+ return IRQ_HANDLED; -+} -+ -+static int map_irq(struct file *fp, struct usdpaa_ioctl_irq_map *irq_map) -+{ -+ struct usdpaa_irq_ctx *ctx = fp->private_data; -+ int ret; -+ -+ if (ctx->irq_set) { -+ pr_debug("Setting USDPAA IRQ when it was already set!\n"); -+ return -EBUSY; -+ } -+ -+ ctx->usdpaa_filp = fget(irq_map->fd); -+ if (!ctx->usdpaa_filp) { -+ pr_debug("USDPAA fget(%d) returned NULL\n", irq_map->fd); -+ return -EINVAL; -+ } -+ -+ ret = usdpaa_get_portal_config(ctx->usdpaa_filp, irq_map->portal_cinh, -+ irq_map->type, &ctx->irq_num, -+ &ctx->inhibit_addr); -+ if (ret) { -+ pr_debug("USDPAA IRQ couldn't identify portal\n"); -+ fput(ctx->usdpaa_filp); -+ return ret; -+ } -+ -+ ctx->irq_set = 1; -+ -+ snprintf(ctx->irq_name, sizeof(ctx->irq_name), -+ "usdpaa_irq %d", ctx->irq_num); -+ -+ ret = request_irq(ctx->irq_num, usdpaa_irq_handler, 0, -+ ctx->irq_name, ctx); -+ if (ret) { -+ pr_err("USDPAA request_irq(%d) failed, ret= %d\n", -+ ctx->irq_num, ret); -+ ctx->irq_set = 0; -+ fput(ctx->usdpaa_filp); -+ return ret; -+ } -+ ret = irq_set_affinity(ctx->irq_num, ¤t->cpus_allowed); -+ if (ret) -+ pr_err("USDPAA irq_set_affinity() failed, ret= %d\n", ret); -+ -+ ret = irq_set_affinity_hint(ctx->irq_num, ¤t->cpus_allowed); -+ if (ret) -+ pr_err("USDPAA irq_set_affinity_hint() failed, ret= %d\n", ret); -+ -+ return 0; -+} -+ -+static long usdpaa_irq_ioctl(struct file *fp, unsigned int cmd, -+ unsigned long arg) -+{ -+ int ret; -+ struct usdpaa_ioctl_irq_map irq_map; -+ -+ if (cmd != USDPAA_IOCTL_PORTAL_IRQ_MAP) { -+ pr_debug("USDPAA IRQ unknown command 0x%x\n", cmd); -+ return -EINVAL; -+ } -+ -+ ret = copy_from_user(&irq_map, (void __user *)arg, -+ sizeof(irq_map)); -+ if (ret) -+ return ret; -+ return map_irq(fp, &irq_map); -+} -+ -+static ssize_t usdpaa_irq_read(struct file *filp, char __user *buff, -+ size_t count, loff_t *offp) -+{ -+ struct usdpaa_irq_ctx *ctx = filp->private_data; -+ int ret; -+ -+ if (!ctx->irq_set) { -+ pr_debug("Reading USDPAA IRQ before it was set\n"); -+ return -EINVAL; -+ } -+ -+ if (count < sizeof(ctx->irq_count)) { -+ pr_debug("USDPAA IRQ Read too small\n"); -+ return -EINVAL; -+ } -+ if (ctx->irq_count == ctx->last_irq_count) { -+ if (filp->f_flags & O_NONBLOCK) -+ return -EAGAIN; -+ -+ ret = wait_event_interruptible(ctx->wait_queue, -+ ctx->irq_count != ctx->last_irq_count); -+ if (ret == -ERESTARTSYS) -+ return ret; -+ } -+ -+ ctx->last_irq_count = ctx->irq_count; -+ -+ if (copy_to_user(buff, &ctx->last_irq_count, -+ sizeof(ctx->last_irq_count))) -+ return -EFAULT; -+ return sizeof(ctx->irq_count); -+} -+ -+static unsigned int usdpaa_irq_poll(struct file *filp, poll_table *wait) -+{ -+ struct usdpaa_irq_ctx *ctx = filp->private_data; -+ unsigned int ret = 0; -+ unsigned long flags; -+ -+ if (!ctx->irq_set) -+ return POLLHUP; -+ -+ poll_wait(filp, &ctx->wait_queue, wait); -+ -+ spin_lock_irqsave(&ctx->lock, flags); -+ if (ctx->irq_count != ctx->last_irq_count) -+ ret |= POLLIN | POLLRDNORM; -+ spin_unlock_irqrestore(&ctx->lock, flags); -+ return ret; -+} -+ -+static long usdpaa_irq_ioctl_compat(struct file *fp, unsigned int cmd, -+ unsigned long arg) -+{ -+#ifdef CONFIG_COMPAT -+ void __user *a = (void __user *)arg; -+#endif -+ switch (cmd) { -+#ifdef CONFIG_COMPAT -+ case USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT: -+ { -+ struct compat_ioctl_irq_map input; -+ struct usdpaa_ioctl_irq_map converted; -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ converted.type = input.type; -+ converted.fd = input.fd; -+ converted.portal_cinh = compat_ptr(input.portal_cinh); -+ return map_irq(fp, &converted); -+ } -+#endif -+ default: -+ return usdpaa_irq_ioctl(fp, cmd, arg); -+ } -+} -+ -+static const struct file_operations usdpaa_irq_fops = { -+ .open = usdpaa_irq_open, -+ .release = usdpaa_irq_release, -+ .unlocked_ioctl = usdpaa_irq_ioctl, -+ .compat_ioctl = usdpaa_irq_ioctl_compat, -+ .read = usdpaa_irq_read, -+ .poll = usdpaa_irq_poll -+}; -+ -+static struct miscdevice usdpaa_miscdev = { -+ .name = "fsl-usdpaa-irq", -+ .fops = &usdpaa_irq_fops, -+ .minor = MISC_DYNAMIC_MINOR, -+}; -+ -+static int __init usdpaa_irq_init(void) -+{ -+ int ret; -+ -+ pr_info("Freescale USDPAA process IRQ driver\n"); -+ ret = misc_register(&usdpaa_miscdev); -+ if (ret) -+ pr_err("fsl-usdpaa-irq: failed to register misc device\n"); -+ return ret; -+} -+ -+static void __exit usdpaa_irq_exit(void) -+{ -+ misc_deregister(&usdpaa_miscdev); -+} -+ -+module_init(usdpaa_irq_init); -+module_exit(usdpaa_irq_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Freescale Semiconductor"); -+MODULE_DESCRIPTION("Freescale USDPAA process IRQ driver"); ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qbman_driver.c -@@ -0,0 +1,88 @@ -+/* Copyright 2013 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include "qman_private.h" -+#include "bman_private.h" -+__init void qman_init_early(void); -+__init void bman_init_early(void); -+ -+static __init int qbman_init(void) -+{ -+ struct device_node *dn; -+ u32 is_portal_available; -+ -+ bman_init(); -+ qman_init(); -+ -+ is_portal_available = 0; -+ for_each_compatible_node(dn, NULL, "fsl,qman-portal") { -+ if (!of_device_is_available(dn)) -+ continue; -+ else -+ is_portal_available = 1; -+ } -+ -+ if (!qman_have_ccsr() && is_portal_available) { -+ struct qman_fq fq = { -+ .fqid = 1 -+ }; -+ struct qm_mcr_queryfq_np np; -+ int err, retry = CONFIG_FSL_QMAN_INIT_TIMEOUT; -+ struct timespec nowts, diffts, startts = current_kernel_time(); -+ /* Loop while querying given fqid succeeds or time out */ -+ while (1) { -+ err = qman_query_fq_np(&fq, &np); -+ if (!err) { -+ /* success, control-plane has configured QMan */ -+ break; -+ } else if (err != -ERANGE) { -+ pr_err("QMan: I/O error, continuing anyway\n"); -+ break; -+ } -+ nowts = current_kernel_time(); -+ diffts = timespec_sub(nowts, startts); -+ if (diffts.tv_sec > 0) { -+ if (!retry--) { -+ pr_err("QMan: time out, control-plane" -+ " dead?\n"); -+ break; -+ } -+ pr_warn("QMan: polling for the control-plane" -+ " (%d)\n", retry); -+ } -+ } -+ } -+ bman_resource_init(); -+ qman_resource_init(); -+ return 0; -+} -+subsys_initcall(qbman_init); ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_config.c -@@ -0,0 +1,1224 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include "qman_private.h" -+#include -+#include -+ -+/* Last updated for v00.800 of the BG */ -+ -+/* Register offsets */ -+#define REG_QCSP_LIO_CFG(n) (0x0000 + ((n) * 0x10)) -+#define REG_QCSP_IO_CFG(n) (0x0004 + ((n) * 0x10)) -+#define REG_QCSP_DD_CFG(n) (0x000c + ((n) * 0x10)) -+#define REG_DD_CFG 0x0200 -+#define REG_DCP_CFG(n) (0x0300 + ((n) * 0x10)) -+#define REG_DCP_DD_CFG(n) (0x0304 + ((n) * 0x10)) -+#define REG_DCP_DLM_AVG(n) (0x030c + ((n) * 0x10)) -+#define REG_PFDR_FPC 0x0400 -+#define REG_PFDR_FP_HEAD 0x0404 -+#define REG_PFDR_FP_TAIL 0x0408 -+#define REG_PFDR_FP_LWIT 0x0410 -+#define REG_PFDR_CFG 0x0414 -+#define REG_SFDR_CFG 0x0500 -+#define REG_SFDR_IN_USE 0x0504 -+#define REG_WQ_CS_CFG(n) (0x0600 + ((n) * 0x04)) -+#define REG_WQ_DEF_ENC_WQID 0x0630 -+#define REG_WQ_SC_DD_CFG(n) (0x640 + ((n) * 0x04)) -+#define REG_WQ_PC_DD_CFG(n) (0x680 + ((n) * 0x04)) -+#define REG_WQ_DC0_DD_CFG(n) (0x6c0 + ((n) * 0x04)) -+#define REG_WQ_DC1_DD_CFG(n) (0x700 + ((n) * 0x04)) -+#define REG_WQ_DCn_DD_CFG(n) (0x6c0 + ((n) * 0x40)) /* n=2,3 */ -+#define REG_CM_CFG 0x0800 -+#define REG_ECSR 0x0a00 -+#define REG_ECIR 0x0a04 -+#define REG_EADR 0x0a08 -+#define REG_ECIR2 0x0a0c -+#define REG_EDATA(n) (0x0a10 + ((n) * 0x04)) -+#define REG_SBEC(n) (0x0a80 + ((n) * 0x04)) -+#define REG_MCR 0x0b00 -+#define REG_MCP(n) (0x0b04 + ((n) * 0x04)) -+#define REG_MISC_CFG 0x0be0 -+#define REG_HID_CFG 0x0bf0 -+#define REG_IDLE_STAT 0x0bf4 -+#define REG_IP_REV_1 0x0bf8 -+#define REG_IP_REV_2 0x0bfc -+#define REG_FQD_BARE 0x0c00 -+#define REG_PFDR_BARE 0x0c20 -+#define REG_offset_BAR 0x0004 /* relative to REG_[FQD|PFDR]_BARE */ -+#define REG_offset_AR 0x0010 /* relative to REG_[FQD|PFDR]_BARE */ -+#define REG_QCSP_BARE 0x0c80 -+#define REG_QCSP_BAR 0x0c84 -+#define REG_CI_SCHED_CFG 0x0d00 -+#define REG_SRCIDR 0x0d04 -+#define REG_LIODNR 0x0d08 -+#define REG_CI_RLM_AVG 0x0d14 -+#define REG_ERR_ISR 0x0e00 /* + "enum qm_isr_reg" */ -+#define REG_REV3_QCSP_LIO_CFG(n) (0x1000 + ((n) * 0x10)) -+#define REG_REV3_QCSP_IO_CFG(n) (0x1004 + ((n) * 0x10)) -+#define REG_REV3_QCSP_DD_CFG(n) (0x100c + ((n) * 0x10)) -+#define REG_CEETM_CFG_IDX 0x900 -+#define REG_CEETM_CFG_PRES 0x904 -+#define REG_CEETM_XSFDR_IN_USE 0x908 -+ -+/* Assists for QMAN_MCR */ -+#define MCR_INIT_PFDR 0x01000000 -+#define MCR_get_rslt(v) (u8)((v) >> 24) -+#define MCR_rslt_idle(r) (!rslt || (rslt >= 0xf0)) -+#define MCR_rslt_ok(r) (rslt == 0xf0) -+#define MCR_rslt_eaccess(r) (rslt == 0xf8) -+#define MCR_rslt_inval(r) (rslt == 0xff) -+ -+struct qman; -+ -+/* Follows WQ_CS_CFG0-5 */ -+enum qm_wq_class { -+ qm_wq_portal = 0, -+ qm_wq_pool = 1, -+ qm_wq_fman0 = 2, -+ qm_wq_fman1 = 3, -+ qm_wq_caam = 4, -+ qm_wq_pme = 5, -+ qm_wq_first = qm_wq_portal, -+ qm_wq_last = qm_wq_pme -+}; -+ -+/* Follows FQD_[BARE|BAR|AR] and PFDR_[BARE|BAR|AR] */ -+enum qm_memory { -+ qm_memory_fqd, -+ qm_memory_pfdr -+}; -+ -+/* Used by all error interrupt registers except 'inhibit' */ -+#define QM_EIRQ_CIDE 0x20000000 /* Corenet Initiator Data Error */ -+#define QM_EIRQ_CTDE 0x10000000 /* Corenet Target Data Error */ -+#define QM_EIRQ_CITT 0x08000000 /* Corenet Invalid Target Transaction */ -+#define QM_EIRQ_PLWI 0x04000000 /* PFDR Low Watermark */ -+#define QM_EIRQ_MBEI 0x02000000 /* Multi-bit ECC Error */ -+#define QM_EIRQ_SBEI 0x01000000 /* Single-bit ECC Error */ -+#define QM_EIRQ_PEBI 0x00800000 /* PFDR Enqueues Blocked Interrupt */ -+#define QM_EIRQ_IFSI 0x00020000 /* Invalid FQ Flow Control State */ -+#define QM_EIRQ_ICVI 0x00010000 /* Invalid Command Verb */ -+#define QM_EIRQ_IDDI 0x00000800 /* Invalid Dequeue (Direct-connect) */ -+#define QM_EIRQ_IDFI 0x00000400 /* Invalid Dequeue FQ */ -+#define QM_EIRQ_IDSI 0x00000200 /* Invalid Dequeue Source */ -+#define QM_EIRQ_IDQI 0x00000100 /* Invalid Dequeue Queue */ -+#define QM_EIRQ_IECE 0x00000010 /* Invalid Enqueue Configuration */ -+#define QM_EIRQ_IEOI 0x00000008 /* Invalid Enqueue Overflow */ -+#define QM_EIRQ_IESI 0x00000004 /* Invalid Enqueue State */ -+#define QM_EIRQ_IECI 0x00000002 /* Invalid Enqueue Channel */ -+#define QM_EIRQ_IEQI 0x00000001 /* Invalid Enqueue Queue */ -+ -+/* QMAN_ECIR valid error bit */ -+#define PORTAL_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IESI | QM_EIRQ_IEOI | \ -+ QM_EIRQ_IDQI | QM_EIRQ_IDSI | QM_EIRQ_IDFI | \ -+ QM_EIRQ_IDDI | QM_EIRQ_ICVI | QM_EIRQ_IFSI) -+#define FQID_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IECI | QM_EIRQ_IESI | \ -+ QM_EIRQ_IEOI | QM_EIRQ_IDQI | QM_EIRQ_IDFI | \ -+ QM_EIRQ_IFSI) -+ -+union qman_ecir { -+ u32 ecir_raw; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 __reserved:2; -+ u32 portal_type:1; -+ u32 portal_num:5; -+ u32 fqid:24; -+#else -+ u32 fqid:24; -+ u32 portal_num:5; -+ u32 portal_type:1; -+ u32 __reserved:2; -+#endif -+ } __packed info; -+}; -+ -+union qman_ecir2 { -+ u32 ecir2_raw; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 portal_type:1; -+ u32 __reserved:21; -+ u32 portal_num:10; -+#else -+ u32 portal_num:10; -+ u32 __reserved:21; -+ u32 portal_type:1; -+#endif -+ } __packed info; -+}; -+ -+union qman_eadr { -+ u32 eadr_raw; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 __reserved1:4; -+ u32 memid:4; -+ u32 __reserved2:12; -+ u32 eadr:12; -+#else -+ u32 eadr:12; -+ u32 __reserved2:12; -+ u32 memid:4; -+ u32 __reserved1:4; -+#endif -+ } __packed info; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 __reserved1:3; -+ u32 memid:5; -+ u32 __reserved:8; -+ u32 eadr:16; -+#else -+ u32 eadr:16; -+ u32 __reserved:8; -+ u32 memid:5; -+ u32 __reserved1:3; -+#endif -+ } __packed info_rev3; -+}; -+ -+struct qman_hwerr_txt { -+ u32 mask; -+ const char *txt; -+}; -+ -+#define QMAN_HWE_TXT(a, b) { .mask = QM_EIRQ_##a, .txt = b } -+ -+static const struct qman_hwerr_txt qman_hwerr_txts[] = { -+ QMAN_HWE_TXT(CIDE, "Corenet Initiator Data Error"), -+ QMAN_HWE_TXT(CTDE, "Corenet Target Data Error"), -+ QMAN_HWE_TXT(CITT, "Corenet Invalid Target Transaction"), -+ QMAN_HWE_TXT(PLWI, "PFDR Low Watermark"), -+ QMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"), -+ QMAN_HWE_TXT(SBEI, "Single-bit ECC Error"), -+ QMAN_HWE_TXT(PEBI, "PFDR Enqueues Blocked Interrupt"), -+ QMAN_HWE_TXT(ICVI, "Invalid Command Verb"), -+ QMAN_HWE_TXT(IFSI, "Invalid Flow Control State"), -+ QMAN_HWE_TXT(IDDI, "Invalid Dequeue (Direct-connect)"), -+ QMAN_HWE_TXT(IDFI, "Invalid Dequeue FQ"), -+ QMAN_HWE_TXT(IDSI, "Invalid Dequeue Source"), -+ QMAN_HWE_TXT(IDQI, "Invalid Dequeue Queue"), -+ QMAN_HWE_TXT(IECE, "Invalid Enqueue Configuration"), -+ QMAN_HWE_TXT(IEOI, "Invalid Enqueue Overflow"), -+ QMAN_HWE_TXT(IESI, "Invalid Enqueue State"), -+ QMAN_HWE_TXT(IECI, "Invalid Enqueue Channel"), -+ QMAN_HWE_TXT(IEQI, "Invalid Enqueue Queue") -+}; -+#define QMAN_HWE_COUNT (sizeof(qman_hwerr_txts)/sizeof(struct qman_hwerr_txt)) -+ -+struct qman_error_info_mdata { -+ u16 addr_mask; -+ u16 bits; -+ const char *txt; -+}; -+ -+#define QMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c} -+static const struct qman_error_info_mdata error_mdata[] = { -+ QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 0"), -+ QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 1"), -+ QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 2"), -+ QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 3"), -+ QMAN_ERR_MDATA(0x0FFF, 512, "FQD cache memory"), -+ QMAN_ERR_MDATA(0x07FF, 128, "SFDR memory"), -+ QMAN_ERR_MDATA(0x01FF, 72, "WQ context memory"), -+ QMAN_ERR_MDATA(0x00FF, 240, "CGR memory"), -+ QMAN_ERR_MDATA(0x00FF, 302, "Internal Order Restoration List memory"), -+ QMAN_ERR_MDATA(0x01FF, 256, "SW portal ring memory"), -+ QMAN_ERR_MDATA(0x07FF, 181, "CEETM class queue descriptor memory"), -+ QMAN_ERR_MDATA(0x0FFF, 140, "CEETM extended SFDR memory"), -+ QMAN_ERR_MDATA(0x0FFF, 25, "CEETM logical FQ mapping memory"), -+ QMAN_ERR_MDATA(0x0FFF, 96, "CEETM dequeue context memory"), -+ QMAN_ERR_MDATA(0x07FF, 396, "CEETM ccgr memory"), -+ QMAN_ERR_MDATA(0x00FF, 146, "CEETM CQ channel shaping memory"), -+ QMAN_ERR_MDATA(0x007F, 256, "CEETM CQ channel scheduling memory"), -+ QMAN_ERR_MDATA(0x01FF, 88, "CEETM dequeue statistics memory"), -+}; -+#define QMAN_ERR_MDATA_COUNT \ -+ (sizeof(error_mdata)/sizeof(struct qman_error_info_mdata)) -+ -+/* Add this in Kconfig */ -+#define QMAN_ERRS_TO_UNENABLE (QM_EIRQ_PLWI | QM_EIRQ_PEBI) -+ -+/** -+ * qm_err_isr__ - Manipulate global interrupt registers -+ * @v: for accessors that write values, this is the 32-bit value -+ * -+ * Manipulates QMAN_ERR_ISR, QMAN_ERR_IER, QMAN_ERR_ISDR, QMAN_ERR_IIR. All -+ * manipulations except qm_err_isr_[un]inhibit() use 32-bit masks composed of -+ * the QM_EIRQ_*** definitions. Note that "qm_err_isr_enable_write" means -+ * "write the enable register" rather than "enable the write register"! -+ */ -+#define qm_err_isr_status_read(qm) \ -+ __qm_err_isr_read(qm, qm_isr_status) -+#define qm_err_isr_status_clear(qm, m) \ -+ __qm_err_isr_write(qm, qm_isr_status, m) -+#define qm_err_isr_enable_read(qm) \ -+ __qm_err_isr_read(qm, qm_isr_enable) -+#define qm_err_isr_enable_write(qm, v) \ -+ __qm_err_isr_write(qm, qm_isr_enable, v) -+#define qm_err_isr_disable_read(qm) \ -+ __qm_err_isr_read(qm, qm_isr_disable) -+#define qm_err_isr_disable_write(qm, v) \ -+ __qm_err_isr_write(qm, qm_isr_disable, v) -+#define qm_err_isr_inhibit(qm) \ -+ __qm_err_isr_write(qm, qm_isr_inhibit, 1) -+#define qm_err_isr_uninhibit(qm) \ -+ __qm_err_isr_write(qm, qm_isr_inhibit, 0) -+ -+/* -+ * TODO: unimplemented registers -+ * -+ * Keeping a list here of Qman registers I have not yet covered; -+ * QCSP_DD_IHRSR, QCSP_DD_IHRFR, QCSP_DD_HASR, -+ * DCP_DD_IHRSR, DCP_DD_IHRFR, DCP_DD_HASR, CM_CFG, -+ * QMAN_EECC, QMAN_SBET, QMAN_EINJ, QMAN_SBEC0-12 -+ */ -+ -+/* Encapsulate "struct qman *" as a cast of the register space address. */ -+ -+static struct qman *qm_create(void *regs) -+{ -+ return (struct qman *)regs; -+} -+ -+static inline u32 __qm_in(struct qman *qm, u32 offset) -+{ -+ return in_be32((void *)qm + offset); -+} -+static inline void __qm_out(struct qman *qm, u32 offset, u32 val) -+{ -+ out_be32((void *)qm + offset, val); -+} -+#define qm_in(reg) __qm_in(qm, REG_##reg) -+#define qm_out(reg, val) __qm_out(qm, REG_##reg, val) -+ -+static u32 __qm_err_isr_read(struct qman *qm, enum qm_isr_reg n) -+{ -+ return __qm_in(qm, REG_ERR_ISR + (n << 2)); -+} -+ -+static void __qm_err_isr_write(struct qman *qm, enum qm_isr_reg n, u32 val) -+{ -+ __qm_out(qm, REG_ERR_ISR + (n << 2), val); -+} -+ -+static void qm_set_dc(struct qman *qm, enum qm_dc_portal portal, -+ int ed, u8 sernd) -+{ -+ DPA_ASSERT(!ed || (portal == qm_dc_portal_fman0) || -+ (portal == qm_dc_portal_fman1)); -+ if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) -+ qm_out(DCP_CFG(portal), (ed ? 0x1000 : 0) | (sernd & 0x3ff)); -+ else -+ qm_out(DCP_CFG(portal), (ed ? 0x100 : 0) | (sernd & 0x1f)); -+} -+ -+static void qm_set_wq_scheduling(struct qman *qm, enum qm_wq_class wq_class, -+ u8 cs_elev, u8 csw2, u8 csw3, u8 csw4, u8 csw5, -+ u8 csw6, u8 csw7) -+{ -+ qm_out(WQ_CS_CFG(wq_class), ((cs_elev & 0xff) << 24) | -+ ((csw2 & 0x7) << 20) | ((csw3 & 0x7) << 16) | -+ ((csw4 & 0x7) << 12) | ((csw5 & 0x7) << 8) | -+ ((csw6 & 0x7) << 4) | (csw7 & 0x7)); -+} -+ -+static void qm_set_hid(struct qman *qm) -+{ -+ qm_out(HID_CFG, 0); -+} -+ -+static void qm_set_corenet_initiator(struct qman *qm) -+{ -+ qm_out(CI_SCHED_CFG, -+ 0x80000000 | /* write srcciv enable */ -+ (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRCCIV << 24) | -+ (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRQ_W << 8) | -+ (CONFIG_FSL_QMAN_CI_SCHED_CFG_RW_W << 4) | -+ CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W); -+} -+ -+static void qm_get_version(struct qman *qm, u16 *id, u8 *major, u8 *minor, -+ u8 *cfg) -+{ -+ u32 v = qm_in(IP_REV_1); -+ u32 v2 = qm_in(IP_REV_2); -+ *id = (v >> 16); -+ *major = (v >> 8) & 0xff; -+ *minor = v & 0xff; -+ *cfg = v2 & 0xff; -+} -+ -+static void qm_set_memory(struct qman *qm, enum qm_memory memory, u64 ba, -+ int enable, int prio, int stash, u32 size) -+{ -+ u32 offset = (memory == qm_memory_fqd) ? REG_FQD_BARE : REG_PFDR_BARE; -+ u32 exp = ilog2(size); -+ /* choke if size isn't within range */ -+ DPA_ASSERT((size >= 4096) && (size <= 1073741824) && -+ is_power_of_2(size)); -+ /* choke if 'ba' has lower-alignment than 'size' */ -+ DPA_ASSERT(!(ba & (size - 1))); -+ __qm_out(qm, offset, upper_32_bits(ba)); -+ __qm_out(qm, offset + REG_offset_BAR, lower_32_bits(ba)); -+ __qm_out(qm, offset + REG_offset_AR, -+ (enable ? 0x80000000 : 0) | -+ (prio ? 0x40000000 : 0) | -+ (stash ? 0x20000000 : 0) | -+ (exp - 1)); -+} -+ -+static void qm_set_pfdr_threshold(struct qman *qm, u32 th, u8 k) -+{ -+ qm_out(PFDR_FP_LWIT, th & 0xffffff); -+ qm_out(PFDR_CFG, k); -+} -+ -+static void qm_set_sfdr_threshold(struct qman *qm, u16 th) -+{ -+ qm_out(SFDR_CFG, th & 0x3ff); -+} -+ -+static int qm_init_pfdr(struct qman *qm, u32 pfdr_start, u32 num) -+{ -+ u8 rslt = MCR_get_rslt(qm_in(MCR)); -+ -+ DPA_ASSERT(pfdr_start && !(pfdr_start & 7) && !(num & 7) && num); -+ /* Make sure the command interface is 'idle' */ -+ if (!MCR_rslt_idle(rslt)) -+ panic("QMAN_MCR isn't idle"); -+ -+ /* Write the MCR command params then the verb */ -+ qm_out(MCP(0), pfdr_start); -+ /* TODO: remove this - it's a workaround for a model bug that is -+ * corrected in more recent versions. We use the workaround until -+ * everyone has upgraded. */ -+ qm_out(MCP(1), (pfdr_start + num - 16)); -+ lwsync(); -+ qm_out(MCR, MCR_INIT_PFDR); -+ /* Poll for the result */ -+ do { -+ rslt = MCR_get_rslt(qm_in(MCR)); -+ } while (!MCR_rslt_idle(rslt)); -+ if (MCR_rslt_ok(rslt)) -+ return 0; -+ if (MCR_rslt_eaccess(rslt)) -+ return -EACCES; -+ if (MCR_rslt_inval(rslt)) -+ return -EINVAL; -+ pr_crit("Unexpected result from MCR_INIT_PFDR: %02x\n", rslt); -+ return -ENOSYS; -+} -+ -+/*****************/ -+/* Config driver */ -+/*****************/ -+ -+#define DEFAULT_FQD_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ) -+#define DEFAULT_PFDR_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_PFDR_SZ) -+ -+/* We support only one of these */ -+static struct qman *qm; -+static struct device_node *qm_node; -+ -+/* And this state belongs to 'qm'. It is set during fsl_qman_init(), but used -+ * during qman_init_ccsr(). */ -+static dma_addr_t fqd_a, pfdr_a; -+static size_t fqd_sz = DEFAULT_FQD_SZ, pfdr_sz = DEFAULT_PFDR_SZ; -+ -+static int qman_fqd(struct reserved_mem *rmem) -+{ -+ fqd_a = rmem->base; -+ fqd_sz = rmem->size; -+ -+ WARN_ON(!(fqd_a && fqd_sz)); -+ -+ return 0; -+} -+RESERVEDMEM_OF_DECLARE(qman_fqd, "fsl,qman-fqd", qman_fqd); -+ -+static int qman_pfdr(struct reserved_mem *rmem) -+{ -+ pfdr_a = rmem->base; -+ pfdr_sz = rmem->size; -+ -+ WARN_ON(!(pfdr_a && pfdr_sz)); -+ -+ return 0; -+} -+RESERVEDMEM_OF_DECLARE(qman_fbpr, "fsl,qman-pfdr", qman_pfdr); -+ -+size_t get_qman_fqd_size() -+{ -+ return fqd_sz; -+} -+ -+/* Parse the property to extract the memory location and size and -+ * memblock_reserve() it. If it isn't supplied, memblock_alloc() the default -+ * size. Also flush this memory range from data cache so that QMAN originated -+ * transactions for this memory region could be marked non-coherent. -+ */ -+static __init int parse_mem_property(struct device_node *node, const char *name, -+ dma_addr_t *addr, size_t *sz, int zero) -+{ -+ int ret; -+ -+ /* If using a "zero-pma", don't try to zero it, even if you asked */ -+ if (zero && of_find_property(node, "zero-pma", &ret)) { -+ pr_info(" it's a 'zero-pma', not zeroing from s/w\n"); -+ zero = 0; -+ } -+ -+ if (zero) { -+ /* map as cacheable, non-guarded */ -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ void __iomem *tmpp = ioremap_cache(*addr, *sz); -+#else -+ void __iomem *tmpp = ioremap(*addr, *sz); -+#endif -+ -+ if (!tmpp) -+ return -ENOMEM; -+ memset_io(tmpp, 0, *sz); -+ flush_dcache_range((unsigned long)tmpp, -+ (unsigned long)tmpp + *sz); -+ iounmap(tmpp); -+ } -+ -+ return 0; -+} -+ -+/* TODO: -+ * - there is obviously no handling of errors, -+ * - the calls to qm_set_memory() hard-code the priority and CPC-stashing for -+ * both memory resources to zero. -+ */ -+static int __init fsl_qman_init(struct device_node *node) -+{ -+ struct resource res; -+ resource_size_t len; -+ u32 __iomem *regs; -+ const char *s; -+ int ret, standby = 0; -+ u16 id; -+ u8 major, minor, cfg; -+ ret = of_address_to_resource(node, 0, &res); -+ if (ret) { -+ pr_err("Can't get %s property '%s'\n", node->full_name, "reg"); -+ return ret; -+ } -+ s = of_get_property(node, "fsl,hv-claimable", &ret); -+ if (s && !strcmp(s, "standby")) -+ standby = 1; -+ if (!standby) { -+ ret = parse_mem_property(node, "fsl,qman-fqd", -+ &fqd_a, &fqd_sz, 1); -+ pr_info("qman-fqd addr %pad size 0x%zx\n", &fqd_a, fqd_sz); -+ BUG_ON(ret); -+ ret = parse_mem_property(node, "fsl,qman-pfdr", -+ &pfdr_a, &pfdr_sz, 0); -+ pr_info("qman-pfdr addr %pad size 0x%zx\n", &pfdr_a, pfdr_sz); -+ BUG_ON(ret); -+ } -+ /* Global configuration */ -+ len = resource_size(&res); -+ if (len != (unsigned long)len) -+ return -EINVAL; -+ regs = ioremap(res.start, (unsigned long)len); -+ qm = qm_create(regs); -+ qm_node = node; -+ qm_get_version(qm, &id, &major, &minor, &cfg); -+ pr_info("Qman ver:%04x,%02x,%02x,%02x\n", id, major, minor, cfg); -+ if (!qman_ip_rev) { -+ if ((major == 1) && (minor == 0)) { -+ pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n"); -+ iounmap(regs); -+ return -ENODEV; -+ } else if ((major == 1) && (minor == 1)) -+ qman_ip_rev = QMAN_REV11; -+ else if ((major == 1) && (minor == 2)) -+ qman_ip_rev = QMAN_REV12; -+ else if ((major == 2) && (minor == 0)) -+ qman_ip_rev = QMAN_REV20; -+ else if ((major == 3) && (minor == 0)) -+ qman_ip_rev = QMAN_REV30; -+ else if ((major == 3) && (minor == 1)) -+ qman_ip_rev = QMAN_REV31; -+ else if ((major == 3) && (minor == 2)) -+ qman_ip_rev = QMAN_REV32; -+ else { -+ pr_warn("unknown Qman version, default to rev1.1\n"); -+ qman_ip_rev = QMAN_REV11; -+ } -+ qman_ip_cfg = cfg; -+ } -+ -+ if (standby) { -+ pr_info(" -> in standby mode\n"); -+ return 0; -+ } -+ return 0; -+} -+ -+int qman_have_ccsr(void) -+{ -+ return qm ? 1 : 0; -+} -+ -+__init int qman_init_early(void) -+{ -+ struct device_node *dn; -+ int ret; -+ -+ for_each_compatible_node(dn, NULL, "fsl,qman") { -+ if (qm) -+ pr_err("%s: only one 'fsl,qman' allowed\n", -+ dn->full_name); -+ else { -+ if (!of_device_is_available(dn)) -+ continue; -+ -+ ret = fsl_qman_init(dn); -+ BUG_ON(ret); -+ } -+ } -+ return 0; -+} -+postcore_initcall_sync(qman_init_early); -+ -+static void log_edata_bits(u32 bit_count) -+{ -+ u32 i, j, mask = 0xffffffff; -+ -+ pr_warn("Qman ErrInt, EDATA:\n"); -+ i = bit_count/32; -+ if (bit_count%32) { -+ i++; -+ mask = ~(mask << bit_count%32); -+ } -+ j = 16-i; -+ pr_warn(" 0x%08x\n", qm_in(EDATA(j)) & mask); -+ j++; -+ for (; j < 16; j++) -+ pr_warn(" 0x%08x\n", qm_in(EDATA(j))); -+} -+ -+static void log_additional_error_info(u32 isr_val, u32 ecsr_val) -+{ -+ union qman_ecir ecir_val; -+ union qman_eadr eadr_val; -+ -+ ecir_val.ecir_raw = qm_in(ECIR); -+ /* Is portal info valid */ -+ if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) { -+ union qman_ecir2 ecir2_val; -+ ecir2_val.ecir2_raw = qm_in(ECIR2); -+ if (ecsr_val & PORTAL_ECSR_ERR) { -+ pr_warn("Qman ErrInt: %s id %d\n", -+ (ecir2_val.info.portal_type) ? -+ "DCP" : "SWP", ecir2_val.info.portal_num); -+ } -+ if (ecsr_val & (FQID_ECSR_ERR | QM_EIRQ_IECE)) { -+ pr_warn("Qman ErrInt: ecir.fqid 0x%x\n", -+ ecir_val.info.fqid); -+ } -+ if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) { -+ eadr_val.eadr_raw = qm_in(EADR); -+ pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n", -+ error_mdata[eadr_val.info_rev3.memid].txt, -+ error_mdata[eadr_val.info_rev3.memid].addr_mask -+ & eadr_val.info_rev3.eadr); -+ log_edata_bits( -+ error_mdata[eadr_val.info_rev3.memid].bits); -+ } -+ } else { -+ if (ecsr_val & PORTAL_ECSR_ERR) { -+ pr_warn("Qman ErrInt: %s id %d\n", -+ (ecir_val.info.portal_type) ? -+ "DCP" : "SWP", ecir_val.info.portal_num); -+ } -+ if (ecsr_val & FQID_ECSR_ERR) { -+ pr_warn("Qman ErrInt: ecir.fqid 0x%x\n", -+ ecir_val.info.fqid); -+ } -+ if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) { -+ eadr_val.eadr_raw = qm_in(EADR); -+ pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n", -+ error_mdata[eadr_val.info.memid].txt, -+ error_mdata[eadr_val.info.memid].addr_mask -+ & eadr_val.info.eadr); -+ log_edata_bits(error_mdata[eadr_val.info.memid].bits); -+ } -+ } -+} -+ -+/* Qman interrupt handler */ -+static irqreturn_t qman_isr(int irq, void *ptr) -+{ -+ u32 isr_val, ier_val, ecsr_val, isr_mask, i; -+ -+ ier_val = qm_err_isr_enable_read(qm); -+ isr_val = qm_err_isr_status_read(qm); -+ ecsr_val = qm_in(ECSR); -+ isr_mask = isr_val & ier_val; -+ -+ if (!isr_mask) -+ return IRQ_NONE; -+ for (i = 0; i < QMAN_HWE_COUNT; i++) { -+ if (qman_hwerr_txts[i].mask & isr_mask) { -+ pr_warn("Qman ErrInt: %s\n", qman_hwerr_txts[i].txt); -+ if (qman_hwerr_txts[i].mask & ecsr_val) { -+ log_additional_error_info(isr_mask, ecsr_val); -+ /* Re-arm error capture registers */ -+ qm_out(ECSR, ecsr_val); -+ } -+ if (qman_hwerr_txts[i].mask & QMAN_ERRS_TO_UNENABLE) { -+ pr_devel("Qman un-enabling error 0x%x\n", -+ qman_hwerr_txts[i].mask); -+ ier_val &= ~qman_hwerr_txts[i].mask; -+ qm_err_isr_enable_write(qm, ier_val); -+ } -+ } -+ } -+ qm_err_isr_status_clear(qm, isr_val); -+ return IRQ_HANDLED; -+} -+ -+static int __bind_irq(void) -+{ -+ int ret, err_irq; -+ -+ err_irq = of_irq_to_resource(qm_node, 0, NULL); -+ if (err_irq == 0) { -+ pr_info("Can't get %s property '%s'\n", qm_node->full_name, -+ "interrupts"); -+ return -ENODEV; -+ } -+ ret = request_irq(err_irq, qman_isr, IRQF_SHARED, "qman-err", qm_node); -+ if (ret) { -+ pr_err("request_irq() failed %d for '%s'\n", ret, -+ qm_node->full_name); -+ return -ENODEV; -+ } -+ /* Write-to-clear any stale bits, (eg. starvation being asserted prior -+ * to resource allocation during driver init). */ -+ qm_err_isr_status_clear(qm, 0xffffffff); -+ /* Enable Error Interrupts */ -+ qm_err_isr_enable_write(qm, 0xffffffff); -+ return 0; -+} -+ -+int qman_init_ccsr(struct device_node *node) -+{ -+ int ret; -+ if (!qman_have_ccsr()) -+ return 0; -+ if (node != qm_node) -+ return -EINVAL; -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ /* TEMP for LS1043 : should be done in uboot */ -+ qm_out(QCSP_BARE, 0x5); -+ qm_out(QCSP_BAR, 0x0); -+#endif -+ /* FQD memory */ -+ qm_set_memory(qm, qm_memory_fqd, fqd_a, 1, 0, 0, fqd_sz); -+ /* PFDR memory */ -+ qm_set_memory(qm, qm_memory_pfdr, pfdr_a, 1, 0, 0, pfdr_sz); -+ qm_init_pfdr(qm, 8, pfdr_sz / 64 - 8); -+ /* thresholds */ -+ qm_set_pfdr_threshold(qm, 512, 64); -+ qm_set_sfdr_threshold(qm, 128); -+ /* clear stale PEBI bit from interrupt status register */ -+ qm_err_isr_status_clear(qm, QM_EIRQ_PEBI); -+ /* corenet initiator settings */ -+ qm_set_corenet_initiator(qm); -+ /* HID settings */ -+ qm_set_hid(qm); -+ /* Set scheduling weights to defaults */ -+ for (ret = qm_wq_first; ret <= qm_wq_last; ret++) -+ qm_set_wq_scheduling(qm, ret, 0, 0, 0, 0, 0, 0, 0); -+ /* We are not prepared to accept ERNs for hardware enqueues */ -+ qm_set_dc(qm, qm_dc_portal_fman0, 1, 0); -+ qm_set_dc(qm, qm_dc_portal_fman1, 1, 0); -+ /* Initialise Error Interrupt Handler */ -+ ret = __bind_irq(); -+ if (ret) -+ return ret; -+ return 0; -+} -+ -+#define LIO_CFG_LIODN_MASK 0x0fff0000 -+void qman_liodn_fixup(u16 channel) -+{ -+ static int done; -+ static u32 liodn_offset; -+ u32 before, after; -+ int idx = channel - QM_CHANNEL_SWPORTAL0; -+ -+ if (!qman_have_ccsr()) -+ return; -+ if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) -+ before = qm_in(REV3_QCSP_LIO_CFG(idx)); -+ else -+ before = qm_in(QCSP_LIO_CFG(idx)); -+ if (!done) { -+ liodn_offset = before & LIO_CFG_LIODN_MASK; -+ done = 1; -+ return; -+ } -+ after = (before & (~LIO_CFG_LIODN_MASK)) | liodn_offset; -+ if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) -+ qm_out(REV3_QCSP_LIO_CFG(idx), after); -+ else -+ qm_out(QCSP_LIO_CFG(idx), after); -+} -+ -+#define IO_CFG_SDEST_MASK 0x00ff0000 -+int qman_set_sdest(u16 channel, unsigned int cpu_idx) -+{ -+ int idx = channel - QM_CHANNEL_SWPORTAL0; -+ u32 before, after; -+ -+ if (!qman_have_ccsr()) -+ return -ENODEV; -+ if ((qman_ip_rev & 0xFF00) == QMAN_REV31) { -+ /* LS1043A - only one L2 cache */ -+ cpu_idx = 0; -+ } -+ -+ if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) { -+ before = qm_in(REV3_QCSP_IO_CFG(idx)); -+ /* Each pair of vcpu share the same SRQ(SDEST) */ -+ cpu_idx /= 2; -+ after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16); -+ qm_out(REV3_QCSP_IO_CFG(idx), after); -+ } else { -+ before = qm_in(QCSP_IO_CFG(idx)); -+ after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16); -+ qm_out(QCSP_IO_CFG(idx), after); -+ } -+ return 0; -+} -+ -+#define MISC_CFG_WPM_MASK 0x00000002 -+int qm_set_wpm(int wpm) -+{ -+ u32 before; -+ u32 after; -+ -+ if (!qman_have_ccsr()) -+ return -ENODEV; -+ -+ before = qm_in(MISC_CFG); -+ after = (before & (~MISC_CFG_WPM_MASK)) | (wpm << 1); -+ qm_out(MISC_CFG, after); -+ return 0; -+} -+ -+int qm_get_wpm(int *wpm) -+{ -+ u32 before; -+ -+ if (!qman_have_ccsr()) -+ return -ENODEV; -+ -+ before = qm_in(MISC_CFG); -+ *wpm = (before & MISC_CFG_WPM_MASK) >> 1; -+ return 0; -+} -+ -+/* CEETM_CFG_PRES register has PRES field which is calculated by: -+ * PRES = (2^22 / credit update reference period) * QMan clock period -+ * = (2^22 * 10^9)/ CONFIG_QMAN_CEETM_UPDATE_PERIOD) / qman_clk -+ */ -+ -+int qman_ceetm_set_prescaler(enum qm_dc_portal portal) -+{ -+ u64 temp; -+ u16 pres; -+ -+ if (!qman_have_ccsr()) -+ return -ENODEV; -+ -+ temp = 0x400000 * 100; -+ do_div(temp, CONFIG_QMAN_CEETM_UPDATE_PERIOD); -+ temp *= 10000000; -+ do_div(temp, qman_clk); -+ pres = (u16) temp; -+ qm_out(CEETM_CFG_IDX, portal); -+ qm_out(CEETM_CFG_PRES, pres); -+ return 0; -+} -+ -+int qman_ceetm_get_prescaler(u16 *pres) -+{ -+ if (!qman_have_ccsr()) -+ return -ENODEV; -+ *pres = (u16)qm_in(CEETM_CFG_PRES); -+ return 0; -+} -+ -+#define DCP_CFG_CEETME_MASK 0xFFFF0000 -+#define QM_SP_ENABLE_CEETM(n) (0x80000000 >> (n)) -+int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal) -+{ -+ u32 dcp_cfg; -+ -+ if (!qman_have_ccsr()) -+ return -ENODEV; -+ -+ dcp_cfg = qm_in(DCP_CFG(portal)); -+ dcp_cfg |= QM_SP_ENABLE_CEETM(sub_portal); -+ qm_out(DCP_CFG(portal), dcp_cfg); -+ return 0; -+} -+ -+int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal) -+{ -+ u32 dcp_cfg; -+ -+ if (!qman_have_ccsr()) -+ return -ENODEV; -+ dcp_cfg = qm_in(DCP_CFG(portal)); -+ dcp_cfg &= ~(QM_SP_ENABLE_CEETM(sub_portal)); -+ qm_out(DCP_CFG(portal), dcp_cfg); -+ return 0; -+} -+ -+int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num) -+{ -+ if (!qman_have_ccsr()) -+ return -ENODEV; -+ *num = qm_in(CEETM_XSFDR_IN_USE); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_get_xsfdr); -+ -+#ifdef CONFIG_SYSFS -+ -+#define DRV_NAME "fsl-qman" -+#define DCP_MAX_ID 3 -+#define DCP_MIN_ID 0 -+ -+static ssize_t show_pfdr_fpc(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_FPC)); -+}; -+ -+static ssize_t show_dlm_avg(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ u32 data; -+ int i; -+ -+ if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i)) -+ return -EINVAL; -+ if (i < DCP_MIN_ID || i > DCP_MAX_ID) -+ return -EINVAL; -+ data = qm_in(DCP_DLM_AVG(i)); -+ return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8, -+ (data & 0x000000ff)*390625); -+}; -+ -+static ssize_t set_dlm_avg(struct device *dev, -+ struct device_attribute *dev_attr, const char *buf, size_t count) -+{ -+ unsigned long val; -+ int i; -+ -+ if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i)) -+ return -EINVAL; -+ if (i < DCP_MIN_ID || i > DCP_MAX_ID) -+ return -EINVAL; -+ if (kstrtoul(buf, 0, &val)) { -+ dev_dbg(dev, "invalid input %s\n", buf); -+ return -EINVAL; -+ } -+ qm_out(DCP_DLM_AVG(i), val); -+ return count; -+}; -+ -+static ssize_t show_pfdr_cfg(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_CFG)); -+}; -+ -+static ssize_t set_pfdr_cfg(struct device *dev, -+ struct device_attribute *dev_attr, const char *buf, size_t count) -+{ -+ unsigned long val; -+ -+ if (kstrtoul(buf, 0, &val)) { -+ dev_dbg(dev, "invalid input %s\n", buf); -+ return -EINVAL; -+ } -+ qm_out(PFDR_CFG, val); -+ return count; -+}; -+ -+static ssize_t show_sfdr_in_use(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SFDR_IN_USE)); -+}; -+ -+static ssize_t show_idle_stat(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(IDLE_STAT)); -+}; -+ -+static ssize_t show_ci_rlm_avg(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ u32 data = qm_in(CI_RLM_AVG); -+ return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8, -+ (data & 0x000000ff)*390625); -+}; -+ -+static ssize_t set_ci_rlm_avg(struct device *dev, -+ struct device_attribute *dev_attr, const char *buf, size_t count) -+{ -+ unsigned long val; -+ -+ if (kstrtoul(buf, 0, &val)) { -+ dev_dbg(dev, "invalid input %s\n", buf); -+ return -EINVAL; -+ } -+ qm_out(CI_RLM_AVG, val); -+ return count; -+}; -+ -+static ssize_t show_err_isr(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "0x%08x\n", qm_in(ERR_ISR)); -+}; -+ -+#define SBEC_MAX_ID 14 -+#define SBEC_MIN_ID 0 -+ -+static ssize_t show_sbec(struct device *dev, -+ struct device_attribute *dev_attr, char *buf) -+{ -+ int i; -+ -+ if (!sscanf(dev_attr->attr.name, "sbec_%d", &i)) -+ return -EINVAL; -+ if (i < SBEC_MIN_ID || i > SBEC_MAX_ID) -+ return -EINVAL; -+ return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SBEC(i))); -+}; -+ -+static DEVICE_ATTR(pfdr_fpc, S_IRUSR, show_pfdr_fpc, NULL); -+static DEVICE_ATTR(pfdr_cfg, S_IRUSR, show_pfdr_cfg, set_pfdr_cfg); -+static DEVICE_ATTR(idle_stat, S_IRUSR, show_idle_stat, NULL); -+static DEVICE_ATTR(ci_rlm_avg, (S_IRUSR|S_IWUSR), -+ show_ci_rlm_avg, set_ci_rlm_avg); -+static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL); -+static DEVICE_ATTR(sfdr_in_use, S_IRUSR, show_sfdr_in_use, NULL); -+ -+static DEVICE_ATTR(dcp0_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg); -+static DEVICE_ATTR(dcp1_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg); -+static DEVICE_ATTR(dcp2_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg); -+static DEVICE_ATTR(dcp3_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg); -+ -+static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_2, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_3, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_4, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_5, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_6, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_7, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_8, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_9, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_10, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_11, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_12, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_13, S_IRUSR, show_sbec, NULL); -+static DEVICE_ATTR(sbec_14, S_IRUSR, show_sbec, NULL); -+ -+static struct attribute *qman_dev_attributes[] = { -+ &dev_attr_pfdr_fpc.attr, -+ &dev_attr_pfdr_cfg.attr, -+ &dev_attr_idle_stat.attr, -+ &dev_attr_ci_rlm_avg.attr, -+ &dev_attr_err_isr.attr, -+ &dev_attr_dcp0_dlm_avg.attr, -+ &dev_attr_dcp1_dlm_avg.attr, -+ &dev_attr_dcp2_dlm_avg.attr, -+ &dev_attr_dcp3_dlm_avg.attr, -+ /* sfdr_in_use will be added if necessary */ -+ NULL -+}; -+ -+static struct attribute *qman_dev_ecr_attributes[] = { -+ &dev_attr_sbec_0.attr, -+ &dev_attr_sbec_1.attr, -+ &dev_attr_sbec_2.attr, -+ &dev_attr_sbec_3.attr, -+ &dev_attr_sbec_4.attr, -+ &dev_attr_sbec_5.attr, -+ &dev_attr_sbec_6.attr, -+ &dev_attr_sbec_7.attr, -+ &dev_attr_sbec_8.attr, -+ &dev_attr_sbec_9.attr, -+ &dev_attr_sbec_10.attr, -+ &dev_attr_sbec_11.attr, -+ &dev_attr_sbec_12.attr, -+ &dev_attr_sbec_13.attr, -+ &dev_attr_sbec_14.attr, -+ NULL -+}; -+ -+/* root level */ -+static const struct attribute_group qman_dev_attr_grp = { -+ .name = NULL, -+ .attrs = qman_dev_attributes -+}; -+static const struct attribute_group qman_dev_ecr_grp = { -+ .name = "error_capture", -+ .attrs = qman_dev_ecr_attributes -+}; -+ -+static int of_fsl_qman_remove(struct platform_device *ofdev) -+{ -+ sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp); -+ return 0; -+}; -+ -+static int of_fsl_qman_probe(struct platform_device *ofdev) -+{ -+ int ret; -+ -+ ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_attr_grp); -+ if (ret) -+ goto done; -+ ret = sysfs_add_file_to_group(&ofdev->dev.kobj, -+ &dev_attr_sfdr_in_use.attr, qman_dev_attr_grp.name); -+ if (ret) -+ goto del_group_0; -+ ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_ecr_grp); -+ if (ret) -+ goto del_group_0; -+ -+ goto done; -+ -+del_group_0: -+ sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp); -+done: -+ if (ret) -+ dev_err(&ofdev->dev, -+ "Cannot create dev attributes ret=%d\n", ret); -+ return ret; -+}; -+ -+static struct of_device_id of_fsl_qman_ids[] = { -+ { -+ .compatible = "fsl,qman", -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, of_fsl_qman_ids); -+ -+#ifdef CONFIG_SUSPEND -+ -+static u32 saved_isdr; -+static int qman_pm_suspend_noirq(struct device *dev) -+{ -+ uint32_t idle_state; -+ -+ suspend_unused_qportal(); -+ /* save isdr, disable all, clear isr */ -+ saved_isdr = qm_err_isr_disable_read(qm); -+ qm_err_isr_disable_write(qm, 0xffffffff); -+ qm_err_isr_status_clear(qm, 0xffffffff); -+ idle_state = qm_in(IDLE_STAT); -+ if (!(idle_state & 0x1)) { -+ pr_err("Qman not idle 0x%x aborting\n", idle_state); -+ qm_err_isr_disable_write(qm, saved_isdr); -+ resume_unused_qportal(); -+ return -EBUSY; -+ } -+#ifdef CONFIG_PM_DEBUG -+ pr_info("Qman suspend code, IDLE_STAT = 0x%x\n", idle_state); -+#endif -+ return 0; -+} -+ -+static int qman_pm_resume_noirq(struct device *dev) -+{ -+ /* restore isdr */ -+ qm_err_isr_disable_write(qm, saved_isdr); -+ resume_unused_qportal(); -+ return 0; -+} -+#else -+#define qman_pm_suspend_noirq NULL -+#define qman_pm_resume_noirq NULL -+#endif -+ -+static const struct dev_pm_ops qman_pm_ops = { -+ .suspend_noirq = qman_pm_suspend_noirq, -+ .resume_noirq = qman_pm_resume_noirq, -+}; -+ -+static struct platform_driver of_fsl_qman_driver = { -+ .driver = { -+ .owner = THIS_MODULE, -+ .name = DRV_NAME, -+ .of_match_table = of_fsl_qman_ids, -+ .pm = &qman_pm_ops, -+ }, -+ .probe = of_fsl_qman_probe, -+ .remove = of_fsl_qman_remove, -+}; -+ -+static int qman_ctrl_init(void) -+{ -+ return platform_driver_register(&of_fsl_qman_driver); -+} -+ -+static void qman_ctrl_exit(void) -+{ -+ platform_driver_unregister(&of_fsl_qman_driver); -+} -+ -+module_init(qman_ctrl_init); -+module_exit(qman_ctrl_exit); -+ -+#endif /* CONFIG_SYSFS */ ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_debugfs.c -@@ -0,0 +1,1594 @@ -+/* Copyright 2010-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+#include "qman_private.h" -+ -+#define MAX_FQID (0x00ffffff) -+#define QM_FQD_BLOCK_SIZE 64 -+#define QM_FQD_AR (0xC10) -+ -+static u32 fqid_max; -+static u64 qman_ccsr_start; -+static u64 qman_ccsr_size; -+ -+static const char * const state_txt[] = { -+ "Out of Service", -+ "Retired", -+ "Tentatively Scheduled", -+ "Truly Scheduled", -+ "Parked", -+ "Active, Active Held or Held Suspended", -+ "Unknown State 6", -+ "Unknown State 7", -+ NULL, -+}; -+ -+static const u8 fqd_states[] = { -+ QM_MCR_NP_STATE_OOS, QM_MCR_NP_STATE_RETIRED, QM_MCR_NP_STATE_TEN_SCHED, -+ QM_MCR_NP_STATE_TRU_SCHED, QM_MCR_NP_STATE_PARKED, -+ QM_MCR_NP_STATE_ACTIVE}; -+ -+struct mask_to_text { -+ u16 mask; -+ const char *txt; -+}; -+ -+struct mask_filter_s { -+ u16 mask; -+ u8 filter; -+}; -+ -+static const struct mask_filter_s mask_filter[] = { -+ {QM_FQCTRL_PREFERINCACHE, 0}, -+ {QM_FQCTRL_PREFERINCACHE, 1}, -+ {QM_FQCTRL_HOLDACTIVE, 0}, -+ {QM_FQCTRL_HOLDACTIVE, 1}, -+ {QM_FQCTRL_AVOIDBLOCK, 0}, -+ {QM_FQCTRL_AVOIDBLOCK, 1}, -+ {QM_FQCTRL_FORCESFDR, 0}, -+ {QM_FQCTRL_FORCESFDR, 1}, -+ {QM_FQCTRL_CPCSTASH, 0}, -+ {QM_FQCTRL_CPCSTASH, 1}, -+ {QM_FQCTRL_CTXASTASHING, 0}, -+ {QM_FQCTRL_CTXASTASHING, 1}, -+ {QM_FQCTRL_ORP, 0}, -+ {QM_FQCTRL_ORP, 1}, -+ {QM_FQCTRL_TDE, 0}, -+ {QM_FQCTRL_TDE, 1}, -+ {QM_FQCTRL_CGE, 0}, -+ {QM_FQCTRL_CGE, 1} -+}; -+ -+static const struct mask_to_text fq_ctrl_text_list[] = { -+ { -+ .mask = QM_FQCTRL_PREFERINCACHE, -+ .txt = "Prefer in cache", -+ }, -+ { -+ .mask = QM_FQCTRL_HOLDACTIVE, -+ .txt = "Hold active in portal", -+ }, -+ { -+ .mask = QM_FQCTRL_AVOIDBLOCK, -+ .txt = "Avoid Blocking", -+ }, -+ { -+ .mask = QM_FQCTRL_FORCESFDR, -+ .txt = "High-priority SFDRs", -+ }, -+ { -+ .mask = QM_FQCTRL_CPCSTASH, -+ .txt = "CPC Stash Enable", -+ }, -+ { -+ .mask = QM_FQCTRL_CTXASTASHING, -+ .txt = "Context-A stashing", -+ }, -+ { -+ .mask = QM_FQCTRL_ORP, -+ .txt = "ORP Enable", -+ }, -+ { -+ .mask = QM_FQCTRL_TDE, -+ .txt = "Tail-Drop Enable", -+ }, -+ { -+ .mask = QM_FQCTRL_CGE, -+ .txt = "Congestion Group Enable", -+ }, -+ { -+ .mask = 0, -+ .txt = NULL, -+ } -+}; -+ -+static const char *get_fqd_ctrl_text(u16 mask) -+{ -+ int i = 0; -+ -+ while (fq_ctrl_text_list[i].txt != NULL) { -+ if (fq_ctrl_text_list[i].mask == mask) -+ return fq_ctrl_text_list[i].txt; -+ i++; -+ } -+ return NULL; -+} -+ -+static const struct mask_to_text stashing_text_list[] = { -+ { -+ .mask = QM_STASHING_EXCL_CTX, -+ .txt = "FQ Ctx Stash" -+ }, -+ { -+ .mask = QM_STASHING_EXCL_DATA, -+ .txt = "Frame Data Stash", -+ }, -+ { -+ .mask = QM_STASHING_EXCL_ANNOTATION, -+ .txt = "Frame Annotation Stash", -+ }, -+ { -+ .mask = 0, -+ .txt = NULL, -+ }, -+}; -+ -+static int user_input_convert(const char __user *user_buf, size_t count, -+ unsigned long *val) -+{ -+ char buf[12]; -+ -+ if (count > sizeof(buf) - 1) -+ return -EINVAL; -+ if (copy_from_user(buf, user_buf, count)) -+ return -EFAULT; -+ buf[count] = '\0'; -+ if (kstrtoul(buf, 0, val)) -+ return -EINVAL; -+ return 0; -+} -+ -+struct line_buffer_fq { -+ u32 buf[8]; -+ u32 buf_cnt; -+ int line_cnt; -+}; -+ -+static void add_to_line_buffer(struct line_buffer_fq *line_buf, u32 fqid, -+ struct seq_file *file) -+{ -+ line_buf->buf[line_buf->buf_cnt] = fqid; -+ line_buf->buf_cnt++; -+ if (line_buf->buf_cnt == 8) { -+ /* Buffer is full, flush it */ -+ if (line_buf->line_cnt != 0) -+ seq_puts(file, ",\n"); -+ seq_printf(file, "0x%06x,0x%06x,0x%06x,0x%06x,0x%06x," -+ "0x%06x,0x%06x,0x%06x", -+ line_buf->buf[0], line_buf->buf[1], line_buf->buf[2], -+ line_buf->buf[3], line_buf->buf[4], line_buf->buf[5], -+ line_buf->buf[6], line_buf->buf[7]); -+ line_buf->buf_cnt = 0; -+ line_buf->line_cnt++; -+ } -+} -+ -+static void flush_line_buffer(struct line_buffer_fq *line_buf, -+ struct seq_file *file) -+{ -+ if (line_buf->buf_cnt) { -+ int y = 0; -+ if (line_buf->line_cnt != 0) -+ seq_puts(file, ",\n"); -+ while (y != line_buf->buf_cnt) { -+ if (y+1 == line_buf->buf_cnt) -+ seq_printf(file, "0x%06x", line_buf->buf[y]); -+ else -+ seq_printf(file, "0x%06x,", line_buf->buf[y]); -+ y++; -+ } -+ line_buf->line_cnt++; -+ } -+ if (line_buf->line_cnt) -+ seq_putc(file, '\n'); -+} -+ -+static struct dentry *dfs_root; /* debugfs root directory */ -+ -+/******************************************************************************* -+ * Query Frame Queue Non Programmable Fields -+ ******************************************************************************/ -+struct query_fq_np_fields_data_s { -+ u32 fqid; -+}; -+static struct query_fq_np_fields_data_s query_fq_np_fields_data = { -+ .fqid = 1, -+}; -+ -+static int query_fq_np_fields_show(struct seq_file *file, void *offset) -+{ -+ int ret; -+ struct qm_mcr_queryfq_np np; -+ struct qman_fq fq; -+ -+ fq.fqid = query_fq_np_fields_data.fqid; -+ ret = qman_query_fq_np(&fq, &np); -+ if (ret) -+ return ret; -+ /* Print state */ -+ seq_printf(file, "Query FQ Non Programmable Fields Result fqid 0x%x\n", -+ fq.fqid); -+ seq_printf(file, " force eligible pending: %s\n", -+ (np.state & QM_MCR_NP_STATE_FE) ? "yes" : "no"); -+ seq_printf(file, " retirement pending: %s\n", -+ (np.state & QM_MCR_NP_STATE_R) ? "yes" : "no"); -+ seq_printf(file, " state: %s\n", -+ state_txt[np.state & QM_MCR_NP_STATE_MASK]); -+ seq_printf(file, " fq_link: 0x%x\n", np.fqd_link); -+ seq_printf(file, " odp_seq: %u\n", np.odp_seq); -+ seq_printf(file, " orp_nesn: %u\n", np.orp_nesn); -+ seq_printf(file, " orp_ea_hseq: %u\n", np.orp_ea_hseq); -+ seq_printf(file, " orp_ea_tseq: %u\n", np.orp_ea_tseq); -+ seq_printf(file, " orp_ea_hptr: 0x%x\n", np.orp_ea_hptr); -+ seq_printf(file, " orp_ea_tptr: 0x%x\n", np.orp_ea_tptr); -+ seq_printf(file, " pfdr_hptr: 0x%x\n", np.pfdr_hptr); -+ seq_printf(file, " pfdr_tptr: 0x%x\n", np.pfdr_tptr); -+ seq_printf(file, " is: ics_surp contains a %s\n", -+ (np.is) ? "deficit" : "surplus"); -+ seq_printf(file, " ics_surp: %u\n", np.ics_surp); -+ seq_printf(file, " byte_cnt: %u\n", np.byte_cnt); -+ seq_printf(file, " frm_cnt: %u\n", np.frm_cnt); -+ seq_printf(file, " ra1_sfdr: 0x%x\n", np.ra1_sfdr); -+ seq_printf(file, " ra2_sfdr: 0x%x\n", np.ra2_sfdr); -+ seq_printf(file, " od1_sfdr: 0x%x\n", np.od1_sfdr); -+ seq_printf(file, " od2_sfdr: 0x%x\n", np.od2_sfdr); -+ seq_printf(file, " od3_sfdr: 0x%x\n", np.od3_sfdr); -+ return 0; -+} -+ -+static int query_fq_np_fields_open(struct inode *inode, -+ struct file *file) -+{ -+ return single_open(file, query_fq_np_fields_show, NULL); -+} -+ -+static ssize_t query_fq_np_fields_write(struct file *f, -+ const char __user *buf, size_t count, loff_t *off) -+{ -+ int ret; -+ unsigned long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ if (val > MAX_FQID) -+ return -EINVAL; -+ query_fq_np_fields_data.fqid = (u32)val; -+ return count; -+} -+ -+static const struct file_operations query_fq_np_fields_fops = { -+ .owner = THIS_MODULE, -+ .open = query_fq_np_fields_open, -+ .read = seq_read, -+ .write = query_fq_np_fields_write, -+ .release = single_release, -+}; -+ -+/******************************************************************************* -+ * Frame Queue Programmable Fields -+ ******************************************************************************/ -+struct query_fq_fields_data_s { -+ u32 fqid; -+}; -+ -+static struct query_fq_fields_data_s query_fq_fields_data = { -+ .fqid = 1, -+}; -+ -+static int query_fq_fields_show(struct seq_file *file, void *offset) -+{ -+ int ret; -+ struct qm_fqd fqd; -+ struct qman_fq fq; -+ int i = 0; -+ -+ memset(&fqd, 0, sizeof(struct qm_fqd)); -+ fq.fqid = query_fq_fields_data.fqid; -+ ret = qman_query_fq(&fq, &fqd); -+ if (ret) -+ return ret; -+ seq_printf(file, "Query FQ Programmable Fields Result fqid 0x%x\n", -+ fq.fqid); -+ seq_printf(file, " orprws: %u\n", fqd.orprws); -+ seq_printf(file, " oa: %u\n", fqd.oa); -+ seq_printf(file, " olws: %u\n", fqd.olws); -+ -+ seq_printf(file, " cgid: %u\n", fqd.cgid); -+ -+ if ((fqd.fq_ctrl & QM_FQCTRL_MASK) == 0) -+ seq_puts(file, " fq_ctrl: None\n"); -+ else { -+ i = 0; -+ seq_puts(file, " fq_ctrl:\n"); -+ while (fq_ctrl_text_list[i].txt != NULL) { -+ if ((fqd.fq_ctrl & QM_FQCTRL_MASK) & -+ fq_ctrl_text_list[i].mask) -+ seq_printf(file, " %s\n", -+ fq_ctrl_text_list[i].txt); -+ i++; -+ } -+ } -+ seq_printf(file, " dest_channel: %u\n", fqd.dest.channel); -+ seq_printf(file, " dest_wq: %u\n", fqd.dest.wq); -+ seq_printf(file, " ics_cred: %u\n", fqd.ics_cred); -+ seq_printf(file, " td_mant: %u\n", fqd.td.mant); -+ seq_printf(file, " td_exp: %u\n", fqd.td.exp); -+ -+ seq_printf(file, " ctx_b: 0x%x\n", fqd.context_b); -+ -+ seq_printf(file, " ctx_a: 0x%llx\n", qm_fqd_stashing_get64(&fqd)); -+ /* Any stashing configured */ -+ if ((fqd.context_a.stashing.exclusive & 0x7) == 0) -+ seq_puts(file, " ctx_a_stash_exclusive: None\n"); -+ else { -+ seq_puts(file, " ctx_a_stash_exclusive:\n"); -+ i = 0; -+ while (stashing_text_list[i].txt != NULL) { -+ if ((fqd.fq_ctrl & 0x7) & stashing_text_list[i].mask) -+ seq_printf(file, " %s\n", -+ stashing_text_list[i].txt); -+ i++; -+ } -+ } -+ seq_printf(file, " ctx_a_stash_annotation_cl: %u\n", -+ fqd.context_a.stashing.annotation_cl); -+ seq_printf(file, " ctx_a_stash_data_cl: %u\n", -+ fqd.context_a.stashing.data_cl); -+ seq_printf(file, " ctx_a_stash_context_cl: %u\n", -+ fqd.context_a.stashing.context_cl); -+ return 0; -+} -+ -+static int query_fq_fields_open(struct inode *inode, -+ struct file *file) -+{ -+ return single_open(file, query_fq_fields_show, NULL); -+} -+ -+static ssize_t query_fq_fields_write(struct file *f, -+ const char __user *buf, size_t count, loff_t *off) -+{ -+ int ret; -+ unsigned long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ if (val > MAX_FQID) -+ return -EINVAL; -+ query_fq_fields_data.fqid = (u32)val; -+ return count; -+} -+ -+static const struct file_operations query_fq_fields_fops = { -+ .owner = THIS_MODULE, -+ .open = query_fq_fields_open, -+ .read = seq_read, -+ .write = query_fq_fields_write, -+ .release = single_release, -+}; -+ -+/******************************************************************************* -+ * Query WQ lengths -+ ******************************************************************************/ -+struct query_wq_lengths_data_s { -+ union { -+ u16 channel_wq; /* ignores wq (3 lsbits) */ -+ struct { -+ u16 id:13; /* qm_channel */ -+ u16 __reserved:3; -+ } __packed channel; -+ }; -+}; -+static struct query_wq_lengths_data_s query_wq_lengths_data; -+static int query_wq_lengths_show(struct seq_file *file, void *offset) -+{ -+ int ret; -+ struct qm_mcr_querywq wq; -+ int i; -+ -+ memset(&wq, 0, sizeof(struct qm_mcr_querywq)); -+ wq.channel.id = query_wq_lengths_data.channel.id; -+ ret = qman_query_wq(0, &wq); -+ if (ret) -+ return ret; -+ seq_printf(file, "Query Result For Channel: 0x%x\n", wq.channel.id); -+ for (i = 0; i < 8; i++) -+ /* mask out upper 4 bits since they are not part of length */ -+ seq_printf(file, " wq%d_len : %u\n", i, wq.wq_len[i] & 0x0fff); -+ return 0; -+} -+ -+static int query_wq_lengths_open(struct inode *inode, -+ struct file *file) -+{ -+ return single_open(file, query_wq_lengths_show, NULL); -+} -+ -+static ssize_t query_wq_lengths_write(struct file *f, -+ const char __user *buf, size_t count, loff_t *off) -+{ -+ int ret; -+ unsigned long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ if (val > 0xfff8) -+ return -EINVAL; -+ query_wq_lengths_data.channel.id = (u16)val; -+ return count; -+} -+ -+static const struct file_operations query_wq_lengths_fops = { -+ .owner = THIS_MODULE, -+ .open = query_wq_lengths_open, -+ .read = seq_read, -+ .write = query_wq_lengths_write, -+ .release = single_release, -+}; -+ -+/******************************************************************************* -+ * Query CGR -+ ******************************************************************************/ -+struct query_cgr_s { -+ u8 cgid; -+}; -+static struct query_cgr_s query_cgr_data; -+ -+static int query_cgr_show(struct seq_file *file, void *offset) -+{ -+ int ret; -+ struct qm_mcr_querycgr cgrd; -+ struct qman_cgr cgr; -+ int i, j; -+ u32 mask; -+ -+ memset(&cgr, 0, sizeof(cgr)); -+ memset(&cgrd, 0, sizeof(cgrd)); -+ cgr.cgrid = query_cgr_data.cgid; -+ ret = qman_query_cgr(&cgr, &cgrd); -+ if (ret) -+ return ret; -+ seq_printf(file, "Query CGR id 0x%x\n", cgr.cgrid); -+ seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n", -+ cgrd.cgr.wr_parm_g.MA, cgrd.cgr.wr_parm_g.Mn, -+ cgrd.cgr.wr_parm_g.SA, cgrd.cgr.wr_parm_g.Sn, -+ cgrd.cgr.wr_parm_g.Pn); -+ -+ seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n", -+ cgrd.cgr.wr_parm_y.MA, cgrd.cgr.wr_parm_y.Mn, -+ cgrd.cgr.wr_parm_y.SA, cgrd.cgr.wr_parm_y.Sn, -+ cgrd.cgr.wr_parm_y.Pn); -+ -+ seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n", -+ cgrd.cgr.wr_parm_r.MA, cgrd.cgr.wr_parm_r.Mn, -+ cgrd.cgr.wr_parm_r.SA, cgrd.cgr.wr_parm_r.Sn, -+ cgrd.cgr.wr_parm_r.Pn); -+ -+ seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n", -+ cgrd.cgr.wr_en_g, cgrd.cgr.wr_en_y, cgrd.cgr.wr_en_r); -+ -+ seq_printf(file, " cscn_en: %u\n", cgrd.cgr.cscn_en); -+ if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) { -+ seq_puts(file, " cscn_targ_dcp:\n"); -+ mask = 0x80000000; -+ for (i = 0; i < 32; i++) { -+ if (cgrd.cgr.cscn_targ & mask) -+ seq_printf(file, " send CSCN to dcp %u\n", -+ (31 - i)); -+ mask >>= 1; -+ } -+ -+ seq_puts(file, " cscn_targ_swp:\n"); -+ for (i = 0; i < 4; i++) { -+ mask = 0x80000000; -+ for (j = 0; j < 32; j++) { -+ if (cgrd.cscn_targ_swp[i] & mask) -+ seq_printf(file, " send CSCN to swp" -+ " %u\n", (127 - (i * 32) - j)); -+ mask >>= 1; -+ } -+ } -+ } else { -+ seq_printf(file, " cscn_targ: %u\n", cgrd.cgr.cscn_targ); -+ } -+ seq_printf(file, " cstd_en: %u\n", cgrd.cgr.cstd_en); -+ seq_printf(file, " cs: %u\n", cgrd.cgr.cs); -+ -+ seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n", -+ cgrd.cgr.cs_thres.TA, cgrd.cgr.cs_thres.Tn); -+ -+ seq_printf(file, " mode: %s\n", -+ (cgrd.cgr.mode & QMAN_CGR_MODE_FRAME) ? -+ "frame count" : "byte count"); -+ seq_printf(file, " i_bcnt: %llu\n", qm_mcr_querycgr_i_get64(&cgrd)); -+ seq_printf(file, " a_bcnt: %llu\n", qm_mcr_querycgr_a_get64(&cgrd)); -+ -+ return 0; -+} -+ -+static int query_cgr_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, query_cgr_show, NULL); -+} -+ -+static ssize_t query_cgr_write(struct file *f, const char __user *buf, -+ size_t count, loff_t *off) -+{ -+ int ret; -+ unsigned long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ if (val > 0xff) -+ return -EINVAL; -+ query_cgr_data.cgid = (u8)val; -+ return count; -+} -+ -+static const struct file_operations query_cgr_fops = { -+ .owner = THIS_MODULE, -+ .open = query_cgr_open, -+ .read = seq_read, -+ .write = query_cgr_write, -+ .release = single_release, -+}; -+ -+/******************************************************************************* -+ * Test Write CGR -+ ******************************************************************************/ -+struct test_write_cgr_s { -+ u64 i_bcnt; -+ u8 cgid; -+}; -+static struct test_write_cgr_s test_write_cgr_data; -+ -+static int testwrite_cgr_show(struct seq_file *file, void *offset) -+{ -+ int ret; -+ struct qm_mcr_cgrtestwrite result; -+ struct qman_cgr cgr; -+ u64 i_bcnt; -+ -+ memset(&cgr, 0, sizeof(struct qman_cgr)); -+ memset(&result, 0, sizeof(struct qm_mcr_cgrtestwrite)); -+ cgr.cgrid = test_write_cgr_data.cgid; -+ i_bcnt = test_write_cgr_data.i_bcnt; -+ ret = qman_testwrite_cgr(&cgr, i_bcnt, &result); -+ if (ret) -+ return ret; -+ seq_printf(file, "CGR Test Write CGR id 0x%x\n", cgr.cgrid); -+ seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n", -+ result.cgr.wr_parm_g.MA, result.cgr.wr_parm_g.Mn, -+ result.cgr.wr_parm_g.SA, result.cgr.wr_parm_g.Sn, -+ result.cgr.wr_parm_g.Pn); -+ seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n", -+ result.cgr.wr_parm_y.MA, result.cgr.wr_parm_y.Mn, -+ result.cgr.wr_parm_y.SA, result.cgr.wr_parm_y.Sn, -+ result.cgr.wr_parm_y.Pn); -+ seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n", -+ result.cgr.wr_parm_r.MA, result.cgr.wr_parm_r.Mn, -+ result.cgr.wr_parm_r.SA, result.cgr.wr_parm_r.Sn, -+ result.cgr.wr_parm_r.Pn); -+ seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n", -+ result.cgr.wr_en_g, result.cgr.wr_en_y, result.cgr.wr_en_r); -+ seq_printf(file, " cscn_en: %u\n", result.cgr.cscn_en); -+ seq_printf(file, " cscn_targ: %u\n", result.cgr.cscn_targ); -+ seq_printf(file, " cstd_en: %u\n", result.cgr.cstd_en); -+ seq_printf(file, " cs: %u\n", result.cgr.cs); -+ seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n", -+ result.cgr.cs_thres.TA, result.cgr.cs_thres.Tn); -+ -+ /* Add Mode for Si 2 */ -+ seq_printf(file, " mode: %s\n", -+ (result.cgr.mode & QMAN_CGR_MODE_FRAME) ? -+ "frame count" : "byte count"); -+ -+ seq_printf(file, " i_bcnt: %llu\n", -+ qm_mcr_cgrtestwrite_i_get64(&result)); -+ seq_printf(file, " a_bcnt: %llu\n", -+ qm_mcr_cgrtestwrite_a_get64(&result)); -+ seq_printf(file, " wr_prob_g: %u\n", result.wr_prob_g); -+ seq_printf(file, " wr_prob_y: %u\n", result.wr_prob_y); -+ seq_printf(file, " wr_prob_r: %u\n", result.wr_prob_r); -+ return 0; -+} -+ -+static int testwrite_cgr_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, testwrite_cgr_show, NULL); -+} -+ -+static const struct file_operations testwrite_cgr_fops = { -+ .owner = THIS_MODULE, -+ .open = testwrite_cgr_open, -+ .read = seq_read, -+ .release = single_release, -+}; -+ -+ -+static int testwrite_cgr_ibcnt_show(struct seq_file *file, void *offset) -+{ -+ seq_printf(file, "i_bcnt: %llu\n", test_write_cgr_data.i_bcnt); -+ return 0; -+} -+static int testwrite_cgr_ibcnt_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, testwrite_cgr_ibcnt_show, NULL); -+} -+ -+static ssize_t testwrite_cgr_ibcnt_write(struct file *f, const char __user *buf, -+ size_t count, loff_t *off) -+{ -+ int ret; -+ unsigned long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ test_write_cgr_data.i_bcnt = val; -+ return count; -+} -+ -+static const struct file_operations teswrite_cgr_ibcnt_fops = { -+ .owner = THIS_MODULE, -+ .open = testwrite_cgr_ibcnt_open, -+ .read = seq_read, -+ .write = testwrite_cgr_ibcnt_write, -+ .release = single_release, -+}; -+ -+static int testwrite_cgr_cgrid_show(struct seq_file *file, void *offset) -+{ -+ seq_printf(file, "cgrid: %u\n", (u32)test_write_cgr_data.cgid); -+ return 0; -+} -+static int testwrite_cgr_cgrid_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, testwrite_cgr_cgrid_show, NULL); -+} -+ -+static ssize_t testwrite_cgr_cgrid_write(struct file *f, const char __user *buf, -+ size_t count, loff_t *off) -+{ -+ int ret; -+ unsigned long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ if (val > 0xff) -+ return -EINVAL; -+ test_write_cgr_data.cgid = (u8)val; -+ return count; -+} -+ -+static const struct file_operations teswrite_cgr_cgrid_fops = { -+ .owner = THIS_MODULE, -+ .open = testwrite_cgr_cgrid_open, -+ .read = seq_read, -+ .write = testwrite_cgr_cgrid_write, -+ .release = single_release, -+}; -+ -+/******************************************************************************* -+ * Query Congestion State -+ ******************************************************************************/ -+static int query_congestion_show(struct seq_file *file, void *offset) -+{ -+ int ret; -+ struct qm_mcr_querycongestion cs; -+ int i, j, in_cong = 0; -+ u32 mask; -+ -+ memset(&cs, 0, sizeof(struct qm_mcr_querycongestion)); -+ ret = qman_query_congestion(&cs); -+ if (ret) -+ return ret; -+ seq_puts(file, "Query Congestion Result\n"); -+ for (i = 0; i < 8; i++) { -+ mask = 0x80000000; -+ for (j = 0; j < 32; j++) { -+ if (cs.state.__state[i] & mask) { -+ in_cong = 1; -+ seq_printf(file, " cg %u: %s\n", (i*32)+j, -+ "in congestion"); -+ } -+ mask >>= 1; -+ } -+ } -+ if (!in_cong) -+ seq_puts(file, " All congestion groups not congested.\n"); -+ return 0; -+} -+ -+static int query_congestion_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, query_congestion_show, NULL); -+} -+ -+static const struct file_operations query_congestion_fops = { -+ .owner = THIS_MODULE, -+ .open = query_congestion_open, -+ .read = seq_read, -+ .release = single_release, -+}; -+ -+/******************************************************************************* -+ * Query CCGR -+ ******************************************************************************/ -+struct query_ccgr_s { -+ u32 ccgid; -+}; -+static struct query_ccgr_s query_ccgr_data; -+ -+static int query_ccgr_show(struct seq_file *file, void *offset) -+{ -+ int ret; -+ struct qm_mcr_ceetm_ccgr_query ccgr_query; -+ struct qm_mcc_ceetm_ccgr_query query_opts; -+ int i, j; -+ u32 mask; -+ -+ memset(&ccgr_query, 0, sizeof(struct qm_mcr_ceetm_ccgr_query)); -+ memset(&query_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_query)); -+ -+ if ((qman_ip_rev & 0xFF00) < QMAN_REV30) -+ return -EINVAL; -+ -+ seq_printf(file, "Query CCGID %x\n", query_ccgr_data.ccgid); -+ query_opts.dcpid = ((query_ccgr_data.ccgid & 0xFF000000) >> 24); -+ query_opts.ccgrid = query_ccgr_data.ccgid & 0x000001FF; -+ ret = qman_ceetm_query_ccgr(&query_opts, &ccgr_query); -+ if (ret) -+ return ret; -+ seq_printf(file, "Query CCGR id %x in DCP %d\n", query_opts.ccgrid, -+ query_opts.dcpid); -+ seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n", -+ ccgr_query.cm_query.wr_parm_g.MA, -+ ccgr_query.cm_query.wr_parm_g.Mn, -+ ccgr_query.cm_query.wr_parm_g.SA, -+ ccgr_query.cm_query.wr_parm_g.Sn, -+ ccgr_query.cm_query.wr_parm_g.Pn); -+ -+ seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n", -+ ccgr_query.cm_query.wr_parm_y.MA, -+ ccgr_query.cm_query.wr_parm_y.Mn, -+ ccgr_query.cm_query.wr_parm_y.SA, -+ ccgr_query.cm_query.wr_parm_y.Sn, -+ ccgr_query.cm_query.wr_parm_y.Pn); -+ -+ seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n", -+ ccgr_query.cm_query.wr_parm_r.MA, -+ ccgr_query.cm_query.wr_parm_r.Mn, -+ ccgr_query.cm_query.wr_parm_r.SA, -+ ccgr_query.cm_query.wr_parm_r.Sn, -+ ccgr_query.cm_query.wr_parm_r.Pn); -+ -+ seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n", -+ ccgr_query.cm_query.ctl_wr_en_g, -+ ccgr_query.cm_query.ctl_wr_en_y, -+ ccgr_query.cm_query.ctl_wr_en_r); -+ -+ seq_printf(file, " cscn_en: %u\n", ccgr_query.cm_query.ctl_cscn_en); -+ seq_puts(file, " cscn_targ_dcp:\n"); -+ mask = 0x80000000; -+ for (i = 0; i < 32; i++) { -+ if (ccgr_query.cm_query.cscn_targ_dcp & mask) -+ seq_printf(file, " send CSCN to dcp %u\n", (31 - i)); -+ mask >>= 1; -+ } -+ -+ seq_puts(file, " cscn_targ_swp:\n"); -+ for (i = 0; i < 4; i++) { -+ mask = 0x80000000; -+ for (j = 0; j < 32; j++) { -+ if (ccgr_query.cm_query.cscn_targ_swp[i] & mask) -+ seq_printf(file, " send CSCN to swp" -+ "%u\n", (127 - (i * 32) - j)); -+ mask >>= 1; -+ } -+ } -+ -+ seq_printf(file, " td_en: %u\n", ccgr_query.cm_query.ctl_td_en); -+ -+ seq_printf(file, " cs_thresh_in_TA: %u, cs_thresh_in_Tn: %u\n", -+ ccgr_query.cm_query.cs_thres.TA, -+ ccgr_query.cm_query.cs_thres.Tn); -+ -+ seq_printf(file, " cs_thresh_out_TA: %u, cs_thresh_out_Tn: %u\n", -+ ccgr_query.cm_query.cs_thres_x.TA, -+ ccgr_query.cm_query.cs_thres_x.Tn); -+ -+ seq_printf(file, " td_thresh_TA: %u, td_thresh_Tn: %u\n", -+ ccgr_query.cm_query.td_thres.TA, -+ ccgr_query.cm_query.td_thres.Tn); -+ -+ seq_printf(file, " mode: %s\n", -+ (ccgr_query.cm_query.ctl_mode & -+ QMAN_CGR_MODE_FRAME) ? -+ "frame count" : "byte count"); -+ seq_printf(file, " i_cnt: %llu\n", (u64)ccgr_query.cm_query.i_cnt); -+ seq_printf(file, " a_cnt: %llu\n", (u64)ccgr_query.cm_query.a_cnt); -+ -+ return 0; -+} -+ -+static int query_ccgr_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, query_ccgr_show, NULL); -+} -+ -+static ssize_t query_ccgr_write(struct file *f, const char __user *buf, -+ size_t count, loff_t *off) -+{ -+ int ret; -+ unsigned long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ query_ccgr_data.ccgid = val; -+ return count; -+} -+ -+static const struct file_operations query_ccgr_fops = { -+ .owner = THIS_MODULE, -+ .open = query_ccgr_open, -+ .read = seq_read, -+ .write = query_ccgr_write, -+ .release = single_release, -+}; -+/******************************************************************************* -+ * QMan register -+ ******************************************************************************/ -+struct qman_register_s { -+ u32 val; -+}; -+static struct qman_register_s qman_register_data; -+ -+static void init_ccsrmempeek(void) -+{ -+ struct device_node *dn; -+ const u32 *regaddr_p; -+ -+ dn = of_find_compatible_node(NULL, NULL, "fsl,qman"); -+ if (!dn) { -+ pr_info("No fsl,qman node\n"); -+ return; -+ } -+ regaddr_p = of_get_address(dn, 0, &qman_ccsr_size, NULL); -+ if (!regaddr_p) { -+ of_node_put(dn); -+ return; -+ } -+ qman_ccsr_start = of_translate_address(dn, regaddr_p); -+ of_node_put(dn); -+} -+/* This function provides access to QMan ccsr memory map */ -+static int qman_ccsrmempeek(u32 *val, u32 offset) -+{ -+ void __iomem *addr; -+ u64 phys_addr; -+ -+ if (!qman_ccsr_start) -+ return -EINVAL; -+ -+ if (offset > (qman_ccsr_size - sizeof(u32))) -+ return -EINVAL; -+ -+ phys_addr = qman_ccsr_start + offset; -+ addr = ioremap(phys_addr, sizeof(u32)); -+ if (!addr) { -+ pr_err("ccsrmempeek, ioremap failed\n"); -+ return -EINVAL; -+ } -+ *val = in_be32(addr); -+ iounmap(addr); -+ return 0; -+} -+ -+static int qman_ccsrmempeek_show(struct seq_file *file, void *offset) -+{ -+ u32 b; -+ -+ qman_ccsrmempeek(&b, qman_register_data.val); -+ seq_printf(file, "QMan register offset = 0x%x\n", -+ qman_register_data.val); -+ seq_printf(file, "value = 0x%08x\n", b); -+ -+ return 0; -+} -+ -+static int qman_ccsrmempeek_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, qman_ccsrmempeek_show, NULL); -+} -+ -+static ssize_t qman_ccsrmempeek_write(struct file *f, const char __user *buf, -+ size_t count, loff_t *off) -+{ -+ int ret; -+ unsigned long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ /* multiple of 4 */ -+ if (val > (qman_ccsr_size - sizeof(u32))) { -+ pr_info("Input 0x%lx > 0x%llx\n", -+ val, (qman_ccsr_size - sizeof(u32))); -+ return -EINVAL; -+ } -+ if (val & 0x3) { -+ pr_info("Input 0x%lx not multiple of 4\n", val); -+ return -EINVAL; -+ } -+ qman_register_data.val = val; -+ return count; -+} -+ -+static const struct file_operations qman_ccsrmempeek_fops = { -+ .owner = THIS_MODULE, -+ .open = qman_ccsrmempeek_open, -+ .read = seq_read, -+ .write = qman_ccsrmempeek_write, -+}; -+ -+/******************************************************************************* -+ * QMan state -+ ******************************************************************************/ -+static int qman_fqd_state_show(struct seq_file *file, void *offset) -+{ -+ struct qm_mcr_queryfq_np np; -+ struct qman_fq fq; -+ struct line_buffer_fq line_buf; -+ int ret, i; -+ u8 *state = file->private; -+ u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)]; -+ -+ memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt)); -+ memset(&line_buf, 0, sizeof(line_buf)); -+ -+ seq_printf(file, "List of fq ids in state: %s\n", state_txt[*state]); -+ -+ for (i = 1; i < fqid_max; i++) { -+ fq.fqid = i; -+ ret = qman_query_fq_np(&fq, &np); -+ if (ret) -+ return ret; -+ if (*state == (np.state & QM_MCR_NP_STATE_MASK)) -+ add_to_line_buffer(&line_buf, fq.fqid, file); -+ /* Keep a summary count of all states */ -+ if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states)) -+ qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++; -+ } -+ flush_line_buffer(&line_buf, file); -+ -+ for (i = 0; i < ARRAY_SIZE(fqd_states); i++) { -+ seq_printf(file, "%s count = %u\n", state_txt[i], -+ qm_fq_state_cnt[i]); -+ } -+ return 0; -+} -+ -+static int qman_fqd_state_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, qman_fqd_state_show, inode->i_private); -+} -+ -+static const struct file_operations qman_fqd_state_fops = { -+ .owner = THIS_MODULE, -+ .open = qman_fqd_state_open, -+ .read = seq_read, -+}; -+ -+static int qman_fqd_ctrl_show(struct seq_file *file, void *offset) -+{ -+ struct qm_fqd fqd; -+ struct qman_fq fq; -+ u32 fq_en_cnt = 0, fq_di_cnt = 0; -+ int ret, i; -+ struct mask_filter_s *data = file->private; -+ const char *ctrl_txt = get_fqd_ctrl_text(data->mask); -+ struct line_buffer_fq line_buf; -+ -+ memset(&line_buf, 0, sizeof(line_buf)); -+ seq_printf(file, "List of fq ids with: %s :%s\n", -+ ctrl_txt, (data->filter) ? "enabled" : "disabled"); -+ for (i = 1; i < fqid_max; i++) { -+ fq.fqid = i; -+ memset(&fqd, 0, sizeof(struct qm_fqd)); -+ ret = qman_query_fq(&fq, &fqd); -+ if (ret) -+ return ret; -+ if (data->filter) { -+ if (fqd.fq_ctrl & data->mask) -+ add_to_line_buffer(&line_buf, fq.fqid, file); -+ } else { -+ if (!(fqd.fq_ctrl & data->mask)) -+ add_to_line_buffer(&line_buf, fq.fqid, file); -+ } -+ if (fqd.fq_ctrl & data->mask) -+ fq_en_cnt++; -+ else -+ fq_di_cnt++; -+ } -+ flush_line_buffer(&line_buf, file); -+ -+ seq_printf(file, "Total FQD with: %s : enabled = %u\n", -+ ctrl_txt, fq_en_cnt); -+ seq_printf(file, "Total FQD with: %s : disabled = %u\n", -+ ctrl_txt, fq_di_cnt); -+ return 0; -+} -+ -+/******************************************************************************* -+ * QMan ctrl CGE, TDE, ORP, CTX, CPC, SFDR, BLOCK, HOLD, CACHE -+ ******************************************************************************/ -+static int qman_fqd_ctrl_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, qman_fqd_ctrl_show, inode->i_private); -+} -+ -+static const struct file_operations qman_fqd_ctrl_fops = { -+ .owner = THIS_MODULE, -+ .open = qman_fqd_ctrl_open, -+ .read = seq_read, -+}; -+ -+/******************************************************************************* -+ * QMan ctrl summary -+ ******************************************************************************/ -+/******************************************************************************* -+ * QMan summary state -+ ******************************************************************************/ -+static int qman_fqd_non_prog_summary_show(struct seq_file *file, void *offset) -+{ -+ struct qm_mcr_queryfq_np np; -+ struct qman_fq fq; -+ int ret, i; -+ u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)]; -+ -+ memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt)); -+ -+ for (i = 1; i < fqid_max; i++) { -+ fq.fqid = i; -+ ret = qman_query_fq_np(&fq, &np); -+ if (ret) -+ return ret; -+ /* Keep a summary count of all states */ -+ if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states)) -+ qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(fqd_states); i++) { -+ seq_printf(file, "%s count = %u\n", state_txt[i], -+ qm_fq_state_cnt[i]); -+ } -+ return 0; -+} -+ -+static int qman_fqd_prog_summary_show(struct seq_file *file, void *offset) -+{ -+ struct qm_fqd fqd; -+ struct qman_fq fq; -+ int ret, i , j; -+ u32 qm_prog_cnt[ARRAY_SIZE(mask_filter)/2]; -+ -+ memset(qm_prog_cnt, 0, sizeof(qm_prog_cnt)); -+ -+ for (i = 1; i < fqid_max; i++) { -+ memset(&fqd, 0, sizeof(struct qm_fqd)); -+ fq.fqid = i; -+ ret = qman_query_fq(&fq, &fqd); -+ if (ret) -+ return ret; -+ /* Keep a summary count of all states */ -+ for (j = 0; j < ARRAY_SIZE(mask_filter); j += 2) -+ if ((fqd.fq_ctrl & QM_FQCTRL_MASK) & -+ mask_filter[j].mask) -+ qm_prog_cnt[j/2]++; -+ } -+ for (i = 0; i < ARRAY_SIZE(mask_filter) / 2; i++) { -+ seq_printf(file, "%s count = %u\n", -+ get_fqd_ctrl_text(mask_filter[i*2].mask), -+ qm_prog_cnt[i]); -+ } -+ return 0; -+} -+ -+static int qman_fqd_summary_show(struct seq_file *file, void *offset) -+{ -+ int ret; -+ -+ /* Display summary of non programmable fields */ -+ ret = qman_fqd_non_prog_summary_show(file, offset); -+ if (ret) -+ return ret; -+ seq_puts(file, "-----------------------------------------\n"); -+ /* Display programmable fields */ -+ ret = qman_fqd_prog_summary_show(file, offset); -+ if (ret) -+ return ret; -+ return 0; -+} -+ -+static int qman_fqd_summary_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, qman_fqd_summary_show, NULL); -+} -+ -+static const struct file_operations qman_fqd_summary_fops = { -+ .owner = THIS_MODULE, -+ .open = qman_fqd_summary_open, -+ .read = seq_read, -+}; -+ -+/******************************************************************************* -+ * QMan destination work queue -+ ******************************************************************************/ -+struct qman_dest_wq_s { -+ u16 wq_id; -+}; -+static struct qman_dest_wq_s qman_dest_wq_data = { -+ .wq_id = 0, -+}; -+ -+static int qman_fqd_dest_wq_show(struct seq_file *file, void *offset) -+{ -+ struct qm_fqd fqd; -+ struct qman_fq fq; -+ int ret, i; -+ u16 *wq, wq_id = qman_dest_wq_data.wq_id; -+ struct line_buffer_fq line_buf; -+ -+ memset(&line_buf, 0, sizeof(line_buf)); -+ /* use vmalloc : need to allocate large memory region and don't -+ * require the memory to be physically contiguous. */ -+ wq = vzalloc(sizeof(u16) * (0xFFFF+1)); -+ if (!wq) -+ return -ENOMEM; -+ -+ seq_printf(file, "List of fq ids with destination work queue id" -+ " = 0x%x\n", wq_id); -+ -+ for (i = 1; i < fqid_max; i++) { -+ fq.fqid = i; -+ memset(&fqd, 0, sizeof(struct qm_fqd)); -+ ret = qman_query_fq(&fq, &fqd); -+ if (ret) { -+ vfree(wq); -+ return ret; -+ } -+ if (wq_id == fqd.dest_wq) -+ add_to_line_buffer(&line_buf, fq.fqid, file); -+ wq[fqd.dest_wq]++; -+ } -+ flush_line_buffer(&line_buf, file); -+ -+ seq_puts(file, "Summary of all FQD destination work queue values\n"); -+ for (i = 0; i < 0xFFFF; i++) { -+ if (wq[i]) -+ seq_printf(file, "Channel: 0x%x WQ: 0x%x WQ_ID: 0x%x, " -+ "count = %u\n", i >> 3, i & 0x3, i, wq[i]); -+ } -+ vfree(wq); -+ return 0; -+} -+ -+static ssize_t qman_fqd_dest_wq_write(struct file *f, const char __user *buf, -+ size_t count, loff_t *off) -+{ -+ int ret; -+ unsigned long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ if (val > 0xFFFF) -+ return -EINVAL; -+ qman_dest_wq_data.wq_id = val; -+ return count; -+} -+ -+static int qman_fqd_dest_wq_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, qman_fqd_dest_wq_show, NULL); -+} -+ -+static const struct file_operations qman_fqd_dest_wq_fops = { -+ .owner = THIS_MODULE, -+ .open = qman_fqd_dest_wq_open, -+ .read = seq_read, -+ .write = qman_fqd_dest_wq_write, -+}; -+ -+/******************************************************************************* -+ * QMan Intra-Class Scheduling Credit -+ ******************************************************************************/ -+static int qman_fqd_cred_show(struct seq_file *file, void *offset) -+{ -+ struct qm_fqd fqd; -+ struct qman_fq fq; -+ int ret, i; -+ u32 fq_cnt = 0; -+ struct line_buffer_fq line_buf; -+ -+ memset(&line_buf, 0, sizeof(line_buf)); -+ seq_puts(file, "List of fq ids with Intra-Class Scheduling Credit > 0" -+ "\n"); -+ -+ for (i = 1; i < fqid_max; i++) { -+ fq.fqid = i; -+ memset(&fqd, 0, sizeof(struct qm_fqd)); -+ ret = qman_query_fq(&fq, &fqd); -+ if (ret) -+ return ret; -+ if (fqd.ics_cred > 0) { -+ add_to_line_buffer(&line_buf, fq.fqid, file); -+ fq_cnt++; -+ } -+ } -+ flush_line_buffer(&line_buf, file); -+ -+ seq_printf(file, "Total FQD with ics_cred > 0 = %d\n", fq_cnt); -+ return 0; -+} -+ -+static int qman_fqd_cred_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, qman_fqd_cred_show, NULL); -+} -+ -+static const struct file_operations qman_fqd_cred_fops = { -+ .owner = THIS_MODULE, -+ .open = qman_fqd_cred_open, -+ .read = seq_read, -+}; -+ -+/******************************************************************************* -+ * Class Queue Fields -+ ******************************************************************************/ -+struct query_cq_fields_data_s { -+ u32 cqid; -+}; -+ -+static struct query_cq_fields_data_s query_cq_fields_data = { -+ .cqid = 1, -+}; -+ -+static int query_cq_fields_show(struct seq_file *file, void *offset) -+{ -+ int ret; -+ struct qm_mcr_ceetm_cq_query query_result; -+ unsigned int cqid; -+ unsigned int portal; -+ -+ if ((qman_ip_rev & 0xFF00) < QMAN_REV30) -+ return -EINVAL; -+ -+ cqid = query_cq_fields_data.cqid & 0x00FFFFFF; -+ portal = query_cq_fields_data.cqid >> 24; -+ if (portal > qm_dc_portal_fman1) -+ return -EINVAL; -+ -+ ret = qman_ceetm_query_cq(cqid, portal, &query_result); -+ if (ret) -+ return ret; -+ seq_printf(file, "Query CQ Fields Result cqid 0x%x on DCP %d\n", -+ cqid, portal); -+ seq_printf(file, " ccgid: %u\n", query_result.ccgid); -+ seq_printf(file, " state: %u\n", query_result.state); -+ seq_printf(file, " pfdr_hptr: %u\n", query_result.pfdr_hptr); -+ seq_printf(file, " pfdr_tptr: %u\n", query_result.pfdr_tptr); -+ seq_printf(file, " od1_xsfdr: %u\n", query_result.od1_xsfdr); -+ seq_printf(file, " od2_xsfdr: %u\n", query_result.od2_xsfdr); -+ seq_printf(file, " od3_xsfdr: %u\n", query_result.od3_xsfdr); -+ seq_printf(file, " od4_xsfdr: %u\n", query_result.od4_xsfdr); -+ seq_printf(file, " od5_xsfdr: %u\n", query_result.od5_xsfdr); -+ seq_printf(file, " od6_xsfdr: %u\n", query_result.od6_xsfdr); -+ seq_printf(file, " ra1_xsfdr: %u\n", query_result.ra1_xsfdr); -+ seq_printf(file, " ra2_xsfdr: %u\n", query_result.ra2_xsfdr); -+ seq_printf(file, " frame_count: %u\n", query_result.frm_cnt); -+ -+ return 0; -+} -+ -+static int query_cq_fields_open(struct inode *inode, -+ struct file *file) -+{ -+ return single_open(file, query_cq_fields_show, NULL); -+} -+ -+static ssize_t query_cq_fields_write(struct file *f, -+ const char __user *buf, size_t count, loff_t *off) -+{ -+ int ret; -+ unsigned long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ query_cq_fields_data.cqid = (u32)val; -+ return count; -+} -+ -+static const struct file_operations query_cq_fields_fops = { -+ .owner = THIS_MODULE, -+ .open = query_cq_fields_open, -+ .read = seq_read, -+ .write = query_cq_fields_write, -+ .release = single_release, -+}; -+ -+/******************************************************************************* -+ * READ CEETM_XSFDR_IN_USE -+ ******************************************************************************/ -+struct query_ceetm_xsfdr_data_s { -+ enum qm_dc_portal dcp_portal; -+}; -+ -+static struct query_ceetm_xsfdr_data_s query_ceetm_xsfdr_data; -+ -+static int query_ceetm_xsfdr_show(struct seq_file *file, void *offset) -+{ -+ int ret; -+ unsigned int xsfdr_in_use; -+ enum qm_dc_portal portal; -+ -+ -+ if (qman_ip_rev < QMAN_REV31) -+ return -EINVAL; -+ -+ portal = query_ceetm_xsfdr_data.dcp_portal; -+ ret = qman_ceetm_get_xsfdr(portal, &xsfdr_in_use); -+ if (ret) { -+ seq_printf(file, "Read CEETM_XSFDR_IN_USE on DCP %d failed\n", -+ portal); -+ return ret; -+ } -+ -+ seq_printf(file, "DCP%d: CEETM_XSFDR_IN_USE number is %u\n", portal, -+ (xsfdr_in_use & 0x1FFF)); -+ return 0; -+} -+ -+static int query_ceetm_xsfdr_open(struct inode *inode, -+ struct file *file) -+{ -+ return single_open(file, query_ceetm_xsfdr_show, NULL); -+} -+ -+static ssize_t query_ceetm_xsfdr_write(struct file *f, -+ const char __user *buf, size_t count, loff_t *off) -+{ -+ int ret; -+ unsigned long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ if (val > qm_dc_portal_fman1) -+ return -EINVAL; -+ query_ceetm_xsfdr_data.dcp_portal = (u32)val; -+ return count; -+} -+ -+static const struct file_operations query_ceetm_xsfdr_fops = { -+ .owner = THIS_MODULE, -+ .open = query_ceetm_xsfdr_open, -+ .read = seq_read, -+ .write = query_ceetm_xsfdr_write, -+ .release = single_release, -+}; -+ -+/* helper macros used in qman_debugfs_module_init */ -+#define QMAN_DBGFS_ENTRY(name, mode, parent, data, fops) \ -+ do { \ -+ d = debugfs_create_file(name, \ -+ mode, parent, \ -+ data, \ -+ fops); \ -+ if (d == NULL) { \ -+ ret = -ENOMEM; \ -+ goto _return; \ -+ } \ -+ } while (0) -+ -+/* dfs_root as parent */ -+#define QMAN_DBGFS_ENTRY_ROOT(name, mode, data, fops) \ -+ QMAN_DBGFS_ENTRY(name, mode, dfs_root, data, fops) -+ -+/* fqd_root as parent */ -+#define QMAN_DBGFS_ENTRY_FQDROOT(name, mode, data, fops) \ -+ QMAN_DBGFS_ENTRY(name, mode, fqd_root, data, fops) -+ -+/* fqd state */ -+#define QMAN_DBGFS_ENTRY_FQDSTATE(name, index) \ -+ QMAN_DBGFS_ENTRY_FQDROOT(name, S_IRUGO, \ -+ (void *)&mask_filter[index], &qman_fqd_ctrl_fops) -+ -+static int __init qman_debugfs_module_init(void) -+{ -+ int ret = 0; -+ struct dentry *d, *fqd_root; -+ u32 reg; -+ -+ fqid_max = 0; -+ init_ccsrmempeek(); -+ if (qman_ccsr_start) { -+ if (!qman_ccsrmempeek(®, QM_FQD_AR)) { -+ /* extract the size of the FQD window */ -+ reg = reg & 0x3f; -+ /* calculate valid frame queue descriptor range */ -+ fqid_max = (1 << (reg + 1)) / QM_FQD_BLOCK_SIZE; -+ } -+ } -+ dfs_root = debugfs_create_dir("qman", NULL); -+ fqd_root = debugfs_create_dir("fqd", dfs_root); -+ if (dfs_root == NULL || fqd_root == NULL) { -+ ret = -ENOMEM; -+ pr_err("Cannot create qman/fqd debugfs dir\n"); -+ goto _return; -+ } -+ if (fqid_max) { -+ QMAN_DBGFS_ENTRY_ROOT("ccsrmempeek", S_IRUGO | S_IWUGO, -+ NULL, &qman_ccsrmempeek_fops); -+ } -+ QMAN_DBGFS_ENTRY_ROOT("query_fq_np_fields", S_IRUGO | S_IWUGO, -+ &query_fq_np_fields_data, &query_fq_np_fields_fops); -+ -+ QMAN_DBGFS_ENTRY_ROOT("query_fq_fields", S_IRUGO | S_IWUGO, -+ &query_fq_fields_data, &query_fq_fields_fops); -+ -+ QMAN_DBGFS_ENTRY_ROOT("query_wq_lengths", S_IRUGO | S_IWUGO, -+ &query_wq_lengths_data, &query_wq_lengths_fops); -+ -+ QMAN_DBGFS_ENTRY_ROOT("query_cgr", S_IRUGO | S_IWUGO, -+ &query_cgr_data, &query_cgr_fops); -+ -+ QMAN_DBGFS_ENTRY_ROOT("query_congestion", S_IRUGO, -+ NULL, &query_congestion_fops); -+ -+ QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr", S_IRUGO, -+ NULL, &testwrite_cgr_fops); -+ -+ QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_cgrid", S_IRUGO | S_IWUGO, -+ NULL, &teswrite_cgr_cgrid_fops); -+ -+ QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_ibcnt", S_IRUGO | S_IWUGO, -+ NULL, &teswrite_cgr_ibcnt_fops); -+ -+ QMAN_DBGFS_ENTRY_ROOT("query_ceetm_ccgr", S_IRUGO | S_IWUGO, -+ &query_ccgr_data, &query_ccgr_fops); -+ /* Create files with fqd_root as parent */ -+ -+ QMAN_DBGFS_ENTRY_FQDROOT("stateoos", S_IRUGO, -+ (void *)&fqd_states[QM_MCR_NP_STATE_OOS], &qman_fqd_state_fops); -+ -+ QMAN_DBGFS_ENTRY_FQDROOT("state_retired", S_IRUGO, -+ (void *)&fqd_states[QM_MCR_NP_STATE_RETIRED], -+ &qman_fqd_state_fops); -+ -+ QMAN_DBGFS_ENTRY_FQDROOT("state_tentatively_sched", S_IRUGO, -+ (void *)&fqd_states[QM_MCR_NP_STATE_TEN_SCHED], -+ &qman_fqd_state_fops); -+ -+ QMAN_DBGFS_ENTRY_FQDROOT("state_truly_sched", S_IRUGO, -+ (void *)&fqd_states[QM_MCR_NP_STATE_TRU_SCHED], -+ &qman_fqd_state_fops); -+ -+ QMAN_DBGFS_ENTRY_FQDROOT("state_parked", S_IRUGO, -+ (void *)&fqd_states[QM_MCR_NP_STATE_PARKED], -+ &qman_fqd_state_fops); -+ -+ QMAN_DBGFS_ENTRY_FQDROOT("state_active", S_IRUGO, -+ (void *)&fqd_states[QM_MCR_NP_STATE_ACTIVE], -+ &qman_fqd_state_fops); -+ QMAN_DBGFS_ENTRY_ROOT("query_cq_fields", S_IRUGO | S_IWUGO, -+ &query_cq_fields_data, &query_cq_fields_fops); -+ QMAN_DBGFS_ENTRY_ROOT("query_ceetm_xsfdr_in_use", S_IRUGO | S_IWUGO, -+ &query_ceetm_xsfdr_data, &query_ceetm_xsfdr_fops); -+ -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("cge_enable", 17); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("cge_disable", 16); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("tde_enable", 15); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("tde_disable", 14); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("orp_enable", 13); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("orp_disable", 12); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_enable", 11); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_disable", 10); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("cpc_enable", 9); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("cpc_disable", 8); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_enable", 7); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_disable", 6); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_enable", 5); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_disable", 4); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_enable", 3); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_disable", 2); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_enable", 1); -+ -+ QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_disable", 0); -+ -+ QMAN_DBGFS_ENTRY_FQDROOT("summary", S_IRUGO, -+ NULL, &qman_fqd_summary_fops); -+ -+ QMAN_DBGFS_ENTRY_FQDROOT("wq", S_IRUGO | S_IWUGO, -+ NULL, &qman_fqd_dest_wq_fops); -+ -+ QMAN_DBGFS_ENTRY_FQDROOT("cred", S_IRUGO, -+ NULL, &qman_fqd_cred_fops); -+ -+ return 0; -+ -+_return: -+ debugfs_remove_recursive(dfs_root); -+ return ret; -+} -+ -+static void __exit qman_debugfs_module_exit(void) -+{ -+ debugfs_remove_recursive(dfs_root); -+} -+ -+module_init(qman_debugfs_module_init); -+module_exit(qman_debugfs_module_exit); -+MODULE_LICENSE("Dual BSD/GPL"); ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_driver.c -@@ -0,0 +1,961 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "qman_private.h" -+ -+#include /* hard_smp_processor_id() if !CONFIG_SMP */ -+#ifdef CONFIG_HOTPLUG_CPU -+#include -+#endif -+ -+/* Global variable containing revision id (even on non-control plane systems -+ * where CCSR isn't available) */ -+u16 qman_ip_rev; -+EXPORT_SYMBOL(qman_ip_rev); -+u8 qman_ip_cfg; -+EXPORT_SYMBOL(qman_ip_cfg); -+u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1; -+EXPORT_SYMBOL(qm_channel_pool1); -+u16 qm_channel_caam = QMAN_CHANNEL_CAAM; -+EXPORT_SYMBOL(qm_channel_caam); -+u16 qm_channel_pme = QMAN_CHANNEL_PME; -+EXPORT_SYMBOL(qm_channel_pme); -+u16 qm_channel_dce = QMAN_CHANNEL_DCE; -+EXPORT_SYMBOL(qm_channel_dce); -+u16 qman_portal_max; -+EXPORT_SYMBOL(qman_portal_max); -+ -+u32 qman_clk; -+struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX]; -+/* the qman ceetm instances on the given SoC */ -+u8 num_ceetms; -+ -+/* For these variables, and the portal-initialisation logic, the -+ * comments in bman_driver.c apply here so won't be repeated. */ -+static struct qman_portal *shared_portals[NR_CPUS]; -+static int num_shared_portals; -+static int shared_portals_idx; -+static LIST_HEAD(unused_pcfgs); -+static DEFINE_SPINLOCK(unused_pcfgs_lock); -+ -+/* A SDQCR mask comprising all the available/visible pool channels */ -+static u32 pools_sdqcr; -+ -+#define STR_ERR_NOPROP "No '%s' property in node %s\n" -+#define STR_ERR_CELL "'%s' is not a %d-cell range in node %s\n" -+#define STR_FQID_RANGE "fsl,fqid-range" -+#define STR_POOL_CHAN_RANGE "fsl,pool-channel-range" -+#define STR_CGRID_RANGE "fsl,cgrid-range" -+ -+/* A "fsl,fqid-range" node; release the given range to the allocator */ -+static __init int fsl_fqid_range_init(struct device_node *node) -+{ -+ int ret; -+ const u32 *range = of_get_property(node, STR_FQID_RANGE, &ret); -+ if (!range) { -+ pr_err(STR_ERR_NOPROP, STR_FQID_RANGE, node->full_name); -+ return -EINVAL; -+ } -+ if (ret != 8) { -+ pr_err(STR_ERR_CELL, STR_FQID_RANGE, 2, node->full_name); -+ return -EINVAL; -+ } -+ qman_seed_fqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ pr_info("Qman: FQID allocator includes range %d:%d\n", -+ be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ return 0; -+} -+ -+/* A "fsl,pool-channel-range" node; add to the SDQCR mask only */ -+static __init int fsl_pool_channel_range_sdqcr(struct device_node *node) -+{ -+ int ret; -+ const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret); -+ if (!chanid) { -+ pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name); -+ return -EINVAL; -+ } -+ if (ret != 8) { -+ pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name); -+ return -EINVAL; -+ } -+ for (ret = 0; ret < be32_to_cpu(chanid[1]); ret++) -+ pools_sdqcr |= QM_SDQCR_CHANNELS_POOL_CONV(be32_to_cpu(chanid[0]) + ret); -+ return 0; -+} -+ -+/* A "fsl,pool-channel-range" node; release the given range to the allocator */ -+static __init int fsl_pool_channel_range_init(struct device_node *node) -+{ -+ int ret; -+ const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret); -+ if (!chanid) { -+ pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name); -+ return -EINVAL; -+ } -+ if (ret != 8) { -+ pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name); -+ return -EINVAL; -+ } -+ qman_seed_pool_range(be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1])); -+ pr_info("Qman: pool channel allocator includes range %d:%d\n", -+ be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1])); -+ return 0; -+} -+ -+/* A "fsl,cgrid-range" node; release the given range to the allocator */ -+static __init int fsl_cgrid_range_init(struct device_node *node) -+{ -+ struct qman_cgr cgr; -+ int ret, errors = 0; -+ const u32 *range = of_get_property(node, STR_CGRID_RANGE, &ret); -+ if (!range) { -+ pr_err(STR_ERR_NOPROP, STR_CGRID_RANGE, node->full_name); -+ return -EINVAL; -+ } -+ if (ret != 8) { -+ pr_err(STR_ERR_CELL, STR_CGRID_RANGE, 2, node->full_name); -+ return -EINVAL; -+ } -+ qman_seed_cgrid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ pr_info("Qman: CGRID allocator includes range %d:%d\n", -+ be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ for (cgr.cgrid = 0; cgr.cgrid < __CGR_NUM; cgr.cgrid++) { -+ ret = qman_modify_cgr(&cgr, QMAN_CGR_FLAG_USE_INIT, NULL); -+ if (ret) -+ errors++; -+ } -+ if (errors) -+ pr_err("Warning: %d error%s while initialising CGRs %d:%d\n", -+ errors, (errors > 1) ? "s" : "", range[0], range[1]); -+ return 0; -+} -+ -+static __init int fsl_ceetm_init(struct device_node *node) -+{ -+ enum qm_dc_portal dcp_portal; -+ struct qm_ceetm_sp *sp; -+ struct qm_ceetm_lni *lni; -+ int ret, i; -+ const u32 *range; -+ -+ /* Find LFQID range */ -+ range = of_get_property(node, "fsl,ceetm-lfqid-range", &ret); -+ if (!range) { -+ pr_err("No fsl,ceetm-lfqid-range in node %s\n", -+ node->full_name); -+ return -EINVAL; -+ } -+ if (ret != 8) { -+ pr_err("fsl,ceetm-lfqid-range is not a 2-cell range in node" -+ " %s\n", node->full_name); -+ return -EINVAL; -+ } -+ -+ dcp_portal = (be32_to_cpu(range[0]) & 0x0F0000) >> 16; -+ if (dcp_portal > qm_dc_portal_fman1) { -+ pr_err("The DCP portal %d doesn't support CEETM\n", dcp_portal); -+ return -EINVAL; -+ } -+ -+ if (dcp_portal == qm_dc_portal_fman0) -+ qman_seed_ceetm0_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ if (dcp_portal == qm_dc_portal_fman1) -+ qman_seed_ceetm1_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ pr_debug("Qman: The lfqid allocator of CEETM %d includes range" -+ " 0x%x:0x%x\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ -+ qman_ceetms[dcp_portal].idx = dcp_portal; -+ INIT_LIST_HEAD(&qman_ceetms[dcp_portal].sub_portals); -+ INIT_LIST_HEAD(&qman_ceetms[dcp_portal].lnis); -+ -+ /* Find Sub-portal range */ -+ range = of_get_property(node, "fsl,ceetm-sp-range", &ret); -+ if (!range) { -+ pr_err("No fsl,ceetm-sp-range in node %s\n", node->full_name); -+ return -EINVAL; -+ } -+ if (ret != 8) { -+ pr_err("fsl,ceetm-sp-range is not a 2-cell range in node %s\n", -+ node->full_name); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < be32_to_cpu(range[1]); i++) { -+ sp = kzalloc(sizeof(*sp), GFP_KERNEL); -+ if (!sp) { -+ pr_err("Can't alloc memory for sub-portal %d\n", -+ range[0] + i); -+ return -ENOMEM; -+ } -+ sp->idx = be32_to_cpu(range[0]) + i; -+ sp->dcp_idx = dcp_portal; -+ sp->is_claimed = 0; -+ list_add_tail(&sp->node, &qman_ceetms[dcp_portal].sub_portals); -+ sp++; -+ } -+ pr_debug("Qman: Reserve sub-portal %d:%d for CEETM %d\n", -+ be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal); -+ qman_ceetms[dcp_portal].sp_range[0] = be32_to_cpu(range[0]); -+ qman_ceetms[dcp_portal].sp_range[1] = be32_to_cpu(range[1]); -+ -+ /* Find LNI range */ -+ range = of_get_property(node, "fsl,ceetm-lni-range", &ret); -+ if (!range) { -+ pr_err("No fsl,ceetm-lni-range in node %s\n", node->full_name); -+ return -EINVAL; -+ } -+ if (ret != 8) { -+ pr_err("fsl,ceetm-lni-range is not a 2-cell range in node %s\n", -+ node->full_name); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < be32_to_cpu(range[1]); i++) { -+ lni = kzalloc(sizeof(*lni), GFP_KERNEL); -+ if (!lni) { -+ pr_err("Can't alloc memory for LNI %d\n", -+ range[0] + i); -+ return -ENOMEM; -+ } -+ lni->idx = be32_to_cpu(range[0]) + i; -+ lni->dcp_idx = dcp_portal; -+ lni->is_claimed = 0; -+ INIT_LIST_HEAD(&lni->channels); -+ list_add_tail(&lni->node, &qman_ceetms[dcp_portal].lnis); -+ lni++; -+ } -+ pr_debug("Qman: Reserve LNI %d:%d for CEETM %d\n", -+ be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal); -+ qman_ceetms[dcp_portal].lni_range[0] = be32_to_cpu(range[0]); -+ qman_ceetms[dcp_portal].lni_range[1] = be32_to_cpu(range[1]); -+ -+ /* Find CEETM channel range */ -+ range = of_get_property(node, "fsl,ceetm-channel-range", &ret); -+ if (!range) { -+ pr_err("No fsl,ceetm-channel-range in node %s\n", -+ node->full_name); -+ return -EINVAL; -+ } -+ if (ret != 8) { -+ pr_err("fsl,ceetm-channel-range is not a 2-cell range in node" -+ "%s\n", node->full_name); -+ return -EINVAL; -+ } -+ -+ if (dcp_portal == qm_dc_portal_fman0) -+ qman_seed_ceetm0_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ if (dcp_portal == qm_dc_portal_fman1) -+ qman_seed_ceetm1_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ pr_debug("Qman: The channel allocator of CEETM %d includes" -+ " range %d:%d\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1])); -+ -+ /* Set CEETM PRES register */ -+ ret = qman_ceetm_set_prescaler(dcp_portal); -+ if (ret) -+ return ret; -+ return 0; -+} -+ -+static void qman_get_ip_revision(struct device_node *dn) -+{ -+ u16 ip_rev = 0; -+ u8 ip_cfg = QMAN_REV_CFG_0; -+ for_each_compatible_node(dn, NULL, "fsl,qman-portal") { -+ if (!of_device_is_available(dn)) -+ continue; -+ if (of_device_is_compatible(dn, "fsl,qman-portal-1.0") || -+ of_device_is_compatible(dn, "fsl,qman-portal-1.0.0")) { -+ pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n"); -+ BUG_ON(1); -+ } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.1") || -+ of_device_is_compatible(dn, "fsl,qman-portal-1.1.0")) { -+ ip_rev = QMAN_REV11; -+ qman_portal_max = 10; -+ } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.2") || -+ of_device_is_compatible(dn, "fsl,qman-portal-1.2.0")) { -+ ip_rev = QMAN_REV12; -+ qman_portal_max = 10; -+ } else if (of_device_is_compatible(dn, "fsl,qman-portal-2.0") || -+ of_device_is_compatible(dn, "fsl,qman-portal-2.0.0")) { -+ ip_rev = QMAN_REV20; -+ qman_portal_max = 3; -+ } else if (of_device_is_compatible(dn, -+ "fsl,qman-portal-3.0.0")) { -+ ip_rev = QMAN_REV30; -+ qman_portal_max = 50; -+ } else if (of_device_is_compatible(dn, -+ "fsl,qman-portal-3.0.1")) { -+ ip_rev = QMAN_REV30; -+ qman_portal_max = 25; -+ ip_cfg = QMAN_REV_CFG_1; -+ } else if (of_device_is_compatible(dn, -+ "fsl,qman-portal-3.1.0")) { -+ ip_rev = QMAN_REV31; -+ qman_portal_max = 50; -+ } else if (of_device_is_compatible(dn, -+ "fsl,qman-portal-3.1.1")) { -+ ip_rev = QMAN_REV31; -+ qman_portal_max = 25; -+ ip_cfg = QMAN_REV_CFG_1; -+ } else if (of_device_is_compatible(dn, -+ "fsl,qman-portal-3.1.2")) { -+ ip_rev = QMAN_REV31; -+ qman_portal_max = 18; -+ ip_cfg = QMAN_REV_CFG_2; -+ } else if (of_device_is_compatible(dn, -+ "fsl,qman-portal-3.1.3")) { -+ ip_rev = QMAN_REV31; -+ qman_portal_max = 10; -+ ip_cfg = QMAN_REV_CFG_3; -+ } else if (of_device_is_compatible(dn, -+ "fsl,qman-portal-3.2.0")) { -+ ip_rev = QMAN_REV32; -+ qman_portal_max = 10; -+ ip_cfg = QMAN_REV_CFG_3; // TODO: Verify for ls1043 -+ } else if (of_device_is_compatible(dn, -+ "fsl,qman-portal-3.2.1")) { -+ ip_rev = QMAN_REV32; -+ qman_portal_max = 10; -+ ip_cfg = QMAN_REV_CFG_3; -+ } else { -+ pr_warn("unknown QMan version in portal node," -+ "default to rev1.1\n"); -+ ip_rev = QMAN_REV11; -+ qman_portal_max = 10; -+ } -+ -+ if (!qman_ip_rev) { -+ if (ip_rev) { -+ qman_ip_rev = ip_rev; -+ qman_ip_cfg = ip_cfg; -+ } else { -+ pr_warn("unknown Qman version," -+ " default to rev1.1\n"); -+ qman_ip_rev = QMAN_REV11; -+ qman_ip_cfg = QMAN_REV_CFG_0; -+ } -+ } else if (ip_rev && (qman_ip_rev != ip_rev)) -+ pr_warn("Revision=0x%04x, but portal '%s' has" -+ " 0x%04x\n", -+ qman_ip_rev, dn->full_name, ip_rev); -+ if (qman_ip_rev == ip_rev) -+ break; -+ } -+} -+ -+/* Parse a portal node, perform generic mapping duties and return the config. It -+ * is not known at this stage for what purpose (or even if) the portal will be -+ * used. */ -+static struct qm_portal_config * __init parse_pcfg(struct device_node *node) -+{ -+ struct qm_portal_config *pcfg; -+ const u32 *index_p; -+ u32 index, channel; -+ int irq, ret; -+ resource_size_t len; -+ -+ pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL); -+ if (!pcfg) { -+ pr_err("can't allocate portal config"); -+ return NULL; -+ } -+ -+ /* -+ * This is a *horrible hack*, but the IOMMU/PAMU driver needs a -+ * 'struct device' in order to get the PAMU stashing setup and the QMan -+ * portal [driver] won't function at all without ring stashing -+ * -+ * Making the QMan portal driver nice and proper is part of the -+ * upstreaming effort -+ */ -+ pcfg->dev.bus = &platform_bus_type; -+ pcfg->dev.of_node = node; -+#ifdef CONFIG_FSL_PAMU -+ pcfg->dev.archdata.iommu_domain = NULL; -+#endif -+ -+ ret = of_address_to_resource(node, DPA_PORTAL_CE, -+ &pcfg->addr_phys[DPA_PORTAL_CE]); -+ if (ret) { -+ pr_err("Can't get %s property '%s'\n", node->full_name, -+ "reg::CE"); -+ goto err; -+ } -+ ret = of_address_to_resource(node, DPA_PORTAL_CI, -+ &pcfg->addr_phys[DPA_PORTAL_CI]); -+ if (ret) { -+ pr_err("Can't get %s property '%s'\n", node->full_name, -+ "reg::CI"); -+ goto err; -+ } -+ index_p = of_get_property(node, "cell-index", &ret); -+ if (!index_p || (ret != 4)) { -+ pr_err("Can't get %s property '%s'\n", node->full_name, -+ "cell-index"); -+ goto err; -+ } -+ index = be32_to_cpu(*index_p); -+ if (index >= qman_portal_max) { -+ pr_err("QMan portal index %d is beyond max (%d)\n", -+ index, qman_portal_max); -+ goto err; -+ } -+ -+ channel = index + QM_CHANNEL_SWPORTAL0; -+ pcfg->public_cfg.channel = channel; -+ pcfg->public_cfg.cpu = -1; -+ irq = irq_of_parse_and_map(node, 0); -+ if (irq == 0) { -+ pr_err("Can't get %s property '%s'\n", node->full_name, -+ "interrupts"); -+ goto err; -+ } -+ pcfg->public_cfg.irq = irq; -+ pcfg->public_cfg.index = index; -+#ifdef CONFIG_FSL_QMAN_CONFIG -+ /* We need the same LIODN offset for all portals */ -+ qman_liodn_fixup(pcfg->public_cfg.channel); -+#endif -+ -+ len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]); -+ if (len != (unsigned long)len) -+ goto err; -+ -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns( -+ pcfg->addr_phys[DPA_PORTAL_CE].start, -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CE])); -+ -+ pcfg->addr_virt[DPA_PORTAL_CI] = ioremap( -+ pcfg->addr_phys[DPA_PORTAL_CI].start, -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CI])); -+#else -+ pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot( -+ pcfg->addr_phys[DPA_PORTAL_CE].start, -+ (unsigned long)len, -+ 0); -+ pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot( -+ pcfg->addr_phys[DPA_PORTAL_CI].start, -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]), -+ _PAGE_GUARDED | _PAGE_NO_CACHE); -+#endif -+ return pcfg; -+err: -+ kfree(pcfg); -+ return NULL; -+} -+ -+static struct qm_portal_config *get_pcfg(struct list_head *list) -+{ -+ struct qm_portal_config *pcfg; -+ if (list_empty(list)) -+ return NULL; -+ pcfg = list_entry(list->prev, struct qm_portal_config, list); -+ list_del(&pcfg->list); -+ return pcfg; -+} -+ -+static struct qm_portal_config *get_pcfg_idx(struct list_head *list, u32 idx) -+{ -+ struct qm_portal_config *pcfg; -+ if (list_empty(list)) -+ return NULL; -+ list_for_each_entry(pcfg, list, list) { -+ if (pcfg->public_cfg.index == idx) { -+ list_del(&pcfg->list); -+ return pcfg; -+ } -+ } -+ return NULL; -+} -+ -+static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu) -+{ -+#ifdef CONFIG_FSL_PAMU -+ int ret; -+ int window_count = 1; -+ struct iommu_domain_geometry geom_attr; -+ struct pamu_stash_attribute stash_attr; -+ -+ pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type); -+ if (!pcfg->iommu_domain) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed", -+ __func__); -+ goto _no_iommu; -+ } -+ geom_attr.aperture_start = 0; -+ geom_attr.aperture_end = -+ ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1; -+ geom_attr.force_aperture = true; -+ ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY, -+ &geom_attr); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d", -+ __func__, ret); -+ goto _iommu_domain_free; -+ } -+ ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS, -+ &window_count); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d", -+ __func__, ret); -+ goto _iommu_domain_free; -+ } -+ stash_attr.cpu = cpu; -+ stash_attr.cache = PAMU_ATTR_CACHE_L1; -+ /* set stash information for the window */ -+ stash_attr.window = 0; -+ ret = iommu_domain_set_attr(pcfg->iommu_domain, -+ DOMAIN_ATTR_FSL_PAMU_STASH, -+ &stash_attr); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d", -+ __func__, ret); -+ goto _iommu_domain_free; -+ } -+ ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36, -+ IOMMU_READ | IOMMU_WRITE); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d", -+ __func__, ret); -+ goto _iommu_domain_free; -+ } -+ ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d", -+ __func__, ret); -+ goto _iommu_domain_free; -+ } -+ ret = iommu_domain_set_attr(pcfg->iommu_domain, -+ DOMAIN_ATTR_FSL_PAMU_ENABLE, -+ &window_count); -+ if (ret < 0) { -+ pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d", -+ __func__, ret); -+ goto _iommu_detach_device; -+ } -+ -+_no_iommu: -+#endif -+#ifdef CONFIG_FSL_QMAN_CONFIG -+ if (qman_set_sdest(pcfg->public_cfg.channel, cpu)) -+#endif -+ pr_warn("Failed to set QMan portal's stash request queue\n"); -+ -+ return; -+ -+#ifdef CONFIG_FSL_PAMU -+_iommu_detach_device: -+ iommu_detach_device(pcfg->iommu_domain, NULL); -+_iommu_domain_free: -+ iommu_domain_free(pcfg->iommu_domain); -+#endif -+} -+ -+struct qm_portal_config *qm_get_unused_portal_idx(u32 idx) -+{ -+ struct qm_portal_config *ret; -+ spin_lock(&unused_pcfgs_lock); -+ if (idx == QBMAN_ANY_PORTAL_IDX) -+ ret = get_pcfg(&unused_pcfgs); -+ else -+ ret = get_pcfg_idx(&unused_pcfgs, idx); -+ spin_unlock(&unused_pcfgs_lock); -+ /* Bind stashing LIODNs to the CPU we are currently executing on, and -+ * set the portal to use the stashing request queue corresonding to the -+ * cpu as well. The user-space driver assumption is that the pthread has -+ * to already be affine to one cpu only before opening a portal. If that -+ * check is circumvented, the only risk is a performance degradation - -+ * stashing will go to whatever cpu they happened to be running on when -+ * opening the device file, and if that isn't the cpu they subsequently -+ * bind to and do their polling on, tough. */ -+ if (ret) -+ portal_set_cpu(ret, hard_smp_processor_id()); -+ return ret; -+} -+ -+struct qm_portal_config *qm_get_unused_portal(void) -+{ -+ return qm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX); -+} -+ -+void qm_put_unused_portal(struct qm_portal_config *pcfg) -+{ -+ spin_lock(&unused_pcfgs_lock); -+ list_add(&pcfg->list, &unused_pcfgs); -+ spin_unlock(&unused_pcfgs_lock); -+} -+ -+static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg) -+{ -+ struct qman_portal *p; -+ -+ pcfg->iommu_domain = NULL; -+ portal_set_cpu(pcfg, pcfg->public_cfg.cpu); -+ p = qman_create_affine_portal(pcfg, NULL); -+ if (p) { -+ u32 irq_sources = 0; -+ /* Determine what should be interrupt-vs-poll driven */ -+#ifdef CONFIG_FSL_DPA_PIRQ_SLOW -+ irq_sources |= QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI | -+ QM_PIRQ_CSCI | QM_PIRQ_CCSCI; -+#endif -+#ifdef CONFIG_FSL_DPA_PIRQ_FAST -+ irq_sources |= QM_PIRQ_DQRI; -+#endif -+ qman_p_irqsource_add(p, irq_sources); -+ pr_info("Qman portal %sinitialised, cpu %d\n", -+ pcfg->public_cfg.is_shared ? "(shared) " : "", -+ pcfg->public_cfg.cpu); -+ } else -+ pr_crit("Qman portal failure on cpu %d\n", -+ pcfg->public_cfg.cpu); -+ return p; -+} -+ -+static void init_slave(int cpu) -+{ -+ struct qman_portal *p; -+ struct cpumask oldmask = current->cpus_allowed; -+ set_cpus_allowed_ptr(current, get_cpu_mask(cpu)); -+ p = qman_create_affine_slave(shared_portals[shared_portals_idx++], cpu); -+ if (!p) -+ pr_err("Qman slave portal failure on cpu %d\n", cpu); -+ else -+ pr_info("Qman portal %sinitialised, cpu %d\n", "(slave) ", cpu); -+ set_cpus_allowed_ptr(current, &oldmask); -+ if (shared_portals_idx >= num_shared_portals) -+ shared_portals_idx = 0; -+} -+ -+static struct cpumask want_unshared __initdata; -+static struct cpumask want_shared __initdata; -+ -+static int __init parse_qportals(char *str) -+{ -+ return parse_portals_bootarg(str, &want_shared, &want_unshared, -+ "qportals"); -+} -+__setup("qportals=", parse_qportals); -+ -+static void qman_portal_update_sdest(const struct qm_portal_config *pcfg, -+ unsigned int cpu) -+{ -+#ifdef CONFIG_FSL_PAMU -+ struct pamu_stash_attribute stash_attr; -+ int ret; -+ -+ if (pcfg->iommu_domain) { -+ stash_attr.cpu = cpu; -+ stash_attr.cache = PAMU_ATTR_CACHE_L1; -+ /* set stash information for the window */ -+ stash_attr.window = 0; -+ ret = iommu_domain_set_attr(pcfg->iommu_domain, -+ DOMAIN_ATTR_FSL_PAMU_STASH, &stash_attr); -+ if (ret < 0) { -+ pr_err("Failed to update pamu stash setting\n"); -+ return; -+ } -+ } -+#endif -+#ifdef CONFIG_FSL_QMAN_CONFIG -+ if (qman_set_sdest(pcfg->public_cfg.channel, cpu)) -+ pr_warn("Failed to update portal's stash request queue\n"); -+#endif -+} -+ -+static int qman_offline_cpu(unsigned int cpu) -+{ -+ struct qman_portal *p; -+ const struct qm_portal_config *pcfg; -+ p = (struct qman_portal *)affine_portals[cpu]; -+ if (p) { -+ pcfg = qman_get_qm_portal_config(p); -+ if (pcfg) { -+ irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0)); -+ qman_portal_update_sdest(pcfg, 0); -+ } -+ } -+ return 0; -+} -+ -+#ifdef CONFIG_HOTPLUG_CPU -+static int qman_online_cpu(unsigned int cpu) -+{ -+ struct qman_portal *p; -+ const struct qm_portal_config *pcfg; -+ p = (struct qman_portal *)affine_portals[cpu]; -+ if (p) { -+ pcfg = qman_get_qm_portal_config(p); -+ if (pcfg) { -+ irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu)); -+ qman_portal_update_sdest(pcfg, cpu); -+ } -+ } -+ return 0; -+} -+ -+#endif /* CONFIG_HOTPLUG_CPU */ -+ -+__init int qman_init(void) -+{ -+ struct cpumask slave_cpus; -+ struct cpumask unshared_cpus = *cpu_none_mask; -+ struct cpumask shared_cpus = *cpu_none_mask; -+ LIST_HEAD(unshared_pcfgs); -+ LIST_HEAD(shared_pcfgs); -+ struct device_node *dn; -+ struct qm_portal_config *pcfg; -+ struct qman_portal *p; -+ int cpu, ret; -+ const u32 *clk; -+ struct cpumask offline_cpus; -+ -+ /* Initialise the Qman (CCSR) device */ -+ for_each_compatible_node(dn, NULL, "fsl,qman") { -+ if (!qman_init_ccsr(dn)) -+ pr_info("Qman err interrupt handler present\n"); -+ else -+ pr_err("Qman CCSR setup failed\n"); -+ -+ clk = of_get_property(dn, "clock-frequency", NULL); -+ if (!clk) -+ pr_warn("Can't find Qman clock frequency\n"); -+ else -+ qman_clk = be32_to_cpu(*clk); -+ } -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ /* Setup lookup table for FQ demux */ -+ ret = qman_setup_fq_lookup_table(get_qman_fqd_size()/64); -+ if (ret) -+ return ret; -+#endif -+ -+ /* Get qman ip revision */ -+ qman_get_ip_revision(dn); -+ if ((qman_ip_rev & 0xff00) >= QMAN_REV30) { -+ qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3; -+ qm_channel_caam = QMAN_CHANNEL_CAAM_REV3; -+ qm_channel_pme = QMAN_CHANNEL_PME_REV3; -+ } -+ -+ if ((qman_ip_rev == QMAN_REV31) && (qman_ip_cfg == QMAN_REV_CFG_2)) -+ qm_channel_dce = QMAN_CHANNEL_DCE_QMANREV312; -+ -+ /* -+ * Parse the ceetm node to get how many ceetm instances are supported -+ * on the current silicon. num_ceetms must be confirmed before portals -+ * are intiailized. -+ */ -+ num_ceetms = 0; -+ for_each_compatible_node(dn, NULL, "fsl,qman-ceetm") -+ num_ceetms++; -+ -+ /* Parse pool channels into the SDQCR mask. (Must happen before portals -+ * are initialised.) */ -+ for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") { -+ ret = fsl_pool_channel_range_sdqcr(dn); -+ if (ret) -+ return ret; -+ } -+ -+ memset(affine_portals, 0, sizeof(void *) * num_possible_cpus()); -+ /* Initialise portals. See bman_driver.c for comments */ -+ for_each_compatible_node(dn, NULL, "fsl,qman-portal") { -+ if (!of_device_is_available(dn)) -+ continue; -+ pcfg = parse_pcfg(dn); -+ if (pcfg) { -+ pcfg->public_cfg.pools = pools_sdqcr; -+ list_add_tail(&pcfg->list, &unused_pcfgs); -+ } -+ } -+ for_each_possible_cpu(cpu) { -+ if (cpumask_test_cpu(cpu, &want_shared)) { -+ pcfg = get_pcfg(&unused_pcfgs); -+ if (!pcfg) -+ break; -+ pcfg->public_cfg.cpu = cpu; -+ list_add_tail(&pcfg->list, &shared_pcfgs); -+ cpumask_set_cpu(cpu, &shared_cpus); -+ } -+ if (cpumask_test_cpu(cpu, &want_unshared)) { -+ if (cpumask_test_cpu(cpu, &shared_cpus)) -+ continue; -+ pcfg = get_pcfg(&unused_pcfgs); -+ if (!pcfg) -+ break; -+ pcfg->public_cfg.cpu = cpu; -+ list_add_tail(&pcfg->list, &unshared_pcfgs); -+ cpumask_set_cpu(cpu, &unshared_cpus); -+ } -+ } -+ if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) { -+ for_each_online_cpu(cpu) { -+ pcfg = get_pcfg(&unused_pcfgs); -+ if (!pcfg) -+ break; -+ pcfg->public_cfg.cpu = cpu; -+ list_add_tail(&pcfg->list, &unshared_pcfgs); -+ cpumask_set_cpu(cpu, &unshared_cpus); -+ } -+ } -+ cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus); -+ cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus); -+ if (cpumask_empty(&slave_cpus)) { -+ if (!list_empty(&shared_pcfgs)) { -+ cpumask_or(&unshared_cpus, &unshared_cpus, -+ &shared_cpus); -+ cpumask_clear(&shared_cpus); -+ list_splice_tail(&shared_pcfgs, &unshared_pcfgs); -+ INIT_LIST_HEAD(&shared_pcfgs); -+ } -+ } else { -+ if (list_empty(&shared_pcfgs)) { -+ pcfg = get_pcfg(&unshared_pcfgs); -+ if (!pcfg) { -+ pr_crit("No QMan portals available!\n"); -+ return 0; -+ } -+ cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus); -+ cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus); -+ list_add_tail(&pcfg->list, &shared_pcfgs); -+ } -+ } -+ list_for_each_entry(pcfg, &unshared_pcfgs, list) { -+ pcfg->public_cfg.is_shared = 0; -+ p = init_pcfg(pcfg); -+ if (!p) { -+ pr_crit("Unable to configure portals\n"); -+ return 0; -+ } -+ } -+ list_for_each_entry(pcfg, &shared_pcfgs, list) { -+ pcfg->public_cfg.is_shared = 1; -+ p = init_pcfg(pcfg); -+ if (p) -+ shared_portals[num_shared_portals++] = p; -+ } -+ if (!cpumask_empty(&slave_cpus)) -+ for_each_cpu(cpu, &slave_cpus) -+ init_slave(cpu); -+ pr_info("Qman portals initialised\n"); -+ cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask); -+ for_each_cpu(cpu, &offline_cpus) -+ qman_offline_cpu(cpu); -+#ifdef CONFIG_HOTPLUG_CPU -+ ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, -+ "soc/qman_portal:online", -+ qman_online_cpu, qman_offline_cpu); -+ if (ret < 0) { -+ pr_err("qman: failed to register hotplug callbacks.\n"); -+ return ret; -+ } -+#endif -+ return 0; -+} -+ -+__init int qman_resource_init(void) -+{ -+ struct device_node *dn; -+ int ret; -+ -+ /* Initialise FQID allocation ranges */ -+ for_each_compatible_node(dn, NULL, "fsl,fqid-range") { -+ ret = fsl_fqid_range_init(dn); -+ if (ret) -+ return ret; -+ } -+ /* Initialise CGRID allocation ranges */ -+ for_each_compatible_node(dn, NULL, "fsl,cgrid-range") { -+ ret = fsl_cgrid_range_init(dn); -+ if (ret) -+ return ret; -+ } -+ /* Parse pool channels into the allocator. (Must happen after portals -+ * are initialised.) */ -+ for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") { -+ ret = fsl_pool_channel_range_init(dn); -+ if (ret) -+ return ret; -+ } -+ -+ /* Parse CEETM */ -+ for_each_compatible_node(dn, NULL, "fsl,qman-ceetm") { -+ ret = fsl_ceetm_init(dn); -+ if (ret) -+ return ret; -+ } -+ return 0; -+} -+ -+#ifdef CONFIG_SUSPEND -+void suspend_unused_qportal(void) -+{ -+ struct qm_portal_config *pcfg; -+ -+ if (list_empty(&unused_pcfgs)) -+ return; -+ -+ list_for_each_entry(pcfg, &unused_pcfgs, list) { -+#ifdef CONFIG_PM_DEBUG -+ pr_info("Need to save qportal %d\n", pcfg->public_cfg.index); -+#endif -+ /* save isdr, disable all via isdr, clear isr */ -+ pcfg->saved_isdr = -+ __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08); -+ __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] + -+ 0xe08); -+ __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] + -+ 0xe00); -+ } -+ return; -+} -+ -+void resume_unused_qportal(void) -+{ -+ struct qm_portal_config *pcfg; -+ -+ if (list_empty(&unused_pcfgs)) -+ return; -+ -+ list_for_each_entry(pcfg, &unused_pcfgs, list) { -+#ifdef CONFIG_PM_DEBUG -+ pr_info("Need to resume qportal %d\n", pcfg->public_cfg.index); -+#endif -+ /* restore isdr */ -+ __raw_writel(pcfg->saved_isdr, -+ pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08); -+ } -+ return; -+} -+#endif ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_high.c -@@ -0,0 +1,5669 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "qman_low.h" -+ -+/* Compilation constants */ -+#define DQRR_MAXFILL 15 -+#define EQCR_ITHRESH 4 /* if EQCR congests, interrupt threshold */ -+#define IRQNAME "QMan portal %d" -+#define MAX_IRQNAME 16 /* big enough for "QMan portal %d" */ -+ -+/* Divide 'n' by 'd', rounding down if 'r' is negative, rounding up if it's -+ * positive, and rounding to the closest value if it's zero. NB, this macro -+ * implicitly upgrades parameters to unsigned 64-bit, so feed it with types -+ * that are compatible with this. NB, these arguments should not be expressions -+ * unless it is safe for them to be evaluated multiple times. Eg. do not pass -+ * in "some_value++" as a parameter to the macro! */ -+#define ROUNDING(n, d, r) \ -+ (((r) < 0) ? div64_u64((n), (d)) : \ -+ (((r) > 0) ? div64_u64(((n) + (d) - 1), (d)) : \ -+ div64_u64(((n) + ((d) / 2)), (d)))) -+ -+/* Lock/unlock frame queues, subject to the "LOCKED" flag. This is about -+ * inter-processor locking only. Note, FQLOCK() is always called either under a -+ * local_irq_save() or from interrupt context - hence there's no need for irq -+ * protection (and indeed, attempting to nest irq-protection doesn't work, as -+ * the "irq en/disable" machinery isn't recursive...). */ -+#define FQLOCK(fq) \ -+ do { \ -+ struct qman_fq *__fq478 = (fq); \ -+ if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \ -+ spin_lock(&__fq478->fqlock); \ -+ } while (0) -+#define FQUNLOCK(fq) \ -+ do { \ -+ struct qman_fq *__fq478 = (fq); \ -+ if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \ -+ spin_unlock(&__fq478->fqlock); \ -+ } while (0) -+ -+static inline void fq_set(struct qman_fq *fq, u32 mask) -+{ -+ set_bits(mask, &fq->flags); -+} -+static inline void fq_clear(struct qman_fq *fq, u32 mask) -+{ -+ clear_bits(mask, &fq->flags); -+} -+static inline int fq_isset(struct qman_fq *fq, u32 mask) -+{ -+ return fq->flags & mask; -+} -+static inline int fq_isclear(struct qman_fq *fq, u32 mask) -+{ -+ return !(fq->flags & mask); -+} -+ -+struct qman_portal { -+ struct qm_portal p; -+ unsigned long bits; /* PORTAL_BITS_*** - dynamic, strictly internal */ -+ unsigned long irq_sources; -+ u32 use_eqcr_ci_stashing; -+ u32 slowpoll; /* only used when interrupts are off */ -+ struct qman_fq *vdqcr_owned; /* only 1 volatile dequeue at a time */ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ struct qman_fq *eqci_owned; /* only 1 enqueue WAIT_SYNC at a time */ -+#endif -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ raw_spinlock_t sharing_lock; /* only used if is_shared */ -+ int is_shared; -+ struct qman_portal *sharing_redirect; -+#endif -+ u32 sdqcr; -+ int dqrr_disable_ref; -+ /* A portal-specific handler for DCP ERNs. If this is NULL, the global -+ * handler is called instead. */ -+ qman_cb_dc_ern cb_dc_ern; -+ /* When the cpu-affine portal is activated, this is non-NULL */ -+ const struct qm_portal_config *config; -+ /* This is needed for providing a non-NULL device to dma_map_***() */ -+ struct platform_device *pdev; -+ struct dpa_rbtree retire_table; -+ char irqname[MAX_IRQNAME]; -+ /* 2-element array. cgrs[0] is mask, cgrs[1] is snapshot. */ -+ struct qman_cgrs *cgrs; -+ /* linked-list of CSCN handlers. */ -+ struct list_head cgr_cbs; -+ /* list lock */ -+ spinlock_t cgr_lock; -+ /* 2-element array. ccgrs[0] is mask, ccgrs[1] is snapshot. */ -+ struct qman_ccgrs *ccgrs[QMAN_CEETM_MAX]; -+ /* 256-element array, each is a linked-list of CCSCN handlers. */ -+ struct list_head ccgr_cbs[QMAN_CEETM_MAX]; -+ /* list lock */ -+ spinlock_t ccgr_lock; -+ /* track if memory was allocated by the driver */ -+ u8 alloced; -+ /* power management data */ -+ u32 save_isdr; -+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -+ /* Keep a shadow copy of the DQRR on LE systems as the SW needs to -+ * do byte swaps of DQRR read only memory. First entry must be aligned -+ * to 2 ** 10 to ensure DQRR index calculations based shadow copy -+ * address (6 bits for address shift + 4 bits for the DQRR size). -+ */ -+ struct qm_dqrr_entry shadow_dqrr[QM_DQRR_SIZE] __aligned(1024); -+#endif -+}; -+ -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+#define PORTAL_IRQ_LOCK(p, irqflags) \ -+ do { \ -+ if ((p)->is_shared) \ -+ raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \ -+ else \ -+ local_irq_save(irqflags); \ -+ } while (0) -+#define PORTAL_IRQ_UNLOCK(p, irqflags) \ -+ do { \ -+ if ((p)->is_shared) \ -+ raw_spin_unlock_irqrestore(&(p)->sharing_lock, \ -+ irqflags); \ -+ else \ -+ local_irq_restore(irqflags); \ -+ } while (0) -+#else -+#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags) -+#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags) -+#endif -+ -+/* Global handler for DCP ERNs. Used when the portal receiving the message does -+ * not have a portal-specific handler. */ -+static qman_cb_dc_ern cb_dc_ern; -+ -+static cpumask_t affine_mask; -+static DEFINE_SPINLOCK(affine_mask_lock); -+static u16 affine_channels[NR_CPUS]; -+static DEFINE_PER_CPU(struct qman_portal, qman_affine_portal); -+void *affine_portals[NR_CPUS]; -+ -+/* "raw" gets the cpu-local struct whether it's a redirect or not. */ -+static inline struct qman_portal *get_raw_affine_portal(void) -+{ -+ return &get_cpu_var(qman_affine_portal); -+} -+/* For ops that can redirect, this obtains the portal to use */ -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+static inline struct qman_portal *get_affine_portal(void) -+{ -+ struct qman_portal *p = get_raw_affine_portal(); -+ if (p->sharing_redirect) -+ return p->sharing_redirect; -+ return p; -+} -+#else -+#define get_affine_portal() get_raw_affine_portal() -+#endif -+/* For every "get", there must be a "put" */ -+static inline void put_affine_portal(void) -+{ -+ put_cpu_var(qman_affine_portal); -+} -+/* Exception: poll functions assume the caller is cpu-affine and in no risk of -+ * re-entrance, which are the two reasons we usually use the get/put_cpu_var() -+ * semantic - ie. to disable pre-emption. Some use-cases expect the execution -+ * context to remain as non-atomic during poll-triggered callbacks as it was -+ * when the poll API was first called (eg. NAPI), so we go out of our way in -+ * this case to not disable pre-emption. */ -+static inline struct qman_portal *get_poll_portal(void) -+{ -+ return &get_cpu_var(qman_affine_portal); -+} -+#define put_poll_portal() -+ -+/* This gives a FQID->FQ lookup to cover the fact that we can't directly demux -+ * retirement notifications (the fact they are sometimes h/w-consumed means that -+ * contextB isn't always a s/w demux - and as we can't know which case it is -+ * when looking at the notification, we have to use the slow lookup for all of -+ * them). NB, it's possible to have multiple FQ objects refer to the same FQID -+ * (though at most one of them should be the consumer), so this table isn't for -+ * all FQs - FQs are added when retirement commands are issued, and removed when -+ * they complete, which also massively reduces the size of this table. */ -+IMPLEMENT_DPA_RBTREE(fqtree, struct qman_fq, node, fqid); -+ -+/* This is what everything can wait on, even if it migrates to a different cpu -+ * to the one whose affine portal it is waiting on. */ -+static DECLARE_WAIT_QUEUE_HEAD(affine_queue); -+ -+static inline int table_push_fq(struct qman_portal *p, struct qman_fq *fq) -+{ -+ int ret = fqtree_push(&p->retire_table, fq); -+ if (ret) -+ pr_err("ERROR: double FQ-retirement %d\n", fq->fqid); -+ return ret; -+} -+ -+static inline void table_del_fq(struct qman_portal *p, struct qman_fq *fq) -+{ -+ fqtree_del(&p->retire_table, fq); -+} -+ -+static inline struct qman_fq *table_find_fq(struct qman_portal *p, u32 fqid) -+{ -+ return fqtree_find(&p->retire_table, fqid); -+} -+ -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+static void **qman_fq_lookup_table; -+static size_t qman_fq_lookup_table_size; -+ -+int qman_setup_fq_lookup_table(size_t num_entries) -+{ -+ num_entries++; -+ /* Allocate 1 more entry since the first entry is not used */ -+ qman_fq_lookup_table = vzalloc((num_entries * sizeof(void *))); -+ if (!qman_fq_lookup_table) { -+ pr_err("QMan: Could not allocate fq lookup table\n"); -+ return -ENOMEM; -+ } -+ qman_fq_lookup_table_size = num_entries; -+ pr_info("QMan: Allocated lookup table at %p, entry count %lu\n", -+ qman_fq_lookup_table, -+ (unsigned long)qman_fq_lookup_table_size); -+ return 0; -+} -+ -+/* global structure that maintains fq object mapping */ -+static DEFINE_SPINLOCK(fq_hash_table_lock); -+ -+static int find_empty_fq_table_entry(u32 *entry, struct qman_fq *fq) -+{ -+ u32 i; -+ -+ spin_lock(&fq_hash_table_lock); -+ /* Can't use index zero because this has special meaning -+ * in context_b field. */ -+ for (i = 1; i < qman_fq_lookup_table_size; i++) { -+ if (qman_fq_lookup_table[i] == NULL) { -+ *entry = i; -+ qman_fq_lookup_table[i] = fq; -+ spin_unlock(&fq_hash_table_lock); -+ return 0; -+ } -+ } -+ spin_unlock(&fq_hash_table_lock); -+ return -ENOMEM; -+} -+ -+static void clear_fq_table_entry(u32 entry) -+{ -+ spin_lock(&fq_hash_table_lock); -+ BUG_ON(entry >= qman_fq_lookup_table_size); -+ qman_fq_lookup_table[entry] = NULL; -+ spin_unlock(&fq_hash_table_lock); -+} -+ -+static inline struct qman_fq *get_fq_table_entry(u32 entry) -+{ -+ BUG_ON(entry >= qman_fq_lookup_table_size); -+ return qman_fq_lookup_table[entry]; -+} -+#endif -+ -+static inline void cpu_to_hw_fqd(struct qm_fqd *fqd) -+{ -+ /* Byteswap the FQD to HW format */ -+ fqd->fq_ctrl = cpu_to_be16(fqd->fq_ctrl); -+ fqd->dest_wq = cpu_to_be16(fqd->dest_wq); -+ fqd->ics_cred = cpu_to_be16(fqd->ics_cred); -+ fqd->context_b = cpu_to_be32(fqd->context_b); -+ fqd->context_a.opaque = cpu_to_be64(fqd->context_a.opaque); -+} -+ -+static inline void hw_fqd_to_cpu(struct qm_fqd *fqd) -+{ -+ /* Byteswap the FQD to CPU format */ -+ fqd->fq_ctrl = be16_to_cpu(fqd->fq_ctrl); -+ fqd->dest_wq = be16_to_cpu(fqd->dest_wq); -+ fqd->ics_cred = be16_to_cpu(fqd->ics_cred); -+ fqd->context_b = be32_to_cpu(fqd->context_b); -+ fqd->context_a.opaque = be64_to_cpu(fqd->context_a.opaque); -+} -+ -+/* Swap a 40 bit address */ -+static inline u64 cpu_to_be40(u64 in) -+{ -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ return in; -+#else -+ u64 out = 0; -+ u8 *p = (u8 *) &out; -+ p[0] = in >> 32; -+ p[1] = in >> 24; -+ p[2] = in >> 16; -+ p[3] = in >> 8; -+ p[4] = in >> 0; -+ return out; -+#endif -+} -+static inline u64 be40_to_cpu(u64 in) -+{ -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ return in; -+#else -+ u64 out = 0; -+ u8 *pout = (u8 *) &out; -+ u8 *pin = (u8 *) ∈ -+ pout[0] = pin[4]; -+ pout[1] = pin[3]; -+ pout[2] = pin[2]; -+ pout[3] = pin[1]; -+ pout[4] = pin[0]; -+ return out; -+#endif -+} -+ -+/* Swap a 24 bit value */ -+static inline u32 cpu_to_be24(u32 in) -+{ -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ return in; -+#else -+ u32 out = 0; -+ u8 *p = (u8 *) &out; -+ p[0] = in >> 16; -+ p[1] = in >> 8; -+ p[2] = in >> 0; -+ return out; -+#endif -+} -+ -+static inline u32 be24_to_cpu(u32 in) -+{ -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ return in; -+#else -+ u32 out = 0; -+ u8 *pout = (u8 *) &out; -+ u8 *pin = (u8 *) ∈ -+ pout[0] = pin[2]; -+ pout[1] = pin[1]; -+ pout[2] = pin[0]; -+ return out; -+#endif -+} -+ -+static inline u64 be48_to_cpu(u64 in) -+{ -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ return in; -+#else -+ u64 out = 0; -+ u8 *pout = (u8 *) &out; -+ u8 *pin = (u8 *) ∈ -+ -+ pout[0] = pin[5]; -+ pout[1] = pin[4]; -+ pout[2] = pin[3]; -+ pout[3] = pin[2]; -+ pout[4] = pin[1]; -+ pout[5] = pin[0]; -+ return out; -+#endif -+} -+static inline void cpu_to_hw_fd(struct qm_fd *fd) -+{ -+ fd->opaque_addr = cpu_to_be64(fd->opaque_addr); -+ fd->status = cpu_to_be32(fd->status); -+ fd->opaque = cpu_to_be32(fd->opaque); -+} -+ -+static inline void hw_fd_to_cpu(struct qm_fd *fd) -+{ -+ fd->opaque_addr = be64_to_cpu(fd->opaque_addr); -+ fd->status = be32_to_cpu(fd->status); -+ fd->opaque = be32_to_cpu(fd->opaque); -+} -+ -+static inline void hw_cq_query_to_cpu(struct qm_mcr_ceetm_cq_query *cq_query) -+{ -+ cq_query->ccgid = be16_to_cpu(cq_query->ccgid); -+ cq_query->state = be16_to_cpu(cq_query->state); -+ cq_query->pfdr_hptr = be24_to_cpu(cq_query->pfdr_hptr); -+ cq_query->pfdr_tptr = be24_to_cpu(cq_query->pfdr_tptr); -+ cq_query->od1_xsfdr = be16_to_cpu(cq_query->od1_xsfdr); -+ cq_query->od2_xsfdr = be16_to_cpu(cq_query->od2_xsfdr); -+ cq_query->od3_xsfdr = be16_to_cpu(cq_query->od3_xsfdr); -+ cq_query->od4_xsfdr = be16_to_cpu(cq_query->od4_xsfdr); -+ cq_query->od5_xsfdr = be16_to_cpu(cq_query->od5_xsfdr); -+ cq_query->od6_xsfdr = be16_to_cpu(cq_query->od6_xsfdr); -+ cq_query->ra1_xsfdr = be16_to_cpu(cq_query->ra1_xsfdr); -+ cq_query->ra2_xsfdr = be16_to_cpu(cq_query->ra2_xsfdr); -+ cq_query->frm_cnt = be24_to_cpu(cq_query->frm_cnt); -+} -+ -+static inline void hw_ccgr_query_to_cpu(struct qm_mcr_ceetm_ccgr_query *ccgr_q) -+{ -+ int i; -+ -+ ccgr_q->cm_query.cs_thres.hword = -+ be16_to_cpu(ccgr_q->cm_query.cs_thres.hword); -+ ccgr_q->cm_query.cs_thres_x.hword = -+ be16_to_cpu(ccgr_q->cm_query.cs_thres_x.hword); -+ ccgr_q->cm_query.td_thres.hword = -+ be16_to_cpu(ccgr_q->cm_query.td_thres.hword); -+ ccgr_q->cm_query.wr_parm_g.word = -+ be32_to_cpu(ccgr_q->cm_query.wr_parm_g.word); -+ ccgr_q->cm_query.wr_parm_y.word = -+ be32_to_cpu(ccgr_q->cm_query.wr_parm_y.word); -+ ccgr_q->cm_query.wr_parm_r.word = -+ be32_to_cpu(ccgr_q->cm_query.wr_parm_r.word); -+ ccgr_q->cm_query.cscn_targ_dcp = -+ be16_to_cpu(ccgr_q->cm_query.cscn_targ_dcp); -+ ccgr_q->cm_query.i_cnt = be40_to_cpu(ccgr_q->cm_query.i_cnt); -+ ccgr_q->cm_query.a_cnt = be40_to_cpu(ccgr_q->cm_query.a_cnt); -+ for (i = 0; i < ARRAY_SIZE(ccgr_q->cm_query.cscn_targ_swp); i++) -+ ccgr_q->cm_query.cscn_targ_swp[i] = -+ be32_to_cpu(ccgr_q->cm_query.cscn_targ_swp[i]); -+} -+ -+/* In the case that slow- and fast-path handling are both done by qman_poll() -+ * (ie. because there is no interrupt handling), we ought to balance how often -+ * we do the fast-path poll versus the slow-path poll. We'll use two decrementer -+ * sources, so we call the fast poll 'n' times before calling the slow poll -+ * once. The idle decrementer constant is used when the last slow-poll detected -+ * no work to do, and the busy decrementer constant when the last slow-poll had -+ * work to do. */ -+#define SLOW_POLL_IDLE 1000 -+#define SLOW_POLL_BUSY 10 -+static u32 __poll_portal_slow(struct qman_portal *p, u32 is); -+static inline unsigned int __poll_portal_fast(struct qman_portal *p, -+ unsigned int poll_limit); -+ -+/* Portal interrupt handler */ -+static irqreturn_t portal_isr(__always_unused int irq, void *ptr) -+{ -+ struct qman_portal *p = ptr; -+ /* -+ * The CSCI/CCSCI source is cleared inside __poll_portal_slow(), because -+ * it could race against a Query Congestion State command also given -+ * as part of the handling of this interrupt source. We mustn't -+ * clear it a second time in this top-level function. -+ */ -+ u32 clear = QM_DQAVAIL_MASK | (p->irq_sources & -+ ~(QM_PIRQ_CSCI | QM_PIRQ_CCSCI)); -+ u32 is = qm_isr_status_read(&p->p) & p->irq_sources; -+ /* DQRR-handling if it's interrupt-driven */ -+ if (is & QM_PIRQ_DQRI) -+ __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT); -+ /* Handling of anything else that's interrupt-driven */ -+ clear |= __poll_portal_slow(p, is); -+ qm_isr_status_clear(&p->p, clear); -+ return IRQ_HANDLED; -+} -+ -+/* This inner version is used privately by qman_create_affine_portal(), as well -+ * as by the exported qman_stop_dequeues(). */ -+static inline void qman_stop_dequeues_ex(struct qman_portal *p) -+{ -+ unsigned long irqflags __maybe_unused; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ if (!(p->dqrr_disable_ref++)) -+ qm_dqrr_set_maxfill(&p->p, 0); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+} -+ -+static int drain_mr_fqrni(struct qm_portal *p) -+{ -+ const struct qm_mr_entry *msg; -+loop: -+ msg = qm_mr_current(p); -+ if (!msg) { -+ /* if MR was full and h/w had other FQRNI entries to produce, we -+ * need to allow it time to produce those entries once the -+ * existing entries are consumed. A worst-case situation -+ * (fully-loaded system) means h/w sequencers may have to do 3-4 -+ * other things before servicing the portal's MR pump, each of -+ * which (if slow) may take ~50 qman cycles (which is ~200 -+ * processor cycles). So rounding up and then multiplying this -+ * worst-case estimate by a factor of 10, just to be -+ * ultra-paranoid, goes as high as 10,000 cycles. NB, we consume -+ * one entry at a time, so h/w has an opportunity to produce new -+ * entries well before the ring has been fully consumed, so -+ * we're being *really* paranoid here. */ -+ u64 now, then = mfatb(); -+ do { -+ now = mfatb(); -+ } while ((then + 10000) > now); -+ msg = qm_mr_current(p); -+ if (!msg) -+ return 0; -+ } -+ if ((msg->verb & QM_MR_VERB_TYPE_MASK) != QM_MR_VERB_FQRNI) { -+ /* We aren't draining anything but FQRNIs */ -+ pr_err("QMan found verb 0x%x in MR\n", msg->verb); -+ return -1; -+ } -+ qm_mr_next(p); -+ qm_mr_cci_consume(p, 1); -+ goto loop; -+} -+ -+#ifdef CONFIG_SUSPEND -+static int _qman_portal_suspend_noirq(struct device *dev) -+{ -+ struct qman_portal *p = (struct qman_portal *)dev->platform_data; -+#ifdef CONFIG_PM_DEBUG -+ struct platform_device *pdev = to_platform_device(dev); -+#endif -+ -+ p->save_isdr = qm_isr_disable_read(&p->p); -+ qm_isr_disable_write(&p->p, 0xffffffff); -+ qm_isr_status_clear(&p->p, 0xffffffff); -+#ifdef CONFIG_PM_DEBUG -+ pr_info("Suspend for %s\n", pdev->name); -+#endif -+ return 0; -+} -+ -+static int _qman_portal_resume_noirq(struct device *dev) -+{ -+ struct qman_portal *p = (struct qman_portal *)dev->platform_data; -+ -+ /* restore isdr */ -+ qm_isr_disable_write(&p->p, p->save_isdr); -+ return 0; -+} -+#else -+#define _qman_portal_suspend_noirq NULL -+#define _qman_portal_resume_noirq NULL -+#endif -+ -+struct dev_pm_domain qman_portal_device_pm_domain = { -+ .ops = { -+ USE_PLATFORM_PM_SLEEP_OPS -+ .suspend_noirq = _qman_portal_suspend_noirq, -+ .resume_noirq = _qman_portal_resume_noirq, -+ } -+}; -+ -+struct qman_portal *qman_create_portal( -+ struct qman_portal *portal, -+ const struct qm_portal_config *config, -+ const struct qman_cgrs *cgrs) -+{ -+ struct qm_portal *__p; -+ char buf[16]; -+ int ret; -+ u32 isdr; -+ -+ if (!portal) { -+ portal = kmalloc(sizeof(*portal), GFP_KERNEL); -+ if (!portal) -+ return portal; -+ portal->alloced = 1; -+ } else -+ portal->alloced = 0; -+ -+ __p = &portal->p; -+ -+#if (defined CONFIG_PPC || defined CONFIG_PPC64) && defined CONFIG_FSL_PAMU -+ /* PAMU is required for stashing */ -+ portal->use_eqcr_ci_stashing = ((qman_ip_rev >= QMAN_REV30) ? -+ 1 : 0); -+#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ portal->use_eqcr_ci_stashing = 1; -+#else -+ portal->use_eqcr_ci_stashing = 0; -+#endif -+ -+ /* prep the low-level portal struct with the mapped addresses from the -+ * config, everything that follows depends on it and "config" is more -+ * for (de)reference... */ -+ __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE]; -+ __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI]; -+ /* -+ * If CI-stashing is used, the current defaults use a threshold of 3, -+ * and stash with high-than-DQRR priority. -+ */ -+ if (qm_eqcr_init(__p, qm_eqcr_pvb, -+ portal->use_eqcr_ci_stashing ? 3 : 0, 1)) { -+ pr_err("Qman EQCR initialisation failed\n"); -+ goto fail_eqcr; -+ } -+ if (qm_dqrr_init(__p, config, qm_dqrr_dpush, qm_dqrr_pvb, -+ qm_dqrr_cdc, DQRR_MAXFILL)) { -+ pr_err("Qman DQRR initialisation failed\n"); -+ goto fail_dqrr; -+ } -+ if (qm_mr_init(__p, qm_mr_pvb, qm_mr_cci)) { -+ pr_err("Qman MR initialisation failed\n"); -+ goto fail_mr; -+ } -+ if (qm_mc_init(__p)) { -+ pr_err("Qman MC initialisation failed\n"); -+ goto fail_mc; -+ } -+ if (qm_isr_init(__p)) { -+ pr_err("Qman ISR initialisation failed\n"); -+ goto fail_isr; -+ } -+ /* static interrupt-gating controls */ -+ qm_dqrr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_DQRR_ITHRESH); -+ qm_mr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_MR_ITHRESH); -+ qm_isr_set_iperiod(__p, CONFIG_FSL_QMAN_PIRQ_IPERIOD); -+ portal->cgrs = kmalloc(2 * sizeof(*cgrs), GFP_KERNEL); -+ if (!portal->cgrs) -+ goto fail_cgrs; -+ /* initial snapshot is no-depletion */ -+ qman_cgrs_init(&portal->cgrs[1]); -+ if (cgrs) -+ portal->cgrs[0] = *cgrs; -+ else -+ /* if the given mask is NULL, assume all CGRs can be seen */ -+ qman_cgrs_fill(&portal->cgrs[0]); -+ INIT_LIST_HEAD(&portal->cgr_cbs); -+ spin_lock_init(&portal->cgr_lock); -+ if (num_ceetms) { -+ for (ret = 0; ret < num_ceetms; ret++) { -+ portal->ccgrs[ret] = kmalloc(2 * -+ sizeof(struct qman_ccgrs), GFP_KERNEL); -+ if (!portal->ccgrs[ret]) -+ goto fail_ccgrs; -+ qman_ccgrs_init(&portal->ccgrs[ret][1]); -+ qman_ccgrs_fill(&portal->ccgrs[ret][0]); -+ INIT_LIST_HEAD(&portal->ccgr_cbs[ret]); -+ } -+ } -+ spin_lock_init(&portal->ccgr_lock); -+ portal->bits = 0; -+ portal->slowpoll = 0; -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ portal->eqci_owned = NULL; -+#endif -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ raw_spin_lock_init(&portal->sharing_lock); -+ portal->is_shared = config->public_cfg.is_shared; -+ portal->sharing_redirect = NULL; -+#endif -+ portal->sdqcr = QM_SDQCR_SOURCE_CHANNELS | QM_SDQCR_COUNT_UPTO3 | -+ QM_SDQCR_DEDICATED_PRECEDENCE | QM_SDQCR_TYPE_PRIO_QOS | -+ QM_SDQCR_TOKEN_SET(0xab) | QM_SDQCR_CHANNELS_DEDICATED; -+ portal->dqrr_disable_ref = 0; -+ portal->cb_dc_ern = NULL; -+ sprintf(buf, "qportal-%d", config->public_cfg.channel); -+ portal->pdev = platform_device_alloc(buf, -1); -+ if (!portal->pdev) { -+ pr_err("qman_portal - platform_device_alloc() failed\n"); -+ goto fail_devalloc; -+ } -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ portal->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40); -+ portal->pdev->dev.dma_mask = &portal->pdev->dev.coherent_dma_mask; -+#else -+ if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) { -+ pr_err("qman_portal - dma_set_mask() failed\n"); -+ goto fail_devadd; -+ } -+#endif -+ portal->pdev->dev.pm_domain = &qman_portal_device_pm_domain; -+ portal->pdev->dev.platform_data = portal; -+ ret = platform_device_add(portal->pdev); -+ if (ret) { -+ pr_err("qman_portal - platform_device_add() failed\n"); -+ goto fail_devadd; -+ } -+ dpa_rbtree_init(&portal->retire_table); -+ isdr = 0xffffffff; -+ qm_isr_disable_write(__p, isdr); -+ portal->irq_sources = 0; -+ qm_isr_enable_write(__p, portal->irq_sources); -+ qm_isr_status_clear(__p, 0xffffffff); -+ snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu); -+ if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname, -+ portal)) { -+ pr_err("request_irq() failed\n"); -+ goto fail_irq; -+ } -+ if ((config->public_cfg.cpu != -1) && -+ irq_can_set_affinity(config->public_cfg.irq) && -+ irq_set_affinity(config->public_cfg.irq, -+ cpumask_of(config->public_cfg.cpu))) { -+ pr_err("irq_set_affinity() failed\n"); -+ goto fail_affinity; -+ } -+ -+ /* Need EQCR to be empty before continuing */ -+ isdr ^= QM_PIRQ_EQCI; -+ qm_isr_disable_write(__p, isdr); -+ ret = qm_eqcr_get_fill(__p); -+ if (ret) { -+ pr_err("Qman EQCR unclean\n"); -+ goto fail_eqcr_empty; -+ } -+ isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI); -+ qm_isr_disable_write(__p, isdr); -+ if (qm_dqrr_current(__p) != NULL) { -+ pr_err("Qman DQRR unclean\n"); -+ qm_dqrr_cdc_consume_n(__p, 0xffff); -+ } -+ if (qm_mr_current(__p) != NULL) { -+ /* special handling, drain just in case it's a few FQRNIs */ -+ if (drain_mr_fqrni(__p)) { -+ const struct qm_mr_entry *e = qm_mr_current(__p); -+ /* -+ * Message ring cannot be empty no need to check -+ * qm_mr_current returned successfully -+ */ -+ pr_err("Qman MR unclean, MR VERB 0x%x, rc 0x%x\n, addr 0x%x", -+ e->verb, e->ern.rc, e->ern.fd.addr_lo); -+ goto fail_dqrr_mr_empty; -+ } -+ } -+ /* Success */ -+ portal->config = config; -+ qm_isr_disable_write(__p, 0); -+ qm_isr_uninhibit(__p); -+ /* Write a sane SDQCR */ -+ qm_dqrr_sdqcr_set(__p, portal->sdqcr); -+ return portal; -+fail_dqrr_mr_empty: -+fail_eqcr_empty: -+fail_affinity: -+ free_irq(config->public_cfg.irq, portal); -+fail_irq: -+ platform_device_del(portal->pdev); -+fail_devadd: -+ platform_device_put(portal->pdev); -+fail_devalloc: -+ if (num_ceetms) -+ for (ret = 0; ret < num_ceetms; ret++) -+ kfree(portal->ccgrs[ret]); -+fail_ccgrs: -+ kfree(portal->cgrs); -+fail_cgrs: -+ qm_isr_finish(__p); -+fail_isr: -+ qm_mc_finish(__p); -+fail_mc: -+ qm_mr_finish(__p); -+fail_mr: -+ qm_dqrr_finish(__p); -+fail_dqrr: -+ qm_eqcr_finish(__p); -+fail_eqcr: -+ if (portal->alloced) -+ kfree(portal); -+ return NULL; -+} -+ -+struct qman_portal *qman_create_affine_portal( -+ const struct qm_portal_config *config, -+ const struct qman_cgrs *cgrs) -+{ -+ struct qman_portal *res; -+ struct qman_portal *portal; -+ -+ portal = &per_cpu(qman_affine_portal, config->public_cfg.cpu); -+ res = qman_create_portal(portal, config, cgrs); -+ if (res) { -+ spin_lock(&affine_mask_lock); -+ cpumask_set_cpu(config->public_cfg.cpu, &affine_mask); -+ affine_channels[config->public_cfg.cpu] = -+ config->public_cfg.channel; -+ affine_portals[config->public_cfg.cpu] = portal; -+ spin_unlock(&affine_mask_lock); -+ } -+ return res; -+} -+ -+/* These checks are BUG_ON()s because the driver is already supposed to avoid -+ * these cases. */ -+struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect, -+ int cpu) -+{ -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ struct qman_portal *p; -+ p = &per_cpu(qman_affine_portal, cpu); -+ /* Check that we don't already have our own portal */ -+ BUG_ON(p->config); -+ /* Check that we aren't already slaving to another portal */ -+ BUG_ON(p->is_shared); -+ /* Check that 'redirect' is prepared to have us */ -+ BUG_ON(!redirect->config->public_cfg.is_shared); -+ /* These are the only elements to initialise when redirecting */ -+ p->irq_sources = 0; -+ p->sharing_redirect = redirect; -+ affine_portals[cpu] = p; -+ return p; -+#else -+ BUG(); -+ return NULL; -+#endif -+} -+ -+void qman_destroy_portal(struct qman_portal *qm) -+{ -+ const struct qm_portal_config *pcfg; -+ int i; -+ -+ /* Stop dequeues on the portal */ -+ qm_dqrr_sdqcr_set(&qm->p, 0); -+ -+ /* NB we do this to "quiesce" EQCR. If we add enqueue-completions or -+ * something related to QM_PIRQ_EQCI, this may need fixing. -+ * Also, due to the prefetching model used for CI updates in the enqueue -+ * path, this update will only invalidate the CI cacheline *after* -+ * working on it, so we need to call this twice to ensure a full update -+ * irrespective of where the enqueue processing was at when the teardown -+ * began. */ -+ qm_eqcr_cce_update(&qm->p); -+ qm_eqcr_cce_update(&qm->p); -+ pcfg = qm->config; -+ -+ free_irq(pcfg->public_cfg.irq, qm); -+ -+ kfree(qm->cgrs); -+ if (num_ceetms) -+ for (i = 0; i < num_ceetms; i++) -+ kfree(qm->ccgrs[i]); -+ qm_isr_finish(&qm->p); -+ qm_mc_finish(&qm->p); -+ qm_mr_finish(&qm->p); -+ qm_dqrr_finish(&qm->p); -+ qm_eqcr_finish(&qm->p); -+ -+ platform_device_del(qm->pdev); -+ platform_device_put(qm->pdev); -+ -+ qm->config = NULL; -+ if (qm->alloced) -+ kfree(qm); -+} -+ -+const struct qm_portal_config *qman_destroy_affine_portal(void) -+{ -+ /* We don't want to redirect if we're a slave, use "raw" */ -+ struct qman_portal *qm = get_raw_affine_portal(); -+ const struct qm_portal_config *pcfg; -+ int cpu; -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (qm->sharing_redirect) { -+ qm->sharing_redirect = NULL; -+ put_affine_portal(); -+ return NULL; -+ } -+ qm->is_shared = 0; -+#endif -+ pcfg = qm->config; -+ cpu = pcfg->public_cfg.cpu; -+ -+ qman_destroy_portal(qm); -+ -+ spin_lock(&affine_mask_lock); -+ cpumask_clear_cpu(cpu, &affine_mask); -+ spin_unlock(&affine_mask_lock); -+ put_affine_portal(); -+ return pcfg; -+} -+ -+const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal *p) -+{ -+ return &p->config->public_cfg; -+} -+EXPORT_SYMBOL(qman_p_get_portal_config); -+ -+const struct qman_portal_config *qman_get_portal_config(void) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ const struct qman_portal_config *ret = qman_p_get_portal_config(p); -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_get_portal_config); -+ -+/* Inline helper to reduce nesting in __poll_portal_slow() */ -+static inline void fq_state_change(struct qman_portal *p, struct qman_fq *fq, -+ const struct qm_mr_entry *msg, u8 verb) -+{ -+ FQLOCK(fq); -+ switch (verb) { -+ case QM_MR_VERB_FQRL: -+ DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_ORL)); -+ fq_clear(fq, QMAN_FQ_STATE_ORL); -+ table_del_fq(p, fq); -+ break; -+ case QM_MR_VERB_FQRN: -+ DPA_ASSERT((fq->state == qman_fq_state_parked) || -+ (fq->state == qman_fq_state_sched)); -+ DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_CHANGING)); -+ fq_clear(fq, QMAN_FQ_STATE_CHANGING); -+ if (msg->fq.fqs & QM_MR_FQS_NOTEMPTY) -+ fq_set(fq, QMAN_FQ_STATE_NE); -+ if (msg->fq.fqs & QM_MR_FQS_ORLPRESENT) -+ fq_set(fq, QMAN_FQ_STATE_ORL); -+ else -+ table_del_fq(p, fq); -+ fq->state = qman_fq_state_retired; -+ break; -+ case QM_MR_VERB_FQPN: -+ DPA_ASSERT(fq->state == qman_fq_state_sched); -+ DPA_ASSERT(fq_isclear(fq, QMAN_FQ_STATE_CHANGING)); -+ fq->state = qman_fq_state_parked; -+ } -+ FQUNLOCK(fq); -+} -+ -+static u32 __poll_portal_slow(struct qman_portal *p, u32 is) -+{ -+ const struct qm_mr_entry *msg; -+ struct qm_mr_entry swapped_msg; -+ int k; -+ -+ if (is & QM_PIRQ_CSCI) { -+ struct qman_cgrs rr, c; -+ struct qm_mc_result *mcr; -+ struct qman_cgr *cgr; -+ unsigned long irqflags __maybe_unused; -+ -+ spin_lock_irqsave(&p->cgr_lock, irqflags); -+ /* -+ * The CSCI bit must be cleared _before_ issuing the -+ * Query Congestion State command, to ensure that a long -+ * CGR State Change callback cannot miss an intervening -+ * state change. -+ */ -+ qm_isr_status_clear(&p->p, QM_PIRQ_CSCI); -+ qm_mc_start(&p->p); -+ qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ for (k = 0; k < 8; k++) -+ mcr->querycongestion.state.__state[k] = be32_to_cpu( -+ mcr->querycongestion.state.__state[k]); -+ /* mask out the ones I'm not interested in */ -+ qman_cgrs_and(&rr, (const struct qman_cgrs *) -+ &mcr->querycongestion.state, &p->cgrs[0]); -+ /* check previous snapshot for delta, enter/exit congestion */ -+ qman_cgrs_xor(&c, &rr, &p->cgrs[1]); -+ /* update snapshot */ -+ qman_cgrs_cp(&p->cgrs[1], &rr); -+ /* Invoke callback */ -+ list_for_each_entry(cgr, &p->cgr_cbs, node) -+ if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid)) -+ cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid)); -+ spin_unlock_irqrestore(&p->cgr_lock, irqflags); -+ } -+ if (is & QM_PIRQ_CCSCI) { -+ struct qman_ccgrs rr, c, congestion_result; -+ struct qm_mc_result *mcr; -+ struct qm_mc_command *mcc; -+ struct qm_ceetm_ccg *ccg; -+ unsigned long irqflags __maybe_unused; -+ int i, j; -+ -+ spin_lock_irqsave(&p->ccgr_lock, irqflags); -+ /* -+ * The CCSCI bit must be cleared _before_ issuing the -+ * Query Congestion State command, to ensure that a long -+ * CCGR State Change callback cannot miss an intervening -+ * state change. -+ */ -+ qm_isr_status_clear(&p->p, QM_PIRQ_CCSCI); -+ -+ for (i = 0; i < num_ceetms; i++) { -+ for (j = 0; j < 2; j++) { -+ mcc = qm_mc_start(&p->p); -+ mcc->ccgr_query.ccgrid = cpu_to_be16( -+ CEETM_QUERY_CONGESTION_STATE | j); -+ mcc->ccgr_query.dcpid = i; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ for (k = 0; k < 8; k++) -+ mcr->ccgr_query.congestion_state.state. -+ __state[k] = be32_to_cpu( -+ mcr->ccgr_query. -+ congestion_state.state. -+ __state[k]); -+ congestion_result.q[j] = -+ mcr->ccgr_query.congestion_state.state; -+ } -+ /* mask out the ones I'm not interested in */ -+ qman_ccgrs_and(&rr, &congestion_result, -+ &p->ccgrs[i][0]); -+ /* -+ * check previous snapshot for delta, enter/exit -+ * congestion. -+ */ -+ qman_ccgrs_xor(&c, &rr, &p->ccgrs[i][1]); -+ /* update snapshot */ -+ qman_ccgrs_cp(&p->ccgrs[i][1], &rr); -+ /* Invoke callback */ -+ list_for_each_entry(ccg, &p->ccgr_cbs[i], cb_node) -+ if (ccg->cb && qman_ccgrs_get(&c, -+ (ccg->parent->idx << 4) | ccg->idx)) -+ ccg->cb(ccg, ccg->cb_ctx, -+ qman_ccgrs_get(&rr, -+ (ccg->parent->idx << 4) -+ | ccg->idx)); -+ } -+ spin_unlock_irqrestore(&p->ccgr_lock, irqflags); -+ } -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (is & QM_PIRQ_EQCI) { -+ unsigned long irqflags; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ p->eqci_owned = NULL; -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ wake_up(&affine_queue); -+ } -+#endif -+ -+ if (is & QM_PIRQ_EQRI) { -+ unsigned long irqflags __maybe_unused; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ qm_eqcr_cce_update(&p->p); -+ qm_eqcr_set_ithresh(&p->p, 0); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ wake_up(&affine_queue); -+ } -+ -+ if (is & QM_PIRQ_MRI) { -+ struct qman_fq *fq; -+ u8 verb, num = 0; -+mr_loop: -+ qm_mr_pvb_update(&p->p); -+ msg = qm_mr_current(&p->p); -+ if (!msg) -+ goto mr_done; -+ swapped_msg = *msg; -+ hw_fd_to_cpu(&swapped_msg.ern.fd); -+ verb = msg->verb & QM_MR_VERB_TYPE_MASK; -+ /* The message is a software ERN iff the 0x20 bit is set */ -+ if (verb & 0x20) { -+ switch (verb) { -+ case QM_MR_VERB_FQRNI: -+ /* nada, we drop FQRNIs on the floor */ -+ break; -+ case QM_MR_VERB_FQRN: -+ case QM_MR_VERB_FQRL: -+ /* Lookup in the retirement table */ -+ fq = table_find_fq(p, be32_to_cpu(msg->fq.fqid)); -+ BUG_ON(!fq); -+ fq_state_change(p, fq, &swapped_msg, verb); -+ if (fq->cb.fqs) -+ fq->cb.fqs(p, fq, &swapped_msg); -+ break; -+ case QM_MR_VERB_FQPN: -+ /* Parked */ -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ fq = get_fq_table_entry( -+ be32_to_cpu(msg->fq.contextB)); -+#else -+ fq = (void *)(uintptr_t) -+ be32_to_cpu(msg->fq.contextB); -+#endif -+ fq_state_change(p, fq, msg, verb); -+ if (fq->cb.fqs) -+ fq->cb.fqs(p, fq, &swapped_msg); -+ break; -+ case QM_MR_VERB_DC_ERN: -+ /* DCP ERN */ -+ if (p->cb_dc_ern) -+ p->cb_dc_ern(p, msg); -+ else if (cb_dc_ern) -+ cb_dc_ern(p, msg); -+ else { -+ static int warn_once; -+ if (!warn_once) { -+ pr_crit("Leaking DCP ERNs!\n"); -+ warn_once = 1; -+ } -+ } -+ break; -+ default: -+ pr_crit("Invalid MR verb 0x%02x\n", verb); -+ } -+ } else { -+ /* Its a software ERN */ -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ fq = get_fq_table_entry(be32_to_cpu(msg->ern.tag)); -+#else -+ fq = (void *)(uintptr_t)be32_to_cpu(msg->ern.tag); -+#endif -+ fq->cb.ern(p, fq, &swapped_msg); -+ } -+ num++; -+ qm_mr_next(&p->p); -+ goto mr_loop; -+mr_done: -+ qm_mr_cci_consume(&p->p, num); -+ } -+ /* -+ * QM_PIRQ_CSCI/CCSCI has already been cleared, as part of its specific -+ * processing. If that interrupt source has meanwhile been re-asserted, -+ * we mustn't clear it here (or in the top-level interrupt handler). -+ */ -+ return is & (QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI); -+} -+ -+/* remove some slowish-path stuff from the "fast path" and make sure it isn't -+ * inlined. */ -+static noinline void clear_vdqcr(struct qman_portal *p, struct qman_fq *fq) -+{ -+ p->vdqcr_owned = NULL; -+ FQLOCK(fq); -+ fq_clear(fq, QMAN_FQ_STATE_VDQCR); -+ FQUNLOCK(fq); -+ wake_up(&affine_queue); -+} -+ -+/* Copy a DQRR entry ensuring reads reach QBMan in order */ -+static inline void safe_copy_dqrr(struct qm_dqrr_entry *dst, -+ const struct qm_dqrr_entry *src) -+{ -+ int i = 0; -+ const u64 *s64 = (u64*)src; -+ u64 *d64 = (u64*)dst; -+ -+ /* DQRR only has 32 bytes of valid data so only need to -+ * copy 4 - 64 bit values */ -+ *d64 = *s64; -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ { -+ u32 res, zero = 0; -+ /* Create a dependancy after copying first bytes ensures no wrap -+ transaction generated to QBMan */ -+ /* Logical AND the value pointed to by s64 with 0x0 and -+ store the result in res */ -+ asm volatile("and %[result], %[in1], %[in2]" -+ : [result] "=r" (res) -+ : [in1] "r" (zero), [in2] "r" (*s64) -+ : "memory"); -+ /* Add res to s64 - this creates a dependancy on the result of -+ reading the value of s64 before the next read. The side -+ effect of this is that the core must stall until the first -+ aligned read is complete therefore preventing a WRAP -+ transaction to be seen by the QBMan */ -+ asm volatile("add %[result], %[in1], %[in2]" -+ : [result] "=r" (s64) -+ : [in1] "r" (res), [in2] "r" (s64) -+ : "memory"); -+ } -+#endif -+ /* Copy the last 3 64 bit parts */ -+ d64++; s64++; -+ for (;i<3; i++) -+ *d64++ = *s64++; -+} -+ -+/* Look: no locks, no irq_save()s, no preempt_disable()s! :-) The only states -+ * that would conflict with other things if they ran at the same time on the -+ * same cpu are; -+ * -+ * (i) setting/clearing vdqcr_owned, and -+ * (ii) clearing the NE (Not Empty) flag. -+ * -+ * Both are safe. Because; -+ * -+ * (i) this clearing can only occur after qman_volatile_dequeue() has set the -+ * vdqcr_owned field (which it does before setting VDQCR), and -+ * qman_volatile_dequeue() blocks interrupts and preemption while this is -+ * done so that we can't interfere. -+ * (ii) the NE flag is only cleared after qman_retire_fq() has set it, and as -+ * with (i) that API prevents us from interfering until it's safe. -+ * -+ * The good thing is that qman_volatile_dequeue() and qman_retire_fq() run far -+ * less frequently (ie. per-FQ) than __poll_portal_fast() does, so the nett -+ * advantage comes from this function not having to "lock" anything at all. -+ * -+ * Note also that the callbacks are invoked at points which are safe against the -+ * above potential conflicts, but that this function itself is not re-entrant -+ * (this is because the function tracks one end of each FIFO in the portal and -+ * we do *not* want to lock that). So the consequence is that it is safe for -+ * user callbacks to call into any Qman API *except* qman_poll() (as that's the -+ * sole API that could be invoking the callback through this function). -+ */ -+static inline unsigned int __poll_portal_fast(struct qman_portal *p, -+ unsigned int poll_limit) -+{ -+ const struct qm_dqrr_entry *dq; -+ struct qman_fq *fq; -+ enum qman_cb_dqrr_result res; -+ unsigned int limit = 0; -+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -+ struct qm_dqrr_entry *shadow; -+ const struct qm_dqrr_entry *orig_dq; -+#endif -+loop: -+ qm_dqrr_pvb_update(&p->p); -+ dq = qm_dqrr_current(&p->p); -+ if (!dq) -+ goto done; -+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -+ /* If running on an LE system the fields of the -+ dequeue entry must be swapped. Because the -+ QMan HW will ignore writes the DQRR entry is -+ copied and the index stored within the copy */ -+ shadow = &p->shadow_dqrr[DQRR_PTR2IDX(dq)]; -+ /* Use safe copy here to avoid WRAP transaction */ -+ safe_copy_dqrr(shadow, dq); -+ orig_dq = dq; -+ dq = shadow; -+ shadow->fqid = be32_to_cpu(shadow->fqid); -+ shadow->contextB = be32_to_cpu(shadow->contextB); -+ shadow->seqnum = be16_to_cpu(shadow->seqnum); -+ hw_fd_to_cpu(&shadow->fd); -+#endif -+ if (dq->stat & QM_DQRR_STAT_UNSCHEDULED) { -+ /* VDQCR: don't trust contextB as the FQ may have been -+ * configured for h/w consumption and we're draining it -+ * post-retirement. */ -+ fq = p->vdqcr_owned; -+ /* We only set QMAN_FQ_STATE_NE when retiring, so we only need -+ * to check for clearing it when doing volatile dequeues. It's -+ * one less thing to check in the critical path (SDQCR). */ -+ if (dq->stat & QM_DQRR_STAT_FQ_EMPTY) -+ fq_clear(fq, QMAN_FQ_STATE_NE); -+ /* this is duplicated from the SDQCR code, but we have stuff to -+ * do before *and* after this callback, and we don't want -+ * multiple if()s in the critical path (SDQCR). */ -+ res = fq->cb.dqrr(p, fq, dq); -+ if (res == qman_cb_dqrr_stop) -+ goto done; -+ /* Check for VDQCR completion */ -+ if (dq->stat & QM_DQRR_STAT_DQCR_EXPIRED) -+ clear_vdqcr(p, fq); -+ } else { -+ /* SDQCR: contextB points to the FQ */ -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ fq = get_fq_table_entry(dq->contextB); -+#else -+ fq = (void *)(uintptr_t)dq->contextB; -+#endif -+ /* Now let the callback do its stuff */ -+ res = fq->cb.dqrr(p, fq, dq); -+ -+ /* The callback can request that we exit without consuming this -+ * entry nor advancing; */ -+ if (res == qman_cb_dqrr_stop) -+ goto done; -+ } -+ /* Interpret 'dq' from a driver perspective. */ -+ /* Parking isn't possible unless HELDACTIVE was set. NB, -+ * FORCEELIGIBLE implies HELDACTIVE, so we only need to -+ * check for HELDACTIVE to cover both. */ -+ DPA_ASSERT((dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) || -+ (res != qman_cb_dqrr_park)); -+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -+ if (res != qman_cb_dqrr_defer) -+ qm_dqrr_cdc_consume_1ptr(&p->p, orig_dq, -+ (res == qman_cb_dqrr_park)); -+#else -+ /* Defer just means "skip it, I'll consume it myself later on" */ -+ if (res != qman_cb_dqrr_defer) -+ qm_dqrr_cdc_consume_1ptr(&p->p, dq, (res == qman_cb_dqrr_park)); -+#endif -+ /* Move forward */ -+ qm_dqrr_next(&p->p); -+ /* Entry processed and consumed, increment our counter. The callback can -+ * request that we exit after consuming the entry, and we also exit if -+ * we reach our processing limit, so loop back only if neither of these -+ * conditions is met. */ -+ if ((++limit < poll_limit) && (res != qman_cb_dqrr_consume_stop)) -+ goto loop; -+done: -+ return limit; -+} -+ -+u32 qman_irqsource_get(void) -+{ -+ /* "irqsource" and "poll" APIs mustn't redirect when sharing, they -+ * should shut the user out if they are not the primary CPU hosting the -+ * portal. That's why we use the "raw" interface. */ -+ struct qman_portal *p = get_raw_affine_portal(); -+ u32 ret = p->irq_sources & QM_PIRQ_VISIBLE; -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_irqsource_get); -+ -+int qman_p_irqsource_add(struct qman_portal *p, u32 bits __maybe_unused) -+{ -+ __maybe_unused unsigned long irqflags; -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (p->sharing_redirect) -+ return -EINVAL; -+ else -+#endif -+ { -+ bits = bits & QM_PIRQ_VISIBLE; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ /* Clear any previously remaining interrupt conditions in -+ * QCSP_ISR. This prevents raising a false interrupt when -+ * interrupt conditions are enabled in QCSP_IER. -+ */ -+ qm_isr_status_clear(&p->p, bits); -+ set_bits(bits, &p->irq_sources); -+ qm_isr_enable_write(&p->p, p->irq_sources); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ } -+ return 0; -+} -+EXPORT_SYMBOL(qman_p_irqsource_add); -+ -+int qman_irqsource_add(u32 bits __maybe_unused) -+{ -+ struct qman_portal *p = get_raw_affine_portal(); -+ int ret; -+ ret = qman_p_irqsource_add(p, bits); -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_irqsource_add); -+ -+int qman_p_irqsource_remove(struct qman_portal *p, u32 bits) -+{ -+ __maybe_unused unsigned long irqflags; -+ u32 ier; -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (p->sharing_redirect) { -+ put_affine_portal(); -+ return -EINVAL; -+ } -+#endif -+ /* Our interrupt handler only processes+clears status register bits that -+ * are in p->irq_sources. As we're trimming that mask, if one of them -+ * were to assert in the status register just before we remove it from -+ * the enable register, there would be an interrupt-storm when we -+ * release the IRQ lock. So we wait for the enable register update to -+ * take effect in h/w (by reading it back) and then clear all other bits -+ * in the status register. Ie. we clear them from ISR once it's certain -+ * IER won't allow them to reassert. */ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ bits &= QM_PIRQ_VISIBLE; -+ clear_bits(bits, &p->irq_sources); -+ qm_isr_enable_write(&p->p, p->irq_sources); -+ -+ ier = qm_isr_enable_read(&p->p); -+ /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a -+ * data-dependency, ie. to protect against re-ordering. */ -+ qm_isr_status_clear(&p->p, ~ier); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ return 0; -+} -+EXPORT_SYMBOL(qman_p_irqsource_remove); -+ -+int qman_irqsource_remove(u32 bits) -+{ -+ struct qman_portal *p = get_raw_affine_portal(); -+ int ret; -+ ret = qman_p_irqsource_remove(p, bits); -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_irqsource_remove); -+ -+const cpumask_t *qman_affine_cpus(void) -+{ -+ return &affine_mask; -+} -+EXPORT_SYMBOL(qman_affine_cpus); -+ -+u16 qman_affine_channel(int cpu) -+{ -+ if (cpu < 0) { -+ struct qman_portal *portal = get_raw_affine_portal(); -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ BUG_ON(portal->sharing_redirect); -+#endif -+ cpu = portal->config->public_cfg.cpu; -+ put_affine_portal(); -+ } -+ BUG_ON(!cpumask_test_cpu(cpu, &affine_mask)); -+ return affine_channels[cpu]; -+} -+EXPORT_SYMBOL(qman_affine_channel); -+ -+void *qman_get_affine_portal(int cpu) -+{ -+ return affine_portals[cpu]; -+} -+EXPORT_SYMBOL(qman_get_affine_portal); -+ -+int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit) -+{ -+ int ret; -+ -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (unlikely(p->sharing_redirect)) -+ ret = -EINVAL; -+ else -+#endif -+ { -+ BUG_ON(p->irq_sources & QM_PIRQ_DQRI); -+ ret = __poll_portal_fast(p, limit); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(qman_p_poll_dqrr); -+ -+int qman_poll_dqrr(unsigned int limit) -+{ -+ struct qman_portal *p = get_poll_portal(); -+ int ret; -+ ret = qman_p_poll_dqrr(p, limit); -+ put_poll_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_poll_dqrr); -+ -+u32 qman_p_poll_slow(struct qman_portal *p) -+{ -+ u32 ret; -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (unlikely(p->sharing_redirect)) -+ ret = (u32)-1; -+ else -+#endif -+ { -+ u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources; -+ ret = __poll_portal_slow(p, is); -+ qm_isr_status_clear(&p->p, ret); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(qman_p_poll_slow); -+ -+u32 qman_poll_slow(void) -+{ -+ struct qman_portal *p = get_poll_portal(); -+ u32 ret; -+ ret = qman_p_poll_slow(p); -+ put_poll_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_poll_slow); -+ -+/* Legacy wrapper */ -+void qman_p_poll(struct qman_portal *p) -+{ -+#ifdef CONFIG_FSL_DPA_PORTAL_SHARE -+ if (unlikely(p->sharing_redirect)) -+ return; -+#endif -+ if ((~p->irq_sources) & QM_PIRQ_SLOW) { -+ if (!(p->slowpoll--)) { -+ u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources; -+ u32 active = __poll_portal_slow(p, is); -+ if (active) { -+ qm_isr_status_clear(&p->p, active); -+ p->slowpoll = SLOW_POLL_BUSY; -+ } else -+ p->slowpoll = SLOW_POLL_IDLE; -+ } -+ } -+ if ((~p->irq_sources) & QM_PIRQ_DQRI) -+ __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT); -+} -+EXPORT_SYMBOL(qman_p_poll); -+ -+void qman_poll(void) -+{ -+ struct qman_portal *p = get_poll_portal(); -+ qman_p_poll(p); -+ put_poll_portal(); -+} -+EXPORT_SYMBOL(qman_poll); -+ -+void qman_p_stop_dequeues(struct qman_portal *p) -+{ -+ qman_stop_dequeues_ex(p); -+} -+EXPORT_SYMBOL(qman_p_stop_dequeues); -+ -+void qman_stop_dequeues(void) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ qman_p_stop_dequeues(p); -+ put_affine_portal(); -+} -+EXPORT_SYMBOL(qman_stop_dequeues); -+ -+void qman_p_start_dequeues(struct qman_portal *p) -+{ -+ unsigned long irqflags __maybe_unused; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ DPA_ASSERT(p->dqrr_disable_ref > 0); -+ if (!(--p->dqrr_disable_ref)) -+ qm_dqrr_set_maxfill(&p->p, DQRR_MAXFILL); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+} -+EXPORT_SYMBOL(qman_p_start_dequeues); -+ -+void qman_start_dequeues(void) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ qman_p_start_dequeues(p); -+ put_affine_portal(); -+} -+EXPORT_SYMBOL(qman_start_dequeues); -+ -+void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools) -+{ -+ unsigned long irqflags __maybe_unused; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ pools &= p->config->public_cfg.pools; -+ p->sdqcr |= pools; -+ qm_dqrr_sdqcr_set(&p->p, p->sdqcr); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+} -+EXPORT_SYMBOL(qman_p_static_dequeue_add); -+ -+void qman_static_dequeue_add(u32 pools) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ qman_p_static_dequeue_add(p, pools); -+ put_affine_portal(); -+} -+EXPORT_SYMBOL(qman_static_dequeue_add); -+ -+void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools) -+{ -+ unsigned long irqflags __maybe_unused; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ pools &= p->config->public_cfg.pools; -+ p->sdqcr &= ~pools; -+ qm_dqrr_sdqcr_set(&p->p, p->sdqcr); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+} -+EXPORT_SYMBOL(qman_p_static_dequeue_del); -+ -+void qman_static_dequeue_del(u32 pools) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ qman_p_static_dequeue_del(p, pools); -+ put_affine_portal(); -+} -+EXPORT_SYMBOL(qman_static_dequeue_del); -+ -+u32 qman_p_static_dequeue_get(struct qman_portal *p) -+{ -+ return p->sdqcr; -+} -+EXPORT_SYMBOL(qman_p_static_dequeue_get); -+ -+u32 qman_static_dequeue_get(void) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ u32 ret = qman_p_static_dequeue_get(p); -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_static_dequeue_get); -+ -+void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq, -+ int park_request) -+{ -+ qm_dqrr_cdc_consume_1ptr(&p->p, dq, park_request); -+} -+EXPORT_SYMBOL(qman_p_dca); -+ -+void qman_dca(struct qm_dqrr_entry *dq, int park_request) -+{ -+ struct qman_portal *p = get_affine_portal(); -+ qman_p_dca(p, dq, park_request); -+ put_affine_portal(); -+} -+EXPORT_SYMBOL(qman_dca); -+ -+/*******************/ -+/* Frame queue API */ -+/*******************/ -+ -+static const char *mcr_result_str(u8 result) -+{ -+ switch (result) { -+ case QM_MCR_RESULT_NULL: -+ return "QM_MCR_RESULT_NULL"; -+ case QM_MCR_RESULT_OK: -+ return "QM_MCR_RESULT_OK"; -+ case QM_MCR_RESULT_ERR_FQID: -+ return "QM_MCR_RESULT_ERR_FQID"; -+ case QM_MCR_RESULT_ERR_FQSTATE: -+ return "QM_MCR_RESULT_ERR_FQSTATE"; -+ case QM_MCR_RESULT_ERR_NOTEMPTY: -+ return "QM_MCR_RESULT_ERR_NOTEMPTY"; -+ case QM_MCR_RESULT_PENDING: -+ return "QM_MCR_RESULT_PENDING"; -+ case QM_MCR_RESULT_ERR_BADCOMMAND: -+ return "QM_MCR_RESULT_ERR_BADCOMMAND"; -+ } -+ return ""; -+} -+ -+int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq) -+{ -+ struct qm_fqd fqd; -+ struct qm_mcr_queryfq_np np; -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ -+ if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID) { -+ int ret = qman_alloc_fqid(&fqid); -+ if (ret) -+ return ret; -+ } -+ spin_lock_init(&fq->fqlock); -+ fq->fqid = fqid; -+ fq->flags = flags; -+ fq->state = qman_fq_state_oos; -+ fq->cgr_groupid = 0; -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ if (unlikely(find_empty_fq_table_entry(&fq->key, fq))) -+ return -ENOMEM; -+#endif -+ if (!(flags & QMAN_FQ_FLAG_AS_IS) || (flags & QMAN_FQ_FLAG_NO_MODIFY)) -+ return 0; -+ /* Everything else is AS_IS support */ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ mcc = qm_mc_start(&p->p); -+ mcc->queryfq.fqid = cpu_to_be32(fqid); -+ qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ); -+ if (mcr->result != QM_MCR_RESULT_OK) { -+ pr_err("QUERYFQ failed: %s\n", mcr_result_str(mcr->result)); -+ goto err; -+ } -+ fqd = mcr->queryfq.fqd; -+ hw_fqd_to_cpu(&fqd); -+ mcc = qm_mc_start(&p->p); -+ mcc->queryfq_np.fqid = cpu_to_be32(fqid); -+ qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ_NP); -+ if (mcr->result != QM_MCR_RESULT_OK) { -+ pr_err("QUERYFQ_NP failed: %s\n", mcr_result_str(mcr->result)); -+ goto err; -+ } -+ np = mcr->queryfq_np; -+ /* Phew, have queryfq and queryfq_np results, stitch together -+ * the FQ object from those. */ -+ fq->cgr_groupid = fqd.cgid; -+ switch (np.state & QM_MCR_NP_STATE_MASK) { -+ case QM_MCR_NP_STATE_OOS: -+ break; -+ case QM_MCR_NP_STATE_RETIRED: -+ fq->state = qman_fq_state_retired; -+ if (np.frm_cnt) -+ fq_set(fq, QMAN_FQ_STATE_NE); -+ break; -+ case QM_MCR_NP_STATE_TEN_SCHED: -+ case QM_MCR_NP_STATE_TRU_SCHED: -+ case QM_MCR_NP_STATE_ACTIVE: -+ fq->state = qman_fq_state_sched; -+ if (np.state & QM_MCR_NP_STATE_R) -+ fq_set(fq, QMAN_FQ_STATE_CHANGING); -+ break; -+ case QM_MCR_NP_STATE_PARKED: -+ fq->state = qman_fq_state_parked; -+ break; -+ default: -+ DPA_ASSERT(NULL == "invalid FQ state"); -+ } -+ if (fqd.fq_ctrl & QM_FQCTRL_CGE) -+ fq->state |= QMAN_FQ_STATE_CGR_EN; -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return 0; -+err: -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID) -+ qman_release_fqid(fqid); -+ return -EIO; -+} -+EXPORT_SYMBOL(qman_create_fq); -+ -+void qman_destroy_fq(struct qman_fq *fq, u32 flags __maybe_unused) -+{ -+ -+ /* We don't need to lock the FQ as it is a pre-condition that the FQ be -+ * quiesced. Instead, run some checks. */ -+ switch (fq->state) { -+ case qman_fq_state_parked: -+ DPA_ASSERT(flags & QMAN_FQ_DESTROY_PARKED); -+ case qman_fq_state_oos: -+ if (fq_isset(fq, QMAN_FQ_FLAG_DYNAMIC_FQID)) -+ qman_release_fqid(fq->fqid); -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ clear_fq_table_entry(fq->key); -+#endif -+ return; -+ default: -+ break; -+ } -+ DPA_ASSERT(NULL == "qman_free_fq() on unquiesced FQ!"); -+} -+EXPORT_SYMBOL(qman_destroy_fq); -+ -+u32 qman_fq_fqid(struct qman_fq *fq) -+{ -+ return fq->fqid; -+} -+EXPORT_SYMBOL(qman_fq_fqid); -+ -+void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags) -+{ -+ if (state) -+ *state = fq->state; -+ if (flags) -+ *flags = fq->flags; -+} -+EXPORT_SYMBOL(qman_fq_state); -+ -+int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res, myverb = (flags & QMAN_INITFQ_FLAG_SCHED) ? -+ QM_MCC_VERB_INITFQ_SCHED : QM_MCC_VERB_INITFQ_PARKED; -+ -+ if ((fq->state != qman_fq_state_oos) && -+ (fq->state != qman_fq_state_parked)) -+ return -EINVAL; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY))) -+ return -EINVAL; -+#endif -+ if (opts && (opts->we_mask & QM_INITFQ_WE_OAC)) { -+ /* And can't be set at the same time as TDTHRESH */ -+ if (opts->we_mask & QM_INITFQ_WE_TDTHRESH) -+ return -EINVAL; -+ } -+ /* Issue an INITFQ_[PARKED|SCHED] management command */ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ FQLOCK(fq); -+ if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) || -+ ((fq->state != qman_fq_state_oos) && -+ (fq->state != qman_fq_state_parked)))) { -+ FQUNLOCK(fq); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return -EBUSY; -+ } -+ mcc = qm_mc_start(&p->p); -+ if (opts) -+ mcc->initfq = *opts; -+ mcc->initfq.fqid = cpu_to_be32(fq->fqid); -+ mcc->initfq.count = 0; -+ -+ /* If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a -+ * demux pointer. Otherwise, the caller-provided value is allowed to -+ * stand, don't overwrite it. */ -+ if (fq_isclear(fq, QMAN_FQ_FLAG_TO_DCPORTAL)) { -+ dma_addr_t phys_fq; -+ mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTB; -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ mcc->initfq.fqd.context_b = fq->key; -+#else -+ mcc->initfq.fqd.context_b = (u32)(uintptr_t)fq; -+#endif -+ /* and the physical address - NB, if the user wasn't trying to -+ * set CONTEXTA, clear the stashing settings. */ -+ if (!(mcc->initfq.we_mask & QM_INITFQ_WE_CONTEXTA)) { -+ mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTA; -+ memset(&mcc->initfq.fqd.context_a, 0, -+ sizeof(mcc->initfq.fqd.context_a)); -+ } else { -+ phys_fq = dma_map_single(&p->pdev->dev, fq, sizeof(*fq), -+ DMA_TO_DEVICE); -+ qm_fqd_stashing_set64(&mcc->initfq.fqd, phys_fq); -+ } -+ } -+ if (flags & QMAN_INITFQ_FLAG_LOCAL) { -+ mcc->initfq.fqd.dest.channel = p->config->public_cfg.channel; -+ if (!(mcc->initfq.we_mask & QM_INITFQ_WE_DESTWQ)) { -+ mcc->initfq.we_mask |= QM_INITFQ_WE_DESTWQ; -+ mcc->initfq.fqd.dest.wq = 4; -+ } -+ } -+ mcc->initfq.we_mask = cpu_to_be16(mcc->initfq.we_mask); -+ cpu_to_hw_fqd(&mcc->initfq.fqd); -+ qm_mc_commit(&p->p, myverb); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb); -+ res = mcr->result; -+ if (res != QM_MCR_RESULT_OK) { -+ FQUNLOCK(fq); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return -EIO; -+ } -+ if (opts) { -+ if (opts->we_mask & QM_INITFQ_WE_FQCTRL) { -+ if (opts->fqd.fq_ctrl & QM_FQCTRL_CGE) -+ fq_set(fq, QMAN_FQ_STATE_CGR_EN); -+ else -+ fq_clear(fq, QMAN_FQ_STATE_CGR_EN); -+ } -+ if (opts->we_mask & QM_INITFQ_WE_CGID) -+ fq->cgr_groupid = opts->fqd.cgid; -+ } -+ fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ? -+ qman_fq_state_sched : qman_fq_state_parked; -+ FQUNLOCK(fq); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return 0; -+} -+EXPORT_SYMBOL(qman_init_fq); -+ -+int qman_schedule_fq(struct qman_fq *fq) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ int ret = 0; -+ u8 res; -+ -+ if (fq->state != qman_fq_state_parked) -+ return -EINVAL; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY))) -+ return -EINVAL; -+#endif -+ /* Issue a ALTERFQ_SCHED management command */ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ FQLOCK(fq); -+ if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) || -+ (fq->state != qman_fq_state_parked))) { -+ ret = -EBUSY; -+ goto out; -+ } -+ mcc = qm_mc_start(&p->p); -+ mcc->alterfq.fqid = cpu_to_be32(fq->fqid); -+ qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_SCHED); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_SCHED); -+ res = mcr->result; -+ if (res != QM_MCR_RESULT_OK) { -+ ret = -EIO; -+ goto out; -+ } -+ fq->state = qman_fq_state_sched; -+out: -+ FQUNLOCK(fq); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_schedule_fq); -+ -+int qman_retire_fq(struct qman_fq *fq, u32 *flags) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ int rval; -+ u8 res; -+ -+ if ((fq->state != qman_fq_state_parked) && -+ (fq->state != qman_fq_state_sched)) -+ return -EINVAL; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY))) -+ return -EINVAL; -+#endif -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ FQLOCK(fq); -+ if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) || -+ (fq->state == qman_fq_state_retired) || -+ (fq->state == qman_fq_state_oos))) { -+ rval = -EBUSY; -+ goto out; -+ } -+ rval = table_push_fq(p, fq); -+ if (rval) -+ goto out; -+ mcc = qm_mc_start(&p->p); -+ mcc->alterfq.fqid = cpu_to_be32(fq->fqid); -+ qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_RETIRE); -+ res = mcr->result; -+ /* "Elegant" would be to treat OK/PENDING the same way; set CHANGING, -+ * and defer the flags until FQRNI or FQRN (respectively) show up. But -+ * "Friendly" is to process OK immediately, and not set CHANGING. We do -+ * friendly, otherwise the caller doesn't necessarily have a fully -+ * "retired" FQ on return even if the retirement was immediate. However -+ * this does mean some code duplication between here and -+ * fq_state_change(). */ -+ if (likely(res == QM_MCR_RESULT_OK)) { -+ rval = 0; -+ /* Process 'fq' right away, we'll ignore FQRNI */ -+ if (mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY) -+ fq_set(fq, QMAN_FQ_STATE_NE); -+ if (mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT) -+ fq_set(fq, QMAN_FQ_STATE_ORL); -+ else -+ table_del_fq(p, fq); -+ if (flags) -+ *flags = fq->flags; -+ fq->state = qman_fq_state_retired; -+ if (fq->cb.fqs) { -+ /* Another issue with supporting "immediate" retirement -+ * is that we're forced to drop FQRNIs, because by the -+ * time they're seen it may already be "too late" (the -+ * fq may have been OOS'd and free()'d already). But if -+ * the upper layer wants a callback whether it's -+ * immediate or not, we have to fake a "MR" entry to -+ * look like an FQRNI... */ -+ struct qm_mr_entry msg; -+ msg.verb = QM_MR_VERB_FQRNI; -+ msg.fq.fqs = mcr->alterfq.fqs; -+ msg.fq.fqid = fq->fqid; -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ msg.fq.contextB = fq->key; -+#else -+ msg.fq.contextB = (u32)(uintptr_t)fq; -+#endif -+ fq->cb.fqs(p, fq, &msg); -+ } -+ } else if (res == QM_MCR_RESULT_PENDING) { -+ rval = 1; -+ fq_set(fq, QMAN_FQ_STATE_CHANGING); -+ } else { -+ rval = -EIO; -+ table_del_fq(p, fq); -+ } -+out: -+ FQUNLOCK(fq); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return rval; -+} -+EXPORT_SYMBOL(qman_retire_fq); -+ -+int qman_oos_fq(struct qman_fq *fq) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ int ret = 0; -+ u8 res; -+ -+ if (fq->state != qman_fq_state_retired) -+ return -EINVAL; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY))) -+ return -EINVAL; -+#endif -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ FQLOCK(fq); -+ if (unlikely((fq_isset(fq, QMAN_FQ_STATE_BLOCKOOS)) || -+ (fq->state != qman_fq_state_retired))) { -+ ret = -EBUSY; -+ goto out; -+ } -+ mcc = qm_mc_start(&p->p); -+ mcc->alterfq.fqid = cpu_to_be32(fq->fqid); -+ qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_OOS); -+ res = mcr->result; -+ if (res != QM_MCR_RESULT_OK) { -+ ret = -EIO; -+ goto out; -+ } -+ fq->state = qman_fq_state_oos; -+out: -+ FQUNLOCK(fq); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_oos_fq); -+ -+int qman_fq_flow_control(struct qman_fq *fq, int xon) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ int ret = 0; -+ u8 res; -+ u8 myverb; -+ -+ if ((fq->state == qman_fq_state_oos) || -+ (fq->state == qman_fq_state_retired) || -+ (fq->state == qman_fq_state_parked)) -+ return -EINVAL; -+ -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY))) -+ return -EINVAL; -+#endif -+ /* Issue a ALTER_FQXON or ALTER_FQXOFF management command */ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ FQLOCK(fq); -+ if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) || -+ (fq->state == qman_fq_state_parked) || -+ (fq->state == qman_fq_state_oos) || -+ (fq->state == qman_fq_state_retired))) { -+ ret = -EBUSY; -+ goto out; -+ } -+ mcc = qm_mc_start(&p->p); -+ mcc->alterfq.fqid = fq->fqid; -+ mcc->alterfq.count = 0; -+ myverb = xon ? QM_MCC_VERB_ALTER_FQXON : QM_MCC_VERB_ALTER_FQXOFF; -+ -+ qm_mc_commit(&p->p, myverb); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb); -+ -+ res = mcr->result; -+ if (res != QM_MCR_RESULT_OK) { -+ ret = -EIO; -+ goto out; -+ } -+out: -+ FQUNLOCK(fq); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_fq_flow_control); -+ -+int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p = get_affine_portal(); -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ mcc = qm_mc_start(&p->p); -+ mcc->queryfq.fqid = cpu_to_be32(fq->fqid); -+ qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ); -+ res = mcr->result; -+ if (res == QM_MCR_RESULT_OK) -+ *fqd = mcr->queryfq.fqd; -+ hw_fqd_to_cpu(fqd); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ if (res != QM_MCR_RESULT_OK) -+ return -EIO; -+ return 0; -+} -+EXPORT_SYMBOL(qman_query_fq); -+ -+int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p = get_affine_portal(); -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ mcc = qm_mc_start(&p->p); -+ mcc->queryfq.fqid = cpu_to_be32(fq->fqid); -+ qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP); -+ res = mcr->result; -+ if (res == QM_MCR_RESULT_OK) { -+ *np = mcr->queryfq_np; -+ np->fqd_link = be24_to_cpu(np->fqd_link); -+ np->odp_seq = be16_to_cpu(np->odp_seq); -+ np->orp_nesn = be16_to_cpu(np->orp_nesn); -+ np->orp_ea_hseq = be16_to_cpu(np->orp_ea_hseq); -+ np->orp_ea_tseq = be16_to_cpu(np->orp_ea_tseq); -+ np->orp_ea_hptr = be24_to_cpu(np->orp_ea_hptr); -+ np->orp_ea_tptr = be24_to_cpu(np->orp_ea_tptr); -+ np->pfdr_hptr = be24_to_cpu(np->pfdr_hptr); -+ np->pfdr_tptr = be24_to_cpu(np->pfdr_tptr); -+ np->ics_surp = be16_to_cpu(np->ics_surp); -+ np->byte_cnt = be32_to_cpu(np->byte_cnt); -+ np->frm_cnt = be24_to_cpu(np->frm_cnt); -+ np->ra1_sfdr = be16_to_cpu(np->ra1_sfdr); -+ np->ra2_sfdr = be16_to_cpu(np->ra2_sfdr); -+ np->od1_sfdr = be16_to_cpu(np->od1_sfdr); -+ np->od2_sfdr = be16_to_cpu(np->od2_sfdr); -+ np->od3_sfdr = be16_to_cpu(np->od3_sfdr); -+ } -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ if (res == QM_MCR_RESULT_ERR_FQID) -+ return -ERANGE; -+ else if (res != QM_MCR_RESULT_OK) -+ return -EIO; -+ return 0; -+} -+EXPORT_SYMBOL(qman_query_fq_np); -+ -+int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p = get_affine_portal(); -+ unsigned long irqflags __maybe_unused; -+ u8 res, myverb; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ myverb = (query_dedicated) ? QM_MCR_VERB_QUERYWQ_DEDICATED : -+ QM_MCR_VERB_QUERYWQ; -+ mcc = qm_mc_start(&p->p); -+ mcc->querywq.channel.id = cpu_to_be16(wq->channel.id); -+ qm_mc_commit(&p->p, myverb); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb); -+ res = mcr->result; -+ if (res == QM_MCR_RESULT_OK) { -+ int i, array_len; -+ wq->channel.id = be16_to_cpu(mcr->querywq.channel.id); -+ array_len = ARRAY_SIZE(mcr->querywq.wq_len); -+ for (i = 0; i < array_len; i++) -+ wq->wq_len[i] = be32_to_cpu(mcr->querywq.wq_len[i]); -+ } -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("QUERYWQ failed: %s\n", mcr_result_str(res)); -+ return -EIO; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(qman_query_wq); -+ -+int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt, -+ struct qm_mcr_cgrtestwrite *result) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p = get_affine_portal(); -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ mcc = qm_mc_start(&p->p); -+ mcc->cgrtestwrite.cgid = cgr->cgrid; -+ mcc->cgrtestwrite.i_bcnt_hi = (u8)(i_bcnt >> 32); -+ mcc->cgrtestwrite.i_bcnt_lo = (u32)i_bcnt; -+ qm_mc_commit(&p->p, QM_MCC_VERB_CGRTESTWRITE); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_CGRTESTWRITE); -+ res = mcr->result; -+ if (res == QM_MCR_RESULT_OK) -+ *result = mcr->cgrtestwrite; -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CGR TEST WRITE failed: %s\n", mcr_result_str(res)); -+ return -EIO; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(qman_testwrite_cgr); -+ -+int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *cgrd) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p = get_affine_portal(); -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ int i; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ mcc = qm_mc_start(&p->p); -+ mcc->querycgr.cgid = cgr->cgrid; -+ qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCGR); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR); -+ res = mcr->result; -+ if (res == QM_MCR_RESULT_OK) -+ *cgrd = mcr->querycgr; -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("QUERY_CGR failed: %s\n", mcr_result_str(res)); -+ return -EIO; -+ } -+ cgrd->cgr.wr_parm_g.word = -+ be32_to_cpu(cgrd->cgr.wr_parm_g.word); -+ cgrd->cgr.wr_parm_y.word = -+ be32_to_cpu(cgrd->cgr.wr_parm_y.word); -+ cgrd->cgr.wr_parm_r.word = -+ be32_to_cpu(cgrd->cgr.wr_parm_r.word); -+ cgrd->cgr.cscn_targ = be32_to_cpu(cgrd->cgr.cscn_targ); -+ cgrd->cgr.__cs_thres = be16_to_cpu(cgrd->cgr.__cs_thres); -+ for (i = 0; i < ARRAY_SIZE(cgrd->cscn_targ_swp); i++) -+ be32_to_cpus(&cgrd->cscn_targ_swp[i]); -+ return 0; -+} -+EXPORT_SYMBOL(qman_query_cgr); -+ -+int qman_query_congestion(struct qm_mcr_querycongestion *congestion) -+{ -+ struct qm_mc_result *mcr; -+ struct qman_portal *p = get_affine_portal(); -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ int i; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ qm_mc_start(&p->p); -+ qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_MCC_VERB_QUERYCONGESTION); -+ res = mcr->result; -+ if (res == QM_MCR_RESULT_OK) -+ memcpy_fromio(congestion, &mcr->querycongestion, -+ sizeof(*congestion)); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("QUERY_CONGESTION failed: %s\n", mcr_result_str(res)); -+ return -EIO; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(congestion->state.__state); i++) -+ be32_to_cpus(&congestion->state.__state[i]); -+ return 0; -+} -+EXPORT_SYMBOL(qman_query_congestion); -+ -+/* internal function used as a wait_event() expression */ -+static int set_p_vdqcr(struct qman_portal *p, struct qman_fq *fq, u32 vdqcr) -+{ -+ unsigned long irqflags __maybe_unused; -+ int ret = -EBUSY; -+ PORTAL_IRQ_LOCK(p, irqflags); -+ if (!p->vdqcr_owned) { -+ FQLOCK(fq); -+ if (fq_isset(fq, QMAN_FQ_STATE_VDQCR)) -+ goto escape; -+ fq_set(fq, QMAN_FQ_STATE_VDQCR); -+ FQUNLOCK(fq); -+ p->vdqcr_owned = fq; -+ ret = 0; -+ } -+escape: -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ if (!ret) -+ qm_dqrr_vdqcr_set(&p->p, vdqcr); -+ return ret; -+} -+ -+static int set_vdqcr(struct qman_portal **p, struct qman_fq *fq, u32 vdqcr) -+{ -+ int ret; -+ *p = get_affine_portal(); -+ ret = set_p_vdqcr(*p, fq, vdqcr); -+ put_affine_portal(); -+ return ret; -+} -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+static int wait_p_vdqcr_start(struct qman_portal *p, struct qman_fq *fq, -+ u32 vdqcr, u32 flags) -+{ -+ int ret = 0; -+ if (flags & QMAN_VOLATILE_FLAG_WAIT_INT) -+ ret = wait_event_interruptible(affine_queue, -+ !(ret = set_p_vdqcr(p, fq, vdqcr))); -+ else -+ wait_event(affine_queue, !(ret = set_p_vdqcr(p, fq, vdqcr))); -+ return ret; -+} -+ -+static int wait_vdqcr_start(struct qman_portal **p, struct qman_fq *fq, -+ u32 vdqcr, u32 flags) -+{ -+ int ret = 0; -+ if (flags & QMAN_VOLATILE_FLAG_WAIT_INT) -+ ret = wait_event_interruptible(affine_queue, -+ !(ret = set_vdqcr(p, fq, vdqcr))); -+ else -+ wait_event(affine_queue, !(ret = set_vdqcr(p, fq, vdqcr))); -+ return ret; -+} -+#endif -+ -+int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq, -+ u32 flags __maybe_unused, u32 vdqcr) -+{ -+ int ret; -+ -+ if ((fq->state != qman_fq_state_parked) && -+ (fq->state != qman_fq_state_retired)) -+ return -EINVAL; -+ if (vdqcr & QM_VDQCR_FQID_MASK) -+ return -EINVAL; -+ if (fq_isset(fq, QMAN_FQ_STATE_VDQCR)) -+ return -EBUSY; -+ vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid; -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & QMAN_VOLATILE_FLAG_WAIT) -+ ret = wait_p_vdqcr_start(p, fq, vdqcr, flags); -+ else -+#endif -+ ret = set_p_vdqcr(p, fq, vdqcr); -+ if (ret) -+ return ret; -+ /* VDQCR is set */ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & QMAN_VOLATILE_FLAG_FINISH) { -+ if (flags & QMAN_VOLATILE_FLAG_WAIT_INT) -+ /* NB: don't propagate any error - the caller wouldn't -+ * know whether the VDQCR was issued or not. A signal -+ * could arrive after returning anyway, so the caller -+ * can check signal_pending() if that's an issue. */ -+ wait_event_interruptible(affine_queue, -+ !fq_isset(fq, QMAN_FQ_STATE_VDQCR)); -+ else -+ wait_event(affine_queue, -+ !fq_isset(fq, QMAN_FQ_STATE_VDQCR)); -+ } -+#endif -+ return 0; -+} -+EXPORT_SYMBOL(qman_p_volatile_dequeue); -+ -+int qman_volatile_dequeue(struct qman_fq *fq, u32 flags __maybe_unused, -+ u32 vdqcr) -+{ -+ struct qman_portal *p; -+ int ret; -+ -+ if ((fq->state != qman_fq_state_parked) && -+ (fq->state != qman_fq_state_retired)) -+ return -EINVAL; -+ if (vdqcr & QM_VDQCR_FQID_MASK) -+ return -EINVAL; -+ if (fq_isset(fq, QMAN_FQ_STATE_VDQCR)) -+ return -EBUSY; -+ vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid; -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & QMAN_VOLATILE_FLAG_WAIT) -+ ret = wait_vdqcr_start(&p, fq, vdqcr, flags); -+ else -+#endif -+ ret = set_vdqcr(&p, fq, vdqcr); -+ if (ret) -+ return ret; -+ /* VDQCR is set */ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & QMAN_VOLATILE_FLAG_FINISH) { -+ if (flags & QMAN_VOLATILE_FLAG_WAIT_INT) -+ /* NB: don't propagate any error - the caller wouldn't -+ * know whether the VDQCR was issued or not. A signal -+ * could arrive after returning anyway, so the caller -+ * can check signal_pending() if that's an issue. */ -+ wait_event_interruptible(affine_queue, -+ !fq_isset(fq, QMAN_FQ_STATE_VDQCR)); -+ else -+ wait_event(affine_queue, -+ !fq_isset(fq, QMAN_FQ_STATE_VDQCR)); -+ } -+#endif -+ return 0; -+} -+EXPORT_SYMBOL(qman_volatile_dequeue); -+ -+static noinline void update_eqcr_ci(struct qman_portal *p, u8 avail) -+{ -+ if (avail) -+ qm_eqcr_cce_prefetch(&p->p); -+ else -+ qm_eqcr_cce_update(&p->p); -+} -+ -+int qman_eqcr_is_empty(void) -+{ -+ unsigned long irqflags __maybe_unused; -+ struct qman_portal *p = get_affine_portal(); -+ u8 avail; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ update_eqcr_ci(p, 0); -+ avail = qm_eqcr_get_fill(&p->p); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return avail == 0; -+} -+EXPORT_SYMBOL(qman_eqcr_is_empty); -+ -+void qman_set_dc_ern(qman_cb_dc_ern handler, int affine) -+{ -+ if (affine) { -+ unsigned long irqflags __maybe_unused; -+ struct qman_portal *p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ p->cb_dc_ern = handler; -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ } else -+ cb_dc_ern = handler; -+} -+EXPORT_SYMBOL(qman_set_dc_ern); -+ -+static inline struct qm_eqcr_entry *try_p_eq_start(struct qman_portal *p, -+ unsigned long *irqflags __maybe_unused, -+ struct qman_fq *fq, -+ const struct qm_fd *fd, -+ u32 flags) -+{ -+ struct qm_eqcr_entry *eq; -+ u8 avail; -+ PORTAL_IRQ_LOCK(p, (*irqflags)); -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) && -+ (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) { -+ if (p->eqci_owned) { -+ PORTAL_IRQ_UNLOCK(p, (*irqflags)); -+ return NULL; -+ } -+ p->eqci_owned = fq; -+ } -+#endif -+ if (p->use_eqcr_ci_stashing) { -+ /* -+ * The stashing case is easy, only update if we need to in -+ * order to try and liberate ring entries. -+ */ -+ eq = qm_eqcr_start_stash(&p->p); -+ } else { -+ /* -+ * The non-stashing case is harder, need to prefetch ahead of -+ * time. -+ */ -+ avail = qm_eqcr_get_avail(&p->p); -+ if (avail < 2) -+ update_eqcr_ci(p, avail); -+ eq = qm_eqcr_start_no_stash(&p->p); -+ } -+ -+ if (unlikely(!eq)) { -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) && -+ (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) -+ p->eqci_owned = NULL; -+#endif -+ PORTAL_IRQ_UNLOCK(p, (*irqflags)); -+ return NULL; -+ } -+ if (flags & QMAN_ENQUEUE_FLAG_DCA) -+ eq->dca = QM_EQCR_DCA_ENABLE | -+ ((flags & QMAN_ENQUEUE_FLAG_DCA_PARK) ? -+ QM_EQCR_DCA_PARK : 0) | -+ ((flags >> 8) & QM_EQCR_DCA_IDXMASK); -+ eq->fqid = cpu_to_be32(fq->fqid); -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ eq->tag = cpu_to_be32(fq->key); -+#else -+ eq->tag = cpu_to_be32((u32)(uintptr_t)fq); -+#endif -+ eq->fd = *fd; -+ cpu_to_hw_fd(&eq->fd); -+ return eq; -+} -+ -+static inline struct qm_eqcr_entry *try_eq_start(struct qman_portal **p, -+ unsigned long *irqflags __maybe_unused, -+ struct qman_fq *fq, -+ const struct qm_fd *fd, -+ u32 flags) -+{ -+ struct qm_eqcr_entry *eq; -+ *p = get_affine_portal(); -+ eq = try_p_eq_start(*p, irqflags, fq, fd, flags); -+ if (!eq) -+ put_affine_portal(); -+ return eq; -+} -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+static noinline struct qm_eqcr_entry *__wait_eq_start(struct qman_portal **p, -+ unsigned long *irqflags __maybe_unused, -+ struct qman_fq *fq, -+ const struct qm_fd *fd, -+ u32 flags) -+{ -+ struct qm_eqcr_entry *eq = try_eq_start(p, irqflags, fq, fd, flags); -+ if (!eq) -+ qm_eqcr_set_ithresh(&(*p)->p, EQCR_ITHRESH); -+ return eq; -+} -+static noinline struct qm_eqcr_entry *wait_eq_start(struct qman_portal **p, -+ unsigned long *irqflags __maybe_unused, -+ struct qman_fq *fq, -+ const struct qm_fd *fd, -+ u32 flags) -+{ -+ struct qm_eqcr_entry *eq; -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT) -+ /* NB: return NULL if signal occurs before completion. Signal -+ * can occur during return. Caller must check for signal */ -+ wait_event_interruptible(affine_queue, -+ (eq = __wait_eq_start(p, irqflags, fq, fd, flags))); -+ else -+ wait_event(affine_queue, -+ (eq = __wait_eq_start(p, irqflags, fq, fd, flags))); -+ return eq; -+} -+static noinline struct qm_eqcr_entry *__wait_p_eq_start(struct qman_portal *p, -+ unsigned long *irqflags __maybe_unused, -+ struct qman_fq *fq, -+ const struct qm_fd *fd, -+ u32 flags) -+{ -+ struct qm_eqcr_entry *eq = try_p_eq_start(p, irqflags, fq, fd, flags); -+ if (!eq) -+ qm_eqcr_set_ithresh(&p->p, EQCR_ITHRESH); -+ return eq; -+} -+static noinline struct qm_eqcr_entry *wait_p_eq_start(struct qman_portal *p, -+ unsigned long *irqflags __maybe_unused, -+ struct qman_fq *fq, -+ const struct qm_fd *fd, -+ u32 flags) -+{ -+ struct qm_eqcr_entry *eq; -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT) -+ /* NB: return NULL if signal occurs before completion. Signal -+ * can occur during return. Caller must check for signal */ -+ wait_event_interruptible(affine_queue, -+ (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags))); -+ else -+ wait_event(affine_queue, -+ (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags))); -+ return eq; -+} -+#endif -+ -+int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq, -+ const struct qm_fd *fd, u32 flags) -+{ -+ struct qm_eqcr_entry *eq; -+ unsigned long irqflags __maybe_unused; -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT) -+ eq = wait_p_eq_start(p, &irqflags, fq, fd, flags); -+ else -+#endif -+ eq = try_p_eq_start(p, &irqflags, fq, fd, flags); -+ if (!eq) -+ return -EBUSY; -+ /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */ -+ qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE | -+ (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT))); -+ /* Factor the below out, it's used from qman_enqueue_orp() too */ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) && -+ (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) { -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT) -+ /* NB: return success even if signal occurs before -+ * condition is true. pvb_commit guarantees success */ -+ wait_event_interruptible(affine_queue, -+ (p->eqci_owned != fq)); -+ else -+ wait_event(affine_queue, (p->eqci_owned != fq)); -+ } -+#endif -+ return 0; -+} -+EXPORT_SYMBOL(qman_p_enqueue); -+ -+int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags) -+{ -+ struct qman_portal *p; -+ struct qm_eqcr_entry *eq; -+ unsigned long irqflags __maybe_unused; -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT) -+ eq = wait_eq_start(&p, &irqflags, fq, fd, flags); -+ else -+#endif -+ eq = try_eq_start(&p, &irqflags, fq, fd, flags); -+ if (!eq) -+ return -EBUSY; -+ /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */ -+ qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE | -+ (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT))); -+ /* Factor the below out, it's used from qman_enqueue_orp() too */ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) && -+ (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) { -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT) -+ /* NB: return success even if signal occurs before -+ * condition is true. pvb_commit guarantees success */ -+ wait_event_interruptible(affine_queue, -+ (p->eqci_owned != fq)); -+ else -+ wait_event(affine_queue, (p->eqci_owned != fq)); -+ } -+#endif -+ return 0; -+} -+EXPORT_SYMBOL(qman_enqueue); -+ -+int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq, -+ const struct qm_fd *fd, u32 flags, -+ struct qman_fq *orp, u16 orp_seqnum) -+{ -+ struct qm_eqcr_entry *eq; -+ unsigned long irqflags __maybe_unused; -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT) -+ eq = wait_p_eq_start(p, &irqflags, fq, fd, flags); -+ else -+#endif -+ eq = try_p_eq_start(p, &irqflags, fq, fd, flags); -+ if (!eq) -+ return -EBUSY; -+ /* Process ORP-specifics here */ -+ if (flags & QMAN_ENQUEUE_FLAG_NLIS) -+ orp_seqnum |= QM_EQCR_SEQNUM_NLIS; -+ else { -+ orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS; -+ if (flags & QMAN_ENQUEUE_FLAG_NESN) -+ orp_seqnum |= QM_EQCR_SEQNUM_NESN; -+ else -+ /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */ -+ orp_seqnum &= ~QM_EQCR_SEQNUM_NESN; -+ } -+ eq->seqnum = cpu_to_be16(orp_seqnum); -+ eq->orp = cpu_to_be32(orp->fqid); -+ /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */ -+ qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP | -+ ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ? -+ 0 : QM_EQCR_VERB_CMD_ENQUEUE) | -+ (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT))); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) && -+ (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) { -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT) -+ /* NB: return success even if signal occurs before -+ * condition is true. pvb_commit guarantees success */ -+ wait_event_interruptible(affine_queue, -+ (p->eqci_owned != fq)); -+ else -+ wait_event(affine_queue, (p->eqci_owned != fq)); -+ } -+#endif -+ return 0; -+} -+EXPORT_SYMBOL(qman_p_enqueue_orp); -+ -+int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags, -+ struct qman_fq *orp, u16 orp_seqnum) -+{ -+ struct qman_portal *p; -+ struct qm_eqcr_entry *eq; -+ unsigned long irqflags __maybe_unused; -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT) -+ eq = wait_eq_start(&p, &irqflags, fq, fd, flags); -+ else -+#endif -+ eq = try_eq_start(&p, &irqflags, fq, fd, flags); -+ if (!eq) -+ return -EBUSY; -+ /* Process ORP-specifics here */ -+ if (flags & QMAN_ENQUEUE_FLAG_NLIS) -+ orp_seqnum |= QM_EQCR_SEQNUM_NLIS; -+ else { -+ orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS; -+ if (flags & QMAN_ENQUEUE_FLAG_NESN) -+ orp_seqnum |= QM_EQCR_SEQNUM_NESN; -+ else -+ /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */ -+ orp_seqnum &= ~QM_EQCR_SEQNUM_NESN; -+ } -+ eq->seqnum = cpu_to_be16(orp_seqnum); -+ eq->orp = cpu_to_be32(orp->fqid); -+ /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */ -+ qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP | -+ ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ? -+ 0 : QM_EQCR_VERB_CMD_ENQUEUE) | -+ (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT))); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) && -+ (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) { -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT) -+ /* NB: return success even if signal occurs before -+ * condition is true. pvb_commit guarantees success */ -+ wait_event_interruptible(affine_queue, -+ (p->eqci_owned != fq)); -+ else -+ wait_event(affine_queue, (p->eqci_owned != fq)); -+ } -+#endif -+ return 0; -+} -+EXPORT_SYMBOL(qman_enqueue_orp); -+ -+int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq, -+ const struct qm_fd *fd, u32 flags, -+ qman_cb_precommit cb, void *cb_arg) -+{ -+ struct qm_eqcr_entry *eq; -+ unsigned long irqflags __maybe_unused; -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT) -+ eq = wait_p_eq_start(p, &irqflags, fq, fd, flags); -+ else -+#endif -+ eq = try_p_eq_start(p, &irqflags, fq, fd, flags); -+ if (!eq) -+ return -EBUSY; -+ /* invoke user supplied callback function before writing commit verb */ -+ if (cb(cb_arg)) { -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ return -EINVAL; -+ } -+ /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */ -+ qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE | -+ (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT))); -+ /* Factor the below out, it's used from qman_enqueue_orp() too */ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) && -+ (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) { -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT) -+ /* NB: return success even if signal occurs before -+ * condition is true. pvb_commit guarantees success */ -+ wait_event_interruptible(affine_queue, -+ (p->eqci_owned != fq)); -+ else -+ wait_event(affine_queue, (p->eqci_owned != fq)); -+ } -+#endif -+ return 0; -+} -+EXPORT_SYMBOL(qman_p_enqueue_precommit); -+ -+int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd, -+ u32 flags, qman_cb_precommit cb, void *cb_arg) -+{ -+ struct qman_portal *p; -+ struct qm_eqcr_entry *eq; -+ unsigned long irqflags __maybe_unused; -+ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT) -+ eq = wait_eq_start(&p, &irqflags, fq, fd, flags); -+ else -+#endif -+ eq = try_eq_start(&p, &irqflags, fq, fd, flags); -+ if (!eq) -+ return -EBUSY; -+ /* invoke user supplied callback function before writing commit verb */ -+ if (cb(cb_arg)) { -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return -EINVAL; -+ } -+ /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */ -+ qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE | -+ (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT))); -+ /* Factor the below out, it's used from qman_enqueue_orp() too */ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+ if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) && -+ (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) { -+ if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT) -+ /* NB: return success even if signal occurs before -+ * condition is true. pvb_commit guarantees success */ -+ wait_event_interruptible(affine_queue, -+ (p->eqci_owned != fq)); -+ else -+ wait_event(affine_queue, (p->eqci_owned != fq)); -+ } -+#endif -+ return 0; -+} -+EXPORT_SYMBOL(qman_enqueue_precommit); -+ -+int qman_modify_cgr(struct qman_cgr *cgr, u32 flags, -+ struct qm_mcc_initcgr *opts) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p = get_affine_portal(); -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ u8 verb = QM_MCC_VERB_MODIFYCGR; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ mcc = qm_mc_start(&p->p); -+ if (opts) -+ mcc->initcgr = *opts; -+ mcc->initcgr.we_mask = cpu_to_be16(mcc->initcgr.we_mask); -+ mcc->initcgr.cgr.wr_parm_g.word = -+ cpu_to_be32(mcc->initcgr.cgr.wr_parm_g.word); -+ mcc->initcgr.cgr.wr_parm_y.word = -+ cpu_to_be32(mcc->initcgr.cgr.wr_parm_y.word); -+ mcc->initcgr.cgr.wr_parm_r.word = -+ cpu_to_be32(mcc->initcgr.cgr.wr_parm_r.word); -+ mcc->initcgr.cgr.cscn_targ = cpu_to_be32(mcc->initcgr.cgr.cscn_targ); -+ mcc->initcgr.cgr.__cs_thres = cpu_to_be16(mcc->initcgr.cgr.__cs_thres); -+ -+ mcc->initcgr.cgid = cgr->cgrid; -+ if (flags & QMAN_CGR_FLAG_USE_INIT) -+ verb = QM_MCC_VERB_INITCGR; -+ qm_mc_commit(&p->p, verb); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == verb); -+ res = mcr->result; -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return (res == QM_MCR_RESULT_OK) ? 0 : -EIO; -+} -+EXPORT_SYMBOL(qman_modify_cgr); -+ -+#define TARG_MASK(n) (0x80000000 >> (n->config->public_cfg.channel - \ -+ QM_CHANNEL_SWPORTAL0)) -+#define TARG_DCP_MASK(n) (0x80000000 >> (10 + n)) -+#define PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0) -+ -+static u8 qman_cgr_cpus[__CGR_NUM]; -+ -+int qman_create_cgr(struct qman_cgr *cgr, u32 flags, -+ struct qm_mcc_initcgr *opts) -+{ -+ unsigned long irqflags __maybe_unused; -+ struct qm_mcr_querycgr cgr_state; -+ struct qm_mcc_initcgr local_opts; -+ int ret; -+ struct qman_portal *p; -+ -+ /* We have to check that the provided CGRID is within the limits of the -+ * data-structures, for obvious reasons. However we'll let h/w take -+ * care of determining whether it's within the limits of what exists on -+ * the SoC. */ -+ if (cgr->cgrid >= __CGR_NUM) -+ return -EINVAL; -+ -+ preempt_disable(); -+ p = get_affine_portal(); -+ qman_cgr_cpus[cgr->cgrid] = smp_processor_id(); -+ preempt_enable(); -+ -+ memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr)); -+ cgr->chan = p->config->public_cfg.channel; -+ spin_lock_irqsave(&p->cgr_lock, irqflags); -+ -+ /* if no opts specified, just add it to the list */ -+ if (!opts) -+ goto add_list; -+ -+ ret = qman_query_cgr(cgr, &cgr_state); -+ if (ret) -+ goto release_lock; -+ if (opts) -+ local_opts = *opts; -+ if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) -+ local_opts.cgr.cscn_targ_upd_ctrl = -+ QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p); -+ else -+ /* Overwrite TARG */ -+ local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ | -+ TARG_MASK(p); -+ local_opts.we_mask |= QM_CGR_WE_CSCN_TARG; -+ -+ /* send init if flags indicate so */ -+ if (opts && (flags & QMAN_CGR_FLAG_USE_INIT)) -+ ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT, &local_opts); -+ else -+ ret = qman_modify_cgr(cgr, 0, &local_opts); -+ if (ret) -+ goto release_lock; -+add_list: -+ list_add(&cgr->node, &p->cgr_cbs); -+ -+ /* Determine if newly added object requires its callback to be called */ -+ ret = qman_query_cgr(cgr, &cgr_state); -+ if (ret) { -+ /* we can't go back, so proceed and return success, but screen -+ * and wail to the log file */ -+ pr_crit("CGR HW state partially modified\n"); -+ ret = 0; -+ goto release_lock; -+ } -+ if (cgr->cb && cgr_state.cgr.cscn_en && qman_cgrs_get(&p->cgrs[1], -+ cgr->cgrid)) -+ cgr->cb(p, cgr, 1); -+release_lock: -+ spin_unlock_irqrestore(&p->cgr_lock, irqflags); -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_create_cgr); -+ -+int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal, -+ struct qm_mcc_initcgr *opts) -+{ -+ unsigned long irqflags __maybe_unused; -+ struct qm_mcc_initcgr local_opts; -+ struct qm_mcr_querycgr cgr_state; -+ int ret; -+ -+ if ((qman_ip_rev & 0xFF00) < QMAN_REV30) { -+ pr_warn("This QMan version doesn't support to send CSCN to DCP portal\n"); -+ return -EINVAL; -+ } -+ /* We have to check that the provided CGRID is within the limits of the -+ * data-structures, for obvious reasons. However we'll let h/w take -+ * care of determining whether it's within the limits of what exists on -+ * the SoC. -+ */ -+ if (cgr->cgrid >= __CGR_NUM) -+ return -EINVAL; -+ -+ ret = qman_query_cgr(cgr, &cgr_state); -+ if (ret) -+ return ret; -+ -+ memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr)); -+ if (opts) -+ local_opts = *opts; -+ -+ if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) -+ local_opts.cgr.cscn_targ_upd_ctrl = -+ QM_CGR_TARG_UDP_CTRL_WRITE_BIT | -+ QM_CGR_TARG_UDP_CTRL_DCP | dcp_portal; -+ else -+ local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ | -+ TARG_DCP_MASK(dcp_portal); -+ local_opts.we_mask |= QM_CGR_WE_CSCN_TARG; -+ -+ /* send init if flags indicate so */ -+ if (opts && (flags & QMAN_CGR_FLAG_USE_INIT)) -+ ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT, -+ &local_opts); -+ else -+ ret = qman_modify_cgr(cgr, 0, &local_opts); -+ -+ return ret; -+} -+EXPORT_SYMBOL(qman_create_cgr_to_dcp); -+ -+int qman_delete_cgr(struct qman_cgr *cgr) -+{ -+ unsigned long irqflags __maybe_unused; -+ struct qm_mcr_querycgr cgr_state; -+ struct qm_mcc_initcgr local_opts; -+ int ret = 0; -+ struct qman_cgr *i; -+ struct qman_portal *p = get_affine_portal(); -+ -+ if (cgr->chan != p->config->public_cfg.channel) { -+ pr_crit("Attempting to delete cgr from different portal " -+ "than it was create: create 0x%x, delete 0x%x\n", -+ cgr->chan, p->config->public_cfg.channel); -+ ret = -EINVAL; -+ goto put_portal; -+ } -+ memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr)); -+ spin_lock_irqsave(&p->cgr_lock, irqflags); -+ list_del(&cgr->node); -+ /* -+ * If there are no other CGR objects for this CGRID in the list, update -+ * CSCN_TARG accordingly -+ */ -+ list_for_each_entry(i, &p->cgr_cbs, node) -+ if ((i->cgrid == cgr->cgrid) && i->cb) -+ goto release_lock; -+ ret = qman_query_cgr(cgr, &cgr_state); -+ if (ret) { -+ /* add back to the list */ -+ list_add(&cgr->node, &p->cgr_cbs); -+ goto release_lock; -+ } -+ /* Overwrite TARG */ -+ local_opts.we_mask = QM_CGR_WE_CSCN_TARG; -+ if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) -+ local_opts.cgr.cscn_targ_upd_ctrl = PORTAL_IDX(p); -+ else -+ local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ & -+ ~(TARG_MASK(p)); -+ ret = qman_modify_cgr(cgr, 0, &local_opts); -+ if (ret) -+ /* add back to the list */ -+ list_add(&cgr->node, &p->cgr_cbs); -+release_lock: -+ spin_unlock_irqrestore(&p->cgr_lock, irqflags); -+put_portal: -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_delete_cgr); -+ -+struct cgr_comp { -+ struct qman_cgr *cgr; -+ struct completion completion; -+}; -+ -+static int qman_delete_cgr_thread(void *p) -+{ -+ struct cgr_comp *cgr_comp = (struct cgr_comp *)p; -+ int res; -+ -+ res = qman_delete_cgr((struct qman_cgr *)cgr_comp->cgr); -+ complete(&cgr_comp->completion); -+ -+ return res; -+} -+ -+void qman_delete_cgr_safe(struct qman_cgr *cgr) -+{ -+ struct task_struct *thread; -+ struct cgr_comp cgr_comp; -+ -+ preempt_disable(); -+ if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) { -+ init_completion(&cgr_comp.completion); -+ cgr_comp.cgr = cgr; -+ thread = kthread_create(qman_delete_cgr_thread, &cgr_comp, -+ "cgr_del"); -+ -+ if (likely(!IS_ERR(thread))) { -+ kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]); -+ wake_up_process(thread); -+ wait_for_completion(&cgr_comp.completion); -+ preempt_enable(); -+ return; -+ } -+ } -+ qman_delete_cgr(cgr); -+ preempt_enable(); -+} -+EXPORT_SYMBOL(qman_delete_cgr_safe); -+ -+int qm_get_clock(u64 *clock_hz) -+{ -+ if (!qman_clk) { -+ pr_warn("Qman clock speed is unknown\n"); -+ return -EINVAL; -+ } -+ *clock_hz = (u64)qman_clk; -+ return 0; -+} -+EXPORT_SYMBOL(qm_get_clock); -+ -+int qm_set_clock(u64 clock_hz) -+{ -+ if (qman_clk) -+ return -1; -+ qman_clk = (u32)clock_hz; -+ return 0; -+} -+EXPORT_SYMBOL(qm_set_clock); -+ -+/* CEETM management command */ -+static int qman_ceetm_configure_lfqmt(struct qm_mcc_ceetm_lfqmt_config *opts) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->lfqmt_config = *opts; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_CONFIG); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_CEETM_VERB_LFQMT_CONFIG); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ res = mcr->result; -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: CONFIGURE LFQMT failed\n"); -+ return -EIO; -+ } -+ return 0; -+} -+ -+int qman_ceetm_query_lfqmt(int lfqid, -+ struct qm_mcr_ceetm_lfqmt_query *lfqmt_query) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->lfqmt_query.lfqid = lfqid; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_QUERY); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_LFQMT_QUERY); -+ res = mcr->result; -+ if (res == QM_MCR_RESULT_OK) -+ *lfqmt_query = mcr->lfqmt_query; -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: QUERY LFQMT failed\n"); -+ return -EIO; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_query_lfqmt); -+ -+static int qman_ceetm_configure_cq(struct qm_mcc_ceetm_cq_config *opts) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->cq_config = *opts; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_CONFIG); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ res = mcr->result; -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_CONFIG); -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: CONFIGURE CQ failed\n"); -+ return -EIO; -+ } -+ return 0; -+} -+ -+int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid, -+ struct qm_mcr_ceetm_cq_query *cq_query) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->cq_query.cqid = cpu_to_be16(cqid); -+ mcc->cq_query.dcpid = dcpid; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_QUERY); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_QUERY); -+ res = mcr->result; -+ if (res == QM_MCR_RESULT_OK) { -+ *cq_query = mcr->cq_query; -+ hw_cq_query_to_cpu(cq_query); -+ } -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: QUERY CQ failed\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_query_cq); -+ -+static int qman_ceetm_configure_dct(struct qm_mcc_ceetm_dct_config *opts) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->dct_config = *opts; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_CONFIG); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_CONFIG); -+ res = mcr->result; -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: CONFIGURE DCT failed\n"); -+ return -EIO; -+ } -+ return 0; -+} -+ -+static int qman_ceetm_query_dct(struct qm_mcc_ceetm_dct_query *opts, -+ struct qm_mcr_ceetm_dct_query *dct_query) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p = get_affine_portal(); -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->dct_query = *opts; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_QUERY); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_QUERY); -+ res = mcr->result; -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: QUERY DCT failed\n"); -+ return -EIO; -+ } -+ -+ *dct_query = mcr->dct_query; -+ return 0; -+} -+ -+static int qman_ceetm_configure_class_scheduler( -+ struct qm_mcc_ceetm_class_scheduler_config *opts) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->csch_config = *opts; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG); -+ res = mcr->result; -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: CONFIGURE CLASS SCHEDULER failed\n"); -+ return -EIO; -+ } -+ return 0; -+} -+ -+static int qman_ceetm_query_class_scheduler(struct qm_ceetm_channel *channel, -+ struct qm_mcr_ceetm_class_scheduler_query *query) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->csch_query.cqcid = cpu_to_be16(channel->idx); -+ mcc->csch_query.dcpid = channel->dcp_idx; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_QUERY); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_CEETM_VERB_CLASS_SCHEDULER_QUERY); -+ res = mcr->result; -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: QUERY CLASS SCHEDULER failed\n"); -+ return -EIO; -+ } -+ *query = mcr->csch_query; -+ return 0; -+} -+ -+static int qman_ceetm_configure_mapping_shaper_tcfc( -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config *opts) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->mst_config = *opts; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG); -+ res = mcr->result; -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: CONFIGURE CHANNEL MAPPING failed\n"); -+ return -EIO; -+ } -+ return 0; -+} -+ -+static int qman_ceetm_query_mapping_shaper_tcfc( -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query *opts, -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query *response) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->mst_query = *opts; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY); -+ res = mcr->result; -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: QUERY CHANNEL MAPPING failed\n"); -+ return -EIO; -+ } -+ -+ *response = mcr->mst_query; -+ return 0; -+} -+ -+static int qman_ceetm_configure_ccgr(struct qm_mcc_ceetm_ccgr_config *opts) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->ccgr_config = *opts; -+ -+ qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_CONFIG); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_CONFIG); -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ res = mcr->result; -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: CONFIGURE CCGR failed\n"); -+ return -EIO; -+ } -+ return 0; -+} -+ -+int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query, -+ struct qm_mcr_ceetm_ccgr_query *response) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->ccgr_query.ccgrid = cpu_to_be16(ccgr_query->ccgrid); -+ mcc->ccgr_query.dcpid = ccgr_query->dcpid; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY); -+ -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_QUERY); -+ res = mcr->result; -+ if (res == QM_MCR_RESULT_OK) { -+ *response = mcr->ccgr_query; -+ hw_ccgr_query_to_cpu(response); -+ } -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: QUERY CCGR failed\n"); -+ return -EIO; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_query_ccgr); -+ -+static int qman_ceetm_cq_peek_pop_xsfdrread(struct qm_ceetm_cq *cq, -+ u8 command_type, u16 xsfdr, -+ struct qm_mcr_ceetm_cq_peek_pop_xsfdrread *cq_ppxr) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ switch (command_type) { -+ case 0: -+ case 1: -+ mcc->cq_ppxr.cqid = (cq->parent->idx << 4) | cq->idx; -+ break; -+ case 2: -+ mcc->cq_ppxr.xsfdr = xsfdr; -+ break; -+ default: -+ break; -+ } -+ mcc->cq_ppxr.ct = command_type; -+ mcc->cq_ppxr.dcpid = cq->parent->dcp_idx; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD); -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD); -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ res = mcr->result; -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: CQ PEEK/POP/XSFDR READ failed\n"); -+ return -EIO; -+ } -+ *cq_ppxr = mcr->cq_ppxr; -+ return 0; -+} -+ -+static int qman_ceetm_query_statistics(u16 cid, -+ enum qm_dc_portal dcp_idx, -+ u16 command_type, -+ struct qm_mcr_ceetm_statistics_query *query_result) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->stats_query_write.cid = cid; -+ mcc->stats_query_write.dcpid = dcp_idx; -+ mcc->stats_query_write.ct = command_type; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE); -+ -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_CEETM_VERB_STATISTICS_QUERY_WRITE); -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ res = mcr->result; -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: STATISTICS QUERY failed\n"); -+ return -EIO; -+ } -+ *query_result = mcr->stats_query; -+ return 0; -+} -+ -+int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx, -+ u16 command_type, u64 frame_count, -+ u64 byte_count) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ mcc->stats_query_write.cid = cid; -+ mcc->stats_query_write.dcpid = dcp_idx; -+ mcc->stats_query_write.ct = command_type; -+ mcc->stats_query_write.frm_cnt = frame_count; -+ mcc->stats_query_write.byte_cnt = byte_count; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE); -+ -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_CEETM_VERB_STATISTICS_QUERY_WRITE); -+ -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ -+ res = mcr->result; -+ if (res != QM_MCR_RESULT_OK) { -+ pr_err("CEETM: STATISTICS WRITE failed\n"); -+ return -EIO; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_query_write_statistics); -+ -+int qman_ceetm_bps2tokenrate(u64 bps, struct qm_ceetm_rate *token_rate, -+ int rounding) -+{ -+ u16 pres; -+ u64 temp; -+ u64 qman_freq; -+ int ret; -+ -+ /* Read PRES from CEET_CFG_PRES register */ -+ ret = qman_ceetm_get_prescaler(&pres); -+ if (ret) -+ return -EINVAL; -+ -+ ret = qm_get_clock(&qman_freq); -+ if (ret) -+ return -EINVAL; -+ -+ /* token-rate = bytes-per-second * update-reference-period -+ * -+ * Where token-rate is N/8192 for a integer N, and -+ * update-reference-period is (2^22)/(PRES*QHz), where PRES -+ * is the prescalar value and QHz is the QMan clock frequency. -+ * So: -+ * -+ * token-rate = (byte-per-second*2^22)/PRES*QHZ) -+ * -+ * Converting to bits-per-second gives; -+ * -+ * token-rate = (bps*2^19) / (PRES*QHZ) -+ * N = (bps*2^32) / (PRES*QHz) -+ * -+ * And to avoid 64-bit overflow if 'bps' is larger than 4Gbps -+ * (yet minimise rounding error if 'bps' is small), we reorganise -+ * the formula to use two 16-bit shifts rather than 1 32-bit shift. -+ * N = (((bps*2^16)/PRES)*2^16)/QHz -+ */ -+ temp = ROUNDING((bps << 16), pres, rounding); -+ temp = ROUNDING((temp << 16), qman_freq, rounding); -+ token_rate->whole = temp >> 13; -+ token_rate->fraction = temp & (((u64)1 << 13) - 1); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_bps2tokenrate); -+ -+int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate, u64 *bps, -+ int rounding) -+{ -+ u16 pres; -+ u64 temp; -+ u64 qman_freq; -+ int ret; -+ -+ /* Read PRES from CEET_CFG_PRES register */ -+ ret = qman_ceetm_get_prescaler(&pres); -+ if (ret) -+ return -EINVAL; -+ -+ ret = qm_get_clock(&qman_freq); -+ if (ret) -+ return -EINVAL; -+ -+ /* bytes-per-second = token-rate / update-reference-period -+ * -+ * where "token-rate" is N/8192 for an integer N, and -+ * "update-reference-period" is (2^22)/(PRES*QHz), where PRES is -+ * the prescalar value and QHz is the QMan clock frequency. So; -+ * -+ * bytes-per-second = (N/8192) / (4194304/PRES*QHz) -+ * = N*PRES*QHz / (4194304*8192) -+ * = N*PRES*QHz / (2^35) -+ * -+ * Converting to bits-per-second gives; -+ * -+ * bps = N*PRES*QHZ / (2^32) -+ * -+ * Note, the numerator has a maximum width of 72 bits! So to -+ * avoid 64-bit overflow errors, we calculate PRES*QHZ (maximum -+ * width 48 bits) divided by 2^9 (reducing to maximum 39 bits), before -+ * multiplying by N (goes to maximum of 63 bits). -+ * -+ * temp = PRES*QHZ / (2^16) -+ * kbps = temp*N / (2^16) -+ */ -+ temp = ROUNDING(qman_freq * pres, (u64)1 << 16 , rounding); -+ temp *= ((token_rate->whole << 13) + token_rate->fraction); -+ *bps = ROUNDING(temp, (u64)(1) << 16, rounding); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_tokenrate2bps); -+ -+int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp, enum qm_dc_portal dcp_idx, -+ unsigned int sp_idx) -+{ -+ struct qm_ceetm_sp *p; -+ -+ DPA_ASSERT((dcp_idx == qm_dc_portal_fman0) || -+ (dcp_idx == qm_dc_portal_fman1)); -+ -+ if ((sp_idx < qman_ceetms[dcp_idx].sp_range[0]) || -+ (sp_idx >= (qman_ceetms[dcp_idx].sp_range[0] + -+ qman_ceetms[dcp_idx].sp_range[1]))) { -+ pr_err("Sub-portal index doesn't exist\n"); -+ return -EINVAL; -+ } -+ -+ list_for_each_entry(p, &qman_ceetms[dcp_idx].sub_portals, node) { -+ if ((p->idx == sp_idx) && (p->is_claimed == 0)) { -+ p->is_claimed = 1; -+ *sp = p; -+ return 0; -+ } -+ } -+ pr_err("The sub-portal#%d is not available!\n", sp_idx); -+ return -ENODEV; -+} -+EXPORT_SYMBOL(qman_ceetm_sp_claim); -+ -+int qman_ceetm_sp_release(struct qm_ceetm_sp *sp) -+{ -+ struct qm_ceetm_sp *p; -+ -+ if (sp->lni && sp->lni->is_claimed == 1) { -+ pr_err("The dependency of sub-portal has not been released!\n"); -+ return -EBUSY; -+ } -+ -+ list_for_each_entry(p, &qman_ceetms[sp->dcp_idx].sub_portals, node) { -+ if (p->idx == sp->idx) { -+ p->is_claimed = 0; -+ p->lni = NULL; -+ } -+ } -+ /* Disable CEETM mode of this sub-portal */ -+ qman_sp_disable_ceetm_mode(sp->dcp_idx, sp->idx); -+ -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_sp_release); -+ -+int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni, enum qm_dc_portal dcp_idx, -+ unsigned int lni_idx) -+{ -+ struct qm_ceetm_lni *p; -+ -+ if ((lni_idx < qman_ceetms[dcp_idx].lni_range[0]) || -+ (lni_idx >= (qman_ceetms[dcp_idx].lni_range[0] + -+ qman_ceetms[dcp_idx].lni_range[1]))) { -+ pr_err("The lni index is out of range\n"); -+ return -EINVAL; -+ } -+ -+ list_for_each_entry(p, &qman_ceetms[dcp_idx].lnis, node) { -+ if ((p->idx == lni_idx) && (p->is_claimed == 0)) { -+ *lni = p; -+ p->is_claimed = 1; -+ return 0; -+ } -+ } -+ -+ pr_err("The LNI#%d is not available!\n", lni_idx); -+ return -EINVAL; -+} -+EXPORT_SYMBOL(qman_ceetm_lni_claim); -+ -+int qman_ceetm_lni_release(struct qm_ceetm_lni *lni) -+{ -+ struct qm_ceetm_lni *p; -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ -+ if (!list_empty(&lni->channels)) { -+ pr_err("The LNI dependencies are not released!\n"); -+ return -EBUSY; -+ } -+ -+ list_for_each_entry(p, &qman_ceetms[lni->dcp_idx].lnis, node) { -+ if (p->idx == lni->idx) { -+ p->shaper_enable = 0; -+ p->shaper_couple = 0; -+ p->cr_token_rate.whole = 0; -+ p->cr_token_rate.fraction = 0; -+ p->er_token_rate.whole = 0; -+ p->er_token_rate.fraction = 0; -+ p->cr_token_bucket_limit = 0; -+ p->er_token_bucket_limit = 0; -+ p->is_claimed = 0; -+ } -+ } -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx); -+ config_opts.dcpid = lni->dcp_idx; -+ memset(&config_opts.shaper_config, 0, -+ sizeof(config_opts.shaper_config)); -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_lni_release); -+ -+int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp, struct qm_ceetm_lni *lni) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx); -+ config_opts.dcpid = sp->dcp_idx; -+ config_opts.sp_mapping.map_lni_id = lni->idx; -+ sp->lni = lni; -+ -+ if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) -+ return -EINVAL; -+ -+ /* Enable CEETM mode for this sub-portal */ -+ return qman_sp_enable_ceetm_mode(sp->dcp_idx, sp->idx); -+} -+EXPORT_SYMBOL(qman_ceetm_sp_set_lni); -+ -+int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp, unsigned int *lni_idx) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx); -+ query_opts.dcpid = sp->dcp_idx; -+ if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) { -+ pr_err("Can't get SP <-> LNI mapping\n"); -+ return -EINVAL; -+ } -+ *lni_idx = query_result.sp_mapping_query.map_lni_id; -+ sp->lni->idx = query_result.sp_mapping_query.map_lni_id; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_sp_get_lni); -+ -+int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled, -+ int oal) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ -+ if (lni->shaper_enable) { -+ pr_err("The shaper has already been enabled\n"); -+ return -EINVAL; -+ } -+ lni->shaper_enable = 1; -+ lni->shaper_couple = coupled; -+ lni->oal = oal; -+ -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx); -+ config_opts.dcpid = lni->dcp_idx; -+ config_opts.shaper_config.cpl = coupled; -+ config_opts.shaper_config.oal = oal; -+ config_opts.shaper_config.crtcr = cpu_to_be24((lni->cr_token_rate.whole -+ << 13) | lni->cr_token_rate.fraction); -+ config_opts.shaper_config.ertcr = cpu_to_be24((lni->er_token_rate.whole -+ << 13) | lni->er_token_rate.fraction); -+ config_opts.shaper_config.crtbl = -+ cpu_to_be16(lni->cr_token_bucket_limit); -+ config_opts.shaper_config.ertbl = -+ cpu_to_be16(lni->er_token_bucket_limit); -+ config_opts.shaper_config.mps = 60; -+ -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_lni_enable_shaper); -+ -+int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ -+ if (!lni->shaper_enable) { -+ pr_err("The shaper has been disabled\n"); -+ return -EINVAL; -+ } -+ -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx); -+ config_opts.dcpid = lni->dcp_idx; -+ config_opts.shaper_config.cpl = lni->shaper_couple; -+ config_opts.shaper_config.oal = lni->oal; -+ config_opts.shaper_config.crtbl = -+ cpu_to_be16(lni->cr_token_bucket_limit); -+ config_opts.shaper_config.ertbl = -+ cpu_to_be16(lni->er_token_bucket_limit); -+ /* Set CR/ER rate with all 1's to configure an infinite rate, thus -+ * disable the shaping. -+ */ -+ config_opts.shaper_config.crtcr = 0xFFFFFF; -+ config_opts.shaper_config.ertcr = 0xFFFFFF; -+ config_opts.shaper_config.mps = 60; -+ lni->shaper_enable = 0; -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_lni_disable_shaper); -+ -+int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni) -+{ -+ return lni->shaper_enable; -+} -+EXPORT_SYMBOL(qman_ceetm_lni_is_shaper_enabled); -+ -+int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni, -+ const struct qm_ceetm_rate *token_rate, -+ u16 token_limit) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ int ret; -+ -+ lni->cr_token_rate.whole = token_rate->whole; -+ lni->cr_token_rate.fraction = token_rate->fraction; -+ lni->cr_token_bucket_limit = token_limit; -+ if (!lni->shaper_enable) -+ return 0; -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx); -+ query_opts.dcpid = lni->dcp_idx; -+ ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, -+ &query_result); -+ if (ret) { -+ pr_err("Fail to get current LNI shaper setting\n"); -+ return -EINVAL; -+ } -+ -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx); -+ config_opts.dcpid = lni->dcp_idx; -+ config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole << 13) -+ | (token_rate->fraction)); -+ config_opts.shaper_config.crtbl = cpu_to_be16(token_limit); -+ config_opts.shaper_config.cpl = query_result.shaper_query.cpl; -+ config_opts.shaper_config.oal = query_result.shaper_query.oal; -+ config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr; -+ config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl; -+ config_opts.shaper_config.mps = query_result.shaper_query.mps; -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate); -+ -+int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni, -+ u64 bps, -+ u16 token_limit) -+{ -+ struct qm_ceetm_rate token_rate; -+ int ret; -+ -+ ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0); -+ if (ret) { -+ pr_err("Can not convert bps to token rate\n"); -+ return -EINVAL; -+ } -+ -+ return qman_ceetm_lni_set_commit_rate(lni, &token_rate, token_limit); -+} -+EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate_bps); -+ -+int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni, -+ struct qm_ceetm_rate *token_rate, -+ u16 *token_limit) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ int ret; -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx); -+ query_opts.dcpid = lni->dcp_idx; -+ -+ ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result); -+ if (ret) { -+ pr_err("The LNI CR rate or limit is not set\n"); -+ return -EINVAL; -+ } -+ token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13; -+ token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) & -+ 0x1FFF; -+ *token_limit = be16_to_cpu(query_result.shaper_query.crtbl); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate); -+ -+int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni, -+ u64 *bps, u16 *token_limit) -+{ -+ struct qm_ceetm_rate token_rate; -+ int ret; -+ -+ ret = qman_ceetm_lni_get_commit_rate(lni, &token_rate, token_limit); -+ if (ret) { -+ pr_err("The LNI CR rate or limit is not available\n"); -+ return -EINVAL; -+ } -+ -+ return qman_ceetm_tokenrate2bps(&token_rate, bps, 0); -+} -+EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate_bps); -+ -+int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni, -+ const struct qm_ceetm_rate *token_rate, -+ u16 token_limit) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ int ret; -+ -+ lni->er_token_rate.whole = token_rate->whole; -+ lni->er_token_rate.fraction = token_rate->fraction; -+ lni->er_token_bucket_limit = token_limit; -+ if (!lni->shaper_enable) -+ return 0; -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx); -+ query_opts.dcpid = lni->dcp_idx; -+ ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, -+ &query_result); -+ if (ret) { -+ pr_err("Fail to get current LNI shaper setting\n"); -+ return -EINVAL; -+ } -+ -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx); -+ config_opts.dcpid = lni->dcp_idx; -+ config_opts.shaper_config.ertcr = cpu_to_be24( -+ (token_rate->whole << 13) | (token_rate->fraction)); -+ config_opts.shaper_config.ertbl = cpu_to_be16(token_limit); -+ config_opts.shaper_config.cpl = query_result.shaper_query.cpl; -+ config_opts.shaper_config.oal = query_result.shaper_query.oal; -+ config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr; -+ config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl; -+ config_opts.shaper_config.mps = query_result.shaper_query.mps; -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate); -+ -+int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni, -+ u64 bps, -+ u16 token_limit) -+{ -+ struct qm_ceetm_rate token_rate; -+ int ret; -+ -+ ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0); -+ if (ret) { -+ pr_err("Can not convert bps to token rate\n"); -+ return -EINVAL; -+ } -+ return qman_ceetm_lni_set_excess_rate(lni, &token_rate, token_limit); -+} -+EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate_bps); -+ -+int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni, -+ struct qm_ceetm_rate *token_rate, -+ u16 *token_limit) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ int ret; -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx); -+ query_opts.dcpid = lni->dcp_idx; -+ ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result); -+ if (ret) { -+ pr_err("The LNI ER rate or limit is not set\n"); -+ return -EINVAL; -+ } -+ token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13; -+ token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) & -+ 0x1FFF; -+ *token_limit = be16_to_cpu(query_result.shaper_query.ertbl); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate); -+ -+int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni, -+ u64 *bps, u16 *token_limit) -+{ -+ struct qm_ceetm_rate token_rate; -+ int ret; -+ -+ ret = qman_ceetm_lni_get_excess_rate(lni, &token_rate, token_limit); -+ if (ret) { -+ pr_err("The LNI ER rate or limit is not available\n"); -+ return -EINVAL; -+ } -+ -+ return qman_ceetm_tokenrate2bps(&token_rate, bps, 0); -+} -+EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate_bps); -+ -+#define QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(n) ((15 - n) * 4) -+#define QMAN_CEETM_LNITCFCC_ENABLE 0x8 -+int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni, -+ unsigned int cq_level, -+ int traffic_class) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ u64 lnitcfcc; -+ -+ if ((cq_level > 15) | (traffic_class > 7)) { -+ pr_err("The CQ or traffic class id is out of range\n"); -+ return -EINVAL; -+ } -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx); -+ query_opts.dcpid = lni->dcp_idx; -+ if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) { -+ pr_err("Fail to query tcfcc\n"); -+ return -EINVAL; -+ } -+ -+ lnitcfcc = be64_to_cpu(query_result.tcfc_query.lnitcfcc); -+ if (traffic_class == -1) { -+ /* disable tcfc for this CQ */ -+ lnitcfcc &= ~((u64)QMAN_CEETM_LNITCFCC_ENABLE << -+ QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level)); -+ } else { -+ lnitcfcc &= ~((u64)0xF << -+ QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level)); -+ lnitcfcc |= ((u64)(QMAN_CEETM_LNITCFCC_ENABLE | -+ traffic_class)) << -+ QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level); -+ } -+ config_opts.tcfc_config.lnitcfcc = cpu_to_be64(lnitcfcc); -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx); -+ config_opts.dcpid = lni->dcp_idx; -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_lni_set_tcfcc); -+ -+#define QMAN_CEETM_LNITCFCC_TC_MASK 0x7 -+int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni, unsigned int cq_level, -+ int *traffic_class) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ int ret; -+ u8 lnitcfcc; -+ -+ if (cq_level > 15) { -+ pr_err("the CQ level is out of range\n"); -+ return -EINVAL; -+ } -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx); -+ query_opts.dcpid = lni->dcp_idx; -+ ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result); -+ if (ret) -+ return ret; -+ lnitcfcc = (u8)be64_to_cpu((query_result.tcfc_query.lnitcfcc) >> -+ QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level)); -+ if (lnitcfcc & QMAN_CEETM_LNITCFCC_ENABLE) -+ *traffic_class = lnitcfcc & QMAN_CEETM_LNITCFCC_TC_MASK; -+ else -+ *traffic_class = -1; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_lni_get_tcfcc); -+ -+int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel, -+ struct qm_ceetm_lni *lni) -+{ -+ struct qm_ceetm_channel *p; -+ u32 channel_idx; -+ int ret = 0; -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ -+ if (lni->dcp_idx == qm_dc_portal_fman0) { -+ ret = qman_alloc_ceetm0_channel(&channel_idx); -+ } else if (lni->dcp_idx == qm_dc_portal_fman1) { -+ ret = qman_alloc_ceetm1_channel(&channel_idx); -+ } else { -+ pr_err("dcp_idx %u does not correspond to a known fman in this driver\n", -+ lni->dcp_idx); -+ return -EINVAL; -+ } -+ -+ if (ret) { -+ pr_err("The is no channel available for LNI#%d\n", lni->idx); -+ return -ENODEV; -+ } -+ -+ p = kzalloc(sizeof(*p), GFP_KERNEL); -+ if (!p) -+ return -ENOMEM; -+ p->idx = channel_idx; -+ p->dcp_idx = lni->dcp_idx; -+ p->lni_idx = lni->idx; -+ list_add_tail(&p->node, &lni->channels); -+ INIT_LIST_HEAD(&p->class_queues); -+ INIT_LIST_HEAD(&p->ccgs); -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING | -+ channel_idx); -+ config_opts.dcpid = lni->dcp_idx; -+ config_opts.channel_mapping.map_lni_id = lni->idx; -+ config_opts.channel_mapping.map_shaped = 0; -+ if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) { -+ pr_err("Can't map channel#%d for LNI#%d\n", -+ channel_idx, lni->idx); -+ return -EINVAL; -+ } -+ *channel = p; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_claim); -+ -+int qman_ceetm_channel_release(struct qm_ceetm_channel *channel) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ if (!list_empty(&channel->class_queues)) { -+ pr_err("CEETM channel#%d has class queue unreleased!\n", -+ channel->idx); -+ return -EBUSY; -+ } -+ if (!list_empty(&channel->ccgs)) { -+ pr_err("CEETM channel#%d has ccg unreleased!\n", -+ channel->idx); -+ return -EBUSY; -+ } -+ -+ /* channel->dcp_idx corresponds to known fman validation */ -+ if ((channel->dcp_idx != qm_dc_portal_fman0) && -+ (channel->dcp_idx != qm_dc_portal_fman1)) { -+ pr_err("dcp_idx %u does not correspond to a known fman in this driver\n", -+ channel->dcp_idx); -+ return -EINVAL; -+ } -+ -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER | -+ channel->idx); -+ config_opts.dcpid = channel->dcp_idx; -+ memset(&config_opts.shaper_config, 0, -+ sizeof(config_opts.shaper_config)); -+ if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) { -+ pr_err("Can't reset channel shapping parameters\n"); -+ return -EINVAL; -+ } -+ -+ if (channel->dcp_idx == qm_dc_portal_fman0) { -+ qman_release_ceetm0_channelid(channel->idx); -+ } else if (channel->dcp_idx == qm_dc_portal_fman1) { -+ qman_release_ceetm1_channelid(channel->idx); -+ } else { -+ pr_err("dcp_idx %u does not correspond to a known fman in this driver\n", -+ channel->dcp_idx); -+ return -EINVAL; -+ } -+ list_del(&channel->node); -+ kfree(channel); -+ -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_release); -+ -+int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel, -+ int coupled) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ -+ if (channel->shaper_enable == 1) { -+ pr_err("This channel shaper has been enabled!\n"); -+ return -EINVAL; -+ } -+ -+ channel->shaper_enable = 1; -+ channel->shaper_couple = coupled; -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING | -+ channel->idx); -+ query_opts.dcpid = channel->dcp_idx; -+ -+ if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) { -+ pr_err("Can't query channel mapping\n"); -+ return -EINVAL; -+ } -+ -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING | -+ channel->idx); -+ config_opts.dcpid = channel->dcp_idx; -+ config_opts.channel_mapping.map_lni_id = -+ query_result.channel_mapping_query.map_lni_id; -+ config_opts.channel_mapping.map_shaped = 1; -+ if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) { -+ pr_err("Can't enable shaper for channel #%d\n", channel->idx); -+ return -EINVAL; -+ } -+ -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER | -+ channel->idx); -+ config_opts.shaper_config.cpl = coupled; -+ config_opts.shaper_config.crtcr = -+ cpu_to_be24((channel->cr_token_rate.whole -+ << 13) | -+ channel->cr_token_rate.fraction); -+ config_opts.shaper_config.ertcr = -+ cpu_to_be24(channel->er_token_rate.whole -+ << 13 | -+ channel->er_token_rate.fraction); -+ config_opts.shaper_config.crtbl = -+ cpu_to_be16(channel->cr_token_bucket_limit); -+ config_opts.shaper_config.ertbl = -+ cpu_to_be16(channel->er_token_bucket_limit); -+ -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_channel_enable_shaper); -+ -+int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING | -+ channel->idx); -+ query_opts.dcpid = channel->dcp_idx; -+ -+ if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) { -+ pr_err("Can't query channel mapping\n"); -+ return -EINVAL; -+ } -+ -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING | -+ channel->idx); -+ config_opts.dcpid = channel->dcp_idx; -+ config_opts.channel_mapping.map_shaped = 0; -+ config_opts.channel_mapping.map_lni_id = -+ query_result.channel_mapping_query.map_lni_id; -+ -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_channel_disable_shaper); -+ -+int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING | -+ channel->idx); -+ query_opts.dcpid = channel->dcp_idx; -+ -+ if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) { -+ pr_err("Can't query channel mapping\n"); -+ return -EINVAL; -+ } -+ -+ return query_result.channel_mapping_query.map_shaped; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_is_shaper_enabled); -+ -+int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel, -+ const struct qm_ceetm_rate *token_rate, -+ u16 token_limit) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ int ret; -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER | -+ channel->idx); -+ query_opts.dcpid = channel->dcp_idx; -+ -+ ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result); -+ if (ret) { -+ pr_err("Fail to get the current channel shaper setting\n"); -+ return -EINVAL; -+ } -+ -+ channel->cr_token_rate.whole = token_rate->whole; -+ channel->cr_token_rate.fraction = token_rate->fraction; -+ channel->cr_token_bucket_limit = token_limit; -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER | -+ channel->idx); -+ config_opts.dcpid = channel->dcp_idx; -+ config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole -+ << 13) | (token_rate->fraction)); -+ config_opts.shaper_config.crtbl = cpu_to_be16(token_limit); -+ config_opts.shaper_config.cpl = query_result.shaper_query.cpl; -+ config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr; -+ config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl; -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate); -+ -+int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel, -+ u64 bps, u16 token_limit) -+{ -+ struct qm_ceetm_rate token_rate; -+ int ret; -+ -+ ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0); -+ if (ret) { -+ pr_err("Can not convert bps to token rate\n"); -+ return -EINVAL; -+ } -+ return qman_ceetm_channel_set_commit_rate(channel, &token_rate, -+ token_limit); -+} -+EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate_bps); -+ -+int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel, -+ struct qm_ceetm_rate *token_rate, -+ u16 *token_limit) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ int ret; -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER | -+ channel->idx); -+ query_opts.dcpid = channel->dcp_idx; -+ -+ ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result); -+ if (ret | !query_result.shaper_query.crtcr | -+ !query_result.shaper_query.crtbl) { -+ pr_err("The channel commit rate or limit is not set\n"); -+ return -EINVAL; -+ } -+ token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13; -+ token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) & -+ 0x1FFF; -+ *token_limit = be16_to_cpu(query_result.shaper_query.crtbl); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate); -+ -+int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel, -+ u64 *bps, u16 *token_limit) -+{ -+ struct qm_ceetm_rate token_rate; -+ int ret; -+ -+ ret = qman_ceetm_channel_get_commit_rate(channel, &token_rate, -+ token_limit); -+ if (ret) { -+ pr_err("The channel CR rate or limit is not available\n"); -+ return -EINVAL; -+ } -+ -+ return qman_ceetm_tokenrate2bps(&token_rate, bps, 0); -+} -+EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate_bps); -+ -+int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel, -+ const struct qm_ceetm_rate *token_rate, -+ u16 token_limit) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ int ret; -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER | -+ channel->idx); -+ query_opts.dcpid = channel->dcp_idx; -+ ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result); -+ if (ret) { -+ pr_err("Fail to get the current channel shaper setting\n"); -+ return -EINVAL; -+ } -+ -+ channel->er_token_rate.whole = token_rate->whole; -+ channel->er_token_rate.fraction = token_rate->fraction; -+ channel->er_token_bucket_limit = token_limit; -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER | -+ channel->idx); -+ config_opts.dcpid = channel->dcp_idx; -+ config_opts.shaper_config.ertcr = cpu_to_be24( -+ (token_rate->whole << 13) | (token_rate->fraction)); -+ config_opts.shaper_config.ertbl = cpu_to_be16(token_limit); -+ config_opts.shaper_config.cpl = query_result.shaper_query.cpl; -+ config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr; -+ config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl; -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate); -+ -+int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel, -+ u64 bps, u16 token_limit) -+{ -+ struct qm_ceetm_rate token_rate; -+ int ret; -+ -+ ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0); -+ if (ret) { -+ pr_err("Can not convert bps to token rate\n"); -+ return -EINVAL; -+ } -+ return qman_ceetm_channel_set_excess_rate(channel, &token_rate, -+ token_limit); -+} -+EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate_bps); -+ -+int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel, -+ struct qm_ceetm_rate *token_rate, -+ u16 *token_limit) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ int ret; -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER | -+ channel->idx); -+ query_opts.dcpid = channel->dcp_idx; -+ ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result); -+ if (ret | !query_result.shaper_query.ertcr | -+ !query_result.shaper_query.ertbl) { -+ pr_err("The channel excess rate or limit is not set\n"); -+ return -EINVAL; -+ } -+ token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13; -+ token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) & -+ 0x1FFF; -+ *token_limit = be16_to_cpu(query_result.shaper_query.ertbl); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate); -+ -+int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel, -+ u64 *bps, u16 *token_limit) -+{ -+ struct qm_ceetm_rate token_rate; -+ int ret; -+ -+ ret = qman_ceetm_channel_get_excess_rate(channel, &token_rate, -+ token_limit); -+ if (ret) { -+ pr_err("The channel ER rate or limit is not available\n"); -+ return -EINVAL; -+ } -+ -+ return qman_ceetm_tokenrate2bps(&token_rate, bps, 0); -+} -+EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate_bps); -+ -+int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel, -+ u16 token_limit) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts; -+ -+ if (channel->shaper_enable) { -+ pr_err("This channel is a shaped one\n"); -+ return -EINVAL; -+ } -+ -+ channel->cr_token_bucket_limit = token_limit; -+ config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER | -+ channel->idx); -+ config_opts.dcpid = channel->dcp_idx; -+ config_opts.shaper_config.crtbl = cpu_to_be16(token_limit); -+ return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_channel_set_weight); -+ -+int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel, -+ u16 *token_limit) -+{ -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result; -+ int ret; -+ -+ query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER | -+ channel->idx); -+ query_opts.dcpid = channel->dcp_idx; -+ ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result); -+ if (ret | !query_result.shaper_query.crtbl) { -+ pr_err("This unshaped channel's uFQ wight is unavailable\n"); -+ return -EINVAL; -+ } -+ *token_limit = be16_to_cpu(query_result.shaper_query.crtbl); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_get_weight); -+ -+int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel, int group_b, -+ unsigned int prio_a, unsigned int prio_b) -+{ -+ struct qm_mcc_ceetm_class_scheduler_config config_opts; -+ struct qm_mcr_ceetm_class_scheduler_query query_result; -+ int i; -+ -+ if (prio_a > 7) { -+ pr_err("The priority of group A is out of range\n"); -+ return -EINVAL; -+ } -+ if (group_b && (prio_b > 7)) { -+ pr_err("The priority of group B is out of range\n"); -+ return -EINVAL; -+ } -+ -+ if (qman_ceetm_query_class_scheduler(channel, &query_result)) { -+ pr_err("Can't query channel#%d's scheduler!\n", channel->idx); -+ return -EINVAL; -+ } -+ -+ config_opts.cqcid = cpu_to_be16(channel->idx); -+ config_opts.dcpid = channel->dcp_idx; -+ config_opts.gpc_combine_flag = !group_b; -+ config_opts.gpc_prio_a = prio_a; -+ config_opts.gpc_prio_b = prio_b; -+ -+ for (i = 0; i < 8; i++) -+ config_opts.w[i] = query_result.w[i]; -+ config_opts.crem = query_result.crem; -+ config_opts.erem = query_result.erem; -+ -+ return qman_ceetm_configure_class_scheduler(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_channel_set_group); -+ -+int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, int *group_b, -+ unsigned int *prio_a, unsigned int *prio_b) -+{ -+ struct qm_mcr_ceetm_class_scheduler_query query_result; -+ -+ if (qman_ceetm_query_class_scheduler(channel, &query_result)) { -+ pr_err("Can't query channel#%d's scheduler!\n", channel->idx); -+ return -EINVAL; -+ } -+ *group_b = !query_result.gpc_combine_flag; -+ *prio_a = query_result.gpc_prio_a; -+ *prio_b = query_result.gpc_prio_b; -+ -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_get_group); -+ -+#define GROUP_A_ELIGIBILITY_SET (1 << 8) -+#define GROUP_B_ELIGIBILITY_SET (1 << 9) -+#define CQ_ELIGIBILITY_SET(n) (1 << (7 - n)) -+int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel -+ *channel, int group_b, int cre) -+{ -+ struct qm_mcc_ceetm_class_scheduler_config csch_config; -+ struct qm_mcr_ceetm_class_scheduler_query csch_query; -+ int i; -+ -+ if (qman_ceetm_query_class_scheduler(channel, &csch_query)) { -+ pr_err("Cannot get the channel %d scheduler setting.\n", -+ channel->idx); -+ return -EINVAL; -+ } -+ csch_config.cqcid = cpu_to_be16(channel->idx); -+ csch_config.dcpid = channel->dcp_idx; -+ csch_config.gpc_combine_flag = csch_query.gpc_combine_flag; -+ csch_config.gpc_prio_a = csch_query.gpc_prio_a; -+ csch_config.gpc_prio_b = csch_query.gpc_prio_b; -+ -+ for (i = 0; i < 8; i++) -+ csch_config.w[i] = csch_query.w[i]; -+ csch_config.erem = csch_query.erem; -+ if (group_b) -+ csch_config.crem = (be16_to_cpu(csch_query.crem) -+ & ~GROUP_B_ELIGIBILITY_SET) -+ | (cre ? GROUP_B_ELIGIBILITY_SET : 0); -+ else -+ csch_config.crem = (be16_to_cpu(csch_query.crem) -+ & ~GROUP_A_ELIGIBILITY_SET) -+ | (cre ? GROUP_A_ELIGIBILITY_SET : 0); -+ -+ csch_config.crem = cpu_to_be16(csch_config.crem); -+ -+ if (qman_ceetm_configure_class_scheduler(&csch_config)) { -+ pr_err("Cannot config channel %d's scheduler with " -+ "group_%c's cr eligibility\n", channel->idx, -+ group_b ? 'b' : 'a'); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_set_group_cr_eligibility); -+ -+int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel -+ *channel, int group_b, int ere) -+{ -+ struct qm_mcc_ceetm_class_scheduler_config csch_config; -+ struct qm_mcr_ceetm_class_scheduler_query csch_query; -+ int i; -+ -+ if (qman_ceetm_query_class_scheduler(channel, &csch_query)) { -+ pr_err("Cannot get the channel %d scheduler setting.\n", -+ channel->idx); -+ return -EINVAL; -+ } -+ csch_config.cqcid = cpu_to_be16(channel->idx); -+ csch_config.dcpid = channel->dcp_idx; -+ csch_config.gpc_combine_flag = csch_query.gpc_combine_flag; -+ csch_config.gpc_prio_a = csch_query.gpc_prio_a; -+ csch_config.gpc_prio_b = csch_query.gpc_prio_b; -+ -+ for (i = 0; i < 8; i++) -+ csch_config.w[i] = csch_query.w[i]; -+ csch_config.crem = csch_query.crem; -+ if (group_b) -+ csch_config.erem = (be16_to_cpu(csch_query.erem) -+ & ~GROUP_B_ELIGIBILITY_SET) -+ | (ere ? GROUP_B_ELIGIBILITY_SET : 0); -+ else -+ csch_config.erem = (be16_to_cpu(csch_query.erem) -+ & ~GROUP_A_ELIGIBILITY_SET) -+ | (ere ? GROUP_A_ELIGIBILITY_SET : 0); -+ -+ csch_config.erem = cpu_to_be16(csch_config.erem); -+ -+ if (qman_ceetm_configure_class_scheduler(&csch_config)) { -+ pr_err("Cannot config channel %d's scheduler with " -+ "group_%c's er eligibility\n", channel->idx, -+ group_b ? 'b' : 'a'); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_set_group_er_eligibility); -+ -+int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel, -+ unsigned int idx, int cre) -+{ -+ struct qm_mcc_ceetm_class_scheduler_config csch_config; -+ struct qm_mcr_ceetm_class_scheduler_query csch_query; -+ int i; -+ -+ if (idx > 7) { -+ pr_err("CQ index is out of range\n"); -+ return -EINVAL; -+ } -+ if (qman_ceetm_query_class_scheduler(channel, &csch_query)) { -+ pr_err("Cannot get the channel %d scheduler setting.\n", -+ channel->idx); -+ return -EINVAL; -+ } -+ csch_config.cqcid = cpu_to_be16(channel->idx); -+ csch_config.dcpid = channel->dcp_idx; -+ csch_config.gpc_combine_flag = csch_query.gpc_combine_flag; -+ csch_config.gpc_prio_a = csch_query.gpc_prio_a; -+ csch_config.gpc_prio_b = csch_query.gpc_prio_b; -+ for (i = 0; i < 8; i++) -+ csch_config.w[i] = csch_query.w[i]; -+ csch_config.erem = csch_query.erem; -+ csch_config.crem = (be16_to_cpu(csch_query.crem) -+ & ~CQ_ELIGIBILITY_SET(idx)) | -+ (cre ? CQ_ELIGIBILITY_SET(idx) : 0); -+ csch_config.crem = cpu_to_be16(csch_config.crem); -+ if (qman_ceetm_configure_class_scheduler(&csch_config)) { -+ pr_err("Cannot config channel scheduler to set " -+ "cr eligibility mask for CQ#%d\n", idx); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_set_cq_cr_eligibility); -+ -+int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel, -+ unsigned int idx, int ere) -+{ -+ struct qm_mcc_ceetm_class_scheduler_config csch_config; -+ struct qm_mcr_ceetm_class_scheduler_query csch_query; -+ int i; -+ -+ if (idx > 7) { -+ pr_err("CQ index is out of range\n"); -+ return -EINVAL; -+ } -+ if (qman_ceetm_query_class_scheduler(channel, &csch_query)) { -+ pr_err("Cannot get the channel %d scheduler setting.\n", -+ channel->idx); -+ return -EINVAL; -+ } -+ csch_config.cqcid = cpu_to_be16(channel->idx); -+ csch_config.dcpid = channel->dcp_idx; -+ csch_config.gpc_combine_flag = csch_query.gpc_combine_flag; -+ csch_config.gpc_prio_a = csch_query.gpc_prio_a; -+ csch_config.gpc_prio_b = csch_query.gpc_prio_b; -+ for (i = 0; i < 8; i++) -+ csch_config.w[i] = csch_query.w[i]; -+ csch_config.crem = csch_query.crem; -+ csch_config.erem = (be16_to_cpu(csch_query.erem) -+ & ~CQ_ELIGIBILITY_SET(idx)) | -+ (ere ? CQ_ELIGIBILITY_SET(idx) : 0); -+ csch_config.erem = cpu_to_be16(csch_config.erem); -+ if (qman_ceetm_configure_class_scheduler(&csch_config)) { -+ pr_err("Cannot config channel scheduler to set " -+ "er eligibility mask for CQ#%d\n", idx); -+ return -EINVAL; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_channel_set_cq_er_eligibility); -+ -+int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq, -+ struct qm_ceetm_channel *channel, unsigned int idx, -+ struct qm_ceetm_ccg *ccg) -+{ -+ struct qm_ceetm_cq *p; -+ struct qm_mcc_ceetm_cq_config cq_config; -+ -+ if (idx > 7) { -+ pr_err("The independent class queue id is out of range\n"); -+ return -EINVAL; -+ } -+ -+ list_for_each_entry(p, &channel->class_queues, node) { -+ if (p->idx == idx) { -+ pr_err("The CQ#%d has been claimed!\n", idx); -+ return -EINVAL; -+ } -+ } -+ -+ p = kmalloc(sizeof(*p), GFP_KERNEL); -+ if (!p) { -+ pr_err("Can't allocate memory for CQ#%d!\n", idx); -+ return -ENOMEM; -+ } -+ -+ list_add_tail(&p->node, &channel->class_queues); -+ p->idx = idx; -+ p->is_claimed = 1; -+ p->parent = channel; -+ INIT_LIST_HEAD(&p->bound_lfqids); -+ -+ if (ccg) { -+ cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx); -+ cq_config.dcpid = channel->dcp_idx; -+ cq_config.ccgid = cpu_to_be16(ccg->idx); -+ if (qman_ceetm_configure_cq(&cq_config)) { -+ pr_err("Can't configure the CQ#%d with CCGRID#%d\n", -+ idx, ccg->idx); -+ list_del(&p->node); -+ kfree(p); -+ return -EINVAL; -+ } -+ } -+ -+ *cq = p; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_cq_claim); -+ -+int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq, -+ struct qm_ceetm_channel *channel, unsigned int idx, -+ struct qm_ceetm_ccg *ccg) -+{ -+ struct qm_ceetm_cq *p; -+ struct qm_mcc_ceetm_cq_config cq_config; -+ -+ if ((idx < 8) || (idx > 15)) { -+ pr_err("This grouped class queue id is out of range\n"); -+ return -EINVAL; -+ } -+ -+ list_for_each_entry(p, &channel->class_queues, node) { -+ if (p->idx == idx) { -+ pr_err("The CQ#%d has been claimed!\n", idx); -+ return -EINVAL; -+ } -+ } -+ -+ p = kmalloc(sizeof(*p), GFP_KERNEL); -+ if (!p) { -+ pr_err("Can't allocate memory for CQ#%d!\n", idx); -+ return -ENOMEM; -+ } -+ -+ list_add_tail(&p->node, &channel->class_queues); -+ p->idx = idx; -+ p->is_claimed = 1; -+ p->parent = channel; -+ INIT_LIST_HEAD(&p->bound_lfqids); -+ -+ if (ccg) { -+ cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx); -+ cq_config.dcpid = channel->dcp_idx; -+ cq_config.ccgid = cpu_to_be16(ccg->idx); -+ if (qman_ceetm_configure_cq(&cq_config)) { -+ pr_err("Can't configure the CQ#%d with CCGRID#%d\n", -+ idx, ccg->idx); -+ list_del(&p->node); -+ kfree(p); -+ return -EINVAL; -+ } -+ } -+ *cq = p; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_cq_claim_A); -+ -+int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq, -+ struct qm_ceetm_channel *channel, unsigned int idx, -+ struct qm_ceetm_ccg *ccg) -+{ -+ struct qm_ceetm_cq *p; -+ struct qm_mcc_ceetm_cq_config cq_config; -+ -+ if ((idx < 12) || (idx > 15)) { -+ pr_err("This grouped class queue id is out of range\n"); -+ return -EINVAL; -+ } -+ -+ list_for_each_entry(p, &channel->class_queues, node) { -+ if (p->idx == idx) { -+ pr_err("The CQ#%d has been claimed!\n", idx); -+ return -EINVAL; -+ } -+ } -+ -+ p = kmalloc(sizeof(*p), GFP_KERNEL); -+ if (!p) { -+ pr_err("Can't allocate memory for CQ#%d!\n", idx); -+ return -ENOMEM; -+ } -+ -+ list_add_tail(&p->node, &channel->class_queues); -+ p->idx = idx; -+ p->is_claimed = 1; -+ p->parent = channel; -+ INIT_LIST_HEAD(&p->bound_lfqids); -+ -+ if (ccg) { -+ cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx); -+ cq_config.dcpid = channel->dcp_idx; -+ cq_config.ccgid = cpu_to_be16(ccg->idx); -+ if (qman_ceetm_configure_cq(&cq_config)) { -+ pr_err("Can't configure the CQ#%d with CCGRID#%d\n", -+ idx, ccg->idx); -+ list_del(&p->node); -+ kfree(p); -+ return -EINVAL; -+ } -+ } -+ *cq = p; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_cq_claim_B); -+ -+int qman_ceetm_cq_release(struct qm_ceetm_cq *cq) -+{ -+ if (!list_empty(&cq->bound_lfqids)) { -+ pr_err("The CQ#%d has unreleased LFQID\n", cq->idx); -+ return -EBUSY; -+ } -+ list_del(&cq->node); -+ qman_ceetm_drain_cq(cq); -+ kfree(cq); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_cq_release); -+ -+int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq, -+ struct qm_ceetm_weight_code *weight_code) -+{ -+ struct qm_mcc_ceetm_class_scheduler_config config_opts; -+ struct qm_mcr_ceetm_class_scheduler_query query_result; -+ int i; -+ -+ if (cq->idx < 8) { -+ pr_err("Can not set weight for ungrouped class queue\n"); -+ return -EINVAL; -+ } -+ -+ if (qman_ceetm_query_class_scheduler(cq->parent, &query_result)) { -+ pr_err("Can't query channel#%d's scheduler!\n", -+ cq->parent->idx); -+ return -EINVAL; -+ } -+ -+ config_opts.cqcid = cpu_to_be16(cq->parent->idx); -+ config_opts.dcpid = cq->parent->dcp_idx; -+ config_opts.crem = query_result.crem; -+ config_opts.erem = query_result.erem; -+ config_opts.gpc_combine_flag = query_result.gpc_combine_flag; -+ config_opts.gpc_prio_a = query_result.gpc_prio_a; -+ config_opts.gpc_prio_b = query_result.gpc_prio_b; -+ -+ for (i = 0; i < 8; i++) -+ config_opts.w[i] = query_result.w[i]; -+ config_opts.w[cq->idx - 8] = ((weight_code->y << 3) | -+ (weight_code->x & 0x7)); -+ return qman_ceetm_configure_class_scheduler(&config_opts); -+} -+EXPORT_SYMBOL(qman_ceetm_set_queue_weight); -+ -+int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq, -+ struct qm_ceetm_weight_code *weight_code) -+{ -+ struct qm_mcr_ceetm_class_scheduler_query query_result; -+ -+ if (cq->idx < 8) { -+ pr_err("Can not get weight for ungrouped class queue\n"); -+ return -EINVAL; -+ } -+ -+ if (qman_ceetm_query_class_scheduler(cq->parent, -+ &query_result)) { -+ pr_err("Can't get the weight code for CQ#%d!\n", cq->idx); -+ return -EINVAL; -+ } -+ weight_code->y = query_result.w[cq->idx - 8] >> 3; -+ weight_code->x = query_result.w[cq->idx - 8] & 0x7; -+ -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_get_queue_weight); -+ -+/* The WBFS code is represent as {x,y}, the effect wieght can be calculated as: -+ * effective weight = 2^x / (1 - (y/64)) -+ * = 2^(x+6) / (64 - y) -+ */ -+static void reduce_fraction(u32 *n, u32 *d) -+{ -+ u32 factor = 2; -+ u32 lesser = (*n < *d) ? *n : *d; -+ /* If factor exceeds the square-root of the lesser of *n and *d, -+ * then there's no point continuing. Proof: if there was a factor -+ * bigger than the square root, that would imply there exists -+ * another factor smaller than the square-root with which it -+ * multiplies to give 'lesser' - but that's a contradiction -+ * because the other factor would have already been found and -+ * divided out. -+ */ -+ while ((factor * factor) <= lesser) { -+ /* If 'factor' is a factor of *n and *d, divide them both -+ * by 'factor' as many times as possible. -+ */ -+ while (!(*n % factor) && !(*d % factor)) { -+ *n /= factor; -+ *d /= factor; -+ lesser /= factor; -+ } -+ if (factor == 2) -+ factor = 3; -+ else -+ factor += 2; -+ } -+} -+ -+int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code, -+ u32 *numerator, -+ u32 *denominator) -+{ -+ *numerator = (u32) 1 << (weight_code->x + 6); -+ *denominator = 64 - weight_code->y; -+ reduce_fraction(numerator, denominator); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_wbfs2ratio); -+ -+/* For a given x, the weight is between 2^x (inclusive) and 2^(x+1) (exclusive). -+ * So find 'x' by range, and then estimate 'y' using: -+ * 64 - y = 2^(x + 6) / weight -+ * = 2^(x + 6) / (n/d) -+ * = d * 2^(x+6) / n -+ * y = 64 - (d * 2^(x+6) / n) -+ */ -+int qman_ceetm_ratio2wbfs(u32 numerator, -+ u32 denominator, -+ struct qm_ceetm_weight_code *weight_code, -+ int rounding) -+{ -+ unsigned int y, x = 0; -+ /* search incrementing 'x' until: -+ * weight < 2^(x+1) -+ * n/d < 2^(x+1) -+ * n < d * 2^(x+1) -+ */ -+ while ((x < 8) && (numerator >= (denominator << (x + 1)))) -+ x++; -+ if (x >= 8) -+ return -ERANGE; -+ /* because of the subtraction, use '-rounding' */ -+ y = 64 - ROUNDING(denominator << (x + 6), numerator, -rounding); -+ if (y >= 32) -+ return -ERANGE; -+ weight_code->x = x; -+ weight_code->y = y; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_ratio2wbfs); -+ -+int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio) -+{ -+ struct qm_ceetm_weight_code weight_code; -+ -+ if (qman_ceetm_ratio2wbfs(ratio, 100, &weight_code, 0)) { -+ pr_err("Cannot get wbfs code for cq %x\n", cq->idx); -+ return -EINVAL; -+ } -+ return qman_ceetm_set_queue_weight(cq, &weight_code); -+} -+EXPORT_SYMBOL(qman_ceetm_set_queue_weight_in_ratio); -+ -+int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio) -+{ -+ struct qm_ceetm_weight_code weight_code; -+ u32 n, d; -+ -+ if (qman_ceetm_get_queue_weight(cq, &weight_code)) { -+ pr_err("Cannot query the weight code for cq%x\n", cq->idx); -+ return -EINVAL; -+ } -+ -+ if (qman_ceetm_wbfs2ratio(&weight_code, &n, &d)) { -+ pr_err("Cannot get the ratio with wbfs code\n"); -+ return -EINVAL; -+ } -+ -+ *ratio = (n * 100) / d; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_get_queue_weight_in_ratio); -+ -+int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags, -+ u64 *frame_count, u64 *byte_count) -+{ -+ struct qm_mcr_ceetm_statistics_query result; -+ u16 cid, command_type; -+ enum qm_dc_portal dcp_idx; -+ int ret; -+ -+ cid = cpu_to_be16((cq->parent->idx << 4) | cq->idx); -+ dcp_idx = cq->parent->dcp_idx; -+ if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER) -+ command_type = CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS; -+ else -+ command_type = CEETM_QUERY_DEQUEUE_STATISTICS; -+ -+ ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result); -+ if (ret) { -+ pr_err("Can't query the statistics of CQ#%d!\n", cq->idx); -+ return -EINVAL; -+ } -+ -+ *frame_count = be40_to_cpu(result.frm_cnt); -+ *byte_count = be48_to_cpu(result.byte_cnt); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_cq_get_dequeue_statistics); -+ -+int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq) -+{ -+ struct qm_mcr_ceetm_cq_peek_pop_xsfdrread ppxr; -+ int ret; -+ -+ do { -+ ret = qman_ceetm_cq_peek_pop_xsfdrread(cq, 1, 0, &ppxr); -+ if (ret) { -+ pr_err("Failed to pop frame from CQ\n"); -+ return -EINVAL; -+ } -+ } while (!(ppxr.stat & 0x2)); -+ -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_drain_cq); -+ -+#define CEETM_LFQMT_LFQID_MSB 0xF00000 -+#define CEETM_LFQMT_LFQID_LSB 0x000FFF -+int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq, -+ struct qm_ceetm_cq *cq) -+{ -+ struct qm_ceetm_lfq *p; -+ u32 lfqid; -+ int ret = 0; -+ struct qm_mcc_ceetm_lfqmt_config lfqmt_config; -+ -+ if (cq->parent->dcp_idx == qm_dc_portal_fman0) { -+ ret = qman_alloc_ceetm0_lfqid(&lfqid); -+ } else if (cq->parent->dcp_idx == qm_dc_portal_fman1) { -+ ret = qman_alloc_ceetm1_lfqid(&lfqid); -+ } else { -+ pr_err("dcp_idx %u does not correspond to a known fman in this driver\n", -+ cq->parent->dcp_idx); -+ return -EINVAL; -+ } -+ -+ if (ret) { -+ pr_err("There is no lfqid avalaible for CQ#%d!\n", cq->idx); -+ return -ENODEV; -+ } -+ p = kmalloc(sizeof(*p), GFP_KERNEL); -+ if (!p) -+ return -ENOMEM; -+ p->idx = lfqid; -+ p->dctidx = (u16)(lfqid & CEETM_LFQMT_LFQID_LSB); -+ p->parent = cq->parent; -+ list_add_tail(&p->node, &cq->bound_lfqids); -+ -+ lfqmt_config.lfqid = cpu_to_be24(CEETM_LFQMT_LFQID_MSB | -+ (cq->parent->dcp_idx << 16) | -+ (lfqid & CEETM_LFQMT_LFQID_LSB)); -+ lfqmt_config.cqid = cpu_to_be16((cq->parent->idx << 4) | (cq->idx)); -+ lfqmt_config.dctidx = cpu_to_be16(p->dctidx); -+ if (qman_ceetm_configure_lfqmt(&lfqmt_config)) { -+ pr_err("Can't configure LFQMT for LFQID#%d @ CQ#%d\n", -+ lfqid, cq->idx); -+ list_del(&p->node); -+ kfree(p); -+ return -EINVAL; -+ } -+ *lfq = p; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_lfq_claim); -+ -+int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq) -+{ -+ if (lfq->parent->dcp_idx == qm_dc_portal_fman0) { -+ qman_release_ceetm0_lfqid(lfq->idx); -+ } else if (lfq->parent->dcp_idx == qm_dc_portal_fman1) { -+ qman_release_ceetm1_lfqid(lfq->idx); -+ } else { -+ pr_err("dcp_idx %u does not correspond to a known fman in this driver\n", -+ lfq->parent->dcp_idx); -+ return -EINVAL; -+ } -+ list_del(&lfq->node); -+ kfree(lfq); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_lfq_release); -+ -+int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq, u64 context_a, -+ u32 context_b) -+{ -+ struct qm_mcc_ceetm_dct_config dct_config; -+ lfq->context_a = context_a; -+ lfq->context_b = context_b; -+ dct_config.dctidx = cpu_to_be16((u16)lfq->dctidx); -+ dct_config.dcpid = lfq->parent->dcp_idx; -+ dct_config.context_b = cpu_to_be32(context_b); -+ dct_config.context_a = cpu_to_be64(context_a); -+ -+ return qman_ceetm_configure_dct(&dct_config); -+} -+EXPORT_SYMBOL(qman_ceetm_lfq_set_context); -+ -+int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq, u64 *context_a, -+ u32 *context_b) -+{ -+ struct qm_mcc_ceetm_dct_query dct_query; -+ struct qm_mcr_ceetm_dct_query query_result; -+ -+ dct_query.dctidx = cpu_to_be16(lfq->dctidx); -+ dct_query.dcpid = lfq->parent->dcp_idx; -+ if (qman_ceetm_query_dct(&dct_query, &query_result)) { -+ pr_err("Can't query LFQID#%d's context!\n", lfq->idx); -+ return -EINVAL; -+ } -+ *context_a = be64_to_cpu(query_result.context_a); -+ *context_b = be32_to_cpu(query_result.context_b); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_lfq_get_context); -+ -+int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq) -+{ -+ spin_lock_init(&fq->fqlock); -+ fq->fqid = lfq->idx; -+ fq->flags = QMAN_FQ_FLAG_NO_MODIFY; -+ if (lfq->ern) -+ fq->cb.ern = lfq->ern; -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ if (unlikely(find_empty_fq_table_entry(&fq->key, fq))) -+ return -ENOMEM; -+#endif -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_create_fq); -+ -+#define MAX_CCG_IDX 0x000F -+int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg, -+ struct qm_ceetm_channel *channel, -+ unsigned int idx, -+ void (*cscn)(struct qm_ceetm_ccg *, -+ void *cb_ctx, -+ int congested), -+ void *cb_ctx) -+{ -+ struct qm_ceetm_ccg *p; -+ -+ if (idx > MAX_CCG_IDX) { -+ pr_err("The given ccg index is out of range\n"); -+ return -EINVAL; -+ } -+ -+ list_for_each_entry(p, &channel->ccgs, node) { -+ if (p->idx == idx) { -+ pr_err("The CCG#%d has been claimed\n", idx); -+ return -EINVAL; -+ } -+ } -+ -+ p = kmalloc(sizeof(*p), GFP_KERNEL); -+ if (!p) { -+ pr_err("Can't allocate memory for CCG#%d!\n", idx); -+ return -ENOMEM; -+ } -+ -+ list_add_tail(&p->node, &channel->ccgs); -+ -+ p->idx = idx; -+ p->parent = channel; -+ p->cb = cscn; -+ p->cb_ctx = cb_ctx; -+ INIT_LIST_HEAD(&p->cb_node); -+ -+ *ccg = p; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_ccg_claim); -+ -+int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg) -+{ -+ unsigned long irqflags __maybe_unused; -+ struct qm_mcc_ceetm_ccgr_config config_opts; -+ int ret = 0; -+ struct qman_portal *p = get_affine_portal(); -+ -+ memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config)); -+ spin_lock_irqsave(&p->ccgr_lock, irqflags); -+ if (!list_empty(&ccg->cb_node)) -+ list_del(&ccg->cb_node); -+ config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE | -+ (ccg->parent->idx << 4) | ccg->idx); -+ config_opts.dcpid = ccg->parent->dcp_idx; -+ config_opts.we_mask = cpu_to_be16(QM_CCGR_WE_CSCN_TUPD); -+ config_opts.cm_config.cscn_tupd = cpu_to_be16(PORTAL_IDX(p)); -+ ret = qman_ceetm_configure_ccgr(&config_opts); -+ spin_unlock_irqrestore(&p->ccgr_lock, irqflags); -+ put_affine_portal(); -+ -+ list_del(&ccg->node); -+ kfree(ccg); -+ return ret; -+} -+EXPORT_SYMBOL(qman_ceetm_ccg_release); -+ -+int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg, u16 we_mask, -+ const struct qm_ceetm_ccg_params *params) -+{ -+ struct qm_mcc_ceetm_ccgr_config config_opts; -+ unsigned long irqflags __maybe_unused; -+ int ret; -+ struct qman_portal *p; -+ -+ if (((ccg->parent->idx << 4) | ccg->idx) >= (2 * __CGR_NUM)) -+ return -EINVAL; -+ -+ p = get_affine_portal(); -+ -+ memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config)); -+ spin_lock_irqsave(&p->ccgr_lock, irqflags); -+ -+ config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE | -+ (ccg->parent->idx << 4) | ccg->idx); -+ config_opts.dcpid = ccg->parent->dcp_idx; -+ config_opts.we_mask = we_mask; -+ if (we_mask & QM_CCGR_WE_CSCN_EN) { -+ config_opts.we_mask |= QM_CCGR_WE_CSCN_TUPD; -+ config_opts.cm_config.cscn_tupd = cpu_to_be16( -+ QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p)); -+ } -+ config_opts.we_mask = cpu_to_be16(config_opts.we_mask); -+ config_opts.cm_config.ctl_wr_en_g = params->wr_en_g; -+ config_opts.cm_config.ctl_wr_en_y = params->wr_en_y; -+ config_opts.cm_config.ctl_wr_en_r = params->wr_en_r; -+ config_opts.cm_config.ctl_td_en = params->td_en; -+ config_opts.cm_config.ctl_td_mode = params->td_mode; -+ config_opts.cm_config.ctl_cscn_en = params->cscn_en; -+ config_opts.cm_config.ctl_mode = params->mode; -+ config_opts.cm_config.oal = params->oal; -+ config_opts.cm_config.cs_thres.hword = -+ cpu_to_be16(params->cs_thres_in.hword); -+ config_opts.cm_config.cs_thres_x.hword = -+ cpu_to_be16(params->cs_thres_out.hword); -+ config_opts.cm_config.td_thres.hword = -+ cpu_to_be16(params->td_thres.hword); -+ config_opts.cm_config.wr_parm_g.word = -+ cpu_to_be32(params->wr_parm_g.word); -+ config_opts.cm_config.wr_parm_y.word = -+ cpu_to_be32(params->wr_parm_y.word); -+ config_opts.cm_config.wr_parm_r.word = -+ cpu_to_be32(params->wr_parm_r.word); -+ ret = qman_ceetm_configure_ccgr(&config_opts); -+ if (ret) { -+ pr_err("Configure CCGR CM failed!\n"); -+ goto release_lock; -+ } -+ -+ if (we_mask & QM_CCGR_WE_CSCN_EN) -+ if (list_empty(&ccg->cb_node)) -+ list_add(&ccg->cb_node, -+ &p->ccgr_cbs[ccg->parent->dcp_idx]); -+release_lock: -+ spin_unlock_irqrestore(&p->ccgr_lock, irqflags); -+ put_affine_portal(); -+ return ret; -+} -+EXPORT_SYMBOL(qman_ceetm_ccg_set); -+ -+#define CEETM_CCGR_CTL_MASK 0x01 -+int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg, -+ struct qm_ceetm_ccg_params *params) -+{ -+ struct qm_mcc_ceetm_ccgr_query query_opts; -+ struct qm_mcr_ceetm_ccgr_query query_result; -+ -+ query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY | -+ (ccg->parent->idx << 4) | ccg->idx); -+ query_opts.dcpid = ccg->parent->dcp_idx; -+ -+ if (qman_ceetm_query_ccgr(&query_opts, &query_result)) { -+ pr_err("Can't query CCGR#%d\n", ccg->idx); -+ return -EINVAL; -+ } -+ -+ params->wr_parm_r.word = query_result.cm_query.wr_parm_r.word; -+ params->wr_parm_y.word = query_result.cm_query.wr_parm_y.word; -+ params->wr_parm_g.word = query_result.cm_query.wr_parm_g.word; -+ params->td_thres.hword = query_result.cm_query.td_thres.hword; -+ params->cs_thres_out.hword = query_result.cm_query.cs_thres_x.hword; -+ params->cs_thres_in.hword = query_result.cm_query.cs_thres.hword; -+ params->oal = query_result.cm_query.oal; -+ params->wr_en_g = query_result.cm_query.ctl_wr_en_g; -+ params->wr_en_y = query_result.cm_query.ctl_wr_en_y; -+ params->wr_en_r = query_result.cm_query.ctl_wr_en_r; -+ params->td_en = query_result.cm_query.ctl_td_en; -+ params->td_mode = query_result.cm_query.ctl_td_mode; -+ params->cscn_en = query_result.cm_query.ctl_cscn_en; -+ params->mode = query_result.cm_query.ctl_mode; -+ -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_ccg_get); -+ -+int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags, -+ u64 *frame_count, u64 *byte_count) -+{ -+ struct qm_mcr_ceetm_statistics_query result; -+ u16 cid, command_type; -+ enum qm_dc_portal dcp_idx; -+ int ret; -+ -+ cid = cpu_to_be16((ccg->parent->idx << 4) | ccg->idx); -+ dcp_idx = ccg->parent->dcp_idx; -+ if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER) -+ command_type = CEETM_QUERY_REJECT_CLEAR_STATISTICS; -+ else -+ command_type = CEETM_QUERY_REJECT_STATISTICS; -+ -+ ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result); -+ if (ret) { -+ pr_err("Can't query the statistics of CCG#%d!\n", ccg->idx); -+ return -EINVAL; -+ } -+ -+ *frame_count = be40_to_cpu(result.frm_cnt); -+ *byte_count = be48_to_cpu(result.byte_cnt); -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_ccg_get_reject_statistics); -+ -+int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg, -+ u16 swp_idx, -+ unsigned int *cscn_enabled) -+{ -+ struct qm_mcc_ceetm_ccgr_query query_opts; -+ struct qm_mcr_ceetm_ccgr_query query_result; -+ int i; -+ -+ DPA_ASSERT(swp_idx < 127); -+ query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY | -+ (ccg->parent->idx << 4) | ccg->idx); -+ query_opts.dcpid = ccg->parent->dcp_idx; -+ -+ if (qman_ceetm_query_ccgr(&query_opts, &query_result)) { -+ pr_err("Can't query CCGR#%d\n", ccg->idx); -+ return -EINVAL; -+ } -+ -+ i = swp_idx / 32; -+ i = 3 - i; -+ *cscn_enabled = query_result.cm_query.cscn_targ_swp[i] >> -+ (31 - swp_idx % 32); -+ -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_cscn_swp_get); -+ -+int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg, -+ u16 dcp_idx, -+ u8 vcgid, -+ unsigned int cscn_enabled, -+ u16 we_mask, -+ const struct qm_ceetm_ccg_params *params) -+{ -+ struct qm_mcc_ceetm_ccgr_config config_opts; -+ int ret; -+ -+ config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE | -+ (ccg->parent->idx << 4) | ccg->idx); -+ config_opts.dcpid = ccg->parent->dcp_idx; -+ config_opts.we_mask = cpu_to_be16(we_mask | QM_CCGR_WE_CSCN_TUPD | -+ QM_CCGR_WE_CDV); -+ config_opts.cm_config.cdv = vcgid; -+ config_opts.cm_config.cscn_tupd = cpu_to_be16((cscn_enabled << 15) | -+ QM_CGR_TARG_UDP_CTRL_DCP | dcp_idx); -+ config_opts.cm_config.ctl_wr_en_g = params->wr_en_g; -+ config_opts.cm_config.ctl_wr_en_y = params->wr_en_y; -+ config_opts.cm_config.ctl_wr_en_r = params->wr_en_r; -+ config_opts.cm_config.ctl_td_en = params->td_en; -+ config_opts.cm_config.ctl_td_mode = params->td_mode; -+ config_opts.cm_config.ctl_cscn_en = params->cscn_en; -+ config_opts.cm_config.ctl_mode = params->mode; -+ config_opts.cm_config.cs_thres.hword = -+ cpu_to_be16(params->cs_thres_in.hword); -+ config_opts.cm_config.cs_thres_x.hword = -+ cpu_to_be16(params->cs_thres_out.hword); -+ config_opts.cm_config.td_thres.hword = -+ cpu_to_be16(params->td_thres.hword); -+ config_opts.cm_config.wr_parm_g.word = -+ cpu_to_be32(params->wr_parm_g.word); -+ config_opts.cm_config.wr_parm_y.word = -+ cpu_to_be32(params->wr_parm_y.word); -+ config_opts.cm_config.wr_parm_r.word = -+ cpu_to_be32(params->wr_parm_r.word); -+ -+ ret = qman_ceetm_configure_ccgr(&config_opts); -+ if (ret) { -+ pr_err("Configure CSCN_TARG_DCP failed!\n"); -+ return -EINVAL; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_cscn_dcp_set); -+ -+int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg, -+ u16 dcp_idx, -+ u8 *vcgid, -+ unsigned int *cscn_enabled) -+{ -+ struct qm_mcc_ceetm_ccgr_query query_opts; -+ struct qm_mcr_ceetm_ccgr_query query_result; -+ -+ query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY | -+ (ccg->parent->idx << 4) | ccg->idx); -+ query_opts.dcpid = ccg->parent->dcp_idx; -+ -+ if (qman_ceetm_query_ccgr(&query_opts, &query_result)) { -+ pr_err("Can't query CCGR#%d\n", ccg->idx); -+ return -EINVAL; -+ } -+ -+ *vcgid = query_result.cm_query.cdv; -+ *cscn_enabled = (query_result.cm_query.cscn_targ_dcp >> dcp_idx) & 0x1; -+ return 0; -+} -+EXPORT_SYMBOL(qman_ceetm_cscn_dcp_get); -+ -+int qman_ceetm_querycongestion(struct __qm_mcr_querycongestion *ccg_state, -+ unsigned int dcp_idx) -+{ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ u8 res; -+ int i, j; -+ -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ -+ mcc = qm_mc_start(&p->p); -+ for (i = 0; i < 2; i++) { -+ mcc->ccgr_query.ccgrid = -+ cpu_to_be16(CEETM_QUERY_CONGESTION_STATE | i); -+ mcc->ccgr_query.dcpid = dcp_idx; -+ qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY); -+ -+ while (!(mcr = qm_mc_result(&p->p))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_CEETM_VERB_CCGR_QUERY); -+ res = mcr->result; -+ if (res == QM_MCR_RESULT_OK) { -+ for (j = 0; j < 8; j++) -+ mcr->ccgr_query.congestion_state.state. -+ __state[j] = be32_to_cpu(mcr->ccgr_query. -+ congestion_state.state.__state[j]); -+ *(ccg_state + i) = -+ mcr->ccgr_query.congestion_state.state; -+ } else { -+ pr_err("QUERY CEETM CONGESTION STATE failed\n"); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ return -EIO; -+ } -+ } -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return 0; -+} -+ -+int qman_set_wpm(int wpm_enable) -+{ -+ return qm_set_wpm(wpm_enable); -+} -+EXPORT_SYMBOL(qman_set_wpm); -+ -+int qman_get_wpm(int *wpm_enable) -+{ -+ return qm_get_wpm(wpm_enable); -+} -+EXPORT_SYMBOL(qman_get_wpm); -+ -+int qman_shutdown_fq(u32 fqid) -+{ -+ struct qman_portal *p; -+ unsigned long irqflags __maybe_unused; -+ int ret; -+ struct qm_portal *low_p; -+ p = get_affine_portal(); -+ PORTAL_IRQ_LOCK(p, irqflags); -+ low_p = &p->p; -+ ret = qm_shutdown_fq(&low_p, 1, fqid); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return ret; -+} -+ -+const struct qm_portal_config *qman_get_qm_portal_config( -+ struct qman_portal *portal) -+{ -+ return portal->sharing_redirect ? NULL : portal->config; -+} ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_low.h -@@ -0,0 +1,1427 @@ -+/* Copyright 2008-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "qman_private.h" -+ -+/***************************/ -+/* Portal register assists */ -+/***************************/ -+ -+/* Cache-inhibited register offsets */ -+#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64) -+ -+#define QM_REG_EQCR_PI_CINH 0x0000 -+#define QM_REG_EQCR_CI_CINH 0x0004 -+#define QM_REG_EQCR_ITR 0x0008 -+#define QM_REG_DQRR_PI_CINH 0x0040 -+#define QM_REG_DQRR_CI_CINH 0x0044 -+#define QM_REG_DQRR_ITR 0x0048 -+#define QM_REG_DQRR_DCAP 0x0050 -+#define QM_REG_DQRR_SDQCR 0x0054 -+#define QM_REG_DQRR_VDQCR 0x0058 -+#define QM_REG_DQRR_PDQCR 0x005c -+#define QM_REG_MR_PI_CINH 0x0080 -+#define QM_REG_MR_CI_CINH 0x0084 -+#define QM_REG_MR_ITR 0x0088 -+#define QM_REG_CFG 0x0100 -+#define QM_REG_ISR 0x0e00 -+#define QM_REG_IIR 0x0e0c -+#define QM_REG_ITPR 0x0e14 -+ -+/* Cache-enabled register offsets */ -+#define QM_CL_EQCR 0x0000 -+#define QM_CL_DQRR 0x1000 -+#define QM_CL_MR 0x2000 -+#define QM_CL_EQCR_PI_CENA 0x3000 -+#define QM_CL_EQCR_CI_CENA 0x3100 -+#define QM_CL_DQRR_PI_CENA 0x3200 -+#define QM_CL_DQRR_CI_CENA 0x3300 -+#define QM_CL_MR_PI_CENA 0x3400 -+#define QM_CL_MR_CI_CENA 0x3500 -+#define QM_CL_CR 0x3800 -+#define QM_CL_RR0 0x3900 -+#define QM_CL_RR1 0x3940 -+ -+#endif -+ -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ -+#define QM_REG_EQCR_PI_CINH 0x3000 -+#define QM_REG_EQCR_CI_CINH 0x3040 -+#define QM_REG_EQCR_ITR 0x3080 -+#define QM_REG_DQRR_PI_CINH 0x3100 -+#define QM_REG_DQRR_CI_CINH 0x3140 -+#define QM_REG_DQRR_ITR 0x3180 -+#define QM_REG_DQRR_DCAP 0x31C0 -+#define QM_REG_DQRR_SDQCR 0x3200 -+#define QM_REG_DQRR_VDQCR 0x3240 -+#define QM_REG_DQRR_PDQCR 0x3280 -+#define QM_REG_MR_PI_CINH 0x3300 -+#define QM_REG_MR_CI_CINH 0x3340 -+#define QM_REG_MR_ITR 0x3380 -+#define QM_REG_CFG 0x3500 -+#define QM_REG_ISR 0x3600 -+#define QM_REG_IIR 0x36C0 -+#define QM_REG_ITPR 0x3740 -+ -+/* Cache-enabled register offsets */ -+#define QM_CL_EQCR 0x0000 -+#define QM_CL_DQRR 0x1000 -+#define QM_CL_MR 0x2000 -+#define QM_CL_EQCR_PI_CENA 0x3000 -+#define QM_CL_EQCR_CI_CENA 0x3040 -+#define QM_CL_DQRR_PI_CENA 0x3100 -+#define QM_CL_DQRR_CI_CENA 0x3140 -+#define QM_CL_MR_PI_CENA 0x3300 -+#define QM_CL_MR_CI_CENA 0x3340 -+#define QM_CL_CR 0x3800 -+#define QM_CL_RR0 0x3900 -+#define QM_CL_RR1 0x3940 -+ -+#endif -+ -+ -+/* BTW, the drivers (and h/w programming model) already obtain the required -+ * synchronisation for portal accesses via lwsync(), hwsync(), and -+ * data-dependencies. Use of barrier()s or other order-preserving primitives -+ * simply degrade performance. Hence the use of the __raw_*() interfaces, which -+ * simply ensure that the compiler treats the portal registers as volatile (ie. -+ * non-coherent). */ -+ -+/* Cache-inhibited register access. */ -+#define __qm_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ci + (o))) -+#define __qm_out(qm, o, val) __raw_writel((cpu_to_be32(val)), \ -+ (qm)->addr_ci + (o)); -+#define qm_in(reg) __qm_in(&portal->addr, QM_REG_##reg) -+#define qm_out(reg, val) __qm_out(&portal->addr, QM_REG_##reg, val) -+ -+/* Cache-enabled (index) register access */ -+#define __qm_cl_touch_ro(qm, o) dcbt_ro((qm)->addr_ce + (o)) -+#define __qm_cl_touch_rw(qm, o) dcbt_rw((qm)->addr_ce + (o)) -+#define __qm_cl_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ce + (o))) -+#define __qm_cl_out(qm, o, val) \ -+ do { \ -+ u32 *__tmpclout = (qm)->addr_ce + (o); \ -+ __raw_writel(cpu_to_be32(val), __tmpclout); \ -+ dcbf(__tmpclout); \ -+ } while (0) -+#define __qm_cl_invalidate(qm, o) dcbi((qm)->addr_ce + (o)) -+#define qm_cl_touch_ro(reg) __qm_cl_touch_ro(&portal->addr, QM_CL_##reg##_CENA) -+#define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, QM_CL_##reg##_CENA) -+#define qm_cl_in(reg) __qm_cl_in(&portal->addr, QM_CL_##reg##_CENA) -+#define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, QM_CL_##reg##_CENA, val) -+#define qm_cl_invalidate(reg)\ -+ __qm_cl_invalidate(&portal->addr, QM_CL_##reg##_CENA) -+ -+/* Cache-enabled ring access */ -+#define qm_cl(base, idx) ((void *)base + ((idx) << 6)) -+ -+/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf -+ * analysis, look at using the "extra" bit in the ring index registers to avoid -+ * cyclic issues. */ -+static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last) -+{ -+ /* 'first' is included, 'last' is excluded */ -+ if (first <= last) -+ return last - first; -+ return ringsize + last - first; -+} -+ -+/* Portal modes. -+ * Enum types; -+ * pmode == production mode -+ * cmode == consumption mode, -+ * dmode == h/w dequeue mode. -+ * Enum values use 3 letter codes. First letter matches the portal mode, -+ * remaining two letters indicate; -+ * ci == cache-inhibited portal register -+ * ce == cache-enabled portal register -+ * vb == in-band valid-bit (cache-enabled) -+ * dc == DCA (Discrete Consumption Acknowledgement), DQRR-only -+ * As for "enum qm_dqrr_dmode", it should be self-explanatory. -+ */ -+enum qm_eqcr_pmode { /* matches QCSP_CFG::EPM */ -+ qm_eqcr_pci = 0, /* PI index, cache-inhibited */ -+ qm_eqcr_pce = 1, /* PI index, cache-enabled */ -+ qm_eqcr_pvb = 2 /* valid-bit */ -+}; -+enum qm_dqrr_dmode { /* matches QCSP_CFG::DP */ -+ qm_dqrr_dpush = 0, /* SDQCR + VDQCR */ -+ qm_dqrr_dpull = 1 /* PDQCR */ -+}; -+enum qm_dqrr_pmode { /* s/w-only */ -+ qm_dqrr_pci, /* reads DQRR_PI_CINH */ -+ qm_dqrr_pce, /* reads DQRR_PI_CENA */ -+ qm_dqrr_pvb /* reads valid-bit */ -+}; -+enum qm_dqrr_cmode { /* matches QCSP_CFG::DCM */ -+ qm_dqrr_cci = 0, /* CI index, cache-inhibited */ -+ qm_dqrr_cce = 1, /* CI index, cache-enabled */ -+ qm_dqrr_cdc = 2 /* Discrete Consumption Acknowledgement */ -+}; -+enum qm_mr_pmode { /* s/w-only */ -+ qm_mr_pci, /* reads MR_PI_CINH */ -+ qm_mr_pce, /* reads MR_PI_CENA */ -+ qm_mr_pvb /* reads valid-bit */ -+}; -+enum qm_mr_cmode { /* matches QCSP_CFG::MM */ -+ qm_mr_cci = 0, /* CI index, cache-inhibited */ -+ qm_mr_cce = 1 /* CI index, cache-enabled */ -+}; -+ -+ -+/* ------------------------- */ -+/* --- Portal structures --- */ -+ -+#define QM_EQCR_SIZE 8 -+#define QM_DQRR_SIZE 16 -+#define QM_MR_SIZE 8 -+ -+struct qm_eqcr { -+ struct qm_eqcr_entry *ring, *cursor; -+ u8 ci, available, ithresh, vbit; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ u32 busy; -+ enum qm_eqcr_pmode pmode; -+#endif -+}; -+ -+struct qm_dqrr { -+ const struct qm_dqrr_entry *ring, *cursor; -+ u8 pi, ci, fill, ithresh, vbit; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ enum qm_dqrr_dmode dmode; -+ enum qm_dqrr_pmode pmode; -+ enum qm_dqrr_cmode cmode; -+#endif -+}; -+ -+struct qm_mr { -+ const struct qm_mr_entry *ring, *cursor; -+ u8 pi, ci, fill, ithresh, vbit; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ enum qm_mr_pmode pmode; -+ enum qm_mr_cmode cmode; -+#endif -+}; -+ -+struct qm_mc { -+ struct qm_mc_command *cr; -+ struct qm_mc_result *rr; -+ u8 rridx, vbit; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ enum { -+ /* Can be _mc_start()ed */ -+ qman_mc_idle, -+ /* Can be _mc_commit()ed or _mc_abort()ed */ -+ qman_mc_user, -+ /* Can only be _mc_retry()ed */ -+ qman_mc_hw -+ } state; -+#endif -+}; -+ -+#define QM_PORTAL_ALIGNMENT ____cacheline_aligned -+ -+struct qm_addr { -+ void __iomem *addr_ce; /* cache-enabled */ -+ void __iomem *addr_ci; /* cache-inhibited */ -+}; -+ -+struct qm_portal { -+ /* In the non-CONFIG_FSL_DPA_CHECKING case, the following stuff up to -+ * and including 'mc' fits within a cacheline (yay!). The 'config' part -+ * is setup-only, so isn't a cause for a concern. In other words, don't -+ * rearrange this structure on a whim, there be dragons ... */ -+ struct qm_addr addr; -+ struct qm_eqcr eqcr; -+ struct qm_dqrr dqrr; -+ struct qm_mr mr; -+ struct qm_mc mc; -+} QM_PORTAL_ALIGNMENT; -+ -+ -+/* ---------------- */ -+/* --- EQCR API --- */ -+ -+/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */ -+#define EQCR_CARRYCLEAR(p) \ -+ (void *)((unsigned long)(p) & (~(unsigned long)(QM_EQCR_SIZE << 6))) -+ -+/* Bit-wise logic to convert a ring pointer to a ring index */ -+static inline u8 EQCR_PTR2IDX(struct qm_eqcr_entry *e) -+{ -+ return ((uintptr_t)e >> 6) & (QM_EQCR_SIZE - 1); -+} -+ -+/* Increment the 'cursor' ring pointer, taking 'vbit' into account */ -+static inline void EQCR_INC(struct qm_eqcr *eqcr) -+{ -+ /* NB: this is odd-looking, but experiments show that it generates fast -+ * code with essentially no branching overheads. We increment to the -+ * next EQCR pointer and handle overflow and 'vbit'. */ -+ struct qm_eqcr_entry *partial = eqcr->cursor + 1; -+ eqcr->cursor = EQCR_CARRYCLEAR(partial); -+ if (partial != eqcr->cursor) -+ eqcr->vbit ^= QM_EQCR_VERB_VBIT; -+} -+ -+static inline int qm_eqcr_init(struct qm_portal *portal, -+ enum qm_eqcr_pmode pmode, -+ unsigned int eq_stash_thresh, -+ int eq_stash_prio) -+{ -+ /* This use of 'register', as well as all other occurrences, is because -+ * it has been observed to generate much faster code with gcc than is -+ * otherwise the case. */ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ u32 cfg; -+ u8 pi; -+ -+ eqcr->ring = portal->addr.addr_ce + QM_CL_EQCR; -+ eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1); -+ qm_cl_invalidate(EQCR_CI); -+ pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1); -+ eqcr->cursor = eqcr->ring + pi; -+ eqcr->vbit = (qm_in(EQCR_PI_CINH) & QM_EQCR_SIZE) ? -+ QM_EQCR_VERB_VBIT : 0; -+ eqcr->available = QM_EQCR_SIZE - 1 - -+ qm_cyc_diff(QM_EQCR_SIZE, eqcr->ci, pi); -+ eqcr->ithresh = qm_in(EQCR_ITR); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ eqcr->busy = 0; -+ eqcr->pmode = pmode; -+#endif -+ cfg = (qm_in(CFG) & 0x00ffffff) | -+ (eq_stash_thresh << 28) | /* QCSP_CFG: EST */ -+ (eq_stash_prio << 26) | /* QCSP_CFG: EP */ -+ ((pmode & 0x3) << 24); /* QCSP_CFG::EPM */ -+ qm_out(CFG, cfg); -+ return 0; -+} -+ -+static inline unsigned int qm_eqcr_get_ci_stashing(struct qm_portal *portal) -+{ -+ return (qm_in(CFG) >> 28) & 0x7; -+} -+ -+static inline void qm_eqcr_finish(struct qm_portal *portal) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ u8 pi, ci; -+ u32 cfg; -+ -+ /* -+ * Disable EQCI stashing because the QMan only -+ * presents the value it previously stashed to -+ * maintain coherency. Setting the stash threshold -+ * to 1 then 0 ensures that QMan has resyncronized -+ * its internal copy so that the portal is clean -+ * when it is reinitialized in the future -+ */ -+ cfg = (qm_in(CFG) & 0x0fffffff) | -+ (1 << 28); /* QCSP_CFG: EST */ -+ qm_out(CFG, cfg); -+ cfg &= 0x0fffffff; /* stash threshold = 0 */ -+ qm_out(CFG, cfg); -+ -+ pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1); -+ ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1); -+ -+ /* Refresh EQCR CI cache value */ -+ qm_cl_invalidate(EQCR_CI); -+ eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1); -+ -+ DPA_ASSERT(!eqcr->busy); -+ if (pi != EQCR_PTR2IDX(eqcr->cursor)) -+ pr_crit("losing uncommited EQCR entries\n"); -+ if (ci != eqcr->ci) -+ pr_crit("missing existing EQCR completions\n"); -+ if (eqcr->ci != EQCR_PTR2IDX(eqcr->cursor)) -+ pr_crit("EQCR destroyed unquiesced\n"); -+} -+ -+static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal -+ *portal) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ DPA_ASSERT(!eqcr->busy); -+ if (!eqcr->available) -+ return NULL; -+ -+ -+#ifdef CONFIG_FSL_DPA_CHECKING -+ eqcr->busy = 1; -+#endif -+#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64) -+ dcbz_64(eqcr->cursor); -+#endif -+ return eqcr->cursor; -+} -+ -+static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal -+ *portal) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ u8 diff, old_ci; -+ -+ DPA_ASSERT(!eqcr->busy); -+ if (!eqcr->available) { -+ old_ci = eqcr->ci; -+ eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1); -+ diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci); -+ eqcr->available += diff; -+ if (!diff) -+ return NULL; -+ } -+#ifdef CONFIG_FSL_DPA_CHECKING -+ eqcr->busy = 1; -+#endif -+#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64) -+ dcbz_64(eqcr->cursor); -+#endif -+ return eqcr->cursor; -+} -+ -+static inline void qm_eqcr_abort(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr; -+ DPA_ASSERT(eqcr->busy); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ eqcr->busy = 0; -+#endif -+} -+ -+static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next( -+ struct qm_portal *portal, u8 myverb) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ DPA_ASSERT(eqcr->busy); -+ DPA_ASSERT(eqcr->pmode != qm_eqcr_pvb); -+ if (eqcr->available == 1) -+ return NULL; -+ eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit; -+ dcbf(eqcr->cursor); -+ EQCR_INC(eqcr); -+ eqcr->available--; -+#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64) -+ dcbz_64(eqcr->cursor); -+#endif -+ return eqcr->cursor; -+} -+ -+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -+#define EQCR_COMMIT_CHECKS(eqcr) \ -+do { \ -+ DPA_ASSERT(eqcr->busy); \ -+ DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0xffffff00)); \ -+ DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0xffffff00)); \ -+} while (0) -+#else -+#define EQCR_COMMIT_CHECKS(eqcr) \ -+do { \ -+ DPA_ASSERT(eqcr->busy); \ -+ DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & \ -+ cpu_to_be32(0x00ffffff))); \ -+ DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & \ -+ cpu_to_be32(0x00ffffff))); \ -+} while (0) -+#endif -+ -+static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ EQCR_COMMIT_CHECKS(eqcr); -+ DPA_ASSERT(eqcr->pmode == qm_eqcr_pci); -+ eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit; -+ EQCR_INC(eqcr); -+ eqcr->available--; -+ dcbf(eqcr->cursor); -+ hwsync(); -+ qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor)); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ eqcr->busy = 0; -+#endif -+} -+ -+static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr; -+ DPA_ASSERT(eqcr->pmode == qm_eqcr_pce); -+ qm_cl_invalidate(EQCR_PI); -+ qm_cl_touch_rw(EQCR_PI); -+} -+ -+static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ EQCR_COMMIT_CHECKS(eqcr); -+ DPA_ASSERT(eqcr->pmode == qm_eqcr_pce); -+ eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit; -+ EQCR_INC(eqcr); -+ eqcr->available--; -+ dcbf(eqcr->cursor); -+ lwsync(); -+ qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor)); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ eqcr->busy = 0; -+#endif -+} -+ -+static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ struct qm_eqcr_entry *eqcursor; -+ EQCR_COMMIT_CHECKS(eqcr); -+ DPA_ASSERT(eqcr->pmode == qm_eqcr_pvb); -+ lwsync(); -+ eqcursor = eqcr->cursor; -+ eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit; -+ dcbf(eqcursor); -+ EQCR_INC(eqcr); -+ eqcr->available--; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ eqcr->busy = 0; -+#endif -+} -+ -+static inline u8 qm_eqcr_cci_update(struct qm_portal *portal) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ u8 diff, old_ci = eqcr->ci; -+ eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1); -+ diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci); -+ eqcr->available += diff; -+ return diff; -+} -+ -+static inline void qm_eqcr_cce_prefetch(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr; -+ qm_cl_touch_ro(EQCR_CI); -+} -+ -+static inline u8 qm_eqcr_cce_update(struct qm_portal *portal) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ u8 diff, old_ci = eqcr->ci; -+ eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1); -+ qm_cl_invalidate(EQCR_CI); -+ diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci); -+ eqcr->available += diff; -+ return diff; -+} -+ -+static inline u8 qm_eqcr_get_ithresh(struct qm_portal *portal) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ return eqcr->ithresh; -+} -+ -+static inline void qm_eqcr_set_ithresh(struct qm_portal *portal, u8 ithresh) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ eqcr->ithresh = ithresh; -+ qm_out(EQCR_ITR, ithresh); -+} -+ -+static inline u8 qm_eqcr_get_avail(struct qm_portal *portal) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ return eqcr->available; -+} -+ -+static inline u8 qm_eqcr_get_fill(struct qm_portal *portal) -+{ -+ register struct qm_eqcr *eqcr = &portal->eqcr; -+ return QM_EQCR_SIZE - 1 - eqcr->available; -+} -+ -+ -+/* ---------------- */ -+/* --- DQRR API --- */ -+ -+/* FIXME: many possible improvements; -+ * - look at changing the API to use pointer rather than index parameters now -+ * that 'cursor' is a pointer, -+ * - consider moving other parameters to pointer if it could help (ci) -+ */ -+ -+#define DQRR_CARRYCLEAR(p) \ -+ (void *)((unsigned long)(p) & (~(unsigned long)(QM_DQRR_SIZE << 6))) -+ -+static inline u8 DQRR_PTR2IDX(const struct qm_dqrr_entry *e) -+{ -+ return ((uintptr_t)e >> 6) & (QM_DQRR_SIZE - 1); -+} -+ -+static inline const struct qm_dqrr_entry *DQRR_INC( -+ const struct qm_dqrr_entry *e) -+{ -+ return DQRR_CARRYCLEAR(e + 1); -+} -+ -+static inline void qm_dqrr_set_maxfill(struct qm_portal *portal, u8 mf) -+{ -+ qm_out(CFG, (qm_in(CFG) & 0xff0fffff) | -+ ((mf & (QM_DQRR_SIZE - 1)) << 20)); -+} -+ -+static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode == qm_dqrr_cci); -+ dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1); -+ qm_out(DQRR_CI_CINH, dqrr->ci); -+} -+ -+static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode == qm_dqrr_cce); -+ dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1); -+ qm_cl_out(DQRR_CI, dqrr->ci); -+} -+ -+static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask) -+{ -+ __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc); -+ qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */ -+ ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */ -+ dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1); -+ dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi); -+} -+ -+static inline int qm_dqrr_init(struct qm_portal *portal, -+ const struct qm_portal_config *config, -+ enum qm_dqrr_dmode dmode, -+ __maybe_unused enum qm_dqrr_pmode pmode, -+ enum qm_dqrr_cmode cmode, u8 max_fill) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ u32 cfg; -+ -+ /* Make sure the DQRR will be idle when we enable */ -+ qm_out(DQRR_SDQCR, 0); -+ qm_out(DQRR_VDQCR, 0); -+ qm_out(DQRR_PDQCR, 0); -+ dqrr->ring = portal->addr.addr_ce + QM_CL_DQRR; -+ dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1); -+ dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1); -+ dqrr->cursor = dqrr->ring + dqrr->ci; -+ dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi); -+ dqrr->vbit = (qm_in(DQRR_PI_CINH) & QM_DQRR_SIZE) ? -+ QM_DQRR_VERB_VBIT : 0; -+ dqrr->ithresh = qm_in(DQRR_ITR); -+ -+ /* Free up pending DQRR entries if any as per current DCM */ -+ if (dqrr->fill) { -+ enum qm_dqrr_cmode dcm = (qm_in(CFG) >> 16) & 3; -+ -+#ifdef CONFIG_FSL_DPA_CHECKING -+ dqrr->cmode = dcm; -+#endif -+ switch (dcm) { -+ case qm_dqrr_cci: -+ qm_dqrr_cci_consume(portal, dqrr->fill); -+ break; -+ case qm_dqrr_cce: -+ qm_dqrr_cce_consume(portal, dqrr->fill); -+ break; -+ case qm_dqrr_cdc: -+ qm_dqrr_cdc_consume_n(portal, (QM_DQRR_SIZE - 1)); -+ break; -+ default: -+ DPA_ASSERT(0); -+ } -+ } -+ -+#ifdef CONFIG_FSL_DPA_CHECKING -+ dqrr->dmode = dmode; -+ dqrr->pmode = pmode; -+ dqrr->cmode = cmode; -+#endif -+ /* Invalidate every ring entry before beginning */ -+ for (cfg = 0; cfg < QM_DQRR_SIZE; cfg++) -+ dcbi(qm_cl(dqrr->ring, cfg)); -+ cfg = (qm_in(CFG) & 0xff000f00) | -+ ((max_fill & (QM_DQRR_SIZE - 1)) << 20) | /* DQRR_MF */ -+ ((dmode & 1) << 18) | /* DP */ -+ ((cmode & 3) << 16) | /* DCM */ -+ 0xa0 | /* RE+SE */ -+ (0 ? 0x40 : 0) | /* Ignore RP */ -+ (0 ? 0x10 : 0); /* Ignore SP */ -+ qm_out(CFG, cfg); -+ qm_dqrr_set_maxfill(portal, max_fill); -+ return 0; -+} -+ -+static inline void qm_dqrr_finish(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if ((dqrr->cmode != qm_dqrr_cdc) && -+ (dqrr->ci != DQRR_PTR2IDX(dqrr->cursor))) -+ pr_crit("Ignoring completed DQRR entries\n"); -+#endif -+} -+ -+static inline const struct qm_dqrr_entry *qm_dqrr_current( -+ struct qm_portal *portal) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ if (!dqrr->fill) -+ return NULL; -+ return dqrr->cursor; -+} -+ -+static inline u8 qm_dqrr_cursor(struct qm_portal *portal) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ return DQRR_PTR2IDX(dqrr->cursor); -+} -+ -+static inline u8 qm_dqrr_next(struct qm_portal *portal) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->fill); -+ dqrr->cursor = DQRR_INC(dqrr->cursor); -+ return --dqrr->fill; -+} -+ -+static inline u8 qm_dqrr_pci_update(struct qm_portal *portal) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ u8 diff, old_pi = dqrr->pi; -+ DPA_ASSERT(dqrr->pmode == qm_dqrr_pci); -+ dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1); -+ diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi); -+ dqrr->fill += diff; -+ return diff; -+} -+ -+static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->pmode == qm_dqrr_pce); -+ qm_cl_invalidate(DQRR_PI); -+ qm_cl_touch_ro(DQRR_PI); -+} -+ -+static inline u8 qm_dqrr_pce_update(struct qm_portal *portal) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ u8 diff, old_pi = dqrr->pi; -+ DPA_ASSERT(dqrr->pmode == qm_dqrr_pce); -+ dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1); -+ diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi); -+ dqrr->fill += diff; -+ return diff; -+} -+ -+static inline void qm_dqrr_pvb_update(struct qm_portal *portal) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi); -+ DPA_ASSERT(dqrr->pmode == qm_dqrr_pvb); -+#if (defined CONFIG_PPC || defined CONFIG_PPC64) && !defined CONFIG_FSL_PAMU -+ /* -+ * On PowerPC platforms if PAMU is not available we need to -+ * manually invalidate the cache. When PAMU is available the -+ * cache is updated by stashing operations generated by QMan -+ */ -+ dcbi(res); -+ dcbt_ro(res); -+#endif -+ -+ /* when accessing 'verb', use __raw_readb() to ensure that compiler -+ * inlining doesn't try to optimise out "excess reads". */ -+ if ((__raw_readb(&res->verb) & QM_DQRR_VERB_VBIT) == dqrr->vbit) { -+ dqrr->pi = (dqrr->pi + 1) & (QM_DQRR_SIZE - 1); -+ if (!dqrr->pi) -+ dqrr->vbit ^= QM_DQRR_VERB_VBIT; -+ dqrr->fill++; -+ } -+} -+ -+ -+static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode == qm_dqrr_cci); -+ dqrr->ci = DQRR_PTR2IDX(dqrr->cursor); -+ qm_out(DQRR_CI_CINH, dqrr->ci); -+} -+ -+static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode == qm_dqrr_cce); -+ qm_cl_invalidate(DQRR_CI); -+ qm_cl_touch_rw(DQRR_CI); -+} -+ -+static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode == qm_dqrr_cce); -+ dqrr->ci = DQRR_PTR2IDX(dqrr->cursor); -+ qm_cl_out(DQRR_CI, dqrr->ci); -+} -+ -+static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx, -+ int park) -+{ -+ __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc); -+ DPA_ASSERT(idx < QM_DQRR_SIZE); -+ qm_out(DQRR_DCAP, (0 << 8) | /* S */ -+ ((park ? 1 : 0) << 6) | /* PK */ -+ idx); /* DCAP_CI */ -+} -+ -+static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal, -+ const struct qm_dqrr_entry *dq, -+ int park) -+{ -+ __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; -+ u8 idx = DQRR_PTR2IDX(dq); -+ DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc); -+ DPA_ASSERT((dqrr->ring + idx) == dq); -+ DPA_ASSERT(idx < QM_DQRR_SIZE); -+ qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */ -+ ((park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */ -+ idx); /* DQRR_DCAP::DCAP_CI */ -+} -+ -+static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc); -+ return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1); -+} -+ -+static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc); -+ qm_cl_invalidate(DQRR_CI); -+ qm_cl_touch_ro(DQRR_CI); -+} -+ -+static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc); -+ return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1); -+} -+ -+static inline u8 qm_dqrr_get_ci(struct qm_portal *portal) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc); -+ return dqrr->ci; -+} -+ -+static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx) -+{ -+ __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc); -+ qm_out(DQRR_DCAP, (0 << 8) | /* S */ -+ (1 << 6) | /* PK */ -+ (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */ -+} -+ -+static inline void qm_dqrr_park_current(struct qm_portal *portal) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc); -+ qm_out(DQRR_DCAP, (0 << 8) | /* S */ -+ (1 << 6) | /* PK */ -+ DQRR_PTR2IDX(dqrr->cursor)); /* DCAP_CI */ -+} -+ -+static inline void qm_dqrr_sdqcr_set(struct qm_portal *portal, u32 sdqcr) -+{ -+ qm_out(DQRR_SDQCR, sdqcr); -+} -+ -+static inline u32 qm_dqrr_sdqcr_get(struct qm_portal *portal) -+{ -+ return qm_in(DQRR_SDQCR); -+} -+ -+static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr) -+{ -+ qm_out(DQRR_VDQCR, vdqcr); -+} -+ -+static inline u32 qm_dqrr_vdqcr_get(struct qm_portal *portal) -+{ -+ return qm_in(DQRR_VDQCR); -+} -+ -+static inline void qm_dqrr_pdqcr_set(struct qm_portal *portal, u32 pdqcr) -+{ -+ qm_out(DQRR_PDQCR, pdqcr); -+} -+ -+static inline u32 qm_dqrr_pdqcr_get(struct qm_portal *portal) -+{ -+ return qm_in(DQRR_PDQCR); -+} -+ -+static inline u8 qm_dqrr_get_ithresh(struct qm_portal *portal) -+{ -+ register struct qm_dqrr *dqrr = &portal->dqrr; -+ return dqrr->ithresh; -+} -+ -+static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh) -+{ -+ qm_out(DQRR_ITR, ithresh); -+} -+ -+static inline u8 qm_dqrr_get_maxfill(struct qm_portal *portal) -+{ -+ return (qm_in(CFG) & 0x00f00000) >> 20; -+} -+ -+ -+/* -------------- */ -+/* --- MR API --- */ -+ -+#define MR_CARRYCLEAR(p) \ -+ (void *)((unsigned long)(p) & (~(unsigned long)(QM_MR_SIZE << 6))) -+ -+static inline u8 MR_PTR2IDX(const struct qm_mr_entry *e) -+{ -+ return ((uintptr_t)e >> 6) & (QM_MR_SIZE - 1); -+} -+ -+static inline const struct qm_mr_entry *MR_INC(const struct qm_mr_entry *e) -+{ -+ return MR_CARRYCLEAR(e + 1); -+} -+ -+static inline int qm_mr_init(struct qm_portal *portal, enum qm_mr_pmode pmode, -+ enum qm_mr_cmode cmode) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ u32 cfg; -+ -+ mr->ring = portal->addr.addr_ce + QM_CL_MR; -+ mr->pi = qm_in(MR_PI_CINH) & (QM_MR_SIZE - 1); -+ mr->ci = qm_in(MR_CI_CINH) & (QM_MR_SIZE - 1); -+ mr->cursor = mr->ring + mr->ci; -+ mr->fill = qm_cyc_diff(QM_MR_SIZE, mr->ci, mr->pi); -+ mr->vbit = (qm_in(MR_PI_CINH) & QM_MR_SIZE) ? QM_MR_VERB_VBIT : 0; -+ mr->ithresh = qm_in(MR_ITR); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mr->pmode = pmode; -+ mr->cmode = cmode; -+#endif -+ cfg = (qm_in(CFG) & 0xfffff0ff) | -+ ((cmode & 1) << 8); /* QCSP_CFG:MM */ -+ qm_out(CFG, cfg); -+ return 0; -+} -+ -+static inline void qm_mr_finish(struct qm_portal *portal) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ if (mr->ci != MR_PTR2IDX(mr->cursor)) -+ pr_crit("Ignoring completed MR entries\n"); -+} -+ -+static inline const struct qm_mr_entry *qm_mr_current(struct qm_portal *portal) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ if (!mr->fill) -+ return NULL; -+ return mr->cursor; -+} -+ -+static inline u8 qm_mr_cursor(struct qm_portal *portal) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ return MR_PTR2IDX(mr->cursor); -+} -+ -+static inline u8 qm_mr_next(struct qm_portal *portal) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ DPA_ASSERT(mr->fill); -+ mr->cursor = MR_INC(mr->cursor); -+ return --mr->fill; -+} -+ -+static inline u8 qm_mr_pci_update(struct qm_portal *portal) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ u8 diff, old_pi = mr->pi; -+ DPA_ASSERT(mr->pmode == qm_mr_pci); -+ mr->pi = qm_in(MR_PI_CINH); -+ diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi); -+ mr->fill += diff; -+ return diff; -+} -+ -+static inline void qm_mr_pce_prefetch(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_mr *mr = &portal->mr; -+ DPA_ASSERT(mr->pmode == qm_mr_pce); -+ qm_cl_invalidate(MR_PI); -+ qm_cl_touch_ro(MR_PI); -+} -+ -+static inline u8 qm_mr_pce_update(struct qm_portal *portal) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ u8 diff, old_pi = mr->pi; -+ DPA_ASSERT(mr->pmode == qm_mr_pce); -+ mr->pi = qm_cl_in(MR_PI) & (QM_MR_SIZE - 1); -+ diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi); -+ mr->fill += diff; -+ return diff; -+} -+ -+static inline void qm_mr_pvb_update(struct qm_portal *portal) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ const struct qm_mr_entry *res = qm_cl(mr->ring, mr->pi); -+ DPA_ASSERT(mr->pmode == qm_mr_pvb); -+ /* when accessing 'verb', use __raw_readb() to ensure that compiler -+ * inlining doesn't try to optimise out "excess reads". */ -+ if ((__raw_readb(&res->verb) & QM_MR_VERB_VBIT) == mr->vbit) { -+ mr->pi = (mr->pi + 1) & (QM_MR_SIZE - 1); -+ if (!mr->pi) -+ mr->vbit ^= QM_MR_VERB_VBIT; -+ mr->fill++; -+ res = MR_INC(res); -+ } -+ dcbit_ro(res); -+} -+ -+static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ DPA_ASSERT(mr->cmode == qm_mr_cci); -+ mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1); -+ qm_out(MR_CI_CINH, mr->ci); -+} -+ -+static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ DPA_ASSERT(mr->cmode == qm_mr_cci); -+ mr->ci = MR_PTR2IDX(mr->cursor); -+ qm_out(MR_CI_CINH, mr->ci); -+} -+ -+static inline void qm_mr_cce_prefetch(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_mr *mr = &portal->mr; -+ DPA_ASSERT(mr->cmode == qm_mr_cce); -+ qm_cl_invalidate(MR_CI); -+ qm_cl_touch_rw(MR_CI); -+} -+ -+static inline void qm_mr_cce_consume(struct qm_portal *portal, u8 num) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ DPA_ASSERT(mr->cmode == qm_mr_cce); -+ mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1); -+ qm_cl_out(MR_CI, mr->ci); -+} -+ -+static inline void qm_mr_cce_consume_to_current(struct qm_portal *portal) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ DPA_ASSERT(mr->cmode == qm_mr_cce); -+ mr->ci = MR_PTR2IDX(mr->cursor); -+ qm_cl_out(MR_CI, mr->ci); -+} -+ -+static inline u8 qm_mr_get_ci(struct qm_portal *portal) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ return mr->ci; -+} -+ -+static inline u8 qm_mr_get_ithresh(struct qm_portal *portal) -+{ -+ register struct qm_mr *mr = &portal->mr; -+ return mr->ithresh; -+} -+ -+static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh) -+{ -+ qm_out(MR_ITR, ithresh); -+} -+ -+ -+/* ------------------------------ */ -+/* --- Management command API --- */ -+ -+static inline int qm_mc_init(struct qm_portal *portal) -+{ -+ register struct qm_mc *mc = &portal->mc; -+ mc->cr = portal->addr.addr_ce + QM_CL_CR; -+ mc->rr = portal->addr.addr_ce + QM_CL_RR0; -+ mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) & -+ QM_MCC_VERB_VBIT) ? 0 : 1; -+ mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = qman_mc_idle; -+#endif -+ return 0; -+} -+ -+static inline void qm_mc_finish(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_mc *mc = &portal->mc; -+ DPA_ASSERT(mc->state == qman_mc_idle); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ if (mc->state != qman_mc_idle) -+ pr_crit("Losing incomplete MC command\n"); -+#endif -+} -+ -+static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal) -+{ -+ register struct qm_mc *mc = &portal->mc; -+ DPA_ASSERT(mc->state == qman_mc_idle); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = qman_mc_user; -+#endif -+#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64) -+ dcbz_64(mc->cr); -+#endif -+ return mc->cr; -+} -+ -+static inline void qm_mc_abort(struct qm_portal *portal) -+{ -+ __maybe_unused register struct qm_mc *mc = &portal->mc; -+ DPA_ASSERT(mc->state == qman_mc_user); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = qman_mc_idle; -+#endif -+} -+ -+static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb) -+{ -+ register struct qm_mc *mc = &portal->mc; -+ struct qm_mc_result *rr = mc->rr + mc->rridx; -+ DPA_ASSERT(mc->state == qman_mc_user); -+ lwsync(); -+ mc->cr->__dont_write_directly__verb = myverb | mc->vbit; -+ dcbf(mc->cr); -+ dcbit_ro(rr); -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = qman_mc_hw; -+#endif -+} -+ -+static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal) -+{ -+ register struct qm_mc *mc = &portal->mc; -+ struct qm_mc_result *rr = mc->rr + mc->rridx; -+ DPA_ASSERT(mc->state == qman_mc_hw); -+ /* The inactive response register's verb byte always returns zero until -+ * its command is submitted and completed. This includes the valid-bit, -+ * in case you were wondering... */ -+ if (!__raw_readb(&rr->verb)) { -+ dcbit_ro(rr); -+ return NULL; -+ } -+ mc->rridx ^= 1; -+ mc->vbit ^= QM_MCC_VERB_VBIT; -+#ifdef CONFIG_FSL_DPA_CHECKING -+ mc->state = qman_mc_idle; -+#endif -+ return rr; -+} -+ -+ -+/* ------------------------------------- */ -+/* --- Portal interrupt register API --- */ -+ -+static inline int qm_isr_init(__always_unused struct qm_portal *portal) -+{ -+ return 0; -+} -+ -+static inline void qm_isr_finish(__always_unused struct qm_portal *portal) -+{ -+} -+ -+static inline void qm_isr_set_iperiod(struct qm_portal *portal, u16 iperiod) -+{ -+ qm_out(ITPR, iperiod); -+} -+ -+static inline u32 __qm_isr_read(struct qm_portal *portal, enum qm_isr_reg n) -+{ -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ return __qm_in(&portal->addr, QM_REG_ISR + (n << 6)); -+#else -+ return __qm_in(&portal->addr, QM_REG_ISR + (n << 2)); -+#endif -+} -+ -+static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n, -+ u32 val) -+{ -+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ __qm_out(&portal->addr, QM_REG_ISR + (n << 6), val); -+#else -+ __qm_out(&portal->addr, QM_REG_ISR + (n << 2), val); -+#endif -+} -+ -+/* Cleanup FQs */ -+static inline int qm_shutdown_fq(struct qm_portal **portal, int portal_count, -+ u32 fqid) -+{ -+ -+ struct qm_mc_command *mcc; -+ struct qm_mc_result *mcr; -+ u8 state; -+ int orl_empty, fq_empty, i, drain = 0; -+ u32 result; -+ u32 channel, wq; -+ u16 dest_wq; -+ -+ /* Determine the state of the FQID */ -+ mcc = qm_mc_start(portal[0]); -+ mcc->queryfq_np.fqid = cpu_to_be32(fqid); -+ qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ_NP); -+ while (!(mcr = qm_mc_result(portal[0]))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP); -+ state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK; -+ if (state == QM_MCR_NP_STATE_OOS) -+ return 0; /* Already OOS, no need to do anymore checks */ -+ -+ /* Query which channel the FQ is using */ -+ mcc = qm_mc_start(portal[0]); -+ mcc->queryfq.fqid = cpu_to_be32(fqid); -+ qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ); -+ while (!(mcr = qm_mc_result(portal[0]))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ); -+ -+ /* Need to store these since the MCR gets reused */ -+ dest_wq = be16_to_cpu(mcr->queryfq.fqd.dest_wq); -+ wq = dest_wq & 0x7; -+ channel = dest_wq>>3; -+ -+ switch (state) { -+ case QM_MCR_NP_STATE_TEN_SCHED: -+ case QM_MCR_NP_STATE_TRU_SCHED: -+ case QM_MCR_NP_STATE_ACTIVE: -+ case QM_MCR_NP_STATE_PARKED: -+ orl_empty = 0; -+ mcc = qm_mc_start(portal[0]); -+ mcc->alterfq.fqid = cpu_to_be32(fqid); -+ qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_RETIRE); -+ while (!(mcr = qm_mc_result(portal[0]))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_MCR_VERB_ALTER_RETIRE); -+ result = mcr->result; /* Make a copy as we reuse MCR below */ -+ -+ if (result == QM_MCR_RESULT_PENDING) { -+ /* Need to wait for the FQRN in the message ring, which -+ will only occur once the FQ has been drained. In -+ order for the FQ to drain the portal needs to be set -+ to dequeue from the channel the FQ is scheduled on */ -+ const struct qm_mr_entry *msg; -+ const struct qm_dqrr_entry *dqrr = NULL; -+ int found_fqrn = 0; -+ u16 dequeue_wq = 0; -+ -+ /* Flag that we need to drain FQ */ -+ drain = 1; -+ -+ if (channel >= qm_channel_pool1 && -+ channel < (qm_channel_pool1 + 15)) { -+ /* Pool channel, enable the bit in the portal */ -+ dequeue_wq = (channel - -+ qm_channel_pool1 + 1)<<4 | wq; -+ } else if (channel < qm_channel_pool1) { -+ /* Dedicated channel */ -+ dequeue_wq = wq; -+ } else { -+ pr_info("Cannot recover FQ 0x%x, it is " -+ "scheduled on channel 0x%x", -+ fqid, channel); -+ return -EBUSY; -+ } -+ /* Set the sdqcr to drain this channel */ -+ if (channel < qm_channel_pool1) -+ for (i = 0; i < portal_count; i++) -+ qm_dqrr_sdqcr_set(portal[i], -+ QM_SDQCR_TYPE_ACTIVE | -+ QM_SDQCR_CHANNELS_DEDICATED); -+ else -+ for (i = 0; i < portal_count; i++) -+ qm_dqrr_sdqcr_set( -+ portal[i], -+ QM_SDQCR_TYPE_ACTIVE | -+ QM_SDQCR_CHANNELS_POOL_CONV -+ (channel)); -+ while (!found_fqrn) { -+ /* Keep draining DQRR while checking the MR*/ -+ for (i = 0; i < portal_count; i++) { -+ qm_dqrr_pvb_update(portal[i]); -+ dqrr = qm_dqrr_current(portal[i]); -+ while (dqrr) { -+ qm_dqrr_cdc_consume_1ptr( -+ portal[i], dqrr, 0); -+ qm_dqrr_pvb_update(portal[i]); -+ qm_dqrr_next(portal[i]); -+ dqrr = qm_dqrr_current( -+ portal[i]); -+ } -+ /* Process message ring too */ -+ qm_mr_pvb_update(portal[i]); -+ msg = qm_mr_current(portal[i]); -+ while (msg) { -+ if ((msg->verb & -+ QM_MR_VERB_TYPE_MASK) -+ == QM_MR_VERB_FQRN) -+ found_fqrn = 1; -+ qm_mr_next(portal[i]); -+ qm_mr_cci_consume_to_current( -+ portal[i]); -+ qm_mr_pvb_update(portal[i]); -+ msg = qm_mr_current(portal[i]); -+ } -+ cpu_relax(); -+ } -+ } -+ } -+ if (result != QM_MCR_RESULT_OK && -+ result != QM_MCR_RESULT_PENDING) { -+ /* error */ -+ pr_err("qman_retire_fq failed on FQ 0x%x, result=0x%x\n", -+ fqid, result); -+ return -1; -+ } -+ if (!(mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)) { -+ /* ORL had no entries, no need to wait until the -+ ERNs come in */ -+ orl_empty = 1; -+ } -+ /* Retirement succeeded, check to see if FQ needs -+ to be drained */ -+ if (drain || mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY) { -+ /* FQ is Not Empty, drain using volatile DQ commands */ -+ fq_empty = 0; -+ do { -+ const struct qm_dqrr_entry *dqrr = NULL; -+ u32 vdqcr = fqid | QM_VDQCR_NUMFRAMES_SET(3); -+ qm_dqrr_vdqcr_set(portal[0], vdqcr); -+ -+ /* Wait for a dequeue to occur */ -+ while (dqrr == NULL) { -+ qm_dqrr_pvb_update(portal[0]); -+ dqrr = qm_dqrr_current(portal[0]); -+ if (!dqrr) -+ cpu_relax(); -+ } -+ /* Process the dequeues, making sure to -+ empty the ring completely */ -+ while (dqrr) { -+ if (be32_to_cpu(dqrr->fqid) == fqid && -+ dqrr->stat & QM_DQRR_STAT_FQ_EMPTY) -+ fq_empty = 1; -+ qm_dqrr_cdc_consume_1ptr(portal[0], -+ dqrr, 0); -+ qm_dqrr_pvb_update(portal[0]); -+ qm_dqrr_next(portal[0]); -+ dqrr = qm_dqrr_current(portal[0]); -+ } -+ } while (fq_empty == 0); -+ } -+ for (i = 0; i < portal_count; i++) -+ qm_dqrr_sdqcr_set(portal[i], 0); -+ -+ /* Wait for the ORL to have been completely drained */ -+ while (orl_empty == 0) { -+ const struct qm_mr_entry *msg; -+ qm_mr_pvb_update(portal[0]); -+ msg = qm_mr_current(portal[0]); -+ while (msg) { -+ if ((msg->verb & QM_MR_VERB_TYPE_MASK) == -+ QM_MR_VERB_FQRL) -+ orl_empty = 1; -+ qm_mr_next(portal[0]); -+ qm_mr_cci_consume_to_current(portal[0]); -+ qm_mr_pvb_update(portal[0]); -+ msg = qm_mr_current(portal[0]); -+ } -+ cpu_relax(); -+ } -+ mcc = qm_mc_start(portal[0]); -+ mcc->alterfq.fqid = cpu_to_be32(fqid); -+ qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS); -+ while (!(mcr = qm_mc_result(portal[0]))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_MCR_VERB_ALTER_OOS); -+ if (mcr->result != QM_MCR_RESULT_OK) { -+ pr_err("OOS after drain Failed on FQID 0x%x, result 0x%x\n", -+ fqid, mcr->result); -+ return -1; -+ } -+ return 0; -+ case QM_MCR_NP_STATE_RETIRED: -+ /* Send OOS Command */ -+ mcc = qm_mc_start(portal[0]); -+ mcc->alterfq.fqid = cpu_to_be32(fqid); -+ qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS); -+ while (!(mcr = qm_mc_result(portal[0]))) -+ cpu_relax(); -+ DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == -+ QM_MCR_VERB_ALTER_OOS); -+ if (mcr->result) { -+ pr_err("OOS Failed on FQID 0x%x\n", fqid); -+ return -1; -+ } -+ return 0; -+ } -+ return -1; -+} ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_private.h -@@ -0,0 +1,398 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "dpa_sys.h" -+#include -+#include -+ -+#if defined(CONFIG_FSL_PAMU) -+#include -+#endif -+ -+#if !defined(CONFIG_FSL_QMAN_FQ_LOOKUP) && defined(CONFIG_PPC64) -+#error "_PPC64 requires _FSL_QMAN_FQ_LOOKUP" -+#endif -+ -+#define QBMAN_ANY_PORTAL_IDX 0xffffffff -+ /* ----------------- */ -+ /* Congestion Groups */ -+ /* ----------------- */ -+/* This wrapper represents a bit-array for the state of the 256 Qman congestion -+ * groups. Is also used as a *mask* for congestion groups, eg. so we ignore -+ * those that don't concern us. We harness the structure and accessor details -+ * already used in the management command to query congestion groups. */ -+struct qman_cgrs { -+ struct __qm_mcr_querycongestion q; -+}; -+static inline void qman_cgrs_init(struct qman_cgrs *c) -+{ -+ memset(c, 0, sizeof(*c)); -+} -+static inline void qman_cgrs_fill(struct qman_cgrs *c) -+{ -+ memset(c, 0xff, sizeof(*c)); -+} -+static inline int qman_cgrs_get(struct qman_cgrs *c, int num) -+{ -+ return QM_MCR_QUERYCONGESTION(&c->q, num); -+} -+static inline void qman_cgrs_set(struct qman_cgrs *c, int num) -+{ -+ c->q.__state[__CGR_WORD(num)] |= (0x80000000 >> __CGR_SHIFT(num)); -+} -+static inline void qman_cgrs_unset(struct qman_cgrs *c, int num) -+{ -+ c->q.__state[__CGR_WORD(num)] &= ~(0x80000000 >> __CGR_SHIFT(num)); -+} -+static inline int qman_cgrs_next(struct qman_cgrs *c, int num) -+{ -+ while ((++num < __CGR_NUM) && !qman_cgrs_get(c, num)) -+ ; -+ return num; -+} -+static inline void qman_cgrs_cp(struct qman_cgrs *dest, -+ const struct qman_cgrs *src) -+{ -+ *dest = *src; -+} -+static inline void qman_cgrs_and(struct qman_cgrs *dest, -+ const struct qman_cgrs *a, const struct qman_cgrs *b) -+{ -+ int ret; -+ u32 *_d = dest->q.__state; -+ const u32 *_a = a->q.__state; -+ const u32 *_b = b->q.__state; -+ for (ret = 0; ret < 8; ret++) -+ *(_d++) = *(_a++) & *(_b++); -+} -+static inline void qman_cgrs_xor(struct qman_cgrs *dest, -+ const struct qman_cgrs *a, const struct qman_cgrs *b) -+{ -+ int ret; -+ u32 *_d = dest->q.__state; -+ const u32 *_a = a->q.__state; -+ const u32 *_b = b->q.__state; -+ for (ret = 0; ret < 8; ret++) -+ *(_d++) = *(_a++) ^ *(_b++); -+} -+ -+ /* ----------------------- */ -+ /* CEETM Congestion Groups */ -+ /* ----------------------- */ -+/* This wrapper represents a bit-array for the state of the 512 Qman CEETM -+ * congestion groups. -+ */ -+struct qman_ccgrs { -+ struct __qm_mcr_querycongestion q[2]; -+}; -+static inline void qman_ccgrs_init(struct qman_ccgrs *c) -+{ -+ memset(c, 0, sizeof(*c)); -+} -+static inline void qman_ccgrs_fill(struct qman_ccgrs *c) -+{ -+ memset(c, 0xff, sizeof(*c)); -+} -+static inline int qman_ccgrs_get(struct qman_ccgrs *c, int num) -+{ -+ if (num < __CGR_NUM) -+ return QM_MCR_QUERYCONGESTION(&c->q[0], num); -+ else -+ return QM_MCR_QUERYCONGESTION(&c->q[1], (num - __CGR_NUM)); -+} -+static inline int qman_ccgrs_next(struct qman_ccgrs *c, int num) -+{ -+ while ((++num < __CGR_NUM) && !qman_ccgrs_get(c, num)) -+ ; -+ return num; -+} -+static inline void qman_ccgrs_cp(struct qman_ccgrs *dest, -+ const struct qman_ccgrs *src) -+{ -+ *dest = *src; -+} -+static inline void qman_ccgrs_and(struct qman_ccgrs *dest, -+ const struct qman_ccgrs *a, const struct qman_ccgrs *b) -+{ -+ int ret, i; -+ u32 *_d; -+ const u32 *_a, *_b; -+ for (i = 0; i < 2; i++) { -+ _d = dest->q[i].__state; -+ _a = a->q[i].__state; -+ _b = b->q[i].__state; -+ for (ret = 0; ret < 8; ret++) -+ *(_d++) = *(_a++) & *(_b++); -+ } -+} -+static inline void qman_ccgrs_xor(struct qman_ccgrs *dest, -+ const struct qman_ccgrs *a, const struct qman_ccgrs *b) -+{ -+ int ret, i; -+ u32 *_d; -+ const u32 *_a, *_b; -+ for (i = 0; i < 2; i++) { -+ _d = dest->q[i].__state; -+ _a = a->q[i].__state; -+ _b = b->q[i].__state; -+ for (ret = 0; ret < 8; ret++) -+ *(_d++) = *(_a++) ^ *(_b++); -+ } -+} -+ -+/* used by CCSR and portal interrupt code */ -+enum qm_isr_reg { -+ qm_isr_status = 0, -+ qm_isr_enable = 1, -+ qm_isr_disable = 2, -+ qm_isr_inhibit = 3 -+}; -+ -+struct qm_portal_config { -+ /* Corenet portal addresses; -+ * [0]==cache-enabled, [1]==cache-inhibited. */ -+ __iomem void *addr_virt[2]; -+ struct resource addr_phys[2]; -+ struct device dev; -+ struct iommu_domain *iommu_domain; -+ /* Allow these to be joined in lists */ -+ struct list_head list; -+ /* User-visible portal configuration settings */ -+ struct qman_portal_config public_cfg; -+ /* power management saved data */ -+ u32 saved_isdr; -+}; -+ -+/* Revision info (for errata and feature handling) */ -+#define QMAN_REV11 0x0101 -+#define QMAN_REV12 0x0102 -+#define QMAN_REV20 0x0200 -+#define QMAN_REV30 0x0300 -+#define QMAN_REV31 0x0301 -+#define QMAN_REV32 0x0302 -+ -+/* QMan REV_2 register contains the Cfg option */ -+#define QMAN_REV_CFG_0 0x0 -+#define QMAN_REV_CFG_1 0x1 -+#define QMAN_REV_CFG_2 0x2 -+#define QMAN_REV_CFG_3 0x3 -+ -+extern u16 qman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */ -+extern u8 qman_ip_cfg; -+extern u32 qman_clk; -+extern u16 qman_portal_max; -+ -+#ifdef CONFIG_FSL_QMAN_CONFIG -+/* Hooks from qman_driver.c to qman_config.c */ -+int qman_init_ccsr(struct device_node *node); -+void qman_liodn_fixup(u16 channel); -+int qman_set_sdest(u16 channel, unsigned int cpu_idx); -+size_t get_qman_fqd_size(void); -+#else -+static inline size_t get_qman_fqd_size(void) -+{ -+ return (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ); -+} -+#endif -+ -+int qm_set_wpm(int wpm); -+int qm_get_wpm(int *wpm); -+ -+/* Hooks from qman_driver.c in to qman_high.c */ -+struct qman_portal *qman_create_portal( -+ struct qman_portal *portal, -+ const struct qm_portal_config *config, -+ const struct qman_cgrs *cgrs); -+ -+struct qman_portal *qman_create_affine_portal( -+ const struct qm_portal_config *config, -+ const struct qman_cgrs *cgrs); -+struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect, -+ int cpu); -+const struct qm_portal_config *qman_destroy_affine_portal(void); -+void qman_destroy_portal(struct qman_portal *qm); -+ -+/* Hooks from fsl_usdpaa.c to qman_driver.c */ -+struct qm_portal_config *qm_get_unused_portal(void); -+struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx); -+ -+void qm_put_unused_portal(struct qm_portal_config *pcfg); -+void qm_set_liodns(struct qm_portal_config *pcfg); -+ -+/* This CGR feature is supported by h/w and required by unit-tests and the -+ * debugfs hooks, so is implemented in the driver. However it allows an explicit -+ * corruption of h/w fields by s/w that are usually incorruptible (because the -+ * counters are usually maintained entirely within h/w). As such, we declare -+ * this API internally. */ -+int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt, -+ struct qm_mcr_cgrtestwrite *result); -+ -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+/* If the fq object pointer is greater than the size of context_b field, -+ * than a lookup table is required. */ -+int qman_setup_fq_lookup_table(size_t num_entries); -+#endif -+ -+ -+/*************************************************/ -+/* QMan s/w corenet portal, low-level i/face */ -+/*************************************************/ -+ -+/* Note: most functions are only used by the high-level interface, so are -+ * inlined from qman_low.h. The stuff below is for use by other parts of the -+ * driver. */ -+ -+/* For qm_dqrr_sdqcr_set(); Choose one SOURCE. Choose one COUNT. Choose one -+ * dequeue TYPE. Choose TOKEN (8-bit). -+ * If SOURCE == CHANNELS, -+ * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL(n). -+ * You can choose DEDICATED_PRECEDENCE if the portal channel should have -+ * priority. -+ * If SOURCE == SPECIFICWQ, -+ * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the -+ * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the -+ * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the -+ * same value. -+ */ -+#define QM_SDQCR_SOURCE_CHANNELS 0x0 -+#define QM_SDQCR_SOURCE_SPECIFICWQ 0x40000000 -+#define QM_SDQCR_COUNT_EXACT1 0x0 -+#define QM_SDQCR_COUNT_UPTO3 0x20000000 -+#define QM_SDQCR_DEDICATED_PRECEDENCE 0x10000000 -+#define QM_SDQCR_TYPE_MASK 0x03000000 -+#define QM_SDQCR_TYPE_NULL 0x0 -+#define QM_SDQCR_TYPE_PRIO_QOS 0x01000000 -+#define QM_SDQCR_TYPE_ACTIVE_QOS 0x02000000 -+#define QM_SDQCR_TYPE_ACTIVE 0x03000000 -+#define QM_SDQCR_TOKEN_MASK 0x00ff0000 -+#define QM_SDQCR_TOKEN_SET(v) (((v) & 0xff) << 16) -+#define QM_SDQCR_TOKEN_GET(v) (((v) >> 16) & 0xff) -+#define QM_SDQCR_CHANNELS_DEDICATED 0x00008000 -+#define QM_SDQCR_SPECIFICWQ_MASK 0x000000f7 -+#define QM_SDQCR_SPECIFICWQ_DEDICATED 0x00000000 -+#define QM_SDQCR_SPECIFICWQ_POOL(n) ((n) << 4) -+#define QM_SDQCR_SPECIFICWQ_WQ(n) (n) -+ -+/* For qm_dqrr_vdqcr_set(): use FQID(n) to fill in the frame queue ID */ -+#define QM_VDQCR_FQID_MASK 0x00ffffff -+#define QM_VDQCR_FQID(n) ((n) & QM_VDQCR_FQID_MASK) -+ -+/* For qm_dqrr_pdqcr_set(); Choose one MODE. Choose one COUNT. -+ * If MODE==SCHEDULED -+ * Choose SCHEDULED_CHANNELS or SCHEDULED_SPECIFICWQ. Choose one dequeue TYPE. -+ * If CHANNELS, -+ * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL() channels. -+ * You can choose DEDICATED_PRECEDENCE if the portal channel should have -+ * priority. -+ * If SPECIFICWQ, -+ * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the -+ * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the -+ * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the -+ * same value. -+ * If MODE==UNSCHEDULED -+ * Choose FQID(). -+ */ -+#define QM_PDQCR_MODE_SCHEDULED 0x0 -+#define QM_PDQCR_MODE_UNSCHEDULED 0x80000000 -+#define QM_PDQCR_SCHEDULED_CHANNELS 0x0 -+#define QM_PDQCR_SCHEDULED_SPECIFICWQ 0x40000000 -+#define QM_PDQCR_COUNT_EXACT1 0x0 -+#define QM_PDQCR_COUNT_UPTO3 0x20000000 -+#define QM_PDQCR_DEDICATED_PRECEDENCE 0x10000000 -+#define QM_PDQCR_TYPE_MASK 0x03000000 -+#define QM_PDQCR_TYPE_NULL 0x0 -+#define QM_PDQCR_TYPE_PRIO_QOS 0x01000000 -+#define QM_PDQCR_TYPE_ACTIVE_QOS 0x02000000 -+#define QM_PDQCR_TYPE_ACTIVE 0x03000000 -+#define QM_PDQCR_CHANNELS_DEDICATED 0x00008000 -+#define QM_PDQCR_CHANNELS_POOL(n) (0x00008000 >> (n)) -+#define QM_PDQCR_SPECIFICWQ_MASK 0x000000f7 -+#define QM_PDQCR_SPECIFICWQ_DEDICATED 0x00000000 -+#define QM_PDQCR_SPECIFICWQ_POOL(n) ((n) << 4) -+#define QM_PDQCR_SPECIFICWQ_WQ(n) (n) -+#define QM_PDQCR_FQID(n) ((n) & 0xffffff) -+ -+/* Used by all portal interrupt registers except 'inhibit' -+ * Channels with frame availability -+ */ -+#define QM_PIRQ_DQAVAIL 0x0000ffff -+ -+/* The DQAVAIL interrupt fields break down into these bits; */ -+#define QM_DQAVAIL_PORTAL 0x8000 /* Portal channel */ -+#define QM_DQAVAIL_POOL(n) (0x8000 >> (n)) /* Pool channel, n==[1..15] */ -+#define QM_DQAVAIL_MASK 0xffff -+/* This mask contains all the "irqsource" bits visible to API users */ -+#define QM_PIRQ_VISIBLE (QM_PIRQ_SLOW | QM_PIRQ_DQRI) -+ -+/* These are qm__(). So for example, qm_disable_write() means "write -+ * the disable register" rather than "disable the ability to write". */ -+#define qm_isr_status_read(qm) __qm_isr_read(qm, qm_isr_status) -+#define qm_isr_status_clear(qm, m) __qm_isr_write(qm, qm_isr_status, m) -+#define qm_isr_enable_read(qm) __qm_isr_read(qm, qm_isr_enable) -+#define qm_isr_enable_write(qm, v) __qm_isr_write(qm, qm_isr_enable, v) -+#define qm_isr_disable_read(qm) __qm_isr_read(qm, qm_isr_disable) -+#define qm_isr_disable_write(qm, v) __qm_isr_write(qm, qm_isr_disable, v) -+/* TODO: unfortunate name-clash here, reword? */ -+#define qm_isr_inhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 1) -+#define qm_isr_uninhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 0) -+ -+#ifdef CONFIG_FSL_QMAN_CONFIG -+int qman_have_ccsr(void); -+#else -+#define qman_have_ccsr 0 -+#endif -+ -+__init int qman_init(void); -+__init int qman_resource_init(void); -+ -+/* CEETM related */ -+#define QMAN_CEETM_MAX 2 -+extern u8 num_ceetms; -+extern struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX]; -+int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal); -+int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal); -+int qman_ceetm_set_prescaler(enum qm_dc_portal portal); -+int qman_ceetm_get_prescaler(u16 *pres); -+int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid, -+ struct qm_mcr_ceetm_cq_query *cq_query); -+int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query, -+ struct qm_mcr_ceetm_ccgr_query *response); -+int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num); -+ -+extern void *affine_portals[NR_CPUS]; -+const struct qm_portal_config *qman_get_qm_portal_config( -+ struct qman_portal *portal); -+ -+/* power management */ -+#ifdef CONFIG_SUSPEND -+void suspend_unused_qportal(void); -+void resume_unused_qportal(void); -+#endif ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_test.c -@@ -0,0 +1,57 @@ -+/* Copyright 2008-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "qman_test.h" -+ -+MODULE_AUTHOR("Geoff Thorpe"); -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("Qman testing"); -+ -+static int test_init(void) -+{ -+ int loop = 1; -+ while (loop--) { -+#ifdef CONFIG_FSL_QMAN_TEST_STASH_POTATO -+ qman_test_hotpotato(); -+#endif -+#ifdef CONFIG_FSL_QMAN_TEST_HIGH -+ qman_test_high(); -+#endif -+ } -+ return 0; -+} -+ -+static void test_exit(void) -+{ -+} -+ -+module_init(test_init); -+module_exit(test_exit); ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_test.h -@@ -0,0 +1,45 @@ -+/* Copyright 2008-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+void qman_test_hotpotato(void); -+void qman_test_high(void); -+ ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_test_high.c -@@ -0,0 +1,216 @@ -+/* Copyright 2008-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "qman_test.h" -+ -+/*************/ -+/* constants */ -+/*************/ -+ -+#define CGR_ID 27 -+#define POOL_ID 2 -+#define FQ_FLAGS QMAN_FQ_FLAG_DYNAMIC_FQID -+#define NUM_ENQUEUES 10 -+#define NUM_PARTIAL 4 -+#define PORTAL_SDQCR (QM_SDQCR_SOURCE_CHANNELS | \ -+ QM_SDQCR_TYPE_PRIO_QOS | \ -+ QM_SDQCR_TOKEN_SET(0x98) | \ -+ QM_SDQCR_CHANNELS_DEDICATED | \ -+ QM_SDQCR_CHANNELS_POOL(POOL_ID)) -+#define PORTAL_OPAQUE ((void *)0xf00dbeef) -+#define VDQCR_FLAGS (QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH) -+ -+/*************************************/ -+/* Predeclarations (eg. for fq_base) */ -+/*************************************/ -+ -+static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *, -+ struct qman_fq *, -+ const struct qm_dqrr_entry *); -+static void cb_ern(struct qman_portal *, struct qman_fq *, -+ const struct qm_mr_entry *); -+static void cb_fqs(struct qman_portal *, struct qman_fq *, -+ const struct qm_mr_entry *); -+ -+/***************/ -+/* global vars */ -+/***************/ -+ -+static struct qm_fd fd, fd_dq; -+static struct qman_fq fq_base = { -+ .cb.dqrr = cb_dqrr, -+ .cb.ern = cb_ern, -+ .cb.fqs = cb_fqs -+}; -+static DECLARE_WAIT_QUEUE_HEAD(waitqueue); -+static int retire_complete, sdqcr_complete; -+ -+/**********************/ -+/* internal functions */ -+/**********************/ -+ -+/* Helpers for initialising and "incrementing" a frame descriptor */ -+static void fd_init(struct qm_fd *__fd) -+{ -+ qm_fd_addr_set64(__fd, 0xabdeadbeefLLU); -+ __fd->format = qm_fd_contig_big; -+ __fd->length29 = 0x0000ffff; -+ __fd->cmd = 0xfeedf00d; -+} -+ -+static void fd_inc(struct qm_fd *__fd) -+{ -+ u64 t = qm_fd_addr_get64(__fd); -+ int z = t >> 40; -+ t <<= 1; -+ if (z) -+ t |= 1; -+ qm_fd_addr_set64(__fd, t); -+ __fd->length29--; -+ __fd->cmd++; -+} -+ -+/* The only part of the 'fd' we can't memcmp() is the ppid */ -+static int fd_cmp(const struct qm_fd *a, const struct qm_fd *b) -+{ -+ int r = (qm_fd_addr_get64(a) == qm_fd_addr_get64(b)) ? 0 : -1; -+ if (!r) -+ r = a->format - b->format; -+ if (!r) -+ r = a->opaque - b->opaque; -+ if (!r) -+ r = a->cmd - b->cmd; -+ return r; -+} -+ -+/********/ -+/* test */ -+/********/ -+ -+static void do_enqueues(struct qman_fq *fq) -+{ -+ unsigned int loop; -+ for (loop = 0; loop < NUM_ENQUEUES; loop++) { -+ if (qman_enqueue(fq, &fd, QMAN_ENQUEUE_FLAG_WAIT | -+ (((loop + 1) == NUM_ENQUEUES) ? -+ QMAN_ENQUEUE_FLAG_WAIT_SYNC : 0))) -+ panic("qman_enqueue() failed\n"); -+ fd_inc(&fd); -+ } -+} -+ -+void qman_test_high(void) -+{ -+ unsigned int flags; -+ int res; -+ struct qman_fq *fq = &fq_base; -+ -+ pr_info("qman_test_high starting\n"); -+ fd_init(&fd); -+ fd_init(&fd_dq); -+ -+ /* Initialise (parked) FQ */ -+ if (qman_create_fq(0, FQ_FLAGS, fq)) -+ panic("qman_create_fq() failed\n"); -+ if (qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, NULL)) -+ panic("qman_init_fq() failed\n"); -+ -+ /* Do enqueues + VDQCR, twice. (Parked FQ) */ -+ do_enqueues(fq); -+ pr_info("VDQCR (till-empty);\n"); -+ if (qman_volatile_dequeue(fq, VDQCR_FLAGS, -+ QM_VDQCR_NUMFRAMES_TILLEMPTY)) -+ panic("qman_volatile_dequeue() failed\n"); -+ do_enqueues(fq); -+ pr_info("VDQCR (%d of %d);\n", NUM_PARTIAL, NUM_ENQUEUES); -+ if (qman_volatile_dequeue(fq, VDQCR_FLAGS, -+ QM_VDQCR_NUMFRAMES_SET(NUM_PARTIAL))) -+ panic("qman_volatile_dequeue() failed\n"); -+ pr_info("VDQCR (%d of %d);\n", NUM_ENQUEUES - NUM_PARTIAL, -+ NUM_ENQUEUES); -+ if (qman_volatile_dequeue(fq, VDQCR_FLAGS, -+ QM_VDQCR_NUMFRAMES_SET(NUM_ENQUEUES - NUM_PARTIAL))) -+ panic("qman_volatile_dequeue() failed\n"); -+ -+ do_enqueues(fq); -+ pr_info("scheduled dequeue (till-empty)\n"); -+ if (qman_schedule_fq(fq)) -+ panic("qman_schedule_fq() failed\n"); -+ wait_event(waitqueue, sdqcr_complete); -+ -+ /* Retire and OOS the FQ */ -+ res = qman_retire_fq(fq, &flags); -+ if (res < 0) -+ panic("qman_retire_fq() failed\n"); -+ wait_event(waitqueue, retire_complete); -+ if (flags & QMAN_FQ_STATE_BLOCKOOS) -+ panic("leaking frames\n"); -+ if (qman_oos_fq(fq)) -+ panic("qman_oos_fq() failed\n"); -+ qman_destroy_fq(fq, 0); -+ pr_info("qman_test_high finished\n"); -+} -+ -+static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry *dq) -+{ -+ if (fd_cmp(&fd_dq, &dq->fd)) { -+ pr_err("BADNESS: dequeued frame doesn't match;\n"); -+ pr_err("Expected 0x%llx, got 0x%llx\n", -+ (unsigned long long)fd_dq.length29, -+ (unsigned long long)dq->fd.length29); -+ BUG(); -+ } -+ fd_inc(&fd_dq); -+ if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_cmp(&fd_dq, &fd)) { -+ sdqcr_complete = 1; -+ wake_up(&waitqueue); -+ } -+ return qman_cb_dqrr_consume; -+} -+ -+static void cb_ern(struct qman_portal *p, struct qman_fq *fq, -+ const struct qm_mr_entry *msg) -+{ -+ panic("cb_ern() unimplemented"); -+} -+ -+static void cb_fqs(struct qman_portal *p, struct qman_fq *fq, -+ const struct qm_mr_entry *msg) -+{ -+ u8 verb = (msg->verb & QM_MR_VERB_TYPE_MASK); -+ if ((verb != QM_MR_VERB_FQRN) && (verb != QM_MR_VERB_FQRNI)) -+ panic("unexpected FQS message"); -+ pr_info("Retirement message received\n"); -+ retire_complete = 1; -+ wake_up(&waitqueue); -+} ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_test_hotpotato.c -@@ -0,0 +1,502 @@ -+/* Copyright 2009-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include -+#include "qman_test.h" -+ -+/* Algorithm: -+ * -+ * Each cpu will have HP_PER_CPU "handlers" set up, each of which incorporates -+ * an rx/tx pair of FQ objects (both of which are stashed on dequeue). The -+ * organisation of FQIDs is such that the HP_PER_CPU*NUM_CPUS handlers will -+ * shuttle a "hot potato" frame around them such that every forwarding action -+ * moves it from one cpu to another. (The use of more than one handler per cpu -+ * is to allow enough handlers/FQs to truly test the significance of caching - -+ * ie. when cache-expiries are occurring.) -+ * -+ * The "hot potato" frame content will be HP_NUM_WORDS*4 bytes in size, and the -+ * first and last words of the frame data will undergo a transformation step on -+ * each forwarding action. To achieve this, each handler will be assigned a -+ * 32-bit "mixer", that is produced using a 32-bit LFSR. When a frame is -+ * received by a handler, the mixer of the expected sender is XOR'd into all -+ * words of the entire frame, which is then validated against the original -+ * values. Then, before forwarding, the entire frame is XOR'd with the mixer of -+ * the current handler. Apart from validating that the frame is taking the -+ * expected path, this also provides some quasi-realistic overheads to each -+ * forwarding action - dereferencing *all* the frame data, computation, and -+ * conditional branching. There is a "special" handler designated to act as the -+ * instigator of the test by creating an enqueuing the "hot potato" frame, and -+ * to determine when the test has completed by counting HP_LOOPS iterations. -+ * -+ * Init phases: -+ * -+ * 1. prepare each cpu's 'hp_cpu' struct using on_each_cpu(,,1) and link them -+ * into 'hp_cpu_list'. Specifically, set processor_id, allocate HP_PER_CPU -+ * handlers and link-list them (but do no other handler setup). -+ * -+ * 2. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each -+ * hp_cpu's 'iterator' to point to its first handler. With each loop, -+ * allocate rx/tx FQIDs and mixer values to the hp_cpu's iterator handler -+ * and advance the iterator for the next loop. This includes a final fixup, -+ * which connects the last handler to the first (and which is why phase 2 -+ * and 3 are separate). -+ * -+ * 3. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each -+ * hp_cpu's 'iterator' to point to its first handler. With each loop, -+ * initialise FQ objects and advance the iterator for the next loop. -+ * Moreover, do this initialisation on the cpu it applies to so that Rx FQ -+ * initialisation targets the correct cpu. -+ */ -+ -+/* helper to run something on all cpus (can't use on_each_cpu(), as that invokes -+ * the fn from irq context, which is too restrictive). */ -+struct bstrap { -+ void (*fn)(void); -+ atomic_t started; -+}; -+static int bstrap_fn(void *__bstrap) -+{ -+ struct bstrap *bstrap = __bstrap; -+ atomic_inc(&bstrap->started); -+ bstrap->fn(); -+ while (!kthread_should_stop()) -+ msleep(1); -+ return 0; -+} -+static int on_all_cpus(void (*fn)(void)) -+{ -+ int cpu; -+ for_each_cpu(cpu, cpu_online_mask) { -+ struct bstrap bstrap = { -+ .fn = fn, -+ .started = ATOMIC_INIT(0) -+ }; -+ struct task_struct *k = kthread_create(bstrap_fn, &bstrap, -+ "hotpotato%d", cpu); -+ int ret; -+ if (IS_ERR(k)) -+ return -ENOMEM; -+ kthread_bind(k, cpu); -+ wake_up_process(k); -+ /* If we call kthread_stop() before the "wake up" has had an -+ * effect, then the thread may exit with -EINTR without ever -+ * running the function. So poll until it's started before -+ * requesting it to stop. */ -+ while (!atomic_read(&bstrap.started)) -+ msleep(10); -+ ret = kthread_stop(k); -+ if (ret) -+ return ret; -+ } -+ return 0; -+} -+ -+struct hp_handler { -+ -+ /* The following data is stashed when 'rx' is dequeued; */ -+ /* -------------- */ -+ /* The Rx FQ, dequeues of which will stash the entire hp_handler */ -+ struct qman_fq rx; -+ /* The Tx FQ we should forward to */ -+ struct qman_fq tx; -+ /* The value we XOR post-dequeue, prior to validating */ -+ u32 rx_mixer; -+ /* The value we XOR pre-enqueue, after validating */ -+ u32 tx_mixer; -+ /* what the hotpotato address should be on dequeue */ -+ dma_addr_t addr; -+ u32 *frame_ptr; -+ -+ /* The following data isn't (necessarily) stashed on dequeue; */ -+ /* -------------- */ -+ u32 fqid_rx, fqid_tx; -+ /* list node for linking us into 'hp_cpu' */ -+ struct list_head node; -+ /* Just to check ... */ -+ unsigned int processor_id; -+} ____cacheline_aligned; -+ -+struct hp_cpu { -+ /* identify the cpu we run on; */ -+ unsigned int processor_id; -+ /* root node for the per-cpu list of handlers */ -+ struct list_head handlers; -+ /* list node for linking us into 'hp_cpu_list' */ -+ struct list_head node; -+ /* when repeatedly scanning 'hp_list', each time linking the n'th -+ * handlers together, this is used as per-cpu iterator state */ -+ struct hp_handler *iterator; -+}; -+ -+/* Each cpu has one of these */ -+static DEFINE_PER_CPU(struct hp_cpu, hp_cpus); -+ -+/* links together the hp_cpu structs, in first-come first-serve order. */ -+static LIST_HEAD(hp_cpu_list); -+static spinlock_t hp_lock = __SPIN_LOCK_UNLOCKED(hp_lock); -+ -+static unsigned int hp_cpu_list_length; -+ -+/* the "special" handler, that starts and terminates the test. */ -+static struct hp_handler *special_handler; -+static int loop_counter; -+ -+/* handlers are allocated out of this, so they're properly aligned. */ -+static struct kmem_cache *hp_handler_slab; -+ -+/* this is the frame data */ -+static void *__frame_ptr; -+static u32 *frame_ptr; -+static dma_addr_t frame_dma; -+ -+/* the main function waits on this */ -+static DECLARE_WAIT_QUEUE_HEAD(queue); -+ -+#define HP_PER_CPU 2 -+#define HP_LOOPS 8 -+/* 80 bytes, like a small ethernet frame, and bleeds into a second cacheline */ -+#define HP_NUM_WORDS 80 -+/* First word of the LFSR-based frame data */ -+#define HP_FIRST_WORD 0xabbaf00d -+ -+static inline u32 do_lfsr(u32 prev) -+{ -+ return (prev >> 1) ^ (-(prev & 1u) & 0xd0000001u); -+} -+ -+static void allocate_frame_data(void) -+{ -+ u32 lfsr = HP_FIRST_WORD; -+ int loop; -+ struct platform_device *pdev = platform_device_alloc("foobar", -1); -+ if (!pdev) -+ panic("platform_device_alloc() failed"); -+ if (platform_device_add(pdev)) -+ panic("platform_device_add() failed"); -+ __frame_ptr = kmalloc(4 * HP_NUM_WORDS, GFP_KERNEL); -+ if (!__frame_ptr) -+ panic("kmalloc() failed"); -+ frame_ptr = (void *)(((unsigned long)__frame_ptr + 63) & -+ ~(unsigned long)63); -+ for (loop = 0; loop < HP_NUM_WORDS; loop++) { -+ frame_ptr[loop] = lfsr; -+ lfsr = do_lfsr(lfsr); -+ } -+ frame_dma = dma_map_single(&pdev->dev, frame_ptr, 4 * HP_NUM_WORDS, -+ DMA_BIDIRECTIONAL); -+ platform_device_del(pdev); -+ platform_device_put(pdev); -+} -+ -+static void deallocate_frame_data(void) -+{ -+ kfree(__frame_ptr); -+} -+ -+static inline void process_frame_data(struct hp_handler *handler, -+ const struct qm_fd *fd) -+{ -+ u32 *p = handler->frame_ptr; -+ u32 lfsr = HP_FIRST_WORD; -+ int loop; -+ if (qm_fd_addr_get64(fd) != (handler->addr & 0xffffffffff)) { -+ pr_err("Got 0x%llx expected 0x%llx\n", -+ qm_fd_addr_get64(fd), handler->addr); -+ panic("bad frame address"); -+ } -+ for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) { -+ *p ^= handler->rx_mixer; -+ if (*p != lfsr) -+ panic("corrupt frame data"); -+ *p ^= handler->tx_mixer; -+ lfsr = do_lfsr(lfsr); -+ } -+} -+ -+static enum qman_cb_dqrr_result normal_dqrr(struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry *dqrr) -+{ -+ struct hp_handler *handler = (struct hp_handler *)fq; -+ -+ process_frame_data(handler, &dqrr->fd); -+ if (qman_enqueue(&handler->tx, &dqrr->fd, 0)) -+ panic("qman_enqueue() failed"); -+ return qman_cb_dqrr_consume; -+} -+ -+static enum qman_cb_dqrr_result special_dqrr(struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry *dqrr) -+{ -+ struct hp_handler *handler = (struct hp_handler *)fq; -+ -+ process_frame_data(handler, &dqrr->fd); -+ if (++loop_counter < HP_LOOPS) { -+ if (qman_enqueue(&handler->tx, &dqrr->fd, 0)) -+ panic("qman_enqueue() failed"); -+ } else { -+ pr_info("Received final (%dth) frame\n", loop_counter); -+ wake_up(&queue); -+ } -+ return qman_cb_dqrr_consume; -+} -+ -+static void create_per_cpu_handlers(void) -+{ -+ struct hp_handler *handler; -+ int loop; -+ struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus); -+ -+ hp_cpu->processor_id = smp_processor_id(); -+ spin_lock(&hp_lock); -+ list_add_tail(&hp_cpu->node, &hp_cpu_list); -+ hp_cpu_list_length++; -+ spin_unlock(&hp_lock); -+ INIT_LIST_HEAD(&hp_cpu->handlers); -+ for (loop = 0; loop < HP_PER_CPU; loop++) { -+ handler = kmem_cache_alloc(hp_handler_slab, GFP_KERNEL); -+ if (!handler) -+ panic("kmem_cache_alloc() failed"); -+ handler->processor_id = hp_cpu->processor_id; -+ handler->addr = frame_dma; -+ handler->frame_ptr = frame_ptr; -+ list_add_tail(&handler->node, &hp_cpu->handlers); -+ } -+ put_cpu_var(hp_cpus); -+} -+ -+static void destroy_per_cpu_handlers(void) -+{ -+ struct list_head *loop, *tmp; -+ struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus); -+ -+ spin_lock(&hp_lock); -+ list_del(&hp_cpu->node); -+ spin_unlock(&hp_lock); -+ list_for_each_safe(loop, tmp, &hp_cpu->handlers) { -+ u32 flags; -+ struct hp_handler *handler = list_entry(loop, struct hp_handler, -+ node); -+ if (qman_retire_fq(&handler->rx, &flags)) -+ panic("qman_retire_fq(rx) failed"); -+ BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS); -+ if (qman_oos_fq(&handler->rx)) -+ panic("qman_oos_fq(rx) failed"); -+ qman_destroy_fq(&handler->rx, 0); -+ qman_destroy_fq(&handler->tx, 0); -+ qman_release_fqid(handler->fqid_rx); -+ list_del(&handler->node); -+ kmem_cache_free(hp_handler_slab, handler); -+ } -+ put_cpu_var(hp_cpus); -+} -+ -+static inline u8 num_cachelines(u32 offset) -+{ -+ u8 res = (offset + (L1_CACHE_BYTES - 1)) -+ / (L1_CACHE_BYTES); -+ if (res > 3) -+ return 3; -+ return res; -+} -+#define STASH_DATA_CL \ -+ num_cachelines(HP_NUM_WORDS * 4) -+#define STASH_CTX_CL \ -+ num_cachelines(offsetof(struct hp_handler, fqid_rx)) -+ -+static void init_handler(void *__handler) -+{ -+ struct qm_mcc_initfq opts; -+ struct hp_handler *handler = __handler; -+ BUG_ON(handler->processor_id != smp_processor_id()); -+ /* Set up rx */ -+ memset(&handler->rx, 0, sizeof(handler->rx)); -+ if (handler == special_handler) -+ handler->rx.cb.dqrr = special_dqrr; -+ else -+ handler->rx.cb.dqrr = normal_dqrr; -+ if (qman_create_fq(handler->fqid_rx, 0, &handler->rx)) -+ panic("qman_create_fq(rx) failed"); -+ memset(&opts, 0, sizeof(opts)); -+ opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_CONTEXTA; -+ opts.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING; -+ opts.fqd.context_a.stashing.data_cl = STASH_DATA_CL; -+ opts.fqd.context_a.stashing.context_cl = STASH_CTX_CL; -+ if (qman_init_fq(&handler->rx, QMAN_INITFQ_FLAG_SCHED | -+ QMAN_INITFQ_FLAG_LOCAL, &opts)) -+ panic("qman_init_fq(rx) failed"); -+ /* Set up tx */ -+ memset(&handler->tx, 0, sizeof(handler->tx)); -+ if (qman_create_fq(handler->fqid_tx, QMAN_FQ_FLAG_NO_MODIFY, -+ &handler->tx)) -+ panic("qman_create_fq(tx) failed"); -+} -+ -+static void init_phase2(void) -+{ -+ int loop; -+ u32 fqid = 0; -+ u32 lfsr = 0xdeadbeef; -+ struct hp_cpu *hp_cpu; -+ struct hp_handler *handler; -+ -+ for (loop = 0; loop < HP_PER_CPU; loop++) { -+ list_for_each_entry(hp_cpu, &hp_cpu_list, node) { -+ int ret; -+ if (!loop) -+ hp_cpu->iterator = list_first_entry( -+ &hp_cpu->handlers, -+ struct hp_handler, node); -+ else -+ hp_cpu->iterator = list_entry( -+ hp_cpu->iterator->node.next, -+ struct hp_handler, node); -+ /* Rx FQID is the previous handler's Tx FQID */ -+ hp_cpu->iterator->fqid_rx = fqid; -+ /* Allocate new FQID for Tx */ -+ ret = qman_alloc_fqid(&fqid); -+ if (ret) -+ panic("qman_alloc_fqid() failed"); -+ hp_cpu->iterator->fqid_tx = fqid; -+ /* Rx mixer is the previous handler's Tx mixer */ -+ hp_cpu->iterator->rx_mixer = lfsr; -+ /* Get new mixer for Tx */ -+ lfsr = do_lfsr(lfsr); -+ hp_cpu->iterator->tx_mixer = lfsr; -+ } -+ } -+ /* Fix up the first handler (fqid_rx==0, rx_mixer=0xdeadbeef) */ -+ hp_cpu = list_first_entry(&hp_cpu_list, struct hp_cpu, node); -+ handler = list_first_entry(&hp_cpu->handlers, struct hp_handler, node); -+ BUG_ON((handler->fqid_rx != 0) || (handler->rx_mixer != 0xdeadbeef)); -+ handler->fqid_rx = fqid; -+ handler->rx_mixer = lfsr; -+ /* and tag it as our "special" handler */ -+ special_handler = handler; -+} -+ -+static void init_phase3(void) -+{ -+ int loop; -+ struct hp_cpu *hp_cpu; -+ -+ for (loop = 0; loop < HP_PER_CPU; loop++) { -+ list_for_each_entry(hp_cpu, &hp_cpu_list, node) { -+ if (!loop) -+ hp_cpu->iterator = list_first_entry( -+ &hp_cpu->handlers, -+ struct hp_handler, node); -+ else -+ hp_cpu->iterator = list_entry( -+ hp_cpu->iterator->node.next, -+ struct hp_handler, node); -+ preempt_disable(); -+ if (hp_cpu->processor_id == smp_processor_id()) -+ init_handler(hp_cpu->iterator); -+ else -+ smp_call_function_single(hp_cpu->processor_id, -+ init_handler, hp_cpu->iterator, 1); -+ preempt_enable(); -+ } -+ } -+} -+ -+static void send_first_frame(void *ignore) -+{ -+ u32 *p = special_handler->frame_ptr; -+ u32 lfsr = HP_FIRST_WORD; -+ int loop; -+ struct qm_fd fd; -+ -+ BUG_ON(special_handler->processor_id != smp_processor_id()); -+ memset(&fd, 0, sizeof(fd)); -+ qm_fd_addr_set64(&fd, special_handler->addr); -+ fd.format = qm_fd_contig_big; -+ fd.length29 = HP_NUM_WORDS * 4; -+ for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) { -+ if (*p != lfsr) -+ panic("corrupt frame data"); -+ *p ^= special_handler->tx_mixer; -+ lfsr = do_lfsr(lfsr); -+ } -+ pr_info("Sending first frame\n"); -+ if (qman_enqueue(&special_handler->tx, &fd, 0)) -+ panic("qman_enqueue() failed"); -+} -+ -+void qman_test_hotpotato(void) -+{ -+ if (cpumask_weight(cpu_online_mask) < 2) { -+ pr_info("qman_test_hotpotato, skip - only 1 CPU\n"); -+ return; -+ } -+ -+ pr_info("qman_test_hotpotato starting\n"); -+ -+ hp_cpu_list_length = 0; -+ loop_counter = 0; -+ hp_handler_slab = kmem_cache_create("hp_handler_slab", -+ sizeof(struct hp_handler), L1_CACHE_BYTES, -+ SLAB_HWCACHE_ALIGN, NULL); -+ if (!hp_handler_slab) -+ panic("kmem_cache_create() failed"); -+ -+ allocate_frame_data(); -+ -+ /* Init phase 1 */ -+ pr_info("Creating %d handlers per cpu...\n", HP_PER_CPU); -+ if (on_all_cpus(create_per_cpu_handlers)) -+ panic("on_each_cpu() failed"); -+ pr_info("Number of cpus: %d, total of %d handlers\n", -+ hp_cpu_list_length, hp_cpu_list_length * HP_PER_CPU); -+ -+ init_phase2(); -+ -+ init_phase3(); -+ -+ preempt_disable(); -+ if (special_handler->processor_id == smp_processor_id()) -+ send_first_frame(NULL); -+ else -+ smp_call_function_single(special_handler->processor_id, -+ send_first_frame, NULL, 1); -+ preempt_enable(); -+ -+ wait_event(queue, loop_counter == HP_LOOPS); -+ deallocate_frame_data(); -+ if (on_all_cpus(destroy_per_cpu_handlers)) -+ panic("on_each_cpu() failed"); -+ kmem_cache_destroy(hp_handler_slab); -+ pr_info("qman_test_hotpotato finished\n"); -+} ---- /dev/null -+++ b/drivers/staging/fsl_qbman/qman_utility.c -@@ -0,0 +1,129 @@ -+/* Copyright 2008-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "qman_private.h" -+ -+/* ----------------- */ -+/* --- FQID Pool --- */ -+ -+struct qman_fqid_pool { -+ /* Base and size of the FQID range */ -+ u32 fqid_base; -+ u32 total; -+ /* Number of FQIDs currently "allocated" */ -+ u32 used; -+ /* Allocation optimisation. When 'usedfqid_base = fqid_start; -+ pool->total = num; -+ pool->used = 0; -+ pool->next = 0; -+ pool->bits = kzalloc(QNUM_BYTES(num), GFP_KERNEL); -+ if (!pool->bits) { -+ kfree(pool); -+ return NULL; -+ } -+ /* If num is not an even multiple of QLONG_BITS (or even 8, for -+ * byte-oriented searching) then we fill the trailing bits with 1, to -+ * make them look allocated (permanently). */ -+ for (i = num + 1; i < QNUM_BITS(num); i++) -+ set_bit(i, pool->bits); -+ return pool; -+} -+EXPORT_SYMBOL(qman_fqid_pool_create); -+ -+int qman_fqid_pool_destroy(struct qman_fqid_pool *pool) -+{ -+ int ret = pool->used; -+ kfree(pool->bits); -+ kfree(pool); -+ return ret; -+} -+EXPORT_SYMBOL(qman_fqid_pool_destroy); -+ -+int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid) -+{ -+ int ret; -+ if (pool->used == pool->total) -+ return -ENOMEM; -+ *fqid = pool->fqid_base + pool->next; -+ ret = test_and_set_bit(pool->next, pool->bits); -+ BUG_ON(ret); -+ if (++pool->used == pool->total) -+ return 0; -+ pool->next = find_next_zero_bit(pool->bits, pool->total, pool->next); -+ if (pool->next >= pool->total) -+ pool->next = find_first_zero_bit(pool->bits, pool->total); -+ BUG_ON(pool->next >= pool->total); -+ return 0; -+} -+EXPORT_SYMBOL(qman_fqid_pool_alloc); -+ -+void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid) -+{ -+ int ret; -+ -+ fqid -= pool->fqid_base; -+ ret = test_and_clear_bit(fqid, pool->bits); -+ BUG_ON(!ret); -+ if (pool->used-- == pool->total) -+ pool->next = fqid; -+} -+EXPORT_SYMBOL(qman_fqid_pool_free); -+ -+u32 qman_fqid_pool_used(struct qman_fqid_pool *pool) -+{ -+ return pool->used; -+} -+EXPORT_SYMBOL(qman_fqid_pool_used); ---- /dev/null -+++ b/include/linux/fsl_bman.h -@@ -0,0 +1,532 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef FSL_BMAN_H -+#define FSL_BMAN_H -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* Last updated for v00.79 of the BG */ -+ -+/* Portal processing (interrupt) sources */ -+#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */ -+#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */ -+ -+/* This wrapper represents a bit-array for the depletion state of the 64 Bman -+ * buffer pools. */ -+struct bman_depletion { -+ u32 __state[2]; -+}; -+#define BMAN_DEPLETION_EMPTY { { 0x00000000, 0x00000000 } } -+#define BMAN_DEPLETION_FULL { { 0xffffffff, 0xffffffff } } -+#define __bmdep_word(x) ((x) >> 5) -+#define __bmdep_shift(x) ((x) & 0x1f) -+#define __bmdep_bit(x) (0x80000000 >> __bmdep_shift(x)) -+static inline void bman_depletion_init(struct bman_depletion *c) -+{ -+ c->__state[0] = c->__state[1] = 0; -+} -+static inline void bman_depletion_fill(struct bman_depletion *c) -+{ -+ c->__state[0] = c->__state[1] = ~0; -+} -+static inline int bman_depletion_get(const struct bman_depletion *c, u8 bpid) -+{ -+ return c->__state[__bmdep_word(bpid)] & __bmdep_bit(bpid); -+} -+static inline void bman_depletion_set(struct bman_depletion *c, u8 bpid) -+{ -+ c->__state[__bmdep_word(bpid)] |= __bmdep_bit(bpid); -+} -+static inline void bman_depletion_unset(struct bman_depletion *c, u8 bpid) -+{ -+ c->__state[__bmdep_word(bpid)] &= ~__bmdep_bit(bpid); -+} -+ -+/* ------------------------------------------------------- */ -+/* --- Bman data structures (and associated constants) --- */ -+ -+/* Represents s/w corenet portal mapped data structures */ -+struct bm_rcr_entry; /* RCR (Release Command Ring) entries */ -+struct bm_mc_command; /* MC (Management Command) command */ -+struct bm_mc_result; /* MC result */ -+ -+/* Code-reduction, define a wrapper for 48-bit buffers. In cases where a buffer -+ * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI, -+ * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used. */ -+struct bm_buffer { -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 __reserved1; -+ u8 bpid; -+ u16 hi; /* High 16-bits of 48-bit address */ -+ u32 lo; /* Low 32-bits of 48-bit address */ -+#else -+ u32 lo; -+ u16 hi; -+ u8 bpid; -+ u8 __reserved; -+#endif -+ }; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u64 __notaddress:16; -+ u64 addr:48; -+#else -+ u64 addr:48; -+ u64 __notaddress:16; -+#endif -+ }; -+ u64 opaque; -+ }; -+} __aligned(8); -+static inline u64 bm_buffer_get64(const struct bm_buffer *buf) -+{ -+ return buf->addr; -+} -+static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf) -+{ -+ return (dma_addr_t)buf->addr; -+} -+/* Macro, so we compile better if 'v' isn't always 64-bit */ -+#define bm_buffer_set64(buf, v) \ -+ do { \ -+ struct bm_buffer *__buf931 = (buf); \ -+ __buf931->hi = upper_32_bits(v); \ -+ __buf931->lo = lower_32_bits(v); \ -+ } while (0) -+ -+/* See 1.5.3.5.4: "Release Command" */ -+struct bm_rcr_entry { -+ union { -+ struct { -+ u8 __dont_write_directly__verb; -+ u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */ -+ u8 __reserved1[62]; -+ }; -+ struct bm_buffer bufs[8]; -+ }; -+} __packed; -+#define BM_RCR_VERB_VBIT 0x80 -+#define BM_RCR_VERB_CMD_MASK 0x70 /* one of two values; */ -+#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20 -+#define BM_RCR_VERB_CMD_BPID_MULTI 0x30 -+#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f /* values 1..8 */ -+ -+/* See 1.5.3.1: "Acquire Command" */ -+/* See 1.5.3.2: "Query Command" */ -+struct bm_mcc_acquire { -+ u8 bpid; -+ u8 __reserved1[62]; -+} __packed; -+struct bm_mcc_query { -+ u8 __reserved2[63]; -+} __packed; -+struct bm_mc_command { -+ u8 __dont_write_directly__verb; -+ union { -+ struct bm_mcc_acquire acquire; -+ struct bm_mcc_query query; -+ }; -+} __packed; -+#define BM_MCC_VERB_VBIT 0x80 -+#define BM_MCC_VERB_CMD_MASK 0x70 /* where the verb contains; */ -+#define BM_MCC_VERB_CMD_ACQUIRE 0x10 -+#define BM_MCC_VERB_CMD_QUERY 0x40 -+#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f /* values 1..8 go here */ -+ -+/* See 1.5.3.3: "Acquire Response" */ -+/* See 1.5.3.4: "Query Response" */ -+struct bm_pool_state { -+ u8 __reserved1[32]; -+ /* "availability state" and "depletion state" */ -+ struct { -+ u8 __reserved1[8]; -+ /* Access using bman_depletion_***() */ -+ struct bman_depletion state; -+ } as, ds; -+}; -+struct bm_mc_result { -+ union { -+ struct { -+ u8 verb; -+ u8 __reserved1[63]; -+ }; -+ union { -+ struct { -+ u8 __reserved1; -+ u8 bpid; -+ u8 __reserved2[62]; -+ }; -+ struct bm_buffer bufs[8]; -+ } acquire; -+ struct bm_pool_state query; -+ }; -+} __packed; -+#define BM_MCR_VERB_VBIT 0x80 -+#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK -+#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE -+#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY -+#define BM_MCR_VERB_CMD_ERR_INVALID 0x60 -+#define BM_MCR_VERB_CMD_ERR_ECC 0x70 -+#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */ -+/* Determine the "availability state" of pool 'p' from a query result 'r' */ -+#define BM_MCR_QUERY_AVAILABILITY(r, p) \ -+ bman_depletion_get(&r->query.as.state, p) -+/* Determine the "depletion state" of pool 'p' from a query result 'r' */ -+#define BM_MCR_QUERY_DEPLETION(r, p) \ -+ bman_depletion_get(&r->query.ds.state, p) -+ -+/*******************************************************************/ -+/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */ -+/*******************************************************************/ -+ -+ /* Portal and Buffer Pools */ -+ /* ----------------------- */ -+/* Represents a managed portal */ -+struct bman_portal; -+ -+/* This object type represents Bman buffer pools. */ -+struct bman_pool; -+ -+struct bman_portal_config { -+ /* This is used for any "core-affine" portals, ie. default portals -+ * associated to the corresponding cpu. -1 implies that there is no core -+ * affinity configured. */ -+ int cpu; -+ /* portal interrupt line */ -+ int irq; -+ /* the unique index of this portal */ -+ u32 index; -+ /* Is this portal shared? (If so, it has coarser locking and demuxes -+ * processing on behalf of other CPUs.) */ -+ int is_shared; -+ /* These are the buffer pool IDs that may be used via this portal. */ -+ struct bman_depletion mask; -+}; -+ -+/* This callback type is used when handling pool depletion entry/exit. The -+ * 'cb_ctx' value is the opaque value associated with the pool object in -+ * bman_new_pool(). 'depleted' is non-zero on depletion-entry, and zero on -+ * depletion-exit. */ -+typedef void (*bman_cb_depletion)(struct bman_portal *bm, -+ struct bman_pool *pool, void *cb_ctx, int depleted); -+ -+/* This struct specifies parameters for a bman_pool object. */ -+struct bman_pool_params { -+ /* index of the buffer pool to encapsulate (0-63), ignored if -+ * BMAN_POOL_FLAG_DYNAMIC_BPID is set. */ -+ u32 bpid; -+ /* bit-mask of BMAN_POOL_FLAG_*** options */ -+ u32 flags; -+ /* depletion-entry/exit callback, if BMAN_POOL_FLAG_DEPLETION is set */ -+ bman_cb_depletion cb; -+ /* opaque user value passed as a parameter to 'cb' */ -+ void *cb_ctx; -+ /* depletion-entry/exit thresholds, if BMAN_POOL_FLAG_THRESH is set. NB: -+ * this is only allowed if BMAN_POOL_FLAG_DYNAMIC_BPID is used *and* -+ * when run in the control plane (which controls Bman CCSR). This array -+ * matches the definition of bm_pool_set(). */ -+ u32 thresholds[4]; -+}; -+ -+/* Flags to bman_new_pool() */ -+#define BMAN_POOL_FLAG_NO_RELEASE 0x00000001 /* can't release to pool */ -+#define BMAN_POOL_FLAG_ONLY_RELEASE 0x00000002 /* can only release to pool */ -+#define BMAN_POOL_FLAG_DEPLETION 0x00000004 /* track depletion entry/exit */ -+#define BMAN_POOL_FLAG_DYNAMIC_BPID 0x00000008 /* (de)allocate bpid */ -+#define BMAN_POOL_FLAG_THRESH 0x00000010 /* set depletion thresholds */ -+#define BMAN_POOL_FLAG_STOCKPILE 0x00000020 /* stockpile to reduce hw ops */ -+ -+/* Flags to bman_release() */ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+#define BMAN_RELEASE_FLAG_WAIT 0x00000001 /* wait if RCR is full */ -+#define BMAN_RELEASE_FLAG_WAIT_INT 0x00000002 /* if we wait, interruptible? */ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+#define BMAN_RELEASE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */ -+#endif -+#endif -+#define BMAN_RELEASE_FLAG_NOW 0x00000008 /* issue immediate release */ -+ -+/* Flags to bman_acquire() */ -+#define BMAN_ACQUIRE_FLAG_STOCKPILE 0x00000001 /* no hw op, stockpile only */ -+ -+ /* Portal Management */ -+ /* ----------------- */ -+/** -+ * bman_get_portal_config - get portal configuration settings -+ * -+ * This returns a read-only view of the current cpu's affine portal settings. -+ */ -+const struct bman_portal_config *bman_get_portal_config(void); -+ -+/** -+ * bman_irqsource_get - return the portal work that is interrupt-driven -+ * -+ * Returns a bitmask of BM_PIRQ_**I processing sources that are currently -+ * enabled for interrupt handling on the current cpu's affine portal. These -+ * sources will trigger the portal interrupt and the interrupt handler (or a -+ * tasklet/bottom-half it defers to) will perform the corresponding processing -+ * work. The bman_poll_***() functions will only process sources that are not in -+ * this bitmask. If the current CPU is sharing a portal hosted on another CPU, -+ * this always returns zero. -+ */ -+u32 bman_irqsource_get(void); -+ -+/** -+ * bman_irqsource_add - add processing sources to be interrupt-driven -+ * @bits: bitmask of BM_PIRQ_**I processing sources -+ * -+ * Adds processing sources that should be interrupt-driven (rather than -+ * processed via bman_poll_***() functions). Returns zero for success, or -+ * -EINVAL if the current CPU is sharing a portal hosted on another CPU. */ -+int bman_irqsource_add(u32 bits); -+ -+/** -+ * bman_irqsource_remove - remove processing sources from being interrupt-driven -+ * @bits: bitmask of BM_PIRQ_**I processing sources -+ * -+ * Removes processing sources from being interrupt-driven, so that they will -+ * instead be processed via bman_poll_***() functions. Returns zero for success, -+ * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. */ -+int bman_irqsource_remove(u32 bits); -+ -+/** -+ * bman_affine_cpus - return a mask of cpus that have affine portals -+ */ -+const cpumask_t *bman_affine_cpus(void); -+ -+/** -+ * bman_poll_slow - process anything that isn't interrupt-driven. -+ * -+ * This function does any portal processing that isn't interrupt-driven. If the -+ * current CPU is sharing a portal hosted on another CPU, this function will -+ * return -EINVAL, otherwise the return value is a bitmask of BM_PIRQ_* sources -+ * indicating what interrupt sources were actually processed by the call. -+ * -+ * NB, unlike the legacy wrapper bman_poll(), this function will -+ * deterministically check for the presence of portal processing work and do it, -+ * which implies some latency even if there's nothing to do. The bman_poll() -+ * wrapper on the other hand (like the qman_poll() wrapper) attenuates this by -+ * checking for (and doing) portal processing infrequently. Ie. such that -+ * qman_poll() and bman_poll() can be called from core-processing loops. Use -+ * bman_poll_slow() when you yourself are deciding when to incur the overhead of -+ * processing. -+ */ -+u32 bman_poll_slow(void); -+ -+/** -+ * bman_poll - process anything that isn't interrupt-driven. -+ * -+ * Dispatcher logic on a cpu can use this to trigger any maintenance of the -+ * affine portal. This function does whatever processing is not triggered by -+ * interrupts. This is a legacy wrapper that can be used in core-processing -+ * loops but mitigates the performance overhead of portal processing by -+ * adaptively bypassing true portal processing most of the time. (Processing is -+ * done once every 10 calls if the previous processing revealed that work needed -+ * to be done, or once very 1000 calls if the previous processing revealed no -+ * work needed doing.) If you wish to control this yourself, call -+ * bman_poll_slow() instead, which always checks for portal processing work. -+ */ -+void bman_poll(void); -+ -+/** -+ * bman_rcr_is_empty - Determine if portal's RCR is empty -+ * -+ * For use in situations where a cpu-affine caller needs to determine when all -+ * releases for the local portal have been processed by Bman but can't use the -+ * BMAN_RELEASE_FLAG_WAIT_SYNC flag to do this from the final bman_release(). -+ * The function forces tracking of RCR consumption (which normally doesn't -+ * happen until release processing needs to find space to put new release -+ * commands), and returns zero if the ring still has unprocessed entries, -+ * non-zero if it is empty. -+ */ -+int bman_rcr_is_empty(void); -+ -+/** -+ * bman_alloc_bpid_range - Allocate a contiguous range of BPIDs -+ * @result: is set by the API to the base BPID of the allocated range -+ * @count: the number of BPIDs required -+ * @align: required alignment of the allocated range -+ * @partial: non-zero if the API can return fewer than @count BPIDs -+ * -+ * Returns the number of buffer pools allocated, or a negative error code. If -+ * @partial is non zero, the allocation request may return a smaller range of -+ * BPs than requested (though alignment will be as requested). If @partial is -+ * zero, the return value will either be 'count' or negative. -+ */ -+int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial); -+static inline int bman_alloc_bpid(u32 *result) -+{ -+ int ret = bman_alloc_bpid_range(result, 1, 0, 0); -+ return (ret > 0) ? 0 : ret; -+} -+ -+/** -+ * bman_release_bpid_range - Release the specified range of buffer pool IDs -+ * @bpid: the base BPID of the range to deallocate -+ * @count: the number of BPIDs in the range -+ * -+ * This function can also be used to seed the allocator with ranges of BPIDs -+ * that it can subsequently allocate from. -+ */ -+void bman_release_bpid_range(u32 bpid, unsigned int count); -+static inline void bman_release_bpid(u32 bpid) -+{ -+ bman_release_bpid_range(bpid, 1); -+} -+ -+int bman_reserve_bpid_range(u32 bpid, unsigned int count); -+static inline int bman_reserve_bpid(u32 bpid) -+{ -+ return bman_reserve_bpid_range(bpid, 1); -+} -+ -+void bman_seed_bpid_range(u32 bpid, unsigned int count); -+ -+ -+int bman_shutdown_pool(u32 bpid); -+ -+ /* Pool management */ -+ /* --------------- */ -+/** -+ * bman_new_pool - Allocates a Buffer Pool object -+ * @params: parameters specifying the buffer pool ID and behaviour -+ * -+ * Creates a pool object for the given @params. A portal and the depletion -+ * callback field of @params are only used if the BMAN_POOL_FLAG_DEPLETION flag -+ * is set. NB, the fields from @params are copied into the new pool object, so -+ * the structure provided by the caller can be released or reused after the -+ * function returns. -+ */ -+struct bman_pool *bman_new_pool(const struct bman_pool_params *params); -+ -+/** -+ * bman_free_pool - Deallocates a Buffer Pool object -+ * @pool: the pool object to release -+ * -+ */ -+void bman_free_pool(struct bman_pool *pool); -+ -+/** -+ * bman_get_params - Returns a pool object's parameters. -+ * @pool: the pool object -+ * -+ * The returned pointer refers to state within the pool object so must not be -+ * modified and can no longer be read once the pool object is destroyed. -+ */ -+const struct bman_pool_params *bman_get_params(const struct bman_pool *pool); -+ -+/** -+ * bman_release - Release buffer(s) to the buffer pool -+ * @pool: the buffer pool object to release to -+ * @bufs: an array of buffers to release -+ * @num: the number of buffers in @bufs (1-8) -+ * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options -+ * -+ * Adds the given buffers to RCR entries. If the portal @p was created with the -+ * "COMPACT" flag, then it will be using a compaction algorithm to improve -+ * utilisation of RCR. As such, these buffers may join an existing ring entry -+ * and/or it may not be issued right away so as to allow future releases to join -+ * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this -+ * behaviour by committing the RCR entry (or entries) right away. If the RCR -+ * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT -+ * is selected, in which case it will sleep waiting for space to become -+ * available in RCR. If the function receives a signal before such time (and -+ * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise, -+ * it returns zero. -+ */ -+int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num, -+ u32 flags); -+ -+/** -+ * bman_acquire - Acquire buffer(s) from a buffer pool -+ * @pool: the buffer pool object to acquire from -+ * @bufs: array for storing the acquired buffers -+ * @num: the number of buffers desired (@bufs is at least this big) -+ * -+ * Issues an "Acquire" command via the portal's management command interface. -+ * The return value will be the number of buffers obtained from the pool, or a -+ * negative error code if a h/w error or pool starvation was encountered. In -+ * the latter case, the content of @bufs is undefined. -+ */ -+int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num, -+ u32 flags); -+ -+/** -+ * bman_flush_stockpile - Flush stockpile buffer(s) to the buffer pool -+ * @pool: the buffer pool object the stockpile belongs -+ * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options -+ * -+ * Adds stockpile buffers to RCR entries until the stockpile is empty. -+ * The return value will be a negative error code if a h/w error occurred. -+ * If BMAN_RELEASE_FLAG_NOW flag is passed and RCR ring is full, -+ * -EAGAIN will be returned. -+ */ -+int bman_flush_stockpile(struct bman_pool *pool, u32 flags); -+ -+/** -+ * bman_query_pools - Query all buffer pool states -+ * @state: storage for the queried availability and depletion states -+ */ -+int bman_query_pools(struct bm_pool_state *state); -+ -+#ifdef CONFIG_FSL_BMAN_CONFIG -+/** -+ * bman_query_free_buffers - Query how many free buffers are in buffer pool -+ * @pool: the buffer pool object to query -+ * -+ * Return the number of the free buffers -+ */ -+u32 bman_query_free_buffers(struct bman_pool *pool); -+ -+/** -+ * bman_update_pool_thresholds - Change the buffer pool's depletion thresholds -+ * @pool: the buffer pool object to which the thresholds will be set -+ * @thresholds: the new thresholds -+ */ -+int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds); -+#endif -+ -+/** -+ * The below bman_p_***() variant might be called in a situation that the cpu -+ * which the portal affine to is not online yet. -+ * @bman_portal specifies which portal the API will use. -+*/ -+int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits); -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* FSL_BMAN_H */ ---- /dev/null -+++ b/include/linux/fsl_qman.h -@@ -0,0 +1,3888 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef FSL_QMAN_H -+#define FSL_QMAN_H -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* Last updated for v00.800 of the BG */ -+ -+/* Hardware constants */ -+#define QM_CHANNEL_SWPORTAL0 0 -+#define QMAN_CHANNEL_POOL1 0x21 -+#define QMAN_CHANNEL_CAAM 0x80 -+#define QMAN_CHANNEL_PME 0xa0 -+#define QMAN_CHANNEL_POOL1_REV3 0x401 -+#define QMAN_CHANNEL_CAAM_REV3 0x840 -+#define QMAN_CHANNEL_PME_REV3 0x860 -+#define QMAN_CHANNEL_DCE 0x8a0 -+#define QMAN_CHANNEL_DCE_QMANREV312 0x880 -+extern u16 qm_channel_pool1; -+extern u16 qm_channel_caam; -+extern u16 qm_channel_pme; -+extern u16 qm_channel_dce; -+enum qm_dc_portal { -+ qm_dc_portal_fman0 = 0, -+ qm_dc_portal_fman1 = 1, -+ qm_dc_portal_caam = 2, -+ qm_dc_portal_pme = 3, -+ qm_dc_portal_rman = 4, -+ qm_dc_portal_dce = 5 -+}; -+ -+/* Portal processing (interrupt) sources */ -+#define QM_PIRQ_CCSCI 0x00200000 /* CEETM Congestion State Change */ -+#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */ -+#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */ -+#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */ -+#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */ -+#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */ -+/* This mask contains all the interrupt sources that need handling except DQRI, -+ * ie. that if present should trigger slow-path processing. */ -+#define QM_PIRQ_SLOW (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \ -+ QM_PIRQ_MRI | QM_PIRQ_CCSCI) -+ -+/* --- Clock speed --- */ -+/* A qman driver instance may or may not know the current qman clock speed. -+ * However, certain CEETM calculations may not be possible if this is not known. -+ * The 'set' function will only succeed (return zero) if the driver did not -+ * already know the clock speed. Likewise, the 'get' function will only succeed -+ * if the driver does know the clock speed (either because it knew when booting, -+ * or was told via 'set'). In cases where software is running on a driver -+ * instance that does not know the clock speed (eg. on a hypervised data-plane), -+ * and the user can obtain the current qman clock speed by other means (eg. from -+ * a message sent from the control-plane), then the 'set' function can be used -+ * to enable rate-calculations in a driver where it would otherwise not be -+ * possible. */ -+int qm_get_clock(u64 *clock_hz); -+int qm_set_clock(u64 clock_hz); -+ -+/* For qman_static_dequeue_*** APIs */ -+#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff -+/* for n in [1,15] */ -+#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n)) -+/* for conversion from n of qm_channel */ -+static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel) -+{ -+ return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1); -+} -+ -+/* For qman_volatile_dequeue(); Choose one PRECEDENCE. EXACT is optional. Use -+ * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use -+ * FQID(n) to fill in the frame queue ID. */ -+#define QM_VDQCR_PRECEDENCE_VDQCR 0x0 -+#define QM_VDQCR_PRECEDENCE_SDQCR 0x80000000 -+#define QM_VDQCR_EXACT 0x40000000 -+#define QM_VDQCR_NUMFRAMES_MASK 0x3f000000 -+#define QM_VDQCR_NUMFRAMES_SET(n) (((n) & 0x3f) << 24) -+#define QM_VDQCR_NUMFRAMES_GET(n) (((n) >> 24) & 0x3f) -+#define QM_VDQCR_NUMFRAMES_TILLEMPTY QM_VDQCR_NUMFRAMES_SET(0) -+ -+ -+/* ------------------------------------------------------- */ -+/* --- Qman data structures (and associated constants) --- */ -+ -+/* Represents s/w corenet portal mapped data structures */ -+struct qm_eqcr_entry; /* EQCR (EnQueue Command Ring) entries */ -+struct qm_dqrr_entry; /* DQRR (DeQueue Response Ring) entries */ -+struct qm_mr_entry; /* MR (Message Ring) entries */ -+struct qm_mc_command; /* MC (Management Command) command */ -+struct qm_mc_result; /* MC result */ -+ -+/* See David Lapp's "Frame formats" document, "dpateam", Jan 07, 2008 */ -+#define QM_FD_FORMAT_SG 0x4 -+#define QM_FD_FORMAT_LONG 0x2 -+#define QM_FD_FORMAT_COMPOUND 0x1 -+enum qm_fd_format { -+ /* 'contig' implies a contiguous buffer, whereas 'sg' implies a -+ * scatter-gather table. 'big' implies a 29-bit length with no offset -+ * field, otherwise length is 20-bit and offset is 9-bit. 'compound' -+ * implies a s/g-like table, where each entry itself represents a frame -+ * (contiguous or scatter-gather) and the 29-bit "length" is -+ * interpreted purely for congestion calculations, ie. a "congestion -+ * weight". */ -+ qm_fd_contig = 0, -+ qm_fd_contig_big = QM_FD_FORMAT_LONG, -+ qm_fd_sg = QM_FD_FORMAT_SG, -+ qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG, -+ qm_fd_compound = QM_FD_FORMAT_COMPOUND -+}; -+ -+/* Capitalised versions are un-typed but can be used in static expressions */ -+#define QM_FD_CONTIG 0 -+#define QM_FD_CONTIG_BIG QM_FD_FORMAT_LONG -+#define QM_FD_SG QM_FD_FORMAT_SG -+#define QM_FD_SG_BIG (QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG) -+#define QM_FD_COMPOUND QM_FD_FORMAT_COMPOUND -+ -+/* See 1.5.1.1: "Frame Descriptor (FD)" */ -+struct qm_fd { -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 dd:2; /* dynamic debug */ -+ u8 liodn_offset:6; -+ u8 bpid:8; /* Buffer Pool ID */ -+ u8 eliodn_offset:4; -+ u8 __reserved:4; -+ u8 addr_hi; /* high 8-bits of 40-bit address */ -+ u32 addr_lo; /* low 32-bits of 40-bit address */ -+#else -+ u32 addr_lo; /* low 32-bits of 40-bit address */ -+ u8 addr_hi; /* high 8-bits of 40-bit address */ -+ u8 __reserved:4; -+ u8 eliodn_offset:4; -+ u8 bpid:8; /* Buffer Pool ID */ -+ u8 liodn_offset:6; -+ u8 dd:2; /* dynamic debug */ -+#endif -+ }; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u64 __notaddress:24; -+ u64 addr:40; -+#else -+ u64 addr:40; -+ u64 __notaddress:24; -+#endif -+ }; -+ u64 opaque_addr; -+ }; -+ /* The 'format' field indicates the interpretation of the remaining 29 -+ * bits of the 32-bit word. For packing reasons, it is duplicated in the -+ * other union elements. Note, union'd structs are difficult to use with -+ * static initialisation under gcc, in which case use the "opaque" form -+ * with one of the macros. */ -+ union { -+ /* For easier/faster copying of this part of the fd (eg. from a -+ * DQRR entry to an EQCR entry) copy 'opaque' */ -+ u32 opaque; -+ /* If 'format' is _contig or _sg, 20b length and 9b offset */ -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ enum qm_fd_format format:3; -+ u16 offset:9; -+ u32 length20:20; -+#else -+ u32 length20:20; -+ u16 offset:9; -+ enum qm_fd_format format:3; -+#endif -+ }; -+ /* If 'format' is _contig_big or _sg_big, 29b length */ -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ enum qm_fd_format _format1:3; -+ u32 length29:29; -+#else -+ u32 length29:29; -+ enum qm_fd_format _format1:3; -+#endif -+ }; -+ /* If 'format' is _compound, 29b "congestion weight" */ -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ enum qm_fd_format _format2:3; -+ u32 cong_weight:29; -+#else -+ u32 cong_weight:29; -+ enum qm_fd_format _format2:3; -+#endif -+ }; -+ }; -+ union { -+ u32 cmd; -+ u32 status; -+ }; -+} __aligned(8); -+#define QM_FD_DD_NULL 0x00 -+#define QM_FD_PID_MASK 0x3f -+static inline u64 qm_fd_addr_get64(const struct qm_fd *fd) -+{ -+ return fd->addr; -+} -+ -+static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd) -+{ -+ return (dma_addr_t)fd->addr; -+} -+/* Macro, so we compile better if 'v' isn't always 64-bit */ -+#define qm_fd_addr_set64(fd, v) \ -+ do { \ -+ struct qm_fd *__fd931 = (fd); \ -+ __fd931->addr = v; \ -+ } while (0) -+ -+/* For static initialisation of FDs (which is complicated by the use of unions -+ * in "struct qm_fd"), use the following macros. Note that; -+ * - 'dd', 'pid' and 'bpid' are ignored because there's no static initialisation -+ * use-case), -+ * - use capitalised QM_FD_*** formats for static initialisation. -+ */ -+#define QM_FD_FMT_20(cmd, addr_hi, addr_lo, fmt, off, len) \ -+ { 0, 0, 0, 0, 0, addr_hi, addr_lo, \ -+ { (((fmt)&0x7) << 29) | (((off)&0x1ff) << 20) | ((len)&0xfffff) }, \ -+ { cmd } } -+#define QM_FD_FMT_29(cmd, addr_hi, addr_lo, fmt, len) \ -+ { 0, 0, 0, 0, 0, addr_hi, addr_lo, \ -+ { (((fmt)&0x7) << 29) | ((len)&0x1fffffff) }, \ -+ { cmd } } -+ -+/* See 2.2.1.3 Multi-Core Datapath Acceleration Architecture */ -+#define QM_SG_OFFSET_MASK 0x1FFF -+struct qm_sg_entry { -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 __reserved1[3]; -+ u8 addr_hi; /* high 8-bits of 40-bit address */ -+ u32 addr_lo; /* low 32-bits of 40-bit address */ -+#else -+ u32 addr_lo; /* low 32-bits of 40-bit address */ -+ u8 addr_hi; /* high 8-bits of 40-bit address */ -+ u8 __reserved1[3]; -+#endif -+ }; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u64 __notaddress:24; -+ u64 addr:40; -+#else -+ u64 addr:40; -+ u64 __notaddress:24; -+#endif -+ }; -+ u64 opaque; -+ }; -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 extension:1; /* Extension bit */ -+ u32 final:1; /* Final bit */ -+ u32 length:30; -+#else -+ u32 length:30; -+ u32 final:1; /* Final bit */ -+ u32 extension:1; /* Extension bit */ -+#endif -+ }; -+ u32 sgt_efl; -+ }; -+ u8 __reserved2; -+ u8 bpid; -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u16 __reserved3:3; -+ u16 offset:13; -+#else -+ u16 offset:13; -+ u16 __reserved3:3; -+#endif -+ }; -+ u16 opaque_offset; -+ }; -+} __packed; -+union qm_sg_efl { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 extension:1; /* Extension bit */ -+ u32 final:1; /* Final bit */ -+ u32 length:30; -+#else -+ u32 length:30; -+ u32 final:1; /* Final bit */ -+ u32 extension:1; /* Extension bit */ -+#endif -+ }; -+ u32 efl; -+}; -+static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg) -+{ -+ return (dma_addr_t)be64_to_cpu(sg->opaque) & 0xffffffffffULL; -+} -+static inline u8 qm_sg_entry_get_ext(const struct qm_sg_entry *sg) -+{ -+ union qm_sg_efl u; -+ -+ u.efl = be32_to_cpu(sg->sgt_efl); -+ return u.extension; -+} -+static inline u8 qm_sg_entry_get_final(const struct qm_sg_entry *sg) -+{ -+ union qm_sg_efl u; -+ -+ u.efl = be32_to_cpu(sg->sgt_efl); -+ return u.final; -+} -+static inline u32 qm_sg_entry_get_len(const struct qm_sg_entry *sg) -+{ -+ union qm_sg_efl u; -+ -+ u.efl = be32_to_cpu(sg->sgt_efl); -+ return u.length; -+} -+static inline u8 qm_sg_entry_get_bpid(const struct qm_sg_entry *sg) -+{ -+ return sg->bpid; -+} -+static inline u16 qm_sg_entry_get_offset(const struct qm_sg_entry *sg) -+{ -+ u32 opaque_offset = be16_to_cpu(sg->opaque_offset); -+ -+ return opaque_offset & 0x1fff; -+} -+ -+/* Macro, so we compile better if 'v' isn't always 64-bit */ -+#define qm_sg_entry_set64(sg, v) \ -+ do { \ -+ struct qm_sg_entry *__sg931 = (sg); \ -+ __sg931->opaque = cpu_to_be64(v); \ -+ } while (0) -+#define qm_sg_entry_set_ext(sg, v) \ -+ do { \ -+ union qm_sg_efl __u932; \ -+ __u932.efl = be32_to_cpu((sg)->sgt_efl); \ -+ __u932.extension = v; \ -+ (sg)->sgt_efl = cpu_to_be32(__u932.efl); \ -+ } while (0) -+#define qm_sg_entry_set_final(sg, v) \ -+ do { \ -+ union qm_sg_efl __u933; \ -+ __u933.efl = be32_to_cpu((sg)->sgt_efl); \ -+ __u933.final = v; \ -+ (sg)->sgt_efl = cpu_to_be32(__u933.efl); \ -+ } while (0) -+#define qm_sg_entry_set_len(sg, v) \ -+ do { \ -+ union qm_sg_efl __u934; \ -+ __u934.efl = be32_to_cpu((sg)->sgt_efl); \ -+ __u934.length = v; \ -+ (sg)->sgt_efl = cpu_to_be32(__u934.efl); \ -+ } while (0) -+#define qm_sg_entry_set_bpid(sg, v) \ -+ do { \ -+ struct qm_sg_entry *__u935 = (sg); \ -+ __u935->bpid = v; \ -+ } while (0) -+#define qm_sg_entry_set_offset(sg, v) \ -+ do { \ -+ struct qm_sg_entry *__u936 = (sg); \ -+ __u936->opaque_offset = cpu_to_be16(v); \ -+ } while (0) -+ -+/* See 1.5.8.1: "Enqueue Command" */ -+struct qm_eqcr_entry { -+ u8 __dont_write_directly__verb; -+ u8 dca; -+ u16 seqnum; -+ u32 orp; /* 24-bit */ -+ u32 fqid; /* 24-bit */ -+ u32 tag; -+ struct qm_fd fd; -+ u8 __reserved3[32]; -+} __packed; -+#define QM_EQCR_VERB_VBIT 0x80 -+#define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */ -+#define QM_EQCR_VERB_CMD_ENQUEUE 0x01 -+#define QM_EQCR_VERB_COLOUR_MASK 0x18 /* 4 possible values; */ -+#define QM_EQCR_VERB_COLOUR_GREEN 0x00 -+#define QM_EQCR_VERB_COLOUR_YELLOW 0x08 -+#define QM_EQCR_VERB_COLOUR_RED 0x10 -+#define QM_EQCR_VERB_COLOUR_OVERRIDE 0x18 -+#define QM_EQCR_VERB_INTERRUPT 0x04 /* on command consumption */ -+#define QM_EQCR_VERB_ORP 0x02 /* enable order restoration */ -+#define QM_EQCR_DCA_ENABLE 0x80 -+#define QM_EQCR_DCA_PARK 0x40 -+#define QM_EQCR_DCA_IDXMASK 0x0f /* "DQRR::idx" goes here */ -+#define QM_EQCR_SEQNUM_NESN 0x8000 /* Advance NESN */ -+#define QM_EQCR_SEQNUM_NLIS 0x4000 /* More fragments to come */ -+#define QM_EQCR_SEQNUM_SEQMASK 0x3fff /* sequence number goes here */ -+#define QM_EQCR_FQID_NULL 0 /* eg. for an ORP seqnum hole */ -+ -+/* See 1.5.8.2: "Frame Dequeue Response" */ -+struct qm_dqrr_entry { -+ u8 verb; -+ u8 stat; -+ u16 seqnum; /* 15-bit */ -+ u8 tok; -+ u8 __reserved2[3]; -+ u32 fqid; /* 24-bit */ -+ u32 contextB; -+ struct qm_fd fd; -+ u8 __reserved4[32]; -+}; -+#define QM_DQRR_VERB_VBIT 0x80 -+#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */ -+#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */ -+#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */ -+#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */ -+#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */ -+#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */ -+#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */ -+#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/ -+ -+/* See 1.5.8.3: "ERN Message Response" */ -+/* See 1.5.8.4: "FQ State Change Notification" */ -+struct qm_mr_entry { -+ u8 verb; -+ union { -+ struct { -+ u8 dca; -+ u16 seqnum; -+ u8 rc; /* Rejection Code */ -+ u32 orp:24; -+ u32 fqid; /* 24-bit */ -+ u32 tag; -+ struct qm_fd fd; -+ } __packed ern; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */ -+ u8 __reserved1:3; -+ enum qm_dc_portal portal:3; -+#else -+ enum qm_dc_portal portal:3; -+ u8 __reserved1:3; -+ u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */ -+#endif -+ u16 __reserved2; -+ u8 rc; /* Rejection Code */ -+ u32 __reserved3:24; -+ u32 fqid; /* 24-bit */ -+ u32 tag; -+ struct qm_fd fd; -+ } __packed dcern; -+ struct { -+ u8 fqs; /* Frame Queue Status */ -+ u8 __reserved1[6]; -+ u32 fqid; /* 24-bit */ -+ u32 contextB; -+ u8 __reserved2[16]; -+ } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */ -+ }; -+ u8 __reserved2[32]; -+} __packed; -+#define QM_MR_VERB_VBIT 0x80 -+/* The "ern" VERB bits match QM_EQCR_VERB_*** so aren't reproduced here. ERNs -+ * originating from direct-connect portals ("dcern") use 0x20 as a verb which -+ * would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished from -+ * the other MR types by noting if the 0x20 bit is unset. */ -+#define QM_MR_VERB_TYPE_MASK 0x27 -+#define QM_MR_VERB_DC_ERN 0x20 -+#define QM_MR_VERB_FQRN 0x21 -+#define QM_MR_VERB_FQRNI 0x22 -+#define QM_MR_VERB_FQRL 0x23 -+#define QM_MR_VERB_FQPN 0x24 -+#define QM_MR_RC_MASK 0xf0 /* contains one of; */ -+#define QM_MR_RC_CGR_TAILDROP 0x00 -+#define QM_MR_RC_WRED 0x10 -+#define QM_MR_RC_ERROR 0x20 -+#define QM_MR_RC_ORPWINDOW_EARLY 0x30 -+#define QM_MR_RC_ORPWINDOW_LATE 0x40 -+#define QM_MR_RC_FQ_TAILDROP 0x50 -+#define QM_MR_RC_ORPWINDOW_RETIRED 0x60 -+#define QM_MR_RC_ORP_ZERO 0x70 -+#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */ -+#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */ -+#define QM_MR_DCERN_COLOUR_GREEN 0x00 -+#define QM_MR_DCERN_COLOUR_YELLOW 0x01 -+#define QM_MR_DCERN_COLOUR_RED 0x02 -+#define QM_MR_DCERN_COLOUR_OVERRIDE 0x03 -+ -+/* An identical structure of FQD fields is present in the "Init FQ" command and -+ * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type. -+ * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the -+ * latter has two inlines to assist with converting to/from the mant+exp -+ * representation. */ -+struct qm_fqd_stashing { -+ /* See QM_STASHING_EXCL_<...> */ -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 exclusive; -+ u8 __reserved1:2; -+ /* Numbers of cachelines */ -+ u8 annotation_cl:2; -+ u8 data_cl:2; -+ u8 context_cl:2; -+#else -+ u8 context_cl:2; -+ u8 data_cl:2; -+ u8 annotation_cl:2; -+ u8 __reserved1:2; -+ u8 exclusive; -+#endif -+} __packed; -+struct qm_fqd_taildrop { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u16 __reserved1:3; -+ u16 mant:8; -+ u16 exp:5; -+#else -+ u16 exp:5; -+ u16 mant:8; -+ u16 __reserved1:3; -+#endif -+} __packed; -+struct qm_fqd_oac { -+ /* See QM_OAC_<...> */ -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 oac:2; /* "Overhead Accounting Control" */ -+ u8 __reserved1:6; -+#else -+ u8 __reserved1:6; -+ u8 oac:2; /* "Overhead Accounting Control" */ -+#endif -+ /* Two's-complement value (-128 to +127) */ -+ signed char oal; /* "Overhead Accounting Length" */ -+} __packed; -+struct qm_fqd { -+ union { -+ u8 orpc; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 __reserved1:2; -+ u8 orprws:3; -+ u8 oa:1; -+ u8 olws:2; -+#else -+ u8 olws:2; -+ u8 oa:1; -+ u8 orprws:3; -+ u8 __reserved1:2; -+#endif -+ } __packed; -+ }; -+ u8 cgid; -+ u16 fq_ctrl; /* See QM_FQCTRL_<...> */ -+ union { -+ u16 dest_wq; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u16 channel:13; /* qm_channel */ -+ u16 wq:3; -+#else -+ u16 wq:3; -+ u16 channel:13; /* qm_channel */ -+#endif -+ } __packed dest; -+ }; -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u16 __reserved2:1; -+ u16 ics_cred:15; -+#else -+ u16 __reserved2:1; -+ u16 ics_cred:15; -+#endif -+ /* For "Initialize Frame Queue" commands, the write-enable mask -+ * determines whether 'td' or 'oac_init' is observed. For query -+ * commands, this field is always 'td', and 'oac_query' (below) reflects -+ * the Overhead ACcounting values. */ -+ union { -+ struct qm_fqd_taildrop td; -+ struct qm_fqd_oac oac_init; -+ }; -+ u32 context_b; -+ union { -+ /* Treat it as 64-bit opaque */ -+ u64 opaque; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 hi; -+ u32 lo; -+#else -+ u32 lo; -+ u32 hi; -+#endif -+ }; -+ /* Treat it as s/w portal stashing config */ -+ /* See 1.5.6.7.1: "FQD Context_A field used for [...] */ -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ struct qm_fqd_stashing stashing; -+ /* 48-bit address of FQ context to -+ * stash, must be cacheline-aligned */ -+ u16 context_hi; -+ u32 context_lo; -+#else -+ u32 context_lo; -+ u16 context_hi; -+ struct qm_fqd_stashing stashing; -+#endif -+ } __packed; -+ } context_a; -+ struct qm_fqd_oac oac_query; -+} __packed; -+/* 64-bit converters for context_hi/lo */ -+static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd) -+{ -+ return ((u64)fqd->context_a.context_hi << 32) | -+ (u64)fqd->context_a.context_lo; -+} -+static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd) -+{ -+ return (dma_addr_t)qm_fqd_stashing_get64(fqd); -+} -+static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd) -+{ -+ return ((u64)fqd->context_a.hi << 32) | -+ (u64)fqd->context_a.lo; -+} -+/* Macro, so we compile better when 'v' isn't necessarily 64-bit */ -+#define qm_fqd_stashing_set64(fqd, v) \ -+ do { \ -+ struct qm_fqd *__fqd931 = (fqd); \ -+ __fqd931->context_a.context_hi = upper_32_bits(v); \ -+ __fqd931->context_a.context_lo = lower_32_bits(v); \ -+ } while (0) -+#define qm_fqd_context_a_set64(fqd, v) \ -+ do { \ -+ struct qm_fqd *__fqd931 = (fqd); \ -+ __fqd931->context_a.hi = upper_32_bits(v); \ -+ __fqd931->context_a.lo = lower_32_bits(v); \ -+ } while (0) -+/* convert a threshold value into mant+exp representation */ -+static inline int qm_fqd_taildrop_set(struct qm_fqd_taildrop *td, u32 val, -+ int roundup) -+{ -+ u32 e = 0; -+ int oddbit = 0; -+ if (val > 0xe0000000) -+ return -ERANGE; -+ while (val > 0xff) { -+ oddbit = val & 1; -+ val >>= 1; -+ e++; -+ if (roundup && oddbit) -+ val++; -+ } -+ td->exp = e; -+ td->mant = val; -+ return 0; -+} -+/* and the other direction */ -+static inline u32 qm_fqd_taildrop_get(const struct qm_fqd_taildrop *td) -+{ -+ return (u32)td->mant << td->exp; -+} -+ -+/* See 1.5.2.2: "Frame Queue Descriptor (FQD)" */ -+/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */ -+#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */ -+#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */ -+#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */ -+#define QM_FQCTRL_ORP 0x0100 /* ORP Enable */ -+#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */ -+#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */ -+#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */ -+#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */ -+#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */ -+#define QM_FQCTRL_PREFERINCACHE 0x0001 /* Aggressively cache FQD */ -+#define QM_FQCTRL_LOCKINCACHE QM_FQCTRL_PREFERINCACHE /* older naming */ -+ -+/* See 1.5.6.7.1: "FQD Context_A field used for [...] */ -+/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */ -+#define QM_STASHING_EXCL_ANNOTATION 0x04 -+#define QM_STASHING_EXCL_DATA 0x02 -+#define QM_STASHING_EXCL_CTX 0x01 -+ -+/* See 1.5.5.3: "Intra Class Scheduling" */ -+/* FQD field 'OAC' (Overhead ACcounting) uses these constants */ -+#define QM_OAC_ICS 0x2 /* Accounting for Intra-Class Scheduling */ -+#define QM_OAC_CG 0x1 /* Accounting for Congestion Groups */ -+ -+/* See 1.5.8.4: "FQ State Change Notification" */ -+/* This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields -+ * and associated commands/responses. The WRED parameters are calculated from -+ * these fields as follows; -+ * MaxTH = MA * (2 ^ Mn) -+ * Slope = SA / (2 ^ Sn) -+ * MaxP = 4 * (Pn + 1) -+ */ -+struct qm_cgr_wr_parm { -+ union { -+ u32 word; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 MA:8; -+ u32 Mn:5; -+ u32 SA:7; /* must be between 64-127 */ -+ u32 Sn:6; -+ u32 Pn:6; -+#else -+ u32 Pn:6; -+ u32 Sn:6; -+ u32 SA:7; /* must be between 64-127 */ -+ u32 Mn:5; -+ u32 MA:8; -+#endif -+ } __packed; -+ }; -+} __packed; -+/* This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding -+ * management commands, this is padded to a 16-bit structure field, so that's -+ * how we represent it here. The congestion state threshold is calculated from -+ * these fields as follows; -+ * CS threshold = TA * (2 ^ Tn) -+ */ -+struct qm_cgr_cs_thres { -+ union { -+ u16 hword; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u16 __reserved:3; -+ u16 TA:8; -+ u16 Tn:5; -+#else -+ u16 Tn:5; -+ u16 TA:8; -+ u16 __reserved:3; -+#endif -+ } __packed; -+ }; -+} __packed; -+/* This identical structure of CGR fields is present in the "Init/Modify CGR" -+ * commands and the "Query CGR" result. It's suctioned out here into its own -+ * struct. */ -+struct __qm_mc_cgr { -+ struct qm_cgr_wr_parm wr_parm_g; -+ struct qm_cgr_wr_parm wr_parm_y; -+ struct qm_cgr_wr_parm wr_parm_r; -+ u8 wr_en_g; /* boolean, use QM_CGR_EN */ -+ u8 wr_en_y; /* boolean, use QM_CGR_EN */ -+ u8 wr_en_r; /* boolean, use QM_CGR_EN */ -+ u8 cscn_en; /* boolean, use QM_CGR_EN */ -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */ -+ u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */ -+#else -+ u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */ -+ u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */ -+#endif -+ }; -+ u32 cscn_targ; /* use QM_CGR_TARG_* */ -+ }; -+ u8 cstd_en; /* boolean, use QM_CGR_EN */ -+ u8 cs; /* boolean, only used in query response */ -+ union { -+ /* use qm_cgr_cs_thres_set64() */ -+ struct qm_cgr_cs_thres cs_thres; -+ u16 __cs_thres; -+ }; -+ u8 mode; /* QMAN_CGR_MODE_FRAME not supported in rev1.0 */ -+} __packed; -+#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en */ -+#define QM_CGR_TARG_UDP_CTRL_WRITE_BIT 0x8000 /* value written to portal bit*/ -+#define QM_CGR_TARG_UDP_CTRL_DCP 0x4000 /* 0: SWP, 1: DCP */ -+#define QM_CGR_TARG_PORTAL(n) (0x80000000 >> (n)) /* s/w portal, 0-9 */ -+#define QM_CGR_TARG_FMAN0 0x00200000 /* direct-connect portal: fman0 */ -+#define QM_CGR_TARG_FMAN1 0x00100000 /* : fman1 */ -+/* Convert CGR thresholds to/from "cs_thres" format */ -+static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th) -+{ -+ return (u64)th->TA << th->Tn; -+} -+static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val, -+ int roundup) -+{ -+ u32 e = 0; -+ int oddbit = 0; -+ while (val > 0xff) { -+ oddbit = val & 1; -+ val >>= 1; -+ e++; -+ if (roundup && oddbit) -+ val++; -+ } -+ th->Tn = e; -+ th->TA = val; -+ return 0; -+} -+ -+/* See 1.5.8.5.1: "Initialize FQ" */ -+/* See 1.5.8.5.2: "Query FQ" */ -+/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */ -+/* See 1.5.8.5.4: "Alter FQ State Commands " */ -+/* See 1.5.8.6.1: "Initialize/Modify CGR" */ -+/* See 1.5.8.6.2: "CGR Test Write" */ -+/* See 1.5.8.6.3: "Query CGR" */ -+/* See 1.5.8.6.4: "Query Congestion Group State" */ -+struct qm_mcc_initfq { -+ u8 __reserved1; -+ u16 we_mask; /* Write Enable Mask */ -+ u32 fqid; /* 24-bit */ -+ u16 count; /* Initialises 'count+1' FQDs */ -+ struct qm_fqd fqd; /* the FQD fields go here */ -+ u8 __reserved3[30]; -+} __packed; -+struct qm_mcc_queryfq { -+ u8 __reserved1[3]; -+ u32 fqid; /* 24-bit */ -+ u8 __reserved2[56]; -+} __packed; -+struct qm_mcc_queryfq_np { -+ u8 __reserved1[3]; -+ u32 fqid; /* 24-bit */ -+ u8 __reserved2[56]; -+} __packed; -+struct qm_mcc_alterfq { -+ u8 __reserved1[3]; -+ u32 fqid; /* 24-bit */ -+ u8 __reserved2; -+ u8 count; /* number of consecutive FQID */ -+ u8 __reserved3[10]; -+ u32 context_b; /* frame queue context b */ -+ u8 __reserved4[40]; -+} __packed; -+struct qm_mcc_initcgr { -+ u8 __reserved1; -+ u16 we_mask; /* Write Enable Mask */ -+ struct __qm_mc_cgr cgr; /* CGR fields */ -+ u8 __reserved2[2]; -+ u8 cgid; -+ u8 __reserved4[32]; -+} __packed; -+struct qm_mcc_cgrtestwrite { -+ u8 __reserved1[2]; -+ u8 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */ -+ u32 i_bcnt_lo; /* low 32-bits of 40-bit */ -+ u8 __reserved2[23]; -+ u8 cgid; -+ u8 __reserved3[32]; -+} __packed; -+struct qm_mcc_querycgr { -+ u8 __reserved1[30]; -+ u8 cgid; -+ u8 __reserved2[32]; -+} __packed; -+struct qm_mcc_querycongestion { -+ u8 __reserved[63]; -+} __packed; -+struct qm_mcc_querywq { -+ u8 __reserved; -+ /* select channel if verb != QUERYWQ_DEDICATED */ -+ union { -+ u16 channel_wq; /* ignores wq (3 lsbits) */ -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u16 id:13; /* qm_channel */ -+ u16 __reserved1:3; -+#else -+ u16 __reserved1:3; -+ u16 id:13; /* qm_channel */ -+#endif -+ } __packed channel; -+ }; -+ u8 __reserved2[60]; -+} __packed; -+ -+struct qm_mcc_ceetm_lfqmt_config { -+ u8 __reserved1[4]; -+ u32 lfqid:24; -+ u8 __reserved2[2]; -+ u16 cqid; -+ u8 __reserved3[2]; -+ u16 dctidx; -+ u8 __reserved4[48]; -+} __packed; -+ -+struct qm_mcc_ceetm_lfqmt_query { -+ u8 __reserved1[4]; -+ u32 lfqid:24; -+ u8 __reserved2[56]; -+} __packed; -+ -+struct qm_mcc_ceetm_cq_config { -+ u8 __reserved1; -+ u16 cqid; -+ u8 dcpid; -+ u8 __reserved2; -+ u16 ccgid; -+ u8 __reserved3[56]; -+} __packed; -+ -+struct qm_mcc_ceetm_cq_query { -+ u8 __reserved1; -+ u16 cqid; -+ u8 dcpid; -+ u8 __reserved2[59]; -+} __packed; -+ -+struct qm_mcc_ceetm_dct_config { -+ u8 __reserved1; -+ u16 dctidx; -+ u8 dcpid; -+ u8 __reserved2[15]; -+ u32 context_b; -+ u64 context_a; -+ u8 __reserved3[32]; -+} __packed; -+ -+struct qm_mcc_ceetm_dct_query { -+ u8 __reserved1; -+ u16 dctidx; -+ u8 dcpid; -+ u8 __reserved2[59]; -+} __packed; -+ -+struct qm_mcc_ceetm_class_scheduler_config { -+ u8 __reserved1; -+ u16 cqcid; -+ u8 dcpid; -+ u8 __reserved2[6]; -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 gpc_reserved:1; -+ u8 gpc_combine_flag:1; -+ u8 gpc_prio_b:3; -+ u8 gpc_prio_a:3; -+#else -+ u8 gpc_prio_a:3; -+ u8 gpc_prio_b:3; -+ u8 gpc_combine_flag:1; -+ u8 gpc_reserved:1; -+#endif -+ u16 crem; -+ u16 erem; -+ u8 w[8]; -+ u8 __reserved3[40]; -+} __packed; -+ -+struct qm_mcc_ceetm_class_scheduler_query { -+ u8 __reserved1; -+ u16 cqcid; -+ u8 dcpid; -+ u8 __reserved2[59]; -+} __packed; -+ -+#define CEETM_COMMAND_CHANNEL_MAPPING (0 << 12) -+#define CEETM_COMMAND_SP_MAPPING (1 << 12) -+#define CEETM_COMMAND_CHANNEL_SHAPER (2 << 12) -+#define CEETM_COMMAND_LNI_SHAPER (3 << 12) -+#define CEETM_COMMAND_TCFC (4 << 12) -+ -+#define CEETM_CCGRID_MASK 0x01FF -+#define CEETM_CCGR_CM_CONFIGURE (0 << 14) -+#define CEETM_CCGR_DN_CONFIGURE (1 << 14) -+#define CEETM_CCGR_TEST_WRITE (2 << 14) -+#define CEETM_CCGR_CM_QUERY (0 << 14) -+#define CEETM_CCGR_DN_QUERY (1 << 14) -+#define CEETM_CCGR_DN_QUERY_FLUSH (2 << 14) -+#define CEETM_QUERY_CONGESTION_STATE (3 << 14) -+ -+struct qm_mcc_ceetm_mapping_shaper_tcfc_config { -+ u8 __reserved1; -+ u16 cid; -+ u8 dcpid; -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 map_shaped:1; -+ u8 map_reserved:4; -+ u8 map_lni_id:3; -+#else -+ u8 map_lni_id:3; -+ u8 map_reserved:4; -+ u8 map_shaped:1; -+#endif -+ u8 __reserved2[58]; -+ } __packed channel_mapping; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 map_reserved:5; -+ u8 map_lni_id:3; -+#else -+ u8 map_lni_id:3; -+ u8 map_reserved:5; -+#endif -+ u8 __reserved2[58]; -+ } __packed sp_mapping; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 cpl:1; -+ u8 cpl_reserved:2; -+ u8 oal:5; -+#else -+ u8 oal:5; -+ u8 cpl_reserved:2; -+ u8 cpl:1; -+#endif -+ u32 crtcr:24; -+ u32 ertcr:24; -+ u16 crtbl; -+ u16 ertbl; -+ u8 mps; /* This will be hardcoded by driver with 60 */ -+ u8 __reserved2[47]; -+ } __packed shaper_config; -+ struct { -+ u8 __reserved2[11]; -+ u64 lnitcfcc; -+ u8 __reserved3[40]; -+ } __packed tcfc_config; -+ }; -+} __packed; -+ -+struct qm_mcc_ceetm_mapping_shaper_tcfc_query { -+ u8 __reserved1; -+ u16 cid; -+ u8 dcpid; -+ u8 __reserved2[59]; -+} __packed; -+ -+struct qm_mcc_ceetm_ccgr_config { -+ u8 __reserved1; -+ u16 ccgrid; -+ u8 dcpid; -+ u8 __reserved2; -+ u16 we_mask; -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 ctl_reserved:1; -+ u8 ctl_wr_en_g:1; -+ u8 ctl_wr_en_y:1; -+ u8 ctl_wr_en_r:1; -+ u8 ctl_td_en:1; -+ u8 ctl_td_mode:1; -+ u8 ctl_cscn_en:1; -+ u8 ctl_mode:1; -+#else -+ u8 ctl_mode:1; -+ u8 ctl_cscn_en:1; -+ u8 ctl_td_mode:1; -+ u8 ctl_td_en:1; -+ u8 ctl_wr_en_r:1; -+ u8 ctl_wr_en_y:1; -+ u8 ctl_wr_en_g:1; -+ u8 ctl_reserved:1; -+#endif -+ u8 cdv; -+ u16 cscn_tupd; -+ u8 oal; -+ u8 __reserved3; -+ struct qm_cgr_cs_thres cs_thres; -+ struct qm_cgr_cs_thres cs_thres_x; -+ struct qm_cgr_cs_thres td_thres; -+ struct qm_cgr_wr_parm wr_parm_g; -+ struct qm_cgr_wr_parm wr_parm_y; -+ struct qm_cgr_wr_parm wr_parm_r; -+ } __packed cm_config; -+ struct { -+ u8 dnc; -+ u8 dn0; -+ u8 dn1; -+ u64 dnba:40; -+ u8 __reserved3[2]; -+ u16 dnth_0; -+ u8 __reserved4[2]; -+ u16 dnth_1; -+ u8 __reserved5[8]; -+ } __packed dn_config; -+ struct { -+ u8 __reserved3[3]; -+ u64 i_cnt:40; -+ u8 __reserved4[16]; -+ } __packed test_write; -+ }; -+ u8 __reserved5[32]; -+} __packed; -+ -+struct qm_mcc_ceetm_ccgr_query { -+ u8 __reserved1; -+ u16 ccgrid; -+ u8 dcpid; -+ u8 __reserved2[59]; -+} __packed; -+ -+struct qm_mcc_ceetm_cq_peek_pop_xsfdrread { -+ u8 __reserved1; -+ u16 cqid; -+ u8 dcpid; -+ u8 ct; -+ u16 xsfdr; -+ u8 __reserved2[56]; -+} __packed; -+ -+#define CEETM_QUERY_DEQUEUE_STATISTICS 0x00 -+#define CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS 0x01 -+#define CEETM_WRITE_DEQUEUE_STATISTICS 0x02 -+#define CEETM_QUERY_REJECT_STATISTICS 0x03 -+#define CEETM_QUERY_REJECT_CLEAR_STATISTICS 0x04 -+#define CEETM_WRITE_REJECT_STATISTICS 0x05 -+struct qm_mcc_ceetm_statistics_query_write { -+ u8 __reserved1; -+ u16 cid; -+ u8 dcpid; -+ u8 ct; -+ u8 __reserved2[13]; -+ u64 frm_cnt:40; -+ u8 __reserved3[2]; -+ u64 byte_cnt:48; -+ u8 __reserved[32]; -+} __packed; -+ -+struct qm_mc_command { -+ u8 __dont_write_directly__verb; -+ union { -+ struct qm_mcc_initfq initfq; -+ struct qm_mcc_queryfq queryfq; -+ struct qm_mcc_queryfq_np queryfq_np; -+ struct qm_mcc_alterfq alterfq; -+ struct qm_mcc_initcgr initcgr; -+ struct qm_mcc_cgrtestwrite cgrtestwrite; -+ struct qm_mcc_querycgr querycgr; -+ struct qm_mcc_querycongestion querycongestion; -+ struct qm_mcc_querywq querywq; -+ struct qm_mcc_ceetm_lfqmt_config lfqmt_config; -+ struct qm_mcc_ceetm_lfqmt_query lfqmt_query; -+ struct qm_mcc_ceetm_cq_config cq_config; -+ struct qm_mcc_ceetm_cq_query cq_query; -+ struct qm_mcc_ceetm_dct_config dct_config; -+ struct qm_mcc_ceetm_dct_query dct_query; -+ struct qm_mcc_ceetm_class_scheduler_config csch_config; -+ struct qm_mcc_ceetm_class_scheduler_query csch_query; -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_config mst_config; -+ struct qm_mcc_ceetm_mapping_shaper_tcfc_query mst_query; -+ struct qm_mcc_ceetm_ccgr_config ccgr_config; -+ struct qm_mcc_ceetm_ccgr_query ccgr_query; -+ struct qm_mcc_ceetm_cq_peek_pop_xsfdrread cq_ppxr; -+ struct qm_mcc_ceetm_statistics_query_write stats_query_write; -+ }; -+} __packed; -+#define QM_MCC_VERB_VBIT 0x80 -+#define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */ -+#define QM_MCC_VERB_INITFQ_PARKED 0x40 -+#define QM_MCC_VERB_INITFQ_SCHED 0x41 -+#define QM_MCC_VERB_QUERYFQ 0x44 -+#define QM_MCC_VERB_QUERYFQ_NP 0x45 /* "non-programmable" fields */ -+#define QM_MCC_VERB_QUERYWQ 0x46 -+#define QM_MCC_VERB_QUERYWQ_DEDICATED 0x47 -+#define QM_MCC_VERB_ALTER_SCHED 0x48 /* Schedule FQ */ -+#define QM_MCC_VERB_ALTER_FE 0x49 /* Force Eligible FQ */ -+#define QM_MCC_VERB_ALTER_RETIRE 0x4a /* Retire FQ */ -+#define QM_MCC_VERB_ALTER_OOS 0x4b /* Take FQ out of service */ -+#define QM_MCC_VERB_ALTER_FQXON 0x4d /* FQ XON */ -+#define QM_MCC_VERB_ALTER_FQXOFF 0x4e /* FQ XOFF */ -+#define QM_MCC_VERB_INITCGR 0x50 -+#define QM_MCC_VERB_MODIFYCGR 0x51 -+#define QM_MCC_VERB_CGRTESTWRITE 0x52 -+#define QM_MCC_VERB_QUERYCGR 0x58 -+#define QM_MCC_VERB_QUERYCONGESTION 0x59 -+/* INITFQ-specific flags */ -+#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */ -+#define QM_INITFQ_WE_OAC 0x0100 -+#define QM_INITFQ_WE_ORPC 0x0080 -+#define QM_INITFQ_WE_CGID 0x0040 -+#define QM_INITFQ_WE_FQCTRL 0x0020 -+#define QM_INITFQ_WE_DESTWQ 0x0010 -+#define QM_INITFQ_WE_ICSCRED 0x0008 -+#define QM_INITFQ_WE_TDTHRESH 0x0004 -+#define QM_INITFQ_WE_CONTEXTB 0x0002 -+#define QM_INITFQ_WE_CONTEXTA 0x0001 -+/* INITCGR/MODIFYCGR-specific flags */ -+#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */ -+#define QM_CGR_WE_WR_PARM_G 0x0400 -+#define QM_CGR_WE_WR_PARM_Y 0x0200 -+#define QM_CGR_WE_WR_PARM_R 0x0100 -+#define QM_CGR_WE_WR_EN_G 0x0080 -+#define QM_CGR_WE_WR_EN_Y 0x0040 -+#define QM_CGR_WE_WR_EN_R 0x0020 -+#define QM_CGR_WE_CSCN_EN 0x0010 -+#define QM_CGR_WE_CSCN_TARG 0x0008 -+#define QM_CGR_WE_CSTD_EN 0x0004 -+#define QM_CGR_WE_CS_THRES 0x0002 -+#define QM_CGR_WE_MODE 0x0001 -+ -+/* See 1.5.9.7 CEETM Management Commands */ -+#define QM_CEETM_VERB_LFQMT_CONFIG 0x70 -+#define QM_CEETM_VERB_LFQMT_QUERY 0x71 -+#define QM_CEETM_VERB_CQ_CONFIG 0x72 -+#define QM_CEETM_VERB_CQ_QUERY 0x73 -+#define QM_CEETM_VERB_DCT_CONFIG 0x74 -+#define QM_CEETM_VERB_DCT_QUERY 0x75 -+#define QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG 0x76 -+#define QM_CEETM_VERB_CLASS_SCHEDULER_QUERY 0x77 -+#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG 0x78 -+#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY 0x79 -+#define QM_CEETM_VERB_CCGR_CONFIG 0x7A -+#define QM_CEETM_VERB_CCGR_QUERY 0x7B -+#define QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD 0x7C -+#define QM_CEETM_VERB_STATISTICS_QUERY_WRITE 0x7D -+ -+/* See 1.5.8.5.1: "Initialize FQ" */ -+/* See 1.5.8.5.2: "Query FQ" */ -+/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */ -+/* See 1.5.8.5.4: "Alter FQ State Commands " */ -+/* See 1.5.8.6.1: "Initialize/Modify CGR" */ -+/* See 1.5.8.6.2: "CGR Test Write" */ -+/* See 1.5.8.6.3: "Query CGR" */ -+/* See 1.5.8.6.4: "Query Congestion Group State" */ -+struct qm_mcr_initfq { -+ u8 __reserved1[62]; -+} __packed; -+struct qm_mcr_queryfq { -+ u8 __reserved1[8]; -+ struct qm_fqd fqd; /* the FQD fields are here */ -+ u8 __reserved2[30]; -+} __packed; -+struct qm_mcr_queryfq_np { -+ u8 __reserved1; -+ u8 state; /* QM_MCR_NP_STATE_*** */ -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 __reserved2; -+ u32 fqd_link:24; -+ u16 __reserved3:2; -+ u16 odp_seq:14; -+ u16 __reserved4:2; -+ u16 orp_nesn:14; -+ u16 __reserved5:1; -+ u16 orp_ea_hseq:15; -+ u16 __reserved6:1; -+ u16 orp_ea_tseq:15; -+ u8 __reserved7; -+ u32 orp_ea_hptr:24; -+ u8 __reserved8; -+ u32 orp_ea_tptr:24; -+ u8 __reserved9; -+ u32 pfdr_hptr:24; -+ u8 __reserved10; -+ u32 pfdr_tptr:24; -+ u8 __reserved11[5]; -+ u8 __reserved12:7; -+ u8 is:1; -+ u16 ics_surp; -+ u32 byte_cnt; -+ u8 __reserved13; -+ u32 frm_cnt:24; -+ u32 __reserved14; -+ u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */ -+ u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */ -+ u16 __reserved15; -+ u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */ -+ u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */ -+ u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */ -+#else -+ u8 __reserved2; -+ u32 fqd_link:24; -+ -+ u16 odp_seq:14; -+ u16 __reserved3:2; -+ -+ u16 orp_nesn:14; -+ u16 __reserved4:2; -+ -+ u16 orp_ea_hseq:15; -+ u16 __reserved5:1; -+ -+ u16 orp_ea_tseq:15; -+ u16 __reserved6:1; -+ -+ u8 __reserved7; -+ u32 orp_ea_hptr:24; -+ -+ u8 __reserved8; -+ u32 orp_ea_tptr:24; -+ -+ u8 __reserved9; -+ u32 pfdr_hptr:24; -+ -+ u8 __reserved10; -+ u32 pfdr_tptr:24; -+ -+ u8 __reserved11[5]; -+ u8 is:1; -+ u8 __reserved12:7; -+ u16 ics_surp; -+ u32 byte_cnt; -+ u8 __reserved13; -+ u32 frm_cnt:24; -+ u32 __reserved14; -+ u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */ -+ u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */ -+ u16 __reserved15; -+ u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */ -+ u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */ -+ u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */ -+#endif -+} __packed; -+ -+ -+struct qm_mcr_alterfq { -+ u8 fqs; /* Frame Queue Status */ -+ u8 __reserved1[61]; -+} __packed; -+struct qm_mcr_initcgr { -+ u8 __reserved1[62]; -+} __packed; -+struct qm_mcr_cgrtestwrite { -+ u16 __reserved1; -+ struct __qm_mc_cgr cgr; /* CGR fields */ -+ u8 __reserved2[3]; -+ u32 __reserved3:24; -+ u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */ -+ u32 i_bcnt_lo; /* low 32-bits of 40-bit */ -+ u32 __reserved4:24; -+ u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */ -+ u32 a_bcnt_lo; /* low 32-bits of 40-bit */ -+ u16 lgt; /* Last Group Tick */ -+ u16 wr_prob_g; -+ u16 wr_prob_y; -+ u16 wr_prob_r; -+ u8 __reserved5[8]; -+} __packed; -+struct qm_mcr_querycgr { -+ u16 __reserved1; -+ struct __qm_mc_cgr cgr; /* CGR fields */ -+ u8 __reserved2[3]; -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 __reserved3:24; -+ u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */ -+ u32 i_bcnt_lo; /* low 32-bits of 40-bit */ -+#else -+ u32 i_bcnt_lo; /* low 32-bits of 40-bit */ -+ u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */ -+ u32 __reserved3:24; -+#endif -+ }; -+ u64 i_bcnt; -+ }; -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u32 __reserved4:24; -+ u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */ -+ u32 a_bcnt_lo; /* low 32-bits of 40-bit */ -+#else -+ u32 a_bcnt_lo; /* low 32-bits of 40-bit */ -+ u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */ -+ u32 __reserved4:24; -+#endif -+ }; -+ u64 a_bcnt; -+ }; -+ union { -+ u32 cscn_targ_swp[4]; -+ u8 __reserved5[16]; -+ }; -+} __packed; -+static inline u64 qm_mcr_querycgr_i_get64(const struct qm_mcr_querycgr *q) -+{ -+ return be64_to_cpu(q->i_bcnt); -+} -+static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q) -+{ -+ return be64_to_cpu(q->a_bcnt); -+} -+static inline u64 qm_mcr_cgrtestwrite_i_get64( -+ const struct qm_mcr_cgrtestwrite *q) -+{ -+ return be64_to_cpu(((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo); -+} -+static inline u64 qm_mcr_cgrtestwrite_a_get64( -+ const struct qm_mcr_cgrtestwrite *q) -+{ -+ return be64_to_cpu(((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo); -+} -+/* Macro, so we compile better if 'v' isn't always 64-bit */ -+#define qm_mcr_querycgr_i_set64(q, v) \ -+ do { \ -+ struct qm_mcr_querycgr *__q931 = (fd); \ -+ __q931->i_bcnt_hi = upper_32_bits(v); \ -+ __q931->i_bcnt_lo = lower_32_bits(v); \ -+ } while (0) -+#define qm_mcr_querycgr_a_set64(q, v) \ -+ do { \ -+ struct qm_mcr_querycgr *__q931 = (fd); \ -+ __q931->a_bcnt_hi = upper_32_bits(v); \ -+ __q931->a_bcnt_lo = lower_32_bits(v); \ -+ } while (0) -+struct __qm_mcr_querycongestion { -+ u32 __state[8]; -+}; -+struct qm_mcr_querycongestion { -+ u8 __reserved[30]; -+ /* Access this struct using QM_MCR_QUERYCONGESTION() */ -+ struct __qm_mcr_querycongestion state; -+} __packed; -+struct qm_mcr_querywq { -+ union { -+ u16 channel_wq; /* ignores wq (3 lsbits) */ -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u16 id:13; /* qm_channel */ -+ u16 __reserved:3; -+#else -+ u16 __reserved:3; -+ u16 id:13; /* qm_channel */ -+#endif -+ } __packed channel; -+ }; -+ u8 __reserved[28]; -+ u32 wq_len[8]; -+} __packed; -+ -+/* QMAN CEETM Management Command Response */ -+struct qm_mcr_ceetm_lfqmt_config { -+ u8 __reserved1[62]; -+} __packed; -+struct qm_mcr_ceetm_lfqmt_query { -+ u8 __reserved1[8]; -+ u16 cqid; -+ u8 __reserved2[2]; -+ u16 dctidx; -+ u8 __reserved3[2]; -+ u16 ccgid; -+ u8 __reserved4[44]; -+} __packed; -+ -+struct qm_mcr_ceetm_cq_config { -+ u8 __reserved1[62]; -+} __packed; -+ -+struct qm_mcr_ceetm_cq_query { -+ u8 __reserved1[4]; -+ u16 ccgid; -+ u16 state; -+ u32 pfdr_hptr:24; -+ u32 pfdr_tptr:24; -+ u16 od1_xsfdr; -+ u16 od2_xsfdr; -+ u16 od3_xsfdr; -+ u16 od4_xsfdr; -+ u16 od5_xsfdr; -+ u16 od6_xsfdr; -+ u16 ra1_xsfdr; -+ u16 ra2_xsfdr; -+ u8 __reserved2; -+ u32 frm_cnt:24; -+ u8 __reserved333[28]; -+} __packed; -+ -+struct qm_mcr_ceetm_dct_config { -+ u8 __reserved1[62]; -+} __packed; -+ -+struct qm_mcr_ceetm_dct_query { -+ u8 __reserved1[18]; -+ u32 context_b; -+ u64 context_a; -+ u8 __reserved2[32]; -+} __packed; -+ -+struct qm_mcr_ceetm_class_scheduler_config { -+ u8 __reserved1[62]; -+} __packed; -+ -+struct qm_mcr_ceetm_class_scheduler_query { -+ u8 __reserved1[9]; -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 gpc_reserved:1; -+ u8 gpc_combine_flag:1; -+ u8 gpc_prio_b:3; -+ u8 gpc_prio_a:3; -+#else -+ u8 gpc_prio_a:3; -+ u8 gpc_prio_b:3; -+ u8 gpc_combine_flag:1; -+ u8 gpc_reserved:1; -+#endif -+ u16 crem; -+ u16 erem; -+ u8 w[8]; -+ u8 __reserved2[5]; -+ u32 wbfslist:24; -+ u32 d8; -+ u32 d9; -+ u32 d10; -+ u32 d11; -+ u32 d12; -+ u32 d13; -+ u32 d14; -+ u32 d15; -+} __packed; -+ -+struct qm_mcr_ceetm_mapping_shaper_tcfc_config { -+ u16 cid; -+ u8 __reserved2[60]; -+} __packed; -+ -+struct qm_mcr_ceetm_mapping_shaper_tcfc_query { -+ u16 cid; -+ u8 __reserved1; -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 map_shaped:1; -+ u8 map_reserved:4; -+ u8 map_lni_id:3; -+#else -+ u8 map_lni_id:3; -+ u8 map_reserved:4; -+ u8 map_shaped:1; -+#endif -+ u8 __reserved2[58]; -+ } __packed channel_mapping_query; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 map_reserved:5; -+ u8 map_lni_id:3; -+#else -+ u8 map_lni_id:3; -+ u8 map_reserved:5; -+#endif -+ u8 __reserved2[58]; -+ } __packed sp_mapping_query; -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 cpl:1; -+ u8 cpl_reserved:2; -+ u8 oal:5; -+#else -+ u8 oal:5; -+ u8 cpl_reserved:2; -+ u8 cpl:1; -+#endif -+ u32 crtcr:24; -+ u32 ertcr:24; -+ u16 crtbl; -+ u16 ertbl; -+ u8 mps; -+ u8 __reserved2[15]; -+ u32 crat; -+ u32 erat; -+ u8 __reserved3[24]; -+ } __packed shaper_query; -+ struct { -+ u8 __reserved1[11]; -+ u64 lnitcfcc; -+ u8 __reserved3[40]; -+ } __packed tcfc_query; -+ }; -+} __packed; -+ -+struct qm_mcr_ceetm_ccgr_config { -+ u8 __reserved1[46]; -+ union { -+ u8 __reserved2[8]; -+ struct { -+ u16 timestamp; -+ u16 wr_porb_g; -+ u16 wr_prob_y; -+ u16 wr_prob_r; -+ } __packed test_write; -+ }; -+ u8 __reserved3[8]; -+} __packed; -+ -+struct qm_mcr_ceetm_ccgr_query { -+ u8 __reserved1[6]; -+ union { -+ struct { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ u8 ctl_reserved:1; -+ u8 ctl_wr_en_g:1; -+ u8 ctl_wr_en_y:1; -+ u8 ctl_wr_en_r:1; -+ u8 ctl_td_en:1; -+ u8 ctl_td_mode:1; -+ u8 ctl_cscn_en:1; -+ u8 ctl_mode:1; -+#else -+ u8 ctl_mode:1; -+ u8 ctl_cscn_en:1; -+ u8 ctl_td_mode:1; -+ u8 ctl_td_en:1; -+ u8 ctl_wr_en_r:1; -+ u8 ctl_wr_en_y:1; -+ u8 ctl_wr_en_g:1; -+ u8 ctl_reserved:1; -+#endif -+ u8 cdv; -+ u8 __reserved2[2]; -+ u8 oal; -+ u8 __reserved3; -+ struct qm_cgr_cs_thres cs_thres; -+ struct qm_cgr_cs_thres cs_thres_x; -+ struct qm_cgr_cs_thres td_thres; -+ struct qm_cgr_wr_parm wr_parm_g; -+ struct qm_cgr_wr_parm wr_parm_y; -+ struct qm_cgr_wr_parm wr_parm_r; -+ u16 cscn_targ_dcp; -+ u8 dcp_lsn; -+ u64 i_cnt:40; -+ u8 __reserved4[3]; -+ u64 a_cnt:40; -+ u32 cscn_targ_swp[4]; -+ } __packed cm_query; -+ struct { -+ u8 dnc; -+ u8 dn0; -+ u8 dn1; -+ u64 dnba:40; -+ u8 __reserved2[2]; -+ u16 dnth_0; -+ u8 __reserved3[2]; -+ u16 dnth_1; -+ u8 __reserved4[10]; -+ u16 dnacc_0; -+ u8 __reserved5[2]; -+ u16 dnacc_1; -+ u8 __reserved6[24]; -+ } __packed dn_query; -+ struct { -+ u8 __reserved2[24]; -+ struct __qm_mcr_querycongestion state; -+ } __packed congestion_state; -+ -+ }; -+} __packed; -+ -+struct qm_mcr_ceetm_cq_peek_pop_xsfdrread { -+ u8 stat; -+ u8 __reserved1[11]; -+ u16 dctidx; -+ struct qm_fd fd; -+ u8 __reserved2[32]; -+} __packed; -+ -+struct qm_mcr_ceetm_statistics_query { -+ u8 __reserved1[17]; -+ u64 frm_cnt:40; -+ u8 __reserved2[2]; -+ u64 byte_cnt:48; -+ u8 __reserved3[32]; -+} __packed; -+ -+struct qm_mc_result { -+ u8 verb; -+ u8 result; -+ union { -+ struct qm_mcr_initfq initfq; -+ struct qm_mcr_queryfq queryfq; -+ struct qm_mcr_queryfq_np queryfq_np; -+ struct qm_mcr_alterfq alterfq; -+ struct qm_mcr_initcgr initcgr; -+ struct qm_mcr_cgrtestwrite cgrtestwrite; -+ struct qm_mcr_querycgr querycgr; -+ struct qm_mcr_querycongestion querycongestion; -+ struct qm_mcr_querywq querywq; -+ struct qm_mcr_ceetm_lfqmt_config lfqmt_config; -+ struct qm_mcr_ceetm_lfqmt_query lfqmt_query; -+ struct qm_mcr_ceetm_cq_config cq_config; -+ struct qm_mcr_ceetm_cq_query cq_query; -+ struct qm_mcr_ceetm_dct_config dct_config; -+ struct qm_mcr_ceetm_dct_query dct_query; -+ struct qm_mcr_ceetm_class_scheduler_config csch_config; -+ struct qm_mcr_ceetm_class_scheduler_query csch_query; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_config mst_config; -+ struct qm_mcr_ceetm_mapping_shaper_tcfc_query mst_query; -+ struct qm_mcr_ceetm_ccgr_config ccgr_config; -+ struct qm_mcr_ceetm_ccgr_query ccgr_query; -+ struct qm_mcr_ceetm_cq_peek_pop_xsfdrread cq_ppxr; -+ struct qm_mcr_ceetm_statistics_query stats_query; -+ }; -+} __packed; -+ -+#define QM_MCR_VERB_RRID 0x80 -+#define QM_MCR_VERB_MASK QM_MCC_VERB_MASK -+#define QM_MCR_VERB_INITFQ_PARKED QM_MCC_VERB_INITFQ_PARKED -+#define QM_MCR_VERB_INITFQ_SCHED QM_MCC_VERB_INITFQ_SCHED -+#define QM_MCR_VERB_QUERYFQ QM_MCC_VERB_QUERYFQ -+#define QM_MCR_VERB_QUERYFQ_NP QM_MCC_VERB_QUERYFQ_NP -+#define QM_MCR_VERB_QUERYWQ QM_MCC_VERB_QUERYWQ -+#define QM_MCR_VERB_QUERYWQ_DEDICATED QM_MCC_VERB_QUERYWQ_DEDICATED -+#define QM_MCR_VERB_ALTER_SCHED QM_MCC_VERB_ALTER_SCHED -+#define QM_MCR_VERB_ALTER_FE QM_MCC_VERB_ALTER_FE -+#define QM_MCR_VERB_ALTER_RETIRE QM_MCC_VERB_ALTER_RETIRE -+#define QM_MCR_VERB_ALTER_OOS QM_MCC_VERB_ALTER_OOS -+#define QM_MCR_RESULT_NULL 0x00 -+#define QM_MCR_RESULT_OK 0xf0 -+#define QM_MCR_RESULT_ERR_FQID 0xf1 -+#define QM_MCR_RESULT_ERR_FQSTATE 0xf2 -+#define QM_MCR_RESULT_ERR_NOTEMPTY 0xf3 /* OOS fails if FQ is !empty */ -+#define QM_MCR_RESULT_ERR_BADCHANNEL 0xf4 -+#define QM_MCR_RESULT_PENDING 0xf8 -+#define QM_MCR_RESULT_ERR_BADCOMMAND 0xff -+#define QM_MCR_NP_STATE_FE 0x10 -+#define QM_MCR_NP_STATE_R 0x08 -+#define QM_MCR_NP_STATE_MASK 0x07 /* Reads FQD::STATE; */ -+#define QM_MCR_NP_STATE_OOS 0x00 -+#define QM_MCR_NP_STATE_RETIRED 0x01 -+#define QM_MCR_NP_STATE_TEN_SCHED 0x02 -+#define QM_MCR_NP_STATE_TRU_SCHED 0x03 -+#define QM_MCR_NP_STATE_PARKED 0x04 -+#define QM_MCR_NP_STATE_ACTIVE 0x05 -+#define QM_MCR_NP_PTR_MASK 0x07ff /* for RA[12] & OD[123] */ -+#define QM_MCR_NP_RA1_NRA(v) (((v) >> 14) & 0x3) /* FQD::NRA */ -+#define QM_MCR_NP_RA2_IT(v) (((v) >> 14) & 0x1) /* FQD::IT */ -+#define QM_MCR_NP_OD1_NOD(v) (((v) >> 14) & 0x3) /* FQD::NOD */ -+#define QM_MCR_NP_OD3_NPC(v) (((v) >> 14) & 0x3) /* FQD::NPC */ -+#define QM_MCR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */ -+#define QM_MCR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */ -+/* This extracts the state for congestion group 'n' from a query response. -+ * Eg. -+ * u8 cgr = [...]; -+ * struct qm_mc_result *res = [...]; -+ * printf("congestion group %d congestion state: %d\n", cgr, -+ * QM_MCR_QUERYCONGESTION(&res->querycongestion.state, cgr)); -+ */ -+#define __CGR_WORD(num) (num >> 5) -+#define __CGR_SHIFT(num) (num & 0x1f) -+#define __CGR_NUM (sizeof(struct __qm_mcr_querycongestion) << 3) -+static inline int QM_MCR_QUERYCONGESTION(struct __qm_mcr_querycongestion *p, -+ u8 cgr) -+{ -+ return p->__state[__CGR_WORD(cgr)] & (0x80000000 >> __CGR_SHIFT(cgr)); -+} -+ -+ -+/*********************/ -+/* Utility interface */ -+/*********************/ -+ -+/* Represents an allocator over a range of FQIDs. NB, accesses are not locked, -+ * spinlock them yourself if needed. */ -+struct qman_fqid_pool; -+ -+/* Create/destroy a FQID pool, num must be a multiple of 32. NB, _destroy() -+ * always succeeds, but returns non-zero if there were "leaked" FQID -+ * allocations. */ -+struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num); -+int qman_fqid_pool_destroy(struct qman_fqid_pool *pool); -+/* Alloc/free a FQID from the range. _alloc() returns zero for success. */ -+int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid); -+void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid); -+u32 qman_fqid_pool_used(struct qman_fqid_pool *pool); -+ -+/*******************************************************************/ -+/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */ -+/*******************************************************************/ -+ -+ /* Portal and Frame Queues */ -+ /* ----------------------- */ -+/* Represents a managed portal */ -+struct qman_portal; -+ -+/* This object type represents Qman frame queue descriptors (FQD), it is -+ * cacheline-aligned, and initialised by qman_create_fq(). The structure is -+ * defined further down. */ -+struct qman_fq; -+ -+/* This object type represents a Qman congestion group, it is defined further -+ * down. */ -+struct qman_cgr; -+ -+struct qman_portal_config { -+ /* If the caller enables DQRR stashing (and thus wishes to operate the -+ * portal from only one cpu), this is the logical CPU that the portal -+ * will stash to. Whether stashing is enabled or not, this setting is -+ * also used for any "core-affine" portals, ie. default portals -+ * associated to the corresponding cpu. -1 implies that there is no core -+ * affinity configured. */ -+ int cpu; -+ /* portal interrupt line */ -+ int irq; -+ /* the unique index of this portal */ -+ u32 index; -+ /* Is this portal shared? (If so, it has coarser locking and demuxes -+ * processing on behalf of other CPUs.) */ -+ int is_shared; -+ /* The portal's dedicated channel id, use this value for initialising -+ * frame queues to target this portal when scheduled. */ -+ u16 channel; -+ /* A mask of which pool channels this portal has dequeue access to -+ * (using QM_SDQCR_CHANNELS_POOL(n) for the bitmask) */ -+ u32 pools; -+}; -+ -+/* This enum, and the callback type that returns it, are used when handling -+ * dequeued frames via DQRR. Note that for "null" callbacks registered with the -+ * portal object (for handling dequeues that do not demux because contextB is -+ * NULL), the return value *MUST* be qman_cb_dqrr_consume. */ -+enum qman_cb_dqrr_result { -+ /* DQRR entry can be consumed */ -+ qman_cb_dqrr_consume, -+ /* Like _consume, but requests parking - FQ must be held-active */ -+ qman_cb_dqrr_park, -+ /* Does not consume, for DCA mode only. This allows out-of-order -+ * consumes by explicit calls to qman_dca() and/or the use of implicit -+ * DCA via EQCR entries. */ -+ qman_cb_dqrr_defer, -+ /* Stop processing without consuming this ring entry. Exits the current -+ * qman_poll_dqrr() or interrupt-handling, as appropriate. If within an -+ * interrupt handler, the callback would typically call -+ * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value, -+ * otherwise the interrupt will reassert immediately. */ -+ qman_cb_dqrr_stop, -+ /* Like qman_cb_dqrr_stop, but consumes the current entry. */ -+ qman_cb_dqrr_consume_stop -+}; -+typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry *dqrr); -+ -+/* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They -+ * are always consumed after the callback returns. */ -+typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq, -+ const struct qm_mr_entry *msg); -+ -+/* This callback type is used when handling DCP ERNs */ -+typedef void (*qman_cb_dc_ern)(struct qman_portal *qm, -+ const struct qm_mr_entry *msg); -+ -+/* s/w-visible states. Ie. tentatively scheduled + truly scheduled + active + -+ * held-active + held-suspended are just "sched". Things like "retired" will not -+ * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until -+ * then, to indicate it's completing and to gate attempts to retry the retire -+ * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's -+ * technically impossible in the case of enqueue DCAs (which refer to DQRR ring -+ * index rather than the FQ that ring entry corresponds to), so repeated park -+ * commands are allowed (if you're silly enough to try) but won't change FQ -+ * state, and the resulting park notifications move FQs from "sched" to -+ * "parked". */ -+enum qman_fq_state { -+ qman_fq_state_oos, -+ qman_fq_state_parked, -+ qman_fq_state_sched, -+ qman_fq_state_retired -+}; -+ -+/* Frame queue objects (struct qman_fq) are stored within memory passed to -+ * qman_create_fq(), as this allows stashing of caller-provided demux callback -+ * pointers at no extra cost to stashing of (driver-internal) FQ state. If the -+ * caller wishes to add per-FQ state and have it benefit from dequeue-stashing, -+ * they should; -+ * -+ * (a) extend the qman_fq structure with their state; eg. -+ * -+ * // myfq is allocated and driver_fq callbacks filled in; -+ * struct my_fq { -+ * struct qman_fq base; -+ * int an_extra_field; -+ * [ ... add other fields to be associated with each FQ ...] -+ * } *myfq = some_my_fq_allocator(); -+ * struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base); -+ * -+ * // in a dequeue callback, access extra fields from 'fq' via a cast; -+ * struct my_fq *myfq = (struct my_fq *)fq; -+ * do_something_with(myfq->an_extra_field); -+ * [...] -+ * -+ * (b) when and if configuring the FQ for context stashing, specify how ever -+ * many cachelines are required to stash 'struct my_fq', to accelerate not -+ * only the Qman driver but the callback as well. -+ */ -+ -+struct qman_fq_cb { -+ qman_cb_dqrr dqrr; /* for dequeued frames */ -+ qman_cb_mr ern; /* for s/w ERNs */ -+ qman_cb_mr fqs; /* frame-queue state changes*/ -+}; -+ -+struct qman_fq { -+ /* Caller of qman_create_fq() provides these demux callbacks */ -+ struct qman_fq_cb cb; -+ /* These are internal to the driver, don't touch. In particular, they -+ * may change, be removed, or extended (so you shouldn't rely on -+ * sizeof(qman_fq) being a constant). */ -+ spinlock_t fqlock; -+ u32 fqid; -+ volatile unsigned long flags; -+ enum qman_fq_state state; -+ int cgr_groupid; -+ struct rb_node node; -+#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP -+ u32 key; -+#endif -+}; -+ -+/* This callback type is used when handling congestion group entry/exit. -+ * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. */ -+typedef void (*qman_cb_cgr)(struct qman_portal *qm, -+ struct qman_cgr *cgr, int congested); -+ -+struct qman_cgr { -+ /* Set these prior to qman_create_cgr() */ -+ u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/ -+ qman_cb_cgr cb; -+ /* These are private to the driver */ -+ u16 chan; /* portal channel this object is created on */ -+ struct list_head node; -+}; -+ -+/* Flags to qman_create_fq() */ -+#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */ -+#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */ -+#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */ -+#define QMAN_FQ_FLAG_LOCKED 0x00000008 /* multi-core locking */ -+#define QMAN_FQ_FLAG_AS_IS 0x00000010 /* query h/w state */ -+#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */ -+ -+/* Flags to qman_destroy_fq() */ -+#define QMAN_FQ_DESTROY_PARKED 0x00000001 /* FQ can be parked or OOS */ -+ -+/* Flags from qman_fq_state() */ -+#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */ -+#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */ -+#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */ -+#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */ -+#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */ -+#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */ -+ -+/* Flags to qman_init_fq() */ -+#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */ -+#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */ -+ -+/* Flags to qman_volatile_dequeue() */ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+#define QMAN_VOLATILE_FLAG_WAIT 0x00000001 /* wait if VDQCR is in use */ -+#define QMAN_VOLATILE_FLAG_WAIT_INT 0x00000002 /* if wait, interruptible? */ -+#define QMAN_VOLATILE_FLAG_FINISH 0x00000004 /* wait till VDQCR completes */ -+#endif -+ -+/* Flags to qman_enqueue(). NB, the strange numbering is to align with hardware, -+ * bit-wise. (NB: the PME API is sensitive to these precise numberings too, so -+ * any change here should be audited in PME.) */ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT -+#define QMAN_ENQUEUE_FLAG_WAIT 0x00010000 /* wait if EQCR is full */ -+#define QMAN_ENQUEUE_FLAG_WAIT_INT 0x00020000 /* if wait, interruptible? */ -+#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC -+#define QMAN_ENQUEUE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */ -+#endif -+#endif -+#define QMAN_ENQUEUE_FLAG_WATCH_CGR 0x00080000 /* watch congestion state */ -+#define QMAN_ENQUEUE_FLAG_DCA 0x00008000 /* perform enqueue-DCA */ -+#define QMAN_ENQUEUE_FLAG_DCA_PARK 0x00004000 /* If DCA, requests park */ -+#define QMAN_ENQUEUE_FLAG_DCA_PTR(p) /* If DCA, p is DQRR entry */ \ -+ (((u32)(p) << 2) & 0x00000f00) -+#define QMAN_ENQUEUE_FLAG_C_GREEN 0x00000000 /* choose one C_*** flag */ -+#define QMAN_ENQUEUE_FLAG_C_YELLOW 0x00000008 -+#define QMAN_ENQUEUE_FLAG_C_RED 0x00000010 -+#define QMAN_ENQUEUE_FLAG_C_OVERRIDE 0x00000018 -+/* For the ORP-specific qman_enqueue_orp() variant; -+ * - this flag indicates "Not Last In Sequence", ie. all but the final fragment -+ * of a frame. */ -+#define QMAN_ENQUEUE_FLAG_NLIS 0x01000000 -+/* - this flag performs no enqueue but fills in an ORP sequence number that -+ * would otherwise block it (eg. if a frame has been dropped). */ -+#define QMAN_ENQUEUE_FLAG_HOLE 0x02000000 -+/* - this flag performs no enqueue but advances NESN to the given sequence -+ * number. */ -+#define QMAN_ENQUEUE_FLAG_NESN 0x04000000 -+ -+/* Flags to qman_modify_cgr() */ -+#define QMAN_CGR_FLAG_USE_INIT 0x00000001 -+#define QMAN_CGR_MODE_FRAME 0x00000001 -+ -+ /* Portal Management */ -+ /* ----------------- */ -+/** -+ * qman_get_portal_config - get portal configuration settings -+ * -+ * This returns a read-only view of the current cpu's affine portal settings. -+ */ -+const struct qman_portal_config *qman_get_portal_config(void); -+ -+/** -+ * qman_irqsource_get - return the portal work that is interrupt-driven -+ * -+ * Returns a bitmask of QM_PIRQ_**I processing sources that are currently -+ * enabled for interrupt handling on the current cpu's affine portal. These -+ * sources will trigger the portal interrupt and the interrupt handler (or a -+ * tasklet/bottom-half it defers to) will perform the corresponding processing -+ * work. The qman_poll_***() functions will only process sources that are not in -+ * this bitmask. If the current CPU is sharing a portal hosted on another CPU, -+ * this always returns zero. -+ */ -+u32 qman_irqsource_get(void); -+ -+/** -+ * qman_irqsource_add - add processing sources to be interrupt-driven -+ * @bits: bitmask of QM_PIRQ_**I processing sources -+ * -+ * Adds processing sources that should be interrupt-driven (rather than -+ * processed via qman_poll_***() functions). Returns zero for success, or -+ * -EINVAL if the current CPU is sharing a portal hosted on another CPU. -+ */ -+int qman_irqsource_add(u32 bits); -+ -+/** -+ * qman_irqsource_remove - remove processing sources from being interrupt-driven -+ * @bits: bitmask of QM_PIRQ_**I processing sources -+ * -+ * Removes processing sources from being interrupt-driven, so that they will -+ * instead be processed via qman_poll_***() functions. Returns zero for success, -+ * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. -+ */ -+int qman_irqsource_remove(u32 bits); -+ -+/** -+ * qman_affine_cpus - return a mask of cpus that have affine portals -+ */ -+const cpumask_t *qman_affine_cpus(void); -+ -+/** -+ * qman_affine_channel - return the channel ID of an portal -+ * @cpu: the cpu whose affine portal is the subject of the query -+ * -+ * If @cpu is -1, the affine portal for the current CPU will be used. It is a -+ * bug to call this function for any value of @cpu (other than -1) that is not a -+ * member of the mask returned from qman_affine_cpus(). -+ */ -+u16 qman_affine_channel(int cpu); -+ -+/** -+ * qman_get_affine_portal - return the portal pointer affine to cpu -+ * @cpu: the cpu whose affine portal is the subject of the query -+ * -+ */ -+void *qman_get_affine_portal(int cpu); -+ -+/** -+ * qman_poll_dqrr - process DQRR (fast-path) entries -+ * @limit: the maximum number of DQRR entries to process -+ * -+ * Use of this function requires that DQRR processing not be interrupt-driven. -+ * Ie. the value returned by qman_irqsource_get() should not include -+ * QM_PIRQ_DQRI. If the current CPU is sharing a portal hosted on another CPU, -+ * this function will return -EINVAL, otherwise the return value is >=0 and -+ * represents the number of DQRR entries processed. -+ */ -+int qman_poll_dqrr(unsigned int limit); -+ -+/** -+ * qman_poll_slow - process anything (except DQRR) that isn't interrupt-driven. -+ * -+ * This function does any portal processing that isn't interrupt-driven. If the -+ * current CPU is sharing a portal hosted on another CPU, this function will -+ * return (u32)-1, otherwise the return value is a bitmask of QM_PIRQ_* sources -+ * indicating what interrupt sources were actually processed by the call. -+ */ -+u32 qman_poll_slow(void); -+ -+/** -+ * qman_poll - legacy wrapper for qman_poll_dqrr() and qman_poll_slow() -+ * -+ * Dispatcher logic on a cpu can use this to trigger any maintenance of the -+ * affine portal. There are two classes of portal processing in question; -+ * fast-path (which involves demuxing dequeue ring (DQRR) entries and tracking -+ * enqueue ring (EQCR) consumption), and slow-path (which involves EQCR -+ * thresholds, congestion state changes, etc). This function does whatever -+ * processing is not triggered by interrupts. -+ * -+ * Note, if DQRR and some slow-path processing are poll-driven (rather than -+ * interrupt-driven) then this function uses a heuristic to determine how often -+ * to run slow-path processing - as slow-path processing introduces at least a -+ * minimum latency each time it is run, whereas fast-path (DQRR) processing is -+ * close to zero-cost if there is no work to be done. Applications can tune this -+ * behaviour themselves by using qman_poll_dqrr() and qman_poll_slow() directly -+ * rather than going via this wrapper. -+ */ -+void qman_poll(void); -+ -+/** -+ * qman_stop_dequeues - Stop h/w dequeuing to the s/w portal -+ * -+ * Disables DQRR processing of the portal. This is reference-counted, so -+ * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to -+ * truly re-enable dequeuing. -+ */ -+void qman_stop_dequeues(void); -+ -+/** -+ * qman_start_dequeues - (Re)start h/w dequeuing to the s/w portal -+ * -+ * Enables DQRR processing of the portal. This is reference-counted, so -+ * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to -+ * truly re-enable dequeuing. -+ */ -+void qman_start_dequeues(void); -+ -+/** -+ * qman_static_dequeue_add - Add pool channels to the portal SDQCR -+ * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n) -+ * -+ * Adds a set of pool channels to the portal's static dequeue command register -+ * (SDQCR). The requested pools are limited to those the portal has dequeue -+ * access to. -+ */ -+void qman_static_dequeue_add(u32 pools); -+ -+/** -+ * qman_static_dequeue_del - Remove pool channels from the portal SDQCR -+ * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n) -+ * -+ * Removes a set of pool channels from the portal's static dequeue command -+ * register (SDQCR). The requested pools are limited to those the portal has -+ * dequeue access to. -+ */ -+void qman_static_dequeue_del(u32 pools); -+ -+/** -+ * qman_static_dequeue_get - return the portal's current SDQCR -+ * -+ * Returns the portal's current static dequeue command register (SDQCR). The -+ * entire register is returned, so if only the currently-enabled pool channels -+ * are desired, mask the return value with QM_SDQCR_CHANNELS_POOL_MASK. -+ */ -+u32 qman_static_dequeue_get(void); -+ -+/** -+ * qman_dca - Perform a Discrete Consumption Acknowledgement -+ * @dq: the DQRR entry to be consumed -+ * @park_request: indicates whether the held-active @fq should be parked -+ * -+ * Only allowed in DCA-mode portals, for DQRR entries whose handler callback had -+ * previously returned 'qman_cb_dqrr_defer'. NB, as with the other APIs, this -+ * does not take a 'portal' argument but implies the core affine portal from the -+ * cpu that is currently executing the function. For reasons of locking, this -+ * function must be called from the same CPU as that which processed the DQRR -+ * entry in the first place. -+ */ -+void qman_dca(struct qm_dqrr_entry *dq, int park_request); -+ -+/** -+ * qman_eqcr_is_empty - Determine if portal's EQCR is empty -+ * -+ * For use in situations where a cpu-affine caller needs to determine when all -+ * enqueues for the local portal have been processed by Qman but can't use the -+ * QMAN_ENQUEUE_FLAG_WAIT_SYNC flag to do this from the final qman_enqueue(). -+ * The function forces tracking of EQCR consumption (which normally doesn't -+ * happen until enqueue processing needs to find space to put new enqueue -+ * commands), and returns zero if the ring still has unprocessed entries, -+ * non-zero if it is empty. -+ */ -+int qman_eqcr_is_empty(void); -+ -+/** -+ * qman_set_dc_ern - Set the handler for DCP enqueue rejection notifications -+ * @handler: callback for processing DCP ERNs -+ * @affine: whether this handler is specific to the locally affine portal -+ * -+ * If a hardware block's interface to Qman (ie. its direct-connect portal, or -+ * DCP) is configured not to receive enqueue rejections, then any enqueues -+ * through that DCP that are rejected will be sent to a given software portal. -+ * If @affine is non-zero, then this handler will only be used for DCP ERNs -+ * received on the portal affine to the current CPU. If multiple CPUs share a -+ * portal and they all call this function, they will be setting the handler for -+ * the same portal! If @affine is zero, then this handler will be global to all -+ * portals handled by this instance of the driver. Only those portals that do -+ * not have their own affine handler will use the global handler. -+ */ -+void qman_set_dc_ern(qman_cb_dc_ern handler, int affine); -+ -+ /* FQ management */ -+ /* ------------- */ -+/** -+ * qman_create_fq - Allocates a FQ -+ * @fqid: the index of the FQD to encapsulate, must be "Out of Service" -+ * @flags: bit-mask of QMAN_FQ_FLAG_*** options -+ * @fq: memory for storing the 'fq', with callbacks filled in -+ * -+ * Creates a frame queue object for the given @fqid, unless the -+ * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is -+ * dynamically allocated (or the function fails if none are available). Once -+ * created, the caller should not touch the memory at 'fq' except as extended to -+ * adjacent memory for user-defined fields (see the definition of "struct -+ * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to -+ * pre-existing frame-queues that aren't to be otherwise interfered with, it -+ * prevents all other modifications to the frame queue. The TO_DCPORTAL flag -+ * causes the driver to honour any contextB modifications requested in the -+ * qm_init_fq() API, as this indicates the frame queue will be consumed by a -+ * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by -+ * software portals, the contextB field is controlled by the driver and can't be -+ * modified by the caller. If the AS_IS flag is specified, management commands -+ * will be used on portal @p to query state for frame queue @fqid and construct -+ * a frame queue object based on that, rather than assuming/requiring that it be -+ * Out of Service. -+ */ -+int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq); -+ -+/** -+ * qman_destroy_fq - Deallocates a FQ -+ * @fq: the frame queue object to release -+ * @flags: bit-mask of QMAN_FQ_FREE_*** options -+ * -+ * The memory for this frame queue object ('fq' provided in qman_create_fq()) is -+ * not deallocated but the caller regains ownership, to do with as desired. The -+ * FQ must be in the 'out-of-service' state unless the QMAN_FQ_FREE_PARKED flag -+ * is specified, in which case it may also be in the 'parked' state. -+ */ -+void qman_destroy_fq(struct qman_fq *fq, u32 flags); -+ -+/** -+ * qman_fq_fqid - Queries the frame queue ID of a FQ object -+ * @fq: the frame queue object to query -+ */ -+u32 qman_fq_fqid(struct qman_fq *fq); -+ -+/** -+ * qman_fq_state - Queries the state of a FQ object -+ * @fq: the frame queue object to query -+ * @state: pointer to state enum to return the FQ scheduling state -+ * @flags: pointer to state flags to receive QMAN_FQ_STATE_*** bitmask -+ * -+ * Queries the state of the FQ object, without performing any h/w commands. -+ * This captures the state, as seen by the driver, at the time the function -+ * executes. -+ */ -+void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags); -+ -+/** -+ * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled" -+ * @fq: the frame queue object to modify, must be 'parked' or new. -+ * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options -+ * @opts: the FQ-modification settings, as defined in the low-level API -+ * -+ * The @opts parameter comes from the low-level portal API. Select -+ * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled -+ * rather than parked. NB, @opts can be NULL. -+ * -+ * Note that some fields and options within @opts may be ignored or overwritten -+ * by the driver; -+ * 1. the 'count' and 'fqid' fields are always ignored (this operation only -+ * affects one frame queue: @fq). -+ * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated -+ * 'fqd' structure's 'context_b' field are sometimes overwritten; -+ * - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is -+ * initialised to a value used by the driver for demux. -+ * - if context_b is initialised for demux, so is context_a in case stashing -+ * is requested (see item 4). -+ * (So caller control of context_b is only possible for TO_DCPORTAL frame queue -+ * objects.) -+ * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's -+ * 'dest::channel' field will be overwritten to match the portal used to issue -+ * the command. If the WE_DESTWQ write-enable bit had already been set by the -+ * caller, the channel workqueue will be left as-is, otherwise the write-enable -+ * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag -+ * isn't set, the destination channel/workqueue fields and the write-enable bit -+ * are left as-is. -+ * 4. if the driver overwrites context_a/b for demux, then if -+ * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite -+ * context_a.address fields and will leave the stashing fields provided by the -+ * user alone, otherwise it will zero out the context_a.stashing fields. -+ */ -+int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts); -+ -+/** -+ * qman_schedule_fq - Schedules a FQ -+ * @fq: the frame queue object to schedule, must be 'parked' -+ * -+ * Schedules the frame queue, which must be Parked, which takes it to -+ * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level. -+ */ -+int qman_schedule_fq(struct qman_fq *fq); -+ -+/** -+ * qman_retire_fq - Retires a FQ -+ * @fq: the frame queue object to retire -+ * @flags: FQ flags (as per qman_fq_state) if retirement completes immediately -+ * -+ * Retires the frame queue. This returns zero if it succeeds immediately, +1 if -+ * the retirement was started asynchronously, otherwise it returns negative for -+ * failure. When this function returns zero, @flags is set to indicate whether -+ * the retired FQ is empty and/or whether it has any ORL fragments (to show up -+ * as ERNs). Otherwise the corresponding flags will be known when a subsequent -+ * FQRN message shows up on the portal's message ring. -+ * -+ * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or -+ * Active state), the completion will be via the message ring as a FQRN - but -+ * the corresponding callback may occur before this function returns!! Ie. the -+ * caller should be prepared to accept the callback as the function is called, -+ * not only once it has returned. -+ */ -+int qman_retire_fq(struct qman_fq *fq, u32 *flags); -+ -+/** -+ * qman_oos_fq - Puts a FQ "out of service" -+ * @fq: the frame queue object to be put out-of-service, must be 'retired' -+ * -+ * The frame queue must be retired and empty, and if any order restoration list -+ * was released as ERNs at the time of retirement, they must all be consumed. -+ */ -+int qman_oos_fq(struct qman_fq *fq); -+ -+/** -+ * qman_fq_flow_control - Set the XON/XOFF state of a FQ -+ * @fq: the frame queue object to be set to XON/XOFF state, must not be 'oos', -+ * or 'retired' or 'parked' state -+ * @xon: boolean to set fq in XON or XOFF state -+ * -+ * The frame should be in Tentatively Scheduled state or Truly Schedule sate, -+ * otherwise the IFSI interrupt will be asserted. -+ */ -+int qman_fq_flow_control(struct qman_fq *fq, int xon); -+ -+/** -+ * qman_query_fq - Queries FQD fields (via h/w query command) -+ * @fq: the frame queue object to be queried -+ * @fqd: storage for the queried FQD fields -+ */ -+int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd); -+ -+/** -+ * qman_query_fq_np - Queries non-programmable FQD fields -+ * @fq: the frame queue object to be queried -+ * @np: storage for the queried FQD fields -+ */ -+int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np); -+ -+/** -+ * qman_query_wq - Queries work queue lengths -+ * @query_dedicated: If non-zero, query length of WQs in the channel dedicated -+ * to this software portal. Otherwise, query length of WQs in a -+ * channel specified in wq. -+ * @wq: storage for the queried WQs lengths. Also specified the channel to -+ * to query if query_dedicated is zero. -+ */ -+int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq); -+ -+/** -+ * qman_volatile_dequeue - Issue a volatile dequeue command -+ * @fq: the frame queue object to dequeue from -+ * @flags: a bit-mask of QMAN_VOLATILE_FLAG_*** options -+ * @vdqcr: bit mask of QM_VDQCR_*** options, as per qm_dqrr_vdqcr_set() -+ * -+ * Attempts to lock access to the portal's VDQCR volatile dequeue functionality. -+ * The function will block and sleep if QMAN_VOLATILE_FLAG_WAIT is specified and -+ * the VDQCR is already in use, otherwise returns non-zero for failure. If -+ * QMAN_VOLATILE_FLAG_FINISH is specified, the function will only return once -+ * the VDQCR command has finished executing (ie. once the callback for the last -+ * DQRR entry resulting from the VDQCR command has been called). If not using -+ * the FINISH flag, completion can be determined either by detecting the -+ * presence of the QM_DQRR_STAT_UNSCHEDULED and QM_DQRR_STAT_DQCR_EXPIRED bits -+ * in the "stat" field of the "struct qm_dqrr_entry" passed to the FQ's dequeue -+ * callback, or by waiting for the QMAN_FQ_STATE_VDQCR bit to disappear from the -+ * "flags" retrieved from qman_fq_state(). -+ */ -+int qman_volatile_dequeue(struct qman_fq *fq, u32 flags, u32 vdqcr); -+ -+/** -+ * qman_enqueue - Enqueue a frame to a frame queue -+ * @fq: the frame queue object to enqueue to -+ * @fd: a descriptor of the frame to be enqueued -+ * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options -+ * -+ * Fills an entry in the EQCR of portal @qm to enqueue the frame described by -+ * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid' -+ * field is ignored. The return value is non-zero on error, such as ring full -+ * (and FLAG_WAIT not specified), congestion avoidance (FLAG_WATCH_CGR -+ * specified), etc. If the ring is full and FLAG_WAIT is specified, this -+ * function will block. If FLAG_INTERRUPT is set, the EQCI bit of the portal -+ * interrupt will assert when Qman consumes the EQCR entry (subject to "status -+ * disable", "enable", and "inhibit" registers). If FLAG_DCA is set, Qman will -+ * perform an implied "discrete consumption acknowledgement" on the dequeue -+ * ring's (DQRR) entry, at the ring index specified by the FLAG_DCA_IDX(x) -+ * macro. (As an alternative to issuing explicit DCA actions on DQRR entries, -+ * this implicit DCA can delay the release of a "held active" frame queue -+ * corresponding to a DQRR entry until Qman consumes the EQCR entry - providing -+ * order-preservation semantics in packet-forwarding scenarios.) If FLAG_DCA is -+ * set, then FLAG_DCA_PARK can also be set to imply that the DQRR consumption -+ * acknowledgement should "park request" the "held active" frame queue. Ie. -+ * when the portal eventually releases that frame queue, it will be left in the -+ * Parked state rather than Tentatively Scheduled or Truly Scheduled. If the -+ * portal is watching congestion groups, the QMAN_ENQUEUE_FLAG_WATCH_CGR flag -+ * is requested, and the FQ is a member of a congestion group, then this -+ * function returns -EAGAIN if the congestion group is currently congested. -+ * Note, this does not eliminate ERNs, as the async interface means we can be -+ * sending enqueue commands to an un-congested FQ that becomes congested before -+ * the enqueue commands are processed, but it does minimise needless thrashing -+ * of an already busy hardware resource by throttling many of the to-be-dropped -+ * enqueues "at the source". -+ */ -+int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags); -+ -+typedef int (*qman_cb_precommit) (void *arg); -+/** -+ * qman_enqueue_precommit - Enqueue a frame to a frame queue and call cb -+ * @fq: the frame queue object to enqueue to -+ * @fd: a descriptor of the frame to be enqueued -+ * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options -+ * @cb: user supplied callback function to invoke before writing commit verb. -+ * @cb_arg: callback function argument -+ * -+ * This is similar to qman_enqueue except that it will invoke a user supplied -+ * callback function just before writng the commit verb. This is useful -+ * when the user want to do something *just before* enqueuing the request and -+ * the enqueue can't fail. -+ */ -+int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd, -+ u32 flags, qman_cb_precommit cb, void *cb_arg); -+ -+/** -+ * qman_enqueue_orp - Enqueue a frame to a frame queue using an ORP -+ * @fq: the frame queue object to enqueue to -+ * @fd: a descriptor of the frame to be enqueued -+ * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options -+ * @orp: the frame queue object used as an order restoration point. -+ * @orp_seqnum: the sequence number of this frame in the order restoration path -+ * -+ * Similar to qman_enqueue(), but with the addition of an Order Restoration -+ * Point (@orp) and corresponding sequence number (@orp_seqnum) for this -+ * enqueue operation to employ order restoration. Each frame queue object acts -+ * as an Order Definition Point (ODP) by providing each frame dequeued from it -+ * with an incrementing sequence number, this value is generally ignored unless -+ * that sequence of dequeued frames will need order restoration later. Each -+ * frame queue object also encapsulates an Order Restoration Point (ORP), which -+ * is a re-assembly context for re-ordering frames relative to their sequence -+ * numbers as they are enqueued. The ORP does not have to be within the frame -+ * queue that receives the enqueued frame, in fact it is usually the frame -+ * queue from which the frames were originally dequeued. For the purposes of -+ * order restoration, multiple frames (or "fragments") can be enqueued for a -+ * single sequence number by setting the QMAN_ENQUEUE_FLAG_NLIS flag for all -+ * enqueues except the final fragment of a given sequence number. Ordering -+ * between sequence numbers is guaranteed, even if fragments of different -+ * sequence numbers are interlaced with one another. Fragments of the same -+ * sequence number will retain the order in which they are enqueued. If no -+ * enqueue is to performed, QMAN_ENQUEUE_FLAG_HOLE indicates that the given -+ * sequence number is to be "skipped" by the ORP logic (eg. if a frame has been -+ * dropped from a sequence), or QMAN_ENQUEUE_FLAG_NESN indicates that the given -+ * sequence number should become the ORP's "Next Expected Sequence Number". -+ * -+ * Side note: a frame queue object can be used purely as an ORP, without -+ * carrying any frames at all. Care should be taken not to deallocate a frame -+ * queue object that is being actively used as an ORP, as a future allocation -+ * of the frame queue object may start using the internal ORP before the -+ * previous use has finished. -+ */ -+int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags, -+ struct qman_fq *orp, u16 orp_seqnum); -+ -+/** -+ * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs -+ * @result: is set by the API to the base FQID of the allocated range -+ * @count: the number of FQIDs required -+ * @align: required alignment of the allocated range -+ * @partial: non-zero if the API can return fewer than @count FQIDs -+ * -+ * Returns the number of frame queues allocated, or a negative error code. If -+ * @partial is non zero, the allocation request may return a smaller range of -+ * FQs than requested (though alignment will be as requested). If @partial is -+ * zero, the return value will either be 'count' or negative. -+ */ -+int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial); -+static inline int qman_alloc_fqid(u32 *result) -+{ -+ int ret = qman_alloc_fqid_range(result, 1, 0, 0); -+ return (ret > 0) ? 0 : ret; -+} -+ -+/** -+ * qman_release_fqid_range - Release the specified range of frame queue IDs -+ * @fqid: the base FQID of the range to deallocate -+ * @count: the number of FQIDs in the range -+ * -+ * This function can also be used to seed the allocator with ranges of FQIDs -+ * that it can subsequently allocate from. -+ */ -+void qman_release_fqid_range(u32 fqid, unsigned int count); -+static inline void qman_release_fqid(u32 fqid) -+{ -+ qman_release_fqid_range(fqid, 1); -+} -+ -+void qman_seed_fqid_range(u32 fqid, unsigned int count); -+ -+ -+int qman_shutdown_fq(u32 fqid); -+ -+/** -+ * qman_reserve_fqid_range - Reserve the specified range of frame queue IDs -+ * @fqid: the base FQID of the range to deallocate -+ * @count: the number of FQIDs in the range -+ */ -+int qman_reserve_fqid_range(u32 fqid, unsigned int count); -+static inline int qman_reserve_fqid(u32 fqid) -+{ -+ return qman_reserve_fqid_range(fqid, 1); -+} -+ -+ /* Pool-channel management */ -+ /* ----------------------- */ -+/** -+ * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs -+ * @result: is set by the API to the base pool-channel ID of the allocated range -+ * @count: the number of pool-channel IDs required -+ * @align: required alignment of the allocated range -+ * @partial: non-zero if the API can return fewer than @count -+ * -+ * Returns the number of pool-channel IDs allocated, or a negative error code. -+ * If @partial is non zero, the allocation request may return a smaller range of -+ * than requested (though alignment will be as requested). If @partial is zero, -+ * the return value will either be 'count' or negative. -+ */ -+int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial); -+static inline int qman_alloc_pool(u32 *result) -+{ -+ int ret = qman_alloc_pool_range(result, 1, 0, 0); -+ return (ret > 0) ? 0 : ret; -+} -+ -+/** -+ * qman_release_pool_range - Release the specified range of pool-channel IDs -+ * @id: the base pool-channel ID of the range to deallocate -+ * @count: the number of pool-channel IDs in the range -+ */ -+void qman_release_pool_range(u32 id, unsigned int count); -+static inline void qman_release_pool(u32 id) -+{ -+ qman_release_pool_range(id, 1); -+} -+ -+/** -+ * qman_reserve_pool_range - Reserve the specified range of pool-channel IDs -+ * @id: the base pool-channel ID of the range to reserve -+ * @count: the number of pool-channel IDs in the range -+ */ -+int qman_reserve_pool_range(u32 id, unsigned int count); -+static inline int qman_reserve_pool(u32 id) -+{ -+ return qman_reserve_pool_range(id, 1); -+} -+ -+void qman_seed_pool_range(u32 id, unsigned int count); -+ -+ /* CGR management */ -+ /* -------------- */ -+/** -+ * qman_create_cgr - Register a congestion group object -+ * @cgr: the 'cgr' object, with fields filled in -+ * @flags: QMAN_CGR_FLAG_* values -+ * @opts: optional state of CGR settings -+ * -+ * Registers this object to receiving congestion entry/exit callbacks on the -+ * portal affine to the cpu portal on which this API is executed. If opts is -+ * NULL then only the callback (cgr->cb) function is registered. If @flags -+ * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset -+ * any unspecified parameters) will be used rather than a modify hw hardware -+ * (which only modifies the specified parameters). -+ */ -+int qman_create_cgr(struct qman_cgr *cgr, u32 flags, -+ struct qm_mcc_initcgr *opts); -+ -+/** -+ * qman_create_cgr_to_dcp - Register a congestion group object to DCP portal -+ * @cgr: the 'cgr' object, with fields filled in -+ * @flags: QMAN_CGR_FLAG_* values -+ * @dcp_portal: the DCP portal to which the cgr object is registered. -+ * @opts: optional state of CGR settings -+ * -+ */ -+int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal, -+ struct qm_mcc_initcgr *opts); -+ -+/** -+ * qman_delete_cgr - Deregisters a congestion group object -+ * @cgr: the 'cgr' object to deregister -+ * -+ * "Unplugs" this CGR object from the portal affine to the cpu on which this API -+ * is executed. This must be excuted on the same affine portal on which it was -+ * created. -+ */ -+int qman_delete_cgr(struct qman_cgr *cgr); -+ -+/** -+ * qman_delete_cgr_safe - Deregisters a congestion group object from any CPU -+ * @cgr: the 'cgr' object to deregister -+ * -+ * This will select the proper CPU and run there qman_delete_cgr(). -+ */ -+void qman_delete_cgr_safe(struct qman_cgr *cgr); -+ -+/** -+ * qman_modify_cgr - Modify CGR fields -+ * @cgr: the 'cgr' object to modify -+ * @flags: QMAN_CGR_FLAG_* values -+ * @opts: the CGR-modification settings -+ * -+ * The @opts parameter comes from the low-level portal API, and can be NULL. -+ * Note that some fields and options within @opts may be ignored or overwritten -+ * by the driver, in particular the 'cgrid' field is ignored (this operation -+ * only affects the given CGR object). If @flags contains -+ * QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset any -+ * unspecified parameters) will be used rather than a modify hw hardware (which -+ * only modifies the specified parameters). -+ */ -+int qman_modify_cgr(struct qman_cgr *cgr, u32 flags, -+ struct qm_mcc_initcgr *opts); -+ -+/** -+* qman_query_cgr - Queries CGR fields -+* @cgr: the 'cgr' object to query -+* @result: storage for the queried congestion group record -+*/ -+int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *result); -+ -+/** -+ * qman_query_congestion - Queries the state of all congestion groups -+ * @congestion: storage for the queried state of all congestion groups -+ */ -+int qman_query_congestion(struct qm_mcr_querycongestion *congestion); -+ -+/** -+ * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs -+ * @result: is set by the API to the base CGR ID of the allocated range -+ * @count: the number of CGR IDs required -+ * @align: required alignment of the allocated range -+ * @partial: non-zero if the API can return fewer than @count -+ * -+ * Returns the number of CGR IDs allocated, or a negative error code. -+ * If @partial is non zero, the allocation request may return a smaller range of -+ * than requested (though alignment will be as requested). If @partial is zero, -+ * the return value will either be 'count' or negative. -+ */ -+int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial); -+static inline int qman_alloc_cgrid(u32 *result) -+{ -+ int ret = qman_alloc_cgrid_range(result, 1, 0, 0); -+ return (ret > 0) ? 0 : ret; -+} -+ -+/** -+ * qman_release_cgrid_range - Release the specified range of CGR IDs -+ * @id: the base CGR ID of the range to deallocate -+ * @count: the number of CGR IDs in the range -+ */ -+void qman_release_cgrid_range(u32 id, unsigned int count); -+static inline void qman_release_cgrid(u32 id) -+{ -+ qman_release_cgrid_range(id, 1); -+} -+ -+/** -+ * qman_reserve_cgrid_range - Reserve the specified range of CGR ID -+ * @id: the base CGR ID of the range to reserve -+ * @count: the number of CGR IDs in the range -+ */ -+int qman_reserve_cgrid_range(u32 id, unsigned int count); -+static inline int qman_reserve_cgrid(u32 id) -+{ -+ return qman_reserve_cgrid_range(id, 1); -+} -+ -+void qman_seed_cgrid_range(u32 id, unsigned int count); -+ -+ -+ /* Helpers */ -+ /* ------- */ -+/** -+ * qman_poll_fq_for_init - Check if an FQ has been initialised from OOS -+ * @fqid: the FQID that will be initialised by other s/w -+ * -+ * In many situations, a FQID is provided for communication between s/w -+ * entities, and whilst the consumer is responsible for initialising and -+ * scheduling the FQ, the producer(s) generally create a wrapper FQ object using -+ * and only call qman_enqueue() (no FQ initialisation, scheduling, etc). Ie; -+ * qman_create_fq(..., QMAN_FQ_FLAG_NO_MODIFY, ...); -+ * However, data can not be enqueued to the FQ until it is initialised out of -+ * the OOS state - this function polls for that condition. It is particularly -+ * useful for users of IPC functions - each endpoint's Rx FQ is the other -+ * endpoint's Tx FQ, so each side can initialise and schedule their Rx FQ object -+ * and then use this API on the (NO_MODIFY) Tx FQ object in order to -+ * synchronise. The function returns zero for success, +1 if the FQ is still in -+ * the OOS state, or negative if there was an error. -+ */ -+static inline int qman_poll_fq_for_init(struct qman_fq *fq) -+{ -+ struct qm_mcr_queryfq_np np; -+ int err; -+ err = qman_query_fq_np(fq, &np); -+ if (err) -+ return err; -+ if ((np.state & QM_MCR_NP_STATE_MASK) == QM_MCR_NP_STATE_OOS) -+ return 1; -+ return 0; -+} -+ -+ /* -------------- */ -+ /* CEETM :: types */ -+ /* -------------- */ -+/** -+ * Token Rate Structure -+ * Shaping rates are based on a "credit" system and a pre-configured h/w -+ * internal timer. The following type represents a shaper "rate" parameter as a -+ * fractional number of "tokens". Here's how it works. This (fractional) number -+ * of tokens is added to the shaper's "credit" every time the h/w timer elapses -+ * (up to a limit which is set by another shaper parameter). Every time a frame -+ * is enqueued through a shaper, the shaper deducts as many tokens as there are -+ * bytes of data in the enqueued frame. A shaper will not allow itself to -+ * enqueue any frames if its token count is negative. As such; -+ * -+ * The rate at which data is enqueued is limited by the -+ * rate at which tokens are added. -+ * -+ * Therefore if the user knows the period between these h/w timer updates in -+ * seconds, they can calculate the maximum traffic rate of the shaper (in -+ * bytes-per-second) from the token rate. And vice versa, they can calculate -+ * the token rate to use in order to achieve a given traffic rate. -+ */ -+struct qm_ceetm_rate { -+ /* The token rate is; whole + (fraction/8192) */ -+ u32 whole:11; /* 0..2047 */ -+ u32 fraction:13; /* 0..8191 */ -+}; -+ -+struct qm_ceetm_weight_code { -+ /* The weight code is; 5 msbits + 3 lsbits */ -+ u8 y:5; -+ u8 x:3; -+}; -+ -+struct qm_ceetm { -+ unsigned int idx; -+ struct list_head sub_portals; -+ struct list_head lnis; -+ unsigned int sp_range[2]; -+ unsigned int lni_range[2]; -+}; -+ -+struct qm_ceetm_sp { -+ struct list_head node; -+ unsigned int idx; -+ unsigned int dcp_idx; -+ int is_claimed; -+ struct qm_ceetm_lni *lni; -+}; -+ -+/* Logical Network Interface */ -+struct qm_ceetm_lni { -+ struct list_head node; -+ unsigned int idx; -+ unsigned int dcp_idx; -+ int is_claimed; -+ struct qm_ceetm_sp *sp; -+ struct list_head channels; -+ int shaper_enable; -+ int shaper_couple; -+ int oal; -+ struct qm_ceetm_rate cr_token_rate; -+ struct qm_ceetm_rate er_token_rate; -+ u16 cr_token_bucket_limit; -+ u16 er_token_bucket_limit; -+}; -+ -+/* Class Queue Channel */ -+struct qm_ceetm_channel { -+ struct list_head node; -+ unsigned int idx; -+ unsigned int lni_idx; -+ unsigned int dcp_idx; -+ struct list_head class_queues; -+ struct list_head ccgs; -+ u8 shaper_enable; -+ u8 shaper_couple; -+ struct qm_ceetm_rate cr_token_rate; -+ struct qm_ceetm_rate er_token_rate; -+ u16 cr_token_bucket_limit; -+ u16 er_token_bucket_limit; -+}; -+ -+struct qm_ceetm_ccg; -+ -+/* This callback type is used when handling congestion entry/exit. The -+ * 'cb_ctx' value is the opaque value associated with ccg object. -+ * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. -+ */ -+typedef void (*qman_cb_ccgr)(struct qm_ceetm_ccg *ccg, void *cb_ctx, -+ int congested); -+ -+/* Class Congestion Group */ -+struct qm_ceetm_ccg { -+ struct qm_ceetm_channel *parent; -+ struct list_head node; -+ struct list_head cb_node; -+ qman_cb_ccgr cb; -+ void *cb_ctx; -+ unsigned int idx; -+}; -+ -+/* Class Queue */ -+struct qm_ceetm_cq { -+ struct qm_ceetm_channel *parent; -+ struct qm_ceetm_ccg *ccg; -+ struct list_head node; -+ unsigned int idx; -+ int is_claimed; -+ struct list_head bound_lfqids; -+ struct list_head binding_node; -+}; -+ -+/* Logical Frame Queue */ -+struct qm_ceetm_lfq { -+ struct qm_ceetm_channel *parent; -+ struct list_head node; -+ unsigned int idx; -+ unsigned int dctidx; -+ u64 context_a; -+ u32 context_b; -+ qman_cb_mr ern; -+}; -+ -+/** -+ * qman_ceetm_bps2tokenrate - Given a desired rate 'bps' measured in bps -+ * (ie. bits-per-second), compute the 'token_rate' fraction that best -+ * approximates that rate. -+ * @bps: the desired shaper rate in bps. -+ * @token_rate: the output token rate computed with the given kbps. -+ * @rounding: dictates how to round if an exact conversion is not possible; if -+ * it is negative then 'token_rate' will round down to the highest value that -+ * does not exceed the desired rate, if it is positive then 'token_rate' will -+ * round up to the lowest value that is greater than or equal to the desired -+ * rate, and if it is zero then it will round to the nearest approximation, -+ * whether that be up or down. -+ * -+ * Return 0 for success, or -EINVAL if prescaler or qman clock is not available. -+ */ -+int qman_ceetm_bps2tokenrate(u64 bps, -+ struct qm_ceetm_rate *token_rate, -+ int rounding); -+ -+/** -+ * qman_ceetm_tokenrate2bps - Given a 'token_rate', compute the -+ * corresponding number of 'bps'. -+ * @token_rate: the input desired token_rate fraction. -+ * @bps: the output shaper rate in bps computed with the give token rate. -+ * @rounding: has the same semantics as the previous function. -+ * -+ * Return 0 for success, or -EINVAL if prescaler or qman clock is not available. -+ */ -+int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate, -+ u64 *bps, -+ int rounding); -+ -+int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align, -+ int partial); -+static inline int qman_alloc_ceetm0_channel(u32 *result) -+{ -+ int ret = qman_alloc_ceetm0_channel_range(result, 1, 0, 0); -+ return (ret > 0) ? 0 : ret; -+} -+void qman_release_ceetm0_channel_range(u32 channelid, u32 count); -+static inline void qman_release_ceetm0_channelid(u32 channelid) -+{ -+ qman_release_ceetm0_channel_range(channelid, 1); -+} -+ -+int qman_reserve_ceetm0_channel_range(u32 channelid, u32 count); -+static inline int qman_reserve_ceetm0_channelid(u32 channelid) -+{ -+ return qman_reserve_ceetm0_channel_range(channelid, 1); -+} -+ -+void qman_seed_ceetm0_channel_range(u32 channelid, u32 count); -+ -+ -+int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align, -+ int partial); -+static inline int qman_alloc_ceetm1_channel(u32 *result) -+{ -+ int ret = qman_alloc_ceetm1_channel_range(result, 1, 0, 0); -+ return (ret > 0) ? 0 : ret; -+} -+void qman_release_ceetm1_channel_range(u32 channelid, u32 count); -+static inline void qman_release_ceetm1_channelid(u32 channelid) -+{ -+ qman_release_ceetm1_channel_range(channelid, 1); -+} -+int qman_reserve_ceetm1_channel_range(u32 channelid, u32 count); -+static inline int qman_reserve_ceetm1_channelid(u32 channelid) -+{ -+ return qman_reserve_ceetm1_channel_range(channelid, 1); -+} -+ -+void qman_seed_ceetm1_channel_range(u32 channelid, u32 count); -+ -+ -+int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align, -+ int partial); -+static inline int qman_alloc_ceetm0_lfqid(u32 *result) -+{ -+ int ret = qman_alloc_ceetm0_lfqid_range(result, 1, 0, 0); -+ return (ret > 0) ? 0 : ret; -+} -+void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count); -+static inline void qman_release_ceetm0_lfqid(u32 lfqid) -+{ -+ qman_release_ceetm0_lfqid_range(lfqid, 1); -+} -+int qman_reserve_ceetm0_lfqid_range(u32 lfqid, u32 count); -+static inline int qman_reserve_ceetm0_lfqid(u32 lfqid) -+{ -+ return qman_reserve_ceetm0_lfqid_range(lfqid, 1); -+} -+ -+void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count); -+ -+ -+int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align, -+ int partial); -+static inline int qman_alloc_ceetm1_lfqid(u32 *result) -+{ -+ int ret = qman_alloc_ceetm1_lfqid_range(result, 1, 0, 0); -+ return (ret > 0) ? 0 : ret; -+} -+void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count); -+static inline void qman_release_ceetm1_lfqid(u32 lfqid) -+{ -+ qman_release_ceetm1_lfqid_range(lfqid, 1); -+} -+int qman_reserve_ceetm1_lfqid_range(u32 lfqid, u32 count); -+static inline int qman_reserve_ceetm1_lfqid(u32 lfqid) -+{ -+ return qman_reserve_ceetm1_lfqid_range(lfqid, 1); -+} -+ -+void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count); -+ -+ -+ /* ----------------------------- */ -+ /* CEETM :: sub-portals */ -+ /* ----------------------------- */ -+ -+/** -+ * qman_ceetm_sp_claim - Claims the given sub-portal, provided it is available -+ * to us and configured for traffic-management. -+ * @sp: the returned sub-portal object, if successful. -+ * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM -+ * instance), -+ * @sp_idx" is the desired sub-portal index from 0 to 15. -+ * -+ * Returns zero for success, or -ENODEV if the sub-portal is in use, or -EINVAL -+ * if the sp_idx is out of range. -+ * -+ * Note that if there are multiple driver domains (eg. a linux kernel versus -+ * user-space drivers in USDPAA, or multiple guests running under a hypervisor) -+ * then a sub-portal may be accessible by more than one instance of a qman -+ * driver and so it may be claimed multiple times. If this is the case, it is -+ * up to the system architect to prevent conflicting configuration actions -+ * coming from the different driver domains. The qman drivers do not have any -+ * behind-the-scenes coordination to prevent this from happening. -+ */ -+int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp, -+ enum qm_dc_portal dcp_idx, -+ unsigned int sp_idx); -+ -+/** -+ * qman_ceetm_sp_release - Releases a previously claimed sub-portal. -+ * @sp: the sub-portal to be released. -+ * -+ * Returns 0 for success, or -EBUSY for failure if the dependencies are not -+ * released. -+ */ -+int qman_ceetm_sp_release(struct qm_ceetm_sp *sp); -+ -+ /* ----------------------------------- */ -+ /* CEETM :: logical network interfaces */ -+ /* ----------------------------------- */ -+ -+/** -+ * qman_ceetm_lni_claim - Claims an unclaimed LNI. -+ * @lni: the returned LNI object, if successful. -+ * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM -+ * instance) -+ * @lni_idx: is the desired LNI index. -+ * -+ * Returns zero for success, or -EINVAL on failure, which will happen if the LNI -+ * is not available or has already been claimed (and not yet successfully -+ * released), or lni_dix is out of range. -+ * -+ * Note that there may be multiple driver domains (or instances) that need to -+ * transmit out the same LNI, so this claim is only guaranteeing exclusivity -+ * within the domain of the driver being called. See qman_ceetm_sp_claim() and -+ * qman_ceetm_sp_get_lni() for more information. -+ */ -+int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni, -+ enum qm_dc_portal dcp_id, -+ unsigned int lni_idx); -+ -+/** -+ * qman_ceetm_lni_releaes - Releases a previously claimed LNI. -+ * @lni: the lni needs to be released. -+ * -+ * This will only succeed if all dependent objects have been released. -+ * Returns zero for success, or -EBUSY if the dependencies are not released. -+ */ -+int qman_ceetm_lni_release(struct qm_ceetm_lni *lni); -+ -+/** -+ * qman_ceetm_sp_set_lni -+ * qman_ceetm_sp_get_lni - Set/get the LNI that the sub-portal is currently -+ * mapped to. -+ * @sp: the given sub-portal. -+ * @lni(in "set"function): the LNI object which the sp will be mappaed to. -+ * @lni_idx(in "get" function): the LNI index which the sp is mapped to. -+ * -+ * Returns zero for success, or -EINVAL for the "set" function when this sp-lni -+ * mapping has been set, or configure mapping command returns error, and -+ * -EINVAL for "get" function when this sp-lni mapping is not set or the query -+ * mapping command returns error. -+ * -+ * This may be useful in situations where multiple driver domains have access -+ * to the same sub-portals in order to all be able to transmit out the same -+ * physical interface (perhaps they're on different IP addresses or VPNs, so -+ * Fman is splitting Rx traffic and here we need to converge Tx traffic). In -+ * that case, a control-plane is likely to use qman_ceetm_lni_claim() followed -+ * by qman_ceetm_sp_set_lni() to configure the sub-portal, and other domains -+ * are likely to use qman_ceetm_sp_get_lni() followed by qman_ceetm_lni_claim() -+ * in order to determine the LNI that the control-plane had assigned. This is -+ * why the "get" returns an index, whereas the "set" takes an (already claimed) -+ * LNI object. -+ */ -+int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp, -+ struct qm_ceetm_lni *lni); -+int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp, -+ unsigned int *lni_idx); -+ -+/** -+ * qman_ceetm_lni_enable_shaper -+ * qman_ceetm_lni_disable_shaper - Enables/disables shaping on the LNI. -+ * @lni: the given LNI. -+ * @coupled: indicates whether CR and ER are coupled. -+ * @oal: the overhead accounting length which is added to the actual length of -+ * each frame when performing shaper calculations. -+ * -+ * When the number of (unused) committed-rate tokens reach the committed-rate -+ * token limit, 'coupled' indicates whether surplus tokens should be added to -+ * the excess-rate token count (up to the excess-rate token limit). -+ * When LNI is claimed, the shaper is disabled by default. The enable function -+ * will turn on this shaper for this lni. -+ * Whenever a claimed LNI is first enabled for shaping, its committed and -+ * excess token rates and limits are zero, so will need to be changed to do -+ * anything useful. The shaper can subsequently be enabled/disabled without -+ * resetting the shaping parameters, but the shaping parameters will be reset -+ * when the LNI is released. -+ * -+ * Returns zero for success, or errno for "enable" function in the cases as: -+ * a) -EINVAL if the shaper is already enabled, -+ * b) -EIO if the configure shaper command returns error. -+ * For "disable" function, returns: -+ * a) -EINVAL if the shaper is has already disabled. -+ * b) -EIO if calling configure shaper command returns error. -+ */ -+int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled, -+ int oal); -+int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni); -+ -+/** -+ * qman_ceetm_lni_is_shaper_enabled - Check LNI shaper status -+ * @lni: the give LNI -+ */ -+int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni); -+ -+/** -+ * qman_ceetm_lni_set_commit_rate -+ * qman_ceetm_lni_get_commit_rate -+ * qman_ceetm_lni_set_excess_rate -+ * qman_ceetm_lni_get_excess_rate - Set/get the shaper CR/ER token rate and -+ * token limit for the given LNI. -+ * @lni: the given LNI. -+ * @token_rate: the desired token rate for "set" fuction, or the token rate of -+ * the LNI queried by "get" function. -+ * @token_limit: the desired token bucket limit for "set" function, or the token -+ * limit of the given LNI queried by "get" function. -+ * -+ * Returns zero for success. The "set" function returns -EINVAL if the given -+ * LNI is unshapped or -EIO if the configure shaper command returns error. -+ * The "get" function returns -EINVAL if the token rate or the token limit is -+ * not set or the query command returns error. -+ */ -+int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni, -+ const struct qm_ceetm_rate *token_rate, -+ u16 token_limit); -+int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni, -+ struct qm_ceetm_rate *token_rate, -+ u16 *token_limit); -+int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni, -+ const struct qm_ceetm_rate *token_rate, -+ u16 token_limit); -+int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni, -+ struct qm_ceetm_rate *token_rate, -+ u16 *token_limit); -+/** -+ * qman_ceetm_lni_set_commit_rate_bps -+ * qman_ceetm_lni_get_commit_rate_bps -+ * qman_ceetm_lni_set_excess_rate_bps -+ * qman_ceetm_lni_get_excess_rate_bps - Set/get the shaper CR/ER rate -+ * and token limit for the given LNI. -+ * @lni: the given LNI. -+ * @bps: the desired shaping rate in bps for "set" fuction, or the shaping rate -+ * of the LNI queried by "get" function. -+ * @token_limit: the desired token bucket limit for "set" function, or the token -+ * limit of the given LNI queried by "get" function. -+ * -+ * Returns zero for success. The "set" function returns -EINVAL if the given -+ * LNI is unshapped or -EIO if the configure shaper command returns error. -+ * The "get" function returns -EINVAL if the token rate or the token limit is -+ * not set or the query command returns error. -+ */ -+int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni, -+ u64 bps, -+ u16 token_limit); -+int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni, -+ u64 *bps, u16 *token_limit); -+int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni, -+ u64 bps, -+ u16 token_limit); -+int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni, -+ u64 *bps, u16 *token_limit); -+ -+/** -+ * qman_ceetm_lni_set_tcfcc -+ * qman_ceetm_lni_get_tcfcc - Configure/query "Traffic Class Flow Control". -+ * @lni: the given LNI. -+ * @cq_level: is between 0 and 15, representing individual class queue levels -+ * (CQ0 to CQ7 for every channel) and grouped class queue levels (CQ8 to CQ15 -+ * for every channel). -+ * @traffic_class: is between 0 and 7 when associating a given class queue level -+ * to a traffic class, or -1 when disabling traffic class flow control for this -+ * class queue level. -+ * -+ * Return zero for success, or -EINVAL if the cq_level or traffic_class is out -+ * of range as indicated above, or -EIO if the configure/query tcfcc command -+ * returns error. -+ * -+ * Refer to the section of QMan CEETM traffic class flow control in the -+ * Reference Manual. -+ */ -+int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni, -+ unsigned int cq_level, -+ int traffic_class); -+int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni, -+ unsigned int cq_level, -+ int *traffic_class); -+ -+ /* ----------------------------- */ -+ /* CEETM :: class queue channels */ -+ /* ----------------------------- */ -+ -+/** -+ * qman_ceetm_channel_claim - Claims an unclaimed CQ channel that is mapped to -+ * the given LNI. -+ * @channel: the returned class queue channel object, if successful. -+ * @lni: the LNI that the channel belongs to. -+ * -+ * Channels are always initially "unshaped". -+ * -+ * Return zero for success, or -ENODEV if there is no channel available(all 32 -+ * channels are claimed) or -EINVAL if the channel mapping command returns -+ * error. -+ */ -+int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel, -+ struct qm_ceetm_lni *lni); -+ -+/** -+ * qman_ceetm_channel_release - Releases a previously claimed CQ channel. -+ * @channel: the channel needs to be released. -+ * -+ * Returns zero for success, or -EBUSY if the dependencies are still in use. -+ * -+ * Note any shaping of the channel will be cleared to leave it in an unshaped -+ * state. -+ */ -+int qman_ceetm_channel_release(struct qm_ceetm_channel *channel); -+ -+/** -+ * qman_ceetm_channel_enable_shaper -+ * qman_ceetm_channel_disable_shaper - Enables/disables shaping on the channel. -+ * @channel: the given channel. -+ * @coupled: indicates whether surplus CR tokens should be added to the -+ * excess-rate token count (up to the excess-rate token limit) when the number -+ * of (unused) committed-rate tokens reach the committed_rate token limit. -+ * -+ * Whenever a claimed channel is first enabled for shaping, its committed and -+ * excess token rates and limits are zero, so will need to be changed to do -+ * anything useful. The shaper can subsequently be enabled/disabled without -+ * resetting the shaping parameters, but the shaping parameters will be reset -+ * when the channel is released. -+ * -+ * Return 0 for success, or -EINVAL for failure, in the case that the channel -+ * shaper has been enabled/disabled or the management command returns error. -+ */ -+int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel, -+ int coupled); -+int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel); -+ -+/** -+ * qman_ceetm_channel_is_shaper_enabled - Check channel shaper status. -+ * @channel: the give channel. -+ */ -+int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel); -+ -+/** -+ * qman_ceetm_channel_set_commit_rate -+ * qman_ceetm_channel_get_commit_rate -+ * qman_ceetm_channel_set_excess_rate -+ * qman_ceetm_channel_get_excess_rate - Set/get channel CR/ER shaper parameters. -+ * @channel: the given channel. -+ * @token_rate: the desired token rate for "set" function, or the queried token -+ * rate for "get" function. -+ * @token_limit: the desired token limit for "set" function, or the queried -+ * token limit for "get" function. -+ * -+ * Return zero for success. The "set" function returns -EINVAL if the channel -+ * is unshaped, or -EIO if the configure shapper command returns error. The -+ * "get" function returns -EINVAL if token rate of token limit is not set, or -+ * the query shaper command returns error. -+ */ -+int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel, -+ const struct qm_ceetm_rate *token_rate, -+ u16 token_limit); -+int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel, -+ struct qm_ceetm_rate *token_rate, -+ u16 *token_limit); -+int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel, -+ const struct qm_ceetm_rate *token_rate, -+ u16 token_limit); -+int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel, -+ struct qm_ceetm_rate *token_rate, -+ u16 *token_limit); -+/** -+ * qman_ceetm_channel_set_commit_rate_bps -+ * qman_ceetm_channel_get_commit_rate_bps -+ * qman_ceetm_channel_set_excess_rate_bps -+ * qman_ceetm_channel_get_excess_rate_bps - Set/get channel CR/ER shaper -+ * parameters. -+ * @channel: the given channel. -+ * @token_rate: the desired shaper rate in bps for "set" function, or the -+ * shaper rate in bps for "get" function. -+ * @token_limit: the desired token limit for "set" function, or the queried -+ * token limit for "get" function. -+ * -+ * Return zero for success. The "set" function returns -EINVAL if the channel -+ * is unshaped, or -EIO if the configure shapper command returns error. The -+ * "get" function returns -EINVAL if token rate of token limit is not set, or -+ * the query shaper command returns error. -+ */ -+int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel, -+ u64 bps, u16 token_limit); -+int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel, -+ u64 *bps, u16 *token_limit); -+int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel, -+ u64 bps, u16 token_limit); -+int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel, -+ u64 *bps, u16 *token_limit); -+ -+/** -+ * qman_ceetm_channel_set_weight -+ * qman_ceetm_channel_get_weight - Set/get the weight for unshaped channel -+ * @channel: the given channel. -+ * @token_limit: the desired token limit as the weight of the unshaped channel -+ * for "set" function, or the queried token limit for "get" function. -+ * -+ * The algorithm of unshaped fair queuing (uFQ) is used for unshaped channel. -+ * It allows the unshaped channels to be included in the CR time eligible list, -+ * and thus use the configured CR token limit value as their fair queuing -+ * weight. -+ * -+ * Return zero for success, or -EINVAL if the channel is a shaped channel or -+ * the management command returns error. -+ */ -+int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel, -+ u16 token_limit); -+int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel, -+ u16 *token_limit); -+ -+/** -+ * qman_ceetm_channel_set_group -+ * qman_ceetm_channel_get_group - Set/get the grouping of the class scheduler. -+ * @channel: the given channel. -+ * @group_b: indicates whether there is group B in this channel. -+ * @prio_a: the priority of group A. -+ * @prio_b: the priority of group B. -+ * -+ * There are 8 individual class queues (CQ0-CQ7), and 8 grouped class queues -+ * (CQ8-CQ15). If 'group_b' is zero, then all the grouped class queues are in -+ * group A, otherwise they are split into group A (CQ8-11) and group B -+ * (CQ12-C15). The individual class queues and the group(s) are in strict -+ * priority order relative to each other. Within the group(s), the scheduling -+ * is not strict priority order, but the result of scheduling within a group -+ * is in strict priority order relative to the other class queues in the -+ * channel. 'prio_a' and 'prio_b' control the priority order of the groups -+ * relative to the individual class queues, and take values from 0-7. Eg. if -+ * 'group_b' is non-zero, 'prio_a' is 2 and 'prio_b' is 6, then the strict -+ * priority order would be; -+ * CQ0, CQ1, CQ2, GROUPA, CQ3, CQ4, CQ5, CQ6, GROUPB, CQ7 -+ * -+ * Return 0 for success. For "set" function, returns -EINVAL if prio_a or -+ * prio_b are out of the range 0 - 7 (priority of group A or group B can not -+ * be 0, CQ0 is always the highest class queue in this channel.), or -EIO if -+ * the configure scheduler command returns error. For "get" function, return -+ * -EINVAL if the query scheduler command returns error. -+ */ -+int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel, -+ int group_b, -+ unsigned int prio_a, -+ unsigned int prio_b); -+int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, -+ int *group_b, -+ unsigned int *prio_a, -+ unsigned int *prio_b); -+ -+/** -+ * qman_ceetm_channel_set_group_cr_eligibility -+ * qman_ceetm_channel_set_group_er_eligibility - Set channel group eligibility -+ * @channel: the given channel object -+ * @group_b: indicates whether there is group B in this channel. -+ * @cre: the commit rate eligibility, 1 for enable, 0 for disable. -+ * -+ * Return zero for success, or -EINVAL if eligibility setting fails. -+*/ -+int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel -+ *channel, int group_b, int cre); -+int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel -+ *channel, int group_b, int ere); -+ -+/** -+ * qman_ceetm_channel_set_cq_cr_eligibility -+ * qman_ceetm_channel_set_cq_er_eligibility - Set channel cq eligibility -+ * @channel: the given channel object -+ * @idx: is from 0 to 7 (representing CQ0 to CQ7). -+ * @cre: the commit rate eligibility, 1 for enable, 0 for disable. -+ * -+ * Return zero for success, or -EINVAL if eligibility setting fails. -+*/ -+int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel, -+ unsigned int idx, int cre); -+int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel, -+ unsigned int idx, int ere); -+ -+ /* --------------------- */ -+ /* CEETM :: class queues */ -+ /* --------------------- */ -+ -+/** -+ * qman_ceetm_cq_claim - Claims an individual class queue. -+ * @cq: the returned class queue object, if successful. -+ * @channel: the class queue channel. -+ * @idx: is from 0 to 7 (representing CQ0 to CQ7). -+ * @ccg: represents the class congestion group that this class queue should be -+ * subscribed to, or NULL if no congestion group membership is desired. -+ * -+ * Returns zero for success, or -EINVAL if @idx is out of range 0 - 7 or -+ * if this class queue has been claimed, or configure class queue command -+ * returns error, or returns -ENOMEM if allocating CQ memory fails. -+ */ -+int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq, -+ struct qm_ceetm_channel *channel, -+ unsigned int idx, -+ struct qm_ceetm_ccg *ccg); -+ -+/** -+ * qman_ceetm_cq_claim_A - Claims a class queue group A. -+ * @cq: the returned class queue object, if successful. -+ * @channel: the class queue channel. -+ * @idx: is from 8 to 15 if only group A exits, otherwise, it is from 8 to 11. -+ * @ccg: represents the class congestion group that this class queue should be -+ * subscribed to, or NULL if no congestion group membership is desired. -+ * -+ * Return zero for success, or -EINVAL if @idx is out the range or if -+ * this class queue has been claimed or configure class queue command returns -+ * error, or returns -ENOMEM if allocating CQ memory fails. -+ */ -+int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq, -+ struct qm_ceetm_channel *channel, -+ unsigned int idx, -+ struct qm_ceetm_ccg *ccg); -+ -+/** -+ * qman_ceetm_cq_claim_B - Claims a class queue group B. -+ * @cq: the returned class queue object, if successful. -+ * @channel: the class queue channel. -+ * @idx: is from 0 to 3 (CQ12 to CQ15). -+ * @ccg: represents the class congestion group that this class queue should be -+ * subscribed to, or NULL if no congestion group membership is desired. -+ * -+ * Return zero for success, or -EINVAL if @idx is out the range or if -+ * this class queue has been claimed or configure class queue command returns -+ * error, or returns -ENOMEM if allocating CQ memory fails. -+ */ -+int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq, -+ struct qm_ceetm_channel *channel, -+ unsigned int idx, -+ struct qm_ceetm_ccg *ccg); -+ -+/** -+ * qman_ceetm_cq_release - Releases a previously claimed class queue. -+ * @cq: The class queue to be released. -+ * -+ * Return zero for success, or -EBUSY if the dependent objects (eg. logical -+ * FQIDs) have not been released. -+ */ -+int qman_ceetm_cq_release(struct qm_ceetm_cq *cq); -+ -+/** -+ * qman_ceetm_set_queue_weight -+ * qman_ceetm_get_queue_weight - Configure/query the weight of a grouped class -+ * queue. -+ * @cq: the given class queue. -+ * @weight_code: the desired weight code to set for the given class queue for -+ * "set" function or the queired weight code for "get" function. -+ * -+ * Grouped class queues have a default weight code of zero, which corresponds to -+ * a scheduler weighting of 1. This function can be used to modify a grouped -+ * class queue to another weight, (Use the helpers qman_ceetm_wbfs2ratio() -+ * and qman_ceetm_ratio2wbfs() to convert between these 'weight_code' values -+ * and the corresponding sharing weight.) -+ * -+ * Returns zero for success, or -EIO if the configure weight command returns -+ * error for "set" function, or -EINVAL if the query command returns -+ * error for "get" function. -+ * See section "CEETM Weighted Scheduling among Grouped Classes" in Reference -+ * Manual for weight and weight code. -+ */ -+int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq, -+ struct qm_ceetm_weight_code *weight_code); -+int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq, -+ struct qm_ceetm_weight_code *weight_code); -+ -+/** -+ * qman_ceetm_set_queue_weight_in_ratio -+ * qman_ceetm_get_queue_weight_in_ratio - Configure/query the weight of a -+ * grouped class queue. -+ * @cq: the given class queue. -+ * @ratio: the weight in ratio. It should be the real ratio number multiplied -+ * by 100 to get rid of fraction. -+ * -+ * Returns zero for success, or -EIO if the configure weight command returns -+ * error for "set" function, or -EINVAL if the query command returns -+ * error for "get" function. -+ */ -+int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio); -+int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio); -+ -+/* Weights are encoded using a pseudo-exponential scheme. The weight codes 0, -+ * 32, 64, [...] correspond to weights of 1, 2, 4, [...]. The weights -+ * corresponding to intermediate weight codes are calculated using linear -+ * interpolation on the inverted values. Or put another way, the inverse weights -+ * for each 32nd weight code are 1, 1/2, 1/4, [...], and so the intervals -+ * between these are divided linearly into 32 intermediate values, the inverses -+ * of which form the remaining weight codes. -+ * -+ * The Weighted Bandwidth Fair Scheduling (WBFS) algorithm provides a form of -+ * scheduling within a group of class queues (group A or B). Weights are used to -+ * normalise the class queues to an underlying BFS algorithm where all class -+ * queues are assumed to require "equal bandwidth". So the weights referred to -+ * by the weight codes act as divisors on the size of frames being enqueued. Ie. -+ * one class queue in a group is assigned a weight of 2 whilst the other class -+ * queues in the group keep the default weight of 1, then the WBFS scheduler -+ * will effectively treat all frames enqueued on the weight-2 class queue as -+ * having half the number of bytes they really have. Ie. if all other things are -+ * equal, that class queue would get twice as much bytes-per-second bandwidth as -+ * the others. So weights should be chosen to provide bandwidth ratios between -+ * members of the same class queue group. These weights have no bearing on -+ * behaviour outside that group's WBFS mechanism though. -+ */ -+ -+/** -+ * qman_ceetm_wbfs2ratio - Given a weight code ('wbfs'), an accurate fractional -+ * representation of the corresponding weight is given (in order to not lose -+ * any precision). -+ * @weight_code: The given weight code in WBFS. -+ * @numerator: the numerator part of the weight computed by the weight code. -+ * @denominator: the denominator part of the weight computed by the weight code -+ * -+ * Returns zero for success or -EINVAL if the given weight code is illegal. -+ */ -+int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code, -+ u32 *numerator, -+ u32 *denominator); -+/** -+ * qman_ceetm_ratio2wbfs - Given a weight, find the nearest possible weight code -+ * If the user needs to know how close this is, convert the resulting weight -+ * code back to a weight and compare. -+ * @numerator: numerator part of the given weight. -+ * @denominator: denominator part of the given weight. -+ * @weight_code: the weight code computed from the given weight. -+ * -+ * Returns zero for success, or -ERANGE if "numerator/denominator" is outside -+ * the range of weights. -+ */ -+int qman_ceetm_ratio2wbfs(u32 numerator, -+ u32 denominator, -+ struct qm_ceetm_weight_code *weight_code, -+ int rounding); -+ -+#define QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER 0x1 -+/** -+ * qman_ceetm_cq_get_dequeue_statistics - Get the statistics provided by CEETM -+ * CQ counters. -+ * @cq: the given CQ object. -+ * @flags: indicates whether the statistics counter will be cleared after query. -+ * @frame_count: The number of the frames that have been counted since the -+ * counter was cleared last time. -+ * @byte_count: the number of bytes in all frames that have been counted. -+ * -+ * Return zero for success or -EINVAL if query statistics command returns error. -+ * -+ */ -+int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags, -+ u64 *frame_count, u64 *byte_count); -+ -+/** -+ * qman_ceetm_drain_cq - drain the CQ till it is empty. -+ * @cq: the give CQ object. -+ * Return 0 for success or -EINVAL for unsuccessful command to empty CQ. -+ */ -+int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq); -+ -+ /* ---------------------- */ -+ /* CEETM :: logical FQIDs */ -+ /* ---------------------- */ -+/** -+ * qman_ceetm_lfq_claim - Claims an unused logical FQID, associates it with -+ * the given class queue. -+ * @lfq: the returned lfq object, if successful. -+ * @cq: the class queue which needs to claim a LFQID. -+ * -+ * Return zero for success, or -ENODEV if no LFQID is available or -ENOMEM if -+ * allocating memory for lfq fails, or -EINVAL if configuring LFQMT fails. -+ */ -+int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq, -+ struct qm_ceetm_cq *cq); -+ -+/** -+ * qman_ceetm_lfq_release - Releases a previously claimed logical FQID. -+ * @lfq: the lfq to be released. -+ * -+ * Return zero for success. -+ */ -+int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq); -+ -+/** -+ * qman_ceetm_lfq_set_context -+ * qman_ceetm_lfq_get_context - Set/get the context_a/context_b pair to the -+ * "dequeue context table" associated with the logical FQID. -+ * @lfq: the given logical FQ object. -+ * @context_a: contextA of the dequeue context. -+ * @context_b: contextB of the dequeue context. -+ * -+ * Returns zero for success, or -EINVAL if there is error to set/get the -+ * context pair. -+ */ -+int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq, -+ u64 context_a, -+ u32 context_b); -+int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq, -+ u64 *context_a, -+ u32 *context_b); -+ -+/** -+ * qman_ceetm_create_fq - Initialise a FQ object for the LFQ. -+ * @lfq: the given logic fq. -+ * @fq: the fq object created for the given logic fq. -+ * -+ * The FQ object can be used in qman_enqueue() and qman_enqueue_orp() APIs to -+ * target a logical FQID (and the class queue it is associated with). -+ * Note that this FQ object can only be used for enqueues, and -+ * in the case of qman_enqueue_orp() it can not be used as the 'orp' parameter, -+ * only as 'fq'. This FQ object can not (and shouldn't) be destroyed, it is only -+ * valid as long as the underlying 'lfq' remains claimed. It is the user's -+ * responsibility to ensure that the underlying 'lfq' is not released until any -+ * enqueues to this FQ object have completed. The only field the user needs to -+ * fill in is fq->cb.ern, as that enqueue rejection handler is the callback that -+ * could conceivably be called on this FQ object. This API can be called -+ * multiple times to create multiple FQ objects referring to the same logical -+ * FQID, and any enqueue rejections will respect the callback of the object that -+ * issued the enqueue (and will identify the object via the parameter passed to -+ * the callback too). There is no 'flags' parameter to this API as there is for -+ * qman_create_fq() - the created FQ object behaves as though qman_create_fq() -+ * had been called with the single flag QMAN_FQ_FLAG_NO_MODIFY. -+ * -+ * Returns 0 for success. -+ */ -+int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq); -+ -+ /* -------------------------------- */ -+ /* CEETM :: class congestion groups */ -+ /* -------------------------------- */ -+ -+/** -+ * qman_ceetm_ccg_claim - Claims an unused CCG. -+ * @ccg: the returned CCG object, if successful. -+ * @channel: the given class queue channel -+ * @cscn: the callback function of this CCG. -+ * @cb_ctx: the corresponding context to be used used if state change -+ * notifications are later enabled for this CCG. -+ * -+ * The congestion group is local to the given class queue channel, so only -+ * class queues within the channel can be associated with that congestion group. -+ * The association of class queues to congestion groups occurs when the class -+ * queues are claimed, see qman_ceetm_cq_claim() and related functions. -+ * Congestion groups are in a "zero" state when initially claimed, and they are -+ * returned to that state when released. -+ * -+ * Return zero for success, or -EINVAL if no CCG in the channel is available. -+ */ -+int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg, -+ struct qm_ceetm_channel *channel, -+ unsigned int idx, -+ void (*cscn)(struct qm_ceetm_ccg *, -+ void *cb_ctx, -+ int congested), -+ void *cb_ctx); -+ -+/** -+ * qman_ceetm_ccg_release - Releases a previously claimed CCG. -+ * @ccg: the given ccg. -+ * -+ * Returns zero for success, or -EBUSY if the given ccg's dependent objects -+ * (class queues that are associated with the CCG) have not been released. -+ */ -+int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg); -+ -+/* This struct is used to specify attributes for a CCG. The 'we_mask' field -+ * controls which CCG attributes are to be updated, and the remainder specify -+ * the values for those attributes. A CCG counts either frames or the bytes -+ * within those frames, but not both ('mode'). A CCG can optionally cause -+ * enqueues to be rejected, due to tail-drop or WRED, or both (they are -+ * independent options, 'td_en' and 'wr_en_g,wr_en_y,wr_en_r'). Tail-drop can be -+ * level-triggered due to a single threshold ('td_thres') or edge-triggered due -+ * to a "congestion state", but not both ('td_mode'). Congestion state has -+ * distinct entry and exit thresholds ('cs_thres_in' and 'cs_thres_out'), and -+ * notifications can be sent to software the CCG goes in to and out of this -+ * congested state ('cscn_en'). */ -+struct qm_ceetm_ccg_params { -+ /* Boolean fields together in a single bitfield struct */ -+ struct { -+ /* Whether to count bytes or frames. 1==frames */ -+ u8 mode:1; -+ /* En/disable tail-drop. 1==enable */ -+ u8 td_en:1; -+ /* Tail-drop on congestion-state or threshold. 1=threshold */ -+ u8 td_mode:1; -+ /* Generate congestion state change notifications. 1==enable */ -+ u8 cscn_en:1; -+ /* Enable WRED rejections (per colour). 1==enable */ -+ u8 wr_en_g:1; -+ u8 wr_en_y:1; -+ u8 wr_en_r:1; -+ } __packed; -+ /* Tail-drop threshold. See qm_cgr_thres_[gs]et64(). */ -+ struct qm_cgr_cs_thres td_thres; -+ /* Congestion state thresholds, for entry and exit. */ -+ struct qm_cgr_cs_thres cs_thres_in; -+ struct qm_cgr_cs_thres cs_thres_out; -+ /* Overhead accounting length. Per-packet "tax", from -128 to +127 */ -+ signed char oal; -+ /* Congestion state change notification for DCP portal, virtual CCGID*/ -+ /* WRED parameters. */ -+ struct qm_cgr_wr_parm wr_parm_g; -+ struct qm_cgr_wr_parm wr_parm_y; -+ struct qm_cgr_wr_parm wr_parm_r; -+}; -+/* Bits used in 'we_mask' to qman_ceetm_ccg_set(), controls which attributes of -+ * the CCGR are to be updated. */ -+#define QM_CCGR_WE_MODE 0x0001 /* mode (bytes/frames) */ -+#define QM_CCGR_WE_CS_THRES_IN 0x0002 /* congestion state entry threshold */ -+#define QM_CCGR_WE_TD_EN 0x0004 /* congestion state tail-drop enable */ -+#define QM_CCGR_WE_CSCN_TUPD 0x0008 /* CSCN target update */ -+#define QM_CCGR_WE_CSCN_EN 0x0010 /* congestion notification enable */ -+#define QM_CCGR_WE_WR_EN_R 0x0020 /* WRED enable - red */ -+#define QM_CCGR_WE_WR_EN_Y 0x0040 /* WRED enable - yellow */ -+#define QM_CCGR_WE_WR_EN_G 0x0080 /* WRED enable - green */ -+#define QM_CCGR_WE_WR_PARM_R 0x0100 /* WRED parameters - red */ -+#define QM_CCGR_WE_WR_PARM_Y 0x0200 /* WRED parameters - yellow */ -+#define QM_CCGR_WE_WR_PARM_G 0x0400 /* WRED parameters - green */ -+#define QM_CCGR_WE_OAL 0x0800 /* overhead accounting length */ -+#define QM_CCGR_WE_CS_THRES_OUT 0x1000 /* congestion state exit threshold */ -+#define QM_CCGR_WE_TD_THRES 0x2000 /* tail-drop threshold */ -+#define QM_CCGR_WE_TD_MODE 0x4000 /* tail-drop mode (state/threshold) */ -+#define QM_CCGR_WE_CDV 0x8000 /* cdv */ -+ -+/** -+ * qman_ceetm_ccg_set -+ * qman_ceetm_ccg_get - Configure/query a subset of CCG attributes. -+ * @ccg: the given CCG object. -+ * @we_mask: the write enable mask. -+ * @params: the parameters setting for this ccg -+ * -+ * Return 0 for success, or -EIO if configure ccg command returns error for -+ * "set" function, or -EINVAL if query ccg command returns error for "get" -+ * function. -+ */ -+int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg, -+ u16 we_mask, -+ const struct qm_ceetm_ccg_params *params); -+int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg, -+ struct qm_ceetm_ccg_params *params); -+ -+/** qman_ceetm_cscn_swp_set - Add or remove a software portal from the target -+ * mask. -+ * qman_ceetm_cscn_swp_get - Query whether a given software portal index is -+ * in the cscn target mask. -+ * @ccg: the give CCG object. -+ * @swp_idx: the index of the software portal. -+ * @cscn_enabled: 1: Set the swp to be cscn target. 0: remove the swp from -+ * the target mask. -+ * @we_mask: the write enable mask. -+ * @params: the parameters setting for this ccg -+ * -+ * Return 0 for success, or -EINVAL if command in set/get function fails. -+ */ -+int qman_ceetm_cscn_swp_set(struct qm_ceetm_ccg *ccg, -+ u16 swp_idx, -+ unsigned int cscn_enabled, -+ u16 we_mask, -+ const struct qm_ceetm_ccg_params *params); -+int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg, -+ u16 swp_idx, -+ unsigned int *cscn_enabled); -+ -+/** qman_ceetm_cscn_dcp_set - Add or remove a direct connect portal from the\ -+ * target mask. -+ * qman_ceetm_cscn_dcp_get - Query whether a given direct connect portal index -+ * is in the cscn target mask. -+ * @ccg: the give CCG object. -+ * @dcp_idx: the index of the direct connect portal. -+ * @vcgid: congestion state change notification for dcp portal, virtual CGID. -+ * @cscn_enabled: 1: Set the dcp to be cscn target. 0: remove the dcp from -+ * the target mask. -+ * @we_mask: the write enable mask. -+ * @params: the parameters setting for this ccg -+ * -+ * Return 0 for success, or -EINVAL if command in set/get function fails. -+ */ -+int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg, -+ u16 dcp_idx, -+ u8 vcgid, -+ unsigned int cscn_enabled, -+ u16 we_mask, -+ const struct qm_ceetm_ccg_params *params); -+int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg, -+ u16 dcp_idx, -+ u8 *vcgid, -+ unsigned int *cscn_enabled); -+ -+/** -+ * qman_ceetm_ccg_get_reject_statistics - Get the statistics provided by -+ * CEETM CCG counters. -+ * @ccg: the given CCG object. -+ * @flags: indicates whether the statistics counter will be cleared after query. -+ * @frame_count: The number of the frames that have been counted since the -+ * counter was cleared last time. -+ * @byte_count: the number of bytes in all frames that have been counted. -+ * -+ * Return zero for success or -EINVAL if query statistics command returns error. -+ * -+ */ -+int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags, -+ u64 *frame_count, u64 *byte_count); -+ -+/** -+ * qman_ceetm_query_lfqmt - Query the logical frame queue mapping table -+ * @lfqid: Logical Frame Queue ID -+ * @lfqmt_query: Results of the query command -+ * -+ * Returns zero for success or -EIO if the query command returns error. -+ * -+ */ -+int qman_ceetm_query_lfqmt(int lfqid, -+ struct qm_mcr_ceetm_lfqmt_query *lfqmt_query); -+ -+/** -+ * qman_ceetm_query_write_statistics - Query (and optionally write) statistics -+ * @cid: Target ID (CQID or CCGRID) -+ * @dcp_idx: CEETM portal ID -+ * @command_type: One of the following: -+ * 0 = Query dequeue statistics. CID carries the CQID to be queried. -+ * 1 = Query and clear dequeue statistics. CID carries the CQID to be queried -+ * 2 = Write dequeue statistics. CID carries the CQID to be written. -+ * 3 = Query reject statistics. CID carries the CCGRID to be queried. -+ * 4 = Query and clear reject statistics. CID carries the CCGRID to be queried -+ * 5 = Write reject statistics. CID carries the CCGRID to be written -+ * @frame_count: Frame count value to be written if this is a write command -+ * @byte_count: Bytes count value to be written if this is a write command -+ * -+ * Returns zero for success or -EIO if the query command returns error. -+ */ -+int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx, -+ u16 command_type, u64 frame_count, -+ u64 byte_count); -+ -+/** -+ * qman_set_wpm - Set waterfall power management -+ * -+ * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm. -+ * -+ * Return 0 for success, return -ENODEV if QMan misc_cfg register is not -+ * accessible. -+ */ -+int qman_set_wpm(int wpm_enable); -+ -+/** -+ * qman_get_wpm - Query the waterfall power management setting -+ * -+ * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm. -+ * -+ * Return 0 for success, return -ENODEV if QMan misc_cfg register is not -+ * accessible. -+ */ -+int qman_get_wpm(int *wpm_enable); -+ -+/* The below qman_p_***() variants might be called in a migration situation -+ * (e.g. cpu hotplug). They are used to continue accessing the portal that -+ * execution was affine to prior to migration. -+ * @qman_portal specifies which portal the APIs will use. -+*/ -+const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal -+ *p); -+int qman_p_irqsource_add(struct qman_portal *p, u32 bits); -+int qman_p_irqsource_remove(struct qman_portal *p, u32 bits); -+int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit); -+u32 qman_p_poll_slow(struct qman_portal *p); -+void qman_p_poll(struct qman_portal *p); -+void qman_p_stop_dequeues(struct qman_portal *p); -+void qman_p_start_dequeues(struct qman_portal *p); -+void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools); -+void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools); -+u32 qman_p_static_dequeue_get(struct qman_portal *p); -+void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq, -+ int park_request); -+int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq, -+ u32 flags __maybe_unused, u32 vdqcr); -+int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq, -+ const struct qm_fd *fd, u32 flags); -+int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq, -+ const struct qm_fd *fd, u32 flags, -+ struct qman_fq *orp, u16 orp_seqnum); -+int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq, -+ const struct qm_fd *fd, u32 flags, -+ qman_cb_precommit cb, void *cb_arg); -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* FSL_QMAN_H */ ---- /dev/null -+++ b/include/linux/fsl_usdpaa.h -@@ -0,0 +1,372 @@ -+/* Copyright 2011-2012 Freescale Semiconductor, Inc. -+ * -+ * This file is licensed under the terms of the GNU General Public License -+ * version 2. This program is licensed "as is" without any warranty of any -+ * kind, whether express or implied. -+ */ -+ -+#ifndef FSL_USDPAA_H -+#define FSL_USDPAA_H -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#include -+#include -+#include /* For "enum qm_channel" */ -+#include -+ -+#ifdef CONFIG_FSL_USDPAA -+ -+/******************************/ -+/* Allocation of resource IDs */ -+/******************************/ -+ -+/* This enum is used to distinguish between the type of underlying object being -+ * manipulated. */ -+enum usdpaa_id_type { -+ usdpaa_id_fqid, -+ usdpaa_id_bpid, -+ usdpaa_id_qpool, -+ usdpaa_id_cgrid, -+ usdpaa_id_ceetm0_lfqid, -+ usdpaa_id_ceetm0_channelid, -+ usdpaa_id_ceetm1_lfqid, -+ usdpaa_id_ceetm1_channelid, -+ usdpaa_id_max /* <-- not a valid type, represents the number of types */ -+}; -+#define USDPAA_IOCTL_MAGIC 'u' -+struct usdpaa_ioctl_id_alloc { -+ uint32_t base; /* Return value, the start of the allocated range */ -+ enum usdpaa_id_type id_type; /* what kind of resource(s) to allocate */ -+ uint32_t num; /* how many IDs to allocate (and return value) */ -+ uint32_t align; /* must be a power of 2, 0 is treated like 1 */ -+ int partial; /* whether to allow less than 'num' */ -+}; -+struct usdpaa_ioctl_id_release { -+ /* Input; */ -+ enum usdpaa_id_type id_type; -+ uint32_t base; -+ uint32_t num; -+}; -+struct usdpaa_ioctl_id_reserve { -+ enum usdpaa_id_type id_type; -+ uint32_t base; -+ uint32_t num; -+}; -+ -+ -+/* ioctl() commands */ -+#define USDPAA_IOCTL_ID_ALLOC \ -+ _IOWR(USDPAA_IOCTL_MAGIC, 0x01, struct usdpaa_ioctl_id_alloc) -+#define USDPAA_IOCTL_ID_RELEASE \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x02, struct usdpaa_ioctl_id_release) -+#define USDPAA_IOCTL_ID_RESERVE \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x0A, struct usdpaa_ioctl_id_reserve) -+ -+/**********************/ -+/* Mapping DMA memory */ -+/**********************/ -+ -+/* Maximum length for a map name, including NULL-terminator */ -+#define USDPAA_DMA_NAME_MAX 16 -+/* Flags for requesting DMA maps. Maps are private+unnamed or sharable+named. -+ * For a sharable and named map, specify _SHARED (whether creating one or -+ * binding to an existing one). If _SHARED is specified and _CREATE is not, then -+ * the mapping must already exist. If _SHARED and _CREATE are specified and the -+ * mapping doesn't already exist, it will be created. If _SHARED and _CREATE are -+ * specified and the mapping already exists, the mapping will fail unless _LAZY -+ * is specified. When mapping to a pre-existing sharable map, the length must be -+ * an exact match. Lengths must be a power-of-4 multiple of page size. -+ * -+ * Note that this does not actually map the memory to user-space, that is done -+ * by a subsequent mmap() using the page offset returned from this ioctl(). The -+ * ioctl() is what gives the process permission to do this, and a page-offset -+ * with which to do so. -+ */ -+#define USDPAA_DMA_FLAG_SHARE 0x01 -+#define USDPAA_DMA_FLAG_CREATE 0x02 -+#define USDPAA_DMA_FLAG_LAZY 0x04 -+#define USDPAA_DMA_FLAG_RDONLY 0x08 -+struct usdpaa_ioctl_dma_map { -+ /* Output parameters - virtual and physical addresses */ -+ void *ptr; -+ uint64_t phys_addr; -+ /* Input parameter, the length of the region to be created (or if -+ * mapping an existing region, this must match it). Must be a power-of-4 -+ * multiple of page size. */ -+ uint64_t len; -+ /* Input parameter, the USDPAA_DMA_FLAG_* settings. */ -+ uint32_t flags; -+ /* If _FLAG_SHARE is specified, the name of the region to be created (or -+ * of the existing mapping to use). */ -+ char name[USDPAA_DMA_NAME_MAX]; -+ /* If this ioctl() creates the mapping, this is an input parameter -+ * stating whether the region supports locking. If mapping an existing -+ * region, this is a return value indicating the same thing. */ -+ int has_locking; -+ /* In the case of a successful map with _CREATE and _LAZY, this return -+ * value indicates whether we created the mapped region or whether it -+ * already existed. */ -+ int did_create; -+}; -+ -+#ifdef CONFIG_COMPAT -+struct usdpaa_ioctl_dma_map_compat { -+ /* Output parameters - virtual and physical addresses */ -+ compat_uptr_t ptr; -+ uint64_t phys_addr; -+ /* Input parameter, the length of the region to be created (or if -+ * mapping an existing region, this must match it). Must be a power-of-4 -+ * multiple of page size. */ -+ uint64_t len; -+ /* Input parameter, the USDPAA_DMA_FLAG_* settings. */ -+ uint32_t flags; -+ /* If _FLAG_SHARE is specified, the name of the region to be created (or -+ * of the existing mapping to use). */ -+ char name[USDPAA_DMA_NAME_MAX]; -+ /* If this ioctl() creates the mapping, this is an input parameter -+ * stating whether the region supports locking. If mapping an existing -+ * region, this is a return value indicating the same thing. */ -+ int has_locking; -+ /* In the case of a successful map with _CREATE and _LAZY, this return -+ * value indicates whether we created the mapped region or whether it -+ * already existed. */ -+ int did_create; -+}; -+ -+#define USDPAA_IOCTL_DMA_MAP_COMPAT \ -+ _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map_compat) -+#endif -+ -+ -+#define USDPAA_IOCTL_DMA_MAP \ -+ _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map) -+/* munmap() does not remove the DMA map, just the user-space mapping to it. -+ * This ioctl will do both (though you can munmap() before calling the ioctl -+ * too). */ -+#define USDPAA_IOCTL_DMA_UNMAP \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x04, unsigned char) -+/* We implement a cross-process locking scheme per DMA map. Call this ioctl() -+ * with a mmap()'d address, and the process will (interruptible) sleep if the -+ * lock is already held by another process. Process destruction will -+ * automatically clean up any held locks. */ -+#define USDPAA_IOCTL_DMA_LOCK \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x05, unsigned char) -+#define USDPAA_IOCTL_DMA_UNLOCK \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x06, unsigned char) -+ -+/***************************************/ -+/* Mapping and using QMan/BMan portals */ -+/***************************************/ -+enum usdpaa_portal_type { -+ usdpaa_portal_qman, -+ usdpaa_portal_bman, -+}; -+ -+#define QBMAN_ANY_PORTAL_IDX 0xffffffff -+ -+struct usdpaa_ioctl_portal_map { -+ /* Input parameter, is a qman or bman portal required. */ -+ -+ enum usdpaa_portal_type type; -+ /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX -+ for don't care. The portal index will be populated by the -+ driver when the ioctl() successfully completes */ -+ uint32_t index; -+ -+ /* Return value if the map succeeds, this gives the mapped -+ * cache-inhibited (cinh) and cache-enabled (cena) addresses. */ -+ struct usdpaa_portal_map { -+ void *cinh; -+ void *cena; -+ } addr; -+ /* Qman-specific return values */ -+ uint16_t channel; -+ uint32_t pools; -+}; -+ -+#ifdef CONFIG_COMPAT -+struct compat_usdpaa_ioctl_portal_map { -+ /* Input parameter, is a qman or bman portal required. */ -+ enum usdpaa_portal_type type; -+ /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX -+ for don't care. The portal index will be populated by the -+ driver when the ioctl() successfully completes */ -+ uint32_t index; -+ /* Return value if the map succeeds, this gives the mapped -+ * cache-inhibited (cinh) and cache-enabled (cena) addresses. */ -+ struct usdpaa_portal_map_compat { -+ compat_uptr_t cinh; -+ compat_uptr_t cena; -+ } addr; -+ /* Qman-specific return values */ -+ uint16_t channel; -+ uint32_t pools; -+}; -+#define USDPAA_IOCTL_PORTAL_MAP_COMPAT \ -+ _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct compat_usdpaa_ioctl_portal_map) -+#define USDPAA_IOCTL_PORTAL_UNMAP_COMPAT \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map_compat) -+#endif -+ -+#define USDPAA_IOCTL_PORTAL_MAP \ -+ _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct usdpaa_ioctl_portal_map) -+#define USDPAA_IOCTL_PORTAL_UNMAP \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map) -+ -+struct usdpaa_ioctl_irq_map { -+ enum usdpaa_portal_type type; /* Type of portal to map */ -+ int fd; /* File descriptor that contains the portal */ -+ void *portal_cinh; /* Cache inhibited area to identify the portal */ -+}; -+ -+#define USDPAA_IOCTL_PORTAL_IRQ_MAP \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct usdpaa_ioctl_irq_map) -+ -+#ifdef CONFIG_COMPAT -+ -+struct compat_ioctl_irq_map { -+ enum usdpaa_portal_type type; /* Type of portal to map */ -+ compat_int_t fd; /* File descriptor that contains the portal */ -+ compat_uptr_t portal_cinh; /* Used identify the portal */}; -+ -+#define USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct compat_ioctl_irq_map) -+#endif -+ -+/* ioctl to query the amount of DMA memory used in the system */ -+struct usdpaa_ioctl_dma_used { -+ uint64_t free_bytes; -+ uint64_t total_bytes; -+}; -+#define USDPAA_IOCTL_DMA_USED \ -+ _IOR(USDPAA_IOCTL_MAGIC, 0x0B, struct usdpaa_ioctl_dma_used) -+ -+/* ioctl to allocate a raw portal */ -+struct usdpaa_ioctl_raw_portal { -+ /* inputs */ -+ enum usdpaa_portal_type type; /* Type of portal to allocate */ -+ -+ /* set to non zero to turn on stashing */ -+ uint8_t enable_stash; -+ /* Stashing attributes for the portal */ -+ uint32_t cpu; -+ uint32_t cache; -+ uint32_t window; -+ -+ /* Specifies the stash request queue this portal should use */ -+ uint8_t sdest; -+ -+ /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX -+ * for don't care. The portal index will be populated by the -+ * driver when the ioctl() successfully completes */ -+ uint32_t index; -+ -+ /* outputs */ -+ uint64_t cinh; -+ uint64_t cena; -+}; -+ -+#define USDPAA_IOCTL_ALLOC_RAW_PORTAL \ -+ _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct usdpaa_ioctl_raw_portal) -+ -+#define USDPAA_IOCTL_FREE_RAW_PORTAL \ -+ _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct usdpaa_ioctl_raw_portal) -+ -+#ifdef CONFIG_COMPAT -+ -+struct compat_ioctl_raw_portal { -+ /* inputs */ -+ enum usdpaa_portal_type type; /* Type of portal to allocate */ -+ -+ /* set to non zero to turn on stashing */ -+ uint8_t enable_stash; -+ /* Stashing attributes for the portal */ -+ uint32_t cpu; -+ uint32_t cache; -+ uint32_t window; -+ /* Specifies the stash request queue this portal should use */ -+ uint8_t sdest; -+ -+ /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX -+ * for don't care. The portal index will be populated by the -+ * driver when the ioctl() successfully completes */ -+ uint32_t index; -+ -+ /* outputs */ -+ uint64_t cinh; -+ uint64_t cena; -+}; -+ -+#define USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT \ -+ _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct compat_ioctl_raw_portal) -+ -+#define USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT \ -+ _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct compat_ioctl_raw_portal) -+ -+#endif -+ -+#ifdef __KERNEL__ -+ -+/* Early-boot hook */ -+int __init fsl_usdpaa_init_early(void); -+ -+/* Fault-handling in arch/powerpc/mm/mem.c gives USDPAA an opportunity to detect -+ * faults within its ranges via this hook. */ -+int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size); -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* CONFIG_FSL_USDPAA */ -+ -+#ifdef __KERNEL__ -+/* This interface is needed in a few places and though it's not specific to -+ * USDPAA as such, creating a new header for it doesn't make any sense. The -+ * qbman kernel driver implements this interface and uses it as the backend for -+ * both the FQID and BPID allocators. The fsl_usdpaa driver also uses this -+ * interface for tracking per-process allocations handed out to user-space. */ -+struct dpa_alloc { -+ struct list_head free; -+ spinlock_t lock; -+ struct list_head used; -+}; -+#define DECLARE_DPA_ALLOC(name) \ -+ struct dpa_alloc name = { \ -+ .free = { \ -+ .prev = &name.free, \ -+ .next = &name.free \ -+ }, \ -+ .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ -+ .used = { \ -+ .prev = &name.used, \ -+ .next = &name.used \ -+ } \ -+ } -+static inline void dpa_alloc_init(struct dpa_alloc *alloc) -+{ -+ INIT_LIST_HEAD(&alloc->free); -+ INIT_LIST_HEAD(&alloc->used); -+ spin_lock_init(&alloc->lock); -+} -+int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align, -+ int partial); -+void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count); -+void dpa_alloc_seed(struct dpa_alloc *alloc, u32 fqid, u32 count); -+ -+/* Like 'new' but specifies the desired range, returns -ENOMEM if the entire -+ * desired range is not available, or 0 for success. */ -+int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base_id, u32 count); -+/* Pops and returns contiguous ranges from the allocator. Returns -ENOMEM when -+ * 'alloc' is empty. */ -+int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count); -+/* Returns 1 if the specified id is alloced, 0 otherwise */ -+int dpa_alloc_check(struct dpa_alloc *list, u32 id); -+#endif /* __KERNEL__ */ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* FSL_USDPAA_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0008-fmd-SDK-DPAA-1.x-FMan-driver.patch b/target/linux/layerscape/patches-5.4/701-net-0008-fmd-SDK-DPAA-1.x-FMan-driver.patch deleted file mode 100644 index 6401ba14be..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0008-fmd-SDK-DPAA-1.x-FMan-driver.patch +++ /dev/null @@ -1,116456 +0,0 @@ -From 2701a01f8da8321d3fb8b2e99240fbc5c093a27b Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Wed, 10 May 2017 16:36:36 +0300 -Subject: [PATCH] fmd: SDK DPAA 1.x FMan driver - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_fman/Kconfig | 153 + - drivers/net/ethernet/freescale/sdk_fman/Makefile | 11 + - .../freescale/sdk_fman/Peripherals/FM/HC/Makefile | 15 + - .../freescale/sdk_fman/Peripherals/FM/HC/hc.c | 1232 ++++ - .../freescale/sdk_fman/Peripherals/FM/MAC/Makefile | 28 + - .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c | 1464 ++++ - .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h | 228 + - .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c | 97 + - .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h | 42 + - .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c | 658 ++ - .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h | 225 + - .../sdk_fman/Peripherals/FM/MAC/fman_crc32.c | 119 + - .../sdk_fman/Peripherals/FM/MAC/fman_crc32.h | 43 + - .../sdk_fman/Peripherals/FM/MAC/fman_dtsec.c | 845 +++ - .../Peripherals/FM/MAC/fman_dtsec_mii_acc.c | 163 + - .../sdk_fman/Peripherals/FM/MAC/fman_memac.c | 511 ++ - .../Peripherals/FM/MAC/fman_memac_mii_acc.c | 213 + - .../sdk_fman/Peripherals/FM/MAC/fman_tgec.c | 367 + - .../freescale/sdk_fman/Peripherals/FM/MAC/memac.c | 1096 +++ - .../freescale/sdk_fman/Peripherals/FM/MAC/memac.h | 110 + - .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c | 78 + - .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h | 73 + - .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.c | 975 +++ - .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.h | 151 + - .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c | 139 + - .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h | 80 + - .../sdk_fman/Peripherals/FM/MACSEC/Makefile | 15 + - .../sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c | 237 + - .../sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h | 203 + - .../Peripherals/FM/MACSEC/fm_macsec_guest.c | 59 + - .../Peripherals/FM/MACSEC/fm_macsec_master.c | 1031 +++ - .../Peripherals/FM/MACSEC/fm_macsec_master.h | 479 ++ - .../Peripherals/FM/MACSEC/fm_macsec_secy.c | 883 +++ - .../Peripherals/FM/MACSEC/fm_macsec_secy.h | 144 + - .../freescale/sdk_fman/Peripherals/FM/Makefile | 23 + - .../freescale/sdk_fman/Peripherals/FM/Pcd/Makefile | 26 + - .../freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h | 360 + - .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c | 7582 ++++++++++++++++++++ - .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h | 399 + - .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c | 3242 +++++++++ - .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h | 206 + - .../sdk_fman/Peripherals/FM/Pcd/fm_manip.c | 5571 ++++++++++++++ - .../sdk_fman/Peripherals/FM/Pcd/fm_manip.h | 555 ++ - .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c | 2095 ++++++ - .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h | 543 ++ - .../sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h | 280 + - .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.c | 1847 +++++ - .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h | 165 + - .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c | 423 ++ - .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h | 316 + - .../sdk_fman/Peripherals/FM/Pcd/fm_replic.c | 984 +++ - .../sdk_fman/Peripherals/FM/Pcd/fm_replic.h | 101 + - .../sdk_fman/Peripherals/FM/Pcd/fman_kg.c | 888 +++ - .../sdk_fman/Peripherals/FM/Pcd/fman_prs.c | 129 + - .../sdk_fman/Peripherals/FM/Port/Makefile | 15 + - .../sdk_fman/Peripherals/FM/Port/fm_port.c | 6436 +++++++++++++++++ - .../sdk_fman/Peripherals/FM/Port/fm_port.h | 999 +++ - .../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h | 494 ++ - .../sdk_fman/Peripherals/FM/Port/fm_port_im.c | 753 ++ - .../sdk_fman/Peripherals/FM/Port/fman_port.c | 1568 ++++ - .../freescale/sdk_fman/Peripherals/FM/Rtc/Makefile | 15 + - .../freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c | 692 ++ - .../freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h | 96 + - .../sdk_fman/Peripherals/FM/Rtc/fman_rtc.c | 334 + - .../freescale/sdk_fman/Peripherals/FM/SP/Makefile | 15 + - .../freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c | 757 ++ - .../freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h | 85 + - .../freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c | 197 + - .../freescale/sdk_fman/Peripherals/FM/fm.c | 5216 ++++++++++++++ - .../freescale/sdk_fman/Peripherals/FM/fm.h | 648 ++ - .../freescale/sdk_fman/Peripherals/FM/fm_ipc.h | 465 ++ - .../freescale/sdk_fman/Peripherals/FM/fm_muram.c | 174 + - .../freescale/sdk_fman/Peripherals/FM/fman.c | 1398 ++++ - .../sdk_fman/Peripherals/FM/inc/fm_common.h | 1214 ++++ - .../freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h | 93 + - .../sdk_fman/Peripherals/FM/inc/fm_sp_common.h | 117 + - .../net/ethernet/freescale/sdk_fman/etc/Makefile | 12 + - .../net/ethernet/freescale/sdk_fman/etc/error.c | 95 + - drivers/net/ethernet/freescale/sdk_fman/etc/list.c | 71 + - .../net/ethernet/freescale/sdk_fman/etc/memcpy.c | 620 ++ - drivers/net/ethernet/freescale/sdk_fman/etc/mm.c | 1155 +++ - drivers/net/ethernet/freescale/sdk_fman/etc/mm.h | 105 + - .../net/ethernet/freescale/sdk_fman/etc/sprint.c | 81 + - .../ethernet/freescale/sdk_fman/fmanv3h_dflags.h | 57 + - .../ethernet/freescale/sdk_fman/fmanv3l_dflags.h | 56 + - .../sdk_fman/inc/Peripherals/crc_mac_addr_ext.h | 364 + - .../freescale/sdk_fman/inc/Peripherals/dpaa_ext.h | 210 + - .../freescale/sdk_fman/inc/Peripherals/fm_ext.h | 1731 +++++ - .../sdk_fman/inc/Peripherals/fm_mac_ext.h | 859 +++ - .../sdk_fman/inc/Peripherals/fm_macsec_ext.h | 1271 ++++ - .../sdk_fman/inc/Peripherals/fm_muram_ext.h | 170 + - .../sdk_fman/inc/Peripherals/fm_pcd_ext.h | 3974 ++++++++++ - .../sdk_fman/inc/Peripherals/fm_port_ext.h | 2608 +++++++ - .../sdk_fman/inc/Peripherals/fm_rtc_ext.h | 619 ++ - .../sdk_fman/inc/Peripherals/fm_vsp_ext.h | 411 ++ - .../sdk_fman/inc/Peripherals/mii_acc_ext.h | 76 + - .../net/ethernet/freescale/sdk_fman/inc/core_ext.h | 90 + - .../freescale/sdk_fman/inc/cores/arm_ext.h | 55 + - .../freescale/sdk_fman/inc/cores/e500v2_ext.h | 476 ++ - .../freescale/sdk_fman/inc/cores/ppc_ext.h | 141 + - .../ethernet/freescale/sdk_fman/inc/ddr_std_ext.h | 77 + - .../ethernet/freescale/sdk_fman/inc/debug_ext.h | 233 + - .../ethernet/freescale/sdk_fman/inc/endian_ext.h | 447 ++ - .../net/ethernet/freescale/sdk_fman/inc/enet_ext.h | 205 + - .../ethernet/freescale/sdk_fman/inc/error_ext.h | 529 ++ - .../ethernet/freescale/sdk_fman/inc/etc/list_ext.h | 358 + - .../ethernet/freescale/sdk_fman/inc/etc/mem_ext.h | 318 + - .../freescale/sdk_fman/inc/etc/memcpy_ext.h | 208 + - .../ethernet/freescale/sdk_fman/inc/etc/mm_ext.h | 310 + - .../freescale/sdk_fman/inc/etc/sprint_ext.h | 118 + - .../sdk_fman/inc/flib/common/arch/ppc_access.h | 37 + - .../freescale/sdk_fman/inc/flib/common/general.h | 52 + - .../freescale/sdk_fman/inc/flib/fman_common.h | 78 + - .../freescale/sdk_fman/inc/flib/fsl_enet.h | 273 + - .../freescale/sdk_fman/inc/flib/fsl_fman.h | 825 +++ - .../freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h | 1096 +++ - .../sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h | 107 + - .../freescale/sdk_fman/inc/flib/fsl_fman_kg.h | 514 ++ - .../freescale/sdk_fman/inc/flib/fsl_fman_memac.h | 427 ++ - .../sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h | 78 + - .../freescale/sdk_fman/inc/flib/fsl_fman_port.h | 593 ++ - .../freescale/sdk_fman/inc/flib/fsl_fman_prs.h | 102 + - .../freescale/sdk_fman/inc/flib/fsl_fman_rtc.h | 449 ++ - .../freescale/sdk_fman/inc/flib/fsl_fman_sp.h | 138 + - .../freescale/sdk_fman/inc/flib/fsl_fman_tgec.h | 479 ++ - .../integrations/FMANV3H/dpaa_integration_ext.h | 291 + - .../sdk_fman/inc/integrations/FMANV3H/part_ext.h | 71 + - .../integrations/FMANV3H/part_integration_ext.h | 304 + - .../integrations/FMANV3L/dpaa_integration_ext.h | 293 + - .../sdk_fman/inc/integrations/FMANV3L/part_ext.h | 59 + - .../integrations/FMANV3L/part_integration_ext.h | 304 + - .../inc/integrations/LS1043/dpaa_integration_ext.h | 291 + - .../sdk_fman/inc/integrations/LS1043/part_ext.h | 64 + - .../inc/integrations/LS1043/part_integration_ext.h | 185 + - .../inc/integrations/P1023/dpaa_integration_ext.h | 213 + - .../sdk_fman/inc/integrations/P1023/part_ext.h | 82 + - .../inc/integrations/P1023/part_integration_ext.h | 635 ++ - .../P3040_P4080_P5020/dpaa_integration_ext.h | 276 + - .../inc/integrations/P3040_P4080_P5020/part_ext.h | 83 + - .../P3040_P4080_P5020/part_integration_ext.h | 336 + - .../net/ethernet/freescale/sdk_fman/inc/math_ext.h | 100 + - .../net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h | 435 ++ - .../net/ethernet/freescale/sdk_fman/inc/net_ext.h | 430 ++ - .../net/ethernet/freescale/sdk_fman/inc/std_ext.h | 48 + - .../ethernet/freescale/sdk_fman/inc/stdarg_ext.h | 49 + - .../ethernet/freescale/sdk_fman/inc/stdlib_ext.h | 162 + - .../ethernet/freescale/sdk_fman/inc/string_ext.h | 56 + - .../ethernet/freescale/sdk_fman/inc/types_ext.h | 62 + - .../ethernet/freescale/sdk_fman/inc/xx_common.h | 56 + - .../net/ethernet/freescale/sdk_fman/inc/xx_ext.h | 791 ++ - .../ethernet/freescale/sdk_fman/ls1043_dflags.h | 56 + - .../net/ethernet/freescale/sdk_fman/ncsw_config.mk | 53 + - .../net/ethernet/freescale/sdk_fman/p1023_dflags.h | 65 + - .../freescale/sdk_fman/p3040_4080_5020_dflags.h | 62 + - .../net/ethernet/freescale/sdk_fman/src/Makefile | 11 + - .../freescale/sdk_fman/src/inc/system/sys_ext.h | 118 + - .../freescale/sdk_fman/src/inc/system/sys_io_ext.h | 46 + - .../freescale/sdk_fman/src/inc/types_linux.h | 208 + - .../sdk_fman/src/inc/wrapper/fsl_fman_test.h | 84 + - .../sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h | 128 + - .../sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h | 163 + - .../sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h | 921 +++ - .../ethernet/freescale/sdk_fman/src/inc/xx/xx.h | 50 + - .../freescale/sdk_fman/src/system/Makefile | 10 + - .../freescale/sdk_fman/src/system/sys_io.c | 171 + - .../freescale/sdk_fman/src/wrapper/Makefile | 19 + - .../freescale/sdk_fman/src/wrapper/fman_test.c | 1665 +++++ - .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 2908 ++++++++ - .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.h | 294 + - .../sdk_fman/src/wrapper/lnxwrp_fm_port.c | 1480 ++++ - .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c | 4813 +++++++++++++ - .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c | 1297 ++++ - .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h | 755 ++ - .../sdk_fman/src/wrapper/lnxwrp_resources.h | 121 + - .../sdk_fman/src/wrapper/lnxwrp_resources_ut.c | 191 + - .../sdk_fman/src/wrapper/lnxwrp_resources_ut.h | 144 + - .../sdk_fman/src/wrapper/lnxwrp_resources_ut.make | 28 + - .../freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c | 60 + - .../freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h | 60 + - .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c | 1855 +++++ - .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h | 136 + - .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c | 1268 ++++ - .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h | 56 + - .../ethernet/freescale/sdk_fman/src/xx/Makefile | 18 + - .../freescale/sdk_fman/src/xx/module_strings.c | 46 + - .../freescale/sdk_fman/src/xx/xx_arm_linux.c | 905 +++ - .../ethernet/freescale/sdk_fman/src/xx/xx_linux.c | 918 +++ - include/linux/fsl/svr.h | 97 + - include/uapi/linux/fmd/Kbuild | 5 + - include/uapi/linux/fmd/Peripherals/Kbuild | 4 + - include/uapi/linux/fmd/Peripherals/fm_ioctls.h | 628 ++ - include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h | 3084 ++++++++ - .../uapi/linux/fmd/Peripherals/fm_port_ioctls.h | 948 +++ - .../uapi/linux/fmd/Peripherals/fm_test_ioctls.h | 208 + - include/uapi/linux/fmd/integrations/Kbuild | 1 + - .../linux/fmd/integrations/integration_ioctls.h | 56 + - include/uapi/linux/fmd/ioctls.h | 96 + - include/uapi/linux/fmd/net_ioctls.h | 430 ++ - 198 files changed, 115457 insertions(+) - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Kconfig - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/error.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/list.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c - create mode 100755 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c - create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c - create mode 100644 include/linux/fsl/svr.h - create mode 100644 include/uapi/linux/fmd/Kbuild - create mode 100644 include/uapi/linux/fmd/Peripherals/Kbuild - create mode 100644 include/uapi/linux/fmd/Peripherals/fm_ioctls.h - create mode 100644 include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h - create mode 100644 include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h - create mode 100644 include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h - create mode 100644 include/uapi/linux/fmd/integrations/Kbuild - create mode 100644 include/uapi/linux/fmd/integrations/integration_ioctls.h - create mode 100644 include/uapi/linux/fmd/ioctls.h - create mode 100644 include/uapi/linux/fmd/net_ioctls.h - ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Kconfig -@@ -0,0 +1,153 @@ -+menu "Frame Manager support" -+ -+menuconfig FSL_SDK_FMAN -+ bool "Freescale Frame Manager (datapath) support - SDK driver" -+ depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && !FSL_FMAN -+ default y -+ ---help--- -+ If unsure, say Y. -+ -+if FSL_SDK_FMAN -+ -+config FSL_SDK_FMAN_TEST -+ bool "FMan test module" -+ default n -+ select FSL_DPAA_HOOKS -+ ---help--- -+ This option compiles test code for FMan. -+ -+menu "FMAN Processor support" -+choice -+ depends on FSL_SDK_FMAN -+ prompt "Processor Type" -+ -+config FMAN_ARM -+ bool "LS1043" -+ depends on ARM64 || ARM -+ ---help--- -+ Choose "LS1043" for the ARM platforms: -+ LS1043 -+ -+config FMAN_P3040_P4080_P5020 -+ bool "P3040 P4080 5020" -+ -+config FMAN_P1023 -+ bool "P1023" -+ -+config FMAN_V3H -+ bool "FmanV3H" -+ ---help--- -+ Choose "FmanV3H" for Fman rev3H: -+ B4860, T4240, T4160, etc -+ -+config FMAN_V3L -+ bool "FmanV3L" -+ ---help--- -+ Choose "FmanV3L" for Fman rev3L: -+ T1040, T1042, T1020, T1022, T1023, T1024, etc -+ -+endchoice -+endmenu -+ -+config FMAN_MIB_CNT_OVF_IRQ_EN -+ bool "Enable the dTSEC MIB counters overflow interrupt" -+ default n -+ ---help--- -+ Enable the dTSEC MIB counters overflow interrupt to get -+ accurate MIB counters values. Enabled it compensates -+ for the counters overflow but reduces performance and -+ triggers error messages in HV setups. -+ -+config FSL_FM_MAX_FRAME_SIZE -+ int "Maximum L2 frame size" -+ depends on FSL_SDK_FMAN -+ range 64 9600 -+ default "1522" -+ help -+ Configure this in relation to the maximum possible MTU of your -+ network configuration. In particular, one would need to -+ increase this value in order to use jumbo frames. -+ FSL_FM_MAX_FRAME_SIZE must accommodate the Ethernet FCS (4 bytes) -+ and one ETH+VLAN header (18 bytes), to a total of 22 bytes in -+ excess of the desired L3 MTU. -+ -+ Note that having too large a FSL_FM_MAX_FRAME_SIZE (much larger -+ than the actual MTU) may lead to buffer exhaustion, especially -+ in the case of badly fragmented datagrams on the Rx path. -+ Conversely, having a FSL_FM_MAX_FRAME_SIZE smaller than the actual -+ MTU will lead to frames being dropped. -+ -+ This can be overridden by specifying "fsl_fm_max_frm" in -+ the kernel bootargs: -+ * in Hypervisor-based scenarios, by adding a "chosen" node -+ with the "bootargs" property specifying -+ "fsl_fm_max_frm="; -+ * in non-Hypervisor-based scenarios, via u-boot's env, by -+ modifying the "bootargs" env variable. -+ -+config FSL_FM_RX_EXTRA_HEADROOM -+ int "Add extra headroom at beginning of data buffers" -+ depends on FSL_SDK_FMAN -+ range 16 384 -+ default "64" -+ help -+ Configure this to tell the Frame Manager to reserve some extra -+ space at the beginning of a data buffer on the receive path, -+ before Internal Context fields are copied. This is in addition -+ to the private data area already reserved for driver internal -+ use. The provided value must be a multiple of 16. -+ -+ This setting can be overridden by specifying -+ "fsl_fm_rx_extra_headroom" in the kernel bootargs: -+ * in Hypervisor-based scenarios, by adding a "chosen" node -+ with the "bootargs" property specifying -+ "fsl_fm_rx_extra_headroom="; -+ * in non-Hypervisor-based scenarios, via u-boot's env, by -+ modifying the "bootargs" env variable. -+ -+config FMAN_PFC -+ bool "FMan PFC support (EXPERIMENTAL)" -+ depends on ( FMAN_V3H || FMAN_V3L || FMAN_ARM) && FSL_SDK_FMAN -+ default n -+ help -+ This option enables PFC support on FMan v3 ports. -+ Data Center Bridging defines Classes of Service that are -+ flow-controlled using PFC pause frames. -+ -+if FMAN_PFC -+config FMAN_PFC_COS_COUNT -+ int "Number of PFC Classes of Service" -+ depends on FMAN_PFC && FSL_SDK_FMAN -+ range 1 4 -+ default "3" -+ help -+ The number of Classes of Service controlled by PFC. -+ -+config FMAN_PFC_QUANTA_0 -+ int "The pause quanta for PFC CoS 0" -+ depends on FMAN_PFC && FSL_SDK_FMAN -+ range 0 65535 -+ default "65535" -+ -+config FMAN_PFC_QUANTA_1 -+ int "The pause quanta for PFC CoS 1" -+ depends on FMAN_PFC && FSL_SDK_FMAN -+ range 0 65535 -+ default "65535" -+ -+config FMAN_PFC_QUANTA_2 -+ int "The pause quanta for PFC CoS 2" -+ depends on FMAN_PFC && FSL_SDK_FMAN -+ range 0 65535 -+ default "65535" -+ -+config FMAN_PFC_QUANTA_3 -+ int "The pause quanta for PFC CoS 3" -+ depends on FMAN_PFC && FSL_SDK_FMAN -+ range 0 65535 -+ default "65535" -+endif -+ -+endif # FSL_SDK_FMAN -+ -+endmenu ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Makefile -@@ -0,0 +1,11 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+# -+obj-y += etc/ -+obj-y += Peripherals/FM/ -+obj-y += src/ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile -@@ -0,0 +1,15 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc -+ -+ccflags-y += -I$(NCSW_FM_INC) -+ -+obj-y += fsl-ncsw-Hc.o -+ -+fsl-ncsw-Hc-objs := hc.o ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c -@@ -0,0 +1,1232 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "sprint_ext.h" -+#include "string_ext.h" -+ -+#include "fm_common.h" -+#include "fm_hc.h" -+ -+ -+/**************************************************************************//** -+ @Description defaults -+*//***************************************************************************/ -+#define DEFAULT_dataMemId 0 -+ -+#define HC_HCOR_OPCODE_PLCR_PRFL 0x0 -+#define HC_HCOR_OPCODE_KG_SCM 0x1 -+#define HC_HCOR_OPCODE_SYNC 0x2 -+#define HC_HCOR_OPCODE_CC 0x3 -+#define HC_HCOR_OPCODE_CC_AGE_MASK 0x4 -+#define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5 -+#define HC_HCOR_OPCODE_CC_REASSM_TIMEOUT 0x10 -+#define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11 -+#define HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING 0x13 -+#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24 -+#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24 -+#define HC_HCOR_EXTRA_REG_CC_AGING_ADD 0x80000000 -+#define HC_HCOR_EXTRA_REG_CC_AGING_REMOVE 0x40000000 -+#define HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK 0xC0000000 -+#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT 24 -+#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK 0x1F000000 -+#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16 -+#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF -+#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24 -+#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16 -+ -+#define HC_HCOR_GBL 0x20000000 -+ -+#define HC_HCOR_KG_SCHEME_COUNTER 0x00000400 -+ -+#if (DPAA_VERSION == 10) -+#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFF800 -+#else -+#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFFE00 -+#endif /* (DPAA_VERSION == 10) */ -+ -+#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdKgPortRegs)) -+#define SIZE_OF_HC_FRAME_SCHEME_REGS sizeof(t_HcFrame) -+#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdPlcrProfileRegs)) -+#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrProfileRegs)+sizeof(uint32_t)) -+#define SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC 16 -+ -+#define HC_CMD_POOL_SIZE (INTG_MAX_NUM_OF_CORES) -+ -+#define BUILD_FD(len) \ -+do { \ -+ memset(&fmFd, 0, sizeof(t_DpaaFD)); \ -+ DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \ -+ DPAA_FD_SET_OFFSET(&fmFd, 0); \ -+ DPAA_FD_SET_LENGTH(&fmFd, len); \ -+} while (0) -+ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+typedef struct t_FmPcdKgPortRegs { -+ volatile uint32_t spReg; -+ volatile uint32_t cppReg; -+} t_FmPcdKgPortRegs; -+ -+typedef struct t_HcFrame { -+ volatile uint32_t opcode; -+ volatile uint32_t actionReg; -+ volatile uint32_t extraReg; -+ volatile uint32_t commandSequence; -+ union { -+ struct fman_kg_scheme_regs schemeRegs; -+ struct fman_kg_scheme_regs schemeRegsWithoutCounter; -+ t_FmPcdPlcrProfileRegs profileRegs; -+ volatile uint32_t singleRegForWrite; /* for writing SP, CPP, profile counter */ -+ t_FmPcdKgPortRegs portRegsForRead; -+ volatile uint32_t clsPlanEntries[CLS_PLAN_NUM_PER_GRP]; -+ t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout; -+ t_FmPcdCcReassmTimeoutParams ccReassmTimeout; -+ } hcSpecificData; -+} t_HcFrame; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+typedef struct t_FmHc { -+ t_Handle h_FmPcd; -+ t_Handle h_HcPortDev; -+ t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< A callback for enqueuing frames to the QM */ -+ t_Handle h_QmArg; /**< A handle to the QM module */ -+ uint8_t dataMemId; /**< Memory partition ID for data buffers */ -+ -+ uint32_t seqNum[HC_CMD_POOL_SIZE]; /* FIFO of seqNum to use when -+ taking buffer */ -+ uint32_t nextSeqNumLocation; /* seqNum location in seqNum[] for next buffer */ -+ volatile bool enqueued[HC_CMD_POOL_SIZE]; /* HC is active - frame is enqueued -+ and not confirmed yet */ -+ t_HcFrame *p_Frm[HC_CMD_POOL_SIZE]; -+} t_FmHc; -+ -+ -+static t_Error FillBufPool(t_FmHc *p_FmHc) -+{ -+ uint32_t i; -+ -+ ASSERT_COND(p_FmHc); -+ -+ for (i = 0; i < HC_CMD_POOL_SIZE; i++) -+ { -+#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 -+ p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + (16 - (sizeof(t_FmHc) % 16))), -+ p_FmHc->dataMemId, -+ 16); -+#else -+ p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart(sizeof(t_HcFrame), -+ p_FmHc->dataMemId, -+ 16); -+#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */ -+ if (!p_FmHc->p_Frm[i]) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM HC frames!")); -+ } -+ -+ /* Initialize FIFO of seqNum to use during GetBuf */ -+ for (i = 0; i < HC_CMD_POOL_SIZE; i++) -+ { -+ p_FmHc->seqNum[i] = i; -+ } -+ p_FmHc->nextSeqNumLocation = 0; -+ -+ return E_OK; -+} -+ -+static __inline__ t_HcFrame * GetBuf(t_FmHc *p_FmHc, uint32_t *p_SeqNum) -+{ -+ uint32_t intFlags; -+ -+ ASSERT_COND(p_FmHc); -+ -+ intFlags = FmPcdLock(p_FmHc->h_FmPcd); -+ -+ if (p_FmHc->nextSeqNumLocation == HC_CMD_POOL_SIZE) -+ { -+ /* No more buffers */ -+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); -+ return NULL; -+ } -+ -+ *p_SeqNum = p_FmHc->seqNum[p_FmHc->nextSeqNumLocation]; -+ p_FmHc->nextSeqNumLocation++; -+ -+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); -+ return p_FmHc->p_Frm[*p_SeqNum]; -+} -+ -+static __inline__ void PutBuf(t_FmHc *p_FmHc, t_HcFrame *p_Buf, uint32_t seqNum) -+{ -+ uint32_t intFlags; -+ -+ UNUSED(p_Buf); -+ -+ intFlags = FmPcdLock(p_FmHc->h_FmPcd); -+ ASSERT_COND(p_FmHc->nextSeqNumLocation); -+ p_FmHc->nextSeqNumLocation--; -+ p_FmHc->seqNum[p_FmHc->nextSeqNumLocation] = seqNum; -+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); -+} -+ -+static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, uint32_t seqNum) -+{ -+ t_Error err = E_OK; -+ uint32_t intFlags; -+ uint32_t timeout=100; -+ -+ intFlags = FmPcdLock(p_FmHc->h_FmPcd); -+ ASSERT_COND(!p_FmHc->enqueued[seqNum]); -+ p_FmHc->enqueued[seqNum] = TRUE; -+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); -+ DBG(TRACE, ("Send Hc, SeqNum %d, buff@0x%x, fd offset 0x%x", -+ seqNum, -+ DPAA_FD_GET_ADDR(p_FmFd), -+ DPAA_FD_GET_OFFSET(p_FmFd))); -+ err = p_FmHc->f_QmEnqueue(p_FmHc->h_QmArg, (void *)p_FmFd); -+ if (err) -+ RETURN_ERROR(MINOR, err, ("HC enqueue failed")); -+ -+ while (p_FmHc->enqueued[seqNum] && --timeout) -+ XX_UDelay(100); -+ -+ if (!timeout) -+ RETURN_ERROR(MINOR, E_TIMEOUT, ("HC Callback, timeout exceeded")); -+ -+ return err; -+} -+ -+ -+t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams) -+{ -+ t_FmHc *p_FmHc; -+ t_FmPortParams fmPortParam; -+ t_Error err; -+ -+ p_FmHc = (t_FmHc *)XX_Malloc(sizeof(t_FmHc)); -+ if (!p_FmHc) -+ { -+ REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC obj")); -+ return NULL; -+ } -+ memset(p_FmHc,0,sizeof(t_FmHc)); -+ -+ p_FmHc->h_FmPcd = p_FmHcParams->h_FmPcd; -+ p_FmHc->f_QmEnqueue = p_FmHcParams->params.f_QmEnqueue; -+ p_FmHc->h_QmArg = p_FmHcParams->params.h_QmArg; -+ p_FmHc->dataMemId = DEFAULT_dataMemId; -+ -+ err = FillBufPool(p_FmHc); -+ if (err != E_OK) -+ { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ FmHcFree(p_FmHc); -+ return NULL; -+ } -+ -+ if (!FmIsMaster(p_FmHcParams->h_Fm)) -+ return (t_Handle)p_FmHc; -+ -+ memset(&fmPortParam, 0, sizeof(fmPortParam)); -+ fmPortParam.baseAddr = p_FmHcParams->params.portBaseAddr; -+ fmPortParam.portType = e_FM_PORT_TYPE_OH_HOST_COMMAND; -+ fmPortParam.portId = p_FmHcParams->params.portId; -+ fmPortParam.liodnBase = p_FmHcParams->params.liodnBase; -+ fmPortParam.h_Fm = p_FmHcParams->h_Fm; -+ -+ fmPortParam.specificParams.nonRxParams.errFqid = p_FmHcParams->params.errFqid; -+ fmPortParam.specificParams.nonRxParams.dfltFqid = p_FmHcParams->params.confFqid; -+ fmPortParam.specificParams.nonRxParams.qmChannel = p_FmHcParams->params.qmChannel; -+ -+ p_FmHc->h_HcPortDev = FM_PORT_Config(&fmPortParam); -+ if (!p_FmHc->h_HcPortDev) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM HC port!")); -+ XX_Free(p_FmHc); -+ return NULL; -+ } -+ -+ err = FM_PORT_ConfigMaxFrameLength(p_FmHc->h_HcPortDev, -+ (uint16_t)sizeof(t_HcFrame)); -+ -+ if (err != E_OK) -+ { -+ REPORT_ERROR(MAJOR, err, ("FM HC port init!")); -+ FmHcFree(p_FmHc); -+ return NULL; -+ } -+ -+ /* final init */ -+ err = FM_PORT_Init(p_FmHc->h_HcPortDev); -+ if (err != E_OK) -+ { -+ REPORT_ERROR(MAJOR, err, ("FM HC port init!")); -+ FmHcFree(p_FmHc); -+ return NULL; -+ } -+ -+ err = FM_PORT_Enable(p_FmHc->h_HcPortDev); -+ if (err != E_OK) -+ { -+ REPORT_ERROR(MAJOR, err, ("FM HC port enable!")); -+ FmHcFree(p_FmHc); -+ return NULL; -+ } -+ -+ return (t_Handle)p_FmHc; -+} -+ -+void FmHcFree(t_Handle h_FmHc) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ int i; -+ -+ if (!p_FmHc) -+ return; -+ -+ for (i=0; ip_Frm[i]) -+ XX_FreeSmart(p_FmHc->p_Frm[i]); -+ else -+ break; -+ -+ if (p_FmHc->h_HcPortDev) -+ FM_PORT_Free(p_FmHc->h_HcPortDev); -+ -+ XX_Free(p_FmHc); -+} -+ -+/*****************************************************************************/ -+t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc, -+ uint8_t memId) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ int i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE); -+ -+ p_FmHc->dataMemId = memId; -+ -+ for (i=0; ip_Frm[i]) -+ XX_FreeSmart(p_FmHc->p_Frm[i]); -+ -+ return FillBufPool(p_FmHc); -+} -+ -+void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_HcFrame *p_HcFrame; -+ uint32_t intFlags; -+ -+ ASSERT_COND(p_FmHc); -+ -+ intFlags = FmPcdLock(p_FmHc->h_FmPcd); -+ p_HcFrame = (t_HcFrame *)PTR_MOVE(DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd)); -+ -+ DBG(TRACE, ("Hc Conf, SeqNum %d, FD@0x%x, fd offset 0x%x", -+ p_HcFrame->commandSequence, DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd))); -+ -+ if (!(p_FmHc->enqueued[p_HcFrame->commandSequence])) -+ REPORT_ERROR(MINOR, E_INVALID_FRAME, ("Not an Host-Command frame received!")); -+ else -+ p_FmHc->enqueued[p_HcFrame->commandSequence] = FALSE; -+ FmPcdUnlock(p_FmHc->h_FmPcd, intFlags); -+} -+ -+t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc, -+ t_Handle h_Scheme, -+ struct fman_kg_scheme_regs *p_SchemeRegs, -+ bool updateCounter) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_Error err = E_OK; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ uint8_t physicalSchemeId; -+ uint32_t seqNum; -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ -+ physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme); -+ -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); -+ p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, updateCounter); -+ p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; -+ memcpy(&p_HcFrame->hcSpecificData.schemeRegs, p_SchemeRegs, sizeof(struct fman_kg_scheme_regs)); -+ if (!updateCounter) -+ { -+ p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = p_SchemeRegs->kgse_dv0; -+ p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = p_SchemeRegs->kgse_dv1; -+ p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = p_SchemeRegs->kgse_ccbs; -+ p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = p_SchemeRegs->kgse_mv; -+ } -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_Error err = E_OK; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme); -+ uint32_t seqNum; -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); -+ p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE); -+ p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; -+ memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(struct fman_kg_scheme_regs)); -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_Error err = E_OK; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ uint8_t relativeSchemeId; -+ uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme); -+ uint32_t tmpReg32 = 0; -+ uint32_t seqNum; -+ -+ /* Scheme is locked by calling routine */ -+ /* WARNING - this lock will not be efficient if other HC routine will attempt to change -+ * "kgse_mode" or "kgse_om" without locking scheme ! -+ */ -+ -+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId); -+ if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); -+ -+ if (!FmPcdKgGetRequiredActionFlag(p_FmHc->h_FmPcd, relativeSchemeId) || -+ !(FmPcdKgGetRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId) & requiredAction)) -+ { -+ if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && -+ (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR)) -+ { -+ if ((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) || -+ (FmPcdKgIsDistrOnPlcrProfile(p_FmHc->h_FmPcd, relativeSchemeId) == TRUE)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared")); -+ err = FmPcdPlcrCcGetSetParams(p_FmHc->h_FmPcd, FmPcdKgGetRelativeProfileId(p_FmHc->h_FmPcd, relativeSchemeId), requiredAction); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ else /* From here we deal with KG-Schemes only */ -+ { -+ /* Pre change general code */ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); -+ p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); -+ p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; -+ p_HcFrame->commandSequence = seqNum; -+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); -+ if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ /* specific change */ -+ if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) && -+ ((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) && -+ (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME))) -+ { -+ tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode; -+ ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); -+ p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; -+ } -+ -+ if ((requiredAction & UPDATE_KG_NIA_CC_WA) && -+ (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_CC)) -+ { -+ tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode; -+ ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC)); -+ tmpReg32 &= ~NIA_FM_CTL_AC_CC; -+ p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_FM_CTL_AC_PRE_CC; -+ } -+ -+ if (requiredAction & UPDATE_KG_OPT_MODE) -+ p_HcFrame->hcSpecificData.schemeRegs.kgse_om = value; -+ -+ if (requiredAction & UPDATE_KG_NIA) -+ { -+ tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode; -+ tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK); -+ tmpReg32 |= value; -+ p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32; -+ } -+ -+ /* Post change general code */ -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); -+ p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); -+ p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ } -+ -+ return E_OK; -+} -+ -+uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_Error err; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ uint32_t retVal; -+ uint8_t relativeSchemeId; -+ uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme); -+ uint32_t seqNum; -+ -+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId); -+ if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); -+ return 0; -+ } -+ -+ /* first read scheme and check that it is valid */ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ { -+ REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ return 0; -+ } -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); -+ p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); -+ p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ if (err != E_OK) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ return 0; -+ } -+ -+ if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode)) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid")); -+ return 0; -+ } -+ -+ retVal = p_HcFrame->hcSpecificData.schemeRegs.kgse_spc; -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ -+ return retVal; -+} -+ -+t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_Error err = E_OK; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ uint8_t relativeSchemeId, physicalSchemeId; -+ uint32_t seqNum; -+ -+ physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme); -+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId); -+ if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); -+ -+ /* first read scheme and check that it is valid */ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); -+ p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE); -+ p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_COUNTER; -+ /* write counter */ -+ p_HcFrame->hcSpecificData.singleRegForWrite = value; -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ return err; -+} -+ -+t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ uint8_t i, idx; -+ uint32_t seqNum; -+ t_Error err = E_OK; -+ -+ ASSERT_COND(p_FmHc); -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ -+ for (i = p_Set->baseEntry; i < (p_Set->baseEntry+p_Set->numOfClsPlanEntries); i+=8) -+ { -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); -+ p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP)); -+ p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; -+ -+ idx = (uint8_t)(i - p_Set->baseEntry); -+ ASSERT_COND(idx < FM_PCD_MAX_NUM_OF_CLS_PLANS); -+ memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t)); -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ -+ if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ } -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ return err; -+} -+ -+t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; -+ -+ p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); -+ if (!p_ClsPlanSet) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set")); -+ -+ memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); -+ -+ p_ClsPlanSet->baseEntry = FmPcdKgGetClsPlanGrpBase(p_FmHc->h_FmPcd, grpId); -+ p_ClsPlanSet->numOfClsPlanEntries = FmPcdKgGetClsPlanGrpSize(p_FmHc->h_FmPcd, grpId); -+ ASSERT_COND(p_ClsPlanSet->numOfClsPlanEntries <= FM_PCD_MAX_NUM_OF_CLS_PLANS); -+ -+ if (FmHcPcdKgSetClsPlan(p_FmHc, p_ClsPlanSet) != E_OK) -+ { -+ XX_Free(p_ClsPlanSet); -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ } -+ -+ XX_Free(p_ClsPlanSet); -+ FmPcdKgDestroyClsPlanGrp(p_FmHc->h_FmPcd, grpId); -+ -+ return E_OK; -+} -+ -+t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams ) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ t_Error err; -+ uint32_t seqNum; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0); -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT); -+ memcpy(&p_HcFrame->hcSpecificData.ccCapwapReassmTimeout, p_CcCapwapReassmTimeoutParams, sizeof(t_FmPcdCcCapwapReassmTimeoutParams)); -+ p_HcFrame->commandSequence = seqNum; -+ BUILD_FD(sizeof(t_HcFrame)); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ return err; -+} -+ -+t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ t_Error err; -+ uint32_t seqNum; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0); -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION); -+ p_HcFrame->actionReg = (uint32_t)(((fill == TRUE) ? 0 : 1) << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT); -+ p_HcFrame->actionReg |= p_FmPcdCcFragScratchPoolCmdParams->bufferPoolId << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID; -+ if (fill == TRUE) -+ { -+ p_HcFrame->extraReg = p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers; -+ } -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers = p_HcFrame->extraReg; -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ return E_OK; -+} -+ -+t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ t_Error err; -+ uint32_t seqNum; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0); -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_REASSM_TIMEOUT); -+ p_HcFrame->actionReg = (uint32_t)((p_CcReassmTimeoutParams->activate ? 0 : 1) << HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT); -+ p_HcFrame->extraReg = (p_CcReassmTimeoutParams->tsbs << HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT) | p_CcReassmTimeoutParams->iprcpt; -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ *p_Result = (uint8_t) -+ ((p_HcFrame->actionReg >> HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT) & HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ return E_OK; -+} -+ -+t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ t_Error err; -+ uint32_t tmpReg32 = 0; -+ uint32_t requiredActionTmp, requiredActionFlag; -+ uint32_t seqNum; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0); -+ -+ /* Profile is locked by calling routine */ -+ /* WARNING - this lock will not be efficient if other HC routine will attempt to change -+ * "fmpl_pegnia" "fmpl_peynia" or "fmpl_pernia" without locking Profile ! -+ */ -+ -+ requiredActionTmp = FmPcdPlcrGetRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId); -+ requiredActionFlag = FmPcdPlcrGetRequiredActionFlag(p_FmHc->h_FmPcd, absoluteProfileId); -+ -+ if (!requiredActionFlag || !(requiredActionTmp & requiredAction)) -+ { -+ if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) -+ { -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ /* first read scheme and check that it is valid */ -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); -+ p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId); -+ p_HcFrame->extraReg = 0x00008000; -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); -+ -+ if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia; -+ if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); -+ } -+ -+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; -+ -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); -+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId); -+ p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(TRUE, FALSE, FALSE); -+ p_HcFrame->extraReg = 0x00008000; -+ p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32; -+ -+ BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT); -+ -+ if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_peynia; -+ if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); -+ } -+ -+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; -+ -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); -+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId); -+ p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, TRUE, FALSE); -+ p_HcFrame->extraReg = 0x00008000; -+ p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32; -+ -+ BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT); -+ -+ if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pernia; -+ if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); -+ } -+ -+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; -+ -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); -+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId); -+ p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, FALSE, TRUE); -+ p_HcFrame->extraReg = 0x00008000; -+ p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32; -+ -+ BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT); -+ -+ if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ } -+ } -+ -+ return E_OK; -+} -+ -+t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_Error err = E_OK; -+ uint16_t profileIndx; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ uint32_t seqNum; -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ -+ profileIndx = FmPcdPlcrProfileGetAbsoluteId(h_Profile); -+ -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); -+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx); -+ p_HcFrame->extraReg = 0x00008000; -+ memcpy(&p_HcFrame->hcSpecificData.profileRegs, p_PlcrRegs, sizeof(t_FmPcdPlcrProfileRegs)); -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile); -+ t_Error err = E_OK; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ uint32_t seqNum; -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); -+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId); -+ p_HcFrame->actionReg |= 0x00008000; -+ p_HcFrame->extraReg = 0x00008000; -+ memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrProfileRegs)); -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value) -+{ -+ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile); -+ t_Error err = E_OK; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ uint32_t seqNum; -+ -+ /* first read scheme and check that it is valid */ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); -+ p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId); -+ p_HcFrame->actionReg |= FmPcdPlcrBuildCounterProfileReg(counter); -+ p_HcFrame->extraReg = 0x00008000; -+ p_HcFrame->hcSpecificData.singleRegForWrite = value; -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile); -+ t_Error err; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ uint32_t retVal = 0; -+ uint32_t seqNum; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0); -+ -+ /* first read scheme and check that it is valid */ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ { -+ REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ return 0; -+ } -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL); -+ p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId); -+ p_HcFrame->extraReg = 0x00008000; -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ if (err != E_OK) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ return 0; -+ } -+ -+ switch (counter) -+ { -+ case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER: -+ retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegpc; -+ break; -+ case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER: -+ retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_peypc; -+ break; -+ case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER: -+ retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perpc; -+ break; -+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER: -+ retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perypc; -+ break; -+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER: -+ retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perrpc; -+ break; -+ default: -+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ return retVal; -+} -+ -+t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ t_Error err = E_OK; -+ uint32_t seqNum; -+ -+ ASSERT_COND(p_FmHc); -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ /* first read SP register */ -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); -+ p_HcFrame->actionReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId); -+ p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(SIZE_OF_HC_FRAME_PORT_REGS); -+ -+ if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK) -+ { -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ /* spReg is the first reg, so we can use it both for read and for write */ -+ if (add) -+ p_HcFrame->hcSpecificData.portRegsForRead.spReg |= spReg; -+ else -+ p_HcFrame->hcSpecificData.portRegsForRead.spReg &= ~spReg; -+ -+ p_HcFrame->actionReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId); -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ t_Error err = E_OK; -+ uint32_t seqNum; -+ -+ ASSERT_COND(p_FmHc); -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ /* first read SP register */ -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM); -+ p_HcFrame->actionReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId); -+ p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK; -+ p_HcFrame->hcSpecificData.singleRegForWrite = cppReg; -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ t_Error err = E_OK; -+ uint32_t seqNum; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE); -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC); -+ p_HcFrame->actionReg = newAdAddrOffset; -+ p_HcFrame->actionReg |= 0xc0000000; -+ p_HcFrame->extraReg = oldAdAddrOffset; -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FmHcPcdSync(t_Handle h_FmHc) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ t_HcFrame *p_HcFrame; -+ t_DpaaFD fmFd; -+ t_Error err = E_OK; -+ uint32_t seqNum; -+ -+ ASSERT_COND(p_FmHc); -+ -+ p_HcFrame = GetBuf(p_FmHc, &seqNum); -+ if (!p_HcFrame) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object")); -+ memset(p_HcFrame, 0, sizeof(t_HcFrame)); -+ /* first read SP register */ -+ p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_SYNC); -+ p_HcFrame->actionReg = 0; -+ p_HcFrame->extraReg = 0; -+ p_HcFrame->commandSequence = seqNum; -+ -+ BUILD_FD(sizeof(t_HcFrame)); -+ -+ err = EnQFrm(p_FmHc, &fmFd, seqNum); -+ -+ PutBuf(p_FmHc, p_HcFrame, seqNum); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Handle FmHcGetPort(t_Handle h_FmHc) -+{ -+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc; -+ return p_FmHc->h_HcPortDev; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile -@@ -0,0 +1,28 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc -+ -+ccflags-y += -I$(NCSW_FM_INC) -+ -+obj-y += fsl-ncsw-MAC.o -+ -+fsl-ncsw-MAC-objs := dtsec.o dtsec_mii_acc.o fm_mac.o tgec.o tgec_mii_acc.o \ -+ fman_dtsec.o fman_dtsec_mii_acc.o fman_memac.o \ -+ fman_tgec.o fman_crc32.o -+ -+ifeq ($(CONFIG_FMAN_V3H),y) -+fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o -+endif -+ifeq ($(CONFIG_FMAN_V3L),y) -+fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o -+endif -+ifeq ($(CONFIG_FMAN_ARM),y) -+fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o -+endif -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c -@@ -0,0 +1,1464 @@ -+/* -+ * Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File dtsec.c -+ -+ @Description FMan dTSEC driver -+*//***************************************************************************/ -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "string_ext.h" -+#include "xx_ext.h" -+#include "endian_ext.h" -+#include "debug_ext.h" -+#include "crc_mac_addr_ext.h" -+ -+#include "fm_common.h" -+#include "dtsec.h" -+#include "fsl_fman_dtsec.h" -+#include "fsl_fman_dtsec_mii_acc.h" -+ -+/*****************************************************************************/ -+/* Internal routines */ -+/*****************************************************************************/ -+ -+static t_Error CheckInitParameters(t_Dtsec *p_Dtsec) -+{ -+ if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds")); -+ if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs")); -+ if (p_Dtsec->addr == 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address")); -+ if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) && -+ p_Dtsec->p_DtsecDriverParam->halfdup_on) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex")); -+ if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode")); -+#ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001 -+ if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */ -+ if (p_Dtsec->p_DtsecDriverParam->rx_preamble) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn")); -+#endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */ -+ if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes")); -+ if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on && -+ (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable")); -+ if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc ) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept ")); -+ if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend > MAX_PACKET_ALIGNMENT) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT )); -+ if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1 > MAX_INTER_PACKET_GAP) || -+ ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) || -+ ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP )); -+ if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB )); -+ if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION )); -+ if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW )); -+ -+ /* If Auto negotiation process is disabled, need to */ -+ /* Set up the PHY using the MII Management Interface */ -+ if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS)); -+ if (!p_Dtsec->f_Exception) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception")); -+ if (!p_Dtsec->f_Event) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event")); -+ -+#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002 -+ if (p_Dtsec->p_DtsecDriverParam->rx_len_check) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!")); -+#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */ -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static uint32_t GetMacAddrHashCode(uint64_t ethAddr) -+{ -+ uint32_t crc; -+ -+ /* CRC calculation */ -+ GET_MAC_ADDR_CRC(ethAddr, crc); -+ -+ crc = GetMirror32(crc); -+ -+ return crc; -+} -+ -+/* ......................................................................... */ -+ -+static void UpdateStatistics(t_Dtsec *p_Dtsec) -+{ -+ uint32_t car1, car2; -+ -+ fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2); -+ -+ if (car1) -+ { -+ if (car1 & CAR1_TR64) -+ p_Dtsec->internalStatistics.tr64 += VAL22BIT; -+ if (car1 & CAR1_TR127) -+ p_Dtsec->internalStatistics.tr127 += VAL22BIT; -+ if (car1 & CAR1_TR255) -+ p_Dtsec->internalStatistics.tr255 += VAL22BIT; -+ if (car1 & CAR1_TR511) -+ p_Dtsec->internalStatistics.tr511 += VAL22BIT; -+ if (car1 & CAR1_TRK1) -+ p_Dtsec->internalStatistics.tr1k += VAL22BIT; -+ if (car1 & CAR1_TRMAX) -+ p_Dtsec->internalStatistics.trmax += VAL22BIT; -+ if (car1 & CAR1_TRMGV) -+ p_Dtsec->internalStatistics.trmgv += VAL22BIT; -+ if (car1 & CAR1_RBYT) -+ p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT; -+ if (car1 & CAR1_RPKT) -+ p_Dtsec->internalStatistics.rpkt += VAL22BIT; -+ if (car1 & CAR1_RMCA) -+ p_Dtsec->internalStatistics.rmca += VAL22BIT; -+ if (car1 & CAR1_RBCA) -+ p_Dtsec->internalStatistics.rbca += VAL22BIT; -+ if (car1 & CAR1_RXPF) -+ p_Dtsec->internalStatistics.rxpf += VAL16BIT; -+ if (car1 & CAR1_RALN) -+ p_Dtsec->internalStatistics.raln += VAL16BIT; -+ if (car1 & CAR1_RFLR) -+ p_Dtsec->internalStatistics.rflr += VAL16BIT; -+ if (car1 & CAR1_RCDE) -+ p_Dtsec->internalStatistics.rcde += VAL16BIT; -+ if (car1 & CAR1_RCSE) -+ p_Dtsec->internalStatistics.rcse += VAL16BIT; -+ if (car1 & CAR1_RUND) -+ p_Dtsec->internalStatistics.rund += VAL16BIT; -+ if (car1 & CAR1_ROVR) -+ p_Dtsec->internalStatistics.rovr += VAL16BIT; -+ if (car1 & CAR1_RFRG) -+ p_Dtsec->internalStatistics.rfrg += VAL16BIT; -+ if (car1 & CAR1_RJBR) -+ p_Dtsec->internalStatistics.rjbr += VAL16BIT; -+ if (car1 & CAR1_RDRP) -+ p_Dtsec->internalStatistics.rdrp += VAL16BIT; -+ } -+ if (car2) -+ { -+ if (car2 & CAR2_TFCS) -+ p_Dtsec->internalStatistics.tfcs += VAL12BIT; -+ if (car2 & CAR2_TBYT) -+ p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT; -+ if (car2 & CAR2_TPKT) -+ p_Dtsec->internalStatistics.tpkt += VAL22BIT; -+ if (car2 & CAR2_TMCA) -+ p_Dtsec->internalStatistics.tmca += VAL22BIT; -+ if (car2 & CAR2_TBCA) -+ p_Dtsec->internalStatistics.tbca += VAL22BIT; -+ if (car2 & CAR2_TXPF) -+ p_Dtsec->internalStatistics.txpf += VAL16BIT; -+ if (car2 & CAR2_TDRP) -+ p_Dtsec->internalStatistics.tdrp += VAL16BIT; -+ } -+} -+ -+/* .............................................................................. */ -+ -+static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0); -+ -+ return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap); -+} -+ -+/* .............................................................................. */ -+ -+static void DtsecIsr(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ uint32_t event; -+ struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap; -+ -+ /* do not handle MDIO events */ -+ event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN))); -+ -+ event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap); -+ -+ fman_dtsec_ack_event(p_DtsecMemMap, event); -+ -+ if (event & DTSEC_IMASK_BREN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX); -+ if (event & DTSEC_IMASK_RXCEN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL); -+ if (event & DTSEC_IMASK_MSROEN) -+ UpdateStatistics(p_Dtsec); -+ if (event & DTSEC_IMASK_GTSCEN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET); -+ if (event & DTSEC_IMASK_BTEN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX); -+ if (event & DTSEC_IMASK_TXCEN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL); -+ if (event & DTSEC_IMASK_TXEEN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR); -+ if (event & DTSEC_IMASK_LCEN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL); -+ if (event & DTSEC_IMASK_CRLEN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT); -+ if (event & DTSEC_IMASK_XFUNEN) -+ { -+#ifdef FM_TX_LOCKUP_ERRATA_DTSEC6 -+ if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2) -+ { -+ uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i; -+ /* a. Write 0x00E0_0C00 to DTSEC_ID */ -+ /* This is a read only regidter */ -+ -+ /* b. Read and save the value of TPKT */ -+ tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt); -+ -+ /* c. Read the register at dTSEC address offset 0x32C */ -+ tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c)); -+ -+ /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */ -+ if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F)) -+ { -+ /* If they are not equal, save the value of this register and wait for at least -+ * MAXFRM*16 ns */ -+ XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1))); -+ } -+ -+ /* e. Read and save TPKT again and read the register at dTSEC address offset -+ 0x32C again*/ -+ tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt); -+ tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c)); -+ -+ /* f. Compare the value of TPKT saved in step b to value read in step e. Also -+ compare bits [9:15] of the register at offset 0x32C saved in step d to the value -+ of bits [9:15] saved in step e. If the two registers values are unchanged, then -+ the transmit portion of the dTSEC controller is locked up and the user should -+ proceed to the recover sequence. */ -+ if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000))) -+ { -+ /* recover sequence */ -+ -+ /* a.Write a 1 to RCTRL[GRS]*/ -+ -+ WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS); -+ -+ /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */ -+ for (i = 0 ; i < 100 ; i++ ) -+ { -+ if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN) -+ break; -+ XX_UDelay(1); -+ } -+ if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN) -+ WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN); -+ else -+ DBG(INFO,("Rx lockup due to dTSEC Tx lockup")); -+ -+ /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/ -+ FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId); -+ -+ /* d.Wait 4 Tx clocks (32 ns) */ -+ XX_UDelay(1); -+ -+ /* e.Write a 0 to bit n of FM_RSTC. */ -+ /* cleared by FMAN */ -+ } -+ } -+#endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */ -+ -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN); -+ } -+ if (event & DTSEC_IMASK_MAGEN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT); -+ if (event & DTSEC_IMASK_GRSCEN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET); -+ if (event & DTSEC_IMASK_TDPEEN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR); -+ if (event & DTSEC_IMASK_RDPEEN) -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR); -+ -+ /* - masked interrupts */ -+ ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN)); -+ ASSERT_COND(!(event & DTSEC_IMASK_IFERREN)); -+} -+ -+static void DtsecMdioIsr(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ uint32_t event; -+ struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap; -+ -+ event = GET_UINT32(p_DtsecMemMap->ievent); -+ /* handle only MDIO events */ -+ event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN); -+ if (event) -+ { -+ event &= GET_UINT32(p_DtsecMemMap->imask); -+ -+ WRITE_UINT32(p_DtsecMemMap->ievent, event); -+ -+ if (event & DTSEC_IMASK_MMRDEN) -+ p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET); -+ if (event & DTSEC_IMASK_MMWREN) -+ p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET); -+ } -+} -+ -+static void Dtsec1588Isr(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ uint32_t event; -+ struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap; -+ -+ if (p_Dtsec->ptpTsuEnabled) -+ { -+ event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap); -+ -+ if (event) -+ { -+ ASSERT_COND(event & TMR_PEVENT_TSRE); -+ p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR); -+ } -+ } -+} -+ -+/* ........................................................................... */ -+ -+static void FreeInitResources(t_Dtsec *p_Dtsec) -+{ -+ if (p_Dtsec->mdioIrq != NO_IRQ) -+ { -+ XX_DisableIntr(p_Dtsec->mdioIrq); -+ XX_FreeIntr(p_Dtsec->mdioIrq); -+ } -+ FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR); -+ FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL); -+ -+ /* release the driver's group hash table */ -+ FreeHashTable(p_Dtsec->p_MulticastAddrHash); -+ p_Dtsec->p_MulticastAddrHash = NULL; -+ -+ /* release the driver's individual hash table */ -+ FreeHashTable(p_Dtsec->p_UnicastAddrHash); -+ p_Dtsec->p_UnicastAddrHash = NULL; -+} -+ -+/* ........................................................................... */ -+ -+static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode) -+{ -+ struct dtsec_regs *p_MemMap; -+ -+ ASSERT_COND(p_Dtsec); -+ -+ p_MemMap = p_Dtsec->p_MemMap; -+ ASSERT_COND(p_MemMap); -+ -+ /* Assert the graceful transmit stop bit */ -+ if (mode & e_COMM_MODE_RX) -+ { -+ fman_dtsec_stop_rx(p_MemMap); -+ -+#ifdef FM_GRS_ERRATA_DTSEC_A002 -+ if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2) -+ XX_UDelay(100); -+#else /* FM_GRS_ERRATA_DTSEC_A002 */ -+#ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 -+ XX_UDelay(10); -+#endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */ -+#endif /* FM_GRS_ERRATA_DTSEC_A002 */ -+ } -+ -+ if (mode & e_COMM_MODE_TX) -+#if defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012) -+ if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2) -+ DBG(INFO, ("GTS not supported due to DTSEC_A004 errata.")); -+#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) ||... */ -+#ifdef FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 -+ DBG(INFO, ("GTS not supported due to DTSEC_A0014 errata.")); -+#else /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */ -+ fman_dtsec_stop_tx(p_MemMap); -+#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */ -+#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) ||... */ -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode) -+{ -+ struct dtsec_regs *p_MemMap; -+ -+ ASSERT_COND(p_Dtsec); -+ p_MemMap = p_Dtsec->p_MemMap; -+ ASSERT_COND(p_MemMap); -+ -+ /* clear the graceful receive stop bit */ -+ if (mode & e_COMM_MODE_TX) -+ fman_dtsec_start_tx(p_MemMap); -+ -+ if (mode & e_COMM_MODE_RX) -+ fman_dtsec_start_rx(p_MemMap); -+ -+ return E_OK; -+} -+ -+ -+/*****************************************************************************/ -+/* dTSEC Configs modification functions */ -+/*****************************************************************************/ -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal) -+{ -+ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ p_Dtsec->p_DtsecDriverParam->loopback = newVal; -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal; -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal; -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal; -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal; -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal; -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ uint32_t bitMask = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR) -+ { -+ GET_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_Dtsec->exceptions |= bitMask; -+ else -+ p_Dtsec->exceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ } -+ else -+ { -+ if (!p_Dtsec->ptpTsuEnabled) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only")); -+ -+ if (enable) -+ p_Dtsec->enTsuErrExeption = TRUE; -+ else -+ p_Dtsec->enTsuErrExeption = FALSE; -+ } -+ -+ return E_OK; -+} -+ -+ -+/*****************************************************************************/ -+/* dTSEC Run Time API functions */ -+/*****************************************************************************/ -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ fman_dtsec_enable(p_Dtsec->p_MemMap, -+ (bool)!!(mode & e_COMM_MODE_RX), -+ (bool)!!(mode & e_COMM_MODE_TX)); -+ -+ GracefulRestart(p_Dtsec, mode); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ GracefulStop(p_Dtsec, mode); -+ -+ fman_dtsec_disable(p_Dtsec->p_MemMap, -+ (bool)!!(mode & e_COMM_MODE_RX), -+ (bool)!!(mode & e_COMM_MODE_TX)); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec, -+ uint8_t priority, -+ uint16_t pauseTime, -+ uint16_t threshTime) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ UNUSED(priority);UNUSED(threshTime); -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+#ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 -+ if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2) -+ if (0 < pauseTime && pauseTime <= 320) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, -+ ("This pause-time value of %d is illegal due to errata dTSEC-A003!" -+ " value should be greater than 320.")); -+#endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */ -+ -+ fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime); -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+/* backward compatibility. will be removed in the future. */ -+static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime) -+{ -+ return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0); -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ bool accept_pause = !en; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ p_Dtsec->ptpTsuEnabled = TRUE; -+ fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ p_Dtsec->ptpTsuEnabled = FALSE; -+ fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ struct dtsec_regs *p_DtsecMemMap; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER); -+ -+ p_DtsecMemMap = p_Dtsec->p_MemMap; -+ -+ if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled")); -+ -+ memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics)); -+ -+ if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS) -+ { -+ p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64) -+ + p_Dtsec->internalStatistics.tr64; -+ p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127) -+ + p_Dtsec->internalStatistics.tr127; -+ p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255) -+ + p_Dtsec->internalStatistics.tr255; -+ p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511) -+ + p_Dtsec->internalStatistics.tr511; -+ p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K) -+ + p_Dtsec->internalStatistics.tr1k; -+ p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX) -+ + p_Dtsec->internalStatistics.trmax; -+ p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV) -+ + p_Dtsec->internalStatistics.trmgv; -+ -+ /* MIB II */ -+ p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT) -+ + p_Dtsec->internalStatistics.rbyt; -+ p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT) -+ + p_Dtsec->internalStatistics.rpkt; -+ p_Statistics->ifInUcastPkts = 0; -+ p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA) -+ + p_Dtsec->internalStatistics.rmca; -+ p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA) -+ + p_Dtsec->internalStatistics.rbca; -+ p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT) -+ + p_Dtsec->internalStatistics.tbyt; -+ p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT) -+ + p_Dtsec->internalStatistics.tpkt; -+ p_Statistics->ifOutUcastPkts = 0; -+ p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA) -+ + p_Dtsec->internalStatistics.tmca; -+ p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA) -+ + p_Dtsec->internalStatistics.tbca; -+ } -+ -+ p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG) -+ + p_Dtsec->internalStatistics.rfrg; -+ p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR) -+ + p_Dtsec->internalStatistics.rjbr; -+ p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP) -+ + p_Dtsec->internalStatistics.rdrp; -+ p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN) -+ + p_Dtsec->internalStatistics.raln; -+ p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND) -+ + p_Dtsec->internalStatistics.rund; -+ p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR) -+ + p_Dtsec->internalStatistics.rovr; -+ p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF) -+ + p_Dtsec->internalStatistics.rxpf; -+ p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF) -+ + p_Dtsec->internalStatistics.txpf; -+ p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents; -+ p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors -+ + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr -+ + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde -+ + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse; -+ -+ p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP) -+ + p_Dtsec->internalStatistics.tdrp; -+ p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */ -+ + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS) -+ + p_Dtsec->internalStatistics.tfcs; -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ /* Initialize MAC Station Address registers (1 & 2) */ -+ /* Station address have to be swapped (big endian to little endian */ -+ p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr); -+ fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr)); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecResetCounters (t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ /* clear HW counters */ -+ fman_dtsec_reset_stat(p_Dtsec->p_MemMap); -+ -+ /* clear SW counters holding carries */ -+ memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics)); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec; -+ uint64_t ethAddr; -+ uint8_t paddrNum; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); -+ -+ if (ethAddr & GROUP_ADDRESS) -+ /* Multicast address has no effect in PADDR */ -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address")); -+ -+ /* Make sure no PADDR contains this address */ -+ for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++) -+ if (p_Dtsec->indAddrRegUsed[paddrNum]) -+ if (p_Dtsec->paddr[paddrNum] == ethAddr) -+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG); -+ -+ /* Find first unused PADDR */ -+ for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++) -+ if (!(p_Dtsec->indAddrRegUsed[paddrNum])) -+ { -+ /* mark this PADDR as used */ -+ p_Dtsec->indAddrRegUsed[paddrNum] = TRUE; -+ /* store address */ -+ p_Dtsec->paddr[paddrNum] = ethAddr; -+ -+ /* put in hardware */ -+ fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(ðAddr), paddrNum); -+ p_Dtsec->numOfIndAddrInRegs++; -+ -+ return E_OK; -+ } -+ -+ /* No free PADDR */ -+ RETURN_ERROR(MAJOR, E_FULL, NO_MSG); -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec; -+ uint64_t ethAddr; -+ uint8_t paddrNum; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); -+ -+ /* Find used PADDR containing this address */ -+ for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++) -+ { -+ if ((p_Dtsec->indAddrRegUsed[paddrNum]) && -+ (p_Dtsec->paddr[paddrNum] == ethAddr)) -+ { -+ /* mark this PADDR as not used */ -+ p_Dtsec->indAddrRegUsed[paddrNum] = FALSE; -+ /* clear in hardware */ -+ fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum); -+ p_Dtsec->numOfIndAddrInRegs--; -+ -+ return E_OK; -+ } -+ } -+ -+ RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG); -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ t_EthHashEntry *p_HashEntry; -+ uint64_t ethAddr; -+ int32_t bucket; -+ uint32_t crc; -+ bool mcast, ghtx; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); -+ -+ ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE); -+ mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE); -+ -+ if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */ -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket")); -+ -+ crc = GetMacAddrHashCode(ethAddr); -+ -+ /* considering the 9 highest order bits in crc H[8:0]: -+ * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register -+ * and H[5:1] (next 5 bits) identify the hash bit -+ * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register -+ * and H[4:0] (next 5 bits) identify the hash bit. -+ * -+ * In bucket index output the low 5 bits identify the hash register bit, -+ * while the higher 4 bits identify the hash register -+ */ -+ -+ if (ghtx) -+ bucket = (int32_t)((crc >> 23) & 0x1ff); -+ else { -+ bucket = (int32_t)((crc >> 24) & 0xff); -+ /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */ -+ if (mcast) -+ bucket += 0x100; -+ } -+ -+ fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE); -+ -+ /* Create element to be added to the driver hash table */ -+ p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry)); -+ p_HashEntry->addr = ethAddr; -+ INIT_LIST(&p_HashEntry->node); -+ -+ if (ethAddr & MAC_GROUP_ADDRESS) -+ /* Group Address */ -+ LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket])); -+ else -+ LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket])); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ t_List *p_Pos; -+ t_EthHashEntry *p_HashEntry = NULL; -+ uint64_t ethAddr; -+ int32_t bucket; -+ uint32_t crc; -+ bool mcast, ghtx; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); -+ -+ ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE); -+ mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE); -+ -+ if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */ -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket")); -+ -+ crc = GetMacAddrHashCode(ethAddr); -+ -+ if (ghtx) -+ bucket = (int32_t)((crc >> 23) & 0x1ff); -+ else { -+ bucket = (int32_t)((crc >> 24) & 0xff); -+ /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */ -+ if (mcast) -+ bucket += 0x100; -+ } -+ -+ if (ethAddr & MAC_GROUP_ADDRESS) -+ { -+ /* Group Address */ -+ LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket])) -+ { -+ p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos); -+ if (p_HashEntry->addr == ethAddr) -+ { -+ LIST_DelAndInit(&p_HashEntry->node); -+ XX_Free(p_HashEntry); -+ break; -+ } -+ } -+ if (LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket])) -+ fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE); -+ } -+ else -+ { -+ /* Individual Address */ -+ LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket])) -+ { -+ p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos); -+ if (p_HashEntry->addr == ethAddr) -+ { -+ LIST_DelAndInit(&p_HashEntry->node); -+ XX_Free(p_HashEntry); -+ break; -+ } -+ } -+ if (LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket])) -+ fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE); -+ } -+ -+ /* address does not exist */ -+ ASSERT_COND(p_HashEntry != NULL); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal); -+ fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ p_Dtsec->statisticsLevel = statisticsLevel; -+ -+ err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap, -+ (enum dtsec_stat_level)statisticsLevel); -+ if (err != E_OK) -+ return err; -+ -+ switch (statisticsLevel) -+ { -+ case (e_FM_MAC_NONE_STATISTICS): -+ p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN; -+ break; -+ case (e_FM_MAC_PARTIAL_STATISTICS): -+ p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN; -+ break; -+ case (e_FM_MAC_FULL_STATISTICS): -+ p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ fman_dtsec_set_wol(p_Dtsec->p_MemMap, en); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ int err; -+ enum enet_interface enet_interface; -+ enum enet_speed enet_speed; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed); -+ enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode); -+ enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode); -+ p_Dtsec->halfDuplex = !fullDuplex; -+ -+ err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex); -+ -+ if (err == -EINVAL) -+ RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode")); -+ -+ return (t_Error)err; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ uint16_t tmpReg16; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16); -+ -+ tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 ); -+ tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1); -+ -+ DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ *macId = p_Dtsec->macId; -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ uint32_t bitMask = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ -+ if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR) -+ { -+ GET_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_Dtsec->exceptions |= bitMask; -+ else -+ p_Dtsec->exceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ if (enable) -+ fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask); -+ else -+ fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask); -+ } -+ else -+ { -+ if (!p_Dtsec->ptpTsuEnabled) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only")); -+ -+ if (enable) -+ { -+ p_Dtsec->enTsuErrExeption = TRUE; -+ fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap); -+ } -+ else -+ { -+ p_Dtsec->enTsuErrExeption = FALSE; -+ fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap); -+ } -+ } -+ -+ return E_OK; -+} -+ -+ -+/*****************************************************************************/ -+/* dTSEC Init & Free API */ -+/*****************************************************************************/ -+ -+/* .............................................................................. */ -+ -+static t_Error DtsecInit(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ struct dtsec_cfg *p_DtsecDriverParam; -+ t_Error err; -+ uint16_t maxFrmLn; -+ enum enet_interface enet_interface; -+ enum enet_speed enet_speed; -+ t_EnetAddr ethAddr; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE); -+ -+ FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo); -+ CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters); -+ -+ p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam; -+ p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on; -+ -+ enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode); -+ enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode); -+ MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr); -+ -+ err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap, -+ p_DtsecDriverParam, -+ enet_interface, -+ enet_speed, -+ (uint8_t*)ethAddr, -+ p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev, -+ p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev, -+ p_Dtsec->exceptions); -+ if (err) -+ { -+ FreeInitResources(p_Dtsec); -+ RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode")); -+ } -+ -+ if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII) -+ { -+ uint16_t tmpReg16; -+ -+ /* Configure the TBI PHY Control Register */ -+ tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET; -+ DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16); -+ -+ tmpReg16 = PHY_TBICON_CLK_SEL; -+ DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16); -+ -+ tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1); -+ DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16); -+ -+ if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX) -+ tmpReg16 = PHY_TBIANA_1000X; -+ else -+ tmpReg16 = PHY_TBIANA_SGMII; -+ DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16); -+ -+ tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1); -+ -+ DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16); -+ } -+ -+ /* Max Frame Length */ -+ maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap); -+ err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, -+ p_Dtsec->fmMacControllerDriver.macId, maxFrmLn); -+ if (err) -+ RETURN_ERROR(MINOR,err, NO_MSG); -+ -+ p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE); -+ if (!p_Dtsec->p_MulticastAddrHash) { -+ FreeInitResources(p_Dtsec); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED")); -+ } -+ -+ p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE); -+ if (!p_Dtsec->p_UnicastAddrHash) -+ { -+ FreeInitResources(p_Dtsec); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED")); -+ } -+ -+ /* register err intr handler for dtsec to FPM (err)*/ -+ FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, -+ e_FM_MOD_1G_MAC, -+ p_Dtsec->macId, -+ e_FM_INTR_TYPE_ERR, -+ DtsecIsr, -+ p_Dtsec); -+ /* register 1588 intr handler for TMR to FPM (normal)*/ -+ FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, -+ e_FM_MOD_1G_MAC, -+ p_Dtsec->macId, -+ e_FM_INTR_TYPE_NORMAL, -+ Dtsec1588Isr, -+ p_Dtsec); -+ /* register normal intr handler for dtsec to main interrupt controller. */ -+ if (p_Dtsec->mdioIrq != NO_IRQ) -+ { -+ XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec); -+ XX_EnableIntr(p_Dtsec->mdioIrq); -+ } -+ -+ XX_Free(p_DtsecDriverParam); -+ p_Dtsec->p_DtsecDriverParam = NULL; -+ -+ err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS); -+ if (err) -+ { -+ FreeInitResources(p_Dtsec); -+ RETURN_ERROR(MAJOR, err, ("Undefined statistics level")); -+ } -+ -+ return E_OK; -+} -+ -+/* ........................................................................... */ -+ -+static t_Error DtsecFree(t_Handle h_Dtsec) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ -+ if (p_Dtsec->p_DtsecDriverParam) -+ { -+ /* Called after config */ -+ XX_Free(p_Dtsec->p_DtsecDriverParam); -+ p_Dtsec->p_DtsecDriverParam = NULL; -+ } -+ else -+ /* Called after init */ -+ FreeInitResources(p_Dtsec); -+ -+ XX_Free(p_Dtsec); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver) -+{ -+ p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit; -+ p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */ -+ -+ p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr = DtsecConfigTbiPhyAddr; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL; -+ -+ p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable; -+ p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable; -+ p_FmMacControllerDriver->f_FM_MAC_Resume = NULL; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous; -+ p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink; -+ p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = DtsecSetWakeOnLan; -+ p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = DtsecRestartAutoneg; -+ -+ p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp; -+ p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause; -+ p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = DtsecSetTxPauseFrames; -+ p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters; -+ p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId; -+ p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion; -+ p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength; -+ -+ p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg; -+ p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg; -+ -+} -+ -+ -+/*****************************************************************************/ -+/* dTSEC Config Main Entry */ -+/*****************************************************************************/ -+ -+/* .............................................................................. */ -+ -+t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam) -+{ -+ t_Dtsec *p_Dtsec; -+ struct dtsec_cfg *p_DtsecDriverParam; -+ uintptr_t baseAddr; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL); -+ -+ baseAddr = p_FmMacParam->baseAddr; -+ -+ /* allocate memory for the UCC GETH data structure. */ -+ p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec)); -+ if (!p_Dtsec) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure")); -+ return NULL; -+ } -+ memset(p_Dtsec, 0, sizeof(t_Dtsec)); -+ InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver); -+ -+ /* allocate memory for the dTSEC driver parameters data structure. */ -+ p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg)); -+ if (!p_DtsecDriverParam) -+ { -+ XX_Free(p_Dtsec); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters")); -+ return NULL; -+ } -+ memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg)); -+ -+ /* Plant parameter structure pointer */ -+ p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam; -+ -+ fman_dtsec_defconfig(p_DtsecDriverParam); -+ -+ p_Dtsec->p_MemMap = (struct dtsec_regs *)UINT_TO_PTR(baseAddr); -+ p_Dtsec->p_MiiMemMap = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET); -+ p_Dtsec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr); -+ p_Dtsec->enetMode = p_FmMacParam->enetMode; -+ p_Dtsec->macId = p_FmMacParam->macId; -+ p_Dtsec->exceptions = DEFAULT_exceptions; -+ p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq; -+ p_Dtsec->f_Exception = p_FmMacParam->f_Exception; -+ p_Dtsec->f_Event = p_FmMacParam->f_Event; -+ p_Dtsec->h_App = p_FmMacParam->h_App; -+ p_Dtsec->ptpTsuEnabled = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en; -+ p_Dtsec->enTsuErrExeption = p_Dtsec->p_DtsecDriverParam->ptp_exception_en; -+ p_Dtsec->tbi_phy_addr = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr; -+ -+ return p_Dtsec; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h -@@ -0,0 +1,228 @@ -+/* -+ * Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File dtsec.h -+ -+ @Description FM dTSEC ... -+*//***************************************************************************/ -+#ifndef __DTSEC_H -+#define __DTSEC_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "list_ext.h" -+#include "enet_ext.h" -+ -+#include "dtsec_mii_acc.h" -+#include "fm_mac.h" -+ -+ -+#define DEFAULT_exceptions \ -+ ((uint32_t)(DTSEC_IMASK_BREN | \ -+ DTSEC_IMASK_RXCEN | \ -+ DTSEC_IMASK_BTEN | \ -+ DTSEC_IMASK_TXCEN | \ -+ DTSEC_IMASK_TXEEN | \ -+ DTSEC_IMASK_ABRTEN | \ -+ DTSEC_IMASK_LCEN | \ -+ DTSEC_IMASK_CRLEN | \ -+ DTSEC_IMASK_XFUNEN | \ -+ DTSEC_IMASK_IFERREN | \ -+ DTSEC_IMASK_MAGEN | \ -+ DTSEC_IMASK_TDPEEN | \ -+ DTSEC_IMASK_RDPEEN)) -+ -+#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \ -+ case e_FM_MAC_EX_1G_BAB_RX: \ -+ bitMask = DTSEC_IMASK_BREN; break; \ -+ case e_FM_MAC_EX_1G_RX_CTL: \ -+ bitMask = DTSEC_IMASK_RXCEN; break; \ -+ case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \ -+ bitMask = DTSEC_IMASK_GTSCEN ; break; \ -+ case e_FM_MAC_EX_1G_BAB_TX: \ -+ bitMask = DTSEC_IMASK_BTEN ; break; \ -+ case e_FM_MAC_EX_1G_TX_CTL: \ -+ bitMask = DTSEC_IMASK_TXCEN ; break; \ -+ case e_FM_MAC_EX_1G_TX_ERR: \ -+ bitMask = DTSEC_IMASK_TXEEN ; break; \ -+ case e_FM_MAC_EX_1G_LATE_COL: \ -+ bitMask = DTSEC_IMASK_LCEN ; break; \ -+ case e_FM_MAC_EX_1G_COL_RET_LMT: \ -+ bitMask = DTSEC_IMASK_CRLEN ; break; \ -+ case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \ -+ bitMask = DTSEC_IMASK_XFUNEN ; break; \ -+ case e_FM_MAC_EX_1G_MAG_PCKT: \ -+ bitMask = DTSEC_IMASK_MAGEN ; break; \ -+ case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \ -+ bitMask = DTSEC_IMASK_MMRDEN; break; \ -+ case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \ -+ bitMask = DTSEC_IMASK_MMWREN ; break; \ -+ case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \ -+ bitMask = DTSEC_IMASK_GRSCEN; break; \ -+ case e_FM_MAC_EX_1G_TX_DATA_ERR: \ -+ bitMask = DTSEC_IMASK_TDPEEN; break; \ -+ case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \ -+ bitMask = DTSEC_IMASK_MSROEN ; break; \ -+ default: bitMask = 0;break;} -+ -+ -+#define MAX_PACKET_ALIGNMENT 31 -+#define MAX_INTER_PACKET_GAP 0x7f -+#define MAX_INTER_PALTERNATE_BEB 0x0f -+#define MAX_RETRANSMISSION 0x0f -+#define MAX_COLLISION_WINDOW 0x03ff -+ -+ -+/********************* From mac ext ******************************************/ -+typedef uint32_t t_ErrorDisable; -+ -+#define ERROR_DISABLE_TRANSMIT 0x00400000 -+#define ERROR_DISABLE_LATE_COLLISION 0x00040000 -+#define ERROR_DISABLE_COLLISION_RETRY_LIMIT 0x00020000 -+#define ERROR_DISABLE_TxFIFO_UNDERRUN 0x00010000 -+#define ERROR_DISABLE_TxABORT 0x00008000 -+#define ERROR_DISABLE_INTERFACE 0x00004000 -+#define ERROR_DISABLE_TxDATA_PARITY 0x00000002 -+#define ERROR_DISABLE_RxDATA_PARITY 0x00000001 -+ -+/*****************************************************************************/ -+#define DTSEC_NUM_OF_PADDRS 15 /* number of pattern match registers (entries) */ -+ -+#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */ -+ -+#define HASH_TABLE_SIZE 256 /* Hash table size (= 32 bits * 8 regs) */ -+ -+#define HASH_TABLE_SIZE 256 /* Hash table size (32 bits * 8 regs) */ -+#define EXTENDED_HASH_TABLE_SIZE 512 /* Extended Hash table size (32 bits * 16 regs) */ -+ -+#define DTSEC_TO_MII_OFFSET 0x1000 /* number of pattern match registers (entries) */ -+ -+#define MAX_PHYS 32 /* maximum number of phys */ -+ -+#define VAL32BIT 0x100000000LL -+#define VAL22BIT 0x00400000 -+#define VAL16BIT 0x00010000 -+#define VAL12BIT 0x00001000 -+ -+/* CAR1/2 bits */ -+#define CAR1_TR64 0x80000000 -+#define CAR1_TR127 0x40000000 -+#define CAR1_TR255 0x20000000 -+#define CAR1_TR511 0x10000000 -+#define CAR1_TRK1 0x08000000 -+#define CAR1_TRMAX 0x04000000 -+#define CAR1_TRMGV 0x02000000 -+ -+#define CAR1_RBYT 0x00010000 -+#define CAR1_RPKT 0x00008000 -+#define CAR1_RMCA 0x00002000 -+#define CAR1_RBCA 0x00001000 -+#define CAR1_RXPF 0x00000400 -+#define CAR1_RALN 0x00000100 -+#define CAR1_RFLR 0x00000080 -+#define CAR1_RCDE 0x00000040 -+#define CAR1_RCSE 0x00000020 -+#define CAR1_RUND 0x00000010 -+#define CAR1_ROVR 0x00000008 -+#define CAR1_RFRG 0x00000004 -+#define CAR1_RJBR 0x00000002 -+#define CAR1_RDRP 0x00000001 -+ -+#define CAR2_TFCS 0x00040000 -+#define CAR2_TBYT 0x00002000 -+#define CAR2_TPKT 0x00001000 -+#define CAR2_TMCA 0x00000800 -+#define CAR2_TBCA 0x00000400 -+#define CAR2_TXPF 0x00000200 -+#define CAR2_TDRP 0x00000001 -+ -+typedef struct t_InternalStatistics -+{ -+ uint64_t tr64; -+ uint64_t tr127; -+ uint64_t tr255; -+ uint64_t tr511; -+ uint64_t tr1k; -+ uint64_t trmax; -+ uint64_t trmgv; -+ uint64_t rfrg; -+ uint64_t rjbr; -+ uint64_t rdrp; -+ uint64_t raln; -+ uint64_t rund; -+ uint64_t rovr; -+ uint64_t rxpf; -+ uint64_t txpf; -+ uint64_t rbyt; -+ uint64_t rpkt; -+ uint64_t rmca; -+ uint64_t rbca; -+ uint64_t rflr; -+ uint64_t rcde; -+ uint64_t rcse; -+ uint64_t tbyt; -+ uint64_t tpkt; -+ uint64_t tmca; -+ uint64_t tbca; -+ uint64_t tdrp; -+ uint64_t tfcs; -+} t_InternalStatistics; -+ -+typedef struct { -+ t_FmMacControllerDriver fmMacControllerDriver; -+ t_Handle h_App; /**< Handle to the upper layer application */ -+ struct dtsec_regs *p_MemMap; /**< pointer to dTSEC memory mapped registers. */ -+ struct dtsec_mii_reg *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */ -+ uint64_t addr; /**< MAC address of device; */ -+ e_EnetMode enetMode; /**< Ethernet physical interface */ -+ t_FmMacExceptionCallback *f_Exception; -+ int mdioIrq; -+ t_FmMacExceptionCallback *f_Event; -+ bool indAddrRegUsed[DTSEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */ -+ uint64_t paddr[DTSEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */ -+ uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */ -+ bool halfDuplex; -+ t_InternalStatistics internalStatistics; -+ t_EthHash *p_MulticastAddrHash; /* pointer to driver's global address hash table */ -+ t_EthHash *p_UnicastAddrHash; /* pointer to driver's individual address hash table */ -+ uint8_t macId; -+ uint8_t tbi_phy_addr; -+ uint32_t exceptions; -+ bool ptpTsuEnabled; -+ bool enTsuErrExeption; -+ e_FmMacStatisticsLevel statisticsLevel; -+ struct dtsec_cfg *p_DtsecDriverParam; -+} t_Dtsec; -+ -+ -+#endif /* __DTSEC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c -@@ -0,0 +1,97 @@ -+/* -+ * Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File dtsec_mii_acc.c -+ -+ @Description FM dtsec MII register access MAC ... -+*//***************************************************************************/ -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "fm_mac.h" -+#include "dtsec.h" -+#include "fsl_fman_dtsec_mii_acc.h" -+ -+ -+/*****************************************************************************/ -+t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t data) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ struct dtsec_mii_reg *miiregs; -+ uint16_t dtsec_freq; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE); -+ -+ dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1); -+ miiregs = p_Dtsec->p_MiiMemMap; -+ -+ err = (t_Error)fman_dtsec_mii_write_reg(miiregs, phyAddr, reg, data, dtsec_freq); -+ -+ return err; -+} -+ -+/*****************************************************************************/ -+t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t *p_Data) -+{ -+ t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec; -+ struct dtsec_mii_reg *miiregs; -+ uint16_t dtsec_freq; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE); -+ -+ dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1); -+ miiregs = p_Dtsec->p_MiiMemMap; -+ -+ err = fman_dtsec_mii_read_reg(miiregs, phyAddr, reg, p_Data, dtsec_freq); -+ -+ if (*p_Data == 0xffff) -+ RETURN_ERROR(MINOR, E_NO_DEVICE, -+ ("Read wrong data (0xffff): phyAddr 0x%x, reg 0x%x", -+ phyAddr, reg)); -+ if (err) -+ RETURN_ERROR(MINOR, (t_Error)err, NO_MSG); -+ -+ return E_OK; -+} -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h -@@ -0,0 +1,42 @@ -+/* -+ * Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __DTSEC_MII_ACC_H -+#define __DTSEC_MII_ACC_H -+ -+#include "std_ext.h" -+ -+ -+t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data); -+t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data); -+ -+#endif /* __DTSEC_MII_ACC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c -@@ -0,0 +1,658 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_mac.c -+ -+ @Description FM MAC ... -+*//***************************************************************************/ -+#include "std_ext.h" -+#include "string_ext.h" -+#include "sprint_ext.h" -+#include "error_ext.h" -+#include "fm_ext.h" -+ -+#include "fm_common.h" -+#include "fm_mac.h" -+ -+ -+/* ......................................................................... */ -+ -+t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver; -+ uint16_t fmClkFreq; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, NULL); -+ -+ fmClkFreq = FmGetClockFreq(p_FmMacParam->h_Fm); -+ if (fmClkFreq == 0) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!")); -+ return NULL; -+ } -+ -+#if (DPAA_VERSION == 10) -+ if (ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000) -+ p_FmMacControllerDriver = (t_FmMacControllerDriver *)DTSEC_Config(p_FmMacParam); -+ else -+#if FM_MAX_NUM_OF_10G_MACS > 0 -+ p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam); -+#else -+ p_FmMacControllerDriver = NULL; -+#endif /* FM_MAX_NUM_OF_10G_MACS > 0 */ -+#else -+ p_FmMacControllerDriver = (t_FmMacControllerDriver *)MEMAC_Config(p_FmMacParam); -+#endif /* (DPAA_VERSION == 10) */ -+ -+ if (!p_FmMacControllerDriver) -+ return NULL; -+ -+ p_FmMacControllerDriver->h_Fm = p_FmMacParam->h_Fm; -+ p_FmMacControllerDriver->enetMode = p_FmMacParam->enetMode; -+ p_FmMacControllerDriver->macId = p_FmMacParam->macId; -+ p_FmMacControllerDriver->resetOnInit = DEFAULT_resetOnInit; -+ -+ p_FmMacControllerDriver->clkFreq = fmClkFreq; -+ -+ return (t_Handle)p_FmMacControllerDriver; -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_Init (t_Handle h_FmMac) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->resetOnInit && -+ !p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit && -+ (FmResetMac(p_FmMacControllerDriver->h_Fm, -+ ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ? -+ e_FM_MAC_10G : e_FM_MAC_1G), -+ p_FmMacControllerDriver->macId) != E_OK)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't reset MAC!")); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_Init) -+ return p_FmMacControllerDriver->f_FM_MAC_Init(h_FmMac); -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_Free (t_Handle h_FmMac) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_Free) -+ return p_FmMacControllerDriver->f_FM_MAC_Free(h_FmMac); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit) -+ return p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit(h_FmMac, enable); -+ -+ p_FmMacControllerDriver->resetOnInit = enable; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback) -+ return p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback(h_FmMac, newVal); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength) -+ return p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength(h_FmMac, newVal); -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigWan) -+ return p_FmMacControllerDriver->f_FM_MAC_ConfigWan(h_FmMac, flag); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc) -+ return p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc(h_FmMac, newVal); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex) -+ return p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex(h_FmMac,newVal); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ConfigTbiPhyAddr (t_Handle h_FmMac, uint8_t newVal) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr) -+ return p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr(h_FmMac,newVal); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool newVal) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck) -+ return p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck(h_FmMac,newVal); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigException) -+ return p_FmMacControllerDriver->f_FM_MAC_ConfigException(h_FmMac, ex, enable); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround) -+ return p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround(h_FmMac); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ -+ -+/*****************************************************************************/ -+/* Run Time Control */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_Enable) -+ return p_FmMacControllerDriver->f_FM_MAC_Enable(h_FmMac, mode); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_Disable) -+ return p_FmMacControllerDriver->f_FM_MAC_Disable(h_FmMac, mode); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MAC_Resume (t_Handle h_FmMac) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_Resume) -+ return p_FmMacControllerDriver->f_FM_MAC_Resume(h_FmMac); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp) -+ return p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp(h_FmMac); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_Disable1588TimeStamp (t_Handle h_FmMac) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp) -+ return p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp(h_FmMac); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac, -+ uint16_t pauseTime) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames) -+ return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac, -+ pauseTime); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac, -+ uint8_t priority, -+ uint16_t pauseTime, -+ uint16_t threshTime) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames) -+ return p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames(h_FmMac, -+ priority, -+ pauseTime, -+ threshTime); -+ -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames) -+ return p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames(h_FmMac, en); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_SetWakeOnLan (t_Handle h_FmMac, bool en) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan) -+ return p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan(h_FmMac, en); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ResetCounters (t_Handle h_FmMac) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ResetCounters) -+ return p_FmMacControllerDriver->f_FM_MAC_ResetCounters(h_FmMac); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_SetException) -+ return p_FmMacControllerDriver->f_FM_MAC_SetException(h_FmMac, ex, enable); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_SetStatistics) -+ return p_FmMacControllerDriver->f_FM_MAC_SetStatistics(h_FmMac, statisticsLevel); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_GetStatistics) -+ return p_FmMacControllerDriver->f_FM_MAC_GetStatistics(h_FmMac, p_Statistics); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr) -+ return p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr(h_FmMac, p_EnetAddr); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr) -+ return p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr(h_FmMac, p_EnetAddr); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr) -+ return p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr(h_FmMac, p_EnetAddr); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr) -+ return p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr(h_FmMac, p_EnetAddr); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr) -+ return p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr(h_FmMac, p_EnetAddr); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_GetVersion) -+ return p_FmMacControllerDriver->f_FM_MAC_GetVersion(h_FmMac, macVresion); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+ -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_GetId) -+ return p_FmMacControllerDriver->f_FM_MAC_GetId(h_FmMac, macId); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous) -+ return p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous(h_FmMac, newVal); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_AdjustLink) -+ return p_FmMacControllerDriver->f_FM_MAC_AdjustLink(h_FmMac, speed, fullDuplex); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg) -+ return p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg(h_FmMac); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg) -+ return p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg(h_FmMac, phyAddr, reg, data); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg) -+ return p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg(h_FmMac, phyAddr, reg, p_Data); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+uint16_t FM_MAC_GetMaxFrameLength(t_Handle h_FmMac) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmMacControllerDriver, E_INVALID_HANDLE, 0); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength) -+ return p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength(h_FmMac); -+ -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+ return 0; -+} -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+/*****************************************************************************/ -+t_Error FM_MAC_DumpRegs(t_Handle h_FmMac) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_DumpRegs) -+ return p_FmMacControllerDriver->f_FM_MAC_DumpRegs(h_FmMac); -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h -@@ -0,0 +1,225 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_mac.h -+ -+ @Description FM MAC ... -+*//***************************************************************************/ -+#ifndef __FM_MAC_H -+#define __FM_MAC_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "list_ext.h" -+#include "fm_mac_ext.h" -+#include "fm_common.h" -+ -+ -+#define __ERR_MODULE__ MODULE_FM_MAC -+ -+/**************************************************************************//** -+ @Description defaults -+*//***************************************************************************/ -+ -+ -+#define DEFAULT_halfDuplex FALSE -+#define DEFAULT_padAndCrcEnable TRUE -+#define DEFAULT_resetOnInit FALSE -+ -+ -+typedef struct { -+ uint64_t addr; /* Ethernet Address */ -+ t_List node; -+} t_EthHashEntry; -+#define ETH_HASH_ENTRY_OBJ(ptr) LIST_OBJECT(ptr, t_EthHashEntry, node) -+ -+typedef struct { -+ uint16_t size; -+ t_List *p_Lsts; -+} t_EthHash; -+ -+typedef struct { -+ t_Error (*f_FM_MAC_Init) (t_Handle h_FmMac); -+ t_Error (*f_FM_MAC_Free) (t_Handle h_FmMac); -+ -+ t_Error (*f_FM_MAC_SetStatistics) (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel); -+ t_Error (*f_FM_MAC_ConfigLoopback) (t_Handle h_FmMac, bool newVal); -+ t_Error (*f_FM_MAC_ConfigMaxFrameLength) (t_Handle h_FmMac, uint16_t newVal); -+ t_Error (*f_FM_MAC_ConfigWan) (t_Handle h_FmMac, bool flag); -+ t_Error (*f_FM_MAC_ConfigPadAndCrc) (t_Handle h_FmMac, bool newVal); -+ t_Error (*f_FM_MAC_ConfigHalfDuplex) (t_Handle h_FmMac, bool newVal); -+ t_Error (*f_FM_MAC_ConfigLengthCheck) (t_Handle h_FmMac, bool newVal); -+ t_Error (*f_FM_MAC_ConfigTbiPhyAddr) (t_Handle h_FmMac, uint8_t newVal); -+ t_Error (*f_FM_MAC_ConfigException) (t_Handle h_FmMac, e_FmMacExceptions, bool enable); -+ t_Error (*f_FM_MAC_ConfigResetOnInit) (t_Handle h_FmMac, bool enable); -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+ t_Error (*f_FM_MAC_ConfigSkipFman11Workaround) (t_Handle h_FmMac); -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ -+ t_Error (*f_FM_MAC_SetException) (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable); -+ -+ t_Error (*f_FM_MAC_Enable) (t_Handle h_FmMac, e_CommMode mode); -+ t_Error (*f_FM_MAC_Disable) (t_Handle h_FmMac, e_CommMode mode); -+ t_Error (*f_FM_MAC_Resume) (t_Handle h_FmMac); -+ t_Error (*f_FM_MAC_Enable1588TimeStamp) (t_Handle h_FmMac); -+ t_Error (*f_FM_MAC_Disable1588TimeStamp) (t_Handle h_FmMac); -+ t_Error (*f_FM_MAC_Reset) (t_Handle h_FmMac, bool wait); -+ -+ t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac, -+ uint16_t pauseTime); -+ t_Error (*f_FM_MAC_SetTxPauseFrames) (t_Handle h_FmMac, -+ uint8_t priority, -+ uint16_t pauseTime, -+ uint16_t threshTime); -+ t_Error (*f_FM_MAC_SetRxIgnorePauseFrames) (t_Handle h_FmMac, bool en); -+ -+ t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac); -+ t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics); -+ -+ t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); -+ t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); -+ t_Error (*f_FM_MAC_RemoveHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); -+ t_Error (*f_FM_MAC_AddExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); -+ t_Error (*f_FM_MAC_RemovelExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); -+ -+ t_Error (*f_FM_MAC_SetPromiscuous) (t_Handle h_FmMac, bool newVal); -+ t_Error (*f_FM_MAC_AdjustLink) (t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex); -+ t_Error (*f_FM_MAC_RestartAutoneg) (t_Handle h_FmMac); -+ -+ t_Error (*f_FM_MAC_SetWakeOnLan) (t_Handle h_FmMac, bool en); -+ -+ t_Error (*f_FM_MAC_GetId) (t_Handle h_FmMac, uint32_t *macId); -+ -+ t_Error (*f_FM_MAC_GetVersion) (t_Handle h_FmMac, uint32_t *macVersion); -+ -+ uint16_t (*f_FM_MAC_GetMaxFrameLength) (t_Handle h_FmMac); -+ -+ t_Error (*f_FM_MAC_MII_WritePhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data); -+ t_Error (*f_FM_MAC_MII_ReadPhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data); -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_Error (*f_FM_MAC_DumpRegs) (t_Handle h_FmMac); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ t_Handle h_Fm; -+ t_FmRevisionInfo fmRevInfo; -+ e_EnetMode enetMode; -+ uint8_t macId; -+ bool resetOnInit; -+ uint16_t clkFreq; -+} t_FmMacControllerDriver; -+ -+ -+#if (DPAA_VERSION == 10) -+t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam); -+t_Handle TGEC_Config(t_FmMacParams *p_FmMacParams); -+#else -+t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam); -+#endif /* (DPAA_VERSION == 10) */ -+uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac); -+ -+ -+/* ........................................................................... */ -+ -+static __inline__ t_EthHashEntry *DequeueAddrFromHashEntry(t_List *p_AddrLst) -+{ -+ t_EthHashEntry *p_HashEntry = NULL; -+ if (!LIST_IsEmpty(p_AddrLst)) -+ { -+ p_HashEntry = ETH_HASH_ENTRY_OBJ(p_AddrLst->p_Next); -+ LIST_DelAndInit(&p_HashEntry->node); -+ } -+ return p_HashEntry; -+} -+ -+/* ........................................................................... */ -+ -+static __inline__ void FreeHashTable(t_EthHash *p_Hash) -+{ -+ t_EthHashEntry *p_HashEntry; -+ int i = 0; -+ -+ if (p_Hash) -+ { -+ if (p_Hash->p_Lsts) -+ { -+ for (i=0; isize; i++) -+ { -+ p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]); -+ while (p_HashEntry) -+ { -+ XX_Free(p_HashEntry); -+ p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]); -+ } -+ } -+ -+ XX_Free(p_Hash->p_Lsts); -+ } -+ -+ XX_Free(p_Hash); -+ } -+} -+ -+/* ........................................................................... */ -+ -+static __inline__ t_EthHash * AllocHashTable(uint16_t size) -+{ -+ uint32_t i; -+ t_EthHash *p_Hash; -+ -+ /* Allocate address hash table */ -+ p_Hash = (t_EthHash *)XX_Malloc(sizeof(t_EthHash)); -+ if (!p_Hash) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table")); -+ return NULL; -+ } -+ p_Hash->size = size; -+ -+ p_Hash->p_Lsts = (t_List *)XX_Malloc(p_Hash->size*sizeof(t_List)); -+ if (!p_Hash->p_Lsts) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table")); -+ XX_Free(p_Hash); -+ return NULL; -+ } -+ -+ for (i=0 ; isize; i++) -+ INIT_LIST(&p_Hash->p_Lsts[i]); -+ -+ return p_Hash; -+} -+ -+ -+#endif /* __FM_MAC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c -@@ -0,0 +1,119 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#include "fman_crc32.h" -+#include "common/general.h" -+ -+ -+/* precomputed CRC values for address hashing */ -+static const uint32_t crc_tbl[256] = { -+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, -+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, -+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, -+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, -+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, -+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, -+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, -+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, -+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, -+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, -+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, -+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, -+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, -+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, -+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, -+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, -+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, -+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, -+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, -+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, -+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, -+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, -+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, -+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, -+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, -+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, -+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, -+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, -+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, -+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, -+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, -+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, -+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, -+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, -+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, -+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, -+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, -+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, -+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, -+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, -+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, -+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, -+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -+}; -+ -+/* Get the mirrored value of a byte size number. (0x11010011 --> 0x11001011) */ -+static inline uint8_t get_mirror8(uint8_t n) -+{ -+ uint8_t mirror[16] = { -+ 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e, -+ 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f -+ }; -+ return (uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4]))); -+} -+ -+static inline uint32_t get_mirror32(uint32_t n) -+{ -+ return ((uint32_t)get_mirror8((uint8_t)(n))<<24) | -+ ((uint32_t)get_mirror8((uint8_t)(n>>8))<<16) | -+ ((uint32_t)get_mirror8((uint8_t)(n>>16))<<8) | -+ ((uint32_t)get_mirror8((uint8_t)(n>>24))); -+} -+ -+uint32_t get_mac_addr_crc(uint64_t _addr) -+{ -+ uint32_t i; -+ uint8_t data; -+ uint32_t crc; -+ -+ /* CRC calculation */ -+ crc = 0xffffffff; -+ for (i = 0; i < 6; i++) { -+ data = (uint8_t)(_addr >> ((5-i)*8)); -+ crc = crc ^ data; -+ crc = crc_tbl[crc&0xff] ^ (crc>>8); -+ } -+ -+ crc = get_mirror32(crc); -+ return crc; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h -@@ -0,0 +1,43 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#ifndef __FMAN_CRC32_H -+#define __FMAN_CRC32_H -+ -+#include "common/general.h" -+ -+ -+uint32_t get_mac_addr_crc(uint64_t _addr); -+ -+ -+#endif /* __FMAN_CRC32_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c -@@ -0,0 +1,845 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#include "fsl_fman_dtsec.h" -+ -+ -+void fman_dtsec_stop_rx(struct dtsec_regs *regs) -+{ -+ /* Assert the graceful stop bit */ -+ iowrite32be(ioread32be(®s->rctrl) | RCTRL_GRS, ®s->rctrl); -+} -+ -+void fman_dtsec_stop_tx(struct dtsec_regs *regs) -+{ -+ /* Assert the graceful stop bit */ -+ iowrite32be(ioread32be(®s->tctrl) | DTSEC_TCTRL_GTS, ®s->tctrl); -+} -+ -+void fman_dtsec_start_tx(struct dtsec_regs *regs) -+{ -+ /* clear the graceful stop bit */ -+ iowrite32be(ioread32be(®s->tctrl) & ~DTSEC_TCTRL_GTS, ®s->tctrl); -+} -+ -+void fman_dtsec_start_rx(struct dtsec_regs *regs) -+{ -+ /* clear the graceful stop bit */ -+ iowrite32be(ioread32be(®s->rctrl) & ~RCTRL_GRS, ®s->rctrl); -+} -+ -+void fman_dtsec_defconfig(struct dtsec_cfg *cfg) -+{ -+ cfg->halfdup_on = DEFAULT_HALFDUP_ON; -+ cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT; -+ cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW; -+ cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER; -+ cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF; -+ cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF; -+ cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL; -+ cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN; -+ cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST; -+ cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM; -+ cfg->rx_len_check = DEFAULT_RX_LEN_CHECK; -+ cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC; -+ cfg->tx_crc = DEFAULT_TX_CRC; -+ cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC; -+ cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME; -+ cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/ -+ cfg->rx_prepend = DEFAULT_RX_PREPEND; -+ cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN; -+ cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN; -+ cfg->preamble_len = DEFAULT_PREAMBLE_LEN; -+ cfg->rx_preamble = DEFAULT_RX_PREAMBLE; -+ cfg->tx_preamble = DEFAULT_TX_PREAMBLE; -+ cfg->loopback = DEFAULT_LOOPBACK; -+ cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN; -+ cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN; -+ cfg->rx_flow = DEFAULT_RX_FLOW; -+ cfg->tx_flow = DEFAULT_TX_FLOW; -+ cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD; -+ cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD; -+ cfg->rx_promisc = DEFAULT_RX_PROMISC; -+ cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1; -+ cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2; -+ cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT; -+ cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG; -+ cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME; -+ cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR; -+ cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN; -+} -+ -+int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg, -+ enum enet_interface iface_mode, -+ enum enet_speed iface_speed, -+ uint8_t *macaddr, -+ uint8_t fm_rev_maj, -+ uint8_t fm_rev_min, -+ uint32_t exception_mask) -+{ -+ bool is_rgmii = FALSE; -+ bool is_sgmii = FALSE; -+ bool is_qsgmii = FALSE; -+ int i; -+ uint32_t tmp; -+ -+UNUSED(fm_rev_maj);UNUSED(fm_rev_min); -+ -+ /* let's start with a soft reset */ -+ iowrite32be(MACCFG1_SOFT_RESET, ®s->maccfg1); -+ iowrite32be(0, ®s->maccfg1); -+ -+ /*************dtsec_id2******************/ -+ tmp = ioread32be(®s->tsec_id2); -+ -+ /* check RGMII support */ -+ if (iface_mode == E_ENET_IF_RGMII || -+ iface_mode == E_ENET_IF_RMII) -+ if (tmp & DTSEC_ID2_INT_REDUCED_OFF) -+ return -EINVAL; -+ -+ if (iface_mode == E_ENET_IF_SGMII || -+ iface_mode == E_ENET_IF_MII) -+ if (tmp & DTSEC_ID2_INT_REDUCED_OFF) -+ return -EINVAL; -+ -+ /***************ECNTRL************************/ -+ -+ is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE); -+ is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE); -+ is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE); -+ -+ tmp = 0; -+ if (is_rgmii || iface_mode == E_ENET_IF_GMII) -+ tmp |= DTSEC_ECNTRL_GMIIM; -+ if (is_sgmii) -+ tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM); -+ if (is_qsgmii) -+ tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM | -+ DTSEC_ECNTRL_QSGMIIM); -+ if (is_rgmii) -+ tmp |= DTSEC_ECNTRL_RPM; -+ if (iface_speed == E_ENET_SPEED_100) -+ tmp |= DTSEC_ECNTRL_R100M; -+ -+ iowrite32be(tmp, ®s->ecntrl); -+ /***************ECNTRL************************/ -+ -+ /***************TCTRL************************/ -+ tmp = 0; -+ if (cfg->halfdup_on) -+ tmp |= DTSEC_TCTRL_THDF; -+ if (cfg->tx_time_stamp_en) -+ tmp |= DTSEC_TCTRL_TTSE; -+ -+ iowrite32be(tmp, ®s->tctrl); -+ -+ /***************TCTRL************************/ -+ -+ /***************PTV************************/ -+ tmp = 0; -+ -+#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 -+ if ((fm_rev_maj == 1) && (fm_rev_min == 0)) -+ cfg->tx_pause_time += 2; -+#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */ -+ -+ if (cfg->tx_pause_time) -+ tmp |= cfg->tx_pause_time; -+ if (cfg->tx_pause_time_extd) -+ tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST; -+ iowrite32be(tmp, ®s->ptv); -+ -+ /***************RCTRL************************/ -+ tmp = 0; -+ tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16; -+ if (cfg->rx_ctrl_acc) -+ tmp |= RCTRL_CFA; -+ if (cfg->rx_group_hash_exd) -+ tmp |= RCTRL_GHTX; -+ if (cfg->rx_time_stamp_en) -+ tmp |= RCTRL_RTSE; -+ if (cfg->rx_drop_bcast) -+ tmp |= RCTRL_BC_REJ; -+ if (cfg->rx_short_frm) -+ tmp |= RCTRL_RSF; -+ if (cfg->rx_promisc) -+ tmp |= RCTRL_PROM; -+ -+ iowrite32be(tmp, ®s->rctrl); -+ /***************RCTRL************************/ -+ -+ /* -+ * Assign a Phy Address to the TBI (TBIPA). -+ * Done also in cases where TBI is not selected to avoid conflict with -+ * the external PHY's Physical address -+ */ -+ iowrite32be(cfg->tbipa, ®s->tbipa); -+ -+ /***************TMR_CTL************************/ -+ iowrite32be(0, ®s->tmr_ctrl); -+ -+ if (cfg->ptp_tsu_en) { -+ tmp = 0; -+ tmp |= TMR_PEVENT_TSRE; -+ iowrite32be(tmp, ®s->tmr_pevent); -+ -+ if (cfg->ptp_exception_en) { -+ tmp = 0; -+ tmp |= TMR_PEMASK_TSREEN; -+ iowrite32be(tmp, ®s->tmr_pemask); -+ } -+ } -+ -+ /***************MACCFG1***********************/ -+ tmp = 0; -+ if (cfg->loopback) -+ tmp |= MACCFG1_LOOPBACK; -+ if (cfg->rx_flow) -+ tmp |= MACCFG1_RX_FLOW; -+ if (cfg->tx_flow) -+ tmp |= MACCFG1_TX_FLOW; -+ iowrite32be(tmp, ®s->maccfg1); -+ -+ /***************MACCFG1***********************/ -+ -+ /***************MACCFG2***********************/ -+ tmp = 0; -+ -+ if (iface_speed < E_ENET_SPEED_1000) -+ tmp |= MACCFG2_NIBBLE_MODE; -+ else if (iface_speed == E_ENET_SPEED_1000) -+ tmp |= MACCFG2_BYTE_MODE; -+ -+ tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f) -+ << PREAMBLE_LENGTH_SHIFT; -+ -+ if (cfg->rx_preamble) -+ tmp |= MACCFG2_PRE_AM_Rx_EN; -+ if (cfg->tx_preamble) -+ tmp |= MACCFG2_PRE_AM_Tx_EN; -+ if (cfg->rx_len_check) -+ tmp |= MACCFG2_LENGTH_CHECK; -+ if (cfg->tx_pad_crc) -+ tmp |= MACCFG2_PAD_CRC_EN; -+ if (cfg->tx_crc) -+ tmp |= MACCFG2_CRC_EN; -+ if (!cfg->halfdup_on) -+ tmp |= MACCFG2_FULL_DUPLEX; -+ iowrite32be(tmp, ®s->maccfg2); -+ -+ /***************MACCFG2***********************/ -+ -+ /***************IPGIFG************************/ -+ tmp = (((cfg->non_back_to_back_ipg1 << -+ IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT) -+ & IPGIFG_NON_BACK_TO_BACK_IPG_1) -+ | ((cfg->non_back_to_back_ipg2 << -+ IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT) -+ & IPGIFG_NON_BACK_TO_BACK_IPG_2) -+ | ((cfg->min_ifg_enforcement << -+ IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT) -+ & IPGIFG_MIN_IFG_ENFORCEMENT) -+ | (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG)); -+ iowrite32be(tmp, ®s->ipgifg); -+ -+ /***************IPGIFG************************/ -+ -+ /***************HAFDUP************************/ -+ tmp = 0; -+ -+ if (cfg->halfdup_alt_backoff_en) -+ tmp = (uint32_t)(HAFDUP_ALT_BEB | -+ ((cfg->halfdup_alt_backoff_val & 0x0000000f) -+ << HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT)); -+ if (cfg->halfdup_bp_no_backoff) -+ tmp |= HAFDUP_BP_NO_BACKOFF; -+ if (cfg->halfdup_no_backoff) -+ tmp |= HAFDUP_NO_BACKOFF; -+ if (cfg->halfdup_excess_defer) -+ tmp |= HAFDUP_EXCESS_DEFER; -+ tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT) -+ & HAFDUP_RETRANSMISSION_MAX); -+ tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW); -+ -+ iowrite32be(tmp, ®s->hafdup); -+ /***************HAFDUP************************/ -+ -+ /***************MAXFRM************************/ -+ /* Initialize MAXFRM */ -+ iowrite32be(cfg->maximum_frame, ®s->maxfrm); -+ -+ /***************MAXFRM************************/ -+ -+ /***************CAM1************************/ -+ iowrite32be(0xffffffff, ®s->cam1); -+ iowrite32be(0xffffffff, ®s->cam2); -+ -+ /***************IMASK************************/ -+ iowrite32be(exception_mask, ®s->imask); -+ /***************IMASK************************/ -+ -+ /***************IEVENT************************/ -+ iowrite32be(0xffffffff, ®s->ievent); -+ -+ /***************MACSTNADDR1/2*****************/ -+ -+ tmp = (uint32_t)((macaddr[5] << 24) | -+ (macaddr[4] << 16) | -+ (macaddr[3] << 8) | -+ macaddr[2]); -+ iowrite32be(tmp, ®s->macstnaddr1); -+ -+ tmp = (uint32_t)((macaddr[1] << 24) | -+ (macaddr[0] << 16)); -+ iowrite32be(tmp, ®s->macstnaddr2); -+ -+ /***************MACSTNADDR1/2*****************/ -+ -+ /*****************HASH************************/ -+ for (i = 0; i < NUM_OF_HASH_REGS ; i++) { -+ /* Initialize IADDRx */ -+ iowrite32be(0, ®s->igaddr[i]); -+ /* Initialize GADDRx */ -+ iowrite32be(0, ®s->gaddr[i]); -+ } -+ -+ fman_dtsec_reset_stat(regs); -+ -+ return 0; -+} -+ -+uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs) -+{ -+ return (uint16_t)ioread32be(®s->maxfrm); -+} -+ -+void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length) -+{ -+ iowrite32be(length, ®s->maxfrm); -+} -+ -+void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr) -+{ -+ uint32_t tmp; -+ -+ tmp = (uint32_t)((adr[5] << 24) | -+ (adr[4] << 16) | -+ (adr[3] << 8) | -+ adr[2]); -+ iowrite32be(tmp, ®s->macstnaddr1); -+ -+ tmp = (uint32_t)((adr[1] << 24) | -+ (adr[0] << 16)); -+ iowrite32be(tmp, ®s->macstnaddr2); -+} -+ -+void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr) -+{ -+ uint32_t tmp1, tmp2; -+ -+ tmp1 = ioread32be(®s->macstnaddr1); -+ tmp2 = ioread32be(®s->macstnaddr2); -+ -+ macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16); -+ macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24); -+ macaddr[2] = (uint8_t)(tmp1 & 0x000000ff); -+ macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8); -+ macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16); -+ macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24); -+} -+ -+void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx) -+{ -+ int32_t bucket; -+ if (ghtx) -+ bucket = (int32_t)((crc >> 23) & 0x1ff); -+ else { -+ bucket = (int32_t)((crc >> 24) & 0xff); -+ /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */ -+ if (mcast) -+ bucket += 0x100; -+ } -+ fman_dtsec_set_bucket(regs, bucket, TRUE); -+} -+ -+void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable) -+{ -+ int reg_idx = (bucket >> 5) & 0xf; -+ int bit_idx = bucket & 0x1f; -+ uint32_t bit_mask = 0x80000000 >> bit_idx; -+ uint32_t *reg; -+ -+ if (reg_idx > 7) -+ reg = ®s->gaddr[reg_idx-8]; -+ else -+ reg = ®s->igaddr[reg_idx]; -+ -+ if (enable) -+ iowrite32be(ioread32be(reg) | bit_mask, reg); -+ else -+ iowrite32be(ioread32be(reg) & (~bit_mask), reg); -+} -+ -+void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast) -+{ -+ int i; -+ bool ghtx; -+ -+ ghtx = (bool)((ioread32be(®s->rctrl) & RCTRL_GHTX) ? TRUE : FALSE); -+ -+ if (ucast || (ghtx && mcast)) { -+ for (i = 0; i < NUM_OF_HASH_REGS; i++) -+ iowrite32be(0, ®s->igaddr[i]); -+ } -+ if (mcast) { -+ for (i = 0; i < NUM_OF_HASH_REGS; i++) -+ iowrite32be(0, ®s->gaddr[i]); -+ } -+} -+ -+int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs, -+ uint8_t addr) -+{ -+ if (addr > 0 && addr < 32) -+ iowrite32be(addr, ®s->tbipa); -+ else -+ return -EINVAL; -+ -+ return 0; -+} -+ -+void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->maccfg2); -+ if (en) -+ tmp |= MACCFG2_MAGIC_PACKET_EN; -+ else -+ tmp &= ~MACCFG2_MAGIC_PACKET_EN; -+ iowrite32be(tmp, ®s->maccfg2); -+} -+ -+int fman_dtsec_adjust_link(struct dtsec_regs *regs, -+ enum enet_interface iface_mode, -+ enum enet_speed speed, bool full_dx) -+{ -+ uint32_t tmp; -+ -+ UNUSED(iface_mode); -+ -+ if ((speed == E_ENET_SPEED_1000) && !full_dx) -+ return -EINVAL; -+ -+ tmp = ioread32be(®s->maccfg2); -+ if (!full_dx) -+ tmp &= ~MACCFG2_FULL_DUPLEX; -+ else -+ tmp |= MACCFG2_FULL_DUPLEX; -+ -+ tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE); -+ if (speed < E_ENET_SPEED_1000) -+ tmp |= MACCFG2_NIBBLE_MODE; -+ else if (speed == E_ENET_SPEED_1000) -+ tmp |= MACCFG2_BYTE_MODE; -+ iowrite32be(tmp, ®s->maccfg2); -+ -+ tmp = ioread32be(®s->ecntrl); -+ if (speed == E_ENET_SPEED_100) -+ tmp |= DTSEC_ECNTRL_R100M; -+ else -+ tmp &= ~DTSEC_ECNTRL_R100M; -+ iowrite32be(tmp, ®s->ecntrl); -+ -+ return 0; -+} -+ -+void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->rctrl); -+ -+ if (enable) -+ tmp |= RCTRL_UPROM; -+ else -+ tmp &= ~RCTRL_UPROM; -+ -+ iowrite32be(tmp, ®s->rctrl); -+} -+ -+void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->rctrl); -+ -+ if (enable) -+ tmp |= RCTRL_MPROM; -+ else -+ tmp &= ~RCTRL_MPROM; -+ -+ iowrite32be(tmp, ®s->rctrl); -+} -+ -+bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs, -+ uint32_t *car1, uint32_t *car2) -+{ -+ /* read carry registers */ -+ *car1 = ioread32be(®s->car1); -+ *car2 = ioread32be(®s->car2); -+ /* clear carry registers */ -+ if (*car1) -+ iowrite32be(*car1, ®s->car1); -+ if (*car2) -+ iowrite32be(*car2, ®s->car2); -+ -+ return (bool)((*car1 | *car2) ? TRUE : FALSE); -+} -+ -+void fman_dtsec_reset_stat(struct dtsec_regs *regs) -+{ -+ /* clear HW counters */ -+ iowrite32be(ioread32be(®s->ecntrl) | -+ DTSEC_ECNTRL_CLRCNT, ®s->ecntrl); -+} -+ -+int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level) -+{ -+ switch (level) { -+ case E_MAC_STAT_NONE: -+ iowrite32be(0xffffffff, ®s->cam1); -+ iowrite32be(0xffffffff, ®s->cam2); -+ iowrite32be(ioread32be(®s->ecntrl) & ~DTSEC_ECNTRL_STEN, -+ ®s->ecntrl); -+ iowrite32be(ioread32be(®s->imask) & ~DTSEC_IMASK_MSROEN, -+ ®s->imask); -+ break; -+ case E_MAC_STAT_PARTIAL: -+ iowrite32be(CAM1_ERRORS_ONLY, ®s->cam1); -+ iowrite32be(CAM2_ERRORS_ONLY, ®s->cam2); -+ iowrite32be(ioread32be(®s->ecntrl) | DTSEC_ECNTRL_STEN, -+ ®s->ecntrl); -+ iowrite32be(ioread32be(®s->imask) | DTSEC_IMASK_MSROEN, -+ ®s->imask); -+ break; -+ case E_MAC_STAT_MIB_GRP1: -+ iowrite32be((uint32_t)~CAM1_MIB_GRP_1, ®s->cam1); -+ iowrite32be((uint32_t)~CAM2_MIB_GRP_1, ®s->cam2); -+ iowrite32be(ioread32be(®s->ecntrl) | DTSEC_ECNTRL_STEN, -+ ®s->ecntrl); -+ iowrite32be(ioread32be(®s->imask) | DTSEC_IMASK_MSROEN, -+ ®s->imask); -+ break; -+ case E_MAC_STAT_FULL: -+ iowrite32be(0, ®s->cam1); -+ iowrite32be(0, ®s->cam2); -+ iowrite32be(ioread32be(®s->ecntrl) | DTSEC_ECNTRL_STEN, -+ ®s->ecntrl); -+ iowrite32be(ioread32be(®s->imask) | DTSEC_IMASK_MSROEN, -+ ®s->imask); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en) -+{ -+ if (en) { -+ iowrite32be(ioread32be(®s->rctrl) | RCTRL_RTSE, -+ ®s->rctrl); -+ iowrite32be(ioread32be(®s->tctrl) | DTSEC_TCTRL_TTSE, -+ ®s->tctrl); -+ } else { -+ iowrite32be(ioread32be(®s->rctrl) & ~RCTRL_RTSE, -+ ®s->rctrl); -+ iowrite32be(ioread32be(®s->tctrl) & ~DTSEC_TCTRL_TTSE, -+ ®s->tctrl); -+ } -+} -+ -+void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->maccfg1); -+ -+ if (apply_rx) -+ tmp |= MACCFG1_RX_EN ; -+ -+ if (apply_tx) -+ tmp |= MACCFG1_TX_EN ; -+ -+ iowrite32be(tmp, ®s->maccfg1); -+} -+ -+void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num) -+{ -+ iowrite32be(0, ®s->macaddr[paddr_num].exact_match1); -+ iowrite32be(0, ®s->macaddr[paddr_num].exact_match2); -+} -+ -+void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs, -+ uint64_t addr, -+ uint8_t paddr_num) -+{ -+ uint32_t tmp; -+ -+ tmp = (uint32_t)(addr); -+ /* swap */ -+ tmp = (((tmp & 0x000000FF) << 24) | -+ ((tmp & 0x0000FF00) << 8) | -+ ((tmp & 0x00FF0000) >> 8) | -+ ((tmp & 0xFF000000) >> 24)); -+ iowrite32be(tmp, ®s->macaddr[paddr_num].exact_match1); -+ -+ tmp = (uint32_t)(addr>>32); -+ /* swap */ -+ tmp = (((tmp & 0x000000FF) << 24) | -+ ((tmp & 0x0000FF00) << 8) | -+ ((tmp & 0x00FF0000) >> 8) | -+ ((tmp & 0xFF000000) >> 24)); -+ iowrite32be(tmp, ®s->macaddr[paddr_num].exact_match2); -+} -+ -+void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->maccfg1); -+ -+ if (apply_rx) -+ tmp &= ~MACCFG1_RX_EN; -+ -+ if (apply_tx) -+ tmp &= ~MACCFG1_TX_EN; -+ -+ iowrite32be(tmp, ®s->maccfg1); -+} -+ -+void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time) -+{ -+ uint32_t ptv = 0; -+ -+ /* fixme: don't enable tx pause for half-duplex */ -+ -+ if (time) { -+ ptv = ioread32be(®s->ptv); -+ ptv &= 0xffff0000; -+ ptv |= time & 0x0000ffff; -+ iowrite32be(ptv, ®s->ptv); -+ -+ /* trigger the transmission of a flow-control pause frame */ -+ iowrite32be(ioread32be(®s->maccfg1) | MACCFG1_TX_FLOW, -+ ®s->maccfg1); -+ } else -+ iowrite32be(ioread32be(®s->maccfg1) & ~MACCFG1_TX_FLOW, -+ ®s->maccfg1); -+} -+ -+void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en) -+{ -+ uint32_t tmp; -+ -+ /* todo: check if mac is set to full-duplex */ -+ -+ tmp = ioread32be(®s->maccfg1); -+ if (en) -+ tmp |= MACCFG1_RX_FLOW; -+ else -+ tmp &= ~MACCFG1_RX_FLOW; -+ iowrite32be(tmp, ®s->maccfg1); -+} -+ -+uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs) -+{ -+ return ioread32be(®s->rctrl); -+} -+ -+uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs) -+{ -+ return ioread32be(®s->tsec_id); -+} -+ -+uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask) -+{ -+ return ioread32be(®s->ievent) & ev_mask; -+} -+ -+void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ev_mask, ®s->ievent); -+} -+ -+uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs) -+{ -+ return ioread32be(®s->imask); -+} -+ -+uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs) -+{ -+ uint32_t event; -+ -+ event = ioread32be(®s->tmr_pevent); -+ event &= ioread32be(®s->tmr_pemask); -+ -+ if (event) -+ iowrite32be(event, ®s->tmr_pevent); -+ return event; -+} -+ -+void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs) -+{ -+ iowrite32be(ioread32be(®s->tmr_pemask) | TMR_PEMASK_TSREEN, -+ ®s->tmr_pemask); -+} -+ -+void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs) -+{ -+ iowrite32be(ioread32be(®s->tmr_pemask) & ~TMR_PEMASK_TSREEN, -+ ®s->tmr_pemask); -+} -+ -+void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ioread32be(®s->imask) | ev_mask, ®s->imask); -+} -+ -+void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ioread32be(®s->imask) & ~ev_mask, ®s->imask); -+} -+ -+uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs, -+ enum dtsec_stat_counters reg_name) -+{ -+ uint32_t ret_val; -+ -+ switch (reg_name) { -+ case E_DTSEC_STAT_TR64: -+ ret_val = ioread32be(®s->tr64); -+ break; -+ case E_DTSEC_STAT_TR127: -+ ret_val = ioread32be(®s->tr127); -+ break; -+ case E_DTSEC_STAT_TR255: -+ ret_val = ioread32be(®s->tr255); -+ break; -+ case E_DTSEC_STAT_TR511: -+ ret_val = ioread32be(®s->tr511); -+ break; -+ case E_DTSEC_STAT_TR1K: -+ ret_val = ioread32be(®s->tr1k); -+ break; -+ case E_DTSEC_STAT_TRMAX: -+ ret_val = ioread32be(®s->trmax); -+ break; -+ case E_DTSEC_STAT_TRMGV: -+ ret_val = ioread32be(®s->trmgv); -+ break; -+ case E_DTSEC_STAT_RBYT: -+ ret_val = ioread32be(®s->rbyt); -+ break; -+ case E_DTSEC_STAT_RPKT: -+ ret_val = ioread32be(®s->rpkt); -+ break; -+ case E_DTSEC_STAT_RMCA: -+ ret_val = ioread32be(®s->rmca); -+ break; -+ case E_DTSEC_STAT_RBCA: -+ ret_val = ioread32be(®s->rbca); -+ break; -+ case E_DTSEC_STAT_RXPF: -+ ret_val = ioread32be(®s->rxpf); -+ break; -+ case E_DTSEC_STAT_RALN: -+ ret_val = ioread32be(®s->raln); -+ break; -+ case E_DTSEC_STAT_RFLR: -+ ret_val = ioread32be(®s->rflr); -+ break; -+ case E_DTSEC_STAT_RCDE: -+ ret_val = ioread32be(®s->rcde); -+ break; -+ case E_DTSEC_STAT_RCSE: -+ ret_val = ioread32be(®s->rcse); -+ break; -+ case E_DTSEC_STAT_RUND: -+ ret_val = ioread32be(®s->rund); -+ break; -+ case E_DTSEC_STAT_ROVR: -+ ret_val = ioread32be(®s->rovr); -+ break; -+ case E_DTSEC_STAT_RFRG: -+ ret_val = ioread32be(®s->rfrg); -+ break; -+ case E_DTSEC_STAT_RJBR: -+ ret_val = ioread32be(®s->rjbr); -+ break; -+ case E_DTSEC_STAT_RDRP: -+ ret_val = ioread32be(®s->rdrp); -+ break; -+ case E_DTSEC_STAT_TFCS: -+ ret_val = ioread32be(®s->tfcs); -+ break; -+ case E_DTSEC_STAT_TBYT: -+ ret_val = ioread32be(®s->tbyt); -+ break; -+ case E_DTSEC_STAT_TPKT: -+ ret_val = ioread32be(®s->tpkt); -+ break; -+ case E_DTSEC_STAT_TMCA: -+ ret_val = ioread32be(®s->tmca); -+ break; -+ case E_DTSEC_STAT_TBCA: -+ ret_val = ioread32be(®s->tbca); -+ break; -+ case E_DTSEC_STAT_TXPF: -+ ret_val = ioread32be(®s->txpf); -+ break; -+ case E_DTSEC_STAT_TNCL: -+ ret_val = ioread32be(®s->tncl); -+ break; -+ case E_DTSEC_STAT_TDRP: -+ ret_val = ioread32be(®s->tdrp); -+ break; -+ default: -+ ret_val = 0; -+ } -+ -+ return ret_val; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c -@@ -0,0 +1,163 @@ -+/* -+ * Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#include "common/general.h" -+#include "fsl_fman_dtsec_mii_acc.h" -+ -+ -+/** -+ * dtsec_mii_get_div() - calculates the value of the dtsec mii divider -+ * @dtsec_freq: dtsec clock frequency (in Mhz) -+ * -+ * This function calculates the dtsec mii clock divider that determines -+ * the MII MDC clock. MII MDC clock will be set to work in the range -+ * of 1.5 to 2.5Mhz -+ * The output of this function is the value of MIIMCFG[MgmtClk] which -+ * implicitly determines the divider value. -+ * Note: the dTSEC system clock is equal to 1/2 of the FMan clock. -+ * -+ * The table below which reflects dtsec_mii_get_div() functionality -+ * shows the relations among dtsec_freq, MgmtClk, actual divider -+ * and the MII frequency: -+ * -+ * dtsec freq MgmtClk div MII freq Mhz -+ * [0.....80] 1 (1/4)(1/8) [0 to 2.5] -+ * [81...120] 2 (1/6)(1/8) [1.6 to 2.5] -+ * [121..160] 3 (1/8)(1/8) [1.8 to 2.5] -+ * [161..200] 4 (1/10)(1/8) [2.0 to 2.5] -+ * [201..280] 5 (1/14)(1/8) [1.8 to 2.5] -+ * [281..400] 6 (1/20)(1/8) [1.1 to 2.5] -+ * [401..560] 7 (1/28)(1/8) [1.8 to 2.5] -+ * [560..frq] 7 (1/28)(1/8) [frq/224] -+ * -+ * Returns: the MIIMCFG[MgmtClk] appropriate value -+ */ -+ -+static uint8_t dtsec_mii_get_div(uint16_t dtsec_freq) -+{ -+ uint16_t mgmt_clk; -+ -+ if (dtsec_freq < 80) mgmt_clk = 1; -+ else if (dtsec_freq < 120) mgmt_clk = 2; -+ else if (dtsec_freq < 160) mgmt_clk = 3; -+ else if (dtsec_freq < 200) mgmt_clk = 4; -+ else if (dtsec_freq < 280) mgmt_clk = 5; -+ else if (dtsec_freq < 400) mgmt_clk = 6; -+ else mgmt_clk = 7; -+ -+ return (uint8_t)mgmt_clk; -+} -+ -+void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs) -+{ -+ /* Reset the management interface */ -+ iowrite32be(ioread32be(®s->miimcfg) | MIIMCFG_RESET_MGMT, -+ ®s->miimcfg); -+ iowrite32be(ioread32be(®s->miimcfg) & ~MIIMCFG_RESET_MGMT, -+ ®s->miimcfg); -+} -+ -+ -+int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, uint8_t addr, -+ uint8_t reg, uint16_t data, uint16_t dtsec_freq) -+{ -+ uint32_t tmp; -+ -+ /* Setup the MII Mgmt clock speed */ -+ iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), ®s->miimcfg); -+ wmb(); -+ -+ /* Stop the MII management read cycle */ -+ iowrite32be(0, ®s->miimcom); -+ /* Dummy read to make sure MIIMCOM is written */ -+ tmp = ioread32be(®s->miimcom); -+ wmb(); -+ -+ /* Setting up MII Management Address Register */ -+ tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg); -+ iowrite32be(tmp, ®s->miimadd); -+ wmb(); -+ -+ /* Setting up MII Management Control Register with data */ -+ iowrite32be((uint32_t)data, ®s->miimcon); -+ /* Dummy read to make sure MIIMCON is written */ -+ tmp = ioread32be(®s->miimcon); -+ wmb(); -+ -+ /* Wait until MII management write is complete */ -+ /* todo: a timeout could be useful here */ -+ while ((ioread32be(®s->miimind)) & MIIMIND_BUSY) -+ /* busy wait */; -+ -+ return 0; -+} -+ -+int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, uint8_t addr, -+ uint8_t reg, uint16_t *data, uint16_t dtsec_freq) -+{ -+ uint32_t tmp; -+ -+ /* Setup the MII Mgmt clock speed */ -+ iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), ®s->miimcfg); -+ wmb(); -+ -+ /* Setting up the MII Management Address Register */ -+ tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg); -+ iowrite32be(tmp, ®s->miimadd); -+ wmb(); -+ -+ /* Perform an MII management read cycle */ -+ iowrite32be(MIIMCOM_READ_CYCLE, ®s->miimcom); -+ /* Dummy read to make sure MIIMCOM is written */ -+ tmp = ioread32be(®s->miimcom); -+ wmb(); -+ -+ /* Wait until MII management read is complete */ -+ /* todo: a timeout could be useful here */ -+ while ((ioread32be(®s->miimind)) & MIIMIND_BUSY) -+ /* busy wait */; -+ -+ /* Read MII management status */ -+ *data = (uint16_t)ioread32be(®s->miimstat); -+ wmb(); -+ -+ iowrite32be(0, ®s->miimcom); -+ /* Dummy read to make sure MIIMCOM is written */ -+ tmp = ioread32be(®s->miimcom); -+ -+ if (*data == 0xffff) -+ return -ENXIO; -+ -+ return 0; -+} -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c -@@ -0,0 +1,511 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#include "fsl_fman_memac.h" -+ -+ -+uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask) -+{ -+ return ioread32be(®s->ievent) & ev_mask; -+} -+ -+uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs) -+{ -+ return ioread32be(®s->imask); -+} -+ -+void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ev_mask, ®s->ievent); -+} -+ -+void fman_memac_set_promiscuous(struct memac_regs *regs, bool val) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ -+ if (val) -+ tmp |= CMD_CFG_PROMIS_EN; -+ else -+ tmp &= ~CMD_CFG_PROMIS_EN; -+ -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+void fman_memac_clear_addr_in_paddr(struct memac_regs *regs, -+ uint8_t paddr_num) -+{ -+ if (paddr_num == 0) { -+ iowrite32be(0, ®s->mac_addr0.mac_addr_l); -+ iowrite32be(0, ®s->mac_addr0.mac_addr_u); -+ } else { -+ iowrite32be(0x0, ®s->mac_addr[paddr_num - 1].mac_addr_l); -+ iowrite32be(0x0, ®s->mac_addr[paddr_num - 1].mac_addr_u); -+ } -+} -+ -+void fman_memac_add_addr_in_paddr(struct memac_regs *regs, -+ uint8_t *adr, -+ uint8_t paddr_num) -+{ -+ uint32_t tmp0, tmp1; -+ -+ tmp0 = (uint32_t)(adr[0] | -+ adr[1] << 8 | -+ adr[2] << 16 | -+ adr[3] << 24); -+ tmp1 = (uint32_t)(adr[4] | adr[5] << 8); -+ -+ if (paddr_num == 0) { -+ iowrite32be(tmp0, ®s->mac_addr0.mac_addr_l); -+ iowrite32be(tmp1, ®s->mac_addr0.mac_addr_u); -+ } else { -+ iowrite32be(tmp0, ®s->mac_addr[paddr_num-1].mac_addr_l); -+ iowrite32be(tmp1, ®s->mac_addr[paddr_num-1].mac_addr_u); -+ } -+} -+ -+void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ -+ if (apply_rx) -+ tmp |= CMD_CFG_RX_EN; -+ -+ if (apply_tx) -+ tmp |= CMD_CFG_TX_EN; -+ -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ -+ if (apply_rx) -+ tmp &= ~CMD_CFG_RX_EN; -+ -+ if (apply_tx) -+ tmp &= ~CMD_CFG_TX_EN; -+ -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+void fman_memac_reset_stat(struct memac_regs *regs) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->statn_config); -+ -+ tmp |= STATS_CFG_CLR; -+ -+ iowrite32be(tmp, ®s->statn_config); -+ -+ while (ioread32be(®s->statn_config) & STATS_CFG_CLR); -+} -+ -+void fman_memac_reset(struct memac_regs *regs) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ -+ tmp |= CMD_CFG_SW_RESET; -+ -+ iowrite32be(tmp, ®s->command_config); -+ -+ while (ioread32be(®s->command_config) & CMD_CFG_SW_RESET); -+} -+ -+int fman_memac_init(struct memac_regs *regs, -+ struct memac_cfg *cfg, -+ enum enet_interface enet_interface, -+ enum enet_speed enet_speed, -+ bool slow_10g_if, -+ uint32_t exceptions) -+{ -+ uint32_t tmp; -+ -+ /* Config */ -+ tmp = 0; -+ if (cfg->wan_mode_enable) -+ tmp |= CMD_CFG_WAN_MODE; -+ if (cfg->promiscuous_mode_enable) -+ tmp |= CMD_CFG_PROMIS_EN; -+ if (cfg->pause_forward_enable) -+ tmp |= CMD_CFG_PAUSE_FWD; -+ if (cfg->pause_ignore) -+ tmp |= CMD_CFG_PAUSE_IGNORE; -+ if (cfg->tx_addr_ins_enable) -+ tmp |= CMD_CFG_TX_ADDR_INS; -+ if (cfg->loopback_enable) -+ tmp |= CMD_CFG_LOOPBACK_EN; -+ if (cfg->cmd_frame_enable) -+ tmp |= CMD_CFG_CNT_FRM_EN; -+ if (cfg->send_idle_enable) -+ tmp |= CMD_CFG_SEND_IDLE; -+ if (cfg->no_length_check_enable) -+ tmp |= CMD_CFG_NO_LEN_CHK; -+ if (cfg->rx_sfd_any) -+ tmp |= CMD_CFG_SFD_ANY; -+ if (cfg->pad_enable) -+ tmp |= CMD_CFG_TX_PAD_EN; -+ if (cfg->wake_on_lan) -+ tmp |= CMD_CFG_MG; -+ -+ tmp |= CMD_CFG_CRC_FWD; -+ -+ iowrite32be(tmp, ®s->command_config); -+ -+ /* Max Frame Length */ -+ iowrite32be((uint32_t)cfg->max_frame_length, ®s->maxfrm); -+ -+ /* Pause Time */ -+ iowrite32be((uint32_t)cfg->pause_quanta, ®s->pause_quanta[0]); -+ iowrite32be((uint32_t)0, ®s->pause_thresh[0]); -+ -+ /* IF_MODE */ -+ tmp = 0; -+ switch (enet_interface) { -+ case E_ENET_IF_XGMII: -+ case E_ENET_IF_XFI: -+ tmp |= IF_MODE_XGMII; -+ break; -+ default: -+ tmp |= IF_MODE_GMII; -+ if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable) -+ tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO; -+ } -+ iowrite32be(tmp, ®s->if_mode); -+ -+ /* TX_FIFO_SECTIONS */ -+ tmp = 0; -+ if (enet_interface == E_ENET_IF_XGMII || -+ enet_interface == E_ENET_IF_XFI) { -+ if(slow_10g_if) { -+ tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G | -+ TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G); -+ } else { -+ tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G | -+ TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G); -+ } -+ } else { -+ tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G | -+ TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G); -+ } -+ iowrite32be(tmp, ®s->tx_fifo_sections); -+ -+ /* clear all pending events and set-up interrupts */ -+ fman_memac_ack_event(regs, 0xffffffff); -+ fman_memac_set_exception(regs, exceptions, TRUE); -+ -+ return 0; -+} -+ -+void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->imask); -+ if (enable) -+ tmp |= val; -+ else -+ tmp &= ~val; -+ -+ iowrite32be(tmp, ®s->imask); -+} -+ -+void fman_memac_reset_filter_table(struct memac_regs *regs) -+{ -+ uint32_t i; -+ for (i = 0; i < 64; i++) -+ iowrite32be(i & ~HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl); -+} -+ -+void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc) -+{ -+ iowrite32be(crc | HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl); -+} -+ -+void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val) -+{ -+ iowrite32be(val, ®s->hashtable_ctrl); -+} -+ -+uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->maxfrm); -+ -+ return(uint16_t)tmp; -+} -+ -+ -+void fman_memac_set_tx_pause_frames(struct memac_regs *regs, -+ uint8_t priority, -+ uint16_t pause_time, -+ uint16_t thresh_time) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->tx_fifo_sections); -+ -+ if (priority == 0xff) { -+ GET_TX_EMPTY_DEFAULT_VALUE(tmp); -+ iowrite32be(tmp, ®s->tx_fifo_sections); -+ -+ tmp = ioread32be(®s->command_config); -+ tmp &= ~CMD_CFG_PFC_MODE; -+ priority = 0; -+ } else { -+ GET_TX_EMPTY_PFC_VALUE(tmp); -+ iowrite32be(tmp, ®s->tx_fifo_sections); -+ -+ tmp = ioread32be(®s->command_config); -+ tmp |= CMD_CFG_PFC_MODE; -+ } -+ -+ iowrite32be(tmp, ®s->command_config); -+ -+ tmp = ioread32be(®s->pause_quanta[priority / 2]); -+ if (priority % 2) -+ tmp &= 0x0000FFFF; -+ else -+ tmp &= 0xFFFF0000; -+ tmp |= ((uint32_t)pause_time << (16 * (priority % 2))); -+ iowrite32be(tmp, ®s->pause_quanta[priority / 2]); -+ -+ tmp = ioread32be(®s->pause_thresh[priority / 2]); -+ if (priority % 2) -+ tmp &= 0x0000FFFF; -+ else -+ tmp &= 0xFFFF0000; -+ tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2))); -+ iowrite32be(tmp, ®s->pause_thresh[priority / 2]); -+} -+ -+void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ if (enable) -+ tmp |= CMD_CFG_PAUSE_IGNORE; -+ else -+ tmp &= ~CMD_CFG_PAUSE_IGNORE; -+ -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+void fman_memac_set_wol(struct memac_regs *regs, bool enable) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ -+ if (enable) -+ tmp |= CMD_CFG_MG; -+ else -+ tmp &= ~CMD_CFG_MG; -+ -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+#define GET_MEMAC_CNTR_64(bn) \ -+ (ioread32be(®s->bn ## _l) | \ -+ ((uint64_t)ioread32be(®s->bn ## _u) << 32)) -+ -+uint64_t fman_memac_get_counter(struct memac_regs *regs, -+ enum memac_counters reg_name) -+{ -+ uint64_t ret_val; -+ -+ switch (reg_name) { -+ case E_MEMAC_COUNTER_R64: -+ ret_val = GET_MEMAC_CNTR_64(r64); -+ break; -+ case E_MEMAC_COUNTER_R127: -+ ret_val = GET_MEMAC_CNTR_64(r127); -+ break; -+ case E_MEMAC_COUNTER_R255: -+ ret_val = GET_MEMAC_CNTR_64(r255); -+ break; -+ case E_MEMAC_COUNTER_R511: -+ ret_val = GET_MEMAC_CNTR_64(r511); -+ break; -+ case E_MEMAC_COUNTER_R1023: -+ ret_val = GET_MEMAC_CNTR_64(r1023); -+ break; -+ case E_MEMAC_COUNTER_R1518: -+ ret_val = GET_MEMAC_CNTR_64(r1518); -+ break; -+ case E_MEMAC_COUNTER_R1519X: -+ ret_val = GET_MEMAC_CNTR_64(r1519x); -+ break; -+ case E_MEMAC_COUNTER_RFRG: -+ ret_val = GET_MEMAC_CNTR_64(rfrg); -+ break; -+ case E_MEMAC_COUNTER_RJBR: -+ ret_val = GET_MEMAC_CNTR_64(rjbr); -+ break; -+ case E_MEMAC_COUNTER_RDRP: -+ ret_val = GET_MEMAC_CNTR_64(rdrp); -+ break; -+ case E_MEMAC_COUNTER_RALN: -+ ret_val = GET_MEMAC_CNTR_64(raln); -+ break; -+ case E_MEMAC_COUNTER_TUND: -+ ret_val = GET_MEMAC_CNTR_64(tund); -+ break; -+ case E_MEMAC_COUNTER_ROVR: -+ ret_val = GET_MEMAC_CNTR_64(rovr); -+ break; -+ case E_MEMAC_COUNTER_RXPF: -+ ret_val = GET_MEMAC_CNTR_64(rxpf); -+ break; -+ case E_MEMAC_COUNTER_TXPF: -+ ret_val = GET_MEMAC_CNTR_64(txpf); -+ break; -+ case E_MEMAC_COUNTER_ROCT: -+ ret_val = GET_MEMAC_CNTR_64(roct); -+ break; -+ case E_MEMAC_COUNTER_RMCA: -+ ret_val = GET_MEMAC_CNTR_64(rmca); -+ break; -+ case E_MEMAC_COUNTER_RBCA: -+ ret_val = GET_MEMAC_CNTR_64(rbca); -+ break; -+ case E_MEMAC_COUNTER_RPKT: -+ ret_val = GET_MEMAC_CNTR_64(rpkt); -+ break; -+ case E_MEMAC_COUNTER_RUCA: -+ ret_val = GET_MEMAC_CNTR_64(ruca); -+ break; -+ case E_MEMAC_COUNTER_RERR: -+ ret_val = GET_MEMAC_CNTR_64(rerr); -+ break; -+ case E_MEMAC_COUNTER_TOCT: -+ ret_val = GET_MEMAC_CNTR_64(toct); -+ break; -+ case E_MEMAC_COUNTER_TMCA: -+ ret_val = GET_MEMAC_CNTR_64(tmca); -+ break; -+ case E_MEMAC_COUNTER_TBCA: -+ ret_val = GET_MEMAC_CNTR_64(tbca); -+ break; -+ case E_MEMAC_COUNTER_TUCA: -+ ret_val = GET_MEMAC_CNTR_64(tuca); -+ break; -+ case E_MEMAC_COUNTER_TERR: -+ ret_val = GET_MEMAC_CNTR_64(terr); -+ break; -+ default: -+ ret_val = 0; -+ } -+ -+ return ret_val; -+} -+ -+void fman_memac_adjust_link(struct memac_regs *regs, -+ enum enet_interface iface_mode, -+ enum enet_speed speed, bool full_dx) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->if_mode); -+ -+ if (full_dx) -+ tmp &= ~IF_MODE_HD; -+ else -+ tmp |= IF_MODE_HD; -+ -+ if (iface_mode == E_ENET_IF_RGMII) { -+ /* Configure RGMII in manual mode */ -+ tmp &= ~IF_MODE_RGMII_AUTO; -+ tmp &= ~IF_MODE_RGMII_SP_MASK; -+ -+ if (full_dx) -+ tmp |= IF_MODE_RGMII_FD; -+ else -+ tmp &= ~IF_MODE_RGMII_FD; -+ -+ switch (speed) { -+ case E_ENET_SPEED_1000: -+ tmp |= IF_MODE_RGMII_1000; -+ break; -+ case E_ENET_SPEED_100: -+ tmp |= IF_MODE_RGMII_100; -+ break; -+ case E_ENET_SPEED_10: -+ tmp |= IF_MODE_RGMII_10; -+ break; -+ default: -+ break; -+ } -+ } -+ -+ iowrite32be(tmp, ®s->if_mode); -+} -+ -+void fman_memac_defconfig(struct memac_cfg *cfg) -+{ -+ cfg->reset_on_init = FALSE; -+ cfg->wan_mode_enable = FALSE; -+ cfg->promiscuous_mode_enable = FALSE; -+ cfg->pause_forward_enable = FALSE; -+ cfg->pause_ignore = FALSE; -+ cfg->tx_addr_ins_enable = FALSE; -+ cfg->loopback_enable = FALSE; -+ cfg->cmd_frame_enable = FALSE; -+ cfg->rx_error_discard = FALSE; -+ cfg->send_idle_enable = FALSE; -+ cfg->no_length_check_enable = TRUE; -+ cfg->lgth_check_nostdr = FALSE; -+ cfg->time_stamp_enable = FALSE; -+ cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH; -+ cfg->max_frame_length = DEFAULT_FRAME_LENGTH; -+ cfg->pause_quanta = DEFAULT_PAUSE_QUANTA; -+ cfg->pad_enable = TRUE; -+ cfg->phy_tx_ena_on = FALSE; -+ cfg->rx_sfd_any = FALSE; -+ cfg->rx_pbl_fwd = FALSE; -+ cfg->tx_pbl_fwd = FALSE; -+ cfg->debug_mode = FALSE; -+ cfg->wake_on_lan = FALSE; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c -@@ -0,0 +1,213 @@ -+/* -+ * Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#include "fsl_fman_memac_mii_acc.h" -+ -+static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs, -+ uint8_t phy_addr, uint8_t reg, uint16_t data) -+{ -+ uint32_t tmp_reg; -+ -+ tmp_reg = ioread32be(&mii_regs->mdio_cfg); -+ /* Leave only MDIO_CLK_DIV bits set on */ -+ tmp_reg &= MDIO_CFG_CLK_DIV_MASK; -+ /* Set maximum MDIO_HOLD value to allow phy to see -+ change of data signal */ -+ tmp_reg |= MDIO_CFG_HOLD_MASK; -+ /* Add 10G interface mode */ -+ tmp_reg |= MDIO_CFG_ENC45; -+ iowrite32be(tmp_reg, &mii_regs->mdio_cfg); -+ -+ /* Wait for command completion */ -+ while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) -+ udelay(1); -+ -+ /* Specify phy and register to be accessed */ -+ iowrite32be(phy_addr, &mii_regs->mdio_ctrl); -+ iowrite32be(reg, &mii_regs->mdio_addr); -+ wmb(); -+ -+ while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) -+ udelay(1); -+ -+ /* Write data */ -+ iowrite32be(data, &mii_regs->mdio_data); -+ wmb(); -+ -+ /* Wait for write transaction end */ -+ while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY) -+ udelay(1); -+} -+ -+static uint32_t read_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs, -+ uint8_t phy_addr, uint8_t reg, uint16_t *data) -+{ -+ uint32_t tmp_reg; -+ -+ tmp_reg = ioread32be(&mii_regs->mdio_cfg); -+ /* Leave only MDIO_CLK_DIV bits set on */ -+ tmp_reg &= MDIO_CFG_CLK_DIV_MASK; -+ /* Set maximum MDIO_HOLD value to allow phy to see -+ change of data signal */ -+ tmp_reg |= MDIO_CFG_HOLD_MASK; -+ /* Add 10G interface mode */ -+ tmp_reg |= MDIO_CFG_ENC45; -+ iowrite32be(tmp_reg, &mii_regs->mdio_cfg); -+ -+ /* Wait for command completion */ -+ while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) -+ udelay(1); -+ -+ /* Specify phy and register to be accessed */ -+ iowrite32be(phy_addr, &mii_regs->mdio_ctrl); -+ iowrite32be(reg, &mii_regs->mdio_addr); -+ wmb(); -+ -+ while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) -+ udelay(1); -+ -+ /* Read cycle */ -+ tmp_reg = phy_addr; -+ tmp_reg |= MDIO_CTL_READ; -+ iowrite32be(tmp_reg, &mii_regs->mdio_ctrl); -+ wmb(); -+ -+ /* Wait for data to be available */ -+ while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY) -+ udelay(1); -+ -+ *data = (uint16_t)ioread32be(&mii_regs->mdio_data); -+ -+ /* Check if there was an error */ -+ return ioread32be(&mii_regs->mdio_cfg); -+} -+ -+static void write_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs, -+ uint8_t phy_addr, uint8_t reg, uint16_t data) -+{ -+ uint32_t tmp_reg; -+ -+ /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */ -+ tmp_reg = ioread32be(&mii_regs->mdio_cfg); -+ tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK); -+ iowrite32be(tmp_reg, &mii_regs->mdio_cfg); -+ -+ /* Wait for command completion */ -+ while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) -+ udelay(1); -+ -+ /* Write transaction */ -+ tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT); -+ tmp_reg |= reg; -+ iowrite32be(tmp_reg, &mii_regs->mdio_ctrl); -+ -+ while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) -+ udelay(1); -+ -+ iowrite32be(data, &mii_regs->mdio_data); -+ -+ wmb(); -+ -+ /* Wait for write transaction to end */ -+ while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY) -+ udelay(1); -+} -+ -+static uint32_t read_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs, -+ uint8_t phy_addr, uint8_t reg, uint16_t *data) -+{ -+ uint32_t tmp_reg; -+ -+ /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */ -+ tmp_reg = ioread32be(&mii_regs->mdio_cfg); -+ tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK); -+ iowrite32be(tmp_reg, &mii_regs->mdio_cfg); -+ -+ /* Wait for command completion */ -+ while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) -+ udelay(1); -+ -+ /* Read transaction */ -+ tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT); -+ tmp_reg |= reg; -+ tmp_reg |= MDIO_CTL_READ; -+ iowrite32be(tmp_reg, &mii_regs->mdio_ctrl); -+ -+ while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY) -+ udelay(1); -+ -+ /* Wait for data to be available */ -+ while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY) -+ udelay(1); -+ -+ *data = (uint16_t)ioread32be(&mii_regs->mdio_data); -+ -+ /* Check error */ -+ return ioread32be(&mii_regs->mdio_cfg); -+} -+ -+/*****************************************************************************/ -+int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs, -+ uint8_t phy_addr, uint8_t reg, uint16_t data, -+ enum enet_speed enet_speed) -+{ -+ /* Figure out interface type - 10G vs 1G. -+ In 10G interface both phy_addr and devAddr present. */ -+ if (enet_speed == E_ENET_SPEED_10000) -+ write_phy_reg_10g(mii_regs, phy_addr, reg, data); -+ else -+ write_phy_reg_1g(mii_regs, phy_addr, reg, data); -+ -+ return 0; -+} -+ -+/*****************************************************************************/ -+int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs, -+ uint8_t phy_addr, uint8_t reg, uint16_t *data, -+ enum enet_speed enet_speed) -+{ -+ uint32_t ans; -+ /* Figure out interface type - 10G vs 1G. -+ In 10G interface both phy_addr and devAddr present. */ -+ if (enet_speed == E_ENET_SPEED_10000) -+ ans = read_phy_reg_10g(mii_regs, phy_addr, reg, data); -+ else -+ ans = read_phy_reg_1g(mii_regs, phy_addr, reg, data); -+ -+ if (ans & MDIO_CFG_READ_ERR) -+ return -EINVAL; -+ return 0; -+} -+ -+/* ......................................................................... */ -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c -@@ -0,0 +1,367 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#include "fsl_fman_tgec.h" -+ -+ -+void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr) -+{ -+ uint32_t tmp0, tmp1; -+ -+ tmp0 = (uint32_t)(adr[0] | -+ adr[1] << 8 | -+ adr[2] << 16 | -+ adr[3] << 24); -+ tmp1 = (uint32_t)(adr[4] | adr[5] << 8); -+ iowrite32be(tmp0, ®s->mac_addr_0); -+ iowrite32be(tmp1, ®s->mac_addr_1); -+} -+ -+void fman_tgec_reset_stat(struct tgec_regs *regs) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ -+ tmp |= CMD_CFG_STAT_CLR; -+ -+ iowrite32be(tmp, ®s->command_config); -+ -+ while (ioread32be(®s->command_config) & CMD_CFG_STAT_CLR) ; -+} -+ -+#define GET_TGEC_CNTR_64(bn) \ -+ (((uint64_t)ioread32be(®s->bn ## _u) << 32) | \ -+ ioread32be(®s->bn ## _l)) -+ -+uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name) -+{ -+ uint64_t ret_val; -+ -+ switch (reg_name) { -+ case E_TGEC_COUNTER_R64: -+ ret_val = GET_TGEC_CNTR_64(r64); -+ break; -+ case E_TGEC_COUNTER_R127: -+ ret_val = GET_TGEC_CNTR_64(r127); -+ break; -+ case E_TGEC_COUNTER_R255: -+ ret_val = GET_TGEC_CNTR_64(r255); -+ break; -+ case E_TGEC_COUNTER_R511: -+ ret_val = GET_TGEC_CNTR_64(r511); -+ break; -+ case E_TGEC_COUNTER_R1023: -+ ret_val = GET_TGEC_CNTR_64(r1023); -+ break; -+ case E_TGEC_COUNTER_R1518: -+ ret_val = GET_TGEC_CNTR_64(r1518); -+ break; -+ case E_TGEC_COUNTER_R1519X: -+ ret_val = GET_TGEC_CNTR_64(r1519x); -+ break; -+ case E_TGEC_COUNTER_TRFRG: -+ ret_val = GET_TGEC_CNTR_64(trfrg); -+ break; -+ case E_TGEC_COUNTER_TRJBR: -+ ret_val = GET_TGEC_CNTR_64(trjbr); -+ break; -+ case E_TGEC_COUNTER_RDRP: -+ ret_val = GET_TGEC_CNTR_64(rdrp); -+ break; -+ case E_TGEC_COUNTER_RALN: -+ ret_val = GET_TGEC_CNTR_64(raln); -+ break; -+ case E_TGEC_COUNTER_TRUND: -+ ret_val = GET_TGEC_CNTR_64(trund); -+ break; -+ case E_TGEC_COUNTER_TROVR: -+ ret_val = GET_TGEC_CNTR_64(trovr); -+ break; -+ case E_TGEC_COUNTER_RXPF: -+ ret_val = GET_TGEC_CNTR_64(rxpf); -+ break; -+ case E_TGEC_COUNTER_TXPF: -+ ret_val = GET_TGEC_CNTR_64(txpf); -+ break; -+ case E_TGEC_COUNTER_ROCT: -+ ret_val = GET_TGEC_CNTR_64(roct); -+ break; -+ case E_TGEC_COUNTER_RMCA: -+ ret_val = GET_TGEC_CNTR_64(rmca); -+ break; -+ case E_TGEC_COUNTER_RBCA: -+ ret_val = GET_TGEC_CNTR_64(rbca); -+ break; -+ case E_TGEC_COUNTER_RPKT: -+ ret_val = GET_TGEC_CNTR_64(rpkt); -+ break; -+ case E_TGEC_COUNTER_RUCA: -+ ret_val = GET_TGEC_CNTR_64(ruca); -+ break; -+ case E_TGEC_COUNTER_RERR: -+ ret_val = GET_TGEC_CNTR_64(rerr); -+ break; -+ case E_TGEC_COUNTER_TOCT: -+ ret_val = GET_TGEC_CNTR_64(toct); -+ break; -+ case E_TGEC_COUNTER_TMCA: -+ ret_val = GET_TGEC_CNTR_64(tmca); -+ break; -+ case E_TGEC_COUNTER_TBCA: -+ ret_val = GET_TGEC_CNTR_64(tbca); -+ break; -+ case E_TGEC_COUNTER_TUCA: -+ ret_val = GET_TGEC_CNTR_64(tuca); -+ break; -+ case E_TGEC_COUNTER_TERR: -+ ret_val = GET_TGEC_CNTR_64(terr); -+ break; -+ default: -+ ret_val = 0; -+ } -+ -+ return ret_val; -+} -+ -+void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ if (apply_rx) -+ tmp |= CMD_CFG_RX_EN; -+ if (apply_tx) -+ tmp |= CMD_CFG_TX_EN; -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx) -+{ -+ uint32_t tmp_reg_32; -+ -+ tmp_reg_32 = ioread32be(®s->command_config); -+ if (apply_rx) -+ tmp_reg_32 &= ~CMD_CFG_RX_EN; -+ if (apply_tx) -+ tmp_reg_32 &= ~CMD_CFG_TX_EN; -+ iowrite32be(tmp_reg_32, ®s->command_config); -+} -+ -+void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ if (val) -+ tmp |= CMD_CFG_PROMIS_EN; -+ else -+ tmp &= ~CMD_CFG_PROMIS_EN; -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+void fman_tgec_reset_filter_table(struct tgec_regs *regs) -+{ -+ uint32_t i; -+ for (i = 0; i < 512; i++) -+ iowrite32be(i & ~TGEC_HASH_MCAST_EN, ®s->hashtable_ctrl); -+} -+ -+void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc) -+{ -+ uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */ -+ iowrite32be(hash | TGEC_HASH_MCAST_EN, ®s->hashtable_ctrl); -+} -+ -+void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value) -+{ -+ iowrite32be(value, ®s->hashtable_ctrl); -+} -+ -+void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time) -+{ -+ iowrite32be((uint32_t)pause_time, ®s->pause_quant); -+} -+ -+void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ if (en) -+ tmp |= CMD_CFG_PAUSE_IGNORE; -+ else -+ tmp &= ~CMD_CFG_PAUSE_IGNORE; -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->command_config); -+ if (en) -+ tmp |= CMD_CFG_EN_TIMESTAMP; -+ else -+ tmp &= ~CMD_CFG_EN_TIMESTAMP; -+ iowrite32be(tmp, ®s->command_config); -+} -+ -+uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask) -+{ -+ return ioread32be(®s->ievent) & ev_mask; -+} -+ -+void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ev_mask, ®s->ievent); -+} -+ -+uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs) -+{ -+ return ioread32be(®s->imask); -+} -+ -+void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr) -+{ -+ uint32_t tmp0, tmp1; -+ -+ tmp0 = (uint32_t)(adr[0] | -+ adr[1] << 8 | -+ adr[2] << 16 | -+ adr[3] << 24); -+ tmp1 = (uint32_t)(adr[4] | adr[5] << 8); -+ iowrite32be(tmp0, ®s->mac_addr_2); -+ iowrite32be(tmp1, ®s->mac_addr_3); -+} -+ -+void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs) -+{ -+ iowrite32be(0, ®s->mac_addr_2); -+ iowrite32be(0, ®s->mac_addr_3); -+} -+ -+uint32_t fman_tgec_get_revision(struct tgec_regs *regs) -+{ -+ return ioread32be(®s->tgec_id); -+} -+ -+void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ioread32be(®s->imask) | ev_mask, ®s->imask); -+} -+ -+void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask) -+{ -+ iowrite32be(ioread32be(®s->imask) & ~ev_mask, ®s->imask); -+} -+ -+uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs) -+{ -+ return (uint16_t) ioread32be(®s->maxfrm); -+} -+ -+void fman_tgec_defconfig(struct tgec_cfg *cfg) -+{ -+ cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE; -+ cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE; -+ cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE; -+ cfg->pause_ignore = DEFAULT_PAUSE_IGNORE; -+ cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE; -+ cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE; -+ cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE; -+ cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD; -+ cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE; -+ cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE; -+ cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR; -+ cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE; -+ cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH; -+ cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH; -+ cfg->pause_quant = DEFAULT_PAUSE_QUANT; -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+ cfg->skip_fman11_workaround = FALSE; -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+} -+ -+int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg, -+ uint32_t exception_mask) -+{ -+ uint32_t tmp; -+ -+ /* Config */ -+ tmp = 0x40; /* CRC forward */ -+ if (cfg->wan_mode_enable) -+ tmp |= CMD_CFG_WAN_MODE; -+ if (cfg->promiscuous_mode_enable) -+ tmp |= CMD_CFG_PROMIS_EN; -+ if (cfg->pause_forward_enable) -+ tmp |= CMD_CFG_PAUSE_FWD; -+ if (cfg->pause_ignore) -+ tmp |= CMD_CFG_PAUSE_IGNORE; -+ if (cfg->tx_addr_ins_enable) -+ tmp |= CMD_CFG_TX_ADDR_INS; -+ if (cfg->loopback_enable) -+ tmp |= CMD_CFG_LOOPBACK_EN; -+ if (cfg->cmd_frame_enable) -+ tmp |= CMD_CFG_CMD_FRM_EN; -+ if (cfg->rx_error_discard) -+ tmp |= CMD_CFG_RX_ER_DISC; -+ if (cfg->send_idle_enable) -+ tmp |= CMD_CFG_SEND_IDLE; -+ if (cfg->no_length_check_enable) -+ tmp |= CMD_CFG_NO_LEN_CHK; -+ if (cfg->time_stamp_enable) -+ tmp |= CMD_CFG_EN_TIMESTAMP; -+ iowrite32be(tmp, ®s->command_config); -+ -+ /* Max Frame Length */ -+ iowrite32be((uint32_t)cfg->max_frame_length, ®s->maxfrm); -+ /* Pause Time */ -+ iowrite32be(cfg->pause_quant, ®s->pause_quant); -+ -+ /* clear all pending events and set-up interrupts */ -+ fman_tgec_ack_event(regs, 0xffffffff); -+ fman_tgec_enable_interrupt(regs, exception_mask); -+ -+ return 0; -+} -+ -+void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs) -+{ -+ uint32_t tmp; -+ -+ /* restore the default tx ipg Length */ -+ tmp = (ioread32be(®s->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12; -+ -+ iowrite32be(tmp, ®s->tx_ipg_len); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c -@@ -0,0 +1,1096 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File memac.c -+ -+ @Description FM mEMAC driver -+*//***************************************************************************/ -+ -+#include "std_ext.h" -+#include "string_ext.h" -+#include "error_ext.h" -+#include "xx_ext.h" -+#include "endian_ext.h" -+#include "debug_ext.h" -+ -+#include "fm_common.h" -+#include "memac.h" -+ -+ -+/*****************************************************************************/ -+/* Internal routines */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+ -+static uint32_t GetMacAddrHashCode(uint64_t ethAddr) -+{ -+ uint64_t mask1, mask2; -+ uint32_t xorVal = 0; -+ uint8_t i, j; -+ -+ for (i=0; i<6; i++) -+ { -+ mask1 = ethAddr & (uint64_t)0x01; -+ ethAddr >>= 1; -+ -+ for (j=0; j<7; j++) -+ { -+ mask2 = ethAddr & (uint64_t)0x01; -+ mask1 ^= mask2; -+ ethAddr >>= 1; -+ } -+ -+ xorVal |= (mask1 << (5-i)); -+ } -+ -+ return xorVal; -+} -+ -+/* ......................................................................... */ -+ -+static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr) -+{ -+ uint16_t tmpReg16; -+ e_EnetMode enetMode; -+ -+ /* In case the higher MACs are used (i.e. the MACs that should support 10G), -+ speed=10000 is provided for SGMII ports. Temporary modify enet mode -+ to 1G one, so MII functions can work correctly. */ -+ enetMode = p_Memac->enetMode; -+ -+ /* SGMII mode + AN enable */ -+ tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII; -+ if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500) -+ tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII; -+ -+ p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000); -+ MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16); -+ -+ /* Device ability according to SGMII specification */ -+ tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII; -+ MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16); -+ -+ /* Adjust link timer for SGMII - -+ According to Cisco SGMII specification the timer should be 1.6 ms. -+ The link_timer register is configured in units of the clock. -+ - When running as 1G SGMII, Serdes clock is 125 MHz, so -+ unit = 1 / (125*10^6 Hz) = 8 ns. -+ 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40 -+ - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so -+ unit = 1 / (312.5*10^6 Hz) = 3.2 ns. -+ 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120. -+ Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, -+ we always set up here a value of 2.5 SGMII. */ -+ MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007); -+ MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120); -+ -+ /* Restart AN */ -+ tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN; -+ MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16); -+ -+ /* Restore original enet mode */ -+ p_Memac->enetMode = enetMode; -+} -+ -+/* ......................................................................... */ -+ -+static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr) -+{ -+ uint16_t tmpReg16; -+ e_EnetMode enetMode; -+ -+ /* In case the higher MACs are used (i.e. the MACs that should support 10G), -+ speed=10000 is provided for SGMII ports. Temporary modify enet mode -+ to 1G one, so MII functions can work correctly. */ -+ enetMode = p_Memac->enetMode; -+ p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000); -+ -+ /* 1000BaseX mode */ -+ tmpReg16 = PHY_SGMII_IF_MODE_1000X; -+ MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16); -+ -+ /* AN Device capability */ -+ tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X; -+ MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16); -+ -+ /* Adjust link timer for SGMII - -+ For Serdes 1000BaseX auto-negotiation the timer should be 10 ms. -+ The link_timer register is configured in units of the clock. -+ - When running as 1G SGMII, Serdes clock is 125 MHz, so -+ unit = 1 / (125*10^6 Hz) = 8 ns. -+ 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0 -+ - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so -+ unit = 1 / (312.5*10^6 Hz) = 3.2 ns. -+ 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08. -+ Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, -+ we always set up here a value of 2.5 SGMII. */ -+ MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f); -+ MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08); -+ -+ /* Restart AN */ -+ tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN; -+ MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16); -+ -+ /* Restore original enet mode */ -+ p_Memac->enetMode = enetMode; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error CheckInitParameters(t_Memac *p_Memac) -+{ -+ e_FmMacType portType; -+ -+ portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G); -+ -+#if (FM_MAX_NUM_OF_10G_MACS > 0) -+ if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS)); -+#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */ -+ -+ if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS)); -+ if (p_Memac->addr == 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address")); -+ if (!p_Memac->f_Exception) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception")); -+ if (!p_Memac->f_Event) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event")); -+#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002 -+ if (!p_Memac->p_MemacDriverParam->no_length_check_enable) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!")); -+#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */ -+ -+ return E_OK; -+} -+ -+/* ........................................................................... */ -+ -+static void MemacErrException(t_Handle h_Memac) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ uint32_t event, imask; -+ -+ event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff); -+ imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap); -+ -+ /* Imask include both error and notification/event bits. -+ Leaving only error bits enabled by imask. -+ The imask error bits are shifted by 16 bits offset from -+ their corresponding location in the ievent - hence the >> 16 */ -+ event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16); -+ -+ fman_memac_ack_event(p_Memac->p_MemMap, event); -+ -+ if (event & MEMAC_IEVNT_TS_ECC_ER) -+ p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR); -+ if (event & MEMAC_IEVNT_TX_ECC_ER) -+ p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER); -+ if (event & MEMAC_IEVNT_RX_ECC_ER) -+ p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER); -+} -+ -+static void MemacException(t_Handle h_Memac) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ uint32_t event, imask; -+ -+ event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff); -+ imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap); -+ -+ /* Imask include both error and notification/event bits. -+ Leaving only error bits enabled by imask. -+ The imask error bits are shifted by 16 bits offset from -+ their corresponding location in the ievent - hence the >> 16 */ -+ event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16); -+ -+ fman_memac_ack_event(p_Memac->p_MemMap, event); -+ -+ if (event & MEMAC_IEVNT_MGI) -+ p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION); -+} -+ -+/* ......................................................................... */ -+ -+static void FreeInitResources(t_Memac *p_Memac) -+{ -+ e_FmMacType portType; -+ -+ portType = -+ ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G); -+ -+ if (portType == e_FM_MAC_10G) -+ FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR); -+ else -+ FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR); -+ -+ /* release the driver's group hash table */ -+ FreeHashTable(p_Memac->p_MulticastAddrHash); -+ p_Memac->p_MulticastAddrHash = NULL; -+ -+ /* release the driver's individual hash table */ -+ FreeHashTable(p_Memac->p_UnicastAddrHash); -+ p_Memac->p_UnicastAddrHash = NULL; -+} -+ -+ -+/*****************************************************************************/ -+/* mEMAC API routines */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+ -+static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX)); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX)); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacSetPromiscuous(t_Handle h_Memac, bool newVal) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex)) -+ RETURN_ERROR(MAJOR, E_CONFLICT, -+ ("Ethernet MAC 1G or 10G does not support half-duplex")); -+ -+ fman_memac_adjust_link(p_Memac->p_MemMap, -+ (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), -+ (enum enet_speed)speed, -+ fullDuplex); -+ return E_OK; -+} -+ -+ -+/*****************************************************************************/ -+/* Memac Configs modification functions */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+ -+static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ p_Memac->p_MemacDriverParam->loopback_enable = newVal; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ p_Memac->p_MemacDriverParam->wan_mode_enable = newVal; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ p_Memac->p_MemacDriverParam->max_frame_length = newVal; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ p_Memac->p_MemacDriverParam->pad_enable = newVal; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ uint32_t bitMask = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ GET_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_Memac->exceptions |= bitMask; -+ else -+ p_Memac->exceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ p_Memac->p_MemacDriverParam->reset_on_init = enable; -+ -+ return E_OK; -+} -+ -+ -+/*****************************************************************************/ -+/* Memac Run Time API functions */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+ -+static t_Error MemacSetTxPauseFrames(t_Handle h_Memac, -+ uint8_t priority, -+ uint16_t pauseTime, -+ uint16_t threshTime) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ if (priority != 0xFF) -+ { -+ bool PortConfigured, PreFetchEnabled; -+ -+ if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0) -+ RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled")); -+ -+ FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm, -+ p_Memac->fmMacControllerDriver.macId, -+ &PortConfigured, -+ &PreFetchEnabled); -+ -+ if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured) -+ DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT")); -+ -+ if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled) -+ DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT")); -+ } -+ -+ fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac, -+ uint16_t pauseTime) -+{ -+ return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0); -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ fman_memac_set_wol(p_Memac->p_MemMap, en); -+ -+ return E_OK; -+} -+ -+/* .............................................................................. */ -+ -+static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+UNUSED(p_Memac); -+DBG(WARNING, ("mEMAC has 1588 always enabled!")); -+ -+ return E_OK; -+} -+ -+/* Counters handling */ -+/* ......................................................................... */ -+ -+static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER); -+ -+ p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64); -+ p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127); -+ p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255); -+ p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511); -+ p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023); -+ p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518); -+ p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X); -+/* */ -+ p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG); -+ p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR); -+ -+ p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP); -+ p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN); -+ -+ p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND); -+ p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR); -+/* Pause */ -+ p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF); -+ p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF); -+ -+/* MIB II */ -+ p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT); -+ p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA); -+ p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA); -+ p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA); -+ p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts -+ + p_Statistics->ifInMcastPkts -+ + p_Statistics->ifInBcastPkts; -+ p_Statistics->ifInDiscards = 0; -+ p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR); -+ -+ p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT); -+ p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA); -+ p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA); -+ p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA); -+ p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts -+ + p_Statistics->ifOutMcastPkts -+ + p_Statistics->ifOutBcastPkts; -+ p_Statistics->ifOutDiscards = 0; -+ p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacResetCounters (t_Handle h_Memac) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ fman_memac_reset_stat(p_Memac->p_MemMap); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) -+{ -+ t_Memac *p_Memac = (t_Memac *) h_Memac; -+ uint64_t ethAddr; -+ uint8_t paddrNum; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); -+ -+ if (ethAddr & GROUP_ADDRESS) -+ /* Multicast address has no effect in PADDR */ -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address")); -+ -+ /* Make sure no PADDR contains this address */ -+ for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++) -+ if (p_Memac->indAddrRegUsed[paddrNum]) -+ if (p_Memac->paddr[paddrNum] == ethAddr) -+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG); -+ -+ /* Find first unused PADDR */ -+ for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++) -+ if (!(p_Memac->indAddrRegUsed[paddrNum])) -+ { -+ /* mark this PADDR as used */ -+ p_Memac->indAddrRegUsed[paddrNum] = TRUE; -+ /* store address */ -+ p_Memac->paddr[paddrNum] = ethAddr; -+ -+ /* put in hardware */ -+ fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum); -+ p_Memac->numOfIndAddrInRegs++; -+ -+ return E_OK; -+ } -+ -+ /* No free PADDR */ -+ RETURN_ERROR(MAJOR, E_FULL, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) -+{ -+ t_Memac *p_Memac = (t_Memac *) h_Memac; -+ uint64_t ethAddr; -+ uint8_t paddrNum; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); -+ -+ /* Find used PADDR containing this address */ -+ for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++) -+ { -+ if ((p_Memac->indAddrRegUsed[paddrNum]) && -+ (p_Memac->paddr[paddrNum] == ethAddr)) -+ { -+ /* mark this PADDR as not used */ -+ p_Memac->indAddrRegUsed[paddrNum] = FALSE; -+ /* clear in hardware */ -+ fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum); -+ p_Memac->numOfIndAddrInRegs--; -+ -+ return E_OK; -+ } -+ } -+ -+ RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ *macId = p_Memac->macId; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+ -+static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ t_EthHashEntry *p_HashEntry; -+ uint32_t hash; -+ uint64_t ethAddr; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); -+ -+ if (!(ethAddr & GROUP_ADDRESS)) -+ /* Unicast addresses not supported in hash */ -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address")); -+ -+ hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK; -+ -+ /* Create element to be added to the driver hash table */ -+ p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry)); -+ p_HashEntry->addr = ethAddr; -+ INIT_LIST(&p_HashEntry->node); -+ -+ LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash])); -+ fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN)); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ t_EthHashEntry *p_HashEntry = NULL; -+ t_List *p_Pos; -+ uint32_t hash; -+ uint64_t ethAddr; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); -+ -+ hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK; -+ -+ LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash])) -+ { -+ p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos); -+ if (p_HashEntry->addr == ethAddr) -+ { -+ LIST_DelAndInit(&p_HashEntry->node); -+ XX_Free(p_HashEntry); -+ break; -+ } -+ } -+ if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash])) -+ fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN)); -+ -+ return E_OK; -+} -+ -+ -+/* ......................................................................... */ -+ -+static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ uint32_t bitMask = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ -+ GET_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_Memac->exceptions |= bitMask; -+ else -+ p_Memac->exceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0); -+ -+ return fman_memac_get_max_frame_len(p_Memac->p_MemMap); -+} -+ -+static t_Error MemacInitInternalPhy(t_Handle h_Memac) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ uint8_t i, phyAddr; -+ -+ if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII) -+ { -+ /* Configure internal SGMII PHY */ -+ if (p_Memac->enetMode & ENET_IF_SGMII_BASEX) -+ SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR); -+ else -+ SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR); -+ } -+ else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII) -+ { -+ /* Configure 4 internal SGMII PHYs */ -+ for (i = 0; i < 4; i++) -+ { -+ /* QSGMII PHY address occupies 3 upper bits of 5-bit -+ phyAddress; the lower 2 bits are used to extend -+ register address space and access each one of 4 -+ ports inside QSGMII. */ -+ phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i); -+ if (p_Memac->enetMode & ENET_IF_SGMII_BASEX) -+ SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr); -+ else -+ SetupSgmiiInternalPhy(p_Memac, phyAddr); -+ } -+ } -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+/* mEMAC Init & Free API */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+void *g_MemacRegs; -+static t_Error MemacInit(t_Handle h_Memac) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ struct memac_cfg *p_MemacDriverParam; -+ enum enet_interface enet_interface; -+ enum enet_speed enet_speed; -+ t_EnetAddr ethAddr; -+ e_FmMacType portType; -+ t_Error err; -+ bool slow_10g_if = FALSE; -+ if (p_Memac->macId == 3) /* This is a quick WA */ -+ g_MemacRegs = p_Memac->p_MemMap; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE); -+ -+ FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo); -+ if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 && -+ p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4) -+ slow_10g_if = TRUE; -+ -+ CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters); -+ -+ p_MemacDriverParam = p_Memac->p_MemacDriverParam; -+ -+ portType = -+ ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G); -+ -+ /* First, reset the MAC if desired. */ -+ if (p_MemacDriverParam->reset_on_init) -+ fman_memac_reset(p_Memac->p_MemMap); -+ -+ /* MAC Address */ -+ MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr); -+ fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0); -+ -+ enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode); -+ enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode); -+ -+ fman_memac_init(p_Memac->p_MemMap, -+ p_Memac->p_MemacDriverParam, -+ enet_interface, -+ enet_speed, -+ slow_10g_if, -+ p_Memac->exceptions); -+ -+#ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 -+ { -+ uint32_t tmpReg = 0; -+ -+ FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo); -+ /* check the FMAN version - the bug exists only in rev1 */ -+ if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) && -+ (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0)) -+ { -+ /* MAC strips CRC from received frames - this workaround should -+ decrease the likelihood of bug appearance -+ */ -+ tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config); -+ tmpReg &= ~CMD_CFG_CRC_FWD; -+ WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg); -+ /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/ -+ } -+ } -+#endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */ -+ -+ MemacInitInternalPhy(h_Memac); -+ -+ /* Max Frame Length */ -+ err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm, -+ portType, -+ p_Memac->fmMacControllerDriver.macId, -+ p_MemacDriverParam->max_frame_length); -+ if (err) -+ RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED")); -+ -+ p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE); -+ if (!p_Memac->p_MulticastAddrHash) -+ { -+ FreeInitResources(p_Memac); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED")); -+ } -+ -+ p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE); -+ if (!p_Memac->p_UnicastAddrHash) -+ { -+ FreeInitResources(p_Memac); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED")); -+ } -+ -+ FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm, -+ (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC, -+ p_Memac->macId, -+ e_FM_INTR_TYPE_ERR, -+ MemacErrException, -+ p_Memac); -+ -+ FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm, -+ (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC, -+ p_Memac->macId, -+ e_FM_INTR_TYPE_NORMAL, -+ MemacException, -+ p_Memac); -+ -+ XX_Free(p_MemacDriverParam); -+ p_Memac->p_MemacDriverParam = NULL; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error MemacFree(t_Handle h_Memac) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ -+ if (p_Memac->p_MemacDriverParam) -+ { -+ /* Called after config */ -+ XX_Free(p_Memac->p_MemacDriverParam); -+ p_Memac->p_MemacDriverParam = NULL; -+ } -+ else -+ /* Called after init */ -+ FreeInitResources(p_Memac); -+ -+ XX_Free(p_Memac); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver) -+{ -+ p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit; -+ p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */ -+ p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException; -+ -+ p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */ -+ p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous; -+ p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink; -+ p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL; -+ -+ p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable; -+ p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable; -+ p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames; -+ p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames; -+ p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters; -+ p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId; -+ p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL; -+ p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength; -+ -+ p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg; -+ p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg; -+} -+ -+ -+/*****************************************************************************/ -+/* mEMAC Config Main Entry */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+ -+t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam) -+{ -+ t_Memac *p_Memac; -+ struct memac_cfg *p_MemacDriverParam; -+ uintptr_t baseAddr; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL); -+ -+ baseAddr = p_FmMacParam->baseAddr; -+ /* Allocate memory for the mEMAC data structure */ -+ p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac)); -+ if (!p_Memac) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure")); -+ return NULL; -+ } -+ memset(p_Memac, 0, sizeof(t_Memac)); -+ InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver); -+ -+ /* Allocate memory for the mEMAC driver parameters data structure */ -+ p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg)); -+ if (!p_MemacDriverParam) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters")); -+ XX_Free(p_Memac); -+ return NULL; -+ } -+ memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg)); -+ -+ /* Plant parameter structure pointer */ -+ p_Memac->p_MemacDriverParam = p_MemacDriverParam; -+ -+ fman_memac_defconfig(p_MemacDriverParam); -+ -+ p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr); -+ -+ p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr); -+ p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET); -+ -+ p_Memac->enetMode = p_FmMacParam->enetMode; -+ p_Memac->macId = p_FmMacParam->macId; -+ p_Memac->exceptions = MEMAC_default_exceptions; -+ p_Memac->f_Exception = p_FmMacParam->f_Exception; -+ p_Memac->f_Event = p_FmMacParam->f_Event; -+ p_Memac->h_App = p_FmMacParam->h_App; -+ -+ return p_Memac; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h -@@ -0,0 +1,110 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File memac.h -+ -+ @Description FM Multirate Ethernet MAC (mEMAC) -+*//***************************************************************************/ -+#ifndef __MEMAC_H -+#define __MEMAC_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "list_ext.h" -+ -+#include "fsl_fman_memac_mii_acc.h" -+#include "fm_mac.h" -+#include "fsl_fman_memac.h" -+ -+ -+#define MEMAC_default_exceptions \ -+ ((uint32_t)(MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI)) -+ -+#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \ -+ case e_FM_MAC_EX_10G_1TX_ECC_ER: \ -+ bitMask = MEMAC_IMASK_TECC_ER; break; \ -+ case e_FM_MAC_EX_10G_RX_ECC_ER: \ -+ bitMask = MEMAC_IMASK_RECC_ER; break; \ -+ case e_FM_MAC_EX_TS_FIFO_ECC_ERR: \ -+ bitMask = MEMAC_IMASK_TSECC_ER; break; \ -+ case e_FM_MAC_EX_MAGIC_PACKET_INDICATION: \ -+ bitMask = MEMAC_IMASK_MGI; break; \ -+ default: bitMask = 0;break;} -+ -+ -+typedef struct -+{ -+ t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */ -+ t_Handle h_App; /**< Handle to the upper layer application */ -+ struct memac_regs *p_MemMap; /**< Pointer to MAC memory mapped registers */ -+ struct memac_mii_access_mem_map *p_MiiMemMap; /**< Pointer to MII memory mapped registers */ -+ uint64_t addr; /**< MAC address of device */ -+ e_EnetMode enetMode; /**< Ethernet physical interface */ -+ t_FmMacExceptionCallback *f_Exception; -+ int mdioIrq; -+ t_FmMacExceptionCallback *f_Event; -+ bool indAddrRegUsed[MEMAC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */ -+ uint64_t paddr[MEMAC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */ -+ uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */ -+ t_EthHash *p_MulticastAddrHash; /**< Pointer to driver's global address hash table */ -+ t_EthHash *p_UnicastAddrHash; /**< Pointer to driver's individual address hash table */ -+ bool debugMode; -+ uint8_t macId; -+ uint32_t exceptions; -+ struct memac_cfg *p_MemacDriverParam; -+} t_Memac; -+ -+ -+/* Internal PHY access */ -+#define PHY_MDIO_ADDR 0 -+ -+/* Internal PHY Registers - SGMII */ -+#define PHY_SGMII_CR_PHY_RESET 0x8000 -+#define PHY_SGMII_CR_RESET_AN 0x0200 -+#define PHY_SGMII_CR_DEF_VAL 0x1140 -+#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001 -+#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0 -+#define PHY_SGMII_IF_SPEED_GIGABIT 0x0008 -+#define PHY_SGMII_IF_MODE_AN 0x0002 -+#define PHY_SGMII_IF_MODE_SGMII 0x0001 -+#define PHY_SGMII_IF_MODE_1000X 0x0000 -+ -+ -+#define MEMAC_TO_MII_OFFSET 0x030 /* Offset from the MEM map to the MDIO mem map */ -+ -+t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t data); -+t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data); -+ -+ -+#endif /* __MEMAC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c -@@ -0,0 +1,78 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "fm_mac.h" -+#include "memac.h" -+#include "xx_ext.h" -+ -+#include "fm_common.h" -+#include "memac_mii_acc.h" -+ -+ -+/*****************************************************************************/ -+t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t data) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE); -+ -+ return (t_Error)fman_memac_mii_write_phy_reg(p_Memac->p_MiiMemMap, -+ phyAddr, -+ reg, -+ data, -+ (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode)); -+} -+ -+/*****************************************************************************/ -+t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t *p_Data) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE); -+ -+ return fman_memac_mii_read_phy_reg(p_Memac->p_MiiMemMap, -+ phyAddr, -+ reg, -+ p_Data, -+ (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode)); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h -@@ -0,0 +1,73 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#ifndef __MEMAC_MII_ACC_H -+#define __MEMAC_MII_ACC_H -+ -+#include "std_ext.h" -+ -+ -+/* MII Management Registers */ -+#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80 -+#define MDIO_CFG_CLK_DIV_SHIFT 7 -+#define MDIO_CFG_HOLD_MASK 0x0000001c -+#define MDIO_CFG_ENC45 0x00000040 -+#define MDIO_CFG_READ_ERR 0x00000002 -+#define MDIO_CFG_BSY 0x00000001 -+ -+#define MDIO_CTL_PHY_ADDR_SHIFT 5 -+#define MDIO_CTL_READ 0x00008000 -+ -+#define MDIO_DATA_BSY 0x80000000 -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+/*----------------------------------------------------*/ -+/* MII Configuration Control Memory Map Registers */ -+/*----------------------------------------------------*/ -+typedef struct t_MemacMiiAccessMemMap -+{ -+ volatile uint32_t mdio_cfg; /* 0x030 */ -+ volatile uint32_t mdio_ctrl; /* 0x034 */ -+ volatile uint32_t mdio_data; /* 0x038 */ -+ volatile uint32_t mdio_addr; /* 0x03c */ -+} t_MemacMiiAccessMemMap ; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+#endif /* __MEMAC_MII_ACC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c -@@ -0,0 +1,975 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File tgec.c -+ -+ @Description FM 10G MAC ... -+*//***************************************************************************/ -+ -+#include "std_ext.h" -+#include "string_ext.h" -+#include "error_ext.h" -+#include "xx_ext.h" -+#include "endian_ext.h" -+#include "debug_ext.h" -+#include "crc_mac_addr_ext.h" -+ -+#include "fm_common.h" -+#include "fsl_fman_tgec.h" -+#include "tgec.h" -+ -+ -+/*****************************************************************************/ -+/* Internal routines */ -+/*****************************************************************************/ -+ -+static t_Error CheckInitParameters(t_Tgec *p_Tgec) -+{ -+ if (ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed")); -+#if (FM_MAX_NUM_OF_10G_MACS > 0) -+ if (p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0")); -+#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */ -+ -+ if (p_Tgec->addr == 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address")); -+ if (!p_Tgec->f_Exception) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception")); -+ if (!p_Tgec->f_Event) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event")); -+#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002 -+ if (!p_Tgec->p_TgecDriverParam->no_length_check_enable) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!")); -+#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static uint32_t GetMacAddrHashCode(uint64_t ethAddr) -+{ -+ uint32_t crc; -+ -+ /* CRC calculation */ -+ GET_MAC_ADDR_CRC(ethAddr, crc); -+ -+ crc = GetMirror32(crc); -+ -+ return crc; -+} -+ -+/* ......................................................................... */ -+ -+static void TgecErrException(t_Handle h_Tgec) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ uint32_t event; -+ struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap; -+ -+ /* do not handle MDIO events */ -+ event = fman_tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL)); -+ event &= fman_tgec_get_interrupt_mask(p_TgecMemMap); -+ -+ fman_tgec_ack_event(p_TgecMemMap, event); -+ -+ if (event & TGEC_IMASK_REM_FAULT) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT); -+ if (event & TGEC_IMASK_LOC_FAULT) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT); -+ if (event & TGEC_IMASK_TX_ECC_ER) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER); -+ if (event & TGEC_IMASK_TX_FIFO_UNFL) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL); -+ if (event & TGEC_IMASK_TX_FIFO_OVFL) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL); -+ if (event & TGEC_IMASK_TX_ER) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER); -+ if (event & TGEC_IMASK_RX_FIFO_OVFL) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL); -+ if (event & TGEC_IMASK_RX_ECC_ER) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER); -+ if (event & TGEC_IMASK_RX_JAB_FRM) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM); -+ if (event & TGEC_IMASK_RX_OVRSZ_FRM) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM); -+ if (event & TGEC_IMASK_RX_RUNT_FRM) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM); -+ if (event & TGEC_IMASK_RX_FRAG_FRM) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM); -+ if (event & TGEC_IMASK_RX_LEN_ER) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER); -+ if (event & TGEC_IMASK_RX_CRC_ER) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER); -+ if (event & TGEC_IMASK_RX_ALIGN_ER) -+ p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER); -+} -+ -+/* ......................................................................... */ -+ -+static void TgecException(t_Handle h_Tgec) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ uint32_t event; -+ struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap; -+ -+ /* handle only MDIO events */ -+ event = fman_tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL)); -+ event &= fman_tgec_get_interrupt_mask(p_TgecMemMap); -+ -+ fman_tgec_ack_event(p_TgecMemMap, event); -+ -+ if (event & TGEC_IMASK_MDIO_SCAN_EVENT) -+ p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO); -+ if (event & TGEC_IMASK_MDIO_CMD_CMPL) -+ p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL); -+} -+ -+/* ......................................................................... */ -+ -+static void FreeInitResources(t_Tgec *p_Tgec) -+{ -+ if (p_Tgec->mdioIrq != NO_IRQ) -+ { -+ XX_DisableIntr(p_Tgec->mdioIrq); -+ XX_FreeIntr(p_Tgec->mdioIrq); -+ } -+ -+ FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR); -+ -+ /* release the driver's group hash table */ -+ FreeHashTable(p_Tgec->p_MulticastAddrHash); -+ p_Tgec->p_MulticastAddrHash = NULL; -+ -+ /* release the driver's individual hash table */ -+ FreeHashTable(p_Tgec->p_UnicastAddrHash); -+ p_Tgec->p_UnicastAddrHash = NULL; -+} -+ -+ -+/*****************************************************************************/ -+/* 10G MAC API routines */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+ -+static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ fman_tgec_enable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX)); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ fman_tgec_disable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX)); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ fman_tgec_set_promiscuous(p_Tgec->p_MemMap, newVal); -+ -+ return E_OK; -+} -+ -+ -+/*****************************************************************************/ -+/* Tgec Configs modification functions */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+ -+static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ p_Tgec->p_TgecDriverParam->loopback_enable = newVal; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ p_Tgec->p_TgecDriverParam->wan_mode_enable = newVal; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ p_Tgec->p_TgecDriverParam->max_frame_length = newVal; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ UNUSED(newVal); -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ p_Tgec->p_TgecDriverParam->no_length_check_enable = !newVal; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ uint32_t bitMask = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ GET_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_Tgec->exceptions |= bitMask; -+ else -+ p_Tgec->exceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ return E_OK; -+} -+ -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+/* ......................................................................... */ -+ -+static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ p_Tgec->p_TgecDriverParam->skip_fman11_workaround = TRUE; -+ -+ return E_OK; -+} -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ -+ -+/*****************************************************************************/ -+/* Tgec Run Time API functions */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+/* backward compatibility. will be removed in the future. */ -+static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime); -+ -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecSetTxPauseFrames(t_Handle h_Tgec, -+ uint8_t priority, -+ uint16_t pauseTime, -+ uint16_t threshTime) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ UNUSED(priority); UNUSED(threshTime); -+ -+ fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ fman_tgec_set_rx_ignore_pause_frames(p_Tgec->p_MemMap, en); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ struct tgec_regs *p_TgecMemMap; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER); -+ -+ p_TgecMemMap = p_Tgec->p_MemMap; -+ -+ p_Statistics->eStatPkts64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64); -+ p_Statistics->eStatPkts65to127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127); -+ p_Statistics->eStatPkts128to255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255); -+ p_Statistics->eStatPkts256to511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511); -+ p_Statistics->eStatPkts512to1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023); -+ p_Statistics->eStatPkts1024to1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518); -+ p_Statistics->eStatPkts1519to1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X); -+/* */ -+ p_Statistics->eStatFragments = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG); -+ p_Statistics->eStatJabbers = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR); -+ -+ p_Statistics->eStatsDropEvents = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP); -+ p_Statistics->eStatCRCAlignErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN); -+ -+ p_Statistics->eStatUndersizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND); -+ p_Statistics->eStatOversizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR); -+/* Pause */ -+ p_Statistics->reStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF); -+ p_Statistics->teStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF); -+ -+/* MIB II */ -+ p_Statistics->ifInOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT); -+ p_Statistics->ifInUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA); -+ p_Statistics->ifInMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA); -+ p_Statistics->ifInBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RBCA); -+ p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts -+ + p_Statistics->ifInMcastPkts -+ + p_Statistics->ifInBcastPkts; -+ p_Statistics->ifInDiscards = 0; -+ p_Statistics->ifInErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR); -+ -+ p_Statistics->ifOutOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT); -+ p_Statistics->ifOutUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA); -+ p_Statistics->ifOutMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA); -+ p_Statistics->ifOutBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TBCA); -+ p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts -+ + p_Statistics->ifOutMcastPkts -+ + p_Statistics->ifOutBcastPkts; -+ p_Statistics->ifOutDiscards = 0; -+ p_Statistics->ifOutErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TERR); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 1); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 0); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ p_Tgec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr); -+ fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)(*p_EnetAddr)); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecResetCounters (t_Handle h_Tgec) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ fman_tgec_reset_stat(p_Tgec->p_MemMap); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *) h_Tgec; -+ uint64_t ethAddr; -+ uint8_t paddrNum; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); -+ -+ if (ethAddr & GROUP_ADDRESS) -+ /* Multicast address has no effect in PADDR */ -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address")); -+ -+ /* Make sure no PADDR contains this address */ -+ for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++) -+ if (p_Tgec->indAddrRegUsed[paddrNum]) -+ if (p_Tgec->paddr[paddrNum] == ethAddr) -+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG); -+ -+ /* Find first unused PADDR */ -+ for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++) -+ { -+ if (!(p_Tgec->indAddrRegUsed[paddrNum])) -+ { -+ /* mark this PADDR as used */ -+ p_Tgec->indAddrRegUsed[paddrNum] = TRUE; -+ /* store address */ -+ p_Tgec->paddr[paddrNum] = ethAddr; -+ -+ /* put in hardware */ -+ fman_tgec_add_addr_in_paddr(p_Tgec->p_MemMap, (uint8_t*)(*p_EthAddr)/* , paddrNum */); -+ p_Tgec->numOfIndAddrInRegs++; -+ -+ return E_OK; -+ } -+ } -+ -+ /* No free PADDR */ -+ RETURN_ERROR(MAJOR, E_FULL, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *) h_Tgec; -+ uint64_t ethAddr; -+ uint8_t paddrNum; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); -+ -+ /* Find used PADDR containing this address */ -+ for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++) -+ { -+ if ((p_Tgec->indAddrRegUsed[paddrNum]) && -+ (p_Tgec->paddr[paddrNum] == ethAddr)) -+ { -+ /* mark this PADDR as not used */ -+ p_Tgec->indAddrRegUsed[paddrNum] = FALSE; -+ /* clear in hardware */ -+ fman_tgec_clear_addr_in_paddr(p_Tgec->p_MemMap /*, paddrNum */); -+ p_Tgec->numOfIndAddrInRegs--; -+ -+ return E_OK; -+ } -+ } -+ -+ RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ t_EthHashEntry *p_HashEntry; -+ uint32_t crc; -+ uint32_t hash; -+ uint64_t ethAddr; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr); -+ -+ if (!(ethAddr & GROUP_ADDRESS)) -+ /* Unicast addresses not supported in hash */ -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address")); -+ -+ /* CRC calculation */ -+ crc = GetMacAddrHashCode(ethAddr); -+ -+ hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */ -+ -+ /* Create element to be added to the driver hash table */ -+ p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry)); -+ p_HashEntry->addr = ethAddr; -+ INIT_LIST(&p_HashEntry->node); -+ -+ LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash])); -+ fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash | TGEC_HASH_MCAST_EN)); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ t_EthHashEntry *p_HashEntry = NULL; -+ t_List *p_Pos; -+ uint32_t crc; -+ uint32_t hash; -+ uint64_t ethAddr; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ ethAddr = ((*(uint64_t *)p_EthAddr) >> 16); -+ -+ /* CRC calculation */ -+ crc = GetMacAddrHashCode(ethAddr); -+ -+ hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */ -+ -+ LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash])) -+ { -+ p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos); -+ if (p_HashEntry->addr == ethAddr) -+ { -+ LIST_DelAndInit(&p_HashEntry->node); -+ XX_Free(p_HashEntry); -+ break; -+ } -+ } -+ if (LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash])) -+ fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash & ~TGEC_HASH_MCAST_EN)); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ UNUSED(p_Tgec); -+ UNUSED(macId); -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported")); -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ *macVersion = fman_tgec_get_revision(p_Tgec->p_MemMap); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ uint32_t bitMask = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ -+ GET_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_Tgec->exceptions |= bitMask; -+ else -+ p_Tgec->exceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ if (enable) -+ fman_tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask); -+ else -+ fman_tgec_disable_interrupt(p_Tgec->p_MemMap, bitMask); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE, 0); -+ -+ return fman_tgec_get_max_frame_len(p_Tgec->p_MemMap); -+} -+ -+/* ......................................................................... */ -+ -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec) -+{ -+ t_Error err; -+ -+#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0) -+ XX_Print("Applying 10G TX ECC workaround (10GMAC-A004) ... "); -+#endif /* (DEBUG_ERRORS > 0) */ -+ /* enable and set promiscuous */ -+ fman_tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE); -+ fman_tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE); -+ err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId); -+ /* disable */ -+ fman_tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE); -+ fman_tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE); -+ fman_tgec_reset_stat(p_Tgec->p_MemMap); -+ fman_tgec_ack_event(p_Tgec->p_MemMap, 0xffffffff); -+#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0) -+ if (err) -+ XX_Print("FAILED!\n"); -+ else -+ XX_Print("done.\n"); -+#endif /* (DEBUG_ERRORS > 0) */ -+ -+ return err; -+} -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ -+/*****************************************************************************/ -+/* FM Init & Free API */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+ -+static t_Error TgecInit(t_Handle h_Tgec) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ struct tgec_cfg *p_TgecDriverParam; -+ t_EnetAddr ethAddr; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_Tgec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE); -+ -+ FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &p_Tgec->fmMacControllerDriver.fmRevInfo); -+ CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters); -+ -+ p_TgecDriverParam = p_Tgec->p_TgecDriverParam; -+ -+ MAKE_ENET_ADDR_FROM_UINT64(p_Tgec->addr, ethAddr); -+ fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)ethAddr); -+ -+ /* interrupts */ -+#ifdef FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 -+ { -+ if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev <=2) -+ p_Tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT | TGEC_IMASK_LOC_FAULT); -+ } -+#endif /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 */ -+ -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+ if (!p_Tgec->p_TgecDriverParam->skip_fman11_workaround && -+ ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK)) -+ { -+ FreeInitResources(p_Tgec); -+ REPORT_ERROR(MINOR, err, ("TgecTxEccWorkaround FAILED")); -+ } -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ -+ err = fman_tgec_init(p_Tgec->p_MemMap, p_TgecDriverParam, p_Tgec->exceptions); -+ if (err) -+ { -+ FreeInitResources(p_Tgec); -+ RETURN_ERROR(MAJOR, err, ("This TGEC version does not support the required i/f mode")); -+ } -+ -+ /* Max Frame Length */ -+ err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm, -+ e_FM_MAC_10G, -+ p_Tgec->fmMacControllerDriver.macId, -+ p_TgecDriverParam->max_frame_length); -+ if (err != E_OK) -+ { -+ FreeInitResources(p_Tgec); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+/* we consider having no IPC a non crasher... */ -+ -+#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 -+ if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2) -+ fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(p_Tgec->p_MemMap); -+#endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */ -+ -+ p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE); -+ if (!p_Tgec->p_MulticastAddrHash) -+ { -+ FreeInitResources(p_Tgec); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED")); -+ } -+ -+ p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE); -+ if (!p_Tgec->p_UnicastAddrHash) -+ { -+ FreeInitResources(p_Tgec); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED")); -+ } -+ -+ FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, -+ e_FM_MOD_10G_MAC, -+ p_Tgec->macId, -+ e_FM_INTR_TYPE_ERR, -+ TgecErrException, -+ p_Tgec); -+ if (p_Tgec->mdioIrq != NO_IRQ) -+ { -+ XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec); -+ XX_EnableIntr(p_Tgec->mdioIrq); -+ } -+ -+ XX_Free(p_TgecDriverParam); -+ p_Tgec->p_TgecDriverParam = NULL; -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static t_Error TgecFree(t_Handle h_Tgec) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ -+ if (p_Tgec->p_TgecDriverParam) -+ { -+ /* Called after config */ -+ XX_Free(p_Tgec->p_TgecDriverParam); -+ p_Tgec->p_TgecDriverParam = NULL; -+ } -+ else -+ /* Called after init */ -+ FreeInitResources(p_Tgec); -+ -+ XX_Free(p_Tgec); -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ -+static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver) -+{ -+ p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit; -+ p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ConfigWan = TgecConfigWan; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = NULL; /* TGEC always works with pad+crc */ -+ p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */ -+ p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException; -+ p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL; -+ -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+ p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround; -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetException = TgecSetExcpetion; -+ -+ p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = TgecEnable1588TimeStamp; -+ p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = TgecDisable1588TimeStamp; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous; -+ p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL; -+ p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = NULL; -+ p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL; -+ -+ p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable; -+ p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable; -+ p_FmMacControllerDriver->f_FM_MAC_Resume = NULL; -+ -+ p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause; -+ p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = TgecSetTxPauseFrames; -+ p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters; -+ p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics; -+ -+ p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = TgecDelHashMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = TgecAddExactMatchMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = TgecDelExactMatchMacAddress; -+ p_FmMacControllerDriver->f_FM_MAC_GetId = TgecGetId; -+ p_FmMacControllerDriver->f_FM_MAC_GetVersion = TgecGetVersion; -+ p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = TgecGetMaxFrameLength; -+ -+ p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg; -+ p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg; -+} -+ -+ -+/*****************************************************************************/ -+/* Tgec Config Main Entry */ -+/*****************************************************************************/ -+ -+/* ......................................................................... */ -+ -+t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam) -+{ -+ t_Tgec *p_Tgec; -+ struct tgec_cfg *p_TgecDriverParam; -+ uintptr_t baseAddr; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL); -+ -+ baseAddr = p_FmMacParam->baseAddr; -+ /* allocate memory for the UCC GETH data structure. */ -+ p_Tgec = (t_Tgec *)XX_Malloc(sizeof(t_Tgec)); -+ if (!p_Tgec) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure")); -+ return NULL; -+ } -+ memset(p_Tgec, 0, sizeof(t_Tgec)); -+ InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver); -+ -+ /* allocate memory for the 10G MAC driver parameters data structure. */ -+ p_TgecDriverParam = (struct tgec_cfg *) XX_Malloc(sizeof(struct tgec_cfg)); -+ if (!p_TgecDriverParam) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters")); -+ XX_Free(p_Tgec); -+ return NULL; -+ } -+ memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg)); -+ -+ /* Plant parameter structure pointer */ -+ p_Tgec->p_TgecDriverParam = p_TgecDriverParam; -+ -+ fman_tgec_defconfig(p_TgecDriverParam); -+ -+ p_Tgec->p_MemMap = (struct tgec_regs *)UINT_TO_PTR(baseAddr); -+ p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET); -+ p_Tgec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr); -+ p_Tgec->enetMode = p_FmMacParam->enetMode; -+ p_Tgec->macId = p_FmMacParam->macId; -+ p_Tgec->exceptions = DEFAULT_exceptions; -+ p_Tgec->mdioIrq = p_FmMacParam->mdioIrq; -+ p_Tgec->f_Exception = p_FmMacParam->f_Exception; -+ p_Tgec->f_Event = p_FmMacParam->f_Event; -+ p_Tgec->h_App = p_FmMacParam->h_App; -+ -+ return p_Tgec; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h -@@ -0,0 +1,151 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File tgec.h -+ -+ @Description FM 10G MAC ... -+*//***************************************************************************/ -+#ifndef __TGEC_H -+#define __TGEC_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "list_ext.h" -+#include "enet_ext.h" -+ -+#include "tgec_mii_acc.h" -+#include "fm_mac.h" -+ -+ -+#define DEFAULT_exceptions \ -+ ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \ -+ TGEC_IMASK_REM_FAULT | \ -+ TGEC_IMASK_LOC_FAULT | \ -+ TGEC_IMASK_TX_ECC_ER | \ -+ TGEC_IMASK_TX_FIFO_UNFL | \ -+ TGEC_IMASK_TX_FIFO_OVFL | \ -+ TGEC_IMASK_TX_ER | \ -+ TGEC_IMASK_RX_FIFO_OVFL | \ -+ TGEC_IMASK_RX_ECC_ER | \ -+ TGEC_IMASK_RX_JAB_FRM | \ -+ TGEC_IMASK_RX_OVRSZ_FRM | \ -+ TGEC_IMASK_RX_RUNT_FRM | \ -+ TGEC_IMASK_RX_FRAG_FRM | \ -+ TGEC_IMASK_RX_CRC_ER | \ -+ TGEC_IMASK_RX_ALIGN_ER)) -+ -+#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \ -+ case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \ -+ bitMask = TGEC_IMASK_MDIO_SCAN_EVENT ; break; \ -+ case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \ -+ bitMask = TGEC_IMASK_MDIO_CMD_CMPL ; break; \ -+ case e_FM_MAC_EX_10G_REM_FAULT: \ -+ bitMask = TGEC_IMASK_REM_FAULT ; break; \ -+ case e_FM_MAC_EX_10G_LOC_FAULT: \ -+ bitMask = TGEC_IMASK_LOC_FAULT ; break; \ -+ case e_FM_MAC_EX_10G_1TX_ECC_ER: \ -+ bitMask = TGEC_IMASK_TX_ECC_ER ; break; \ -+ case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \ -+ bitMask = TGEC_IMASK_TX_FIFO_UNFL ; break; \ -+ case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \ -+ bitMask = TGEC_IMASK_TX_FIFO_OVFL ; break; \ -+ case e_FM_MAC_EX_10G_TX_ER: \ -+ bitMask = TGEC_IMASK_TX_ER ; break; \ -+ case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \ -+ bitMask = TGEC_IMASK_RX_FIFO_OVFL ; break; \ -+ case e_FM_MAC_EX_10G_RX_ECC_ER: \ -+ bitMask = TGEC_IMASK_RX_ECC_ER ; break; \ -+ case e_FM_MAC_EX_10G_RX_JAB_FRM: \ -+ bitMask = TGEC_IMASK_RX_JAB_FRM ; break; \ -+ case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \ -+ bitMask = TGEC_IMASK_RX_OVRSZ_FRM ; break; \ -+ case e_FM_MAC_EX_10G_RX_RUNT_FRM: \ -+ bitMask = TGEC_IMASK_RX_RUNT_FRM ; break; \ -+ case e_FM_MAC_EX_10G_RX_FRAG_FRM: \ -+ bitMask = TGEC_IMASK_RX_FRAG_FRM ; break; \ -+ case e_FM_MAC_EX_10G_RX_LEN_ER: \ -+ bitMask = TGEC_IMASK_RX_LEN_ER ; break; \ -+ case e_FM_MAC_EX_10G_RX_CRC_ER: \ -+ bitMask = TGEC_IMASK_RX_CRC_ER ; break; \ -+ case e_FM_MAC_EX_10G_RX_ALIGN_ER: \ -+ bitMask = TGEC_IMASK_RX_ALIGN_ER ; break; \ -+ default: bitMask = 0;break;} -+ -+#define MAX_PACKET_ALIGNMENT 31 -+#define MAX_INTER_PACKET_GAP 0x7f -+#define MAX_INTER_PALTERNATE_BEB 0x0f -+#define MAX_RETRANSMISSION 0x0f -+#define MAX_COLLISION_WINDOW 0x03ff -+ -+#define TGEC_NUM_OF_PADDRS 1 /* number of pattern match registers (entries) */ -+ -+#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */ -+ -+#define HASH_TABLE_SIZE 512 /* Hash table size (= 32 bits * 8 regs) */ -+ -+#define TGEC_TO_MII_OFFSET 0x1030 /* Offset from the MEM map to the MDIO mem map */ -+ -+/* 10-gigabit Ethernet MAC Controller ID (10GEC_ID) */ -+#define TGEC_ID_ID 0xffff0000 -+#define TGEC_ID_MAC_VERSION 0x0000FF00 -+#define TGEC_ID_MAC_REV 0x000000ff -+ -+ -+typedef struct { -+ t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */ -+ t_Handle h_App; /**< Handle to the upper layer application */ -+ struct tgec_regs *p_MemMap; /**< pointer to 10G memory mapped registers. */ -+ t_TgecMiiAccessMemMap *p_MiiMemMap; /**< pointer to MII memory mapped registers. */ -+ uint64_t addr; /**< MAC address of device; */ -+ e_EnetMode enetMode; /**< Ethernet physical interface */ -+ t_FmMacExceptionCallback *f_Exception; -+ int mdioIrq; -+ t_FmMacExceptionCallback *f_Event; -+ bool indAddrRegUsed[TGEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */ -+ uint64_t paddr[TGEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */ -+ uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */ -+ t_EthHash *p_MulticastAddrHash; /**< pointer to driver's global address hash table */ -+ t_EthHash *p_UnicastAddrHash; /**< pointer to driver's individual address hash table */ -+ bool debugMode; -+ uint8_t macId; -+ uint32_t exceptions; -+ struct tgec_cfg *p_TgecDriverParam; -+} t_Tgec; -+ -+ -+t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t data); -+t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data); -+ -+ -+#endif /* __TGEC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c -@@ -0,0 +1,139 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "fm_mac.h" -+#include "tgec.h" -+#include "xx_ext.h" -+ -+#include "fm_common.h" -+ -+ -+/*****************************************************************************/ -+t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t data) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ t_TgecMiiAccessMemMap *p_MiiAccess; -+ uint32_t cfgStatusReg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE); -+ -+ p_MiiAccess = p_Tgec->p_MiiMemMap; -+ -+ /* Configure MII */ -+ cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status); -+ cfgStatusReg &= ~MIIMCOM_DIV_MASK; -+ /* (one half of fm clock => 2.5Mhz) */ -+ cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT); -+ WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg); -+ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY) -+ XX_UDelay (1); -+ -+ WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr); -+ -+ WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg); -+ -+ CORE_MemoryBarrier(); -+ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY) -+ XX_UDelay (1); -+ -+ WRITE_UINT32(p_MiiAccess->mdio_data, data); -+ -+ CORE_MemoryBarrier(); -+ -+ while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY) -+ XX_UDelay (1); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t *p_Data) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ t_TgecMiiAccessMemMap *p_MiiAccess; -+ uint32_t cfgStatusReg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE); -+ -+ p_MiiAccess = p_Tgec->p_MiiMemMap; -+ -+ /* Configure MII */ -+ cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status); -+ cfgStatusReg &= ~MIIMCOM_DIV_MASK; -+ /* (one half of fm clock => 2.5Mhz) */ -+ cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT); -+ WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg); -+ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY) -+ XX_UDelay (1); -+ -+ WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr); -+ -+ WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg); -+ -+ CORE_MemoryBarrier(); -+ -+ while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY) -+ XX_UDelay (1); -+ -+ WRITE_UINT32(p_MiiAccess->mdio_command, (uint32_t)(phyAddr | MIIMCOM_READ_CYCLE)); -+ -+ CORE_MemoryBarrier(); -+ -+ while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY) -+ XX_UDelay (1); -+ -+ *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data); -+ -+ cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status); -+ -+ if (cfgStatusReg & MIIMIND_READ_ERROR) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, -+ ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfgStatusReg 0x%x", -+ ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfgStatusReg)); -+ -+ return E_OK; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h -@@ -0,0 +1,80 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#ifndef __TGEC_MII_ACC_H -+#define __TGEC_MII_ACC_H -+ -+#include "std_ext.h" -+ -+ -+/* MII Management Command Register */ -+#define MIIMCOM_READ_POST_INCREMENT 0x00004000 -+#define MIIMCOM_READ_CYCLE 0x00008000 -+#define MIIMCOM_SCAN_CYCLE 0x00000800 -+#define MIIMCOM_PREAMBLE_DISABLE 0x00000400 -+ -+#define MIIMCOM_MDIO_HOLD_1_REG_CLK 0 -+#define MIIMCOM_MDIO_HOLD_2_REG_CLK 1 -+#define MIIMCOM_MDIO_HOLD_3_REG_CLK 2 -+#define MIIMCOM_MDIO_HOLD_4_REG_CLK 3 -+ -+#define MIIMCOM_DIV_MASK 0x0000ff00 -+#define MIIMCOM_DIV_SHIFT 8 -+ -+/* MII Management Indicator Register */ -+#define MIIMIND_BUSY 0x00000001 -+#define MIIMIND_READ_ERROR 0x00000002 -+ -+#define MIIDATA_BUSY 0x80000000 -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+/*----------------------------------------------------*/ -+/* MII Configuration Control Memory Map Registers */ -+/*----------------------------------------------------*/ -+typedef _Packed struct t_TgecMiiAccessMemMap -+{ -+ volatile uint32_t mdio_cfg_status; /* 0x030 */ -+ volatile uint32_t mdio_command; /* 0x034 */ -+ volatile uint32_t mdio_data; /* 0x038 */ -+ volatile uint32_t mdio_regaddr; /* 0x03c */ -+} _PackedType t_TgecMiiAccessMemMap ; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+#endif /* __TGEC_MII_ACC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile -@@ -0,0 +1,15 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc -+ -+ccflags-y += -I$(NCSW_FM_INC) -+ -+obj-y += fsl-ncsw-macsec.o -+ -+fsl-ncsw-macsec-objs := fm_macsec.o fm_macsec_guest.o fm_macsec_master.o fm_macsec_secy.o ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c -@@ -0,0 +1,237 @@ -+/* -+ * Copyright 2008-2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+/****************************************************************************** -+ -+ @File fm_macsec.c -+ -+ @Description FM MACSEC driver routines implementation. -+*//***************************************************************************/ -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "xx_ext.h" -+#include "string_ext.h" -+#include "sprint_ext.h" -+#include "debug_ext.h" -+ -+#include "fm_macsec.h" -+ -+ -+/****************************************/ -+/* API Init unit functions */ -+/****************************************/ -+t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmMacsecParam, E_INVALID_HANDLE, NULL); -+ -+ if (p_FmMacsecParam->guestMode) -+ p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_GUEST_Config(p_FmMacsecParam); -+ else -+ p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_MASTER_Config(p_FmMacsecParam); -+ -+ if (!p_FmMacsecControllerDriver) -+ return NULL; -+ -+ return (t_Handle)p_FmMacsecControllerDriver; -+} -+ -+t_Error FM_MACSEC_Init(t_Handle h_FmMacsec) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_Init) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_Init(h_FmMacsec); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_Free(t_Handle h_FmMacsec) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_Free) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_Free(h_FmMacsec); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment(h_FmMacsec, treatMode); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment(h_FmMacsec, deliverUncontrolled); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(h_FmMacsec, discardUncontrolled); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment(h_FmMacsec, treatMode); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold(h_FmMacsec, pnExhThr); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable(h_FmMacsec); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI(h_FmMacsec); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException(h_FmMacsec, exception, enable); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision(h_FmMacsec, p_MacsecRevision); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+ -+t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_Enable) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_Enable(h_FmMacsec); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_Disable) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_Disable(h_FmMacsec); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable) -+{ -+ t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecControllerDriver->f_FM_MACSEC_SetException) -+ return p_FmMacsecControllerDriver->f_FM_MACSEC_SetException(h_FmMacsec, exception, enable); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h -@@ -0,0 +1,203 @@ -+/* -+ * Copyright 2008-2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File fm_macsec.h -+ -+ @Description FM MACSEC internal structures and definitions. -+*//***************************************************************************/ -+#ifndef __FM_MACSEC_H -+#define __FM_MACSEC_H -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "fm_macsec_ext.h" -+ -+#include "fm_common.h" -+ -+ -+#define __ERR_MODULE__ MODULE_FM_MACSEC -+ -+ -+typedef struct -+{ -+ t_Error (*f_FM_MACSEC_Init) (t_Handle h_FmMacsec); -+ t_Error (*f_FM_MACSEC_Free) (t_Handle h_FmMacsec); -+ -+ t_Error (*f_FM_MACSEC_ConfigUnknownSciFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode); -+ t_Error (*f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled); -+ t_Error (*f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) (t_Handle h_FmMacsec, bool discardUncontrolled); -+ t_Error (*f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled); -+ t_Error (*f_FM_MACSEC_ConfigUntagFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode); -+ t_Error (*f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled); -+ t_Error (*f_FM_MACSEC_ConfigPnExhaustionThreshold) (t_Handle h_FmMacsec, uint32_t pnExhThr); -+ t_Error (*f_FM_MACSEC_ConfigKeysUnreadable) (t_Handle h_FmMacsec); -+ t_Error (*f_FM_MACSEC_ConfigSectagWithoutSCI) (t_Handle h_FmMacsec); -+ t_Error (*f_FM_MACSEC_ConfigException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable); -+ -+ t_Error (*f_FM_MACSEC_GetRevision) (t_Handle h_FmMacsec, uint32_t *p_MacsecRevision); -+ t_Error (*f_FM_MACSEC_Enable) (t_Handle h_FmMacsec); -+ t_Error (*f_FM_MACSEC_Disable) (t_Handle h_FmMacsec); -+ t_Error (*f_FM_MACSEC_SetException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable); -+ -+} t_FmMacsecControllerDriver; -+ -+t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam); -+t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParams); -+ -+/***********************************************************************/ -+/* MACSEC internal routines */ -+/***********************************************************************/ -+ -+/**************************************************************************//** -+ -+ @Group FM_MACSEC_InterModule_grp FM MACSEC Inter-Module Unit -+ -+ @Description FM MACSEC Inter Module functions - -+ These are not User API routines but routines that may be called -+ from other modules. This will be the case in a single core environment, -+ where instead of using the XX messaging mechanism, the routines may be -+ called from other modules. In a multicore environment, the other modules may -+ be run by other cores and therefore these routines may not be called directly. -+ -+ @{ -+*//***************************************************************************/ -+ -+#define MAX_NUM_OF_SA_PER_SC 4 -+ -+typedef enum -+{ -+ e_SC_RX = 0, -+ e_SC_TX -+} e_ScType; -+ -+typedef enum -+{ -+ e_SC_SA_A = 0, -+ e_SC_SA_B , -+ e_SC_SA_C , -+ e_SC_SA_D -+} e_ScSaId; -+ -+typedef struct -+{ -+ uint32_t scId; -+ macsecSCI_t sci; -+ bool replayProtect; -+ uint32_t replayWindow; -+ e_FmMacsecValidFrameBehavior validateFrames; -+ uint16_t confidentialityOffset; -+ e_FmMacsecSecYCipherSuite cipherSuite; -+} t_RxScParams; -+ -+typedef struct -+{ -+ uint32_t scId; -+ macsecSCI_t sci; -+ bool protectFrames; -+ e_FmMacsecSciInsertionMode sciInsertionMode; -+ bool confidentialityEnable; -+ uint16_t confidentialityOffset; -+ e_FmMacsecSecYCipherSuite cipherSuite; -+} t_TxScParams; -+ -+typedef enum e_FmMacsecGlobalExceptions { -+ e_FM_MACSEC_EX_TX_SC, /**< Tx Sc 0 frame discarded error. */ -+ e_FM_MACSEC_EX_ECC /**< MACSEC memory ECC multiple-bit error. */ -+} e_FmMacsecGlobalExceptions; -+ -+typedef enum e_FmMacsecGlobalEvents { -+ e_FM_MACSEC_EV_TX_SC_NEXT_PN /**< Tx Sc 0 Next Pn exhaustion threshold reached. */ -+} e_FmMacsecGlobalEvents; -+ -+/**************************************************************************//** -+ @Description Enum for inter-module interrupts registration -+*//***************************************************************************/ -+typedef enum e_FmMacsecEventModules{ -+ e_FM_MACSEC_MOD_SC_TX, -+ e_FM_MACSEC_MOD_DUMMY_LAST -+} e_FmMacsecEventModules; -+ -+typedef enum e_FmMacsecInterModuleEvent { -+ e_FM_MACSEC_EV_SC_TX, -+ e_FM_MACSEC_EV_ERR_SC_TX, -+ e_FM_MACSEC_EV_DUMMY_LAST -+} e_FmMacsecInterModuleEvent; -+ -+#define NUM_OF_INTER_MODULE_EVENTS (NUM_OF_TX_SC * 2) -+ -+#define GET_MACSEC_MODULE_EVENT(mod, id, intrType, event) \ -+ switch(mod){ \ -+ case e_FM_MACSEC_MOD_SC_TX: \ -+ event = (intrType == e_FM_INTR_TYPE_ERR) ? \ -+ e_FM_MACSEC_EV_ERR_SC_TX: \ -+ e_FM_MACSEC_EV_SC_TX; \ -+ event += (uint8_t)(2 * id);break; \ -+ break; \ -+ default:event = e_FM_MACSEC_EV_DUMMY_LAST; \ -+ break;} -+ -+void FmMacsecRegisterIntr(t_Handle h_FmMacsec, -+ e_FmMacsecEventModules module, -+ uint8_t modId, -+ e_FmIntrType intrType, -+ void (*f_Isr) (t_Handle h_Arg, uint32_t id), -+ t_Handle h_Arg); -+ -+void FmMacsecUnregisterIntr(t_Handle h_FmMacsec, -+ e_FmMacsecEventModules module, -+ uint8_t modId, -+ e_FmIntrType intrType); -+ -+t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds); -+t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds); -+t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams); -+t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId); -+t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_RxScParams); -+t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId); -+t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key); -+t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key); -+t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId); -+t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId); -+t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive); -+t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN); -+t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN); -+t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an); -+t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An); -+t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable); -+ -+t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable); -+t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable); -+ -+ -+ -+#endif /* __FM_MACSEC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c -@@ -0,0 +1,59 @@ -+/* -+ * Copyright 2008-2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File fm_macsec.c -+ -+ @Description FM MACSEC driver routines implementation. -+*//***************************************************************************/ -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "xx_ext.h" -+#include "string_ext.h" -+#include "sprint_ext.h" -+#include "debug_ext.h" -+#include "fm_macsec.h" -+ -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+ -+/****************************************/ -+/* API Init unit functions */ -+/****************************************/ -+t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam) -+{ -+ UNUSED(p_FmMacsecParam); -+ return NULL; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c -@@ -0,0 +1,1031 @@ -+/* -+ * Copyright 2008-2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File fm_macsec.c -+ -+ @Description FM MACSEC driver routines implementation. -+*//***************************************************************************/ -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "xx_ext.h" -+#include "string_ext.h" -+#include "sprint_ext.h" -+#include "fm_mac_ext.h" -+ -+#include "fm_macsec_master.h" -+ -+ -+extern uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac); -+ -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec) -+{ -+ if (!p_FmMacsec->f_Exception) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); -+ -+ return E_OK; -+} -+ -+static void UnimplementedIsr(t_Handle h_Arg, uint32_t id) -+{ -+ UNUSED(h_Arg); UNUSED(id); -+ -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!")); -+} -+ -+static void MacsecEventIsr(t_Handle h_FmMacsec) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ uint32_t events,event,i; -+ -+ SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE); -+ -+ events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr); -+ events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events); -+ -+ for (i=0; iintrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i); -+ } -+} -+ -+static void MacsecErrorIsr(t_Handle h_FmMacsec) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ uint32_t errors,error,i; -+ -+ SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE); -+ -+ errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err); -+ errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors); -+ -+ for (i=0; iintrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i); -+ } -+ -+ if (errors & FM_MACSEC_EX_ECC) -+ { -+ uint8_t eccType; -+ uint32_t tmpReg; -+ -+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec); -+ ASSERT_COND(tmpReg & MECC_CAP); -+ eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT); -+ -+ if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC)) -+ p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC); -+ else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC)) -+ p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC); -+ else -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg); -+ } -+} -+ -+static t_Error MacsecInit(t_Handle h_FmMacsec) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_FmMacsecDriverParam *p_FmMacsecDriverParam = NULL; -+ uint32_t tmpReg,i,macId; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters); -+ -+ p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam; -+ -+ for (i=0;iintrMng[i].f_Isr = UnimplementedIsr; -+ -+ tmpReg = 0; -+ tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)| -+ (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT) | -+ (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT) | -+ (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT) | -+ (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) | -+ (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT) | -+ (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT) | -+ (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT) | -+ (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg); -+ -+ tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac); -+ /* At least Ethernet FCS (4 bytes) overhead must be subtracted from MFL. -+ * In addition, the SCI (8 bytes) overhead might be subtracted as well. */ -+ tmpReg -= p_FmMacsecDriverParam->mflSubtract; -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr); -+ -+ if (!p_FmMacsec->userExceptions) -+ p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC; -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions); -+ -+ p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC; -+ if (p_FmMacsecDriverParam->reservedSc0) -+ p_FmMacsec->numRxScAvailable --; -+ p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC; -+ -+ XX_Free(p_FmMacsecDriverParam); -+ p_FmMacsec->p_FmMacsecDriverParam = NULL; -+ -+ FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId); -+ FmRegisterIntr(p_FmMacsec->h_Fm, -+ e_FM_MOD_MACSEC, -+ (uint8_t)macId, -+ e_FM_INTR_TYPE_NORMAL, -+ MacsecEventIsr, -+ p_FmMacsec); -+ -+ FmRegisterIntr(p_FmMacsec->h_Fm, -+ e_FM_MOD_MACSEC, -+ 0, -+ e_FM_INTR_TYPE_ERR, -+ MacsecErrorIsr, -+ p_FmMacsec); -+ -+ return E_OK; -+} -+ -+static t_Error MacsecFree(t_Handle h_FmMacsec) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ uint32_t macId; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId); -+ FmUnregisterIntr(p_FmMacsec->h_Fm, -+ e_FM_MOD_MACSEC, -+ (uint8_t)macId, -+ e_FM_INTR_TYPE_NORMAL); -+ -+ FmUnregisterIntr(p_FmMacsec->h_Fm, -+ e_FM_MOD_MACSEC, -+ 0, -+ e_FM_INTR_TYPE_ERR); -+ -+ if (p_FmMacsec->rxScSpinLock) -+ XX_FreeSpinlock(p_FmMacsec->rxScSpinLock); -+ if (p_FmMacsec->txScSpinLock) -+ XX_FreeSpinlock(p_FmMacsec->txScSpinLock); -+ -+ XX_Free(p_FmMacsec); -+ -+ return E_OK; -+} -+ -+static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode; -+ -+ return E_OK; -+} -+ -+static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled; -+ -+ return E_OK; -+} -+ -+static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled; -+ -+ return E_OK; -+} -+ -+static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled; -+ -+ return E_OK; -+} -+ -+static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled; -+ -+ return E_OK; -+} -+ -+static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode; -+ -+ return E_OK; -+} -+ -+static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr; -+ -+ return E_OK; -+} -+ -+static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE; -+ -+ return E_OK; -+} -+ -+static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE; -+ p_FmMacsec->p_FmMacsecDriverParam->mflSubtract += MACSEC_SCI_SIZE; -+ -+ return E_OK; -+} -+ -+static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ uint32_t bitMask = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ GET_USER_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_FmMacsec->userExceptions |= bitMask; -+ else -+ p_FmMacsec->userExceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ return E_OK; -+} -+ -+static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1); -+ -+ return E_OK; -+} -+ -+static t_Error MacsecEnable(t_Handle h_FmMacsec) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ uint32_t tmpReg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg); -+ tmpReg |= CFG_BYPN; -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg); -+ -+ return E_OK; -+} -+ -+static t_Error MacsecDisable(t_Handle h_FmMacsec) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ uint32_t tmpReg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg); -+ tmpReg &= ~CFG_BYPN; -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg); -+ -+ return E_OK; -+} -+ -+static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ uint32_t bitMask; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ GET_USER_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_FmMacsec->userExceptions |= bitMask; -+ else -+ p_FmMacsec->userExceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ if (!p_FmMacsec->userExceptions) -+ p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC; -+ else -+ p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC; -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions); -+ -+ return E_OK; -+} -+ -+static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver) -+{ -+ p_FmMacsecControllerDriver->f_FM_MACSEC_Init = MacsecInit; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_Free = MacsecFree; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment = MacsecConfigUnknownSciFrameTreatment; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment = MacsecConfigInvalidTagsFrameTreatment; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment = MacsecConfigEncryptWithNoChangedTextFrameTreatment; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment = MacsecConfigUntagFrameTreatment; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment = MacsecConfigChangedTextWithNoEncryptFrameTreatment; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment = MacsecConfigOnlyScbIsSetFrameTreatment; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold = MacsecConfigPnExhaustionThreshold; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable = MacsecConfigKeysUnreadable; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI = MacsecConfigSectagWithoutSCI; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException = MacsecConfigException; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision = MacsecGetRevision; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_Enable = MacsecEnable; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_Disable = MacsecDisable; -+ p_FmMacsecControllerDriver->f_FM_MACSEC_SetException = MacsecSetException; -+} -+ -+/****************************************/ -+/* Inter-Module functions */ -+/****************************************/ -+ -+void FmMacsecRegisterIntr(t_Handle h_FmMacsec, -+ e_FmMacsecEventModules module, -+ uint8_t modId, -+ e_FmIntrType intrType, -+ void (*f_Isr) (t_Handle h_Arg, uint32_t id), -+ t_Handle h_Arg) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ uint8_t event= 0; -+ -+ SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE); -+ -+ GET_MACSEC_MODULE_EVENT(module, modId, intrType, event); -+ -+ ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST); -+ p_FmMacsec->intrMng[event].f_Isr = f_Isr; -+ p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg; -+} -+ -+void FmMacsecUnregisterIntr(t_Handle h_FmMacsec, -+ e_FmMacsecEventModules module, -+ uint8_t modId, -+ e_FmIntrType intrType) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ uint8_t event= 0; -+ -+ SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE); -+ -+ GET_MACSEC_MODULE_EVENT(module, modId,intrType, event); -+ -+ ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST); -+ p_FmMacsec->intrMng[event].f_Isr = NULL; -+ p_FmMacsec->intrMng[event].h_SrcHandle = NULL; -+} -+ -+t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ bool *p_ScTable; -+ uint32_t *p_ScAvailable,i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE); -+ -+ if (type == e_SC_RX) -+ { -+ p_ScTable = (bool *)p_FmMacsec->rxScTable; -+ p_ScAvailable = &p_FmMacsec->numRxScAvailable; -+ i = (NUM_OF_RX_SC - 1); -+ } -+ else -+ { -+ p_ScTable = (bool *)p_FmMacsec->txScTable; -+ p_ScAvailable = &p_FmMacsec->numTxScAvailable; -+ i = (NUM_OF_TX_SC - 1); -+ -+ } -+ if (*p_ScAvailable < numOfScs) -+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available")); -+ -+ if (isPtp) -+ { -+ i = 0; -+ if (p_ScTable[i]) -+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available")); -+ } -+ -+ for (;numOfScs;i--) -+ { -+ if (p_ScTable[i]) -+ continue; -+ numOfScs --; -+ (*p_ScAvailable)--; -+ p_ScIds[numOfScs] = i; -+ p_ScTable[i] = TRUE; -+ } -+ -+ return err; -+} -+ -+t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ bool *p_ScTable; -+ uint32_t *p_ScAvailable,maxNumOfSc,i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE); -+ -+ if (type == e_SC_RX) -+ { -+ p_ScTable = (bool *)p_FmMacsec->rxScTable; -+ p_ScAvailable = &p_FmMacsec->numRxScAvailable; -+ maxNumOfSc = NUM_OF_RX_SC; -+ } -+ else -+ { -+ p_ScTable = (bool *)p_FmMacsec->txScTable; -+ p_ScAvailable = &p_FmMacsec->numTxScAvailable; -+ maxNumOfSc = NUM_OF_TX_SC; -+ } -+ -+ if ((*p_ScAvailable + numOfScs) > maxNumOfSc) -+ RETURN_ERROR(MINOR, E_FULL, ("Too much SCs")); -+ -+ for (i=0;ip_FmMacsecRegs->cfg); -+ if (enable && (tmpReg & CFG_S0I)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode")); -+ -+ if (enable) -+ tmpReg |= CFG_S0I; -+ else -+ tmpReg &= ~CFG_S0I; -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg); -+ -+ return E_OK; -+} -+ -+t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t tmpReg = 0, intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId); -+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg); -+ if (tmpReg & RX_SCCFG_SCI_EN_MASK) -+ { -+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId)); -+ } -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci)); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci)); -+ tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK); -+ tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK); -+ tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK); -+ tmpReg |= RX_SCCFG_SCI_EN_MASK; -+ tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t tmpReg = 0, intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); -+ -+ tmpReg &= ~RX_SCCFG_SCI_EN_MASK; -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t tmpReg = 0, intFlags; -+ bool alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId); -+ -+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg); -+ if (tmpReg & TX_SCCFG_SCE_MASK) -+ { -+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId)); -+ } -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci)); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci)); -+ alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG); -+ useES = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA); -+ -+ tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK); -+ tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK); -+ tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK); -+ tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK); -+ tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK); -+ tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK); -+ tmpReg |= TX_SCCFG_SCE_MASK; -+ tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t tmpReg = 0, intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); -+ -+ tmpReg &= ~TX_SCCFG_SCE_MASK; -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t tmpReg = 0, intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn); -+ MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t)); -+ -+ tmpReg |= RX_SACFG_ACTIVE; -+ tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t tmpReg = 0, intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn); -+ MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t)); -+ -+ tmpReg |= TX_SACFG_ACTIVE; -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t tmpReg = 0, i, intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0); -+ for (i=0; i<4; i++) -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0); -+ -+ tmpReg |= RX_SACFG_ACTIVE; -+ tmpReg &= ~RX_SACFG_EN_MASK; -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t tmpReg = 0, i, intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0); -+ for (i=0; i<4; i++) -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0); -+ -+ tmpReg |= TX_SACFG_ACTIVE; -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t tmpReg = 0, intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); -+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs); -+ if (enableReceive) -+ tmpReg |= RX_SACFG_EN_MASK; -+ else -+ tmpReg &= ~RX_SACFG_EN_MASK; -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId); -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t tmpReg = 0, intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId); -+ -+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg); -+ -+ tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK); -+ tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ t_Error err = E_OK; -+ uint32_t tmpReg = 0, intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE); -+ -+ intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId); -+ -+ tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg); -+ -+ XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags); -+ -+ *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT); -+ -+ return err; -+} -+ -+t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ uint32_t bitMask; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ GET_EXCEPTION_FLAG(bitMask, exception, scId); -+ if (bitMask) -+ { -+ if (enable) -+ p_FmMacsec->exceptions |= bitMask; -+ else -+ p_FmMacsec->exceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions); -+ -+ return E_OK; -+} -+ -+t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable) -+{ -+ t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec; -+ uint32_t bitMask; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE); -+ -+ GET_EVENT_FLAG(bitMask, event, scId); -+ if (bitMask) -+ { -+ if (enable) -+ p_FmMacsec->events |= bitMask; -+ else -+ p_FmMacsec->events &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event")); -+ -+ WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events); -+ -+ return E_OK; -+} -+ -+/****************************************/ -+/* API Init unit functions */ -+/****************************************/ -+t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam) -+{ -+ t_FmMacsec *p_FmMacsec; -+ uint32_t macId; -+ -+ /* Allocate FM MACSEC structure */ -+ p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec)); -+ if (!p_FmMacsec) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure")); -+ return NULL; -+ } -+ memset(p_FmMacsec, 0, sizeof(t_FmMacsec)); -+ InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver); -+ -+ /* Allocate the FM MACSEC driver's parameters structure */ -+ p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam)); -+ if (!p_FmMacsec->p_FmMacsecDriverParam) -+ { -+ XX_Free(p_FmMacsec); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters")); -+ return NULL; -+ } -+ memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam)); -+ -+ /* Initialize FM MACSEC parameters which will be kept by the driver */ -+ p_FmMacsec->h_Fm = p_FmMacsecParam->h_Fm; -+ p_FmMacsec->h_FmMac = p_FmMacsecParam->nonGuestParams.h_FmMac; -+ p_FmMacsec->p_FmMacsecRegs = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr); -+ p_FmMacsec->f_Exception = p_FmMacsecParam->nonGuestParams.f_Exception; -+ p_FmMacsec->h_App = p_FmMacsecParam->nonGuestParams.h_App; -+ p_FmMacsec->userExceptions = DEFAULT_userExceptions; -+ p_FmMacsec->exceptions = DEFAULT_exceptions; -+ p_FmMacsec->events = DEFAULT_events; -+ p_FmMacsec->rxScSpinLock = XX_InitSpinlock(); -+ p_FmMacsec->txScSpinLock = XX_InitSpinlock(); -+ -+ /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */ -+ p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = DEFAULT_unknownSciFrameTreatment; -+ p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = DEFAULT_invalidTagsFrameTreatment; -+ p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = DEFAULT_encryptWithNoChangedTextFrameTreatment; -+ p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = DEFAULT_untagFrameTreatment; -+ p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = DEFAULT_keysUnreadable; -+ p_FmMacsec->p_FmMacsecDriverParam->reservedSc0 = DEFAULT_sc0ReservedForPTP; -+ p_FmMacsec->p_FmMacsecDriverParam->byPassMode = !DEFAULT_normalMode; -+ p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = DEFAULT_pnExhThr; -+ p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead = DEFAULT_sectagOverhead; -+ p_FmMacsec->p_FmMacsecDriverParam->mflSubtract = DEFAULT_mflSubtract; -+ /* build the FM MACSEC master IPC address */ -+ memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE); -+ FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId); -+ if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master", -+ FmGetId(p_FmMacsec->h_Fm),macId) != 24) -+ { -+ XX_Free(p_FmMacsec->p_FmMacsecDriverParam); -+ XX_Free(p_FmMacsec); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); -+ return NULL; -+ } -+ return p_FmMacsec; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h -@@ -0,0 +1,479 @@ -+/* -+ * Copyright 2008-2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File fm_macsec_master.h -+ -+ @Description FM MACSEC internal structures and definitions. -+*//***************************************************************************/ -+#ifndef __FM_MACSEC_MASTER_H -+#define __FM_MACSEC_MASTER_H -+ -+#include "error_ext.h" -+#include "std_ext.h" -+ -+#include "fm_macsec.h" -+ -+ -+#define MACSEC_ICV_SIZE 16 -+#define MACSEC_SECTAG_SIZE 16 -+#define MACSEC_SCI_SIZE 8 -+#define MACSEC_FCS_SIZE 4 -+ -+/**************************************************************************//** -+ @Description Exceptions -+*//***************************************************************************/ -+ -+#define FM_MACSEC_EX_TX_SC_0 0x80000000 -+#define FM_MACSEC_EX_TX_SC(sc) (FM_MACSEC_EX_TX_SC_0 >> (sc)) -+#define FM_MACSEC_EX_ECC 0x00000001 -+ -+#define GET_EXCEPTION_FLAG(bitMask, exception, id) switch (exception){ \ -+ case e_FM_MACSEC_EX_TX_SC: \ -+ bitMask = FM_MACSEC_EX_TX_SC(id); break; \ -+ case e_FM_MACSEC_EX_ECC: \ -+ bitMask = FM_MACSEC_EX_ECC; break; \ -+ default: bitMask = 0;break;} -+ -+#define FM_MACSEC_USER_EX_SINGLE_BIT_ECC 0x80000000 -+#define FM_MACSEC_USER_EX_MULTI_BIT_ECC 0x40000000 -+ -+#define GET_USER_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \ -+ case e_FM_MACSEC_EX_SINGLE_BIT_ECC: \ -+ bitMask = FM_MACSEC_USER_EX_SINGLE_BIT_ECC; break; \ -+ case e_FM_MACSEC_EX_MULTI_BIT_ECC: \ -+ bitMask = FM_MACSEC_USER_EX_MULTI_BIT_ECC; break; \ -+ default: bitMask = 0;break;} -+ -+/**************************************************************************//** -+ @Description Events -+*//***************************************************************************/ -+ -+#define FM_MACSEC_EV_TX_SC_0_NEXT_PN 0x80000000 -+#define FM_MACSEC_EV_TX_SC_NEXT_PN(sc) (FM_MACSEC_EV_TX_SC_0_NEXT_PN >> (sc)) -+ -+#define GET_EVENT_FLAG(bitMask, event, id) switch (event){ \ -+ case e_FM_MACSEC_EV_TX_SC_NEXT_PN: \ -+ bitMask = FM_MACSEC_EV_TX_SC_NEXT_PN(id); break; \ -+ default: bitMask = 0;break;} -+ -+/**************************************************************************//** -+ @Description Defaults -+*//***************************************************************************/ -+#define DEFAULT_userExceptions (FM_MACSEC_USER_EX_SINGLE_BIT_ECC |\ -+ FM_MACSEC_USER_EX_MULTI_BIT_ECC) -+ -+#define DEFAULT_exceptions (FM_MACSEC_EX_TX_SC(0) |\ -+ FM_MACSEC_EX_TX_SC(1) |\ -+ FM_MACSEC_EX_TX_SC(2) |\ -+ FM_MACSEC_EX_TX_SC(3) |\ -+ FM_MACSEC_EX_TX_SC(4) |\ -+ FM_MACSEC_EX_TX_SC(5) |\ -+ FM_MACSEC_EX_TX_SC(6) |\ -+ FM_MACSEC_EX_TX_SC(7) |\ -+ FM_MACSEC_EX_TX_SC(8) |\ -+ FM_MACSEC_EX_TX_SC(9) |\ -+ FM_MACSEC_EX_TX_SC(10) |\ -+ FM_MACSEC_EX_TX_SC(11) |\ -+ FM_MACSEC_EX_TX_SC(12) |\ -+ FM_MACSEC_EX_TX_SC(13) |\ -+ FM_MACSEC_EX_TX_SC(14) |\ -+ FM_MACSEC_EX_TX_SC(15) |\ -+ FM_MACSEC_EX_ECC ) -+ -+#define DEFAULT_events (FM_MACSEC_EV_TX_SC_NEXT_PN(0) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(1) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(2) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(3) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(4) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(5) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(6) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(7) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(8) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(9) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(10) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(11) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(12) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(13) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(14) |\ -+ FM_MACSEC_EV_TX_SC_NEXT_PN(15) ) -+ -+#define DEFAULT_unknownSciFrameTreatment e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH -+#define DEFAULT_invalidTagsFrameTreatment FALSE -+#define DEFAULT_encryptWithNoChangedTextFrameTreatment FALSE -+#define DEFAULT_untagFrameTreatment e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED -+#define DEFAULT_changedTextWithNoEncryptFrameTreatment FALSE -+#define DEFAULT_onlyScbIsSetFrameTreatment FALSE -+#define DEFAULT_keysUnreadable FALSE -+#define DEFAULT_normalMode TRUE -+#define DEFAULT_sc0ReservedForPTP FALSE -+#define DEFAULT_initNextPn 1 -+#define DEFAULT_pnExhThr 0xffffffff -+#define DEFAULT_sectagOverhead (MACSEC_ICV_SIZE + MACSEC_SECTAG_SIZE) -+#define DEFAULT_mflSubtract MACSEC_FCS_SIZE -+ -+ -+/**************************************************************************//** -+ @Description Memory Mapped Registers -+*//***************************************************************************/ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+typedef _Packed struct -+{ -+ /* MACsec configuration */ -+ volatile uint32_t cfg; /**< MACsec configuration */ -+ volatile uint32_t et; /**< MACsec EtherType */ -+ volatile uint8_t res1[56]; /**< reserved */ -+ volatile uint32_t mfl; /**< Maximum Frame Length */ -+ volatile uint32_t tpnet; /**< TX Packet Number exhaustion threshold */ -+ volatile uint8_t res2[56]; /**< reserved */ -+ volatile uint32_t rxsca; /**< RX SC access select */ -+ volatile uint8_t res3[60]; /**< reserved */ -+ volatile uint32_t txsca; /**< TX SC access select */ -+ volatile uint8_t res4[60]; /**< reserved */ -+ -+ /* RX configuration, status and statistic */ -+ volatile uint32_t rxsci1h; /**< RX Secure Channel Identifier first half */ -+ volatile uint32_t rxsci2h; /**< RX Secure Channel Identifier second half */ -+ volatile uint8_t res5[8]; /**< reserved */ -+ volatile uint32_t ifio1hs; /**< ifInOctets first half Statistic */ -+ volatile uint32_t ifio2hs; /**< ifInOctets second half Statistic */ -+ volatile uint32_t ifiups; /**< ifInUcastPkts Statistic */ -+ volatile uint8_t res6[4]; /**< reserved */ -+ volatile uint32_t ifimps; /**< ifInMulticastPkts Statistic */ -+ volatile uint32_t ifibps; /**< ifInBroadcastPkts Statistic */ -+ volatile uint32_t rxsccfg; /**< RX Secure Channel configuration */ -+ volatile uint32_t rpw; /**< replayWindow */ -+ volatile uint8_t res7[16]; /**< reserved */ -+ volatile uint32_t inov1hs; /**< InOctetsValidated first half Statistic */ -+ volatile uint32_t inov2hs; /**< InOctetsValidated second half Statistic */ -+ volatile uint32_t inod1hs; /**< InOctetsDecrypted first half Statistic */ -+ volatile uint32_t inod2hs; /**< InOctetsDecrypted second half Statistic */ -+ volatile uint32_t rxscipus; /**< RX Secure Channel InPktsUnchecked Statistic */ -+ volatile uint32_t rxscipds; /**< RX Secure Channel InPktsDelayed Statistic */ -+ volatile uint32_t rxscipls; /**< RX Secure Channel InPktsLate Statistic */ -+ volatile uint8_t res8[4]; /**< reserved */ -+ volatile uint32_t rxaninuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InNotUsingSA Statistic */ -+ volatile uint32_t rxanipuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InPktsUnusedSA Statistic */ -+ _Packed struct -+ { -+ volatile uint32_t rxsacs; /**< RX Security Association configuration and status */ -+ volatile uint32_t rxsanpn; /**< RX Security Association nextPN */ -+ volatile uint32_t rxsalpn; /**< RX Security Association lowestPN */ -+ volatile uint32_t rxsaipos; /**< RX Security Association InPktsOK Statistic */ -+ volatile uint32_t rxsak[4]; /**< RX Security Association key (128 bit) */ -+ volatile uint32_t rxsah[4]; /**< RX Security Association hash (128 bit) */ -+ volatile uint32_t rxsaipis; /**< RX Security Association InPktsInvalid Statistic */ -+ volatile uint32_t rxsaipnvs; /**< RX Security Association InPktsNotValid Statistic */ -+ volatile uint8_t res9[8]; /**< reserved */ -+ } _PackedType fmMacsecRxScSa[NUM_OF_SA_PER_RX_SC]; -+ -+ /* TX configuration, status and statistic */ -+ volatile uint32_t txsci1h; /**< TX Secure Channel Identifier first half */ -+ volatile uint32_t txsci2h; /**< TX Secure Channel Identifier second half */ -+ volatile uint8_t res10[8]; /**< reserved */ -+ volatile uint32_t ifoo1hs; /**< ifOutOctets first half Statistic */ -+ volatile uint32_t ifoo2hs; /**< ifOutOctets second half Statistic */ -+ volatile uint32_t ifoups; /**< ifOutUcastPkts Statistic */ -+ volatile uint32_t opus; /**< OutPktsUntagged Statistic */ -+ volatile uint32_t ifomps; /**< ifOutMulticastPkts Statistic */ -+ volatile uint32_t ifobps; /**< ifOutBroadcastPkts Statistic */ -+ volatile uint32_t txsccfg; /**< TX Secure Channel configuration */ -+ volatile uint32_t optls; /**< OutPktsTooLong Statistic */ -+ volatile uint8_t res11[16]; /**< reserved */ -+ volatile uint32_t oop1hs; /**< OutOctetsProtected first half Statistic */ -+ volatile uint32_t oop2hs; /**< OutOctetsProtected second half Statistic */ -+ volatile uint32_t ooe1hs; /**< OutOctetsEncrypted first half Statistic */ -+ volatile uint32_t ooe2hs; /**< OutOctetsEncrypted second half Statistic */ -+ volatile uint8_t res12[48]; /**< reserved */ -+ _Packed struct -+ { -+ volatile uint32_t txsacs; /**< TX Security Association configuration and status */ -+ volatile uint32_t txsanpn; /**< TX Security Association nextPN */ -+ volatile uint32_t txsaopps; /**< TX Security Association OutPktsProtected Statistic */ -+ volatile uint32_t txsaopes; /**< TX Security Association OutPktsEncrypted Statistic */ -+ volatile uint32_t txsak[4]; /**< TX Security Association key (128 bit) */ -+ volatile uint32_t txsah[4]; /**< TX Security Association hash (128 bit) */ -+ volatile uint8_t res13[16]; /**< reserved */ -+ } _PackedType fmMacsecTxScSa[NUM_OF_SA_PER_TX_SC]; -+ volatile uint8_t res14[248]; /**< reserved */ -+ -+ /* Global configuration and status */ -+ volatile uint32_t ip_rev1; /**< MACsec IP Block Revision 1 register */ -+ volatile uint32_t ip_rev2; /**< MACsec IP Block Revision 2 register */ -+ volatile uint32_t evr; /**< MACsec Event Register */ -+ volatile uint32_t ever; /**< MACsec Event Enable Register */ -+ volatile uint32_t evfr; /**< MACsec Event Force Register */ -+ volatile uint32_t err; /**< MACsec Error Register */ -+ volatile uint32_t erer; /**< MACsec Error Enable Register */ -+ volatile uint32_t erfr; /**< MACsec Error Force Register */ -+ volatile uint8_t res15[40]; /**< reserved */ -+ volatile uint32_t meec; /**< MACsec Memory ECC Error Capture Register */ -+ volatile uint32_t idle; /**< MACsec Idle status Register */ -+ volatile uint8_t res16[184]; /**< reserved */ -+ /* DEBUG */ -+ volatile uint32_t rxec; /**< MACsec RX error capture Register */ -+ volatile uint8_t res17[28]; /**< reserved */ -+ volatile uint32_t txec; /**< MACsec TX error capture Register */ -+ volatile uint8_t res18[220]; /**< reserved */ -+ -+ /* Macsec Rx global statistic */ -+ volatile uint32_t ifiocp1hs; /**< ifInOctetsCp first half Statistic */ -+ volatile uint32_t ifiocp2hs; /**< ifInOctetsCp second half Statistic */ -+ volatile uint32_t ifiupcps; /**< ifInUcastPktsCp Statistic */ -+ volatile uint8_t res19[4]; /**< reserved */ -+ volatile uint32_t ifioup1hs; /**< ifInOctetsUp first half Statistic */ -+ volatile uint32_t ifioup2hs; /**< ifInOctetsUp second half Statistic */ -+ volatile uint32_t ifiupups; /**< ifInUcastPktsUp Statistic */ -+ volatile uint8_t res20[4]; /**< reserved */ -+ volatile uint32_t ifimpcps; /**< ifInMulticastPktsCp Statistic */ -+ volatile uint32_t ifibpcps; /**< ifInBroadcastPktsCp Statistic */ -+ volatile uint32_t ifimpups; /**< ifInMulticastPktsUp Statistic */ -+ volatile uint32_t ifibpups; /**< ifInBroadcastPktsUp Statistic */ -+ volatile uint32_t ipwts; /**< InPktsWithoutTag Statistic */ -+ volatile uint32_t ipkays; /**< InPktsKaY Statistic */ -+ volatile uint32_t ipbts; /**< InPktsBadTag Statistic */ -+ volatile uint32_t ipsnfs; /**< InPktsSCINotFound Statistic */ -+ volatile uint32_t ipuecs; /**< InPktsUnsupportedEC Statistic */ -+ volatile uint32_t ipescbs; /**< InPktsEponSingleCopyBroadcast Statistic */ -+ volatile uint32_t iptls; /**< InPktsTooLong Statistic */ -+ volatile uint8_t res21[52]; /**< reserved */ -+ -+ /* Macsec Tx global statistic */ -+ volatile uint32_t opds; /**< OutPktsDiscarded Statistic */ -+#if (DPAA_VERSION >= 11) -+ volatile uint8_t res22[124]; /**< reserved */ -+ _Packed struct -+ { -+ volatile uint32_t rxsak[8]; /**< RX Security Association key (128/256 bit) */ -+ volatile uint8_t res23[32]; /**< reserved */ -+ } _PackedType rxScSaKey[NUM_OF_SA_PER_RX_SC]; -+ _Packed struct -+ { -+ volatile uint32_t txsak[8]; /**< TX Security Association key (128/256 bit) */ -+ volatile uint8_t res24[32]; /**< reserved */ -+ } _PackedType txScSaKey[NUM_OF_SA_PER_TX_SC]; -+#endif /* (DPAA_VERSION >= 11) */ -+} _PackedType t_FmMacsecRegs; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+/**************************************************************************//** -+ @Description General defines -+*//***************************************************************************/ -+ -+#define SCI_HIGH_MASK 0xffffffff00000000LL -+#define SCI_LOW_MASK 0x00000000ffffffffLL -+ -+#define LONG_SHIFT 32 -+ -+#define GET_SCI_FIRST_HALF(sci) (uint32_t)((macsecSCI_t)((macsecSCI_t)(sci) & SCI_HIGH_MASK) >> LONG_SHIFT) -+#define GET_SCI_SECOND_HALF(sci) (uint32_t)((macsecSCI_t)(sci) & SCI_LOW_MASK) -+ -+/**************************************************************************//** -+ @Description Configuration defines -+*//***************************************************************************/ -+ -+/* masks */ -+#define CFG_UECT 0x00000800 -+#define CFG_ESCBT 0x00000400 -+#define CFG_USFT 0x00000300 -+#define CFG_ITT 0x00000080 -+#define CFG_KFT 0x00000040 -+#define CFG_UFT 0x00000030 -+#define CFG_KSS 0x00000004 -+#define CFG_BYPN 0x00000002 -+#define CFG_S0I 0x00000001 -+ -+#define ET_TYPE 0x0000ffff -+ -+#define MFL_MAX_LEN 0x0000ffff -+ -+#define RXSCA_SC_SEL 0x0000000f -+ -+#define TXSCA_SC_SEL 0x0000000f -+ -+#define IP_REV_1_IP_ID 0xffff0000 -+#define IP_REV_1_IP_MJ 0x0000ff00 -+#define IP_REV_1_IP_MM 0x000000ff -+ -+#define IP_REV_2_IP_INT 0x00ff0000 -+#define IP_REV_2_IP_ERR 0x0000ff00 -+#define IP_REV_2_IP_CFG 0x000000ff -+ -+#define MECC_CAP 0x80000000 -+#define MECC_CET 0x40000000 -+#define MECC_SERCNT 0x00ff0000 -+#define MECC_MEMADDR 0x000001ff -+ -+/* shifts */ -+#define CFG_UECT_SHIFT (31-20) -+#define CFG_ESCBT_SHIFT (31-21) -+#define CFG_USFT_SHIFT (31-23) -+#define CFG_ITT_SHIFT (31-24) -+#define CFG_KFT_SHIFT (31-25) -+#define CFG_UFT_SHIFT (31-27) -+#define CFG_KSS_SHIFT (31-29) -+#define CFG_BYPN_SHIFT (31-30) -+#define CFG_S0I_SHIFT (31-31) -+ -+#define IP_REV_1_IP_ID_SHIFT (31-15) -+#define IP_REV_1_IP_MJ_SHIFT (31-23) -+#define IP_REV_1_IP_MM_SHIFT (31-31) -+ -+#define IP_REV_2_IP_INT_SHIFT (31-15) -+#define IP_REV_2_IP_ERR_SHIFT (31-23) -+#define IP_REV_2_IP_CFG_SHIFT (31-31) -+ -+#define MECC_CAP_SHIFT (31-0) -+#define MECC_CET_SHIFT (31-1) -+#define MECC_SERCNT_SHIFT (31-15) -+#define MECC_MEMADDR_SHIFT (31-31) -+ -+/**************************************************************************//** -+ @Description RX SC defines -+*//***************************************************************************/ -+ -+/* masks */ -+#define RX_SCCFG_SCI_EN_MASK 0x00000800 -+#define RX_SCCFG_RP_MASK 0x00000400 -+#define RX_SCCFG_VF_MASK 0x00000300 -+#define RX_SCCFG_CO_MASK 0x0000003f -+ -+/* shifts */ -+#define RX_SCCFG_SCI_EN_SHIFT (31-20) -+#define RX_SCCFG_RP_SHIFT (31-21) -+#define RX_SCCFG_VF_SHIFT (31-23) -+#define RX_SCCFG_CO_SHIFT (31-31) -+#define RX_SCCFG_CS_SHIFT (31-7) -+ -+/**************************************************************************//** -+ @Description RX SA defines -+*//***************************************************************************/ -+ -+/* masks */ -+#define RX_SACFG_ACTIVE 0x80000000 -+#define RX_SACFG_AN_MASK 0x00000006 -+#define RX_SACFG_EN_MASK 0x00000001 -+ -+/* shifts */ -+#define RX_SACFG_AN_SHIFT (31-30) -+#define RX_SACFG_EN_SHIFT (31-31) -+ -+/**************************************************************************//** -+ @Description TX SC defines -+*//***************************************************************************/ -+ -+/* masks */ -+#define TX_SCCFG_AN_MASK 0x000c0000 -+#define TX_SCCFG_ASA_MASK 0x00020000 -+#define TX_SCCFG_SCE_MASK 0x00010000 -+#define TX_SCCFG_CO_MASK 0x00003f00 -+#define TX_SCCFG_CE_MASK 0x00000010 -+#define TX_SCCFG_PF_MASK 0x00000008 -+#define TX_SCCFG_AIS_MASK 0x00000004 -+#define TX_SCCFG_UES_MASK 0x00000002 -+#define TX_SCCFG_USCB_MASK 0x00000001 -+ -+/* shifts */ -+#define TX_SCCFG_AN_SHIFT (31-13) -+#define TX_SCCFG_ASA_SHIFT (31-14) -+#define TX_SCCFG_SCE_SHIFT (31-15) -+#define TX_SCCFG_CO_SHIFT (31-23) -+#define TX_SCCFG_CE_SHIFT (31-27) -+#define TX_SCCFG_PF_SHIFT (31-28) -+#define TX_SCCFG_AIS_SHIFT (31-29) -+#define TX_SCCFG_UES_SHIFT (31-30) -+#define TX_SCCFG_USCB_SHIFT (31-31) -+#define TX_SCCFG_CS_SHIFT (31-7) -+ -+/**************************************************************************//** -+ @Description TX SA defines -+*//***************************************************************************/ -+ -+/* masks */ -+#define TX_SACFG_ACTIVE 0x80000000 -+ -+ -+typedef struct -+{ -+ void (*f_Isr) (t_Handle h_Arg, uint32_t id); -+ t_Handle h_SrcHandle; -+} t_FmMacsecIntrSrc; -+ -+typedef struct -+{ -+ e_FmMacsecUnknownSciFrameTreatment unknownSciTreatMode; -+ bool invalidTagsDeliverUncontrolled; -+ bool changedTextWithNoEncryptDeliverUncontrolled; -+ bool onlyScbIsSetDeliverUncontrolled; -+ bool encryptWithNoChangedTextDiscardUncontrolled; -+ e_FmMacsecUntagFrameTreatment untagTreatMode; -+ uint32_t pnExhThr; -+ bool keysUnreadable; -+ bool byPassMode; -+ bool reservedSc0; -+ uint32_t sectagOverhead; -+ uint32_t mflSubtract; -+} t_FmMacsecDriverParam; -+ -+typedef struct -+{ -+ t_FmMacsecControllerDriver fmMacsecControllerDriver; -+ t_Handle h_Fm; -+ t_FmMacsecRegs *p_FmMacsecRegs; -+ t_Handle h_FmMac; /**< A handle to the FM MAC object related to */ -+ char fmMacsecModuleName[MODULE_NAME_SIZE]; -+ t_FmMacsecIntrSrc intrMng[NUM_OF_INTER_MODULE_EVENTS]; -+ uint32_t events; -+ uint32_t exceptions; -+ uint32_t userExceptions; -+ t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */ -+ t_Handle h_App; /**< A handle to an application layer object; This handle will -+ be passed by the driver upon calling the above callbacks */ -+ bool rxScTable[NUM_OF_RX_SC]; -+ uint32_t numRxScAvailable; -+ bool txScTable[NUM_OF_TX_SC]; -+ uint32_t numTxScAvailable; -+ t_Handle rxScSpinLock; -+ t_Handle txScSpinLock; -+ t_FmMacsecDriverParam *p_FmMacsecDriverParam; -+} t_FmMacsec; -+ -+ -+#endif /* __FM_MACSEC_MASTER_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c -@@ -0,0 +1,883 @@ -+/* -+ * Copyright 2008-2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File fm_macsec_secy.c -+ -+ @Description FM MACSEC SECY driver routines implementation. -+*//***************************************************************************/ -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "xx_ext.h" -+#include "string_ext.h" -+#include "sprint_ext.h" -+ -+#include "fm_macsec_secy.h" -+ -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ -+ UNUSED(id); -+ SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED) -+ p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED); -+} -+ -+static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ -+ UNUSED(id); -+ SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE); -+ -+ if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN) -+ p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN); -+} -+ -+static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY) -+{ -+ if (!p_FmMacsecSecY->f_Exception) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); -+ -+ if (!p_FmMacsecSecY->f_Event) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided")); -+ -+ if (!p_FmMacsecSecY->numOfRxSc) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'")); -+ -+ -+ return E_OK; -+} -+ -+static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY *p_FmMacsecSecY, -+ macsecSCI_t sci, -+ e_FmMacsecSecYCipherSuite cipherSuite, -+ e_ScType type) -+{ -+ t_SecYSc *p_ScTable; -+ void *p_Params; -+ uint32_t numOfSc,i; -+ t_Error err = E_OK; -+ t_RxScParams rxScParams; -+ t_TxScParams txScParams; -+ -+ ASSERT_COND(p_FmMacsecSecY); -+ ASSERT_COND(p_FmMacsecSecY->h_FmMacsec); -+ -+ if (type == e_SC_RX) -+ { -+ memset(&rxScParams, 0, sizeof(rxScParams)); -+ i = (NUM_OF_RX_SC - 1); -+ p_ScTable = p_FmMacsecSecY->p_RxSc; -+ numOfSc = p_FmMacsecSecY->numOfRxSc; -+ rxScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset; -+ rxScParams.replayProtect = p_FmMacsecSecY->replayProtect; -+ rxScParams.replayWindow = p_FmMacsecSecY->replayWindow; -+ rxScParams.validateFrames = p_FmMacsecSecY->validateFrames; -+ rxScParams.cipherSuite = cipherSuite; -+ p_Params = &rxScParams; -+ } -+ else -+ { -+ memset(&txScParams, 0, sizeof(txScParams)); -+ i = (NUM_OF_TX_SC - 1); -+ p_ScTable = p_FmMacsecSecY->p_TxSc; -+ numOfSc = p_FmMacsecSecY->numOfTxSc; -+ txScParams.sciInsertionMode = p_FmMacsecSecY->sciInsertionMode; -+ txScParams.protectFrames = p_FmMacsecSecY->protectFrames; -+ txScParams.confidentialityEnable = p_FmMacsecSecY->confidentialityEnable; -+ txScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset; -+ txScParams.cipherSuite = cipherSuite; -+ p_Params = &txScParams; -+ } -+ -+ for (i=0;iscId = p_ScTable[i].scId; -+ ((t_RxScParams *)p_Params)->sci = sci; -+ if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC")); -+ return NULL; -+ } -+ } -+ else -+ { -+ ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId; -+ ((t_TxScParams *)p_Params)->sci = sci; -+ if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC")); -+ return NULL; -+ } -+ } -+ -+ p_ScTable[i].inUse = TRUE; -+ return &p_ScTable[i]; -+} -+ -+static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type) -+{ -+ t_Error err = E_OK; -+ -+ ASSERT_COND(p_FmMacsecSecY); -+ ASSERT_COND(p_FmMacsecSecY->h_FmMacsec); -+ ASSERT_COND(p_FmSecYSc); -+ -+ if (type == e_SC_RX) -+ { -+ if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ else -+ if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ p_FmSecYSc->inUse = FALSE; -+ -+ return err; -+} -+ -+/****************************************/ -+/* API Init unit functions */ -+/****************************************/ -+t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY; -+ -+ /* Allocate FM MACSEC structure */ -+ p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY)); -+ if (!p_FmMacsecSecY) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure")); -+ return NULL; -+ } -+ memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY)); -+ -+ /* Allocate the FM MACSEC driver's parameters structure */ -+ p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam)); -+ if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam) -+ { -+ XX_Free(p_FmMacsecSecY); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters")); -+ return NULL; -+ } -+ memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam)); -+ -+ /* Initialize FM MACSEC SECY parameters which will be kept by the driver */ -+ p_FmMacsecSecY->h_FmMacsec = p_FmMacsecSecYParam->h_FmMacsec; -+ p_FmMacsecSecY->f_Event = p_FmMacsecSecYParam->f_Event; -+ p_FmMacsecSecY->f_Exception = p_FmMacsecSecYParam->f_Exception; -+ p_FmMacsecSecY->h_App = p_FmMacsecSecYParam->h_App; -+ p_FmMacsecSecY->confidentialityEnable = DEFAULT_confidentialityEnable; -+ p_FmMacsecSecY->confidentialityOffset = DEFAULT_confidentialityOffset; -+ p_FmMacsecSecY->validateFrames = DEFAULT_validateFrames; -+ p_FmMacsecSecY->replayProtect = DEFAULT_replayEnable; -+ p_FmMacsecSecY->replayWindow = DEFAULT_replayWindow; -+ p_FmMacsecSecY->protectFrames = DEFAULT_protectFrames; -+ p_FmMacsecSecY->sciInsertionMode = DEFAULT_sciInsertionMode; -+ p_FmMacsecSecY->isPointToPoint = DEFAULT_ptp; -+ p_FmMacsecSecY->numOfRxSc = p_FmMacsecSecYParam->numReceiveChannels; -+ p_FmMacsecSecY->numOfTxSc = DEFAULT_numOfTxSc; -+ p_FmMacsecSecY->exceptions = DEFAULT_exceptions; -+ p_FmMacsecSecY->events = DEFAULT_events; -+ -+ memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams, -+ &p_FmMacsecSecYParam->txScParams, -+ sizeof(t_FmMacsecSecYSCParams)); -+ return p_FmMacsecSecY; -+} -+ -+t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam = NULL; -+ uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE); -+ -+ CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters); -+ -+ p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam; -+ -+ if ((p_FmMacsecSecY->isPointToPoint) && -+ ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK)) -+ RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point")); -+ -+ /* Rx Sc Allocation */ -+ p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc); -+ if (!p_FmMacsecSecY->p_RxSc) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC")); -+ memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc); -+ if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK) -+ { -+ if (p_FmMacsecSecY->p_TxSc) -+ XX_Free(p_FmMacsecSecY->p_TxSc); -+ if (p_FmMacsecSecY->p_RxSc) -+ XX_Free(p_FmMacsecSecY->p_RxSc); -+ return ERROR_CODE(err); -+ } -+ for (i=0; inumOfRxSc; i++) -+ { -+ p_FmMacsecSecY->p_RxSc[i].scId = rxScIds[i]; -+ p_FmMacsecSecY->p_RxSc[i].type = e_SC_RX; -+ for (j=0; jp_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE; -+ } -+ -+ /* Tx Sc Allocation */ -+ p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc); -+ if (!p_FmMacsecSecY->p_TxSc) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC")); -+ memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc); -+ -+ if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK) -+ { -+ if (p_FmMacsecSecY->p_TxSc) -+ XX_Free(p_FmMacsecSecY->p_TxSc); -+ if (p_FmMacsecSecY->p_RxSc) -+ XX_Free(p_FmMacsecSecY->p_RxSc); -+ return ERROR_CODE(err); -+ } -+ for (i=0; inumOfTxSc; i++) -+ { -+ p_FmMacsecSecY->p_TxSc[i].scId = txScIds[i]; -+ p_FmMacsecSecY->p_TxSc[i].type = e_SC_TX; -+ for (j=0; jp_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE; -+ FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec, -+ e_FM_MACSEC_MOD_SC_TX, -+ (uint8_t)txScIds[i], -+ e_FM_INTR_TYPE_ERR, -+ FmMacsecSecYExceptionsIsr, -+ p_FmMacsecSecY); -+ FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec, -+ e_FM_MACSEC_MOD_SC_TX, -+ (uint8_t)txScIds[i], -+ e_FM_INTR_TYPE_NORMAL, -+ FmMacsecSecYEventsIsr, -+ p_FmMacsecSecY); -+ -+ if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED) -+ FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE); -+ if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN) -+ FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE); -+ } -+ -+ FmMacsecSecYCreateSc(p_FmMacsecSecY, -+ p_FmMacsecSecYDriverParam->txScParams.sci, -+ p_FmMacsecSecYDriverParam->txScParams.cipherSuite, -+ e_SC_TX); -+ XX_Free(p_FmMacsecSecYDriverParam); -+ p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL; -+ -+ return E_OK; -+} -+ -+t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_Error err = E_OK; -+ uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ -+ if (p_FmMacsecSecY->isPointToPoint) -+ FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE); -+ if (p_FmMacsecSecY->p_RxSc) -+ { -+ for (i=0; inumOfRxSc; i++) -+ rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId; -+ if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK) -+ return ERROR_CODE(err); -+ XX_Free(p_FmMacsecSecY->p_RxSc); -+ } -+ if (p_FmMacsecSecY->p_TxSc) -+ { -+ FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX); -+ -+ for (i=0; inumOfTxSc; i++) { -+ txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId; -+ FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec, -+ e_FM_MACSEC_MOD_SC_TX, -+ (uint8_t)txScIds[i], -+ e_FM_INTR_TYPE_ERR); -+ FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec, -+ e_FM_MACSEC_MOD_SC_TX, -+ (uint8_t)txScIds[i], -+ e_FM_INTR_TYPE_NORMAL); -+ -+ if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED) -+ FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE); -+ if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN) -+ FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE); -+ } -+ -+ if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK) -+ return ERROR_CODE(err); -+ XX_Free(p_FmMacsecSecY->p_TxSc); -+ } -+ -+ XX_Free(p_FmMacsecSecY); -+ -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ -+ p_FmMacsecSecY->sciInsertionMode = sciInsertionMode; -+ -+ return E_OK; -+} -+ -+t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ -+ p_FmMacsecSecY->protectFrames = protectFrames; -+ -+ return E_OK; -+} -+ -+t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ -+ p_FmMacsecSecY->replayProtect = replayProtect; -+ p_FmMacsecSecY->replayWindow = replayWindow; -+ -+ return E_OK; -+} -+ -+t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ -+ p_FmMacsecSecY->validateFrames = validateFrames; -+ -+ return E_OK; -+} -+ -+t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ -+ p_FmMacsecSecY->confidentialityEnable = confidentialityEnable; -+ p_FmMacsecSecY->confidentialityOffset = confidentialityOffset; -+ -+ return E_OK; -+} -+ -+t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ -+ p_FmMacsecSecY->numOfRxSc = 1; -+ p_FmMacsecSecY->isPointToPoint = TRUE; -+ p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP; -+ -+ return E_OK; -+} -+ -+t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ uint32_t bitMask = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ -+ GET_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_FmMacsecSecY->exceptions |= bitMask; -+ else -+ p_FmMacsecSecY->exceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ return E_OK; -+} -+ -+t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ uint32_t bitMask = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ -+ GET_EVENT_FLAG(bitMask, event); -+ if (bitMask) -+ { -+ if (enable) -+ p_FmMacsecSecY->events |= bitMask; -+ else -+ p_FmMacsecSecY->events &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event")); -+ -+ return E_OK; -+} -+ -+t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL); -+ SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL); -+ -+ return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX); -+} -+ -+t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ -+ return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX); -+} -+ -+t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); -+ -+ if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an)); -+ -+ if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++; -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); -+ -+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an)); -+ -+ if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ p_FmSecYSc->numOfSa--; -+ p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE; -+ /* TODO - check if statistics need to be read*/ -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); -+ -+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); -+ -+ if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ p_FmSecYSc->sa[an].active = TRUE; -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); -+ -+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); -+ -+ if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ p_FmSecYSc->sa[an].active = FALSE; -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); -+ -+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); -+ -+ if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); -+ -+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); -+ -+ if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); -+ -+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); -+ -+ if (p_FmSecYSc->sa[an].active) -+ if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ /* TODO - statistics should be read */ -+ -+ if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ if (p_FmSecYSc->sa[an].active) -+ if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ return err; -+} -+ -+ -+t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); -+ -+ if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE) -+ RETURN_ERROR(MINOR, err, ("An %d is already assigned",an)); -+ -+ if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++; -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); -+ -+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an)); -+ -+ if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ p_FmSecYSc->numOfSa--; -+ p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE; -+ /* TODO - check if statistics need to be read*/ -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc; -+ macsecAN_t currentAn; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); -+ -+ if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec, -+ p_FmSecYSc->scId, -+ ¤tAn)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec, -+ p_FmSecYSc->scId, -+ p_FmSecYSc->sa[nextActiveAn].saId, -+ nextActiveAn)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ /* TODO - statistics should be read */ -+ -+ if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE); -+ -+ if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an)); -+ -+ if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec, -+ p_FmSecYSc->scId, -+ p_FmSecYSc->sa[an].saId, -+ an)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE); -+ -+ if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec, -+ p_FmSecYSc->scId, -+ p_An)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId) -+{ -+ t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+#ifdef DISABLE_SANITY_CHECKS -+ UNUSED(h_FmMacsecSecY); -+#endif /* DISABLE_SANITY_CHECKS */ -+ -+ *p_ScPhysId = p_FmSecYSc->scId; -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId) -+{ -+ t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY; -+ t_SecYSc *p_FmSecYSc; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE); -+ p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0]; -+ SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE); -+ -+ *p_ScPhysId = p_FmSecYSc->scId; -+ return err; -+} -+ -+t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable) -+{ -+ UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable); -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable) -+{ -+ UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable); -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics) -+{ -+ UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics); -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics) -+{ -+ UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics); -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics) -+{ -+ UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics); -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics) -+{ -+ UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics); -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics) -+{ -+ UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics); -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h -@@ -0,0 +1,144 @@ -+/* -+ * Copyright 2008-2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File fm_macsec_secy.h -+ -+ @Description FM MACSEC SecY internal structures and definitions. -+*//***************************************************************************/ -+#ifndef __FM_MACSEC_SECY_H -+#define __FM_MACSEC_SECY_H -+ -+#include "error_ext.h" -+#include "std_ext.h" -+ -+#include "fm_macsec.h" -+ -+ -+/**************************************************************************//** -+ @Description Exceptions -+*//***************************************************************************/ -+ -+#define FM_MACSEC_SECY_EX_FRAME_DISCARDED 0x80000000 -+ -+#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \ -+ case e_FM_MACSEC_SECY_EX_FRAME_DISCARDED: \ -+ bitMask = FM_MACSEC_SECY_EX_FRAME_DISCARDED; break; \ -+ default: bitMask = 0;break;} -+ -+/**************************************************************************//** -+ @Description Events -+*//***************************************************************************/ -+ -+#define FM_MACSEC_SECY_EV_NEXT_PN 0x80000000 -+ -+#define GET_EVENT_FLAG(bitMask, event) switch (event){ \ -+ case e_FM_MACSEC_SECY_EV_NEXT_PN: \ -+ bitMask = FM_MACSEC_SECY_EV_NEXT_PN; break; \ -+ default: bitMask = 0;break;} -+ -+/**************************************************************************//** -+ @Description Defaults -+*//***************************************************************************/ -+ -+#define DEFAULT_exceptions (FM_MACSEC_SECY_EX_FRAME_DISCARDED) -+#define DEFAULT_events (FM_MACSEC_SECY_EV_NEXT_PN) -+#define DEFAULT_numOfTxSc 1 -+#define DEFAULT_confidentialityEnable FALSE -+#define DEFAULT_confidentialityOffset 0 -+#define DEFAULT_sciInsertionMode e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG -+#define DEFAULT_validateFrames e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT -+#define DEFAULT_replayEnable FALSE -+#define DEFAULT_replayWindow 0 -+#define DEFAULT_protectFrames TRUE -+#define DEFAULT_ptp FALSE -+ -+/**************************************************************************//** -+ @Description General defines -+*//***************************************************************************/ -+ -+#define SECY_AN_FREE_VALUE MAX_NUM_OF_SA_PER_SC -+ -+ -+typedef struct { -+ e_ScSaId saId; -+ bool active; -+ union { -+ t_FmMacsecSecYRxSaStatistics rxSaStatistics; -+ t_FmMacsecSecYTxSaStatistics txSaStatistics; -+ }; -+} t_SecYSa; -+ -+typedef struct { -+ bool inUse; -+ uint32_t scId; -+ e_ScType type; -+ uint8_t numOfSa; -+ t_SecYSa sa[MAX_NUM_OF_SA_PER_SC]; -+ union { -+ t_FmMacsecSecYRxScStatistics rxScStatistics; -+ t_FmMacsecSecYTxScStatistics txScStatistics; -+ }; -+} t_SecYSc; -+ -+typedef struct { -+ t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */ -+} t_FmMacsecSecYDriverParam; -+ -+typedef struct { -+ t_Handle h_FmMacsec; -+ bool confidentialityEnable; /**< TRUE - confidentiality protection and integrity protection -+ FALSE - no confidentiality protection, only integrity protection*/ -+ uint16_t confidentialityOffset; /**< The number of initial octets of each MSDU without confidentiality protection -+ common values are 0, 30, and 50 */ -+ bool replayProtect; /**< replay protection function mode */ -+ uint32_t replayWindow; /**< the size of the replay window */ -+ e_FmMacsecValidFrameBehavior validateFrames; /**< validation function mode */ -+ e_FmMacsecSciInsertionMode sciInsertionMode; -+ bool protectFrames; -+ bool isPointToPoint; -+ e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for this SecY */ -+ uint32_t numOfRxSc; /**< Number of receive channels */ -+ uint32_t numOfTxSc; /**< Number of transmit channels */ -+ t_SecYSc *p_RxSc; -+ t_SecYSc *p_TxSc; -+ uint32_t events; -+ uint32_t exceptions; -+ t_FmMacsecSecYExceptionsCallback *f_Exception; /**< TODO */ -+ t_FmMacsecSecYEventsCallback *f_Event; /**< TODO */ -+ t_Handle h_App; -+ t_FmMacsecSecYStatistics statistics; -+ t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam; -+} t_FmMacsecSecY; -+ -+ -+#endif /* __FM_MACSEC_SECY_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile -@@ -0,0 +1,23 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc -+ -+ccflags-y += -I$(NCSW_FM_INC) -+ -+ -+obj-y += fsl-ncsw-PFM1.o -+ -+fsl-ncsw-PFM1-objs := fm.o fm_muram.o fman.o -+ -+obj-y += MAC/ -+obj-y += Pcd/ -+obj-y += SP/ -+obj-y += Port/ -+obj-y += HC/ -+obj-y += Rtc/ -+obj-y += MACSEC/ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile -@@ -0,0 +1,26 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc -+ -+ccflags-y += -I$(NCSW_FM_INC) -+ -+obj-y += fsl-ncsw-Pcd.o -+ -+fsl-ncsw-Pcd-objs := fman_kg.o fman_prs.o fm_cc.o fm_kg.o fm_pcd.o fm_plcr.o fm_prs.o fm_manip.o -+ -+ifeq ($(CONFIG_FMAN_V3H),y) -+fsl-ncsw-Pcd-objs += fm_replic.o -+endif -+ifeq ($(CONFIG_FMAN_V3L),y) -+fsl-ncsw-Pcd-objs += fm_replic.o -+endif -+ifeq ($(CONFIG_FMAN_ARM),y) -+fsl-ncsw-Pcd-objs += fm_replic.o -+endif -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h -@@ -0,0 +1,360 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+ /**************************************************************************//** -+ @File crc64.h -+ -+ @Description brief This file contains the CRC64 Table, and __inline__ -+ functions used for calculating crc. -+*//***************************************************************************/ -+#ifndef __CRC64_H -+#define __CRC64_H -+ -+#include "std_ext.h" -+ -+ -+#define BITS_PER_BYTE 8 -+ -+#define CRC64_EXPON_ECMA_182 0xC96C5795D7870F42ULL -+#define CRC64_DEFAULT_INITVAL 0xFFFFFFFFFFFFFFFFULL -+ -+#define CRC64_BYTE_MASK 0xFF -+#define CRC64_TABLE_ENTRIES ( 1 << BITS_PER_BYTE ) -+#define CRC64_ODD_MASK 1 -+ -+ -+/** -+ \brief '64 bit crc' Table -+ */ -+struct crc64_t { -+ uint64_t initial; /**< Initial seed */ -+ uint64_t table[CRC64_TABLE_ENTRIES]; /**< CRC table entries */ -+}; -+ -+ -+static struct crc64_t CRC64_ECMA_182 = { -+ CRC64_DEFAULT_INITVAL, -+ { -+ 0x0000000000000000ULL, -+ 0xb32e4cbe03a75f6fULL, -+ 0xf4843657a840a05bULL, -+ 0x47aa7ae9abe7ff34ULL, -+ 0x7bd0c384ff8f5e33ULL, -+ 0xc8fe8f3afc28015cULL, -+ 0x8f54f5d357cffe68ULL, -+ 0x3c7ab96d5468a107ULL, -+ 0xf7a18709ff1ebc66ULL, -+ 0x448fcbb7fcb9e309ULL, -+ 0x0325b15e575e1c3dULL, -+ 0xb00bfde054f94352ULL, -+ 0x8c71448d0091e255ULL, -+ 0x3f5f08330336bd3aULL, -+ 0x78f572daa8d1420eULL, -+ 0xcbdb3e64ab761d61ULL, -+ 0x7d9ba13851336649ULL, -+ 0xceb5ed8652943926ULL, -+ 0x891f976ff973c612ULL, -+ 0x3a31dbd1fad4997dULL, -+ 0x064b62bcaebc387aULL, -+ 0xb5652e02ad1b6715ULL, -+ 0xf2cf54eb06fc9821ULL, -+ 0x41e11855055bc74eULL, -+ 0x8a3a2631ae2dda2fULL, -+ 0x39146a8fad8a8540ULL, -+ 0x7ebe1066066d7a74ULL, -+ 0xcd905cd805ca251bULL, -+ 0xf1eae5b551a2841cULL, -+ 0x42c4a90b5205db73ULL, -+ 0x056ed3e2f9e22447ULL, -+ 0xb6409f5cfa457b28ULL, -+ 0xfb374270a266cc92ULL, -+ 0x48190ecea1c193fdULL, -+ 0x0fb374270a266cc9ULL, -+ 0xbc9d3899098133a6ULL, -+ 0x80e781f45de992a1ULL, -+ 0x33c9cd4a5e4ecdceULL, -+ 0x7463b7a3f5a932faULL, -+ 0xc74dfb1df60e6d95ULL, -+ 0x0c96c5795d7870f4ULL, -+ 0xbfb889c75edf2f9bULL, -+ 0xf812f32ef538d0afULL, -+ 0x4b3cbf90f69f8fc0ULL, -+ 0x774606fda2f72ec7ULL, -+ 0xc4684a43a15071a8ULL, -+ 0x83c230aa0ab78e9cULL, -+ 0x30ec7c140910d1f3ULL, -+ 0x86ace348f355aadbULL, -+ 0x3582aff6f0f2f5b4ULL, -+ 0x7228d51f5b150a80ULL, -+ 0xc10699a158b255efULL, -+ 0xfd7c20cc0cdaf4e8ULL, -+ 0x4e526c720f7dab87ULL, -+ 0x09f8169ba49a54b3ULL, -+ 0xbad65a25a73d0bdcULL, -+ 0x710d64410c4b16bdULL, -+ 0xc22328ff0fec49d2ULL, -+ 0x85895216a40bb6e6ULL, -+ 0x36a71ea8a7ace989ULL, -+ 0x0adda7c5f3c4488eULL, -+ 0xb9f3eb7bf06317e1ULL, -+ 0xfe5991925b84e8d5ULL, -+ 0x4d77dd2c5823b7baULL, -+ 0x64b62bcaebc387a1ULL, -+ 0xd7986774e864d8ceULL, -+ 0x90321d9d438327faULL, -+ 0x231c512340247895ULL, -+ 0x1f66e84e144cd992ULL, -+ 0xac48a4f017eb86fdULL, -+ 0xebe2de19bc0c79c9ULL, -+ 0x58cc92a7bfab26a6ULL, -+ 0x9317acc314dd3bc7ULL, -+ 0x2039e07d177a64a8ULL, -+ 0x67939a94bc9d9b9cULL, -+ 0xd4bdd62abf3ac4f3ULL, -+ 0xe8c76f47eb5265f4ULL, -+ 0x5be923f9e8f53a9bULL, -+ 0x1c4359104312c5afULL, -+ 0xaf6d15ae40b59ac0ULL, -+ 0x192d8af2baf0e1e8ULL, -+ 0xaa03c64cb957be87ULL, -+ 0xeda9bca512b041b3ULL, -+ 0x5e87f01b11171edcULL, -+ 0x62fd4976457fbfdbULL, -+ 0xd1d305c846d8e0b4ULL, -+ 0x96797f21ed3f1f80ULL, -+ 0x2557339fee9840efULL, -+ 0xee8c0dfb45ee5d8eULL, -+ 0x5da24145464902e1ULL, -+ 0x1a083bacedaefdd5ULL, -+ 0xa9267712ee09a2baULL, -+ 0x955cce7fba6103bdULL, -+ 0x267282c1b9c65cd2ULL, -+ 0x61d8f8281221a3e6ULL, -+ 0xd2f6b4961186fc89ULL, -+ 0x9f8169ba49a54b33ULL, -+ 0x2caf25044a02145cULL, -+ 0x6b055fede1e5eb68ULL, -+ 0xd82b1353e242b407ULL, -+ 0xe451aa3eb62a1500ULL, -+ 0x577fe680b58d4a6fULL, -+ 0x10d59c691e6ab55bULL, -+ 0xa3fbd0d71dcdea34ULL, -+ 0x6820eeb3b6bbf755ULL, -+ 0xdb0ea20db51ca83aULL, -+ 0x9ca4d8e41efb570eULL, -+ 0x2f8a945a1d5c0861ULL, -+ 0x13f02d374934a966ULL, -+ 0xa0de61894a93f609ULL, -+ 0xe7741b60e174093dULL, -+ 0x545a57dee2d35652ULL, -+ 0xe21ac88218962d7aULL, -+ 0x5134843c1b317215ULL, -+ 0x169efed5b0d68d21ULL, -+ 0xa5b0b26bb371d24eULL, -+ 0x99ca0b06e7197349ULL, -+ 0x2ae447b8e4be2c26ULL, -+ 0x6d4e3d514f59d312ULL, -+ 0xde6071ef4cfe8c7dULL, -+ 0x15bb4f8be788911cULL, -+ 0xa6950335e42fce73ULL, -+ 0xe13f79dc4fc83147ULL, -+ 0x521135624c6f6e28ULL, -+ 0x6e6b8c0f1807cf2fULL, -+ 0xdd45c0b11ba09040ULL, -+ 0x9aefba58b0476f74ULL, -+ 0x29c1f6e6b3e0301bULL, -+ 0xc96c5795d7870f42ULL, -+ 0x7a421b2bd420502dULL, -+ 0x3de861c27fc7af19ULL, -+ 0x8ec62d7c7c60f076ULL, -+ 0xb2bc941128085171ULL, -+ 0x0192d8af2baf0e1eULL, -+ 0x4638a2468048f12aULL, -+ 0xf516eef883efae45ULL, -+ 0x3ecdd09c2899b324ULL, -+ 0x8de39c222b3eec4bULL, -+ 0xca49e6cb80d9137fULL, -+ 0x7967aa75837e4c10ULL, -+ 0x451d1318d716ed17ULL, -+ 0xf6335fa6d4b1b278ULL, -+ 0xb199254f7f564d4cULL, -+ 0x02b769f17cf11223ULL, -+ 0xb4f7f6ad86b4690bULL, -+ 0x07d9ba1385133664ULL, -+ 0x4073c0fa2ef4c950ULL, -+ 0xf35d8c442d53963fULL, -+ 0xcf273529793b3738ULL, -+ 0x7c0979977a9c6857ULL, -+ 0x3ba3037ed17b9763ULL, -+ 0x888d4fc0d2dcc80cULL, -+ 0x435671a479aad56dULL, -+ 0xf0783d1a7a0d8a02ULL, -+ 0xb7d247f3d1ea7536ULL, -+ 0x04fc0b4dd24d2a59ULL, -+ 0x3886b22086258b5eULL, -+ 0x8ba8fe9e8582d431ULL, -+ 0xcc0284772e652b05ULL, -+ 0x7f2cc8c92dc2746aULL, -+ 0x325b15e575e1c3d0ULL, -+ 0x8175595b76469cbfULL, -+ 0xc6df23b2dda1638bULL, -+ 0x75f16f0cde063ce4ULL, -+ 0x498bd6618a6e9de3ULL, -+ 0xfaa59adf89c9c28cULL, -+ 0xbd0fe036222e3db8ULL, -+ 0x0e21ac88218962d7ULL, -+ 0xc5fa92ec8aff7fb6ULL, -+ 0x76d4de52895820d9ULL, -+ 0x317ea4bb22bfdfedULL, -+ 0x8250e80521188082ULL, -+ 0xbe2a516875702185ULL, -+ 0x0d041dd676d77eeaULL, -+ 0x4aae673fdd3081deULL, -+ 0xf9802b81de97deb1ULL, -+ 0x4fc0b4dd24d2a599ULL, -+ 0xfceef8632775faf6ULL, -+ 0xbb44828a8c9205c2ULL, -+ 0x086ace348f355aadULL, -+ 0x34107759db5dfbaaULL, -+ 0x873e3be7d8faa4c5ULL, -+ 0xc094410e731d5bf1ULL, -+ 0x73ba0db070ba049eULL, -+ 0xb86133d4dbcc19ffULL, -+ 0x0b4f7f6ad86b4690ULL, -+ 0x4ce50583738cb9a4ULL, -+ 0xffcb493d702be6cbULL, -+ 0xc3b1f050244347ccULL, -+ 0x709fbcee27e418a3ULL, -+ 0x3735c6078c03e797ULL, -+ 0x841b8ab98fa4b8f8ULL, -+ 0xadda7c5f3c4488e3ULL, -+ 0x1ef430e13fe3d78cULL, -+ 0x595e4a08940428b8ULL, -+ 0xea7006b697a377d7ULL, -+ 0xd60abfdbc3cbd6d0ULL, -+ 0x6524f365c06c89bfULL, -+ 0x228e898c6b8b768bULL, -+ 0x91a0c532682c29e4ULL, -+ 0x5a7bfb56c35a3485ULL, -+ 0xe955b7e8c0fd6beaULL, -+ 0xaeffcd016b1a94deULL, -+ 0x1dd181bf68bdcbb1ULL, -+ 0x21ab38d23cd56ab6ULL, -+ 0x9285746c3f7235d9ULL, -+ 0xd52f0e859495caedULL, -+ 0x6601423b97329582ULL, -+ 0xd041dd676d77eeaaULL, -+ 0x636f91d96ed0b1c5ULL, -+ 0x24c5eb30c5374ef1ULL, -+ 0x97eba78ec690119eULL, -+ 0xab911ee392f8b099ULL, -+ 0x18bf525d915feff6ULL, -+ 0x5f1528b43ab810c2ULL, -+ 0xec3b640a391f4fadULL, -+ 0x27e05a6e926952ccULL, -+ 0x94ce16d091ce0da3ULL, -+ 0xd3646c393a29f297ULL, -+ 0x604a2087398eadf8ULL, -+ 0x5c3099ea6de60cffULL, -+ 0xef1ed5546e415390ULL, -+ 0xa8b4afbdc5a6aca4ULL, -+ 0x1b9ae303c601f3cbULL, -+ 0x56ed3e2f9e224471ULL, -+ 0xe5c372919d851b1eULL, -+ 0xa26908783662e42aULL, -+ 0x114744c635c5bb45ULL, -+ 0x2d3dfdab61ad1a42ULL, -+ 0x9e13b115620a452dULL, -+ 0xd9b9cbfcc9edba19ULL, -+ 0x6a978742ca4ae576ULL, -+ 0xa14cb926613cf817ULL, -+ 0x1262f598629ba778ULL, -+ 0x55c88f71c97c584cULL, -+ 0xe6e6c3cfcadb0723ULL, -+ 0xda9c7aa29eb3a624ULL, -+ 0x69b2361c9d14f94bULL, -+ 0x2e184cf536f3067fULL, -+ 0x9d36004b35545910ULL, -+ 0x2b769f17cf112238ULL, -+ 0x9858d3a9ccb67d57ULL, -+ 0xdff2a94067518263ULL, -+ 0x6cdce5fe64f6dd0cULL, -+ 0x50a65c93309e7c0bULL, -+ 0xe388102d33392364ULL, -+ 0xa4226ac498dedc50ULL, -+ 0x170c267a9b79833fULL, -+ 0xdcd7181e300f9e5eULL, -+ 0x6ff954a033a8c131ULL, -+ 0x28532e49984f3e05ULL, -+ 0x9b7d62f79be8616aULL, -+ 0xa707db9acf80c06dULL, -+ 0x14299724cc279f02ULL, -+ 0x5383edcd67c06036ULL, -+ 0xe0ada17364673f59ULL -+ } -+}; -+ -+ -+/** -+ \brief Initializes the crc seed -+ */ -+static __inline__ uint64_t crc64_init(void) -+{ -+ return CRC64_ECMA_182.initial; -+} -+ -+/** -+ \brief Computes 64 bit the crc -+ \param[in] data Pointer to the Data in the frame -+ \param[in] len Length of the Data -+ \param[in] crc seed -+ \return calculated crc -+ */ -+static __inline__ uint64_t crc64_compute(void const *data, -+ uint32_t len, -+ uint64_t seed) -+{ -+ uint32_t i; -+ uint64_t crc = seed; -+ uint8_t *bdata = (uint8_t *) data; -+ -+ for (i = 0; i < len; i++) -+ crc = -+ CRC64_ECMA_182. -+ table[(crc ^ *bdata++) & CRC64_BYTE_MASK] ^ (crc >> 8); -+ -+ return crc; -+} -+ -+ -+#endif /* __CRC64_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c -@@ -0,0 +1,7582 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_cc.c -+ -+ @Description FM Coarse Classifier implementation -+ *//***************************************************************************/ -+#include -+#include "std_ext.h" -+#include "error_ext.h" -+#include "string_ext.h" -+#include "debug_ext.h" -+#include "fm_pcd_ext.h" -+#include "fm_muram_ext.h" -+ -+#include "fm_common.h" -+#include "fm_pcd.h" -+#include "fm_hc.h" -+#include "fm_cc.h" -+#include "crc64.h" -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+ -+ -+static t_Error CcRootTryLock(t_Handle h_FmPcdCcTree) -+{ -+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; -+ -+ ASSERT_COND(h_FmPcdCcTree); -+ -+ if (FmPcdLockTryLock(p_FmPcdCcTree->p_Lock)) -+ return E_OK; -+ -+ return ERROR_CODE(E_BUSY); -+} -+ -+static void CcRootReleaseLock(t_Handle h_FmPcdCcTree) -+{ -+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; -+ -+ ASSERT_COND(h_FmPcdCcTree); -+ -+ FmPcdLockUnlock(p_FmPcdCcTree->p_Lock); -+} -+ -+static void UpdateNodeOwner(t_FmPcdCcNode *p_CcNode, bool add) -+{ -+ uint32_t intFlags; -+ -+ ASSERT_COND(p_CcNode); -+ -+ intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); -+ -+ if (add) -+ p_CcNode->owners++; -+ else -+ { -+ ASSERT_COND(p_CcNode->owners); -+ p_CcNode->owners--; -+ } -+ -+ XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); -+} -+ -+static __inline__ t_FmPcdStatsObj* DequeueStatsObj(t_List *p_List) -+{ -+ t_FmPcdStatsObj *p_StatsObj = NULL; -+ t_List *p_Next; -+ -+ if (!LIST_IsEmpty(p_List)) -+ { -+ p_Next = LIST_FIRST(p_List); -+ p_StatsObj = LIST_OBJECT(p_Next, t_FmPcdStatsObj, node); -+ ASSERT_COND(p_StatsObj); -+ LIST_DelAndInit(p_Next); -+ } -+ -+ return p_StatsObj; -+} -+ -+static __inline__ void EnqueueStatsObj(t_List *p_List, -+ t_FmPcdStatsObj *p_StatsObj) -+{ -+ LIST_AddToTail(&p_StatsObj->node, p_List); -+} -+ -+static void FreeStatObjects(t_List *p_List, t_Handle h_FmMuram) -+{ -+ t_FmPcdStatsObj *p_StatsObj; -+ -+ while (!LIST_IsEmpty(p_List)) -+ { -+ p_StatsObj = DequeueStatsObj(p_List); -+ ASSERT_COND(p_StatsObj); -+ -+ FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd); -+ FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters); -+ -+ XX_Free(p_StatsObj); -+ } -+} -+ -+static t_FmPcdStatsObj* GetStatsObj(t_FmPcdCcNode *p_CcNode) -+{ -+ t_FmPcdStatsObj* p_StatsObj; -+ t_Handle h_FmMuram; -+ -+ ASSERT_COND(p_CcNode); -+ -+ /* If 'maxNumOfKeys' was passed, all statistics object were preallocated -+ upon node initialization */ -+ if (p_CcNode->maxNumOfKeys) -+ { -+ p_StatsObj = DequeueStatsObj(&p_CcNode->availableStatsLst); -+ -+ /* Clean statistics counters & ADs */ -+ MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize); -+ } -+ else -+ { -+ h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram; -+ ASSERT_COND(h_FmMuram); -+ -+ p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj)); -+ if (!p_StatsObj) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("statistics object")); -+ return NULL; -+ } -+ -+ p_StatsObj->h_StatsAd = (t_Handle)FM_MURAM_AllocMem( -+ h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_StatsObj->h_StatsAd) -+ { -+ XX_Free(p_StatsObj); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics ADs")); -+ return NULL; -+ } -+ MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ p_StatsObj->h_StatsCounters = (t_Handle)FM_MURAM_AllocMem( -+ h_FmMuram, p_CcNode->countersArraySize, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_StatsObj->h_StatsCounters) -+ { -+ FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd); -+ XX_Free(p_StatsObj); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics counters")); -+ return NULL; -+ } -+ MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize); -+ } -+ -+ return p_StatsObj; -+} -+ -+static void PutStatsObj(t_FmPcdCcNode *p_CcNode, t_FmPcdStatsObj *p_StatsObj) -+{ -+ t_Handle h_FmMuram; -+ -+ ASSERT_COND(p_CcNode); -+ ASSERT_COND(p_StatsObj); -+ -+ /* If 'maxNumOfKeys' was passed, all statistics object were preallocated -+ upon node initialization and now will be enqueued back to the list */ -+ if (p_CcNode->maxNumOfKeys) -+ { -+ /* Clean statistics counters */ -+ MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize); -+ -+ /* Clean statistics ADs */ -+ MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj); -+ } -+ else -+ { -+ h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram; -+ ASSERT_COND(h_FmMuram); -+ -+ FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd); -+ FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters); -+ -+ XX_Free(p_StatsObj); -+ } -+} -+ -+static void SetStatsCounters(t_AdOfTypeStats *p_StatsAd, -+ uint32_t statsCountersAddr) -+{ -+ uint32_t tmp = (statsCountersAddr & FM_PCD_AD_STATS_COUNTERS_ADDR_MASK); -+ -+ WRITE_UINT32(p_StatsAd->statsTableAddr, tmp); -+} -+ -+ -+static void UpdateStatsAd(t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, -+ t_Handle h_Ad, uint64_t physicalMuramBase) -+{ -+ t_AdOfTypeStats *p_StatsAd; -+ uint32_t statsCountersAddr, nextActionAddr, tmp; -+#if (DPAA_VERSION >= 11) -+ uint32_t frameLengthRangesAddr; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ p_StatsAd = (t_AdOfTypeStats *)p_FmPcdCcStatsParams->h_StatsAd; -+ -+ tmp = FM_PCD_AD_STATS_TYPE; -+ -+#if (DPAA_VERSION >= 11) -+ if (p_FmPcdCcStatsParams->h_StatsFLRs) -+ { -+ frameLengthRangesAddr = (uint32_t)((XX_VirtToPhys( -+ p_FmPcdCcStatsParams->h_StatsFLRs) - physicalMuramBase)); -+ tmp |= (frameLengthRangesAddr & FM_PCD_AD_STATS_FLR_ADDR_MASK); -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ WRITE_UINT32(p_StatsAd->profileTableAddr, tmp); -+ -+ nextActionAddr = (uint32_t)((XX_VirtToPhys(h_Ad) - physicalMuramBase)); -+ tmp = 0; -+ tmp |= (uint32_t)((nextActionAddr << FM_PCD_AD_STATS_NEXT_ACTION_SHIFT) -+ & FM_PCD_AD_STATS_NEXT_ACTION_MASK); -+ tmp |= (FM_PCD_AD_STATS_NAD_EN | FM_PCD_AD_STATS_OP_CODE); -+ -+#if (DPAA_VERSION >= 11) -+ if (p_FmPcdCcStatsParams->h_StatsFLRs) -+ tmp |= FM_PCD_AD_STATS_FLR_EN; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ WRITE_UINT32(p_StatsAd->nextActionIndx, tmp); -+ -+ statsCountersAddr = (uint32_t)((XX_VirtToPhys( -+ p_FmPcdCcStatsParams->h_StatsCounters) - physicalMuramBase)); -+ SetStatsCounters(p_StatsAd, statsCountersAddr); -+} -+ -+static void FillAdOfTypeContLookup(t_Handle h_Ad, -+ t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, -+ t_Handle h_FmPcd, t_Handle p_CcNode, -+ t_Handle h_Manip, t_Handle h_FrmReplic) -+{ -+ t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_CcNode; -+ t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad; -+ t_Handle h_TmpAd; -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t tmpReg32; -+ t_Handle p_AdNewPtr = NULL; -+ -+ UNUSED(h_Manip); -+ UNUSED(h_FrmReplic); -+ -+ /* there are 3 cases handled in this routine of building a "Continue lookup" type AD. -+ * Case 1: No Manip. The action descriptor is built within the match table. -+ * p_AdResult = p_AdNewPtr; -+ * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized -+ * either in the FmPcdManipUpdateAdResultForCc routine or it was already -+ * initialized and returned here. -+ * p_AdResult (within the match table) will be initialized after -+ * this routine returns and point to the existing AD. -+ * Case 3: Manip exists. The action descriptor is built within the match table. -+ * FmPcdManipUpdateAdContLookupForCc returns a NULL p_AdNewPtr. -+ */ -+ -+ /* As default, the "new" ptr is the current one. i.e. the content of the result -+ * AD will be written into the match table itself (case (1))*/ -+ p_AdNewPtr = p_AdContLookup; -+ -+ /* Initialize an action descriptor, if current statistics mode requires an Ad */ -+ if (p_FmPcdCcStatsParams) -+ { -+ ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd); -+ ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters); -+ -+ /* Swapping addresses between statistics Ad and the current lookup AD */ -+ h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd; -+ p_FmPcdCcStatsParams->h_StatsAd = h_Ad; -+ h_Ad = h_TmpAd; -+ -+ p_AdNewPtr = h_Ad; -+ p_AdContLookup = h_Ad; -+ -+ /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */ -+ UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase); -+ } -+ -+#if DPAA_VERSION >= 11 -+ if (h_Manip && h_FrmReplic) -+ FmPcdManipUpdateAdContLookupForCc( -+ h_Manip, -+ h_Ad, -+ &p_AdNewPtr, -+ (uint32_t)((XX_VirtToPhys( -+ FrmReplicGroupGetSourceTableDescriptor(h_FrmReplic)) -+ - p_FmPcd->physicalMuramBase))); -+ else -+ if (h_FrmReplic) -+ FrmReplicGroupUpdateAd(h_FrmReplic, h_Ad, &p_AdNewPtr); -+ else -+#endif /* (DPAA_VERSION >= 11) */ -+ if (h_Manip) -+ FmPcdManipUpdateAdContLookupForCc( -+ h_Manip, -+ h_Ad, -+ &p_AdNewPtr, -+ -+#ifdef FM_CAPWAP_SUPPORT -+ /*no check for opcode of manip - this step can be reached only with capwap_applic_specific*/ -+ (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase)) -+#else /* not FM_CAPWAP_SUPPORT */ -+ (uint32_t)((XX_VirtToPhys(p_Node->h_Ad) -+ - p_FmPcd->physicalMuramBase)) -+#endif /* not FM_CAPWAP_SUPPORT */ -+ ); -+ -+ /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */ -+ if (p_AdNewPtr) -+ { -+ /* cases (1) & (2) */ -+ tmpReg32 = 0; -+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ tmpReg32 |= -+ p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) : -+ 0; -+ tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable) -+ - p_FmPcd->physicalMuramBase); -+ WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32); -+ -+ tmpReg32 = 0; -+ tmpReg32 |= p_Node->numOfKeys << 24; -+ tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0); -+ tmpReg32 |= -+ p_Node->h_KeysMatchTable ? (uint32_t)(XX_VirtToPhys( -+ p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) : -+ 0; -+ WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32); -+ -+ tmpReg32 = 0; -+ tmpReg32 |= p_Node->prsArrayOffset << 24; -+ tmpReg32 |= p_Node->offset << 16; -+ tmpReg32 |= p_Node->parseCode; -+ WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32); -+ -+ MemCpy8((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask, -+ CC_GLBL_MASK_SIZE); -+ } -+} -+ -+static t_Error AllocAndFillAdForContLookupManip(t_Handle h_CcNode) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ uint32_t intFlags; -+ -+ ASSERT_COND(p_CcNode); -+ -+ intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); -+ -+ if (!p_CcNode->h_Ad) -+ { -+ if (p_CcNode->maxNumOfKeys) -+ p_CcNode->h_Ad = p_CcNode->h_TmpAd; -+ else -+ p_CcNode->h_Ad = (t_Handle)FM_MURAM_AllocMem( -+ ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram, -+ FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN); -+ -+ XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); -+ -+ if (!p_CcNode->h_Ad) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for CC action descriptor")); -+ -+ MemSet8(p_CcNode->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ FillAdOfTypeContLookup(p_CcNode->h_Ad, NULL, p_CcNode->h_FmPcd, -+ p_CcNode, NULL, NULL); -+ } -+ else -+ XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); -+ -+ return E_OK; -+} -+ -+static t_Error SetRequiredAction1( -+ t_Handle h_FmPcd, uint32_t requiredAction, -+ t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp, -+ t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree) -+{ -+ t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp; -+ uint32_t tmpReg32; -+ t_Error err; -+ t_FmPcdCcNode *p_CcNode; -+ int i = 0; -+ uint16_t tmp = 0; -+ uint16_t profileId; -+ uint8_t relativeSchemeId, physicalSchemeId; -+ t_CcNodeInformation ccNodeInfo; -+ -+ for (i = 0; i < numOfEntries; i++) -+ { -+ if (i == 0) -+ h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE); -+ else -+ h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ switch (p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.nextEngine) -+ { -+ case (e_FM_PCD_CC): -+ if (requiredAction) -+ { -+ p_CcNode = -+ p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode; -+ ASSERT_COND(p_CcNode); -+ if (p_CcNode->shadowAction == requiredAction) -+ break; -+ if ((requiredAction & UPDATE_CC_WITH_TREE) -+ && !(p_CcNode->shadowAction & UPDATE_CC_WITH_TREE)) -+ { -+ -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ ccNodeInfo.h_CcNode = h_Tree; -+ EnqueueNodeInfoToRelevantLst(&p_CcNode->ccTreesLst, -+ &ccNodeInfo, NULL); -+ p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= -+ UPDATE_CC_WITH_TREE; -+ } -+ if ((requiredAction & UPDATE_CC_SHADOW_CLEAR) -+ && !(p_CcNode->shadowAction & UPDATE_CC_SHADOW_CLEAR)) -+ { -+ -+ p_CcNode->shadowAction = 0; -+ } -+ -+ if ((requiredAction & UPDATE_CC_WITH_DELETE_TREE) -+ && !(p_CcNode->shadowAction -+ & UPDATE_CC_WITH_DELETE_TREE)) -+ { -+ DequeueNodeInfoFromRelevantLst(&p_CcNode->ccTreesLst, -+ h_Tree, NULL); -+ p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= -+ UPDATE_CC_WITH_DELETE_TREE; -+ } -+ if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine -+ != e_FM_PCD_INVALID) -+ tmp = (uint8_t)(p_CcNode->numOfKeys + 1); -+ else -+ tmp = p_CcNode->numOfKeys; -+ err = SetRequiredAction1(h_FmPcd, requiredAction, -+ p_CcNode->keyAndNextEngineParams, -+ p_CcNode->h_AdTable, tmp, h_Tree); -+ if (err != E_OK) -+ return err; -+ if (requiredAction != UPDATE_CC_SHADOW_CLEAR) -+ p_CcNode->shadowAction |= requiredAction; -+ } -+ break; -+ -+ case (e_FM_PCD_KG): -+ if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) -+ && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction -+ & UPDATE_NIA_ENQ_WITHOUT_DMA)) -+ { -+ physicalSchemeId = -+ FmPcdKgGetSchemeId( -+ p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme); -+ relativeSchemeId = FmPcdKgGetRelativeSchemeId( -+ h_FmPcd, physicalSchemeId); -+ if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); -+ if (!FmPcdKgIsSchemeValidSw( -+ p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Invalid direct scheme.")); -+ if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_STATE, -+ ("For this action scheme has to be direct.")); -+ err = -+ FmPcdKgCcGetSetParams( -+ h_FmPcd, -+ p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme, -+ requiredAction, 0); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= -+ requiredAction; -+ } -+ break; -+ -+ case (e_FM_PCD_PLCR): -+ if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) -+ && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction -+ & UPDATE_NIA_ENQ_WITHOUT_DMA)) -+ { -+ if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams) -+ RETURN_ERROR( -+ MAJOR, -+ E_NOT_SUPPORTED, -+ ("In this initialization only overrideFqid can be initialized")); -+ if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile) -+ RETURN_ERROR( -+ MAJOR, -+ E_NOT_SUPPORTED, -+ ("In this initialization only overrideFqid can be initialized")); -+ err = -+ FmPcdPlcrGetAbsoluteIdByProfileParams( -+ h_FmPcd, -+ e_FM_PCD_PLCR_SHARED, -+ NULL, -+ p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId, -+ &profileId); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId, -+ requiredAction); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= -+ requiredAction; -+ } -+ break; -+ -+ case (e_FM_PCD_DONE): -+ if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) -+ && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction -+ & UPDATE_NIA_ENQ_WITHOUT_DMA)) -+ { -+ tmpReg32 = GET_UINT32(p_AdTmp->nia); -+ if ((tmpReg32 & GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd)) -+ != GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("Next engine was previously assigned not as PCD_DONE")); -+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; -+ WRITE_UINT32(p_AdTmp->nia, tmpReg32); -+ p_CcKeyAndNextEngineParamsTmp[i].shadowAction |= -+ requiredAction; -+ } -+ break; -+ -+ default: -+ break; -+ } -+ } -+ -+ return E_OK; -+} -+ -+static t_Error SetRequiredAction( -+ t_Handle h_FmPcd, uint32_t requiredAction, -+ t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp, -+ t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree) -+{ -+ t_Error err = SetRequiredAction1(h_FmPcd, requiredAction, -+ p_CcKeyAndNextEngineParamsTmp, h_AdTmp, -+ numOfEntries, h_Tree); -+ if (err != E_OK) -+ return err; -+ return SetRequiredAction1(h_FmPcd, UPDATE_CC_SHADOW_CLEAR, -+ p_CcKeyAndNextEngineParamsTmp, h_AdTmp, -+ numOfEntries, h_Tree); -+} -+ -+static t_Error ReleaseModifiedDataStructure( -+ t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst, -+ t_List *h_FmPcdNewPointersLst, -+ t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams, -+ bool useShadowStructs) -+{ -+ t_List *p_Pos; -+ t_Error err = E_OK; -+ t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation; -+ t_Handle h_Muram; -+ t_FmPcdCcNode *p_FmPcdCcNextNode, *p_FmPcdCcWorkingOnNode; -+ t_List *p_UpdateLst; -+ uint32_t intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_AdditionalParams->h_CurrentNode, -+ E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst, E_INVALID_HANDLE); -+ -+ /* We don't update subtree of the new node with new tree because it was done in the previous stage */ -+ if (p_AdditionalParams->h_NodeForAdd) -+ { -+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForAdd; -+ -+ if (!p_AdditionalParams->tree) -+ p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst; -+ else -+ p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst; -+ -+ p_CcNodeInformation = FindNodeInfoInReleventLst( -+ p_UpdateLst, p_AdditionalParams->h_CurrentNode, -+ p_FmPcdCcNextNode->h_Spinlock); -+ -+ if (p_CcNodeInformation) -+ p_CcNodeInformation->index++; -+ else -+ { -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ ccNodeInfo.h_CcNode = (t_Handle)p_AdditionalParams->h_CurrentNode; -+ ccNodeInfo.index = 1; -+ EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo, -+ p_FmPcdCcNextNode->h_Spinlock); -+ } -+ if (p_AdditionalParams->h_ManipForAdd) -+ { -+ p_CcNodeInformation = FindNodeInfoInReleventLst( -+ FmPcdManipGetNodeLstPointedOnThisManip( -+ p_AdditionalParams->h_ManipForAdd), -+ p_AdditionalParams->h_CurrentNode, -+ FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForAdd)); -+ -+ if (p_CcNodeInformation) -+ p_CcNodeInformation->index++; -+ else -+ { -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ ccNodeInfo.h_CcNode = -+ (t_Handle)p_AdditionalParams->h_CurrentNode; -+ ccNodeInfo.index = 1; -+ EnqueueNodeInfoToRelevantLst( -+ FmPcdManipGetNodeLstPointedOnThisManip( -+ p_AdditionalParams->h_ManipForAdd), -+ &ccNodeInfo, -+ FmPcdManipGetSpinlock( -+ p_AdditionalParams->h_ManipForAdd)); -+ } -+ } -+ } -+ -+ if (p_AdditionalParams->h_NodeForRmv) -+ { -+ p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForRmv; -+ -+ if (!p_AdditionalParams->tree) -+ { -+ p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst; -+ p_FmPcdCcWorkingOnNode = -+ (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode); -+ -+ for (p_Pos = LIST_FIRST(&p_FmPcdCcWorkingOnNode->ccTreesLst); -+ p_Pos != (&p_FmPcdCcWorkingOnNode->ccTreesLst); p_Pos = -+ LIST_NEXT(p_Pos)) -+ { -+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); -+ -+ ASSERT_COND(p_CcNodeInformation->h_CcNode); -+ -+ err = -+ SetRequiredAction( -+ h_FmPcd, -+ UPDATE_CC_WITH_DELETE_TREE, -+ &((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex], -+ PTR_MOVE(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable, p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE), -+ 1, p_CcNodeInformation->h_CcNode); -+ } -+ } -+ else -+ { -+ p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst; -+ -+ err = -+ SetRequiredAction( -+ h_FmPcd, -+ UPDATE_CC_WITH_DELETE_TREE, -+ &((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex], -+ UINT_TO_PTR(((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE), -+ 1, p_AdditionalParams->h_CurrentNode); -+ } -+ if (err) -+ return err; -+ -+ /* We remove from the subtree of the removed node tree because it wasn't done in the previous stage -+ Update ccPrevNodesLst or ccTreeIdLst of the removed node -+ Update of the node owner */ -+ p_CcNodeInformation = FindNodeInfoInReleventLst( -+ p_UpdateLst, p_AdditionalParams->h_CurrentNode, -+ p_FmPcdCcNextNode->h_Spinlock); -+ -+ ASSERT_COND(p_CcNodeInformation); -+ ASSERT_COND(p_CcNodeInformation->index); -+ -+ p_CcNodeInformation->index--; -+ -+ if (p_CcNodeInformation->index == 0) -+ DequeueNodeInfoFromRelevantLst(p_UpdateLst, -+ p_AdditionalParams->h_CurrentNode, -+ p_FmPcdCcNextNode->h_Spinlock); -+ -+ UpdateNodeOwner(p_FmPcdCcNextNode, FALSE); -+ -+ if (p_AdditionalParams->h_ManipForRmv) -+ { -+ p_CcNodeInformation = FindNodeInfoInReleventLst( -+ FmPcdManipGetNodeLstPointedOnThisManip( -+ p_AdditionalParams->h_ManipForRmv), -+ p_AdditionalParams->h_CurrentNode, -+ FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForRmv)); -+ -+ ASSERT_COND(p_CcNodeInformation); -+ ASSERT_COND(p_CcNodeInformation->index); -+ -+ p_CcNodeInformation->index--; -+ -+ if (p_CcNodeInformation->index == 0) -+ DequeueNodeInfoFromRelevantLst( -+ FmPcdManipGetNodeLstPointedOnThisManip( -+ p_AdditionalParams->h_ManipForRmv), -+ p_AdditionalParams->h_CurrentNode, -+ FmPcdManipGetSpinlock( -+ p_AdditionalParams->h_ManipForRmv)); -+ } -+ } -+ -+ if (p_AdditionalParams->h_ManipForRmv) -+ FmPcdManipUpdateOwner(p_AdditionalParams->h_ManipForRmv, FALSE); -+ -+ if (p_AdditionalParams->p_StatsObjForRmv) -+ PutStatsObj((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode), -+ p_AdditionalParams->p_StatsObjForRmv); -+ -+#if (DPAA_VERSION >= 11) -+ if (p_AdditionalParams->h_FrmReplicForRmv) -+ FrmReplicGroupUpdateOwner(p_AdditionalParams->h_FrmReplicForRmv, -+ FALSE/* remove */); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ if (!useShadowStructs) -+ { -+ h_Muram = FmPcdGetMuramHandle(h_FmPcd); -+ ASSERT_COND(h_Muram); -+ -+ if ((p_AdditionalParams->tree && !((t_FmPcd *)h_FmPcd)->p_CcShadow) -+ || (!p_AdditionalParams->tree -+ && !((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->maxNumOfKeys)) -+ { -+ /* We release new AD which was allocated and updated for copy from to actual AD */ -+ for (p_Pos = LIST_FIRST(h_FmPcdNewPointersLst); -+ p_Pos != (h_FmPcdNewPointersLst); p_Pos = LIST_NEXT(p_Pos)) -+ { -+ -+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); -+ ASSERT_COND(p_CcNodeInformation->h_CcNode); -+ FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode); -+ } -+ } -+ -+ /* Free Old data structure if it has to be freed - new data structure was allocated*/ -+ if (p_AdditionalParams->p_AdTableOld) -+ FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_AdTableOld); -+ -+ if (p_AdditionalParams->p_KeysMatchTableOld) -+ FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_KeysMatchTableOld); -+ } -+ -+ /* Update current modified node with changed fields if it's required*/ -+ if (!p_AdditionalParams->tree) -+ { -+ if (p_AdditionalParams->p_AdTableNew) -+ ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable = -+ p_AdditionalParams->p_AdTableNew; -+ -+ if (p_AdditionalParams->p_KeysMatchTableNew) -+ ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_KeysMatchTable = -+ p_AdditionalParams->p_KeysMatchTableNew; -+ -+ /* Locking node's spinlock before updating 'keys and next engine' structure, -+ as it maybe used to retrieve keys statistics */ -+ intFlags = -+ XX_LockIntrSpinlock( -+ ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock); -+ -+ ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->numOfKeys = -+ p_AdditionalParams->numOfKeys; -+ -+ memcpy(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams, -+ &p_AdditionalParams->keyAndNextEngineParams, -+ sizeof(t_FmPcdCcKeyAndNextEngineParams) * (CC_MAX_NUM_OF_KEYS)); -+ -+ XX_UnlockIntrSpinlock( -+ ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock, -+ intFlags); -+ } -+ else -+ { -+ uint8_t numEntries = -+ ((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->numOfEntries; -+ ASSERT_COND(numEntries < FM_PCD_MAX_NUM_OF_CC_GROUPS); -+ memcpy(&((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams, -+ &p_AdditionalParams->keyAndNextEngineParams, -+ sizeof(t_FmPcdCcKeyAndNextEngineParams) * numEntries); -+ } -+ -+ ReleaseLst(h_FmPcdOldPointersLst); -+ ReleaseLst(h_FmPcdNewPointersLst); -+ -+ XX_Free(p_AdditionalParams); -+ -+ return E_OK; -+} -+ -+static t_Handle BuildNewAd( -+ t_Handle h_Ad, -+ t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, -+ t_FmPcdCcNode *p_CcNode, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcdCcNode *p_FmPcdCcNodeTmp; -+ t_Handle h_OrigAd = NULL; -+ -+ p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode)); -+ if (!p_FmPcdCcNodeTmp) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp")); -+ return NULL; -+ } -+ memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode)); -+ -+ p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys; -+ p_FmPcdCcNodeTmp->h_KeysMatchTable = -+ p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew; -+ p_FmPcdCcNodeTmp->h_AdTable = -+ p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew; -+ -+ p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask; -+ p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode; -+ p_FmPcdCcNodeTmp->offset = p_CcNode->offset; -+ p_FmPcdCcNodeTmp->prsArrayOffset = p_CcNode->prsArrayOffset; -+ p_FmPcdCcNodeTmp->ctrlFlow = p_CcNode->ctrlFlow; -+ p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_CcNode->ccKeySizeAccExtraction; -+ p_FmPcdCcNodeTmp->sizeOfExtraction = p_CcNode->sizeOfExtraction; -+ p_FmPcdCcNodeTmp->glblMaskSize = p_CcNode->glblMaskSize; -+ p_FmPcdCcNodeTmp->p_GlblMask = p_CcNode->p_GlblMask; -+ -+ if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC) -+ { -+ if (p_FmPcdCcNextEngineParams->h_Manip) -+ { -+ h_OrigAd = p_CcNode->h_Ad; -+ if (AllocAndFillAdForContLookupManip( -+ p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) -+ != E_OK) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ XX_Free(p_FmPcdCcNodeTmp); -+ return NULL; -+ } -+ } -+ FillAdOfTypeContLookup(h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp, -+ h_OrigAd ? NULL : p_FmPcdCcNextEngineParams->h_Manip, NULL); -+ } -+ -+#if (DPAA_VERSION >= 11) -+ if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_FR) -+ && (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)) -+ { -+ FillAdOfTypeContLookup( -+ h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp, -+ p_FmPcdCcNextEngineParams->h_Manip, -+ p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic); -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ XX_Free(p_FmPcdCcNodeTmp); -+ -+ return E_OK; -+} -+ -+static t_Error DynamicChangeHc( -+ t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst, -+ t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams, -+ bool useShadowStructs) -+{ -+ t_List *p_PosOld, *p_PosNew; -+ uint32_t oldAdAddrOffset, newAdAddrOffset; -+ uint16_t i = 0; -+ t_Error err = E_OK; -+ uint8_t numOfModifiedPtr; -+ -+ ASSERT_COND(h_FmPcd); -+ ASSERT_COND(h_OldPointersLst); -+ ASSERT_COND(h_NewPointersLst); -+ -+ numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst); -+ -+ if (numOfModifiedPtr) -+ { -+ p_PosNew = LIST_FIRST(h_NewPointersLst); -+ p_PosOld = LIST_FIRST(h_OldPointersLst); -+ -+ /* Retrieve address of new AD */ -+ newAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd, -+ p_PosNew); -+ if (newAdAddrOffset == (uint32_t)ILLEGAL_BASE) -+ { -+ ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, -+ h_NewPointersLst, -+ p_AdditionalParams, useShadowStructs); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address")); -+ } -+ -+ for (i = 0; i < numOfModifiedPtr; i++) -+ { -+ /* Retrieve address of current AD */ -+ oldAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd, -+ p_PosOld); -+ if (oldAdAddrOffset == (uint32_t)ILLEGAL_BASE) -+ { -+ ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, -+ h_NewPointersLst, -+ p_AdditionalParams, -+ useShadowStructs); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old AD address")); -+ } -+ -+ /* Invoke host command to copy from new AD to old AD */ -+ err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc, -+ oldAdAddrOffset, newAdAddrOffset); -+ if (err) -+ { -+ ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, -+ h_NewPointersLst, -+ p_AdditionalParams, -+ useShadowStructs); -+ RETURN_ERROR( -+ MAJOR, -+ err, -+ ("For part of nodes changes are done - situation is danger")); -+ } -+ -+ p_PosOld = LIST_NEXT(p_PosOld); -+ } -+ } -+ return E_OK; -+} -+ -+static t_Error DoDynamicChange( -+ t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst, -+ t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams, -+ bool useShadowStructs) -+{ -+ t_FmPcdCcNode *p_CcNode = -+ (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode); -+ t_List *p_PosNew; -+ t_CcNodeInformation *p_CcNodeInfo; -+ t_FmPcdCcNextEngineParams nextEngineParams; -+ t_Handle h_Ad; -+ uint32_t keySize; -+ t_Error err = E_OK; -+ uint8_t numOfModifiedPtr; -+ -+ ASSERT_COND(h_FmPcd); -+ -+ memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams)); -+ -+ numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst); -+ -+ if (numOfModifiedPtr) -+ { -+ -+ p_PosNew = LIST_FIRST(h_NewPointersLst); -+ -+ /* Invoke host-command to copy from the new Ad to existing Ads */ -+ err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst, -+ p_AdditionalParams, useShadowStructs); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (useShadowStructs) -+ { -+ /* When the host-command above has ended, the old structures are 'free'and we can update -+ them by copying from the new shadow structures. */ -+ if (p_CcNode->lclMask) -+ keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction); -+ else -+ keySize = p_CcNode->ccKeySizeAccExtraction; -+ -+ MemCpy8(p_AdditionalParams->p_KeysMatchTableOld, -+ p_AdditionalParams->p_KeysMatchTableNew, -+ p_CcNode->maxNumOfKeys * keySize * sizeof(uint8_t)); -+ -+ MemCpy8( -+ p_AdditionalParams->p_AdTableOld, -+ p_AdditionalParams->p_AdTableNew, -+ (uint32_t)((p_CcNode->maxNumOfKeys + 1) -+ * FM_PCD_CC_AD_ENTRY_SIZE)); -+ -+ /* Retrieve the address of the allocated Ad */ -+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_PosNew); -+ h_Ad = p_CcNodeInfo->h_CcNode; -+ -+ /* Build a new Ad that holds the old (now updated) structures */ -+ p_AdditionalParams->p_KeysMatchTableNew = -+ p_AdditionalParams->p_KeysMatchTableOld; -+ p_AdditionalParams->p_AdTableNew = p_AdditionalParams->p_AdTableOld; -+ -+ nextEngineParams.nextEngine = e_FM_PCD_CC; -+ nextEngineParams.params.ccParams.h_CcNode = (t_Handle)p_CcNode; -+ -+ BuildNewAd(h_Ad, p_AdditionalParams, p_CcNode, &nextEngineParams); -+ -+ /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */ -+ err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst, -+ p_AdditionalParams, useShadowStructs); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ -+ err = ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst, -+ h_NewPointersLst, -+ p_AdditionalParams, useShadowStructs); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+#ifdef FM_CAPWAP_SUPPORT -+static bool IsCapwapApplSpecific(t_Handle h_Node) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_Node; -+ bool isManipForCapwapApplSpecificBuild = FALSE; -+ int i = 0; -+ -+ ASSERT_COND(h_Node); -+ /* assumption that this function called only for INDEXED_FLOW_ID - so no miss*/ -+ for (i = 0; i < p_CcNode->numOfKeys; i++) -+ { -+ if ( p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip && -+ FmPcdManipIsCapwapApplSpecific(p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)) -+ { -+ isManipForCapwapApplSpecificBuild = TRUE; -+ break; -+ } -+ } -+ return isManipForCapwapApplSpecificBuild; -+ -+} -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+static t_Error CcUpdateParam( -+ t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort, -+ t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParams, -+ uint16_t numOfEntries, t_Handle h_Ad, bool validate, uint16_t level, -+ t_Handle h_FmTree, bool modify) -+{ -+ t_FmPcdCcNode *p_CcNode; -+ t_Error err; -+ uint16_t tmp = 0; -+ int i = 0; -+ t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree; -+ -+ level++; -+ -+ if (p_CcTree->h_IpReassemblyManip) -+ { -+ err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort, -+ p_CcTree->h_IpReassemblyManip, NULL, validate, -+ level, h_FmTree, modify); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ if (p_CcTree->h_CapwapReassemblyManip) -+ { -+ err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort, -+ p_CcTree->h_CapwapReassemblyManip, NULL, validate, -+ level, h_FmTree, modify); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ if (numOfEntries) -+ { -+ for (i = 0; i < numOfEntries; i++) -+ { -+ if (i == 0) -+ h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE); -+ else -+ h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ if (p_CcKeyAndNextEngineParams[i].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ { -+ p_CcNode = -+ p_CcKeyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; -+ ASSERT_COND(p_CcNode); -+ -+ if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip) -+ { -+ err = -+ FmPcdManipUpdate( -+ h_FmPcd, -+ NULL, -+ h_FmPort, -+ p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip, -+ h_Ad, validate, level, h_FmTree, modify); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine -+ != e_FM_PCD_INVALID) -+ tmp = (uint8_t)(p_CcNode->numOfKeys + 1); -+ else -+ tmp = p_CcNode->numOfKeys; -+ -+ err = CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort, -+ p_CcNode->keyAndNextEngineParams, tmp, -+ p_CcNode->h_AdTable, validate, level, -+ h_FmTree, modify); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ else -+ { -+ if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip) -+ { -+ err = -+ FmPcdManipUpdate( -+ h_FmPcd, -+ NULL, -+ h_FmPort, -+ p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip, -+ h_Ad, validate, level, h_FmTree, modify); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ } -+ } -+ -+ return E_OK; -+} -+ -+static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam) -+{ -+ switch (p_CcNodeParam->extractCcParams.extractNonHdr.action) -+ { -+ case (e_FM_PCD_ACTION_EXACT_MATCH): -+ switch (p_CcNodeParam->extractCcParams.extractNonHdr.src) -+ { -+ case (e_FM_PCD_EXTRACT_FROM_KEY): -+ return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH; -+ case (e_FM_PCD_EXTRACT_FROM_HASH): -+ return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH; -+ default: -+ return CC_PRIVATE_INFO_NONE; -+ } -+ -+ case (e_FM_PCD_ACTION_INDEXED_LOOKUP): -+ switch (p_CcNodeParam->extractCcParams.extractNonHdr.src) -+ { -+ case (e_FM_PCD_EXTRACT_FROM_HASH): -+ return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP; -+ case (e_FM_PCD_EXTRACT_FROM_FLOW_ID): -+ return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP; -+ default: -+ return CC_PRIVATE_INFO_NONE; -+ } -+ -+ default: -+ break; -+ } -+ -+ return CC_PRIVATE_INFO_NONE; -+} -+ -+static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst( -+ t_List *p_List) -+{ -+ t_CcNodeInformation *p_CcNodeInfo = NULL; -+ -+ if (!LIST_IsEmpty(p_List)) -+ { -+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next); -+ LIST_DelAndInit(&p_CcNodeInfo->node); -+ } -+ -+ return p_CcNodeInfo; -+} -+ -+void ReleaseLst(t_List *p_List) -+{ -+ t_CcNodeInformation *p_CcNodeInfo = NULL; -+ -+ if (!LIST_IsEmpty(p_List)) -+ { -+ p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List); -+ while (p_CcNodeInfo) -+ { -+ XX_Free(p_CcNodeInfo); -+ p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List); -+ } -+ } -+ -+ LIST_Del(p_List); -+} -+ -+static void DeleteNode(t_FmPcdCcNode *p_CcNode) -+{ -+ uint32_t i; -+ -+ if (!p_CcNode) -+ return; -+ -+ if (p_CcNode->p_GlblMask) -+ { -+ XX_Free(p_CcNode->p_GlblMask); -+ p_CcNode->p_GlblMask = NULL; -+ } -+ -+ if (p_CcNode->h_KeysMatchTable) -+ { -+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), -+ p_CcNode->h_KeysMatchTable); -+ p_CcNode->h_KeysMatchTable = NULL; -+ } -+ -+ if (p_CcNode->h_AdTable) -+ { -+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), -+ p_CcNode->h_AdTable); -+ p_CcNode->h_AdTable = NULL; -+ } -+ -+ if (p_CcNode->h_Ad) -+ { -+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), -+ p_CcNode->h_Ad); -+ p_CcNode->h_Ad = NULL; -+ p_CcNode->h_TmpAd = NULL; -+ } -+ -+ if (p_CcNode->h_StatsFLRs) -+ { -+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), -+ p_CcNode->h_StatsFLRs); -+ p_CcNode->h_StatsFLRs = NULL; -+ } -+ -+ if (p_CcNode->h_Spinlock) -+ { -+ XX_FreeSpinlock(p_CcNode->h_Spinlock); -+ p_CcNode->h_Spinlock = NULL; -+ } -+ -+ /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */ -+ if (p_CcNode->isHashBucket -+ && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)) -+ p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters = -+ p_CcNode->h_PrivMissStatsCounters; -+ -+ /* Releasing all currently used statistics objects, including 'miss' entry */ -+ for (i = 0; i < p_CcNode->numOfKeys + 1; i++) -+ if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj) -+ PutStatsObj(p_CcNode, -+ p_CcNode->keyAndNextEngineParams[i].p_StatsObj); -+ -+ if (!LIST_IsEmpty(&p_CcNode->availableStatsLst)) -+ { -+ t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd); -+ ASSERT_COND(h_FmMuram); -+ -+ FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); -+ } -+ -+ LIST_Del(&p_CcNode->availableStatsLst); -+ -+ ReleaseLst(&p_CcNode->availableStatsLst); -+ ReleaseLst(&p_CcNode->ccPrevNodesLst); -+ ReleaseLst(&p_CcNode->ccTreeIdLst); -+ ReleaseLst(&p_CcNode->ccTreesLst); -+ -+ XX_Free(p_CcNode); -+} -+ -+static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd) -+{ -+ if (p_FmPcdTree) -+ { -+ if (p_FmPcdTree->ccTreeBaseAddr) -+ { -+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), -+ UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr)); -+ p_FmPcdTree->ccTreeBaseAddr = 0; -+ } -+ -+ ReleaseLst(&p_FmPcdTree->fmPortsLst); -+ -+ XX_Free(p_FmPcdTree); -+ } -+} -+ -+static void GetCcExtractKeySize(uint8_t parseCodeRealSize, -+ uint8_t *parseCodeCcSize) -+{ -+ if ((parseCodeRealSize > 0) && (parseCodeRealSize < 2)) -+ *parseCodeCcSize = 1; -+ else -+ if (parseCodeRealSize == 2) -+ *parseCodeCcSize = 2; -+ else -+ if ((parseCodeRealSize > 2) && (parseCodeRealSize <= 4)) -+ *parseCodeCcSize = 4; -+ else -+ if ((parseCodeRealSize > 4) && (parseCodeRealSize <= 8)) -+ *parseCodeCcSize = 8; -+ else -+ if ((parseCodeRealSize > 8) && (parseCodeRealSize <= 16)) -+ *parseCodeCcSize = 16; -+ else -+ if ((parseCodeRealSize > 16) -+ && (parseCodeRealSize <= 24)) -+ *parseCodeCcSize = 24; -+ else -+ if ((parseCodeRealSize > 24) -+ && (parseCodeRealSize <= 32)) -+ *parseCodeCcSize = 32; -+ else -+ if ((parseCodeRealSize > 32) -+ && (parseCodeRealSize <= 40)) -+ *parseCodeCcSize = 40; -+ else -+ if ((parseCodeRealSize > 40) -+ && (parseCodeRealSize <= 48)) -+ *parseCodeCcSize = 48; -+ else -+ if ((parseCodeRealSize > 48) -+ && (parseCodeRealSize <= 56)) -+ *parseCodeCcSize = 56; -+ else -+ *parseCodeCcSize = 0; -+} -+ -+static void GetSizeHeaderField(e_NetHeaderType hdr, t_FmPcdFields field, -+ uint8_t *parseCodeRealSize) -+{ -+ switch (hdr) -+ { -+ case (HEADER_TYPE_ETH): -+ switch (field.eth) -+ { -+ case (NET_HEADER_FIELD_ETH_DA): -+ *parseCodeRealSize = 6; -+ break; -+ -+ case (NET_HEADER_FIELD_ETH_SA): -+ *parseCodeRealSize = 6; -+ break; -+ -+ case (NET_HEADER_FIELD_ETH_TYPE): -+ *parseCodeRealSize = 2; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+ break; -+ -+ case (HEADER_TYPE_PPPoE): -+ switch (field.pppoe) -+ { -+ case (NET_HEADER_FIELD_PPPoE_PID): -+ *parseCodeRealSize = 2; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+ break; -+ -+ case (HEADER_TYPE_VLAN): -+ switch (field.vlan) -+ { -+ case (NET_HEADER_FIELD_VLAN_TCI): -+ *parseCodeRealSize = 2; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+ break; -+ -+ case (HEADER_TYPE_MPLS): -+ switch (field.mpls) -+ { -+ case (NET_HEADER_FIELD_MPLS_LABEL_STACK): -+ *parseCodeRealSize = 4; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+ break; -+ -+ case (HEADER_TYPE_IPv4): -+ switch (field.ipv4) -+ { -+ case (NET_HEADER_FIELD_IPv4_DST_IP): -+ case (NET_HEADER_FIELD_IPv4_SRC_IP): -+ *parseCodeRealSize = 4; -+ break; -+ -+ case (NET_HEADER_FIELD_IPv4_TOS): -+ case (NET_HEADER_FIELD_IPv4_PROTO): -+ *parseCodeRealSize = 1; -+ break; -+ -+ case (NET_HEADER_FIELD_IPv4_DST_IP -+ | NET_HEADER_FIELD_IPv4_SRC_IP): -+ *parseCodeRealSize = 8; -+ break; -+ -+ case (NET_HEADER_FIELD_IPv4_TTL): -+ *parseCodeRealSize = 1; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+ break; -+ -+ case (HEADER_TYPE_IPv6): -+ switch (field.ipv6) -+ { -+ case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL -+ | NET_HEADER_FIELD_IPv6_TC): -+ *parseCodeRealSize = 4; -+ break; -+ -+ case (NET_HEADER_FIELD_IPv6_NEXT_HDR): -+ case (NET_HEADER_FIELD_IPv6_HOP_LIMIT): -+ *parseCodeRealSize = 1; -+ break; -+ -+ case (NET_HEADER_FIELD_IPv6_DST_IP): -+ case (NET_HEADER_FIELD_IPv6_SRC_IP): -+ *parseCodeRealSize = 16; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+ break; -+ -+ case (HEADER_TYPE_IP): -+ switch (field.ip) -+ { -+ case (NET_HEADER_FIELD_IP_DSCP): -+ case (NET_HEADER_FIELD_IP_PROTO): -+ *parseCodeRealSize = 1; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+ break; -+ -+ case (HEADER_TYPE_GRE): -+ switch (field.gre) -+ { -+ case (NET_HEADER_FIELD_GRE_TYPE): -+ *parseCodeRealSize = 2; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+ break; -+ -+ case (HEADER_TYPE_MINENCAP): -+ switch (field.minencap) -+ { -+ case (NET_HEADER_FIELD_MINENCAP_TYPE): -+ *parseCodeRealSize = 1; -+ break; -+ -+ case (NET_HEADER_FIELD_MINENCAP_DST_IP): -+ case (NET_HEADER_FIELD_MINENCAP_SRC_IP): -+ *parseCodeRealSize = 4; -+ break; -+ -+ case (NET_HEADER_FIELD_MINENCAP_SRC_IP -+ | NET_HEADER_FIELD_MINENCAP_DST_IP): -+ *parseCodeRealSize = 8; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+ break; -+ -+ case (HEADER_TYPE_TCP): -+ switch (field.tcp) -+ { -+ case (NET_HEADER_FIELD_TCP_PORT_SRC): -+ case (NET_HEADER_FIELD_TCP_PORT_DST): -+ *parseCodeRealSize = 2; -+ break; -+ -+ case (NET_HEADER_FIELD_TCP_PORT_SRC -+ | NET_HEADER_FIELD_TCP_PORT_DST): -+ *parseCodeRealSize = 4; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+ break; -+ -+ case (HEADER_TYPE_UDP): -+ switch (field.udp) -+ { -+ case (NET_HEADER_FIELD_UDP_PORT_SRC): -+ case (NET_HEADER_FIELD_UDP_PORT_DST): -+ *parseCodeRealSize = 2; -+ break; -+ -+ case (NET_HEADER_FIELD_UDP_PORT_SRC -+ | NET_HEADER_FIELD_UDP_PORT_DST): -+ *parseCodeRealSize = 4; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10")); -+ *parseCodeRealSize = CC_SIZE_ILLEGAL; -+ break; -+ } -+} -+ -+t_Error ValidateNextEngineParams( -+ t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, -+ e_FmPcdCcStatsMode statsMode) -+{ -+ uint16_t absoluteProfileId; -+ t_Error err = E_OK; -+ uint8_t relativeSchemeId; -+ -+ if ((statsMode == e_FM_PCD_CC_STATS_MODE_NONE) -+ && (p_FmPcdCcNextEngineParams->statisticsEn)) -+ RETURN_ERROR( -+ MAJOR, -+ E_CONFLICT, -+ ("Statistics are requested for a key, but statistics mode was set" -+ "to 'NONE' upon initialization")); -+ -+ switch (p_FmPcdCcNextEngineParams->nextEngine) -+ { -+ case (e_FM_PCD_INVALID): -+ err = E_NOT_SUPPORTED; -+ break; -+ -+ case (e_FM_PCD_DONE): -+ if ((p_FmPcdCcNextEngineParams->params.enqueueParams.action -+ == e_FM_PCD_ENQ_FRAME) -+ && p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) -+ { -+ if (!p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid) -+ RETURN_ERROR( -+ MAJOR, -+ E_CONFLICT, -+ ("When overrideFqid is set, newFqid must not be zero")); -+ if (p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid -+ & ~0x00FFFFFF) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("fqidForCtrlFlow must be between 1 and 2^24-1")); -+ } -+ break; -+ -+ case (e_FM_PCD_KG): -+ relativeSchemeId = -+ FmPcdKgGetRelativeSchemeId( -+ h_FmPcd, -+ FmPcdKgGetSchemeId( -+ p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme)); -+ if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); -+ if (!FmPcdKgIsSchemeValidSw( -+ p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("not valid schemeIndex in KG next engine param")); -+ if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("CC Node may point only to a scheme that is always direct.")); -+ break; -+ -+ case (e_FM_PCD_PLCR): -+ if (p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams) -+ { -+ /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */ -+ if (p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile) -+ { -+ err = -+ FmPcdPlcrGetAbsoluteIdByProfileParams( -+ h_FmPcd, -+ e_FM_PCD_PLCR_SHARED, -+ NULL, -+ p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId, -+ &absoluteProfileId); -+ if (err) -+ RETURN_ERROR(MAJOR, err, -+ ("Shared profile offset is out of range")); -+ if (!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Invalid profile")); -+ } -+ } -+ break; -+ -+ case (e_FM_PCD_HASH): -+ p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC; -+ case (e_FM_PCD_CC): -+ if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) -+ RETURN_ERROR(MAJOR, E_NULL_POINTER, -+ ("handler to next Node is NULL")); -+ break; -+ -+#if (DPAA_VERSION >= 11) -+ case (e_FM_PCD_FR): -+ if (!p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic) -+ err = E_NOT_SUPPORTED; -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Next engine is not correct")); -+ } -+ -+ -+ return err; -+} -+ -+static uint8_t GetGenParseCode(e_FmPcdExtractFrom src, -+ uint32_t offset, bool glblMask, -+ uint8_t *parseArrayOffset, bool fromIc, -+ ccPrivateInfo_t icCode) -+{ -+ if (!fromIc) -+ { -+ switch (src) -+ { -+ case (e_FM_PCD_EXTRACT_FROM_FRAME_START): -+ if (glblMask) -+ return CC_PC_GENERIC_WITH_MASK; -+ else -+ return CC_PC_GENERIC_WITHOUT_MASK; -+ -+ case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE): -+ *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET; -+ if (offset) -+ return CC_PR_OFFSET; -+ else -+ return CC_PR_WITHOUT_OFFSET; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src")); -+ return CC_PC_ILLEGAL; -+ } -+ } -+ else -+ { -+ switch (icCode) -+ { -+ case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH): -+ *parseArrayOffset = 0x50; -+ return CC_PC_GENERIC_IC_GMASK; -+ -+ case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH): -+ *parseArrayOffset = 0x48; -+ return CC_PC_GENERIC_IC_GMASK; -+ -+ case (CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP): -+ *parseArrayOffset = 0x48; -+ return CC_PC_GENERIC_IC_HASH_INDEXED; -+ -+ case (CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP): -+ *parseArrayOffset = 0x16; -+ return CC_PC_GENERIC_IC_HASH_INDEXED; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src")); -+ break; -+ } -+ } -+ -+ return CC_PC_ILLEGAL; -+} -+ -+static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index, -+ t_FmPcdFields field) -+{ -+ switch (hdr) -+ { -+ case (HEADER_TYPE_NONE): -+ ASSERT_COND(FALSE); -+ return CC_PC_ILLEGAL; -+ -+ case (HEADER_TYPE_ETH): -+ switch (field.eth) -+ { -+ case (NET_HEADER_FIELD_ETH_DA): -+ return CC_PC_FF_MACDST; -+ case (NET_HEADER_FIELD_ETH_SA): -+ return CC_PC_FF_MACSRC; -+ case (NET_HEADER_FIELD_ETH_TYPE): -+ return CC_PC_FF_ETYPE; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ case (HEADER_TYPE_VLAN): -+ switch (field.vlan) -+ { -+ case (NET_HEADER_FIELD_VLAN_TCI): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_TCI1; -+ if (index == e_FM_PCD_HDR_INDEX_LAST) -+ return CC_PC_FF_TCI2; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ case (HEADER_TYPE_MPLS): -+ switch (field.mpls) -+ { -+ case (NET_HEADER_FIELD_MPLS_LABEL_STACK): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_MPLS1; -+ if (index == e_FM_PCD_HDR_INDEX_LAST) -+ return CC_PC_FF_MPLS_LAST; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index")); -+ return CC_PC_ILLEGAL; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ case (HEADER_TYPE_IPv4): -+ switch (field.ipv4) -+ { -+ case (NET_HEADER_FIELD_IPv4_DST_IP): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_IPV4DST1; -+ if (index == e_FM_PCD_HDR_INDEX_2) -+ return CC_PC_FF_IPV4DST2; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); -+ return CC_PC_ILLEGAL; -+ case (NET_HEADER_FIELD_IPv4_TOS): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_IPV4IPTOS_TC1; -+ if (index == e_FM_PCD_HDR_INDEX_2) -+ return CC_PC_FF_IPV4IPTOS_TC2; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); -+ return CC_PC_ILLEGAL; -+ case (NET_HEADER_FIELD_IPv4_PROTO): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_IPV4PTYPE1; -+ if (index == e_FM_PCD_HDR_INDEX_2) -+ return CC_PC_FF_IPV4PTYPE2; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); -+ return CC_PC_ILLEGAL; -+ case (NET_HEADER_FIELD_IPv4_SRC_IP): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_IPV4SRC1; -+ if (index == e_FM_PCD_HDR_INDEX_2) -+ return CC_PC_FF_IPV4SRC2; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); -+ return CC_PC_ILLEGAL; -+ case (NET_HEADER_FIELD_IPv4_SRC_IP -+ | NET_HEADER_FIELD_IPv4_DST_IP): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_IPV4SRC1_IPV4DST1; -+ if (index == e_FM_PCD_HDR_INDEX_2) -+ return CC_PC_FF_IPV4SRC2_IPV4DST2; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index")); -+ return CC_PC_ILLEGAL; -+ case (NET_HEADER_FIELD_IPv4_TTL): -+ return CC_PC_FF_IPV4TTL; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ case (HEADER_TYPE_IPv6): -+ switch (field.ipv6) -+ { -+ case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL -+ | NET_HEADER_FIELD_IPv6_TC): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1; -+ if (index == e_FM_PCD_HDR_INDEX_2) -+ return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); -+ return CC_PC_ILLEGAL; -+ -+ case (NET_HEADER_FIELD_IPv6_NEXT_HDR): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_IPV6PTYPE1; -+ if (index == e_FM_PCD_HDR_INDEX_2) -+ return CC_PC_FF_IPV6PTYPE2; -+ if (index == e_FM_PCD_HDR_INDEX_LAST) -+ return CC_PC_FF_IPPID; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); -+ return CC_PC_ILLEGAL; -+ -+ case (NET_HEADER_FIELD_IPv6_DST_IP): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_IPV6DST1; -+ if (index == e_FM_PCD_HDR_INDEX_2) -+ return CC_PC_FF_IPV6DST2; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); -+ return CC_PC_ILLEGAL; -+ -+ case (NET_HEADER_FIELD_IPv6_SRC_IP): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_IPV6SRC1; -+ if (index == e_FM_PCD_HDR_INDEX_2) -+ return CC_PC_FF_IPV6SRC2; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); -+ return CC_PC_ILLEGAL; -+ -+ case (NET_HEADER_FIELD_IPv6_HOP_LIMIT): -+ return CC_PC_FF_IPV6HOP_LIMIT; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ case (HEADER_TYPE_IP): -+ switch (field.ip) -+ { -+ case (NET_HEADER_FIELD_IP_DSCP): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) -+ || (index == e_FM_PCD_HDR_INDEX_1)) -+ return CC_PC_FF_IPDSCP; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index")); -+ return CC_PC_ILLEGAL; -+ -+ case (NET_HEADER_FIELD_IP_PROTO): -+ if (index == e_FM_PCD_HDR_INDEX_LAST) -+ return CC_PC_FF_IPPID; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index")); -+ return CC_PC_ILLEGAL; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ case (HEADER_TYPE_GRE): -+ switch (field.gre) -+ { -+ case (NET_HEADER_FIELD_GRE_TYPE): -+ return CC_PC_FF_GREPTYPE; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ case (HEADER_TYPE_MINENCAP): -+ switch (field.minencap) -+ { -+ case (NET_HEADER_FIELD_MINENCAP_TYPE): -+ return CC_PC_FF_MINENCAP_PTYPE; -+ -+ case (NET_HEADER_FIELD_MINENCAP_DST_IP): -+ return CC_PC_FF_MINENCAP_IPDST; -+ -+ case (NET_HEADER_FIELD_MINENCAP_SRC_IP): -+ return CC_PC_FF_MINENCAP_IPSRC; -+ -+ case (NET_HEADER_FIELD_MINENCAP_SRC_IP -+ | NET_HEADER_FIELD_MINENCAP_DST_IP): -+ return CC_PC_FF_MINENCAP_IPSRC_IPDST; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ case (HEADER_TYPE_TCP): -+ switch (field.tcp) -+ { -+ case (NET_HEADER_FIELD_TCP_PORT_SRC): -+ return CC_PC_FF_L4PSRC; -+ -+ case (NET_HEADER_FIELD_TCP_PORT_DST): -+ return CC_PC_FF_L4PDST; -+ -+ case (NET_HEADER_FIELD_TCP_PORT_DST -+ | NET_HEADER_FIELD_TCP_PORT_SRC): -+ return CC_PC_FF_L4PSRC_L4PDST; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ case (HEADER_TYPE_PPPoE): -+ switch (field.pppoe) -+ { -+ case (NET_HEADER_FIELD_PPPoE_PID): -+ return CC_PC_FF_PPPPID; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ case (HEADER_TYPE_UDP): -+ switch (field.udp) -+ { -+ case (NET_HEADER_FIELD_UDP_PORT_SRC): -+ return CC_PC_FF_L4PSRC; -+ -+ case (NET_HEADER_FIELD_UDP_PORT_DST): -+ return CC_PC_FF_L4PDST; -+ -+ case (NET_HEADER_FIELD_UDP_PORT_DST -+ | NET_HEADER_FIELD_UDP_PORT_SRC): -+ return CC_PC_FF_L4PSRC_L4PDST; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+} -+ -+static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, -+ uint32_t offset, bool glblMask, -+ uint8_t *parseArrayOffset) -+{ -+ bool offsetRelevant = FALSE; -+ -+ if (offset) -+ offsetRelevant = TRUE; -+ -+ switch (hdr) -+ { -+ case (HEADER_TYPE_NONE): -+ ASSERT_COND(FALSE); -+ return CC_PC_ILLEGAL; -+ -+ case (HEADER_TYPE_ETH): -+ *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET; -+ break; -+ -+ case (HEADER_TYPE_USER_DEFINED_SHIM1): -+ if (offset || glblMask) -+ *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET; -+ else -+ return CC_PC_PR_SHIM1; -+ break; -+ -+ case (HEADER_TYPE_USER_DEFINED_SHIM2): -+ if (offset || glblMask) -+ *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET; -+ else -+ return CC_PC_PR_SHIM2; -+ break; -+ -+ case (HEADER_TYPE_LLC_SNAP): -+ *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET; -+ break; -+ -+ case (HEADER_TYPE_PPPoE): -+ *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET; -+ break; -+ -+ case (HEADER_TYPE_MPLS): -+ if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) -+ || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) -+ *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET; -+ else -+ if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) -+ *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET; -+ else -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index")); -+ return CC_PC_ILLEGAL; -+ } -+ break; -+ -+ case (HEADER_TYPE_IPv4): -+ case (HEADER_TYPE_IPv6): -+ if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) -+ || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) -+ *parseArrayOffset = CC_PC_PR_IP1_OFFSET; -+ else -+ if (hdrIndex == e_FM_PCD_HDR_INDEX_2) -+ *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET; -+ else -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index")); -+ return CC_PC_ILLEGAL; -+ } -+ break; -+ -+ case (HEADER_TYPE_MINENCAP): -+ *parseArrayOffset = CC_PC_PR_MINENC_OFFSET; -+ break; -+ -+ case (HEADER_TYPE_GRE): -+ *parseArrayOffset = CC_PC_PR_GRE_OFFSET; -+ break; -+ -+ case (HEADER_TYPE_TCP): -+ case (HEADER_TYPE_UDP): -+ case (HEADER_TYPE_IPSEC_AH): -+ case (HEADER_TYPE_IPSEC_ESP): -+ case (HEADER_TYPE_DCCP): -+ case (HEADER_TYPE_SCTP): -+ *parseArrayOffset = CC_PC_PR_L4_OFFSET; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ if (offsetRelevant) -+ return CC_PR_OFFSET; -+ else -+ return CC_PR_WITHOUT_OFFSET; -+} -+ -+static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field, -+ uint32_t offset, uint8_t *parseArrayOffset, -+ e_FmPcdHdrIndex hdrIndex) -+{ -+ bool offsetRelevant = FALSE; -+ -+ if (offset) -+ offsetRelevant = TRUE; -+ -+ switch (hdr) -+ { -+ case (HEADER_TYPE_NONE): -+ ASSERT_COND(FALSE); -+ break; -+ case (HEADER_TYPE_ETH): -+ switch (field.eth) -+ { -+ case (NET_HEADER_FIELD_ETH_TYPE): -+ *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ break; -+ -+ case (HEADER_TYPE_VLAN): -+ switch (field.vlan) -+ { -+ case (NET_HEADER_FIELD_VLAN_TCI): -+ if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) -+ || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) -+ *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET; -+ else -+ if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) -+ *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET; -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return CC_PC_ILLEGAL; -+ } -+ break; -+ -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header ")); -+ return CC_PC_ILLEGAL; -+ } -+ -+ if (offsetRelevant) -+ return CC_PR_OFFSET; -+ else -+ return CC_PR_WITHOUT_OFFSET; -+} -+ -+static void FillAdOfTypeResult(t_Handle h_Ad, -+ t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, -+ t_FmPcd *p_FmPcd, -+ t_FmPcdCcNextEngineParams *p_CcNextEngineParams) -+{ -+ t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult *)h_Ad; -+ t_Handle h_TmpAd; -+ uint32_t tmp = 0, tmpNia = 0; -+ uint16_t profileId; -+ t_Handle p_AdNewPtr = NULL; -+ t_Error err = E_OK; -+ -+ /* There are 3 cases handled in this routine of building a "result" type AD. -+ * Case 1: No Manip. The action descriptor is built within the match table. -+ * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized -+ * either in the FmPcdManipUpdateAdResultForCc routine or it was already -+ * initialized and returned here. -+ * p_AdResult (within the match table) will be initialized after -+ * this routine returns and point to the existing AD. -+ * Case 3: Manip exists. The action descriptor is built within the match table. -+ * FmPcdManipUpdateAdResultForCc returns a NULL p_AdNewPtr. -+ * -+ * If statistics were enabled and the statistics mode of this node requires -+ * a statistics Ad, it will be placed after the result Ad and before the -+ * manip Ad, if manip Ad exists here. -+ */ -+ -+ /* As default, the "new" ptr is the current one. i.e. the content of the result -+ * AD will be written into the match table itself (case (1))*/ -+ p_AdNewPtr = p_AdResult; -+ -+ /* Initialize an action descriptor, if current statistics mode requires an Ad */ -+ if (p_FmPcdCcStatsParams) -+ { -+ ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd); -+ ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters); -+ -+ /* Swapping addresses between statistics Ad and the current lookup AD addresses */ -+ h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd; -+ p_FmPcdCcStatsParams->h_StatsAd = h_Ad; -+ h_Ad = h_TmpAd; -+ -+ p_AdNewPtr = h_Ad; -+ p_AdResult = h_Ad; -+ -+ /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */ -+ UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase); -+ } -+ -+ /* Create manip and return p_AdNewPtr to either a new descriptor or NULL */ -+ if (p_CcNextEngineParams->h_Manip) -+ FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip, -+ p_CcNextEngineParams, h_Ad, &p_AdNewPtr); -+ -+ /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */ -+ if (p_AdNewPtr) -+ { -+ /* case (1) and (2) */ -+ switch (p_CcNextEngineParams->nextEngine) -+ { -+ case (e_FM_PCD_DONE): -+ if (p_CcNextEngineParams->params.enqueueParams.action -+ == e_FM_PCD_ENQ_FRAME) -+ { -+ if (p_CcNextEngineParams->params.enqueueParams.overrideFqid) -+ { -+ tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE; -+ tmp |= -+ p_CcNextEngineParams->params.enqueueParams.newFqid; -+#if (DPAA_VERSION >= 11) -+ tmp |= -+ (p_CcNextEngineParams->params.enqueueParams.newRelativeStorageProfileId -+ & FM_PCD_AD_RESULT_VSP_MASK) -+ << FM_PCD_AD_RESULT_VSP_SHIFT; -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ else -+ { -+ tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE; -+ tmp |= FM_PCD_AD_RESULT_PLCR_DIS; -+ } -+ } -+ -+ if (p_CcNextEngineParams->params.enqueueParams.action -+ == e_FM_PCD_DROP_FRAME) -+ tmpNia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd); -+ else -+ tmpNia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd); -+ break; -+ -+ case (e_FM_PCD_KG): -+ if (p_CcNextEngineParams->params.kgParams.overrideFqid) -+ { -+ tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE; -+ tmp |= p_CcNextEngineParams->params.kgParams.newFqid; -+#if (DPAA_VERSION >= 11) -+ tmp |= -+ (p_CcNextEngineParams->params.kgParams.newRelativeStorageProfileId -+ & FM_PCD_AD_RESULT_VSP_MASK) -+ << FM_PCD_AD_RESULT_VSP_SHIFT; -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ else -+ { -+ tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE; -+ tmp |= FM_PCD_AD_RESULT_PLCR_DIS; -+ } -+ tmpNia = NIA_KG_DIRECT; -+ tmpNia |= NIA_ENG_KG; -+ tmpNia |= NIA_KG_CC_EN; -+ tmpNia |= FmPcdKgGetSchemeId( -+ p_CcNextEngineParams->params.kgParams.h_DirectScheme); -+ break; -+ -+ case (e_FM_PCD_PLCR): -+ if (p_CcNextEngineParams->params.plcrParams.overrideParams) -+ { -+ tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE; -+ -+ /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */ -+ if (p_CcNextEngineParams->params.plcrParams.sharedProfile) -+ { -+ tmpNia |= NIA_PLCR_ABSOLUTE; -+ err = FmPcdPlcrGetAbsoluteIdByProfileParams( -+ (t_Handle)p_FmPcd, -+ e_FM_PCD_PLCR_SHARED, -+ NULL, -+ p_CcNextEngineParams->params.plcrParams.newRelativeProfileId, -+ &profileId); -+ -+ if (err != E_OK) { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return; -+ } -+ -+ } -+ else -+ profileId = -+ p_CcNextEngineParams->params.plcrParams.newRelativeProfileId; -+ -+ tmp |= p_CcNextEngineParams->params.plcrParams.newFqid; -+#if (DPAA_VERSION >= 11) -+ tmp |= -+ (p_CcNextEngineParams->params.plcrParams.newRelativeStorageProfileId -+ & FM_PCD_AD_RESULT_VSP_MASK) -+ << FM_PCD_AD_RESULT_VSP_SHIFT; -+#endif /* (DPAA_VERSION >= 11) */ -+ WRITE_UINT32( -+ p_AdResult->plcrProfile, -+ (uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT)); -+ } -+ else -+ tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE; -+ -+ tmpNia |= -+ NIA_ENG_PLCR -+ | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId; -+ break; -+ -+ default: -+ return; -+ }WRITE_UINT32(p_AdResult->fqid, tmp); -+ -+ if (p_CcNextEngineParams->h_Manip) -+ { -+ tmp = GET_UINT32(p_AdResult->plcrProfile); -+ tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr) -+ - (p_FmPcd->physicalMuramBase)) >> 4; -+ WRITE_UINT32(p_AdResult->plcrProfile, tmp); -+ -+ tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE; -+ tmpNia |= FM_PCD_AD_RESULT_NADEN; -+ } -+ -+#if (DPAA_VERSION >= 11) -+ tmpNia |= FM_PCD_AD_RESULT_NO_OM_VSPE; -+#endif /* (DPAA_VERSION >= 11) */ -+ WRITE_UINT32(p_AdResult->nia, tmpNia); -+ } -+} -+ -+static t_Error CcUpdateParams(t_Handle h_FmPcd, t_Handle h_PcdParams, -+ t_Handle h_FmPort, t_Handle h_FmTree, -+ bool validate) -+{ -+ t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree; -+ -+ return CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort, -+ p_CcTree->keyAndNextEngineParams, -+ p_CcTree->numOfEntries, -+ UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), validate, 0, -+ h_FmTree, FALSE); -+} -+ -+ -+static void ReleaseNewNodeCommonPart( -+ t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) -+{ -+ if (p_AdditionalInfo->p_AdTableNew) -+ FM_MURAM_FreeMem( -+ FmPcdGetMuramHandle( -+ ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), -+ p_AdditionalInfo->p_AdTableNew); -+ -+ if (p_AdditionalInfo->p_KeysMatchTableNew) -+ FM_MURAM_FreeMem( -+ FmPcdGetMuramHandle( -+ ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd), -+ p_AdditionalInfo->p_KeysMatchTableNew); -+} -+ -+static t_Error UpdateGblMask(t_FmPcdCcNode *p_CcNode, uint8_t keySize, -+ uint8_t *p_Mask) -+{ -+ uint8_t prvGlblMaskSize = p_CcNode->glblMaskSize; -+ -+ if (p_Mask && !p_CcNode->glblMaskUpdated && (keySize <= 4) -+ && !p_CcNode->lclMask) -+ { -+ if (p_CcNode->parseCode && (p_CcNode->parseCode != CC_PC_FF_TCI1) -+ && (p_CcNode->parseCode != CC_PC_FF_TCI2) -+ && (p_CcNode->parseCode != CC_PC_FF_MPLS1) -+ && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST) -+ && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1) -+ && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2) -+ && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1) -+ && (p_CcNode->parseCode != CC_PC_FF_IPDSCP) -+ && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2)) -+ { -+ p_CcNode->glblMaskSize = 0; -+ p_CcNode->lclMask = TRUE; -+ } -+ else -+ { -+ memcpy(p_CcNode->p_GlblMask, p_Mask, (sizeof(uint8_t)) * keySize); -+ p_CcNode->glblMaskUpdated = TRUE; -+ p_CcNode->glblMaskSize = 4; -+ } -+ } -+ else -+ if (p_Mask && (keySize <= 4) && !p_CcNode->lclMask) -+ { -+ if (memcmp(p_CcNode->p_GlblMask, p_Mask, keySize) != 0) -+ { -+ p_CcNode->lclMask = TRUE; -+ p_CcNode->glblMaskSize = 0; -+ } -+ } -+ else -+ if (!p_Mask && p_CcNode->glblMaskUpdated && (keySize <= 4)) -+ { -+ uint32_t tmpMask = 0xffffffff; -+ if (memcmp(p_CcNode->p_GlblMask, &tmpMask, 4) != 0) -+ { -+ p_CcNode->lclMask = TRUE; -+ p_CcNode->glblMaskSize = 0; -+ } -+ } -+ else -+ if (p_Mask) -+ { -+ p_CcNode->lclMask = TRUE; -+ p_CcNode->glblMaskSize = 0; -+ } -+ -+ /* In static mode (maxNumOfKeys > 0), local mask is supported -+ only is mask support was enabled at initialization */ -+ if (p_CcNode->maxNumOfKeys && (!p_CcNode->maskSupport) && p_CcNode->lclMask) -+ { -+ p_CcNode->lclMask = FALSE; -+ p_CcNode->glblMaskSize = prvGlblMaskSize; -+ return ERROR_CODE(E_NOT_SUPPORTED); -+ } -+ -+ return E_OK; -+} -+ -+static __inline__ t_Handle GetNewAd(t_Handle h_FmPcdCcNodeOrTree, bool isTree) -+{ -+ t_FmPcd *p_FmPcd; -+ t_Handle h_Ad; -+ -+ if (isTree) -+ p_FmPcd = (t_FmPcd *)(((t_FmPcdCcTree *)h_FmPcdCcNodeOrTree)->h_FmPcd); -+ else -+ p_FmPcd = (t_FmPcd *)(((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_FmPcd); -+ -+ if ((isTree && p_FmPcd->p_CcShadow) -+ || (!isTree && ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->maxNumOfKeys)) -+ { -+ /* The allocated shadow is divided as follows: -+ 0 . . . 16 . . . -+ --------------------------------------------------- -+ | Shadow | Shadow Keys | Shadow Next | -+ | Ad | Match Table | Engine Table | -+ | (16 bytes) | (maximal size) | (maximal size) | -+ --------------------------------------------------- -+ */ -+ if (!p_FmPcd->p_CcShadow) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated")); -+ return NULL; -+ } -+ -+ h_Ad = p_FmPcd->p_CcShadow; -+ } -+ else -+ { -+ h_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd), -+ FM_PCD_CC_AD_ENTRY_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!h_Ad) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptor")); -+ return NULL; -+ } -+ } -+ -+ return h_Ad; -+} -+ -+static t_Error BuildNewNodeCommonPart( -+ t_FmPcdCcNode *p_CcNode, int *size, -+ t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ -+ if (p_CcNode->lclMask) -+ *size = 2 * p_CcNode->ccKeySizeAccExtraction; -+ else -+ *size = p_CcNode->ccKeySizeAccExtraction; -+ -+ if (p_CcNode->maxNumOfKeys == 0) -+ { -+ p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem( -+ FmPcdGetMuramHandle(p_FmPcd), -+ (uint32_t)((p_AdditionalInfo->numOfKeys + 1) -+ * FM_PCD_CC_AD_ENTRY_SIZE), -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_AdditionalInfo->p_AdTableNew) -+ RETURN_ERROR( -+ MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for CC node action descriptors table")); -+ -+ p_AdditionalInfo->p_KeysMatchTableNew = (t_Handle)FM_MURAM_AllocMem( -+ FmPcdGetMuramHandle(p_FmPcd), -+ (uint32_t)(*size * sizeof(uint8_t) -+ * (p_AdditionalInfo->numOfKeys + 1)), -+ FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN); -+ if (!p_AdditionalInfo->p_KeysMatchTableNew) -+ { -+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd), -+ p_AdditionalInfo->p_AdTableNew); -+ p_AdditionalInfo->p_AdTableNew = NULL; -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for CC node key match table")); -+ } -+ -+ MemSet8( -+ (uint8_t*)p_AdditionalInfo->p_AdTableNew, -+ 0, -+ (uint32_t)((p_AdditionalInfo->numOfKeys + 1) -+ * FM_PCD_CC_AD_ENTRY_SIZE)); -+ MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0, -+ *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1)); -+ } -+ else -+ { -+ /* The allocated shadow is divided as follows: -+ 0 . . . 16 . . . -+ --------------------------------------------------- -+ | Shadow | Shadow Keys | Shadow Next | -+ | Ad | Match Table | Engine Table | -+ | (16 bytes) | (maximal size) | (maximal size) | -+ --------------------------------------------------- -+ */ -+ -+ if (!p_FmPcd->p_CcShadow) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated")); -+ -+ p_AdditionalInfo->p_KeysMatchTableNew = -+ PTR_MOVE(p_FmPcd->p_CcShadow, FM_PCD_CC_AD_ENTRY_SIZE); -+ p_AdditionalInfo->p_AdTableNew = -+ PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, p_CcNode->keysMatchTableMaxSize); -+ -+ MemSet8( -+ (uint8_t*)p_AdditionalInfo->p_AdTableNew, -+ 0, -+ (uint32_t)((p_CcNode->maxNumOfKeys + 1) -+ * FM_PCD_CC_AD_ENTRY_SIZE)); -+ MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0, -+ (*size) * sizeof(uint8_t) * (p_CcNode->maxNumOfKeys)); -+ } -+ -+ p_AdditionalInfo->p_AdTableOld = p_CcNode->h_AdTable; -+ p_AdditionalInfo->p_KeysMatchTableOld = p_CcNode->h_KeysMatchTable; -+ -+ return E_OK; -+} -+ -+static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine( -+ t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, -+ t_FmPcdCcKeyParams *p_KeyParams, -+ t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add) -+{ -+ t_Error err = E_OK; -+ t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp; -+ t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; -+ int size; -+ int i = 0, j = 0; -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t requiredAction = 0; -+ bool prvLclMask; -+ t_CcNodeInformation *p_CcNodeInformation; -+ t_FmPcdCcStatsParams statsParams = { 0 }; -+ t_List *p_Pos; -+ t_FmPcdStatsObj *p_StatsObj; -+ -+ /* Check that new NIA is legal */ -+ err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams, -+ p_CcNode->statisticsMode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ prvLclMask = p_CcNode->lclMask; -+ -+ /* Check that new key is not require update of localMask */ -+ err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, -+ p_KeyParams->p_Mask); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ -+ /* Update internal data structure with new next engine for the given index */ -+ memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams, -+ &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams)); -+ -+ memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, -+ p_KeyParams->p_Key, p_CcNode->userSizeOfExtraction); -+ -+ if ((p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ && p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) -+ { -+ err = -+ AllocAndFillAdForContLookupManip( -+ p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ -+ if (p_KeyParams->p_Mask) -+ memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, -+ p_KeyParams->p_Mask, p_CcNode->userSizeOfExtraction); -+ else -+ memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF, -+ p_CcNode->userSizeOfExtraction); -+ -+ /* Update numOfKeys */ -+ if (add) -+ p_AdditionalInfo->numOfKeys = (uint8_t)(p_CcNode->numOfKeys + 1); -+ else -+ p_AdditionalInfo->numOfKeys = (uint8_t)p_CcNode->numOfKeys; -+ -+ /* Allocate new tables in MURAM: keys match table and action descriptors table */ -+ err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ /* Check that manip is legal and what requiredAction is necessary for this manip */ -+ if (p_KeyParams->ccNextEngineParams.h_Manip) -+ { -+ err = FmPcdManipCheckParamsForCcNextEngine( -+ &p_KeyParams->ccNextEngineParams, &requiredAction); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ -+ p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction = -+ requiredAction; -+ p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |= -+ UPDATE_CC_WITH_TREE; -+ -+ /* Update new Ad and new Key Table according to new requirement */ -+ i = 0; -+ for (j = 0; j < p_AdditionalInfo->numOfKeys; j++) -+ { -+ p_AdTableNewTmp = -+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ if (j == keyIndex) -+ { -+ if (p_KeyParams->ccNextEngineParams.statisticsEn) -+ { -+ /* Allocate a statistics object that holds statistics AD and counters. -+ - For added key - New statistics AD and counters pointer need to be allocated -+ new statistics object. If statistics were enabled, we need to replace the -+ existing descriptor with a new descriptor with nullified counters. -+ */ -+ p_StatsObj = GetStatsObj(p_CcNode); -+ ASSERT_COND(p_StatsObj); -+ -+ /* Store allocated statistics object */ -+ ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS); -+ p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = -+ p_StatsObj; -+ -+ statsParams.h_StatsAd = p_StatsObj->h_StatsAd; -+ statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; -+#if (DPAA_VERSION >= 11) -+ statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs; -+ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ /* Building action descriptor for the received new key */ -+ NextStepAd(p_AdTableNewTmp, &statsParams, -+ &p_KeyParams->ccNextEngineParams, p_FmPcd); -+ } -+ else -+ { -+ /* Building action descriptor for the received new key */ -+ NextStepAd(p_AdTableNewTmp, NULL, -+ &p_KeyParams->ccNextEngineParams, p_FmPcd); -+ } -+ -+ /* Copy the received new key into keys match table */ -+ p_KeysMatchTableNewTmp = -+ PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size*sizeof(uint8_t)); -+ -+ MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key, -+ p_CcNode->userSizeOfExtraction); -+ -+ /* Update mask for the received new key */ -+ if (p_CcNode->lclMask) -+ { -+ if (p_KeyParams->p_Mask) -+ { -+ MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ p_KeyParams->p_Mask, -+ p_CcNode->userSizeOfExtraction); -+ } -+ else -+ if (p_CcNode->ccKeySizeAccExtraction > 4) -+ { -+ MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ 0xff, p_CcNode->userSizeOfExtraction); -+ } -+ else -+ { -+ MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ p_CcNode->p_GlblMask, -+ p_CcNode->userSizeOfExtraction); -+ } -+ } -+ -+ /* If key modification requested, the old entry is omitted and replaced by the new parameters */ -+ if (!add) -+ i++; -+ } -+ else -+ { -+ /* Copy existing action descriptors to the newly allocated Ad table */ -+ p_AdTableOldTmp = -+ PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE); -+ MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, -+ FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* Copy existing keys and their masks to the newly allocated keys match table */ -+ p_KeysMatchTableNewTmp = -+ PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t)); -+ p_KeysMatchTableOldTmp = -+ PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i * size * sizeof(uint8_t)); -+ -+ if (p_CcNode->lclMask) -+ { -+ if (prvLclMask) -+ { -+ MemCpy8( -+ PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction), -+ PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction), -+ p_CcNode->ccKeySizeAccExtraction); -+ } -+ else -+ { -+ p_KeysMatchTableOldTmp = -+ PTR_MOVE(p_CcNode->h_KeysMatchTable, -+ i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)); -+ -+ if (p_CcNode->ccKeySizeAccExtraction > 4) -+ { -+ MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ 0xff, p_CcNode->userSizeOfExtraction); -+ } -+ else -+ { -+ MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ p_CcNode->p_GlblMask, -+ p_CcNode->userSizeOfExtraction); -+ } -+ } -+ } -+ -+ MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, -+ p_CcNode->ccKeySizeAccExtraction); -+ -+ i++; -+ } -+ } -+ -+ /* Miss action descriptor */ -+ p_AdTableNewTmp = -+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE); -+ p_AdTableOldTmp = -+ PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i * FM_PCD_CC_AD_ENTRY_SIZE); -+ MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ if (!LIST_IsEmpty(&p_CcNode->ccTreesLst)) -+ { -+ LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst) -+ { -+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); -+ ASSERT_COND(p_CcNodeInformation->h_CcNode); -+ /* Update the manipulation which has to be updated from parameters of the port */ -+ /* It's has to be updated with restrictions defined in the function */ -+ err = -+ SetRequiredAction( -+ p_CcNode->h_FmPcd, -+ p_CcNode->shadowAction -+ | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction, -+ &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], -+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE), -+ 1, p_CcNodeInformation->h_CcNode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ -+ err = -+ CcUpdateParam( -+ p_CcNode->h_FmPcd, -+ NULL, -+ NULL, -+ &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], -+ 1, -+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE), -+ TRUE, p_CcNodeInformation->index, -+ p_CcNodeInformation->h_CcNode, TRUE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ } -+ -+ if (p_CcNode->lclMask) -+ memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); -+ -+ if (p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC) -+ p_AdditionalInfo->h_NodeForAdd = -+ p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode; -+ if (p_KeyParams->ccNextEngineParams.h_Manip) -+ p_AdditionalInfo->h_ManipForAdd = -+ p_KeyParams->ccNextEngineParams.h_Manip; -+ -+#if (DPAA_VERSION >= 11) -+ if ((p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_FR) -+ && (p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic)) -+ p_AdditionalInfo->h_FrmReplicForAdd = -+ p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ if (!add) -+ { -+ if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ p_AdditionalInfo->h_NodeForRmv = -+ p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; -+ -+ if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) -+ p_AdditionalInfo->h_ManipForRmv = -+ p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; -+ -+ /* If statistics were previously enabled, store the old statistics object to be released */ -+ if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) -+ { -+ p_AdditionalInfo->p_StatsObjForRmv = -+ p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj; -+ } -+ -+#if (DPAA_VERSION >= 11) -+ if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine -+ == e_FM_PCD_FR) -+ && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) -+ p_AdditionalInfo->h_FrmReplicForRmv = -+ p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+ return E_OK; -+} -+ -+static t_Error BuildNewNodeRemoveKey( -+ t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, -+ t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) -+{ -+ int i = 0, j = 0; -+ t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp; -+ t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; -+ int size; -+ t_Error err = E_OK; -+ -+ /*save new numOfKeys*/ -+ p_AdditionalInfo->numOfKeys = (uint16_t)(p_CcNode->numOfKeys - 1); -+ -+ /*function which allocates in the memory new KeyTbl, AdTbl*/ -+ err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ /*update new Ad and new Key Table according to new requirement*/ -+ for (i = 0, j = 0; j < p_CcNode->numOfKeys; i++, j++) -+ { -+ if (j == keyIndex) -+ j++; -+ -+ if (j == p_CcNode->numOfKeys) -+ break; -+ p_AdTableNewTmp = -+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE); -+ p_AdTableOldTmp = -+ PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE); -+ MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ p_KeysMatchTableOldTmp = -+ PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j * size * sizeof(uint8_t)); -+ p_KeysMatchTableNewTmp = -+ PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i * size * sizeof(uint8_t)); -+ MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, -+ size * sizeof(uint8_t)); -+ } -+ -+ p_AdTableNewTmp = -+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE); -+ p_AdTableOldTmp = -+ PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE); -+ MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ p_AdditionalInfo->h_NodeForRmv = -+ p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; -+ -+ if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) -+ p_AdditionalInfo->h_ManipForRmv = -+ p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; -+ -+ /* If statistics were previously enabled, store the old statistics object to be released */ -+ if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) -+ { -+ p_AdditionalInfo->p_StatsObjForRmv = -+ p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj; -+ } -+ -+#if (DPAA_VERSION >= 11) -+ if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine -+ == e_FM_PCD_FR) -+ && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) -+ p_AdditionalInfo->h_FrmReplicForRmv = -+ p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ return E_OK; -+} -+ -+static t_Error BuildNewNodeModifyKey( -+ t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, uint8_t *p_Key, -+ uint8_t *p_Mask, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ t_Error err = E_OK; -+ t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp; -+ t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp; -+ int size; -+ int i = 0, j = 0; -+ bool prvLclMask; -+ t_FmPcdStatsObj *p_StatsObj, tmpStatsObj; -+ p_AdditionalInfo->numOfKeys = p_CcNode->numOfKeys; -+ -+ prvLclMask = p_CcNode->lclMask; -+ -+ /* Check that new key is not require update of localMask */ -+ err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, p_Mask); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ -+ /* Update internal data structure with new next engine for the given index */ -+ memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, p_Key, -+ p_CcNode->userSizeOfExtraction); -+ -+ if (p_Mask) -+ memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, p_Mask, -+ p_CcNode->userSizeOfExtraction); -+ else -+ memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF, -+ p_CcNode->userSizeOfExtraction); -+ -+ /*function which build in the memory new KeyTbl, AdTbl*/ -+ err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ /*fill the New AdTable and New KeyTable*/ -+ for (j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++) -+ { -+ p_AdTableNewTmp = -+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE); -+ p_AdTableOldTmp = -+ PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ if (j == keyIndex) -+ { -+ ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS); -+ if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) -+ { -+ /* As statistics were enabled, we need to update the existing -+ statistics descriptor with a new nullified counters. */ -+ p_StatsObj = GetStatsObj(p_CcNode); -+ ASSERT_COND(p_StatsObj); -+ -+ SetStatsCounters( -+ p_AdTableNewTmp, -+ (uint32_t)((XX_VirtToPhys(p_StatsObj->h_StatsCounters) -+ - p_FmPcd->physicalMuramBase))); -+ -+ tmpStatsObj.h_StatsAd = p_StatsObj->h_StatsAd; -+ tmpStatsObj.h_StatsCounters = p_StatsObj->h_StatsCounters; -+ -+ /* As we need to replace only the counters, we build a new statistics -+ object that holds the old AD and the new counters - this will be the -+ currently used statistics object. -+ The newly allocated AD is not required and may be released back to -+ the available objects with the previous counters pointer. */ -+ p_StatsObj->h_StatsAd = -+ p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd; -+ -+ p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd = -+ tmpStatsObj.h_StatsAd; -+ -+ /* Store allocated statistics object */ -+ p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = -+ p_StatsObj; -+ -+ /* As statistics were previously enabled, store the old statistics object to be released */ -+ p_AdditionalInfo->p_StatsObjForRmv = -+ p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj; -+ } -+ -+ p_KeysMatchTableNewTmp = -+ PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t)); -+ -+ MemCpy8(p_KeysMatchTableNewTmp, p_Key, -+ p_CcNode->userSizeOfExtraction); -+ -+ if (p_CcNode->lclMask) -+ { -+ if (p_Mask) -+ MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ p_Mask, p_CcNode->userSizeOfExtraction); -+ else -+ if (p_CcNode->ccKeySizeAccExtraction > 4) -+ MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ 0xff, p_CcNode->userSizeOfExtraction); -+ else -+ MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ p_CcNode->p_GlblMask, -+ p_CcNode->userSizeOfExtraction); -+ } -+ } -+ else -+ { -+ p_KeysMatchTableNewTmp = -+ PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t)); -+ p_KeysMatchTableOldTmp = -+ PTR_MOVE(p_CcNode->h_KeysMatchTable, i * size * sizeof(uint8_t)); -+ -+ if (p_CcNode->lclMask) -+ { -+ if (prvLclMask) -+ MemCpy8( -+ PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction), -+ PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction), -+ p_CcNode->userSizeOfExtraction); -+ else -+ { -+ p_KeysMatchTableOldTmp = -+ PTR_MOVE(p_CcNode->h_KeysMatchTable, -+ i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)); -+ -+ if (p_CcNode->ccKeySizeAccExtraction > 4) -+ MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp, -+ p_CcNode->ccKeySizeAccExtraction), -+ 0xff, p_CcNode->userSizeOfExtraction); -+ else -+ MemCpy8( -+ PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction), -+ p_CcNode->p_GlblMask, -+ p_CcNode->userSizeOfExtraction); -+ } -+ } -+ MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp, -+ p_CcNode->ccKeySizeAccExtraction); -+ } -+ } -+ -+ p_AdTableNewTmp = -+ PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE); -+ p_AdTableOldTmp = PTR_MOVE(p_CcNode->h_AdTable, i * FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ return E_OK; -+} -+ -+static t_Error BuildNewNodeModifyNextEngine( -+ t_Handle h_FmPcd, t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex, -+ t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst, -+ t_List *h_NewLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo) -+{ -+ t_Error err = E_OK; -+ uint32_t requiredAction = 0; -+ t_List *p_Pos; -+ t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo; -+ t_Handle p_Ad; -+ t_FmPcdCcNode *p_FmPcdCcNode1 = NULL; -+ t_FmPcdCcTree *p_FmPcdCcTree = NULL; -+ t_FmPcdStatsObj *p_StatsObj; -+ t_FmPcdCcStatsParams statsParams = { 0 }; -+ -+ ASSERT_COND(p_CcNextEngineParams); -+ -+ /* check that new NIA is legal */ -+ if (!p_AdditionalInfo->tree) -+ err = ValidateNextEngineParams( -+ h_FmPcd, p_CcNextEngineParams, -+ ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->statisticsMode); -+ else -+ /* Statistics are not supported for CC root */ -+ err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams, -+ e_FM_PCD_CC_STATS_MODE_NONE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ /* Update internal data structure for next engine per index (index - key) */ -+ memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams, -+ p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams)); -+ -+ /* Check that manip is legal and what requiredAction is necessary for this manip */ -+ if (p_CcNextEngineParams->h_Manip) -+ { -+ err = FmPcdManipCheckParamsForCcNextEngine(p_CcNextEngineParams, -+ &requiredAction); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ -+ if (!p_AdditionalInfo->tree) -+ { -+ p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree; -+ p_AdditionalInfo->numOfKeys = p_FmPcdCcNode1->numOfKeys; -+ p_Ad = p_FmPcdCcNode1->h_AdTable; -+ -+ if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ p_AdditionalInfo->h_NodeForRmv = -+ p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; -+ -+ if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) -+ p_AdditionalInfo->h_ManipForRmv = -+ p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; -+ -+#if (DPAA_VERSION >= 11) -+ if ((p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine -+ == e_FM_PCD_FR) -+ && (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) -+ p_AdditionalInfo->h_FrmReplicForRmv = -+ p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ else -+ { -+ p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree; -+ p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); -+ -+ if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ p_AdditionalInfo->h_NodeForRmv = -+ p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode; -+ -+ if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip) -+ p_AdditionalInfo->h_ManipForRmv = -+ p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip; -+ -+#if (DPAA_VERSION >= 11) -+ if ((p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine -+ == e_FM_PCD_FR) -+ && (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic)) -+ p_AdditionalInfo->h_FrmReplicForRmv = -+ p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic; -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+ if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_CC) -+ && p_CcNextEngineParams->h_Manip) -+ { -+ err = AllocAndFillAdForContLookupManip( -+ p_CcNextEngineParams->params.ccParams.h_CcNode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ -+ ASSERT_COND(p_Ad); -+ -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* If statistics were enabled, this Ad is the statistics Ad. Need to follow its -+ nextAction to retrieve the actual Nia-Ad. If statistics should remain enabled, -+ only the actual Nia-Ad should be modified. */ -+ if ((!p_AdditionalInfo->tree) -+ && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj) -+ && (p_CcNextEngineParams->statisticsEn)) -+ ccNodeInfo.h_CcNode = -+ ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd; -+ -+ EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL); -+ -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ p_Ad = GetNewAd(h_FmPcdCcNodeOrTree, p_AdditionalInfo->tree); -+ if (!p_Ad) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for CC node action descriptor")); -+ MemSet8((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* If statistics were not enabled before, but requested now - Allocate a statistics -+ object that holds statistics AD and counters. */ -+ if ((!p_AdditionalInfo->tree) -+ && (!((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj) -+ && (p_CcNextEngineParams->statisticsEn)) -+ { -+ p_StatsObj = GetStatsObj((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree); -+ ASSERT_COND(p_StatsObj); -+ -+ /* Store allocated statistics object */ -+ p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = -+ p_StatsObj; -+ -+ statsParams.h_StatsAd = p_StatsObj->h_StatsAd; -+ statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; -+ -+#if (DPAA_VERSION >= 11) -+ statsParams.h_StatsFLRs = -+ ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_StatsFLRs; -+ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ NextStepAd(p_Ad, &statsParams, p_CcNextEngineParams, h_FmPcd); -+ } -+ else -+ NextStepAd(p_Ad, NULL, p_CcNextEngineParams, h_FmPcd); -+ -+ ccNodeInfo.h_CcNode = p_Ad; -+ EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL); -+ -+ p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction = -+ requiredAction; -+ p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |= -+ UPDATE_CC_WITH_TREE; -+ -+ if (!p_AdditionalInfo->tree) -+ { -+ ASSERT_COND(p_FmPcdCcNode1); -+ if (!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst)) -+ { -+ LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst) -+ { -+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); -+ -+ ASSERT_COND(p_CcNodeInformation->h_CcNode); -+ /* Update the manipulation which has to be updated from parameters of the port -+ it's has to be updated with restrictions defined in the function */ -+ -+ err = -+ SetRequiredAction( -+ p_FmPcdCcNode1->h_FmPcd, -+ p_FmPcdCcNode1->shadowAction -+ | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction, -+ &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], -+ p_Ad, 1, p_CcNodeInformation->h_CcNode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ -+ err = CcUpdateParam( -+ p_FmPcdCcNode1->h_FmPcd, NULL, NULL, -+ &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 1, -+ p_Ad, TRUE, p_CcNodeInformation->index, -+ p_CcNodeInformation->h_CcNode, TRUE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ } -+ } -+ else -+ { -+ ASSERT_COND(p_FmPcdCcTree); -+ -+ err = -+ SetRequiredAction( -+ h_FmPcd, -+ p_FmPcdCcTree->requiredAction -+ | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction, -+ &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], -+ p_Ad, 1, (t_Handle)p_FmPcdCcTree); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ -+ err = CcUpdateParam(h_FmPcd, NULL, NULL, -+ &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], -+ 1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ -+ if (p_CcNextEngineParams->nextEngine == e_FM_PCD_CC) -+ p_AdditionalInfo->h_NodeForAdd = -+ p_CcNextEngineParams->params.ccParams.h_CcNode; -+ if (p_CcNextEngineParams->h_Manip) -+ p_AdditionalInfo->h_ManipForAdd = p_CcNextEngineParams->h_Manip; -+ -+ /* If statistics were previously enabled, but now are disabled, -+ store the old statistics object to be released */ -+ if ((!p_AdditionalInfo->tree) -+ && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj) -+ && (!p_CcNextEngineParams->statisticsEn)) -+ { -+ p_AdditionalInfo->p_StatsObjForRmv = -+ ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj; -+ -+ -+ p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = NULL; -+ } -+#if (DPAA_VERSION >= 11) -+ if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_FR) -+ && (p_CcNextEngineParams->params.frParams.h_FrmReplic)) -+ p_AdditionalInfo->h_FrmReplicForAdd = -+ p_CcNextEngineParams->params.frParams.h_FrmReplic; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ return E_OK; -+} -+ -+static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode( -+ t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst, -+ t_FmPcdCcNextEngineParams **p_NextEngineParams) -+{ -+ t_CcNodeInformation *p_CcNodeInformation; -+ t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL; -+ t_List *p_Pos; -+ int i = 0; -+ t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/; -+ t_CcNodeInformation ccNodeInfo; -+ -+ LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst) -+ { -+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); -+ p_NodePtrOnCurrentMdfNode = -+ (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode; -+ -+ ASSERT_COND(p_NodePtrOnCurrentMdfNode); -+ -+ /* Search in the previous node which exact index points on this current modified node for getting AD */ -+ for (i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++) -+ { -+ if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ { -+ if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode -+ == (t_Handle)p_CrntMdfNode) -+ { -+ if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip) -+ p_AdTablePtOnCrntCurrentMdfNode = p_CrntMdfNode->h_Ad; -+ else -+ if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj) -+ p_AdTablePtOnCrntCurrentMdfNode = -+ p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd; -+ else -+ p_AdTablePtOnCrntCurrentMdfNode = -+ PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode; -+ EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL); -+ -+ if (!(*p_NextEngineParams)) -+ *p_NextEngineParams = -+ &p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams; -+ } -+ } -+ } -+ -+ ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys); -+ } -+} -+ -+static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode( -+ t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst, -+ t_FmPcdCcNextEngineParams **p_NextEngineParams) -+{ -+ t_CcNodeInformation *p_CcNodeInformation; -+ t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL; -+ t_List *p_Pos; -+ int i = 0; -+ t_Handle p_AdTableTmp; -+ t_CcNodeInformation ccNodeInfo; -+ -+ LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst) -+ { -+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); -+ p_TreePtrOnCurrentMdfNode = -+ (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode; -+ -+ ASSERT_COND(p_TreePtrOnCurrentMdfNode); -+ -+ /*search in the trees which exact index points on this current modified node for getting AD */ -+ for (i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++) -+ { -+ if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ { -+ if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode -+ == (t_Handle)p_CrntMdfNode) -+ { -+ p_AdTableTmp = -+ UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE); -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ ccNodeInfo.h_CcNode = p_AdTableTmp; -+ EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL); -+ -+ if (!(*p_NextEngineParams)) -+ *p_NextEngineParams = -+ &p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams; -+ } -+ } -+ } -+ -+ ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries); -+ } -+} -+ -+static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart( -+ t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex, -+ e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree) -+{ -+ t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams; -+ int i = 0, j = 0; -+ bool wasUpdate = FALSE; -+ t_FmPcdCcNode *p_CcNode = NULL; -+ t_FmPcdCcTree *p_FmPcdCcTree; -+ uint16_t numOfKeys; -+ t_FmPcdCcKeyAndNextEngineParams *p_KeyAndNextEngineParams; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcdCcNodeOrTree, E_INVALID_HANDLE, NULL); -+ -+ if (!tree) -+ { -+ p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree; -+ numOfKeys = p_CcNode->numOfKeys; -+ -+ /* node has to be pointed by another node or tree */ -+ -+ p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc( -+ sizeof(t_FmPcdCcKeyAndNextEngineParams) * (numOfKeys + 1)); -+ if (!p_KeyAndNextEngineParams) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure")); -+ return NULL; -+ } -+ memcpy(p_KeyAndNextEngineParams, p_CcNode->keyAndNextEngineParams, -+ (numOfKeys + 1) * sizeof(t_FmPcdCcKeyAndNextEngineParams)); -+ -+ if (ttlCheck) -+ { -+ if ((p_CcNode->parseCode == CC_PC_FF_IPV4TTL) -+ || (p_CcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT)) -+ { -+ XX_Free(p_KeyAndNextEngineParams); -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_FF_IPV4TTL or CC_PC_FF_IPV6HOP_LIMIT can not be used for this operation")); -+ return NULL; -+ } -+ } -+ -+ if (hashCheck) -+ { -+ if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED) -+ { -+ XX_Free(p_KeyAndNextEngineParams); -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_GENERIC_IC_HASH_INDEXED can not be used for this operation")); -+ return NULL; -+ } -+ } -+ } -+ else -+ { -+ p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree; -+ numOfKeys = p_FmPcdCcTree->numOfEntries; -+ -+ p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc( -+ sizeof(t_FmPcdCcKeyAndNextEngineParams) -+ * FM_PCD_MAX_NUM_OF_CC_GROUPS); -+ if (!p_KeyAndNextEngineParams) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure")); -+ return NULL; -+ } -+ memcpy(p_KeyAndNextEngineParams, -+ p_FmPcdCcTree->keyAndNextEngineParams, -+ FM_PCD_MAX_NUM_OF_CC_GROUPS -+ * sizeof(t_FmPcdCcKeyAndNextEngineParams)); -+ } -+ -+ p_FmPcdModifyCcKeyAdditionalParams = -+ (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc( -+ sizeof(t_FmPcdModifyCcKeyAdditionalParams)); -+ if (!p_FmPcdModifyCcKeyAdditionalParams) -+ { -+ XX_Free(p_KeyAndNextEngineParams); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED")); -+ return NULL; -+ } -+ memset(p_FmPcdModifyCcKeyAdditionalParams, 0, -+ sizeof(t_FmPcdModifyCcKeyAdditionalParams)); -+ -+ p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree; -+ p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex; -+ -+ while (i < numOfKeys) -+ { -+ if ((j == keyIndex) && !wasUpdate) -+ { -+ if (modifyState == e_MODIFY_STATE_ADD) -+ j++; -+ else -+ if (modifyState == e_MODIFY_STATE_REMOVE) -+ i++; -+ wasUpdate = TRUE; -+ } -+ else -+ { -+ memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j], -+ p_KeyAndNextEngineParams + i, -+ sizeof(t_FmPcdCcKeyAndNextEngineParams)); -+ i++; -+ j++; -+ } -+ } -+ -+ if (keyIndex == numOfKeys) -+ { -+ if (modifyState == e_MODIFY_STATE_ADD) -+ j++; -+ } -+ -+ memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j], -+ p_KeyAndNextEngineParams + numOfKeys, -+ sizeof(t_FmPcdCcKeyAndNextEngineParams)); -+ -+ XX_Free(p_KeyAndNextEngineParams); -+ -+ return p_FmPcdModifyCcKeyAdditionalParams; -+} -+ -+static t_Error UpdatePtrWhichPointOnCrntMdfNode( -+ t_FmPcdCcNode *p_CcNode, -+ t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams, -+ t_List *h_OldLst, t_List *h_NewLst) -+{ -+ t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL; -+ t_CcNodeInformation ccNodeInfo = { 0 }; -+ t_Handle h_NewAd; -+ t_Handle h_OrigAd = NULL; -+ -+ /* Building a list of all action descriptors that point to the previous node */ -+ if (!LIST_IsEmpty(&p_CcNode->ccPrevNodesLst)) -+ UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst, -+ &p_NextEngineParams); -+ -+ if (!LIST_IsEmpty(&p_CcNode->ccTreeIdLst)) -+ UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst, -+ &p_NextEngineParams); -+ -+ /* This node must be found as next engine of one of its previous nodes or trees*/ -+ if (p_NextEngineParams) -+ { -+ /* Building a new action descriptor that points to the modified node */ -+ h_NewAd = GetNewAd(p_CcNode, FALSE); -+ if (!h_NewAd) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ MemSet8(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ h_OrigAd = p_CcNode->h_Ad; -+ BuildNewAd(h_NewAd, p_FmPcdModifyCcKeyAdditionalParams, p_CcNode, -+ p_NextEngineParams); -+ -+ ccNodeInfo.h_CcNode = h_NewAd; -+ EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL); -+ -+ if (p_NextEngineParams->h_Manip && !h_OrigAd) -+ FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE); -+ } -+ return E_OK; -+} -+ -+static void UpdateCcRootOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add) -+{ -+ ASSERT_COND(p_FmPcdCcTree); -+ -+ /* this routine must be protected by the calling routine! */ -+ -+ if (add) -+ p_FmPcdCcTree->owners++; -+ else -+ { -+ ASSERT_COND(p_FmPcdCcTree->owners); -+ p_FmPcdCcTree->owners--; -+ } -+} -+ -+static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_CcNode) -+{ -+ t_Error err = E_OK; -+ int i = 0; -+ -+ for (i = 0; i < p_CcNode->numOfKeys; i++) -+ { -+ if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip) -+ { -+ err = -+ FmPcdManipCheckParamsWithCcNodeParams( -+ p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip, -+ (t_Handle)p_CcNode); -+ if (err) -+ return err; -+ } -+ } -+ -+ return err; -+} -+static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode, -+ t_FmPcdCcNodeParams *p_CcNodeParam, -+ uint32_t *p_NumOfRanges, -+ uint32_t *p_CountersArraySize) -+{ -+ e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode; -+ uint32_t i; -+ -+ UNUSED(p_CcNodeParam); -+ -+ switch (statisticsMode) -+ { -+ case e_FM_PCD_CC_STATS_MODE_NONE: -+ for (i = 0; i < p_CcNode->numOfKeys; i++) -+ if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i)); -+ return E_OK; -+ -+ case e_FM_PCD_CC_STATS_MODE_FRAME: -+ case e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME: -+ *p_NumOfRanges = 1; -+ *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE; -+ return E_OK; -+ -+#if (DPAA_VERSION >= 11) -+ case e_FM_PCD_CC_STATS_MODE_RMON: -+ { -+ uint16_t *p_FrameLengthRanges = -+ p_CcNodeParam->keysParams.frameLengthRanges; -+ uint32_t i; -+ -+ if (p_FrameLengthRanges[0] <= 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode")); -+ -+ if (p_FrameLengthRanges[0] == 0xFFFF) -+ { -+ *p_NumOfRanges = 1; -+ *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE; -+ return E_OK; -+ } -+ -+ for (i = 1; i < FM_PCD_CC_STATS_MAX_NUM_OF_FLR; i++) -+ { -+ if (p_FrameLengthRanges[i - 1] >= p_FrameLengthRanges[i]) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("Frame length range must be larger at least by 1 from preceding range")); -+ -+ /* Stop when last range is reached */ -+ if (p_FrameLengthRanges[i] == 0xFFFF) -+ break; -+ } -+ -+ if ((i >= FM_PCD_CC_STATS_MAX_NUM_OF_FLR) -+ || (p_FrameLengthRanges[i] != 0xFFFF)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("Last Frame length range must be 0xFFFF")); -+ -+ *p_NumOfRanges = i + 1; -+ -+ /* Allocate an extra counter for byte count, as counters -+ array always begins with byte count */ -+ *p_CountersArraySize = (*p_NumOfRanges + 1) -+ * FM_PCD_CC_STATS_COUNTER_SIZE; -+ -+ } -+ return E_OK; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode")); -+ } -+} -+ -+static t_Error CheckParams(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam, -+ t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc) -+{ -+ int tmp = 0; -+ t_FmPcdCcKeyParams *p_KeyParams; -+ t_Error err; -+ uint32_t requiredAction = 0; -+ -+ /* Validate statistics parameters */ -+ err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam, -+ &(p_CcNode->numOfStatsFLRs), -+ &(p_CcNode->countersArraySize)); -+ if (err) -+ RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters")); -+ -+ /* Validate next engine parameters on Miss */ -+ err = ValidateNextEngineParams( -+ h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, -+ p_CcNode->statisticsMode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, -+ ("For this node MissNextEngineParams are not valid")); -+ -+ if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip) -+ { -+ err = FmPcdManipCheckParamsForCcNextEngine( -+ &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, -+ &requiredAction); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ -+ memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams, -+ &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, -+ sizeof(t_FmPcdCcNextEngineParams)); -+ -+ p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction = -+ requiredAction; -+ -+ if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip) -+ { -+ err = -+ AllocAndFillAdForContLookupManip( -+ p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ -+ for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) -+ { -+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; -+ -+ if (!p_KeyParams->p_Key) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized")); -+ -+ err = ValidateNextEngineParams(h_FmPcd, -+ &p_KeyParams->ccNextEngineParams, -+ p_CcNode->statisticsMode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ -+ err = UpdateGblMask(p_CcNode, p_CcNodeParam->keysParams.keySize, -+ p_KeyParams->p_Mask); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ -+ if (p_KeyParams->ccNextEngineParams.h_Manip) -+ { -+ err = FmPcdManipCheckParamsForCcNextEngine( -+ &p_KeyParams->ccNextEngineParams, &requiredAction); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ -+ /* Store 'key' parameters - key, mask (if passed by the user) */ -+ memcpy(p_CcNode->keyAndNextEngineParams[tmp].key, p_KeyParams->p_Key, -+ p_CcNodeParam->keysParams.keySize); -+ -+ if (p_KeyParams->p_Mask) -+ memcpy(p_CcNode->keyAndNextEngineParams[tmp].mask, -+ p_KeyParams->p_Mask, p_CcNodeParam->keysParams.keySize); -+ else -+ memset((void *)(p_CcNode->keyAndNextEngineParams[tmp].mask), 0xFF, -+ p_CcNodeParam->keysParams.keySize); -+ -+ /* Store next engine parameters */ -+ memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams, -+ &p_KeyParams->ccNextEngineParams, -+ sizeof(t_FmPcdCcNextEngineParams)); -+ -+ p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction; -+ -+ if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) -+ { -+ err = -+ AllocAndFillAdForContLookupManip( -+ p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ } -+ -+ if (p_CcNode->maxNumOfKeys) -+ { -+ if (p_CcNode->maxNumOfKeys < p_CcNode->numOfKeys) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("Number of keys exceed the provided maximal number of keys")); -+ } -+ -+ *isKeyTblAlloc = TRUE; -+ -+ return E_OK; -+} -+ -+static t_Error Ipv4TtlOrIpv6HopLimitCheckParams( -+ t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam, -+ t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc) -+{ -+ int tmp = 0; -+ t_FmPcdCcKeyParams *p_KeyParams; -+ t_Error err; -+ uint8_t key = 0x01; -+ uint32_t requiredAction = 0; -+ -+ if (p_CcNode->numOfKeys != 1) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'numOfKeys' is 1")); -+ -+ if ((p_CcNodeParam->keysParams.maxNumOfKeys) -+ && (p_CcNodeParam->keysParams.maxNumOfKeys != 1)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'maxNumOfKeys' is 1")); -+ -+ /* Validate statistics parameters */ -+ err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam, -+ &(p_CcNode->numOfStatsFLRs), -+ &(p_CcNode->countersArraySize)); -+ if (err) -+ RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters")); -+ -+ err = ValidateNextEngineParams( -+ h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, -+ p_CcNodeParam->keysParams.statisticsMode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, -+ ("For this node MissNextEngineParams are not valid")); -+ -+ if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip) -+ { -+ err = FmPcdManipCheckParamsForCcNextEngine( -+ &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, -+ &requiredAction); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ -+ memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams, -+ &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, -+ sizeof(t_FmPcdCcNextEngineParams)); -+ -+ p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction = -+ requiredAction; -+ -+ if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip) -+ { -+ err = -+ AllocAndFillAdForContLookupManip( -+ p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ -+ for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) -+ { -+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; -+ -+ if (p_KeyParams->p_Mask) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized")); -+ -+ if (memcmp(p_KeyParams->p_Key, &key, 1) != 0) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1")); -+ -+ err = ValidateNextEngineParams(h_FmPcd, -+ &p_KeyParams->ccNextEngineParams, -+ p_CcNode->statisticsMode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ -+ if (p_KeyParams->ccNextEngineParams.h_Manip) -+ { -+ err = FmPcdManipCheckParamsForCcNextEngine( -+ &p_KeyParams->ccNextEngineParams, &requiredAction); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ -+ /* Store 'key' parameters - key (fixed to 0x01), key size of 1 byte and full mask */ -+ p_CcNode->keyAndNextEngineParams[tmp].key[0] = key; -+ p_CcNode->keyAndNextEngineParams[tmp].mask[0] = 0xFF; -+ -+ /* Store NextEngine parameters */ -+ memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams, -+ &p_KeyParams->ccNextEngineParams, -+ sizeof(t_FmPcdCcNextEngineParams)); -+ -+ if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) -+ { -+ err = -+ AllocAndFillAdForContLookupManip( -+ p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction; -+ } -+ -+ *isKeyTblAlloc = FALSE; -+ -+ return E_OK; -+} -+ -+static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd, -+ t_FmPcdCcNodeParams *p_CcNodeParam, -+ t_FmPcdCcNode *p_CcNode, -+ bool *isKeyTblAlloc) -+{ -+ int tmp = 0, countOnes = 0; -+ t_FmPcdCcKeyParams *p_KeyParams; -+ t_Error err; -+ uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask; -+ uint16_t countMask = (uint16_t)(glblMask >> 4); -+ uint32_t requiredAction = 0; -+ -+ if (glblMask & 0x000f) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("icIndxMask has to be with last nibble 0")); -+ -+ while (countMask) -+ { -+ countOnes++; -+ countMask = (uint16_t)(countMask >> 1); -+ } -+ -+ if (!POWER_OF_2(p_CcNode->numOfKeys)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("For Node of the type INDEXED numOfKeys has to be powerOfTwo")); -+ -+ if (p_CcNode->numOfKeys != ((uint32_t)1 << countOnes)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo")); -+ -+ if (p_CcNodeParam->keysParams.maxNumOfKeys -+ && (p_CcNodeParam->keysParams.maxNumOfKeys != p_CcNode->numOfKeys)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("For Node of the type INDEXED 'maxNumOfKeys' should be 0 or equal 'numOfKeys'")); -+ -+ /* Validate statistics parameters */ -+ err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam, -+ &(p_CcNode->numOfStatsFLRs), -+ &(p_CcNode->countersArraySize)); -+ if (err) -+ RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters")); -+ -+ err = ValidateNextEngineParams( -+ h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, -+ p_CcNode->statisticsMode); -+ if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED) -+ RETURN_ERROR( -+ MAJOR, -+ err, -+ ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized")); -+ -+ for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) -+ { -+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; -+ -+ if (p_KeyParams->p_Mask || p_KeyParams->p_Key) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL")); -+ -+ if ((glblMask & (tmp * 16)) == (tmp * 16)) -+ { -+ err = ValidateNextEngineParams(h_FmPcd, -+ &p_KeyParams->ccNextEngineParams, -+ p_CcNode->statisticsMode); -+ if (err) -+ RETURN_ERROR( -+ MAJOR, -+ err, -+ ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask ")); -+ -+ if (p_KeyParams->ccNextEngineParams.h_Manip) -+ { -+ err = FmPcdManipCheckParamsForCcNextEngine( -+ &p_KeyParams->ccNextEngineParams, &requiredAction); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ p_CcNode->keyAndNextEngineParams[tmp].requiredAction = -+ requiredAction; -+ } -+ -+ memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams, -+ &p_KeyParams->ccNextEngineParams, -+ sizeof(t_FmPcdCcNextEngineParams)); -+ -+ if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) -+ { -+ err = -+ AllocAndFillAdForContLookupManip( -+ p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode); -+ if (err) -+ RETURN_ERROR(MAJOR, err, (NO_MSG)); -+ } -+ } -+ else -+ { -+ err = ValidateNextEngineParams(h_FmPcd, -+ &p_KeyParams->ccNextEngineParams, -+ p_CcNode->statisticsMode); -+ if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED) -+ RETURN_ERROR( -+ MAJOR, -+ err, -+ ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask")); -+ } -+ } -+ -+ *isKeyTblAlloc = FALSE; -+ cpu_to_be16s(&glblMask); -+ memcpy(PTR_MOVE(p_CcNode->p_GlblMask, 2), &glblMask, 2); -+ -+ return E_OK; -+} -+ -+static t_Error ModifyNextEngineParamNode( -+ t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; -+ t_FmPcd *p_FmPcd; -+ t_List h_OldPointersLst, h_NewPointersLst; -+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_VALUE); -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ -+ if (keyIndex >= p_CcNode->numOfKeys) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("keyIndex > previously cleared last index + 1")); -+ -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ -+ INIT_LIST(&h_OldPointersLst); -+ INIT_LIST(&h_NewPointersLst); -+ -+ p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, -+ e_MODIFY_STATE_CHANGE, FALSE, -+ FALSE, FALSE); -+ if (!p_ModifyKeyParams) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ if (p_CcNode->maxNumOfKeys -+ && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) -+ { -+ XX_Free(p_ModifyKeyParams); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex, -+ p_FmPcdCcNextEngineParams, -+ &h_OldPointersLst, &h_NewPointersLst, -+ p_ModifyKeyParams); -+ if (err) -+ { -+ XX_Free(p_ModifyKeyParams); -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, -+ p_ModifyKeyParams, FALSE); -+ -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ -+ ReleaseLst(&h_OldPointersLst); -+ ReleaseLst(&h_NewPointersLst); -+ -+ return err; -+} -+ -+static t_Error FindKeyIndex(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, -+ uint8_t *p_Mask, uint16_t *p_KeyIndex) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ uint8_t tmpMask[FM_PCD_MAX_SIZE_OF_KEY]; -+ uint16_t i; -+ -+ ASSERT_COND(p_Key); -+ ASSERT_COND(p_KeyIndex); -+ ASSERT_COND(keySize < FM_PCD_MAX_SIZE_OF_KEY); -+ -+ if (keySize != p_CcNode->userSizeOfExtraction) -+ RETURN_ERROR( -+ MINOR, E_INVALID_VALUE, -+ ("Key size doesn't match the extraction size of the node")); -+ -+ /* If user didn't pass a mask for this key, we'll look for full extraction mask */ -+ if (!p_Mask) -+ memset(tmpMask, 0xFF, keySize); -+ -+ for (i = 0; i < p_CcNode->numOfKeys; i++) -+ { -+ /* Comparing received key */ -+ if (memcmp(p_Key, p_CcNode->keyAndNextEngineParams[i].key, keySize) -+ == 0) -+ { -+ if (p_Mask) -+ { -+ /* If a user passed a mask for this key, it must match to the existing key's mask for a correct match */ -+ if (memcmp(p_Mask, p_CcNode->keyAndNextEngineParams[i].mask, -+ keySize) == 0) -+ { -+ *p_KeyIndex = i; -+ return E_OK; -+ } -+ } -+ else -+ { -+ /* If user didn't pass a mask for this key, check if the existing key mask is full extraction */ -+ if (memcmp(tmpMask, p_CcNode->keyAndNextEngineParams[i].mask, -+ keySize) == 0) -+ { -+ *p_KeyIndex = i; -+ return E_OK; -+ } -+ } -+ } -+ } -+ -+ return ERROR_CODE(E_NOT_FOUND); -+} -+ -+static t_Error CalcAndUpdateCcShadow(t_FmPcdCcNode *p_CcNode, -+ bool isKeyTblAlloc, -+ uint32_t *p_MatchTableSize, -+ uint32_t *p_AdTableSize) -+{ -+ uint32_t shadowSize; -+ t_Error err; -+ -+ /* Calculate keys table maximal size - each entry consists of a key and a mask, -+ (if local mask support is requested) */ -+ *p_MatchTableSize = p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t) -+ * p_CcNode->maxNumOfKeys; -+ -+ if (p_CcNode->maskSupport) -+ *p_MatchTableSize *= 2; -+ -+ /* Calculate next action descriptors table, including one more entry for miss */ -+ *p_AdTableSize = (uint32_t)((p_CcNode->maxNumOfKeys + 1) -+ * FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* Calculate maximal shadow size of this node. -+ All shadow structures will be used for runtime modifications host command. If -+ keys table was allocated for this node, the keys table and next engines table may -+ be modified in run time (entries added or removed), so shadow tables are requires. -+ Otherwise, the only supported runtime modification is a specific next engine update -+ and this requires shadow memory of a single AD */ -+ -+ /* Shadow size should be enough to hold the following 3 structures: -+ * 1 - an action descriptor */ -+ shadowSize = FM_PCD_CC_AD_ENTRY_SIZE; -+ -+ /* 2 - keys match table, if was allocated for the current node */ -+ if (isKeyTblAlloc) -+ shadowSize += *p_MatchTableSize; -+ -+ /* 3 - next action descriptors table */ -+ shadowSize += *p_AdTableSize; -+ -+ /* Update shadow to the calculated size */ -+ err = FmPcdUpdateCcShadow(p_CcNode->h_FmPcd, (uint32_t)shadowSize, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (err != E_OK) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node shadow")); -+ } -+ -+ return E_OK; -+} -+ -+static t_Error AllocStatsObjs(t_FmPcdCcNode *p_CcNode) -+{ -+ t_FmPcdStatsObj *p_StatsObj; -+ t_Handle h_FmMuram, h_StatsAd, h_StatsCounters; -+ uint32_t i; -+ -+ h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd); -+ if (!h_FmMuram) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM")); -+ -+ /* Allocate statistics ADs and statistics counter. An extra pair (AD + counters) -+ will be allocated to support runtime modifications */ -+ for (i = 0; i < p_CcNode->maxNumOfKeys + 2; i++) -+ { -+ /* Allocate list object structure */ -+ p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj)); -+ if (!p_StatsObj) -+ { -+ FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Statistics object")); -+ } -+ memset(p_StatsObj, 0, sizeof(t_FmPcdStatsObj)); -+ -+ /* Allocate statistics AD from MURAM */ -+ h_StatsAd = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, -+ FM_PCD_CC_AD_ENTRY_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!h_StatsAd) -+ { -+ FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); -+ XX_Free(p_StatsObj); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for statistics ADs")); -+ } -+ MemSet8(h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* Allocate statistics counters from MURAM */ -+ h_StatsCounters = (t_Handle)FM_MURAM_AllocMem( -+ h_FmMuram, p_CcNode->countersArraySize, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!h_StatsCounters) -+ { -+ FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram); -+ FM_MURAM_FreeMem(h_FmMuram, h_StatsAd); -+ XX_Free(p_StatsObj); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for statistics counters")); -+ } -+ MemSet8(h_StatsCounters, 0, p_CcNode->countersArraySize); -+ -+ p_StatsObj->h_StatsAd = h_StatsAd; -+ p_StatsObj->h_StatsCounters = h_StatsCounters; -+ -+ EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj); -+ } -+ -+ return E_OK; -+} -+ -+static t_Error MatchTableGetKeyStatistics( -+ t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, -+ t_FmPcdCcKeyStatistics *p_KeyStatistics) -+{ -+ uint32_t *p_StatsCounters, i; -+ -+ if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Statistics were not enabled for this match table")); -+ -+ if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Statistics were not enabled for this key")); -+ -+ memset(p_KeyStatistics, 0, sizeof(t_FmPcdCcKeyStatistics)); -+ -+ p_StatsCounters = -+ p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters; -+ ASSERT_COND(p_StatsCounters); -+ -+ p_KeyStatistics->byteCount = GET_UINT32(*p_StatsCounters); -+ -+ for (i = 1; i <= p_CcNode->numOfStatsFLRs; i++) -+ { -+ p_StatsCounters = -+ PTR_MOVE(p_StatsCounters, FM_PCD_CC_STATS_COUNTER_SIZE); -+ -+ p_KeyStatistics->frameCount += GET_UINT32(*p_StatsCounters); -+ -+#if (DPAA_VERSION >= 11) -+ p_KeyStatistics->frameLengthRangeCount[i - 1] = -+ GET_UINT32(*p_StatsCounters); -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+ return E_OK; -+} -+ -+static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, -+ t_FmPcdCcNodeParams *p_CcNodeParam) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ t_FmPcdCcNode *p_FmPcdCcNextNode; -+ t_Error err = E_OK; -+ uint32_t tmp, keySize; -+ bool glblMask = FALSE; -+ t_FmPcdCcKeyParams *p_KeyParams; -+ t_Handle h_FmMuram, p_KeysMatchTblTmp, p_AdTableTmp; -+#if (DPAA_VERSION >= 11) -+ t_Handle h_StatsFLRs; -+#endif /* (DPAA_VERSION >= 11) */ -+ bool fullField = FALSE; -+ ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE; -+ bool isKeyTblAlloc, fromIc = FALSE; -+ uint32_t matchTableSize, adTableSize; -+ t_CcNodeInformation ccNodeInfo, *p_CcInformation; -+ t_FmPcdStatsObj *p_StatsObj; -+ t_FmPcdCcStatsParams statsParams = { 0 }; -+ t_Handle h_Manip; -+ -+ ASSERT_COND(h_FmPcd); -+ ASSERT_COND(p_CcNode); -+ ASSERT_COND(p_CcNodeParam); -+ -+ p_CcNode->p_GlblMask = (t_Handle)XX_Malloc( -+ CC_GLBL_MASK_SIZE * sizeof(uint8_t)); -+ memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); -+ -+ p_CcNode->h_FmPcd = h_FmPcd; -+ p_CcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys; -+ p_CcNode->maxNumOfKeys = p_CcNodeParam->keysParams.maxNumOfKeys; -+ p_CcNode->maskSupport = p_CcNodeParam->keysParams.maskSupport; -+ p_CcNode->statisticsMode = p_CcNodeParam->keysParams.statisticsMode; -+ -+ /* For backward compatibility - even if statistics mode is nullified, -+ we'll fix it to frame mode so we can support per-key request for -+ statistics using 'statisticsEn' in next engine parameters */ -+ if (!p_CcNode->maxNumOfKeys -+ && (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)) -+ p_CcNode->statisticsMode = e_FM_PCD_CC_STATS_MODE_FRAME; -+ -+ h_FmMuram = FmPcdGetMuramHandle(h_FmPcd); -+ if (!h_FmMuram) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM")); -+ -+ INIT_LIST(&p_CcNode->ccPrevNodesLst); -+ INIT_LIST(&p_CcNode->ccTreeIdLst); -+ INIT_LIST(&p_CcNode->ccTreesLst); -+ INIT_LIST(&p_CcNode->availableStatsLst); -+ -+ p_CcNode->h_Spinlock = XX_InitSpinlock(); -+ if (!p_CcNode->h_Spinlock) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock")); -+ } -+ -+ if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR) -+ && ((p_CcNodeParam->extractCcParams.extractByHdr.hdr -+ == HEADER_TYPE_IPv4) -+ || (p_CcNodeParam->extractCcParams.extractByHdr.hdr -+ == HEADER_TYPE_IPv6)) -+ && (p_CcNodeParam->extractCcParams.extractByHdr.type -+ == e_FM_PCD_EXTRACT_FULL_FIELD) -+ && ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6 -+ == NET_HEADER_FIELD_IPv6_HOP_LIMIT) -+ || (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4 -+ == NET_HEADER_FIELD_IPv4_TTL))) -+ { -+ err = Ipv4TtlOrIpv6HopLimitCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, -+ &isKeyTblAlloc); -+ glblMask = FALSE; -+ } -+ else -+ if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR) -+ && ((p_CcNodeParam->extractCcParams.extractNonHdr.src -+ == e_FM_PCD_EXTRACT_FROM_KEY) -+ || (p_CcNodeParam->extractCcParams.extractNonHdr.src -+ == e_FM_PCD_EXTRACT_FROM_HASH) -+ || (p_CcNodeParam->extractCcParams.extractNonHdr.src -+ == e_FM_PCD_EXTRACT_FROM_FLOW_ID))) -+ { -+ if ((p_CcNodeParam->extractCcParams.extractNonHdr.src -+ == e_FM_PCD_EXTRACT_FROM_FLOW_ID) -+ && (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0)) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0")); -+ } -+ -+ icCode = IcDefineCode(p_CcNodeParam); -+ fromIc = TRUE; -+ if (icCode == CC_PRIVATE_INFO_NONE) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way")); -+ } -+ -+ if ((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP) -+ || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP)) -+ { -+ err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, -+ &isKeyTblAlloc); -+ glblMask = TRUE; -+ } -+ else -+ { -+ err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, -+ &isKeyTblAlloc); -+ if (p_CcNode->glblMaskSize) -+ glblMask = TRUE; -+ } -+ } -+ else -+ { -+ err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, &isKeyTblAlloc); -+ if (p_CcNode->glblMaskSize) -+ glblMask = TRUE; -+ } -+ -+ if (err) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ switch (p_CcNodeParam->extractCcParams.type) -+ { -+ case (e_FM_PCD_EXTRACT_BY_HDR): -+ switch (p_CcNodeParam->extractCcParams.extractByHdr.type) -+ { -+ case (e_FM_PCD_EXTRACT_FULL_FIELD): -+ p_CcNode->parseCode = -+ GetFullFieldParseCode( -+ p_CcNodeParam->extractCcParams.extractByHdr.hdr, -+ p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex, -+ p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField); -+ GetSizeHeaderField( -+ p_CcNodeParam->extractCcParams.extractByHdr.hdr, -+ p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField, -+ &p_CcNode->sizeOfExtraction); -+ fullField = TRUE; -+ if ((p_CcNode->parseCode != CC_PC_FF_TCI1) -+ && (p_CcNode->parseCode != CC_PC_FF_TCI2) -+ && (p_CcNode->parseCode != CC_PC_FF_MPLS1) -+ && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST) -+ && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1) -+ && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2) -+ && (p_CcNode->parseCode -+ != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1) -+ && (p_CcNode->parseCode != CC_PC_FF_IPDSCP) -+ && (p_CcNode->parseCode -+ != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2) -+ && glblMask) -+ { -+ glblMask = FALSE; -+ p_CcNode->glblMaskSize = 4; -+ p_CcNode->lclMask = TRUE; -+ } -+ break; -+ -+ case (e_FM_PCD_EXTRACT_FROM_HDR): -+ p_CcNode->sizeOfExtraction = -+ p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size; -+ p_CcNode->offset = -+ p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset; -+ p_CcNode->userOffset = -+ p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset; -+ p_CcNode->parseCode = -+ GetPrParseCode( -+ p_CcNodeParam->extractCcParams.extractByHdr.hdr, -+ p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex, -+ p_CcNode->offset, glblMask, -+ &p_CcNode->prsArrayOffset); -+ break; -+ -+ case (e_FM_PCD_EXTRACT_FROM_FIELD): -+ p_CcNode->offset = -+ p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset; -+ p_CcNode->userOffset = -+ p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset; -+ p_CcNode->sizeOfExtraction = -+ p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size; -+ p_CcNode->parseCode = -+ GetFieldParseCode( -+ p_CcNodeParam->extractCcParams.extractByHdr.hdr, -+ p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field, -+ p_CcNode->offset, -+ &p_CcNode->prsArrayOffset, -+ p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex); -+ break; -+ -+ default: -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ break; -+ -+ case (e_FM_PCD_EXTRACT_NON_HDR): -+ /* get the field code for the generic extract */ -+ p_CcNode->sizeOfExtraction = -+ p_CcNodeParam->extractCcParams.extractNonHdr.size; -+ p_CcNode->offset = -+ p_CcNodeParam->extractCcParams.extractNonHdr.offset; -+ p_CcNode->userOffset = -+ p_CcNodeParam->extractCcParams.extractNonHdr.offset; -+ p_CcNode->parseCode = GetGenParseCode( -+ p_CcNodeParam->extractCcParams.extractNonHdr.src, -+ p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset, -+ fromIc, icCode); -+ -+ if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED) -+ { -+ if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_SELECTION, -+ ("when node of the type CC_PC_GENERIC_IC_HASH_INDEXED offset + size can not be bigger then size of HASH 64 bits (8 bytes)")); -+ } -+ } -+ if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK) -+ || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)) -+ { -+ p_CcNode->offset += p_CcNode->prsArrayOffset; -+ p_CcNode->prsArrayOffset = 0; -+ } -+ break; -+ -+ default: -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ -+ if (p_CcNode->parseCode == CC_PC_ILLEGAL) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type")); -+ } -+ -+ if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY) -+ || !p_CcNode->sizeOfExtraction) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("sizeOfExatrction can not be greater than 56 and not 0")); -+ } -+ -+ if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("keySize has to be equal to sizeOfExtraction")); -+ } -+ -+ p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction; -+ -+ if (!glblMask) -+ memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t)); -+ -+ err = CheckAndSetManipParamsWithCcNodeParams(p_CcNode); -+ if (err != E_OK) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("keySize has to be equal to sizeOfExtraction")); -+ } -+ -+ /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */ -+ GetCcExtractKeySize(p_CcNode->sizeOfExtraction, -+ &p_CcNode->ccKeySizeAccExtraction); -+ -+ /* If local mask is used, it is stored next to each key in the keys match table */ -+ if (p_CcNode->lclMask) -+ keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction); -+ else -+ keySize = p_CcNode->ccKeySizeAccExtraction; -+ -+ /* Update CC shadow with maximal size required by this node */ -+ if (p_CcNode->maxNumOfKeys) -+ { -+ err = CalcAndUpdateCcShadow(p_CcNode, isKeyTblAlloc, &matchTableSize, -+ &adTableSize); -+ if (err != E_OK) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ p_CcNode->keysMatchTableMaxSize = matchTableSize; -+ -+ if (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE) -+ { -+ err = AllocStatsObjs(p_CcNode); -+ if (err != E_OK) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ -+ /* If manipulation will be initialized before this node, it will use the table -+ descriptor in the AD table of previous node and this node will need an extra -+ AD as his table descriptor. */ -+ p_CcNode->h_TmpAd = (t_Handle)FM_MURAM_AllocMem( -+ h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_CcNode->h_TmpAd) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for CC action descriptor")); -+ } -+ } -+ else -+ { -+ matchTableSize = (uint32_t)(keySize * sizeof(uint8_t) -+ * (p_CcNode->numOfKeys + 1)); -+ adTableSize = (uint32_t)(FM_PCD_CC_AD_ENTRY_SIZE -+ * (p_CcNode->numOfKeys + 1)); -+ } -+ -+#if (DPAA_VERSION >= 11) -+ switch (p_CcNode->statisticsMode) -+ { -+ -+ case e_FM_PCD_CC_STATS_MODE_RMON: -+ /* If RMON statistics or RMON conditional statistics modes are requested, -+ allocate frame length ranges array */ -+ p_CcNode->h_StatsFLRs = FM_MURAM_AllocMem( -+ h_FmMuram, -+ (uint32_t)(p_CcNode->numOfStatsFLRs) -+ * FM_PCD_CC_STATS_FLR_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ -+ if (!p_CcNode->h_StatsFLRs) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR( -+ MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for CC frame length ranges array")); -+ } -+ -+ /* Initialize using value received from the user */ -+ for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++) -+ { -+ uint16_t flr = -+ cpu_to_be16(p_CcNodeParam->keysParams.frameLengthRanges[tmp]); -+ -+ h_StatsFLRs = -+ PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE); -+ -+ MemCpy8(h_StatsFLRs, -+ &flr, -+ FM_PCD_CC_STATS_FLR_SIZE); -+ } -+ break; -+ -+ default: -+ break; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ /* Allocate keys match table. Not required for some CC nodes, for example for IPv4 TTL -+ identification, IPv6 hop count identification, etc. */ -+ if (isKeyTblAlloc) -+ { -+ p_CcNode->h_KeysMatchTable = (t_Handle)FM_MURAM_AllocMem( -+ h_FmMuram, matchTableSize, FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN); -+ if (!p_CcNode->h_KeysMatchTable) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for CC node key match table")); -+ } -+ MemSet8((uint8_t *)p_CcNode->h_KeysMatchTable, 0, matchTableSize); -+ } -+ -+ /* Allocate action descriptors table */ -+ p_CcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, adTableSize, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_CcNode->h_AdTable) -+ { -+ DeleteNode(p_CcNode); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for CC node action descriptors table")); -+ } -+ MemSet8((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize); -+ -+ p_KeysMatchTblTmp = p_CcNode->h_KeysMatchTable; -+ p_AdTableTmp = p_CcNode->h_AdTable; -+ -+ /* For each key, create the key and the next step AD */ -+ for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++) -+ { -+ p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp]; -+ -+ if (p_KeysMatchTblTmp) -+ { -+ /* Copy the key */ -+ MemCpy8((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key, -+ p_CcNode->sizeOfExtraction); -+ -+ /* Copy the key mask or initialize it to 0xFF..F */ -+ if (p_CcNode->lclMask && p_KeyParams->p_Mask) -+ { -+ MemCpy8(PTR_MOVE(p_KeysMatchTblTmp, -+ p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */ -+ p_KeyParams->p_Mask, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */ -+ } -+ else -+ if (p_CcNode->lclMask) -+ { -+ MemSet8(PTR_MOVE(p_KeysMatchTblTmp, -+ p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */ -+ 0xff, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */ -+ } -+ -+ p_KeysMatchTblTmp = -+ PTR_MOVE(p_KeysMatchTblTmp, keySize * sizeof(uint8_t)); -+ } -+ -+ /* Create the next action descriptor in the match table */ -+ if (p_KeyParams->ccNextEngineParams.statisticsEn) -+ { -+ p_StatsObj = GetStatsObj(p_CcNode); -+ ASSERT_COND(p_StatsObj); -+ -+ statsParams.h_StatsAd = p_StatsObj->h_StatsAd; -+ statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; -+#if (DPAA_VERSION >= 11) -+ statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs; -+ -+#endif /* (DPAA_VERSION >= 11) */ -+ NextStepAd(p_AdTableTmp, &statsParams, -+ &p_KeyParams->ccNextEngineParams, p_FmPcd); -+ -+ p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj; -+ } -+ else -+ { -+ NextStepAd(p_AdTableTmp, NULL, &p_KeyParams->ccNextEngineParams, -+ p_FmPcd); -+ -+ p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL; -+ } -+ -+ p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE); -+ } -+ -+ /* Update next engine for the 'miss' entry */ -+ if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.statisticsEn) -+ { -+ p_StatsObj = GetStatsObj(p_CcNode); -+ ASSERT_COND(p_StatsObj); -+ -+ /* All 'bucket' nodes of a hash table should share the same statistics counters, -+ allocated by the hash table. So, if this node is a bucket of a hash table, -+ we'll replace the locally allocated counters with the shared counters. */ -+ if (p_CcNode->isHashBucket) -+ { -+ ASSERT_COND(p_CcNode->h_MissStatsCounters); -+ -+ /* Store original counters pointer and replace it with mutual preallocated pointer */ -+ p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters; -+ p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters; -+ } -+ -+ statsParams.h_StatsAd = p_StatsObj->h_StatsAd; -+ statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters; -+#if (DPAA_VERSION >= 11) -+ statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs; -+ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ NextStepAd(p_AdTableTmp, &statsParams, -+ &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, -+ p_FmPcd); -+ -+ p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj; -+ } -+ else -+ { -+ NextStepAd(p_AdTableTmp, NULL, -+ &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss, -+ p_FmPcd); -+ -+ p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL; -+ } -+ -+ /* This parameter will be used to initialize the "key length" field in the action descriptor -+ that points to this node and it should be 0 for full field extraction */ -+ if (fullField == TRUE) -+ p_CcNode->sizeOfExtraction = 0; -+ -+ for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++) -+ { -+ if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ { -+ p_FmPcdCcNextNode = -+ (t_FmPcdCcNode*)p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode; -+ p_CcInformation = FindNodeInfoInReleventLst( -+ &p_FmPcdCcNextNode->ccPrevNodesLst, (t_Handle)p_CcNode, -+ p_FmPcdCcNextNode->h_Spinlock); -+ if (!p_CcInformation) -+ { -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ ccNodeInfo.h_CcNode = (t_Handle)p_CcNode; -+ ccNodeInfo.index = 1; -+ EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst, -+ &ccNodeInfo, -+ p_FmPcdCcNextNode->h_Spinlock); -+ } -+ else -+ p_CcInformation->index++; -+ -+ if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip) -+ { -+ h_Manip = -+ p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip; -+ p_CcInformation = FindNodeInfoInReleventLst( -+ FmPcdManipGetNodeLstPointedOnThisManip(h_Manip), -+ (t_Handle)p_CcNode, FmPcdManipGetSpinlock(h_Manip)); -+ if (!p_CcInformation) -+ { -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ ccNodeInfo.h_CcNode = (t_Handle)p_CcNode; -+ ccNodeInfo.index = 1; -+ EnqueueNodeInfoToRelevantLst( -+ FmPcdManipGetNodeLstPointedOnThisManip(h_Manip), -+ &ccNodeInfo, FmPcdManipGetSpinlock(h_Manip)); -+ } -+ else -+ p_CcInformation->index++; -+ } -+ } -+ } -+ -+ p_AdTableTmp = p_CcNode->h_AdTable; -+ -+ if (!FmPcdLockTryLockAll(h_FmPcd)) -+ { -+ FM_PCD_MatchTableDelete((t_Handle)p_CcNode); -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ /* Required action for each next engine */ -+ for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++) -+ { -+ if (p_CcNode->keyAndNextEngineParams[tmp].requiredAction) -+ { -+ err = SetRequiredAction( -+ h_FmPcd, -+ p_CcNode->keyAndNextEngineParams[tmp].requiredAction, -+ &p_CcNode->keyAndNextEngineParams[tmp], p_AdTableTmp, 1, -+ NULL); -+ if (err) -+ { -+ FmPcdLockUnlockAll(h_FmPcd); -+ FM_PCD_MatchTableDelete((t_Handle)p_CcNode); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE); -+ } -+ } -+ -+ FmPcdLockUnlockAll(h_FmPcd); -+ -+ return E_OK; -+} -+/************************** End of static functions **************************/ -+ -+/*****************************************************************************/ -+/* Inter-module API routines */ -+/*****************************************************************************/ -+ -+t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, -+ t_Handle h_Spinlock) -+{ -+ t_CcNodeInformation *p_CcInformation; -+ t_List *p_Pos; -+ uint32_t intFlags; -+ -+ intFlags = XX_LockIntrSpinlock(h_Spinlock); -+ -+ for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List); -+ p_Pos = LIST_NEXT(p_Pos)) -+ { -+ p_CcInformation = CC_NODE_F_OBJECT(p_Pos); -+ -+ ASSERT_COND(p_CcInformation->h_CcNode); -+ -+ if (p_CcInformation->h_CcNode == h_Info) -+ { -+ XX_UnlockIntrSpinlock(h_Spinlock, intFlags); -+ return p_CcInformation; -+ } -+ } -+ -+ XX_UnlockIntrSpinlock(h_Spinlock, intFlags); -+ -+ return NULL; -+} -+ -+void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, -+ t_Handle h_Spinlock) -+{ -+ t_CcNodeInformation *p_CcInformation; -+ uint32_t intFlags = 0; -+ -+ p_CcInformation = (t_CcNodeInformation *)XX_Malloc( -+ sizeof(t_CcNodeInformation)); -+ -+ if (p_CcInformation) -+ { -+ memset(p_CcInformation, 0, sizeof(t_CcNodeInformation)); -+ memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation)); -+ INIT_LIST(&p_CcInformation->node); -+ -+ if (h_Spinlock) -+ intFlags = XX_LockIntrSpinlock(h_Spinlock); -+ -+ LIST_AddToTail(&p_CcInformation->node, p_List); -+ -+ if (h_Spinlock) -+ XX_UnlockIntrSpinlock(h_Spinlock, intFlags); -+ } -+ else -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information")); -+} -+ -+void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, -+ t_Handle h_Spinlock) -+{ -+ t_CcNodeInformation *p_CcInformation = NULL; -+ uint32_t intFlags = 0; -+ t_List *p_Pos; -+ -+ if (h_Spinlock) -+ intFlags = XX_LockIntrSpinlock(h_Spinlock); -+ -+ if (LIST_IsEmpty(p_List)) -+ { -+ XX_RestoreAllIntr(intFlags); -+ return; -+ } -+ -+ for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List); -+ p_Pos = LIST_NEXT(p_Pos)) -+ { -+ p_CcInformation = CC_NODE_F_OBJECT(p_Pos); -+ ASSERT_COND(p_CcInformation); -+ ASSERT_COND(p_CcInformation->h_CcNode); -+ if (p_CcInformation->h_CcNode == h_Info) -+ break; -+ } -+ -+ if (p_CcInformation) -+ { -+ LIST_DelAndInit(&p_CcInformation->node); -+ XX_Free(p_CcInformation); -+ } -+ -+ if (h_Spinlock) -+ XX_UnlockIntrSpinlock(h_Spinlock, intFlags); -+} -+ -+void NextStepAd(t_Handle h_Ad, t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, -+ t_FmPcd *p_FmPcd) -+{ -+ switch (p_FmPcdCcNextEngineParams->nextEngine) -+ { -+ case (e_FM_PCD_KG): -+ case (e_FM_PCD_PLCR): -+ case (e_FM_PCD_DONE): -+ /* if NIA is not CC, create a "result" type AD */ -+ FillAdOfTypeResult(h_Ad, p_FmPcdCcStatsParams, p_FmPcd, -+ p_FmPcdCcNextEngineParams); -+ break; -+#if (DPAA_VERSION >= 11) -+ case (e_FM_PCD_FR): -+ if (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic) -+ { -+ FillAdOfTypeContLookup( -+ h_Ad, p_FmPcdCcStatsParams, p_FmPcd, -+ p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode, -+ p_FmPcdCcNextEngineParams->h_Manip, -+ p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic); -+ FrmReplicGroupUpdateOwner( -+ p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic, -+ TRUE/* add */); -+ } -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ case (e_FM_PCD_CC): -+ /* if NIA is not CC, create a TD to continue the CC lookup */ -+ FillAdOfTypeContLookup( -+ h_Ad, p_FmPcdCcStatsParams, p_FmPcd, -+ p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode, -+ p_FmPcdCcNextEngineParams->h_Manip, NULL); -+ -+ UpdateNodeOwner(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode, -+ TRUE); -+ break; -+ -+ default: -+ return; -+ } -+} -+ -+t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, -+ t_Handle h_NetEnv, t_Handle h_IpReassemblyManip, -+ bool createSchemes) -+{ -+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; -+ t_FmPcdCcNextEngineParams nextEngineParams; -+ t_NetEnvParams netEnvParams; -+ t_Handle h_Ad; -+ bool isIpv6Present; -+ uint8_t ipv4GroupId, ipv6GroupId; -+ t_Error err; -+ -+ ASSERT_COND(p_FmPcdCcTree); -+ -+ /* this routine must be protected by the calling routine! */ -+ -+ memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams)); -+ memset(&netEnvParams, 0, sizeof(t_NetEnvParams)); -+ -+ h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); -+ -+ isIpv6Present = FmPcdManipIpReassmIsIpv6Hdr(h_IpReassemblyManip); -+ -+ if (isIpv6Present -+ && (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR")); -+ -+ if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR")); -+ -+ nextEngineParams.nextEngine = e_FM_PCD_DONE; -+ nextEngineParams.h_Manip = h_IpReassemblyManip; -+ -+ /* Lock tree */ -+ err = CcRootTryLock(p_FmPcdCcTree); -+ if (err) -+ return ERROR_CODE(E_BUSY); -+ -+ if (p_FmPcdCcTree->h_IpReassemblyManip == h_IpReassemblyManip) -+ { -+ CcRootReleaseLock(p_FmPcdCcTree); -+ return E_OK; -+ } -+ -+ if ((p_FmPcdCcTree->h_IpReassemblyManip) -+ && (p_FmPcdCcTree->h_IpReassemblyManip != h_IpReassemblyManip)) -+ { -+ CcRootReleaseLock(p_FmPcdCcTree); -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("This tree was previously updated with different IPR")); -+ } -+ -+ /* Initialize IPR for the first time for this tree */ -+ if (isIpv6Present) -+ { -+ ipv6GroupId = p_FmPcdCcTree->numOfGrps++; -+ p_FmPcdCcTree->fmPcdGroupParam[ipv6GroupId].baseGroupEntry = -+ (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2); -+ -+ if (createSchemes) -+ { -+ err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, -+ p_FmPcdCcTree, -+ h_IpReassemblyManip, FALSE, -+ ipv6GroupId); -+ if (err) -+ { -+ p_FmPcdCcTree->numOfGrps--; -+ CcRootReleaseLock(p_FmPcdCcTree); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ -+ NextStepAd( -+ PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-2) * FM_PCD_CC_AD_ENTRY_SIZE), -+ NULL, &nextEngineParams, h_FmPcd); -+ } -+ -+ ipv4GroupId = p_FmPcdCcTree->numOfGrps++; -+ p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].totalBitsMask = 0; -+ p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].baseGroupEntry = -+ (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1); -+ -+ if (createSchemes) -+ { -+ err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, p_FmPcdCcTree, -+ h_IpReassemblyManip, TRUE, -+ ipv4GroupId); -+ if (err) -+ { -+ p_FmPcdCcTree->numOfGrps--; -+ if (isIpv6Present) -+ { -+ p_FmPcdCcTree->numOfGrps--; -+ FmPcdManipDeleteIpReassmSchemes(h_IpReassemblyManip); -+ } -+ CcRootReleaseLock(p_FmPcdCcTree); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ -+ NextStepAd( -+ PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE), -+ NULL, &nextEngineParams, h_FmPcd); -+ -+ p_FmPcdCcTree->h_IpReassemblyManip = h_IpReassemblyManip; -+ -+ CcRootReleaseLock(p_FmPcdCcTree); -+ -+ return E_OK; -+} -+ -+t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, -+ t_Handle h_NetEnv, t_Handle h_ReassemblyManip, -+ bool createSchemes) -+{ -+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; -+ t_FmPcdCcNextEngineParams nextEngineParams; -+ t_NetEnvParams netEnvParams; -+ t_Handle h_Ad; -+ uint8_t groupId; -+ t_Error err; -+ -+ ASSERT_COND(p_FmPcdCcTree); -+ -+ /* this routine must be protected by the calling routine! */ -+ memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams)); -+ memset(&netEnvParams, 0, sizeof(t_NetEnvParams)); -+ -+ h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); -+ -+ if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need one free entries for CPR")); -+ -+ nextEngineParams.nextEngine = e_FM_PCD_DONE; -+ nextEngineParams.h_Manip = h_ReassemblyManip; -+ -+ /* Lock tree */ -+ err = CcRootTryLock(p_FmPcdCcTree); -+ if (err) -+ return ERROR_CODE(E_BUSY); -+ -+ if (p_FmPcdCcTree->h_CapwapReassemblyManip == h_ReassemblyManip) -+ { -+ CcRootReleaseLock(p_FmPcdCcTree); -+ return E_OK; -+ } -+ -+ if ((p_FmPcdCcTree->h_CapwapReassemblyManip) -+ && (p_FmPcdCcTree->h_CapwapReassemblyManip != h_ReassemblyManip)) -+ { -+ CcRootReleaseLock(p_FmPcdCcTree); -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("This tree was previously updated with different CPR")); -+ } -+ -+ groupId = p_FmPcdCcTree->numOfGrps++; -+ p_FmPcdCcTree->fmPcdGroupParam[groupId].baseGroupEntry = -+ (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1); -+ -+ if (createSchemes) -+ { -+ err = FmPcdManipBuildCapwapReassmScheme(h_FmPcd, h_NetEnv, -+ p_FmPcdCcTree, -+ h_ReassemblyManip, groupId); -+ if (err) -+ { -+ p_FmPcdCcTree->numOfGrps--; -+ CcRootReleaseLock(p_FmPcdCcTree); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ -+ NextStepAd( -+ PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE), -+ NULL, &nextEngineParams, h_FmPcd); -+ -+ p_FmPcdCcTree->h_CapwapReassemblyManip = h_ReassemblyManip; -+ -+ CcRootReleaseLock(p_FmPcdCcTree); -+ -+ return E_OK; -+} -+ -+t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree) -+{ -+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; -+ -+ ASSERT_COND(p_FmPcdCcTree); -+ -+ return p_FmPcdCcTree->h_FmPcdCcSavedManipParams; -+} -+ -+void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, -+ t_Handle h_SavedManipParams) -+{ -+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree; -+ -+ ASSERT_COND(p_FmPcdCcTree); -+ -+ p_FmPcdCcTree->h_FmPcdCcSavedManipParams = h_SavedManipParams; -+} -+ -+uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ -+ ASSERT_COND(p_CcNode); -+ -+ return p_CcNode->parseCode; -+} -+ -+uint8_t FmPcdCcGetOffset(t_Handle h_CcNode) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ -+ ASSERT_COND(p_CcNode); -+ -+ return p_CcNode->offset; -+} -+ -+uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ -+ ASSERT_COND(p_CcNode); -+ -+ return p_CcNode->numOfKeys; -+} -+ -+t_Error FmPcdCcModifyNextEngineParamTree( -+ t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; -+ t_FmPcd *p_FmPcd; -+ t_List h_OldPointersLst, h_NewPointersLst; -+ uint16_t keyIndex; -+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((grpId <= 7), E_INVALID_VALUE); -+ -+ if (grpId >= p_FmPcdCcTree->numOfGrps) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, -+ ("grpId you asked > numOfGroup of relevant tree")); -+ -+ if (index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup")); -+ -+ p_FmPcd = (t_FmPcd *)h_FmPcd; -+ -+ INIT_LIST(&h_OldPointersLst); -+ INIT_LIST(&h_NewPointersLst); -+ -+ keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry -+ + index); -+ -+ p_ModifyKeyParams = ModifyNodeCommonPart(p_FmPcdCcTree, keyIndex, -+ e_MODIFY_STATE_CHANGE, FALSE, -+ FALSE, TRUE); -+ if (!p_ModifyKeyParams) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ p_ModifyKeyParams->tree = TRUE; -+ -+ if (p_FmPcd->p_CcShadow -+ && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) -+ { -+ XX_Free(p_ModifyKeyParams); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = BuildNewNodeModifyNextEngine(p_FmPcd, p_FmPcdCcTree, keyIndex, -+ p_FmPcdCcNextEngineParams, -+ &h_OldPointersLst, &h_NewPointersLst, -+ p_ModifyKeyParams); -+ if (err) -+ { -+ XX_Free(p_ModifyKeyParams); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, -+ p_ModifyKeyParams, FALSE); -+ -+ if (p_FmPcd->p_CcShadow) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ -+ ReleaseLst(&h_OldPointersLst); -+ ReleaseLst(&h_NewPointersLst); -+ -+ return err; -+ -+} -+ -+t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, -+ uint16_t keyIndex) -+{ -+ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; -+ t_FmPcd *p_FmPcd; -+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; -+ t_List h_OldPointersLst, h_NewPointersLst; -+ bool useShadowStructs = FALSE; -+ t_Error err = E_OK; -+ -+ if (keyIndex >= p_CcNode->numOfKeys) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("impossible to remove key when numOfKeys <= keyIndex")); -+ -+ if (p_CcNode->h_FmPcd != h_FmPcd) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("handler to FmPcd is different from the handle provided at node initialization time")); -+ -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ -+ INIT_LIST(&h_OldPointersLst); -+ INIT_LIST(&h_NewPointersLst); -+ -+ p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, -+ e_MODIFY_STATE_REMOVE, TRUE, TRUE, -+ FALSE); -+ if (!p_ModifyKeyParams) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ if (p_CcNode->maxNumOfKeys) -+ { -+ if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) -+ { -+ XX_Free(p_ModifyKeyParams); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ useShadowStructs = TRUE; -+ } -+ -+ err = BuildNewNodeRemoveKey(p_CcNode, keyIndex, p_ModifyKeyParams); -+ if (err) -+ { -+ XX_Free(p_ModifyKeyParams); -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, -+ &h_OldPointersLst, -+ &h_NewPointersLst); -+ if (err) -+ { -+ ReleaseNewNodeCommonPart(p_ModifyKeyParams); -+ XX_Free(p_ModifyKeyParams); -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, -+ p_ModifyKeyParams, useShadowStructs); -+ -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ -+ ReleaseLst(&h_OldPointersLst); -+ ReleaseLst(&h_NewPointersLst); -+ -+ return err; -+} -+ -+t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, -+ uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key, -+ uint8_t *p_Mask) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; -+ t_FmPcd *p_FmPcd; -+ t_List h_OldPointersLst, h_NewPointersLst; -+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; -+ uint16_t tmpKeyIndex; -+ bool useShadowStructs = FALSE; -+ t_Error err = E_OK; -+ -+ if (keyIndex >= p_CcNode->numOfKeys) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("keyIndex > previously cleared last index + 1")); -+ -+ if (keySize != p_CcNode->userSizeOfExtraction) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("size for ModifyKey has to be the same as defined in SetNode")); -+ -+ if (p_CcNode->h_FmPcd != h_FmPcd) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("handler to FmPcd is different from the handle provided at node initialization time")); -+ -+ err = FindKeyIndex(h_FmPcdCcNode, keySize, p_Key, p_Mask, &tmpKeyIndex); -+ if (GET_ERROR_TYPE(err) != E_NOT_FOUND) -+ RETURN_ERROR( -+ MINOR, -+ E_ALREADY_EXISTS, -+ ("The received key and mask pair was already found in the match table of the provided node")); -+ -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ -+ INIT_LIST(&h_OldPointersLst); -+ INIT_LIST(&h_NewPointersLst); -+ -+ p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, -+ e_MODIFY_STATE_CHANGE, TRUE, TRUE, -+ FALSE); -+ if (!p_ModifyKeyParams) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ if (p_CcNode->maxNumOfKeys) -+ { -+ if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) -+ { -+ XX_Free(p_ModifyKeyParams); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ useShadowStructs = TRUE; -+ } -+ -+ err = BuildNewNodeModifyKey(p_CcNode, keyIndex, p_Key, p_Mask, -+ p_ModifyKeyParams); -+ if (err) -+ { -+ XX_Free(p_ModifyKeyParams); -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, -+ &h_OldPointersLst, -+ &h_NewPointersLst); -+ if (err) -+ { -+ ReleaseNewNodeCommonPart(p_ModifyKeyParams); -+ XX_Free(p_ModifyKeyParams); -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, -+ p_ModifyKeyParams, useShadowStructs); -+ -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ -+ ReleaseLst(&h_OldPointersLst); -+ ReleaseLst(&h_NewPointersLst); -+ -+ return err; -+} -+ -+t_Error FmPcdCcModifyMissNextEngineParamNode( -+ t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; -+ t_FmPcd *p_FmPcd; -+ t_List h_OldPointersLst, h_NewPointersLst; -+ uint16_t keyIndex; -+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_VALUE); -+ -+ keyIndex = p_CcNode->numOfKeys; -+ -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ -+ INIT_LIST(&h_OldPointersLst); -+ INIT_LIST(&h_NewPointersLst); -+ -+ p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, -+ e_MODIFY_STATE_CHANGE, FALSE, TRUE, -+ FALSE); -+ if (!p_ModifyKeyParams) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ if (p_CcNode->maxNumOfKeys -+ && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) -+ { -+ XX_Free(p_ModifyKeyParams); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex, -+ p_FmPcdCcNextEngineParams, -+ &h_OldPointersLst, &h_NewPointersLst, -+ p_ModifyKeyParams); -+ if (err) -+ { -+ XX_Free(p_ModifyKeyParams); -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, -+ p_ModifyKeyParams, FALSE); -+ -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ -+ ReleaseLst(&h_OldPointersLst); -+ ReleaseLst(&h_NewPointersLst); -+ -+ return err; -+} -+ -+t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, -+ uint16_t keyIndex, uint8_t keySize, -+ t_FmPcdCcKeyParams *p_FmPcdCcKeyParams) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; -+ t_FmPcd *p_FmPcd; -+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; -+ t_List h_OldPointersLst, h_NewPointersLst; -+ bool useShadowStructs = FALSE; -+ uint16_t tmpKeyIndex; -+ t_Error err = E_OK; -+ -+ if (keyIndex > p_CcNode->numOfKeys) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, -+ ("keyIndex > previously cleared last index + 1")); -+ -+ if (keySize != p_CcNode->userSizeOfExtraction) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("keySize has to be defined as it was defined in initialization step")); -+ -+ if (p_CcNode->h_FmPcd != h_FmPcd) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("handler to FmPcd is different from the handle provided at node initialization time")); -+ -+ if (p_CcNode->maxNumOfKeys) -+ { -+ if (p_CcNode->numOfKeys == p_CcNode->maxNumOfKeys) -+ RETURN_ERROR( -+ MAJOR, -+ E_FULL, -+ ("number of keys exceeds the maximal number of keys provided at node initialization time")); -+ } -+ else -+ if (p_CcNode->numOfKeys == FM_PCD_MAX_NUM_OF_KEYS) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("number of keys can not be larger than %d", FM_PCD_MAX_NUM_OF_KEYS)); -+ -+ err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key, -+ p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex); -+ if (GET_ERROR_TYPE(err) != E_NOT_FOUND) -+ RETURN_ERROR( -+ MAJOR, -+ E_ALREADY_EXISTS, -+ ("The received key and mask pair was already found in the match table of the provided node")); -+ -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ -+ INIT_LIST(&h_OldPointersLst); -+ INIT_LIST(&h_NewPointersLst); -+ -+ p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, -+ e_MODIFY_STATE_ADD, TRUE, TRUE, -+ FALSE); -+ if (!p_ModifyKeyParams) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ if (p_CcNode->maxNumOfKeys) -+ { -+ if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) -+ { -+ XX_Free(p_ModifyKeyParams); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ useShadowStructs = TRUE; -+ } -+ -+ err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex, -+ p_FmPcdCcKeyParams, -+ p_ModifyKeyParams, TRUE); -+ if (err) -+ { -+ ReleaseNewNodeCommonPart(p_ModifyKeyParams); -+ XX_Free(p_ModifyKeyParams); -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, -+ &h_OldPointersLst, -+ &h_NewPointersLst); -+ if (err) -+ { -+ ReleaseNewNodeCommonPart(p_ModifyKeyParams); -+ XX_Free(p_ModifyKeyParams); -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, -+ p_ModifyKeyParams, useShadowStructs); -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ -+ ReleaseLst(&h_OldPointersLst); -+ ReleaseLst(&h_NewPointersLst); -+ -+ return err; -+} -+ -+t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, -+ uint16_t keyIndex, uint8_t keySize, -+ t_FmPcdCcKeyParams *p_FmPcdCcKeyParams) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; -+ t_FmPcd *p_FmPcd; -+ t_List h_OldPointersLst, h_NewPointersLst; -+ t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams; -+ uint16_t tmpKeyIndex; -+ bool useShadowStructs = FALSE; -+ t_Error err = E_OK; -+ -+ if (keyIndex > p_CcNode->numOfKeys) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("keyIndex > previously cleared last index + 1")); -+ -+ if (keySize != p_CcNode->userSizeOfExtraction) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("keySize has to be defined as it was defined in initialization step")); -+ -+ if (p_CcNode->h_FmPcd != h_FmPcd) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("handler to FmPcd is different from the handle provided at node initialization time")); -+ -+ err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key, -+ p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex); -+ if (GET_ERROR_TYPE(err) != E_NOT_FOUND) -+ RETURN_ERROR( -+ MINOR, -+ E_ALREADY_EXISTS, -+ ("The received key and mask pair was already found in the match table of the provided node")); -+ -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ -+ INIT_LIST(&h_OldPointersLst); -+ INIT_LIST(&h_NewPointersLst); -+ -+ p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex, -+ e_MODIFY_STATE_CHANGE, TRUE, TRUE, -+ FALSE); -+ if (!p_ModifyKeyParams) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ if (p_CcNode->maxNumOfKeys) -+ { -+ if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) -+ { -+ XX_Free(p_ModifyKeyParams); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ useShadowStructs = TRUE; -+ } -+ -+ err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex, -+ p_FmPcdCcKeyParams, -+ p_ModifyKeyParams, FALSE); -+ if (err) -+ { -+ ReleaseNewNodeCommonPart(p_ModifyKeyParams); -+ XX_Free(p_ModifyKeyParams); -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams, -+ &h_OldPointersLst, -+ &h_NewPointersLst); -+ if (err) -+ { -+ ReleaseNewNodeCommonPart(p_ModifyKeyParams); -+ XX_Free(p_ModifyKeyParams); -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst, -+ p_ModifyKeyParams, useShadowStructs); -+ -+ if (p_CcNode->maxNumOfKeys) -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ -+ ReleaseLst(&h_OldPointersLst); -+ ReleaseLst(&h_NewPointersLst); -+ -+ return err; -+} -+ -+uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, -+ t_Handle h_Pointer) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ t_CcNodeInformation *p_CcNodeInfo; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, -+ (uint32_t)ILLEGAL_BASE); -+ -+ p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer); -+ -+ return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode) -+ - p_FmPcd->physicalMuramBase); -+} -+ -+t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId, -+ uint32_t *p_GrpBits, uint8_t *p_GrpBase) -+{ -+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); -+ -+ if (grpId >= p_FmPcdCcTree->numOfGrps) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, -+ ("grpId you asked > numOfGroup of relevant tree")); -+ -+ *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask; -+ *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry; -+ -+ return E_OK; -+} -+ -+t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, -+ t_Handle h_FmPcdCcTree, uint32_t *p_Offset, -+ t_Handle h_FmPort) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); -+ -+ /* this routine must be protected by the calling routine by locking all PCD modules! */ -+ -+ err = CcUpdateParams(h_FmPcd, h_PcdParams, h_FmPort, h_FmPcdCcTree, TRUE); -+ -+ if (err == E_OK) -+ UpdateCcRootOwner(p_FmPcdCcTree, TRUE); -+ -+ *p_Offset = (uint32_t)(XX_VirtToPhys( -+ UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr)) -+ - p_FmPcd->physicalMuramBase); -+ -+ return err; -+} -+ -+t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree) -+{ -+ t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree; -+ -+ /* this routine must be protected by the calling routine by locking all PCD modules! */ -+ -+ UNUSED(h_FmPcd); -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE); -+ -+ UpdateCcRootOwner(p_FmPcdCcTree, FALSE); -+ -+ return E_OK; -+} -+ -+t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, -+ t_List *p_List) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode; -+ t_List *p_Pos, *p_Tmp; -+ t_CcNodeInformation *p_CcNodeInfo, nodeInfo; -+ uint32_t intFlags; -+ t_Error err = E_OK; -+ -+ intFlags = FmPcdLock(h_FmPcd); -+ -+ LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst) -+ { -+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); -+ ASSERT_COND(p_CcNodeInfo->h_CcNode); -+ -+ err = CcRootTryLock(p_CcNodeInfo->h_CcNode); -+ -+ if (err) -+ { -+ LIST_FOR_EACH(p_Tmp, &p_CcNode->ccTreesLst) -+ { -+ if (p_Tmp == p_Pos) -+ break; -+ -+ CcRootReleaseLock(p_CcNodeInfo->h_CcNode); -+ } -+ break; -+ } -+ -+ memset(&nodeInfo, 0, sizeof(t_CcNodeInformation)); -+ nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode; -+ EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo, NULL); -+ } -+ -+ FmPcdUnlock(h_FmPcd, intFlags); -+ CORE_MemoryBarrier(); -+ -+ return err; -+} -+ -+void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List) -+{ -+ t_List *p_Pos; -+ t_CcNodeInformation *p_CcNodeInfo; -+ t_Handle h_FmPcdCcTree; -+ uint32_t intFlags; -+ -+ intFlags = FmPcdLock(h_FmPcd); -+ -+ LIST_FOR_EACH(p_Pos, p_List) -+ { -+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); -+ h_FmPcdCcTree = p_CcNodeInfo->h_CcNode; -+ CcRootReleaseLock(h_FmPcdCcTree); -+ } -+ -+ ReleaseLst(p_List); -+ -+ FmPcdUnlock(h_FmPcd, intFlags); -+ CORE_MemoryBarrier(); -+} -+ -+t_Error FmPcdUpdateCcShadow(t_FmPcd *p_FmPcd, uint32_t size, uint32_t align) -+{ -+ uint32_t intFlags; -+ uint32_t newSize = 0, newAlign = 0; -+ bool allocFail = FALSE; -+ -+ ASSERT_COND(p_FmPcd); -+ -+ if (!size) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size must be larger then 0")); -+ -+ if (!POWER_OF_2(align)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("alignment must be power of 2")); -+ -+ newSize = p_FmPcd->ccShadowSize; -+ newAlign = p_FmPcd->ccShadowAlign; -+ -+ /* Check if current shadow is large enough to hold the requested size */ -+ if (size > p_FmPcd->ccShadowSize) -+ newSize = size; -+ -+ /* Check if current shadow matches the requested alignment */ -+ if (align > p_FmPcd->ccShadowAlign) -+ newAlign = align; -+ -+ /* If a bigger shadow size or bigger shadow alignment are required, -+ a new shadow will be allocated */ -+ if ((newSize != p_FmPcd->ccShadowSize) -+ || (newAlign != p_FmPcd->ccShadowAlign)) -+ { -+ intFlags = FmPcdLock(p_FmPcd); -+ -+ if (p_FmPcd->p_CcShadow) -+ { -+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->p_CcShadow); -+ p_FmPcd->ccShadowSize = 0; -+ p_FmPcd->ccShadowAlign = 0; -+ } -+ -+ p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd), -+ newSize, newAlign); -+ if (!p_FmPcd->p_CcShadow) -+ { -+ allocFail = TRUE; -+ -+ /* If new shadow size allocation failed, -+ re-allocate with previous parameters */ -+ p_FmPcd->p_CcShadow = FM_MURAM_AllocMem( -+ FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->ccShadowSize, -+ p_FmPcd->ccShadowAlign); -+ } -+ -+ FmPcdUnlock(p_FmPcd, intFlags); -+ -+ if (allocFail) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for CC Shadow memory")); -+ -+ p_FmPcd->ccShadowSize = newSize; -+ p_FmPcd->ccShadowAlign = newAlign; -+ } -+ -+ return E_OK; -+} -+ -+#if (DPAA_VERSION >= 11) -+void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node, -+ t_Handle h_ReplicGroup, -+ t_List *p_AdTables, -+ uint32_t *p_NumOfAdTables) -+{ -+ t_FmPcdCcNode *p_CurrentNode = (t_FmPcdCcNode *)h_Node; -+ int i = 0; -+ void * p_AdTable; -+ t_CcNodeInformation ccNodeInfo; -+ -+ ASSERT_COND(h_Node); -+ *p_NumOfAdTables = 0; -+ -+ /* search in the current node which exact index points on this current replicator group for getting AD */ -+ for (i = 0; i < p_CurrentNode->numOfKeys + 1; i++) -+ { -+ if ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine -+ == e_FM_PCD_FR) -+ && ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic -+ == (t_Handle)h_ReplicGroup))) -+ { -+ /* save the current ad table in the list */ -+ /* this entry uses the input replicator group */ -+ p_AdTable = -+ PTR_MOVE(p_CurrentNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE); -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ ccNodeInfo.h_CcNode = p_AdTable; -+ EnqueueNodeInfoToRelevantLst(p_AdTables, &ccNodeInfo, NULL); -+ (*p_NumOfAdTables)++; -+ } -+ } -+ -+ ASSERT_COND(i != p_CurrentNode->numOfKeys); -+} -+#endif /* (DPAA_VERSION >= 11) */ -+/*********************** End of inter-module routines ************************/ -+ -+/****************************************/ -+/* API Init unit functions */ -+/****************************************/ -+ -+t_Handle FM_PCD_CcRootBuild(t_Handle h_FmPcd, -+ t_FmPcdCcTreeParams *p_PcdGroupsParam) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ t_Error err = E_OK; -+ int i = 0, j = 0, k = 0; -+ t_FmPcdCcTree *p_FmPcdCcTree; -+ uint8_t numOfEntries; -+ t_Handle p_CcTreeTmp; -+ t_FmPcdCcGrpParams *p_FmPcdCcGroupParams; -+ t_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams; -+ t_NetEnvParams netEnvParams; -+ uint8_t lastOne = 0; -+ uint32_t requiredAction = 0; -+ t_FmPcdCcNode *p_FmPcdCcNextNode; -+ t_CcNodeInformation ccNodeInfo, *p_CcInformation; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam, E_INVALID_HANDLE, NULL); -+ -+ if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS)); -+ return NULL; -+ } -+ -+ p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree)); -+ if (!p_FmPcdCcTree) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure")); -+ return NULL; -+ } -+ memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree)); -+ p_FmPcdCcTree->h_FmPcd = h_FmPcd; -+ -+ p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc( -+ FM_PCD_MAX_NUM_OF_CC_GROUPS -+ * sizeof(t_FmPcdCcKeyAndNextEngineParams)); -+ memset(p_Params, -+ 0, -+ FM_PCD_MAX_NUM_OF_CC_GROUPS -+ * sizeof(t_FmPcdCcKeyAndNextEngineParams)); -+ -+ INIT_LIST(&p_FmPcdCcTree->fmPortsLst); -+ -+#ifdef FM_CAPWAP_SUPPORT -+ if ((p_PcdGroupsParam->numOfGrps == 1) && -+ (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) && -+ (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) && -+ p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode && -+ IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode)) -+ { -+ p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild(); -+ if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip) -+ { -+ DeleteTree(p_FmPcdCcTree,p_FmPcd); -+ XX_Free(p_Params); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ return NULL; -+ } -+ } -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+ numOfEntries = 0; -+ p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv); -+ -+ for (i = 0; i < p_PcdGroupsParam->numOfGrps; i++) -+ { -+ p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i]; -+ -+ if (p_FmPcdCcGroupParams->numOfDistinctionUnits -+ > FM_PCD_MAX_NUM_OF_CC_UNITS) -+ { -+ DeleteTree(p_FmPcdCcTree, p_FmPcd); -+ XX_Free(p_Params); -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS)); -+ return NULL; -+ } -+ -+ p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries; -+ p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup = (uint8_t)(0x01 -+ << p_FmPcdCcGroupParams->numOfDistinctionUnits); -+ numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; -+ if (numOfEntries > FM_PCD_MAX_NUM_OF_CC_GROUPS) -+ { -+ DeleteTree(p_FmPcdCcTree, p_FmPcd); -+ XX_Free(p_Params); -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS)); -+ return NULL; -+ } -+ -+ if (lastOne) -+ { -+ if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne) -+ { -+ DeleteTree(p_FmPcdCcTree, p_FmPcd); -+ XX_Free(p_Params); -+ REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order")); -+ return NULL; -+ } -+ } -+ -+ lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; -+ -+ netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId; -+ netEnvParams.numOfDistinctionUnits = -+ p_FmPcdCcGroupParams->numOfDistinctionUnits; -+ -+ memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds, -+ (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits); -+ -+ err = PcdGetUnitsVector(p_FmPcd, &netEnvParams); -+ if (err) -+ { -+ DeleteTree(p_FmPcdCcTree, p_FmPcd); -+ XX_Free(p_Params); -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return NULL; -+ } -+ -+ p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector; -+ for (j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup; -+ j++) -+ { -+ err = ValidateNextEngineParams( -+ h_FmPcd, -+ &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], -+ e_FM_PCD_CC_STATS_MODE_NONE); -+ if (err) -+ { -+ DeleteTree(p_FmPcdCcTree, p_FmPcd); -+ XX_Free(p_Params); -+ REPORT_ERROR(MAJOR, err, (NO_MSG)); -+ return NULL; -+ } -+ -+ if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip) -+ { -+ err = FmPcdManipCheckParamsForCcNextEngine( -+ &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], -+ &requiredAction); -+ if (err) -+ { -+ DeleteTree(p_FmPcdCcTree, p_FmPcd); -+ XX_Free(p_Params); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ return NULL; -+ } -+ } -+ p_KeyAndNextEngineParams = p_Params + k; -+ -+ memcpy(&p_KeyAndNextEngineParams->nextEngineParams, -+ &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j], -+ sizeof(t_FmPcdCcNextEngineParams)); -+ -+ if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ && p_KeyAndNextEngineParams->nextEngineParams.h_Manip) -+ { -+ err = -+ AllocAndFillAdForContLookupManip( -+ p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode); -+ if (err) -+ { -+ DeleteTree(p_FmPcdCcTree, p_FmPcd); -+ XX_Free(p_Params); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree")); -+ return NULL; -+ } -+ } -+ -+ requiredAction |= UPDATE_CC_WITH_TREE; -+ p_KeyAndNextEngineParams->requiredAction = requiredAction; -+ -+ k++; -+ } -+ } -+ -+ p_FmPcdCcTree->numOfEntries = (uint8_t)k; -+ p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps; -+ -+ p_FmPcdCcTree->ccTreeBaseAddr = -+ PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd), -+ (uint32_t)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE), -+ FM_PCD_CC_TREE_ADDR_ALIGN)); -+ if (!p_FmPcdCcTree->ccTreeBaseAddr) -+ { -+ DeleteTree(p_FmPcdCcTree, p_FmPcd); -+ XX_Free(p_Params); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree")); -+ return NULL; -+ } -+ MemSet8( -+ UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0, -+ (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE)); -+ -+ p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); -+ -+ for (i = 0; i < numOfEntries; i++) -+ { -+ p_KeyAndNextEngineParams = p_Params + i; -+ -+ NextStepAd(p_CcTreeTmp, NULL, -+ &p_KeyAndNextEngineParams->nextEngineParams, p_FmPcd); -+ -+ p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i], -+ p_KeyAndNextEngineParams, -+ sizeof(t_FmPcdCcKeyAndNextEngineParams)); -+ -+ if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ { -+ p_FmPcdCcNextNode = -+ (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; -+ p_CcInformation = FindNodeInfoInReleventLst( -+ &p_FmPcdCcNextNode->ccTreeIdLst, (t_Handle)p_FmPcdCcTree, -+ p_FmPcdCcNextNode->h_Spinlock); -+ -+ if (!p_CcInformation) -+ { -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree; -+ ccNodeInfo.index = 1; -+ EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst, -+ &ccNodeInfo, -+ p_FmPcdCcNextNode->h_Spinlock); -+ } -+ else -+ p_CcInformation->index++; -+ } -+ } -+ -+ FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId); -+ p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr); -+ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ FM_PCD_CcRootDelete(p_FmPcdCcTree); -+ XX_Free(p_Params); -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return NULL; -+ } -+ -+ for (i = 0; i < numOfEntries; i++) -+ { -+ if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction) -+ { -+ err = SetRequiredAction( -+ h_FmPcd, -+ p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction, -+ &p_FmPcdCcTree->keyAndNextEngineParams[i], p_CcTreeTmp, 1, -+ p_FmPcdCcTree); -+ if (err) -+ { -+ FmPcdLockUnlockAll(p_FmPcd); -+ FM_PCD_CcRootDelete(p_FmPcdCcTree); -+ XX_Free(p_Params); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); -+ return NULL; -+ } -+ p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE); -+ } -+ } -+ -+ FmPcdLockUnlockAll(p_FmPcd); -+ p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd); -+ if (!p_FmPcdCcTree->p_Lock) -+ { -+ FM_PCD_CcRootDelete(p_FmPcdCcTree); -+ XX_Free(p_Params); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock")); -+ return NULL; -+ } -+ -+ XX_Free(p_Params); -+ -+ return p_FmPcdCcTree; -+} -+ -+t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree; -+ int i = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE); -+ p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ -+ FmPcdDecNetEnvOwners(p_FmPcd, p_CcTree->netEnvId); -+ -+ if (p_CcTree->owners) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_SELECTION, -+ ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree")); -+ -+ /* Delete ip-reassembly schemes if exist */ -+ if (p_CcTree->h_IpReassemblyManip) -+ { -+ FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip); -+ FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE); -+ } -+ -+ /* Delete capwap-reassembly schemes if exist */ -+ if (p_CcTree->h_CapwapReassemblyManip) -+ { -+ FmPcdManipDeleteCapwapReassmSchemes(p_CcTree->h_CapwapReassemblyManip); -+ FmPcdManipUpdateOwner(p_CcTree->h_CapwapReassemblyManip, FALSE); -+ } -+ -+ for (i = 0; i < p_CcTree->numOfEntries; i++) -+ { -+ if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ UpdateNodeOwner( -+ p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode, -+ FALSE); -+ -+ if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip) -+ FmPcdManipUpdateOwner( -+ p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip, -+ FALSE); -+ -+#ifdef FM_CAPWAP_SUPPORT -+ if ((p_CcTree->numOfGrps == 1) && -+ (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) && -+ (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) && -+ p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode && -+ IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode)) -+ { -+ if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK) -+ return E_INVALID_STATE; -+ } -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+#if (DPAA_VERSION >= 11) -+ if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine -+ == e_FM_PCD_FR) -+ && (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic)) -+ FrmReplicGroupUpdateOwner( -+ p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic, -+ FALSE); -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+ if (p_CcTree->p_Lock) -+ FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock); -+ -+ DeleteTree(p_CcTree, p_FmPcd); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_CcRootModifyNextEngine( -+ t_Handle h_CcTree, uint8_t grpId, uint8_t index, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE); -+ p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, p_CcTree, grpId, index, -+ p_FmPcdCcNextEngineParams); -+ FmPcdLockUnlockAll(p_FmPcd); -+ -+ if (err) -+ { -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ return E_OK; -+} -+ -+t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, -+ t_FmPcdCcNodeParams *p_CcNodeParam) -+{ -+ t_FmPcdCcNode *p_CcNode; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL); -+ -+ p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode)); -+ if (!p_CcNode) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); -+ return NULL; -+ } -+ memset(p_CcNode, 0, sizeof(t_FmPcdCcNode)); -+ -+ err = MatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam); -+ -+ switch(GET_ERROR_TYPE(err) -+) { -+ case E_OK: -+ break; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return NULL; -+ -+ default: -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return NULL; -+ } -+ -+ return p_CcNode; -+} -+ -+t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ int i = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_CcNode->h_FmPcd, E_INVALID_HANDLE); -+ -+ if (p_CcNode->owners) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("This node cannot be removed because it is occupied; first unbind this node")); -+ -+ for (i = 0; i < p_CcNode->numOfKeys; i++) -+ if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ UpdateNodeOwner( -+ p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode, -+ FALSE); -+ -+ if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ UpdateNodeOwner( -+ p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode, -+ FALSE); -+ -+ /* Handle also Miss entry */ -+ for (i = 0; i < p_CcNode->numOfKeys + 1; i++) -+ { -+ if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip) -+ FmPcdManipUpdateOwner( -+ p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip, -+ FALSE); -+ -+#if (DPAA_VERSION >= 11) -+ if ((p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine -+ == e_FM_PCD_FR) -+ && (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic)) -+ { -+ FrmReplicGroupUpdateOwner( -+ p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic, -+ FALSE); -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+ DeleteNode(p_CcNode); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, uint16_t keyIndex, -+ uint8_t keySize, -+ t_FmPcdCcKeyParams *p_KeyParams) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ if (keyIndex == FM_PCD_LAST_KEY_INDEX) -+ keyIndex = p_CcNode->numOfKeys; -+ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FmPcdCcAddKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_KeyParams); -+ -+ FmPcdLockUnlockAll(p_FmPcd); -+ -+ switch(GET_ERROR_TYPE(err) -+) { -+ case E_OK: -+ return E_OK; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return ERROR_CODE(E_BUSY); -+ -+ default: -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+} -+ -+t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex); -+ -+ FmPcdLockUnlockAll(p_FmPcd); -+ -+ switch(GET_ERROR_TYPE(err) -+) { -+ case E_OK: -+ return E_OK; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return ERROR_CODE(E_BUSY); -+ -+ default: -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, uint16_t keyIndex, -+ uint8_t keySize, uint8_t *p_Key, -+ uint8_t *p_Mask) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_Key, p_Mask); -+ -+ FmPcdLockUnlockAll(p_FmPcd); -+ -+ switch(GET_ERROR_TYPE(err) -+) { -+ case E_OK: -+ return E_OK; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return ERROR_CODE(E_BUSY); -+ -+ default: -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+} -+ -+t_Error FM_PCD_MatchTableModifyNextEngine( -+ t_Handle h_CcNode, uint16_t keyIndex, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex, -+ p_FmPcdCcNextEngineParams); -+ -+ FmPcdLockUnlockAll(p_FmPcd); -+ -+ switch(GET_ERROR_TYPE(err) -+) { -+ case E_OK: -+ return E_OK; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return ERROR_CODE(E_BUSY); -+ -+ default: -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+} -+ -+t_Error FM_PCD_MatchTableModifyMissNextEngine( -+ t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FmPcdCcModifyMissNextEngineParamNode(p_FmPcd, p_CcNode, -+ p_FmPcdCcNextEngineParams); -+ -+ FmPcdLockUnlockAll(p_FmPcd); -+ -+ switch(GET_ERROR_TYPE(err) -+) { -+ case E_OK: -+ return E_OK; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return ERROR_CODE(E_BUSY); -+ -+ default: -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+} -+ -+t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode, -+ uint16_t keyIndex, -+ uint8_t keySize, -+ t_FmPcdCcKeyParams *p_KeyParams) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, p_CcNode, keyIndex, keySize, -+ p_KeyParams); -+ -+ FmPcdLockUnlockAll(p_FmPcd); -+ -+ switch(GET_ERROR_TYPE(err) -+) { -+ case E_OK: -+ return E_OK; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return ERROR_CODE(E_BUSY); -+ -+ default: -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+} -+ -+t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, uint8_t keySize, -+ uint8_t *p_Key, uint8_t *p_Mask) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ uint16_t keyIndex; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); -+ if (GET_ERROR_TYPE(err) != E_OK) -+ { -+ FmPcdLockUnlockAll(p_FmPcd); -+ RETURN_ERROR( -+ MAJOR, -+ err, -+ ("The received key and mask pair was not found in the match table of the provided node")); -+ } -+ -+ err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex); -+ -+ FmPcdLockUnlockAll(p_FmPcd); -+ -+ switch(GET_ERROR_TYPE(err) -+) { -+ case E_OK: -+ return E_OK; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return ERROR_CODE(E_BUSY); -+ -+ default: -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+} -+ -+t_Error FM_PCD_MatchTableFindNModifyNextEngine( -+ t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ uint16_t keyIndex; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); -+ if (GET_ERROR_TYPE(err) != E_OK) -+ { -+ FmPcdLockUnlockAll(p_FmPcd); -+ RETURN_ERROR( -+ MAJOR, -+ err, -+ ("The received key and mask pair was not found in the match table of the provided node")); -+ } -+ -+ err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex, -+ p_FmPcdCcNextEngineParams); -+ -+ FmPcdLockUnlockAll(p_FmPcd); -+ -+ switch(GET_ERROR_TYPE(err) -+) { -+ case E_OK: -+ return E_OK; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return ERROR_CODE(E_BUSY); -+ -+ default: -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+} -+ -+t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine( -+ t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, -+ t_FmPcdCcKeyParams *p_KeyParams) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ uint16_t keyIndex; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); -+ if (GET_ERROR_TYPE(err) != E_OK) -+ { -+ FmPcdLockUnlockAll(p_FmPcd); -+ RETURN_ERROR( -+ MAJOR, -+ err, -+ ("The received key and mask pair was not found in the match table of the provided node")); -+ } -+ -+ err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, h_CcNode, keyIndex, keySize, -+ p_KeyParams); -+ -+ FmPcdLockUnlockAll(p_FmPcd); -+ -+ switch(GET_ERROR_TYPE(err) -+) { -+ case E_OK: -+ return E_OK; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return ERROR_CODE(E_BUSY); -+ -+ default: -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+} -+ -+t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, uint8_t keySize, -+ uint8_t *p_Key, uint8_t *p_Mask, -+ uint8_t *p_NewKey, uint8_t *p_NewMask) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ t_List h_List; -+ uint16_t keyIndex; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_NewKey, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ INIT_LIST(&h_List); -+ -+ err = FmPcdCcNodeTreeTryLock(p_FmPcd, p_CcNode, &h_List); -+ if (err) -+ { -+ DBG(TRACE, ("Node's trees lock failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); -+ if (GET_ERROR_TYPE(err) != E_OK) -+ { -+ FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List); -+ RETURN_ERROR(MAJOR, err, -+ ("The received key and mask pair was not found in the " -+ "match table of the provided node")); -+ } -+ -+ err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_NewKey, -+ p_NewMask); -+ -+ FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List); -+ -+ switch(GET_ERROR_TYPE(err) -+) { -+ case E_OK: -+ return E_OK; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return ERROR_CODE(E_BUSY); -+ -+ default: -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+} -+ -+t_Error FM_PCD_MatchTableGetNextEngine( -+ t_Handle h_CcNode, uint16_t keyIndex, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ -+ SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); -+ -+ if (keyIndex >= p_CcNode->numOfKeys) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("keyIndex exceeds current number of keys")); -+ -+ if (keyIndex > (FM_PCD_MAX_NUM_OF_KEYS - 1)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("keyIndex can not be larger than %d", (FM_PCD_MAX_NUM_OF_KEYS - 1))); -+ -+ memcpy(p_FmPcdCcNextEngineParams, -+ &p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams, -+ sizeof(t_FmPcdCcNextEngineParams)); -+ -+ return E_OK; -+} -+ -+ -+uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ uint32_t *p_StatsCounters, frameCount; -+ uint32_t intFlags; -+ -+ SANITY_CHECK_RETURN_VALUE(p_CcNode, E_INVALID_HANDLE, 0); -+ -+ if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table")); -+ return 0; -+ } -+ -+ if ((p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_FRAME) -+ && (p_CcNode->statisticsMode -+ != e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME)) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Frame count is not supported in the statistics mode of this match table")); -+ return 0; -+ } -+ -+ intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); -+ -+ if (keyIndex >= p_CcNode->numOfKeys) -+ { -+ XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table")); -+ return 0; -+ } -+ -+ if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj) -+ { -+ XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key")); -+ return 0; -+ } -+ -+ p_StatsCounters = -+ p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters; -+ ASSERT_COND(p_StatsCounters); -+ -+ /* The first counter is byte counter, so we need to advance to the next counter */ -+ frameCount = GET_UINT32(*(uint32_t *)(PTR_MOVE(p_StatsCounters, -+ FM_PCD_CC_STATS_COUNTER_SIZE))); -+ -+ XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); -+ -+ return frameCount; -+} -+ -+t_Error FM_PCD_MatchTableGetKeyStatistics( -+ t_Handle h_CcNode, uint16_t keyIndex, -+ t_FmPcdCcKeyStatistics *p_KeyStatistics) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ uint32_t intFlags; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER); -+ -+ intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); -+ -+ if (keyIndex >= p_CcNode->numOfKeys) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("The provided keyIndex exceeds the number of keys in this match table")); -+ -+ err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics); -+ -+ XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_MatchTableGetMissStatistics( -+ t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_MissStatistics) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ uint32_t intFlags; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER); -+ -+ intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); -+ -+ err = MatchTableGetKeyStatistics(p_CcNode, p_CcNode->numOfKeys, -+ p_MissStatistics); -+ -+ XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_MatchTableFindNGetKeyStatistics( -+ t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask, -+ t_FmPcdCcKeyStatistics *p_KeyStatistics) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ uint16_t keyIndex; -+ uint32_t intFlags; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER); -+ -+ intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock); -+ -+ err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex); -+ if (GET_ERROR_TYPE(err) != E_OK) -+ { -+ XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); -+ RETURN_ERROR(MAJOR, err, -+ ("The received key and mask pair was not found in the " -+ "match table of the provided node")); -+ } -+ -+ ASSERT_COND(keyIndex < p_CcNode->numOfKeys); -+ -+ err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics); -+ -+ XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode, -+ uint8_t keySize, uint8_t *p_Key, -+ uint8_t hashShift, -+ t_Handle *p_CcNodeBucketHandle, -+ uint8_t *p_BucketIndex, -+ uint16_t *p_LastIndex) -+{ -+ t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode; -+ uint16_t glblMask; -+ uint64_t crc64 = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR( -+ p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED, -+ E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_CcNodeBucketHandle, E_NULL_POINTER); -+ -+ memcpy(&glblMask, PTR_MOVE(p_CcNode->p_GlblMask, 2), 2); -+ be16_to_cpus(&glblMask); -+ -+ crc64 = crc64_init(); -+ crc64 = crc64_compute(p_Key, keySize, crc64); -+ crc64 >>= hashShift; -+ -+ *p_BucketIndex = (uint8_t)(((crc64 >> (8 * (6 - p_CcNode->userOffset))) -+ & glblMask) >> 4); -+ if (*p_BucketIndex >= p_CcNode->numOfKeys) -+ RETURN_ERROR(MINOR, E_NOT_IN_RANGE, ("bucket index!")); -+ -+ *p_CcNodeBucketHandle = -+ p_CcNode->keyAndNextEngineParams[*p_BucketIndex].nextEngineParams.params.ccParams.h_CcNode; -+ if (!*p_CcNodeBucketHandle) -+ RETURN_ERROR(MINOR, E_NOT_FOUND, ("bucket!")); -+ -+ *p_LastIndex = ((t_FmPcdCcNode *)*p_CcNodeBucketHandle)->numOfKeys; -+ -+ return E_OK; -+} -+ -+t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param) -+{ -+ t_FmPcdCcNode *p_CcNodeHashTbl; -+ t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam; -+ t_FmPcdCcNode *p_CcNode; -+ t_Handle h_MissStatsCounters = NULL; -+ t_FmPcdCcKeyParams *p_HashKeyParams; -+ int i; -+ uint16_t numOfSets, numOfWays, countMask, onesCount = 0; -+ bool statsEnForMiss = FALSE; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL); -+ -+ if (p_Param->maxNumOfKeys == 0) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Max number of keys must be higher then 0")); -+ return NULL; -+ } -+ -+ if (p_Param->hashResMask == 0) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Hash result mask must differ from 0")); -+ return NULL; -+ } -+ -+ /*Fix: QorIQ SDK / QSDK-2131*/ -+ if (p_Param->ccNextEngineParamsForMiss.nextEngine == e_FM_PCD_INVALID) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Next PCD Engine for on-miss entry is invalid. On-miss entry is always required. You can use e_FM_PCD_DONE.")); -+ return NULL; -+ } -+ -+#if (DPAA_VERSION >= 11) -+ if (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_RMON) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("RMON statistics mode is not supported for hash table")); -+ return NULL; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ p_ExactMatchCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc( -+ sizeof(t_FmPcdCcNodeParams)); -+ if (!p_ExactMatchCcNodeParam) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_ExactMatchCcNodeParam")); -+ return NULL; -+ } -+ memset(p_ExactMatchCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams)); -+ -+ p_IndxHashCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc( -+ sizeof(t_FmPcdCcNodeParams)); -+ if (!p_IndxHashCcNodeParam) -+ { -+ XX_Free(p_ExactMatchCcNodeParam); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_IndxHashCcNodeParam")); -+ return NULL; -+ } -+ memset(p_IndxHashCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams)); -+ -+ /* Calculate number of sets and number of ways of the hash table */ -+ countMask = (uint16_t)(p_Param->hashResMask >> 4); -+ while (countMask) -+ { -+ onesCount++; -+ countMask = (uint16_t)(countMask >> 1); -+ } -+ -+ numOfSets = (uint16_t)(1 << onesCount); -+ numOfWays = (uint16_t)DIV_CEIL(p_Param->maxNumOfKeys, numOfSets); -+ -+ if (p_Param->maxNumOfKeys % numOfSets) -+ DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up")); -+ -+ if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME) -+ || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME)) -+ { -+ /* Allocating a statistics counters table that will be used by all -+ 'miss' entries of the hash table */ -+ h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem( -+ FmPcdGetMuramHandle(h_FmPcd), 2 * FM_PCD_CC_STATS_COUNTER_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!h_MissStatsCounters) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss")); -+ XX_Free(p_IndxHashCcNodeParam); -+ XX_Free(p_ExactMatchCcNodeParam); -+ return NULL; -+ } -+ memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); -+ -+ /* Always enable statistics for 'miss', so that a statistics AD will be -+ initialized from the start. We'll store the requested 'statistics enable' -+ value and it will be used when statistics are read by the user. */ -+ statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn; -+ p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE; -+ } -+ -+ /* Building exact-match node params, will be used to create the hash buckets */ -+ p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR; -+ -+ p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.src = -+ e_FM_PCD_EXTRACT_FROM_KEY; -+ p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.action = -+ e_FM_PCD_ACTION_EXACT_MATCH; -+ p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.offset = 0; -+ p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.size = -+ p_Param->matchKeySize; -+ -+ p_ExactMatchCcNodeParam->keysParams.maxNumOfKeys = numOfWays; -+ p_ExactMatchCcNodeParam->keysParams.maskSupport = FALSE; -+ p_ExactMatchCcNodeParam->keysParams.statisticsMode = -+ p_Param->statisticsMode; -+ p_ExactMatchCcNodeParam->keysParams.numOfKeys = 0; -+ p_ExactMatchCcNodeParam->keysParams.keySize = p_Param->matchKeySize; -+ p_ExactMatchCcNodeParam->keysParams.ccNextEngineParamsForMiss = -+ p_Param->ccNextEngineParamsForMiss; -+ -+ p_HashKeyParams = p_IndxHashCcNodeParam->keysParams.keyParams; -+ -+ for (i = 0; i < numOfSets; i++) -+ { -+ /* Each exact-match node will be marked as a 'bucket' and provided with -+ a pointer to statistics counters, to be used for 'miss' entry -+ statistics */ -+ p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode)); -+ if (!p_CcNode) -+ break; -+ memset(p_CcNode, 0, sizeof(t_FmPcdCcNode)); -+ -+ p_CcNode->isHashBucket = TRUE; -+ p_CcNode->h_MissStatsCounters = h_MissStatsCounters; -+ -+ err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam); -+ if (err) -+ break; -+ -+ p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC; -+ p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE; -+ p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode = -+ p_CcNode; -+ } -+ -+ if (i < numOfSets) -+ { -+ for (i = i - 1; i >= 0; i--) -+ FM_PCD_MatchTableDelete( -+ p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode); -+ -+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters); -+ -+ REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG); -+ XX_Free(p_IndxHashCcNodeParam); -+ XX_Free(p_ExactMatchCcNodeParam); -+ return NULL; -+ } -+ -+ /* Creating indexed-hash CC node */ -+ p_IndxHashCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR; -+ p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.src = -+ e_FM_PCD_EXTRACT_FROM_HASH; -+ p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.action = -+ e_FM_PCD_ACTION_INDEXED_LOOKUP; -+ p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.icIndxMask = -+ p_Param->hashResMask; -+ p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.offset = -+ p_Param->hashShift; -+ p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.size = 2; -+ -+ p_IndxHashCcNodeParam->keysParams.maxNumOfKeys = numOfSets; -+ p_IndxHashCcNodeParam->keysParams.maskSupport = FALSE; -+ p_IndxHashCcNodeParam->keysParams.statisticsMode = -+ e_FM_PCD_CC_STATS_MODE_NONE; -+ /* Number of keys of this node is number of sets of the hash */ -+ p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets; -+ p_IndxHashCcNodeParam->keysParams.keySize = 2; -+ -+ p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam); -+ -+ if (p_CcNodeHashTbl) -+ { -+ p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift; -+ -+ /* Storing the allocated counters for buckets 'miss' in the hash table -+ and if statistics for miss were enabled. */ -+ p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters; -+ p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss; -+ } -+ -+ XX_Free(p_IndxHashCcNodeParam); -+ XX_Free(p_ExactMatchCcNodeParam); -+ -+ return p_CcNodeHashTbl; -+} -+ -+t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl) -+{ -+ t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; -+ t_Handle h_FmPcd; -+ t_Handle *p_HashBuckets, h_MissStatsCounters; -+ uint16_t i, numOfBuckets; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); -+ -+ /* Store all hash buckets before the hash is freed */ -+ numOfBuckets = p_HashTbl->numOfKeys; -+ -+ p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle)); -+ if (!p_HashBuckets) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ -+ for (i = 0; i < numOfBuckets; i++) -+ p_HashBuckets[i] = -+ p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; -+ -+ h_FmPcd = p_HashTbl->h_FmPcd; -+ h_MissStatsCounters = p_HashTbl->h_MissStatsCounters; -+ -+ /* Free the hash */ -+ err = FM_PCD_MatchTableDelete(p_HashTbl); -+ -+ /* Free each hash bucket */ -+ for (i = 0; i < numOfBuckets; i++) -+ err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]); -+ -+ XX_Free(p_HashBuckets); -+ -+ /* Free statistics counters for 'miss', if these were allocated */ -+ if (h_MissStatsCounters) -+ FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters); -+ -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, uint8_t keySize, -+ t_FmPcdCcKeyParams *p_KeyParams) -+{ -+ t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; -+ t_Handle h_HashBucket; -+ uint8_t bucketIndex; -+ uint16_t lastIndex; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_KeyParams->p_Key, E_NULL_POINTER); -+ -+ if (p_KeyParams->p_Mask) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("Keys masks not supported for hash table")); -+ -+ err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, -+ p_KeyParams->p_Key, -+ p_HashTbl->kgHashShift, -+ &h_HashBucket, &bucketIndex, -+ &lastIndex); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return FM_PCD_MatchTableAddKey(h_HashBucket, FM_PCD_LAST_KEY_INDEX, keySize, -+ p_KeyParams); -+} -+ -+t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, uint8_t keySize, -+ uint8_t *p_Key) -+{ -+ t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; -+ t_Handle h_HashBucket; -+ uint8_t bucketIndex; -+ uint16_t lastIndex; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); -+ -+ err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key, -+ p_HashTbl->kgHashShift, -+ &h_HashBucket, &bucketIndex, -+ &lastIndex); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return FM_PCD_MatchTableFindNRemoveKey(h_HashBucket, keySize, p_Key, NULL); -+} -+ -+t_Error FM_PCD_HashTableModifyNextEngine( -+ t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; -+ t_Handle h_HashBucket; -+ uint8_t bucketIndex; -+ uint16_t lastIndex; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); -+ -+ err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key, -+ p_HashTbl->kgHashShift, -+ &h_HashBucket, &bucketIndex, -+ &lastIndex); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return FM_PCD_MatchTableFindNModifyNextEngine(h_HashBucket, keySize, p_Key, -+ NULL, -+ p_FmPcdCcNextEngineParams); -+} -+ -+t_Error FM_PCD_HashTableModifyMissNextEngine( -+ t_Handle h_HashTbl, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; -+ t_Handle h_HashBucket; -+ uint8_t i; -+ bool nullifyMissStats = FALSE; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); -+ -+ if ((!p_HashTbl->h_MissStatsCounters) -+ && (p_FmPcdCcNextEngineParams->statisticsEn)) -+ RETURN_ERROR( -+ MAJOR, -+ E_CONFLICT, -+ ("Statistics are requested for a key, but statistics mode was set" -+ "to 'NONE' upon initialization")); -+ -+ if (p_HashTbl->h_MissStatsCounters) -+ { -+ if ((!p_HashTbl->statsEnForMiss) -+ && (p_FmPcdCcNextEngineParams->statisticsEn)) -+ nullifyMissStats = TRUE; -+ -+ if ((p_HashTbl->statsEnForMiss) -+ && (!p_FmPcdCcNextEngineParams->statisticsEn)) -+ { -+ p_HashTbl->statsEnForMiss = FALSE; -+ p_FmPcdCcNextEngineParams->statisticsEn = TRUE; -+ } -+ } -+ -+ for (i = 0; i < p_HashTbl->numOfKeys; i++) -+ { -+ h_HashBucket = -+ p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode; -+ -+ err = FM_PCD_MatchTableModifyMissNextEngine(h_HashBucket, -+ p_FmPcdCcNextEngineParams); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ if (nullifyMissStats) -+ { -+ memset(p_HashTbl->h_MissStatsCounters, 0, -+ (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); -+ memset(p_HashTbl->h_MissStatsCounters, 0, -+ (2 * FM_PCD_CC_STATS_COUNTER_SIZE)); -+ p_HashTbl->statsEnForMiss = TRUE; -+ } -+ -+ return E_OK; -+} -+ -+ -+t_Error FM_PCD_HashTableGetMissNextEngine( -+ t_Handle h_HashTbl, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams) -+{ -+ t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; -+ t_FmPcdCcNode *p_HashBucket; -+ -+ SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); -+ -+ /* Miss next engine of each bucket was initialized with the next engine of the hash table */ -+ p_HashBucket = -+ p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode; -+ -+ memcpy(p_FmPcdCcNextEngineParams, -+ &p_HashBucket->keyAndNextEngineParams[p_HashBucket->numOfKeys].nextEngineParams, -+ sizeof(t_FmPcdCcNextEngineParams)); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_HashTableFindNGetKeyStatistics( -+ t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key, -+ t_FmPcdCcKeyStatistics *p_KeyStatistics) -+{ -+ t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; -+ t_Handle h_HashBucket; -+ uint8_t bucketIndex; -+ uint16_t lastIndex; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER); -+ -+ err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key, -+ p_HashTbl->kgHashShift, -+ &h_HashBucket, &bucketIndex, -+ &lastIndex); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, keySize, p_Key, -+ NULL, p_KeyStatistics); -+} -+ -+t_Error FM_PCD_HashTableGetMissStatistics( -+ t_Handle h_HashTbl, t_FmPcdCcKeyStatistics *p_MissStatistics) -+{ -+ t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl; -+ t_Handle h_HashBucket; -+ -+ SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER); -+ -+ if (!p_HashTbl->statsEnForMiss) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Statistics were not enabled for miss")); -+ -+ h_HashBucket = -+ p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode; -+ -+ return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h -@@ -0,0 +1,399 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_cc.h -+ -+ @Description FM PCD CC ... -+*//***************************************************************************/ -+#ifndef __FM_CC_H -+#define __FM_CC_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "list_ext.h" -+ -+#include "fm_pcd.h" -+ -+ -+/***********************************************************************/ -+/* Coarse classification defines */ -+/***********************************************************************/ -+ -+#define CC_MAX_NUM_OF_KEYS (FM_PCD_MAX_NUM_OF_KEYS + 1) -+ -+#define CC_PC_FF_MACDST 0x00 -+#define CC_PC_FF_MACSRC 0x01 -+#define CC_PC_FF_ETYPE 0x02 -+ -+#define CC_PC_FF_TCI1 0x03 -+#define CC_PC_FF_TCI2 0x04 -+ -+#define CC_PC_FF_MPLS1 0x06 -+#define CC_PC_FF_MPLS_LAST 0x07 -+ -+#define CC_PC_FF_IPV4DST1 0x08 -+#define CC_PC_FF_IPV4DST2 0x16 -+#define CC_PC_FF_IPV4IPTOS_TC1 0x09 -+#define CC_PC_FF_IPV4IPTOS_TC2 0x17 -+#define CC_PC_FF_IPV4PTYPE1 0x0A -+#define CC_PC_FF_IPV4PTYPE2 0x18 -+#define CC_PC_FF_IPV4SRC1 0x0b -+#define CC_PC_FF_IPV4SRC2 0x19 -+#define CC_PC_FF_IPV4SRC1_IPV4DST1 0x0c -+#define CC_PC_FF_IPV4SRC2_IPV4DST2 0x1a -+#define CC_PC_FF_IPV4TTL 0x29 -+ -+ -+#define CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1 0x0d /*TODO - CLASS - what is it? TOS*/ -+#define CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2 0x1b -+#define CC_PC_FF_IPV6PTYPE1 0x0e -+#define CC_PC_FF_IPV6PTYPE2 0x1c -+#define CC_PC_FF_IPV6DST1 0x0f -+#define CC_PC_FF_IPV6DST2 0x1d -+#define CC_PC_FF_IPV6SRC1 0x10 -+#define CC_PC_FF_IPV6SRC2 0x1e -+#define CC_PC_FF_IPV6HOP_LIMIT 0x2a -+#define CC_PC_FF_IPPID 0x24 -+#define CC_PC_FF_IPDSCP 0x76 -+ -+#define CC_PC_FF_GREPTYPE 0x11 -+ -+#define CC_PC_FF_MINENCAP_PTYPE 0x12 -+#define CC_PC_FF_MINENCAP_IPDST 0x13 -+#define CC_PC_FF_MINENCAP_IPSRC 0x14 -+#define CC_PC_FF_MINENCAP_IPSRC_IPDST 0x15 -+ -+#define CC_PC_FF_L4PSRC 0x1f -+#define CC_PC_FF_L4PDST 0x20 -+#define CC_PC_FF_L4PSRC_L4PDST 0x21 -+ -+#define CC_PC_FF_PPPPID 0x05 -+ -+#define CC_PC_PR_SHIM1 0x22 -+#define CC_PC_PR_SHIM2 0x23 -+ -+#define CC_PC_GENERIC_WITHOUT_MASK 0x27 -+#define CC_PC_GENERIC_WITH_MASK 0x28 -+#define CC_PC_GENERIC_IC_GMASK 0x2B -+#define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C -+#define CC_PC_GENERIC_IC_AGING_MASK 0x2D -+ -+#define CC_PR_OFFSET 0x25 -+#define CC_PR_WITHOUT_OFFSET 0x26 -+ -+#define CC_PC_PR_ETH_OFFSET 19 -+#define CC_PC_PR_USER_DEFINED_SHIM1_OFFSET 16 -+#define CC_PC_PR_USER_DEFINED_SHIM2_OFFSET 17 -+#define CC_PC_PR_USER_LLC_SNAP_OFFSET 20 -+#define CC_PC_PR_VLAN1_OFFSET 21 -+#define CC_PC_PR_VLAN2_OFFSET 22 -+#define CC_PC_PR_PPPOE_OFFSET 24 -+#define CC_PC_PR_MPLS1_OFFSET 25 -+#define CC_PC_PR_MPLS_LAST_OFFSET 26 -+#define CC_PC_PR_IP1_OFFSET 27 -+#define CC_PC_PR_IP_LAST_OFFSET 28 -+#define CC_PC_PR_MINENC_OFFSET 28 -+#define CC_PC_PR_L4_OFFSET 30 -+#define CC_PC_PR_GRE_OFFSET 29 -+#define CC_PC_PR_ETYPE_LAST_OFFSET 23 -+#define CC_PC_PR_NEXT_HEADER_OFFSET 31 -+ -+#define CC_PC_ILLEGAL 0xff -+#define CC_SIZE_ILLEGAL 0 -+ -+#define FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN 16 -+#define FM_PCD_CC_AD_TABLE_ALIGN 16 -+#define FM_PCD_CC_AD_ENTRY_SIZE 16 -+#define FM_PCD_CC_NUM_OF_KEYS 255 -+#define FM_PCD_CC_TREE_ADDR_ALIGN 256 -+ -+#define FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE 0x00000000 -+#define FM_PCD_AD_RESULT_DATA_FLOW_TYPE 0x80000000 -+#define FM_PCD_AD_RESULT_PLCR_DIS 0x20000000 -+#define FM_PCD_AD_RESULT_EXTENDED_MODE 0x80000000 -+#define FM_PCD_AD_RESULT_NADEN 0x20000000 -+#define FM_PCD_AD_RESULT_STATISTICS_EN 0x40000000 -+ -+#define FM_PCD_AD_CONT_LOOKUP_TYPE 0x40000000 -+#define FM_PCD_AD_CONT_LOOKUP_LCL_MASK 0x00800000 -+ -+#define FM_PCD_AD_STATS_TYPE 0x40000000 -+#define FM_PCD_AD_STATS_FLR_ADDR_MASK 0x00FFFFFF -+#define FM_PCD_AD_STATS_COUNTERS_ADDR_MASK 0x00FFFFFF -+#define FM_PCD_AD_STATS_NEXT_ACTION_MASK 0xFFFF0000 -+#define FM_PCD_AD_STATS_NEXT_ACTION_SHIFT 12 -+#define FM_PCD_AD_STATS_NAD_EN 0x00008000 -+#define FM_PCD_AD_STATS_OP_CODE 0x00000036 -+#define FM_PCD_AD_STATS_FLR_EN 0x00004000 -+#define FM_PCD_AD_STATS_COND_EN 0x00002000 -+ -+ -+ -+#define FM_PCD_AD_BYPASS_TYPE 0xc0000000 -+ -+#define FM_PCD_AD_TYPE_MASK 0xc0000000 -+#define FM_PCD_AD_OPCODE_MASK 0x0000000f -+ -+#define FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT 16 -+#if (DPAA_VERSION >= 11) -+#define FM_PCD_AD_RESULT_VSP_SHIFT 24 -+#define FM_PCD_AD_RESULT_NO_OM_VSPE 0x02000000 -+#define FM_PCD_AD_RESULT_VSP_MASK 0x3f -+#define FM_PCD_AD_NCSPFQIDM_MASK 0x80000000 -+#endif /* (DPAA_VERSION >= 11) */ -+ -+#define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000 -+#define CC_GLBL_MASK_SIZE 4 -+#define CC_AGING_MASK_SIZE 4 -+ -+typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */ -+ -+#define CC_PRIVATE_INFO_NONE 0 -+#define CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP 0x80000000 -+#define CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH 0x40000000 -+#define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000 -+#define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000 -+ -+#define CC_BUILD_AGING_MASK(numOfKeys) ((((1LL << ((numOfKeys) + 1)) - 1)) << (31 - (numOfKeys))) -+/***********************************************************************/ -+/* Memory map */ -+/***********************************************************************/ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+typedef struct -+{ -+ volatile uint32_t fqid; -+ volatile uint32_t plcrProfile; -+ volatile uint32_t nia; -+ volatile uint32_t res; -+} t_AdOfTypeResult; -+ -+typedef struct -+{ -+ volatile uint32_t ccAdBase; -+ volatile uint32_t matchTblPtr; -+ volatile uint32_t pcAndOffsets; -+ volatile uint32_t gmask; -+} t_AdOfTypeContLookup; -+ -+typedef struct -+{ -+ volatile uint32_t profileTableAddr; -+ volatile uint32_t reserved; -+ volatile uint32_t nextActionIndx; -+ volatile uint32_t statsTableAddr; -+} t_AdOfTypeStats; -+ -+typedef union -+{ -+ volatile t_AdOfTypeResult adResult; -+ volatile t_AdOfTypeContLookup adContLookup; -+} t_Ad; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+/***********************************************************************/ -+/* Driver's internal structures */ -+/***********************************************************************/ -+ -+typedef struct t_FmPcdStatsObj -+{ -+ t_Handle h_StatsAd; -+ t_Handle h_StatsCounters; -+ t_List node; -+} t_FmPcdStatsObj; -+ -+typedef struct -+{ -+ uint8_t key[FM_PCD_MAX_SIZE_OF_KEY]; -+ uint8_t mask[FM_PCD_MAX_SIZE_OF_KEY]; -+ -+ t_FmPcdCcNextEngineParams nextEngineParams; -+ uint32_t requiredAction; -+ uint32_t shadowAction; -+ -+ t_FmPcdStatsObj *p_StatsObj; -+ -+} t_FmPcdCcKeyAndNextEngineParams; -+ -+typedef struct -+{ -+ t_Handle p_Ad; -+ e_FmPcdEngine fmPcdEngine; -+ bool adAllocated; -+ bool isTree; -+ -+ uint32_t myInfo; -+ t_List *h_CcNextNodesLst; -+ t_Handle h_AdditionalInfo; -+ t_Handle h_Node; -+} t_FmPcdModifyCcAdditionalParams; -+ -+typedef struct -+{ -+ t_Handle p_AdTableNew; -+ t_Handle p_KeysMatchTableNew; -+ t_Handle p_AdTableOld; -+ t_Handle p_KeysMatchTableOld; -+ uint16_t numOfKeys; -+ t_Handle h_CurrentNode; -+ uint16_t savedKeyIndex; -+ t_Handle h_NodeForAdd; -+ t_Handle h_NodeForRmv; -+ t_Handle h_ManipForRmv; -+ t_Handle h_ManipForAdd; -+ t_FmPcdStatsObj *p_StatsObjForRmv; -+#if (DPAA_VERSION >= 11) -+ t_Handle h_FrmReplicForAdd; -+ t_Handle h_FrmReplicForRmv; -+#endif /* (DPAA_VERSION >= 11) */ -+ bool tree; -+ -+ t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS]; -+} t_FmPcdModifyCcKeyAdditionalParams; -+ -+typedef struct -+{ -+ t_Handle h_Manip; -+ t_Handle h_CcNode; -+} t_CcNextEngineInfo; -+ -+typedef struct -+{ -+ uint16_t numOfKeys; -+ uint16_t maxNumOfKeys; -+ -+ bool maskSupport; -+ uint32_t keysMatchTableMaxSize; -+ -+ e_FmPcdCcStatsMode statisticsMode; -+ uint32_t numOfStatsFLRs; -+ uint32_t countersArraySize; -+ -+ bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */ -+ t_Handle h_MissStatsCounters; /**< Valid for hash table node and match table that is a bucket; -+ Holds the statistics counters allocated by the hash table and -+ are shared by all hash table buckets; */ -+ t_Handle h_PrivMissStatsCounters; /**< Valid for match table node that is a bucket of a hash table only; -+ Holds the statistics counters that were allocated for this node -+ and replaced by the shared counters (allocated by the hash table); */ -+ bool statsEnForMiss; /**< Valid for hash table node only; TRUE is statistics are currently -+ enabled for hash 'miss', FALSE otherwise; This parameter effects the -+ returned statistics count to user, statistics AD always present for 'miss' -+ for all hash buckets; */ -+ bool glblMaskUpdated; -+ t_Handle p_GlblMask; -+ bool lclMask; -+ uint8_t parseCode; -+ uint8_t offset; -+ uint8_t prsArrayOffset; -+ bool ctrlFlow; -+ uint16_t owners; -+ -+ uint8_t ccKeySizeAccExtraction; -+ uint8_t sizeOfExtraction; -+ uint8_t glblMaskSize; -+ -+ t_Handle h_KeysMatchTable; -+ t_Handle h_AdTable; -+ t_Handle h_StatsAds; -+ t_Handle h_TmpAd; -+ t_Handle h_Ad; -+ t_Handle h_StatsFLRs; -+ -+ t_List availableStatsLst; -+ -+ t_List ccPrevNodesLst; -+ -+ t_List ccTreeIdLst; -+ t_List ccTreesLst; -+ -+ t_Handle h_FmPcd; -+ uint32_t shadowAction; -+ uint8_t userSizeOfExtraction; -+ uint8_t userOffset; -+ uint8_t kgHashShift; /* used in hash-table */ -+ -+ t_Handle h_Spinlock; -+ -+ t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS]; -+} t_FmPcdCcNode; -+ -+typedef struct -+{ -+ t_FmPcdCcNode *p_FmPcdCcNode; -+ bool occupied; -+ uint16_t owners; -+ volatile bool lock; -+} t_FmPcdCcNodeArray; -+ -+typedef struct -+{ -+ uint8_t numOfEntriesInGroup; -+ uint32_t totalBitsMask; -+ uint8_t baseGroupEntry; -+} t_FmPcdCcGroupParam; -+ -+typedef struct -+{ -+ t_Handle h_FmPcd; -+ uint8_t netEnvId; -+ uintptr_t ccTreeBaseAddr; -+ uint8_t numOfGrps; -+ t_FmPcdCcGroupParam fmPcdGroupParam[FM_PCD_MAX_NUM_OF_CC_GROUPS]; -+ t_List fmPortsLst; -+ t_FmPcdLock *p_Lock; -+ uint8_t numOfEntries; -+ uint16_t owners; -+ t_Handle h_FmPcdCcSavedManipParams; -+ bool modifiedState; -+ uint32_t requiredAction; -+ t_Handle h_IpReassemblyManip; -+ t_Handle h_CapwapReassemblyManip; -+ -+ t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[FM_PCD_MAX_NUM_OF_CC_GROUPS]; -+} t_FmPcdCcTree; -+ -+ -+t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List); -+void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List); -+t_Error FmPcdUpdateCcShadow (t_FmPcd *p_FmPcd, uint32_t size, uint32_t align); -+ -+ -+#endif /* __FM_CC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c -@@ -0,0 +1,3242 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_kg.c -+ -+ @Description FM PCD ... -+*//***************************************************************************/ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "string_ext.h" -+#include "debug_ext.h" -+#include "net_ext.h" -+#include "fm_port_ext.h" -+ -+#include "fm_common.h" -+#include "fm_pcd.h" -+#include "fm_hc.h" -+#include "fm_pcd_ipc.h" -+#include "fm_kg.h" -+#include "fsl_fman_kg.h" -+ -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+ -+static uint32_t KgHwLock(t_Handle h_FmPcdKg) -+{ -+ ASSERT_COND(h_FmPcdKg); -+ return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock); -+} -+ -+static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags) -+{ -+ ASSERT_COND(h_FmPcdKg); -+ XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags); -+} -+ -+static uint32_t KgSchemeLock(t_Handle h_Scheme) -+{ -+ ASSERT_COND(h_Scheme); -+ return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock); -+} -+ -+static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags) -+{ -+ ASSERT_COND(h_Scheme); -+ FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags); -+} -+ -+static bool KgSchemeFlagTryLock(t_Handle h_Scheme) -+{ -+ ASSERT_COND(h_Scheme); -+ return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock); -+} -+ -+static void KgSchemeFlagUnlock(t_Handle h_Scheme) -+{ -+ ASSERT_COND(h_Scheme); -+ FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock); -+} -+ -+static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar) -+{ -+ -+ struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; -+ -+ if (fman_kg_write_ar_wait(regs, fmkg_ar)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation")); -+ -+ return E_OK; -+} -+ -+static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code) -+{ -+ int i; -+ -+ switch (code) -+ { -+ case (KG_SCH_GEN_PARSE_RESULT_N_FQID): -+ case (KG_SCH_GEN_DEFAULT): -+ case (KG_SCH_GEN_NEXTHDR): -+ for (i=0 ; ifmRevInfo.majorRev < 6) -+ return KG_SCH_KN_PTYPE2; -+#endif /* FM_KG_NO_IPPID_SUPPORT */ -+ return KG_SCH_KN_IPPID; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); -+ return 0; -+ case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) -+ return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1); -+ if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) -+ return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2); -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); -+ return 0; -+ case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) -+ return KG_SCH_KN_IPTOS_TC1; -+ if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) -+ return KG_SCH_KN_IPTOS_TC2; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); -+ return 0; -+ case (NET_HEADER_FIELD_IPv6_FL): -+ if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1)) -+ return KG_SCH_KN_IPV6FL1; -+ if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST)) -+ return KG_SCH_KN_IPV6FL2; -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index")); -+ return 0; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return 0; -+ } -+ case (HEADER_TYPE_GRE): -+ switch (field.gre) -+ { -+ case (NET_HEADER_FIELD_GRE_TYPE): -+ return KG_SCH_KN_GREPTYPE; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return 0; -+ } -+ case (HEADER_TYPE_MINENCAP): -+ switch (field.minencap) -+ { -+ case (NET_HEADER_FIELD_MINENCAP_SRC_IP): -+ return KG_SCH_KN_IPSRC2; -+ case (NET_HEADER_FIELD_MINENCAP_DST_IP): -+ return KG_SCH_KN_IPDST2; -+ case (NET_HEADER_FIELD_MINENCAP_TYPE): -+ return KG_SCH_KN_PTYPE2; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return 0; -+ } -+ case (HEADER_TYPE_TCP): -+ switch (field.tcp) -+ { -+ case (NET_HEADER_FIELD_TCP_PORT_SRC): -+ return KG_SCH_KN_L4PSRC; -+ case (NET_HEADER_FIELD_TCP_PORT_DST): -+ return KG_SCH_KN_L4PDST; -+ case (NET_HEADER_FIELD_TCP_FLAGS): -+ return KG_SCH_KN_TFLG; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return 0; -+ } -+ case (HEADER_TYPE_UDP): -+ switch (field.udp) -+ { -+ case (NET_HEADER_FIELD_UDP_PORT_SRC): -+ return KG_SCH_KN_L4PSRC; -+ case (NET_HEADER_FIELD_UDP_PORT_DST): -+ return KG_SCH_KN_L4PDST; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return 0; -+ } -+ case (HEADER_TYPE_IPSEC_AH): -+ switch (field.ipsecAh) -+ { -+ case (NET_HEADER_FIELD_IPSEC_AH_SPI): -+ return KG_SCH_KN_IPSEC_SPI; -+ case (NET_HEADER_FIELD_IPSEC_AH_NH): -+ return KG_SCH_KN_IPSEC_NH; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return 0; -+ } -+ case (HEADER_TYPE_IPSEC_ESP): -+ switch (field.ipsecEsp) -+ { -+ case (NET_HEADER_FIELD_IPSEC_ESP_SPI): -+ return KG_SCH_KN_IPSEC_SPI; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return 0; -+ } -+ case (HEADER_TYPE_SCTP): -+ switch (field.sctp) -+ { -+ case (NET_HEADER_FIELD_SCTP_PORT_SRC): -+ return KG_SCH_KN_L4PSRC; -+ case (NET_HEADER_FIELD_SCTP_PORT_DST): -+ return KG_SCH_KN_L4PDST; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return 0; -+ } -+ case (HEADER_TYPE_DCCP): -+ switch (field.dccp) -+ { -+ case (NET_HEADER_FIELD_DCCP_PORT_SRC): -+ return KG_SCH_KN_L4PSRC; -+ case (NET_HEADER_FIELD_DCCP_PORT_DST): -+ return KG_SCH_KN_L4PDST; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return 0; -+ } -+ case (HEADER_TYPE_PPPoE): -+ switch (field.pppoe) -+ { -+ case (NET_HEADER_FIELD_PPPoE_PID): -+ return KG_SCH_KN_PPPID; -+ case (NET_HEADER_FIELD_PPPoE_SID): -+ return KG_SCH_KN_PPPSID; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return 0; -+ } -+ default: -+ break; -+ -+ } -+ -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported")); -+ return 0; -+} -+ -+ -+static uint8_t GetKnownFieldId(uint32_t bitMask) -+{ -+ uint8_t cnt = 0; -+ -+ while (bitMask) -+ if (bitMask & 0x80000000) -+ break; -+ else -+ { -+ cnt++; -+ bitMask <<= 1; -+ } -+ return cnt; -+ -+} -+ -+static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid) -+{ -+ uint8_t i, mask, numOfOnesToClear, walking1Mask = 1; -+ -+ /* bitOffset 1-7 --> mask 0x1-0x7F */ -+ if (bitOffset<8) -+ { -+ mask = 0; -+ for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1) -+ mask |= walking1Mask; -+ } -+ else -+ { -+ mask = 0xFF; -+ numOfOnesToClear = 0; -+ if (fqid && bitOffset>24) -+ /* bitOffset 25-31 --> mask 0xFE-0x80 */ -+ numOfOnesToClear = (uint8_t)(bitOffset-24); -+ else -+ /* bitOffset 9-15 --> mask 0xFE-0x80 */ -+ if (!fqid && bitOffset>8) -+ numOfOnesToClear = (uint8_t)(bitOffset-8); -+ for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1) -+ mask &= ~walking1Mask; -+ /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/ -+ } -+ return mask; -+} -+ -+static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort) -+{ -+ t_FmPcdKg *p_FmPcdKg; -+ t_FmPcdKgScheme *p_Scheme; -+ uint32_t intFlags; -+ uint8_t relativeSchemeId; -+ int i; -+ -+ p_FmPcdKg = p_FmPcd->p_FmPcdKg; -+ -+ /* for each scheme - update owners counters */ -+ for (i = 0; i < p_BindPort->numOfSchemes; i++) -+ { -+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]); -+ ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES); -+ -+ p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId]; -+ -+ /* increment owners number */ -+ intFlags = KgSchemeLock(p_Scheme); -+ p_Scheme->owners++; -+ KgSchemeUnlock(p_Scheme, intFlags); -+ } -+} -+ -+static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort) -+{ -+ t_FmPcdKg *p_FmPcdKg; -+ t_FmPcdKgScheme *p_Scheme; -+ uint32_t intFlags; -+ uint8_t relativeSchemeId; -+ int i; -+ -+ p_FmPcdKg = p_FmPcd->p_FmPcdKg; -+ -+ /* for each scheme - update owners counters */ -+ for (i = 0; i < p_BindPort->numOfSchemes; i++) -+ { -+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]); -+ ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES); -+ -+ p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId]; -+ -+ /* increment owners number */ -+ ASSERT_COND(p_Scheme->owners); -+ intFlags = KgSchemeLock(p_Scheme); -+ p_Scheme->owners--; -+ KgSchemeUnlock(p_Scheme, intFlags); -+ } -+} -+ -+static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set) -+{ -+ /* this routine is locked by the calling routine */ -+ ASSERT_COND(p_Scheme); -+ ASSERT_COND(p_Scheme->valid); -+ -+ if (set) -+ p_Scheme->requiredActionFlag = TRUE; -+ else -+ { -+ p_Scheme->requiredAction = 0; -+ p_Scheme->requiredActionFlag = FALSE; -+ } -+} -+ -+static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add) -+{ -+ struct fman_kg_regs *p_KgRegs; -+ -+ uint32_t tmpKgarReg = 0, intFlags; -+ t_Error err = E_OK; -+ -+ /* The calling routine had locked the port, so for each port only one core can access -+ * (so we don't need a lock here) */ -+ -+ if (p_FmPcd->h_Hc) -+ return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add); -+ -+ p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; -+ -+ tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId); -+ /* lock a common KG reg */ -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ err = WriteKgarWait(p_FmPcd, tmpKgarReg); -+ if (err) -+ { -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ fman_kg_write_sp(p_KgRegs, spReg, add); -+ -+ tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId); -+ -+ err = WriteKgarWait(p_FmPcd, tmpKgarReg); -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ return err; -+} -+ -+static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg) -+{ -+ struct fman_kg_regs *p_KgRegs; -+ uint32_t tmpKgarReg, intFlags; -+ t_Error err; -+ -+ p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; -+ -+ if (p_FmPcd->h_Hc) -+ { -+ err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg); -+ return err; -+ } -+ -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ fman_kg_write_cpp(p_KgRegs, cppReg); -+ tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId); -+ err = WriteKgarWait(p_FmPcd, tmpKgarReg); -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ -+ return err; -+} -+ -+static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId) -+{ -+ uint32_t tmpKgpeCpp; -+ -+ tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8); -+ tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT); -+ -+ return tmpKgpeCpp; -+} -+ -+static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId) -+{ -+ uint32_t tmpKgpeCpp = 0; -+ -+ tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId); -+ return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp); -+} -+ -+static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId) -+{ -+ KgWriteCpp(p_FmPcd, hardwarePortId, 0); -+} -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId) -+{ -+ return (uint32_t)(FM_KG_KGAR_GO | -+ FM_KG_KGAR_READ | -+ FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | -+ DUMMY_PORT_ID | -+ ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) | -+ FM_PCD_KG_KGAR_WSEL_MASK); -+ -+ /* if we ever want to write 1 by 1, use: -+ sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP))); -+ */ -+} -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+static void PcdKgErrorException(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint32_t event,schemeIndexes = 0, index = 0; -+ struct fman_kg_regs *p_KgRegs; -+ -+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); -+ p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; -+ fman_kg_get_event(p_KgRegs, &event, &schemeIndexes); -+ -+ if (event & FM_EX_KG_DOUBLE_ECC) -+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC); -+ if (event & FM_EX_KG_KEYSIZE_OVERFLOW) -+ { -+ if (schemeIndexes) -+ { -+ while (schemeIndexes) -+ { -+ if (schemeIndexes & 0x1) -+ p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index)); -+ schemeIndexes >>= 1; -+ index+=1; -+ } -+ } -+ else /* this should happen only when interrupt is forced. */ -+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW); -+ } -+} -+ -+static t_Error KgInitGuest(t_FmPcd *p_FmPcd) -+{ -+ t_Error err = E_OK; -+ t_FmPcdIpcKgSchemesParams kgAlloc; -+ uint32_t replyLength; -+ t_FmPcdIpcReply reply; -+ t_FmPcdIpcMsg msg; -+ -+ ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID); -+ -+ /* in GUEST_PARTITION, we use the IPC */ -+ memset(&reply, 0, sizeof(reply)); -+ memset(&msg, 0, sizeof(msg)); -+ memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams)); -+ kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes; -+ kgAlloc.guestId = p_FmPcd->guestId; -+ msg.msgId = FM_PCD_ALLOC_KG_SCHEMES; -+ memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); -+ replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t); -+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(kgAlloc), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)); -+ -+ return (t_Error)reply.error; -+} -+ -+static t_Error KgInitMaster(t_FmPcd *p_FmPcd) -+{ -+ t_Error err = E_OK; -+ struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; -+ -+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); -+ -+ if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC) -+ FmEnableRamsEcc(p_FmPcd->h_Fm); -+ -+ fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd)); -+ -+ /* register even if no interrupts enabled, to allow future enablement */ -+ FmRegisterIntr(p_FmPcd->h_Fm, -+ e_FM_MOD_KG, -+ 0, -+ e_FM_INTR_TYPE_ERR, -+ PcdKgErrorException, -+ p_FmPcd); -+ -+ fman_kg_enable_scheme_interrupts(p_Regs); -+ -+ if (p_FmPcd->p_FmPcdKg->numOfSchemes) -+ { -+ err = FmPcdKgAllocSchemes(p_FmPcd, -+ p_FmPcd->p_FmPcdKg->numOfSchemes, -+ p_FmPcd->guestId, -+ p_FmPcd->p_FmPcdKg->schemesIds); -+ if (err) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ return E_OK; -+} -+ -+static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme) -+{ -+ ASSERT_COND(!p_Scheme->valid); -+ if (p_Scheme->netEnvId != ILLEGAL_NETENV) -+ FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId); -+ p_Scheme->valid = TRUE; -+} -+ -+static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme) -+{ -+ if (p_Scheme->owners) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to")); -+ -+ if (p_Scheme->netEnvId != ILLEGAL_NETENV) -+ FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId); -+ p_Scheme->valid = FALSE; -+ -+ return E_OK; -+} -+ -+static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme, -+ t_FmPcdKgSchemeParams *p_SchemeParams, -+ struct fman_kg_scheme_regs *p_SchemeRegs) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd); -+ uint32_t grpBits = 0; -+ uint8_t grpBase; -+ bool direct=TRUE, absolute=FALSE; -+ uint16_t profileId=0, numOfProfiles=0, relativeProfileId; -+ t_Error err = E_OK; -+ int i = 0; -+ t_NetEnvParams netEnvParams; -+ uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp; -+ t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL; -+ uint8_t j, curr, idx; -+ uint8_t id, shift=0, code=0, offset=0, size=0; -+ t_FmPcdExtractEntry *p_Extract = NULL; -+ t_FmPcdKgExtractedOrParams *p_ExtractOr; -+ bool generic = FALSE; -+ t_KnownFieldsMasks bitMask; -+ e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0; -+ t_FmPcdKgSchemesExtracts *p_LocalExtractsArray; -+ uint8_t numOfSwDefaults = 0; -+ t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS]; -+ uint8_t currGenId = 0; -+ -+ memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt)); -+ memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs)); -+ -+ if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)); -+ -+ /* by netEnv parameters, get match vector */ -+ if (!p_SchemeParams->alwaysDirect) -+ { -+ p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv); -+ netEnvParams.netEnvId = p_Scheme->netEnvId; -+ netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits; -+ memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits); -+ err = PcdGetUnitsVector(p_FmPcd, &netEnvParams); -+ if (err) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ p_Scheme->matchVector = netEnvParams.vector; -+ } -+ else -+ { -+ p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT; -+ p_Scheme->netEnvId = ILLEGAL_NETENV; -+ } -+ -+ if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid")); -+ -+ if (p_SchemeParams->bypassFqidGeneration) -+ { -+#ifdef FM_KG_NO_BYPASS_FQID_GEN -+ if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration.")); -+#endif /* FM_KG_NO_BYPASS_FQID_GEN */ -+ if (p_SchemeParams->baseFqid) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID")); -+ } -+ else -+ if (!p_SchemeParams->baseFqid) -+ DBG(WARNING, ("baseFqid is 0.")); -+ -+ if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR) -+ { -+ direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct; -+ p_Scheme->directPlcr = direct; -+ absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE); -+ if (!direct && absolute) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared.")); -+ -+ if (direct) -+ { -+ profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId; -+ numOfProfiles = 1; -+ } -+ else -+ { -+ profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; -+ shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift; -+ numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles; -+ } -+ } -+ -+ if (p_SchemeParams->nextEngine == e_FM_PCD_CC) -+ { -+#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN -+ if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)) -+ { -+ if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration.")); -+ } -+#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */ -+ -+ err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree, -+ p_SchemeParams->kgNextEngineParams.cc.grpId, -+ &grpBits, -+ &grpBase); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ p_Scheme->ccUnits = grpBits; -+ -+ if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && -+ (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)) -+ { -+ if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification.")); -+ absolute = FALSE; -+ direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct; -+ if (direct) -+ { -+ profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId; -+ numOfProfiles = 1; -+ } -+ else -+ { -+ profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; -+ shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift; -+ numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles; -+ } -+ } -+ } -+ -+ /* if policer is used directly after KG, or after CC */ -+ if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) || -+ ((p_SchemeParams->nextEngine == e_FM_PCD_CC) && -+ (p_SchemeParams->kgNextEngineParams.cc.plcrNext) && -+ (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))) -+ { -+ /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */ -+ if (absolute) -+ { -+ /* for absolute direct policy only, */ -+ relativeProfileId = profileId; -+ err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId); -+ if (err) -+ RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset")); -+ if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid.")); -+ p_Scheme->relativeProfileId = profileId; -+ } -+ else -+ { -+ /* save relative profile id's for later check */ -+ p_Scheme->nextRelativePlcrProfile = TRUE; -+ p_Scheme->relativeProfileId = profileId; -+ p_Scheme->numOfProfiles = numOfProfiles; -+ } -+ } -+ else -+ { -+ /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration -+ is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */ -+ if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID")); -+ if (p_SchemeParams->bypassFqidGeneration && -+ p_SchemeParams->useHash && -+ p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID")); -+ } -+ -+ /* configure all 21 scheme registers */ -+ tmpReg = KG_SCH_MODE_EN; -+ switch (p_SchemeParams->nextEngine) -+ { -+ case (e_FM_PCD_PLCR): -+ /* add to mode register - NIA */ -+ tmpReg |= KG_SCH_MODE_NIA_PLCR; -+ tmpReg |= NIA_ENG_PLCR; -+ tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0); -+ /* initialize policer profile command - */ -+ /* configure kgse_ppc */ -+ if (direct) -+ /* use profileId as base, other fields are 0 */ -+ p_SchemeRegs->kgse_ppc = (uint32_t)profileId; -+ else -+ { -+ if (shift > MAX_PP_SHIFT) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT)); -+ -+ if (!numOfProfiles || !POWER_OF_2(numOfProfiles)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2")); -+ -+ ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH; -+ ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW; -+ ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT); -+ ppcTmp |= (uint32_t)profileId; -+ -+ p_SchemeRegs->kgse_ppc = ppcTmp; -+ } -+ break; -+ case (e_FM_PCD_CC): -+ /* mode reg - define NIA */ -+ tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC); -+ -+ p_SchemeRegs->kgse_ccbs = grpBits; -+ tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT); -+ -+ if (p_SchemeParams->kgNextEngineParams.cc.plcrNext) -+ { -+ if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration) -+ { -+ /* find out if absolute or relative */ -+ if (absolute) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("It is illegal to request a shared profile in a scheme that is in a KG->CC->PLCR flow")); -+ if (direct) -+ { -+ /* mask = 0, base = directProfileId */ -+ p_SchemeRegs->kgse_ppc = (uint32_t)profileId; -+ } -+ else -+ { -+ if (shift > MAX_PP_SHIFT) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT)); -+ if (!numOfProfiles || !POWER_OF_2(numOfProfiles)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2")); -+ -+ ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH; -+ ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW; -+ ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT); -+ ppcTmp |= (uint32_t)profileId; -+ -+ p_SchemeRegs->kgse_ppc = ppcTmp; -+ } -+ } -+ } -+ break; -+ case (e_FM_PCD_DONE): -+ if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME) -+ tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd); -+ else -+ tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd); -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported")); -+ } -+ p_SchemeRegs->kgse_mode = tmpReg; -+ -+ p_SchemeRegs->kgse_mv = p_Scheme->matchVector; -+ -+#if (DPAA_VERSION >= 11) -+ if (p_SchemeParams->overrideStorageProfile) -+ { -+ p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE; -+ -+ if (p_SchemeParams->storageProfile.direct) -+ { -+ profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId; -+ shift = 0; -+ numOfProfiles = 1; -+ } -+ else -+ { -+ profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase; -+ shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift; -+ numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles; -+ } -+ if (shift > MAX_SP_SHIFT) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT)); -+ -+ if (!numOfProfiles || !POWER_OF_2(numOfProfiles)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2")); -+ -+ tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT; -+ tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT); -+ tmpReg |= (uint32_t)profileId; -+ -+ -+ p_SchemeRegs->kgse_vsp = tmpReg; -+ -+ p_Scheme->vspe = TRUE; -+ -+ } -+ else -+ p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ if (p_SchemeParams->useHash) -+ { -+ p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams; -+ -+ if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range")); -+ -+ /* configure kgse_dv0 */ -+ p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0; -+ -+ /* configure kgse_dv1 */ -+ p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1; -+ -+ if (!p_SchemeParams->bypassFqidGeneration) -+ { -+ if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2")); -+ if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid) -+ DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues.")); -+ } -+ -+ /* configure kgse_ekdv */ -+ tmpReg = 0; -+ for ( i=0 ;inumOfUsedDflts ; i++) -+ { -+ switch (p_KeyAndHash->dflts[i].type) -+ { -+ case (e_FM_PCD_KG_MAC_ADDR): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT); -+ break; -+ case (e_FM_PCD_KG_TCI): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT); -+ break; -+ case (e_FM_PCD_KG_ENET_TYPE): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT); -+ break; -+ case (e_FM_PCD_KG_PPP_SESSION_ID): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT); -+ break; -+ case (e_FM_PCD_KG_PPP_PROTOCOL_ID): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT); -+ break; -+ case (e_FM_PCD_KG_MPLS_LABEL): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT); -+ break; -+ case (e_FM_PCD_KG_IP_ADDR): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT); -+ break; -+ case (e_FM_PCD_KG_PROTOCOL_TYPE): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT); -+ break; -+ case (e_FM_PCD_KG_IP_TOS_TC): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT); -+ break; -+ case (e_FM_PCD_KG_IPV6_FLOW_LABEL): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT); -+ break; -+ case (e_FM_PCD_KG_IPSEC_SPI): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT); -+ break; -+ case (e_FM_PCD_KG_L4_PORT): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT); -+ break; -+ case (e_FM_PCD_KG_TCP_FLAG): -+ tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT); -+ break; -+ case (e_FM_PCD_KG_GENERIC_FROM_DATA): -+ swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA; -+ swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; -+ numOfSwDefaults ++; -+ break; -+ case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V): -+ swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V; -+ swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; -+ numOfSwDefaults ++; -+ break; -+ case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA): -+ swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA; -+ swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect; -+ numOfSwDefaults ++; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ } -+ p_SchemeRegs->kgse_ekdv = tmpReg; -+ -+ p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts)); -+ if (!p_LocalExtractsArray) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); -+ -+ /* configure kgse_ekfc and kgse_gec */ -+ knownTmp = 0; -+ for ( i=0 ;inumOfUsedExtracts ; i++) -+ { -+ p_Extract = &p_KeyAndHash->extractArray[i]; -+ switch (p_Extract->type) -+ { -+ case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO): -+ knownTmp |= KG_SCH_KN_PORT_ID; -+ /* save in driver structure */ -+ p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID); -+ p_LocalExtractsArray->extractsArray[i].known = TRUE; -+ break; -+ case (e_FM_PCD_EXTRACT_BY_HDR): -+ switch (p_Extract->extractByHdr.hdr) -+ { -+#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+ case (HEADER_TYPE_UDP_LITE): -+ p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; -+ break; -+#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+ case (HEADER_TYPE_UDP_ENCAP_ESP): -+ switch (p_Extract->extractByHdr.type) -+ { -+ case (e_FM_PCD_EXTRACT_FROM_HDR): -+ /* case where extraction from ESP only */ -+ if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE) -+ { -+ p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); -+ p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE; -+ p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; -+ } -+ else -+ { -+ p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; -+ p_Extract->extractByHdr.ignoreProtocolValidation = FALSE; -+ } -+ break; -+ case (e_FM_PCD_EXTRACT_FROM_FIELD): -+ switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp) -+ { -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC): -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST): -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN): -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM): -+ p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; -+ break; -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI): -+ p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; -+ p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); -+ /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/ -+ p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; -+ break; -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM): -+ p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; -+ p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); -+ p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET; -+ p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; -+ break; -+ } -+ break; -+ case (e_FM_PCD_EXTRACT_FULL_FIELD): -+ switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp) -+ { -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC): -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST): -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN): -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM): -+ p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP; -+ break; -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI): -+ p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; -+ p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); -+ p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE; -+ p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET; -+ p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; -+ break; -+ case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM): -+ p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR; -+ p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP); -+ p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE; -+ p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET; -+ p_Extract->extractByHdr.ignoreProtocolValidation = TRUE; -+ break; -+ } -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ switch (p_Extract->extractByHdr.type) -+ { -+ case (e_FM_PCD_EXTRACT_FROM_HDR): -+ generic = TRUE; -+ /* get the header code for the generic extract */ -+ code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation); -+ /* set generic register fields */ -+ offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset; -+ size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size; -+ break; -+ case (e_FM_PCD_EXTRACT_FROM_FIELD): -+ generic = TRUE; -+ /* get the field code for the generic extract */ -+ code = GetGenFieldCode(p_Extract->extractByHdr.hdr, -+ p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex); -+ offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset; -+ size = p_Extract->extractByHdr.extractByHdrType.fromField.size; -+ break; -+ case (e_FM_PCD_EXTRACT_FULL_FIELD): -+ if (!p_Extract->extractByHdr.ignoreProtocolValidation) -+ { -+ /* if we have a known field for it - use it, otherwise use generic */ -+ bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, -+ p_Extract->extractByHdr.extractByHdrType.fullField); -+ if (bitMask) -+ { -+ knownTmp |= bitMask; -+ /* save in driver structure */ -+ p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask); -+ p_LocalExtractsArray->extractsArray[i].known = TRUE; -+ } -+ else -+ generic = TRUE; -+ } -+ else -+ generic = TRUE; -+ if (generic) -+ { -+ /* tmp - till we cover more headers under generic */ -+ XX_Free(p_LocalExtractsArray); -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported")); -+ } -+ break; -+ default: -+ XX_Free(p_LocalExtractsArray); -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ break; -+ case (e_FM_PCD_EXTRACT_NON_HDR): -+ /* use generic */ -+ generic = TRUE; -+ offset = 0; -+ /* get the field code for the generic extract */ -+ code = GetGenCode(p_Extract->extractNonHdr.src, &offset); -+ offset += p_Extract->extractNonHdr.offset; -+ size = p_Extract->extractNonHdr.size; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ -+ if (generic) -+ { -+ /* set generic register fields */ -+ if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS) -+ { -+ XX_Free(p_LocalExtractsArray); -+ RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used")); -+ } -+ if (!code) -+ { -+ XX_Free(p_LocalExtractsArray); -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); -+ } -+ -+ genTmp = KG_SCH_GEN_VALID; -+ genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT); -+ genTmp |= offset; -+ if ((size > MAX_KG_SCH_SIZE) || (size < 1)) -+ { -+ XX_Free(p_LocalExtractsArray); -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)")); -+ } -+ genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT); -+ swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code); -+ if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL) -+ DBG(WARNING, ("No sw default configured")); -+ else -+ genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT; -+ -+ genTmp |= KG_SCH_GEN_MASK; -+ p_SchemeRegs->kgse_gec[currGenId] = genTmp; -+ /* save in driver structure */ -+ p_LocalExtractsArray->extractsArray[i].id = currGenId++; -+ p_LocalExtractsArray->extractsArray[i].known = FALSE; -+ generic = FALSE; -+ } -+ } -+ p_SchemeRegs->kgse_ekfc = knownTmp; -+ -+ selectTmp = 0; -+ maskTmp = 0xFFFFFFFF; -+ /* configure kgse_bmch, kgse_bmcl and kgse_fqb */ -+ -+ if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS) -+ { -+ XX_Free(p_LocalExtractsArray); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS)); -+ } -+ for ( i=0 ;inumOfUsedMasks ; i++) -+ { -+ /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */ -+ id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id; -+ /* Get the shift of the select field (depending on i) */ -+ GET_MASK_SEL_SHIFT(shift,i); -+ if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known) -+ selectTmp |= id << shift; -+ else -+ selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift; -+ -+ /* Get the shift of the offset field (depending on i) - may -+ be in kgse_bmch or in kgse_fqb (depending on i) */ -+ GET_MASK_OFFSET_SHIFT(shift,i); -+ if (i<=1) -+ selectTmp |= p_KeyAndHash->masks[i].offset << shift; -+ else -+ fqbTmp |= p_KeyAndHash->masks[i].offset << shift; -+ -+ /* Get the shift of the mask field (depending on i) */ -+ GET_MASK_SHIFT(shift,i); -+ /* pass all bits */ -+ maskTmp |= KG_SCH_BITMASK_MASK << shift; -+ /* clear bits that need masking */ -+ maskTmp &= ~(0xFF << shift) ; -+ /* set mask bits */ -+ maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ; -+ } -+ p_SchemeRegs->kgse_bmch = selectTmp; -+ p_SchemeRegs->kgse_bmcl = maskTmp; -+ /* kgse_fqb will be written t the end of the routine */ -+ -+ /* configure kgse_hc */ -+ if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT) -+ { -+ XX_Free(p_LocalExtractsArray); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT)); -+ } -+ if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT) -+ { -+ XX_Free(p_LocalExtractsArray); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT)); -+ } -+ -+ tmpReg = 0; -+ -+ tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift); -+ tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT; -+ -+ if (p_KeyAndHash->symmetricHash) -+ { -+ if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) || -+ (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) || -+ (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) || -+ (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST))) -+ { -+ XX_Free(p_LocalExtractsArray); -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing")); -+ } -+ tmpReg |= KG_SCH_HASH_CONFIG_SYM; -+ } -+ p_SchemeRegs->kgse_hc = tmpReg; -+ -+ /* build the return array describing the order of the extractions */ -+ -+ /* the last currGenId places of the array -+ are for generic extracts that are always last. -+ We now sort for the calculation of the order of the known -+ extractions we sort the known extracts between orderedArray[0] and -+ orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1]. -+ for the calculation of the order of the generic extractions we use: -+ num_of_generic - currGenId -+ num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId -+ first_generic_index = num_of_known */ -+ curr = 0; -+ for (i=0;inumOfUsedExtracts ; i++) -+ { -+ if (p_LocalExtractsArray->extractsArray[i].known) -+ { -+ ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId)); -+ j = curr; -+ /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original -+ index in the user's extractions array */ -+ /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1] -+ location */ -+ while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id < -+ p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id)) -+ { -+ p_Scheme->orderedArray[j] = -+ p_Scheme->orderedArray[j-1]; -+ j--; -+ } -+ p_Scheme->orderedArray[j] = (uint8_t)i; -+ curr++; -+ } -+ else -+ { -+ /* index is first_generic_index + generic index (id) */ -+ idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id); -+ ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY); -+ p_Scheme->orderedArray[idx]= (uint8_t)i; -+ } -+ } -+ XX_Free(p_LocalExtractsArray); -+ } -+ else -+ { -+ /* clear all unused registers: */ -+ p_SchemeRegs->kgse_ekfc = 0; -+ p_SchemeRegs->kgse_ekdv = 0; -+ p_SchemeRegs->kgse_bmch = 0; -+ p_SchemeRegs->kgse_bmcl = 0; -+ p_SchemeRegs->kgse_hc = 0; -+ p_SchemeRegs->kgse_dv0 = 0; -+ p_SchemeRegs->kgse_dv1 = 0; -+ } -+ -+ if (p_SchemeParams->bypassFqidGeneration) -+ p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID; -+ -+ /* configure kgse_spc */ -+ if ( p_SchemeParams->schemeCounter.update) -+ p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value; -+ -+ -+ /* check that are enough generic registers */ -+ if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS) -+ RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used")); -+ -+ /* extracted OR mask on Qid */ -+ for ( i=0 ;inumOfUsedExtractedOrs ; i++) -+ { -+ -+ p_Scheme->extractedOrs = TRUE; -+ /* configure kgse_gec[i] */ -+ p_ExtractOr = &p_SchemeParams->extractedOrs[i]; -+ switch (p_ExtractOr->type) -+ { -+ case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO): -+ code = KG_SCH_GEN_PARSE_RESULT_N_FQID; -+ offset = 0; -+ break; -+ case (e_FM_PCD_EXTRACT_BY_HDR): -+ /* get the header code for the generic extract */ -+ code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation); -+ /* set generic register fields */ -+ offset = p_ExtractOr->extractionOffset; -+ break; -+ case (e_FM_PCD_EXTRACT_NON_HDR): -+ /* get the field code for the generic extract */ -+ offset = 0; -+ code = GetGenCode(p_ExtractOr->src, &offset); -+ offset += p_ExtractOr->extractionOffset; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ -+ /* set generic register fields */ -+ if (!code) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); -+ genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID; -+ genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT); -+ genTmp |= offset; -+ if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile")); -+ -+ /************************************************************************************ -+ bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter -+ in the following way: -+ -+ Driver API and implementation: -+ ============================== -+ FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID. -+ if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that -+ are not overlapping FQID. -+ ------------------------ -+ | FQID (24) | -+ ------------------------ -+ -------- -+ | | extracted OR byte -+ -------- -+ -+ Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the -+ PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that -+ are not overlapping PP id. -+ -+ -------- -+ | PP (8) | -+ -------- -+ -------- -+ | | extracted OR byte -+ -------- -+ -+ HW implementation -+ ================= -+ FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located -+ as the highest byte of that word and may be rotated to effect any part os the FQID or -+ the PP. -+ ------------------------ -------- -+ | FQID (24) || PP (8) | -+ ------------------------ -------- -+ -------- -+ | | extracted OR byte -+ -------- -+ -+ ************************************************************************************/ -+ -+ if (p_ExtractOr->bitOffsetInFqid) -+ { -+ if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET ) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)")); -+ if (p_ExtractOr->bitOffsetInFqid<8) -+ genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT); -+ else -+ genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT); -+ p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE); -+ } -+ else /* effect policer profile */ -+ { -+ if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET ) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)")); -+ p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile; -+ genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT); -+ p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE); -+ } -+ -+ genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT); -+ /* clear bits that need masking */ -+ genTmp &= ~KG_SCH_GEN_MASK ; -+ /* set mask bits */ -+ genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT); -+ p_SchemeRegs->kgse_gec[currGenId++] = genTmp; -+ -+ } -+ /* clear all unused GEC registers */ -+ for ( i=currGenId ;ikgse_gec[i] = 0; -+ -+ /* add base Qid for this scheme */ -+ /* add configuration for kgse_fqb */ -+ if (p_SchemeParams->baseFqid & ~0x00FFFFFF) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1")); -+ -+ fqbTmp |= p_SchemeParams->baseFqid; -+ p_SchemeRegs->kgse_fqb = fqbTmp; -+ -+ p_Scheme->nextEngine = p_SchemeParams->nextEngine; -+ p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction; -+ -+ return E_OK; -+} -+ -+ -+/*****************************************************************************/ -+/* Inter-module API routines */ -+/*****************************************************************************/ -+ -+t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmPcdKgClsPlanGrp *p_ClsPlanGrp; -+ t_FmPcdIpcKgClsPlanParams kgAlloc; -+ t_Error err = E_OK; -+ uint32_t oredVectors = 0; -+ int i, j; -+ -+ /* this routine is protected by the calling routine ! */ -+ if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected.")); -+ -+ /* find a new clsPlan group */ -+ for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) -+ if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used) -+ break; -+ if (i == FM_MAX_NUM_OF_PORTS) -+ RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available.")); -+ -+ p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE; -+ -+ p_Grp->clsPlanGrpId = (uint8_t)i; -+ -+ if (p_Grp->numOfOptions == 0) -+ p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i; -+ -+ p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i]; -+ p_ClsPlanGrp->netEnvId = p_Grp->netEnvId; -+ p_ClsPlanGrp->owners = 0; -+ FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId); -+ if (p_Grp->numOfOptions != 0) -+ FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId); -+ -+ p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions); -+ /* a minimal group of 8 is required */ -+ if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP) -+ p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP; -+ if (p_FmPcd->guestId == NCSW_MASTER_ID) -+ { -+ err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry); -+ -+ if (err) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG); -+ } -+ else -+ { -+ t_FmPcdIpcMsg msg; -+ uint32_t replyLength; -+ t_FmPcdIpcReply reply; -+ -+ /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */ -+ memset(&reply, 0, sizeof(reply)); -+ memset(&msg, 0, sizeof(msg)); -+ memset(&kgAlloc, 0, sizeof(kgAlloc)); -+ kgAlloc.guestId = p_FmPcd->guestId; -+ kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp; -+ msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN; -+ memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); -+ replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)); -+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(kgAlloc), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ if ((t_Error)reply.error != E_OK) -+ RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG); -+ -+ p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody); -+ } -+ -+ /* build classification plan entries parameters */ -+ p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry; -+ p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp; -+ -+ oredVectors = 0; -+ for (i = 0; inumOfOptions; i++) -+ { -+ oredVectors |= p_Grp->optVectors[i]; -+ /* save an array of used options - the indexes represent the power of 2 index */ -+ p_ClsPlanGrp->optArray[i] = p_Grp->options[i]; -+ } -+ /* set the classification plan relevant entries so that all bits -+ * relevant to the list of options is cleared -+ */ -+ for (j = 0; jsizeOfGrp; j++) -+ p_ClsPlanSet->vectors[j] = ~oredVectors; -+ -+ for (i = 0; inumOfOptions; i++) -+ { -+ /* option i got the place 2^i in the clsPlan array. all entries that -+ * have bit i set, should have the vector bit cleared. So each option -+ * has one location that it is exclusive (1,2,4,8...) and represent the -+ * presence of that option only, and other locations that represent a -+ * combination of options. -+ * e.g: -+ * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2 -+ * now represents a frame with ethernet-BC header - so the bit -+ * representing ethernet-BC should be set and all other option bits -+ * should be cleared. -+ * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit -+ * vector[1] set, but they also have other bits set: -+ * 3=1+2, options 0 and 1 -+ * 6=2+4, options 1 and 2 -+ * 7=1+2+4, options 0,1,and 2 -+ * 10=2+8, options 1 and 3 -+ * etc. -+ * */ -+ -+ /* now for each option (i), we set their bits in all entries (j) -+ * that contain bit 2^i. -+ */ -+ for (j = 0; jsizeOfGrp; j++) -+ { -+ if (j & (1<vectors[j] |= p_Grp->optVectors[i]; -+ } -+ } -+ -+ return E_OK; -+} -+ -+void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmPcdIpcKgClsPlanParams kgAlloc; -+ t_Error err; -+ t_FmPcdIpcMsg msg; -+ uint32_t replyLength; -+ t_FmPcdIpcReply reply; -+ -+ /* check that no port is bound to this clsPlan */ -+ if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to")); -+ return; -+ } -+ -+ FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN); -+ -+ if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId) -+ p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN; -+ else -+ FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId); -+ -+ /* free blocks */ -+ if (p_FmPcd->guestId == NCSW_MASTER_ID) -+ KgFreeClsPlanEntries(h_FmPcd, -+ p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp, -+ p_FmPcd->guestId, -+ p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry); -+ else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */ -+ { -+ memset(&reply, 0, sizeof(reply)); -+ memset(&msg, 0, sizeof(msg)); -+ kgAlloc.guestId = p_FmPcd->guestId; -+ kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp; -+ kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry; -+ msg.msgId = FM_PCD_FREE_KG_CLSPLAN; -+ memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); -+ replyLength = sizeof(uint32_t); -+ err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(kgAlloc), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ { -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ return; -+ } -+ if (replyLength != sizeof(uint32_t)) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ return; -+ } -+ if ((t_Error)reply.error != E_OK) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed")); -+ return; -+ } -+ } -+ -+ /* clear clsPlan driver structure */ -+ memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp)); -+} -+ -+t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t j, schemesPerPortVector = 0; -+ t_FmPcdKgScheme *p_Scheme; -+ uint8_t i, relativeSchemeId; -+ uint32_t tmp, walking1Mask; -+ uint8_t swPortIndex = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); -+ -+ /* for each scheme */ -+ for (i = 0; inumOfSchemes; i++) -+ { -+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]); -+ if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); -+ -+ if (add) -+ { -+ p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]; -+ if (!FmPcdKgIsSchemeValidSw(p_Scheme)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid.")); -+ /* check netEnvId of the port against the scheme netEnvId */ -+ if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId")); -+ -+ /* if next engine is private port policer profile, we need to check that it is valid */ -+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId); -+ if (p_Scheme->nextRelativePlcrProfile) -+ { -+ for (j = 0;jnumOfProfiles;j++) -+ { -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort); -+ if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range")); -+ if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j))) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid.")); -+ } -+ } -+ if (!p_BindPort->useClsPlan) -+ { -+ /* This check may be redundant as port is a assigned to the whole NetEnv */ -+ -+ /* if this port does not use clsPlan, it may not be bound to schemes with units that contain -+ cls plan options. Schemes that are used only directly, should not be checked. -+ it also may not be bound to schemes that go to CC with units that are options - so we OR -+ the match vector and the grpBits (= ccUnits) */ -+ if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits) -+ { -+ uint8_t netEnvId; -+ walking1Mask = 0x80000000; -+ netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId; -+ tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector; -+ tmp |= p_Scheme->ccUnits; -+ while (tmp) -+ { -+ if (tmp & walking1Mask) -+ { -+ tmp &= ~walking1Mask; -+ if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options")); -+ } -+ walking1Mask >>= 1; -+ } -+ } -+ } -+ } -+ /* build vector */ -+ schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]); -+ } -+ -+ *p_SpReg = schemesPerPortVector; -+ -+ return E_OK; -+} -+ -+t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t spReg; -+ t_Error err = E_OK; -+ -+ err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ IncSchemeOwners(p_FmPcd, p_SchemeBind); -+ -+ return E_OK; -+} -+ -+t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t spReg; -+ t_Error err = E_OK; -+ -+ err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ DecSchemeOwners(p_FmPcd, p_SchemeBind); -+ -+ return E_OK; -+} -+ -+bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme) -+{ -+ t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme; -+ -+ return p_Scheme->valid; -+} -+ -+bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT) -+ return TRUE; -+ else -+ return FALSE; -+} -+ -+t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint8_t i, j; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); -+ -+ /* This routine is issued only on master core of master partition - -+ either directly or through IPC, so no need for lock */ -+ -+ for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++) -+ { -+ if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated) -+ { -+ p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE; -+ p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId; -+ p_SchemesIds[j] = i; -+ j++; -+ } -+ } -+ -+ if (j != numOfSchemes) -+ { -+ /* roll back */ -+ for (j--; j; j--) -+ { -+ p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE; -+ p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0; -+ p_SchemesIds[j] = 0; -+ } -+ -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found")); -+ } -+ -+ return E_OK; -+} -+ -+t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint8_t i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE); -+ -+ /* This routine is issued only on master core of master partition - -+ either directly or through IPC */ -+ -+ for (i = 0; i < numOfSchemes; i++) -+ { -+ if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated")); -+ } -+ if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. ")); -+ } -+ p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE; -+ p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0; -+ } -+ -+ return E_OK; -+} -+ -+t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint8_t numOfBlocks, blocksFound=0, first=0; -+ uint8_t i, j; -+ -+ /* This routine is issued only on master core of master partition - -+ either directly or through IPC, so no need for lock */ -+ -+ if (!numOfClsPlanEntries) -+ return E_OK; -+ -+ if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8")); -+ -+ numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP); -+ -+ /* try to find consequent blocks */ -+ first = 0; -+ for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;) -+ { -+ if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated) -+ { -+ blocksFound++; -+ i++; -+ if (blocksFound == numOfBlocks) -+ break; -+ } -+ else -+ { -+ blocksFound = 0; -+ /* advance i to the next aligned address */ -+ first = i = (uint8_t)(first + numOfBlocks); -+ } -+ } -+ -+ if (blocksFound == numOfBlocks) -+ { -+ *p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP); -+ for (j = first; j < (first + numOfBlocks); j++) -+ { -+ p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE; -+ p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId; -+ } -+ return E_OK; -+ } -+ else -+ RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan")); -+} -+ -+void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint8_t numOfBlocks; -+ uint8_t i, baseBlock; -+ -+#ifdef DISABLE_ASSERTIONS -+UNUSED(guestId); -+#endif /* DISABLE_ASSERTIONS */ -+ -+ /* This routine is issued only on master core of master partition - -+ either directly or through IPC, so no need for lock */ -+ -+ numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP); -+ ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP)); -+ -+ baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP); -+ for (i=baseBlock;ip_FmPcdKg->clsPlanBlocksMng[i].allocated); -+ ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId); -+ p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE; -+ p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0; -+ } -+} -+ -+void KgEnable(t_FmPcd *p_FmPcd) -+{ -+ struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; -+ -+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); -+ fman_kg_enable(p_Regs); -+} -+ -+void KgDisable(t_FmPcd *p_FmPcd) -+{ -+ struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; -+ -+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); -+ fman_kg_disable(p_Regs); -+} -+ -+void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ struct fman_kg_cp_regs *p_FmPcdKgPortRegs; -+ uint32_t tmpKgarReg = 0, intFlags; -+ uint16_t i, j; -+ -+ /* This routine is protected by the calling routine ! */ -+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); -+ p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs; -+ -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ for (i=p_Set->baseEntry;ibaseEntry+p_Set->numOfClsPlanEntries;i+=8) -+ { -+ tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP)); -+ -+ for (j = i; j < i+8; j++) -+ { -+ ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1)); -+ WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]); -+ } -+ -+ if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED")); -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ return; -+ } -+ } -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+} -+ -+t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams) -+{ -+ t_FmPcdKg *p_FmPcdKg; -+ -+ UNUSED(p_FmPcd); -+ -+ if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES)); -+ return NULL; -+ } -+ -+ p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg)); -+ if (!p_FmPcdKg) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED")); -+ return NULL; -+ } -+ memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg)); -+ -+ -+ if (FmIsMaster(p_FmPcd->h_Fm)) -+ { -+ p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm)); -+ p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions; -+ p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0]; -+ } -+ -+ p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes; -+ if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes) -+ { -+ p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES; -+ DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES")); -+ } -+ -+ p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN; -+ -+ return p_FmPcdKg; -+} -+ -+t_Error KgInit(t_FmPcd *p_FmPcd) -+{ -+ t_Error err = E_OK; -+ -+ p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock(); -+ if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock")); -+ -+ if (p_FmPcd->guestId == NCSW_MASTER_ID) -+ err = KgInitMaster(p_FmPcd); -+ else -+ err = KgInitGuest(p_FmPcd); -+ -+ if (err != E_OK) -+ { -+ if (p_FmPcd->p_FmPcdKg->h_HwSpinlock) -+ XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock); -+ } -+ -+ return err; -+} -+ -+t_Error KgFree(t_FmPcd *p_FmPcd) -+{ -+ t_FmPcdIpcKgSchemesParams kgAlloc; -+ t_Error err = E_OK; -+ t_FmPcdIpcMsg msg; -+ uint32_t replyLength; -+ t_FmPcdIpcReply reply; -+ -+ FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR); -+ -+ if (p_FmPcd->guestId == NCSW_MASTER_ID) -+ { -+ err = FmPcdKgFreeSchemes(p_FmPcd, -+ p_FmPcd->p_FmPcdKg->numOfSchemes, -+ p_FmPcd->guestId, -+ p_FmPcd->p_FmPcdKg->schemesIds); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (p_FmPcd->p_FmPcdKg->h_HwSpinlock) -+ XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock); -+ -+ return E_OK; -+ } -+ -+ /* guest */ -+ memset(&reply, 0, sizeof(reply)); -+ memset(&msg, 0, sizeof(msg)); -+ kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes; -+ kgAlloc.guestId = p_FmPcd->guestId; -+ ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES); -+ memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes); -+ msg.msgId = FM_PCD_FREE_KG_SCHEMES; -+ memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc)); -+ replyLength = sizeof(uint32_t); -+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(kgAlloc), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ if (replyLength != sizeof(uint32_t)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ -+ if (p_FmPcd->p_FmPcdKg->h_HwSpinlock) -+ XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock); -+ -+ return (t_Error)reply.error; -+} -+ -+t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams; -+ t_FmPcdKgClsPlanGrp *p_ClsPlanGrp; -+ t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; -+ t_Error err; -+ -+ /* This function is issued only from FM_PORT_SetPcd which locked all PCD modules, -+ so no need for lock here */ -+ -+ memset(&grpParams, 0, sizeof(grpParams)); -+ grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN; -+ p_GrpParams = &grpParams; -+ -+ p_GrpParams->netEnvId = netEnvId; -+ -+ /* Get from the NetEnv the information of the clsPlan (can be already created, -+ * or needs to build) */ -+ err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams); -+ if (err) -+ RETURN_ERROR(MINOR,err,NO_MSG); -+ -+ if (p_GrpParams->grpExists) -+ { -+ /* this group was already updated (at least) in SW */ -+ *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId; -+ } -+ else -+ { -+ p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); -+ if (!p_ClsPlanSet) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set")); -+ memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); -+ /* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */ -+ err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet); -+ if (err) -+ { -+ XX_Free(p_ClsPlanSet); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId; -+ -+ if (p_FmPcd->h_Hc) -+ { -+ /* write clsPlan entries to memory */ -+ err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet); -+ if (err) -+ { -+ XX_Free(p_ClsPlanSet); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ else -+ /* write clsPlan entries to memory */ -+ KgSetClsPlan(p_FmPcd, p_ClsPlanSet); -+ -+ XX_Free(p_ClsPlanSet); -+ } -+ -+ /* Set caller parameters */ -+ -+ /* mark if this is an empty classification group */ -+ if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId) -+ *p_IsEmptyClsPlanGrp = TRUE; -+ else -+ *p_IsEmptyClsPlanGrp = FALSE; -+ -+ p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId]; -+ -+ /* increment owners number */ -+ p_ClsPlanGrp->owners++; -+ -+ /* copy options array for port */ -+ memcpy(p_OptArray, &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId].optArray, FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)*sizeof(protocolOpt_t)); -+ -+ /* bind port to the new or existing group */ -+ err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId); -+ if (err) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId]; -+ t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet; -+ t_Error err; -+ -+ /* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules, -+ so no need for lock here */ -+ -+ UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId); -+ -+ /* decrement owners number */ -+ ASSERT_COND(p_ClsPlanGrp->owners); -+ p_ClsPlanGrp->owners--; -+ -+ if (!p_ClsPlanGrp->owners) -+ { -+ if (p_FmPcd->h_Hc) -+ { -+ err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId); -+ return err; -+ } -+ else -+ { -+ /* clear clsPlan entries in memory */ -+ p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet)); -+ if (!p_ClsPlanSet) -+ { -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set")); -+ } -+ memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet)); -+ -+ p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry; -+ p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp; -+ KgSetClsPlan(p_FmPcd, p_ClsPlanSet); -+ XX_Free(p_ClsPlanSet); -+ -+ FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId); -+ } -+ } -+ return E_OK; -+} -+ -+uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); -+ -+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction; -+} -+ -+uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); -+ -+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag; -+} -+ -+bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); -+ -+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr; -+} -+ -+ -+uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); -+ -+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId; -+} -+ -+bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); -+ -+ if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs && -+ p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) || -+ p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile) -+ return TRUE; -+ else -+ return FALSE; -+ -+} -+ -+e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid); -+ -+ return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine; -+} -+ -+e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid); -+ -+ return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction; -+} -+ -+void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction) -+{ -+ t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme; -+ -+ /* this routine is protected by calling routine */ -+ -+ ASSERT_COND(p_Scheme->valid); -+ -+ p_Scheme->requiredAction |= requiredAction; -+} -+ -+bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg) -+{ -+ return (bool)!!(schemeModeReg & KG_SCH_MODE_EN); -+} -+ -+uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter) -+{ -+ return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) | -+ FM_KG_KGAR_GO | -+ FM_KG_KGAR_WRITE | -+ FM_KG_KGAR_SEL_SCHEME_ENTRY | -+ DUMMY_PORT_ID | -+ (updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0)); -+} -+ -+uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId) -+{ -+ return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) | -+ FM_KG_KGAR_GO | -+ FM_KG_KGAR_READ | -+ FM_KG_KGAR_SEL_SCHEME_ENTRY | -+ DUMMY_PORT_ID | -+ FM_KG_KGAR_SCM_WSEL_UPDATE_CNT); -+ -+} -+ -+uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId) -+{ -+ return (uint32_t)(FM_KG_KGAR_GO | -+ FM_KG_KGAR_WRITE | -+ FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | -+ DUMMY_PORT_ID | -+ ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) | -+ FM_PCD_KG_KGAR_WSEL_MASK); -+ -+ /* if we ever want to write 1 by 1, use: -+ sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP))); -+ */ -+} -+ -+uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId) -+{ -+ -+ return (uint32_t)(FM_KG_KGAR_GO | -+ FM_KG_KGAR_WRITE | -+ FM_PCD_KG_KGAR_SEL_PORT_ENTRY | -+ hardwarePortId | -+ FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); -+} -+ -+uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId) -+{ -+ -+ return (uint32_t)(FM_KG_KGAR_GO | -+ FM_KG_KGAR_READ | -+ FM_PCD_KG_KGAR_SEL_PORT_ENTRY | -+ hardwarePortId | -+ FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); -+} -+ -+uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId) -+{ -+ -+ return (uint32_t)(FM_KG_KGAR_GO | -+ FM_KG_KGAR_WRITE | -+ FM_PCD_KG_KGAR_SEL_PORT_ENTRY | -+ hardwarePortId | -+ FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP); -+} -+ -+uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry; -+} -+ -+uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp; -+} -+ -+ -+uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme) -+{ -+ return ((t_FmPcdKgScheme*)h_Scheme)->schemeId; -+ -+} -+ -+#if (DPAA_VERSION >= 11) -+bool FmPcdKgGetVspe(t_Handle h_Scheme) -+{ -+ return ((t_FmPcdKgScheme*)h_Scheme)->vspe; -+ -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint8_t i; -+ -+ for (i = 0;ip_FmPcdKg->numOfSchemes;i++) -+ if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId) -+ return i; -+ -+ if (i == p_FmPcd->p_FmPcdKg->numOfSchemes) -+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range")); -+ -+ return FM_PCD_KG_NUM_OF_SCHEMES; -+} -+ -+t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ ASSERT_COND(p_FmPcd); -+ -+ /* check that schemeId is in range */ -+ if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId)); -+ return NULL; -+ } -+ -+ if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId])) -+ return NULL; -+ -+ return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]; -+} -+ -+bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme) -+{ -+ return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE; -+} -+ -+t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint8_t relativeSchemeId, physicalSchemeId; -+ uint32_t tmpKgarReg, tmpReg32 = 0, intFlags; -+ t_Error err; -+ t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); -+ -+ /* Calling function locked all PCD modules, so no need to lock here */ -+ -+ if (!FmPcdKgIsSchemeValidSw(h_Scheme)) -+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); -+ -+ if (p_FmPcd->h_Hc) -+ { -+ err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value); -+ -+ UpdateRequiredActionFlag(h_Scheme,TRUE); -+ FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction); -+ return err; -+ } -+ -+ physicalSchemeId = p_Scheme->schemeId; -+ -+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId); -+ if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); -+ -+ if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag || -+ !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction)) -+ { -+ if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) -+ { -+ switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine) -+ { -+ case (e_FM_PCD_DONE): -+ if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME) -+ { -+ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode); -+ ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); -+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA); -+ /* call indirect command for scheme write */ -+ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ } -+ break; -+ case (e_FM_PCD_PLCR): -+ if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr || -+ (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs && -+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) || -+ p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile) -+ { -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared")); -+ } -+ err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction); -+ if (err) -+ { -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME")); -+ } -+ } -+ if (requiredAction & UPDATE_KG_NIA_CC_WA) -+ { -+ if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC) -+ { -+ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode); -+ ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC)); -+ tmpReg32 &= ~NIA_FM_CTL_AC_CC; -+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC); -+ /* call indirect command for scheme write */ -+ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ } -+ } -+ if (requiredAction & UPDATE_KG_OPT_MODE) -+ { -+ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value); -+ /* call indirect command for scheme write */ -+ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ } -+ if (requiredAction & UPDATE_KG_NIA) -+ { -+ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode); -+ tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK); -+ tmpReg32 |= value; -+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32); -+ /* call indirect command for scheme write */ -+ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ } -+ } -+ -+ UpdateRequiredActionFlag(h_Scheme, TRUE); -+ FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction); -+ -+ return E_OK; -+} -+/*********************** End of inter-module routines ************************/ -+ -+ -+/****************************************/ -+/* API routines */ -+/****************************************/ -+ -+t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams) -+{ -+ t_FmPcd *p_FmPcd; -+ struct fman_kg_scheme_regs schemeRegs; -+ struct fman_kg_scheme_regs *p_MemRegs; -+ uint8_t i; -+ t_Error err = E_OK; -+ uint32_t tmpKgarReg; -+ uint32_t intFlags; -+ uint8_t physicalSchemeId, relativeSchemeId = 0; -+ t_FmPcdKgScheme *p_Scheme; -+ -+ if (p_SchemeParams->modify) -+ { -+ p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme; -+ p_FmPcd = p_Scheme->h_FmPcd; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL); -+ -+ if (!FmPcdKgIsSchemeValidSw(p_Scheme)) -+ { -+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, -+ ("Scheme is invalid")); -+ return NULL; -+ } -+ -+ if (!KgSchemeFlagTryLock(p_Scheme)) -+ { -+ DBG(TRACE, ("Scheme Try Lock - BUSY")); -+ /* Signal to caller BUSY condition */ -+ p_SchemeParams->id.h_Scheme = NULL; -+ return NULL; -+ } -+ } -+ else -+ { -+ p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL); -+ -+ relativeSchemeId = p_SchemeParams->id.relativeSchemeId; -+ /* check that schemeId is in range */ -+ if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId)); -+ return NULL; -+ } -+ -+ p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]; -+ if (FmPcdKgIsSchemeValidSw(p_Scheme)) -+ { -+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, -+ ("Scheme id (%d)!", relativeSchemeId)); -+ return NULL; -+ } -+ /* Clear all fields, scheme may have beed previously used */ -+ memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme)); -+ -+ p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId]; -+ p_Scheme->h_FmPcd = p_FmPcd; -+ -+ p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd); -+ if (!p_Scheme->p_Lock) -+ REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!")); -+ } -+ -+ err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs); -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ if (p_SchemeParams->modify) -+ KgSchemeFlagUnlock(p_Scheme); -+ if (!p_SchemeParams->modify && -+ p_Scheme->p_Lock) -+ FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); -+ return NULL; -+ } -+ -+ if (p_FmPcd->h_Hc) -+ { -+ err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc, -+ (t_Handle)p_Scheme, -+ &schemeRegs, -+ p_SchemeParams->schemeCounter.update); -+ if (p_SchemeParams->modify) -+ KgSchemeFlagUnlock(p_Scheme); -+ if (err) -+ { -+ if (!p_SchemeParams->modify && -+ p_Scheme->p_Lock) -+ FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); -+ return NULL; -+ } -+ if (!p_SchemeParams->modify) -+ ValidateSchemeSw(p_Scheme); -+ return (t_Handle)p_Scheme; -+ } -+ -+ physicalSchemeId = p_Scheme->schemeId; -+ -+ /* configure all 21 scheme registers */ -+ p_MemRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs; -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc); -+ WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs); -+ WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode); -+ WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv); -+ WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0); -+ WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1); -+ WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv); -+ WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc); -+ WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch); -+ WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl); -+ WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc); -+ WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc); -+ WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb); -+ WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om); -+ WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp); -+ for (i=0 ; ikgse_gec[i], schemeRegs.kgse_gec[i]); -+ -+ /* call indirect command for scheme write */ -+ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update); -+ -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ -+ if (!p_SchemeParams->modify) -+ ValidateSchemeSw(p_Scheme); -+ else -+ KgSchemeFlagUnlock(p_Scheme); -+ -+ return (t_Handle)p_Scheme; -+} -+ -+t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme) -+{ -+ t_FmPcd *p_FmPcd; -+ uint8_t physicalSchemeId; -+ uint32_t tmpKgarReg, intFlags; -+ t_Error err = E_OK; -+ t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme; -+ -+ SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE); -+ -+ p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd); -+ -+ UpdateRequiredActionFlag(h_Scheme, FALSE); -+ -+ /* check that no port is bound to this scheme */ -+ err = InvalidateSchemeSw(h_Scheme); -+ if (err) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ if (p_FmPcd->h_Hc) -+ { -+ err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme); -+ if (p_Scheme->p_Lock) -+ FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); -+ return err; -+ } -+ -+ physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId; -+ -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ /* clear mode register, including enable bit */ -+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0); -+ -+ /* call indirect command for scheme write */ -+ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE); -+ -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ -+ if (p_Scheme->p_Lock) -+ FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock); -+ -+ return E_OK; -+} -+ -+uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme) -+{ -+ t_FmPcd *p_FmPcd; -+ uint32_t tmpKgarReg, spc, intFlags; -+ uint8_t physicalSchemeId; -+ -+ SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0); -+ -+ p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd); -+ if (p_FmPcd->h_Hc) -+ return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme); -+ -+ physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId; -+ -+ if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES) -+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); -+ -+ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) -+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); -+ spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc); -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ -+ return spc; -+} -+ -+t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value) -+{ -+ t_FmPcd *p_FmPcd; -+ uint32_t tmpKgarReg, intFlags; -+ uint8_t physicalSchemeId; -+ -+ SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0); -+ -+ p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd); -+ -+ if (!FmPcdKgIsSchemeValidSw(h_Scheme)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid.")); -+ -+ if (p_FmPcd->h_Hc) -+ return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value); -+ -+ physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId; -+ /* check that schemeId is in range */ -+ if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES) -+ REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); -+ -+ /* read specified scheme into scheme registers */ -+ tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId); -+ intFlags = KgHwLock(p_FmPcd->p_FmPcdKg); -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN)) -+ { -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid")); -+ } -+ -+ /* change counter value */ -+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value); -+ -+ /* call indirect command for scheme write */ -+ tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE); -+ -+ WriteKgarWait(p_FmPcd, tmpKgarReg); -+ KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ struct fman_kg_regs *p_Regs; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER); -+ -+ p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; -+ if (!FmIsMaster(p_FmPcd->h_Fm)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!")); -+ -+ WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ struct fman_kg_regs *p_Regs; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER); -+ -+ p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs; -+ -+ if (!FmIsMaster(p_FmPcd->h_Fm)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!")); -+ -+ if (valueId == 0) -+ WRITE_UINT32(p_Regs->fmkg_gdv0r,value); -+ else -+ WRITE_UINT32(p_Regs->fmkg_gdv1r,value); -+ return E_OK; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h -@@ -0,0 +1,206 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_kg.h -+ -+ @Description FM KG private header -+*//***************************************************************************/ -+#ifndef __FM_KG_H -+#define __FM_KG_H -+ -+#include "std_ext.h" -+ -+/***********************************************************************/ -+/* Keygen defines */ -+/***********************************************************************/ -+/* maskes */ -+#if (DPAA_VERSION >= 11) -+#define KG_SCH_VSP_SHIFT_MASK 0x0003f000 -+#define KG_SCH_OM_VSPE 0x00000001 -+#define KG_SCH_VSP_NO_KSP_EN 0x80000000 -+ -+#define MAX_SP_SHIFT 23 -+#define KG_SCH_VSP_MASK_SHIFT 12 -+#define KG_SCH_VSP_SHIFT 24 -+#endif /* (DPAA_VERSION >= 11) */ -+ -+typedef uint32_t t_KnownFieldsMasks; -+#define KG_SCH_KN_PORT_ID 0x80000000 -+#define KG_SCH_KN_MACDST 0x40000000 -+#define KG_SCH_KN_MACSRC 0x20000000 -+#define KG_SCH_KN_TCI1 0x10000000 -+#define KG_SCH_KN_TCI2 0x08000000 -+#define KG_SCH_KN_ETYPE 0x04000000 -+#define KG_SCH_KN_PPPSID 0x02000000 -+#define KG_SCH_KN_PPPID 0x01000000 -+#define KG_SCH_KN_MPLS1 0x00800000 -+#define KG_SCH_KN_MPLS2 0x00400000 -+#define KG_SCH_KN_MPLS_LAST 0x00200000 -+#define KG_SCH_KN_IPSRC1 0x00100000 -+#define KG_SCH_KN_IPDST1 0x00080000 -+#define KG_SCH_KN_PTYPE1 0x00040000 -+#define KG_SCH_KN_IPTOS_TC1 0x00020000 -+#define KG_SCH_KN_IPV6FL1 0x00010000 -+#define KG_SCH_KN_IPSRC2 0x00008000 -+#define KG_SCH_KN_IPDST2 0x00004000 -+#define KG_SCH_KN_PTYPE2 0x00002000 -+#define KG_SCH_KN_IPTOS_TC2 0x00001000 -+#define KG_SCH_KN_IPV6FL2 0x00000800 -+#define KG_SCH_KN_GREPTYPE 0x00000400 -+#define KG_SCH_KN_IPSEC_SPI 0x00000200 -+#define KG_SCH_KN_IPSEC_NH 0x00000100 -+#define KG_SCH_KN_IPPID 0x00000080 -+#define KG_SCH_KN_L4PSRC 0x00000004 -+#define KG_SCH_KN_L4PDST 0x00000002 -+#define KG_SCH_KN_TFLG 0x00000001 -+ -+typedef uint8_t t_GenericCodes; -+#define KG_SCH_GEN_SHIM1 0x70 -+#define KG_SCH_GEN_DEFAULT 0x10 -+#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20 -+#define KG_SCH_GEN_START_OF_FRM 0x40 -+#define KG_SCH_GEN_SHIM2 0x71 -+#define KG_SCH_GEN_IP_PID_NO_V 0x72 -+#define KG_SCH_GEN_ETH 0x03 -+#define KG_SCH_GEN_ETH_NO_V 0x73 -+#define KG_SCH_GEN_SNAP 0x04 -+#define KG_SCH_GEN_SNAP_NO_V 0x74 -+#define KG_SCH_GEN_VLAN1 0x05 -+#define KG_SCH_GEN_VLAN1_NO_V 0x75 -+#define KG_SCH_GEN_VLAN2 0x06 -+#define KG_SCH_GEN_VLAN2_NO_V 0x76 -+#define KG_SCH_GEN_ETH_TYPE 0x07 -+#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77 -+#define KG_SCH_GEN_PPP 0x08 -+#define KG_SCH_GEN_PPP_NO_V 0x78 -+#define KG_SCH_GEN_MPLS1 0x09 -+#define KG_SCH_GEN_MPLS2 0x19 -+#define KG_SCH_GEN_MPLS3 0x29 -+#define KG_SCH_GEN_MPLS1_NO_V 0x79 -+#define KG_SCH_GEN_MPLS_LAST 0x0a -+#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a -+#define KG_SCH_GEN_IPV4 0x0b -+#define KG_SCH_GEN_IPV6 0x1b -+#define KG_SCH_GEN_L3_NO_V 0x7b -+#define KG_SCH_GEN_IPV4_TUNNELED 0x0c -+#define KG_SCH_GEN_IPV6_TUNNELED 0x1c -+#define KG_SCH_GEN_MIN_ENCAP 0x2c -+#define KG_SCH_GEN_IP2_NO_V 0x7c -+#define KG_SCH_GEN_GRE 0x0d -+#define KG_SCH_GEN_GRE_NO_V 0x7d -+#define KG_SCH_GEN_TCP 0x0e -+#define KG_SCH_GEN_UDP 0x1e -+#define KG_SCH_GEN_IPSEC_AH 0x2e -+#define KG_SCH_GEN_SCTP 0x3e -+#define KG_SCH_GEN_DCCP 0x4e -+#define KG_SCH_GEN_IPSEC_ESP 0x6e -+#define KG_SCH_GEN_L4_NO_V 0x7e -+#define KG_SCH_GEN_NEXTHDR 0x7f -+/* shifts */ -+#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27 -+#define KG_SCH_PP_SHIFT_LOW_SHIFT 12 -+#define KG_SCH_PP_MASK_SHIFT 16 -+#define KG_SCH_MODE_CCOBASE_SHIFT 24 -+#define KG_SCH_DEF_MAC_ADDR_SHIFT 30 -+#define KG_SCH_DEF_TCI_SHIFT 28 -+#define KG_SCH_DEF_ENET_TYPE_SHIFT 26 -+#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24 -+#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22 -+#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20 -+#define KG_SCH_DEF_IP_ADDR_SHIFT 18 -+#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16 -+#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14 -+#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12 -+#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10 -+#define KG_SCH_DEF_L4_PORT_SHIFT 8 -+#define KG_SCH_DEF_TCP_FLAG_SHIFT 6 -+#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24 -+#define KG_SCH_GEN_MASK_SHIFT 16 -+#define KG_SCH_GEN_HT_SHIFT 8 -+#define KG_SCH_GEN_SIZE_SHIFT 24 -+#define KG_SCH_GEN_DEF_SHIFT 29 -+#define FM_PCD_KG_KGAR_NUM_SHIFT 16 -+ -+/* others */ -+#define NUM_OF_SW_DEFAULTS 3 -+#define MAX_PP_SHIFT 23 -+#define MAX_KG_SCH_SIZE 16 -+#define MASK_FOR_GENERIC_BASE_ID 0x20 -+#define MAX_HASH_SHIFT 40 -+#define MAX_KG_SCH_FQID_BIT_OFFSET 31 -+#define MAX_KG_SCH_PP_BIT_OFFSET 15 -+#define MAX_DIST_FQID_SHIFT 23 -+ -+#define GET_MASK_SEL_SHIFT(shift,i) \ -+switch (i) { \ -+ case (0):shift = 26;break; \ -+ case (1):shift = 20;break; \ -+ case (2):shift = 10;break; \ -+ case (3):shift = 4;break; \ -+ default: \ -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \ -+} -+ -+#define GET_MASK_OFFSET_SHIFT(shift,i) \ -+switch (i) { \ -+ case (0):shift = 16;break; \ -+ case (1):shift = 0;break; \ -+ case (2):shift = 28;break; \ -+ case (3):shift = 24;break; \ -+ default: \ -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \ -+} -+ -+#define GET_MASK_SHIFT(shift,i) \ -+switch (i) { \ -+ case (0):shift = 24;break; \ -+ case (1):shift = 16;break; \ -+ case (2):shift = 8;break; \ -+ case (3):shift = 0;break; \ -+ default: \ -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \ -+} -+ -+/***********************************************************************/ -+/* Keygen defines */ -+/***********************************************************************/ -+ -+#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100 -+#define NO_VALIDATION 0x70 -+#define KG_ACTION_REG_TO 1024 -+#define KG_MAX_PROFILE 255 -+#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF -+ -+ -+#endif /* __FM_KG_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c -@@ -0,0 +1,5571 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_manip.c -+ -+ @Description FM PCD manip ... -+ *//***************************************************************************/ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "string_ext.h" -+#include "debug_ext.h" -+#include "fm_pcd_ext.h" -+#include "fm_port_ext.h" -+#include "fm_muram_ext.h" -+#include "memcpy_ext.h" -+ -+#include "fm_common.h" -+#include "fm_hc.h" -+#include "fm_manip.h" -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo) -+{ -+ t_FmPcdManip *p_CurManip = p_Manip; -+ -+ if (!MANIP_IS_UNIFIED(p_Manip)) -+ p_CurManip = p_Manip; -+ else -+ { -+ /* go to first unified */ -+ while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip)) -+ p_CurManip = p_CurManip->h_PrevManip; -+ } -+ -+ switch (manipInfo) -+ { -+ case (e_MANIP_HMCT): -+ return p_CurManip->p_Hmct; -+ case (e_MANIP_HMTD): -+ return p_CurManip->h_Ad; -+ case (e_MANIP_HANDLER_TABLE_OWNER): -+ return (t_Handle)p_CurManip; -+ default: -+ return NULL; -+ } -+} -+ -+static uint16_t GetHmctSize(t_FmPcdManip *p_Manip) -+{ -+ uint16_t size = 0; -+ t_FmPcdManip *p_CurManip = p_Manip; -+ -+ if (!MANIP_IS_UNIFIED(p_Manip)) -+ return p_Manip->tableSize; -+ -+ /* accumulate sizes, starting with the first node */ -+ while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip)) -+ p_CurManip = p_CurManip->h_PrevManip; -+ -+ while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) -+ { -+ size += p_CurManip->tableSize; -+ p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip; -+ } -+ size += p_CurManip->tableSize; /* add last size */ -+ -+ return (size); -+} -+ -+static uint16_t GetDataSize(t_FmPcdManip *p_Manip) -+{ -+ uint16_t size = 0; -+ t_FmPcdManip *p_CurManip = p_Manip; -+ -+ if (!MANIP_IS_UNIFIED(p_Manip)) -+ return p_Manip->dataSize; -+ -+ /* accumulate sizes, starting with the first node */ -+ while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip)) -+ p_CurManip = p_CurManip->h_PrevManip; -+ -+ while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) -+ { -+ size += p_CurManip->dataSize; -+ p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip; -+ } -+ size += p_CurManip->dataSize; /* add last size */ -+ -+ return (size); -+} -+ -+static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams, -+ uint16_t *p_TableSize, uint8_t *p_DataSize) -+{ -+ uint8_t localDataSize, remain, tableSize = 0, dataSize = 0; -+ -+ if (p_FmPcdManipParams->u.hdr.rmv) -+ { -+ switch (p_FmPcdManipParams->u.hdr.rmvParams.type) -+ { -+ case (e_FM_PCD_MANIP_RMV_GENERIC): -+ tableSize += HMCD_BASIC_SIZE; -+ break; -+ case (e_FM_PCD_MANIP_RMV_BY_HDR): -+ switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type) -+ { -+ case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2): -+#if (DPAA_VERSION >= 11) -+ case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP): -+ case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START): -+#endif /* (DPAA_VERSION >= 11) */ -+ tableSize += HMCD_BASIC_SIZE; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, -+ ("Unknown byHdr.type")); -+ } -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, -+ ("Unknown rmvParams.type")); -+ } -+ } -+ -+ if (p_FmPcdManipParams->u.hdr.insrt) -+ { -+ switch (p_FmPcdManipParams->u.hdr.insrtParams.type) -+ { -+ case (e_FM_PCD_MANIP_INSRT_GENERIC): -+ remain = -+ (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size -+ % 4); -+ if (remain) -+ localDataSize = -+ (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size -+ + 4 - remain); -+ else -+ localDataSize = -+ p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size; -+ tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize); -+ break; -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR): -+ { -+ switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type) -+ { -+ -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2): -+ tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE; -+ switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2) -+ { -+ case (e_FM_PCD_MANIP_HDR_INSRT_MPLS): -+ case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE): -+ dataSize += -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+ } -+ break; -+#if (DPAA_VERSION >= 11) -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP): -+ tableSize += -+ (HMCD_BASIC_SIZE + HMCD_PTR_SIZE -+ + HMCD_PARAM_SIZE -+ + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size); -+ dataSize += 2; -+ break; -+ -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP): -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE): -+ tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE); -+ -+ break; -+ -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP): -+ tableSize += -+ (HMCD_BASIC_SIZE -+ + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size); -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, -+ ("Unknown byHdr.type")); -+ } -+ } -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, -+ ("Unknown insrtParams.type")); -+ } -+ } -+ -+ if (p_FmPcdManipParams->u.hdr.fieldUpdate) -+ { -+ switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type) -+ { -+ case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN): -+ tableSize += HMCD_BASIC_SIZE; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType -+ == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN) -+ { -+ tableSize += HMCD_PTR_SIZE; -+ dataSize += DSCP_TO_VLAN_TABLE_SIZE; -+ } -+ break; -+ case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4): -+ tableSize += HMCD_BASIC_SIZE; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV4_ID) -+ { -+ tableSize += HMCD_PARAM_SIZE; -+ dataSize += 2; -+ } -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV4_SRC) -+ tableSize += HMCD_IPV4_ADDR_SIZE; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV4_DST) -+ tableSize += HMCD_IPV4_ADDR_SIZE; -+ break; -+ case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6): -+ tableSize += HMCD_BASIC_SIZE; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV6_SRC) -+ tableSize += HMCD_IPV6_ADDR_SIZE; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV6_DST) -+ tableSize += HMCD_IPV6_ADDR_SIZE; -+ break; -+ case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP): -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates -+ == HDR_MANIP_TCP_UDP_CHECKSUM) -+ /* we implement this case with the update-checksum descriptor */ -+ tableSize += HMCD_BASIC_SIZE; -+ else -+ /* we implement this case with the TCP/UDP-update descriptor */ -+ tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, -+ ("Unknown fieldUpdateParams.type")); -+ } -+ } -+ -+ if (p_FmPcdManipParams->u.hdr.custom) -+ { -+ switch (p_FmPcdManipParams->u.hdr.customParams.type) -+ { -+ case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE): -+ { -+ tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE; -+ dataSize += -+ p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize; -+ if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType -+ == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4) -+ && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)) -+ dataSize += 2; -+ } -+ break; -+ case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE): -+ tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, -+ ("Unknown customParams.type")); -+ } -+ } -+ -+ *p_TableSize = tableSize; -+ *p_DataSize = dataSize; -+ -+ return E_OK; -+} -+ -+static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo, -+ uint8_t *parseArrayOffset) -+{ -+ e_NetHeaderType hdr = p_HdrInfo->hdr; -+ e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex; -+ bool byField = p_HdrInfo->byField; -+ t_FmPcdFields field; -+ -+ if (byField) -+ field = p_HdrInfo->fullField; -+ -+ if (byField) -+ { -+ switch (hdr) -+ { -+ case (HEADER_TYPE_ETH): -+ switch (field.eth) -+ { -+ case (NET_HEADER_FIELD_ETH_TYPE): -+ *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET; -+ break; -+ default: -+ RETURN_ERROR( -+ MAJOR, -+ E_NOT_SUPPORTED, -+ ("Header manipulation of the type Ethernet with this field not supported")); -+ } -+ break; -+ case (HEADER_TYPE_VLAN): -+ switch (field.vlan) -+ { -+ case (NET_HEADER_FIELD_VLAN_TCI): -+ if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) -+ || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) -+ *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET; -+ else -+ if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) -+ *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET; -+ break; -+ default: -+ RETURN_ERROR( -+ MAJOR, -+ E_NOT_SUPPORTED, -+ ("Header manipulation of the type VLAN with this field not supported")); -+ } -+ break; -+ default: -+ RETURN_ERROR( -+ MAJOR, -+ E_NOT_SUPPORTED, -+ ("Header manipulation of this header by field not supported")); -+ } -+ } -+ else -+ { -+ switch (hdr) -+ { -+ case (HEADER_TYPE_ETH): -+ *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET; -+ break; -+ case (HEADER_TYPE_USER_DEFINED_SHIM1): -+ *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET; -+ break; -+ case (HEADER_TYPE_USER_DEFINED_SHIM2): -+ *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET; -+ break; -+ case (HEADER_TYPE_LLC_SNAP): -+ *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET; -+ break; -+ case (HEADER_TYPE_PPPoE): -+ *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET; -+ break; -+ case (HEADER_TYPE_MPLS): -+ if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) -+ || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) -+ *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET; -+ else -+ if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST) -+ *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET; -+ break; -+ case (HEADER_TYPE_IPv4): -+ case (HEADER_TYPE_IPv6): -+ if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) -+ || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) -+ *parseArrayOffset = CC_PC_PR_IP1_OFFSET; -+ else -+ if (hdrIndex == e_FM_PCD_HDR_INDEX_2) -+ *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET; -+ break; -+ case (HEADER_TYPE_MINENCAP): -+ *parseArrayOffset = CC_PC_PR_MINENC_OFFSET; -+ break; -+ case (HEADER_TYPE_GRE): -+ *parseArrayOffset = CC_PC_PR_GRE_OFFSET; -+ break; -+ case (HEADER_TYPE_TCP): -+ case (HEADER_TYPE_UDP): -+ case (HEADER_TYPE_IPSEC_AH): -+ case (HEADER_TYPE_IPSEC_ESP): -+ case (HEADER_TYPE_DCCP): -+ case (HEADER_TYPE_SCTP): -+ *parseArrayOffset = CC_PC_PR_L4_OFFSET; -+ break; -+ case (HEADER_TYPE_CAPWAP): -+ case (HEADER_TYPE_CAPWAP_DTLS): -+ *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET; -+ break; -+ default: -+ RETURN_ERROR( -+ MAJOR, -+ E_NOT_SUPPORTED, -+ ("Header manipulation of this header is not supported")); -+ } -+ } -+ return E_OK; -+} -+ -+static t_Error BuildHmct(t_FmPcdManip *p_Manip, -+ t_FmPcdManipParams *p_FmPcdManipParams, -+ uint8_t *p_DestHmct, uint8_t *p_DestData, bool new) -+{ -+ uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData; -+ uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr; -+ uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData = -+ p_DestData; -+ t_Handle h_FmPcd = p_Manip->h_FmPcd; -+ uint8_t j = 0; -+ -+ if (p_FmPcdManipParams->u.hdr.rmv) -+ { -+ if (p_FmPcdManipParams->u.hdr.rmvParams.type -+ == e_FM_PCD_MANIP_RMV_GENERIC) -+ { -+ /* initialize HMCD */ -+ tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT; -+ /* tmp, should be conditional */ -+ tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset -+ << HMCD_RMV_OFFSET_SHIFT; -+ tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size -+ << HMCD_RMV_SIZE_SHIFT; -+ } -+ else -+ if (p_FmPcdManipParams->u.hdr.rmvParams.type -+ == e_FM_PCD_MANIP_RMV_BY_HDR) -+ { -+ switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type) -+ { -+ case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2): -+ { -+ uint8_t hmcdOpt; -+ -+ /* initialize HMCD */ -+ tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT; -+ -+ switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2) -+ { -+ case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET): -+ hmcdOpt = HMCD_RMV_L2_ETHERNET; -+ break; -+ case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS): -+ hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS; -+ break; -+ case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS): -+ hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS; -+ break; -+ case (e_FM_PCD_MANIP_HDR_RMV_MPLS): -+ hmcdOpt = HMCD_RMV_L2_MPLS; -+ break; -+ case (e_FM_PCD_MANIP_HDR_RMV_PPPOE): -+ hmcdOpt = HMCD_RMV_L2_PPPOE; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+ } -+ tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT; -+ break; -+ } -+#if (DPAA_VERSION >= 11) -+ case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP): -+ tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV) -+ << HMCD_OC_SHIFT; -+ break; -+ case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START): -+ { -+ uint8_t prsArrayOffset; -+ t_Error err = E_OK; -+ -+ tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL) -+ << HMCD_OC_SHIFT; -+ -+ err = -+ GetPrOffsetByHeaderOrField( -+ &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo, -+ &prsArrayOffset); -+ ASSERT_COND(!err); -+ /* was previously checked */ -+ -+ tmpReg |= ((uint32_t)prsArrayOffset << 16); -+ } -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+ default: -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("manip header remove by hdr type!")); -+ } -+ } -+ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ /* advance to next command */ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ } -+ -+ if (p_FmPcdManipParams->u.hdr.insrt) -+ { -+ if (p_FmPcdManipParams->u.hdr.insrtParams.type -+ == e_FM_PCD_MANIP_INSRT_GENERIC) -+ { -+ /* initialize HMCD */ -+ if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace) -+ tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE) -+ << HMCD_OC_SHIFT; -+ else -+ tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT; -+ -+ tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset -+ << HMCD_INSRT_OFFSET_SHIFT; -+ tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size -+ << HMCD_INSRT_SIZE_SHIFT; -+ -+ size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size; -+ p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data; -+ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ -+ /* initialize data to be inserted */ -+ /* if size is not a multiple of 4, padd with 0's */ -+ origSize = size; -+ remain = (uint8_t)(size % 4); -+ if (remain) -+ { -+ size += (uint8_t)(4 - remain); -+ p_LocalData = (uint32_t *)XX_Malloc(size); -+ memset((uint8_t *)p_LocalData, 0, size); -+ memcpy((uint8_t *)p_LocalData, p_UsrData, origSize); -+ } -+ else -+ p_LocalData = (uint32_t*)p_UsrData; -+ -+ /* initialize data and advance pointer to next command */ -+ MemCpy8(p_TmpHmct, p_LocalData, size); -+ p_TmpHmct += size / sizeof(uint32_t); -+ -+ if (remain) -+ XX_Free(p_LocalData); -+ } -+ -+ else -+ if (p_FmPcdManipParams->u.hdr.insrtParams.type -+ == e_FM_PCD_MANIP_INSRT_BY_HDR) -+ { -+ switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type) -+ { -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2): -+ { -+ uint8_t hmcdOpt; -+ -+ /* initialize HMCD */ -+ tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT) -+ << HMCD_OC_SHIFT; -+ -+ switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2) -+ { -+ case (e_FM_PCD_MANIP_HDR_INSRT_MPLS): -+ if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update) -+ hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS; -+ else -+ hmcdOpt = HMCD_INSRT_L2_MPLS; -+ break; -+ case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE): -+ hmcdOpt = HMCD_INSRT_L2_PPPOE; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+ } -+ tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT; -+ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ -+ /* set size and pointer of user's data */ -+ size = -+ (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size; -+ -+ ASSERT_COND(p_TmpData); -+ MemCpy8( -+ p_TmpData, -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data, -+ size); -+ tmpReg = -+ (size << HMCD_INSRT_L2_SIZE_SHIFT) -+ | (uint32_t)(XX_VirtToPhys(p_TmpData) -+ - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)); -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ p_TmpHmct += HMCD_PTR_SIZE / 4; -+ p_TmpData += size; -+ } -+ break; -+#if (DPAA_VERSION >= 11) -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP): -+ tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT) -+ << HMCD_OC_SHIFT; -+ if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum) -+ tmpReg |= HMCD_IP_L4_CS_CALC; -+ if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode -+ == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS) -+ tmpReg |= HMCD_IP_OR_QOS; -+ tmpReg |= -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset -+ & HMCD_IP_LAST_PID_MASK; -+ tmpReg |= -+ ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size -+ << HMCD_IP_SIZE_SHIFT) -+ & HMCD_IP_SIZE_MASK); -+ if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite) -+ tmpReg |= HMCD_IP_DF_MODE; -+ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ -+ /* set IP id */ -+ ASSERT_COND(p_TmpData); -+ WRITE_UINT16( -+ *(uint16_t*)p_TmpData, -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id); -+ WRITE_UINT32( -+ *p_TmpHmct, -+ (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase))); -+ p_TmpData += 2; -+ p_TmpHmct += HMCD_PTR_SIZE / 4; -+ -+ WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset); -+ p_TmpHmct += HMCD_PARAM_SIZE / 4; -+ -+ MemCpy8( -+ p_TmpHmct, -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data, -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size); -+ p_TmpHmct += -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size -+ / 4; -+ break; -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE): -+ tmpReg = HMCD_INSRT_UDP_LITE; -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP): -+ tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT) -+ << HMCD_OC_SHIFT; -+ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ -+ MemCpy8( -+ p_TmpHmct, -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data, -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size); -+ p_TmpHmct += -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size -+ / 4; -+ break; -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP): -+ tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT) -+ << HMCD_OC_SHIFT; -+ tmpReg |= HMCD_CAPWAP_INSRT; -+ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ -+ MemCpy8( -+ p_TmpHmct, -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data, -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size); -+ p_TmpHmct += -+ p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size -+ / 4; -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+ default: -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("manip header insert by header type!")); -+ -+ } -+ } -+ } -+ -+ if (p_FmPcdManipParams->u.hdr.fieldUpdate) -+ { -+ switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type) -+ { -+ case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN): -+ /* set opcode */ -+ tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE) -+ << HMCD_OC_SHIFT; -+ -+ /* set mode & table pointer */ -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType -+ == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN) -+ { -+ /* set Mode */ -+ tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI) -+ << HMCD_VLAN_PRI_REP_MODE_SHIFT; -+ /* set VPRI default */ -+ tmpReg |= -+ p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal; -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ /* write the table pointer into the Manip descriptor */ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ -+ tmpReg = 0; -+ ASSERT_COND(p_TmpData); -+ for (i = 0; i < HMCD_DSCP_VALUES; i++) -+ { -+ /* first we build from each 8 values a 32bit register */ -+ tmpReg |= -+ (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]) -+ << (32 - 4 * (j + 1)); -+ j++; -+ /* Than we write this register to the next table word -+ * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */ -+ if ((i % 8) == 7) -+ { -+ WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1), -+ tmpReg); -+ tmpReg = 0; -+ j = 0; -+ } -+ } -+ -+ WRITE_UINT32( -+ *p_TmpHmct, -+ (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase))); -+ p_TmpHmct += HMCD_PTR_SIZE / 4; -+ -+ p_TmpData += DSCP_TO_VLAN_TABLE_SIZE; -+ } -+ else -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType -+ == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI) -+ { -+ /* set Mode */ -+ /* line commented out as it has no-side-effect ('0' value). */ -+ /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/; -+ /* set VPRI parameter */ -+ tmpReg |= -+ p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri; -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ } -+ break; -+ -+ case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4): -+ /* set opcode */ -+ tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV4_TTL) -+ tmpReg |= HMCD_IPV4_UPDATE_TTL; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV4_TOS) -+ { -+ tmpReg |= HMCD_IPV4_UPDATE_TOS; -+ tmpReg |= -+ p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos -+ << HMCD_IPV4_UPDATE_TOS_SHIFT; -+ } -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV4_ID) -+ tmpReg |= HMCD_IPV4_UPDATE_ID; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV4_SRC) -+ tmpReg |= HMCD_IPV4_UPDATE_SRC; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV4_DST) -+ tmpReg |= HMCD_IPV4_UPDATE_DST; -+ /* write the first 4 bytes of the descriptor */ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV4_ID) -+ { -+ ASSERT_COND(p_TmpData); -+ WRITE_UINT16( -+ *(uint16_t*)p_TmpData, -+ p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id); -+ WRITE_UINT32( -+ *p_TmpHmct, -+ (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase))); -+ p_TmpData += 2; -+ p_TmpHmct += HMCD_PTR_SIZE / 4; -+ } -+ -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV4_SRC) -+ { -+ WRITE_UINT32( -+ *p_TmpHmct, -+ p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src); -+ p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4; -+ } -+ -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates -+ & HDR_MANIP_IPV4_DST) -+ { -+ WRITE_UINT32( -+ *p_TmpHmct, -+ p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst); -+ p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4; -+ } -+ break; -+ -+ case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6): -+ /* set opcode */ -+ tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates -+ & HDR_MANIP_IPV6_HL) -+ tmpReg |= HMCD_IPV6_UPDATE_HL; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates -+ & HDR_MANIP_IPV6_TC) -+ { -+ tmpReg |= HMCD_IPV6_UPDATE_TC; -+ tmpReg |= -+ p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass -+ << HMCD_IPV6_UPDATE_TC_SHIFT; -+ } -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates -+ & HDR_MANIP_IPV6_SRC) -+ tmpReg |= HMCD_IPV6_UPDATE_SRC; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates -+ & HDR_MANIP_IPV6_DST) -+ tmpReg |= HMCD_IPV6_UPDATE_DST; -+ /* write the first 4 bytes of the descriptor */ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates -+ & HDR_MANIP_IPV6_SRC) -+ { -+ for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4) -+ { -+ memcpy(&tmp_ipv6_addr, -+ &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i], -+ sizeof(uint32_t)); -+ WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr); -+ p_TmpHmct += HMCD_PTR_SIZE / 4; -+ } -+ } -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates -+ & HDR_MANIP_IPV6_DST) -+ { -+ for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4) -+ { -+ memcpy(&tmp_ipv6_addr, -+ &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i], -+ sizeof(uint32_t)); -+ WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr); -+ p_TmpHmct += HMCD_PTR_SIZE / 4; -+ } -+ } -+ break; -+ -+ case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP): -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates -+ == HDR_MANIP_TCP_UDP_CHECKSUM) -+ { -+ /* we implement this case with the update-checksum descriptor */ -+ /* set opcode */ -+ tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM) -+ << HMCD_OC_SHIFT; -+ /* write the first 4 bytes of the descriptor */ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ } -+ else -+ { -+ /* we implement this case with the TCP/UDP update descriptor */ -+ /* set opcode */ -+ tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE) -+ << HMCD_OC_SHIFT; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates -+ & HDR_MANIP_TCP_UDP_DST) -+ tmpReg |= HMCD_TCP_UDP_UPDATE_DST; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates -+ & HDR_MANIP_TCP_UDP_SRC) -+ tmpReg |= HMCD_TCP_UDP_UPDATE_SRC; -+ /* write the first 4 bytes of the descriptor */ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ -+ tmpReg = 0; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates -+ & HDR_MANIP_TCP_UDP_SRC) -+ tmpReg |= -+ ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src) -+ << HMCD_TCP_UDP_UPDATE_SRC_SHIFT; -+ if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates -+ & HDR_MANIP_TCP_UDP_DST) -+ tmpReg |= -+ ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst); -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ p_TmpHmct += HMCD_PTR_SIZE / 4; -+ } -+ break; -+ -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, -+ ("Unknown fieldUpdateParams.type")); -+ } -+ } -+ -+ if (p_FmPcdManipParams->u.hdr.custom) -+ { -+ switch (p_FmPcdManipParams->u.hdr.customParams.type) -+ { -+ case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE): -+ /* set opcode */ -+ tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT; -+ -+ if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl) -+ tmpReg |= HMCD_IP_REPLACE_TTL_HL; -+ if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType -+ == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6) -+ /* line commented out as it has no-side-effect ('0' value). */ -+ /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/; -+ else -+ if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType -+ == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4) -+ { -+ tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6; -+ if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id) -+ tmpReg |= HMCD_IP_REPLACE_ID; -+ } -+ else -+ RETURN_ERROR( -+ MINOR, -+ E_NOT_SUPPORTED, -+ ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set.")); -+ -+ /* write the first 4 bytes of the descriptor */ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ -+ p_TmpHmct += HMCD_BASIC_SIZE / 4; -+ -+ size = -+ p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize; -+ ASSERT_COND(p_TmpData); -+ MemCpy8( -+ p_TmpData, -+ p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr, -+ size); -+ tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT); -+ tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData) -+ - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)); -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ p_TmpHmct += HMCD_PTR_SIZE / 4; -+ p_TmpData += size; -+ -+ if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType -+ == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4) -+ && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)) -+ { -+ WRITE_UINT16( -+ *(uint16_t*)p_TmpData, -+ p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id); -+ WRITE_UINT32( -+ *p_TmpHmct, -+ (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase))); -+ p_TmpData += 2; -+ } -+ p_TmpHmct += HMCD_PTR_SIZE / 4; -+ break; -+ case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE): -+ /* set opcode */ -+ tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT; -+ tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT; -+ tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT; -+ tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT; -+ if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask) -+ tmpReg |= HMCD_GEN_FIELD_MASK_EN; -+ -+ /* write the first 4 bytes of the descriptor */ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ /* save a pointer to the "last" indication word */ -+ p_Last = p_TmpHmct; -+ -+ p_TmpHmct += HMCD_BASIC_SIZE/4; -+ -+ if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask) -+ { -+ tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT; -+ tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT; -+ /* write the next 4 bytes of the descriptor */ -+ WRITE_UINT32(*p_TmpHmct, tmpReg); -+ } -+ p_TmpHmct += HMCD_PARAM_SIZE/4; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, -+ ("Unknown customParams.type")); -+ } -+ } -+ -+ /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table -+ the old table and should be freed */ -+ if (p_FmPcdManipParams->h_NextManip -+ && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) -+ && (MANIP_DONT_REPARSE(p_Manip))) -+ { -+ if (new) -+ { -+ /* If this is the first time this manip is created we need to free unused memory. If it -+ * is a dynamic changes case, the memory used is either the CC shadow or the existing -+ * table - no allocation, no free */ -+ MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip); -+ -+ p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST; -+ } -+ } -+ else -+ { -+ ASSERT_COND(p_Last); -+ /* set the "last" indication on the last command of the current table */ -+ WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST); -+ } -+ -+ return E_OK; -+} -+ -+static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip, -+ t_FmPcdManipParams *p_FmPcdManipParams) -+{ -+ t_FmPcdManip *p_CurManip; -+ t_Error err; -+ uint32_t nextSize = 0, totalSize; -+ uint16_t tmpReg; -+ uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr; -+ -+ /* set Manip structure */ -+ -+ p_Manip->dontParseAfterManip = -+ p_FmPcdManipParams->u.hdr.dontParseAfterManip; -+ -+ if (p_FmPcdManipParams->h_NextManip) -+ { /* Next Header manipulation exists */ -+ p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip); -+ -+ if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip) -+ nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip) -+ + GetDataSize(p_FmPcdManipParams->h_NextManip)); -+ else /* either parsing is required or next manip is Frag; no table merging. */ -+ p_Manip->cascaded = TRUE; -+ /* pass up the "cascaded" attribute. The whole chain is cascaded -+ * if something is cascaded along the way. */ -+ if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip)) -+ p_Manip->cascaded = TRUE; -+ } -+ -+ /* Allocate new table */ -+ /* calculate table size according to manip parameters */ -+ err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize, -+ &p_Manip->dataSize); -+ if (err) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize); -+ -+ p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem( -+ ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4); -+ if (!p_Manip->p_Hmct) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed")); -+ -+ if (p_Manip->dataSize) -+ p_Manip->p_Data = -+ (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize)); -+ -+ /* update shadow size to allow runtime replacement of Header manipulation */ -+ /* The allocated shadow is divided as follows: -+ 0 . . . 16 . . . -+ -------------------------------- -+ | Shadow | Shadow HMTD | -+ | HMTD | Match Table | -+ | (16 bytes) | (maximal size) | -+ -------------------------------- -+ */ -+ -+ err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16), -+ (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN); -+ if (err != E_OK) -+ { -+ FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM allocation for HdrManip node shadow")); -+ } -+ -+ if (p_FmPcdManipParams->h_NextManip -+ && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) -+ && (MANIP_DONT_REPARSE(p_Manip))) -+ { -+ p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip, -+ e_MANIP_HMCT); -+ p_CurManip = p_FmPcdManipParams->h_NextManip; -+ /* Run till the last Manip (which is the first to configure) */ -+ while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) -+ p_CurManip = p_CurManip->h_NextManip; -+ -+ while (p_CurManip) -+ { -+ /* If this is a unified table, point to the part of the table -+ * which is the relative offset in HMCT. -+ */ -+ p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, -+ (p_Manip->tableSize + -+ (PTR_TO_UINT(p_CurManip->p_Hmct) - -+ PTR_TO_UINT(p_OldHmct)))); -+ if (p_CurManip->p_Data) -+ p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, -+ (p_Manip->tableSize + -+ (PTR_TO_UINT(p_CurManip->p_Data) - -+ PTR_TO_UINT(p_OldHmct)))); -+ else -+ p_TmpDataPtr = NULL; -+ -+ BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr, -+ p_TmpDataPtr, FALSE); -+ /* update old manip table pointer */ -+ MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr); -+ MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr); -+ -+ p_CurManip = p_CurManip->h_PrevManip; -+ } -+ /* We copied the HMCT to create a new large HMCT so we can free the old one */ -+ FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip), -+ p_OldHmct); -+ } -+ -+ /* Fill table */ -+ err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, -+ p_Manip->p_Data, TRUE); -+ if (err) -+ { -+ FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ /* Build HMTD (table descriptor) */ -+ tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */ -+ -+ /* add parseAfterManip */ -+ if (!p_Manip->dontParseAfterManip) -+ tmpReg |= HMTD_CFG_PRS_AFTER_HM; -+ -+ /* create cascade */ -+ /*if (p_FmPcdManipParams->h_NextManip -+ && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/ -+ if (p_Manip->cascaded) -+ { -+ uint16_t nextAd; -+ /* indicate that there's another HM table descriptor */ -+ tmpReg |= HMTD_CFG_NEXT_AD_EN; -+ /* get address of next HMTD (table descriptor; h_Ad). -+ * If the next HMTD was removed due to table unifing, get the address -+ * of the "next next" as written in the h_Ad of the next h_Manip node. -+ */ -+ if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST) -+ nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4); -+ else -+ nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx; -+ -+ WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd); -+ } -+ -+ WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg); -+ WRITE_UINT32( -+ ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr, -+ (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase))); -+ -+ WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC); -+ -+ if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST) -+ { -+ /* The HMTD of the next Manip is never going to be used */ -+ if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate) -+ FM_MURAM_FreeMem( -+ ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram, -+ ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad); -+ else -+ XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad); -+ ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL; -+ } -+ -+ return E_OK; -+} -+ -+static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip, -+ t_FmPcdManipParams *p_FmPcdManipParams) -+{ -+ uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL; -+ uint16_t newSize; -+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; -+ t_Error err; -+ t_FmPcdManip *p_CurManip = p_Manip; -+ -+ err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize); -+ if (err) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ /* check coherency of new table parameters */ -+ if (newSize > p_Manip->tableSize) -+ RETURN_ERROR( -+ MINOR, -+ E_INVALID_VALUE, -+ ("New Hdr Manip configuration requires larger size than current one (command table).")); -+ if (newDataSize > p_Manip->dataSize) -+ RETURN_ERROR( -+ MINOR, -+ E_INVALID_VALUE, -+ ("New Hdr Manip configuration requires larger size than current one (data).")); -+ if (p_FmPcdManipParams->h_NextManip) -+ RETURN_ERROR( -+ MINOR, E_INVALID_VALUE, -+ ("New Hdr Manip configuration can not contain h_NextManip.")); -+ if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize)) -+ RETURN_ERROR( -+ MINOR, -+ E_INVALID_VALUE, -+ ("New Hdr Manip configuration in a chained manipulation requires different size than current one.")); -+ if (p_Manip->dontParseAfterManip -+ != p_FmPcdManipParams->u.hdr.dontParseAfterManip) -+ RETURN_ERROR( -+ MINOR, -+ E_INVALID_VALUE, -+ ("New Hdr Manip configuration differs in dontParseAfterManip value.")); -+ -+ p_Manip->tableSize = newSize; -+ p_Manip->dataSize = newDataSize; -+ -+ /* Build the new table in the shadow */ -+ if (!MANIP_IS_UNIFIED(p_Manip)) -+ { -+ p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16); -+ if (p_Manip->p_Data) -+ p_TmpDataPtr = -+ (uint8_t*)PTR_MOVE(p_TmpHmctPtr, -+ (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct))); -+ -+ BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data, -+ FALSE); -+ } -+ else -+ { -+ p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT); -+ ASSERT_COND(p_WholeHmct); -+ -+ /* Run till the last Manip (which is the first to configure) */ -+ while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) -+ p_CurManip = p_CurManip->h_NextManip; -+ -+ while (p_CurManip) -+ { -+ /* If this is a non-head node in a unified table, point to the part of the shadow -+ * which is the relative offset in HMCT. -+ * else, point to the beginning of the -+ * shadow table (we save 16 for the HMTD. -+ */ -+ p_TmpHmctPtr = -+ (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, -+ (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct))); -+ if (p_CurManip->p_Data) -+ p_TmpDataPtr = -+ (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, -+ (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct))); -+ -+ BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr, -+ p_TmpDataPtr, FALSE); -+ p_CurManip = p_CurManip->h_PrevManip; -+ } -+ } -+ -+ return E_OK; -+} -+ -+static t_Error CreateManipActionBackToOrig( -+ t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams) -+{ -+ uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr; -+ t_FmPcdManip *p_CurManip = p_Manip; -+ -+ /* Build the new table in the shadow */ -+ if (!MANIP_IS_UNIFIED(p_Manip)) -+ BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data, -+ FALSE); -+ else -+ { -+ p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT); -+ ASSERT_COND(p_WholeHmct); -+ -+ /* Run till the last Manip (which is the first to configure) */ -+ while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip)) -+ p_CurManip = p_CurManip->h_NextManip; -+ -+ while (p_CurManip) -+ { -+ /* If this is a unified table, point to the part of the table -+ * which is the relative offset in HMCT. -+ */ -+ p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/ -+ p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/ -+ -+ BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr, -+ p_TmpDataPtr, FALSE); -+ -+ p_CurManip = p_CurManip->h_PrevManip; -+ } -+ } -+ -+ return E_OK; -+} -+ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ t_Handle p_Ad; -+ uint32_t tmpReg32 = 0; -+ SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); -+ -+ switch (p_Manip->opcode) -+ { -+ case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET) -+ { -+ tmpReg32 = -+ *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets; -+ tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16); -+ *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets = -+ tmpReg32; -+ p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET; -+ p_Manip->icOffset = icOffset; -+ } -+ else -+ { -+ if (p_Manip->icOffset != icOffset) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("this manipulation was updated previously by different value");); -+ } -+ break; -+ case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): -+ if (p_Manip->h_Frag) -+ { -+ if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET) -+ { -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets); -+ tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16); -+ WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32); -+ p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET; -+ p_Manip->icOffset = icOffset; -+ } -+ else -+ { -+ if (p_Manip->icOffset != icOffset) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value");); -+ } -+ } -+ break; -+ } -+ -+ return E_OK; -+} -+ -+static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix( -+ t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate) -+{ -+ -+ t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad; -+ t_FmPortGetSetCcParams fmPortGetSetCcParams; -+ t_Error err; -+ uint32_t tmpReg32; -+ -+ memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR( -+ (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX), -+ E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE); -+ -+ if (p_Manip->updateParams) -+ { -+ if ((!(p_Manip->updateParams & OFFSET_OF_PR)) -+ || (p_Manip->shadowUpdateParams & OFFSET_OF_PR)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_STATE, -+ ("in this stage parameters from Port has not be updated")); -+ -+ fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams; -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO; -+ fmPortGetSetCcParams.setCcParams.psoSize = 16; -+ -+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_STATE, -+ ("Parser result offset wasn't configured previousely")); -+#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 -+ ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16)); -+#endif -+ } -+ else -+ if (validate) -+ { -+ if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) -+ || (p_Manip->updateParams & OFFSET_OF_PR)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_STATE, -+ ("in this stage parameters from Port has be updated")); -+ fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams; -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO; -+ fmPortGetSetCcParams.setCcParams.psoSize = 16; -+ -+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_STATE, -+ ("Parser result offset wasn't configured previousely")); -+ -+ } -+ -+ ASSERT_COND(p_Ad); -+ -+ if (p_Manip->updateParams & OFFSET_OF_PR) -+ { -+ tmpReg32 = 0; -+ tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset; -+ WRITE_UINT32(p_Ad->matchTblPtr, -+ (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32)); -+ p_Manip->updateParams &= ~OFFSET_OF_PR; -+ p_Manip->shadowUpdateParams |= OFFSET_OF_PR; -+ } -+ else -+ if (validate) -+ { -+ tmpReg32 = GET_UINT32(p_Ad->matchTblPtr); -+ if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("this manipulation was updated previousely by different value");); -+ } -+ -+ return E_OK; -+} -+ -+static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree) -+{ -+ t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad; -+ t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL; -+ uint32_t tmpReg32 = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; -+ -+ if (p_Manip->updateParams) -+ { -+ -+ if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) || -+ ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA))) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); -+ p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree); -+ if (!p_SavedManipParams) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type")); -+ p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset; -+ -+ tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets); -+ tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16); -+ WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32); -+ -+ p_Manip->updateParams &= ~OFFSET_OF_DATA; -+ p_Manip->shadowUpdateParams |= OFFSET_OF_DATA; -+ } -+ else if (validate) -+ { -+ -+ p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree); -+ if (!p_SavedManipParams) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type")); -+ if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value")); -+ } -+ -+ return E_OK; -+} -+ -+static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort, -+ t_FmPcdManip *p_Manip, -+ t_Handle h_Ad, -+ bool validate, -+ t_Handle h_FmTree) -+{ -+ t_AdOfTypeContLookup *p_Ad; -+ t_FmPortGetSetCcParams fmPortGetSetCcParams; -+ t_Error err; -+ uint32_t tmpReg32 = 0; -+ t_FmPcdCcSavedManipParams *p_SavedManipParams; -+ -+ UNUSED(h_Ad); -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) || -+ (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; -+ -+ if (p_Manip->updateParams) -+ { -+ if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) || -+ ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA))) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); -+ fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams; -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY; -+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; -+ /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */ -+ fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1; -+ -+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely")); -+ -+ p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams)); -+ p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; -+ -+#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 -+ ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16)); -+#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */ -+ -+ FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams); -+ } -+ else if (validate) -+ { -+ if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) || -+ ((p_Manip->updateParams & OFFSET_OF_DATA))) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated")); -+ fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams; -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY; -+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; -+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely")); -+ } -+ -+ if (p_Manip->updateParams) -+ { -+ tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets); -+ tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16); -+ WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32); -+ -+ p_Manip->updateParams &= ~OFFSET_OF_DATA; -+ p_Manip->shadowUpdateParams |= OFFSET_OF_DATA; -+ p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; -+ } -+ else if (validate) -+ { -+ if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value")); -+ } -+ -+ return E_OK; -+} -+ -+static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd, -+ t_Handle h_FmPort, -+ t_FmPcdManip *p_Manip, -+ t_Handle h_Ad, -+ bool validate) -+{ -+ t_CapwapReasmPram *p_ReassmTbl; -+ t_Error err; -+ t_FmPortGetSetCcParams fmPortGetSetCcParams; -+ uint8_t i = 0; -+ uint16_t size; -+ uint32_t tmpReg32; -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE); -+ -+ if (p_Manip->h_FmPcd != h_FmPcd) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("handler of PCD previously was initiated by different value")); -+ -+ UNUSED(h_Ad); -+ -+ memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); -+ p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag; -+ -+ if (p_Manip->updateParams) -+ { -+ if ((!(p_Manip->updateParams & NUM_OF_TASKS) && -+ !(p_Manip->updateParams & OFFSET_OF_DATA) && -+ !(p_Manip->updateParams & OFFSET_OF_PR) && -+ !(p_Manip->updateParams & HW_PORT_ID)) || -+ ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) || -+ (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) || -+ (p_Manip->shadowUpdateParams & HW_PORT_ID))) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated")); -+ -+ fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams; -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN; -+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; -+ -+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely")); -+ if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely")); -+ if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated")); -+#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 -+ ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0); -+#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */ -+ } -+ else if (validate) -+ { -+ if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) && -+ !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) && -+ !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) && -+ !(p_Manip->shadowUpdateParams & HW_PORT_ID)) && -+ ((p_Manip->updateParams & NUM_OF_TASKS) || -+ (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) || -+ (p_Manip->updateParams & HW_PORT_ID))) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated")); -+ -+ fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams; -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN; -+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; -+ -+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously")); -+ if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously")); -+ if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated")); -+ } -+ -+ if (p_Manip->updateParams) -+ { -+ if (p_Manip->updateParams & NUM_OF_TASKS) -+ { -+ /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */ -+ size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks); -+ if (size > 255) -+ RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256")); -+ -+ p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks; -+ -+ /*p_ReassmFrmDescrIndxPoolTbl*/ -+ p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl = -+ (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)(size + 1), -+ 4); -+ if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table")); -+ -+ MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1)); -+ -+ for ( i = 0; i < size; i++) -+ WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1)); -+ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase); -+ -+ WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32); -+ -+ /*p_ReassmFrmDescrPoolTbl*/ -+ p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl = -+ (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE), -+ 4); -+ -+ if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table")); -+ -+ MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE)); -+ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase); -+ -+ WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32); -+ -+ /*p_TimeOutTbl*/ -+ -+ p_Manip->capwapFragParams.p_TimeOutTbl = -+ (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE), -+ 4); -+ -+ if (!p_Manip->capwapFragParams.p_TimeOutTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table")); -+ -+ MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE)); -+ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase); -+ WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32); -+ -+ p_Manip->updateParams &= ~NUM_OF_TASKS; -+ p_Manip->shadowUpdateParams |= NUM_OF_TASKS; -+ } -+ -+ if (p_Manip->updateParams & OFFSET_OF_DATA) -+ { -+ p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset; -+ tmpReg32 = GET_UINT32(p_ReassmTbl->mode); -+ tmpReg32|= p_Manip->capwapFragParams.dataOffset; -+ WRITE_UINT32(p_ReassmTbl->mode, tmpReg32); -+ p_Manip->updateParams &= ~OFFSET_OF_DATA; -+ p_Manip->shadowUpdateParams |= OFFSET_OF_DATA; -+ } -+ -+ if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)) -+ { -+ p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset; -+ -+ tmpReg32 = GET_UINT32(p_ReassmTbl->mode); -+ tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY; -+ WRITE_UINT32(p_ReassmTbl->mode, tmpReg32); -+ -+ tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr); -+ tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24; -+ WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32); -+ p_Manip->updateParams &= ~OFFSET_OF_PR; -+ p_Manip->shadowUpdateParams |= OFFSET_OF_PR; -+ } -+ else -+ { -+ p_Manip->capwapFragParams.prOffset = 0xff; -+ p_Manip->updateParams &= ~OFFSET_OF_PR; -+ p_Manip->shadowUpdateParams |= OFFSET_OF_PR; -+ } -+ -+ p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId; -+ p_Manip->updateParams &= ~HW_PORT_ID; -+ p_Manip->shadowUpdateParams |= HW_PORT_ID; -+ -+ /*timeout hc */ -+ ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames; -+ ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24; -+ ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase)); -+ ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2; -+ return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams); -+ } -+ -+ else if (validate) -+ { -+ if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port")); -+ if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value ")); -+ -+ if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)) -+ { -+ if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); -+ } -+ else -+ { -+ if (p_Manip->capwapFragParams.prOffset != 0xff) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value ")); -+ } -+ if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value ")); -+ } -+ -+ return E_OK; -+} -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ -+t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 }; -+ t_Error err = E_OK; -+ uint8_t result; -+ uint32_t bitFor1Micro, tsbs, log2num; -+ -+ ASSERT_COND(p_FmPcd); -+ ASSERT_COND(h_ReasmCommonPramTbl); -+ -+ bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); -+ if (bitFor1Micro == 0) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale")); -+ -+ bitFor1Micro = 32 - bitFor1Micro; -+ LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num); -+ tsbs = bitFor1Micro - log2num; -+ -+ ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys( -+ h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase); -+ ccReassmTimeoutParams.tsbs = (uint8_t)tsbs; -+ ccReassmTimeoutParams.activate = TRUE; -+ if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, -+ &result)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ switch (result) -+ { -+ case (0): -+ return E_OK; -+ case (1): -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM")); -+ case (2): -+ RETURN_ERROR( -+ MAJOR, E_NO_MEMORY, -+ ("failed to allocate internal buffer from the HC-Port")); -+ case (3): -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("'Disable Timeout Task' with invalid IPRCPT")); -+ case (4): -+ RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks")); -+ case (5): -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command")); -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ } -+ return E_OK; -+} -+ -+static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip) -+{ -+ uint32_t tmpReg32 = 0, i, bitFor1Micro; -+ uint64_t tmpReg64, size; -+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; -+ t_Error err = E_OK; -+ -+ bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); -+ if (bitFor1Micro == 0) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale")); -+ -+ /* Allocation of the Reassembly Common Parameters table. This table is located in the -+ MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */ -+ p_Manip->reassmParams.p_ReassCommonTbl = -+ (t_ReassCommonTbl *)FM_MURAM_AllocMem( -+ p_FmPcd->h_FmMuram, -+ FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE, -+ FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN); -+ -+ if (!p_Manip->reassmParams.p_ReassCommonTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM alloc for Reassembly common parameters table")); -+ -+ MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0, -+ FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE); -+ -+ /* Setting the TimeOut Mode.*/ -+ tmpReg32 = 0; -+ if (p_Manip->reassmParams.timeOutMode -+ == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES) -+ tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES; -+ -+ /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID. -+ In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/ -+ tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames; -+ WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid, -+ tmpReg32); -+ -+ /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/ -+ size = p_Manip->reassmParams.maxNumFramesInProcess + 129; -+ -+ /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */ -+ p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr = -+ PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)(size * 2), -+ 256)); -+ if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr) -+ RETURN_ERROR( -+ MAJOR, E_NO_MEMORY, -+ ("MURAM alloc for Reassembly frame descriptor indexes pool")); -+ -+ MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), -+ 0, (uint32_t)(size * 2)); -+ -+ /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to -+ the maximum number of frames that are allowed to be reassembled simultaneously + 128. -+ The last entry in this pool must contain the index zero*/ -+ for (i = 0; i < (size - 1); i++) -+ WRITE_UINT16( -+ *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)), -+ (uint16_t)(i+1)); -+ -+ /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys( -+ UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)) -+ - p_FmPcd->physicalMuramBase); -+ WRITE_UINT32( -+ p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr, -+ tmpReg32); -+ -+ /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory. -+ The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/ -+ p_Manip->reassmParams.reassFrmDescrPoolTblAddr = -+ PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64)); -+ -+ if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); -+ -+ MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0, -+ (uint32_t)(size * 64)); -+ -+ /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/ -+ tmpReg64 = (uint64_t)(XX_VirtToPhys( -+ UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr))); -+ tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset -+ & FM_PCD_MANIP_REASM_LIODN_MASK) -+ << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT); -+ tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset -+ & FM_PCD_MANIP_REASM_ELIODN_MASK) -+ << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT); -+ WRITE_UINT32( -+ p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi, -+ (uint32_t)(tmpReg64 >> 32)); -+ WRITE_UINT32( -+ p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow, -+ (uint32_t)tmpReg64); -+ -+ /*Allocation of the TimeOut table - This table resides in the MURAM. -+ The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/ -+ p_Manip->reassmParams.timeOutTblAddr = -+ PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8)); -+ -+ if (!p_Manip->reassmParams.timeOutTblAddr) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM alloc for Reassembly timeout table")); -+ -+ MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0, -+ (uint16_t)(size * 8)); -+ -+ /* Sets the TimeOut table offset from MURAM */ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys( -+ UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr)) -+ - p_FmPcd->physicalMuramBase); -+ WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr, -+ tmpReg32); -+ -+ /* Sets the Expiration Delay */ -+ tmpReg32 = 0; -+ tmpReg32 |= (((uint32_t)(1 << bitFor1Micro)) -+ * p_Manip->reassmParams.timeoutThresholdForReassmProcess); -+ WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay, -+ tmpReg32); -+ -+ err = FmPcdRegisterReassmPort(p_FmPcd, -+ p_Manip->reassmParams.p_ReassCommonTbl); -+ if (err != E_OK) -+ { -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, -+ p_Manip->reassmParams.p_ReassCommonTbl); -+ RETURN_ERROR(MAJOR, err, ("port registration")); -+ } -+ -+ return err; -+} -+ -+static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr) -+{ -+ t_FmPcd *p_FmPcd = p_Manip->h_FmPcd; -+ uint32_t tmpReg32, autoLearnHashTblSize; -+ uint32_t numOfWays, setSize, setSizeCode, keySize; -+ uint32_t waySize, numOfSets, numOfEntries; -+ uint64_t tmpReg64; -+ uint16_t minFragSize; -+ uint16_t maxReassemSize; -+ uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr; -+ t_ReassTbl **p_ReassTbl; -+ -+ switch (hdr) -+ { -+ case HEADER_TYPE_IPv4: -+ p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl; -+ p_AutoLearnHashTblAddr = -+ &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr; -+ p_AutoLearnSetLockTblAddr = -+ &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr; -+ minFragSize = p_Manip->reassmParams.ip.minFragSize[0]; -+ maxReassemSize = 0; -+ numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0]; -+ keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */ -+ break; -+ case HEADER_TYPE_IPv6: -+ p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl; -+ p_AutoLearnHashTblAddr = -+ &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr; -+ p_AutoLearnSetLockTblAddr = -+ &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr; -+ minFragSize = p_Manip->reassmParams.ip.minFragSize[1]; -+ maxReassemSize = 0; -+ numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1]; -+ keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */ -+ if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways")); -+ break; -+ case HEADER_TYPE_CAPWAP: -+ p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl; -+ p_AutoLearnHashTblAddr = -+ &p_Manip->reassmParams.capwap.autoLearnHashTblAddr; -+ p_AutoLearnSetLockTblAddr = -+ &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr; -+ minFragSize = 0; -+ maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize; -+ numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry; -+ keySize = 4; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type")); -+ } -+ keySize += 2; /* 2 bytes reserved for RFDIndex */ -+#if (DPAA_VERSION >= 11) -+ keySize += 2; /* 2 bytes reserved */ -+#endif /* (DPAA_VERSION >= 11) */ -+ waySize = ROUND_UP(keySize, 8); -+ -+ /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/ -+ *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem( -+ p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE, -+ FM_PCD_MANIP_REASM_TABLE_ALIGN); -+ if (!*p_ReassTbl) -+ RETURN_ERROR( MAJOR, E_NO_MEMORY, -+ ("MURAM alloc for Reassembly specific parameters table")); -+ memset(*p_ReassTbl, 0, sizeof(t_ReassTbl)); -+ -+ /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl) -+ - p_FmPcd->physicalMuramBase); -+ WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32); -+ -+ /* Calculate set size (set size is rounded-up to next power of 2) */ -+ NEXT_POWER_OF_2(numOfWays * waySize, setSize); -+ -+ /* Get set size code */ -+ LOG2(setSize, setSizeCode); -+ -+ /* Sets ways number and set size code */ -+ WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize, -+ (uint16_t)((numOfWays << 8) | setSizeCode)); -+ -+ /* It is recommended that the total number of entries in this table -+ (number of sets * number of ways) will be twice the number of frames that -+ are expected to be reassembled simultaneously.*/ -+ numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2); -+ -+ /* sets number calculation - number of entries = number of sets * number of ways */ -+ numOfSets = numOfEntries / numOfWays; -+ -+ /* Sets AutoLearnHashKeyMask*/ -+ NEXT_POWER_OF_2(numOfSets, numOfSets); -+ -+ WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask, -+ (uint16_t)(numOfSets - 1)); -+ -+ /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory. -+ The size of this table is determined by the number of sets and the set size. -+ Table size = set size * number of sets -+ This table base address should be aligned to SetSize.*/ -+ autoLearnHashTblSize = numOfSets * setSize; -+ -+ *p_AutoLearnHashTblAddr = -+ PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize)); -+ if (!*p_AutoLearnHashTblAddr) -+ { -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl); -+ *p_ReassTbl = NULL; -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); -+ } -+ MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize); -+ -+ /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */ -+ tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset -+ & FM_PCD_MANIP_REASM_LIODN_MASK) -+ << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT); -+ tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset -+ & FM_PCD_MANIP_REASM_ELIODN_MASK) -+ << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT); -+ tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr)); -+ WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi, -+ (uint32_t)(tmpReg64 >> 32)); -+ WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64); -+ -+ /* Allocation of the Set Lock table - This table resides in external memory -+ The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes. -+ This table resides in external memory and its base address should be 4-byte aligned */ -+ *p_AutoLearnSetLockTblAddr = -+ PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4)); -+ if (!*p_AutoLearnSetLockTblAddr) -+ { -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl); -+ *p_ReassTbl = NULL; -+ XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr)); -+ *p_AutoLearnHashTblAddr = 0; -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED")); -+ } -+ MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4)); -+ -+ /* sets Set Lock table pointer and liodn offset*/ -+ tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset -+ & FM_PCD_MANIP_REASM_LIODN_MASK) -+ << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT); -+ tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset -+ & FM_PCD_MANIP_REASM_ELIODN_MASK) -+ << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT); -+ tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr)); -+ WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi, -+ (uint32_t)(tmpReg64 >> 32)); -+ WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64); -+ -+ /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */ -+ WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize); -+ -+ WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize); -+ -+ return E_OK; -+} -+ -+static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams, -+ t_Handle h_FmPort, t_FmPcdManip *p_Manip, -+ t_Handle h_Ad, bool validate) -+{ -+ t_FmPortGetSetCcParams fmPortGetSetCcParams; -+ uint32_t tmpReg32; -+ t_Error err; -+ t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams; -+#if (DPAA_VERSION >= 11) -+ t_FmPcdCtrlParamsPage *p_ParamsPage; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR( -+ (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY), -+ E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams, -+ E_INVALID_HANDLE); -+ -+ UNUSED(h_Ad); -+ -+ if (!p_Manip->updateParams) -+ return E_OK; -+ -+ if (p_Manip->h_FmPcd != h_FmPcd) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_STATE, -+ ("handler of PCD previously was initiated by different value")); -+ -+ if (p_Manip->updateParams) -+ { -+ if ((!(p_Manip->updateParams -+ & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))) -+ || ((p_Manip->shadowUpdateParams -+ & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_STATE, -+ ("in this stage parameters from Port has not be updated")); -+ -+ fmPortGetSetCcParams.setCcParams.type = 0; -+ if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY) -+ { -+ fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE; -+ fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF; -+ } -+ fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV; -+ if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) -+ != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ if (fmPortGetSetCcParams.getCcParams.type -+ & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("offset of the data wasn't configured previously")); -+ if (p_Manip->updateParams -+ & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)) -+ { -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint8_t *p_Ptr, i, totalNumOfTnums; -+ -+ totalNumOfTnums = -+ (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks -+ + fmPortGetSetCcParams.getCcParams.numOfExtraTasks); -+ -+ p_Manip->reassmParams.internalBufferPoolAddr = -+ PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS), -+ BMI_FIFO_UNITS)); -+ if (!p_Manip->reassmParams.internalBufferPoolAddr) -+ RETURN_ERROR( -+ MAJOR, E_NO_MEMORY, -+ ("MURAM alloc for Reassembly internal buffers pool")); -+ MemSet8( -+ UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr), -+ 0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS)); -+ -+ p_Manip->reassmParams.internalBufferPoolManagementIndexAddr = -+ PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)(5 + totalNumOfTnums), -+ 4)); -+ if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr) -+ RETURN_ERROR( -+ MAJOR, -+ E_NO_MEMORY, -+ ("MURAM alloc for Reassembly internal buffers management")); -+ -+ p_Ptr = -+ (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr); -+ WRITE_UINT32( -+ *(uint32_t*)p_Ptr, -+ (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase)); -+ for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++) -+ WRITE_UINT8(*p_Ptr, i); -+ WRITE_UINT8(*p_Ptr, 0xFF); -+ -+ tmpReg32 = -+ (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT) -+ | ((uint32_t)(XX_VirtToPhys( -+ UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)) -+ - p_FmPcd->physicalMuramBase)); -+ WRITE_UINT32( -+ p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement, -+ tmpReg32); -+ -+ p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS -+ | DISCARD_MASK); -+ p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS -+ | DISCARD_MASK); -+ } -+ } -+ -+ if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY) -+ { -+ if (p_Manip->reassmParams.capwap.h_Scheme) -+ { -+ p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] = -+ p_Manip->reassmParams.capwap.h_Scheme; -+ p_PcdParams->p_KgParams->numOfSchemes++; -+ } -+ -+ } -+ else -+ { -+ if (p_Manip->reassmParams.ip.h_Ipv4Scheme) -+ { -+ p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] = -+ p_Manip->reassmParams.ip.h_Ipv4Scheme; -+ p_PcdParams->p_KgParams->numOfSchemes++; -+ } -+ if (p_Manip->reassmParams.ip.h_Ipv6Scheme) -+ { -+ p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] = -+ p_Manip->reassmParams.ip.h_Ipv6Scheme; -+ p_PcdParams->p_KgParams->numOfSchemes++; -+ } -+#if (DPAA_VERSION >= 11) -+ if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6) -+ { -+ if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE, -+ (void**)&p_ParamsPage)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ tmpReg32 = NIA_ENG_KG; -+ if (p_Manip->reassmParams.ip.h_Ipv4Scheme) -+ { -+ tmpReg32 |= NIA_KG_DIRECT; -+ tmpReg32 |= NIA_KG_CC_EN; -+ tmpReg32 |= FmPcdKgGetSchemeId( -+ p_Manip->reassmParams.ip.h_Ipv4Scheme); -+ WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32); -+ } -+ if (p_Manip->reassmParams.ip.h_Ipv6Scheme) -+ { -+ tmpReg32 &= ~NIA_AC_MASK; -+ tmpReg32 |= NIA_KG_DIRECT; -+ tmpReg32 |= NIA_KG_CC_EN; -+ tmpReg32 |= FmPcdKgGetSchemeId( -+ p_Manip->reassmParams.ip.h_Ipv6Scheme); -+ WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32); -+ } -+ } -+#else -+ if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6) -+ { -+ WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask, -+ fmPortGetSetCcParams.getCcParams.discardMask); -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ return E_OK; -+} -+ -+#if (DPAA_VERSION == 10) -+static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ -+ memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams)); -+ -+ fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS; -+ fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid; -+ if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed," -+ "Failed to release %d buffers to the BM (missing FBPRs)", -+ fmPcdCcFragScratchPoolCmdParams.numOfBuffers)); -+ -+ return E_OK; -+} -+ -+static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ -+ memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams)); -+ -+ fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid; -+ if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return E_OK; -+} -+#endif /* (DPAA_VERSION == 10) */ -+ -+static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd) -+{ -+ if (p_Manip->h_Ad) -+ { -+ if (p_Manip->muramAllocate) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad); -+ else -+ XX_Free(p_Manip->h_Ad); -+ p_Manip->h_Ad = NULL; -+ } -+ if (p_Manip->p_Template) -+ { -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template); -+ p_Manip->p_Template = NULL; -+ } -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ if (p_Manip->h_Frag) -+ { -+ if (p_Manip->capwapFragParams.p_AutoLearnHashTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, -+ p_Manip->capwapFragParams.p_AutoLearnHashTbl); -+ if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, -+ p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl); -+ if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, -+ p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl); -+ if (p_Manip->capwapFragParams.p_TimeOutTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, -+ p_Manip->capwapFragParams.p_TimeOutTbl); -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag); -+ -+ } -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ if (p_Manip->frag) -+ { -+ if (p_Manip->fragParams.p_Frag) -+ { -+#if (DPAA_VERSION == 10) -+ FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid); -+#endif /* (DPAA_VERSION == 10) */ -+ -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag); -+ } -+ } -+ else -+ if (p_Manip->reassm) -+ { -+ FmPcdUnregisterReassmPort(p_FmPcd, -+ p_Manip->reassmParams.p_ReassCommonTbl); -+ -+ if (p_Manip->reassmParams.timeOutTblAddr) -+ FM_MURAM_FreeMem( -+ p_FmPcd->h_FmMuram, -+ UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr)); -+ if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr) -+ XX_FreeSmart( -+ UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)); -+ if (p_Manip->reassmParams.p_ReassCommonTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, -+ p_Manip->reassmParams.p_ReassCommonTbl); -+ if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr) -+ FM_MURAM_FreeMem( -+ p_FmPcd->h_FmMuram, -+ UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)); -+ if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr) -+ FM_MURAM_FreeMem( -+ p_FmPcd->h_FmMuram, -+ UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)); -+ if (p_Manip->reassmParams.internalBufferPoolAddr) -+ FM_MURAM_FreeMem( -+ p_FmPcd->h_FmMuram, -+ UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)); -+ if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP) -+ { -+ -+ } -+ else -+ { -+ if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr) -+ XX_FreeSmart( -+ UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)); -+ if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr) -+ XX_FreeSmart( -+ UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)); -+ if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr) -+ XX_FreeSmart( -+ UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)); -+ if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr) -+ XX_FreeSmart( -+ UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)); -+ if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, -+ p_Manip->reassmParams.ip.p_Ipv4ReassTbl); -+ if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, -+ p_Manip->reassmParams.ip.p_Ipv6ReassTbl); -+ if (p_Manip->reassmParams.ip.h_Ipv6Ad) -+ XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad); -+ if (p_Manip->reassmParams.ip.h_Ipv4Ad) -+ XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad); -+ } -+ } -+ -+ if (p_Manip->p_StatsTbl) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl); -+} -+ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams) -+{ -+ if (p_ManipParams->u.hdr.rmv) -+ { -+ switch (p_ManipParams->u.hdr.rmvParams.type) -+ { -+ case (e_FM_PCD_MANIP_RMV_BY_HDR): -+ switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type) -+ { -+ case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) : -+ if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include) -+ { -+ switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr) -+ { -+ case (HEADER_TYPE_CAPWAP_DTLS) : -+ p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST; -+ p_Manip->muramAllocate = TRUE; -+ if (p_ManipParams->u.hdr.insrt) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after")); -+ if (p_ManipParams->fragOrReasm) -+ { -+ if (!p_ManipParams->fragOrReasmParams.frag) -+ { -+ switch (p_ManipParams->fragOrReasmParams.hdr) -+ { -+ case (HEADER_TYPE_CAPWAP): -+ p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly")); -+ } -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE")); -+ } -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location")); -+ } -+ } -+ else -+ { -+ switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr) -+ { -+ case (HEADER_TYPE_CAPWAP_DTLS) : -+ case (HEADER_TYPE_CAPWAP) : -+ if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for the type of remove e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_CAPWAP can not be insert or fragOrReasm TRUE")); -+ p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR; -+ p_Manip->muramAllocate = TRUE; -+ p_ManipParams->u.hdr.insrt = TRUE; //internal frame header -+ break; -+ default : -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); -+ } -+ } -+ break; -+ default : -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); -+ } -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation")); -+ } -+ } -+ else if (p_ManipParams->u.hdr.insrt) -+ { -+ switch (p_ManipParams->u.hdr.insrtParams.type) -+ { -+ case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) : -+ -+ p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER; -+ p_Manip->muramAllocate = FALSE; -+ if (p_ManipParams->fragOrReasm) -+ { -+ if (p_ManipParams->fragOrReasmParams.frag) -+ { -+ switch (p_ManipParams->fragOrReasmParams.hdr) -+ { -+ case (HEADER_TYPE_CAPWAP): -+ p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation")); -+ } -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point")); -+ } -+ break; -+ -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type")); -+ } -+ } -+ else if (p_ManipParams->fragOrReasm) -+ { -+ if (p_ManipParams->fragOrReasmParams.frag) -+ { -+ switch (p_ManipParams->fragOrReasmParams.hdr) -+ { -+ case (HEADER_TYPE_CAPWAP): -+ p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION; -+ p_Manip->muramAllocate = FALSE; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation")); -+ } -+ } -+ else -+ { -+ switch (p_ManipParams->fragOrReasmParams.hdr) -+ { -+ case (HEADER_TYPE_CAPWAP): -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Reassembly has to be with additional operation - rmv = TRUE, type of remove - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION,type = e_FM_PCD_MANIP_LOC_BY_HDR, hdr = HEADER_TYPE_CAPWAP_DTLS")); -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly")); -+ } -+ } -+ -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation")); -+ -+ p_Manip->insrt = p_ManipParams->u.hdr.insrt; -+ p_Manip->rmv = p_ManipParams->u.hdr.rmv; -+ -+ return E_OK; -+} -+ -+#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, -+ t_FmPcdManipParams *p_ManipParams) -+{ -+ switch (p_ManipParams->type) -+ { -+ case e_FM_PCD_MANIP_HDR: -+ /* Check that next-manip is not already used */ -+ if (p_ManipParams->h_NextManip) -+ { -+ if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_STATE, -+ ("h_NextManip is already a part of another chain")); -+ if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip) -+ != e_FM_PCD_MANIP_HDR) && -+ (MANIP_GET_TYPE(p_ManipParams->h_NextManip) -+ != e_FM_PCD_MANIP_FRAG)) -+ RETURN_ERROR( -+ MAJOR, -+ E_NOT_SUPPORTED, -+ ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation.")); -+ } -+ -+ if (p_ManipParams->u.hdr.rmv) -+ { -+ switch (p_ManipParams->u.hdr.rmvParams.type) -+ { -+ case (e_FM_PCD_MANIP_RMV_BY_HDR): -+ switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type) -+ { -+ case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2): -+ break; -+#if (DPAA_VERSION >= 11) -+ case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP): -+ break; -+ case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START): -+ { -+ t_Error err; -+ uint8_t prsArrayOffset; -+ -+ err = -+ GetPrOffsetByHeaderOrField( -+ &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo, -+ &prsArrayOffset); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ break; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ default: -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("invalid type of remove manipulation")); -+ } -+ break; -+ case (e_FM_PCD_MANIP_RMV_GENERIC): -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("invalid type of remove manipulation")); -+ } -+ p_Manip->opcode = HMAN_OC; -+ p_Manip->muramAllocate = TRUE; -+ p_Manip->rmv = TRUE; -+ } -+ else -+ if (p_ManipParams->u.hdr.insrt) -+ { -+ switch (p_ManipParams->u.hdr.insrtParams.type) -+ { -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR): -+ { -+ switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type) -+ { -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2): -+ /* nothing to check */ -+ break; -+#if (DPAA_VERSION >= 11) -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP): -+ if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size -+ % 4) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("IP inserted header must be of size which is a multiple of four bytes")); -+ break; -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP): -+ if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size -+ % 4) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("CAPWAP inserted header must be of size which is a multiple of four bytes")); -+ break; -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP): -+ case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE): -+ if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size -+ != 8) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("Inserted header must be of size 8")); -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+ default: -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("unsupported insert by header type")); -+ } -+ } -+ case (e_FM_PCD_MANIP_INSRT_GENERIC): -+ break; -+ default: -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("for only insert manipulation unsupported type")); -+ } -+ p_Manip->opcode = HMAN_OC; -+ p_Manip->muramAllocate = TRUE; -+ p_Manip->insrt = TRUE; -+ } -+ else -+ if (p_ManipParams->u.hdr.fieldUpdate) -+ { -+ /* Check parameters */ -+ if (p_ManipParams->u.hdr.fieldUpdateParams.type -+ == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN) -+ { -+ if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType -+ == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI) -+ && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri -+ > 7)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("vpri should get values of 0-7 ")); -+ if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType -+ == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN) -+ { -+ int i; -+ -+ if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal -+ > 7) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("vpriDefVal should get values of 0-7 ")); -+ for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS; -+ i++) -+ if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i] -+ & 0xf0) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("dscpToVpriTabl value out of range (0-15)")); -+ } -+ -+ } -+ -+ p_Manip->opcode = HMAN_OC; -+ p_Manip->muramAllocate = TRUE; -+ p_Manip->fieldUpdate = TRUE; -+ } -+ else -+ if (p_ManipParams->u.hdr.custom) -+ { -+ if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE) -+ { -+ -+ if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) || -+ (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("size should get values of 1-8 ")); -+ -+ if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("srcOffset should be <= 7")); -+ -+ if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset + -+ p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("(srcOffset + size) should be <= 8")); -+ -+ if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset + -+ p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("(dstOffset + size) should be <= 256")); -+ -+ } -+ -+ p_Manip->opcode = HMAN_OC; -+ p_Manip->muramAllocate = TRUE; -+ p_Manip->custom = TRUE; -+ } -+ break; -+ case e_FM_PCD_MANIP_REASSEM: -+ if (p_ManipParams->h_NextManip) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("next manip with reassembly")); -+ switch (p_ManipParams->u.reassem.hdr) -+ { -+ case (HEADER_TYPE_IPv4): -+ p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4; -+ p_Manip->opcode = HMAN_OC_IP_REASSEMBLY; -+ break; -+ case (HEADER_TYPE_IPv6): -+ p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6; -+ p_Manip->opcode = HMAN_OC_IP_REASSEMBLY; -+ break; -+#if (DPAA_VERSION >= 11) -+ case (HEADER_TYPE_CAPWAP): -+ p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP; -+ p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY; -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+ default: -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("header for reassembly")); -+ } -+ break; -+ case e_FM_PCD_MANIP_FRAG: -+ if (p_ManipParams->h_NextManip) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("next manip with fragmentation")); -+ switch (p_ManipParams->u.frag.hdr) -+ { -+ case (HEADER_TYPE_IPv4): -+ case (HEADER_TYPE_IPv6): -+ p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION; -+ break; -+#if (DPAA_VERSION >= 11) -+ case (HEADER_TYPE_CAPWAP): -+ p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION; -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+ default: -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("header for fragmentation")); -+ } -+ p_Manip->muramAllocate = TRUE; -+ break; -+ case e_FM_PCD_MANIP_SPECIAL_OFFLOAD: -+ switch (p_ManipParams->u.specialOffload.type) -+ { -+ case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC): -+ p_Manip->opcode = HMAN_OC_IPSEC_MANIP; -+ p_Manip->muramAllocate = TRUE; -+ break; -+#if (DPAA_VERSION >= 11) -+ case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP): -+ p_Manip->opcode = HMAN_OC_CAPWAP_MANIP; -+ p_Manip->muramAllocate = TRUE; -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+ default: -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("special offload type")); -+ } -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type")); -+ } -+ -+ return E_OK; -+} -+#endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ -+static t_Error UpdateIndxStats(t_Handle h_FmPcd, -+ t_Handle h_FmPort, -+ t_FmPcdManip *p_Manip) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint32_t tmpReg32 = 0; -+ t_AdOfTypeContLookup *p_Ad; -+ t_FmPortGetSetCcParams fmPortGetSetCcParams; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ if (p_Manip->h_FmPcd != h_FmPcd) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("handler of PCD previously was initiated by different value")); -+ -+ memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); -+ -+ if (!p_Manip->p_StatsTbl) -+ { -+ -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN; -+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC; -+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ tmpReg32 = GET_UINT32(p_Ad->ccAdBase); -+ -+ p_Manip->p_StatsTbl = -+ (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE, -+ 4); -+ if (!p_Manip->p_StatsTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table")); -+ -+ MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4)); -+ -+ tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase); -+ -+ if (p_Manip->cnia) -+ tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA; -+ -+ tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD; -+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); -+ } -+ else -+ { -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN; -+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC; -+ err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ return E_OK; -+} -+ -+static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip) -+{ -+ t_AdOfTypeContLookup *p_Ad; -+ uint32_t tmpReg32 = 0; -+ uint8_t prsArrayOffset = 0; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ if (p_Manip->rmv) -+ { -+ err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ tmpReg32 |= (uint32_t)prsArrayOffset << 24; -+ tmpReg32 |= HMAN_RMV_HDR; -+ } -+ -+ if (p_Manip->insrt) -+ tmpReg32 |= HMAN_INSRT_INT_FRM_HDR; -+ -+ tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR; -+ -+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); -+ -+ tmpReg32 = 0; -+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); -+ -+ return E_OK; -+} -+ -+static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip, -+ bool caamUsed) -+{ -+ t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ uint32_t tmpReg32 = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE); -+ -+ p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET; -+ -+ tmpReg32 = 0; -+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ *(uint32_t *)&p_Ad->ccAdBase = tmpReg32; -+ -+ tmpReg32 = 0; -+ tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX; -+ tmpReg32 |= (uint32_t)0x16 << 16; -+ *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32; -+ -+ if (caamUsed) -+ *(uint32_t *)&p_Ad->gmask = 0xf0000000; -+ -+ return E_OK; -+} -+ -+static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip) -+{ -+ t_AdOfTypeContLookup *p_Ad; -+ uint32_t tmpReg32 = 0; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ -+ tmpReg32 = 0; -+ tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST; -+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); -+ -+ tmpReg32 = 0; -+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ -+ -+ if (p_Manip->h_Frag) -+ { -+ p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET; -+ tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase)); -+ } -+ -+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); -+ -+ return err; -+} -+ -+static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams, -+ t_FmPcdManip *p_Manip, -+ t_FmPcd *p_FmPcd, -+ uint8_t poolId) -+{ -+ t_Handle p_Table; -+ uint32_t tmpReg32 = 0; -+ int i = 0; -+ uint8_t log2Num; -+ uint8_t numOfSets; -+ uint32_t j = 0; -+ uint32_t bitFor1Micro; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ if (!p_FmPcd->h_Hc) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode")); -+ if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2")); -+ if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2")); -+ if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess) -+ DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly")); -+ if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH) -+ { -+ if ((p_ManipParams->maxNumFramesInProcess < 4) || -+ (p_ManipParams->maxNumFramesInProcess > 512)) -+ RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_EIGHT_WAYS_HASH maxNumFramesInProcess has to be in the range 4-512")); -+ } -+ else -+ { -+ if ((p_ManipParams->maxNumFramesInProcess < 8) || -+ (p_ManipParams->maxNumFramesInProcess > 2048)) -+ RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_FOUR_WAYS_HASH maxNumFramesInProcess has to be in the range 8-2048")); -+ } -+ -+ bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); -+ if (bitFor1Micro == 0) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale")); -+ -+ p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID); -+ -+ p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE, -+ FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN); -+ if (!p_Manip->h_Frag) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table")); -+ -+ MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE); -+ -+ p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag; -+ -+ p_Manip->capwapFragParams.p_AutoLearnHashTbl = -+ (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), -+ FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN); -+ -+ if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table")); -+ -+ MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE)); -+ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase); -+ -+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32); -+ -+ tmpReg32 = 0; -+ if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES) -+ tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES; -+ if (p_ManipParams->haltOnDuplicationFrag) -+ tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG; -+ if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH) -+ { -+ i = 8; -+ tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS; -+ } -+ else -+ i = 4; -+ -+ numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i); -+ LOG2(numOfSets, log2Num); -+ tmpReg32 |= (uint32_t)(log2Num - 1) << 24; -+ -+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32); -+ -+ for (j=0; jmaxNumFramesInProcess*2; j++) -+ if (((j / i) % 2)== 0) -+ WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000); -+ -+ tmpReg32 = 0x00008000; -+ tmpReg32 |= (uint32_t)poolId << 16; -+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32); -+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000); -+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000); -+ -+ p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess; -+ -+ p_Manip->capwapFragParams.sgBpid = poolId; -+ -+ p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames; -+ p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime; -+ p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro; -+ -+ tmpReg32 = 0; -+ tmpReg32 |= (((uint32_t)1<capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess); -+ WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32); -+ -+ return E_OK; -+} -+ -+static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams, -+ t_FmPcdManip *p_Manip, -+ t_FmPcd *p_FmPcd, -+ uint8_t poolId) -+{ -+ t_AdOfTypeContLookup *p_Ad; -+ uint32_t tmpReg32 = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); -+ -+ p_Manip->updateParams |= OFFSET_OF_DATA; -+ -+ p_Manip->frag = TRUE; -+ -+ p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ FM_PCD_CC_AD_ENTRY_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_Manip->h_Frag) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor")); -+ -+ MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag; -+ -+ tmpReg32 = 0; -+ tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION; -+ -+ if (p_ManipParams->headerOptionsCompr) -+ tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN; -+ tmpReg32 |= ((uint32_t)poolId << 8); -+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); -+ -+ tmpReg32 = 0; -+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); -+ -+ p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation; -+ p_Manip->capwapFragParams.sgBpid = poolId; -+ -+ return E_OK; -+} -+ -+static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd) -+{ -+ t_AdOfTypeContLookup *p_Ad; -+ uint32_t tmpReg32 = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); -+ -+ UNUSED(p_FmPcd); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ -+ tmpReg32 = 0; -+ tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS; -+ if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID) -+ tmpReg32 |= (uint32_t)0x16 << 16; -+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); -+ -+ tmpReg32 = 0; -+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); -+ -+ return E_OK; -+} -+ -+static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd) -+{ -+ t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate; -+ uint8_t tmpReg8 = 0xff; -+ t_AdOfTypeContLookup *p_Ad; -+ bool ipModify = FALSE; -+ uint32_t tmpReg32 = 0, tmpRegNia = 0; -+ uint16_t tmpReg16 = 0; -+ t_Error err = E_OK; -+ uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0; -+ uint8_t *p_Template = NULL; -+ -+ SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ if (p_Manip->insrt) -+ { -+ if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) || -+ (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)")); -+ -+ if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset")); -+ -+ if (p_InsrtByTemplate->size > 128) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128")); -+ -+ if (p_InsrtByTemplate->size) -+ { -+ p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, -+ p_InsrtByTemplate->size, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if(!p_Manip->p_Template) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED")); -+ -+ tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase)); -+ tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24; -+ *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32; -+ } -+ -+ tmpReg32 = 0; -+ -+ p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t)); -+ -+ if (!p_Template) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED")); -+ -+ memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t)); -+ -+ if (p_InsrtByTemplate->modifyOuterIp) -+ { -+ ipModify = TRUE; -+ -+ tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset]; -+ -+ if((tmpReg8 & 0xf0) == 0x40) -+ tmpReg8 = 4; -+ else if((tmpReg8 & 0xf0) == 0x60) -+ tmpReg8 = 6; -+ else -+ tmpReg8 = 0xff; -+ -+ if (tmpReg8 != 0xff) -+ { -+ if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte")); -+ if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength) -+ { -+ -+ if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes")); -+ extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize); -+ blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize; -+ extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize; -+ /*IP header template - IP totalLength - -+ (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage , -+ in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13) -+ second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/ -+ } -+ if (blockSize) -+ { -+ if (!POWER_OF_2(blockSize)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2")); -+ } -+ -+ } -+ if (tmpReg8 == 4) -+ { -+ if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IP present in header template, user asked for IP modifications but ipOffset + ipTotalLengthFieldOffset in header template bigger than template size")); -+ -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn; -+ -+ if (blockSize) -+ blockSize -= 1; -+ -+ if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255")); -+ -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes);// for IPV6 decrement additional 40 bytes of IPV6 heade size -+ -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00; -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize; -+ -+ /*IP header template - relevant only for ipv4 CheckSum = 0*/ -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00; -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00; -+ -+ /*UDP checksum has to be 0*/ -+ if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent) -+ { -+ if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template")); -+ -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00; -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00; -+ -+ } -+ -+ if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field")); -+ -+ tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24; -+ } -+ else if (tmpReg8 == 6) -+ { -+ /*TODO - add check for maximum value of blockSize;*/ -+ if (blockSize) -+ LOG2(blockSize, log2Num); -+ tmpRegNia |= (uint32_t)log2Num << 24; -+ -+ // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40); -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize; -+ if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent) -+ { -+ if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template")); -+ if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite")); -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00; -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08; -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00; -+ p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00; -+ } -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4")); -+ } -+ -+ tmpReg32 = tmpReg16 = tmpReg8 = 0; -+ /*TODO - check it*/ -+ if (p_InsrtByTemplate->modifyOuterVlan) -+ { -+ if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits")); -+ -+ memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t))); -+ if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN ")); -+ -+ memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t))); -+ tmpReg8 &= 0x1f; -+ tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5); -+ -+ p_Template[14] = tmpReg8; -+ } -+ -+ MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size); -+ -+ XX_Free(p_Template); -+ } -+ -+ tmpReg32 = 0; -+ if (p_Manip->h_Frag) -+ { -+ tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase)); -+ tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16; -+ } -+ else -+ tmpReg32 = 0xffff0000; -+ -+ if (ipModify) -+ tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8; -+ else -+ tmpReg32 |= (uint32_t)0x0000ff00; -+ -+ tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER; -+ *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32; -+ -+ tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia; -+ -+ return err; -+} -+ -+static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams) -+{ -+ -+ switch (p_StatsParams->type) -+ { -+ case (e_FM_PCD_STATS_PER_FLOWID): -+ p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS; -+ p_Manip->muramAllocate = TRUE; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type")); -+ } -+ -+ return E_OK; -+} -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ -+static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr) -+{ -+ t_AdOfTypeContLookup *p_Ad; -+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; -+ uint32_t tmpReg32; -+ t_Error err = E_OK; -+ -+ /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly -+ function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then -+ two separate IP Reassembly Parameter tables are required.*/ -+ if ((err = CreateReassTable(p_Manip, hdr)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/ -+ tmpReg32 = 0; -+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ -+ /* Gets the required Action descriptor table pointer */ -+ switch (hdr) -+ { -+ case HEADER_TYPE_IPv4: -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad; -+ tmpReg32 |= (uint32_t)(XX_VirtToPhys( -+ p_Manip->reassmParams.ip.p_Ipv4ReassTbl) -+ - (p_FmPcd->physicalMuramBase)); -+ break; -+ case HEADER_TYPE_IPv6: -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad; -+ tmpReg32 |= (uint32_t)(XX_VirtToPhys( -+ p_Manip->reassmParams.ip.p_Ipv6ReassTbl) -+ - (p_FmPcd->physicalMuramBase)); -+ break; -+ case HEADER_TYPE_CAPWAP: -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad; -+ tmpReg32 |= (uint32_t)(XX_VirtToPhys( -+ p_Manip->reassmParams.capwap.p_ReassTbl) -+ - (p_FmPcd->physicalMuramBase)); -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type")); -+ } -+ -+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); -+ -+ /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/ -+ /* mark the Scatter/Gather table offset to be set later on when the port will be known */ -+ p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK); -+ -+ if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4)) -+ { -+#if (DPAA_VERSION == 10) -+ tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8); -+ WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32); -+#endif /* (DPAA_VERSION == 10) */ -+#if (DPAA_VERSION >= 11) -+ if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0) -+ { -+ tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK -+ | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid); -+ WRITE_UINT32(p_Ad->gmask, tmpReg32); -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/ -+ tmpReg32 = 0; -+ tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY; -+ } -+#if (DPAA_VERSION >= 11) -+ else -+ if (hdr == HEADER_TYPE_CAPWAP) -+ { -+ tmpReg32 = 0; -+ tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); -+ -+ p_Manip->reassm = TRUE; -+ -+ return E_OK; -+} -+ -+static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; -+ -+ /* Allocation if IPv4 Action descriptor */ -+ p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart( -+ FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_Manip->reassmParams.ip.h_Ipv4Ad) -+ { -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("Allocation of IPv4 table descriptor")); -+ } -+ -+ memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */ -+ return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4); -+} -+ -+static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; -+ -+ /* Allocation if IPv6 Action descriptor */ -+ p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart( -+ FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_Manip->reassmParams.ip.h_Ipv6Ad) -+ { -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("Allocation of IPv6 table descriptor")); -+ } -+ -+ memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */ -+ return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6); -+} -+ -+static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams, -+ t_FmPcdManip *p_Manip) -+{ -+ uint32_t maxSetNumber = 10000; -+ t_FmPcdManipReassemIpParams reassmManipParams = -+ p_ManipReassmParams->u.ipReassem; -+ t_Error res; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc, -+ E_INVALID_HANDLE); -+ -+ /* Check validation of user's parameter.*/ -+ if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000) -+ || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("timeoutThresholdForReassmProcess should be 1msec - 8sec")); -+ /* It is recommended that the total number of entries in this table (number of sets * number of ways) -+ will be twice the number of frames that are expected to be reassembled simultaneously.*/ -+ if (reassmManipParams.maxNumFramesInProcess -+ > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)")); -+ -+ if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6) -+ && (reassmManipParams.minFragSize[1] < 256)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256")); -+ -+ /* Saves user's reassembly manipulation parameters */ -+ p_Manip->reassmParams.ip.relativeSchemeId[0] = -+ reassmManipParams.relativeSchemeId[0]; -+ p_Manip->reassmParams.ip.relativeSchemeId[1] = -+ reassmManipParams.relativeSchemeId[1]; -+ p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] = -+ reassmManipParams.numOfFramesPerHashEntry[0]; -+ p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] = -+ reassmManipParams.numOfFramesPerHashEntry[1]; -+ p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0]; -+ p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1]; -+ p_Manip->reassmParams.maxNumFramesInProcess = -+ reassmManipParams.maxNumFramesInProcess; -+ p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode; -+ p_Manip->reassmParams.fqidForTimeOutFrames = -+ reassmManipParams.fqidForTimeOutFrames; -+ p_Manip->reassmParams.timeoutThresholdForReassmProcess = -+ reassmManipParams.timeoutThresholdForReassmProcess; -+ p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId; -+ p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset; -+#if (DPAA_VERSION == 10) -+ p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid; -+#endif /* (DPAA_VERSION == 10) */ -+#if (DPAA_VERSION >= 11) -+ if (reassmManipParams.nonConsistentSpFqid != 0) -+ { -+ p_Manip->reassmParams.ip.nonConsistentSpFqid = -+ reassmManipParams.nonConsistentSpFqid; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ /* Creates and initializes the IP Reassembly common parameter table */ -+ CreateReassCommonTable(p_Manip); -+ -+ /* Creation of IPv4 reassembly manipulation */ -+ if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6) -+ || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4)) -+ { -+ res = SetIpv4ReassmManip(p_Manip); -+ if (res != E_OK) -+ return res; -+ } -+ -+ /* Creation of IPv6 reassembly manipulation */ -+ if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6) -+ { -+ res = SetIpv6ReassmManip(p_Manip); -+ if (res != E_OK) -+ return res; -+ } -+ -+ return E_OK; -+} -+ -+static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd, -+ t_FmPcdKgSchemeParams *p_Scheme, -+ t_Handle h_CcTree, bool ipv4, -+ uint8_t groupId) -+{ -+ uint32_t j; -+ uint8_t res; -+ -+ /* Configures scheme's network environment parameters */ -+ p_Scheme->netEnvParams.numOfDistinctionUnits = 2; -+ if (ipv4) -+ res = FmPcdNetEnvGetUnitId( -+ p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), -+ HEADER_TYPE_IPv4, FALSE, 0); -+ else -+ res = FmPcdNetEnvGetUnitId( -+ p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), -+ HEADER_TYPE_IPv6, FALSE, 0); -+ ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); -+ p_Scheme->netEnvParams.unitIds[0] = res; -+ -+ res = FmPcdNetEnvGetUnitId( -+ p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), -+ HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0); -+ ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); -+ p_Scheme->netEnvParams.unitIds[1] = res; -+ -+ /* Configures scheme's next engine parameters*/ -+ p_Scheme->nextEngine = e_FM_PCD_CC; -+ p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree; -+ p_Scheme->kgNextEngineParams.cc.grpId = groupId; -+ p_Scheme->useHash = TRUE; -+ -+ /* Configures scheme's key*/ -+ if (ipv4 == TRUE) -+ { -+ p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].type = -+ e_FM_PCD_EXTRACT_BY_HDR; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type = -+ e_FM_PCD_EXTRACT_FULL_FIELD; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr = -+ HEADER_TYPE_IPv4; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 = -+ NET_HEADER_FIELD_IPv4_DST_IP; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].type = -+ e_FM_PCD_EXTRACT_BY_HDR; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type = -+ e_FM_PCD_EXTRACT_FULL_FIELD; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr = -+ HEADER_TYPE_IPv4; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 = -+ NET_HEADER_FIELD_IPv4_SRC_IP; -+ p_Scheme->keyExtractAndHashParams.extractArray[2].type = -+ e_FM_PCD_EXTRACT_BY_HDR; -+ p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type = -+ e_FM_PCD_EXTRACT_FULL_FIELD; -+ p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr = -+ HEADER_TYPE_IPv4; -+ p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 = -+ NET_HEADER_FIELD_IPv4_PROTO; -+ p_Scheme->keyExtractAndHashParams.extractArray[3].type = -+ e_FM_PCD_EXTRACT_BY_HDR; -+ p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr = -+ HEADER_TYPE_IPv4; -+ p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type = -+ e_FM_PCD_EXTRACT_FROM_HDR; -+ p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation = -+ FALSE; -+ p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size = -+ 2; -+ p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset = -+ 4; -+ } -+ else /* IPv6 */ -+ { -+ p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].type = -+ e_FM_PCD_EXTRACT_BY_HDR; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type = -+ e_FM_PCD_EXTRACT_FULL_FIELD; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr = -+ HEADER_TYPE_IPv6; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 = -+ NET_HEADER_FIELD_IPv6_DST_IP; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].type = -+ e_FM_PCD_EXTRACT_BY_HDR; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type = -+ e_FM_PCD_EXTRACT_FULL_FIELD; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr = -+ HEADER_TYPE_IPv6; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 = -+ NET_HEADER_FIELD_IPv6_SRC_IP; -+ p_Scheme->keyExtractAndHashParams.extractArray[2].type = -+ e_FM_PCD_EXTRACT_BY_HDR; -+ p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr = -+ HEADER_TYPE_USER_DEFINED_SHIM2; -+ p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type = -+ e_FM_PCD_EXTRACT_FROM_HDR; -+ p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size = -+ 4; -+ p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset = -+ 4; -+ p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation = -+ TRUE; -+ } -+ -+ p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304; -+ p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314; -+ p_Scheme->keyExtractAndHashParams.numOfUsedDflts = -+ FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; -+ for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++) -+ { -+ p_Scheme->keyExtractAndHashParams.dflts[j].type = -+ (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */ -+ p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect = -+ e_FM_PCD_KG_DFLT_GBL_0; -+ } -+} -+ -+static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip, -+ t_FmPcdManipReassemIpStats *p_Stats) -+{ -+ ASSERT_COND(p_Manip); -+ ASSERT_COND(p_Stats); -+ ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl); -+ -+ p_Stats->timeout = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter); -+ p_Stats->rfdPoolBusy = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter); -+ p_Stats->internalBufferBusy = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy); -+ p_Stats->externalBufferBusy = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy); -+ p_Stats->sgFragments = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter); -+ p_Stats->dmaSemaphoreDepletion = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter); -+#if (DPAA_VERSION >= 11) -+ p_Stats->nonConsistentSp = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl) -+ { -+ p_Stats->specificHdrStatistics[0].successfullyReassembled = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter); -+ p_Stats->specificHdrStatistics[0].validFragments = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter); -+ p_Stats->specificHdrStatistics[0].processedFragments = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter); -+ p_Stats->specificHdrStatistics[0].malformedFragments = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter); -+ p_Stats->specificHdrStatistics[0].autoLearnBusy = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter); -+ p_Stats->specificHdrStatistics[0].discardedFragments = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter); -+ p_Stats->specificHdrStatistics[0].moreThan16Fragments = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter); -+ } -+ if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl) -+ { -+ p_Stats->specificHdrStatistics[1].successfullyReassembled = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter); -+ p_Stats->specificHdrStatistics[1].validFragments = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter); -+ p_Stats->specificHdrStatistics[1].processedFragments = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter); -+ p_Stats->specificHdrStatistics[1].malformedFragments = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter); -+ p_Stats->specificHdrStatistics[1].autoLearnBusy = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter); -+ p_Stats->specificHdrStatistics[1].discardedFragments = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter); -+ p_Stats->specificHdrStatistics[1].moreThan16Fragments = -+ GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter); -+ } -+ return E_OK; -+} -+ -+static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip, -+ t_FmPcdManipFragIpStats *p_Stats) -+{ -+ t_AdOfTypeContLookup *p_Ad; -+ -+ ASSERT_COND(p_Manip); -+ ASSERT_COND(p_Stats); -+ ASSERT_COND(p_Manip->h_Ad); -+ ASSERT_COND(p_Manip->fragParams.p_Frag); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ -+ p_Stats->totalFrames = GET_UINT32(p_Ad->gmask); -+ p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase) -+ & 0x00ffffff; -+ p_Stats->generatedFragments = -+ GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr); -+ -+ return E_OK; -+} -+ -+static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams, -+ t_FmPcdManip *p_Manip) -+{ -+ uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0; -+ t_FmPcd *p_FmPcd; -+#if (DPAA_VERSION == 10) -+ t_Error err = E_OK; -+#endif /* (DPAA_VERSION == 10) */ -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF, -+ E_INVALID_VALUE); -+ -+ p_FmPcd = p_Manip->h_FmPcd; -+ /* Allocation of fragmentation Action Descriptor */ -+ p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem( -+ p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_Manip->fragParams.p_Frag) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM alloc for Fragmentation table descriptor")); -+ MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* Prepare the third Ad register (pcAndOffsets)- OperationCode */ -+ pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION; -+ -+ /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/ -+ ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE; -+ ccAdBaseReg |= (p_ManipParams->dontFragAction -+ << FM_PCD_MANIP_IP_FRAG_DF_SHIFT); -+ -+ -+ /* Set Scatter/Gather BPid */ -+ if (p_ManipParams->sgBpidEn) -+ { -+ ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN; -+ pcAndOffsetsReg |= ((p_ManipParams->sgBpid -+ << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT) -+ & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK); -+ } -+ -+ /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */ -+ gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr)) -+ - p_FmPcd->physicalMuramBase); -+#if (DPAA_VERSION == 10) -+ gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID; -+#else -+ gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID; -+#endif /* (DPAA_VERSION == 10) */ -+ -+ /* Set all Ad registers */ -+ WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg); -+ WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg); -+ WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg); -+ -+ /* Saves user's fragmentation manipulation parameters */ -+ p_Manip->frag = TRUE; -+ p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation; -+ -+#if (DPAA_VERSION == 10) -+ p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid; -+ -+ /* scratch buffer pool initialization */ -+ if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK) -+ { -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag); -+ p_Manip->fragParams.p_Frag = NULL; -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+#endif /* (DPAA_VERSION == 10) */ -+ -+ return E_OK; -+} -+ -+static t_Error IPManip(t_FmPcdManip *p_Manip) -+{ -+ t_Error err = E_OK; -+ t_FmPcd *p_FmPcd; -+ t_AdOfTypeContLookup *p_Ad; -+ uint32_t tmpReg32 = 0, tmpRegNia = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); -+ p_FmPcd = p_Manip->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ -+ tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION; -+ if (p_Manip->frag == TRUE) -+ { -+ tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag) -+ - (p_FmPcd->physicalMuramBase)); -+ tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation -+ << FM_PCD_MANIP_IP_MTU_SHIFT; -+ } -+ -+ tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ tmpReg32 |= HMAN_OC_IP_MANIP; -+ -+#if (DPAA_VERSION >= 11) -+ tmpRegNia |= FM_PCD_MANIP_IP_CNIA; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); -+ WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia); -+ WRITE_UINT32(p_Ad->gmask, 0); -+ /* Total frame counter - MUST be initialized to zero.*/ -+ -+ return err; -+} -+ -+static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams, -+ t_Handle h_FmPort, t_FmPcdManip *p_Manip, -+ t_Handle h_Ad, bool validate) -+{ -+ t_FmPortGetSetCcParams fmPortGetSetCcParams; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION), -+ E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); -+ -+ UNUSED(h_FmPcd); -+ UNUSED(h_Ad); -+ UNUSED(h_PcdParams); -+ UNUSED(validate); -+ UNUSED(p_Manip); -+ -+ fmPortGetSetCcParams.setCcParams.type = 0; -+ fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE; -+ if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset) -+ DBG(WARNING, ("manipExtraSpace must be larger than '0'")); -+ -+ return E_OK; -+} -+ -+static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams, -+ t_FmPcdManip *p_Manip) -+{ -+ t_AdOfTypeContLookup *p_Ad; -+ t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams; -+ t_Error err = E_OK; -+ uint32_t tmpReg32 = 0; -+ uint32_t power; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE); -+ -+ p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec; -+ -+ SANITY_CHECK_RETURN_ERROR( -+ !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption, -+ E_INVALID_VALUE); -+ SANITY_CHECK_RETURN_ERROR( -+ !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption, -+ E_INVALID_VALUE); -+ SANITY_CHECK_RETURN_ERROR( -+ !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen, -+ E_INVALID_VALUE); -+ SANITY_CHECK_RETURN_ERROR( -+ !p_IPSecParams->arwSize || p_IPSecParams->arwAddr, -+ E_INVALID_VALUE); -+ SANITY_CHECK_RETURN_ERROR( -+ !p_IPSecParams->arwSize || p_IPSecParams->decryption, -+ E_INVALID_VALUE); -+ SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ -+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0; -+ tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0; -+ tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0; -+ tmpReg32 |= -+ (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0; -+ tmpReg32 |= -+ (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0; -+ if (p_IPSecParams->arwSize) -+ tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM) -+ & (FM_MURAM_SIZE-1)); -+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); -+ -+ tmpReg32 = 0; -+ if (p_IPSecParams->arwSize) { -+ NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power); -+ LOG2(power, power); -+ tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT; -+ } -+ -+ if (p_ManipParams->h_NextManip) -+ tmpReg32 |= -+ (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- -+ (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4; -+ WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32); -+ -+ tmpReg32 = HMAN_OC_IPSEC_MANIP; -+ tmpReg32 |= p_IPSecParams->outerIPHdrLen -+ << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT; -+ if (p_ManipParams->h_NextManip) -+ tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN; -+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); -+ -+ return err; -+} -+ -+static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd; -+ -+ /* Allocation if CAPWAP Action descriptor */ -+ p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart( -+ FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_Manip->reassmParams.capwap.h_Ad) -+ { -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("Allocation of CAPWAP table descriptor")); -+ } -+ -+ memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */ -+ return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP); -+} -+ -+static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd, -+ t_FmPcdKgSchemeParams *p_Scheme, -+ t_Handle h_CcTree, uint8_t groupId) -+{ -+ uint8_t res; -+ -+ /* Configures scheme's network environment parameters */ -+ p_Scheme->netEnvParams.numOfDistinctionUnits = 1; -+ res = FmPcdNetEnvGetUnitId( -+ p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv), -+ HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0); -+ ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); -+ p_Scheme->netEnvParams.unitIds[0] = res; -+ -+ /* Configures scheme's next engine parameters*/ -+ p_Scheme->nextEngine = e_FM_PCD_CC; -+ p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree; -+ p_Scheme->kgNextEngineParams.cc.grpId = groupId; -+ p_Scheme->useHash = TRUE; -+ -+ /* Configures scheme's key*/ -+ p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].type = -+ e_FM_PCD_EXTRACT_NON_HDR; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src = -+ e_FM_PCD_EXTRACT_FROM_PARSE_RESULT; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action = -+ e_FM_PCD_ACTION_NONE; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20; -+ p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].type = -+ e_FM_PCD_EXTRACT_NON_HDR; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src = -+ e_FM_PCD_EXTRACT_FROM_DFLT_VALUE; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action = -+ e_FM_PCD_ACTION_NONE; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0; -+ p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1; -+ -+ p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0; -+ p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0; -+ p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1; -+ p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA; -+ p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0; -+} -+ -+#if (DPAA_VERSION >= 11) -+static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip, -+ t_FmPcdManipReassemCapwapStats *p_Stats) -+{ -+ ASSERT_COND(p_Manip); -+ ASSERT_COND(p_Stats); -+ ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl); -+ -+ p_Stats->timeout = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter); -+ p_Stats->rfdPoolBusy = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter); -+ p_Stats->internalBufferBusy = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy); -+ p_Stats->externalBufferBusy = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy); -+ p_Stats->sgFragments = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter); -+ p_Stats->dmaSemaphoreDepletion = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter); -+ p_Stats->exceedMaxReassemblyFrameLen = -+ GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter); -+ -+ p_Stats->successfullyReassembled = -+ GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter); -+ p_Stats->validFragments = -+ GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter); -+ p_Stats->processedFragments = -+ GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter); -+ p_Stats->malformedFragments = -+ GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter); -+ p_Stats->autoLearnBusy = -+ GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter); -+ p_Stats->discardedFragments = -+ GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter); -+ p_Stats->moreThan16Fragments = -+ GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter); -+ -+ return E_OK; -+} -+ -+static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip, -+ t_FmPcdManipFragCapwapStats *p_Stats) -+{ -+ t_AdOfTypeContLookup *p_Ad; -+ -+ ASSERT_COND(p_Manip); -+ ASSERT_COND(p_Stats); -+ ASSERT_COND(p_Manip->h_Ad); -+ ASSERT_COND(p_Manip->fragParams.p_Frag); -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ -+ p_Stats->totalFrames = GET_UINT32(p_Ad->gmask); -+ -+ return E_OK; -+} -+ -+static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams, -+ t_FmPcdManip *p_Manip) -+{ -+ uint32_t maxSetNumber = 10000; -+ t_FmPcdManipReassemCapwapParams reassmManipParams = -+ p_ManipReassmParams->u.capwapReassem; -+ t_Error res; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc, -+ E_INVALID_HANDLE); -+ -+ /* Check validation of user's parameter.*/ -+ if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000) -+ || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("timeoutThresholdForReassmProcess should be 1msec - 8sec")); -+ /* It is recommended that the total number of entries in this table (number of sets * number of ways) -+ will be twice the number of frames that are expected to be reassembled simultaneously.*/ -+ if (reassmManipParams.maxNumFramesInProcess -+ > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)")); -+ -+ /* Saves user's reassembly manipulation parameters */ -+ p_Manip->reassmParams.capwap.relativeSchemeId = -+ reassmManipParams.relativeSchemeId; -+ p_Manip->reassmParams.capwap.numOfFramesPerHashEntry = -+ reassmManipParams.numOfFramesPerHashEntry; -+ p_Manip->reassmParams.capwap.maxRessembledsSize = -+ reassmManipParams.maxReassembledFrameLength; -+ p_Manip->reassmParams.maxNumFramesInProcess = -+ reassmManipParams.maxNumFramesInProcess; -+ p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode; -+ p_Manip->reassmParams.fqidForTimeOutFrames = -+ reassmManipParams.fqidForTimeOutFrames; -+ p_Manip->reassmParams.timeoutThresholdForReassmProcess = -+ reassmManipParams.timeoutThresholdForReassmProcess; -+ p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId; -+ p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset; -+ -+ /* Creates and initializes the Reassembly common parameter table */ -+ CreateReassCommonTable(p_Manip); -+ -+ res = SetCapwapReassmManip(p_Manip); -+ if (res != E_OK) -+ return res; -+ -+ return E_OK; -+} -+ -+static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams, -+ t_FmPcdManip *p_Manip) -+{ -+ t_FmPcd *p_FmPcd; -+ t_AdOfTypeContLookup *p_Ad; -+ uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0; -+ uint32_t tmpReg32 = 0, tmpRegNia = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF, -+ E_INVALID_VALUE); -+ p_FmPcd = p_Manip->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ -+ /* Allocation of fragmentation Action Descriptor */ -+ p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem( -+ p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_Manip->fragParams.p_Frag) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("MURAM alloc for Fragmentation table descriptor")); -+ MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* Prepare the third Ad register (pcAndOffsets)- OperationCode */ -+ pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION; -+ -+ /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/ -+ ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE; -+ ccAdBaseReg |= -+ (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN : -+ 0; -+ -+ /* Set Scatter/Gather BPid */ -+ if (p_ManipParams->sgBpidEn) -+ { -+ ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN; -+ pcAndOffsetsReg |= ((p_ManipParams->sgBpid -+ << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT) -+ & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK); -+ } -+ -+ /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */ -+ gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr)) -+ - p_FmPcd->physicalMuramBase); -+ gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID; -+ -+ /* Set all Ad registers */ -+ WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg); -+ WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg); -+ WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg); -+ -+ /* Saves user's fragmentation manipulation parameters */ -+ p_Manip->frag = TRUE; -+ p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation; -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ -+ tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag) -+ - (p_FmPcd->physicalMuramBase)); -+ tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation -+ << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT; -+ -+ tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK; -+ -+ tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA; -+ -+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); -+ WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia); -+ WRITE_UINT32(p_Ad->gmask, 0); -+ /* Total frame counter - MUST be initialized to zero.*/ -+ -+ return E_OK; -+} -+ -+static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams, -+ t_Handle h_FmPort, t_FmPcdManip *p_Manip, -+ t_Handle h_Ad, bool validate) -+{ -+ t_FmPortGetSetCcParams fmPortGetSetCcParams; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION), -+ E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); -+ -+ UNUSED(h_FmPcd); -+ UNUSED(h_Ad); -+ UNUSED(h_PcdParams); -+ UNUSED(validate); -+ UNUSED(p_Manip); -+ -+ fmPortGetSetCcParams.setCcParams.type = 0; -+ fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE; -+ if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset) -+ DBG(WARNING, ("manipExtraSpace must be larger than '0'")); -+ -+ return E_OK; -+} -+ -+static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams, -+ t_FmPcdManip *p_Manip) -+{ -+ t_AdOfTypeContLookup *p_Ad; -+ t_FmPcdManipSpecialOffloadCapwapParams *p_Params; -+ t_Error err = E_OK; -+ uint32_t tmpReg32 = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE); -+ -+ p_Params = &p_ManipParams->u.specialOffload.u.capwap; -+ -+ p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad; -+ tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE; -+ tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0; -+ /* TODO - add 'qosSrc' */ -+ WRITE_UINT32(p_Ad->ccAdBase, tmpReg32); -+ -+ tmpReg32 = HMAN_OC_CAPWAP_MANIP; -+ if (p_ManipParams->h_NextManip) -+ { -+ WRITE_UINT32( -+ p_Ad->matchTblPtr, -+ (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4); -+ -+ tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN; -+ } -+ -+ WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32); -+ -+ return err; -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params, -+ bool stats) -+{ -+ t_FmPcdManip *p_Manip; -+ t_Error err; -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ -+ p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip)); -+ if (!p_Manip) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); -+ return NULL; -+ } -+ memset(p_Manip, 0, sizeof(t_FmPcdManip)); -+ -+ p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type; -+ memcpy((uint8_t*)&p_Manip->manipParams, p_Params, -+ sizeof(p_Manip->manipParams)); -+ -+ if (!stats) -+ err = CheckManipParamsAndSetType(p_Manip, -+ (t_FmPcdManipParams *)p_Params); -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ else -+ err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params); -+#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ else -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!")); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type")); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ -+ if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY)) -+ { -+ /* In Case of reassembly manipulation the reassembly action descriptor will -+ be defines later on */ -+ if (p_Manip->muramAllocate) -+ { -+ p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem( -+ p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_Manip->h_Ad) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor")); -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ -+ MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ } -+ else -+ { -+ p_Manip->h_Ad = (t_Handle)XX_Malloc( -+ FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); -+ if (!p_Manip->h_Ad) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor")); -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ -+ memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); -+ } -+ } -+ -+ p_Manip->h_FmPcd = h_FmPcd; -+ -+ return p_Manip; -+} -+ -+static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip( -+ t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst) -+{ -+ t_CcNodeInformation *p_CcNodeInformation; -+ t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL; -+ t_List *p_Pos; -+ int i = 0; -+ t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/; -+ t_CcNodeInformation ccNodeInfo; -+ -+ LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst) -+ { -+ p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos); -+ p_NodePtrOnCurrentMdfManip = -+ (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode; -+ -+ ASSERT_COND(p_NodePtrOnCurrentMdfManip); -+ -+ /* Search in the previous node which exact index points on this current modified node for getting AD */ -+ for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++) -+ { -+ if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine -+ == e_FM_PCD_CC) -+ { -+ if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip -+ == (t_Handle)p_CrntMdfManip) -+ { -+ if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj) -+ p_AdTablePtOnCrntCurrentMdfNode = -+ p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd; -+ else -+ p_AdTablePtOnCrntCurrentMdfNode = -+ PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation)); -+ ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode; -+ EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL); -+ } -+ } -+ } -+ -+ ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys); -+ } -+} -+ -+static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd, -+ t_FmPcd *p_FmPcd) -+{ -+ t_Error err; -+ -+ /* Copy the HMTD */ -+ MemCpy8(p_Dest, (uint8_t*)p_Src, 16); -+ /* Replace the HMCT table pointer */ -+ WRITE_UINT32( -+ ((t_Hmtd *)p_Dest)->hmcdBasePtr, -+ (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase)); -+ /* Call Host Command to replace HMTD by a new HMTD */ -+ err = FmHcPcdCcDoDynamicChange( -+ p_FmPcd->h_Hc, -+ (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase), -+ (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase)); -+ if (err) -+ REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners.")); -+} -+ -+static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams, -+ t_Handle h_FmPort, t_Handle h_Manip, -+ t_Handle h_Ad, bool validate, int level, -+ t_Handle h_FmTree) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); -+ -+ UNUSED(level); -+ UNUSED(h_FmTree); -+ -+ switch (p_Manip->opcode) -+ { -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): -+ err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort, -+ p_Manip, -+ h_Ad, -+ validate); -+ break; -+ case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): -+ if (!p_Manip->h_Frag) -+ break; -+ case (HMAN_OC_CAPWAP_FRAGMENTATION): -+ err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree); -+ break; -+ case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): -+ if (p_Manip->h_Frag) -+ err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate); -+ break; -+ case (HMAN_OC_CAPWAP_INDEXED_STATS): -+ err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip); -+ break; -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ case (HMAN_OC_IP_REASSEMBLY): -+ err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad, -+ validate); -+ break; -+ case (HMAN_OC_IP_FRAGMENTATION): -+ err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, -+ h_Ad, validate); -+ break; -+#if (DPAA_VERSION >= 11) -+ case (HMAN_OC_CAPWAP_FRAGMENTATION): -+ err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, -+ h_Ad, validate); -+ break; -+ case (HMAN_OC_CAPWAP_REASSEMBLY): -+ err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad, -+ validate); -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+ default: -+ return E_OK; -+ } -+ -+ return err; -+} -+ -+static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad, -+ bool validate, int level, -+ t_Handle h_FmTree) -+{ -+ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ t_Error err = E_OK; -+ -+ UNUSED(level); -+ -+ switch (p_Manip->opcode) -+ { -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("modify node with this type of manipulation is not suppported")); -+ case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): -+ -+ if (p_Manip->h_Frag) -+ { -+ if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) -+ && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) -+ && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function")); -+ } -+ break; -+ case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): -+ if (p_Manip->h_Frag) -+ err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree); -+ break; -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ default: -+ return E_OK; -+ } -+ -+ return err; -+} -+ -+/*****************************************************************************/ -+/* Inter-module API routines */ -+/*****************************************************************************/ -+ -+t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams, -+ t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, -+ bool validate, int level, t_Handle h_FmTree, -+ bool modify) -+{ -+ t_Error err; -+ -+ if (!modify) -+ err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip, -+ h_Ad, validate, level, h_FmTree); -+ else -+ err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree); -+ -+ return err; -+} -+ -+void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add) -+{ -+ -+ uint32_t intFlags; -+ -+ intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock); -+ if (add) -+ ((t_FmPcdManip *)h_Manip)->owner++; -+ else -+ { -+ ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner); -+ ((t_FmPcdManip *)h_Manip)->owner--; -+ } -+ XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags); -+} -+ -+t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip) -+{ -+ ASSERT_COND(h_Manip); -+ return &((t_FmPcdManip *)h_Manip)->nodesLst; -+} -+ -+t_List *FmPcdManipGetSpinlock(t_Handle h_Manip) -+{ -+ ASSERT_COND(h_Manip); -+ return ((t_FmPcdManip *)h_Manip)->h_Spinlock; -+} -+ -+t_Error FmPcdManipCheckParamsForCcNextEngine( -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, -+ uint32_t *requiredAction) -+{ -+ t_FmPcdManip *p_Manip; -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ t_Error err = E_OK; -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/ -+ bool pointFromCc = TRUE; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip, -+ E_NULL_POINTER); -+ -+ p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip); -+ *requiredAction = 0; -+ -+ while (p_Manip) -+ { -+ switch (p_Manip->opcode) -+ { -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ case (HMAN_OC_CAPWAP_INDEXED_STATS): -+ if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE")); -+ if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) -+ p_Manip->cnia = TRUE; -+ case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): -+ *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA; -+ case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): -+ p_Manip->ownerTmp++; -+ break; -+ case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): -+ if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) -+ && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE")); -+ p_Manip->ownerTmp++; -+ break; -+ case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): -+ if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC) -+ && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) -+ != CC_PC_GENERIC_IC_HASH_INDEXED)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation next engine has to be CC and action = e_FM_PCD_ACTION_INDEXED_LOOKUP")); -+ err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip, -+ FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA; -+ break; -+ #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ case (HMAN_OC_IP_FRAGMENTATION): -+ case (HMAN_OC_IP_REASSEMBLY): -+#if (DPAA_VERSION >= 11) -+ case (HMAN_OC_CAPWAP_REASSEMBLY): -+ case (HMAN_OC_CAPWAP_FRAGMENTATION): -+#endif /* (DPAA_VERSION >= 11) */ -+ if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE")); -+ p_Manip->ownerTmp++; -+ break; -+ case (HMAN_OC_IPSEC_MANIP): -+#if (DPAA_VERSION >= 11) -+ case (HMAN_OC_CAPWAP_MANIP): -+#endif /* (DPAA_VERSION >= 11) */ -+ p_Manip->ownerTmp++; -+ break; -+ case (HMAN_OC): -+ if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC) -+ && MANIP_IS_CASCADED(p_Manip)) -+ RETURN_ERROR( -+ MINOR, -+ E_INVALID_STATE, -+ ("Can't have a cascaded manipulation when and Next Engine is CC")); -+ if (!MANIP_IS_FIRST(p_Manip) && pointFromCc) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)")); -+ break; -+ default: -+ RETURN_ERROR( -+ MAJOR, E_INVALID_STATE, -+ ("invalid type of header manipulation for this state")); -+ } -+ p_Manip = p_Manip->h_NextManip; -+ pointFromCc = FALSE; -+ } -+ return E_OK; -+} -+ -+ -+t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, -+ t_Handle h_FmPcdCcNode) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE); -+ -+ switch (p_Manip->opcode) -+ { -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ case (HMAN_OC_CAPWAP_INDEXED_STATS): -+ if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys")); -+ break; -+ case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): -+ if (p_Manip->h_Frag) -+ { -+ if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys")); -+ err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode)); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ break; -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ default: -+ break; -+ } -+ -+ return err; -+} -+ -+void FmPcdManipUpdateAdResultForCc( -+ t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams, -+ t_Handle p_Ad, t_Handle *p_AdNewPtr) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ -+ /* This routine creates a Manip AD and can return in "p_AdNewPtr" -+ * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */ -+ -+ ASSERT_COND(p_Manip); -+ ASSERT_COND(p_CcNextEngineParams); -+ ASSERT_COND(p_Ad); -+ ASSERT_COND(p_AdNewPtr); -+ -+ FmPcdManipUpdateOwner(h_Manip, TRUE); -+ -+ /* According to "type", either build & initialize a new AD (p_AdNew) or initialize -+ * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */ -+ switch (p_Manip->opcode) -+ { -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): -+ case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): -+ case (HMAN_OC_CAPWAP_INDEXED_STATS): -+ *p_AdNewPtr = p_Manip->h_Ad; -+ break; -+ case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): -+ case (HMAN_OC_CAPWAP_FRAGMENTATION): -+ WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid, -+ ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid); -+ WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile, -+ ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile); -+ WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia, -+ ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia); -+ *p_AdNewPtr = NULL; -+ break; -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ case (HMAN_OC_IPSEC_MANIP): -+#if (DPAA_VERSION >= 11) -+ case (HMAN_OC_CAPWAP_MANIP): -+#endif /* (DPAA_VERSION >= 11) */ -+ *p_AdNewPtr = p_Manip->h_Ad; -+ break; -+ case (HMAN_OC_IP_FRAGMENTATION): -+#if (DPAA_VERSION >= 11) -+ case (HMAN_OC_CAPWAP_FRAGMENTATION): -+#endif /* (DPAA_VERSION >= 11) */ -+ if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE) -+ && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid)) -+ { -+ memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad, -+ sizeof(t_AdOfTypeContLookup)); -+#if (DPAA_VERSION >= 11) -+ WRITE_UINT32( -+ ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, -+ GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA); -+#endif /* (DPAA_VERSION >= 11) */ -+ *p_AdNewPtr = NULL; -+ } -+ else -+ *p_AdNewPtr = p_Manip->h_Ad; -+ break; -+ case (HMAN_OC_IP_REASSEMBLY): -+ if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip)) -+ { -+ if (!p_Manip->reassmParams.ip.ipv6Assigned) -+ { -+ *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad; -+ p_Manip->reassmParams.ip.ipv6Assigned = TRUE; -+ FmPcdManipUpdateOwner(h_Manip, FALSE); -+ } -+ else -+ { -+ *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad; -+ p_Manip->reassmParams.ip.ipv6Assigned = FALSE; -+ } -+ } -+ else -+ *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad; -+ memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr, -+ sizeof(t_AdOfTypeContLookup)); -+ *p_AdNewPtr = NULL; -+ break; -+#if (DPAA_VERSION >= 11) -+ case (HMAN_OC_CAPWAP_REASSEMBLY): -+ *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad; -+ memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr, -+ sizeof(t_AdOfTypeContLookup)); -+ *p_AdNewPtr = NULL; -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+ case (HMAN_OC): -+ /* Allocate and initialize HMTD */ -+ *p_AdNewPtr = p_Manip->h_Ad; -+ break; -+ default: -+ break; -+ } -+} -+ -+void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, -+ t_Handle *p_AdNewPtr, -+ uint32_t adTableOffset) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ -+ /* This routine creates a Manip AD and can return in "p_AdNewPtr" -+ * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */ -+ ASSERT_COND(p_Manip); -+ -+ FmPcdManipUpdateOwner(h_Manip, TRUE); -+ -+ switch (p_Manip->opcode) -+ { -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): -+ WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, -+ ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase); -+ WRITE_UINT32( -+ ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr, -+ ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr); -+ WRITE_UINT32( -+ ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, -+ ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets); -+ WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask, -+ ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask); -+ WRITE_UINT32( -+ ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase, -+ (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset)); -+ *p_AdNewPtr = NULL; -+ break; -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ case (HMAN_OC): -+ /* Initialize HMTD within the match table*/ -+ MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ /* copy the existing HMTD *//* ask Alla - memcpy??? */ -+ memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd)); -+ /* update NADEN to be "1"*/ -+ WRITE_UINT16( -+ ((t_Hmtd *)p_Ad)->cfg, -+ (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN)); -+ /* update next action descriptor */ -+ WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx, -+ (uint16_t)(adTableOffset >> 4)); -+ /* mark that Manip's HMTD is not used */ -+ *p_AdNewPtr = NULL; -+ break; -+ -+ default: -+ break; -+ } -+} -+ -+t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, -+ t_Handle h_CcTree, t_Handle h_Manip, -+ bool isIpv4, uint8_t groupId) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ t_FmPcdKgSchemeParams *p_SchemeParams = NULL; -+ t_Handle h_Scheme; -+ -+ ASSERT_COND(p_FmPcd); -+ ASSERT_COND(h_NetEnv); -+ ASSERT_COND(p_Manip); -+ -+ /* scheme was already build, no need to check for IPv6 */ -+ if (p_Manip->reassmParams.ip.h_Ipv4Scheme) -+ return E_OK; -+ -+ if (isIpv4) { -+ h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]); -+ if (h_Scheme) { -+ /* scheme was found */ -+ p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme; -+ return E_OK; -+ } -+ } else { -+ h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]); -+ if (h_Scheme) { -+ /* scheme was found */ -+ p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme; -+ return E_OK; -+ } -+ } -+ -+ p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams)); -+ if (!p_SchemeParams) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("Memory allocation failed for scheme")); -+ -+ /* Configures the IPv4 or IPv6 scheme*/ -+ memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams)); -+ p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv; -+ p_SchemeParams->id.relativeSchemeId = (uint8_t)( -+ (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] : -+ p_Manip->reassmParams.ip.relativeSchemeId[1]); -+ p_SchemeParams->schemeCounter.update = TRUE; -+#if (DPAA_VERSION >= 11) -+ p_SchemeParams->alwaysDirect = TRUE; -+ p_SchemeParams->bypassFqidGeneration = TRUE; -+#else -+ p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1; -+ p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId); -+ -+ /* Sets the new scheme */ -+ if (isIpv4) -+ p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet( -+ p_FmPcd, p_SchemeParams); -+ else -+ p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet( -+ p_FmPcd, p_SchemeParams); -+ -+ XX_Free(p_SchemeParams); -+ -+ return E_OK; -+} -+ -+t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ -+ ASSERT_COND(p_Manip); -+ -+ if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) && -+ !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme)) -+ FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme); -+ -+ if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) && -+ !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme)) -+ FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme); -+ -+ return E_OK; -+} -+ -+bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ -+ ASSERT_COND(p_Manip); -+ -+ return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6); -+} -+ -+t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, -+ t_Handle h_CcTree, t_Handle h_Manip, -+ uint8_t groupId) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ t_FmPcdKgSchemeParams *p_SchemeParams = NULL; -+ -+ ASSERT_COND(p_FmPcd); -+ ASSERT_COND(h_NetEnv); -+ ASSERT_COND(p_Manip); -+ -+ /* scheme was already build, no need to check for IPv6 */ -+ if (p_Manip->reassmParams.capwap.h_Scheme) -+ return E_OK; -+ -+ p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams)); -+ if (!p_SchemeParams) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, -+ ("Memory allocation failed for scheme")); -+ -+ memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams)); -+ p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv; -+ p_SchemeParams->id.relativeSchemeId = -+ (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId; -+ p_SchemeParams->schemeCounter.update = TRUE; -+ p_SchemeParams->bypassFqidGeneration = TRUE; -+ -+ setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId); -+ -+ p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd, -+ p_SchemeParams); -+ -+ XX_Free(p_SchemeParams); -+ -+ return E_OK; -+} -+ -+t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ -+ ASSERT_COND(p_Manip); -+ -+ if (p_Manip->reassmParams.capwap.h_Scheme) -+ FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme); -+ -+ return E_OK; -+} -+ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+t_Handle FmPcdManipApplSpecificBuild(void) -+{ -+ t_FmPcdManip *p_Manip; -+ -+ p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip)); -+ if (!p_Manip) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); -+ return NULL; -+ } -+ memset(p_Manip, 0, sizeof(t_FmPcdManip)); -+ -+ p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX; -+ p_Manip->muramAllocate = FALSE; -+ -+ p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); -+ if (!p_Manip->h_Ad) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor")); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ -+ memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t)); -+ -+ /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/ -+ /*Application specific = type of flowId index, move internal frame header from data to IC, -+ SEC errors check*/ -+ if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK) -+ { -+ XX_Free(p_Manip->h_Ad); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ return p_Manip; -+} -+ -+bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip; -+ ASSERT_COND(h_Manip); -+ -+ return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE); -+} -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+/*********************** End of inter-module routines ************************/ -+ -+/****************************************/ -+/* API Init unit functions */ -+/****************************************/ -+ -+t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, -+ t_FmPcdManipParams *p_ManipParams) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ t_FmPcdManip *p_Manip; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL); -+ -+ p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE); -+ if (!p_Manip) -+ return NULL; -+ -+ if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) -+ || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION) -+ || (p_Manip->opcode == HMAN_OC) -+ || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP) -+#if (DPAA_VERSION >= 11) -+ || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP) -+ || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) -+ || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY) -+#endif /* (DPAA_VERSION >= 11) */ -+ ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd))) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled")); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ p_Manip->h_Spinlock = XX_InitSpinlock(); -+ if (!p_Manip->h_Spinlock) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ XX_Free(p_Manip); -+ return NULL; -+ }INIT_LIST(&p_Manip->nodesLst); -+ -+ switch (p_Manip->opcode) -+ { -+ case (HMAN_OC_IP_REASSEMBLY): -+ /* IpReassembly */ -+ err = IpReassembly(&p_ManipParams->u.reassem, p_Manip); -+ break; -+ case (HMAN_OC_IP_FRAGMENTATION): -+ /* IpFragmentation */ -+ err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip); -+ if (err) -+ break; -+ err = IPManip(p_Manip); -+ break; -+ case (HMAN_OC_IPSEC_MANIP): -+ err = IPSecManip(p_ManipParams, p_Manip); -+ break; -+#if (DPAA_VERSION >= 11) -+ case (HMAN_OC_CAPWAP_REASSEMBLY): -+ /* CapwapReassembly */ -+ err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip); -+ break; -+ case (HMAN_OC_CAPWAP_FRAGMENTATION): -+ /* CapwapFragmentation */ -+ err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag, -+ p_Manip); -+ break; -+ case (HMAN_OC_CAPWAP_MANIP): -+ err = CapwapManip(p_ManipParams, p_Manip); -+ break; -+#endif /* (DPAA_VERSION >= 11) */ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR): -+ /* HmanType1 */ -+ err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip); -+ break; -+ case (HMAN_OC_CAPWAP_FRAGMENTATION): -+ err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams, -+ p_Manip, -+ p_FmPcd, -+ p_ManipParams->fragOrReasmParams.sgBpid); -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ if (p_Manip->insrt) -+ p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER; -+ case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER): -+ /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */ -+ err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd); -+ break; -+ case (HMAN_OC_CAPWAP_REASSEMBLY): -+ err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams, -+ p_Manip, -+ p_FmPcd, -+ p_ManipParams->fragOrReasmParams.sgBpid); -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ if (p_Manip->rmv) -+ p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST; -+ case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST): -+ /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/ -+ err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip); -+ break; -+ case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX): -+ /*Application Specific type 1*/ -+ err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE); -+ break; -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ case (HMAN_OC): -+ /* New Manip */ -+ err = CreateManipActionNew(p_Manip, p_ManipParams); -+ break; -+ default: -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE")); -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ -+ if (p_ManipParams->h_NextManip) -+ { -+ /* in the check routine we've verified that h_NextManip has no owners -+ * and that only supported types are allowed. */ -+ p_Manip->h_NextManip = p_ManipParams->h_NextManip; -+ /* save a "prev" pointer in h_NextManip */ -+ MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip); -+ FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE); -+ } -+ -+ return p_Manip; -+} -+ -+t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip, -+ t_FmPcdManipParams *p_ManipParams) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip; -+ t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd); -+ t_Error err; -+ uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL; -+ t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos; -+ t_CcNodeInformation *p_CcNodeInfo; -+ SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE); -+ -+ INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip); -+ -+ if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR) -+ || (p_Manip->type != e_FM_PCD_MANIP_HDR)) -+ RETURN_ERROR( -+ MINOR, -+ E_NOT_SUPPORTED, -+ ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation.")); -+ -+ ASSERT_COND(p_Manip->opcode == HMAN_OC); -+ ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip); -+ memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams, -+ sizeof(p_Manip->manipParams)); -+ p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip; -+ -+ /* The replacement of the HdrManip depends on the node type.*/ -+ /* -+ * (1) If this is an independent node, all its owners should be updated. -+ * -+ * (2) If it is the head of a cascaded chain (it does not have a "prev" but -+ * it has a "next" and it has a "cascaded" indication), the next -+ * node remains unchanged, and the behavior is as in (1). -+ * -+ * (3) If it is not the head, but a part of a cascaded chain, in can be -+ * also replaced as a regular node with just one owner. -+ * -+ * (4) If it is a part of a chain implemented as a unified table, the -+ * whole table is replaced and the owners of the head node must be updated. -+ * -+ */ -+ /* lock shadow */ -+ if (!p_FmPcd->p_CcShadow) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated")); -+ -+ if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) -+ return ERROR_CODE(E_BUSY); -+ -+ /* this routine creates a new manip action in the CC Shadow. */ -+ err = CreateManipActionShadow(p_Manip, p_ManipParams); -+ if (err) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC) -+ * replace only HMTD and no lcok is required. Otherwise -+ * lock the whole PCD -+ * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */ -+ if (!FmPcdLockTryLockAll(p_FmPcd)) -+ { -+ DBG(TRACE, ("FmPcdLockTryLockAll failed")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16); -+ -+ p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip, -+ e_MANIP_HANDLER_TABLE_OWNER); -+ ASSERT_COND(p_FirstManip); -+ -+ if (!LIST_IsEmpty(&p_FirstManip->nodesLst)) -+ UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip( -+ p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip); -+ -+ p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD); -+ ASSERT_COND(p_Hmtd); -+ BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct, -+ ((t_FmPcd*)(p_Manip->h_FmPcd))); -+ -+ LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip) -+ { -+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); -+ BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode, -+ p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd))); -+ } -+ -+ p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT); -+ ASSERT_COND(p_WholeHmct); -+ -+ /* re-build the HMCT n the original location */ -+ err = CreateManipActionBackToOrig(p_Manip, p_ManipParams); -+ if (err) -+ { -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD); -+ ASSERT_COND(p_Hmtd); -+ BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct, -+ ((t_FmPcd*)p_Manip->h_FmPcd)); -+ -+ /* If LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list. -+ * For each p_Hmct (from list+fixed): -+ * call Host Command to replace HMTD by a new one */LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip) -+ { -+ p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos); -+ BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode, -+ p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd))); -+ } -+ -+ -+ ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip); -+ -+ FmPcdLockUnlockAll(p_FmPcd); -+ -+ /* unlock shadow */ -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); -+ -+ if (p_Manip->owner) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("This manipulation node not be removed because this node is occupied, first - unbind this node ")); -+ -+ if (p_Manip->h_NextManip) -+ { -+ MANIP_SET_PREV(p_Manip->h_NextManip, NULL); -+ FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE); -+ } -+ -+ if (p_Manip->p_Hmct -+ && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip))) -+ FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, -+ p_Manip->p_Hmct); -+ -+ if (p_Manip->h_Spinlock) -+ { -+ XX_FreeSpinlock(p_Manip->h_Spinlock); -+ p_Manip->h_Spinlock = NULL; -+ } -+ -+ ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd); -+ -+ XX_Free(h_ManipNode); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, -+ t_FmPcdManipStats *p_FmPcdManipStats) -+{ -+ t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER); -+ -+ switch (p_Manip->opcode) -+ { -+ case (HMAN_OC_IP_REASSEMBLY): -+ return IpReassemblyStats(p_Manip, -+ &p_FmPcdManipStats->u.reassem.u.ipReassem); -+ case (HMAN_OC_IP_FRAGMENTATION): -+ return IpFragmentationStats(p_Manip, -+ &p_FmPcdManipStats->u.frag.u.ipFrag); -+#if (DPAA_VERSION >= 11) -+ case (HMAN_OC_CAPWAP_REASSEMBLY): -+ return CapwapReassemblyStats( -+ p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem); -+ case (HMAN_OC_CAPWAP_FRAGMENTATION): -+ return CapwapFragmentationStats( -+ p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag); -+#endif /* (DPAA_VERSION >= 11) */ -+ default: -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("no statistics to this type of manip")); -+ } -+ -+ return E_OK; -+} -+ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ t_FmPcdManip *p_Manip; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL); -+ SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL); -+ -+ p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE); -+ if (!p_Manip) -+ return NULL; -+ -+ switch (p_Manip->opcode) -+ { -+ case (HMAN_OC_CAPWAP_INDEXED_STATS): -+ /* Indexed statistics */ -+ err = IndxStats(p_StatsParams, p_Manip, p_FmPcd); -+ break; -+ default: -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type")); -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ ReleaseManipHandler(p_Manip, p_FmPcd); -+ XX_Free(p_Manip); -+ return NULL; -+ } -+ -+ return p_Manip; -+} -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h -@@ -0,0 +1,555 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_manip.h -+ -+ @Description FM PCD manip... -+*//***************************************************************************/ -+#ifndef __FM_MANIP_H -+#define __FM_MANIP_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "list_ext.h" -+ -+#include "fm_cc.h" -+ -+ -+/***********************************************************************/ -+/* Header manipulations defines */ -+/***********************************************************************/ -+ -+#define NUM_OF_SCRATCH_POOL_BUFFERS 1000 /*TODO - Change it!!*/ -+ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+#define HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR 0x2e -+#define HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER 0x31 -+#define HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX 0x2f -+#define HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST 0x30 -+#define HMAN_OC_CAPWAP_REASSEMBLY 0x11 /* dummy */ -+#define HMAN_OC_CAPWAP_INDEXED_STATS 0x32 /* dummy */ -+#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33 -+#else -+#define HMAN_OC_CAPWAP_MANIP 0x2F -+#define HMAN_OC_CAPWAP_FRAG_CHECK 0x2E -+#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33 -+#define HMAN_OC_CAPWAP_REASSEMBLY 0x30 -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+#define HMAN_OC_IP_MANIP 0x34 -+#define HMAN_OC_IP_FRAGMENTATION 0x74 -+#define HMAN_OC_IP_REASSEMBLY 0xB4 -+#define HMAN_OC_IPSEC_MANIP 0xF4 -+#define HMAN_OC 0x35 -+ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+#define HMAN_RMV_HDR 0x80000000 -+#define HMAN_INSRT_INT_FRM_HDR 0x40000000 -+ -+#define UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP 6 -+#define UDP_CHECKSUM_FIELD_SIZE 2 -+#define UDP_LENGTH_FIELD_OFFSET_FROM_UDP 4 -+ -+#define IPv4_DSCECN_FIELD_OFFSET_FROM_IP 1 -+#define IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2 -+#define IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10 -+#define VLAN_TAG_FIELD_OFFSET_FROM_ETH 12 -+#define IPv4_ID_FIELD_OFFSET_FROM_IP 4 -+ -+#define IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP 4 -+#define IPv6_NEXT_HEADER_OFFSET_FROM_IP 6 -+ -+#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 0x80 -+#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN 8 -+#define FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE 32 -+#define FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE 4 -+#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE 8 -+ -+ -+#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES 0x40000000 -+#define FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG 0x10000000 -+#define FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS 0x08000000 -+#define FM_PCD_MANIP_CAPWAP_REASM_PR_COPY 0x00800000 -+ -+#define FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN 0x80000000 -+ -+#define FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE 4 -+#define FM_PCD_MANIP_INDEXED_STATS_CNIA 0x20000000 -+#define FM_PCD_MANIP_INDEXED_STATS_DPD 0x10000000 -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ -+#if (DPAA_VERSION >= 11) -+#define FM_PCD_MANIP_CAPWAP_DTLS 0x00040000 -+#define FM_PCD_MANIP_CAPWAP_NADEN 0x20000000 -+ -+#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT 16 -+#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_NO_FRAGMENTATION 0xFFFF0000 -+#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA 0x20000000 -+ -+#define FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN 0x04000000 -+#define FM_PCD_MANIP_CAPWAP_FRAG_SCRATCH_BPID 24 -+#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN 0x08000000 -+#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK 0xFF000000 -+#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT 24 -+#endif /* (DPAA_VERSION >= 11) */ -+ -+#define FM_PCD_MANIP_REASM_TABLE_SIZE 0x40 -+#define FM_PCD_MANIP_REASM_TABLE_ALIGN 8 -+ -+#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE 64 -+#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN 8 -+#define FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000 -+#define FM_PCD_MANIP_REASM_COUPLING_ENABLE 0x40000000 -+#define FM_PCD_MANIP_REASM_COUPLING_MASK 0xFF000000 -+#define FM_PCD_MANIP_REASM_COUPLING_SHIFT 24 -+#define FM_PCD_MANIP_REASM_LIODN_MASK 0x0000003F -+#define FM_PCD_MANIP_REASM_LIODN_SHIFT 56 -+#define FM_PCD_MANIP_REASM_ELIODN_MASK 0x000003c0 -+#define FM_PCD_MANIP_REASM_ELIODN_SHIFT 38 -+#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_MASK 0x000000FF -+#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT 24 -+#define FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH 1024 -+ -+#define FM_PCD_MANIP_IP_MTU_SHIFT 16 -+#define FM_PCD_MANIP_IP_NO_FRAGMENTATION 0xFFFF0000 -+#define FM_PCD_MANIP_IP_CNIA 0x20000000 -+ -+#define FM_PCD_MANIP_IP_FRAG_DF_SHIFT 28 -+#define FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID 24 -+#define FM_PCD_MANIP_IP_FRAG_SG_BDID_EN 0x08000000 -+#define FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK 0xFF000000 -+#define FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT 24 -+ -+#define FM_PCD_MANIP_IPSEC_DEC 0x10000000 -+#define FM_PCD_MANIP_IPSEC_VIPV_EN 0x08000000 -+#define FM_PCD_MANIP_IPSEC_ECN_EN 0x04000000 -+#define FM_PCD_MANIP_IPSEC_DSCP_EN 0x02000000 -+#define FM_PCD_MANIP_IPSEC_VIPL_EN 0x01000000 -+#define FM_PCD_MANIP_IPSEC_NADEN 0x20000000 -+ -+#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_MASK 0x00FF0000 -+#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT 16 -+ -+#define FM_PCD_MANIP_IPSEC_ARW_SIZE_MASK 0xFFFF0000 -+#define FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT 16 -+ -+#define e_FM_MANIP_IP_INDX 1 -+ -+#define HMCD_OPCODE_GENERIC_RMV 0x01 -+#define HMCD_OPCODE_GENERIC_INSRT 0x02 -+#define HMCD_OPCODE_GENERIC_REPLACE 0x05 -+#define HMCD_OPCODE_L2_RMV 0x08 -+#define HMCD_OPCODE_L2_INSRT 0x09 -+#define HMCD_OPCODE_VLAN_PRI_UPDATE 0x0B -+#define HMCD_OPCODE_IPV4_UPDATE 0x0C -+#define HMCD_OPCODE_IPV6_UPDATE 0x10 -+#define HMCD_OPCODE_TCP_UDP_UPDATE 0x0E -+#define HMCD_OPCODE_TCP_UDP_CHECKSUM 0x14 -+#define HMCD_OPCODE_REPLACE_IP 0x12 -+#define HMCD_OPCODE_RMV_TILL 0x15 -+#define HMCD_OPCODE_UDP_INSRT 0x16 -+#define HMCD_OPCODE_IP_INSRT 0x17 -+#define HMCD_OPCODE_CAPWAP_RMV 0x18 -+#define HMCD_OPCODE_CAPWAP_INSRT 0x18 -+#define HMCD_OPCODE_GEN_FIELD_REPLACE 0x19 -+ -+#define HMCD_LAST 0x00800000 -+ -+#define HMCD_DSCP_VALUES 64 -+ -+#define HMCD_BASIC_SIZE 4 -+#define HMCD_PTR_SIZE 4 -+#define HMCD_PARAM_SIZE 4 -+#define HMCD_IPV4_ADDR_SIZE 4 -+#define HMCD_IPV6_ADDR_SIZE 0x10 -+#define HMCD_L4_HDR_SIZE 8 -+ -+#define HMCD_CAPWAP_INSRT 0x00010000 -+#define HMCD_INSRT_UDP_LITE 0x00010000 -+#define HMCD_IP_ID_MASK 0x0000FFFF -+#define HMCD_IP_SIZE_MASK 0x0000FF00 -+#define HMCD_IP_SIZE_SHIFT 8 -+#define HMCD_IP_LAST_PID_MASK 0x000000FF -+#define HMCD_IP_OR_QOS 0x00010000 -+#define HMCD_IP_L4_CS_CALC 0x00040000 -+#define HMCD_IP_DF_MODE 0x00400000 -+ -+ -+#define HMCD_OC_SHIFT 24 -+ -+#define HMCD_RMV_OFFSET_SHIFT 0 -+#define HMCD_RMV_SIZE_SHIFT 8 -+ -+#define HMCD_INSRT_OFFSET_SHIFT 0 -+#define HMCD_INSRT_SIZE_SHIFT 8 -+ -+#define HMTD_CFG_TYPE 0x4000 -+#define HMTD_CFG_EXT_HMCT 0x0080 -+#define HMTD_CFG_PRS_AFTER_HM 0x0040 -+#define HMTD_CFG_NEXT_AD_EN 0x0020 -+ -+#define HMCD_RMV_L2_ETHERNET 0 -+#define HMCD_RMV_L2_STACKED_QTAGS 1 -+#define HMCD_RMV_L2_ETHERNET_AND_MPLS 2 -+#define HMCD_RMV_L2_MPLS 3 -+#define HMCD_RMV_L2_PPPOE 4 -+ -+#define HMCD_INSRT_L2_MPLS 0 -+#define HMCD_INSRT_N_UPDATE_L2_MPLS 1 -+#define HMCD_INSRT_L2_PPPOE 2 -+#define HMCD_INSRT_L2_SIZE_SHIFT 24 -+ -+#define HMCD_L2_MODE_SHIFT 16 -+ -+#define HMCD_VLAN_PRI_REP_MODE_SHIFT 16 -+#define HMCD_VLAN_PRI_UPDATE 0 -+#define HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI 1 -+ -+#define HMCD_IPV4_UPDATE_TTL 0x00000001 -+#define HMCD_IPV4_UPDATE_TOS 0x00000002 -+#define HMCD_IPV4_UPDATE_DST 0x00000020 -+#define HMCD_IPV4_UPDATE_SRC 0x00000040 -+#define HMCD_IPV4_UPDATE_ID 0x00000080 -+#define HMCD_IPV4_UPDATE_TOS_SHIFT 8 -+ -+#define HMCD_IPV6_UPDATE_HL 0x00000001 -+#define HMCD_IPV6_UPDATE_TC 0x00000002 -+#define HMCD_IPV6_UPDATE_DST 0x00000040 -+#define HMCD_IPV6_UPDATE_SRC 0x00000080 -+#define HMCD_IPV6_UPDATE_TC_SHIFT 8 -+ -+#define HMCD_TCP_UDP_UPDATE_DST 0x00004000 -+#define HMCD_TCP_UDP_UPDATE_SRC 0x00008000 -+#define HMCD_TCP_UDP_UPDATE_SRC_SHIFT 16 -+ -+#define HMCD_IP_REPLACE_REPLACE_IPV4 0x00000000 -+#define HMCD_IP_REPLACE_REPLACE_IPV6 0x00010000 -+#define HMCD_IP_REPLACE_TTL_HL 0x00200000 -+#define HMCD_IP_REPLACE_ID 0x00400000 -+ -+#define HMCD_IP_REPLACE_L3HDRSIZE_SHIFT 24 -+ -+#define HMCD_GEN_FIELD_SIZE_SHIFT 16 -+#define HMCD_GEN_FIELD_SRC_OFF_SHIFT 8 -+#define HMCD_GEN_FIELD_DST_OFF_SHIFT 0 -+#define HMCD_GEN_FIELD_MASK_EN 0x00400000 -+ -+#define HMCD_GEN_FIELD_MASK_OFF_SHIFT 16 -+#define HMCD_GEN_FIELD_MASK_SHIFT 24 -+ -+#define DSCP_TO_VLAN_TABLE_SIZE 32 -+ -+#define MANIP_GET_HMCT_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->tableSize) -+#define MANIP_GET_DATA_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->dataSize) -+ -+#define MANIP_GET_HMCT_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Hmct) -+#define MANIP_GET_DATA_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Data) -+ -+#define MANIP_SET_HMCT_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Hmct = h_NewPtr) -+#define MANIP_SET_DATA_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Data = h_NewPtr) -+ -+#define MANIP_GET_HMTD_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->h_Ad) -+#define MANIP_DONT_REPARSE(h_Manip) (((t_FmPcdManip *)h_Manip)->dontParseAfterManip) -+#define MANIP_SET_PREV(h_Manip, h_Prev) (((t_FmPcdManip *)h_Manip)->h_PrevManip = h_Prev) -+#define MANIP_GET_OWNERS(h_Manip) (((t_FmPcdManip *)h_Manip)->owner) -+#define MANIP_GET_TYPE(h_Manip) (((t_FmPcdManip *)h_Manip)->type) -+#define MANIP_SET_UNIFIED_TBL_PTR_INDICATION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedTablePtr = TRUE) -+#define MANIP_GET_MURAM(h_Manip) (((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram) -+#define MANIP_FREE_HMTD(h_Manip) \ -+ {if (((t_FmPcdManip *)h_Manip)->muramAllocate) \ -+ FM_MURAM_FreeMem(((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram, ((t_FmPcdManip *)h_Manip)->h_Ad);\ -+ else \ -+ XX_Free(((t_FmPcdManip *)h_Manip)->h_Ad); \ -+ ((t_FmPcdManip *)h_Manip)->h_Ad = NULL; \ -+ } -+/* position regarding Manip SW structure */ -+#define MANIP_IS_FIRST(h_Manip) (!(((t_FmPcdManip *)h_Manip)->h_PrevManip)) -+#define MANIP_IS_CASCADED(h_Manip) (((t_FmPcdManip *)h_Manip)->cascaded) -+#define MANIP_IS_UNIFIED(h_Manip) (!(((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)) -+#define MANIP_IS_UNIFIED_NON_FIRST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID) || \ -+ (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST)) -+#define MANIP_IS_UNIFIED_NON_LAST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) ||\ -+ (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID)) -+#define MANIP_IS_UNIFIED_FIRST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) -+#define MANIP_IS_UNIFIED_LAST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST) -+ -+#define MANIP_UPDATE_UNIFIED_POSITION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition = \ -+ (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)? \ -+ e_MANIP_UNIFIED_LAST : e_MANIP_UNIFIED_MID) -+ -+typedef enum e_ManipUnifiedPosition { -+ e_MANIP_UNIFIED_NONE = 0, -+ e_MANIP_UNIFIED_FIRST, -+ e_MANIP_UNIFIED_MID, -+ e_MANIP_UNIFIED_LAST -+} e_ManipUnifiedPosition; -+ -+typedef enum e_ManipInfo { -+ e_MANIP_HMTD, -+ e_MANIP_HMCT, -+ e_MANIP_HANDLER_TABLE_OWNER -+}e_ManipInfo; -+/***********************************************************************/ -+/* Memory map */ -+/***********************************************************************/ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+typedef struct t_CapwapReasmPram { -+ volatile uint32_t mode; -+ volatile uint32_t autoLearnHashTblPtr; -+ volatile uint32_t intStatsTblPtr; -+ volatile uint32_t reasmFrmDescPoolTblPtr; -+ volatile uint32_t reasmFrmDescIndexPoolTblPtr; -+ volatile uint32_t timeOutTblPtr; -+ volatile uint32_t bufferPoolIdAndRisc1SetIndexes; -+ volatile uint32_t risc23SetIndexes; -+ volatile uint32_t risc4SetIndexesAndExtendedStatsTblPtr; -+ volatile uint32_t extendedStatsTblPtr; -+ volatile uint32_t expirationDelay; -+ volatile uint32_t totalProcessedFragCounter; -+ volatile uint32_t totalUnsuccessfulReasmFramesCounter; -+ volatile uint32_t totalDuplicatedFragCounter; -+ volatile uint32_t totalMalformdFragCounter; -+ volatile uint32_t totalTimeOutCounter; -+ volatile uint32_t totalSetBusyCounter; -+ volatile uint32_t totalRfdPoolBusyCounter; -+ volatile uint32_t totalDiscardedFragsCounter; -+ volatile uint32_t totalMoreThan16FramesCounter; -+ volatile uint32_t internalBufferBusy; -+ volatile uint32_t externalBufferBusy; -+ volatile uint32_t reserved1[4]; -+} t_CapwapReasmPram; -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ -+typedef _Packed struct t_ReassTbl { -+ volatile uint16_t waysNumAndSetSize; -+ volatile uint16_t autoLearnHashKeyMask; -+ volatile uint32_t reassCommonPrmTblPtr; -+ volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi; -+ volatile uint32_t autoLearnHashTblPtrLow; -+ volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi; -+ volatile uint32_t autoLearnSetLockTblPtrLow; -+ volatile uint16_t minFragSize; /* Not relevant for CAPWAP*/ -+ volatile uint16_t maxReassemblySize; /* Only relevant for CAPWAP*/ -+ volatile uint32_t totalSuccessfullyReasmFramesCounter; -+ volatile uint32_t totalValidFragmentCounter; -+ volatile uint32_t totalProcessedFragCounter; -+ volatile uint32_t totalMalformdFragCounter; -+ volatile uint32_t totalSetBusyCounter; -+ volatile uint32_t totalDiscardedFragsCounter; -+ volatile uint32_t totalMoreThan16FramesCounter; -+ volatile uint32_t reserved2[2]; -+} _PackedType t_ReassTbl; -+ -+typedef struct t_ReassCommonTbl { -+ volatile uint32_t timeoutModeAndFqid; -+ volatile uint32_t reassFrmDescIndexPoolTblPtr; -+ volatile uint32_t liodnAndReassFrmDescPoolPtrHi; -+ volatile uint32_t reassFrmDescPoolPtrLow; -+ volatile uint32_t timeOutTblPtr; -+ volatile uint32_t expirationDelay; -+ volatile uint32_t internalBufferManagement; -+ volatile uint32_t reserved2; -+ volatile uint32_t totalTimeOutCounter; -+ volatile uint32_t totalRfdPoolBusyCounter; -+ volatile uint32_t totalInternalBufferBusy; -+ volatile uint32_t totalExternalBufferBusy; -+ volatile uint32_t totalSgFragmentCounter; -+ volatile uint32_t totalDmaSemaphoreDepletionCounter; -+ volatile uint32_t totalNCSPCounter; -+ volatile uint32_t discardMask; -+} t_ReassCommonTbl; -+ -+typedef _Packed struct t_Hmtd { -+ volatile uint16_t cfg; -+ volatile uint8_t eliodnOffset; -+ volatile uint8_t extHmcdBasePtrHi; -+ volatile uint32_t hmcdBasePtr; -+ volatile uint16_t nextAdIdx; -+ volatile uint8_t res1; -+ volatile uint8_t opCode; -+ volatile uint32_t res2; -+} _PackedType t_Hmtd; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+/***********************************************************************/ -+/* Driver's internal structures */ -+/***********************************************************************/ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+typedef struct -+{ -+ t_Handle p_AutoLearnHashTbl; -+ t_Handle p_ReassmFrmDescrPoolTbl; -+ t_Handle p_ReassmFrmDescrIndxPoolTbl; -+ t_Handle p_TimeOutTbl; -+ uint16_t maxNumFramesInProcess; -+ uint8_t numOfTasks; -+ //uint8_t poolId; -+ uint8_t prOffset; -+ uint16_t dataOffset; -+ uint8_t sgBpid; -+ uint8_t hwPortId; -+ uint32_t fqidForTimeOutFrames; -+ uint32_t timeoutRoutineRequestTime; -+ uint32_t bitFor1Micro; -+} t_CapwapFragParams; -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ -+typedef struct -+{ -+ t_AdOfTypeContLookup *p_Frag; -+#if (DPAA_VERSION == 10) -+ uint8_t scratchBpid; -+#endif /* (DPAA_VERSION == 10) */ -+} t_FragParams; -+ -+typedef struct t_ReassmParams -+{ -+ e_NetHeaderType hdr; /* Header selection */ -+ t_ReassCommonTbl *p_ReassCommonTbl; -+ uintptr_t reassFrmDescrIndxPoolTblAddr; -+ uintptr_t reassFrmDescrPoolTblAddr; -+ uintptr_t timeOutTblAddr; -+ uintptr_t internalBufferPoolManagementIndexAddr; -+ uintptr_t internalBufferPoolAddr; -+ uint32_t maxNumFramesInProcess; -+ uint8_t sgBpid; -+ uint8_t dataMemId; -+ uint16_t dataLiodnOffset; -+ uint32_t fqidForTimeOutFrames; -+ e_FmPcdManipReassemTimeOutMode timeOutMode; -+ uint32_t timeoutThresholdForReassmProcess; -+ union { -+ struct { -+ t_Handle h_Ipv4Ad; -+ t_Handle h_Ipv6Ad; -+ bool ipv6Assigned; -+ t_ReassTbl *p_Ipv4ReassTbl; -+ t_ReassTbl *p_Ipv6ReassTbl; -+ uintptr_t ipv4AutoLearnHashTblAddr; -+ uintptr_t ipv6AutoLearnHashTblAddr; -+ uintptr_t ipv4AutoLearnSetLockTblAddr; -+ uintptr_t ipv6AutoLearnSetLockTblAddr; -+ uint16_t minFragSize[2]; -+ e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2]; -+ uint8_t relativeSchemeId[2]; -+ t_Handle h_Ipv4Scheme; -+ t_Handle h_Ipv6Scheme; -+ uint32_t nonConsistentSpFqid; -+ } ip; -+ struct { -+ t_Handle h_Ad; -+ t_ReassTbl *p_ReassTbl; -+ uintptr_t autoLearnHashTblAddr; -+ uintptr_t autoLearnSetLockTblAddr; -+ uint16_t maxRessembledsSize; -+ e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry; -+ uint8_t relativeSchemeId; -+ t_Handle h_Scheme; -+ } capwap; -+ }; -+} t_ReassmParams; -+ -+typedef struct{ -+ e_FmPcdManipType type; -+ t_FmPcdManipParams manipParams; -+ bool muramAllocate; -+ t_Handle h_Ad; -+ uint32_t opcode; -+ bool rmv; -+ bool insrt; -+ t_Handle h_NextManip; -+ t_Handle h_PrevManip; -+ e_FmPcdManipType nextManipType; -+ /* HdrManip parameters*/ -+ uint8_t *p_Hmct; -+ uint8_t *p_Data; -+ bool dontParseAfterManip; -+ bool fieldUpdate; -+ bool custom; -+ uint16_t tableSize; -+ uint8_t dataSize; -+ bool cascaded; -+ e_ManipUnifiedPosition unifiedPosition; -+ /* end HdrManip */ -+ uint8_t *p_Template; -+ uint16_t owner; -+ uint32_t updateParams; -+ uint32_t shadowUpdateParams; -+ bool frag; -+ bool reassm; -+ uint16_t sizeForFragmentation; -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ t_Handle h_Frag; -+ t_CapwapFragParams capwapFragParams; -+#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */ -+ union { -+ t_ReassmParams reassmParams; -+ t_FragParams fragParams; -+ }; -+ uint8_t icOffset; -+ uint16_t ownerTmp; -+ bool cnia; -+ t_Handle p_StatsTbl; -+ t_Handle h_FmPcd; -+ t_List nodesLst; -+ t_Handle h_Spinlock; -+} t_FmPcdManip; -+ -+typedef struct t_FmPcdCcSavedManipParams -+{ -+ union -+ { -+ struct -+ { -+ uint16_t dataOffset; -+ //uint8_t poolId; -+ }capwapParams; -+ struct -+ { -+ uint16_t dataOffset; -+ uint8_t poolId; -+ }ipParams; -+ }; -+ -+} t_FmPcdCcSavedManipParams; -+ -+ -+#endif /* __FM_MANIP_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c -@@ -0,0 +1,2095 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_pcd.c -+ -+ @Description FM PCD ... -+*//***************************************************************************/ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "string_ext.h" -+#include "xx_ext.h" -+#include "sprint_ext.h" -+#include "debug_ext.h" -+#include "net_ext.h" -+#include "fm_ext.h" -+#include "fm_pcd_ext.h" -+ -+#include "fm_common.h" -+#include "fm_pcd.h" -+#include "fm_pcd_ipc.h" -+#include "fm_hc.h" -+#include "fm_muram_ext.h" -+ -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+ -+static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd) -+{ -+ if (!p_FmPcd->h_Fm) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized")); -+ -+ if (p_FmPcd->guestId == NCSW_MASTER_ID) -+ { -+ if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG")); -+ -+ if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG")); -+ -+ if (!p_FmPcd->f_Exception) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized")); -+ -+ if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized")); -+ -+ if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191")); -+ } -+ -+ return E_OK; -+} -+ -+static volatile bool blockingFlag = FALSE; -+static void IpcMsgCompletionCB(t_Handle h_FmPcd, -+ uint8_t *p_Msg, -+ uint8_t *p_Reply, -+ uint32_t replyLength, -+ t_Error status) -+{ -+ UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status); -+ blockingFlag = FALSE; -+} -+ -+static t_Error IpcMsgHandlerCB(t_Handle h_FmPcd, -+ uint8_t *p_Msg, -+ uint32_t msgLength, -+ uint8_t *p_Reply, -+ uint32_t *p_ReplyLength) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_Error err = E_OK; -+ t_FmPcdIpcMsg *p_IpcMsg = (t_FmPcdIpcMsg*)p_Msg; -+ t_FmPcdIpcReply *p_IpcReply = (t_FmPcdIpcReply*)p_Reply; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE); -+ -+#ifdef DISABLE_SANITY_CHECKS -+ UNUSED(msgLength); -+#endif /* DISABLE_SANITY_CHECKS */ -+ -+ ASSERT_COND(p_Msg); -+ -+ memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE)); -+ *p_ReplyLength = 0; -+ -+ switch (p_IpcMsg->msgId) -+ { -+ case (FM_PCD_MASTER_IS_ALIVE): -+ *(uint8_t*)(p_IpcReply->replyBody) = 1; -+ p_IpcReply->error = E_OK; -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ break; -+ case (FM_PCD_MASTER_IS_ENABLED): -+ /* count partitions registrations */ -+ if (p_FmPcd->enabled) -+ p_FmPcd->numOfEnabledGuestPartitionsPcds++; -+ *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled; -+ p_IpcReply->error = E_OK; -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ break; -+ case (FM_PCD_GUEST_DISABLE): -+ if (p_FmPcd->numOfEnabledGuestPartitionsPcds) -+ { -+ p_FmPcd->numOfEnabledGuestPartitionsPcds--; -+ p_IpcReply->error = E_OK; -+ } -+ else -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition")); -+ p_IpcReply->error = E_INVALID_STATE; -+ } -+ *p_ReplyLength = sizeof(uint32_t); -+ break; -+ case (FM_PCD_GET_COUNTER): -+ { -+ e_FmPcdCounters inCounter; -+ uint32_t outCounter; -+ -+ memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t)); -+ outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter); -+ memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t)); -+ p_IpcReply->error = E_OK; -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); -+ break; -+ } -+ case (FM_PCD_ALLOC_KG_SCHEMES): -+ { -+ t_FmPcdIpcKgSchemesParams ipcSchemesParams; -+ -+ memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams)); -+ err = FmPcdKgAllocSchemes(h_FmPcd, -+ ipcSchemesParams.numOfSchemes, -+ ipcSchemesParams.guestId, -+ p_IpcReply->replyBody); -+ p_IpcReply->error = err; -+ *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t); -+ break; -+ } -+ case (FM_PCD_FREE_KG_SCHEMES): -+ { -+ t_FmPcdIpcKgSchemesParams ipcSchemesParams; -+ -+ memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams)); -+ err = FmPcdKgFreeSchemes(h_FmPcd, -+ ipcSchemesParams.numOfSchemes, -+ ipcSchemesParams.guestId, -+ ipcSchemesParams.schemesIds); -+ p_IpcReply->error = err; -+ *p_ReplyLength = sizeof(uint32_t); -+ break; -+ } -+ case (FM_PCD_ALLOC_KG_CLSPLAN): -+ { -+ t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams; -+ -+ memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams)); -+ err = KgAllocClsPlanEntries(h_FmPcd, -+ ipcKgClsPlanParams.numOfClsPlanEntries, -+ ipcKgClsPlanParams.guestId, -+ p_IpcReply->replyBody); -+ p_IpcReply->error = err; -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ break; -+ } -+ case (FM_PCD_FREE_KG_CLSPLAN): -+ { -+ t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams; -+ -+ memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams)); -+ KgFreeClsPlanEntries(h_FmPcd, -+ ipcKgClsPlanParams.numOfClsPlanEntries, -+ ipcKgClsPlanParams.guestId, -+ ipcKgClsPlanParams.clsPlanBase); -+ *p_ReplyLength = sizeof(uint32_t); -+ break; -+ } -+ case (FM_PCD_ALLOC_PROFILES): -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ uint16_t base; -+ memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); -+ base = PlcrAllocProfilesForPartition(h_FmPcd, -+ ipcAllocParams.base, -+ ipcAllocParams.num, -+ ipcAllocParams.guestId); -+ memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t)); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t); -+ break; -+ } -+ case (FM_PCD_FREE_PROFILES): -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); -+ PlcrFreeProfilesForPartition(h_FmPcd, -+ ipcAllocParams.base, -+ ipcAllocParams.num, -+ ipcAllocParams.guestId); -+ break; -+ } -+ case (FM_PCD_SET_PORT_PROFILES): -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); -+ PlcrSetPortProfiles(h_FmPcd, -+ ipcAllocParams.guestId, -+ ipcAllocParams.num, -+ ipcAllocParams.base); -+ break; -+ } -+ case (FM_PCD_CLEAR_PORT_PROFILES): -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); -+ PlcrClearPortProfiles(h_FmPcd, -+ ipcAllocParams.guestId); -+ break; -+ } -+ case (FM_PCD_GET_SW_PRS_OFFSET): -+ { -+ t_FmPcdIpcSwPrsLable ipcSwPrsLable; -+ uint32_t swPrsOffset; -+ -+ memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable)); -+ swPrsOffset = -+ FmPcdGetSwPrsOffset(h_FmPcd, -+ (e_NetHeaderType)ipcSwPrsLable.enumHdr, -+ ipcSwPrsLable.indexPerHdr); -+ memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t)); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); -+ break; -+ } -+ case (FM_PCD_PRS_INC_PORT_STATS): -+ { -+ t_FmPcdIpcPrsIncludePort ipcPrsIncludePort; -+ -+ memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort)); -+ PrsIncludePortInStatistics(h_FmPcd, -+ ipcPrsIncludePort.hardwarePortId, -+ ipcPrsIncludePort.include); -+ break; -+ } -+ default: -+ *p_ReplyLength = 0; -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!")); -+ } -+ return E_OK; -+} -+ -+static uint32_t NetEnvLock(t_Handle h_NetEnv) -+{ -+ ASSERT_COND(h_NetEnv); -+ return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock); -+} -+ -+static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags) -+{ -+ ASSERT_COND(h_NetEnv); -+ XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags); -+} -+ -+static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock) -+{ -+ uint32_t intFlags; -+ -+ intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock); -+ LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst); -+ XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); -+} -+ -+static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd) -+{ -+ t_FmPcdLock *p_Lock = NULL; -+ uint32_t intFlags; -+ -+ intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock); -+ if (!LIST_IsEmpty(&p_FmPcd->freeLocksLst)) -+ { -+ p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next); -+ LIST_DelAndInit(&p_Lock->node); -+ } -+ if (p_FmPcd->h_Spinlock) -+ XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); -+ -+ return p_Lock; -+} -+ -+static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock) -+{ -+ uint32_t intFlags; -+ -+ intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock); -+ LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst); -+ XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); -+} -+ -+static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd) -+{ -+ t_FmPcdLock *p_Lock; -+ int i; -+ -+ for (i=0; i<10; i++) -+ { -+ p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock)); -+ if (!p_Lock) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!")); -+ memset(p_Lock, 0, sizeof(t_FmPcdLock)); -+ INIT_LIST(&p_Lock->node); -+ p_Lock->h_Spinlock = XX_InitSpinlock(); -+ if (!p_Lock->h_Spinlock) -+ { -+ XX_Free(p_Lock); -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!")); -+ } -+ EnqueueLockToFreeLst(p_FmPcd, p_Lock); -+ } -+ -+ return E_OK; -+} -+ -+static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd) -+{ -+ t_FmPcdLock *p_Lock; -+ -+ p_Lock = DequeueLockFromFreeLst(p_FmPcd); -+ while (p_Lock) -+ { -+ XX_FreeSpinlock(p_Lock->h_Spinlock); -+ XX_Free(p_Lock); -+ p_Lock = DequeueLockFromFreeLst(p_FmPcd); -+ } -+} -+ -+ -+ -+/*****************************************************************************/ -+/* Inter-module API routines */ -+/*****************************************************************************/ -+ -+void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId) -+{ -+ ASSERT_COND(p_FmPcd); -+ p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId; -+} -+ -+t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams) -+{ -+ uint8_t netEnvId = p_GrpParams->netEnvId; -+ int i, k, j; -+ -+ ASSERT_COND(p_FmPcd); -+ if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN) -+ { -+ p_GrpParams->grpExists = TRUE; -+ p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId; -+ return E_OK; -+ } -+ -+ for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && -+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++) -+ { -+ for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && -+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++) -+ { -+ /* if an option exists, add it to the opts list */ -+ if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) -+ { -+ /* check if this option already exists, add if it doesn't */ -+ for (j = 0;jnumOfOptions;j++) -+ { -+ if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) -+ break; -+ } -+ p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i]; -+ if (j == p_GrpParams->numOfOptions) -+ { -+ p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt; -+ p_GrpParams->numOfOptions++; -+ } -+ } -+ } -+ } -+ -+ if (p_GrpParams->numOfOptions == 0) -+ { -+ if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN) -+ { -+ p_GrpParams->grpExists = TRUE; -+ p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId; -+ } -+ } -+ -+ return E_OK; -+ -+} -+ -+t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector) -+{ -+ uint8_t j,k; -+ -+ *p_Vector = 0; -+ -+ ASSERT_COND(p_FmPcd); -+ for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && -+ (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++) -+ { -+ for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && -+ (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++) -+ { -+ if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt) -+ *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j]; -+ } -+ } -+ -+ if (!*p_Vector) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module")); -+ else -+ return E_OK; -+} -+ -+t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params) -+{ -+ int i; -+ -+ ASSERT_COND(p_FmPcd); -+ ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS); -+ -+ p_Params->vector = 0; -+ for (i=0; inumOfDistinctionUnits ;i++) -+ { -+ if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module")); -+ ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]); -+ p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]; -+ } -+ -+ return E_OK; -+} -+ -+bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector) -+{ -+ int i=0, k; -+ -+ ASSERT_COND(p_FmPcd); -+ /* check whether a given unit may be used by non-clsPlan users. */ -+ /* first, recognize the unit by its vector */ -+ while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE) -+ { -+ if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector) -+ { -+ for (k=0; -+ ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && -+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); -+ k++) -+ /* check that no option exists */ -+ if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt) -+ return FALSE; -+ break; -+ } -+ i++; -+ } -+ /* assert that a unit was found to mach the vector */ -+ ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); -+ -+ return TRUE; -+} -+bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ int i, k; -+ -+ ASSERT_COND(p_FmPcd); -+ -+ for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && -+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++) -+ { -+ for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && -+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++) -+ if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) -+ return TRUE; -+ } -+ for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) && -+ (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++) -+ { -+ if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) -+ return TRUE; -+ } -+ -+ return FALSE; -+} -+ -+uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt) -+{ -+ uint8_t i, k; -+ -+ ASSERT_COND(p_FmPcd); -+ -+ if (interchangeable) -+ { -+ for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && -+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) -+ { -+ for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) && -+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) -+ { -+ if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) && -+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt)) -+ -+ return i; -+ } -+ } -+ } -+ else -+ { -+ for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) && -+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) -+ if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) && -+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) && -+ (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE)) -+ return i; -+ -+ for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) && -+ (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++) -+ if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) && -+ (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt)) -+ return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr; -+ } -+ -+ return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS; -+} -+ -+t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = {0}; -+ uint8_t result; -+ t_Error err = E_OK; -+ -+ ASSERT_COND(p_FmPcd); -+ ASSERT_COND(h_ReasmCommonPramTbl); -+ -+ ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase); -+ ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/ -+ -+ if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ switch (result) -+ { -+ case (0): -+ return E_OK; -+ case (1): -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("")); -+ case (2): -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("")); -+ case (3): -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT")); -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ } -+ -+ return E_OK; -+} -+ -+e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr) -+{ -+ int i; -+ -+ ASSERT_COND(p_FmPcd); -+ ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS); -+ -+ for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) -+ && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++) -+ { -+ if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) -+ return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr; -+ } -+ -+ return HEADER_TYPE_NONE; -+} -+ -+void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint16_t swPortIndex = 0; -+ -+ ASSERT_COND(h_FmPcd); -+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); -+ p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort; -+} -+ -+uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ ASSERT_COND(h_FmPcd); -+ return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum]; -+} -+ -+uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ ASSERT_COND(h_FmPcd); -+ return p_FmPcd->netEnvs[netEnvId].macsecVector; -+} -+ -+uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv) -+{ -+ return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId; -+} -+ -+void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId) -+{ -+ uint32_t intFlags; -+ -+ ASSERT_COND(h_FmPcd); -+ -+ intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]); -+ ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++; -+ NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags); -+} -+ -+void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId) -+{ -+ uint32_t intFlags; -+ -+ ASSERT_COND(h_FmPcd); -+ ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners); -+ -+ intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]); -+ ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--; -+ NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags); -+} -+ -+uint32_t FmPcdLock(t_Handle h_FmPcd) -+{ -+ ASSERT_COND(h_FmPcd); -+ return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock); -+} -+ -+void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags) -+{ -+ ASSERT_COND(h_FmPcd); -+ XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags); -+} -+ -+t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd) -+{ -+ t_FmPcdLock *p_Lock; -+ ASSERT_COND(h_FmPcd); -+ p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd); -+ if (!p_Lock) -+ { -+ FillFreeLocksLst(h_FmPcd); -+ p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd); -+ } -+ -+ if (p_Lock) -+ EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock); -+ return p_Lock; -+} -+ -+void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock) -+{ -+ uint32_t intFlags; -+ ASSERT_COND(h_FmPcd); -+ intFlags = FmPcdLock(h_FmPcd); -+ LIST_DelAndInit(&p_Lock->node); -+ FmPcdUnlock(h_FmPcd, intFlags); -+ EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock); -+} -+ -+bool FmPcdLockTryLockAll(t_Handle h_FmPcd) -+{ -+ uint32_t intFlags; -+ t_List *p_Pos, *p_SavedPos=NULL; -+ -+ ASSERT_COND(h_FmPcd); -+ intFlags = FmPcdLock(h_FmPcd); -+ LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst) -+ { -+ t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos); -+ if (!FmPcdLockTryLock(p_Lock)) -+ { -+ p_SavedPos = p_Pos; -+ break; -+ } -+ } -+ if (p_SavedPos) -+ { -+ LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst) -+ { -+ t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos); -+ if (p_Pos == p_SavedPos) -+ break; -+ FmPcdLockUnlock(p_Lock); -+ } -+ } -+ FmPcdUnlock(h_FmPcd, intFlags); -+ -+ CORE_MemoryBarrier(); -+ -+ if (p_SavedPos) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+void FmPcdLockUnlockAll(t_Handle h_FmPcd) -+{ -+ uint32_t intFlags; -+ t_List *p_Pos; -+ -+ ASSERT_COND(h_FmPcd); -+ intFlags = FmPcdLock(h_FmPcd); -+ LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst) -+ { -+ t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos); -+ p_Lock->flag = FALSE; -+ } -+ FmPcdUnlock(h_FmPcd, intFlags); -+ -+ CORE_MemoryBarrier(); -+} -+ -+t_Error FmPcdHcSync(t_Handle h_FmPcd) -+{ -+ ASSERT_COND(h_FmPcd); -+ ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc); -+ -+ return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc); -+} -+ -+t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd) -+{ -+ ASSERT_COND(h_FmPcd); -+ return ((t_FmPcd*)h_FmPcd)->h_Hc; -+} -+ -+bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd) -+{ -+ ASSERT_COND(h_FmPcd); -+ return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport; -+} -+/*********************** End of inter-module routines ************************/ -+ -+ -+/****************************************/ -+/* API Init unit functions */ -+/****************************************/ -+ -+t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams) -+{ -+ t_FmPcd *p_FmPcd = NULL; -+ t_FmPhysAddr physicalMuramBase; -+ uint8_t i; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL); -+ -+ p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd)); -+ if (!p_FmPcd) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD")); -+ return NULL; -+ } -+ memset(p_FmPcd, 0, sizeof(t_FmPcd)); -+ -+ p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam)); -+ if (!p_FmPcd->p_FmPcdDriverParam) -+ { -+ XX_Free(p_FmPcd); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param")); -+ return NULL; -+ } -+ memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam)); -+ -+ p_FmPcd->h_Fm = p_FmPcdParams->h_Fm; -+ p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm); -+ p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm); -+ if (p_FmPcd->h_FmMuram) -+ { -+ FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase); -+ p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32)); -+ } -+ -+ for (i = 0; inetEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN; -+ -+ if (p_FmPcdParams->useHostCommand) -+ { -+ t_FmHcParams hcParams; -+ -+ memset(&hcParams, 0, sizeof(hcParams)); -+ hcParams.h_Fm = p_FmPcd->h_Fm; -+ hcParams.h_FmPcd = (t_Handle)p_FmPcd; -+ memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams)); -+ p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams); -+ if (!p_FmPcd->h_Hc) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC")); -+ FM_PCD_Free(p_FmPcd); -+ return NULL; -+ } -+ } -+ else if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition.")); -+ -+ if (p_FmPcdParams->kgSupport) -+ { -+ p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams); -+ if (!p_FmPcd->p_FmPcdKg) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen")); -+ FM_PCD_Free(p_FmPcd); -+ return NULL; -+ } -+ } -+ -+ if (p_FmPcdParams->plcrSupport) -+ { -+ p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams); -+ if (!p_FmPcd->p_FmPcdPlcr) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer")); -+ FM_PCD_Free(p_FmPcd); -+ return NULL; -+ } -+ } -+ -+ if (p_FmPcdParams->prsSupport) -+ { -+ p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams); -+ if (!p_FmPcd->p_FmPcdPrs) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser")); -+ FM_PCD_Free(p_FmPcd); -+ return NULL; -+ } -+ } -+ -+ p_FmPcd->h_Spinlock = XX_InitSpinlock(); -+ if (!p_FmPcd->h_Spinlock) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock")); -+ FM_PCD_Free(p_FmPcd); -+ return NULL; -+ } -+ INIT_LIST(&p_FmPcd->freeLocksLst); -+ INIT_LIST(&p_FmPcd->acquiredLocksLst); -+ -+ p_FmPcd->numOfEnabledGuestPartitionsPcds = 0; -+ -+ p_FmPcd->f_Exception = p_FmPcdParams->f_Exception; -+ p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId; -+ p_FmPcd->h_App = p_FmPcdParams->h_App; -+ -+ p_FmPcd->p_CcShadow = NULL; -+ p_FmPcd->ccShadowSize = 0; -+ p_FmPcd->ccShadowAlign = 0; -+ -+ p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock(); -+ if (!p_FmPcd->h_ShadowSpinlock) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock")); -+ FM_PCD_Free(p_FmPcd); -+ return NULL; -+ } -+ -+ return p_FmPcd; -+} -+ -+t_Error FM_PCD_Init(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_Error err = E_OK; -+ t_FmPcdIpcMsg msg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); -+ -+ FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo); -+ -+ if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ { -+ memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); -+ if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); -+ memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); -+ if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); -+ -+ p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName); -+ if (p_FmPcd->h_IpcSession) -+ { -+ t_FmPcdIpcReply reply; -+ uint32_t replyLength; -+ uint8_t isMasterAlive = 0; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_PCD_MASTER_IS_ALIVE; -+ msg.msgBody[0] = p_FmPcd->guestId; -+ blockingFlag = TRUE; -+ -+ do -+ { -+ replyLength = sizeof(uint32_t) + sizeof(isMasterAlive); -+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId)+sizeof(p_FmPcd->guestId), -+ (uint8_t*)&reply, -+ &replyLength, -+ IpcMsgCompletionCB, -+ h_FmPcd)) != E_OK) -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ while (blockingFlag) ; -+ if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive))) -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ isMasterAlive = *(uint8_t*)(reply.replyBody); -+ } while (!isMasterAlive); -+ } -+ } -+ -+ CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters); -+ -+ if (p_FmPcd->p_FmPcdKg) -+ { -+ err = KgInit(p_FmPcd); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ if (p_FmPcd->p_FmPcdPlcr) -+ { -+ err = PlcrInit(p_FmPcd); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ if (p_FmPcd->p_FmPcdPrs) -+ { -+ err = PrsInit(p_FmPcd); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ if (p_FmPcd->guestId == NCSW_MASTER_ID) -+ { -+ /* register to inter-core messaging mechanism */ -+ memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); -+ if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); -+ err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ /* IPv6 Frame-Id used for fragmentation */ -+ p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4)); -+ if (!p_FmPcd->ipv6FrameIdAddr) -+ { -+ FM_PCD_Free(p_FmPcd); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id")); -+ } -+ IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0, 4); -+ -+ /* CAPWAP Frame-Id used for fragmentation */ -+ p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4)); -+ if (!p_FmPcd->capwapFrameIdAddr) -+ { -+ FM_PCD_Free(p_FmPcd); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id")); -+ } -+ IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0, 2); -+ -+ XX_Free(p_FmPcd->p_FmPcdDriverParam); -+ p_FmPcd->p_FmPcdDriverParam = NULL; -+ -+ FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_Free(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd; -+ t_Error err = E_OK; -+ -+ if (p_FmPcd->ipv6FrameIdAddr) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr)); -+ -+ if (p_FmPcd->capwapFrameIdAddr) -+ FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr)); -+ -+ if (p_FmPcd->enabled) -+ FM_PCD_Disable(p_FmPcd); -+ -+ if (p_FmPcd->p_FmPcdDriverParam) -+ { -+ XX_Free(p_FmPcd->p_FmPcdDriverParam); -+ p_FmPcd->p_FmPcdDriverParam = NULL; -+ } -+ -+ if (p_FmPcd->p_FmPcdKg) -+ { -+ if ((err = KgFree(p_FmPcd)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ XX_Free(p_FmPcd->p_FmPcdKg); -+ p_FmPcd->p_FmPcdKg = NULL; -+ } -+ -+ if (p_FmPcd->p_FmPcdPlcr) -+ { -+ PlcrFree(p_FmPcd); -+ XX_Free(p_FmPcd->p_FmPcdPlcr); -+ p_FmPcd->p_FmPcdPlcr = NULL; -+ } -+ -+ if (p_FmPcd->p_FmPcdPrs) -+ { -+ if (p_FmPcd->guestId == NCSW_MASTER_ID) -+ PrsFree(p_FmPcd); -+ XX_Free(p_FmPcd->p_FmPcdPrs); -+ p_FmPcd->p_FmPcdPrs = NULL; -+ } -+ -+ if (p_FmPcd->h_Hc) -+ { -+ FmHcFree(p_FmPcd->h_Hc); -+ p_FmPcd->h_Hc = NULL; -+ } -+ -+ XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName); -+ -+ FmUnregisterPcd(p_FmPcd->h_Fm); -+ -+ ReleaseFreeLocksLst(p_FmPcd); -+ -+ if (p_FmPcd->h_Spinlock) -+ XX_FreeSpinlock(p_FmPcd->h_Spinlock); -+ -+ if (p_FmPcd->h_ShadowSpinlock) -+ XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock); -+ -+ XX_Free(p_FmPcd); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t bitMask = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ -+ if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!")); -+ -+ GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_FmPcd->exceptions |= bitMask; -+ else -+ p_FmPcd->exceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE); -+ -+ return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId); -+} -+ -+t_Error FM_PCD_Enable(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ -+ if (p_FmPcd->enabled) -+ return E_OK; -+ -+ if ((p_FmPcd->guestId != NCSW_MASTER_ID) && -+ p_FmPcd->h_IpcSession) -+ { -+ uint8_t enabled; -+ t_FmPcdIpcMsg msg; -+ t_FmPcdIpcReply reply; -+ uint32_t replyLength; -+ -+ memset(&reply, 0, sizeof(reply)); -+ memset(&msg, 0, sizeof(msg)); -+ msg.msgId = FM_PCD_MASTER_IS_ENABLED; -+ replyLength = sizeof(uint32_t) + sizeof(enabled); -+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ if (replyLength != sizeof(uint32_t) + sizeof(enabled)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody)); -+ if (!p_FmPcd->enabled) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!")); -+ -+ return E_OK; -+ } -+ else if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without IPC!")); -+ -+ if (p_FmPcd->p_FmPcdKg) -+ KgEnable(p_FmPcd); -+ -+ if (p_FmPcd->p_FmPcdPlcr) -+ PlcrEnable(p_FmPcd); -+ -+ if (p_FmPcd->p_FmPcdPrs) -+ PrsEnable(p_FmPcd); -+ -+ p_FmPcd->enabled = TRUE; -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_Disable(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ -+ if (!p_FmPcd->enabled) -+ return E_OK; -+ -+ if ((p_FmPcd->guestId != NCSW_MASTER_ID) && -+ p_FmPcd->h_IpcSession) -+ { -+ t_FmPcdIpcMsg msg; -+ t_FmPcdIpcReply reply; -+ uint32_t replyLength; -+ -+ memset(&reply, 0, sizeof(reply)); -+ memset(&msg, 0, sizeof(msg)); -+ msg.msgId = FM_PCD_GUEST_DISABLE; -+ replyLength = sizeof(uint32_t); -+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ if (replyLength != sizeof(uint32_t)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ if (reply.error == E_OK) -+ p_FmPcd->enabled = FALSE; -+ -+ return (t_Error)(reply.error); -+ } -+ else if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without IPC!")); -+ -+ if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Trying to disable a master partition PCD while" -+ "guest partitions are still enabled!")); -+ -+ if (p_FmPcd->p_FmPcdKg) -+ KgDisable(p_FmPcd); -+ -+ if (p_FmPcd->p_FmPcdPlcr) -+ PlcrDisable(p_FmPcd); -+ -+ if (p_FmPcd->p_FmPcdPrs) -+ PrsDisable(p_FmPcd); -+ -+ p_FmPcd->enabled = FALSE; -+ -+ return E_OK; -+} -+ -+t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t intFlags, specialUnits = 0; -+ uint8_t bitId = 0; -+ uint8_t i, j, k; -+ uint8_t netEnvCurrId; -+ uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0; -+ bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE; -+ uint8_t hdrNum; -+ t_FmPcdNetEnvParams *p_ModifiedNetEnvParams; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL); -+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL); -+ -+ intFlags = FmPcdLock(p_FmPcd); -+ -+ /* find a new netEnv */ -+ for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) -+ if (!p_FmPcd->netEnvs[i].used) -+ break; -+ -+ if (i== FM_MAX_NUM_OF_PORTS) -+ { -+ REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS)); -+ FmPcdUnlock(p_FmPcd, intFlags); -+ return NULL; -+ } -+ -+ p_FmPcd->netEnvs[i].used = TRUE; -+ FmPcdUnlock(p_FmPcd, intFlags); -+ -+ /* As anyone doesn't have handle of this netEnv yet, no need -+ to protect it with spinlocks */ -+ -+ p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams)); -+ if (!p_ModifiedNetEnvParams) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams")); -+ return NULL; -+ } -+ -+ memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams)); -+ p_NetEnvParams = p_ModifiedNetEnvParams; -+ -+ netEnvCurrId = (uint8_t)i; -+ -+ /* clear from previous use */ -+ memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit)); -+ memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases)); -+ memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit)); -+ -+ p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId; -+ p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd; -+ -+ p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN; -+ -+ /* check that header with opt is not interchanged with the same header */ -+ for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) -+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) -+ { -+ for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) -+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) -+ { -+ /* if an option exists, check that other headers are not the same header -+ without option */ -+ if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt) -+ { -+ for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) -+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++) -+ { -+ if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) && -+ !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt) -+ { -+ REPORT_ERROR(MINOR, E_FULL, -+ ("Illegal unit - header with opt may not be interchangeable with the same header without opt")); -+ XX_Free(p_ModifiedNetEnvParams); -+ return NULL; -+ } -+ } -+ } -+ } -+ } -+ -+ /* Specific headers checking */ -+ for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) -+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) -+ { -+ for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) -+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) -+ { -+ /* Some headers pairs may not be defined on different units as the parser -+ doesn't distinguish */ -+ /* IPSEC_AH and IPSEC_SPI can't be 2 units, */ -+ /* check that header with opt is not interchanged with the same header */ -+ if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH) -+ { -+ if (ipsecEspExists && (ipsecEspUnit != i)) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units")); -+ XX_Free(p_ModifiedNetEnvParams); -+ return NULL; -+ } -+ else -+ { -+ ipsecAhUnit = i; -+ ipsecAhExists = TRUE; -+ } -+ } -+ if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP) -+ { -+ if (ipsecAhExists && (ipsecAhUnit != i)) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units")); -+ XX_Free(p_ModifiedNetEnvParams); -+ return NULL; -+ } -+ else -+ { -+ ipsecEspUnit = i; -+ ipsecEspExists = TRUE; -+ } -+ } -+ /* ENCAP_ESP */ -+ if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP) -+ { -+ /* IPSec UDP encapsulation is currently set to use SHIM1 */ -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP; -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1; -+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1; -+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; -+ } -+#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+ /* UDP_LITE */ -+ if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE) -+ { -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE; -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP; -+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP; -+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; -+ } -+#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+ -+ /* IP FRAG */ -+ if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) && -+ (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1)) -+ { -+ /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if -+ * IPv4 exists. If so we don't need to set an extra unit -+ * We consider as "having IPv4" any IPv4 without interchangable headers -+ * but including any options. */ -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4; -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1; -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2; -+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2; -+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; -+ -+ /* check if IPv4 header exists by itself */ -+ if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) -+ { -+ p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4; -+ p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0; -+ } -+ } -+ if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) && -+ (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1)) -+ { -+ /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if -+ * IPv4 exists. If so we don't need to set an extra unit -+ * We consider as "having IPv6" any IPv6 without interchangable headers -+ * but including any options. */ -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6; -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1; -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2; -+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2; -+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; -+ -+ /* check if IPv6 header exists by itself */ -+ if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) -+ { -+ p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6; -+ p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0; -+ } -+ } -+#if (DPAA_VERSION >= 11) -+ /* CAPWAP FRAG */ -+ if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) && -+ (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1)) -+ { -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP; -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1; -+ p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2; -+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2; -+ p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ } -+ -+ /* if private header (shim), check that no other headers specified */ -+ for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) -+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) -+ { -+ if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) -+ if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers")); -+ XX_Free(p_ModifiedNetEnvParams); -+ return NULL; -+ } -+ } -+ -+ for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++) -+ { -+ if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) -+ switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr) -+ { -+ case (HEADER_TYPE_USER_DEFINED_SHIM1): -+ if (shim1Selected) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP")); -+ XX_Free(p_ModifiedNetEnvParams); -+ return NULL; -+ } -+ shim1Selected = TRUE; -+ p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001; -+ break; -+ case (HEADER_TYPE_USER_DEFINED_SHIM2): -+ p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002; -+ break; -+ default: -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported")); -+ } -+ else -+ { -+ p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++); -+ -+ if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) -+ p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i]; -+ } -+ } -+ -+ /* define a set of hardware parser LCV's according to the defined netenv */ -+ -+ /* set an array of LCV's for each header in the netEnv */ -+ for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) -+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++) -+ { -+ /* private headers have no LCV in the hard parser */ -+ if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)) -+ { -+ for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) -+ && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++) -+ { -+ hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr); -+ if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM)) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG); -+ XX_Free(p_ModifiedNetEnvParams); -+ return NULL; -+ } -+ p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i]; -+ } -+ } -+ } -+ XX_Free(p_ModifiedNetEnvParams); -+ -+ p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock(); -+ if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock")); -+ return NULL; -+ } -+ return &p_FmPcd->netEnvs[netEnvCurrId]; -+} -+ -+t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv) -+{ -+ t_FmPcdNetEnv *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv; -+ t_FmPcd *p_FmPcd = p_NetEnv->h_FmPcd; -+ uint32_t intFlags; -+ uint8_t netEnvId = p_NetEnv->netEnvId; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); -+ -+ /* check that no port is bound to this netEnv */ -+ if (p_FmPcd->netEnvs[netEnvId].owners) -+ { -+ RETURN_ERROR(MINOR, E_INVALID_STATE, -+ ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to")); -+ } -+ -+ intFlags = FmPcdLock(p_FmPcd); -+ -+ p_FmPcd->netEnvs[netEnvId].used = FALSE; -+ p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN; -+ -+ memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); -+ memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); -+ memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS); -+ -+ if (p_FmPcd->netEnvs[netEnvId].h_Spinlock) -+ XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock); -+ -+ FmPcdUnlock(p_FmPcd, intFlags); -+ return E_OK; -+} -+ -+void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE); -+ -+ FmHcTxConf(p_FmPcd->h_Hc, p_Fd); -+} -+ -+t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmCtrlCodeRevisionInfo revInfo; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE); -+ -+ if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK) -+ { -+ DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision.")); -+ revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER; -+ } -+ if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package")); -+ -+ if (!p_FmPcd->h_Hc) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode")); -+ -+ p_FmPcd->advancedOffloadSupport = TRUE; -+ -+ return E_OK; -+} -+ -+uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t outCounter = 0; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0); -+ -+ switch (counter) -+ { -+ case (e_FM_PCD_KG_COUNTERS_TOTAL): -+ if (!p_FmPcd->p_FmPcdKg) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated")); -+ return 0; -+ } -+ if ((p_FmPcd->guestId != NCSW_MASTER_ID) && -+ !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs && -+ !p_FmPcd->h_IpcSession) -+ { -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without neither IPC nor mapped register!")); -+ return 0; -+ } -+ break; -+ -+ case (e_FM_PCD_PLCR_COUNTERS_YELLOW): -+ case (e_FM_PCD_PLCR_COUNTERS_RED): -+ case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): -+ case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): -+ case (e_FM_PCD_PLCR_COUNTERS_TOTAL): -+ case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): -+ if (!p_FmPcd->p_FmPcdPlcr) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated")); -+ return 0; -+ } -+ if ((p_FmPcd->guestId != NCSW_MASTER_ID) && -+ !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs && -+ !p_FmPcd->h_IpcSession) -+ { -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in \"guest-mode\" without neither IPC nor mapped register!")); -+ return 0; -+ } -+ -+ /* check that counters are enabled */ -+ if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs && -+ !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN)) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); -+ return 0; -+ } -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs || -+ ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession)); -+ break; -+ -+ case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): -+ case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): -+ case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): -+ case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): -+ case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): -+ case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): -+ case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): -+ case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): -+ case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): -+ case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): -+ if (!p_FmPcd->p_FmPcdPrs) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated")); -+ return 0; -+ } -+ if ((p_FmPcd->guestId != NCSW_MASTER_ID) && -+ !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs && -+ !p_FmPcd->h_IpcSession) -+ { -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without neither IPC nor mapped register!")); -+ return 0; -+ } -+ break; -+ default: -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter")); -+ return 0; -+ } -+ -+ if ((p_FmPcd->guestId != NCSW_MASTER_ID) && -+ p_FmPcd->h_IpcSession) -+ { -+ t_FmPcdIpcMsg msg; -+ t_FmPcdIpcReply reply; -+ uint32_t replyLength; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_PCD_GET_COUNTER; -+ memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t)); -+ replyLength = sizeof(uint32_t) + sizeof(uint32_t); -+ if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) +sizeof(uint32_t), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ if (replyLength != sizeof(uint32_t) + sizeof(uint32_t)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ -+ memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t)); -+ return outCounter; -+ } -+ -+ switch (counter) -+ { -+ /* Parser statistics */ -+ case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds); -+ case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs); -+ case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs); -+ case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs); -+ case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs); -+ case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres); -+ case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres); -+ case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres); -+ case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres); -+ case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs); -+ case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs); -+ case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs); -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs); -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs); -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs); -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs); -+ case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): -+ return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs); -+ case (e_FM_PCD_KG_COUNTERS_TOTAL): -+ return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc); -+ -+ /* Policer statistics */ -+ case (e_FM_PCD_PLCR_COUNTERS_YELLOW): -+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt); -+ case (e_FM_PCD_PLCR_COUNTERS_RED): -+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt); -+ case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): -+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt); -+ case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): -+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt); -+ case (e_FM_PCD_PLCR_COUNTERS_TOTAL): -+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt); -+ case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): -+ return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt); -+ } -+ return 0; -+} -+ -+t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t bitMask = 0, tmpReg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!")); -+ -+ GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception); -+ -+ if (bitMask) -+ { -+ if (enable) -+ p_FmPcd->exceptions |= bitMask; -+ else -+ p_FmPcd->exceptions &= ~bitMask; -+ -+ switch (exception) -+ { -+ case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): -+ case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): -+ if (!p_FmPcd->p_FmPcdKg) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working")); -+ break; -+ case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): -+ case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): -+ case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): -+ case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): -+ if (!p_FmPcd->p_FmPcdPlcr) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working")); -+ break; -+ case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): -+ case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): -+ if (!p_FmPcd->p_FmPcdPrs) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working")); -+ break; -+ } -+ -+ switch (exception) -+ { -+ case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): -+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer); -+ if (enable) -+ tmpReg |= FM_EX_KG_DOUBLE_ECC; -+ else -+ tmpReg &= ~FM_EX_KG_DOUBLE_ECC; -+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg); -+ break; -+ case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): -+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer); -+ if (enable) -+ tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW; -+ else -+ tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW; -+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg); -+ break; -+ case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): -+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer); -+ if (enable) -+ tmpReg |= FM_PCD_PRS_DOUBLE_ECC; -+ else -+ tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC; -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg); -+ break; -+ case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): -+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever); -+ if (enable) -+ tmpReg |= FM_PCD_PRS_SINGLE_ECC; -+ else -+ tmpReg &= ~FM_PCD_PRS_SINGLE_ECC; -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg); -+ break; -+ case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): -+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier); -+ if (enable) -+ tmpReg |= FM_PCD_PLCR_DOUBLE_ECC; -+ else -+ tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC; -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg); -+ break; -+ case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): -+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier); -+ if (enable) -+ tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR; -+ else -+ tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR; -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg); -+ break; -+ case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): -+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier); -+ if (enable) -+ tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE; -+ else -+ tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE; -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg); -+ break; -+ case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): -+ tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier); -+ if (enable) -+ tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE; -+ else -+ tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE; -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg); -+ break; -+ } -+ /* for ECC exceptions driver automatically enables ECC mechanism, if disabled. -+ Driver may disable them automatically, depending on driver's status */ -+ if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) | -+ (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) | -+ (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) | -+ (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC))) -+ FmEnableRamsEcc(p_FmPcd->h_Fm); -+ if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) | -+ (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) | -+ (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) | -+ (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC))) -+ FmDisableRamsEcc(p_FmPcd->h_Fm); -+ } -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!")); -+ -+ switch (exception) -+ { -+ case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC): -+ case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW): -+ if (!p_FmPcd->p_FmPcdKg) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working")); -+ break; -+ case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC): -+ case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR): -+ case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE): -+ case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE): -+ if (!p_FmPcd->p_FmPcdPlcr) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working")); -+ break; -+ case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC): -+ case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC): -+ if (!p_FmPcd->p_FmPcdPrs) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working")); -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested")); -+ } -+ switch (exception) -+ { -+ case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: -+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ break; -+ case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: -+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ break; -+ case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: -+ if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC); -+ break; -+ case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: -+ if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW); -+ break; -+ case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: -+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC); -+ break; -+ case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: -+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR); -+ break; -+ case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: -+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE); -+ break; -+ case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: -+ if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE); -+ break; -+ } -+ -+ return E_OK; -+} -+ -+ -+t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!")); -+ -+ switch (counter) -+ { -+ case (e_FM_PCD_KG_COUNTERS_TOTAL): -+ if (!p_FmPcd->p_FmPcdKg) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working")); -+ break; -+ case (e_FM_PCD_PLCR_COUNTERS_YELLOW): -+ case (e_FM_PCD_PLCR_COUNTERS_RED): -+ case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): -+ case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): -+ case (e_FM_PCD_PLCR_COUNTERS_TOTAL): -+ case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): -+ if (!p_FmPcd->p_FmPcdPlcr) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working")); -+ if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): -+ case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): -+ case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): -+ case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): -+ case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): -+ case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): -+ case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): -+ case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): -+ case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): -+ case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): -+ case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): -+ if (!p_FmPcd->p_FmPcdPrs) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter")); -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter")); -+ } -+ switch (counter) -+ { -+ case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value); -+ break; -+ case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value); -+ break; -+ case (e_FM_PCD_KG_COUNTERS_TOTAL): -+ WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value); -+ break; -+ -+ /*Policer counters*/ -+ case (e_FM_PCD_PLCR_COUNTERS_YELLOW): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value); -+ break; -+ case (e_FM_PCD_PLCR_COUNTERS_RED): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value); -+ break; -+ case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value); -+ break; -+ case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value); -+ break; -+ case (e_FM_PCD_PLCR_COUNTERS_TOTAL): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value); -+ break; -+ case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH): -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value); -+ break; -+ } -+ -+ return E_OK; -+} -+ -+t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ return FmHcGetPort(p_FmPcd->h_Hc); -+} -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h -@@ -0,0 +1,543 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_pcd.h -+ -+ @Description FM PCD ... -+*//***************************************************************************/ -+#ifndef __FM_PCD_H -+#define __FM_PCD_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "list_ext.h" -+#include "fm_pcd_ext.h" -+#include "fm_common.h" -+#include "fsl_fman_prs.h" -+#include "fsl_fman_kg.h" -+ -+#define __ERR_MODULE__ MODULE_FM_PCD -+ -+ -+/****************************/ -+/* Defaults */ -+/****************************/ -+#define DEFAULT_plcrAutoRefresh FALSE -+#define DEFAULT_fmPcdKgErrorExceptions (FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW) -+#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR) -+#define DEFAULT_fmPcdPlcrExceptions 0 -+#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC) -+ -+#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC -+#define DEFAULT_numOfUsedProfilesPerWindow 16 -+#define DEFAULT_numOfSharedPlcrProfiles 4 -+ -+/****************************/ -+/* Network defines */ -+/****************************/ -+#define UDP_HEADER_SIZE 8 -+ -+#define ESP_SPI_OFFSET 0 -+#define ESP_SPI_SIZE 4 -+#define ESP_SEQ_NUM_OFFSET ESP_SPI_SIZE -+#define ESP_SEQ_NUM_SIZE 4 -+ -+/****************************/ -+/* General defines */ -+/****************************/ -+#define ILLEGAL_CLS_PLAN 0xff -+#define ILLEGAL_NETENV 0xff -+ -+#define FM_PCD_MAX_NUM_OF_ALIAS_HDRS 3 -+ -+/****************************/ -+/* Error defines */ -+/****************************/ -+ -+#define FM_PCD_EX_PLCR_DOUBLE_ECC 0x20000000 -+#define FM_PCD_EX_PLCR_INIT_ENTRY_ERROR 0x10000000 -+#define FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE 0x08000000 -+#define FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE 0x04000000 -+ -+#define GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception) \ -+switch (exception){ \ -+ case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: \ -+ bitMask = FM_EX_KG_DOUBLE_ECC; break; \ -+ case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: \ -+ bitMask = FM_PCD_EX_PLCR_DOUBLE_ECC; break; \ -+ case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: \ -+ bitMask = FM_EX_KG_KEYSIZE_OVERFLOW; break; \ -+ case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: \ -+ bitMask = FM_PCD_EX_PLCR_INIT_ENTRY_ERROR; break; \ -+ case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: \ -+ bitMask = FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE; break; \ -+ case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: \ -+ bitMask = FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE; break; \ -+ case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: \ -+ bitMask = FM_PCD_EX_PRS_DOUBLE_ECC; break; \ -+ case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: \ -+ bitMask = FM_PCD_EX_PRS_SINGLE_ECC; break; \ -+ default: bitMask = 0;break;} -+ -+/***********************************************************************/ -+/* Policer defines */ -+/***********************************************************************/ -+#define FM_PCD_PLCR_GCR_STEN 0x40000000 -+#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000 -+#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000 -+#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000 -+#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000 -+ -+/***********************************************************************/ -+/* Memory map */ -+/***********************************************************************/ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+typedef struct { -+/* General Configuration and Status Registers */ -+ volatile uint32_t fmpl_gcr; /* 0x000 FMPL_GCR - FM Policer General Configuration */ -+ volatile uint32_t fmpl_gsr; /* 0x004 FMPL_GSR - FM Policer Global Status Register */ -+ volatile uint32_t fmpl_evr; /* 0x008 FMPL_EVR - FM Policer Event Register */ -+ volatile uint32_t fmpl_ier; /* 0x00C FMPL_IER - FM Policer Interrupt Enable Register */ -+ volatile uint32_t fmpl_ifr; /* 0x010 FMPL_IFR - FM Policer Interrupt Force Register */ -+ volatile uint32_t fmpl_eevr; /* 0x014 FMPL_EEVR - FM Policer Error Event Register */ -+ volatile uint32_t fmpl_eier; /* 0x018 FMPL_EIER - FM Policer Error Interrupt Enable Register */ -+ volatile uint32_t fmpl_eifr; /* 0x01C FMPL_EIFR - FM Policer Error Interrupt Force Register */ -+/* Global Statistic Counters */ -+ volatile uint32_t fmpl_rpcnt; /* 0x020 FMPL_RPC - FM Policer RED Packets Counter */ -+ volatile uint32_t fmpl_ypcnt; /* 0x024 FMPL_YPC - FM Policer YELLOW Packets Counter */ -+ volatile uint32_t fmpl_rrpcnt; /* 0x028 FMPL_RRPC - FM Policer Recolored RED Packet Counter */ -+ volatile uint32_t fmpl_rypcnt; /* 0x02C FMPL_RYPC - FM Policer Recolored YELLOW Packet Counter */ -+ volatile uint32_t fmpl_tpcnt; /* 0x030 FMPL_TPC - FM Policer Total Packet Counter */ -+ volatile uint32_t fmpl_flmcnt; /* 0x034 FMPL_FLMC - FM Policer Frame Length Mismatch Counter */ -+ volatile uint32_t fmpl_res0[21]; /* 0x038 - 0x08B Reserved */ -+/* Profile RAM Access Registers */ -+ volatile uint32_t fmpl_par; /* 0x08C FMPL_PAR - FM Policer Profile Action Register*/ -+ t_FmPcdPlcrProfileRegs profileRegs; -+/* Error Capture Registers */ -+ volatile uint32_t fmpl_serc; /* 0x100 FMPL_SERC - FM Policer Soft Error Capture */ -+ volatile uint32_t fmpl_upcr; /* 0x104 FMPL_UPCR - FM Policer Uninitialized Profile Capture Register */ -+ volatile uint32_t fmpl_res2; /* 0x108 Reserved */ -+/* Debug Registers */ -+ volatile uint32_t fmpl_res3[61]; /* 0x10C-0x200 Reserved Debug*/ -+/* Profile Selection Mapping Registers Per Port-ID (n=1-11, 16) */ -+ volatile uint32_t fmpl_dpmr; /* 0x200 FMPL_DPMR - FM Policer Default Mapping Register */ -+ volatile uint32_t fmpl_pmr[63]; /*+default 0x204-0x2FF FMPL_PMR1 - FMPL_PMR63, - FM Policer Profile Mapping Registers. -+ (for port-ID 1-11, only for supported Port-ID registers) */ -+} t_FmPcdPlcrRegs; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+/***********************************************************************/ -+/* Driver's internal structures */ -+/***********************************************************************/ -+ -+typedef struct { -+ bool known; -+ uint8_t id; -+} t_FmPcdKgSchemesExtractsEntry; -+ -+typedef struct { -+ t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; -+} t_FmPcdKgSchemesExtracts; -+ -+typedef struct { -+ t_Handle h_Manip; -+ bool keepRes; -+ e_FmPcdEngine nextEngine; -+ uint8_t parseCode; -+} t_FmPcdInfoForManip; -+ -+/**************************************************************************//** -+ @Description A structure of parameters to communicate -+ between the port and PCD regarding the KG scheme. -+*//***************************************************************************/ -+typedef struct { -+ uint8_t netEnvId; /* in */ -+ uint8_t numOfDistinctionUnits; /* in */ -+ uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */ -+ uint32_t vector; /* out */ -+} t_NetEnvParams; -+ -+typedef struct { -+ bool allocated; -+ uint8_t ownerId; /* guestId for KG in multi-partition only. -+ portId for PLCR in any environment */ -+} t_FmPcdAllocMng; -+ -+typedef struct { -+ volatile bool lock; -+ bool used; -+ uint8_t owners; -+ uint8_t netEnvId; -+ uint8_t guestId; -+ uint8_t baseEntry; -+ uint16_t sizeOfGrp; -+ protocolOpt_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)]; -+} t_FmPcdKgClsPlanGrp; -+ -+typedef struct { -+ t_Handle h_FmPcd; -+ uint8_t schemeId; -+ t_FmPcdLock *p_Lock; -+ bool valid; -+ uint8_t netEnvId; -+ uint8_t owners; -+ uint32_t matchVector; -+ uint32_t ccUnits; -+ bool nextRelativePlcrProfile; -+ uint16_t relativeProfileId; -+ uint16_t numOfProfiles; -+ t_FmPcdKgKeyOrder orderedArray; -+ e_FmPcdEngine nextEngine; -+ e_FmPcdDoneAction doneAction; -+ bool requiredActionFlag; -+ uint32_t requiredAction; -+ bool extractedOrs; -+ uint8_t bitOffsetInPlcrProfile; -+ bool directPlcr; -+#if (DPAA_VERSION >= 11) -+ bool vspe; -+#endif -+} t_FmPcdKgScheme; -+ -+typedef union { -+ struct fman_kg_scheme_regs schemeRegs; -+ struct fman_kg_pe_regs portRegs; -+ struct fman_kg_cp_regs clsPlanRegs; -+} u_FmPcdKgIndirectAccessRegs; -+ -+typedef struct { -+ struct fman_kg_regs *p_FmPcdKgRegs; -+ uint32_t schemeExceptionsBitMask; -+ uint8_t numOfSchemes; -+ t_Handle h_HwSpinlock; -+ uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES]; -+ t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES]; -+ t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS]; -+ uint8_t emptyClsPlanGrpId; -+ t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */ -+ t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP]; -+ u_FmPcdKgIndirectAccessRegs *p_IndirectAccessRegs; -+} t_FmPcdKg; -+ -+typedef struct { -+ uint16_t profilesBase; -+ uint16_t numOfProfiles; -+ t_Handle h_FmPort; -+} t_FmPcdPlcrMapParam; -+ -+typedef struct { -+ uint16_t absoluteProfileId; -+ t_Handle h_FmPcd; -+ bool valid; -+ t_FmPcdLock *p_Lock; -+ t_FmPcdAllocMng profilesMng; -+ bool requiredActionFlag; -+ uint32_t requiredAction; -+ e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */ -+ u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */ -+ -+ e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */ -+ u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */ -+ -+ e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */ -+ u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */ -+} t_FmPcdPlcrProfile; -+ -+typedef struct { -+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; -+ uint16_t partPlcrProfilesBase; -+ uint16_t partNumOfPlcrProfiles; -+ t_FmPcdPlcrProfile profiles[FM_PCD_PLCR_NUM_ENTRIES]; -+ uint16_t numOfSharedProfiles; -+ uint16_t sharedProfilesIds[FM_PCD_PLCR_NUM_ENTRIES]; -+ t_FmPcdPlcrMapParam portsMapping[FM_MAX_NUM_OF_PORTS]; -+ t_Handle h_HwSpinlock; -+ t_Handle h_SwSpinlock; -+} t_FmPcdPlcr; -+ -+typedef struct { -+ uint32_t *p_SwPrsCode; -+ uint32_t *p_CurrSwPrs; -+ uint8_t currLabel; -+ struct fman_prs_regs *p_FmPcdPrsRegs; -+ t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS]; -+ uint32_t fmPcdPrsPortIdStatistics; -+} t_FmPcdPrs; -+ -+typedef struct { -+ struct { -+ e_NetHeaderType hdr; -+ protocolOpt_t opt; /* only one option !! */ -+ } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS]; -+} t_FmPcdIntDistinctionUnit; -+ -+typedef struct { -+ e_NetHeaderType hdr; -+ protocolOpt_t opt; /* only one option !! */ -+ e_NetHeaderType aliasHdr; -+} t_FmPcdNetEnvAliases; -+ -+typedef struct { -+ uint8_t netEnvId; -+ t_Handle h_FmPcd; -+ t_Handle h_Spinlock; -+ bool used; -+ uint8_t owners; -+ uint8_t clsPlanGrpId; -+ t_FmPcdIntDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; -+ uint32_t unitsVectors[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; -+ uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS]; -+ uint32_t macsecVector; -+ t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_ALIAS_HDRS]; -+} t_FmPcdNetEnv; -+ -+typedef struct { -+ struct fman_prs_cfg dfltCfg; -+ bool plcrAutoRefresh; -+ uint16_t prsMaxParseCycleLimit; -+} t_FmPcdDriverParam; -+ -+typedef struct { -+ t_Handle h_Fm; -+ t_Handle h_FmMuram; -+ t_FmRevisionInfo fmRevInfo; -+ -+ uint64_t physicalMuramBase; -+ -+ t_Handle h_Spinlock; -+ t_List freeLocksLst; -+ t_List acquiredLocksLst; -+ -+ t_Handle h_IpcSession; /* relevant for guest only */ -+ bool enabled; -+ uint8_t guestId; /**< Guest Partition Id */ -+ uint8_t numOfEnabledGuestPartitionsPcds; -+ char fmPcdModuleName[MODULE_NAME_SIZE]; -+ char fmPcdIpcHandlerModuleName[MODULE_NAME_SIZE]; /* relevant for guest only - this is the master's name */ -+ t_FmPcdNetEnv netEnvs[FM_MAX_NUM_OF_PORTS]; -+ t_FmPcdKg *p_FmPcdKg; -+ t_FmPcdPlcr *p_FmPcdPlcr; -+ t_FmPcdPrs *p_FmPcdPrs; -+ -+ void *p_CcShadow; /**< CC MURAM shadow */ -+ uint32_t ccShadowSize; -+ uint32_t ccShadowAlign; -+ volatile bool shadowLock; -+ t_Handle h_ShadowSpinlock; -+ -+ t_Handle h_Hc; -+ -+ uint32_t exceptions; -+ t_FmPcdExceptionCallback *f_Exception; -+ t_FmPcdIdExceptionCallback *f_FmPcdIndexedException; -+ t_Handle h_App; -+ uintptr_t ipv6FrameIdAddr; -+ uintptr_t capwapFrameIdAddr; -+ bool advancedOffloadSupport; -+ -+ t_FmPcdDriverParam *p_FmPcdDriverParam; -+} t_FmPcd; -+ -+#if (DPAA_VERSION >= 11) -+typedef uint8_t t_FmPcdFrmReplicUpdateType; -+#define FRM_REPLIC_UPDATE_COUNTER 0x01 -+#define FRM_REPLIC_UPDATE_INFO 0x02 -+#endif /* (DPAA_VERSION >= 11) */ -+/***********************************************************************/ -+/* PCD internal routines */ -+/***********************************************************************/ -+ -+t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector); -+t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params); -+bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector); -+t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams); -+void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId); -+e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr); -+uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr); -+uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt); -+ -+t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, bool isIpv4, uint8_t groupId); -+t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip); -+t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, uint8_t groupId); -+t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip); -+bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip); -+ -+t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams); -+t_Error KgInit(t_FmPcd *p_FmPcd); -+t_Error KgFree(t_FmPcd *p_FmPcd); -+void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set); -+bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId); -+void KgEnable(t_FmPcd *p_FmPcd); -+void KgDisable(t_FmPcd *p_FmPcd); -+t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First); -+void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base); -+ -+/* only for MULTI partittion */ -+t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds); -+t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds); -+/* only for SINGLE partittion */ -+t_Error KgBindPortToSchemes(t_Handle h_FmPcd , uint8_t hardwarePortId, uint32_t spReg); -+ -+t_FmPcdLock *FmPcdAcquireLock(t_Handle h_FmPcd); -+void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock); -+ -+t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams); -+t_Error PlcrInit(t_FmPcd *p_FmPcd); -+t_Error PlcrFree(t_FmPcd *p_FmPcd); -+void PlcrEnable(t_FmPcd *p_FmPcd); -+void PlcrDisable(t_FmPcd *p_FmPcd); -+uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId); -+void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId); -+t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd, -+ uint8_t hardwarePortId, -+ uint16_t numOfProfiles, -+ uint16_t base); -+t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId); -+ -+t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams); -+t_Error PrsInit(t_FmPcd *p_FmPcd); -+void PrsEnable(t_FmPcd *p_FmPcd); -+void PrsDisable(t_FmPcd *p_FmPcd); -+void PrsFree(t_FmPcd *p_FmPcd ); -+t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include); -+ -+t_Error FmPcdCcGetGrpParams(t_Handle treeId, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase); -+uint8_t FmPcdCcGetOffset(t_Handle h_CcNode); -+uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode); -+uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode); -+t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, e_FmPcdCcStatsMode supportedStatsMode); -+ -+void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add); -+t_Error FmPcdManipCheckParamsForCcNextEngine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction); -+void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip, -+ t_FmPcdCcNextEngineParams *p_CcNextEngineParams, -+ t_Handle p_Ad, -+ t_Handle *p_AdNewPtr); -+void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset); -+void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add); -+t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode); -+#ifdef FM_CAPWAP_SUPPORT -+t_Handle FmPcdManipApplSpecificBuild(void); -+bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip); -+#endif /* FM_CAPWAP_SUPPORT */ -+#if (DPAA_VERSION >= 11) -+void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup); -+void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, bool add); -+void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, void *p_Ad, t_Handle *h_AdNew); -+ -+void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node, -+ t_Handle h_ReplicGroup, -+ t_List *p_AdTables, -+ uint32_t *p_NumOfAdTables); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, t_Handle h_Spinlock); -+void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock); -+t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock); -+t_List *FmPcdManipGetSpinlock(t_Handle h_Manip); -+t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip); -+ -+typedef struct -+{ -+ t_Handle h_StatsAd; -+ t_Handle h_StatsCounters; -+#if (DPAA_VERSION >= 11) -+ t_Handle h_StatsFLRs; -+#endif /* (DPAA_VERSION >= 11) */ -+} t_FmPcdCcStatsParams; -+ -+void NextStepAd(t_Handle h_Ad, -+ t_FmPcdCcStatsParams *p_FmPcdCcStatsParams, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, -+ t_FmPcd *p_FmPcd); -+void ReleaseLst(t_List *p_List); -+ -+static __inline__ t_Handle FmPcdGetMuramHandle(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ ASSERT_COND(p_FmPcd); -+ return p_FmPcd->h_FmMuram; -+} -+ -+static __inline__ uint64_t FmPcdGetMuramPhysBase(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ ASSERT_COND(p_FmPcd); -+ return p_FmPcd->physicalMuramBase; -+} -+ -+static __inline__ uint32_t FmPcdLockSpinlock(t_FmPcdLock *p_Lock) -+{ -+ ASSERT_COND(p_Lock); -+ return XX_LockIntrSpinlock(p_Lock->h_Spinlock); -+} -+ -+static __inline__ void FmPcdUnlockSpinlock(t_FmPcdLock *p_Lock, uint32_t flags) -+{ -+ ASSERT_COND(p_Lock); -+ XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, flags); -+} -+ -+static __inline__ bool FmPcdLockTryLock(t_FmPcdLock *p_Lock) -+{ -+ uint32_t intFlags; -+ -+ ASSERT_COND(p_Lock); -+ intFlags = XX_LockIntrSpinlock(p_Lock->h_Spinlock); -+ if (p_Lock->flag) -+ { -+ XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags); -+ return FALSE; -+ } -+ p_Lock->flag = TRUE; -+ XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags); -+ return TRUE; -+} -+ -+static __inline__ void FmPcdLockUnlock(t_FmPcdLock *p_Lock) -+{ -+ ASSERT_COND(p_Lock); -+ p_Lock->flag = FALSE; -+} -+ -+ -+#endif /* __FM_PCD_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h -@@ -0,0 +1,280 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File fm_pcd_ipc.h -+ -+ @Description FM PCD Inter-Partition prototypes, structures and definitions. -+*//***************************************************************************/ -+#ifndef __FM_PCD_IPC_H -+#define __FM_PCD_IPC_H -+ -+#include "std_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group FM_grp Frame Manager API -+ -+ @Description FM API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+/**************************************************************************//** -+ @Description Structure for getting a sw parser address according to a label -+ Fields commented 'IN' are passed by the port module to be used -+ by the FM module. -+ Fields commented 'OUT' will be filled by FM before returning to port. -+*//***************************************************************************/ -+typedef _Packed struct t_FmPcdIpcSwPrsLable -+{ -+ uint32_t enumHdr; /**< IN. The existence of this header will invoke -+ the sw parser code. */ -+ uint8_t indexPerHdr; /**< IN. Normally 0, if more than one sw parser -+ attachments for the same header, use this -+ -+ index to distinguish between them. */ -+} _PackedType t_FmPcdIpcSwPrsLable; -+ -+/**************************************************************************//** -+ @Description Structure for port-PCD communication. -+ Fields commented 'IN' are passed by the port module to be used -+ by the FM module. -+ Fields commented 'OUT' will be filled by FM before returning to port. -+ Some fields are optional (depending on configuration) and -+ will be analized by the port and FM modules accordingly. -+*//***************************************************************************/ -+ -+typedef struct t_FmPcdIpcKgSchemesParams -+{ -+ uint8_t guestId; -+ uint8_t numOfSchemes; -+ uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES]; -+} _PackedType t_FmPcdIpcKgSchemesParams; -+ -+typedef struct t_FmPcdIpcKgClsPlanParams -+{ -+ uint8_t guestId; -+ uint16_t numOfClsPlanEntries; -+ uint8_t clsPlanBase; -+} _PackedType t_FmPcdIpcKgClsPlanParams; -+ -+typedef _Packed struct t_FmPcdIpcPrsIncludePort -+{ -+ uint8_t hardwarePortId; -+ bool include; -+} _PackedType t_FmPcdIpcPrsIncludePort; -+ -+ -+#define FM_PCD_MAX_REPLY_SIZE 16 -+#define FM_PCD_MAX_MSG_SIZE 36 -+#define FM_PCD_MAX_REPLY_BODY_SIZE 36 -+ -+typedef _Packed struct { -+ uint32_t msgId; -+ uint8_t msgBody[FM_PCD_MAX_MSG_SIZE]; -+} _PackedType t_FmPcdIpcMsg; -+ -+typedef _Packed struct t_FmPcdIpcReply { -+ uint32_t error; -+ uint8_t replyBody[FM_PCD_MAX_REPLY_BODY_SIZE]; -+} _PackedType t_FmPcdIpcReply; -+ -+typedef _Packed struct t_FmIpcResourceAllocParams { -+ uint8_t guestId; -+ uint16_t base; -+ uint16_t num; -+}_PackedType t_FmIpcResourceAllocParams; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+ -+/**************************************************************************//** -+ @Function FM_PCD_ALLOC_KG_SCHEMES -+ -+ @Description Used by FM PCD front-end in order to allocate KG resources -+ -+ @Param[in/out] t_FmPcdIpcKgAllocParams Pointer -+*//***************************************************************************/ -+#define FM_PCD_ALLOC_KG_SCHEMES 3 -+ -+/**************************************************************************//** -+ @Function FM_PCD_FREE_KG_SCHEMES -+ -+ @Description Used by FM PCD front-end in order to Free KG resources -+ -+ @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer -+*//***************************************************************************/ -+#define FM_PCD_FREE_KG_SCHEMES 4 -+ -+/**************************************************************************//** -+ @Function FM_PCD_ALLOC_PROFILES -+ -+ @Description Used by FM PCD front-end in order to allocate Policer profiles -+ -+ @Param[in/out] t_FmIpcResourceAllocParams Pointer -+*//***************************************************************************/ -+#define FM_PCD_ALLOC_PROFILES 5 -+ -+/**************************************************************************//** -+ @Function FM_PCD_FREE_PROFILES -+ -+ @Description Used by FM PCD front-end in order to Free Policer profiles -+ -+ @Param[in/out] t_FmIpcResourceAllocParams Pointer -+*//***************************************************************************/ -+#define FM_PCD_FREE_PROFILES 6 -+ -+/**************************************************************************//** -+ @Function FM_PCD_SET_PORT_PROFILES -+ -+ @Description Used by FM PCD front-end in order to allocate Policer profiles -+ for specific port -+ -+ @Param[in/out] t_FmIpcResourceAllocParams Pointer -+*//***************************************************************************/ -+#define FM_PCD_SET_PORT_PROFILES 7 -+ -+/**************************************************************************//** -+ @Function FM_PCD_CLEAR_PORT_PROFILES -+ -+ @Description Used by FM PCD front-end in order to allocate Policer profiles -+ for specific port -+ -+ @Param[in/out] t_FmIpcResourceAllocParams Pointer -+*//***************************************************************************/ -+#define FM_PCD_CLEAR_PORT_PROFILES 8 -+ -+/**************************************************************************//** -+ @Function FM_PCD_GET_PHYS_MURAM_BASE -+ -+ @Description Used by FM PCD front-end in order to get MURAM base address -+ -+ @Param[in/out] t_FmPcdIcPhysAddr Pointer -+*//***************************************************************************/ -+#define FM_PCD_GET_PHYS_MURAM_BASE 9 -+ -+/**************************************************************************//** -+ @Function FM_PCD_GET_SW_PRS_OFFSET -+ -+ @Description Used by FM front-end to get the SW parser offset of the start of -+ code relevant to a given label. -+ -+ @Param[in/out] t_FmPcdIpcSwPrsLable Pointer -+*//***************************************************************************/ -+#define FM_PCD_GET_SW_PRS_OFFSET 10 -+ -+/**************************************************************************//** -+ @Function FM_PCD_MASTER_IS_ENABLED -+ -+ @Description Used by FM front-end in order to verify -+ PCD enablement. -+ -+ @Param[in] bool Pointer -+*//***************************************************************************/ -+#define FM_PCD_MASTER_IS_ENABLED 15 -+ -+/**************************************************************************//** -+ @Function FM_PCD_GUEST_DISABLE -+ -+ @Description Used by FM front-end to inform back-end when -+ front-end PCD is disabled -+ -+ @Param[in] None -+*//***************************************************************************/ -+#define FM_PCD_GUEST_DISABLE 16 -+ -+/**************************************************************************//** -+ @Function FM_PCD_FREE_KG_CLSPLAN -+ -+ @Description Used by FM PCD front-end in order to Free KG classification plan entries -+ -+ @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer -+*//***************************************************************************/ -+#define FM_PCD_FREE_KG_CLSPLAN 22 -+ -+/**************************************************************************//** -+ @Function FM_PCD_ALLOC_KG_CLSPLAN -+ -+ @Description Used by FM PCD front-end in order to allocate KG classification plan entries -+ -+ @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer -+*//***************************************************************************/ -+#define FM_PCD_ALLOC_KG_CLSPLAN 23 -+ -+/**************************************************************************//** -+ @Function FM_PCD_MASTER_IS_ALIVE -+ -+ @Description Used by FM front-end to check that back-end exists -+ -+ @Param[in] None -+*//***************************************************************************/ -+#define FM_PCD_MASTER_IS_ALIVE 24 -+ -+/**************************************************************************//** -+ @Function FM_PCD_GET_COUNTER -+ -+ @Description Used by FM front-end to read PCD counters -+ -+ @Param[in/out] t_FmPcdIpcGetCounter Pointer -+*//***************************************************************************/ -+#define FM_PCD_GET_COUNTER 25 -+ -+/**************************************************************************//** -+ @Function FM_PCD_PRS_INC_PORT_STATS -+ -+ @Description Used by FM front-end to set/clear statistics for port -+ -+ @Param[in/out] t_FmPcdIpcPrsIncludePort Pointer -+*//***************************************************************************/ -+#define FM_PCD_PRS_INC_PORT_STATS 26 -+ -+#if (DPAA_VERSION >= 11) -+/* TODO - doc */ -+#define FM_PCD_ALLOC_SP 27 -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ -+/** @} */ /* end of FM_PCD_IPC_grp group */ -+/** @} */ /* end of FM_grp group */ -+ -+ -+#endif /* __FM_PCD_IPC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c -@@ -0,0 +1,1847 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_plcr.c -+ -+ @Description FM PCD POLICER... -+*//***************************************************************************/ -+#include -+#include "std_ext.h" -+#include "error_ext.h" -+#include "string_ext.h" -+#include "debug_ext.h" -+#include "net_ext.h" -+#include "fm_ext.h" -+ -+#include "fm_common.h" -+#include "fm_pcd.h" -+#include "fm_hc.h" -+#include "fm_pcd_ipc.h" -+#include "fm_plcr.h" -+ -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+ -+static uint32_t PlcrProfileLock(t_Handle h_Profile) -+{ -+ ASSERT_COND(h_Profile); -+ return FmPcdLockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock); -+} -+ -+static void PlcrProfileUnlock(t_Handle h_Profile, uint32_t intFlags) -+{ -+ ASSERT_COND(h_Profile); -+ FmPcdUnlockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock, intFlags); -+} -+ -+static bool PlcrProfileFlagTryLock(t_Handle h_Profile) -+{ -+ ASSERT_COND(h_Profile); -+ return FmPcdLockTryLock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock); -+} -+ -+static void PlcrProfileFlagUnlock(t_Handle h_Profile) -+{ -+ ASSERT_COND(h_Profile); -+ FmPcdLockUnlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock); -+} -+ -+static uint32_t PlcrHwLock(t_Handle h_FmPcdPlcr) -+{ -+ ASSERT_COND(h_FmPcdPlcr); -+ return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock); -+} -+ -+static void PlcrHwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags) -+{ -+ ASSERT_COND(h_FmPcdPlcr); -+ XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock, intFlags); -+} -+ -+static uint32_t PlcrSwLock(t_Handle h_FmPcdPlcr) -+{ -+ ASSERT_COND(h_FmPcdPlcr); -+ return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock); -+} -+ -+static void PlcrSwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags) -+{ -+ ASSERT_COND(h_FmPcdPlcr); -+ XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock, intFlags); -+} -+ -+static bool IsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint16_t i; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE); -+ -+ for (i=0;ip_FmPcdPlcr->numOfSharedProfiles;i++) -+ if (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId) -+ return TRUE; -+ return FALSE; -+} -+ -+static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction) -+{ -+ uint32_t nia; -+ uint16_t absoluteProfileId; -+ uint8_t relativeSchemeId, physicalSchemeId; -+ -+ nia = FM_PCD_PLCR_NIA_VALID; -+ -+ switch (nextEngine) -+ { -+ case e_FM_PCD_DONE : -+ switch (p_NextEngineParams->action) -+ { -+ case e_FM_PCD_DROP_FRAME : -+ nia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd); -+ break; -+ case e_FM_PCD_ENQ_FRAME: -+ nia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd); -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ break; -+ case e_FM_PCD_KG: -+ physicalSchemeId = FmPcdKgGetSchemeId(p_NextEngineParams->h_DirectScheme); -+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId); -+ if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG); -+ if (!FmPcdKgIsSchemeValidSw(p_NextEngineParams->h_DirectScheme)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme.")); -+ if (!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct.")); -+ nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicalSchemeId; -+ break; -+ case e_FM_PCD_PLCR: -+ absoluteProfileId = ((t_FmPcdPlcrProfile *)p_NextEngineParams->h_Profile)->absoluteProfileId; -+ if (!IsProfileShared(p_FmPcd, absoluteProfileId)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile")); -+ if (!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile ")); -+ nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ -+ *nextAction = nia; -+ -+ return E_OK; -+} -+ -+static uint32_t CalcFPP(uint32_t fpp) -+{ -+ if (fpp > 15) -+ return 15 - (0x1f - fpp); -+ else -+ return 16 + fpp; -+} -+ -+static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode, -+ uint32_t rate, -+ uint64_t tsuInTenthNano, -+ uint32_t fppShift, -+ uint64_t *p_Integer, -+ uint64_t *p_Fraction) -+{ -+ uint64_t tmp, div; -+ -+ if (rateMode == e_FM_PCD_PLCR_BYTE_MODE) -+ { -+ /* now we calculate the initial integer for the bigger rate */ -+ /* from Kbps to Bytes/TSU */ -+ tmp = (uint64_t)rate; -+ tmp *= 1000; /* kb --> b */ -+ tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */ -+ -+ div = 1000000000; /* nano */ -+ div *= 10; /* 10 nano */ -+ div *= 8; /* bit to byte */ -+ } -+ else -+ { -+ /* now we calculate the initial integer for the bigger rate */ -+ /* from Kbps to Bytes/TSU */ -+ tmp = (uint64_t)rate; -+ tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */ -+ -+ div = 1000000000; /* nano */ -+ div *= 10; /* 10 nano */ -+ } -+ *p_Integer = div64_u64(tmp<committedInfoRate > p_NonPassthroughAlgParam->peakOrExcessInfoRate) -+ GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, 0, &integer, &fraction); -+ else -+ GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, 0, &integer, &fraction); -+ -+ /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and -+ * the LSB bits are for the fraction */ -+ temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF); -+ /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll -+ * take max FP = 31. -+ * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is -+ * limited by the 10G physical port. -+ */ -+ if (temp != 0) -+ { -+ /* In this case, the largest rate integer is non 0, if it does not occupy all (high) 16 -+ * bits of the PIR_EIR we can use this fact and enlarge it to occupy all 16 bits. -+ * The logic is to have as many bits for integer in the higher rates, but if we have "0"s -+ * in the integer part of the cir/pir register, than these bits are wasted. So we want -+ * to use these bits for the fraction. in this way we will have for fraction - the number -+ * of "0" bits and the rest - for integer. -+ * In other words: For each bit we shift it in PIR_EIR, we move the FP in the TS -+ * one bit to the left - preserving the relationship and achieving more bits -+ * for integer in the TS. -+ */ -+ -+ /* count zeroes left of the higher used bit (in order to shift the value such that -+ * unused bits may be used for fraction). -+ */ -+ while ((temp & 0x80000000) == 0) -+ { -+ temp = temp << 1; -+ fppShift++; -+ } -+ if (fppShift > 15) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small")); -+ return; -+ } -+ } -+ else -+ { -+ temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */ -+ if (!temp) -+ /* integer and fraction are 0, we set FP to its max val */ -+ fppShift = 31; -+ else -+ { -+ /* integer was 0 but fraction is not. FP is 16 for the fraction, -+ * + all left zeroes of the fraction. */ -+ fppShift=16; -+ /* count zeroes left of the higher used bit (in order to shift the value such that -+ * unused bits may be used for fraction). -+ */ -+ while ((temp & 0x8000) == 0) -+ { -+ temp = temp << 1; -+ fppShift++; -+ } -+ } -+ } -+ -+ /* -+ * This means that the FM TS register will now be used so that 'fppShift' bits are for -+ * fraction and the rest for integer */ -+ /* now we re-calculate cir and pir_eir with the calculated FP */ -+ GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction); -+ *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF)); -+ GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction); -+ *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF)); -+ -+ *cbs = p_NonPassthroughAlgParam->committedBurstSize; -+ *pbs_ebs = p_NonPassthroughAlgParam->peakOrExcessBurstSize; -+ -+ /* convert FP as it should be written to reg. -+ * 0-15 --> 16-31 -+ * 16-31 --> 0-15 -+ */ -+ *fpp = CalcFPP(fppShift); -+} -+ -+static void WritePar(t_FmPcd *p_FmPcd, uint32_t par) -+{ -+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; -+ -+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); -+ WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par); -+ -+ while (GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ; -+} -+ -+static t_Error BuildProfileRegs(t_FmPcd *p_FmPcd, -+ t_FmPcdPlcrProfileParams *p_ProfileParams, -+ t_FmPcdPlcrProfileRegs *p_PlcrRegs) -+{ -+ t_Error err = E_OK; -+ uint32_t pemode, gnia, ynia, rnia, bitFor1Micro; -+ -+ ASSERT_COND(p_FmPcd); -+ -+ bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm); -+ if (bitFor1Micro == 0) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale")); -+ -+/* Set G, Y, R Nia */ -+ err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnGreen, &(p_ProfileParams->paramsOnGreen), &gnia); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnYellow, &(p_ProfileParams->paramsOnYellow), &ynia); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnRed, &(p_ProfileParams->paramsOnRed), &rnia); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+/* Mode fmpl_pemode */ -+ pemode = FM_PCD_PLCR_PEMODE_PI; -+ -+ switch (p_ProfileParams->algSelection) -+ { -+ case e_FM_PCD_PLCR_PASS_THROUGH: -+ p_PlcrRegs->fmpl_pecir = 0; -+ p_PlcrRegs->fmpl_pecbs = 0; -+ p_PlcrRegs->fmpl_pepepir_eir = 0; -+ p_PlcrRegs->fmpl_pepbs_ebs = 0; -+ p_PlcrRegs->fmpl_pelts = 0; -+ p_PlcrRegs->fmpl_pects = 0; -+ p_PlcrRegs->fmpl_pepts_ets = 0; -+ pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK; -+ switch (p_ProfileParams->colorMode) -+ { -+ case e_FM_PCD_PLCR_COLOR_BLIND: -+ pemode |= FM_PCD_PLCR_PEMODE_CBLND; -+ switch (p_ProfileParams->color.dfltColor) -+ { -+ case e_FM_PCD_PLCR_GREEN: -+ pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK; -+ break; -+ case e_FM_PCD_PLCR_YELLOW: -+ pemode |= FM_PCD_PLCR_PEMODE_DEFC_Y; -+ break; -+ case e_FM_PCD_PLCR_RED: -+ pemode |= FM_PCD_PLCR_PEMODE_DEFC_R; -+ break; -+ case e_FM_PCD_PLCR_OVERRIDE: -+ pemode |= FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ -+ break; -+ case e_FM_PCD_PLCR_COLOR_AWARE: -+ pemode &= ~FM_PCD_PLCR_PEMODE_CBLND; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ break; -+ -+ case e_FM_PCD_PLCR_RFC_2698: -+ /* Select algorithm MODE[ALG] = "01" */ -+ pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698; -+ if (p_ProfileParams->nonPassthroughAlgParams.committedInfoRate > p_ProfileParams->nonPassthroughAlgParams.peakOrExcessInfoRate) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than committedInfoRate.")); -+ goto cont_rfc; -+ case e_FM_PCD_PLCR_RFC_4115: -+ /* Select algorithm MODE[ALG] = "10" */ -+ pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115; -+cont_rfc: -+ /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */ -+ switch (p_ProfileParams->colorMode) -+ { -+ case e_FM_PCD_PLCR_COLOR_BLIND: -+ pemode |= FM_PCD_PLCR_PEMODE_CBLND; -+ break; -+ case e_FM_PCD_PLCR_COLOR_AWARE: -+ pemode &= ~FM_PCD_PLCR_PEMODE_CBLND; -+ /*In color aware more select override color interpretation (MODE[OVCLR]) */ -+ switch (p_ProfileParams->color.override) -+ { -+ case e_FM_PCD_PLCR_GREEN: -+ pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK; -+ break; -+ case e_FM_PCD_PLCR_YELLOW: -+ pemode |= FM_PCD_PLCR_PEMODE_OVCLR_Y; -+ break; -+ case e_FM_PCD_PLCR_RED: -+ pemode |= FM_PCD_PLCR_PEMODE_OVCLR_R; -+ break; -+ case e_FM_PCD_PLCR_OVERRIDE: -+ pemode |= FM_PCD_PLCR_PEMODE_OVCLR_G_NC; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */ -+ switch (p_ProfileParams->nonPassthroughAlgParams.rateMode) -+ { -+ case e_FM_PCD_PLCR_BYTE_MODE : -+ pemode &= ~FM_PCD_PLCR_PEMODE_PKT; -+ switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.frameLengthSelection) -+ { -+ case e_FM_PCD_PLCR_L2_FRM_LEN: -+ pemode |= FM_PCD_PLCR_PEMODE_FLS_L2; -+ break; -+ case e_FM_PCD_PLCR_L3_FRM_LEN: -+ pemode |= FM_PCD_PLCR_PEMODE_FLS_L3; -+ break; -+ case e_FM_PCD_PLCR_L4_FRM_LEN: -+ pemode |= FM_PCD_PLCR_PEMODE_FLS_L4; -+ break; -+ case e_FM_PCD_PLCR_FULL_FRM_LEN: -+ pemode |= FM_PCD_PLCR_PEMODE_FLS_FULL; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection) -+ { -+ case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN: -+ pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS; -+ break; -+ case e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN: -+ pemode |= FM_PCD_PLCR_PEMODE_RBFLS; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ break; -+ case e_FM_PCD_PLCR_PACKET_MODE : -+ pemode |= FM_PCD_PLCR_PEMODE_PKT; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ /* Select timeStamp floating point position (MODE[FPP]) to fit the actual traffic rates. For PACKET -+ mode with low traffic rates move the fixed point to the left to increase fraction accuracy. For BYTE -+ mode with high traffic rates move the fixed point to the right to increase integer accuracy. */ -+ -+ /* Configure Traffic Parameters*/ -+ { -+ uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0; -+ -+ CalcRates(bitFor1Micro, &p_ProfileParams->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp); -+ -+ /* Set Committed Information Rate (CIR) */ -+ p_PlcrRegs->fmpl_pecir = cir; -+ /* Set Committed Burst Size (CBS). */ -+ p_PlcrRegs->fmpl_pecbs = cbs; -+ /* Set Peak Information Rate (PIR_EIR used as PIR) */ -+ p_PlcrRegs->fmpl_pepepir_eir = pir_eir; -+ /* Set Peak Burst Size (PBS_EBS used as PBS) */ -+ p_PlcrRegs->fmpl_pepbs_ebs = pbs_ebs; -+ -+ /* Initialize the Metering Buckets to be full (write them with 0xFFFFFFFF. */ -+ /* Peak Rate Token Bucket Size (PTS_ETS used as PTS) */ -+ p_PlcrRegs->fmpl_pepts_ets = 0xFFFFFFFF; -+ /* Committed Rate Token Bucket Size (CTS) */ -+ p_PlcrRegs->fmpl_pects = 0xFFFFFFFF; -+ -+ /* Set the FPP based on calculation */ -+ pemode |= (fpp << FM_PCD_PLCR_PEMODE_FPP_SHIFT); -+ } -+ break; /* FM_PCD_PLCR_PEMODE_ALG_RFC2698 , FM_PCD_PLCR_PEMODE_ALG_RFC4115 */ -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ -+ p_PlcrRegs->fmpl_pemode = pemode; -+ -+ p_PlcrRegs->fmpl_pegnia = gnia; -+ p_PlcrRegs->fmpl_peynia = ynia; -+ p_PlcrRegs->fmpl_pernia = rnia; -+ -+ /* Zero Counters */ -+ p_PlcrRegs->fmpl_pegpc = 0; -+ p_PlcrRegs->fmpl_peypc = 0; -+ p_PlcrRegs->fmpl_perpc = 0; -+ p_PlcrRegs->fmpl_perypc = 0; -+ p_PlcrRegs->fmpl_perrpc = 0; -+ -+ return E_OK; -+} -+ -+static t_Error AllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds) -+{ -+ uint32_t profilesFound; -+ uint16_t i, k=0; -+ uint32_t intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ -+ if (!numOfProfiles) -+ return E_OK; -+ -+ if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big.")); -+ -+ intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr); -+ /* Find numOfProfiles free profiles (may be spread) */ -+ profilesFound = 0; -+ for (i=0;ip_FmPcdPlcr->profiles[i].profilesMng.allocated) -+ { -+ profilesFound++; -+ profilesIds[k] = i; -+ k++; -+ if (profilesFound == numOfProfiles) -+ break; -+ } -+ -+ if (profilesFound != numOfProfiles) -+ { -+ PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); -+ RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG); -+ } -+ -+ for (i = 0;ip_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE; -+ p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0; -+ } -+ PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); -+ -+ return E_OK; -+} -+ -+static void FreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds) -+{ -+ uint16_t i; -+ -+ SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE); -+ -+ ASSERT_COND(numOfProfiles); -+ -+ for (i=0; i < numOfProfiles; i++) -+ { -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated); -+ p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE; -+ p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = p_FmPcd->guestId; -+ } -+} -+ -+static void UpdateRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool set) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ /* this routine is protected by calling routine */ -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); -+ -+ if (set) -+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = TRUE; -+ else -+ { -+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = 0; -+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = FALSE; -+ } -+} -+ -+/*********************************************/ -+/*............Policer Exception..............*/ -+/*********************************************/ -+static void EventsCB(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint32_t event, mask, force; -+ -+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); -+ event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr); -+ mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier); -+ -+ event &= mask; -+ -+ /* clear the forced events */ -+ force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr); -+ if (force & event) -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event); -+ -+ -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event); -+ -+ if (event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE) -+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE); -+ if (event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE) -+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE); -+} -+ -+/* ..... */ -+ -+static void ErrorExceptionsCB(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint32_t event, force, captureReg, mask; -+ -+ ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm)); -+ event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr); -+ mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier); -+ -+ event &= mask; -+ -+ /* clear the forced events */ -+ force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr); -+ if (force & event) -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event); -+ -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event); -+ -+ if (event & FM_PCD_PLCR_DOUBLE_ECC) -+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC); -+ if (event & FM_PCD_PLCR_INIT_ENTRY_ERROR) -+ { -+ captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr); -+ /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP); -+ p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK); -+ p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ; -+ p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/ -+ p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK)); -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP); -+ } -+} -+ -+ -+/*****************************************************************************/ -+/* Inter-module API routines */ -+/*****************************************************************************/ -+ -+t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams) -+{ -+ t_FmPcdPlcr *p_FmPcdPlcr; -+ uint16_t i=0; -+ -+ UNUSED(p_FmPcd); -+ UNUSED(p_FmPcdParams); -+ -+ p_FmPcdPlcr = (t_FmPcdPlcr *) XX_Malloc(sizeof(t_FmPcdPlcr)); -+ if (!p_FmPcdPlcr) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer structure allocation FAILED")); -+ return NULL; -+ } -+ memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr)); -+ if (p_FmPcd->guestId == NCSW_MASTER_ID) -+ { -+ p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm)); -+ p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh; -+ p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions); -+ } -+ -+ p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles; -+ -+ p_FmPcdPlcr->partPlcrProfilesBase = p_FmPcdParams->partPlcrProfilesBase; -+ p_FmPcdPlcr->partNumOfPlcrProfiles = p_FmPcdParams->partNumOfPlcrProfiles; -+ /* for backward compatabilty. if no policer profile, will set automatically to the max */ -+ if ((p_FmPcd->guestId == NCSW_MASTER_ID) && -+ (p_FmPcdPlcr->partNumOfPlcrProfiles == 0)) -+ p_FmPcdPlcr->partNumOfPlcrProfiles = FM_PCD_PLCR_NUM_ENTRIES; -+ -+ for (i=0; iprofiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE; -+ -+ return p_FmPcdPlcr; -+} -+ -+t_Error PlcrInit(t_FmPcd *p_FmPcd) -+{ -+ t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam; -+ t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; -+ t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; -+ t_Error err = E_OK; -+ uint32_t tmpReg32 = 0; -+ uint16_t base; -+ -+ if ((p_FmPcdPlcr->partPlcrProfilesBase + p_FmPcdPlcr->partNumOfPlcrProfiles) > FM_PCD_PLCR_NUM_ENTRIES) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partPlcrProfilesBase+partNumOfPlcrProfiles out of range!!!")); -+ -+ p_FmPcdPlcr->h_HwSpinlock = XX_InitSpinlock(); -+ if (!p_FmPcdPlcr->h_HwSpinlock) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer HW spinlock")); -+ -+ p_FmPcdPlcr->h_SwSpinlock = XX_InitSpinlock(); -+ if (!p_FmPcdPlcr->h_SwSpinlock) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer SW spinlock")); -+ -+ base = PlcrAllocProfilesForPartition(p_FmPcd, -+ p_FmPcdPlcr->partPlcrProfilesBase, -+ p_FmPcdPlcr->partNumOfPlcrProfiles, -+ p_FmPcd->guestId); -+ if (base == (uint16_t)ILLEGAL_BASE) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ -+ if (p_FmPcdPlcr->numOfSharedProfiles) -+ { -+ err = AllocSharedProfiles(p_FmPcd, -+ p_FmPcdPlcr->numOfSharedProfiles, -+ p_FmPcdPlcr->sharedProfilesIds); -+ if (err) -+ RETURN_ERROR(MAJOR, err,NO_MSG); -+ } -+ -+ if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ return E_OK; -+ -+ /**********************FMPL_GCR******************/ -+ tmpReg32 = 0; -+ tmpReg32 |= FM_PCD_PLCR_GCR_STEN; -+ if (p_Param->plcrAutoRefresh) -+ tmpReg32 |= FM_PCD_PLCR_GCR_DAR; -+ tmpReg32 |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd); -+ -+ WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32); -+ /**********************FMPL_GCR******************/ -+ -+ /**********************FMPL_EEVR******************/ -+ WRITE_UINT32(p_Regs->fmpl_eevr, (FM_PCD_PLCR_DOUBLE_ECC | FM_PCD_PLCR_INIT_ENTRY_ERROR)); -+ /**********************FMPL_EEVR******************/ -+ /**********************FMPL_EIER******************/ -+ tmpReg32 = 0; -+ if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC) -+ { -+ FmEnableRamsEcc(p_FmPcd->h_Fm); -+ tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC; -+ } -+ if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR) -+ tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR; -+ WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32); -+ /**********************FMPL_EIER******************/ -+ -+ /**********************FMPL_EVR******************/ -+ WRITE_UINT32(p_Regs->fmpl_evr, (FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE | FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE)); -+ /**********************FMPL_EVR******************/ -+ /**********************FMPL_IER******************/ -+ tmpReg32 = 0; -+ if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE) -+ tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE; -+ if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE) -+ tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE; -+ WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32); -+ /**********************FMPL_IER******************/ -+ -+ /* register even if no interrupts enabled, to allow future enablement */ -+ FmRegisterIntr(p_FmPcd->h_Fm, -+ e_FM_MOD_PLCR, -+ 0, -+ e_FM_INTR_TYPE_ERR, -+ ErrorExceptionsCB, -+ p_FmPcd); -+ FmRegisterIntr(p_FmPcd->h_Fm, -+ e_FM_MOD_PLCR, -+ 0, -+ e_FM_INTR_TYPE_NORMAL, -+ EventsCB, -+ p_FmPcd); -+ -+ /* driver initializes one DFLT profile at the last entry*/ -+ /**********************FMPL_DPMR******************/ -+ tmpReg32 = 0; -+ WRITE_UINT32(p_Regs->fmpl_dpmr, tmpReg32); -+ p_FmPcd->p_FmPcdPlcr->profiles[0].profilesMng.allocated = TRUE; -+ -+ return E_OK; -+} -+ -+t_Error PlcrFree(t_FmPcd *p_FmPcd) -+{ -+ FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR); -+ FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL); -+ -+ if (p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles) -+ FreeSharedProfiles(p_FmPcd, -+ p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles, -+ p_FmPcd->p_FmPcdPlcr->sharedProfilesIds); -+ -+ if (p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles) -+ PlcrFreeProfilesForPartition(p_FmPcd, -+ p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, -+ p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles, -+ p_FmPcd->guestId); -+ -+ if (p_FmPcd->p_FmPcdPlcr->h_SwSpinlock) -+ XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_SwSpinlock); -+ -+ if (p_FmPcd->p_FmPcdPlcr->h_HwSpinlock) -+ XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_HwSpinlock); -+ -+ return E_OK; -+} -+ -+void PlcrEnable(t_FmPcd *p_FmPcd) -+{ -+ t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; -+ -+ WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN); -+} -+ -+void PlcrDisable(t_FmPcd *p_FmPcd) -+{ -+ t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; -+ -+ WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN); -+} -+ -+uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId) -+{ -+ uint32_t intFlags; -+ uint16_t profilesFound = 0; -+ int i = 0; -+ -+ ASSERT_COND(p_FmPcd); -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr); -+ -+ if (!numOfProfiles) -+ return 0; -+ -+ if ((numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES) || -+ (base + numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES)) -+ return (uint16_t)ILLEGAL_BASE; -+ -+ if (p_FmPcd->h_IpcSession) -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ t_FmPcdIpcMsg msg; -+ t_FmPcdIpcReply reply; -+ t_Error err; -+ uint32_t replyLength; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); -+ ipcAllocParams.guestId = p_FmPcd->guestId; -+ ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles; -+ ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase; -+ msg.msgId = FM_PCD_ALLOC_PROFILES; -+ memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); -+ replyLength = sizeof(uint32_t) + sizeof(uint16_t); -+ err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if ((err != E_OK) || -+ (replyLength != (sizeof(uint32_t) + sizeof(uint16_t)))) -+ { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return (uint16_t)ILLEGAL_BASE; -+ } -+ else -+ memcpy((uint8_t*)&p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, reply.replyBody, sizeof(uint16_t)); -+ if (p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase == (uint16_t)ILLEGAL_BASE) -+ { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return (uint16_t)ILLEGAL_BASE; -+ } -+ } -+ else if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ { -+ DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!")); -+ return (uint16_t)ILLEGAL_BASE; -+ } -+ -+ intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock); -+ for (i=base; i<(base+numOfProfiles); i++) -+ if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE) -+ profilesFound++; -+ else -+ break; -+ -+ if (profilesFound == numOfProfiles) -+ for (i=base; i<(base+numOfProfiles); i++) -+ p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = guestId; -+ else -+ { -+ XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); -+ return (uint16_t)ILLEGAL_BASE; -+ } -+ XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags); -+ -+ return base; -+} -+ -+void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId) -+{ -+ int i = 0; -+ -+ ASSERT_COND(p_FmPcd); -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr); -+ -+ if (p_FmPcd->h_IpcSession) -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ t_FmPcdIpcMsg msg; -+ t_Error err; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); -+ ipcAllocParams.guestId = p_FmPcd->guestId; -+ ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles; -+ ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase; -+ msg.msgId = FM_PCD_FREE_PROFILES; -+ memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); -+ err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return; -+ } -+ else if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ { -+ DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!")); -+ return; -+ } -+ -+ for (i=base; i<(base+numOfProfiles); i++) -+ { -+ if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == guestId) -+ p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE; -+ else -+ DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition")); -+ } -+} -+ -+t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd, -+ uint8_t hardwarePortId, -+ uint16_t numOfProfiles, -+ uint16_t base) -+{ -+ t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; -+ uint32_t log2Num, tmpReg32; -+ -+ if ((p_FmPcd->guestId != NCSW_MASTER_ID) && -+ !p_Regs && -+ p_FmPcd->h_IpcSession) -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ t_FmPcdIpcMsg msg; -+ t_Error err; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); -+ ipcAllocParams.guestId = hardwarePortId; -+ ipcAllocParams.num = numOfProfiles; -+ ipcAllocParams.base = base; -+ msg.msgId = FM_PCD_SET_PORT_PROFILES; -+ memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); -+ err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ return E_OK; -+ } -+ else if (!p_Regs) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("Either IPC or 'baseAddress' is required!")); -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ -+ if (GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("The requesting port has already an allocated profiles window.")); -+ -+ /**********************FMPL_PMRx******************/ -+ LOG2((uint64_t)numOfProfiles, log2Num); -+ tmpReg32 = base; -+ tmpReg32 |= log2Num << 16; -+ tmpReg32 |= FM_PCD_PLCR_PMR_V; -+ WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32); -+ -+ return E_OK; -+} -+ -+t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId) -+{ -+ t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; -+ -+ if ((p_FmPcd->guestId != NCSW_MASTER_ID) && -+ !p_Regs && -+ p_FmPcd->h_IpcSession) -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ t_FmPcdIpcMsg msg; -+ t_Error err; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); -+ ipcAllocParams.guestId = hardwarePortId; -+ msg.msgId = FM_PCD_CLEAR_PORT_PROFILES; -+ memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); -+ err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ return E_OK; -+ } -+ else if (!p_Regs) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("Either IPC or 'baseAddress' is required!")); -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0); -+ -+ return E_OK; -+} -+ -+t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_Error err = E_OK; -+ uint32_t profilesFound; -+ uint32_t intFlags; -+ uint16_t i, first, swPortIndex = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ -+ if (!numOfProfiles) -+ return E_OK; -+ -+ ASSERT_COND(hardwarePortId); -+ -+ if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big.")); -+ -+ if (!POWER_OF_2(numOfProfiles)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2.")); -+ -+ first = 0; -+ profilesFound = 0; -+ intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr); -+ -+ for (i=0; ip_FmPcdPlcr->profiles[i].profilesMng.allocated) -+ { -+ profilesFound++; -+ i++; -+ if (profilesFound == numOfProfiles) -+ break; -+ } -+ else -+ { -+ profilesFound = 0; -+ /* advance i to the next aligned address */ -+ i = first = (uint16_t)(first + numOfProfiles); -+ } -+ } -+ -+ if (profilesFound == numOfProfiles) -+ { -+ for (i=first; ip_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE; -+ p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId; -+ } -+ } -+ else -+ { -+ PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); -+ RETURN_ERROR(MINOR, E_FULL, ("No profiles.")); -+ } -+ PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); -+ -+ err = PlcrSetPortProfiles(p_FmPcd, hardwarePortId, numOfProfiles, first); -+ if (err) -+ { -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); -+ -+ p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles; -+ p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = first; -+ -+ return E_OK; -+} -+ -+t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_Error err = E_OK; -+ uint32_t intFlags; -+ uint16_t i, swPortIndex = 0; -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); -+ -+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); -+ -+ err = PlcrClearPortProfiles(p_FmPcd, hardwarePortId); -+ if (err) -+ RETURN_ERROR(MAJOR, err,NO_MSG); -+ -+ intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr); -+ for (i=p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase; -+ i<(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + -+ p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles); -+ i++) -+ { -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId); -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated); -+ -+ p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE; -+ p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = p_FmPcd->guestId; -+ } -+ PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); -+ -+ p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0; -+ p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0; -+ -+ return E_OK; -+} -+ -+t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; -+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs; -+ uint32_t tmpReg32, intFlags; -+ t_Error err; -+ -+ /* Calling function locked all PCD modules, so no need to lock here */ -+ -+ if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range")); -+ -+ if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileIndx)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid")); -+ -+ /*intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx]);*/ -+ -+ if (p_FmPcd->h_Hc) -+ { -+ err = FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction); -+ -+ UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE); -+ FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction); -+ -+ /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ -+ return err; -+ } -+ -+ /* lock the HW because once we read the registers we don't want them to be changed -+ * by another access. (We can copy to a tmp location and release the lock!) */ -+ -+ intFlags = PlcrHwLock(p_FmPcdPlcr); -+ WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx)); -+ -+ if (!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredActionFlag || -+ !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction)) -+ { -+ if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) -+ { -+ if ((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) || -+ (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) || -+ (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE)) -+ { -+ PlcrHwUnlock(p_FmPcdPlcr, intFlags); -+ /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ -+ RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE")); -+ } -+ -+ if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME) -+ { -+ tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia); -+ if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) -+ { -+ PlcrHwUnlock(p_FmPcdPlcr, intFlags); -+ /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); -+ } -+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32); -+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); -+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA; -+ WritePar(p_FmPcd, tmpReg32); -+ } -+ -+ if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME) -+ { -+ tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia); -+ if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) -+ { -+ PlcrHwUnlock(p_FmPcdPlcr, intFlags); -+ /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); -+ } -+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32); -+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); -+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA; -+ WritePar(p_FmPcd, tmpReg32); -+ PlcrHwUnlock(p_FmPcdPlcr, intFlags); -+ } -+ -+ if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME) -+ { -+ tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia); -+ if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))) -+ { -+ PlcrHwUnlock(p_FmPcdPlcr, intFlags); -+ /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE")); -+ } -+ tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA; -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32); -+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); -+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA; -+ WritePar(p_FmPcd, tmpReg32); -+ -+ } -+ } -+ } -+ PlcrHwUnlock(p_FmPcdPlcr, intFlags); -+ -+ UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE); -+ FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction); -+ -+ /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/ -+ -+ return E_OK; -+} -+ -+uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); -+ -+ return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag; -+} -+ -+uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); -+ -+ return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction; -+} -+ -+bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; -+ -+ ASSERT_COND(absoluteProfileId < FM_PCD_PLCR_NUM_ENTRIES); -+ -+ return p_FmPcdPlcr->profiles[absoluteProfileId].valid; -+} -+ -+void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t intFlags; -+ -+ ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); -+ -+ intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]); -+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE; -+ PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags); -+} -+ -+void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t intFlags; -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); -+ -+ intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]); -+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE; -+ PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags); -+} -+ -+uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile) -+{ -+ return ((t_FmPcdPlcrProfile*)h_Profile)->absoluteProfileId; -+} -+ -+t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd, -+ e_FmPcdProfileTypeSelection profileType, -+ t_Handle h_FmPort, -+ uint16_t relativeProfile, -+ uint16_t *p_AbsoluteId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr; -+ uint8_t i; -+ -+ switch (profileType) -+ { -+ case e_FM_PCD_PLCR_PORT_PRIVATE: -+ /* get port PCD id from port handle */ -+ for (i=0;ip_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort) -+ break; -+ if (i == FM_MAX_NUM_OF_PORTS) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle.")); -+ -+ if (!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles")); -+ if (relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range")); -+ *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile); -+ break; -+ case e_FM_PCD_PLCR_SHARED: -+ if (relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range")); -+ *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]); -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type")); -+ } -+ -+ return E_OK; -+} -+ -+uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint16_t swPortIndex = 0; -+ -+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); -+ -+ return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase; -+} -+ -+uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint16_t swPortIndex = 0; -+ -+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); -+ -+ return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles; -+ -+} -+uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId) -+{ -+ return (uint32_t)(FM_PCD_PLCR_PAR_GO | -+ ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT)); -+} -+ -+uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId) -+{ -+ return (uint32_t)(FM_PCD_PLCR_PAR_GO | -+ ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) | -+ FM_PCD_PLCR_PAR_PWSEL_MASK); -+} -+ -+bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg) -+{ -+ -+ if (profileModeReg & FM_PCD_PLCR_PEMODE_PI) -+ return TRUE; -+ else -+ return FALSE; -+} -+ -+uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId) -+{ -+ return (uint32_t)(FM_PCD_PLCR_PAR_GO | -+ FM_PCD_PLCR_PAR_R | -+ ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) | -+ FM_PCD_PLCR_PAR_PWSEL_MASK); -+} -+ -+uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter) -+{ -+ switch (counter) -+ { -+ case (e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER): -+ return FM_PCD_PLCR_PAR_PWSEL_PEGPC; -+ case (e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER): -+ return FM_PCD_PLCR_PAR_PWSEL_PEYPC; -+ case (e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) : -+ return FM_PCD_PLCR_PAR_PWSEL_PERPC; -+ case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) : -+ return FM_PCD_PLCR_PAR_PWSEL_PERYPC; -+ case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) : -+ return FM_PCD_PLCR_PAR_PWSEL_PERRPC; -+ default: -+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ return 0; -+ } -+} -+ -+uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red) -+{ -+ -+ uint32_t tmpReg32 = 0; -+ -+ if (green) -+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA; -+ if (yellow) -+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA; -+ if (red) -+ tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA; -+ -+ return tmpReg32; -+} -+ -+void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ /* this routine is protected by calling routine */ -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid); -+ -+ p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction |= requiredAction; -+} -+ -+/*********************** End of inter-module routines ************************/ -+ -+ -+/**************************************************/ -+/*............Policer API.........................*/ -+/**************************************************/ -+ -+t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); -+ -+ if (!FmIsMaster(p_FmPcd->h_Fm)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!")); -+ -+ p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable; -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); -+ -+ p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles; -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t tmpReg32; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE); -+ -+ if (!FmIsMaster(p_FmPcd->h_Fm)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!")); -+ -+ tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr); -+ if (enable) -+ tmpReg32 |= FM_PCD_PLCR_GCR_STEN; -+ else -+ tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN; -+ -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32); -+ return E_OK; -+} -+ -+t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd, -+ t_FmPcdPlcrProfileParams *p_ProfileParams) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; -+ t_FmPcdPlcrProfileRegs plcrProfileReg; -+ uint32_t intFlags; -+ uint16_t absoluteProfileId; -+ t_Error err = E_OK; -+ uint32_t tmpReg32; -+ t_FmPcdPlcrProfile *p_Profile; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); -+ -+ if (p_ProfileParams->modify) -+ { -+ p_Profile = (t_FmPcdPlcrProfile *)p_ProfileParams->id.h_Profile; -+ p_FmPcd = p_Profile->h_FmPcd; -+ absoluteProfileId = p_Profile->absoluteProfileId; -+ if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big ")); -+ return NULL; -+ } -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL); -+ -+ /* Try lock profile using flag */ -+ if (!PlcrProfileFlagTryLock(p_Profile)) -+ { -+ DBG(TRACE, ("Profile Try Lock - BUSY")); -+ /* Signal to caller BUSY condition */ -+ p_ProfileParams->id.h_Profile = NULL; -+ return NULL; -+ } -+ } -+ else -+ { -+ p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL); -+ -+ /* SMP: needs to be protected only if another core now changes the windows */ -+ err = FmPcdPlcrGetAbsoluteIdByProfileParams(h_FmPcd, -+ p_ProfileParams->id.newParams.profileType, -+ p_ProfileParams->id.newParams.h_FmPort, -+ p_ProfileParams->id.newParams.relativeProfileId, -+ &absoluteProfileId); -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return NULL; -+ } -+ -+ if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big ")); -+ return NULL; -+ } -+ -+ if (FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId)) -+ { -+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used")); -+ return NULL; -+ } -+ -+ /* initialize profile struct */ -+ p_Profile = &p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]; -+ -+ p_Profile->h_FmPcd = p_FmPcd; -+ p_Profile->absoluteProfileId = absoluteProfileId; -+ -+ p_Profile->p_Lock = FmPcdAcquireLock(p_FmPcd); -+ if (!p_Profile->p_Lock) -+ REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Policer Profile lock obj!")); -+ } -+ -+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL); -+ -+ p_Profile->nextEngineOnGreen = p_ProfileParams->nextEngineOnGreen; -+ memcpy(&p_Profile->paramsOnGreen, &(p_ProfileParams->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams)); -+ -+ p_Profile->nextEngineOnYellow = p_ProfileParams->nextEngineOnYellow; -+ memcpy(&p_Profile->paramsOnYellow, &(p_ProfileParams->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams)); -+ -+ p_Profile->nextEngineOnRed = p_ProfileParams->nextEngineOnRed; -+ memcpy(&p_Profile->paramsOnRed, &(p_ProfileParams->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams)); -+ -+ memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrProfileRegs)); -+ -+ /* build the policer profile registers */ -+ err = BuildProfileRegs(h_FmPcd, p_ProfileParams, &plcrProfileReg); -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ if (p_ProfileParams->modify) -+ /* unlock */ -+ PlcrProfileFlagUnlock(p_Profile); -+ if (!p_ProfileParams->modify && -+ p_Profile->p_Lock) -+ /* release allocated Profile lock */ -+ FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock); -+ return NULL; -+ } -+ -+ if (p_FmPcd->h_Hc) -+ { -+ err = FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, (t_Handle)p_Profile, &plcrProfileReg); -+ if (p_ProfileParams->modify) -+ PlcrProfileFlagUnlock(p_Profile); -+ if (err) -+ { -+ /* release the allocated scheme lock */ -+ if (!p_ProfileParams->modify && -+ p_Profile->p_Lock) -+ FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock); -+ -+ return NULL; -+ } -+ if (!p_ProfileParams->modify) -+ FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId); -+ return (t_Handle)p_Profile; -+ } -+ -+ p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; -+ SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL); -+ -+ intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia , plcrProfileReg.fmpl_pernia); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecir , plcrProfileReg.fmpl_pecir); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecbs , plcrProfileReg.fmpl_pecbs); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepepir_eir,plcrProfileReg.fmpl_pepepir_eir); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepbs_ebs,plcrProfileReg.fmpl_pepbs_ebs); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pelts , plcrProfileReg.fmpl_pelts); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pects , plcrProfileReg.fmpl_pects); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepts_ets,plcrProfileReg.fmpl_pepts_ets); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc , plcrProfileReg.fmpl_pegpc); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc , plcrProfileReg.fmpl_peypc); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc , plcrProfileReg.fmpl_perpc); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc , plcrProfileReg.fmpl_perypc); -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc , plcrProfileReg.fmpl_perrpc); -+ -+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId); -+ WritePar(p_FmPcd, tmpReg32); -+ -+ PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); -+ -+ if (!p_ProfileParams->modify) -+ FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId); -+ else -+ PlcrProfileFlagUnlock(p_Profile); -+ -+ return (t_Handle)p_Profile; -+} -+ -+t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile) -+{ -+ t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile; -+ t_FmPcd *p_FmPcd; -+ uint16_t profileIndx; -+ uint32_t tmpReg32, intFlags; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE); -+ p_FmPcd = p_Profile->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ -+ profileIndx = p_Profile->absoluteProfileId; -+ -+ UpdateRequiredActionFlag(p_FmPcd, profileIndx, FALSE); -+ -+ FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx); -+ -+ if (p_FmPcd->h_Hc) -+ { -+ err = FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile); -+ if (p_Profile->p_Lock) -+ /* release allocated Profile lock */ -+ FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock); -+ -+ return err; -+ } -+ -+ intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr); -+ WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI); -+ -+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx); -+ WritePar(p_FmPcd, tmpReg32); -+ PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); -+ -+ -+ if (p_Profile->p_Lock) -+ /* release allocated Profile lock */ -+ FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock); -+ -+ /* we do not memset profile as all its fields are being re-initialized at "set", -+ * plus its allocation information is still valid. */ -+ return E_OK; -+} -+ -+/***************************************************/ -+/*............Policer Profile Counter..............*/ -+/***************************************************/ -+uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter) -+{ -+ t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile; -+ t_FmPcd *p_FmPcd; -+ uint16_t profileIndx; -+ uint32_t intFlags, counterVal = 0; -+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE); -+ p_FmPcd = p_Profile->h_FmPcd; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ -+ if (p_FmPcd->h_Hc) -+ return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter); -+ -+ p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; -+ SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0); -+ -+ profileIndx = p_Profile->absoluteProfileId; -+ -+ if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big ")); -+ return 0; -+ } -+ intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr); -+ WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx)); -+ -+ switch (counter) -+ { -+ case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER: -+ counterVal = (GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc)); -+ break; -+ case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER: -+ counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc); -+ break; -+ case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER: -+ counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc); -+ break; -+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER: -+ counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc); -+ break; -+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER: -+ counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc); -+ break; -+ default: -+ REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ break; -+ } -+ PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); -+ -+ return counterVal; -+} -+ -+t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value) -+{ -+ t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile; -+ t_FmPcd *p_FmPcd; -+ uint16_t profileIndx; -+ uint32_t tmpReg32, intFlags; -+ t_FmPcdPlcrRegs *p_FmPcdPlcrRegs; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE); -+ -+ p_FmPcd = p_Profile->h_FmPcd; -+ profileIndx = p_Profile->absoluteProfileId; -+ -+ if (p_FmPcd->h_Hc) -+ return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value); -+ -+ p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; -+ SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE); -+ -+ intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr); -+ switch (counter) -+ { -+ case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER: -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc, value); -+ break; -+ case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER: -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc, value); -+ break; -+ case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER: -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc, value); -+ break; -+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER: -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc ,value); -+ break; -+ case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER: -+ WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value); -+ break; -+ default: -+ PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ -+ /* Activate the atomic write action by writing FMPL_PAR with: GO=1, RW=1, PSI=0, PNUM = -+ * Profile Number, PWSEL=0xFFFF (select all words). -+ */ -+ tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx); -+ tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter); -+ WritePar(p_FmPcd, tmpReg32); -+ PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags); -+ -+ return E_OK; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h -@@ -0,0 +1,165 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_plcr.h -+ -+ @Description FM Policer private header -+*//***************************************************************************/ -+#ifndef __FM_PLCR_H -+#define __FM_PLCR_H -+ -+#include "std_ext.h" -+ -+ -+/***********************************************************************/ -+/* Policer defines */ -+/***********************************************************************/ -+ -+#define FM_PCD_PLCR_PAR_GO 0x80000000 -+#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF -+#define FM_PCD_PLCR_PAR_R 0x40000000 -+ -+/* shifts */ -+#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16 -+ -+/* masks */ -+#define FM_PCD_PLCR_PEMODE_PI 0x80000000 -+#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000 -+#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000 -+#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000 -+#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000 -+#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000 -+#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000 -+#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000 -+#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000 -+#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000 -+#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000 -+#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000 -+#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000 -+#define FM_PCD_PLCR_PEMODE_PKT 0x00800000 -+#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000 -+#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16 -+#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000 -+#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000 -+#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000 -+#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000 -+#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000 -+#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800 -+#define FM_PCD_PLCR_PEMODE_TRA 0x00000004 -+#define FM_PCD_PLCR_PEMODE_TRB 0x00000002 -+#define FM_PCD_PLCR_PEMODE_TRC 0x00000001 -+#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000 -+#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000 -+#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000 -+#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000 -+ -+#define FM_PCD_PLCR_NIA_VALID 0x80000000 -+ -+#define FM_PCD_PLCR_GCR_EN 0x80000000 -+#define FM_PCD_PLCR_GCR_STEN 0x40000000 -+#define FM_PCD_PLCR_GCR_DAR 0x20000000 -+#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF -+#define FM_PCD_PLCR_NIA_ABS 0x00000100 -+ -+#define FM_PCD_PLCR_GSR_BSY 0x80000000 -+#define FM_PCD_PLCR_GSR_DQS 0x60000000 -+#define FM_PCD_PLCR_GSR_RPB 0x20000000 -+#define FM_PCD_PLCR_GSR_FQS 0x0C000000 -+#define FM_PCD_PLCR_GSR_LPALG 0x0000C000 -+#define FM_PCD_PLCR_GSR_LPCA 0x00003000 -+#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF -+ -+#define FM_PCD_PLCR_EVR_PSIC 0x80000000 -+#define FM_PCD_PLCR_EVR_AAC 0x40000000 -+ -+#define FM_PCD_PLCR_PAR_PSI 0x20000000 -+#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000 -+/* PWSEL Selctive select options */ -+#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */ -+#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */ -+ -+#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1] -+ 1-> 2^N specific locations. */ -+#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}. -+ 2-> 2^(N-1) base locations. */ -+#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}. -+ 4-> 2^(N-2) base locations. */ -+#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}. -+ 8->2^(N-3) base locations. */ -+#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}. -+ 16-> 2^(N-4) base locations. */ -+#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}. -+ 32-> 2^(N-5) base locations. */ -+#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}. -+ 64-> 2^(N-6) base locations. */ -+#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}. -+ 128-> 2^(N-7) base locations. */ -+#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}. -+ When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */ -+ -+#define FM_PCD_PLCR_PMR_V 0x80000000 -+#define PLCR_ERR_ECC_CAP 0x80000000 -+#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000 -+#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0 -+#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F -+ -+#define PLCR_ERR_UNINIT_CAP 0x80000000 -+#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF -+#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000 -+#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000 -+ -+/* shifts */ -+#define PLCR_ERR_ECC_PNUM_SHIFT 4 -+#define PLCR_ERR_UNINIT_PID_SHIFT 16 -+ -+#define FM_PCD_PLCR_PMR_BRN_SHIFT 16 -+ -+#define PLCR_PORT_WINDOW_SIZE(hardwarePortId) -+ -+ -+#endif /* __FM_PLCR_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c -@@ -0,0 +1,423 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_pcd.c -+ -+ @Description FM PCD ... -+*//***************************************************************************/ -+#include -+#include "std_ext.h" -+#include "error_ext.h" -+#include "string_ext.h" -+#include "debug_ext.h" -+#include "net_ext.h" -+ -+#include "fm_common.h" -+#include "fm_pcd.h" -+#include "fm_pcd_ipc.h" -+#include "fm_prs.h" -+#include "fsl_fman_prs.h" -+ -+ -+static void PcdPrsErrorException(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint32_t event, ev_mask; -+ struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; -+ -+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); -+ ev_mask = fman_prs_get_err_ev_mask(PrsRegs); -+ -+ event = fman_prs_get_err_event(PrsRegs, ev_mask); -+ -+ fman_prs_ack_err_event(PrsRegs, event); -+ -+ DBG(TRACE, ("parser error - 0x%08x\n",event)); -+ -+ if(event & FM_PCD_PRS_DOUBLE_ECC) -+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC); -+} -+ -+static void PcdPrsException(t_Handle h_FmPcd) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ uint32_t event, ev_mask; -+ struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; -+ -+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); -+ ev_mask = fman_prs_get_expt_ev_mask(PrsRegs); -+ event = fman_prs_get_expt_event(PrsRegs, ev_mask); -+ -+ ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC); -+ -+ DBG(TRACE, ("parser event - 0x%08x\n",event)); -+ -+ fman_prs_ack_expt_event(PrsRegs, event); -+ -+ p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC); -+} -+ -+t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams) -+{ -+ t_FmPcdPrs *p_FmPcdPrs; -+ uintptr_t baseAddr; -+ -+ UNUSED(p_FmPcd); -+ UNUSED(p_FmPcdParams); -+ -+ p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs)); -+ if (!p_FmPcdPrs) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED")); -+ return NULL; -+ } -+ memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs)); -+ fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg); -+ -+ if (p_FmPcd->guestId == NCSW_MASTER_ID) -+ { -+ baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm); -+ p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr); -+ p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET); -+ } -+ -+ p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat; -+ p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim; -+ p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions; -+ -+ return p_FmPcdPrs; -+} -+ -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+ static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH; -+#else -+ static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH; -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+t_Error PrsInit(t_FmPcd *p_FmPcd) -+{ -+ t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam; -+ uint32_t *p_TmpCode; -+ uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode, -+ FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE); -+ struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; -+ uint32_t i; -+ -+ ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE)); -+ -+ /* nothing to do in guest-partition */ -+ if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ return E_OK; -+ -+ p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t)); -+ if (!p_TmpCode) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED")); -+ memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4)); -+ memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch)); -+ -+ fman_prs_init(PrsRegs, &p_Param->dfltCfg); -+ -+ /* register even if no interrupts enabled, to allow future enablement */ -+ FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd); -+ -+ /* register even if no interrupts enabled, to allow future enablement */ -+ FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd); -+ -+ if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC) -+ FmEnableRamsEcc(p_FmPcd->h_Fm); -+ -+ if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC) -+ FmEnableRamsEcc(p_FmPcd->h_Fm); -+ -+ /* load sw parser Ip-Frag patch */ -+ for (i=0; iguestId == NCSW_MASTER_ID); -+ FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR); -+ /* register even if no interrupts enabled, to allow future enablement */ -+ FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL); -+} -+ -+void PrsEnable(t_FmPcd *p_FmPcd) -+{ -+ struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; -+ -+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); -+ fman_prs_enable(PrsRegs); -+} -+ -+void PrsDisable(t_FmPcd *p_FmPcd) -+{ -+ struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; -+ -+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); -+ fman_prs_disable(PrsRegs); -+} -+ -+int PrsIsEnabled(t_FmPcd *p_FmPcd) -+{ -+ struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; -+ -+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID); -+ return fman_prs_is_enabled(PrsRegs); -+} -+ -+t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include) -+{ -+ struct fman_prs_regs *PrsRegs; -+ uint32_t bitMask = 0; -+ uint8_t prsPortId; -+ -+ SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE); -+ -+ PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; -+ -+ GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId); -+ GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId); -+ -+ if (include) -+ p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask; -+ else -+ p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask; -+ -+ fman_prs_set_stst_port_msk(PrsRegs, -+ p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics); -+ -+ return E_OK; -+} -+ -+t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE); -+ -+ if ((p_FmPcd->guestId != NCSW_MASTER_ID) && -+ p_FmPcd->h_IpcSession) -+ { -+ t_FmPcdIpcPrsIncludePort prsIncludePortParams; -+ t_FmPcdIpcMsg msg; -+ -+ prsIncludePortParams.hardwarePortId = hardwarePortId; -+ prsIncludePortParams.include = include; -+ memset(&msg, 0, sizeof(msg)); -+ msg.msgId = FM_PCD_PRS_INC_PORT_STATS; -+ memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams)); -+ err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) +sizeof(prsIncludePortParams), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ return E_OK; -+ } -+ else if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without IPC!")); -+ -+ return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include); -+} -+ -+uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd; -+ t_FmPcdPrsLabelParams *p_Label; -+ int i; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0); -+ -+ if ((p_FmPcd->guestId != NCSW_MASTER_ID) && -+ p_FmPcd->h_IpcSession) -+ { -+ t_Error err = E_OK; -+ t_FmPcdIpcSwPrsLable labelParams; -+ t_FmPcdIpcMsg msg; -+ uint32_t prsOffset = 0; -+ t_FmPcdIpcReply reply; -+ uint32_t replyLength; -+ -+ memset(&reply, 0, sizeof(reply)); -+ memset(&msg, 0, sizeof(msg)); -+ labelParams.enumHdr = (uint32_t)hdr; -+ labelParams.indexPerHdr = indexPerHdr; -+ msg.msgId = FM_PCD_GET_SW_PRS_OFFSET; -+ memcpy(msg.msgBody, &labelParams, sizeof(labelParams)); -+ replyLength = sizeof(uint32_t) + sizeof(uint32_t); -+ err = XX_IpcSendMessage(p_FmPcd->h_IpcSession, -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) +sizeof(labelParams), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ if (replyLength != sizeof(uint32_t) + sizeof(uint32_t)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ -+ memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t)); -+ return prsOffset; -+ } -+ else if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without IPC!")); -+ -+ ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS); -+ -+ for (i=0; ip_FmPcdPrs->currLabel; i++) -+ { -+ p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i]; -+ -+ if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr)) -+ return p_Label->instructionOffset; -+ } -+ -+ REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found")); -+ return (uint32_t)ILLEGAL_BASE; -+} -+ -+void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ struct fman_prs_regs *PrsRegs; -+ -+ SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE); -+ -+ PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs; -+ -+ -+ if(p_FmPcd->guestId != NCSW_MASTER_ID) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!")); -+ return; -+ } -+ -+ fman_prs_set_stst(PrsRegs, enable); -+} -+ -+t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ uint32_t *p_LoadTarget; -+ uint32_t *p_TmpCode; -+ int i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE); -+ -+ if (p_FmPcd->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!")); -+ -+ if (!p_SwPrs->override) -+ { -+ if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code")); -+ } -+ else -+ p_FmPcd->p_FmPcdPrs->currLabel = 0; -+ -+ if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE")); -+ -+ if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed ")); -+ -+ p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t)); -+ if (!p_TmpCode) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED")); -+ memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4)); -+ memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size); -+ -+ /* save sw parser labels */ -+ memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel], -+ p_SwPrs->labelsTable, -+ p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams)); -+ p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels; -+ -+ /* load sw parser code */ -+ p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4; -+ -+ for(i=0; isize, 4); i++) -+ WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i])); -+ -+ p_FmPcd->p_FmPcdPrs->p_CurrSwPrs = -+ p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4); -+ -+ /* copy data parameters */ -+ for (i=0;ip_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]); -+ -+ /* Clear last 4 bytes */ -+ WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0); -+ -+ XX_FreeSmart(p_TmpCode); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value) -+{ -+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE); -+ -+ if(p_FmPcd->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!")); -+ -+ p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value; -+ -+ return E_OK; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h -@@ -0,0 +1,316 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_prs.h -+ -+ @Description FM Parser private header -+ *//***************************************************************************/ -+#ifndef __FM_PRS_H -+#define __FM_PRS_H -+ -+#include "std_ext.h" -+ -+/***********************************************************************/ -+/* SW parser IP_FRAG patch */ -+/***********************************************************************/ -+ -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+#define SW_PRS_UDP_LITE_PATCH \ -+{\ -+ 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x50,0x2C,0x40,0x00,0x31,0x92,0x50,0x2C, \ -+ 0x00,0x88,0x18,0x2F,0x00,0x01,0x1B,0xFE,0x18,0x71, \ -+ 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \ -+ 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x60,0x4F, \ -+ 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \ -+ 0x00,0x01,0x07,0x01,0x60,0x3B,0x00,0x00,0x30,0xD0, \ -+ 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \ -+ 0x40,0x4C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \ -+ 0x00,0x06,0x18,0x5D,0x00,0x00,0x9F,0xFF,0x30,0xF2, \ -+ 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \ -+ 0x00,0x08,0x28,0x1A,0x60,0x37,0x00,0x00,0x30,0xF2, \ -+ 0x18,0x5D,0x06,0x00,0x29,0x1E,0x30,0xF2,0x2F,0x0E, \ -+ 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x2F,0x0E, \ -+ 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \ -+ 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \ -+ 0x2F,0x0E,0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80, \ -+ 0x00,0x02,0x00,0x00,0x97,0x9E,0x40,0x7E,0x00,0x08, \ -+ 0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE,0x00,0x00, \ -+ 0x9F,0x9E,0x40,0xB3,0x00,0x00,0x02,0x1F,0x00,0x08, \ -+ 0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0,0x60,0x9F, \ -+ 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \ -+ 0x00,0x01,0x07,0x01,0x60,0x8B,0x00,0x00,0x30,0xD0, \ -+ 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \ -+ 0x40,0x9C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \ -+ 0x00,0x06,0x18,0xAD,0x00,0x00,0x9F,0xFF,0x30,0xF2, \ -+ 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \ -+ 0x00,0x08,0x28,0x1A,0x60,0x87,0x00,0x00,0x30,0xF2, \ -+ 0x18,0xAD,0x06,0x00,0x29,0x1E,0x30,0xF2,0x50,0xB3, \ -+ 0xFF,0xFF,0x18,0xB8,0x08,0x16,0x00,0x54,0x00,0x01, \ -+ 0x1B,0xFE,0x18,0xC5,0x32,0xF1,0x28,0x5D,0x32,0xF1, \ -+ 0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00,0x8F,0x9F, \ -+ 0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01,0x1B,0xFF, \ -+ 0x00,0x01,0x1B,0xFF \ -+} -+#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+ -+#if (DPAA_VERSION == 10) -+/* Version: 106.1.9 */ -+#define SW_PRS_OFFLOAD_PATCH \ -+{ \ -+ 0x31,0x52,0x00,0xDA,0x0A,0x00,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x43,0x0A,0x00,0x00,0x00,0x01,0x1B,0xFE, \ -+ 0x00,0x00,0x99,0x00,0x53,0x13,0x00,0x00,0x00,0x00, \ -+ 0x9F,0x98,0x53,0x13,0x00,0x00,0x1B,0x23,0x33,0xF1, \ -+ 0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \ -+ 0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x01, \ -+ 0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80,0x1F,0xFF, \ -+ 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x06,0x00, \ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x2F,0x00,0x00, \ -+ 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x00,0x40, \ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x00,0x00, \ -+ 0x00,0x00,0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55, \ -+ 0x00,0x28,0x28,0x43,0x30,0x7E,0x43,0x45,0x00,0x00, \ -+ 0x30,0x7E,0x43,0x45,0x00,0x3C,0x1B,0x5D,0x32,0x11, \ -+ 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x83,0x8F, \ -+ 0x2F,0x0F,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \ -+ 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \ -+ 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \ -+ 0x28,0x43,0x06,0x00,0x1B,0x3E,0x30,0x7E,0x53,0x79, \ -+ 0x00,0x2B,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \ -+ 0x00,0x00,0x87,0x8F,0x28,0x23,0x06,0x00,0x32,0x11, \ -+ 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \ -+ 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \ -+ 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x00,0x01, \ -+ 0x1B,0xFE,0x00,0x00,0x9B,0x8E,0x53,0x90,0x00,0x00, \ -+ 0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23,0x06,0x00, \ -+ 0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28,0x00,0x00, \ -+ 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \ -+ 0x28,0x43,0x06,0x00,0x00,0x01,0x1B,0xFE,0x32,0xC1, \ -+ 0x00,0x55,0x00,0x28,0x28,0x43,0x1B,0xCF,0x00,0x00, \ -+ 0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55,0x00,0x28, \ -+ 0x28,0x43,0x30,0x7E,0x43,0xBF,0x00,0x2C,0x32,0x11, \ -+ 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \ -+ 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \ -+ 0x00,0x81,0x00,0x00,0x83,0x8F,0x2F,0x0F,0x06,0x00, \ -+ 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01, \ -+ 0x00,0x81,0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50, \ -+ 0x00,0x01,0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00, \ -+ 0x1B,0x9C,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \ -+ 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \ -+ 0x00,0x00,0x00,0x01,0x32,0xC1,0x32,0xF0,0x00,0x4A, \ -+ 0x00,0x80,0x1F,0xFF,0x00,0x01,0x1B,0xFE, \ -+} -+ -+#else -+#define SW_PRS_OFFLOAD_PATCH \ -+{ \ -+ 0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x51,0x16,0x08,0x4B,0x31,0x53,0x00,0xFB, \ -+ 0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x2B, \ -+ 0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA,0x0A,0x00, \ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x20,0x00,0x00, \ -+ 0x00,0x01,0x1B,0xFE,0x00,0x00,0x99,0x00,0x51,0x29, \ -+ 0x00,0x00,0x00,0x00,0x9F,0x98,0x51,0x29,0x00,0x00, \ -+ 0x19,0x44,0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F, \ -+ 0x00,0x20,0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00, \ -+ 0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3, \ -+ 0x29,0x8F,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \ -+ 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \ -+ 0x00,0x00,0x00,0x01,0x1B,0xFE,0x00,0x01,0x1B,0xFE, \ -+ 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x51,0x52,0x40,0x00,0x31,0x92,0x51,0x52, \ -+ 0x00,0x88,0x19,0x55,0x08,0x05,0x00,0x00,0x19,0x99, \ -+ 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \ -+ 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x61,0x75, \ -+ 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \ -+ 0x00,0x01,0x07,0x01,0x61,0x61,0x00,0x00,0x30,0xD0, \ -+ 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \ -+ 0x41,0x72,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \ -+ 0x00,0x06,0x19,0x83,0x00,0x00,0x9F,0xFF,0x30,0xF2, \ -+ 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \ -+ 0x00,0x08,0x28,0x1A,0x61,0x5D,0x00,0x00,0x30,0xF2, \ -+ 0x19,0x83,0x06,0x00,0x29,0x1E,0x30,0xF2,0x29,0x0E, \ -+ 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x29,0x0E, \ -+ 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \ -+ 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \ -+ 0x29,0x0E,0x08,0x05,0x00,0x01,0x31,0x52,0x00,0xDA, \ -+ 0x0E,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0xAF, \ -+ 0x04,0x4B,0x31,0x53,0x00,0xFB,0xFF,0xF0,0x00,0x00, \ -+ 0x00,0x00,0x00,0x00,0x29,0x2B,0x33,0xF1,0x00,0xFB, \ -+ 0x00,0xDF,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7F, \ -+ 0x31,0x52,0x00,0xDA,0x06,0x00,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x41,0xB9,0x00,0x00,0x00,0x01,0x1B,0xFE, \ -+ 0x31,0x52,0x00,0xDA,0x00,0x40,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x42,0x06,0x00,0x00,0x00,0x00,0x9B,0x8F, \ -+ 0x28,0x01,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \ -+ 0x30,0x00,0x41,0xEB,0x00,0x2C,0x32,0x11,0x32,0xC0, \ -+ 0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F,0x28,0x23, \ -+ 0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \ -+ 0x00,0x00,0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11, \ -+ 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \ -+ 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \ -+ 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x19,0xC8, \ -+ 0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F,0x00,0x20, \ -+ 0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00,0x01,0x00, \ -+ 0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3,0x29,0x8F, \ -+ 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \ -+ 0x00,0x01,0x1B,0xFE,0x30,0x50,0x52,0x0B,0x00,0x00, \ -+ 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \ -+ 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x42,0x18, \ -+ 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \ -+ 0x00,0x00,0x9F,0x9E,0x42,0x4D,0x00,0x00,0x02,0x1F, \ -+ 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \ -+ 0x62,0x39,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \ -+ 0x00,0x52,0x00,0x01,0x07,0x01,0x62,0x25,0x00,0x00, \ -+ 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x42,0x36,0x00,0x00,0x02,0x8F,0x00,0x00, \ -+ 0x30,0xF2,0x00,0x06,0x1A,0x47,0x00,0x00,0x9F,0xFF, \ -+ 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \ -+ 0x00,0x52,0x00,0x08,0x28,0x1A,0x62,0x21,0x00,0x00, \ -+ 0x30,0xF2,0x1A,0x47,0x06,0x00,0x29,0x1E,0x30,0xF2, \ -+ 0x52,0x4D,0xFF,0xFF,0x1A,0x52,0x08,0x16,0x00,0x54, \ -+ 0x00,0x01,0x1B,0xFE,0x1A,0x5F,0x32,0xF1,0x28,0x5D, \ -+ 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \ -+ 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \ -+ 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x31,0x52,0x00,0xDA, \ -+ 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x6D, \ -+ 0x40,0x00,0x31,0x92,0x52,0x6D,0x00,0x88,0x1A,0x70, \ -+ 0x08,0x05,0x00,0x00,0x1A,0xB4,0x02,0x1F,0x00,0x08, \ -+ 0x00,0x83,0x02,0x1F,0x00,0x20,0x28,0x1B,0x00,0x05, \ -+ 0x29,0x1F,0x30,0xD0,0x62,0x90,0x00,0x07,0x00,0x05, \ -+ 0x00,0x00,0xC3,0x8F,0x00,0x52,0x00,0x01,0x07,0x01, \ -+ 0x62,0x7C,0x00,0x00,0x30,0xD0,0x00,0xDA,0x00,0x01, \ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x8D,0x00,0x00, \ -+ 0x02,0x8F,0x00,0x00,0x30,0xF2,0x00,0x06,0x1A,0x9E, \ -+ 0x00,0x00,0x9F,0xFF,0x30,0xF2,0x00,0x06,0x29,0x1E, \ -+ 0x07,0x08,0x30,0xD0,0x00,0x52,0x00,0x08,0x28,0x1A, \ -+ 0x62,0x78,0x00,0x00,0x30,0xF2,0x1A,0x9E,0x06,0x00, \ -+ 0x29,0x1E,0x30,0xF2,0x29,0x0E,0x30,0x72,0x00,0x00, \ -+ 0x9B,0x8F,0x00,0x06,0x29,0x0E,0x32,0xF1,0x32,0xB0, \ -+ 0x00,0x4F,0x00,0x57,0x00,0x28,0x00,0x00,0x97,0x9E, \ -+ 0x00,0x4E,0x30,0x72,0x00,0x06,0x29,0x0E,0x08,0x05, \ -+ 0x00,0x01,0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00, \ -+ 0x00,0x00,0x00,0x00,0x52,0xCA,0x04,0x4B,0x31,0x53, \ -+ 0x00,0xFB,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, \ -+ 0x29,0x2B,0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00, \ -+ 0x00,0x00,0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA, \ -+ 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xD4, \ -+ 0x00,0x00,0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA, \ -+ 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x37, \ -+ 0x00,0x00,0x00,0x00,0x9B,0x8F,0x28,0x01,0x32,0xC1, \ -+ 0x00,0x55,0x00,0x28,0x28,0x43,0x30,0x00,0x42,0xEA, \ -+ 0x00,0x00,0x30,0x00,0x42,0xEA,0x00,0x3C,0x1B,0x02, \ -+ 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00, \ -+ 0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11,0x32,0xC0, \ -+ 0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11, \ -+ 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \ -+ 0x00,0x4D,0x28,0x43,0x06,0x00,0x1A,0xE3,0x30,0x00, \ -+ 0x43,0x20,0x00,0x2B,0x00,0x00,0x9B,0x8E,0x43,0x0E, \ -+ 0x00,0x00,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \ -+ 0x1B,0x1F,0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23, \ -+ 0x06,0x00,0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28, \ -+ 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \ -+ 0x00,0x4D,0x28,0x43,0x06,0x00,0x1B,0x37,0x32,0x11, \ -+ 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \ -+ 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \ -+ 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \ -+ 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \ -+ 0x28,0x43,0x06,0x00,0x30,0x50,0x53,0x3C,0x00,0x00, \ -+ 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \ -+ 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x43,0x49, \ -+ 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \ -+ 0x00,0x00,0x9F,0x9E,0x43,0x7E,0x00,0x00,0x02,0x1F, \ -+ 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \ -+ 0x63,0x6A,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \ -+ 0x00,0x52,0x00,0x01,0x07,0x01,0x63,0x56,0x00,0x00, \ -+ 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x43,0x67,0x00,0x00,0x02,0x8F,0x00,0x00, \ -+ 0x30,0xF2,0x00,0x06,0x1B,0x78,0x00,0x00,0x9F,0xFF, \ -+ 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \ -+ 0x00,0x52,0x00,0x08,0x28,0x1A,0x63,0x52,0x00,0x00, \ -+ 0x30,0xF2,0x1B,0x78,0x06,0x00,0x29,0x1E,0x30,0xF2, \ -+ 0x53,0x7E,0xFF,0xFF,0x1B,0x83,0x08,0x16,0x00,0x54, \ -+ 0x00,0x01,0x1B,0xFE,0x1B,0x90,0x32,0xF1,0x28,0x5D, \ -+ 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \ -+ 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \ -+ 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x08,0x07,0x00,0x02, \ -+ 0x00,0x00,0x8D,0x80,0x53,0x9C,0x00,0x01,0x30,0x71, \ -+ 0x00,0x55,0x00,0x01,0x28,0x0F,0x00,0x00,0x8D,0x00, \ -+ 0x53,0xA4,0x00,0x01,0x30,0x71,0x00,0x55,0x00,0x01, \ -+ 0x28,0x0F,0x00,0x00,0x83,0x8E,0x53,0xB9,0x00,0x00, \ -+ 0x00,0x00,0x86,0x08,0x30,0x71,0x00,0x7B,0x03,0xB9, \ -+ 0x33,0xB4,0x00,0xDA,0xFF,0xFF,0x00,0x0F,0x00,0x00, \ -+ 0x00,0x00,0x00,0x00,0x86,0x09,0x01,0x03,0x00,0x7D, \ -+ 0x03,0xB9,0x1B,0xC8,0x33,0xD1,0x00,0xF9,0x00,0x10, \ -+ 0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7B,0x09,0x5F, \ -+ 0x00,0x1A,0x00,0x00,0x09,0x4F,0x00,0x1A,0x00,0x00, \ -+ 0x00,0x01,0x1B,0xFF,0x00,0x00,0x8C,0x00,0x53,0xF0, \ -+ 0x00,0x01,0x34,0xF5,0x00,0xFB,0xFF,0xFF,0x00,0x7F, \ -+ 0x00,0x00,0x00,0x00,0x2A,0x9F,0x00,0x00,0x93,0x8F, \ -+ 0x28,0x49,0x00,0x00,0x97,0x8F,0x28,0x4B,0x34,0x61, \ -+ 0x28,0x4D,0x34,0x71,0x28,0x4F,0x34,0xB7,0x00,0xF9, \ -+ 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97, \ -+ 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \ -+ 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \ -+ 0x00,0x01,0x1B,0xFF,0x00,0x01,0x1B,0xFF, \ -+} -+#endif /* (DPAA_VERSION == 10) */ -+ -+/****************************/ -+/* Parser defines */ -+/****************************/ -+#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at -+ the end of the SW parser area */ -+ -+/* masks */ -+#define PRS_ERR_CAP 0x80000000 -+#define PRS_ERR_TYPE_DOUBLE 0x40000000 -+#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000 -+#define PRS_ERR_ADDR_MASK 0x000001FF -+ -+/* others */ -+#define PRS_MAX_CYCLE_LIMIT 8191 -+#define PRS_SW_DATA 0x00000800 -+#define PRS_REGS_OFFSET 0x00000840 -+ -+#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \ -+ prsPortId = (uint8_t)(hardwarePortId & 0x0f) -+ -+#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \ -+ bitMask = 0x80000000>>prsPortId -+ -+#endif /* __FM_PRS_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c -@@ -0,0 +1,984 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_replic.c -+ -+ @Description FM frame replicator -+*//***************************************************************************/ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "string_ext.h" -+#include "debug_ext.h" -+#include "fm_pcd_ext.h" -+#include "fm_muram_ext.h" -+#include "fm_common.h" -+#include "fm_hc.h" -+#include "fm_replic.h" -+#include "fm_cc.h" -+#include "list_ext.h" -+ -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+static uint8_t GetMemberPosition(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ uint32_t memberIndex, -+ bool isAddOperation) -+{ -+ uint8_t memberPosition; -+ uint32_t lastMemberIndex; -+ -+ ASSERT_COND(p_ReplicGroup); -+ -+ /* the last member index is different between add and remove operation - -+ in case of remove - this is exactly the last member index -+ in case of add - this is the last member index + 1 - e.g. -+ if we have 4 members, the index of the actual last member is 3(because the -+ index starts from 0) therefore in order to add a new member as the last -+ member we shall use memberIndex = 4 and not 3 -+ */ -+ if (isAddOperation) -+ lastMemberIndex = p_ReplicGroup->numOfEntries; -+ else -+ lastMemberIndex = p_ReplicGroup->numOfEntries-1; -+ -+ /* last */ -+ if (memberIndex == lastMemberIndex) -+ memberPosition = FRM_REPLIC_LAST_MEMBER_INDEX; -+ else -+ { -+ /* first */ -+ if (memberIndex == 0) -+ memberPosition = FRM_REPLIC_FIRST_MEMBER_INDEX; -+ else -+ { -+ /* middle */ -+ ASSERT_COND(memberIndex < lastMemberIndex); -+ memberPosition = FRM_REPLIC_MIDDLE_MEMBER_INDEX; -+ } -+ } -+ return memberPosition; -+} -+ -+static t_Error MemberCheckParams(t_Handle h_FmPcd, -+ t_FmPcdCcNextEngineParams *p_MemberParams) -+{ -+ t_Error err; -+ -+ -+ if ((p_MemberParams->nextEngine != e_FM_PCD_DONE) && -+ (p_MemberParams->nextEngine != e_FM_PCD_KG) && -+ (p_MemberParams->nextEngine != e_FM_PCD_PLCR)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine of a member should be MatchTable(cc) or Done or Policer")); -+ -+ /* check the regular parameters of the next engine */ -+ err = ValidateNextEngineParams(h_FmPcd, p_MemberParams, e_FM_PCD_CC_STATS_MODE_NONE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, ("member next engine parameters")); -+ -+ return E_OK; -+} -+ -+static t_Error CheckParams(t_Handle h_FmPcd, -+ t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam) -+{ -+ int i; -+ t_Error err; -+ -+ /* check that max num of entries is at least 2 */ -+ if (!IN_RANGE(2, p_ReplicGroupParam->maxNumOfEntries, FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("maxNumOfEntries in the frame replicator parameters should be 2-%d",FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)); -+ -+ /* check that number of entries is greater than zero */ -+ if (!p_ReplicGroupParam->numOfEntries) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOFEntries in the frame replicator group should be greater than zero")); -+ -+ /* check that max num of entries is equal or greater than number of entries */ -+ if (p_ReplicGroupParam->maxNumOfEntries < p_ReplicGroupParam->numOfEntries) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfEntries should be equal or greater than numOfEntries")); -+ -+ for (i=0; inumOfEntries; i++) -+ { -+ err = MemberCheckParams(h_FmPcd, &p_ReplicGroupParam->nextEngineParams[i]); -+ if (err) -+ RETURN_ERROR(MAJOR, err, ("member check parameters")); -+ } -+ return E_OK; -+} -+ -+static t_FmPcdFrmReplicMember *GetAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup) -+{ -+ t_FmPcdFrmReplicMember *p_ReplicMember = NULL; -+ t_List *p_Next; -+ -+ if (!LIST_IsEmpty(&p_ReplicGroup->availableMembersList)) -+ { -+ p_Next = LIST_FIRST(&p_ReplicGroup->availableMembersList); -+ p_ReplicMember = LIST_OBJECT(p_Next, t_FmPcdFrmReplicMember, node); -+ ASSERT_COND(p_ReplicMember); -+ LIST_DelAndInit(p_Next); -+ } -+ return p_ReplicMember; -+} -+ -+static void PutAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ t_FmPcdFrmReplicMember *p_ReplicMember) -+{ -+ LIST_AddToTail(&p_ReplicMember->node, &p_ReplicGroup->availableMembersList); -+} -+ -+static void AddMemberToList(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ t_FmPcdFrmReplicMember *p_CurrentMember, -+ t_List *p_ListHead) -+{ -+ LIST_Add(&p_CurrentMember->node, p_ListHead); -+ -+ p_ReplicGroup->numOfEntries++; -+} -+ -+static void RemoveMemberFromList(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ t_FmPcdFrmReplicMember *p_CurrentMember) -+{ -+ ASSERT_COND(p_ReplicGroup->numOfEntries); -+ LIST_DelAndInit(&p_CurrentMember->node); -+ p_ReplicGroup->numOfEntries--; -+} -+ -+static void LinkSourceToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ t_AdOfTypeContLookup *p_SourceTd, -+ t_FmPcdFrmReplicMember *p_ReplicMember) -+{ -+ t_FmPcd *p_FmPcd; -+ -+ ASSERT_COND(p_SourceTd); -+ ASSERT_COND(p_ReplicMember); -+ ASSERT_COND(p_ReplicGroup); -+ ASSERT_COND(p_ReplicGroup->h_FmPcd); -+ -+ /* Link the first member in the group to the source TD */ -+ p_FmPcd = p_ReplicGroup->h_FmPcd; -+ -+ WRITE_UINT32(p_SourceTd->matchTblPtr, -+ (uint32_t)(XX_VirtToPhys(p_ReplicMember->p_MemberAd) - -+ p_FmPcd->physicalMuramBase)); -+} -+ -+static void LinkMemberToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ t_FmPcdFrmReplicMember *p_CurrentMember, -+ t_FmPcdFrmReplicMember *p_NextMember) -+{ -+ t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_CurrentMember->p_MemberAd; -+ t_AdOfTypeResult *p_NextReplicAd = NULL; -+ t_FmPcd *p_FmPcd; -+ uint32_t offset = 0; -+ -+ /* Check if the next member exists or it's NULL (- means that this is the last member) */ -+ if (p_NextMember) -+ { -+ p_NextReplicAd = (t_AdOfTypeResult*)p_NextMember->p_MemberAd; -+ p_FmPcd = p_ReplicGroup->h_FmPcd; -+ offset = (XX_VirtToPhys(p_NextReplicAd) - (p_FmPcd->physicalMuramBase)); -+ offset = ((offset>>NEXT_FRM_REPLIC_ADDR_SHIFT)<< NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT); -+ } -+ -+ /* link the current AD to point to the AD of the next member */ -+ WRITE_UINT32(p_CurrReplicAd->res, offset); -+} -+ -+static t_Error ModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ void *p_OldDescriptor, -+ void *p_NewDescriptor) -+{ -+ t_Handle h_Hc; -+ t_Error err; -+ t_FmPcd *p_FmPcd; -+ -+ ASSERT_COND(p_ReplicGroup); -+ ASSERT_COND(p_ReplicGroup->h_FmPcd); -+ ASSERT_COND(p_OldDescriptor); -+ ASSERT_COND(p_NewDescriptor); -+ -+ p_FmPcd = p_ReplicGroup->h_FmPcd; -+ h_Hc = FmPcdGetHcHandle(p_FmPcd); -+ if (!h_Hc) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Host command")); -+ -+ err = FmHcPcdCcDoDynamicChange(h_Hc, -+ (uint32_t)(XX_VirtToPhys(p_OldDescriptor) - p_FmPcd->physicalMuramBase), -+ (uint32_t)(XX_VirtToPhys(p_NewDescriptor) - p_FmPcd->physicalMuramBase)); -+ if (err) -+ RETURN_ERROR(MAJOR, err, ("Dynamic change host command")); -+ -+ return E_OK; -+} -+ -+static void FillReplicAdOfTypeResult(void *p_ReplicAd, bool last) -+{ -+ t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_ReplicAd; -+ uint32_t tmp; -+ -+ tmp = GET_UINT32(p_CurrReplicAd->plcrProfile); -+ if (last) -+ /* clear the NL bit in case it's the last member in the group*/ -+ WRITE_UINT32(p_CurrReplicAd->plcrProfile,(tmp & ~FRM_REPLIC_NL_BIT)); -+ else -+ /* set the NL bit in case it's not the last member in the group */ -+ WRITE_UINT32(p_CurrReplicAd->plcrProfile, (tmp |FRM_REPLIC_NL_BIT)); -+ -+ /* set FR bit in the action descriptor */ -+ tmp = GET_UINT32(p_CurrReplicAd->nia); -+ WRITE_UINT32(p_CurrReplicAd->nia, -+ (tmp | FRM_REPLIC_FR_BIT | FM_PCD_AD_RESULT_EXTENDED_MODE )); -+} -+ -+static void BuildSourceTd(void *p_Ad) -+{ -+ t_AdOfTypeContLookup *p_SourceTd; -+ -+ ASSERT_COND(p_Ad); -+ -+ p_SourceTd = (t_AdOfTypeContLookup *)p_Ad; -+ -+ IOMemSet32((uint8_t*)p_SourceTd, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* initialize the source table descriptor */ -+ WRITE_UINT32(p_SourceTd->ccAdBase, FM_PCD_AD_CONT_LOOKUP_TYPE); -+ WRITE_UINT32(p_SourceTd->pcAndOffsets, FRM_REPLIC_SOURCE_TD_OPCODE); -+} -+ -+static t_Error BuildShadowAndModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ t_FmPcdFrmReplicMember *p_NextMember, -+ t_FmPcdFrmReplicMember *p_CurrentMember, -+ bool sourceDescriptor, -+ bool last) -+{ -+ t_FmPcd *p_FmPcd; -+ t_FmPcdFrmReplicMember shadowMember; -+ t_Error err; -+ -+ ASSERT_COND(p_ReplicGroup); -+ ASSERT_COND(p_ReplicGroup->h_FmPcd); -+ -+ p_FmPcd = p_ReplicGroup->h_FmPcd; -+ ASSERT_COND(p_FmPcd->p_CcShadow); -+ -+ if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock)) -+ return ERROR_CODE(E_BUSY); -+ -+ if (sourceDescriptor) -+ { -+ BuildSourceTd(p_FmPcd->p_CcShadow); -+ LinkSourceToMember(p_ReplicGroup, p_FmPcd->p_CcShadow, p_NextMember); -+ -+ /* Modify the source table descriptor according to the prepared shadow descriptor */ -+ err = ModifyDescriptor(p_ReplicGroup, -+ p_ReplicGroup->p_SourceTd, -+ p_FmPcd->p_CcShadow/* new prepared source td */); -+ -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ if (err) -+ RETURN_ERROR(MAJOR, err, ("Modify source Descriptor in BuildShadowAndModifyDescriptor")); -+ -+ } -+ else -+ { -+ IO2IOCpy32(p_FmPcd->p_CcShadow, -+ p_CurrentMember->p_MemberAd, -+ FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* update the last bit in the shadow ad */ -+ FillReplicAdOfTypeResult(p_FmPcd->p_CcShadow, last); -+ -+ shadowMember.p_MemberAd = p_FmPcd->p_CcShadow; -+ -+ /* update the next FR member index */ -+ LinkMemberToMember(p_ReplicGroup, &shadowMember, p_NextMember); -+ -+ /* Modify the next member according to the prepared shadow descriptor */ -+ err = ModifyDescriptor(p_ReplicGroup, -+ p_CurrentMember->p_MemberAd, -+ p_FmPcd->p_CcShadow); -+ -+ RELEASE_LOCK(p_FmPcd->shadowLock); -+ if (err) -+ RETURN_ERROR(MAJOR, err, ("Modify Descriptor in BuildShadowAndModifyDescriptor")); -+ } -+ -+ -+ return E_OK; -+} -+ -+static t_FmPcdFrmReplicMember* GetMemberByIndex(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ uint16_t memberIndex) -+{ -+ int i=0; -+ t_List *p_Pos; -+ t_FmPcdFrmReplicMember *p_Member = NULL; -+ -+ LIST_FOR_EACH(p_Pos, &p_ReplicGroup->membersList) -+ { -+ if (i == memberIndex) -+ { -+ p_Member = LIST_OBJECT(p_Pos, t_FmPcdFrmReplicMember, node); -+ return p_Member; -+ } -+ i++; -+ } -+ return p_Member; -+} -+ -+static t_Error AllocMember(t_FmPcdFrmReplicGroup *p_ReplicGroup) -+{ -+ t_FmPcdFrmReplicMember *p_CurrentMember; -+ t_Handle h_Muram; -+ -+ ASSERT_COND(p_ReplicGroup); -+ -+ h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd); -+ ASSERT_COND(h_Muram); -+ -+ /* Initialize an internal structure of a member to add to the available members list */ -+ p_CurrentMember = (t_FmPcdFrmReplicMember *)XX_Malloc(sizeof(t_FmPcdFrmReplicMember)); -+ if (!p_CurrentMember) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Frame replicator member")); -+ -+ memset(p_CurrentMember, 0 ,sizeof(t_FmPcdFrmReplicMember)); -+ -+ /* Allocate the member AD */ -+ p_CurrentMember->p_MemberAd = -+ (t_AdOfTypeResult*)FM_MURAM_AllocMem(h_Muram, -+ FM_PCD_CC_AD_ENTRY_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_CurrentMember->p_MemberAd) -+ { -+ XX_Free(p_CurrentMember); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("member AD table")); -+ } -+ IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ /* Add the new member to the available members list */ -+ LIST_AddToTail(&p_CurrentMember->node, &(p_ReplicGroup->availableMembersList)); -+ -+ return E_OK; -+} -+ -+static t_FmPcdFrmReplicMember* InitMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ t_FmPcdCcNextEngineParams *p_MemberParams, -+ bool last) -+{ -+ t_FmPcdFrmReplicMember *p_CurrentMember = NULL; -+ -+ ASSERT_COND(p_ReplicGroup); -+ -+ /* Get an available member from the internal members list */ -+ p_CurrentMember = GetAvailableMember(p_ReplicGroup); -+ if (!p_CurrentMember) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Available member")); -+ return NULL; -+ } -+ p_CurrentMember->h_Manip = NULL; -+ -+ /* clear the Ad of the new member */ -+ IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ INIT_LIST(&p_CurrentMember->node); -+ -+ /* Initialize the Ad of the member */ -+ NextStepAd(p_CurrentMember->p_MemberAd, -+ NULL, -+ p_MemberParams, -+ p_ReplicGroup->h_FmPcd); -+ -+ /* save Manip handle (for free needs) */ -+ if (p_MemberParams->h_Manip) -+ p_CurrentMember->h_Manip = p_MemberParams->h_Manip; -+ -+ /* Initialize the relevant frame replicator fields in the AD */ -+ FillReplicAdOfTypeResult(p_CurrentMember->p_MemberAd, last); -+ -+ return p_CurrentMember; -+} -+ -+static void FreeMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ t_FmPcdFrmReplicMember *p_Member) -+{ -+ /* Note: Can't free the member AD just returns the member to the available -+ member list - therefore only memset the AD */ -+ -+ /* zero the AD */ -+ IOMemSet32(p_Member->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE); -+ -+ -+ /* return the member to the available members list */ -+ PutAvailableMember(p_ReplicGroup, p_Member); -+} -+ -+static t_Error RemoveMember(t_FmPcdFrmReplicGroup *p_ReplicGroup, -+ uint16_t memberIndex) -+{ -+ t_FmPcd *p_FmPcd = NULL; -+ t_FmPcdFrmReplicMember *p_CurrentMember = NULL, *p_PreviousMember = NULL, *p_NextMember = NULL; -+ t_Error err; -+ uint8_t memberPosition; -+ -+ p_FmPcd = p_ReplicGroup->h_FmPcd; -+ ASSERT_COND(p_FmPcd); -+ UNUSED(p_FmPcd); -+ -+ p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex); -+ ASSERT_COND(p_CurrentMember); -+ -+ /* determine the member position in the group */ -+ memberPosition = GetMemberPosition(p_ReplicGroup, -+ memberIndex, -+ FALSE/*remove operation*/); -+ -+ switch (memberPosition) -+ { -+ case FRM_REPLIC_FIRST_MEMBER_INDEX: -+ p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1)); -+ ASSERT_COND(p_NextMember); -+ -+ /* update the source td itself by using a host command */ -+ err = BuildShadowAndModifyDescriptor(p_ReplicGroup, -+ p_NextMember, -+ NULL, -+ TRUE/*sourceDescriptor*/, -+ FALSE/*last*/); -+ break; -+ -+ case FRM_REPLIC_MIDDLE_MEMBER_INDEX: -+ p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1)); -+ ASSERT_COND(p_PreviousMember); -+ -+ p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1)); -+ ASSERT_COND(p_NextMember); -+ -+ err = BuildShadowAndModifyDescriptor(p_ReplicGroup, -+ p_NextMember, -+ p_PreviousMember, -+ FALSE/*sourceDescriptor*/, -+ FALSE/*last*/); -+ -+ break; -+ -+ case FRM_REPLIC_LAST_MEMBER_INDEX: -+ p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1)); -+ ASSERT_COND(p_PreviousMember); -+ -+ err = BuildShadowAndModifyDescriptor(p_ReplicGroup, -+ NULL, -+ p_PreviousMember, -+ FALSE/*sourceDescriptor*/, -+ TRUE/*last*/); -+ break; -+ -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in remove member")); -+ } -+ -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (p_CurrentMember->h_Manip) -+ { -+ FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE); -+ p_CurrentMember->h_Manip = NULL; -+ } -+ -+ /* remove the member from the driver internal members list */ -+ RemoveMemberFromList(p_ReplicGroup, p_CurrentMember); -+ -+ /* return the member to the available members list */ -+ FreeMember(p_ReplicGroup, p_CurrentMember); -+ -+ return E_OK; -+} -+ -+static void DeleteGroup(t_FmPcdFrmReplicGroup *p_ReplicGroup) -+{ -+ int i, j; -+ t_Handle h_Muram; -+ t_FmPcdFrmReplicMember *p_Member, *p_CurrentMember; -+ -+ if (p_ReplicGroup) -+ { -+ ASSERT_COND(p_ReplicGroup->h_FmPcd); -+ h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd); -+ ASSERT_COND(h_Muram); -+ -+ /* free the source table descriptor */ -+ if (p_ReplicGroup->p_SourceTd) -+ { -+ FM_MURAM_FreeMem(h_Muram, p_ReplicGroup->p_SourceTd); -+ p_ReplicGroup->p_SourceTd = NULL; -+ } -+ -+ /* Remove all members from the members linked list (hw and sw) and -+ return the members to the available members list */ -+ if (p_ReplicGroup->numOfEntries) -+ { -+ j = p_ReplicGroup->numOfEntries-1; -+ -+ /* manually removal of the member because there are no owners of -+ this group */ -+ for (i=j; i>=0; i--) -+ { -+ p_CurrentMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)i/*memberIndex*/); -+ ASSERT_COND(p_CurrentMember); -+ -+ if (p_CurrentMember->h_Manip) -+ { -+ FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE); -+ p_CurrentMember->h_Manip = NULL; -+ } -+ -+ /* remove the member from the internal driver members list */ -+ RemoveMemberFromList(p_ReplicGroup, p_CurrentMember); -+ -+ /* return the member to the available members list */ -+ FreeMember(p_ReplicGroup, p_CurrentMember); -+ } -+ } -+ -+ /* Free members AD */ -+ for (i=0; imaxNumOfEntries; i++) -+ { -+ p_Member = GetAvailableMember(p_ReplicGroup); -+ ASSERT_COND(p_Member); -+ if (p_Member->p_MemberAd) -+ { -+ FM_MURAM_FreeMem(h_Muram, p_Member->p_MemberAd); -+ p_Member->p_MemberAd = NULL; -+ } -+ XX_Free(p_Member); -+ } -+ -+ /* release the group lock */ -+ if (p_ReplicGroup->p_Lock) -+ FmPcdReleaseLock(p_ReplicGroup->h_FmPcd, p_ReplicGroup->p_Lock); -+ -+ /* free the replicator group */ -+ XX_Free(p_ReplicGroup); -+ } -+} -+ -+ -+/*****************************************************************************/ -+/* Inter-module API routines */ -+/*****************************************************************************/ -+ -+/* NOTE: the inter-module routines are locked by cc in case of using them */ -+void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup) -+{ -+ t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; -+ ASSERT_COND(p_ReplicGroup); -+ -+ return (p_ReplicGroup->p_SourceTd); -+} -+ -+void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, -+ void *p_Ad, -+ t_Handle *h_AdNew) -+{ -+ t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; -+ t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad; -+ t_FmPcd *p_FmPcd; -+ -+ ASSERT_COND(p_ReplicGroup); -+ p_FmPcd = p_ReplicGroup->h_FmPcd; -+ -+ /* build a bypass ad */ -+ WRITE_UINT32(p_AdResult->fqid, FM_PCD_AD_BYPASS_TYPE | -+ (uint32_t)((XX_VirtToPhys(p_ReplicGroup->p_SourceTd)) - p_FmPcd->physicalMuramBase)); -+ -+ *h_AdNew = NULL; -+} -+ -+void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, -+ bool add) -+{ -+ t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; -+ ASSERT_COND(p_ReplicGroup); -+ -+ /* update the group owner counter */ -+ if (add) -+ p_ReplicGroup->owners++; -+ else -+ { -+ ASSERT_COND(p_ReplicGroup->owners); -+ p_ReplicGroup->owners--; -+ } -+} -+ -+t_Error FrmReplicGroupTryLock(t_Handle h_ReplicGroup) -+{ -+ t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; -+ -+ ASSERT_COND(h_ReplicGroup); -+ -+ if (FmPcdLockTryLock(p_ReplicGroup->p_Lock)) -+ return E_OK; -+ -+ return ERROR_CODE(E_BUSY); -+} -+ -+void FrmReplicGroupUnlock(t_Handle h_ReplicGroup) -+{ -+ t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; -+ -+ ASSERT_COND(h_ReplicGroup); -+ -+ FmPcdLockUnlock(p_ReplicGroup->p_Lock); -+} -+/*********************** End of inter-module routines ************************/ -+ -+ -+/****************************************/ -+/* API Init unit functions */ -+/****************************************/ -+t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, -+ t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam) -+{ -+ t_FmPcdFrmReplicGroup *p_ReplicGroup; -+ t_FmPcdFrmReplicMember *p_CurrentMember, *p_NextMember = NULL; -+ int i; -+ t_Error err; -+ bool last = FALSE; -+ t_Handle h_Muram; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_ReplicGroupParam, E_INVALID_HANDLE, NULL); -+ -+ if (!FmPcdIsAdvancedOffloadSupported(h_FmPcd)) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled")); -+ return NULL; -+ } -+ -+ err = CheckParams(h_FmPcd, p_ReplicGroupParam); -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, err, (NO_MSG)); -+ return NULL; -+ } -+ -+ p_ReplicGroup = (t_FmPcdFrmReplicGroup*)XX_Malloc(sizeof(t_FmPcdFrmReplicGroup)); -+ if (!p_ReplicGroup) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory")); -+ return NULL; -+ } -+ memset(p_ReplicGroup, 0, sizeof(t_FmPcdFrmReplicGroup)); -+ -+ /* initialize lists for internal driver use */ -+ INIT_LIST(&p_ReplicGroup->availableMembersList); -+ INIT_LIST(&p_ReplicGroup->membersList); -+ -+ p_ReplicGroup->h_FmPcd = h_FmPcd; -+ -+ h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd); -+ ASSERT_COND(h_Muram); -+ -+ /* initialize the group lock */ -+ p_ReplicGroup->p_Lock = FmPcdAcquireLock(p_ReplicGroup->h_FmPcd); -+ if (!p_ReplicGroup->p_Lock) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Replic group lock")); -+ DeleteGroup(p_ReplicGroup); -+ return NULL; -+ } -+ -+ /* Allocate the frame replicator source table descriptor */ -+ p_ReplicGroup->p_SourceTd = -+ (t_Handle)FM_MURAM_AllocMem(h_Muram, -+ FM_PCD_CC_AD_ENTRY_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (!p_ReplicGroup->p_SourceTd) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("frame replicator source table descriptor")); -+ DeleteGroup(p_ReplicGroup); -+ return NULL; -+ } -+ -+ /* update the shadow size - required for the host commands */ -+ err = FmPcdUpdateCcShadow(p_ReplicGroup->h_FmPcd, -+ FM_PCD_CC_AD_ENTRY_SIZE, -+ FM_PCD_CC_AD_TABLE_ALIGN); -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, err, ("Update CC shadow")); -+ DeleteGroup(p_ReplicGroup); -+ return NULL; -+ } -+ -+ p_ReplicGroup->maxNumOfEntries = p_ReplicGroupParam->maxNumOfEntries; -+ -+ /* Allocate the maximal number of members ADs and Statistics AD for the group -+ It prevents allocation of Muram in run-time */ -+ for (i=0; imaxNumOfEntries; i++) -+ { -+ err = AllocMember(p_ReplicGroup); -+ if (err) -+ { -+ REPORT_ERROR(MAJOR, err, ("allocate a new member")); -+ DeleteGroup(p_ReplicGroup); -+ return NULL; -+ } -+ } -+ -+ /* Initialize the members linked lists: -+ (hw - the one that is used by the FMan controller and -+ sw - the one that is managed by the driver internally) */ -+ for (i=(p_ReplicGroupParam->numOfEntries-1); i>=0; i--) -+ { -+ /* check if this is the last member in the group */ -+ if (i == (p_ReplicGroupParam->numOfEntries-1)) -+ last = TRUE; -+ else -+ last = FALSE; -+ -+ /* Initialize a new member */ -+ p_CurrentMember = InitMember(p_ReplicGroup, -+ &(p_ReplicGroupParam->nextEngineParams[i]), -+ last); -+ if (!p_CurrentMember) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member")); -+ DeleteGroup(p_ReplicGroup); -+ return NULL; -+ } -+ -+ /* Build the members group - link two consecutive members in the hw linked list */ -+ LinkMemberToMember(p_ReplicGroup, p_CurrentMember, p_NextMember); -+ -+ /* update the driver internal members list to be compatible to the hw members linked list */ -+ AddMemberToList(p_ReplicGroup, p_CurrentMember, &p_ReplicGroup->membersList); -+ -+ p_NextMember = p_CurrentMember; -+ } -+ -+ /* initialize the source table descriptor */ -+ BuildSourceTd(p_ReplicGroup->p_SourceTd); -+ -+ /* link the source table descriptor to point to the first member in the group */ -+ LinkSourceToMember(p_ReplicGroup, p_ReplicGroup->p_SourceTd, p_NextMember); -+ -+ return p_ReplicGroup; -+} -+ -+t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_ReplicGroup) -+{ -+ t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup; -+ -+ SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE); -+ -+ if (p_ReplicGroup->owners) -+ RETURN_ERROR(MAJOR, -+ E_INVALID_STATE, -+ ("the group has owners and can't be deleted")); -+ -+ DeleteGroup(p_ReplicGroup); -+ -+ return E_OK; -+} -+ -+ -+/*****************************************************************************/ -+/* API Run-time Frame replicator Control unit functions */ -+/*****************************************************************************/ -+t_Error FM_PCD_FrmReplicAddMember(t_Handle h_ReplicGroup, -+ uint16_t memberIndex, -+ t_FmPcdCcNextEngineParams *p_MemberParams) -+{ -+ t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup; -+ t_FmPcdFrmReplicMember *p_NewMember, *p_CurrentMember = NULL, *p_PreviousMember = NULL; -+ t_Error err; -+ uint8_t memberPosition; -+ -+ SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_MemberParams, E_INVALID_HANDLE); -+ -+ /* group lock */ -+ err = FrmReplicGroupTryLock(p_ReplicGroup); -+ if (GET_ERROR_TYPE(err) == E_BUSY) -+ return ERROR_CODE(E_BUSY); -+ -+ if (memberIndex > p_ReplicGroup->numOfEntries) -+ { -+ /* unlock */ -+ FrmReplicGroupUnlock(p_ReplicGroup); -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, -+ ("memberIndex is greater than the members in the list")); -+ } -+ -+ if (memberIndex >= p_ReplicGroup->maxNumOfEntries) -+ { -+ /* unlock */ -+ FrmReplicGroupUnlock(p_ReplicGroup); -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("memberIndex is greater than the allowed number of members in the group")); -+ } -+ -+ if ((p_ReplicGroup->numOfEntries + 1) > FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES) -+ { -+ /* unlock */ -+ FrmReplicGroupUnlock(p_ReplicGroup); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("numOfEntries with new entry can not be larger than %d\n", -+ FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)); -+ } -+ -+ err = MemberCheckParams(p_ReplicGroup->h_FmPcd, p_MemberParams); -+ if (err) -+ { -+ /* unlock */ -+ FrmReplicGroupUnlock(p_ReplicGroup); -+ RETURN_ERROR(MAJOR, err, ("member check parameters in add operation")); -+ } -+ /* determine the member position in the group */ -+ memberPosition = GetMemberPosition(p_ReplicGroup, -+ memberIndex, -+ TRUE/* add operation */); -+ -+ /* Initialize a new member */ -+ p_NewMember = InitMember(p_ReplicGroup, -+ p_MemberParams, -+ (memberPosition == FRM_REPLIC_LAST_MEMBER_INDEX ? TRUE : FALSE)); -+ if (!p_NewMember) -+ { -+ /* unlock */ -+ FrmReplicGroupUnlock(p_ReplicGroup); -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member")); -+ } -+ -+ switch (memberPosition) -+ { -+ case FRM_REPLIC_FIRST_MEMBER_INDEX: -+ p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex); -+ ASSERT_COND(p_CurrentMember); -+ -+ LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember); -+ -+ /* update the internal group source TD */ -+ LinkSourceToMember(p_ReplicGroup, -+ p_ReplicGroup->p_SourceTd, -+ p_NewMember); -+ -+ /* add member to the internal sw member list */ -+ AddMemberToList(p_ReplicGroup, -+ p_NewMember, -+ &p_ReplicGroup->membersList); -+ break; -+ -+ case FRM_REPLIC_MIDDLE_MEMBER_INDEX: -+ p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex); -+ ASSERT_COND(p_CurrentMember); -+ -+ p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1)); -+ ASSERT_COND(p_PreviousMember); -+ -+ LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember); -+ LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember); -+ -+ AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node); -+ break; -+ -+ case FRM_REPLIC_LAST_MEMBER_INDEX: -+ p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1)); -+ ASSERT_COND(p_PreviousMember); -+ -+ LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember); -+ FillReplicAdOfTypeResult(p_PreviousMember->p_MemberAd, FALSE/*last*/); -+ -+ /* add the new member to the internal sw member list */ -+ AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node); -+ break; -+ -+ default: -+ /* unlock */ -+ FrmReplicGroupUnlock(p_ReplicGroup); -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in add member")); -+ -+ } -+ -+ /* unlock */ -+ FrmReplicGroupUnlock(p_ReplicGroup); -+ -+ return E_OK; -+} -+ -+t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_ReplicGroup, -+ uint16_t memberIndex) -+{ -+ t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE); -+ -+ /* lock */ -+ err = FrmReplicGroupTryLock(p_ReplicGroup); -+ if (GET_ERROR_TYPE(err) == E_BUSY) -+ return ERROR_CODE(E_BUSY); -+ -+ if (memberIndex >= p_ReplicGroup->numOfEntries) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member index to remove")); -+ -+ /* Design decision: group must contain at least one member -+ No possibility to remove the last member from the group */ -+ if (p_ReplicGroup->numOfEntries == 1) -+ RETURN_ERROR(MAJOR, E_CONFLICT, ("Can't remove the last member. At least one member should be related to a group.")); -+ -+ err = RemoveMember(p_ReplicGroup, memberIndex); -+ -+ /* unlock */ -+ FrmReplicGroupUnlock(p_ReplicGroup); -+ -+ switch (GET_ERROR_TYPE(err)) -+ { -+ case E_OK: -+ return E_OK; -+ -+ case E_BUSY: -+ DBG(TRACE, ("E_BUSY error")); -+ return ERROR_CODE(E_BUSY); -+ -+ default: -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+} -+ -+/*********************** End of API routines ************************/ -+ -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h -@@ -0,0 +1,101 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_replic.h -+ -+ @Description FM frame replicator -+*//***************************************************************************/ -+#ifndef __FM_REPLIC_H -+#define __FM_REPLIC_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+ -+ -+#define FRM_REPLIC_SOURCE_TD_OPCODE 0x75 -+#define NEXT_FRM_REPLIC_ADDR_SHIFT 4 -+#define NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT 16 -+#define FRM_REPLIC_FR_BIT 0x08000000 -+#define FRM_REPLIC_NL_BIT 0x10000000 -+#define FRM_REPLIC_INVALID_MEMBER_INDEX 0xffff -+#define FRM_REPLIC_FIRST_MEMBER_INDEX 0 -+ -+#define FRM_REPLIC_MIDDLE_MEMBER_INDEX 1 -+#define FRM_REPLIC_LAST_MEMBER_INDEX 2 -+ -+#define SOURCE_TD_ITSELF_OPTION 0x01 -+#define SOURCE_TD_COPY_OPTION 0x02 -+#define SOURCE_TD_ITSELF_AND_COPY_OPTION SOURCE_TD_ITSELF_OPTION | SOURCE_TD_COPY_OPTION -+#define SOURCE_TD_NONE 0x04 -+ -+/*typedef enum e_SourceTdOption -+{ -+ e_SOURCE_TD_NONE = 0, -+ e_SOURCE_TD_ITSELF_OPTION = 1, -+ e_SOURCE_TD_COPY_OPTION = 2, -+ e_SOURCE_TD_ITSELF_AND_COPY_OPTION = e_SOURCE_TD_ITSELF_OPTION | e_SOURCE_TD_COPY_OPTION -+} e_SourceTdOption; -+*/ -+ -+typedef struct -+{ -+ volatile uint32_t type; -+ volatile uint32_t frGroupPointer; -+ volatile uint32_t operationCode; -+ volatile uint32_t reserved; -+} t_FrmReplicGroupSourceAd; -+ -+typedef struct t_FmPcdFrmReplicMember -+{ -+ void *p_MemberAd; /**< pointer to the member AD */ -+ void *p_StatisticsAd;/**< pointer to the statistics AD of the member */ -+ t_Handle h_Manip; /**< manip handle - need for free routines */ -+ t_List node; -+} t_FmPcdFrmReplicMember; -+ -+typedef struct t_FmPcdFrmReplicGroup -+{ -+ t_Handle h_FmPcd; -+ -+ uint8_t maxNumOfEntries;/**< maximal number of members in the group */ -+ uint8_t numOfEntries; /**< actual number of members in the group */ -+ uint16_t owners; /**< how many keys share this frame replicator group */ -+ void *p_SourceTd; /**< pointer to the frame replicator source table descriptor */ -+ t_List membersList; /**< the members list - should reflect the order of the members as in the hw linked list*/ -+ t_List availableMembersList;/**< list of all the available members in the group */ -+ t_FmPcdLock *p_Lock; -+} t_FmPcdFrmReplicGroup; -+ -+ -+#endif /* __FM_REPLIC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c -@@ -0,0 +1,888 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "fsl_fman_kg.h" -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+ -+ -+static uint32_t build_ar_bind_scheme(uint8_t hwport_id, bool write) -+{ -+ uint32_t rw; -+ -+ rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ; -+ -+ return (uint32_t)(FM_KG_KGAR_GO | -+ rw | -+ FM_PCD_KG_KGAR_SEL_PORT_ENTRY | -+ hwport_id | -+ FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP); -+} -+ -+static void clear_pe_all_scheme(struct fman_kg_regs *regs, uint8_t hwport_id) -+{ -+ uint32_t ar; -+ -+ fman_kg_write_sp(regs, 0xffffffff, 0); -+ -+ ar = build_ar_bind_scheme(hwport_id, TRUE); -+ fman_kg_write_ar_wait(regs, ar); -+} -+ -+static uint32_t build_ar_bind_cls_plan(uint8_t hwport_id, bool write) -+{ -+ uint32_t rw; -+ -+ rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ; -+ -+ return (uint32_t)(FM_KG_KGAR_GO | -+ rw | -+ FM_PCD_KG_KGAR_SEL_PORT_ENTRY | -+ hwport_id | -+ FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP); -+} -+ -+static void clear_pe_all_cls_plan(struct fman_kg_regs *regs, uint8_t hwport_id) -+{ -+ uint32_t ar; -+ -+ fman_kg_write_cpp(regs, 0); -+ -+ ar = build_ar_bind_cls_plan(hwport_id, TRUE); -+ fman_kg_write_ar_wait(regs, ar); -+} -+ -+static uint8_t get_gen_ht_code(enum fman_kg_gen_extract_src src, -+ bool no_validation, -+ uint8_t *offset) -+{ -+ int code; -+ -+ switch (src) { -+ case E_FMAN_KG_GEN_EXTRACT_ETH: -+ code = no_validation ? 0x73 : 0x3; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_ETYPE: -+ code = no_validation ? 0x77 : 0x7; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_SNAP: -+ code = no_validation ? 0x74 : 0x4; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1: -+ code = no_validation ? 0x75 : 0x5; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N: -+ code = no_validation ? 0x76 : 0x6; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_PPPoE: -+ code = no_validation ? 0x78 : 0x8; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_MPLS_1: -+ code = no_validation ? 0x79 : 0x9; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_MPLS_2: -+ code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x19; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_MPLS_3: -+ code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x29; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_MPLS_N: -+ code = no_validation ? 0x7a : 0xa; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_IPv4_1: -+ code = no_validation ? 0x7b : 0xb; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_IPv6_1: -+ code = no_validation ? 0x7b : 0x1b; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_IPv4_2: -+ code = no_validation ? 0x7c : 0xc; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_IPv6_2: -+ code = no_validation ? 0x7c : 0x1c; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_MINENCAP: -+ code = no_validation ? 0x7c : 0x2c; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_IP_PID: -+ code = no_validation ? 0x72 : 0x2; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_GRE: -+ code = no_validation ? 0x7d : 0xd; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_TCP: -+ code = no_validation ? 0x7e : 0xe; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_UDP: -+ code = no_validation ? 0x7e : 0x1e; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_SCTP: -+ code = no_validation ? 0x7e : 0x3e; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_DCCP: -+ code = no_validation ? 0x7e : 0x4e; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_IPSEC_AH: -+ code = no_validation ? 0x7e : 0x2e; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP: -+ code = no_validation ? 0x7e : 0x6e; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_SHIM_1: -+ code = 0x70; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_SHIM_2: -+ code = 0x71; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_FROM_DFLT: -+ code = 0x10; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START: -+ code = 0x40; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT: -+ code = 0x20; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE: -+ code = 0x7f; -+ break; -+ -+ case E_FMAN_KG_GEN_EXTRACT_FROM_FQID: -+ code = 0x20; -+ *offset += 0x20; -+ break; -+ -+ default: -+ code = FM_KG_SCH_GEN_HT_INVALID; -+ } -+ -+ return (uint8_t)code; -+} -+ -+static uint32_t build_ar_scheme(uint8_t scheme, -+ uint8_t hwport_id, -+ bool update_counter, -+ bool write) -+{ -+ uint32_t rw; -+ -+ rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ); -+ -+ return (uint32_t)(FM_KG_KGAR_GO | -+ rw | -+ FM_KG_KGAR_SEL_SCHEME_ENTRY | -+ hwport_id | -+ ((uint32_t)scheme << FM_KG_KGAR_NUM_SHIFT) | -+ (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0)); -+} -+ -+static uint32_t build_ar_cls_plan(uint8_t grp, -+ uint8_t entries_mask, -+ uint8_t hwport_id, -+ bool write) -+{ -+ uint32_t rw; -+ -+ rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ); -+ -+ return (uint32_t)(FM_KG_KGAR_GO | -+ rw | -+ FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | -+ hwport_id | -+ ((uint32_t)grp << FM_KG_KGAR_NUM_SHIFT) | -+ ((uint32_t)entries_mask << FM_KG_KGAR_WSEL_SHIFT)); -+} -+ -+int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar) -+{ -+ iowrite32be(fmkg_ar, ®s->fmkg_ar); -+ /* Wait for GO to be idle and read error */ -+ while ((fmkg_ar = ioread32be(®s->fmkg_ar)) & FM_KG_KGAR_GO) ; -+ if (fmkg_ar & FM_PCD_KG_KGAR_ERR) -+ return -EINVAL; -+ return 0; -+} -+ -+void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add) -+{ -+ -+ struct fman_kg_pe_regs *kgpe_regs; -+ uint32_t tmp; -+ -+ kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]); -+ tmp = ioread32be(&kgpe_regs->fmkg_pe_sp); -+ -+ if (add) -+ tmp |= sp; -+ else /* clear */ -+ tmp &= ~sp; -+ -+ iowrite32be(tmp, &kgpe_regs->fmkg_pe_sp); -+ -+} -+ -+void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp) -+{ -+ struct fman_kg_pe_regs *kgpe_regs; -+ -+ kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]); -+ -+ iowrite32be(cpp, &kgpe_regs->fmkg_pe_cpp); -+} -+ -+void fman_kg_get_event(struct fman_kg_regs *regs, -+ uint32_t *event, -+ uint32_t *scheme_idx) -+{ -+ uint32_t mask, force; -+ -+ *event = ioread32be(®s->fmkg_eer); -+ mask = ioread32be(®s->fmkg_eeer); -+ *scheme_idx = ioread32be(®s->fmkg_seer); -+ *scheme_idx &= ioread32be(®s->fmkg_seeer); -+ -+ *event &= mask; -+ -+ /* clear the forced events */ -+ force = ioread32be(®s->fmkg_feer); -+ if (force & *event) -+ iowrite32be(force & ~*event ,®s->fmkg_feer); -+ -+ iowrite32be(*event, ®s->fmkg_eer); -+ iowrite32be(*scheme_idx, ®s->fmkg_seer); -+} -+ -+ -+void fman_kg_init(struct fman_kg_regs *regs, -+ uint32_t exceptions, -+ uint32_t dflt_nia) -+{ -+ uint32_t tmp; -+ int i; -+ -+ iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW, -+ ®s->fmkg_eer); -+ -+ tmp = 0; -+ if (exceptions & FM_EX_KG_DOUBLE_ECC) -+ tmp |= FM_EX_KG_DOUBLE_ECC; -+ -+ if (exceptions & FM_EX_KG_KEYSIZE_OVERFLOW) -+ tmp |= FM_EX_KG_KEYSIZE_OVERFLOW; -+ -+ iowrite32be(tmp, ®s->fmkg_eeer); -+ iowrite32be(0, ®s->fmkg_fdor); -+ iowrite32be(0, ®s->fmkg_gdv0r); -+ iowrite32be(0, ®s->fmkg_gdv1r); -+ iowrite32be(dflt_nia, ®s->fmkg_gcr); -+ -+ /* Clear binding between ports to schemes and classification plans -+ * so that all ports are not bound to any scheme/classification plan */ -+ for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) { -+ clear_pe_all_scheme(regs, (uint8_t)i); -+ clear_pe_all_cls_plan(regs, (uint8_t)i); -+ } -+} -+ -+void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs) -+{ -+ /* enable and enable all scheme interrupts */ -+ iowrite32be(0xFFFFFFFF, ®s->fmkg_seer); -+ iowrite32be(0xFFFFFFFF, ®s->fmkg_seeer); -+} -+ -+void fman_kg_enable(struct fman_kg_regs *regs) -+{ -+ iowrite32be(ioread32be(®s->fmkg_gcr) | FM_KG_KGGCR_EN, -+ ®s->fmkg_gcr); -+} -+ -+void fman_kg_disable(struct fman_kg_regs *regs) -+{ -+ iowrite32be(ioread32be(®s->fmkg_gcr) & ~FM_KG_KGGCR_EN, -+ ®s->fmkg_gcr); -+} -+ -+void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset) -+{ -+ iowrite32be(offset, ®s->fmkg_fdor); -+} -+ -+void fman_kg_set_dflt_val(struct fman_kg_regs *regs, -+ uint8_t def_id, -+ uint32_t val) -+{ -+ if(def_id == 0) -+ iowrite32be(val, ®s->fmkg_gdv0r); -+ else -+ iowrite32be(val, ®s->fmkg_gdv1r); -+} -+ -+ -+void fman_kg_set_exception(struct fman_kg_regs *regs, -+ uint32_t exception, -+ bool enable) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->fmkg_eeer); -+ -+ if (enable) { -+ tmp |= exception; -+ } else { -+ tmp &= ~exception; -+ } -+ -+ iowrite32be(tmp, ®s->fmkg_eeer); -+} -+ -+void fman_kg_get_exception(struct fman_kg_regs *regs, -+ uint32_t *events, -+ uint32_t *scheme_ids, -+ bool clear) -+{ -+ uint32_t mask; -+ -+ *events = ioread32be(®s->fmkg_eer); -+ mask = ioread32be(®s->fmkg_eeer); -+ *events &= mask; -+ -+ *scheme_ids = 0; -+ -+ if (*events & FM_EX_KG_KEYSIZE_OVERFLOW) { -+ *scheme_ids = ioread32be(®s->fmkg_seer); -+ mask = ioread32be(®s->fmkg_seeer); -+ *scheme_ids &= mask; -+ } -+ -+ if (clear) { -+ iowrite32be(*scheme_ids, ®s->fmkg_seer); -+ iowrite32be(*events, ®s->fmkg_eer); -+ } -+} -+ -+void fman_kg_get_capture(struct fman_kg_regs *regs, -+ struct fman_kg_ex_ecc_attr *ecc_attr, -+ bool clear) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->fmkg_serc); -+ -+ if (tmp & KG_FMKG_SERC_CAP) { -+ /* Captured data is valid */ -+ ecc_attr->valid = TRUE; -+ ecc_attr->double_ecc = -+ (bool)((tmp & KG_FMKG_SERC_CET) ? TRUE : FALSE); -+ ecc_attr->single_ecc_count = -+ (uint8_t)((tmp & KG_FMKG_SERC_CNT_MSK) >> -+ KG_FMKG_SERC_CNT_SHIFT); -+ ecc_attr->addr = (uint16_t)(tmp & KG_FMKG_SERC_ADDR_MSK); -+ -+ if (clear) -+ iowrite32be(KG_FMKG_SERC_CAP, ®s->fmkg_serc); -+ } else { -+ /* No ECC error is captured */ -+ ecc_attr->valid = FALSE; -+ } -+} -+ -+int fman_kg_build_scheme(struct fman_kg_scheme_params *params, -+ struct fman_kg_scheme_regs *scheme_regs) -+{ -+ struct fman_kg_extract_params *extract_params; -+ struct fman_kg_gen_extract_params *gen_params; -+ uint32_t tmp_reg, i, select, mask, fqb; -+ uint8_t offset, shift, ht; -+ -+ /* Zero out all registers so no need to care about unused ones */ -+ memset(scheme_regs, 0, sizeof(struct fman_kg_scheme_regs)); -+ -+ /* Mode register */ -+ tmp_reg = fm_kg_build_nia(params->next_engine, -+ params->next_engine_action); -+ if (tmp_reg == KG_NIA_INVALID) { -+ return -EINVAL; -+ } -+ -+ if (params->next_engine == E_FMAN_PCD_PLCR) { -+ tmp_reg |= FMAN_KG_SCH_MODE_NIA_PLCR; -+ } -+ else if (params->next_engine == E_FMAN_PCD_CC) { -+ tmp_reg |= (uint32_t)params->cc_params.base_offset << -+ FMAN_KG_SCH_MODE_CCOBASE_SHIFT; -+ } -+ -+ tmp_reg |= FMAN_KG_SCH_MODE_EN; -+ scheme_regs->kgse_mode = tmp_reg; -+ -+ /* Match vector */ -+ scheme_regs->kgse_mv = params->match_vector; -+ -+ extract_params = ¶ms->extract_params; -+ -+ /* Scheme default values registers */ -+ scheme_regs->kgse_dv0 = extract_params->def_scheme_0; -+ scheme_regs->kgse_dv1 = extract_params->def_scheme_1; -+ -+ /* Extract Known Fields Command register */ -+ scheme_regs->kgse_ekfc = extract_params->known_fields; -+ -+ /* Entry Extract Known Default Value register */ -+ tmp_reg = 0; -+ tmp_reg |= extract_params->known_fields_def.mac_addr << -+ FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.vlan_tci << -+ FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.etype << -+ FMAN_KG_SCH_DEF_ETYPE_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.ppp_sid << -+ FMAN_KG_SCH_DEF_PPP_SID_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.ppp_pid << -+ FMAN_KG_SCH_DEF_PPP_PID_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.mpls << -+ FMAN_KG_SCH_DEF_MPLS_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.ip_addr << -+ FMAN_KG_SCH_DEF_IP_ADDR_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.ptype << -+ FMAN_KG_SCH_DEF_PTYPE_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.ip_tos_tc << -+ FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.ipv6_fl << -+ FMAN_KG_SCH_DEF_IPv6_FL_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.ipsec_spi << -+ FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.l4_port << -+ FMAN_KG_SCH_DEF_L4_PORT_SHIFT; -+ tmp_reg |= extract_params->known_fields_def.tcp_flg << -+ FMAN_KG_SCH_DEF_TCP_FLG_SHIFT; -+ -+ scheme_regs->kgse_ekdv = tmp_reg; -+ -+ /* Generic extract registers */ -+ if (extract_params->gen_extract_num > FM_KG_NUM_OF_GENERIC_REGS) { -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < extract_params->gen_extract_num; i++) { -+ gen_params = extract_params->gen_extract + i; -+ -+ tmp_reg = FMAN_KG_SCH_GEN_VALID; -+ tmp_reg |= (uint32_t)gen_params->def_val << -+ FMAN_KG_SCH_GEN_DEF_SHIFT; -+ -+ if (gen_params->type == E_FMAN_KG_HASH_EXTRACT) { -+ if ((gen_params->extract > FMAN_KG_SCH_GEN_SIZE_MAX) || -+ (gen_params->extract == 0)) { -+ return -EINVAL; -+ } -+ } else { -+ tmp_reg |= FMAN_KG_SCH_GEN_OR; -+ } -+ -+ tmp_reg |= (uint32_t)gen_params->extract << -+ FMAN_KG_SCH_GEN_SIZE_SHIFT; -+ tmp_reg |= (uint32_t)gen_params->mask << -+ FMAN_KG_SCH_GEN_MASK_SHIFT; -+ -+ offset = gen_params->offset; -+ ht = get_gen_ht_code(gen_params->src, -+ gen_params->no_validation, -+ &offset); -+ tmp_reg |= (uint32_t)ht << FMAN_KG_SCH_GEN_HT_SHIFT; -+ tmp_reg |= offset; -+ -+ scheme_regs->kgse_gec[i] = tmp_reg; -+ } -+ -+ /* Masks registers */ -+ if (extract_params->masks_num > FM_KG_EXTRACT_MASKS_NUM) { -+ return -EINVAL; -+ } -+ -+ select = 0; -+ mask = 0; -+ fqb = 0; -+ for (i = 0; i < extract_params->masks_num; i++) { -+ /* MCSx fields */ -+ KG_GET_MASK_SEL_SHIFT(shift, i); -+ if (extract_params->masks[i].is_known) { -+ /* Mask known field */ -+ select |= extract_params->masks[i].field_or_gen_idx << -+ shift; -+ } else { -+ /* Mask generic extract */ -+ select |= (extract_params->masks[i].field_or_gen_idx + -+ FM_KG_MASK_SEL_GEN_BASE) << shift; -+ } -+ -+ /* MOx fields - spread between se_bmch and se_fqb registers */ -+ KG_GET_MASK_OFFSET_SHIFT(shift, i); -+ if (i < 2) { -+ select |= (uint32_t)extract_params->masks[i].offset << -+ shift; -+ } else { -+ fqb |= (uint32_t)extract_params->masks[i].offset << -+ shift; -+ } -+ -+ /* BMx fields */ -+ KG_GET_MASK_SHIFT(shift, i); -+ mask |= (uint32_t)extract_params->masks[i].mask << shift; -+ } -+ -+ /* Finish with rest of BMx fileds - -+ * don't mask bits for unused masks by setting -+ * corresponding BMx field = 0xFF */ -+ for (i = extract_params->masks_num; i < FM_KG_EXTRACT_MASKS_NUM; i++) { -+ KG_GET_MASK_SHIFT(shift, i); -+ mask |= 0xFF << shift; -+ } -+ -+ scheme_regs->kgse_bmch = select; -+ scheme_regs->kgse_bmcl = mask; -+ -+ /* Finish with FQB register initialization. -+ * Check fqid is 24-bit value. */ -+ if (params->base_fqid & ~0x00FFFFFF) { -+ return -EINVAL; -+ } -+ -+ fqb |= params->base_fqid; -+ scheme_regs->kgse_fqb = fqb; -+ -+ /* Hash Configuration register */ -+ tmp_reg = 0; -+ if (params->hash_params.use_hash) { -+ /* Check hash mask is 24-bit value */ -+ if (params->hash_params.mask & ~0x00FFFFFF) { -+ return -EINVAL; -+ } -+ -+ /* Hash function produces 64-bit value, 24 bits of that -+ * are used to generate fq_id and policer profile. -+ * Thus, maximal shift is 40 bits to allow 24 bits out of 64. -+ */ -+ if (params->hash_params.shift_r > FMAN_KG_SCH_HASH_HSHIFT_MAX) { -+ return -EINVAL; -+ } -+ -+ tmp_reg |= params->hash_params.mask; -+ tmp_reg |= (uint32_t)params->hash_params.shift_r << -+ FMAN_KG_SCH_HASH_HSHIFT_SHIFT; -+ -+ if (params->hash_params.sym) { -+ tmp_reg |= FMAN_KG_SCH_HASH_SYM; -+ } -+ -+ } -+ -+ if (params->bypass_fqid_gen) { -+ tmp_reg |= FMAN_KG_SCH_HASH_NO_FQID_GEN; -+ } -+ -+ scheme_regs->kgse_hc = tmp_reg; -+ -+ /* Policer Profile register */ -+ if (params->policer_params.bypass_pp_gen) { -+ tmp_reg = 0; -+ } else { -+ /* Lower 8 bits of 24-bits extracted from hash result -+ * are used for policer profile generation. -+ * That leaves maximum shift value = 23. */ -+ if (params->policer_params.shift > FMAN_KG_SCH_PP_SHIFT_MAX) { -+ return -EINVAL; -+ } -+ -+ tmp_reg = params->policer_params.base; -+ tmp_reg |= ((uint32_t)params->policer_params.shift << -+ FMAN_KG_SCH_PP_SH_SHIFT) & -+ FMAN_KG_SCH_PP_SH_MASK; -+ tmp_reg |= ((uint32_t)params->policer_params.shift << -+ FMAN_KG_SCH_PP_SL_SHIFT) & -+ FMAN_KG_SCH_PP_SL_MASK; -+ tmp_reg |= (uint32_t)params->policer_params.mask << -+ FMAN_KG_SCH_PP_MASK_SHIFT; -+ } -+ -+ scheme_regs->kgse_ppc = tmp_reg; -+ -+ /* Coarse Classification Bit Select register */ -+ if (params->next_engine == E_FMAN_PCD_CC) { -+ scheme_regs->kgse_ccbs = params->cc_params.qlcv_bits_sel; -+ } -+ -+ /* Packets Counter register */ -+ if (params->update_counter) { -+ scheme_regs->kgse_spc = params->counter_value; -+ } -+ -+ return 0; -+} -+ -+int fman_kg_write_scheme(struct fman_kg_regs *regs, -+ uint8_t scheme_id, -+ uint8_t hwport_id, -+ struct fman_kg_scheme_regs *scheme_regs, -+ bool update_counter) -+{ -+ struct fman_kg_scheme_regs *kgse_regs; -+ uint32_t tmp_reg; -+ int err, i; -+ -+ /* Write indirect scheme registers */ -+ kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]); -+ -+ iowrite32be(scheme_regs->kgse_mode, &kgse_regs->kgse_mode); -+ iowrite32be(scheme_regs->kgse_ekfc, &kgse_regs->kgse_ekfc); -+ iowrite32be(scheme_regs->kgse_ekdv, &kgse_regs->kgse_ekdv); -+ iowrite32be(scheme_regs->kgse_bmch, &kgse_regs->kgse_bmch); -+ iowrite32be(scheme_regs->kgse_bmcl, &kgse_regs->kgse_bmcl); -+ iowrite32be(scheme_regs->kgse_fqb, &kgse_regs->kgse_fqb); -+ iowrite32be(scheme_regs->kgse_hc, &kgse_regs->kgse_hc); -+ iowrite32be(scheme_regs->kgse_ppc, &kgse_regs->kgse_ppc); -+ iowrite32be(scheme_regs->kgse_spc, &kgse_regs->kgse_spc); -+ iowrite32be(scheme_regs->kgse_dv0, &kgse_regs->kgse_dv0); -+ iowrite32be(scheme_regs->kgse_dv1, &kgse_regs->kgse_dv1); -+ iowrite32be(scheme_regs->kgse_ccbs, &kgse_regs->kgse_ccbs); -+ iowrite32be(scheme_regs->kgse_mv, &kgse_regs->kgse_mv); -+ -+ for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++) -+ iowrite32be(scheme_regs->kgse_gec[i], &kgse_regs->kgse_gec[i]); -+ -+ /* Write AR (Action register) */ -+ tmp_reg = build_ar_scheme(scheme_id, hwport_id, update_counter, TRUE); -+ err = fman_kg_write_ar_wait(regs, tmp_reg); -+ return err; -+} -+ -+int fman_kg_delete_scheme(struct fman_kg_regs *regs, -+ uint8_t scheme_id, -+ uint8_t hwport_id) -+{ -+ struct fman_kg_scheme_regs *kgse_regs; -+ uint32_t tmp_reg; -+ int err, i; -+ -+ kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]); -+ -+ /* Clear all registers including enable bit in mode register */ -+ for (i = 0; i < (sizeof(struct fman_kg_scheme_regs)) / 4; ++i) { -+ iowrite32be(0, ((uint32_t *)kgse_regs + i)); -+ } -+ -+ /* Write AR (Action register) */ -+ tmp_reg = build_ar_scheme(scheme_id, hwport_id, FALSE, TRUE); -+ err = fman_kg_write_ar_wait(regs, tmp_reg); -+ return err; -+} -+ -+int fman_kg_get_scheme_counter(struct fman_kg_regs *regs, -+ uint8_t scheme_id, -+ uint8_t hwport_id, -+ uint32_t *counter) -+{ -+ struct fman_kg_scheme_regs *kgse_regs; -+ uint32_t tmp_reg; -+ int err; -+ -+ kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]); -+ -+ tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE); -+ err = fman_kg_write_ar_wait(regs, tmp_reg); -+ -+ if (err != 0) -+ return err; -+ -+ *counter = ioread32be(&kgse_regs->kgse_spc); -+ -+ return 0; -+} -+ -+int fman_kg_set_scheme_counter(struct fman_kg_regs *regs, -+ uint8_t scheme_id, -+ uint8_t hwport_id, -+ uint32_t counter) -+{ -+ struct fman_kg_scheme_regs *kgse_regs; -+ uint32_t tmp_reg; -+ int err; -+ -+ kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]); -+ -+ tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE); -+ -+ err = fman_kg_write_ar_wait(regs, tmp_reg); -+ if (err != 0) -+ return err; -+ -+ /* Keygen indirect access memory contains all scheme_id registers -+ * by now. Change only counter value. */ -+ iowrite32be(counter, &kgse_regs->kgse_spc); -+ -+ /* Write back scheme registers */ -+ tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, TRUE); -+ err = fman_kg_write_ar_wait(regs, tmp_reg); -+ -+ return err; -+} -+ -+uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs) -+{ -+ return ioread32be(®s->fmkg_tpc); -+} -+ -+int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params, -+ struct fman_kg_cp_regs *cls_plan_regs) -+{ -+ uint8_t entries_set, entry_bit; -+ int i; -+ -+ /* Zero out all group's register */ -+ memset(cls_plan_regs, 0, sizeof(struct fman_kg_cp_regs)); -+ -+ /* Go over all classification entries in params->entries_mask and -+ * configure the corresponding cpe register */ -+ entries_set = params->entries_mask; -+ for (i = 0; entries_set; i++) { -+ entry_bit = (uint8_t)(0x80 >> i); -+ if ((entry_bit & entries_set) == 0) -+ continue; -+ entries_set ^= entry_bit; -+ cls_plan_regs->kgcpe[i] = params->mask_vector[i]; -+ } -+ -+ return 0; -+} -+ -+int fman_kg_write_cls_plan(struct fman_kg_regs *regs, -+ uint8_t grp_id, -+ uint8_t entries_mask, -+ uint8_t hwport_id, -+ struct fman_kg_cp_regs *cls_plan_regs) -+{ -+ struct fman_kg_cp_regs *kgcpe_regs; -+ uint32_t tmp_reg; -+ int i, err; -+ -+ /* Check group index is valid and the group isn't empty */ -+ if (grp_id >= FM_KG_CLS_PLAN_GRPS_NUM) -+ return -EINVAL; -+ -+ /* Write indirect classification plan registers */ -+ kgcpe_regs = (struct fman_kg_cp_regs *)&(regs->fmkg_indirect[0]); -+ -+ for (i = 0; i < FM_KG_NUM_CLS_PLAN_ENTR; i++) { -+ iowrite32be(cls_plan_regs->kgcpe[i], &kgcpe_regs->kgcpe[i]); -+ } -+ -+ tmp_reg = build_ar_cls_plan(grp_id, entries_mask, hwport_id, TRUE); -+ err = fman_kg_write_ar_wait(regs, tmp_reg); -+ return err; -+} -+ -+int fman_kg_write_bind_schemes(struct fman_kg_regs *regs, -+ uint8_t hwport_id, -+ uint32_t schemes) -+{ -+ struct fman_kg_pe_regs *kg_pe_regs; -+ uint32_t tmp_reg; -+ int err; -+ -+ kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]); -+ -+ iowrite32be(schemes, &kg_pe_regs->fmkg_pe_sp); -+ -+ tmp_reg = build_ar_bind_scheme(hwport_id, TRUE); -+ err = fman_kg_write_ar_wait(regs, tmp_reg); -+ return err; -+} -+ -+int fman_kg_build_bind_cls_plans(uint8_t grp_base, -+ uint8_t grp_mask, -+ uint32_t *bind_cls_plans) -+{ -+ /* Check grp_base and grp_mask are 5-bits values */ -+ if ((grp_base & ~0x0000001F) || (grp_mask & ~0x0000001F)) -+ return -EINVAL; -+ -+ *bind_cls_plans = (uint32_t) ((grp_mask << FMAN_KG_PE_CPP_MASK_SHIFT) | grp_base); -+ return 0; -+} -+ -+ -+int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs, -+ uint8_t hwport_id, -+ uint32_t bind_cls_plans) -+{ -+ struct fman_kg_pe_regs *kg_pe_regs; -+ uint32_t tmp_reg; -+ int err; -+ -+ kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]); -+ -+ iowrite32be(bind_cls_plans, &kg_pe_regs->fmkg_pe_cpp); -+ -+ tmp_reg = build_ar_bind_cls_plan(hwport_id, TRUE); -+ err = fman_kg_write_ar_wait(regs, tmp_reg); -+ return err; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c -@@ -0,0 +1,129 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "fsl_fman_prs.h" -+ -+uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask) -+{ -+ return ioread32be(®s->fmpr_perr) & ev_mask; -+} -+ -+uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs) -+{ -+ return ioread32be(®s->fmpr_perer); -+} -+ -+void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event) -+{ -+ iowrite32be(event, ®s->fmpr_perr); -+} -+ -+uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask) -+{ -+ return ioread32be(®s->fmpr_pevr) & ev_mask; -+} -+ -+uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs) -+{ -+ return ioread32be(®s->fmpr_pever); -+} -+ -+void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event) -+{ -+ iowrite32be(event, ®s->fmpr_pevr); -+} -+ -+void fman_prs_defconfig(struct fman_prs_cfg *cfg) -+{ -+ cfg->port_id_stat = 0; -+ cfg->max_prs_cyc_lim = DEFAULT_MAX_PRS_CYC_LIM; -+ cfg->prs_exceptions = 0x03000000; -+} -+ -+int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg) -+{ -+ uint32_t tmp; -+ -+ iowrite32be(cfg->max_prs_cyc_lim, ®s->fmpr_rpclim); -+ iowrite32be((FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS), -+ ®s->fmpr_pevr); -+ -+ if (cfg->prs_exceptions & FM_PCD_EX_PRS_SINGLE_ECC) -+ iowrite32be(FM_PCD_PRS_SINGLE_ECC, ®s->fmpr_pever); -+ else -+ iowrite32be(0, ®s->fmpr_pever); -+ -+ iowrite32be(FM_PCD_PRS_DOUBLE_ECC, ®s->fmpr_perr); -+ -+ tmp = 0; -+ if (cfg->prs_exceptions & FM_PCD_EX_PRS_DOUBLE_ECC) -+ tmp |= FM_PCD_PRS_DOUBLE_ECC; -+ iowrite32be(tmp, ®s->fmpr_perer); -+ -+ iowrite32be(cfg->port_id_stat, ®s->fmpr_ppsc); -+ -+ return 0; -+} -+ -+void fman_prs_enable(struct fman_prs_regs *regs) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->fmpr_rpimac) | FM_PCD_PRS_RPIMAC_EN; -+ iowrite32be(tmp, ®s->fmpr_rpimac); -+} -+ -+void fman_prs_disable(struct fman_prs_regs *regs) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(®s->fmpr_rpimac) & ~FM_PCD_PRS_RPIMAC_EN; -+ iowrite32be(tmp, ®s->fmpr_rpimac); -+} -+ -+int fman_prs_is_enabled(struct fman_prs_regs *regs) -+{ -+ return ioread32be(®s->fmpr_rpimac) & FM_PCD_PRS_RPIMAC_EN; -+} -+ -+void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk) -+{ -+ iowrite32be(pid_msk, ®s->fmpr_ppsc); -+} -+ -+void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable) -+{ -+ if (enable) -+ iowrite32be(FM_PCD_PRS_PPSC_ALL_PORTS, ®s->fmpr_ppsc); -+ else -+ iowrite32be(0, ®s->fmpr_ppsc); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile -@@ -0,0 +1,15 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc -+ -+ccflags-y += -I$(NCSW_FM_INC) -+ -+obj-y += fsl-ncsw-Pcd.o -+ -+fsl-ncsw-Pcd-objs := fm_port.o fm_port_im.o fman_port.o ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c -@@ -0,0 +1,6436 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_port.c -+ -+ @Description FM driver routines implementation. -+ *//***************************************************************************/ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "string_ext.h" -+#include "sprint_ext.h" -+#include "debug_ext.h" -+#include "fm_muram_ext.h" -+ -+#include "fman_common.h" -+#include "fm_port.h" -+#include "fm_port_dsar.h" -+#include "common/general.h" -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort); -+ -+static t_Error CheckInitParameters(t_FmPort *p_FmPort) -+{ -+ t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam; -+ struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg; -+ t_Error ans = E_OK; -+ uint32_t unusedMask; -+ -+ if (p_FmPort->imEn) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth -+ > 2) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("fifoDeqPipelineDepth for IM 10G can't be larger than 2")); -+ -+ if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK) -+ return ERROR_CODE(ans); -+ } -+ else -+ { -+ /****************************************/ -+ /* Rx only */ -+ /****************************************/ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ { -+ /* external buffer pools */ -+ if (!p_Params->extBufPools.numOfPoolsUsed) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined")); -+ -+ if (FmSpCheckBufPoolsParams(&p_Params->extBufPools, -+ p_Params->p_BackupBmPools, -+ &p_Params->bufPoolDepletion) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ -+ /* Check that part of IC that needs copying is small enough to enter start margin */ -+ if (p_Params->intContext.size -+ && (p_Params->intContext.size -+ + p_Params->intContext.extBufOffset -+ > p_Params->bufMargins.startMargins)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("intContext.size is larger than start margins")); -+ -+ if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE) -+ && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1)); -+ -+#ifdef FM_NO_BACKUP_POOLS -+ if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6)) -+ if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools")); -+#endif /* FM_NO_BACKUP_POOLS */ -+ } -+ -+ /****************************************/ -+ /* Non Rx ports */ -+ /****************************************/ -+ else -+ { -+ if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS)); -+ -+ /* to protect HW internal-context from overwrite */ -+ if ((p_Params->intContext.size) -+ && (p_Params->intContext.intContextOffset -+ < MIN_TX_INT_OFFSET)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET)); -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) -+ /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */ -+ || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth -+ != DEFAULT_notSupported)) -+ { -+ /* Check that not larger than 8 */ -+ if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth) -+ || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth -+ > MAX_FIFO_PIPELINE_DEPTH)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH)); -+ } -+ } -+ -+ /****************************************/ -+ /* Rx Or Offline Parsing */ -+ /****************************************/ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ { -+ if (!p_Params->dfltFqid) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("dfltFqid must be between 1 and 2^24-1")); -+#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004) -+ if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16")); -+#endif /* defined(FM_CAPWAP_SUPPORT) && ... */ -+ } -+ -+ /****************************************/ -+ /* All ports */ -+ /****************************************/ -+ /* common BMI registers values */ -+ /* Check that Queue Id is not larger than 2^24, and is not 0 */ -+ if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("errFqid must be between 1 and 2^24-1")); -+ if (p_Params->dfltFqid & ~0x00FFFFFF) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("dfltFqid must be between 1 and 2^24-1")); -+ } -+ -+ /****************************************/ -+ /* Rx only */ -+ /****************************************/ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ { -+ if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS)); -+ if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS) -+ || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); -+ if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS)); -+ if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS) -+ || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); -+ -+ /* Check that not larger than 16 */ -+ if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); -+ -+ if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ -+ /* extra FIFO size (allowed only to Rx ports) */ -+ if (p_Params->setSizeOfFifo -+ && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS)); -+ -+ if (p_Params->bufPoolDepletion.poolsGrpModeEnable -+ && !p_Params->bufPoolDepletion.numOfPools) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE")); -+#ifdef FM_CSI_CFED_LIMIT -+ if (p_FmPort->fmRevInfo.majorRev == 4) -+ { -+ /* Check that not larger than 16 */ -+ if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE)); -+ } -+#endif /* FM_CSI_CFED_LIMIT */ -+ } -+ -+ /****************************************/ -+ /* Non Rx ports */ -+ /****************************************/ -+ /* extra FIFO size (allowed only to Rx ports) */ -+ else -+ if (p_FmPort->fifoBufs.extra) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ (" No fifoBufs.extra for non Rx ports")); -+ -+ /****************************************/ -+ /* Tx only */ -+ /****************************************/ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) -+ { -+ if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS)); -+ if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256))); -+ if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS)); -+ if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS) -+ || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); -+ -+ if (p_FmPort->portType == e_FM_PORT_TYPE_TX) -+ if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth -+ > 2) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("fifoDeqPipelineDepth for 1G can't be larger than 2")); -+ } -+ -+ /****************************************/ -+ /* Non Tx Ports */ -+ /****************************************/ -+ /* If discard override was selected , no frames may be discarded. */ -+ else -+ if (p_DfltConfig->discard_override && p_Params->errorsToDiscard) -+ RETURN_ERROR( -+ MAJOR, -+ E_CONFLICT, -+ ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue).")); -+ -+ /****************************************/ -+ /* Rx and Offline parsing */ -+ /****************************************/ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ unusedMask = BMI_STATUS_OP_MASK_UNUSED; -+ else -+ unusedMask = BMI_STATUS_RX_MASK_UNUSED; -+ -+ /* Check that no common bits with BMI_STATUS_MASK_UNUSED */ -+ if (p_Params->errorsToDiscard & unusedMask) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, -+ ("errorsToDiscard contains undefined bits")); -+ } -+ -+ /****************************************/ -+ /* Offline Ports */ -+ /****************************************/ -+#ifdef FM_OP_OPEN_DMA_MIN_LIMIT -+ if ((p_FmPort->fmRevInfo.majorRev >= 6) -+ && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ && p_Params->setNumOfOpenDmas -+ && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS)); -+#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */ -+ -+ /****************************************/ -+ /* Offline & HC Ports */ -+ /****************************************/ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) -+ { -+#ifndef FM_FRAME_END_PARAMS_FOR_OP -+ if ((p_FmPort->fmRevInfo.majorRev < 6) && -+ (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported)) -+ /* this is an indication that user called config for this mode which is not supported in this integration */ -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only")); -+#endif /* !FM_FRAME_END_PARAMS_FOR_OP */ -+ -+#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP -+ if ((!((p_FmPort->fmRevInfo.majorRev == 4) || -+ (p_FmPort->fmRevInfo.majorRev >= 6))) && -+ (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported)) -+ /* this is an indication that user called config for this mode which is not supported in this integration */ -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only")); -+#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */ -+ } -+ -+ /****************************************/ -+ /* All ports */ -+ /****************************************/ -+ /* Check that not larger than 16 */ -+ if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE) -+ && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported))) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE)); -+ -+ if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ -+ /* common BMI registers values */ -+ if (p_Params->setNumOfTasks -+ && ((!p_FmPort->tasks.num) -+ || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS)); -+ if (p_Params->setNumOfTasks -+ && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS)); -+ if (p_Params->setNumOfOpenDmas -+ && ((!p_FmPort->openDmas.num) -+ || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS)); -+ if (p_Params->setNumOfOpenDmas -+ && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS)); -+ if (p_Params->setSizeOfFifo -+ && (!p_FmPort->fifoBufs.num -+ || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE))) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); -+ if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS)); -+ -+#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT -+ if (p_FmPort->fmRevInfo.majorRev == 4) -+ if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported) -+ /* this is an indication that user called config for this mode which is not supported in this integration */ -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption")); -+#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ -+ -+ return E_OK; -+} -+ -+static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort) -+{ -+ uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0; -+ -+ /*************************/ -+ /* TX PORTS */ -+ /*************************/ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) -+ { -+ minFifoSizeRequired = -+ (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) -+ + (3 * BMI_FIFO_UNITS)); -+ if (!p_FmPort->imEn) -+ minFifoSizeRequired += -+ p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth -+ * BMI_FIFO_UNITS; -+ -+ optFifoSizeForB2B = minFifoSizeRequired; -+ -+ /* Add some margin for back-to-back capability to improve performance, -+ allows the hardware to pipeline new frame dma while the previous -+ frame not yet transmitted. */ -+ if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) -+ optFifoSizeForB2B += 3 * BMI_FIFO_UNITS; -+ else -+ optFifoSizeForB2B += 2 * BMI_FIFO_UNITS; -+ } -+ -+ /*************************/ -+ /* RX IM PORTS */ -+ /*************************/ -+ else -+ if (((p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ && p_FmPort->imEn) -+ { -+ optFifoSizeForB2B = -+ minFifoSizeRequired = -+ (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) -+ + (4 * BMI_FIFO_UNITS)); -+ } -+ -+ /*************************/ -+ /* RX non-IM PORTS */ -+ /*************************/ -+ else -+ if (((p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ && !p_FmPort->imEn) -+ { -+ if (p_FmPort->fmRevInfo.majorRev == 4) -+ { -+ if (p_FmPort->rxPoolsParams.numOfPools == 1) -+ minFifoSizeRequired = 8 * BMI_FIFO_UNITS; -+ else -+ minFifoSizeRequired = -+ (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS) -+ + (7 * BMI_FIFO_UNITS)); -+ } -+ else -+ { -+#if (DPAA_VERSION >= 11) -+ minFifoSizeRequired = -+ (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) -+ + (5 * BMI_FIFO_UNITS)); -+ /* 4 according to spec + 1 for FOF>0 */ -+#else -+ minFifoSizeRequired = (uint32_t) -+ (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS) -+ + (7*BMI_FIFO_UNITS)); -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+ optFifoSizeForB2B = minFifoSizeRequired; -+ -+ /* Add some margin for back-to-back capability to improve performance, -+ allows the hardware to pipeline new frame dma while the previous -+ frame not yet transmitted. */ -+ if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ optFifoSizeForB2B += 8 * BMI_FIFO_UNITS; -+ else -+ optFifoSizeForB2B += 3 * BMI_FIFO_UNITS; -+ } -+ -+ /* For O/H ports, check fifo size and update if necessary */ -+ else -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) -+ { -+#if (DPAA_VERSION >= 11) -+ optFifoSizeForB2B = -+ minFifoSizeRequired = -+ (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS) -+ + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth -+ + 5) * BMI_FIFO_UNITS)); -+ /* 4 according to spec + 1 for FOF>0 */ -+#else -+ optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS); -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+ ASSERT_COND(minFifoSizeRequired > 0); -+ ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired); -+ -+ /* Verify the size */ -+ if (p_FmPort->fifoBufs.num < minFifoSizeRequired) -+ DBG(INFO, -+ ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired)); -+ else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B) -+ DBG(INFO, -+ ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B)); -+ -+ return E_OK; -+} -+ -+static void FmPortDriverParamFree(t_FmPort *p_FmPort) -+{ -+ if (p_FmPort->p_FmPortDriverParam) -+ { -+ XX_Free(p_FmPort->p_FmPortDriverParam); -+ p_FmPort->p_FmPortDriverParam = NULL; -+ } -+} -+ -+static t_Error SetExtBufferPools(t_FmPort *p_FmPort) -+{ -+ t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools; -+ t_FmBufPoolDepletion *p_BufPoolDepletion = -+ &p_FmPort->p_FmPortDriverParam->bufPoolDepletion; -+ uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS]; -+ uint16_t sizesArray[BM_MAX_NUM_OF_POOLS]; -+ int i = 0, j = 0, err; -+ struct fman_port_bpools bpools; -+ -+ memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS); -+ memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS); -+ memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools)); -+ -+ FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray, -+ sizesArray); -+ -+ /* Prepare flibs bpools structure */ -+ memset(&bpools, 0, sizeof(struct fman_port_bpools)); -+ bpools.count = p_ExtBufPools->numOfPoolsUsed; -+ bpools.counters_enable = TRUE; -+ for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++) -+ { -+ bpools.bpool[i].bpid = orderedArray[i]; -+ bpools.bpool[i].size = sizesArray[orderedArray[i]]; -+ /* functionality available only for some derivatives (limited by config) */ -+ if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) -+ for (j = 0; -+ j -+ < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools; -+ j++) -+ if (orderedArray[i] -+ == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j]) -+ { -+ bpools.bpool[i].is_backup = TRUE; -+ break; -+ } -+ } -+ -+ /* save pools parameters for later use */ -+ p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed; -+ p_FmPort->rxPoolsParams.largestBufSize = -+ sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]]; -+ p_FmPort->rxPoolsParams.secondLargestBufSize = -+ sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]]; -+ -+ /* FMBM_RMPD reg. - pool depletion */ -+ if (p_BufPoolDepletion->poolsGrpModeEnable) -+ { -+ bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools; -+ for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++) -+ { -+ if (p_BufPoolDepletion->poolsToConsider[i]) -+ { -+ for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++) -+ { -+ if (i == orderedArray[j]) -+ { -+ bpools.bpool[j].grp_bp_depleted = TRUE; -+ break; -+ } -+ } -+ } -+ } -+ } -+ -+ if (p_BufPoolDepletion->singlePoolModeEnable) -+ { -+ for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++) -+ { -+ if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i]) -+ { -+ for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++) -+ { -+ if (i == orderedArray[j]) -+ { -+ bpools.bpool[j].single_bp_depleted = TRUE; -+ break; -+ } -+ } -+ } -+ } -+ } -+ -+#if (DPAA_VERSION >= 11) -+ /* fill QbbPEV */ -+ if (p_BufPoolDepletion->poolsGrpModeEnable -+ || p_BufPoolDepletion->singlePoolModeEnable) -+ { -+ for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++) -+ { -+ if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE) -+ { -+ bpools.bpool[i].pfc_priorities_en = TRUE; -+ } -+ } -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ /* Issue flibs function */ -+ err = fman_port_set_bpools(&p_FmPort->port, &bpools); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools")); -+ -+ if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools) -+ XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools); -+ -+ return E_OK; -+} -+ -+static t_Error ClearPerfCnts(t_FmPort *p_FmPort) -+{ -+ if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0); -+ FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0); -+ FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0); -+ FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0); -+ return E_OK; -+} -+ -+static t_Error InitLowLevelDriver(t_FmPort *p_FmPort) -+{ -+ t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam; -+ struct fman_port_params portParams; -+ uint32_t tmpVal; -+ t_Error err; -+ -+ /* Set up flibs parameters and issue init function */ -+ -+ memset(&portParams, 0, sizeof(struct fman_port_params)); -+ portParams.discard_mask = p_DriverParams->errorsToDiscard; -+ portParams.dflt_fqid = p_DriverParams->dfltFqid; -+ portParams.err_fqid = p_DriverParams->errFqid; -+ portParams.deq_sp = p_DriverParams->deqSubPortal; -+ portParams.dont_release_buf = p_DriverParams->dontReleaseBuf; -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask); -+ if (!p_FmPort->imEn) -+ { -+ if (p_DriverParams->forwardReuseIntContext) -+ p_DriverParams->dfltCfg.rx_fd_bits = -+ (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24); -+ } -+ break; -+ -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask); -+ break; -+ break; -+ -+ default: -+ break; -+ } -+ -+ tmpVal = -+ (uint32_t)( -+ (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset -+ / OFFSET_UNITS + 1) : -+ (p_FmPort->internalBufferOffset / OFFSET_UNITS)); -+ p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS); -+ p_DriverParams->dfltCfg.int_buf_start_margin = -+ p_FmPort->internalBufferOffset; -+ -+ p_DriverParams->dfltCfg.ext_buf_start_margin = -+ p_DriverParams->bufMargins.startMargins; -+ p_DriverParams->dfltCfg.ext_buf_end_margin = -+ p_DriverParams->bufMargins.endMargins; -+ -+ p_DriverParams->dfltCfg.ic_ext_offset = -+ p_DriverParams->intContext.extBufOffset; -+ p_DriverParams->dfltCfg.ic_int_offset = -+ p_DriverParams->intContext.intContextOffset; -+ p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size; -+ -+ p_DriverParams->dfltCfg.stats_counters_enable = TRUE; -+ p_DriverParams->dfltCfg.perf_counters_enable = TRUE; -+ p_DriverParams->dfltCfg.queue_counters_enable = TRUE; -+ -+ p_DriverParams->dfltCfg.perf_cnt_params.task_val = -+ (uint8_t)p_FmPort->tasks.num; -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING || -+ p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0; -+ else -+ p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1; -+ p_DriverParams->dfltCfg.perf_cnt_params.dma_val = -+ (uint8_t)p_FmPort->openDmas.num; -+ p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num; -+ -+ if (0 -+ != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg, -+ &portParams)) -+ RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init")); -+ -+ if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK)) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ else -+ { -+ // from QMIInit -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ { -+ if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH) -+ FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId, -+ FALSE); -+ else -+ FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId, -+ TRUE); -+ } -+ } -+ /* The code bellow is a trick so the FM will not release the buffer -+ to BM nor will try to enqueue the frame to QM */ -+ if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn)) -+ { -+ if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf) -+ { -+ /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to -+ * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release -+ * buffers to BM regardless of fmbm_tfene -+ */ -+ WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF); -+ WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene, -+ NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE); -+ } -+ } -+ -+ return E_OK; -+} -+ -+static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) -+{ -+ UNUSED(p_FmPort); -+ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_CYCLE): -+ case (e_FM_PORT_COUNTERS_TASK_UTIL): -+ case (e_FM_PORT_COUNTERS_QUEUE_UTIL): -+ case (e_FM_PORT_COUNTERS_DMA_UTIL): -+ case (e_FM_PORT_COUNTERS_FIFO_UTIL): -+ case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): -+ case (e_FM_PORT_COUNTERS_FRAME): -+ case (e_FM_PORT_COUNTERS_DISCARD_FRAME): -+ case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): -+ case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): -+ case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): -+ case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): -+ case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): -+ case (e_FM_PORT_COUNTERS_DEALLOC_BUF): -+ case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER): -+ return TRUE; -+ default: -+ return FALSE; -+ } -+} -+ -+static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) -+{ -+ UNUSED(p_FmPort); -+ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_CYCLE): -+ case (e_FM_PORT_COUNTERS_TASK_UTIL): -+ case (e_FM_PORT_COUNTERS_QUEUE_UTIL): -+ case (e_FM_PORT_COUNTERS_DMA_UTIL): -+ case (e_FM_PORT_COUNTERS_FIFO_UTIL): -+ case (e_FM_PORT_COUNTERS_FRAME): -+ case (e_FM_PORT_COUNTERS_DISCARD_FRAME): -+ case (e_FM_PORT_COUNTERS_LENGTH_ERR): -+ case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): -+ case (e_FM_PORT_COUNTERS_DEALLOC_BUF): -+ return TRUE; -+ default: -+ return FALSE; -+ } -+} -+ -+static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter) -+{ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_CYCLE): -+ case (e_FM_PORT_COUNTERS_TASK_UTIL): -+ case (e_FM_PORT_COUNTERS_DMA_UTIL): -+ case (e_FM_PORT_COUNTERS_FIFO_UTIL): -+ case (e_FM_PORT_COUNTERS_FRAME): -+ case (e_FM_PORT_COUNTERS_DISCARD_FRAME): -+ case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): -+ case (e_FM_PORT_COUNTERS_WRED_DISCARD): -+ case (e_FM_PORT_COUNTERS_LENGTH_ERR): -+ case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): -+ case (e_FM_PORT_COUNTERS_DEALLOC_BUF): -+ return TRUE; -+ case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) -+ return FALSE; -+ else -+ return TRUE; -+ default: -+ return FALSE; -+ } -+} -+ -+static t_Error BmiPortCheckAndGetCounterType( -+ t_FmPort *p_FmPort, e_FmPortCounters counter, -+ enum fman_port_stats_counters *p_StatsType, -+ enum fman_port_perf_counters *p_PerfType, bool *p_IsStats) -+{ -+ volatile uint32_t *p_Reg; -+ bool isValid; -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc; -+ isValid = CheckRxBmiCounter(p_FmPort, counter); -+ break; -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc; -+ isValid = CheckTxBmiCounter(p_FmPort, counter); -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc; -+ isValid = CheckOhBmiCounter(p_FmPort, counter); -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type")); -+ } -+ -+ if (!isValid) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, -+ ("Requested counter is not available for this port type")); -+ -+ /* check that counters are enabled */ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_CYCLE): -+ case (e_FM_PORT_COUNTERS_TASK_UTIL): -+ case (e_FM_PORT_COUNTERS_QUEUE_UTIL): -+ case (e_FM_PORT_COUNTERS_DMA_UTIL): -+ case (e_FM_PORT_COUNTERS_FIFO_UTIL): -+ case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): -+ /* performance counters - may be read when disabled */ -+ *p_IsStats = FALSE; -+ break; -+ case (e_FM_PORT_COUNTERS_FRAME): -+ case (e_FM_PORT_COUNTERS_DISCARD_FRAME): -+ case (e_FM_PORT_COUNTERS_DEALLOC_BUF): -+ case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): -+ case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): -+ case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): -+ case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): -+ case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): -+ case (e_FM_PORT_COUNTERS_LENGTH_ERR): -+ case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): -+ case (e_FM_PORT_COUNTERS_WRED_DISCARD): -+ *p_IsStats = TRUE; -+ if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN)) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, -+ ("Requested counter was not enabled")); -+ break; -+ default: -+ break; -+ } -+ -+ /* Set counter */ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_CYCLE): -+ *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE; -+ break; -+ case (e_FM_PORT_COUNTERS_TASK_UTIL): -+ *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL; -+ break; -+ case (e_FM_PORT_COUNTERS_QUEUE_UTIL): -+ *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL; -+ break; -+ case (e_FM_PORT_COUNTERS_DMA_UTIL): -+ *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL; -+ break; -+ case (e_FM_PORT_COUNTERS_FIFO_UTIL): -+ *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION): -+ *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE; -+ break; -+ case (e_FM_PORT_COUNTERS_FRAME): -+ *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME; -+ break; -+ case (e_FM_PORT_COUNTERS_DISCARD_FRAME): -+ *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD; -+ break; -+ case (e_FM_PORT_COUNTERS_DEALLOC_BUF): -+ *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_BAD_FRAME): -+ *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME): -+ *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD): -+ *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME): -+ *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME; -+ break; -+ case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR): -+ *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR; -+ break; -+ case (e_FM_PORT_COUNTERS_WRED_DISCARD): -+ *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD; -+ break; -+ case (e_FM_PORT_COUNTERS_LENGTH_ERR): -+ *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR; -+ break; -+ case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT): -+ *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT; -+ break; -+ default: -+ break; -+ } -+ -+ return E_OK; -+} -+ -+static t_Error AdditionalPrsParams(t_FmPort *p_FmPort, -+ t_FmPcdPrsAdditionalHdrParams *p_HdrParams, -+ uint32_t *p_SoftSeqAttachReg) -+{ -+ uint8_t hdrNum, Ipv4HdrNum; -+ u_FmPcdHdrPrsOpts *p_prsOpts; -+ uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset; -+ -+ if (IS_PRIVATE_HEADER(p_HdrParams->hdr) -+ || IS_SPECIAL_HEADER(p_HdrParams->hdr)) -+ RETURN_ERROR( -+ MAJOR, E_NOT_SUPPORTED, -+ ("No additional parameters for private or special headers.")); -+ -+ if (p_HdrParams->errDisable) -+ tmpReg |= PRS_HDR_ERROR_DIS; -+ -+ /* Set parser options */ -+ if (p_HdrParams->usePrsOpts) -+ { -+ p_prsOpts = &p_HdrParams->prsOpts; -+ switch (p_HdrParams->hdr) -+ { -+ case (HEADER_TYPE_MPLS): -+ if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable) -+ tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN; -+ hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse); -+ if (hdrNum == ILLEGAL_HDR_NUM) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); -+ if (hdrNum < Ipv4HdrNum) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("Header must be equal or higher than IPv4")); -+ tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE) -+ << PRS_HDR_MPLS_NEXT_HDR_SHIFT; -+ break; -+ case (HEADER_TYPE_PPPoE): -+ if (p_prsOpts->pppoePrsOptions.enableMTUCheck) -+ tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN; -+ break; -+ case (HEADER_TYPE_IPv6): -+ if (p_prsOpts->ipv6PrsOptions.routingHdrEnable) -+ tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN; -+ break; -+ case (HEADER_TYPE_TCP): -+ if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum) -+ tmpReg |= PRS_HDR_TCP_PAD_REMOVAL; -+ else -+ tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL; -+ break; -+ case (HEADER_TYPE_UDP): -+ if (p_prsOpts->udpPrsOptions.padIgnoreChecksum) -+ tmpReg |= PRS_HDR_UDP_PAD_REMOVAL; -+ else -+ tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header")); -+ } -+ } -+ -+ /* set software parsing (address is divided in 2 since parser uses 2 byte access. */ -+ if (p_HdrParams->swPrsEnable) -+ { -+ tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr, -+ p_HdrParams->indexPerHdr); -+ if (tmpPrsOffset == ILLEGAL_BASE) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset); -+ } -+ *p_SoftSeqAttachReg = tmpReg; -+ -+ return E_OK; -+} -+ -+static uint32_t GetPortSchemeBindParams( -+ t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ uint32_t walking1Mask = 0x80000000, tmp; -+ uint8_t idx = 0; -+ -+ p_SchemeBind->netEnvId = p_FmPort->netEnvId; -+ p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId; -+ p_SchemeBind->useClsPlan = p_FmPort->useClsPlan; -+ p_SchemeBind->numOfSchemes = 0; -+ tmp = p_FmPort->schemesPerPortVector; -+ if (tmp) -+ { -+ while (tmp) -+ { -+ if (tmp & walking1Mask) -+ { -+ p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx; -+ p_SchemeBind->numOfSchemes++; -+ tmp &= ~walking1Mask; -+ } -+ walking1Mask >>= 1; -+ idx++; -+ } -+ } -+ -+ return tmp; -+} -+ -+static void FmPortCheckNApplyMacsec(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ volatile uint32_t *p_BmiCfgReg = NULL; -+ uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC; -+ uint32_t lcv, walking1Mask = 0x80000000; -+ uint8_t cnt = 0; -+ -+ ASSERT_COND(p_FmPort); -+ ASSERT_COND(p_FmPort->h_FmPcd); -+ ASSERT_COND(!p_FmPort->p_FmPortDriverParam); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ return; -+ -+ p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg; -+ /* get LCV for MACSEC */ -+ if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId)) -+ != 0) -+ { -+ while (!(lcv & walking1Mask)) -+ { -+ cnt++; -+ walking1Mask >>= 1; -+ } -+ -+ macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT; -+ WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn); -+ } -+} -+ -+static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams) -+{ -+ t_Error err = E_OK; -+ uint32_t tmpReg; -+ volatile uint32_t *p_BmiNia = NULL; -+ volatile uint32_t *p_BmiPrsNia = NULL; -+ volatile uint32_t *p_BmiPrsStartOffset = NULL; -+ volatile uint32_t *p_BmiInitPrsResult = NULL; -+ volatile uint32_t *p_BmiCcBase = NULL; -+ uint16_t hdrNum, L3HdrNum, greHdrNum; -+ int i; -+ bool isEmptyClsPlanGrp; -+ uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS]; -+ uint16_t absoluteProfileId; -+ uint8_t physicalSchemeId; -+ uint32_t ccTreePhysOffset; -+ t_FmPcdKgInterModuleBindPortToSchemes schemeBind; -+ uint32_t initialSwPrs = 0; -+ -+ ASSERT_COND(p_FmPort); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPort->imEn) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for non-independant mode ports only")); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ -+ p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv); -+ -+ p_FmPort->pcdEngines = 0; -+ -+ /* initialize p_FmPort->pcdEngines field in port's structure */ -+ switch (p_PcdParams->pcdSupport) -+ { -+ case (e_FM_PORT_PCD_SUPPORT_NONE): -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected")); -+ case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY): -+ p_FmPort->pcdEngines |= FM_PCD_PRS; -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY): -+ p_FmPort->pcdEngines |= FM_PCD_PLCR; -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): -+ p_FmPort->pcdEngines |= FM_PCD_PRS; -+ p_FmPort->pcdEngines |= FM_PCD_PLCR; -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): -+ p_FmPort->pcdEngines |= FM_PCD_PRS; -+ p_FmPort->pcdEngines |= FM_PCD_KG; -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): -+ p_FmPort->pcdEngines |= FM_PCD_PRS; -+ p_FmPort->pcdEngines |= FM_PCD_CC; -+ p_FmPort->pcdEngines |= FM_PCD_KG; -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): -+ p_FmPort->pcdEngines |= FM_PCD_PRS; -+ p_FmPort->pcdEngines |= FM_PCD_KG; -+ p_FmPort->pcdEngines |= FM_PCD_CC; -+ p_FmPort->pcdEngines |= FM_PCD_PLCR; -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC): -+ p_FmPort->pcdEngines |= FM_PCD_PRS; -+ p_FmPort->pcdEngines |= FM_PCD_CC; -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR): -+ p_FmPort->pcdEngines |= FM_PCD_PRS; -+ p_FmPort->pcdEngines |= FM_PCD_CC; -+ p_FmPort->pcdEngines |= FM_PCD_PLCR; -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): -+ p_FmPort->pcdEngines |= FM_PCD_PRS; -+ p_FmPort->pcdEngines |= FM_PCD_KG; -+ p_FmPort->pcdEngines |= FM_PCD_PLCR; -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_CC_ONLY): -+ p_FmPort->pcdEngines |= FM_PCD_CC; -+ break; -+#ifdef FM_CAPWAP_SUPPORT -+ case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG): -+ p_FmPort->pcdEngines |= FM_PCD_CC; -+ p_FmPort->pcdEngines |= FM_PCD_KG; -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR): -+ p_FmPort->pcdEngines |= FM_PCD_CC; -+ p_FmPort->pcdEngines |= FM_PCD_KG; -+ p_FmPort->pcdEngines |= FM_PCD_PLCR; -+ break; -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport")); -+ } -+ -+ if ((p_FmPort->pcdEngines & FM_PCD_PRS) -+ && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams -+ > FM_PCD_PRS_NUM_OF_HDRS)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS)); -+ -+ /* check that parameters exist for each and only each defined engine */ -+ if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams) -+ || (!!(p_FmPort->pcdEngines & FM_PCD_KG) -+ != !!p_PcdParams->p_KgParams) -+ || (!!(p_FmPort->pcdEngines & FM_PCD_CC) -+ != !!p_PcdParams->p_CcParams)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("PCD initialization structure is not consistent with pcdSupport")); -+ -+ /* get PCD registers pointers */ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; -+ p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne; -+ p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso; -+ p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0]; -+ p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; -+ p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne; -+ p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso; -+ p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0]; -+ p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ /* set PCD port parameter */ -+ if (p_FmPort->pcdEngines & FM_PCD_CC) -+ { -+ err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams, -+ p_PcdParams->p_CcParams->h_CcTree, -+ &ccTreePhysOffset, p_FmPort); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset); -+ p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree; -+ } -+ -+ if (p_FmPort->pcdEngines & FM_PCD_KG) -+ { -+ if (p_PcdParams->p_KgParams->numOfSchemes == 0) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("For ports using Keygen, at least one scheme must be bound. ")); -+ -+ err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd, -+ p_FmPort->hardwarePortId, -+ p_FmPort->netEnvId, -+ p_FmPort->optArray, -+ &p_FmPort->clsPlanGrpId, -+ &isEmptyClsPlanGrp); -+ if (err) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("FmPcdKgSetOrBindToClsPlanGrp failed. ")); -+ -+ p_FmPort->useClsPlan = !isEmptyClsPlanGrp; -+ -+ schemeBind.netEnvId = p_FmPort->netEnvId; -+ schemeBind.hardwarePortId = p_FmPort->hardwarePortId; -+ schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes; -+ schemeBind.useClsPlan = p_FmPort->useClsPlan; -+ -+ /* for each scheme */ -+ for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++) -+ { -+ ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]); -+ physicalSchemeId = FmPcdKgGetSchemeId( -+ p_PcdParams->p_KgParams->h_Schemes[i]); -+ schemeBind.schemesIds[i] = physicalSchemeId; -+ /* build vector */ -+ p_FmPort->schemesPerPortVector |= 1 -+ << (31 - (uint32_t)physicalSchemeId); -+#if (DPAA_VERSION >= 11) -+ /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement -+ if !VSPE - in port, for relevant scheme VSPE can not be set*/ -+ if (!p_FmPort->vspe -+ && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i]))) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("VSPE is not at port level")); -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+ err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ /***************************/ -+ /* configure NIA after BMI */ -+ /***************************/ -+ /* rfne may contain FDCS bits, so first we read them. */ -+ p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; -+ -+ /* If policer is used directly after BMI or PRS */ -+ if ((p_FmPort->pcdEngines & FM_PCD_PLCR) -+ && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY) -+ || (p_PcdParams->pcdSupport -+ == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR))) -+ { -+ if (!p_PcdParams->p_PlcrParams->h_Profile) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Profile should be initialized")); -+ -+ absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId( -+ p_PcdParams->p_PlcrParams->h_Profile); -+ -+ if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Private port profile not valid.")); -+ -+ tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE); -+ -+ if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */ -+ /* update BMI HPNIA */ -+ WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg)); -+ else -+ /* e_FM_PCD_SUPPORT_PLCR_ONLY */ -+ /* update BMI NIA */ -+ p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR); -+ } -+ -+ /* if CC is used directly after BMI */ -+ if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY) -+#ifdef FM_CAPWAP_SUPPORT -+ || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG) -+ || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR) -+#endif /* FM_CAPWAP_SUPPORT */ -+ ) -+ { -+ if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_OPERATION, -+ ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only")); -+ p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC); -+ /* check that prs start offset == RIM[FOF] */ -+ } -+ -+ if (p_FmPort->pcdEngines & FM_PCD_PRS) -+ { -+ ASSERT_COND(p_PcdParams->p_PrsParams); -+#if (DPAA_VERSION >= 11) -+ if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP) -+ hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL; -+ else -+ { -+#endif /* (DPAA_VERSION >= 11) */ -+ /* if PRS is used it is always first */ -+ hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr); -+ if (hdrNum == ILLEGAL_HDR_NUM) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header.")); -+#if (DPAA_VERSION >= 11) -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum)); -+ /* set after parser NIA */ -+ tmpReg = 0; -+ switch (p_PcdParams->pcdSupport) -+ { -+ case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY): -+ WRITE_UINT32(*p_BmiPrsNia, -+ GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd)); -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): -+ tmpReg = NIA_KG_CC_EN; -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): -+ if (p_PcdParams->p_KgParams->directScheme) -+ { -+ physicalSchemeId = FmPcdKgGetSchemeId( -+ p_PcdParams->p_KgParams->h_DirectScheme); -+ /* check that this scheme was bound to this port */ -+ for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++) -+ if (p_PcdParams->p_KgParams->h_DirectScheme -+ == p_PcdParams->p_KgParams->h_Schemes[i]) -+ break; -+ if (i == p_PcdParams->p_KgParams->numOfSchemes) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("Direct scheme is not one of the port selected schemes.")); -+ tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId); -+ } -+ WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg); -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC): -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR): -+ WRITE_UINT32(*p_BmiPrsNia, -+ (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC)); -+ break; -+ case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR): -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support")); -+ } -+ -+ /* set start parsing offset */ -+ WRITE_UINT32(*p_BmiPrsStartOffset, -+ p_PcdParams->p_PrsParams->parsingOffset); -+ -+ /************************************/ -+ /* Parser port parameters */ -+ /************************************/ -+ /* stop before configuring */ -+ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP); -+ /* wait for parser to be in idle state */ -+ while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) -+ ; -+ -+ /* set soft seq attachment register */ -+ memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t)); -+ -+ /* set protocol options */ -+ for (i = 0; p_FmPort->optArray[i]; i++) -+ switch (p_FmPort->optArray[i]) -+ { -+ case (ETH_BROADCAST): -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH); -+ tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT; -+ break; -+ case (ETH_MULTICAST): -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH); -+ tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT; -+ break; -+ case (VLAN_STACKED): -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN); -+ tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT; -+ break; -+ case (MPLS_STACKED): -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS); -+ tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT; -+ break; -+ case (IPV4_BROADCAST_1): -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); -+ tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT; -+ break; -+ case (IPV4_MULTICAST_1): -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); -+ tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT; -+ break; -+ case (IPV4_UNICAST_2): -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); -+ tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT; -+ break; -+ case (IPV4_MULTICAST_BROADCAST_2): -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); -+ tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT; -+ break; -+ case (IPV6_MULTICAST_1): -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); -+ tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT; -+ break; -+ case (IPV6_UNICAST_2): -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); -+ tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT; -+ break; -+ case (IPV6_MULTICAST_2): -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); -+ tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT; -+ break; -+ } -+ -+ if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, -+ HEADER_TYPE_UDP_ENCAP_ESP)) -+ { -+ if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS) -+ RETURN_ERROR( -+ MINOR, E_INVALID_VALUE, -+ ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1")); -+ -+ p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr = -+ HEADER_TYPE_UDP; -+ p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable = -+ TRUE; -+ p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++; -+ } -+ -+ /* set MPLS default next header - HW reset workaround */ -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS); -+ tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN; -+ L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3); -+ tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT; -+ -+ /* for GRE, disable errors */ -+ greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE); -+ tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS; -+ -+ /* For UDP remove PAD from L4 checksum calculation */ -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP); -+ tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL; -+ /* For TCP remove PAD from L4 checksum calculation */ -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP); -+ tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL; -+ -+ /* config additional params for specific headers */ -+ for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams; -+ i++) -+ { -+ /* case for using sw parser as the initial NIA address, before -+ * HW parsing -+ */ -+ if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) && -+ p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable) -+ { -+ initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE, -+ p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr); -+ if (initialSwPrs == ILLEGAL_BASE) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ -+ /* clear parser first HXS */ -+ p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */ -+ /* rewrite with soft parser start */ -+ p_FmPort->savedBmiNia |= initialSwPrs; -+ continue; -+ } -+ -+ hdrNum = -+ GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr); -+ if (hdrNum == ILLEGAL_HDR_NUM) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ if (hdrNum == NO_HDR_NUM) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("Private headers may not use additional parameters")); -+ -+ err = AdditionalPrsParams( -+ p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i], -+ &tmpHxs[hdrNum]); -+ if (err) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ } -+ -+ /* Check if ip-reassembly port - need to link sw-parser code */ -+ if (p_FmPort->h_IpReassemblyManip) -+ { -+ /* link to sw parser code for IP Frag - only if no other code is applied. */ -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4); -+ if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) -+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL); -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); -+ if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) -+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL); -+ } else { -+ if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE)) -+ { -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); -+ if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) -+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL); -+ } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd) -+ && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))) -+ { -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); -+ if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) -+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL); -+ } -+ } -+ -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+ if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, -+ HEADER_TYPE_UDP_LITE)) -+ { -+ /* link to sw parser code for udp lite - only if no other code is applied. */ -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); -+ if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN)) -+ tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL); -+ } -+#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+ for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++) -+ { -+ /* For all header set LCV as taken from netEnv*/ -+ WRITE_UINT32( -+ p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv, -+ FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i)); -+ /* set HXS register according to default+Additional params+protocol options */ -+ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach, -+ tmpHxs[i]); -+ } -+ -+ /* set tpid. */ -+ tmpReg = PRS_TPID_DFLT; -+ if (p_PcdParams->p_PrsParams->setVlanTpid1) -+ { -+ tmpReg &= PRS_TPID2_MASK; -+ tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1 -+ << PRS_PCTPID_SHIFT; -+ } -+ if (p_PcdParams->p_PrsParams->setVlanTpid2) -+ { -+ tmpReg &= PRS_TPID1_MASK; -+ tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2; -+ }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg); -+ -+ /* enable parser */ -+ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0); -+ -+ if (p_PcdParams->p_PrsParams->prsResultPrivateInfo) -+ p_FmPort->privateInfo = -+ p_PcdParams->p_PrsParams->prsResultPrivateInfo; -+ -+ } /* end parser */ -+ else { -+ if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd) -+ && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ { -+ hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6); -+ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach, -+ (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL)); -+ } -+ -+ WRITE_UINT32(*p_BmiPrsStartOffset, 0); -+ -+ p_FmPort->privateInfo = 0; -+ } -+ -+ FmPortCheckNApplyMacsec(p_FmPort); -+ -+ WRITE_UINT32( -+ *p_BmiPrsStartOffset, -+ GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset); -+ -+ /* set initial parser result - used for all engines */ -+ for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++) -+ { -+ if (!i) -+ WRITE_UINT32( -+ *(p_BmiInitPrsResult), -+ (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH)); -+ else -+ { -+ if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2) -+ WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH); -+ else -+ WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW); -+ } -+ } -+ -+ return E_OK; -+} -+ -+static t_Error DeletePcd(t_FmPort *p_FmPort) -+{ -+ t_Error err = E_OK; -+ volatile uint32_t *p_BmiNia = NULL; -+ volatile uint32_t *p_BmiPrsStartOffset = NULL; -+ -+ ASSERT_COND(p_FmPort); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPort->imEn) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for non-independant mode ports only")); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ -+ if (!p_FmPort->pcdEngines) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port")); -+ -+ /* get PCD registers pointers */ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; -+ p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; -+ p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) -+ != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("port has to be detached previousely")); -+ -+ WRITE_UINT32(*p_BmiPrsStartOffset, 0); -+ -+ /* "cut" PCD out of the port's flow - go to BMI */ -+ /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */ -+ -+ if (p_FmPort->pcdEngines & FM_PCD_PRS) -+ { -+ /* stop parser */ -+ WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP); -+ /* wait for parser to be in idle state */ -+ while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE) -+ ; -+ } -+ -+ if (p_FmPort->pcdEngines & FM_PCD_KG) -+ { -+ t_FmPcdKgInterModuleBindPortToSchemes schemeBind; -+ -+ /* unbind all schemes */ -+ p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort, -+ &schemeBind); -+ -+ err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd, -+ p_FmPort->hardwarePortId, -+ p_FmPort->clsPlanGrpId); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ p_FmPort->useClsPlan = FALSE; -+ } -+ -+ if (p_FmPort->pcdEngines & FM_PCD_CC) -+ { -+ /* unbind - we need to get the treeId too */ -+ err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ p_FmPort->pcdEngines = 0; -+ -+ return E_OK; -+} -+ -+static t_Error AttachPCD(t_FmPort *p_FmPort) -+{ -+ volatile uint32_t *p_BmiNia = NULL; -+ -+ ASSERT_COND(p_FmPort); -+ -+ /* get PCD registers pointers */ -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; -+ else -+ p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; -+ -+ /* check that current NIA is BMI to BMI */ -+ if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) -+ != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()) -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("may be called only for ports in BMI-to-BMI state.")); -+ -+ if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) -+ if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1, -+ p_FmPort->orFmanCtrl) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_CMNE) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne, -+ p_FmPort->savedBmiCmne); -+ else -+ WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne, -+ p_FmPort->savedBmiCmne); -+ } -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_PNEN) -+ WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen, -+ p_FmPort->savedQmiPnen); -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_FENE) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene, -+ p_FmPort->savedBmiFene); -+ else -+ WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene, -+ p_FmPort->savedBmiFene); -+ } -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_FPNE) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne, -+ p_FmPort->savedBmiFpne); -+ else -+ WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne, -+ p_FmPort->savedBmiFpne); -+ } -+ -+ if (p_FmPort->requiredAction & UPDATE_OFP_DPTE) -+ { -+ ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING); -+ -+ WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp, -+ p_FmPort->savedBmiOfp); -+ } -+ -+ WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia); -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_PNDN) -+ { -+ p_FmPort->origNonRxQmiRegsPndn = -+ GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn); -+ WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn, -+ p_FmPort->savedNonRxQmiRegsPndn); -+ } -+ -+ return E_OK; -+} -+ -+static t_Error DetachPCD(t_FmPort *p_FmPort) -+{ -+ volatile uint32_t *p_BmiNia = NULL; -+ -+ ASSERT_COND(p_FmPort); -+ -+ /* get PCD registers pointers */ -+ if (p_FmPort->requiredAction & UPDATE_NIA_PNDN) -+ WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn, -+ p_FmPort->origNonRxQmiRegsPndn); -+ -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; -+ else -+ p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; -+ -+ WRITE_UINT32( -+ *p_BmiNia, -+ (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME()); -+ -+ if (FmPcdGetHcHandle(p_FmPort->h_FmPcd)) -+ FmPcdHcSync(p_FmPort->h_FmPcd); -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_FENE) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene, -+ NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); -+ else -+ WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene, -+ NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR); -+ } -+ -+ if (p_FmPort->requiredAction & UPDATE_NIA_PNEN) -+ WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen, -+ NIA_ENG_BMI | NIA_BMI_AC_RELEASE); -+ -+ if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) -+ if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2, -+ p_FmPort->orFmanCtrl) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ p_FmPort->requiredAction = 0; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+/* Inter-module API routines */ -+/*****************************************************************************/ -+void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ volatile uint32_t *p_BmiCfgReg = NULL; -+ uint32_t tmpReg; -+ -+ SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only")); -+ return; -+ } -+ -+ p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca; -+ tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK; -+ tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED; -+ tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT) -+ & BMI_CMD_ATTR_MACCMD_SC_MASK); -+ -+ WRITE_UINT32(*p_BmiCfgReg, tmpReg); -+} -+ -+uint8_t FmPortGetNetEnvId(t_Handle h_FmPort) -+{ -+ return ((t_FmPort*)h_FmPort)->netEnvId; -+} -+ -+uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort) -+{ -+ return ((t_FmPort*)h_FmPort)->hardwarePortId; -+} -+ -+uint32_t FmPortGetPcdEngines(t_Handle h_FmPort) -+{ -+ return ((t_FmPort*)h_FmPort)->pcdEngines; -+} -+ -+#if (DPAA_VERSION >= 11) -+t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, -+ void **p_Value) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ uint32_t muramPageOffset; -+ -+ ASSERT_COND(p_FmPort); -+ ASSERT_COND(p_Value); -+ -+ if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY) -+ { -+ if (p_FmPort->gprFunc != gprFunc) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("gpr was assigned with different func")); -+ } -+ else -+ { -+ switch (gprFunc) -+ { -+ case (e_FM_PORT_GPR_MURAM_PAGE): -+ p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, -+ 256, 8); -+ if (!p_FmPort->p_ParamsPage) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page")); -+ -+ IOMemSet32(p_FmPort->p_ParamsPage, 0, 256); -+ muramPageOffset = -+ (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage) -+ - p_FmPort->fmMuramPhysBaseAddr); -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ WRITE_UINT32( -+ p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr, -+ muramPageOffset); -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ WRITE_UINT32( -+ p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr, -+ muramPageOffset); -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Invalid port type")); -+ } -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ p_FmPort->gprFunc = gprFunc; -+ } -+ -+ switch (p_FmPort->gprFunc) -+ { -+ case (e_FM_PORT_GPR_MURAM_PAGE): -+ *p_Value = p_FmPort->p_ParamsPage; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ -+ return E_OK; -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+t_Error FmPortGetSetCcParams(t_Handle h_FmPort, -+ t_FmPortGetSetCcParams *p_CcParams) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ int tmpInt; -+ volatile uint32_t *p_BmiPrsStartOffset = NULL; -+ -+ /* this function called from Cc for pass and receive parameters port params between CC and PORT*/ -+ -+ if ((p_CcParams->getCcParams.type & OFFSET_OF_PR) -+ && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE)) -+ { -+ p_CcParams->getCcParams.prOffset = -+ (uint8_t)p_FmPort->bufferOffsets.prsResultOffset; -+ p_CcParams->getCcParams.type &= ~OFFSET_OF_PR; -+ } -+ if (p_CcParams->getCcParams.type & HW_PORT_ID) -+ { -+ p_CcParams->getCcParams.hardwarePortId = -+ (uint8_t)p_FmPort->hardwarePortId; -+ p_CcParams->getCcParams.type &= ~HW_PORT_ID; -+ } -+ if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA) -+ && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE)) -+ { -+ p_CcParams->getCcParams.dataOffset = -+ (uint16_t)p_FmPort->bufferOffsets.dataOffset; -+ p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA; -+ } -+ if (p_CcParams->getCcParams.type & NUM_OF_TASKS) -+ { -+ p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num; -+ p_CcParams->getCcParams.type &= ~NUM_OF_TASKS; -+ } -+ if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS) -+ { -+ p_CcParams->getCcParams.numOfExtraTasks = -+ (uint8_t)p_FmPort->tasks.extra; -+ p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS; -+ } -+ if (p_CcParams->getCcParams.type & FM_REV) -+ { -+ p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev; -+ p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev; -+ p_CcParams->getCcParams.type &= ~FM_REV; -+ } -+ if (p_CcParams->getCcParams.type & DISCARD_MASK) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ p_CcParams->getCcParams.discardMask = -+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm); -+ else -+ p_CcParams->getCcParams.discardMask = -+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm); -+ p_CcParams->getCcParams.type &= ~DISCARD_MASK; -+ } -+ if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE) -+ { -+ p_CcParams->getCcParams.internalBufferOffset = -+ p_FmPort->internalBufferOffset; -+ p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE; -+ } -+ if (p_CcParams->getCcParams.type & GET_NIA_FPNE) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ p_CcParams->getCcParams.nia = -+ GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne); -+ else -+ p_CcParams->getCcParams.nia = -+ GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne); -+ p_CcParams->getCcParams.type &= ~GET_NIA_FPNE; -+ } -+ if (p_CcParams->getCcParams.type & GET_NIA_PNDN) -+ { -+ if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ p_CcParams->getCcParams.nia = -+ GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn); -+ p_CcParams->getCcParams.type &= ~GET_NIA_PNDN; -+ } -+ -+ if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY) -+ && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)) -+ { -+ p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY; -+ p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl; -+ } -+ -+ if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN) -+ && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN)) -+ { -+ p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia; -+ p_FmPort->requiredAction |= UPDATE_NIA_PNEN; -+ } -+ else -+ if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN) -+ { -+ if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("PNEN was defined previously different")); -+ } -+ -+ if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN) -+ && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN)) -+ { -+ p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia; -+ p_FmPort->requiredAction |= UPDATE_NIA_PNDN; -+ } -+ else -+ if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN) -+ { -+ if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("PNDN was defined previously different")); -+ } -+ -+ if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE) -+ && (p_CcParams->setCcParams.overwrite -+ || !(p_FmPort->requiredAction & UPDATE_NIA_FENE))) -+ { -+ p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia; -+ p_FmPort->requiredAction |= UPDATE_NIA_FENE; -+ } -+ else -+ if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE) -+ { -+ if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia) -+ RETURN_ERROR( MAJOR, E_INVALID_STATE, -+ ("xFENE was defined previously different")); -+ } -+ -+ if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE) -+ && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE)) -+ { -+ p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia; -+ p_FmPort->requiredAction |= UPDATE_NIA_FPNE; -+ } -+ else -+ if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE) -+ { -+ if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia) -+ RETURN_ERROR( MAJOR, E_INVALID_STATE, -+ ("xFPNE was defined previously different")); -+ } -+ -+ if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE) -+ && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE)) -+ { -+ p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia; -+ p_FmPort->requiredAction |= UPDATE_NIA_CMNE; -+ } -+ else -+ if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE) -+ { -+ if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia) -+ RETURN_ERROR( MAJOR, E_INVALID_STATE, -+ ("xCMNE was defined previously different")); -+ } -+ -+ if ((p_CcParams->setCcParams.type & UPDATE_PSO) -+ && !(p_FmPort->requiredAction & UPDATE_PSO)) -+ { -+ /* get PCD registers pointers */ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ /* set start parsing offset */ -+ tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset) -+ + p_CcParams->setCcParams.psoSize; -+ if (tmpInt > 0) -+ WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt); -+ -+ p_FmPort->requiredAction |= UPDATE_PSO; -+ p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize; -+ } -+ else -+ if (p_CcParams->setCcParams.type & UPDATE_PSO) -+ { -+ if (p_FmPort->savedPrsStartOffset -+ != p_CcParams->setCcParams.psoSize) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("parser start offset was defoned previousley different")); -+ } -+ -+ if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE) -+ && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE)) -+ { -+ if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp); -+ p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK; -+ p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde -+ << BMI_FIFO_PIPELINE_DEPTH_SHIFT; -+ p_FmPort->requiredAction |= UPDATE_OFP_DPTE; -+ } -+ -+ return E_OK; -+} -+/*********************** End of inter-module routines ************************/ -+ -+/****************************************/ -+/* API Init unit functions */ -+/****************************************/ -+ -+t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams) -+{ -+ t_FmPort *p_FmPort; -+ uintptr_t baseAddr = p_FmPortParams->baseAddr; -+ uint32_t tmpReg; -+ -+ /* Allocate FM structure */ -+ p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort)); -+ if (!p_FmPort) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure")); -+ return NULL; -+ } -+ memset(p_FmPort, 0, sizeof(t_FmPort)); -+ -+ /* Allocate the FM driver's parameters structure */ -+ p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc( -+ sizeof(t_FmPortDriverParam)); -+ if (!p_FmPort->p_FmPortDriverParam) -+ { -+ XX_Free(p_FmPort); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters")); -+ return NULL; -+ } -+ memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam)); -+ -+ /* Initialize FM port parameters which will be kept by the driver */ -+ p_FmPort->portType = p_FmPortParams->portType; -+ p_FmPort->portId = p_FmPortParams->portId; -+ p_FmPort->pcdEngines = FM_PCD_NONE; -+ p_FmPort->f_Exception = p_FmPortParams->f_Exception; -+ p_FmPort->h_App = p_FmPortParams->h_App; -+ p_FmPort->h_Fm = p_FmPortParams->h_Fm; -+ -+ /* get FM revision */ -+ FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo); -+ -+ /* calculate global portId number */ -+ p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType, -+ p_FmPortParams->portId, -+ p_FmPort->fmRevInfo.majorRev, -+ p_FmPort->fmRevInfo.minorRev); -+ -+ if (p_FmPort->fmRevInfo.majorRev >= 6) -+ { -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) -+ && (p_FmPortParams->portId != FM_OH_PORT_ID)) -+ DBG(WARNING, -+ ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.", -+ FM_OH_PORT_ID)); -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ && (p_FmPortParams->portId == FM_OH_PORT_ID)) -+ DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0.")); -+ } -+ -+ /* Set up FM port parameters for initialization phase only */ -+ -+ /* First, fill in flibs struct */ -+ fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg, -+ (enum fman_port_type)p_FmPort->portType); -+ /* Overwrite some integration specific parameters */ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = -+ DEFAULT_PORT_rxFifoPriElevationLevel; -+ p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = -+ DEFAULT_PORT_rxFifoThreshold; -+ -+#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006) -+ p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE; -+#else -+ p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE; -+#endif -+ if ((p_FmPort->fmRevInfo.majorRev == 6) -+ && (p_FmPort->fmRevInfo.minorRev == 0)) -+ p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE; -+ else -+ p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE; -+ -+ /* Excessive Threshold register - exists for pre-FMv3 chips only */ -+ if (p_FmPort->fmRevInfo.majorRev < 6) -+ { -+#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC -+ p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register = -+ TRUE; -+#endif -+ p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE; -+ p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE; -+ } -+ else -+ { -+ p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register = -+ FALSE; -+ p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE; -+ p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE; -+ } -+ if (p_FmPort->fmRevInfo.majorRev == 4) -+ p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE; -+ else -+ p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE; -+ -+ /* Continue with other parameters */ -+ p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr; -+ /* set memory map pointers */ -+ p_FmPort->p_FmPortQmiRegs = -+ (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET); -+ p_FmPort->p_FmPortBmiRegs = -+ (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET); -+ p_FmPort->p_FmPortPrsRegs = -+ (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET); -+ -+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize = -+ DEFAULT_PORT_bufferPrefixContent_privDataSize; -+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult = -+ DEFAULT_PORT_bufferPrefixContent_passPrsResult; -+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp = -+ DEFAULT_PORT_bufferPrefixContent_passTimeStamp; -+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo = -+ DEFAULT_PORT_bufferPrefixContent_passTimeStamp; -+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = -+ DEFAULT_PORT_bufferPrefixContent_dataAlign; -+ /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData; -+ p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr; -+ p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr; -+ p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr; -+ p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize; -+ */ -+ p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase; -+ p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = -+ DEFAULT_PORT_cheksumLastBytesIgnore; -+ -+ p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength; -+ /* resource distribution. */ -+ p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType) -+ * BMI_FIFO_UNITS; -+ p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs -+ * BMI_FIFO_UNITS; -+ p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType); -+ p_FmPort->openDmas.extra = -+ DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType); -+ p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType); -+ p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType); -+ -+ -+#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 -+ if ((p_FmPort->fmRevInfo.majorRev == 6) -+ && (p_FmPort->fmRevInfo.minorRev == 0) -+ && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_TX))) -+ { -+ p_FmPort->openDmas.num = 16; -+ p_FmPort->openDmas.extra = 0; -+ } -+#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */ -+ -+ /* Port type specific initialization: */ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX): -+ case (e_FM_PORT_TYPE_RX_10G): -+ /* Initialize FM port parameters for initialization phase only */ -+ p_FmPort->p_FmPortDriverParam->cutBytesFromEnd = -+ DEFAULT_PORT_cutBytesFromEnd; -+ p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE; -+ p_FmPort->p_FmPortDriverParam->frmDiscardOverride = -+ DEFAULT_PORT_frmDiscardOverride; -+ -+ tmpReg = -+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp); -+ p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel = -+ (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK) -+ >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1) -+ * BMI_FIFO_UNITS; -+ p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg -+ & BMI_RX_FIFO_THRESHOLD_MASK) -+ >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS; -+ -+ p_FmPort->p_FmPortDriverParam->bufMargins.endMargins = -+ DEFAULT_PORT_BufMargins_endMargins; -+ p_FmPort->p_FmPortDriverParam->errorsToDiscard = -+ DEFAULT_PORT_errorsToDiscard; -+ p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = -+ DEFAULT_PORT_forwardIntContextReuse; -+#if (DPAA_VERSION >= 11) -+ p_FmPort->p_FmPortDriverParam->noScatherGather = -+ DEFAULT_PORT_noScatherGather; -+#endif /* (DPAA_VERSION >= 11) */ -+ break; -+ -+ case (e_FM_PORT_TYPE_TX): -+ p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE; -+#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 -+ tmpReg = 0x00001013; -+ WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp, -+ tmpReg); -+#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */ -+ case (e_FM_PORT_TYPE_TX_10G): -+ tmpReg = -+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp); -+ p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg -+ & BMI_TX_FIFO_MIN_FILL_MASK) -+ >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS; -+ p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = -+ (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK) -+ >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1); -+ p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg -+ & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1) -+ * BMI_FIFO_UNITS; -+ -+ p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType; -+ p_FmPort->p_FmPortDriverParam->deqPrefetchOption = -+ DEFAULT_PORT_deqPrefetchOption; -+ p_FmPort->p_FmPortDriverParam->deqHighPriority = -+ (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G : -+ DEFAULT_PORT_deqHighPriority_10G); -+ p_FmPort->p_FmPortDriverParam->deqByteCnt = -+ (uint16_t)( -+ (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G : -+ DEFAULT_PORT_deqByteCnt_10G); -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_FmPort->p_FmPortDriverParam->errorsToDiscard = -+ DEFAULT_PORT_errorsToDiscard; -+#if (DPAA_VERSION >= 11) -+ p_FmPort->p_FmPortDriverParam->noScatherGather = -+ DEFAULT_PORT_noScatherGather; -+#endif /* (DPAA_VERSION >= 11) */ -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ p_FmPort->p_FmPortDriverParam->deqPrefetchOption = -+ DEFAULT_PORT_deqPrefetchOption_HC; -+ p_FmPort->p_FmPortDriverParam->deqHighPriority = -+ DEFAULT_PORT_deqHighPriority_1G; -+ p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType; -+ p_FmPort->p_FmPortDriverParam->deqByteCnt = -+ DEFAULT_PORT_deqByteCnt_1G; -+ -+ tmpReg = -+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp); -+ p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = -+ (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK) -+ >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1); -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) -+ && (p_FmPortParams->portId != FM_OH_PORT_ID)) -+ { -+ /* Overwrite HC defaults */ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = -+ DEFAULT_PORT_fifoDeqPipelineDepth_OH; -+ } -+ -+#ifndef FM_FRAME_END_PARAMS_FOR_OP -+ if (p_FmPort->fmRevInfo.majorRev < 6) -+ p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported; -+#endif /* !FM_FRAME_END_PARAMS_FOR_OP */ -+ -+#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP -+ if (!((p_FmPort->fmRevInfo.majorRev == 4) || -+ (p_FmPort->fmRevInfo.majorRev >= 6))) -+ p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported; -+#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */ -+ break; -+ -+ default: -+ XX_Free(p_FmPort->p_FmPortDriverParam); -+ XX_Free(p_FmPort); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ return NULL; -+ } -+#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT -+ if (p_FmPort->fmRevInfo.majorRev == 4) -+ p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported; -+#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ -+ -+ p_FmPort->imEn = p_FmPortParams->independentModeEnable; -+ -+ if (p_FmPort->imEn) -+ { -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)) -+ p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = -+ DEFAULT_PORT_fifoDeqPipelineDepth_IM; -+ FmPortConfigIM(p_FmPort, p_FmPortParams); -+ } -+ else -+ { -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX): -+ case (e_FM_PORT_TYPE_RX_10G): -+ /* Initialize FM port parameters for initialization phase only */ -+ memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, -+ &p_FmPortParams->specificParams.rxParams.extBufPools, -+ sizeof(t_FmExtPools)); -+ p_FmPort->p_FmPortDriverParam->errFqid = -+ p_FmPortParams->specificParams.rxParams.errFqid; -+ p_FmPort->p_FmPortDriverParam->dfltFqid = -+ p_FmPortParams->specificParams.rxParams.dfltFqid; -+ p_FmPort->p_FmPortDriverParam->liodnOffset = -+ p_FmPortParams->specificParams.rxParams.liodnOffset; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_TX): -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ p_FmPort->p_FmPortDriverParam->errFqid = -+ p_FmPortParams->specificParams.nonRxParams.errFqid; -+ p_FmPort->p_FmPortDriverParam->deqSubPortal = -+ (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel -+ & QMI_DEQ_CFG_SUBPORTAL_MASK); -+ p_FmPort->p_FmPortDriverParam->dfltFqid = -+ p_FmPortParams->specificParams.nonRxParams.dfltFqid; -+ break; -+ default: -+ XX_Free(p_FmPort->p_FmPortDriverParam); -+ XX_Free(p_FmPort); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ return NULL; -+ } -+ } -+ -+ memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE); -+ if (Sprint( -+ p_FmPort->name, -+ "FM-%d-port-%s-%d", -+ FmGetId(p_FmPort->h_Fm), -+ ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING -+ || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" : -+ (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" : -+ (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" : -+ (p_FmPort->portType -+ == e_FM_PORT_TYPE_RX_10G ? "10g-RX" : -+ "10g-TX")))), -+ p_FmPort->portId) == 0) -+ { -+ XX_Free(p_FmPort->p_FmPortDriverParam); -+ XX_Free(p_FmPort); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); -+ return NULL; -+ } -+ -+ p_FmPort->h_Spinlock = XX_InitSpinlock(); -+ if (!p_FmPort->h_Spinlock) -+ { -+ XX_Free(p_FmPort->p_FmPortDriverParam); -+ XX_Free(p_FmPort); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); -+ return NULL; -+ } -+ -+ return p_FmPort; -+} -+ -+t_FmPort *rx_port = 0; -+t_FmPort *tx_port = 0; -+ -+/**************************************************************************//** -+ @Function FM_PORT_Init -+ -+ @Description Initializes the FM module -+ -+ @Param[in] h_FmPort - FM module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+ *//***************************************************************************/ -+t_Error FM_PORT_Init(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_FmPortDriverParam *p_DriverParams; -+ t_Error errCode; -+ t_FmInterModulePortInitParams fmParams; -+ t_FmRevisionInfo revInfo; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ errCode = FmSpBuildBufferStructure( -+ &p_FmPort->p_FmPortDriverParam->intContext, -+ &p_FmPort->p_FmPortDriverParam->bufferPrefixContent, -+ &p_FmPort->p_FmPortDriverParam->bufMargins, -+ &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset); -+ if (errCode != E_OK) -+ RETURN_ERROR(MAJOR, errCode, NO_MSG); -+#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 -+ if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) && -+ (p_FmPort->portType == e_FM_PORT_TYPE_RX)) -+ { -+ p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL; -+ if (!p_FmPort->fifoBufs.num) -+ p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS; -+ p_FmPort->fifoBufs.num += 4*KILOBYTE; -+ } -+#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */ -+ -+ CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters); -+ -+ p_DriverParams = p_FmPort->p_FmPortDriverParam; -+ -+ /* Set up flibs port structure */ -+ memset(&p_FmPort->port, 0, sizeof(struct fman_port)); -+ p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType; -+ FM_GetRevision(p_FmPort->h_Fm, &revInfo); -+ p_FmPort->port.fm_rev_maj = revInfo.majorRev; -+ p_FmPort->port.fm_rev_min = revInfo.minorRev; -+ p_FmPort->port.bmi_regs = -+ (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET); -+ p_FmPort->port.qmi_regs = -+ (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET); -+ p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8); -+ p_FmPort->port.im_en = p_FmPort->imEn; -+ p_FmPort->p_FmPortPrsRegs = -+ (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET); -+ -+ if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn) -+ { -+ /* Call the external Buffer routine which also checks fifo -+ size and updates it if necessary */ -+ /* define external buffer pools and pool depletion*/ -+ errCode = SetExtBufferPools(p_FmPort); -+ if (errCode) -+ RETURN_ERROR(MAJOR, errCode, NO_MSG); -+ /* check if the largest external buffer pool is large enough */ -+ if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE -+ + p_DriverParams->bufMargins.endMargins -+ > p_FmPort->rxPoolsParams.largestBufSize) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("bufMargins.startMargins (%d) + minimum buf size (64) + bufMargins.endMargins (%d) is larger than maximum external buffer size (%d)", p_DriverParams->bufMargins.startMargins, p_DriverParams->bufMargins.endMargins, p_FmPort->rxPoolsParams.largestBufSize)); -+ } -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ { -+ { -+#ifdef FM_NO_OP_OBSERVED_POOLS -+ t_FmRevisionInfo revInfo; -+ -+ FM_GetRevision(p_FmPort->h_Fm, &revInfo); -+ if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion)) -+#endif /* FM_NO_OP_OBSERVED_POOLS */ -+ { -+ /* define external buffer pools */ -+ errCode = SetExtBufferPools(p_FmPort); -+ if (errCode) -+ RETURN_ERROR(MAJOR, errCode, NO_MSG); -+ } -+ } -+ } -+ -+ /************************************************************/ -+ /* Call FM module routine for communicating parameters */ -+ /************************************************************/ -+ memset(&fmParams, 0, sizeof(fmParams)); -+ fmParams.hardwarePortId = p_FmPort->hardwarePortId; -+ fmParams.portType = (e_FmPortType)p_FmPort->portType; -+ fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num; -+ fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra; -+ fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num; -+ fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra; -+ -+ if (p_FmPort->fifoBufs.num) -+ { -+ errCode = VerifySizeOfFifo(p_FmPort); -+ if (errCode != E_OK) -+ RETURN_ERROR(MAJOR, errCode, NO_MSG); -+ } -+ fmParams.sizeOfFifo = p_FmPort->fifoBufs.num; -+ fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra; -+ fmParams.independentMode = p_FmPort->imEn; -+ fmParams.liodnOffset = p_DriverParams->liodnOffset; -+ fmParams.liodnBase = p_DriverParams->liodnBase; -+ fmParams.deqPipelineDepth = -+ p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth; -+ fmParams.maxFrameLength = p_FmPort->maxFrameLength; -+#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) || -+ (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) -+ { -+ if (!((p_FmPort->fmRevInfo.majorRev == 4) || -+ (p_FmPort->fmRevInfo.majorRev >= 6))) -+ /* HC ports do not have fifoDeqPipelineDepth, but it is needed only -+ * for deq threshold calculation. -+ */ -+ fmParams.deqPipelineDepth = 2; -+ } -+#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */ -+ -+ errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams); -+ if (errCode) -+ RETURN_ERROR(MAJOR, errCode, NO_MSG); -+ -+ /* get params for use in init */ -+ p_FmPort->fmMuramPhysBaseAddr = -+ (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low) -+ | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32)); -+ p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm); -+ -+ errCode = InitLowLevelDriver(p_FmPort); -+ if (errCode != E_OK) -+ RETURN_ERROR(MAJOR, errCode, NO_MSG); -+ -+ FmPortDriverParamFree(p_FmPort); -+ -+#if (DPAA_VERSION >= 11) -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ { -+ t_FmPcdCtrlParamsPage *p_ParamsPage; -+ -+ FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, -+ (void**)&p_ParamsPage); -+ ASSERT_COND(p_ParamsPage); -+ -+ WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON); -+#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ { -+ WRITE_UINT32( -+ p_ParamsPage->misc, -+ (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN)); -+ WRITE_UINT32( -+ p_ParamsPage->discardMask, -+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm)); -+ } -+#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */ -+#ifdef FM_ERROR_VSP_NO_MATCH_SW006 -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ WRITE_UINT32( -+ p_ParamsPage->errorsDiscardMask, -+ (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem))); -+ else -+ WRITE_UINT32( -+ p_ParamsPage->errorsDiscardMask, -+ (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem))); -+#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */ -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ if (p_FmPort->deepSleepVars.autoResMaxSizes) -+ FmPortConfigAutoResForDeepSleepSupport1(p_FmPort); -+ return E_OK; -+} -+ -+/**************************************************************************//** -+ @Function FM_PORT_Free -+ -+ @Description Frees all resources that were assigned to FM module. -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_FmPort - FM module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+ *//***************************************************************************/ -+t_Error FM_PORT_Free(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_FmInterModulePortFreeParams fmParams; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ -+ if (p_FmPort->pcdEngines) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first.")); -+ -+ if (p_FmPort->enabled) -+ { -+ if (FM_PORT_Disable(p_FmPort) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED")); -+ } -+ -+ if (p_FmPort->imEn) -+ FmPortImFree(p_FmPort); -+ -+ FmPortDriverParamFree(p_FmPort); -+ -+ memset(&fmParams, 0, sizeof(fmParams)); -+ fmParams.hardwarePortId = p_FmPort->hardwarePortId; -+ fmParams.portType = (e_FmPortType)p_FmPort->portType; -+ fmParams.deqPipelineDepth = -+ p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth; -+ -+ FmFreePortParams(p_FmPort->h_Fm, &fmParams); -+ -+#if (DPAA_VERSION >= 11) -+ if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId) -+ != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED")); -+ -+ if (p_FmPort->p_ParamsPage) -+ FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ if (p_FmPort->h_Spinlock) -+ XX_FreeSpinlock(p_FmPort->h_Spinlock); -+ -+ XX_Free(p_FmPort); -+ -+ return E_OK; -+} -+ -+/*************************************************/ -+/* API Advanced Init unit functions */ -+/*************************************************/ -+ -+t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE; -+ memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc)); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc)); -+ p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE; -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE; -+ memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc)); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("not available for Rx ports")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type = -+ (enum fman_port_deq_type)deqType; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigDeqPrefetchOption( -+ t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("not available for Rx ports")); -+ p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt = -+ (enum fman_port_deq_prefetch)deqPrefetchOption; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, -+ t_FmBackupBmPools *p_BackupBmPools) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Rx ports only")); -+ -+ p_FmPort->p_FmPortDriverParam->p_BackupBmPools = -+ (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools)); -+ if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed")); -+ memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools, -+ sizeof(t_FmBackupBmPools)); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("not available for Rx ports")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigBufferPrefixContent( -+ t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent, -+ p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent)); -+ /* if dataAlign was not initialized by user, we return to driver's default */ -+ if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign) -+ p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign = -+ DEFAULT_PORT_bufferPrefixContent_dataAlign; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, -+ uint8_t checksumLastBytesIgnore) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore = -+ checksumLastBytesIgnore; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, -+ uint8_t cutBytesFromEnd) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Rx ports only")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, -+ t_FmBufPoolDepletion *p_BufPoolDepletion) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Rx ports only")); -+ -+ p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE; -+ memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion, -+ sizeof(t_FmBufPoolDepletion)); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigObservedPoolDepletion( -+ t_Handle h_FmPort, -+ t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for OP ports only")); -+ -+ p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE; -+ memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, -+ &p_FmPortObservedBufPoolDepletion->poolDepletionParams, -+ sizeof(t_FmBufPoolDepletion)); -+ memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, -+ &p_FmPortObservedBufPoolDepletion->poolsParams, -+ sizeof(t_FmExtPools)); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for OP ports only")); -+ -+ memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools, -+ sizeof(t_FmExtPools)); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Tx ports only")); -+ -+ p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("Not available for Tx ports")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("Not available for Tx ports")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, -+ fmPortFrameErrSelect_t errs) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ -+ p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data = -+ (enum fman_port_dma_swap)swapData; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, -+ e_FmDmaCacheOption intContextCacheAttr) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on = -+ (bool)(intContextCacheAttr == e_FM_DMA_STASH); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, -+ e_FmDmaCacheOption headerCacheAttr) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on = -+ (bool)(headerCacheAttr == e_FM_DMA_STASH); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigDmaScatterGatherAttr( -+ t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on = -+ (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("Not available for Tx ports")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize; -+ -+ return E_OK; -+} -+ -+#if (DPAA_VERSION >= 11) -+t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ UNUSED(noScatherGather); -+ UNUSED(p_FmPort); -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather; -+ -+ return E_OK; -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, -+ bool forwardReuse) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Rx ports only")); -+ -+ p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->maxFrameLength = length; -+ -+ return E_OK; -+} -+ -+#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 -+t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE; -+ -+ return E_OK; -+} -+#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */ -+ -+/****************************************************/ -+/* Hidden-DEBUG Only API */ -+/****************************************************/ -+ -+t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, -+ uint32_t minFillLevel) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Tx ports only")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, -+ uint8_t deqPipelineDepth) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("Not available for Rx ports")); -+ -+ if (p_FmPort->imEn) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("Not available for IM ports!")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = -+ deqPipelineDepth; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, -+ uint32_t fifoLowComfLevel) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_TX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Tx ports only")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level = -+ fifoLowComfLevel; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Rx ports only")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, -+ uint32_t priElevationLevel) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Rx ports only")); -+ -+ p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel; -+ -+ return E_OK; -+} -+/****************************************************/ -+/* API Run-time Control unit functions */ -+/****************************************************/ -+ -+t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, -+ t_FmPortRsrc *p_NumOfOpenDmas) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS)) -+ RETURN_ERROR( MAJOR, E_INVALID_VALUE, -+ ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS)); -+ if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS)); -+ err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId, -+ (uint8_t*)&p_NumOfOpenDmas->num, -+ (uint8_t*)&p_NumOfOpenDmas->extra, FALSE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc)); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */ -+ ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND); -+ -+ if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS)); -+ if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS)); -+ -+ err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId, -+ (uint8_t*)&p_NumOfTasks->num, -+ (uint8_t*)&p_NumOfTasks->extra, FALSE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ /* update driver's struct */ -+ memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc)); -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE)); -+ if (p_SizeOfFifo->num % BMI_FIFO_UNITS) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS)); -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ { -+ /* extra FIFO size (allowed only to Rx ports) */ -+ if (p_SizeOfFifo->extra % BMI_FIFO_UNITS) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS)); -+ } -+ else -+ if (p_SizeOfFifo->extra) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ (" No SizeOfFifo-extra for non Rx ports")); -+ -+ memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc)); -+ -+ /* we do not change user's parameter */ -+ err = VerifySizeOfFifo(p_FmPort); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId, -+ &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, -+ 0); -+ -+ return p_FmPort->bufferOffsets.dataOffset; -+} -+ -+uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, -+ NULL); -+ -+ if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE) -+ return NULL; -+ -+ return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset); -+} -+ -+t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, -+ NULL); -+ -+ if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE) -+ return NULL; -+ -+ return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset); -+} -+ -+uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, -+ NULL); -+ -+ if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE) -+ return NULL; -+ -+ return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset); -+} -+ -+uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, -+ NULL); -+ -+ if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE) -+ return NULL; -+ -+ return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset); -+} -+ -+t_Error FM_PORT_Disable(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ int err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPort->imEn) -+ FmPortImDisable(p_FmPort); -+ -+ err = fman_port_disable(&p_FmPort->port); -+ if (err == -EBUSY) -+ { -+ DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down", -+ p_FmPort->name)); -+ } -+ else -+ if (err != 0) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable")); -+ } -+ -+ p_FmPort->enabled = FALSE; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_Enable(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ int err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ /* Used by FM_PORT_Free routine as indication -+ if to disable port. Thus set it to TRUE prior -+ to enabling itself. This way if part of enable -+ process fails there will be still things -+ to disable during Free. For example, if BMI -+ enable succeeded but QMI failed, still BMI -+ needs to be disabled by Free. */ -+ p_FmPort->enabled = TRUE; -+ -+ if (p_FmPort->imEn) -+ FmPortImEnable(p_FmPort); -+ -+ err = fman_port_enable(&p_FmPort->port); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable")); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ uint8_t factor, countUnitBit; -+ uint16_t baseGran; -+ struct fman_port_rate_limiter params; -+ int err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ baseGran = BMI_RATE_LIMIT_GRAN_TX; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ baseGran = BMI_RATE_LIMIT_GRAN_OP; -+ break; -+ default: -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Tx and Offline parsing ports only")); -+ } -+ -+ countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */ -+ /* normally, we use 1 usec as the reference count */ -+ factor = 1; -+ /* if ratelimit is too small for a 1usec factor, multiply the factor */ -+ while (p_RateLimit->rateLimit < baseGran / factor) -+ { -+ if (countUnitBit == 31) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small")); -+ -+ countUnitBit++; -+ factor <<= 1; -+ } -+ /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/ -+ if (p_RateLimit->rateLimit -+ > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large")); -+ -+ if (!p_RateLimit->maxBurstSize -+ || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE)); -+ -+ params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); -+ params.high_burst_size_gran = FALSE; -+ params.burst_size = p_RateLimit->maxBurstSize; -+ params.rate = p_RateLimit->rateLimit; -+ params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE; -+ -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ { -+#ifndef FM_NO_ADVANCED_RATE_LIMITER -+ -+ if ((p_FmPort->fmRevInfo.majorRev == 4) -+ || (p_FmPort->fmRevInfo.majorRev >= 6)) -+ { -+ params.high_burst_size_gran = TRUE; -+ } -+ else -+#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */ -+ { -+ if (p_RateLimit->rateLimitDivider -+ != e_FM_PORT_DUAL_RATE_LIMITER_NONE) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("FM_PORT_ConfigDualRateLimitScaleDown")); -+ -+ if (p_RateLimit->maxBurstSize % 1000) -+ { -+ p_RateLimit->maxBurstSize = -+ (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1); -+ DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000)); -+ } -+ else -+ p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize -+ / 1000); -+ } -+ params.rate_factor = -+ (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider; -+ params.burst_size = p_RateLimit->maxBurstSize; -+ } -+ -+ err = fman_port_set_rate_limiter(&p_FmPort->port, ¶ms); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter")); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ int err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Tx and Offline parsing ports only")); -+ -+ err = fman_port_delete_rate_limiter(&p_FmPort->port); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter")); -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, -+ uint8_t wq) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ uint32_t tmpReg; -+ uint32_t wqTmpReg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_TX) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("PFC mapping is available for Tx ports only")); -+ -+ if (prio > 7) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, -+ ("PFC priority (%d) is out of range (0-7)", prio)); -+ if (wq > 7) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, -+ ("WQ (%d) is out of range (0-7)", wq)); -+ -+ tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]); -+ tmpReg &= ~(0xf << ((7 - prio) * 4)); -+ wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4)); -+ tmpReg |= wqTmpReg; -+ -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0], -+ tmpReg); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ fman_port_set_queue_cnt_mode(&p_FmPort->port, enable); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ int err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode")); -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetPerformanceCountersParams( -+ t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ struct fman_port_perf_cnt_params params; -+ int err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ -+ /* check parameters */ -+ if (!p_FmPortPerformanceCnt->taskCompVal -+ || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num)); -+ if (!p_FmPortPerformanceCnt->dmaCompVal -+ || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num)); -+ if (!p_FmPortPerformanceCnt->fifoCompVal -+ || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num)); -+ if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS)); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ if (!p_FmPortPerformanceCnt->queueCompVal -+ || (p_FmPortPerformanceCnt->queueCompVal -+ > MAX_PERFORMANCE_RX_QUEUE_COMP)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP)); -+ break; -+ case (e_FM_PORT_TYPE_TX_10G): -+ case (e_FM_PORT_TYPE_TX): -+ if (!p_FmPortPerformanceCnt->queueCompVal -+ || (p_FmPortPerformanceCnt->queueCompVal -+ > MAX_PERFORMANCE_TX_QUEUE_COMP)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP)); -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ if (p_FmPortPerformanceCnt->queueCompVal) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("performanceCnt.queueCompVal is not relevant for H/O ports.")); -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ params.task_val = p_FmPortPerformanceCnt->taskCompVal; -+ params.queue_val = p_FmPortPerformanceCnt->queueCompVal; -+ params.dma_val = p_FmPortPerformanceCnt->dmaCompVal; -+ params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal; -+ -+ err = fman_port_set_perf_cnt_params(&p_FmPort->port, ¶ms); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params")); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_FmPortPerformanceCnt currParams, savedParams; -+ t_Error err; -+ bool underTest, failed = FALSE; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ -+ XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n", -+ p_FmPort->portType, p_FmPort->portId); -+ -+ currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num; -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) -+ currParams.queueCompVal = 0; -+ else -+ currParams.queueCompVal = 1; -+ currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num; -+ currParams.fifoCompVal = p_FmPort->fifoBufs.num; -+ -+ FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); -+ ClearPerfCnts(p_FmPort); -+ if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) -+ != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ FM_PORT_SetPerformanceCounters(p_FmPort, TRUE); -+ XX_UDelay(1000000); -+ FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); -+ if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL)) -+ { -+ XX_Print( -+ "Max num of defined port tasks (%d) utilized - Please enlarge\n", -+ p_FmPort->tasks.num); -+ failed = TRUE; -+ } -+ if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL)) -+ { -+ XX_Print( -+ "Max num of defined port openDmas (%d) utilized - Please enlarge\n", -+ p_FmPort->openDmas.num); -+ failed = TRUE; -+ } -+ if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL)) -+ { -+ XX_Print( -+ "Max size of defined port fifo (%d) utilized - Please enlarge\n", -+ p_FmPort->fifoBufs.num); -+ failed = TRUE; -+ } -+ if (failed) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ memset(&savedParams, 0, sizeof(savedParams)); -+ while (TRUE) -+ { -+ underTest = FALSE; -+ if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal) -+ { -+ currParams.taskCompVal--; -+ underTest = TRUE; -+ } -+ if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal) -+ { -+ currParams.dmaCompVal--; -+ underTest = TRUE; -+ } -+ if ((currParams.fifoCompVal != BMI_FIFO_UNITS) -+ && !savedParams.fifoCompVal) -+ { -+ currParams.fifoCompVal -= BMI_FIFO_UNITS; -+ underTest = TRUE; -+ } -+ if (!underTest) -+ break; -+ -+ ClearPerfCnts(p_FmPort); -+ if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams)) -+ != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ FM_PORT_SetPerformanceCounters(p_FmPort, TRUE); -+ XX_UDelay(1000000); -+ FM_PORT_SetPerformanceCounters(p_FmPort, FALSE); -+ -+ if (!savedParams.taskCompVal -+ && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL)) -+ savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2); -+ if (!savedParams.dmaCompVal -+ && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL)) -+ savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2); -+ if (!savedParams.fifoCompVal -+ && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL)) -+ savedParams.fifoCompVal = currParams.fifoCompVal -+ + (2 * BMI_FIFO_UNITS); -+ } -+ -+ XX_Print("best vals: tasks %d, dmas %d, fifos %d\n", -+ savedParams.taskCompVal, savedParams.dmaCompVal, -+ savedParams.fifoCompVal); -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ int err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode")); -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ volatile uint32_t *p_ErrDiscard = NULL; -+ int err; -+ -+ UNUSED(p_ErrDiscard); -+ err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask")); -+ -+#ifdef FM_ERROR_VSP_NO_MATCH_SW006 -+ if (p_FmPort->fmRevInfo.majorRev >= 6) -+ { -+ t_FmPcdCtrlParamsPage *p_ParamsPage; -+ -+ FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, -+ (void**)&p_ParamsPage); -+ ASSERT_COND(p_ParamsPage); -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_ErrDiscard = -+ &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_ErrDiscard = -+ &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm; -+ break; -+ default: -+ RETURN_ERROR( -+ MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ } -+ WRITE_UINT32(p_ParamsPage->errorsDiscardMask, -+ GET_UINT32(*p_ErrDiscard) | errs); -+ } -+#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */ -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, -+ bool enable) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ int err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(poolIdp_FmPortDriverParam, E_INVALID_STATE); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Rx ports only")); -+ -+ err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode")); -+ return E_OK; -+} -+ -+t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){ -+ p_BmiStats->cntCycle = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE); -+ /* fmbm_rccn */ -+ p_BmiStats->cntTaskUtil = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL); -+ /* fmbm_rtuc */ -+ p_BmiStats->cntQueueUtil = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL); -+ /* fmbm_rrquc */ -+ p_BmiStats->cntDmaUtil = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL); -+ /* fmbm_rduc */ -+ p_BmiStats->cntFifoUtil = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL); -+ /* fmbm_rfuc */ -+ p_BmiStats->cntRxPauseActivation = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION); -+ /* fmbm_rpac */ -+ p_BmiStats->cntFrame = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME); -+ /* fmbm_rfrc */ -+ p_BmiStats->cntDiscardFrame = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME); -+ /* fmbm_rfdc */ -+ p_BmiStats->cntDeallocBuf = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF); -+ /* fmbm_rbdc */ -+ p_BmiStats->cntRxBadFrame = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME); -+ /* fmbm_rfbc */ -+ p_BmiStats->cntRxLargeFrame = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME); -+ /* fmbm_rlfc */ -+ p_BmiStats->cntRxFilterFrame = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME); -+ /* fmbm_rffc */ -+ p_BmiStats->cntRxListDmaErr = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR); -+ /* fmbm_rfldec */ -+ p_BmiStats->cntRxOutOfBuffersDiscard = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD); -+ /* fmbm_rodc */ -+ p_BmiStats->cntWredDiscard = 0; -+ p_BmiStats->cntLengthErr = 0; -+ p_BmiStats->cntUnsupportedFormat = 0; -+ } -+ else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){ -+ p_BmiStats->cntCycle = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE); -+ /* fmbm_tccn */ -+ p_BmiStats->cntTaskUtil = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL); -+ /* fmbm_ttuc */ -+ p_BmiStats->cntQueueUtil = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL); -+ /* fmbm_ttcquc */ -+ p_BmiStats->cntDmaUtil = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL); -+ /* fmbm_tduc */ -+ p_BmiStats->cntFifoUtil = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL); -+ /* fmbm_tfuc */ -+ p_BmiStats->cntRxPauseActivation = 0; -+ p_BmiStats->cntFrame = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME); -+ /* fmbm_tfrc */ -+ p_BmiStats->cntDiscardFrame = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME); -+ /* fmbm_tfdc */ -+ p_BmiStats->cntDeallocBuf = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF); -+ /* fmbm_tbdc */ -+ p_BmiStats->cntRxBadFrame = 0; -+ p_BmiStats->cntRxLargeFrame = 0; -+ p_BmiStats->cntRxFilterFrame = 0; -+ p_BmiStats->cntRxListDmaErr = 0; -+ p_BmiStats->cntRxOutOfBuffersDiscard = 0; -+ p_BmiStats->cntWredDiscard = 0; -+ p_BmiStats->cntLengthErr = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR); -+ /* fmbm_tfledc */ -+ p_BmiStats->cntUnsupportedFormat = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT); -+ /* fmbm_tfufdc */ -+ } -+ else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) { -+ p_BmiStats->cntCycle = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE); -+ /* fmbm_occn */ -+ p_BmiStats->cntTaskUtil = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL); -+ /* fmbm_otuc */ -+ p_BmiStats->cntQueueUtil = 0; -+ p_BmiStats->cntDmaUtil = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL); -+ /* fmbm_oduc */ -+ p_BmiStats->cntFifoUtil = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL); -+ /* fmbm_ofuc*/ -+ p_BmiStats->cntRxPauseActivation = 0; -+ p_BmiStats->cntFrame = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME); -+ /* fmbm_ofrc */ -+ p_BmiStats->cntDiscardFrame = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME); -+ /* fmbm_ofdc */ -+ p_BmiStats->cntDeallocBuf = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF); -+ /* fmbm_obdc*/ -+ p_BmiStats->cntRxBadFrame = 0; -+ p_BmiStats->cntRxLargeFrame = 0; -+ p_BmiStats->cntRxFilterFrame = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME); -+ /* fmbm_offc */ -+ p_BmiStats->cntRxListDmaErr = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR); -+ /* fmbm_ofldec */ -+ p_BmiStats->cntRxOutOfBuffersDiscard = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD); -+ /* fmbm_rodc */ -+ p_BmiStats->cntWredDiscard = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD); -+ /* fmbm_ofwdc */ -+ p_BmiStats->cntLengthErr = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR); -+ /* fmbm_ofledc */ -+ p_BmiStats->cntUnsupportedFormat = -+ FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT); -+ /* fmbm_ofufdc */ -+ } -+ return E_OK; -+} -+ -+uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ bool bmiCounter = FALSE; -+ enum fman_port_stats_counters statsType; -+ enum fman_port_perf_counters perfType; -+ enum fman_port_qmi_counters queueType; -+ bool isStats; -+ t_Error errCode; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_DEQ_TOTAL): -+ case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): -+ case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): -+ /* check that counter is available for the port type */ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE, -+ ("Requested counter is not available for Rx ports")); -+ return 0; -+ } -+ bmiCounter = FALSE; -+ break; -+ case (e_FM_PORT_COUNTERS_ENQ_TOTAL): -+ bmiCounter = FALSE; -+ break; -+ default: /* BMI counters (or error - will be checked in BMI routine )*/ -+ bmiCounter = TRUE; -+ break; -+ } -+ -+ if (bmiCounter) -+ { -+ errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType, -+ &perfType, &isStats); -+ if (errCode != E_OK) -+ { -+ REPORT_ERROR(MINOR, errCode, NO_MSG); -+ return 0; -+ } -+ if (isStats) -+ return fman_port_get_stats_counter(&p_FmPort->port, statsType); -+ else -+ return fman_port_get_perf_counter(&p_FmPort->port, perfType); -+ } -+ else /* QMI counter */ -+ { -+ /* check that counters are enabled */ -+ if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc) -+ & QMI_PORT_CFG_EN_COUNTERS)) -+ -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled")); -+ return 0; -+ } -+ -+ /* Set counter */ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_ENQ_TOTAL): -+ queueType = E_FMAN_PORT_ENQ_TOTAL; -+ break; -+ case (e_FM_PORT_COUNTERS_DEQ_TOTAL): -+ queueType = E_FMAN_PORT_DEQ_TOTAL; -+ break; -+ case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): -+ queueType = E_FMAN_PORT_DEQ_FROM_DFLT; -+ break; -+ case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): -+ queueType = E_FMAN_PORT_DEQ_CONFIRM; -+ break; -+ default: -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available")); -+ return 0; -+ } -+ -+ return fman_port_get_qmi_counter(&p_FmPort->port, queueType); -+ } -+ -+ return 0; -+} -+ -+t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter, -+ uint32_t value) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ bool bmiCounter = FALSE; -+ enum fman_port_stats_counters statsType; -+ enum fman_port_perf_counters perfType; -+ enum fman_port_qmi_counters queueType; -+ bool isStats; -+ t_Error errCode; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_DEQ_TOTAL): -+ case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): -+ case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): -+ /* check that counter is available for the port type */ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) -+ || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ RETURN_ERROR( -+ MINOR, E_INVALID_STATE, -+ ("Requested counter is not available for Rx ports")); -+ case (e_FM_PORT_COUNTERS_ENQ_TOTAL): -+ bmiCounter = FALSE; -+ break; -+ default: /* BMI counters (or error - will be checked in BMI routine )*/ -+ bmiCounter = TRUE; -+ break; -+ } -+ -+ if (bmiCounter) -+ { -+ errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType, -+ &perfType, &isStats); -+ if (errCode != E_OK) -+ { -+ RETURN_ERROR(MINOR, errCode, NO_MSG); -+ } -+ if (isStats) -+ fman_port_set_stats_counter(&p_FmPort->port, statsType, value); -+ else -+ fman_port_set_perf_counter(&p_FmPort->port, perfType, value); -+ } -+ else /* QMI counter */ -+ { -+ /* check that counters are enabled */ -+ if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc) -+ & QMI_PORT_CFG_EN_COUNTERS)) -+ { -+ RETURN_ERROR(MINOR, E_INVALID_STATE, -+ ("Requested counter was not enabled")); -+ } -+ -+ /* Set counter */ -+ switch (counter) -+ { -+ case (e_FM_PORT_COUNTERS_ENQ_TOTAL): -+ queueType = E_FMAN_PORT_ENQ_TOTAL; -+ break; -+ case (e_FM_PORT_COUNTERS_DEQ_TOTAL): -+ queueType = E_FMAN_PORT_DEQ_TOTAL; -+ break; -+ case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT): -+ queueType = E_FMAN_PORT_DEQ_FROM_DFLT; -+ break; -+ case (e_FM_PORT_COUNTERS_DEQ_CONFIRM): -+ queueType = E_FMAN_PORT_DEQ_CONFIRM; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Requested counter is not available")); -+ } -+ -+ fman_port_set_qmi_counter(&p_FmPort->port, queueType, value); -+ } -+ -+ return E_OK; -+} -+ -+uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) -+ && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports")); -+ return 0; -+ } -+ return fman_port_get_bpool_counter(&p_FmPort->port, poolId); -+} -+ -+t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, -+ uint32_t value) -+{ -+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) -+ && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ RETURN_ERROR( MINOR, E_INVALID_STATE, -+ ("Requested counter is not available for non-Rx ports")); -+ -+ fman_port_set_bpool_counter(&p_FmPort->port, poolId, value); -+ return E_OK; -+} -+bool FM_PORT_IsStalled(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err; -+ bool isStalled; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE); -+ SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE, -+ FALSE); -+ -+ err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled); -+ if (err != E_OK) -+ { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return TRUE; -+ } -+ return isStalled; -+} -+ -+t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId); -+} -+ -+t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ int err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for Rx ports only")); -+ -+ if (l4Checksum) -+ err = fman_port_modify_rx_fd_bits( -+ &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24), -+ TRUE); -+ else -+ err = fman_port_modify_rx_fd_bits( -+ &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24), -+ FALSE); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits")); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+/* API Run-time PCD Control unit functions */ -+/*****************************************************************************/ -+ -+#if (DPAA_VERSION >= 11) -+t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err = E_OK; -+ volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL; -+ uint32_t tmpReg = 0, tmp = 0; -+ uint16_t hwStoragePrflId; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE); -+ /*for numOfProfiles = 0 don't call this function*/ -+ SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE); -+ /*dfltRelativeId should be in the range of numOfProfiles*/ -+ SANITY_CHECK_RETURN_ERROR( -+ p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles, -+ E_INVALID_VALUE); -+ /*p_FmPort should be from Rx type or OP*/ -+ SANITY_CHECK_RETURN_ERROR( -+ ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)), -+ E_INVALID_VALUE); -+ /*port should be disabled*/ -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE); -+ /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/ -+ SANITY_CHECK_RETURN_ERROR( -+ ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)), -+ E_INVALID_VALUE); -+ /*should be called before SetPCD - this port should be without PCD*/ -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE); -+ -+ /*alloc window of VSPs for this port*/ -+ err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType, -+ p_FmPort->portId, p_VSPParams->numOfProfiles); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ /*get absolute VSP ID for dfltRelative*/ -+ err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType, -+ p_FmPort->portId, -+ p_VSPParams->dfltRelativeId, -+ &hwStoragePrflId); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiStorageProfileId = -+ &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid); -+ p_BmiVspe = -+ &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne); -+ -+ tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK; -+ tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT; -+ WRITE_UINT32(*p_BmiStorageProfileId, tmpReg); -+ -+ tmpReg = GET_UINT32(*p_BmiVspe); -+ WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN); -+ -+ p_BmiStorageProfileId = -+ &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid; -+ p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp; -+ hwStoragePrflId = p_VSPParams->dfltRelativeId; -+ break; -+ -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME; -+ WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn, -+ tmpReg); -+ -+ p_BmiStorageProfileId = -+ &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid; -+ p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp; -+ tmp |= BMI_EBD_EN; -+ break; -+ -+ default: -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ } -+ -+ p_FmPort->vspe = TRUE; -+ p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId; -+ -+ tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK; -+ tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT; -+ WRITE_UINT32(*p_BmiStorageProfileId, tmpReg); -+ -+ tmpReg = GET_UINT32(*p_BmiVspe); -+ WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp); -+ return E_OK; -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err = E_OK; -+ -+ p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm); -+ ASSERT_COND(p_FmPort->h_FmPcd); -+ -+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ if (numOfProfiles) -+ { -+ err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd, -+ p_FmPort->hardwarePortId, numOfProfiles); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ /* set the port handle within the PCD policer, even if no profiles defined */ -+ FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId); -+ -+ RELEASE_LOCK(p_FmPort->lock); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err = E_OK; -+ -+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId); -+ -+ RELEASE_LOCK(p_FmPort->lock); -+ -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort, -+ t_FmPcdKgSchemeSelect *p_FmPcdKgScheme) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ volatile uint32_t *p_BmiHpnia = NULL; -+ uint32_t tmpReg; -+ uint8_t relativeSchemeId; -+ uint8_t physicalSchemeId; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG, -+ E_INVALID_STATE); -+ -+ tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0); -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne; -+ break; -+ default: -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ } -+ -+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ /* if we want to change to direct scheme, we need to check that this scheme is valid */ -+ if (p_FmPcdKgScheme->direct) -+ { -+ physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme); -+ /* check that this scheme is bound to this port */ -+ if (!(p_FmPort->schemesPerPortVector -+ & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId)))) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR( -+ MAJOR, E_INVALID_STATE, -+ ("called with a scheme that is not bound to this port")); -+ } -+ -+ relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd, -+ physicalSchemeId); -+ if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, -+ ("called with invalid Scheme ")); -+ } -+ -+ if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme)) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("called with uninitialized Scheme ")); -+ } -+ -+ WRITE_UINT32( -+ *p_BmiHpnia, -+ NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId); -+ } -+ else -+ /* change to indirect scheme */ -+ WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg); -+ RELEASE_LOCK(p_FmPort->lock); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort, -+ t_Handle h_Profile) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ volatile uint32_t *p_BmiNia; -+ volatile uint32_t *p_BmiHpnia; -+ uint32_t tmpReg; -+ uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile); -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR, -+ E_INVALID_STATE); -+ -+ /* check relevance of this routine - only when policer is used -+ directly after BMI or Parser */ -+ if ((p_FmPort->pcdEngines & FM_PCD_KG) -+ || (p_FmPort->pcdEngines & FM_PCD_CC)) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR")); -+ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; -+ p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne; -+ tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; -+ p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne; -+ tmpReg = 0; -+ break; -+ default: -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ } -+ -+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId)) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile")); -+ } -+ -+ tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId); -+ -+ if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */ -+ { -+ /* update BMI HPNIA */ -+ WRITE_UINT32(*p_BmiHpnia, tmpReg); -+ } -+ else /* e_FM_PCD_SUPPORT_PLCR_ONLY */ -+ { -+ /* rfne may contain FDCS bits, so first we read them. */ -+ tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK); -+ /* update BMI NIA */ -+ WRITE_UINT32(*p_BmiNia, tmpReg); -+ }RELEASE_LOCK(p_FmPort->lock); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err = E_OK; -+ volatile uint32_t *p_BmiCcBase = NULL; -+ volatile uint32_t *p_BmiNia = NULL; -+ uint32_t ccTreePhysOffset; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE); -+ -+ if (p_FmPort->imEn) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for non-independent mode ports only")); -+ -+ /* get PCD registers pointers */ -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne; -+ break; -+ default: -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ } -+ -+ /* check that current NIA is BMI to BMI */ -+ if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK) -+ != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd)) -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("may be called only for ports in BMI-to-BMI state.")); -+ -+ if (p_FmPort->pcdEngines & FM_PCD_CC) -+ { -+ if (p_FmPort->h_IpReassemblyManip) -+ { -+ err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL, -+ p_FmPort->h_IpReassemblyManip, FALSE); -+ if (err != E_OK) -+ { -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ else -+ if (p_FmPort->h_CapwapReassemblyManip) -+ { -+ err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL, -+ p_FmPort->h_CapwapReassemblyManip, -+ FALSE); -+ if (err != E_OK) -+ { -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ switch (p_FmPort->portType) -+ { -+ case (e_FM_PORT_TYPE_RX_10G): -+ case (e_FM_PORT_TYPE_RX): -+ p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb; -+ break; -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb; -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type")); -+ } -+ -+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree, -+ &ccTreePhysOffset, h_FmPort); -+ if (err) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset); -+ -+ p_FmPort->ccTreeId = h_CcTree; -+ RELEASE_LOCK(p_FmPort->lock); -+ } -+ else -+ RETURN_ERROR( MAJOR, E_INVALID_STATE, -+ ("Coarse Classification not defined for this port.")); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_AttachPCD(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPort->imEn) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for non-independent mode ports only")); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ -+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ if (p_FmPort->h_ReassemblyTree) -+ p_FmPort->pcdEngines |= FM_PCD_CC; -+ -+ err = AttachPCD(h_FmPort); -+ RELEASE_LOCK(p_FmPort->lock); -+ -+ return err; -+} -+ -+t_Error FM_PORT_DetachPCD(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPort->imEn) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for non-independent mode ports only")); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ -+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = DetachPCD(h_FmPort); -+ if (err != E_OK) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ if (p_FmPort->h_ReassemblyTree) -+ p_FmPort->pcdEngines &= ~FM_PCD_CC; -+ RELEASE_LOCK(p_FmPort->lock); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err = E_OK; -+ t_FmPortPcdParams modifiedPcdParams, *p_PcdParams; -+ t_FmPcdCcTreeParams *p_FmPcdCcTreeParams; -+ t_FmPortPcdCcParams fmPortPcdCcParams; -+ t_FmPortGetSetCcParams fmPortGetSetCcParams; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPort->imEn) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for non-independent mode ports only")); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ -+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm); -+ ASSERT_COND(p_FmPort->h_FmPcd); -+ -+ if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, -+ ("Tree handle must be given if CC is required")); -+ -+ memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams)); -+ p_PcdParams = &modifiedPcdParams; -+ if ((p_PcdParams->h_IpReassemblyManip) -+#if (DPAA_VERSION >= 11) -+ || (p_PcdParams->h_CapwapReassemblyManip) -+#endif /* (DPAA_VERSION >= 11) */ -+ ) -+ { -+ if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG) -+ && (p_PcdParams->pcdSupport -+ != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC) -+ && (p_PcdParams->pcdSupport -+ != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR) -+ && (p_PcdParams->pcdSupport -+ != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR( MAJOR, E_INVALID_STATE, -+ ("pcdSupport must have KG for supporting Reassembly")); -+ } -+ p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip; -+#if (DPAA_VERSION >= 11) -+ if ((p_PcdParams->h_IpReassemblyManip) -+ && (p_PcdParams->h_CapwapReassemblyManip)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("Either IP-R or CAPWAP-R is allowed")); -+ if ((p_PcdParams->h_CapwapReassemblyManip) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("CAPWAP-R is allowed only on offline-port")); -+ if (p_PcdParams->h_CapwapReassemblyManip) -+ p_FmPort->h_CapwapReassemblyManip = -+ p_PcdParams->h_CapwapReassemblyManip; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ if (!p_PcdParams->p_CcParams) -+ { -+ if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG) -+ || (p_PcdParams->pcdSupport -+ == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_STATE, -+ ("PCD initialization structure is not consistent with pcdSupport")); -+ } -+ -+ /* No user-tree, need to build internal tree */ -+ p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc( -+ sizeof(t_FmPcdCcTreeParams)); -+ if (!p_FmPcdCcTreeParams) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams")); -+ memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams)); -+ p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv; -+ p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild( -+ p_FmPort->h_FmPcd, p_FmPcdCcTreeParams); -+ -+ if (!p_FmPort->h_ReassemblyTree) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ XX_Free(p_FmPcdCcTreeParams); -+ RETURN_ERROR( MAJOR, E_INVALID_HANDLE, -+ ("FM_PCD_CcBuildTree for Reassembly failed")); -+ } -+ if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG) -+ p_PcdParams->pcdSupport = -+ e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC; -+ else -+ p_PcdParams->pcdSupport = -+ e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR; -+ -+ memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams)); -+ fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree; -+ p_PcdParams->p_CcParams = &fmPortPcdCcParams; -+ XX_Free(p_FmPcdCcTreeParams); -+ } -+ -+ if (p_FmPort->h_IpReassemblyManip) -+ err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, -+ p_PcdParams->p_CcParams->h_CcTree, -+ p_PcdParams->h_NetEnv, -+ p_FmPort->h_IpReassemblyManip, TRUE); -+#if (DPAA_VERSION >= 11) -+ else -+ if (p_FmPort->h_CapwapReassemblyManip) -+ err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, -+ p_PcdParams->p_CcParams->h_CcTree, -+ p_PcdParams->h_NetEnv, -+ p_FmPort->h_CapwapReassemblyManip, -+ TRUE); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ if (err != E_OK) -+ { -+ if (p_FmPort->h_ReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); -+ p_FmPort->h_ReassemblyTree = NULL; -+ }RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ -+ if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd)) -+ { -+ if (p_FmPort->h_ReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); -+ p_FmPort->h_ReassemblyTree = NULL; -+ }RELEASE_LOCK(p_FmPort->lock); -+ DBG(TRACE, ("Try LockAll - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = SetPcd(h_FmPort, p_PcdParams); -+ if (err) -+ { -+ if (p_FmPort->h_ReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); -+ p_FmPort->h_ReassemblyTree = NULL; -+ } -+ FmPcdLockUnlockAll(p_FmPort->h_FmPcd); -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ if ((p_FmPort->pcdEngines & FM_PCD_PRS) -+ && (p_PcdParams->p_PrsParams->includeInPrsStatistics)) -+ { -+ err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, -+ p_FmPort->hardwarePortId, TRUE); -+ if (err) -+ { -+ DeletePcd(p_FmPort); -+ if (p_FmPort->h_ReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); -+ p_FmPort->h_ReassemblyTree = NULL; -+ } -+ FmPcdLockUnlockAll(p_FmPort->h_FmPcd); -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ p_FmPort->includeInPrsStatistics = TRUE; -+ } -+ -+ FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId); -+ -+ if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) -+ { -+ memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); -+ -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ { -+#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 -+ if ((p_FmPort->fmRevInfo.majorRev < 6) && -+ (p_FmPort->pcdEngines & FM_PCD_KG)) -+ { -+ int i; -+ for (i = 0; ip_KgParams->numOfSchemes; i++) -+ /* The following function must be locked */ -+ FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, -+ p_PcdParams->p_KgParams->h_Schemes[i], -+ UPDATE_KG_NIA_CC_WA, -+ 0); -+ } -+#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */ -+ -+#if (DPAA_VERSION >= 11) -+ { -+ t_FmPcdCtrlParamsPage *p_ParamsPage; -+ -+ FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, -+ (void**)&p_ParamsPage); -+ ASSERT_COND(p_ParamsPage); -+ WRITE_UINT32(p_ParamsPage->postBmiFetchNia, -+ p_FmPort->savedBmiNia); -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ /* Set post-bmi-fetch nia */ -+ p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK; -+ p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH -+ | NIA_ENG_FM_CTL); -+ -+ /* Set pre-bmi-fetch nia */ -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN; -+#if (DPAA_VERSION >= 11) -+ fmPortGetSetCcParams.setCcParams.nia = -+ (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL); -+#else -+ fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL); -+#endif /* (DPAA_VERSION >= 11) */ -+ if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams)) -+ != E_OK) -+ { -+ DeletePcd(p_FmPort); -+ if (p_FmPort->h_ReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); -+ p_FmPort->h_ReassemblyTree = NULL; -+ } -+ FmPcdLockUnlockAll(p_FmPort->h_FmPcd); -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ -+ FmPcdLockUnlockAll(p_FmPort->h_FmPcd); -+ -+ /* Set pop-to-next-step nia */ -+#if (DPAA_VERSION == 10) -+ if (p_FmPort->fmRevInfo.majorRev < 6) -+ { -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN; -+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL; -+ } -+ else -+ { -+#endif /* (DPAA_VERSION == 10) */ -+ fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE; -+#if (DPAA_VERSION == 10) -+ } -+#endif /* (DPAA_VERSION == 10) */ -+ if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) -+ != E_OK) -+ { -+ DeletePcd(p_FmPort); -+ if (p_FmPort->h_ReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); -+ p_FmPort->h_ReassemblyTree = NULL; -+ }RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ /* Set post-bmi-prepare-to-enq nia */ -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE; -+ fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ -+ | NIA_ENG_FM_CTL); -+ if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) -+ != E_OK) -+ { -+ DeletePcd(p_FmPort); -+ if (p_FmPort->h_ReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); -+ p_FmPort->h_ReassemblyTree = NULL; -+ }RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ if ((p_FmPort->h_IpReassemblyManip) -+ || (p_FmPort->h_CapwapReassemblyManip)) -+ { -+#if (DPAA_VERSION == 10) -+ if (p_FmPort->fmRevInfo.majorRev < 6) -+ { -+ /* Overwrite post-bmi-prepare-to-enq nia */ -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE; -+ fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR); -+ fmPortGetSetCcParams.setCcParams.overwrite = TRUE; -+ } -+ else -+ { -+#endif /* (DPAA_VERSION == 10) */ -+ /* Set the ORR bit (for order-restoration) */ -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE; -+ fmPortGetSetCcParams.setCcParams.nia = -+ fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR; -+#if (DPAA_VERSION == 10) -+ } -+#endif /* (DPAA_VERSION == 10) */ -+ if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) -+ != E_OK) -+ { -+ DeletePcd(p_FmPort); -+ if (p_FmPort->h_ReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); -+ p_FmPort->h_ReassemblyTree = NULL; -+ }RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ } -+ } -+ else -+ FmPcdLockUnlockAll(p_FmPort->h_FmPcd); -+ -+#if (DPAA_VERSION >= 11) -+ { -+ t_FmPcdCtrlParamsPage *p_ParamsPage; -+ -+ memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams)); -+ -+ fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE; -+ if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) -+ fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP -+ | NIA_ENG_FM_CTL; -+ else -+ fmPortGetSetCcParams.setCcParams.nia = -+ NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL; -+ if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) -+ != E_OK) -+ { -+ DeletePcd(p_FmPort); -+ if (p_FmPort->h_ReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); -+ p_FmPort->h_ReassemblyTree = NULL; -+ }RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE, -+ (void**)&p_ParamsPage); -+ ASSERT_COND(p_ParamsPage); -+ -+ if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) -+ WRITE_UINT32( -+ p_ParamsPage->misc, -+ GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN); -+ -+ if ((p_FmPort->h_IpReassemblyManip) -+ || (p_FmPort->h_CapwapReassemblyManip)) -+ { -+ if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ WRITE_UINT32( -+ p_ParamsPage->discardMask, -+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm)); -+ else -+ WRITE_UINT32( -+ p_ParamsPage->discardMask, -+ GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm)); -+ } -+#ifdef FM_ERROR_VSP_NO_MATCH_SW006 -+ if (p_FmPort->vspe) -+ WRITE_UINT32( -+ p_ParamsPage->misc, -+ GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK)); -+#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */ -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ err = AttachPCD(h_FmPort); -+ if (err) -+ { -+ DeletePcd(p_FmPort); -+ if (p_FmPort->h_ReassemblyTree) -+ { -+ FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); -+ p_FmPort->h_ReassemblyTree = NULL; -+ }RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ RELEASE_LOCK(p_FmPort->lock); -+ -+ return err; -+} -+ -+t_Error FM_PORT_DeletePCD(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ -+ if (p_FmPort->imEn) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, -+ ("available for non-independant mode ports only")); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ RETURN_ERROR( MAJOR, E_INVALID_OPERATION, -+ ("available for Rx and offline parsing ports only")); -+ -+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = DetachPCD(h_FmPort); -+ if (err) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId); -+ -+ /* we do it anyway, instead of checking if included */ -+ if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics) -+ { -+ FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd, -+ p_FmPort->hardwarePortId, FALSE); -+ p_FmPort->includeInPrsStatistics = FALSE; -+ } -+ -+ if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd)) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ DBG(TRACE, ("Try LockAll - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = DeletePcd(h_FmPort); -+ FmPcdLockUnlockAll(p_FmPort->h_FmPcd); -+ if (err) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ if (p_FmPort->h_ReassemblyTree) -+ { -+ err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree); -+ if (err) -+ { -+ RELEASE_LOCK(p_FmPort->lock); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ p_FmPort->h_ReassemblyTree = NULL; -+ }RELEASE_LOCK(p_FmPort->lock); -+ -+ return err; -+} -+ -+t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort, -+ t_FmPcdPortSchemesParams *p_PortScheme) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_FmPcdKgInterModuleBindPortToSchemes schemeBind; -+ t_Error err = E_OK; -+ uint32_t tmpScmVec = 0; -+ int i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG, -+ E_INVALID_STATE); -+ -+ schemeBind.netEnvId = p_FmPort->netEnvId; -+ schemeBind.hardwarePortId = p_FmPort->hardwarePortId; -+ schemeBind.numOfSchemes = p_PortScheme->numOfSchemes; -+ schemeBind.useClsPlan = p_FmPort->useClsPlan; -+ for (i = 0; i < schemeBind.numOfSchemes; i++) -+ { -+ schemeBind.schemesIds[i] = FmPcdKgGetSchemeId( -+ p_PortScheme->h_Schemes[i]); -+ /* build vector */ -+ tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]); -+ } -+ -+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); -+ if (err == E_OK) -+ p_FmPort->schemesPerPortVector |= tmpScmVec; -+ -+#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 -+ if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) && -+ (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) && -+ (p_FmPort->fmRevInfo.majorRev < 6)) -+ { -+ for (i=0; inumOfSchemes; i++) -+ FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0); -+ } -+#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */ -+ -+ RELEASE_LOCK(p_FmPort->lock); -+ -+ return err; -+} -+ -+t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort, -+ t_FmPcdPortSchemesParams *p_PortScheme) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_FmPcdKgInterModuleBindPortToSchemes schemeBind; -+ t_Error err = E_OK; -+ uint32_t tmpScmVec = 0; -+ int i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG, -+ E_INVALID_STATE); -+ -+ schemeBind.netEnvId = p_FmPort->netEnvId; -+ schemeBind.hardwarePortId = p_FmPort->hardwarePortId; -+ schemeBind.numOfSchemes = p_PortScheme->numOfSchemes; -+ for (i = 0; i < schemeBind.numOfSchemes; i++) -+ { -+ schemeBind.schemesIds[i] = FmPcdKgGetSchemeId( -+ p_PortScheme->h_Schemes[i]); -+ /* build vector */ -+ tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]); -+ } -+ -+ if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock)) -+ { -+ DBG(TRACE, ("FM Port Try Lock - BUSY")); -+ return ERROR_CODE(E_BUSY); -+ } -+ -+ err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind); -+ if (err == E_OK) -+ p_FmPort->schemesPerPortVector &= ~tmpScmVec; -+ RELEASE_LOCK(p_FmPort->lock); -+ -+ return err; -+} -+ -+t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, -+ t_FmPortCongestionGrps *p_CongestionGrps) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS]; -+ uint8_t mod, index; -+ uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM]; -+ int err; -+#if (DPAA_VERSION >= 11) -+ int j; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ -+ /* un-necessary check of the indexes; probably will be needed in the future when there -+ will be more CGs available .... -+ for (i=0; inumOfCongestionGrpsToConsider; i++) -+ if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!")); -+ */ -+ -+#ifdef FM_NO_OP_OBSERVED_CGS -+ if ((p_FmPort->fmRevInfo.majorRev != 4) && -+ (p_FmPort->fmRevInfo.majorRev < 6)) -+ { -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && -+ (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only")); -+ } -+ else -+#endif /* FM_NO_OP_OBSERVED_CGS */ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("Available for Rx & OP ports only")); -+ -+ /* Prepare groups map array */ -+ memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t)); -+ for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) -+ { -+ index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32); -+ mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32); -+ if (p_FmPort->fmRevInfo.majorRev != 4) -+ grpsMap[7 - index] |= (uint32_t)(1 << mod); -+ else -+ grpsMap[0] |= (uint32_t)(1 << mod); -+ } -+ -+ memset(&priorityTmpArray, 0, -+ FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t)); -+ -+ for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) -+ { -+#if (DPAA_VERSION >= 11) -+ for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++) -+ if (p_CongestionGrps->pfcPrioritiesEn[i][j]) -+ priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |= -+ (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1)); -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+#if (DPAA_VERSION >= 11) -+ for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++) -+ { -+ err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i, -+ priorityTmpArray[i]); -+ if (err) -+ return err; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps")); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, -+ t_FmPortCongestionGrps *p_CongestionGrps) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ uint8_t mod, index; -+ uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM]; -+ int err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ -+ { -+#ifdef FM_NO_OP_OBSERVED_CGS -+ t_FmRevisionInfo revInfo; -+ -+ FM_GetRevision(p_FmPort->h_Fm, &revInfo); -+ if (revInfo.majorRev != 4) -+ { -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && -+ (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only")); -+ } -+ else -+#endif /* FM_NO_OP_OBSERVED_CGS */ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_RX) -+ && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("Available for Rx & OP ports only")); -+ } -+ -+ /* Prepare groups map array */ -+ memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t)); -+ for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) -+ { -+ index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32); -+ mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32); -+ if (p_FmPort->fmRevInfo.majorRev != 4) -+ grpsMap[7 - index] |= (uint32_t)(1 << mod); -+ else -+ grpsMap[0] |= (uint32_t)(1 << mod); -+ } -+ -+#if (DPAA_VERSION >= 11) -+ for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++) -+ { -+ t_Error err = FmSetCongestionGroupPFCpriority( -+ p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i], -+ 0); -+ if (err) -+ return err; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap); -+ if (err != 0) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("fman_port_remove_congestion_grps")); -+ return E_OK; -+} -+ -+#if (DPAA_VERSION >= 11) -+t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, -+ uint32_t *p_Ipv4OptionsCount) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR( -+ (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING), -+ E_INVALID_VALUE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER); -+ -+ *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter); -+ -+ return E_OK; -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, -+ t_FmPortDsarTablesSizes *params) -+{ -+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; -+ p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc( -+ sizeof(struct t_FmPortDsarTablesSizes)); -+ memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params, -+ sizeof(struct t_FmPortDsarTablesSizes)); -+ return E_OK; -+} -+ -+static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort) -+{ -+ uint32_t *param_page; -+ t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes; -+ t_ArCommonDesc *ArCommonDescPtr; -+ uint32_t size = sizeof(t_ArCommonDesc); -+ // ARP -+ // should put here if (params->max_num_of_arp_entries)? -+ size = ROUND_UP(size,4); -+ size += sizeof(t_DsarArpDescriptor); -+ size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries; -+ size += sizeof(t_DsarArpStatistics); -+ //ICMPV4 -+ size = ROUND_UP(size,4); -+ size += sizeof(t_DsarIcmpV4Descriptor); -+ size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries; -+ size += sizeof(t_DsarIcmpV4Statistics); -+ //ICMPV6 -+ size = ROUND_UP(size,4); -+ size += sizeof(t_DsarIcmpV6Descriptor); -+ size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries; -+ size += sizeof(t_DsarIcmpV6Statistics); -+ //ND -+ size = ROUND_UP(size,4); -+ size += sizeof(t_DsarNdDescriptor); -+ size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries; -+ size += sizeof(t_DsarIcmpV6Statistics); -+ //SNMP -+ size = ROUND_UP(size,4); -+ size += sizeof(t_DsarSnmpDescriptor); -+ size += sizeof(t_DsarSnmpIpv4AddrTblEntry) -+ * params->maxNumOfSnmpIPV4Entries; -+ size += sizeof(t_DsarSnmpIpv6AddrTblEntry) -+ * params->maxNumOfSnmpIPV6Entries; -+ size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries; -+ size += params->maxNumOfSnmpOidChar; -+ size += sizeof(t_DsarIcmpV6Statistics); -+ //filters -+ size = ROUND_UP(size,4); -+ size += params->maxNumOfIpProtFiltering; -+ size = ROUND_UP(size,4); -+ size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry); -+ size = ROUND_UP(size,4); -+ size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry); -+ -+ // add here for more protocols -+ -+ // statistics -+ size = ROUND_UP(size,4); -+ size += sizeof(t_ArStatistics); -+ -+ ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10); -+ -+ param_page = -+ XX_PhysToVirt( -+ p_FmPort->fmMuramPhysBaseAddr -+ + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr)); -+ WRITE_UINT32( -+ *param_page, -+ (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr)); -+ return E_OK; -+} -+ -+t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx) -+{ -+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; -+ return p_FmPort->deepSleepVars.autoResMaxSizes; -+} -+ -+struct arOffsets -+{ -+ uint32_t arp; -+ uint32_t nd; -+ uint32_t icmpv4; -+ uint32_t icmpv6; -+ uint32_t snmp; -+ uint32_t stats; -+ uint32_t filtIp; -+ uint32_t filtUdp; -+ uint32_t filtTcp; -+}; -+ -+static uint32_t AR_ComputeOffsets(struct arOffsets* of, -+ struct t_FmPortDsarParams *params, -+ t_FmPort *p_FmPort) -+{ -+ uint32_t size = sizeof(t_ArCommonDesc); -+ // ARP -+ if (params->p_AutoResArpInfo) -+ { -+ size = ROUND_UP(size,4); -+ of->arp = size; -+ size += sizeof(t_DsarArpDescriptor); -+ size += sizeof(t_DsarArpBindingEntry) -+ * params->p_AutoResArpInfo->tableSize; -+ size += sizeof(t_DsarArpStatistics); -+ } -+ // ICMPV4 -+ if (params->p_AutoResEchoIpv4Info) -+ { -+ size = ROUND_UP(size,4); -+ of->icmpv4 = size; -+ size += sizeof(t_DsarIcmpV4Descriptor); -+ size += sizeof(t_DsarIcmpV4BindingEntry) -+ * params->p_AutoResEchoIpv4Info->tableSize; -+ size += sizeof(t_DsarIcmpV4Statistics); -+ } -+ // ICMPV6 -+ if (params->p_AutoResEchoIpv6Info) -+ { -+ size = ROUND_UP(size,4); -+ of->icmpv6 = size; -+ size += sizeof(t_DsarIcmpV6Descriptor); -+ size += sizeof(t_DsarIcmpV6BindingEntry) -+ * params->p_AutoResEchoIpv6Info->tableSize; -+ size += sizeof(t_DsarIcmpV6Statistics); -+ } -+ // ND -+ if (params->p_AutoResNdpInfo) -+ { -+ size = ROUND_UP(size,4); -+ of->nd = size; -+ size += sizeof(t_DsarNdDescriptor); -+ size += sizeof(t_DsarIcmpV6BindingEntry) -+ * (params->p_AutoResNdpInfo->tableSizeAssigned -+ + params->p_AutoResNdpInfo->tableSizeTmp); -+ size += sizeof(t_DsarIcmpV6Statistics); -+ } -+ // SNMP -+ if (params->p_AutoResSnmpInfo) -+ { -+ size = ROUND_UP(size,4); -+ of->snmp = size; -+ size += sizeof(t_DsarSnmpDescriptor); -+ size += sizeof(t_DsarSnmpIpv4AddrTblEntry) -+ * params->p_AutoResSnmpInfo->numOfIpv4Addresses; -+ size += sizeof(t_DsarSnmpIpv6AddrTblEntry) -+ * params->p_AutoResSnmpInfo->numOfIpv6Addresses; -+ size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize; -+ size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar; -+ size += sizeof(t_DsarIcmpV6Statistics); -+ } -+ //filters -+ size = ROUND_UP(size,4); -+ if (params->p_AutoResFilteringInfo) -+ { -+ of->filtIp = size; -+ size += params->p_AutoResFilteringInfo->ipProtTableSize; -+ size = ROUND_UP(size,4); -+ of->filtUdp = size; -+ size += params->p_AutoResFilteringInfo->udpPortsTableSize -+ * sizeof(t_PortTblEntry); -+ size = ROUND_UP(size,4); -+ of->filtTcp = size; -+ size += params->p_AutoResFilteringInfo->tcpPortsTableSize -+ * sizeof(t_PortTblEntry); -+ } -+ // add here for more protocols -+ // statistics -+ size = ROUND_UP(size,4); -+ of->stats = size; -+ size += sizeof(t_ArStatistics); -+ return size; -+} -+ -+uint32_t* ARDesc; -+void PrsEnable(t_Handle p_FmPcd); -+void PrsDisable(t_Handle p_FmPcd); -+int PrsIsEnabled(t_Handle p_FmPcd); -+t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd); -+ -+static t_Error DsarCheckParams(t_FmPortDsarParams *params, -+ t_FmPortDsarTablesSizes *sizes) -+{ -+ bool macInit = FALSE; -+ uint8_t mac[6]; -+ int i = 0; -+ -+ // check table sizes -+ if (params->p_AutoResArpInfo -+ && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("DSAR: Arp table size exceeds the configured maximum size.")); -+ if (params->p_AutoResEchoIpv4Info -+ && sizes->maxNumOfEchoIpv4Entries -+ < params->p_AutoResEchoIpv4Info->tableSize) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("DSAR: EchoIpv4 table size exceeds the configured maximum size.")); -+ if (params->p_AutoResNdpInfo -+ && sizes->maxNumOfNdpEntries -+ < params->p_AutoResNdpInfo->tableSizeAssigned -+ + params->p_AutoResNdpInfo->tableSizeTmp) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("DSAR: NDP table size exceeds the configured maximum size.")); -+ if (params->p_AutoResEchoIpv6Info -+ && sizes->maxNumOfEchoIpv6Entries -+ < params->p_AutoResEchoIpv6Info->tableSize) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("DSAR: EchoIpv6 table size exceeds the configured maximum size.")); -+ if (params->p_AutoResSnmpInfo -+ && sizes->maxNumOfSnmpOidEntries -+ < params->p_AutoResSnmpInfo->oidsTblSize) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("DSAR: Snmp Oid table size exceeds the configured maximum size.")); -+ if (params->p_AutoResSnmpInfo -+ && sizes->maxNumOfSnmpIPV4Entries -+ < params->p_AutoResSnmpInfo->numOfIpv4Addresses) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("DSAR: Snmp ipv4 table size exceeds the configured maximum size.")); -+ if (params->p_AutoResSnmpInfo -+ && sizes->maxNumOfSnmpIPV6Entries -+ < params->p_AutoResSnmpInfo->numOfIpv6Addresses) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("DSAR: Snmp ipv6 table size exceeds the configured maximum size.")); -+ if (params->p_AutoResFilteringInfo) -+ { -+ if (sizes->maxNumOfIpProtFiltering -+ < params->p_AutoResFilteringInfo->ipProtTableSize) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("DSAR: ip filter table size exceeds the configured maximum size.")); -+ if (sizes->maxNumOfTcpPortFiltering -+ < params->p_AutoResFilteringInfo->udpPortsTableSize) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("DSAR: udp filter table size exceeds the configured maximum size.")); -+ if (sizes->maxNumOfUdpPortFiltering -+ < params->p_AutoResFilteringInfo->tcpPortsTableSize) -+ RETURN_ERROR( -+ MAJOR, -+ E_INVALID_VALUE, -+ ("DSAR: tcp filter table size exceeds the configured maximum size.")); -+ } -+ /* check only 1 MAC address is configured (this is what ucode currently supports) */ -+ if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize) -+ { -+ memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6); -+ i = 1; -+ macInit = TRUE; -+ -+ for (; i < params->p_AutoResArpInfo->tableSize; i++) -+ if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("DSAR: Only 1 mac address is currently supported.")); -+ } -+ if (params->p_AutoResEchoIpv4Info -+ && params->p_AutoResEchoIpv4Info->tableSize) -+ { -+ i = 0; -+ if (!macInit) -+ { -+ memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac, -+ 6); -+ i = 1; -+ macInit = TRUE; -+ } -+ for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++) -+ if (memcmp(mac, -+ params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("DSAR: Only 1 mac address is currently supported.")); -+ } -+ if (params->p_AutoResEchoIpv6Info -+ && params->p_AutoResEchoIpv6Info->tableSize) -+ { -+ i = 0; -+ if (!macInit) -+ { -+ memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac, -+ 6); -+ i = 1; -+ macInit = TRUE; -+ } -+ for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++) -+ if (memcmp(mac, -+ params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("DSAR: Only 1 mac address is currently supported.")); -+ } -+ if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned) -+ { -+ i = 0; -+ if (!macInit) -+ { -+ memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac, -+ 6); -+ i = 1; -+ macInit = TRUE; -+ } -+ for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++) -+ if (memcmp(mac, -+ params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac, -+ 6)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("DSAR: Only 1 mac address is currently supported.")); -+ } -+ if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp) -+ { -+ i = 0; -+ if (!macInit) -+ { -+ memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6); -+ i = 1; -+ } -+ for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++) -+ if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac, -+ 6)) -+ RETURN_ERROR( -+ MAJOR, E_INVALID_VALUE, -+ ("DSAR: Only 1 mac address is currently supported.")); -+ } -+ return E_OK; -+} -+ -+static int GetBERLen(uint8_t* buf) -+{ -+ if (*buf & 0x80) -+ { -+ if ((*buf & 0x7F) == 1) -+ return buf[1]; -+ else -+ return *(uint16_t*)&buf[1]; // assuming max len is 2 -+ } -+ else -+ return buf[0]; -+} -+#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3 -+ -+#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C -+#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000 -+#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000 -+static int fm_soc_suspend(void) -+{ -+ uint32_t *fmclk, tmp32; -+ fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4); -+ tmp32 = GET_UINT32(*fmclk); -+ WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL); -+ tmp32 = GET_UINT32(*fmclk); -+ iounmap(fmclk); -+ return 0; -+} -+ -+void fm_clk_down(void) -+{ -+ uint32_t *fmclk, tmp32; -+ fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4); -+ tmp32 = GET_UINT32(*fmclk); -+ WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000); -+ tmp32 = GET_UINT32(*fmclk); -+ iounmap(fmclk); -+} -+ -+t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params) -+{ -+ int i, j; -+ t_Error err; -+ uint32_t nia; -+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; -+ t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx; -+ t_DsarArpDescriptor *ArpDescriptor; -+ t_DsarIcmpV4Descriptor* ICMPV4Descriptor; -+ t_DsarIcmpV6Descriptor* ICMPV6Descriptor; -+ t_DsarNdDescriptor* NDDescriptor; -+ -+ uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr)); -+ uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr)); -+ t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page))); -+ struct arOffsets* of; -+ uint8_t tmp = 0; -+ t_FmGetSetParams fmGetSetParams; -+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); -+ fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; -+ fmGetSetParams.setParams.sleep = 1; -+ -+ err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes); -+ if (err != E_OK) -+ return err; -+ -+ p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets)); -+ of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets; -+ IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort)); -+ -+ // common -+ WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId); -+ nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia -+ if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser -+ WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne)); -+ else -+ WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia); -+ WRITE_UINT16(ArCommonDescPtr->snmpPort, 161); -+ -+ // ARP -+ if (params->p_AutoResArpInfo) -+ { -+ t_DsarArpBindingEntry* arp_bindings; -+ ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp); -+ WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr); -+ arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor)); -+ if (params->p_AutoResArpInfo->enableConflictDetection) -+ WRITE_UINT16(ArpDescriptor->control, 1); -+ else -+ WRITE_UINT16(ArpDescriptor->control, 0); -+ if (params->p_AutoResArpInfo->tableSize) -+ { -+ t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable; -+ WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]); -+ WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]); -+ WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize); -+ -+ for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++) -+ { -+ WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress); -+ if (arp_entry[i].isVlan) -+ WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF); -+ } -+ WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr); -+ } -+ WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) + -+ sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr); -+ } -+ -+ // ICMPV4 -+ if (params->p_AutoResEchoIpv4Info) -+ { -+ t_DsarIcmpV4BindingEntry* icmpv4_bindings; -+ ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4); -+ WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr); -+ icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor)); -+ WRITE_UINT16(ICMPV4Descriptor->control, 0); -+ if (params->p_AutoResEchoIpv4Info->tableSize) -+ { -+ t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable; -+ WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]); -+ WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]); -+ WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize); -+ -+ for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++) -+ { -+ WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress); -+ if (arp_entry[i].isVlan) -+ WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF); -+ } -+ WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr); -+ } -+ WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) + -+ sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr); -+ } -+ -+ // ICMPV6 -+ if (params->p_AutoResEchoIpv6Info) -+ { -+ t_DsarIcmpV6BindingEntry* icmpv6_bindings; -+ ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6); -+ WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr); -+ icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor)); -+ WRITE_UINT16(ICMPV6Descriptor->control, 0); -+ if (params->p_AutoResEchoIpv6Info->tableSize) -+ { -+ t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable; -+ WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]); -+ WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]); -+ WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize); -+ -+ for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++) -+ { -+ for (j = 0; j < 4; j++) -+ WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]); -+ if (ndp_entry[i].isVlan) -+ WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan -+ } -+ WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr); -+ } -+ WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + -+ sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr); -+ } -+ -+ // ND -+ if (params->p_AutoResNdpInfo) -+ { -+ t_DsarIcmpV6BindingEntry* icmpv6_bindings; -+ NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd); -+ WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr); -+ icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor)); -+ if (params->p_AutoResNdpInfo->enableConflictDetection) -+ WRITE_UINT16(NDDescriptor->control, 1); -+ else -+ WRITE_UINT16(NDDescriptor->control, 0); -+ if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp) -+ { -+ t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned; -+ WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]); -+ WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]); -+ WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned -+ + params->p_AutoResNdpInfo->tableSizeTmp); -+ -+ for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++) -+ { -+ for (j = 0; j < 4; j++) -+ WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]); -+ if (ndp_entry[i].isVlan) -+ WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan -+ } -+ ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp; -+ for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++) -+ { -+ for (j = 0; j < 4; j++) -+ WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]); -+ if (ndp_entry[i].isVlan) -+ WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan -+ } -+ WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr); -+ } -+ WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry) -+ * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp) -+ - fmMuramVirtBaseAddr); -+ WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF); -+ } -+ -+ // SNMP -+ if (params->p_AutoResSnmpInfo) -+ { -+ t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo; -+ t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr; -+ t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr; -+ t_OidsTblEntry* snmpOid; -+ uint8_t *charPointer; -+ int len; -+ t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp); -+ WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr); -+ WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control); -+ WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength); -+ snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor)); -+ if (snmpSrc->numOfIpv4Addresses) -+ { -+ t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl; -+ WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses); -+ for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++) -+ { -+ WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr); -+ if (snmpIpv4AddrSrc[i].isVlan) -+ WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF); -+ } -+ WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr); -+ } -+ snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr) -+ + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses); -+ if (snmpSrc->numOfIpv6Addresses) -+ { -+ t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl; -+ WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses); -+ for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++) -+ { -+ for (j = 0; j < 4; j++) -+ WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]); -+ if (snmpIpv6AddrSrc[i].isVlan) -+ WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF); -+ } -+ WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr); -+ } -+ snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr) -+ + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses); -+ charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid) -+ + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize); -+ len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1])); -+ Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len); -+ WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); -+ charPointer += len; -+ len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1])); -+ Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len); -+ WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); -+ charPointer += len; -+ WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize); -+ WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr); -+ for (i = 0; i < snmpSrc->oidsTblSize; i++) -+ { -+ WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize); -+ WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize); -+ Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize); -+ WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); -+ charPointer += snmpSrc->p_OidsTbl[i].oidSize; -+ if (snmpSrc->p_OidsTbl[i].resSize <= 4) -+ WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal); -+ else -+ { -+ Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize); -+ WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); -+ charPointer += snmpSrc->p_OidsTbl[i].resSize; -+ } -+ snmpOid++; -+ } -+ charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4)); -+ WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr); -+ } -+ -+ // filtering -+ if (params->p_AutoResFilteringInfo) -+ { -+ if (params->p_AutoResFilteringInfo->ipProtPassOnHit) -+ tmp |= IP_PROT_TBL_PASS_MASK; -+ if (params->p_AutoResFilteringInfo->udpPortPassOnHit) -+ tmp |= UDP_PORT_TBL_PASS_MASK; -+ if (params->p_AutoResFilteringInfo->tcpPortPassOnHit) -+ tmp |= TCP_PORT_TBL_PASS_MASK; -+ WRITE_UINT8(ArCommonDescPtr->filterControl, tmp); -+ WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask); -+ -+ // ip filtering -+ if (params->p_AutoResFilteringInfo->ipProtTableSize) -+ { -+ uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp); -+ WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize); -+ for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++) -+ WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]); -+ WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr); -+ } -+ -+ // udp filtering -+ if (params->p_AutoResFilteringInfo->udpPortsTableSize) -+ { -+ t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp); -+ WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize); -+ for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++) -+ { -+ WRITE_UINT32(udp_tbl[i].Ports, -+ (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) + -+ params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort); -+ WRITE_UINT32(udp_tbl[i].PortsMask, -+ (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) + -+ params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask); -+ } -+ WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr); -+ } -+ -+ // tcp filtering -+ if (params->p_AutoResFilteringInfo->tcpPortsTableSize) -+ { -+ t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp); -+ WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize); -+ for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++) -+ { -+ WRITE_UINT32(tcp_tbl[i].Ports, -+ (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) + -+ params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort); -+ WRITE_UINT32(tcp_tbl[i].PortsMask, -+ (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) + -+ params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask); -+ } -+ WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr); -+ } -+ } -+ // common stats -+ WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr); -+ -+ // get into Deep Sleep sequence: -+ -+ // Ensures that FMan do not enter the idle state. This is done by programing -+ // FMDPSLPCR[FM_STOP] to one. -+ fm_soc_suspend(); -+ -+ ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr)); -+ return E_OK; -+ -+} -+ -+void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId); -+t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort) -+{ -+ t_FmGetSetParams fmGetSetParams; -+ t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort; -+ t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort; -+ t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm); -+ t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd); -+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); -+ fmGetSetParams.setParams.type = UPDATE_FM_CLD; -+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); -+ -+ /* Issue graceful stop to HC port */ -+ FM_PORT_Disable(p_FmPortHc); -+ -+ // config tx port -+ p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg); -+ WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg) | BMI_PORT_CFG_IM | BMI_PORT_CFG_EN); -+ // ???? -+ p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne); -+ WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE); -+ // Stage 7:echo -+ p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne); -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E); -+ if (!PrsIsEnabled(h_FmPcd)) -+ { -+ p_FmPort->deepSleepVars.dsarEnabledParser = TRUE; -+ PrsEnable(h_FmPcd); -+ } -+ else -+ p_FmPort->deepSleepVars.dsarEnabledParser = FALSE; -+ -+ p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000); -+ -+ // save rcfg for restoring: accumulate mode is changed by ucode -+ p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg); -+ WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM); -+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); -+ fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; -+ fmGetSetParams.setParams.sleep = 1; -+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); -+ -+// ***** issue external request sync command -+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); -+ fmGetSetParams.setParams.type = UPDATE_FPM_EXTC; -+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); -+ // get -+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); -+ fmGetSetParams.getParams.type = GET_FMFP_EXTC; -+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); -+ if (fmGetSetParams.getParams.fmfp_extc != 0) -+ { -+ // clear -+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); -+ fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR; -+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); -+} -+ -+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); -+ fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI; -+ do -+ { -+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); -+ } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0); -+ if (fmGetSetParams.getParams.fm_npi != 0) -+ XX_Print("FM: Sync did not finish\n"); -+ -+ // check that all stoped -+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); -+ fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI; -+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); -+ while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000) -+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); -+ if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0) -+ XX_Print("FM: Sleeping\n"); -+// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId); -+ -+ return E_OK; -+} -+ -+EXPORT_SYMBOL(FM_PORT_EnterDsarFinal); -+ -+void FM_PORT_Dsar_DumpRegs() -+{ -+ uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc)); -+ DUMP_MEMORY(hh, 0x220); -+} -+ -+void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx) -+{ -+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; -+ t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx; -+ t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm); -+ t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd); -+ t_FmGetSetParams fmGetSetParams; -+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); -+ fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; -+ fmGetSetParams.setParams.sleep = 0; -+ if (p_FmPort->deepSleepVars.autoResOffsets) -+ { -+ XX_Free(p_FmPort->deepSleepVars.autoResOffsets); -+ p_FmPort->deepSleepVars.autoResOffsets = 0; -+ } -+ -+ if (p_FmPort->deepSleepVars.dsarEnabledParser) -+ PrsDisable(FmGetPcd(p_FmPort->h_Fm)); -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne); -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne); -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg); -+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); -+ WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne); -+ WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg); -+ FM_PORT_Enable(p_FmPortHc); -+} -+ -+bool FM_PORT_IsInDsar(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPort; -+ return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets); -+} -+ -+t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats) -+{ -+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx; -+ struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets; -+ uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr); -+ uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr)); -+ t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page))); -+ t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp); -+ t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr); -+ t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4); -+ t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr); -+ t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd); -+ t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr); -+ t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6); -+ t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr); -+ t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp); -+ t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr); -+ stats->arpArCnt = arp_stats->arCnt; -+ stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt; -+ stats->ndpArCnt = nd_stats->arCnt; -+ stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt; -+ stats->snmpGetCnt = snmp_stats->snmpGetReqCnt; -+ stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt; -+ return E_OK; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h -@@ -0,0 +1,999 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_port.h -+ -+ @Description FM Port internal structures and definitions. -+*//***************************************************************************/ -+#ifndef __FM_PORT_H -+#define __FM_PORT_H -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "fm_port_ext.h" -+ -+#include "fm_common.h" -+#include "fm_sp_common.h" -+#include "fsl_fman_sp.h" -+#include "fm_port_ext.h" -+#include "fsl_fman_port.h" -+ -+#define __ERR_MODULE__ MODULE_FM_PORT -+ -+ -+#define MIN_EXT_BUF_SIZE 64 -+#define DATA_ALIGNMENT 64 -+#define MAX_LIODN_OFFSET 64 -+#define MAX_PORT_FIFO_SIZE MIN(BMI_MAX_FIFO_SIZE, 1024*BMI_FIFO_UNITS) -+ -+/**************************************************************************//** -+ @Description Memory Map defines -+*//***************************************************************************/ -+#define BMI_PORT_REGS_OFFSET 0 -+#define QMI_PORT_REGS_OFFSET 0x400 -+#define PRS_PORT_REGS_OFFSET 0x800 -+ -+/**************************************************************************//** -+ @Description defaults -+*//***************************************************************************/ -+#define DEFAULT_PORT_deqHighPriority_1G FALSE -+#define DEFAULT_PORT_deqHighPriority_10G TRUE -+#define DEFAULT_PORT_deqType e_FM_PORT_DEQ_TYPE1 -+#define DEFAULT_PORT_deqPrefetchOption e_FM_PORT_DEQ_FULL_PREFETCH -+#define DEFAULT_PORT_deqPrefetchOption_HC e_FM_PORT_DEQ_NO_PREFETCH -+#define DEFAULT_PORT_deqByteCnt_10G 0x1400 -+#define DEFAULT_PORT_deqByteCnt_1G 0x400 -+#define DEFAULT_PORT_bufferPrefixContent_privDataSize DEFAULT_FM_SP_bufferPrefixContent_privDataSize -+#define DEFAULT_PORT_bufferPrefixContent_passPrsResult DEFAULT_FM_SP_bufferPrefixContent_passPrsResult -+#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp -+#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo -+#define DEFAULT_PORT_bufferPrefixContent_dataAlign DEFAULT_FM_SP_bufferPrefixContent_dataAlign -+#define DEFAULT_PORT_cheksumLastBytesIgnore 0 -+#define DEFAULT_PORT_cutBytesFromEnd 4 -+#define DEFAULT_PORT_fifoDeqPipelineDepth_IM 2 -+ -+#define DEFAULT_PORT_frmDiscardOverride FALSE -+ -+#define DEFAULT_PORT_dmaSwapData (e_FmDmaSwapOption)DEFAULT_FMAN_SP_DMA_SWAP_DATA -+#define DEFAULT_PORT_dmaIntContextCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR -+#define DEFAULT_PORT_dmaHeaderCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR -+#define DEFAULT_PORT_dmaScatterGatherCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR -+#define DEFAULT_PORT_dmaWriteOptimize DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE -+ -+#define DEFAULT_PORT_noScatherGather DEFAULT_FMAN_SP_NO_SCATTER_GATHER -+#define DEFAULT_PORT_forwardIntContextReuse FALSE -+#define DEFAULT_PORT_BufMargins_startMargins 32 -+#define DEFAULT_PORT_BufMargins_endMargins 0 -+#define DEFAULT_PORT_syncReq TRUE -+#define DEFAULT_PORT_syncReqForHc FALSE -+#define DEFAULT_PORT_color e_FM_PORT_COLOR_GREEN -+#define DEFAULT_PORT_errorsToDiscard FM_PORT_FRM_ERR_CLS_DISCARD -+/* #define DEFAULT_PORT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE */ -+/* #define DEFAULT_PORT_rateLimitBurstSizeHighGranularity FALSE */ -+#define DEFAULT_PORT_exception IM_EV_BSY -+#define DEFAULT_PORT_maxFrameLength 9600 -+ -+#define DEFAULT_notSupported 0xff -+ -+#if (DPAA_VERSION < 11) -+#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE -+#define DEFAULT_PORT_rxFifoThreshold (MAX_PORT_FIFO_SIZE*3/4) -+ -+#define DEFAULT_PORT_txFifoMinFillLevel 0 -+#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE) -+#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 1 -+#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4 -+ -+#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2 -+ -+/* Host command port MUST NOT be changed to more than 1 !!! */ -+#define DEFAULT_PORT_numOfTasks(type) \ -+ (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \ -+ ((type) == e_FM_PORT_TYPE_TX_10G)) ? 16 : \ -+ ((((type) == e_FM_PORT_TYPE_RX) || \ -+ ((type) == e_FM_PORT_TYPE_TX) || \ -+ ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 3 : 1)) -+ -+#define DEFAULT_PORT_extraNumOfTasks(type) \ -+ (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \ -+ (((type) == e_FM_PORT_TYPE_RX) ? 2 : 0)) -+ -+#define DEFAULT_PORT_numOfOpenDmas(type) \ -+ (uint32_t)((((type) == e_FM_PORT_TYPE_TX_10G) || \ -+ ((type) == e_FM_PORT_TYPE_RX_10G)) ? 8 : 1 ) -+ -+#define DEFAULT_PORT_extraNumOfOpenDmas(type) \ -+ (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \ -+ (((type) == e_FM_PORT_TYPE_RX) ? 1 : 0)) -+ -+#define DEFAULT_PORT_numOfFifoBufs(type) \ -+ (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \ -+ ((type) == e_FM_PORT_TYPE_TX_10G)) ? 48 : \ -+ ((type) == e_FM_PORT_TYPE_RX) ? 45 : \ -+ ((type) == e_FM_PORT_TYPE_TX) ? 44 : 8) -+ -+#define DEFAULT_PORT_extraNumOfFifoBufs 0 -+ -+#else /* (DPAA_VERSION < 11) */ -+/* Defaults are registers' reset values */ -+#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE -+#define DEFAULT_PORT_rxFifoThreshold MAX_PORT_FIFO_SIZE -+ -+#define DEFAULT_PORT_txFifoMinFillLevel 0 -+#define DEFAULT_PORT_txFifoLowComfLevel (5 * KILOBYTE) -+#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 2 -+#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4 -+ -+#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2 -+ -+#define DEFAULT_PORT_numOfTasks(type) \ -+ (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \ -+ ((type) == e_FM_PORT_TYPE_TX_10G)) ? 14 : \ -+ (((type) == e_FM_PORT_TYPE_RX) || \ -+ ((type) == e_FM_PORT_TYPE_TX)) ? 4 : \ -+ ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? 6 : 1) -+ -+#define DEFAULT_PORT_extraNumOfTasks(type) 0 -+ -+#define DEFAULT_PORT_numOfOpenDmas(type) \ -+ (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \ -+ ((type) == e_FM_PORT_TYPE_TX_10G) ? 12 : \ -+ ((type) == e_FM_PORT_TYPE_RX) ? 2 : \ -+ ((type) == e_FM_PORT_TYPE_TX) ? 3 : \ -+ ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 2 : 4) -+ -+#define DEFAULT_PORT_extraNumOfOpenDmas(type) 0 -+ -+#define DEFAULT_PORT_numOfFifoBufs(type) \ -+ (uint32_t) (((type) == e_FM_PORT_TYPE_RX_10G) ? 96 : \ -+ ((type) == e_FM_PORT_TYPE_TX_10G) ? 64 : \ -+ ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 10 : 50) -+ -+#define DEFAULT_PORT_extraNumOfFifoBufs 0 -+ -+#endif /* (DPAA_VERSION < 11) */ -+ -+#define DEFAULT_PORT_txBdRingLength 16 -+#define DEFAULT_PORT_rxBdRingLength 128 -+#define DEFAULT_PORT_ImfwExtStructsMemId 0 -+#define DEFAULT_PORT_ImfwExtStructsMemAttr MEMORY_ATTR_CACHEABLE -+ -+#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32) -+ -+/**************************************************************************//** -+ @Collection PCD Engines -+*//***************************************************************************/ -+typedef uint32_t fmPcdEngines_t; /**< options as defined below: */ -+ -+#define FM_PCD_NONE 0 /**< No PCD Engine indicated */ -+#define FM_PCD_PRS 0x80000000 /**< Parser indicated */ -+#define FM_PCD_KG 0x40000000 /**< Keygen indicated */ -+#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */ -+#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */ -+#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */ -+/* @} */ -+ -+#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8 -+#define FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256 -+#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32) -+ -+#define FM_OH_PORT_ID 0 -+ -+/***********************************************************************/ -+/* SW parser OFFLOAD labels (offsets) */ -+/***********************************************************************/ -+#if (DPAA_VERSION == 10) -+#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x300 -+#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x325 -+#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x325 -+#else -+#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x100 -+/* Will be used for: -+ * 1. identify fragments -+ * 2. udp-lite -+ */ -+#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x146 -+/* Will be used for: -+ * 1. will identify the fragmentable area -+ * 2. udp-lite -+ */ -+#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x261 -+#define OFFLOAD_SW_PATCH_CAPWAP_LABEL 0x38d -+#endif /* (DPAA_VERSION == 10) */ -+ -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+#define UDP_LITE_SW_PATCH_LABEL 0x2E0 -+#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+ -+ -+/**************************************************************************//** -+ @Description Memory Mapped Registers -+*//***************************************************************************/ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+typedef struct -+{ -+ volatile uint32_t fmbm_rcfg; /**< Rx Configuration */ -+ volatile uint32_t fmbm_rst; /**< Rx Status */ -+ volatile uint32_t fmbm_rda; /**< Rx DMA attributes*/ -+ volatile uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/ -+ volatile uint32_t fmbm_rfed; /**< Rx Frame End Data*/ -+ volatile uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/ -+ volatile uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/ -+ volatile uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/ -+ volatile uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/ -+ volatile uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/ -+ volatile uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/ -+ volatile uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/ -+ volatile uint32_t fmbm_rpp; /**< Rx Policer Profile */ -+ volatile uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */ -+ volatile uint32_t fmbm_reth; /**< Rx Excessive Threshold */ -+ volatile uint32_t reserved1[0x01];/**< (0x03C) */ -+ volatile uint32_t fmbm_rprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS]; -+ /**< Rx Parse Results Array Initialization*/ -+ volatile uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/ -+ volatile uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/ -+ volatile uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/ -+ volatile uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/ -+ volatile uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */ -+ volatile uint32_t reserved2[0x02];/**< (0x074-0x078) */ -+ volatile uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */ -+ volatile uint32_t reserved3[0x20];/**< (0x080 0x0FF) */ -+ volatile uint32_t fmbm_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS]; -+ /**< Buffer Manager pool Information-*/ -+ volatile uint32_t fmbm_acnt[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS]; -+ /**< Allocate Counter-*/ -+ volatile uint32_t reserved4[0x08]; -+ /**< 0x130/0x140 - 0x15F reserved -*/ -+ volatile uint32_t fmbm_rcgm[FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32]; -+ /**< Congestion Group Map*/ -+ volatile uint32_t fmbm_rmpd; /**< BM Pool Depletion */ -+ volatile uint32_t reserved5[0x1F];/**< (0x184 0x1FF) */ -+ volatile uint32_t fmbm_rstc; /**< Rx Statistics Counters*/ -+ volatile uint32_t fmbm_rfrc; /**< Rx Frame Counter*/ -+ volatile uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/ -+ volatile uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/ -+ volatile uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/ -+ volatile uint32_t fmbm_rfcd; /**< Rx Frame Discard Counter*/ -+ volatile uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/ -+ volatile uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard Counter-*/ -+ volatile uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter-*/ -+ volatile uint32_t fmbm_rpec; /**< Rx RX Prepare to enqueue Counter-*/ -+ volatile uint32_t reserved6[0x16];/**< (0x228 0x27F) */ -+ volatile uint32_t fmbm_rpc; /**< Rx Performance Counters*/ -+ volatile uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/ -+ volatile uint32_t fmbm_rccn; /**< Rx Cycle Counter*/ -+ volatile uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/ -+ volatile uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization Counter*/ -+ volatile uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/ -+ volatile uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/ -+ volatile uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/ -+ volatile uint32_t reserved7[0x18];/**< (0x2A0-0x2FF) */ -+ volatile uint32_t fmbm_rdcfg[0x3];/**< Rx Debug-*/ -+ volatile uint32_t fmbm_rgpr; /**< Rx General Purpose Register. */ -+ volatile uint32_t reserved8[0x3a];/**< (0x310-0x3FF) */ -+} t_FmPortRxBmiRegs; -+ -+typedef struct -+{ -+ volatile uint32_t fmbm_tcfg; /**< Tx Configuration */ -+ volatile uint32_t fmbm_tst; /**< Tx Status */ -+ volatile uint32_t fmbm_tda; /**< Tx DMA attributes */ -+ volatile uint32_t fmbm_tfp; /**< Tx FIFO Parameters */ -+ volatile uint32_t fmbm_tfed; /**< Tx Frame End Data */ -+ volatile uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */ -+ volatile uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */ -+ volatile uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */ -+ volatile uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */ -+ volatile uint32_t fmbm_tfeqid; /**< Tx Frame Error Queue ID */ -+ volatile uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */ -+ volatile uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */ -+ volatile uint32_t fmbm_trlmt; /**< Tx Rate Limiter */ -+ volatile uint32_t fmbm_tccb; /**< Tx Coarse Classification Base */ -+ volatile uint32_t reserved0[0x0e];/**< (0x038-0x070) */ -+ volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine */ -+ volatile uint32_t fmbm_tpfcm[0x02];/**< Tx Priority based Flow Control (PFC) Mapping */ -+ volatile uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */ -+ volatile uint32_t reserved2[0x60];/**< (0x080-0x200) */ -+ volatile uint32_t fmbm_tstc; /**< Tx Statistics Counters */ -+ volatile uint32_t fmbm_tfrc; /**< Tx Frame Counter */ -+ volatile uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */ -+ volatile uint32_t fmbm_tfledc; /**< Tx Frame Length error discard counter */ -+ volatile uint32_t fmbm_tfufdc; /**< Tx Frame unsupported format discard Counter */ -+ volatile uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */ -+ volatile uint32_t reserved3[0x1A];/**< (0x218-0x280) */ -+ volatile uint32_t fmbm_tpc; /**< Tx Performance Counters*/ -+ volatile uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/ -+ volatile uint32_t fmbm_tccn; /**< Tx Cycle Counter*/ -+ volatile uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/ -+ volatile uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/ -+ volatile uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/ -+ volatile uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/ -+ volatile uint32_t reserved4[16]; /**< (0x29C-0x2FF) */ -+ volatile uint32_t fmbm_tdcfg[0x3];/**< Tx Debug-*/ -+ volatile uint32_t fmbm_tgpr; /**< O/H General Purpose Register */ -+ volatile uint32_t reserved5[0x3a];/**< (0x310-0x3FF) */ -+} t_FmPortTxBmiRegs; -+ -+typedef struct -+{ -+ volatile uint32_t fmbm_ocfg; /**< O/H Configuration */ -+ volatile uint32_t fmbm_ost; /**< O/H Status */ -+ volatile uint32_t fmbm_oda; /**< O/H DMA attributes */ -+ volatile uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */ -+ volatile uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */ -+ volatile uint32_t fmbm_ofne; /**< O/H Frame Next Engine */ -+ volatile uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */ -+ volatile uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */ -+ volatile uint32_t fmbm_opso; /**< O/H Parse Start Offset */ -+ volatile uint32_t fmbm_opp; /**< O/H Policer Profile */ -+ volatile uint32_t fmbm_occb; /**< O/H Coarse Classification base */ -+ volatile uint32_t fmbm_oim; /**< O/H Internal margins*/ -+ volatile uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/ -+ volatile uint32_t fmbm_ofed; /**< O/H Frame End Data*/ -+ volatile uint32_t reserved0[2]; /**< (0x038 - 0x03F) */ -+ volatile uint32_t fmbm_oprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS]; -+ /**< O/H Parse Results Array Initialization */ -+ volatile uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */ -+ volatile uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */ -+ volatile uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */ -+ volatile uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */ -+ volatile uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */ -+ volatile uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */ -+ volatile uint32_t fmbm_orlmt; /**< O/H Rate Limiter */ -+ volatile uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */ -+ volatile uint32_t reserved1[0x20];/**< (0x080 - 0x0FF) */ -+ volatile uint32_t fmbm_oebmpi[2]; /**< Buffer Manager Observed Pool Information */ -+ volatile uint32_t reserved2[0x16];/**< (0x108 - 0x15F) */ -+ volatile uint32_t fmbm_ocgm; /**< Observed Congestion Group Map */ -+ volatile uint32_t reserved3[0x7]; /**< (0x164 - 0x17F) */ -+ volatile uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */ -+ volatile uint32_t reserved4[0x1F];/**< (0x184 - 0x1FF) */ -+ volatile uint32_t fmbm_ostc; /**< O/H Statistics Counters */ -+ volatile uint32_t fmbm_ofrc; /**< O/H Frame Counter */ -+ volatile uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */ -+ volatile uint32_t fmbm_ofledc; /**< O/H Frames Length Error Discard Counter */ -+ volatile uint32_t fmbm_ofufdc; /**< O/H Frames Unsupported Format Discard Counter */ -+ volatile uint32_t fmbm_offc; /**< O/H Filter Frames Counter */ -+ volatile uint32_t fmbm_ofwdc; /**< - Rx Frames WRED Discard Counter */ -+ volatile uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Counter */ -+ volatile uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */ -+ volatile uint32_t fmbm_oodc; /**< O/H Out of Buffers Discard Counter */ -+ volatile uint32_t fmbm_opec; /**< O/H Prepare to enqueue Counter */ -+ volatile uint32_t reserved5[0x15];/**< ( - 0x27F) */ -+ volatile uint32_t fmbm_opc; /**< O/H Performance Counters */ -+ volatile uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */ -+ volatile uint32_t fmbm_occn; /**< O/H Cycle Counter */ -+ volatile uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */ -+ volatile uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */ -+ volatile uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */ -+ volatile uint32_t reserved6[26]; /**< (0x298-0x2FF) */ -+ volatile uint32_t fmbm_odcfg[0x3];/**< O/H Debug (only 1 in P1023) */ -+ volatile uint32_t fmbm_ogpr; /**< O/H General Purpose Register. */ -+ volatile uint32_t reserved7[0x3a];/**< (0x310 0x3FF) */ -+} t_FmPortOhBmiRegs; -+ -+typedef union -+{ -+ t_FmPortRxBmiRegs rxPortBmiRegs; -+ t_FmPortTxBmiRegs txPortBmiRegs; -+ t_FmPortOhBmiRegs ohPortBmiRegs; -+} u_FmPortBmiRegs; -+ -+typedef struct -+{ -+ volatile uint32_t reserved1[2]; /**< 0xn024 - 0x02B */ -+ volatile uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */ -+ volatile uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */ -+ volatile uint32_t fmqm_pndtfc; /**< PortID n Dequeue Total Frame Counter */ -+ volatile uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID from Default Counter */ -+ volatile uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */ -+} t_FmPortNonRxQmiRegs; -+ -+typedef struct -+{ -+ volatile uint32_t fmqm_pnc; /**< PortID n Configuration Register */ -+ volatile uint32_t fmqm_pns; /**< PortID n Status Register */ -+ volatile uint32_t fmqm_pnts; /**< PortID n Task Status Register */ -+ volatile uint32_t reserved0[4]; /**< 0xn00C - 0xn01B */ -+ volatile uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */ -+ volatile uint32_t fmqm_pnetfc; /**< PortID n Enqueue Total Frame Counter */ -+ t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */ -+} t_FmPortQmiRegs; -+ -+typedef struct -+{ -+ struct -+ { -+ volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */ -+ volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */ -+ } hdrs[FM_PCD_PRS_NUM_OF_HDRS]; -+ volatile uint32_t reserved0[0xde]; -+ volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */ -+ volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */ -+} t_FmPortPrsRegs; -+ -+/**************************************************************************//* -+ @Description Basic buffer descriptor (BD) structure -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ volatile uint16_t status; -+ volatile uint16_t length; -+ volatile uint8_t reserved0[0x6]; -+ volatile uint8_t reserved1[0x1]; -+ volatile t_FmPhysAddr buff; -+} _PackedType t_FmImBd; -+ -+typedef _Packed struct -+{ -+ volatile uint16_t gen; /**< tbd */ -+ volatile uint8_t reserved0[0x1]; -+ volatile t_FmPhysAddr bdRingBase; /**< tbd */ -+ volatile uint16_t bdRingSize; /**< tbd */ -+ volatile uint16_t offsetIn; /**< tbd */ -+ volatile uint16_t offsetOut; /**< tbd */ -+ volatile uint8_t reserved1[0x12]; /**< 0x0e - 0x1f */ -+} _PackedType t_FmPortImQd; -+ -+typedef _Packed struct -+{ -+ volatile uint32_t mode; /**< Mode register */ -+ volatile uint32_t rxQdPtr; /**< tbd */ -+ volatile uint32_t txQdPtr; /**< tbd */ -+ volatile uint16_t mrblr; /**< tbd */ -+ volatile uint16_t rxQdBsyCnt; /**< tbd */ -+ volatile uint8_t reserved0[0x10]; /**< 0x10 - 0x1f */ -+ t_FmPortImQd rxQd; -+ t_FmPortImQd txQd; -+ volatile uint8_t reserved1[0xa0]; /**< 0x60 - 0xff */ -+} _PackedType t_FmPortImPram; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+/**************************************************************************//** -+ @Description Registers bit fields -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description BMI defines -+*//***************************************************************************/ -+#if (DPAA_VERSION >= 11) -+#define BMI_SP_ID_MASK 0xff000000 -+#define BMI_SP_ID_SHIFT 24 -+#define BMI_SP_EN 0x01000000 -+#endif /* (DPAA_VERSION >= 11) */ -+ -+#define BMI_PORT_CFG_EN 0x80000000 -+#define BMI_PORT_CFG_EN_MACSEC 0x00800000 -+#define BMI_PORT_CFG_FDOVR 0x02000000 -+#define BMI_PORT_CFG_IM 0x01000000 -+#define BMI_PORT_CFG_AM 0x00000040 -+#define BMI_PORT_STATUS_BSY 0x80000000 -+#define BMI_COUNTERS_EN 0x80000000 -+ -+#define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000 -+#define BMI_PORT_RFNE_FRWD_RPD 0x40000000 -+#define BMI_RFNE_FDCS_MASK 0xFF000000 -+#define BMI_RFNE_HXS_MASK 0x000000FF -+ -+#define BMI_CMD_MR_LEAC 0x00200000 -+#define BMI_CMD_MR_SLEAC 0x00100000 -+#define BMI_CMD_MR_MA 0x00080000 -+#define BMI_CMD_MR_DEAS 0x00040000 -+#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \ -+ BMI_CMD_MR_SLEAC | \ -+ BMI_CMD_MR_MA | \ -+ BMI_CMD_MR_DEAS) -+#define BMI_CMD_ATTR_ORDER 0x80000000 -+#define BMI_CMD_ATTR_SYNC 0x02000000 -+#define BMI_CMD_ATTR_MODE_MISS_ALLIGN_ADDR_EN 0x00080000 -+#define BMI_CMD_ATTR_MACCMD_MASK 0x0000ff00 -+#define BMI_CMD_ATTR_MACCMD_OVERRIDE 0x00008000 -+#define BMI_CMD_ATTR_MACCMD_SECURED 0x00001000 -+#define BMI_CMD_ATTR_MACCMD_SC_MASK 0x00000f00 -+ -+#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000 -+#define BMI_STATUS_RX_MASK_UNUSED (uint32_t)(~(FM_PORT_FRM_ERR_DMA | \ -+ FM_PORT_FRM_ERR_PHYSICAL | \ -+ FM_PORT_FRM_ERR_SIZE | \ -+ FM_PORT_FRM_ERR_CLS_DISCARD | \ -+ FM_PORT_FRM_ERR_EXTRACTION | \ -+ FM_PORT_FRM_ERR_NO_SCHEME | \ -+ FM_PORT_FRM_ERR_COLOR_RED | \ -+ FM_PORT_FRM_ERR_COLOR_YELLOW | \ -+ FM_PORT_FRM_ERR_ILL_PLCR | \ -+ FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \ -+ FM_PORT_FRM_ERR_PRS_TIMEOUT | \ -+ FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \ -+ FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \ -+ FM_PORT_FRM_ERR_PRS_HDR_ERR | \ -+ FM_PORT_FRM_ERR_IPRE | \ -+ FM_PORT_FRM_ERR_IPR_NCSP | \ -+ FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW)) -+ -+#define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \ -+ ~(FM_PORT_FRM_ERR_LENGTH | \ -+ FM_PORT_FRM_ERR_NON_FM | \ -+ FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)) -+ -+#define BMI_RATE_LIMIT_EN 0x80000000 -+#define BMI_RATE_LIMIT_BURST_SIZE_GRAN 0x80000000 -+#define BMI_RATE_LIMIT_SCALE_BY_2 0x00000001 -+#define BMI_RATE_LIMIT_SCALE_BY_4 0x00000002 -+#define BMI_RATE_LIMIT_SCALE_BY_8 0x00000003 -+ -+#define BMI_RX_FIFO_THRESHOLD_BC 0x80000000 -+ -+#define BMI_PRS_RESULT_HIGH 0x00000000 -+#define BMI_PRS_RESULT_LOW 0xFFFFFFFF -+ -+ -+#define RX_ERRS_TO_ENQ (FM_PORT_FRM_ERR_DMA | \ -+ FM_PORT_FRM_ERR_PHYSICAL | \ -+ FM_PORT_FRM_ERR_SIZE | \ -+ FM_PORT_FRM_ERR_EXTRACTION | \ -+ FM_PORT_FRM_ERR_NO_SCHEME | \ -+ FM_PORT_FRM_ERR_ILL_PLCR | \ -+ FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \ -+ FM_PORT_FRM_ERR_PRS_TIMEOUT | \ -+ FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \ -+ FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \ -+ FM_PORT_FRM_ERR_PRS_HDR_ERR | \ -+ FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW | \ -+ FM_PORT_FRM_ERR_IPRE) -+ -+#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \ -+ FM_PORT_FRM_ERR_LENGTH | \ -+ FM_PORT_FRM_ERR_NON_FM | \ -+ FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT) -+ -+ -+#define BMI_RX_FIFO_PRI_ELEVATION_MASK 0x03FF0000 -+#define BMI_RX_FIFO_THRESHOLD_MASK 0x000003FF -+#define BMI_TX_FIFO_MIN_FILL_MASK 0x03FF0000 -+#define BMI_FIFO_PIPELINE_DEPTH_MASK 0x0000F000 -+#define BMI_TX_LOW_COMF_MASK 0x000003FF -+ -+/* shifts */ -+#define BMI_PORT_CFG_MS_SEL_SHIFT 16 -+#define BMI_DMA_ATTR_IC_CACHE_SHIFT FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT -+#define BMI_DMA_ATTR_HDR_CACHE_SHIFT FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT -+#define BMI_DMA_ATTR_SG_CACHE_SHIFT FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT -+ -+#define BMI_IM_FOF_SHIFT 28 -+#define BMI_PR_PORTID_SHIFT 24 -+ -+#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16 -+#define BMI_RX_FIFO_THRESHOLD_SHIFT 0 -+ -+#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24 -+#define BMI_RX_FRAME_END_CUT_SHIFT 16 -+ -+#define BMI_IC_SIZE_SHIFT FMAN_SP_IC_SIZE_SHIFT -+ -+#define BMI_INT_BUF_MARG_SHIFT 28 -+ -+#define BMI_EXT_BUF_MARG_END_SHIFT FMAN_SP_EXT_BUF_MARG_END_SHIFT -+ -+#define BMI_CMD_ATTR_COLOR_SHIFT 26 -+#define BMI_CMD_ATTR_COM_MODE_SHIFT 16 -+#define BMI_CMD_ATTR_MACCMD_SHIFT 8 -+#define BMI_CMD_ATTR_MACCMD_OVERRIDE_SHIFT 15 -+#define BMI_CMD_ATTR_MACCMD_SECURED_SHIFT 12 -+#define BMI_CMD_ATTR_MACCMD_SC_SHIFT 8 -+ -+#define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24 -+ -+#define BMI_TX_FIFO_MIN_FILL_SHIFT 16 -+#define BMI_TX_LOW_COMF_SHIFT 0 -+ -+#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24 -+#define BMI_PERFORMANCE_PORT_COMP_SHIFT 16 -+#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12 -+#define BMI_PERFORMANCE_FIFO_COMP_SHIFT 0 -+ -+#define BMI_MAX_BURST_SHIFT 16 -+#define BMI_COUNT_RATE_UNIT_SHIFT 16 -+ -+/* sizes */ -+#define FRAME_END_DATA_SIZE 16 -+#define FRAME_OFFSET_UNITS 16 -+#define MIN_TX_INT_OFFSET 16 -+#define MAX_FRAME_OFFSET 64 -+#define MAX_FIFO_PIPELINE_DEPTH 8 -+#define MAX_PERFORMANCE_TASK_COMP 64 -+#define MAX_PERFORMANCE_TX_QUEUE_COMP 8 -+#define MAX_PERFORMANCE_RX_QUEUE_COMP 64 -+#define MAX_PERFORMANCE_DMA_COMP 16 -+#define MAX_NUM_OF_TASKS 64 -+#define MAX_NUM_OF_EXTRA_TASKS 8 -+#define MAX_NUM_OF_DMAS 16 -+#define MAX_NUM_OF_EXTRA_DMAS 8 -+#define MAX_BURST_SIZE 1024 -+#define MIN_NUM_OF_OP_DMAS 2 -+ -+ -+/**************************************************************************//** -+ @Description QMI defines -+*//***************************************************************************/ -+/* masks */ -+#define QMI_PORT_CFG_EN 0x80000000 -+#define QMI_PORT_CFG_EN_COUNTERS 0x10000000 -+#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000 -+#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000 -+ -+#define QMI_DEQ_CFG_PREFETCH_NO_TNUM 0x02000000 -+#define QMI_DEQ_CFG_PREFETCH_WAITING_TNUM 0 -+#define QMI_DEQ_CFG_PREFETCH_1_FRAME 0 -+#define QMI_DEQ_CFG_PREFETCH_3_FRAMES 0x01000000 -+ -+#define QMI_DEQ_CFG_PRI 0x80000000 -+#define QMI_DEQ_CFG_TYPE1 0x10000000 -+#define QMI_DEQ_CFG_TYPE2 0x20000000 -+#define QMI_DEQ_CFG_TYPE3 0x30000000 -+ -+#define QMI_DEQ_CFG_SUBPORTAL_MASK 0x1f -+#define QMI_DEQ_CFG_SUBPORTAL_SHIFT 20 -+ -+/**************************************************************************//** -+ @Description PARSER defines -+*//***************************************************************************/ -+/* masks */ -+#define PRS_HDR_ERROR_DIS 0x00000800 -+#define PRS_HDR_SW_PRS_EN 0x00000400 -+#define PRS_CP_OFFSET_MASK 0x0000000F -+#define PRS_TPID1_MASK 0xFFFF0000 -+#define PRS_TPID2_MASK 0x0000FFFF -+#define PRS_TPID_DFLT 0x91009100 -+ -+#define PRS_HDR_MPLS_LBL_INTER_EN 0x00200000 -+#define PRS_HDR_IPV6_ROUTE_HDR_EN 0x00008000 -+#define PRS_HDR_PPPOE_MTU_CHECK_EN 0x80000000 -+#define PRS_HDR_UDP_PAD_REMOVAL 0x80000000 -+#define PRS_HDR_TCP_PAD_REMOVAL 0x80000000 -+#define PRS_CAC_STOP 0x00000001 -+#define PRS_CAC_ACTIVE 0x00000100 -+ -+/* shifts */ -+#define PRS_PCTPID_SHIFT 16 -+#define PRS_HDR_MPLS_NEXT_HDR_SHIFT 22 -+#define PRS_HDR_ETH_BC_SHIFT 28 -+#define PRS_HDR_ETH_MC_SHIFT 24 -+#define PRS_HDR_VLAN_STACKED_SHIFT 16 -+#define PRS_HDR_MPLS_STACKED_SHIFT 16 -+#define PRS_HDR_IPV4_1_BC_SHIFT 28 -+#define PRS_HDR_IPV4_1_MC_SHIFT 24 -+#define PRS_HDR_IPV4_2_UC_SHIFT 20 -+#define PRS_HDR_IPV4_2_MC_BC_SHIFT 16 -+#define PRS_HDR_IPV6_1_MC_SHIFT 24 -+#define PRS_HDR_IPV6_2_UC_SHIFT 20 -+#define PRS_HDR_IPV6_2_MC_SHIFT 16 -+ -+#define PRS_HDR_ETH_BC_MASK 0x0fffffff -+#define PRS_HDR_ETH_MC_MASK 0xf0ffffff -+#define PRS_HDR_VLAN_STACKED_MASK 0xfff0ffff -+#define PRS_HDR_MPLS_STACKED_MASK 0xfff0ffff -+#define PRS_HDR_IPV4_1_BC_MASK 0x0fffffff -+#define PRS_HDR_IPV4_1_MC_MASK 0xf0ffffff -+#define PRS_HDR_IPV4_2_UC_MASK 0xff0fffff -+#define PRS_HDR_IPV4_2_MC_BC_MASK 0xfff0ffff -+#define PRS_HDR_IPV6_1_MC_MASK 0xf0ffffff -+#define PRS_HDR_IPV6_2_UC_MASK 0xff0fffff -+#define PRS_HDR_IPV6_2_MC_MASK 0xfff0ffff -+ -+/* others */ -+#define PRS_HDR_ENTRY_SIZE 8 -+#define DEFAULT_CLS_PLAN_VECTOR 0xFFFFFFFF -+ -+#define IPSEC_SW_PATCH_START 0x20 -+#define SCTP_SW_PATCH_START 0x4D -+#define DCCP_SW_PATCH_START 0x41 -+ -+/**************************************************************************//** -+ @Description IM defines -+*//***************************************************************************/ -+#define BD_R_E 0x80000000 -+#define BD_L 0x08000000 -+ -+#define BD_RX_CRE 0x00080000 -+#define BD_RX_FTL 0x00040000 -+#define BD_RX_FTS 0x00020000 -+#define BD_RX_OV 0x00010000 -+ -+#define BD_RX_ERRORS (BD_RX_CRE | BD_RX_FTL | BD_RX_FTS | BD_RX_OV) -+ -+#define FM_IM_SIZEOF_BD sizeof(t_FmImBd) -+ -+#define BD_STATUS_MASK 0xffff0000 -+#define BD_LENGTH_MASK 0x0000ffff -+ -+#define BD_STATUS_AND_LENGTH_SET(bd, val) WRITE_UINT32(*(volatile uint32_t*)(bd), (val)) -+ -+#define BD_STATUS_AND_LENGTH(bd) GET_UINT32(*(volatile uint32_t*)(bd)) -+ -+#define BD_GET(id) &p_FmPort->im.p_BdRing[id] -+ -+#define IM_ILEGAL_BD_ID 0xffff -+ -+/* others */ -+#define IM_PRAM_ALIGN 0x100 -+ -+/* masks */ -+#define IM_MODE_GBL 0x20000000 -+#define IM_MODE_BO_MASK 0x18000000 -+#define IM_MODE_BO_SHIFT 3 -+#define IM_MODE_GRC_STP 0x00800000 -+ -+#define IM_MODE_SET_BO(val) (uint32_t)((val << (31-IM_MODE_BO_SHIFT)) & IM_MODE_BO_MASK) -+ -+#define IM_RXQD_BSYINTM 0x0008 -+#define IM_RXQD_RXFINTM 0x0010 -+#define IM_RXQD_FPMEVT_SEL_MASK 0x0003 -+ -+#define IM_EV_BSY 0x40000000 -+#define IM_EV_RX 0x80000000 -+ -+ -+/**************************************************************************//** -+ @Description Additional defines -+*//***************************************************************************/ -+ -+typedef struct { -+ t_Handle h_FmMuram; -+ t_FmPortImPram *p_FmPortImPram; -+ uint8_t fwExtStructsMemId; -+ uint32_t fwExtStructsMemAttr; -+ uint16_t bdRingSize; -+ t_FmImBd *p_BdRing; -+ t_Handle *p_BdShadow; -+ uint16_t currBdId; -+ uint16_t firstBdOfFrameId; -+ -+ /* Rx port parameters */ -+ uint8_t dataMemId; /**< Memory partition ID for data buffers */ -+ uint32_t dataMemAttributes; /**< Memory attributes for data buffers */ -+ t_BufferPoolInfo rxPool; -+ uint16_t mrblr; -+ uint16_t rxFrameAccumLength; -+ t_FmPortImRxStoreCallback *f_RxStore; -+ -+ /* Tx port parameters */ -+ uint32_t txFirstBdStatus; -+ t_FmPortImTxConfCallback *f_TxConf; -+} t_FmMacIm; -+ -+ -+typedef struct { -+ struct fman_port_cfg dfltCfg; -+ uint32_t dfltFqid; -+ uint32_t confFqid; -+ uint32_t errFqid; -+ uintptr_t baseAddr; -+ uint8_t deqSubPortal; -+ bool deqHighPriority; -+ e_FmPortDeqType deqType; -+ e_FmPortDeqPrefetchOption deqPrefetchOption; -+ uint16_t deqByteCnt; -+ uint8_t cheksumLastBytesIgnore; -+ uint8_t cutBytesFromEnd; -+ t_FmBufPoolDepletion bufPoolDepletion; -+ uint8_t pipelineDepth; -+ uint16_t fifoLowComfLevel; -+ bool frmDiscardOverride; -+ bool enRateLimit; -+ t_FmPortRateLimit rateLimit; -+ e_FmPortDualRateLimiterScaleDown rateLimitDivider; -+ bool enBufPoolDepletion; -+ uint16_t liodnOffset; -+ uint16_t liodnBase; -+ t_FmExtPools extBufPools; -+ e_FmDmaSwapOption dmaSwapData; -+ e_FmDmaCacheOption dmaIntContextCacheAttr; -+ e_FmDmaCacheOption dmaHeaderCacheAttr; -+ e_FmDmaCacheOption dmaScatterGatherCacheAttr; -+ bool dmaReadOptimize; -+ bool dmaWriteOptimize; -+ uint32_t txFifoMinFillLevel; -+ uint32_t txFifoLowComfLevel; -+ uint32_t rxFifoPriElevationLevel; -+ uint32_t rxFifoThreshold; -+ t_FmSpBufMargins bufMargins; -+ t_FmSpIntContextDataCopy intContext; -+ bool syncReq; -+ e_FmPortColor color; -+ fmPortFrameErrSelect_t errorsToDiscard; -+ fmPortFrameErrSelect_t errorsToEnq; -+ bool forwardReuseIntContext; -+ t_FmBufferPrefixContent bufferPrefixContent; -+ t_FmBackupBmPools *p_BackupBmPools; -+ bool dontReleaseBuf; -+ bool setNumOfTasks; -+ bool setNumOfOpenDmas; -+ bool setSizeOfFifo; -+#if (DPAA_VERSION >= 11) -+ bool noScatherGather; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 -+ bool bcbWorkaround; -+#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */ -+} t_FmPortDriverParam; -+ -+ -+typedef struct t_FmPortRxPoolsParams -+{ -+ uint8_t numOfPools; -+ uint16_t secondLargestBufSize; -+ uint16_t largestBufSize; -+} t_FmPortRxPoolsParams; -+ -+typedef struct t_FmPortDsarVars { -+ t_Handle *autoResOffsets; -+ t_FmPortDsarTablesSizes *autoResMaxSizes; -+ uint32_t fmbm_tcfg; -+ uint32_t fmbm_tcmne; -+ uint32_t fmbm_rfne; -+ uint32_t fmbm_rfpne; -+ uint32_t fmbm_rcfg; -+ bool dsarEnabledParser; -+} t_FmPortDsarVars; -+typedef struct { -+ struct fman_port port; -+ t_Handle h_Fm; -+ t_Handle h_FmPcd; -+ t_Handle h_FmMuram; -+ t_FmRevisionInfo fmRevInfo; -+ uint8_t portId; -+ e_FmPortType portType; -+ int enabled; -+ char name[MODULE_NAME_SIZE]; -+ uint8_t hardwarePortId; -+ uint16_t fmClkFreq; -+ t_FmPortQmiRegs *p_FmPortQmiRegs; -+ u_FmPortBmiRegs *p_FmPortBmiRegs; -+ t_FmPortPrsRegs *p_FmPortPrsRegs; -+ fmPcdEngines_t pcdEngines; -+ uint32_t savedBmiNia; -+ uint8_t netEnvId; -+ uint32_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)]; -+ uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS]; -+ uint8_t privateInfo; -+ uint32_t schemesPerPortVector; -+ bool useClsPlan; -+ uint8_t clsPlanGrpId; -+ t_Handle ccTreeId; -+ t_Handle completeArg; -+ void (*f_Complete)(t_Handle arg); -+ t_FmSpBufferOffsets bufferOffsets; -+ /* Independent-Mode parameters support */ -+ bool imEn; -+ t_FmMacIm im; -+ volatile bool lock; -+ t_Handle h_Spinlock; -+ t_FmPortExceptionCallback *f_Exception; -+ t_Handle h_App; -+ uint8_t internalBufferOffset; -+ uint8_t fmanCtrlEventId; -+ uint32_t exceptions; -+ bool polling; -+ t_FmExtPools extBufPools; -+ uint32_t requiredAction; -+ uint32_t savedQmiPnen; -+ uint32_t savedBmiFene; -+ uint32_t savedBmiFpne; -+ uint32_t savedBmiCmne; -+ uint32_t savedBmiOfp; -+ uint32_t savedNonRxQmiRegsPndn; -+ uint32_t origNonRxQmiRegsPndn; -+ int savedPrsStartOffset; -+ bool includeInPrsStatistics; -+ uint16_t maxFrameLength; -+ t_FmFmanCtrl orFmanCtrl; -+ t_FmPortRsrc openDmas; -+ t_FmPortRsrc tasks; -+ t_FmPortRsrc fifoBufs; -+ t_FmPortRxPoolsParams rxPoolsParams; -+// bool explicitUserSizeOfFifo; -+ t_Handle h_IpReassemblyManip; -+ t_Handle h_CapwapReassemblyManip; -+ t_Handle h_ReassemblyTree; -+ uint64_t fmMuramPhysBaseAddr; -+#if (DPAA_VERSION >= 11) -+ bool vspe; -+ uint8_t dfltRelativeId; -+ e_FmPortGprFuncType gprFunc; -+ t_FmPcdCtrlParamsPage *p_ParamsPage; -+#endif /* (DPAA_VERSION >= 11) */ -+ t_FmPortDsarVars deepSleepVars; -+ t_FmPortDriverParam *p_FmPortDriverParam; -+} t_FmPort; -+ -+ -+void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams); -+t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort); -+ -+t_Error FmPortImInit(t_FmPort *p_FmPort); -+void FmPortImFree(t_FmPort *p_FmPort); -+ -+t_Error FmPortImEnable (t_FmPort *p_FmPort); -+t_Error FmPortImDisable (t_FmPort *p_FmPort); -+t_Error FmPortImRx (t_FmPort *p_FmPort); -+ -+void FmPortSetMacsecLcv(t_Handle h_FmPort); -+void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci); -+ -+ -+t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas); -+t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks); -+t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo); -+ -+static __inline__ uint8_t * BdBufferGet (t_PhysToVirt *f_PhysToVirt, t_FmImBd *p_Bd) -+{ -+ uint64_t physAddr = (uint64_t)((uint64_t)GET_UINT8(p_Bd->buff.high) << 32); -+ physAddr |= GET_UINT32(p_Bd->buff.low); -+ -+ return (uint8_t *)f_PhysToVirt((physAddress_t)(physAddr)); -+} -+ -+static __inline__ void SET_ADDR(volatile t_FmPhysAddr *fmPhysAddr, uint64_t value) -+{ -+ WRITE_UINT8(fmPhysAddr->high,(uint8_t)((value & 0x000000ff00000000LL) >> 32)); -+ WRITE_UINT32(fmPhysAddr->low,(uint32_t)value); -+} -+ -+static __inline__ void BdBufferSet(t_VirtToPhys *f_VirtToPhys, t_FmImBd *p_Bd, uint8_t *p_Buffer) -+{ -+ uint64_t physAddr = (uint64_t)(f_VirtToPhys(p_Buffer)); -+ SET_ADDR(&p_Bd->buff, physAddr); -+} -+ -+static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id) -+{ -+ if (id < p_FmPort->im.bdRingSize-1) -+ return (uint16_t)(id+1); -+ else -+ return 0; -+} -+ -+void FM_PORT_Dsar_DumpRegs(void); -+ -+ -+#endif /* __FM_PORT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h -@@ -0,0 +1,494 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ @File fm_port_dsar.h -+ -+ @Description Deep Sleep Auto Response project - common module header file. -+ -+ Author - Eyal Harari -+ -+ @Cautions See the FMan Controller spec and design document for more information. -+*//***************************************************************************/ -+ -+#ifndef __FM_PORT_DSAR_H_ -+#define __FM_PORT_DSAR_H_ -+ -+#define DSAR_GETSER_MASK 0xFF0000FF -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4) -+ Refer to the FMan Controller spec for more details. -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */ -+ uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ -+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ -+ uint16_t reserved; -+} _PackedType t_DsarArpBindingEntry; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response Address Resolution Protocol Statistics Descriptor -+ Refer to the FMan Controller spec for more details. -+ 0x00 INVAL_CNT Invalid ARP IPv4-Ethernet counter -+ 0x04 ECHO_CNT Echo counter -+ 0x08 CD_CNT Conflict Detection counter -+ 0x0C AR_CNT Auto-Response counter -+ 0x10 RATM_CNT Replies Addressed To Me counter -+ 0x14 UKOP_CNT Unknown Operation counter -+ 0x18 NMTP_CNT Not my TPA counter -+ 0x1C NMVLAN_CNT Not My VLAN counter -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint32_t invalCnt; /**< Invalid ARP IPv4-Ethernet counter. */ -+ uint32_t echoCnt; /**< Echo counter. */ -+ uint32_t cdCnt; /**< Conflict Detection counter. */ -+ uint32_t arCnt; /**< Auto-Response counter. */ -+ uint32_t ratmCnt; /**< Replies Addressed To Me counter. */ -+ uint32_t ukopCnt; /**< Unknown Operation counter. */ -+ uint32_t nmtpCnt; /**< Not my TPA counter. */ -+ uint32_t nmVlanCnt; /**< Not My VLAN counter */ -+} _PackedType t_DsarArpStatistics; -+ -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response Address Resolution Protocol Descriptor -+ 0x0 0-15 Control bits [0-15]. Bit 15 = CDEN. -+ 0x2 0-15 NumOfBindings Number of entries in the binding list. -+ 0x4 0-15 BindingsPointer Bindings Pointer. This points to an IPv4-MAC Addresses Bindings list. -+ 0x6 0-15 -+ 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ARP Descriptors statistics data structure. -+ 0xA 0-15 -+ 0xC 0-15 Reserved Reserved. Must be cleared. -+ 0xE 015 -+ -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint16_t control; /** Control bits [0-15]. Bit 15 = CDEN */ -+ uint16_t numOfBindings; /**< Number of VLAN-IPv4 */ -+ uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */ -+ uint32_t p_Statistics; /**< Statistics Data Structure pointer. */ -+ uint32_t reserved1; /**< Reserved. */ -+} _PackedType t_DsarArpDescriptor; -+ -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4) -+ Refer to the FMan Controller spec for more details. -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */ -+ uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ -+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ -+ uint16_t reserved; -+} _PackedType t_DsarIcmpV4BindingEntry; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor -+ Refer to the FMan Controller spec for more details. -+ 0x00 INVAL_CNT Invalid ICMPv4 header counter -+ 0x04 NMVLAN_CNT Not My VLAN counter -+ 0x08 NMIP_CNT Not My IP counter -+ 0x0C AR_CNT Auto-Response counter -+ 0x10 CSERR_CNT Checksum Error counter -+ 0x14 Reserved Reserved -+ 0x18 Reserved Reserved -+ 0x1C Reserved Reserved -+ -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */ -+ uint32_t nmVlanCnt; /**< Not My VLAN counter */ -+ uint32_t nmIpCnt; /**< Not My IP counter */ -+ uint32_t arCnt; /**< Auto-Response counter */ -+ uint32_t cserrCnt; /**< Checksum Error counter */ -+ uint32_t reserved0; /**< Reserved */ -+ uint32_t reserved1; /**< Reserved */ -+ uint32_t reserved2; /**< Reserved */ -+} _PackedType t_DsarIcmpV4Statistics; -+ -+ -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response ICMPv4 Descriptor -+ 0x0 0-15 Control bits [0-15] -+ 0x2 0-15 NumOfBindings Number of entries in the binding list. -+ 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list. -+ 0x6 0-15 -+ 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure. -+ 0xA 0-15 -+ 0xC 0-15 Reserved Reserved. Must be cleared. -+ 0xE 015 -+ -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint16_t control; /** Control bits [0-15]. */ -+ uint16_t numOfBindings; /**< Number of VLAN-IPv4 */ -+ uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */ -+ uint32_t p_Statistics; /**< Statistics Data Structure pointer. */ -+ uint32_t reserved1; /**< Reserved. */ -+} _PackedType t_DsarIcmpV4Descriptor; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4) -+ The 4 left-most bits (15:12) of the VlanId parameter are control flags. -+ Flags[3:1] (VlanId[15:13]): Reserved, should be cleared. -+ Flags[0] (VlanId[12]): Temporary address. -+ • 0 - Assigned IP address. -+ • 1- Temporary (tentative) IP address. -+ Refer to the FMan Controller spec for more details. -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint32_t ipv6Addr[4]; /*!< 3 * 32 bit IPv4 Address. */ -+ uint16_t resFlags:4; /*!< reserved flags. should be cleared */ -+ uint16_t vlanId:12; /*!< 12 bits VLAN ID. */ -+ /*!< This field should be 0x000 for an entry with no VLAN tag or a null VLAN ID. */ -+ uint16_t reserved; -+} _PackedType t_DsarIcmpV6BindingEntry; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor -+ Refer to the FMan Controller spec for more details. -+ 0x00 INVAL_CNT Invalid ICMPv4 header counter -+ 0x04 NMVLAN_CNT Not My VLAN counter -+ 0x08 NMIP_CNT Not My IP counter -+ 0x0C AR_CNT Auto-Response counter -+ 0x10 CSERR_CNT Checksum Error counter -+ 0x14 MCAST_CNT Multicast counter -+ 0x18 Reserved Reserved -+ 0x1C Reserved Reserved -+ -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */ -+ uint32_t nmVlanCnt; /**< Not My VLAN counter */ -+ uint32_t nmIpCnt; /**< Not My IP counter */ -+ uint32_t arCnt; /**< Auto-Response counter */ -+ uint32_t reserved1; /**< Reserved */ -+ uint32_t reserved2; /**< Reserved */ -+ uint32_t reserved3; /**< Reserved */ -+ uint32_t reserved4; /**< Reserved */ -+} _PackedType t_DsarIcmpV6Statistics; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response Neighbor Discovery Statistics Descriptor -+ 0x00 INVAL_CNT Invalid Neighbor Discovery message counter -+ 0x04 NMVLAN_CNT Not My VLAN counter -+ 0x08 NMIP_CNT Not My IP counter -+ 0x0C AR_CNT Auto-Response counter -+ 0x10 CSERR_CNT Checksum Error counter -+ 0x14 USADVERT_CNT Unsolicited Neighbor Advertisements counter -+ 0x18 NMMCAST_CNT Not My Multicast group counter -+ 0x1C NSLLA_CNT No Source Link-Layer Address counter. Indicates that there was a match on a Target -+ Address of a packet that its source IP address is a unicast address, but the ICMPv6 -+ Source Link-layer Address option is omitted -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */ -+ uint32_t nmVlanCnt; /**< Not My VLAN counter */ -+ uint32_t nmIpCnt; /**< Not My IP counter */ -+ uint32_t arCnt; /**< Auto-Response counter */ -+ uint32_t reserved1; /**< Reserved */ -+ uint32_t usadvertCnt; /**< Unsolicited Neighbor Advertisements counter */ -+ uint32_t nmmcastCnt; /**< Not My Multicast group counter */ -+ uint32_t nsllaCnt; /**< No Source Link-Layer Address counter */ -+} _PackedType t_NdStatistics; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response ICMPv6 Descriptor -+ 0x0 0-15 Control bits [0-15] -+ 0x2 0-15 NumOfBindings Number of entries in the binding list. -+ 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list. -+ 0x6 0-15 -+ 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure. -+ 0xA 0-15 -+ 0xC 0-15 Reserved Reserved. Must be cleared. -+ 0xE 015 -+ -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint16_t control; /** Control bits [0-15]. */ -+ uint16_t numOfBindings; /**< Number of VLAN-IPv6 */ -+ uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */ -+ uint32_t p_Statistics; /**< Statistics Data Structure pointer. */ -+ uint32_t reserved1; /**< Reserved. */ -+} _PackedType t_DsarIcmpV6Descriptor; -+ -+ -+/**************************************************************************//** -+ @Description Internet Control Message Protocol (ICMPv6) Echo message header -+ The fields names are taken from RFC 4443. -+*//***************************************************************************/ -+/* 0 1 2 3 */ -+/* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 */ -+/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -+/* | Type | Code | Checksum | */ -+/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -+/* | Identifier | Sequence Number | */ -+/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -+/* | Data ... */ -+/* +-+-+-+-+- */ -+typedef _Packed struct -+{ -+ uint8_t type; -+ uint8_t code; -+ uint16_t checksum; -+ uint16_t identifier; -+ uint16_t sequenceNumber; -+} _PackedType t_IcmpV6EchoHdr; -+ -+/**************************************************************************//** -+ @Description Internet Control Message Protocol (ICMPv6) -+ Neighbor Solicitation/Advertisement header -+ The fields names are taken from RFC 4861. -+ The R/S/O fields are valid for Neighbor Advertisement only -+*//***************************************************************************/ -+/* 0 1 2 3 -+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | Type | Code | Checksum | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * |R|S|O| Reserved | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | | -+ * + + -+ * | | -+ * + Target Address + -+ * | | -+ * + + -+ * | | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | Options ... -+ * +-+-+-+-+-+-+-+-+-+-+-+- -+ * -+ * Options Format: -+ * 0 1 2 3 -+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | Type | Length | Link-Layer Address ... | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ * | Link-Layer Address | -+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+*/ -+typedef _Packed struct -+{ -+ uint8_t type; -+ uint8_t code; -+ uint16_t checksum; -+ uint32_t router:1; -+ uint32_t solicited:1; -+ uint32_t override:1; -+ uint32_t reserved:29; -+ uint32_t targetAddr[4]; -+ uint8_t optionType; -+ uint8_t optionLength; -+ uint8_t linkLayerAddr[6]; -+} _PackedType t_IcmpV6NdHdr; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response ICMPv6 Descriptor -+ 0x0 0-15 Control bits [0-15] -+ 0x2 0-15 NumOfBindings Number of entries in the binding list. -+ 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list. -+ 0x6 0-15 -+ 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure. -+ 0xA 0-15 -+ 0xC 0-15 Reserved Reserved. Must be cleared. -+ 0xE 015 -+ -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint16_t control; /** Control bits [0-15]. */ -+ uint16_t numOfBindings; /**< Number of VLAN-IPv6 */ -+ uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */ -+ uint32_t p_Statistics; /**< Statistics Data Structure pointer. */ -+ uint32_t solicitedAddr; /**< Solicited Node Multicast Group Address */ -+} _PackedType t_DsarNdDescriptor; -+ -+/**************************************************************************//** -+@Description Deep Sleep Auto Response SNMP OIDs table entry -+ -+*//***************************************************************************/ -+typedef struct { -+ uint16_t oidSize; /**< Size in octets of the OID. */ -+ uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */ -+ uint32_t p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */ -+ uint32_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */ -+ uint32_t reserved; -+} t_OidsTblEntry; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry -+ Refer to the FMan Controller spec for more details. -+*//***************************************************************************/ -+typedef struct -+{ -+ uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */ -+ uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ -+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ -+ uint16_t reserved; -+} t_DsarSnmpIpv4AddrTblEntry; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry -+ Refer to the FMan Controller spec for more details. -+*//***************************************************************************/ -+#pragma pack(push,1) -+typedef struct -+{ -+ uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */ -+ uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ -+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ -+ uint16_t reserved; -+} t_DsarSnmpIpv6AddrTblEntry; -+#pragma pack(pop) -+ -+/**************************************************************************//** -+@Description Deep Sleep Auto Response SNMP statistics table -+ -+*//***************************************************************************/ -+typedef struct { -+ uint32_t snmpErrCnt; /**< Counts SNMP errors (wrong version, BER encoding, format). */ -+ uint32_t snmpCommunityErrCnt; /**< Counts messages that were dropped due to insufficient permission. */ -+ uint32_t snmpTotalDiscardCnt; /**< Counts any message that was dropped. */ -+ uint32_t snmpGetReqCnt; /**< Counts the number of get-request messages */ -+ uint32_t snmpGetNextReqCnt; /**< Counts the number of get-next-request messages */ -+} t_DsarSnmpStatistics; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response SNMP Descriptor -+ -+*//***************************************************************************/ -+typedef struct -+{ -+ uint16_t control; /**< Control bits [0-15]. */ -+ uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */ -+ uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */ -+ uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */ -+ uint32_t p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */ -+ uint32_t p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */ -+ uint32_t p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */ -+ uint32_t p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */ -+ uint32_t p_OidsTbl; /**< Pointer to OIDs table. */ -+ uint32_t oidsTblSize; /**< Number of entries in OIDs table. */ -+ uint32_t p_Statistics; /**< Pointer to SNMP statistics table. */ -+} t_DsarSnmpDescriptor; -+ -+/**************************************************************************//** -+@Description Deep Sleep Auto Response (Common) Statistics -+ -+*//***************************************************************************/ -+typedef _Packed struct { -+ uint32_t dsarDiscarded; -+ uint32_t dsarErrDiscarded; -+ uint32_t dsarFragDiscarded; -+ uint32_t dsarTunnelDiscarded; -+ uint32_t dsarArpDiscarded; -+ uint32_t dsarIpDiscarded; -+ uint32_t dsarTcpDiscarded; -+ uint32_t dsarUdpDiscarded; -+ uint32_t dsarIcmpV6ChecksumErr; /* ICMPv6 Checksum Error counter */ -+ uint32_t dsarIcmpV6OtherType; /* ICMPv6 'Other' type (not Echo or Neighbor Solicitaion/Advertisement counter */ -+ uint32_t dsarIcmpV4OtherType; /* ICMPv4 'Other' type (not Echo) counter */ -+} _PackedType t_ArStatistics; -+ -+ -+/**************************************************************************//** -+@Description Deep Sleep Auto Response TCP/UDP port filter table entry -+ -+*//***************************************************************************/ -+typedef _Packed struct { -+ uint32_t Ports; -+ uint32_t PortsMask; -+} _PackedType t_PortTblEntry; -+ -+ -+ -+/**************************************************************************//** -+@Description Deep Sleep Auto Response Common Parameters Descriptor -+ -+*//***************************************************************************/ -+typedef _Packed struct { -+ uint8_t arTxPort; /* 0x00 0-7 Auto Response Transmit Port number */ -+ uint8_t controlBits; /* 0x00 8-15 Auto Response control bits */ -+ uint16_t res1; /* 0x00 16-31 Reserved */ -+ uint32_t activeHPNIA; /* 0x04 0-31 Active mode Hardware Parser NIA */ -+ uint16_t snmpPort; /* 0x08 0-15 SNMP Port. */ -+ uint8_t macStationAddr[6]; /* 0x08 16-31 and 0x0C 0-31 MAC Station Address */ -+ uint8_t res2; /* 0x10 0-7 Reserved */ -+ uint8_t filterControl; /* 0x10 8-15 Filtering Control Bits. */ -+ uint16_t tcpControlPass; /* 0x10 16-31 TCP control pass flags */ -+ uint8_t ipProtocolTblSize; /* 0x14 0-7 IP Protocol Table Size. */ -+ uint8_t udpPortTblSize; /* 0x14 8-15 UDP Port Table Size. */ -+ uint8_t tcpPortTblSize; /* 0x14 16-23 TCP Port Table Size. */ -+ uint8_t res3; /* 0x14 24-31 Reserved */ -+ uint32_t p_IpProtocolFiltTbl; /* 0x18 0-31 Pointer to IP Protocol Filter Table */ -+ uint32_t p_UdpPortFiltTbl; /* 0x1C 0-31 Pointer to UDP Port Filter Table */ -+ uint32_t p_TcpPortFiltTbl; /* 0x20 0-31 Pointer to TCP Port Filter Table */ -+ uint32_t res4; /* 0x24 Reserved */ -+ uint32_t p_ArpDescriptor; /* 0x28 0-31 ARP Descriptor Pointer. */ -+ uint32_t p_NdDescriptor; /* 0x2C 0-31 Neighbor Discovery Descriptor. */ -+ uint32_t p_IcmpV4Descriptor; /* 0x30 0-31 ICMPv4 Descriptor pointer. */ -+ uint32_t p_IcmpV6Descriptor; /* 0x34 0-31 ICMPv6 Descriptor pointer. */ -+ uint32_t p_SnmpDescriptor; /* 0x38 0-31 SNMP Descriptor pointer. */ -+ uint32_t p_ArStats; /* 0x3C 0-31 Pointer to Auto Response Statistics */ -+} _PackedType t_ArCommonDesc; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+/* t_ArCommonDesc.filterControl bits */ -+#define IP_PROT_TBL_PASS_MASK 0x08 -+#define UDP_PORT_TBL_PASS_MASK 0x04 -+#define TCP_PORT_TBL_PASS_MASK 0x02 -+ -+/* Offset of TCF flags within TCP packet */ -+#define TCP_FLAGS_OFFSET 12 -+ -+ -+#endif /* __FM_PORT_DSAR_H_ */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c -@@ -0,0 +1,753 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_port_im.c -+ -+ @Description FM Port Independent-Mode ... -+*//***************************************************************************/ -+#include "std_ext.h" -+#include "string_ext.h" -+#include "error_ext.h" -+#include "memcpy_ext.h" -+#include "fm_muram_ext.h" -+ -+#include "fm_port.h" -+ -+ -+#define TX_CONF_STATUS_UNSENT 0x1 -+ -+ -+typedef enum e_TxConfType -+{ -+ e_TX_CONF_TYPE_CHECK = 0 /**< check if all the buffers were touched by the muxator, no confirmation callback */ -+ ,e_TX_CONF_TYPE_CALLBACK = 1 /**< confirm to user all the available sent buffers */ -+ ,e_TX_CONF_TYPE_FLUSH = 3 /**< confirm all buffers plus the unsent one with an appropriate status */ -+} e_TxConfType; -+ -+ -+static void ImException(t_Handle h_FmPort, uint32_t event) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ ASSERT_COND(((event & (IM_EV_RX | IM_EV_BSY)) && FmIsMaster(p_FmPort->h_Fm)) || -+ !FmIsMaster(p_FmPort->h_Fm)); -+ -+ if (event & IM_EV_RX) -+ FmPortImRx(p_FmPort); -+ if ((event & IM_EV_BSY) && p_FmPort->f_Exception) -+ p_FmPort->f_Exception(p_FmPort->h_App, e_FM_PORT_EXCEPTION_IM_BUSY); -+} -+ -+ -+static t_Error TxConf(t_FmPort *p_FmPort, e_TxConfType confType) -+{ -+ t_Error retVal = E_BUSY; -+ uint32_t bdStatus; -+ uint16_t savedStartBdId, confBdId; -+ -+ ASSERT_COND(p_FmPort); -+ -+ /* -+ if (confType==e_TX_CONF_TYPE_CHECK) -+ return (WfqEntryIsQueueEmpty(p_FmPort->im.h_WfqEntry) ? E_OK : E_BUSY); -+ */ -+ -+ confBdId = savedStartBdId = p_FmPort->im.currBdId; -+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId)); -+ -+ /* If R bit is set, we don't enter, or we break. -+ we run till we get to R, or complete the loop */ -+ while ((!(bdStatus & BD_R_E) || (confType == e_TX_CONF_TYPE_FLUSH)) && (retVal != E_OK)) -+ { -+ if (confType & e_TX_CONF_TYPE_CALLBACK) /* if it is confirmation with user callbacks */ -+ BD_STATUS_AND_LENGTH_SET(BD_GET(confBdId), 0); -+ -+ /* case 1: R bit is 0 and Length is set -> confirm! */ -+ if ((confType & e_TX_CONF_TYPE_CALLBACK) && (bdStatus & BD_LENGTH_MASK)) -+ { -+ if (p_FmPort->im.f_TxConf) -+ { -+ if ((confType == e_TX_CONF_TYPE_FLUSH) && (bdStatus & BD_R_E)) -+ p_FmPort->im.f_TxConf(p_FmPort->h_App, -+ BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)), -+ TX_CONF_STATUS_UNSENT, -+ p_FmPort->im.p_BdShadow[confBdId]); -+ else -+ p_FmPort->im.f_TxConf(p_FmPort->h_App, -+ BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)), -+ 0, -+ p_FmPort->im.p_BdShadow[confBdId]); -+ } -+ } -+ /* case 2: R bit is 0 and Length is 0 -> not used yet, nop! */ -+ -+ confBdId = GetNextBdId(p_FmPort, confBdId); -+ if (confBdId == savedStartBdId) -+ retVal = E_OK; -+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId)); -+ } -+ -+ return retVal; -+} -+ -+t_Error FmPortImEnable(t_FmPort *p_FmPort) -+{ -+ uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode); -+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg & ~IM_MODE_GRC_STP)); -+ return E_OK; -+} -+ -+t_Error FmPortImDisable(t_FmPort *p_FmPort) -+{ -+ uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode); -+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg | IM_MODE_GRC_STP)); -+ return E_OK; -+} -+ -+t_Error FmPortImRx(t_FmPort *p_FmPort) -+{ -+ t_Handle h_CurrUserPriv, h_NewUserPriv; -+ uint32_t bdStatus; -+ volatile uint8_t buffPos; -+ uint16_t length; -+ uint16_t errors; -+ uint8_t *p_CurData, *p_Data; -+ uint32_t flags; -+ -+ ASSERT_COND(p_FmPort); -+ -+ flags = XX_LockIntrSpinlock(p_FmPort->h_Spinlock); -+ if (p_FmPort->lock) -+ { -+ XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags); -+ return E_OK; -+ } -+ p_FmPort->lock = TRUE; -+ XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags); -+ -+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId)); -+ -+ while (!(bdStatus & BD_R_E)) /* while there is data in the Rx BD */ -+ { -+ if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_NewUserPriv)) == NULL) -+ { -+ p_FmPort->lock = FALSE; -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer")); -+ } -+ -+ if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID) -+ p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId; -+ -+ p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId)); -+ h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]; -+ length = (uint16_t)((bdStatus & BD_L) ? -+ ((bdStatus & BD_LENGTH_MASK) - p_FmPort->im.rxFrameAccumLength): -+ (bdStatus & BD_LENGTH_MASK)); -+ p_FmPort->im.rxFrameAccumLength += length; -+ -+ /* determine whether buffer is first, last, first and last (single */ -+ /* buffer frame) or middle (not first and not last) */ -+ buffPos = (uint8_t)((p_FmPort->im.currBdId == p_FmPort->im.firstBdOfFrameId) ? -+ ((bdStatus & BD_L) ? SINGLE_BUF : FIRST_BUF) : -+ ((bdStatus & BD_L) ? LAST_BUF : MIDDLE_BUF)); -+ -+ if (bdStatus & BD_L) -+ { -+ p_FmPort->im.rxFrameAccumLength = 0; -+ p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID; -+ } -+ -+ BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data); -+ -+ BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), BD_R_E); -+ -+ errors = (uint16_t)((bdStatus & BD_RX_ERRORS) >> 16); -+ p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_NewUserPriv; -+ -+ p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId); -+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4)); -+ /* Pass the buffer if one of the conditions is true: -+ - There are no errors -+ - This is a part of a larger frame ( the application has already received some buffers ) */ -+ if ((buffPos != SINGLE_BUF) || !errors) -+ { -+ if (p_FmPort->im.f_RxStore(p_FmPort->h_App, -+ p_CurData, -+ length, -+ errors, -+ buffPos, -+ h_CurrUserPriv) == e_RX_STORE_RESPONSE_PAUSE) -+ break; -+ } -+ else if (p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool, -+ p_CurData, -+ h_CurrUserPriv)) -+ { -+ p_FmPort->lock = FALSE; -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Failed freeing data buffer")); -+ } -+ -+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId)); -+ } -+ p_FmPort->lock = FALSE; -+ return E_OK; -+} -+ -+void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams) -+{ -+ ASSERT_COND(p_FmPort); -+ -+ SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->im.h_FmMuram = p_FmPortParams->specificParams.imRxTxParams.h_FmMuram; -+ p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.imRxTxParams.liodnOffset; -+ p_FmPort->im.dataMemId = p_FmPortParams->specificParams.imRxTxParams.dataMemId; -+ p_FmPort->im.dataMemAttributes = p_FmPortParams->specificParams.imRxTxParams.dataMemAttributes; -+ -+ p_FmPort->im.fwExtStructsMemId = DEFAULT_PORT_ImfwExtStructsMemId; -+ p_FmPort->im.fwExtStructsMemAttr = DEFAULT_PORT_ImfwExtStructsMemAttr; -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) || -+ (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ { -+ p_FmPort->im.rxPool.h_BufferPool = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.h_BufferPool; -+ p_FmPort->im.rxPool.f_GetBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_GetBuf; -+ p_FmPort->im.rxPool.f_PutBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PutBuf; -+ p_FmPort->im.rxPool.bufferSize = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.bufferSize; -+ p_FmPort->im.rxPool.f_PhysToVirt = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PhysToVirt; -+ if (!p_FmPort->im.rxPool.f_PhysToVirt) -+ p_FmPort->im.rxPool.f_PhysToVirt = XX_PhysToVirt; -+ p_FmPort->im.rxPool.f_VirtToPhys = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_VirtToPhys; -+ if (!p_FmPort->im.rxPool.f_VirtToPhys) -+ p_FmPort->im.rxPool.f_VirtToPhys = XX_VirtToPhys; -+ p_FmPort->im.f_RxStore = p_FmPortParams->specificParams.imRxTxParams.f_RxStore; -+ -+ p_FmPort->im.mrblr = 0x8000; -+ while (p_FmPort->im.mrblr) -+ { -+ if (p_FmPort->im.rxPool.bufferSize & p_FmPort->im.mrblr) -+ break; -+ p_FmPort->im.mrblr >>= 1; -+ } -+ if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize) -+ DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr)); -+ p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength; -+ p_FmPort->exceptions = DEFAULT_PORT_exception; -+ if (FmIsMaster(p_FmPort->h_Fm)) -+ p_FmPort->polling = FALSE; -+ else -+ p_FmPort->polling = TRUE; -+ p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ; -+ } -+ else -+ { -+ p_FmPort->im.f_TxConf = p_FmPortParams->specificParams.imRxTxParams.f_TxConf; -+ -+ p_FmPort->im.bdRingSize = DEFAULT_PORT_txBdRingLength; -+ } -+} -+ -+t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort) -+{ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) && -+ (p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && -+ (p_FmPort->portType != e_FM_PORT_TYPE_TX) && -+ (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) || -+ (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ { -+ if (!POWER_OF_2(p_FmPort->im.mrblr)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!")); -+ if (p_FmPort->im.mrblr < 256) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!")); -+ if (p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1)); -+ } -+ -+ return E_OK; -+} -+ -+t_Error FmPortImInit(t_FmPort *p_FmPort) -+{ -+ t_FmImBd *p_Bd=NULL; -+ t_Handle h_BufContext; -+ uint64_t tmpPhysBase; -+ uint16_t log2Num; -+ uint8_t *p_Data/*, *p_Tmp*/; -+ int i; -+ t_Error err; -+ uint16_t tmpReg16; -+ uint32_t tmpReg32; -+ -+ ASSERT_COND(p_FmPort); -+ -+ p_FmPort->im.p_FmPortImPram = -+ (t_FmPortImPram *)FM_MURAM_AllocMem(p_FmPort->im.h_FmMuram, sizeof(t_FmPortImPram), IM_PRAM_ALIGN); -+ if (!p_FmPort->im.p_FmPortImPram) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Parameter-RAM!!!")); -+ WRITE_BLOCK(p_FmPort->im.p_FmPortImPram, 0, sizeof(t_FmPortImPram)); -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) || -+ (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ { -+ p_FmPort->im.p_BdRing = -+ (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), -+ p_FmPort->im.fwExtStructsMemId, -+ 4); -+ if (!p_FmPort->im.p_BdRing) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!")); -+ IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize)); -+ -+ p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize)); -+ if (!p_FmPort->im.p_BdShadow) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!")); -+ memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize)); -+ -+ /* Initialize the Rx-BD ring */ -+ for (i=0; iim.bdRingSize; i++) -+ { -+ p_Bd = BD_GET(i); -+ BD_STATUS_AND_LENGTH_SET (p_Bd, BD_R_E); -+ -+ if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_BufContext)) == NULL) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer")); -+ BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, p_Bd, p_Data); -+ p_FmPort->im.p_BdShadow[i] = h_BufContext; -+ } -+ -+ if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) || -+ (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE)) -+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2)); -+ else -+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2)); -+ -+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr, -+ (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - -+ p_FmPort->fmMuramPhysBaseAddr + 0x20)); -+ -+ LOG2((uint64_t)p_FmPort->im.mrblr, log2Num); -+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num); -+ -+ /* Initialize Rx QD */ -+ tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing)); -+ SET_ADDR(&p_FmPort->im.p_FmPortImPram->rxQd.bdRingBase, tmpPhysBase); -+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize)); -+ -+ /* Update the IM PRAM address in the BMI */ -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid, -+ (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - -+ p_FmPort->fmMuramPhysBaseAddr)); -+ if (!p_FmPort->polling || p_FmPort->exceptions) -+ { -+ /* Allocate, configure and register interrupts */ -+ err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK)); -+ tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK); -+ tmpReg32 = 0; -+ -+ if (p_FmPort->exceptions & IM_EV_BSY) -+ { -+ tmpReg16 |= IM_RXQD_BSYINTM; -+ tmpReg32 |= IM_EV_BSY; -+ } -+ if (!p_FmPort->polling) -+ { -+ tmpReg16 |= IM_RXQD_RXFINTM; -+ tmpReg32 |= IM_EV_RX; -+ } -+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16); -+ -+ FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException , (t_Handle)p_FmPort); -+ -+ FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32); -+ } -+ else -+ p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ; -+ } -+ else -+ { -+ p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4); -+ if (!p_FmPort->im.p_BdRing) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Tx BD ring!!!")); -+ IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize)); -+ -+ p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize)); -+ if (!p_FmPort->im.p_BdShadow) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!")); -+ memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize)); -+ p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID; -+ -+ if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) || -+ (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE)) -+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2)); -+ else -+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2)); -+ -+ WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr, -+ (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - -+ p_FmPort->fmMuramPhysBaseAddr + 0x40)); -+ -+ /* Initialize Tx QD */ -+ tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing)); -+ SET_ADDR(&p_FmPort->im.p_FmPortImPram->txQd.bdRingBase, tmpPhysBase); -+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize)); -+ -+ /* Update the IM PRAM address in the BMI */ -+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid, -+ (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) - -+ p_FmPort->fmMuramPhysBaseAddr)); -+ } -+ -+ -+ return E_OK; -+} -+ -+void FmPortImFree(t_FmPort *p_FmPort) -+{ -+ uint32_t bdStatus; -+ uint8_t *p_CurData; -+ -+ ASSERT_COND(p_FmPort); -+ ASSERT_COND(p_FmPort->im.p_FmPortImPram); -+ -+ if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) || -+ (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)) -+ { -+ if (!p_FmPort->polling || p_FmPort->exceptions) -+ { -+ /* Deallocate and unregister interrupts */ -+ FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0); -+ -+ FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId); -+ -+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0); -+ -+ FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId); -+ } -+ /* Try first clean what has received */ -+ FmPortImRx(p_FmPort); -+ -+ /* Now, get rid of the the empty buffer! */ -+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId)); -+ -+ while (bdStatus & BD_R_E) /* while there is data in the Rx BD */ -+ { -+ p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId)); -+ -+ BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), NULL); -+ BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), 0); -+ -+ p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool, -+ p_CurData, -+ p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]); -+ -+ p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId); -+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId)); -+ } -+ } -+ else -+ TxConf(p_FmPort, e_TX_CONF_TYPE_FLUSH); -+ -+ FM_MURAM_FreeMem(p_FmPort->im.h_FmMuram, p_FmPort->im.p_FmPortImPram); -+ -+ if (p_FmPort->im.p_BdShadow) -+ XX_Free(p_FmPort->im.p_BdShadow); -+ -+ if (p_FmPort->im.p_BdRing) -+ XX_FreeSmart(p_FmPort->im.p_BdRing); -+} -+ -+ -+t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->im.mrblr = newVal; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->im.bdRingSize = newVal; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->im.bdRingSize = newVal; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort, -+ uint8_t memId, -+ uint32_t memAttributes) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ p_FmPort->im.fwExtStructsMemId = memId; -+ p_FmPort->im.fwExtStructsMemAttr = memAttributes; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only")); -+ -+ if (!FmIsMaster(p_FmPort->h_Fm)) -+ RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available on master-partition only;" -+ "in guest-partitions, IM is always in polling!")); -+ -+ p_FmPort->polling = TRUE; -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ t_Error err; -+ uint16_t tmpReg16; -+ uint32_t tmpReg32; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ if (exception == e_FM_PORT_EXCEPTION_IM_BUSY) -+ { -+ if (enable) -+ { -+ p_FmPort->exceptions |= IM_EV_BSY; -+ if (p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ) -+ { -+ /* Allocate, configure and register interrupts */ -+ err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK)); -+ -+ FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException, (t_Handle)p_FmPort); -+ tmpReg16 = (uint16_t)((p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK) | IM_RXQD_BSYINTM); -+ tmpReg32 = IM_EV_BSY; -+ } -+ else -+ { -+ tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) | IM_RXQD_BSYINTM); -+ tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) | IM_EV_BSY; -+ } -+ -+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16); -+ FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32); -+ } -+ else -+ { -+ p_FmPort->exceptions &= ~IM_EV_BSY; -+ if (!p_FmPort->exceptions && p_FmPort->polling) -+ { -+ FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId); -+ FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId); -+ FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0); -+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0); -+ p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ; -+ } -+ else -+ { -+ tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) & ~IM_RXQD_BSYINTM); -+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16); -+ tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) & ~IM_EV_BSY; -+ FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32); -+ } -+ } -+ } -+ else -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Invalid exception.")); -+ -+ return E_OK; -+} -+ -+t_Error FM_PORT_ImTx( t_Handle h_FmPort, -+ uint8_t *p_Data, -+ uint16_t length, -+ bool lastBuffer, -+ t_Handle h_BufContext) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ uint16_t nextBdId; -+ uint32_t bdStatus, nextBdStatus; -+ bool firstBuffer; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId)); -+ nextBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId); -+ nextBdStatus = BD_STATUS_AND_LENGTH(BD_GET(nextBdId)); -+ -+ if (!(bdStatus & BD_R_E) && !(nextBdStatus & BD_R_E)) -+ { -+ /* Confirm the current BD - BD is available */ -+ if ((bdStatus & BD_LENGTH_MASK) && (p_FmPort->im.f_TxConf)) -+ p_FmPort->im.f_TxConf (p_FmPort->h_App, -+ BdBufferGet(XX_PhysToVirt, BD_GET(p_FmPort->im.currBdId)), -+ 0, -+ p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]); -+ -+ bdStatus = length; -+ -+ /* if this is the first BD of a frame */ -+ if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID) -+ { -+ firstBuffer = TRUE; -+ p_FmPort->im.txFirstBdStatus = (bdStatus | BD_R_E); -+ -+ if (!lastBuffer) -+ p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId; -+ } -+ else -+ firstBuffer = FALSE; -+ -+ BdBufferSet(XX_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data); -+ p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_BufContext; -+ -+ /* deal with last */ -+ if (lastBuffer) -+ { -+ /* if single buffer frame */ -+ if (firstBuffer) -+ BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), p_FmPort->im.txFirstBdStatus | BD_L); -+ else -+ { -+ /* Set the last BD of the frame */ -+ BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), (bdStatus | BD_R_E | BD_L)); -+ /* Set the first BD of the frame */ -+ BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.firstBdOfFrameId), p_FmPort->im.txFirstBdStatus); -+ p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID; -+ } -+ WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.offsetIn, (uint16_t)(GetNextBdId(p_FmPort, p_FmPort->im.currBdId)<<4)); -+ } -+ else if (!firstBuffer) /* mid frame buffer */ -+ BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), bdStatus | BD_R_E); -+ -+ p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId); -+ } -+ else -+ { -+ /* Discard current frame. Return error. */ -+ if (p_FmPort->im.firstBdOfFrameId != IM_ILEGAL_BD_ID) -+ { -+ /* Error: No free BD */ -+ /* Response: Discard current frame. Return error. */ -+ uint16_t cleanBdId = p_FmPort->im.firstBdOfFrameId; -+ -+ ASSERT_COND(p_FmPort->im.firstBdOfFrameId != p_FmPort->im.currBdId); -+ -+ /* Since firstInFrame is not NULL, one buffer at least has already been -+ inserted into the BD ring. Using do-while covers the situation of a -+ frame spanned throughout the whole Tx BD ring (p_CleanBd is incremented -+ prior to testing whether or not it's equal to TxBd). */ -+ do -+ { -+ BD_STATUS_AND_LENGTH_SET(BD_GET(cleanBdId), 0); -+ /* Advance BD pointer */ -+ cleanBdId = GetNextBdId(p_FmPort, cleanBdId); -+ } while (cleanBdId != p_FmPort->im.currBdId); -+ -+ p_FmPort->im.currBdId = cleanBdId; -+ p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID; -+ } -+ -+ return ERROR_CODE(E_FULL); -+ } -+ -+ return E_OK; -+} -+ -+void FM_PORT_ImTxConf(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN(p_FmPort->imEn, E_INVALID_STATE); -+ SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ TxConf(p_FmPort, e_TX_CONF_TYPE_CALLBACK); -+} -+ -+t_Error FM_PORT_ImRx(t_Handle h_FmPort) -+{ -+ t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE); -+ -+ return FmPortImRx(p_FmPort); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c -@@ -0,0 +1,1568 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#include "common/general.h" -+ -+#include "fman_common.h" -+#include "fsl_fman_port.h" -+ -+ -+/* problem Eyal: the following should not be here*/ -+#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028 -+ -+static uint32_t get_no_pcd_nia_bmi_ac_enc_frame(struct fman_port_cfg *cfg) -+{ -+ if (cfg->errata_A006675) -+ return NIA_ENG_FM_CTL | -+ NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME; -+ else -+ return NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME; -+} -+ -+static int init_bmi_rx(struct fman_port *port, -+ struct fman_port_cfg *cfg, -+ struct fman_port_params *params) -+{ -+ struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx; -+ uint32_t tmp; -+ -+ /* Rx Configuration register */ -+ tmp = 0; -+ if (port->im_en) -+ tmp |= BMI_PORT_CFG_IM; -+ else if (cfg->discard_override) -+ tmp |= BMI_PORT_CFG_FDOVR; -+ iowrite32be(tmp, ®s->fmbm_rcfg); -+ -+ /* DMA attributes */ -+ tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT; -+ if (cfg->dma_ic_stash_on) -+ tmp |= BMI_DMA_ATTR_IC_STASH_ON; -+ if (cfg->dma_header_stash_on) -+ tmp |= BMI_DMA_ATTR_HDR_STASH_ON; -+ if (cfg->dma_sg_stash_on) -+ tmp |= BMI_DMA_ATTR_SG_STASH_ON; -+ if (cfg->dma_write_optimize) -+ tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE; -+ iowrite32be(tmp, ®s->fmbm_rda); -+ -+ /* Rx FIFO parameters */ -+ tmp = (cfg->rx_pri_elevation / FMAN_PORT_BMI_FIFO_UNITS - 1) << -+ BMI_RX_FIFO_PRI_ELEVATION_SHIFT; -+ tmp |= cfg->rx_fifo_thr / FMAN_PORT_BMI_FIFO_UNITS - 1; -+ iowrite32be(tmp, ®s->fmbm_rfp); -+ -+ if (cfg->excessive_threshold_register) -+ /* always allow access to the extra resources */ -+ iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, ®s->fmbm_reth); -+ -+ /* Frame end data */ -+ tmp = (uint32_t)cfg->checksum_bytes_ignore << -+ BMI_RX_FRAME_END_CS_IGNORE_SHIFT; -+ tmp |= (uint32_t)cfg->rx_cut_end_bytes << -+ BMI_RX_FRAME_END_CUT_SHIFT; -+ if (cfg->errata_A006320) -+ tmp &= 0xffe0ffff; -+ iowrite32be(tmp, ®s->fmbm_rfed); -+ -+ /* Internal context parameters */ -+ tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) << -+ BMI_IC_TO_EXT_SHIFT; -+ tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) << -+ BMI_IC_FROM_INT_SHIFT; -+ tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS; -+ iowrite32be(tmp, ®s->fmbm_ricp); -+ -+ /* Internal buffer offset */ -+ tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS) -+ << BMI_INT_BUF_MARG_SHIFT; -+ iowrite32be(tmp, ®s->fmbm_rim); -+ -+ /* External buffer margins */ -+ if (!port->im_en) -+ { -+ tmp = (uint32_t)cfg->ext_buf_start_margin << -+ BMI_EXT_BUF_MARG_START_SHIFT; -+ tmp |= (uint32_t)cfg->ext_buf_end_margin; -+ if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather) -+ tmp |= BMI_SG_DISABLE; -+ iowrite32be(tmp, ®s->fmbm_rebm); -+ } -+ -+ /* Frame attributes */ -+ tmp = BMI_CMD_RX_MR_DEF; -+ if (!port->im_en) -+ { -+ tmp |= BMI_CMD_ATTR_ORDER; -+ tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT; -+ if (cfg->sync_req) -+ tmp |= BMI_CMD_ATTR_SYNC; -+ } -+ iowrite32be(tmp, ®s->fmbm_rfca); -+ -+ /* NIA */ -+ if (port->im_en) -+ tmp = NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX; -+ else -+ { -+ tmp = (uint32_t)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT; -+ tmp |= get_no_pcd_nia_bmi_ac_enc_frame(cfg); -+ } -+ iowrite32be(tmp, ®s->fmbm_rfne); -+ -+ /* Enqueue NIA */ -+ iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, ®s->fmbm_rfene); -+ -+ /* Default/error queues */ -+ if (!port->im_en) -+ { -+ iowrite32be((params->dflt_fqid & 0x00FFFFFF), ®s->fmbm_rfqid); -+ iowrite32be((params->err_fqid & 0x00FFFFFF), ®s->fmbm_refqid); -+ } -+ -+ /* Discard/error masks */ -+ iowrite32be(params->discard_mask, ®s->fmbm_rfsdm); -+ iowrite32be(params->err_mask, ®s->fmbm_rfsem); -+ -+ /* Statistics counters */ -+ tmp = 0; -+ if (cfg->stats_counters_enable) -+ tmp = BMI_COUNTERS_EN; -+ iowrite32be(tmp, ®s->fmbm_rstc); -+ -+ /* Performance counters */ -+ fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params); -+ tmp = 0; -+ if (cfg->perf_counters_enable) -+ tmp = BMI_COUNTERS_EN; -+ iowrite32be(tmp, ®s->fmbm_rpc); -+ -+ return 0; -+} -+ -+static int init_bmi_tx(struct fman_port *port, -+ struct fman_port_cfg *cfg, -+ struct fman_port_params *params) -+{ -+ struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx; -+ uint32_t tmp; -+ -+ /* Tx Configuration register */ -+ tmp = 0; -+ if (port->im_en) -+ tmp |= BMI_PORT_CFG_IM; -+ iowrite32be(tmp, ®s->fmbm_tcfg); -+ -+ /* DMA attributes */ -+ tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT; -+ if (cfg->dma_ic_stash_on) -+ tmp |= BMI_DMA_ATTR_IC_STASH_ON; -+ if (cfg->dma_header_stash_on) -+ tmp |= BMI_DMA_ATTR_HDR_STASH_ON; -+ if (cfg->dma_sg_stash_on) -+ tmp |= BMI_DMA_ATTR_SG_STASH_ON; -+ iowrite32be(tmp, ®s->fmbm_tda); -+ -+ /* Tx FIFO parameters */ -+ tmp = (cfg->tx_fifo_min_level / FMAN_PORT_BMI_FIFO_UNITS) << -+ BMI_TX_FIFO_MIN_FILL_SHIFT; -+ tmp |= ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) << -+ BMI_FIFO_PIPELINE_DEPTH_SHIFT; -+ tmp |= (uint32_t)(cfg->tx_fifo_low_comf_level / -+ FMAN_PORT_BMI_FIFO_UNITS - 1); -+ iowrite32be(tmp, ®s->fmbm_tfp); -+ -+ /* Frame end data */ -+ tmp = (uint32_t)cfg->checksum_bytes_ignore << -+ BMI_FRAME_END_CS_IGNORE_SHIFT; -+ iowrite32be(tmp, ®s->fmbm_tfed); -+ -+ /* Internal context parameters */ -+ if (!port->im_en) -+ { -+ tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) << -+ BMI_IC_TO_EXT_SHIFT; -+ tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) << -+ BMI_IC_FROM_INT_SHIFT; -+ tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS; -+ iowrite32be(tmp, ®s->fmbm_ticp); -+ } -+ /* Frame attributes */ -+ tmp = BMI_CMD_TX_MR_DEF; -+ if (port->im_en) -+ tmp |= BMI_CMD_MR_DEAS; -+ else -+ { -+ tmp |= BMI_CMD_ATTR_ORDER; -+ tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT; -+ } -+ iowrite32be(tmp, ®s->fmbm_tfca); -+ -+ /* Dequeue NIA + enqueue NIA */ -+ if (port->im_en) -+ { -+ iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, ®s->fmbm_tfdne); -+ iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, ®s->fmbm_tfene); -+ } -+ else -+ { -+ iowrite32be(NIA_ENG_QMI_DEQ, ®s->fmbm_tfdne); -+ iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, ®s->fmbm_tfene); -+ if (cfg->fmbm_tfne_has_features) -+ iowrite32be(!params->dflt_fqid ? -+ BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME : -+ NIA_BMI_AC_FETCH_ALL_FRAME, ®s->fmbm_tfne); -+ if (!params->dflt_fqid && params->dont_release_buf) -+ { -+ iowrite32be(0x00FFFFFF, ®s->fmbm_tcfqid); -+ iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, ®s->fmbm_tfene); -+ if (cfg->fmbm_tfne_has_features) -+ iowrite32be(ioread32be(®s->fmbm_tfne) & ~BMI_EBD_EN, ®s->fmbm_tfne); -+ } -+ } -+ -+ /* Confirmation/error queues */ -+ if (!port->im_en) -+ { -+ if (params->dflt_fqid || !params->dont_release_buf) -+ iowrite32be(params->dflt_fqid & 0x00FFFFFF, ®s->fmbm_tcfqid); -+ iowrite32be((params->err_fqid & 0x00FFFFFF), ®s->fmbm_tefqid); -+ } -+ /* Statistics counters */ -+ tmp = 0; -+ if (cfg->stats_counters_enable) -+ tmp = BMI_COUNTERS_EN; -+ iowrite32be(tmp, ®s->fmbm_tstc); -+ -+ /* Performance counters */ -+ fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params); -+ tmp = 0; -+ if (cfg->perf_counters_enable) -+ tmp = BMI_COUNTERS_EN; -+ iowrite32be(tmp, ®s->fmbm_tpc); -+ -+ return 0; -+} -+ -+static int init_bmi_oh(struct fman_port *port, -+ struct fman_port_cfg *cfg, -+ struct fman_port_params *params) -+{ -+ struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh; -+ uint32_t tmp; -+ -+ /* OP Configuration register */ -+ tmp = 0; -+ if (cfg->discard_override) -+ tmp |= BMI_PORT_CFG_FDOVR; -+ iowrite32be(tmp, ®s->fmbm_ocfg); -+ -+ /* DMA attributes */ -+ tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT; -+ if (cfg->dma_ic_stash_on) -+ tmp |= BMI_DMA_ATTR_IC_STASH_ON; -+ if (cfg->dma_header_stash_on) -+ tmp |= BMI_DMA_ATTR_HDR_STASH_ON; -+ if (cfg->dma_sg_stash_on) -+ tmp |= BMI_DMA_ATTR_SG_STASH_ON; -+ if (cfg->dma_write_optimize) -+ tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE; -+ iowrite32be(tmp, ®s->fmbm_oda); -+ -+ /* Tx FIFO parameters */ -+ tmp = ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) << -+ BMI_FIFO_PIPELINE_DEPTH_SHIFT; -+ iowrite32be(tmp, ®s->fmbm_ofp); -+ -+ /* Internal context parameters */ -+ tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) << -+ BMI_IC_TO_EXT_SHIFT; -+ tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) << -+ BMI_IC_FROM_INT_SHIFT; -+ tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS; -+ iowrite32be(tmp, ®s->fmbm_oicp); -+ -+ /* Frame attributes */ -+ tmp = BMI_CMD_OP_MR_DEF; -+ tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT; -+ if (cfg->sync_req) -+ tmp |= BMI_CMD_ATTR_SYNC; -+ if (port->type == E_FMAN_PORT_TYPE_OP) -+ tmp |= BMI_CMD_ATTR_ORDER; -+ iowrite32be(tmp, ®s->fmbm_ofca); -+ -+ /* Internal buffer offset */ -+ tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS) -+ << BMI_INT_BUF_MARG_SHIFT; -+ iowrite32be(tmp, ®s->fmbm_oim); -+ -+ /* Dequeue NIA */ -+ iowrite32be(NIA_ENG_QMI_DEQ, ®s->fmbm_ofdne); -+ -+ /* NIA and Enqueue NIA */ -+ if (port->type == E_FMAN_PORT_TYPE_HC) { -+ iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC, -+ ®s->fmbm_ofne); -+ iowrite32be(NIA_ENG_QMI_ENQ, ®s->fmbm_ofene); -+ } else { -+ iowrite32be(get_no_pcd_nia_bmi_ac_enc_frame(cfg), -+ ®s->fmbm_ofne); -+ iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, -+ ®s->fmbm_ofene); -+ } -+ -+ /* Default/error queues */ -+ iowrite32be((params->dflt_fqid & 0x00FFFFFF), ®s->fmbm_ofqid); -+ iowrite32be((params->err_fqid & 0x00FFFFFF), ®s->fmbm_oefqid); -+ -+ /* Discard/error masks */ -+ if (port->type == E_FMAN_PORT_TYPE_OP) { -+ iowrite32be(params->discard_mask, ®s->fmbm_ofsdm); -+ iowrite32be(params->err_mask, ®s->fmbm_ofsem); -+ } -+ -+ /* Statistics counters */ -+ tmp = 0; -+ if (cfg->stats_counters_enable) -+ tmp = BMI_COUNTERS_EN; -+ iowrite32be(tmp, ®s->fmbm_ostc); -+ -+ /* Performance counters */ -+ fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params); -+ tmp = 0; -+ if (cfg->perf_counters_enable) -+ tmp = BMI_COUNTERS_EN; -+ iowrite32be(tmp, ®s->fmbm_opc); -+ -+ return 0; -+} -+ -+static int init_qmi(struct fman_port *port, -+ struct fman_port_cfg *cfg, -+ struct fman_port_params *params) -+{ -+ struct fman_port_qmi_regs *regs = port->qmi_regs; -+ uint32_t tmp; -+ -+ tmp = 0; -+ if (cfg->queue_counters_enable) -+ tmp |= QMI_PORT_CFG_EN_COUNTERS; -+ iowrite32be(tmp, ®s->fmqm_pnc); -+ -+ /* Rx port configuration */ -+ if ((port->type == E_FMAN_PORT_TYPE_RX) || -+ (port->type == E_FMAN_PORT_TYPE_RX_10G)) { -+ /* Enqueue NIA */ -+ iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, ®s->fmqm_pnen); -+ return 0; -+ } -+ -+ /* Continue with Tx and O/H port configuration */ -+ if ((port->type == E_FMAN_PORT_TYPE_TX) || -+ (port->type == E_FMAN_PORT_TYPE_TX_10G)) { -+ /* Enqueue NIA */ -+ iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, -+ ®s->fmqm_pnen); -+ /* Dequeue NIA */ -+ iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, ®s->fmqm_pndn); -+ } else { -+ /* Enqueue NIA */ -+ iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, ®s->fmqm_pnen); -+ /* Dequeue NIA */ -+ iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_FETCH, ®s->fmqm_pndn); -+ } -+ -+ /* Dequeue Configuration register */ -+ tmp = 0; -+ if (cfg->deq_high_pri) -+ tmp |= QMI_DEQ_CFG_PRI; -+ -+ switch (cfg->deq_type) { -+ case E_FMAN_PORT_DEQ_BY_PRI: -+ tmp |= QMI_DEQ_CFG_TYPE1; -+ break; -+ case E_FMAN_PORT_DEQ_ACTIVE_FQ: -+ tmp |= QMI_DEQ_CFG_TYPE2; -+ break; -+ case E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS: -+ tmp |= QMI_DEQ_CFG_TYPE3; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (cfg->qmi_deq_options_support) { -+ if ((port->type == E_FMAN_PORT_TYPE_HC) && -+ (cfg->deq_prefetch_opt != E_FMAN_PORT_DEQ_NO_PREFETCH)) -+ return -EINVAL; -+ -+ switch (cfg->deq_prefetch_opt) { -+ case E_FMAN_PORT_DEQ_NO_PREFETCH: -+ break; -+ case E_FMAN_PORT_DEQ_PART_PREFETCH: -+ tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL; -+ break; -+ case E_FMAN_PORT_DEQ_FULL_PREFETCH: -+ tmp |= QMI_DEQ_CFG_PREFETCH_FULL; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ tmp |= (uint32_t)(params->deq_sp & QMI_DEQ_CFG_SP_MASK) << -+ QMI_DEQ_CFG_SP_SHIFT; -+ tmp |= cfg->deq_byte_cnt; -+ iowrite32be(tmp, ®s->fmqm_pndc); -+ -+ return 0; -+} -+ -+static void get_rx_stats_reg(struct fman_port *port, -+ enum fman_port_stats_counters counter, -+ uint32_t **stats_reg) -+{ -+ struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx; -+ -+ switch (counter) { -+ case E_FMAN_PORT_STATS_CNT_FRAME: -+ *stats_reg = ®s->fmbm_rfrc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_DISCARD: -+ *stats_reg = ®s->fmbm_rfdc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF: -+ *stats_reg = ®s->fmbm_rbdc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME: -+ *stats_reg = ®s->fmbm_rfbc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME: -+ *stats_reg = ®s->fmbm_rlfc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF: -+ *stats_reg = ®s->fmbm_rodc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME: -+ *stats_reg = ®s->fmbm_rffc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_DMA_ERR: -+ *stats_reg = ®s->fmbm_rfldec; -+ break; -+ default: -+ *stats_reg = NULL; -+ } -+} -+ -+static void get_tx_stats_reg(struct fman_port *port, -+ enum fman_port_stats_counters counter, -+ uint32_t **stats_reg) -+{ -+ struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx; -+ -+ switch (counter) { -+ case E_FMAN_PORT_STATS_CNT_FRAME: -+ *stats_reg = ®s->fmbm_tfrc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_DISCARD: -+ *stats_reg = ®s->fmbm_tfdc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF: -+ *stats_reg = ®s->fmbm_tbdc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_LEN_ERR: -+ *stats_reg = ®s->fmbm_tfledc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT: -+ *stats_reg = ®s->fmbm_tfufdc; -+ break; -+ default: -+ *stats_reg = NULL; -+ } -+} -+ -+static void get_oh_stats_reg(struct fman_port *port, -+ enum fman_port_stats_counters counter, -+ uint32_t **stats_reg) -+{ -+ struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh; -+ -+ switch (counter) { -+ case E_FMAN_PORT_STATS_CNT_FRAME: -+ *stats_reg = ®s->fmbm_ofrc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_DISCARD: -+ *stats_reg = ®s->fmbm_ofdc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF: -+ *stats_reg = ®s->fmbm_obdc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME: -+ *stats_reg = ®s->fmbm_offc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_DMA_ERR: -+ *stats_reg = ®s->fmbm_ofldec; -+ break; -+ case E_FMAN_PORT_STATS_CNT_LEN_ERR: -+ *stats_reg = ®s->fmbm_ofledc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT: -+ *stats_reg = ®s->fmbm_ofufdc; -+ break; -+ case E_FMAN_PORT_STATS_CNT_WRED_DISCARD: -+ *stats_reg = ®s->fmbm_ofwdc; -+ break; -+ default: -+ *stats_reg = NULL; -+ } -+} -+ -+static void get_rx_perf_reg(struct fman_port *port, -+ enum fman_port_perf_counters counter, -+ uint32_t **perf_reg) -+{ -+ struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx; -+ -+ switch (counter) { -+ case E_FMAN_PORT_PERF_CNT_CYCLE: -+ *perf_reg = ®s->fmbm_rccn; -+ break; -+ case E_FMAN_PORT_PERF_CNT_TASK_UTIL: -+ *perf_reg = ®s->fmbm_rtuc; -+ break; -+ case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL: -+ *perf_reg = ®s->fmbm_rrquc; -+ break; -+ case E_FMAN_PORT_PERF_CNT_DMA_UTIL: -+ *perf_reg = ®s->fmbm_rduc; -+ break; -+ case E_FMAN_PORT_PERF_CNT_FIFO_UTIL: -+ *perf_reg = ®s->fmbm_rfuc; -+ break; -+ case E_FMAN_PORT_PERF_CNT_RX_PAUSE: -+ *perf_reg = ®s->fmbm_rpac; -+ break; -+ default: -+ *perf_reg = NULL; -+ } -+} -+ -+static void get_tx_perf_reg(struct fman_port *port, -+ enum fman_port_perf_counters counter, -+ uint32_t **perf_reg) -+{ -+ struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx; -+ -+ switch (counter) { -+ case E_FMAN_PORT_PERF_CNT_CYCLE: -+ *perf_reg = ®s->fmbm_tccn; -+ break; -+ case E_FMAN_PORT_PERF_CNT_TASK_UTIL: -+ *perf_reg = ®s->fmbm_ttuc; -+ break; -+ case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL: -+ *perf_reg = ®s->fmbm_ttcquc; -+ break; -+ case E_FMAN_PORT_PERF_CNT_DMA_UTIL: -+ *perf_reg = ®s->fmbm_tduc; -+ break; -+ case E_FMAN_PORT_PERF_CNT_FIFO_UTIL: -+ *perf_reg = ®s->fmbm_tfuc; -+ break; -+ default: -+ *perf_reg = NULL; -+ } -+} -+ -+static void get_oh_perf_reg(struct fman_port *port, -+ enum fman_port_perf_counters counter, -+ uint32_t **perf_reg) -+{ -+ struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh; -+ -+ switch (counter) { -+ case E_FMAN_PORT_PERF_CNT_CYCLE: -+ *perf_reg = ®s->fmbm_occn; -+ break; -+ case E_FMAN_PORT_PERF_CNT_TASK_UTIL: -+ *perf_reg = ®s->fmbm_otuc; -+ break; -+ case E_FMAN_PORT_PERF_CNT_DMA_UTIL: -+ *perf_reg = ®s->fmbm_oduc; -+ break; -+ case E_FMAN_PORT_PERF_CNT_FIFO_UTIL: -+ *perf_reg = ®s->fmbm_ofuc; -+ break; -+ default: -+ *perf_reg = NULL; -+ } -+} -+ -+static void get_qmi_counter_reg(struct fman_port *port, -+ enum fman_port_qmi_counters counter, -+ uint32_t **queue_reg) -+{ -+ struct fman_port_qmi_regs *regs = port->qmi_regs; -+ -+ switch (counter) { -+ case E_FMAN_PORT_ENQ_TOTAL: -+ *queue_reg = ®s->fmqm_pnetfc; -+ break; -+ case E_FMAN_PORT_DEQ_TOTAL: -+ if ((port->type == E_FMAN_PORT_TYPE_RX) || -+ (port->type == E_FMAN_PORT_TYPE_RX_10G)) -+ /* Counter not available for Rx ports */ -+ *queue_reg = NULL; -+ else -+ *queue_reg = ®s->fmqm_pndtfc; -+ break; -+ case E_FMAN_PORT_DEQ_FROM_DFLT: -+ if ((port->type == E_FMAN_PORT_TYPE_RX) || -+ (port->type == E_FMAN_PORT_TYPE_RX_10G)) -+ /* Counter not available for Rx ports */ -+ *queue_reg = NULL; -+ else -+ *queue_reg = ®s->fmqm_pndfdc; -+ break; -+ case E_FMAN_PORT_DEQ_CONFIRM: -+ if ((port->type == E_FMAN_PORT_TYPE_RX) || -+ (port->type == E_FMAN_PORT_TYPE_RX_10G)) -+ /* Counter not available for Rx ports */ -+ *queue_reg = NULL; -+ else -+ *queue_reg = ®s->fmqm_pndcc; -+ break; -+ default: -+ *queue_reg = NULL; -+ } -+} -+ -+void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type) -+{ -+ cfg->dma_swap_data = E_FMAN_PORT_DMA_NO_SWAP; -+ cfg->dma_ic_stash_on = FALSE; -+ cfg->dma_header_stash_on = FALSE; -+ cfg->dma_sg_stash_on = FALSE; -+ cfg->dma_write_optimize = TRUE; -+ cfg->color = E_FMAN_PORT_COLOR_GREEN; -+ cfg->discard_override = FALSE; -+ cfg->checksum_bytes_ignore = 0; -+ cfg->rx_cut_end_bytes = 4; -+ cfg->rx_pri_elevation = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS); -+ cfg->rx_fifo_thr = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS); -+ cfg->rx_fd_bits = 0; -+ cfg->ic_ext_offset = 0; -+ cfg->ic_int_offset = 0; -+ cfg->ic_size = 0; -+ cfg->int_buf_start_margin = 0; -+ cfg->ext_buf_start_margin = 0; -+ cfg->ext_buf_end_margin = 0; -+ cfg->tx_fifo_min_level = 0; -+ cfg->tx_fifo_low_comf_level = (5 * KILOBYTE); -+ cfg->stats_counters_enable = TRUE; -+ cfg->perf_counters_enable = TRUE; -+ cfg->deq_type = E_FMAN_PORT_DEQ_BY_PRI; -+ -+ if (type == E_FMAN_PORT_TYPE_HC) { -+ cfg->sync_req = FALSE; -+ cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_NO_PREFETCH; -+ } else { -+ cfg->sync_req = TRUE; -+ cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_FULL_PREFETCH; -+ } -+ -+ if (type == E_FMAN_PORT_TYPE_TX_10G) { -+ cfg->tx_fifo_deq_pipeline_depth = 4; -+ cfg->deq_high_pri = TRUE; -+ cfg->deq_byte_cnt = 0x1400; -+ } else { -+ if ((type == E_FMAN_PORT_TYPE_HC) || -+ (type == E_FMAN_PORT_TYPE_OP)) -+ cfg->tx_fifo_deq_pipeline_depth = 2; -+ else -+ cfg->tx_fifo_deq_pipeline_depth = 1; -+ -+ cfg->deq_high_pri = FALSE; -+ cfg->deq_byte_cnt = 0x400; -+ } -+ cfg->no_scatter_gather = DEFAULT_FMAN_SP_NO_SCATTER_GATHER; -+} -+ -+static uint8_t fman_port_find_bpool(struct fman_port *port, uint8_t bpid) -+{ -+ uint32_t *bp_reg, tmp; -+ uint8_t i, id; -+ -+ /* Find the pool */ -+ bp_reg = port->bmi_regs->rx.fmbm_ebmpi; -+ for (i = 0; -+ (i < port->ext_pools_num && (i < FMAN_PORT_MAX_EXT_POOLS_NUM)); -+ i++) { -+ tmp = ioread32be(&bp_reg[i]); -+ id = (uint8_t)((tmp & BMI_EXT_BUF_POOL_ID_MASK) >> -+ BMI_EXT_BUF_POOL_ID_SHIFT); -+ -+ if (id == bpid) -+ break; -+ } -+ -+ return i; -+} -+ -+int fman_port_init(struct fman_port *port, -+ struct fman_port_cfg *cfg, -+ struct fman_port_params *params) -+{ -+ int err; -+ -+ /* Init BMI registers */ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ err = init_bmi_rx(port, cfg, params); -+ break; -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ err = init_bmi_tx(port, cfg, params); -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ case E_FMAN_PORT_TYPE_HC: -+ err = init_bmi_oh(port, cfg, params); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (err) -+ return err; -+ -+ /* Init QMI registers */ -+ if (!port->im_en) -+ { -+ err = init_qmi(port, cfg, params); -+ return err; -+ } -+ return 0; -+} -+ -+int fman_port_enable(struct fman_port *port) -+{ -+ uint32_t *bmi_cfg_reg, tmp; -+ bool rx_port; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg; -+ rx_port = TRUE; -+ break; -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg; -+ rx_port = FALSE; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ case E_FMAN_PORT_TYPE_HC: -+ bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg; -+ rx_port = FALSE; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* Enable QMI */ -+ if (!rx_port) { -+ tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN; -+ iowrite32be(tmp, &port->qmi_regs->fmqm_pnc); -+ } -+ -+ /* Enable BMI */ -+ tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN; -+ iowrite32be(tmp, bmi_cfg_reg); -+ -+ return 0; -+} -+ -+int fman_port_disable(const struct fman_port *port) -+{ -+ uint32_t *bmi_cfg_reg, *bmi_status_reg, tmp; -+ bool rx_port, failure = FALSE; -+ int count; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg; -+ bmi_status_reg = &port->bmi_regs->rx.fmbm_rst; -+ rx_port = TRUE; -+ break; -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg; -+ bmi_status_reg = &port->bmi_regs->tx.fmbm_tst; -+ rx_port = FALSE; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ case E_FMAN_PORT_TYPE_HC: -+ bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg; -+ bmi_status_reg = &port->bmi_regs->oh.fmbm_ost; -+ rx_port = FALSE; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* Disable QMI */ -+ if (!rx_port) { -+ tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN; -+ iowrite32be(tmp, &port->qmi_regs->fmqm_pnc); -+ -+ /* Wait for QMI to finish FD handling */ -+ count = 100; -+ do { -+ udelay(10); -+ tmp = ioread32be(&port->qmi_regs->fmqm_pns); -+ } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count); -+ -+ if (count == 0) -+ { -+ /* Timeout */ -+ failure = TRUE; -+ } -+ } -+ -+ /* Disable BMI */ -+ tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN; -+ iowrite32be(tmp, bmi_cfg_reg); -+ -+ /* Wait for graceful stop end */ -+ count = 500; -+ do { -+ udelay(10); -+ tmp = ioread32be(bmi_status_reg); -+ } while ((tmp & BMI_PORT_STATUS_BSY) && --count); -+ -+ if (count == 0) -+ { -+ /* Timeout */ -+ failure = TRUE; -+ } -+ -+ if (failure) -+ return -EBUSY; -+ -+ return 0; -+} -+ -+int fman_port_set_bpools(const struct fman_port *port, -+ const struct fman_port_bpools *bp) -+{ -+ uint32_t tmp, *bp_reg, *bp_depl_reg; -+ uint8_t i, max_bp_num; -+ bool grp_depl_used = FALSE, rx_port; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ max_bp_num = port->ext_pools_num; -+ rx_port = TRUE; -+ bp_reg = port->bmi_regs->rx.fmbm_ebmpi; -+ bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ if (port->fm_rev_maj != 4) -+ return -EINVAL; -+ max_bp_num = FMAN_PORT_OBS_EXT_POOLS_NUM; -+ rx_port = FALSE; -+ bp_reg = port->bmi_regs->oh.fmbm_oebmpi; -+ bp_depl_reg = &port->bmi_regs->oh.fmbm_ompd; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (rx_port) { -+ /* Check buffers are provided in ascending order */ -+ for (i = 0; -+ (i < (bp->count-1) && (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1)); -+ i++) { -+ if (bp->bpool[i].size > bp->bpool[i+1].size) -+ return -EINVAL; -+ } -+ } -+ -+ /* Set up external buffers pools */ -+ for (i = 0; i < bp->count; i++) { -+ tmp = BMI_EXT_BUF_POOL_VALID; -+ tmp |= ((uint32_t)bp->bpool[i].bpid << -+ BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK; -+ -+ if (rx_port) { -+ if (bp->counters_enable) -+ tmp |= BMI_EXT_BUF_POOL_EN_COUNTER; -+ -+ if (bp->bpool[i].is_backup) -+ tmp |= BMI_EXT_BUF_POOL_BACKUP; -+ -+ tmp |= (uint32_t)bp->bpool[i].size; -+ } -+ -+ iowrite32be(tmp, &bp_reg[i]); -+ } -+ -+ /* Clear unused pools */ -+ for (i = bp->count; i < max_bp_num; i++) -+ iowrite32be(0, &bp_reg[i]); -+ -+ /* Pools depletion */ -+ tmp = 0; -+ for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) { -+ if (bp->bpool[i].grp_bp_depleted) { -+ grp_depl_used = TRUE; -+ tmp |= 0x80000000 >> i; -+ } -+ -+ if (bp->bpool[i].single_bp_depleted) -+ tmp |= 0x80 >> i; -+ -+ if (bp->bpool[i].pfc_priorities_en) -+ tmp |= 0x0100 << i; -+ } -+ -+ if (grp_depl_used) -+ tmp |= ((uint32_t)bp->grp_bp_depleted_num - 1) << -+ BMI_POOL_DEP_NUM_OF_POOLS_SHIFT; -+ -+ iowrite32be(tmp, bp_depl_reg); -+ return 0; -+} -+ -+int fman_port_set_rate_limiter(struct fman_port *port, -+ struct fman_port_rate_limiter *rate_limiter) -+{ -+ uint32_t *rate_limit_reg, *rate_limit_scale_reg; -+ uint32_t granularity, tmp; -+ uint8_t usec_bit, factor; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ rate_limit_reg = &port->bmi_regs->tx.fmbm_trlmt; -+ rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts; -+ granularity = BMI_RATE_LIMIT_GRAN_TX; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ rate_limit_reg = &port->bmi_regs->oh.fmbm_orlmt; -+ rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts; -+ granularity = BMI_RATE_LIMIT_GRAN_OP; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* Factor is per 1 usec count */ -+ factor = 1; -+ usec_bit = rate_limiter->count_1micro_bit; -+ -+ /* If rate limit is too small for an 1usec factor, adjust timestamp -+ * scale and multiply the factor */ -+ while (rate_limiter->rate < (granularity / factor)) { -+ if (usec_bit == 31) -+ /* Can't configure rate limiter - rate is too small */ -+ return -EINVAL; -+ -+ usec_bit++; -+ factor <<= 1; -+ } -+ -+ /* Figure out register value. The "while" above quarantees that -+ * (rate_limiter->rate * factor / granularity) >= 1 */ -+ tmp = (uint32_t)(rate_limiter->rate * factor / granularity - 1); -+ -+ /* Check rate limit isn't too large */ -+ if (tmp >= BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS) -+ return -EINVAL; -+ -+ /* Check burst size is in allowed range */ -+ if ((rate_limiter->burst_size == 0) || -+ (rate_limiter->burst_size > -+ BMI_RATE_LIMIT_MAX_BURST_SIZE)) -+ return -EINVAL; -+ -+ tmp |= (uint32_t)(rate_limiter->burst_size - 1) << -+ BMI_RATE_LIMIT_MAX_BURST_SHIFT; -+ -+ if ((port->type == E_FMAN_PORT_TYPE_OP) && -+ (port->fm_rev_maj == 4)) { -+ if (rate_limiter->high_burst_size_gran) -+ tmp |= BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN; -+ } -+ -+ iowrite32be(tmp, rate_limit_reg); -+ -+ /* Set up rate limiter scale register */ -+ tmp = BMI_RATE_LIMIT_SCALE_EN; -+ tmp |= (31 - (uint32_t)usec_bit) << BMI_RATE_LIMIT_SCALE_TSBS_SHIFT; -+ -+ if ((port->type == E_FMAN_PORT_TYPE_OP) && -+ (port->fm_rev_maj == 4)) -+ tmp |= rate_limiter->rate_factor; -+ -+ iowrite32be(tmp, rate_limit_scale_reg); -+ -+ return 0; -+} -+ -+int fman_port_delete_rate_limiter(struct fman_port *port) -+{ -+ uint32_t *rate_limit_scale_reg; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ iowrite32be(0, rate_limit_scale_reg); -+ return 0; -+} -+ -+int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask) -+{ -+ uint32_t *err_mask_reg; -+ -+ /* Obtain register address */ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ err_mask_reg = &port->bmi_regs->rx.fmbm_rfsem; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ err_mask_reg = &port->bmi_regs->oh.fmbm_ofsem; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ iowrite32be(err_mask, err_mask_reg); -+ return 0; -+} -+ -+int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask) -+{ -+ uint32_t *discard_mask_reg; -+ -+ /* Obtain register address */ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ discard_mask_reg = &port->bmi_regs->rx.fmbm_rfsdm; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ discard_mask_reg = &port->bmi_regs->oh.fmbm_ofsdm; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ iowrite32be(discard_mask, discard_mask_reg); -+ return 0; -+} -+ -+int fman_port_modify_rx_fd_bits(struct fman_port *port, -+ uint8_t rx_fd_bits, -+ bool add) -+{ -+ uint32_t tmp; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ tmp = ioread32be(&port->bmi_regs->rx.fmbm_rfne); -+ -+ if (add) -+ tmp |= (uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT; -+ else -+ tmp &= ~((uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT); -+ -+ iowrite32be(tmp, &port->bmi_regs->rx.fmbm_rfne); -+ return 0; -+} -+ -+int fman_port_set_perf_cnt_params(struct fman_port *port, -+ struct fman_port_perf_cnt_params *params) -+{ -+ uint32_t *pcp_reg, tmp; -+ -+ /* Obtain register address and check parameters are in range */ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ pcp_reg = &port->bmi_regs->rx.fmbm_rpcp; -+ if ((params->queue_val == 0) || -+ (params->queue_val > MAX_PERFORMANCE_RX_QUEUE_COMP)) -+ return -EINVAL; -+ break; -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ pcp_reg = &port->bmi_regs->tx.fmbm_tpcp; -+ if ((params->queue_val == 0) || -+ (params->queue_val > MAX_PERFORMANCE_TX_QUEUE_COMP)) -+ return -EINVAL; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ case E_FMAN_PORT_TYPE_HC: -+ pcp_reg = &port->bmi_regs->oh.fmbm_opcp; -+ if (params->queue_val != 0) -+ return -EINVAL; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if ((params->task_val == 0) || -+ (params->task_val > MAX_PERFORMANCE_TASK_COMP)) -+ return -EINVAL; -+ if ((params->dma_val == 0) || -+ (params->dma_val > MAX_PERFORMANCE_DMA_COMP)) -+ return -EINVAL; -+ if ((params->fifo_val == 0) || -+ ((params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS) > -+ MAX_PERFORMANCE_FIFO_COMP)) -+ return -EINVAL; -+ tmp = (uint32_t)(params->task_val - 1) << -+ BMI_PERFORMANCE_TASK_COMP_SHIFT; -+ tmp |= (uint32_t)(params->dma_val - 1) << -+ BMI_PERFORMANCE_DMA_COMP_SHIFT; -+ tmp |= (uint32_t)(params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS - 1); -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ tmp |= (uint32_t)(params->queue_val - 1) << -+ BMI_PERFORMANCE_QUEUE_COMP_SHIFT; -+ break; -+ default: -+ break; -+ } -+ -+ -+ iowrite32be(tmp, pcp_reg); -+ return 0; -+} -+ -+int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable) -+{ -+ uint32_t *stats_reg, tmp; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ stats_reg = &port->bmi_regs->rx.fmbm_rstc; -+ break; -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ stats_reg = &port->bmi_regs->tx.fmbm_tstc; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ case E_FMAN_PORT_TYPE_HC: -+ stats_reg = &port->bmi_regs->oh.fmbm_ostc; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ tmp = ioread32be(stats_reg); -+ -+ if (enable) -+ tmp |= BMI_COUNTERS_EN; -+ else -+ tmp &= ~BMI_COUNTERS_EN; -+ -+ iowrite32be(tmp, stats_reg); -+ return 0; -+} -+ -+int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable) -+{ -+ uint32_t *stats_reg, tmp; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ stats_reg = &port->bmi_regs->rx.fmbm_rpc; -+ break; -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ stats_reg = &port->bmi_regs->tx.fmbm_tpc; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ case E_FMAN_PORT_TYPE_HC: -+ stats_reg = &port->bmi_regs->oh.fmbm_opc; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ tmp = ioread32be(stats_reg); -+ -+ if (enable) -+ tmp |= BMI_COUNTERS_EN; -+ else -+ tmp &= ~BMI_COUNTERS_EN; -+ -+ iowrite32be(tmp, stats_reg); -+ return 0; -+} -+ -+int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(&port->qmi_regs->fmqm_pnc); -+ -+ if (enable) -+ tmp |= QMI_PORT_CFG_EN_COUNTERS; -+ else -+ tmp &= ~QMI_PORT_CFG_EN_COUNTERS; -+ -+ iowrite32be(tmp, &port->qmi_regs->fmqm_pnc); -+ return 0; -+} -+ -+int fman_port_set_bpool_cnt_mode(struct fman_port *port, -+ uint8_t bpid, -+ bool enable) -+{ -+ uint8_t index; -+ uint32_t tmp; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* Find the pool */ -+ index = fman_port_find_bpool(port, bpid); -+ if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM) -+ /* Not found */ -+ return -EINVAL; -+ -+ tmp = ioread32be(&port->bmi_regs->rx.fmbm_ebmpi[index]); -+ -+ if (enable) -+ tmp |= BMI_EXT_BUF_POOL_EN_COUNTER; -+ else -+ tmp &= ~BMI_EXT_BUF_POOL_EN_COUNTER; -+ -+ iowrite32be(tmp, &port->bmi_regs->rx.fmbm_ebmpi[index]); -+ return 0; -+} -+ -+uint32_t fman_port_get_stats_counter(struct fman_port *port, -+ enum fman_port_stats_counters counter) -+{ -+ uint32_t *stats_reg, ret_val; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ get_rx_stats_reg(port, counter, &stats_reg); -+ break; -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ get_tx_stats_reg(port, counter, &stats_reg); -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ case E_FMAN_PORT_TYPE_HC: -+ get_oh_stats_reg(port, counter, &stats_reg); -+ break; -+ default: -+ stats_reg = NULL; -+ } -+ -+ if (stats_reg == NULL) -+ return 0; -+ -+ ret_val = ioread32be(stats_reg); -+ return ret_val; -+} -+ -+void fman_port_set_stats_counter(struct fman_port *port, -+ enum fman_port_stats_counters counter, -+ uint32_t value) -+{ -+ uint32_t *stats_reg; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ get_rx_stats_reg(port, counter, &stats_reg); -+ break; -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ get_tx_stats_reg(port, counter, &stats_reg); -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ case E_FMAN_PORT_TYPE_HC: -+ get_oh_stats_reg(port, counter, &stats_reg); -+ break; -+ default: -+ stats_reg = NULL; -+ } -+ -+ if (stats_reg == NULL) -+ return; -+ -+ iowrite32be(value, stats_reg); -+} -+ -+uint32_t fman_port_get_perf_counter(struct fman_port *port, -+ enum fman_port_perf_counters counter) -+{ -+ uint32_t *perf_reg, ret_val; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ get_rx_perf_reg(port, counter, &perf_reg); -+ break; -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ get_tx_perf_reg(port, counter, &perf_reg); -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ case E_FMAN_PORT_TYPE_HC: -+ get_oh_perf_reg(port, counter, &perf_reg); -+ break; -+ default: -+ perf_reg = NULL; -+ } -+ -+ if (perf_reg == NULL) -+ return 0; -+ -+ ret_val = ioread32be(perf_reg); -+ return ret_val; -+} -+ -+void fman_port_set_perf_counter(struct fman_port *port, -+ enum fman_port_perf_counters counter, -+ uint32_t value) -+{ -+ uint32_t *perf_reg; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ get_rx_perf_reg(port, counter, &perf_reg); -+ break; -+ case E_FMAN_PORT_TYPE_TX: -+ case E_FMAN_PORT_TYPE_TX_10G: -+ get_tx_perf_reg(port, counter, &perf_reg); -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ case E_FMAN_PORT_TYPE_HC: -+ get_oh_perf_reg(port, counter, &perf_reg); -+ break; -+ default: -+ perf_reg = NULL; -+ } -+ -+ if (perf_reg == NULL) -+ return; -+ -+ iowrite32be(value, perf_reg); -+} -+ -+uint32_t fman_port_get_qmi_counter(struct fman_port *port, -+ enum fman_port_qmi_counters counter) -+{ -+ uint32_t *queue_reg, ret_val; -+ -+ get_qmi_counter_reg(port, counter, &queue_reg); -+ -+ if (queue_reg == NULL) -+ return 0; -+ -+ ret_val = ioread32be(queue_reg); -+ return ret_val; -+} -+ -+void fman_port_set_qmi_counter(struct fman_port *port, -+ enum fman_port_qmi_counters counter, -+ uint32_t value) -+{ -+ uint32_t *queue_reg; -+ -+ get_qmi_counter_reg(port, counter, &queue_reg); -+ -+ if (queue_reg == NULL) -+ return; -+ -+ iowrite32be(value, queue_reg); -+} -+ -+uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid) -+{ -+ uint8_t index; -+ uint32_t ret_val; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ break; -+ default: -+ return 0; -+ } -+ -+ /* Find the pool */ -+ index = fman_port_find_bpool(port, bpid); -+ if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM) -+ /* Not found */ -+ return 0; -+ -+ ret_val = ioread32be(&port->bmi_regs->rx.fmbm_acnt[index]); -+ return ret_val; -+} -+ -+void fman_port_set_bpool_counter(struct fman_port *port, -+ uint8_t bpid, -+ uint32_t value) -+{ -+ uint8_t index; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ break; -+ default: -+ return; -+ } -+ -+ /* Find the pool */ -+ index = fman_port_find_bpool(port, bpid); -+ if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM) -+ /* Not found */ -+ return; -+ -+ iowrite32be(value, &port->bmi_regs->rx.fmbm_acnt[index]); -+} -+ -+int fman_port_add_congestion_grps(struct fman_port *port, -+ uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]) -+{ -+ int i; -+ uint32_t tmp, *grp_map_reg; -+ uint8_t max_grp_map_num; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ if (port->fm_rev_maj == 4) -+ max_grp_map_num = 1; -+ else -+ max_grp_map_num = FMAN_PORT_CG_MAP_NUM; -+ grp_map_reg = port->bmi_regs->rx.fmbm_rcgm; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ max_grp_map_num = 1; -+ if (port->fm_rev_maj != 4) -+ return -EINVAL; -+ grp_map_reg = port->bmi_regs->oh.fmbm_ocgm; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ for (i = (max_grp_map_num - 1); i >= 0; i--) { -+ if (grps_map[i] == 0) -+ continue; -+ tmp = ioread32be(&grp_map_reg[i]); -+ tmp |= grps_map[i]; -+ iowrite32be(tmp, &grp_map_reg[i]); -+ } -+ -+ return 0; -+} -+ -+int fman_port_remove_congestion_grps(struct fman_port *port, -+ uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]) -+{ -+ int i; -+ uint32_t tmp, *grp_map_reg; -+ uint8_t max_grp_map_num; -+ -+ switch (port->type) { -+ case E_FMAN_PORT_TYPE_RX: -+ case E_FMAN_PORT_TYPE_RX_10G: -+ if (port->fm_rev_maj == 4) -+ max_grp_map_num = 1; -+ else -+ max_grp_map_num = FMAN_PORT_CG_MAP_NUM; -+ grp_map_reg = port->bmi_regs->rx.fmbm_rcgm; -+ break; -+ case E_FMAN_PORT_TYPE_OP: -+ max_grp_map_num = 1; -+ if (port->fm_rev_maj != 4) -+ return -EINVAL; -+ grp_map_reg = port->bmi_regs->oh.fmbm_ocgm; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ for (i = (max_grp_map_num - 1); i >= 0; i--) { -+ if (grps_map[i] == 0) -+ continue; -+ tmp = ioread32be(&grp_map_reg[i]); -+ tmp &= ~grps_map[i]; -+ iowrite32be(tmp, &grp_map_reg[i]); -+ } -+ return 0; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile -@@ -0,0 +1,15 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc -+ -+ccflags-y += -I$(NCSW_FM_INC) -+ -+obj-y += fsl-ncsw-RTC.o -+ -+fsl-ncsw-RTC-objs := fm_rtc.o fman_rtc.o ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c -@@ -0,0 +1,692 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_rtc.c -+ -+ @Description FM RTC driver implementation. -+ -+ @Cautions None -+*//***************************************************************************/ -+#include -+#include "error_ext.h" -+#include "debug_ext.h" -+#include "string_ext.h" -+#include "part_ext.h" -+#include "xx_ext.h" -+#include "ncsw_ext.h" -+ -+#include "fm_rtc.h" -+#include "fm_common.h" -+ -+ -+ -+/*****************************************************************************/ -+static t_Error CheckInitParameters(t_FmRtc *p_Rtc) -+{ -+ struct rtc_cfg *p_RtcDriverParam = p_Rtc->p_RtcDriverParam; -+ int i; -+ -+ if ((p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL) && -+ (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) && -+ (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR)) -+ RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined")); -+ -+ if (p_Rtc->outputClockDivisor == 0) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("Divisor for output clock (should be positive)")); -+ } -+ -+ for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++) -+ { -+ if ((p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) && -+ (p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH)) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i)); -+ } -+ } -+ for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++) -+ { -+ if ((p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) && -+ (p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_RISING_EDGE)) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i)); -+ } -+ } -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+static void RtcExceptions(t_Handle h_FmRtc) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ struct rtc_regs *p_MemMap; -+ register uint32_t events; -+ -+ ASSERT_COND(p_Rtc); -+ p_MemMap = p_Rtc->p_MemMap; -+ -+ events = fman_rtc_check_and_clear_event(p_MemMap); -+ if (events & FMAN_RTC_TMR_TEVENT_ALM1) -+ { -+ if (p_Rtc->alarmParams[0].clearOnExpiration) -+ { -+ fman_rtc_set_timer_alarm_l(p_MemMap, 0, 0); -+ fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM1); -+ } -+ ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback); -+ p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0); -+ } -+ if (events & FMAN_RTC_TMR_TEVENT_ALM2) -+ { -+ if (p_Rtc->alarmParams[1].clearOnExpiration) -+ { -+ fman_rtc_set_timer_alarm_l(p_MemMap, 1, 0); -+ fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM2); -+ } -+ ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback); -+ p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1); -+ } -+ if (events & FMAN_RTC_TMR_TEVENT_PP1) -+ { -+ ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback); -+ p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0); -+ } -+ if (events & FMAN_RTC_TMR_TEVENT_PP2) -+ { -+ ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback); -+ p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1); -+ } -+ if (events & FMAN_RTC_TMR_TEVENT_ETS1) -+ { -+ ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback); -+ p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0); -+ } -+ if (events & FMAN_RTC_TMR_TEVENT_ETS2) -+ { -+ ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback); -+ p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1); -+ } -+} -+ -+ -+/*****************************************************************************/ -+t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam) -+{ -+ t_FmRtc *p_Rtc; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmRtcParam, E_NULL_POINTER, NULL); -+ -+ /* Allocate memory for the FM RTC driver parameters */ -+ p_Rtc = (t_FmRtc *)XX_Malloc(sizeof(t_FmRtc)); -+ if (!p_Rtc) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver structure")); -+ return NULL; -+ } -+ -+ memset(p_Rtc, 0, sizeof(t_FmRtc)); -+ -+ /* Allocate memory for the FM RTC driver parameters */ -+ p_Rtc->p_RtcDriverParam = (struct rtc_cfg *)XX_Malloc(sizeof(struct rtc_cfg)); -+ if (!p_Rtc->p_RtcDriverParam) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters")); -+ XX_Free(p_Rtc); -+ return NULL; -+ } -+ -+ memset(p_Rtc->p_RtcDriverParam, 0, sizeof(struct rtc_cfg)); -+ -+ /* Store RTC configuration parameters */ -+ p_Rtc->h_Fm = p_FmRtcParam->h_Fm; -+ -+ /* Set default RTC configuration parameters */ -+ fman_rtc_defconfig(p_Rtc->p_RtcDriverParam); -+ -+ p_Rtc->outputClockDivisor = DEFAULT_OUTPUT_CLOCK_DIVISOR; -+ p_Rtc->p_RtcDriverParam->bypass = DEFAULT_BYPASS; -+ p_Rtc->clockPeriodNanoSec = DEFAULT_CLOCK_PERIOD; /* 1 usec */ -+ -+ -+ /* Store RTC parameters in the RTC control structure */ -+ p_Rtc->p_MemMap = (struct rtc_regs *)UINT_TO_PTR(p_FmRtcParam->baseAddress); -+ p_Rtc->h_App = p_FmRtcParam->h_App; -+ -+ return p_Rtc; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_Init(t_Handle h_FmRtc) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ struct rtc_cfg *p_RtcDriverParam; -+ struct rtc_regs *p_MemMap; -+ uint32_t freqCompensation = 0; -+ uint64_t tmpDouble; -+ bool init_freq_comp = FALSE; -+ -+ p_RtcDriverParam = p_Rtc->p_RtcDriverParam; -+ p_MemMap = p_Rtc->p_MemMap; -+ -+ if (CheckInitParameters(p_Rtc)!=E_OK) -+ RETURN_ERROR(MAJOR, E_CONFLICT, -+ ("Init Parameters are not Valid")); -+ -+ /* TODO check that no timestamping MACs are working in this stage. */ -+ -+ /* find source clock frequency in Mhz */ -+ if (p_Rtc->p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) -+ p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->ext_src_clk_freq; -+ else -+ p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetMacClockFreq(p_Rtc->h_Fm)); -+ -+ /* if timer in Master mode Initialize TMR_CTRL */ -+ /* We want the counter (TMR_CNT) to count in nano-seconds */ -+ if (!p_RtcDriverParam->timer_slave_mode && p_Rtc->p_RtcDriverParam->bypass) -+ p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz); -+ else -+ { -+ /* Initialize TMR_ADD with the initial frequency compensation value: -+ freqCompensation = (2^32 / frequency ratio) */ -+ /* frequency ratio = sorce clock/rtc clock = -+ * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */ -+ init_freq_comp = TRUE; -+ freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000, -+ p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz); -+ } -+ -+ /* check the legality of the relation between source and destination clocks */ -+ /* should be larger than 1.0001 */ -+ tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz; -+ if ((tmpDouble) <= 10001) -+ RETURN_ERROR(MAJOR, E_CONFLICT, -+ ("Invalid relation between source and destination clocks. Should be larger than 1.0001")); -+ -+ fman_rtc_init(p_RtcDriverParam, -+ p_MemMap, -+ FM_RTC_NUM_OF_ALARMS, -+ FM_RTC_NUM_OF_PERIODIC_PULSES, -+ FM_RTC_NUM_OF_EXT_TRIGGERS, -+ init_freq_comp, -+ freqCompensation, -+ p_Rtc->outputClockDivisor); -+ -+ /* Register the FM RTC interrupt */ -+ FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc); -+ -+ /* Free parameters structures */ -+ XX_Free(p_Rtc->p_RtcDriverParam); -+ p_Rtc->p_RtcDriverParam = NULL; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_Free(t_Handle h_FmRtc) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ -+ if (p_Rtc->p_RtcDriverParam) -+ { -+ XX_Free(p_Rtc->p_RtcDriverParam); -+ } -+ else -+ { -+ FM_RTC_Disable(h_FmRtc); -+ } -+ -+ /* Unregister FM RTC interrupt */ -+ FmUnregisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL); -+ XX_Free(p_Rtc); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc, -+ e_FmSrcClk srcClk, -+ uint32_t freqInMhz) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ p_Rtc->p_RtcDriverParam->src_clk = (enum fman_src_clock)srcClk; -+ if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM) -+ p_Rtc->p_RtcDriverParam->ext_src_clk_freq = freqInMhz; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ p_Rtc->clockPeriodNanoSec = period; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ p_Rtc->p_RtcDriverParam->bypass = enabled; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ p_Rtc->p_RtcDriverParam->invert_input_clk_phase = inverted; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ p_Rtc->p_RtcDriverParam->invert_output_clk_phase = inverted; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ p_Rtc->outputClockDivisor = divisor; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ p_Rtc->p_RtcDriverParam->pulse_realign = enable; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc, -+ uint8_t alarmId, -+ e_FmRtcAlarmPolarity alarmPolarity) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ if (alarmId >= FM_RTC_NUM_OF_ALARMS) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID")); -+ -+ p_Rtc->p_RtcDriverParam->alarm_polarity[alarmId] = -+ (enum fman_rtc_alarm_polarity)alarmPolarity; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc, -+ uint8_t triggerId, -+ e_FmRtcTriggerPolarity triggerPolarity) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID")); -+ } -+ -+ p_Rtc->p_RtcDriverParam->trigger_polarity[triggerId] = -+ (enum fman_rtc_trigger_polarity)triggerPolarity; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ fman_rtc_enable(p_Rtc->p_MemMap, resetClock); -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_Disable(t_Handle h_FmRtc) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ /* TODO A check must be added here, that no timestamping MAC's -+ * are working in this stage. */ -+ fman_rtc_disable(p_Rtc->p_MemMap); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ fman_rtc_set_timer_offset(p_Rtc->p_MemMap, offset); -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ uint64_t tmpAlarm; -+ bool enable = FALSE; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID")); -+ } -+ -+ if (p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, -+ ("Alarm time must be equal or larger than RTC period - %d nanoseconds", -+ p_Rtc->clockPeriodNanoSec)); -+ tmpAlarm = p_FmRtcAlarmParams->alarmTime; -+ if (do_div(tmpAlarm, p_Rtc->clockPeriodNanoSec)) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, -+ ("Alarm time must be a multiple of RTC period - %d nanoseconds", -+ p_Rtc->clockPeriodNanoSec)); -+ -+ if (p_FmRtcAlarmParams->f_AlarmCallback) -+ { -+ p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback; -+ p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration; -+ enable = TRUE; -+ } -+ -+ fman_rtc_set_alarm(p_Rtc->p_MemMap, p_FmRtcAlarmParams->alarmId, (unsigned long)tmpAlarm, enable); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ bool enable = FALSE; -+ uint64_t tmpFiper; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID")); -+ } -+ if (fman_rtc_is_enabled(p_Rtc->p_MemMap)) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled.")); -+ if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, -+ ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds", -+ p_Rtc->clockPeriodNanoSec)); -+ tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod; -+ if (do_div(tmpFiper, p_Rtc->clockPeriodNanoSec)) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, -+ ("Periodic pulse must be a multiple of RTC period - %d nanoseconds", -+ p_Rtc->clockPeriodNanoSec)); -+ if (tmpFiper & 0xffffffff00000000LL) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, -+ ("Periodic pulse/RTC Period must be smaller than 4294967296", -+ p_Rtc->clockPeriodNanoSec)); -+ -+ if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback) -+ { -+ p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback = -+ p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback; -+ enable = TRUE; -+ } -+ fman_rtc_set_periodic_pulse(p_Rtc->p_MemMap, p_FmRtcPeriodicPulseParams->periodicPulseId, (uint32_t)tmpFiper, enable); -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ if (periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID")); -+ } -+ -+ p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL; -+ fman_rtc_clear_periodic_pulse(p_Rtc->p_MemMap, periodicPulseId); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ bool enable = FALSE; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ if (p_FmRtcExternalTriggerParams->externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID")); -+ } -+ -+ if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback) -+ { -+ p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback; -+ enable = TRUE; -+ } -+ -+ fman_rtc_set_ext_trigger(p_Rtc->p_MemMap, p_FmRtcExternalTriggerParams->externalTriggerId, enable, p_FmRtcExternalTriggerParams->usePulseAsInput); -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ if (externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID")); -+ -+ p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL; -+ -+ fman_rtc_clear_external_trigger(p_Rtc->p_MemMap, externalTriggerId); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc, -+ uint8_t triggerId, -+ uint64_t *p_TimeStamp) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS) -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID")); -+ -+ *p_TimeStamp = fman_rtc_get_trigger_stamp(p_Rtc->p_MemMap, triggerId)*p_Rtc->clockPeriodNanoSec; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ *p_Ts = fman_rtc_get_timer(p_Rtc->p_MemMap)*p_Rtc->clockPeriodNanoSec; -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ do_div(ts, p_Rtc->clockPeriodNanoSec); -+ fman_rtc_set_timer(p_Rtc->p_MemMap, (int64_t)ts); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ *p_Compensation = fman_rtc_get_frequency_compensation(p_Rtc->p_MemMap); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ /* set the new freqCompensation */ -+ fman_rtc_set_frequency_compensation(p_Rtc->p_MemMap, freqCompensation); -+ -+ return E_OK; -+} -+ -+#ifdef CONFIG_PTP_1588_CLOCK_DPAA -+/*****************************************************************************/ -+t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ /* enable interrupt */ -+ fman_rtc_enable_interupt(p_Rtc->p_MemMap, events); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events) -+{ -+ t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE); -+ -+ /* disable interrupt */ -+ fman_rtc_disable_interupt(p_Rtc->p_MemMap, events); -+ -+ return E_OK; -+} -+#endif ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h -@@ -0,0 +1,96 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_rtc.h -+ -+ @Description Memory map and internal definitions for FM RTC IEEE1588 Timer driver. -+ -+ @Cautions None -+*//***************************************************************************/ -+ -+#ifndef __FM_RTC_H__ -+#define __FM_RTC_H__ -+ -+#include "std_ext.h" -+#include "fm_rtc_ext.h" -+ -+ -+#define __ERR_MODULE__ MODULE_FM_RTC -+ -+/* General definitions */ -+ -+#define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32)) -+#define DEFAULT_OUTPUT_CLOCK_DIVISOR 0x00000002 -+#define DEFAULT_BYPASS FALSE -+#define DEFAULT_CLOCK_PERIOD 1000 -+ -+ -+ -+typedef struct t_FmRtcAlarm -+{ -+ t_FmRtcExceptionsCallback *f_AlarmCallback; -+ bool clearOnExpiration; -+} t_FmRtcAlarm; -+ -+typedef struct t_FmRtcPeriodicPulse -+{ -+ t_FmRtcExceptionsCallback *f_PeriodicPulseCallback; -+} t_FmRtcPeriodicPulse; -+ -+typedef struct t_FmRtcExternalTrigger -+{ -+ t_FmRtcExceptionsCallback *f_ExternalTriggerCallback; -+} t_FmRtcExternalTrigger; -+ -+ -+/**************************************************************************//** -+ @Description RTC FM driver control structure. -+*//***************************************************************************/ -+typedef struct t_FmRtc -+{ -+ t_Part *p_Part; /**< Pointer to the integration device */ -+ t_Handle h_Fm; -+ t_Handle h_App; /**< Application handle */ -+ struct rtc_regs *p_MemMap; -+ uint32_t clockPeriodNanoSec; /**< RTC clock period in nano-seconds (for FS mode) */ -+ uint32_t srcClkFreqMhz; -+ uint16_t outputClockDivisor; /**< Output clock divisor (for FS mode) */ -+ t_FmRtcAlarm alarmParams[FM_RTC_NUM_OF_ALARMS]; -+ t_FmRtcPeriodicPulse periodicPulseParams[FM_RTC_NUM_OF_PERIODIC_PULSES]; -+ t_FmRtcExternalTrigger externalTriggerParams[FM_RTC_NUM_OF_EXT_TRIGGERS]; -+ struct rtc_cfg *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */ -+} t_FmRtc; -+ -+ -+#endif /* __FM_RTC_H__ */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c -@@ -0,0 +1,334 @@ -+/* -+ * Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "fsl_fman_rtc.h" -+ -+void fman_rtc_defconfig(struct rtc_cfg *cfg) -+{ -+ int i; -+ cfg->src_clk = DEFAULT_SRC_CLOCK; -+ cfg->invert_input_clk_phase = DEFAULT_INVERT_INPUT_CLK_PHASE; -+ cfg->invert_output_clk_phase = DEFAULT_INVERT_OUTPUT_CLK_PHASE; -+ cfg->pulse_realign = DEFAULT_PULSE_REALIGN; -+ for (i = 0; i < FMAN_RTC_MAX_NUM_OF_ALARMS; i++) -+ cfg->alarm_polarity[i] = DEFAULT_ALARM_POLARITY; -+ for (i = 0; i < FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS; i++) -+ cfg->trigger_polarity[i] = DEFAULT_TRIGGER_POLARITY; -+} -+ -+uint32_t fman_rtc_get_events(struct rtc_regs *regs) -+{ -+ return ioread32be(®s->tmr_tevent); -+} -+ -+uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask) -+{ -+ return ioread32be(®s->tmr_tevent) & ev_mask; -+} -+ -+uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs) -+{ -+ return ioread32be(®s->tmr_temask); -+} -+ -+void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask) -+{ -+ iowrite32be(mask, ®s->tmr_temask); -+} -+ -+void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events) -+{ -+ iowrite32be(events, ®s->tmr_tevent); -+} -+ -+uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs) -+{ -+ uint32_t event; -+ -+ event = ioread32be(®s->tmr_tevent); -+ event &= ioread32be(®s->tmr_temask); -+ -+ if (event) -+ iowrite32be(event, ®s->tmr_tevent); -+ return event; -+} -+ -+uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs) -+{ -+ return ioread32be(®s->tmr_add); -+} -+ -+void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val) -+{ -+ iowrite32be(val, ®s->tmr_add); -+} -+ -+void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t events) -+{ -+ fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) | events); -+} -+ -+void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t events) -+{ -+ fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) & ~events); -+} -+ -+void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, uint32_t val) -+{ -+ iowrite32be(val, ®s->tmr_alarm[index].tmr_alarm_l); -+} -+ -+void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val) -+{ -+ iowrite32be(val, ®s->tmr_fiper[index]); -+} -+ -+void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val) -+{ -+ iowrite32be((uint32_t)val, ®s->tmr_alarm[index].tmr_alarm_l); -+ iowrite32be((uint32_t)(val >> 32), ®s->tmr_alarm[index].tmr_alarm_h); -+} -+ -+void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val) -+{ -+ iowrite32be((uint32_t)val, ®s->tmr_off_l); -+ iowrite32be((uint32_t)(val >> 32), ®s->tmr_off_h); -+} -+ -+uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id) -+{ -+ uint64_t time; -+ /* TMR_CNT_L must be read first to get an accurate value */ -+ time = (uint64_t)ioread32be(®s->tmr_etts[id].tmr_etts_l); -+ time |= ((uint64_t)ioread32be(®s->tmr_etts[id].tmr_etts_h) -+ << 32); -+ -+ return time; -+} -+ -+uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs) -+{ -+ return ioread32be(®s->tmr_ctrl); -+} -+ -+void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val) -+{ -+ iowrite32be(val, ®s->tmr_ctrl); -+} -+ -+void fman_rtc_timers_soft_reset(struct rtc_regs *regs) -+{ -+ fman_rtc_set_timer_ctrl(regs, FMAN_RTC_TMR_CTRL_TMSR); -+ udelay(10); -+ fman_rtc_set_timer_ctrl(regs, 0); -+} -+ -+void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms, -+ int num_fipers, int num_ext_triggers, bool init_freq_comp, -+ uint32_t freq_compensation, uint32_t output_clock_divisor) -+{ -+ uint32_t tmr_ctrl; -+ int i; -+ -+ fman_rtc_timers_soft_reset(regs); -+ -+ /* Set the source clock */ -+ switch (cfg->src_clk) { -+ case E_FMAN_RTC_SOURCE_CLOCK_SYSTEM: -+ tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK; -+ break; -+ case E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR: -+ tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK; -+ break; -+ default: -+ /* Use a clock from the External TMR reference clock.*/ -+ tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK; -+ break; -+ } -+ -+ /* whatever period the user picked, the timestamp will advance in '1' -+ * every time the period passed. */ -+ tmr_ctrl |= ((1 << FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT) & -+ FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK); -+ -+ if (cfg->invert_input_clk_phase) -+ tmr_ctrl |= FMAN_RTC_TMR_CTRL_CIPH; -+ if (cfg->invert_output_clk_phase) -+ tmr_ctrl |= FMAN_RTC_TMR_CTRL_COPH; -+ -+ for (i = 0; i < num_alarms; i++) { -+ if (cfg->alarm_polarity[i] == -+ E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) -+ tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ALMP1 >> i); -+ } -+ -+ for (i = 0; i < num_ext_triggers; i++) -+ if (cfg->trigger_polarity[i] == -+ E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) -+ tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ETEP1 << i); -+ -+ if (!cfg->timer_slave_mode && cfg->bypass) -+ tmr_ctrl |= FMAN_RTC_TMR_CTRL_BYP; -+ -+ fman_rtc_set_timer_ctrl(regs, tmr_ctrl); -+ if (init_freq_comp) -+ fman_rtc_set_frequency_compensation(regs, freq_compensation); -+ -+ /* Clear TMR_ALARM registers */ -+ for (i = 0; i < num_alarms; i++) -+ fman_rtc_set_timer_alarm(regs, i, 0xFFFFFFFFFFFFFFFFLL); -+ -+ /* Clear TMR_TEVENT */ -+ fman_rtc_ack_event(regs, FMAN_RTC_TMR_TEVENT_ALL); -+ -+ /* Initialize TMR_TEMASK */ -+ fman_rtc_set_interrupt_mask(regs, 0); -+ -+ /* Clear TMR_FIPER registers */ -+ for (i = 0; i < num_fipers; i++) -+ fman_rtc_set_timer_fiper(regs, i, 0xFFFFFFFF); -+ -+ /* Initialize TMR_PRSC */ -+ iowrite32be(output_clock_divisor, ®s->tmr_prsc); -+ -+ /* Clear TMR_OFF */ -+ fman_rtc_set_timer_offset(regs, 0); -+} -+ -+bool fman_rtc_is_enabled(struct rtc_regs *regs) -+{ -+ return (bool)(fman_rtc_get_timer_ctrl(regs) & FMAN_RTC_TMR_CTRL_TE); -+} -+ -+void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock) -+{ -+ uint32_t tmr_ctrl = fman_rtc_get_timer_ctrl(regs); -+ -+ /* TODO check that no timestamping MACs are working in this stage. */ -+ if (reset_clock) { -+ fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TMSR)); -+ -+ udelay(10); -+ /* Clear TMR_OFF */ -+ fman_rtc_set_timer_offset(regs, 0); -+ } -+ -+ fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TE)); -+} -+ -+void fman_rtc_disable(struct rtc_regs *regs) -+{ -+ fman_rtc_set_timer_ctrl(regs, (fman_rtc_get_timer_ctrl(regs) -+ & ~(FMAN_RTC_TMR_CTRL_TE))); -+} -+ -+void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id) -+{ -+ uint32_t tmp_reg; -+ if (id == 0) -+ tmp_reg = FMAN_RTC_TMR_TEVENT_PP1; -+ else -+ tmp_reg = FMAN_RTC_TMR_TEVENT_PP2; -+ fman_rtc_disable_interupt(regs, tmp_reg); -+ -+ tmp_reg = fman_rtc_get_timer_ctrl(regs); -+ if (tmp_reg & FMAN_RTC_TMR_CTRL_FS) -+ fman_rtc_set_timer_ctrl(regs, tmp_reg & ~FMAN_RTC_TMR_CTRL_FS); -+ -+ fman_rtc_set_timer_fiper(regs, id, 0xFFFFFFFF); -+} -+ -+void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id) -+{ -+ uint32_t tmpReg, tmp_ctrl; -+ -+ if (id == 0) -+ tmpReg = FMAN_RTC_TMR_TEVENT_ETS1; -+ else -+ tmpReg = FMAN_RTC_TMR_TEVENT_ETS2; -+ fman_rtc_disable_interupt(regs, tmpReg); -+ -+ if (id == 0) -+ tmpReg = FMAN_RTC_TMR_CTRL_PP1L; -+ else -+ tmpReg = FMAN_RTC_TMR_CTRL_PP2L; -+ tmp_ctrl = fman_rtc_get_timer_ctrl(regs); -+ if (tmp_ctrl & tmpReg) -+ fman_rtc_set_timer_ctrl(regs, tmp_ctrl & ~tmpReg); -+} -+ -+void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable) -+{ -+ uint32_t tmpReg; -+ fman_rtc_set_timer_alarm(regs, id, val); -+ if (enable) { -+ if (id == 0) -+ tmpReg = FMAN_RTC_TMR_TEVENT_ALM1; -+ else -+ tmpReg = FMAN_RTC_TMR_TEVENT_ALM2; -+ fman_rtc_enable_interupt(regs, tmpReg); -+ } -+} -+ -+void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val, -+ bool enable) -+{ -+ uint32_t tmpReg; -+ fman_rtc_set_timer_fiper(regs, id, val); -+ if (enable) { -+ if (id == 0) -+ tmpReg = FMAN_RTC_TMR_TEVENT_PP1; -+ else -+ tmpReg = FMAN_RTC_TMR_TEVENT_PP2; -+ fman_rtc_enable_interupt(regs, tmpReg); -+ } -+} -+ -+void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable, -+ bool use_pulse_as_input) -+{ -+ uint32_t tmpReg; -+ if (enable) { -+ if (id == 0) -+ tmpReg = FMAN_RTC_TMR_TEVENT_ETS1; -+ else -+ tmpReg = FMAN_RTC_TMR_TEVENT_ETS2; -+ fman_rtc_enable_interupt(regs, tmpReg); -+ } -+ if (use_pulse_as_input) { -+ if (id == 0) -+ tmpReg = FMAN_RTC_TMR_CTRL_PP1L; -+ else -+ tmpReg = FMAN_RTC_TMR_CTRL_PP2L; -+ fman_rtc_set_timer_ctrl(regs, fman_rtc_get_timer_ctrl(regs) | tmpReg); -+ } -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile -@@ -0,0 +1,15 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc -+ -+ccflags-y += -I$(NCSW_FM_INC) -+ -+obj-y += fsl-ncsw-sp.o -+ -+fsl-ncsw-sp-objs := fm_sp.o fman_sp.o ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c -@@ -0,0 +1,757 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_sp.c -+ -+ @Description FM PCD Storage profile ... -+*//***************************************************************************/ -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "string_ext.h" -+#include "debug_ext.h" -+#include "net_ext.h" -+ -+#include "fm_vsp_ext.h" -+#include "fm_sp.h" -+#include "fm_common.h" -+#include "fsl_fman_sp.h" -+ -+ -+#if (DPAA_VERSION >= 11) -+static t_Error CheckParamsGeneratedInternally(t_FmVspEntry *p_FmVspEntry) -+{ -+ t_Error err = E_OK; -+ -+ if ((err = FmSpCheckIntContextParams(&p_FmVspEntry->intContext))!= E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ if ((err = FmSpCheckBufMargins(&p_FmVspEntry->bufMargins)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ return err; -+ -+} -+ -+static t_Error CheckParams(t_FmVspEntry *p_FmVspEntry) -+{ -+ t_Error err = E_OK; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->h_Fm, E_INVALID_HANDLE); -+ -+ if ((err = FmSpCheckBufPoolsParams(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, -+ p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, -+ p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)) != E_OK) -+ -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset & ~FM_LIODN_OFFSET_MASK) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1)); -+ -+ err = FmVSPCheckRelativeProfile(p_FmVspEntry->h_Fm, -+ p_FmVspEntry->portType, -+ p_FmVspEntry->portId, -+ p_FmVspEntry->relativeProfileId); -+ -+ return err; -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ -+/*****************************************************************************/ -+/* Inter-module API routines */ -+/*****************************************************************************/ -+void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, -+ uint8_t *orderedArray, -+ uint16_t *sizesArray) -+{ -+ uint16_t bufSize = 0; -+ int i=0, j=0, k=0; -+ -+ /* First we copy the external buffers pools information to an ordered local array */ -+ for (i=0;inumOfPoolsUsed;i++) -+ { -+ /* get pool size */ -+ bufSize = p_FmExtPools->extBufPool[i].size; -+ -+ /* keep sizes in an array according to poolId for direct access */ -+ sizesArray[p_FmExtPools->extBufPool[i].id] = bufSize; -+ -+ /* save poolId in an ordered array according to size */ -+ for (j=0;j<=i;j++) -+ { -+ /* this is the next free place in the array */ -+ if (j==i) -+ orderedArray[i] = p_FmExtPools->extBufPool[i].id; -+ else -+ { -+ /* find the right place for this poolId */ -+ if (bufSize < sizesArray[orderedArray[j]]) -+ { -+ /* move the poolIds one place ahead to make room for this poolId */ -+ for (k=i;k>j;k--) -+ orderedArray[k] = orderedArray[k-1]; -+ -+ /* now k==j, this is the place for the new size */ -+ orderedArray[k] = p_FmExtPools->extBufPool[i].id; -+ break; -+ } -+ } -+ } -+ } -+} -+ -+t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools, -+ t_FmBackupBmPools *p_FmBackupBmPools, -+ t_FmBufPoolDepletion *p_FmBufPoolDepletion) -+{ -+ -+ int i = 0, j = 0; -+ bool found; -+ uint8_t count = 0; -+ -+ if (p_FmExtPools) -+ { -+ if (p_FmExtPools->numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS)); -+ -+ for (i=0;inumOfPoolsUsed;i++) -+ { -+ if (p_FmExtPools->extBufPool[i].id >= BM_MAX_NUM_OF_POOLS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS)); -+ if (!p_FmExtPools->extBufPool[i].size) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i)); -+ } -+ } -+ if (!p_FmExtPools && (p_FmBackupBmPools || p_FmBufPoolDepletion)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("backupBmPools ot bufPoolDepletion can not be defined without external pools")); -+ -+ /* backup BM pools indication is valid only for some chip derivatives -+ (limited by the config routine) */ -+ if (p_FmBackupBmPools) -+ { -+ if (p_FmBackupBmPools->numOfBackupPools >= p_FmExtPools->numOfPoolsUsed) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed")); -+ found = FALSE; -+ for (i = 0;inumOfBackupPools;i++) -+ { -+ -+ for (j=0;jnumOfPoolsUsed;j++) -+ { -+ if (p_FmBackupBmPools->poolIds[i] == p_FmExtPools->extBufPool[j].id) -+ { -+ found = TRUE; -+ break; -+ } -+ } -+ if (!found) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id")); -+ else -+ found = FALSE; -+ } -+ } -+ -+ /* up to extBufPools.numOfPoolsUsed pools may be defined */ -+ if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->poolsGrpModeEnable) -+ { -+ if ((p_FmBufPoolDepletion->numOfPools > p_FmExtPools->numOfPoolsUsed)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools can't be larger than %d and can't be larger than numOfPoolsUsed", FM_PORT_MAX_NUM_OF_EXT_POOLS)); -+ -+ if (!p_FmBufPoolDepletion->numOfPools) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when poolsGrpModeEnable=TRUE")); -+ -+ found = FALSE; -+ count = 0; -+ /* for each pool that is in poolsToConsider, check if it is defined -+ in extBufPool */ -+ for (i=0;ipoolsToConsider[i]) -+ { -+ for (j=0;jnumOfPoolsUsed;j++) -+ { -+ if (i == p_FmExtPools->extBufPool[j].id) -+ { -+ found = TRUE; -+ count++; -+ break; -+ } -+ } -+ if (!found) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used.")); -+ else -+ found = FALSE; -+ } -+ } -+ /* check that the number of pools that we have checked is equal to the number announced by the user */ -+ if (count != p_FmBufPoolDepletion->numOfPools) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined.")); -+ } -+ -+ if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->singlePoolModeEnable) -+ { -+ /* calculate vector for number of pools depletion */ -+ found = FALSE; -+ count = 0; -+ for (i=0;ipoolsToConsiderForSingleMode[i]) -+ { -+ for (j=0;jnumOfPoolsUsed;j++) -+ { -+ if (i == p_FmExtPools->extBufPool[j].id) -+ { -+ found = TRUE; -+ count++; -+ break; -+ } -+ } -+ if (!found) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used.")); -+ else -+ found = FALSE; -+ } -+ } -+ if (!count) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion.")); -+ } -+ -+ return E_OK; -+} -+ -+t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy) -+{ -+ /* Check that divisible by 16 and not larger than 240 */ -+ if (p_FmSpIntContextDataCopy->intContextOffset >MAX_INT_OFFSET) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET)); -+ if (p_FmSpIntContextDataCopy->intContextOffset % OFFSET_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS)); -+ -+ /* check that ic size+ic internal offset, does not exceed ic block size */ -+ if (p_FmSpIntContextDataCopy->size + p_FmSpIntContextDataCopy->intContextOffset > MAX_IC_SIZE) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE)); -+ /* Check that divisible by 16 and not larger than 256 */ -+ if (p_FmSpIntContextDataCopy->size % OFFSET_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS)); -+ -+ /* Check that divisible by 16 and not larger than 4K */ -+ if (p_FmSpIntContextDataCopy->extBufOffset > MAX_EXT_OFFSET) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET)); -+ if (p_FmSpIntContextDataCopy->extBufOffset % OFFSET_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS)); -+ -+ return E_OK; -+} -+ -+t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins) -+{ -+ /* Check the margin definition */ -+ if (p_FmSpBufMargins->startMargins > MAX_EXT_BUFFER_OFFSET) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET)); -+ if (p_FmSpBufMargins->endMargins > MAX_EXT_BUFFER_OFFSET) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET)); -+ -+ return E_OK; -+} -+ -+t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy, -+ t_FmBufferPrefixContent *p_BufferPrefixContent, -+ t_FmSpBufMargins *p_FmSpBufMargins, -+ t_FmSpBufferOffsets *p_FmSpBufferOffsets, -+ uint8_t *internalBufferOffset) -+{ -+ uint32_t tmp; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmSpIntContextDataCopy, E_INVALID_VALUE); -+ ASSERT_COND(p_FmSpIntContextDataCopy); -+ ASSERT_COND(p_BufferPrefixContent); -+ ASSERT_COND(p_FmSpBufMargins); -+ ASSERT_COND(p_FmSpBufferOffsets); -+ -+ /* Align start of internal context data to 16 byte */ -+ p_FmSpIntContextDataCopy->extBufOffset = -+ (uint16_t)((p_BufferPrefixContent->privDataSize & (OFFSET_UNITS-1)) ? -+ ((p_BufferPrefixContent->privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) : -+ p_BufferPrefixContent->privDataSize); -+ -+ /* Translate margin and intContext params to FM parameters */ -+ /* Initialize with illegal value. Later we'll set legal values. */ -+ p_FmSpBufferOffsets->prsResultOffset = (uint32_t)ILLEGAL_BASE; -+ p_FmSpBufferOffsets->timeStampOffset = (uint32_t)ILLEGAL_BASE; -+ p_FmSpBufferOffsets->hashResultOffset= (uint32_t)ILLEGAL_BASE; -+ p_FmSpBufferOffsets->pcdInfoOffset = (uint32_t)ILLEGAL_BASE; -+ -+ /* Internally the driver supports 4 options -+ 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll -+ relate to it as 1). -+ 2. All IC context (from AD) not including debug.*/ -+ -+ /* This 'if' covers option 2. We copy from beginning of context. */ -+ if (p_BufferPrefixContent->passAllOtherPCDInfo) -+ { -+ p_FmSpIntContextDataCopy->size = 128; /* must be aligned to 16 */ -+ /* Start copying data after 16 bytes (FD) from the beginning of the internal context */ -+ p_FmSpIntContextDataCopy->intContextOffset = 16; -+ -+ if (p_BufferPrefixContent->passAllOtherPCDInfo) -+ p_FmSpBufferOffsets->pcdInfoOffset = p_FmSpIntContextDataCopy->extBufOffset; -+ if (p_BufferPrefixContent->passPrsResult) -+ p_FmSpBufferOffsets->prsResultOffset = -+ (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 16); -+ if (p_BufferPrefixContent->passTimeStamp) -+ p_FmSpBufferOffsets->timeStampOffset = -+ (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 48); -+ if (p_BufferPrefixContent->passHashResult) -+ p_FmSpBufferOffsets->hashResultOffset = -+ (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 56); -+ } -+ else -+ { -+ /* This case covers the options under 1 */ -+ /* Copy size must be in 16-byte granularity. */ -+ p_FmSpIntContextDataCopy->size = -+ (uint16_t)((p_BufferPrefixContent->passPrsResult ? 32 : 0) + -+ ((p_BufferPrefixContent->passTimeStamp || -+ p_BufferPrefixContent->passHashResult) ? 16 : 0)); -+ -+ /* Align start of internal context data to 16 byte */ -+ p_FmSpIntContextDataCopy->intContextOffset = -+ (uint8_t)(p_BufferPrefixContent->passPrsResult ? 32 : -+ ((p_BufferPrefixContent->passTimeStamp || -+ p_BufferPrefixContent->passHashResult) ? 64 : 0)); -+ -+ if (p_BufferPrefixContent->passPrsResult) -+ p_FmSpBufferOffsets->prsResultOffset = p_FmSpIntContextDataCopy->extBufOffset; -+ if (p_BufferPrefixContent->passTimeStamp) -+ p_FmSpBufferOffsets->timeStampOffset = p_BufferPrefixContent->passPrsResult ? -+ (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult)) : -+ p_FmSpIntContextDataCopy->extBufOffset; -+ if (p_BufferPrefixContent->passHashResult) -+ /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */ -+ p_FmSpBufferOffsets->hashResultOffset = p_BufferPrefixContent->passPrsResult ? -+ (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult) + 8) : -+ p_FmSpIntContextDataCopy->extBufOffset + 8; -+ } -+ -+ if (p_FmSpIntContextDataCopy->size) -+ p_FmSpBufMargins->startMargins = -+ (uint16_t)(p_FmSpIntContextDataCopy->extBufOffset + -+ p_FmSpIntContextDataCopy->size); -+ else -+ /* No Internal Context passing, STartMargin is immediately after privateInfo */ -+ p_FmSpBufMargins->startMargins = p_BufferPrefixContent->privDataSize; -+ -+ /* save extra space for manip in both external and internal buffers */ -+ if (p_BufferPrefixContent->manipExtraSpace) -+ { -+ uint8_t extraSpace; -+#ifdef FM_CAPWAP_SUPPORT -+ if ((p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE) >= 256) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("p_BufferPrefixContent->manipExtraSpace should be less than %d", -+ 256-CAPWAP_FRAG_EXTRA_SPACE)); -+ extraSpace = (uint8_t)(p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE); -+#else -+ extraSpace = p_BufferPrefixContent->manipExtraSpace; -+#endif /* FM_CAPWAP_SUPPORT */ -+ p_FmSpBufferOffsets->manipOffset = p_FmSpBufMargins->startMargins; -+ p_FmSpBufMargins->startMargins += extraSpace; -+ *internalBufferOffset = extraSpace; -+ } -+ -+ /* align data start */ -+ tmp = (uint32_t)(p_FmSpBufMargins->startMargins % p_BufferPrefixContent->dataAlign); -+ if (tmp) -+ p_FmSpBufMargins->startMargins += (p_BufferPrefixContent->dataAlign-tmp); -+ p_FmSpBufferOffsets->dataOffset = p_FmSpBufMargins->startMargins; -+ -+ return E_OK; -+} -+/*********************** End of inter-module routines ************************/ -+ -+ -+#if (DPAA_VERSION >= 11) -+/*****************************************************************************/ -+/* API routines */ -+/*****************************************************************************/ -+t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams) -+{ -+ t_FmVspEntry *p_FmVspEntry = NULL; -+ struct fm_storage_profile_params fm_vsp_params; -+ -+ p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry)); -+ if (!p_FmVspEntry) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed")); -+ return NULL; -+ } -+ memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry)); -+ -+ p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams)); -+ if (!p_FmVspEntry->p_FmVspEntryDriverParams) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed")); -+ XX_Free(p_FmVspEntry); -+ return NULL; -+ } -+ memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams)); -+ fman_vsp_defconfig(&fm_vsp_params); -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr; -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr; -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr; -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data; -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize; -+ p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather; -+ p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize; -+ p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult; -+ p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp; -+ p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo -+ = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp; -+ p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign; -+ p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset; -+ -+ memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools)); -+ p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm; -+ p_FmVspEntry->portType = p_FmVspParams->portParams.portType; -+ p_FmVspEntry->portId = p_FmVspParams->portParams.portId; -+ -+ p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId; -+ -+ return p_FmVspEntry; -+} -+ -+t_Error FM_VSP_Init(t_Handle h_FmVsp) -+{ -+ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp; -+ struct fm_storage_profile_params fm_vsp_params; -+ uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS]; -+ uint16_t sizesArray[BM_MAX_NUM_OF_POOLS]; -+ t_Error err; -+ uint16_t absoluteProfileId = 0; -+ int i = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams,E_INVALID_HANDLE); -+ -+ CHECK_INIT_PARAMETERS(p_FmVspEntry, CheckParams); -+ -+ memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS); -+ memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS); -+ -+ err = FmSpBuildBufferStructure(&p_FmVspEntry->intContext, -+ &p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, -+ &p_FmVspEntry->bufMargins, -+ &p_FmVspEntry->bufferOffsets, -+ &p_FmVspEntry->internalBufferOffset); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ -+ err = CheckParamsGeneratedInternally(p_FmVspEntry); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ -+ p_FmVspEntry->p_FmSpRegsBase = -+ (struct fm_pcd_storage_profile_regs *)FmGetVSPBaseAddr(p_FmVspEntry->h_Fm); -+ if (!p_FmVspEntry->p_FmSpRegsBase) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("impossible to initialize SpRegsBase")); -+ -+ /* order external buffer pools in ascending order of buffer pools sizes */ -+ FmSpSetBufPoolsInAscOrderOfBufSizes(&(p_FmVspEntry->p_FmVspEntryDriverParams)->extBufPools, -+ orderedArray, -+ sizesArray); -+ -+ p_FmVspEntry->extBufPools.numOfPoolsUsed = -+ p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools.numOfPoolsUsed; -+ for (i = 0; i < p_FmVspEntry->extBufPools.numOfPoolsUsed; i++) -+ { -+ p_FmVspEntry->extBufPools.extBufPool[i].id = orderedArray[i]; -+ p_FmVspEntry->extBufPools.extBufPool[i].size = sizesArray[orderedArray[i]]; -+ } -+ -+ /* on user responsibility to fill it according requirement */ -+ memset(&fm_vsp_params, 0, sizeof(struct fm_storage_profile_params)); -+ fm_vsp_params.dma_swap_data = p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData; -+ fm_vsp_params.int_context_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr; -+ fm_vsp_params.header_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr; -+ fm_vsp_params.scatter_gather_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr; -+ fm_vsp_params.dma_write_optimize = p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize; -+ fm_vsp_params.liodn_offset = p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset; -+ fm_vsp_params.no_scather_gather = p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather; -+ -+ if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion) -+ { -+ fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = TRUE; -+ fm_vsp_params.buf_pool_depletion.pools_grp_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsGrpModeEnable; -+ fm_vsp_params.buf_pool_depletion.num_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->numOfPools; -+ fm_vsp_params.buf_pool_depletion.pools_to_consider = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsider; -+ fm_vsp_params.buf_pool_depletion.single_pool_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->singlePoolModeEnable; -+ fm_vsp_params.buf_pool_depletion.pools_to_consider_for_single_mode = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsiderForSingleMode; -+ fm_vsp_params.buf_pool_depletion.has_pfc_priorities = TRUE; -+ fm_vsp_params.buf_pool_depletion.pfc_priorities_en = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->pfcPrioritiesEn; -+ } -+ else -+ fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = FALSE; -+ -+ if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools) -+ { -+ fm_vsp_params.backup_pools.num_backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->numOfBackupPools; -+ fm_vsp_params.backup_pools.pool_ids = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->poolIds; -+ } -+ else -+ fm_vsp_params.backup_pools.num_backup_pools = 0; -+ -+ fm_vsp_params.fm_ext_pools.num_pools_used = p_FmVspEntry->extBufPools.numOfPoolsUsed; -+ fm_vsp_params.fm_ext_pools.ext_buf_pool = (struct fman_ext_pool_params*)&p_FmVspEntry->extBufPools.extBufPool; -+ fm_vsp_params.buf_margins = (struct fman_sp_buf_margins*)&p_FmVspEntry->bufMargins; -+ fm_vsp_params.int_context = (struct fman_sp_int_context_data_copy*)&p_FmVspEntry->intContext; -+ -+ /* no check on err - it was checked earlier */ -+ FmVSPGetAbsoluteProfileId(p_FmVspEntry->h_Fm, -+ p_FmVspEntry->portType, -+ p_FmVspEntry->portId, -+ p_FmVspEntry->relativeProfileId, -+ &absoluteProfileId); -+ -+ ASSERT_COND(p_FmVspEntry->p_FmSpRegsBase); -+ ASSERT_COND(fm_vsp_params.int_context); -+ ASSERT_COND(fm_vsp_params.buf_margins); -+ ASSERT_COND((absoluteProfileId <= FM_VSP_MAX_NUM_OF_ENTRIES)); -+ -+ /* Set all registers related to VSP */ -+ fman_vsp_init(p_FmVspEntry->p_FmSpRegsBase, absoluteProfileId, &fm_vsp_params,FM_PORT_MAX_NUM_OF_EXT_POOLS, BM_MAX_NUM_OF_POOLS, FM_MAX_NUM_OF_PFC_PRIORITIES); -+ -+ p_FmVspEntry->absoluteSpId = absoluteProfileId; -+ -+ if (p_FmVspEntry->p_FmVspEntryDriverParams) -+ XX_Free(p_FmVspEntry->p_FmVspEntryDriverParams); -+ p_FmVspEntry->p_FmVspEntryDriverParams = NULL; -+ -+ return E_OK; -+} -+ -+t_Error FM_VSP_Free(t_Handle h_FmVsp) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp; -+ SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE); -+ XX_Free(p_FmVspEntry); -+ return E_OK; -+} -+ -+t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, t_FmBufferPrefixContent *p_FmBufferPrefixContent) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); -+ -+ memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent)); -+ /* if dataAlign was not initialized by user, we return to driver's default */ -+ if (!p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign) -+ p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign; -+ -+ return E_OK; -+} -+ -+t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); -+ -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = swapData; -+ -+ return E_OK; -+} -+ -+t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, e_FmDmaCacheOption intContextCacheAttr) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); -+ -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = intContextCacheAttr; -+ -+ return E_OK; -+} -+ -+t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); -+ -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = headerCacheAttr; -+ -+ return E_OK; -+} -+ -+t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, e_FmDmaCacheOption scatterGatherCacheAttr) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); -+ -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = scatterGatherCacheAttr; -+ -+ return E_OK; -+} -+ -+t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); -+ -+ -+ p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = optimize; -+ -+ return E_OK; -+} -+ -+t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); -+ -+ -+ p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = noScatherGather; -+ -+ return E_OK; -+} -+ -+t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE); -+ -+ p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion)); -+ if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed")); -+ memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion)); -+ -+ return E_OK; -+} -+ -+t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE); -+ -+ p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools)); -+ if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed")); -+ memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools)); -+ -+ return E_OK; -+} -+ -+uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, 0); -+ -+ return p_FmVspEntry->bufferOffsets.dataOffset; -+} -+ -+uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL); -+ -+ if (p_FmVspEntry->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE) -+ return NULL; -+ -+ return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.pcdInfoOffset); -+} -+ -+t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL); -+ -+ if (p_FmVspEntry->bufferOffsets.prsResultOffset == ILLEGAL_BASE) -+ return NULL; -+ -+ return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.prsResultOffset); -+} -+ -+uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL); -+ -+ if (p_FmVspEntry->bufferOffsets.timeStampOffset == ILLEGAL_BASE) -+ return NULL; -+ -+ return (uint64_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.timeStampOffset); -+} -+ -+uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data) -+{ -+ t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL); -+ -+ if (p_FmVspEntry->bufferOffsets.hashResultOffset == ILLEGAL_BASE) -+ return NULL; -+ -+ return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.hashResultOffset); -+} -+ -+#endif /* (DPAA_VERSION >= 11) */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h -@@ -0,0 +1,85 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_sp.h -+ -+ @Description FM SP ... -+*//***************************************************************************/ -+#ifndef __FM_SP_H -+#define __FM_SP_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "list_ext.h" -+ -+#include "fm_sp_common.h" -+#include "fm_common.h" -+ -+ -+#define __ERR_MODULE__ MODULE_FM_SP -+ -+typedef struct { -+ t_FmBufferPrefixContent bufferPrefixContent; -+ e_FmDmaSwapOption dmaSwapData; -+ e_FmDmaCacheOption dmaIntContextCacheAttr; -+ e_FmDmaCacheOption dmaHeaderCacheAttr; -+ e_FmDmaCacheOption dmaScatterGatherCacheAttr; -+ bool dmaWriteOptimize; -+ uint16_t liodnOffset; -+ bool noScatherGather; -+ t_FmBufPoolDepletion *p_BufPoolDepletion; -+ t_FmBackupBmPools *p_BackupBmPools; -+ t_FmExtPools extBufPools; -+} t_FmVspEntryDriverParams; -+ -+typedef struct { -+ bool valid; -+ volatile bool lock; -+ uint8_t pointedOwners; -+ uint16_t absoluteSpId; -+ uint8_t internalBufferOffset; -+ t_FmSpBufMargins bufMargins; -+ t_FmSpIntContextDataCopy intContext; -+ t_FmSpBufferOffsets bufferOffsets; -+ t_Handle h_Fm; -+ e_FmPortType portType; /**< Port type */ -+ uint8_t portId; /**< Port Id - relative to type */ -+ uint8_t relativeProfileId; -+ struct fm_pcd_storage_profile_regs *p_FmSpRegsBase; -+ t_FmExtPools extBufPools; -+ t_FmVspEntryDriverParams *p_FmVspEntryDriverParams; -+} t_FmVspEntry; -+ -+ -+#endif /* __FM_SP_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c -@@ -0,0 +1,197 @@ -+/* -+ * Copyright 2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "fsl_fman_sp.h" -+ -+ -+uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs, -+ uint16_t index) -+{ -+ struct fm_pcd_storage_profile_regs *sp_regs; -+ sp_regs = ®s[index]; -+ return ioread32be(&sp_regs->fm_sp_acnt); -+} -+ -+void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs, -+ uint16_t index, uint32_t value) -+{ -+ struct fm_pcd_storage_profile_regs *sp_regs; -+ sp_regs = ®s[index]; -+ iowrite32be(value, &sp_regs->fm_sp_acnt); -+} -+ -+void fman_vsp_defconfig(struct fm_storage_profile_params *cfg) -+{ -+ cfg->dma_swap_data = -+ DEFAULT_FMAN_SP_DMA_SWAP_DATA; -+ cfg->int_context_cache_attr = -+ DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR; -+ cfg->header_cache_attr = -+ DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR; -+ cfg->scatter_gather_cache_attr = -+ DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR; -+ cfg->dma_write_optimize = -+ DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE; -+ cfg->no_scather_gather = -+ DEFAULT_FMAN_SP_NO_SCATTER_GATHER; -+} -+ -+static inline uint32_t calc_vec_dep(int max_pools, bool *pools, -+ struct fman_ext_pools *ext_buf_pools, uint32_t mask) -+{ -+ int i, j; -+ uint32_t vector = 0; -+ for (i = 0; i < max_pools; i++) -+ if (pools[i]) -+ for (j = 0; j < ext_buf_pools->num_pools_used; j++) -+ if (i == ext_buf_pools->ext_buf_pool[j].id) { -+ vector |= mask >> j; -+ break; -+ } -+ return vector; -+} -+ -+void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs, -+ uint16_t index, struct fm_storage_profile_params *fm_vsp_params, -+ int port_max_num_of_ext_pools, int bm_max_num_of_pools, -+ int max_num_of_pfc_priorities) -+{ -+ int i = 0, j = 0; -+ struct fm_pcd_storage_profile_regs *sp_regs; -+ uint32_t tmp_reg, vector; -+ struct fman_ext_pools *ext_buf_pools = &fm_vsp_params->fm_ext_pools; -+ struct fman_buf_pool_depletion *buf_pool_depletion = -+ &fm_vsp_params->buf_pool_depletion; -+ struct fman_backup_bm_pools *backup_pools = -+ &fm_vsp_params->backup_pools; -+ struct fman_sp_int_context_data_copy *int_context_data_copy = -+ fm_vsp_params->int_context; -+ struct fman_sp_buf_margins *external_buffer_margins = -+ fm_vsp_params->buf_margins; -+ bool no_scather_gather = fm_vsp_params->no_scather_gather; -+ uint16_t liodn_offset = fm_vsp_params->liodn_offset; -+ -+ sp_regs = ®s[index]; -+ -+ /* fill external buffers manager pool information register*/ -+ for (i = 0; i < ext_buf_pools->num_pools_used; i++) { -+ tmp_reg = FMAN_SP_EXT_BUF_POOL_VALID | -+ FMAN_SP_EXT_BUF_POOL_EN_COUNTER; -+ tmp_reg |= ((uint32_t)ext_buf_pools->ext_buf_pool[i].id << -+ FMAN_SP_EXT_BUF_POOL_ID_SHIFT); -+ tmp_reg |= ext_buf_pools->ext_buf_pool[i].size; -+ /* functionality available only for some deriviatives -+ (limited by config) */ -+ for (j = 0; j < backup_pools->num_backup_pools; j++) -+ if (ext_buf_pools->ext_buf_pool[i].id == -+ backup_pools->pool_ids[j]) { -+ tmp_reg |= FMAN_SP_EXT_BUF_POOL_BACKUP; -+ break; -+ } -+ iowrite32be(tmp_reg, &sp_regs->fm_sp_ebmpi[i]); -+ } -+ -+ /* clear unused pools */ -+ for (i = ext_buf_pools->num_pools_used; -+ i < port_max_num_of_ext_pools; i++) -+ iowrite32be(0, &sp_regs->fm_sp_ebmpi[i]); -+ -+ /* fill pool depletion register*/ -+ tmp_reg = 0; -+ if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->pools_grp_mode_enable) { -+ /* calculate vector for number of pools depletion */ -+ vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion-> -+ pools_to_consider, ext_buf_pools, 0x80000000); -+ -+ /* configure num of pools and vector for number of pools mode */ -+ tmp_reg |= (((uint32_t)buf_pool_depletion->num_pools - 1) << -+ FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT); -+ tmp_reg |= vector; -+ } -+ -+ if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->single_pool_mode_enable) { -+ /* calculate vector for number of pools depletion */ -+ vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion-> -+ pools_to_consider_for_single_mode, -+ ext_buf_pools, 0x00000080); -+ -+ /* configure num of pools and vector for number of pools mode */ -+ tmp_reg |= vector; -+ } -+ -+ /* fill QbbPEV */ -+ if (buf_pool_depletion->buf_pool_depletion_enabled) { -+ vector = 0; -+ for (i = 0; i < max_num_of_pfc_priorities; i++) -+ if (buf_pool_depletion->pfc_priorities_en[i] == TRUE) -+ vector |= 0x00000100 << i; -+ tmp_reg |= vector; -+ } -+ iowrite32be(tmp_reg, &sp_regs->fm_sp_mpd); -+ -+ /* fill dma attributes register */ -+ tmp_reg = 0; -+ tmp_reg |= (uint32_t)fm_vsp_params->dma_swap_data << -+ FMAN_SP_DMA_ATTR_SWP_SHIFT; -+ tmp_reg |= (uint32_t)fm_vsp_params->int_context_cache_attr << -+ FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT; -+ tmp_reg |= (uint32_t)fm_vsp_params->header_cache_attr << -+ FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT; -+ tmp_reg |= (uint32_t)fm_vsp_params->scatter_gather_cache_attr << -+ FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT; -+ if (fm_vsp_params->dma_write_optimize) -+ tmp_reg |= FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE; -+ iowrite32be(tmp_reg, &sp_regs->fm_sp_da); -+ -+ /* IC parameters - fill internal context parameters register */ -+ tmp_reg = 0; -+ tmp_reg |= (((uint32_t)int_context_data_copy->ext_buf_offset/ -+ OFFSET_UNITS) << FMAN_SP_IC_TO_EXT_SHIFT); -+ tmp_reg |= (((uint32_t)int_context_data_copy->int_context_offset/ -+ OFFSET_UNITS) << FMAN_SP_IC_FROM_INT_SHIFT); -+ tmp_reg |= (((uint32_t)int_context_data_copy->size/OFFSET_UNITS) << -+ FMAN_SP_IC_SIZE_SHIFT); -+ iowrite32be(tmp_reg, &sp_regs->fm_sp_icp); -+ -+ /* buffer margins - fill external buffer margins register */ -+ tmp_reg = 0; -+ tmp_reg |= (((uint32_t)external_buffer_margins->start_margins) << -+ FMAN_SP_EXT_BUF_MARG_START_SHIFT); -+ tmp_reg |= (((uint32_t)external_buffer_margins->end_margins) << -+ FMAN_SP_EXT_BUF_MARG_END_SHIFT); -+ if (no_scather_gather) -+ tmp_reg |= FMAN_SP_SG_DISABLE; -+ iowrite32be(tmp_reg, &sp_regs->fm_sp_ebm); -+ -+ /* buffer margins - fill spliodn register */ -+ iowrite32be(liodn_offset, &sp_regs->fm_sp_spliodn); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c -@@ -0,0 +1,5216 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm.c -+ -+ @Description FM driver routines implementation. -+*//***************************************************************************/ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "xx_ext.h" -+#include "string_ext.h" -+#include "sprint_ext.h" -+#include "debug_ext.h" -+#include "fm_muram_ext.h" -+#include -+ -+#include "fm_common.h" -+#include "fm_ipc.h" -+#include "fm.h" -+#ifndef CONFIG_FMAN_ARM -+#include -+#endif -+#include "fsl_fman.h" -+ -+ -+/****************************************/ -+/* static functions */ -+/****************************************/ -+ -+static volatile bool blockingFlag = FALSE; -+static void IpcMsgCompletionCB(t_Handle h_Fm, -+ uint8_t *p_Msg, -+ uint8_t *p_Reply, -+ uint32_t replyLength, -+ t_Error status) -+{ -+ UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status); -+ blockingFlag = FALSE; -+} -+ -+static void FreeInitResources(t_Fm *p_Fm) -+{ -+ if (p_Fm->camBaseAddr) -+ FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr)); -+ if (p_Fm->fifoBaseAddr) -+ FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr)); -+ if (p_Fm->resAddr) -+ FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr)); -+} -+ -+static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm) -+{ -+ t_FMIramRegs *p_Iram; -+ -+ ASSERT_COND(p_Fm); -+ p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); -+ -+ return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY); -+} -+ -+static t_Error CheckFmParameters(t_Fm *p_Fm) -+{ -+ if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->resetOnInit) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!")); -+#if (DPAA_VERSION < 11) -+ if (!p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats || -+ (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS)); -+#endif /* (DPAA_VERSION < 11) */ -+ if (p_Fm->p_FmDriverParam->dma_cam_num_of_entries % DMA_CAM_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be divisble by %d", DMA_CAM_UNITS)); -+// if (!p_Fm->p_FmDriverParam->dma_cam_num_of_entries || (p_Fm->p_FmDriverParam->dma_cam_num_of_entries > DMA_MODE_MAX_CAM_NUM_OF_ENTRIES)) -+// RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be in the range 1 - %d", DMA_MODE_MAX_CAM_NUM_OF_ENTRIES)); -+ if (p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer > DMA_THRESH_MAX_COMMQ) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ)); -+ if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer > DMA_THRESH_MAX_COMMQ) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ)); -+ if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer >= p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer must be smaller than dma_comm_qtsh_asrt_emer")); -+#if (DPAA_VERSION < 11) -+ if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF)); -+ if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF)); -+ if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer must be smaller than dma_read_buf_tsh_asrt_emer")); -+ if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF)); -+ if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF)); -+ if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer must be smaller than dma_write_buf_tsh_asrt_emer")); -+#else /* (DPAA_VERSION >= 11) */ -+ if ((p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_READ_EM)|| -+ (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_WRITE_EM) || -+ (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_dbg_cnt_mode value not supported by this integration.")); -+ if ((p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_READ_EMERGENCY)|| -+ (p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_WRITE_EMERGENCY)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration.")); -+ if (p_Fm->p_FmDriverParam->dma_stop_on_bus_error) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_stop_on_bus_error not supported by this integration.")); -+#ifdef FM_AID_MODE_NO_TNUM_SW005 -+ if (p_Fm->p_FmDriverParam->dma_aid_mode != E_FMAN_DMA_AID_OUT_PORT_ID) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_aid_mode not supported by this integration.")); -+#endif /* FM_AID_MODE_NO_TNUM_SW005 */ -+ if (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_axi_dbg_num_of_beats not supported by this integration.")); -+#endif /* (DPAA_VERSION < 11) */ -+ -+ if (!p_Fm->p_FmStateStruct->fmClkFreq) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set.")); -+ if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dma_watchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("dma_watchdog depends on FM clock. dma_watchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG)); -+ -+#if (DPAA_VERSION >= 11) -+ if ((p_Fm->partVSPBase + p_Fm->partNumOfVSPs) > FM_VSP_MAX_NUM_OF_ENTRIES) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partVSPBase+partNumOfVSPs out of range!!!")); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ if (p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS)); -+ if (!p_Fm->p_FmStateStruct->totalFifoSize || -+ (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("totalFifoSize (currently defined as %d) has to be in the range of 256 to %d", -+ p_Fm->p_FmStateStruct->totalFifoSize, -+ BMI_MAX_FIFO_SIZE)); -+ if (!p_Fm->p_FmStateStruct->totalNumOfTasks || -+ (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS)); -+ -+#ifdef FM_HAS_TOTAL_DMAS -+ if (!p_Fm->p_FmStateStruct->maxNumOfOpenDmas || -+ (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS)); -+#endif /* FM_HAS_TOTAL_DMAS */ -+ -+ if (p_Fm->p_FmDriverParam->disp_limit_tsh > FPM_MAX_DISP_LIMIT) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("disp_limit_tsh can't be greater than %d", FPM_MAX_DISP_LIMIT)); -+ -+ if (!p_Fm->f_Exception) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); -+ if (!p_Fm->f_BusError) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided")); -+ -+#ifdef FM_NO_WATCHDOG -+ if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 2) && -+ (p_Fm->p_FmDriverParam->dma_watchdog)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("watchdog!")); -+#endif /* FM_NO_WATCHDOG */ -+ -+#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 -+ if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) && -+ (p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("HaltOnEccError!")); -+#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */ -+ -+#ifdef FM_NO_TNUM_AGING -+ if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) && -+ (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)) -+ if (p_Fm->p_FmDriverParam->tnum_aging_period) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Tnum aging!")); -+#endif /* FM_NO_TNUM_AGING */ -+ -+ /* check that user did not set revision-dependent exceptions */ -+#ifdef FM_NO_DISPATCH_RAM_ECC -+ if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) && -+ (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)) -+ if (p_Fm->userSetExceptions & FM_EX_BMI_DISPATCH_RAM_ECC) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_BMI_DISPATCH_RAM_ECC!")); -+#endif /* FM_NO_DISPATCH_RAM_ECC */ -+ -+#ifdef FM_QMI_NO_ECC_EXCEPTIONS -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4) -+ if (p_Fm->userSetExceptions & (FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC)) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC/e_FM_EX_QMI_DOUBLE_ECC!")); -+#endif /* FM_QMI_NO_ECC_EXCEPTIONS */ -+ -+#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ if (p_Fm->userSetExceptions & FM_EX_QMI_SINGLE_ECC) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC!")); -+#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */ -+ -+ return E_OK; -+} -+ -+ -+static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg) -+{ -+ ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID); -+ -+ if (p_Fm->intrMng[macEvent].guestId == NCSW_MASTER_ID) -+ p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle); -+ -+ /* If the MAC is running on guest-partition and we have IPC session with it, -+ we inform him about the event through IPC; otherwise, we ignore the event. */ -+ else if (p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId]) -+ { -+ t_Error err; -+ t_FmIpcIsr fmIpcIsr; -+ t_FmIpcMsg msg; -+ -+ memset(&msg, 0, sizeof(msg)); -+ msg.msgId = FM_GUEST_ISR; -+ fmIpcIsr.pendingReg = pendingReg; -+ fmIpcIsr.boolErr = FALSE; -+ memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr)); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(fmIpcIsr), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ } -+ else -+ DBG(TRACE, ("FM Guest mode, without IPC - can't call ISR!")); -+} -+ -+static void BmiErrEvent(t_Fm *p_Fm) -+{ -+ uint32_t event; -+ struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs; -+ -+ -+ event = fman_get_bmi_err_event(bmi_rg); -+ -+ if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC) -+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STORAGE_PROFILE_ECC); -+ if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC) -+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC); -+ if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC) -+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC); -+ if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC) -+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC); -+} -+ -+static void QmiErrEvent(t_Fm *p_Fm) -+{ -+ uint32_t event; -+ struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs; -+ -+ event = fman_get_qmi_err_event(qmi_rg); -+ -+ if (event & QMI_ERR_INTR_EN_DOUBLE_ECC) -+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC); -+ if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF) -+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID); -+} -+ -+static void DmaErrEvent(t_Fm *p_Fm) -+{ -+ uint32_t status, com_id; -+ uint8_t tnum; -+ uint8_t hardwarePortId; -+ uint8_t relativePortId; -+ uint16_t liodn; -+ struct fman_dma_regs *dma_rg = p_Fm->p_FmDmaRegs; -+ -+ status = fman_get_dma_err_event(dma_rg); -+ -+ if (status & DMA_STATUS_BUS_ERR) -+ { -+ com_id = fman_get_dma_com_id(dma_rg); -+ hardwarePortId = (uint8_t)(((com_id & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT)); -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId); -+ tnum = (uint8_t)((com_id & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT); -+ liodn = (uint16_t)(com_id & DMA_TRANSFER_LIODN_MASK); -+ ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY); -+ p_Fm->f_BusError(p_Fm->h_App, -+ p_Fm->p_FmStateStruct->portsTypes[hardwarePortId], -+ relativePortId, -+ fman_get_dma_addr(dma_rg), -+ tnum, -+ liodn); -+ } -+ if (status & DMA_STATUS_FM_SPDAT_ECC) -+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SINGLE_PORT_ECC); -+ if (status & DMA_STATUS_READ_ECC) -+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC); -+ if (status & DMA_STATUS_SYSTEM_WRITE_ECC) -+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC); -+ if (status & DMA_STATUS_FM_WRITE_ECC) -+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC); -+ } -+ -+static void FpmErrEvent(t_Fm *p_Fm) -+{ -+ uint32_t event; -+ struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ event = fman_get_fpm_err_event(fpm_rg); -+ -+ if ((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN)) -+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC); -+ if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN)) -+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS); -+ if ((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN)) -+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC); -+} -+ -+static void MuramErrIntr(t_Fm *p_Fm) -+{ -+ uint32_t event; -+ struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ event = fman_get_muram_err_event(fpm_rg); -+ -+ if (event & FPM_RAM_MURAM_ECC) -+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC); -+} -+ -+static void IramErrIntr(t_Fm *p_Fm) -+{ -+ uint32_t event; -+ struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ event = fman_get_iram_err_event(fpm_rg); -+ -+ if (event & FPM_RAM_IRAM_ECC) -+ p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC); -+} -+ -+static void QmiEvent(t_Fm *p_Fm) -+{ -+ uint32_t event; -+ struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs; -+ -+ event = fman_get_qmi_event(qmi_rg); -+ -+ if (event & QMI_INTR_EN_SINGLE_ECC) -+ p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC); -+} -+ -+static void UnimplementedIsr(t_Handle h_Arg) -+{ -+ UNUSED(h_Arg); -+ -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented ISR!")); -+} -+ -+static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event) -+{ -+ UNUSED(h_Arg); UNUSED(event); -+ -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl ISR!")); -+} -+ -+static void EnableTimeStamp(t_Fm *p_Fm) -+{ -+ struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ ASSERT_COND(p_Fm->p_FmStateStruct); -+ ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit); -+ -+ fman_enable_time_stamp(fpm_rg, p_Fm->p_FmStateStruct->count1MicroBit, p_Fm->p_FmStateStruct->fmClkFreq); -+ -+ p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE; -+} -+ -+static t_Error ClearIRam(t_Fm *p_Fm) -+{ -+ t_FMIramRegs *p_Iram; -+ int i; -+ int iram_size; -+ -+ ASSERT_COND(p_Fm); -+ p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); -+ iram_size = FM_IRAM_SIZE(p_Fm->p_FmStateStruct->revInfo.majorRev,p_Fm->p_FmStateStruct->revInfo.minorRev); -+ -+ /* Enable the auto-increment */ -+ WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE); -+ while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ; -+ -+ for (i=0; i < (iram_size/4); i++) -+ WRITE_UINT32(p_Iram->idata, 0xffffffff); -+ -+ WRITE_UINT32(p_Iram->iadd, iram_size - 4); -+ CORE_MemoryBarrier(); -+ while (GET_UINT32(p_Iram->idata) != 0xffffffff) ; -+ -+ return E_OK; -+} -+ -+static t_Error LoadFmanCtrlCode(t_Fm *p_Fm) -+{ -+ t_FMIramRegs *p_Iram; -+ int i; -+ uint32_t tmp; -+ uint8_t compTo16; -+ -+ ASSERT_COND(p_Fm); -+ p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); -+ -+ /* Enable the auto-increment */ -+ WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE); -+ while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ; -+ -+ for (i=0; i < (p_Fm->firmware.size / 4); i++) -+ WRITE_UINT32(p_Iram->idata, p_Fm->firmware.p_Code[i]); -+ -+ compTo16 = (uint8_t)(p_Fm->firmware.size % 16); -+ if (compTo16) -+ for (i=0; i < ((16-compTo16) / 4); i++) -+ WRITE_UINT32(p_Iram->idata, 0xffffffff); -+ -+ WRITE_UINT32(p_Iram->iadd,p_Fm->firmware.size-4); -+ while (GET_UINT32(p_Iram->iadd) != (p_Fm->firmware.size-4)) ; -+ -+ /* verify that writing has completed */ -+ while (GET_UINT32(p_Iram->idata) != p_Fm->firmware.p_Code[(p_Fm->firmware.size / 4)-1]) ; -+ -+ if (p_Fm->fwVerify) -+ { -+ WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE); -+ while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ; -+ for (i=0; i < (p_Fm->firmware.size / 4); i++) -+ { -+ tmp = GET_UINT32(p_Iram->idata); -+ if (tmp != p_Fm->firmware.p_Code[i]) -+ RETURN_ERROR(MAJOR, E_WRITE_FAILED, -+ ("UCode write error : write 0x%x, read 0x%x", -+ p_Fm->firmware.p_Code[i],tmp)); -+ } -+ WRITE_UINT32(p_Iram->iadd, 0x0); -+ } -+ -+ /* Enable patch from IRAM */ -+ WRITE_UINT32(p_Iram->iready, IRAM_READY); -+ XX_UDelay(1000); -+ -+ DBG(INFO, ("FMan-Controller code (ver %d.%d.%d) loaded to IRAM.", -+ ((uint16_t *)p_Fm->firmware.p_Code)[2], -+ ((uint8_t *)p_Fm->firmware.p_Code)[6], -+ ((uint8_t *)p_Fm->firmware.p_Code)[7])); -+ -+ return E_OK; -+} -+ -+#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 -+static t_Error FwNotResetErratumBugzilla6173WA(t_Fm *p_Fm) -+{ -+ t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); -+ uint32_t tmpReg; -+ uint32_t savedSpliodn[63]; -+ -+ /* write to IRAM first location the debug instruction */ -+ WRITE_UINT32(p_Iram->iadd, 0); -+ while (GET_UINT32(p_Iram->iadd) != 0) ; -+ WRITE_UINT32(p_Iram->idata, FM_FW_DEBUG_INSTRUCTION); -+ -+ WRITE_UINT32(p_Iram->iadd, 0); -+ while (GET_UINT32(p_Iram->iadd) != 0) ; -+ while (GET_UINT32(p_Iram->idata) != FM_FW_DEBUG_INSTRUCTION) ; -+ -+ /* Enable patch from IRAM */ -+ WRITE_UINT32(p_Iram->iready, IRAM_READY); -+ CORE_MemoryBarrier(); -+ XX_UDelay(100); -+ IO2MemCpy32((uint8_t *)savedSpliodn, -+ (uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn, -+ 63*sizeof(uint32_t)); -+ -+ /* reset FMAN */ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET); -+ CORE_MemoryBarrier(); -+ XX_UDelay(100); -+ -+ /* verify breakpoint debug status register */ -+ tmpReg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET)); -+ if (!tmpReg) -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid debug status register value is '0'")); -+ -+ /*************************************/ -+ /* Load FMan-Controller code to IRAM */ -+ /*************************************/ -+ ClearIRam(p_Fm); -+ if (p_Fm->firmware.p_Code && -+ (LoadFmanCtrlCode(p_Fm) != E_OK)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ XX_UDelay(100); -+ -+ /* reset FMAN again to start the microcode */ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET); -+ CORE_MemoryBarrier(); -+ XX_UDelay(100); -+ Mem2IOCpy32((uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn, -+ (uint8_t *)savedSpliodn, -+ 63*sizeof(uint32_t)); -+ -+ if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs)) -+ { -+ fman_resume(p_Fm->p_FmFpmRegs); -+ CORE_MemoryBarrier(); -+ XX_UDelay(100); -+ } -+ -+ return E_OK; -+} -+#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ -+ -+static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending) -+{ -+#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \ -+do { \ -+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\ -+} while (0) -+#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \ -+do { \ -+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].h_SrcHandle);\ -+} while (0) -+ -+ /* error interrupts */ -+ if (pending & ERR_INTR_EN_1G_MAC0) -+ FM_G_CALL_1G_MAC_ERR_ISR(0); -+ if (pending & ERR_INTR_EN_1G_MAC1) -+ FM_G_CALL_1G_MAC_ERR_ISR(1); -+ if (pending & ERR_INTR_EN_1G_MAC2) -+ FM_G_CALL_1G_MAC_ERR_ISR(2); -+ if (pending & ERR_INTR_EN_1G_MAC3) -+ FM_G_CALL_1G_MAC_ERR_ISR(3); -+ if (pending & ERR_INTR_EN_1G_MAC4) -+ FM_G_CALL_1G_MAC_ERR_ISR(4); -+ if (pending & ERR_INTR_EN_1G_MAC5) -+ FM_G_CALL_1G_MAC_ERR_ISR(5); -+ if (pending & ERR_INTR_EN_1G_MAC6) -+ FM_G_CALL_1G_MAC_ERR_ISR(6); -+ if (pending & ERR_INTR_EN_1G_MAC7) -+ FM_G_CALL_1G_MAC_ERR_ISR(7); -+ if (pending & ERR_INTR_EN_10G_MAC0) -+ FM_G_CALL_10G_MAC_ERR_ISR(0); -+ if (pending & ERR_INTR_EN_10G_MAC1) -+ FM_G_CALL_10G_MAC_ERR_ISR(1); -+} -+ -+static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending) -+{ -+#define FM_G_CALL_1G_MAC_ISR(_id) \ -+do { \ -+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].h_SrcHandle);\ -+} while (0) -+#define FM_G_CALL_10G_MAC_ISR(_id) \ -+do { \ -+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].h_SrcHandle);\ -+} while (0) -+ -+ if (pending & INTR_EN_1G_MAC0) -+ FM_G_CALL_1G_MAC_ISR(0); -+ if (pending & INTR_EN_1G_MAC1) -+ FM_G_CALL_1G_MAC_ISR(1); -+ if (pending & INTR_EN_1G_MAC2) -+ FM_G_CALL_1G_MAC_ISR(2); -+ if (pending & INTR_EN_1G_MAC3) -+ FM_G_CALL_1G_MAC_ISR(3); -+ if (pending & INTR_EN_1G_MAC4) -+ FM_G_CALL_1G_MAC_ISR(4); -+ if (pending & INTR_EN_1G_MAC5) -+ FM_G_CALL_1G_MAC_ISR(5); -+ if (pending & INTR_EN_1G_MAC6) -+ FM_G_CALL_1G_MAC_ISR(6); -+ if (pending & INTR_EN_1G_MAC7) -+ FM_G_CALL_1G_MAC_ISR(7); -+ if (pending & INTR_EN_10G_MAC0) -+ FM_G_CALL_10G_MAC_ISR(0); -+ if (pending & INTR_EN_10G_MAC1) -+ FM_G_CALL_10G_MAC_ISR(1); -+ if (pending & INTR_EN_TMR) -+ p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle); -+} -+ -+#if (DPAA_VERSION >= 11) -+static t_Error SetVSPWindow(t_Handle h_Fm, -+ uint8_t hardwarePortId, -+ uint8_t baseStorageProfile, -+ uint8_t log2NumOfProfiles) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ -+ ASSERT_COND(h_Fm); -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->p_FmBmiRegs && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcVspSetPortWindow fmIpcVspSetPortWindow; -+ t_FmIpcMsg msg; -+ t_Error err = E_OK; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&fmIpcVspSetPortWindow, 0, sizeof(t_FmIpcVspSetPortWindow)); -+ fmIpcVspSetPortWindow.hardwarePortId = hardwarePortId; -+ fmIpcVspSetPortWindow.baseStorageProfile = baseStorageProfile; -+ fmIpcVspSetPortWindow.log2NumOfProfiles = log2NumOfProfiles; -+ msg.msgId = FM_VSP_SET_PORT_WINDOW; -+ memcpy(msg.msgBody, &fmIpcVspSetPortWindow, sizeof(t_FmIpcVspSetPortWindow)); -+ -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ return E_OK; -+ } -+ else if (!p_Fm->p_FmBmiRegs) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("Either IPC or 'baseAddress' is required!")); -+ -+ fman_set_vsp_window(p_Fm->p_FmBmiRegs, -+ hardwarePortId, -+ baseStorageProfile, -+ log2NumOfProfiles); -+ -+ return E_OK; -+} -+ -+static uint8_t AllocVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ uint8_t profilesFound = 0; -+ int i = 0; -+ uint32_t intFlags; -+ -+ if (!numOfProfiles) -+ return E_OK; -+ -+ if ((numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES) || -+ (base + numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES)) -+ return (uint8_t)ILLEGAL_BASE; -+ -+ if (p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ t_Error err; -+ uint32_t replyLength; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); -+ ipcAllocParams.guestId = p_Fm->guestId; -+ ipcAllocParams.num = p_Fm->partNumOfVSPs; -+ ipcAllocParams.base = p_Fm->partVSPBase; -+ msg.msgId = FM_VSP_ALLOC; -+ memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); -+ replyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if ((err != E_OK) || -+ (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ else -+ memcpy((uint8_t*)&p_Fm->partVSPBase, reply.replyBody, sizeof(uint8_t)); -+ if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE)) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ { -+ DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!")); -+ return (uint8_t)ILLEGAL_BASE; -+ } -+ -+ intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock); -+ for (i = base; i < base + numOfProfiles; i++) -+ if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE) -+ profilesFound++; -+ else -+ break; -+ -+ if (profilesFound == numOfProfiles) -+ for (i = base; ip_FmSp->profiles[i].profilesMng.ownerId = guestId; -+ else -+ { -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ return (uint8_t)ILLEGAL_BASE; -+ } -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ -+ return base; -+} -+ -+static void FreeVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ int i = 0; -+ -+ ASSERT_COND(p_Fm); -+ -+ if (p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ t_Error err; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams)); -+ ipcAllocParams.guestId = p_Fm->guestId; -+ ipcAllocParams.num = p_Fm->partNumOfVSPs; -+ ipcAllocParams.base = p_Fm->partVSPBase; -+ msg.msgId = FM_VSP_FREE; -+ memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams)); -+ replyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return; -+ } -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ { -+ DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!")); -+ return; -+ } -+ -+ ASSERT_COND(p_Fm->p_FmSp); -+ -+ for (i=base; ip_FmSp->profiles[i].profilesMng.ownerId == guestId) -+ p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE; -+ else -+ DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition")); -+ } -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm, -+ uint8_t *p_Msg, -+ uint32_t msgLength, -+ uint8_t *p_Reply, -+ uint32_t *p_ReplyLength) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg; -+ -+ UNUSED(p_Reply); -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE); -+ -+#ifdef DISABLE_SANITY_CHECKS -+ UNUSED(msgLength); -+#endif /* DISABLE_SANITY_CHECKS */ -+ -+ ASSERT_COND(p_Msg); -+ -+ *p_ReplyLength = 0; -+ -+ switch (p_IpcMsg->msgId) -+ { -+ case (FM_GUEST_ISR): -+ { -+ t_FmIpcIsr ipcIsr; -+ -+ memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr)); -+ if (ipcIsr.boolErr) -+ GuestErrorIsr(p_Fm, ipcIsr.pendingReg); -+ else -+ GuestEventIsr(p_Fm, ipcIsr.pendingReg); -+ break; -+ } -+ default: -+ *p_ReplyLength = 0; -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!")); -+ } -+ return E_OK; -+} -+ -+static t_Error FmHandleIpcMsgCB(t_Handle h_Fm, -+ uint8_t *p_Msg, -+ uint32_t msgLength, -+ uint8_t *p_Reply, -+ uint32_t *p_ReplyLength) -+{ -+ t_Error err; -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg; -+ t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE); -+ -+#ifdef DISABLE_SANITY_CHECKS -+ UNUSED(msgLength); -+#endif /* DISABLE_SANITY_CHECKS */ -+ -+ ASSERT_COND(p_IpcMsg); -+ -+ memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE)); -+ *p_ReplyLength = 0; -+ -+ switch (p_IpcMsg->msgId) -+ { -+ case (FM_GET_SET_PORT_PARAMS): -+ { -+ t_FmIpcPortInInitParams ipcInitParams; -+ t_FmInterModulePortInitParams initParams; -+ t_FmIpcPortOutInitParams ipcOutInitParams; -+ -+ memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams)); -+ initParams.hardwarePortId = ipcInitParams.hardwarePortId; -+ initParams.portType = (e_FmPortType)ipcInitParams.enumPortType; -+ initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode); -+ initParams.liodnOffset = ipcInitParams.liodnOffset; -+ initParams.numOfTasks = ipcInitParams.numOfTasks; -+ initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks; -+ initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas; -+ initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas; -+ initParams.sizeOfFifo = ipcInitParams.sizeOfFifo; -+ initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo; -+ initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth; -+ initParams.maxFrameLength = ipcInitParams.maxFrameLength; -+ initParams.liodnBase = ipcInitParams.liodnBase; -+ -+ p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams); -+ -+ ipcOutInitParams.ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high; -+ ipcOutInitParams.ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low; -+ ipcOutInitParams.sizeOfFifo = initParams.sizeOfFifo; -+ ipcOutInitParams.extraSizeOfFifo = initParams.extraSizeOfFifo; -+ ipcOutInitParams.numOfTasks = initParams.numOfTasks; -+ ipcOutInitParams.numOfExtraTasks = initParams.numOfExtraTasks; -+ ipcOutInitParams.numOfOpenDmas = initParams.numOfOpenDmas; -+ ipcOutInitParams.numOfExtraOpenDmas = initParams.numOfExtraOpenDmas; -+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcOutInitParams, sizeof(ipcOutInitParams)); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams); -+ break; -+ } -+ case (FM_SET_SIZE_OF_FIFO): -+ { -+ t_FmIpcPortRsrcParams ipcPortRsrcParams; -+ -+ memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams)); -+ p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm, -+ ipcPortRsrcParams.hardwarePortId, -+ &ipcPortRsrcParams.val, -+ &ipcPortRsrcParams.extra, -+ (bool)ipcPortRsrcParams.boolInitialConfig); -+ *p_ReplyLength = sizeof(uint32_t); -+ break; -+ } -+ case (FM_SET_NUM_OF_TASKS): -+ { -+ t_FmIpcPortRsrcParams ipcPortRsrcParams; -+ -+ memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams)); -+ p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId, -+ (uint8_t*)&ipcPortRsrcParams.val, -+ (uint8_t*)&ipcPortRsrcParams.extra, -+ (bool)ipcPortRsrcParams.boolInitialConfig); -+ *p_ReplyLength = sizeof(uint32_t); -+ break; -+ } -+ case (FM_SET_NUM_OF_OPEN_DMAS): -+ { -+ t_FmIpcPortRsrcParams ipcPortRsrcParams; -+ -+ memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams)); -+ p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId, -+ (uint8_t*)&ipcPortRsrcParams.val, -+ (uint8_t*)&ipcPortRsrcParams.extra, -+ (bool)ipcPortRsrcParams.boolInitialConfig); -+ *p_ReplyLength = sizeof(uint32_t); -+ break; -+ } -+ case (FM_RESUME_STALLED_PORT): -+ *p_ReplyLength = sizeof(uint32_t); -+ p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]); -+ break; -+ case (FM_MASTER_IS_ALIVE): -+ { -+ uint8_t guestId = p_IpcMsg->msgBody[0]; -+ /* build the FM master partition IPC address */ -+ memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE); -+ if (Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); -+ p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName); -+ if (p_Fm->h_IpcSessions[guestId] == NULL) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId)); -+ *(uint8_t*)(p_IpcReply->replyBody) = 1; -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ break; -+ } -+ case (FM_IS_PORT_STALLED): -+ { -+ bool tmp; -+ -+ p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp); -+ *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp; -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ break; -+ } -+ case (FM_RESET_MAC): -+ { -+ t_FmIpcMacParams ipcMacParams; -+ -+ memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams)); -+ p_IpcReply->error = (uint32_t)FmResetMac(p_Fm, -+ (e_FmMacType)(ipcMacParams.enumType), -+ ipcMacParams.id); -+ *p_ReplyLength = sizeof(uint32_t); -+ break; -+ } -+ case (FM_SET_MAC_MAX_FRAME): -+ { -+ t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams; -+ -+ memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams)); -+ err = FmSetMacMaxFrame(p_Fm, -+ (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType), -+ ipcMacMaxFrameParams.macParams.id, -+ ipcMacMaxFrameParams.maxFrameLength); -+ if (err != E_OK) -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ break; -+ } -+#if (DPAA_VERSION >= 11) -+ case (FM_VSP_ALLOC) : -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ uint8_t vspBase; -+ memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); -+ vspBase = AllocVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId); -+ memcpy(p_IpcReply->replyBody, (uint8_t*)&vspBase, sizeof(uint8_t)); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ break; -+ } -+ case (FM_VSP_FREE) : -+ { -+ t_FmIpcResourceAllocParams ipcAllocParams; -+ memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams)); -+ FreeVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId); -+ break; -+ } -+ case (FM_VSP_SET_PORT_WINDOW) : -+ { -+ t_FmIpcVspSetPortWindow ipcVspSetPortWindow; -+ memcpy(&ipcVspSetPortWindow, p_IpcMsg->msgBody, sizeof(t_FmIpcVspSetPortWindow)); -+ err = SetVSPWindow(h_Fm, -+ ipcVspSetPortWindow.hardwarePortId, -+ ipcVspSetPortWindow.baseStorageProfile, -+ ipcVspSetPortWindow.log2NumOfProfiles); -+ return err; -+ } -+ case (FM_SET_CONG_GRP_PFC_PRIO) : -+ { -+ t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority; -+ memcpy(&fmIpcSetCongestionGroupPfcPriority, p_IpcMsg->msgBody, sizeof(t_FmIpcSetCongestionGroupPfcPriority)); -+ err = FmSetCongestionGroupPFCpriority(h_Fm, -+ fmIpcSetCongestionGroupPfcPriority.congestionGroupId, -+ fmIpcSetCongestionGroupPfcPriority.priorityBitMap); -+ return err; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ case (FM_FREE_PORT): -+ { -+ t_FmInterModulePortFreeParams portParams; -+ t_FmIpcPortFreeParams ipcPortParams; -+ -+ memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams)); -+ portParams.hardwarePortId = ipcPortParams.hardwarePortId; -+ portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType); -+ portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth; -+ FmFreePortParams(h_Fm, &portParams); -+ break; -+ } -+ case (FM_REGISTER_INTR): -+ { -+ t_FmIpcRegisterIntr ipcRegIntr; -+ -+ memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr)); -+ p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId; -+ break; -+ } -+ case (FM_GET_PARAMS): -+ { -+ t_FmIpcParams ipcParams; -+ -+ /* Get clock frequency */ -+ ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq; -+ ipcParams.fmMacClkFreq = p_Fm->p_FmStateStruct->fmMacClkFreq; -+ -+ fman_get_revision(p_Fm->p_FmFpmRegs,&ipcParams.majorRev,&ipcParams.minorRev); -+ -+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcParams, sizeof(t_FmIpcParams)); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams); -+ break; -+ } -+ case (FM_GET_FMAN_CTRL_CODE_REV): -+ { -+ t_FmCtrlCodeRevisionInfo fmanCtrlRevInfo; -+ t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo; -+ -+ p_IpcReply->error = (uint32_t)FM_GetFmanCtrlCodeRevision(h_Fm, &fmanCtrlRevInfo); -+ ipcRevInfo.packageRev = fmanCtrlRevInfo.packageRev; -+ ipcRevInfo.majorRev = fmanCtrlRevInfo.majorRev; -+ ipcRevInfo.minorRev = fmanCtrlRevInfo.minorRev; -+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcFmanCtrlCodeRevisionInfo)); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcFmanCtrlCodeRevisionInfo); -+ break; -+ } -+ -+ case (FM_DMA_STAT): -+ { -+ t_FmDmaStatus dmaStatus; -+ t_FmIpcDmaStatus ipcDmaStatus; -+ -+ FM_GetDmaStatus(h_Fm, &dmaStatus); -+ ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty; -+ ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError; -+ ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError; -+ ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError; -+ ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError; -+ ipcDmaStatus.boolSinglePortEccError = (uint8_t)dmaStatus.singlePortEccError; -+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus)); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus); -+ break; -+ } -+ case (FM_ALLOC_FMAN_CTRL_EVENT_REG): -+ p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ break; -+ case (FM_FREE_FMAN_CTRL_EVENT_REG): -+ FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]); -+ break; -+ case (FM_GET_TIMESTAMP_SCALE): -+ { -+ uint32_t timeStamp = FmGetTimeStampScale(h_Fm); -+ -+ memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t)); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); -+ break; -+ } -+ case (FM_GET_COUNTER): -+ { -+ e_FmCounters inCounter; -+ uint32_t outCounter; -+ -+ memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t)); -+ outCounter = FM_GetCounter(h_Fm, inCounter); -+ memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t)); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); -+ break; -+ } -+ case (FM_SET_FMAN_CTRL_EVENTS_ENABLE): -+ { -+ t_FmIpcFmanEvents ipcFmanEvents; -+ -+ memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents)); -+ FmSetFmanCtrlIntr(h_Fm, -+ ipcFmanEvents.eventRegId, -+ ipcFmanEvents.enableEvents); -+ break; -+ } -+ case (FM_GET_FMAN_CTRL_EVENTS_ENABLE): -+ { -+ uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]); -+ -+ memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t)); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t); -+ break; -+ } -+ case (FM_GET_PHYS_MURAM_BASE): -+ { -+ t_FmPhysAddr physAddr; -+ t_FmIpcPhysAddr ipcPhysAddr; -+ -+ FmGetPhysicalMuramBase(h_Fm, &physAddr); -+ ipcPhysAddr.high = physAddr.high; -+ ipcPhysAddr.low = physAddr.low; -+ memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr)); -+ *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr); -+ break; -+ } -+ case (FM_ENABLE_RAM_ECC): -+ { -+ if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) || -+ ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) || -+ ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK)) -+#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) -+ UNUSED(err); -+#else -+ REPORT_ERROR(MINOR, err, NO_MSG); -+#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */ -+ break; -+ } -+ case (FM_DISABLE_RAM_ECC): -+ { -+ -+ if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) || -+ ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) || -+ ((err = FM_DisableRamsEcc(h_Fm)) != E_OK)) -+#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) -+ UNUSED(err); -+#else -+ REPORT_ERROR(MINOR, err, NO_MSG); -+#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */ -+ break; -+ } -+ case (FM_SET_NUM_OF_FMAN_CTRL): -+ { -+ t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls; -+ -+ memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls)); -+ err = FmSetNumOfRiscsPerPort(h_Fm, -+ ipcPortNumOfFmanCtrls.hardwarePortId, -+ ipcPortNumOfFmanCtrls.numOfFmanCtrls, -+ ipcPortNumOfFmanCtrls.orFmanCtrl); -+ if (err != E_OK) -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ break; -+ } -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+ case (FM_10G_TX_ECC_WA): -+ p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]); -+ *p_ReplyLength = sizeof(uint32_t); -+ break; -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ default: -+ *p_ReplyLength = 0; -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!")); -+ } -+ return E_OK; -+} -+ -+ -+/****************************************/ -+/* Inter-Module functions */ -+/****************************************/ -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ t_Error err = E_OK; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ uint8_t rxHardwarePortId, txHardwarePortId; -+ struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ { -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_10G_TX_ECC_WA; -+ msg.msgBody[0] = macId; -+ replyLength = sizeof(uint32_t); -+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId)+sizeof(macId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ if (replyLength != sizeof(uint32_t)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ return (t_Error)(reply.error); -+ } -+ -+ SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED); -+ SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE); -+ -+ rxHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_RX_10G, -+ macId, -+ p_Fm->p_FmStateStruct->revInfo.majorRev, -+ p_Fm->p_FmStateStruct->revInfo.minorRev); -+ txHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_TX_10G, -+ macId, -+ p_Fm->p_FmStateStruct->revInfo.majorRev, -+ p_Fm->p_FmStateStruct->revInfo.minorRev); -+ if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) || -+ (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("MAC should be initialized prior to Rx and Tx ports!")); -+ -+ return fman_set_erratum_10gmac_a004_wa(fpm_rg); -+} -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ -+uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0); -+ -+ return p_Fm->tnumAgingPeriod; -+} -+ -+t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, -+ uint8_t portNum, -+ bool preFetchConfigured) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ -+ p_Fm->portsPreFetchConfigured[portNum] = TRUE; -+ p_Fm->portsPreFetchValue[portNum] = preFetchConfigured; -+ -+ return E_OK; -+} -+ -+t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, -+ uint8_t portNum, -+ bool *p_PortConfigured, -+ bool *p_PreFetchConfigured) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ -+ /* If the prefetch wasn't configured yet (not enable or disabled) -+ we return the value TRUE as it was already configured */ -+ if (!p_Fm->portsPreFetchConfigured[portNum]) -+ { -+ *p_PortConfigured = FALSE; -+ *p_PreFetchConfigured = FALSE; -+ } -+ else -+ { -+ *p_PortConfigured = TRUE; -+ *p_PreFetchConfigured = (p_Fm->portsPreFetchConfigured[portNum]); -+ } -+ -+ return E_OK; -+} -+ -+t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm, -+ uint32_t congestionGroupId, -+ uint8_t priorityBitMap) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ uint32_t regNum; -+ -+ ASSERT_COND(h_Fm); -+ -+ if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("Congestion group ID bigger than %d", -+ FM_PORT_NUM_OF_CONGESTION_GRPS)); -+ -+ if (p_Fm->guestId == NCSW_MASTER_ID) -+ { -+ ASSERT_COND(p_Fm->baseAddr); -+ regNum = (FM_PORT_NUM_OF_CONGESTION_GRPS - 1 - congestionGroupId) / 4; -+ fman_set_congestion_group_pfc_priority((uint32_t *)((p_Fm->baseAddr+FM_MM_CGP)), -+ congestionGroupId, -+ priorityBitMap, -+ regNum); -+ } -+ else if (p_Fm->h_IpcSessions[0]) -+ { -+ t_Error err; -+ t_FmIpcMsg msg; -+ t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&fmIpcSetCongestionGroupPfcPriority, 0, sizeof(t_FmIpcSetCongestionGroupPfcPriority)); -+ fmIpcSetCongestionGroupPfcPriority.congestionGroupId = congestionGroupId; -+ fmIpcSetCongestionGroupPfcPriority.priorityBitMap = priorityBitMap; -+ -+ msg.msgId = FM_SET_CONG_GRP_PFC_PRIO; -+ memcpy(msg.msgBody, &fmIpcSetCongestionGroupPfcPriority, sizeof(t_FmIpcSetCongestionGroupPfcPriority)); -+ -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("guest without IPC!")); -+ -+ return E_OK; -+} -+ -+uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); -+ -+ if (!p_Fm->baseAddr) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, -+ ("No base-addr; probably Guest with IPC!")); -+ return 0; -+ } -+ -+ return (p_Fm->baseAddr + FM_MM_PRS); -+} -+ -+uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); -+ -+ if (!p_Fm->baseAddr) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, -+ ("No base-addr; probably Guest with IPC!")); -+ return 0; -+ } -+ -+ return (p_Fm->baseAddr + FM_MM_KG); -+} -+ -+uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); -+ -+ if (!p_Fm->baseAddr) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, -+ ("No base-addr; probably Guest with IPC!")); -+ return 0; -+ } -+ -+ return (p_Fm->baseAddr + FM_MM_PLCR); -+} -+ -+#if (DPAA_VERSION >= 11) -+uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); -+ -+ return p_Fm->vspBaseAddr; -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+t_Handle FmGetMuramHandle(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL); -+ -+ return (p_Fm->h_FmMuram); -+} -+ -+void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ if (p_Fm->fmMuramPhysBaseAddr) -+ { -+ /* General FM driver initialization */ -+ p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr; -+ p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32); -+ return; -+ } -+ -+ ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID); -+ -+ if (p_Fm->h_IpcSessions[0]) -+ { -+ t_Error err; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ t_FmIpcPhysAddr ipcPhysAddr; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_GET_PHYS_MURAM_BASE; -+ replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ { -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ return; -+ } -+ if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr))) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch")); -+ return; -+ } -+ memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr)); -+ p_FmPhysAddr->high = ipcPhysAddr.high; -+ p_FmPhysAddr->low = ipcPhysAddr.low; -+ } -+ else -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without neither IPC nor mapped register!")); -+} -+ -+#if (DPAA_VERSION >= 11) -+t_Error FmVSPAllocForPort (t_Handle h_Fm, -+ e_FmPortType portType, -+ uint8_t portId, -+ uint8_t numOfVSPs) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ t_Error err = E_OK; -+ uint32_t profilesFound, intFlags; -+ uint8_t first, i; -+ uint8_t log2Num; -+ uint8_t swPortIndex=0, hardwarePortId; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ -+ if (!numOfVSPs) -+ return E_OK; -+ -+ if (numOfVSPs > FM_VSP_MAX_NUM_OF_ENTRIES) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles can not be bigger than %d.",FM_VSP_MAX_NUM_OF_ENTRIES)); -+ -+ if (!POWER_OF_2(numOfVSPs)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2.")); -+ -+ LOG2((uint64_t)numOfVSPs, log2Num); -+ -+ if ((log2Num == 0) || (p_Fm->partVSPBase == 0)) -+ first = 0; -+ else -+ first = 1< (p_Fm->partVSPBase + p_Fm->partNumOfVSPs)) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window")); -+ -+ if (first < p_Fm->partVSPBase) -+ while (first < p_Fm->partVSPBase) -+ first = first + numOfVSPs; -+ -+ if ((first + numOfVSPs) > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs)) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window")); -+ -+ intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock); -+ profilesFound = 0; -+ for (i=first; i < p_Fm->partVSPBase + p_Fm->partNumOfVSPs; ) -+ { -+ if (!p_Fm->p_FmSp->profiles[i].profilesMng.allocated) -+ { -+ profilesFound++; -+ i++; -+ if (profilesFound == numOfVSPs) -+ break; -+ } -+ else -+ { -+ profilesFound = 0; -+ /* advance i to the next aligned address */ -+ first = i = (uint8_t)(first + numOfVSPs); -+ } -+ } -+ if (profilesFound == numOfVSPs) -+ for (i = first; ip_FmSp->profiles[i].profilesMng.allocated = TRUE; -+ else -+ { -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ RETURN_ERROR(MINOR, E_FULL, ("No profiles.")); -+ } -+ -+ hardwarePortId = SwPortIdToHwPortId(portType, -+ portId, -+ p_Fm->p_FmStateStruct->revInfo.majorRev, -+ p_Fm->p_FmStateStruct->revInfo.minorRev); -+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); -+ -+ p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = numOfVSPs; -+ p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = first; -+ -+ if ((err = SetVSPWindow(h_Fm,hardwarePortId, first,log2Num)) != E_OK) -+ for (i = first; i < first + numOfVSPs; i++) -+ p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE; -+ -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ -+ return err; -+} -+ -+t_Error FmVSPFreeForPort(t_Handle h_Fm, -+ e_FmPortType portType, -+ uint8_t portId) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ uint8_t swPortIndex=0, hardwarePortId, first, numOfVSPs, i; -+ uint32_t intFlags; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ -+ hardwarePortId = SwPortIdToHwPortId(portType, -+ portId, -+ p_Fm->p_FmStateStruct->revInfo.majorRev, -+ p_Fm->p_FmStateStruct->revInfo.minorRev); -+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); -+ -+ numOfVSPs = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles; -+ first = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase; -+ -+ intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock); -+ for (i = first; i < first + numOfVSPs; i++) -+ p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE; -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ -+ p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = 0; -+ p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = 0; -+ -+ return E_OK; -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint8_t i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_Error err; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG; -+ replyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ -+ *p_EventId = *(uint8_t*)(reply.replyBody); -+ -+ return (t_Error)(reply.error); -+ } -+ else if (p_Fm->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without IPC!")); -+ -+ for (i=0;iusedEventRegs[i]) -+ { -+ p_Fm->usedEventRegs[i] = TRUE; -+ *p_EventId = i; -+ break; -+ } -+ -+ if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS) -+ RETURN_ERROR(MAJOR, E_BUSY, ("No resource - FMan controller event register.")); -+ -+ return E_OK; -+} -+ -+void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_Error err; -+ t_FmIpcMsg msg; -+ -+ memset(&msg, 0, sizeof(msg)); -+ msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG; -+ msg.msgBody[0] = eventId; -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId)+sizeof(eventId), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ return; -+ } -+ else if (p_Fm->guestId != NCSW_MASTER_ID) -+ { -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without IPC!")); -+ return; -+ } -+ -+ ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE; -+} -+ -+void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->p_FmFpmRegs && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcFmanEvents fmanCtrl; -+ t_Error err; -+ t_FmIpcMsg msg; -+ -+ fmanCtrl.eventRegId = eventRegId; -+ fmanCtrl.enableEvents = enableEvents; -+ memset(&msg, 0, sizeof(msg)); -+ msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE; -+ memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl)); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId)+sizeof(fmanCtrl), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ return; -+ } -+ else if (!p_Fm->p_FmFpmRegs) -+ { -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("Either IPC or 'baseAddress' is required!")); -+ return; -+ } -+ -+ ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS); -+ fman_set_ctrl_intr(fpm_rg, eventRegId, enableEvents); -+} -+ -+uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->p_FmFpmRegs && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_Error err; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength, ctrlIntr; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE; -+ msg.msgBody[0] = eventRegId; -+ replyLength = sizeof(uint32_t) + sizeof(uint32_t); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId)+sizeof(eventRegId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ { -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ return 0; -+ } -+ if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) -+ { -+ REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ return 0; -+ } -+ memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t)); -+ return ctrlIntr; -+ } -+ else if (!p_Fm->p_FmFpmRegs) -+ { -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("Either IPC or 'baseAddress' is required!")); -+ return 0; -+ } -+ -+ return fman_get_ctrl_intr(fpm_rg, eventRegId); -+} -+ -+void FmRegisterIntr(t_Handle h_Fm, -+ e_FmEventModules module, -+ uint8_t modId, -+ e_FmIntrType intrType, -+ void (*f_Isr) (t_Handle h_Arg), -+ t_Handle h_Arg) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ int event = 0; -+ -+ ASSERT_COND(h_Fm); -+ -+ GET_FM_MODULE_EVENT(module, modId, intrType, event); -+ ASSERT_COND(event < e_FM_EV_DUMMY_LAST); -+ -+ /* register in local FM structure */ -+ p_Fm->intrMng[event].f_Isr = f_Isr; -+ p_Fm->intrMng[event].h_SrcHandle = h_Arg; -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcRegisterIntr fmIpcRegisterIntr; -+ t_Error err; -+ t_FmIpcMsg msg; -+ -+ /* register in Master FM structure */ -+ fmIpcRegisterIntr.event = (uint32_t)event; -+ fmIpcRegisterIntr.guestId = p_Fm->guestId; -+ memset(&msg, 0, sizeof(msg)); -+ msg.msgId = FM_REGISTER_INTR; -+ memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr)); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ } -+ else if (p_Fm->guestId != NCSW_MASTER_ID) -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without IPC!")); -+} -+ -+void FmUnregisterIntr(t_Handle h_Fm, -+ e_FmEventModules module, -+ uint8_t modId, -+ e_FmIntrType intrType) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ int event = 0; -+ -+ ASSERT_COND(h_Fm); -+ -+ GET_FM_MODULE_EVENT(module, modId,intrType, event); -+ ASSERT_COND(event < e_FM_EV_DUMMY_LAST); -+ -+ p_Fm->intrMng[event].f_Isr = UnimplementedIsr; -+ p_Fm->intrMng[event].h_SrcHandle = NULL; -+} -+ -+void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ ASSERT_COND(eventRegIdguestId != NCSW_MASTER_ID) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode")); -+ return; -+ } -+ -+ p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr; -+ p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg; -+} -+ -+void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ ASSERT_COND(eventRegIdguestId != NCSW_MASTER_ID) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode")); -+ return; -+ } -+ -+ p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr; -+ p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL; -+} -+ -+void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ if (p_Fm->h_Pcd) -+ REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set")); -+ -+ p_Fm->h_Pcd = h_FmPcd; -+} -+ -+void FmUnregisterPcd(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ if (!p_Fm->h_Pcd) -+ REPORT_ERROR(MAJOR, E_NOT_FOUND, ("PCD handle!")); -+ -+ p_Fm->h_Pcd = NULL; -+} -+ -+t_Handle FmGetPcdHandle(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ return p_Fm->h_Pcd; -+} -+ -+uint8_t FmGetId(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff); -+ -+ return p_Fm->p_FmStateStruct->fmId; -+} -+ -+t_Error FmReset(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET); -+ CORE_MemoryBarrier(); -+ XX_UDelay(100); -+ -+ return E_OK; -+} -+ -+t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, -+ uint8_t hardwarePortId, -+ uint8_t numOfFmanCtrls, -+ t_FmFmanCtrl orFmanCtrl) -+{ -+ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ struct fman_fpm_regs *fpm_rg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE); -+ -+ fpm_rg = p_Fm->p_FmFpmRegs; -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->p_FmFpmRegs && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_Error err; -+ t_FmIpcPortNumOfFmanCtrls params; -+ t_FmIpcMsg msg; -+ -+ memset(&msg, 0, sizeof(msg)); -+ params.hardwarePortId = hardwarePortId; -+ params.numOfFmanCtrls = numOfFmanCtrls; -+ params.orFmanCtrl = orFmanCtrl; -+ msg.msgId = FM_SET_NUM_OF_FMAN_CTRL; -+ memcpy(msg.msgBody, ¶ms, sizeof(params)); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) +sizeof(params), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ return E_OK; -+ } -+ else if (!p_Fm->p_FmFpmRegs) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("Either IPC or 'baseAddress' is required!")); -+ -+ fman_set_num_of_riscs_per_port(fpm_rg, hardwarePortId, numOfFmanCtrls, orFmanCtrl); -+ -+ return E_OK; -+} -+ -+t_Error FmGetSetPortParams(t_Handle h_Fm, t_FmInterModulePortInitParams *p_PortParams) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ t_Error err; -+ uint32_t intFlags; -+ uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId; -+ struct fman_rg fman_rg; -+ -+ fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; -+ fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; -+ fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; -+ fman_rg.dma_rg = p_Fm->p_FmDmaRegs; -+ -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ { -+ t_FmIpcPortInInitParams portInParams; -+ t_FmIpcPortOutInitParams portOutParams; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ -+ portInParams.hardwarePortId = p_PortParams->hardwarePortId; -+ portInParams.enumPortType = (uint32_t)p_PortParams->portType; -+ portInParams.boolIndependentMode= (uint8_t)p_PortParams->independentMode; -+ portInParams.liodnOffset = p_PortParams->liodnOffset; -+ portInParams.numOfTasks = p_PortParams->numOfTasks; -+ portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks; -+ portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas; -+ portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas; -+ portInParams.sizeOfFifo = p_PortParams->sizeOfFifo; -+ portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo; -+ portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth; -+ portInParams.maxFrameLength = p_PortParams->maxFrameLength; -+ portInParams.liodnBase = p_PortParams->liodnBase; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_GET_SET_PORT_PARAMS; -+ memcpy(msg.msgBody, &portInParams, sizeof(portInParams)); -+ replyLength = (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams)); -+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) +sizeof(portInParams), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ memcpy((uint8_t*)&portOutParams, reply.replyBody, sizeof(t_FmIpcPortOutInitParams)); -+ -+ p_PortParams->fmMuramPhysBaseAddr.high = portOutParams.ipcPhysAddr.high; -+ p_PortParams->fmMuramPhysBaseAddr.low = portOutParams.ipcPhysAddr.low; -+ p_PortParams->numOfTasks = portOutParams.numOfTasks; -+ p_PortParams->numOfExtraTasks = portOutParams.numOfExtraTasks; -+ p_PortParams->numOfOpenDmas = portOutParams.numOfOpenDmas; -+ p_PortParams->numOfExtraOpenDmas = portOutParams.numOfExtraOpenDmas; -+ p_PortParams->sizeOfFifo = portOutParams.sizeOfFifo; -+ p_PortParams->extraSizeOfFifo = portOutParams.extraSizeOfFifo; -+ -+ return (t_Error)(reply.error); -+ } -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ -+ intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock); -+ if (p_PortParams->independentMode) -+ { -+ /* set port parameters */ -+ p_Fm->independentMode = p_PortParams->independentMode; -+ /* disable dispatch limit */ -+ fman_qmi_disable_dispatch_limit(fman_rg.fpm_rg); -+ } -+ -+ if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) -+ { -+ if (p_Fm->hcPortInitialized) -+ { -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed.")); -+ } -+ else -+ p_Fm->hcPortInitialized = TRUE; -+ } -+ p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType; -+ -+ err = FmSetNumOfTasks(p_Fm, hardwarePortId, &p_PortParams->numOfTasks, &p_PortParams->numOfExtraTasks, TRUE); -+ if (err) -+ { -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4) -+#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ -+ if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) && -+ (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G)) -+ /* for transmit & O/H ports */ -+ { -+ uint8_t enqTh; -+ uint8_t deqTh; -+ -+ /* update qmi ENQ/DEQ threshold */ -+ p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth; -+ enqTh = fman_get_qmi_enq_th(fman_rg.qmi_rg); -+ /* if enqTh is too big, we reduce it to the max value that is still OK */ -+ if (enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums)) -+ { -+ enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1); -+ fman_set_qmi_enq_th(fman_rg.qmi_rg, enqTh); -+ } -+ -+ deqTh = fman_get_qmi_deq_th(fman_rg.qmi_rg); -+ /* if deqTh is too small, we enlarge it to the min value that is still OK. -+ deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */ -+ if ((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1)) -+ { -+ deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1); -+ fman_set_qmi_deq_th(fman_rg.qmi_rg, deqTh); -+ } -+ } -+ -+#ifdef FM_LOW_END_RESTRICTION -+ if ((hardwarePortId==0x1) || (hardwarePortId==0x29)) -+ { -+ if (p_Fm->p_FmStateStruct->lowEndRestriction) -+ { -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1.")); -+ } -+ else -+ p_Fm->p_FmStateStruct->lowEndRestriction = TRUE; -+ } -+#endif /* FM_LOW_END_RESTRICTION */ -+ -+ err = FmSetSizeOfFifo(p_Fm, -+ hardwarePortId, -+ &p_PortParams->sizeOfFifo, -+ &p_PortParams->extraSizeOfFifo, -+ TRUE); -+ if (err) -+ { -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ err = FmSetNumOfOpenDmas(p_Fm, -+ hardwarePortId, -+ &p_PortParams->numOfOpenDmas, -+ &p_PortParams->numOfExtraOpenDmas, -+ TRUE); -+ if (err) -+ { -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ fman_set_liodn_per_port(&fman_rg, -+ hardwarePortId, -+ p_PortParams->liodnBase, -+ p_PortParams->liodnOffset); -+ -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6) -+ fman_set_order_restoration_per_port(fman_rg.fpm_rg, -+ hardwarePortId, -+ p_PortParams->independentMode, -+ !!((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G))); -+ -+ HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId); -+ -+#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS) -+ if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) || -+ (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G)) -+ { -+ ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS); -+ if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId]) -+ p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = p_PortParams->maxFrameLength; -+ else -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU")); -+ } -+ else -+#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */ -+ if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) || -+ (p_PortParams->portType == e_FM_PORT_TYPE_RX)) -+ { -+ ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS); -+ if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId]) -+ p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = p_PortParams->maxFrameLength; -+ else -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU")); -+ } -+ -+ FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr); -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+ -+ return E_OK; -+} -+ -+void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t intFlags; -+ uint8_t hardwarePortId = p_PortParams->hardwarePortId; -+ uint8_t numOfTasks, numOfDmas, macId; -+ uint16_t sizeOfFifo; -+ t_Error err; -+ t_FmIpcPortFreeParams portParams; -+ t_FmIpcMsg msg; -+ struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs; -+ struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs; -+ -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ { -+ portParams.hardwarePortId = p_PortParams->hardwarePortId; -+ portParams.enumPortType = (uint32_t)p_PortParams->portType; -+ portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth; -+ memset(&msg, 0, sizeof(msg)); -+ msg.msgId = FM_FREE_PORT; -+ memcpy(msg.msgBody, &portParams, sizeof(portParams)); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId)+sizeof(portParams), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ return; -+ } -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ -+ intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock); -+ -+ if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND) -+ { -+ ASSERT_COND(p_Fm->hcPortInitialized); -+ p_Fm->hcPortInitialized = FALSE; -+ } -+ -+ p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY; -+ -+ /* free numOfTasks */ -+ numOfTasks = fman_get_num_of_tasks(bmi_rg, hardwarePortId); -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks); -+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks; -+ -+ /* free numOfOpenDmas */ -+ numOfDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId); -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= numOfDmas); -+ p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= numOfDmas; -+ -+#ifdef FM_HAS_TOTAL_DMAS -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6) -+ { -+ /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */ -+ fman_set_num_of_open_dmas(bmi_rg, -+ hardwarePortId, -+ 1, -+ 0, -+ (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize)); -+ } -+#endif /* FM_HAS_TOTAL_DMAS */ -+ -+ /* free sizeOfFifo */ -+ sizeOfFifo = fman_get_size_of_fifo(bmi_rg, hardwarePortId); -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= (sizeOfFifo * BMI_FIFO_UNITS)); -+ p_Fm->p_FmStateStruct->accumulatedFifoSize -= (sizeOfFifo * BMI_FIFO_UNITS); -+ -+#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4) -+#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ -+ if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) && -+ (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G)) -+ /* for transmit & O/H ports */ -+ { -+ uint8_t enqTh; -+ uint8_t deqTh; -+ -+ /* update qmi ENQ/DEQ threshold */ -+ p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth; -+ -+ /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller, -+ so we can enlarge enqTh */ -+ enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1); -+ -+ /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller, -+ so we can reduce deqTh */ -+ deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1); -+ -+ fman_set_qmi_enq_th(qmi_rg, enqTh); -+ fman_set_qmi_deq_th(qmi_rg, deqTh); -+ } -+ -+ HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId); -+ -+#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS) -+ if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) || -+ (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G)) -+ { -+ ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS); -+ p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = 0; -+ } -+ else -+#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */ -+ if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) || -+ (p_PortParams->portType == e_FM_PORT_TYPE_RX)) -+ { -+ ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS); -+ p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = 0; -+ } -+ -+#ifdef FM_LOW_END_RESTRICTION -+ if ((hardwarePortId==0x1) || (hardwarePortId==0x29)) -+ p_Fm->p_FmStateStruct->lowEndRestriction = FALSE; -+#endif /* FM_LOW_END_RESTRICTION */ -+ XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags); -+} -+ -+t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ t_Error err; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->baseAddr && -+ p_Fm->h_IpcSessions[0]) -+ { -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_IS_PORT_STALLED; -+ msg.msgBody[0] = hardwarePortId; -+ replyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId)+sizeof(hardwarePortId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ -+ *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody)); -+ -+ return (t_Error)(reply.error); -+ } -+ else if (!p_Fm->baseAddr) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("Either IPC or 'baseAddress' is required!")); -+ -+ *p_IsStalled = fman_is_port_stalled(fpm_rg, hardwarePortId); -+ -+ return E_OK; -+} -+ -+t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ t_Error err; -+ bool isStalled; -+ struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->baseAddr && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_RESUME_STALLED_PORT; -+ msg.msgBody[0] = hardwarePortId; -+ replyLength = sizeof(uint32_t); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(hardwarePortId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ if (replyLength != sizeof(uint32_t)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ return (t_Error)(reply.error); -+ } -+ else if (!p_Fm->baseAddr) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("Either IPC or 'baseAddress' is required!")); -+ -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not available for this FM revision!")); -+ -+ /* Get port status */ -+ err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled); -+ if (err) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status")); -+ if (!isStalled) -+ return E_OK; -+ -+ fman_resume_stalled_port(fpm_rg, hardwarePortId); -+ -+ return E_OK; -+} -+ -+t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ t_Error err; -+ struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs; -+ -+#if (DPAA_VERSION >= 11) -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("FMan MAC reset!")); -+#endif /*(DPAA_VERSION >= 11)*/ -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->baseAddr && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcMacParams macParams; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ macParams.id = macId; -+ macParams.enumType = (uint32_t)type; -+ msg.msgId = FM_RESET_MAC; -+ memcpy(msg.msgBody, &macParams, sizeof(macParams)); -+ replyLength = sizeof(uint32_t); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId)+sizeof(macParams), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ if (replyLength != sizeof(uint32_t)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ return (t_Error)(reply.error); -+ } -+ else if (!p_Fm->baseAddr) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("Either IPC or 'baseAddress' is required!")); -+ -+ err = (t_Error)fman_reset_mac(fpm_rg, macId, !!(type == e_FM_MAC_10G)); -+ -+ if (err == -EBUSY) -+ return ERROR_CODE(E_TIMEOUT); -+ else if (err) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal MAC ID")); -+ -+ return E_OK; -+} -+ -+t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcMacMaxFrameParams macMaxFrameLengthParams; -+ t_Error err; -+ t_FmIpcMsg msg; -+ -+ memset(&msg, 0, sizeof(msg)); -+ macMaxFrameLengthParams.macParams.id = macId; -+ macMaxFrameLengthParams.macParams.enumType = (uint32_t)type; -+ macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu; -+ msg.msgId = FM_SET_MAC_MAX_FRAME; -+ memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams)); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ return E_OK; -+ } -+ else if (p_Fm->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without IPC!")); -+ -+ /* if port is already initialized, check that MaxFrameLength is smaller -+ * or equal to the port's max */ -+#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)) -+ if (type == e_FM_MAC_10G) -+ { -+ if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId]) -+ || (p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] && -+ (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId]))) -+ p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu; -+ else -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength")); -+ -+ } -+ else -+#else -+ UNUSED(type); -+#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */ -+ if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId]) -+ || (p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] && -+ (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId]))) -+ p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu; -+ else -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength")); -+ -+ return E_OK; -+} -+ -+uint16_t FmGetClockFreq(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ /* for multicore environment: this depends on the -+ * fact that fmClkFreq was properly initialized at "init". */ -+ return p_Fm->p_FmStateStruct->fmClkFreq; -+} -+ -+uint16_t FmGetMacClockFreq(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ return p_Fm->p_FmStateStruct->fmMacClkFreq; -+} -+ -+uint32_t FmGetTimeStampScale(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->baseAddr && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_Error err; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength, timeStamp; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_GET_TIMESTAMP_SCALE; -+ replyLength = sizeof(uint32_t) + sizeof(uint32_t); -+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return 0; -+ } -+ if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ return 0; -+ } -+ -+ memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t)); -+ return timeStamp; -+ } -+ else if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ p_Fm->baseAddr) -+ { -+ if (!(GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1) & FPM_TS_CTL_EN)) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!")); -+ return 0; -+ } -+ } -+ else if (p_Fm->guestId != NCSW_MASTER_ID) -+ DBG(WARNING, ("No IPC - can't validate FM if timestamp enabled.")); -+ -+ return p_Fm->p_FmStateStruct->count1MicroBit; -+} -+ -+t_Error FmEnableRamsEcc(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ -+ p_Fm->p_FmStateStruct->ramsEccOwners++; -+ p_Fm->p_FmStateStruct->internalCall = TRUE; -+ -+ return FM_EnableRamsEcc(p_Fm); -+} -+ -+t_Error FmDisableRamsEcc(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ -+ ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners); -+ p_Fm->p_FmStateStruct->ramsEccOwners--; -+ -+ if (p_Fm->p_FmStateStruct->ramsEccOwners==0) -+ { -+ p_Fm->p_FmStateStruct->internalCall = TRUE; -+ return FM_DisableRamsEcc(p_Fm); -+ } -+ -+ return E_OK; -+} -+ -+uint8_t FmGetGuestId(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ return p_Fm->guestId; -+} -+ -+bool FmIsMaster(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ return (p_Fm->guestId == NCSW_MASTER_ID); -+} -+ -+t_Error FmSetSizeOfFifo(t_Handle h_Fm, -+ uint8_t hardwarePortId, -+ uint32_t *p_SizeOfFifo, -+ uint32_t *p_ExtraSizeOfFifo, -+ bool initialConfig) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ t_FmIpcPortRsrcParams rsrcParams; -+ t_Error err; -+ struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs; -+ uint32_t sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo; -+ uint16_t currentVal = 0, currentExtraVal = 0; -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->baseAddr && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ -+ rsrcParams.hardwarePortId = hardwarePortId; -+ rsrcParams.val = sizeOfFifo; -+ rsrcParams.extra = extraSizeOfFifo; -+ rsrcParams.boolInitialConfig = (uint8_t)initialConfig; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_SET_SIZE_OF_FIFO; -+ memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams)); -+ replyLength = sizeof(uint32_t); -+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(rsrcParams), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ if (replyLength != sizeof(uint32_t)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ return (t_Error)(reply.error); -+ } -+ else if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ p_Fm->baseAddr) -+ { -+ DBG(WARNING, ("No IPC - can't validate FM total-fifo size.")); -+ fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo); -+ } -+ else if (p_Fm->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without neither IPC nor mapped register!")); -+ -+ if (!initialConfig) -+ { -+ /* !initialConfig - runtime change of existing value. -+ * - read the current FIFO and extra FIFO size */ -+ currentExtraVal = fman_get_size_of_extra_fifo(bmi_rg, hardwarePortId); -+ currentVal = fman_get_size_of_fifo(bmi_rg, hardwarePortId); -+ } -+ -+ if (extraSizeOfFifo > currentExtraVal) -+ { -+ if (extraSizeOfFifo && !p_Fm->p_FmStateStruct->extraFifoPoolSize) -+ /* if this is the first time a port requires extraFifoPoolSize, the total extraFifoPoolSize -+ * must be initialized to 1 buffer per port -+ */ -+ p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS; -+ -+ p_Fm->p_FmStateStruct->extraFifoPoolSize = MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo); -+ } -+ -+ /* check that there are enough uncommitted fifo size */ -+ if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - currentVal + sizeOfFifo) > -+ (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)){ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("Port request fifo size + accumulated size > total FIFO size:")); -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, -+ ("port 0x%x requested %d bytes, extra size = %d, accumulated size = %d total size = %d", -+ hardwarePortId, sizeOfFifo, p_Fm->p_FmStateStruct->extraFifoPoolSize, -+ p_Fm->p_FmStateStruct->accumulatedFifoSize, -+ p_Fm->p_FmStateStruct->totalFifoSize)); -+ } -+ else -+ { -+ /* update accumulated */ -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal); -+ p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal; -+ p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo; -+ fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo); -+ } -+ -+ return E_OK; -+} -+ -+t_Error FmSetNumOfTasks(t_Handle h_Fm, -+ uint8_t hardwarePortId, -+ uint8_t *p_NumOfTasks, -+ uint8_t *p_NumOfExtraTasks, -+ bool initialConfig) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ t_Error err; -+ struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs; -+ uint8_t currentVal = 0, currentExtraVal = 0, numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks; -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->baseAddr && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcPortRsrcParams rsrcParams; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ -+ rsrcParams.hardwarePortId = hardwarePortId; -+ rsrcParams.val = numOfTasks; -+ rsrcParams.extra = numOfExtraTasks; -+ rsrcParams.boolInitialConfig = (uint8_t)initialConfig; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_SET_NUM_OF_TASKS; -+ memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams)); -+ replyLength = sizeof(uint32_t); -+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(rsrcParams), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ if (replyLength != sizeof(uint32_t)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ return (t_Error)(reply.error); -+ } -+ else if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ p_Fm->baseAddr) -+ { -+ DBG(WARNING, ("No IPC - can't validate FM total-num-of-tasks.")); -+ fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks); -+ } -+ else if (p_Fm->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without neither IPC nor mapped register!")); -+ -+ if (!initialConfig) -+ { -+ /* !initialConfig - runtime change of existing value. -+ * - read the current number of tasks */ -+ currentVal = fman_get_num_of_tasks(bmi_rg, hardwarePortId); -+ currentExtraVal = fman_get_num_extra_tasks(bmi_rg, hardwarePortId); -+ } -+ -+ if (numOfExtraTasks > currentExtraVal) -+ p_Fm->p_FmStateStruct->extraTasksPoolSize = -+ (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks); -+ -+ /* check that there are enough uncommitted tasks */ -+ if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - currentVal + numOfTasks) > -+ (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize)) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, -+ ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.", -+ p_Fm->p_FmStateStruct->fmId)); -+ else -+ { -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= currentVal); -+ /* update accumulated */ -+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal; -+ p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks; -+ fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks); -+ } -+ -+ return E_OK; -+} -+ -+t_Error FmSetNumOfOpenDmas(t_Handle h_Fm, -+ uint8_t hardwarePortId, -+ uint8_t *p_NumOfOpenDmas, -+ uint8_t *p_NumOfExtraOpenDmas, -+ bool initialConfig) -+ -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ t_Error err; -+ struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs; -+ uint8_t numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas; -+ uint8_t totalNumDmas = 0, currentVal = 0, currentExtraVal = 0; -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->baseAddr && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcPortRsrcParams rsrcParams; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ -+ rsrcParams.hardwarePortId = hardwarePortId; -+ rsrcParams.val = numOfOpenDmas; -+ rsrcParams.extra = numOfExtraOpenDmas; -+ rsrcParams.boolInitialConfig = (uint8_t)initialConfig; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_SET_NUM_OF_OPEN_DMAS; -+ memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams)); -+ replyLength = sizeof(uint32_t); -+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) + sizeof(rsrcParams), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ if (replyLength != sizeof(uint32_t)) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ return (t_Error)(reply.error); -+ } -+#ifdef FM_HAS_TOTAL_DMAS -+ else if (p_Fm->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("running in guest-mode without IPC!")); -+#else -+ else if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ p_Fm->baseAddr && -+ (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)) -+ { -+ /*DBG(WARNING, ("No IPC - can't validate FM total-num-of-dmas."));*/ -+ -+ if (!numOfOpenDmas) -+ { -+ /* first config without explic it value: Do Nothing - reset value shouldn't be -+ changed, read register for port save */ -+ *p_NumOfOpenDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId); -+ *p_NumOfExtraOpenDmas = fman_get_num_extra_dmas(bmi_rg, hardwarePortId); -+ } -+ else -+ /* whether it is the first time with explicit value, or runtime "set" - write register */ -+ fman_set_num_of_open_dmas(bmi_rg, -+ hardwarePortId, -+ numOfOpenDmas, -+ numOfExtraOpenDmas, -+ p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize); -+ } -+ else if (p_Fm->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without neither IPC nor mapped register!")); -+#endif /* FM_HAS_TOTAL_DMAS */ -+ -+ if (!initialConfig) -+ { -+ /* !initialConfig - runtime change of existing value. -+ * - read the current number of open Dma's */ -+ currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId); -+ currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId); -+ } -+ -+#ifdef FM_NO_GUARANTEED_RESET_VALUES -+ /* it's illegal to be in a state where this is not the first set and no value is specified */ -+ ASSERT_COND(initialConfig || numOfOpenDmas); -+ if (!numOfOpenDmas) -+ { -+ /* !numOfOpenDmas - first configuration according to values in regs. -+ * - read the current number of open Dma's */ -+ currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId); -+ currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId); -+ /* This is the first configuration and user did not specify value (!numOfOpenDmas), -+ * reset values will be used and we just save these values for resource management */ -+ p_Fm->p_FmStateStruct->extraOpenDmasPoolSize = -+ (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, currentExtraVal); -+ p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += currentVal; -+ *p_NumOfOpenDmas = currentVal; -+ *p_NumOfExtraOpenDmas = currentExtraVal; -+ return E_OK; -+ } -+#endif /* FM_NO_GUARANTEED_RESET_VALUES */ -+ -+ if (numOfExtraOpenDmas > currentExtraVal) -+ p_Fm->p_FmStateStruct->extraOpenDmasPoolSize = -+ (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas); -+ -+#ifdef FM_HAS_TOTAL_DMAS -+ if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) && -+ (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > -+ p_Fm->p_FmStateStruct->maxNumOfOpenDmas)) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, -+ ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.", -+ p_Fm->p_FmStateStruct->fmId)); -+#else -+ if ((p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) && -+#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 -+ !((p_Fm->p_FmStateStruct->revInfo.majorRev == 6) && -+ (p_Fm->p_FmStateStruct->revInfo.minorRev == 0)) && -+#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */ -+ (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > DMA_THRESH_MAX_COMMQ + 1)) -+ RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, -+ ("Requested numOfOpenDmas for fm%d exceeds DMA Command queue (%d)", -+ p_Fm->p_FmStateStruct->fmId, DMA_THRESH_MAX_COMMQ+1)); -+#endif /* FM_HAS_TOTAL_DMAS */ -+ else -+ { -+ ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= currentVal); -+ /* update acummulated */ -+ p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= currentVal; -+ p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas; -+ -+#ifdef FM_HAS_TOTAL_DMAS -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6) -+ totalNumDmas = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize); -+#endif /* FM_HAS_TOTAL_DMAS */ -+ fman_set_num_of_open_dmas(bmi_rg, -+ hardwarePortId, -+ numOfOpenDmas, -+ numOfExtraOpenDmas, -+ totalNumDmas); -+ } -+ -+ return E_OK; -+} -+ -+#if (DPAA_VERSION >= 11) -+t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm, -+ e_FmPortType portType, -+ uint8_t portId, -+ uint16_t relativeProfile) -+{ -+ t_Fm *p_Fm; -+ t_FmSp *p_FmPcdSp; -+ uint8_t swPortIndex=0, hardwarePortId; -+ -+ ASSERT_COND(h_Fm); -+ p_Fm = (t_Fm*)h_Fm; -+ -+ hardwarePortId = SwPortIdToHwPortId(portType, -+ portId, -+ p_Fm->p_FmStateStruct->revInfo.majorRev, -+ p_Fm->p_FmStateStruct->revInfo.minorRev); -+ ASSERT_COND(hardwarePortId); -+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); -+ -+ p_FmPcdSp = p_Fm->p_FmSp; -+ ASSERT_COND(p_FmPcdSp); -+ -+ if (!p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Port has no allocated profiles")); -+ if (relativeProfile >= p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles) -+ RETURN_ERROR(MAJOR, E_NOT_IN_RANGE , ("Profile id is out of range")); -+ -+ return E_OK; -+} -+ -+t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm, -+ e_FmPortType portType, -+ uint8_t portId, -+ uint16_t relativeProfile, -+ uint16_t *p_AbsoluteId) -+{ -+ t_Fm *p_Fm; -+ t_FmSp *p_FmPcdSp; -+ uint8_t swPortIndex=0, hardwarePortId; -+ t_Error err; -+ -+ ASSERT_COND(h_Fm); -+ p_Fm = (t_Fm*)h_Fm; -+ -+ err = FmVSPCheckRelativeProfile(h_Fm, portType, portId, relativeProfile); -+ if (err != E_OK) -+ return err; -+ -+ hardwarePortId = SwPortIdToHwPortId(portType, -+ portId, -+ p_Fm->p_FmStateStruct->revInfo.majorRev, -+ p_Fm->p_FmStateStruct->revInfo.minorRev); -+ ASSERT_COND(hardwarePortId); -+ HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId); -+ -+ p_FmPcdSp = p_Fm->p_FmSp; -+ ASSERT_COND(p_FmPcdSp); -+ -+ *p_AbsoluteId = (uint16_t)(p_FmPcdSp->portsMapping[swPortIndex].profilesBase + relativeProfile); -+ -+ return E_OK; -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+static t_Error InitFmDma(t_Fm *p_Fm) -+{ -+ t_Error err; -+ -+ err = (t_Error)fman_dma_init(p_Fm->p_FmDmaRegs, p_Fm->p_FmDriverParam); -+ if (err != E_OK) -+ return err; -+ -+ /* Allocate MURAM for CAM */ -+ p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, -+ (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY), -+ DMA_CAM_ALIGN)); -+ if (!p_Fm->camBaseAddr) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed")); -+ -+ WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr), -+ 0, -+ (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY)); -+ -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev == 2) -+ { -+ FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr)); -+ -+ p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, -+ (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128), -+ 64)); -+ if (!p_Fm->camBaseAddr) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed")); -+ -+ WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr), -+ 0, -+ (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128)); -+ -+ switch(p_Fm->p_FmDriverParam->dma_cam_num_of_entries) -+ { -+ case (8): -+ WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xff000000); -+ break; -+ case (16): -+ WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffff0000); -+ break; -+ case (24): -+ WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffff00); -+ break; -+ case (32): -+ WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffffff); -+ break; -+ default: -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("wrong dma_cam_num_of_entries")); -+ } -+ } -+ -+ p_Fm->p_FmDriverParam->cam_base_addr = -+ (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr); -+ -+ return E_OK; -+} -+ -+static t_Error InitFmFpm(t_Fm *p_Fm) -+{ -+ return (t_Error)fman_fpm_init(p_Fm->p_FmFpmRegs, p_Fm->p_FmDriverParam); -+} -+ -+static t_Error InitFmBmi(t_Fm *p_Fm) -+{ -+ return (t_Error)fman_bmi_init(p_Fm->p_FmBmiRegs, p_Fm->p_FmDriverParam); -+} -+ -+static t_Error InitFmQmi(t_Fm *p_Fm) -+{ -+ return (t_Error)fman_qmi_init(p_Fm->p_FmQmiRegs, p_Fm->p_FmDriverParam); -+} -+ -+static t_Error InitGuestMode(t_Fm *p_Fm) -+{ -+ t_Error err = E_OK; -+ int i; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ -+ ASSERT_COND(p_Fm); -+ ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID); -+ -+ /* build the FM guest partition IPC address */ -+ if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); -+ -+ /* build the FM master partition IPC address */ -+ memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE); -+ if (Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); -+ -+ for (i=0;iintrMng[i].f_Isr = UnimplementedIsr; -+ -+ p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName); -+ if (p_Fm->h_IpcSessions[0]) -+ { -+ uint8_t isMasterAlive; -+ t_FmIpcParams ipcParams; -+ -+ err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE); -+ if (err) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_MASTER_IS_ALIVE; -+ msg.msgBody[0] = p_Fm->guestId; -+ replyLength = sizeof(uint32_t) + sizeof(uint8_t); -+ do -+ { -+ blockingFlag = TRUE; -+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId)+sizeof(p_Fm->guestId), -+ (uint8_t*)&reply, -+ &replyLength, -+ IpcMsgCompletionCB, -+ p_Fm)) != E_OK) -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ while (blockingFlag) ; -+ if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))) -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ isMasterAlive = *(uint8_t*)(reply.replyBody); -+ } while (!isMasterAlive); -+ -+ /* read FM parameters and save */ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_GET_PARAMS; -+ replyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams); -+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcParams))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ memcpy((uint8_t*)&ipcParams, reply.replyBody, sizeof(t_FmIpcParams)); -+ -+ p_Fm->p_FmStateStruct->fmClkFreq = ipcParams.fmClkFreq; -+ p_Fm->p_FmStateStruct->fmMacClkFreq = ipcParams.fmMacClkFreq; -+ p_Fm->p_FmStateStruct->revInfo.majorRev = ipcParams.majorRev; -+ p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev; -+ } -+ else -+ { -+ DBG(WARNING, ("FM Guest mode - without IPC")); -+ if (!p_Fm->p_FmStateStruct->fmClkFreq) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC")); -+ if (p_Fm->baseAddr) -+ { -+ fman_get_revision(p_Fm->p_FmFpmRegs, -+ &p_Fm->p_FmStateStruct->revInfo.majorRev, -+ &p_Fm->p_FmStateStruct->revInfo.minorRev); -+ -+ } -+ } -+ -+#if (DPAA_VERSION >= 11) -+ p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId); -+ if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE)) -+ DBG(WARNING, ("partition VSPs allocation is FAILED")); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ /* General FM driver initialization */ -+ if (p_Fm->baseAddr) -+ p_Fm->fmMuramPhysBaseAddr = -+ (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM))); -+ -+ XX_Free(p_Fm->p_FmDriverParam); -+ p_Fm->p_FmDriverParam = NULL; -+ -+ if ((p_Fm->guestId == NCSW_MASTER_ID) || -+ (p_Fm->h_IpcSessions[0])) -+ { -+ FM_DisableRamsEcc(p_Fm); -+ FmMuramClear(p_Fm->h_FmMuram); -+ FM_EnableRamsEcc(p_Fm); -+ } -+ -+ return E_OK; -+} -+ -+static __inline__ enum fman_exceptions FmanExceptionTrans(e_FmExceptions exception) -+{ -+ switch (exception) { -+ case e_FM_EX_DMA_BUS_ERROR: -+ return E_FMAN_EX_DMA_BUS_ERROR; -+ case e_FM_EX_DMA_READ_ECC: -+ return E_FMAN_EX_DMA_READ_ECC; -+ case e_FM_EX_DMA_SYSTEM_WRITE_ECC: -+ return E_FMAN_EX_DMA_SYSTEM_WRITE_ECC; -+ case e_FM_EX_DMA_FM_WRITE_ECC: -+ return E_FMAN_EX_DMA_FM_WRITE_ECC; -+ case e_FM_EX_FPM_STALL_ON_TASKS: -+ return E_FMAN_EX_FPM_STALL_ON_TASKS; -+ case e_FM_EX_FPM_SINGLE_ECC: -+ return E_FMAN_EX_FPM_SINGLE_ECC; -+ case e_FM_EX_FPM_DOUBLE_ECC: -+ return E_FMAN_EX_FPM_DOUBLE_ECC; -+ case e_FM_EX_QMI_SINGLE_ECC: -+ return E_FMAN_EX_QMI_SINGLE_ECC; -+ case e_FM_EX_QMI_DOUBLE_ECC: -+ return E_FMAN_EX_QMI_DOUBLE_ECC; -+ case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: -+ return E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; -+ case e_FM_EX_BMI_LIST_RAM_ECC: -+ return E_FMAN_EX_BMI_LIST_RAM_ECC; -+ case e_FM_EX_BMI_STORAGE_PROFILE_ECC: -+ return E_FMAN_EX_BMI_STORAGE_PROFILE_ECC; -+ case e_FM_EX_BMI_STATISTICS_RAM_ECC: -+ return E_FMAN_EX_BMI_STATISTICS_RAM_ECC; -+ case e_FM_EX_BMI_DISPATCH_RAM_ECC: -+ return E_FMAN_EX_BMI_DISPATCH_RAM_ECC; -+ case e_FM_EX_IRAM_ECC: -+ return E_FMAN_EX_IRAM_ECC; -+ case e_FM_EX_MURAM_ECC: -+ return E_FMAN_EX_MURAM_ECC; -+ default: -+ return E_FMAN_EX_DMA_BUS_ERROR; -+ } -+} -+ -+uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev) -+{ -+ switch (type) -+ { -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ CHECK_PORT_ID_OH_PORTS(relativePortId); -+ return (uint8_t)(BASE_OH_PORTID + (relativePortId)); -+ case (e_FM_PORT_TYPE_RX): -+ CHECK_PORT_ID_1G_RX_PORTS(relativePortId); -+ return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId)); -+ case (e_FM_PORT_TYPE_RX_10G): -+ /* The 10G port in T1024 (FMan Version 6.4) is the first port. -+ * This is the reason why the 1G port offset is used. -+ */ -+ if (majorRev == 6 && minorRev == 4) -+ { -+ CHECK_PORT_ID_1G_RX_PORTS(relativePortId); -+ return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId)); -+ } -+ else -+ { -+ CHECK_PORT_ID_10G_RX_PORTS(relativePortId); -+ return (uint8_t)(BASE_10G_RX_PORTID + (relativePortId)); -+ } -+ case (e_FM_PORT_TYPE_TX): -+ CHECK_PORT_ID_1G_TX_PORTS(relativePortId); -+ return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId)); -+ case (e_FM_PORT_TYPE_TX_10G): -+ /* The 10G port in T1024 (FMan Version 6.4) is the first port. -+ * This is the reason why the 1G port offset is used. -+ */ -+ if (majorRev == 6 && minorRev == 4) -+ { -+ CHECK_PORT_ID_1G_TX_PORTS(relativePortId); -+ return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId)); -+ } -+ else -+ { -+ CHECK_PORT_ID_10G_TX_PORTS(relativePortId); -+ return (uint8_t)(BASE_10G_TX_PORTID + (relativePortId)); -+ } -+ default: -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type")); -+ return 0; -+ } -+} -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+t_Error FmDumpPortRegs (t_Handle h_Fm, uint8_t hardwarePortId) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ -+ DECLARE_DUMP; -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) || -+ p_Fm->baseAddr), E_INVALID_OPERATION); -+ -+ DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId))); -+ DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t)); -+ -+ DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId ))); -+ DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t)); -+ -+ DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], ("fmbm_spliodn for port %u", (hardwarePortId))); -+ DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], sizeof(uint32_t)); -+ -+ DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], ("fmfp_ps for port %u", (hardwarePortId))); -+ DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], sizeof(uint32_t)); -+ -+ DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], ("fmdmplr for port %u", (hardwarePortId))); -+ DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], sizeof(uint32_t)); -+ -+ return E_OK; -+} -+#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */ -+ -+ -+/*****************************************************************************/ -+/* API Init unit functions */ -+/*****************************************************************************/ -+t_Handle FM_Config(t_FmParams *p_FmParam) -+{ -+ t_Fm *p_Fm; -+ uint8_t i; -+ uintptr_t baseAddr; -+ -+ SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL); -+ SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) || -+ (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)), -+ E_INVALID_VALUE, NULL); -+ -+ baseAddr = p_FmParam->baseAddr; -+ -+ /* Allocate FM structure */ -+ p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm)); -+ if (!p_Fm) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure")); -+ return NULL; -+ } -+ memset(p_Fm, 0, sizeof(t_Fm)); -+ -+ p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct)); -+ if (!p_Fm->p_FmStateStruct) -+ { -+ XX_Free(p_Fm); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure")); -+ return NULL; -+ } -+ memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct)); -+ -+ /* Initialize FM parameters which will be kept by the driver */ -+ p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId; -+ p_Fm->guestId = p_FmParam->guestId; -+ -+ for (i=0; ip_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY; -+ -+ /* Allocate the FM driver's parameters structure */ -+ p_Fm->p_FmDriverParam = (struct fman_cfg *)XX_Malloc(sizeof(struct fman_cfg)); -+ if (!p_Fm->p_FmDriverParam) -+ { -+ XX_Free(p_Fm->p_FmStateStruct); -+ XX_Free(p_Fm); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters")); -+ return NULL; -+ } -+ memset(p_Fm->p_FmDriverParam, 0, sizeof(struct fman_cfg)); -+ -+#if (DPAA_VERSION >= 11) -+ p_Fm->p_FmSp = (t_FmSp *)XX_Malloc(sizeof(t_FmSp)); -+ if (!p_Fm->p_FmSp) -+ { -+ XX_Free(p_Fm->p_FmDriverParam); -+ XX_Free(p_Fm->p_FmStateStruct); -+ XX_Free(p_Fm); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("allocation for internal data structure failed")); -+ return NULL; -+ } -+ memset(p_Fm->p_FmSp, 0, sizeof(t_FmSp)); -+ -+ for (i=0; ip_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ /* Initialize FM parameters which will be kept by the driver */ -+ p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId; -+ p_Fm->h_FmMuram = p_FmParam->h_FmMuram; -+ p_Fm->h_App = p_FmParam->h_App; -+ p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq; -+ p_Fm->p_FmStateStruct->fmMacClkFreq = p_FmParam->fmClkFreq / ((!p_FmParam->fmMacClkRatio)? 2: p_FmParam->fmMacClkRatio); -+ p_Fm->f_Exception = p_FmParam->f_Exception; -+ p_Fm->f_BusError = p_FmParam->f_BusError; -+ p_Fm->p_FmFpmRegs = (struct fman_fpm_regs *)UINT_TO_PTR(baseAddr + FM_MM_FPM); -+ p_Fm->p_FmBmiRegs = (struct fman_bmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI); -+ p_Fm->p_FmQmiRegs = (struct fman_qmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_QMI); -+ p_Fm->p_FmDmaRegs = (struct fman_dma_regs *)UINT_TO_PTR(baseAddr + FM_MM_DMA); -+ p_Fm->p_FmRegs = (struct fman_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI); -+ p_Fm->baseAddr = baseAddr; -+ p_Fm->p_FmStateStruct->irq = p_FmParam->irq; -+ p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq; -+ p_Fm->hcPortInitialized = FALSE; -+ p_Fm->independentMode = FALSE; -+ -+ p_Fm->h_Spinlock = XX_InitSpinlock(); -+ if (!p_Fm->h_Spinlock) -+ { -+ XX_Free(p_Fm->p_FmDriverParam); -+ XX_Free(p_Fm->p_FmStateStruct); -+ XX_Free(p_Fm); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("can't allocate spinlock!")); -+ return NULL; -+ } -+ -+#if (DPAA_VERSION >= 11) -+ p_Fm->partVSPBase = p_FmParam->partVSPBase; -+ p_Fm->partNumOfVSPs = p_FmParam->partNumOfVSPs; -+ p_Fm->vspBaseAddr = p_FmParam->vspBaseAddr; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ fman_defconfig(p_Fm->p_FmDriverParam, -+ !!(p_Fm->guestId == NCSW_MASTER_ID)); -+/* overide macros dependent parameters */ -+#ifdef FM_PEDANTIC_DMA -+ p_Fm->p_FmDriverParam->pedantic_dma = TRUE; -+ p_Fm->p_FmDriverParam->dma_aid_override = TRUE; -+#endif /* FM_PEDANTIC_DMA */ -+#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT -+ p_Fm->p_FmDriverParam->qmi_deq_option_support = TRUE; -+#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ -+ -+ p_Fm->p_FmStateStruct->ramsEccEnable = FALSE; -+ p_Fm->p_FmStateStruct->extraFifoPoolSize = 0; -+ p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions; -+ p_Fm->resetOnInit = DEFAULT_resetOnInit; -+ p_Fm->f_ResetOnInitOverride = DEFAULT_resetOnInitOverrideCallback; -+ p_Fm->fwVerify = DEFAULT_VerifyUcode; -+ p_Fm->firmware.size = p_FmParam->firmware.size; -+ if (p_Fm->firmware.size) -+ { -+ p_Fm->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->firmware.size); -+ if (!p_Fm->firmware.p_Code) -+ { -+ XX_FreeSpinlock(p_Fm->h_Spinlock); -+ XX_Free(p_Fm->p_FmStateStruct); -+ XX_Free(p_Fm->p_FmDriverParam); -+ XX_Free(p_Fm); -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code")); -+ return NULL; -+ } -+ memcpy(p_Fm->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->firmware.size); -+ } -+ -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ return p_Fm; -+ -+ /* read revision */ -+ /* Chip dependent, will be configured in Init */ -+ fman_get_revision(p_Fm->p_FmFpmRegs, -+ &p_Fm->p_FmStateStruct->revInfo.majorRev, -+ &p_Fm->p_FmStateStruct->revInfo.minorRev); -+ -+#ifdef FM_AID_MODE_NO_TNUM_SW005 -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ p_Fm->p_FmDriverParam->dma_aid_mode = e_FM_DMA_AID_OUT_PORT_ID; -+#endif /* FM_AID_MODE_NO_TNUM_SW005 */ -+#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4) -+ p_Fm->p_FmDriverParam->qmi_def_tnums_thresh = QMI_DEF_TNUMS_THRESH; -+#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ -+ -+ p_Fm->p_FmStateStruct->totalFifoSize = 0; -+ p_Fm->p_FmStateStruct->totalNumOfTasks = -+ DEFAULT_totalNumOfTasks(p_Fm->p_FmStateStruct->revInfo.majorRev, -+ p_Fm->p_FmStateStruct->revInfo.minorRev); -+ -+#ifdef FM_HAS_TOTAL_DMAS -+ p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS; -+#endif /* FM_HAS_TOTAL_DMAS */ -+#if (DPAA_VERSION < 11) -+ p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = DEFAULT_dmaCommQLow; -+ p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = DEFAULT_dmaCommQHigh; -+ p_Fm->p_FmDriverParam->dma_cam_num_of_entries = DEFAULT_dmaCamNumOfEntries; -+ p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = DEFAULT_dmaReadIntBufLow; -+ p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = DEFAULT_dmaReadIntBufHigh; -+ p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = DEFAULT_dmaWriteIntBufLow; -+ p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = DEFAULT_dmaWriteIntBufHigh; -+ p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = DEFAULT_axiDbgNumOfBeats; -+#endif /* (DPAA_VERSION < 11) */ -+#ifdef FM_NO_TNUM_AGING -+ p_Fm->p_FmDriverParam->tnum_aging_period = 0; -+#endif -+ p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period; -+ -+ return p_Fm; -+} -+ -+/**************************************************************************//** -+ @Function FM_Init -+ -+ @Description Initializes the FM module -+ -+ @Param[in] h_Fm - FM module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_Init(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ struct fman_cfg *p_FmDriverParam = NULL; -+ t_Error err = E_OK; -+ int i; -+ t_FmRevisionInfo revInfo; -+ struct fman_rg fman_rg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ -+ fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; -+ fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; -+ fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; -+ fman_rg.dma_rg = p_Fm->p_FmDmaRegs; -+ -+ p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT; -+ p_Fm->p_FmDriverParam->num_of_fman_ctrl_evnt_regs = FM_NUM_OF_FMAN_CTRL_EVENT_REGS; -+ -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ return InitGuestMode(p_Fm); -+ -+ /* if user didn't configured totalFifoSize - (totalFifoSize=0) we configure default -+ * according to chip. otherwise, we use user's configuration. -+ */ -+ if (p_Fm->p_FmStateStruct->totalFifoSize == 0) -+ p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize(p_Fm->p_FmStateStruct->revInfo.majorRev, -+ p_Fm->p_FmStateStruct->revInfo.minorRev); -+ -+ CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters); -+ -+ p_FmDriverParam = p_Fm->p_FmDriverParam; -+ -+ FM_GetRevision(p_Fm, &revInfo); -+ -+ /* clear revision-dependent non existing exception */ -+#ifdef FM_NO_DISPATCH_RAM_ECC -+ if ((revInfo.majorRev != 4) && -+ (revInfo.majorRev < 6)) -+ p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC; -+#endif /* FM_NO_DISPATCH_RAM_ECC */ -+ -+#ifdef FM_QMI_NO_ECC_EXCEPTIONS -+ if (revInfo.majorRev == 4) -+ p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC); -+#endif /* FM_QMI_NO_ECC_EXCEPTIONS */ -+ -+#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION -+ if (revInfo.majorRev >= 6) -+ p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_QMI_SINGLE_ECC; -+#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */ -+ -+ FmMuramClear(p_Fm->h_FmMuram); -+ -+ /* clear CPG */ -+ IOMemSet32(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_CGP), 0, FM_PORT_NUM_OF_CONGESTION_GRPS); -+ -+ /* add to the default exceptions the user's definitions */ -+ p_Fm->p_FmStateStruct->exceptions |= p_Fm->userSetExceptions; -+ -+ /* Reset the FM if required */ -+ if (p_Fm->resetOnInit) -+ { -+#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 -+ if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+#else /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ -+ -+ if (p_Fm->f_ResetOnInitOverride) -+ { -+ /* Perform user specific FMan reset */ -+ p_Fm->f_ResetOnInitOverride(h_Fm); -+ } -+ else -+ { -+ /* Perform FMan reset */ -+ FmReset(h_Fm); -+ } -+ -+ if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs)) -+ { -+ fman_resume(p_Fm->p_FmFpmRegs); -+ XX_UDelay(100); -+ } -+#endif /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ -+ } -+ -+#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 -+ if (!p_Fm->resetOnInit) /* Skip operations done in errata workaround */ -+ { -+#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ -+ /* Load FMan-Controller code to IRAM */ -+ -+ ClearIRam(p_Fm); -+ -+ if (p_Fm->firmware.p_Code && (LoadFmanCtrlCode(p_Fm) != E_OK)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 -+ } -+#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ -+ -+#ifdef FM_CAPWAP_SUPPORT -+ /* save first 256 byte in MURAM */ -+ p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0)); -+ if (!p_Fm->resAddr) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed")); -+ -+ WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256); -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+#if (DPAA_VERSION >= 11) -+ p_Fm->partVSPBase = AllocVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId); -+ if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE)) -+ DBG(WARNING, ("partition VSPs allocation is FAILED")); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ /* General FM driver initialization */ -+ p_Fm->fmMuramPhysBaseAddr = -+ (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM))); -+ -+ for (i=0;iintrMng[i].f_Isr = UnimplementedIsr; -+ for (i=0;ifmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr; -+ -+ p_FmDriverParam->exceptions = p_Fm->p_FmStateStruct->exceptions; -+ -+ /**********************/ -+ /* Init DMA Registers */ -+ /**********************/ -+ err = InitFmDma(p_Fm); -+ if (err != E_OK) -+ { -+ FreeInitResources(p_Fm); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ /**********************/ -+ /* Init FPM Registers */ -+ /**********************/ -+ err = InitFmFpm(p_Fm); -+ if (err != E_OK) -+ { -+ FreeInitResources(p_Fm); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ /* define common resources */ -+ /* allocate MURAM for FIFO according to total size */ -+ p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, -+ p_Fm->p_FmStateStruct->totalFifoSize, -+ BMI_FIFO_ALIGN)); -+ if (!p_Fm->fifoBaseAddr) -+ { -+ FreeInitResources(p_Fm); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for BMI FIFO failed")); -+ } -+ -+ p_FmDriverParam->fifo_base_addr = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr); -+ p_FmDriverParam->total_fifo_size = p_Fm->p_FmStateStruct->totalFifoSize; -+ p_FmDriverParam->total_num_of_tasks = p_Fm->p_FmStateStruct->totalNumOfTasks; -+ p_FmDriverParam->clk_freq = p_Fm->p_FmStateStruct->fmClkFreq; -+ -+ /**********************/ -+ /* Init BMI Registers */ -+ /**********************/ -+ err = InitFmBmi(p_Fm); -+ if (err != E_OK) -+ { -+ FreeInitResources(p_Fm); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ /**********************/ -+ /* Init QMI Registers */ -+ /**********************/ -+ err = InitFmQmi(p_Fm); -+ if (err != E_OK) -+ { -+ FreeInitResources(p_Fm); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ /* build the FM master partition IPC address */ -+ if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6) -+ { -+ FreeInitResources(p_Fm); -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed")); -+ } -+ -+ err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE); -+ if (err) -+ { -+ FreeInitResources(p_Fm); -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ } -+ -+ /* Register the FM interrupts handlers */ -+ if (p_Fm->p_FmStateStruct->irq != NO_IRQ) -+ { -+ XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm); -+ XX_EnableIntr(p_Fm->p_FmStateStruct->irq); -+ } -+ -+ if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ) -+ { -+ XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, (void (*) (t_Handle))FM_ErrorIsr, p_Fm); -+ XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq); -+ } -+ -+ err = (t_Error)fman_enable(&fman_rg , p_FmDriverParam); -+ if (err != E_OK) -+ return err; /* FIXME */ -+ -+ EnableTimeStamp(p_Fm); -+ -+ if (p_Fm->firmware.p_Code) -+ { -+ XX_Free(p_Fm->firmware.p_Code); -+ p_Fm->firmware.p_Code = NULL; -+ } -+ -+ XX_Free(p_Fm->p_FmDriverParam); -+ p_Fm->p_FmDriverParam = NULL; -+ -+ return E_OK; -+} -+ -+/**************************************************************************//** -+ @Function FM_Free -+ -+ @Description Frees all resources that were assigned to FM module. -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_Fm - FM module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_Free(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ struct fman_rg fman_rg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ -+ fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; -+ fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; -+ fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; -+ fman_rg.dma_rg = p_Fm->p_FmDmaRegs; -+ -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ { -+#if (DPAA_VERSION >= 11) -+ FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId); -+ -+ if (p_Fm->p_FmSp) -+ { -+ XX_Free(p_Fm->p_FmSp); -+ p_Fm->p_FmSp = NULL; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ if (p_Fm->fmModuleName[0] != 0) -+ XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName); -+ -+ if (!p_Fm->recoveryMode) -+ XX_Free(p_Fm->p_FmStateStruct); -+ -+ XX_Free(p_Fm); -+ -+ return E_OK; -+ } -+ -+ fman_free_resources(&fman_rg); -+ -+ if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0)) -+ XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName); -+ -+ if (p_Fm->p_FmStateStruct) -+ { -+ if (p_Fm->p_FmStateStruct->irq != NO_IRQ) -+ { -+ XX_DisableIntr(p_Fm->p_FmStateStruct->irq); -+ XX_FreeIntr(p_Fm->p_FmStateStruct->irq); -+ } -+ if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ) -+ { -+ XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq); -+ XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq); -+ } -+ } -+ -+#if (DPAA_VERSION >= 11) -+ FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId); -+ -+ if (p_Fm->p_FmSp) -+ { -+ XX_Free(p_Fm->p_FmSp); -+ p_Fm->p_FmSp = NULL; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ if (p_Fm->h_Spinlock) -+ XX_FreeSpinlock(p_Fm->h_Spinlock); -+ -+ if (p_Fm->p_FmDriverParam) -+ { -+ if (p_Fm->firmware.p_Code) -+ XX_Free(p_Fm->firmware.p_Code); -+ XX_Free(p_Fm->p_FmDriverParam); -+ p_Fm->p_FmDriverParam = NULL; -+ } -+ -+ FreeInitResources(p_Fm); -+ -+ if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct) -+ XX_Free(p_Fm->p_FmStateStruct); -+ -+ XX_Free(p_Fm); -+ -+ return E_OK; -+} -+ -+/*************************************************/ -+/* API Advanced Init unit functions */ -+/*************************************************/ -+ -+t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->resetOnInit = enable; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->f_ResetOnInitOverride = f_ResetOnInitOverride; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ enum fman_dma_cache_override fsl_cache_override; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, cacheOverride) -+ p_Fm->p_FmDriverParam->dma_cache_override = fsl_cache_override; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmDriverParam->dma_aid_override = aidOverride; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ enum fman_dma_aid_mode fsl_aid_mode; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ FMAN_AID_MODE_TRANS(fsl_aid_mode, aidMode); -+ p_Fm->p_FmDriverParam->dma_aid_mode = fsl_aid_mode; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+#if (DPAA_VERSION >= 11) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); -+#else -+ p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = axiDbgNumOfBeats; -+ -+ return E_OK; -+#endif /* (DPAA_VERSION >= 11) */ -+} -+ -+t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmDriverParam->dma_cam_num_of_entries = numOfEntries; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ enum fman_dma_dbg_cnt_mode fsl_dma_dbg_cnt; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, fmDmaDbgCntMode); -+ p_Fm->p_FmDriverParam->dma_dbg_cnt_mode = fsl_dma_dbg_cnt; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmDriverParam->dma_stop_on_bus_error = stop; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ enum fman_dma_emergency_level fsl_dma_emer; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ FMAN_DMA_EMER_TRANS(fsl_dma_emer, p_Emergency->emergencyLevel); -+ p_Fm->p_FmDriverParam->dma_en_emergency = TRUE; -+ p_Fm->p_FmDriverParam->dma_emergency_bus_select = (uint32_t)p_Emergency->emergencyBusSelect; -+ p_Fm->p_FmDriverParam->dma_emergency_level = fsl_dma_emer; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmDriverParam->dma_en_emergency_smoother = TRUE; -+ p_Fm->p_FmDriverParam->dma_emergency_switch_counter = emergencyCnt; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ enum fman_dma_err fsl_dma_err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ FMAN_DMA_ERR_TRANS(fsl_dma_err, dmaErr); -+ p_Fm->p_FmDriverParam->dma_err = fsl_dma_err; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ enum fman_catastrophic_err fsl_catastrophic_err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, catastrophicErr); -+ p_Fm->p_FmDriverParam->catastrophic_err = fsl_catastrophic_err; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); -+ -+ p_Fm->p_FmDriverParam->en_muram_test_mode = TRUE; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE ); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); -+ -+ p_Fm->p_FmDriverParam->en_iram_test_mode = TRUE; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmDriverParam->halt_on_external_activ = enable; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); -+ -+ p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err = enable; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t bitMask = 0; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ GET_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_Fm->userSetExceptions |= bitMask; -+ else -+ p_Fm->p_FmStateStruct->exceptions &= ~bitMask; -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmDriverParam->external_ecc_rams_enable = enable; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmDriverParam->tnum_aging_period = tnumAgingPeriod; -+ p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period; -+ -+ return E_OK; -+} -+ -+/****************************************************/ -+/* Hidden-DEBUG Only API */ -+/****************************************************/ -+ -+t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmDriverParam->disp_limit_tsh = p_FmThresholds->dispLimit; -+ p_Fm->p_FmDriverParam->prs_disp_tsh = p_FmThresholds->prsDispTh; -+ p_Fm->p_FmDriverParam->plcr_disp_tsh = p_FmThresholds->plcrDispTh; -+ p_Fm->p_FmDriverParam->kg_disp_tsh = p_FmThresholds->kgDispTh; -+ p_Fm->p_FmDriverParam->bmi_disp_tsh = p_FmThresholds->bmiDispTh; -+ p_Fm->p_FmDriverParam->qmi_enq_disp_tsh = p_FmThresholds->qmiEnqDispTh; -+ p_Fm->p_FmDriverParam->qmi_deq_disp_tsh = p_FmThresholds->qmiDeqDispTh; -+ p_Fm->p_FmDriverParam->fm_ctl1_disp_tsh = p_FmThresholds->fmCtl1DispTh; -+ p_Fm->p_FmDriverParam->fm_ctl2_disp_tsh = p_FmThresholds->fmCtl2DispTh; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmDriverParam->dma_sos_emergency = dmaSosEmergency; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds) -+ -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+#if (DPAA_VERSION >= 11) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); -+#else -+ p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency; -+ p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency; -+ -+ return E_OK; -+#endif -+} -+ -+t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = p_FmDmaThresholds->assertEmergency; -+ p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = p_FmDmaThresholds->clearEmergency; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+#if (DPAA_VERSION >= 11) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!")); -+#else -+ p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency; -+ p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency; -+ -+ return E_OK; -+#endif -+} -+ -+t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ p_Fm->p_FmDriverParam->dma_watchdog = watchdogValue; -+ -+ return E_OK; -+} -+ -+t_Error FM_ConfigEnableCounters(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+UNUSED(p_Fm); -+ -+ return E_OK; -+} -+ -+t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params) -+{ -+ t_Fm* p_Fm = (t_Fm*)h_Fm; -+ if (p_Params->setParams.type & UPDATE_FM_CLD) -+ { -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32( -+ p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800); -+ } -+ if (p_Params->setParams.type & CLEAR_IRAM_READY) -+ { -+ t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); -+ WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY); -+ } -+ if (p_Params->setParams.type & UPDATE_FPM_EXTC) -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000); -+ if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR) -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x00800000); -+ if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP) -+ { -+ if (p_Params->setParams.sleep) -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32( -+ p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP); -+ else -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32( -+ p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP); -+ } -+ if (p_Params->getParams.type & GET_FM_CLD) -+ p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld); -+ if (p_Params->getParams.type & GET_FMQM_GS) -+ p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs); -+ if (p_Params->getParams.type & GET_FM_NPI) -+ p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi); -+ if (p_Params->getParams.type & GET_FMFP_EXTC) -+ p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc); -+ return E_OK; -+} -+ -+ -+/****************************************************/ -+/* API Run-time Control uint functions */ -+/****************************************************/ -+void FM_EventIsr(t_Handle h_Fm) -+{ -+#define FM_M_CALL_1G_MAC_ISR(_id) \ -+ { \ -+ if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].guestId) \ -+ SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id), pending); \ -+ else \ -+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].h_SrcHandle);\ -+ } -+#define FM_M_CALL_10G_MAC_ISR(_id) \ -+ { \ -+ if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].guestId) \ -+ SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id), pending); \ -+ else \ -+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].h_SrcHandle);\ -+ } -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t pending, event; -+ struct fman_fpm_regs *fpm_rg; -+ -+ SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ /* normal interrupts */ -+ pending = fman_get_normal_pending(fpm_rg); -+ if (!pending) -+ return; -+ if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt -+ { -+ t_FmGetSetParams fmGetSetParams; -+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); -+ fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; -+ fmGetSetParams.setParams.sleep = 0; -+ FmGetSetParams(h_Fm, &fmGetSetParams); -+ } -+ if (pending & INTR_EN_QMI) -+ QmiEvent(p_Fm); -+ if (pending & INTR_EN_PRS) -+ p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle); -+ if (pending & INTR_EN_PLCR) -+ p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle); -+ if (pending & INTR_EN_TMR) -+ p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle); -+ -+ /* MAC events may belong to different partitions */ -+ if (pending & INTR_EN_1G_MAC0) -+ FM_M_CALL_1G_MAC_ISR(0); -+ if (pending & INTR_EN_1G_MAC1) -+ FM_M_CALL_1G_MAC_ISR(1); -+ if (pending & INTR_EN_1G_MAC2) -+ FM_M_CALL_1G_MAC_ISR(2); -+ if (pending & INTR_EN_1G_MAC3) -+ FM_M_CALL_1G_MAC_ISR(3); -+ if (pending & INTR_EN_1G_MAC4) -+ FM_M_CALL_1G_MAC_ISR(4); -+ if (pending & INTR_EN_1G_MAC5) -+ FM_M_CALL_1G_MAC_ISR(5); -+ if (pending & INTR_EN_1G_MAC6) -+ FM_M_CALL_1G_MAC_ISR(6); -+ if (pending & INTR_EN_1G_MAC7) -+ FM_M_CALL_1G_MAC_ISR(7); -+ if (pending & INTR_EN_10G_MAC0) -+ FM_M_CALL_10G_MAC_ISR(0); -+ if (pending & INTR_EN_10G_MAC1) -+ FM_M_CALL_10G_MAC_ISR(1); -+ -+ /* IM port events may belong to different partitions */ -+ if (pending & INTR_EN_REV0) -+ { -+ event = fman_get_controller_event(fpm_rg, 0); -+ if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId) -+ /*TODO IPC ISR For Fman Ctrl */ -+ ASSERT_COND(0); -+ /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */ -+ else -+ p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event); -+ -+ } -+ if (pending & INTR_EN_REV1) -+ { -+ event = fman_get_controller_event(fpm_rg, 1); -+ if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId) -+ /*TODO IPC ISR For Fman Ctrl */ -+ ASSERT_COND(0); -+ /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */ -+ else -+ p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event); -+ } -+ if (pending & INTR_EN_REV2) -+ { -+ event = fman_get_controller_event(fpm_rg, 2); -+ if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId) -+ /*TODO IPC ISR For Fman Ctrl */ -+ ASSERT_COND(0); -+ /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */ -+ else -+ p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event); -+ } -+ if (pending & INTR_EN_REV3) -+ { -+ event = fman_get_controller_event(fpm_rg, 3); -+ if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId) -+ /*TODO IPC ISR For Fman Ctrl */ -+ ASSERT_COND(0); -+ /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */ -+ else -+ p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event); -+ } -+#ifdef FM_MACSEC_SUPPORT -+ if (pending & INTR_EN_MACSEC_MAC0) -+ { -+ if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].guestId) -+ SendIpcIsr(p_Fm, e_FM_EV_MACSEC_MAC0, pending); -+ else -+ p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].h_SrcHandle); -+ } -+#endif /* FM_MACSEC_SUPPORT */ -+} -+ -+t_Error FM_ErrorIsr(t_Handle h_Fm) -+{ -+#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \ -+ { \ -+ if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \ -+ SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \ -+ else \ -+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\ -+ } -+#define FM_M_CALL_10G_MAC_ERR_ISR(_id) \ -+ { \ -+ if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].guestId) \ -+ SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id), pending); \ -+ else \ -+ p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].h_SrcHandle);\ -+ } -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t pending; -+ struct fman_fpm_regs *fpm_rg; -+ -+ SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ /* error interrupts */ -+ pending = fman_get_fpm_error_interrupts(fpm_rg); -+ if (!pending) -+ return ERROR_CODE(E_EMPTY); -+ -+ if (pending & ERR_INTR_EN_BMI) -+ BmiErrEvent(p_Fm); -+ if (pending & ERR_INTR_EN_QMI) -+ QmiErrEvent(p_Fm); -+ if (pending & ERR_INTR_EN_FPM) -+ FpmErrEvent(p_Fm); -+ if (pending & ERR_INTR_EN_DMA) -+ DmaErrEvent(p_Fm); -+ if (pending & ERR_INTR_EN_IRAM) -+ IramErrIntr(p_Fm); -+ if (pending & ERR_INTR_EN_MURAM) -+ MuramErrIntr(p_Fm); -+ if (pending & ERR_INTR_EN_PRS) -+ p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle); -+ if (pending & ERR_INTR_EN_PLCR) -+ p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle); -+ if (pending & ERR_INTR_EN_KG) -+ p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle); -+ -+ /* MAC events may belong to different partitions */ -+ if (pending & ERR_INTR_EN_1G_MAC0) -+ FM_M_CALL_1G_MAC_ERR_ISR(0); -+ if (pending & ERR_INTR_EN_1G_MAC1) -+ FM_M_CALL_1G_MAC_ERR_ISR(1); -+ if (pending & ERR_INTR_EN_1G_MAC2) -+ FM_M_CALL_1G_MAC_ERR_ISR(2); -+ if (pending & ERR_INTR_EN_1G_MAC3) -+ FM_M_CALL_1G_MAC_ERR_ISR(3); -+ if (pending & ERR_INTR_EN_1G_MAC4) -+ FM_M_CALL_1G_MAC_ERR_ISR(4); -+ if (pending & ERR_INTR_EN_1G_MAC5) -+ FM_M_CALL_1G_MAC_ERR_ISR(5); -+ if (pending & ERR_INTR_EN_1G_MAC6) -+ FM_M_CALL_1G_MAC_ERR_ISR(6); -+ if (pending & ERR_INTR_EN_1G_MAC7) -+ FM_M_CALL_1G_MAC_ERR_ISR(7); -+ if (pending & ERR_INTR_EN_10G_MAC0) -+ FM_M_CALL_10G_MAC_ERR_ISR(0); -+ if (pending & ERR_INTR_EN_10G_MAC1) -+ FM_M_CALL_10G_MAC_ERR_ISR(1); -+ -+#ifdef FM_MACSEC_SUPPORT -+ if (pending & ERR_INTR_EN_MACSEC_MAC0) -+ { -+ if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].guestId) -+ SendIpcIsr(p_Fm, e_FM_EV_ERR_MACSEC_MAC0, pending); -+ else -+ p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].h_SrcHandle); -+ } -+#endif /* FM_MACSEC_SUPPORT */ -+ -+ return E_OK; -+} -+ -+t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ int i; -+ uint8_t sum; -+ uint8_t hardwarePortId; -+ uint8_t weights[64]; -+ uint8_t weight, maxPercent = 0; -+ struct fman_bmi_regs *bmi_rg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ bmi_rg = p_Fm->p_FmBmiRegs; -+ -+ memset(weights, 0, (sizeof(uint8_t) * 64)); -+ -+ /* check that all ports add up to 100% */ -+ sum = 0; -+ for (i=0; i < p_PortsBandwidth->numOfPorts; i++) -+ sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth; -+ if (sum != 100) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%")); -+ -+ /* find highest percent */ -+ for (i=0; i < p_PortsBandwidth->numOfPorts; i++) -+ { -+ if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent) -+ maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth; -+ } -+ -+ ASSERT_COND(maxPercent > 0); /* guaranteed by sum = 100 */ -+ -+ /* calculate weight for each port */ -+ for (i=0; i < p_PortsBandwidth->numOfPorts; i++) -+ { -+ weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) / maxPercent); -+ /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exact division -+ is not reached, we round up so that: -+ 0 until maxPercent/PORT_MAX_WEIGHT get "1" -+ maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2" -+ ... -+ maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */ -+ if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent)) -+ weight++; -+ -+ /* find the location of this port within the register */ -+ hardwarePortId = -+ SwPortIdToHwPortId(p_PortsBandwidth->portsBandwidths[i].type, -+ p_PortsBandwidth->portsBandwidths[i].relativePortId, -+ p_Fm->p_FmStateStruct->revInfo.majorRev, -+ p_Fm->p_FmStateStruct->revInfo.minorRev); -+ -+ ASSERT_COND(IN_RANGE(1, hardwarePortId, 63)); -+ weights[hardwarePortId] = weight; -+ } -+ -+ fman_set_ports_bandwidth(bmi_rg, weights); -+ -+ return E_OK; -+} -+ -+t_Error FM_EnableRamsEcc(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ struct fman_fpm_regs *fpm_rg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ -+ fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ { -+ t_FmIpcMsg msg; -+ t_Error err; -+ -+ memset(&msg, 0, sizeof(msg)); -+ msg.msgId = FM_ENABLE_RAM_ECC; -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ NULL, -+ NULL, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ return E_OK; -+ } -+ -+ if (!p_Fm->p_FmStateStruct->internalCall) -+ p_Fm->p_FmStateStruct->explicitEnable = TRUE; -+ p_Fm->p_FmStateStruct->internalCall = FALSE; -+ -+ if (p_Fm->p_FmStateStruct->ramsEccEnable) -+ return E_OK; -+ else -+ { -+ fman_enable_rams_ecc(fpm_rg); -+ p_Fm->p_FmStateStruct->ramsEccEnable = TRUE; -+ } -+ -+ return E_OK; -+} -+ -+t_Error FM_DisableRamsEcc(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ bool explicitDisable = FALSE; -+ struct fman_fpm_regs *fpm_rg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE); -+ -+ fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ if (p_Fm->guestId != NCSW_MASTER_ID) -+ { -+ t_Error err; -+ t_FmIpcMsg msg; -+ -+ memset(&msg, 0, sizeof(msg)); -+ msg.msgId = FM_DISABLE_RAM_ECC; -+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ NULL, -+ NULL, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ return E_OK; -+ } -+ -+ if (!p_Fm->p_FmStateStruct->internalCall) -+ explicitDisable = TRUE; -+ p_Fm->p_FmStateStruct->internalCall = FALSE; -+ -+ /* if rams are already disabled, or if rams were explicitly enabled and are -+ currently called indirectly (not explicitly), ignore this call. */ -+ if (!p_Fm->p_FmStateStruct->ramsEccEnable || -+ (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable)) -+ return E_OK; -+ else -+ { -+ if (p_Fm->p_FmStateStruct->explicitEnable) -+ /* This is the case were both explicit are TRUE. -+ Turn off this flag for cases were following ramsEnable -+ routines are called */ -+ p_Fm->p_FmStateStruct->explicitEnable = FALSE; -+ -+ fman_enable_rams_ecc(fpm_rg); -+ p_Fm->p_FmStateStruct->ramsEccEnable = FALSE; -+ } -+ -+ return E_OK; -+} -+ -+t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t bitMask = 0; -+ enum fman_exceptions fslException; -+ struct fman_rg fman_rg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ -+ fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; -+ fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; -+ fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; -+ fman_rg.dma_rg = p_Fm->p_FmDmaRegs; -+ -+ GET_EXCEPTION_FLAG(bitMask, exception); -+ if (bitMask) -+ { -+ if (enable) -+ p_Fm->p_FmStateStruct->exceptions |= bitMask; -+ else -+ p_Fm->p_FmStateStruct->exceptions &= ~bitMask; -+ -+ fslException = FmanExceptionTrans(exception); -+ -+ return (t_Error)fman_set_exception(&fman_rg, -+ fslException, -+ enable); -+ } -+ else -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception")); -+ -+ return E_OK; -+} -+ -+t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ p_FmRevisionInfo->majorRev = p_Fm->p_FmStateStruct->revInfo.majorRev; -+ p_FmRevisionInfo->minorRev = p_Fm->p_FmStateStruct->revInfo.minorRev; -+ -+ return E_OK; -+} -+ -+t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ t_FMIramRegs *p_Iram; -+ uint32_t revInfo; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_RevisionInfo, E_NULL_POINTER); -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_Error err; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength; -+ t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_GET_FMAN_CTRL_CODE_REV; -+ replyLength = sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo); -+ if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ if (replyLength != (sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo))) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmCtrlCodeRevisionInfo)); -+ p_RevisionInfo->packageRev = ipcRevInfo.packageRev; -+ p_RevisionInfo->majorRev = ipcRevInfo.majorRev; -+ p_RevisionInfo->minorRev = ipcRevInfo.minorRev; -+ return (t_Error)(reply.error); -+ } -+ else if (p_Fm->guestId != NCSW_MASTER_ID) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("running in guest-mode without IPC!")); -+ -+ p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM); -+ WRITE_UINT32(p_Iram->iadd, 0x4); -+ while (GET_UINT32(p_Iram->iadd) != 0x4) ; -+ revInfo = GET_UINT32(p_Iram->idata); -+ p_RevisionInfo->packageRev = (uint16_t)((revInfo & 0xFFFF0000) >> 16); -+ p_RevisionInfo->majorRev = (uint8_t)((revInfo & 0x0000FF00) >> 8); -+ p_RevisionInfo->minorRev = (uint8_t)(revInfo & 0x000000FF); -+ -+ return E_OK; -+} -+ -+uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ t_Error err; -+ uint32_t counterValue; -+ struct fman_rg fman_rg; -+ enum fman_counters fsl_counter; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0); -+ -+ fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; -+ fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; -+ fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; -+ fman_rg.dma_rg = p_Fm->p_FmDmaRegs; -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->baseAddr && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ uint32_t replyLength, outCounter; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_GET_COUNTER; -+ memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t)); -+ replyLength = sizeof(uint32_t) + sizeof(uint32_t); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId) +sizeof(counterValue), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ { -+ REPORT_ERROR(MAJOR, err, NO_MSG); -+ return 0; -+ } -+ if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t))) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ return 0; -+ } -+ -+ memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t)); -+ return outCounter; -+ } -+ else if (!p_Fm->baseAddr) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Either IPC or 'baseAddress' is required!")); -+ return 0; -+ } -+ -+ /* When applicable (when there is an 'enable counters' bit, -+ check that counters are enabled */ -+ switch (counter) -+ { -+ case (e_FM_COUNTERS_DEQ_1): -+ case (e_FM_COUNTERS_DEQ_2): -+ case (e_FM_COUNTERS_DEQ_3): -+ if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) || -+ (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported")); -+ return 0; -+ } -+ case (e_FM_COUNTERS_ENQ_TOTAL_FRAME): -+ case (e_FM_COUNTERS_DEQ_TOTAL_FRAME): -+ case (e_FM_COUNTERS_DEQ_0): -+ case (e_FM_COUNTERS_DEQ_FROM_DEFAULT): -+ case (e_FM_COUNTERS_DEQ_FROM_CONTEXT): -+ case (e_FM_COUNTERS_DEQ_FROM_FD): -+ case (e_FM_COUNTERS_DEQ_CONFIRM): -+ if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS)) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Requested counter was not enabled")); -+ return 0; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ FMAN_COUNTERS_TRANS(fsl_counter, counter); -+ return fman_get_counter(&fman_rg, fsl_counter); -+} -+ -+t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ struct fman_rg fman_rg; -+ enum fman_counters fsl_counter; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ -+ fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; -+ fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; -+ fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; -+ fman_rg.dma_rg = p_Fm->p_FmDmaRegs; -+ -+ FMAN_COUNTERS_TRANS(fsl_counter, counter); -+ return (t_Error)fman_modify_counter(&fman_rg, fsl_counter, val); -+} -+ -+void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ struct fman_dma_regs *dma_rg; -+ -+ SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ -+ dma_rg = p_Fm->p_FmDmaRegs; -+ -+ fman_set_dma_emergency(dma_rg, !!(muramPort==e_FM_DMA_MURAM_PORT_WRITE), enable); -+} -+ -+void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ struct fman_dma_regs *dma_rg; -+ -+ SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ -+ dma_rg = p_Fm->p_FmDmaRegs; -+ -+ fman_set_dma_ext_bus_pri(dma_rg, pri); -+} -+ -+void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ uint32_t dmaStatus; -+ struct fman_dma_regs *dma_rg; -+ -+ SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ -+ dma_rg = p_Fm->p_FmDmaRegs; -+ -+ if ((p_Fm->guestId != NCSW_MASTER_ID) && -+ !p_Fm->baseAddr && -+ p_Fm->h_IpcSessions[0]) -+ { -+ t_FmIpcDmaStatus ipcDmaStatus; -+ t_FmIpcMsg msg; -+ t_FmIpcReply reply; -+ t_Error err; -+ uint32_t replyLength; -+ -+ memset(&msg, 0, sizeof(msg)); -+ memset(&reply, 0, sizeof(reply)); -+ msg.msgId = FM_DMA_STAT; -+ replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus); -+ err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0], -+ (uint8_t*)&msg, -+ sizeof(msg.msgId), -+ (uint8_t*)&reply, -+ &replyLength, -+ NULL, -+ NULL); -+ if (err != E_OK) -+ { -+ REPORT_ERROR(MINOR, err, NO_MSG); -+ return; -+ } -+ if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus))) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch")); -+ return; -+ } -+ memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus)); -+ -+ p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */ -+ p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */ -+ p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */ -+ p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */ -+ p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */ -+ p_FmDmaStatus->singlePortEccError = (bool)ipcDmaStatus.boolSinglePortEccError; /**< Double ECC error on buffer write from FM side */ -+ return; -+ } -+ else if (!p_Fm->baseAddr) -+ { -+ REPORT_ERROR(MINOR, E_NOT_SUPPORTED, -+ ("Either IPC or 'baseAddress' is required!")); -+ return; -+ } -+ -+ dmaStatus = fman_get_dma_status(dma_rg); -+ -+ p_FmDmaStatus->cmqNotEmpty = (bool)(dmaStatus & DMA_STATUS_CMD_QUEUE_NOT_EMPTY); -+ p_FmDmaStatus->busError = (bool)(dmaStatus & DMA_STATUS_BUS_ERR); -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ p_FmDmaStatus->singlePortEccError = (bool)(dmaStatus & DMA_STATUS_FM_SPDAT_ECC); -+ else -+ { -+ p_FmDmaStatus->readBufEccError = (bool)(dmaStatus & DMA_STATUS_READ_ECC); -+ p_FmDmaStatus->writeBufEccSysError = (bool)(dmaStatus & DMA_STATUS_SYSTEM_WRITE_ECC); -+ p_FmDmaStatus->writeBufEccFmError = (bool)(dmaStatus & DMA_STATUS_FM_WRITE_ECC); -+ } -+} -+ -+void FM_Resume(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ struct fman_fpm_regs *fpm_rg; -+ -+ SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ fpm_rg = p_Fm->p_FmFpmRegs; -+ -+ fman_resume(fpm_rg); -+} -+ -+t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm, -+ fmSpecialOperations_t spOper, -+ uint8_t *p_SpOperCoding) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ t_FmCtrlCodeRevisionInfo revInfo; -+ t_Error err; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_SpOperCoding, E_NULL_POINTER); -+ -+ if (!spOper) -+ { -+ *p_SpOperCoding = 0; -+ return E_OK; -+ } -+ -+ if ((err = FM_GetFmanCtrlCodeRevision(p_Fm, &revInfo)) != E_OK) -+ { -+ DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision.")); -+ revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER; -+ } -+ else if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package")); -+ -+ switch (spOper) -+ { -+ case (FM_SP_OP_CAPWAP_DTLS_DEC): -+ *p_SpOperCoding = 9; -+ break; -+ case (FM_SP_OP_CAPWAP_DTLS_ENC): -+ *p_SpOperCoding = 10; -+ break; -+ case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP): -+ case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD): -+ *p_SpOperCoding = 5; -+ break; -+ case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP): -+ case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD): -+ *p_SpOperCoding = 6; -+ break; -+ case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_RPD): -+ *p_SpOperCoding = 3; -+ break; -+ case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN): -+ *p_SpOperCoding = 1; -+ break; -+ case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_NO_ETH_HDR): -+ *p_SpOperCoding = 12; -+ break; -+ case (FM_SP_OP_IPSEC|FM_SP_OP_RPD): -+ *p_SpOperCoding = 4; -+ break; -+ case (FM_SP_OP_IPSEC): -+ *p_SpOperCoding = 2; -+ break; -+ case (FM_SP_OP_DCL4C): -+ *p_SpOperCoding = 7; -+ break; -+ case (FM_SP_OP_CLEAR_RPD): -+ *p_SpOperCoding = 8; -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ } -+ -+ return E_OK; -+} -+ -+t_Error FM_CtrlMonStart(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ t_FmTrbRegs *p_MonRegs; -+ uint8_t i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, -+ GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_RDBG); -+ -+ for (i = 0; i < FM_NUM_OF_CTRL; i++) -+ { -+ p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i)); -+ -+ /* Reset control registers */ -+ WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_RESET); -+ WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET); -+ -+ /* Configure: counter #1 counts all stalls in risc - ldsched stall -+ counter #2 counts all stalls in risc - other stall*/ -+ WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET | TRB_TCRL_UTIL); -+ -+ /* Enable monitoring */ -+ WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_ENABLE_COUNTERS); -+ } -+ -+ return E_OK; -+} -+ -+t_Error FM_CtrlMonStop(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ t_FmTrbRegs *p_MonRegs; -+ uint8_t i; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ -+ for (i = 0; i < FM_NUM_OF_CTRL; i++) -+ { -+ p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i)); -+ WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_DISABLE_COUNTERS); -+ } -+ -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, -+ GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_RDBG); -+ -+ return E_OK; -+} -+ -+t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_Fm; -+ t_FmTrbRegs *p_MonRegs; -+ uint64_t clkCnt, utilValue, effValue; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED); -+ SANITY_CHECK_RETURN_ERROR(p_Mon, E_NULL_POINTER); -+ -+ if (fmCtrlIndex >= FM_NUM_OF_CTRL) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM Controller index")); -+ -+ p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(fmCtrlIndex)); -+ -+ clkCnt = (uint64_t) -+ ((uint64_t)GET_UINT32(p_MonRegs->tpcch) << 32 | GET_UINT32(p_MonRegs->tpccl)); -+ -+ utilValue = (uint64_t) -+ ((uint64_t)GET_UINT32(p_MonRegs->tpc1h) << 32 | GET_UINT32(p_MonRegs->tpc1l)); -+ -+ effValue = (uint64_t) -+ ((uint64_t)GET_UINT32(p_MonRegs->tpc2h) << 32 | GET_UINT32(p_MonRegs->tpc2l)); -+ -+ p_Mon->percentCnt[0] = (uint8_t)div64_u64((clkCnt - utilValue) * 100, clkCnt); -+ if (clkCnt != utilValue) -+ p_Mon->percentCnt[1] = (uint8_t)div64_u64(((clkCnt - utilValue) - effValue) * 100, clkCnt - utilValue); -+ else -+ p_Mon->percentCnt[1] = 0; -+ -+ return E_OK; -+} -+ -+t_Handle FM_GetMuramHandle(t_Handle h_Fm) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ -+ SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL); -+ -+ return (p_Fm->h_FmMuram); -+} -+ -+/****************************************************/ -+/* Hidden-DEBUG Only API */ -+/****************************************************/ -+t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception) -+{ -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ enum fman_exceptions fslException; -+ struct fman_rg fman_rg; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE); -+ -+ fman_rg.bmi_rg = p_Fm->p_FmBmiRegs; -+ fman_rg.qmi_rg = p_Fm->p_FmQmiRegs; -+ fman_rg.fpm_rg = p_Fm->p_FmFpmRegs; -+ fman_rg.dma_rg = p_Fm->p_FmDmaRegs; -+ -+ switch (exception) -+ { -+ case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: -+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ break; -+ case e_FM_EX_QMI_SINGLE_ECC: -+ if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC not supported on this integration.")); -+ -+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ break; -+ case e_FM_EX_QMI_DOUBLE_ECC: -+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ break; -+ case e_FM_EX_BMI_LIST_RAM_ECC: -+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ break; -+ case e_FM_EX_BMI_STORAGE_PROFILE_ECC: -+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ break; -+ case e_FM_EX_BMI_STATISTICS_RAM_ECC: -+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ break; -+ case e_FM_EX_BMI_DISPATCH_RAM_ECC: -+ if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC)) -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked")); -+ break; -+ default: -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced")); -+ } -+ -+ fslException = FmanExceptionTrans(exception); -+ fman_force_intr (&fman_rg, fslException); -+ -+ return E_OK; -+} -+ -+t_Handle FmGetPcd(t_Handle h_Fm) -+{ -+ return ((t_Fm*)h_Fm)->h_Pcd; -+} -+#if (DPAA_VERSION >= 11) -+extern void *g_MemacRegs; -+void fm_clk_down(void); -+uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask); -+void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId) -+{ -+ int macId; -+ uint32_t event, rcr; -+ t_Fm *p_Fm = (t_Fm*)h_Fm; -+ rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr); -+ rcr |= 0x04000000; -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr); -+ -+ HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId); -+ do -+ { -+ event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF); -+ } while ((event & 0x00000020) == 0); -+ fm_clk_down(); -+ rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr); -+ rcr &= ~0x04000000; -+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr); -+} -+#endif ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h -@@ -0,0 +1,648 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm.h -+ -+ @Description FM internal structures and definitions. -+*//***************************************************************************/ -+#ifndef __FM_H -+#define __FM_H -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "fm_ext.h" -+#include "fm_ipc.h" -+ -+#include "fsl_fman.h" -+ -+#define __ERR_MODULE__ MODULE_FM -+ -+#define FM_MAX_NUM_OF_HW_PORT_IDS 64 -+#define FM_MAX_NUM_OF_GUESTS 100 -+ -+/**************************************************************************//** -+ @Description Exceptions -+*//***************************************************************************/ -+#define FM_EX_DMA_BUS_ERROR 0x80000000 /**< DMA bus error. */ -+#define FM_EX_DMA_READ_ECC 0x40000000 -+#define FM_EX_DMA_SYSTEM_WRITE_ECC 0x20000000 -+#define FM_EX_DMA_FM_WRITE_ECC 0x10000000 -+#define FM_EX_FPM_STALL_ON_TASKS 0x08000000 /**< Stall of tasks on FPM */ -+#define FM_EX_FPM_SINGLE_ECC 0x04000000 /**< Single ECC on FPM */ -+#define FM_EX_FPM_DOUBLE_ECC 0x02000000 -+#define FM_EX_QMI_SINGLE_ECC 0x01000000 /**< Single ECC on FPM */ -+#define FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 /**< Dequeu from default queue id */ -+#define FM_EX_QMI_DOUBLE_ECC 0x00400000 -+#define FM_EX_BMI_LIST_RAM_ECC 0x00200000 -+#define FM_EX_BMI_STORAGE_PROFILE_ECC 0x00100000 -+#define FM_EX_BMI_STATISTICS_RAM_ECC 0x00080000 -+#define FM_EX_IRAM_ECC 0x00040000 -+#define FM_EX_MURAM_ECC 0x00020000 -+#define FM_EX_BMI_DISPATCH_RAM_ECC 0x00010000 -+#define FM_EX_DMA_SINGLE_PORT_ECC 0x00008000 -+ -+#define DMA_EMSR_EMSTR_MASK 0x0000FFFF -+ -+#define DMA_THRESH_COMMQ_MASK 0xFF000000 -+#define DMA_THRESH_READ_INT_BUF_MASK 0x007F0000 -+#define DMA_THRESH_WRITE_INT_BUF_MASK 0x0000007F -+ -+#define GET_EXCEPTION_FLAG(bitMask, exception) \ -+switch (exception){ \ -+ case e_FM_EX_DMA_BUS_ERROR: \ -+ bitMask = FM_EX_DMA_BUS_ERROR; break; \ -+ case e_FM_EX_DMA_SINGLE_PORT_ECC: \ -+ bitMask = FM_EX_DMA_SINGLE_PORT_ECC; break; \ -+ case e_FM_EX_DMA_READ_ECC: \ -+ bitMask = FM_EX_DMA_READ_ECC; break; \ -+ case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \ -+ bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \ -+ case e_FM_EX_DMA_FM_WRITE_ECC: \ -+ bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \ -+ case e_FM_EX_FPM_STALL_ON_TASKS: \ -+ bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \ -+ case e_FM_EX_FPM_SINGLE_ECC: \ -+ bitMask = FM_EX_FPM_SINGLE_ECC; break; \ -+ case e_FM_EX_FPM_DOUBLE_ECC: \ -+ bitMask = FM_EX_FPM_DOUBLE_ECC; break; \ -+ case e_FM_EX_QMI_SINGLE_ECC: \ -+ bitMask = FM_EX_QMI_SINGLE_ECC; break; \ -+ case e_FM_EX_QMI_DOUBLE_ECC: \ -+ bitMask = FM_EX_QMI_DOUBLE_ECC; break; \ -+ case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \ -+ bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \ -+ case e_FM_EX_BMI_LIST_RAM_ECC: \ -+ bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \ -+ case e_FM_EX_BMI_STORAGE_PROFILE_ECC: \ -+ bitMask = FM_EX_BMI_STORAGE_PROFILE_ECC; break; \ -+ case e_FM_EX_BMI_STATISTICS_RAM_ECC: \ -+ bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \ -+ case e_FM_EX_BMI_DISPATCH_RAM_ECC: \ -+ bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \ -+ case e_FM_EX_IRAM_ECC: \ -+ bitMask = FM_EX_IRAM_ECC; break; \ -+ case e_FM_EX_MURAM_ECC: \ -+ bitMask = FM_EX_MURAM_ECC; break; \ -+ default: bitMask = 0;break; \ -+} -+ -+#define GET_FM_MODULE_EVENT(_mod, _id, _intrType, _event) \ -+ switch (_mod) { \ -+ case e_FM_MOD_PRS: \ -+ if (_id) _event = e_FM_EV_DUMMY_LAST; \ -+ else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \ -+ break; \ -+ case e_FM_MOD_KG: \ -+ if (_id) _event = e_FM_EV_DUMMY_LAST; \ -+ else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \ -+ break; \ -+ case e_FM_MOD_PLCR: \ -+ if (_id) _event = e_FM_EV_DUMMY_LAST; \ -+ else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \ -+ break; \ -+ case e_FM_MOD_TMR: \ -+ if (_id) _event = e_FM_EV_DUMMY_LAST; \ -+ else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \ -+ break; \ -+ case e_FM_MOD_10G_MAC: \ -+ if (_id >= FM_MAX_NUM_OF_10G_MACS) _event = e_FM_EV_DUMMY_LAST; \ -+ else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_10G_MAC0 + _id) : (e_FM_EV_10G_MAC0 + _id); \ -+ break; \ -+ case e_FM_MOD_1G_MAC: \ -+ if (_id >= FM_MAX_NUM_OF_1G_MACS) _event = e_FM_EV_DUMMY_LAST; \ -+ else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_1G_MAC0 + _id) : (e_FM_EV_1G_MAC0 + _id); \ -+ break; \ -+ case e_FM_MOD_MACSEC: \ -+ switch (_id){ \ -+ case (0): _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_MACSEC_MAC0:e_FM_EV_MACSEC_MAC0; \ -+ break; \ -+ } \ -+ break; \ -+ case e_FM_MOD_FMAN_CTRL: \ -+ if (_intrType == e_FM_INTR_TYPE_ERR) _event = e_FM_EV_DUMMY_LAST; \ -+ else _event = (e_FM_EV_FMAN_CTRL_0 + _id); \ -+ break; \ -+ default: _event = e_FM_EV_DUMMY_LAST; \ -+ break; \ -+ } -+ -+#define FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, _cache_override) \ -+ switch (_cache_override){ \ -+ case e_FM_DMA_NO_CACHE_OR: \ -+ fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \ -+ case e_FM_DMA_NO_STASH_DATA: \ -+ fsl_cache_override = E_FMAN_DMA_NO_STASH_DATA; break; \ -+ case e_FM_DMA_MAY_STASH_DATA: \ -+ fsl_cache_override = E_FMAN_DMA_MAY_STASH_DATA; break; \ -+ case e_FM_DMA_STASH_DATA: \ -+ fsl_cache_override = E_FMAN_DMA_STASH_DATA; break; \ -+ default: \ -+ fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \ -+ } -+ -+#define FMAN_AID_MODE_TRANS(fsl_aid_mode, _aid_mode) \ -+ switch (_aid_mode){ \ -+ case e_FM_DMA_AID_OUT_PORT_ID: \ -+ fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \ -+ case e_FM_DMA_AID_OUT_TNUM: \ -+ fsl_aid_mode = E_FMAN_DMA_AID_OUT_TNUM; break; \ -+ default: \ -+ fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \ -+ } -+ -+#define FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, _dma_dbg_cnt) \ -+ switch (_dma_dbg_cnt){ \ -+ case e_FM_DMA_DBG_NO_CNT: \ -+ fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \ -+ case e_FM_DMA_DBG_CNT_DONE: \ -+ fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_DONE; break; \ -+ case e_FM_DMA_DBG_CNT_COMM_Q_EM: \ -+ fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_COMM_Q_EM; break; \ -+ case e_FM_DMA_DBG_CNT_INT_READ_EM: \ -+ fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_READ_EM; break; \ -+ case e_FM_DMA_DBG_CNT_INT_WRITE_EM: \ -+ fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_WRITE_EM ; break; \ -+ case e_FM_DMA_DBG_CNT_FPM_WAIT: \ -+ fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_FPM_WAIT ; break; \ -+ case e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC: \ -+ fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC ; break; \ -+ case e_FM_DMA_DBG_CNT_RAW_WAR_PROT: \ -+ fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT ; break; \ -+ default: \ -+ fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \ -+ } -+ -+#define FMAN_DMA_EMER_TRANS(fsl_dma_emer, _dma_emer) \ -+ switch (_dma_emer){ \ -+ case e_FM_DMA_EM_EBS: \ -+ fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \ -+ case e_FM_DMA_EM_SOS: \ -+ fsl_dma_emer = E_FMAN_DMA_EM_SOS; break; \ -+ default: \ -+ fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \ -+ } -+ -+#define FMAN_DMA_ERR_TRANS(fsl_dma_err, _dma_err) \ -+ switch (_dma_err){ \ -+ case e_FM_DMA_ERR_CATASTROPHIC: \ -+ fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \ -+ case e_FM_DMA_ERR_REPORT: \ -+ fsl_dma_err = E_FMAN_DMA_ERR_REPORT; break; \ -+ default: \ -+ fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \ -+ } -+ -+#define FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, _catastrophic_err) \ -+ switch (_catastrophic_err){ \ -+ case e_FM_CATASTROPHIC_ERR_STALL_PORT: \ -+ fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \ -+ case e_FM_CATASTROPHIC_ERR_STALL_TASK: \ -+ fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_TASK; break; \ -+ default: \ -+ fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \ -+ } -+ -+#define FMAN_COUNTERS_TRANS(fsl_counters, _counters) \ -+ switch (_counters){ \ -+ case e_FM_COUNTERS_ENQ_TOTAL_FRAME: \ -+ fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \ -+ case e_FM_COUNTERS_DEQ_TOTAL_FRAME: \ -+ fsl_counters = E_FMAN_COUNTERS_DEQ_TOTAL_FRAME; break; \ -+ case e_FM_COUNTERS_DEQ_0: \ -+ fsl_counters = E_FMAN_COUNTERS_DEQ_0; break; \ -+ case e_FM_COUNTERS_DEQ_1: \ -+ fsl_counters = E_FMAN_COUNTERS_DEQ_1; break; \ -+ case e_FM_COUNTERS_DEQ_2: \ -+ fsl_counters = E_FMAN_COUNTERS_DEQ_2; break; \ -+ case e_FM_COUNTERS_DEQ_3: \ -+ fsl_counters = E_FMAN_COUNTERS_DEQ_3; break; \ -+ case e_FM_COUNTERS_DEQ_FROM_DEFAULT: \ -+ fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_DEFAULT; break; \ -+ case e_FM_COUNTERS_DEQ_FROM_CONTEXT: \ -+ fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_CONTEXT; break; \ -+ case e_FM_COUNTERS_DEQ_FROM_FD: \ -+ fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_FD; break; \ -+ case e_FM_COUNTERS_DEQ_CONFIRM: \ -+ fsl_counters = E_FMAN_COUNTERS_DEQ_CONFIRM; break; \ -+ default: \ -+ fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \ -+ } -+ -+/**************************************************************************//** -+ @Description defaults -+*//***************************************************************************/ -+#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\ -+ FM_EX_DMA_READ_ECC |\ -+ FM_EX_DMA_SYSTEM_WRITE_ECC |\ -+ FM_EX_DMA_FM_WRITE_ECC |\ -+ FM_EX_FPM_STALL_ON_TASKS |\ -+ FM_EX_FPM_SINGLE_ECC |\ -+ FM_EX_FPM_DOUBLE_ECC |\ -+ FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID|\ -+ FM_EX_BMI_LIST_RAM_ECC |\ -+ FM_EX_BMI_STORAGE_PROFILE_ECC |\ -+ FM_EX_BMI_STATISTICS_RAM_ECC |\ -+ FM_EX_IRAM_ECC |\ -+ FM_EX_MURAM_ECC |\ -+ FM_EX_BMI_DISPATCH_RAM_ECC |\ -+ FM_EX_QMI_DOUBLE_ECC |\ -+ FM_EX_QMI_SINGLE_ECC) -+ -+#define DEFAULT_eccEnable FALSE -+#ifdef FM_PEDANTIC_DMA -+#define DEFAULT_aidOverride TRUE -+#else -+#define DEFAULT_aidOverride FALSE -+#endif /* FM_PEDANTIC_DMA */ -+#define DEFAULT_aidMode e_FM_DMA_AID_OUT_TNUM -+#define DEFAULT_dmaStopOnBusError FALSE -+#define DEFAULT_stopAtBusError FALSE -+#define DEFAULT_axiDbgNumOfBeats 1 -+#define DEFAULT_dmaReadIntBufLow ((DMA_THRESH_MAX_BUF+1)/2) -+#define DEFAULT_dmaReadIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4) -+#define DEFAULT_dmaWriteIntBufLow ((DMA_THRESH_MAX_BUF+1)/2) -+#define DEFAULT_dmaWriteIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4) -+#define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT -+#define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC -+#define DEFAULT_resetOnInit FALSE -+#define DEFAULT_resetOnInitOverrideCallback NULL -+#define DEFAULT_haltOnExternalActivation FALSE /* do not change! if changed, must be disabled for rev1 ! */ -+#define DEFAULT_haltOnUnrecoverableEccError FALSE /* do not change! if changed, must be disabled for rev1 ! */ -+#define DEFAULT_externalEccRamsEnable FALSE -+#define DEFAULT_VerifyUcode FALSE -+ -+#if (DPAA_VERSION < 11) -+#define DEFAULT_totalFifoSize(major, minor) \ -+ (((major == 2) || (major == 5)) ? \ -+ (100*KILOBYTE) : ((major == 4) ? \ -+ (49*KILOBYTE) : (122*KILOBYTE))) -+#define DEFAULT_totalNumOfTasks(major, minor) \ -+ BMI_MAX_NUM_OF_TASKS -+ -+#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2) -+#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4) -+#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR -+#define DEFAULT_dmaCamNumOfEntries 32 -+#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT -+#define DEFAULT_dmaEnEmergency FALSE -+#define DEFAULT_dmaSosEmergency 0 -+#define DEFAULT_dmaWatchdog 0 /* disabled */ -+#define DEFAULT_dmaEnEmergencySmoother FALSE -+#define DEFAULT_dmaEmergencySwitchCounter 0 -+ -+#define DEFAULT_dispLimit 0 -+#define DEFAULT_prsDispTh 16 -+#define DEFAULT_plcrDispTh 16 -+#define DEFAULT_kgDispTh 16 -+#define DEFAULT_bmiDispTh 16 -+#define DEFAULT_qmiEnqDispTh 16 -+#define DEFAULT_qmiDeqDispTh 16 -+#define DEFAULT_fmCtl1DispTh 16 -+#define DEFAULT_fmCtl2DispTh 16 -+ -+#else /* (DPAA_VERSION < 11) */ -+/* Defaults are registers' reset values */ -+#define DEFAULT_totalFifoSize(major, minor) \ -+ (((major == 6) && ((minor == 1) || (minor == 4))) ? \ -+ (156*KILOBYTE) : (295*KILOBYTE)) -+ -+/* According to the default value of FMBM_CFG2[TNTSKS] */ -+#define DEFAULT_totalNumOfTasks(major, minor) \ -+ (((major == 6) && ((minor == 1) || (minor == 4))) ? 59 : 124) -+ -+#define DEFAULT_dmaCommQLow 0x2A -+#define DEFAULT_dmaCommQHigh 0x3F -+#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR -+#define DEFAULT_dmaCamNumOfEntries 64 -+#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT -+#define DEFAULT_dmaEnEmergency FALSE -+#define DEFAULT_dmaSosEmergency 0 -+#define DEFAULT_dmaWatchdog 0 /* disabled */ -+#define DEFAULT_dmaEnEmergencySmoother FALSE -+#define DEFAULT_dmaEmergencySwitchCounter 0 -+ -+#define DEFAULT_dispLimit 0 -+#define DEFAULT_prsDispTh 16 -+#define DEFAULT_plcrDispTh 16 -+#define DEFAULT_kgDispTh 16 -+#define DEFAULT_bmiDispTh 16 -+#define DEFAULT_qmiEnqDispTh 16 -+#define DEFAULT_qmiDeqDispTh 16 -+#define DEFAULT_fmCtl1DispTh 16 -+#define DEFAULT_fmCtl2DispTh 16 -+#endif /* (DPAA_VERSION < 11) */ -+ -+#define FM_TIMESTAMP_1_USEC_BIT 8 -+ -+/**************************************************************************//** -+ @Collection Defines used for enabling/disabling FM interrupts -+ @{ -+*//***************************************************************************/ -+#define ERR_INTR_EN_DMA 0x00010000 -+#define ERR_INTR_EN_FPM 0x80000000 -+#define ERR_INTR_EN_BMI 0x00800000 -+#define ERR_INTR_EN_QMI 0x00400000 -+#define ERR_INTR_EN_PRS 0x00200000 -+#define ERR_INTR_EN_KG 0x00100000 -+#define ERR_INTR_EN_PLCR 0x00080000 -+#define ERR_INTR_EN_MURAM 0x00040000 -+#define ERR_INTR_EN_IRAM 0x00020000 -+#define ERR_INTR_EN_10G_MAC0 0x00008000 -+#define ERR_INTR_EN_10G_MAC1 0x00000040 -+#define ERR_INTR_EN_1G_MAC0 0x00004000 -+#define ERR_INTR_EN_1G_MAC1 0x00002000 -+#define ERR_INTR_EN_1G_MAC2 0x00001000 -+#define ERR_INTR_EN_1G_MAC3 0x00000800 -+#define ERR_INTR_EN_1G_MAC4 0x00000400 -+#define ERR_INTR_EN_1G_MAC5 0x00000200 -+#define ERR_INTR_EN_1G_MAC6 0x00000100 -+#define ERR_INTR_EN_1G_MAC7 0x00000080 -+#define ERR_INTR_EN_MACSEC_MAC0 0x00000001 -+ -+#define INTR_EN_QMI 0x40000000 -+#define INTR_EN_PRS 0x20000000 -+#define INTR_EN_WAKEUP 0x10000000 -+#define INTR_EN_PLCR 0x08000000 -+#define INTR_EN_1G_MAC0 0x00080000 -+#define INTR_EN_1G_MAC1 0x00040000 -+#define INTR_EN_1G_MAC2 0x00020000 -+#define INTR_EN_1G_MAC3 0x00010000 -+#define INTR_EN_1G_MAC4 0x00000040 -+#define INTR_EN_1G_MAC5 0x00000020 -+#define INTR_EN_1G_MAC6 0x00000008 -+#define INTR_EN_1G_MAC7 0x00000002 -+#define INTR_EN_10G_MAC0 0x00200000 -+#define INTR_EN_10G_MAC1 0x00100000 -+#define INTR_EN_REV0 0x00008000 -+#define INTR_EN_REV1 0x00004000 -+#define INTR_EN_REV2 0x00002000 -+#define INTR_EN_REV3 0x00001000 -+#define INTR_EN_BRK 0x00000080 -+#define INTR_EN_TMR 0x01000000 -+#define INTR_EN_MACSEC_MAC0 0x00000001 -+/* @} */ -+ -+/**************************************************************************//** -+ @Description Memory Mapped Registers -+*//***************************************************************************/ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+typedef struct -+{ -+ volatile uint32_t iadd; /**< FM IRAM instruction address register */ -+ volatile uint32_t idata; /**< FM IRAM instruction data register */ -+ volatile uint32_t itcfg; /**< FM IRAM timing config register */ -+ volatile uint32_t iready; /**< FM IRAM ready register */ -+ volatile uint32_t res[0x1FFFC]; -+} t_FMIramRegs; -+ -+/* Trace buffer registers - -+ each FM Controller has its own trace buffer residing at FM_MM_TRB(fmCtrlIndex) offset */ -+typedef struct t_FmTrbRegs -+{ -+ volatile uint32_t tcrh; -+ volatile uint32_t tcrl; -+ volatile uint32_t tesr; -+ volatile uint32_t tecr0h; -+ volatile uint32_t tecr0l; -+ volatile uint32_t terf0h; -+ volatile uint32_t terf0l; -+ volatile uint32_t tecr1h; -+ volatile uint32_t tecr1l; -+ volatile uint32_t terf1h; -+ volatile uint32_t terf1l; -+ volatile uint32_t tpcch; -+ volatile uint32_t tpccl; -+ volatile uint32_t tpc1h; -+ volatile uint32_t tpc1l; -+ volatile uint32_t tpc2h; -+ volatile uint32_t tpc2l; -+ volatile uint32_t twdimr; -+ volatile uint32_t twicvr; -+ volatile uint32_t tar; -+ volatile uint32_t tdr; -+ volatile uint32_t tsnum1; -+ volatile uint32_t tsnum2; -+ volatile uint32_t tsnum3; -+ volatile uint32_t tsnum4; -+} t_FmTrbRegs; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+/**************************************************************************//** -+ @Description General defines -+*//***************************************************************************/ -+#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL -+#define FM_FW_DEBUG_INSTRUCTION 0x6ffff805UL -+ -+/**************************************************************************//** -+ @Description FPM defines -+*//***************************************************************************/ -+/* masks */ -+#define FPM_BRKC_RDBG 0x00000200 -+#define FPM_BRKC_SLP 0x00000800 -+/**************************************************************************//** -+ @Description BMI defines -+*//***************************************************************************/ -+/* masks */ -+#define BMI_INIT_START 0x80000000 -+#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000 -+#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000 -+#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000 -+#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000 -+/**************************************************************************//** -+ @Description QMI defines -+*//***************************************************************************/ -+/* masks */ -+#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000 -+#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000 -+#define QMI_INTR_EN_SINGLE_ECC 0x80000000 -+ -+/**************************************************************************//** -+ @Description IRAM defines -+*//***************************************************************************/ -+/* masks */ -+#define IRAM_IADD_AIE 0x80000000 -+#define IRAM_READY 0x80000000 -+ -+/**************************************************************************//** -+ @Description TRB defines -+*//***************************************************************************/ -+/* masks */ -+#define TRB_TCRH_RESET 0x04000000 -+#define TRB_TCRH_ENABLE_COUNTERS 0x84008000 -+#define TRB_TCRH_DISABLE_COUNTERS 0x8400C000 -+#define TRB_TCRL_RESET 0x20000000 -+#define TRB_TCRL_UTIL 0x00000460 -+typedef struct { -+ void (*f_Isr) (t_Handle h_Arg, uint32_t event); -+ t_Handle h_SrcHandle; -+} t_FmanCtrlIntrSrc; -+ -+ -+typedef void (t_FmanCtrlIsr)( t_Handle h_Fm, uint32_t event); -+ -+typedef struct -+{ -+/***************************/ -+/* Master/Guest parameters */ -+/***************************/ -+ uint8_t fmId; -+ e_FmPortType portsTypes[FM_MAX_NUM_OF_HW_PORT_IDS]; -+ uint16_t fmClkFreq; -+ uint16_t fmMacClkFreq; -+ t_FmRevisionInfo revInfo; -+/**************************/ -+/* Master Only parameters */ -+/**************************/ -+ bool enabledTimeStamp; -+ uint8_t count1MicroBit; -+ uint8_t totalNumOfTasks; -+ uint32_t totalFifoSize; -+ uint8_t maxNumOfOpenDmas; -+ uint8_t accumulatedNumOfTasks; -+ uint32_t accumulatedFifoSize; -+ uint8_t accumulatedNumOfOpenDmas; -+ uint8_t accumulatedNumOfDeqTnums; -+#ifdef FM_LOW_END_RESTRICTION -+ bool lowEndRestriction; -+#endif /* FM_LOW_END_RESTRICTION */ -+ uint32_t exceptions; -+ int irq; -+ int errIrq; -+ bool ramsEccEnable; -+ bool explicitEnable; -+ bool internalCall; -+ uint8_t ramsEccOwners; -+ uint32_t extraFifoPoolSize; -+ uint8_t extraTasksPoolSize; -+ uint8_t extraOpenDmasPoolSize; -+#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS) -+ uint16_t portMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS]; -+ uint16_t macMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS]; -+#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */ -+ uint16_t portMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS]; -+ uint16_t macMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS]; -+} t_FmStateStruct; -+ -+#if (DPAA_VERSION >= 11) -+typedef struct t_FmMapParam { -+ uint16_t profilesBase; -+ uint16_t numOfProfiles; -+ t_Handle h_FmPort; -+} t_FmMapParam; -+ -+typedef struct t_FmAllocMng { -+ bool allocated; -+ uint8_t ownerId; /* guestId for KG in multi-partition only, -+ portId for PLCR in any environment */ -+} t_FmAllocMng; -+ -+typedef struct t_FmPcdSpEntry { -+ bool valid; -+ t_FmAllocMng profilesMng; -+} t_FmPcdSpEntry; -+ -+typedef struct t_FmSp { -+ void *p_FmPcdStoragePrflRegs; -+ t_FmPcdSpEntry profiles[FM_VSP_MAX_NUM_OF_ENTRIES]; -+ t_FmMapParam portsMapping[FM_MAX_NUM_OF_PORTS]; -+} t_FmSp; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+typedef struct t_Fm -+{ -+/***************************/ -+/* Master/Guest parameters */ -+/***************************/ -+/* locals for recovery */ -+ uintptr_t baseAddr; -+ -+/* un-needed for recovery */ -+ t_Handle h_Pcd; -+ char fmModuleName[MODULE_NAME_SIZE]; -+ char fmIpcHandlerModuleName[FM_MAX_NUM_OF_GUESTS][MODULE_NAME_SIZE]; -+ t_Handle h_IpcSessions[FM_MAX_NUM_OF_GUESTS]; -+ t_FmIntrSrc intrMng[e_FM_EV_DUMMY_LAST]; /* FM exceptions user callback */ -+ uint8_t guestId; -+/**************************/ -+/* Master Only parameters */ -+/**************************/ -+/* locals for recovery */ -+ struct fman_fpm_regs *p_FmFpmRegs; -+ struct fman_bmi_regs *p_FmBmiRegs; -+ struct fman_qmi_regs *p_FmQmiRegs; -+ struct fman_dma_regs *p_FmDmaRegs; -+ struct fman_regs *p_FmRegs; -+ t_FmExceptionsCallback *f_Exception; -+ t_FmBusErrorCallback *f_BusError; -+ t_Handle h_App; /* Application handle */ -+ t_Handle h_Spinlock; -+ bool recoveryMode; -+ t_FmStateStruct *p_FmStateStruct; -+ uint16_t tnumAgingPeriod; -+#if (DPAA_VERSION >= 11) -+ t_FmSp *p_FmSp; -+ uint8_t partNumOfVSPs; -+ uint8_t partVSPBase; -+ uintptr_t vspBaseAddr; -+#endif /* (DPAA_VERSION >= 11) */ -+ bool portsPreFetchConfigured[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */ -+ bool portsPreFetchValue[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */ -+ -+/* un-needed for recovery */ -+ struct fman_cfg *p_FmDriverParam; -+ t_Handle h_FmMuram; -+ uint64_t fmMuramPhysBaseAddr; -+ bool independentMode; -+ bool hcPortInitialized; -+ uintptr_t camBaseAddr; /* save for freeing */ -+ uintptr_t resAddr; -+ uintptr_t fifoBaseAddr; /* save for freeing */ -+ t_FmanCtrlIntrSrc fmanCtrlIntr[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; /* FM exceptions user callback */ -+ bool usedEventRegs[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; -+ t_FmFirmwareParams firmware; -+ bool fwVerify; -+ bool resetOnInit; -+ t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride; -+ uint32_t userSetExceptions; -+} t_Fm; -+ -+ -+#endif /* __FM_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h -@@ -0,0 +1,465 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File fm_ipc.h -+ -+ @Description FM Inter-Partition prototypes, structures and definitions. -+*//***************************************************************************/ -+#ifndef __FM_IPC_H -+#define __FM_IPC_H -+ -+#include "error_ext.h" -+#include "std_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group FM_grp Frame Manager API -+ -+ @Description FM API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_IPC_grp FM Inter-Partition messaging Unit -+ -+ @Description FM Inter-Partition messaging unit API definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+/**************************************************************************//** -+ @Description enum for defining MAC types -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description A structure of parameters for specifying a MAC. -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ uint8_t id; -+ uint32_t enumType; -+} _PackedType t_FmIpcMacParams; -+ -+/**************************************************************************//** -+ @Description A structure of parameters for specifying a MAC. -+*//***************************************************************************/ -+typedef _Packed struct -+{ -+ t_FmIpcMacParams macParams; -+ uint16_t maxFrameLength; -+} _PackedType t_FmIpcMacMaxFrameParams; -+ -+/**************************************************************************//** -+ @Description FM physical Address -+*//***************************************************************************/ -+typedef _Packed struct t_FmIpcPhysAddr -+{ -+ volatile uint8_t high; -+ volatile uint32_t low; -+} _PackedType t_FmIpcPhysAddr; -+ -+ -+typedef _Packed struct t_FmIpcPortOutInitParams { -+ uint8_t numOfTasks; /**< OUT */ -+ uint8_t numOfExtraTasks; /**< OUT */ -+ uint8_t numOfOpenDmas; /**< OUT */ -+ uint8_t numOfExtraOpenDmas; /**< OUT */ -+ uint32_t sizeOfFifo; /**< OUT */ -+ uint32_t extraSizeOfFifo; /**< OUT */ -+ t_FmIpcPhysAddr ipcPhysAddr; /**< OUT */ -+} _PackedType t_FmIpcPortOutInitParams; -+ -+/**************************************************************************//** -+ @Description Structure for IPC communication during FM_PORT_Init. -+*//***************************************************************************/ -+typedef _Packed struct t_FmIpcPortInInitParams { -+ uint8_t hardwarePortId; /**< IN. port Id */ -+ uint32_t enumPortType; /**< IN. Port type */ -+ uint8_t boolIndependentMode;/**< IN. TRUE if FM Port operates in independent mode */ -+ uint16_t liodnOffset; /**< IN. Port's requested resource */ -+ uint8_t numOfTasks; /**< IN. Port's requested resource */ -+ uint8_t numOfExtraTasks; /**< IN. Port's requested resource */ -+ uint8_t numOfOpenDmas; /**< IN. Port's requested resource */ -+ uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */ -+ uint32_t sizeOfFifo; /**< IN. Port's requested resource */ -+ uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */ -+ uint8_t deqPipelineDepth; /**< IN. Port's requested resource */ -+ uint16_t maxFrameLength; /**< IN. Port's max frame length. */ -+ uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1. -+ LIODN base for this port, to be -+ used together with LIODN offset. */ -+} _PackedType t_FmIpcPortInInitParams; -+ -+ -+/**************************************************************************//** -+ @Description Structure for IPC communication between port and FM -+ regarding tasks and open DMA resources management. -+*//***************************************************************************/ -+typedef _Packed struct t_FmIpcPortRsrcParams { -+ uint8_t hardwarePortId; /**< IN. port Id */ -+ uint32_t val; /**< IN. Port's requested resource */ -+ uint32_t extra; /**< IN. Port's requested resource */ -+ uint8_t boolInitialConfig; -+} _PackedType t_FmIpcPortRsrcParams; -+ -+ -+/**************************************************************************//** -+ @Description Structure for IPC communication between port and FM -+ regarding tasks and open DMA resources management. -+*//***************************************************************************/ -+typedef _Packed struct t_FmIpcPortFifoParams { -+ t_FmIpcPortRsrcParams rsrcParams; -+ uint32_t enumPortType; -+ uint8_t boolIndependentMode; -+ uint8_t deqPipelineDepth; -+ uint8_t numOfPools; -+ uint16_t secondLargestBufSize; -+ uint16_t largestBufSize; -+ uint8_t boolInitialConfig; -+} _PackedType t_FmIpcPortFifoParams; -+ -+/**************************************************************************//** -+ @Description Structure for port-FM communication during FM_PORT_Free. -+*//***************************************************************************/ -+typedef _Packed struct t_FmIpcPortFreeParams { -+ uint8_t hardwarePortId; /**< IN. port Id */ -+ uint32_t enumPortType; /**< IN. Port type */ -+ uint8_t deqPipelineDepth; /**< IN. Port's requested resource */ -+} _PackedType t_FmIpcPortFreeParams; -+ -+/**************************************************************************//** -+ @Description Structure for defining DMA status -+*//***************************************************************************/ -+typedef _Packed struct t_FmIpcDmaStatus { -+ uint8_t boolCmqNotEmpty; /**< Command queue is not empty */ -+ uint8_t boolBusError; /**< Bus error occurred */ -+ uint8_t boolReadBufEccError; /**< Double ECC error on buffer Read */ -+ uint8_t boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */ -+ uint8_t boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */ -+ uint8_t boolSinglePortEccError; /**< Single port ECC error from FM side */ -+} _PackedType t_FmIpcDmaStatus; -+ -+typedef _Packed struct t_FmIpcRegisterIntr -+{ -+ uint8_t guestId; /* IN */ -+ uint32_t event; /* IN */ -+} _PackedType t_FmIpcRegisterIntr; -+ -+typedef _Packed struct t_FmIpcIsr -+{ -+ uint8_t boolErr; /* IN */ -+ uint32_t pendingReg; /* IN */ -+} _PackedType t_FmIpcIsr; -+ -+/**************************************************************************//** -+ @Description structure for returning FM parameters -+*//***************************************************************************/ -+typedef _Packed struct t_FmIpcParams { -+ uint16_t fmClkFreq; /**< OUT: FM Clock frequency */ -+ uint16_t fmMacClkFreq; /**< OUT: FM MAC clock frequence */ -+ uint8_t majorRev; /**< OUT: FM Major revision */ -+ uint8_t minorRev; /**< OUT: FM Minor revision */ -+} _PackedType t_FmIpcParams; -+ -+ -+/**************************************************************************//** -+ @Description structure for returning Fman Ctrl Code revision information -+*//***************************************************************************/ -+typedef _Packed struct t_FmIpcFmanCtrlCodeRevisionInfo { -+ uint16_t packageRev; /**< OUT: Package revision */ -+ uint8_t majorRev; /**< OUT: Major revision */ -+ uint8_t minorRev; /**< OUT: Minor revision */ -+} _PackedType t_FmIpcFmanCtrlCodeRevisionInfo; -+ -+/**************************************************************************//** -+ @Description Structure for defining Fm number of Fman controlers -+*//***************************************************************************/ -+typedef _Packed struct t_FmIpcPortNumOfFmanCtrls { -+ uint8_t hardwarePortId; /**< IN. port Id */ -+ uint8_t numOfFmanCtrls; /**< IN. Port type */ -+ t_FmFmanCtrl orFmanCtrl; /**< IN. fman controller for order restoration*/ -+} t_FmIpcPortNumOfFmanCtrls; -+ -+/**************************************************************************//** -+ @Description structure for setting Fman contriller events -+*//***************************************************************************/ -+typedef _Packed struct t_FmIpcFmanEvents { -+ uint8_t eventRegId; /**< IN: Fman controller event register id */ -+ uint32_t enableEvents; /**< IN/OUT: required enabled events mask */ -+} _PackedType t_FmIpcFmanEvents; -+ -+typedef _Packed struct t_FmIpcResourceAllocParams { -+ uint8_t guestId; -+ uint16_t base; -+ uint16_t num; -+}_PackedType t_FmIpcResourceAllocParams; -+ -+typedef _Packed struct t_FmIpcVspSetPortWindow { -+ uint8_t hardwarePortId; -+ uint8_t baseStorageProfile; -+ uint8_t log2NumOfProfiles; -+}_PackedType t_FmIpcVspSetPortWindow; -+ -+typedef _Packed struct t_FmIpcSetCongestionGroupPfcPriority { -+ uint32_t congestionGroupId; -+ uint8_t priorityBitMap; -+}_PackedType t_FmIpcSetCongestionGroupPfcPriority; -+ -+#define FM_IPC_MAX_REPLY_BODY_SIZE 20 -+#define FM_IPC_MAX_REPLY_SIZE (FM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t)) -+#define FM_IPC_MAX_MSG_SIZE 30 -+ -+typedef _Packed struct t_FmIpcMsg -+{ -+ uint32_t msgId; -+ uint8_t msgBody[FM_IPC_MAX_MSG_SIZE]; -+} _PackedType t_FmIpcMsg; -+ -+typedef _Packed struct t_FmIpcReply -+{ -+ uint32_t error; -+ uint8_t replyBody[FM_IPC_MAX_REPLY_BODY_SIZE]; -+} _PackedType t_FmIpcReply; -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+/***************************************************************************/ -+/************************ FRONT-END-TO-BACK-END*****************************/ -+/***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_GET_TIMESTAMP_SCALE -+ -+ @Description Used by FM front-end. -+ -+ @Param[out] uint32_t Pointer -+*//***************************************************************************/ -+#define FM_GET_TIMESTAMP_SCALE 1 -+ -+/**************************************************************************//** -+ @Function FM_GET_COUNTER -+ -+ @Description Used by FM front-end. -+ -+ @Param[in/out] t_FmIpcGetCounter Pointer -+*//***************************************************************************/ -+#define FM_GET_COUNTER 2 -+ -+/**************************************************************************//** -+ @Function FM_GET_SET_PORT_PARAMS -+ -+ @Description Used by FM front-end for the PORT module in order to set and get -+ parameters in/from master FM module on FM PORT initialization time. -+ -+ @Param[in/out] t_FmIcPortInitParams Pointer -+*//***************************************************************************/ -+#define FM_GET_SET_PORT_PARAMS 4 -+ -+/**************************************************************************//** -+ @Function FM_FREE_PORT -+ -+ @Description Used by FM front-end for the PORT module when a port is freed -+ to free all FM PORT resources. -+ -+ @Param[in] uint8_t Pointer -+*//***************************************************************************/ -+#define FM_FREE_PORT 5 -+ -+/**************************************************************************//** -+ @Function FM_RESET_MAC -+ -+ @Description Used by front-end for the MAC module to reset the MAC registers -+ -+ @Param[in] t_FmIpcMacParams Pointer . -+*//***************************************************************************/ -+#define FM_RESET_MAC 6 -+ -+/**************************************************************************//** -+ @Function FM_RESUME_STALLED_PORT -+ -+ @Description Used by FM front-end for the PORT module in order to -+ release a stalled FM Port. -+ -+ @Param[in] uint8_t Pointer -+*//***************************************************************************/ -+#define FM_RESUME_STALLED_PORT 7 -+ -+/**************************************************************************//** -+ @Function FM_IS_PORT_STALLED -+ -+ @Description Used by FM front-end for the PORT module in order to check whether -+ an FM port is stalled. -+ -+ @Param[in/out] t_FmIcPortIsStalled Pointer -+*//***************************************************************************/ -+#define FM_IS_PORT_STALLED 8 -+ -+/**************************************************************************//** -+ @Function FM_GET_PARAMS -+ -+ @Description Used by FM front-end for the PORT module in order to dump -+ return FM parameters. -+ -+ @Param[in] uint8_t Pointer -+*//***************************************************************************/ -+#define FM_GET_PARAMS 10 -+ -+/**************************************************************************//** -+ @Function FM_REGISTER_INTR -+ -+ @Description Used by FM front-end to register an interrupt handler to -+ be called upon interrupt for guest. -+ -+ @Param[out] t_FmIpcRegisterIntr Pointer -+*//***************************************************************************/ -+#define FM_REGISTER_INTR 11 -+ -+/**************************************************************************//** -+ @Function FM_DMA_STAT -+ -+ @Description Used by FM front-end to read the FM DMA status. -+ -+ @Param[out] t_FmIpcDmaStatus Pointer -+*//***************************************************************************/ -+#define FM_DMA_STAT 13 -+ -+/**************************************************************************//** -+ @Function FM_ALLOC_FMAN_CTRL_EVENT_REG -+ -+ @Description Used by FM front-end to allocate event register. -+ -+ @Param[out] Event register id Pointer -+*//***************************************************************************/ -+#define FM_ALLOC_FMAN_CTRL_EVENT_REG 14 -+ -+/**************************************************************************//** -+ @Function FM_FREE_FMAN_CTRL_EVENT_REG -+ -+ @Description Used by FM front-end to free locate event register. -+ -+ @Param[in] uint8_t Pointer - Event register id -+*//***************************************************************************/ -+#define FM_FREE_FMAN_CTRL_EVENT_REG 15 -+ -+/**************************************************************************//** -+ @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE -+ -+ @Description Used by FM front-end to enable events in the FPM -+ Fman controller event register. -+ -+ @Param[in] t_FmIpcFmanEvents Pointer -+*//***************************************************************************/ -+#define FM_SET_FMAN_CTRL_EVENTS_ENABLE 16 -+ -+/**************************************************************************//** -+ @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE -+ -+ @Description Used by FM front-end to enable events in the FPM -+ Fman controller event register. -+ -+ @Param[in/out] t_FmIpcFmanEvents Pointer -+*//***************************************************************************/ -+#define FM_GET_FMAN_CTRL_EVENTS_ENABLE 17 -+ -+/**************************************************************************//** -+ @Function FM_SET_MAC_MAX_FRAME -+ -+ @Description Used by FM front-end to set MAC's MTU/RTU's in -+ back-end. -+ -+ @Param[in/out] t_FmIpcMacMaxFrameParams Pointer -+*//***************************************************************************/ -+#define FM_SET_MAC_MAX_FRAME 18 -+ -+/**************************************************************************//** -+ @Function FM_GET_PHYS_MURAM_BASE -+ -+ @Description Used by FM front-end in order to get MURAM base address -+ -+ @Param[in/out] t_FmIpcPhysAddr Pointer -+*//***************************************************************************/ -+#define FM_GET_PHYS_MURAM_BASE 19 -+ -+/**************************************************************************//** -+ @Function FM_MASTER_IS_ALIVE -+ -+ @Description Used by FM front-end in order to verify Master is up -+ -+ @Param[in/out] bool -+*//***************************************************************************/ -+#define FM_MASTER_IS_ALIVE 20 -+ -+#define FM_ENABLE_RAM_ECC 21 -+#define FM_DISABLE_RAM_ECC 22 -+#define FM_SET_NUM_OF_FMAN_CTRL 23 -+#define FM_SET_SIZE_OF_FIFO 24 -+#define FM_SET_NUM_OF_TASKS 25 -+#define FM_SET_NUM_OF_OPEN_DMAS 26 -+#define FM_VSP_ALLOC 27 -+#define FM_VSP_FREE 28 -+#define FM_VSP_SET_PORT_WINDOW 29 -+#define FM_GET_FMAN_CTRL_CODE_REV 30 -+#define FM_SET_CONG_GRP_PFC_PRIO 31 -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+#define FM_10G_TX_ECC_WA 100 -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ -+/***************************************************************************/ -+/************************ BACK-END-TO-FRONT-END*****************************/ -+/***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_GUEST_ISR -+ -+ @Description Used by FM back-end to report an interrupt to the front-end. -+ -+ @Param[out] t_FmIpcIsr Pointer -+*//***************************************************************************/ -+#define FM_GUEST_ISR 1 -+ -+ -+ -+/** @} */ /* end of FM_IPC_grp group */ -+/** @} */ /* end of FM_grp group */ -+ -+ -+#endif /* __FM_IPC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c -@@ -0,0 +1,174 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File FM_muram.c -+ -+ @Description FM MURAM ... -+*//***************************************************************************/ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "mm_ext.h" -+#include "string_ext.h" -+#include "sprint_ext.h" -+#include "fm_muram_ext.h" -+#include "fm_common.h" -+ -+#define __ERR_MODULE__ MODULE_FM_MURAM -+ -+ -+typedef struct -+{ -+ t_Handle h_Mem; -+ uintptr_t baseAddr; -+ uint32_t size; -+} t_FmMuram; -+ -+ -+void FmMuramClear(t_Handle h_FmMuram) -+{ -+ t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram; -+ -+ SANITY_CHECK_RETURN(h_FmMuram, E_INVALID_HANDLE); -+ IOMemSet32(UINT_TO_PTR(p_FmMuram->baseAddr), 0, p_FmMuram->size); -+} -+ -+ -+t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size) -+{ -+ t_Handle h_Mem; -+ t_FmMuram *p_FmMuram; -+ -+ if (!baseAddress) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress 0 is not supported")); -+ return NULL; -+ } -+ -+ if (baseAddress%4) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress not 4 bytes aligned!")); -+ return NULL; -+ } -+ -+ /* Allocate FM MURAM structure */ -+ p_FmMuram = (t_FmMuram *) XX_Malloc(sizeof(t_FmMuram)); -+ if (!p_FmMuram) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MURAM driver structure")); -+ return NULL; -+ } -+ memset(p_FmMuram, 0, sizeof(t_FmMuram)); -+ -+ -+ if ((MM_Init(&h_Mem, baseAddress, size) != E_OK) || (!h_Mem)) -+ { -+ XX_Free(p_FmMuram); -+ REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM partition!!!")); -+ return NULL; -+ } -+ -+ /* Initialize FM MURAM parameters which will be kept by the driver */ -+ p_FmMuram->baseAddr = baseAddress; -+ p_FmMuram->size = size; -+ p_FmMuram->h_Mem = h_Mem; -+ -+ return p_FmMuram; -+} -+ -+t_Error FM_MURAM_Free(t_Handle h_FmMuram) -+{ -+ t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram; -+ -+ if (p_FmMuram->h_Mem) -+ MM_Free(p_FmMuram->h_Mem); -+ -+ XX_Free(h_FmMuram); -+ -+ return E_OK; -+} -+ -+void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align) -+{ -+ t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram; -+ uintptr_t addr; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL); -+ -+ addr = (uintptr_t)MM_Get(p_FmMuram->h_Mem, size, align ,"FM MURAM"); -+ -+ if (addr == ILLEGAL_BASE) -+ return NULL; -+ -+ return UINT_TO_PTR(addr); -+} -+ -+void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size) -+{ -+ t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram; -+ uintptr_t addr; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL); -+ SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL); -+ -+ addr = (uintptr_t)MM_GetForce(p_FmMuram->h_Mem, base, size, "FM MURAM"); -+ -+ if (addr == ILLEGAL_BASE) -+ return NULL; -+ -+ return UINT_TO_PTR(addr); -+} -+ -+t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr) -+{ -+ t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram; -+ -+ SANITY_CHECK_RETURN_ERROR(h_FmMuram, E_INVALID_HANDLE); -+ SANITY_CHECK_RETURN_ERROR(p_FmMuram->h_Mem, E_INVALID_HANDLE); -+ -+ if (MM_Put(p_FmMuram->h_Mem, PTR_TO_UINT(ptr)) == 0) -+ RETURN_ERROR(MINOR, E_INVALID_ADDRESS, ("memory pointer!!!")); -+ -+ return E_OK; -+} -+ -+uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram) -+{ -+ t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram; -+ -+ SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, 0); -+ SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, 0); -+ -+ return MM_GetFreeMemSize(p_FmMuram->h_Mem); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c -@@ -0,0 +1,1398 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#include -+#include "fsl_fman.h" -+#include "dpaa_integration_ext.h" -+ -+uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg) -+{ -+ uint32_t event, mask, force; -+ -+ event = ioread32be(&bmi_rg->fmbm_ievr); -+ mask = ioread32be(&bmi_rg->fmbm_ier); -+ event &= mask; -+ /* clear the forced events */ -+ force = ioread32be(&bmi_rg->fmbm_ifr); -+ if (force & event) -+ iowrite32be(force & ~event, &bmi_rg->fmbm_ifr); -+ /* clear the acknowledged events */ -+ iowrite32be(event, &bmi_rg->fmbm_ievr); -+ return event; -+} -+ -+uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg) -+{ -+ uint32_t event, mask, force; -+ -+ event = ioread32be(&qmi_rg->fmqm_eie); -+ mask = ioread32be(&qmi_rg->fmqm_eien); -+ event &= mask; -+ -+ /* clear the forced events */ -+ force = ioread32be(&qmi_rg->fmqm_eif); -+ if (force & event) -+ iowrite32be(force & ~event, &qmi_rg->fmqm_eif); -+ /* clear the acknowledged events */ -+ iowrite32be(event, &qmi_rg->fmqm_eie); -+ return event; -+} -+ -+uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg) -+{ -+ return ioread32be(&dma_rg->fmdmtcid); -+} -+ -+uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg) -+{ -+ uint64_t addr; -+ -+ addr = (uint64_t)ioread32be(&dma_rg->fmdmtal); -+ addr |= ((uint64_t)(ioread32be(&dma_rg->fmdmtah)) << 32); -+ -+ return addr; -+} -+ -+uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg) -+{ -+ uint32_t status, mask; -+ -+ status = ioread32be(&dma_rg->fmdmsr); -+ mask = ioread32be(&dma_rg->fmdmmr); -+ -+ /* clear DMA_STATUS_BUS_ERR if mask has no DMA_MODE_BER */ -+ if ((mask & DMA_MODE_BER) != DMA_MODE_BER) -+ status &= ~DMA_STATUS_BUS_ERR; -+ -+ /* clear relevant bits if mask has no DMA_MODE_ECC */ -+ if ((mask & DMA_MODE_ECC) != DMA_MODE_ECC) -+ status &= ~(DMA_STATUS_FM_SPDAT_ECC | -+ DMA_STATUS_READ_ECC | -+ DMA_STATUS_SYSTEM_WRITE_ECC | -+ DMA_STATUS_FM_WRITE_ECC); -+ -+ /* clear set events */ -+ iowrite32be(status, &dma_rg->fmdmsr); -+ -+ return status; -+} -+ -+uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg) -+{ -+ uint32_t event; -+ -+ event = ioread32be(&fpm_rg->fmfp_ee); -+ /* clear the all occurred events */ -+ iowrite32be(event, &fpm_rg->fmfp_ee); -+ return event; -+} -+ -+uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg) -+{ -+ uint32_t event, mask; -+ -+ event = ioread32be(&fpm_rg->fm_rcr); -+ mask = ioread32be(&fpm_rg->fm_rie); -+ -+ /* clear MURAM event bit (do not clear IRAM event) */ -+ iowrite32be(event & ~FPM_RAM_IRAM_ECC, &fpm_rg->fm_rcr); -+ -+ if ((mask & FPM_MURAM_ECC_ERR_EX_EN)) -+ return event; -+ else -+ return 0; -+} -+ -+uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg) -+{ -+ uint32_t event, mask; -+ -+ event = ioread32be(&fpm_rg->fm_rcr) ; -+ mask = ioread32be(&fpm_rg->fm_rie); -+ /* clear IRAM event bit (do not clear MURAM event) */ -+ iowrite32be(event & ~FPM_RAM_MURAM_ECC, -+ &fpm_rg->fm_rcr); -+ -+ if ((mask & FPM_IRAM_ECC_ERR_EX_EN)) -+ return event; -+ else -+ return 0; -+} -+ -+uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg) -+{ -+ uint32_t event, mask, force; -+ -+ event = ioread32be(&qmi_rg->fmqm_ie); -+ mask = ioread32be(&qmi_rg->fmqm_ien); -+ event &= mask; -+ /* clear the forced events */ -+ force = ioread32be(&qmi_rg->fmqm_if); -+ if (force & event) -+ iowrite32be(force & ~event, &qmi_rg->fmqm_if); -+ /* clear the acknowledged events */ -+ iowrite32be(event, &qmi_rg->fmqm_ie); -+ return event; -+} -+ -+void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg, -+ uint8_t count1ubit, -+ uint16_t fm_clk_freq) -+{ -+ uint32_t tmp; -+ uint64_t frac; -+ uint32_t intgr; -+ uint32_t ts_freq = (uint32_t)(1 << count1ubit); /* in Mhz */ -+ -+ /* configure timestamp so that bit 8 will count 1 microsecond -+ * Find effective count rate at TIMESTAMP least significant bits: -+ * Effective_Count_Rate = 1MHz x 2^8 = 256MHz -+ * Find frequency ratio between effective count rate and the clock: -+ * Effective_Count_Rate / CLK e.g. for 600 MHz clock: -+ * 256/600 = 0.4266666... */ -+ -+ intgr = ts_freq / fm_clk_freq; -+ /* we multiply by 2^16 to keep the fraction of the division -+ * we do not div back, since we write this value as a fraction -+ * see spec */ -+ -+ frac = ((uint64_t)ts_freq << 16) - ((uint64_t)intgr << 16) * fm_clk_freq; -+ /* we check remainder of the division in order to round up if not int */ -+ if (do_div(frac, fm_clk_freq)) -+ frac++; -+ -+ tmp = (intgr << FPM_TS_INT_SHIFT) | (uint16_t)frac; -+ iowrite32be(tmp, &fpm_rg->fmfp_tsc2); -+ -+ /* enable timestamp with original clock */ -+ iowrite32be(FPM_TS_CTL_EN, &fpm_rg->fmfp_tsc1); -+} -+ -+uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg) -+{ -+ return ioread32be(&fpm_rg->fm_epi); -+} -+ -+ -+int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg) -+{ -+ int timeout = 100; -+ -+ iowrite32be(0x40000000, &fpm_rg->fmfp_extc); -+ -+ while ((ioread32be(&fpm_rg->fmfp_extc) & 0x40000000) && --timeout) -+ udelay(10); -+ -+ if (!timeout) -+ return -EBUSY; -+ return 0; -+} -+ -+void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, -+ uint8_t event_reg_id, -+ uint32_t enable_events) -+{ -+ iowrite32be(enable_events, &fpm_rg->fmfp_cee[event_reg_id]); -+} -+ -+uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id) -+{ -+ return ioread32be(&fpm_rg->fmfp_cee[event_reg_id]); -+} -+ -+void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg, -+ uint8_t port_id, -+ uint8_t num_fman_ctrls, -+ uint32_t or_fman_ctrl) -+{ -+ uint32_t tmp = 0; -+ -+ tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT); -+ /*TODO - maybe to put CTL# according to another criteria*/ -+ if (num_fman_ctrls == 2) -+ tmp = FPM_PRT_FM_CTL2 | FPM_PRT_FM_CTL1; -+ /* order restoration */ -+ tmp |= (or_fman_ctrl << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | or_fman_ctrl; -+ -+ iowrite32be(tmp, &fpm_rg->fmfp_prc); -+} -+ -+void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg, -+ uint8_t port_id, -+ bool independent_mode, -+ bool is_rx_port) -+{ -+ uint32_t tmp = 0; -+ -+ tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT); -+ if (independent_mode) { -+ if (is_rx_port) -+ tmp |= (FPM_PRT_FM_CTL1 << -+ FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL1; -+ else -+ tmp |= (FPM_PRT_FM_CTL2 << -+ FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL2; -+ } else { -+ tmp |= (FPM_PRT_FM_CTL2|FPM_PRT_FM_CTL1); -+ -+ /* order restoration */ -+ if (port_id % 2) -+ tmp |= (FPM_PRT_FM_CTL1 << -+ FPM_PRC_ORA_FM_CTL_SEL_SHIFT); -+ else -+ tmp |= (FPM_PRT_FM_CTL2 << -+ FPM_PRC_ORA_FM_CTL_SEL_SHIFT); -+ } -+ iowrite32be(tmp, &fpm_rg->fmfp_prc); -+} -+ -+uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg) -+{ -+ return (uint8_t)ioread32be(&qmi_rg->fmqm_gc); -+} -+ -+uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg) -+{ -+ return (uint8_t)(ioread32be(&qmi_rg->fmqm_gc) >> 8); -+} -+ -+void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val) -+{ -+ uint32_t tmp_reg; -+ -+ tmp_reg = ioread32be(&qmi_rg->fmqm_gc); -+ tmp_reg &= ~QMI_CFG_ENQ_MASK; -+ tmp_reg |= ((uint32_t)val << 8); -+ iowrite32be(tmp_reg, &qmi_rg->fmqm_gc); -+} -+ -+void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val) -+{ -+ uint32_t tmp_reg; -+ -+ tmp_reg = ioread32be(&qmi_rg->fmqm_gc); -+ tmp_reg &= ~QMI_CFG_DEQ_MASK; -+ tmp_reg |= (uint32_t)val; -+ iowrite32be(tmp_reg, &qmi_rg->fmqm_gc); -+} -+ -+void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg) -+{ -+ iowrite32be(0, &fpm_rg->fmfp_mxd); -+} -+ -+void fman_set_liodn_per_port(struct fman_rg *fman_rg, uint8_t port_id, -+ uint16_t liodn_base, -+ uint16_t liodn_ofst) -+{ -+ uint32_t tmp; -+ -+ if ((port_id > 63) || (port_id < 1)) -+ return; -+ -+ /* set LIODN base for this port */ -+ tmp = ioread32be(&fman_rg->dma_rg->fmdmplr[port_id / 2]); -+ if (port_id % 2) { -+ tmp &= ~FM_LIODN_BASE_MASK; -+ tmp |= (uint32_t)liodn_base; -+ } else { -+ tmp &= ~(FM_LIODN_BASE_MASK << DMA_LIODN_SHIFT); -+ tmp |= (uint32_t)liodn_base << DMA_LIODN_SHIFT; -+ } -+ iowrite32be(tmp, &fman_rg->dma_rg->fmdmplr[port_id / 2]); -+ iowrite32be((uint32_t)liodn_ofst, -+ &fman_rg->bmi_rg->fmbm_spliodn[port_id - 1]); -+} -+ -+bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id) -+{ -+ return (bool)!!(ioread32be(&fpm_rg->fmfp_ps[port_id]) & FPM_PS_STALLED); -+} -+ -+void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id) -+{ -+ uint32_t tmp; -+ -+ tmp = (uint32_t)((port_id << FPM_PORT_FM_CTL_PORTID_SHIFT) | -+ FPM_PRC_REALSE_STALLED); -+ iowrite32be(tmp, &fpm_rg->fmfp_prc); -+} -+ -+int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t mac_id, bool is_10g) -+{ -+ uint32_t msk, timeout = 100; -+ -+ /* Get the relevant bit mask */ -+ if (is_10g) { -+ switch (mac_id) { -+ case(0): -+ msk = FPM_RSTC_10G0_RESET; -+ break; -+ case(1): -+ msk = FPM_RSTC_10G1_RESET; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } else { -+ switch (mac_id) { -+ case(0): -+ msk = FPM_RSTC_1G0_RESET; -+ break; -+ case(1): -+ msk = FPM_RSTC_1G1_RESET; -+ break; -+ case(2): -+ msk = FPM_RSTC_1G2_RESET; -+ break; -+ case(3): -+ msk = FPM_RSTC_1G3_RESET; -+ break; -+ case(4): -+ msk = FPM_RSTC_1G4_RESET; -+ break; -+ case (5): -+ msk = FPM_RSTC_1G5_RESET; -+ break; -+ case (6): -+ msk = FPM_RSTC_1G6_RESET; -+ break; -+ case (7): -+ msk = FPM_RSTC_1G7_RESET; -+ break; -+ default: -+ return -EINVAL; -+ } -+ } -+ /* reset */ -+ iowrite32be(msk, &fpm_rg->fm_rstc); -+ while ((ioread32be(&fpm_rg->fm_rstc) & msk) && --timeout) -+ udelay(10); -+ -+ if (!timeout) -+ return -EBUSY; -+ return 0; -+} -+ -+uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id) -+{ -+ uint32_t tmp_reg; -+ -+ if ((port_id > 63) || (port_id < 1)) -+ return 0; -+ -+ tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id - 1]); -+ return (uint16_t)((tmp_reg & BMI_FIFO_SIZE_MASK) + 1); -+} -+ -+uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg) -+{ -+ uint32_t reg, res; -+ -+ reg = ioread32be(&bmi_rg->fmbm_cfg1); -+ res = (reg >> BMI_CFG1_FIFO_SIZE_SHIFT) & 0x3ff; -+ return res * FMAN_BMI_FIFO_UNITS; -+} -+ -+uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id) -+{ -+ uint32_t tmp_reg; -+ -+ if ((port_id > 63) || (port_id < 1)) -+ return 0; -+ -+ tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id-1]); -+ return (uint16_t)((tmp_reg & BMI_EXTRA_FIFO_SIZE_MASK) >> -+ BMI_EXTRA_FIFO_SIZE_SHIFT); -+} -+ -+void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id, -+ uint32_t sz_fifo, -+ uint32_t extra_sz_fifo) -+{ -+ uint32_t tmp; -+ -+ if ((port_id > 63) || (port_id < 1)) -+ return; -+ -+ /* calculate reg */ -+ tmp = (uint32_t)((sz_fifo / FMAN_BMI_FIFO_UNITS - 1) | -+ ((extra_sz_fifo / FMAN_BMI_FIFO_UNITS) << -+ BMI_EXTRA_FIFO_SIZE_SHIFT)); -+ iowrite32be(tmp, &bmi_rg->fmbm_pfs[port_id - 1]); -+} -+ -+uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id) -+{ -+ uint32_t tmp; -+ -+ if ((port_id > 63) || (port_id < 1)) -+ return 0; -+ -+ tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]); -+ return (uint8_t)(((tmp & BMI_NUM_OF_TASKS_MASK) >> -+ BMI_NUM_OF_TASKS_SHIFT) + 1); -+} -+ -+uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id) -+{ -+ uint32_t tmp; -+ -+ if ((port_id > 63) || (port_id < 1)) -+ return 0; -+ -+ tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]); -+ return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_TASKS_MASK) >> -+ BMI_EXTRA_NUM_OF_TASKS_SHIFT); -+} -+ -+void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id, -+ uint8_t num_tasks, -+ uint8_t num_extra_tasks) -+{ -+ uint32_t tmp; -+ -+ if ((port_id > 63) || (port_id < 1)) -+ return; -+ -+ /* calculate reg */ -+ tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) & -+ ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK); -+ tmp |= (uint32_t)(((num_tasks - 1) << BMI_NUM_OF_TASKS_SHIFT) | -+ (num_extra_tasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT)); -+ iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]); -+} -+ -+uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id) -+{ -+ uint32_t tmp; -+ -+ if ((port_id > 63) || (port_id < 1)) -+ return 0; -+ -+ tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]); -+ return (uint8_t)(((tmp & BMI_NUM_OF_DMAS_MASK) >> -+ BMI_NUM_OF_DMAS_SHIFT) + 1); -+} -+ -+uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id) -+{ -+ uint32_t tmp; -+ -+ if ((port_id > 63) || (port_id < 1)) -+ return 0; -+ -+ tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]); -+ return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_DMAS_MASK) >> -+ BMI_EXTRA_NUM_OF_DMAS_SHIFT); -+} -+ -+void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id, -+ uint8_t num_open_dmas, -+ uint8_t num_extra_open_dmas, -+ uint8_t total_num_dmas) -+{ -+ uint32_t tmp = 0; -+ -+ if ((port_id > 63) || (port_id < 1)) -+ return; -+ -+ /* calculate reg */ -+ tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) & -+ ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK); -+ tmp |= (uint32_t)(((num_open_dmas-1) << BMI_NUM_OF_DMAS_SHIFT) | -+ (num_extra_open_dmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT)); -+ iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]); -+ -+ /* update total num of DMA's with committed number of open DMAS, -+ * and max uncommitted pool. */ -+ if (total_num_dmas) -+ { -+ tmp = ioread32be(&bmi_rg->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK; -+ tmp |= (uint32_t)(total_num_dmas - 1) << BMI_CFG2_DMAS_SHIFT; -+ iowrite32be(tmp, &bmi_rg->fmbm_cfg2); -+ } -+} -+ -+void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id, -+ uint8_t base_storage_profile, -+ uint8_t log2_num_of_profiles) -+{ -+ uint32_t tmp = 0; -+ if ((port_id > 63) || (port_id < 1)) -+ return; -+ -+ tmp = ioread32be(&bmi_rg->fmbm_spliodn[port_id-1]); -+ tmp |= (uint32_t)((uint32_t)base_storage_profile & 0x3f) << 16; -+ tmp |= (uint32_t)log2_num_of_profiles << 28; -+ iowrite32be(tmp, &bmi_rg->fmbm_spliodn[port_id-1]); -+} -+ -+void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg, -+ uint32_t congestion_group_id, -+ uint8_t priority_bit_map, -+ uint32_t reg_num) -+{ -+ uint32_t offset, tmp = 0; -+ -+ offset = (congestion_group_id%4)*8; -+ -+ tmp = ioread32be(&cpg_rg[reg_num]); -+ tmp &= ~(0xFF<catastrophic_err = DEFAULT_CATASTROPHIC_ERR; -+ cfg->dma_err = DEFAULT_DMA_ERR; -+ cfg->halt_on_external_activ = DEFAULT_HALT_ON_EXTERNAL_ACTIVATION; -+ cfg->halt_on_unrecov_ecc_err = DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR; -+ cfg->en_iram_test_mode = FALSE; -+ cfg->en_muram_test_mode = FALSE; -+ cfg->external_ecc_rams_enable = DEFAULT_EXTERNAL_ECC_RAMS_ENABLE; -+ -+ if (!is_master) -+ return; -+ -+ cfg->dma_aid_override = DEFAULT_AID_OVERRIDE; -+ cfg->dma_aid_mode = DEFAULT_AID_MODE; -+ cfg->dma_comm_qtsh_clr_emer = DEFAULT_DMA_COMM_Q_LOW; -+ cfg->dma_comm_qtsh_asrt_emer = DEFAULT_DMA_COMM_Q_HIGH; -+ cfg->dma_cache_override = DEFAULT_CACHE_OVERRIDE; -+ cfg->dma_cam_num_of_entries = DEFAULT_DMA_CAM_NUM_OF_ENTRIES; -+ cfg->dma_dbg_cnt_mode = DEFAULT_DMA_DBG_CNT_MODE; -+ cfg->dma_en_emergency = DEFAULT_DMA_EN_EMERGENCY; -+ cfg->dma_sos_emergency = DEFAULT_DMA_SOS_EMERGENCY; -+ cfg->dma_watchdog = DEFAULT_DMA_WATCHDOG; -+ cfg->dma_en_emergency_smoother = DEFAULT_DMA_EN_EMERGENCY_SMOOTHER; -+ cfg->dma_emergency_switch_counter = DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER; -+ cfg->disp_limit_tsh = DEFAULT_DISP_LIMIT; -+ cfg->prs_disp_tsh = DEFAULT_PRS_DISP_TH; -+ cfg->plcr_disp_tsh = DEFAULT_PLCR_DISP_TH; -+ cfg->kg_disp_tsh = DEFAULT_KG_DISP_TH; -+ cfg->bmi_disp_tsh = DEFAULT_BMI_DISP_TH; -+ cfg->qmi_enq_disp_tsh = DEFAULT_QMI_ENQ_DISP_TH; -+ cfg->qmi_deq_disp_tsh = DEFAULT_QMI_DEQ_DISP_TH; -+ cfg->fm_ctl1_disp_tsh = DEFAULT_FM_CTL1_DISP_TH; -+ cfg->fm_ctl2_disp_tsh = DEFAULT_FM_CTL2_DISP_TH; -+ -+ cfg->pedantic_dma = FALSE; -+ cfg->tnum_aging_period = DEFAULT_TNUM_AGING_PERIOD; -+ cfg->dma_stop_on_bus_error = FALSE; -+ cfg->qmi_deq_option_support = FALSE; -+} -+ -+void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg) -+{ -+ uint32_t tmp_reg; -+ -+ /* read the values from the registers as they are initialized by the HW with -+ * the required values. -+ */ -+ tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg1); -+ cfg->total_fifo_size = -+ (((tmp_reg & BMI_TOTAL_FIFO_SIZE_MASK) >> BMI_CFG1_FIFO_SIZE_SHIFT) + 1) * FMAN_BMI_FIFO_UNITS; -+ -+ tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg2); -+ cfg->total_num_of_tasks = -+ (uint8_t)(((tmp_reg & BMI_TOTAL_NUM_OF_TASKS_MASK) >> BMI_CFG2_TASKS_SHIFT) + 1); -+ -+ tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmtr); -+ cfg->dma_comm_qtsh_asrt_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT); -+ -+ tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmhy); -+ cfg->dma_comm_qtsh_clr_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT); -+ -+ tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmmr); -+ cfg->dma_cache_override = (enum fman_dma_cache_override)((tmp_reg & DMA_MODE_CACHE_OR_MASK) >> DMA_MODE_CACHE_OR_SHIFT); -+ cfg->dma_cam_num_of_entries = (uint8_t)((((tmp_reg & DMA_MODE_CEN_MASK) >> DMA_MODE_CEN_SHIFT) +1)*DMA_CAM_UNITS); -+ cfg->dma_aid_override = (bool)((tmp_reg & DMA_MODE_AID_OR)? TRUE:FALSE); -+ cfg->dma_dbg_cnt_mode = (enum fman_dma_dbg_cnt_mode)((tmp_reg & DMA_MODE_DBG_MASK) >> DMA_MODE_DBG_SHIFT); -+ cfg->dma_en_emergency = (bool)((tmp_reg & DMA_MODE_EB)? TRUE : FALSE); -+ -+ tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_mxd); -+ cfg->disp_limit_tsh = (uint8_t)((tmp_reg & FPM_DISP_LIMIT_MASK) >> FPM_DISP_LIMIT_SHIFT); -+ -+ tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist1); -+ cfg->prs_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PRS_MASK ) >> FPM_THR1_PRS_SHIFT); -+ cfg->plcr_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_KG_MASK ) >> FPM_THR1_KG_SHIFT); -+ cfg->kg_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PLCR_MASK ) >> FPM_THR1_PLCR_SHIFT); -+ cfg->bmi_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_BMI_MASK ) >> FPM_THR1_BMI_SHIFT); -+ -+ tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist2); -+ cfg->qmi_enq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_ENQ_MASK ) >> FPM_THR2_QMI_ENQ_SHIFT); -+ cfg->qmi_deq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_DEQ_MASK ) >> FPM_THR2_QMI_DEQ_SHIFT); -+ cfg->fm_ctl1_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL1_MASK ) >> FPM_THR2_FM_CTL1_SHIFT); -+ cfg->fm_ctl2_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL2_MASK ) >> FPM_THR2_FM_CTL2_SHIFT); -+ -+ tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmsetr); -+ cfg->dma_sos_emergency = tmp_reg; -+ -+ tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmwcr); -+ cfg->dma_watchdog = tmp_reg/cfg->clk_freq; -+ -+ tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmemsr); -+ cfg->dma_en_emergency_smoother = (bool)((tmp_reg & DMA_EMSR_EMSTR_MASK)? TRUE : FALSE); -+ cfg->dma_emergency_switch_counter = (tmp_reg & DMA_EMSR_EMSTR_MASK); -+} -+ -+void fman_reset(struct fman_fpm_regs *fpm_rg) -+{ -+ iowrite32be(FPM_RSTC_FM_RESET, &fpm_rg->fm_rstc); -+} -+ -+/**************************************************************************//** -+ @Function FM_Init -+ -+ @Description Initializes the FM module -+ -+ @Param[in] h_Fm - FM module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg) -+{ -+ uint32_t tmp_reg; -+ -+ /**********************/ -+ /* Init DMA Registers */ -+ /**********************/ -+ /* clear status reg events */ -+ /* oren - check!!! */ -+ tmp_reg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC | -+ DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC); -+ iowrite32be(ioread32be(&dma_rg->fmdmsr) | tmp_reg, -+ &dma_rg->fmdmsr); -+ -+ /* configure mode register */ -+ tmp_reg = 0; -+ tmp_reg |= cfg->dma_cache_override << DMA_MODE_CACHE_OR_SHIFT; -+ if (cfg->dma_aid_override) -+ tmp_reg |= DMA_MODE_AID_OR; -+ if (cfg->exceptions & FMAN_EX_DMA_BUS_ERROR) -+ tmp_reg |= DMA_MODE_BER; -+ if ((cfg->exceptions & FMAN_EX_DMA_SYSTEM_WRITE_ECC) | -+ (cfg->exceptions & FMAN_EX_DMA_READ_ECC) | -+ (cfg->exceptions & FMAN_EX_DMA_FM_WRITE_ECC)) -+ tmp_reg |= DMA_MODE_ECC; -+ if (cfg->dma_stop_on_bus_error) -+ tmp_reg |= DMA_MODE_SBER; -+ if(cfg->dma_axi_dbg_num_of_beats) -+ tmp_reg |= (uint32_t)(DMA_MODE_AXI_DBG_MASK & -+ ((cfg->dma_axi_dbg_num_of_beats - 1) << DMA_MODE_AXI_DBG_SHIFT)); -+ -+ if (cfg->dma_en_emergency) { -+ tmp_reg |= cfg->dma_emergency_bus_select; -+ tmp_reg |= cfg->dma_emergency_level << DMA_MODE_EMER_LVL_SHIFT; -+ if (cfg->dma_en_emergency_smoother) -+ iowrite32be(cfg->dma_emergency_switch_counter, -+ &dma_rg->fmdmemsr); -+ } -+ tmp_reg |= ((cfg->dma_cam_num_of_entries / DMA_CAM_UNITS) - 1) << -+ DMA_MODE_CEN_SHIFT; -+ tmp_reg |= DMA_MODE_SECURE_PROT; -+ tmp_reg |= cfg->dma_dbg_cnt_mode << DMA_MODE_DBG_SHIFT; -+ tmp_reg |= cfg->dma_aid_mode << DMA_MODE_AID_MODE_SHIFT; -+ -+ if (cfg->pedantic_dma) -+ tmp_reg |= DMA_MODE_EMER_READ; -+ -+ iowrite32be(tmp_reg, &dma_rg->fmdmmr); -+ -+ /* configure thresholds register */ -+ tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_asrt_emer << -+ DMA_THRESH_COMMQ_SHIFT) | -+ ((uint32_t)cfg->dma_read_buf_tsh_asrt_emer << -+ DMA_THRESH_READ_INT_BUF_SHIFT) | -+ ((uint32_t)cfg->dma_write_buf_tsh_asrt_emer); -+ -+ iowrite32be(tmp_reg, &dma_rg->fmdmtr); -+ -+ /* configure hysteresis register */ -+ tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_clr_emer << -+ DMA_THRESH_COMMQ_SHIFT) | -+ ((uint32_t)cfg->dma_read_buf_tsh_clr_emer << -+ DMA_THRESH_READ_INT_BUF_SHIFT) | -+ ((uint32_t)cfg->dma_write_buf_tsh_clr_emer); -+ -+ iowrite32be(tmp_reg, &dma_rg->fmdmhy); -+ -+ /* configure emergency threshold */ -+ iowrite32be(cfg->dma_sos_emergency, &dma_rg->fmdmsetr); -+ -+ /* configure Watchdog */ -+ iowrite32be((cfg->dma_watchdog * cfg->clk_freq), -+ &dma_rg->fmdmwcr); -+ -+ iowrite32be(cfg->cam_base_addr, &dma_rg->fmdmebcr); -+ -+ return 0; -+} -+ -+int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg) -+{ -+ uint32_t tmp_reg; -+ int i; -+ -+ /**********************/ -+ /* Init FPM Registers */ -+ /**********************/ -+ tmp_reg = (uint32_t)(cfg->disp_limit_tsh << FPM_DISP_LIMIT_SHIFT); -+ iowrite32be(tmp_reg, &fpm_rg->fmfp_mxd); -+ -+ tmp_reg = (((uint32_t)cfg->prs_disp_tsh << FPM_THR1_PRS_SHIFT) | -+ ((uint32_t)cfg->kg_disp_tsh << FPM_THR1_KG_SHIFT) | -+ ((uint32_t)cfg->plcr_disp_tsh << FPM_THR1_PLCR_SHIFT) | -+ ((uint32_t)cfg->bmi_disp_tsh << FPM_THR1_BMI_SHIFT)); -+ iowrite32be(tmp_reg, &fpm_rg->fmfp_dist1); -+ -+ tmp_reg = (((uint32_t)cfg->qmi_enq_disp_tsh << FPM_THR2_QMI_ENQ_SHIFT) | -+ ((uint32_t)cfg->qmi_deq_disp_tsh << FPM_THR2_QMI_DEQ_SHIFT) | -+ ((uint32_t)cfg->fm_ctl1_disp_tsh << FPM_THR2_FM_CTL1_SHIFT) | -+ ((uint32_t)cfg->fm_ctl2_disp_tsh << FPM_THR2_FM_CTL2_SHIFT)); -+ iowrite32be(tmp_reg, &fpm_rg->fmfp_dist2); -+ -+ /* define exceptions and error behavior */ -+ tmp_reg = 0; -+ /* Clear events */ -+ tmp_reg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC | -+ FPM_EV_MASK_SINGLE_ECC); -+ /* enable interrupts */ -+ if (cfg->exceptions & FMAN_EX_FPM_STALL_ON_TASKS) -+ tmp_reg |= FPM_EV_MASK_STALL_EN; -+ if (cfg->exceptions & FMAN_EX_FPM_SINGLE_ECC) -+ tmp_reg |= FPM_EV_MASK_SINGLE_ECC_EN; -+ if (cfg->exceptions & FMAN_EX_FPM_DOUBLE_ECC) -+ tmp_reg |= FPM_EV_MASK_DOUBLE_ECC_EN; -+ tmp_reg |= (cfg->catastrophic_err << FPM_EV_MASK_CAT_ERR_SHIFT); -+ tmp_reg |= (cfg->dma_err << FPM_EV_MASK_DMA_ERR_SHIFT); -+ if (!cfg->halt_on_external_activ) -+ tmp_reg |= FPM_EV_MASK_EXTERNAL_HALT; -+ if (!cfg->halt_on_unrecov_ecc_err) -+ tmp_reg |= FPM_EV_MASK_ECC_ERR_HALT; -+ iowrite32be(tmp_reg, &fpm_rg->fmfp_ee); -+ -+ /* clear all fmCtls event registers */ -+ for (i = 0; i < cfg->num_of_fman_ctrl_evnt_regs; i++) -+ iowrite32be(0xFFFFFFFF, &fpm_rg->fmfp_cev[i]); -+ -+ /* RAM ECC - enable and clear events*/ -+ /* first we need to clear all parser memory, -+ * as it is uninitialized and may cause ECC errors */ -+ /* event bits */ -+ tmp_reg = (FPM_RAM_MURAM_ECC | FPM_RAM_IRAM_ECC); -+ /* Rams enable not effected by RCR bit, but by a COP configuration */ -+ if (cfg->external_ecc_rams_enable) -+ tmp_reg |= FPM_RAM_RAMS_ECC_EN_SRC_SEL; -+ -+ /* enable test mode */ -+ if (cfg->en_muram_test_mode) -+ tmp_reg |= FPM_RAM_MURAM_TEST_ECC; -+ if (cfg->en_iram_test_mode) -+ tmp_reg |= FPM_RAM_IRAM_TEST_ECC; -+ iowrite32be(tmp_reg, &fpm_rg->fm_rcr); -+ -+ tmp_reg = 0; -+ if (cfg->exceptions & FMAN_EX_IRAM_ECC) { -+ tmp_reg |= FPM_IRAM_ECC_ERR_EX_EN; -+ fman_enable_rams_ecc(fpm_rg); -+ } -+ if (cfg->exceptions & FMAN_EX_NURAM_ECC) { -+ tmp_reg |= FPM_MURAM_ECC_ERR_EX_EN; -+ fman_enable_rams_ecc(fpm_rg); -+ } -+ iowrite32be(tmp_reg, &fpm_rg->fm_rie); -+ -+ return 0; -+} -+ -+int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg) -+{ -+ uint32_t tmp_reg; -+ -+ /**********************/ -+ /* Init BMI Registers */ -+ /**********************/ -+ -+ /* define common resources */ -+ tmp_reg = cfg->fifo_base_addr; -+ tmp_reg = tmp_reg / BMI_FIFO_ALIGN; -+ -+ tmp_reg |= ((cfg->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) << -+ BMI_CFG1_FIFO_SIZE_SHIFT); -+ iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg1); -+ -+ tmp_reg = ((uint32_t)(cfg->total_num_of_tasks - 1) << -+ BMI_CFG2_TASKS_SHIFT); -+ /* num of DMA's will be dynamically updated when each port is set */ -+ iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg2); -+ -+ /* define unmaskable exceptions, enable and clear events */ -+ tmp_reg = 0; -+ iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC | -+ BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC | -+ BMI_ERR_INTR_EN_STATISTICS_RAM_ECC | -+ BMI_ERR_INTR_EN_DISPATCH_RAM_ECC, -+ &bmi_rg->fmbm_ievr); -+ -+ if (cfg->exceptions & FMAN_EX_BMI_LIST_RAM_ECC) -+ tmp_reg |= BMI_ERR_INTR_EN_LIST_RAM_ECC; -+ if (cfg->exceptions & FMAN_EX_BMI_PIPELINE_ECC) -+ tmp_reg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC; -+ if (cfg->exceptions & FMAN_EX_BMI_STATISTICS_RAM_ECC) -+ tmp_reg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; -+ if (cfg->exceptions & FMAN_EX_BMI_DISPATCH_RAM_ECC) -+ tmp_reg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; -+ iowrite32be(tmp_reg, &bmi_rg->fmbm_ier); -+ -+ return 0; -+} -+ -+int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg) -+{ -+ uint32_t tmp_reg; -+ uint16_t period_in_fm_clocks; -+ uint8_t remainder; -+ /**********************/ -+ /* Init QMI Registers */ -+ /**********************/ -+ /* Clear error interrupt events */ -+ -+ iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF, -+ &qmi_rg->fmqm_eie); -+ tmp_reg = 0; -+ if (cfg->exceptions & FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID) -+ tmp_reg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF; -+ if (cfg->exceptions & FMAN_EX_QMI_DOUBLE_ECC) -+ tmp_reg |= QMI_ERR_INTR_EN_DOUBLE_ECC; -+ /* enable events */ -+ iowrite32be(tmp_reg, &qmi_rg->fmqm_eien); -+ -+ if (cfg->tnum_aging_period) { -+ /* tnum_aging_period is in units of usec, p_FmClockFreq in Mhz */ -+ period_in_fm_clocks = (uint16_t) -+ (cfg->tnum_aging_period * cfg->clk_freq); -+ /* period_in_fm_clocks must be a 64 multiply */ -+ remainder = (uint8_t)(period_in_fm_clocks % 64); -+ if (remainder) -+ tmp_reg = (uint32_t)((period_in_fm_clocks / 64) + 1); -+ else{ -+ tmp_reg = (uint32_t)(period_in_fm_clocks / 64); -+ if (!tmp_reg) -+ tmp_reg = 1; -+ } -+ tmp_reg <<= QMI_TAPC_TAP; -+ iowrite32be(tmp_reg, &qmi_rg->fmqm_tapc); -+ } -+ tmp_reg = 0; -+ /* Clear interrupt events */ -+ iowrite32be(QMI_INTR_EN_SINGLE_ECC, &qmi_rg->fmqm_ie); -+ if (cfg->exceptions & FMAN_EX_QMI_SINGLE_ECC) -+ tmp_reg |= QMI_INTR_EN_SINGLE_ECC; -+ /* enable events */ -+ iowrite32be(tmp_reg, &qmi_rg->fmqm_ien); -+ -+ return 0; -+} -+ -+int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg) -+{ -+ uint32_t cfg_reg = 0; -+ -+ /**********************/ -+ /* Enable all modules */ -+ /**********************/ -+ /* clear & enable global counters - calculate reg and save for later, -+ because it's the same reg for QMI enable */ -+ cfg_reg = QMI_CFG_EN_COUNTERS; -+ if (cfg->qmi_deq_option_support) -+ cfg_reg |= (uint32_t)(((cfg->qmi_def_tnums_thresh) << 8) | -+ (uint32_t)cfg->qmi_def_tnums_thresh); -+ -+ iowrite32be(BMI_INIT_START, &fman_rg->bmi_rg->fmbm_init); -+ iowrite32be(cfg_reg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN, -+ &fman_rg->qmi_rg->fmqm_gc); -+ -+ return 0; -+} -+ -+void fman_free_resources(struct fman_rg *fman_rg) -+{ -+ /* disable BMI and QMI */ -+ iowrite32be(0, &fman_rg->bmi_rg->fmbm_init); -+ iowrite32be(0, &fman_rg->qmi_rg->fmqm_gc); -+ -+ /* release BMI resources */ -+ iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg2); -+ iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg1); -+ -+ /* disable ECC */ -+ iowrite32be(0, &fman_rg->fpm_rg->fm_rcr); -+} -+ -+/****************************************************/ -+/* API Run-time Control uint functions */ -+/****************************************************/ -+uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg) -+{ -+ return ioread32be(&fpm_rg->fm_npi); -+} -+ -+uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, uint8_t reg_id) -+{ -+ uint32_t event; -+ -+ event = ioread32be(&fpm_rg->fmfp_fcev[reg_id]) & -+ ioread32be(&fpm_rg->fmfp_cee[reg_id]); -+ iowrite32be(event, &fpm_rg->fmfp_cev[reg_id]); -+ -+ return event; -+} -+ -+uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg) -+{ -+ return ioread32be(&fpm_rg->fm_epi); -+} -+ -+void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights) -+{ -+ int i; -+ uint8_t shift; -+ uint32_t tmp = 0; -+ -+ for (i = 0; i < 64; i++) { -+ if (weights[i] > 1) { /* no need to write 1 since it is 0 */ -+ /* Add this port to tmp_reg */ -+ /* (each 8 ports result in one register)*/ -+ shift = (uint8_t)(32 - 4 * ((i % 8) + 1)); -+ tmp |= ((weights[i] - 1) << shift); -+ } -+ if (i % 8 == 7) { /* last in this set */ -+ iowrite32be(tmp, &bmi_rg->fmbm_arb[i / 8]); -+ tmp = 0; -+ } -+ } -+} -+ -+void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(&fpm_rg->fm_rcr); -+ if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL) -+ iowrite32be(tmp | FPM_RAM_IRAM_ECC_EN, -+ &fpm_rg->fm_rcr); -+ else -+ iowrite32be(tmp | FPM_RAM_RAMS_ECC_EN | -+ FPM_RAM_IRAM_ECC_EN, -+ &fpm_rg->fm_rcr); -+} -+ -+void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(&fpm_rg->fm_rcr); -+ if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL) -+ iowrite32be(tmp & ~FPM_RAM_IRAM_ECC_EN, -+ &fpm_rg->fm_rcr); -+ else -+ iowrite32be(tmp & ~(FPM_RAM_RAMS_ECC_EN | FPM_RAM_IRAM_ECC_EN), -+ &fpm_rg->fm_rcr); -+} -+ -+int fman_set_exception(struct fman_rg *fman_rg, -+ enum fman_exceptions exception, -+ bool enable) -+{ -+ uint32_t tmp; -+ -+ switch (exception) { -+ case(E_FMAN_EX_DMA_BUS_ERROR): -+ tmp = ioread32be(&fman_rg->dma_rg->fmdmmr); -+ if (enable) -+ tmp |= DMA_MODE_BER; -+ else -+ tmp &= ~DMA_MODE_BER; -+ /* disable bus error */ -+ iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr); -+ break; -+ case(E_FMAN_EX_DMA_READ_ECC): -+ case(E_FMAN_EX_DMA_SYSTEM_WRITE_ECC): -+ case(E_FMAN_EX_DMA_FM_WRITE_ECC): -+ tmp = ioread32be(&fman_rg->dma_rg->fmdmmr); -+ if (enable) -+ tmp |= DMA_MODE_ECC; -+ else -+ tmp &= ~DMA_MODE_ECC; -+ iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr); -+ break; -+ case(E_FMAN_EX_FPM_STALL_ON_TASKS): -+ tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee); -+ if (enable) -+ tmp |= FPM_EV_MASK_STALL_EN; -+ else -+ tmp &= ~FPM_EV_MASK_STALL_EN; -+ iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee); -+ break; -+ case(E_FMAN_EX_FPM_SINGLE_ECC): -+ tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee); -+ if (enable) -+ tmp |= FPM_EV_MASK_SINGLE_ECC_EN; -+ else -+ tmp &= ~FPM_EV_MASK_SINGLE_ECC_EN; -+ iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee); -+ break; -+ case(E_FMAN_EX_FPM_DOUBLE_ECC): -+ tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee); -+ if (enable) -+ tmp |= FPM_EV_MASK_DOUBLE_ECC_EN; -+ else -+ tmp &= ~FPM_EV_MASK_DOUBLE_ECC_EN; -+ iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee); -+ break; -+ case(E_FMAN_EX_QMI_SINGLE_ECC): -+ tmp = ioread32be(&fman_rg->qmi_rg->fmqm_ien); -+ if (enable) -+ tmp |= QMI_INTR_EN_SINGLE_ECC; -+ else -+ tmp &= ~QMI_INTR_EN_SINGLE_ECC; -+ iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_ien); -+ break; -+ case(E_FMAN_EX_QMI_DOUBLE_ECC): -+ tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien); -+ if (enable) -+ tmp |= QMI_ERR_INTR_EN_DOUBLE_ECC; -+ else -+ tmp &= ~QMI_ERR_INTR_EN_DOUBLE_ECC; -+ iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien); -+ break; -+ case(E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID): -+ tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien); -+ if (enable) -+ tmp |= QMI_ERR_INTR_EN_DEQ_FROM_DEF; -+ else -+ tmp &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF; -+ iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien); -+ break; -+ case(E_FMAN_EX_BMI_LIST_RAM_ECC): -+ tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier); -+ if (enable) -+ tmp |= BMI_ERR_INTR_EN_LIST_RAM_ECC; -+ else -+ tmp &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC; -+ iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier); -+ break; -+ case(E_FMAN_EX_BMI_STORAGE_PROFILE_ECC): -+ tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier); -+ if (enable) -+ tmp |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC; -+ else -+ tmp &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC; -+ iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier); -+ break; -+ case(E_FMAN_EX_BMI_STATISTICS_RAM_ECC): -+ tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier); -+ if (enable) -+ tmp |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; -+ else -+ tmp &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC; -+ iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier); -+ break; -+ case(E_FMAN_EX_BMI_DISPATCH_RAM_ECC): -+ tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier); -+ if (enable) -+ tmp |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; -+ else -+ tmp &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC; -+ iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier); -+ break; -+ case(E_FMAN_EX_IRAM_ECC): -+ tmp = ioread32be(&fman_rg->fpm_rg->fm_rie); -+ if (enable) { -+ /* enable ECC if not enabled */ -+ fman_enable_rams_ecc(fman_rg->fpm_rg); -+ /* enable ECC interrupts */ -+ tmp |= FPM_IRAM_ECC_ERR_EX_EN; -+ } else { -+ /* ECC mechanism may be disabled, -+ * depending on driver status */ -+ fman_disable_rams_ecc(fman_rg->fpm_rg); -+ tmp &= ~FPM_IRAM_ECC_ERR_EX_EN; -+ } -+ iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie); -+ break; -+ case(E_FMAN_EX_MURAM_ECC): -+ tmp = ioread32be(&fman_rg->fpm_rg->fm_rie); -+ if (enable) { -+ /* enable ECC if not enabled */ -+ fman_enable_rams_ecc(fman_rg->fpm_rg); -+ /* enable ECC interrupts */ -+ tmp |= FPM_MURAM_ECC_ERR_EX_EN; -+ } else { -+ /* ECC mechanism may be disabled, -+ * depending on driver status */ -+ fman_disable_rams_ecc(fman_rg->fpm_rg); -+ tmp &= ~FPM_MURAM_ECC_ERR_EX_EN; -+ } -+ iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie); -+ break; -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+void fman_get_revision(struct fman_fpm_regs *fpm_rg, -+ uint8_t *major, -+ uint8_t *minor) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(&fpm_rg->fm_ip_rev_1); -+ *major = (uint8_t)((tmp & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT); -+ *minor = (uint8_t)((tmp & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT); -+ -+} -+ -+uint32_t fman_get_counter(struct fman_rg *fman_rg, -+ enum fman_counters reg_name) -+{ -+ uint32_t ret_val; -+ -+ switch (reg_name) { -+ case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME): -+ ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_etfc); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME): -+ ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dtfc); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_0): -+ ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc0); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_1): -+ ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc1); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_2): -+ ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc2); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_3): -+ ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc3); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT): -+ ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfdc); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT): -+ ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfcc); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_FROM_FD): -+ ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dffc); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_CONFIRM): -+ ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dcc); -+ break; -+ default: -+ ret_val = 0; -+ } -+ return ret_val; -+} -+ -+int fman_modify_counter(struct fman_rg *fman_rg, -+ enum fman_counters reg_name, -+ uint32_t val) -+{ -+ /* When applicable (when there is an 'enable counters' bit, -+ * check that counters are enabled */ -+ switch (reg_name) { -+ case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME): -+ case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME): -+ case(E_FMAN_COUNTERS_DEQ_0): -+ case(E_FMAN_COUNTERS_DEQ_1): -+ case(E_FMAN_COUNTERS_DEQ_2): -+ case(E_FMAN_COUNTERS_DEQ_3): -+ case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT): -+ case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT): -+ case(E_FMAN_COUNTERS_DEQ_FROM_FD): -+ case(E_FMAN_COUNTERS_DEQ_CONFIRM): -+ if (!(ioread32be(&fman_rg->qmi_rg->fmqm_gc) & -+ QMI_CFG_EN_COUNTERS)) -+ return -EINVAL; -+ break; -+ default: -+ break; -+ } -+ /* Set counter */ -+ switch (reg_name) { -+ case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME): -+ iowrite32be(val, &fman_rg->qmi_rg->fmqm_etfc); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME): -+ iowrite32be(val, &fman_rg->qmi_rg->fmqm_dtfc); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_0): -+ iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc0); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_1): -+ iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc1); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_2): -+ iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc2); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_3): -+ iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc3); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT): -+ iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfdc); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT): -+ iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfcc); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_FROM_FD): -+ iowrite32be(val, &fman_rg->qmi_rg->fmqm_dffc); -+ break; -+ case(E_FMAN_COUNTERS_DEQ_CONFIRM): -+ iowrite32be(val, &fman_rg->qmi_rg->fmqm_dcc); -+ break; -+ case(E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT): -+ iowrite32be(val, &fman_rg->dma_rg->fmdmsefrc); -+ break; -+ case(E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT): -+ iowrite32be(val, &fman_rg->dma_rg->fmdmsqfrc); -+ break; -+ case(E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT): -+ iowrite32be(val, &fman_rg->dma_rg->fmdmssrc); -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, -+ bool is_write, -+ bool enable) -+{ -+ uint32_t msk; -+ -+ msk = (uint32_t)(is_write ? DMA_MODE_EMER_WRITE : DMA_MODE_EMER_READ); -+ -+ if (enable) -+ iowrite32be(ioread32be(&dma_rg->fmdmmr) | msk, -+ &dma_rg->fmdmmr); -+ else /* disable */ -+ iowrite32be(ioread32be(&dma_rg->fmdmmr) & ~msk, -+ &dma_rg->fmdmmr); -+} -+ -+void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(&dma_rg->fmdmmr) | -+ (pri << DMA_MODE_BUS_PRI_SHIFT); -+ -+ iowrite32be(tmp, &dma_rg->fmdmmr); -+} -+ -+uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg) -+{ -+ return ioread32be(&dma_rg->fmdmsr); -+} -+ -+void fman_force_intr(struct fman_rg *fman_rg, -+ enum fman_exceptions exception) -+{ -+ switch (exception) { -+ case E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: -+ iowrite32be(QMI_ERR_INTR_EN_DEQ_FROM_DEF, -+ &fman_rg->qmi_rg->fmqm_eif); -+ break; -+ case E_FMAN_EX_QMI_SINGLE_ECC: -+ iowrite32be(QMI_INTR_EN_SINGLE_ECC, -+ &fman_rg->qmi_rg->fmqm_if); -+ break; -+ case E_FMAN_EX_QMI_DOUBLE_ECC: -+ iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC, -+ &fman_rg->qmi_rg->fmqm_eif); -+ break; -+ case E_FMAN_EX_BMI_LIST_RAM_ECC: -+ iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC, -+ &fman_rg->bmi_rg->fmbm_ifr); -+ break; -+ case E_FMAN_EX_BMI_STORAGE_PROFILE_ECC: -+ iowrite32be(BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC, -+ &fman_rg->bmi_rg->fmbm_ifr); -+ break; -+ case E_FMAN_EX_BMI_STATISTICS_RAM_ECC: -+ iowrite32be(BMI_ERR_INTR_EN_STATISTICS_RAM_ECC, -+ &fman_rg->bmi_rg->fmbm_ifr); -+ break; -+ case E_FMAN_EX_BMI_DISPATCH_RAM_ECC: -+ iowrite32be(BMI_ERR_INTR_EN_DISPATCH_RAM_ECC, -+ &fman_rg->bmi_rg->fmbm_ifr); -+ break; -+ default: -+ break; -+ } -+} -+ -+bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg) -+{ -+ return (bool)!!(ioread32be(&qmi_rg->fmqm_gs) & QMI_GS_HALT_NOT_BUSY); -+} -+void fman_resume(struct fman_fpm_regs *fpm_rg) -+{ -+ uint32_t tmp; -+ -+ tmp = ioread32be(&fpm_rg->fmfp_ee); -+ /* clear tmp_reg event bits in order not to clear standing events */ -+ tmp &= ~(FPM_EV_MASK_DOUBLE_ECC | -+ FPM_EV_MASK_STALL | -+ FPM_EV_MASK_SINGLE_ECC); -+ tmp |= FPM_EV_MASK_RELEASE_FM; -+ -+ iowrite32be(tmp, &fpm_rg->fmfp_ee); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h -@@ -0,0 +1,1214 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_common.h -+ -+ @Description FM internal structures and definitions. -+*//***************************************************************************/ -+#ifndef __FM_COMMON_H -+#define __FM_COMMON_H -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "fm_pcd_ext.h" -+#include "fm_ext.h" -+#include "fm_port_ext.h" -+ -+ -+#define e_FM_PORT_TYPE_OH_HOST_COMMAND e_FM_PORT_TYPE_DUMMY -+ -+#define CLS_PLAN_NUM_PER_GRP 8 -+ -+#define IP_OFFLOAD_PACKAGE_NUMBER 106 -+#define CAPWAP_OFFLOAD_PACKAGE_NUMBER 108 -+#define IS_OFFLOAD_PACKAGE(num) ((num == IP_OFFLOAD_PACKAGE_NUMBER) || (num == CAPWAP_OFFLOAD_PACKAGE_NUMBER)) -+ -+ -+ -+/**************************************************************************//** -+ @Description Modules registers offsets -+*//***************************************************************************/ -+#define FM_MM_MURAM 0x00000000 -+#define FM_MM_BMI 0x00080000 -+#define FM_MM_QMI 0x00080400 -+#define FM_MM_PRS 0x000c7000 -+#define FM_MM_KG 0x000C1000 -+#define FM_MM_DMA 0x000C2000 -+#define FM_MM_FPM 0x000C3000 -+#define FM_MM_PLCR 0x000C0000 -+#define FM_MM_IMEM 0x000C4000 -+#define FM_MM_CGP 0x000DB000 -+#define FM_MM_TRB(i) (0x000D0200 + 0x400 * (i)) -+#if (DPAA_VERSION >= 11) -+#define FM_MM_SP 0x000dc000 -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ -+/**************************************************************************//** -+ @Description Enum for inter-module interrupts registration -+*//***************************************************************************/ -+typedef enum e_FmEventModules{ -+ e_FM_MOD_PRS, /**< Parser event */ -+ e_FM_MOD_KG, /**< Keygen event */ -+ e_FM_MOD_PLCR, /**< Policer event */ -+ e_FM_MOD_10G_MAC, /**< 10G MAC event */ -+ e_FM_MOD_1G_MAC, /**< 1G MAC event */ -+ e_FM_MOD_TMR, /**< Timer event */ -+ e_FM_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */ -+ e_FM_MOD_MACSEC, -+ e_FM_MOD_DUMMY_LAST -+} e_FmEventModules; -+ -+/**************************************************************************//** -+ @Description Enum for interrupts types -+*//***************************************************************************/ -+typedef enum e_FmIntrType { -+ e_FM_INTR_TYPE_ERR, -+ e_FM_INTR_TYPE_NORMAL -+} e_FmIntrType; -+ -+/**************************************************************************//** -+ @Description Enum for inter-module interrupts registration -+*//***************************************************************************/ -+typedef enum e_FmInterModuleEvent -+{ -+ e_FM_EV_PRS = 0, /**< Parser event */ -+ e_FM_EV_ERR_PRS, /**< Parser error event */ -+ e_FM_EV_KG, /**< Keygen event */ -+ e_FM_EV_ERR_KG, /**< Keygen error event */ -+ e_FM_EV_PLCR, /**< Policer event */ -+ e_FM_EV_ERR_PLCR, /**< Policer error event */ -+ e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */ -+ e_FM_EV_ERR_10G_MAC1, /**< 10G MAC 1 error event */ -+ e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */ -+ e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */ -+ e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */ -+ e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */ -+ e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */ -+ e_FM_EV_ERR_1G_MAC5, /**< 1G MAC 5 error event */ -+ e_FM_EV_ERR_1G_MAC6, /**< 1G MAC 6 error event */ -+ e_FM_EV_ERR_1G_MAC7, /**< 1G MAC 7 error event */ -+ e_FM_EV_ERR_MACSEC_MAC0, -+ e_FM_EV_TMR, /**< Timer event */ -+ e_FM_EV_10G_MAC0, /**< 10G MAC 0 event (Magic packet detection)*/ -+ e_FM_EV_10G_MAC1, /**< 10G MAC 1 event (Magic packet detection)*/ -+ e_FM_EV_1G_MAC0, /**< 1G MAC 0 event (Magic packet detection)*/ -+ e_FM_EV_1G_MAC1, /**< 1G MAC 1 event (Magic packet detection)*/ -+ e_FM_EV_1G_MAC2, /**< 1G MAC 2 (Magic packet detection)*/ -+ e_FM_EV_1G_MAC3, /**< 1G MAC 3 (Magic packet detection)*/ -+ e_FM_EV_1G_MAC4, /**< 1G MAC 4 (Magic packet detection)*/ -+ e_FM_EV_1G_MAC5, /**< 1G MAC 5 (Magic packet detection)*/ -+ e_FM_EV_1G_MAC6, /**< 1G MAC 6 (Magic packet detection)*/ -+ e_FM_EV_1G_MAC7, /**< 1G MAC 7 (Magic packet detection)*/ -+ e_FM_EV_MACSEC_MAC0, /**< MACSEC MAC 0 event */ -+ e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */ -+ e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */ -+ e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */ -+ e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */ -+ e_FM_EV_DUMMY_LAST -+} e_FmInterModuleEvent; -+ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+/**************************************************************************//** -+ @Description PCD KG scheme registers -+*//***************************************************************************/ -+typedef _Packed struct t_FmPcdPlcrProfileRegs { -+ volatile uint32_t fmpl_pemode; /* 0x090 FMPL_PEMODE - FM Policer Profile Entry Mode*/ -+ volatile uint32_t fmpl_pegnia; /* 0x094 FMPL_PEGNIA - FM Policer Profile Entry GREEN Next Invoked Action*/ -+ volatile uint32_t fmpl_peynia; /* 0x098 FMPL_PEYNIA - FM Policer Profile Entry YELLOW Next Invoked Action*/ -+ volatile uint32_t fmpl_pernia; /* 0x09C FMPL_PERNIA - FM Policer Profile Entry RED Next Invoked Action*/ -+ volatile uint32_t fmpl_pecir; /* 0x0A0 FMPL_PECIR - FM Policer Profile Entry Committed Information Rate*/ -+ volatile uint32_t fmpl_pecbs; /* 0x0A4 FMPL_PECBS - FM Policer Profile Entry Committed Burst Size*/ -+ volatile uint32_t fmpl_pepepir_eir; /* 0x0A8 FMPL_PEPIR_EIR - FM Policer Profile Entry Peak/Excess Information Rate*/ -+ volatile uint32_t fmpl_pepbs_ebs; /* 0x0AC FMPL_PEPBS_EBS - FM Policer Profile Entry Peak/Excess Information Rate*/ -+ volatile uint32_t fmpl_pelts; /* 0x0B0 FMPL_PELTS - FM Policer Profile Entry Last TimeStamp*/ -+ volatile uint32_t fmpl_pects; /* 0x0B4 FMPL_PECTS - FM Policer Profile Entry Committed Token Status*/ -+ volatile uint32_t fmpl_pepts_ets; /* 0x0B8 FMPL_PEPTS_ETS - FM Policer Profile Entry Peak/Excess Token Status*/ -+ volatile uint32_t fmpl_pegpc; /* 0x0BC FMPL_PEGPC - FM Policer Profile Entry GREEN Packet Counter*/ -+ volatile uint32_t fmpl_peypc; /* 0x0C0 FMPL_PEYPC - FM Policer Profile Entry YELLOW Packet Counter*/ -+ volatile uint32_t fmpl_perpc; /* 0x0C4 FMPL_PERPC - FM Policer Profile Entry RED Packet Counter */ -+ volatile uint32_t fmpl_perypc; /* 0x0C8 FMPL_PERYPC - FM Policer Profile Entry Recolored YELLOW Packet Counter*/ -+ volatile uint32_t fmpl_perrpc; /* 0x0CC FMPL_PERRPC - FM Policer Profile Entry Recolored RED Packet Counter*/ -+ volatile uint32_t fmpl_res1[12]; /* 0x0D0-0x0FF Reserved */ -+} _PackedType t_FmPcdPlcrProfileRegs; -+ -+ -+typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams { -+ volatile uint32_t portIdAndCapwapReassmTbl; -+ volatile uint32_t fqidForTimeOutFrames; -+ volatile uint32_t timeoutRequestTime; -+}_PackedType t_FmPcdCcCapwapReassmTimeoutParams; -+ -+/**************************************************************************//** -+ @Description PCD CTRL Parameters Page -+*//***************************************************************************/ -+typedef _Packed struct t_FmPcdCtrlParamsPage { -+ volatile uint8_t reserved0[16]; -+ volatile uint32_t iprIpv4Nia; -+ volatile uint32_t iprIpv6Nia; -+ volatile uint8_t reserved1[24]; -+ volatile uint32_t ipfOptionsCounter; -+ volatile uint8_t reserved2[12]; -+ volatile uint32_t misc; -+ volatile uint32_t errorsDiscardMask; -+ volatile uint32_t discardMask; -+ volatile uint8_t reserved3[4]; -+ volatile uint32_t postBmiFetchNia; -+ volatile uint8_t reserved4[172]; -+} _PackedType t_FmPcdCtrlParamsPage; -+ -+ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+/*for UNDER_CONSTRUCTION_FM_RMU_USE_SEC its defined in fm_ext.h*/ -+typedef uint32_t t_FmFmanCtrl; -+ -+#define FPM_PORT_FM_CTL1 0x00000001 -+#define FPM_PORT_FM_CTL2 0x00000002 -+ -+ -+ -+typedef struct t_FmPcdCcFragScratchPoolCmdParams { -+ uint32_t numOfBuffers; -+ uint8_t bufferPoolId; -+} t_FmPcdCcFragScratchPoolCmdParams; -+ -+typedef struct t_FmPcdCcReassmTimeoutParams { -+ bool activate; -+ uint8_t tsbs; -+ uint32_t iprcpt; -+} t_FmPcdCcReassmTimeoutParams; -+ -+typedef struct { -+ uint8_t baseEntry; -+ uint16_t numOfClsPlanEntries; -+ uint32_t vectors[FM_PCD_MAX_NUM_OF_CLS_PLANS]; -+} t_FmPcdKgInterModuleClsPlanSet; -+ -+/**************************************************************************//** -+ @Description Structure for binding a port to keygen schemes. -+*//***************************************************************************/ -+typedef struct t_FmPcdKgInterModuleBindPortToSchemes { -+ uint8_t hardwarePortId; -+ uint8_t netEnvId; -+ bool useClsPlan; /**< TRUE if this port uses the clsPlan mechanism */ -+ uint8_t numOfSchemes; -+ uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES]; -+} t_FmPcdKgInterModuleBindPortToSchemes; -+ -+typedef struct { -+ uint32_t nextCcNodeInfo; -+ t_List node; -+} t_CcNodeInfo; -+ -+typedef struct -+{ -+ t_Handle h_CcNode; -+ uint16_t index; -+ t_List node; -+}t_CcNodeInformation; -+#define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node) -+ -+typedef enum e_ModifyState -+{ -+ e_MODIFY_STATE_ADD = 0, -+ e_MODIFY_STATE_REMOVE, -+ e_MODIFY_STATE_CHANGE -+} e_ModifyState; -+ -+typedef struct -+{ -+ t_Handle h_Manip; -+ t_List node; -+}t_ManipInfo; -+#define CC_NEXT_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInfo, node) -+ -+typedef struct { -+ uint32_t type; -+ uint8_t prOffset; -+ uint16_t dataOffset; -+ uint8_t internalBufferOffset; -+ uint8_t numOfTasks; -+ uint8_t numOfExtraTasks; -+ uint8_t hardwarePortId; -+ t_FmRevisionInfo revInfo; -+ uint32_t nia; -+ uint32_t discardMask; -+} t_GetCcParams; -+ -+typedef struct { -+ uint32_t type; -+ int psoSize; -+ uint32_t nia; -+ t_FmFmanCtrl orFmanCtrl; -+ bool overwrite; -+ uint8_t ofpDpde; -+} t_SetCcParams; -+ -+typedef struct { -+ t_GetCcParams getCcParams; -+ t_SetCcParams setCcParams; -+} t_FmPortGetSetCcParams; -+ -+typedef struct { -+ uint32_t type; -+ bool sleep; -+} t_FmSetParams; -+ -+typedef struct { -+ uint32_t type; -+ uint32_t fmqm_gs; -+ uint32_t fm_npi; -+ uint32_t fm_cld; -+ uint32_t fmfp_extc; -+} t_FmGetParams; -+ -+typedef struct { -+ t_FmSetParams setParams; -+ t_FmGetParams getParams; -+} t_FmGetSetParams; -+ -+t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params); -+ -+static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag) -+{ -+ uint32_t intFlags; -+ if (h_Spinlock) -+ intFlags = XX_LockIntrSpinlock(h_Spinlock); -+ else -+ intFlags = XX_DisableAllIntr(); -+ -+ if (*p_Flag) -+ { -+ if (h_Spinlock) -+ XX_UnlockIntrSpinlock(h_Spinlock, intFlags); -+ else -+ XX_RestoreAllIntr(intFlags); -+ return FALSE; -+ } -+ *p_Flag = TRUE; -+ -+ if (h_Spinlock) -+ XX_UnlockIntrSpinlock(h_Spinlock, intFlags); -+ else -+ XX_RestoreAllIntr(intFlags); -+ -+ return TRUE; -+} -+ -+#define RELEASE_LOCK(_flag) _flag = FALSE; -+ -+/**************************************************************************//** -+ @Collection Defines used for manipulation CC and BMI -+ @{ -+*//***************************************************************************/ -+#define INTERNAL_CONTEXT_OFFSET 0x80000000 -+#define OFFSET_OF_PR 0x40000000 -+#define MANIP_EXTRA_SPACE 0x20000000 -+#define NUM_OF_TASKS 0x10000000 -+#define OFFSET_OF_DATA 0x08000000 -+#define HW_PORT_ID 0x04000000 -+#define FM_REV 0x02000000 -+#define GET_NIA_FPNE 0x01000000 -+#define GET_NIA_PNDN 0x00800000 -+#define NUM_OF_EXTRA_TASKS 0x00400000 -+#define DISCARD_MASK 0x00200000 -+ -+#define UPDATE_NIA_PNEN 0x80000000 -+#define UPDATE_PSO 0x40000000 -+#define UPDATE_NIA_PNDN 0x20000000 -+#define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000 -+#define UPDATE_OFP_DPTE 0x08000000 -+#define UPDATE_NIA_FENE 0x04000000 -+#define UPDATE_NIA_CMNE 0x02000000 -+#define UPDATE_NIA_FPNE 0x01000000 -+/* @} */ -+ -+/**************************************************************************//** -+ @Collection Defines used for manipulation CC and CC -+ @{ -+*//***************************************************************************/ -+#define UPDATE_NIA_ENQ_WITHOUT_DMA 0x80000000 -+#define UPDATE_CC_WITH_TREE 0x40000000 -+#define UPDATE_CC_WITH_DELETE_TREE 0x20000000 -+#define UPDATE_KG_NIA_CC_WA 0x10000000 -+#define UPDATE_KG_OPT_MODE 0x08000000 -+#define UPDATE_KG_NIA 0x04000000 -+#define UPDATE_CC_SHADOW_CLEAR 0x02000000 -+/* @} */ -+ -+#define UPDATE_FPM_BRKC_SLP 0x80000000 -+#define UPDATE_FPM_EXTC 0x40000000 -+#define UPDATE_FPM_EXTC_CLEAR 0x20000000 -+#define GET_FMQM_GS 0x10000000 -+#define GET_FM_NPI 0x08000000 -+#define GET_FMFP_EXTC 0x04000000 -+#define CLEAR_IRAM_READY 0x02000000 -+#define UPDATE_FM_CLD 0x01000000 -+#define GET_FM_CLD 0x00800000 -+#define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \ -+ FM_MAX_NUM_OF_1G_RX_PORTS + \ -+ FM_MAX_NUM_OF_10G_RX_PORTS + \ -+ FM_MAX_NUM_OF_1G_TX_PORTS + \ -+ FM_MAX_NUM_OF_10G_TX_PORTS) -+ -+#define MODULE_NAME_SIZE 30 -+#define DUMMY_PORT_ID 0 -+ -+#define FM_LIODN_OFFSET_MASK 0x3FF -+ -+/**************************************************************************//** -+ @Description NIA Description -+*//***************************************************************************/ -+#define NIA_ENG_MASK 0x007C0000 -+#define NIA_AC_MASK 0x0003ffff -+ -+#define NIA_ORDER_RESTOR 0x00800000 -+#define NIA_ENG_FM_CTL 0x00000000 -+#define NIA_ENG_PRS 0x00440000 -+#define NIA_ENG_KG 0x00480000 -+#define NIA_ENG_PLCR 0x004C0000 -+#define NIA_ENG_BMI 0x00500000 -+#define NIA_ENG_QMI_ENQ 0x00540000 -+#define NIA_ENG_QMI_DEQ 0x00580000 -+ -+#define NIA_FM_CTL_AC_CC 0x00000006 -+#define NIA_FM_CTL_AC_HC 0x0000000C -+#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008 -+#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A -+#define NIA_FM_CTL_AC_POP_TO_N_STEP 0x0000000e -+#define NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER 0x00000010 -+#define NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME 0x00000018 -+#define NIA_FM_CTL_AC_POST_BMI_FETCH 0x00000012 -+#define NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME 0x0000001A -+#define NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME 0x0000001E -+#define NIA_FM_CTL_AC_POST_BMI_ENQ_ORR 0x00000014 -+#define NIA_FM_CTL_AC_POST_BMI_ENQ 0x00000022 -+#define NIA_FM_CTL_AC_PRE_CC 0x00000020 -+#define NIA_FM_CTL_AC_POST_TX 0x00000024 -+/* V3 only */ -+#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028 -+#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME 0x0000002A -+#define NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP 0x0000002C -+ -+#define NIA_BMI_AC_ENQ_FRAME 0x00000002 -+#define NIA_BMI_AC_TX_RELEASE 0x000002C0 -+#define NIA_BMI_AC_RELEASE 0x000000C0 -+#define NIA_BMI_AC_DISCARD 0x000000C1 -+#define NIA_BMI_AC_TX 0x00000274 -+#define NIA_BMI_AC_FETCH 0x00000208 -+#define NIA_BMI_AC_MASK 0x000003FF -+ -+#define NIA_KG_DIRECT 0x00000100 -+#define NIA_KG_CC_EN 0x00000200 -+#define NIA_PLCR_ABSOLUTE 0x00008000 -+ -+#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202 -+ -+#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006) -+#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \ -+ (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \ -+ (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \ -+ (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME)) -+#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \ -+ (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \ -+ (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \ -+ (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME)) -+#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \ -+ (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME) -+#else -+#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \ -+ (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \ -+ (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \ -+ (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)) -+#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \ -+ (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \ -+ (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \ -+ (NIA_ENG_BMI | NIA_BMI_AC_DISCARD)) -+#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \ -+ (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME) -+#endif /* defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || ... */ -+ -+/**************************************************************************//** -+ @Description CTRL Parameters Page defines -+*//***************************************************************************/ -+#define FM_CTL_PARAMS_PAGE_OP_FIX_EN 0x80000000 -+#define FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN 0x40000000 -+#define FM_CTL_PARAMS_PAGE_ALWAYS_ON 0x00000100 -+ -+#define FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK 0x0000003f -+ -+/**************************************************************************//** -+ @Description Port Id defines -+*//***************************************************************************/ -+#if (DPAA_VERSION == 10) -+#define BASE_OH_PORTID 1 -+#else -+#define BASE_OH_PORTID 2 -+#endif /* (DPAA_VERSION == 10) */ -+#define BASE_1G_RX_PORTID 8 -+#define BASE_10G_RX_PORTID 0x10 -+#define BASE_1G_TX_PORTID 0x28 -+#define BASE_10G_TX_PORTID 0x30 -+ -+#define FM_PCD_PORT_OH_BASE_INDX 0 -+#define FM_PCD_PORT_1G_RX_BASE_INDX (FM_PCD_PORT_OH_BASE_INDX+FM_MAX_NUM_OF_OH_PORTS) -+#define FM_PCD_PORT_10G_RX_BASE_INDX (FM_PCD_PORT_1G_RX_BASE_INDX+FM_MAX_NUM_OF_1G_RX_PORTS) -+#define FM_PCD_PORT_1G_TX_BASE_INDX (FM_PCD_PORT_10G_RX_BASE_INDX+FM_MAX_NUM_OF_10G_RX_PORTS) -+#define FM_PCD_PORT_10G_TX_BASE_INDX (FM_PCD_PORT_1G_TX_BASE_INDX+FM_MAX_NUM_OF_1G_TX_PORTS) -+ -+#if (FM_MAX_NUM_OF_OH_PORTS > 0) -+#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \ -+ if ((_relativePortId) >= FM_MAX_NUM_OF_OH_PORTS) \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id")) -+#else -+#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id")) -+#endif -+#if (FM_MAX_NUM_OF_1G_RX_PORTS > 0) -+#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \ -+ if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id")) -+#else -+#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id")) -+#endif -+#if (FM_MAX_NUM_OF_10G_RX_PORTS > 0) -+#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \ -+ if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id")) -+#else -+#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id")) -+#endif -+#if (FM_MAX_NUM_OF_1G_TX_PORTS > 0) -+#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \ -+ if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id")) -+#else -+#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id")) -+#endif -+#if (FM_MAX_NUM_OF_10G_TX_PORTS > 0) -+#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \ -+ if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id")) -+#else -+#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id")) -+#endif -+ -+uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev); -+ -+#define HW_PORT_ID_TO_SW_PORT_ID(_relativePortId, hardwarePortId) \ -+{ if (((hardwarePortId) >= BASE_OH_PORTID) && \ -+ ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \ -+ _relativePortId = (uint8_t)((hardwarePortId)-BASE_OH_PORTID); \ -+ else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \ -+ ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \ -+ _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID); \ -+ else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \ -+ ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \ -+ _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID); \ -+ else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \ -+ ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \ -+ _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID); \ -+ else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \ -+ ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \ -+ _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID); \ -+ else { \ -+ _relativePortId = (uint8_t)DUMMY_PORT_ID; \ -+ ASSERT_COND(TRUE); \ -+ } \ -+} -+ -+#define HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId) \ -+do { \ -+ if (((hardwarePortId) >= BASE_OH_PORTID) && ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \ -+ swPortIndex = (uint8_t)((hardwarePortId)-BASE_OH_PORTID+FM_PCD_PORT_OH_BASE_INDX); \ -+ else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \ -+ ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \ -+ swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID+FM_PCD_PORT_1G_RX_BASE_INDX); \ -+ else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \ -+ ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \ -+ swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID+FM_PCD_PORT_10G_RX_BASE_INDX); \ -+ else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \ -+ ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \ -+ swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID+FM_PCD_PORT_1G_TX_BASE_INDX); \ -+ else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \ -+ ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \ -+ swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID+FM_PCD_PORT_10G_TX_BASE_INDX); \ -+ else ASSERT_COND(FALSE); \ -+} while (0) -+ -+#define SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, swPortIndex) \ -+do { \ -+ if (((swPortIndex) >= FM_PCD_PORT_OH_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_1G_RX_BASE_INDX)) \ -+ hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_OH_BASE_INDX+BASE_OH_PORTID); \ -+ else if (((swPortIndex) >= FM_PCD_PORT_1G_RX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_RX_BASE_INDX)) \ -+ hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_RX_BASE_INDX+BASE_1G_RX_PORTID); \ -+ else if (((swPortIndex) >= FM_PCD_PORT_10G_RX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \ -+ hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_RX_BASE_INDX+BASE_10G_RX_PORTID); \ -+ else if (((swPortIndex) >= FM_PCD_PORT_1G_TX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_TX_BASE_INDX)) \ -+ hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_TX_BASE_INDX+BASE_1G_TX_PORTID); \ -+ else if (((swPortIndex) >= FM_PCD_PORT_10G_TX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \ -+ hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_TX_BASE_INDX+BASE_10G_TX_PORTID); \ -+ else ASSERT_COND(FALSE); \ -+} while (0) -+ -+#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE) -+#define BMI_FIFO_UNITS 0x100 -+ -+typedef struct { -+ void (*f_Isr) (t_Handle h_Arg); -+ t_Handle h_SrcHandle; -+ uint8_t guestId; -+} t_FmIntrSrc; -+ -+#define ILLEGAL_HDR_NUM 0xFF -+#define NO_HDR_NUM FM_PCD_PRS_NUM_OF_HDRS -+ -+#define IS_PRIVATE_HEADER(hdr) (((hdr) == HEADER_TYPE_USER_DEFINED_SHIM1) || \ -+ ((hdr) == HEADER_TYPE_USER_DEFINED_SHIM2)) -+#define IS_SPECIAL_HEADER(hdr) ((hdr) == HEADER_TYPE_MACSEC) -+ -+static __inline__ uint8_t GetPrsHdrNum(e_NetHeaderType hdr) -+{ -+ switch (hdr) -+ { case (HEADER_TYPE_ETH): return 0; -+ case (HEADER_TYPE_LLC_SNAP): return 1; -+ case (HEADER_TYPE_VLAN): return 2; -+ case (HEADER_TYPE_PPPoE): return 3; -+ case (HEADER_TYPE_PPP): return 3; -+ case (HEADER_TYPE_MPLS): return 4; -+ case (HEADER_TYPE_IPv4): return 5; -+ case (HEADER_TYPE_IPv6): return 6; -+ case (HEADER_TYPE_GRE): return 7; -+ case (HEADER_TYPE_MINENCAP): return 8; -+ case (HEADER_TYPE_USER_DEFINED_L3): return 9; -+ case (HEADER_TYPE_TCP): return 10; -+ case (HEADER_TYPE_UDP): return 11; -+ case (HEADER_TYPE_IPSEC_AH): -+ case (HEADER_TYPE_IPSEC_ESP): return 12; -+ case (HEADER_TYPE_SCTP): return 13; -+ case (HEADER_TYPE_DCCP): return 14; -+ case (HEADER_TYPE_USER_DEFINED_L4): return 15; -+ case (HEADER_TYPE_USER_DEFINED_SHIM1): -+ case (HEADER_TYPE_USER_DEFINED_SHIM2): -+ case (HEADER_TYPE_MACSEC): return NO_HDR_NUM; -+ default: -+ return ILLEGAL_HDR_NUM; -+ } -+} -+ -+#define FM_PCD_MAX_NUM_OF_OPTIONS(clsPlanEntries) ((clsPlanEntries==256)? 8:((clsPlanEntries==128)? 7: ((clsPlanEntries==64)? 6: ((clsPlanEntries==32)? 5:0)))) -+ -+ -+/**************************************************************************//** -+ @Description A structure for initializing a keygen classification plan group -+*//***************************************************************************/ -+typedef struct t_FmPcdKgInterModuleClsPlanGrpParams { -+ uint8_t netEnvId; /* IN */ -+ bool grpExists; /* OUT (unused in FmPcdKgBuildClsPlanGrp)*/ -+ uint8_t clsPlanGrpId; /* OUT */ -+ bool emptyClsPlanGrp; /* OUT */ -+ uint8_t numOfOptions; /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/ -+ protocolOpt_t options[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)]; -+ /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/ -+ uint32_t optVectors[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)]; -+ /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/ -+} t_FmPcdKgInterModuleClsPlanGrpParams; -+ -+typedef struct t_FmPcdLock { -+ t_Handle h_Spinlock; -+ volatile bool flag; -+ t_List node; -+} t_FmPcdLock; -+#define FM_PCD_LOCK_OBJ(ptr) LIST_OBJECT(ptr, t_FmPcdLock, node) -+ -+ -+typedef t_Error (t_FmPortGetSetCcParamsCallback) (t_Handle h_FmPort, -+ t_FmPortGetSetCcParams *p_FmPortGetSetCcParams); -+ -+ -+/***********************************************************************/ -+/* Common API for FM-PCD module */ -+/***********************************************************************/ -+t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd); -+uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr); -+uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum); -+uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId); -+void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId); -+void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId); -+uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv); -+void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId); -+uint32_t FmPcdLock(t_Handle h_FmPcd); -+void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags); -+bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr); -+t_Error FmPcdFragHcScratchPoolInit(t_Handle h_FmPcd, uint8_t scratchBpid); -+t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl); -+t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl); -+bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd); -+bool FmPcdLockTryLockAll(t_Handle h_FmPcd); -+void FmPcdLockUnlockAll(t_Handle h_FmPcd); -+t_Error FmPcdHcSync(t_Handle h_FmPcd); -+t_Handle FmGetPcd(t_Handle h_Fm); -+/***********************************************************************/ -+/* Common API for FM-PCD KG module */ -+/***********************************************************************/ -+uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp); -+uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp); -+t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet); -+ -+uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme); -+#if (DPAA_VERSION >= 11) -+bool FmPcdKgGetVspe(t_Handle h_Scheme); -+#endif /* (DPAA_VERSION >= 11) */ -+uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId); -+void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId); -+t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_Scheme); -+t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPortToSchemes, uint32_t *p_SpReg, bool add); -+bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg); -+uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter); -+uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId); -+uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId); -+uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId); -+uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId); -+uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId); -+bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme); -+ -+t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind); -+t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind); -+uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId); -+uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId); -+e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId); -+e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId); -+void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction); -+bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId); -+bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId); -+uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId); -+t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId); -+bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme); -+t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value); -+t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp); -+t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId); -+ -+/***********************************************************************/ -+/* Common API for FM-PCD parser module */ -+/***********************************************************************/ -+t_Error FmPcdPrsIncludePortInStatistics(t_Handle p_FmPcd, uint8_t hardwarePortId, bool include); -+ -+/***********************************************************************/ -+/* Common API for FM-PCD policer module */ -+/***********************************************************************/ -+t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles); -+t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId); -+bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId); -+uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId); -+uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId); -+uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId); -+uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter); -+uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId); -+uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId); -+uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile); -+t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd, -+ e_FmPcdProfileTypeSelection profileType, -+ t_Handle h_FmPort, -+ uint16_t relativeProfile, -+ uint16_t *p_AbsoluteId); -+void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId); -+void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId); -+bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg); -+uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId); -+uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId); -+uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red); -+void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction); -+t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction); -+ -+/***********************************************************************/ -+/* Common API for FM-PCD CC module */ -+/***********************************************************************/ -+uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode); -+uint8_t FmPcdCcGetOffset(t_Handle h_CcNode); -+t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex); -+t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams); -+t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask); -+t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams); -+t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -+t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -+uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer); -+t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree); -+void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams); -+t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes); -+t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes); -+t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort); -+t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_CcTree); -+ -+/***********************************************************************/ -+/* Common API for FM-PCD Manip module */ -+/***********************************************************************/ -+t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree, bool modify); -+ -+/***********************************************************************/ -+/* Common API for FM-Port module */ -+/***********************************************************************/ -+#if (DPAA_VERSION >= 11) -+typedef enum e_FmPortGprFuncType -+{ -+ e_FM_PORT_GPR_EMPTY = 0, -+ e_FM_PORT_GPR_MURAM_PAGE -+} e_FmPortGprFuncType; -+ -+t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, void **p_Value); -+#endif /* DPAA_VERSION >= 11) */ -+t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_FmGetSetParams); -+t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams); -+uint8_t FmPortGetNetEnvId(t_Handle h_FmPort); -+uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort); -+uint32_t FmPortGetPcdEngines(t_Handle h_FmPort); -+void FmPortPcdKgSwUnbindClsPlanGrp (t_Handle h_FmPort); -+ -+ -+#if (DPAA_VERSION >= 11) -+t_Error FmPcdFrmReplicUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_FrmReplic); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Function FmRegisterIntr -+ -+ @Description Used to register an inter-module event handler to be processed by FM -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] mod The module that causes the event -+ @Param[in] modId Module id - if more than 1 instansiation of this -+ mode exists,0 otherwise. -+ @Param[in] intrType Interrupt type (error/normal) selection. -+ @Param[in] f_Isr The interrupt service routine. -+ @Param[in] h_Arg Argument to be passed to f_Isr. -+ -+ @Return None. -+*//***************************************************************************/ -+void FmRegisterIntr(t_Handle h_Fm, -+ e_FmEventModules mod, -+ uint8_t modId, -+ e_FmIntrType intrType, -+ void (*f_Isr) (t_Handle h_Arg), -+ t_Handle h_Arg); -+ -+/**************************************************************************//** -+ @Function FmUnregisterIntr -+ -+ @Description Used to un-register an inter-module event handler that was processed by FM -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] mod The module that causes the event -+ @Param[in] modId Module id - if more than 1 instansiation of this -+ mode exists,0 otherwise. -+ @Param[in] intrType Interrupt type (error/normal) selection. -+ -+ @Return None. -+*//***************************************************************************/ -+void FmUnregisterIntr(t_Handle h_Fm, -+ e_FmEventModules mod, -+ uint8_t modId, -+ e_FmIntrType intrType); -+ -+/**************************************************************************//** -+ @Function FmRegisterFmCtlIntr -+ -+ @Description Used to register to one of the fmCtl events in the FM module -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] eventRegId FmCtl event id (0-7). -+ @Param[in] f_Isr The interrupt service routine. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+void FmRegisterFmCtlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event)); -+ -+ -+/**************************************************************************//** -+ @Description enum for defining MAC types -+*//***************************************************************************/ -+typedef enum e_FmMacType { -+ e_FM_MAC_10G = 0, /**< 10G MAC */ -+ e_FM_MAC_1G /**< 1G MAC */ -+} e_FmMacType; -+ -+/**************************************************************************//** -+ @Description Structure for port-FM communication during FM_PORT_Init. -+ Fields commented 'IN' are passed by the port module to be used -+ by the FM module. -+ Fields commented 'OUT' will be filled by FM before returning to port. -+ Some fields are optional (depending on configuration) and -+ will be analized by the port and FM modules accordingly. -+*//***************************************************************************/ -+typedef struct t_FmInterModulePortInitParams { -+ uint8_t hardwarePortId; /**< IN. port Id */ -+ e_FmPortType portType; /**< IN. Port type */ -+ bool independentMode; /**< IN. TRUE if FM Port operates in independent mode */ -+ uint16_t liodnOffset; /**< IN. Port's requested resource */ -+ uint8_t numOfTasks; /**< IN. Port's requested resource */ -+ uint8_t numOfExtraTasks; /**< IN. Port's requested resource */ -+ uint8_t numOfOpenDmas; /**< IN. Port's requested resource */ -+ uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */ -+ uint32_t sizeOfFifo; /**< IN. Port's requested resource */ -+ uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */ -+ uint8_t deqPipelineDepth; /**< IN. Port's requested resource */ -+ uint16_t maxFrameLength; /**< IN. Port's max frame length. */ -+ uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1. -+ LIODN base for this port, to be -+ used together with LIODN offset. */ -+ t_FmPhysAddr fmMuramPhysBaseAddr;/**< OUT. FM-MURAM physical address*/ -+} t_FmInterModulePortInitParams; -+ -+/**************************************************************************//** -+ @Description Structure for port-FM communication during FM_PORT_Free. -+*//***************************************************************************/ -+typedef struct t_FmInterModulePortFreeParams { -+ uint8_t hardwarePortId; /**< IN. port Id */ -+ e_FmPortType portType; /**< IN. Port type */ -+ uint8_t deqPipelineDepth; /**< IN. Port's requested resource */ -+} t_FmInterModulePortFreeParams; -+ -+/**************************************************************************//** -+ @Function FmGetPcdPrsBaseAddr -+ -+ @Description Get the base address of the Parser from the FM module -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return Base address. -+*//***************************************************************************/ -+uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FmGetPcdKgBaseAddr -+ -+ @Description Get the base address of the Keygen from the FM module -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return Base address. -+*//***************************************************************************/ -+uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FmGetPcdPlcrBaseAddr -+ -+ @Description Get the base address of the Policer from the FM module -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return Base address. -+*//***************************************************************************/ -+uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FmGetMuramHandle -+ -+ @Description Get the handle of the MURAM from the FM module -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return MURAM module handle. -+*//***************************************************************************/ -+t_Handle FmGetMuramHandle(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FmGetPhysicalMuramBase -+ -+ @Description Get the physical base address of the MURAM from the FM module -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] fmPhysAddr Physical MURAM base -+ -+ @Return Physical base address. -+*//***************************************************************************/ -+void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *fmPhysAddr); -+ -+/**************************************************************************//** -+ @Function FmGetTimeStampScale -+ -+ @Description Used internally by other modules in order to get the timeStamp -+ period as requested by the application. -+ -+ This function returns bit number that is incremented every 1 usec. -+ To calculate timestamp period in nsec, use -+ 1000 / (1 << FmGetTimeStampScale()). -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return Bit that counts 1 usec. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+uint32_t FmGetTimeStampScale(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FmResumeStalledPort -+ -+ @Description Used internally by FM port to release a stalled port. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] hardwarePortId HW port id. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId); -+ -+/**************************************************************************//** -+ @Function FmIsPortStalled -+ -+ @Description Used internally by FM port to read the port's status. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] hardwarePortId HW port id. -+ @Param[in] p_IsStalled A pointer to the boolean port stalled state -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled); -+ -+/**************************************************************************//** -+ @Function FmResetMac -+ -+ @Description Used by MAC driver to reset the MAC registers -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] type MAC type. -+ @Param[in] macId MAC id - according to type. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId); -+ -+/**************************************************************************//** -+ @Function FmGetClockFreq -+ -+ @Description Used by MAC driver to get the FM clock frequency -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return clock-freq on success; 0 otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+uint16_t FmGetClockFreq(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FmGetMacClockFreq -+ -+ @Description Used by MAC driver to get the MAC clock frequency -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return clock-freq on success; 0 otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+uint16_t FmGetMacClockFreq(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FmGetId -+ -+ @Description Used by PCD driver to read rhe FM id -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+uint8_t FmGetId(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FmReset -+ -+ @Description Used to reset the FM -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FmReset(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FmGetSetPortParams -+ -+ @Description Used by FM-PORT driver to pass and receive parameters between -+ PORT and FM modules. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in,out] p_PortParams A structure of FM Port parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams); -+ -+/**************************************************************************//** -+ @Function FmFreePortParams -+ -+ @Description Used by FM-PORT driver to free port's resources within the FM. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in,out] p_PortParams A structure of FM Port parameters. -+ -+ @Return None. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams); -+ -+/**************************************************************************//** -+ @Function FmSetNumOfRiscsPerPort -+ -+ @Description Used by FM-PORT driver to pass parameter between -+ PORT and FM modules for working with number of RISC.. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] hardwarePortId hardware port Id. -+ @Param[in] numOfFmanCtrls number of Fman Controllers. -+ @Param[in] orFmanCtrl Fman Controller for order restoration. -+ -+ @Return None. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls, t_FmFmanCtrl orFmanCtrl); -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+/**************************************************************************//* -+ @Function FmDumpPortRegs -+ -+ @Description Dumps FM port registers which are part of FM common registers -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] hardwarePortId HW port id. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only FM_Init(). -+*//***************************************************************************/ -+t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd); -+void FmUnregisterPcd(t_Handle h_Fm); -+t_Handle FmGetPcdHandle(t_Handle h_Fm); -+t_Error FmEnableRamsEcc(t_Handle h_Fm); -+t_Error FmDisableRamsEcc(t_Handle h_Fm); -+void FmGetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo); -+t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId); -+void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId); -+void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents); -+uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId); -+void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event), t_Handle h_Arg); -+void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId); -+t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu); -+bool FmIsMaster(t_Handle h_Fm); -+uint8_t FmGetGuestId(t_Handle h_Fm); -+uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm); -+t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool preFetchConfigured); -+t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool *p_PortConfigured, bool *p_PreFetchConfigured); -+ -+ -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId); -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+ -+void FmMuramClear(t_Handle h_FmMuram); -+t_Error FmSetNumOfOpenDmas(t_Handle h_Fm, -+ uint8_t hardwarePortId, -+ uint8_t *p_NumOfOpenDmas, -+ uint8_t *p_NumOfExtraOpenDmas, -+ bool initialConfig); -+t_Error FmSetNumOfTasks(t_Handle h_Fm, -+ uint8_t hardwarePortId, -+ uint8_t *p_NumOfTasks, -+ uint8_t *p_NumOfExtraTasks, -+ bool initialConfig); -+t_Error FmSetSizeOfFifo(t_Handle h_Fm, -+ uint8_t hardwarePortId, -+ uint32_t *p_SizeOfFifo, -+ uint32_t *p_ExtraSizeOfFifo, -+ bool initialConfig); -+ -+t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm, -+ uint32_t congestionGroupId, -+ uint8_t priorityBitMap); -+ -+#if (DPAA_VERSION >= 11) -+t_Error FmVSPAllocForPort(t_Handle h_Fm, -+ e_FmPortType portType, -+ uint8_t portId, -+ uint8_t numOfStorageProfiles); -+ -+t_Error FmVSPFreeForPort(t_Handle h_Fm, -+ e_FmPortType portType, -+ uint8_t portId); -+ -+t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm, -+ e_FmPortType portType, -+ uint8_t portId, -+ uint16_t relativeProfile, -+ uint16_t *p_AbsoluteId); -+t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm, -+ e_FmPortType portType, -+ uint8_t portId, -+ uint16_t relativeProfile); -+ -+uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ -+#endif /* __FM_COMMON_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h -@@ -0,0 +1,93 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#ifndef __FM_HC_H -+#define __FM_HC_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "fsl_fman_kg.h" -+ -+#define __ERR_MODULE__ MODULE_FM_PCD -+ -+ -+typedef struct t_FmHcParams { -+ t_Handle h_Fm; -+ t_Handle h_FmPcd; -+ t_FmPcdHcParams params; -+} t_FmHcParams; -+ -+ -+t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams); -+void FmHcFree(t_Handle h_FmHc); -+t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc, -+ uint8_t memId); -+t_Error FmHcDumpRegs(t_Handle h_FmHc); -+ -+void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd); -+ -+t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc, -+ t_Handle h_Scheme, -+ struct fman_kg_scheme_regs *p_SchemeRegs, -+ bool updateCounter); -+t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme); -+t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams ); -+t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams); -+t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result); -+t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set); -+t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t clsPlanGrpId); -+ -+t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value); -+uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme); -+ -+t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset); -+ -+t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs); -+t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile); -+ -+t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value); -+uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter); -+ -+t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add); -+t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg); -+ -+t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value); -+t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction); -+ -+t_Error FmHcPcdSync(t_Handle h_FmHc); -+t_Handle FmHcGetPort(t_Handle h_FmHc); -+ -+ -+ -+ -+#endif /* __FM_HC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h -@@ -0,0 +1,117 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_sp_common.h -+ -+ @Description FM SP ... -+*//***************************************************************************/ -+#ifndef __FM_SP_COMMON_H -+#define __FM_SP_COMMON_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "list_ext.h" -+ -+#include "fm_ext.h" -+#include "fm_pcd_ext.h" -+#include "fsl_fman.h" -+ -+/**************************************************************************//** -+ @Description defaults -+*//***************************************************************************/ -+#define DEFAULT_FM_SP_bufferPrefixContent_privDataSize 0 -+#define DEFAULT_FM_SP_bufferPrefixContent_passPrsResult FALSE -+#define DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp FALSE -+#define DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo FALSE -+#define DEFAULT_FM_SP_bufferPrefixContent_dataAlign 64 -+ -+/**************************************************************************//** -+ @Description structure for defining internal context copying -+*//***************************************************************************/ -+typedef struct -+{ -+ uint16_t extBufOffset; /**< Offset in External buffer to which internal -+ context is copied to (Rx) or taken from (Tx, Op). */ -+ uint8_t intContextOffset; /**< Offset within internal context to copy from -+ (Rx) or to copy to (Tx, Op). */ -+ uint16_t size; /**< Internal offset size to be copied */ -+} t_FmSpIntContextDataCopy; -+ -+/**************************************************************************//** -+ @Description struct for defining external buffer margins -+*//***************************************************************************/ -+typedef struct { -+ uint16_t startMargins; /**< Number of bytes to be left at the beginning -+ of the external buffer (must be divisible by 16) */ -+ uint16_t endMargins; /**< number of bytes to be left at the end -+ of the external buffer(must be divisible by 16) */ -+} t_FmSpBufMargins; -+ -+typedef struct { -+ uint32_t dataOffset; -+ uint32_t prsResultOffset; -+ uint32_t timeStampOffset; -+ uint32_t hashResultOffset; -+ uint32_t pcdInfoOffset; -+ uint32_t manipOffset; -+} t_FmSpBufferOffsets; -+ -+ -+t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmPortIntContextDataCopy, -+ t_FmBufferPrefixContent *p_BufferPrefixContent, -+ t_FmSpBufMargins *p_FmPortBufMargins, -+ t_FmSpBufferOffsets *p_FmPortBufferOffsets, -+ uint8_t *internalBufferOffset); -+ -+t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy); -+t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools, -+ t_FmBackupBmPools *p_FmBackupBmPools, -+ t_FmBufPoolDepletion *p_FmBufPoolDepletion); -+t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins); -+void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, uint8_t *orderedArray, uint16_t *sizesArray); -+ -+t_Error FmPcdSpAllocProfiles(t_Handle h_FmPcd, -+ uint8_t hardwarePortId, -+ uint16_t numOfStorageProfiles, -+ uint16_t *base, -+ uint8_t *log2Num); -+t_Error FmPcdSpGetAbsoluteProfileId(t_Handle h_FmPcd, -+ t_Handle h_FmPort, -+ uint16_t relativeProfile, -+ uint16_t *p_AbsoluteId); -+void SpInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId); -+void SpValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId); -+ -+ -+#endif /* __FM_SP_COMMON_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile -@@ -0,0 +1,12 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+ -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ -+obj-y += fsl-ncsw-etc.o -+ -+fsl-ncsw-etc-objs := mm.o memcpy.o sprint.o list.o error.o ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/etc/error.c -@@ -0,0 +1,95 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/* -+ -+ @File error.c -+ -+ @Description General errors and events reporting utilities. -+*//***************************************************************************/ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+#include "error_ext.h" -+ -+ -+const char *dbgLevelStrings[] = -+{ -+ "CRITICAL" -+ ,"MAJOR" -+ ,"MINOR" -+ ,"WARNING" -+ ,"INFO" -+ ,"TRACE" -+}; -+ -+ -+char * ErrTypeStrings (e_ErrorType err) -+{ -+ switch (err) -+ { -+ case (E_OK): return "OK"; -+ case (E_WRITE_FAILED): return "Write Access Failed"; -+ case (E_NO_DEVICE): return "No Device"; -+ case (E_NOT_AVAILABLE): return "Resource Is Unavailable"; -+ case (E_NO_MEMORY): return "Memory Allocation Failed"; -+ case (E_INVALID_ADDRESS): return "Invalid Address"; -+ case (E_BUSY): return "Resource Is Busy"; -+ case (E_ALREADY_EXISTS): return "Resource Already Exists"; -+ case (E_INVALID_OPERATION): return "Invalid Operation"; -+ case (E_INVALID_VALUE): return "Invalid Value"; -+ case (E_NOT_IN_RANGE): return "Value Out Of Range"; -+ case (E_NOT_SUPPORTED): return "Unsupported Operation"; -+ case (E_INVALID_STATE): return "Invalid State"; -+ case (E_INVALID_HANDLE): return "Invalid Handle"; -+ case (E_INVALID_ID): return "Invalid ID"; -+ case (E_NULL_POINTER): return "Unexpected NULL Pointer"; -+ case (E_INVALID_SELECTION): return "Invalid Selection"; -+ case (E_INVALID_COMM_MODE): return "Invalid Communication Mode"; -+ case (E_INVALID_MEMORY_TYPE): return "Invalid Memory Type"; -+ case (E_INVALID_CLOCK): return "Invalid Clock"; -+ case (E_CONFLICT): return "Conflict In Settings"; -+ case (E_NOT_ALIGNED): return "Incorrect Alignment"; -+ case (E_NOT_FOUND): return "Resource Not Found"; -+ case (E_FULL): return "Resource Is Full"; -+ case (E_EMPTY): return "Resource Is Empty"; -+ case (E_ALREADY_FREE): return "Resource Already Free"; -+ case (E_READ_FAILED): return "Read Access Failed"; -+ case (E_INVALID_FRAME): return "Invalid Frame"; -+ case (E_SEND_FAILED): return "Send Operation Failed"; -+ case (E_RECEIVE_FAILED): return "Receive Operation Failed"; -+ case (E_TIMEOUT): return "Operation Timed Out"; -+ default: -+ break; -+ } -+ return NULL; -+} -+#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/etc/list.c -@@ -0,0 +1,71 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ -+ @File list.c -+ -+ @Description Implementation of list. -+*//***************************************************************************/ -+#include "std_ext.h" -+#include "list_ext.h" -+ -+ -+void LIST_Append(t_List *p_NewList, t_List *p_Head) -+{ -+ t_List *p_First = LIST_FIRST(p_NewList); -+ -+ if (p_First != p_NewList) -+ { -+ t_List *p_Last = LIST_LAST(p_NewList); -+ t_List *p_Cur = LIST_NEXT(p_Head); -+ -+ LIST_PREV(p_First) = p_Head; -+ LIST_FIRST(p_Head) = p_First; -+ LIST_NEXT(p_Last) = p_Cur; -+ LIST_LAST(p_Cur) = p_Last; -+ } -+} -+ -+ -+int LIST_NumOfObjs(t_List *p_List) -+{ -+ t_List *p_Tmp; -+ int numOfObjs = 0; -+ -+ if (!LIST_IsEmpty(p_List)) -+ LIST_FOR_EACH(p_Tmp, p_List) -+ numOfObjs++; -+ -+ return numOfObjs; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c -@@ -0,0 +1,620 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+ -+#include "std_ext.h" -+#include "xx_ext.h" -+#include "memcpy_ext.h" -+ -+void * MemCpy8(void* pDst, void* pSrc, uint32_t size) -+{ -+ int i; -+ -+ for(i = 0; i < size; ++i) -+ *(((uint8_t*)(pDst)) + i) = *(((uint8_t*)(pSrc)) + i); -+ -+ return pDst; -+} -+ -+void * MemSet8(void* pDst, int c, uint32_t size) -+{ -+ int i; -+ -+ for(i = 0; i < size; ++i) -+ *(((uint8_t*)(pDst)) + i) = (uint8_t)(c); -+ -+ return pDst; -+} -+ -+void * MemCpy32(void* pDst,void* pSrc, uint32_t size) -+{ -+ uint32_t leftAlign; -+ uint32_t rightAlign; -+ uint32_t lastWord; -+ uint32_t currWord; -+ uint32_t *p_Src32; -+ uint32_t *p_Dst32; -+ uint8_t *p_Src8; -+ uint8_t *p_Dst8; -+ -+ p_Src8 = (uint8_t*)(pSrc); -+ p_Dst8 = (uint8_t*)(pDst); -+ /* first copy byte by byte till the source first alignment -+ * this step is necessary to ensure we do not even try to access -+ * data which is before the source buffer, hence it is not ours. -+ */ -+ while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */ -+ { -+ *p_Dst8++ = *p_Src8++; -+ size--; -+ } -+ -+ /* align destination (possibly disaligning source)*/ -+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */ -+ { -+ *p_Dst8++ = *p_Src8++; -+ size--; -+ } -+ -+ /* dest is aligned and source is not necessarily aligned */ -+ leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */ -+ rightAlign = 32 - leftAlign; -+ -+ -+ if (leftAlign == 0) -+ { -+ /* source is also aligned */ -+ p_Src32 = (uint32_t*)(p_Src8); -+ p_Dst32 = (uint32_t*)(p_Dst8); -+ while (size >> 2) /* size >= 4 */ -+ { -+ *p_Dst32++ = *p_Src32++; -+ size -= 4; -+ } -+ p_Src8 = (uint8_t*)(p_Src32); -+ p_Dst8 = (uint8_t*)(p_Dst32); -+ } -+ else -+ { -+ /* source is not aligned (destination is aligned)*/ -+ p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3)); -+ p_Dst32 = (uint32_t*)(p_Dst8); -+ lastWord = *p_Src32++; -+ while(size >> 3) /* size >= 8 */ -+ { -+ currWord = *p_Src32; -+ *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign); -+ lastWord = currWord; -+ p_Src32++; -+ p_Dst32++; -+ size -= 4; -+ } -+ p_Dst8 = (uint8_t*)(p_Dst32); -+ p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3); -+ } -+ -+ /* complete the left overs */ -+ while (size--) -+ *p_Dst8++ = *p_Src8++; -+ -+ return pDst; -+} -+ -+void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size) -+{ -+ uint32_t leftAlign; -+ uint32_t rightAlign; -+ uint32_t lastWord; -+ uint32_t currWord; -+ uint32_t *p_Src32; -+ uint32_t *p_Dst32; -+ uint8_t *p_Src8; -+ uint8_t *p_Dst8; -+ -+ p_Src8 = (uint8_t*)(pSrc); -+ p_Dst8 = (uint8_t*)(pDst); -+ /* first copy byte by byte till the source first alignment -+ * this step is necessary to ensure we do not even try to access -+ * data which is before the source buffer, hence it is not ours. -+ */ -+ while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */ -+ { -+ WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8)); -+ p_Dst8++;p_Src8++; -+ size--; -+ } -+ -+ /* align destination (possibly disaligning source)*/ -+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */ -+ { -+ WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8)); -+ p_Dst8++;p_Src8++; -+ size--; -+ } -+ -+ /* dest is aligned and source is not necessarily aligned */ -+ leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */ -+ rightAlign = 32 - leftAlign; -+ -+ if (leftAlign == 0) -+ { -+ /* source is also aligned */ -+ p_Src32 = (uint32_t*)(p_Src8); -+ p_Dst32 = (uint32_t*)(p_Dst8); -+ while (size >> 2) /* size >= 4 */ -+ { -+ WRITE_UINT32(*p_Dst32, GET_UINT32(*p_Src32)); -+ p_Dst32++;p_Src32++; -+ size -= 4; -+ } -+ p_Src8 = (uint8_t*)(p_Src32); -+ p_Dst8 = (uint8_t*)(p_Dst32); -+ } -+ else -+ { -+ /* source is not aligned (destination is aligned)*/ -+ p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3)); -+ p_Dst32 = (uint32_t*)(p_Dst8); -+ lastWord = GET_UINT32(*p_Src32); -+ p_Src32++; -+ while(size >> 3) /* size >= 8 */ -+ { -+ currWord = GET_UINT32(*p_Src32); -+ WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign)); -+ lastWord = currWord; -+ p_Src32++;p_Dst32++; -+ size -= 4; -+ } -+ p_Dst8 = (uint8_t*)(p_Dst32); -+ p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3); -+ } -+ -+ /* complete the left overs */ -+ while (size--) -+ { -+ WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8)); -+ p_Dst8++;p_Src8++; -+ } -+ -+ return pDst; -+} -+ -+void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size) -+{ -+ uint32_t leftAlign; -+ uint32_t rightAlign; -+ uint32_t lastWord; -+ uint32_t currWord; -+ uint32_t *p_Src32; -+ uint32_t *p_Dst32; -+ uint8_t *p_Src8; -+ uint8_t *p_Dst8; -+ -+ p_Src8 = (uint8_t*)(pSrc); -+ p_Dst8 = (uint8_t*)(pDst); -+ /* first copy byte by byte till the source first alignment -+ * this step is necessary to ensure we do not even try to access -+ * data which is before the source buffer, hence it is not ours. -+ */ -+ while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */ -+ { -+ WRITE_UINT8(*p_Dst8, *p_Src8); -+ p_Dst8++;p_Src8++; -+ size--; -+ } -+ -+ /* align destination (possibly disaligning source)*/ -+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */ -+ { -+ WRITE_UINT8(*p_Dst8, *p_Src8); -+ p_Dst8++;p_Src8++; -+ size--; -+ } -+ -+ /* dest is aligned and source is not necessarily aligned */ -+ leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */ -+ rightAlign = 32 - leftAlign; -+ -+ if (leftAlign == 0) -+ { -+ /* source is also aligned */ -+ p_Src32 = (uint32_t*)(p_Src8); -+ p_Dst32 = (uint32_t*)(p_Dst8); -+ while (size >> 2) /* size >= 4 */ -+ { -+ WRITE_UINT32(*p_Dst32, *p_Src32); -+ p_Dst32++;p_Src32++; -+ size -= 4; -+ } -+ p_Src8 = (uint8_t*)(p_Src32); -+ p_Dst8 = (uint8_t*)(p_Dst32); -+ } -+ else -+ { -+ /* source is not aligned (destination is aligned)*/ -+ p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3)); -+ p_Dst32 = (uint32_t*)(p_Dst8); -+ lastWord = *p_Src32++; -+ while(size >> 3) /* size >= 8 */ -+ { -+ currWord = *p_Src32; -+ WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign)); -+ lastWord = currWord; -+ p_Src32++;p_Dst32++; -+ size -= 4; -+ } -+ p_Dst8 = (uint8_t*)(p_Dst32); -+ p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3); -+ } -+ -+ /* complete the left overs */ -+ while (size--) -+ { -+ WRITE_UINT8(*p_Dst8, *p_Src8); -+ p_Dst8++;p_Src8++; -+ } -+ -+ return pDst; -+} -+ -+void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size) -+{ -+ uint32_t leftAlign; -+ uint32_t rightAlign; -+ uint32_t lastWord; -+ uint32_t currWord; -+ uint32_t *p_Src32; -+ uint32_t *p_Dst32; -+ uint8_t *p_Src8; -+ uint8_t *p_Dst8; -+ -+ p_Src8 = (uint8_t*)(pSrc); -+ p_Dst8 = (uint8_t*)(pDst); -+ /* first copy byte by byte till the source first alignment -+ * this step is necessary to ensure we do not even try to access -+ * data which is before the source buffer, hence it is not ours. -+ */ -+ while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */ -+ { -+ *p_Dst8 = GET_UINT8(*p_Src8); -+ p_Dst8++;p_Src8++; -+ size--; -+ } -+ -+ /* align destination (possibly disaligning source)*/ -+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */ -+ { -+ *p_Dst8 = GET_UINT8(*p_Src8); -+ p_Dst8++;p_Src8++; -+ size--; -+ } -+ -+ /* dest is aligned and source is not necessarily aligned */ -+ leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */ -+ rightAlign = 32 - leftAlign; -+ -+ if (leftAlign == 0) -+ { -+ /* source is also aligned */ -+ p_Src32 = (uint32_t*)(p_Src8); -+ p_Dst32 = (uint32_t*)(p_Dst8); -+ while (size >> 2) /* size >= 4 */ -+ { -+ *p_Dst32 = GET_UINT32(*p_Src32); -+ p_Dst32++;p_Src32++; -+ size -= 4; -+ } -+ p_Src8 = (uint8_t*)(p_Src32); -+ p_Dst8 = (uint8_t*)(p_Dst32); -+ } -+ else -+ { -+ /* source is not aligned (destination is aligned)*/ -+ p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3)); -+ p_Dst32 = (uint32_t*)(p_Dst8); -+ lastWord = GET_UINT32(*p_Src32); -+ p_Src32++; -+ while(size >> 3) /* size >= 8 */ -+ { -+ currWord = GET_UINT32(*p_Src32); -+ *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign); -+ lastWord = currWord; -+ p_Src32++;p_Dst32++; -+ size -= 4; -+ } -+ p_Dst8 = (uint8_t*)(p_Dst32); -+ p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3); -+ } -+ -+ /* complete the left overs */ -+ while (size--) -+ { -+ *p_Dst8 = GET_UINT8(*p_Src8); -+ p_Dst8++;p_Src8++; -+ } -+ -+ return pDst; -+} -+ -+void * MemCpy64(void* pDst,void* pSrc, uint32_t size) -+{ -+ uint32_t leftAlign; -+ uint32_t rightAlign; -+ uint64_t lastWord; -+ uint64_t currWord; -+ uint64_t *pSrc64; -+ uint64_t *pDst64; -+ uint8_t *p_Src8; -+ uint8_t *p_Dst8; -+ -+ p_Src8 = (uint8_t*)(pSrc); -+ p_Dst8 = (uint8_t*)(pDst); -+ /* first copy byte by byte till the source first alignment -+ * this step is necessarily to ensure we do not even try to access -+ * data which is before the source buffer, hence it is not ours. -+ */ -+ while((PTR_TO_UINT(p_Src8) & 7) && size) /* (pSrc mod 8) > 0 and size > 0 */ -+ { -+ *p_Dst8++ = *p_Src8++; -+ size--; -+ } -+ -+ /* align destination (possibly disaligning source)*/ -+ while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */ -+ { -+ *p_Dst8++ = *p_Src8++; -+ size--; -+ } -+ -+ /* dest is aligned and source is not necessarily aligned */ -+ leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 7) << 3); /* leftAlign = (pSrc mod 8)*8 */ -+ rightAlign = 64 - leftAlign; -+ -+ -+ if (leftAlign == 0) -+ { -+ /* source is also aligned */ -+ pSrc64 = (uint64_t*)(p_Src8); -+ pDst64 = (uint64_t*)(p_Dst8); -+ while (size >> 3) /* size >= 8 */ -+ { -+ *pDst64++ = *pSrc64++; -+ size -= 8; -+ } -+ p_Src8 = (uint8_t*)(pSrc64); -+ p_Dst8 = (uint8_t*)(pDst64); -+ } -+ else -+ { -+ /* source is not aligned (destination is aligned)*/ -+ pSrc64 = (uint64_t*)(p_Src8 - (leftAlign >> 3)); -+ pDst64 = (uint64_t*)(p_Dst8); -+ lastWord = *pSrc64++; -+ while(size >> 4) /* size >= 16 */ -+ { -+ currWord = *pSrc64; -+ *pDst64 = (lastWord << leftAlign) | (currWord >> rightAlign); -+ lastWord = currWord; -+ pSrc64++; -+ pDst64++; -+ size -= 8; -+ } -+ p_Dst8 = (uint8_t*)(pDst64); -+ p_Src8 = (uint8_t*)(pSrc64) - 8 + (leftAlign >> 3); -+ } -+ -+ /* complete the left overs */ -+ while (size--) -+ *p_Dst8++ = *p_Src8++; -+ -+ return pDst; -+} -+ -+void * MemSet32(void* pDst, uint8_t val, uint32_t size) -+{ -+ uint32_t val32; -+ uint32_t *p_Dst32; -+ uint8_t *p_Dst8; -+ -+ p_Dst8 = (uint8_t*)(pDst); -+ -+ /* generate four 8-bit val's in 32-bit container */ -+ val32 = (uint32_t) val; -+ val32 |= (val32 << 8); -+ val32 |= (val32 << 16); -+ -+ /* align destination to 32 */ -+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */ -+ { -+ *p_Dst8++ = val; -+ size--; -+ } -+ -+ /* 32-bit chunks */ -+ p_Dst32 = (uint32_t*)(p_Dst8); -+ while (size >> 2) /* size >= 4 */ -+ { -+ *p_Dst32++ = val32; -+ size -= 4; -+ } -+ -+ /* complete the leftovers */ -+ p_Dst8 = (uint8_t*)(p_Dst32); -+ while (size--) -+ *p_Dst8++ = val; -+ -+ return pDst; -+} -+ -+void * IOMemSet32(void* pDst, uint8_t val, uint32_t size) -+{ -+ uint32_t val32; -+ uint32_t *p_Dst32; -+ uint8_t *p_Dst8; -+ -+ p_Dst8 = (uint8_t*)(pDst); -+ -+ /* generate four 8-bit val's in 32-bit container */ -+ val32 = (uint32_t) val; -+ val32 |= (val32 << 8); -+ val32 |= (val32 << 16); -+ -+ /* align destination to 32 */ -+ while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */ -+ { -+ WRITE_UINT8(*p_Dst8, val); -+ p_Dst8++; -+ size--; -+ } -+ -+ /* 32-bit chunks */ -+ p_Dst32 = (uint32_t*)(p_Dst8); -+ while (size >> 2) /* size >= 4 */ -+ { -+ WRITE_UINT32(*p_Dst32, val32); -+ p_Dst32++; -+ size -= 4; -+ } -+ -+ /* complete the leftovers */ -+ p_Dst8 = (uint8_t*)(p_Dst32); -+ while (size--) -+ { -+ WRITE_UINT8(*p_Dst8, val); -+ p_Dst8++; -+ } -+ -+ return pDst; -+} -+ -+void * MemSet64(void* pDst, uint8_t val, uint32_t size) -+{ -+ uint64_t val64; -+ uint64_t *pDst64; -+ uint8_t *p_Dst8; -+ -+ p_Dst8 = (uint8_t*)(pDst); -+ -+ /* generate four 8-bit val's in 32-bit container */ -+ val64 = (uint64_t) val; -+ val64 |= (val64 << 8); -+ val64 |= (val64 << 16); -+ val64 |= (val64 << 24); -+ val64 |= (val64 << 32); -+ -+ /* align destination to 64 */ -+ while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */ -+ { -+ *p_Dst8++ = val; -+ size--; -+ } -+ -+ /* 64-bit chunks */ -+ pDst64 = (uint64_t*)(p_Dst8); -+ while (size >> 4) /* size >= 8 */ -+ { -+ *pDst64++ = val64; -+ size -= 8; -+ } -+ -+ /* complete the leftovers */ -+ p_Dst8 = (uint8_t*)(pDst64); -+ while (size--) -+ *p_Dst8++ = val; -+ -+ return pDst; -+} -+ -+void MemDisp(uint8_t *p, int size) -+{ -+ uint32_t space = (uint32_t)(PTR_TO_UINT(p) & 0x3); -+ uint8_t *p_Limit; -+ -+ if (space) -+ { -+ p_Limit = (p - space + 4); -+ -+ XX_Print("0x%08X: ", (p - space)); -+ -+ while (space--) -+ { -+ XX_Print("--"); -+ } -+ while (size && (p < p_Limit)) -+ { -+ XX_Print("%02x", *(uint8_t*)p); -+ size--; -+ p++; -+ } -+ -+ XX_Print(" "); -+ p_Limit += 12; -+ -+ while ((size > 3) && (p < p_Limit)) -+ { -+ XX_Print("%08x ", *(uint32_t*)p); -+ size -= 4; -+ p += 4; -+ } -+ XX_Print("\r\n"); -+ } -+ -+ while (size > 15) -+ { -+ XX_Print("0x%08X: %08x %08x %08x %08x\r\n", -+ p, *(uint32_t *)p, *(uint32_t *)(p + 4), -+ *(uint32_t *)(p + 8), *(uint32_t *)(p + 12)); -+ size -= 16; -+ p += 16; -+ } -+ -+ if (size) -+ { -+ XX_Print("0x%08X: ", p); -+ -+ while (size > 3) -+ { -+ XX_Print("%08x ", *(uint32_t *)p); -+ size -= 4; -+ p += 4; -+ } -+ while (size) -+ { -+ XX_Print("%02x", *(uint8_t *)p); -+ size--; -+ p++; -+ } -+ -+ XX_Print("\r\n"); -+ } -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c -@@ -0,0 +1,1155 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#include "string_ext.h" -+#include "error_ext.h" -+#include "std_ext.h" -+#include "part_ext.h" -+#include "xx_ext.h" -+ -+#include "mm.h" -+ -+ -+ -+ -+/********************************************************************** -+ * MM internal routines set * -+ **********************************************************************/ -+ -+/**************************************************************** -+ * Routine: CreateBusyBlock -+ * -+ * Description: -+ * Initializes a new busy block of "size" bytes and started -+ * rom "base" address. Each busy block has a name that -+ * specified the purpose of the memory allocation. -+ * -+ * Arguments: -+ * base - base address of the busy block -+ * size - size of the busy block -+ * name - name that specified the busy block -+ * -+ * Return value: -+ * A pointer to new created structure returned on success; -+ * Otherwise, NULL. -+ ****************************************************************/ -+static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name) -+{ -+ t_BusyBlock *p_BusyBlock; -+ uint32_t n; -+ -+ p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock)); -+ if ( !p_BusyBlock ) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ return NULL; -+ } -+ -+ p_BusyBlock->base = base; -+ p_BusyBlock->end = base + size; -+ -+ n = strlen(name); -+ if (n >= MM_MAX_NAME_LEN) -+ n = MM_MAX_NAME_LEN - 1; -+ strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1); -+ p_BusyBlock->name[n] = '\0'; -+ p_BusyBlock->p_Next = 0; -+ -+ return p_BusyBlock; -+} -+ -+/**************************************************************** -+ * Routine: CreateNewBlock -+ * -+ * Description: -+ * Initializes a new memory block of "size" bytes and started -+ * from "base" address. -+ * -+ * Arguments: -+ * base - base address of the memory block -+ * size - size of the memory block -+ * -+ * Return value: -+ * A pointer to new created structure returned on success; -+ * Otherwise, NULL. -+ ****************************************************************/ -+static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size) -+{ -+ t_MemBlock *p_MemBlock; -+ -+ p_MemBlock = (t_MemBlock *)XX_Malloc(sizeof(t_MemBlock)); -+ if ( !p_MemBlock ) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ return NULL; -+ } -+ -+ p_MemBlock->base = base; -+ p_MemBlock->end = base+size; -+ p_MemBlock->p_Next = 0; -+ -+ return p_MemBlock; -+} -+ -+/**************************************************************** -+ * Routine: CreateFreeBlock -+ * -+ * Description: -+ * Initializes a new free block of of "size" bytes and -+ * started from "base" address. -+ * -+ * Arguments: -+ * base - base address of the free block -+ * size - size of the free block -+ * -+ * Return value: -+ * A pointer to new created structure returned on success; -+ * Otherwise, NULL. -+ ****************************************************************/ -+static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size) -+{ -+ t_FreeBlock *p_FreeBlock; -+ -+ p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock)); -+ if ( !p_FreeBlock ) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ return NULL; -+ } -+ -+ p_FreeBlock->base = base; -+ p_FreeBlock->end = base + size; -+ p_FreeBlock->p_Next = 0; -+ -+ return p_FreeBlock; -+} -+ -+/**************************************************************** -+ * Routine: AddFree -+ * -+ * Description: -+ * Adds a new free block to the free lists. It updates each -+ * free list to include a new free block. -+ * Note, that all free block in each free list are ordered -+ * by their base address. -+ * -+ * Arguments: -+ * p_MM - pointer to the MM object -+ * base - base address of a given free block -+ * end - end address of a given free block -+ * -+ * Return value: -+ * -+ * -+ ****************************************************************/ -+static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end) -+{ -+ t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB; -+ uint64_t alignment; -+ uint64_t alignBase; -+ int i; -+ -+ /* Updates free lists to include a just released block */ -+ for (i=0; i <= MM_MAX_ALIGNMENT; i++) -+ { -+ p_PrevB = p_NewB = 0; -+ p_CurrB = p_MM->freeBlocks[i]; -+ -+ alignment = (uint64_t)(0x1 << i); -+ alignBase = MAKE_ALIGNED(base, alignment); -+ -+ /* Goes to the next free list if there is no block to free */ -+ if (alignBase >= end) -+ continue; -+ -+ /* Looks for a free block that should be updated */ -+ while ( p_CurrB ) -+ { -+ if ( alignBase <= p_CurrB->end ) -+ { -+ if ( end > p_CurrB->end ) -+ { -+ t_FreeBlock *p_NextB; -+ while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end ) -+ { -+ p_NextB = p_CurrB->p_Next; -+ p_CurrB->p_Next = p_CurrB->p_Next->p_Next; -+ XX_Free(p_NextB); -+ } -+ -+ p_NextB = p_CurrB->p_Next; -+ if ( !p_NextB || (p_NextB && end < p_NextB->base) ) -+ { -+ p_CurrB->end = end; -+ } -+ else -+ { -+ p_CurrB->end = p_NextB->end; -+ p_CurrB->p_Next = p_NextB->p_Next; -+ XX_Free(p_NextB); -+ } -+ } -+ else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) ) -+ { -+ if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ -+ p_NewB->p_Next = p_CurrB; -+ if (p_PrevB) -+ p_PrevB->p_Next = p_NewB; -+ else -+ p_MM->freeBlocks[i] = p_NewB; -+ break; -+ } -+ -+ if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base)) -+ { -+ p_CurrB->base = alignBase; -+ } -+ -+ /* if size of the free block is less then alignment -+ * deletes that free block from the free list. */ -+ if ( (p_CurrB->end - p_CurrB->base) < alignment) -+ { -+ if ( p_PrevB ) -+ p_PrevB->p_Next = p_CurrB->p_Next; -+ else -+ p_MM->freeBlocks[i] = p_CurrB->p_Next; -+ XX_Free(p_CurrB); -+ p_CurrB = NULL; -+ } -+ break; -+ } -+ else -+ { -+ p_PrevB = p_CurrB; -+ p_CurrB = p_CurrB->p_Next; -+ } -+ } -+ -+ /* If no free block found to be updated, insert a new free block -+ * to the end of the free list. -+ */ -+ if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) ) -+ { -+ if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ -+ if (p_PrevB) -+ p_PrevB->p_Next = p_NewB; -+ else -+ p_MM->freeBlocks[i] = p_NewB; -+ } -+ -+ /* Update boundaries of the new free block */ -+ if ((alignment == 1) && !p_NewB) -+ { -+ if ( p_CurrB && base > p_CurrB->base ) -+ base = p_CurrB->base; -+ if ( p_CurrB && end < p_CurrB->end ) -+ end = p_CurrB->end; -+ } -+ } -+ -+ return (E_OK); -+} -+ -+/**************************************************************** -+ * Routine: CutFree -+ * -+ * Description: -+ * Cuts a free block from holdBase to holdEnd from the free lists. -+ * That is, it updates all free lists of the MM object do -+ * not include a block of memory from holdBase to holdEnd. -+ * For each free lists it seek for a free block that holds -+ * either holdBase or holdEnd. If such block is found it updates it. -+ * -+ * Arguments: -+ * p_MM - pointer to the MM object -+ * holdBase - base address of the allocated block -+ * holdEnd - end address of the allocated block -+ * -+ * Return value: -+ * E_OK is returned on success, -+ * otherwise returns an error code. -+ * -+ ****************************************************************/ -+static t_Error CutFree(t_MM *p_MM, uint64_t holdBase, uint64_t holdEnd) -+{ -+ t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB; -+ uint64_t alignBase, base, end; -+ uint64_t alignment; -+ int i; -+ -+ for (i=0; i <= MM_MAX_ALIGNMENT; i++) -+ { -+ p_PrevB = p_NewB = 0; -+ p_CurrB = p_MM->freeBlocks[i]; -+ -+ alignment = (uint64_t)(0x1 << i); -+ alignBase = MAKE_ALIGNED(holdEnd, alignment); -+ -+ while ( p_CurrB ) -+ { -+ base = p_CurrB->base; -+ end = p_CurrB->end; -+ -+ if ( (holdBase <= base) && (holdEnd <= end) && (holdEnd > base) ) -+ { -+ if ( alignBase >= end || -+ (alignBase < end && ((end-alignBase) < alignment)) ) -+ { -+ if (p_PrevB) -+ p_PrevB->p_Next = p_CurrB->p_Next; -+ else -+ p_MM->freeBlocks[i] = p_CurrB->p_Next; -+ XX_Free(p_CurrB); -+ } -+ else -+ { -+ p_CurrB->base = alignBase; -+ } -+ break; -+ } -+ else if ( (holdBase > base) && (holdEnd <= end) ) -+ { -+ if ( (holdBase-base) >= alignment ) -+ { -+ if ( (alignBase < end) && ((end-alignBase) >= alignment) ) -+ { -+ if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ p_NewB->p_Next = p_CurrB->p_Next; -+ p_CurrB->p_Next = p_NewB; -+ } -+ p_CurrB->end = holdBase; -+ } -+ else if ( (alignBase < end) && ((end-alignBase) >= alignment) ) -+ { -+ p_CurrB->base = alignBase; -+ } -+ else -+ { -+ if (p_PrevB) -+ p_PrevB->p_Next = p_CurrB->p_Next; -+ else -+ p_MM->freeBlocks[i] = p_CurrB->p_Next; -+ XX_Free(p_CurrB); -+ } -+ break; -+ } -+ else -+ { -+ p_PrevB = p_CurrB; -+ p_CurrB = p_CurrB->p_Next; -+ } -+ } -+ } -+ -+ return (E_OK); -+} -+ -+/**************************************************************** -+ * Routine: AddBusy -+ * -+ * Description: -+ * Adds a new busy block to the list of busy blocks. Note, -+ * that all busy blocks are ordered by their base address in -+ * the busy list. -+ * -+ * Arguments: -+ * MM - handler to the MM object -+ * p_NewBusyB - pointer to the a busy block -+ * -+ * Return value: -+ * None. -+ * -+ ****************************************************************/ -+static void AddBusy(t_MM *p_MM, t_BusyBlock *p_NewBusyB) -+{ -+ t_BusyBlock *p_CurrBusyB, *p_PrevBusyB; -+ -+ /* finds a place of a new busy block in the list of busy blocks */ -+ p_PrevBusyB = 0; -+ p_CurrBusyB = p_MM->busyBlocks; -+ -+ while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base ) -+ { -+ p_PrevBusyB = p_CurrBusyB; -+ p_CurrBusyB = p_CurrBusyB->p_Next; -+ } -+ -+ /* insert the new busy block into the list of busy blocks */ -+ if ( p_CurrBusyB ) -+ p_NewBusyB->p_Next = p_CurrBusyB; -+ if ( p_PrevBusyB ) -+ p_PrevBusyB->p_Next = p_NewBusyB; -+ else -+ p_MM->busyBlocks = p_NewBusyB; -+} -+ -+/**************************************************************** -+ * Routine: CutBusy -+ * -+ * Description: -+ * Cuts a block from base to end from the list of busy blocks. -+ * This is done by updating the list of busy blocks do not -+ * include a given block, that block is going to be free. If a -+ * given block is a part of some other busy block, so that -+ * busy block is updated. If there are number of busy blocks -+ * included in the given block, so all that blocks are removed -+ * from the busy list and the end blocks are updated. -+ * If the given block devides some block into two parts, a new -+ * busy block is added to the busy list. -+ * -+ * Arguments: -+ * p_MM - pointer to the MM object -+ * base - base address of a given busy block -+ * end - end address of a given busy block -+ * -+ * Return value: -+ * E_OK on success, E_NOMEMORY otherwise. -+ * -+ ****************************************************************/ -+static t_Error CutBusy(t_MM *p_MM, uint64_t base, uint64_t end) -+{ -+ t_BusyBlock *p_CurrB, *p_PrevB, *p_NewB; -+ -+ p_CurrB = p_MM->busyBlocks; -+ p_PrevB = p_NewB = 0; -+ -+ while ( p_CurrB ) -+ { -+ if ( base < p_CurrB->end ) -+ { -+ if ( end > p_CurrB->end ) -+ { -+ t_BusyBlock *p_NextB; -+ while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end ) -+ { -+ p_NextB = p_CurrB->p_Next; -+ p_CurrB->p_Next = p_CurrB->p_Next->p_Next; -+ XX_Free(p_NextB); -+ } -+ -+ p_NextB = p_CurrB->p_Next; -+ if ( p_NextB && end > p_NextB->base ) -+ { -+ p_NextB->base = end; -+ } -+ } -+ -+ if ( base <= p_CurrB->base ) -+ { -+ if ( end < p_CurrB->end && end > p_CurrB->base ) -+ { -+ p_CurrB->base = end; -+ } -+ else if ( end >= p_CurrB->end ) -+ { -+ if ( p_PrevB ) -+ p_PrevB->p_Next = p_CurrB->p_Next; -+ else -+ p_MM->busyBlocks = p_CurrB->p_Next; -+ XX_Free(p_CurrB); -+ } -+ } -+ else -+ { -+ if ( end < p_CurrB->end && end > p_CurrB->base ) -+ { -+ if ((p_NewB = CreateBusyBlock(end, -+ p_CurrB->end-end, -+ p_CurrB->name)) == NULL) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ p_NewB->p_Next = p_CurrB->p_Next; -+ p_CurrB->p_Next = p_NewB; -+ } -+ p_CurrB->end = base; -+ } -+ break; -+ } -+ else -+ { -+ p_PrevB = p_CurrB; -+ p_CurrB = p_CurrB->p_Next; -+ } -+ } -+ -+ return (E_OK); -+} -+ -+/**************************************************************** -+ * Routine: MmGetGreaterAlignment -+ * -+ * Description: -+ * Allocates a block of memory according to the given size -+ * and the alignment. That routine is called from the MM_Get -+ * routine if the required alignment is greater then MM_MAX_ALIGNMENT. -+ * In that case, it goes over free blocks of 64 byte align list -+ * and checks if it has the required size of bytes of the required -+ * alignment. If no blocks found returns ILLEGAL_BASE. -+ * After the block is found and data is allocated, it calls -+ * the internal CutFree routine to update all free lists -+ * do not include a just allocated block. Of course, each -+ * free list contains a free blocks with the same alignment. -+ * It is also creates a busy block that holds -+ * information about an allocated block. -+ * -+ * Arguments: -+ * MM - handle to the MM object -+ * size - size of the MM -+ * alignment - index as a power of two defines -+ * a required alignment that is greater then 64. -+ * name - the name that specifies an allocated block. -+ * -+ * Return value: -+ * base address of an allocated block. -+ * ILLEGAL_BASE if can't allocate a block -+ * -+ ****************************************************************/ -+static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name) -+{ -+ t_FreeBlock *p_FreeB; -+ t_BusyBlock *p_NewBusyB; -+ uint64_t holdBase, holdEnd, alignBase = 0; -+ -+ /* goes over free blocks of the 64 byte alignment list -+ and look for a block of the suitable size and -+ base address according to the alignment. */ -+ p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT]; -+ -+ while ( p_FreeB ) -+ { -+ alignBase = MAKE_ALIGNED(p_FreeB->base, alignment); -+ -+ /* the block is found if the aligned base inside the block -+ * and has the anough size. */ -+ if ( alignBase >= p_FreeB->base && -+ alignBase < p_FreeB->end && -+ size <= (p_FreeB->end - alignBase) ) -+ break; -+ else -+ p_FreeB = p_FreeB->p_Next; -+ } -+ -+ /* If such block isn't found */ -+ if ( !p_FreeB ) -+ return (uint64_t)(ILLEGAL_BASE); -+ -+ holdBase = alignBase; -+ holdEnd = alignBase + size; -+ -+ /* init a new busy block */ -+ if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL) -+ return (uint64_t)(ILLEGAL_BASE); -+ -+ /* calls Update routine to update a lists of free blocks */ -+ if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK ) -+ { -+ XX_Free(p_NewBusyB); -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ /* insert the new busy block into the list of busy blocks */ -+ AddBusy ( p_MM, p_NewBusyB ); -+ -+ return (holdBase); -+} -+ -+ -+/********************************************************************** -+ * MM API routines set * -+ **********************************************************************/ -+ -+/*****************************************************************************/ -+t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size) -+{ -+ t_MM *p_MM; -+ uint64_t newBase, newSize; -+ int i; -+ -+ if (!size) -+ { -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)")); -+ } -+ -+ /* Initializes a new MM object */ -+ p_MM = (t_MM *)XX_Malloc(sizeof(t_MM)); -+ if (!p_MM) -+ { -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ } -+ -+ p_MM->h_Spinlock = XX_InitSpinlock(); -+ if (!p_MM->h_Spinlock) -+ { -+ XX_Free(p_MM); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!")); -+ } -+ -+ /* Initializes counter of free memory to total size */ -+ p_MM->freeMemSize = size; -+ -+ /* A busy list is empty */ -+ p_MM->busyBlocks = 0; -+ -+ /* Initializes a new memory block */ -+ if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL) -+ { -+ MM_Free(p_MM); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ } -+ -+ /* Initializes a new free block for each free list*/ -+ for (i=0; i <= MM_MAX_ALIGNMENT; i++) -+ { -+ newBase = MAKE_ALIGNED( base, (0x1 << i) ); -+ newSize = size - (newBase - base); -+ -+ if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL) -+ { -+ MM_Free(p_MM); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ } -+ } -+ -+ *h_MM = p_MM; -+ -+ return (E_OK); -+} -+ -+/*****************************************************************************/ -+void MM_Free(t_Handle h_MM) -+{ -+ t_MM *p_MM = (t_MM *)h_MM; -+ t_MemBlock *p_MemBlock; -+ t_BusyBlock *p_BusyBlock; -+ t_FreeBlock *p_FreeBlock; -+ void *p_Block; -+ int i; -+ -+ ASSERT_COND(p_MM); -+ -+ /* release memory allocated for busy blocks */ -+ p_BusyBlock = p_MM->busyBlocks; -+ while ( p_BusyBlock ) -+ { -+ p_Block = p_BusyBlock; -+ p_BusyBlock = p_BusyBlock->p_Next; -+ XX_Free(p_Block); -+ } -+ -+ /* release memory allocated for free blocks */ -+ for (i=0; i <= MM_MAX_ALIGNMENT; i++) -+ { -+ p_FreeBlock = p_MM->freeBlocks[i]; -+ while ( p_FreeBlock ) -+ { -+ p_Block = p_FreeBlock; -+ p_FreeBlock = p_FreeBlock->p_Next; -+ XX_Free(p_Block); -+ } -+ } -+ -+ /* release memory allocated for memory blocks */ -+ p_MemBlock = p_MM->memBlocks; -+ while ( p_MemBlock ) -+ { -+ p_Block = p_MemBlock; -+ p_MemBlock = p_MemBlock->p_Next; -+ XX_Free(p_Block); -+ } -+ -+ if (p_MM->h_Spinlock) -+ XX_FreeSpinlock(p_MM->h_Spinlock); -+ -+ /* release memory allocated for MM object itself */ -+ XX_Free(p_MM); -+} -+ -+/*****************************************************************************/ -+uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name) -+{ -+ t_MM *p_MM = (t_MM *)h_MM; -+ t_FreeBlock *p_FreeB; -+ t_BusyBlock *p_NewBusyB; -+ uint64_t holdBase, holdEnd, j, i = 0; -+ uint32_t intFlags; -+ -+ SANITY_CHECK_RETURN_VALUE(p_MM, E_INVALID_HANDLE, (uint64_t)ILLEGAL_BASE); -+ -+ /* checks that alignment value is greater then zero */ -+ if (alignment == 0) -+ { -+ alignment = 1; -+ } -+ -+ j = alignment; -+ -+ /* checks if alignment is a power of two, if it correct and if the -+ required size is multiple of the given alignment. */ -+ while ((j & 0x1) == 0) -+ { -+ i++; -+ j = j >> 1; -+ } -+ -+ /* if the given alignment isn't power of two, returns an error */ -+ if (j != 1) -+ { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("alignment (should be power of 2)")); -+ return (uint64_t)ILLEGAL_BASE; -+ } -+ -+ if (i > MM_MAX_ALIGNMENT) -+ { -+ return (MmGetGreaterAlignment(p_MM, size, alignment, name)); -+ } -+ -+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); -+ /* look for a block of the size greater or equal to the required size. */ -+ p_FreeB = p_MM->freeBlocks[i]; -+ while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size ) -+ p_FreeB = p_FreeB->p_Next; -+ -+ /* If such block is found */ -+ if ( !p_FreeB ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ holdBase = p_FreeB->base; -+ holdEnd = holdBase + size; -+ -+ /* init a new busy block */ -+ if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ /* calls Update routine to update a lists of free blocks */ -+ if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ XX_Free(p_NewBusyB); -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ /* Decreasing the allocated memory size from free memory size */ -+ p_MM->freeMemSize -= size; -+ -+ /* insert the new busy block into the list of busy blocks */ -+ AddBusy ( p_MM, p_NewBusyB ); -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ -+ return (holdBase); -+} -+ -+/*****************************************************************************/ -+uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name) -+{ -+ t_MM *p_MM = (t_MM *)h_MM; -+ t_FreeBlock *p_FreeB; -+ t_BusyBlock *p_NewBusyB; -+ uint32_t intFlags; -+ bool blockIsFree = FALSE; -+ -+ ASSERT_COND(p_MM); -+ -+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); -+ p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the -+ free list with alignment 1 */ -+ -+ while ( p_FreeB ) -+ { -+ if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end ) -+ { -+ blockIsFree = TRUE; -+ break; -+ } -+ else -+ p_FreeB = p_FreeB->p_Next; -+ } -+ -+ if ( !blockIsFree ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ /* init a new busy block */ -+ if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ /* calls Update routine to update a lists of free blocks */ -+ if ( CutFree ( p_MM, base, base+size ) != E_OK ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ XX_Free(p_NewBusyB); -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ /* Decreasing the allocated memory size from free memory size */ -+ p_MM->freeMemSize -= size; -+ -+ /* insert the new busy block into the list of busy blocks */ -+ AddBusy ( p_MM, p_NewBusyB ); -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ -+ return (base); -+} -+ -+/*****************************************************************************/ -+uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name) -+{ -+ t_MM *p_MM = (t_MM *)h_MM; -+ t_FreeBlock *p_FreeB; -+ t_BusyBlock *p_NewBusyB; -+ uint64_t holdBase, holdEnd, j = alignment, i=0; -+ uint32_t intFlags; -+ -+ ASSERT_COND(p_MM); -+ -+ /* checks if alignment is a power of two, if it correct and if the -+ required size is multiple of the given alignment. */ -+ while ((j & 0x1) == 0) -+ { -+ i++; -+ j = j >> 1; -+ } -+ -+ if ( (j != 1) || (i > MM_MAX_ALIGNMENT) ) -+ { -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); -+ p_FreeB = p_MM->freeBlocks[i]; -+ -+ /* look for the first block that contains the minimum -+ base address. If the whole required size may be fit -+ into it, use that block, otherwise look for the next -+ block of size greater or equal to the required size. */ -+ while ( p_FreeB && (min >= p_FreeB->end)) -+ p_FreeB = p_FreeB->p_Next; -+ -+ /* If such block is found */ -+ if ( !p_FreeB ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ /* if this block is large enough, use this block */ -+ holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min; -+ if ((holdBase + size) <= p_FreeB->end ) -+ { -+ holdEnd = holdBase + size; -+ } -+ else -+ { -+ p_FreeB = p_FreeB->p_Next; -+ while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) ) -+ p_FreeB = p_FreeB->p_Next; -+ -+ /* If such block is found */ -+ if ( !p_FreeB ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ holdBase = p_FreeB->base; -+ holdEnd = holdBase + size; -+ } -+ -+ /* init a new busy block */ -+ if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ /* calls Update routine to update a lists of free blocks */ -+ if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ XX_Free(p_NewBusyB); -+ return (uint64_t)(ILLEGAL_BASE); -+ } -+ -+ /* Decreasing the allocated memory size from free memory size */ -+ p_MM->freeMemSize -= size; -+ -+ /* insert the new busy block into the list of busy blocks */ -+ AddBusy( p_MM, p_NewBusyB ); -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ -+ return (holdBase); -+} -+ -+/*****************************************************************************/ -+uint64_t MM_Put(t_Handle h_MM, uint64_t base) -+{ -+ t_MM *p_MM = (t_MM *)h_MM; -+ t_BusyBlock *p_BusyB, *p_PrevBusyB; -+ uint64_t size; -+ uint32_t intFlags; -+ -+ ASSERT_COND(p_MM); -+ -+ /* Look for a busy block that have the given base value. -+ * That block will be returned back to the memory. -+ */ -+ p_PrevBusyB = 0; -+ -+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); -+ p_BusyB = p_MM->busyBlocks; -+ while ( p_BusyB && base != p_BusyB->base ) -+ { -+ p_PrevBusyB = p_BusyB; -+ p_BusyB = p_BusyB->p_Next; -+ } -+ -+ if ( !p_BusyB ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ return (uint64_t)(0); -+ } -+ -+ if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ return (uint64_t)(0); -+ } -+ -+ /* removes a busy block form the list of busy blocks */ -+ if ( p_PrevBusyB ) -+ p_PrevBusyB->p_Next = p_BusyB->p_Next; -+ else -+ p_MM->busyBlocks = p_BusyB->p_Next; -+ -+ size = p_BusyB->end - p_BusyB->base; -+ -+ /* Adding the deallocated memory size to free memory size */ -+ p_MM->freeMemSize += size; -+ -+ XX_Free(p_BusyB); -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ -+ return (size); -+} -+ -+/*****************************************************************************/ -+uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size) -+{ -+ t_MM *p_MM = (t_MM *)h_MM; -+ uint64_t end = base + size; -+ uint32_t intFlags; -+ -+ ASSERT_COND(p_MM); -+ -+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); -+ -+ if ( CutBusy( p_MM, base, end ) != E_OK ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ return (uint64_t)(0); -+ } -+ -+ if ( AddFree ( p_MM, base, end ) != E_OK ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ return (uint64_t)(0); -+ } -+ -+ /* Adding the deallocated memory size to free memory size */ -+ p_MM->freeMemSize += size; -+ -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ -+ return (size); -+} -+ -+/*****************************************************************************/ -+t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size) -+{ -+ t_MM *p_MM = (t_MM *)h_MM; -+ t_MemBlock *p_MemB, *p_NewMemB; -+ t_Error errCode; -+ uint32_t intFlags; -+ -+ ASSERT_COND(p_MM); -+ -+ /* find a last block in the list of memory blocks to insert a new -+ * memory block -+ */ -+ intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); -+ -+ p_MemB = p_MM->memBlocks; -+ while ( p_MemB->p_Next ) -+ { -+ if ( base >= p_MemB->base && base < p_MemB->end ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG); -+ } -+ p_MemB = p_MemB->p_Next; -+ } -+ /* check for a last memory block */ -+ if ( base >= p_MemB->base && base < p_MemB->end ) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG); -+ } -+ -+ /* create a new memory block */ -+ if ((p_NewMemB = CreateNewBlock(base, size)) == NULL) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ } -+ -+ /* append a new memory block to the end of the list of memory blocks */ -+ p_MemB->p_Next = p_NewMemB; -+ -+ /* add a new free block to the free lists */ -+ errCode = AddFree(p_MM, base, base+size); -+ if (errCode) -+ { -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ p_MemB->p_Next = 0; -+ XX_Free(p_NewMemB); -+ return ((t_Error)errCode); -+ } -+ -+ /* Adding the new block size to free memory size */ -+ p_MM->freeMemSize += size; -+ -+ XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); -+ -+ return (E_OK); -+} -+ -+/*****************************************************************************/ -+uint64_t MM_GetMemBlock(t_Handle h_MM, int index) -+{ -+ t_MM *p_MM = (t_MM*)h_MM; -+ t_MemBlock *p_MemBlock; -+ int i; -+ -+ ASSERT_COND(p_MM); -+ -+ p_MemBlock = p_MM->memBlocks; -+ for (i=0; i < index; i++) -+ p_MemBlock = p_MemBlock->p_Next; -+ -+ if ( p_MemBlock ) -+ return (p_MemBlock->base); -+ else -+ return (uint64_t)ILLEGAL_BASE; -+} -+ -+/*****************************************************************************/ -+uint64_t MM_GetBase(t_Handle h_MM) -+{ -+ t_MM *p_MM = (t_MM*)h_MM; -+ t_MemBlock *p_MemBlock; -+ -+ ASSERT_COND(p_MM); -+ -+ p_MemBlock = p_MM->memBlocks; -+ return p_MemBlock->base; -+} -+ -+/*****************************************************************************/ -+bool MM_InRange(t_Handle h_MM, uint64_t addr) -+{ -+ t_MM *p_MM = (t_MM*)h_MM; -+ t_MemBlock *p_MemBlock; -+ -+ ASSERT_COND(p_MM); -+ -+ p_MemBlock = p_MM->memBlocks; -+ -+ if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end)) -+ return TRUE; -+ else -+ return FALSE; -+} -+ -+/*****************************************************************************/ -+uint64_t MM_GetFreeMemSize(t_Handle h_MM) -+{ -+ t_MM *p_MM = (t_MM*)h_MM; -+ -+ ASSERT_COND(p_MM); -+ -+ return p_MM->freeMemSize; -+} -+ -+/*****************************************************************************/ -+void MM_Dump(t_Handle h_MM) -+{ -+ t_MM *p_MM = (t_MM *)h_MM; -+ t_FreeBlock *p_FreeB; -+ t_BusyBlock *p_BusyB; -+ int i; -+ -+ p_BusyB = p_MM->busyBlocks; -+ XX_Print("List of busy blocks:\n"); -+ while (p_BusyB) -+ { -+ XX_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end ); -+ p_BusyB = p_BusyB->p_Next; -+ } -+ -+ XX_Print("\nLists of free blocks according to alignment:\n"); -+ for (i=0; i <= MM_MAX_ALIGNMENT; i++) -+ { -+ XX_Print("%d alignment:\n", (0x1 << i)); -+ p_FreeB = p_MM->freeBlocks[i]; -+ while (p_FreeB) -+ { -+ XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end); -+ p_FreeB = p_FreeB->p_Next; -+ } -+ XX_Print("\n"); -+ } -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h -@@ -0,0 +1,105 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************** -+ * -+ * File: mm.h -+ * -+ * -+ * Description: -+ * MM (Memory Management) object definitions. -+ * It also includes definitions of the Free Block, Busy Block -+ * and Memory Block structures used by the MM object. -+ * -+ ****************************************************************/ -+ -+#ifndef __MM_H -+#define __MM_H -+ -+ -+#include "mm_ext.h" -+ -+#define __ERR_MODULE__ MODULE_MM -+ -+ -+#define MAKE_ALIGNED(addr, align) \ -+ (((uint64_t)(addr) + ((align) - 1)) & (~(((uint64_t)align) - 1))) -+ -+ -+/* t_MemBlock data structure defines parameters of the Memory Block */ -+typedef struct t_MemBlock -+{ -+ struct t_MemBlock *p_Next; /* Pointer to the next memory block */ -+ -+ uint64_t base; /* Base address of the memory block */ -+ uint64_t end; /* End address of the memory block */ -+} t_MemBlock; -+ -+ -+/* t_FreeBlock data structure defines parameters of the Free Block */ -+typedef struct t_FreeBlock -+{ -+ struct t_FreeBlock *p_Next; /* Pointer to the next free block */ -+ -+ uint64_t base; /* Base address of the block */ -+ uint64_t end; /* End address of the block */ -+} t_FreeBlock; -+ -+ -+/* t_BusyBlock data structure defines parameters of the Busy Block */ -+typedef struct t_BusyBlock -+{ -+ struct t_BusyBlock *p_Next; /* Pointer to the next free block */ -+ -+ uint64_t base; /* Base address of the block */ -+ uint64_t end; /* End address of the block */ -+ char name[MM_MAX_NAME_LEN]; /* That block of memory was allocated for -+ something specified by the Name */ -+} t_BusyBlock; -+ -+ -+/* t_MM data structure defines parameters of the MM object */ -+typedef struct t_MM -+{ -+ t_Handle h_Spinlock; -+ -+ t_MemBlock *memBlocks; /* List of memory blocks (Memory list) */ -+ t_BusyBlock *busyBlocks; /* List of busy blocks (Busy list) */ -+ t_FreeBlock *freeBlocks[MM_MAX_ALIGNMENT + 1]; -+ /* Alignment lists of free blocks (Free lists) */ -+ -+ uint64_t freeMemSize; /* Total size of free memory (in bytes) */ -+} t_MM; -+ -+ -+#endif /* __MM_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c -@@ -0,0 +1,81 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/*------------------------------------------------------*/ -+/* File: sprint.c */ -+/* */ -+/* Description: */ -+/* Debug routines (externals) */ -+/*------------------------------------------------------*/ -+#include "string_ext.h" -+#include "stdlib_ext.h" -+#include "stdarg_ext.h" -+#include "sprint_ext.h" -+#include "std_ext.h" -+#include "xx_ext.h" -+ -+ -+int Sprint(char * buf, const char *fmt, ...) -+{ -+ va_list args; -+ int i; -+ -+ va_start(args, fmt); -+ i=vsprintf(buf,fmt,args); -+ va_end(args); -+ return i; -+} -+ -+int Snprint(char * buf, uint32_t size, const char *fmt, ...) -+{ -+ va_list args; -+ int i; -+ -+ va_start(args, fmt); -+ i=vsnprintf(buf,size,fmt,args); -+ va_end(args); -+ return i; -+} -+ -+#ifndef NCSW_VXWORKS -+int Sscan(const char * buf, const char * fmt, ...) -+{ -+ va_list args; -+ int i; -+ -+ va_start(args,fmt); -+ i = vsscanf(buf,fmt,args); -+ va_end(args); -+ return i; -+} -+#endif /* NCSW_VXWORKS */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h -@@ -0,0 +1,57 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __dflags_h -+#define __dflags_h -+ -+ -+#define NCSW_LINUX -+ -+#define T4240 -+#define NCSW_PPC_CORE -+ -+#define DEBUG_ERRORS 1 -+ -+#if defined(DEBUG) -+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO -+ -+#define DEBUG_XX_MALLOC -+#define DEBUG_MEM_LEAKS -+ -+#else -+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING -+#endif /* (DEBUG) */ -+ -+#define REPORT_EVENTS 1 -+#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR -+ -+#endif /* __dflags_h */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h -@@ -0,0 +1,56 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __dflags_h -+#define __dflags_h -+ -+ -+#define NCSW_LINUX -+ -+#define NCSW_PPC_CORE -+ -+#define DEBUG_ERRORS 1 -+ -+#if defined(DEBUG) -+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO -+ -+#define DEBUG_XX_MALLOC -+#define DEBUG_MEM_LEAKS -+ -+#else -+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING -+#endif /* (DEBUG) */ -+ -+#define REPORT_EVENTS 1 -+#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR -+ -+#endif /* __dflags_h */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h -@@ -0,0 +1,364 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/*------------------------------------------------------*/ -+/* */ -+/* File: crc_mac_addr_ext.h */ -+/* */ -+/* Description: */ -+/* Define a macro that calculate the crc value of */ -+/* an Ethernet MAC address (48 bitd address */ -+/*------------------------------------------------------*/ -+ -+#ifndef __crc_mac_addr_ext_h -+#define __crc_mac_addr_ext_h -+ -+#include "std_ext.h" -+ -+ -+static uint32_t crc_table[256] = -+{ -+ 0x00000000, -+ 0x77073096, -+ 0xee0e612c, -+ 0x990951ba, -+ 0x076dc419, -+ 0x706af48f, -+ 0xe963a535, -+ 0x9e6495a3, -+ 0x0edb8832, -+ 0x79dcb8a4, -+ 0xe0d5e91e, -+ 0x97d2d988, -+ 0x09b64c2b, -+ 0x7eb17cbd, -+ 0xe7b82d07, -+ 0x90bf1d91, -+ 0x1db71064, -+ 0x6ab020f2, -+ 0xf3b97148, -+ 0x84be41de, -+ 0x1adad47d, -+ 0x6ddde4eb, -+ 0xf4d4b551, -+ 0x83d385c7, -+ 0x136c9856, -+ 0x646ba8c0, -+ 0xfd62f97a, -+ 0x8a65c9ec, -+ 0x14015c4f, -+ 0x63066cd9, -+ 0xfa0f3d63, -+ 0x8d080df5, -+ 0x3b6e20c8, -+ 0x4c69105e, -+ 0xd56041e4, -+ 0xa2677172, -+ 0x3c03e4d1, -+ 0x4b04d447, -+ 0xd20d85fd, -+ 0xa50ab56b, -+ 0x35b5a8fa, -+ 0x42b2986c, -+ 0xdbbbc9d6, -+ 0xacbcf940, -+ 0x32d86ce3, -+ 0x45df5c75, -+ 0xdcd60dcf, -+ 0xabd13d59, -+ 0x26d930ac, -+ 0x51de003a, -+ 0xc8d75180, -+ 0xbfd06116, -+ 0x21b4f4b5, -+ 0x56b3c423, -+ 0xcfba9599, -+ 0xb8bda50f, -+ 0x2802b89e, -+ 0x5f058808, -+ 0xc60cd9b2, -+ 0xb10be924, -+ 0x2f6f7c87, -+ 0x58684c11, -+ 0xc1611dab, -+ 0xb6662d3d, -+ 0x76dc4190, -+ 0x01db7106, -+ 0x98d220bc, -+ 0xefd5102a, -+ 0x71b18589, -+ 0x06b6b51f, -+ 0x9fbfe4a5, -+ 0xe8b8d433, -+ 0x7807c9a2, -+ 0x0f00f934, -+ 0x9609a88e, -+ 0xe10e9818, -+ 0x7f6a0dbb, -+ 0x086d3d2d, -+ 0x91646c97, -+ 0xe6635c01, -+ 0x6b6b51f4, -+ 0x1c6c6162, -+ 0x856530d8, -+ 0xf262004e, -+ 0x6c0695ed, -+ 0x1b01a57b, -+ 0x8208f4c1, -+ 0xf50fc457, -+ 0x65b0d9c6, -+ 0x12b7e950, -+ 0x8bbeb8ea, -+ 0xfcb9887c, -+ 0x62dd1ddf, -+ 0x15da2d49, -+ 0x8cd37cf3, -+ 0xfbd44c65, -+ 0x4db26158, -+ 0x3ab551ce, -+ 0xa3bc0074, -+ 0xd4bb30e2, -+ 0x4adfa541, -+ 0x3dd895d7, -+ 0xa4d1c46d, -+ 0xd3d6f4fb, -+ 0x4369e96a, -+ 0x346ed9fc, -+ 0xad678846, -+ 0xda60b8d0, -+ 0x44042d73, -+ 0x33031de5, -+ 0xaa0a4c5f, -+ 0xdd0d7cc9, -+ 0x5005713c, -+ 0x270241aa, -+ 0xbe0b1010, -+ 0xc90c2086, -+ 0x5768b525, -+ 0x206f85b3, -+ 0xb966d409, -+ 0xce61e49f, -+ 0x5edef90e, -+ 0x29d9c998, -+ 0xb0d09822, -+ 0xc7d7a8b4, -+ 0x59b33d17, -+ 0x2eb40d81, -+ 0xb7bd5c3b, -+ 0xc0ba6cad, -+ 0xedb88320, -+ 0x9abfb3b6, -+ 0x03b6e20c, -+ 0x74b1d29a, -+ 0xead54739, -+ 0x9dd277af, -+ 0x04db2615, -+ 0x73dc1683, -+ 0xe3630b12, -+ 0x94643b84, -+ 0x0d6d6a3e, -+ 0x7a6a5aa8, -+ 0xe40ecf0b, -+ 0x9309ff9d, -+ 0x0a00ae27, -+ 0x7d079eb1, -+ 0xf00f9344, -+ 0x8708a3d2, -+ 0x1e01f268, -+ 0x6906c2fe, -+ 0xf762575d, -+ 0x806567cb, -+ 0x196c3671, -+ 0x6e6b06e7, -+ 0xfed41b76, -+ 0x89d32be0, -+ 0x10da7a5a, -+ 0x67dd4acc, -+ 0xf9b9df6f, -+ 0x8ebeeff9, -+ 0x17b7be43, -+ 0x60b08ed5, -+ 0xd6d6a3e8, -+ 0xa1d1937e, -+ 0x38d8c2c4, -+ 0x4fdff252, -+ 0xd1bb67f1, -+ 0xa6bc5767, -+ 0x3fb506dd, -+ 0x48b2364b, -+ 0xd80d2bda, -+ 0xaf0a1b4c, -+ 0x36034af6, -+ 0x41047a60, -+ 0xdf60efc3, -+ 0xa867df55, -+ 0x316e8eef, -+ 0x4669be79, -+ 0xcb61b38c, -+ 0xbc66831a, -+ 0x256fd2a0, -+ 0x5268e236, -+ 0xcc0c7795, -+ 0xbb0b4703, -+ 0x220216b9, -+ 0x5505262f, -+ 0xc5ba3bbe, -+ 0xb2bd0b28, -+ 0x2bb45a92, -+ 0x5cb36a04, -+ 0xc2d7ffa7, -+ 0xb5d0cf31, -+ 0x2cd99e8b, -+ 0x5bdeae1d, -+ 0x9b64c2b0, -+ 0xec63f226, -+ 0x756aa39c, -+ 0x026d930a, -+ 0x9c0906a9, -+ 0xeb0e363f, -+ 0x72076785, -+ 0x05005713, -+ 0x95bf4a82, -+ 0xe2b87a14, -+ 0x7bb12bae, -+ 0x0cb61b38, -+ 0x92d28e9b, -+ 0xe5d5be0d, -+ 0x7cdcefb7, -+ 0x0bdbdf21, -+ 0x86d3d2d4, -+ 0xf1d4e242, -+ 0x68ddb3f8, -+ 0x1fda836e, -+ 0x81be16cd, -+ 0xf6b9265b, -+ 0x6fb077e1, -+ 0x18b74777, -+ 0x88085ae6, -+ 0xff0f6a70, -+ 0x66063bca, -+ 0x11010b5c, -+ 0x8f659eff, -+ 0xf862ae69, -+ 0x616bffd3, -+ 0x166ccf45, -+ 0xa00ae278, -+ 0xd70dd2ee, -+ 0x4e048354, -+ 0x3903b3c2, -+ 0xa7672661, -+ 0xd06016f7, -+ 0x4969474d, -+ 0x3e6e77db, -+ 0xaed16a4a, -+ 0xd9d65adc, -+ 0x40df0b66, -+ 0x37d83bf0, -+ 0xa9bcae53, -+ 0xdebb9ec5, -+ 0x47b2cf7f, -+ 0x30b5ffe9, -+ 0xbdbdf21c, -+ 0xcabac28a, -+ 0x53b39330, -+ 0x24b4a3a6, -+ 0xbad03605, -+ 0xcdd70693, -+ 0x54de5729, -+ 0x23d967bf, -+ 0xb3667a2e, -+ 0xc4614ab8, -+ 0x5d681b02, -+ 0x2a6f2b94, -+ 0xb40bbe37, -+ 0xc30c8ea1, -+ 0x5a05df1b, -+ 0x2d02ef8d -+}; -+ -+ -+#define GET_MAC_ADDR_CRC(addr, crc) \ -+{ \ -+ uint32_t i; \ -+ uint8_t data; \ -+ \ -+ /* CRC calculation */ \ -+ crc = 0xffffffff; \ -+ for (i=0; i < 6; i++) \ -+ { \ -+ data = (uint8_t)(addr >> ((5-i)*8)); \ -+ crc = crc^data; \ -+ crc = crc_table[crc&0xff] ^ (crc>>8); \ -+ } \ -+} \ -+ -+/* Define a macro for getting the mirrored value of */ -+/* a byte size number. (0x11010011 --> 0x11001011) */ -+/* Sometimes the mirrored value of the CRC is required */ -+static __inline__ uint8_t GetMirror(uint8_t n) -+{ -+ uint8_t mirror[16] = -+ { -+ 0x00, -+ 0x08, -+ 0x04, -+ 0x0c, -+ 0x02, -+ 0x0a, -+ 0x06, -+ 0x0e, -+ 0x01, -+ 0x09, -+ 0x05, -+ 0x0d, -+ 0x03, -+ 0x0b, -+ 0x07, -+ 0x0f -+ }; -+ return ((uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4])))); -+} -+ -+static __inline__ uint32_t GetMirror32(uint32_t n) -+{ -+ return (((uint32_t)GetMirror((uint8_t)(n))<<24) | -+ ((uint32_t)GetMirror((uint8_t)(n>>8))<<16) | -+ ((uint32_t)GetMirror((uint8_t)(n>>16))<<8) | -+ ((uint32_t)GetMirror((uint8_t)(n>>24)))); -+} -+ -+#define MIRROR GetMirror -+#define MIRROR_32 GetMirror32 -+ -+ -+#endif /* __crc_mac_addr_ext_h */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h -@@ -0,0 +1,210 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File dpaa_ext.h -+ -+ @Description DPAA Application Programming Interface. -+*//***************************************************************************/ -+#ifndef __DPAA_EXT_H -+#define __DPAA_EXT_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group DPAA_grp Data Path Acceleration Architecture API -+ -+ @Description DPAA API functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+/**************************************************************************//** -+ @Description Frame descriptor -+*//***************************************************************************/ -+typedef _Packed struct t_DpaaFD { -+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -+ volatile uint8_t liodn; -+ volatile uint8_t bpid; -+ volatile uint8_t elion; -+ volatile uint8_t addrh; -+ volatile uint32_t addrl; -+#else -+ volatile uint32_t addrl; -+ volatile uint8_t addrh; -+ volatile uint8_t elion; -+ volatile uint8_t bpid; -+ volatile uint8_t liodn; -+ #endif -+ volatile uint32_t length; /**< Frame length */ -+ volatile uint32_t status; /**< FD status */ -+} _PackedType t_DpaaFD; -+ -+/**************************************************************************//** -+ @Description enum for defining frame format -+*//***************************************************************************/ -+typedef enum e_DpaaFDFormatType { -+ e_DPAA_FD_FORMAT_TYPE_SHORT_SBSF = 0x0, /**< Simple frame Single buffer; Offset and -+ small length (9b OFFSET, 20b LENGTH) */ -+ e_DPAA_FD_FORMAT_TYPE_LONG_SBSF = 0x2, /**< Simple frame, single buffer; big length -+ (29b LENGTH ,No OFFSET) */ -+ e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF = 0x4, /**< Simple frame, Scatter Gather table; Offset -+ and small length (9b OFFSET, 20b LENGTH) */ -+ e_DPAA_FD_FORMAT_TYPE_LONG_MBSF = 0x6, /**< Simple frame, Scatter Gather table; -+ big length (29b LENGTH ,No OFFSET) */ -+ e_DPAA_FD_FORMAT_TYPE_COMPOUND = 0x1, /**< Compound Frame (29b CONGESTION-WEIGHT -+ No LENGTH or OFFSET) */ -+ e_DPAA_FD_FORMAT_TYPE_DUMMY -+} e_DpaaFDFormatType; -+ -+/**************************************************************************//** -+ @Collection Frame descriptor macros -+*//***************************************************************************/ -+#define DPAA_FD_DD_MASK 0xc0000000 /**< FD DD field mask */ -+#define DPAA_FD_PID_MASK 0x3f000000 /**< FD PID field mask */ -+#define DPAA_FD_ELIODN_MASK 0x0000f000 /**< FD ELIODN field mask */ -+#define DPAA_FD_BPID_MASK 0x00ff0000 /**< FD BPID field mask */ -+#define DPAA_FD_ADDRH_MASK 0x000000ff /**< FD ADDRH field mask */ -+#define DPAA_FD_ADDRL_MASK 0xffffffff /**< FD ADDRL field mask */ -+#define DPAA_FD_FORMAT_MASK 0xe0000000 /**< FD FORMAT field mask */ -+#define DPAA_FD_OFFSET_MASK 0x1ff00000 /**< FD OFFSET field mask */ -+#define DPAA_FD_LENGTH_MASK 0x000fffff /**< FD LENGTH field mask */ -+ -+#define DPAA_FD_GET_ADDRH(fd) ((t_DpaaFD *)fd)->addrh /**< Macro to get FD ADDRH field */ -+#define DPAA_FD_GET_ADDRL(fd) ((t_DpaaFD *)fd)->addrl /**< Macro to get FD ADDRL field */ -+#define DPAA_FD_GET_PHYS_ADDR(fd) ((physAddress_t)(((uint64_t)DPAA_FD_GET_ADDRH(fd) << 32) | (uint64_t)DPAA_FD_GET_ADDRL(fd))) /**< Macro to get FD ADDR field */ -+#define DPAA_FD_GET_FORMAT(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_FORMAT_MASK) >> (31-2)) /**< Macro to get FD FORMAT field */ -+#define DPAA_FD_GET_OFFSET(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_OFFSET_MASK) >> (31-11)) /**< Macro to get FD OFFSET field */ -+#define DPAA_FD_GET_LENGTH(fd) (((t_DpaaFD *)fd)->length & DPAA_FD_LENGTH_MASK) /**< Macro to get FD LENGTH field */ -+#define DPAA_FD_GET_STATUS(fd) ((t_DpaaFD *)fd)->status /**< Macro to get FD STATUS field */ -+#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd)) /**< Macro to get FD ADDR (virtual) */ -+ -+#define DPAA_FD_SET_ADDRH(fd,val) ((t_DpaaFD *)fd)->addrh = (val) /**< Macro to set FD ADDRH field */ -+#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */ -+#define DPAA_FD_SET_ADDR(fd,val) \ -+do { \ -+ uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \ -+ DPAA_FD_SET_ADDRH(fd, ((uint32_t)(physAddr >> 32))); \ -+ DPAA_FD_SET_ADDRL(fd, (uint32_t)physAddr); \ -+} while (0) /**< Macro to set FD ADDR field */ -+#define DPAA_FD_SET_FORMAT(fd,val) (((t_DpaaFD *)fd)->length = ((((t_DpaaFD *)fd)->length & ~DPAA_FD_FORMAT_MASK) | (((val) << (31-2))& DPAA_FD_FORMAT_MASK))) /**< Macro to set FD FORMAT field */ -+#define DPAA_FD_SET_OFFSET(fd,val) (((t_DpaaFD *)fd)->length = ((((t_DpaaFD *)fd)->length & ~DPAA_FD_OFFSET_MASK) | (((val) << (31-11))& DPAA_FD_OFFSET_MASK) )) /**< Macro to set FD OFFSET field */ -+#define DPAA_FD_SET_LENGTH(fd,val) (((t_DpaaFD *)fd)->length = (((t_DpaaFD *)fd)->length & ~DPAA_FD_LENGTH_MASK) | ((val) & DPAA_FD_LENGTH_MASK)) /**< Macro to set FD LENGTH field */ -+#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */ -+/* @} */ -+ -+/**************************************************************************//** -+ @Description Frame Scatter/Gather Table Entry -+*//***************************************************************************/ -+typedef _Packed struct t_DpaaSGTE { -+ volatile uint32_t addrh; /**< Buffer Address high */ -+ volatile uint32_t addrl; /**< Buffer Address low */ -+ volatile uint32_t length; /**< Buffer length */ -+ volatile uint32_t offset; /**< SGTE offset */ -+} _PackedType t_DpaaSGTE; -+ -+#define DPAA_NUM_OF_SG_TABLE_ENTRY 16 -+ -+/**************************************************************************//** -+ @Description Frame Scatter/Gather Table -+*//***************************************************************************/ -+typedef _Packed struct t_DpaaSGT { -+ t_DpaaSGTE tableEntry[DPAA_NUM_OF_SG_TABLE_ENTRY]; -+ /**< Structure that holds information about -+ a single S/G entry. */ -+} _PackedType t_DpaaSGT; -+ -+/**************************************************************************//** -+ @Description Compound Frame Table -+*//***************************************************************************/ -+typedef _Packed struct t_DpaaCompTbl { -+ t_DpaaSGTE outputBuffInfo; /**< Structure that holds information about -+ the compound-frame output buffer; -+ NOTE: this may point to a S/G table */ -+ t_DpaaSGTE inputBuffInfo; /**< Structure that holds information about -+ the compound-frame input buffer; -+ NOTE: this may point to a S/G table */ -+} _PackedType t_DpaaCompTbl; -+ -+/**************************************************************************//** -+ @Collection Frame Scatter/Gather Table Entry macros -+*//***************************************************************************/ -+#define DPAA_SGTE_ADDRH_MASK 0x000000ff /**< SGTE ADDRH field mask */ -+#define DPAA_SGTE_ADDRL_MASK 0xffffffff /**< SGTE ADDRL field mask */ -+#define DPAA_SGTE_E_MASK 0x80000000 /**< SGTE Extension field mask */ -+#define DPAA_SGTE_F_MASK 0x40000000 /**< SGTE Final field mask */ -+#define DPAA_SGTE_LENGTH_MASK 0x3fffffff /**< SGTE LENGTH field mask */ -+#define DPAA_SGTE_BPID_MASK 0x00ff0000 /**< SGTE BPID field mask */ -+#define DPAA_SGTE_OFFSET_MASK 0x00001fff /**< SGTE OFFSET field mask */ -+ -+#define DPAA_SGTE_GET_ADDRH(sgte) (((t_DpaaSGTE *)sgte)->addrh & DPAA_SGTE_ADDRH_MASK) /**< Macro to get SGTE ADDRH field */ -+#define DPAA_SGTE_GET_ADDRL(sgte) ((t_DpaaSGTE *)sgte)->addrl /**< Macro to get SGTE ADDRL field */ -+#define DPAA_SGTE_GET_PHYS_ADDR(sgte) ((physAddress_t)(((uint64_t)DPAA_SGTE_GET_ADDRH(sgte) << 32) | (uint64_t)DPAA_SGTE_GET_ADDRL(sgte))) /**< Macro to get FD ADDR field */ -+#define DPAA_SGTE_GET_EXTENSION(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_E_MASK) >> (31-0)) /**< Macro to get SGTE EXTENSION field */ -+#define DPAA_SGTE_GET_FINAL(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_F_MASK) >> (31-1)) /**< Macro to get SGTE FINAL field */ -+#define DPAA_SGTE_GET_LENGTH(sgte) (((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_LENGTH_MASK) /**< Macro to get SGTE LENGTH field */ -+#define DPAA_SGTE_GET_BPID(sgte) ((((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_BPID_MASK) >> (31-15)) /**< Macro to get SGTE BPID field */ -+#define DPAA_SGTE_GET_OFFSET(sgte) (((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_OFFSET_MASK) /**< Macro to get SGTE OFFSET field */ -+#define DPAA_SGTE_GET_ADDR(sgte) XX_PhysToVirt(DPAA_SGTE_GET_PHYS_ADDR(sgte)) -+ -+#define DPAA_SGTE_SET_ADDRH(sgte,val) (((t_DpaaSGTE *)sgte)->addrh = ((((t_DpaaSGTE *)sgte)->addrh & ~DPAA_SGTE_ADDRH_MASK) | ((val) & DPAA_SGTE_ADDRH_MASK))) /**< Macro to set SGTE ADDRH field */ -+#define DPAA_SGTE_SET_ADDRL(sgte,val) ((t_DpaaSGTE *)sgte)->addrl = (val) /**< Macro to set SGTE ADDRL field */ -+#define DPAA_SGTE_SET_ADDR(sgte,val) \ -+do { \ -+ uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \ -+ DPAA_SGTE_SET_ADDRH(sgte, ((uint32_t)(physAddr >> 32))); \ -+ DPAA_SGTE_SET_ADDRL(sgte, (uint32_t)physAddr); \ -+} while (0) /**< Macro to set SGTE ADDR field */ -+#define DPAA_SGTE_SET_EXTENSION(sgte,val) (((t_DpaaSGTE *)sgte)->length = ((((t_DpaaSGTE *)sgte)->length & ~DPAA_SGTE_E_MASK) | (((val) << (31-0))& DPAA_SGTE_E_MASK))) /**< Macro to set SGTE EXTENSION field */ -+#define DPAA_SGTE_SET_FINAL(sgte,val) (((t_DpaaSGTE *)sgte)->length = ((((t_DpaaSGTE *)sgte)->length & ~DPAA_SGTE_F_MASK) | (((val) << (31-1))& DPAA_SGTE_F_MASK))) /**< Macro to set SGTE FINAL field */ -+#define DPAA_SGTE_SET_LENGTH(sgte,val) (((t_DpaaSGTE *)sgte)->length = (((t_DpaaSGTE *)sgte)->length & ~DPAA_SGTE_LENGTH_MASK) | ((val) & DPAA_SGTE_LENGTH_MASK)) /**< Macro to set SGTE LENGTH field */ -+#define DPAA_SGTE_SET_BPID(sgte,val) (((t_DpaaSGTE *)sgte)->offset = ((((t_DpaaSGTE *)sgte)->offset & ~DPAA_SGTE_BPID_MASK) | (((val) << (31-15))& DPAA_SGTE_BPID_MASK))) /**< Macro to set SGTE BPID field */ -+#define DPAA_SGTE_SET_OFFSET(sgte,val) (((t_DpaaSGTE *)sgte)->offset = ((((t_DpaaSGTE *)sgte)->offset & ~DPAA_SGTE_OFFSET_MASK) | (((val) << (31-31))& DPAA_SGTE_OFFSET_MASK) )) /**< Macro to set SGTE OFFSET field */ -+/* @} */ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+#define DPAA_LIODN_DONT_OVERRIDE (-1) -+ -+/** @} */ /* end of DPAA_grp group */ -+ -+ -+#endif /* __DPAA_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h -@@ -0,0 +1,1731 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File fm_ext.h -+ -+ @Description FM Application Programming Interface. -+*//***************************************************************************/ -+#ifndef __FM_EXT -+#define __FM_EXT -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "dpaa_ext.h" -+#include "fsl_fman_sp.h" -+ -+/**************************************************************************//** -+ @Group FM_grp Frame Manager API -+ -+ @Description FM API functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_lib_grp FM library -+ -+ @Description FM API functions, definitions and enums. -+ -+ The FM module is the main driver module and is a mandatory module -+ for FM driver users. This module must be initialized first prior -+ to any other drivers modules. -+ The FM is a "singleton" module. It is responsible of the common -+ HW modules: FPM, DMA, common QMI and common BMI initializations and -+ run-time control routines. This module must be initialized always -+ when working with any of the FM modules. -+ NOTE - We assume that the FM library will be initialized only by core No. 0! -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description Enum for defining port types -+*//***************************************************************************/ -+typedef enum e_FmPortType { -+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */ -+ e_FM_PORT_TYPE_RX, /**< 1G Rx port */ -+ e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */ -+ e_FM_PORT_TYPE_TX, /**< 1G Tx port */ -+ e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */ -+ e_FM_PORT_TYPE_DUMMY -+} e_FmPortType; -+ -+/**************************************************************************//** -+ @Collection General FM defines -+*//***************************************************************************/ -+#define FM_MAX_NUM_OF_PARTITIONS 64 /**< Maximum number of partitions */ -+#define FM_PHYS_ADDRESS_SIZE 6 /**< FM Physical address size */ -+/* @} */ -+ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(push,1) -+#endif /* defined(__MWERKS__) && ... */ -+ -+/**************************************************************************//** -+ @Description FM physical Address -+*//***************************************************************************/ -+typedef _Packed struct t_FmPhysAddr { -+ volatile uint8_t high; /**< High part of the physical address */ -+ volatile uint32_t low; /**< Low part of the physical address */ -+} _PackedType t_FmPhysAddr; -+ -+/**************************************************************************//** -+ @Description Parse results memory layout -+*//***************************************************************************/ -+typedef _Packed struct t_FmPrsResult { -+ volatile uint8_t lpid; /**< Logical port id */ -+ volatile uint8_t shimr; /**< Shim header result */ -+ volatile uint16_t l2r; /**< Layer 2 result */ -+ volatile uint16_t l3r; /**< Layer 3 result */ -+ volatile uint8_t l4r; /**< Layer 4 result */ -+ volatile uint8_t cplan; /**< Classification plan id */ -+ volatile uint16_t nxthdr; /**< Next Header */ -+ volatile uint16_t cksum; /**< Running-sum */ -+ volatile uint16_t flags_frag_off; /**< Flags & fragment-offset field of the last IP-header */ -+ volatile uint8_t route_type; /**< Routing type field of a IPv6 routing extension header */ -+ volatile uint8_t rhp_ip_valid; /**< Routing Extension Header Present; last bit is IP valid */ -+ volatile uint8_t shim_off[2]; /**< Shim offset */ -+ volatile uint8_t ip_pid_off; /**< IP PID (last IP-proto) offset */ -+ volatile uint8_t eth_off; /**< ETH offset */ -+ volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */ -+ volatile uint8_t vlan_off[2]; /**< VLAN offset */ -+ volatile uint8_t etype_off; /**< ETYPE offset */ -+ volatile uint8_t pppoe_off; /**< PPP offset */ -+ volatile uint8_t mpls_off[2]; /**< MPLS offset */ -+ volatile uint8_t ip_off[2]; /**< IP offset */ -+ volatile uint8_t gre_off; /**< GRE offset */ -+ volatile uint8_t l4_off; /**< Layer 4 offset */ -+ volatile uint8_t nxthdr_off; /**< Parser end point */ -+} _PackedType t_FmPrsResult; -+ -+/**************************************************************************//** -+ @Collection FM Parser results -+*//***************************************************************************/ -+#define FM_PR_L2_VLAN_STACK 0x00000100 /**< Parse Result: VLAN stack */ -+#define FM_PR_L2_ETHERNET 0x00008000 /**< Parse Result: Ethernet*/ -+#define FM_PR_L2_VLAN 0x00004000 /**< Parse Result: VLAN */ -+#define FM_PR_L2_LLC_SNAP 0x00002000 /**< Parse Result: LLC_SNAP */ -+#define FM_PR_L2_MPLS 0x00001000 /**< Parse Result: MPLS */ -+#define FM_PR_L2_PPPoE 0x00000800 /**< Parse Result: PPPoE */ -+/* @} */ -+ -+/**************************************************************************//** -+ @Collection FM Frame descriptor macros -+*//***************************************************************************/ -+#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */ -+#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */ -+#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */ -+#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */ -+#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */ -+#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */ -+ -+#define FM_FD_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Not for Rx-Port! Unsupported Format */ -+#define FM_FD_ERR_LENGTH 0x02000000 /**< Not for Rx-Port! Length Error */ -+#define FM_FD_ERR_DMA 0x01000000 /**< DMA Data error */ -+ -+#define FM_FD_IPR 0x00000001 /**< IPR frame (not error) */ -+ -+#define FM_FD_ERR_IPR_NCSP (0x00100000 | FM_FD_IPR) /**< IPR non-consistent-sp */ -+#define FM_FD_ERR_IPR (0x00200000 | FM_FD_IPR) /**< IPR error */ -+#define FM_FD_ERR_IPR_TO (0x00300000 | FM_FD_IPR) /**< IPR timeout */ -+ -+#ifdef FM_CAPWAP_SUPPORT -+#define FM_FD_ERR_CRE 0x00200000 -+#define FM_FD_ERR_CHE 0x00100000 -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+#define FM_FD_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity -+ error (SGMII and TBI modes), FIFO parity error. PHY -+ Sequence error, PHY error control character detected. */ -+#define FM_FD_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */ -+#define FM_FD_ERR_CLS_DISCARD 0x00020000 /**< classification discard */ -+#define FM_FD_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */ -+#define FM_FD_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */ -+#define FM_FD_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */ -+#define FM_FD_ERR_COLOR_RED 0x00000800 /**< Frame color is red */ -+#define FM_FD_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */ -+#define FM_FD_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */ -+#define FM_FD_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */ -+#define FM_FD_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */ -+#define FM_FD_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */ -+#define FM_FD_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */ -+#define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */ -+ -+#define FM_FD_TX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \ -+ FM_FD_ERR_LENGTH | \ -+ FM_FD_ERR_DMA) /**< TX Error FD bits */ -+ -+#define FM_FD_RX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \ -+ FM_FD_ERR_LENGTH | \ -+ FM_FD_ERR_DMA | \ -+ FM_FD_ERR_IPR | \ -+ FM_FD_ERR_IPR_TO | \ -+ FM_FD_ERR_IPR_NCSP | \ -+ FM_FD_ERR_PHYSICAL | \ -+ FM_FD_ERR_SIZE | \ -+ FM_FD_ERR_CLS_DISCARD | \ -+ FM_FD_ERR_COLOR_RED | \ -+ FM_FD_ERR_COLOR_YELLOW | \ -+ FM_FD_ERR_ILL_PLCR | \ -+ FM_FD_ERR_PLCR_FRAME_LEN | \ -+ FM_FD_ERR_EXTRACTION | \ -+ FM_FD_ERR_NO_SCHEME | \ -+ FM_FD_ERR_KEYSIZE_OVERFLOW | \ -+ FM_FD_ERR_PRS_TIMEOUT | \ -+ FM_FD_ERR_PRS_ILL_INSTRUCT | \ -+ FM_FD_ERR_PRS_HDR_ERR | \ -+ FM_FD_ERR_BLOCK_LIMIT_EXCEEDED) /**< RX Error FD bits */ -+ -+#define FM_FD_RX_STATUS_ERR_NON_FM 0x00400000 /**< non Frame-Manager error */ -+/* @} */ -+ -+/**************************************************************************//** -+ @Description Context A -+*//***************************************************************************/ -+typedef _Packed struct t_FmContextA { -+ volatile uint32_t command; /**< ContextA Command */ -+ volatile uint8_t res0[4]; /**< ContextA Reserved bits */ -+} _PackedType t_FmContextA; -+ -+/**************************************************************************//** -+ @Description Context B -+*//***************************************************************************/ -+typedef uint32_t t_FmContextB; -+ -+/**************************************************************************//** -+ @Collection Special Operation options -+*//***************************************************************************/ -+typedef uint32_t fmSpecialOperations_t; /**< typedef for defining Special Operation options */ -+ -+#define FM_SP_OP_IPSEC 0x80000000 /**< activate features that related to IPSec (e.g fix Eth-type) */ -+#define FM_SP_OP_IPSEC_UPDATE_UDP_LEN 0x40000000 /**< update the UDP-Len after Encryption */ -+#define FM_SP_OP_IPSEC_MANIP 0x20000000 /**< handle the IPSec-manip options */ -+#define FM_SP_OP_RPD 0x10000000 /**< Set the RPD bit */ -+#define FM_SP_OP_DCL4C 0x08000000 /**< Set the DCL4C bit */ -+#define FM_SP_OP_CHECK_SEC_ERRORS 0x04000000 /**< Check SEC errors */ -+#define FM_SP_OP_CLEAR_RPD 0x02000000 /**< Clear the RPD bit */ -+#define FM_SP_OP_CAPWAP_DTLS_ENC 0x01000000 /**< activate features that related to CAPWAP-DTLS post Encryption */ -+#define FM_SP_OP_CAPWAP_DTLS_DEC 0x00800000 /**< activate features that related to CAPWAP-DTLS post Decryption */ -+#define FM_SP_OP_IPSEC_NO_ETH_HDR 0x00400000 /**< activate features that related to IPSec without Eth hdr */ -+/* @} */ -+ -+/**************************************************************************//** -+ @Collection Context A macros -+*//***************************************************************************/ -+#define FM_CONTEXTA_OVERRIDE_MASK 0x80000000 -+#define FM_CONTEXTA_ICMD_MASK 0x40000000 -+#define FM_CONTEXTA_A1_VALID_MASK 0x20000000 -+#define FM_CONTEXTA_MACCMD_MASK 0x00ff0000 -+#define FM_CONTEXTA_MACCMD_VALID_MASK 0x00800000 -+#define FM_CONTEXTA_MACCMD_SECURED_MASK 0x00100000 -+#define FM_CONTEXTA_MACCMD_SC_MASK 0x000f0000 -+#define FM_CONTEXTA_A1_MASK 0x0000ffff -+ -+#define FM_CONTEXTA_GET_OVERRIDE(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_OVERRIDE_MASK) >> (31-0)) -+#define FM_CONTEXTA_GET_ICMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_ICMD_MASK) >> (31-1)) -+#define FM_CONTEXTA_GET_A1_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_VALID_MASK) >> (31-2)) -+#define FM_CONTEXTA_GET_A1(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_MASK) >> (31-31)) -+#define FM_CONTEXTA_GET_MACCMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_MASK) >> (31-15)) -+#define FM_CONTEXTA_GET_MACCMD_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_VALID_MASK) >> (31-8)) -+#define FM_CONTEXTA_GET_MACCMD_SECURED(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SECURED_MASK) >> (31-11)) -+#define FM_CONTEXTA_GET_MACCMD_SECURE_CHANNEL(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SC_MASK) >> (31-15)) -+ -+#define FM_CONTEXTA_SET_OVERRIDE(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_OVERRIDE_MASK) | (((uint32_t)(val) << (31-0)) & FM_CONTEXTA_OVERRIDE_MASK) )) -+#define FM_CONTEXTA_SET_ICMD(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_ICMD_MASK) | (((val) << (31-1)) & FM_CONTEXTA_ICMD_MASK) )) -+#define FM_CONTEXTA_SET_A1_VALID(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_A1_VALID_MASK) | (((val) << (31-2)) & FM_CONTEXTA_A1_VALID_MASK) )) -+#define FM_CONTEXTA_SET_A1(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_A1_MASK) | (((val) << (31-31)) & FM_CONTEXTA_A1_MASK) )) -+#define FM_CONTEXTA_SET_MACCMD(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_MASK) | (((val) << (31-15)) & FM_CONTEXTA_MACCMD_MASK) )) -+#define FM_CONTEXTA_SET_MACCMD_VALID(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_VALID_MASK) | (((val) << (31-8)) & FM_CONTEXTA_MACCMD_VALID_MASK) )) -+#define FM_CONTEXTA_SET_MACCMD_SECURED(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_SECURED_MASK) | (((val) << (31-11)) & FM_CONTEXTA_MACCMD_SECURED_MASK) )) -+#define FM_CONTEXTA_SET_MACCMD_SECURE_CHANNEL(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_SC_MASK) | (((val) << (31-15)) & FM_CONTEXTA_MACCMD_SC_MASK) )) -+/* @} */ -+ -+/**************************************************************************//** -+ @Collection Context B macros -+*//***************************************************************************/ -+#define FM_CONTEXTB_FQID_MASK 0x00ffffff -+ -+#define FM_CONTEXTB_GET_FQID(contextB) (*((t_FmContextB *)contextB) & FM_CONTEXTB_FQID_MASK) -+#define FM_CONTEXTB_SET_FQID(contextB,val) (*((t_FmContextB *)contextB) = ((*((t_FmContextB *)contextB) & ~FM_CONTEXTB_FQID_MASK) | ((val) & FM_CONTEXTB_FQID_MASK))) -+/* @} */ -+ -+#if defined(__MWERKS__) && !defined(__GNUC__) -+#pragma pack(pop) -+#endif /* defined(__MWERKS__) && ... */ -+ -+ -+/**************************************************************************//** -+ @Description FM Exceptions -+*//***************************************************************************/ -+typedef enum e_FmExceptions { -+ e_FM_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */ -+ e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/ -+ e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/ -+ e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/ -+ e_FM_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/ -+ e_FM_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */ -+ e_FM_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */ -+ e_FM_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */ -+ e_FM_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */ -+ e_FM_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */ -+ e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */ -+ e_FM_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */ -+ e_FM_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */ -+ e_FM_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */ -+ e_FM_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */ -+ e_FM_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/ -+ e_FM_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/ -+} e_FmExceptions; -+ -+/**************************************************************************//** -+ @Description Enum for defining port DMA swap mode -+*//***************************************************************************/ -+typedef enum e_FmDmaSwapOption { -+ e_FM_DMA_NO_SWP = FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/ -+ e_FM_DMA_SWP_PPC_LE = FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped -+ in PowerPc Little Endian mode. */ -+ e_FM_DMA_SWP_BE = FMAN_DMA_SWP_BE /**< The transferred data should be swapped -+ in Big Endian mode */ -+} e_FmDmaSwapOption; -+ -+/**************************************************************************//** -+ @Description Enum for defining port DMA cache attributes -+*//***************************************************************************/ -+typedef enum e_FmDmaCacheOption { -+ e_FM_DMA_NO_STASH = FMAN_DMA_NO_STASH, /**< Cacheable, no Allocate (No Stashing) */ -+ e_FM_DMA_STASH = FMAN_DMA_STASH /**< Cacheable and Allocate (Stashing on) */ -+} e_FmDmaCacheOption; -+ -+ -+/**************************************************************************//** -+ @Group FM_init_grp FM Initialization Unit -+ -+ @Description FM Initialization Unit -+ -+ Initialization Flow -+ Initialization of the FM Module will be carried out by the application -+ according to the following sequence: -+ - Calling the configuration routine with basic parameters. -+ - Calling the advance initialization routines to change driver's defaults. -+ - Calling the initialization routine. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function t_FmExceptionsCallback -+ -+ @Description Exceptions user callback routine, will be called upon an -+ exception passing the exception identification. -+ -+ @Param[in] h_App - User's application descriptor. -+ @Param[in] exception - The exception. -+*//***************************************************************************/ -+typedef void (t_FmExceptionsCallback)(t_Handle h_App, -+ e_FmExceptions exception); -+ -+ -+/**************************************************************************//** -+ @Function t_FmBusErrorCallback -+ -+ @Description Bus error user callback routine, will be called upon a -+ bus error, passing parameters describing the errors and the owner. -+ -+ @Param[in] h_App - User's application descriptor. -+ @Param[in] portType - Port type (e_FmPortType) -+ @Param[in] portId - Port id - relative to type. -+ @Param[in] addr - Address that caused the error -+ @Param[in] tnum - Owner of error -+ @Param[in] liodn - Logical IO device number -+*//***************************************************************************/ -+typedef void (t_FmBusErrorCallback) (t_Handle h_App, -+ e_FmPortType portType, -+ uint8_t portId, -+ uint64_t addr, -+ uint8_t tnum, -+ uint16_t liodn); -+ -+/**************************************************************************//** -+ @Description A structure for defining buffer prefix area content. -+*//***************************************************************************/ -+typedef struct t_FmBufferPrefixContent { -+ uint16_t privDataSize; /**< Number of bytes to be left at the beginning -+ of the external buffer; Note that the private-area will -+ start from the base of the buffer address. */ -+ bool passPrsResult; /**< TRUE to pass the parse result to/from the FM; -+ User may use FM_PORT_GetBufferPrsResult() in order to -+ get the parser-result from a buffer. */ -+ bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM -+ User may use FM_PORT_GetBufferTimeStamp() in order to -+ get the parser-result from a buffer. */ -+ bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM -+ User may use FM_PORT_GetBufferHashResult() in order to -+ get the parser-result from a buffer. */ -+ bool passAllOtherPCDInfo;/**< Add all other Internal-Context information: -+ AD, hash-result, key, etc. */ -+ uint16_t dataAlign; /**< 0 to use driver's default alignment [DEFAULT_FM_SP_bufferPrefixContent_dataAlign], -+ other value for selecting a data alignment (must be a power of 2); -+ if write optimization is used, must be >= 16. */ -+ uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size); -+ Note that this field impacts the size of the buffer-prefix -+ (i.e. it pushes the data offset); -+ This field is irrelevant if DPAA_VERSION==10 */ -+} t_FmBufferPrefixContent; -+ -+/**************************************************************************//** -+ @Description A structure of information about each of the external -+ buffer pools used by a port or storage-profile. -+*//***************************************************************************/ -+typedef struct t_FmExtPoolParams { -+ uint8_t id; /**< External buffer pool id */ -+ uint16_t size; /**< External buffer pool buffer size */ -+} t_FmExtPoolParams; -+ -+/**************************************************************************//** -+ @Description A structure for informing the driver about the external -+ buffer pools allocated in the BM and used by a port or a -+ storage-profile. -+*//***************************************************************************/ -+typedef struct t_FmExtPools { -+ uint8_t numOfPoolsUsed; /**< Number of pools use by this port */ -+ t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS]; -+ /**< Parameters for each port */ -+} t_FmExtPools; -+ -+/**************************************************************************//** -+ @Description A structure for defining backup BM Pools. -+*//***************************************************************************/ -+typedef struct t_FmBackupBmPools { -+ uint8_t numOfBackupPools; /**< Number of BM backup pools - -+ must be smaller than the total number of -+ pools defined for the specified port.*/ -+ uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS]; -+ /**< numOfBackupPools pool id's, specifying which -+ pools should be used only as backup. Pool -+ id's specified here must be a subset of the -+ pools used by the specified port.*/ -+} t_FmBackupBmPools; -+ -+/**************************************************************************//** -+ @Description A structure for defining BM pool depletion criteria -+*//***************************************************************************/ -+typedef struct t_FmBufPoolDepletion { -+ bool poolsGrpModeEnable; /**< select mode in which pause frames will be sent after -+ a number of pools (all together!) are depleted */ -+ uint8_t numOfPools; /**< the number of depleted pools that will invoke -+ pause frames transmission. */ -+ bool poolsToConsider[BM_MAX_NUM_OF_POOLS]; -+ /**< For each pool, TRUE if it should be considered for -+ depletion (Note - this pool must be used by this port!). */ -+ bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after -+ a single-pool is depleted; */ -+ bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS]; -+ /**< For each pool, TRUE if it should be considered for -+ depletion (Note - this pool must be used by this port!) */ -+#if (DPAA_VERSION >= 11) -+ bool pfcPrioritiesEn[FM_MAX_NUM_OF_PFC_PRIORITIES]; -+ /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame which is transmitted */ -+#endif /* (DPAA_VERSION >= 11) */ -+} t_FmBufPoolDepletion; -+ -+/**************************************************************************//** -+ @Description A Structure for defining Ucode patch for loading. -+*//***************************************************************************/ -+typedef struct t_FmFirmwareParams { -+ uint32_t size; /**< Size of uCode */ -+ uint32_t *p_Code; /**< A pointer to the uCode */ -+} t_FmFirmwareParams; -+ -+/**************************************************************************//** -+ @Description A Structure for defining FM initialization parameters -+*//***************************************************************************/ -+typedef struct t_FmParams { -+ uint8_t fmId; /**< Index of the FM */ -+ uint8_t guestId; /**< FM Partition Id */ -+ uintptr_t baseAddr; /**< A pointer to base of memory mapped FM registers (virtual); -+ this field is optional when the FM runs in "guest-mode" -+ (i.e. guestId != NCSW_MASTER_ID); in that case, the driver will -+ use the memory-map instead of calling the IPC where possible; -+ NOTE that this should include ALL common registers of the FM including -+ the PCD registers area (i.e. until the VSP pages - 880KB). */ -+ t_Handle h_FmMuram; /**< A handle of an initialized MURAM object, -+ to be used by the FM. */ -+ uint16_t fmClkFreq; /**< In Mhz; -+ Relevant when FM not runs in "guest-mode". */ -+ uint16_t fmMacClkRatio; /**< FM MAC Clock ratio, for backward comparability: -+ when fmMacClkRatio = 0, ratio is 2:1 -+ when fmMacClkRatio = 1, ratio is 1:1 */ -+ t_FmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions; -+ Relevant when FM not runs in "guest-mode". */ -+ t_FmBusErrorCallback *f_BusError; /**< An application callback routine to handle exceptions; -+ Relevant when FM not runs in "guest-mode". */ -+ t_Handle h_App; /**< A handle to an application layer object; This handle will -+ be passed by the driver upon calling the above callbacks; -+ Relevant when FM not runs in "guest-mode". */ -+ int irq; /**< FM interrupt source for normal events; -+ Relevant when FM not runs in "guest-mode". */ -+ int errIrq; /**< FM interrupt source for errors; -+ Relevant when FM not runs in "guest-mode". */ -+ t_FmFirmwareParams firmware; /**< The firmware parameters structure; -+ Relevant when FM not runs in "guest-mode". */ -+ -+#if (DPAA_VERSION >= 11) -+ uintptr_t vspBaseAddr; /**< A pointer to base of memory mapped FM VSP registers (virtual); -+ i.e. up to 24KB, depending on the specific chip. */ -+ uint8_t partVSPBase; /**< The first Virtual-Storage-Profile-id dedicated to this partition. -+ NOTE: this parameter relevant only when working with multiple partitions. */ -+ uint8_t partNumOfVSPs; /**< Number of VSPs dedicated to this partition. -+ NOTE: this parameter relevant only when working with multiple partitions. */ -+#endif /* (DPAA_VERSION >= 11) */ -+} t_FmParams; -+ -+ -+/**************************************************************************//** -+ @Function FM_Config -+ -+ @Description Creates the FM module and returns its handle (descriptor). -+ This descriptor must be passed as first parameter to all other -+ FM function calls. -+ -+ No actual initialization or configuration of FM hardware is -+ done by this routine. All FM parameters get default values that -+ may be changed by calling one or more of the advance config routines. -+ -+ @Param[in] p_FmParams - A pointer to a data structure of mandatory FM parameters -+ -+ @Return A handle to the FM object, or NULL for Failure. -+*//***************************************************************************/ -+t_Handle FM_Config(t_FmParams *p_FmParams); -+ -+/**************************************************************************//** -+ @Function FM_Init -+ -+ @Description Initializes the FM module by defining the software structure -+ and configuring the hardware registers. -+ -+ @Param[in] h_Fm - FM module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_Init(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_Free -+ -+ @Description Frees all resources that were assigned to FM module. -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_Fm - FM module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_Free(t_Handle h_Fm); -+ -+ -+/**************************************************************************//** -+ @Group FM_advanced_init_grp FM Advanced Configuration Unit -+ -+ @Description Advanced configuration routines are optional routines that may -+ be called in order to change the default driver settings. -+ -+ Note: Advanced configuration routines are not available for guest partition. -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description Enum for selecting DMA debug mode -+*//***************************************************************************/ -+typedef enum e_FmDmaDbgCntMode { -+ e_FM_DMA_DBG_NO_CNT = 0, /**< No counting */ -+ e_FM_DMA_DBG_CNT_DONE, /**< Count DONE commands */ -+ e_FM_DMA_DBG_CNT_COMM_Q_EM, /**< count command queue emergency signals */ -+ e_FM_DMA_DBG_CNT_INT_READ_EM, /**< Count Internal Read buffer emergency signal */ -+ e_FM_DMA_DBG_CNT_INT_WRITE_EM, /**< Count Internal Write buffer emergency signal */ -+ e_FM_DMA_DBG_CNT_FPM_WAIT, /**< Count FPM WAIT signal */ -+ e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors. */ -+ e_FM_DMA_DBG_CNT_RAW_WAR_PROT /**< Number of times there was a need for RAW & WAR protection. */ -+} e_FmDmaDbgCntMode; -+ -+/**************************************************************************//** -+ @Description Enum for selecting DMA Cache Override -+*//***************************************************************************/ -+typedef enum e_FmDmaCacheOverride { -+ e_FM_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */ -+ e_FM_DMA_NO_STASH_DATA, /**< Data should not be stashed in system level cache */ -+ e_FM_DMA_MAY_STASH_DATA, /**< Data may be stashed in system level cache */ -+ e_FM_DMA_STASH_DATA /**< Data should be stashed in system level cache */ -+} e_FmDmaCacheOverride; -+ -+/**************************************************************************//** -+ @Description Enum for selecting DMA External Bus Priority -+*//***************************************************************************/ -+typedef enum e_FmDmaExtBusPri { -+ e_FM_DMA_EXT_BUS_NORMAL = 0, /**< Normal priority */ -+ e_FM_DMA_EXT_BUS_EBS, /**< AXI extended bus service priority */ -+ e_FM_DMA_EXT_BUS_SOS, /**< AXI sos priority */ -+ e_FM_DMA_EXT_BUS_EBS_AND_SOS /**< AXI ebs + sos priority */ -+} e_FmDmaExtBusPri; -+ -+/**************************************************************************//** -+ @Description Enum for choosing the field that will be output on AID -+*//***************************************************************************/ -+typedef enum e_FmDmaAidMode { -+ e_FM_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */ -+ e_FM_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */ -+} e_FmDmaAidMode; -+ -+/**************************************************************************//** -+ @Description Enum for selecting FPM Catastrophic error behavior -+*//***************************************************************************/ -+typedef enum e_FmCatastrophicErr { -+ e_FM_CATASTROPHIC_ERR_STALL_PORT = 0, /**< Port_ID is stalled (only reset can release it) */ -+ e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only erroneous task is stalled */ -+} e_FmCatastrophicErr; -+ -+/**************************************************************************//** -+ @Description Enum for selecting FPM DMA Error behavior -+*//***************************************************************************/ -+typedef enum e_FmDmaErr { -+ e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic -+ error (e_FmCatastrophicErr)*/ -+ e_FM_DMA_ERR_REPORT /**< Dma error is just reported */ -+} e_FmDmaErr; -+ -+/**************************************************************************//** -+ @Description Enum for selecting DMA Emergency level by BMI emergency signal -+*//***************************************************************************/ -+typedef enum e_FmDmaEmergencyLevel { -+ e_FM_DMA_EM_EBS = 0, /**< EBS emergency */ -+ e_FM_DMA_EM_SOS /**< SOS emergency */ -+} e_FmDmaEmergencyLevel; -+ -+/**************************************************************************//** -+ @Collection Enum for selecting DMA Emergency options -+*//***************************************************************************/ -+typedef uint32_t fmEmergencyBus_t; /**< DMA emergency options */ -+ -+#define FM_DMA_MURAM_READ_EMERGENCY 0x00800000 /**< Enable emergency for MURAM1 */ -+#define FM_DMA_MURAM_WRITE_EMERGENCY 0x00400000 /**< Enable emergency for MURAM2 */ -+#define FM_DMA_EXT_BUS_EMERGENCY 0x00100000 /**< Enable emergency for external bus */ -+/* @} */ -+ -+/**************************************************************************//** -+ @Description A structure for defining DMA emergency level -+*//***************************************************************************/ -+typedef struct t_FmDmaEmergency { -+ fmEmergencyBus_t emergencyBusSelect; /**< An OR of the busses where emergency -+ should be enabled */ -+ e_FmDmaEmergencyLevel emergencyLevel; /**< EBS/SOS */ -+} t_FmDmaEmergency; -+ -+/**************************************************************************//* -+ @Description structure for defining FM threshold -+*//***************************************************************************/ -+typedef struct t_FmThresholds { -+ uint8_t dispLimit; /**< The number of times a frames may -+ be passed in the FM before assumed to -+ be looping. */ -+ uint8_t prsDispTh; /**< This is the number pf packets that may be -+ queued in the parser dispatch queue*/ -+ uint8_t plcrDispTh; /**< This is the number pf packets that may be -+ queued in the policer dispatch queue*/ -+ uint8_t kgDispTh; /**< This is the number pf packets that may be -+ queued in the keygen dispatch queue*/ -+ uint8_t bmiDispTh; /**< This is the number pf packets that may be -+ queued in the BMI dispatch queue*/ -+ uint8_t qmiEnqDispTh; /**< This is the number pf packets that may be -+ queued in the QMI enqueue dispatch queue*/ -+ uint8_t qmiDeqDispTh; /**< This is the number pf packets that may be -+ queued in the QMI dequeue dispatch queue*/ -+ uint8_t fmCtl1DispTh; /**< This is the number pf packets that may be -+ queued in fmCtl1 dispatch queue*/ -+ uint8_t fmCtl2DispTh; /**< This is the number pf packets that may be -+ queued in fmCtl2 dispatch queue*/ -+} t_FmThresholds; -+ -+/**************************************************************************//* -+ @Description structure for defining DMA thresholds -+*//***************************************************************************/ -+typedef struct t_FmDmaThresholds { -+ uint8_t assertEmergency; /**< When this value is reached, -+ assert emergency (Threshold)*/ -+ uint8_t clearEmergency; /**< After emergency is asserted, it is held -+ until this value is reached (Hystheresis) */ -+} t_FmDmaThresholds; -+ -+/**************************************************************************//** -+ @Function t_FmResetOnInitOverrideCallback -+ -+ @Description FMan specific reset on init user callback routine, -+ will be used to override the standard FMan reset on init procedure -+ -+ @Param[in] h_Fm - FMan handler -+*//***************************************************************************/ -+typedef void (t_FmResetOnInitOverrideCallback)(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_ConfigResetOnInit -+ -+ @Description Define whether to reset the FM before initialization. -+ Change the default configuration [DEFAULT_resetOnInit]. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] enable When TRUE, FM will be reset before any initialization. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_ConfigResetOnInitOverrideCallback -+ -+ @Description Define a special reset of FM before initialization. -+ Change the default configuration [DEFAULT_resetOnInitOverrideCallback]. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] f_ResetOnInitOverride FM specific reset on init user callback routine. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride); -+ -+/**************************************************************************//** -+ @Function FM_ConfigTotalFifoSize -+ -+ @Description Define Total FIFO size for the whole FM. -+ Calling this routine changes the total Fifo size in the internal driver -+ data base from its default configuration [DEFAULT_totalFifoSize] -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] totalFifoSize The selected new value. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize); -+ -+ /**************************************************************************//** -+ @Function FM_ConfigDmaCacheOverride -+ -+ @Description Define cache override mode. -+ Calling this routine changes the cache override mode -+ in the internal driver data base from its default configuration [DEFAULT_cacheOverride] -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] cacheOverride The selected new value. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride); -+ -+/**************************************************************************//** -+ @Function FM_ConfigDmaAidOverride -+ -+ @Description Define DMA AID override mode. -+ Calling this routine changes the AID override mode -+ in the internal driver data base from its default configuration [DEFAULT_aidOverride] -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] aidOverride The selected new value. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride); -+ -+/**************************************************************************//** -+ @Function FM_ConfigDmaAidMode -+ -+ @Description Define DMA AID mode. -+ Calling this routine changes the AID mode in the internal -+ driver data base from its default configuration [DEFAULT_aidMode] -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] aidMode The selected new value. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode); -+ -+/**************************************************************************//** -+ @Function FM_ConfigDmaAxiDbgNumOfBeats -+ -+ @Description Define DMA AXI number of beats. -+ Calling this routine changes the AXI number of beats in the internal -+ driver data base from its default configuration [DEFAULT_axiDbgNumOfBeats] -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] axiDbgNumOfBeats The selected new value. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats); -+ -+/**************************************************************************//** -+ @Function FM_ConfigDmaCamNumOfEntries -+ -+ @Description Define number of CAM entries. -+ Calling this routine changes the number of CAM entries in the internal -+ driver data base from its default configuration [DEFAULT_dmaCamNumOfEntries]. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] numOfEntries The selected new value. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries); -+ -+/**************************************************************************//** -+ @Function FM_ConfigEnableCounters -+ -+ @Description Obsolete, always return E_OK. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_ConfigEnableCounters(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_ConfigDmaDbgCounter -+ -+ @Description Define DMA debug counter. -+ Calling this routine changes the number of the DMA debug counter in the internal -+ driver data base from its default configuration [DEFAULT_dmaDbgCntMode]. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] fmDmaDbgCntMode An enum selecting the debug counter mode. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode); -+ -+/**************************************************************************//** -+ @Function FM_ConfigDmaStopOnBusErr -+ -+ @Description Define bus error behavior. -+ Calling this routine changes the bus error behavior definition -+ in the internal driver data base from its default -+ configuration [DEFAULT_dmaStopOnBusError]. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] stop TRUE to stop on bus error, FALSE to continue. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ Only if bus error is enabled. -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop); -+ -+/**************************************************************************//** -+ @Function FM_ConfigDmaEmergency -+ -+ @Description Define DMA emergency. -+ Calling this routine changes the DMA emergency definition -+ in the internal driver data base from its default -+ configuration where's it's disabled. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] p_Emergency An OR mask of all required options. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency); -+ -+/**************************************************************************//** -+ @Function FM_ConfigDmaErr -+ -+ @Description DMA error treatment. -+ Calling this routine changes the DMA error treatment -+ in the internal driver data base from its default -+ configuration [DEFAULT_dmaErr]. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] dmaErr The selected new choice. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr); -+ -+/**************************************************************************//** -+ @Function FM_ConfigCatastrophicErr -+ -+ @Description Define FM behavior on catastrophic error. -+ Calling this routine changes the FM behavior on catastrophic -+ error in the internal driver data base from its default -+ [DEFAULT_catastrophicErr]. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] catastrophicErr The selected new choice. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr); -+ -+/**************************************************************************//** -+ @Function FM_ConfigEnableMuramTestMode -+ -+ @Description Enable MURAM test mode. -+ Calling this routine changes the internal driver data base -+ from its default selection of test mode where it's disabled. -+ This routine is only avaiable on old FM revisions (FMan v2). -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_ConfigEnableIramTestMode -+ -+ @Description Enable IRAM test mode. -+ Calling this routine changes the internal driver data base -+ from its default selection of test mode where it's disabled. -+ This routine is only avaiable on old FM revisions (FMan v2). -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_ConfigHaltOnExternalActivation -+ -+ @Description Define FM behavior on external halt activation. -+ Calling this routine changes the FM behavior on external halt -+ activation in the internal driver data base from its default -+ [DEFAULT_haltOnExternalActivation]. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] enable TRUE to enable halt on external halt -+ activation. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_ConfigHaltOnUnrecoverableEccError -+ -+ @Description Define FM behavior on external halt activation. -+ Calling this routine changes the FM behavior on unrecoverable -+ ECC error in the internal driver data base from its default -+ [DEFAULT_haltOnUnrecoverableEccError]. -+ This routine is only avaiable on old FM revisions (FMan v2). -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] enable TRUE to enable halt on unrecoverable Ecc error -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_ConfigException -+ -+ @Description Define FM exceptions. -+ Calling this routine changes the exceptions defaults in the -+ internal driver data base where all exceptions are enabled. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] exception The exception to be selected. -+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_ConfigExternalEccRamsEnable -+ -+ @Description Select external ECC enabling. -+ Calling this routine changes the ECC enabling control in the internal -+ driver data base from its default [DEFAULT_externalEccRamsEnable]. -+ When this option is enabled Rams ECC enabling is not effected -+ by FM_EnableRamsEcc/FM_DisableRamsEcc, but by a JTAG. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] enable TRUE to enable this option. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_ConfigTnumAgingPeriod -+ -+ @Description Define Tnum aging period. -+ Calling this routine changes the Tnum aging of dequeue TNUMs -+ in the QMI in the internal driver data base from its default -+ [DEFAULT_tnumAgingPeriod]. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] tnumAgingPeriod Tnum Aging Period in microseconds. -+ Note that period is recalculated in units of -+ 64 FM clocks. Driver will pick the closest -+ possible period. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+ NOTE that if some MAC is configured for PFC, '0' value is NOT -+ allowed. -+*//***************************************************************************/ -+t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod); -+ -+/**************************************************************************//* -+ @Function FM_ConfigDmaEmergencySmoother -+ -+ @Description Define DMA emergency smoother. -+ Calling this routine changes the definition of the minimum -+ amount of DATA beats transferred on the AXI READ and WRITE -+ ports before lowering the emergency level. -+ By default smoother is disabled. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] emergencyCnt emergency switching counter. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt); -+ -+/**************************************************************************//* -+ @Function FM_ConfigThresholds -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default FM threshold configuration: -+ dispLimit: [DEFAULT_dispLimit] -+ prsDispTh: [DEFAULT_prsDispTh] -+ plcrDispTh: [DEFAULT_plcrDispTh] -+ kgDispTh: [DEFAULT_kgDispTh] -+ bmiDispTh: [DEFAULT_bmiDispTh] -+ qmiEnqDispTh: [DEFAULT_qmiEnqDispTh] -+ qmiDeqDispTh: [DEFAULT_qmiDeqDispTh] -+ fmCtl1DispTh: [DEFAULT_fmCtl1DispTh] -+ fmCtl2DispTh: [DEFAULT_fmCtl2DispTh] -+ -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] p_FmThresholds A structure of threshold parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds); -+ -+/**************************************************************************//* -+ @Function FM_ConfigDmaSosEmergencyThreshold -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default dma SOS emergency configuration [DEFAULT_dmaSosEmergency] -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] dmaSosEmergency The selected new value. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency); -+ -+/**************************************************************************//* -+ @Function FM_ConfigDmaWriteBufThresholds -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default configuration of DMA write buffer threshold -+ assertEmergency: [DEFAULT_dmaWriteIntBufLow] -+ clearEmergency: [DEFAULT_dmaWriteIntBufHigh] -+ This routine is only avaiable on old FM revisions (FMan v2). -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior - -+ When 'assertEmergency' value is reached, emergency is asserted, -+ then it is held until 'clearEmergency' value is reached. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds); -+ -+ /**************************************************************************//* -+ @Function FM_ConfigDmaCommQThresholds -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default configuration of DMA command queue threshold -+ assertEmergency: [DEFAULT_dmaCommQLow] -+ clearEmergency: [DEFAULT_dmaCommQHigh] -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior - -+ When 'assertEmergency' value is reached, emergency is asserted, -+ then it is held until 'clearEmergency' value is reached.. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds); -+ -+/**************************************************************************//* -+ @Function FM_ConfigDmaReadBufThresholds -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default configuration of DMA read buffer threshold -+ assertEmergency: [DEFAULT_dmaReadIntBufLow] -+ clearEmergency: [DEFAULT_dmaReadIntBufHigh] -+ This routine is only avaiable on old FM revisions (FMan v2). -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior - -+ When 'assertEmergency' value is reached, emergency is asserted, -+ then it is held until 'clearEmergency' value is reached.. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds); -+ -+/**************************************************************************//* -+ @Function FM_ConfigDmaWatchdog -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default watchdog configuration, which is disabled -+ [DEFAULT_dmaWatchdog]. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] watchDogValue The selected new value - in microseconds. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue); -+ -+/** @} */ /* end of FM_advanced_init_grp group */ -+/** @} */ /* end of FM_init_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_runtime_control_grp FM Runtime Control Unit -+ -+ @Description FM Runtime control unit API functions, definitions and enums. -+ The FM driver provides a set of control routines. -+ These routines may only be called after the module was fully -+ initialized (both configuration and initialization routines were -+ called). They are typically used to get information from hardware -+ (status, counters/statistics, revision etc.), to modify a current -+ state or to force/enable a required action. Run-time control may -+ be called whenever necessary and as many times as needed. -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Collection General FM defines. -+*//***************************************************************************/ -+#define FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \ -+ FM_MAX_NUM_OF_1G_RX_PORTS + \ -+ FM_MAX_NUM_OF_10G_RX_PORTS + \ -+ FM_MAX_NUM_OF_1G_TX_PORTS + \ -+ FM_MAX_NUM_OF_10G_TX_PORTS) /**< Number of available FM ports */ -+/* @} */ -+ -+/**************************************************************************//* -+ @Description A Structure for Port bandwidth requirement. Port is identified -+ by type and relative id. -+*//***************************************************************************/ -+typedef struct t_FmPortBandwidth { -+ e_FmPortType type; /**< FM port type */ -+ uint8_t relativePortId; /**< Type relative port id */ -+ uint8_t bandwidth; /**< bandwidth - (in term of percents) */ -+} t_FmPortBandwidth; -+ -+/**************************************************************************//* -+ @Description A Structure containing an array of Port bandwidth requirements. -+ The user should state the ports requiring bandwidth in terms of -+ percentage - i.e. all port's bandwidths in the array must add -+ up to 100. -+*//***************************************************************************/ -+typedef struct t_FmPortsBandwidthParams { -+ uint8_t numOfPorts; /**< The number of relevant ports, which is the -+ number of valid entries in the array below */ -+ t_FmPortBandwidth portsBandwidths[FM_MAX_NUM_OF_VALID_PORTS]; -+ /**< for each port, it's bandwidth (all port's -+ bandwidths must add up to 100.*/ -+} t_FmPortsBandwidthParams; -+ -+/**************************************************************************//** -+ @Description DMA Emergency control on MURAM -+*//***************************************************************************/ -+typedef enum e_FmDmaMuramPort { -+ e_FM_DMA_MURAM_PORT_WRITE, /**< MURAM write port */ -+ e_FM_DMA_MURAM_PORT_READ /**< MURAM read port */ -+} e_FmDmaMuramPort; -+ -+/**************************************************************************//** -+ @Description Enum for defining FM counters -+*//***************************************************************************/ -+typedef enum e_FmCounters { -+ e_FM_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI total enqueued frames counter */ -+ e_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */ -+ e_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */ -+ e_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */ -+ e_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */ -+ e_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */ -+ e_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */ -+ e_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */ -+ e_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */ -+ e_FM_COUNTERS_DEQ_CONFIRM /**< QMI dequeue confirm counter */ -+} e_FmCounters; -+ -+/**************************************************************************//** -+ @Description A Structure for returning FM revision information -+*//***************************************************************************/ -+typedef struct t_FmRevisionInfo { -+ uint8_t majorRev; /**< Major revision */ -+ uint8_t minorRev; /**< Minor revision */ -+} t_FmRevisionInfo; -+ -+/**************************************************************************//** -+ @Description A Structure for returning FM ctrl code revision information -+*//***************************************************************************/ -+typedef struct t_FmCtrlCodeRevisionInfo { -+ uint16_t packageRev; /**< Package revision */ -+ uint8_t majorRev; /**< Major revision */ -+ uint8_t minorRev; /**< Minor revision */ -+} t_FmCtrlCodeRevisionInfo; -+ -+/**************************************************************************//** -+ @Description A Structure for defining DMA status -+*//***************************************************************************/ -+typedef struct t_FmDmaStatus { -+ bool cmqNotEmpty; /**< Command queue is not empty */ -+ bool busError; /**< Bus error occurred */ -+ bool readBufEccError; /**< Double ECC error on buffer Read (Valid for FM rev < 6)*/ -+ bool writeBufEccSysError; /**< Double ECC error on buffer write from system side (Valid for FM rev < 6)*/ -+ bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side (Valid for FM rev < 6) */ -+ bool singlePortEccError; /**< Single Port ECC error from FM side (Valid for FM rev >= 6)*/ -+} t_FmDmaStatus; -+ -+/**************************************************************************//** -+ @Description A Structure for obtaining FM controller monitor values -+*//***************************************************************************/ -+typedef struct t_FmCtrlMon { -+ uint8_t percentCnt[2]; /**< Percentage value */ -+} t_FmCtrlMon; -+ -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+/**************************************************************************//** -+ @Function FM_DumpRegs -+ -+ @Description Dumps all FM registers -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+t_Error FM_DumpRegs(t_Handle h_Fm); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+/**************************************************************************//** -+ @Function FM_SetException -+ -+ @Description Calling this routine enables/disables the specified exception. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] exception The exception to be selected. -+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_EnableRamsEcc -+ -+ @Description Enables ECC mechanism for all the different FM RAM's; E.g. IRAM, -+ MURAM, Parser, Keygen, Policer, etc. -+ Note: -+ If FM_ConfigExternalEccRamsEnable was called to enable external -+ setting of ECC, this routine effects IRAM ECC only. -+ This routine is also called by the driver if an ECC exception is -+ enabled. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_EnableRamsEcc(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_DisableRamsEcc -+ -+ @Description Disables ECC mechanism for all the different FM RAM's; E.g. IRAM, -+ MURAM, Parser, Keygen, Policer, etc. -+ Note: -+ If FM_ConfigExternalEccRamsEnable was called to enable external -+ setting of ECC, this routine effects IRAM ECC only. -+ In opposed to FM_EnableRamsEcc, this routine must be called -+ explicitly to disable all Rams ECC. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Config() and before FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_DisableRamsEcc(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_GetRevision -+ -+ @Description Returns the FM revision -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[out] p_FmRevisionInfo A structure of revision information parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo); -+ -+/**************************************************************************//** -+ @Function FM_GetFmanCtrlCodeRevision -+ -+ @Description Returns the Fman controller code revision -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[out] p_RevisionInfo A structure of revision information parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo); -+ -+/**************************************************************************//** -+ @Function FM_GetCounter -+ -+ @Description Reads one of the FM counters. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] counter The requested counter. -+ -+ @Return Counter's current value. -+ -+ @Cautions Allowed only following FM_Init(). -+ Note that it is user's responsibility to call this routine only -+ for enabled counters, and there will be no indication if a -+ disabled counter is accessed. -+*//***************************************************************************/ -+uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter); -+ -+/**************************************************************************//** -+ @Function FM_ModifyCounter -+ -+ @Description Sets a value to an enabled counter. Use "0" to reset the counter. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] counter The requested counter. -+ @Param[in] val The requested value to be written into the counter. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val); -+ -+/**************************************************************************//** -+ @Function FM_Resume -+ -+ @Description Release FM after halt FM command or after unrecoverable ECC error. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+void FM_Resume(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_SetDmaEmergency -+ -+ @Description Manual emergency set -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] muramPort MURAM direction select. -+ @Param[in] enable TRUE to manually enable emergency, FALSE to disable. -+ -+ @Return None. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_SetDmaExtBusPri -+ -+ @Description Set the DMA external bus priority -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] pri External bus priority select -+ -+ @Return None. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri); -+ -+/**************************************************************************//** -+ @Function FM_GetDmaStatus -+ -+ @Description Reads the DMA current status -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[out] p_FmDmaStatus A structure of DMA status parameters. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus); -+ -+/**************************************************************************//** -+ @Function FM_ErrorIsr -+ -+ @Description FM interrupt-service-routine for errors. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; E_EMPTY if no errors found in register, other -+ error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ErrorIsr(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_EventIsr -+ -+ @Description FM interrupt-service-routine for normal events. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+void FM_EventIsr(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_GetSpecialOperationCoding -+ -+ @Description Return a specific coding according to the input mask. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] spOper special operation mask. -+ @Param[out] p_SpOperCoding special operation code. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm, -+ fmSpecialOperations_t spOper, -+ uint8_t *p_SpOperCoding); -+ -+/**************************************************************************//** -+ @Function FM_CtrlMonStart -+ -+ @Description Start monitoring utilization of all available FM controllers. -+ -+ In order to obtain FM controllers utilization the following sequence -+ should be used: -+ -# FM_CtrlMonStart() -+ -# FM_CtrlMonStop() -+ -# FM_CtrlMonGetCounters() - issued for each FM controller -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID). -+*//***************************************************************************/ -+t_Error FM_CtrlMonStart(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_CtrlMonStop -+ -+ @Description Stop monitoring utilization of all available FM controllers. -+ -+ In order to obtain FM controllers utilization the following sequence -+ should be used: -+ -# FM_CtrlMonStart() -+ -# FM_CtrlMonStop() -+ -# FM_CtrlMonGetCounters() - issued for each FM controller -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID). -+*//***************************************************************************/ -+t_Error FM_CtrlMonStop(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_CtrlMonGetCounters -+ -+ @Description Obtain FM controller utilization parameters. -+ -+ In order to obtain FM controllers utilization the following sequence -+ should be used: -+ -# FM_CtrlMonStart() -+ -# FM_CtrlMonStop() -+ -# FM_CtrlMonGetCounters() - issued for each FM controller -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] fmCtrlIndex FM Controller index for that utilization results -+ are requested. -+ @Param[in] p_Mon Pointer to utilization results structure. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID). -+*//***************************************************************************/ -+t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon); -+ -+ -+/**************************************************************************//* -+ @Function FM_ForceIntr -+ -+ @Description Causes an interrupt event on the requested source. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] exception An exception to be forced. -+ -+ @Return E_OK on success; Error code if the exception is not enabled, -+ or is not able to create interrupt. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception); -+ -+/**************************************************************************//* -+ @Function FM_SetPortsBandwidth -+ -+ @Description Sets relative weights between ports when accessing common resources. -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e. -+ total must equal 100. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth); -+ -+/**************************************************************************//* -+ @Function FM_GetMuramHandle -+ -+ @Description Gets the corresponding MURAM handle -+ -+ @Param[in] h_Fm A handle to an FM Module. -+ -+ @Return MURAM handle; NULL otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Handle FM_GetMuramHandle(t_Handle h_Fm); -+ -+/** @} */ /* end of FM_runtime_control_grp group */ -+/** @} */ /* end of FM_lib_grp group */ -+/** @} */ /* end of FM_grp group */ -+ -+ -+#ifdef NCSW_BACKWARD_COMPATIBLE_API -+typedef t_FmFirmwareParams t_FmPcdFirmwareParams; -+typedef t_FmBufferPrefixContent t_FmPortBufferPrefixContent; -+typedef t_FmExtPoolParams t_FmPortExtPoolParams; -+typedef t_FmExtPools t_FmPortExtPools; -+typedef t_FmBackupBmPools t_FmPortBackupBmPools; -+typedef t_FmBufPoolDepletion t_FmPortBufPoolDepletion; -+typedef e_FmDmaSwapOption e_FmPortDmaSwapOption; -+typedef e_FmDmaCacheOption e_FmPortDmaCacheOption; -+ -+#define FM_CONTEXTA_GET_OVVERIDE FM_CONTEXTA_GET_OVERRIDE -+#define FM_CONTEXTA_SET_OVVERIDE FM_CONTEXTA_SET_OVERRIDE -+ -+#define e_FM_EX_BMI_PIPELINE_ECC e_FM_EX_BMI_STORAGE_PROFILE_ECC -+#define e_FM_PORT_DMA_NO_SWP e_FM_DMA_NO_SWP -+#define e_FM_PORT_DMA_SWP_PPC_LE e_FM_DMA_SWP_PPC_LE -+#define e_FM_PORT_DMA_SWP_BE e_FM_DMA_SWP_BE -+#define e_FM_PORT_DMA_NO_STASH e_FM_DMA_NO_STASH -+#define e_FM_PORT_DMA_STASH e_FM_DMA_STASH -+#endif /* NCSW_BACKWARD_COMPATIBLE_API */ -+ -+ -+#endif /* __FM_EXT */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h -@@ -0,0 +1,859 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File fm_mac_ext.h -+ -+ @Description FM MAC ... -+*//***************************************************************************/ -+#ifndef __FM_MAC_EXT_H -+#define __FM_MAC_EXT_H -+ -+#include "std_ext.h" -+#include "enet_ext.h" -+ -+ -+/**************************************************************************//** -+ -+ @Group FM_grp Frame Manager API -+ -+ @Description FM API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_mac_grp FM MAC -+ -+ @Description FM MAC API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+#define FM_MAC_NO_PFC 0xff -+ -+ -+/**************************************************************************//** -+ @Description FM MAC Exceptions -+*//***************************************************************************/ -+typedef enum e_FmMacExceptions { -+ e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0 /**< 10GEC MDIO scan event interrupt */ -+ ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL /**< 10GEC MDIO command completion interrupt */ -+ ,e_FM_MAC_EX_10G_REM_FAULT /**< 10GEC, mEMAC Remote fault interrupt */ -+ ,e_FM_MAC_EX_10G_LOC_FAULT /**< 10GEC, mEMAC Local fault interrupt */ -+ ,e_FM_MAC_EX_10G_1TX_ECC_ER /**< 10GEC, mEMAC Transmit frame ECC error interrupt */ -+ ,e_FM_MAC_EX_10G_TX_FIFO_UNFL /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */ -+ ,e_FM_MAC_EX_10G_TX_FIFO_OVFL /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */ -+ ,e_FM_MAC_EX_10G_TX_ER /**< 10GEC Transmit frame error interrupt */ -+ ,e_FM_MAC_EX_10G_RX_FIFO_OVFL /**< 10GEC, mEMAC Receive FIFO overflow interrupt */ -+ ,e_FM_MAC_EX_10G_RX_ECC_ER /**< 10GEC, mEMAC Receive frame ECC error interrupt */ -+ ,e_FM_MAC_EX_10G_RX_JAB_FRM /**< 10GEC Receive jabber frame interrupt */ -+ ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM /**< 10GEC Receive oversized frame interrupt */ -+ ,e_FM_MAC_EX_10G_RX_RUNT_FRM /**< 10GEC Receive runt frame interrupt */ -+ ,e_FM_MAC_EX_10G_RX_FRAG_FRM /**< 10GEC Receive fragment frame interrupt */ -+ ,e_FM_MAC_EX_10G_RX_LEN_ER /**< 10GEC Receive payload length error interrupt */ -+ ,e_FM_MAC_EX_10G_RX_CRC_ER /**< 10GEC Receive CRC error interrupt */ -+ ,e_FM_MAC_EX_10G_RX_ALIGN_ER /**< 10GEC Receive alignment error interrupt */ -+ ,e_FM_MAC_EX_1G_BAB_RX /**< dTSEC Babbling receive error */ -+ ,e_FM_MAC_EX_1G_RX_CTL /**< dTSEC Receive control (pause frame) interrupt */ -+ ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET /**< dTSEC Graceful transmit stop complete */ -+ ,e_FM_MAC_EX_1G_BAB_TX /**< dTSEC Babbling transmit error */ -+ ,e_FM_MAC_EX_1G_TX_CTL /**< dTSEC Transmit control (pause frame) interrupt */ -+ ,e_FM_MAC_EX_1G_TX_ERR /**< dTSEC Transmit error */ -+ ,e_FM_MAC_EX_1G_LATE_COL /**< dTSEC Late collision */ -+ ,e_FM_MAC_EX_1G_COL_RET_LMT /**< dTSEC Collision retry limit */ -+ ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN /**< dTSEC Transmit FIFO underrun */ -+ ,e_FM_MAC_EX_1G_MAG_PCKT /**< dTSEC Magic Packet detection */ -+ ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET /**< dTSEC MII management read completion */ -+ ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET /**< dTSEC MII management write completion */ -+ ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET /**< dTSEC Graceful receive stop complete */ -+ ,e_FM_MAC_EX_1G_TX_DATA_ERR /**< dTSEC Internal data error on transmit */ -+ ,e_FM_MAC_EX_1G_RX_DATA_ERR /**< dTSEC Internal data error on receive */ -+ ,e_FM_MAC_EX_1G_1588_TS_RX_ERR /**< dTSEC Time-Stamp Receive Error */ -+ ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL /**< dTSEC MIB counter overflow */ -+ ,e_FM_MAC_EX_TS_FIFO_ECC_ERR /**< mEMAC Time-stamp FIFO ECC error interrupt; -+ not supported on T4240/B4860 rev1 chips */ -+ ,e_FM_MAC_EX_MAGIC_PACKET_INDICATION = e_FM_MAC_EX_1G_MAG_PCKT -+ /**< mEMAC Magic Packet Indication Interrupt */ -+} e_FmMacExceptions; -+ -+/**************************************************************************//** -+ @Description TM MAC statistics level -+*//***************************************************************************/ -+typedef enum e_FmMacStatisticsLevel { -+ e_FM_MAC_NONE_STATISTICS = 0, /**< No statistics */ -+ e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; Optimized for performance */ -+ e_FM_MAC_FULL_STATISTICS /**< All counters available; Not optimized for performance */ -+} e_FmMacStatisticsLevel; -+ -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Priority Flow Control Parameters -+*//***************************************************************************/ -+typedef struct t_FmMacPfcParams { -+ bool pfcEnable; /**< Enable/Disable PFC */ -+ -+ uint16_t pauseQuanta[FM_MAX_NUM_OF_PFC_PRIORITIES]; /**< Pause Quanta per priority to be sent in a pause frame. Each quanta represents a 512 bit-times*/ -+ -+ uint16_t pauseThresholdQuanta[FM_MAX_NUM_OF_PFC_PRIORITIES];/**< Pause threshold per priority, when timer passes this threshold time a PFC frames is sent again if the port is still congested or BM pool in depletion*/ -+ -+ -+} t_FmMacPfcParams; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Function t_FmMacExceptionCallback -+ -+ @Description Fm Mac Exception Callback from FM MAC to the user -+ -+ @Param[in] h_App - Handle to the upper layer handler -+ -+ @Param[in] exceptions - The exception that occurred -+ -+ @Return void. -+*//***************************************************************************/ -+typedef void (t_FmMacExceptionCallback)(t_Handle h_App, e_FmMacExceptions exceptions); -+ -+ -+/**************************************************************************//** -+ @Description TM MAC statistics rfc3635 -+*//***************************************************************************/ -+typedef struct t_FmMacStatistics { -+/* RMON */ -+ uint64_t eStatPkts64; /**< r-10G tr-DT 64 byte frame counter */ -+ uint64_t eStatPkts65to127; /**< r-10G 65 to 127 byte frame counter */ -+ uint64_t eStatPkts128to255; /**< r-10G 128 to 255 byte frame counter */ -+ uint64_t eStatPkts256to511; /**< r-10G 256 to 511 byte frame counter */ -+ uint64_t eStatPkts512to1023; /**< r-10G 512 to 1023 byte frame counter */ -+ uint64_t eStatPkts1024to1518; /**< r-10G 1024 to 1518 byte frame counter */ -+ uint64_t eStatPkts1519to1522; /**< r-10G 1519 to 1522 byte good frame count */ -+/* */ -+ uint64_t eStatFragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/ -+ uint64_t eStatJabbers; /**< Total number of packets longer than valid maximum length octets */ -+ uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client (during receive). */ -+ uint64_t eStatCRCAlignErrors; /**< Incremented when frames of correct length but with CRC error are received.*/ -+ uint64_t eStatUndersizePkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed; -+ This count does not include range length errors */ -+ uint64_t eStatOversizePkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains -+ a valid FCS and otherwise well formed */ -+/* Pause */ -+ uint64_t teStatPause; /**< Pause MAC Control received */ -+ uint64_t reStatPause; /**< Pause MAC Control sent */ -+/* MIB II */ -+ uint64_t ifInOctets; /**< Total number of byte received. */ -+ uint64_t ifInPkts; /**< Total number of packets received.*/ -+ uint64_t ifInUcastPkts; /**< Total number of unicast frame received; -+ NOTE: this counter is not supported on dTSEC MAC */ -+ uint64_t ifInMcastPkts; /**< Total number of multicast frame received*/ -+ uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */ -+ uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX. */ -+ uint64_t ifInErrors; /**< Number of frames received with error: -+ - FIFO Overflow Error -+ - CRC Error -+ - Frame Too Long Error -+ - Alignment Error -+ - The dedicated Error Code (0xfe, not a code error) was received */ -+ uint64_t ifOutOctets; /**< Total number of byte sent. */ -+ uint64_t ifOutPkts; /**< Total number of packets sent .*/ -+ uint64_t ifOutUcastPkts; /**< Total number of unicast frame sent; -+ NOTE: this counter is not supported on dTSEC MAC */ -+ uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */ -+ uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */ -+ uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/ -+ uint64_t ifOutErrors; /**< Number of frames transmitted with error: -+ - FIFO Overflow Error -+ - FIFO Underflow Error -+ - Other */ -+} t_FmMacStatistics; -+ -+ -+/**************************************************************************//** -+ @Group FM_mac_init_grp FM MAC Initialization Unit -+ -+ @Description FM MAC Initialization Unit -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description FM MAC config input -+*//***************************************************************************/ -+typedef struct t_FmMacParams { -+ uintptr_t baseAddr; /**< Base of memory mapped FM MAC registers */ -+ t_EnetAddr addr; /**< MAC address of device; First octet is sent first */ -+ uint8_t macId; /**< MAC ID; -+ numbering of dTSEC and 1G-mEMAC: -+ 0 - FM_MAX_NUM_OF_1G_MACS; -+ numbering of 10G-MAC (TGEC) and 10G-mEMAC: -+ 0 - FM_MAX_NUM_OF_10G_MACS */ -+ e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed); -+ Note that the speed should indicate the maximum rate that -+ this MAC should support rather than the actual speed; -+ i.e. user should use the FM_MAC_AdjustLink() routine to -+ provide accurate speed; -+ In case of mEMAC RGMII mode, the MAC is configured to RGMII -+ automatic mode, where actual speed/duplex mode information -+ is provided by PHY automatically in-band; FM_MAC_AdjustLink() -+ function should be used to switch to manual RGMII speed/duplex mode -+ configuration if RGMII PHY doesn't support in-band status signaling; -+ In addition, in mEMAC, in case where user is using the higher MACs -+ (i.e. the MACs that should support 10G), user should pass here -+ speed=10000 even if the interface is not allowing that (e.g. SGMII). */ -+ t_Handle h_Fm; /**< A handle to the FM object this port related to */ -+ int mdioIrq; /**< MDIO exceptions interrupt source - not valid for all -+ MACs; MUST be set to 'NO_IRQ' for MACs that don't have -+ mdio-irq, or for polling */ -+ t_FmMacExceptionCallback *f_Event; /**< MDIO Events Callback Routine */ -+ t_FmMacExceptionCallback *f_Exception; /**< Exception Callback Routine */ -+ t_Handle h_App; /**< A handle to an application layer object; This handle will -+ be passed by the driver upon calling the above callbacks */ -+} t_FmMacParams; -+ -+ -+/**************************************************************************//** -+ @Function FM_MAC_Config -+ -+ @Description Creates descriptor for the FM MAC module. -+ -+ The routine returns a handle (descriptor) to the FM MAC object. -+ This descriptor must be passed as first parameter to all other -+ FM MAC function calls. -+ -+ No actual initialization or configuration of FM MAC hardware is -+ done by this routine. -+ -+ @Param[in] p_FmMacParam - Pointer to data structure of parameters -+ -+ @Retval Handle to FM MAC object, or NULL for Failure. -+*//***************************************************************************/ -+t_Handle FM_MAC_Config(t_FmMacParams *p_FmMacParam); -+ -+/**************************************************************************//** -+ @Function FM_MAC_Init -+ -+ @Description Initializes the FM MAC module -+ -+ @Param[in] h_FmMac - FM module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_MAC_Init(t_Handle h_FmMac); -+ -+/**************************************************************************//** -+ @Function FM_Free -+ -+ @Description Frees all resources that were assigned to FM MAC module. -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_FmMac - FM module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_MAC_Free(t_Handle h_FmMac); -+ -+ -+/**************************************************************************//** -+ @Group FM_mac_advanced_init_grp FM MAC Advanced Configuration Unit -+ -+ @Description Configuration functions used to change default values. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_MAC_ConfigResetOnInit -+ -+ @Description Tell the driver whether to reset the FM MAC before initialization or -+ not. It changes the default configuration [DEFAULT_resetOnInit]. -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ @Param[in] enable When TRUE, FM will be reset before any initialization. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_ConfigResetOnInit(t_Handle h_FmMac, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_MAC_ConfigLoopback -+ -+ @Description Enable/Disable internal loopback mode -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ @Param[in] enable TRUE to enable or FALSE to disable. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_ConfigLoopback(t_Handle h_FmMac, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_MAC_ConfigMaxFrameLength -+ -+ @Description Setup maximum Rx Frame Length (in 1G MAC, effects also Tx) -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ @Param[in] newVal MAX Frame length -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_ConfigMaxFrameLength(t_Handle h_FmMac, uint16_t newVal); -+ -+/**************************************************************************//** -+ @Function FM_MAC_ConfigWan -+ -+ @Description ENABLE WAN mode in 10G-MAC -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ @Param[in] enable TRUE to enable or FALSE to disable. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_ConfigWan(t_Handle h_FmMac, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_MAC_ConfigPadAndCrc -+ -+ @Description Config PAD and CRC mode -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ @Param[in] enable TRUE to enable or FALSE to disable. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). -+ Not supported on 10G-MAC (i.e. CRC & PAD are added automatically -+ by HW); on mEMAC, this routine supports only PAD (i.e. CRC is -+ added automatically by HW). -+*//***************************************************************************/ -+t_Error FM_MAC_ConfigPadAndCrc(t_Handle h_FmMac, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_MAC_ConfigHalfDuplex -+ -+ @Description Config Half Duplex Mode -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ @Param[in] enable TRUE to enable or FALSE to disable. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_ConfigHalfDuplex(t_Handle h_FmMac, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_MAC_ConfigTbiPhyAddr -+ -+ @Description Configures the address of internal TBI PHY. -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ @Param[in] newVal TBI PHY address (1-31). -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_ConfigTbiPhyAddr(t_Handle h_FmMac, uint8_t newVal); -+ -+/**************************************************************************//** -+ @Function FM_MAC_ConfigLengthCheck -+ -+ @Description Configure the frame length checking. -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ @Param[in] enable TRUE to enable or FALSE to disable. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_ConfigLengthCheck(t_Handle h_FmMac, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_MAC_ConfigException -+ -+ @Description Change Exception selection from default -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ @Param[in] ex Type of the desired exceptions -+ @Param[in] enable TRUE to enable the specified exception, FALSE to disable it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_ConfigException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable); -+ -+#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac); -+#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */ -+/** @} */ /* end of FM_mac_advanced_init_grp group */ -+/** @} */ /* end of FM_mac_init_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_mac_runtime_control_grp FM MAC Runtime Control Unit -+ -+ @Description FM MAC Runtime control unit API functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_MAC_Enable -+ -+ @Description Enable the MAC -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ @Param[in] mode Mode of operation (RX, TX, Both) -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_Enable(t_Handle h_FmMac, e_CommMode mode); -+ -+/**************************************************************************//** -+ @Function FM_MAC_Disable -+ -+ @Description DISABLE the MAC -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ @Param[in] mode Define what part to Disable (RX, TX or BOTH) -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_Disable(t_Handle h_FmMac, e_CommMode mode); -+ -+/**************************************************************************//** -+ @Function FM_MAC_Resume -+ -+ @Description Re-init the MAC after suspend -+ -+ @Param[in] h_FmMac A handle to a FM MAC Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_Resume(t_Handle h_FmMac); -+ -+/**************************************************************************//** -+ @Function FM_MAC_Enable1588TimeStamp -+ -+ @Description Enables the TSU operation. -+ -+ @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_Enable1588TimeStamp(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_MAC_Disable1588TimeStamp -+ -+ @Description Disables the TSU operation. -+ -+ @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_Disable1588TimeStamp(t_Handle h_Fm); -+ -+/**************************************************************************//** -+ @Function FM_MAC_SetTxAutoPauseFrames -+ -+ @Description Enable/Disable transmission of Pause-Frames. -+ The routine changes the default configuration [DEFAULT_TX_PAUSE_TIME]. -+ -+ @Param[in] h_FmMac - A handle to a FM MAC Module. -+ @Param[in] pauseTime - Pause quanta value used with transmitted pause frames. -+ Each quanta represents a 512 bit-times; Note that '0' -+ as an input here will be used as disabling the -+ transmission of the pause-frames. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac, -+ uint16_t pauseTime); -+ -+ /**************************************************************************//** -+ @Function FM_MAC_SetTxPauseFrames -+ -+ @Description Enable/Disable transmission of Pause-Frames. -+ The routine changes the default configuration: -+ pause-time - [DEFAULT_TX_PAUSE_TIME] -+ threshold-time - [0] -+ -+ @Param[in] h_FmMac - A handle to a FM MAC Module. -+ @Param[in] priority - the PFC class of service; use 'FM_MAC_NO_PFC' -+ to indicate legacy pause support (i.e. no PFC). -+ @Param[in] pauseTime - Pause quanta value used with transmitted pause frames. -+ Each quanta represents a 512 bit-times; -+ Note that '0' as an input here will be used as disabling the -+ transmission of the pause-frames. -+ @Param[in] threshTime - Pause Threshold equanta value used by the MAC to retransmit pause frame. -+ if the situation causing a pause frame to be sent didn't finish when the timer -+ reached the threshold quanta, the MAC will retransmit the pause frame. -+ Each quanta represents a 512 bit-times. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+ In order for PFC to work properly the user must configure -+ TNUM-aging in the tx-port it is recommended that pre-fetch and -+ rate limit in the tx port should be disabled; -+ PFC is supported only on new mEMAC; i.e. in MACs that don't have -+ PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC' -+ in the 'priority' field. -+*//***************************************************************************/ -+t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac, -+ uint8_t priority, -+ uint16_t pauseTime, -+ uint16_t threshTime); -+ -+/**************************************************************************//** -+ @Function FM_MAC_SetRxIgnorePauseFrames -+ -+ @Description Enable/Disable ignoring of Pause-Frames. -+ -+ @Param[in] h_FmMac - A handle to a FM MAC Module. -+ @Param[in] en - boolean indicates whether to ignore the incoming pause -+ frames or not. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_SetRxIgnorePauseFrames(t_Handle h_FmMac, bool en); -+ -+/**************************************************************************//** -+ @Function FM_MAC_SetWakeOnLan -+ -+ @Description Enable/Disable Wake On Lan support -+ -+ @Param[in] h_FmMac - A handle to a FM MAC Module. -+ @Param[in] en - boolean indicates whether to enable Wake On Lan -+ support or not. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_SetWakeOnLan(t_Handle h_FmMac, bool en); -+ -+/**************************************************************************//** -+ @Function FM_MAC_ResetCounters -+ -+ @Description reset all statistics counters -+ -+ @Param[in] h_FmMac - A handle to a FM MAC Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_ResetCounters(t_Handle h_FmMac); -+ -+/**************************************************************************//** -+ @Function FM_MAC_SetException -+ -+ @Description Enable/Disable a specific Exception -+ -+ @Param[in] h_FmMac - A handle to a FM MAC Module. -+ @Param[in] ex - Type of the desired exceptions -+ @Param[in] enable - TRUE to enable the specified exception, FALSE to disable it. -+ -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_MAC_SetStatistics -+ -+ @Description Define Statistics level. -+ Where applicable, the routine also enables the MIB counters -+ overflow interrupt in order to keep counters accurate -+ and account for overflows. -+ This routine is relevant only for dTSEC. -+ -+ @Param[in] h_FmMac - A handle to a FM MAC Module. -+ @Param[in] statisticsLevel - Full statistics level provides all standard counters but may -+ reduce performance. Partial statistics provides only special -+ event counters (errors etc.). If selected, regular counters (such as -+ byte/packet) will be invalid and will return -1. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_SetStatistics(t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel); -+ -+/**************************************************************************//** -+ @Function FM_MAC_GetStatistics -+ -+ @Description get all statistics counters -+ -+ @Param[in] h_FmMac - A handle to a FM MAC Module. -+ @Param[in] p_Statistics - Structure with statistics -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics); -+ -+/**************************************************************************//** -+ @Function FM_MAC_ModifyMacAddr -+ -+ @Description Replace the main MAC Address -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ @Param[in] p_EnetAddr - Ethernet Mac address -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_ModifyMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); -+ -+/**************************************************************************//** -+ @Function FM_MAC_AddHashMacAddr -+ -+ @Description Add an Address to the hash table. This is for filter purpose only. -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ @Param[in] p_EnetAddr - Ethernet Mac address -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). It is a filter only address. -+ @Cautions Some address need to be filterd out in upper FM blocks. -+*//***************************************************************************/ -+t_Error FM_MAC_AddHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); -+ -+/**************************************************************************//** -+ @Function FM_MAC_RemoveHashMacAddr -+ -+ @Description Delete an Address to the hash table. This is for filter purpose only. -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ @Param[in] p_EnetAddr - Ethernet Mac address -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_RemoveHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); -+ -+/**************************************************************************//** -+ @Function FM_MAC_AddExactMatchMacAddr -+ -+ @Description Add a unicast or multicast mac address for exact-match filtering -+ (8 on dTSEC, 2 for 10G-MAC) -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ @Param[in] p_EnetAddr - MAC Address to ADD -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_AddExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); -+ -+/**************************************************************************//** -+ @Function FM_MAC_RemovelExactMatchMacAddr -+ -+ @Description Remove a uni cast or multi cast mac address. -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ @Param[in] p_EnetAddr - MAC Address to remove -+ -+ @Return E_OK on success; Error code otherwise.. -+ -+ @Cautions Allowed only after FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_RemovelExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); -+ -+/**************************************************************************//** -+ @Function FM_MAC_SetPromiscuous -+ -+ @Description Enable/Disable MAC Promiscuous mode for ALL mac addresses. -+ -+ @Param[in] h_FmMac - A handle to a FM MAC Module. -+ @Param[in] enable - TRUE to enable or FALSE to disable. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_SetPromiscuous(t_Handle h_FmMac, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_MAC_AdjustLink -+ -+ @Description Adjusts the Ethernet link with new speed/duplex setup. -+ This routine is relevant for dTSEC and mEMAC. -+ In case of mEMAC, this routine is also used for manual -+ re-configuration of RGMII speed and duplex mode for -+ RGMII PHYs not supporting in-band status information -+ to MAC. -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ @Param[in] speed - Ethernet speed. -+ @Param[in] fullDuplex - TRUE for full-duplex mode; -+ FALSE for half-duplex mode. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex); -+ -+/**************************************************************************//** -+ @Function FM_MAC_RestartAutoneg -+ -+ @Description Restarts the auto-negotiation process. -+ When auto-negotiation process is invoked under traffic the -+ auto-negotiation process between the internal SGMII PHY and the -+ external PHY does not always complete successfully. Calling this -+ function will restart the auto-negotiation process that will end -+ successfully. It is recommended to call this function after issuing -+ auto-negotiation restart command to the Eth Phy. -+ This routine is relevant only for dTSEC. -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac); -+ -+/**************************************************************************//** -+ @Function FM_MAC_GetId -+ -+ @Description Return the MAC ID -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ @Param[out] p_MacId - MAC ID of device -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_GetId(t_Handle h_FmMac, uint32_t *p_MacId); -+ -+/**************************************************************************//** -+ @Function FM_MAC_GetVesrion -+ -+ @Description Return Mac HW chip version -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ @Param[out] p_MacVresion - Mac version as defined by the chip -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_GetVesrion(t_Handle h_FmMac, uint32_t *p_MacVresion); -+ -+/**************************************************************************//** -+ @Function FM_MAC_MII_WritePhyReg -+ -+ @Description Write data into Phy Register -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ @Param[in] phyAddr - Phy Address on the MII bus -+ @Param[in] reg - Register Number. -+ @Param[in] data - Data to write. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_MII_WritePhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data); -+ -+/**************************************************************************//** -+ @Function FM_MAC_MII_ReadPhyReg -+ -+ @Description Read data from Phy Register -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ @Param[in] phyAddr - Phy Address on the MII bus -+ @Param[in] reg - Register Number. -+ @Param[out] p_Data - Data from PHY. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data); -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+/**************************************************************************//** -+ @Function FM_MAC_DumpRegs -+ -+ @Description Dump internal registers -+ -+ @Param[in] h_FmMac - A handle to a FM Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_MAC_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_DumpRegs(t_Handle h_FmMac); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+/** @} */ /* end of FM_mac_runtime_control_grp group */ -+/** @} */ /* end of FM_mac_grp group */ -+/** @} */ /* end of FM_grp group */ -+ -+ -+#endif /* __FM_MAC_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h -@@ -0,0 +1,1271 @@ -+/* -+ * Copyright 2008-2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ @File fm_macsec_ext.h -+ -+ @Description FM MACSEC ... -+*//***************************************************************************/ -+#ifndef __FM_MACSEC_EXT_H -+#define __FM_MACSEC_EXT_H -+ -+#include "std_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group FM_grp Frame Manager API -+ -+ @Description FM API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_MACSEC_grp FM MACSEC -+ -+ @Description FM MACSEC API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description MACSEC Exceptions -+*//***************************************************************************/ -+typedef enum e_FmMacsecExceptions { -+ e_FM_MACSEC_EX_SINGLE_BIT_ECC, /**< Single bit ECC error */ -+ e_FM_MACSEC_EX_MULTI_BIT_ECC /**< Multi bit ECC error */ -+} e_FmMacsecExceptions; -+ -+ -+/**************************************************************************//** -+ @Group FM_MACSEC_init_grp FM-MACSEC Initialization Unit -+ -+ @Description FM MACSEC Initialization Unit -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function t_FmMacsecExceptionsCallback -+ -+ @Description Exceptions user callback routine, will be called upon an -+ exception passing the exception identification. -+ -+ @Param[in] h_App A handle to an application layer object; This handle -+ will be passed by the driver upon calling this callback. -+ @Param[in] exception The exception. -+*//***************************************************************************/ -+typedef void (t_FmMacsecExceptionsCallback) ( t_Handle h_App, -+ e_FmMacsecExceptions exception); -+ -+ -+/**************************************************************************//** -+ @Description FM MACSEC config input -+*//***************************************************************************/ -+typedef struct t_FmMacsecParams { -+ t_Handle h_Fm; /**< A handle to the FM object related to */ -+ bool guestMode; /**< Partition-id */ -+ union { -+ struct { -+ uint8_t fmMacId; /**< FM MAC id */ -+ } guestParams; -+ -+ struct { -+ uintptr_t baseAddr; /**< Base of memory mapped FM MACSEC registers */ -+ t_Handle h_FmMac; /**< A handle to the FM MAC object related to */ -+ t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */ -+ t_Handle h_App; /**< A handle to an application layer object; This handle will -+ be passed by the driver upon calling the above callbacks */ -+ } nonGuestParams; -+ }; -+} t_FmMacsecParams; -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_Config -+ -+ @Description Creates descriptor for the FM MACSEC module; -+ -+ The routine returns a handle (descriptor) to the FM MACSEC object; -+ This descriptor must be passed as first parameter to all other -+ FM MACSEC function calls; -+ -+ No actual initialization or configuration of FM MACSEC hardware is -+ done by this routine. -+ -+ @Param[in] p_FmMacsecParam Pointer to data structure of parameters. -+ -+ @Retval Handle to FM MACSEC object, or NULL for Failure. -+*//***************************************************************************/ -+t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_Init -+ -+ @Description Initializes the FM MACSEC module. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_MACSEC_Init(t_Handle h_FmMacsec); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_Free -+ -+ @Description Frees all resources that were assigned to FM MACSEC module; -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_MACSEC_Free(t_Handle h_FmMacsec); -+ -+ -+/**************************************************************************//** -+ @Group FM_MACSEC_advanced_init_grp FM-MACSEC Advanced Configuration Unit -+ -+ @Description Configuration functions used to change default values. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description enum for unknown sci frame treatment -+*//***************************************************************************/ -+typedef enum e_FmMacsecUnknownSciFrameTreatment { -+ e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH = 0, /**< Controlled port - Strict mode */ -+ e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, /**< If C bit clear deliver on controlled port, else discard -+ Controlled port - Check or Disable mode */ -+ e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, /**< Controlled port - Strict mode */ -+ e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED /**< If C bit set deliver on uncontrolled port and discard on controlled port, -+ else discard on uncontrolled port and deliver on controlled port -+ Controlled port - Check or Disable mode */ -+} e_FmMacsecUnknownSciFrameTreatment; -+ -+/**************************************************************************//** -+ @Description enum for untag frame treatment -+*//***************************************************************************/ -+typedef enum e_FmMacsecUntagFrameTreatment { -+ e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED = 0, /**< Controlled port - Strict mode */ -+ e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, /**< Controlled port - Strict mode */ -+ e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED /**< Controlled port - Strict mode */ -+} e_FmMacsecUntagFrameTreatment; -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_ConfigUnknownSciFrameTreatment -+ -+ @Description Change the treatment for received frames with unknown sci from its default -+ configuration [DEFAULT_unknownSciFrameTreatment]. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[in] treatMode The selected mode. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_ConfigInvalidTagsFrameTreatment -+ -+ @Description Change the treatment for received frames with invalid tags or -+ a zero value PN or an invalid ICV from its default configuration -+ [DEFAULT_invalidTagsFrameTreatment]. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard; -+ In both cases discard on the controlled port; -+ this provide Strict, Check or Disable mode. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment -+ -+ @Description Change the treatment for received frames with the Encryption bit -+ set and the Changed Text bit clear from its default configuration -+ [DEFAULT_encryptWithNoChangedTextFrameTreatment]. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[in] discardUncontrolled If True discard on the uncontrolled port, else deliver; -+ In both cases discard on the controlled port; -+ this provide Strict, Check or Disable mode. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment -+ -+ @Description Change the treatment for received frames with the Encryption bit -+ clear and the Changed Text bit set from its default configuration -+ [DEFAULT_changedTextWithNoEncryptFrameTreatment]. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard; -+ In both cases discard on the controlled port; -+ this provide Strict, Check or Disable mode. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_ConfigUntagFrameTreatment -+ -+ @Description Change the treatment for received frames without the MAC security tag (SecTAG) -+ from its default configuration [DEFAULT_untagFrameTreatment]. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[in] treatMode The selected mode. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment -+ -+ @Description Change the treatment for received frames with only SCB bit set -+ from its default configuration [DEFAULT_onlyScbIsSetFrameTreatment]. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard; -+ In both cases discard on the controlled port; -+ this provide Strict, Check or Disable mode. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_ConfigPnExhaustionThreshold -+ -+ @Description It's provide the ability to configure a PN exhaustion threshold; -+ When the NextPn crosses this value an interrupt event -+ is asserted to warn that the active SA should re-key. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[in] pnExhThr If the threshold is reached, an interrupt event -+ is asserted to re-key. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_ConfigKeysUnreadable -+ -+ @Description Turn on privacy mode; All the keys and their hash values can't be read any more; -+ Can not be cleared unless hard reset. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_ConfigSectagWithoutSCI -+ -+ @Description Promise that all generated Sectag will be without SCI included. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_ConfigException -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default selection of exceptions enablement; -+ By default all exceptions are enabled. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[in] exception The exception to be selected. -+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable); -+ -+/** @} */ /* end of FM_MACSEC_advanced_init_grp group */ -+/** @} */ /* end of FM_MACSEC_init_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_MACSEC_runtime_control_grp FM-MACSEC Runtime Control Data Unit -+ -+ @Description FM MACSEC runtime control data unit API functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_GetRevision -+ -+ @Description Return MACSEC HW chip revision -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[out] p_MacsecRevision MACSEC revision as defined by the chip. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_Enable -+ -+ @Description This routine should be called after MACSEC is initialized for enabling all -+ MACSEC engines according to their existing configuration. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is disabled. -+*//***************************************************************************/ -+t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_Disable -+ -+ @Description This routine may be called when MACSEC is enabled in order to -+ disable all MACSEC engines; The MACSEC is working in bypass mode. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is enabled. -+*//***************************************************************************/ -+t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SetException -+ -+ @Description Calling this routine enables/disables the specified exception. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[in] exception The exception to be selected. -+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable); -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+/**************************************************************************//** -+ @Function FM_MACSEC_DumpRegs -+ -+ @Description Dump internal registers. -+ -+ @Param[in] h_FmMacsec - FM MACSEC module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_DumpRegs(t_Handle h_FmMacsec); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+#ifdef VERIFICATION_SUPPORT -+/********************* VERIFICATION ONLY ********************************/ -+/**************************************************************************//** -+ @Function FM_MACSEC_BackdoorSet -+ -+ @Description Set register of the MACSEC memory map -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[out] offset Register offset. -+ @Param[out] value Value to write. -+ -+ -+ @Return None -+ -+ @Cautions Allowed only following FM_MACSEC_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_BackdoorSet(t_Handle h_FmMacsec, uint32_t offset, uint32_t value); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_BackdoorGet -+ -+ @Description Read from register of the MACSEC memory map. -+ -+ @Param[in] h_FmMacsec FM MACSEC module descriptor. -+ @Param[out] offset Register offset. -+ -+ @Return Value read -+ -+ @Cautions Allowed only following FM_MACSEC_Init(). -+*//***************************************************************************/ -+uint32_t FM_MACSEC_BackdoorGet(t_Handle h_FmMacsec, uint32_t offset); -+#endif /* VERIFICATION_SUPPORT */ -+ -+/** @} */ /* end of FM_MACSEC_runtime_control_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_MACSEC_SECY_grp FM-MACSEC SecY -+ -+ @Description FM-MACSEC SecY API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+typedef uint8_t macsecSAKey_t[32]; -+typedef uint64_t macsecSCI_t; -+typedef uint8_t macsecAN_t; -+ -+/**************************************************************************//** -+@Description MACSEC SECY Cipher Suite -+*//***************************************************************************/ -+typedef enum e_FmMacsecSecYCipherSuite { -+ e_FM_MACSEC_SECY_GCM_AES_128 = 0, /**< GCM-AES-128 */ -+#if (DPAA_VERSION >= 11) -+ e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */ -+#endif /* (DPAA_VERSION >= 11) */ -+} e_FmMacsecSecYCipherSuite; -+ -+/**************************************************************************//** -+ @Description MACSEC SECY Exceptions -+*//***************************************************************************/ -+typedef enum e_FmMacsecSecYExceptions { -+ e_FM_MACSEC_SECY_EX_FRAME_DISCARDED /**< Frame Discarded */ -+} e_FmMacsecSecYExceptions; -+ -+/**************************************************************************//** -+ @Description MACSEC SECY Events -+*//***************************************************************************/ -+typedef enum e_FmMacsecSecYEvents { -+ e_FM_MACSEC_SECY_EV_NEXT_PN /**< Next Packet Number exhaustion threshold reached */ -+} e_FmMacsecSecYEvents; -+ -+/**************************************************************************//** -+ @Collection MACSEC SECY Frame Discarded Descriptor error -+*//***************************************************************************/ -+typedef uint8_t macsecTxScFrameDiscardedErrSelect_t; /**< typedef for defining Frame Discarded Descriptor errors */ -+ -+#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_NEXT_PN_ZERO 0x8000 /**< NextPn == 0 */ -+#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_SC_DISBALE 0x4000 /**< SC is disable */ -+/* @} */ -+ -+/**************************************************************************//** -+ @Function t_FmMacsecSecYExceptionsCallback -+ -+ @Description Exceptions user callback routine, will be called upon an -+ exception passing the exception identification. -+ -+ @Param[in] h_App A handle to an application layer object; This handle -+ will be passed by the driver upon calling this callback. -+ @Param[in] exception The exception. -+*//***************************************************************************/ -+typedef void (t_FmMacsecSecYExceptionsCallback) ( t_Handle h_App, -+ e_FmMacsecSecYExceptions exception); -+ -+/**************************************************************************//** -+ @Function t_FmMacsecSecYEventsCallback -+ -+ @Description Events user callback routine, will be called upon an -+ event passing the event identification. -+ -+ @Param[in] h_App A handle to an application layer object; This handle -+ will be passed by the driver upon calling this callback. -+ @Param[in] event The event. -+*//***************************************************************************/ -+typedef void (t_FmMacsecSecYEventsCallback) ( t_Handle h_App, -+ e_FmMacsecSecYEvents event); -+ -+/**************************************************************************//** -+ @Description RFC2863 MIB -+*//***************************************************************************/ -+typedef struct t_MIBStatistics { -+ uint64_t ifInOctets; /**< Total number of byte received */ -+ uint64_t ifInPkts; /**< Total number of packets received */ -+ uint64_t ifInMcastPkts; /**< Total number of multicast frame received */ -+ uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */ -+ uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX : -+ - InPktsNoTag, -+ - InPktsLate, -+ - InPktsOverrun */ -+ uint64_t ifInErrors; /**< Number of frames received with error: -+ - InPktsBadTag, -+ - InPktsNoSCI, -+ - InPktsNotUsingSA -+ - InPktsNotValid */ -+ uint64_t ifOutOctets; /**< Total number of byte sent */ -+ uint64_t ifOutPkts; /**< Total number of packets sent */ -+ uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */ -+ uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */ -+ uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A! */ -+ uint64_t ifOutErrors; /**< Number of frames transmitted with error: -+ - FIFO Overflow Error -+ - FIFO Underflow Error -+ - Other */ -+} t_MIBStatistics; -+ -+/**************************************************************************//** -+ @Description MACSEC SecY Rx SA Statistics -+*//***************************************************************************/ -+typedef struct t_FmMacsecSecYRxSaStatistics { -+ uint32_t inPktsOK; /**< The number of frames with resolved SCI, have passed all -+ frame validation frame validation with the validateFrame not set to disable */ -+ uint32_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame -+ validation with the validateFrame set to check */ -+ uint32_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port, -+ that have failed frame validation with the validateFrame set to strict or the c bit is set */ -+ uint32_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or -+ not provisioned SA with validateFrame in the strict mode or the C bit is set */ -+ uint32_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA -+ with validateFrame not in the strict mode and the C bit is cleared */ -+} t_FmMacsecSecYRxSaStatistics; -+ -+/**************************************************************************//** -+ @Description MACSEC SecY Tx SA Statistics -+*//***************************************************************************/ -+typedef struct t_FmMacsecSecYTxSaStatistics { -+ uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to -+ be transmitted, which were integrity protected */ -+ uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to -+ be transmitted, which were confidentiality protected */ -+} t_FmMacsecSecYTxSaStatistics; -+ -+/**************************************************************************//** -+ @Description MACSEC SecY Rx SC Statistics -+*//***************************************************************************/ -+typedef struct t_FmMacsecSecYRxScStatistics { -+ uint64_t inPktsUnchecked; /**< The number of frames with resolved SCI, delivered to the user of a controlled port, -+ that are not validated with the validateFrame set to disable */ -+ uint64_t inPktsDelayed; /**< The number of frames with resolved SCI, delivered to the user of a controlled port, -+ that have their PN smaller than the lowest_PN with the validateFrame set to -+ disable or replayProtect disabled */ -+ uint64_t inPktsLate; /**< The number of frames with resolved SCI, discarded on the controlled port, -+ that have their PN smaller than the lowest_PN with the validateFrame set to -+ Check or Strict and replayProtect enabled */ -+ uint64_t inPktsOK; /**< The number of frames with resolved SCI, have passed all -+ frame validation frame validation with the validateFrame not set to disable */ -+ uint64_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame -+ validation with the validateFrame set to check */ -+ uint64_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port, -+ that have failed frame validation with the validateFrame set to strict or the c bit is set */ -+ uint64_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or -+ not provisioned SA with validateFrame in the strict mode or the C bit is set */ -+ uint64_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA -+ with validateFrame not in the strict mode and the C bit is cleared */ -+} t_FmMacsecSecYRxScStatistics; -+ -+/**************************************************************************//** -+ @Description MACSEC SecY Tx SC Statistics -+*//***************************************************************************/ -+typedef struct t_FmMacsecSecYTxScStatistics { -+ uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to -+ be transmitted, which were integrity protected */ -+ uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to -+ be transmitted, which were confidentiality protected */ -+} t_FmMacsecSecYTxScStatistics; -+ -+/**************************************************************************//** -+ @Description MACSEC SecY Statistics -+*//***************************************************************************/ -+typedef struct t_FmMacsecSecYStatistics { -+ t_MIBStatistics mibCtrlStatistics; /**< Controlled port MIB statistics */ -+ t_MIBStatistics mibNonCtrlStatistics; /**< Uncontrolled port MIB statistics */ -+/* Frame verification statistics */ -+ uint64_t inPktsUntagged; /**< The number of received packets without the MAC security tag -+ (SecTAG) with validateFrames which is not in the strict mode */ -+ uint64_t inPktsNoTag; /**< The number of received packets discarded without the -+ MAC security tag (SecTAG) with validateFrames which is in the strict mode */ -+ uint64_t inPktsBadTag; /**< The number of received packets discarded with an invalid -+ SecTAG or a zero value PN or an invalid ICV */ -+ uint64_t inPktsUnknownSCI; /**< The number of received packets with unknown SCI with the -+ condition : validateFrames is not in the strict mode and the -+ C bit in the SecTAG is not set */ -+ uint64_t inPktsNoSCI; /**< The number of received packets discarded with unknown SCI -+ information with the condition : validateFrames is in the strict mode -+ or the C bit in the SecTAG is set */ -+ uint64_t inPktsOverrun; /**< The number of packets discarded because the number of -+ received packets exceeded the cryptographic performance capabilities */ -+/* Frame validation statistics */ -+ uint64_t inOctetsValidated; /**< The number of octets of plaintext recovered from received frames with -+ resolved SCI that were integrity protected but not encrypted */ -+ uint64_t inOctetsDecrypted; /**< The number of octets of plaintext recovered from received frames with -+ resolved SCI that were integrity protected and encrypted */ -+/* Frame generation statistics */ -+ uint64_t outPktsUntagged; /**< The number of frames, that the user of the controlled port requested to -+ be transmitted, with protectFrame false */ -+ uint64_t outPktsTooLong; /**< The number of frames, that the user of the controlled port requested to -+ be transmitted, discarded due to length being larger than Maximum Frame Length (MACSEC_MFL) */ -+/* Frame protection statistics */ -+ uint64_t outOctetsProtected; /**< The number of octets of User Data in transmitted frames that were -+ integrity protected but not encrypted */ -+ uint64_t outOctetsEncrypted; /**< The number of octets of User Data in transmitted frames that were -+ both integrity protected and encrypted */ -+} t_FmMacsecSecYStatistics; -+ -+ -+/**************************************************************************//** -+ @Description MACSEC SecY SC Params -+*//***************************************************************************/ -+typedef struct t_FmMacsecSecYSCParams { -+ macsecSCI_t sci; /**< The secure channel identification of the SC */ -+ e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for the SC */ -+} t_FmMacsecSecYSCParams; -+ -+/**************************************************************************//** -+ @Group FM_MACSEC_SECY_init_grp FM-MACSEC SecY Initialization Unit -+ -+ @Description FM-MACSEC SecY Initialization Unit -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description enum for validate frames -+*//***************************************************************************/ -+typedef enum e_FmMacsecValidFrameBehavior { -+ e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE = 0, /**< disable the validation function */ -+ e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, /**< enable the validation function but only for checking -+ without filtering out invalid frames */ -+ e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT /**< enable the validation function and also strictly filter -+ out those invalid frames */ -+} e_FmMacsecValidFrameBehavior; -+ -+/**************************************************************************//** -+ @Description enum for sci insertion -+*//***************************************************************************/ -+typedef enum e_FmMacsecSciInsertionMode { -+ e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG = 0, /**< explicit sci in the sectag */ -+ e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, /**< mac sa is overwritten with the sci*/ -+ e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP /**< implicit point-to-point sci (pre-shared) */ -+} e_FmMacsecSciInsertionMode; -+ -+/**************************************************************************//** -+ @Description FM MACSEC SecY config input -+*//***************************************************************************/ -+typedef struct t_FmMacsecSecYParams { -+ t_Handle h_FmMacsec; /**< A handle to the FM MACSEC object */ -+ t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */ -+ uint32_t numReceiveChannels; /**< Number of receive channels dedicated to this SecY */ -+ t_FmMacsecSecYExceptionsCallback *f_Exception; /**< Callback routine to be called by the driver upon SecY exception */ -+ t_FmMacsecSecYEventsCallback *f_Event; /**< Callback routine to be called by the driver upon SecY event */ -+ t_Handle h_App; /**< A handle to an application layer object; This handle will -+ be passed by the driver upon calling the above callbacks */ -+} t_FmMacsecSecYParams; -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_Config -+ -+ @Description Creates descriptor for the FM MACSEC SECY module; -+ -+ The routine returns a handle (descriptor) to the FM MACSEC SECY object; -+ This descriptor must be passed as first parameter to all other -+ FM MACSEC SECY function calls; -+ No actual initialization or configuration of FM MACSEC SecY hardware is -+ done by this routine. -+ -+ @Param[in] p_FmMacsecSecYParam Pointer to data structure of parameters. -+ -+ @Return Handle to FM MACSEC SECY object, or NULL for Failure. -+*//***************************************************************************/ -+t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_Init -+ -+ @Description Initializes the FM MACSEC SECY module. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_Free -+ -+ @Description Frees all resources that were assigned to FM MACSEC SECY module. -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY); -+ -+/**************************************************************************//** -+ @Group FM_MACSEC_SECY_advanced_init_grp FM-MACSEC SecY Advanced Configuration Unit -+ -+ @Description Configuration functions used to change default values. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_ConfigSciInsertionMode -+ -+ @Description Calling this routine changes the SCI-insertion-mode in the -+ internal driver data base from its default configuration -+ [DEFAULT_sciInsertionMode] -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] sciInsertionMode Sci insertion mode -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); -+ -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_ConfigProtectFrames -+ -+ @Description Calling this routine changes the protect-frame mode in the -+ internal driver data base from its default configuration -+ [DEFAULT_protectFrames] -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] protectFrames If FALSE, frames are transmitted without modification -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); -+ -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_ConfigReplayWindow -+ -+ @Description Calling this routine changes the replay-window settings in the -+ internal driver data base from its default configuration -+ [DEFAULT_replayEnable], [DEFAULT_replayWindow] -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] replayProtect; Replay protection function mode -+ @Param[in] replayWindow; The size of the replay window -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); -+ -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_ConfigValidationMode -+ -+ @Description Calling this routine changes the frame-validation-behavior mode -+ in the internal driver data base from its default configuration -+ [DEFAULT_validateFrames] -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] validateFrames Validation function mode -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); -+ -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_ConfigConfidentiality -+ -+ @Description Calling this routine changes the confidentiality settings in the -+ internal driver data base from its default configuration -+ [DEFAULT_confidentialityEnable], [DEFAULT_confidentialityOffset] -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] confidentialityEnable TRUE - confidentiality protection and integrity protection -+ FALSE - no confidentiality protection, only integrity protection -+ @Param[in] confidentialityOffset The number of initial octets of each MSDU without confidentiality protection -+ common values are 0, 30, and 50 -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); -+ -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_ConfigPointToPoint -+ -+ @Description configure this SecY to work in point-to-point mode, means that -+ it will have only one rx sc; -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(); -+ Can be called only once in a system; only the first secY that will call this -+ routine will be able to operate in Point-To-Point mode. -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_ConfigException -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default selection of exceptions enablement; -+ By default all exceptions are enabled. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] exception The exception to be selected. -+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_ConfigEvent -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default selection of events enablement; -+ By default all events are enabled. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] event The event to be selected. -+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable); -+ -+/** @} */ /* end of FM_MACSEC_SECY_advanced_init_grp group */ -+/** @} */ /* end of FM_MACSEC_SECY_init_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_MACSEC_SECY_runtime_control_grp FM-MACSEC SecY Runtime Control Unit -+ -+ @Description FM MACSEC SECY Runtime control unit API functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_CreateRxSc -+ -+ @Description Create a receive secure channel. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] scParams secure channel params. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_DeleteRxSc -+ -+ @Description Deleting an initialized secure channel. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_CreateRxSa -+ -+ @Description Create a receive secure association for the secure channel; -+ the SA cannot be used to receive frames until FM_MACSEC_SECY_RxSaEnableReceive is called. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. -+ @Param[in] an association number represent the SA. -+ @Param[in] lowestPn the lowest acceptable PN value for a received frame. -+ @Param[in] key the desired key for this SA. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_DeleteRxSa -+ -+ @Description Deleting an initialized secure association. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. -+ @Param[in] an association number represent the SA. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_RxSaEnableReceive -+ -+ @Description Enabling the SA to receive frames. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. -+ @Param[in] an association number represent the SA. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_RxSaDisableReceive -+ -+ @Description Disabling the SA from receive frames. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. -+ @Param[in] an association number represent the SA. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_RxSaUpdateNextPn -+ -+ @Description Update the next packet number expected on RX; -+ The value of nextPN shall be set to the greater of its existing value and the -+ supplied of updtNextPN (802.1AE-2006 10.7.15). -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. -+ @Param[in] an association number represent the SA. -+ @Param[in] updtNextPN the next PN value for a received frame. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_RxSaUpdateLowestPn -+ -+ @Description Update the lowest packet number expected on RX; -+ The value of lowestPN shall be set to the greater of its existing value and the -+ supplied of updtLowestPN (802.1AE-2006 10.7.15). -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. -+ @Param[in] an association number represent the SA. -+ @Param[in] updtLowestPN the lowest PN acceptable value for a received frame. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_RxSaModifyKey -+ -+ @Description Modify the current key of the SA with a new one. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. -+ @Param[in] an association number represent the SA. -+ @Param[in] key new key to replace the current key. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_CreateTxSa -+ -+ @Description Create a transmit secure association for the secure channel; -+ the SA cannot be used to transmit frames until FM_MACSEC_SECY_TxSaSetActivate is called; -+ Only one SA can be active at a time. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] an association number represent the SA. -+ @Param[in] key the desired key for this SA. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_DeleteTxSa -+ -+ @Description Deleting an initialized secure association. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] an association number represent the SA. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_TxSaModifyKey -+ -+ @Description Modify the key of the inactive SA with a new one. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] nextActiveAn association number represent the next SA to be activated. -+ @Param[in] key new key to replace the current key. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_TxSaSetActive -+ -+ @Description Set this SA to the active SA to be used on TX for SC; -+ only one SA can be active at a time. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] an association number represent the SA. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_TxSaGetActive -+ -+ @Description Get the active SA that being used for TX. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[out] p_An the active an. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_GetStatistics -+ -+ @Description get all statistics counters. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] p_Statistics Structure with statistics. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_RxScGetStatistics -+ -+ @Description get all statistics counters. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] h_Sc Rx Sc handle. -+ @Param[in] p_Statistics Structure with statistics. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_RxSaGetStatistics -+ -+ @Description get all statistics counters -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] h_Sc Rx Sc handle. -+ @Param[in] an association number represent the SA. -+ @Param[in] p_Statistics Structure with statistics. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_TxScGetStatistics -+ -+ @Description get all statistics counters. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] p_Statistics Structure with statistics. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_TxSaGetStatistics -+ -+ @Description get all statistics counters. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] an association number represent the SA. -+ @Param[in] p_Statistics Structure with statistics. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_SetException -+ -+ @Description Calling this routine enables/disables the specified exception. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] exception The exception to be selected. -+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_SetEvent -+ -+ @Description Calling this routine enables/disables the specified event. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] event The event to be selected. -+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_GetRxScPhysId -+ -+ @Description return the physical id of the Secure Channel. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc. -+ @Param[out] p_ScPhysId the SC physical id. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId); -+ -+/**************************************************************************//** -+ @Function FM_MACSEC_SECY_GetTxScPhysId -+ -+ @Description return the physical id of the Secure Channel. -+ -+ @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor. -+ @Param[out] p_ScPhysId the SC physical id. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MACSEC_SECY_Init(). -+*//***************************************************************************/ -+t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId); -+ -+/** @} */ /* end of FM_MACSEC_SECY_runtime_control_grp group */ -+/** @} */ /* end of FM_MACSEC_SECY_grp group */ -+/** @} */ /* end of FM_MACSEC_grp group */ -+/** @} */ /* end of FM_grp group */ -+ -+ -+#endif /* __FM_MACSEC_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h -@@ -0,0 +1,170 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File fm_muram_ext.h -+ -+ @Description FM MURAM Application Programming Interface. -+*//***************************************************************************/ -+#ifndef __FM_MURAM_EXT -+#define __FM_MURAM_EXT -+ -+#include "error_ext.h" -+#include "std_ext.h" -+ -+ -+/**************************************************************************//** -+ -+ @Group FM_grp Frame Manager API -+ -+ @Description FM API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_muram_grp FM MURAM -+ -+ @Description FM MURAM API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_muram_init_grp FM MURAM Initialization Unit -+ -+ @Description FM MURAM initialization API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_MURAM_ConfigAndInit -+ -+ @Description Creates partition in the MURAM. -+ -+ The routine returns a handle (descriptor) to the MURAM partition. -+ This descriptor must be passed as first parameter to all other -+ FM-MURAM function calls. -+ -+ No actual initialization or configuration of FM_MURAM hardware is -+ done by this routine. -+ -+ @Param[in] baseAddress - Pointer to base of memory mapped FM-MURAM. -+ @Param[in] size - Size of the FM-MURAM partition. -+ -+ @Return Handle to FM-MURAM object, or NULL for Failure. -+*//***************************************************************************/ -+t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size); -+ -+/**************************************************************************//** -+ @Function FM_MURAM_Free -+ -+ @Description Frees all resources that were assigned to FM-MURAM module. -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_FmMuram - FM-MURAM module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_MURAM_Free(t_Handle h_FmMuram); -+ -+/** @} */ /* end of FM_muram_init_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_muram_ctrl_grp FM MURAM Control Unit -+ -+ @Description FM MURAM control API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_MURAM_AllocMem -+ -+ @Description Allocate some memory from FM-MURAM partition. -+ -+ @Param[in] h_FmMuram - FM-MURAM module descriptor. -+ @Param[in] size - size of the memory to be allocated. -+ @Param[in] align - Alignment of the memory. -+ -+ @Return address of the allocated memory; NULL otherwise. -+*//***************************************************************************/ -+void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align); -+ -+/**************************************************************************//** -+ @Function FM_MURAM_AllocMemForce -+ -+ @Description Allocate some specific memory from FM-MURAM partition (according -+ to base). -+ -+ @Param[in] h_FmMuram - FM-MURAM module descriptor. -+ @Param[in] base - the desired base-address to be allocated. -+ @Param[in] size - size of the memory to be allocated. -+ -+ @Return address of the allocated memory; NULL otherwise. -+*//***************************************************************************/ -+void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size); -+ -+/**************************************************************************//** -+ @Function FM_MURAM_FreeMem -+ -+ @Description Free an allocated memory from FM-MURAM partition. -+ -+ @Param[in] h_FmMuram - FM-MURAM module descriptor. -+ @Param[in] ptr - A pointer to an allocated memory. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr); -+ -+/**************************************************************************//** -+ @Function FM_MURAM_GetFreeMemSize -+ -+ @Description Returns the size (in bytes) of free MURAM memory. -+ -+ @Param[in] h_FmMuram - FM-MURAM module descriptor. -+ -+ @Return Free MURAM memory size in bytes. -+*//***************************************************************************/ -+uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram); -+ -+/** @} */ /* end of FM_muram_ctrl_grp group */ -+/** @} */ /* end of FM_muram_grp group */ -+/** @} */ /* end of FM_grp group */ -+ -+ -+ -+#endif /* __FM_MURAM_EXT */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h -@@ -0,0 +1,3974 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File fm_pcd_ext.h -+ -+ @Description FM PCD API definitions -+*//***************************************************************************/ -+#ifndef __FM_PCD_EXT -+#define __FM_PCD_EXT -+ -+#include "std_ext.h" -+#include "net_ext.h" -+#include "list_ext.h" -+#include "fm_ext.h" -+#include "fsl_fman_kg.h" -+ -+ -+/**************************************************************************//** -+ @Group FM_grp Frame Manager API -+ -+ @Description Frame Manager Application Programming Interface -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_PCD_grp FM PCD -+ -+ @Description Frame Manager PCD (Parse-Classify-Distribute) API. -+ -+ The FM PCD module is responsible for the initialization of all -+ global classifying FM modules. This includes the parser general and -+ common registers, the key generator global and common registers, -+ and the policer global and common registers. -+ In addition, the FM PCD SW module will initialize all required -+ key generator schemes, coarse classification flows, and policer -+ profiles. When FM module is configured to work with one of these -+ entities, it will register to it using the FM PORT API. The PCD -+ module will manage the PCD resources - i.e. resource management of -+ KeyGen schemes, etc. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Collection General PCD defines -+*//***************************************************************************/ -+#define FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */ -+ -+#define FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */ -+#define FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - FM_PCD_MAX_NUM_OF_PRIVATE_HDRS) -+ /**< Number of distinction units is limited by -+ register size (32 bits) minus reserved bits -+ for private headers. */ -+#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers -+ in a distinction unit */ -+#define FM_PCD_KG_NUM_OF_GENERIC_REGS FM_KG_NUM_OF_GENERIC_REGS /**< Total number of generic KeyGen registers */ -+#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration; -+ For HW implementation reasons, in most -+ cases less than this will be allowed; The -+ driver will return an initialization error -+ if resource is unavailable. */ -+#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */ -+#define FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */ -+ -+#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */ -+#define FM_SW_PRS_MAX_IMAGE_SIZE (FM_PCD_SW_PRS_SIZE /*- FM_PCD_PRS_SW_OFFSET -FM_PCD_PRS_SW_TAIL_SIZE*/-FM_PCD_PRS_SW_PATCHES_SIZE) -+ /**< Maximum size of SW parser code */ -+ -+#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for -+ insert manipulation */ -+ -+#if (DPAA_VERSION >= 11) -+#define FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */ -+#endif /* (DPAA_VERSION >= 11) */ -+/* @} */ -+ -+ -+/**************************************************************************//** -+ @Group FM_PCD_init_grp FM PCD Initialization Unit -+ -+ @Description Frame Manager PCD Initialization Unit API -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description PCD counters -+*//***************************************************************************/ -+typedef enum e_FmPcdCounters { -+ e_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */ -+ e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */ -+ e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */ -+ e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer; -+ This is a subset of e_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */ -+ e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer; -+ This is a subset of e_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */ -+ e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */ -+ e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */ -+ e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */ -+ e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */ -+ e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */ -+ e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */ -+ e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */ -+ e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L2 parse result is returned with errors. */ -+ e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L3 parse result is returned with errors. */ -+ e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L4 parse result is returned with errors. */ -+ e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times SHIM parse result is returned with errors. */ -+ e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */ -+ e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES, /**< Parser counter - counts the number of cycles stalled waiting for parser internal memory reads while executing soft parser instruction. */ -+ e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES, /**< Parser counter - counts the number of cycles spent executing hard parser (including stall cycles). */ -+ e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */ -+ e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */ -+ e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */ -+ e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */ -+ e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */ -+} e_FmPcdCounters; -+ -+/**************************************************************************//** -+ @Description PCD interrupts -+*//***************************************************************************/ -+typedef enum e_FmPcdExceptions { -+ e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */ -+ e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */ -+ e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */ -+ e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */ -+ e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */ -+ e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */ -+ e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */ -+ e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */ -+} e_FmPcdExceptions; -+ -+ -+/**************************************************************************//** -+ @Description Exceptions user callback routine, will be called upon an -+ exception passing the exception identification. -+ -+ @Param[in] h_App - User's application descriptor. -+ @Param[in] exception - The exception. -+ *//***************************************************************************/ -+typedef void (t_FmPcdExceptionCallback) (t_Handle h_App, e_FmPcdExceptions exception); -+ -+/**************************************************************************//** -+ @Description Exceptions user callback routine, will be called upon an exception -+ passing the exception identification. -+ -+ @Param[in] h_App - User's application descriptor. -+ @Param[in] exception - The exception. -+ @Param[in] index - id of the relevant source (may be scheme or profile id). -+ *//***************************************************************************/ -+typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App, -+ e_FmPcdExceptions exception, -+ uint16_t index); -+ -+/**************************************************************************//** -+ @Description A callback for enqueuing frame onto a QM queue. -+ -+ @Param[in] h_QmArg - Application's handle passed to QM module on enqueue. -+ @Param[in] p_Fd - Frame descriptor for the frame. -+ -+ @Return E_OK on success; Error code otherwise. -+ *//***************************************************************************/ -+typedef t_Error (t_FmPcdQmEnqueueCallback) (t_Handle h_QmArg, void *p_Fd); -+ -+/**************************************************************************//** -+ @Description Host-Command parameters structure. -+ -+ When using Host command for PCD functionalities, a dedicated port -+ must be used. If this routine is called for a PCD in a single partition -+ environment, or it is the Master partition in a Multi-partition -+ environment, The port will be initialized by the PCD driver -+ initialization routine. -+ *//***************************************************************************/ -+typedef struct t_FmPcdHcParams { -+ uintptr_t portBaseAddr; /**< Virtual Address of Host-Command Port memory mapped registers.*/ -+ uint8_t portId; /**< Port Id (0-6 relative to Host-Command/Offline-Parsing ports); -+ NOTE: When configuring Host Command port for -+ FMANv3 devices (DPAA_VERSION 11 and higher), -+ portId=0 MUST be used. */ -+ uint16_t liodnBase; /**< LIODN base for this port, to be used together with LIODN offset -+ (irrelevant for P4080 revision 1.0) */ -+ uint32_t errFqid; /**< Host-Command Port error queue Id. */ -+ uint32_t confFqid; /**< Host-Command Port confirmation queue Id. */ -+ uint32_t qmChannel; /**< QM channel dedicated to this Host-Command port; -+ will be used by the FM for dequeue. */ -+ t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Callback routine for enqueuing a frame to the QM */ -+ t_Handle h_QmArg; /**< Application's handle passed to QM module on enqueue */ -+} t_FmPcdHcParams; -+ -+/**************************************************************************//** -+ @Description The main structure for PCD initialization -+ *//***************************************************************************/ -+typedef struct t_FmPcdParams { -+ bool prsSupport; /**< TRUE if Parser will be used for any of the FM ports. */ -+ bool ccSupport; /**< TRUE if Coarse Classification will be used for any -+ of the FM ports. */ -+ bool kgSupport; /**< TRUE if KeyGen will be used for any of the FM ports. */ -+ bool plcrSupport; /**< TRUE if Policer will be used for any of the FM ports. */ -+ t_Handle h_Fm; /**< A handle to the FM module. */ -+ uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition. -+ this parameter is relevant if 'kgSupport'=TRUE. */ -+ bool useHostCommand; /**< Optional for single partition, Mandatory for Multi partition */ -+ t_FmPcdHcParams hc; /**< Host Command parameters, relevant only if 'useHostCommand'=TRUE; -+ Relevant when FM not runs in "guest-mode". */ -+ -+ t_FmPcdExceptionCallback *f_Exception; /**< Callback routine for general PCD exceptions; -+ Relevant when FM not runs in "guest-mode". */ -+ t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Callback routine for specific KeyGen scheme or -+ Policer profile exceptions; -+ Relevant when FM not runs in "guest-mode". */ -+ t_Handle h_App; /**< A handle to an application layer object; This handle will -+ be passed by the driver upon calling the above callbacks; -+ Relevant when FM not runs in "guest-mode". */ -+ uint8_t partPlcrProfilesBase; /**< The first policer-profile-id dedicated to this partition. -+ this parameter is relevant if 'plcrSupport'=TRUE. -+ NOTE: this parameter relevant only when working with multiple partitions. */ -+ uint16_t partNumOfPlcrProfiles; /**< Number of policer-profiles dedicated to this partition. -+ this parameter is relevant if 'plcrSupport'=TRUE. -+ NOTE: this parameter relevant only when working with multiple partitions. */ -+} t_FmPcdParams; -+ -+ -+/**************************************************************************//** -+ @Function FM_PCD_Config -+ -+ @Description Basic configuration of the PCD module. -+ Creates descriptor for the FM PCD module. -+ -+ @Param[in] p_FmPcdParams A structure of parameters for the initialization of PCD. -+ -+ @Return A handle to the initialized module. -+*//***************************************************************************/ -+t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_Init -+ -+ @Description Initialization of the PCD module. -+ -+ @Param[in] h_FmPcd - FM PCD module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_PCD_Init(t_Handle h_FmPcd); -+ -+/**************************************************************************//** -+ @Function FM_PCD_Free -+ -+ @Description Frees all resources that were assigned to FM module. -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_FmPcd - FM PCD module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_PCD_Free(t_Handle h_FmPcd); -+ -+/**************************************************************************//** -+ @Group FM_PCD_advanced_cfg_grp FM PCD Advanced Configuration Unit -+ -+ @Description Frame Manager PCD Advanced Configuration API. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_PCD_ConfigException -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default selection of exceptions enabling. -+ [DEFAULT_numOfSharedPlcrProfiles]. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] exception The exception to be selected. -+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_PCD_ConfigHcFramesDataMemory -+ -+ @Description Configures memory-partition-id for FMan-Controller Host-Command -+ frames. Calling this routine changes the internal driver data -+ base from its default configuration [0]. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] memId Memory partition ID. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions This routine may be called only if 'useHostCommand' was TRUE -+ when FM_PCD_Config() routine was called. -+*//***************************************************************************/ -+t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId); -+ -+/**************************************************************************//** -+ @Function FM_PCD_ConfigPlcrNumOfSharedProfiles -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default selection of exceptions enablement. -+ [DEFAULT_numOfSharedPlcrProfiles]. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] numOfSharedPlcrProfiles Number of profiles to -+ be shared between ports on this partition -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles); -+ -+/**************************************************************************//** -+ @Function FM_PCD_ConfigPlcrAutoRefreshMode -+ -+ @Description Calling this routine changes the internal driver data base -+ from its default selection of exceptions enablement. -+ By default auto-refresh is [DEFAULT_plcrAutoRefresh]. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] enable TRUE to enable, FALSE to disable -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_PCD_ConfigPrsMaxCycleLimit -+ -+ @Description Calling this routine changes the internal data structure for -+ the maximum parsing time from its default value -+ [DEFAULT_MAX_PRS_CYC_LIM]. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] value 0 to disable the mechanism, or new -+ maximum parsing time. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value); -+ -+/** @} */ /* end of FM_PCD_advanced_cfg_grp group */ -+/** @} */ /* end of FM_PCD_init_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_PCD_Runtime_grp FM PCD Runtime Unit -+ -+ @Description Frame Manager PCD Runtime Unit API -+ -+ The runtime control allows creation of PCD infrastructure modules -+ such as Network Environment Characteristics, Classification Plan -+ Groups and Coarse Classification Trees. -+ It also allows on-the-fly initialization, modification and removal -+ of PCD modules such as KeyGen schemes, coarse classification nodes -+ and Policer profiles. -+ -+ In order to explain the programming model of the PCD driver interface -+ a few terms should be explained, and will be used below. -+ - Distinction Header - One of the 16 protocols supported by the FM parser, -+ or one of the SHIM headers (1 or 2). May be a header with a special -+ option (see below). -+ - Interchangeable Headers Group - This is a group of Headers recognized -+ by either one of them. For example, if in a specific context the user -+ chooses to treat IPv4 and IPV6 in the same way, they may create an -+ interchangeable Headers Unit consisting of these 2 headers. -+ - A Distinction Unit - a Distinction Header or an Interchangeable Headers -+ Group. -+ - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and -+ IPv6, includes multicast, broadcast and other protocol specific options. -+ In terms of hardware it relates to the options available in the classification -+ plan. -+ - Network Environment Characteristics - a set of Distinction Units that define -+ the total recognizable header selection for a certain environment. This is -+ NOT the list of all headers that will ever appear in a flow, but rather -+ everything that needs distinction in a flow, where distinction is made by KeyGen -+ schemes and coarse classification action descriptors. -+ -+ The PCD runtime modules initialization is done in stages. The first stage after -+ initializing the PCD module itself is to establish a Network Flows Environment -+ Definition. The application may choose to establish one or more such environments. -+ Later, when needed, the application will have to state, for some of its modules, -+ to which single environment it belongs. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description A structure for SW parser labels -+ *//***************************************************************************/ -+typedef struct t_FmPcdPrsLabelParams { -+ uint32_t instructionOffset; /**< SW parser label instruction offset (2 bytes -+ resolution), relative to Parser RAM. */ -+ e_NetHeaderType hdr; /**< The existence of this header will invoke -+ the SW parser code; Use HEADER_TYPE_NONE -+ to indicate that sw parser is to run -+ independent of the existence of any protocol -+ (run before HW parser). */ -+ uint8_t indexPerHdr; /**< Normally 0, if more than one SW parser -+ attachments for the same header, use this -+ index to distinguish between them. */ -+} t_FmPcdPrsLabelParams; -+ -+/**************************************************************************//** -+ @Description A structure for SW parser -+ *//***************************************************************************/ -+typedef struct t_FmPcdPrsSwParams { -+ bool override; /**< FALSE to invoke a check that nothing else -+ was loaded to this address, including -+ internal patches. -+ TRUE to override any existing code.*/ -+ uint32_t size; /**< SW parser code size */ -+ uint16_t base; /**< SW parser base (in instruction counts! -+ must be larger than 0x20)*/ -+ uint8_t *p_Code; /**< SW parser code */ -+ uint32_t swPrsDataParams[FM_PCD_PRS_NUM_OF_HDRS]; -+ /**< SW parser data (parameters) */ -+ uint8_t numOfLabels; /**< Number of labels for SW parser. */ -+ t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS]; -+ /**< SW parser labels table, containing -+ numOfLabels entries */ -+} t_FmPcdPrsSwParams; -+ -+ -+/**************************************************************************//** -+ @Function FM_PCD_Enable -+ -+ @Description This routine should be called after PCD is initialized for enabling all -+ PCD engines according to their existing configuration. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled. -+*//***************************************************************************/ -+t_Error FM_PCD_Enable(t_Handle h_FmPcd); -+ -+/**************************************************************************//** -+ @Function FM_PCD_Disable -+ -+ @Description This routine may be called when PCD is enabled in order to -+ disable all PCD engines. It may be called -+ only when none of the ports in the system are using the PCD. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init() and when PCD is enabled. -+*//***************************************************************************/ -+t_Error FM_PCD_Disable(t_Handle h_FmPcd); -+ -+/**************************************************************************//** -+ @Function FM_PCD_GetCounter -+ -+ @Description Reads one of the FM PCD counters. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] counter The requested counter. -+ -+ @Return Counter's current value. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ Note that it is user's responsibility to call this routine only -+ for enabled counters, and there will be no indication if a -+ disabled counter is accessed. -+*//***************************************************************************/ -+uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter); -+ -+/**************************************************************************//** -+@Function FM_PCD_PrsLoadSw -+ -+@Description This routine may be called in order to load software parsing code. -+ -+ -+@Param[in] h_FmPcd FM PCD module descriptor. -+@Param[in] p_SwPrs A pointer to a structure of software -+ parser parameters, including the software -+ parser image. -+ -+@Return E_OK on success; Error code otherwise. -+ -+@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled. -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs); -+ -+/**************************************************************************//** -+@Function FM_PCD_SetAdvancedOffloadSupport -+ -+@Description This routine must be called in order to support the following features: -+ IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator. -+ -+@Param[in] h_FmPcd FM PCD module descriptor. -+ -+@Return E_OK on success; Error code otherwise. -+ -+@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled. -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd); -+ -+/**************************************************************************//** -+ @Function FM_PCD_KgSetDfltValue -+ -+ @Description Calling this routine sets a global default value to be used -+ by the KeyGen when parser does not recognize a required -+ field/header. -+ By default default values are 0. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] valueId 0,1 - one of 2 global default values. -+ @Param[in] value The requested default value. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled. -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value); -+ -+/**************************************************************************//** -+ @Function FM_PCD_KgSetAdditionalDataAfterParsing -+ -+ @Description Calling this routine allows the KeyGen to access data past -+ the parser finishing point. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] payloadOffset the number of bytes beyond the parser location. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled. -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset); -+ -+/**************************************************************************//** -+ @Function FM_PCD_SetException -+ -+ @Description Calling this routine enables/disables PCD interrupts. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] exception The exception to be selected. -+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_PCD_ModifyCounter -+ -+ @Description Sets a value to an enabled counter. Use "0" to reset the counter. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] counter The requested counter. -+ @Param[in] value The requested value to be written into the counter. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value); -+ -+/**************************************************************************//** -+ @Function FM_PCD_SetPlcrStatistics -+ -+ @Description This routine may be used to enable/disable policer statistics -+ counter. By default the statistics is enabled. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor -+ @Param[in] enable TRUE to enable, FALSE to disable. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_PCD_SetPrsStatistics -+ -+ @Description Defines whether to gather parser statistics including all ports. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] enable TRUE to enable, FALSE to disable. -+ -+ @Return None -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_PCD_HcTxConf -+ -+ @Description This routine should be called to confirm frames that were -+ received on the HC confirmation queue. -+ -+ @Param[in] h_FmPcd A handle to an FM PCD Module. -+ @Param[in] p_Fd Frame descriptor of the received frame. -+ -+ @Cautions Allowed only following FM_PCD_Init(). Allowed only if 'useHostCommand' -+ option was selected in the initialization. -+*//***************************************************************************/ -+void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd); -+ -+/**************************************************************************//* -+ @Function FM_PCD_ForceIntr -+ -+ @Description Causes an interrupt event on the requested source. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] exception An exception to be forced. -+ -+ @Return E_OK on success; Error code if the exception is not enabled, -+ or is not able to create interrupt. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception); -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+/**************************************************************************//** -+ @Function FM_PCD_DumpRegs -+ -+ @Description Dumps all PCD registers -+ -+ @Param[in] h_FmPcd A handle to an FM PCD Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ NOTE: this routine may be called only for FM in master mode -+ (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers -+ are mapped. -+*//***************************************************************************/ -+t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd); -+ -+/**************************************************************************//** -+ @Function FM_PCD_KgDumpRegs -+ -+ @Description Dumps all PCD KG registers -+ -+ @Param[in] h_FmPcd A handle to an FM PCD Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ NOTE: this routine may be called only for FM in master mode -+ (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers -+ are mapped. -+*//***************************************************************************/ -+t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd); -+ -+/**************************************************************************//** -+ @Function FM_PCD_PlcrDumpRegs -+ -+ @Description Dumps all PCD Policer registers -+ -+ @Param[in] h_FmPcd A handle to an FM PCD Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ NOTE: this routine may be called only for FM in master mode -+ (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers -+ are mapped. -+*//***************************************************************************/ -+t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd); -+ -+/**************************************************************************//** -+ @Function FM_PCD_PlcrProfileDumpRegs -+ -+ @Description Dumps all PCD Policer profile registers -+ -+ @Param[in] h_Profile A handle to a Policer profile. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ NOTE: this routine may be called only for FM in master mode -+ (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers -+ are mapped. -+*//***************************************************************************/ -+t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_Profile); -+ -+/**************************************************************************//** -+ @Function FM_PCD_PrsDumpRegs -+ -+ @Description Dumps all PCD Parser registers -+ -+ @Param[in] h_FmPcd A handle to an FM PCD Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ NOTE: this routine may be called only for FM in master mode -+ (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers -+ are mapped. -+*//***************************************************************************/ -+t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd); -+ -+/**************************************************************************//** -+ @Function FM_PCD_HcDumpRegs -+ -+ @Description Dumps HC Port registers -+ -+ @Param[in] h_FmPcd A handle to an FM PCD Module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+ NOTE: this routine may be called only for FM in master mode -+ (i.e. 'guestId'=NCSW_MASTER_ID). -+*//***************************************************************************/ -+t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ -+ -+/**************************************************************************//** -+ KeyGen FM_PCD_Runtime_build_grp FM PCD Runtime Building Unit -+ -+ @Description Frame Manager PCD Runtime Building API -+ -+ This group contains routines for setting, deleting and modifying -+ PCD resources, for defining the total PCD tree. -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Collection Definitions of coarse classification -+ parameters as required by KeyGen (when coarse classification -+ is the next engine after this scheme). -+*//***************************************************************************/ -+#define FM_PCD_MAX_NUM_OF_CC_TREES 8 -+#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16 -+#define FM_PCD_MAX_NUM_OF_CC_UNITS 4 -+#define FM_PCD_MAX_NUM_OF_KEYS 256 -+#define FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE) -+#define FM_PCD_MAX_SIZE_OF_KEY 56 -+#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16 -+#define FM_PCD_LAST_KEY_INDEX 0xffff -+ -+#define FM_PCD_MAX_NUM_OF_CC_NODES 255 /* Obsolete, not used - will be removed in the future */ -+/* @} */ -+ -+/**************************************************************************//** -+ @Collection A set of definitions to allow protocol -+ special option description. -+*//***************************************************************************/ -+typedef uint32_t protocolOpt_t; /**< A general type to define a protocol option. */ -+ -+typedef protocolOpt_t ethProtocolOpt_t; /**< Ethernet protocol options. */ -+#define ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */ -+#define ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */ -+ -+typedef protocolOpt_t vlanProtocolOpt_t; /**< VLAN protocol options. */ -+#define VLAN_STACKED 0x20000000 /**< Stacked VLAN. */ -+ -+typedef protocolOpt_t mplsProtocolOpt_t; /**< MPLS protocol options. */ -+#define MPLS_STACKED 0x10000000 /**< Stacked MPLS. */ -+ -+typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */ -+#define IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */ -+#define IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */ -+#define IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */ -+#define IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */ -+ -+#define IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option. -+ IPV4 Reassembly manipulation requires network -+ environment with IPV4 header and IPV4_FRAG_1 option */ -+ -+typedef protocolOpt_t ipv6ProtocolOpt_t; /**< IPv6 protocol options. */ -+#define IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */ -+#define IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */ -+#define IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */ -+ -+#define IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option. -+ IPV6 Reassembly manipulation requires network -+ environment with IPV6 header and IPV6_FRAG_1 option; -+ in case where fragment found, the fragment-extension offset -+ may be found at 'shim2' (in parser-result). */ -+#if (DPAA_VERSION >= 11) -+typedef protocolOpt_t capwapProtocolOpt_t; /**< CAPWAP protocol options. */ -+#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option. -+ CAPWAP Reassembly manipulation requires network -+ environment with CAPWAP header and CAPWAP_FRAG_1 option; -+ in case where fragment found, the fragment-extension offset -+ may be found at 'shim2' (in parser-result). */ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ -+/* @} */ -+ -+#define FM_PCD_MANIP_MAX_HDR_SIZE 256 -+#define FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64 -+ -+/**************************************************************************//** -+ @Collection A set of definitions to support Header Manipulation selection. -+*//***************************************************************************/ -+typedef uint32_t hdrManipFlags_t; /**< A general type to define a HMan update command flags. */ -+ -+typedef hdrManipFlags_t ipv4HdrManipUpdateFlags_t; /**< IPv4 protocol HMan update command flags. */ -+ -+#define HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field -+ of t_FmPcdManipHdrFieldUpdateIpv4) */ -+#define HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field -+ of t_FmPcdManipHdrFieldUpdateIpv4) */ -+#define HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */ -+#define HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value -+ ('src' field of t_FmPcdManipHdrFieldUpdateIpv4) */ -+#define HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value -+ ('dst' field of t_FmPcdManipHdrFieldUpdateIpv4) */ -+ -+typedef hdrManipFlags_t ipv6HdrManipUpdateFlags_t; /**< IPv6 protocol HMan update command flags. */ -+ -+#define HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value -+ ('trafficClass' field of t_FmPcdManipHdrFieldUpdateIpv6) */ -+#define HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */ -+#define HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value -+ ('src' field of t_FmPcdManipHdrFieldUpdateIpv6) */ -+#define HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value -+ ('dst' field of t_FmPcdManipHdrFieldUpdateIpv6) */ -+ -+typedef hdrManipFlags_t tcpUdpHdrManipUpdateFlags_t;/**< TCP/UDP protocol HMan update command flags. */ -+ -+#define HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value -+ ('src' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */ -+#define HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value -+ ('dst' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */ -+#define HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */ -+ -+/* @} */ -+ -+/**************************************************************************//** -+ @Description A type used for returning the order of the key extraction. -+ each value in this array represents the index of the extraction -+ command as defined by the user in the initialization extraction array. -+ The valid size of this array is the user define number of extractions -+ required (also marked by the second '0' in this array). -+*//***************************************************************************/ -+typedef uint8_t t_FmPcdKgKeyOrder [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; -+ -+/**************************************************************************//** -+ @Description All PCD engines -+*//***************************************************************************/ -+typedef enum e_FmPcdEngine { -+ e_FM_PCD_INVALID = 0, /**< Invalid PCD engine */ -+ e_FM_PCD_DONE, /**< No PCD Engine indicated */ -+ e_FM_PCD_KG, /**< KeyGen */ -+ e_FM_PCD_CC, /**< Coarse classifier */ -+ e_FM_PCD_PLCR, /**< Policer */ -+ e_FM_PCD_PRS, /**< Parser */ -+#if (DPAA_VERSION >= 11) -+ e_FM_PCD_FR, /**< Frame-Replicator */ -+#endif /* (DPAA_VERSION >= 11) */ -+ e_FM_PCD_HASH /**< Hash table */ -+} e_FmPcdEngine; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting extraction by header types -+*//***************************************************************************/ -+typedef enum e_FmPcdExtractByHdrType { -+ e_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */ -+ e_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */ -+ e_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */ -+} e_FmPcdExtractByHdrType; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting extraction source -+ (when it is not the header) -+*//***************************************************************************/ -+typedef enum e_FmPcdExtractFrom { -+ e_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */ -+ e_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */ -+ e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG & CC: Extract from the point where parsing had finished */ -+ e_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */ -+ e_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */ -+ e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG only: Extract from the parser result */ -+ e_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */ -+ e_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */ -+} e_FmPcdExtractFrom; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting extraction type -+*//***************************************************************************/ -+typedef enum e_FmPcdExtractType { -+ e_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */ -+ e_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */ -+ e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */ -+} e_FmPcdExtractType; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting default extraction value -+*//***************************************************************************/ -+typedef enum e_FmPcdKgExtractDfltSelect { -+ e_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */ -+ e_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */ -+ e_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */ -+ e_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */ -+ e_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */ -+} e_FmPcdKgExtractDfltSelect; -+ -+/**************************************************************************//** -+ @Description Enumeration type defining all default groups - each group shares -+ a default value, one of four user-initialized values. -+*//***************************************************************************/ -+typedef enum e_FmPcdKgKnownFieldsDfltTypes { -+ e_FM_PCD_KG_MAC_ADDR, /**< MAC Address */ -+ e_FM_PCD_KG_TCI, /**< TCI field */ -+ e_FM_PCD_KG_ENET_TYPE, /**< ENET Type */ -+ e_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */ -+ e_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */ -+ e_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */ -+ e_FM_PCD_KG_IP_ADDR, /**< IP address */ -+ e_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */ -+ e_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */ -+ e_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */ -+ e_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */ -+ e_FM_PCD_KG_L4_PORT, /**< L4 Port */ -+ e_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */ -+ e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW, -+ any data extraction that is not the full -+ field described above */ -+ e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW, -+ any data extraction without validation */ -+ e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW, -+ extraction from parser result or -+ direct use of default value */ -+} e_FmPcdKgKnownFieldsDfltTypes; -+ -+/**************************************************************************//** -+ @Description Enumeration type for defining header index for scenarios with -+ multiple (tunneled) headers -+*//***************************************************************************/ -+typedef enum e_FmPcdHdrIndex { -+ e_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also -+ to specify regular IP (not tunneled). */ -+ e_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */ -+ e_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */ -+ e_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */ -+ e_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */ -+} e_FmPcdHdrIndex; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the policer profile functional type -+*//***************************************************************************/ -+typedef enum e_FmPcdProfileTypeSelection { -+ e_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */ -+ e_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */ -+} e_FmPcdProfileTypeSelection; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the policer profile algorithm -+*//***************************************************************************/ -+typedef enum e_FmPcdPlcrAlgorithmSelection { -+ e_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */ -+ e_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */ -+ e_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */ -+} e_FmPcdPlcrAlgorithmSelection; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting a policer profile color mode -+*//***************************************************************************/ -+typedef enum e_FmPcdPlcrColorMode { -+ e_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */ -+ e_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */ -+} e_FmPcdPlcrColorMode; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting a policer profile color -+*//***************************************************************************/ -+typedef enum e_FmPcdPlcrColor { -+ e_FM_PCD_PLCR_GREEN, /**< Green color code */ -+ e_FM_PCD_PLCR_YELLOW, /**< Yellow color code */ -+ e_FM_PCD_PLCR_RED, /**< Red color code */ -+ e_FM_PCD_PLCR_OVERRIDE /**< Color override code */ -+} e_FmPcdPlcrColor; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the policer profile packet frame length selector -+*//***************************************************************************/ -+typedef enum e_FmPcdPlcrFrameLengthSelect { -+ e_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */ -+ e_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */ -+ e_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */ -+ e_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */ -+} e_FmPcdPlcrFrameLengthSelect; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting roll-back frame -+*//***************************************************************************/ -+typedef enum e_FmPcdPlcrRollBackFrameSelect { -+ e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Roll-back L2 frame length */ -+ e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Roll-back Full frame length */ -+} e_FmPcdPlcrRollBackFrameSelect; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the policer profile packet or byte mode -+*//***************************************************************************/ -+typedef enum e_FmPcdPlcrRateMode { -+ e_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */ -+ e_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */ -+} e_FmPcdPlcrRateMode; -+ -+/**************************************************************************//** -+ @Description Enumeration type for defining action of frame -+*//***************************************************************************/ -+typedef enum e_FmPcdDoneAction { -+ e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */ -+ e_FM_PCD_DROP_FRAME /**< Mark this frame as error frame and continue -+ to error flow; 'FM_PORT_FRM_ERR_CLS_DISCARD' -+ flag will be set for this frame. */ -+} e_FmPcdDoneAction; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the policer counter -+*//***************************************************************************/ -+typedef enum e_FmPcdPlcrProfileCounters { -+ e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */ -+ e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */ -+ e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */ -+ e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */ -+ e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */ -+} e_FmPcdPlcrProfileCounters; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the PCD action after extraction -+*//***************************************************************************/ -+typedef enum e_FmPcdAction { -+ e_FM_PCD_ACTION_NONE, /**< NONE */ -+ e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction */ -+ e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction */ -+} e_FmPcdAction; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of insert manipulation -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrInsrtType { -+ e_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */ -+ e_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */ -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+ e_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */ -+#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+} e_FmPcdManipHdrInsrtType; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of remove manipulation -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrRmvType { -+ e_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */ -+ e_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */ -+} e_FmPcdManipHdrRmvType; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting specific L2 fields removal -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrRmvSpecificL2 { -+ e_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */ -+ e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */ -+ e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until -+ the header which follows the MPLS header */ -+ e_FM_PCD_MANIP_HDR_RMV_MPLS, /**< Remove MPLS header (Unlimited MPLS labels) */ -+ e_FM_PCD_MANIP_HDR_RMV_PPPOE /**< Remove the PPPoE header and PPP protocol field. */ -+} e_FmPcdManipHdrRmvSpecificL2; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting specific fields updates -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrFieldUpdateType { -+ e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */ -+ e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */ -+ e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */ -+ e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */ -+} e_FmPcdManipHdrFieldUpdateType; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting VLAN updates -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrFieldUpdateVlan { -+ e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */ -+ e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */ -+} e_FmPcdManipHdrFieldUpdateVlan; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting specific L2 header insertion -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrInsrtSpecificL2 { -+ e_FM_PCD_MANIP_HDR_INSRT_MPLS, /**< Insert MPLS header (Unlimited MPLS labels) */ -+ e_FM_PCD_MANIP_HDR_INSRT_PPPOE /**< Insert PPPOE */ -+} e_FmPcdManipHdrInsrtSpecificL2; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Enumeration type for selecting QoS mapping mode -+ -+ Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE' -+ User should instruct the port to read the hash-result -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrQosMappingMode { -+ e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */ -+ e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the hash-result. */ -+} e_FmPcdManipHdrQosMappingMode; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting QoS source -+ -+ Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE' -+ User should left room for the hash-result on input/output buffer -+ and instruct the port to read/write the hash-result to the buffer (RPD should be set) -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrQosSrc { -+ e_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */ -+ e_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the hash-result. */ -+} e_FmPcdManipHdrQosSrc; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of header insertion -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrInsrtByHdrType { -+ e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */ -+#if (DPAA_VERSION >= 11) -+ e_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */ -+ e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */ -+ e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */ -+ e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */ -+#endif /* (DPAA_VERSION >= 11) */ -+} e_FmPcdManipHdrInsrtByHdrType; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting specific customCommand -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrCustomType { -+ e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */ -+ e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE, /**< Replace IPv4/IPv6 */ -+} e_FmPcdManipHdrCustomType; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting specific customCommand -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrCustomIpReplace { -+ e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */ -+ e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */ -+} e_FmPcdManipHdrCustomIpReplace; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of header removal -+*//***************************************************************************/ -+typedef enum e_FmPcdManipHdrRmvByHdrType { -+ e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */ -+#if (DPAA_VERSION >= 11) -+ e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */ -+#endif /* (DPAA_VERSION >= 11) */ -+#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+ e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */ -+#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+} e_FmPcdManipHdrRmvByHdrType; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of timeout mode -+*//***************************************************************************/ -+typedef enum e_FmPcdManipReassemTimeOutMode { -+ e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process -+ from the first fragment to the last */ -+ e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */ -+} e_FmPcdManipReassemTimeOutMode; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of WaysNumber mode -+*//***************************************************************************/ -+typedef enum e_FmPcdManipReassemWaysNumber { -+ e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */ -+ e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */ -+ e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */ -+ e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */ -+ e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */ -+ e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */ -+ e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */ -+ e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */ -+} e_FmPcdManipReassemWaysNumber; -+ -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of statistics mode -+*//***************************************************************************/ -+typedef enum e_FmPcdStatsType { -+ e_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */ -+} e_FmPcdStatsType; -+#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting manipulation type -+*//***************************************************************************/ -+typedef enum e_FmPcdManipType { -+ e_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */ -+ e_FM_PCD_MANIP_REASSEM, /**< Reassembly */ -+ e_FM_PCD_MANIP_FRAG, /**< Fragmentation */ -+ e_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */ -+} e_FmPcdManipType; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of statistics mode -+*//***************************************************************************/ -+typedef enum e_FmPcdCcStatsMode { -+ e_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */ -+ e_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */ -+ e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */ -+#if (DPAA_VERSION >= 11) -+ e_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics; -+ This mode is supported only on B4860 device */ -+#endif /* (DPAA_VERSION >= 11) */ -+} e_FmPcdCcStatsMode; -+ -+/**************************************************************************//** -+ @Description Enumeration type for determining the action in case an IP packet -+ is larger than MTU but its DF (Don't Fragment) bit is set. -+*//***************************************************************************/ -+typedef enum e_FmPcdManipDontFragAction { -+ e_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */ -+ e_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_FM_PCD_MANIP_DISCARD_PACKET, -+ /**< Obsolete, cannot enqueue to error queue; -+ In practice, selects to discard packets; -+ Will be removed in the future */ -+ e_FM_PCD_MANIP_FRAGMENT_PACKET, /**< Fragment packet and continue normal processing */ -+ e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */ -+} e_FmPcdManipDontFragAction; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of special offload manipulation -+*//***************************************************************************/ -+typedef enum e_FmPcdManipSpecialOffloadType { -+ e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */ -+#if (DPAA_VERSION >= 11) -+ e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */ -+#endif /* (DPAA_VERSION >= 11) */ -+} e_FmPcdManipSpecialOffloadType; -+ -+ -+/**************************************************************************//** -+ @Description A Union of protocol dependent special options -+*//***************************************************************************/ -+typedef union u_FmPcdHdrProtocolOpt { -+ ethProtocolOpt_t ethOpt; /**< Ethernet options */ -+ vlanProtocolOpt_t vlanOpt; /**< VLAN options */ -+ mplsProtocolOpt_t mplsOpt; /**< MPLS options */ -+ ipv4ProtocolOpt_t ipv4Opt; /**< IPv4 options */ -+ ipv6ProtocolOpt_t ipv6Opt; /**< IPv6 options */ -+#if (DPAA_VERSION >= 11) -+ capwapProtocolOpt_t capwapOpt; /**< CAPWAP options */ -+#endif /* (DPAA_VERSION >= 11) */ -+} u_FmPcdHdrProtocolOpt; -+ -+/**************************************************************************//** -+ @Description A union holding protocol fields -+ -+ -+ Fields supported as "full fields": -+ HEADER_TYPE_ETH: -+ NET_HEADER_FIELD_ETH_DA -+ NET_HEADER_FIELD_ETH_SA -+ NET_HEADER_FIELD_ETH_TYPE -+ -+ HEADER_TYPE_LLC_SNAP: -+ NET_HEADER_FIELD_LLC_SNAP_TYPE -+ -+ HEADER_TYPE_VLAN: -+ NET_HEADER_FIELD_VLAN_TCI -+ (index may apply: -+ e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, -+ e_FM_PCD_HDR_INDEX_LAST) -+ -+ HEADER_TYPE_MPLS: -+ NET_HEADER_FIELD_MPLS_LABEL_STACK -+ (index may apply: -+ e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, -+ e_FM_PCD_HDR_INDEX_2, -+ e_FM_PCD_HDR_INDEX_LAST) -+ -+ HEADER_TYPE_IPv4: -+ NET_HEADER_FIELD_IPv4_SRC_IP -+ NET_HEADER_FIELD_IPv4_DST_IP -+ NET_HEADER_FIELD_IPv4_PROTO -+ NET_HEADER_FIELD_IPv4_TOS -+ (index may apply: -+ e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, -+ e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST) -+ -+ HEADER_TYPE_IPv6: -+ NET_HEADER_FIELD_IPv6_SRC_IP -+ NET_HEADER_FIELD_IPv6_DST_IP -+ NET_HEADER_FIELD_IPv6_NEXT_HDR -+ NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC (must come together!) -+ (index may apply: -+ e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, -+ e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST) -+ -+ (Note that starting from DPAA 1-1, NET_HEADER_FIELD_IPv6_NEXT_HDR applies to -+ the last next header indication, meaning the next L4, which may be -+ present at the Ipv6 last extension. On earlier revisions this field -+ applies to the Next-Header field of the main IPv6 header) -+ -+ HEADER_TYPE_IP: -+ NET_HEADER_FIELD_IP_PROTO -+ (index may apply: -+ e_FM_PCD_HDR_INDEX_LAST) -+ NET_HEADER_FIELD_IP_DSCP -+ (index may apply: -+ e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1) -+ HEADER_TYPE_GRE: -+ NET_HEADER_FIELD_GRE_TYPE -+ -+ HEADER_TYPE_MINENCAP -+ NET_HEADER_FIELD_MINENCAP_SRC_IP -+ NET_HEADER_FIELD_MINENCAP_DST_IP -+ NET_HEADER_FIELD_MINENCAP_TYPE -+ -+ HEADER_TYPE_TCP: -+ NET_HEADER_FIELD_TCP_PORT_SRC -+ NET_HEADER_FIELD_TCP_PORT_DST -+ NET_HEADER_FIELD_TCP_FLAGS -+ -+ HEADER_TYPE_UDP: -+ NET_HEADER_FIELD_UDP_PORT_SRC -+ NET_HEADER_FIELD_UDP_PORT_DST -+ -+ HEADER_TYPE_UDP_LITE: -+ NET_HEADER_FIELD_UDP_LITE_PORT_SRC -+ NET_HEADER_FIELD_UDP_LITE_PORT_DST -+ -+ HEADER_TYPE_IPSEC_AH: -+ NET_HEADER_FIELD_IPSEC_AH_SPI -+ NET_HEADER_FIELD_IPSEC_AH_NH -+ -+ HEADER_TYPE_IPSEC_ESP: -+ NET_HEADER_FIELD_IPSEC_ESP_SPI -+ -+ HEADER_TYPE_SCTP: -+ NET_HEADER_FIELD_SCTP_PORT_SRC -+ NET_HEADER_FIELD_SCTP_PORT_DST -+ -+ HEADER_TYPE_DCCP: -+ NET_HEADER_FIELD_DCCP_PORT_SRC -+ NET_HEADER_FIELD_DCCP_PORT_DST -+ -+ HEADER_TYPE_PPPoE: -+ NET_HEADER_FIELD_PPPoE_PID -+ NET_HEADER_FIELD_PPPoE_SID -+ -+ ***************************************************************** -+ Fields supported as "from fields": -+ HEADER_TYPE_ETH (with or without validation): -+ NET_HEADER_FIELD_ETH_TYPE -+ -+ HEADER_TYPE_VLAN (with or without validation): -+ NET_HEADER_FIELD_VLAN_TCI -+ (index may apply: -+ e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, -+ e_FM_PCD_HDR_INDEX_LAST) -+ -+ HEADER_TYPE_IPv4 (without validation): -+ NET_HEADER_FIELD_IPv4_PROTO -+ (index may apply: -+ e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, -+ e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST) -+ -+ HEADER_TYPE_IPv6 (without validation): -+ NET_HEADER_FIELD_IPv6_NEXT_HDR -+ (index may apply: -+ e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1, -+ e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST) -+ -+*//***************************************************************************/ -+typedef union t_FmPcdFields { -+ headerFieldEth_t eth; /**< Ethernet */ -+ headerFieldVlan_t vlan; /**< VLAN */ -+ headerFieldLlcSnap_t llcSnap; /**< LLC SNAP */ -+ headerFieldPppoe_t pppoe; /**< PPPoE */ -+ headerFieldMpls_t mpls; /**< MPLS */ -+ headerFieldIp_t ip; /**< IP */ -+ headerFieldIpv4_t ipv4; /**< IPv4 */ -+ headerFieldIpv6_t ipv6; /**< IPv6 */ -+ headerFieldUdp_t udp; /**< UDP */ -+ headerFieldUdpLite_t udpLite; /**< UDP Lite */ -+ headerFieldTcp_t tcp; /**< TCP */ -+ headerFieldSctp_t sctp; /**< SCTP */ -+ headerFieldDccp_t dccp; /**< DCCP */ -+ headerFieldGre_t gre; /**< GRE */ -+ headerFieldMinencap_t minencap; /**< Minimal Encapsulation */ -+ headerFieldIpsecAh_t ipsecAh; /**< IPSec AH */ -+ headerFieldIpsecEsp_t ipsecEsp; /**< IPSec ESP */ -+ headerFieldUdpEncapEsp_t udpEncapEsp; /**< UDP Encapsulation ESP */ -+} t_FmPcdFields; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header extraction for key generation -+*//***************************************************************************/ -+typedef struct t_FmPcdFromHdr { -+ uint8_t size; /**< Size in byte */ -+ uint8_t offset; /**< Byte offset */ -+} t_FmPcdFromHdr; -+ -+/**************************************************************************//** -+ @Description Parameters for defining field extraction for key generation -+*//***************************************************************************/ -+typedef struct t_FmPcdFromField { -+ t_FmPcdFields field; /**< Field selection */ -+ uint8_t size; /**< Size in byte */ -+ uint8_t offset; /**< Byte offset */ -+} t_FmPcdFromField; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a single network environment unit -+ -+ A distinction unit should be defined if it will later be used -+ by one or more PCD engines to distinguish between flows. -+*//***************************************************************************/ -+typedef struct t_FmPcdDistinctionUnit { -+ struct { -+ e_NetHeaderType hdr; /**< One of the headers supported by the FM */ -+ u_FmPcdHdrProtocolOpt opt; /**< Select only one option ! */ -+ } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS]; -+} t_FmPcdDistinctionUnit; -+ -+/**************************************************************************//** -+ @Description Parameters for defining all different distinction units supported -+ by a specific PCD Network Environment Characteristics module. -+ -+ Each unit represent a protocol or a group of protocols that may -+ be used later by the different PCD engines to distinguish -+ between flows. -+*//***************************************************************************/ -+typedef struct t_FmPcdNetEnvParams { -+ uint8_t numOfDistinctionUnits; /**< Number of different units to be identified */ -+ t_FmPcdDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /**< An array of numOfDistinctionUnits of the -+ different units to be identified */ -+} t_FmPcdNetEnvParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a single extraction action when -+ creating a key -+*//***************************************************************************/ -+typedef struct t_FmPcdExtractEntry { -+ e_FmPcdExtractType type; /**< Extraction type select */ -+ union { -+ struct { -+ e_NetHeaderType hdr; /**< Header selection */ -+ bool ignoreProtocolValidation; -+ /**< Ignore protocol validation */ -+ e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled -+ IP. Otherwise should be cleared. */ -+ e_FmPcdExtractByHdrType type; /**< Header extraction type select */ -+ union { -+ t_FmPcdFromHdr fromHdr; /**< Extract bytes from header parameters */ -+ t_FmPcdFromField fromField; /**< Extract bytes from field parameters */ -+ t_FmPcdFields fullField; /**< Extract full filed parameters */ -+ } extractByHdrType; -+ } extractByHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */ -+ struct { -+ e_FmPcdExtractFrom src; /**< Non-header extraction source */ -+ e_FmPcdAction action; /**< Relevant for CC Only */ -+ uint16_t icIndxMask; /**< Relevant only for CC when -+ action = e_FM_PCD_ACTION_INDEXED_LOOKUP; -+ Note that the number of bits that are set within -+ this mask must be log2 of the CC-node 'numOfKeys'. -+ Note that the mask cannot be set on the lower bits. */ -+ uint8_t offset; /**< Byte offset */ -+ uint8_t size; /**< Size in byte */ -+ } extractNonHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */ -+ }; -+} t_FmPcdExtractEntry; -+ -+/**************************************************************************//** -+ @Description Parameters for defining masks for each extracted field in the key. -+*//***************************************************************************/ -+typedef struct t_FmPcdKgExtractMask { -+ uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */ -+ uint8_t offset; /**< Byte offset */ -+ uint8_t mask; /**< A byte mask (selected bits will be used) */ -+} t_FmPcdKgExtractMask; -+ -+/**************************************************************************//** -+ @Description Parameters for defining default selection per groups of fields -+*//***************************************************************************/ -+typedef struct t_FmPcdKgExtractDflt { -+ e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select */ -+ e_FmPcdKgExtractDfltSelect dfltSelect; /**< Default register select */ -+} t_FmPcdKgExtractDflt; -+ -+/**************************************************************************//** -+ @Description Parameters for defining key extraction and hashing -+*//***************************************************************************/ -+typedef struct t_FmPcdKgKeyExtractAndHashParams { -+ uint32_t privateDflt0; /**< Scheme default register 0 */ -+ uint32_t privateDflt1; /**< Scheme default register 1 */ -+ uint8_t numOfUsedExtracts; /**< defines the valid size of the following array */ -+ t_FmPcdExtractEntry extractArray [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; /**< An array of extractions definition. */ -+ uint8_t numOfUsedDflts; /**< defines the valid size of the following array */ -+ t_FmPcdKgExtractDflt dflts[FM_PCD_KG_NUM_OF_DEFAULT_GROUPS]; -+ /**< For each extraction used in this scheme, specify the required -+ default register to be used when header is not found. -+ types not specified in this array will get undefined value. */ -+ uint8_t numOfUsedMasks; /**< defines the valid size of the following array */ -+ t_FmPcdKgExtractMask masks[FM_PCD_KG_NUM_OF_EXTRACT_MASKS]; -+ uint8_t hashShift; /**< hash result right shift. Select the 24 bits out of the 64 hash -+ result. 0 means using the 24 LSB's, otherwise use the -+ 24 LSB's after shifting right.*/ -+ uint32_t hashDistributionNumOfFqids; /**< must be > 1 and a power of 2. Represents the range -+ of queues for the key and hash functionality */ -+ uint8_t hashDistributionFqidsShift; /**< selects the FQID bits that will be effected by the hash */ -+ bool symmetricHash; /**< TRUE to generate the same hash for frames with swapped source and -+ destination fields on all layers; If TRUE, driver will check that for -+ all layers, if SRC extraction is selected, DST extraction must also be -+ selected, and vice versa. */ -+} t_FmPcdKgKeyExtractAndHashParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a single FQID mask (extracted OR). -+*//***************************************************************************/ -+typedef struct t_FmPcdKgExtractedOrParams { -+ e_FmPcdExtractType type; /**< Extraction type select */ -+ union { -+ struct { /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */ -+ e_NetHeaderType hdr; -+ e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled -+ IP. Otherwise should be cleared.*/ -+ bool ignoreProtocolValidation; -+ /**< continue extraction even if protocol is not recognized */ -+ } extractByHdr; /**< Header to extract by */ -+ e_FmPcdExtractFrom src; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */ -+ }; -+ uint8_t extractionOffset; /**< Offset for extraction (in bytes). */ -+ e_FmPcdKgExtractDfltSelect dfltValue; /**< Select register from which extraction is taken if -+ field not found */ -+ uint8_t mask; /**< Extraction mask (specified bits are used) */ -+ uint8_t bitOffsetInFqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using -+ the extracted byte; Assume byte is placed as the 8 MSB's in -+ a 32 bit word where the lower bits -+ are the FQID; i.e if bitOffsetInFqid=1 than its LSB -+ will effect the FQID MSB, if bitOffsetInFqid=24 than the -+ extracted byte will effect the 8 LSB's of the FQID, -+ if bitOffsetInFqid=31 than the byte's MSB will effect -+ the FQID's LSB; 0 means - no effect on FQID; -+ Note that one, and only one of -+ bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e, -+ extracted byte must effect either FQID or Policer profile).*/ -+ uint8_t bitOffsetInPlcrProfile; -+ /**< 0-15, Selects which bits of the 8 policer profile id bits to -+ effect using the extracted byte; Assume byte is placed -+ as the 8 MSB's in a 16 bit word where the lower bits -+ are the policer profile id; i.e if bitOffsetInPlcrProfile=1 -+ than its LSB will effect the profile MSB, if bitOffsetInFqid=8 -+ than the extracted byte will effect the whole policer profile id, -+ if bitOffsetInFqid=15 than the byte's MSB will effect -+ the Policer Profile id's LSB; -+ 0 means - no effect on policer profile; Note that one, and only one of -+ bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e, -+ extracted byte must effect either FQID or Policer profile).*/ -+} t_FmPcdKgExtractedOrParams; -+ -+/**************************************************************************//** -+ @Description Parameters for configuring a scheme counter -+*//***************************************************************************/ -+typedef struct t_FmPcdKgSchemeCounter { -+ bool update; /**< FALSE to keep the current counter state -+ and continue from that point, TRUE to update/reset -+ the counter when the scheme is written. */ -+ uint32_t value; /**< If update=TRUE, this value will be written into the -+ counter. clear this field to reset the counter. */ -+} t_FmPcdKgSchemeCounter; -+ -+/**************************************************************************//** -+ @Description Parameters for configuring a policer profile for a KeyGen scheme -+ (when policer is the next engine after this scheme). -+*//***************************************************************************/ -+typedef struct t_FmPcdKgPlcrProfile { -+ bool sharedProfile; /**< TRUE if this profile is shared between ports -+ (managed by master partition); Must not be TRUE -+ if profile is after Coarse Classification*/ -+ bool direct; /**< if TRUE, directRelativeProfileId only selects the profile -+ id, if FALSE fqidOffsetRelativeProfileIdBase is used -+ together with fqidOffsetShift and numOfProfiles -+ parameters, to define a range of profiles from -+ which the KeyGen result will determine the -+ destination policer profile. */ -+ union { -+ uint16_t directRelativeProfileId; /**< Used if 'direct' is TRUE, to select policer profile. -+ should indicate the policer profile offset within the -+ port's policer profiles or shared window. */ -+ struct { -+ uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the -+ final FQID - without the FQID base). */ -+ uint8_t fqidOffsetRelativeProfileIdBase; -+ /**< The base of the FMan Port's relative Storage-Profile ID; -+ this value will be "OR'ed" with the KeyGen create FQID -+ offset (i.e. not the final FQID - without the FQID base); -+ the final result should indicate the Storage-Profile offset -+ within the FMan Port's relative Storage-Profiles window/ -+ (or the SHARED window depends on 'sharedProfile'). */ -+ uint8_t numOfProfiles; /**< Range of profiles starting at base */ -+ } indirectProfile; /**< Indirect profile parameters */ -+ } profileSelect; /**< Direct/indirect profile selection and parameters */ -+} t_FmPcdKgPlcrProfile; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Parameters for configuring a storage profile for a KeyGen scheme. -+*//***************************************************************************/ -+typedef struct t_FmPcdKgStorageProfile { -+ bool direct; /**< If TRUE, directRelativeProfileId only selects the -+ profile id; -+ If FALSE, fqidOffsetRelativeProfileIdBase is used -+ together with fqidOffsetShift and numOfProfiles -+ parameters to define a range of profiles from which -+ the KeyGen result will determine the destination -+ storage profile. */ -+ union { -+ uint16_t directRelativeProfileId; /**< Used when 'direct' is TRUE, to select a storage profile; -+ should indicate the storage profile offset within the -+ port's storage profiles window. */ -+ struct { -+ uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the -+ final FQID - without the FQID base). */ -+ uint8_t fqidOffsetRelativeProfileIdBase; -+ /**< The base of the FMan Port's relative Storage-Profile ID; -+ this value will be "OR'ed" with the KeyGen create FQID -+ offset (i.e. not the final FQID - without the FQID base); -+ the final result should indicate the Storage-Profile offset -+ within the FMan Port's relative Storage-Profiles window. */ -+ uint8_t numOfProfiles; /**< Range of profiles starting at base. */ -+ } indirectProfile; /**< Indirect profile parameters. */ -+ } profileSelect; /**< Direct/indirect profile selection and parameters. */ -+} t_FmPcdKgStorageProfile; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Description Parameters for defining CC as the next engine after KeyGen -+*//***************************************************************************/ -+typedef struct t_FmPcdKgCc { -+ t_Handle h_CcTree; /**< A handle to a CC Tree */ -+ uint8_t grpId; /**< CC group id within the CC tree */ -+ bool plcrNext; /**< TRUE if after CC, in case of data frame, -+ policing is required. */ -+ bool bypassPlcrProfileGeneration; /**< TRUE to bypass KeyGen policer profile generation; -+ selected profile is the one set at port initialization. */ -+ t_FmPcdKgPlcrProfile plcrProfile; /**< Valid only if plcrNext = TRUE and -+ bypassPlcrProfileGeneration = FALSE */ -+} t_FmPcdKgCc; -+ -+/**************************************************************************//** -+ @Description Parameters for defining initializing a KeyGen scheme -+*//***************************************************************************/ -+typedef struct t_FmPcdKgSchemeParams { -+ bool modify; /**< TRUE to change an existing scheme */ -+ union -+ { -+ uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */ -+ t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */ -+ } id; -+ bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need -+ for match vector; KeyGen will ignore it when matching */ -+ struct { /**< HL Relevant only if alwaysDirect = FALSE */ -+ t_Handle h_NetEnv; /**< A handle to the Network environment as returned -+ by FM_PCD_NetEnvCharacteristicsSet() */ -+ uint8_t numOfDistinctionUnits; /**< Number of NetEnv units listed in unitIds array */ -+ uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; -+ /**< Indexes as passed to SetNetEnvCharacteristics array*/ -+ } netEnvParams; -+ bool useHash; /**< use the KeyGen Hash functionality */ -+ t_FmPcdKgKeyExtractAndHashParams keyExtractAndHashParams; -+ /**< used only if useHash = TRUE */ -+ bool bypassFqidGeneration; /**< Normally - FALSE, TRUE to avoid FQID update in the IC; -+ In such a case FQID after KeyGen will be the default FQID -+ defined for the relevant port, or the FQID defined by CC -+ in cases where CC was the previous engine. */ -+ uint32_t baseFqid; /**< Base FQID; Relevant only if bypassFqidGeneration = FALSE; -+ If hash is used and an even distribution is expected -+ according to hashDistributionNumOfFqids, baseFqid must be aligned to -+ hashDistributionNumOfFqids. */ -+ uint8_t numOfUsedExtractedOrs; /**< Number of FQID masks listed in extractedOrs array */ -+ t_FmPcdKgExtractedOrParams extractedOrs[FM_PCD_KG_NUM_OF_GENERIC_REGS]; -+ /**< FM_PCD_KG_NUM_OF_GENERIC_REGS -+ registers are shared between qidMasks -+ functionality and some of the extraction -+ actions; Normally only some will be used -+ for qidMask. Driver will return error if -+ resource is full at initialization time. */ -+ -+#if (DPAA_VERSION >= 11) -+ bool overrideStorageProfile; /**< TRUE if KeyGen override previously decided storage profile */ -+ t_FmPcdKgStorageProfile storageProfile; /**< Used when overrideStorageProfile TRUE */ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ e_FmPcdEngine nextEngine; /**< may be BMI, PLCR or CC */ -+ union { /**< depends on nextEngine */ -+ e_FmPcdDoneAction doneAction; /**< Used when next engine is BMI (done) */ -+ t_FmPcdKgPlcrProfile plcrProfile; /**< Used when next engine is PLCR */ -+ t_FmPcdKgCc cc; /**< Used when next engine is CC */ -+ } kgNextEngineParams; -+ t_FmPcdKgSchemeCounter schemeCounter; /**< A structure of parameters for updating -+ the scheme counter */ -+} t_FmPcdKgSchemeParams; -+ -+/**************************************************************************//** -+ @Collection Definitions for CC statistics -+*//***************************************************************************/ -+#if (DPAA_VERSION >= 11) -+#define FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */ -+#define FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */ -+#endif /* (DPAA_VERSION >= 11) */ -+#define FM_PCD_CC_STATS_COUNTER_SIZE 4 /* Size in bytes of a frame length range counter */ -+/* @} */ -+ -+/**************************************************************************//** -+ @Description Parameters for defining CC as the next engine after a CC node. -+*//***************************************************************************/ -+typedef struct t_FmPcdCcNextCcParams { -+ t_Handle h_CcNode; /**< A handle of the next CC node */ -+} t_FmPcdCcNextCcParams; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Parameters for defining Frame replicator as the next engine after a CC node. -+*//***************************************************************************/ -+typedef struct t_FmPcdCcNextFrParams { -+ t_Handle h_FrmReplic; /**< A handle of the next frame replicator group */ -+} t_FmPcdCcNextFrParams; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Description Parameters for defining Policer as the next engine after a CC node. -+*//***************************************************************************/ -+typedef struct t_FmPcdCcNextPlcrParams { -+ bool overrideParams; /**< TRUE if CC override previously decided parameters*/ -+ bool sharedProfile; /**< Relevant only if overrideParams=TRUE: -+ TRUE if this profile is shared between ports */ -+ uint16_t newRelativeProfileId; /**< Relevant only if overrideParams=TRUE: -+ (otherwise profile id is taken from KeyGen); -+ This parameter should indicate the policer -+ profile offset within the port's -+ policer profiles or from SHARED window.*/ -+ uint32_t newFqid; /**< Relevant only if overrideParams=TRUE: -+ FQID for enqueuing the frame; -+ In earlier chips if policer next engine is KEYGEN, -+ this parameter can be 0, because the KEYGEN -+ always decides the enqueue FQID.*/ -+#if (DPAA_VERSION >= 11) -+ uint8_t newRelativeStorageProfileId; -+ /**< Indicates the relative storage profile offset within -+ the port's storage profiles window; -+ Relevant only if the port was configured with VSP. */ -+#endif /* (DPAA_VERSION >= 11) */ -+} t_FmPcdCcNextPlcrParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining enqueue as the next action after a CC node. -+*//***************************************************************************/ -+typedef struct t_FmPcdCcNextEnqueueParams { -+ e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */ -+ bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid, -+ relevant if action = e_FM_PCD_ENQ_FRAME */ -+ uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame -+ (otherwise FQID is taken from KeyGen), -+ relevant if action = e_FM_PCD_ENQ_FRAME */ -+#if (DPAA_VERSION >= 11) -+ uint8_t newRelativeStorageProfileId; -+ /**< Valid if overrideFqid=TRUE, Indicates the relative virtual -+ storage profile offset within the port's storage profiles -+ window; Relevant only if the port was configured with VSP. */ -+#endif /* (DPAA_VERSION >= 11) */ -+} t_FmPcdCcNextEnqueueParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining KeyGen as the next engine after a CC node. -+*//***************************************************************************/ -+typedef struct t_FmPcdCcNextKgParams { -+ bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid, -+ Note - this parameters irrelevant for earlier chips */ -+ uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame -+ (otherwise FQID is taken from KeyGen), -+ Note - this parameters irrelevant for earlier chips */ -+#if (DPAA_VERSION >= 11) -+ uint8_t newRelativeStorageProfileId; -+ /**< Valid if overrideFqid=TRUE, Indicates the relative virtual -+ storage profile offset within the port's storage profiles -+ window; Relevant only if the port was configured with VSP. */ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ t_Handle h_DirectScheme; /**< Direct scheme handle to go to. */ -+} t_FmPcdCcNextKgParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining the next engine after a CC node. -+*//***************************************************************************/ -+typedef struct t_FmPcdCcNextEngineParams { -+ e_FmPcdEngine nextEngine; /**< User has to initialize parameters -+ according to nextEngine definition */ -+ union { -+ t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */ -+ t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */ -+ t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */ -+ t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */ -+#if (DPAA_VERSION >= 11) -+ t_FmPcdCcNextFrParams frParams; /**< Parameters in case next engine is FR */ -+#endif /* (DPAA_VERSION >= 11) */ -+ } params; /**< union used for all the next-engine parameters options */ -+ -+ t_Handle h_Manip; /**< Handle to Manipulation object. -+ Relevant if next engine is of type result -+ (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */ -+ -+ bool statisticsEn; /**< If TRUE, statistics counters are incremented -+ for each frame passing through this -+ Coarse Classification entry. */ -+} t_FmPcdCcNextEngineParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a single CC key -+*//***************************************************************************/ -+typedef struct t_FmPcdCcKeyParams { -+ uint8_t *p_Key; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH; -+ pointer to the key of the size defined in keySize */ -+ uint8_t *p_Mask; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH; -+ pointer to the Mask per key of the size defined -+ in keySize. p_Key and p_Mask (if defined) has to be -+ of the same size defined in the keySize; -+ NOTE that if this value is equal for all entries whithin -+ this table, the driver will automatically use global-mask -+ (i.e. one common mask for all entries) instead of private -+ one; that is done in order to spare some memory and for -+ better performance. */ -+ t_FmPcdCcNextEngineParams ccNextEngineParams; -+ /**< parameters for the next for the defined Key in -+ the p_Key */ -+} t_FmPcdCcKeyParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining CC keys parameters -+ The driver supports two methods for CC node allocation: dynamic and static. -+ Static mode was created in order to prevent runtime alloc/free -+ of FMan memory (MURAM), which may cause fragmentation; in this mode, -+ the driver automatically allocates the memory according to -+ 'maxNumOfKeys' parameter. The driver calculates the maximal memory -+ size that may be used for this CC-Node taking into consideration -+ 'maskSupport' and 'statisticsMode' parameters. -+ When 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction -+ parameters of this node, 'maxNumOfKeys' must be equal to 'numOfKeys'. -+ In dynamic mode, 'maxNumOfKeys' must be zero. At initialization, -+ all required structures are allocated according to 'numOfKeys' -+ parameter. During runtime modification, these structures are -+ re-allocated according to the updated number of keys. -+ -+ Please note that 'action' and 'icIndxMask' mentioned in the -+ specific parameter explanations are passed in the extraction -+ parameters of the node (fields of extractCcParams.extractNonHdr). -+*//***************************************************************************/ -+typedef struct t_KeysParams { -+ uint16_t maxNumOfKeys; /**< Maximum number of keys that will (ever) be used in this CC-Node; -+ A value of zero may be used for dynamic memory allocation. */ -+ bool maskSupport; /**< This parameter is relevant only if a node is initialized with -+ 'action' = e_FM_PCD_ACTION_EXACT_MATCH and maxNumOfKeys > 0; -+ Should be TRUE to reserve table memory for key masks, even if -+ initial keys do not contain masks, or if the node was initialized -+ as 'empty' (without keys); this will allow user to add keys with -+ masks at runtime. -+ NOTE that if user want to use only global-masks (i.e. one common mask -+ for all the entries within this table, this parameter should set to 'FALSE'. */ -+ e_FmPcdCcStatsMode statisticsMode; /**< Determines the supported statistics mode for all node's keys. -+ To enable statistics gathering, statistics should be enabled per -+ every key, using 'statisticsEn' in next engine parameters structure -+ of that key; -+ If 'maxNumOfKeys' is set, all required structures will be -+ preallocated for all keys. */ -+#if (DPAA_VERSION >= 11) -+ uint16_t frameLengthRanges[FM_PCD_CC_STATS_MAX_NUM_OF_FLR]; -+ /**< Relevant only for 'RMON' statistics mode -+ (this feature is supported only on B4860 device); -+ Holds a list of programmable thresholds - for each received frame, -+ its length in bytes is examined against these range thresholds and -+ the appropriate counter is incremented by 1 - for example, to belong -+ to range i, the following should hold: -+ range i-1 threshold < frame length <= range i threshold -+ Each range threshold must be larger then its preceding range -+ threshold, and last range threshold must be 0xFFFF. */ -+#endif /* (DPAA_VERSION >= 11) */ -+ uint16_t numOfKeys; /**< Number of initial keys; -+ Note that in case of 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP, -+ this field should be power-of-2 of the number of bits that are -+ set in 'icIndxMask'. */ -+ uint8_t keySize; /**< Size of key - for extraction of type FULL_FIELD, 'keySize' has -+ to be the standard size of the selected key; For other extraction -+ types, 'keySize' has to be as size of extraction; When 'action' = -+ e_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */ -+ t_FmPcdCcKeyParams keyParams[FM_PCD_MAX_NUM_OF_KEYS]; -+ /**< An array with 'numOfKeys' entries, each entry specifies the -+ corresponding key parameters; -+ When 'action' = e_FM_PCD_ACTION_EXACT_MATCH, this value must not -+ exceed 255 (FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved -+ for the 'miss' entry. */ -+ t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; -+ /**< Parameters for defining the next engine when a key is not matched; -+ Not relevant if action = e_FM_PCD_ACTION_INDEXED_LOOKUP. */ -+} t_KeysParams; -+ -+ -+/**************************************************************************//** -+ @Description Parameters for defining a CC node -+*//***************************************************************************/ -+typedef struct t_FmPcdCcNodeParams { -+ t_FmPcdExtractEntry extractCcParams; /**< Extraction parameters */ -+ t_KeysParams keysParams; /**< Keys definition matching the selected extraction */ -+} t_FmPcdCcNodeParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a hash table -+*//***************************************************************************/ -+typedef struct t_FmPcdHashTableParams { -+ uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */ -+ e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the -+ requested statistics mode will be allocated according to maxNumOfKeys. */ -+ uint8_t kgHashShift; /**< KG-Hash-shift as it was configured in the KG-scheme -+ that leads to this hash-table. */ -+ uint16_t hashResMask; /**< Mask that will be used on the hash-result; -+ The number-of-sets for this hash will be calculated -+ as (2^(number of bits set in 'hashResMask')); -+ The 4 lower bits must be cleared. */ -+ uint8_t hashShift; /**< Byte offset from the beginning of the KeyGen hash result to the -+ 2-bytes to be used as hash index. */ -+ uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */ -+ -+ t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */ -+ -+} t_FmPcdHashTableParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a CC tree group. -+ -+ This structure defines a CC group in terms of NetEnv units -+ and the action to be taken in each case. The unitIds list must -+ be given in order from low to high indices. -+ -+ t_FmPcdCcNextEngineParams is a list of 2^numOfDistinctionUnits -+ structures where each defines the next action to be taken for -+ each units combination. for example: -+ numOfDistinctionUnits = 2 -+ unitIds = {1,3} -+ p_NextEnginePerEntriesInGrp[0] = t_FmPcdCcNextEngineParams for the case that -+ unit 1 - not found; unit 3 - not found; -+ p_NextEnginePerEntriesInGrp[1] = t_FmPcdCcNextEngineParams for the case that -+ unit 1 - not found; unit 3 - found; -+ p_NextEnginePerEntriesInGrp[2] = t_FmPcdCcNextEngineParams for the case that -+ unit 1 - found; unit 3 - not found; -+ p_NextEnginePerEntriesInGrp[3] = t_FmPcdCcNextEngineParams for the case that -+ unit 1 - found; unit 3 - found; -+*//***************************************************************************/ -+typedef struct t_FmPcdCcGrpParams { -+ uint8_t numOfDistinctionUnits; /**< Up to 4 */ -+ uint8_t unitIds[FM_PCD_MAX_NUM_OF_CC_UNITS]; -+ /**< Indices of the units as defined in -+ FM_PCD_NetEnvCharacteristicsSet() */ -+ t_FmPcdCcNextEngineParams nextEnginePerEntriesInGrp[FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP]; -+ /**< Maximum entries per group is 16 */ -+} t_FmPcdCcGrpParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining CC tree groups -+*//***************************************************************************/ -+typedef struct t_FmPcdCcTreeParams { -+ t_Handle h_NetEnv; /**< A handle to the Network environment as returned -+ by FM_PCD_NetEnvCharacteristicsSet() */ -+ uint8_t numOfGrps; /**< Number of CC groups within the CC tree */ -+ t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS]; -+ /**< Parameters for each group. */ -+} t_FmPcdCcTreeParams; -+ -+ -+/**************************************************************************//** -+ @Description CC key statistics structure -+*//***************************************************************************/ -+typedef struct t_FmPcdCcKeyStatistics { -+ uint32_t byteCount; /**< This counter reflects byte count of frames that -+ were matched by this key. */ -+ uint32_t frameCount; /**< This counter reflects count of frames that -+ were matched by this key. */ -+#if (DPAA_VERSION >= 11) -+ uint32_t frameLengthRangeCount[FM_PCD_CC_STATS_MAX_NUM_OF_FLR]; -+ /**< These counters reflect how many frames matched -+ this key in 'RMON' statistics mode: -+ Each counter holds the number of frames of a -+ specific frames length range, according to the -+ ranges provided at initialization. */ -+#endif /* (DPAA_VERSION >= 11) */ -+} t_FmPcdCcKeyStatistics; -+ -+/**************************************************************************//** -+ @Description Parameters for defining policer byte rate -+*//***************************************************************************/ -+typedef struct t_FmPcdPlcrByteRateModeParams { -+ e_FmPcdPlcrFrameLengthSelect frameLengthSelection; /**< Frame length selection */ -+ e_FmPcdPlcrRollBackFrameSelect rollBackFrameSelection; /**< relevant option only e_FM_PCD_PLCR_L2_FRM_LEN, -+ e_FM_PCD_PLCR_FULL_FRM_LEN */ -+} t_FmPcdPlcrByteRateModeParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining the policer profile (based on -+ RFC-2698 or RFC-4115 attributes). -+*//***************************************************************************/ -+typedef struct t_FmPcdPlcrNonPassthroughAlgParams { -+ e_FmPcdPlcrRateMode rateMode; /**< Byte mode or Packet mode */ -+ t_FmPcdPlcrByteRateModeParams byteModeParams; /**< Valid for Byte NULL for Packet */ -+ uint32_t committedInfoRate; /**< KBits/Second or Packets/Second */ -+ uint32_t committedBurstSize; /**< Bytes/Packets */ -+ uint32_t peakOrExcessInfoRate; /**< KBits/Second or Packets/Second */ -+ uint32_t peakOrExcessBurstSize; /**< Bytes/Packets */ -+} t_FmPcdPlcrNonPassthroughAlgParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining the next engine after policer -+*//***************************************************************************/ -+typedef union u_FmPcdPlcrNextEngineParams { -+ e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */ -+ t_Handle h_Profile; /**< Policer profile handle - used when next engine -+ is Policer, must be a SHARED profile */ -+ t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is KeyGen */ -+} u_FmPcdPlcrNextEngineParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining the policer profile entry -+*//***************************************************************************/ -+typedef struct t_FmPcdPlcrProfileParams { -+ bool modify; /**< TRUE to change an existing profile */ -+ union { -+ struct { -+ e_FmPcdProfileTypeSelection profileType; /**< Type of policer profile */ -+ t_Handle h_FmPort; /**< Relevant for per-port profiles only */ -+ uint16_t relativeProfileId; /**< Profile id - relative to shared group or to port */ -+ } newParams; /**< use it when modify = FALSE */ -+ t_Handle h_Profile; /**< A handle to a profile - use it when modify=TRUE */ -+ } id; -+ e_FmPcdPlcrAlgorithmSelection algSelection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */ -+ e_FmPcdPlcrColorMode colorMode; /**< COLOR_BLIND, COLOR_AWARE */ -+ -+ union { -+ e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode; the policer will re-color -+ any incoming packet with the default value. */ -+ e_FmPcdPlcrColor override; /**< For Color-Aware modes; the profile response to a -+ pre-color value of 2'b11. */ -+ } color; -+ -+ t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 parameters */ -+ -+ e_FmPcdEngine nextEngineOnGreen; /**< Next engine for green-colored frames */ -+ u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Next engine parameters for green-colored frames */ -+ -+ e_FmPcdEngine nextEngineOnYellow; /**< Next engine for yellow-colored frames */ -+ u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Next engine parameters for yellow-colored frames */ -+ -+ e_FmPcdEngine nextEngineOnRed; /**< Next engine for red-colored frames */ -+ u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Next engine parameters for red-colored frames */ -+ -+ bool trapProfileOnFlowA; /**< Obsolete - do not use */ -+ bool trapProfileOnFlowB; /**< Obsolete - do not use */ -+ bool trapProfileOnFlowC; /**< Obsolete - do not use */ -+} t_FmPcdPlcrProfileParams; -+ -+/**************************************************************************//** -+ @Description Parameters for selecting a location for requested manipulation -+*//***************************************************************************/ -+typedef struct t_FmManipHdrInfo { -+ e_NetHeaderType hdr; /**< Header selection */ -+ e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */ -+ bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/ -+ t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */ -+} t_FmManipHdrInfo; -+ -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+/**************************************************************************//** -+ @Description Parameters for defining an insertion manipulation -+ of type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrInsrtByTemplateParams { -+ uint8_t size; /**< Size of insert template to the start of the frame. */ -+ uint8_t hdrTemplate[FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE]; -+ /**< Array of the insertion template. */ -+ -+ bool modifyOuterIp; /**< TRUE if user want to modify some fields in outer IP. */ -+ struct { -+ uint16_t ipOuterOffset; /**< Offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/ -+ uint16_t dscpEcn; /**< value of dscpEcn in IP outer, relevant if modifyOuterIp = TRUE. -+ in IPV4 dscpEcn only byte - it has to be adjusted to the right*/ -+ bool udpPresent; /**< TRUE if UDP is present in the insert template, relevant if modifyOuterIp = TRUE.*/ -+ uint8_t udpOffset; /**< Offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/ -+ uint8_t ipIdentGenId; /**< Used by FMan-CTRL to calculate IP-identification field,relevant if modifyOuterIp = TRUE.*/ -+ bool recalculateLength; /**< TRUE if recalculate length has to be performed due to the engines in the path which can change the frame later, relevant if modifyOuterIp = TRUE.*/ -+ struct { -+ uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP Total Length field.*/ -+ uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length*/ -+ uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length.*/ -+ } recalculateLengthParams; /**< Recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */ -+ } modifyOuterIpParams; /**< Outer IP modification parameters - ignored if modifyOuterIp is FALSE */ -+ -+ bool modifyOuterVlan; /**< TRUE if user wants to modify VPri field in the outer VLAN header*/ -+ struct { -+ uint8_t vpri; /**< Value of VPri, relevant if modifyOuterVlan = TRUE -+ VPri only 3 bits, it has to be adjusted to the right*/ -+ } modifyOuterVlanParams; -+} t_FmPcdManipHdrInsrtByTemplateParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining CAPWAP fragmentation -+*//***************************************************************************/ -+typedef struct t_CapwapFragmentationParams { -+ uint16_t sizeForFragmentation; /**< if length of the frame is greater than this value, CAPWAP fragmentation will be executed.*/ -+ bool headerOptionsCompr; /**< TRUE - first fragment include the CAPWAP header options field, -+ and all other fragments exclude the CAPWAP options field, -+ FALSE - all fragments include CAPWAP header options field. */ -+} t_CapwapFragmentationParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining CAPWAP reassembly -+*//***************************************************************************/ -+typedef struct t_CapwapReassemblyParams { -+ uint16_t maxNumFramesInProcess; /**< Number of frames which can be reassembled concurrently; must be power of 2. -+ In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH, -+ maxNumFramesInProcess has to be in the range of 4 - 512, -+ In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH, -+ maxNumFramesInProcess has to be in the range of 8 - 2048 */ -+ bool haltOnDuplicationFrag; /**< If TRUE, reassembly process will be halted due to duplicated fragment, -+ and all processed fragments will be enqueued with error indication; -+ If FALSE, only duplicated fragments will be enqueued with error indication. */ -+ -+ e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by the reassembly process */ -+ uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process */ -+ uint32_t timeoutRoutineRequestTime; -+ /**< Represents the time interval in microseconds between consecutive -+ timeout routine requests It has to be power of 2. */ -+ uint32_t timeoutThresholdForReassmProcess; -+ /**< Time interval (microseconds) for marking frames in process as too old; -+ Frames in process are those for which at least one fragment was received -+ but not all fragments. */ -+ -+ e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry (needed for the reassembly process) */ -+} t_CapwapReassemblyParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining fragmentation/reassembly manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipFragOrReasmParams { -+ bool frag; /**< TRUE if using the structure for fragmentation, -+ otherwise this structure is used for reassembly */ -+ uint8_t sgBpid; /**< Scatter/Gather buffer pool id; -+ Same LIODN number is used for these buffers as for -+ the received frames buffers, so buffers of this pool -+ need to be allocated in the same memory area as the -+ received buffers. If the received buffers arrive -+ from different sources, the Scatter/Gather BP id -+ should be mutual to all these sources. */ -+ e_NetHeaderType hdr; /**< Header selection */ -+ union { -+ t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation, -+ relevant if 'frag' = TRUE, 'hdr' = HEADER_TYPE_CAPWAP */ -+ t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly, -+ relevant if 'frag' = FALSE, 'hdr' = HEADER_TYPE_CAPWAP */ -+ } u; -+} t_FmPcdManipFragOrReasmParams; -+#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+ -+ -+/**************************************************************************//** -+ @Description Parameters for defining header removal by header type -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrRmvByHdrParams { -+ e_FmPcdManipHdrRmvByHdrType type; /**< Selection of header removal location */ -+ union { -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+ struct { -+ bool include; /**< If FALSE, remove until the specified header (not including the header); -+ If TRUE, remove also the specified header. */ -+ t_FmManipHdrInfo hdrInfo; -+ } fromStartByHdr; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */ -+#endif /* (DPAA_VERSION >= 11) || ... */ -+#if (DPAA_VERSION >= 11) -+ t_FmManipHdrInfo hdrInfo; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */ -+#endif /* (DPAA_VERSION >= 11) */ -+ e_FmPcdManipHdrRmvSpecificL2 specificL2; /**< Relevant when type = e_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2; -+ Defines which L2 headers to remove. */ -+ } u; -+} t_FmPcdManipHdrRmvByHdrParams; -+ -+/**************************************************************************//** -+ @Description Parameters for configuring IP fragmentation manipulation -+ -+ Restrictions: -+ - IP Fragmentation output fragments must not be forwarded to application directly. -+ - Maximum number of fragments per frame is 16. -+ - Fragmentation of IP fragments is not supported. -+ - IPv4 packets containing header Option fields are fragmented by copying all option -+ fields to each fragment, regardless of the copy bit value. -+ - Transmit confirmation is not supported. -+ - Fragmentation after SEC can't handle S/G frames. -+ - Fragmentation nodes must be set as the last PCD action (i.e. the -+ corresponding CC node key must have next engine set to e_FM_PCD_DONE). -+ - Only BMan buffers shall be used for frames to be fragmented. -+ - IPF does not support VSP. Therefore, on the same port where we have IPF -+ we cannot support VSP. -+ - NOTE: The following comment is relevant only for FMAN v3 devices: IPF -+ does not support VSP. Therefore, on the same port where we have IPF we -+ cannot support VSP. -+*//***************************************************************************/ -+typedef struct t_FmPcdManipFragIpParams { -+ uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value, -+ IP fragmentation will be executed.*/ -+#if (DPAA_VERSION == 10) -+ uint8_t scratchBpid; /**< Absolute buffer pool id according to BM configuration.*/ -+#endif /* (DPAA_VERSION == 10) */ -+ bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation; -+ If disabled, the Scatter/Gather buffer will be allocated from the same pool as the -+ received frame's buffer. */ -+ uint8_t sgBpid; /**< Scatter/Gather buffer pool id; -+ This parameters is relevant when 'sgBpidEn=TRUE'; -+ Same LIODN number is used for these buffers as for the received frames buffers, so buffers -+ of this pool need to be allocated in the same memory area as the received buffers. -+ If the received buffers arrive from different sources, the Scatter/Gather BP id should be -+ mutual to all these sources. */ -+ e_FmPcdManipDontFragAction dontFragAction; /**< Don't Fragment Action - If an IP packet is larger -+ than MTU and its DF bit is set, then this field will -+ determine the action to be taken.*/ -+} t_FmPcdManipFragIpParams; -+ -+/**************************************************************************//** -+ @Description Parameters for configuring IP reassembly manipulation. -+ -+ This is a common structure for both IPv4 and IPv6 reassembly -+ manipulation. For reassembly of both IPv4 and IPv6, make sure to -+ set the 'hdr' field in t_FmPcdManipReassemParams to HEADER_TYPE_IPv6. -+ -+ Restrictions: -+ - Application must define at least one scheme to catch the reassembled frames. -+ - Maximum number of fragments per frame is 16. -+ - Reassembly of IPv4 fragments containing Option fields is supported. -+ -+*//***************************************************************************/ -+typedef struct t_FmPcdManipReassemIpParams { -+ uint8_t relativeSchemeId[2]; /**< Partition relative scheme id: -+ relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation; -+ relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation; -+ NOTE: The following comment is relevant only for FMAN v2 devices: -+ Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than -+ the user schemes id to ensure that the reassembly schemes will be first match; -+ Rest schemes, if defined, should have higher relative scheme ID. */ -+#if (DPAA_VERSION >= 11) -+ uint32_t nonConsistentSpFqid; /**< In case that other fragments of the frame corresponds to different storage -+ profile than the opening fragment (Non-Consistent-SP state) -+ then one of two possible scenarios occurs: -+ if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to -+ this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/ -+#else -+ uint8_t sgBpid; /**< Buffer pool id for the S/G frame created by the reassembly process */ -+#endif /* (DPAA_VERSION >= 11) */ -+ uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */ -+ uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */ -+ uint16_t minFragSize[2]; /**< Minimum fragment size: -+ minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */ -+ e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2]; -+ /**< Number of frames per hash entry needed for reassembly process: -+ numOfFramesPerHashEntry[0] - for ipv4 (max value is e_FM_PCD_MANIP_EIGHT_WAYS_HASH); -+ numOfFramesPerHashEntry[1] - for ipv6 (max value is e_FM_PCD_MANIP_SIX_WAYS_HASH). */ -+ uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time; -+ Must be power of 2; -+ In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH, -+ maxNumFramesInProcess has to be in the range of 4 - 512; -+ In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH, -+ maxNumFramesInProcess has to be in the range of 8 - 2048. */ -+ e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */ -+ uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process; -+ Recommended value for this field is 0; in this way timed-out frames will be discarded */ -+ uint32_t timeoutThresholdForReassmProcess; -+ /**< Represents the time interval in microseconds which defines -+ if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/ -+} t_FmPcdManipReassemIpParams; -+ -+/**************************************************************************//** -+ @Description structure for defining IPSEC manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipSpecialOffloadIPSecParams { -+ bool decryption; /**< TRUE if being used in decryption direction; -+ FALSE if being used in encryption direction. */ -+ bool ecnCopy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner -+ (direction depends on the 'decryption' field). */ -+ bool dscpCopy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner -+ (direction depends on the 'decryption' field). */ -+ bool variableIpHdrLen; /**< TRUE for supporting variable IP header length in decryption. */ -+ bool variableIpVersion; /**< TRUE for supporting both IP version on the same SA in encryption */ -+ uint8_t outerIPHdrLen; /**< if 'variableIpVersion == TRUE' then this field must be set to non-zero value; -+ It is specifies the length of the outer IP header that was configured in the -+ corresponding SA. */ -+ uint16_t arwSize; /**< if <> '0' then will perform ARW check for this SA; -+ The value must be a multiplication of 16 */ -+ uintptr_t arwAddr; /**< if arwSize <> '0' then this field must be set to non-zero value; -+ MUST be allocated from FMAN's MURAM that the post-sec op-port belongs to; -+ Must be 4B aligned. Required MURAM size is 'NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */ -+} t_FmPcdManipSpecialOffloadIPSecParams; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Parameters for configuring CAPWAP fragmentation manipulation -+ -+ Restrictions: -+ - Maximum number of fragments per frame is 16. -+ - Transmit confirmation is not supported. -+ - Fragmentation nodes must be set as the last PCD action (i.e. the -+ corresponding CC node key must have next engine set to e_FM_PCD_DONE). -+ - Only BMan buffers shall be used for frames to be fragmented. -+ - NOTE: The following comment is relevant only for FMAN v3 devices: IPF -+ does not support VSP. Therefore, on the same port where we have IPF we -+ cannot support VSP. -+*//***************************************************************************/ -+typedef struct t_FmPcdManipFragCapwapParams { -+ uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value, -+ CAPWAP fragmentation will be executed.*/ -+ bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation; -+ If disabled, the Scatter/Gather buffer will be allocated from the same pool as the -+ received frame's buffer. */ -+ uint8_t sgBpid; /**< Scatter/Gather buffer pool id; -+ This parameters is relevant when 'sgBpidEn=TRUE'; -+ Same LIODN number is used for these buffers as for the received frames buffers, so buffers -+ of this pool need to be allocated in the same memory area as the received buffers. -+ If the received buffers arrive from different sources, the Scatter/Gather BP id should be -+ mutual to all these sources. */ -+ bool compressModeEn; /**< CAPWAP Header Options Compress Enable mode; -+ When this mode is enabled then only the first fragment include the CAPWAP header options -+ field (if user provides it in the input frame) and all other fragments exclude the CAPWAP -+ options field (CAPWAP header is updated accordingly).*/ -+} t_FmPcdManipFragCapwapParams; -+ -+/**************************************************************************//** -+ @Description Parameters for configuring CAPWAP reassembly manipulation. -+ -+ Restrictions: -+ - Application must define one scheme to catch the reassembled frames. -+ - Maximum number of fragments per frame is 16. -+ -+*//***************************************************************************/ -+typedef struct t_FmPcdManipReassemCapwapParams { -+ uint8_t relativeSchemeId; /**< Partition relative scheme id; -+ NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match; -+ Rest schemes, if defined, should have higher relative scheme ID. */ -+ uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */ -+ uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */ -+ uint16_t maxReassembledFrameLength;/**< The maximum CAPWAP reassembled frame length in bytes; -+ If maxReassembledFrameLength == 0, any successful reassembled frame length is -+ considered as a valid length; -+ if maxReassembledFrameLength > 0, a successful reassembled frame which its length -+ exceeds this value is considered as an error frame (FD status[CRE] bit is set). */ -+ e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry; -+ /**< Number of frames per hash entry needed for reassembly process */ -+ uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by reassembly in the same time; -+ Must be power of 2; -+ In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH, -+ maxNumFramesInProcess has to be in the range of 4 - 512; -+ In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH, -+ maxNumFramesInProcess has to be in the range of 8 - 2048. */ -+ e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */ -+ uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process; -+ Recommended value for this field is 0; in this way timed-out frames will be discarded */ -+ uint32_t timeoutThresholdForReassmProcess; -+ /**< Represents the time interval in microseconds which defines -+ if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/ -+} t_FmPcdManipReassemCapwapParams; -+ -+/**************************************************************************//** -+ @Description structure for defining CAPWAP manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipSpecialOffloadCapwapParams { -+ bool dtls; /**< TRUE if continue to SEC DTLS encryption */ -+ e_FmPcdManipHdrQosSrc qosSrc; /**< TODO */ -+} t_FmPcdManipSpecialOffloadCapwapParams; -+ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ -+/**************************************************************************//** -+ @Description Parameters for defining special offload manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipSpecialOffloadParams { -+ e_FmPcdManipSpecialOffloadType type; /**< Type of special offload manipulation */ -+ union -+ { -+ t_FmPcdManipSpecialOffloadIPSecParams ipsec; /**< Parameters for IPSec; Relevant when -+ type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */ -+#if (DPAA_VERSION >= 11) -+ t_FmPcdManipSpecialOffloadCapwapParams capwap; /**< Parameters for CAPWAP; Relevant when -+ type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */ -+#endif /* (DPAA_VERSION >= 11) */ -+ } u; -+} t_FmPcdManipSpecialOffloadParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining insertion manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrInsrt { -+ uint8_t size; /**< size of inserted section */ -+ uint8_t *p_Data; /**< data to be inserted */ -+} t_FmPcdManipHdrInsrt; -+ -+ -+/**************************************************************************//** -+ @Description Parameters for defining generic removal manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrRmvGenericParams { -+ uint8_t offset; /**< Offset from beginning of header to the start -+ location of the removal */ -+ uint8_t size; /**< Size of removed section */ -+} t_FmPcdManipHdrRmvGenericParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining generic insertion manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrInsrtGenericParams { -+ uint8_t offset; /**< Offset from beginning of header to the start -+ location of the insertion */ -+ uint8_t size; /**< Size of inserted section */ -+ bool replace; /**< TRUE to override (replace) existing data at -+ 'offset', FALSE to insert */ -+ uint8_t *p_Data; /**< Pointer to data to be inserted */ -+} t_FmPcdManipHdrInsrtGenericParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrFieldUpdateVlanDscpToVpri { -+ uint8_t dscpToVpriTable[FM_PCD_MANIP_DSCP_TO_VLAN_TRANS]; -+ /**< A table of VPri values for each DSCP value; -+ The index is the DSCP value (0-0x3F) and the -+ value is the corresponding VPRI (0-15). */ -+ uint8_t vpriDefVal; /**< 0-7, Relevant only if if updateType = -+ e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN, -+ this field is the Q Tag default value if the -+ IP header is not found. */ -+} t_FmPcdManipHdrFieldUpdateVlanDscpToVpri; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation VLAN fields updates -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrFieldUpdateVlan { -+ e_FmPcdManipHdrFieldUpdateVlan updateType; /**< Selects VLAN update type */ -+ union { -+ uint8_t vpri; /**< 0-7, Relevant only if If updateType = -+ e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this -+ is the new VLAN pri. */ -+ t_FmPcdManipHdrFieldUpdateVlanDscpToVpri dscpToVpri; /**< Parameters structure, Relevant only if updateType -+ = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */ -+ } u; -+} t_FmPcdManipHdrFieldUpdateVlan; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation IPV4 fields updates -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrFieldUpdateIpv4 { -+ ipv4HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */ -+ uint8_t tos; /**< 8 bit New TOS; Relevant if validUpdates contains -+ HDR_MANIP_IPV4_TOS */ -+ uint16_t id; /**< 16 bit New IP ID; Relevant only if validUpdates -+ contains HDR_MANIP_IPV4_ID */ -+ uint32_t src; /**< 32 bit New IP SRC; Relevant only if validUpdates -+ contains HDR_MANIP_IPV4_SRC */ -+ uint32_t dst; /**< 32 bit New IP DST; Relevant only if validUpdates -+ contains HDR_MANIP_IPV4_DST */ -+} t_FmPcdManipHdrFieldUpdateIpv4; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation IPV6 fields updates -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrFieldUpdateIpv6 { -+ ipv6HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */ -+ uint8_t trafficClass; /**< 8 bit New Traffic Class; Relevant if validUpdates contains -+ HDR_MANIP_IPV6_TC */ -+ uint8_t src[NET_HEADER_FIELD_IPv6_ADDR_SIZE]; -+ /**< 16 byte new IP SRC; Relevant only if validUpdates -+ contains HDR_MANIP_IPV6_SRC */ -+ uint8_t dst[NET_HEADER_FIELD_IPv6_ADDR_SIZE]; -+ /**< 16 byte new IP DST; Relevant only if validUpdates -+ contains HDR_MANIP_IPV6_DST */ -+} t_FmPcdManipHdrFieldUpdateIpv6; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation TCP/UDP fields updates -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrFieldUpdateTcpUdp { -+ tcpUdpHdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */ -+ uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if validUpdates -+ contains HDR_MANIP_TCP_UDP_SRC */ -+ uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if validUpdates -+ contains HDR_MANIP_TCP_UDP_DST */ -+} t_FmPcdManipHdrFieldUpdateTcpUdp; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation fields updates -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrFieldUpdateParams { -+ e_FmPcdManipHdrFieldUpdateType type; /**< Type of header field update manipulation */ -+ union { -+ t_FmPcdManipHdrFieldUpdateVlan vlan; /**< Parameters for VLAN update. Relevant when -+ type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */ -+ t_FmPcdManipHdrFieldUpdateIpv4 ipv4; /**< Parameters for IPv4 update. Relevant when -+ type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */ -+ t_FmPcdManipHdrFieldUpdateIpv6 ipv6; /**< Parameters for IPv6 update. Relevant when -+ type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */ -+ t_FmPcdManipHdrFieldUpdateTcpUdp tcpUdp; /**< Parameters for TCP/UDP update. Relevant when -+ type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */ -+ } u; -+} t_FmPcdManipHdrFieldUpdateParams; -+ -+ -+ -+/**************************************************************************//** -+ @Description Parameters for defining custom header manipulation for generic field replacement -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrCustomGenFieldReplace { -+ uint8_t srcOffset; /**< Location of new data - Offset from -+ Parse Result (>= 16, srcOffset+size <= 32, ) */ -+ uint8_t dstOffset; /**< Location of data to be overwritten - Offset from -+ start of frame (dstOffset + size <= 256). */ -+ uint8_t size; /**< The number of bytes (<=16) to be replaced */ -+ uint8_t mask; /**< Optional 1 byte mask. Set to select bits for -+ replacement (1 - bit will be replaced); -+ Clear to use field as is. */ -+ uint8_t maskOffset; /**< Relevant if mask != 0; -+ Mask offset within the replaces "size" */ -+} t_FmPcdManipHdrCustomGenFieldReplace; -+ -+/**************************************************************************//** -+ @Description Parameters for defining custom header manipulation for IP replacement -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrCustomIpHdrReplace { -+ e_FmPcdManipHdrCustomIpReplace replaceType; /**< Selects replace update type */ -+ bool decTtlHl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */ -+ bool updateIpv4Id; /**< Relevant when replaceType = -+ e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */ -+ uint16_t id; /**< 16 bit New IP ID; Relevant only if -+ updateIpv4Id = TRUE */ -+ uint8_t hdrSize; /**< The size of the new IP header */ -+ uint8_t hdr[FM_PCD_MANIP_MAX_HDR_SIZE]; -+ /**< The new IP header */ -+} t_FmPcdManipHdrCustomIpHdrReplace; -+ -+/**************************************************************************//** -+ @Description Parameters for defining custom header manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrCustomParams { -+ e_FmPcdManipHdrCustomType type; /**< Type of header field update manipulation */ -+ union { -+ t_FmPcdManipHdrCustomIpHdrReplace ipHdrReplace; /**< Parameters IP header replacement */ -+ t_FmPcdManipHdrCustomGenFieldReplace genFieldReplace; /**< Parameters IP header replacement */ -+ } u; -+} t_FmPcdManipHdrCustomParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining specific L2 insertion manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrInsrtSpecificL2Params { -+ e_FmPcdManipHdrInsrtSpecificL2 specificL2; /**< Selects which L2 headers to insert */ -+ bool update; /**< TRUE to update MPLS header */ -+ uint8_t size; /**< size of inserted section */ -+ uint8_t *p_Data; /**< data to be inserted */ -+} t_FmPcdManipHdrInsrtSpecificL2Params; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Parameters for defining IP insertion manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrInsrtIpParams { -+ bool calcL4Checksum; /**< Calculate L4 checksum. */ -+ e_FmPcdManipHdrQosMappingMode mappingMode; /**< TODO */ -+ uint8_t lastPidOffset; /**< the offset of the last Protocol within -+ the inserted header */ -+ uint16_t id; /**< 16 bit New IP ID */ -+ bool dontFragOverwrite; -+ /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte. -+ * This byte is configured to be overwritten when RPD is set. */ -+ uint8_t lastDstOffset; -+ /**< IPv6 only. if routing extension exist, user should set the offset of the destination address -+ * in order to calculate UDP checksum pseudo header; -+ * Otherwise set it to '0'. */ -+ t_FmPcdManipHdrInsrt insrt; /**< size and data to be inserted. */ -+} t_FmPcdManipHdrInsrtIpParams; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Description Parameters for defining header insertion manipulation by header type -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrInsrtByHdrParams { -+ e_FmPcdManipHdrInsrtByHdrType type; /**< Selects manipulation type */ -+ union { -+ -+ t_FmPcdManipHdrInsrtSpecificL2Params specificL2Params; -+ /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2: -+ Selects which L2 headers to insert */ -+#if (DPAA_VERSION >= 11) -+ t_FmPcdManipHdrInsrtIpParams ipParams; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */ -+ t_FmPcdManipHdrInsrt insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, -+ e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or -+ e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */ -+#endif /* (DPAA_VERSION >= 11) */ -+ } u; -+} t_FmPcdManipHdrInsrtByHdrParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header insertion manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrInsrtParams { -+ e_FmPcdManipHdrInsrtType type; /**< Type of insertion manipulation */ -+ union { -+ t_FmPcdManipHdrInsrtByHdrParams byHdr; /**< Parameters for defining header insertion manipulation by header type, -+ relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_HDR */ -+ t_FmPcdManipHdrInsrtGenericParams generic; /**< Parameters for defining generic header insertion manipulation, -+ relevant if 'type' = e_FM_PCD_MANIP_INSRT_GENERIC */ -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+ t_FmPcdManipHdrInsrtByTemplateParams byTemplate; /**< Parameters for defining header insertion manipulation by template, -+ relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_TEMPLATE */ -+#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+ } u; -+} t_FmPcdManipHdrInsrtParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header removal manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrRmvParams { -+ e_FmPcdManipHdrRmvType type; /**< Type of header removal manipulation */ -+ union { -+ t_FmPcdManipHdrRmvByHdrParams byHdr; /**< Parameters for defining header removal manipulation by header type, -+ relevant if type = e_FM_PCD_MANIP_RMV_BY_HDR */ -+ t_FmPcdManipHdrRmvGenericParams generic; /**< Parameters for defining generic header removal manipulation, -+ relevant if type = e_FM_PCD_MANIP_RMV_GENERIC */ -+ } u; -+} t_FmPcdManipHdrRmvParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation node -+*//***************************************************************************/ -+typedef struct t_FmPcdManipHdrParams { -+ bool rmv; /**< TRUE, to define removal manipulation */ -+ t_FmPcdManipHdrRmvParams rmvParams; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */ -+ -+ bool insrt; /**< TRUE, to define insertion manipulation */ -+ t_FmPcdManipHdrInsrtParams insrtParams; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */ -+ -+ bool fieldUpdate; /**< TRUE, to define field update manipulation */ -+ t_FmPcdManipHdrFieldUpdateParams fieldUpdateParams; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */ -+ -+ bool custom; /**< TRUE, to define custom manipulation */ -+ t_FmPcdManipHdrCustomParams customParams; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */ -+ -+ bool dontParseAfterManip;/**< TRUE to de-activate the parser after the manipulation defined in this node. -+ Restrictions: -+ 1. MUST be set if the next engine after the CC is not another CC node -+ (but rather Policer or Keygen), and this is the last (no h_NextManip) in a chain -+ of manipulation nodes. This includes single nodes (i.e. no h_NextManip and -+ also never pointed as h_NextManip of other manipulation nodes) -+ 2. MUST be set if the next engine after the CC is another CC node, and -+ this is NOT the last manipulation node (i.e. it has h_NextManip).*/ -+} t_FmPcdManipHdrParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining fragmentation manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipFragParams { -+ e_NetHeaderType hdr; /**< Header selection */ -+ union { -+#if (DPAA_VERSION >= 11) -+ t_FmPcdManipFragCapwapParams capwapFrag; /**< Parameters for defining CAPWAP fragmentation, -+ relevant if 'hdr' = HEADER_TYPE_CAPWAP */ -+#endif /* (DPAA_VERSION >= 11) */ -+ t_FmPcdManipFragIpParams ipFrag; /**< Parameters for defining IP fragmentation, -+ relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */ -+ } u; -+} t_FmPcdManipFragParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining reassembly manipulation -+*//***************************************************************************/ -+typedef struct t_FmPcdManipReassemParams { -+ e_NetHeaderType hdr; /**< Header selection */ -+ union { -+#if (DPAA_VERSION >= 11) -+ t_FmPcdManipReassemCapwapParams capwapReassem; /**< Parameters for defining CAPWAP reassembly, -+ relevant if 'hdr' = HEADER_TYPE_CAPWAP */ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ t_FmPcdManipReassemIpParams ipReassem; /**< Parameters for defining IP reassembly, -+ relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */ -+ } u; -+} t_FmPcdManipReassemParams; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a manipulation node -+*//***************************************************************************/ -+typedef struct t_FmPcdManipParams { -+ e_FmPcdManipType type; /**< Selects type of manipulation node */ -+ union{ -+ t_FmPcdManipHdrParams hdr; /**< Parameters for defining header manipulation node */ -+ t_FmPcdManipReassemParams reassem; /**< Parameters for defining reassembly manipulation node */ -+ t_FmPcdManipFragParams frag; /**< Parameters for defining fragmentation manipulation node */ -+ t_FmPcdManipSpecialOffloadParams specialOffload; /**< Parameters for defining special offload manipulation node */ -+ } u; -+ -+ t_Handle h_NextManip; /**< Supported for Header Manipulation only; -+ Handle to another (previously defined) manipulation node; -+ Allows concatenation of manipulation actions; -+ This parameter is optional and may be NULL. */ -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+ bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */ -+ t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation, -+ relevant if fragOrReasm = TRUE */ -+#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+} t_FmPcdManipParams; -+ -+/**************************************************************************//** -+ @Description Structure for retrieving IP reassembly statistics -+*//***************************************************************************/ -+typedef struct t_FmPcdManipReassemIpStats { -+ /* common counters for both IPv4 and IPv6 */ -+ uint32_t timeout; /**< Counts the number of timeout occurrences */ -+ uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate -+ a Reassembly Frame Descriptor */ -+ uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */ -+ uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */ -+ uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */ -+ uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */ -+#if (DPAA_VERSION >= 11) -+ uint32_t nonConsistentSp; /**< Counts the number of Non Consistent Storage Profile events for -+ successfully reassembled frames */ -+#endif /* (DPAA_VERSION >= 11) */ -+ struct { -+ uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */ -+ uint32_t validFragments; /**< Counts the total number of valid fragments that -+ have been processed for all frames */ -+ uint32_t processedFragments; /**< Counts the number of processed fragments -+ (valid and error fragments) for all frames */ -+ uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */ -+ uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */ -+ uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting -+ to access an IP-Reassembly Automatic Learning Hash set */ -+ uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame -+ exceeds 16 */ -+ } specificHdrStatistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */ -+} t_FmPcdManipReassemIpStats; -+ -+/**************************************************************************//** -+ @Description Structure for retrieving IP fragmentation statistics -+*//***************************************************************************/ -+typedef struct t_FmPcdManipFragIpStats { -+ uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */ -+ uint32_t fragmentedFrames; /**< Number of frames that were fragmented */ -+ uint32_t generatedFragments; /**< Number of fragments that were generated */ -+} t_FmPcdManipFragIpStats; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Structure for retrieving CAPWAP reassembly statistics -+*//***************************************************************************/ -+typedef struct t_FmPcdManipReassemCapwapStats { -+ uint32_t timeout; /**< Counts the number of timeout occurrences */ -+ uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate -+ a Reassembly Frame Descriptor */ -+ uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */ -+ uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */ -+ uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */ -+ uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */ -+ uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */ -+ uint32_t validFragments; /**< Counts the total number of valid fragments that -+ have been processed for all frames */ -+ uint32_t processedFragments; /**< Counts the number of processed fragments -+ (valid and error fragments) for all frames */ -+ uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */ -+ uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting -+ to access an Reassembly Automatic Learning Hash set */ -+ uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */ -+ uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame -+ exceeds 16 */ -+ uint32_t exceedMaxReassemblyFrameLen;/**< ounts the number of times that a successful reassembled frame -+ length exceeds MaxReassembledFrameLength value */ -+} t_FmPcdManipReassemCapwapStats; -+ -+/**************************************************************************//** -+ @Description Structure for retrieving CAPWAP fragmentation statistics -+*//***************************************************************************/ -+typedef struct t_FmPcdManipFragCapwapStats { -+ uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */ -+ uint32_t fragmentedFrames; /**< Number of frames that were fragmented */ -+ uint32_t generatedFragments; /**< Number of fragments that were generated */ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ uint8_t sgAllocationFailure; /**< Number of allocation failure of s/g buffers */ -+#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */ -+} t_FmPcdManipFragCapwapStats; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Description Structure for retrieving reassembly statistics -+*//***************************************************************************/ -+typedef struct t_FmPcdManipReassemStats { -+ union { -+ t_FmPcdManipReassemIpStats ipReassem; /**< Structure for IP reassembly statistics */ -+#if (DPAA_VERSION >= 11) -+ t_FmPcdManipReassemCapwapStats capwapReassem; /**< Structure for CAPWAP reassembly statistics */ -+#endif /* (DPAA_VERSION >= 11) */ -+ } u; -+} t_FmPcdManipReassemStats; -+ -+/**************************************************************************//** -+ @Description Structure for retrieving fragmentation statistics -+*//***************************************************************************/ -+typedef struct t_FmPcdManipFragStats { -+ union { -+ t_FmPcdManipFragIpStats ipFrag; /**< Structure for IP fragmentation statistics */ -+#if (DPAA_VERSION >= 11) -+ t_FmPcdManipFragCapwapStats capwapFrag; /**< Structure for CAPWAP fragmentation statistics */ -+#endif /* (DPAA_VERSION >= 11) */ -+ } u; -+} t_FmPcdManipFragStats; -+ -+/**************************************************************************//** -+ @Description Structure for selecting manipulation statistics -+*//***************************************************************************/ -+typedef struct t_FmPcdManipStats { -+ union { -+ t_FmPcdManipReassemStats reassem; /**< Structure for reassembly statistics */ -+ t_FmPcdManipFragStats frag; /**< Structure for fragmentation statistics */ -+ } u; -+} t_FmPcdManipStats; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Parameters for defining frame replicator group and its members -+*//***************************************************************************/ -+typedef struct t_FmPcdFrmReplicGroupParams { -+ uint8_t maxNumOfEntries; /**< Maximal number of members in the group; -+ Must be at least 2. */ -+ uint8_t numOfEntries; /**< Number of members in the group; -+ Must be at least 1. */ -+ t_FmPcdCcNextEngineParams nextEngineParams[FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES]; -+ /**< Array of members' parameters */ -+} t_FmPcdFrmReplicGroupParams; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+/**************************************************************************//** -+ @Description structure for defining statistics node -+*//***************************************************************************/ -+typedef struct t_FmPcdStatsParams { -+ e_FmPcdStatsType type; /**< type of statistics node */ -+} t_FmPcdStatsParams; -+#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+ -+/**************************************************************************//** -+ @Function FM_PCD_NetEnvCharacteristicsSet -+ -+ @Description Define a set of Network Environment Characteristics. -+ -+ When setting an environment it is important to understand its -+ application. It is not meant to describe the flows that will run -+ on the ports using this environment, but what the user means TO DO -+ with the PCD mechanisms in order to parse-classify-distribute those -+ frames. -+ By specifying a distinction unit, the user means it would use that option -+ for distinction between frames at either a KeyGen scheme or a coarse -+ classification action descriptor. Using interchangeable headers to define a -+ unit means that the user is indifferent to which of the interchangeable -+ headers is present in the frame, and wants the distinction to be based -+ on the presence of either one of them. -+ -+ Depending on context, there are limitations to the use of environments. A -+ port using the PCD functionality is bound to an environment. Some or even -+ all ports may share an environment but also an environment per port is -+ possible. When initializing a scheme, a classification plan group (see below), -+ or a coarse classification tree, one of the initialized environments must be -+ stated and related to. When a port is bound to a scheme, a classification -+ plan group, or a coarse classification tree, it MUST be bound to the same -+ environment. -+ -+ The different PCD modules, may relate (for flows definition) ONLY on -+ distinction units as defined by their environment. When initializing a -+ scheme for example, it may not choose to select IPV4 as a match for -+ recognizing flows unless it was defined in the relating environment. In -+ fact, to guide the user through the configuration of the PCD, each module's -+ characterization in terms of flows is not done using protocol names, but using -+ environment indexes. -+ -+ In terms of HW implementation, the list of distinction units sets the LCV vectors -+ and later used for match vector, classification plan vectors and coarse classification -+ indexing. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] p_NetEnvParams A structure of parameters for the initialization of -+ the network environment. -+ -+ @Return A handle to the initialized object on success; NULL code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_NetEnvCharacteristicsDelete -+ -+ @Description Deletes a set of Network Environment Characteristics. -+ -+ @Param[in] h_NetEnv A handle to the Network environment. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv); -+ -+/**************************************************************************//** -+ @Function FM_PCD_KgSchemeSet -+ -+ @Description Initializing or modifying and enabling a scheme for the KeyGen. -+ This routine should be called for adding or modifying a scheme. -+ When a scheme needs modifying, the API requires that it will be -+ rewritten. In such a case 'modify' should be TRUE. If the -+ routine is called for a valid scheme and 'modify' is FALSE, -+ it will return error. -+ -+ @Param[in] h_FmPcd If this is a new scheme - A handle to an FM PCD Module. -+ Otherwise NULL (ignored by driver). -+ @Param[in,out] p_SchemeParams A structure of parameters for defining the scheme -+ -+ @Return A handle to the initialized scheme on success; NULL code otherwise. -+ When used as "modify" (rather than for setting a new scheme), -+ p_SchemeParams->id.h_Scheme will return NULL if action fails due to scheme -+ BUSY state. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, -+ t_FmPcdKgSchemeParams *p_SchemeParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_KgSchemeDelete -+ -+ @Description Deleting an initialized scheme. -+ -+ @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet() -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme); -+ -+/**************************************************************************//** -+ @Function FM_PCD_KgSchemeGetCounter -+ -+ @Description Reads scheme packet counter. -+ -+ @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet(). -+ -+ @Return Counter's current value. -+ -+ @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet(). -+*//***************************************************************************/ -+uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme); -+ -+/**************************************************************************//** -+ @Function FM_PCD_KgSchemeSetCounter -+ -+ @Description Writes scheme packet counter. -+ -+ @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet(). -+ @Param[in] value New scheme counter value - typically '0' for -+ resetting the counter. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value); -+ -+/**************************************************************************//** -+ @Function FM_PCD_PlcrProfileSet -+ -+ @Description Sets a profile entry in the policer profile table. -+ The routine overrides any existing value. -+ -+ @Param[in] h_FmPcd A handle to an FM PCD Module. -+ @Param[in] p_Profile A structure of parameters for defining a -+ policer profile entry. -+ -+ @Return A handle to the initialized object on success; NULL code otherwise. -+ When used as "modify" (rather than for setting a new profile), -+ p_Profile->id.h_Profile will return NULL if action fails due to profile -+ BUSY state. -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd, -+ t_FmPcdPlcrProfileParams *p_Profile); -+ -+/**************************************************************************//** -+ @Function FM_PCD_PlcrProfileDelete -+ -+ @Description Delete a profile entry in the policer profile table. -+ The routine set entry to invalid. -+ -+ @Param[in] h_Profile A handle to the profile. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile); -+ -+/**************************************************************************//** -+ @Function FM_PCD_PlcrProfileGetCounter -+ -+ @Description Sets an entry in the classification plan. -+ The routine overrides any existing value. -+ -+ @Param[in] h_Profile A handle to the profile. -+ @Param[in] counter Counter selector. -+ -+ @Return specific counter value. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, -+ e_FmPcdPlcrProfileCounters counter); -+ -+/**************************************************************************//** -+ @Function FM_PCD_PlcrProfileSetCounter -+ -+ @Description Sets an entry in the classification plan. -+ The routine overrides any existing value. -+ -+ @Param[in] h_Profile A handle to the profile. -+ @Param[in] counter Counter selector. -+ @Param[in] value value to set counter with. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, -+ e_FmPcdPlcrProfileCounters counter, -+ uint32_t value); -+ -+/**************************************************************************//** -+ @Function FM_PCD_CcRootBuild -+ -+ @Description This routine must be called to define a complete coarse -+ classification tree. This is the way to define coarse -+ classification to a certain flow - the KeyGen schemes -+ may point only to trees defined in this way. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] p_Params A structure of parameters to define the tree. -+ -+ @Return A handle to the initialized object on success; NULL code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Handle FM_PCD_CcRootBuild (t_Handle h_FmPcd, -+ t_FmPcdCcTreeParams *p_Params); -+ -+/**************************************************************************//** -+ @Function FM_PCD_CcRootDelete -+ -+ @Description Deleting an built tree. -+ -+ @Param[in] h_CcTree A handle to a CC tree. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree); -+ -+/**************************************************************************//** -+ @Function FM_PCD_CcRootModifyNextEngine -+ -+ @Description Modify the Next Engine Parameters in the entry of the tree. -+ -+ @Param[in] h_CcTree A handle to the tree -+ @Param[in] grpId A Group index in the tree -+ @Param[in] index Entry index in the group defined by grpId -+ @Param[in] p_FmPcdCcNextEngineParams Pointer to new next engine parameters -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_CcBuildTree(). -+*//***************************************************************************/ -+t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree, -+ uint8_t grpId, -+ uint8_t index, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableSet -+ -+ @Description This routine should be called for each CC (coarse classification) -+ node. The whole CC tree should be built bottom up so that each -+ node points to already defined nodes. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] p_Param A structure of parameters defining the CC node -+ -+ @Return A handle to the initialized object on success; NULL code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_Param); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableDelete -+ -+ @Description Deleting an built node. -+ -+ @Param[in] h_CcNode A handle to a CC node. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableModifyMissNextEngine -+ -+ @Description Modify the Next Engine Parameters of the Miss key case of the node. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet(); -+ Not relevant in the case the node is of type 'INDEXED_LOOKUP'. -+ When configuring nextEngine = e_FM_PCD_CC, note that -+ p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different -+ from the currently changed table. -+ -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableRemoveKey -+ -+ @Description Remove the key (including next engine parameters of this key) -+ defined by the index of the relevant node. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keyIndex Key index for removing -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this -+ node and the nodes that lead to it. -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableAddKey -+ -+ @Description Add the key (including next engine parameters of this key in the -+ index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX' -+ may be used by user that don't care about the position of the -+ key in the table - in that case, the key will be automatically -+ added by the driver in the last available entry. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keyIndex Key index for adding. -+ @Param[in] keySize Key size of added key -+ @Param[in] p_KeyParams A pointer to the parameters includes -+ new key with Next Engine Parameters -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this -+ node and the nodes that lead to it. -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, -+ uint16_t keyIndex, -+ uint8_t keySize, -+ t_FmPcdCcKeyParams *p_KeyParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableModifyNextEngine -+ -+ @Description Modify the Next Engine Parameters in the relevant key entry of the node. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keyIndex Key index for Next Engine modifications -+ @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet(). -+ When configuring nextEngine = e_FM_PCD_CC, note that -+ p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different -+ from the currently changed table. -+ -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableModifyNextEngine(t_Handle h_CcNode, -+ uint16_t keyIndex, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableModifyKeyAndNextEngine -+ -+ @Description Modify the key and Next Engine Parameters of this key in the -+ index defined by the keyIndex. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keyIndex Key index for adding -+ @Param[in] keySize Key size of added key -+ @Param[in] p_KeyParams A pointer to the parameters includes -+ modified key and modified Next Engine Parameters -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this -+ node and the nodes that lead to it. -+ When configuring nextEngine = e_FM_PCD_CC, note that -+ p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different -+ from the currently changed table. -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode, -+ uint16_t keyIndex, -+ uint8_t keySize, -+ t_FmPcdCcKeyParams *p_KeyParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableModifyKey -+ -+ @Description Modify the key in the index defined by the keyIndex. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keyIndex Key index for adding -+ @Param[in] keySize Key size of added key -+ @Param[in] p_Key A pointer to the new key -+ @Param[in] p_Mask A pointer to the new mask if relevant, -+ otherwise pointer to NULL -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this -+ node and the nodes that lead to it. -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, -+ uint16_t keyIndex, -+ uint8_t keySize, -+ uint8_t *p_Key, -+ uint8_t *p_Mask); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableFindNRemoveKey -+ -+ @Description Remove the key (including next engine parameters of this key) -+ defined by the key and mask. Note that this routine will search -+ the node to locate the index of the required key (& mask) to remove. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keySize Key size of the one to remove. -+ @Param[in] p_Key A pointer to the requested key to remove. -+ @Param[in] p_Mask A pointer to the mask if relevant, -+ otherwise pointer to NULL -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this -+ node and the nodes that lead to it. -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, -+ uint8_t keySize, -+ uint8_t *p_Key, -+ uint8_t *p_Mask); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableFindNModifyNextEngine -+ -+ @Description Modify the Next Engine Parameters in the relevant key entry of -+ the node. Note that this routine will search the node to locate -+ the index of the required key (& mask) to modify. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keySize Key size of the one to modify. -+ @Param[in] p_Key A pointer to the requested key to modify. -+ @Param[in] p_Mask A pointer to the mask if relevant, -+ otherwise pointer to NULL -+ @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet(). -+ When configuring nextEngine = e_FM_PCD_CC, note that -+ p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different -+ from the currently changed table. -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableFindNModifyNextEngine(t_Handle h_CcNode, -+ uint8_t keySize, -+ uint8_t *p_Key, -+ uint8_t *p_Mask, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableFindNModifyKeyAndNextEngine -+ -+ @Description Modify the key and Next Engine Parameters of this key in the -+ index defined by the keyIndex. Note that this routine will search -+ the node to locate the index of the required key (& mask) to modify. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keySize Key size of the one to modify. -+ @Param[in] p_Key A pointer to the requested key to modify. -+ @Param[in] p_Mask A pointer to the mask if relevant, -+ otherwise pointer to NULL -+ @Param[in] p_KeyParams A pointer to the parameters includes -+ modified key and modified Next Engine Parameters -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this -+ node and the nodes that lead to it. -+ When configuring nextEngine = e_FM_PCD_CC, note that -+ p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different -+ from the currently changed table. -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(t_Handle h_CcNode, -+ uint8_t keySize, -+ uint8_t *p_Key, -+ uint8_t *p_Mask, -+ t_FmPcdCcKeyParams *p_KeyParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableFindNModifyKey -+ -+ @Description Modify the key in the index defined by the keyIndex. Note that -+ this routine will search the node to locate the index of the -+ required key (& mask) to modify. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keySize Key size of the one to modify. -+ @Param[in] p_Key A pointer to the requested key to modify. -+ @Param[in] p_Mask A pointer to the mask if relevant, -+ otherwise pointer to NULL -+ @Param[in] p_NewKey A pointer to the new key -+ @Param[in] p_NewMask A pointer to the new mask if relevant, -+ otherwise pointer to NULL -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this -+ node and the nodes that lead to it. -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, -+ uint8_t keySize, -+ uint8_t *p_Key, -+ uint8_t *p_Mask, -+ uint8_t *p_NewKey, -+ uint8_t *p_NewMask); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableGetKeyCounter -+ -+ @Description This routine may be used to get a counter of specific key in a CC -+ Node; This counter reflects how many frames passed that were matched -+ this key. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keyIndex Key index for adding -+ -+ @Return The specific key counter. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet(). -+*//***************************************************************************/ -+uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableGetKeyStatistics -+ -+ @Description This routine may be used to get statistics counters of specific key -+ in a CC Node. -+ -+ If 'e_FM_PCD_CC_STATS_MODE_FRAME' and -+ 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, -+ these counters reflect how many frames passed that were matched -+ this key; The total frames count will be returned in the counter -+ of the first range (as only one frame length range was defined). -+ If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total -+ frame count will be separated to frame length counters, based on -+ provided frame length ranges. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keyIndex Key index for adding -+ @Param[out] p_KeyStatistics Key statistics counters -+ -+ @Return The specific key statistics. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode, -+ uint16_t keyIndex, -+ t_FmPcdCcKeyStatistics *p_KeyStatistics); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableGetMissStatistics -+ -+ @Description This routine may be used to get statistics counters of miss entry -+ in a CC Node. -+ -+ If 'e_FM_PCD_CC_STATS_MODE_FRAME' and -+ 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, -+ these counters reflect how many frames were not matched to any -+ existing key and therefore passed through the miss entry; The -+ total frames count will be returned in the counter of the -+ first range (as only one frame length range was defined). -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[out] p_MissStatistics Statistics counters for 'miss' -+ -+ @Return The statistics for 'miss'. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode, -+ t_FmPcdCcKeyStatistics *p_MissStatistics); -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableFindNGetKeyStatistics -+ -+ @Description This routine may be used to get statistics counters of specific key -+ in a CC Node. -+ -+ If 'e_FM_PCD_CC_STATS_MODE_FRAME' and -+ 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, -+ these counters reflect how many frames passed that were matched -+ this key; The total frames count will be returned in the counter -+ of the first range (as only one frame length range was defined). -+ If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total -+ frame count will be separated to frame length counters, based on -+ provided frame length ranges. -+ Note that this routine will search the node to locate the index -+ of the required key based on received key parameters. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keySize Size of the requested key -+ @Param[in] p_Key A pointer to the requested key -+ @Param[in] p_Mask A pointer to the mask if relevant, -+ otherwise pointer to NULL -+ @Param[out] p_KeyStatistics Key statistics counters -+ -+ @Return The specific key statistics. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode, -+ uint8_t keySize, -+ uint8_t *p_Key, -+ uint8_t *p_Mask, -+ t_FmPcdCcKeyStatistics *p_KeyStatistics); -+ -+/**************************************************************************//* -+ @Function FM_PCD_MatchTableGetNextEngine -+ -+ @Description Gets NextEngine of the relevant keyIndex. -+ -+ @Param[in] h_CcNode A handle to the node. -+ @Param[in] keyIndex keyIndex in the relevant node. -+ @Param[out] p_FmPcdCcNextEngineParams here updated nextEngine parameters for -+ the relevant keyIndex of the CC Node -+ received as parameter to this function -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableGetNextEngine(t_Handle h_CcNode, -+ uint16_t keyIndex, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -+ -+/**************************************************************************//* -+ @Function FM_PCD_MatchTableGetIndexedHashBucket -+ -+ @Description This routine simulates KeyGen operation on the provided key and -+ calculates to which hash bucket it will be mapped. -+ -+ @Param[in] h_CcNode A handle to the node. -+ @Param[in] kgKeySize Key size as it was configured in the KG -+ scheme that leads to this hash. -+ @Param[in] p_KgKey Pointer to the key; must be like the key -+ that the KG is generated, i.e. the same -+ extraction and with mask if exist. -+ @Param[in] kgHashShift Hash-shift as it was configured in the KG -+ scheme that leads to this hash. -+ @Param[out] p_CcNodeBucketHandle Pointer to the bucket of the provided key. -+ @Param[out] p_BucketIndex Index to the bucket of the provided key -+ @Param[out] p_LastIndex Pointer to last index in the bucket of the -+ provided key. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet() -+*//***************************************************************************/ -+t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode, -+ uint8_t kgKeySize, -+ uint8_t *p_KgKey, -+ uint8_t kgHashShift, -+ t_Handle *p_CcNodeBucketHandle, -+ uint8_t *p_BucketIndex, -+ uint16_t *p_LastIndex); -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableSet -+ -+ @Description This routine initializes a hash table structure. -+ KeyGen hash result determines the hash bucket. -+ Next, KeyGen key is compared against all keys of this -+ bucket (exact match). -+ Number of sets (number of buckets) of the hash equals to the -+ number of 1-s in 'hashResMask' in the provided parameters. -+ Number of hash table ways is then calculated by dividing -+ 'maxNumOfKeys' equally between the hash sets. This is the maximal -+ number of keys that a hash bucket may hold. -+ The hash table is initialized empty and keys may be -+ added to it following the initialization. Keys masks are not -+ supported in current hash table implementation. -+ The initialized hash table can be integrated as a node in a -+ CC tree. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] p_Param A structure of parameters defining the hash table -+ -+ @Return A handle to the initialized object on success; NULL code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param); -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableDelete -+ -+ @Description This routine deletes the provided hash table and released all -+ its allocated resources. -+ -+ @Param[in] h_HashTbl A handle to a hash table -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl); -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableAddKey -+ -+ @Description This routine adds the provided key (including next engine -+ parameters of this key) to the hash table. -+ The key is added as the last key of the bucket that it is -+ mapped to. -+ -+ @Param[in] h_HashTbl A handle to a hash table -+ @Param[in] keySize Key size of added key -+ @Param[in] p_KeyParams A pointer to the parameters includes -+ new key with next engine parameters; The pointer -+ to the key mask must be NULL, as masks are not -+ supported in hash table implementation. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, -+ uint8_t keySize, -+ t_FmPcdCcKeyParams *p_KeyParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableRemoveKey -+ -+ @Description This routine removes the requested key (including next engine -+ parameters of this key) from the hash table. -+ -+ @Param[in] h_HashTbl A handle to a hash table -+ @Param[in] keySize Key size of the one to remove. -+ @Param[in] p_Key A pointer to the requested key to remove. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, -+ uint8_t keySize, -+ uint8_t *p_Key); -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableModifyNextEngine -+ -+ @Description This routine modifies the next engine for the provided key. The -+ key should be previously added to the hash table. -+ -+ @Param[in] h_HashTbl A handle to a hash table -+ @Param[in] keySize Key size of the key to modify. -+ @Param[in] p_Key A pointer to the requested key to modify. -+ @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine -+ parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+ When configuring nextEngine = e_FM_PCD_CC, note that -+ p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different -+ from the currently changed table. -+*//***************************************************************************/ -+t_Error FM_PCD_HashTableModifyNextEngine(t_Handle h_HashTbl, -+ uint8_t keySize, -+ uint8_t *p_Key, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableModifyMissNextEngine -+ -+ @Description This routine modifies the next engine on key match miss. -+ -+ @Param[in] h_HashTbl A handle to a hash table -+ @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine -+ parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+ When configuring nextEngine = e_FM_PCD_CC, note that -+ p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different -+ from the currently changed table. -+*//***************************************************************************/ -+t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -+ -+/**************************************************************************//* -+ @Function FM_PCD_HashTableGetMissNextEngine -+ -+ @Description Gets NextEngine in case of key match miss. -+ -+ @Param[in] h_HashTbl A handle to a hash table -+ @Param[out] p_FmPcdCcNextEngineParams Next engine parameters for the specified -+ hash table. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_HashTableGetMissNextEngine(t_Handle h_HashTbl, -+ t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableFindNGetKeyStatistics -+ -+ @Description This routine may be used to get statistics counters of specific key -+ in a hash table. -+ -+ If 'e_FM_PCD_CC_STATS_MODE_FRAME' and -+ 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, -+ these counters reflect how many frames passed that were matched -+ this key; The total frames count will be returned in the counter -+ of the first range (as only one frame length range was defined). -+ If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total -+ frame count will be separated to frame length counters, based on -+ provided frame length ranges. -+ Note that this routine will identify the bucket of this key in -+ the hash table and will search the bucket to locate the index -+ of the required key based on received key parameters. -+ -+ @Param[in] h_HashTbl A handle to a hash table -+ @Param[in] keySize Size of the requested key -+ @Param[in] p_Key A pointer to the requested key -+ @Param[out] p_KeyStatistics Key statistics counters -+ -+ @Return The specific key statistics. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl, -+ uint8_t keySize, -+ uint8_t *p_Key, -+ t_FmPcdCcKeyStatistics *p_KeyStatistics); -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableGetMissStatistics -+ -+ @Description This routine may be used to get statistics counters of 'miss' -+ entry of the a hash table. -+ -+ If 'e_FM_PCD_CC_STATS_MODE_FRAME' and -+ 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, -+ these counters reflect how many frames were not matched to any -+ existing key and therefore passed through the miss entry; -+ -+ @Param[in] h_HashTbl A handle to a hash table -+ @Param[out] p_MissStatistics Statistics counters for 'miss' -+ -+ @Return The statistics for 'miss'. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl, -+ t_FmPcdCcKeyStatistics *p_MissStatistics); -+ -+/**************************************************************************//** -+ @Function FM_PCD_ManipNodeSet -+ -+ @Description This routine should be called for defining a manipulation -+ node. A manipulation node must be defined before the CC node -+ that precedes it. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] p_FmPcdManipParams A structure of parameters defining the manipulation -+ -+ @Return A handle to the initialized object on success; NULL code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_ManipNodeDelete -+ -+ @Description Delete an existing manipulation node. -+ -+ @Param[in] h_ManipNode A handle to a manipulation node. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_ManipNodeSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode); -+ -+/**************************************************************************//** -+ @Function FM_PCD_ManipGetStatistics -+ -+ @Description Retrieve the manipulation statistics. -+ -+ @Param[in] h_ManipNode A handle to a manipulation node. -+ @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_ManipNodeSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, t_FmPcdManipStats *p_FmPcdManipStats); -+ -+/**************************************************************************//** -+ @Function FM_PCD_ManipNodeReplace -+ -+ @Description Change existing manipulation node to be according to new requirement. -+ -+ @Param[in] h_ManipNode A handle to a manipulation node. -+ @Param[out] p_ManipParams A structure of parameters defining the change requirement -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_ManipNodeSet(). -+*//***************************************************************************/ -+t_Error FM_PCD_ManipNodeReplace(t_Handle h_ManipNode, t_FmPcdManipParams *p_ManipParams); -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Function FM_PCD_FrmReplicSetGroup -+ -+ @Description Initialize a Frame Replicator group. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of -+ the frame replicator group. -+ -+ @Return A handle to the initialized object on success; NULL code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, t_FmPcdFrmReplicGroupParams *p_FrmReplicGroupParam); -+ -+/**************************************************************************//** -+ @Function FM_PCD_FrmReplicDeleteGroup -+ -+ @Description Delete a Frame Replicator group. -+ -+ @Param[in] h_FrmReplicGroup A handle to the frame replicator group. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_FrmReplicSetGroup(). -+*//***************************************************************************/ -+t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_FrmReplicGroup); -+ -+/**************************************************************************//** -+ @Function FM_PCD_FrmReplicAddMember -+ -+ @Description Add the member in the index defined by the memberIndex. -+ -+ @Param[in] h_FrmReplicGroup A handle to the frame replicator group. -+ @Param[in] memberIndex member index for adding. -+ @Param[in] p_MemberParams A pointer to the new member parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group. -+*//***************************************************************************/ -+t_Error FM_PCD_FrmReplicAddMember(t_Handle h_FrmReplicGroup, -+ uint16_t memberIndex, -+ t_FmPcdCcNextEngineParams *p_MemberParams); -+ -+/**************************************************************************//** -+ @Function FM_PCD_FrmReplicRemoveMember -+ -+ @Description Remove the member defined by the index from the relevant group. -+ -+ @Param[in] h_FrmReplicGroup A handle to the frame replicator group. -+ @Param[in] memberIndex member index for removing. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group. -+*//***************************************************************************/ -+t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_FrmReplicGroup, -+ uint16_t memberIndex); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+/**************************************************************************//** -+ @Function FM_PCD_StatisticsSetNode -+ -+ @Description This routine should be called for defining a statistics node. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] p_FmPcdstatsParams A structure of parameters defining the statistics -+ -+ @Return A handle to the initialized object on success; NULL code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_FmPcdstatsParams); -+#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+ -+/** @} */ /* end of FM_PCD_Runtime_build_grp group */ -+/** @} */ /* end of FM_PCD_Runtime_grp group */ -+/** @} */ /* end of FM_PCD_grp group */ -+/** @} */ /* end of FM_grp group */ -+ -+ -+#ifdef NCSW_BACKWARD_COMPATIBLE_API -+#define FM_PCD_MAX_NUM_OF_INTERCHANGABLE_HDRS FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS -+#define e_FM_PCD_MANIP_ONE_WAYS_HASH e_FM_PCD_MANIP_ONE_WAY_HASH -+#define e_FM_PCD_MANIP_TOW_WAYS_HASH e_FM_PCD_MANIP_TWO_WAYS_HASH -+ -+#define e_FM_PCD_MANIP_FRAGMENT_PACKECT e_FM_PCD_MANIP_FRAGMENT_PACKET /* Feb13 */ -+ -+#define FM_PCD_SetNetEnvCharacteristics(_pcd, _params) \ -+ FM_PCD_NetEnvCharacteristicsSet(_pcd, _params) -+#define FM_PCD_KgSetScheme(_pcd, _params) FM_PCD_KgSchemeSet(_pcd, _params) -+#define FM_PCD_CcBuildTree(_pcd, _params) FM_PCD_CcRootBuild(_pcd, _params) -+#define FM_PCD_CcSetNode(_pcd, _params) FM_PCD_MatchTableSet(_pcd, _params) -+#define FM_PCD_PlcrSetProfile(_pcd, _params) FM_PCD_PlcrProfileSet(_pcd, _params) -+#define FM_PCD_ManipSetNode(_pcd, _params) FM_PCD_ManipNodeSet(_pcd, _params) -+ -+#define FM_PCD_DeleteNetEnvCharacteristics(_pcd, ...) \ -+ FM_PCD_NetEnvCharacteristicsDelete(__VA_ARGS__) -+#define FM_PCD_KgDeleteScheme(_pcd, ...) \ -+ FM_PCD_KgSchemeDelete(__VA_ARGS__) -+#define FM_PCD_KgGetSchemeCounter(_pcd, ...) \ -+ FM_PCD_KgSchemeGetCounter(__VA_ARGS__) -+#define FM_PCD_KgSetSchemeCounter(_pcd, ...) \ -+ FM_PCD_KgSchemeSetCounter(__VA_ARGS__) -+#define FM_PCD_PlcrDeleteProfile(_pcd, ...) \ -+ FM_PCD_PlcrProfileDelete(__VA_ARGS__) -+#define FM_PCD_PlcrGetProfileCounter(_pcd, ...) \ -+ FM_PCD_PlcrProfileGetCounter(__VA_ARGS__) -+#define FM_PCD_PlcrSetProfileCounter(_pcd, ...) \ -+ FM_PCD_PlcrProfileSetCounter(__VA_ARGS__) -+#define FM_PCD_CcDeleteTree(_pcd, ...) \ -+ FM_PCD_CcRootDelete(__VA_ARGS__) -+#define FM_PCD_CcTreeModifyNextEngine(_pcd, ...) \ -+ FM_PCD_CcRootModifyNextEngine(__VA_ARGS__) -+#define FM_PCD_CcDeleteNode(_pcd, ...) \ -+ FM_PCD_MatchTableDelete(__VA_ARGS__) -+#define FM_PCD_CcNodeModifyMissNextEngine(_pcd, ...) \ -+ FM_PCD_MatchTableModifyMissNextEngine(__VA_ARGS__) -+#define FM_PCD_CcNodeRemoveKey(_pcd, ...) \ -+ FM_PCD_MatchTableRemoveKey(__VA_ARGS__) -+#define FM_PCD_CcNodeAddKey(_pcd, ...) \ -+ FM_PCD_MatchTableAddKey(__VA_ARGS__) -+#define FM_PCD_CcNodeModifyNextEngine(_pcd, ...) \ -+ FM_PCD_MatchTableModifyNextEngine(__VA_ARGS__) -+#define FM_PCD_CcNodeModifyKeyAndNextEngine(_pcd, ...) \ -+ FM_PCD_MatchTableModifyKeyAndNextEngine(__VA_ARGS__) -+#define FM_PCD_CcNodeModifyKey(_pcd, ...) \ -+ FM_PCD_MatchTableModifyKey(__VA_ARGS__) -+#define FM_PCD_CcNodeFindNRemoveKey(_pcd, ...) \ -+ FM_PCD_MatchTableFindNRemoveKey(__VA_ARGS__) -+#define FM_PCD_CcNodeFindNModifyNextEngine(_pcd, ...) \ -+ FM_PCD_MatchTableFindNModifyNextEngine(__VA_ARGS__) -+#define FM_PCD_CcNodeFindNModifyKeyAndNextEngine(_pcd, ...) \ -+ FM_PCD_MatchTableFindNModifyKeyAndNextEngine(__VA_ARGS__) -+#define FM_PCD_CcNodeFindNModifyKey(_pcd, ...) \ -+ FM_PCD_MatchTableFindNModifyKey(__VA_ARGS__) -+#define FM_PCD_CcIndexedHashNodeGetBucket(_pcd, ...) \ -+ FM_PCD_MatchTableGetIndexedHashBucket(__VA_ARGS__) -+#define FM_PCD_CcNodeGetNextEngine(_pcd, ...) \ -+ FM_PCD_MatchTableGetNextEngine(__VA_ARGS__) -+#define FM_PCD_CcNodeGetKeyCounter(_pcd, ...) \ -+ FM_PCD_MatchTableGetKeyCounter(__VA_ARGS__) -+#define FM_PCD_ManipDeleteNode(_pcd, ...) \ -+ FM_PCD_ManipNodeDelete(__VA_ARGS__) -+#endif /* NCSW_BACKWARD_COMPATIBLE_API */ -+ -+ -+#endif /* __FM_PCD_EXT */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h -@@ -0,0 +1,2608 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File fm_port_ext.h -+ -+ @Description FM-Port Application Programming Interface. -+*//***************************************************************************/ -+#ifndef __FM_PORT_EXT -+#define __FM_PORT_EXT -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "fm_pcd_ext.h" -+#include "fm_ext.h" -+#include "net_ext.h" -+ -+ -+/**************************************************************************//** -+ -+ @Group FM_grp Frame Manager API -+ -+ @Description FM API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_PORT_grp FM Port -+ -+ @Description FM Port API -+ -+ The FM uses a general module called "port" to represent a Tx port -+ (MAC), an Rx port (MAC) or Offline Parsing port. -+ The number of ports in an FM varies between SOCs. -+ The SW driver manages these ports as sub-modules of the FM, i.e. -+ after an FM is initialized, its ports may be initialized and -+ operated upon. -+ -+ The port is initialized aware of its type, but other functions on -+ a port may be indifferent to its type. When necessary, the driver -+ verifies coherence and returns error if applicable. -+ -+ On initialization, user specifies the port type and it's index -+ (relative to the port's type) - always starting at 0. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description An enum for defining port PCD modes. -+ This enum defines the superset of PCD engines support - i.e. not -+ all engines have to be used, but all have to be enabled. The real -+ flow of a specific frame depends on the PCD configuration and the -+ frame headers and payload. -+ Note: the first engine and the first engine after the parser (if -+ exists) should be in order, the order is important as it will -+ define the flow of the port. However, as for the rest engines -+ (the ones that follows), the order is not important anymore as -+ it is defined by the PCD graph itself. -+*//***************************************************************************/ -+typedef enum e_FmPortPcdSupport { -+ e_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */ -+ , e_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */ -+ , e_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */ -+ , e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */ -+ , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */ -+ , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */ -+ , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR -+ /**< Use all PCD engines */ -+ , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */ -+ , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */ -+ , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */ -+ , e_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */ -+#ifdef FM_CAPWAP_SUPPORT -+ , e_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */ -+ , e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */ -+#endif /* FM_CAPWAP_SUPPORT */ -+} e_FmPortPcdSupport; -+ -+/**************************************************************************//** -+ @Description Port interrupts -+*//***************************************************************************/ -+typedef enum e_FmPortExceptions { -+ e_FM_PORT_EXCEPTION_IM_BUSY /**< Independent-Mode Rx-BUSY */ -+} e_FmPortExceptions; -+ -+ -+/**************************************************************************//** -+ @Collection General FM Port defines -+*//***************************************************************************/ -+#define FM_PORT_PRS_RESULT_NUM_OF_WORDS 8 /**< Number of 4 bytes words in parser result */ -+/* @} */ -+ -+/**************************************************************************//** -+ @Collection FM Frame error -+*//***************************************************************************/ -+typedef uint32_t fmPortFrameErrSelect_t; /**< typedef for defining Frame Descriptor errors */ -+ -+#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT FM_FD_ERR_UNSUPPORTED_FORMAT /**< Not for Rx-Port! Unsupported Format */ -+#define FM_PORT_FRM_ERR_LENGTH FM_FD_ERR_LENGTH /**< Not for Rx-Port! Length Error */ -+#define FM_PORT_FRM_ERR_DMA FM_FD_ERR_DMA /**< DMA Data error */ -+#define FM_PORT_FRM_ERR_NON_FM FM_FD_RX_STATUS_ERR_NON_FM /**< non Frame-Manager error; probably come from SEC that -+ was chained to FM */ -+ -+#define FM_PORT_FRM_ERR_IPRE (FM_FD_ERR_IPR & ~FM_FD_IPR) /**< IPR error */ -+#define FM_PORT_FRM_ERR_IPR_NCSP (FM_FD_ERR_IPR_NCSP & ~FM_FD_IPR) /**< IPR non-consistent-sp */ -+ -+#define FM_PORT_FRM_ERR_IPFE 0 /**< Obsolete; will be removed in the future */ -+ -+#ifdef FM_CAPWAP_SUPPORT -+#define FM_PORT_FRM_ERR_CRE FM_FD_ERR_CRE -+#define FM_PORT_FRM_ERR_CHE FM_FD_ERR_CHE -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+#define FM_PORT_FRM_ERR_PHYSICAL FM_FD_ERR_PHYSICAL /**< Rx FIFO overflow, FCS error, code error, running disparity -+ error (SGMII and TBI modes), FIFO parity error. PHY -+ Sequence error, PHY error control character detected. */ -+#define FM_PORT_FRM_ERR_SIZE FM_FD_ERR_SIZE /**< Frame too long OR Frame size exceeds max_length_frame */ -+#define FM_PORT_FRM_ERR_CLS_DISCARD FM_FD_ERR_CLS_DISCARD /**< indicates a classifier "drop" operation */ -+#define FM_PORT_FRM_ERR_EXTRACTION FM_FD_ERR_EXTRACTION /**< Extract Out of Frame */ -+#define FM_PORT_FRM_ERR_NO_SCHEME FM_FD_ERR_NO_SCHEME /**< No Scheme Selected */ -+#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW FM_FD_ERR_KEYSIZE_OVERFLOW /**< Keysize Overflow */ -+#define FM_PORT_FRM_ERR_COLOR_RED FM_FD_ERR_COLOR_RED /**< Frame color is red */ -+#define FM_PORT_FRM_ERR_COLOR_YELLOW FM_FD_ERR_COLOR_YELLOW /**< Frame color is yellow */ -+#define FM_PORT_FRM_ERR_ILL_PLCR FM_FD_ERR_ILL_PLCR /**< Illegal Policer Profile selected */ -+#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN FM_FD_ERR_PLCR_FRAME_LEN /**< Policer frame length error */ -+#define FM_PORT_FRM_ERR_PRS_TIMEOUT FM_FD_ERR_PRS_TIMEOUT /**< Parser Time out Exceed */ -+#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT FM_FD_ERR_PRS_ILL_INSTRUCT /**< Invalid Soft Parser instruction */ -+#define FM_PORT_FRM_ERR_PRS_HDR_ERR FM_FD_ERR_PRS_HDR_ERR /**< Header error was identified during parsing */ -+#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED FM_FD_ERR_BLOCK_LIMIT_EXCEEDED /**< Frame parsed beyind 256 first bytes */ -+#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */ -+/* @} */ -+ -+ -+ -+/**************************************************************************//** -+ @Group FM_PORT_init_grp FM Port Initialization Unit -+ -+ @Description FM Port Initialization Unit -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description Exceptions user callback routine, will be called upon an -+ exception passing the exception identification. -+ -+ @Param[in] h_App - User's application descriptor. -+ @Param[in] exception - The exception. -+ *//***************************************************************************/ -+typedef void (t_FmPortExceptionCallback) (t_Handle h_App, e_FmPortExceptions exception); -+ -+/**************************************************************************//** -+ @Description User callback function called by driver with received data. -+ -+ User provides this function. Driver invokes it. -+ -+ @Param[in] h_App Application's handle originally specified to -+ the API Config function -+ @Param[in] p_Data A pointer to data received -+ @Param[in] length length of received data -+ @Param[in] status receive status and errors -+ @Param[in] position position of buffer in frame -+ @Param[in] h_BufContext A handle of the user acossiated with this buffer -+ -+ @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx -+ operation for all ready data. -+ @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation. -+*//***************************************************************************/ -+typedef e_RxStoreResponse (t_FmPortImRxStoreCallback) (t_Handle h_App, -+ uint8_t *p_Data, -+ uint16_t length, -+ uint16_t status, -+ uint8_t position, -+ t_Handle h_BufContext); -+ -+/**************************************************************************//** -+ @Description User callback function called by driver when transmit completed. -+ -+ User provides this function. Driver invokes it. -+ -+ @Param[in] h_App Application's handle originally specified to -+ the API Config function -+ @Param[in] p_Data A pointer to data received -+ @Param[in] status transmit status and errors -+ @Param[in] lastBuffer is last buffer in frame -+ @Param[in] h_BufContext A handle of the user acossiated with this buffer -+ *//***************************************************************************/ -+typedef void (t_FmPortImTxConfCallback) (t_Handle h_App, -+ uint8_t *p_Data, -+ uint16_t status, -+ t_Handle h_BufContext); -+ -+/**************************************************************************//** -+ @Description A structure for additional Rx port parameters -+*//***************************************************************************/ -+typedef struct t_FmPortRxParams { -+ uint32_t errFqid; /**< Error Queue Id. */ -+ uint32_t dfltFqid; /**< Default Queue Id. */ -+ uint16_t liodnOffset; /**< Port's LIODN offset. */ -+ t_FmExtPools extBufPools; /**< Which external buffer pools are used -+ (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. */ -+} t_FmPortRxParams; -+ -+/**************************************************************************//** -+ @Description A structure for additional non-Rx port parameters -+*//***************************************************************************/ -+typedef struct t_FmPortNonRxParams { -+ uint32_t errFqid; /**< Error Queue Id. */ -+ uint32_t dfltFqid; /**< For Tx - Default Confirmation queue, -+ 0 means no Tx confirmation for processed -+ frames. For OP port - default Rx queue. */ -+ uint32_t qmChannel; /**< QM-channel dedicated to this port; will be used -+ by the FM for dequeue. */ -+} t_FmPortNonRxParams; -+ -+/**************************************************************************//** -+ @Description A structure for additional Rx port parameters -+*//***************************************************************************/ -+typedef struct t_FmPortImRxTxParams { -+ t_Handle h_FmMuram; /**< A handle of the FM-MURAM partition */ -+ uint16_t liodnOffset; /**< For Rx ports only. Port's LIODN Offset. */ -+ uint8_t dataMemId; /**< Memory partition ID for data buffers */ -+ uint32_t dataMemAttributes; /**< Memory attributes for data buffers */ -+ t_BufferPoolInfo rxPoolParams; /**< For Rx ports only. */ -+ t_FmPortImRxStoreCallback *f_RxStore; /**< For Rx ports only. */ -+ t_FmPortImTxConfCallback *f_TxConf; /**< For Tx ports only. */ -+} t_FmPortImRxTxParams; -+ -+/**************************************************************************//** -+ @Description A union for additional parameters depending on port type -+*//***************************************************************************/ -+typedef union u_FmPortSpecificParams { -+ t_FmPortImRxTxParams imRxTxParams; /**< Rx/Tx Independent-Mode port parameter structure */ -+ t_FmPortRxParams rxParams; /**< Rx port parameters structure */ -+ t_FmPortNonRxParams nonRxParams; /**< Non-Rx port parameters structure */ -+} u_FmPortSpecificParams; -+ -+/**************************************************************************//** -+ @Description A structure representing FM initialization parameters -+*//***************************************************************************/ -+typedef struct t_FmPortParams { -+ uintptr_t baseAddr; /**< Virtual Address of memory mapped FM Port registers.*/ -+ t_Handle h_Fm; /**< A handle to the FM object this port related to */ -+ e_FmPortType portType; /**< Port type */ -+ uint8_t portId; /**< Port Id - relative to type; -+ NOTE: When configuring Offline Parsing port for -+ FMANv3 devices (DPAA_VERSION 11 and higher), -+ it is highly recommended NOT to use portId=0 due to lack -+ of HW resources on portId=0. */ -+ bool independentModeEnable; -+ /**< This port is Independent-Mode - Used for Rx/Tx ports only! */ -+ uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be -+ used together with LIODN offset. */ -+ u_FmPortSpecificParams specificParams; /**< Additional parameters depending on port -+ type. */ -+ -+ t_FmPortExceptionCallback *f_Exception; /**< Relevant for IM only Callback routine to be called on BUSY exception */ -+ t_Handle h_App; /**< A handle to an application layer object; This handle will -+ be passed by the driver upon calling the above callbacks */ -+} t_FmPortParams; -+ -+ -+/**************************************************************************//** -+ @Function FM_PORT_Config -+ -+ @Description Creates a descriptor for the FM PORT module. -+ -+ The routine returns a handle (descriptor) to the FM PORT object. -+ This descriptor must be passed as first parameter to all other -+ FM PORT function calls. -+ -+ No actual initialization or configuration of FM hardware is -+ done by this routine. -+ -+ @Param[in] p_FmPortParams - Pointer to data structure of parameters -+ -+ @Retval Handle to FM object, or NULL for Failure. -+*//***************************************************************************/ -+t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams); -+ -+/**************************************************************************//** -+ @Function FM_PORT_Init -+ -+ @Description Initializes the FM PORT module by defining the software structure -+ and configuring the hardware registers. -+ -+ @Param[in] h_FmPort - FM PORT module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_PORT_Init(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_Free -+ -+ @Description Frees all resources that were assigned to FM PORT module. -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_FmPort - FM PORT module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_PORT_Free(t_Handle h_FmPort); -+ -+ -+/**************************************************************************//** -+ @Group FM_PORT_advanced_init_grp FM Port Advanced Configuration Unit -+ -+ @Description Configuration functions used to change default values. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description enum for defining QM frame dequeue -+*//***************************************************************************/ -+typedef enum e_FmPortDeqType { -+ e_FM_PORT_DEQ_TYPE1, /**< Dequeue from the SP channel - with priority precedence, -+ and Intra-Class Scheduling respected. */ -+ e_FM_PORT_DEQ_TYPE2, /**< Dequeue from the SP channel - with active FQ precedence, -+ and Intra-Class Scheduling respected. */ -+ e_FM_PORT_DEQ_TYPE3 /**< Dequeue from the SP channel - with active FQ precedence, -+ and override Intra-Class Scheduling */ -+} e_FmPortDeqType; -+ -+/**************************************************************************//** -+ @Description enum for defining QM frame dequeue -+*//***************************************************************************/ -+typedef enum e_FmPortDeqPrefetchOption { -+ e_FM_PORT_DEQ_NO_PREFETCH, /**< QMI preforms a dequeue action for a single frame -+ only when a dedicated portID Tnum is waiting. */ -+ e_FM_PORT_DEQ_PARTIAL_PREFETCH, /**< QMI preforms a dequeue action for 3 frames when -+ one dedicated portId tnum is waiting. */ -+ e_FM_PORT_DEQ_FULL_PREFETCH /**< QMI preforms a dequeue action for 3 frames when -+ no dedicated portId tnums are waiting. */ -+ -+} e_FmPortDeqPrefetchOption; -+ -+/**************************************************************************//** -+ @Description enum for defining port default color -+*//***************************************************************************/ -+typedef enum e_FmPortColor { -+ e_FM_PORT_COLOR_GREEN, /**< Default port color is green */ -+ e_FM_PORT_COLOR_YELLOW, /**< Default port color is yellow */ -+ e_FM_PORT_COLOR_RED, /**< Default port color is red */ -+ e_FM_PORT_COLOR_OVERRIDE /**< Ignore color */ -+} e_FmPortColor; -+ -+/**************************************************************************//** -+ @Description A structure for defining Dual Tx rate limiting scale -+*//***************************************************************************/ -+typedef enum e_FmPortDualRateLimiterScaleDown { -+ e_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */ -+ e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */ -+ e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */ -+ e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */ -+} e_FmPortDualRateLimiterScaleDown; -+ -+ -+/**************************************************************************//** -+ @Description A structure for defining FM port resources -+*//***************************************************************************/ -+typedef struct t_FmPortRsrc { -+ uint32_t num; /**< Committed required resource */ -+ uint32_t extra; /**< Extra (not committed) required resource */ -+} t_FmPortRsrc; -+ -+/**************************************************************************//** -+ @Description A structure for defining observed pool depletion -+*//***************************************************************************/ -+typedef struct t_FmPortObservedBufPoolDepletion { -+ t_FmBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */ -+ t_FmExtPools poolsParams; /**< Which external buffer pools are observed -+ (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS), -+ and their sizes. */ -+} t_FmPortObservedBufPoolDepletion; -+ -+/**************************************************************************//** -+ @Description A structure for defining Tx rate limiting -+*//***************************************************************************/ -+typedef struct t_FmPortRateLimit { -+ uint16_t maxBurstSize; /**< in KBytes for Tx ports, in frames -+ for OP ports. (note that -+ for early chips burst size is -+ rounded up to a multiply of 1000 frames).*/ -+ uint32_t rateLimit; /**< in Kb/sec for Tx ports, in frame/sec for -+ OP ports. Rate limit refers to -+ data rate (rather than line rate). */ -+ e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For OP ports only. Not-valid -+ for some earlier chip revisions */ -+} t_FmPortRateLimit; -+ -+/**************************************************************************//** -+ @Description A structure for defining the parameters of -+ the Rx port performance counters -+*//***************************************************************************/ -+typedef struct t_FmPortPerformanceCnt { -+ uint8_t taskCompVal; /**< Task compare value */ -+ uint8_t queueCompVal; /**< Rx queue/Tx confirm queue compare -+ value (unused for H/O) */ -+ uint8_t dmaCompVal; /**< Dma compare value */ -+ uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */ -+} t_FmPortPerformanceCnt; -+ -+ -+/**************************************************************************//** -+ @Description A structure for defining the sizes of the Deep Sleep -+ the Auto Response tables -+*//***************************************************************************/ -+typedef struct t_FmPortDsarTablesSizes -+{ -+ uint16_t maxNumOfArpEntries; -+ uint16_t maxNumOfEchoIpv4Entries; -+ uint16_t maxNumOfNdpEntries; -+ uint16_t maxNumOfEchoIpv6Entries; -+ uint16_t maxNumOfSnmpIPV4Entries; -+ uint16_t maxNumOfSnmpIPV6Entries; -+ uint16_t maxNumOfSnmpOidEntries; -+ uint16_t maxNumOfSnmpOidChar; /* total amount of character needed for the snmp table */ -+ -+ uint16_t maxNumOfIpProtFiltering; -+ uint16_t maxNumOfTcpPortFiltering; -+ uint16_t maxNumOfUdpPortFiltering; -+} t_FmPortDsarTablesSizes; -+ -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDsarSupport -+ -+ @Description This function will allocate the amount of MURAM needed for -+ this max number of entries for Deep Sleep Auto Response. -+ it will calculate all needed MURAM for autoresponse including -+ necesary common stuff. -+ -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] params A pointer to a structure containing the maximum -+ sizes of the auto response tables -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigNumOfOpenDmas -+ -+ @Description Calling this routine changes the max number of open DMA's -+ available for this port. It changes this parameter in the -+ internal driver data base from its default configuration -+ [OP: 1] -+ [1G-RX, 1G-TX: 1 (+1)] -+ [10G-RX, 10G-TX: 8 (+8)] -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_OpenDmas A pointer to a structure of parameters defining -+ the open DMA allocation. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigNumOfTasks -+ -+ @Description Calling this routine changes the max number of tasks -+ available for this port. It changes this parameter in the -+ internal driver data base from its default configuration -+ [OP: 1] -+ [1G-RX, 1G-TX: 3 (+2)] -+ [10G-RX, 10G-TX: 16 (+8)] -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_NumOfTasks A pointer to a structure of parameters defining -+ the tasks allocation. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigSizeOfFifo -+ -+ @Description Calling this routine changes the max FIFO size configured for this port. -+ -+ This function changes the internal driver data base from its -+ default configuration. Please refer to the driver's User Guide for -+ information on default FIFO sizes in the various devices. -+ [OP: 2KB] -+ [1G-RX, 1G-TX: 11KB] -+ [10G-RX, 10G-TX: 12KB] -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_SizeOfFifo A pointer to a structure of parameters defining -+ the FIFO allocation. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDeqHighPriority -+ -+ @Description Calling this routine changes the dequeue priority in the -+ internal driver data base from its default configuration -+ 1G: [DEFAULT_PORT_deqHighPriority_1G] -+ 10G: [DEFAULT_PORT_deqHighPriority_10G] -+ -+ May be used for Non-Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] highPri TRUE to select high priority, FALSE for normal operation. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDeqType -+ -+ @Description Calling this routine changes the dequeue type parameter in the -+ internal driver data base from its default configuration -+ [DEFAULT_PORT_deqType]. -+ -+ May be used for Non-Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] deqType According to QM definition. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDeqPrefetchOption -+ -+ @Description Calling this routine changes the dequeue prefetch option parameter in the -+ internal driver data base from its default configuration -+ [DEFAULT_PORT_deqPrefetchOption] -+ Note: Available for some chips only -+ -+ May be used for Non-Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] deqPrefetchOption New option -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDeqByteCnt -+ -+ @Description Calling this routine changes the dequeue byte count parameter in -+ the internal driver data base from its default configuration -+ 1G:[DEFAULT_PORT_deqByteCnt_1G]. -+ 10G:[DEFAULT_PORT_deqByteCnt_10G]. -+ -+ May be used for Non-Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] deqByteCnt New byte count -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigBufferPrefixContent -+ -+ @Description Defines the structure, size and content of the application buffer. -+ The prefix will -+ In Tx ports, if 'passPrsResult', the application -+ should set a value to their offsets in the prefix of -+ the FM will save the first 'privDataSize', than, -+ depending on 'passPrsResult' and 'passTimeStamp', copy parse result -+ and timeStamp, and the packet itself (in this order), to the -+ application buffer, and to offset. -+ Calling this routine changes the buffer margins definitions -+ in the internal driver data base from its default -+ configuration: Data size: [DEFAULT_PORT_bufferPrefixContent_privDataSize] -+ Pass Parser result: [DEFAULT_PORT_bufferPrefixContent_passPrsResult]. -+ Pass timestamp: [DEFAULT_PORT_bufferPrefixContent_passTimeStamp]. -+ -+ May be used for all ports -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the -+ structure of the buffer. -+ Out parameter: Start margin - offset -+ of data from start of external buffer. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort, -+ t_FmBufferPrefixContent *p_FmBufferPrefixContent); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigCheksumLastBytesIgnore -+ -+ @Description Calling this routine changes the number of checksum bytes to ignore -+ parameter in the internal driver data base from its default configuration -+ [DEFAULT_PORT_cheksumLastBytesIgnore] -+ -+ May be used by Tx & Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] cheksumLastBytesIgnore New value -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigCutBytesFromEnd -+ -+ @Description Calling this routine changes the number of bytes to cut from a -+ frame's end parameter in the internal driver data base -+ from its default configuration [DEFAULT_PORT_cutBytesFromEnd] -+ Note that if the result of (frame length before chop - cutBytesFromEnd) is -+ less than 14 bytes, the chop operation is not executed. -+ -+ May be used for Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] cutBytesFromEnd New value -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigPoolDepletion -+ -+ @Description Calling this routine enables pause frame generation depending on the -+ depletion status of BM pools. It also defines the conditions to activate -+ this functionality. By default, this functionality is disabled. -+ -+ May be used for Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_BufPoolDepletion A structure of pool depletion parameters -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmBufPoolDepletion *p_BufPoolDepletion); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigObservedPoolDepletion -+ -+ @Description Calling this routine enables a mechanism to stop port enqueue -+ depending on the depletion status of selected BM pools. -+ It also defines the conditions to activate -+ this functionality. By default, this functionality is disabled. -+ -+ Note: Available for some chips only -+ -+ May be used for OP ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_FmPortObservedBufPoolDepletion A structure of parameters for pool depletion. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort, -+ t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigExtBufPools -+ -+ @Description This routine should be called for OP ports -+ that internally use BM buffer pools. In such cases, e.g. for fragmentation and -+ re-assembly, the FM needs new BM buffers. By calling this routine the user -+ specifies the BM buffer pools that should be used. -+ -+ Note: Available for some chips only -+ -+ May be used for OP ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_FmExtPools A structure of parameters for the external pools. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigBackupPools -+ -+ @Description Calling this routine allows the configuration of some of the BM pools -+ defined for this port as backup pools. -+ A pool configured to be a backup pool will be used only if all other -+ enabled non-backup pools are depleted. -+ -+ May be used for Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_FmPortBackupBmPools An array of pool id's. All pools specified here will -+ be defined as backup pools. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmBackupBmPools *p_FmPortBackupBmPools); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigFrmDiscardOverride -+ -+ @Description Calling this routine changes the error frames destination parameter -+ in the internal driver data base from its default configuration: -+ override = [DEFAULT_PORT_frmDiscardOverride] -+ -+ May be used for Rx and OP ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] override TRUE to override discarding of error frames and -+ enqueueing them to error queue. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigErrorsToDiscard -+ -+ @Description Calling this routine changes the behaviour on error parameter -+ in the internal driver data base from its default configuration: -+ [DEFAULT_PORT_errorsToDiscard]. -+ If a requested error was previously defined as "ErrorsToEnqueue" it's -+ definition will change and the frame will be discarded. -+ Errors that were not defined either as "ErrorsToEnqueue" nor as -+ "ErrorsToDiscard", will be forwarded to CPU. -+ -+ May be used for Rx and OP ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] errs A list of errors to discard -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDmaSwapData -+ -+ @Description Calling this routine changes the DMA swap data aparameter -+ in the internal driver data base from its default -+ configuration [DEFAULT_PORT_dmaSwapData] -+ -+ May be used for all port types -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] swapData New selection -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDmaIcCacheAttr -+ -+ @Description Calling this routine changes the internal context cache -+ attribute parameter in the internal driver data base -+ from its default configuration [DEFAULT_PORT_dmaIntContextCacheAttr] -+ -+ May be used for all port types -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] intContextCacheAttr New selection -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmDmaCacheOption intContextCacheAttr); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDmaHdrAttr -+ -+ @Description Calling this routine changes the header cache -+ attribute parameter in the internal driver data base -+ from its default configuration [DEFAULT_PORT_dmaHeaderCacheAttr] -+ -+ May be used for all port types -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] headerCacheAttr New selection -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmDmaCacheOption headerCacheAttr); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDmaScatterGatherAttr -+ -+ @Description Calling this routine changes the scatter gather cache -+ attribute parameter in the internal driver data base -+ from its default configuration [DEFAULT_PORT_dmaScatterGatherCacheAttr] -+ -+ May be used for all port types -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] scatterGatherCacheAttr New selection -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDmaWriteOptimize -+ -+ @Description Calling this routine changes the write optimization -+ parameter in the internal driver data base -+ from its default configuration: By default optimize = [DEFAULT_PORT_dmaWriteOptimize]. -+ Note: -+ -+ 1. For head optimization, data alignment must be >= 16 (supported by default). -+ -+ 3. For tail optimization, note that the optimization is performed by extending the write transaction -+ of the frame payload at the tail as needed to achieve optimal bus transfers, so that the last write -+ is extended to be on 16/64 bytes aligned block (chip dependent). -+ -+ Relevant for non-Tx port types -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] optimize TRUE to enable optimization, FALSE for normal operation -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigNoScatherGather -+ -+ @Description Calling this routine changes the noScatherGather parameter in internal driver data base -+ from its default configuration. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] noScatherGather (TRUE - frame is discarded if can not be stored in single buffer, -+ FALSE - frame can be stored in scatter gather (S/G) format). -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDfltColor -+ -+ @Description Calling this routine changes the internal default color parameter -+ in the internal driver data base -+ from its default configuration [DEFAULT_PORT_color] -+ -+ May be used for all port types -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] color New selection -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigSyncReq -+ -+ @Description Calling this routine changes the synchronization attribute parameter -+ in the internal driver data base from its default configuration: -+ syncReq = [DEFAULT_PORT_syncReq] -+ -+ May be used for all port types -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] syncReq TRUE to request synchronization, FALSE otherwize. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigForwardReuseIntContext -+ -+ @Description This routine is relevant for Rx ports that are routed to OP port. -+ It changes the internal context reuse option in the internal -+ driver data base from its default configuration: -+ reuse = [DEFAULT_PORT_forwardIntContextReuse] -+ -+ May be used for Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] reuse TRUE to reuse internal context on frames -+ forwarded to OP port. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool reuse); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigDontReleaseTxBufToBM -+ -+ @Description This routine should be called if no Tx confirmation -+ is done, and yet buffers should not be released to the BM. -+ Normally, buffers are returned using the Tx confirmation -+ process. When Tx confirmation is not used (defFqid=0), -+ buffers are typically released to the BM. This routine -+ may be called to avoid this behavior and not release the -+ buffers. -+ -+ May be used for Tx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigIMMaxRxBufLength -+ -+ @Description Changes the maximum receive buffer length from its default -+ configuration: Closest rounded down power of 2 value of the -+ data buffer size. -+ -+ The maximum receive buffer length directly affects the structure -+ of received frames (single- or multi-buffered) and the performance -+ of both the FM and the driver. -+ -+ The selection between single- or multi-buffered frames should be -+ done according to the characteristics of the specific application. -+ The recommended mode is to use a single data buffer per packet, -+ as this mode provides the best performance. However, the user can -+ select to use multiple data buffers per packet. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] newVal Maximum receive buffer length (in bytes). -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+ This routine is to be used only if Independent-Mode is enabled. -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigIMRxBdRingLength -+ -+ @Description Changes the receive BD ring length from its default -+ configuration:[DEFAULT_PORT_rxBdRingLength] -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] newVal The desired BD ring length. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+ This routine is to be used only if Independent-Mode is enabled. -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigIMTxBdRingLength -+ -+ @Description Changes the transmit BD ring length from its default -+ configuration:[DEFAULT_PORT_txBdRingLength] -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] newVal The desired BD ring length. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+ This routine is to be used only if Independent-Mode is enabled. -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigIMFmanCtrlExternalStructsMemory -+ -+ @Description Configures memory partition and attributes for FMan-Controller -+ data structures (e.g. BD rings). -+ Calling this routine changes the internal driver data base -+ from its default configuration -+ [DEFAULT_PORT_ImfwExtStructsMemId, DEFAULT_PORT_ImfwExtStructsMemAttr]. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] memId Memory partition ID. -+ @Param[in] memAttributes Memory attributes mask (a combination of MEMORY_ATTR_x flags). -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort, -+ uint8_t memId, -+ uint32_t memAttributes); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigIMPolling -+ -+ @Description Changes the Rx flow from interrupt driven (default) to polling. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+ This routine is to be used only if Independent-Mode is enabled. -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigMaxFrameLength -+ -+ @Description Changes the definition of the max size of frame that should be -+ transmitted/received on this port from its default value [DEFAULT_PORT_maxFrameLength]. -+ This parameter is used for confirmation of the minimum Fifo -+ size calculations and only for Tx ports or ports working in -+ independent mode. This should be larger than the maximum possible -+ MTU that will be used for this port (i.e. its MAC). -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] length Max size of frame -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+ This routine is to be used only if Independent-Mode is enabled. -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length); -+ -+/**************************************************************************//* -+ @Function FM_PORT_ConfigTxFifoMinFillLevel -+ -+ @Description Calling this routine changes the fifo minimum -+ fill level parameter in the internal driver data base -+ from its default configuration [DEFAULT_PORT_txFifoMinFillLevel] -+ -+ May be used for Tx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] minFillLevel New value -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel); -+ -+/**************************************************************************//* -+ @Function FM_PORT_ConfigFifoDeqPipelineDepth -+ -+ @Description Calling this routine changes the fifo dequeue -+ pipeline depth parameter in the internal driver data base -+ -+ from its default configuration: 1G ports: [DEFAULT_PORT_fifoDeqPipelineDepth_1G], -+ 10G port: [DEFAULT_PORT_fifoDeqPipelineDepth_10G], -+ OP port: [DEFAULT_PORT_fifoDeqPipelineDepth_OH] -+ -+ May be used for Tx/OP ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] deqPipelineDepth New value -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth); -+ -+/**************************************************************************//* -+ @Function FM_PORT_ConfigTxFifoLowComfLevel -+ -+ @Description Calling this routine changes the fifo low comfort level -+ parameter in internal driver data base -+ from its default configuration [DEFAULT_PORT_txFifoLowComfLevel] -+ -+ May be used for Tx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] fifoLowComfLevel New value -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel); -+ -+/**************************************************************************//* -+ @Function FM_PORT_ConfigRxFifoThreshold -+ -+ @Description Calling this routine changes the threshold of the FIFO -+ fill level parameter in the internal driver data base -+ from its default configuration [DEFAULT_PORT_rxFifoThreshold] -+ -+ If the total number of buffers which are -+ currently in use and associated with the -+ specific RX port exceed this threshold, the -+ BMI will signal the MAC to send a pause frame -+ over the link. -+ -+ May be used for Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] fifoThreshold New value -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold); -+ -+/**************************************************************************//* -+ @Function FM_PORT_ConfigRxFifoPriElevationLevel -+ -+ @Description Calling this routine changes the priority elevation level -+ parameter in the internal driver data base from its default -+ configuration [DEFAULT_PORT_rxFifoPriElevationLevel] -+ -+ If the total number of buffers which are currently in use and -+ associated with the specific RX port exceed the amount specified -+ in priElevationLevel, BMI will signal the main FM's DMA to -+ elevate the FM priority on the system bus. -+ -+ May be used for Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] priElevationLevel New value -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel); -+ -+#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 -+/**************************************************************************//* -+ @Function FM_PORT_ConfigBCBWorkaround -+ -+ @Description Configures BCB errata workaround. -+ -+ When BCB errata is applicable, the workaround is always -+ performed by FM Controller. Thus, this functions doesn't -+ actually enable errata workaround but rather allows driver -+ to perform adjustments required due to errata workaround -+ execution in FM controller. -+ -+ Applying BCB workaround also configures FM_PORT_FRM_ERR_PHYSICAL -+ errors to be discarded. Thus FM_PORT_FRM_ERR_PHYSICAL can't be -+ set by FM_PORT_SetErrorsRoute() function. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort); -+#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */ -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//* -+ @Function FM_PORT_ConfigInternalBuffOffset -+ -+ @Description Configures internal buffer offset. -+ -+ May be used for Rx and OP ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] val New value -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ConfigInternalBuffOffset(t_Handle h_FmPort, uint8_t val); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/** @} */ /* end of FM_PORT_advanced_init_grp group */ -+/** @} */ /* end of FM_PORT_init_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_PORT_runtime_control_grp FM Port Runtime Control Unit -+ -+ @Description FM Port Runtime control unit API functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description enum for defining FM Port counters -+*//***************************************************************************/ -+typedef enum e_FmPortCounters { -+ e_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */ -+ e_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */ -+ e_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */ -+ e_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */ -+ e_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */ -+ e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */ -+ e_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */ -+ e_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */ -+ e_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */ -+ e_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */ -+ e_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */ -+ e_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */ -+ e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */ -+ e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */ -+ e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */ -+ e_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */ -+ e_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */ -+ e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */ -+ e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */ -+ e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */ -+ e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */ -+ e_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */ -+} e_FmPortCounters; -+ -+typedef struct t_FmPortBmiStats { -+ uint32_t cntCycle; -+ uint32_t cntTaskUtil; -+ uint32_t cntQueueUtil; -+ uint32_t cntDmaUtil; -+ uint32_t cntFifoUtil; -+ uint32_t cntRxPauseActivation; -+ uint32_t cntFrame; -+ uint32_t cntDiscardFrame; -+ uint32_t cntDeallocBuf; -+ uint32_t cntRxBadFrame; -+ uint32_t cntRxLargeFrame; -+ uint32_t cntRxFilterFrame; -+ uint32_t cntRxListDmaErr; -+ uint32_t cntRxOutOfBuffersDiscard; -+ uint32_t cntWredDiscard; -+ uint32_t cntLengthErr; -+ uint32_t cntUnsupportedFormat; -+} t_FmPortBmiStats; -+ -+/**************************************************************************//** -+ @Description Structure for Port id parameters. -+ Fields commented 'IN' are passed by the port module to be used -+ by the FM module. -+ Fields commented 'OUT' will be filled by FM before returning to port. -+*//***************************************************************************/ -+typedef struct t_FmPortCongestionGrps { -+ uint16_t numOfCongestionGrpsToConsider; /**< The number of required CGs -+ to define the size of the following array */ -+ uint8_t congestionGrpsToConsider[FM_PORT_NUM_OF_CONGESTION_GRPS]; -+ /**< An array of CG indexes; -+ Note that the size of the array should be -+ 'numOfCongestionGrpsToConsider'. */ -+#if (DPAA_VERSION >= 11) -+ bool pfcPrioritiesEn[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES]; -+ /**< a matrix that represents the map between the CG ids -+ defined in 'congestionGrpsToConsider' to the priorties -+ mapping array. */ -+#endif /* (DPAA_VERSION >= 11) */ -+} t_FmPortCongestionGrps; -+ -+/**************************************************************************//** -+ @Description Structure for Deep Sleep Auto Response ARP Entry -+*//***************************************************************************/ -+typedef struct t_FmPortDsarArpEntry -+{ -+ uint32_t ipAddress; -+ uint8_t mac[6]; -+ bool isVlan; -+ uint16_t vid; -+} t_FmPortDsarArpEntry; -+ -+/**************************************************************************//** -+ @Description Structure for Deep Sleep Auto Response ARP info -+*//***************************************************************************/ -+typedef struct t_FmPortDsarArpInfo -+{ -+ uint8_t tableSize; -+ t_FmPortDsarArpEntry *p_AutoResTable; -+ bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */ -+} t_FmPortDsarArpInfo; -+ -+/**************************************************************************//** -+ @Description Structure for Deep Sleep Auto Response NDP Entry -+*//***************************************************************************/ -+typedef struct t_FmPortDsarNdpEntry -+{ -+ uint32_t ipAddress[4]; -+ uint8_t mac[6]; -+ bool isVlan; -+ uint16_t vid; -+} t_FmPortDsarNdpEntry; -+ -+/**************************************************************************//** -+ @Description Structure for Deep Sleep Auto Response NDP info -+*//***************************************************************************/ -+typedef struct t_FmPortDsarNdpInfo -+{ -+ uint32_t multicastGroup; -+ -+ uint8_t tableSizeAssigned; -+ t_FmPortDsarNdpEntry *p_AutoResTableAssigned; /* This list refer to solicitation IP addresses. -+ Note that all IP adresses must be from the same multicast group. -+ This will be checked and if not operation will fail. */ -+ uint8_t tableSizeTmp; -+ t_FmPortDsarNdpEntry *p_AutoResTableTmp; /* This list refer to temp IP addresses. -+ Note that all temp IP adresses must be from the same multicast group. -+ This will be checked and if not operation will fail. */ -+ -+ bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */ -+ -+} t_FmPortDsarNdpInfo; -+ -+/**************************************************************************//** -+ @Description Structure for Deep Sleep Auto Response ICMPV4 info -+*//***************************************************************************/ -+typedef struct t_FmPortDsarEchoIpv4Info -+{ -+ uint8_t tableSize; -+ t_FmPortDsarArpEntry *p_AutoResTable; -+} t_FmPortDsarEchoIpv4Info; -+ -+/**************************************************************************//** -+ @Description Structure for Deep Sleep Auto Response ICMPV6 info -+*//***************************************************************************/ -+typedef struct t_FmPortDsarEchoIpv6Info -+{ -+ uint8_t tableSize; -+ t_FmPortDsarNdpEntry *p_AutoResTable; -+} t_FmPortDsarEchoIpv6Info; -+ -+/**************************************************************************//** -+@Description Deep Sleep Auto Response SNMP OIDs table entry -+ -+*//***************************************************************************/ -+typedef struct { -+ uint16_t oidSize; -+ uint8_t *oidVal; /* only the oid string */ -+ uint16_t resSize; -+ uint8_t *resVal; /* resVal will be the entire reply, -+ i.e. "Type|Length|Value" */ -+} t_FmPortDsarOidsEntry; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry -+ Refer to the FMan Controller spec for more details. -+*//***************************************************************************/ -+typedef struct -+{ -+ uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */ -+ bool isVlan; -+ uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ -+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ -+} t_FmPortDsarSnmpIpv4AddrTblEntry; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry -+ Refer to the FMan Controller spec for more details. -+*//***************************************************************************/ -+typedef struct -+{ -+ uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */ -+ bool isVlan; -+ uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ -+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ -+} t_FmPortDsarSnmpIpv6AddrTblEntry; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response SNMP Descriptor -+ -+*//***************************************************************************/ -+typedef struct -+{ -+ uint16_t control; /**< Control bits [0-15]. */ -+ uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */ -+ uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */ -+ uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */ -+ t_FmPortDsarSnmpIpv4AddrTblEntry *p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */ -+ t_FmPortDsarSnmpIpv6AddrTblEntry *p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */ -+ uint8_t *p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */ -+ uint8_t *p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */ -+ t_FmPortDsarOidsEntry *p_OidsTbl; /**< Pointer to OIDs table. */ -+ uint32_t oidsTblSize; /**< Number of entries in OIDs table. */ -+} t_FmPortDsarSnmpInfo; -+ -+/**************************************************************************//** -+ @Description Structure for Deep Sleep Auto Response filtering Entry -+*//***************************************************************************/ -+typedef struct t_FmPortDsarFilteringEntry -+{ -+ uint16_t srcPort; -+ uint16_t dstPort; -+ uint16_t srcPortMask; -+ uint16_t dstPortMask; -+} t_FmPortDsarFilteringEntry; -+ -+/**************************************************************************//** -+ @Description Structure for Deep Sleep Auto Response filtering info -+*//***************************************************************************/ -+typedef struct t_FmPortDsarFilteringInfo -+{ -+ /* IP protocol filtering parameters */ -+ uint8_t ipProtTableSize; -+ uint8_t *p_IpProtTablePtr; -+ bool ipProtPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped, -+ hit will pass the packet to UDP/TCP filters if needed and if not -+ to the classification tree. If the classification tree will pass -+ the packet to a queue it will cause a wake interupt. -+ When FALSE it the other way around. */ -+ /* UDP port filtering parameters */ -+ uint8_t udpPortsTableSize; -+ t_FmPortDsarFilteringEntry *p_UdpPortsTablePtr; -+ bool udpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped, -+ hit will pass the packet to classification tree. -+ If the classification tree will pass the packet to a queue it -+ will cause a wake interupt. -+ When FALSE it the other way around. */ -+ /* TCP port filtering parameters */ -+ uint16_t tcpFlagsMask; -+ uint8_t tcpPortsTableSize; -+ t_FmPortDsarFilteringEntry *p_TcpPortsTablePtr; -+ bool tcpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped, -+ hit will pass the packet to classification tree. -+ If the classification tree will pass the packet to a queue it -+ will cause a wake interupt. -+ When FALSE it the other way around. */ -+} t_FmPortDsarFilteringInfo; -+ -+/**************************************************************************//** -+ @Description Structure for Deep Sleep Auto Response parameters -+*//***************************************************************************/ -+typedef struct t_FmPortDsarParams -+{ -+ t_Handle h_FmPortTx; -+ t_FmPortDsarArpInfo *p_AutoResArpInfo; -+ t_FmPortDsarEchoIpv4Info *p_AutoResEchoIpv4Info; -+ t_FmPortDsarNdpInfo *p_AutoResNdpInfo; -+ t_FmPortDsarEchoIpv6Info *p_AutoResEchoIpv6Info; -+ t_FmPortDsarSnmpInfo *p_AutoResSnmpInfo; -+ t_FmPortDsarFilteringInfo *p_AutoResFilteringInfo; -+} t_FmPortDsarParams; -+ -+/**************************************************************************//** -+ @Function FM_PORT_EnterDsar -+ -+ @Description Enter Deep Sleep Auto Response mode. -+ This function write the apropriate values to in the relevant -+ tables in the MURAM. -+ -+ @Param[in] h_FmPortRx - FM PORT module descriptor -+ @Param[in] params - Auto Response parameters -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params); -+ -+/**************************************************************************//** -+ @Function FM_PORT_EnterDsarFinal -+ -+ @Description Enter Deep Sleep Auto Response mode. -+ This function sets the Tx port in independent mode as needed -+ and redirect the receive flow to go through the -+ Dsar Fman-ctrl code -+ -+ @Param[in] h_DsarRxPort - FM Rx PORT module descriptor -+ @Param[in] h_DsarTxPort - FM Tx PORT module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ExitDsar -+ -+ @Description Exit Deep Sleep Auto Response mode. -+ This function reverse the AR mode and put the ports back into -+ their original wake mode -+ -+ @Param[in] h_FmPortRx - FM PORT Rx module descriptor -+ @Param[in] h_FmPortTx - FM PORT Tx module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_EnterDsar(). -+*//***************************************************************************/ -+void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx); -+ -+/**************************************************************************//** -+ @Function FM_PORT_IsInDsar -+ -+ @Description This function returns TRUE if the port was set as Auto Response -+ and FALSE if not. Once Exit AR mode it will return FALSE as well -+ until re-enabled once more. -+ -+ @Param[in] h_FmPort - FM PORT module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+bool FM_PORT_IsInDsar(t_Handle h_FmPort); -+ -+typedef struct t_FmPortDsarStats -+{ -+ uint32_t arpArCnt; -+ uint32_t echoIcmpv4ArCnt; -+ uint32_t ndpArCnt; -+ uint32_t echoIcmpv6ArCnt; -+ uint32_t snmpGetCnt; -+ uint32_t snmpGetNextCnt; -+} t_FmPortDsarStats; -+ -+/**************************************************************************//** -+ @Function FM_PORT_GetDsarStats -+ -+ @Description Return statistics for Deep Sleep Auto Response -+ -+ @Param[in] h_FmPortRx - FM PORT module descriptor -+ @Param[out] stats - structure containing the statistics counters -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats); -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+/**************************************************************************//** -+ @Function FM_PORT_DumpRegs -+ -+ @Description Dump all regs. -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_FmPort - FM PORT module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_DumpRegs(t_Handle h_FmPort); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+/**************************************************************************//** -+ @Function FM_PORT_GetBufferDataOffset -+ -+ @Description Relevant for Rx ports. -+ Returns the data offset from the beginning of the data buffer -+ -+ @Param[in] h_FmPort - FM PORT module descriptor -+ -+ @Return data offset. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_GetBufferICInfo -+ -+ @Description Returns the Internal Context offset from the beginning of the data buffer -+ -+ @Param[in] h_FmPort - FM PORT module descriptor -+ @Param[in] p_Data - A pointer to the data buffer. -+ -+ @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not -+ configured for this port. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data); -+ -+/**************************************************************************//** -+ @Function FM_PORT_GetBufferPrsResult -+ -+ @Description Returns the pointer to the parse result in the data buffer. -+ In Rx ports this is relevant after reception, if parse -+ result is configured to be part of the data passed to the -+ application. For non Rx ports it may be used to get the pointer -+ of the area in the buffer where parse result should be -+ initialized - if so configured. -+ See FM_PORT_ConfigBufferPrefixContent for data buffer prefix -+ configuration. -+ -+ @Param[in] h_FmPort - FM PORT module descriptor -+ @Param[in] p_Data - A pointer to the data buffer. -+ -+ @Return Parse result pointer on success, NULL if parse result was not -+ configured for this port. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data); -+ -+/**************************************************************************//** -+ @Function FM_PORT_GetBufferTimeStamp -+ -+ @Description Returns the time stamp in the data buffer. -+ Relevant for Rx ports for getting the buffer time stamp. -+ See FM_PORT_ConfigBufferPrefixContent for data buffer prefix -+ configuration. -+ -+ @Param[in] h_FmPort - FM PORT module descriptor -+ @Param[in] p_Data - A pointer to the data buffer. -+ -+ @Return A pointer to the hash result on success, NULL otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data); -+ -+/**************************************************************************//** -+ @Function FM_PORT_GetBufferHashResult -+ -+ @Description Given a data buffer, on the condition that hash result was defined -+ as a part of the buffer content (see FM_PORT_ConfigBufferPrefixContent) -+ this routine will return the pointer to the hash result location in the -+ buffer prefix. -+ -+ @Param[in] h_FmPort - FM PORT module descriptor -+ @Param[in] p_Data - A pointer to the data buffer. -+ -+ @Return A pointer to the hash result on success, NULL otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data); -+ -+/**************************************************************************//** -+ @Function FM_PORT_Disable -+ -+ @Description Gracefully disable an FM port. The port will not start new tasks after all -+ tasks associated with the port are terminated. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+ This is a blocking routine, it returns after port is -+ gracefully stopped, i.e. the port will not except new frames, -+ but it will finish all frames or tasks which were already began -+*//***************************************************************************/ -+t_Error FM_PORT_Disable(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_Enable -+ -+ @Description A runtime routine provided to allow disable/enable of port. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_Enable(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetRateLimit -+ -+ @Description Calling this routine enables rate limit algorithm. -+ By default, this functionality is disabled. -+ Note that rate-limit mechanism uses the FM time stamp. -+ The selected rate limit specified here would be -+ rounded DOWN to the nearest 16M. -+ -+ May be used for Tx and OP ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_RateLimit A structure of rate limit parameters -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+ If rate limit is set on a port that need to send PFC frames, -+ it might violate the stop transmit timing. -+*//***************************************************************************/ -+t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit); -+ -+/**************************************************************************//** -+ @Function FM_PORT_DeleteRateLimit -+ -+ @Description Calling this routine disables and clears rate limit -+ initialization. -+ -+ May be used for Tx and OP ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetPfcPrioritiesMappingToQmanWQ -+ -+ @Description Calling this routine maps each PFC received priority to the transmit WQ. -+ This WQ will be blocked upon receiving a PFC frame with this priority. -+ -+ May be used for Tx ports only. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] prio PFC priority (0-7). -+ @Param[in] wq Work Queue (0-7). -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, uint8_t wq); -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetStatisticsCounters -+ -+ @Description Calling this routine enables/disables port's statistics counters. -+ By default, counters are enabled. -+ -+ May be used for all port types -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] enable TRUE to enable, FALSE to disable. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetFrameQueueCounters -+ -+ @Description Calling this routine enables/disables port's enqueue/dequeue counters. -+ By default, counters are enabled. -+ -+ May be used for all ports -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] enable TRUE to enable, FALSE to disable. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_PORT_AnalyzePerformanceParams -+ -+ @Description User may call this routine to so the driver will analyze if the -+ basic performance parameters are correct and also the driver may -+ suggest of improvements; The basic parameters are FIFO sizes, number -+ of DMAs and number of TNUMs for the port. -+ -+ May be used for all port types -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort); -+ -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetAllocBufCounter -+ -+ @Description Calling this routine enables/disables BM pool allocate -+ buffer counters. -+ By default, counters are enabled. -+ -+ May be used for Rx ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] poolId BM pool id. -+ @Param[in] enable TRUE to enable, FALSE to disable. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_PORT_GetBmiCounters -+ -+ @Description Read port's BMI stat counters and place them into -+ a designated structure of counters. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[out] p_BmiStats counters structure -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats); -+ -+/**************************************************************************//** -+ @Function FM_PORT_GetCounter -+ -+ @Description Reads one of the FM PORT counters. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] fmPortCounter The requested counter. -+ -+ @Return Counter's current value. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+ Note that it is user's responsibility to call this routine only -+ for enabled counters, and there will be no indication if a -+ disabled counter is accessed. -+*//***************************************************************************/ -+uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ModifyCounter -+ -+ @Description Sets a value to an enabled counter. Use "0" to reset the counter. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] fmPortCounter The requested counter. -+ @Param[in] value The requested value to be written into the counter. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter, uint32_t value); -+ -+/**************************************************************************//** -+ @Function FM_PORT_GetAllocBufCounter -+ -+ @Description Reads one of the FM PORT buffer counters. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] poolId The requested pool. -+ -+ @Return Counter's current value. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+ Note that it is user's responsibility to call this routine only -+ for enabled counters, and there will be no indication if a -+ disabled counter is accessed. -+*//***************************************************************************/ -+uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ModifyAllocBufCounter -+ -+ @Description Sets a value to an enabled counter. Use "0" to reset the counter. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] poolId The requested pool. -+ @Param[in] value The requested value to be written into the counter. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value); -+ -+/**************************************************************************//** -+ @Function FM_PORT_AddCongestionGrps -+ -+ @Description This routine effects the corresponding Tx port. -+ It should be called in order to enable pause -+ frame transmission in case of congestion in one or more -+ of the congestion groups relevant to this port. -+ Each call to this routine may add one or more congestion -+ groups to be considered relevant to this port. -+ -+ May be used for Rx, or RX+OP ports only (depending on chip) -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_CongestionGrps A pointer to an array of congestion groups -+ id's to consider. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps); -+ -+/**************************************************************************//** -+ @Function FM_PORT_RemoveCongestionGrps -+ -+ @Description This routine effects the corresponding Tx port. It should be -+ called when congestion groups were -+ defined for this port and are no longer relevant, or pause -+ frames transmitting is not required on their behalf. -+ Each call to this routine may remove one or more congestion -+ groups to be considered relevant to this port. -+ -+ May be used for Rx, or RX+OP ports only (depending on chip) -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_CongestionGrps A pointer to an array of congestion groups -+ id's to consider. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps); -+ -+/**************************************************************************//** -+ @Function FM_PORT_IsStalled -+ -+ @Description A routine for checking whether the specified port is stalled. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return TRUE if port is stalled, FALSE otherwize -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+bool FM_PORT_IsStalled(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ReleaseStalled -+ -+ @Description This routine may be called in case the port was stalled and may -+ now be released. -+ Note that this routine is available only on older FMan revisions -+ (FMan v2, DPAA v1.0 only). -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetRxL4ChecksumVerify -+ -+ @Description This routine is relevant for Rx ports (1G and 10G). The routine -+ set/clear the L3/L4 checksum verification (on RX side). -+ Note that this takes affect only if hw-parser is enabled! -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] l4Checksum boolean indicates whether to do L3/L4 checksum -+ on frames or not. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum); -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetErrorsRoute -+ -+ @Description Errors selected for this routine will cause a frame with that error -+ to be enqueued to error queue. -+ Errors not selected for this routine will cause a frame with that error -+ to be enqueued to the one of the other port queues. -+ By default all errors are defined to be enqueued to error queue. -+ Errors that were configured to be discarded (at initialization) -+ may not be selected here. -+ -+ May be used for Rx and OP ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] errs A list of errors to enqueue to error queue -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs); -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetIMExceptions -+ -+ @Description Calling this routine enables/disables FM PORT interrupts. -+ -+ @Param[in] h_FmPort FM PORT module descriptor. -+ @Param[in] exception The exception to be selected. -+ @Param[in] enable TRUE to enable interrupt, FALSE to mask it. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+ This routine should NOT be called from guest-partition -+ (i.e. guestId != NCSW_MASTER_ID) -+*//***************************************************************************/ -+t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable); -+ -+/**************************************************************************//* -+ @Function FM_PORT_SetPerformanceCounters -+ -+ @Description Calling this routine enables/disables port's performance counters. -+ By default, counters are enabled. -+ -+ May be used for all port types -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] enable TRUE to enable, FALSE to disable. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable); -+ -+/**************************************************************************//* -+ @Function FM_PORT_SetPerformanceCountersParams -+ -+ @Description Calling this routine defines port's performance -+ counters parameters. -+ -+ May be used for all port types -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance -+ counters parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt); -+ -+/**************************************************************************//** -+ @Group FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit -+ -+ @Description FM Port PCD Runtime control unit API functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description A structure defining the KG scheme after the parser. -+ This is relevant only to change scheme selection mode - from -+ direct to indirect and vice versa, or when the scheme is selected directly, -+ to select the scheme id. -+ -+*//***************************************************************************/ -+typedef struct t_FmPcdKgSchemeSelect { -+ bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV. */ -+ t_Handle h_DirectScheme; /**< Scheme handle, selects the scheme after parser; -+ Relevant only when 'direct' is TRUE. */ -+} t_FmPcdKgSchemeSelect; -+ -+/**************************************************************************//** -+ @Description A structure of scheme parameters -+*//***************************************************************************/ -+typedef struct t_FmPcdPortSchemesParams { -+ uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */ -+ t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'numOfSchemes' schemes for the -+ port to be bound to */ -+} t_FmPcdPortSchemesParams; -+ -+/**************************************************************************//** -+ @Description Union for defining port protocol parameters for parser -+*//***************************************************************************/ -+typedef union u_FmPcdHdrPrsOpts { -+ /* MPLS */ -+ struct { -+ bool labelInterpretationEnable; /**< When this bit is set, the last MPLS label will be -+ interpreted as described in HW spec table. When the bit -+ is cleared, the parser will advance to MPLS next parse */ -+ e_NetHeaderType nextParse; /**< must be equal or higher than IPv4 */ -+ } mplsPrsOptions; -+ /* VLAN */ -+ struct { -+ uint16_t tagProtocolId1; /**< User defined Tag Protocol Identifier, to be recognized -+ on VLAN TAG on top of 0x8100 and 0x88A8 */ -+ uint16_t tagProtocolId2; /**< User defined Tag Protocol Identifier, to be recognized -+ on VLAN TAG on top of 0x8100 and 0x88A8 */ -+ } vlanPrsOptions; -+ /* PPP */ -+ struct{ -+ bool enableMTUCheck; /**< Check validity of MTU according to RFC2516 */ -+ } pppoePrsOptions; -+ -+ /* IPV6 */ -+ struct{ -+ bool routingHdrEnable; /**< TRUE to enable routing header, otherwise ignore */ -+ } ipv6PrsOptions; -+ -+ /* UDP */ -+ struct{ -+ bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */ -+ } udpPrsOptions; -+ -+ /* TCP */ -+ struct { -+ bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */ -+ } tcpPrsOptions; -+} u_FmPcdHdrPrsOpts; -+ -+/**************************************************************************//** -+ @Description A structure for defining each header for the parser -+*//***************************************************************************/ -+typedef struct t_FmPcdPrsAdditionalHdrParams { -+ e_NetHeaderType hdr; /**< Selected header; use HEADER_TYPE_NONE -+ to indicate that sw parser is to run first -+ (before HW parser, and independent of the -+ existence of any protocol), in this case, -+ swPrsEnable must be set, and all other -+ parameters are irrelevant. */ -+ bool errDisable; /**< TRUE to disable error indication */ -+ bool swPrsEnable; /**< Enable jump to SW parser when this -+ header is recognized by the HW parser. */ -+ uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser -+ attachments exists for the same header, -+ (in the main sw parser code) use this -+ index to distinguish between them. */ -+ bool usePrsOpts; /**< TRUE to use parser options. */ -+ u_FmPcdHdrPrsOpts prsOpts; /**< A union according to header type, -+ defining the parser options selected.*/ -+} t_FmPcdPrsAdditionalHdrParams; -+ -+/**************************************************************************//** -+ @Description struct for defining port PCD parameters -+*//***************************************************************************/ -+typedef struct t_FmPortPcdPrsParams { -+ uint8_t prsResultPrivateInfo; /**< The private info provides a method of inserting -+ port information into the parser result. This information -+ may be extracted by Keygen and be used for frames -+ distribution when a per-port distinction is required, -+ it may also be used as a port logical id for analyzing -+ incoming frames. */ -+ uint8_t parsingOffset; /**< Number of bytes from beginning of packet to start parsing */ -+ e_NetHeaderType firstPrsHdr; /**< The type of the first header expected at 'parsingOffset' */ -+ bool includeInPrsStatistics; /**< TRUE to include this port in the parser statistics; -+ NOTE: this field is not valid when the FM is in "guest" mode -+ and IPC is not available. */ -+ uint8_t numOfHdrsWithAdditionalParams; /**< Normally 0, some headers may get -+ special parameters */ -+ t_FmPcdPrsAdditionalHdrParams additionalParams[FM_PCD_PRS_NUM_OF_HDRS]; -+ /**< 'numOfHdrsWithAdditionalParams' structures -+ of additional parameters -+ for each header that requires them */ -+ bool setVlanTpid1; /**< TRUE to configure user selection of Ethertype to -+ indicate a VLAN tag (in addition to the TPID values -+ 0x8100 and 0x88A8). */ -+ uint16_t vlanTpid1; /**< extra tag to use if setVlanTpid1=TRUE. */ -+ bool setVlanTpid2; /**< TRUE to configure user selection of Ethertype to -+ indicate a VLAN tag (in addition to the TPID values -+ 0x8100 and 0x88A8). */ -+ uint16_t vlanTpid2; /**< extra tag to use if setVlanTpid1=TRUE. */ -+} t_FmPortPcdPrsParams; -+ -+/**************************************************************************//** -+ @Description struct for defining coarse alassification parameters -+*//***************************************************************************/ -+typedef struct t_FmPortPcdCcParams { -+ t_Handle h_CcTree; /**< A handle to a CC tree */ -+} t_FmPortPcdCcParams; -+ -+/**************************************************************************//** -+ @Description struct for defining keygen parameters -+*//***************************************************************************/ -+typedef struct t_FmPortPcdKgParams { -+ uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */ -+ t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; -+ /**< Array of 'numOfSchemes' schemes handles for the -+ port to be bound to */ -+ bool directScheme; /**< TRUE for going from parser to a specific scheme, -+ regardless of parser result */ -+ t_Handle h_DirectScheme; /**< relevant only if direct == TRUE, Scheme handle, -+ as returned by FM_PCD_KgSetScheme */ -+} t_FmPortPcdKgParams; -+ -+/**************************************************************************//** -+ @Description struct for defining policer parameters -+*//***************************************************************************/ -+typedef struct t_FmPortPcdPlcrParams { -+ t_Handle h_Profile; /**< Selected profile handle */ -+} t_FmPortPcdPlcrParams; -+ -+/**************************************************************************//** -+ @Description struct for defining port PCD parameters -+*//***************************************************************************/ -+typedef struct t_FmPortPcdParams { -+ e_FmPortPcdSupport pcdSupport; /**< Relevant for Rx and offline ports only. -+ Describes the active PCD engines for this port. */ -+ t_Handle h_NetEnv; /**< HL Unused in PLCR only mode */ -+ t_FmPortPcdPrsParams *p_PrsParams; /**< Parser parameters for this port */ -+ t_FmPortPcdCcParams *p_CcParams; /**< Coarse classification parameters for this port */ -+ t_FmPortPcdKgParams *p_KgParams; /**< Keygen parameters for this port */ -+ t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port; Relevant for one of -+ following cases: -+ e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or -+ e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected, -+ or if any flow uses a KG scheme were policer -+ profile is not generated -+ ('bypassPlcrProfileGeneration selected'). */ -+ t_Handle h_IpReassemblyManip; /**< IP Reassembly manipulation */ -+#if (DPAA_VERSION >= 11) -+ t_Handle h_CapwapReassemblyManip;/**< CAPWAP Reassembly manipulation */ -+#endif /* (DPAA_VERSION >= 11) */ -+} t_FmPortPcdParams; -+ -+/**************************************************************************//** -+ @Description A structure for defining the Parser starting point -+*//***************************************************************************/ -+typedef struct t_FmPcdPrsStart { -+ uint8_t parsingOffset; /**< Number of bytes from beginning of packet to -+ start parsing */ -+ e_NetHeaderType firstPrsHdr; /**< The type of the first header axpected at -+ 'parsingOffset' */ -+} t_FmPcdPrsStart; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description struct for defining external buffer margins -+*//***************************************************************************/ -+typedef struct t_FmPortVSPAllocParams { -+ uint8_t numOfProfiles; /**< Number of Virtual Storage Profiles; must be a power of 2 */ -+ uint8_t dfltRelativeId; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port -+ The same default Virtual-Storage-Profile-id will be for coupled Tx port -+ if relevant function called for Rx port */ -+ t_Handle h_FmTxPort; /**< Handle to coupled Tx Port; not relevant for OP port. */ -+} t_FmPortVSPAllocParams; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetPCD -+ -+ @Description Calling this routine defines the port's PCD configuration. -+ It changes it from its default configuration which is PCD -+ disabled (BMI to BMI) and configures it according to the passed -+ parameters. -+ -+ May be used for Rx and OP ports only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_FmPortPcd A Structure of parameters defining the port's PCD -+ configuration. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_FmPortPcd); -+ -+/**************************************************************************//** -+ @Function FM_PORT_DeletePCD -+ -+ @Description Calling this routine releases the port's PCD configuration. -+ The port returns to its default configuration which is PCD -+ disabled (BMI to BMI) and all PCD configuration is removed. -+ -+ May be used for Rx and OP ports which are -+ in PCD mode only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_DeletePCD(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_AttachPCD -+ -+ @Description This routine may be called after FM_PORT_DetachPCD was called, -+ to return to the originally configured PCD support flow. -+ The couple of routines are used to allow PCD configuration changes -+ that demand that PCD will not be used while changes take place. -+ -+ May be used for Rx and OP ports which are -+ in PCD mode only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+t_Error FM_PORT_AttachPCD(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_DetachPCD -+ -+ @Description Calling this routine detaches the port from its PCD functionality. -+ The port returns to its default flow which is BMI to BMI. -+ -+ May be used for Rx and OP ports which are -+ in PCD mode only -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_AttachPCD(). -+*//***************************************************************************/ -+t_Error FM_PORT_DetachPCD(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdPlcrAllocProfiles -+ -+ @Description This routine may be called only for ports that use the Policer in -+ order to allocate private policer profiles. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] numOfProfiles The number of required policer profiles -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(), -+ and before FM_PORT_SetPCD(). -+*//***************************************************************************/ -+t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles); -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdPlcrFreeProfiles -+ -+ @Description This routine should be called for freeing private policer profiles. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(), -+ and before FM_PORT_SetPCD(). -+*//***************************************************************************/ -+t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort); -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Function FM_PORT_VSPAlloc -+ -+ @Description This routine allocated VSPs per port and forces the port to work -+ in VSP mode. Note that the port is initialized by default with the -+ physical-storage-profile only. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_Params A structure of parameters for allocation VSP's per port -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD() -+ and also before FM_PORT_Enable(); i.e. the port should be disabled. -+*//***************************************************************************/ -+t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_Params); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdKgModifyInitialScheme -+ -+ @Description This routine may be called only for ports that use the keygen in -+ order to change the initial scheme frame should be routed to. -+ The change may be of a scheme id (in case of direct mode), -+ from direct to indirect, or from indirect to direct - specifying the scheme id. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_FmPcdKgScheme A structure of parameters for defining whether -+ a scheme is direct/indirect, and if direct - scheme id. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD(). -+*//***************************************************************************/ -+t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme); -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdPlcrModifyInitialProfile -+ -+ @Description This routine may be called for ports with flows -+ e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR -+ only, to change the initial Policer profile frame should be -+ routed to. The change may be of a profile and/or absolute/direct -+ mode selection. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] h_Profile Policer profile handle -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD(). -+*//***************************************************************************/ -+t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile); -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdCcModifyTree -+ -+ @Description This routine may be called for ports that use coarse classification tree -+ if the user wishes to replace the tree. The routine may not be called while port -+ receives packets using the PCD functionalities, therefor port must be first detached -+ from the PCD, only than the routine may be called, and than port be attached to PCD again. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] h_CcTree A CC tree that was already built. The tree id as returned from -+ the BuildTree routine. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetachPCD() -+*//***************************************************************************/ -+t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree); -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdKgBindSchemes -+ -+ @Description These routines may be called for adding more schemes for the -+ port to be bound to. The selected schemes are not added, -+ just this specific port starts using them. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_PortScheme A structure defining the list of schemes to be added. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD(). -+*//***************************************************************************/ -+t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme); -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdKgUnbindSchemes -+ -+ @Description These routines may be called for adding more schemes for the -+ port to be bound to. The selected schemes are not removed or invalidated, -+ just this specific port stops using them. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_PortScheme A structure defining the list of schemes to be added. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD(). -+*//***************************************************************************/ -+t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme); -+ -+/**************************************************************************//** -+ @Function FM_PORT_GetIPv4OptionsCount -+ -+ @Description TODO -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[out] p_Ipv4OptionsCount will hold the counter value -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init() -+*//***************************************************************************/ -+t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, uint32_t *p_Ipv4OptionsCount); -+ -+/** @} */ /* end of FM_PORT_pcd_runtime_control_grp group */ -+/** @} */ /* end of FM_PORT_runtime_control_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_PORT_runtime_data_grp FM Port Runtime Data-path Unit -+ -+ @Description FM Port Runtime data unit API functions, definitions and enums. -+ This API is valid only if working in Independent-Mode. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_PORT_ImTx -+ -+ @Description Tx function, called to transmit a data buffer on the port. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_Data A pointer to an LCP data buffer. -+ @Param[in] length Size of data for transmission. -+ @Param[in] lastBuffer Buffer position - TRUE for the last buffer -+ of a frame, including a single buffer frame -+ @Param[in] h_BufContext A handle of the user acossiated with this buffer -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+ NOTE - This routine can be used only when working in -+ Independent-Mode mode. -+*//***************************************************************************/ -+t_Error FM_PORT_ImTx( t_Handle h_FmPort, -+ uint8_t *p_Data, -+ uint16_t length, -+ bool lastBuffer, -+ t_Handle h_BufContext); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ImTxConf -+ -+ @Description Tx port confirmation routine, optional, may be called to verify -+ transmission of all frames. The procedure performed by this -+ routine will be performed automatically on next buffer transmission, -+ but if desired, calling this routine will invoke this action on -+ demand. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+ NOTE - This routine can be used only when working in -+ Independent-Mode mode. -+*//***************************************************************************/ -+void FM_PORT_ImTxConf(t_Handle h_FmPort); -+ -+/**************************************************************************//** -+ @Function FM_PORT_ImRx -+ -+ @Description Rx function, may be called to poll for received buffers. -+ Normally, Rx process is invoked by the driver on Rx interrupt. -+ Alternatively, this routine may be called on demand. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+ NOTE - This routine can be used only when working in -+ Independent-Mode mode. -+*//***************************************************************************/ -+t_Error FM_PORT_ImRx(t_Handle h_FmPort); -+ -+/** @} */ /* end of FM_PORT_runtime_data_grp group */ -+/** @} */ /* end of FM_PORT_grp group */ -+/** @} */ /* end of FM_grp group */ -+ -+ -+ -+#ifdef NCSW_BACKWARD_COMPATIBLE_API -+#define FM_PORT_ConfigTxFifoDeqPipelineDepth FM_PORT_ConfigFifoDeqPipelineDepth -+#endif /* NCSW_BACKWARD_COMPATIBLE_API */ -+ -+ -+#endif /* __FM_PORT_EXT */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h -@@ -0,0 +1,619 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File fm_rtc_ext.h -+ -+ @Description External definitions and API for FM RTC IEEE1588 Timer Module. -+ -+ @Cautions None. -+*//***************************************************************************/ -+ -+#ifndef __FM_RTC_EXT_H__ -+#define __FM_RTC_EXT_H__ -+ -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "fsl_fman_rtc.h" -+ -+/**************************************************************************//** -+ -+ @Group FM_grp Frame Manager API -+ -+ @Description FM API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group fm_rtc_grp FM RTC -+ -+ @Description FM RTC functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group fm_rtc_init_grp FM RTC Initialization Unit -+ -+ @Description FM RTC initialization API. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description FM RTC Alarm Polarity Options. -+*//***************************************************************************/ -+typedef enum e_FmRtcAlarmPolarity -+{ -+ e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */ -+ e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */ -+} e_FmRtcAlarmPolarity; -+ -+/**************************************************************************//** -+ @Description FM RTC Trigger Polarity Options. -+*//***************************************************************************/ -+typedef enum e_FmRtcTriggerPolarity -+{ -+ e_FM_RTC_TRIGGER_ON_RISING_EDGE = E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */ -+ e_FM_RTC_TRIGGER_ON_FALLING_EDGE = E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */ -+} e_FmRtcTriggerPolarity; -+ -+/**************************************************************************//** -+ @Description IEEE1588 Timer Module FM RTC Optional Clock Sources. -+*//***************************************************************************/ -+typedef enum e_FmSrcClock -+{ -+ e_FM_RTC_SOURCE_CLOCK_EXTERNAL = E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */ -+ e_FM_RTC_SOURCE_CLOCK_SYSTEM = E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */ -+ e_FM_RTC_SOURCE_CLOCK_OSCILATOR = E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */ -+}e_FmSrcClk; -+ -+/**************************************************************************//** -+ @Description FM RTC configuration parameters structure. -+ -+ This structure should be passed to FM_RTC_Config(). -+*//***************************************************************************/ -+typedef struct t_FmRtcParams -+{ -+ t_Handle h_Fm; /**< FM Handle*/ -+ uintptr_t baseAddress; /**< Base address of FM RTC registers */ -+ t_Handle h_App; /**< A handle to an application layer object; This handle will -+ be passed by the driver upon calling the above callbacks */ -+} t_FmRtcParams; -+ -+ -+/**************************************************************************//** -+ @Function FM_RTC_Config -+ -+ @Description Configures the FM RTC module according to user's parameters. -+ -+ The driver assigns default values to some FM RTC parameters. -+ These parameters can be overwritten using the advanced -+ configuration routines. -+ -+ @Param[in] p_FmRtcParam - FM RTC configuration parameters. -+ -+ @Return Handle to the new FM RTC object; NULL pointer on failure. -+ -+ @Cautions None -+*//***************************************************************************/ -+t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam); -+ -+/**************************************************************************//** -+ @Function FM_RTC_Init -+ -+ @Description Initializes the FM RTC driver and hardware. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config(). -+*//***************************************************************************/ -+t_Error FM_RTC_Init(t_Handle h_FmRtc); -+ -+/**************************************************************************//** -+ @Function FM_RTC_Free -+ -+ @Description Frees the FM RTC object and all allocated resources. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config(). -+*//***************************************************************************/ -+t_Error FM_RTC_Free(t_Handle h_FmRtc); -+ -+ -+/**************************************************************************//** -+ @Group fm_rtc_adv_config_grp FM RTC Advanced Configuration Unit -+ -+ @Description FM RTC advanced configuration functions. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_RTC_ConfigPeriod -+ -+ @Description Configures the period of the timestamp if different than -+ default [DEFAULT_clockPeriod]. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] period - Period in nano-seconds. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config(). -+*//***************************************************************************/ -+t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period); -+ -+/**************************************************************************//** -+ @Function FM_RTC_ConfigSourceClock -+ -+ @Description Configures the source clock of the RTC. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] srcClk - Source clock selection. -+ @Param[in] freqInMhz - the source-clock frequency (in MHz). -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config(). -+*//***************************************************************************/ -+t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc, -+ e_FmSrcClk srcClk, -+ uint32_t freqInMhz); -+ -+/**************************************************************************//** -+ @Function FM_RTC_ConfigPulseRealignment -+ -+ @Description Configures the RTC to automatic FIPER pulse realignment in -+ response to timer adjustments [DEFAULT_pulseRealign] -+ -+ In this mode, the RTC clock is identical to the source clock. -+ This feature can be useful when the system contains an external -+ RTC with inherent frequency compensation. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] enable - TRUE to enable automatic realignment. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config(). -+*//***************************************************************************/ -+t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable); -+ -+/**************************************************************************//** -+ @Function FM_RTC_ConfigFrequencyBypass -+ -+ @Description Configures the RTC to bypass the frequency compensation -+ mechanism. [DEFAULT_bypass] -+ -+ In this mode, the RTC clock is identical to the source clock. -+ This feature can be useful when the system contains an external -+ RTC with inherent frequency compensation. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] enabled - TRUE to bypass frequency compensation; -+ FALSE otherwise. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config(). -+*//***************************************************************************/ -+t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled); -+ -+/**************************************************************************//** -+ @Function FM_RTC_ConfigInvertedInputClockPhase -+ -+ @Description Configures the RTC to invert the source clock phase on input. -+ [DEFAULT_invertInputClkPhase] -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] inverted - TRUE to invert the source clock phase on input. -+ FALSE otherwise. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config(). -+*//***************************************************************************/ -+t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted); -+ -+/**************************************************************************//** -+ @Function FM_RTC_ConfigInvertedOutputClockPhase -+ -+ @Description Configures the RTC to invert the output clock phase. -+ [DEFAULT_invertOutputClkPhase] -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] inverted - TRUE to invert the output clock phase. -+ FALSE otherwise. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config(). -+*//***************************************************************************/ -+t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted); -+ -+/**************************************************************************//** -+ @Function FM_RTC_ConfigOutputClockDivisor -+ -+ @Description Configures the divisor for generating the output clock from -+ the RTC clock. [DEFAULT_outputClockDivisor] -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] divisor - Divisor for generation of the output clock. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config(). -+*//***************************************************************************/ -+t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor); -+ -+/**************************************************************************//** -+ @Function FM_RTC_ConfigAlarmPolarity -+ -+ @Description Configures the polarity (active-high/active-low) of a specific -+ alarm signal. [DEFAULT_alarmPolarity] -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] alarmId - Alarm ID. -+ @Param[in] alarmPolarity - Alarm polarity. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config(). -+*//***************************************************************************/ -+t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc, -+ uint8_t alarmId, -+ e_FmRtcAlarmPolarity alarmPolarity); -+ -+/**************************************************************************//** -+ @Function FM_RTC_ConfigExternalTriggerPolarity -+ -+ @Description Configures the polarity (rising/falling edge) of a specific -+ external trigger signal. [DEFAULT_triggerPolarity] -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] triggerId - Trigger ID. -+ @Param[in] triggerPolarity - Trigger polarity. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously created using FM_RTC_Config(). -+*//***************************************************************************/ -+t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc, -+ uint8_t triggerId, -+ e_FmRtcTriggerPolarity triggerPolarity); -+ -+/** @} */ /* end of fm_rtc_adv_config_grp */ -+/** @} */ /* end of fm_rtc_init_grp */ -+ -+ -+/**************************************************************************//** -+ @Group fm_rtc_control_grp FM RTC Control Unit -+ -+ @Description FM RTC runtime control API. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function t_FmRtcExceptionsCallback -+ -+ @Description Exceptions user callback routine, used for RTC different mechanisms. -+ -+ @Param[in] h_App - User's application descriptor. -+ @Param[in] id - source id. -+*//***************************************************************************/ -+typedef void (t_FmRtcExceptionsCallback) ( t_Handle h_App, uint8_t id); -+ -+/**************************************************************************//** -+ @Description FM RTC alarm parameters. -+*//***************************************************************************/ -+typedef struct t_FmRtcAlarmParams { -+ uint8_t alarmId; /**< 0 or 1 */ -+ uint64_t alarmTime; /**< In nanoseconds, the time when the alarm -+ should go off - must be a multiple of -+ the RTC period */ -+ t_FmRtcExceptionsCallback *f_AlarmCallback; /**< This routine will be called when RTC -+ reaches alarmTime */ -+ bool clearOnExpiration; /**< TRUE to turn off the alarm once expired. */ -+} t_FmRtcAlarmParams; -+ -+/**************************************************************************//** -+ @Description FM RTC Periodic Pulse parameters. -+*//***************************************************************************/ -+typedef struct t_FmRtcPeriodicPulseParams { -+ uint8_t periodicPulseId; /**< 0 or 1 */ -+ uint64_t periodicPulsePeriod; /**< In Nanoseconds. Must be -+ a multiple of the RTC period */ -+ t_FmRtcExceptionsCallback *f_PeriodicPulseCallback; /**< This routine will be called every -+ periodicPulsePeriod. */ -+} t_FmRtcPeriodicPulseParams; -+ -+/**************************************************************************//** -+ @Description FM RTC Periodic Pulse parameters. -+*//***************************************************************************/ -+typedef struct t_FmRtcExternalTriggerParams { -+ uint8_t externalTriggerId; /**< 0 or 1 */ -+ bool usePulseAsInput; /**< Use the pulse interrupt instead of -+ an external signal */ -+ t_FmRtcExceptionsCallback *f_ExternalTriggerCallback; /**< This routine will be called every -+ periodicPulsePeriod. */ -+} t_FmRtcExternalTriggerParams; -+ -+ -+/**************************************************************************//** -+ @Function FM_RTC_Enable -+ -+ @Description Enable the RTC (time count is started). -+ -+ The user can select to resume the time count from previous -+ point, or to restart the time count. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] resetClock - Restart the time count from zero. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock); -+ -+/**************************************************************************//** -+ @Function FM_RTC_Disable -+ -+ @Description Disables the RTC (time count is stopped). -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_Disable(t_Handle h_FmRtc); -+ -+/**************************************************************************//** -+ @Function FM_RTC_SetClockOffset -+ -+ @Description Sets the clock offset (usually relative to another clock). -+ -+ The user can pass a negative offset value. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] offset - New clock offset (in nanoseconds). -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset); -+ -+/**************************************************************************//** -+ @Function FM_RTC_SetAlarm -+ -+ @Description Schedules an alarm event to a given RTC time. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] p_FmRtcAlarmParams - Alarm parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+ Must be called only prior to FM_RTC_Enable(). -+*//***************************************************************************/ -+t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams); -+ -+/**************************************************************************//** -+ @Function FM_RTC_SetPeriodicPulse -+ -+ @Description Sets a periodic pulse. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] p_FmRtcPeriodicPulseParams - Periodic pulse parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+ Must be called only prior to FM_RTC_Enable(). -+*//***************************************************************************/ -+t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams); -+ -+/**************************************************************************//** -+ @Function FM_RTC_ClearPeriodicPulse -+ -+ @Description Clears a periodic pulse. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] periodicPulseId - Periodic pulse id. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId); -+ -+/**************************************************************************//** -+ @Function FM_RTC_SetExternalTrigger -+ -+ @Description Sets an external trigger indication and define a callback -+ routine to be called on such event. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] p_FmRtcExternalTriggerParams - External Trigger parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams); -+ -+/**************************************************************************//** -+ @Function FM_RTC_ClearExternalTrigger -+ -+ @Description Clears external trigger indication. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] id - External Trigger id. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t id); -+ -+/**************************************************************************//** -+ @Function FM_RTC_GetExternalTriggerTimeStamp -+ -+ @Description Reads the External Trigger TimeStamp. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] triggerId - External Trigger id. -+ @Param[out] p_TimeStamp - External Trigger timestamp (in nanoseconds). -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc, -+ uint8_t triggerId, -+ uint64_t *p_TimeStamp); -+ -+/**************************************************************************//** -+ @Function FM_RTC_GetCurrentTime -+ -+ @Description Returns the current RTC time. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[out] p_Ts - returned time stamp (in nanoseconds). -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts); -+ -+/**************************************************************************//** -+ @Function FM_RTC_SetCurrentTime -+ -+ @Description Sets the current RTC time. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] ts - The new time stamp (in nanoseconds). -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts); -+ -+/**************************************************************************//** -+ @Function FM_RTC_GetFreqCompensation -+ -+ @Description Retrieves the frequency compensation value -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[out] p_Compensation - A pointer to the returned value of compensation. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation); -+ -+/**************************************************************************//** -+ @Function FM_RTC_SetFreqCompensation -+ -+ @Description Sets a new frequency compensation value. -+ -+ @Param[in] h_FmRtc - Handle to FM RTC object. -+ @Param[in] freqCompensation - The new frequency compensation value to set. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation); -+ -+#ifdef CONFIG_PTP_1588_CLOCK_DPAA -+/**************************************************************************//** -+*@Function FM_RTC_EnableInterrupt -+* -+*@Description Enable interrupt of FM RTC. -+* -+*@Param[in] h_FmRtc - Handle to FM RTC object. -+*@Param[in] events - Interrupt events. -+* -+*@Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events); -+ -+/**************************************************************************//** -+*@Function FM_RTC_DisableInterrupt -+* -+*@Description Disable interrupt of FM RTC. -+* -+*@Param[in] h_FmRtc - Handle to FM RTC object. -+*@Param[in] events - Interrupt events. -+* -+*@Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events); -+#endif -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+/**************************************************************************//** -+ @Function FM_RTC_DumpRegs -+ -+ @Description Dumps all FM registers -+ -+ @Param[in] h_FmRtc A handle to an FM RTC Module. -+ -+ @Return E_OK on success; -+ -+ @Cautions Allowed only FM_Init(). -+*//***************************************************************************/ -+t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+/** @} */ /* end of fm_rtc_control_grp */ -+/** @} */ /* end of fm_rtc_grp */ -+/** @} */ /* end of FM_grp group */ -+ -+ -+#endif /* __FM_RTC_EXT_H__ */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h -@@ -0,0 +1,411 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File fm_vsp_ext.h -+ -+ @Description FM Virtual Storage-Profile ... -+*//***************************************************************************/ -+#ifndef __FM_VSP_EXT_H -+#define __FM_VSP_EXT_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "string_ext.h" -+#include "debug_ext.h" -+ -+#include "fm_ext.h" -+ -+ -+/**************************************************************************//** -+ -+ @Group FM_grp Frame Manager API -+ -+ @Description FM API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_VSP_grp FM Virtual-Storage-Profile -+ -+ @Description FM Virtual-Storage-Profile API -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_VSP_init_grp FM VSP Initialization Unit -+ -+ @Description FM VSP initialization API. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description Virtual Storage Profile -+*//***************************************************************************/ -+typedef struct t_FmVspParams { -+ t_Handle h_Fm; /**< A handle to the FM object this VSP related to */ -+ t_FmExtPools extBufPools; /**< Which external buffer pools are used -+ (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. -+ parameter associated with Rx / OP port */ -+ uint16_t liodnOffset; /**< VSP's LIODN offset */ -+ struct { -+ e_FmPortType portType; /**< Port type */ -+ uint8_t portId; /**< Port Id - relative to type */ -+ } portParams; -+ uint8_t relativeProfileId; /**< VSP Id - relative to VSP's range -+ defined in relevant FM object */ -+} t_FmVspParams; -+ -+ -+/**************************************************************************//** -+ @Function FM_VSP_Config -+ -+ @Description Creates descriptor for the FM VSP module. -+ -+ The routine returns a handle (descriptor) to the FM VSP object. -+ This descriptor must be passed as first parameter to all other -+ FM VSP function calls. -+ -+ No actual initialization or configuration of FM hardware is -+ done by this routine. -+ -+@Param[in] p_FmVspParams Pointer to data structure of parameters -+ -+ @Retval Handle to FM VSP object, or NULL for Failure. -+*//***************************************************************************/ -+t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams); -+ -+/**************************************************************************//** -+ @Function FM_VSP_Init -+ -+ @Description Initializes the FM VSP module -+ -+ @Param[in] h_FmVsp - FM VSP module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_VSP_Init(t_Handle h_FmVsp); -+ -+/**************************************************************************//** -+ @Function FM_VSP_Free -+ -+ @Description Frees all resources that were assigned to FM VSP module. -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_FmVsp - FM VSP module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error FM_VSP_Free(t_Handle h_FmVsp); -+ -+ -+/**************************************************************************//** -+ @Group FM_VSP_adv_config_grp FM VSP Advanced Configuration Unit -+ -+ @Description FM VSP advanced configuration functions. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigBufferPrefixContent -+ -+ @Description Defines the structure, size and content of the application buffer. -+ -+ The prefix will -+ In VSPs defined for Tx ports, if 'passPrsResult', the application -+ should set a value to their offsets in the prefix of -+ the FM will save the first 'privDataSize', than, -+ depending on 'passPrsResult' and 'passTimeStamp', copy parse result -+ and timeStamp, and the packet itself (in this order), to the -+ application buffer, and to offset. -+ -+ Calling this routine changes the buffer margins definitions -+ in the internal driver data base from its default -+ configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize] -+ Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult]. -+ Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp]. -+ -+ @Param[in] h_FmVsp A handle to a FM VSP module. -+ @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the -+ structure of the buffer. -+ Out parameter: Start margin - offset -+ of data from start of external buffer. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, -+ t_FmBufferPrefixContent *p_FmBufferPrefixContent); -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigDmaSwapData -+ -+ @Description Calling this routine changes the DMA swap data parameter -+ in the internal driver data base from its default -+ configuration [DEFAULT_FM_SP_dmaSwapData] -+ -+ @Param[in] h_FmVsp A handle to a FM VSP module. -+ @Param[in] swapData New selection -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData); -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigDmaIcCacheAttr -+ -+ @Description Calling this routine changes the internal context cache -+ attribute parameter in the internal driver data base -+ from its default configuration [DEFAULT_FM_SP_dmaIntContextCacheAttr] -+ -+ @Param[in] h_FmVsp A handle to a FM VSP module. -+ @Param[in] intContextCacheAttr New selection -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, -+ e_FmDmaCacheOption intContextCacheAttr); -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigDmaHdrAttr -+ -+ @Description Calling this routine changes the header cache -+ attribute parameter in the internal driver data base -+ from its default configuration [DEFAULT_FM_SP_dmaHeaderCacheAttr] -+ -+ @Param[in] h_FmVsp A handle to a FM VSP module. -+ @Param[in] headerCacheAttr New selection -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr); -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigDmaScatterGatherAttr -+ -+ @Description Calling this routine changes the scatter gather cache -+ attribute parameter in the internal driver data base -+ from its default configuration [DEFAULT_FM_SP_dmaScatterGatherCacheAttr] -+ -+ @Param[in] h_FmVsp A handle to a FM VSP module. -+ @Param[in] scatterGatherCacheAttr New selection -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, -+ e_FmDmaCacheOption scatterGatherCacheAttr); -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigDmaWriteOptimize -+ -+ @Description Calling this routine changes the write optimization -+ parameter in the internal driver data base -+ from its default configuration: optimize = [DEFAULT_FM_SP_dmaWriteOptimize] -+ -+ @Param[in] h_FmVsp A handle to a FM VSP module. -+ @Param[in] optimize TRUE to enable optimization, FALSE for normal operation -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize); -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigNoScatherGather -+ -+ @Description Calling this routine changes the possibility to receive S/G frame -+ in the internal driver data base -+ from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather] -+ -+ @Param[in] h_FmVsp A handle to a FM VSP module. -+ @Param[in] noScatherGather TRUE to operate without scatter/gather capability. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather); -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigPoolDepletion -+ -+ @Description Calling this routine enables pause frame generation depending on the -+ depletion status of BM pools. It also defines the conditions to activate -+ this functionality. By default, this functionality is disabled. -+ -+ @Param[in] h_FmVsp A handle to a FM VSP module. -+ @Param[in] p_BufPoolDepletion A structure of pool depletion parameters -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion); -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigBackupPools -+ -+ @Description Calling this routine allows the configuration of some of the BM pools -+ defined for this port as backup pools. -+ A pool configured to be a backup pool will be used only if all other -+ enabled non-backup pools are depleted. -+ -+ @Param[in] h_FmVsp A handle to a FM VSP module. -+ @Param[in] p_BackupBmPools An array of pool id's. All pools specified here will -+ be defined as backup pools. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools); -+ -+/** @} */ /* end of FM_VSP_adv_config_grp group */ -+/** @} */ /* end of FM_VSP_init_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_VSP_control_grp FM VSP Control Unit -+ -+ @Description FM VSP runtime control API. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function FM_VSP_GetBufferDataOffset -+ -+ @Description Relevant for Rx ports. -+ Returns the data offset from the beginning of the data buffer -+ -+ @Param[in] h_FmVsp - FM PORT module descriptor -+ -+ @Return data offset. -+ -+ @Cautions Allowed only following FM_VSP_Init(). -+*//***************************************************************************/ -+uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp); -+ -+/**************************************************************************//** -+ @Function FM_VSP_GetBufferICInfo -+ -+ @Description Returns the Internal Context offset from the beginning of the data buffer -+ -+ @Param[in] h_FmVsp - FM PORT module descriptor -+ @Param[in] p_Data - A pointer to the data buffer. -+ -+ @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not -+ configured for this port. -+ -+ @Cautions Allowed only following FM_VSP_Init(). -+*//***************************************************************************/ -+uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data); -+ -+/**************************************************************************//** -+ @Function FM_VSP_GetBufferPrsResult -+ -+ @Description Returns the pointer to the parse result in the data buffer. -+ In Rx ports this is relevant after reception, if parse -+ result is configured to be part of the data passed to the -+ application. For non Rx ports it may be used to get the pointer -+ of the area in the buffer where parse result should be -+ initialized - if so configured. -+ See FM_VSP_ConfigBufferPrefixContent for data buffer prefix -+ configuration. -+ -+ @Param[in] h_FmVsp - FM PORT module descriptor -+ @Param[in] p_Data - A pointer to the data buffer. -+ -+ @Return Parse result pointer on success, NULL if parse result was not -+ configured for this port. -+ -+ @Cautions Allowed only following FM_VSP_Init(). -+*//***************************************************************************/ -+t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data); -+ -+/**************************************************************************//** -+ @Function FM_VSP_GetBufferTimeStamp -+ -+ @Description Returns the time stamp in the data buffer. -+ Relevant for Rx ports for getting the buffer time stamp. -+ See FM_VSP_ConfigBufferPrefixContent for data buffer prefix -+ configuration. -+ -+ @Param[in] h_FmVsp - FM PORT module descriptor -+ @Param[in] p_Data - A pointer to the data buffer. -+ -+ @Return A pointer to the hash result on success, NULL otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Init(). -+*//***************************************************************************/ -+uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data); -+ -+/**************************************************************************//** -+ @Function FM_VSP_GetBufferHashResult -+ -+ @Description Given a data buffer, on the condition that hash result was defined -+ as a part of the buffer content (see FM_VSP_ConfigBufferPrefixContent) -+ this routine will return the pointer to the hash result location in the -+ buffer prefix. -+ -+ @Param[in] h_FmVsp - FM PORT module descriptor -+ @Param[in] p_Data - A pointer to the data buffer. -+ -+ @Return A pointer to the hash result on success, NULL otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Init(). -+*//***************************************************************************/ -+uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data); -+ -+ -+/** @} */ /* end of FM_VSP_control_grp group */ -+/** @} */ /* end of FM_VSP_grp group */ -+/** @} */ /* end of FM_grp group */ -+ -+ -+#endif /* __FM_VSP_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h -@@ -0,0 +1,76 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+ -+#ifndef __MII_ACC_EXT_H -+#define __MII_ACC_EXT_H -+ -+ -+/**************************************************************************//** -+ @Function MII_ReadPhyReg -+ -+ @Description This routine is called to read a specified PHY -+ register value. -+ -+ @Param[in] h_MiiAccess - Handle to MII configuration access registers -+ @Param[in] phyAddr - PHY address (0-31). -+ @Param[in] reg - PHY register to read -+ @Param[out] p_Data - Gets the register value. -+ -+ @Return Always zero (success). -+*//***************************************************************************/ -+int MII_ReadPhyReg(t_Handle h_MiiAccess, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t *p_Data); -+ -+/**************************************************************************//** -+ @Function MII_WritePhyReg -+ -+ @Description This routine is called to write data to a specified PHY -+ register. -+ -+ @Param[in] h_MiiAccess - Handle to MII configuration access registers -+ @Param[in] phyAddr - PHY address (0-31). -+ @Param[in] reg - PHY register to write -+ @Param[in] data - Data to write in register. -+ -+ @Return Always zero (success). -+*//***************************************************************************/ -+int MII_WritePhyReg(t_Handle h_MiiAccess, -+ uint8_t phyAddr, -+ uint8_t reg, -+ uint16_t data); -+ -+ -+#endif /* __MII_ACC_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h -@@ -0,0 +1,90 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File core_ext.h -+ -+ @Description Generic interface to basic core operations. -+ -+ The system integrator must ensure that this interface is -+ mapped to a specific core implementation, by including the -+ appropriate header file. -+*//***************************************************************************/ -+#ifndef __CORE_EXT_H -+#define __CORE_EXT_H -+ -+#ifdef CONFIG_FMAN_ARM -+#include "arm_ext.h" -+#include -+#else -+#ifdef NCSW_PPC_CORE -+#include "ppc_ext.h" -+#elif defined(NCSW_VXWORKS) -+#include "core_vxw_ext.h" -+#else -+#error "Core is not defined!" -+#endif /* NCSW_CORE */ -+ -+#if (!defined(CORE_IS_LITTLE_ENDIAN) && !defined(CORE_IS_BIG_ENDIAN)) -+#error "Must define core as little-endian or big-endian!" -+#endif /* (!defined(CORE_IS_LITTLE_ENDIAN) && ... */ -+ -+#ifndef CORE_CACHELINE_SIZE -+#error "Must define the core cache-line size!" -+#endif /* !CORE_CACHELINE_SIZE */ -+ -+#endif /* CONFIG_FMAN_ARM */ -+ -+ -+/**************************************************************************//** -+ @Function CORE_GetId -+ -+ @Description Returns the core ID in the system. -+ -+ @Return Core ID. -+*//***************************************************************************/ -+uint32_t CORE_GetId(void); -+ -+/**************************************************************************//** -+ @Function CORE_MemoryBarrier -+ -+ @Description This routine will cause the core to stop executing any commands -+ until all previous memory read/write commands are completely out -+ of the core's pipeline. -+ -+ @Return None. -+*//***************************************************************************/ -+void CORE_MemoryBarrier(void); -+#define fsl_mem_core_barrier() CORE_MemoryBarrier() -+ -+#endif /* __CORE_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h -@@ -0,0 +1,55 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File arm_ext.h -+ -+ @Description Core API for ARM cores -+ -+ These routines must be implemented by each specific PowerPC -+ core driver. -+*//***************************************************************************/ -+#ifndef __ARM_EXT_H -+#define __ARM_EXT_H -+ -+#include "part_ext.h" -+ -+ -+#define CORE_IS_LITTLE_ENDIAN -+ -+static __inline__ void CORE_MemoryBarrier(void) -+{ -+ mb(); -+} -+ -+#endif /* __PPC_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h -@@ -0,0 +1,476 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File e500v2_ext.h -+ -+ @Description E500 external definitions prototypes -+ This file is not included by the E500 -+ source file as it is an assembly file. It is used -+ only for prototypes exposure, for inclusion -+ by user and other modules. -+*//***************************************************************************/ -+ -+#ifndef __E500V2_EXT_H -+#define __E500V2_EXT_H -+ -+#include "std_ext.h" -+ -+ -+/* Layer 1 Cache Manipulations -+ *============================== -+ * Should not be called directly by the user. -+ */ -+void L1DCache_Invalidate (void); -+void L1ICache_Invalidate(void); -+void L1DCache_Enable(void); -+void L1ICache_Enable(void); -+void L1DCache_Disable(void); -+void L1ICache_Disable(void); -+void L1DCache_Flush(void); -+void L1ICache_Flush(void); -+uint32_t L1ICache_IsEnabled(void); -+uint32_t L1DCache_IsEnabled(void); -+/* -+ * -+ */ -+uint32_t L1DCache_LineLock(uint32_t addr); -+uint32_t L1ICache_LineLock(uint32_t addr); -+void L1Cache_BroadCastEnable(void); -+void L1Cache_BroadCastDisable(void); -+ -+ -+#define CORE_DCacheEnable E500_DCacheEnable -+#define CORE_ICacheEnable E500_ICacheEnable -+#define CORE_DCacheDisable E500_DCacheDisable -+#define CORE_ICacheDisable E500_ICacheDisable -+#define CORE_GetId E500_GetId -+#define CORE_TestAndSet E500_TestAndSet -+#define CORE_MemoryBarrier E500_MemoryBarrier -+#define CORE_InstructionSync E500_InstructionSync -+ -+#define CORE_SetDozeMode E500_SetDozeMode -+#define CORE_SetNapMode E500_SetNapMode -+#define CORE_SetSleepMode E500_SetSleepMode -+#define CORE_SetJogMode E500_SetJogMode -+#define CORE_SetDeepSleepMode E500_SetDeepSleepMode -+ -+#define CORE_RecoverDozeMode E500_RecoverDozeMode -+#define CORE_RecoverNapMode E500_RecoverNapMode -+#define CORE_RecoverSleepMode E500_RecoverSleepMode -+#define CORE_RecoverJogMode E500_RecoverJogMode -+ -+void E500_SetDozeMode(void); -+void E500_SetNapMode(void); -+void E500_SetSleepMode(void); -+void E500_SetJogMode(void); -+t_Error E500_SetDeepSleepMode(uint32_t bptrAddress); -+ -+void E500_RecoverDozeMode(void); -+void E500_RecoverNapMode(void); -+void E500_RecoverSleepMode(void); -+void E500_RecoverJogMode(void); -+ -+ -+/**************************************************************************//** -+ @Group E500_id E500 Application Programming Interface -+ -+ @Description E500 API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group E500_init_grp E500 Initialization Unit -+ -+ @Description E500 initialization unit API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+ -+/**************************************************************************//** -+ @Function E500_DCacheEnable -+ -+ @Description Enables the data cache for memory pages that are -+ not cache inhibited. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_DCacheEnable(void); -+ -+/**************************************************************************//** -+ @Function E500_ICacheEnable -+ -+ @Description Enables the instruction cache for memory pages that are -+ not cache inhibited. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_ICacheEnable(void); -+ -+/**************************************************************************//** -+ @Function E500_DCacheDisable -+ -+ @Description Disables the data cache. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_DCacheDisable(void); -+ -+/**************************************************************************//** -+ @Function E500_ICacheDisable -+ -+ @Description Disables the instruction cache. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_ICacheDisable(void); -+ -+/**************************************************************************//** -+ @Function E500_DCacheFlush -+ -+ @Description Flushes the data cache -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_DCacheFlush(void); -+ -+/**************************************************************************//** -+ @Function E500_ICacheFlush -+ -+ @Description Flushes the instruction cache. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_ICacheFlush(void); -+ -+/**************************************************************************//** -+ @Function E500_DCacheSetStashId -+ -+ @Description Set Stash Id for data cache -+ -+ @Param[in] stashId the stash id to be set. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_DCacheSetStashId(uint8_t stashId); -+ -+/**************************************************************************//** -+ @Description E500mc L2 Cache Operation Mode -+*//***************************************************************************/ -+typedef enum e_E500mcL2CacheMode -+{ -+ e_L2_CACHE_MODE_DATA_ONLY = 0x00000001, /**< Cache data only */ -+ e_L2_CACHE_MODE_INST_ONLY = 0x00000002, /**< Cache instructions only */ -+ e_L2_CACHE_MODE_DATA_AND_INST = 0x00000003 /**< Cache data and instructions */ -+} e_E500mcL2CacheMode; -+ -+#if defined(CORE_E500MC) || defined(CORE_E5500) -+/**************************************************************************//** -+ @Function E500_L2CacheEnable -+ -+ @Description Enables the cache for memory pages that are not cache inhibited. -+ -+ @param[in] mode - L2 cache mode: data only, instruction only or instruction and data. -+ -+ @Return None. -+ -+ @Cautions This routine must be call only ONCE for both caches. I.e. it is -+ not possible to call this routine for i-cache and than to call -+ again for d-cache; The second call will override the first one. -+*//***************************************************************************/ -+void E500_L2CacheEnable(e_E500mcL2CacheMode mode); -+ -+/**************************************************************************//** -+ @Function E500_L2CacheDisable -+ -+ @Description Disables the cache (data instruction or both). -+ -+ @Return None. -+ -+*//***************************************************************************/ -+void E500_L2CacheDisable(void); -+ -+/**************************************************************************//** -+ @Function E500_L2CacheFlush -+ -+ @Description Flushes the cache. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_L2CacheFlush(void); -+ -+/**************************************************************************//** -+ @Function E500_L2SetStashId -+ -+ @Description Set Stash Id -+ -+ @Param[in] stashId the stash id to be set. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_L2SetStashId(uint8_t stashId); -+#endif /* defined(CORE_E500MC) || defined(CORE_E5500) */ -+ -+#ifdef CORE_E6500 -+/**************************************************************************//** -+ @Function E6500_L2CacheEnable -+ -+ @Description Enables the cache for memory pages that are not cache inhibited. -+ -+ @param[in] mode - L2 cache mode: support data & instruction only. -+ -+ @Return None. -+ -+ @Cautions This routine must be call only ONCE for both caches. I.e. it is -+ not possible to call this routine for i-cache and than to call -+ again for d-cache; The second call will override the first one. -+*//***************************************************************************/ -+void E6500_L2CacheEnable(uintptr_t clusterBase); -+ -+/**************************************************************************//** -+ @Function E6500_L2CacheDisable -+ -+ @Description Disables the cache (data instruction or both). -+ -+ @Return None. -+ -+*//***************************************************************************/ -+void E6500_L2CacheDisable(uintptr_t clusterBase); -+ -+/**************************************************************************//** -+ @Function E6500_L2CacheFlush -+ -+ @Description Flushes the cache. -+ -+ @Return None. -+*//***************************************************************************/ -+void E6500_L2CacheFlush(uintptr_t clusterBase); -+ -+/**************************************************************************//** -+ @Function E6500_L2SetStashId -+ -+ @Description Set Stash Id -+ -+ @Param[in] stashId the stash id to be set. -+ -+ @Return None. -+*//***************************************************************************/ -+void E6500_L2SetStashId(uintptr_t clusterBase, uint8_t stashId); -+ -+/**************************************************************************//** -+ @Function E6500_GetCcsrBase -+ -+ @Description Obtain SoC CCSR base address -+ -+ @Param[in] None. -+ -+ @Return Physical CCSR base address. -+*//***************************************************************************/ -+physAddress_t E6500_GetCcsrBase(void); -+#endif /* CORE_E6500 */ -+ -+/**************************************************************************//** -+ @Function E500_AddressBusStreamingEnable -+ -+ @Description Enables address bus streaming on the CCB. -+ -+ This setting, along with the ECM streaming configuration -+ parameters, enables address bus streaming on the CCB. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_AddressBusStreamingEnable(void); -+ -+/**************************************************************************//** -+ @Function E500_AddressBusStreamingDisable -+ -+ @Description Disables address bus streaming on the CCB. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_AddressBusStreamingDisable(void); -+ -+/**************************************************************************//** -+ @Function E500_AddressBroadcastEnable -+ -+ @Description Enables address broadcast. -+ -+ The e500 broadcasts cache management instructions (dcbst, dcblc -+ (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi) -+ based on ABE. ABE must be set to allow management of external -+ L2 caches. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_AddressBroadcastEnable(void); -+ -+/**************************************************************************//** -+ @Function E500_AddressBroadcastDisable -+ -+ @Description Disables address broadcast. -+ -+ The e500 broadcasts cache management instructions (dcbst, dcblc -+ (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi) -+ based on ABE. ABE must be set to allow management of external -+ L2 caches. -+ -+ @Return None. -+*//***************************************************************************/ -+void E500_AddressBroadcastDisable(void); -+ -+/**************************************************************************//** -+ @Function E500_IsTaskletSupported -+ -+ @Description Checks if tasklets are supported by the e500 interrupt handler. -+ -+ @Retval TRUE - Tasklets are supported. -+ @Retval FALSE - Tasklets are not supported. -+*//***************************************************************************/ -+bool E500_IsTaskletSupported(void); -+ -+void E500_EnableTimeBase(void); -+void E500_DisableTimeBase(void); -+ -+uint64_t E500_GetTimeBaseTime(void); -+ -+void E500_GenericIntrInit(void); -+ -+t_Error E500_SetIntr(int ppcIntrSrc, -+ void (* Isr)(t_Handle handle), -+ t_Handle handle); -+ -+t_Error E500_ClearIntr(int ppcIntrSrc); -+ -+/**************************************************************************//** -+ @Function E500_GenericIntrHandler -+ -+ @Description This is the general e500 interrupt handler. -+ -+ It is called by the main assembly interrupt handler -+ when an exception occurs and no other function has been -+ assigned to this exception. -+ -+ @Param intrEntry - (In) The exception interrupt vector entry. -+*//***************************************************************************/ -+void E500_GenericIntrHandler(uint32_t intrEntry); -+ -+/**************************************************************************//** -+ @Function CriticalIntr -+ -+ @Description This is the specific critical e500 interrupt handler. -+ -+ It is called by the main assembly interrupt handler -+ when an critical interrupt. -+ -+ @Param intrEntry - (In) The exception interrupt vector entry. -+*//***************************************************************************/ -+void CriticalIntr(uint32_t intrEntry); -+ -+ -+/**************************************************************************//** -+ @Function E500_GetId -+ -+ @Description Returns the core ID in the system. -+ -+ @Return Core ID. -+*//***************************************************************************/ -+uint32_t E500_GetId(void); -+ -+/**************************************************************************//** -+ @Function E500_TestAndSet -+ -+ @Description This routine tries to atomically test-and-set an integer -+ in memory to a non-zero value. -+ -+ The memory will be set only if it is tested as zero, in which -+ case the routine returns the new non-zero value; otherwise the -+ routine returns zero. -+ -+ @Param[in] p - pointer to a volatile int in memory, on which test-and-set -+ operation should be made. -+ -+ @Retval Zero - Operation failed - memory was already set. -+ @Retval Non-zero - Operation succeeded - memory has been set. -+*//***************************************************************************/ -+int E500_TestAndSet(volatile int *p); -+ -+/**************************************************************************//** -+ @Function E500_MemoryBarrier -+ -+ @Description This routine will cause the core to stop executing any commands -+ until all previous memory read/write commands are completely out -+ of the core's pipeline. -+ -+ @Return None. -+*//***************************************************************************/ -+static __inline__ void E500_MemoryBarrier(void) -+{ -+#ifndef CORE_E500V2 -+ __asm__ ("mbar 1"); -+#else /* CORE_E500V2 */ -+ /**** ERRATA WORK AROUND START ****/ -+ /* ERRATA num: CPU1 */ -+ /* Description: "mbar MO = 1" instruction fails to order caching-inhibited -+ guarded loads and stores. */ -+ -+ /* "msync" instruction is used instead */ -+ -+ __asm__ ("msync"); -+ -+ /**** ERRATA WORK AROUND END ****/ -+#endif /* CORE_E500V2 */ -+} -+ -+/**************************************************************************//** -+ @Function E500_InstructionSync -+ -+ @Description This routine will cause the core to wait for previous instructions -+ (including any interrupts they generate) to complete before the -+ synchronization command executes, which purges all instructions -+ from the processor's pipeline and refetches the next instruction. -+ -+ @Return None. -+*//***************************************************************************/ -+static __inline__ void E500_InstructionSync(void) -+{ -+ __asm__ ("isync"); -+} -+ -+ -+/** @} */ /* end of E500_init_grp group */ -+/** @} */ /* end of E500_grp group */ -+ -+ -+#endif /* __E500V2_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h -@@ -0,0 +1,141 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File ppc_ext.h -+ -+ @Description Core API for PowerPC cores -+ -+ These routines must be implemented by each specific PowerPC -+ core driver. -+*//***************************************************************************/ -+#ifndef __PPC_EXT_H -+#define __PPC_EXT_H -+ -+#include "part_ext.h" -+ -+ -+#define CORE_IS_BIG_ENDIAN -+ -+#if defined(CORE_E300) || defined(CORE_E500V2) -+#define CORE_CACHELINE_SIZE 32 -+#elif defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500) -+#define CORE_CACHELINE_SIZE 64 -+#else -+#error "Core not defined!" -+#endif /* defined(CORE_E300) || ... */ -+ -+ -+/**************************************************************************//** -+ @Function CORE_TestAndSet -+ -+ @Description This routine tries to atomically test-and-set an integer -+ in memory to a non-zero value. -+ -+ The memory will be set only if it is tested as zero, in which -+ case the routine returns the new non-zero value; otherwise the -+ routine returns zero. -+ -+ @Param[in] p - pointer to a volatile int in memory, on which test-and-set -+ operation should be made. -+ -+ @Retval Zero - Operation failed - memory was already set. -+ @Retval Non-zero - Operation succeeded - memory has been set. -+*//***************************************************************************/ -+int CORE_TestAndSet(volatile int *p); -+ -+/**************************************************************************//** -+ @Function CORE_InstructionSync -+ -+ @Description This routine will cause the core to wait for previous instructions -+ (including any interrupts they generate) to complete before the -+ synchronization command executes, which purges all instructions -+ from the processor's pipeline and refetches the next instruction. -+ -+ @Return None. -+*//***************************************************************************/ -+void CORE_InstructionSync(void); -+ -+/**************************************************************************//** -+ @Function CORE_DCacheEnable -+ -+ @Description Enables the data cache for memory pages that are -+ not cache inhibited. -+ -+ @Return None. -+*//***************************************************************************/ -+void CORE_DCacheEnable(void); -+ -+/**************************************************************************//** -+ @Function CORE_ICacheEnable -+ -+ @Description Enables the instruction cache for memory pages that are -+ not cache inhibited. -+ -+ @Return None. -+*//***************************************************************************/ -+void CORE_ICacheEnable(void); -+ -+/**************************************************************************//** -+ @Function CORE_DCacheDisable -+ -+ @Description Disables the data cache. -+ -+ @Return None. -+*//***************************************************************************/ -+void CORE_DCacheDisable(void); -+ -+/**************************************************************************//** -+ @Function CORE_ICacheDisable -+ -+ @Description Disables the instruction cache. -+ -+ @Return None. -+*//***************************************************************************/ -+void CORE_ICacheDisable(void); -+ -+ -+ -+#if defined(CORE_E300) -+#include "e300_ext.h" -+#elif defined(CORE_E500V2) || defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500) -+#include "e500v2_ext.h" -+#if !defined(NCSW_LINUX) -+#include "e500v2_asm_ext.h" -+#endif -+#else -+#error "Core not defined!" -+#endif -+ -+ -+#endif /* __PPC_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h -@@ -0,0 +1,77 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __DDR_SDT_EXT_H -+#define __DDR_SDT_EXT_H -+ -+ -+/**************************************************************************//** -+ @Group ddr_Generic_Resources -+ -+ @Description ddr generic functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+ -+/**************************************************************************//** -+ @Description SPD maximum size -+*//***************************************************************************/ -+#define SPD_MAX_SIZE 256 -+ -+/**************************************************************************//** -+ @Description DDR types select -+*//***************************************************************************/ -+typedef enum e_DdrType -+{ -+ e_DDR_DDR1, -+ e_DDR_DDR2, -+ e_DDR_DDR3, -+ e_DDR_DDR3L, -+ e_DDR_DDR4 -+} e_DdrType; -+ -+/**************************************************************************//** -+ @Description DDR Mode. -+*//***************************************************************************/ -+typedef enum e_DdrMode -+{ -+ e_DDR_BUS_WIDTH_32BIT, -+ e_DDR_BUS_WIDTH_64BIT -+} e_DdrMode; -+ -+/** @} */ /* end of ddr_Generic_Resources group */ -+ -+ -+ -+#endif /* __DDR_SDT_EXT_H */ -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h -@@ -0,0 +1,233 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File debug_ext.h -+ -+ @Description Debug mode definitions. -+*//***************************************************************************/ -+ -+#ifndef __DEBUG_EXT_H -+#define __DEBUG_EXT_H -+ -+#include "std_ext.h" -+#include "xx_ext.h" -+#include "memcpy_ext.h" -+#if (DEBUG_ERRORS > 0) -+#include "sprint_ext.h" -+#include "string_ext.h" -+#endif /* DEBUG_ERRORS > 0 */ -+ -+ -+#if (DEBUG_ERRORS > 0) -+ -+/* Internally used macros */ -+ -+#define DUMP_Print XX_Print -+#define DUMP_MAX_LEVELS 6 -+#define DUMP_IDX_LEN 6 -+#define DUMP_MAX_STR 64 -+ -+ -+#define _CREATE_DUMP_SUBSTR(phrase) \ -+ dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \ -+ snprintf(dumpTmpStr, DUMP_MAX_STR, "%s", #phrase); \ -+ p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \ -+ while ((p_DumpToken != NULL) && (dumpTmpLevel < DUMP_MAX_LEVELS)) \ -+ { \ -+ strlcat(dumpSubStr, p_DumpToken, DUMP_MAX_STR); \ -+ if (dumpIsArr[dumpTmpLevel]) \ -+ { \ -+ strlcat(dumpSubStr, dumpIdxStr[dumpTmpLevel], DUMP_MAX_STR); \ -+ p_DumpToken = strtok(NULL, "."); \ -+ } \ -+ if ((p_DumpToken != NULL) && \ -+ ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != NULL)) \ -+ strlcat(dumpSubStr, ".", DUMP_MAX_STR); \ -+ } -+ -+ -+/**************************************************************************//** -+ @Group gen_id General Drivers Utilities -+ -+ @Description External routines. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group dump_id Memory and Registers Dump Mechanism -+ -+ @Description Macros for dumping memory mapped structures. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description Declaration of dump mechanism variables. -+ -+ This macro must be declared at the beginning of each routine -+ which uses the dump mechanism macros, before the routine's code -+ starts. -+*//***************************************************************************/ -+#define DECLARE_DUMP \ -+ char dumpIdxStr[DUMP_MAX_LEVELS + 1][DUMP_IDX_LEN] = { "", }; \ -+ char dumpSubStr[DUMP_MAX_STR] = ""; \ -+ char dumpTmpStr[DUMP_MAX_STR] = ""; \ -+ char *p_DumpToken = NULL; \ -+ int dumpArrIdx = 0, dumpArrSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \ -+ uint8_t dumpIsArr[DUMP_MAX_LEVELS + 1] = { 0 }; \ -+ /* Prevent warnings if not all used */ \ -+ UNUSED(dumpIdxStr[0][0]); \ -+ UNUSED(dumpSubStr[0]); \ -+ UNUSED(dumpTmpStr[0]); \ -+ UNUSED(p_DumpToken); \ -+ UNUSED(dumpArrIdx); \ -+ UNUSED(dumpArrSize); \ -+ UNUSED(dumpLevel); \ -+ UNUSED(dumpTmpLevel); \ -+ UNUSED(dumpIsArr[0]); -+ -+ -+/**************************************************************************//** -+ @Description Prints a title for a subsequent dumped structure or memory. -+ -+ The inputs for this macro are the structure/memory title and -+ its base addresses. -+*//***************************************************************************/ -+#define DUMP_TITLE(addr, msg) \ -+ DUMP_Print("\r\n"); DUMP_Print msg; \ -+ if (addr) \ -+ DUMP_Print(" (%p)", (addr)); \ -+ DUMP_Print("\r\n---------------------------------------------------------\r\n"); -+ -+/**************************************************************************//** -+ @Description Prints a subtitle for a subsequent dumped sub-structure (optional). -+ -+ The inputs for this macro are the sub-structure subtitle. -+ A separating line with this subtitle will be printed. -+*//***************************************************************************/ -+#define DUMP_SUBTITLE(subtitle) \ -+ DUMP_Print("----------- "); DUMP_Print subtitle; DUMP_Print("\r\n") -+ -+ -+/**************************************************************************//** -+ @Description Dumps a memory region in 4-bytes aligned format. -+ -+ The inputs for this macro are the base addresses and size -+ (in bytes) of the memory region. -+*//***************************************************************************/ -+#define DUMP_MEMORY(addr, size) \ -+ MemDisp((uint8_t *)(addr), (int)(size)) -+ -+ -+/**************************************************************************//** -+ @Description Declares a dump loop, for dumping a sub-structure array. -+ -+ The inputs for this macro are: -+ - idx: an index variable, for indexing the sub-structure items -+ inside the loop. This variable must be declared separately -+ in the beginning of the routine. -+ - cnt: the number of times to repeat the loop. This number should -+ equal the number of items in the sub-structures array. -+ -+ Note, that the body of the loop must be written inside brackets. -+*//***************************************************************************/ -+#define DUMP_SUBSTRUCT_ARRAY(idx, cnt) \ -+ for (idx=0, dumpIsArr[dumpLevel++] = 1; \ -+ (idx < cnt) && (dumpLevel > 0) && snprintf(dumpIdxStr[dumpLevel-1], DUMP_IDX_LEN, "[%d]", idx); \ -+ idx++, ((idx < cnt) || (dumpIsArr[--dumpLevel] = 0))) -+ -+ -+/**************************************************************************//** -+ @Description Dumps a structure's member variable. -+ -+ The input for this macro is the full reference for the member -+ variable, where the structure is referenced using a pointer. -+ -+ Note, that a members array must be dumped using DUMP_ARR macro, -+ rather than using this macro. -+ -+ If the member variable is part of a sub-structure hierarchy, -+ the full hierarchy (including array indexing) must be specified. -+ -+ Examples: p_Struct->member -+ p_Struct->sub.member -+ p_Struct->sub[i].member -+*//***************************************************************************/ -+#define DUMP_VAR(st, phrase) \ -+ do { \ -+ void *addr = (void *)&((st)->phrase); \ -+ physAddress_t physAddr = XX_VirtToPhys(addr); \ -+ _CREATE_DUMP_SUBSTR(phrase); \ -+ DUMP_Print("0x%010llX: 0x%08x%8s\t%s\r\n", \ -+ physAddr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); \ -+ } while (0) -+ -+ -+/**************************************************************************//** -+ @Description Dumps a structure's members array. -+ -+ The input for this macro is the full reference for the members -+ array, where the structure is referenced using a pointer. -+ -+ If the members array is part of a sub-structure hierarchy, -+ the full hierarchy (including array indexing) must be specified. -+ -+ Examples: p_Struct->array -+ p_Struct->sub.array -+ p_Struct->sub[i].array -+*//***************************************************************************/ -+#define DUMP_ARR(st, phrase) \ -+ do { \ -+ physAddress_t physAddr; \ -+ _CREATE_DUMP_SUBSTR(phrase); \ -+ dumpArrSize = ARRAY_SIZE((st)->phrase); \ -+ for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \ -+ physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \ -+ DUMP_Print("0x%010llX: 0x%08x%8s\t%s[%d]\r\n", \ -+ physAddr, GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \ -+ } \ -+ } while (0) -+ -+ -+ -+#endif /* DEBUG_ERRORS > 0 */ -+ -+ -+/** @} */ /* end of dump_id group */ -+/** @} */ /* end of gen_id group */ -+ -+ -+#endif /* __DEBUG_EXT_H */ -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h -@@ -0,0 +1,447 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ -+ @File endian_ext.h -+ -+ @Description Big/little endian swapping routines. -+*//***************************************************************************/ -+ -+#ifndef __ENDIAN_EXT_H -+#define __ENDIAN_EXT_H -+ -+#include "std_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group gen_id General Drivers Utilities -+ -+ @Description General usage API. This API is intended for usage by both the -+ internal modules and the user's application. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group endian_id Big/Little-Endian Conversion -+ -+ @Description Routines and macros for Big/Little-Endian conversion and -+ general byte swapping. -+ -+ All routines and macros are expecting unsigned values as -+ parameters, but will generate the correct result also for -+ signed values. Therefore, signed/unsigned casting is allowed. -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Collection Byte-Swap Macros -+ -+ Macros for swapping byte order. -+ -+ @Cautions The parameters of these macros are evaluated multiple times. -+ For calculated expressions or expressions that contain function -+ calls it is recommended to use the byte-swap routines. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description Swaps the byte order of a given 16-bit value. -+ -+ @Param[in] val - The 16-bit value to swap. -+ -+ @Return The byte-swapped value.. -+ -+ @Cautions The given value is evaluated multiple times by this macro. -+ For calculated expressions or expressions that contain function -+ calls it is recommended to use the SwapUint16() routine. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define SWAP_UINT16(val) \ -+ ((uint16_t)((((val) & 0x00FF) << 8) | (((val) & 0xFF00) >> 8))) -+ -+/**************************************************************************//** -+ @Description Swaps the byte order of a given 32-bit value. -+ -+ @Param[in] val - The 32-bit value to swap. -+ -+ @Return The byte-swapped value.. -+ -+ @Cautions The given value is evaluated multiple times by this macro. -+ For calculated expressions or expressions that contain function -+ calls it is recommended to use the SwapUint32() routine. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define SWAP_UINT32(val) \ -+ ((uint32_t)((((val) & 0x000000FF) << 24) | \ -+ (((val) & 0x0000FF00) << 8) | \ -+ (((val) & 0x00FF0000) >> 8) | \ -+ (((val) & 0xFF000000) >> 24))) -+ -+/**************************************************************************//** -+ @Description Swaps the byte order of a given 64-bit value. -+ -+ @Param[in] val - The 64-bit value to swap. -+ -+ @Return The byte-swapped value.. -+ -+ @Cautions The given value is evaluated multiple times by this macro. -+ For calculated expressions or expressions that contain function -+ calls it is recommended to use the SwapUint64() routine. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define SWAP_UINT64(val) \ -+ ((uint64_t)((((val) & 0x00000000000000FFULL) << 56) | \ -+ (((val) & 0x000000000000FF00ULL) << 40) | \ -+ (((val) & 0x0000000000FF0000ULL) << 24) | \ -+ (((val) & 0x00000000FF000000ULL) << 8) | \ -+ (((val) & 0x000000FF00000000ULL) >> 8) | \ -+ (((val) & 0x0000FF0000000000ULL) >> 24) | \ -+ (((val) & 0x00FF000000000000ULL) >> 40) | \ -+ (((val) & 0xFF00000000000000ULL) >> 56))) -+ -+/* @} */ -+ -+/**************************************************************************//** -+ @Collection Byte-Swap Routines -+ -+ Routines for swapping the byte order of a given parameter and -+ returning the swapped value. -+ -+ These inline routines are safer than the byte-swap macros, -+ because they evaluate the parameter expression only once. -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function SwapUint16 -+ -+ @Description Returns the byte-swapped value of a given 16-bit value. -+ -+ @Param[in] val - The 16-bit value. -+ -+ @Return The byte-swapped value of the parameter. -+*//***************************************************************************/ -+static __inline__ uint16_t SwapUint16(uint16_t val) -+{ -+ return (uint16_t)(((val & 0x00FF) << 8) | -+ ((val & 0xFF00) >> 8)); -+} -+ -+/**************************************************************************//** -+ @Function SwapUint32 -+ -+ @Description Returns the byte-swapped value of a given 32-bit value. -+ -+ @Param[in] val - The 32-bit value. -+ -+ @Return The byte-swapped value of the parameter. -+*//***************************************************************************/ -+static __inline__ uint32_t SwapUint32(uint32_t val) -+{ -+ return (uint32_t)(((val & 0x000000FF) << 24) | -+ ((val & 0x0000FF00) << 8) | -+ ((val & 0x00FF0000) >> 8) | -+ ((val & 0xFF000000) >> 24)); -+} -+ -+/**************************************************************************//** -+ @Function SwapUint64 -+ -+ @Description Returns the byte-swapped value of a given 64-bit value. -+ -+ @Param[in] val - The 64-bit value. -+ -+ @Return The byte-swapped value of the parameter. -+*//***************************************************************************/ -+static __inline__ uint64_t SwapUint64(uint64_t val) -+{ -+ return (uint64_t)(((val & 0x00000000000000FFULL) << 56) | -+ ((val & 0x000000000000FF00ULL) << 40) | -+ ((val & 0x0000000000FF0000ULL) << 24) | -+ ((val & 0x00000000FF000000ULL) << 8) | -+ ((val & 0x000000FF00000000ULL) >> 8) | -+ ((val & 0x0000FF0000000000ULL) >> 24) | -+ ((val & 0x00FF000000000000ULL) >> 40) | -+ ((val & 0xFF00000000000000ULL) >> 56)); -+} -+ -+/* @} */ -+ -+/**************************************************************************//** -+ @Collection In-place Byte-Swap-And-Set Routines -+ -+ Routines for swapping the byte order of a given variable and -+ setting the swapped value back to the same variable. -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function SwapUint16P -+ -+ @Description Swaps the byte order of a given 16-bit variable. -+ -+ @Param[in] p_Val - Pointer to the 16-bit variable. -+ -+ @Return None. -+*//***************************************************************************/ -+static __inline__ void SwapUint16P(uint16_t *p_Val) -+{ -+ *p_Val = SwapUint16(*p_Val); -+} -+ -+/**************************************************************************//** -+ @Function SwapUint32P -+ -+ @Description Swaps the byte order of a given 32-bit variable. -+ -+ @Param[in] p_Val - Pointer to the 32-bit variable. -+ -+ @Return None. -+*//***************************************************************************/ -+static __inline__ void SwapUint32P(uint32_t *p_Val) -+{ -+ *p_Val = SwapUint32(*p_Val); -+} -+ -+/**************************************************************************//** -+ @Function SwapUint64P -+ -+ @Description Swaps the byte order of a given 64-bit variable. -+ -+ @Param[in] p_Val - Pointer to the 64-bit variable. -+ -+ @Return None. -+*//***************************************************************************/ -+static __inline__ void SwapUint64P(uint64_t *p_Val) -+{ -+ *p_Val = SwapUint64(*p_Val); -+} -+ -+/* @} */ -+ -+ -+/**************************************************************************//** -+ @Collection Little-Endian Conversion Macros -+ -+ These macros convert given parameters to or from Little-Endian -+ format. Use these macros when you want to read or write a specific -+ Little-Endian value in memory, without a-priori knowing the CPU -+ byte order. -+ -+ These macros use the byte-swap routines. For conversion of -+ constants in initialization structures, you may use the CONST -+ versions of these macros (see below), which are using the -+ byte-swap macros instead. -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description Converts a given 16-bit value from CPU byte order to -+ Little-Endian byte order. -+ -+ @Param[in] val - The 16-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define CPU_TO_LE16(val) SwapUint16(val) -+ -+/**************************************************************************//** -+ @Description Converts a given 32-bit value from CPU byte order to -+ Little-Endian byte order. -+ -+ @Param[in] val - The 32-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define CPU_TO_LE32(val) SwapUint32(val) -+ -+/**************************************************************************//** -+ @Description Converts a given 64-bit value from CPU byte order to -+ Little-Endian byte order. -+ -+ @Param[in] val - The 64-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define CPU_TO_LE64(val) SwapUint64(val) -+ -+ -+/**************************************************************************//** -+ @Description Converts a given 16-bit value from Little-Endian byte order to -+ CPU byte order. -+ -+ @Param[in] val - The 16-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define LE16_TO_CPU(val) CPU_TO_LE16(val) -+ -+/**************************************************************************//** -+ @Description Converts a given 32-bit value from Little-Endian byte order to -+ CPU byte order. -+ -+ @Param[in] val - The 32-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define LE32_TO_CPU(val) CPU_TO_LE32(val) -+ -+/**************************************************************************//** -+ @Description Converts a given 64-bit value from Little-Endian byte order to -+ CPU byte order. -+ -+ @Param[in] val - The 64-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define LE64_TO_CPU(val) CPU_TO_LE64(val) -+ -+/* @} */ -+ -+/**************************************************************************//** -+ @Collection Little-Endian Constant Conversion Macros -+ -+ These macros convert given constants to or from Little-Endian -+ format. Use these macros when you want to read or write a specific -+ Little-Endian constant in memory, without a-priori knowing the -+ CPU byte order. -+ -+ These macros use the byte-swap macros, therefore can be used for -+ conversion of constants in initialization structures. -+ -+ @Cautions The parameters of these macros are evaluated multiple times. -+ For non-constant expressions, use the non-CONST macro versions. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description Converts a given 16-bit constant from CPU byte order to -+ Little-Endian byte order. -+ -+ @Param[in] val - The 16-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define CONST_CPU_TO_LE16(val) SWAP_UINT16(val) -+ -+/**************************************************************************//** -+ @Description Converts a given 32-bit constant from CPU byte order to -+ Little-Endian byte order. -+ -+ @Param[in] val - The 32-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define CONST_CPU_TO_LE32(val) SWAP_UINT32(val) -+ -+/**************************************************************************//** -+ @Description Converts a given 64-bit constant from CPU byte order to -+ Little-Endian byte order. -+ -+ @Param[in] val - The 64-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define CONST_CPU_TO_LE64(val) SWAP_UINT64(val) -+ -+ -+/**************************************************************************//** -+ @Description Converts a given 16-bit constant from Little-Endian byte order -+ to CPU byte order. -+ -+ @Param[in] val - The 16-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define CONST_LE16_TO_CPU(val) CONST_CPU_TO_LE16(val) -+ -+/**************************************************************************//** -+ @Description Converts a given 32-bit constant from Little-Endian byte order -+ to CPU byte order. -+ -+ @Param[in] val - The 32-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define CONST_LE32_TO_CPU(val) CONST_CPU_TO_LE32(val) -+ -+/**************************************************************************//** -+ @Description Converts a given 64-bit constant from Little-Endian byte order -+ to CPU byte order. -+ -+ @Param[in] val - The 64-bit value to convert. -+ -+ @Return The converted value. -+ -+ @hideinitializer -+*//***************************************************************************/ -+#define CONST_LE64_TO_CPU(val) CONST_CPU_TO_LE64(val) -+ -+/* @} */ -+ -+ -+/** @} */ /* end of endian_id group */ -+/** @} */ /* end of gen_id group */ -+ -+ -+#endif /* __ENDIAN_EXT_H */ -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h -@@ -0,0 +1,205 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File enet_ext.h -+ -+ @Description Ethernet generic definitions and enums. -+*//***************************************************************************/ -+ -+#ifndef __ENET_EXT_H -+#define __ENET_EXT_H -+ -+#include "fsl_enet.h" -+ -+#define ENET_NUM_OCTETS_PER_ADDRESS 6 /**< Number of octets (8-bit bytes) in an ethernet address */ -+#define ENET_GROUP_ADDR 0x01 /**< Group address mask for ethernet addresses */ -+ -+ -+/**************************************************************************//** -+ @Description Ethernet Address -+*//***************************************************************************/ -+typedef uint8_t t_EnetAddr[ENET_NUM_OCTETS_PER_ADDRESS]; -+ -+/**************************************************************************//** -+ @Description Ethernet Address Type. -+*//***************************************************************************/ -+typedef enum e_EnetAddrType -+{ -+ e_ENET_ADDR_TYPE_INDIVIDUAL, /**< Individual (unicast) address */ -+ e_ENET_ADDR_TYPE_GROUP, /**< Group (multicast) address */ -+ e_ENET_ADDR_TYPE_BROADCAST /**< Broadcast address */ -+} e_EnetAddrType; -+ -+/**************************************************************************//** -+ @Description Ethernet MAC-PHY Interface -+*//***************************************************************************/ -+typedef enum e_EnetInterface -+{ -+ e_ENET_IF_MII = E_ENET_IF_MII, /**< MII interface */ -+ e_ENET_IF_RMII = E_ENET_IF_RMII, /**< RMII interface */ -+ e_ENET_IF_SMII = E_ENET_IF_SMII, /**< SMII interface */ -+ e_ENET_IF_GMII = E_ENET_IF_GMII, /**< GMII interface */ -+ e_ENET_IF_RGMII = E_ENET_IF_RGMII, /**< RGMII interface */ -+ e_ENET_IF_TBI = E_ENET_IF_TBI, /**< TBI interface */ -+ e_ENET_IF_RTBI = E_ENET_IF_RTBI, /**< RTBI interface */ -+ e_ENET_IF_SGMII = E_ENET_IF_SGMII, /**< SGMII interface */ -+ e_ENET_IF_XGMII = E_ENET_IF_XGMII, /**< XGMII interface */ -+ e_ENET_IF_QSGMII= E_ENET_IF_QSGMII, /**< QSGMII interface */ -+ e_ENET_IF_XFI = E_ENET_IF_XFI /**< XFI interface */ -+} e_EnetInterface; -+ -+#define ENET_IF_SGMII_BASEX 0x80000000 /**< SGMII/QSGII interface with 1000BaseX -+ auto-negotiation between MAC and phy -+ or backplane; -+ Note: 1000BaseX auto-negotiation relates -+ only to interface between MAC and phy/backplane, -+ SGMII phy can still synchronize with far-end phy -+ at 10Mbps, 100Mbps or 1000Mbps */ -+ -+/**************************************************************************//** -+ @Description Ethernet Duplex Mode -+*//***************************************************************************/ -+typedef enum e_EnetDuplexMode -+{ -+ e_ENET_HALF_DUPLEX, /**< Half-Duplex mode */ -+ e_ENET_FULL_DUPLEX /**< Full-Duplex mode */ -+} e_EnetDuplexMode; -+ -+/**************************************************************************//** -+ @Description Ethernet Speed (nominal data rate) -+*//***************************************************************************/ -+typedef enum e_EnetSpeed -+{ -+ e_ENET_SPEED_10 = E_ENET_SPEED_10, /**< 10 Mbps */ -+ e_ENET_SPEED_100 = E_ENET_SPEED_100, /**< 100 Mbps */ -+ e_ENET_SPEED_1000 = E_ENET_SPEED_1000, /**< 1000 Mbps = 1 Gbps */ -+ e_ENET_SPEED_2500 = E_ENET_SPEED_2500, /**< 2500 Mbps = 2.5 Gbps */ -+ e_ENET_SPEED_10000 = E_ENET_SPEED_10000 /**< 10000 Mbps = 10 Gbps */ -+} e_EnetSpeed; -+ -+/**************************************************************************//** -+ @Description Ethernet mode (combination of MAC-PHY interface and speed) -+*//***************************************************************************/ -+typedef enum e_EnetMode -+{ -+ e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */ -+ e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */ -+ e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */ -+ e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */ -+ e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */ -+ e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */ -+ e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */ -+ e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */ -+ e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */ -+ e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */ -+ e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */ -+ e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */ -+ e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */ -+ e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10), -+ /**< 10 Mbps SGMII with auto-negotiation between MAC and -+ SGMII phy according to Cisco SGMII specification */ -+ e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100), -+ /**< 100 Mbps SGMII with auto-negotiation between MAC and -+ SGMII phy according to Cisco SGMII specification */ -+ e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000), -+ /**< 1000 Mbps SGMII with auto-negotiation between MAC and -+ SGMII phy according to Cisco SGMII specification */ -+ e_ENET_MODE_SGMII_2500 = (e_ENET_IF_SGMII | e_ENET_SPEED_2500), -+ e_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_10), -+ /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between -+ MAC and SGMII phy or backplane */ -+ e_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_100), -+ /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between -+ MAC and SGMII phy or backplane */ -+ e_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_1000), -+ /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between -+ MAC and SGMII phy or backplane */ -+ e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000), -+ /**< 1000 Mbps QSGMII with auto-negotiation between MAC and -+ QSGMII phy according to Cisco QSGMII specification */ -+ e_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_QSGMII| e_ENET_SPEED_1000), -+ /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between -+ MAC and QSGMII phy or backplane */ -+ e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */ -+ e_ENET_MODE_XFI_10000 = (e_ENET_IF_XFI | e_ENET_SPEED_10000) /**< 10000 Mbps XFI */ -+} e_EnetMode; -+ -+ -+#define IS_ENET_MODE_VALID(mode) \ -+ (((mode) == e_ENET_MODE_MII_10 ) || \ -+ ((mode) == e_ENET_MODE_MII_100 ) || \ -+ ((mode) == e_ENET_MODE_RMII_10 ) || \ -+ ((mode) == e_ENET_MODE_RMII_100 ) || \ -+ ((mode) == e_ENET_MODE_SMII_10 ) || \ -+ ((mode) == e_ENET_MODE_SMII_100 ) || \ -+ ((mode) == e_ENET_MODE_GMII_1000 ) || \ -+ ((mode) == e_ENET_MODE_RGMII_10 ) || \ -+ ((mode) == e_ENET_MODE_RGMII_100 ) || \ -+ ((mode) == e_ENET_MODE_RGMII_1000 ) || \ -+ ((mode) == e_ENET_MODE_TBI_1000 ) || \ -+ ((mode) == e_ENET_MODE_RTBI_1000 ) || \ -+ ((mode) == e_ENET_MODE_SGMII_10 ) || \ -+ ((mode) == e_ENET_MODE_SGMII_100 ) || \ -+ ((mode) == e_ENET_MODE_SGMII_1000 ) || \ -+ ((mode) == e_ENET_MODE_SGMII_BASEX_10 ) || \ -+ ((mode) == e_ENET_MODE_SGMII_BASEX_100 ) || \ -+ ((mode) == e_ENET_MODE_SGMII_BASEX_1000 ) || \ -+ ((mode) == e_ENET_MODE_XGMII_10000) || \ -+ ((mode) == e_ENET_MODE_QSGMII_1000) || \ -+ ((mode) == e_ENET_MODE_QSGMII_BASEX_1000) || \ -+ ((mode) == e_ENET_MODE_XFI_10000)) -+ -+ -+#define MAKE_ENET_MODE(_interface, _speed) (e_EnetMode)((_interface) | (_speed)) -+ -+#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0x0FFF0000) -+#define ENET_SPEED_FROM_MODE(mode) (e_EnetSpeed)((mode) & 0x0000FFFF) -+ -+#define ENET_ADDR_TO_UINT64(_enetAddr) \ -+ (uint64_t)(((uint64_t)(_enetAddr)[0] << 40) | \ -+ ((uint64_t)(_enetAddr)[1] << 32) | \ -+ ((uint64_t)(_enetAddr)[2] << 24) | \ -+ ((uint64_t)(_enetAddr)[3] << 16) | \ -+ ((uint64_t)(_enetAddr)[4] << 8) | \ -+ ((uint64_t)(_enetAddr)[5])) -+ -+#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enetAddr) \ -+ do { \ -+ int i; \ -+ for (i=0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \ -+ (_enetAddr)[i] = (uint8_t)((_addr64) >> ((5-i)*8)); \ -+ } while (0) -+ -+ -+#endif /* __ENET_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h -@@ -0,0 +1,529 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File error_ext.h -+ -+ @Description Error definitions. -+*//***************************************************************************/ -+ -+#ifndef __ERROR_EXT_H -+#define __ERROR_EXT_H -+ -+#if !defined(NCSW_LINUX) -+#include -+#endif -+ -+#include "std_ext.h" -+#include "xx_ext.h" -+#include "core_ext.h" -+ -+ -+ -+ -+/**************************************************************************//** -+ @Group gen_id General Drivers Utilities -+ -+ @Description External routines. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group gen_error_id Errors, Events and Debug -+ -+ @Description External routines. -+ -+ @{ -+*//***************************************************************************/ -+ -+/****************************************************************************** -+The scheme below provides the bits description for error codes: -+ -+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -+| Reserved (should be zero) | Module ID | -+ -+ 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 -+| Error Type | -+******************************************************************************/ -+ -+#define ERROR_CODE(_err) ((((uint32_t)_err) & 0x0000FFFF) | __ERR_MODULE__) -+ -+#define GET_ERROR_TYPE(_errcode) ((_errcode) & 0x0000FFFF) -+ /**< Extract module code from error code (#t_Error) */ -+ -+#define GET_ERROR_MODULE(_errcode) ((_errcode) & 0x00FF0000) -+ /**< Extract error type (#e_ErrorType) from -+ error code (#t_Error) */ -+ -+ -+/**************************************************************************//** -+ @Description Error Type Enumeration -+*//***************************************************************************/ -+typedef enum e_ErrorType /* Comments / Associated Message Strings */ -+{ /* ------------------------------------------------------------ */ -+ E_OK = 0 /* Never use "RETURN_ERROR" with E_OK; Use "return E_OK;" */ -+ ,E_WRITE_FAILED = EIO /**< Write access failed on memory/device. */ -+ /* String: none, or device name. */ -+ ,E_NO_DEVICE = ENXIO /**< The associated device is not initialized. */ -+ /* String: none. */ -+ ,E_NOT_AVAILABLE = EAGAIN -+ /**< Resource is unavailable. */ -+ /* String: none, unless the operation is not the main goal -+ of the function (in this case add resource description). */ -+ ,E_NO_MEMORY = ENOMEM /**< External memory allocation failed. */ -+ /* String: description of item for which allocation failed. */ -+ ,E_INVALID_ADDRESS = EFAULT -+ /**< Invalid address. */ -+ /* String: description of the specific violation. */ -+ ,E_BUSY = EBUSY /**< Resource or module is busy. */ -+ /* String: none, unless the operation is not the main goal -+ of the function (in this case add resource description). */ -+ ,E_ALREADY_EXISTS = EEXIST -+ /**< Requested resource or item already exists. */ -+ /* Use when resource duplication or sharing are not allowed. -+ String: none, unless the operation is not the main goal -+ of the function (in this case add item description). */ -+ ,E_INVALID_OPERATION = ENODEV -+ /**< The operation/command is invalid (unrecognized). */ -+ /* String: none. */ -+ ,E_INVALID_VALUE = EDOM /**< Invalid value. */ -+ /* Use for non-enumeration parameters, and -+ only when other error types are not suitable. -+ String: parameter description + "(should be )", -+ e.g: "Maximum Rx buffer length (should be divisible by 8)", -+ "Channel number (should be even)". */ -+ ,E_NOT_IN_RANGE = ERANGE/**< Parameter value is out of range. */ -+ /* Don't use this error for enumeration parameters. -+ String: parameter description + "(should be %d-%d)", -+ e.g: "Number of pad characters (should be 0-15)". */ -+ ,E_NOT_SUPPORTED = ENOSYS -+ /**< The function is not supported or not implemented. */ -+ /* String: none. */ -+ ,E_INVALID_STATE /**< The operation is not allowed in current module state. */ -+ /* String: none. */ -+ ,E_INVALID_HANDLE /**< Invalid handle of module or object. */ -+ /* String: none, unless the function takes in more than one -+ handle (in this case add the handle description) */ -+ ,E_INVALID_ID /**< Invalid module ID (usually enumeration or index). */ -+ /* String: none, unless the function takes in more than one -+ ID (in this case add the ID description) */ -+ ,E_NULL_POINTER /**< Unexpected NULL pointer. */ -+ /* String: pointer description. */ -+ ,E_INVALID_SELECTION /**< Invalid selection or mode. */ -+ /* Use for enumeration values, only when other error types -+ are not suitable. -+ String: parameter description. */ -+ ,E_INVALID_COMM_MODE /**< Invalid communication mode. */ -+ /* String: none, unless the function takes in more than one -+ communication mode indications (in this case add -+ parameter description). */ -+ ,E_INVALID_MEMORY_TYPE /**< Invalid memory type. */ -+ /* String: none, unless the function takes in more than one -+ memory types (in this case add memory description, -+ e.g: "Data memory", "Buffer descriptors memory"). */ -+ ,E_INVALID_CLOCK /**< Invalid clock. */ -+ /* String: none, unless the function takes in more than one -+ clocks (in this case add clock description, -+ e.g: "Rx clock", "Tx clock"). */ -+ ,E_CONFLICT /**< Some setting conflicts with another setting. */ -+ /* String: description of the conflicting settings. */ -+ ,E_NOT_ALIGNED /**< Non-aligned address. */ -+ /* String: parameter description + "(should be %d-bytes aligned)", -+ e.g: "Rx data buffer (should be 32-bytes aligned)". */ -+ ,E_NOT_FOUND /**< Requested resource or item was not found. */ -+ /* Use only when the resource/item is uniquely identified. -+ String: none, unless the operation is not the main goal -+ of the function (in this case add item description). */ -+ ,E_FULL /**< Resource is full. */ -+ /* String: none, unless the operation is not the main goal -+ of the function (in this case add resource description). */ -+ ,E_EMPTY /**< Resource is empty. */ -+ /* String: none, unless the operation is not the main goal -+ of the function (in this case add resource description). */ -+ ,E_ALREADY_FREE /**< Specified resource or item is already free or deleted. */ -+ /* String: none, unless the operation is not the main goal -+ of the function (in this case add item description). */ -+ ,E_READ_FAILED /**< Read access failed on memory/device. */ -+ /* String: none, or device name. */ -+ ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */ -+ /* String: none. */ -+ ,E_SEND_FAILED /**< Send operation failed on device. */ -+ /* String: none, or device name. */ -+ ,E_RECEIVE_FAILED /**< Receive operation failed on device. */ -+ /* String: none, or device name. */ -+ ,E_TIMEOUT/* = ETIMEDOUT*/ /**< The operation timed out. */ -+ /* String: none. */ -+ -+ ,E_DUMMY_LAST /* NEVER USED */ -+ -+} e_ErrorType; -+ -+/**************************************************************************//** -+ @Description Event Type Enumeration -+*//***************************************************************************/ -+typedef enum e_Event /* Comments / Associated Flags and Message Strings */ -+{ /* ------------------------------------------------------------ */ -+ EV_NO_EVENT = 0 /**< No event; Never used. */ -+ -+ ,EV_RX_DISCARD /**< Received packet discarded (by the driver, and only for -+ complete packets); -+ Flags: error flags in case of error, zero otherwise. */ -+ /* String: reason for discard, e.g: "Error in frame", -+ "Disordered frame", "Incomplete frame", "No frame object". */ -+ ,EV_RX_ERROR /**< Receive error (by hardware/firmware); -+ Flags: usually status flags from the buffer descriptor. */ -+ /* String: none. */ -+ ,EV_TX_ERROR /**< Transmit error (by hardware/firmware); -+ Flags: usually status flags from the buffer descriptor. */ -+ /* String: none. */ -+ ,EV_NO_BUFFERS /**< System ran out of buffer objects; -+ Flags: zero. */ -+ /* String: none. */ -+ ,EV_NO_MB_FRAMES /**< System ran out of multi-buffer frame objects; -+ Flags: zero. */ -+ /* String: none. */ -+ ,EV_NO_SB_FRAMES /**< System ran out of single-buffer frame objects; -+ Flags: zero. */ -+ /* String: none. */ -+ ,EV_TX_QUEUE_FULL /**< Transmit queue is full; -+ Flags: zero. */ -+ /* String: none. */ -+ ,EV_RX_QUEUE_FULL /**< Receive queue is full; -+ Flags: zero. */ -+ /* String: none. */ -+ ,EV_INTR_QUEUE_FULL /**< Interrupt queue overflow; -+ Flags: zero. */ -+ /* String: none. */ -+ ,EV_NO_DATA_BUFFER /**< Data buffer allocation (from higher layer) failed; -+ Flags: zero. */ -+ /* String: none. */ -+ ,EV_OBJ_POOL_EMPTY /**< Objects pool is empty; -+ Flags: zero. */ -+ /* String: object description (name). */ -+ ,EV_BUS_ERROR /**< Illegal access on bus; -+ Flags: the address (if available) or bus identifier */ -+ /* String: bus/address/module description. */ -+ ,EV_PTP_TXTS_QUEUE_FULL /**< PTP Tx timestamps queue is full; -+ Flags: zero. */ -+ /* String: none. */ -+ ,EV_PTP_RXTS_QUEUE_FULL /**< PTP Rx timestamps queue is full; -+ Flags: zero. */ -+ /* String: none. */ -+ ,EV_DUMMY_LAST -+ -+} e_Event; -+ -+ -+/**************************************************************************//** -+ @Collection Debug Levels for Errors and Events -+ -+ The level description refers to errors only. -+ For events, classification is done by the user. -+ -+ The TRACE, INFO and WARNING levels are allowed only when using -+ the DBG macro, and are not allowed when using the error macros -+ (RETURN_ERROR or REPORT_ERROR). -+ @{ -+*//***************************************************************************/ -+#define REPORT_LEVEL_CRITICAL 1 /**< Crasher: Incorrect flow, NULL pointers/handles. */ -+#define REPORT_LEVEL_MAJOR 2 /**< Cannot proceed: Invalid operation, parameters or -+ configuration. */ -+#define REPORT_LEVEL_MINOR 3 /**< Recoverable problem: a repeating call with the same -+ parameters may be successful. */ -+#define REPORT_LEVEL_WARNING 4 /**< Something is not exactly right, yet it is not an error. */ -+#define REPORT_LEVEL_INFO 5 /**< Messages which may be of interest to user/programmer. */ -+#define REPORT_LEVEL_TRACE 6 /**< Program flow messages. */ -+ -+#define EVENT_DISABLED 0xFF /**< Disabled event (not reported at all) */ -+ -+/* @} */ -+ -+ -+ -+#define NO_MSG ("") -+ -+#ifndef DEBUG_GLOBAL_LEVEL -+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING -+#endif /* DEBUG_GLOBAL_LEVEL */ -+ -+#ifndef ERROR_GLOBAL_LEVEL -+#define ERROR_GLOBAL_LEVEL DEBUG_GLOBAL_LEVEL -+#endif /* ERROR_GLOBAL_LEVEL */ -+ -+#ifndef EVENT_GLOBAL_LEVEL -+#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR -+#endif /* EVENT_GLOBAL_LEVEL */ -+ -+#ifdef EVENT_LOCAL_LEVEL -+#define EVENT_DYNAMIC_LEVEL EVENT_LOCAL_LEVEL -+#else -+#define EVENT_DYNAMIC_LEVEL EVENT_GLOBAL_LEVEL -+#endif /* EVENT_LOCAL_LEVEL */ -+ -+ -+#ifndef DEBUG_DYNAMIC_LEVEL -+#define DEBUG_USING_STATIC_LEVEL -+ -+#ifdef DEBUG_STATIC_LEVEL -+#define DEBUG_DYNAMIC_LEVEL DEBUG_STATIC_LEVEL -+#else -+#define DEBUG_DYNAMIC_LEVEL DEBUG_GLOBAL_LEVEL -+#endif /* DEBUG_STATIC_LEVEL */ -+ -+#else /* DEBUG_DYNAMIC_LEVEL */ -+#ifdef DEBUG_STATIC_LEVEL -+#error "Please use either DEBUG_STATIC_LEVEL or DEBUG_DYNAMIC_LEVEL (not both)" -+#else -+int DEBUG_DYNAMIC_LEVEL = DEBUG_GLOBAL_LEVEL; -+#endif /* DEBUG_STATIC_LEVEL */ -+#endif /* !DEBUG_DYNAMIC_LEVEL */ -+ -+ -+#ifndef ERROR_DYNAMIC_LEVEL -+ -+#ifdef ERROR_STATIC_LEVEL -+#define ERROR_DYNAMIC_LEVEL ERROR_STATIC_LEVEL -+#else -+#define ERROR_DYNAMIC_LEVEL ERROR_GLOBAL_LEVEL -+#endif /* ERROR_STATIC_LEVEL */ -+ -+#else /* ERROR_DYNAMIC_LEVEL */ -+#ifdef ERROR_STATIC_LEVEL -+#error "Please use either ERROR_STATIC_LEVEL or ERROR_DYNAMIC_LEVEL (not both)" -+#else -+int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL; -+#endif /* ERROR_STATIC_LEVEL */ -+#endif /* !ERROR_DYNAMIC_LEVEL */ -+ -+#define PRINT_FORMAT "[CPU%02d, %s:%d %s]" -+#define PRINT_FMT_PARAMS raw_smp_processor_id(), __FILE__, __LINE__, __FUNCTION__ -+ -+#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) -+/* No debug/error/event messages at all */ -+#define DBG(_level, _vmsg) -+ -+#define REPORT_ERROR(_level, _err, _vmsg) -+ -+#define RETURN_ERROR(_level, _err, _vmsg) \ -+ return ERROR_CODE(_err) -+ -+#if (REPORT_EVENTS > 0) -+ -+#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \ -+ do { \ -+ if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \ -+ XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \ -+ } \ -+ } while (0) -+ -+#else -+ -+#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) -+ -+#endif /* (REPORT_EVENTS > 0) */ -+ -+ -+#else /* DEBUG_ERRORS > 0 */ -+ -+extern const char *dbgLevelStrings[]; -+extern const char *moduleStrings[]; -+#if (REPORT_EVENTS > 0) -+extern const char *eventStrings[]; -+#endif /* (REPORT_EVENTS > 0) */ -+ -+char * ErrTypeStrings (e_ErrorType err); -+ -+ -+#if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING)) -+/* No need for DBG macro - debug level is higher anyway */ -+#define DBG(_level, _vmsg) -+#else -+#define DBG(_level, _vmsg) \ -+ do { \ -+ if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \ -+ XX_Print("> %s (%s) " PRINT_FORMAT ": ", \ -+ dbgLevelStrings[REPORT_LEVEL_##_level - 1], \ -+ moduleStrings[__ERR_MODULE__ >> 16], \ -+ PRINT_FMT_PARAMS); \ -+ XX_Print _vmsg; \ -+ XX_Print("\r\n"); \ -+ } \ -+ } while (0) -+#endif /* (defined(DEBUG_USING_STATIC_LEVEL) && (DEBUG_DYNAMIC_LEVEL < WARNING)) */ -+ -+ -+#define REPORT_ERROR(_level, _err, _vmsg) \ -+ do { \ -+ if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \ -+ XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \ -+ dbgLevelStrings[REPORT_LEVEL_##_level - 1], \ -+ moduleStrings[__ERR_MODULE__ >> 16], \ -+ PRINT_FMT_PARAMS, \ -+ ErrTypeStrings((e_ErrorType)GET_ERROR_TYPE(_err))); \ -+ XX_Print _vmsg; \ -+ XX_Print("\r\n"); \ -+ } \ -+ } while (0) -+ -+ -+#define RETURN_ERROR(_level, _err, _vmsg) \ -+ do { \ -+ REPORT_ERROR(_level, (_err), _vmsg); \ -+ return ERROR_CODE(_err); \ -+ } while (0) -+ -+ -+#if (REPORT_EVENTS > 0) -+ -+#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \ -+ do { \ -+ if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \ -+ XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \ -+ dbgLevelStrings[_ev##_LEVEL - 1], \ -+ moduleStrings[__ERR_MODULE__ >> 16], \ -+ PRINT_FMT_PARAMS, \ -+ eventStrings[((_ev) - EV_NO_EVENT - 1)], \ -+ (uint16_t)(_flg)); \ -+ XX_Print _vmsg; \ -+ XX_Print("\r\n"); \ -+ XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \ -+ } \ -+ } while (0) -+ -+#else /* not REPORT_EVENTS */ -+ -+#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) -+ -+#endif /* (REPORT_EVENTS > 0) */ -+ -+#endif /* (DEBUG_ERRORS > 0) */ -+ -+ -+/**************************************************************************//** -+ @Function ASSERT_COND -+ -+ @Description Assertion macro. -+ -+ @Param[in] _cond - The condition being checked, in positive form; -+ Failure of the condition triggers the assert. -+*//***************************************************************************/ -+#ifdef DISABLE_ASSERTIONS -+#define ASSERT_COND(_cond) -+#else -+#define ASSERT_COND(_cond) \ -+ do { \ -+ if (!(_cond)) { \ -+ XX_Print("*** ASSERT_COND failed " PRINT_FORMAT "\r\n", \ -+ PRINT_FMT_PARAMS); \ -+ XX_Exit(1); \ -+ } \ -+ } while (0) -+#endif /* DISABLE_ASSERTIONS */ -+ -+ -+#ifdef DISABLE_INIT_PARAMETERS_CHECK -+ -+#define CHECK_INIT_PARAMETERS(handle, f_check) -+#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) -+ -+#else -+ -+#define CHECK_INIT_PARAMETERS(handle, f_check) \ -+ do { \ -+ t_Error err = f_check(handle); \ -+ if (err != E_OK) { \ -+ RETURN_ERROR(MAJOR, err, NO_MSG); \ -+ } \ -+ } while (0) -+ -+#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) \ -+ do { \ -+ t_Error err = f_check(handle); \ -+ if (err != E_OK) { \ -+ REPORT_ERROR(MAJOR, err, NO_MSG); \ -+ return (retval); \ -+ } \ -+ } while (0) -+ -+#endif /* DISABLE_INIT_PARAMETERS_CHECK */ -+ -+#ifdef DISABLE_SANITY_CHECKS -+ -+#define SANITY_CHECK_RETURN_ERROR(_cond, _err) -+#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) -+#define SANITY_CHECK_RETURN(_cond, _err) -+#define SANITY_CHECK_EXIT(_cond, _err) -+ -+#else /* DISABLE_SANITY_CHECKS */ -+ -+#define SANITY_CHECK_RETURN_ERROR(_cond, _err) \ -+ do { \ -+ if (!(_cond)) { \ -+ RETURN_ERROR(CRITICAL, (_err), NO_MSG); \ -+ } \ -+ } while (0) -+ -+#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) \ -+ do { \ -+ if (!(_cond)) { \ -+ REPORT_ERROR(CRITICAL, (_err), NO_MSG); \ -+ return (retval); \ -+ } \ -+ } while (0) -+ -+#define SANITY_CHECK_RETURN(_cond, _err) \ -+ do { \ -+ if (!(_cond)) { \ -+ REPORT_ERROR(CRITICAL, (_err), NO_MSG); \ -+ return; \ -+ } \ -+ } while (0) -+ -+#define SANITY_CHECK_EXIT(_cond, _err) \ -+ do { \ -+ if (!(_cond)) { \ -+ REPORT_ERROR(CRITICAL, (_err), NO_MSG); \ -+ XX_Exit(1); \ -+ } \ -+ } while (0) -+ -+#endif /* DISABLE_SANITY_CHECKS */ -+ -+/** @} */ /* end of Debug/error Utils group */ -+ -+/** @} */ /* end of General Utils group */ -+ -+#endif /* __ERROR_EXT_H */ -+ -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h -@@ -0,0 +1,358 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ -+ @File list_ext.h -+ -+ @Description External prototypes for list.c -+*//***************************************************************************/ -+ -+#ifndef __LIST_EXT_H -+#define __LIST_EXT_H -+ -+ -+#include "std_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group etc_id Utility Library Application Programming Interface -+ -+ @Description External routines. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group list_id List -+ -+ @Description List module functions,definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description List structure. -+*//***************************************************************************/ -+typedef struct List -+{ -+ struct List *p_Next; /**< A pointer to the next list object */ -+ struct List *p_Prev; /**< A pointer to the previous list object */ -+} t_List; -+ -+ -+/**************************************************************************//** -+ @Function LIST_FIRST/LIST_LAST/LIST_NEXT/LIST_PREV -+ -+ @Description Macro to get first/last/next/previous entry in a list. -+ -+ @Param[in] p_List - A pointer to a list. -+*//***************************************************************************/ -+#define LIST_FIRST(p_List) (p_List)->p_Next -+#define LIST_LAST(p_List) (p_List)->p_Prev -+#define LIST_NEXT LIST_FIRST -+#define LIST_PREV LIST_LAST -+ -+ -+/**************************************************************************//** -+ @Function LIST_INIT -+ -+ @Description Macro for initialization of a list struct. -+ -+ @Param[in] lst - The t_List object to initialize. -+*//***************************************************************************/ -+#define LIST_INIT(lst) {&(lst), &(lst)} -+ -+ -+/**************************************************************************//** -+ @Function LIST -+ -+ @Description Macro to declare of a list. -+ -+ @Param[in] listName - The list object name. -+*//***************************************************************************/ -+#define LIST(listName) t_List listName = LIST_INIT(listName) -+ -+ -+/**************************************************************************//** -+ @Function INIT_LIST -+ -+ @Description Macro to initialize a list pointer. -+ -+ @Param[in] p_List - The list pointer. -+*//***************************************************************************/ -+#define INIT_LIST(p_List) LIST_FIRST(p_List) = LIST_LAST(p_List) = (p_List) -+ -+ -+/**************************************************************************//** -+ @Function LIST_OBJECT -+ -+ @Description Macro to get the struct (object) for this entry. -+ -+ @Param[in] type - The type of the struct (object) this list is embedded in. -+ @Param[in] member - The name of the t_List object within the struct. -+ -+ @Return The structure pointer for this entry. -+*//***************************************************************************/ -+#define MEMBER_OFFSET(type, member) (PTR_TO_UINT(&((type *)0)->member)) -+#define LIST_OBJECT(p_List, type, member) \ -+ ((type *)((char *)(p_List)-MEMBER_OFFSET(type, member))) -+ -+ -+/**************************************************************************//** -+ @Function LIST_FOR_EACH -+ -+ @Description Macro to iterate over a list. -+ -+ @Param[in] p_Pos - A pointer to a list to use as a loop counter. -+ @Param[in] p_Head - A pointer to the head for your list pointer. -+ -+ @Cautions You can't delete items with this routine. -+ For deletion use LIST_FOR_EACH_SAFE(). -+*//***************************************************************************/ -+#define LIST_FOR_EACH(p_Pos, p_Head) \ -+ for (p_Pos = LIST_FIRST(p_Head); p_Pos != (p_Head); p_Pos = LIST_NEXT(p_Pos)) -+ -+ -+/**************************************************************************//** -+ @Function LIST_FOR_EACH_SAFE -+ -+ @Description Macro to iterate over a list safe against removal of list entry. -+ -+ @Param[in] p_Pos - A pointer to a list to use as a loop counter. -+ @Param[in] p_Tmp - Another pointer to a list to use as temporary storage. -+ @Param[in] p_Head - A pointer to the head for your list pointer. -+*//***************************************************************************/ -+#define LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \ -+ for (p_Pos = LIST_FIRST(p_Head), p_Tmp = LIST_FIRST(p_Pos); \ -+ p_Pos != (p_Head); \ -+ p_Pos = p_Tmp, p_Tmp = LIST_NEXT(p_Pos)) -+ -+ -+/**************************************************************************//** -+ @Function LIST_FOR_EACH_OBJECT_SAFE -+ -+ @Description Macro to iterate over list of given type safely. -+ -+ @Param[in] p_Pos - A pointer to a list to use as a loop counter. -+ @Param[in] p_Tmp - Another pointer to a list to use as temporary storage. -+ @Param[in] type - The type of the struct this is embedded in. -+ @Param[in] p_Head - A pointer to the head for your list pointer. -+ @Param[in] member - The name of the list_struct within the struct. -+ -+ @Cautions You can't delete items with this routine. -+ For deletion use LIST_FOR_EACH_SAFE(). -+*//***************************************************************************/ -+#define LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \ -+ for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member), \ -+ p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member); \ -+ &p_Pos->member != (p_Head); \ -+ p_Pos = p_Tmp, \ -+ p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member)) -+ -+/**************************************************************************//** -+ @Function LIST_FOR_EACH_OBJECT -+ -+ @Description Macro to iterate over list of given type. -+ -+ @Param[in] p_Pos - A pointer to a list to use as a loop counter. -+ @Param[in] type - The type of the struct this is embedded in. -+ @Param[in] p_Head - A pointer to the head for your list pointer. -+ @Param[in] member - The name of the list_struct within the struct. -+ -+ @Cautions You can't delete items with this routine. -+ For deletion use LIST_FOR_EACH_SAFE(). -+*//***************************************************************************/ -+#define LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \ -+ for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member); \ -+ &p_Pos->member != (p_Head); \ -+ p_Pos = LIST_OBJECT(LIST_FIRST(&(p_Pos->member)), type, member)) -+ -+ -+/**************************************************************************//** -+ @Function LIST_Add -+ -+ @Description Add a new entry to a list. -+ -+ Insert a new entry after the specified head. -+ This is good for implementing stacks. -+ -+ @Param[in] p_New - A pointer to a new list entry to be added. -+ @Param[in] p_Head - A pointer to a list head to add it after. -+ -+ @Return none. -+*//***************************************************************************/ -+static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head) -+{ -+ LIST_PREV(LIST_NEXT(p_Head)) = p_New; -+ LIST_NEXT(p_New) = LIST_NEXT(p_Head); -+ LIST_PREV(p_New) = p_Head; -+ LIST_NEXT(p_Head) = p_New; -+} -+ -+ -+/**************************************************************************//** -+ @Function LIST_AddToTail -+ -+ @Description Add a new entry to a list. -+ -+ Insert a new entry before the specified head. -+ This is useful for implementing queues. -+ -+ @Param[in] p_New - A pointer to a new list entry to be added. -+ @Param[in] p_Head - A pointer to a list head to add it before. -+ -+ @Return none. -+*//***************************************************************************/ -+static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head) -+{ -+ LIST_NEXT(LIST_PREV(p_Head)) = p_New; -+ LIST_PREV(p_New) = LIST_PREV(p_Head); -+ LIST_NEXT(p_New) = p_Head; -+ LIST_PREV(p_Head) = p_New; -+} -+ -+ -+/**************************************************************************//** -+ @Function LIST_Del -+ -+ @Description Deletes entry from a list. -+ -+ @Param[in] p_Entry - A pointer to the element to delete from the list. -+ -+ @Return none. -+ -+ @Cautions LIST_IsEmpty() on entry does not return true after this, -+ the entry is in an undefined state. -+*//***************************************************************************/ -+static __inline__ void LIST_Del(t_List *p_Entry) -+{ -+ LIST_PREV(LIST_NEXT(p_Entry)) = LIST_PREV(p_Entry); -+ LIST_NEXT(LIST_PREV(p_Entry)) = LIST_NEXT(p_Entry); -+} -+ -+ -+/**************************************************************************//** -+ @Function LIST_DelAndInit -+ -+ @Description Deletes entry from list and reinitialize it. -+ -+ @Param[in] p_Entry - A pointer to the element to delete from the list. -+ -+ @Return none. -+*//***************************************************************************/ -+static __inline__ void LIST_DelAndInit(t_List *p_Entry) -+{ -+ LIST_Del(p_Entry); -+ INIT_LIST(p_Entry); -+} -+ -+ -+/**************************************************************************//** -+ @Function LIST_Move -+ -+ @Description Delete from one list and add as another's head. -+ -+ @Param[in] p_Entry - A pointer to the list entry to move. -+ @Param[in] p_Head - A pointer to the list head that will precede our entry. -+ -+ @Return none. -+*//***************************************************************************/ -+static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head) -+{ -+ LIST_Del(p_Entry); -+ LIST_Add(p_Entry, p_Head); -+} -+ -+ -+/**************************************************************************//** -+ @Function LIST_MoveToTail -+ -+ @Description Delete from one list and add as another's tail. -+ -+ @Param[in] p_Entry - A pointer to the entry to move. -+ @Param[in] p_Head - A pointer to the list head that will follow our entry. -+ -+ @Return none. -+*//***************************************************************************/ -+static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head) -+{ -+ LIST_Del(p_Entry); -+ LIST_AddToTail(p_Entry, p_Head); -+} -+ -+ -+/**************************************************************************//** -+ @Function LIST_IsEmpty -+ -+ @Description Tests whether a list is empty. -+ -+ @Param[in] p_List - A pointer to the list to test. -+ -+ @Return 1 if the list is empty, 0 otherwise. -+*//***************************************************************************/ -+static __inline__ int LIST_IsEmpty(t_List *p_List) -+{ -+ return (LIST_FIRST(p_List) == p_List); -+} -+ -+ -+/**************************************************************************//** -+ @Function LIST_Append -+ -+ @Description Join two lists. -+ -+ @Param[in] p_NewList - A pointer to the new list to add. -+ @Param[in] p_Head - A pointer to the place to add it in the first list. -+ -+ @Return none. -+*//***************************************************************************/ -+void LIST_Append(t_List *p_NewList, t_List *p_Head); -+ -+ -+/**************************************************************************//** -+ @Function LIST_NumOfObjs -+ -+ @Description Counts number of objects in the list -+ -+ @Param[in] p_List - A pointer to the list which objects are to be counted. -+ -+ @Return Number of objects in the list. -+*//***************************************************************************/ -+int LIST_NumOfObjs(t_List *p_List); -+ -+/** @} */ /* end of list_id group */ -+/** @} */ /* end of etc_id group */ -+ -+ -+#endif /* __LIST_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h -@@ -0,0 +1,318 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ -+ @File mem_ext.h -+ -+ @Description External prototypes for the memory manager object -+*//***************************************************************************/ -+ -+#ifndef __MEM_EXT_H -+#define __MEM_EXT_H -+ -+#include "std_ext.h" -+#include "part_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group etc_id Utility Library Application Programming Interface -+ -+ @Description External routines. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group mem_id Slab Memory Manager -+ -+ @Description Slab Memory Manager module functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/* Each block is of the following structure: -+ * -+ * -+ * +-----------+----------+---------------------------+-----------+-----------+ -+ * | Alignment | Prefix | Data | Postfix | Alignment | -+ * | field | field | field | field | Padding | -+ * | | | | | | -+ * +-----------+----------+---------------------------+-----------+-----------+ -+ * and at the beginning of all bytes, an additional optional padding might reside -+ * to ensure that the first blocks data field is aligned as requested. -+ */ -+ -+ -+#define MEM_MAX_NAME_LENGTH 8 -+ -+/**************************************************************************//* -+ @Description Memory Segment structure -+*//***************************************************************************/ -+ -+typedef struct -+{ -+ char name[MEM_MAX_NAME_LENGTH]; -+ /* The segment's name */ -+ uint8_t **p_Bases; /* Base addresses of the segments */ -+ uint8_t **p_BlocksStack; /* Array of pointers to blocks */ -+ t_Handle h_Spinlock; -+ uint16_t dataSize; /* Size of each data block */ -+ uint16_t prefixSize; /* How many bytes to reserve before the data */ -+ uint16_t postfixSize; /* How many bytes to reserve after the data */ -+ uint16_t alignment; /* Requested alignment for the data field */ -+ int allocOwner; /* Memory allocation owner */ -+ uint32_t getFailures; /* Number of times get failed */ -+ uint32_t num; /* Number of blocks in segment */ -+ uint32_t current; /* Current block */ -+ bool consecutiveMem; /* Allocate consecutive data blocks memory */ -+#ifdef DEBUG_MEM_LEAKS -+ void *p_MemDbg; /* MEM debug database (MEM leaks detection) */ -+ uint32_t blockOffset; -+ uint32_t blockSize; -+#endif /* DEBUG_MEM_LEAKS */ -+} t_MemorySegment; -+ -+ -+ -+/**************************************************************************//** -+ @Function MEM_Init -+ -+ @Description Create a new memory segment. -+ -+ @Param[in] name - Name of memory partition. -+ @Param[in] p_Handle - Handle to new segment is returned through here. -+ @Param[in] num - Number of blocks in new segment. -+ @Param[in] dataSize - Size of blocks in segment. -+ @Param[in] prefixSize - How many bytes to allocate before the data. -+ @Param[in] postfixSize - How many bytes to allocate after the data. -+ @Param[in] alignment - Requested alignment for data field (in bytes). -+ -+ @Return E_OK - success, E_NO_MEMORY - out of memory. -+*//***************************************************************************/ -+t_Error MEM_Init(char name[], -+ t_Handle *p_Handle, -+ uint32_t num, -+ uint16_t dataSize, -+ uint16_t prefixSize, -+ uint16_t postfixSize, -+ uint16_t alignment); -+ -+/**************************************************************************//** -+ @Function MEM_InitSmart -+ -+ @Description Create a new memory segment. -+ -+ @Param[in] name - Name of memory partition. -+ @Param[in] p_Handle - Handle to new segment is returned through here. -+ @Param[in] num - Number of blocks in new segment. -+ @Param[in] dataSize - Size of blocks in segment. -+ @Param[in] prefixSize - How many bytes to allocate before the data. -+ @Param[in] postfixSize - How many bytes to allocate after the data. -+ @Param[in] alignment - Requested alignment for data field (in bytes). -+ @Param[in] memPartitionId - Memory partition ID for allocation. -+ @Param[in] consecutiveMem - Whether to allocate the memory blocks -+ continuously or not. -+ -+ @Return E_OK - success, E_NO_MEMORY - out of memory. -+*//***************************************************************************/ -+t_Error MEM_InitSmart(char name[], -+ t_Handle *p_Handle, -+ uint32_t num, -+ uint16_t dataSize, -+ uint16_t prefixSize, -+ uint16_t postfixSize, -+ uint16_t alignment, -+ uint8_t memPartitionId, -+ bool consecutiveMem); -+ -+/**************************************************************************//** -+ @Function MEM_InitByAddress -+ -+ @Description Create a new memory segment with a specified base address. -+ -+ @Param[in] name - Name of memory partition. -+ @Param[in] p_Handle - Handle to new segment is returned through here. -+ @Param[in] num - Number of blocks in new segment. -+ @Param[in] dataSize - Size of blocks in segment. -+ @Param[in] prefixSize - How many bytes to allocate before the data. -+ @Param[in] postfixSize - How many bytes to allocate after the data. -+ @Param[in] alignment - Requested alignment for data field (in bytes). -+ @Param[in] address - The required base address. -+ -+ @Return E_OK - success, E_NO_MEMORY - out of memory. -+ *//***************************************************************************/ -+t_Error MEM_InitByAddress(char name[], -+ t_Handle *p_Handle, -+ uint32_t num, -+ uint16_t dataSize, -+ uint16_t prefixSize, -+ uint16_t postfixSize, -+ uint16_t alignment, -+ uint8_t *address); -+ -+/**************************************************************************//** -+ @Function MEM_Free -+ -+ @Description Free a specific memory segment. -+ -+ @Param[in] h_Mem - Handle to memory segment. -+ -+ @Return None. -+*//***************************************************************************/ -+void MEM_Free(t_Handle h_Mem); -+ -+/**************************************************************************//** -+ @Function MEM_Get -+ -+ @Description Get a block of memory from a segment. -+ -+ @Param[in] h_Mem - Handle to memory segment. -+ -+ @Return Pointer to new memory block on success,0 otherwise. -+*//***************************************************************************/ -+void * MEM_Get(t_Handle h_Mem); -+ -+/**************************************************************************//** -+ @Function MEM_GetN -+ -+ @Description Get up to N blocks of memory from a segment. -+ -+ The blocks are assumed to be of a fixed size (one size per segment). -+ -+ @Param[in] h_Mem - Handle to memory segment. -+ @Param[in] num - Number of blocks to allocate. -+ @Param[out] array - Array of at least num pointers to which the addresses -+ of the allocated blocks are written. -+ -+ @Return The number of blocks actually allocated. -+ -+ @Cautions Interrupts are disabled for all of the allocation loop. -+ Although this loop is very short for each block (several machine -+ instructions), you should not allocate a very large number -+ of blocks via this routine. -+*//***************************************************************************/ -+uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]); -+ -+/**************************************************************************//** -+ @Function MEM_Put -+ -+ @Description Put a block of memory back to a segment. -+ -+ @Param[in] h_Mem - Handle to memory segment. -+ @Param[in] p_Block - The block to return. -+ -+ @Return Pointer to new memory block on success,0 otherwise. -+*//***************************************************************************/ -+t_Error MEM_Put(t_Handle h_Mem, void *p_Block); -+ -+/**************************************************************************//** -+ @Function MEM_ComputePartitionSize -+ -+ @Description calculate a tight upper boundary of the size of a partition with -+ given attributes. -+ -+ The returned value is suitable if one wants to use MEM_InitByAddress(). -+ -+ @Param[in] num - The number of blocks in the segment. -+ @Param[in] dataSize - Size of block to get. -+ @Param[in] prefixSize - The prefix size -+ @Param postfixSize - The postfix size -+ @Param[in] alignment - The requested alignment value (in bytes) -+ -+ @Return The memory block size a segment with the given attributes needs. -+*//***************************************************************************/ -+uint32_t MEM_ComputePartitionSize(uint32_t num, -+ uint16_t dataSize, -+ uint16_t prefixSize, -+ uint16_t postfixSize, -+ uint16_t alignment); -+ -+#ifdef DEBUG_MEM_LEAKS -+#if !((defined(__MWERKS__) || defined(__GNUC__)) && (__dest_os == __ppc_eabi)) -+#error "Memory-Leaks-Debug option is supported only for freescale CodeWarrior" -+#endif /* !(defined(__MWERKS__) && ... */ -+ -+/**************************************************************************//** -+ @Function MEM_CheckLeaks -+ -+ @Description Report MEM object leaks. -+ -+ This routine is automatically called by the MEM_Free() routine, -+ but it can also be invoked while the MEM object is alive. -+ -+ @Param[in] h_Mem - Handle to memory segment. -+ -+ @Return None. -+*//***************************************************************************/ -+void MEM_CheckLeaks(t_Handle h_Mem); -+ -+#else /* not DEBUG_MEM_LEAKS */ -+#define MEM_CheckLeaks(h_Mem) -+#endif /* not DEBUG_MEM_LEAKS */ -+ -+/**************************************************************************//** -+ @Description Get base of MEM -+*//***************************************************************************/ -+#define MEM_GetBase(h_Mem) ((t_MemorySegment *)(h_Mem))->p_Bases[0] -+ -+/**************************************************************************//** -+ @Description Get size of MEM block -+*//***************************************************************************/ -+#define MEM_GetSize(h_Mem) ((t_MemorySegment *)(h_Mem))->dataSize -+ -+/**************************************************************************//** -+ @Description Get prefix size of MEM block -+*//***************************************************************************/ -+#define MEM_GetPrefixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->prefixSize -+ -+/**************************************************************************//** -+ @Description Get postfix size of MEM block -+*//***************************************************************************/ -+#define MEM_GetPostfixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->postfixSize -+ -+/**************************************************************************//** -+ @Description Get alignment of MEM block (in bytes) -+*//***************************************************************************/ -+#define MEM_GetAlignment(h_Mem) ((t_MemorySegment *)(h_Mem))->alignment -+ -+/**************************************************************************//** -+ @Description Get the number of blocks in the segment -+*//***************************************************************************/ -+#define MEM_GetNumOfBlocks(h_Mem) ((t_MemorySegment *)(h_Mem))->num -+ -+/** @} */ /* end of MEM group */ -+/** @} */ /* end of etc_id group */ -+ -+ -+#endif /* __MEM_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h -@@ -0,0 +1,208 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ -+ @File memcpy_ext.h -+ -+ @Description Efficient functions for copying and setting blocks of memory. -+*//***************************************************************************/ -+ -+#ifndef __MEMCPY_EXT_H -+#define __MEMCPY_EXT_H -+ -+#include "std_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group etc_id Utility Library Application Programming Interface -+ -+ @Description External routines. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group mem_cpy Memory Copy -+ -+ @Description Memory Copy module functions,definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function MemCpy32 -+ -+ @Description Copies one memory buffer into another one in 4-byte chunks! -+ Which should be more efficient than byte by byte. -+ -+ For large buffers (over 60 bytes) this function is about 4 times -+ more efficient than the trivial memory copy. For short buffers -+ it is reduced to the trivial copy and may be a bit worse. -+ -+ @Param[in] pDst - The address of the destination buffer. -+ @Param[in] pSrc - The address of the source buffer. -+ @Param[in] size - The number of bytes that will be copied from pSrc to pDst. -+ -+ @Return pDst (the address of the destination buffer). -+ -+ @Cautions There is no parameter or boundary checking! It is up to the user -+ to supply non-null parameters as source & destination and size -+ that actually fits into the destination buffer. -+*//***************************************************************************/ -+void * MemCpy32(void* pDst,void* pSrc, uint32_t size); -+void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size); -+void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size); -+void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size); -+ -+/**************************************************************************//** -+ @Function MemCpy64 -+ -+ @Description Copies one memory buffer into another one in 8-byte chunks! -+ Which should be more efficient than byte by byte. -+ -+ For large buffers (over 60 bytes) this function is about 8 times -+ more efficient than the trivial memory copy. For short buffers -+ it is reduced to the trivial copy and may be a bit worse. -+ -+ Some testing suggests that MemCpy32() preforms better than -+ MemCpy64() over small buffers. On average they break even at -+ 100 byte buffers. For buffers larger than that MemCpy64 is -+ superior. -+ -+ @Param[in] pDst - The address of the destination buffer. -+ @Param[in] pSrc - The address of the source buffer. -+ @Param[in] size - The number of bytes that will be copied from pSrc to pDst. -+ -+ @Return pDst (the address of the destination buffer). -+ -+ @Cautions There is no parameter or boundary checking! It is up to the user -+ to supply non null parameters as source & destination and size -+ that actually fits into their buffer. -+ -+ Do not use under Linux. -+*//***************************************************************************/ -+void * MemCpy64(void* pDst,void* pSrc, uint32_t size); -+ -+/**************************************************************************//** -+ @Function MemSet32 -+ -+ @Description Sets all bytes of a memory buffer to a specific value, in -+ 4-byte chunks. -+ -+ @Param[in] pDst - The address of the destination buffer. -+ @Param[in] val - Value to set destination bytes to. -+ @Param[in] size - The number of bytes that will be set to val. -+ -+ @Return pDst (the address of the destination buffer). -+ -+ @Cautions There is no parameter or boundary checking! It is up to the user -+ to supply non null parameter as destination and size -+ that actually fits into the destination buffer. -+*//***************************************************************************/ -+void * MemSet32(void* pDst, uint8_t val, uint32_t size); -+void * IOMemSet32(void* pDst, uint8_t val, uint32_t size); -+ -+/**************************************************************************//** -+ @Function MemSet64 -+ -+ @Description Sets all bytes of a memory buffer to a specific value, in -+ 8-byte chunks. -+ -+ @Param[in] pDst - The address of the destination buffer. -+ @Param[in] val - Value to set destination bytes to. -+ @Param[in] size - The number of bytes that will be set to val. -+ -+ @Return pDst (the address of the destination buffer). -+ -+ @Cautions There is no parameter or boundary checking! It is up to the user -+ to supply non null parameter as destination and size -+ that actually fits into the destination buffer. -+*//***************************************************************************/ -+void * MemSet64(void* pDst, uint8_t val, uint32_t size); -+ -+/**************************************************************************//** -+ @Function MemDisp -+ -+ @Description Displays a block of memory in chunks of 32 bits. -+ -+ @Param[in] addr - The address of the memory to display. -+ @Param[in] size - The number of bytes that will be displayed. -+ -+ @Return None. -+ -+ @Cautions There is no parameter or boundary checking! It is up to the user -+ to supply non null parameter as destination and size -+ that actually fits into the destination buffer. -+*//***************************************************************************/ -+void MemDisp(uint8_t *addr, int size); -+ -+/**************************************************************************//** -+ @Function MemCpy8 -+ -+ @Description Trivial copy one memory buffer into another byte by byte -+ -+ @Param[in] pDst - The address of the destination buffer. -+ @Param[in] pSrc - The address of the source buffer. -+ @Param[in] size - The number of bytes that will be copied from pSrc to pDst. -+ -+ @Return pDst (the address of the destination buffer). -+ -+ @Cautions There is no parameter or boundary checking! It is up to the user -+ to supply non-null parameters as source & destination and size -+ that actually fits into the destination buffer. -+*//***************************************************************************/ -+void * MemCpy8(void* pDst,void* pSrc, uint32_t size); -+ -+/**************************************************************************//** -+ @Function MemSet8 -+ -+ @Description Sets all bytes of a memory buffer to a specific value byte by byte. -+ -+ @Param[in] pDst - The address of the destination buffer. -+ @Param[in] c - Value to set destination bytes to. -+ @Param[in] size - The number of bytes that will be set to val. -+ -+ @Return pDst (the address of the destination buffer). -+ -+ @Cautions There is no parameter or boundary checking! It is up to the user -+ to supply non null parameter as destination and size -+ that actually fits into the destination buffer. -+*//***************************************************************************/ -+void * MemSet8(void* pDst, int c, uint32_t size); -+ -+/** @} */ /* end of mem_cpy group */ -+/** @} */ /* end of etc_id group */ -+ -+ -+#endif /* __MEMCPY_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h -@@ -0,0 +1,310 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File mm_ext.h -+ -+ @Description Memory Manager Application Programming Interface -+*//***************************************************************************/ -+#ifndef __MM_EXT -+#define __MM_EXT -+ -+#include "std_ext.h" -+ -+#define MM_MAX_ALIGNMENT 20 /* Alignments from 2 to 128 are available -+ where maximum alignment defined as -+ MM_MAX_ALIGNMENT power of 2 */ -+ -+#define MM_MAX_NAME_LEN 32 -+ -+/**************************************************************************//** -+ @Group etc_id Utility Library Application Programming Interface -+ -+ @Description External routines. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group mm_grp Flexible Memory Manager -+ -+ @Description Flexible Memory Manager module functions,definitions and enums. -+ (All of the following functions,definitions and enums can be found in mm_ext.h) -+ -+ @{ -+*//***************************************************************************/ -+ -+ -+/**************************************************************************//** -+ @Function MM_Init -+ -+ @Description Initializes a new MM object. -+ -+ It initializes a new memory block consisting of base address -+ and size of the available memory by calling to MemBlock_Init -+ routine. It is also initializes a new free block for each -+ by calling FreeBlock_Init routine, which is pointed to -+ the almost all memory started from the required alignment -+ from the base address and to the end of the memory. -+ The handle to the new MM object is returned via "MM" -+ argument (passed by reference). -+ -+ @Param[in] h_MM - Handle to the MM object. -+ @Param[in] base - Base address of the MM. -+ @Param[in] size - Size of the MM. -+ -+ @Return E_OK is returned on success. E_NOMEMORY is returned if the new MM object or a new free block can not be initialized. -+*//***************************************************************************/ -+t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size); -+ -+/**************************************************************************//** -+ @Function MM_Get -+ -+ @Description Allocates a block of memory according to the given size and the alignment. -+ -+ The Alignment argument tells from which -+ free list allocate a block of memory. 2^alignment indicates -+ the alignment that the base address of the allocated block -+ should have. So, the only values 1, 2, 4, 8, 16, 32 and 64 -+ are available for the alignment argument. -+ The routine passes through the specific free list of free -+ blocks and seeks for a first block that have anough memory -+ that is required (best fit). -+ After the block is found and data is allocated, it calls -+ the internal MM_CutFree routine to update all free lists -+ do not include a just allocated block. Of course, each -+ free list contains a free blocks with the same alignment. -+ It is also creates a busy block that holds -+ information about an allocated block. -+ -+ @Param[in] h_MM - Handle to the MM object. -+ @Param[in] size - Size of the MM. -+ @Param[in] alignment - Index as a power of two defines a required -+ alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64 -+ @Param[in] name - The name that specifies an allocated block. -+ -+ @Return base address of an allocated block ILLEGAL_BASE if can't allocate a block -+*//***************************************************************************/ -+uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char *name); -+ -+/**************************************************************************//** -+ @Function MM_GetBase -+ -+ @Description Gets the base address of the required MM objects. -+ -+ @Param[in] h_MM - Handle to the MM object. -+ -+ @Return base address of the block. -+*//***************************************************************************/ -+uint64_t MM_GetBase(t_Handle h_MM); -+ -+/**************************************************************************//** -+ @Function MM_GetForce -+ -+ @Description Force memory allocation. -+ -+ It means to allocate a block of memory of the given -+ size from the given base address. -+ The routine checks if the required block can be allocated -+ (that is it is free) and then, calls the internal MM_CutFree -+ routine to update all free lists do not include that block. -+ -+ @Param[in] h_MM - Handle to the MM object. -+ @Param[in] base - Base address of the MM. -+ @Param[in] size - Size of the MM. -+ @Param[in] name - Name that specifies an allocated block. -+ -+ @Return base address of an allocated block, ILLEGAL_BASE if can't allocate a block. -+*//***************************************************************************/ -+uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char *name); -+ -+/**************************************************************************//** -+ @Function MM_GetForceMin -+ -+ @Description Allocates a block of memory according to the given size, the alignment and minimum base address. -+ -+ The Alignment argument tells from which -+ free list allocate a block of memory. 2^alignment indicates -+ the alignment that the base address of the allocated block -+ should have. So, the only values 1, 2, 4, 8, 16, 32 and 64 -+ are available for the alignment argument. -+ The minimum baser address forces the location of the block -+ to be from a given address onward. -+ The routine passes through the specific free list of free -+ blocks and seeks for the first base address equal or smaller -+ than the required minimum address and end address larger than -+ than the required base + its size - i.e. that may contain -+ the required block. -+ After the block is found and data is allocated, it calls -+ the internal MM_CutFree routine to update all free lists -+ do not include a just allocated block. Of course, each -+ free list contains a free blocks with the same alignment. -+ It is also creates a busy block that holds -+ information about an allocated block. -+ -+ @Param[in] h_MM - Handle to the MM object. -+ @Param[in] size - Size of the MM. -+ @Param[in] alignment - Index as a power of two defines a required -+ alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64 -+ @Param[in] min - The minimum base address of the block. -+ @Param[in] name - Name that specifies an allocated block. -+ -+ @Return base address of an allocated block,ILLEGAL_BASE if can't allocate a block. -+*//***************************************************************************/ -+uint64_t MM_GetForceMin(t_Handle h_MM, -+ uint64_t size, -+ uint64_t alignment, -+ uint64_t min, -+ char *name); -+ -+/**************************************************************************//** -+ @Function MM_Put -+ -+ @Description Puts a block of memory of the given base address back to the memory. -+ -+ It checks if there is a busy block with the -+ given base address. If not, it returns 0, that -+ means can't free a block. Otherwise, it gets parameters of -+ the busy block and after it updates lists of free blocks, -+ removes that busy block from the list by calling to MM_CutBusy -+ routine. -+ After that it calls to MM_AddFree routine to add a new free -+ block to the free lists. -+ -+ @Param[in] h_MM - Handle to the MM object. -+ @Param[in] base - Base address of the MM. -+ -+ @Return The size of bytes released, 0 if failed. -+*//***************************************************************************/ -+uint64_t MM_Put(t_Handle h_MM, uint64_t base); -+ -+/**************************************************************************//** -+ @Function MM_PutForce -+ -+ @Description Releases a block of memory of the required size from the required base address. -+ -+ First, it calls to MM_CutBusy routine -+ to cut a free block from the busy list. And then, calls to -+ MM_AddFree routine to add the free block to the free lists. -+ -+ @Param[in] h_MM - Handle to the MM object. -+ @Param[in] base - Base address of of a block to free. -+ @Param[in] size - Size of a block to free. -+ -+ @Return The number of bytes released, 0 on failure. -+*//***************************************************************************/ -+uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size); -+ -+/**************************************************************************//** -+ @Function MM_Add -+ -+ @Description Adds a new memory block for memory allocation. -+ -+ When a new memory block is initialized and added to the -+ memory list, it calls to MM_AddFree routine to add the -+ new free block to the free lists. -+ -+ @Param[in] h_MM - Handle to the MM object. -+ @Param[in] base - Base address of the memory block. -+ @Param[in] size - Size of the memory block. -+ -+ @Return E_OK on success, otherwise returns an error code. -+*//***************************************************************************/ -+t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size); -+ -+/**************************************************************************//** -+ @Function MM_Dump -+ -+ @Description Prints results of free and busy lists. -+ -+ @Param[in] h_MM - Handle to the MM object. -+*//***************************************************************************/ -+void MM_Dump(t_Handle h_MM); -+ -+/**************************************************************************//** -+ @Function MM_Free -+ -+ @Description Releases memory allocated for MM object. -+ -+ @Param[in] h_MM - Handle of the MM object. -+*//***************************************************************************/ -+void MM_Free(t_Handle h_MM); -+ -+/**************************************************************************//** -+ @Function MM_GetMemBlock -+ -+ @Description Returns base address of the memory block specified by the index. -+ -+ If index is 0, returns base address -+ of the first memory block, 1 - returns base address -+ of the second memory block, etc. -+ Note, those memory blocks are allocated by the -+ application before MM_Init or MM_Add and have to -+ be released by the application before or after invoking -+ the MM_Free routine. -+ -+ @Param[in] h_MM - Handle to the MM object. -+ @Param[in] index - Index of the memory block. -+ -+ @Return valid base address or ILLEGAL_BASE if no memory block specified by the index. -+*//***************************************************************************/ -+uint64_t MM_GetMemBlock(t_Handle h_MM, int index); -+ -+/**************************************************************************//** -+ @Function MM_InRange -+ -+ @Description Checks if a specific address is in the memory range of the passed MM object. -+ -+ @Param[in] h_MM - Handle to the MM object. -+ @Param[in] addr - The address to be checked. -+ -+ @Return TRUE if the address is in the address range of the block, FALSE otherwise. -+*//***************************************************************************/ -+bool MM_InRange(t_Handle h_MM, uint64_t addr); -+ -+/**************************************************************************//** -+ @Function MM_GetFreeMemSize -+ -+ @Description Returns the size (in bytes) of free memory. -+ -+ @Param[in] h_MM - Handle to the MM object. -+ -+ @Return Free memory size in bytes. -+*//***************************************************************************/ -+uint64_t MM_GetFreeMemSize(t_Handle h_MM); -+ -+ -+/** @} */ /* end of mm_grp group */ -+/** @} */ /* end of etc_id group */ -+ -+#endif /* __MM_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h -@@ -0,0 +1,118 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File sprint_ext.h -+ -+ @Description Debug routines (externals). -+ -+*//***************************************************************************/ -+ -+#ifndef __SPRINT_EXT_H -+#define __SPRINT_EXT_H -+ -+ -+#if defined(NCSW_LINUX) && defined(__KERNEL__) -+#include -+ -+#elif defined(NCSW_VXWORKS) -+#include "private/stdioP.h" -+ -+#else -+#include -+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */ -+ -+#include "std_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group etc_id Utility Library Application Programming Interface -+ -+ @Description External routines. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group sprint_id Sprint -+ -+ @Description Sprint & Sscan module functions,definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Function Sprint -+ -+ @Description Format a string and place it in a buffer. -+ -+ @Param[in] buff - The buffer to place the result into. -+ @Param[in] str - The format string to use. -+ @Param[in] ... - Arguments for the format string. -+ -+ @Return Number of bytes formatted. -+*//***************************************************************************/ -+int Sprint(char *buff, const char *str, ...); -+ -+/**************************************************************************//** -+ @Function Snprint -+ -+ @Description Format a string and place it in a buffer. -+ -+ @Param[in] buf - The buffer to place the result into. -+ @Param[in] size - The size of the buffer, including the trailing null space. -+ @Param[in] fmt - The format string to use. -+ @Param[in] ... - Arguments for the format string. -+ -+ @Return Number of bytes formatted. -+*//***************************************************************************/ -+int Snprint(char * buf, uint32_t size, const char *fmt, ...); -+ -+/**************************************************************************//** -+ @Function Sscan -+ -+ @Description Unformat a buffer into a list of arguments. -+ -+ @Param[in] buf - input buffer. -+ @Param[in] fmt - formatting of buffer. -+ @Param[out] ... - resulting arguments. -+ -+ @Return Number of bytes unformatted. -+*//***************************************************************************/ -+int Sscan(const char * buf, const char * fmt, ...); -+ -+/** @} */ /* end of sprint_id group */ -+/** @} */ /* end of etc_id group */ -+ -+ -+#endif /* __SPRINT_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h -@@ -0,0 +1,37 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef FL_E500_MACROS_H -+#define FL_E500_MACROS_H -+ -+#endif /* FL_E500_MACROS_H */ -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h -@@ -0,0 +1,52 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __GENERAL_H -+#define __GENERAL_H -+ -+#include "std_ext.h" -+#if !defined(NCSW_LINUX) -+#include "errno.h" -+#endif -+ -+ -+extern uint32_t get_mac_addr_crc(uint64_t _addr); -+ -+#ifndef CONFIG_FMAN_ARM -+#define iowrite32be(val, addr) WRITE_UINT32(*addr, val) -+#define ioread32be(addr) GET_UINT32(*addr) -+#endif -+ -+#define ether_crc(len, addr) get_mac_addr_crc(*(uint64_t *)(addr)>>16) -+ -+ -+#endif /* __GENERAL_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h -@@ -0,0 +1,78 @@ -+/* -+ * Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#ifndef __FMAN_COMMON_H -+#define __FMAN_COMMON_H -+ -+/**************************************************************************//** -+ @Description NIA Description -+*//***************************************************************************/ -+#define NIA_ORDER_RESTOR 0x00800000 -+#define NIA_ENG_FM_CTL 0x00000000 -+#define NIA_ENG_PRS 0x00440000 -+#define NIA_ENG_KG 0x00480000 -+#define NIA_ENG_PLCR 0x004C0000 -+#define NIA_ENG_BMI 0x00500000 -+#define NIA_ENG_QMI_ENQ 0x00540000 -+#define NIA_ENG_QMI_DEQ 0x00580000 -+#define NIA_ENG_MASK 0x007C0000 -+ -+#define NIA_FM_CTL_AC_CC 0x00000006 -+#define NIA_FM_CTL_AC_HC 0x0000000C -+#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008 -+#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A -+#define NIA_FM_CTL_AC_FRAG 0x0000000e -+#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010 -+#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012 -+#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018 -+#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012 -+#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014 -+#define NIA_FM_CTL_AC_PRE_CC 0x00000020 -+ -+ -+#define NIA_BMI_AC_ENQ_FRAME 0x00000002 -+#define NIA_BMI_AC_TX_RELEASE 0x000002C0 -+#define NIA_BMI_AC_RELEASE 0x000000C0 -+#define NIA_BMI_AC_DISCARD 0x000000C1 -+#define NIA_BMI_AC_TX 0x00000274 -+#define NIA_BMI_AC_FETCH 0x00000208 -+#define NIA_BMI_AC_MASK 0x000003FF -+ -+#define NIA_KG_DIRECT 0x00000100 -+#define NIA_KG_CC_EN 0x00000200 -+#define NIA_PLCR_ABSOLUTE 0x00008000 -+ -+#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202 -+#define NIA_BMI_AC_FETCH_ALL_FRAME 0x0000020c -+ -+#endif /* __FMAN_COMMON_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h -@@ -0,0 +1,273 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __FSL_ENET_H -+#define __FSL_ENET_H -+ -+/** -+ @Description Ethernet MAC-PHY Interface -+*/ -+ -+enum enet_interface { -+ E_ENET_IF_MII = 0x00010000, /**< MII interface */ -+ E_ENET_IF_RMII = 0x00020000, /**< RMII interface */ -+ E_ENET_IF_SMII = 0x00030000, /**< SMII interface */ -+ E_ENET_IF_GMII = 0x00040000, /**< GMII interface */ -+ E_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */ -+ E_ENET_IF_TBI = 0x00060000, /**< TBI interface */ -+ E_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */ -+ E_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */ -+ E_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */ -+ E_ENET_IF_QSGMII = 0x000a0000, /**< QSGMII interface */ -+ E_ENET_IF_XFI = 0x000b0000 /**< XFI interface */ -+}; -+ -+/** -+ @Description Ethernet Speed (nominal data rate) -+*/ -+enum enet_speed { -+ E_ENET_SPEED_10 = 10, /**< 10 Mbps */ -+ E_ENET_SPEED_100 = 100, /**< 100 Mbps */ -+ E_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */ -+ E_ENET_SPEED_2500 = 2500, /**< 2500 Mbps = 2.5 Gbps */ -+ E_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */ -+}; -+ -+enum mac_type { -+ E_MAC_DTSEC, -+ E_MAC_TGEC, -+ E_MAC_MEMAC -+}; -+ -+/**************************************************************************//** -+ @Description Enum for inter-module interrupts registration -+*//***************************************************************************/ -+enum fman_event_modules { -+ E_FMAN_MOD_PRS, /**< Parser event */ -+ E_FMAN_MOD_KG, /**< Keygen event */ -+ E_FMAN_MOD_PLCR, /**< Policer event */ -+ E_FMAN_MOD_10G_MAC, /**< 10G MAC event */ -+ E_FMAN_MOD_1G_MAC, /**< 1G MAC event */ -+ E_FMAN_MOD_TMR, /**< Timer event */ -+ E_FMAN_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */ -+ E_FMAN_MOD_MACSEC, -+ E_FMAN_MOD_DUMMY_LAST -+}; -+ -+/**************************************************************************//** -+ @Description Enum for interrupts types -+*//***************************************************************************/ -+enum fman_intr_type { -+ E_FMAN_INTR_TYPE_ERR, -+ E_FMAN_INTR_TYPE_NORMAL -+}; -+ -+/**************************************************************************//** -+ @Description enum for defining MAC types -+*//***************************************************************************/ -+enum fman_mac_type { -+ E_FMAN_MAC_10G = 0, /**< 10G MAC */ -+ E_FMAN_MAC_1G /**< 1G MAC */ -+}; -+ -+enum fman_mac_exceptions { -+ E_FMAN_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0, -+ /**< 10GEC MDIO scan event interrupt */ -+ E_FMAN_MAC_EX_10G_MDIO_CMD_CMPL, -+ /**< 10GEC MDIO command completion interrupt */ -+ E_FMAN_MAC_EX_10G_REM_FAULT, -+ /**< 10GEC, mEMAC Remote fault interrupt */ -+ E_FMAN_MAC_EX_10G_LOC_FAULT, -+ /**< 10GEC, mEMAC Local fault interrupt */ -+ E_FMAN_MAC_EX_10G_1TX_ECC_ER, -+ /**< 10GEC, mEMAC Transmit frame ECC error interrupt */ -+ E_FMAN_MAC_EX_10G_TX_FIFO_UNFL, -+ /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */ -+ E_FMAN_MAC_EX_10G_TX_FIFO_OVFL, -+ /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */ -+ E_FMAN_MAC_EX_10G_TX_ER, -+ /**< 10GEC Transmit frame error interrupt */ -+ E_FMAN_MAC_EX_10G_RX_FIFO_OVFL, -+ /**< 10GEC, mEMAC Receive FIFO overflow interrupt */ -+ E_FMAN_MAC_EX_10G_RX_ECC_ER, -+ /**< 10GEC, mEMAC Receive frame ECC error interrupt */ -+ E_FMAN_MAC_EX_10G_RX_JAB_FRM, -+ /**< 10GEC Receive jabber frame interrupt */ -+ E_FMAN_MAC_EX_10G_RX_OVRSZ_FRM, -+ /**< 10GEC Receive oversized frame interrupt */ -+ E_FMAN_MAC_EX_10G_RX_RUNT_FRM, -+ /**< 10GEC Receive runt frame interrupt */ -+ E_FMAN_MAC_EX_10G_RX_FRAG_FRM, -+ /**< 10GEC Receive fragment frame interrupt */ -+ E_FMAN_MAC_EX_10G_RX_LEN_ER, -+ /**< 10GEC Receive payload length error interrupt */ -+ E_FMAN_MAC_EX_10G_RX_CRC_ER, -+ /**< 10GEC Receive CRC error interrupt */ -+ E_FMAN_MAC_EX_10G_RX_ALIGN_ER, -+ /**< 10GEC Receive alignment error interrupt */ -+ E_FMAN_MAC_EX_1G_BAB_RX, -+ /**< dTSEC Babbling receive error */ -+ E_FMAN_MAC_EX_1G_RX_CTL, -+ /**< dTSEC Receive control (pause frame) interrupt */ -+ E_FMAN_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET, -+ /**< dTSEC Graceful transmit stop complete */ -+ E_FMAN_MAC_EX_1G_BAB_TX, -+ /**< dTSEC Babbling transmit error */ -+ E_FMAN_MAC_EX_1G_TX_CTL, -+ /**< dTSEC Transmit control (pause frame) interrupt */ -+ E_FMAN_MAC_EX_1G_TX_ERR, -+ /**< dTSEC Transmit error */ -+ E_FMAN_MAC_EX_1G_LATE_COL, -+ /**< dTSEC Late collision */ -+ E_FMAN_MAC_EX_1G_COL_RET_LMT, -+ /**< dTSEC Collision retry limit */ -+ E_FMAN_MAC_EX_1G_TX_FIFO_UNDRN, -+ /**< dTSEC Transmit FIFO underrun */ -+ E_FMAN_MAC_EX_1G_MAG_PCKT, -+ /**< dTSEC Magic Packet detection */ -+ E_FMAN_MAC_EX_1G_MII_MNG_RD_COMPLET, -+ /**< dTSEC MII management read completion */ -+ E_FMAN_MAC_EX_1G_MII_MNG_WR_COMPLET, -+ /**< dTSEC MII management write completion */ -+ E_FMAN_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET, -+ /**< dTSEC Graceful receive stop complete */ -+ E_FMAN_MAC_EX_1G_TX_DATA_ERR, -+ /**< dTSEC Internal data error on transmit */ -+ E_FMAN_MAC_EX_1G_RX_DATA_ERR, -+ /**< dTSEC Internal data error on receive */ -+ E_FMAN_MAC_EX_1G_1588_TS_RX_ERR, -+ /**< dTSEC Time-Stamp Receive Error */ -+ E_FMAN_MAC_EX_1G_RX_MIB_CNT_OVFL, -+ /**< dTSEC MIB counter overflow */ -+ E_FMAN_MAC_EX_TS_FIFO_ECC_ERR, -+ /**< mEMAC Time-stamp FIFO ECC error interrupt; -+ not supported on T4240/B4860 rev1 chips */ -+}; -+ -+#define ENET_IF_SGMII_BASEX 0x80000000 -+ /**< SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC -+ and phy or backplane; -+ Note: 1000BaseX auto-negotiation relates only to interface between MAC -+ and phy/backplane, SGMII phy can still synchronize with far-end phy at -+ 10Mbps, 100Mbps or 1000Mbps */ -+ -+enum enet_mode { -+ E_ENET_MODE_INVALID = 0, -+ /**< Invalid Ethernet mode */ -+ E_ENET_MODE_MII_10 = (E_ENET_IF_MII | E_ENET_SPEED_10), -+ /**< 10 Mbps MII */ -+ E_ENET_MODE_MII_100 = (E_ENET_IF_MII | E_ENET_SPEED_100), -+ /**< 100 Mbps MII */ -+ E_ENET_MODE_RMII_10 = (E_ENET_IF_RMII | E_ENET_SPEED_10), -+ /**< 10 Mbps RMII */ -+ E_ENET_MODE_RMII_100 = (E_ENET_IF_RMII | E_ENET_SPEED_100), -+ /**< 100 Mbps RMII */ -+ E_ENET_MODE_SMII_10 = (E_ENET_IF_SMII | E_ENET_SPEED_10), -+ /**< 10 Mbps SMII */ -+ E_ENET_MODE_SMII_100 = (E_ENET_IF_SMII | E_ENET_SPEED_100), -+ /**< 100 Mbps SMII */ -+ E_ENET_MODE_GMII_1000 = (E_ENET_IF_GMII | E_ENET_SPEED_1000), -+ /**< 1000 Mbps GMII */ -+ E_ENET_MODE_RGMII_10 = (E_ENET_IF_RGMII | E_ENET_SPEED_10), -+ /**< 10 Mbps RGMII */ -+ E_ENET_MODE_RGMII_100 = (E_ENET_IF_RGMII | E_ENET_SPEED_100), -+ /**< 100 Mbps RGMII */ -+ E_ENET_MODE_RGMII_1000 = (E_ENET_IF_RGMII | E_ENET_SPEED_1000), -+ /**< 1000 Mbps RGMII */ -+ E_ENET_MODE_TBI_1000 = (E_ENET_IF_TBI | E_ENET_SPEED_1000), -+ /**< 1000 Mbps TBI */ -+ E_ENET_MODE_RTBI_1000 = (E_ENET_IF_RTBI | E_ENET_SPEED_1000), -+ /**< 1000 Mbps RTBI */ -+ E_ENET_MODE_SGMII_10 = (E_ENET_IF_SGMII | E_ENET_SPEED_10), -+ /**< 10 Mbps SGMII with auto-negotiation between MAC and -+ SGMII phy according to Cisco SGMII specification */ -+ E_ENET_MODE_SGMII_100 = (E_ENET_IF_SGMII | E_ENET_SPEED_100), -+ /**< 100 Mbps SGMII with auto-negotiation between MAC and -+ SGMII phy according to Cisco SGMII specification */ -+ E_ENET_MODE_SGMII_1000 = (E_ENET_IF_SGMII | E_ENET_SPEED_1000), -+ /**< 1000 Mbps SGMII with auto-negotiation between MAC and -+ SGMII phy according to Cisco SGMII specification */ -+ E_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII -+ | E_ENET_SPEED_10), -+ /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between -+ MAC and SGMII phy or backplane */ -+ E_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII -+ | E_ENET_SPEED_100), -+ /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between -+ MAC and SGMII phy or backplane */ -+ E_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII -+ | E_ENET_SPEED_1000), -+ /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between -+ MAC and SGMII phy or backplane */ -+ E_ENET_MODE_QSGMII_1000 = (E_ENET_IF_QSGMII | E_ENET_SPEED_1000), -+ /**< 1000 Mbps QSGMII with auto-negotiation between MAC and -+ QSGMII phy according to Cisco QSGMII specification */ -+ E_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_QSGMII -+ | E_ENET_SPEED_1000), -+ /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between -+ MAC and QSGMII phy or backplane */ -+ E_ENET_MODE_XGMII_10000 = (E_ENET_IF_XGMII | E_ENET_SPEED_10000), -+ /**< 10000 Mbps XGMII */ -+ E_ENET_MODE_XFI_10000 = (E_ENET_IF_XFI | E_ENET_SPEED_10000) -+ /**< 10000 Mbps XFI */ -+}; -+ -+enum fmam_mac_statistics_level { -+ E_FMAN_MAC_NONE_STATISTICS, /**< No statistics */ -+ E_FMAN_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; -+ Optimized for performance */ -+ E_FMAN_MAC_FULL_STATISTICS /**< All counters available; Not -+ optimized for performance */ -+}; -+ -+#define _MAKE_ENET_MODE(_interface, _speed) (enum enet_mode)((_interface) \ -+ | (_speed)) -+ -+#define _ENET_INTERFACE_FROM_MODE(mode) (enum enet_interface) \ -+ ((mode) & 0x0FFF0000) -+#define _ENET_SPEED_FROM_MODE(mode) (enum enet_speed)((mode) & 0x0000FFFF) -+#define _ENET_ADDR_TO_UINT64(_enet_addr) \ -+ (uint64_t)(((uint64_t)(_enet_addr)[0] << 40) | \ -+ ((uint64_t)(_enet_addr)[1] << 32) | \ -+ ((uint64_t)(_enet_addr)[2] << 24) | \ -+ ((uint64_t)(_enet_addr)[3] << 16) | \ -+ ((uint64_t)(_enet_addr)[4] << 8) | \ -+ ((uint64_t)(_enet_addr)[5])) -+ -+#define _MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \ -+ do { \ -+ int i; \ -+ for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \ -+ (_enet_addr)[i] = (uint8_t)((_addr64) >> ((5-i)*8));\ -+ } while (0) -+ -+#endif /* __FSL_ENET_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h -@@ -0,0 +1,825 @@ -+/* -+ * Copyright 2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __FSL_FMAN_H -+#define __FSL_FMAN_H -+ -+#include "common/general.h" -+ -+struct fman_ext_pool_params { -+ uint8_t id; /**< External buffer pool id */ -+ uint16_t size; /**< External buffer pool buffer size */ -+}; -+ -+struct fman_ext_pools { -+ uint8_t num_pools_used; /**< Number of pools use by this port */ -+ struct fman_ext_pool_params *ext_buf_pool; -+ /**< Parameters for each port */ -+}; -+ -+struct fman_backup_bm_pools { -+ uint8_t num_backup_pools; /**< Number of BM backup pools - -+ must be smaller than the total number -+ of pools defined for the specified -+ port.*/ -+ uint8_t *pool_ids; /**< numOfBackupPools pool id's, -+ specifying which pools should be used -+ only as backup. Pool id's specified -+ here must be a subset of the pools -+ used by the specified port.*/ -+}; -+ -+/**************************************************************************//** -+ @Description A structure for defining BM pool depletion criteria -+*//***************************************************************************/ -+struct fman_buf_pool_depletion { -+ bool buf_pool_depletion_enabled; -+ bool pools_grp_mode_enable; /**< select mode in which pause frames -+ will be sent after a number of pools -+ (all together!) are depleted */ -+ uint8_t num_pools; /**< the number of depleted pools that -+ will invoke pause frames transmission. -+ */ -+ bool *pools_to_consider; /**< For each pool, TRUE if it should be -+ considered for depletion (Note - this -+ pool must be used by this port!). */ -+ bool single_pool_mode_enable; /**< select mode in which pause frames -+ will be sent after a single-pool -+ is depleted; */ -+ bool *pools_to_consider_for_single_mode; -+ /**< For each pool, TRUE if it should be -+ considered for depletion (Note - this -+ pool must be used by this port!) */ -+ bool has_pfc_priorities; -+ bool *pfc_priorities_en; /**< This field is used by the MAC as -+ the Priority Enable Vector in the PFC -+ frame which is transmitted */ -+}; -+ -+/**************************************************************************//** -+ @Description Enum for defining port DMA swap mode -+*//***************************************************************************/ -+enum fman_dma_swap_option { -+ FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/ -+ FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped -+ in PowerPc Little Endian mode. */ -+ FMAN_DMA_SWP_BE /**< The transferred data should be swapped -+ in Big Endian mode */ -+}; -+ -+/**************************************************************************//** -+ @Description Enum for defining port DMA cache attributes -+*//***************************************************************************/ -+enum fman_dma_cache_option { -+ FMAN_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */ -+ FMAN_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */ -+}; -+ -+typedef struct t_FmPrsResult fm_prs_result_t; -+typedef enum e_EnetMode enet_mode_t; -+typedef t_Handle handle_t; -+ -+struct fman_revision_info { -+ uint8_t majorRev; /**< Major revision */ -+ uint8_t minorRev; /**< Minor revision */ -+}; -+ -+/* sizes */ -+#define CAPWAP_FRAG_EXTRA_SPACE 32 -+#define OFFSET_UNITS 16 -+#define MAX_INT_OFFSET 240 -+#define MAX_IC_SIZE 256 -+#define MAX_EXT_OFFSET 496 -+#define MAX_EXT_BUFFER_OFFSET 511 -+ -+/************************************************************************** -+ @Description Memory Mapped Registers -+***************************************************************************/ -+#define FMAN_LIODN_TBL 64 /* size of LIODN table */ -+ -+struct fman_fpm_regs { -+ uint32_t fmfp_tnc; /**< FPM TNUM Control 0x00 */ -+ uint32_t fmfp_prc; /**< FPM Port_ID FmCtl Association 0x04 */ -+ uint32_t fmfp_brkc; /**< FPM Breakpoint Control 0x08 */ -+ uint32_t fmfp_mxd; /**< FPM Flush Control 0x0c */ -+ uint32_t fmfp_dist1; /**< FPM Dispatch Thresholds1 0x10 */ -+ uint32_t fmfp_dist2; /**< FPM Dispatch Thresholds2 0x14 */ -+ uint32_t fm_epi; /**< FM Error Pending Interrupts 0x18 */ -+ uint32_t fm_rie; /**< FM Error Interrupt Enable 0x1c */ -+ uint32_t fmfp_fcev[4]; /**< FPM FMan-Controller Event 1-4 0x20-0x2f */ -+ uint32_t res0030[4]; /**< res 0x30 - 0x3f */ -+ uint32_t fmfp_cee[4]; /**< PM FMan-Controller Event 1-4 0x40-0x4f */ -+ uint32_t res0050[4]; /**< res 0x50-0x5f */ -+ uint32_t fmfp_tsc1; /**< FPM TimeStamp Control1 0x60 */ -+ uint32_t fmfp_tsc2; /**< FPM TimeStamp Control2 0x64 */ -+ uint32_t fmfp_tsp; /**< FPM Time Stamp 0x68 */ -+ uint32_t fmfp_tsf; /**< FPM Time Stamp Fraction 0x6c */ -+ uint32_t fm_rcr; /**< FM Rams Control 0x70 */ -+ uint32_t fmfp_extc; /**< FPM External Requests Control 0x74 */ -+ uint32_t fmfp_ext1; /**< FPM External Requests Config1 0x78 */ -+ uint32_t fmfp_ext2; /**< FPM External Requests Config2 0x7c */ -+ uint32_t fmfp_drd[16]; /**< FPM Data_Ram Data 0-15 0x80 - 0xbf */ -+ uint32_t fmfp_dra; /**< FPM Data Ram Access 0xc0 */ -+ uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 0xc4 */ -+ uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 0xc8 */ -+ uint32_t fm_rstc; /**< FM Reset Command 0xcc */ -+ uint32_t fm_cld; /**< FM Classifier Debug 0xd0 */ -+ uint32_t fm_npi; /**< FM Normal Pending Interrupts 0xd4 */ -+ uint32_t fmfp_exte; /**< FPM External Requests Enable 0xd8 */ -+ uint32_t fmfp_ee; /**< FPM Event & Mask 0xdc */ -+ uint32_t fmfp_cev[4]; /**< FPM CPU Event 1-4 0xe0-0xef */ -+ uint32_t res00f0[4]; /**< res 0xf0-0xff */ -+ uint32_t fmfp_ps[64]; /**< FPM Port Status 0x100-0x1ff */ -+ uint32_t fmfp_clfabc; /**< FPM CLFABC 0x200 */ -+ uint32_t fmfp_clfcc; /**< FPM CLFCC 0x204 */ -+ uint32_t fmfp_clfaval; /**< FPM CLFAVAL 0x208 */ -+ uint32_t fmfp_clfbval; /**< FPM CLFBVAL 0x20c */ -+ uint32_t fmfp_clfcval; /**< FPM CLFCVAL 0x210 */ -+ uint32_t fmfp_clfamsk; /**< FPM CLFAMSK 0x214 */ -+ uint32_t fmfp_clfbmsk; /**< FPM CLFBMSK 0x218 */ -+ uint32_t fmfp_clfcmsk; /**< FPM CLFCMSK 0x21c */ -+ uint32_t fmfp_clfamc; /**< FPM CLFAMC 0x220 */ -+ uint32_t fmfp_clfbmc; /**< FPM CLFBMC 0x224 */ -+ uint32_t fmfp_clfcmc; /**< FPM CLFCMC 0x228 */ -+ uint32_t fmfp_decceh; /**< FPM DECCEH 0x22c */ -+ uint32_t res0230[116]; /**< res 0x230 - 0x3ff */ -+ uint32_t fmfp_ts[128]; /**< 0x400: FPM Task Status 0x400 - 0x5ff */ -+ uint32_t res0600[0x400 - 384]; -+}; -+ -+struct fman_bmi_regs { -+ uint32_t fmbm_init; /**< BMI Initialization 0x00 */ -+ uint32_t fmbm_cfg1; /**< BMI Configuration 1 0x04 */ -+ uint32_t fmbm_cfg2; /**< BMI Configuration 2 0x08 */ -+ uint32_t res000c[5]; /**< 0x0c - 0x1f */ -+ uint32_t fmbm_ievr; /**< Interrupt Event Register 0x20 */ -+ uint32_t fmbm_ier; /**< Interrupt Enable Register 0x24 */ -+ uint32_t fmbm_ifr; /**< Interrupt Force Register 0x28 */ -+ uint32_t res002c[5]; /**< 0x2c - 0x3f */ -+ uint32_t fmbm_arb[8]; /**< BMI Arbitration 0x40 - 0x5f */ -+ uint32_t res0060[12]; /**<0x60 - 0x8f */ -+ uint32_t fmbm_dtc[3]; /**< Debug Trap Counter 0x90 - 0x9b */ -+ uint32_t res009c; /**< 0x9c */ -+ uint32_t fmbm_dcv[3][4]; /**< Debug Compare val 0xa0-0xcf */ -+ uint32_t fmbm_dcm[3][4]; /**< Debug Compare Mask 0xd0-0xff */ -+ uint32_t fmbm_gde; /**< BMI Global Debug Enable 0x100 */ -+ uint32_t fmbm_pp[63]; /**< BMI Port Parameters 0x104 - 0x1ff */ -+ uint32_t res0200; /**< 0x200 */ -+ uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size 0x204 - 0x2ff */ -+ uint32_t res0300; /**< 0x300 */ -+ uint32_t fmbm_spliodn[63]; /**< Port Partition ID 0x304 - 0x3ff */ -+}; -+ -+struct fman_qmi_regs { -+ uint32_t fmqm_gc; /**< General Configuration Register 0x00 */ -+ uint32_t res0004; /**< 0x04 */ -+ uint32_t fmqm_eie; /**< Error Interrupt Event Register 0x08 */ -+ uint32_t fmqm_eien; /**< Error Interrupt Enable Register 0x0c */ -+ uint32_t fmqm_eif; /**< Error Interrupt Force Register 0x10 */ -+ uint32_t fmqm_ie; /**< Interrupt Event Register 0x14 */ -+ uint32_t fmqm_ien; /**< Interrupt Enable Register 0x18 */ -+ uint32_t fmqm_if; /**< Interrupt Force Register 0x1c */ -+ uint32_t fmqm_gs; /**< Global Status Register 0x20 */ -+ uint32_t fmqm_ts; /**< Task Status Register 0x24 */ -+ uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter 0x28 */ -+ uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter 0x2c */ -+ uint32_t fmqm_dc0; /**< Dequeue Counter 0 0x30 */ -+ uint32_t fmqm_dc1; /**< Dequeue Counter 1 0x34 */ -+ uint32_t fmqm_dc2; /**< Dequeue Counter 2 0x38 */ -+ uint32_t fmqm_dc3; /**< Dequeue Counter 3 0x3c */ -+ uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter 0x40 */ -+ uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter 0x44 */ -+ uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter 0x48 */ -+ uint32_t fmqm_dcc; /**< Dequeue Confirm Counter 0x4c */ -+ uint32_t res0050[7]; /**< 0x50 - 0x6b */ -+ uint32_t fmqm_tapc; /**< Tnum Aging Period Control 0x6c */ -+ uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter 0x70 */ -+ uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter 0x74 */ -+ uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter 0x78 */ -+ uint32_t res007c; /**< 0x7c */ -+ uint32_t fmqm_dtc; /**< 0x80 Debug Trap Counter 0x80 */ -+ uint32_t fmqm_efddd; /**< 0x84 Enqueue Frame desc Dynamic dbg 0x84 */ -+ uint32_t res0088[2]; /**< 0x88 - 0x8f */ -+ struct { -+ uint32_t fmqm_dtcfg1; /**< 0x90 dbg trap cfg 1 Register 0x00 */ -+ uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register 0x04 */ -+ uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register 0x08 */ -+ uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register 0x0c */ -+ uint32_t fmqm_dtcfg2; /**< dbg Trap cfg 2 Register 0x10 */ -+ uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register 0x14 */ -+ uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register 0x18 */ -+ uint32_t res001c; /**< 0x1c */ -+ } dbg_traps[3]; /**< 0x90 - 0xef */ -+ uint8_t res00f0[0x400 - 0xf0]; /**< 0xf0 - 0x3ff */ -+}; -+ -+struct fman_dma_regs { -+ uint32_t fmdmsr; /**< FM DMA status register 0x00 */ -+ uint32_t fmdmmr; /**< FM DMA mode register 0x04 */ -+ uint32_t fmdmtr; /**< FM DMA bus threshold register 0x08 */ -+ uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x0c */ -+ uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x10 */ -+ uint32_t fmdmtah; /**< FM DMA transfer bus address high reg 0x14 */ -+ uint32_t fmdmtal; /**< FM DMA transfer bus address low reg 0x18 */ -+ uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID reg 0x1c */ -+ uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x20 */ -+ uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x24 */ -+ uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x28 */ -+ uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x2c */ -+ uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug reg 0x30 */ -+ uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value reg #1 0x34 */ -+ uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value reg #2 0x38 */ -+ uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x3c */ -+ uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x40 */ -+ uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x44 */ -+ uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Cntr 0x48 */ -+ uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Cntr 0x4c */ -+ uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x50 */ -+ uint32_t fmdmdcr; /**< FM DMA Debug Counter 0x54 */ -+ uint32_t fmdmemsr; /**< FM DMA Emergency Smoother Register 0x58 */ -+ uint32_t res005c; /**< 0x5c */ -+ uint32_t fmdmplr[FMAN_LIODN_TBL / 2]; /**< DMA LIODN regs 0x60-0xdf */ -+ uint32_t res00e0[0x400 - 56]; -+}; -+ -+struct fman_rg { -+ struct fman_fpm_regs *fpm_rg; -+ struct fman_dma_regs *dma_rg; -+ struct fman_bmi_regs *bmi_rg; -+ struct fman_qmi_regs *qmi_rg; -+}; -+ -+enum fman_dma_cache_override { -+ E_FMAN_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */ -+ E_FMAN_DMA_NO_STASH_DATA, /**< No data stashing in system level cache */ -+ E_FMAN_DMA_MAY_STASH_DATA, /**< Stashing allowed in sys level cache */ -+ E_FMAN_DMA_STASH_DATA /**< Stashing performed in system level cache */ -+}; -+ -+enum fman_dma_aid_mode { -+ E_FMAN_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */ -+ E_FMAN_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */ -+}; -+ -+enum fman_dma_dbg_cnt_mode { -+ E_FMAN_DMA_DBG_NO_CNT = 0, /**< No counting */ -+ E_FMAN_DMA_DBG_CNT_DONE, /**< Count DONE commands */ -+ E_FMAN_DMA_DBG_CNT_COMM_Q_EM, /**< command Q emergency signal */ -+ E_FMAN_DMA_DBG_CNT_INT_READ_EM, /**< Read buf emergency signal */ -+ E_FMAN_DMA_DBG_CNT_INT_WRITE_EM, /**< Write buf emergency signal */ -+ E_FMAN_DMA_DBG_CNT_FPM_WAIT, /**< FPM WAIT signal */ -+ E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors */ -+ E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT /**< RAW & WAR protection counter */ -+}; -+ -+enum fman_dma_emergency_level { -+ E_FMAN_DMA_EM_EBS = 0, /**< EBS emergency */ -+ E_FMAN_DMA_EM_SOS /**< SOS emergency */ -+}; -+ -+enum fman_catastrophic_err { -+ E_FMAN_CATAST_ERR_STALL_PORT = 0, /**< Port_ID stalled reset required */ -+ E_FMAN_CATAST_ERR_STALL_TASK /**< Only erroneous task is stalled */ -+}; -+ -+enum fman_dma_err { -+ E_FMAN_DMA_ERR_CATASTROPHIC = 0, /**< Catastrophic DMA error */ -+ E_FMAN_DMA_ERR_REPORT /**< Reported DMA error */ -+}; -+ -+struct fman_cfg { -+ uint16_t liodn_bs_pr_port[FMAN_LIODN_TBL];/* base per port */ -+ bool en_counters; -+ uint8_t disp_limit_tsh; -+ uint8_t prs_disp_tsh; -+ uint8_t plcr_disp_tsh; -+ uint8_t kg_disp_tsh; -+ uint8_t bmi_disp_tsh; -+ uint8_t qmi_enq_disp_tsh; -+ uint8_t qmi_deq_disp_tsh; -+ uint8_t fm_ctl1_disp_tsh; -+ uint8_t fm_ctl2_disp_tsh; -+ enum fman_dma_cache_override dma_cache_override; -+ enum fman_dma_aid_mode dma_aid_mode; -+ bool dma_aid_override; -+ uint8_t dma_axi_dbg_num_of_beats; -+ uint8_t dma_cam_num_of_entries; -+ uint32_t dma_watchdog; -+ uint8_t dma_comm_qtsh_asrt_emer; -+ uint8_t dma_write_buf_tsh_asrt_emer; -+ uint8_t dma_read_buf_tsh_asrt_emer; -+ uint8_t dma_comm_qtsh_clr_emer; -+ uint8_t dma_write_buf_tsh_clr_emer; -+ uint8_t dma_read_buf_tsh_clr_emer; -+ uint32_t dma_sos_emergency; -+ enum fman_dma_dbg_cnt_mode dma_dbg_cnt_mode; -+ bool dma_stop_on_bus_error; -+ bool dma_en_emergency; -+ uint32_t dma_emergency_bus_select; -+ enum fman_dma_emergency_level dma_emergency_level; -+ bool dma_en_emergency_smoother; -+ uint32_t dma_emergency_switch_counter; -+ bool halt_on_external_activ; -+ bool halt_on_unrecov_ecc_err; -+ enum fman_catastrophic_err catastrophic_err; -+ enum fman_dma_err dma_err; -+ bool en_muram_test_mode; -+ bool en_iram_test_mode; -+ bool external_ecc_rams_enable; -+ uint16_t tnum_aging_period; -+ uint32_t exceptions; -+ uint16_t clk_freq; -+ bool pedantic_dma; -+ uint32_t cam_base_addr; -+ uint32_t fifo_base_addr; -+ uint32_t total_fifo_size; -+ uint8_t total_num_of_tasks; -+ bool qmi_deq_option_support; -+ uint32_t qmi_def_tnums_thresh; -+ bool fman_partition_array; -+ uint8_t num_of_fman_ctrl_evnt_regs; -+}; -+ -+/**************************************************************************//** -+ @Description Exceptions -+*//***************************************************************************/ -+#define FMAN_EX_DMA_BUS_ERROR 0x80000000 -+#define FMAN_EX_DMA_READ_ECC 0x40000000 -+#define FMAN_EX_DMA_SYSTEM_WRITE_ECC 0x20000000 -+#define FMAN_EX_DMA_FM_WRITE_ECC 0x10000000 -+#define FMAN_EX_FPM_STALL_ON_TASKS 0x08000000 -+#define FMAN_EX_FPM_SINGLE_ECC 0x04000000 -+#define FMAN_EX_FPM_DOUBLE_ECC 0x02000000 -+#define FMAN_EX_QMI_SINGLE_ECC 0x01000000 -+#define FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 -+#define FMAN_EX_QMI_DOUBLE_ECC 0x00400000 -+#define FMAN_EX_BMI_LIST_RAM_ECC 0x00200000 -+#define FMAN_EX_BMI_PIPELINE_ECC 0x00100000 -+#define FMAN_EX_BMI_STATISTICS_RAM_ECC 0x00080000 -+#define FMAN_EX_IRAM_ECC 0x00040000 -+#define FMAN_EX_NURAM_ECC 0x00020000 -+#define FMAN_EX_BMI_DISPATCH_RAM_ECC 0x00010000 -+ -+enum fman_exceptions { -+ E_FMAN_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */ -+ E_FMAN_EX_DMA_READ_ECC, /**< Read Buffer ECC error */ -+ E_FMAN_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC err on sys side */ -+ E_FMAN_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */ -+ E_FMAN_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */ -+ E_FMAN_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */ -+ E_FMAN_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */ -+ E_FMAN_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */ -+ E_FMAN_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */ -+ E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< DeQ from unknown port id */ -+ E_FMAN_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */ -+ E_FMAN_EX_BMI_STORAGE_PROFILE_ECC, /**< storage profile */ -+ E_FMAN_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics RAM ECC Err Enable */ -+ E_FMAN_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */ -+ E_FMAN_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/ -+ E_FMAN_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/ -+}; -+ -+enum fman_counters { -+ E_FMAN_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI tot enQ frames counter */ -+ E_FMAN_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI tot deQ frames counter */ -+ E_FMAN_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */ -+ E_FMAN_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */ -+ E_FMAN_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */ -+ E_FMAN_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */ -+ E_FMAN_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI deQ from dflt queue cntr */ -+ E_FMAN_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI deQ from FQ context cntr */ -+ E_FMAN_COUNTERS_DEQ_FROM_FD, /**< QMI deQ from FD command field cntr */ -+ E_FMAN_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */ -+ E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA full entry cntr */ -+ E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA full CAM Q cntr */ -+ E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA sync counter */ -+}; -+ -+#define FPM_PRT_FM_CTL1 0x00000001 -+#define FPM_PRT_FM_CTL2 0x00000002 -+ -+/**************************************************************************//** -+ @Description DMA definitions -+*//***************************************************************************/ -+ -+/* masks */ -+#define DMA_MODE_AID_OR 0x20000000 -+#define DMA_MODE_SBER 0x10000000 -+#define DMA_MODE_BER 0x00200000 -+#define DMA_MODE_EB 0x00100000 -+#define DMA_MODE_ECC 0x00000020 -+#define DMA_MODE_PRIVILEGE_PROT 0x00001000 -+#define DMA_MODE_SECURE_PROT 0x00000800 -+#define DMA_MODE_EMER_READ 0x00080000 -+#define DMA_MODE_EMER_WRITE 0x00040000 -+#define DMA_MODE_CACHE_OR_MASK 0xC0000000 -+#define DMA_MODE_CEN_MASK 0x0000E000 -+#define DMA_MODE_DBG_MASK 0x00000380 -+#define DMA_MODE_AXI_DBG_MASK 0x0F000000 -+ -+#define DMA_EMSR_EMSTR_MASK 0x0000FFFF -+ -+#define DMA_TRANSFER_PORTID_MASK 0xFF000000 -+#define DMA_TRANSFER_TNUM_MASK 0x00FF0000 -+#define DMA_TRANSFER_LIODN_MASK 0x00000FFF -+ -+#define DMA_HIGH_LIODN_MASK 0x0FFF0000 -+#define DMA_LOW_LIODN_MASK 0x00000FFF -+ -+#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000 -+#define DMA_STATUS_BUS_ERR 0x08000000 -+#define DMA_STATUS_READ_ECC 0x04000000 -+#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000 -+#define DMA_STATUS_FM_WRITE_ECC 0x01000000 -+#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000 -+#define DMA_STATUS_FM_DPEXT_ECC 0x00400000 -+#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000 -+#define DMA_STATUS_FM_DPDAT_ECC 0x00100000 -+#define DMA_STATUS_FM_SPDAT_ECC 0x00080000 -+ -+#define FM_LIODN_BASE_MASK 0x00000FFF -+ -+/* shifts */ -+#define DMA_MODE_CACHE_OR_SHIFT 30 -+#define DMA_MODE_BUS_PRI_SHIFT 16 -+#define DMA_MODE_AXI_DBG_SHIFT 24 -+#define DMA_MODE_CEN_SHIFT 13 -+#define DMA_MODE_BUS_PROT_SHIFT 10 -+#define DMA_MODE_DBG_SHIFT 7 -+#define DMA_MODE_EMER_LVL_SHIFT 6 -+#define DMA_MODE_AID_MODE_SHIFT 4 -+#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16 -+#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32 -+ -+#define DMA_THRESH_COMMQ_SHIFT 24 -+#define DMA_THRESH_READ_INT_BUF_SHIFT 16 -+ -+#define DMA_LIODN_SHIFT 16 -+ -+#define DMA_TRANSFER_PORTID_SHIFT 24 -+#define DMA_TRANSFER_TNUM_SHIFT 16 -+ -+/* sizes */ -+#define DMA_MAX_WATCHDOG 0xffffffff -+ -+/* others */ -+#define DMA_CAM_SIZEOF_ENTRY 0x40 -+#define DMA_CAM_ALIGN 0x1000 -+#define DMA_CAM_UNITS 8 -+ -+/**************************************************************************//** -+ @Description General defines -+*//***************************************************************************/ -+ -+#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL -+#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL -+ -+/**************************************************************************//** -+ @Description FPM defines -+*//***************************************************************************/ -+ -+/* masks */ -+#define FPM_EV_MASK_DOUBLE_ECC 0x80000000 -+#define FPM_EV_MASK_STALL 0x40000000 -+#define FPM_EV_MASK_SINGLE_ECC 0x20000000 -+#define FPM_EV_MASK_RELEASE_FM 0x00010000 -+#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000 -+#define FPM_EV_MASK_STALL_EN 0x00004000 -+#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000 -+#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008 -+#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004 -+ -+#define FPM_RAM_RAMS_ECC_EN 0x80000000 -+#define FPM_RAM_IRAM_ECC_EN 0x40000000 -+#define FPM_RAM_MURAM_ECC 0x00008000 -+#define FPM_RAM_IRAM_ECC 0x00004000 -+#define FPM_RAM_MURAM_TEST_ECC 0x20000000 -+#define FPM_RAM_IRAM_TEST_ECC 0x10000000 -+#define FPM_RAM_RAMS_ECC_EN_SRC_SEL 0x08000000 -+ -+#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000 -+#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000 -+ -+#define FPM_REV1_MAJOR_MASK 0x0000FF00 -+#define FPM_REV1_MINOR_MASK 0x000000FF -+ -+#define FPM_REV2_INTEG_MASK 0x00FF0000 -+#define FPM_REV2_ERR_MASK 0x0000FF00 -+#define FPM_REV2_CFG_MASK 0x000000FF -+ -+#define FPM_TS_FRACTION_MASK 0x0000FFFF -+#define FPM_TS_CTL_EN 0x80000000 -+ -+#define FPM_PRC_REALSE_STALLED 0x00800000 -+ -+#define FPM_PS_STALLED 0x00800000 -+#define FPM_PS_FM_CTL1_SEL 0x80000000 -+#define FPM_PS_FM_CTL2_SEL 0x40000000 -+#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL) -+ -+#define FPM_RSTC_FM_RESET 0x80000000 -+#define FPM_RSTC_10G0_RESET 0x04000000 -+#define FPM_RSTC_1G0_RESET 0x40000000 -+#define FPM_RSTC_1G1_RESET 0x20000000 -+#define FPM_RSTC_1G2_RESET 0x10000000 -+#define FPM_RSTC_1G3_RESET 0x08000000 -+#define FPM_RSTC_1G4_RESET 0x02000000 -+ -+ -+#define FPM_DISP_LIMIT_MASK 0x1F000000 -+#define FPM_THR1_PRS_MASK 0xFF000000 -+#define FPM_THR1_KG_MASK 0x00FF0000 -+#define FPM_THR1_PLCR_MASK 0x0000FF00 -+#define FPM_THR1_BMI_MASK 0x000000FF -+ -+#define FPM_THR2_QMI_ENQ_MASK 0xFF000000 -+#define FPM_THR2_QMI_DEQ_MASK 0x000000FF -+#define FPM_THR2_FM_CTL1_MASK 0x00FF0000 -+#define FPM_THR2_FM_CTL2_MASK 0x0000FF00 -+ -+/* shifts */ -+#define FPM_DISP_LIMIT_SHIFT 24 -+ -+#define FPM_THR1_PRS_SHIFT 24 -+#define FPM_THR1_KG_SHIFT 16 -+#define FPM_THR1_PLCR_SHIFT 8 -+#define FPM_THR1_BMI_SHIFT 0 -+ -+#define FPM_THR2_QMI_ENQ_SHIFT 24 -+#define FPM_THR2_QMI_DEQ_SHIFT 0 -+#define FPM_THR2_FM_CTL1_SHIFT 16 -+#define FPM_THR2_FM_CTL2_SHIFT 8 -+ -+#define FPM_EV_MASK_CAT_ERR_SHIFT 1 -+#define FPM_EV_MASK_DMA_ERR_SHIFT 0 -+ -+#define FPM_REV1_MAJOR_SHIFT 8 -+#define FPM_REV1_MINOR_SHIFT 0 -+ -+#define FPM_REV2_INTEG_SHIFT 16 -+#define FPM_REV2_ERR_SHIFT 8 -+#define FPM_REV2_CFG_SHIFT 0 -+ -+#define FPM_TS_INT_SHIFT 16 -+ -+#define FPM_PORT_FM_CTL_PORTID_SHIFT 24 -+ -+#define FPM_PS_FM_CTL_SEL_SHIFT 30 -+#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16 -+ -+#define FPM_DISP_LIMIT_SHIFT 24 -+ -+/* Interrupts defines */ -+#define FPM_EVENT_FM_CTL_0 0x00008000 -+#define FPM_EVENT_FM_CTL 0x0000FF00 -+#define FPM_EVENT_FM_CTL_BRK 0x00000080 -+ -+/* others */ -+#define FPM_MAX_DISP_LIMIT 31 -+#define FPM_RSTC_FM_RESET 0x80000000 -+#define FPM_RSTC_1G0_RESET 0x40000000 -+#define FPM_RSTC_1G1_RESET 0x20000000 -+#define FPM_RSTC_1G2_RESET 0x10000000 -+#define FPM_RSTC_1G3_RESET 0x08000000 -+#define FPM_RSTC_10G0_RESET 0x04000000 -+#define FPM_RSTC_1G4_RESET 0x02000000 -+#define FPM_RSTC_1G5_RESET 0x01000000 -+#define FPM_RSTC_1G6_RESET 0x00800000 -+#define FPM_RSTC_1G7_RESET 0x00400000 -+#define FPM_RSTC_10G1_RESET 0x00200000 -+/**************************************************************************//** -+ @Description BMI defines -+*//***************************************************************************/ -+/* masks */ -+#define BMI_INIT_START 0x80000000 -+#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000 -+#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000 -+#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000 -+#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000 -+#define BMI_NUM_OF_TASKS_MASK 0x3F000000 -+#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000 -+#define BMI_NUM_OF_DMAS_MASK 0x00000F00 -+#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F -+#define BMI_FIFO_SIZE_MASK 0x000003FF -+#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000 -+#define BMI_CFG2_DMAS_MASK 0x0000003F -+#define BMI_TOTAL_FIFO_SIZE_MASK 0x07FF0000 -+#define BMI_TOTAL_NUM_OF_TASKS_MASK 0x007F0000 -+ -+/* shifts */ -+#define BMI_CFG2_TASKS_SHIFT 16 -+#define BMI_CFG2_DMAS_SHIFT 0 -+#define BMI_CFG1_FIFO_SIZE_SHIFT 16 -+#define BMI_FIFO_SIZE_SHIFT 0 -+#define BMI_EXTRA_FIFO_SIZE_SHIFT 16 -+#define BMI_NUM_OF_TASKS_SHIFT 24 -+#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16 -+#define BMI_NUM_OF_DMAS_SHIFT 8 -+#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0 -+ -+/* others */ -+#define BMI_FIFO_ALIGN 0x100 -+#define FMAN_BMI_FIFO_UNITS 0x100 -+ -+ -+/**************************************************************************//** -+ @Description QMI defines -+*//***************************************************************************/ -+/* masks */ -+#define QMI_CFG_ENQ_EN 0x80000000 -+#define QMI_CFG_DEQ_EN 0x40000000 -+#define QMI_CFG_EN_COUNTERS 0x10000000 -+#define QMI_CFG_SOFT_RESET 0x01000000 -+#define QMI_CFG_DEQ_MASK 0x0000003F -+#define QMI_CFG_ENQ_MASK 0x00003F00 -+ -+#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000 -+#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000 -+#define QMI_INTR_EN_SINGLE_ECC 0x80000000 -+ -+/* shifts */ -+#define QMI_CFG_ENQ_SHIFT 8 -+#define QMI_TAPC_TAP 22 -+ -+#define QMI_GS_HALT_NOT_BUSY 0x00000002 -+ -+/**************************************************************************//** -+ @Description IRAM defines -+*//***************************************************************************/ -+/* masks */ -+#define IRAM_IADD_AIE 0x80000000 -+#define IRAM_READY 0x80000000 -+ -+uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg); -+uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg); -+uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg); -+uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg); -+uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg); -+uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg); -+uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg); -+uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg); -+uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg); -+uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg); -+uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, -+ uint8_t event_reg_id); -+uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg); -+uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg); -+uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id); -+uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg); -+uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id); -+uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id); -+uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id); -+uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id); -+uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id); -+uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg); -+uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, -+ uint8_t reg_id); -+uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg); -+void fman_get_revision(struct fman_fpm_regs *fpm_rg, uint8_t *major, -+ uint8_t *minor); -+uint32_t fman_get_counter(struct fman_rg *fman_rg, -+ enum fman_counters reg_name); -+uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg); -+ -+ -+int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg); -+void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id, -+ uint32_t enable_events); -+void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg, -+ uint8_t port_id, -+ uint8_t num_fman_ctrls, -+ uint32_t or_fman_ctrl); -+void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg, -+ uint8_t port_id, -+ bool independent_mode, -+ bool is_rx_port); -+void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val); -+void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val); -+void fman_set_liodn_per_port(struct fman_rg *fman_rg, -+ uint8_t port_id, -+ uint16_t liodn_base, -+ uint16_t liodn_offset); -+void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id, -+ uint32_t size_of_fifo, -+ uint32_t extra_size_of_fifo); -+void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id, -+ uint8_t num_of_tasks, -+ uint8_t num_of_extra_tasks); -+void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id, -+ uint8_t num_of_open_dmas, -+ uint8_t num_of_extra_open_dmas, -+ uint8_t total_num_of_dmas); -+void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights); -+int fman_set_exception(struct fman_rg *fman_rg, -+ enum fman_exceptions exception, -+ bool enable); -+void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, bool is_write, -+ bool enable); -+void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri); -+void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg, -+ uint32_t congestion_group_id, -+ uint8_t piority_bit_map, -+ uint32_t reg_num); -+ -+ -+void fman_defconfig(struct fman_cfg *cfg, bool is_master); -+void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg); -+int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg); -+int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg); -+int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg); -+int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg); -+void fman_free_resources(struct fman_rg *fman_rg); -+int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg); -+void fman_reset(struct fman_fpm_regs *fpm_rg); -+void fman_resume(struct fman_fpm_regs *fpm_rg); -+ -+ -+void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg, -+ uint8_t count1ubit, -+ uint16_t fm_clk_freq); -+void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg); -+void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg); -+void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg); -+void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id); -+int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t macId, bool is_10g); -+bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id); -+bool fman_rams_ecc_is_external_ctl(struct fman_fpm_regs *fpm_rg); -+bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg); -+int fman_modify_counter(struct fman_rg *fman_rg, -+ enum fman_counters reg_name, -+ uint32_t val); -+void fman_force_intr(struct fman_rg *fman_rg, -+ enum fman_exceptions exception); -+void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg, -+ uint8_t port_id, -+ uint8_t base_storage_profile, -+ uint8_t log2_num_of_profiles); -+ -+/**************************************************************************//** -+ @Description default values -+*//***************************************************************************/ -+#define DEFAULT_CATASTROPHIC_ERR E_FMAN_CATAST_ERR_STALL_PORT -+#define DEFAULT_DMA_ERR E_FMAN_DMA_ERR_CATASTROPHIC -+#define DEFAULT_HALT_ON_EXTERNAL_ACTIVATION FALSE /* do not change! if changed, must be disabled for rev1 ! */ -+#define DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR FALSE /* do not change! if changed, must be disabled for rev1 ! */ -+#define DEFAULT_EXTERNAL_ECC_RAMS_ENABLE FALSE -+#define DEFAULT_AID_OVERRIDE FALSE -+#define DEFAULT_AID_MODE E_FMAN_DMA_AID_OUT_TNUM -+#define DEFAULT_DMA_COMM_Q_LOW 0x2A -+#define DEFAULT_DMA_COMM_Q_HIGH 0x3F -+#define DEFAULT_CACHE_OVERRIDE E_FMAN_DMA_NO_CACHE_OR -+#define DEFAULT_DMA_CAM_NUM_OF_ENTRIES 64 -+#define DEFAULT_DMA_DBG_CNT_MODE E_FMAN_DMA_DBG_NO_CNT -+#define DEFAULT_DMA_EN_EMERGENCY FALSE -+#define DEFAULT_DMA_SOS_EMERGENCY 0 -+#define DEFAULT_DMA_WATCHDOG 0 /* disabled */ -+#define DEFAULT_DMA_EN_EMERGENCY_SMOOTHER FALSE -+#define DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER 0 -+#define DEFAULT_DISP_LIMIT 0 -+#define DEFAULT_PRS_DISP_TH 16 -+#define DEFAULT_PLCR_DISP_TH 16 -+#define DEFAULT_KG_DISP_TH 16 -+#define DEFAULT_BMI_DISP_TH 16 -+#define DEFAULT_QMI_ENQ_DISP_TH 16 -+#define DEFAULT_QMI_DEQ_DISP_TH 16 -+#define DEFAULT_FM_CTL1_DISP_TH 16 -+#define DEFAULT_FM_CTL2_DISP_TH 16 -+#define DEFAULT_TNUM_AGING_PERIOD 4 -+ -+ -+#endif /* __FSL_FMAN_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h -@@ -0,0 +1,1096 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __FSL_FMAN_DTSEC_H -+#define __FSL_FMAN_DTSEC_H -+ -+#include "common/general.h" -+#include "fsl_enet.h" -+ -+/** -+ * DOC: dTSEC Init sequence -+ * -+ * To prepare dTSEC block for transfer use the following call sequence: -+ * -+ * - fman_dtsec_defconfig() - This step is optional and yet recommended. Its -+ * use is to obtain the default dTSEC configuration parameters. -+ * -+ * - Change dtsec configuration in &dtsec_cfg. This structure will be used -+ * to customize the dTSEC behavior. -+ * -+ * - fman_dtsec_init() - Applies the configuration on dTSEC hardware. Note that -+ * dTSEC is initialized while both Tx and Rx are disabled. -+ * -+ * - fman_dtsec_set_mac_address() - Set the station address (mac address). -+ * This is used by dTSEC to match against received packets. -+ * -+ * - fman_dtsec_adjust_link() - Set the link speed and duplex parameters -+ * after the PHY establishes the link. -+ * -+ * - dtsec_enable_tx() and dtsec_enable_rx() to enable transmission and -+ * reception. -+ */ -+ -+/** -+ * DOC: dTSEC Graceful stop -+ * -+ * To temporary stop dTSEC activity use fman_dtsec_stop_tx() and -+ * fman_dtsec_stop_rx(). Note that these functions request dTSEC graceful stop -+ * but return before this stop is complete. To query for graceful stop -+ * completion use fman_dtsec_get_event() and check DTSEC_IEVENT_GTSC and -+ * DTSEC_IEVENT_GRSC bits. Alternatively the dTSEC interrupt mask can be set to -+ * enable graceful stop interrupts. -+ * -+ * To resume operation after graceful stop use fman_dtsec_start_tx() and -+ * fman_dtsec_start_rx(). -+ */ -+ -+/** -+ * DOC: dTSEC interrupt handling -+ * -+ * This code does not provide an interrupt handler for dTSEC. Instead this -+ * handler should be implemented and registered to the operating system by the -+ * caller. Some primitives for accessing the event status and mask registers -+ * are provided. -+ * -+ * See "dTSEC Events" section for a list of events that dTSEC can generate. -+ */ -+ -+/** -+ * DOC: dTSEC Events -+ * -+ * Interrupt events cause dTSEC event bits to be set. Software may poll the -+ * event register at any time to check for pending interrupts. If an event -+ * occurs and its corresponding enable bit is set in the interrupt mask -+ * register, the event also causes a hardware interrupt at the PIC. -+ * -+ * To poll for event status use the fman_dtsec_get_event() function. -+ * To configure the interrupt mask use fman_dtsec_enable_interrupt() and -+ * fman_dtsec_disable_interrupt() functions. -+ * After servicing a dTSEC interrupt use fman_dtsec_ack_event to reset the -+ * serviced event bit. -+ * -+ * The following events may be signaled by dTSEC hardware: -+ * -+ * %DTSEC_IEVENT_BABR - Babbling receive error. This bit indicates that -+ * a frame was received with length in excess of the MAC's maximum frame length -+ * register. -+ * -+ * %DTSEC_IEVENT_RXC - Receive control (pause frame) interrupt. A pause -+ * control frame was received while Rx pause frame handling is enabled. -+ * Also see fman_dtsec_handle_rx_pause(). -+ * -+ * %DTSEC_IEVENT_MSRO - MIB counter overflow. The count for one of the MIB -+ * counters has exceeded the size of its register. -+ * -+ * %DTSEC_IEVENT_GTSC - Graceful transmit stop complete. Graceful stop is now -+ * complete. The transmitter is in a stopped state, in which only pause frames -+ * can be transmitted. -+ * Also see fman_dtsec_stop_tx(). -+ * -+ * %DTSEC_IEVENT_BABT - Babbling transmit error. The transmitted frame length -+ * has exceeded the value in the MAC's Maximum Frame Length register. -+ * -+ * %DTSEC_IEVENT_TXC - Transmit control (pause frame) interrupt. his bit -+ * indicates that a control frame was transmitted. -+ * -+ * %DTSEC_IEVENT_TXE - Transmit error. This bit indicates that an error -+ * occurred on the transmitted channel. This bit is set whenever any transmit -+ * error occurs which causes the dTSEC to discard all or part of a frame -+ * (LC, CRL, XFUN). -+ * -+ * %DTSEC_IEVENT_LC - Late collision. This bit indicates that a collision -+ * occurred beyond the collision window (slot time) in half-duplex mode. -+ * The frame is truncated with a bad CRC and the remainder of the frame -+ * is discarded. -+ * -+ * %DTSEC_IEVENT_CRL - Collision retry limit. is bit indicates that the number -+ * of successive transmission collisions has exceeded the MAC's half-duplex -+ * register's retransmission maximum count. The frame is discarded without -+ * being transmitted and transmission of the next frame commences. This only -+ * occurs while in half-duplex mode. -+ * The number of retransmit attempts can be set in -+ * &dtsec_halfdup_cfg.@retransmit before calling fman_dtsec_init(). -+ * -+ * %DTSEC_IEVENT_XFUN - Transmit FIFO underrun. This bit indicates that the -+ * transmit FIFO became empty before the complete frame was transmitted. -+ * The frame is truncated with a bad CRC and the remainder of the frame is -+ * discarded. -+ * -+ * %DTSEC_IEVENT_MAG - TBD -+ * -+ * %DTSEC_IEVENT_MMRD - MII management read completion. -+ * -+ * %DTSEC_IEVENT_MMWR - MII management write completion. -+ * -+ * %DTSEC_IEVENT_GRSC - Graceful receive stop complete. It allows the user to -+ * know if the system has completed the stop and it is safe to write to receive -+ * registers (status, control or configuration registers) that are used by the -+ * system during normal operation. -+ * -+ * %DTSEC_IEVENT_TDPE - Internal data error on transmit. This bit indicates -+ * that the dTSEC has detected a parity error on its stored transmit data, which -+ * is likely to compromise the validity of recently transferred frames. -+ * -+ * %DTSEC_IEVENT_RDPE - Internal data error on receive. This bit indicates that -+ * the dTSEC has detected a parity error on its stored receive data, which is -+ * likely to compromise the validity of recently transferred frames. -+ */ -+/* Interrupt Mask Register (IMASK) */ -+#define DTSEC_IMASK_BREN 0x80000000 -+#define DTSEC_IMASK_RXCEN 0x40000000 -+#define DTSEC_IMASK_MSROEN 0x04000000 -+#define DTSEC_IMASK_GTSCEN 0x02000000 -+#define DTSEC_IMASK_BTEN 0x01000000 -+#define DTSEC_IMASK_TXCEN 0x00800000 -+#define DTSEC_IMASK_TXEEN 0x00400000 -+#define DTSEC_IMASK_LCEN 0x00040000 -+#define DTSEC_IMASK_CRLEN 0x00020000 -+#define DTSEC_IMASK_XFUNEN 0x00010000 -+#define DTSEC_IMASK_ABRTEN 0x00008000 -+#define DTSEC_IMASK_IFERREN 0x00004000 -+#define DTSEC_IMASK_MAGEN 0x00000800 -+#define DTSEC_IMASK_MMRDEN 0x00000400 -+#define DTSEC_IMASK_MMWREN 0x00000200 -+#define DTSEC_IMASK_GRSCEN 0x00000100 -+#define DTSEC_IMASK_TDPEEN 0x00000002 -+#define DTSEC_IMASK_RDPEEN 0x00000001 -+ -+#define DTSEC_EVENTS_MASK \ -+ ((uint32_t)(DTSEC_IMASK_BREN | \ -+ DTSEC_IMASK_RXCEN | \ -+ DTSEC_IMASK_BTEN | \ -+ DTSEC_IMASK_TXCEN | \ -+ DTSEC_IMASK_TXEEN | \ -+ DTSEC_IMASK_ABRTEN | \ -+ DTSEC_IMASK_LCEN | \ -+ DTSEC_IMASK_CRLEN | \ -+ DTSEC_IMASK_XFUNEN | \ -+ DTSEC_IMASK_IFERREN | \ -+ DTSEC_IMASK_MAGEN | \ -+ DTSEC_IMASK_TDPEEN | \ -+ DTSEC_IMASK_RDPEEN)) -+ -+/* dtsec timestamp event bits */ -+#define TMR_PEMASK_TSREEN 0x00010000 -+#define TMR_PEVENT_TSRE 0x00010000 -+ -+/* Group address bit indication */ -+#define MAC_GROUP_ADDRESS 0x0000010000000000ULL -+/* size in bytes of L2 address */ -+#define MAC_ADDRLEN 6 -+ -+#define DEFAULT_HALFDUP_ON FALSE -+#define DEFAULT_HALFDUP_RETRANSMIT 0xf -+#define DEFAULT_HALFDUP_COLL_WINDOW 0x37 -+#define DEFAULT_HALFDUP_EXCESS_DEFER TRUE -+#define DEFAULT_HALFDUP_NO_BACKOFF FALSE -+#define DEFAULT_HALFDUP_BP_NO_BACKOFF FALSE -+#define DEFAULT_HALFDUP_ALT_BACKOFF_VAL 0x0A -+#define DEFAULT_HALFDUP_ALT_BACKOFF_EN FALSE -+#define DEFAULT_RX_DROP_BCAST FALSE -+#define DEFAULT_RX_SHORT_FRM TRUE -+#define DEFAULT_RX_LEN_CHECK FALSE -+#define DEFAULT_TX_PAD_CRC TRUE -+#define DEFAULT_TX_CRC FALSE -+#define DEFAULT_RX_CTRL_ACC FALSE -+#define DEFAULT_TX_PAUSE_TIME 0xf000 -+#define DEFAULT_TBIPA 5 -+#define DEFAULT_RX_PREPEND 0 -+#define DEFAULT_PTP_TSU_EN TRUE -+#define DEFAULT_PTP_EXCEPTION_EN TRUE -+#define DEFAULT_PREAMBLE_LEN 7 -+#define DEFAULT_RX_PREAMBLE FALSE -+#define DEFAULT_TX_PREAMBLE FALSE -+#define DEFAULT_LOOPBACK FALSE -+#define DEFAULT_RX_TIME_STAMP_EN FALSE -+#define DEFAULT_TX_TIME_STAMP_EN FALSE -+#define DEFAULT_RX_FLOW TRUE -+#define DEFAULT_TX_FLOW TRUE -+#define DEFAULT_RX_GROUP_HASH_EXD FALSE -+#define DEFAULT_TX_PAUSE_TIME_EXTD 0 -+#define DEFAULT_RX_PROMISC FALSE -+#define DEFAULT_NON_BACK_TO_BACK_IPG1 0x40 -+#define DEFAULT_NON_BACK_TO_BACK_IPG2 0x60 -+#define DEFAULT_MIN_IFG_ENFORCEMENT 0x50 -+#define DEFAULT_BACK_TO_BACK_IPG 0x60 -+#define DEFAULT_MAXIMUM_FRAME 0x600 -+#define DEFAULT_TBI_PHY_ADDR 5 -+#define DEFAULT_WAKE_ON_LAN FALSE -+ -+/* register related defines (bits, field offsets..) */ -+#define DTSEC_ID1_ID 0xffff0000 -+#define DTSEC_ID1_REV_MJ 0x0000FF00 -+#define DTSEC_ID1_REV_MN 0x000000ff -+ -+#define DTSEC_ID2_INT_REDUCED_OFF 0x00010000 -+#define DTSEC_ID2_INT_NORMAL_OFF 0x00020000 -+ -+#define DTSEC_ECNTRL_CLRCNT 0x00004000 -+#define DTSEC_ECNTRL_AUTOZ 0x00002000 -+#define DTSEC_ECNTRL_STEN 0x00001000 -+#define DTSEC_ECNTRL_CFG_RO 0x80000000 -+#define DTSEC_ECNTRL_GMIIM 0x00000040 -+#define DTSEC_ECNTRL_TBIM 0x00000020 -+#define DTSEC_ECNTRL_SGMIIM 0x00000002 -+#define DTSEC_ECNTRL_RPM 0x00000010 -+#define DTSEC_ECNTRL_R100M 0x00000008 -+#define DTSEC_ECNTRL_RMM 0x00000004 -+#define DTSEC_ECNTRL_QSGMIIM 0x00000001 -+ -+#define DTSEC_TCTRL_THDF 0x00000800 -+#define DTSEC_TCTRL_TTSE 0x00000040 -+#define DTSEC_TCTRL_GTS 0x00000020 -+#define DTSEC_TCTRL_TFC_PAUSE 0x00000010 -+ -+/* PTV offsets */ -+#define PTV_PTE_OFST 16 -+ -+#define RCTRL_CFA 0x00008000 -+#define RCTRL_GHTX 0x00000400 -+#define RCTRL_RTSE 0x00000040 -+#define RCTRL_GRS 0x00000020 -+#define RCTRL_BC_REJ 0x00000010 -+#define RCTRL_MPROM 0x00000008 -+#define RCTRL_RSF 0x00000004 -+#define RCTRL_UPROM 0x00000001 -+#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM) -+ -+#define TMR_CTL_ESFDP 0x00000800 -+#define TMR_CTL_ESFDE 0x00000400 -+ -+#define MACCFG1_SOFT_RESET 0x80000000 -+#define MACCFG1_LOOPBACK 0x00000100 -+#define MACCFG1_RX_FLOW 0x00000020 -+#define MACCFG1_TX_FLOW 0x00000010 -+#define MACCFG1_TX_EN 0x00000001 -+#define MACCFG1_RX_EN 0x00000004 -+#define MACCFG1_RESET_RxMC 0x00080000 -+#define MACCFG1_RESET_TxMC 0x00040000 -+#define MACCFG1_RESET_RxFUN 0x00020000 -+#define MACCFG1_RESET_TxFUN 0x00010000 -+ -+#define MACCFG2_NIBBLE_MODE 0x00000100 -+#define MACCFG2_BYTE_MODE 0x00000200 -+#define MACCFG2_PRE_AM_Rx_EN 0x00000080 -+#define MACCFG2_PRE_AM_Tx_EN 0x00000040 -+#define MACCFG2_LENGTH_CHECK 0x00000010 -+#define MACCFG2_MAGIC_PACKET_EN 0x00000008 -+#define MACCFG2_PAD_CRC_EN 0x00000004 -+#define MACCFG2_CRC_EN 0x00000002 -+#define MACCFG2_FULL_DUPLEX 0x00000001 -+ -+#define PREAMBLE_LENGTH_SHIFT 12 -+ -+#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24 -+#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16 -+#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8 -+ -+#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000 -+#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000 -+#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00 -+#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F -+ -+#define HAFDUP_ALT_BEB 0x00080000 -+#define HAFDUP_BP_NO_BACKOFF 0x00040000 -+#define HAFDUP_NO_BACKOFF 0x00020000 -+#define HAFDUP_EXCESS_DEFER 0x00010000 -+#define HAFDUP_COLLISION_WINDOW 0x000003ff -+ -+#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20 -+#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12 -+#define HAFDUP_RETRANSMISSION_MAX 0x0000f000 -+ -+#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */ -+ -+/* CAR1/2 bits */ -+#define DTSEC_CAR1_TR64 0x80000000 -+#define DTSEC_CAR1_TR127 0x40000000 -+#define DTSEC_CAR1_TR255 0x20000000 -+#define DTSEC_CAR1_TR511 0x10000000 -+#define DTSEC_CAR1_TRK1 0x08000000 -+#define DTSEC_CAR1_TRMAX 0x04000000 -+#define DTSEC_CAR1_TRMGV 0x02000000 -+ -+#define DTSEC_CAR1_RBYT 0x00010000 -+#define DTSEC_CAR1_RPKT 0x00008000 -+#define DTSEC_CAR1_RFCS 0x00004000 -+#define DTSEC_CAR1_RMCA 0x00002000 -+#define DTSEC_CAR1_RBCA 0x00001000 -+#define DTSEC_CAR1_RXCF 0x00000800 -+#define DTSEC_CAR1_RXPF 0x00000400 -+#define DTSEC_CAR1_RXUO 0x00000200 -+#define DTSEC_CAR1_RALN 0x00000100 -+#define DTSEC_CAR1_RFLR 0x00000080 -+#define DTSEC_CAR1_RCDE 0x00000040 -+#define DTSEC_CAR1_RCSE 0x00000020 -+#define DTSEC_CAR1_RUND 0x00000010 -+#define DTSEC_CAR1_ROVR 0x00000008 -+#define DTSEC_CAR1_RFRG 0x00000004 -+#define DTSEC_CAR1_RJBR 0x00000002 -+#define DTSEC_CAR1_RDRP 0x00000001 -+ -+#define DTSEC_CAR2_TJBR 0x00080000 -+#define DTSEC_CAR2_TFCS 0x00040000 -+#define DTSEC_CAR2_TXCF 0x00020000 -+#define DTSEC_CAR2_TOVR 0x00010000 -+#define DTSEC_CAR2_TUND 0x00008000 -+#define DTSEC_CAR2_TFRG 0x00004000 -+#define DTSEC_CAR2_TBYT 0x00002000 -+#define DTSEC_CAR2_TPKT 0x00001000 -+#define DTSEC_CAR2_TMCA 0x00000800 -+#define DTSEC_CAR2_TBCA 0x00000400 -+#define DTSEC_CAR2_TXPF 0x00000200 -+#define DTSEC_CAR2_TDFR 0x00000100 -+#define DTSEC_CAR2_TEDF 0x00000080 -+#define DTSEC_CAR2_TSCL 0x00000040 -+#define DTSEC_CAR2_TMCL 0x00000020 -+#define DTSEC_CAR2_TLCL 0x00000010 -+#define DTSEC_CAR2_TXCL 0x00000008 -+#define DTSEC_CAR2_TNCL 0x00000004 -+#define DTSEC_CAR2_TDRP 0x00000001 -+ -+#define CAM1_ERRORS_ONLY \ -+ (DTSEC_CAR1_RXPF | DTSEC_CAR1_RALN | DTSEC_CAR1_RFLR \ -+ | DTSEC_CAR1_RCDE | DTSEC_CAR1_RCSE | DTSEC_CAR1_RUND \ -+ | DTSEC_CAR1_ROVR | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \ -+ | DTSEC_CAR1_RDRP) -+ -+#define CAM2_ERRORS_ONLY (DTSEC_CAR2_TFCS | DTSEC_CAR2_TXPF | DTSEC_CAR2_TDRP) -+ -+/* -+ * Group of dTSEC specific counters relating to the standard RMON MIB Group 1 -+ * (or Ethernet) statistics. -+ */ -+#define CAM1_MIB_GRP_1 \ -+ (DTSEC_CAR1_RDRP | DTSEC_CAR1_RBYT | DTSEC_CAR1_RPKT | DTSEC_CAR1_RMCA\ -+ | DTSEC_CAR1_RBCA | DTSEC_CAR1_RALN | DTSEC_CAR1_RUND | DTSEC_CAR1_ROVR\ -+ | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \ -+ | DTSEC_CAR1_TR64 | DTSEC_CAR1_TR127 | DTSEC_CAR1_TR255 \ -+ | DTSEC_CAR1_TR511 | DTSEC_CAR1_TRMAX) -+ -+#define CAM2_MIB_GRP_1 (DTSEC_CAR2_TNCL | DTSEC_CAR2_TDRP) -+ -+/* memory map */ -+ -+struct dtsec_regs { -+ /* dTSEC General Control and Status Registers */ -+ uint32_t tsec_id; /* 0x000 ETSEC_ID register */ -+ uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */ -+ uint32_t ievent; /* 0x008 Interrupt event register */ -+ uint32_t imask; /* 0x00C Interrupt mask register */ -+ uint32_t reserved0010[1]; -+ uint32_t ecntrl; /* 0x014 E control register */ -+ uint32_t ptv; /* 0x018 Pause time value register */ -+ uint32_t tbipa; /* 0x01C TBI PHY address register */ -+ uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */ -+ uint32_t tmr_pevent; /* 0x024 Time-stamp event register */ -+ uint32_t tmr_pemask; /* 0x028 Timer event mask register */ -+ uint32_t reserved002c[5]; -+ uint32_t tctrl; /* 0x040 Transmit control register */ -+ uint32_t reserved0044[3]; -+ uint32_t rctrl; /* 0x050 Receive control register */ -+ uint32_t reserved0054[11]; -+ uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address */ -+ uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */ -+ uint32_t reserved00c0[16]; -+ uint32_t maccfg1; /* 0x100 MAC configuration #1 */ -+ uint32_t maccfg2; /* 0x104 MAC configuration #2 */ -+ uint32_t ipgifg; /* 0x108 IPG/IFG */ -+ uint32_t hafdup; /* 0x10C Half-duplex */ -+ uint32_t maxfrm; /* 0x110 Maximum frame */ -+ uint32_t reserved0114[10]; -+ uint32_t ifstat; /* 0x13C Interface status */ -+ uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */ -+ uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */ -+ struct { -+ uint32_t exact_match1; /* octets 1-4 */ -+ uint32_t exact_match2; /* octets 5-6 */ -+ } macaddr[15]; /* 0x148-0x1BC mac exact match addresses 1-15 */ -+ uint32_t reserved01c0[16]; -+ uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */ -+ uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame -+ * counter */ -+ uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame -+ * counter */ -+ uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame -+ * counter */ -+ uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame -+ * counter */ -+ uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame -+ * counter */ -+ uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good -+ * VLAN frame count */ -+ uint32_t rbyt; /* 0x21C receive byte counter */ -+ uint32_t rpkt; /* 0x220 receive packet counter */ -+ uint32_t rfcs; /* 0x224 receive FCS error counter */ -+ uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */ -+ uint32_t rbca; /* 0x22C receive broadcast packet counter */ -+ uint32_t rxcf; /* 0x230 receive control frame packet counter */ -+ uint32_t rxpf; /* 0x234 receive pause frame packet counter */ -+ uint32_t rxuo; /* 0x238 receive unknown OP code counter */ -+ uint32_t raln; /* 0x23C receive alignment error counter */ -+ uint32_t rflr; /* 0x240 receive frame length error counter */ -+ uint32_t rcde; /* 0x244 receive code error counter */ -+ uint32_t rcse; /* 0x248 receive carrier sense error counter */ -+ uint32_t rund; /* 0x24C receive undersize packet counter */ -+ uint32_t rovr; /* 0x250 receive oversize packet counter */ -+ uint32_t rfrg; /* 0x254 receive fragments counter */ -+ uint32_t rjbr; /* 0x258 receive jabber counter */ -+ uint32_t rdrp; /* 0x25C receive drop */ -+ uint32_t tbyt; /* 0x260 transmit byte counter */ -+ uint32_t tpkt; /* 0x264 transmit packet counter */ -+ uint32_t tmca; /* 0x268 transmit multicast packet counter */ -+ uint32_t tbca; /* 0x26C transmit broadcast packet counter */ -+ uint32_t txpf; /* 0x270 transmit pause control frame counter */ -+ uint32_t tdfr; /* 0x274 transmit deferral packet counter */ -+ uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */ -+ uint32_t tscl; /* 0x27C transmit single collision packet counter */ -+ uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */ -+ uint32_t tlcl; /* 0x284 transmit late collision packet counter */ -+ uint32_t txcl; /* 0x288 transmit excessive collision packet counter */ -+ uint32_t tncl; /* 0x28C transmit total collision counter */ -+ uint32_t reserved0290[1]; -+ uint32_t tdrp; /* 0x294 transmit drop frame counter */ -+ uint32_t tjbr; /* 0x298 transmit jabber frame counter */ -+ uint32_t tfcs; /* 0x29C transmit FCS error counter */ -+ uint32_t txcf; /* 0x2A0 transmit control frame counter */ -+ uint32_t tovr; /* 0x2A4 transmit oversize frame counter */ -+ uint32_t tund; /* 0x2A8 transmit undersize frame counter */ -+ uint32_t tfrg; /* 0x2AC transmit fragments frame counter */ -+ uint32_t car1; /* 0x2B0 carry register one register* */ -+ uint32_t car2; /* 0x2B4 carry register two register* */ -+ uint32_t cam1; /* 0x2B8 carry register one mask register */ -+ uint32_t cam2; /* 0x2BC carry register two mask register */ -+ uint32_t reserved02c0[848]; -+}; -+ -+/** -+ * struct dtsec_mib_grp_1_counters - MIB counter overflows -+ * -+ * @tr64: Transmit and Receive 64 byte frame count. Increment for each -+ * good or bad frame, of any type, transmitted or received, which -+ * is 64 bytes in length. -+ * @tr127: Transmit and Receive 65 to 127 byte frame count. Increments for -+ * each good or bad frame of any type, transmitted or received, -+ * which is 65-127 bytes in length. -+ * @tr255: Transmit and Receive 128 to 255 byte frame count. Increments -+ * for each good or bad frame, of any type, transmitted or -+ * received, which is 128-255 bytes in length. -+ * @tr511: Transmit and Receive 256 to 511 byte frame count. Increments -+ * for each good or bad frame, of any type, transmitted or -+ * received, which is 256-511 bytes in length. -+ * @tr1k: Transmit and Receive 512 to 1023 byte frame count. Increments -+ * for each good or bad frame, of any type, transmitted or -+ * received, which is 512-1023 bytes in length. -+ * @trmax: Transmit and Receive 1024 to 1518 byte frame count. Increments -+ * for each good or bad frame, of any type, transmitted or -+ * received, which is 1024-1518 bytes in length. -+ * @rfrg: Receive fragments count. Increments for each received frame -+ * which is less than 64 bytes in length and contains an invalid -+ * FCS. This includes integral and non-integral lengths. -+ * @rjbr: Receive jabber count. Increments for received frames which -+ * exceed 1518 (non VLAN) or 1522 (VLAN) bytes and contain an -+ * invalid FCS. This includes alignment errors. -+ * @rdrp: Receive dropped packets count. Increments for received frames -+ * which are streamed to system but are later dropped due to lack -+ * of system resources. Does not increment for frames rejected due -+ * to address filtering. -+ * @raln: Receive alignment error count. Increments for each received -+ * frame from 64 to 1518 (non VLAN) or 1522 (VLAN) which contains -+ * an invalid FCS and is not an integral number of bytes. -+ * @rund: Receive undersize packet count. Increments each time a frame is -+ * received which is less than 64 bytes in length and contains a -+ * valid FCS and is otherwise well formed. This count does not -+ * include range length errors. -+ * @rovr: Receive oversize packet count. Increments each time a frame is -+ * received which exceeded 1518 (non VLAN) or 1522 (VLAN) and -+ * contains a valid FCS and is otherwise well formed. -+ * @rbyt: Receive byte count. Increments by the byte count of frames -+ * received, including those in bad packets, excluding preamble and -+ * SFD but including FCS bytes. -+ * @rpkt: Receive packet count. Increments for each received frame -+ * (including bad packets, all unicast, broadcast, and multicast -+ * packets). -+ * @rmca: Receive multicast packet count. Increments for each multicast -+ * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or -+ * 1522 (VLAN), excluding broadcast frames. This count does not -+ * include range/length errors. -+ * @rbca: Receive broadcast packet count. Increments for each broadcast -+ * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or -+ * 1522 (VLAN), excluding multicast frames. Does not include -+ * range/length errors. -+ * @tdrp: Transmit drop frame count. Increments each time a memory error -+ * or an underrun has occurred. -+ * @tncl: Transmit total collision counter. Increments by the number of -+ * collisions experienced during the transmission of a frame. Does -+ * not increment for aborted frames. -+ * -+ * The structure contains a group of dTSEC HW specific counters relating to the -+ * standard RMON MIB Group 1 (or Ethernet statistics) counters. This structure -+ * is counting only the carry events of the corresponding HW counters. -+ * -+ * tr64 to trmax notes: Frame sizes specified are considered excluding preamble -+ * and SFD but including FCS bytes. -+ */ -+struct dtsec_mib_grp_1_counters { -+ uint64_t rdrp; -+ uint64_t tdrp; -+ uint64_t rbyt; -+ uint64_t rpkt; -+ uint64_t rbca; -+ uint64_t rmca; -+ uint64_t raln; -+ uint64_t rund; -+ uint64_t rovr; -+ uint64_t rfrg; -+ uint64_t rjbr; -+ uint64_t tncl; -+ uint64_t tr64; -+ uint64_t tr127; -+ uint64_t tr255; -+ uint64_t tr511; -+ uint64_t tr1k; -+ uint64_t trmax; -+}; -+ -+enum dtsec_stat_counters { -+ E_DTSEC_STAT_TR64, -+ E_DTSEC_STAT_TR127, -+ E_DTSEC_STAT_TR255, -+ E_DTSEC_STAT_TR511, -+ E_DTSEC_STAT_TR1K, -+ E_DTSEC_STAT_TRMAX, -+ E_DTSEC_STAT_TRMGV, -+ E_DTSEC_STAT_RBYT, -+ E_DTSEC_STAT_RPKT, -+ E_DTSEC_STAT_RMCA, -+ E_DTSEC_STAT_RBCA, -+ E_DTSEC_STAT_RXPF, -+ E_DTSEC_STAT_RALN, -+ E_DTSEC_STAT_RFLR, -+ E_DTSEC_STAT_RCDE, -+ E_DTSEC_STAT_RCSE, -+ E_DTSEC_STAT_RUND, -+ E_DTSEC_STAT_ROVR, -+ E_DTSEC_STAT_RFRG, -+ E_DTSEC_STAT_RJBR, -+ E_DTSEC_STAT_RDRP, -+ E_DTSEC_STAT_TFCS, -+ E_DTSEC_STAT_TBYT, -+ E_DTSEC_STAT_TPKT, -+ E_DTSEC_STAT_TMCA, -+ E_DTSEC_STAT_TBCA, -+ E_DTSEC_STAT_TXPF, -+ E_DTSEC_STAT_TNCL, -+ E_DTSEC_STAT_TDRP -+}; -+ -+enum dtsec_stat_level { -+ /* No statistics */ -+ E_MAC_STAT_NONE = 0, -+ /* Only RMON MIB group 1 (ether stats). Optimized for performance */ -+ E_MAC_STAT_MIB_GRP1, -+ /* Only error counters are available. Optimized for performance */ -+ E_MAC_STAT_PARTIAL, -+ /* All counters available. Not optimized for performance */ -+ E_MAC_STAT_FULL -+}; -+ -+ -+/** -+ * struct dtsec_cfg - dTSEC configuration -+ * -+ * @halfdup_on: Transmit half-duplex flow control, under software -+ * control for 10/100-Mbps half-duplex media. If set, -+ * back pressure is applied to media by raising carrier. -+ * @halfdup_retransmit: Number of retransmission attempts following a collision. -+ * If this is exceeded dTSEC aborts transmission due to -+ * excessive collisions. The standard specifies the -+ * attempt limit to be 15. -+ * @halfdup_coll_window:The number of bytes of the frame during which -+ * collisions may occur. The default value of 55 -+ * corresponds to the frame byte at the end of the -+ * standard 512-bit slot time window. If collisions are -+ * detected after this byte, the late collision event is -+ * asserted and transmission of current frame is aborted. -+ * @rx_drop_bcast: Discard broadcast frames. If set, all broadcast frames -+ * will be discarded by dTSEC. -+ * @rx_short_frm: Accept short frames. If set, dTSEC will accept frames -+ * of length 14..63 bytes. -+ * @rx_len_check: Length check for received frames. If set, the MAC -+ * checks the frame's length field on receive to ensure it -+ * matches the actual data field length. This only works -+ * for received frames with length field less than 1500. -+ * No check is performed for larger frames. -+ * @tx_pad_crc: Pad and append CRC. If set, the MAC pads all -+ * transmitted short frames and appends a CRC to every -+ * frame regardless of padding requirement. -+ * @tx_crc: Transmission CRC enable. If set, the MAC appends a CRC -+ * to all frames. If frames presented to the MAC have a -+ * valid length and contain a valid CRC, @tx_crc should be -+ * reset. -+ * This field is ignored if @tx_pad_crc is set. -+ * @rx_ctrl_acc: Control frame accept. If set, this overrides 802.3 -+ * standard control frame behavior, and all Ethernet frames -+ * that have an ethertype of 0x8808 are treated as normal -+ * Ethernet frames and passed up to the packet interface on -+ * a DA match. Received pause control frames are passed to -+ * the packet interface only if Rx flow control is also -+ * disabled. See fman_dtsec_handle_rx_pause() function. -+ * @tx_pause_time: Transmit pause time value. This pause value is used as -+ * part of the pause frame to be sent when a transmit pause -+ * frame is initiated. If set to 0 this disables -+ * transmission of pause frames. -+ * @rx_preamble: Receive preamble enable. If set, the MAC recovers the -+ * received Ethernet 7-byte preamble and passes it to the -+ * packet interface at the start of each received frame. -+ * This field should be reset for internal MAC loop-back -+ * mode. -+ * @tx_preamble: User defined preamble enable for transmitted frames. -+ * If set, a user-defined preamble must passed to the MAC -+ * and it is transmitted instead of the standard preamble. -+ * @preamble_len: Length, in bytes, of the preamble field preceding each -+ * Ethernet start-of-frame delimiter byte. The default -+ * value of 0x7 should be used in order to guarantee -+ * reliable operation with IEEE 802.3 compliant hardware. -+ * @rx_prepend: Packet alignment padding length. The specified number -+ * of bytes (1-31) of zero padding are inserted before the -+ * start of each received frame. For Ethernet, where -+ * optional preamble extraction is enabled, the padding -+ * appears before the preamble, otherwise the padding -+ * precedes the layer 2 header. -+ * -+ * This structure contains basic dTSEC configuration and must be passed to -+ * fman_dtsec_init() function. A default set of configuration values can be -+ * obtained by calling fman_dtsec_defconfig(). -+ */ -+struct dtsec_cfg { -+ bool halfdup_on; -+ bool halfdup_alt_backoff_en; -+ bool halfdup_excess_defer; -+ bool halfdup_no_backoff; -+ bool halfdup_bp_no_backoff; -+ uint8_t halfdup_alt_backoff_val; -+ uint16_t halfdup_retransmit; -+ uint16_t halfdup_coll_window; -+ bool rx_drop_bcast; -+ bool rx_short_frm; -+ bool rx_len_check; -+ bool tx_pad_crc; -+ bool tx_crc; -+ bool rx_ctrl_acc; -+ unsigned short tx_pause_time; -+ unsigned short tbipa; -+ bool ptp_tsu_en; -+ bool ptp_exception_en; -+ bool rx_preamble; -+ bool tx_preamble; -+ unsigned char preamble_len; -+ unsigned char rx_prepend; -+ bool loopback; -+ bool rx_time_stamp_en; -+ bool tx_time_stamp_en; -+ bool rx_flow; -+ bool tx_flow; -+ bool rx_group_hash_exd; -+ bool rx_promisc; -+ uint8_t tbi_phy_addr; -+ uint16_t tx_pause_time_extd; -+ uint16_t maximum_frame; -+ uint32_t non_back_to_back_ipg1; -+ uint32_t non_back_to_back_ipg2; -+ uint32_t min_ifg_enforcement; -+ uint32_t back_to_back_ipg; -+ bool wake_on_lan; -+}; -+ -+ -+/** -+ * fman_dtsec_defconfig() - Get default dTSEC configuration -+ * @cfg: pointer to configuration structure. -+ * -+ * Call this function to obtain a default set of configuration values for -+ * initializing dTSEC. The user can overwrite any of the values before calling -+ * fman_dtsec_init(), if specific configuration needs to be applied. -+ */ -+void fman_dtsec_defconfig(struct dtsec_cfg *cfg); -+ -+/** -+ * fman_dtsec_init() - Init dTSEC hardware block -+ * @regs: Pointer to dTSEC register block -+ * @cfg: dTSEC configuration data -+ * @iface_mode: dTSEC interface mode, the type of MAC - PHY interface. -+ * @iface_speed: 1G or 10G -+ * @macaddr: MAC station address to be assigned to the device -+ * @fm_rev_maj: major rev number -+ * @fm_rev_min: minor rev number -+ * @exceptions_mask: initial exceptions mask -+ * -+ * This function initializes dTSEC and applies basic configuration. -+ * -+ * dTSEC initialization sequence: -+ * Before enabling Rx/Tx call dtsec_set_address() to set MAC address, -+ * fman_dtsec_adjust_link() to configure interface speed and duplex and finally -+ * dtsec_enable_tx()/dtsec_enable_rx() to start transmission and reception. -+ * -+ * Returns: 0 if successful, an error code otherwise. -+ */ -+int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg, -+ enum enet_interface iface_mode, -+ enum enet_speed iface_speed, -+ uint8_t *macaddr, uint8_t fm_rev_maj, -+ uint8_t fm_rev_min, -+ uint32_t exception_mask); -+ -+/** -+ * fman_dtsec_enable() - Enable dTSEC Tx and Tx -+ * @regs: Pointer to dTSEC register block -+ * @apply_rx: enable rx side -+ * @apply_tx: enable tx side -+ * -+ * This function resets Tx and Rx graceful stop bit and enables dTSEC Tx and Rx. -+ */ -+void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx); -+ -+/** -+ * fman_dtsec_disable() - Disable dTSEC Tx and Rx -+ * @regs: Pointer to dTSEC register block -+ * @apply_rx: disable rx side -+ * @apply_tx: disable tx side -+ * -+ * This function disables Tx and Rx in dTSEC. -+ */ -+void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx); -+ -+/** -+ * fman_dtsec_get_revision() - Get dTSEC hardware revision -+ * @regs: Pointer to dTSEC register block -+ * -+ * Returns dtsec_id content -+ * -+ * Call this function to obtain the dTSEC hardware version. -+ */ -+uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs); -+ -+/** -+ * fman_dtsec_set_mac_address() - Set MAC station address -+ * @regs: Pointer to dTSEC register block -+ * @macaddr: MAC address array -+ * -+ * This function sets MAC station address. To enable unicast reception call -+ * this after fman_dtsec_init(). While promiscuous mode is disabled dTSEC will -+ * match the destination address of received unicast frames against this -+ * address. -+ */ -+void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *macaddr); -+ -+/** -+ * fman_dtsec_get_mac_address() - Query MAC station address -+ * @regs: Pointer to dTSEC register block -+ * @macaddr: MAC address array -+ */ -+void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr); -+ -+/** -+ * fman_dtsec_set_uc_promisc() - Sets unicast promiscuous mode -+ * @regs: Pointer to dTSEC register block -+ * @enable: Enable unicast promiscuous mode -+ * -+ * Use this function to enable/disable dTSEC L2 address filtering. If the -+ * address filtering is disabled all unicast packets are accepted. -+ * To set dTSEC in promiscuous mode call both fman_dtsec_set_uc_promisc() and -+ * fman_dtsec_set_mc_promisc() to disable filtering for both unicast and -+ * multicast addresses. -+ */ -+void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable); -+ -+/** -+ * fman_dtsec_set_wol() - Enable/Disable wake on lan -+ * (magic packet support) -+ * @regs: Pointer to dTSEC register block -+ * @en: Enable Wake On Lan support in dTSEC -+ * -+ */ -+void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en); -+ -+/** -+ * fman_dtsec_adjust_link() - Adjust dTSEC speed/duplex settings -+ * @regs: Pointer to dTSEC register block -+ * @iface_mode: dTSEC interface mode -+ * @speed: Link speed -+ * @full_dx: True for full-duplex, false for half-duplex. -+ * -+ * This function configures the MAC to function and the desired rates. Use it -+ * to configure dTSEC after fman_dtsec_init() and whenever the link speed -+ * changes (for instance following PHY auto-negociation). -+ * -+ * Returns: 0 if successful, an error code otherwise. -+ */ -+int fman_dtsec_adjust_link(struct dtsec_regs *regs, -+ enum enet_interface iface_mode, -+ enum enet_speed speed, bool full_dx); -+ -+/** -+ * fman_dtsec_set_tbi_phy_addr() - Updates TBI address field -+ * @regs: Pointer to dTSEC register block -+ * @address: Valid PHY address in the range of 1 to 31. 0 is reserved. -+ * -+ * In SGMII mode, the dTSEC's TBIPA field must contain a valid TBI PHY address -+ * so that the associated TBI PHY (i.e. the link) may be initialized. -+ * -+ * Returns: 0 if successful, an error code otherwise. -+ */ -+int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs, -+ uint8_t addr); -+ -+/** -+ * fman_dtsec_set_max_frame_len() - Set max frame length -+ * @regs: Pointer to dTSEC register block -+ * @length: Max frame length. -+ * -+ * Sets maximum frame length for received and transmitted frames. Frames that -+ * exceeds this length are truncated. -+ */ -+void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length); -+ -+/** -+ * fman_dtsec_get_max_frame_len() - Query max frame length -+ * @regs: Pointer to dTSEC register block -+ * -+ * Returns: the current value of the maximum frame length. -+ */ -+uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs); -+ -+/** -+ * fman_dtsec_handle_rx_pause() - Configure pause frame handling -+ * @regs: Pointer to dTSEC register block -+ * @en: Enable pause frame handling in dTSEC -+ * -+ * If enabled, dTSEC will handle pause frames internally. This must be disabled -+ * if dTSEC is set in half-duplex mode. -+ * If pause frame handling is disabled and &dtsec_cfg.rx_ctrl_acc is set, pause -+ * frames will be transferred to the packet interface just like regular Ethernet -+ * frames. -+ */ -+void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en); -+ -+/** -+ * fman_dtsec_set_tx_pause_frames() - Configure Tx pause time -+ * @regs: Pointer to dTSEC register block -+ * @time: Time value included in pause frames -+ * -+ * Call this function to set the time value used in transmitted pause frames. -+ * If time is 0, transmission of pause frames is disabled -+ */ -+void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time); -+ -+/** -+ * fman_dtsec_ack_event() - Acknowledge handled events -+ * @regs: Pointer to dTSEC register block -+ * @ev_mask: Events to acknowledge -+ * -+ * After handling events signaled by dTSEC in either polling or interrupt mode, -+ * call this function to reset the associated status bits in dTSEC event -+ * register. -+ */ -+void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask); -+ -+/** -+ * fman_dtsec_get_event() - Returns currently asserted events -+ * @regs: Pointer to dTSEC register block -+ * @ev_mask: Mask of relevant events -+ * -+ * Call this function to obtain a bit-mask of events that are currently asserted -+ * in dTSEC, taken from IEVENT register. -+ * -+ * Returns: a bit-mask of events asserted in dTSEC. -+ */ -+uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask); -+ -+/** -+ * fman_dtsec_get_interrupt_mask() - Returns a bit-mask of enabled interrupts -+ * @regs: Pointer to dTSEC register block -+ * -+ * Call this function to obtain a bit-mask of enabled interrupts -+ * in dTSEC, taken from IMASK register. -+ * -+ * Returns: a bit-mask of enabled interrupts in dTSEC. -+ */ -+uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs); -+ -+void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, -+ uint8_t paddr_num); -+ -+void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs, -+ uint64_t addr, -+ uint8_t paddr_num); -+ -+void fman_dtsec_enable_tmr_interrupt (struct dtsec_regs *regs); -+ -+void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs); -+ -+/** -+ * fman_dtsec_disable_interrupt() - Disables interrupts for the specified events -+ * @regs: Pointer to dTSEC register block -+ * @ev_mask: Mask of relevant events -+ * -+ * Call this function to disable interrupts in dTSEC for the specified events. -+ * To enable interrupts use fman_dtsec_enable_interrupt(). -+ */ -+void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask); -+ -+/** -+ * fman_dtsec_enable_interrupt() - Enable interrupts for the specified events -+ * @regs: Pointer to dTSEC register block -+ * @ev_mask: Mask of relevant events -+ * -+ * Call this function to enable interrupts in dTSEC for the specified events. -+ * To disable interrupts use fman_dtsec_disable_interrupt(). -+ */ -+void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask); -+ -+/** -+ * fman_dtsec_set_ts() - Enables dTSEC timestamps -+ * @regs: Pointer to dTSEC register block -+ * @en: true to enable timestamps, false to disable them -+ * -+ * Call this function to enable/disable dTSEC timestamps. This affects both -+ * Tx and Rx. -+ */ -+void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en); -+ -+/** -+ * fman_dtsec_set_bucket() - Enables/disables a filter bucket -+ * @regs: Pointer to dTSEC register block -+ * @bucket: Bucket index -+ * @enable: true/false to enable/disable this bucket -+ * -+ * This function enables or disables the specified bucket. Enabling a bucket -+ * associated with an address configures dTSEC to accept received packets -+ * with that destination address. -+ * Multiple addresses may be associated with the same bucket. Disabling a -+ * bucket will affect all addresses associated with that bucket. A bucket that -+ * is enabled requires further filtering and verification in the upper layers -+ * -+ */ -+void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable); -+ -+/** -+ * dtsec_set_hash_table() - insert a crc code into thr filter table -+ * @regs: Pointer to dTSEC register block -+ * @crc: crc to insert -+ * @mcast: true is this is a multicast address -+ * @ghtx: true if we are in ghtx mode -+ * -+ * This function inserts a crc code into the filter table. -+ */ -+void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, -+ bool mcast, bool ghtx); -+ -+/** -+ * fman_dtsec_reset_filter_table() - Resets the address filtering table -+ * @regs: Pointer to dTSEC register block -+ * @mcast: Reset multicast entries -+ * @ucast: Reset unicast entries -+ * -+ * Resets all entries in L2 address filter table. After calling this function -+ * all buckets enabled using fman_dtsec_set_bucket() will be disabled. -+ * If dtsec_init_filter_table() was called with @unicast_hash set to false, -+ * @ucast argument is ignored. -+ * This does not affect the primary nor the 15 additional addresses configured -+ * using dtsec_set_address() or dtsec_set_match_address(). -+ */ -+void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, -+ bool ucast); -+ -+/** -+ * fman_dtsec_set_mc_promisc() - Set multicast promiscuous mode -+ * @regs: Pointer to dTSEC register block -+ * @enable: Enable multicast promiscuous mode -+ * -+ * Call this to enable/disable L2 address filtering for multicast packets. -+ */ -+void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable); -+ -+/* statistics APIs */ -+ -+/** -+ * fman_dtsec_set_stat_level() - Enable a group of MIB statistics counters -+ * @regs: Pointer to dTSEC register block -+ * @level: Specifies a certain group of dTSEC MIB HW counters or _all_, -+ * to specify all the existing counters. -+ * If set to _none_, it disables all the counters. -+ * -+ * Enables the MIB statistics hw counters and sets up the carry interrupt -+ * masks for the counters corresponding to the @level input parameter. -+ * -+ * Returns: error if invalid @level value given. -+ */ -+int fman_dtsec_set_stat_level(struct dtsec_regs *regs, -+ enum dtsec_stat_level level); -+ -+/** -+ * fman_dtsec_reset_stat() - Completely resets all dTSEC HW counters -+ * @regs: Pointer to dTSEC register block -+ */ -+void fman_dtsec_reset_stat(struct dtsec_regs *regs); -+ -+/** -+ * fman_dtsec_get_clear_carry_regs() - Read and clear carry bits (CAR1-2 registers) -+ * @regs: Pointer to dTSEC register block -+ * @car1: car1 register value -+ * @car2: car2 register value -+ * -+ * When set, the carry bits signal that an overflow occurred on the -+ * corresponding counters. -+ * Note that the carry bits (CAR1-2 registers) will assert the -+ * %DTSEC_IEVENT_MSRO interrupt if unmasked (via CAM1-2 regs). -+ * -+ * Returns: true if overflow occurred, otherwise - false -+ */ -+bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs, -+ uint32_t *car1, uint32_t *car2); -+ -+uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs); -+ -+uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs, -+ enum dtsec_stat_counters reg_name); -+ -+void fman_dtsec_start_tx(struct dtsec_regs *regs); -+void fman_dtsec_start_rx(struct dtsec_regs *regs); -+void fman_dtsec_stop_tx(struct dtsec_regs *regs); -+void fman_dtsec_stop_rx(struct dtsec_regs *regs); -+uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs); -+ -+ -+#endif /* __FSL_FMAN_DTSEC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h -@@ -0,0 +1,107 @@ -+/* -+ * Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __FSL_FMAN_DTSEC_MII_ACC_H -+#define __FSL_FMAN_DTSEC_MII_ACC_H -+ -+#include "common/general.h" -+ -+ -+/* MII Management Configuration Register */ -+#define MIIMCFG_RESET_MGMT 0x80000000 -+#define MIIMCFG_MGNTCLK_MASK 0x00000007 -+#define MIIMCFG_MGNTCLK_SHIFT 0 -+ -+/* MII Management Command Register */ -+#define MIIMCOM_SCAN_CYCLE 0x00000002 -+#define MIIMCOM_READ_CYCLE 0x00000001 -+ -+/* MII Management Address Register */ -+#define MIIMADD_PHY_ADDR_SHIFT 8 -+#define MIIMADD_PHY_ADDR_MASK 0x00001f00 -+ -+#define MIIMADD_REG_ADDR_SHIFT 0 -+#define MIIMADD_REG_ADDR_MASK 0x0000001f -+ -+/* MII Management Indicator Register */ -+#define MIIMIND_BUSY 0x00000001 -+ -+ -+/* PHY Control Register */ -+#define PHY_CR_PHY_RESET 0x8000 -+#define PHY_CR_LOOPBACK 0x4000 -+#define PHY_CR_SPEED0 0x2000 -+#define PHY_CR_ANE 0x1000 -+#define PHY_CR_RESET_AN 0x0200 -+#define PHY_CR_FULLDUPLEX 0x0100 -+#define PHY_CR_SPEED1 0x0040 -+ -+#define PHY_TBICON_SRESET 0x8000 -+#define PHY_TBICON_SPEED2 0x0020 -+#define PHY_TBICON_CLK_SEL 0x0020 -+#define PHY_TBIANA_SGMII 0x4001 -+#define PHY_TBIANA_1000X 0x01a0 -+/* register map */ -+ -+/* MII Configuration Control Memory Map Registers */ -+struct dtsec_mii_reg { -+ uint32_t reserved1[72]; -+ uint32_t miimcfg; /* MII Mgmt:configuration */ -+ uint32_t miimcom; /* MII Mgmt:command */ -+ uint32_t miimadd; /* MII Mgmt:address */ -+ uint32_t miimcon; /* MII Mgmt:control 3 */ -+ uint32_t miimstat; /* MII Mgmt:status */ -+ uint32_t miimind; /* MII Mgmt:indicators */ -+}; -+ -+/* dTSEC MII API */ -+ -+/* functions to access the mii registers for phy configuration. -+ * this functionality may not be available for all dtsecs in the system. -+ * consult the reference manual for details */ -+void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs); -+/* frequency is in MHz. -+ * note that dtsec clock is 1/2 of fman clock */ -+void fman_dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq); -+int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, -+ uint8_t addr, -+ uint8_t reg, -+ uint16_t data, -+ uint16_t dtsec_freq); -+ -+int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, -+ uint8_t addr, -+ uint8_t reg, -+ uint16_t *data, -+ uint16_t dtsec_freq); -+ -+#endif /* __FSL_FMAN_DTSEC_MII_ACC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h -@@ -0,0 +1,514 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __FSL_FMAN_KG_H -+#define __FSL_FMAN_KG_H -+ -+#include "common/general.h" -+ -+#define FM_KG_NUM_OF_GENERIC_REGS 8 /**< Num of generic KeyGen regs */ -+#define FMAN_MAX_NUM_OF_HW_PORTS 64 -+/**< Total num of masks allowed on KG extractions */ -+#define FM_KG_EXTRACT_MASKS_NUM 4 -+#define FM_KG_NUM_CLS_PLAN_ENTR 8 /**< Num of class. plan regs */ -+#define FM_KG_CLS_PLAN_GRPS_NUM 32 /**< Max num of class. groups */ -+ -+struct fman_kg_regs { -+ uint32_t fmkg_gcr; -+ uint32_t res004; -+ uint32_t res008; -+ uint32_t fmkg_eer; -+ uint32_t fmkg_eeer; -+ uint32_t res014; -+ uint32_t res018; -+ uint32_t fmkg_seer; -+ uint32_t fmkg_seeer; -+ uint32_t fmkg_gsr; -+ uint32_t fmkg_tpc; -+ uint32_t fmkg_serc; -+ uint32_t res030[4]; -+ uint32_t fmkg_fdor; -+ uint32_t fmkg_gdv0r; -+ uint32_t fmkg_gdv1r; -+ uint32_t res04c[6]; -+ uint32_t fmkg_feer; -+ uint32_t res068[38]; -+ uint32_t fmkg_indirect[63]; -+ uint32_t fmkg_ar; -+}; -+ -+struct fman_kg_scheme_regs { -+ uint32_t kgse_mode; /**< MODE */ -+ uint32_t kgse_ekfc; /**< Extract Known Fields Command */ -+ uint32_t kgse_ekdv; /**< Extract Known Default Value */ -+ uint32_t kgse_bmch; /**< Bit Mask Command High */ -+ uint32_t kgse_bmcl; /**< Bit Mask Command Low */ -+ uint32_t kgse_fqb; /**< Frame Queue Base */ -+ uint32_t kgse_hc; /**< Hash Command */ -+ uint32_t kgse_ppc; /**< Policer Profile Command */ -+ uint32_t kgse_gec[FM_KG_NUM_OF_GENERIC_REGS]; -+ /**< Generic Extract Command */ -+ uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */ -+ uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */ -+ uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */ -+ uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/ -+ uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */ -+ uint32_t kgse_om; /**< KeyGen Scheme Entry Operation Mode bits */ -+ uint32_t kgse_vsp; /**< KeyGen Scheme Entry Virtual Storage Profile */ -+}; -+ -+struct fman_kg_pe_regs{ -+ uint32_t fmkg_pe_sp; -+ uint32_t fmkg_pe_cpp; -+}; -+ -+struct fman_kg_cp_regs { -+ uint32_t kgcpe[FM_KG_NUM_CLS_PLAN_ENTR]; -+}; -+ -+ -+#define FM_KG_KGAR_GO 0x80000000 -+#define FM_KG_KGAR_READ 0x40000000 -+#define FM_KG_KGAR_WRITE 0x00000000 -+#define FM_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000 -+#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT 0x00008000 -+ -+#define KG_SCH_PP_SHIFT_HIGH 0x80000000 -+#define KG_SCH_PP_NO_GEN 0x10000000 -+#define KG_SCH_PP_SHIFT_LOW 0x0000F000 -+#define KG_SCH_MODE_NIA_PLCR 0x40000000 -+#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000 -+#define KG_SCH_BITMASK_MASK 0x000000FF -+#define KG_SCH_GEN_VALID 0x80000000 -+#define KG_SCH_GEN_MASK 0x00FF0000 -+#define FM_PCD_KG_KGAR_ERR 0x20000000 -+#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000 -+#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000 -+#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000 -+#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000 -+#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00 -+#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000 -+#define KG_SCH_HASH_CONFIG_SYM 0x40000000 -+ -+#define FM_EX_KG_DOUBLE_ECC 0x80000000 -+#define FM_EX_KG_KEYSIZE_OVERFLOW 0x40000000 -+ -+/* ECC capture register */ -+#define KG_FMKG_SERC_CAP 0x80000000 -+#define KG_FMKG_SERC_CET 0x40000000 -+#define KG_FMKG_SERC_CNT_MSK 0x00FF0000 -+#define KG_FMKG_SERC_CNT_SHIFT 16 -+#define KG_FMKG_SERC_ADDR_MSK 0x000003FF -+ -+/* Masks */ -+#define FM_KG_KGGCR_EN 0x80000000 -+#define KG_SCH_GEN_VALID 0x80000000 -+#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000 -+#define KG_ERR_TYPE_DOUBLE 0x40000000 -+#define KG_ERR_ADDR_MASK 0x00000FFF -+#define KG_SCH_MODE_EN 0x80000000 -+ -+/* shifts */ -+#define FM_KG_KGAR_NUM_SHIFT 16 -+#define FM_KG_PE_CPP_MASK_SHIFT 16 -+#define FM_KG_KGAR_WSEL_SHIFT 8 -+ -+#define FM_KG_SCH_GEN_HT_INVALID 0 -+ -+#define FM_KG_MASK_SEL_GEN_BASE 0x20 -+ -+#define KG_GET_MASK_SEL_SHIFT(shift, i) \ -+switch (i) \ -+{ \ -+ case 0: (shift) = 26; break; \ -+ case 1: (shift) = 20; break; \ -+ case 2: (shift) = 10; break; \ -+ case 3: (shift) = 4; break; \ -+ default: (shift) = 0; \ -+} -+ -+#define KG_GET_MASK_OFFSET_SHIFT(shift, i) \ -+switch (i) \ -+{ \ -+ case 0: (shift) = 16; break; \ -+ case 1: (shift) = 0; break; \ -+ case 2: (shift) = 28; break; \ -+ case 3: (shift) = 24; break; \ -+ default: (shift) = 0; \ -+} -+ -+#define KG_GET_MASK_SHIFT(shift, i) \ -+switch (i) \ -+{ \ -+ case 0: shift = 24; break; \ -+ case 1: shift = 16; break; \ -+ case 2: shift = 8; break; \ -+ case 3: shift = 0; break; \ -+ default: shift = 0; \ -+} -+ -+/* Port entry CPP register */ -+#define FMAN_KG_PE_CPP_MASK_SHIFT 16 -+ -+/* Scheme registers */ -+#define FMAN_KG_SCH_MODE_EN 0x80000000 -+#define FMAN_KG_SCH_MODE_NIA_PLCR 0x40000000 -+#define FMAN_KG_SCH_MODE_CCOBASE_SHIFT 24 -+ -+#define FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT 30 -+#define FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT 28 -+#define FMAN_KG_SCH_DEF_ETYPE_SHIFT 26 -+#define FMAN_KG_SCH_DEF_PPP_SID_SHIFT 24 -+#define FMAN_KG_SCH_DEF_PPP_PID_SHIFT 22 -+#define FMAN_KG_SCH_DEF_MPLS_SHIFT 20 -+#define FMAN_KG_SCH_DEF_IP_ADDR_SHIFT 18 -+#define FMAN_KG_SCH_DEF_PTYPE_SHIFT 16 -+#define FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT 14 -+#define FMAN_KG_SCH_DEF_IPv6_FL_SHIFT 12 -+#define FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT 10 -+#define FMAN_KG_SCH_DEF_L4_PORT_SHIFT 8 -+#define FMAN_KG_SCH_DEF_TCP_FLG_SHIFT 6 -+ -+#define FMAN_KG_SCH_GEN_VALID 0x80000000 -+#define FMAN_KG_SCH_GEN_SIZE_MAX 16 -+#define FMAN_KG_SCH_GEN_OR 0x00008000 -+ -+#define FMAN_KG_SCH_GEN_DEF_SHIFT 29 -+#define FMAN_KG_SCH_GEN_SIZE_SHIFT 24 -+#define FMAN_KG_SCH_GEN_MASK_SHIFT 16 -+#define FMAN_KG_SCH_GEN_HT_SHIFT 8 -+ -+#define FMAN_KG_SCH_HASH_HSHIFT_SHIFT 24 -+#define FMAN_KG_SCH_HASH_HSHIFT_MAX 0x28 -+#define FMAN_KG_SCH_HASH_SYM 0x40000000 -+#define FMAN_KG_SCH_HASH_NO_FQID_GEN 0x80000000 -+ -+#define FMAN_KG_SCH_PP_SH_SHIFT 27 -+#define FMAN_KG_SCH_PP_SL_SHIFT 12 -+#define FMAN_KG_SCH_PP_SH_MASK 0x80000000 -+#define FMAN_KG_SCH_PP_SL_MASK 0x0000F000 -+#define FMAN_KG_SCH_PP_SHIFT_MAX 0x17 -+#define FMAN_KG_SCH_PP_MASK_SHIFT 16 -+#define FMAN_KG_SCH_PP_NO_GEN 0x10000000 -+ -+enum fman_kg_gen_extract_src { -+ E_FMAN_KG_GEN_EXTRACT_ETH, -+ E_FMAN_KG_GEN_EXTRACT_ETYPE, -+ E_FMAN_KG_GEN_EXTRACT_SNAP, -+ E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1, -+ E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N, -+ E_FMAN_KG_GEN_EXTRACT_PPPoE, -+ E_FMAN_KG_GEN_EXTRACT_MPLS_1, -+ E_FMAN_KG_GEN_EXTRACT_MPLS_2, -+ E_FMAN_KG_GEN_EXTRACT_MPLS_3, -+ E_FMAN_KG_GEN_EXTRACT_MPLS_N, -+ E_FMAN_KG_GEN_EXTRACT_IPv4_1, -+ E_FMAN_KG_GEN_EXTRACT_IPv6_1, -+ E_FMAN_KG_GEN_EXTRACT_IPv4_2, -+ E_FMAN_KG_GEN_EXTRACT_IPv6_2, -+ E_FMAN_KG_GEN_EXTRACT_MINENCAP, -+ E_FMAN_KG_GEN_EXTRACT_IP_PID, -+ E_FMAN_KG_GEN_EXTRACT_GRE, -+ E_FMAN_KG_GEN_EXTRACT_TCP, -+ E_FMAN_KG_GEN_EXTRACT_UDP, -+ E_FMAN_KG_GEN_EXTRACT_SCTP, -+ E_FMAN_KG_GEN_EXTRACT_DCCP, -+ E_FMAN_KG_GEN_EXTRACT_IPSEC_AH, -+ E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP, -+ E_FMAN_KG_GEN_EXTRACT_SHIM_1, -+ E_FMAN_KG_GEN_EXTRACT_SHIM_2, -+ E_FMAN_KG_GEN_EXTRACT_FROM_DFLT, -+ E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START, -+ E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT, -+ E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE, -+ E_FMAN_KG_GEN_EXTRACT_FROM_FQID -+}; -+ -+struct fman_kg_ex_ecc_attr -+{ -+ bool valid; -+ bool double_ecc; -+ uint16_t addr; -+ uint8_t single_ecc_count; -+}; -+ -+enum fman_kg_def_select -+{ -+ E_FMAN_KG_DEF_GLOBAL_0, -+ E_FMAN_KG_DEF_GLOBAL_1, -+ E_FMAN_KG_DEF_SCHEME_0, -+ E_FMAN_KG_DEF_SCHEME_1 -+}; -+ -+struct fman_kg_extract_def -+{ -+ enum fman_kg_def_select mac_addr; -+ enum fman_kg_def_select vlan_tci; -+ enum fman_kg_def_select etype; -+ enum fman_kg_def_select ppp_sid; -+ enum fman_kg_def_select ppp_pid; -+ enum fman_kg_def_select mpls; -+ enum fman_kg_def_select ip_addr; -+ enum fman_kg_def_select ptype; -+ enum fman_kg_def_select ip_tos_tc; -+ enum fman_kg_def_select ipv6_fl; -+ enum fman_kg_def_select ipsec_spi; -+ enum fman_kg_def_select l4_port; -+ enum fman_kg_def_select tcp_flg; -+}; -+ -+enum fman_kg_gen_extract_type -+{ -+ E_FMAN_KG_HASH_EXTRACT, -+ E_FMAN_KG_OR_EXTRACT -+}; -+ -+struct fman_kg_gen_extract_params -+{ -+ /* Hash or Or-ed extract */ -+ enum fman_kg_gen_extract_type type; -+ enum fman_kg_gen_extract_src src; -+ bool no_validation; -+ /* Extraction offset from the header location specified above */ -+ uint8_t offset; -+ /* Size of extraction for FMAN_KG_HASH_EXTRACT, -+ * hash result shift for FMAN_KG_OR_EXTRACT */ -+ uint8_t extract; -+ uint8_t mask; -+ /* Default value to use when header specified -+ * by fman_kg_gen_extract_src doesn't present */ -+ enum fman_kg_def_select def_val; -+}; -+ -+struct fman_kg_extract_mask -+{ -+ /**< Indication if mask is on known field extraction or -+ * on general extraction; TRUE for known field */ -+ bool is_known; -+ /**< One of FMAN_KG_EXTRACT_xxx defines for known fields mask and -+ * generic register index for generic extracts mask */ -+ uint32_t field_or_gen_idx; -+ /**< Byte offset from start of the extracted data specified -+ * by field_or_gen_idx */ -+ uint8_t offset; -+ /**< Byte mask (selected bits will be used) */ -+ uint8_t mask; -+}; -+ -+struct fman_kg_extract_params -+{ -+ /* Or-ed mask of FMAN_KG_EXTRACT_xxx defines */ -+ uint32_t known_fields; -+ struct fman_kg_extract_def known_fields_def; -+ /* Number of entries in gen_extract */ -+ uint8_t gen_extract_num; -+ struct fman_kg_gen_extract_params gen_extract[FM_KG_NUM_OF_GENERIC_REGS]; -+ /* Number of entries in masks */ -+ uint8_t masks_num; -+ struct fman_kg_extract_mask masks[FM_KG_EXTRACT_MASKS_NUM]; -+ uint32_t def_scheme_0; -+ uint32_t def_scheme_1; -+}; -+ -+struct fman_kg_hash_params -+{ -+ bool use_hash; -+ uint8_t shift_r; -+ uint32_t mask; /**< 24-bit mask */ -+ bool sym; /**< Symmetric hash for src and dest pairs */ -+}; -+ -+struct fman_kg_pp_params -+{ -+ uint8_t base; -+ uint8_t shift; -+ uint8_t mask; -+ bool bypass_pp_gen; -+}; -+ -+struct fman_kg_cc_params -+{ -+ uint8_t base_offset; -+ uint32_t qlcv_bits_sel; -+}; -+ -+enum fman_pcd_engine -+{ -+ E_FMAN_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/ -+ E_FMAN_PCD_DONE, /**< No PCD Engine indicated */ -+ E_FMAN_PCD_KG, /**< Keygen indicated */ -+ E_FMAN_PCD_CC, /**< Coarse classification indicated */ -+ E_FMAN_PCD_PLCR, /**< Policer indicated */ -+ E_FMAN_PCD_PRS /**< Parser indicated */ -+}; -+ -+struct fman_kg_cls_plan_params -+{ -+ uint8_t entries_mask; -+ uint32_t mask_vector[FM_KG_NUM_CLS_PLAN_ENTR]; -+}; -+ -+struct fman_kg_scheme_params -+{ -+ uint32_t match_vector; -+ struct fman_kg_extract_params extract_params; -+ struct fman_kg_hash_params hash_params; -+ uint32_t base_fqid; -+ /* What we do w/features supported per FM version ?? */ -+ bool bypass_fqid_gen; -+ struct fman_kg_pp_params policer_params; -+ struct fman_kg_cc_params cc_params; -+ bool update_counter; -+ /**< counter_value: Set scheme counter to the specified value; -+ * relevant only when update_counter = TRUE. */ -+ uint32_t counter_value; -+ enum fman_pcd_engine next_engine; -+ /**< Next engine action code */ -+ uint32_t next_engine_action; -+}; -+ -+ -+ -+int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar); -+void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add); -+void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp); -+void fman_kg_get_event(struct fman_kg_regs *regs, -+ uint32_t *event, -+ uint32_t *scheme_idx); -+void fman_kg_init(struct fman_kg_regs *regs, -+ uint32_t exceptions, -+ uint32_t dflt_nia); -+void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs); -+void fman_kg_enable(struct fman_kg_regs *regs); -+void fman_kg_disable(struct fman_kg_regs *regs); -+int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs, -+ uint8_t hwport_id, -+ uint32_t bind_cls_plans); -+int fman_kg_build_bind_cls_plans(uint8_t grp_base, -+ uint8_t grp_mask, -+ uint32_t *bind_cls_plans); -+int fman_kg_write_bind_schemes(struct fman_kg_regs *regs, -+ uint8_t hwport_id, -+ uint32_t schemes); -+int fman_kg_write_cls_plan(struct fman_kg_regs *regs, -+ uint8_t grp_id, -+ uint8_t entries_mask, -+ uint8_t hwport_id, -+ struct fman_kg_cp_regs *cls_plan_regs); -+int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params, -+ struct fman_kg_cp_regs *cls_plan_regs); -+uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs); -+int fman_kg_set_scheme_counter(struct fman_kg_regs *regs, -+ uint8_t scheme_id, -+ uint8_t hwport_id, -+ uint32_t counter); -+int fman_kg_get_scheme_counter(struct fman_kg_regs *regs, -+ uint8_t scheme_id, -+ uint8_t hwport_id, -+ uint32_t *counter); -+int fman_kg_delete_scheme(struct fman_kg_regs *regs, -+ uint8_t scheme_id, -+ uint8_t hwport_id); -+int fman_kg_write_scheme(struct fman_kg_regs *regs, -+ uint8_t scheme_id, -+ uint8_t hwport_id, -+ struct fman_kg_scheme_regs *scheme_regs, -+ bool update_counter); -+int fman_kg_build_scheme(struct fman_kg_scheme_params *params, -+ struct fman_kg_scheme_regs *scheme_regs); -+void fman_kg_get_capture(struct fman_kg_regs *regs, -+ struct fman_kg_ex_ecc_attr *ecc_attr, -+ bool clear); -+void fman_kg_get_exception(struct fman_kg_regs *regs, -+ uint32_t *events, -+ uint32_t *scheme_ids, -+ bool clear); -+void fman_kg_set_exception(struct fman_kg_regs *regs, -+ uint32_t exception, -+ bool enable); -+void fman_kg_set_dflt_val(struct fman_kg_regs *regs, -+ uint8_t def_id, -+ uint32_t val); -+void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset); -+ -+ -+ -+/**************************************************************************//** -+ @Description NIA Description -+*//***************************************************************************/ -+#define KG_NIA_ORDER_RESTOR 0x00800000 -+#define KG_NIA_ENG_FM_CTL 0x00000000 -+#define KG_NIA_ENG_PRS 0x00440000 -+#define KG_NIA_ENG_KG 0x00480000 -+#define KG_NIA_ENG_PLCR 0x004C0000 -+#define KG_NIA_ENG_BMI 0x00500000 -+#define KG_NIA_ENG_QMI_ENQ 0x00540000 -+#define KG_NIA_ENG_QMI_DEQ 0x00580000 -+#define KG_NIA_ENG_MASK 0x007C0000 -+ -+#define KG_NIA_AC_MASK 0x0003FFFF -+ -+#define KG_NIA_INVALID 0xFFFFFFFF -+ -+static __inline__ uint32_t fm_kg_build_nia(enum fman_pcd_engine next_engine, -+ uint32_t next_engine_action) -+{ -+ uint32_t nia; -+ -+ if (next_engine_action & ~KG_NIA_AC_MASK) -+ return KG_NIA_INVALID; -+ -+ switch (next_engine) { -+ case E_FMAN_PCD_DONE: -+ nia = KG_NIA_ENG_BMI | next_engine_action; -+ break; -+ -+ case E_FMAN_PCD_KG: -+ nia = KG_NIA_ENG_KG | next_engine_action; -+ break; -+ -+ case E_FMAN_PCD_CC: -+ nia = KG_NIA_ENG_FM_CTL | next_engine_action; -+ break; -+ -+ case E_FMAN_PCD_PLCR: -+ nia = KG_NIA_ENG_PLCR | next_engine_action; -+ break; -+ -+ default: -+ nia = KG_NIA_INVALID; -+ } -+ -+ return nia; -+} -+ -+#endif /* __FSL_FMAN_KG_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h -@@ -0,0 +1,427 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#ifndef __FSL_FMAN_MEMAC_H -+#define __FSL_FMAN_MEMAC_H -+ -+#include "common/general.h" -+#include "fsl_enet.h" -+ -+ -+#define MEMAC_NUM_OF_PADDRS 7 /* Num of additional exact match MAC adr regs */ -+ -+/* Control and Configuration Register (COMMAND_CONFIG) */ -+#define CMD_CFG_MG 0x80000000 /* 00 Magic Packet detection */ -+#define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */ -+#define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */ -+#define CMD_CFG_SFD_ANY 0x00200000 /* 10 Disable SFD check */ -+#define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */ -+#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */ -+#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 Force idle generation */ -+#define CMD_CFG_CNT_FRM_EN 0x00002000 /* 18 Control frame rx enable */ -+#define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */ -+#define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */ -+#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 XGMII/GMII loopback enable */ -+#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 Tx source MAC addr insertion */ -+#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */ -+#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 Terminate/frwd Pause frames */ -+#define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */ -+#define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */ -+#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */ -+#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN mode enable */ -+#define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */ -+#define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */ -+ -+/* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */ -+#define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000 -+#define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF -+#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000 -+#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000 -+#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G 0x00360000 -+#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G 0x00040000 -+#define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019 -+#define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020 -+#define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060 -+ -+#define GET_TX_EMPTY_DEFAULT_VALUE(_val) \ -+_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \ -+((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \ -+ (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) : \ -+ (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G)); -+ -+#define GET_TX_EMPTY_PFC_VALUE(_val) \ -+_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \ -+((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \ -+ (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G) : \ -+ (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G)); -+ -+/* Interface Mode Register (IF_MODE) */ -+#define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */ -+#define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */ -+#define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */ -+#define IF_MODE_RGMII 0x00000004 -+#define IF_MODE_RGMII_AUTO 0x00008000 -+#define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */ -+#define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */ -+#define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */ -+#define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */ -+#define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */ -+#define IF_MODE_HD 0x00000040 /* Half duplex operation */ -+ -+/* Hash table Control Register (HASHTABLE_CTRL) */ -+#define HASH_CTRL_MCAST_SHIFT 26 -+#define HASH_CTRL_MCAST_EN 0x00000100 /* 23 Mcast frame rx for hash */ -+#define HASH_CTRL_ADDR_MASK 0x0000003F /* 26-31 Hash table address code */ -+ -+#define GROUP_ADDRESS 0x0000010000000000LL /* MAC mcast indication */ -+#define HASH_TABLE_SIZE 64 /* Hash tbl size */ -+ -+/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */ -+#define MEMAC_TX_IPG_LENGTH_MASK 0x0000003F -+ -+/* Statistics Configuration Register (STATN_CONFIG) */ -+#define STATS_CFG_CLR 0x00000004 /* 29 Reset all counters */ -+#define STATS_CFG_CLR_ON_RD 0x00000002 /* 30 Clear on read */ -+#define STATS_CFG_SATURATE 0x00000001 /* 31 Saturate at the maximum val */ -+ -+/* Interrupt Mask Register (IMASK) */ -+#define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */ -+#define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */ -+#define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */ -+#define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */ -+ -+#define MEMAC_ALL_ERRS_IMASK \ -+ ((uint32_t)(MEMAC_IMASK_TSECC_ER | \ -+ MEMAC_IMASK_TECC_ER | \ -+ MEMAC_IMASK_RECC_ER | \ -+ MEMAC_IMASK_MGI)) -+ -+#define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */ -+#define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */ -+#define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */ -+#define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */ -+#define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error */ -+#define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */ -+#define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */ -+#define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */ -+#define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */ -+#define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */ -+#define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */ -+#define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */ -+#define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */ -+#define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */ -+#define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */ -+#define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */ -+#define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */ -+ -+enum memac_counters { -+ E_MEMAC_COUNTER_R64, -+ E_MEMAC_COUNTER_R127, -+ E_MEMAC_COUNTER_R255, -+ E_MEMAC_COUNTER_R511, -+ E_MEMAC_COUNTER_R1023, -+ E_MEMAC_COUNTER_R1518, -+ E_MEMAC_COUNTER_R1519X, -+ E_MEMAC_COUNTER_RFRG, -+ E_MEMAC_COUNTER_RJBR, -+ E_MEMAC_COUNTER_RDRP, -+ E_MEMAC_COUNTER_RALN, -+ E_MEMAC_COUNTER_TUND, -+ E_MEMAC_COUNTER_ROVR, -+ E_MEMAC_COUNTER_RXPF, -+ E_MEMAC_COUNTER_TXPF, -+ E_MEMAC_COUNTER_ROCT, -+ E_MEMAC_COUNTER_RMCA, -+ E_MEMAC_COUNTER_RBCA, -+ E_MEMAC_COUNTER_RPKT, -+ E_MEMAC_COUNTER_RUCA, -+ E_MEMAC_COUNTER_RERR, -+ E_MEMAC_COUNTER_TOCT, -+ E_MEMAC_COUNTER_TMCA, -+ E_MEMAC_COUNTER_TBCA, -+ E_MEMAC_COUNTER_TUCA, -+ E_MEMAC_COUNTER_TERR -+}; -+ -+#define DEFAULT_PAUSE_QUANTA 0xf000 -+#define DEFAULT_FRAME_LENGTH 0x600 -+#define DEFAULT_TX_IPG_LENGTH 12 -+ -+/* -+ * memory map -+ */ -+ -+struct mac_addr { -+ uint32_t mac_addr_l; /* Lower 32 bits of 48-bit MAC address */ -+ uint32_t mac_addr_u; /* Upper 16 bits of 48-bit MAC address */ -+}; -+ -+struct memac_regs { -+ /* General Control and Status */ -+ uint32_t res0000[2]; -+ uint32_t command_config; /* 0x008 Ctrl and cfg */ -+ struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */ -+ uint32_t maxfrm; /* 0x014 Max frame length */ -+ uint32_t res0018[1]; -+ uint32_t rx_fifo_sections; /* Receive FIFO configuration reg */ -+ uint32_t tx_fifo_sections; /* Transmit FIFO configuration reg */ -+ uint32_t res0024[2]; -+ uint32_t hashtable_ctrl; /* 0x02C Hash table control */ -+ uint32_t res0030[4]; -+ uint32_t ievent; /* 0x040 Interrupt event */ -+ uint32_t tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */ -+ uint32_t res0048; -+ uint32_t imask; /* 0x04C Interrupt mask */ -+ uint32_t res0050; -+ uint32_t pause_quanta[4]; /* 0x054 Pause quanta */ -+ uint32_t pause_thresh[4]; /* 0x064 Pause quanta threshold */ -+ uint32_t rx_pause_status; /* 0x074 Receive pause status */ -+ uint32_t res0078[2]; -+ struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS]; /* 0x80-0x0B4 mac padr */ -+ uint32_t lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */ -+ uint32_t sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */ -+ uint32_t res00c0[8]; -+ uint32_t statn_config; /* 0x0E0 Statistics configuration */ -+ uint32_t res00e4[7]; -+ /* Rx Statistics Counter */ -+ uint32_t reoct_l; -+ uint32_t reoct_u; -+ uint32_t roct_l; -+ uint32_t roct_u; -+ uint32_t raln_l; -+ uint32_t raln_u; -+ uint32_t rxpf_l; -+ uint32_t rxpf_u; -+ uint32_t rfrm_l; -+ uint32_t rfrm_u; -+ uint32_t rfcs_l; -+ uint32_t rfcs_u; -+ uint32_t rvlan_l; -+ uint32_t rvlan_u; -+ uint32_t rerr_l; -+ uint32_t rerr_u; -+ uint32_t ruca_l; -+ uint32_t ruca_u; -+ uint32_t rmca_l; -+ uint32_t rmca_u; -+ uint32_t rbca_l; -+ uint32_t rbca_u; -+ uint32_t rdrp_l; -+ uint32_t rdrp_u; -+ uint32_t rpkt_l; -+ uint32_t rpkt_u; -+ uint32_t rund_l; -+ uint32_t rund_u; -+ uint32_t r64_l; -+ uint32_t r64_u; -+ uint32_t r127_l; -+ uint32_t r127_u; -+ uint32_t r255_l; -+ uint32_t r255_u; -+ uint32_t r511_l; -+ uint32_t r511_u; -+ uint32_t r1023_l; -+ uint32_t r1023_u; -+ uint32_t r1518_l; -+ uint32_t r1518_u; -+ uint32_t r1519x_l; -+ uint32_t r1519x_u; -+ uint32_t rovr_l; -+ uint32_t rovr_u; -+ uint32_t rjbr_l; -+ uint32_t rjbr_u; -+ uint32_t rfrg_l; -+ uint32_t rfrg_u; -+ uint32_t rcnp_l; -+ uint32_t rcnp_u; -+ uint32_t rdrntp_l; -+ uint32_t rdrntp_u; -+ uint32_t res01d0[12]; -+ /* Tx Statistics Counter */ -+ uint32_t teoct_l; -+ uint32_t teoct_u; -+ uint32_t toct_l; -+ uint32_t toct_u; -+ uint32_t res0210[2]; -+ uint32_t txpf_l; -+ uint32_t txpf_u; -+ uint32_t tfrm_l; -+ uint32_t tfrm_u; -+ uint32_t tfcs_l; -+ uint32_t tfcs_u; -+ uint32_t tvlan_l; -+ uint32_t tvlan_u; -+ uint32_t terr_l; -+ uint32_t terr_u; -+ uint32_t tuca_l; -+ uint32_t tuca_u; -+ uint32_t tmca_l; -+ uint32_t tmca_u; -+ uint32_t tbca_l; -+ uint32_t tbca_u; -+ uint32_t res0258[2]; -+ uint32_t tpkt_l; -+ uint32_t tpkt_u; -+ uint32_t tund_l; -+ uint32_t tund_u; -+ uint32_t t64_l; -+ uint32_t t64_u; -+ uint32_t t127_l; -+ uint32_t t127_u; -+ uint32_t t255_l; -+ uint32_t t255_u; -+ uint32_t t511_l; -+ uint32_t t511_u; -+ uint32_t t1023_l; -+ uint32_t t1023_u; -+ uint32_t t1518_l; -+ uint32_t t1518_u; -+ uint32_t t1519x_l; -+ uint32_t t1519x_u; -+ uint32_t res02a8[6]; -+ uint32_t tcnp_l; -+ uint32_t tcnp_u; -+ uint32_t res02c8[14]; -+ /* Line Interface Control */ -+ uint32_t if_mode; /* 0x300 Interface Mode Control */ -+ uint32_t if_status; /* 0x304 Interface Status */ -+ uint32_t res0308[14]; -+ /* HiGig/2 */ -+ uint32_t hg_config; /* 0x340 Control and cfg */ -+ uint32_t res0344[3]; -+ uint32_t hg_pause_quanta; /* 0x350 Pause quanta */ -+ uint32_t res0354[3]; -+ uint32_t hg_pause_thresh; /* 0x360 Pause quanta threshold */ -+ uint32_t res0364[3]; -+ uint32_t hgrx_pause_status; /* 0x370 Receive pause status */ -+ uint32_t hg_fifos_status; /* 0x374 fifos status */ -+ uint32_t rhm; /* 0x378 rx messages counter */ -+ uint32_t thm; /* 0x37C tx messages counter */ -+}; -+ -+struct memac_cfg { -+ bool reset_on_init; -+ bool rx_error_discard; -+ bool pause_ignore; -+ bool pause_forward_enable; -+ bool no_length_check_enable; -+ bool cmd_frame_enable; -+ bool send_idle_enable; -+ bool wan_mode_enable; -+ bool promiscuous_mode_enable; -+ bool tx_addr_ins_enable; -+ bool loopback_enable; -+ bool lgth_check_nostdr; -+ bool time_stamp_enable; -+ bool pad_enable; -+ bool phy_tx_ena_on; -+ bool rx_sfd_any; -+ bool rx_pbl_fwd; -+ bool tx_pbl_fwd; -+ bool debug_mode; -+ bool wake_on_lan; -+ uint16_t max_frame_length; -+ uint16_t pause_quanta; -+ uint32_t tx_ipg_length; -+}; -+ -+ -+/** -+ * fman_memac_defconfig() - Get default MEMAC configuration -+ * @cfg: pointer to configuration structure. -+ * -+ * Call this function to obtain a default set of configuration values for -+ * initializing MEMAC. The user can overwrite any of the values before calling -+ * fman_memac_init(), if specific configuration needs to be applied. -+ */ -+void fman_memac_defconfig(struct memac_cfg *cfg); -+ -+int fman_memac_init(struct memac_regs *regs, -+ struct memac_cfg *cfg, -+ enum enet_interface enet_interface, -+ enum enet_speed enet_speed, -+ bool slow_10g_if, -+ uint32_t exceptions); -+ -+void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx); -+ -+void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx); -+ -+void fman_memac_set_promiscuous(struct memac_regs *regs, bool val); -+ -+void fman_memac_add_addr_in_paddr(struct memac_regs *regs, -+ uint8_t *adr, -+ uint8_t paddr_num); -+ -+void fman_memac_clear_addr_in_paddr(struct memac_regs *regs, -+ uint8_t paddr_num); -+ -+uint64_t fman_memac_get_counter(struct memac_regs *regs, -+ enum memac_counters reg_name); -+ -+void fman_memac_set_tx_pause_frames(struct memac_regs *regs, -+ uint8_t priority, uint16_t pauseTime, uint16_t threshTime); -+ -+uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs); -+ -+void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, -+ bool enable); -+ -+void fman_memac_reset_stat(struct memac_regs *regs); -+ -+void fman_memac_reset(struct memac_regs *regs); -+ -+void fman_memac_reset_filter_table(struct memac_regs *regs); -+ -+void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc); -+ -+void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val); -+ -+void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs, -+ bool enable); -+ -+void fman_memac_set_wol(struct memac_regs *regs, bool enable); -+ -+uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask); -+ -+void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask); -+ -+uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs); -+ -+void fman_memac_adjust_link(struct memac_regs *regs, -+ enum enet_interface iface_mode, -+ enum enet_speed speed, bool full_dx); -+ -+ -+ -+#endif /*__FSL_FMAN_MEMAC_H*/ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h -@@ -0,0 +1,78 @@ -+/* -+ * Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __FSL_FMAN_MEMAC_MII_ACC_H -+#define __FSL_FMAN_MEMAC_MII_ACC_H -+ -+#include "common/general.h" -+#include "fsl_enet.h" -+/* MII Management Registers */ -+#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80 -+#define MDIO_CFG_CLK_DIV_SHIFT 7 -+#define MDIO_CFG_HOLD_MASK 0x0000001c -+#define MDIO_CFG_ENC45 0x00000040 -+#define MDIO_CFG_READ_ERR 0x00000002 -+#define MDIO_CFG_BSY 0x00000001 -+ -+#define MDIO_CTL_PHY_ADDR_SHIFT 5 -+#define MDIO_CTL_READ 0x00008000 -+ -+#define MDIO_DATA_BSY 0x80000000 -+ -+/*MEMAC Internal PHY Registers - SGMII */ -+#define PHY_SGMII_CR_PHY_RESET 0x8000 -+#define PHY_SGMII_CR_RESET_AN 0x0200 -+#define PHY_SGMII_CR_DEF_VAL 0x1140 -+#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001 -+#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0 -+#define PHY_SGMII_IF_MODE_AN 0x0002 -+#define PHY_SGMII_IF_MODE_SGMII 0x0001 -+#define PHY_SGMII_IF_MODE_1000X 0x0000 -+ -+/*----------------------------------------------------*/ -+/* MII Configuration Control Memory Map Registers */ -+/*----------------------------------------------------*/ -+struct memac_mii_access_mem_map { -+ uint32_t mdio_cfg; /* 0x030 */ -+ uint32_t mdio_ctrl; /* 0x034 */ -+ uint32_t mdio_data; /* 0x038 */ -+ uint32_t mdio_addr; /* 0x03c */ -+}; -+ -+int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs, -+ uint8_t phy_addr, uint8_t reg, uint16_t *data, -+ enum enet_speed enet_speed); -+int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs, -+ uint8_t phy_addr, uint8_t reg, uint16_t data, -+ enum enet_speed enet_speed); -+ -+#endif /* __MAC_API_MEMAC_MII_ACC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h -@@ -0,0 +1,593 @@ -+/* -+ * Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __FSL_FMAN_PORT_H -+#define __FSL_FMAN_PORT_H -+ -+#include "fsl_fman_sp.h" -+ -+/** @Collection Registers bit fields */ -+ -+/** @Description BMI defines */ -+#define BMI_EBD_EN 0x80000000 -+ -+#define BMI_PORT_CFG_EN 0x80000000 -+#define BMI_PORT_CFG_FDOVR 0x02000000 -+#define BMI_PORT_CFG_IM 0x01000000 -+ -+#define BMI_PORT_STATUS_BSY 0x80000000 -+ -+#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT -+#define BMI_DMA_ATTR_IC_STASH_ON 0x10000000 -+#define BMI_DMA_ATTR_HDR_STASH_ON 0x04000000 -+#define BMI_DMA_ATTR_SG_STASH_ON 0x01000000 -+#define BMI_DMA_ATTR_WRITE_OPTIMIZE FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE -+ -+#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16 -+#define BMI_RX_FIFO_THRESHOLD_ETHE 0x80000000 -+ -+#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24 -+#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24 -+#define BMI_RX_FRAME_END_CUT_SHIFT 16 -+ -+#define BMI_IC_TO_EXT_SHIFT FMAN_SP_IC_TO_EXT_SHIFT -+#define BMI_IC_FROM_INT_SHIFT FMAN_SP_IC_FROM_INT_SHIFT -+ -+#define BMI_INT_BUF_MARG_SHIFT 28 -+#define BMI_EXT_BUF_MARG_START_SHIFT FMAN_SP_EXT_BUF_MARG_START_SHIFT -+ -+#define BMI_CMD_MR_LEAC 0x00200000 -+#define BMI_CMD_MR_SLEAC 0x00100000 -+#define BMI_CMD_MR_MA 0x00080000 -+#define BMI_CMD_MR_DEAS 0x00040000 -+#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \ -+ BMI_CMD_MR_SLEAC | \ -+ BMI_CMD_MR_MA | \ -+ BMI_CMD_MR_DEAS) -+#define BMI_CMD_TX_MR_DEF 0 -+#define BMI_CMD_OP_MR_DEF (BMI_CMD_MR_DEAS | \ -+ BMI_CMD_MR_MA) -+ -+#define BMI_CMD_ATTR_ORDER 0x80000000 -+#define BMI_CMD_ATTR_SYNC 0x02000000 -+#define BMI_CMD_ATTR_COLOR_SHIFT 26 -+ -+#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12 -+#define BMI_NEXT_ENG_FD_BITS_SHIFT 24 -+#define BMI_FRAME_END_CS_IGNORE_SHIFT 24 -+ -+#define BMI_COUNTERS_EN 0x80000000 -+ -+#define BMI_EXT_BUF_POOL_VALID FMAN_SP_EXT_BUF_POOL_VALID -+#define BMI_EXT_BUF_POOL_EN_COUNTER FMAN_SP_EXT_BUF_POOL_EN_COUNTER -+#define BMI_EXT_BUF_POOL_BACKUP FMAN_SP_EXT_BUF_POOL_BACKUP -+#define BMI_EXT_BUF_POOL_ID_SHIFT 16 -+#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000 -+#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16 -+ -+#define BMI_TX_FIFO_MIN_FILL_SHIFT 16 -+#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12 -+ -+#define MAX_PERFORMANCE_TASK_COMP 64 -+#define MAX_PERFORMANCE_RX_QUEUE_COMP 64 -+#define MAX_PERFORMANCE_TX_QUEUE_COMP 8 -+#define MAX_PERFORMANCE_DMA_COMP 16 -+#define MAX_PERFORMANCE_FIFO_COMP 1024 -+ -+#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24 -+#define BMI_PERFORMANCE_QUEUE_COMP_SHIFT 16 -+#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12 -+ -+#define BMI_RATE_LIMIT_GRAN_TX 16000 /* In Kbps */ -+#define BMI_RATE_LIMIT_GRAN_OP 10000 /* In frames */ -+#define BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS 1024 -+#define BMI_RATE_LIMIT_MAX_BURST_SIZE 1024 /* In KBytes */ -+#define BMI_RATE_LIMIT_MAX_BURST_SHIFT 16 -+#define BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN 0x80000000 -+#define BMI_RATE_LIMIT_SCALE_TSBS_SHIFT 16 -+#define BMI_RATE_LIMIT_SCALE_EN 0x80000000 -+#define BMI_SG_DISABLE FMAN_SP_SG_DISABLE -+ -+/** @Description QMI defines */ -+#define QMI_PORT_CFG_EN 0x80000000 -+#define QMI_PORT_CFG_EN_COUNTERS 0x10000000 -+ -+#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000 -+#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000 -+ -+#define QMI_DEQ_CFG_PRI 0x80000000 -+#define QMI_DEQ_CFG_TYPE1 0x10000000 -+#define QMI_DEQ_CFG_TYPE2 0x20000000 -+#define QMI_DEQ_CFG_TYPE3 0x30000000 -+#define QMI_DEQ_CFG_PREFETCH_PARTIAL 0x01000000 -+#define QMI_DEQ_CFG_PREFETCH_FULL 0x03000000 -+#define QMI_DEQ_CFG_SP_MASK 0xf -+#define QMI_DEQ_CFG_SP_SHIFT 20 -+ -+ -+/** @Description General port defines */ -+#define FMAN_PORT_EXT_POOLS_NUM(fm_rev_maj) \ -+ (((fm_rev_maj) == 4) ? 4 : 8) -+#define FMAN_PORT_MAX_EXT_POOLS_NUM 8 -+#define FMAN_PORT_OBS_EXT_POOLS_NUM 2 -+#define FMAN_PORT_CG_MAP_NUM 8 -+#define FMAN_PORT_PRS_RESULT_WORDS_NUM 8 -+#define FMAN_PORT_BMI_FIFO_UNITS 0x100 -+#define FMAN_PORT_IC_OFFSET_UNITS 0x10 -+ -+ -+/** @Collection FM Port Register Map */ -+ -+/** @Description BMI Rx port register map */ -+struct fman_port_rx_bmi_regs { -+ uint32_t fmbm_rcfg; /**< Rx Configuration */ -+ uint32_t fmbm_rst; /**< Rx Status */ -+ uint32_t fmbm_rda; /**< Rx DMA attributes*/ -+ uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/ -+ uint32_t fmbm_rfed; /**< Rx Frame End Data*/ -+ uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/ -+ uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/ -+ uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/ -+ uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/ -+ uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/ -+ uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/ -+ uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/ -+ uint32_t fmbm_rpp; /**< Rx Policer Profile */ -+ uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */ -+ uint32_t fmbm_reth; /**< Rx Excessive Threshold */ -+ uint32_t reserved003c[1]; /**< (0x03C 0x03F) */ -+ uint32_t fmbm_rprai[FMAN_PORT_PRS_RESULT_WORDS_NUM]; -+ /**< Rx Parse Results Array Init*/ -+ uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/ -+ uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/ -+ uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/ -+ uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/ -+ uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */ -+ uint32_t reserved0074[0x2]; /**< (0x074-0x07C) */ -+ uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */ -+ uint32_t reserved0080[0x20];/**< (0x080 0x0FF) */ -+ uint32_t fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM]; -+ /**< Buffer Manager pool Information-*/ -+ uint32_t fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM]; -+ /**< Allocate Counter-*/ -+ uint32_t reserved0130[8]; -+ /**< 0x130/0x140 - 0x15F reserved -*/ -+ uint32_t fmbm_rcgm[FMAN_PORT_CG_MAP_NUM]; -+ /**< Congestion Group Map*/ -+ uint32_t fmbm_mpd; /**< BM Pool Depletion */ -+ uint32_t reserved0184[0x1F]; /**< (0x184 0x1FF) */ -+ uint32_t fmbm_rstc; /**< Rx Statistics Counters*/ -+ uint32_t fmbm_rfrc; /**< Rx Frame Counter*/ -+ uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/ -+ uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/ -+ uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/ -+ uint32_t fmbm_rfdc; /**< Rx Frame Discard Counter*/ -+ uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/ -+ uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard nntr*/ -+ uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/ -+ uint32_t reserved0224[0x17]; /**< (0x224 0x27F) */ -+ uint32_t fmbm_rpc; /**< Rx Performance Counters*/ -+ uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/ -+ uint32_t fmbm_rccn; /**< Rx Cycle Counter*/ -+ uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/ -+ uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization cntr*/ -+ uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/ -+ uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/ -+ uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/ -+ uint32_t reserved02a0[0x18]; /**< (0x2A0 0x2FF) */ -+ uint32_t fmbm_rdbg; /**< Rx Debug-*/ -+}; -+ -+/** @Description BMI Tx port register map */ -+struct fman_port_tx_bmi_regs { -+ uint32_t fmbm_tcfg; /**< Tx Configuration */ -+ uint32_t fmbm_tst; /**< Tx Status */ -+ uint32_t fmbm_tda; /**< Tx DMA attributes */ -+ uint32_t fmbm_tfp; /**< Tx FIFO Parameters */ -+ uint32_t fmbm_tfed; /**< Tx Frame End Data */ -+ uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */ -+ uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */ -+ uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */ -+ uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */ -+ uint32_t fmbm_tefqid; /**< Tx Frame Error Queue ID */ -+ uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */ -+ uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */ -+ uint32_t fmbm_trlmt; /**< Tx Rate Limiter */ -+ uint32_t reserved0034[0x0e]; /**< (0x034-0x6c) */ -+ uint32_t fmbm_tccb; /**< Tx Coarse Classification base */ -+ uint32_t fmbm_tfne; /**< Tx Frame Next Engine */ -+ uint32_t fmbm_tpfcm[0x02]; /**< Tx Priority based Flow Control (PFC) Mapping */ -+ uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */ -+ uint32_t reserved0080[0x60]; /**< (0x080-0x200) */ -+ uint32_t fmbm_tstc; /**< Tx Statistics Counters */ -+ uint32_t fmbm_tfrc; /**< Tx Frame Counter */ -+ uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */ -+ uint32_t fmbm_tfledc; /**< Tx Frame len error discard cntr */ -+ uint32_t fmbm_tfufdc; /**< Tx Frame unsprt frmt discard cntr*/ -+ uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */ -+ uint32_t reserved0218[0x1A]; /**< (0x218-0x280) */ -+ uint32_t fmbm_tpc; /**< Tx Performance Counters*/ -+ uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/ -+ uint32_t fmbm_tccn; /**< Tx Cycle Counter*/ -+ uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/ -+ uint32_t fmbm_ttcquc; /**< Tx Transmit conf Q util Counter*/ -+ uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/ -+ uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/ -+}; -+ -+/** @Description BMI O/H port register map */ -+struct fman_port_oh_bmi_regs { -+ uint32_t fmbm_ocfg; /**< O/H Configuration */ -+ uint32_t fmbm_ost; /**< O/H Status */ -+ uint32_t fmbm_oda; /**< O/H DMA attributes */ -+ uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */ -+ uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */ -+ uint32_t fmbm_ofne; /**< O/H Frame Next Engine */ -+ uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */ -+ uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */ -+ uint32_t fmbm_opso; /**< O/H Parse Start Offset */ -+ uint32_t fmbm_opp; /**< O/H Policer Profile */ -+ uint32_t fmbm_occb; /**< O/H Coarse Classification base */ -+ uint32_t fmbm_oim; /**< O/H Internal margins*/ -+ uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/ -+ uint32_t fmbm_ofed; /**< O/H Frame End Data*/ -+ uint32_t reserved0030[2]; /**< (0x038 - 0x03F) */ -+ uint32_t fmbm_oprai[FMAN_PORT_PRS_RESULT_WORDS_NUM]; -+ /**< O/H Parse Results Array Initialization */ -+ uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */ -+ uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */ -+ uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */ -+ uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */ -+ uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */ -+ uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */ -+ uint32_t fmbm_orlmt; /**< O/H Rate Limiter */ -+ uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */ -+ uint32_t reserved0080[0x20]; /**< 0x080 - 0x0FF Reserved */ -+ uint32_t fmbm_oebmpi[2]; /**< Buf Mngr Observed Pool Info */ -+ uint32_t reserved0108[0x16]; /**< 0x108 - 0x15F Reserved */ -+ uint32_t fmbm_ocgm[FMAN_PORT_CG_MAP_NUM]; /**< Observed Congestion Group Map */ -+ uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */ -+ uint32_t reserved0184[0x1F]; /**< 0x184 - 0x1FF Reserved */ -+ uint32_t fmbm_ostc; /**< O/H Statistics Counters */ -+ uint32_t fmbm_ofrc; /**< O/H Frame Counter */ -+ uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */ -+ uint32_t fmbm_ofledc; /**< O/H Frames Len Err Discard Cntr */ -+ uint32_t fmbm_ofufdc; /**< O/H Frames Unsprtd Discard Cutr */ -+ uint32_t fmbm_offc; /**< O/H Filter Frames Counter */ -+ uint32_t fmbm_ofwdc; /**< Rx Frames WRED Discard Counter */ -+ uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Cntr */ -+ uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */ -+ uint32_t reserved0218[0x17]; /**< (0x218 - 0x27F) */ -+ uint32_t fmbm_opc; /**< O/H Performance Counters */ -+ uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */ -+ uint32_t fmbm_occn; /**< O/H Cycle Counter */ -+ uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */ -+ uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */ -+ uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */ -+}; -+ -+/** @Description BMI port register map */ -+union fman_port_bmi_regs { -+ struct fman_port_rx_bmi_regs rx; -+ struct fman_port_tx_bmi_regs tx; -+ struct fman_port_oh_bmi_regs oh; -+}; -+ -+/** @Description QMI port register map */ -+struct fman_port_qmi_regs { -+ uint32_t fmqm_pnc; /**< PortID n Configuration Register */ -+ uint32_t fmqm_pns; /**< PortID n Status Register */ -+ uint32_t fmqm_pnts; /**< PortID n Task Status Register */ -+ uint32_t reserved00c[4]; /**< 0xn00C - 0xn01B */ -+ uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */ -+ uint32_t fmqm_pnetfc; /**< PortID n Enq Total Frame Counter */ -+ uint32_t reserved024[2]; /**< 0xn024 - 0x02B */ -+ uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */ -+ uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */ -+ uint32_t fmqm_pndtfc; /**< PortID n Dequeue tot Frame cntr */ -+ uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID Dflt Cntr */ -+ uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */ -+}; -+ -+ -+enum fman_port_dma_swap { -+ E_FMAN_PORT_DMA_NO_SWAP, /**< No swap, transfer data as is */ -+ E_FMAN_PORT_DMA_SWAP_LE, -+ /**< The transferred data should be swapped in PPC Little Endian mode */ -+ E_FMAN_PORT_DMA_SWAP_BE -+ /**< The transferred data should be swapped in Big Endian mode */ -+}; -+ -+/* Default port color */ -+enum fman_port_color { -+ E_FMAN_PORT_COLOR_GREEN, /**< Default port color is green */ -+ E_FMAN_PORT_COLOR_YELLOW, /**< Default port color is yellow */ -+ E_FMAN_PORT_COLOR_RED, /**< Default port color is red */ -+ E_FMAN_PORT_COLOR_OVERRIDE /**< Ignore color */ -+}; -+ -+/* QMI dequeue from the SP channel - types */ -+enum fman_port_deq_type { -+ E_FMAN_PORT_DEQ_BY_PRI, -+ /**< Priority precedence and Intra-Class scheduling */ -+ E_FMAN_PORT_DEQ_ACTIVE_FQ, -+ /**< Active FQ precedence and Intra-Class scheduling */ -+ E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS -+ /**< Active FQ precedence and override Intra-Class scheduling */ -+}; -+ -+/* QMI dequeue prefetch modes */ -+enum fman_port_deq_prefetch { -+ E_FMAN_PORT_DEQ_NO_PREFETCH, /**< No prefetch mode */ -+ E_FMAN_PORT_DEQ_PART_PREFETCH, /**< Partial prefetch mode */ -+ E_FMAN_PORT_DEQ_FULL_PREFETCH /**< Full prefetch mode */ -+}; -+ -+/* Parameters for defining performance counters behavior */ -+struct fman_port_perf_cnt_params { -+ uint8_t task_val; /**< Task compare value */ -+ uint8_t queue_val; -+ /**< Rx or Tx conf queue compare value (unused for O/H ports) */ -+ uint8_t dma_val; /**< Dma compare value */ -+ uint32_t fifo_val; /**< Fifo compare value (in bytes) */ -+}; -+ -+/** @Description FM Port configuration structure, used at init */ -+struct fman_port_cfg { -+ struct fman_port_perf_cnt_params perf_cnt_params; -+ /* BMI parameters */ -+ enum fman_port_dma_swap dma_swap_data; -+ bool dma_ic_stash_on; -+ bool dma_header_stash_on; -+ bool dma_sg_stash_on; -+ bool dma_write_optimize; -+ uint16_t ic_ext_offset; -+ uint8_t ic_int_offset; -+ uint16_t ic_size; -+ enum fman_port_color color; -+ bool sync_req; -+ bool discard_override; -+ uint8_t checksum_bytes_ignore; -+ uint8_t rx_cut_end_bytes; -+ uint32_t rx_pri_elevation; -+ uint32_t rx_fifo_thr; -+ uint8_t rx_fd_bits; -+ uint8_t int_buf_start_margin; -+ uint16_t ext_buf_start_margin; -+ uint16_t ext_buf_end_margin; -+ uint32_t tx_fifo_min_level; -+ uint32_t tx_fifo_low_comf_level; -+ uint8_t tx_fifo_deq_pipeline_depth; -+ bool stats_counters_enable; -+ bool perf_counters_enable; -+ /* QMI parameters */ -+ bool deq_high_pri; -+ enum fman_port_deq_type deq_type; -+ enum fman_port_deq_prefetch deq_prefetch_opt; -+ uint16_t deq_byte_cnt; -+ bool queue_counters_enable; -+ bool no_scatter_gather; -+ int errata_A006675; -+ int errata_A006320; -+ int excessive_threshold_register; -+ int fmbm_rebm_has_sgd; -+ int fmbm_tfne_has_features; -+ int qmi_deq_options_support; -+}; -+ -+enum fman_port_type { -+ E_FMAN_PORT_TYPE_OP = 0, -+ /**< Offline parsing port, shares id-s with -+ * host command, so must have exclusive id-s */ -+ E_FMAN_PORT_TYPE_RX, /**< 1G Rx port */ -+ E_FMAN_PORT_TYPE_RX_10G, /**< 10G Rx port */ -+ E_FMAN_PORT_TYPE_TX, /**< 1G Tx port */ -+ E_FMAN_PORT_TYPE_TX_10G, /**< 10G Tx port */ -+ E_FMAN_PORT_TYPE_DUMMY, -+ E_FMAN_PORT_TYPE_HC = E_FMAN_PORT_TYPE_DUMMY -+ /**< Host command port, shares id-s with -+ * offline parsing ports, so must have exclusive id-s */ -+}; -+ -+struct fman_port_params { -+ uint32_t discard_mask; -+ uint32_t err_mask; -+ uint32_t dflt_fqid; -+ uint32_t err_fqid; -+ uint8_t deq_sp; -+ bool dont_release_buf; -+}; -+ -+/* Port context - used by most API functions */ -+struct fman_port { -+ enum fman_port_type type; -+ uint8_t fm_rev_maj; -+ uint8_t fm_rev_min; -+ union fman_port_bmi_regs *bmi_regs; -+ struct fman_port_qmi_regs *qmi_regs; -+ bool im_en; -+ uint8_t ext_pools_num; -+}; -+ -+/** @Description External buffer pools configuration */ -+struct fman_port_bpools { -+ uint8_t count; /**< Num of pools to set up */ -+ bool counters_enable; /**< Enable allocate counters */ -+ uint8_t grp_bp_depleted_num; -+ /**< Number of depleted pools - if reached the BMI indicates -+ * the MAC to send a pause frame */ -+ struct { -+ uint8_t bpid; /**< BM pool ID */ -+ uint16_t size; -+ /**< Pool's size - must be in ascending order */ -+ bool is_backup; -+ /**< If this is a backup pool */ -+ bool grp_bp_depleted; -+ /**< Consider this buffer in multiple pools depletion criteria*/ -+ bool single_bp_depleted; -+ /**< Consider this buffer in single pool depletion criteria */ -+ bool pfc_priorities_en; -+ } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM]; -+}; -+ -+enum fman_port_rate_limiter_scale_down { -+ E_FMAN_PORT_RATE_DOWN_NONE, -+ E_FMAN_PORT_RATE_DOWN_BY_2, -+ E_FMAN_PORT_RATE_DOWN_BY_4, -+ E_FMAN_PORT_RATE_DOWN_BY_8 -+}; -+ -+/* Rate limiter configuration */ -+struct fman_port_rate_limiter { -+ uint8_t count_1micro_bit; -+ bool high_burst_size_gran; -+ /**< Defines burst_size granularity for OP ports; when TRUE, -+ * burst_size below counts in frames, otherwise in 10^3 frames */ -+ uint16_t burst_size; -+ /**< Max burst size, in KBytes for Tx port, according to -+ * high_burst_size_gran definition for OP port */ -+ uint32_t rate; -+ /**< In Kbps for Tx port, in frames/sec for OP port */ -+ enum fman_port_rate_limiter_scale_down rate_factor; -+}; -+ -+/* BMI statistics counters */ -+enum fman_port_stats_counters { -+ E_FMAN_PORT_STATS_CNT_FRAME, -+ /**< Number of processed frames; valid for all ports */ -+ E_FMAN_PORT_STATS_CNT_DISCARD, -+ /**< For Rx ports - frames discarded by QMAN, for Tx or O/H ports - -+ * frames discarded due to DMA error; valid for all ports */ -+ E_FMAN_PORT_STATS_CNT_DEALLOC_BUF, -+ /**< Number of buffer deallocate operations; valid for all ports */ -+ E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME, -+ /**< Number of bad Rx frames, like CRC error, Rx FIFO overflow etc; -+ * valid for Rx ports only */ -+ E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME, -+ /**< Number of Rx oversized frames, that is frames exceeding max frame -+ * size configured for the corresponding ETH controller; -+ * valid for Rx ports only */ -+ E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF, -+ /**< Frames discarded due to lack of external buffers; valid for -+ * Rx ports only */ -+ E_FMAN_PORT_STATS_CNT_LEN_ERR, -+ /**< Frames discarded due to frame length error; valid for Tx and -+ * O/H ports only */ -+ E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT, -+ /**< Frames discarded due to unsupported FD format; valid for Tx -+ * and O/H ports only */ -+ E_FMAN_PORT_STATS_CNT_FILTERED_FRAME, -+ /**< Number of frames filtered out by PCD module; valid for -+ * Rx and OP ports only */ -+ E_FMAN_PORT_STATS_CNT_DMA_ERR, -+ /**< Frames rejected by QMAN that were not able to release their -+ * buffers due to DMA error; valid for Rx and O/H ports only */ -+ E_FMAN_PORT_STATS_CNT_WRED_DISCARD -+ /**< Frames going through O/H port that were not able to to enter the -+ * return queue due to WRED algorithm; valid for O/H ports only */ -+}; -+ -+/* BMI performance counters */ -+enum fman_port_perf_counters { -+ E_FMAN_PORT_PERF_CNT_CYCLE, /**< Cycle counter */ -+ E_FMAN_PORT_PERF_CNT_TASK_UTIL, /**< Tasks utilization counter */ -+ E_FMAN_PORT_PERF_CNT_QUEUE_UTIL, -+ /**< For Rx ports - Rx queue utilization, for Tx ports - Tx conf queue -+ * utilization; not valid for O/H ports */ -+ E_FMAN_PORT_PERF_CNT_DMA_UTIL, /**< DMA utilization counter */ -+ E_FMAN_PORT_PERF_CNT_FIFO_UTIL, /**< FIFO utilization counter */ -+ E_FMAN_PORT_PERF_CNT_RX_PAUSE -+ /**< Number of cycles in which Rx pause activation control is on; -+ * valid for Rx ports only */ -+}; -+ -+/* QMI counters */ -+enum fman_port_qmi_counters { -+ E_FMAN_PORT_ENQ_TOTAL, /**< EnQ tot frame cntr */ -+ E_FMAN_PORT_DEQ_TOTAL, /**< DeQ tot frame cntr; invalid for Rx ports */ -+ E_FMAN_PORT_DEQ_FROM_DFLT, -+ /**< Dequeue from default FQID counter not valid for Rx ports */ -+ E_FMAN_PORT_DEQ_CONFIRM /**< DeQ confirm cntr invalid for Rx ports */ -+}; -+ -+ -+/** @Collection FM Port API */ -+void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type); -+int fman_port_init(struct fman_port *port, -+ struct fman_port_cfg *cfg, -+ struct fman_port_params *params); -+int fman_port_enable(struct fman_port *port); -+int fman_port_disable(const struct fman_port *port); -+int fman_port_set_bpools(const struct fman_port *port, -+ const struct fman_port_bpools *bp); -+int fman_port_set_rate_limiter(struct fman_port *port, -+ struct fman_port_rate_limiter *rate_limiter); -+int fman_port_delete_rate_limiter(struct fman_port *port); -+int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask); -+int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask); -+int fman_port_modify_rx_fd_bits(struct fman_port *port, -+ uint8_t rx_fd_bits, -+ bool add); -+int fman_port_set_perf_cnt_params(struct fman_port *port, -+ struct fman_port_perf_cnt_params *params); -+int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable); -+int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable); -+int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable); -+int fman_port_set_bpool_cnt_mode(struct fman_port *port, -+ uint8_t bpid, -+ bool enable); -+uint32_t fman_port_get_stats_counter(struct fman_port *port, -+ enum fman_port_stats_counters counter); -+void fman_port_set_stats_counter(struct fman_port *port, -+ enum fman_port_stats_counters counter, -+ uint32_t value); -+uint32_t fman_port_get_perf_counter(struct fman_port *port, -+ enum fman_port_perf_counters counter); -+void fman_port_set_perf_counter(struct fman_port *port, -+ enum fman_port_perf_counters counter, -+ uint32_t value); -+uint32_t fman_port_get_qmi_counter(struct fman_port *port, -+ enum fman_port_qmi_counters counter); -+void fman_port_set_qmi_counter(struct fman_port *port, -+ enum fman_port_qmi_counters counter, -+ uint32_t value); -+uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid); -+void fman_port_set_bpool_counter(struct fman_port *port, -+ uint8_t bpid, -+ uint32_t value); -+int fman_port_add_congestion_grps(struct fman_port *port, -+ uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]); -+int fman_port_remove_congestion_grps(struct fman_port *port, -+ uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]); -+ -+ -+#endif /* __FSL_FMAN_PORT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h -@@ -0,0 +1,102 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __FSL_FMAN_PRS_H -+#define __FSL_FMAN_PRS_H -+ -+#include "common/general.h" -+ -+#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000 -+#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000 -+ -+#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000 -+#define FM_PCD_PRS_RPIMAC_EN 0x00000001 -+#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000 -+#define FM_PCD_PRS_SINGLE_ECC 0x00004000 -+#define FM_PCD_PRS_DOUBLE_ECC 0x00004000 -+#define PRS_MAX_CYCLE_LIMIT 8191 -+ -+#define DEFAULT_MAX_PRS_CYC_LIM 0 -+ -+struct fman_prs_regs { -+ uint32_t fmpr_rpclim; -+ uint32_t fmpr_rpimac; -+ uint32_t pmeec; -+ uint32_t res00c[5]; -+ uint32_t fmpr_pevr; -+ uint32_t fmpr_pever; -+ uint32_t res028; -+ uint32_t fmpr_perr; -+ uint32_t fmpr_perer; -+ uint32_t res034; -+ uint32_t res038[10]; -+ uint32_t fmpr_ppsc; -+ uint32_t res064; -+ uint32_t fmpr_pds; -+ uint32_t fmpr_l2rrs; -+ uint32_t fmpr_l3rrs; -+ uint32_t fmpr_l4rrs; -+ uint32_t fmpr_srrs; -+ uint32_t fmpr_l2rres; -+ uint32_t fmpr_l3rres; -+ uint32_t fmpr_l4rres; -+ uint32_t fmpr_srres; -+ uint32_t fmpr_spcs; -+ uint32_t fmpr_spscs; -+ uint32_t fmpr_hxscs; -+ uint32_t fmpr_mrcs; -+ uint32_t fmpr_mwcs; -+ uint32_t fmpr_mrscs; -+ uint32_t fmpr_mwscs; -+ uint32_t fmpr_fcscs; -+}; -+ -+struct fman_prs_cfg { -+ uint32_t port_id_stat; -+ uint16_t max_prs_cyc_lim; -+ uint32_t prs_exceptions; -+}; -+ -+uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask); -+uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs); -+void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event); -+uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask); -+uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs); -+void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event); -+void fman_prs_defconfig(struct fman_prs_cfg *cfg); -+int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg); -+void fman_prs_enable(struct fman_prs_regs *regs); -+void fman_prs_disable(struct fman_prs_regs *regs); -+int fman_prs_is_enabled(struct fman_prs_regs *regs); -+void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk); -+void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable); -+#endif /* __FSL_FMAN_PRS_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h -@@ -0,0 +1,449 @@ -+/* -+ * Copyright 2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __FSL_FMAN_RTC_H -+#define __FSL_FMAN_RTC_H -+ -+#include "common/general.h" -+ -+/* FM RTC Registers definitions */ -+#define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000 -+#define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000 -+#define FMAN_RTC_TMR_CTRL_FS 0x10000000 -+#define FMAN_RTC_TMR_CTRL_PP1L 0x08000000 -+#define FMAN_RTC_TMR_CTRL_PP2L 0x04000000 -+#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000 -+#define FMAN_RTC_TMR_CTRL_FRD 0x00004000 -+#define FMAN_RTC_TMR_CTRL_SLV 0x00002000 -+#define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100 -+#define FMAN_RTC_TMR_CTRL_COPH 0x00000080 -+#define FMAN_RTC_TMR_CTRL_CIPH 0x00000040 -+#define FMAN_RTC_TMR_CTRL_TMSR 0x00000020 -+#define FMAN_RTC_TMR_CTRL_DBG 0x00000010 -+#define FMAN_RTC_TMR_CTRL_BYP 0x00000008 -+#define FMAN_RTC_TMR_CTRL_TE 0x00000004 -+#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003 -+#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001 -+#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000 -+#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16 -+ -+#define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000 -+#define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000 -+#define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000 -+#define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000 -+#define FMAN_RTC_TMR_TEVENT_PP1 0x00000080 -+#define FMAN_RTC_TMR_TEVENT_PP2 0x00000040 -+#define FMAN_RTC_TMR_TEVENT_PP3 0x00000020 -+#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\ -+ FMAN_RTC_TMR_TEVENT_ETS1 |\ -+ FMAN_RTC_TMR_TEVENT_ALM2 |\ -+ FMAN_RTC_TMR_TEVENT_ALM1 |\ -+ FMAN_RTC_TMR_TEVENT_PP1 |\ -+ FMAN_RTC_TMR_TEVENT_PP2 |\ -+ FMAN_RTC_TMR_TEVENT_PP3) -+ -+#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF -+ -+/**************************************************************************//** -+ @Description FM RTC Alarm Polarity Options. -+*//***************************************************************************/ -+enum fman_rtc_alarm_polarity { -+ E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */ -+ E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */ -+}; -+ -+/**************************************************************************//** -+ @Description FM RTC Trigger Polarity Options. -+*//***************************************************************************/ -+enum fman_rtc_trigger_polarity { -+ E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */ -+ E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */ -+}; -+ -+/**************************************************************************//** -+ @Description IEEE1588 Timer Module FM RTC Optional Clock Sources. -+*//***************************************************************************/ -+enum fman_src_clock { -+ E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer -+ reference clock */ -+ E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */ -+ E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */ -+}; -+ -+/* RTC default values */ -+#define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM -+#define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE -+#define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE -+#define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH -+#define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE -+#define DEFAULT_PULSE_REALIGN FALSE -+ -+#define FMAN_RTC_MAX_NUM_OF_ALARMS 3 -+#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4 -+#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3 -+ -+/**************************************************************************//** -+ @Description FM RTC timer alarm -+*//***************************************************************************/ -+struct t_tmr_alarm{ -+ uint32_t tmr_alarm_h; /**< */ -+ uint32_t tmr_alarm_l; /**< */ -+}; -+ -+/**************************************************************************//** -+ @Description FM RTC timer Ex trigger -+*//***************************************************************************/ -+struct t_tmr_ext_trigger{ -+ uint32_t tmr_etts_h; /**< */ -+ uint32_t tmr_etts_l; /**< */ -+}; -+ -+struct rtc_regs { -+ uint32_t tmr_id; /* 0x000 Module ID register */ -+ uint32_t tmr_id2; /* 0x004 Controller ID register */ -+ uint32_t reserved0008[30]; -+ uint32_t tmr_ctrl; /* 0x0080 timer control register */ -+ uint32_t tmr_tevent; /* 0x0084 timer event register */ -+ uint32_t tmr_temask; /* 0x0088 timer event mask register */ -+ uint32_t reserved008c[3]; -+ uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */ -+ uint32_t tmr_cnt_l; /* 0x009c timer counter low register */ -+ uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */ -+ uint32_t tmr_acc; /* 0x00a4 timer accumulator register */ -+ uint32_t tmr_prsc; /* 0x00a8 timer prescale */ -+ uint32_t reserved00ac; -+ uint32_t tmr_off_h; /* 0x00b0 timer offset high */ -+ uint32_t tmr_off_l; /* 0x00b4 timer offset low */ -+ struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer -+ alarm */ -+ uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer -+ fixed period interval */ -+ struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS]; -+ /* 0x00e0 time stamp general purpose external */ -+ uint32_t reserved00f0[4]; -+}; -+ -+struct rtc_cfg { -+ enum fman_src_clock src_clk; -+ uint32_t ext_src_clk_freq; -+ uint32_t rtc_freq_hz; -+ bool timer_slave_mode; -+ bool invert_input_clk_phase; -+ bool invert_output_clk_phase; -+ uint32_t events_mask; -+ bool bypass; /**< Indicates if frequency compensation -+ is bypassed */ -+ bool pulse_realign; -+ enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS]; -+ enum fman_rtc_trigger_polarity trigger_polarity -+ [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS]; -+}; -+ -+/** -+ * fman_rtc_defconfig() - Get default RTC configuration -+ * @cfg: pointer to configuration structure. -+ * -+ * Call this function to obtain a default set of configuration values for -+ * initializing RTC. The user can overwrite any of the values before calling -+ * fman_rtc_init(), if specific configuration needs to be applied. -+ */ -+void fman_rtc_defconfig(struct rtc_cfg *cfg); -+ -+/** -+ * fman_rtc_get_events() - Get the events -+ * @regs: Pointer to RTC register block -+ * -+ * Returns: The events -+ */ -+uint32_t fman_rtc_get_events(struct rtc_regs *regs); -+ -+/** -+ * fman_rtc_get_interrupt_mask() - Get the events mask -+ * @regs: Pointer to RTC register block -+ * -+ * Returns: The events mask -+ */ -+uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs); -+ -+ -+/** -+ * fman_rtc_set_interrupt_mask() - Set the events mask -+ * @regs: Pointer to RTC register block -+ * @mask: The mask to set -+ */ -+void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask); -+ -+/** -+ * fman_rtc_get_event() - Check if specific events occurred -+ * @regs: Pointer to RTC register block -+ * @ev_mask: a mask of the events to check -+ * -+ * Returns: 0 if the events did not occur. Non zero if one of the events occurred -+ */ -+uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask); -+ -+/** -+ * fman_rtc_check_and_clear_event() - Clear events which are on -+ * @regs: Pointer to RTC register block -+ * -+ * Returns: A mask of the events which were cleared -+ */ -+uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs); -+ -+/** -+ * fman_rtc_ack_event() - Clear events -+ * @regs: Pointer to RTC register block -+ * @events: The events to disable -+ */ -+void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events); -+ -+/** -+ * fman_rtc_enable_interupt() - Enable events interrupts -+ * @regs: Pointer to RTC register block -+ * @mask: The events to disable -+ */ -+void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask); -+ -+/** -+ * fman_rtc_disable_interupt() - Disable events interrupts -+ * @regs: Pointer to RTC register block -+ * @mask: The events to disable -+ */ -+void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask); -+ -+/** -+ * fman_rtc_get_timer_ctrl() - Get the control register -+ * @regs: Pointer to RTC register block -+ * -+ * Returns: The control register value -+ */ -+uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs); -+ -+/** -+ * fman_rtc_set_timer_ctrl() - Set timer control register -+ * @regs: Pointer to RTC register block -+ * @val: The value to set -+ */ -+void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val); -+ -+/** -+ * fman_rtc_get_frequency_compensation() - Get the frequency compensation -+ * @regs: Pointer to RTC register block -+ * -+ * Returns: The timer counter -+ */ -+uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs); -+ -+/** -+ * fman_rtc_set_frequency_compensation() - Set frequency compensation -+ * @regs: Pointer to RTC register block -+ * @val: The value to set -+ */ -+void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val); -+ -+/** -+ * fman_rtc_get_trigger_stamp() - Get a trigger stamp -+ * @regs: Pointer to RTC register block -+ * @id: The id of the trigger stamp -+ * -+ * Returns: The time stamp -+ */ -+uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id); -+ -+/** -+ * fman_rtc_set_timer_alarm_l() - Set timer alarm low register -+ * @regs: Pointer to RTC register block -+ * @index: The index of alarm to set -+ * @val: The value to set -+ */ -+void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, -+ uint32_t val); -+ -+/** -+ * fman_rtc_set_timer_alarm() - Set timer alarm -+ * @regs: Pointer to RTC register block -+ * @index: The index of alarm to set -+ * @val: The value to set -+ */ -+void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val); -+ -+/** -+ * fman_rtc_set_timer_fiper() - Set timer fiper -+ * @regs: Pointer to RTC register block -+ * @index: The index of fiper to set -+ * @val: The value to set -+ */ -+void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val); -+ -+/** -+ * fman_rtc_set_timer_offset() - Set timer offset -+ * @regs: Pointer to RTC register block -+ * @val: The value to set -+ */ -+void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val); -+ -+/** -+ * fman_rtc_get_timer() - Get the timer counter -+ * @regs: Pointer to RTC register block -+ * -+ * Returns: The timer counter -+ */ -+static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs) -+{ -+ uint64_t time; -+ /* TMR_CNT_L must be read first to get an accurate value */ -+ time = (uint64_t)ioread32be(®s->tmr_cnt_l); -+ time |= ((uint64_t)ioread32be(®s->tmr_cnt_h) << 32); -+ -+ return time; -+} -+ -+/** -+ * fman_rtc_set_timer() - Set timer counter -+ * @regs: Pointer to RTC register block -+ * @val: The value to set -+ */ -+static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val) -+{ -+ iowrite32be((uint32_t)val, ®s->tmr_cnt_l); -+ iowrite32be((uint32_t)(val >> 32), ®s->tmr_cnt_h); -+} -+ -+/** -+ * fman_rtc_timers_soft_reset() - Soft reset -+ * @regs: Pointer to RTC register block -+ * -+ * Resets all the timer registers and state machines for the 1588 IP and -+ * the attached client 1588 -+ */ -+void fman_rtc_timers_soft_reset(struct rtc_regs *regs); -+ -+/** -+ * fman_rtc_clear_external_trigger() - Clear an external trigger -+ * @regs: Pointer to RTC register block -+ * @id: The id of the trigger to clear -+ */ -+void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id); -+ -+/** -+ * fman_rtc_clear_periodic_pulse() - Clear periodic pulse -+ * @regs: Pointer to RTC register block -+ * @id: The id of the fiper to clear -+ */ -+void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id); -+ -+/** -+ * fman_rtc_enable() - Enable RTC hardware block -+ * @regs: Pointer to RTC register block -+ */ -+void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock); -+ -+/** -+ * fman_rtc_is_enabled() - Is RTC hardware block enabled -+ * @regs: Pointer to RTC register block -+ * -+ * Return: TRUE if enabled -+ */ -+bool fman_rtc_is_enabled(struct rtc_regs *regs); -+ -+/** -+ * fman_rtc_disable() - Disable RTC hardware block -+ * @regs: Pointer to RTC register block -+ */ -+void fman_rtc_disable(struct rtc_regs *regs); -+ -+/** -+ * fman_rtc_init() - Init RTC hardware block -+ * @cfg: RTC configuration data -+ * @regs: Pointer to RTC register block -+ * @num_alarms: Number of alarms in RTC -+ * @num_fipers: Number of fipers in RTC -+ * @num_ext_triggers: Number of external triggers in RTC -+ * @freq_compensation: Frequency compensation -+ * @output_clock_divisor: Output clock divisor -+ * -+ * This function initializes RTC and applies basic configuration. -+ */ -+void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms, -+ int num_fipers, int num_ext_triggers, bool init_freq_comp, -+ uint32_t freq_compensation, uint32_t output_clock_divisor); -+ -+/** -+ * fman_rtc_set_alarm() - Set an alarm -+ * @regs: Pointer to RTC register block -+ * @id: id of alarm -+ * @val: value to write -+ * @enable: should interrupt be enabled -+ */ -+void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable); -+ -+/** -+ * fman_rtc_set_periodic_pulse() - Set an alarm -+ * @regs: Pointer to RTC register block -+ * @id: id of fiper -+ * @val: value to write -+ * @enable: should interrupt be enabled -+ */ -+void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val, -+ bool enable); -+ -+/** -+ * fman_rtc_set_ext_trigger() - Set an external trigger -+ * @regs: Pointer to RTC register block -+ * @id: id of trigger -+ * @enable: should interrupt be enabled -+ * @use_pulse_as_input: use the pulse as input -+ */ -+void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable, -+ bool use_pulse_as_input); -+ -+struct fm_rtc_alarm_params { -+ uint8_t alarm_id; /**< 0 or 1 */ -+ uint64_t alarm_time; /**< In nanoseconds, the time when the -+ alarm should go off - must be a -+ multiple of the RTC period */ -+ void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will -+ be called when RTC reaches alarmTime */ -+ bool clear_on_expiration; /**< TRUE to turn off the alarm once -+ expired.*/ -+}; -+ -+struct fm_rtc_periodic_pulse_params { -+ uint8_t periodic_pulse_id; /**< 0 or 1 */ -+ uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple -+ of the RTC period */ -+ void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This -+ routine will be called every -+ periodicPulsePeriod. */ -+}; -+ -+#endif /* __FSL_FMAN_RTC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h -@@ -0,0 +1,138 @@ -+/* -+ * Copyright 2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __FSL_FMAN_SP_H -+#define __FSL_FMAN_SP_H -+ -+#include "common/general.h" -+#include "fsl_fman.h" -+ -+ -+struct fm_pcd_storage_profile_regs{ -+ uint32_t fm_sp_ebmpi[8]; -+ /*offset 0 - 0xc*/ -+ /**< Buffer Manager pool Information */ -+ -+ uint32_t fm_sp_acnt; /*offset 0x20*/ -+ uint32_t fm_sp_ebm; /*offset 0x24*/ -+ uint32_t fm_sp_da; /*offset 0x28*/ -+ uint32_t fm_sp_icp; /*offset 0x2c*/ -+ uint32_t fm_sp_mpd; /*offset 0x30*/ -+ uint32_t res1[2]; /*offset 0x34 - 0x38*/ -+ uint32_t fm_sp_spliodn; /*offset 0x3c*/ -+}; -+ -+/**************************************************************************//** -+ @Description structure for defining internal context copying -+*//***************************************************************************/ -+struct fman_sp_int_context_data_copy{ -+ uint16_t ext_buf_offset; /**< Offset in External buffer to which -+ internal context is copied to (Rx) -+ or taken from (Tx, Op). */ -+ uint8_t int_context_offset; /**< Offset within internal context to copy -+ from (Rx) or to copy to (Tx, Op).*/ -+ uint16_t size; /**< Internal offset size to be copied */ -+}; -+ -+/**************************************************************************//** -+ @Description struct for defining external buffer margins -+*//***************************************************************************/ -+struct fman_sp_buf_margins{ -+ uint16_t start_margins; /**< Number of bytes to be left at the -+ beginning of the external buffer (must be -+ divisible by 16) */ -+ uint16_t end_margins; /**< number of bytes to be left at the end of -+ the external buffer(must be divisible by 16)*/ -+}; -+ -+struct fm_storage_profile_params { -+ struct fman_ext_pools fm_ext_pools; -+ struct fman_backup_bm_pools backup_pools; -+ struct fman_sp_int_context_data_copy *int_context; -+ struct fman_sp_buf_margins *buf_margins; -+ enum fman_dma_swap_option dma_swap_data; -+ enum fman_dma_cache_option int_context_cache_attr; -+ enum fman_dma_cache_option header_cache_attr; -+ enum fman_dma_cache_option scatter_gather_cache_attr; -+ bool dma_write_optimize; -+ uint16_t liodn_offset; -+ bool no_scather_gather; -+ struct fman_buf_pool_depletion buf_pool_depletion; -+}; -+ -+/**************************************************************************//** -+ @Description Registers bit fields -+*//***************************************************************************/ -+#define FMAN_SP_EXT_BUF_POOL_EN_COUNTER 0x40000000 -+#define FMAN_SP_EXT_BUF_POOL_VALID 0x80000000 -+#define FMAN_SP_EXT_BUF_POOL_BACKUP 0x20000000 -+#define FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE 0x00100000 -+#define FMAN_SP_SG_DISABLE 0x80000000 -+ -+/* shifts */ -+#define FMAN_SP_EXT_BUF_POOL_ID_SHIFT 16 -+#define FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT 16 -+#define FMAN_SP_EXT_BUF_MARG_START_SHIFT 16 -+#define FMAN_SP_EXT_BUF_MARG_END_SHIFT 0 -+#define FMAN_SP_DMA_ATTR_SWP_SHIFT 30 -+#define FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT 28 -+#define FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT 26 -+#define FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT 24 -+#define FMAN_SP_IC_TO_EXT_SHIFT 16 -+#define FMAN_SP_IC_FROM_INT_SHIFT 8 -+#define FMAN_SP_IC_SIZE_SHIFT 0 -+ -+/**************************************************************************//** -+ @Description defaults -+*//***************************************************************************/ -+#define DEFAULT_FMAN_SP_DMA_SWAP_DATA FMAN_DMA_NO_SWP -+#define DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR FMAN_DMA_NO_STASH -+#define DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR FMAN_DMA_NO_STASH -+#define DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR FMAN_DMA_NO_STASH -+#define DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE TRUE -+#define DEFAULT_FMAN_SP_NO_SCATTER_GATHER FALSE -+ -+void fman_vsp_defconfig(struct fm_storage_profile_params *cfg); -+ -+void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs, -+ uint16_t index, struct fm_storage_profile_params *fm_vsp_params, -+ int port_max_num_of_ext_pools, int bm_max_num_of_pools, -+ int max_num_of_pfc_priorities); -+ -+uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs, -+ uint16_t index); -+ -+void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs, -+ uint16_t index, uint32_t value); -+ -+ -+#endif /* __FSL_FMAN_SP_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h -@@ -0,0 +1,479 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __FSL_FMAN_TGEC_H -+#define __FSL_FMAN_TGEC_H -+ -+#include "common/general.h" -+#include "fsl_enet.h" -+ -+ -+/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */ -+#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff -+ -+enum tgec_counters { -+ E_TGEC_COUNTER_R64, -+ E_TGEC_COUNTER_R127, -+ E_TGEC_COUNTER_R255, -+ E_TGEC_COUNTER_R511, -+ E_TGEC_COUNTER_R1023, -+ E_TGEC_COUNTER_R1518, -+ E_TGEC_COUNTER_R1519X, -+ E_TGEC_COUNTER_TRFRG, -+ E_TGEC_COUNTER_TRJBR, -+ E_TGEC_COUNTER_RDRP, -+ E_TGEC_COUNTER_RALN, -+ E_TGEC_COUNTER_TRUND, -+ E_TGEC_COUNTER_TROVR, -+ E_TGEC_COUNTER_RXPF, -+ E_TGEC_COUNTER_TXPF, -+ E_TGEC_COUNTER_ROCT, -+ E_TGEC_COUNTER_RMCA, -+ E_TGEC_COUNTER_RBCA, -+ E_TGEC_COUNTER_RPKT, -+ E_TGEC_COUNTER_RUCA, -+ E_TGEC_COUNTER_RERR, -+ E_TGEC_COUNTER_TOCT, -+ E_TGEC_COUNTER_TMCA, -+ E_TGEC_COUNTER_TBCA, -+ E_TGEC_COUNTER_TUCA, -+ E_TGEC_COUNTER_TERR -+}; -+ -+/* Command and Configuration Register (COMMAND_CONFIG) */ -+#define CMD_CFG_EN_TIMESTAMP 0x00100000 -+#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000 -+#define CMD_CFG_NO_LEN_CHK 0x00020000 -+#define CMD_CFG_SEND_IDLE 0x00010000 -+#define CMD_CFG_RX_ER_DISC 0x00004000 -+#define CMD_CFG_CMD_FRM_EN 0x00002000 -+#define CMD_CFG_STAT_CLR 0x00001000 -+#define CMD_CFG_LOOPBACK_EN 0x00000400 -+#define CMD_CFG_TX_ADDR_INS 0x00000200 -+#define CMD_CFG_PAUSE_IGNORE 0x00000100 -+#define CMD_CFG_PAUSE_FWD 0x00000080 -+#define CMD_CFG_PROMIS_EN 0x00000010 -+#define CMD_CFG_WAN_MODE 0x00000008 -+#define CMD_CFG_RX_EN 0x00000002 -+#define CMD_CFG_TX_EN 0x00000001 -+ -+/* Interrupt Mask Register (IMASK) */ -+#define TGEC_IMASK_MDIO_SCAN_EVENT 0x00010000 -+#define TGEC_IMASK_MDIO_CMD_CMPL 0x00008000 -+#define TGEC_IMASK_REM_FAULT 0x00004000 -+#define TGEC_IMASK_LOC_FAULT 0x00002000 -+#define TGEC_IMASK_TX_ECC_ER 0x00001000 -+#define TGEC_IMASK_TX_FIFO_UNFL 0x00000800 -+#define TGEC_IMASK_TX_FIFO_OVFL 0x00000400 -+#define TGEC_IMASK_TX_ER 0x00000200 -+#define TGEC_IMASK_RX_FIFO_OVFL 0x00000100 -+#define TGEC_IMASK_RX_ECC_ER 0x00000080 -+#define TGEC_IMASK_RX_JAB_FRM 0x00000040 -+#define TGEC_IMASK_RX_OVRSZ_FRM 0x00000020 -+#define TGEC_IMASK_RX_RUNT_FRM 0x00000010 -+#define TGEC_IMASK_RX_FRAG_FRM 0x00000008 -+#define TGEC_IMASK_RX_LEN_ER 0x00000004 -+#define TGEC_IMASK_RX_CRC_ER 0x00000002 -+#define TGEC_IMASK_RX_ALIGN_ER 0x00000001 -+ -+#define TGEC_EVENTS_MASK \ -+ ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \ -+ TGEC_IMASK_MDIO_CMD_CMPL | \ -+ TGEC_IMASK_REM_FAULT | \ -+ TGEC_IMASK_LOC_FAULT | \ -+ TGEC_IMASK_TX_ECC_ER | \ -+ TGEC_IMASK_TX_FIFO_UNFL | \ -+ TGEC_IMASK_TX_FIFO_OVFL | \ -+ TGEC_IMASK_TX_ER | \ -+ TGEC_IMASK_RX_FIFO_OVFL | \ -+ TGEC_IMASK_RX_ECC_ER | \ -+ TGEC_IMASK_RX_JAB_FRM | \ -+ TGEC_IMASK_RX_OVRSZ_FRM | \ -+ TGEC_IMASK_RX_RUNT_FRM | \ -+ TGEC_IMASK_RX_FRAG_FRM | \ -+ TGEC_IMASK_RX_LEN_ER | \ -+ TGEC_IMASK_RX_CRC_ER | \ -+ TGEC_IMASK_RX_ALIGN_ER)) -+ -+/* Hashtable Control Register (HASHTABLE_CTRL) */ -+#define TGEC_HASH_MCAST_SHIFT 23 -+#define TGEC_HASH_MCAST_EN 0x00000200 -+#define TGEC_HASH_ADR_MSK 0x000001ff -+ -+#define DEFAULT_WAN_MODE_ENABLE FALSE -+#define DEFAULT_PROMISCUOUS_MODE_ENABLE FALSE -+#define DEFAULT_PAUSE_FORWARD_ENABLE FALSE -+#define DEFAULT_PAUSE_IGNORE FALSE -+#define DEFAULT_TX_ADDR_INS_ENABLE FALSE -+#define DEFAULT_LOOPBACK_ENABLE FALSE -+#define DEFAULT_CMD_FRAME_ENABLE FALSE -+#define DEFAULT_RX_ERROR_DISCARD FALSE -+#define DEFAULT_SEND_IDLE_ENABLE FALSE -+#define DEFAULT_NO_LENGTH_CHECK_ENABLE TRUE -+#define DEFAULT_LGTH_CHECK_NOSTDR FALSE -+#define DEFAULT_TIME_STAMP_ENABLE FALSE -+#define DEFAULT_TX_IPG_LENGTH 12 -+#define DEFAULT_MAX_FRAME_LENGTH 0x600 -+#define DEFAULT_PAUSE_QUANT 0xf000 -+ -+/* -+ * 10G memory map -+ */ -+struct tgec_regs { -+ uint32_t tgec_id; /* 0x000 Controller ID */ -+ uint32_t reserved001[1]; /* 0x004 */ -+ uint32_t command_config; /* 0x008 Control and configuration */ -+ uint32_t mac_addr_0; /* 0x00c Lower 32 bits of the MAC adr */ -+ uint32_t mac_addr_1; /* 0x010 Upper 16 bits of the MAC adr */ -+ uint32_t maxfrm; /* 0x014 Maximum frame length */ -+ uint32_t pause_quant; /* 0x018 Pause quanta */ -+ uint32_t rx_fifo_sections; /* 0x01c */ -+ uint32_t tx_fifo_sections; /* 0x020 */ -+ uint32_t rx_fifo_almost_f_e; /* 0x024 */ -+ uint32_t tx_fifo_almost_f_e; /* 0x028 */ -+ uint32_t hashtable_ctrl; /* 0x02c Hash table control*/ -+ uint32_t mdio_cfg_status; /* 0x030 */ -+ uint32_t mdio_command; /* 0x034 */ -+ uint32_t mdio_data; /* 0x038 */ -+ uint32_t mdio_regaddr; /* 0x03c */ -+ uint32_t status; /* 0x040 */ -+ uint32_t tx_ipg_len; /* 0x044 Transmitter inter-packet-gap */ -+ uint32_t mac_addr_2; /* 0x048 Lower 32 bits of 2nd MAC adr */ -+ uint32_t mac_addr_3; /* 0x04c Upper 16 bits of 2nd MAC adr */ -+ uint32_t rx_fifo_ptr_rd; /* 0x050 */ -+ uint32_t rx_fifo_ptr_wr; /* 0x054 */ -+ uint32_t tx_fifo_ptr_rd; /* 0x058 */ -+ uint32_t tx_fifo_ptr_wr; /* 0x05c */ -+ uint32_t imask; /* 0x060 Interrupt mask */ -+ uint32_t ievent; /* 0x064 Interrupt event */ -+ uint32_t udp_port; /* 0x068 Defines a UDP Port number */ -+ uint32_t type_1588v2; /* 0x06c Type field for 1588v2 */ -+ uint32_t reserved070[4]; /* 0x070 */ -+ /*10Ge Statistics Counter */ -+ uint32_t tfrm_u; /* 80 aFramesTransmittedOK */ -+ uint32_t tfrm_l; /* 84 aFramesTransmittedOK */ -+ uint32_t rfrm_u; /* 88 aFramesReceivedOK */ -+ uint32_t rfrm_l; /* 8c aFramesReceivedOK */ -+ uint32_t rfcs_u; /* 90 aFrameCheckSequenceErrors */ -+ uint32_t rfcs_l; /* 94 aFrameCheckSequenceErrors */ -+ uint32_t raln_u; /* 98 aAlignmentErrors */ -+ uint32_t raln_l; /* 9c aAlignmentErrors */ -+ uint32_t txpf_u; /* A0 aPAUSEMACCtrlFramesTransmitted */ -+ uint32_t txpf_l; /* A4 aPAUSEMACCtrlFramesTransmitted */ -+ uint32_t rxpf_u; /* A8 aPAUSEMACCtrlFramesReceived */ -+ uint32_t rxpf_l; /* Ac aPAUSEMACCtrlFramesReceived */ -+ uint32_t rlong_u; /* B0 aFrameTooLongErrors */ -+ uint32_t rlong_l; /* B4 aFrameTooLongErrors */ -+ uint32_t rflr_u; /* B8 aInRangeLengthErrors */ -+ uint32_t rflr_l; /* Bc aInRangeLengthErrors */ -+ uint32_t tvlan_u; /* C0 VLANTransmittedOK */ -+ uint32_t tvlan_l; /* C4 VLANTransmittedOK */ -+ uint32_t rvlan_u; /* C8 VLANReceivedOK */ -+ uint32_t rvlan_l; /* Cc VLANReceivedOK */ -+ uint32_t toct_u; /* D0 ifOutOctets */ -+ uint32_t toct_l; /* D4 ifOutOctets */ -+ uint32_t roct_u; /* D8 ifInOctets */ -+ uint32_t roct_l; /* Dc ifInOctets */ -+ uint32_t ruca_u; /* E0 ifInUcastPkts */ -+ uint32_t ruca_l; /* E4 ifInUcastPkts */ -+ uint32_t rmca_u; /* E8 ifInMulticastPkts */ -+ uint32_t rmca_l; /* Ec ifInMulticastPkts */ -+ uint32_t rbca_u; /* F0 ifInBroadcastPkts */ -+ uint32_t rbca_l; /* F4 ifInBroadcastPkts */ -+ uint32_t terr_u; /* F8 ifOutErrors */ -+ uint32_t terr_l; /* Fc ifOutErrors */ -+ uint32_t reserved100[2]; /* 100-108*/ -+ uint32_t tuca_u; /* 108 ifOutUcastPkts */ -+ uint32_t tuca_l; /* 10c ifOutUcastPkts */ -+ uint32_t tmca_u; /* 110 ifOutMulticastPkts */ -+ uint32_t tmca_l; /* 114 ifOutMulticastPkts */ -+ uint32_t tbca_u; /* 118 ifOutBroadcastPkts */ -+ uint32_t tbca_l; /* 11c ifOutBroadcastPkts */ -+ uint32_t rdrp_u; /* 120 etherStatsDropEvents */ -+ uint32_t rdrp_l; /* 124 etherStatsDropEvents */ -+ uint32_t reoct_u; /* 128 etherStatsOctets */ -+ uint32_t reoct_l; /* 12c etherStatsOctets */ -+ uint32_t rpkt_u; /* 130 etherStatsPkts */ -+ uint32_t rpkt_l; /* 134 etherStatsPkts */ -+ uint32_t trund_u; /* 138 etherStatsUndersizePkts */ -+ uint32_t trund_l; /* 13c etherStatsUndersizePkts */ -+ uint32_t r64_u; /* 140 etherStatsPkts64Octets */ -+ uint32_t r64_l; /* 144 etherStatsPkts64Octets */ -+ uint32_t r127_u; /* 148 etherStatsPkts65to127Octets */ -+ uint32_t r127_l; /* 14c etherStatsPkts65to127Octets */ -+ uint32_t r255_u; /* 150 etherStatsPkts128to255Octets */ -+ uint32_t r255_l; /* 154 etherStatsPkts128to255Octets */ -+ uint32_t r511_u; /* 158 etherStatsPkts256to511Octets */ -+ uint32_t r511_l; /* 15c etherStatsPkts256to511Octets */ -+ uint32_t r1023_u; /* 160 etherStatsPkts512to1023Octets */ -+ uint32_t r1023_l; /* 164 etherStatsPkts512to1023Octets */ -+ uint32_t r1518_u; /* 168 etherStatsPkts1024to1518Octets */ -+ uint32_t r1518_l; /* 16c etherStatsPkts1024to1518Octets */ -+ uint32_t r1519x_u; /* 170 etherStatsPkts1519toX */ -+ uint32_t r1519x_l; /* 174 etherStatsPkts1519toX */ -+ uint32_t trovr_u; /* 178 etherStatsOversizePkts */ -+ uint32_t trovr_l; /* 17c etherStatsOversizePkts */ -+ uint32_t trjbr_u; /* 180 etherStatsJabbers */ -+ uint32_t trjbr_l; /* 184 etherStatsJabbers */ -+ uint32_t trfrg_u; /* 188 etherStatsFragments */ -+ uint32_t trfrg_l; /* 18C etherStatsFragments */ -+ uint32_t rerr_u; /* 190 ifInErrors */ -+ uint32_t rerr_l; /* 194 ifInErrors */ -+}; -+ -+/** -+ * struct tgec_cfg - TGEC configuration -+ * -+ * @rx_error_discard: Receive Erroneous Frame Discard Enable. When set to 1 -+ * any frame received with an error is discarded in the -+ * Core and not forwarded to the Client interface. -+ * When set to 0 (Reset value), erroneous Frames are -+ * forwarded to the Client interface with ff_rx_err -+ * asserted. -+ * @pause_ignore: Ignore Pause Frame Quanta. If set to 1 received pause -+ * frames are ignored by the MAC. When set to 0 -+ * (Reset value) the transmit process is stopped for the -+ * amount of time specified in the pause quanta received -+ * within a pause frame. -+ * @pause_forward_enable: -+ * Terminate / Forward Pause Frames. If set to 1 pause -+ * frames are forwarded to the user application. When set -+ * to 0 (Reset value) pause frames are terminated and -+ * discarded within the MAC. -+ * @no_length_check_enable: -+ * Payload Length Check Disable. When set to 0 -+ * (Reset value), the Core checks the frame's payload -+ * length with the Frame Length/Type field, when set to 1 -+ * the payload length check is disabled. -+ * @cmd_frame_enable: Enables reception of all command frames. When set to 1 -+ * all Command Frames are accepted, when set to 0 -+ * (Reset Value) only Pause Frames are accepted and all -+ * other Command Frames are rejected. -+ * @send_idle_enable: Force Idle Generation. When set to 1, the MAC -+ * permanently sends XGMII Idle sequences even when faults -+ * are received. -+ * @wan_mode_enable: WAN Mode Enable. Sets WAN mode (1) or LAN mode -+ * (0, default) of operation. -+ * @promiscuous_mode_enable: -+ * Enables MAC promiscuous operation. When set to 1, all -+ * frames are received without any MAC address filtering, -+ * when set to 0 (Reset value) Unicast Frames with a -+ * destination address not matching the Core MAC Address -+ * (MAC Address programmed in Registers MAC_ADDR_0 and -+ * MAC_ADDR_1 or the MAC address programmed in Registers -+ * MAC_ADDR_2 and MAC_ADDR_3) are rejected. -+ * @tx_addr_ins_enable: Set Source MAC Address on Transmit. If set to 1 the -+ * MAC overwrites the source MAC address received from the -+ * Client Interface with one of the MAC addresses. If set -+ * to 0 (Reset value), the source MAC address from the -+ * Client Interface is transmitted unmodified to the line. -+ * @loopback_enable: PHY Interface Loopback. When set to 1, the signal -+ * loop_ena is set to '1', when set to 0 (Reset value) -+ * the signal loop_ena is set to 0. -+ * @lgth_check_nostdr: The Core interprets the Length/Type field differently -+ * depending on the value of this Bit -+ * @time_stamp_enable: This bit selects between enabling and disabling the -+ * IEEE 1588 functionality. 1: IEEE 1588 is enabled -+ * 0: IEEE 1588 is disabled -+ * @max_frame_length: Maximum supported received frame length. -+ * The 10GEC MAC supports reception of any frame size up -+ * to 16,352 bytes (0x3FE0). Typical settings are -+ * 0x05EE (1,518 bytes) for standard frames. -+ * Default setting is 0x0600 (1,536 bytes). -+ * Received frames that exceed this stated maximum -+ * are truncated. -+ * @pause_quant: Pause quanta value used with transmitted pause frames. -+ * Each quanta represents a 512 bit-times. -+ * @tx_ipg_length: Transmit Inter-Packet-Gap (IPG) value. A 6-bit value: -+ * Depending on LAN or WAN mode of operation the value has -+ * the following meaning: - LAN Mode: Number of octets in -+ * steps of 4. Valid values are 8, 12, 16, ... 100. DIC is -+ * fully supported (see 10.6.1 page 49) for any setting. A -+ * default of 12 (reset value) must be set to conform to -+ * IEEE802.3ae. Warning: When set to 8, PCS layers may not -+ * be able to perform clock rate compensation. - WAN Mode: -+ * Stretch factor. Valid values are 4..15. The stretch -+ * factor is calculated as (value+1)*8. A default of 12 -+ * (reset value) must be set to conform to IEEE 802.3ae -+ * (i.e. 13*8=104). A larger value shrinks the IPG -+ * (increasing bandwidth). -+ * -+ * This structure contains basic TGEC configuration and must be passed to -+ * fman_tgec_init() function. A default set of configuration values can be -+ * obtained by calling fman_tgec_defconfig(). -+ */ -+struct tgec_cfg { -+ bool rx_error_discard; -+ bool pause_ignore; -+ bool pause_forward_enable; -+ bool no_length_check_enable; -+ bool cmd_frame_enable; -+ bool send_idle_enable; -+ bool wan_mode_enable; -+ bool promiscuous_mode_enable; -+ bool tx_addr_ins_enable; -+ bool loopback_enable; -+ bool lgth_check_nostdr; -+ bool time_stamp_enable; -+ uint16_t max_frame_length; -+ uint16_t pause_quant; -+ uint32_t tx_ipg_length; -+ bool skip_fman11_workaround; -+}; -+ -+ -+void fman_tgec_defconfig(struct tgec_cfg *cfg); -+ -+/** -+ * fman_tgec_init() - Init tgec hardware block -+ * @regs: Pointer to tgec register block -+ * @cfg: tgec configuration data -+ * @exceptions_mask: initial exceptions mask -+ * -+ * This function initializes the tgec controller and applies its -+ * basic configuration. -+ * -+ * Returns: 0 if successful, an error code otherwise. -+ */ -+ -+int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg, -+ uint32_t exception_mask); -+ -+void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx); -+ -+void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx); -+ -+uint32_t fman_tgec_get_revision(struct tgec_regs *regs); -+ -+void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *macaddr); -+ -+void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val); -+ -+/** -+ * fman_tgec_reset_stat() - Completely resets all TGEC HW counters -+ * @regs: Pointer to TGEC register block -+ */ -+void fman_tgec_reset_stat(struct tgec_regs *regs); -+ -+/** -+ * fman_tgec_get_counter() - Reads TGEC HW counters -+ * @regs: Pointer to TGEC register block -+ * @reg_name: Counter name according to the appropriate enum -+ * -+ * Returns: Required counter value -+ */ -+uint64_t fman_tgec_get_counter(struct tgec_regs *regs, -+ enum tgec_counters reg_name); -+ -+/** -+ * fman_tgec_set_hash_table() - Sets the Hashtable Control Register -+ * @regs: Pointer to TGEC register block -+ * @value: Value to be written in Hashtable Control Register -+ */ -+void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value); -+ -+/** -+ * fman_tgec_set_tx_pause_frames() - Sets the Pause Quanta Register -+ * @regs: Pointer to TGEC register block -+ * @pause_time: Pause quanta value used with transmitted pause frames. -+ * Each quanta represents a 512 bit-times -+ */ -+void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time); -+ -+/** -+ * fman_tgec_set_rx_ignore_pause_frames() - Changes the policy WRT pause frames -+ * @regs: Pointer to TGEC register block -+ * @en: Ignore/Respond to pause frame quanta -+ * -+ * Sets the value of PAUSE_IGNORE field in the COMMAND_CONFIG Register -+ * 0 - MAC stops transmit process for the duration specified -+ * in the Pause frame quanta of a received Pause frame. -+ * 1 - MAC ignores received Pause frames. -+ */ -+void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en); -+ -+/** -+ * fman_tgec_enable_1588_time_stamp() - change timestamp functionality -+ * @regs: Pointer to TGEC register block -+ * @en: enable/disable timestamp functionality -+ * -+ * Sets the value of EN_TIMESTAMP field in the COMMAND_CONFIG Register -+ * IEEE 1588 timestamp functionality control: -+ * 0 disabled, 1 enabled -+ */ -+ -+void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en); -+ -+uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask); -+ -+void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask); -+ -+uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs); -+ -+/** -+ * fman_tgec_add_addr_in_paddr() - Sets additional exact match MAC address -+ * @regs: Pointer to TGEC register block -+ * @addr_ptr: Pointer to 6-byte array containing the MAC address -+ * -+ * Sets the additional station MAC address -+ */ -+void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *addr_ptr); -+ -+void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs); -+ -+void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask); -+ -+void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask); -+ -+void fman_tgec_reset_filter_table(struct tgec_regs *regs); -+ -+void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc); -+ -+ -+/** -+ * fman_tgec_get_max_frame_len() - Returns the maximum frame length value -+ * @regs: Pointer to TGEC register block -+ */ -+uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs); -+ -+/** -+ * fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007() - Initialize the -+ * main tgec configuration parameters -+ * @regs: Pointer to TGEC register block -+ * -+ * TODO -+ */ -+void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs -+ *regs); -+ -+ -+#endif /* __FSL_FMAN_TGEC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h -@@ -0,0 +1,291 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/** -+ -+ @File dpaa_integration_ext.h -+ -+ @Description T4240 FM external definitions and structures. -+*//***************************************************************************/ -+#ifndef __DPAA_INTEGRATION_EXT_H -+#define __DPAA_INTEGRATION_EXT_H -+ -+#include "std_ext.h" -+ -+ -+#define DPAA_VERSION 11 -+ -+/**************************************************************************//** -+ @Description DPAA SW Portals Enumeration. -+*//***************************************************************************/ -+typedef enum -+{ -+ e_DPAA_SWPORTAL0 = 0, -+ e_DPAA_SWPORTAL1, -+ e_DPAA_SWPORTAL2, -+ e_DPAA_SWPORTAL3, -+ e_DPAA_SWPORTAL4, -+ e_DPAA_SWPORTAL5, -+ e_DPAA_SWPORTAL6, -+ e_DPAA_SWPORTAL7, -+ e_DPAA_SWPORTAL8, -+ e_DPAA_SWPORTAL9, -+ e_DPAA_SWPORTAL10, -+ e_DPAA_SWPORTAL11, -+ e_DPAA_SWPORTAL12, -+ e_DPAA_SWPORTAL13, -+ e_DPAA_SWPORTAL14, -+ e_DPAA_SWPORTAL15, -+ e_DPAA_SWPORTAL16, -+ e_DPAA_SWPORTAL17, -+ e_DPAA_SWPORTAL18, -+ e_DPAA_SWPORTAL19, -+ e_DPAA_SWPORTAL20, -+ e_DPAA_SWPORTAL21, -+ e_DPAA_SWPORTAL22, -+ e_DPAA_SWPORTAL23, -+ e_DPAA_SWPORTAL24, -+ e_DPAA_SWPORTAL_DUMMY_LAST -+} e_DpaaSwPortal; -+ -+/**************************************************************************//** -+ @Description DPAA Direct Connect Portals Enumeration. -+*//***************************************************************************/ -+typedef enum -+{ -+ e_DPAA_DCPORTAL0 = 0, -+ e_DPAA_DCPORTAL1, -+ e_DPAA_DCPORTAL2, -+ e_DPAA_DCPORTAL_DUMMY_LAST -+} e_DpaaDcPortal; -+ -+#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST -+#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST -+ -+/***************************************************************************** -+ QMan INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */ -+#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */ -+#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */ -+#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) -+ /**< FQIDs range - 24 bits */ -+ -+/**************************************************************************//** -+ @Description Work Queue Channel assignments in QMan. -+*//***************************************************************************/ -+typedef enum -+{ -+ e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */ -+ e_QM_FQ_CHANNEL_SWPORTAL1, -+ e_QM_FQ_CHANNEL_SWPORTAL2, -+ e_QM_FQ_CHANNEL_SWPORTAL3, -+ e_QM_FQ_CHANNEL_SWPORTAL4, -+ e_QM_FQ_CHANNEL_SWPORTAL5, -+ e_QM_FQ_CHANNEL_SWPORTAL6, -+ e_QM_FQ_CHANNEL_SWPORTAL7, -+ e_QM_FQ_CHANNEL_SWPORTAL8, -+ e_QM_FQ_CHANNEL_SWPORTAL9, -+ e_QM_FQ_CHANNEL_SWPORTAL10, -+ e_QM_FQ_CHANNEL_SWPORTAL11, -+ e_QM_FQ_CHANNEL_SWPORTAL12, -+ e_QM_FQ_CHANNEL_SWPORTAL13, -+ e_QM_FQ_CHANNEL_SWPORTAL14, -+ e_QM_FQ_CHANNEL_SWPORTAL15, -+ e_QM_FQ_CHANNEL_SWPORTAL16, -+ e_QM_FQ_CHANNEL_SWPORTAL17, -+ e_QM_FQ_CHANNEL_SWPORTAL18, -+ e_QM_FQ_CHANNEL_SWPORTAL19, -+ e_QM_FQ_CHANNEL_SWPORTAL20, -+ e_QM_FQ_CHANNEL_SWPORTAL21, -+ e_QM_FQ_CHANNEL_SWPORTAL22, -+ e_QM_FQ_CHANNEL_SWPORTAL23, -+ e_QM_FQ_CHANNEL_SWPORTAL24, -+ -+ e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */ -+ e_QM_FQ_CHANNEL_POOL2, -+ e_QM_FQ_CHANNEL_POOL3, -+ e_QM_FQ_CHANNEL_POOL4, -+ e_QM_FQ_CHANNEL_POOL5, -+ e_QM_FQ_CHANNEL_POOL6, -+ e_QM_FQ_CHANNEL_POOL7, -+ e_QM_FQ_CHANNEL_POOL8, -+ e_QM_FQ_CHANNEL_POOL9, -+ e_QM_FQ_CHANNEL_POOL10, -+ e_QM_FQ_CHANNEL_POOL11, -+ e_QM_FQ_CHANNEL_POOL12, -+ e_QM_FQ_CHANNEL_POOL13, -+ e_QM_FQ_CHANNEL_POOL14, -+ e_QM_FQ_CHANNEL_POOL15, -+ -+ e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0: -+ connected to FMan 0; assigned in incrementing order to -+ each sub-portal (SP) in the portal */ -+ e_QM_FQ_CHANNEL_FMAN0_SP1, -+ e_QM_FQ_CHANNEL_FMAN0_SP2, -+ e_QM_FQ_CHANNEL_FMAN0_SP3, -+ e_QM_FQ_CHANNEL_FMAN0_SP4, -+ e_QM_FQ_CHANNEL_FMAN0_SP5, -+ e_QM_FQ_CHANNEL_FMAN0_SP6, -+ e_QM_FQ_CHANNEL_FMAN0_SP7, -+ e_QM_FQ_CHANNEL_FMAN0_SP8, -+ e_QM_FQ_CHANNEL_FMAN0_SP9, -+ e_QM_FQ_CHANNEL_FMAN0_SP10, -+ e_QM_FQ_CHANNEL_FMAN0_SP11, -+ e_QM_FQ_CHANNEL_FMAN0_SP12, -+ e_QM_FQ_CHANNEL_FMAN0_SP13, -+ e_QM_FQ_CHANNEL_FMAN0_SP14, -+ e_QM_FQ_CHANNEL_FMAN0_SP15, -+ -+ e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */ -+ e_QM_FQ_CHANNEL_RMAN_SP1, -+ -+ e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2: -+ connected to SEC */ -+} e_QmFQChannel; -+ -+/***************************************************************************** -+ BMan INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */ -+ -+/***************************************************************************** -+ SEC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define SEC_NUM_OF_DECOS 3 -+#define SEC_ALL_DECOS_MASK 0x00000003 -+ -+ -+/***************************************************************************** -+ FM INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define INTG_MAX_NUM_OF_FM 2 -+/* Ports defines */ -+#define FM_MAX_NUM_OF_1G_MACS 6 -+#define FM_MAX_NUM_OF_10G_MACS 2 -+#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS) -+#define FM_MAX_NUM_OF_OH_PORTS 6 -+ -+#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS -+#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS -+#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS) -+ -+#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS -+#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS -+#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS) -+ -+#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */ -+#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */ -+#define FM_MAX_NUM_OF_SUB_PORTALS 16 -+#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0 -+ -+#define FM_VSP_MAX_NUM_OF_ENTRIES 64 -+#define FM_MAX_NUM_OF_PFC_PRIORITIES 8 -+ -+/* RAMs defines */ -+#define FM_MURAM_SIZE (384 * KILOBYTE) -+#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE) -+#define FM_NUM_OF_CTRL 4 -+ -+/* PCD defines */ -+#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */ -+#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */ -+#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */ -+#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */ -+#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */ -+ -+/* RTC defines */ -+#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */ -+#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */ -+#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */ -+ -+/* QMI defines */ -+#define QMI_MAX_NUM_OF_TNUMS 64 -+#define QMI_DEF_TNUMS_THRESH 32 -+/* FPM defines */ -+#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4 -+ -+/* DMA defines */ -+#define DMA_THRESH_MAX_COMMQ 83 -+#define DMA_THRESH_MAX_BUF 127 -+ -+/* BMI defines */ -+#define BMI_MAX_NUM_OF_TASKS 128 -+#define BMI_MAX_NUM_OF_DMAS 84 -+ -+#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE) -+#define PORT_MAX_WEIGHT 16 -+ -+#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE -+ -+/* Unique T4240 */ -+#define FM_OP_OPEN_DMA_MIN_LIMIT -+#define FM_NO_RESTRICT_ON_ACCESS_RSRC -+#define FM_NO_OP_OBSERVED_POOLS -+#define FM_FRAME_END_PARAMS_FOR_OP -+#define FM_DEQ_PIPELINE_PARAMS_FOR_OP -+#define FM_QMI_NO_SINGLE_ECC_EXCEPTION -+ -+#define FM_NO_GUARANTEED_RESET_VALUES -+ -+/* FM errata */ -+#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 -+#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 -+#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 -+#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 -+#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 -+#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 -+ -+#define FM_BCB_ERRATA_BMI_SW001 -+#define FM_LEN_CHECK_ERRATA_FMAN_SW002 -+#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */ -+#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */ -+ -+/***************************************************************************** -+ RMan INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */ -+#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */ -+ -+/* RMan erratas */ -+#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756 -+ -+/***************************************************************************** -+ FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define NUM_OF_RX_SC 16 -+#define NUM_OF_TX_SC 16 -+ -+#define NUM_OF_SA_PER_RX_SC 2 -+#define NUM_OF_SA_PER_TX_SC 2 -+ -+#endif /* __DPAA_INTEGRATION_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h -@@ -0,0 +1,71 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ -+ @File part_ext.h -+ -+ @Description Definitions for the part (integration) module. -+*//***************************************************************************/ -+ -+#ifndef __PART_EXT_H -+#define __PART_EXT_H -+ -+#include "std_ext.h" -+#include "part_integration_ext.h" -+ -+#if !(defined(P1023) || \ -+ defined(P2041) || \ -+ defined(P3041) || \ -+ defined(P4080) || \ -+ defined(P5020) || \ -+ defined(P5040) || \ -+ defined(B4860) || \ -+ defined(T4240)) -+#error "unable to proceed without chip-definition" -+#endif -+ -+ -+/**************************************************************************//* -+ @Description Part data structure - must be contained in any integration -+ data structure. -+*//***************************************************************************/ -+typedef struct t_Part -+{ -+ uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId); -+ /**< Returns the address of the module's memory map base. */ -+ e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress); -+ /**< Returns the module's ID according to its memory map base. */ -+} t_Part; -+ -+ -+#endif /* __PART_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h -@@ -0,0 +1,304 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/** -+ -+ @File part_integration_ext.h -+ -+ @Description T4240 external definitions and structures. -+*//***************************************************************************/ -+#ifndef __PART_INTEGRATION_EXT_H -+#define __PART_INTEGRATION_EXT_H -+ -+#include "std_ext.h" -+#include "ddr_std_ext.h" -+#include "enet_ext.h" -+#include "dpaa_integration_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group T4240_chip_id T4240 Application Programming Interface -+ -+ @Description T4240 Chip functions,definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+#define CORE_E6500 -+ -+#define INTG_MAX_NUM_OF_CORES 24 -+ -+ -+/**************************************************************************//** -+ @Description Module types. -+*//***************************************************************************/ -+typedef enum e_ModuleId -+{ -+ e_MODULE_ID_DUART_1 = 0, -+ e_MODULE_ID_DUART_2, -+ e_MODULE_ID_DUART_3, -+ e_MODULE_ID_DUART_4, -+ e_MODULE_ID_LAW, -+ e_MODULE_ID_IFC, -+ e_MODULE_ID_PAMU, -+ e_MODULE_ID_QM, /**< Queue manager module */ -+ e_MODULE_ID_BM, /**< Buffer manager module */ -+ e_MODULE_ID_QM_CE_PORTAL_0, -+ e_MODULE_ID_QM_CI_PORTAL_0, -+ e_MODULE_ID_QM_CE_PORTAL_1, -+ e_MODULE_ID_QM_CI_PORTAL_1, -+ e_MODULE_ID_QM_CE_PORTAL_2, -+ e_MODULE_ID_QM_CI_PORTAL_2, -+ e_MODULE_ID_QM_CE_PORTAL_3, -+ e_MODULE_ID_QM_CI_PORTAL_3, -+ e_MODULE_ID_QM_CE_PORTAL_4, -+ e_MODULE_ID_QM_CI_PORTAL_4, -+ e_MODULE_ID_QM_CE_PORTAL_5, -+ e_MODULE_ID_QM_CI_PORTAL_5, -+ e_MODULE_ID_QM_CE_PORTAL_6, -+ e_MODULE_ID_QM_CI_PORTAL_6, -+ e_MODULE_ID_QM_CE_PORTAL_7, -+ e_MODULE_ID_QM_CI_PORTAL_7, -+ e_MODULE_ID_QM_CE_PORTAL_8, -+ e_MODULE_ID_QM_CI_PORTAL_8, -+ e_MODULE_ID_QM_CE_PORTAL_9, -+ e_MODULE_ID_QM_CI_PORTAL_9, -+ e_MODULE_ID_BM_CE_PORTAL_0, -+ e_MODULE_ID_BM_CI_PORTAL_0, -+ e_MODULE_ID_BM_CE_PORTAL_1, -+ e_MODULE_ID_BM_CI_PORTAL_1, -+ e_MODULE_ID_BM_CE_PORTAL_2, -+ e_MODULE_ID_BM_CI_PORTAL_2, -+ e_MODULE_ID_BM_CE_PORTAL_3, -+ e_MODULE_ID_BM_CI_PORTAL_3, -+ e_MODULE_ID_BM_CE_PORTAL_4, -+ e_MODULE_ID_BM_CI_PORTAL_4, -+ e_MODULE_ID_BM_CE_PORTAL_5, -+ e_MODULE_ID_BM_CI_PORTAL_5, -+ e_MODULE_ID_BM_CE_PORTAL_6, -+ e_MODULE_ID_BM_CI_PORTAL_6, -+ e_MODULE_ID_BM_CE_PORTAL_7, -+ e_MODULE_ID_BM_CI_PORTAL_7, -+ e_MODULE_ID_BM_CE_PORTAL_8, -+ e_MODULE_ID_BM_CI_PORTAL_8, -+ e_MODULE_ID_BM_CE_PORTAL_9, -+ e_MODULE_ID_BM_CI_PORTAL_9, -+ e_MODULE_ID_FM, /**< Frame manager module */ -+ e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */ -+ e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */ -+ e_MODULE_ID_FM_BMI, /**< FM BMI block */ -+ e_MODULE_ID_FM_QMI, /**< FM QMI block */ -+ e_MODULE_ID_FM_PARSER, /**< FM parser block */ -+ e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */ -+ e_MODULE_ID_FM_PLCR, /**< FM Policer */ -+ e_MODULE_ID_FM_KG, /**< FM Keygen */ -+ e_MODULE_ID_FM_DMA, /**< FM DMA */ -+ e_MODULE_ID_FM_FPM, /**< FM FPM */ -+ e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */ -+ e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */ -+ e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */ -+ e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */ -+ e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */ -+ e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */ -+ e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */ -+ e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */ -+ e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */ -+ e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */ -+ e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */ -+ e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */ -+ -+ e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */ -+ e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */ -+ e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */ -+ e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */ -+ e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */ -+ e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */ -+ e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */ -+ e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */ -+ e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */ -+ e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */ -+ e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */ -+ e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */ -+ -+ e_MODULE_ID_PIC, /**< PIC */ -+ e_MODULE_ID_GPIO, /**< GPIO */ -+ e_MODULE_ID_SERDES, /**< SERDES */ -+ e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */ -+ e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */ -+ -+ e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */ -+ -+ e_MODULE_ID_DUMMY_LAST -+} e_ModuleId; -+ -+#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST -+ -+#if 0 /* using unified values */ -+/***************************************************************************** -+ INTEGRATION-SPECIFIC MODULE CODES -+******************************************************************************/ -+#define MODULE_UNKNOWN 0x00000000 -+#define MODULE_MEM 0x00010000 -+#define MODULE_MM 0x00020000 -+#define MODULE_CORE 0x00030000 -+#define MODULE_T4240 0x00040000 -+#define MODULE_T4240_PLATFORM 0x00050000 -+#define MODULE_PM 0x00060000 -+#define MODULE_MMU 0x00070000 -+#define MODULE_PIC 0x00080000 -+#define MODULE_CPC 0x00090000 -+#define MODULE_DUART 0x000a0000 -+#define MODULE_SERDES 0x000b0000 -+#define MODULE_PIO 0x000c0000 -+#define MODULE_QM 0x000d0000 -+#define MODULE_BM 0x000e0000 -+#define MODULE_SEC 0x000f0000 -+#define MODULE_LAW 0x00100000 -+#define MODULE_LBC 0x00110000 -+#define MODULE_PAMU 0x00120000 -+#define MODULE_FM 0x00130000 -+#define MODULE_FM_MURAM 0x00140000 -+#define MODULE_FM_PCD 0x00150000 -+#define MODULE_FM_RTC 0x00160000 -+#define MODULE_FM_MAC 0x00170000 -+#define MODULE_FM_PORT 0x00180000 -+#define MODULE_FM_SP 0x00190000 -+#define MODULE_DPA_PORT 0x001a0000 -+#define MODULE_MII 0x001b0000 -+#define MODULE_I2C 0x001c0000 -+#define MODULE_DMA 0x001d0000 -+#define MODULE_DDR 0x001e0000 -+#define MODULE_ESPI 0x001f0000 -+#define MODULE_DPAA_IPSEC 0x00200000 -+#endif /* using unified values */ -+ -+/***************************************************************************** -+ PAMU INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define PAMU_NUM_OF_PARTITIONS 4 -+ -+/***************************************************************************** -+ LAW INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define LAW_NUM_OF_WINDOWS 32 -+#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */ -+#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */ -+ -+ -+/***************************************************************************** -+ LBC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+/**************************************************************************//** -+ @Group lbc_exception_grp LBC Exception Unit -+ -+ @Description LBC Exception unit API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Anchor lbc_exbm -+ -+ @Collection LBC Errors Bit Mask -+ -+ These errors are reported through the exceptions callback.. -+ The values can be or'ed in any combination in the errors mask -+ parameter of the errors report structure. -+ -+ These errors can also be passed as a bit-mask to -+ LBC_EnableErrorChecking() or LBC_DisableErrorChecking(), -+ for enabling or disabling error checking. -+ @{ -+*//***************************************************************************/ -+#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */ -+#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */ -+#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */ -+#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */ -+ -+#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \ -+ LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT) -+ /**< All possible errors */ -+/* @} */ -+/** @} */ /* end of lbc_exception_grp group */ -+ -+#define LBC_INCORRECT_ERROR_REPORT_ERRATA -+ -+#define LBC_NUM_OF_BANKS 8 -+#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */ -+#define LBC_PARITY_SUPPORT -+#define LBC_ADDRESS_HOLD_TIME_CTRL -+#define LBC_HIGH_CLK_DIVIDERS -+#define LBC_FCM_AVAILABLE -+ -+/***************************************************************************** -+ GPIO INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define GPIO_PORT_OFFSET_0x1000 -+ -+#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module; -+ Each port contains up to 32 I/O pins. */ -+ -+#define GPIO_VALID_PIN_MASKS \ -+ { /* Port A */ 0xFFFFFFFF, \ -+ /* Port B */ 0xFFFFFFFF, \ -+ /* Port C */ 0xFFFFFFFF } -+ -+#define GPIO_VALID_INTR_MASKS \ -+ { /* Port A */ 0xFFFFFFFF, \ -+ /* Port B */ 0xFFFFFFFF, \ -+ /* Port C */ 0xFFFFFFFF } -+ -+ -+ -+#endif /* __PART_INTEGRATION_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h -@@ -0,0 +1,293 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/** -+ -+ @File dpaa_integration_ext.h -+ -+ @Description T4240 FM external definitions and structures. -+*//***************************************************************************/ -+#ifndef __DPAA_INTEGRATION_EXT_H -+#define __DPAA_INTEGRATION_EXT_H -+ -+#include "std_ext.h" -+ -+ -+#define DPAA_VERSION 11 -+ -+/**************************************************************************//** -+ @Description DPAA SW Portals Enumeration. -+*//***************************************************************************/ -+typedef enum -+{ -+ e_DPAA_SWPORTAL0 = 0, -+ e_DPAA_SWPORTAL1, -+ e_DPAA_SWPORTAL2, -+ e_DPAA_SWPORTAL3, -+ e_DPAA_SWPORTAL4, -+ e_DPAA_SWPORTAL5, -+ e_DPAA_SWPORTAL6, -+ e_DPAA_SWPORTAL7, -+ e_DPAA_SWPORTAL8, -+ e_DPAA_SWPORTAL9, -+ e_DPAA_SWPORTAL10, -+ e_DPAA_SWPORTAL11, -+ e_DPAA_SWPORTAL12, -+ e_DPAA_SWPORTAL13, -+ e_DPAA_SWPORTAL14, -+ e_DPAA_SWPORTAL15, -+ e_DPAA_SWPORTAL16, -+ e_DPAA_SWPORTAL17, -+ e_DPAA_SWPORTAL18, -+ e_DPAA_SWPORTAL19, -+ e_DPAA_SWPORTAL20, -+ e_DPAA_SWPORTAL21, -+ e_DPAA_SWPORTAL22, -+ e_DPAA_SWPORTAL23, -+ e_DPAA_SWPORTAL24, -+ e_DPAA_SWPORTAL_DUMMY_LAST -+} e_DpaaSwPortal; -+ -+/**************************************************************************//** -+ @Description DPAA Direct Connect Portals Enumeration. -+*//***************************************************************************/ -+typedef enum -+{ -+ e_DPAA_DCPORTAL0 = 0, -+ e_DPAA_DCPORTAL1, -+ e_DPAA_DCPORTAL2, -+ e_DPAA_DCPORTAL_DUMMY_LAST -+} e_DpaaDcPortal; -+ -+#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST -+#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST -+ -+/***************************************************************************** -+ QMan INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */ -+#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */ -+#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */ -+#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) -+ /**< FQIDs range - 24 bits */ -+ -+/**************************************************************************//** -+ @Description Work Queue Channel assignments in QMan. -+*//***************************************************************************/ -+typedef enum -+{ -+ e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */ -+ e_QM_FQ_CHANNEL_SWPORTAL1, -+ e_QM_FQ_CHANNEL_SWPORTAL2, -+ e_QM_FQ_CHANNEL_SWPORTAL3, -+ e_QM_FQ_CHANNEL_SWPORTAL4, -+ e_QM_FQ_CHANNEL_SWPORTAL5, -+ e_QM_FQ_CHANNEL_SWPORTAL6, -+ e_QM_FQ_CHANNEL_SWPORTAL7, -+ e_QM_FQ_CHANNEL_SWPORTAL8, -+ e_QM_FQ_CHANNEL_SWPORTAL9, -+ e_QM_FQ_CHANNEL_SWPORTAL10, -+ e_QM_FQ_CHANNEL_SWPORTAL11, -+ e_QM_FQ_CHANNEL_SWPORTAL12, -+ e_QM_FQ_CHANNEL_SWPORTAL13, -+ e_QM_FQ_CHANNEL_SWPORTAL14, -+ e_QM_FQ_CHANNEL_SWPORTAL15, -+ e_QM_FQ_CHANNEL_SWPORTAL16, -+ e_QM_FQ_CHANNEL_SWPORTAL17, -+ e_QM_FQ_CHANNEL_SWPORTAL18, -+ e_QM_FQ_CHANNEL_SWPORTAL19, -+ e_QM_FQ_CHANNEL_SWPORTAL20, -+ e_QM_FQ_CHANNEL_SWPORTAL21, -+ e_QM_FQ_CHANNEL_SWPORTAL22, -+ e_QM_FQ_CHANNEL_SWPORTAL23, -+ e_QM_FQ_CHANNEL_SWPORTAL24, -+ -+ e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */ -+ e_QM_FQ_CHANNEL_POOL2, -+ e_QM_FQ_CHANNEL_POOL3, -+ e_QM_FQ_CHANNEL_POOL4, -+ e_QM_FQ_CHANNEL_POOL5, -+ e_QM_FQ_CHANNEL_POOL6, -+ e_QM_FQ_CHANNEL_POOL7, -+ e_QM_FQ_CHANNEL_POOL8, -+ e_QM_FQ_CHANNEL_POOL9, -+ e_QM_FQ_CHANNEL_POOL10, -+ e_QM_FQ_CHANNEL_POOL11, -+ e_QM_FQ_CHANNEL_POOL12, -+ e_QM_FQ_CHANNEL_POOL13, -+ e_QM_FQ_CHANNEL_POOL14, -+ e_QM_FQ_CHANNEL_POOL15, -+ -+ e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0: -+ connected to FMan 0; assigned in incrementing order to -+ each sub-portal (SP) in the portal */ -+ e_QM_FQ_CHANNEL_FMAN0_SP1, -+ e_QM_FQ_CHANNEL_FMAN0_SP2, -+ e_QM_FQ_CHANNEL_FMAN0_SP3, -+ e_QM_FQ_CHANNEL_FMAN0_SP4, -+ e_QM_FQ_CHANNEL_FMAN0_SP5, -+ e_QM_FQ_CHANNEL_FMAN0_SP6, -+ e_QM_FQ_CHANNEL_FMAN0_SP7, -+ e_QM_FQ_CHANNEL_FMAN0_SP8, -+ e_QM_FQ_CHANNEL_FMAN0_SP9, -+ e_QM_FQ_CHANNEL_FMAN0_SP10, -+ e_QM_FQ_CHANNEL_FMAN0_SP11, -+ e_QM_FQ_CHANNEL_FMAN0_SP12, -+ e_QM_FQ_CHANNEL_FMAN0_SP13, -+ e_QM_FQ_CHANNEL_FMAN0_SP14, -+ e_QM_FQ_CHANNEL_FMAN0_SP15, -+ -+ e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */ -+ e_QM_FQ_CHANNEL_RMAN_SP1, -+ -+ e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2: -+ connected to SEC */ -+} e_QmFQChannel; -+ -+/***************************************************************************** -+ BMan INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */ -+ -+/***************************************************************************** -+ SEC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define SEC_NUM_OF_DECOS 3 -+#define SEC_ALL_DECOS_MASK 0x00000003 -+ -+ -+/***************************************************************************** -+ FM INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define INTG_MAX_NUM_OF_FM 1 -+/* Ports defines */ -+#define FM_MAX_NUM_OF_1G_MACS 5 -+#define FM_MAX_NUM_OF_10G_MACS 1 -+#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS) -+#define FM_MAX_NUM_OF_OH_PORTS 4 -+ -+#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS -+#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS -+#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS) -+ -+#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS -+#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS -+#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS) -+ -+#define FM_MAX_NUM_OF_MACSECS 1 /* Should be updated */ -+ -+#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */ -+#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */ -+#define FM_MAX_NUM_OF_SUB_PORTALS 16 -+#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0 -+ -+#define FM_VSP_MAX_NUM_OF_ENTRIES 32 -+#define FM_MAX_NUM_OF_PFC_PRIORITIES 8 -+ -+/* RAMs defines */ -+#define FM_MURAM_SIZE (192 * KILOBYTE) -+#define FM_IRAM_SIZE(major, minor) \ -+ (((major == 6) && ((minor == 4) )) ? (64 * KILOBYTE) : (32 * KILOBYTE)) -+#define FM_NUM_OF_CTRL 2 -+ -+/* PCD defines */ -+#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */ -+#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */ -+#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */ -+#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */ -+#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */ -+ -+/* RTC defines */ -+#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */ -+#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */ -+#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */ -+ -+/* QMI defines */ -+#define QMI_MAX_NUM_OF_TNUMS 64 -+#define QMI_DEF_TNUMS_THRESH 32 -+/* FPM defines */ -+#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4 -+ -+/* DMA defines */ -+#define DMA_THRESH_MAX_COMMQ 83 -+#define DMA_THRESH_MAX_BUF 127 -+ -+/* BMI defines */ -+#define BMI_MAX_NUM_OF_TASKS 64 -+#define BMI_MAX_NUM_OF_DMAS 32 -+ -+#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE) -+#define PORT_MAX_WEIGHT 16 -+ -+#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE -+ -+/* Unique T4240 */ -+#define FM_OP_OPEN_DMA_MIN_LIMIT -+#define FM_NO_RESTRICT_ON_ACCESS_RSRC -+#define FM_NO_OP_OBSERVED_POOLS -+#define FM_FRAME_END_PARAMS_FOR_OP -+#define FM_DEQ_PIPELINE_PARAMS_FOR_OP -+#define FM_QMI_NO_SINGLE_ECC_EXCEPTION -+ -+#define FM_NO_GUARANTEED_RESET_VALUES -+ -+/* FM errata */ -+#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 -+#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 -+#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 -+#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 -+#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 -+ -+#define FM_BCB_ERRATA_BMI_SW001 -+#define FM_LEN_CHECK_ERRATA_FMAN_SW002 -+#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */ -+#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */ -+ -+/***************************************************************************** -+ RMan INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */ -+#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */ -+ -+/* RMan erratas */ -+#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756 -+ -+/***************************************************************************** -+ FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define NUM_OF_RX_SC 16 -+#define NUM_OF_TX_SC 16 -+ -+#define NUM_OF_SA_PER_RX_SC 2 -+#define NUM_OF_SA_PER_TX_SC 2 -+ -+#endif /* __DPAA_INTEGRATION_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h -@@ -0,0 +1,59 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ -+ @File part_ext.h -+ -+ @Description Definitions for the part (integration) module. -+*//***************************************************************************/ -+ -+#ifndef __PART_EXT_H -+#define __PART_EXT_H -+ -+#include "std_ext.h" -+#include "part_integration_ext.h" -+ -+/**************************************************************************//* -+ @Description Part data structure - must be contained in any integration -+ data structure. -+*//***************************************************************************/ -+typedef struct t_Part -+{ -+ uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId); -+ /**< Returns the address of the module's memory map base. */ -+ e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress); -+ /**< Returns the module's ID according to its memory map base. */ -+} t_Part; -+ -+ -+#endif /* __PART_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h -@@ -0,0 +1,304 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/** -+ -+ @File part_integration_ext.h -+ -+ @Description T4240 external definitions and structures. -+*//***************************************************************************/ -+#ifndef __PART_INTEGRATION_EXT_H -+#define __PART_INTEGRATION_EXT_H -+ -+#include "std_ext.h" -+#include "ddr_std_ext.h" -+#include "enet_ext.h" -+#include "dpaa_integration_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group T4240_chip_id T4240 Application Programming Interface -+ -+ @Description T4240 Chip functions,definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+#define CORE_E6500 -+ -+#define INTG_MAX_NUM_OF_CORES 24 -+ -+ -+/**************************************************************************//** -+ @Description Module types. -+*//***************************************************************************/ -+typedef enum e_ModuleId -+{ -+ e_MODULE_ID_DUART_1 = 0, -+ e_MODULE_ID_DUART_2, -+ e_MODULE_ID_DUART_3, -+ e_MODULE_ID_DUART_4, -+ e_MODULE_ID_LAW, -+ e_MODULE_ID_IFC, -+ e_MODULE_ID_PAMU, -+ e_MODULE_ID_QM, /**< Queue manager module */ -+ e_MODULE_ID_BM, /**< Buffer manager module */ -+ e_MODULE_ID_QM_CE_PORTAL_0, -+ e_MODULE_ID_QM_CI_PORTAL_0, -+ e_MODULE_ID_QM_CE_PORTAL_1, -+ e_MODULE_ID_QM_CI_PORTAL_1, -+ e_MODULE_ID_QM_CE_PORTAL_2, -+ e_MODULE_ID_QM_CI_PORTAL_2, -+ e_MODULE_ID_QM_CE_PORTAL_3, -+ e_MODULE_ID_QM_CI_PORTAL_3, -+ e_MODULE_ID_QM_CE_PORTAL_4, -+ e_MODULE_ID_QM_CI_PORTAL_4, -+ e_MODULE_ID_QM_CE_PORTAL_5, -+ e_MODULE_ID_QM_CI_PORTAL_5, -+ e_MODULE_ID_QM_CE_PORTAL_6, -+ e_MODULE_ID_QM_CI_PORTAL_6, -+ e_MODULE_ID_QM_CE_PORTAL_7, -+ e_MODULE_ID_QM_CI_PORTAL_7, -+ e_MODULE_ID_QM_CE_PORTAL_8, -+ e_MODULE_ID_QM_CI_PORTAL_8, -+ e_MODULE_ID_QM_CE_PORTAL_9, -+ e_MODULE_ID_QM_CI_PORTAL_9, -+ e_MODULE_ID_BM_CE_PORTAL_0, -+ e_MODULE_ID_BM_CI_PORTAL_0, -+ e_MODULE_ID_BM_CE_PORTAL_1, -+ e_MODULE_ID_BM_CI_PORTAL_1, -+ e_MODULE_ID_BM_CE_PORTAL_2, -+ e_MODULE_ID_BM_CI_PORTAL_2, -+ e_MODULE_ID_BM_CE_PORTAL_3, -+ e_MODULE_ID_BM_CI_PORTAL_3, -+ e_MODULE_ID_BM_CE_PORTAL_4, -+ e_MODULE_ID_BM_CI_PORTAL_4, -+ e_MODULE_ID_BM_CE_PORTAL_5, -+ e_MODULE_ID_BM_CI_PORTAL_5, -+ e_MODULE_ID_BM_CE_PORTAL_6, -+ e_MODULE_ID_BM_CI_PORTAL_6, -+ e_MODULE_ID_BM_CE_PORTAL_7, -+ e_MODULE_ID_BM_CI_PORTAL_7, -+ e_MODULE_ID_BM_CE_PORTAL_8, -+ e_MODULE_ID_BM_CI_PORTAL_8, -+ e_MODULE_ID_BM_CE_PORTAL_9, -+ e_MODULE_ID_BM_CI_PORTAL_9, -+ e_MODULE_ID_FM, /**< Frame manager module */ -+ e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */ -+ e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */ -+ e_MODULE_ID_FM_BMI, /**< FM BMI block */ -+ e_MODULE_ID_FM_QMI, /**< FM QMI block */ -+ e_MODULE_ID_FM_PARSER, /**< FM parser block */ -+ e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */ -+ e_MODULE_ID_FM_PLCR, /**< FM Policer */ -+ e_MODULE_ID_FM_KG, /**< FM Keygen */ -+ e_MODULE_ID_FM_DMA, /**< FM DMA */ -+ e_MODULE_ID_FM_FPM, /**< FM FPM */ -+ e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */ -+ e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */ -+ e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */ -+ e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */ -+ e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */ -+ e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */ -+ e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */ -+ e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */ -+ e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */ -+ e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */ -+ e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */ -+ e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */ -+ -+ e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */ -+ e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */ -+ e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */ -+ e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */ -+ e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */ -+ e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */ -+ e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */ -+ e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */ -+ e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */ -+ e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */ -+ e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */ -+ e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */ -+ -+ e_MODULE_ID_PIC, /**< PIC */ -+ e_MODULE_ID_GPIO, /**< GPIO */ -+ e_MODULE_ID_SERDES, /**< SERDES */ -+ e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */ -+ e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */ -+ -+ e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */ -+ -+ e_MODULE_ID_DUMMY_LAST -+} e_ModuleId; -+ -+#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST -+ -+#if 0 /* using unified values */ -+/***************************************************************************** -+ INTEGRATION-SPECIFIC MODULE CODES -+******************************************************************************/ -+#define MODULE_UNKNOWN 0x00000000 -+#define MODULE_MEM 0x00010000 -+#define MODULE_MM 0x00020000 -+#define MODULE_CORE 0x00030000 -+#define MODULE_T4240 0x00040000 -+#define MODULE_T4240_PLATFORM 0x00050000 -+#define MODULE_PM 0x00060000 -+#define MODULE_MMU 0x00070000 -+#define MODULE_PIC 0x00080000 -+#define MODULE_CPC 0x00090000 -+#define MODULE_DUART 0x000a0000 -+#define MODULE_SERDES 0x000b0000 -+#define MODULE_PIO 0x000c0000 -+#define MODULE_QM 0x000d0000 -+#define MODULE_BM 0x000e0000 -+#define MODULE_SEC 0x000f0000 -+#define MODULE_LAW 0x00100000 -+#define MODULE_LBC 0x00110000 -+#define MODULE_PAMU 0x00120000 -+#define MODULE_FM 0x00130000 -+#define MODULE_FM_MURAM 0x00140000 -+#define MODULE_FM_PCD 0x00150000 -+#define MODULE_FM_RTC 0x00160000 -+#define MODULE_FM_MAC 0x00170000 -+#define MODULE_FM_PORT 0x00180000 -+#define MODULE_FM_SP 0x00190000 -+#define MODULE_DPA_PORT 0x001a0000 -+#define MODULE_MII 0x001b0000 -+#define MODULE_I2C 0x001c0000 -+#define MODULE_DMA 0x001d0000 -+#define MODULE_DDR 0x001e0000 -+#define MODULE_ESPI 0x001f0000 -+#define MODULE_DPAA_IPSEC 0x00200000 -+#endif /* using unified values */ -+ -+/***************************************************************************** -+ PAMU INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define PAMU_NUM_OF_PARTITIONS 4 -+ -+/***************************************************************************** -+ LAW INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define LAW_NUM_OF_WINDOWS 32 -+#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */ -+#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */ -+ -+ -+/***************************************************************************** -+ LBC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+/**************************************************************************//** -+ @Group lbc_exception_grp LBC Exception Unit -+ -+ @Description LBC Exception unit API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Anchor lbc_exbm -+ -+ @Collection LBC Errors Bit Mask -+ -+ These errors are reported through the exceptions callback.. -+ The values can be or'ed in any combination in the errors mask -+ parameter of the errors report structure. -+ -+ These errors can also be passed as a bit-mask to -+ LBC_EnableErrorChecking() or LBC_DisableErrorChecking(), -+ for enabling or disabling error checking. -+ @{ -+*//***************************************************************************/ -+#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */ -+#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */ -+#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */ -+#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */ -+ -+#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \ -+ LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT) -+ /**< All possible errors */ -+/* @} */ -+/** @} */ /* end of lbc_exception_grp group */ -+ -+#define LBC_INCORRECT_ERROR_REPORT_ERRATA -+ -+#define LBC_NUM_OF_BANKS 8 -+#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */ -+#define LBC_PARITY_SUPPORT -+#define LBC_ADDRESS_HOLD_TIME_CTRL -+#define LBC_HIGH_CLK_DIVIDERS -+#define LBC_FCM_AVAILABLE -+ -+/***************************************************************************** -+ GPIO INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define GPIO_PORT_OFFSET_0x1000 -+ -+#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module; -+ Each port contains up to 32 I/O pins. */ -+ -+#define GPIO_VALID_PIN_MASKS \ -+ { /* Port A */ 0xFFFFFFFF, \ -+ /* Port B */ 0xFFFFFFFF, \ -+ /* Port C */ 0xFFFFFFFF } -+ -+#define GPIO_VALID_INTR_MASKS \ -+ { /* Port A */ 0xFFFFFFFF, \ -+ /* Port B */ 0xFFFFFFFF, \ -+ /* Port C */ 0xFFFFFFFF } -+ -+ -+ -+#endif /* __PART_INTEGRATION_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h -@@ -0,0 +1,291 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/** -+ -+ @File dpaa_integration_ext.h -+ -+ @Description T4240 FM external definitions and structures. -+*//***************************************************************************/ -+#ifndef __DPAA_INTEGRATION_EXT_H -+#define __DPAA_INTEGRATION_EXT_H -+ -+#include "std_ext.h" -+ -+ -+#define DPAA_VERSION 11 -+ -+/**************************************************************************//** -+ @Description DPAA SW Portals Enumeration. -+*//***************************************************************************/ -+typedef enum -+{ -+ e_DPAA_SWPORTAL0 = 0, -+ e_DPAA_SWPORTAL1, -+ e_DPAA_SWPORTAL2, -+ e_DPAA_SWPORTAL3, -+ e_DPAA_SWPORTAL4, -+ e_DPAA_SWPORTAL5, -+ e_DPAA_SWPORTAL6, -+ e_DPAA_SWPORTAL7, -+ e_DPAA_SWPORTAL8, -+ e_DPAA_SWPORTAL9, -+ e_DPAA_SWPORTAL10, -+ e_DPAA_SWPORTAL11, -+ e_DPAA_SWPORTAL12, -+ e_DPAA_SWPORTAL13, -+ e_DPAA_SWPORTAL14, -+ e_DPAA_SWPORTAL15, -+ e_DPAA_SWPORTAL16, -+ e_DPAA_SWPORTAL17, -+ e_DPAA_SWPORTAL18, -+ e_DPAA_SWPORTAL19, -+ e_DPAA_SWPORTAL20, -+ e_DPAA_SWPORTAL21, -+ e_DPAA_SWPORTAL22, -+ e_DPAA_SWPORTAL23, -+ e_DPAA_SWPORTAL24, -+ e_DPAA_SWPORTAL_DUMMY_LAST -+} e_DpaaSwPortal; -+ -+/**************************************************************************//** -+ @Description DPAA Direct Connect Portals Enumeration. -+*//***************************************************************************/ -+typedef enum -+{ -+ e_DPAA_DCPORTAL0 = 0, -+ e_DPAA_DCPORTAL1, -+ e_DPAA_DCPORTAL2, -+ e_DPAA_DCPORTAL_DUMMY_LAST -+} e_DpaaDcPortal; -+ -+#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST -+#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST -+ -+/***************************************************************************** -+ QMan INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */ -+#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */ -+#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */ -+#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) -+ /**< FQIDs range - 24 bits */ -+ -+/**************************************************************************//** -+ @Description Work Queue Channel assignments in QMan. -+*//***************************************************************************/ -+typedef enum -+{ -+ e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */ -+ e_QM_FQ_CHANNEL_SWPORTAL1, -+ e_QM_FQ_CHANNEL_SWPORTAL2, -+ e_QM_FQ_CHANNEL_SWPORTAL3, -+ e_QM_FQ_CHANNEL_SWPORTAL4, -+ e_QM_FQ_CHANNEL_SWPORTAL5, -+ e_QM_FQ_CHANNEL_SWPORTAL6, -+ e_QM_FQ_CHANNEL_SWPORTAL7, -+ e_QM_FQ_CHANNEL_SWPORTAL8, -+ e_QM_FQ_CHANNEL_SWPORTAL9, -+ e_QM_FQ_CHANNEL_SWPORTAL10, -+ e_QM_FQ_CHANNEL_SWPORTAL11, -+ e_QM_FQ_CHANNEL_SWPORTAL12, -+ e_QM_FQ_CHANNEL_SWPORTAL13, -+ e_QM_FQ_CHANNEL_SWPORTAL14, -+ e_QM_FQ_CHANNEL_SWPORTAL15, -+ e_QM_FQ_CHANNEL_SWPORTAL16, -+ e_QM_FQ_CHANNEL_SWPORTAL17, -+ e_QM_FQ_CHANNEL_SWPORTAL18, -+ e_QM_FQ_CHANNEL_SWPORTAL19, -+ e_QM_FQ_CHANNEL_SWPORTAL20, -+ e_QM_FQ_CHANNEL_SWPORTAL21, -+ e_QM_FQ_CHANNEL_SWPORTAL22, -+ e_QM_FQ_CHANNEL_SWPORTAL23, -+ e_QM_FQ_CHANNEL_SWPORTAL24, -+ -+ e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */ -+ e_QM_FQ_CHANNEL_POOL2, -+ e_QM_FQ_CHANNEL_POOL3, -+ e_QM_FQ_CHANNEL_POOL4, -+ e_QM_FQ_CHANNEL_POOL5, -+ e_QM_FQ_CHANNEL_POOL6, -+ e_QM_FQ_CHANNEL_POOL7, -+ e_QM_FQ_CHANNEL_POOL8, -+ e_QM_FQ_CHANNEL_POOL9, -+ e_QM_FQ_CHANNEL_POOL10, -+ e_QM_FQ_CHANNEL_POOL11, -+ e_QM_FQ_CHANNEL_POOL12, -+ e_QM_FQ_CHANNEL_POOL13, -+ e_QM_FQ_CHANNEL_POOL14, -+ e_QM_FQ_CHANNEL_POOL15, -+ -+ e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0: -+ connected to FMan 0; assigned in incrementing order to -+ each sub-portal (SP) in the portal */ -+ e_QM_FQ_CHANNEL_FMAN0_SP1, -+ e_QM_FQ_CHANNEL_FMAN0_SP2, -+ e_QM_FQ_CHANNEL_FMAN0_SP3, -+ e_QM_FQ_CHANNEL_FMAN0_SP4, -+ e_QM_FQ_CHANNEL_FMAN0_SP5, -+ e_QM_FQ_CHANNEL_FMAN0_SP6, -+ e_QM_FQ_CHANNEL_FMAN0_SP7, -+ e_QM_FQ_CHANNEL_FMAN0_SP8, -+ e_QM_FQ_CHANNEL_FMAN0_SP9, -+ e_QM_FQ_CHANNEL_FMAN0_SP10, -+ e_QM_FQ_CHANNEL_FMAN0_SP11, -+ e_QM_FQ_CHANNEL_FMAN0_SP12, -+ e_QM_FQ_CHANNEL_FMAN0_SP13, -+ e_QM_FQ_CHANNEL_FMAN0_SP14, -+ e_QM_FQ_CHANNEL_FMAN0_SP15, -+ -+ e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */ -+ e_QM_FQ_CHANNEL_RMAN_SP1, -+ -+ e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2: -+ connected to SEC */ -+} e_QmFQChannel; -+ -+/***************************************************************************** -+ BMan INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */ -+ -+/***************************************************************************** -+ SEC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define SEC_NUM_OF_DECOS 3 -+#define SEC_ALL_DECOS_MASK 0x00000003 -+ -+ -+/***************************************************************************** -+ FM INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define INTG_MAX_NUM_OF_FM 2 -+ -+/* Ports defines */ -+#define FM_MAX_NUM_OF_1G_MACS 6 -+#define FM_MAX_NUM_OF_10G_MACS 2 -+#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS) -+#define FM_MAX_NUM_OF_OH_PORTS 6 -+ -+#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS -+#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS -+#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS) -+ -+#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS -+#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS -+#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS) -+ -+#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */ -+#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */ -+#define FM_MAX_NUM_OF_SUB_PORTALS 16 -+#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0 -+ -+#define FM_VSP_MAX_NUM_OF_ENTRIES 64 -+#define FM_MAX_NUM_OF_PFC_PRIORITIES 8 -+ -+/* RAMs defines */ -+#define FM_MURAM_SIZE (384 * KILOBYTE) -+#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE) -+#define FM_NUM_OF_CTRL 4 -+ -+/* PCD defines */ -+#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */ -+#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */ -+#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */ -+#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */ -+#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */ -+ -+/* RTC defines */ -+#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */ -+#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */ -+#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */ -+ -+/* QMI defines */ -+#define QMI_MAX_NUM_OF_TNUMS 64 -+#define QMI_DEF_TNUMS_THRESH 32 -+/* FPM defines */ -+#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4 -+ -+/* DMA defines */ -+#define DMA_THRESH_MAX_COMMQ 83 -+#define DMA_THRESH_MAX_BUF 127 -+ -+/* BMI defines */ -+#define BMI_MAX_NUM_OF_TASKS 128 -+#define BMI_MAX_NUM_OF_DMAS 84 -+ -+#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE) -+#define PORT_MAX_WEIGHT 16 -+ -+#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE -+ -+/* Unique T4240 */ -+#define FM_OP_OPEN_DMA_MIN_LIMIT -+#define FM_NO_RESTRICT_ON_ACCESS_RSRC -+#define FM_NO_OP_OBSERVED_POOLS -+#define FM_FRAME_END_PARAMS_FOR_OP -+#define FM_DEQ_PIPELINE_PARAMS_FOR_OP -+#define FM_QMI_NO_SINGLE_ECC_EXCEPTION -+ -+#define FM_NO_GUARANTEED_RESET_VALUES -+ -+/* FM errata */ -+#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 -+#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 -+#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 -+#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 -+#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 -+ -+#define FM_BCB_ERRATA_BMI_SW001 -+#define FM_LEN_CHECK_ERRATA_FMAN_SW002 -+#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */ -+#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */ -+ -+/***************************************************************************** -+ RMan INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */ -+#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */ -+ -+/* RMan erratas */ -+#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756 -+ -+/***************************************************************************** -+ FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define NUM_OF_RX_SC 16 -+#define NUM_OF_TX_SC 16 -+ -+#define NUM_OF_SA_PER_RX_SC 2 -+#define NUM_OF_SA_PER_TX_SC 2 -+ -+#endif /* __DPAA_INTEGRATION_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h -@@ -0,0 +1,64 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ -+ @File part_ext.h -+ -+ @Description Definitions for the part (integration) module. -+*//***************************************************************************/ -+ -+#ifndef __PART_EXT_H -+#define __PART_EXT_H -+ -+#include "std_ext.h" -+#include "part_integration_ext.h" -+ -+#if !(defined(LS1043)) -+#error "unable to proceed without chip-definition" -+#endif -+ -+ -+/**************************************************************************//* -+ @Description Part data structure - must be contained in any integration -+ data structure. -+*//***************************************************************************/ -+typedef struct t_Part -+{ -+ uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId); -+ /**< Returns the address of the module's memory map base. */ -+ e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress); -+ /**< Returns the module's ID according to its memory map base. */ -+} t_Part; -+ -+ -+#endif /* __PART_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h -@@ -0,0 +1,185 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/** -+ -+ @File part_integration_ext.h -+ -+ @Description T4240 external definitions and structures. -+*//***************************************************************************/ -+#ifndef __PART_INTEGRATION_EXT_H -+#define __PART_INTEGRATION_EXT_H -+ -+#include "std_ext.h" -+#include "ddr_std_ext.h" -+#include "enet_ext.h" -+#include "dpaa_integration_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group T4240_chip_id T4240 Application Programming Interface -+ -+ @Description T4240 Chip functions,definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+#define INTG_MAX_NUM_OF_CORES 4 -+ -+/**************************************************************************//** -+ @Description Module types. -+*//***************************************************************************/ -+typedef enum e_ModuleId -+{ -+ e_MODULE_ID_DUART_1 = 0, -+ e_MODULE_ID_DUART_2, -+ e_MODULE_ID_DUART_3, -+ e_MODULE_ID_DUART_4, -+ e_MODULE_ID_LAW, -+ e_MODULE_ID_IFC, -+ e_MODULE_ID_PAMU, -+ e_MODULE_ID_QM, /**< Queue manager module */ -+ e_MODULE_ID_BM, /**< Buffer manager module */ -+ e_MODULE_ID_QM_CE_PORTAL_0, -+ e_MODULE_ID_QM_CI_PORTAL_0, -+ e_MODULE_ID_QM_CE_PORTAL_1, -+ e_MODULE_ID_QM_CI_PORTAL_1, -+ e_MODULE_ID_QM_CE_PORTAL_2, -+ e_MODULE_ID_QM_CI_PORTAL_2, -+ e_MODULE_ID_QM_CE_PORTAL_3, -+ e_MODULE_ID_QM_CI_PORTAL_3, -+ e_MODULE_ID_QM_CE_PORTAL_4, -+ e_MODULE_ID_QM_CI_PORTAL_4, -+ e_MODULE_ID_QM_CE_PORTAL_5, -+ e_MODULE_ID_QM_CI_PORTAL_5, -+ e_MODULE_ID_QM_CE_PORTAL_6, -+ e_MODULE_ID_QM_CI_PORTAL_6, -+ e_MODULE_ID_QM_CE_PORTAL_7, -+ e_MODULE_ID_QM_CI_PORTAL_7, -+ e_MODULE_ID_QM_CE_PORTAL_8, -+ e_MODULE_ID_QM_CI_PORTAL_8, -+ e_MODULE_ID_QM_CE_PORTAL_9, -+ e_MODULE_ID_QM_CI_PORTAL_9, -+ e_MODULE_ID_BM_CE_PORTAL_0, -+ e_MODULE_ID_BM_CI_PORTAL_0, -+ e_MODULE_ID_BM_CE_PORTAL_1, -+ e_MODULE_ID_BM_CI_PORTAL_1, -+ e_MODULE_ID_BM_CE_PORTAL_2, -+ e_MODULE_ID_BM_CI_PORTAL_2, -+ e_MODULE_ID_BM_CE_PORTAL_3, -+ e_MODULE_ID_BM_CI_PORTAL_3, -+ e_MODULE_ID_BM_CE_PORTAL_4, -+ e_MODULE_ID_BM_CI_PORTAL_4, -+ e_MODULE_ID_BM_CE_PORTAL_5, -+ e_MODULE_ID_BM_CI_PORTAL_5, -+ e_MODULE_ID_BM_CE_PORTAL_6, -+ e_MODULE_ID_BM_CI_PORTAL_6, -+ e_MODULE_ID_BM_CE_PORTAL_7, -+ e_MODULE_ID_BM_CI_PORTAL_7, -+ e_MODULE_ID_BM_CE_PORTAL_8, -+ e_MODULE_ID_BM_CI_PORTAL_8, -+ e_MODULE_ID_BM_CE_PORTAL_9, -+ e_MODULE_ID_BM_CI_PORTAL_9, -+ e_MODULE_ID_FM, /**< Frame manager module */ -+ e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */ -+ e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */ -+ e_MODULE_ID_FM_BMI, /**< FM BMI block */ -+ e_MODULE_ID_FM_QMI, /**< FM QMI block */ -+ e_MODULE_ID_FM_PARSER, /**< FM parser block */ -+ e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */ -+ e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */ -+ e_MODULE_ID_FM_PLCR, /**< FM Policer */ -+ e_MODULE_ID_FM_KG, /**< FM Keygen */ -+ e_MODULE_ID_FM_DMA, /**< FM DMA */ -+ e_MODULE_ID_FM_FPM, /**< FM FPM */ -+ e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */ -+ e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */ -+ e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */ -+ e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */ -+ e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */ -+ e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */ -+ e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */ -+ e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */ -+ e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */ -+ e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */ -+ e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */ -+ e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */ -+ -+ e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */ -+ e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */ -+ e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */ -+ e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */ -+ e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */ -+ e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */ -+ e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */ -+ e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */ -+ e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */ -+ e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */ -+ e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */ -+ e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */ -+ -+ e_MODULE_ID_PIC, /**< PIC */ -+ e_MODULE_ID_GPIO, /**< GPIO */ -+ e_MODULE_ID_SERDES, /**< SERDES */ -+ e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */ -+ e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */ -+ -+ e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */ -+ -+ e_MODULE_ID_DUMMY_LAST -+} e_ModuleId; -+ -+#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST -+ -+ -+#endif /* __PART_INTEGRATION_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h -@@ -0,0 +1,213 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/** -+ -+ @File dpaa_integration_ext.h -+ -+ @Description P1023 FM external definitions and structures. -+*//***************************************************************************/ -+#ifndef __DPAA_INTEGRATION_EXT_H -+#define __DPAA_INTEGRATION_EXT_H -+ -+#include "std_ext.h" -+ -+ -+#define DPAA_VERSION 10 -+ -+typedef enum e_DpaaSwPortal { -+ e_DPAA_SWPORTAL0 = 0, -+ e_DPAA_SWPORTAL1, -+ e_DPAA_SWPORTAL2, -+ e_DPAA_SWPORTAL_DUMMY_LAST -+} e_DpaaSwPortal; -+ -+typedef enum { -+ e_DPAA_DCPORTAL0 = 0, -+ e_DPAA_DCPORTAL2, -+ e_DPAA_DCPORTAL_DUMMY_LAST -+} e_DpaaDcPortal; -+ -+#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST -+#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST -+ -+/***************************************************************************** -+ QMAN INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define QM_MAX_NUM_OF_POOL_CHANNELS 3 -+#define QM_MAX_NUM_OF_WQ 8 -+#define QM_MAX_NUM_OF_SWP_AS 2 -+#define QM_MAX_NUM_OF_CGS 64 -+#define QM_MAX_NUM_OF_FQIDS (16*MEGABYTE) -+ -+typedef enum { -+ e_QM_FQ_CHANNEL_SWPORTAL0 = 0, -+ e_QM_FQ_CHANNEL_SWPORTAL1, -+ e_QM_FQ_CHANNEL_SWPORTAL2, -+ -+ e_QM_FQ_CHANNEL_POOL1 = 0x21, -+ e_QM_FQ_CHANNEL_POOL2, -+ e_QM_FQ_CHANNEL_POOL3, -+ -+ e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, -+ e_QM_FQ_CHANNEL_FMAN0_SP1, -+ e_QM_FQ_CHANNEL_FMAN0_SP2, -+ e_QM_FQ_CHANNEL_FMAN0_SP3, -+ e_QM_FQ_CHANNEL_FMAN0_SP4, -+ e_QM_FQ_CHANNEL_FMAN0_SP5, -+ e_QM_FQ_CHANNEL_FMAN0_SP6, -+ -+ -+ e_QM_FQ_CHANNEL_CAAM = 0x80 -+} e_QmFQChannel; -+ -+/***************************************************************************** -+ BMAN INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define BM_MAX_NUM_OF_POOLS 8 -+ -+/***************************************************************************** -+ SEC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define SEC_NUM_OF_DECOS 2 -+#define SEC_ALL_DECOS_MASK 0x00000003 -+#define SEC_RNGB -+#define SEC_NO_ESP_TRAILER_REMOVAL -+ -+/***************************************************************************** -+ FM INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define INTG_MAX_NUM_OF_FM 1 -+ -+/* Ports defines */ -+#define FM_MAX_NUM_OF_1G_MACS 2 -+#define FM_MAX_NUM_OF_10G_MACS 0 -+#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS) -+#define FM_MAX_NUM_OF_OH_PORTS 5 -+ -+#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS -+#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS -+#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS) -+ -+#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS -+#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS -+#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS) -+ -+#define FM_MAX_NUM_OF_MACSECS 1 -+ -+#define FM_MACSEC_SUPPORT -+ -+#define FM_LOW_END_RESTRICTION /* prevents the use of TX port 1 with OP port 0 */ -+ -+#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */ -+#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 2 /**< Number of Offline parsing port external BM pools per Rx port */ -+#define FM_PORT_NUM_OF_CONGESTION_GRPS 32 /**< Total number of congestion groups in QM */ -+#define FM_MAX_NUM_OF_SUB_PORTALS 7 -+ -+/* Rams defines */ -+#define FM_MURAM_SIZE (64*KILOBYTE) -+#define FM_IRAM_SIZE(major, minor) (32 * KILOBYTE) -+#define FM_NUM_OF_CTRL 2 -+ -+/* PCD defines */ -+#define FM_PCD_PLCR_NUM_ENTRIES 32 /**< Total number of policer profiles */ -+#define FM_PCD_KG_NUM_OF_SCHEMES 16 /**< Total number of KG schemes */ -+#define FM_PCD_MAX_NUM_OF_CLS_PLANS 128 /**< Number of classification plan entries. */ -+#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000240 /**< Number of bytes saved for patches */ -+#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */ -+ -+/* RTC defines */ -+#define FM_RTC_NUM_OF_ALARMS 2 -+#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 -+#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 -+ -+/* QMI defines */ -+#define QMI_MAX_NUM_OF_TNUMS 15 -+ -+/* FPM defines */ -+#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4 -+ -+/* DMA defines */ -+#define DMA_THRESH_MAX_COMMQ 15 -+#define DMA_THRESH_MAX_BUF 7 -+ -+/* BMI defines */ -+#define BMI_MAX_NUM_OF_TASKS 64 -+#define BMI_MAX_NUM_OF_DMAS 16 -+#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE) -+#define PORT_MAX_WEIGHT 4 -+ -+/***************************************************************************** -+ FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define NUM_OF_RX_SC 16 -+#define NUM_OF_TX_SC 16 -+ -+#define NUM_OF_SA_PER_RX_SC 2 -+#define NUM_OF_SA_PER_TX_SC 2 -+ -+/**************************************************************************//** -+ @Description Enum for inter-module interrupts registration -+*//***************************************************************************/ -+ -+/* 1023 unique features */ -+#define FM_QMI_NO_ECC_EXCEPTIONS -+#define FM_CSI_CFED_LIMIT -+#define FM_PEDANTIC_DMA -+#define FM_QMI_NO_DEQ_OPTIONS_SUPPORT -+#define FM_FIFO_ALLOCATION_ALG -+#define FM_DEQ_PIPELINE_PARAMS_FOR_OP -+#define FM_HAS_TOTAL_DMAS -+#define FM_KG_NO_IPPID_SUPPORT -+#define FM_NO_GUARANTEED_RESET_VALUES -+#define FM_MAC_RESET -+ -+/* FM erratas */ -+#define FM_RX_PREAM_4_ERRATA_DTSEC_A001 -+#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */ -+ -+#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */ -+#define FM_INT_BUF_LEAK_FMAN_A005 /* No implementation, Out of LLD scope. App must avoid S/G */ -+ -+#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 -+ -+/* #define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */ -+ -+/* -+TKT056919 - axi12axi0 can hang if read request follows the single byte write on the very next cycle -+TKT038900 - FM dma lockup occur due to AXI slave protocol violation -+*/ -+#define FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 -+ -+ -+#endif /* __DPAA_INTEGRATION_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h -@@ -0,0 +1,82 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ -+ @File part_ext.h -+ -+ @Description Definitions for the part (integration) module. -+*//***************************************************************************/ -+ -+#ifndef __PART_EXT_H -+#define __PART_EXT_H -+ -+#include "std_ext.h" -+#include "part_integration_ext.h" -+ -+ -+#if !(defined(MPC8306) || \ -+ defined(MPC8309) || \ -+ defined(MPC834x) || \ -+ defined(MPC836x) || \ -+ defined(MPC832x) || \ -+ defined(MPC837x) || \ -+ defined(MPC8568) || \ -+ defined(MPC8569) || \ -+ defined(P1020) || \ -+ defined(P1021) || \ -+ defined(P1022) || \ -+ defined(P1023) || \ -+ defined(P2020) || \ -+ defined(P3041) || \ -+ defined(P4080) || \ -+ defined(P5020) || \ -+ defined(MSC814x)) -+#error "unable to proceed without chip-definition" -+#endif -+ -+ -+/**************************************************************************//* -+ @Description Part data structure - must be contained in any integration -+ data structure. -+*//***************************************************************************/ -+typedef struct t_Part -+{ -+ uint64_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId); -+ /**< Returns the address of the module's memory map base. */ -+ e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uint64_t baseAddress); -+ /**< Returns the module's ID according to its memory map base. */ -+} t_Part; -+ -+ -+#endif /* __PART_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h -@@ -0,0 +1,635 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ @File part_integration_ext.h -+ -+ @Description P1023 external definitions and structures. -+*//***************************************************************************/ -+#ifndef __PART_INTEGRATION_EXT_H -+#define __PART_INTEGRATION_EXT_H -+ -+#include "std_ext.h" -+#include "dpaa_integration_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group 1023_chip_id P1023 Application Programming Interface -+ -+ @Description P1023 Chip functions,definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+#define INTG_MAX_NUM_OF_CORES 2 -+ -+ -+/**************************************************************************//** -+ @Description Module types. -+*//***************************************************************************/ -+typedef enum e_ModuleId -+{ -+ e_MODULE_ID_LAW, /**< Local Access module */ -+ e_MODULE_ID_ECM, /**< e500 Coherency Module */ -+ e_MODULE_ID_DDR, /**< DDR memory controller */ -+ e_MODULE_ID_I2C_1, /**< I2C 1 */ -+ e_MODULE_ID_I2C_2, /**< I2C 1 */ -+ e_MODULE_ID_DUART_1, /**< DUART module 1 */ -+ e_MODULE_ID_DUART_2, /**< DUART module 2 */ -+ e_MODULE_ID_LBC, /**< Local bus memory controller module */ -+ e_MODULE_ID_PCIE_1, /**< PCI Express 1 controller module */ -+ e_MODULE_ID_PCIE_ATMU_1, /**< PCI 1 ATMU Window */ -+ e_MODULE_ID_PCIE_2, /**< PCI Express 2 controller module */ -+ e_MODULE_ID_PCIE_ATMU_2, /**< PCI 2 ATMU Window */ -+ e_MODULE_ID_PCIE_3, /**< PCI Express 3 controller module */ -+ e_MODULE_ID_PCIE_ATMU_3, /**< PCI 3 ATMU Window */ -+ e_MODULE_ID_MSI, /**< MSI registers */ -+ e_MODULE_ID_L2_SRAM, /**< L2/SRAM Memory-Mapped controller module */ -+ e_MODULE_ID_DMA_1, /**< DMA controller 1 */ -+ e_MODULE_ID_DMA_2, /**< DMA controller 2 */ -+ e_MODULE_ID_EPIC, /**< Programmable interrupt controller */ -+ e_MODULE_ID_ESPI, /**< ESPI module */ -+ e_MODULE_ID_GPIO, /**< General Purpose I/O */ -+ e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */ -+ e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */ -+ e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */ -+ e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */ -+ e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */ -+ e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */ -+ e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */ -+ e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */ -+ e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */ -+ e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */ -+ e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */ -+ e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */ -+ e_MODULE_ID_USB_DR_1, /**< USB 2.0 module 1 */ -+ e_MODULE_ID_USB_DR_2, /**< USB 2.0 module 2 */ -+ e_MODULE_ID_ETSEC_MII_MNG, /**< MII MNG registers */ -+ e_MODULE_ID_ETSEC_1, /**< ETSEC module 1 */ -+ e_MODULE_ID_ETSEC_2, /**< ETSEC module 2 */ -+ e_MODULE_ID_GUTS, /**< Serial DMA */ -+ e_MODULE_ID_PM, /**< Performance Monitor module */ -+ e_MODULE_ID_QM, /**< Queue manager module */ -+ e_MODULE_ID_BM, /**< Buffer manager module */ -+ e_MODULE_ID_QM_CE_PORTAL, -+ e_MODULE_ID_QM_CI_PORTAL, -+ e_MODULE_ID_BM_CE_PORTAL, -+ e_MODULE_ID_BM_CI_PORTAL, -+ e_MODULE_ID_FM, /**< Frame manager #1 module */ -+ e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */ -+ e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */ -+ e_MODULE_ID_FM_BMI, /**< FM BMI block */ -+ e_MODULE_ID_FM_QMI, /**< FM QMI block */ -+ e_MODULE_ID_FM_PRS, /**< FM parser block */ -+ e_MODULE_ID_FM_PORT_HO0, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM_PORT_1GRx0, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx0, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM_PLCR, /**< FM Policer */ -+ e_MODULE_ID_FM_KG, /**< FM Keygen */ -+ e_MODULE_ID_FM_DMA, /**< FM DMA */ -+ e_MODULE_ID_FM_FPM, /**< FM FPM */ -+ e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */ -+ e_MODULE_ID_FM_1GMDIO0, /**< FM 1G MDIO MAC 0*/ -+ e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/ -+ e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */ -+ e_MODULE_ID_FM_RISC0, /**< FM risc #0 */ -+ e_MODULE_ID_FM_RISC1, /**< FM risc #1 */ -+ e_MODULE_ID_FM_1GMAC0, /**< FM 1G MAC #0 */ -+ e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */ -+ e_MODULE_ID_FM_MACSEC, /**< FM MACSEC */ -+ -+ e_MODULE_ID_DUMMY_LAST -+} e_ModuleId; -+ -+#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST -+ -+ -+#define P1023_OFFSET_LAW 0x00000C08 -+#define P1023_OFFSET_ECM 0x00001000 -+#define P1023_OFFSET_DDR 0x00002000 -+#define P1023_OFFSET_I2C1 0x00003000 -+#define P1023_OFFSET_I2C2 0x00003100 -+#define P1023_OFFSET_DUART1 0x00004500 -+#define P1023_OFFSET_DUART2 0x00004600 -+#define P1023_OFFSET_LBC 0x00005000 -+#define P1023_OFFSET_ESPI 0x00007000 -+#define P1023_OFFSET_PCIE2 0x00009000 -+#define P1023_OFFSET_PCIE2_ATMU 0x00009C00 -+#define P1023_OFFSET_PCIE1 0x0000A000 -+#define P1023_OFFSET_PCIE1_ATMU 0x0000AC00 -+#define P1023_OFFSET_PCIE3 0x0000B000 -+#define P1023_OFFSET_PCIE3_ATMU 0x0000BC00 -+#define P1023_OFFSET_DMA2 0x0000C100 -+#define P1023_OFFSET_GPIO 0x0000F000 -+#define P1023_OFFSET_L2_SRAM 0x00020000 -+#define P1023_OFFSET_DMA1 0x00021100 -+#define P1023_OFFSET_USB1 0x00022000 -+#define P1023_OFFSET_SEC_GEN 0x00030000 -+#define P1023_OFFSET_SEC_JQ0 0x00031000 -+#define P1023_OFFSET_SEC_JQ1 0x00032000 -+#define P1023_OFFSET_SEC_JQ2 0x00033000 -+#define P1023_OFFSET_SEC_JQ3 0x00034000 -+#define P1023_OFFSET_SEC_RTIC 0x00036000 -+#define P1023_OFFSET_SEC_QI 0x00037000 -+#define P1023_OFFSET_SEC_DECO0_CCB0 0x00038000 -+#define P1023_OFFSET_SEC_DECO1_CCB1 0x00039000 -+#define P1023_OFFSET_SEC_DECO2_CCB2 0x0003a000 -+#define P1023_OFFSET_SEC_DECO3_CCB3 0x0003b000 -+#define P1023_OFFSET_SEC_DECO4_CCB4 0x0003c000 -+#define P1023_OFFSET_PIC 0x00040000 -+#define P1023_OFFSET_MSI 0x00041600 -+#define P1023_OFFSET_AXI 0x00081000 -+#define P1023_OFFSET_QM 0x00088000 -+#define P1023_OFFSET_BM 0x0008A000 -+#define P1022_OFFSET_PM 0x000E1000 -+ -+#define P1023_OFFSET_GUTIL 0x000E0000 -+#define P1023_OFFSET_PM 0x000E1000 -+#define P1023_OFFSET_DEBUG 0x000E2000 -+#define P1023_OFFSET_SERDES 0x000E3000 -+#define P1023_OFFSET_ROM 0x000F0000 -+#define P1023_OFFSET_FM 0x00100000 -+ -+#define P1023_OFFSET_FM_MURAM (P1023_OFFSET_FM + 0x00000000) -+#define P1023_OFFSET_FM_BMI (P1023_OFFSET_FM + 0x00080000) -+#define P1023_OFFSET_FM_QMI (P1023_OFFSET_FM + 0x00080400) -+#define P1023_OFFSET_FM_PRS (P1023_OFFSET_FM + 0x00080800) -+#define P1023_OFFSET_FM_PORT_HO0 (P1023_OFFSET_FM + 0x00081000) -+#define P1023_OFFSET_FM_PORT_HO1 (P1023_OFFSET_FM + 0x00082000) -+#define P1023_OFFSET_FM_PORT_HO2 (P1023_OFFSET_FM + 0x00083000) -+#define P1023_OFFSET_FM_PORT_HO3 (P1023_OFFSET_FM + 0x00084000) -+#define P1023_OFFSET_FM_PORT_HO4 (P1023_OFFSET_FM + 0x00085000) -+#define P1023_OFFSET_FM_PORT_1GRX0 (P1023_OFFSET_FM + 0x00088000) -+#define P1023_OFFSET_FM_PORT_1GRX1 (P1023_OFFSET_FM + 0x00089000) -+#define P1023_OFFSET_FM_PORT_1GTX0 (P1023_OFFSET_FM + 0x000A8000) -+#define P1023_OFFSET_FM_PORT_1GTX1 (P1023_OFFSET_FM + 0x000A9000) -+#define P1023_OFFSET_FM_PLCR (P1023_OFFSET_FM + 0x000C0000) -+#define P1023_OFFSET_FM_KG (P1023_OFFSET_FM + 0x000C1000) -+#define P1023_OFFSET_FM_DMA (P1023_OFFSET_FM + 0x000C2000) -+#define P1023_OFFSET_FM_FPM (P1023_OFFSET_FM + 0x000C3000) -+#define P1023_OFFSET_FM_IRAM (P1023_OFFSET_FM + 0x000C4000) -+#define P1023_OFFSET_FM_PRS_IRAM (P1023_OFFSET_FM + 0x000C7000) -+#define P1023_OFFSET_FM_RISC0 (P1023_OFFSET_FM + 0x000D0000) -+#define P1023_OFFSET_FM_RISC1 (P1023_OFFSET_FM + 0x000D0400) -+#define P1023_OFFSET_FM_MACSEC (P1023_OFFSET_FM + 0x000D8000) -+#define P1023_OFFSET_FM_1GMAC0 (P1023_OFFSET_FM + 0x000E0000) -+#define P1023_OFFSET_FM_1GMDIO0 (P1023_OFFSET_FM + 0x000E1120) -+#define P1023_OFFSET_FM_1GMAC1 (P1023_OFFSET_FM + 0x000E2000) -+#define P1023_OFFSET_FM_1GMDIO1 (P1023_OFFSET_FM + 0x000E3000) -+#define P1023_OFFSET_FM_RTC (P1023_OFFSET_FM + 0x000FE000) -+ -+/* Offsets relative to QM or BM portals base */ -+#define P1023_OFFSET_PORTALS_CE_AREA 0x00000000 /* cache enabled area */ -+#define P1023_OFFSET_PORTALS_CI_AREA 0x00100000 /* cache inhibited area */ -+ -+#define P1023_OFFSET_PORTALS_CE(portal) (P1023_OFFSET_PORTALS_CE_AREA + 0x4000 * (portal)) -+#define P1023_OFFSET_PORTALS_CI(portal) (P1023_OFFSET_PORTALS_CI_AREA + 0x1000 * (portal)) -+ -+/**************************************************************************//** -+ @Description Transaction source ID (for memory controllers error reporting). -+*//***************************************************************************/ -+typedef enum e_TransSrc -+{ -+ e_TRANS_SRC_PCIE_2 = 0x01, /**< PCIe port 2 */ -+ e_TRANS_SRC_PCIE_1 = 0x02, /**< PCIe port 1 */ -+ e_TRANS_SRC_PCIE_3 = 0x03, /**< PCIe port 3 */ -+ e_TRANS_SRC_LBC = 0x04, /**< Enhanced local bus */ -+ e_TRANS_SRC_DPAA_SW_PORTALS = 0x0E, /**< DPAA software portals or SRAM */ -+ e_TRANS_SRC_DDR = 0x0F, /**< DDR controller */ -+ e_TRANS_SRC_CORE_INS_FETCH = 0x10, /**< Processor (instruction) */ -+ e_TRANS_SRC_CORE_DATA = 0x11, /**< Processor (data) */ -+ e_TRANS_SRC_DMA = 0x15 /**< DMA */ -+} e_TransSrc; -+ -+/**************************************************************************//** -+ @Description Local Access Window Target interface ID -+*//***************************************************************************/ -+typedef enum e_P1023LawTargetId -+{ -+ e_P1023_LAW_TARGET_PCIE_2 = 0x01, /**< PCI Express 2 target interface */ -+ e_P1023_LAW_TARGET_PCIE_1 = 0x02, /**< PCI Express 1 target interface */ -+ e_P1023_LAW_TARGET_PCIE_3 = 0x03, /**< PCI Express 3 target interface */ -+ e_P1023_LAW_TARGET_LBC = 0x04, /**< Local bus target interface */ -+ e_P1023_LAW_TARGET_QM_PORTALS = 0x0E, /**< Queue Manager Portals */ -+ e_P1023_LAW_TARGET_BM_PORTALS = 0x0E, /**< Buffer Manager Portals */ -+ e_P1023_LAW_TARGET_SRAM = 0x0E, /**< SRAM scratchpad */ -+ e_P1023_LAW_TARGET_DDR = 0x0F, /**< DDR target interface */ -+ e_P1023_LAW_TARGET_NONE = 0xFF /**< Invalid target interface */ -+} e_P1023LawTargetId; -+ -+ -+/**************************************************************************//** -+ @Group 1023_init_grp P1023 Initialization Unit -+ -+ @Description P1023 initialization unit API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description Part ID and revision number -+*//***************************************************************************/ -+typedef enum e_P1023DeviceName -+{ -+ e_P1023_REV_INVALID = 0x00000000, /**< Invalid revision */ -+ e_SC1023_REV_1_0 = (int)0x80FC0010, /**< SC1023 rev 1.0 */ -+ e_SC1023_REV_1_1 = (int)0x80FC0011, /**< SC1023 rev 1.1 */ -+ e_P1023_REV_1_0 = (int)0x80FE0010, /**< P1023 rev 1.0 with security */ -+ e_P1023_REV_1_1 = (int)0x80FE0011, /**< P1023 rev 1.1 with security */ -+ e_P1017_REV_1_1 = (int)0x80FF0011, /**< P1017 rev 1.1 with security */ -+ e_P1023_REV_1_0_NO_SEC = (int)0x80F60010, /**< P1023 rev 1.0 without security */ -+ e_P1023_REV_1_1_NO_SEC = (int)0x80F60011, /**< P1023 rev 1.1 without security */ -+ e_P1017_REV_1_1_NO_SEC = (int)0x80F70011 /**< P1017 rev 1.1 without security */ -+} e_P1023DeviceName; -+ -+/**************************************************************************//** -+ @Description structure representing P1023 initialization parameters -+*//***************************************************************************/ -+typedef struct t_P1023Params -+{ -+ uintptr_t ccsrBaseAddress; /**< CCSR base address (virtual) */ -+ uintptr_t bmPortalsBaseAddress; /**< Portals base address (virtual) */ -+ uintptr_t qmPortalsBaseAddress; /**< Portals base address (virtual) */ -+} t_P1023Params; -+ -+/**************************************************************************//** -+ @Function P1023_ConfigAndInit -+ -+ @Description General initiation of the chip registers. -+ -+ @Param[in] p_P1023Params - A pointer to data structure of parameters -+ -+ @Return A handle to the P1023 data structure. -+*//***************************************************************************/ -+t_Handle P1023_ConfigAndInit(t_P1023Params *p_P1023Params); -+ -+/**************************************************************************//** -+ @Function P1023_Free -+ -+ @Description Free all resources. -+ -+ @Param h_P1023 - (In) The handle of the initialized P1023 object. -+ -+ @Return E_OK on success; Other value otherwise. -+*//***************************************************************************/ -+t_Error P1023_Free(t_Handle h_P1023); -+ -+/**************************************************************************//** -+ @Function P1023_GetRevInfo -+ -+ @Description This routine enables access to chip and revision information. -+ -+ @Param[in] gutilBase - Base address of P1023 GUTIL registers. -+ -+ @Return Part ID and revision. -+*//***************************************************************************/ -+e_P1023DeviceName P1023_GetRevInfo(uintptr_t gutilBase); -+ -+/**************************************************************************//** -+ @Function P1023_GetE500Factor -+ -+ @Description Returns E500 core clock multiplication factor. -+ -+ @Param[in] gutilBase - Base address of P1023 GUTIL registers. -+ @Param[in] coreId - Id of the requested core. -+ @Param[out] p_E500MulFactor - Returns E500 to CCB multification factor. -+ @Param[out] p_E500DivFactor - Returns E500 to CCB division factor. -+ -+ @Return E_OK on success; Other value otherwise. -+* -+*//***************************************************************************/ -+t_Error P1023_GetE500Factor(uintptr_t gutilBase, -+ uint32_t coreId, -+ uint32_t *p_E500MulFactor, -+ uint32_t *p_E500DivFactor); -+ -+/**************************************************************************//** -+ @Function P1023_GetFmFactor -+ -+ @Description returns FM multiplication factors. (This value is returned using -+ two parameters to avoid using float parameter). -+ -+ @Param[in] gutilBase - Base address of P1023 GUTIL registers. -+ @Param[out] p_FmMulFactor - returns E500 to CCB multification factor. -+ @Param[out] p_FmDivFactor - returns E500 to CCB division factor. -+ -+ @Return E_OK on success; Other value otherwise. -+*//***************************************************************************/ -+t_Error P1023_GetFmFactor(uintptr_t gutilBase, uint32_t *p_FmMulFactor, uint32_t *p_FmDivFactor); -+ -+/**************************************************************************//** -+ @Function P1023_GetCcbFactor -+ -+ @Description returns system multiplication factor. -+ -+ @Param[in] gutilBase - Base address of P1023 GUTIL registers. -+ -+ @Return System multiplication factor. -+*//***************************************************************************/ -+uint32_t P1023_GetCcbFactor(uintptr_t gutilBase); -+ -+#if 0 -+/**************************************************************************//** -+ @Function P1023_GetDdrFactor -+ -+ @Description returns the multiplication factor of the clock in for the DDR clock . -+ Note: assumes the ddr_in_clk is identical to the sys_in_clk -+ -+ @Param[in] gutilBase - Base address of P1023 GUTIL registers. -+ @Param p_DdrMulFactor - returns DDR in clk multification factor. -+ @Param p_DdrDivFactor - returns DDR division factor. -+ -+ @Return E_OK on success; Other value otherwise.. -+*//***************************************************************************/ -+t_Error P1023_GetDdrFactor( uintptr_t gutilBase, -+ uint32_t *p_DdrMulFactor, -+ uint32_t *p_DdrDivFactor); -+ -+/**************************************************************************//** -+ @Function P1023_GetDdrType -+ -+ @Description returns the multiplication factor of the clock in for the DDR clock . -+ -+ @Param[in] gutilBase - Base address of P1023 GUTIL registers. -+ @Param p_DdrType - (Out) returns DDR type DDR1/DDR2/DDR3. -+ -+ @Return E_OK on success; Other value otherwise. -+*//***************************************************************************/ -+t_Error P1023_GetDdrType(uintptr_t gutilBase, e_DdrType *p_DdrType ); -+#endif -+ -+/** @} */ /* end of 1023_init_grp group */ -+/** @} */ /* end of 1023_grp group */ -+ -+#define CORE_E500V2 -+ -+#if 0 /* using unified values */ -+/***************************************************************************** -+ INTEGRATION-SPECIFIC MODULE CODES -+******************************************************************************/ -+#define MODULE_UNKNOWN 0x00000000 -+#define MODULE_MEM 0x00010000 -+#define MODULE_MM 0x00020000 -+#define MODULE_CORE 0x00030000 -+#define MODULE_P1023 0x00040000 -+#define MODULE_MII 0x00050000 -+#define MODULE_PM 0x00060000 -+#define MODULE_MMU 0x00070000 -+#define MODULE_PIC 0x00080000 -+#define MODULE_L2_CACHE 0x00090000 -+#define MODULE_DUART 0x000a0000 -+#define MODULE_SERDES 0x000b0000 -+#define MODULE_PIO 0x000c0000 -+#define MODULE_QM 0x000d0000 -+#define MODULE_BM 0x000e0000 -+#define MODULE_SEC 0x000f0000 -+#define MODULE_FM 0x00100000 -+#define MODULE_FM_MURAM 0x00110000 -+#define MODULE_FM_PCD 0x00120000 -+#define MODULE_FM_RTC 0x00130000 -+#define MODULE_FM_MAC 0x00140000 -+#define MODULE_FM_PORT 0x00150000 -+#define MODULE_FM_MACSEC 0x00160000 -+#define MODULE_FM_MACSEC_SECY 0x00170000 -+#define MODULE_FM_SP 0x00280000 -+#define MODULE_ECM 0x00190000 -+#define MODULE_DMA 0x001a0000 -+#define MODULE_DDR 0x001b0000 -+#define MODULE_LAW 0x001c0000 -+#define MODULE_LBC 0x001d0000 -+#define MODULE_I2C 0x001e0000 -+#define MODULE_ESPI 0x001f0000 -+#define MODULE_PCI 0x00200000 -+#define MODULE_DPA_PORT 0x00210000 -+#define MODULE_USB 0x00220000 -+#endif /* using unified values */ -+ -+/***************************************************************************** -+ LBC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+/**************************************************************************//** -+ @Group lbc_exception_grp LBC Exception Unit -+ -+ @Description LBC Exception unit API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Anchor lbc_exbm -+ -+ @Collection LBC Errors Bit Mask -+ -+ These errors are reported through the exceptions callback.. -+ The values can be or'ed in any combination in the errors mask -+ parameter of the errors report structure. -+ -+ These errors can also be passed as a bit-mask to -+ LBC_EnableErrorChecking() or LBC_DisableErrorChecking(), -+ for enabling or disabling error checking. -+ @{ -+*//***************************************************************************/ -+#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */ -+#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */ -+#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */ -+#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */ -+ -+#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \ -+ LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT) -+ /**< All possible errors */ -+/* @} */ -+/** @} */ /* end of lbc_exception_grp group */ -+ -+#define LBC_NUM_OF_BANKS 2 -+#define LBC_MAX_CS_SIZE 0x0000000100000000LL -+#define LBC_ATOMIC_OPERATION_SUPPORT -+#define LBC_PARITY_SUPPORT -+#define LBC_ADDRESS_SHIFT_SUPPORT -+#define LBC_ADDRESS_HOLD_TIME_CTRL -+#define LBC_HIGH_CLK_DIVIDERS -+#define LBC_FCM_AVAILABLE -+ -+ -+/***************************************************************************** -+ LAW INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define LAW_ARCH_CCB -+#define LAW_NUM_OF_WINDOWS 12 -+#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */ -+#define LAW_MAX_WINDOW_SIZE 0x0000001000000000LL /**< 32GB */ -+ -+ -+/***************************************************************************** -+ SPI INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define SPI_NUM_OF_CONTROLLERS 1 -+ -+/***************************************************************************** -+ PCI/PCIe INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+ -+#define PCI_MAX_INBOUND_WINDOWS_NUM 4 -+#define PCI_MAX_OUTBOUND_WINDOWS_NUM 5 -+ -+/**************************************************************************//** -+ @Description Target interface of an inbound window -+*//***************************************************************************/ -+typedef enum e_PciTargetInterface -+{ -+ e_PCI_TARGET_PCIE_2 = 0x1, /**< PCI Express target interface 2 */ -+ e_PCI_TARGET_PCIE_1 = 0x2, /**< PCI Express target interface 1 */ -+ e_PCI_TARGET_PCIE_3 = 0x3, /**< PCI Express target interface 3 */ -+ e_PCI_TARGET_LOCAL_MEMORY = 0xF /**< Local Memory (DDR SDRAM, Local Bus, SRAM) target interface */ -+ -+} e_PciTargetInterface; -+ -+/***************************************************************************** -+ DDR INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define DDR_NUM_OF_VALID_CS 2 -+ -+/***************************************************************************** -+ SEC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define SEC_ERRATA_STAT_REGS_UNUSABLE -+ -+/***************************************************************************** -+ DMA INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define DMA_NUM_OF_CONTROLLERS 2 -+ -+ -+ -+ -+/***************************************************************************** -+ 1588 INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define PTP_V2 -+ -+/**************************************************************************//** -+ @Function P1023_GetMuxControlReg -+ -+ @Description Returns the value of PMUXCR (Alternate Function Signal Multiplex -+ Control Register) -+ -+ @Param[in] gutilBase - Base address of P1023 GUTIL registers. -+ -+ @Return Value of PMUXCR -+*//***************************************************************************/ -+uint32_t P1023_GetMuxControlReg(uintptr_t gutilBase); -+ -+/**************************************************************************//** -+ @Function P1023_SetMuxControlReg -+ -+ @Description Sets the value of PMUXCR (Alternate Function Signal Multiplex -+ Control Register) -+ -+ @Param[in] gutilBase - Base address of P1023 GUTIL registers. -+ @Param[in] val - the new value for PMUXCR. -+ -+ @Return None -+*//***************************************************************************/ -+void P1023_SetMuxControlReg(uintptr_t gutilBase, uint32_t val); -+ -+/**************************************************************************//** -+ @Function P1023_GetDeviceDisableStatusRegister -+ -+ @Description Returns the value of DEVDISR (Device Disable Register) -+ -+ @Param[in] gutilBase - Base address of P1023 GUTIL registers. -+ -+ @Return Value of DEVDISR -+*//***************************************************************************/ -+uint32_t P1023_GetDeviceDisableStatusRegister(uintptr_t gutilBase); -+ -+/**************************************************************************//** -+ @Function P1023_GetPorDeviceStatusRegister -+ -+ @Description Returns the value of POR Device Status Register -+ -+ @Param[in] gutilBase - Base address of P1023 GUTIL registers. -+ -+ @Return POR Device Status Register -+*//***************************************************************************/ -+uint32_t P1023_GetPorDeviceStatusRegister(uintptr_t gutilBase); -+ -+/**************************************************************************//** -+ @Function P1023_GetPorBootModeStatusRegister -+ -+ @Description Returns the value of POR Boot Mode Status Register -+ -+ @Param[in] gutilBase - Base address of P1023 GUTIL registers. -+ -+ @Return POR Boot Mode Status Register value -+*//***************************************************************************/ -+uint32_t P1023_GetPorBootModeStatusRegister(uintptr_t gutilBase); -+ -+ -+#define PORDEVSR_SGMII1_DIS 0x10000000 -+#define PORDEVSR_SGMII2_DIS 0x08000000 -+#define PORDEVSR_ECP1 0x02000000 -+#define PORDEVSR_IO_SEL 0x00780000 -+#define PORDEVSR_IO_SEL_SHIFT 19 -+#define PORBMSR_HA 0x00070000 -+#define PORBMSR_HA_SHIFT 16 -+ -+#define DEVDISR_QM_BM 0x80000000 -+#define DEVDISR_FM 0x40000000 -+#define DEVDISR_PCIE1 0x20000000 -+#define DEVDISR_MAC_SEC 0x10000000 -+#define DEVDISR_ELBC 0x08000000 -+#define DEVDISR_PCIE2 0x04000000 -+#define DEVDISR_PCIE3 0x02000000 -+#define DEVDISR_CAAM 0x01000000 -+#define DEVDISR_USB0 0x00800000 -+#define DEVDISR_1588 0x00020000 -+#define DEVDISR_CORE0 0x00008000 -+#define DEVDISR_TB0 0x00004000 -+#define DEVDISR_CORE1 0x00002000 -+#define DEVDISR_TB1 0x00001000 -+#define DEVDISR_DMA1 0x00000400 -+#define DEVDISR_DMA2 0x00000200 -+#define DEVDISR_DDR 0x00000010 -+#define DEVDISR_TSEC1 0x00000080 -+#define DEVDISR_TSEC2 0x00000040 -+#define DEVDISR_SPI 0x00000008 -+#define DEVDISR_I2C 0x00000004 -+#define DEVDISR_DUART 0x00000002 -+ -+ -+#endif /* __PART_INTEGRATION_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h -@@ -0,0 +1,276 @@ -+/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ @File dpaa_integration_ext.h -+ -+ @Description P3040/P4080/P5020 FM external definitions and structures. -+*//***************************************************************************/ -+#ifndef __DPAA_INTEGRATION_EXT_H -+#define __DPAA_INTEGRATION_EXT_H -+ -+#include "std_ext.h" -+ -+ -+#define DPAA_VERSION 10 -+ -+typedef enum { -+ e_DPAA_SWPORTAL0 = 0, -+ e_DPAA_SWPORTAL1, -+ e_DPAA_SWPORTAL2, -+ e_DPAA_SWPORTAL3, -+ e_DPAA_SWPORTAL4, -+ e_DPAA_SWPORTAL5, -+ e_DPAA_SWPORTAL6, -+ e_DPAA_SWPORTAL7, -+ e_DPAA_SWPORTAL8, -+ e_DPAA_SWPORTAL9, -+ e_DPAA_SWPORTAL_DUMMY_LAST -+} e_DpaaSwPortal; -+ -+typedef enum { -+ e_DPAA_DCPORTAL0 = 0, -+ e_DPAA_DCPORTAL1, -+ e_DPAA_DCPORTAL2, -+ e_DPAA_DCPORTAL3, -+ e_DPAA_DCPORTAL4, -+ e_DPAA_DCPORTAL_DUMMY_LAST -+} e_DpaaDcPortal; -+ -+#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST -+#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST -+ -+/***************************************************************************** -+ QMan INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */ -+#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */ -+#define QM_MAX_NUM_OF_SWP_AS 4 -+#define QM_MAX_NUM_OF_CGS 256 /**< Number of congestion groups */ -+#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) /**< FQIDs range - 24 bits */ -+ -+/**************************************************************************//** -+ @Description Work Queue Channel assignments in QMan. -+*//***************************************************************************/ -+typedef enum -+{ -+ e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */ -+ e_QM_FQ_CHANNEL_SWPORTAL1, -+ e_QM_FQ_CHANNEL_SWPORTAL2, -+ e_QM_FQ_CHANNEL_SWPORTAL3, -+ e_QM_FQ_CHANNEL_SWPORTAL4, -+ e_QM_FQ_CHANNEL_SWPORTAL5, -+ e_QM_FQ_CHANNEL_SWPORTAL6, -+ e_QM_FQ_CHANNEL_SWPORTAL7, -+ e_QM_FQ_CHANNEL_SWPORTAL8, -+ e_QM_FQ_CHANNEL_SWPORTAL9, -+ -+ e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */ -+ e_QM_FQ_CHANNEL_POOL2, -+ e_QM_FQ_CHANNEL_POOL3, -+ e_QM_FQ_CHANNEL_POOL4, -+ e_QM_FQ_CHANNEL_POOL5, -+ e_QM_FQ_CHANNEL_POOL6, -+ e_QM_FQ_CHANNEL_POOL7, -+ e_QM_FQ_CHANNEL_POOL8, -+ e_QM_FQ_CHANNEL_POOL9, -+ e_QM_FQ_CHANNEL_POOL10, -+ e_QM_FQ_CHANNEL_POOL11, -+ e_QM_FQ_CHANNEL_POOL12, -+ e_QM_FQ_CHANNEL_POOL13, -+ e_QM_FQ_CHANNEL_POOL14, -+ e_QM_FQ_CHANNEL_POOL15, -+ -+ e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0: -+ connected to FMan 0; assigned in incrementing order to -+ each sub-portal (SP) in the portal */ -+ e_QM_FQ_CHANNEL_FMAN0_SP1, -+ e_QM_FQ_CHANNEL_FMAN0_SP2, -+ e_QM_FQ_CHANNEL_FMAN0_SP3, -+ e_QM_FQ_CHANNEL_FMAN0_SP4, -+ e_QM_FQ_CHANNEL_FMAN0_SP5, -+ e_QM_FQ_CHANNEL_FMAN0_SP6, -+ e_QM_FQ_CHANNEL_FMAN0_SP7, -+ e_QM_FQ_CHANNEL_FMAN0_SP8, -+ e_QM_FQ_CHANNEL_FMAN0_SP9, -+ e_QM_FQ_CHANNEL_FMAN0_SP10, -+ e_QM_FQ_CHANNEL_FMAN0_SP11, -+/* difference between 5020 and 4080 :) */ -+ e_QM_FQ_CHANNEL_FMAN1_SP0 = 0x60, -+ e_QM_FQ_CHANNEL_FMAN1_SP1, -+ e_QM_FQ_CHANNEL_FMAN1_SP2, -+ e_QM_FQ_CHANNEL_FMAN1_SP3, -+ e_QM_FQ_CHANNEL_FMAN1_SP4, -+ e_QM_FQ_CHANNEL_FMAN1_SP5, -+ e_QM_FQ_CHANNEL_FMAN1_SP6, -+ e_QM_FQ_CHANNEL_FMAN1_SP7, -+ e_QM_FQ_CHANNEL_FMAN1_SP8, -+ e_QM_FQ_CHANNEL_FMAN1_SP9, -+ e_QM_FQ_CHANNEL_FMAN1_SP10, -+ e_QM_FQ_CHANNEL_FMAN1_SP11, -+ -+ e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2: -+ connected to SEC 4.x */ -+ -+ e_QM_FQ_CHANNEL_PME = 0xA0, /**< Dedicated channel serviced by Direct Connect Portal 3: -+ connected to PME */ -+ e_QM_FQ_CHANNEL_RAID = 0xC0 /**< Dedicated channel serviced by Direct Connect Portal 4: -+ connected to RAID */ -+} e_QmFQChannel; -+ -+/***************************************************************************** -+ BMan INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */ -+ -+ -+/***************************************************************************** -+ FM INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define INTG_MAX_NUM_OF_FM 2 -+ -+/* Ports defines */ -+#define FM_MAX_NUM_OF_1G_MACS 5 -+#define FM_MAX_NUM_OF_10G_MACS 1 -+#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS) -+#define FM_MAX_NUM_OF_OH_PORTS 7 -+ -+#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS -+#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS -+#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS) -+ -+#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS -+#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS -+#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS) -+ -+#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */ -+#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */ -+#define FM_MAX_NUM_OF_SUB_PORTALS 12 -+#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0 -+ -+/* Rams defines */ -+#define FM_MURAM_SIZE (160*KILOBYTE) -+#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE) -+#define FM_NUM_OF_CTRL 2 -+ -+/* PCD defines */ -+#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */ -+#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */ -+#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */ -+#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */ -+#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */ -+ -+/* RTC defines */ -+#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */ -+#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */ -+#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */ -+ -+/* QMI defines */ -+#define QMI_MAX_NUM_OF_TNUMS 64 -+#define QMI_DEF_TNUMS_THRESH 48 -+ -+/* FPM defines */ -+#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4 -+ -+/* DMA defines */ -+#define DMA_THRESH_MAX_COMMQ 31 -+#define DMA_THRESH_MAX_BUF 127 -+ -+/* BMI defines */ -+#define BMI_MAX_NUM_OF_TASKS 128 -+#define BMI_MAX_NUM_OF_DMAS 32 -+#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE) -+#define PORT_MAX_WEIGHT 16 -+ -+ -+#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE -+ -+/* p4080-rev1 unique features */ -+#define QM_CGS_NO_FRAME_MODE -+ -+/* p4080 unique features */ -+#define FM_NO_DISPATCH_RAM_ECC -+#define FM_NO_WATCHDOG -+#define FM_NO_TNUM_AGING -+#define FM_KG_NO_BYPASS_FQID_GEN -+#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN -+#define FM_NO_BACKUP_POOLS -+#define FM_NO_OP_OBSERVED_POOLS -+#define FM_NO_ADVANCED_RATE_LIMITER -+#define FM_NO_OP_OBSERVED_CGS -+#define FM_HAS_TOTAL_DMAS -+#define FM_KG_NO_IPPID_SUPPORT -+#define FM_NO_GUARANTEED_RESET_VALUES -+#define FM_MAC_RESET -+ -+/* FM erratas */ -+#define FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 -+#define FM_TX_SHORT_FRAME_BAD_TS_ERRATA_10GMAC_A006 /* No implementation, Out of LLD scope */ -+#define FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 -+#define FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 -+#define FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 /* Out of LLD scope, user may disable ECC exceptions using FM_DisableRamsEcc */ -+#define FM_BAD_VLAN_DETECT_ERRATA_10GMAC_A010 -+ -+#define FM_RX_PREAM_4_ERRATA_DTSEC_A001 -+#define FM_GRS_ERRATA_DTSEC_A002 -+#define FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 -+#define FM_GTS_ERRATA_DTSEC_A004 -+#define FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012 -+#define FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 -+#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 -+ -+#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */ -+#define FM_TX_LOCKUP_ERRATA_DTSEC6 -+ -+#define FM_HC_DEF_FQID_ONLY_ERRATA_FMAN_A003 /* Implemented by ucode */ -+#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */ -+ -+#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 -+ -+#define FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 -+ -+#define FM_LEN_CHECK_ERRATA_FMAN_SW002 -+ -+#define FM_NO_CTXA_COPY_ERRATA_FMAN_SW001 -+#define FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 -+ -+/***************************************************************************** -+ FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define NUM_OF_RX_SC 16 -+#define NUM_OF_TX_SC 16 -+ -+#define NUM_OF_SA_PER_RX_SC 2 -+#define NUM_OF_SA_PER_TX_SC 2 -+ -+ -+#endif /* __DPAA_INTEGRATION_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h -@@ -0,0 +1,83 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ -+ @File part_ext.h -+ -+ @Description Definitions for the part (integration) module. -+*//***************************************************************************/ -+ -+#ifndef __PART_EXT_H -+#define __PART_EXT_H -+ -+#include "std_ext.h" -+#include "part_integration_ext.h" -+ -+ -+#if !(defined(MPC8306) || \ -+ defined(MPC8309) || \ -+ defined(MPC834x) || \ -+ defined(MPC836x) || \ -+ defined(MPC832x) || \ -+ defined(MPC837x) || \ -+ defined(MPC8568) || \ -+ defined(MPC8569) || \ -+ defined(P1020) || \ -+ defined(P1021) || \ -+ defined(P1022) || \ -+ defined(P1023) || \ -+ defined(P2020) || \ -+ defined(P2040) || \ -+ defined(P3041) || \ -+ defined(P4080) || \ -+ defined(SC4080) || \ -+ defined(P5020) || \ -+ defined(MSC814x)) -+#error "unable to proceed without chip-definition" -+#endif /* !(defined(MPC834x) || ... */ -+ -+ -+/**************************************************************************//* -+ @Description Part data structure - must be contained in any integration -+ data structure. -+*//***************************************************************************/ -+typedef struct t_Part -+{ -+ uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId); -+ /**< Returns the address of the module's memory map base. */ -+ e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress); -+ /**< Returns the module's ID according to its memory map base. */ -+} t_Part; -+ -+ -+#endif /* __PART_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h -@@ -0,0 +1,336 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ @File part_integration_ext.h -+ -+ @Description P3040/P4080/P5020 external definitions and structures. -+*//***************************************************************************/ -+#ifndef __PART_INTEGRATION_EXT_H -+#define __PART_INTEGRATION_EXT_H -+ -+#include "std_ext.h" -+#include "dpaa_integration_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group P3040/P4080/P5020_chip_id P5020 Application Programming Interface -+ -+ @Description P3040/P4080/P5020 Chip functions,definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+#define CORE_E500MC -+ -+#define INTG_MAX_NUM_OF_CORES 1 -+ -+ -+/**************************************************************************//** -+ @Description Module types. -+*//***************************************************************************/ -+typedef enum e_ModuleId -+{ -+ e_MODULE_ID_DUART_1 = 0, -+ e_MODULE_ID_DUART_2, -+ e_MODULE_ID_DUART_3, -+ e_MODULE_ID_DUART_4, -+ e_MODULE_ID_LAW, -+ e_MODULE_ID_LBC, -+ e_MODULE_ID_PAMU, -+ e_MODULE_ID_QM, /**< Queue manager module */ -+ e_MODULE_ID_BM, /**< Buffer manager module */ -+ e_MODULE_ID_QM_CE_PORTAL_0, -+ e_MODULE_ID_QM_CI_PORTAL_0, -+ e_MODULE_ID_QM_CE_PORTAL_1, -+ e_MODULE_ID_QM_CI_PORTAL_1, -+ e_MODULE_ID_QM_CE_PORTAL_2, -+ e_MODULE_ID_QM_CI_PORTAL_2, -+ e_MODULE_ID_QM_CE_PORTAL_3, -+ e_MODULE_ID_QM_CI_PORTAL_3, -+ e_MODULE_ID_QM_CE_PORTAL_4, -+ e_MODULE_ID_QM_CI_PORTAL_4, -+ e_MODULE_ID_QM_CE_PORTAL_5, -+ e_MODULE_ID_QM_CI_PORTAL_5, -+ e_MODULE_ID_QM_CE_PORTAL_6, -+ e_MODULE_ID_QM_CI_PORTAL_6, -+ e_MODULE_ID_QM_CE_PORTAL_7, -+ e_MODULE_ID_QM_CI_PORTAL_7, -+ e_MODULE_ID_QM_CE_PORTAL_8, -+ e_MODULE_ID_QM_CI_PORTAL_8, -+ e_MODULE_ID_QM_CE_PORTAL_9, -+ e_MODULE_ID_QM_CI_PORTAL_9, -+ e_MODULE_ID_BM_CE_PORTAL_0, -+ e_MODULE_ID_BM_CI_PORTAL_0, -+ e_MODULE_ID_BM_CE_PORTAL_1, -+ e_MODULE_ID_BM_CI_PORTAL_1, -+ e_MODULE_ID_BM_CE_PORTAL_2, -+ e_MODULE_ID_BM_CI_PORTAL_2, -+ e_MODULE_ID_BM_CE_PORTAL_3, -+ e_MODULE_ID_BM_CI_PORTAL_3, -+ e_MODULE_ID_BM_CE_PORTAL_4, -+ e_MODULE_ID_BM_CI_PORTAL_4, -+ e_MODULE_ID_BM_CE_PORTAL_5, -+ e_MODULE_ID_BM_CI_PORTAL_5, -+ e_MODULE_ID_BM_CE_PORTAL_6, -+ e_MODULE_ID_BM_CI_PORTAL_6, -+ e_MODULE_ID_BM_CE_PORTAL_7, -+ e_MODULE_ID_BM_CI_PORTAL_7, -+ e_MODULE_ID_BM_CE_PORTAL_8, -+ e_MODULE_ID_BM_CI_PORTAL_8, -+ e_MODULE_ID_BM_CE_PORTAL_9, -+ e_MODULE_ID_BM_CI_PORTAL_9, -+ e_MODULE_ID_FM1, /**< Frame manager #1 module */ -+ e_MODULE_ID_FM1_RTC, /**< FM Real-Time-Clock */ -+ e_MODULE_ID_FM1_MURAM, /**< FM Multi-User-RAM */ -+ e_MODULE_ID_FM1_BMI, /**< FM BMI block */ -+ e_MODULE_ID_FM1_QMI, /**< FM QMI block */ -+ e_MODULE_ID_FM1_PRS, /**< FM parser block */ -+ e_MODULE_ID_FM1_PORT_HO0, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM1_PORT_HO1, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM1_PORT_HO2, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM1_PORT_HO3, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM1_PORT_HO4, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM1_PORT_HO5, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM1_PORT_HO6, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM1_PORT_1GRx0, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM1_PORT_1GRx1, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM1_PORT_1GRx2, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM1_PORT_1GRx3, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM1_PORT_1GRx4, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM1_PORT_10GRx0, /**< FM Rx 10G MAC port block */ -+ e_MODULE_ID_FM1_PORT_1GTx0, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM1_PORT_1GTx1, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM1_PORT_1GTx2, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM1_PORT_1GTx3, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM1_PORT_1GTx4, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM1_PORT_10GTx0, /**< FM Tx 10G MAC port block */ -+ e_MODULE_ID_FM1_PLCR, /**< FM Policer */ -+ e_MODULE_ID_FM1_KG, /**< FM Keygen */ -+ e_MODULE_ID_FM1_DMA, /**< FM DMA */ -+ e_MODULE_ID_FM1_FPM, /**< FM FPM */ -+ e_MODULE_ID_FM1_IRAM, /**< FM Instruction-RAM */ -+ e_MODULE_ID_FM1_1GMDIO0, /**< FM 1G MDIO MAC 0*/ -+ e_MODULE_ID_FM1_1GMDIO1, /**< FM 1G MDIO MAC 1*/ -+ e_MODULE_ID_FM1_1GMDIO2, /**< FM 1G MDIO MAC 2*/ -+ e_MODULE_ID_FM1_1GMDIO3, /**< FM 1G MDIO MAC 3*/ -+ e_MODULE_ID_FM1_10GMDIO, /**< FM 10G MDIO */ -+ e_MODULE_ID_FM1_PRS_IRAM, /**< FM SW-parser Instruction-RAM */ -+ e_MODULE_ID_FM1_1GMAC0, /**< FM 1G MAC #0 */ -+ e_MODULE_ID_FM1_1GMAC1, /**< FM 1G MAC #1 */ -+ e_MODULE_ID_FM1_1GMAC2, /**< FM 1G MAC #2 */ -+ e_MODULE_ID_FM1_1GMAC3, /**< FM 1G MAC #3 */ -+ e_MODULE_ID_FM1_10GMAC0, /**< FM 10G MAC #0 */ -+ -+ e_MODULE_ID_FM2, /**< Frame manager #2 module */ -+ e_MODULE_ID_FM2_RTC, /**< FM Real-Time-Clock */ -+ e_MODULE_ID_FM2_MURAM, /**< FM Multi-User-RAM */ -+ e_MODULE_ID_FM2_BMI, /**< FM BMI block */ -+ e_MODULE_ID_FM2_QMI, /**< FM QMI block */ -+ e_MODULE_ID_FM2_PRS, /**< FM parser block */ -+ e_MODULE_ID_FM2_PORT_HO0, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM2_PORT_HO1, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM2_PORT_HO2, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM2_PORT_HO3, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM2_PORT_HO4, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM2_PORT_HO5, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM2_PORT_HO6, /**< FM Host-command/offline-parsing port block */ -+ e_MODULE_ID_FM2_PORT_1GRx0, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM2_PORT_1GRx1, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM2_PORT_1GRx2, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM2_PORT_1GRx3, /**< FM Rx 1G MAC port block */ -+ e_MODULE_ID_FM2_PORT_10GRx0, /**< FM Rx 10G MAC port block */ -+ e_MODULE_ID_FM2_PORT_1GTx0, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM2_PORT_1GTx1, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM2_PORT_1GTx2, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM2_PORT_1GTx3, /**< FM Tx 1G MAC port block */ -+ e_MODULE_ID_FM2_PORT_10GTx0, /**< FM Tx 10G MAC port block */ -+ e_MODULE_ID_FM2_PLCR, /**< FM Policer */ -+ e_MODULE_ID_FM2_KG, /**< FM Keygen */ -+ e_MODULE_ID_FM2_DMA, /**< FM DMA */ -+ e_MODULE_ID_FM2_FPM, /**< FM FPM */ -+ e_MODULE_ID_FM2_IRAM, /**< FM Instruction-RAM */ -+ e_MODULE_ID_FM2_1GMDIO0, /**< FM 1G MDIO MAC 0*/ -+ e_MODULE_ID_FM2_1GMDIO1, /**< FM 1G MDIO MAC 1*/ -+ e_MODULE_ID_FM2_1GMDIO2, /**< FM 1G MDIO MAC 2*/ -+ e_MODULE_ID_FM2_1GMDIO3, /**< FM 1G MDIO MAC 3*/ -+ e_MODULE_ID_FM2_10GMDIO, /**< FM 10G MDIO */ -+ e_MODULE_ID_FM2_PRS_IRAM, /**< FM SW-parser Instruction-RAM */ -+ e_MODULE_ID_FM2_1GMAC0, /**< FM 1G MAC #0 */ -+ e_MODULE_ID_FM2_1GMAC1, /**< FM 1G MAC #1 */ -+ e_MODULE_ID_FM2_1GMAC2, /**< FM 1G MAC #2 */ -+ e_MODULE_ID_FM2_1GMAC3, /**< FM 1G MAC #3 */ -+ e_MODULE_ID_FM2_10GMAC0, /**< FM 10G MAC #0 */ -+ -+ e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */ -+ e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */ -+ e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */ -+ e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */ -+ e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */ -+ e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */ -+ e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */ -+ e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */ -+ e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */ -+ e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */ -+ e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */ -+ e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */ -+ -+ e_MODULE_ID_MPIC, /**< MPIC */ -+ e_MODULE_ID_GPIO, /**< GPIO */ -+ e_MODULE_ID_SERDES, /**< SERDES */ -+ e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */ -+ e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */ -+ -+ e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */ -+ e_MODULE_ID_SRIO_MU, /**< RapidIO messaging unit module */ -+ -+ e_MODULE_ID_DUMMY_LAST -+} e_ModuleId; -+ -+#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST -+ -+#if 0 /* using unified values */ -+/***************************************************************************** -+ INTEGRATION-SPECIFIC MODULE CODES -+******************************************************************************/ -+#define MODULE_UNKNOWN 0x00000000 -+#define MODULE_MEM 0x00010000 -+#define MODULE_MM 0x00020000 -+#define MODULE_CORE 0x00030000 -+#define MODULE_CHIP 0x00040000 -+#define MODULE_PLTFRM 0x00050000 -+#define MODULE_PM 0x00060000 -+#define MODULE_MMU 0x00070000 -+#define MODULE_PIC 0x00080000 -+#define MODULE_CPC 0x00090000 -+#define MODULE_DUART 0x000a0000 -+#define MODULE_SERDES 0x000b0000 -+#define MODULE_PIO 0x000c0000 -+#define MODULE_QM 0x000d0000 -+#define MODULE_BM 0x000e0000 -+#define MODULE_SEC 0x000f0000 -+#define MODULE_LAW 0x00100000 -+#define MODULE_LBC 0x00110000 -+#define MODULE_PAMU 0x00120000 -+#define MODULE_FM 0x00130000 -+#define MODULE_FM_MURAM 0x00140000 -+#define MODULE_FM_PCD 0x00150000 -+#define MODULE_FM_RTC 0x00160000 -+#define MODULE_FM_MAC 0x00170000 -+#define MODULE_FM_PORT 0x00180000 -+#define MODULE_FM_SP 0x00190000 -+#define MODULE_DPA_PORT 0x001a0000 -+#define MODULE_MII 0x001b0000 -+#define MODULE_I2C 0x001c0000 -+#define MODULE_DMA 0x001d0000 -+#define MODULE_DDR 0x001e0000 -+#define MODULE_ESPI 0x001f0000 -+#define MODULE_DPAA_IPSEC 0x00200000 -+#endif /* using unified values */ -+ -+/***************************************************************************** -+ PAMU INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define PAMU_NUM_OF_PARTITIONS 5 -+ -+#define PAMU_PICS_AVICS_ERRATA_PAMU3 -+ -+/***************************************************************************** -+ LAW INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define LAW_NUM_OF_WINDOWS 32 -+#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */ -+#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */ -+ -+ -+/***************************************************************************** -+ LBC INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+/**************************************************************************//** -+ @Group lbc_exception_grp LBC Exception Unit -+ -+ @Description LBC Exception unit API functions, definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Anchor lbc_exbm -+ -+ @Collection LBC Errors Bit Mask -+ -+ These errors are reported through the exceptions callback.. -+ The values can be or'ed in any combination in the errors mask -+ parameter of the errors report structure. -+ -+ These errors can also be passed as a bit-mask to -+ LBC_EnableErrorChecking() or LBC_DisableErrorChecking(), -+ for enabling or disabling error checking. -+ @{ -+*//***************************************************************************/ -+#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */ -+#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */ -+#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */ -+#define LBC_ERR_ATOMIC_WRITE 0x00800000 /**< Atomic write error */ -+#define LBC_ERR_ATOMIC_READ 0x00400000 /**< Atomic read error */ -+#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */ -+ -+#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \ -+ LBC_ERR_WRITE_PROTECT | LBC_ERR_ATOMIC_WRITE | \ -+ LBC_ERR_ATOMIC_READ | LBC_ERR_CHIP_SELECT) -+ /**< All possible errors */ -+/* @} */ -+/** @} */ /* end of lbc_exception_grp group */ -+ -+#define LBC_INCORRECT_ERROR_REPORT_ERRATA -+ -+#define LBC_NUM_OF_BANKS 8 -+#define LBC_MAX_CS_SIZE 0x0000000100000000LL -+#define LBC_ATOMIC_OPERATION_SUPPORT -+#define LBC_PARITY_SUPPORT -+#define LBC_ADDRESS_HOLD_TIME_CTRL -+#define LBC_HIGH_CLK_DIVIDERS -+#define LBC_FCM_AVAILABLE -+ -+/***************************************************************************** -+ GPIO INTEGRATION-SPECIFIC DEFINITIONS -+******************************************************************************/ -+#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module; -+ Each port contains up to 32 i/O pins. */ -+ -+#define GPIO_VALID_PIN_MASKS \ -+ { /* Port A */ 0xFFFFFFFF } -+ -+#define GPIO_VALID_INTR_MASKS \ -+ { /* Port A */ 0xFFFFFFFF } -+ -+#endif /* __PART_INTEGRATION_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h -@@ -0,0 +1,100 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#ifndef __MATH_EXT_H -+#define __MATH_EXT_H -+ -+ -+#if defined(NCSW_LINUX) && defined(__KERNEL__) -+#include -+#include -+ -+#elif defined(__MWERKS__) -+#define LOW(x) ( sizeof(x)==8 ? *(1+(int32_t*)&x) : (*(int32_t*)&x)) -+#define HIGH(x) (*(int32_t*)&x) -+#define ULOW(x) ( sizeof(x)==8 ? *(1+(uint32_t*)&x) : (*(uint32_t*)&x)) -+#define UHIGH(x) (*(uint32_t*)&x) -+ -+static const double big = 1.0e300; -+ -+/* Macro for checking if a number is a power of 2 */ -+static __inline__ double ceil(double x) -+{ -+ int32_t i0,i1,j0; /*- cc 020130 -*/ -+ uint32_t i,j; /*- cc 020130 -*/ -+ i0 = HIGH(x); -+ i1 = LOW(x); -+ j0 = ((i0>>20)&0x7ff)-0x3ff; -+ if(j0<20) { -+ if(j0<0) { /* raise inexact if x != 0 */ -+ if(big+x>0.0) {/* return 0*sign(x) if |x|<1 */ -+ if(i0<0) {i0=0x80000000;i1=0;} -+ else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;} -+ } -+ } else { -+ i = (uint32_t)(0x000fffff)>>j0; -+ if(((i0&i)|i1)==0) return x; /* x is integral */ -+ if(big+x>0.0) { /* raise inexact flag */ -+ if(i0>0) i0 += (0x00100000)>>j0; -+ i0 &= (~i); i1=0; -+ } -+ } -+ } else if (j0>51) { -+ if(j0==0x400) return x+x; /* inf or NaN */ -+ else return x; /* x is integral */ -+ } else { -+ i = ((uint32_t)(0xffffffff))>>(j0-20); /*- cc 020130 -*/ -+ if((i1&i)==0) return x; /* x is integral */ -+ if(big+x>0.0) { /* raise inexact flag */ -+ if(i0>0) { -+ if(j0==20) i0+=1; -+ else { -+ j = (uint32_t)(i1 + (1<<(52-j0))); -+ if(j -+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */ -+ -+ -+#endif /* __MATH_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h -@@ -0,0 +1,435 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File ncsw_ext.h -+ -+ @Description General NetCommSw Standard Definitions -+*//***************************************************************************/ -+ -+#ifndef __NCSW_EXT_H -+#define __NCSW_EXT_H -+ -+ -+#include "memcpy_ext.h" -+ -+#define WRITE_BLOCK IOMemSet32 /* include memcpy_ext.h */ -+#define COPY_BLOCK Mem2IOCpy32 /* include memcpy_ext.h */ -+ -+#define PTR_TO_UINT(_ptr) ((uintptr_t)(_ptr)) -+#define UINT_TO_PTR(_val) ((void*)(uintptr_t)(_val)) -+ -+#define PTR_MOVE(_ptr, _offset) (void*)((uint8_t*)(_ptr) + (_offset)) -+ -+ -+#define WRITE_UINT8_UINT24(arg, data08, data24) \ -+ WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF)) -+#define WRITE_UINT24_UINT8(arg, data24, data08) \ -+ WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF)) -+ -+/* Little-Endian access macros */ -+ -+#define WRITE_UINT16_LE(arg, data) \ -+ WRITE_UINT16((arg), SwapUint16(data)) -+ -+#define WRITE_UINT32_LE(arg, data) \ -+ WRITE_UINT32((arg), SwapUint32(data)) -+ -+#define WRITE_UINT64_LE(arg, data) \ -+ WRITE_UINT64((arg), SwapUint64(data)) -+ -+#define GET_UINT16_LE(arg) \ -+ SwapUint16(GET_UINT16(arg)) -+ -+#define GET_UINT32_LE(arg) \ -+ SwapUint32(GET_UINT32(arg)) -+ -+#define GET_UINT64_LE(arg) \ -+ SwapUint64(GET_UINT64(arg)) -+ -+/* Write and Read again macros */ -+#define WRITE_UINT_SYNC(size, arg, data) \ -+ do { \ -+ WRITE_UINT##size((arg), (data)); \ -+ CORE_MemoryBarrier(); \ -+ } while (0) -+ -+#define WRITE_UINT8_SYNC(arg, data) WRITE_UINT_SYNC(8, (arg), (data)) -+ -+#define WRITE_UINT16_SYNC(arg, data) WRITE_UINT_SYNC(16, (arg), (data)) -+#define WRITE_UINT32_SYNC(arg, data) WRITE_UINT_SYNC(32, (arg), (data)) -+ -+#define MAKE_UINT64(high32, low32) (((uint64_t)high32 << 32) | (low32)) -+ -+ -+/*----------------------*/ -+/* Miscellaneous macros */ -+/*----------------------*/ -+ -+#define UNUSED(_x) ((void)(_x)) -+ -+#define KILOBYTE 0x400UL /* 1024 */ -+#define MEGABYTE (KILOBYTE * KILOBYTE) /* 1024*1024 */ -+#define GIGABYTE ((uint64_t)(KILOBYTE * MEGABYTE)) /* 1024*1024*1024 */ -+#define TERABYTE ((uint64_t)(KILOBYTE * GIGABYTE)) /* 1024*1024*1024*1024 */ -+ -+#ifndef NO_IRQ -+#define NO_IRQ (0) -+#endif -+#define NCSW_MASTER_ID (0) -+ -+/* Macro for checking if a number is a power of 2 */ -+#define POWER_OF_2(n) (!((n) & ((n)-1))) -+ -+/* Macro for calculating log of base 2 */ -+#define LOG2(num, log2Num) \ -+ do \ -+ { \ -+ uint64_t tmp = (num); \ -+ log2Num = 0; \ -+ while (tmp > 1) \ -+ { \ -+ log2Num++; \ -+ tmp >>= 1; \ -+ } \ -+ } while (0) -+ -+#define NEXT_POWER_OF_2(_num, _nextPow) \ -+do \ -+{ \ -+ if (POWER_OF_2(_num)) \ -+ _nextPow = (_num); \ -+ else \ -+ { \ -+ uint64_t tmp = (_num); \ -+ _nextPow = 1; \ -+ while (tmp) \ -+ { \ -+ _nextPow <<= 1; \ -+ tmp >>= 1; \ -+ } \ -+ } \ -+} while (0) -+ -+/* Ceiling division - not the fastest way, but safer in terms of overflow */ -+#define DIV_CEIL(x,y) (div64_u64((x),(y)) + (((div64_u64((x),(y))*(y)) == (x)) ? 0 : 1)) -+ -+/* Round up a number to be a multiple of a second number */ -+#define ROUND_UP(x,y) ((((x) + (y) - 1) / (y)) * (y)) -+ -+/* Timing macro for converting usec units to number of ticks. */ -+/* (number of usec * clock_Hz) / 1,000,000) - since */ -+/* clk is in MHz units, no division needed. */ -+#define USEC_TO_CLK(usec,clk) ((usec) * (clk)) -+#define CYCLES_TO_USEC(cycles,clk) ((cycles) / (clk)) -+ -+/* Timing macros for converting between nsec units and number of clocks. */ -+#define NSEC_TO_CLK(nsec,clk) DIV_CEIL(((nsec) * (clk)), 1000) -+#define CYCLES_TO_NSEC(cycles,clk) (((cycles) * 1000) / (clk)) -+ -+/* Timing macros for converting between psec units and number of clocks. */ -+#define PSEC_TO_CLK(psec,clk) DIV_CEIL(((psec) * (clk)), 1000000) -+#define CYCLES_TO_PSEC(cycles,clk) (((cycles) * 1000000) / (clk)) -+ -+/* Min, Max macros */ -+#define MIN(a,b) ((a) < (b) ? (a) : (b)) -+#define MAX(a,b) ((a) > (b) ? (a) : (b)) -+#define IN_RANGE(min,val,max) ((min)<=(val) && (val)<=(max)) -+ -+#define ABS(a) ((a<0)?(a*-1):a) -+ -+#if !(defined(ARRAY_SIZE)) -+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -+#endif /* !defined(ARRAY_SIZE) */ -+ -+ -+/* possible alignments */ -+#define HALF_WORD_ALIGNMENT 2 -+#define WORD_ALIGNMENT 4 -+#define DOUBLE_WORD_ALIGNMENT 8 -+#define BURST_ALIGNMENT 32 -+ -+#define HALF_WORD_ALIGNED 0x00000001 -+#define WORD_ALIGNED 0x00000003 -+#define DOUBLE_WORD_ALIGNED 0x00000007 -+#define BURST_ALIGNED 0x0000001f -+#ifndef IS_ALIGNED -+#define IS_ALIGNED(n,align) (!((uint32_t)(n) & (align - 1))) -+#endif /* IS_ALIGNED */ -+ -+ -+#define LAST_BUF 1 -+#define FIRST_BUF 2 -+#define SINGLE_BUF (LAST_BUF | FIRST_BUF) -+#define MIDDLE_BUF 4 -+ -+#define ARRAY_END -1 -+ -+#define ILLEGAL_BASE (~0) -+ -+#define BUF_POSITION(first, last) state[(!!(last))<<1 | !!(first)] -+#define DECLARE_POSITION static uint8_t state[4] = { (uint8_t)MIDDLE_BUF, (uint8_t)FIRST_BUF, (uint8_t)LAST_BUF, (uint8_t)SINGLE_BUF }; -+ -+ -+/**************************************************************************//** -+ @Description Timers operation mode -+*//***************************************************************************/ -+typedef enum e_TimerMode -+{ -+ e_TIMER_MODE_INVALID = 0, -+ e_TIMER_MODE_FREE_RUN, /**< Free run - counter continues to increase -+ after reaching the reference value. */ -+ e_TIMER_MODE_PERIODIC, /**< Periodic - counter restarts counting from 0 -+ after reaching the reference value. */ -+ e_TIMER_MODE_SINGLE /**< Single (one-shot) - counter stops counting -+ after reaching the reference value. */ -+} e_TimerMode; -+ -+ -+/**************************************************************************//** -+ @Description Enumeration (bit flags) of communication modes (Transmit, -+ receive or both). -+*//***************************************************************************/ -+typedef enum e_CommMode -+{ -+ e_COMM_MODE_NONE = 0, /**< No transmit/receive communication */ -+ e_COMM_MODE_RX = 1, /**< Only receive communication */ -+ e_COMM_MODE_TX = 2, /**< Only transmit communication */ -+ e_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */ -+} e_CommMode; -+ -+/**************************************************************************//** -+ @Description General Diagnostic Mode -+*//***************************************************************************/ -+typedef enum e_DiagMode -+{ -+ e_DIAG_MODE_NONE = 0, /**< Normal operation; no diagnostic mode */ -+ e_DIAG_MODE_CTRL_LOOPBACK, /**< Loopback in the controller */ -+ e_DIAG_MODE_CHIP_LOOPBACK, /**< Loopback in the chip but not in the -+ controller; e.g. IO-pins, SerDes, etc. */ -+ e_DIAG_MODE_PHY_LOOPBACK, /**< Loopback in the external PHY */ -+ e_DIAG_MODE_EXT_LOOPBACK, /**< Loopback in the external line (beyond the PHY) */ -+ e_DIAG_MODE_CTRL_ECHO, /**< Echo incoming data by the controller */ -+ e_DIAG_MODE_PHY_ECHO /**< Echo incoming data by the PHY */ -+} e_DiagMode; -+ -+/**************************************************************************//** -+ @Description Possible RxStore callback responses. -+*//***************************************************************************/ -+typedef enum e_RxStoreResponse -+{ -+ e_RX_STORE_RESPONSE_PAUSE /**< Pause invoking callback with received data; -+ in polling mode, start again invoking callback -+ only next time user invokes the receive routine; -+ in interrupt mode, start again invoking callback -+ only next time a receive event triggers an interrupt; -+ in all cases, received data that are pending are not -+ lost, rather, their processing is temporarily deferred; -+ in all cases, received data are processed in the order -+ in which they were received. */ -+ , e_RX_STORE_RESPONSE_CONTINUE /**< Continue invoking callback with received data. */ -+} e_RxStoreResponse; -+ -+ -+/**************************************************************************//** -+ @Description General Handle -+*//***************************************************************************/ -+typedef void * t_Handle; /**< handle, used as object's descriptor */ -+ -+/**************************************************************************//** -+ @Description MUTEX type -+*//***************************************************************************/ -+typedef uint32_t t_Mutex; -+ -+/**************************************************************************//** -+ @Description Error Code. -+ -+ The high word of the error code is the code of the software -+ module (driver). The low word is the error type (e_ErrorType). -+ To get the values from the error code, use GET_ERROR_TYPE() -+ and GET_ERROR_MODULE(). -+*//***************************************************************************/ -+typedef uint32_t t_Error; -+ -+/**************************************************************************//** -+ @Description General prototype of interrupt service routine (ISR). -+ -+ @Param[in] handle - Optional handle of the module handling the interrupt. -+ -+ @Return None -+ *//***************************************************************************/ -+typedef void (t_Isr)(t_Handle handle); -+ -+/**************************************************************************//** -+ @Anchor mem_attr -+ -+ @Collection Memory Attributes -+ -+ Various attributes of memory partitions. These values may be -+ or'ed together to create a mask of all memory attributes. -+ @{ -+*//***************************************************************************/ -+#define MEMORY_ATTR_CACHEABLE 0x00000001 -+ /**< Memory is cacheable */ -+#define MEMORY_ATTR_QE_2ND_BUS_ACCESS 0x00000002 -+ /**< Memory can be accessed by QUICC Engine -+ through its secondary bus interface */ -+ -+/* @} */ -+ -+ -+/**************************************************************************//** -+ @Function t_GetBufFunction -+ -+ @Description User callback function called by driver to get data buffer. -+ -+ User provides this function. Driver invokes it. -+ -+ @Param[in] h_BufferPool - A handle to buffer pool manager -+ @Param[out] p_BufContextHandle - Returns the user's private context that -+ should be associated with the buffer -+ -+ @Return Pointer to data buffer, NULL if error -+ *//***************************************************************************/ -+typedef uint8_t * (t_GetBufFunction)(t_Handle h_BufferPool, -+ t_Handle *p_BufContextHandle); -+ -+/**************************************************************************//** -+ @Function t_PutBufFunction -+ -+ @Description User callback function called by driver to return data buffer. -+ -+ User provides this function. Driver invokes it. -+ -+ @Param[in] h_BufferPool - A handle to buffer pool manager -+ @Param[in] p_Buffer - A pointer to buffer to return -+ @Param[in] h_BufContext - The user's private context associated with -+ the returned buffer -+ -+ @Return E_OK on success; Error code otherwise -+ *//***************************************************************************/ -+typedef t_Error (t_PutBufFunction)(t_Handle h_BufferPool, -+ uint8_t *p_Buffer, -+ t_Handle h_BufContext); -+ -+/**************************************************************************//** -+ @Function t_PhysToVirt -+ -+ @Description Translates a physical address to the matching virtual address. -+ -+ @Param[in] addr - The physical address to translate. -+ -+ @Return Virtual address. -+*//***************************************************************************/ -+typedef void * t_PhysToVirt(physAddress_t addr); -+ -+/**************************************************************************//** -+ @Function t_VirtToPhys -+ -+ @Description Translates a virtual address to the matching physical address. -+ -+ @Param[in] addr - The virtual address to translate. -+ -+ @Return Physical address. -+*//***************************************************************************/ -+typedef physAddress_t t_VirtToPhys(void *addr); -+ -+/**************************************************************************//** -+ @Description Buffer Pool Information Structure. -+*//***************************************************************************/ -+typedef struct t_BufferPoolInfo -+{ -+ t_Handle h_BufferPool; /**< A handle to the buffer pool manager */ -+ t_GetBufFunction *f_GetBuf; /**< User callback to get a free buffer */ -+ t_PutBufFunction *f_PutBuf; /**< User callback to return a buffer */ -+ uint16_t bufferSize; /**< Buffer size (in bytes) */ -+ -+ t_PhysToVirt *f_PhysToVirt; /**< User callback to translate pool buffers -+ physical addresses to virtual addresses */ -+ t_VirtToPhys *f_VirtToPhys; /**< User callback to translate pool buffers -+ virtual addresses to physical addresses */ -+} t_BufferPoolInfo; -+ -+ -+/**************************************************************************//** -+ @Description User callback function called by driver when transmit completed. -+ -+ User provides this function. Driver invokes it. -+ -+ @Param[in] h_App - Application's handle, as was provided to the -+ driver by the user -+ @Param[in] queueId - Transmit queue ID -+ @Param[in] p_Data - Pointer to the data buffer -+ @Param[in] h_BufContext - The user's private context associated with -+ the given data buffer -+ @Param[in] status - Transmit status and errors -+ @Param[in] flags - Driver-dependent information -+ *//***************************************************************************/ -+typedef void (t_TxConfFunction)(t_Handle h_App, -+ uint32_t queueId, -+ uint8_t *p_Data, -+ t_Handle h_BufContext, -+ uint16_t status, -+ uint32_t flags); -+ -+/**************************************************************************//** -+ @Description User callback function called by driver with receive data. -+ -+ User provides this function. Driver invokes it. -+ -+ @Param[in] h_App - Application's handle, as was provided to the -+ driver by the user -+ @Param[in] queueId - Receive queue ID -+ @Param[in] p_Data - Pointer to the buffer with received data -+ @Param[in] h_BufContext - The user's private context associated with -+ the given data buffer -+ @Param[in] length - Length of received data -+ @Param[in] status - Receive status and errors -+ @Param[in] position - Position of buffer in frame -+ @Param[in] flags - Driver-dependent information -+ -+ @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx -+ operation for all ready data. -+ @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation. -+ *//***************************************************************************/ -+typedef e_RxStoreResponse (t_RxStoreFunction)(t_Handle h_App, -+ uint32_t queueId, -+ uint8_t *p_Data, -+ t_Handle h_BufContext, -+ uint32_t length, -+ uint16_t status, -+ uint8_t position, -+ uint32_t flags); -+ -+ -+#endif /* __NCSW_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h -@@ -0,0 +1,430 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File net_ext.h -+ -+ @Description This file contains common and general netcomm headers definitions. -+*//***************************************************************************/ -+#ifndef __NET_EXT_H -+#define __NET_EXT_H -+ -+#include "std_ext.h" -+ -+ -+typedef uint8_t headerFieldPpp_t; -+ -+#define NET_HEADER_FIELD_PPP_PID (1) -+#define NET_HEADER_FIELD_PPP_COMPRESSED (NET_HEADER_FIELD_PPP_PID << 1) -+#define NET_HEADER_FIELD_PPP_ALL_FIELDS ((NET_HEADER_FIELD_PPP_PID << 2) - 1) -+ -+ -+typedef uint8_t headerFieldPppoe_t; -+ -+#define NET_HEADER_FIELD_PPPoE_VER (1) -+#define NET_HEADER_FIELD_PPPoE_TYPE (NET_HEADER_FIELD_PPPoE_VER << 1) -+#define NET_HEADER_FIELD_PPPoE_CODE (NET_HEADER_FIELD_PPPoE_VER << 2) -+#define NET_HEADER_FIELD_PPPoE_SID (NET_HEADER_FIELD_PPPoE_VER << 3) -+#define NET_HEADER_FIELD_PPPoE_LEN (NET_HEADER_FIELD_PPPoE_VER << 4) -+#define NET_HEADER_FIELD_PPPoE_SESSION (NET_HEADER_FIELD_PPPoE_VER << 5) -+#define NET_HEADER_FIELD_PPPoE_PID (NET_HEADER_FIELD_PPPoE_VER << 6) -+#define NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((NET_HEADER_FIELD_PPPoE_VER << 7) - 1) -+ -+#define NET_HEADER_FIELD_PPPMUX_PID (1) -+#define NET_HEADER_FIELD_PPPMUX_CKSUM (NET_HEADER_FIELD_PPPMUX_PID << 1) -+#define NET_HEADER_FIELD_PPPMUX_COMPRESSED (NET_HEADER_FIELD_PPPMUX_PID << 2) -+#define NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_PID << 3) - 1) -+ -+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1) -+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1) -+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2) -+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3) -+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4) -+#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1) -+ -+ -+typedef uint8_t headerFieldEth_t; -+ -+#define NET_HEADER_FIELD_ETH_DA (1) -+#define NET_HEADER_FIELD_ETH_SA (NET_HEADER_FIELD_ETH_DA << 1) -+#define NET_HEADER_FIELD_ETH_LENGTH (NET_HEADER_FIELD_ETH_DA << 2) -+#define NET_HEADER_FIELD_ETH_TYPE (NET_HEADER_FIELD_ETH_DA << 3) -+#define NET_HEADER_FIELD_ETH_FINAL_CKSUM (NET_HEADER_FIELD_ETH_DA << 4) -+#define NET_HEADER_FIELD_ETH_PADDING (NET_HEADER_FIELD_ETH_DA << 5) -+#define NET_HEADER_FIELD_ETH_ALL_FIELDS ((NET_HEADER_FIELD_ETH_DA << 6) - 1) -+ -+#define NET_HEADER_FIELD_ETH_ADDR_SIZE 6 -+ -+typedef uint16_t headerFieldIp_t; -+ -+#define NET_HEADER_FIELD_IP_VER (1) -+#define NET_HEADER_FIELD_IP_DSCP (NET_HEADER_FIELD_IP_VER << 2) -+#define NET_HEADER_FIELD_IP_ECN (NET_HEADER_FIELD_IP_VER << 3) -+#define NET_HEADER_FIELD_IP_PROTO (NET_HEADER_FIELD_IP_VER << 4) -+ -+#define NET_HEADER_FIELD_IP_PROTO_SIZE 1 -+ -+typedef uint16_t headerFieldIpv4_t; -+ -+#define NET_HEADER_FIELD_IPv4_VER (1) -+#define NET_HEADER_FIELD_IPv4_HDR_LEN (NET_HEADER_FIELD_IPv4_VER << 1) -+#define NET_HEADER_FIELD_IPv4_TOS (NET_HEADER_FIELD_IPv4_VER << 2) -+#define NET_HEADER_FIELD_IPv4_TOTAL_LEN (NET_HEADER_FIELD_IPv4_VER << 3) -+#define NET_HEADER_FIELD_IPv4_ID (NET_HEADER_FIELD_IPv4_VER << 4) -+#define NET_HEADER_FIELD_IPv4_FLAG_D (NET_HEADER_FIELD_IPv4_VER << 5) -+#define NET_HEADER_FIELD_IPv4_FLAG_M (NET_HEADER_FIELD_IPv4_VER << 6) -+#define NET_HEADER_FIELD_IPv4_OFFSET (NET_HEADER_FIELD_IPv4_VER << 7) -+#define NET_HEADER_FIELD_IPv4_TTL (NET_HEADER_FIELD_IPv4_VER << 8) -+#define NET_HEADER_FIELD_IPv4_PROTO (NET_HEADER_FIELD_IPv4_VER << 9) -+#define NET_HEADER_FIELD_IPv4_CKSUM (NET_HEADER_FIELD_IPv4_VER << 10) -+#define NET_HEADER_FIELD_IPv4_SRC_IP (NET_HEADER_FIELD_IPv4_VER << 11) -+#define NET_HEADER_FIELD_IPv4_DST_IP (NET_HEADER_FIELD_IPv4_VER << 12) -+#define NET_HEADER_FIELD_IPv4_OPTS (NET_HEADER_FIELD_IPv4_VER << 13) -+#define NET_HEADER_FIELD_IPv4_OPTS_COUNT (NET_HEADER_FIELD_IPv4_VER << 14) -+#define NET_HEADER_FIELD_IPv4_ALL_FIELDS ((NET_HEADER_FIELD_IPv4_VER << 15) - 1) -+ -+#define NET_HEADER_FIELD_IPv4_ADDR_SIZE 4 -+#define NET_HEADER_FIELD_IPv4_PROTO_SIZE 1 -+ -+ -+typedef uint8_t headerFieldIpv6_t; -+ -+#define NET_HEADER_FIELD_IPv6_VER (1) -+#define NET_HEADER_FIELD_IPv6_TC (NET_HEADER_FIELD_IPv6_VER << 1) -+#define NET_HEADER_FIELD_IPv6_SRC_IP (NET_HEADER_FIELD_IPv6_VER << 2) -+#define NET_HEADER_FIELD_IPv6_DST_IP (NET_HEADER_FIELD_IPv6_VER << 3) -+#define NET_HEADER_FIELD_IPv6_NEXT_HDR (NET_HEADER_FIELD_IPv6_VER << 4) -+#define NET_HEADER_FIELD_IPv6_FL (NET_HEADER_FIELD_IPv6_VER << 5) -+#define NET_HEADER_FIELD_IPv6_HOP_LIMIT (NET_HEADER_FIELD_IPv6_VER << 6) -+#define NET_HEADER_FIELD_IPv6_ALL_FIELDS ((NET_HEADER_FIELD_IPv6_VER << 7) - 1) -+ -+#define NET_HEADER_FIELD_IPv6_ADDR_SIZE 16 -+#define NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1 -+ -+#define NET_HEADER_FIELD_ICMP_TYPE (1) -+#define NET_HEADER_FIELD_ICMP_CODE (NET_HEADER_FIELD_ICMP_TYPE << 1) -+#define NET_HEADER_FIELD_ICMP_CKSUM (NET_HEADER_FIELD_ICMP_TYPE << 2) -+#define NET_HEADER_FIELD_ICMP_ID (NET_HEADER_FIELD_ICMP_TYPE << 3) -+#define NET_HEADER_FIELD_ICMP_SQ_NUM (NET_HEADER_FIELD_ICMP_TYPE << 4) -+#define NET_HEADER_FIELD_ICMP_ALL_FIELDS ((NET_HEADER_FIELD_ICMP_TYPE << 5) - 1) -+ -+#define NET_HEADER_FIELD_ICMP_CODE_SIZE 1 -+#define NET_HEADER_FIELD_ICMP_TYPE_SIZE 1 -+ -+#define NET_HEADER_FIELD_IGMP_VERSION (1) -+#define NET_HEADER_FIELD_IGMP_TYPE (NET_HEADER_FIELD_IGMP_VERSION << 1) -+#define NET_HEADER_FIELD_IGMP_CKSUM (NET_HEADER_FIELD_IGMP_VERSION << 2) -+#define NET_HEADER_FIELD_IGMP_DATA (NET_HEADER_FIELD_IGMP_VERSION << 3) -+#define NET_HEADER_FIELD_IGMP_ALL_FIELDS ((NET_HEADER_FIELD_IGMP_VERSION << 4) - 1) -+ -+ -+typedef uint16_t headerFieldTcp_t; -+ -+#define NET_HEADER_FIELD_TCP_PORT_SRC (1) -+#define NET_HEADER_FIELD_TCP_PORT_DST (NET_HEADER_FIELD_TCP_PORT_SRC << 1) -+#define NET_HEADER_FIELD_TCP_SEQ (NET_HEADER_FIELD_TCP_PORT_SRC << 2) -+#define NET_HEADER_FIELD_TCP_ACK (NET_HEADER_FIELD_TCP_PORT_SRC << 3) -+#define NET_HEADER_FIELD_TCP_OFFSET (NET_HEADER_FIELD_TCP_PORT_SRC << 4) -+#define NET_HEADER_FIELD_TCP_FLAGS (NET_HEADER_FIELD_TCP_PORT_SRC << 5) -+#define NET_HEADER_FIELD_TCP_WINDOW (NET_HEADER_FIELD_TCP_PORT_SRC << 6) -+#define NET_HEADER_FIELD_TCP_CKSUM (NET_HEADER_FIELD_TCP_PORT_SRC << 7) -+#define NET_HEADER_FIELD_TCP_URGPTR (NET_HEADER_FIELD_TCP_PORT_SRC << 8) -+#define NET_HEADER_FIELD_TCP_OPTS (NET_HEADER_FIELD_TCP_PORT_SRC << 9) -+#define NET_HEADER_FIELD_TCP_OPTS_COUNT (NET_HEADER_FIELD_TCP_PORT_SRC << 10) -+#define NET_HEADER_FIELD_TCP_ALL_FIELDS ((NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1) -+ -+#define NET_HEADER_FIELD_TCP_PORT_SIZE 2 -+ -+ -+typedef uint8_t headerFieldSctp_t; -+ -+#define NET_HEADER_FIELD_SCTP_PORT_SRC (1) -+#define NET_HEADER_FIELD_SCTP_PORT_DST (NET_HEADER_FIELD_SCTP_PORT_SRC << 1) -+#define NET_HEADER_FIELD_SCTP_VER_TAG (NET_HEADER_FIELD_SCTP_PORT_SRC << 2) -+#define NET_HEADER_FIELD_SCTP_CKSUM (NET_HEADER_FIELD_SCTP_PORT_SRC << 3) -+#define NET_HEADER_FIELD_SCTP_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1) -+ -+#define NET_HEADER_FIELD_SCTP_PORT_SIZE 2 -+ -+typedef uint8_t headerFieldDccp_t; -+ -+#define NET_HEADER_FIELD_DCCP_PORT_SRC (1) -+#define NET_HEADER_FIELD_DCCP_PORT_DST (NET_HEADER_FIELD_DCCP_PORT_SRC << 1) -+#define NET_HEADER_FIELD_DCCP_ALL_FIELDS ((NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1) -+ -+#define NET_HEADER_FIELD_DCCP_PORT_SIZE 2 -+ -+ -+typedef uint8_t headerFieldUdp_t; -+ -+#define NET_HEADER_FIELD_UDP_PORT_SRC (1) -+#define NET_HEADER_FIELD_UDP_PORT_DST (NET_HEADER_FIELD_UDP_PORT_SRC << 1) -+#define NET_HEADER_FIELD_UDP_LEN (NET_HEADER_FIELD_UDP_PORT_SRC << 2) -+#define NET_HEADER_FIELD_UDP_CKSUM (NET_HEADER_FIELD_UDP_PORT_SRC << 3) -+#define NET_HEADER_FIELD_UDP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1) -+ -+#define NET_HEADER_FIELD_UDP_PORT_SIZE 2 -+ -+typedef uint8_t headerFieldUdpLite_t; -+ -+#define NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1) -+#define NET_HEADER_FIELD_UDP_LITE_PORT_DST (NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1) -+#define NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1) -+ -+#define NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2 -+ -+typedef uint8_t headerFieldUdpEncapEsp_t; -+ -+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1) -+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1) -+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2) -+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3) -+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4) -+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5) -+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1) -+ -+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2 -+#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4 -+ -+#define NET_HEADER_FIELD_IPHC_CID (1) -+#define NET_HEADER_FIELD_IPHC_CID_TYPE (NET_HEADER_FIELD_IPHC_CID << 1) -+#define NET_HEADER_FIELD_IPHC_HCINDEX (NET_HEADER_FIELD_IPHC_CID << 2) -+#define NET_HEADER_FIELD_IPHC_GEN (NET_HEADER_FIELD_IPHC_CID << 3) -+#define NET_HEADER_FIELD_IPHC_D_BIT (NET_HEADER_FIELD_IPHC_CID << 4) -+#define NET_HEADER_FIELD_IPHC_ALL_FIELDS ((NET_HEADER_FIELD_IPHC_CID << 5) - 1) -+ -+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1) -+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1) -+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2) -+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3) -+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4) -+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5) -+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6) -+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7) -+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8) -+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9) -+#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1) -+ -+#define NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1) -+#define NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1) -+#define NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2) -+#define NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3) -+#define NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4) -+#define NET_HEADER_FIELD_L2TPv2_VERSION (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5) -+#define NET_HEADER_FIELD_L2TPv2_LEN (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6) -+#define NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7) -+#define NET_HEADER_FIELD_L2TPv2_SESSION_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8) -+#define NET_HEADER_FIELD_L2TPv2_NS (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9) -+#define NET_HEADER_FIELD_L2TPv2_NR (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10) -+#define NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11) -+#define NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12) -+#define NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1) -+ -+#define NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1) -+#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1) -+#define NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2) -+#define NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3) -+#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4) -+#define NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5) -+#define NET_HEADER_FIELD_L2TPv3_CTRL_SENT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6) -+#define NET_HEADER_FIELD_L2TPv3_CTRL_RECV (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7) -+#define NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8) -+#define NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1) -+ -+#define NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1) -+#define NET_HEADER_FIELD_L2TPv3_SESS_VERSION (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1) -+#define NET_HEADER_FIELD_L2TPv3_SESS_ID (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2) -+#define NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3) -+#define NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1) -+ -+ -+typedef uint8_t headerFieldVlan_t; -+ -+#define NET_HEADER_FIELD_VLAN_VPRI (1) -+#define NET_HEADER_FIELD_VLAN_CFI (NET_HEADER_FIELD_VLAN_VPRI << 1) -+#define NET_HEADER_FIELD_VLAN_VID (NET_HEADER_FIELD_VLAN_VPRI << 2) -+#define NET_HEADER_FIELD_VLAN_LENGTH (NET_HEADER_FIELD_VLAN_VPRI << 3) -+#define NET_HEADER_FIELD_VLAN_TYPE (NET_HEADER_FIELD_VLAN_VPRI << 4) -+#define NET_HEADER_FIELD_VLAN_ALL_FIELDS ((NET_HEADER_FIELD_VLAN_VPRI << 5) - 1) -+ -+#define NET_HEADER_FIELD_VLAN_TCI (NET_HEADER_FIELD_VLAN_VPRI | \ -+ NET_HEADER_FIELD_VLAN_CFI | \ -+ NET_HEADER_FIELD_VLAN_VID) -+ -+ -+typedef uint8_t headerFieldLlc_t; -+ -+#define NET_HEADER_FIELD_LLC_DSAP (1) -+#define NET_HEADER_FIELD_LLC_SSAP (NET_HEADER_FIELD_LLC_DSAP << 1) -+#define NET_HEADER_FIELD_LLC_CTRL (NET_HEADER_FIELD_LLC_DSAP << 2) -+#define NET_HEADER_FIELD_LLC_ALL_FIELDS ((NET_HEADER_FIELD_LLC_DSAP << 3) - 1) -+ -+#define NET_HEADER_FIELD_NLPID_NLPID (1) -+#define NET_HEADER_FIELD_NLPID_ALL_FIELDS ((NET_HEADER_FIELD_NLPID_NLPID << 1) - 1) -+ -+ -+typedef uint8_t headerFieldSnap_t; -+ -+#define NET_HEADER_FIELD_SNAP_OUI (1) -+#define NET_HEADER_FIELD_SNAP_PID (NET_HEADER_FIELD_SNAP_OUI << 1) -+#define NET_HEADER_FIELD_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_SNAP_OUI << 2) - 1) -+ -+ -+typedef uint8_t headerFieldLlcSnap_t; -+ -+#define NET_HEADER_FIELD_LLC_SNAP_TYPE (1) -+#define NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1) -+ -+#define NET_HEADER_FIELD_ARP_HTYPE (1) -+#define NET_HEADER_FIELD_ARP_PTYPE (NET_HEADER_FIELD_ARP_HTYPE << 1) -+#define NET_HEADER_FIELD_ARP_HLEN (NET_HEADER_FIELD_ARP_HTYPE << 2) -+#define NET_HEADER_FIELD_ARP_PLEN (NET_HEADER_FIELD_ARP_HTYPE << 3) -+#define NET_HEADER_FIELD_ARP_OPER (NET_HEADER_FIELD_ARP_HTYPE << 4) -+#define NET_HEADER_FIELD_ARP_SHA (NET_HEADER_FIELD_ARP_HTYPE << 5) -+#define NET_HEADER_FIELD_ARP_SPA (NET_HEADER_FIELD_ARP_HTYPE << 6) -+#define NET_HEADER_FIELD_ARP_THA (NET_HEADER_FIELD_ARP_HTYPE << 7) -+#define NET_HEADER_FIELD_ARP_TPA (NET_HEADER_FIELD_ARP_HTYPE << 8) -+#define NET_HEADER_FIELD_ARP_ALL_FIELDS ((NET_HEADER_FIELD_ARP_HTYPE << 9) - 1) -+ -+#define NET_HEADER_FIELD_RFC2684_LLC (1) -+#define NET_HEADER_FIELD_RFC2684_NLPID (NET_HEADER_FIELD_RFC2684_LLC << 1) -+#define NET_HEADER_FIELD_RFC2684_OUI (NET_HEADER_FIELD_RFC2684_LLC << 2) -+#define NET_HEADER_FIELD_RFC2684_PID (NET_HEADER_FIELD_RFC2684_LLC << 3) -+#define NET_HEADER_FIELD_RFC2684_VPN_OUI (NET_HEADER_FIELD_RFC2684_LLC << 4) -+#define NET_HEADER_FIELD_RFC2684_VPN_IDX (NET_HEADER_FIELD_RFC2684_LLC << 5) -+#define NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((NET_HEADER_FIELD_RFC2684_LLC << 6) - 1) -+ -+#define NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1) -+#define NET_HEADER_FIELD_USER_DEFINED_PCDID (NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1) -+#define NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1) -+ -+#define NET_HEADER_FIELD_PAYLOAD_BUFFER (1) -+#define NET_HEADER_FIELD_PAYLOAD_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 1) -+#define NET_HEADER_FIELD_MAX_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 2) -+#define NET_HEADER_FIELD_MIN_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 3) -+#define NET_HEADER_FIELD_PAYLOAD_TYPE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 4) -+#define NET_HEADER_FIELD_FRAME_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 5) -+#define NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1) -+ -+ -+typedef uint8_t headerFieldGre_t; -+ -+#define NET_HEADER_FIELD_GRE_TYPE (1) -+#define NET_HEADER_FIELD_GRE_ALL_FIELDS ((NET_HEADER_FIELD_GRE_TYPE << 1) - 1) -+ -+ -+typedef uint8_t headerFieldMinencap_t; -+ -+#define NET_HEADER_FIELD_MINENCAP_SRC_IP (1) -+#define NET_HEADER_FIELD_MINENCAP_DST_IP (NET_HEADER_FIELD_MINENCAP_SRC_IP << 1) -+#define NET_HEADER_FIELD_MINENCAP_TYPE (NET_HEADER_FIELD_MINENCAP_SRC_IP << 2) -+#define NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1) -+ -+ -+typedef uint8_t headerFieldIpsecAh_t; -+ -+#define NET_HEADER_FIELD_IPSEC_AH_SPI (1) -+#define NET_HEADER_FIELD_IPSEC_AH_NH (NET_HEADER_FIELD_IPSEC_AH_SPI << 1) -+#define NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1) -+ -+ -+typedef uint8_t headerFieldIpsecEsp_t; -+ -+#define NET_HEADER_FIELD_IPSEC_ESP_SPI (1) -+#define NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_IPSEC_ESP_SPI << 1) -+#define NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1) -+ -+#define NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4 -+ -+ -+typedef uint8_t headerFieldMpls_t; -+ -+#define NET_HEADER_FIELD_MPLS_LABEL_STACK (1) -+#define NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1) -+ -+ -+typedef uint8_t headerFieldMacsec_t; -+ -+#define NET_HEADER_FIELD_MACSEC_SECTAG (1) -+#define NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1) -+ -+ -+typedef enum { -+ HEADER_TYPE_NONE = 0, -+ HEADER_TYPE_PAYLOAD, -+ HEADER_TYPE_ETH, -+ HEADER_TYPE_VLAN, -+ HEADER_TYPE_IPv4, -+ HEADER_TYPE_IPv6, -+ HEADER_TYPE_IP, -+ HEADER_TYPE_TCP, -+ HEADER_TYPE_UDP, -+ HEADER_TYPE_UDP_LITE, -+ HEADER_TYPE_IPHC, -+ HEADER_TYPE_SCTP, -+ HEADER_TYPE_SCTP_CHUNK_DATA, -+ HEADER_TYPE_PPPoE, -+ HEADER_TYPE_PPP, -+ HEADER_TYPE_PPPMUX, -+ HEADER_TYPE_PPPMUX_SUBFRAME, -+ HEADER_TYPE_L2TPv2, -+ HEADER_TYPE_L2TPv3_CTRL, -+ HEADER_TYPE_L2TPv3_SESS, -+ HEADER_TYPE_LLC, -+ HEADER_TYPE_LLC_SNAP, -+ HEADER_TYPE_NLPID, -+ HEADER_TYPE_SNAP, -+ HEADER_TYPE_MPLS, -+ HEADER_TYPE_IPSEC_AH, -+ HEADER_TYPE_IPSEC_ESP, -+ HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */ -+ HEADER_TYPE_MACSEC, -+ HEADER_TYPE_GRE, -+ HEADER_TYPE_MINENCAP, -+ HEADER_TYPE_DCCP, -+ HEADER_TYPE_ICMP, -+ HEADER_TYPE_IGMP, -+ HEADER_TYPE_ARP, -+ HEADER_TYPE_CAPWAP, -+ HEADER_TYPE_CAPWAP_DTLS, -+ HEADER_TYPE_RFC2684, -+ HEADER_TYPE_USER_DEFINED_L2, -+ HEADER_TYPE_USER_DEFINED_L3, -+ HEADER_TYPE_USER_DEFINED_L4, -+ HEADER_TYPE_USER_DEFINED_SHIM1, -+ HEADER_TYPE_USER_DEFINED_SHIM2, -+ MAX_HEADER_TYPE_COUNT -+} e_NetHeaderType; -+ -+ -+#endif /* __NET_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h -@@ -0,0 +1,48 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File std_ext.h -+ -+ @Description General Standard Definitions -+*//***************************************************************************/ -+ -+#ifndef __STD_EXT_H -+#define __STD_EXT_H -+ -+ -+#include "types_ext.h" -+#include "ncsw_ext.h" -+ -+ -+#endif /* __STD_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h -@@ -0,0 +1,49 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#ifndef __STDARG_EXT_H -+#define __STDARG_EXT_H -+ -+ -+#if defined(NCSW_LINUX) && defined(__KERNEL__) -+#include -+ -+#else -+#include -+ -+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */ -+ -+#include "std_ext.h" -+ -+ -+#endif /* __STDARG_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h -@@ -0,0 +1,162 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+ -+#ifndef __STDLIB_EXT_H -+#define __STDLIB_EXT_H -+ -+ -+#if (defined(NCSW_LINUX)) && defined(__KERNEL__) -+#include "stdarg_ext.h" -+#include "std_ext.h" -+ -+ -+/** -+ * strtoul - convert a string to an uint32_t -+ * @cp: The start of the string -+ * @endp: A pointer to the end of the parsed string will be placed here -+ * @base: The number base to use -+ */ -+uint32_t strtoul(const char *cp,char **endp,uint32_t base); -+ -+/** -+ * strtol - convert a string to a int32_t -+ * @cp: The start of the string -+ * @endp: A pointer to the end of the parsed string will be placed here -+ * @base: The number base to use -+ */ -+long strtol(const char *cp,char **endp,uint32_t base); -+ -+/** -+ * strtoull - convert a string to an uint64_t -+ * @cp: The start of the string -+ * @endp: A pointer to the end of the parsed string will be placed here -+ * @base: The number base to use -+ */ -+uint64_t strtoull(const char *cp,char **endp,uint32_t base); -+ -+/** -+ * strtoll - convert a string to a int64 long -+ * @cp: The start of the string -+ * @endp: A pointer to the end of the parsed string will be placed here -+ * @base: The number base to use -+ */ -+long long strtoll(const char *cp,char **endp,uint32_t base); -+ -+/** -+ * atoi - convert a character to a int -+ * @s: The start of the string -+ */ -+int atoi(const char *s); -+ -+/** -+ * strnlen - Find the length of a length-limited string -+ * @s: The string to be sized -+ * @count: The maximum number of bytes to search -+ */ -+size_t strnlen(const char * s, size_t count); -+ -+/** -+ * strlen - Find the length of a string -+ * @s: The string to be sized -+ */ -+size_t strlen(const char * s); -+ -+/** -+ * strtok - Split a string into tokens -+ * @s: The string to be searched -+ * @ct: The characters to search for -+ * -+ * WARNING: strtok is deprecated, use strsep instead. -+ */ -+char * strtok(char * s,const char * ct); -+ -+/** -+ * strncpy - Copy a length-limited, %NUL-terminated string -+ * @dest: Where to copy the string to -+ * @src: Where to copy the string from -+ * @count: The maximum number of bytes to copy -+ * -+ * Note that unlike userspace strncpy, this does not %NUL-pad the buffer. -+ * However, the result is not %NUL-terminated if the source exceeds -+ * @count bytes. -+ */ -+char * strncpy(char * dest,const char *src,size_t count); -+ -+/** -+ * strcpy - Copy a %NUL terminated string -+ * @dest: Where to copy the string to -+ * @src: Where to copy the string from -+ */ -+char * strcpy(char * dest,const char *src); -+ -+/** -+ * vsscanf - Unformat a buffer into a list of arguments -+ * @buf: input buffer -+ * @fmt: format of buffer -+ * @args: arguments -+ */ -+int vsscanf(const char * buf, const char * fmt, va_list args); -+ -+/** -+ * vsnprintf - Format a string and place it in a buffer -+ * @buf: The buffer to place the result into -+ * @size: The size of the buffer, including the trailing null space -+ * @fmt: The format string to use -+ * @args: Arguments for the format string -+ * -+ * Call this function if you are already dealing with a va_list. -+ * You probably want snprintf instead. -+ */ -+int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); -+ -+/** -+ * vsprintf - Format a string and place it in a buffer -+ * @buf: The buffer to place the result into -+ * @fmt: The format string to use -+ * @args: Arguments for the format string -+ * -+ * Call this function if you are already dealing with a va_list. -+ * You probably want sprintf instead. -+ */ -+int vsprintf(char *buf, const char *fmt, va_list args); -+ -+#else -+#include -+#include -+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */ -+ -+#include "std_ext.h" -+ -+ -+#endif /* __STDLIB_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h -@@ -0,0 +1,56 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#ifndef __STRING_EXT_H -+#define __STRING_EXT_H -+ -+ -+#if defined(NCSW_LINUX) && defined(__KERNEL__) -+#include -+#include -+extern char * strtok ( char * str, const char * delimiters ); -+ -+#elif defined(__KERNEL__) -+#include "linux/types.h" -+#include "linux/posix_types.h" -+#include "linux/string.h" -+ -+#else -+#include -+ -+#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */ -+ -+#include "std_ext.h" -+ -+ -+#endif /* __STRING_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h -@@ -0,0 +1,62 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File types_ext.h -+ -+ @Description General types Standard Definitions -+*//***************************************************************************/ -+ -+#ifndef __TYPES_EXT_H -+#define __TYPES_EXT_H -+ -+#if defined(NCSW_LINUX) -+#include "types_linux.h" -+ -+#elif defined(NCSW_VXWORKS) -+#include "types_vxworks.h" -+ -+#elif defined(__GNUC__) && defined(__cplusplus) -+#include "types_bb_gpp.h" -+ -+#elif defined(__GNUC__) -+#include "types_bb_gcc.h" -+ -+#elif defined(__ghs__) -+#include "types_ghs.h" -+ -+#else -+#include "types_dflt.h" -+#endif /* defined (__ROCOO__) */ -+ -+#endif /* __TYPES_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h -@@ -0,0 +1,56 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File debug_ext.h -+ -+ @Description Debug mode definitions. -+*//***************************************************************************/ -+ -+#ifndef __XX_COMMON_H -+#define __XX_COMMON_H -+ -+/***************************************************************************** -+ * UNIFIED MODULE CODES -+ *****************************************************************************/ -+#define MODULE_UNKNOWN 0x00000000 -+#define MODULE_FM 0x00010000 -+#define MODULE_FM_MURAM 0x00020000 -+#define MODULE_FM_PCD 0x00030000 -+#define MODULE_FM_RTC 0x00040000 -+#define MODULE_FM_MAC 0x00050000 -+#define MODULE_FM_PORT 0x00060000 -+#define MODULE_MM 0x00070000 -+#define MODULE_FM_SP 0x00080000 -+#define MODULE_FM_MACSEC 0x00090000 -+#endif /* __XX_COMMON_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h -@@ -0,0 +1,791 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File xx_ext.h -+ -+ @Description Prototypes, externals and typedefs for system-supplied -+ (external) routines -+*//***************************************************************************/ -+ -+#ifndef __XX_EXT_H -+#define __XX_EXT_H -+ -+#include "std_ext.h" -+#include "xx_common.h" -+#include "part_ext.h" -+ -+ -+ -+/**************************************************************************//** -+ @Group xx_id XX Interface (System call hooks) -+ -+ @Description Prototypes, externals and typedefs for system-supplied -+ (external) routines -+ -+ @{ -+*//***************************************************************************/ -+ -+#ifdef DEBUG_XX_MALLOC -+void * XX_MallocDebug(uint32_t size, char *fname, int line); -+ -+void * XX_MallocSmartDebug(uint32_t size, -+ int memPartitionId, -+ uint32_t alignment, -+ char *fname, -+ int line); -+ -+#define XX_Malloc(sz) \ -+ XX_MallocDebug((sz), __FILE__, __LINE__) -+ -+#define XX_MallocSmart(sz, memt, al) \ -+ XX_MallocSmartDebug((sz), (memt), (al), __FILE__, __LINE__) -+ -+#else /* not DEBUG_XX_MALLOC */ -+/**************************************************************************//** -+ @Function XX_Malloc -+ -+ @Description allocates contiguous block of memory. -+ -+ @Param[in] size - Number of bytes to allocate. -+ -+ @Return The address of the newly allocated block on success, NULL on failure. -+*//***************************************************************************/ -+void * XX_Malloc(uint32_t size); -+ -+/**************************************************************************//** -+ @Function XX_MallocSmart -+ -+ @Description Allocates contiguous block of memory in a specified -+ alignment and from the specified segment. -+ -+ @Param[in] size - Number of bytes to allocate. -+ @Param[in] memPartitionId - Memory partition ID; The value zero must -+ be mapped to the default heap partition. -+ @Param[in] alignment - Required memory alignment (in bytes). -+ -+ @Return The address of the newly allocated block on success, NULL on failure. -+*//***************************************************************************/ -+void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment); -+#endif /* not DEBUG_XX_MALLOC */ -+ -+/**************************************************************************//** -+ @Function XX_FreeSmart -+ -+ @Description Frees the memory block pointed to by "p". -+ Only for memory allocated by XX_MallocSmart -+ -+ @Param[in] p_Memory - pointer to the memory block. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_FreeSmart(void *p_Memory); -+ -+/**************************************************************************//** -+ @Function XX_Free -+ -+ @Description frees the memory block pointed to by "p". -+ -+ @Param[in] p_Memory - pointer to the memory block. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_Free(void *p_Memory); -+ -+/**************************************************************************//** -+ @Function XX_Print -+ -+ @Description print a string. -+ -+ @Param[in] str - string to print. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_Print(char *str, ...); -+ -+/**************************************************************************//** -+ @Function XX_SetIntr -+ -+ @Description Set an interrupt service routine for a specific interrupt source. -+ -+ @Param[in] irq - Interrupt ID (system-specific number). -+ @Param[in] f_Isr - Callback routine that will be called when the interrupt occurs. -+ @Param[in] handle - The argument for the user callback routine. -+ -+ @Return E_OK on success; error code otherwise.. -+*//***************************************************************************/ -+t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle); -+ -+/**************************************************************************//** -+ @Function XX_FreeIntr -+ -+ @Description Free a specific interrupt and a specific callback routine. -+ -+ @Param[in] irq - Interrupt ID (system-specific number). -+ -+ @Return E_OK on success; error code otherwise.. -+*//***************************************************************************/ -+t_Error XX_FreeIntr(int irq); -+ -+/**************************************************************************//** -+ @Function XX_EnableIntr -+ -+ @Description Enable a specific interrupt. -+ -+ @Param[in] irq - Interrupt ID (system-specific number). -+ -+ @Return E_OK on success; error code otherwise.. -+*//***************************************************************************/ -+t_Error XX_EnableIntr(int irq); -+ -+/**************************************************************************//** -+ @Function XX_DisableIntr -+ -+ @Description Disable a specific interrupt. -+ -+ @Param[in] irq - Interrupt ID (system-specific number). -+ -+ @Return E_OK on success; error code otherwise.. -+*//***************************************************************************/ -+t_Error XX_DisableIntr(int irq); -+ -+/**************************************************************************//** -+ @Function XX_DisableAllIntr -+ -+ @Description Disable all interrupts by masking them at the CPU. -+ -+ @Return A value that represents the interrupts state before the -+ operation, and should be passed to the matching -+ XX_RestoreAllIntr() call. -+*//***************************************************************************/ -+uint32_t XX_DisableAllIntr(void); -+ -+/**************************************************************************//** -+ @Function XX_RestoreAllIntr -+ -+ @Description Restore previous state of interrupts level at the CPU. -+ -+ @Param[in] flags - A value that represents the interrupts state to restore, -+ as returned by the matching call for XX_DisableAllIntr(). -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_RestoreAllIntr(uint32_t flags); -+ -+ -+/**************************************************************************//** -+ @Function XX_Exit -+ -+ @Description Stop execution and report status (where it is applicable) -+ -+ @Param[in] status - exit status -+*//***************************************************************************/ -+void XX_Exit(int status); -+ -+ -+/*****************************************************************************/ -+/* Tasklet Service Routines */ -+/*****************************************************************************/ -+typedef t_Handle t_TaskletHandle; -+ -+/**************************************************************************//** -+ @Function XX_InitTasklet -+ -+ @Description Create and initialize a tasklet object. -+ -+ @Param[in] routine - A routine to be ran as a tasklet. -+ @Param[in] data - An argument to pass to the tasklet. -+ -+ @Return Tasklet handle is returned on success. NULL is returned otherwise. -+*//***************************************************************************/ -+t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data); -+ -+/**************************************************************************//** -+ @Function XX_FreeTasklet -+ -+ @Description Free a tasklet object. -+ -+ @Param[in] h_Tasklet - A handle to a tasklet to be free. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_FreeTasklet (t_TaskletHandle h_Tasklet); -+ -+/**************************************************************************//** -+ @Function XX_ScheduleTask -+ -+ @Description Schedule a tasklet object. -+ -+ @Param[in] h_Tasklet - A handle to a tasklet to be scheduled. -+ @Param[in] immediate - Indicate whether to schedule this tasklet on -+ the immediate queue or on the delayed one. -+ -+ @Return 0 - on success. Error code - otherwise. -+*//***************************************************************************/ -+int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate); -+ -+/**************************************************************************//** -+ @Function XX_FlushScheduledTasks -+ -+ @Description Flush all tasks there are in the scheduled tasks queue. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_FlushScheduledTasks(void); -+ -+/**************************************************************************//** -+ @Function XX_TaskletIsQueued -+ -+ @Description Check if task is queued. -+ -+ @Param[in] h_Tasklet - A handle to a tasklet to be scheduled. -+ -+ @Return 1 - task is queued. 0 - otherwise. -+*//***************************************************************************/ -+int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet); -+ -+/**************************************************************************//** -+ @Function XX_SetTaskletData -+ -+ @Description Set data to a scheduled task. Used to change data of already -+ scheduled task. -+ -+ @Param[in] h_Tasklet - A handle to a tasklet to be scheduled. -+ @Param[in] data - Data to be set. -+*//***************************************************************************/ -+void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data); -+ -+/**************************************************************************//** -+ @Function XX_GetTaskletData -+ -+ @Description Get the data of scheduled task. -+ -+ @Param[in] h_Tasklet - A handle to a tasklet to be scheduled. -+ -+ @Return handle to the data of the task. -+*//***************************************************************************/ -+t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet); -+ -+/**************************************************************************//** -+ @Function XX_BottomHalf -+ -+ @Description Bottom half implementation, invoked by the interrupt handler. -+ -+ This routine handles all bottom-half tasklets with interrupts -+ enabled. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_BottomHalf(void); -+ -+ -+/*****************************************************************************/ -+/* Spinlock Service Routines */ -+/*****************************************************************************/ -+ -+/**************************************************************************//** -+ @Function XX_InitSpinlock -+ -+ @Description Creates a spinlock. -+ -+ @Return Spinlock handle is returned on success; NULL otherwise. -+*//***************************************************************************/ -+t_Handle XX_InitSpinlock(void); -+ -+/**************************************************************************//** -+ @Function XX_FreeSpinlock -+ -+ @Description Frees the memory allocated for the spinlock creation. -+ -+ @Param[in] h_Spinlock - A handle to a spinlock. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_FreeSpinlock(t_Handle h_Spinlock); -+ -+/**************************************************************************//** -+ @Function XX_LockSpinlock -+ -+ @Description Locks a spinlock. -+ -+ @Param[in] h_Spinlock - A handle to a spinlock. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_LockSpinlock(t_Handle h_Spinlock); -+ -+/**************************************************************************//** -+ @Function XX_UnlockSpinlock -+ -+ @Description Unlocks a spinlock. -+ -+ @Param[in] h_Spinlock - A handle to a spinlock. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_UnlockSpinlock(t_Handle h_Spinlock); -+ -+/**************************************************************************//** -+ @Function XX_LockIntrSpinlock -+ -+ @Description Locks a spinlock (interrupt safe). -+ -+ @Param[in] h_Spinlock - A handle to a spinlock. -+ -+ @Return A value that represents the interrupts state before the -+ operation, and should be passed to the matching -+ XX_UnlockIntrSpinlock() call. -+*//***************************************************************************/ -+uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock); -+ -+/**************************************************************************//** -+ @Function XX_UnlockIntrSpinlock -+ -+ @Description Unlocks a spinlock (interrupt safe). -+ -+ @Param[in] h_Spinlock - A handle to a spinlock. -+ @Param[in] intrFlags - A value that represents the interrupts state to -+ restore, as returned by the matching call for -+ XX_LockIntrSpinlock(). -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags); -+ -+ -+/*****************************************************************************/ -+/* Timers Service Routines */ -+/*****************************************************************************/ -+ -+/**************************************************************************//** -+ @Function XX_CurrentTime -+ -+ @Description Returns current system time. -+ -+ @Return Current system time (in milliseconds). -+*//***************************************************************************/ -+uint32_t XX_CurrentTime(void); -+ -+/**************************************************************************//** -+ @Function XX_CreateTimer -+ -+ @Description Creates a timer. -+ -+ @Return Timer handle is returned on success; NULL otherwise. -+*//***************************************************************************/ -+t_Handle XX_CreateTimer(void); -+ -+/**************************************************************************//** -+ @Function XX_FreeTimer -+ -+ @Description Frees the memory allocated for the timer creation. -+ -+ @Param[in] h_Timer - A handle to a timer. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_FreeTimer(t_Handle h_Timer); -+ -+/**************************************************************************//** -+ @Function XX_StartTimer -+ -+ @Description Starts a timer. -+ -+ The user can select to start the timer as periodic timer or as -+ one-shot timer. The user should provide a callback routine that -+ will be called when the timer expires. -+ -+ @Param[in] h_Timer - A handle to a timer. -+ @Param[in] msecs - Timer expiration period (in milliseconds). -+ @Param[in] periodic - TRUE for a periodic timer; -+ FALSE for a one-shot timer.. -+ @Param[in] f_TimerExpired - A callback routine to be called when the -+ timer expires. -+ @Param[in] h_Arg - The argument to pass in the timer-expired -+ callback routine. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_StartTimer(t_Handle h_Timer, -+ uint32_t msecs, -+ bool periodic, -+ void (*f_TimerExpired)(t_Handle h_Arg), -+ t_Handle h_Arg); -+ -+/**************************************************************************//** -+ @Function XX_StopTimer -+ -+ @Description Frees the memory allocated for the timer creation. -+ -+ @Param[in] h_Timer - A handle to a timer. -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_StopTimer(t_Handle h_Timer); -+ -+/**************************************************************************//** -+ @Function XX_ModTimer -+ -+ @Description Updates the expiration time of a timer. -+ -+ This routine adds the given time to the current system time, -+ and sets this value as the new expiration time of the timer. -+ -+ @Param[in] h_Timer - A handle to a timer. -+ @Param[in] msecs - The new interval until timer expiration -+ (in milliseconds). -+ -+ @Return None. -+*//***************************************************************************/ -+void XX_ModTimer(t_Handle h_Timer, uint32_t msecs); -+ -+/**************************************************************************//** -+ @Function XX_Sleep -+ -+ @Description Non-busy wait until the desired time (in milliseconds) has passed. -+ -+ @Param[in] msecs - The requested sleep time (in milliseconds). -+ -+ @Return Zero if the requested time has elapsed; Otherwise, the value -+ returned will be the unslept amount) in milliseconds. -+ -+ @Cautions This routine enables interrupts during its wait time. -+*//***************************************************************************/ -+uint32_t XX_Sleep(uint32_t msecs); -+ -+/**************************************************************************//** -+ @Function XX_UDelay -+ -+ @Description Busy-wait until the desired time (in microseconds) has passed. -+ -+ @Param[in] usecs - The requested delay time (in microseconds). -+ -+ @Return None. -+ -+ @Cautions It is highly unrecommended to call this routine during interrupt -+ time, because the system time may not be updated properly during -+ the delay loop. The behavior of this routine during interrupt -+ time is unexpected. -+*//***************************************************************************/ -+void XX_UDelay(uint32_t usecs); -+ -+ -+/*****************************************************************************/ -+/* Other Service Routines */ -+/*****************************************************************************/ -+ -+/**************************************************************************//** -+ @Function XX_PhysToVirt -+ -+ @Description Translates a physical address to the matching virtual address. -+ -+ @Param[in] addr - The physical address to translate. -+ -+ @Return Virtual address. -+*//***************************************************************************/ -+void * XX_PhysToVirt(physAddress_t addr); -+ -+/**************************************************************************//** -+ @Function XX_VirtToPhys -+ -+ @Description Translates a virtual address to the matching physical address. -+ -+ @Param[in] addr - The virtual address to translate. -+ -+ @Return Physical address. -+*//***************************************************************************/ -+physAddress_t XX_VirtToPhys(void *addr); -+ -+ -+/**************************************************************************//** -+ @Group xx_ipc XX Inter-Partition-Communication API -+ -+ @Description The following API is to be used when working with multiple -+ partitions configuration. -+ -+ @{ -+*//***************************************************************************/ -+ -+#define XX_IPC_MAX_ADDR_NAME_LENGTH 16 /**< Maximum length of an endpoint name string; -+ The IPC service can use this constant to limit -+ the storage space for IPC endpoint names. */ -+ -+ -+/**************************************************************************//** -+ @Function t_IpcMsgCompletion -+ -+ @Description Callback function used upon IPC non-blocking transaction completion -+ to return message buffer to the caller and to forward reply if available. -+ -+ This callback function may be attached by the source endpoint to any outgoing -+ IPC message to indicate a non-blocking send (see also XX_IpcSendMessage() routine). -+ Upon completion of an IPC transaction (consisting of a message and an optional reply), -+ the IPC service invokes this callback routine to return the message buffer to the sender -+ and to provide the received reply, if requested. -+ -+ User provides this function. Driver invokes it. -+ -+ @Param[in] h_Module - Abstract handle to the sending module - the same handle as was passed -+ in the XX_IpcSendMessage() function; This handle is typically used to point -+ to the internal data structure of the source endpoint. -+ @Param[in] p_Msg - Pointer to original (sent) message buffer; -+ The source endpoint can free (or reuse) this buffer when message -+ completion callback is called. -+ @Param[in] p_Reply - Pointer to (received) reply buffer; -+ This pointer is the same as was provided by the source endpoint in -+ XX_IpcSendMessage(). -+ @Param[in] replyLength - Length (in bytes) of actual data in the reply buffer. -+ @Param[in] status - Completion status - E_OK or failure indication, e.g. IPC transaction completion -+ timeout. -+ -+ @Return None -+ *//***************************************************************************/ -+typedef void (t_IpcMsgCompletion)(t_Handle h_Module, -+ uint8_t *p_Msg, -+ uint8_t *p_Reply, -+ uint32_t replyLength, -+ t_Error status); -+ -+/**************************************************************************//** -+ @Function t_IpcMsgHandler -+ -+ @Description Callback function used as IPC message handler. -+ -+ The IPC service invokes message handlers for each IPC message received. -+ The actual function pointer should be registered by each destination endpoint -+ via the XX_IpcRegisterMsgHandler() routine. -+ -+ User provides this function. Driver invokes it. -+ -+ @Param[in] h_Module - Abstract handle to the message handling module - the same handle as -+ was passed in the XX_IpcRegisterMsgHandler() function; this handle is -+ typically used to point to the internal data structure of the destination -+ endpoint. -+ @Param[in] p_Msg - Pointer to message buffer with data received from peer. -+ @Param[in] msgLength - Length (in bytes) of message data. -+ @Param[in] p_Reply - Pointer to reply buffer, to be filled by the message handler and then sent -+ by the IPC service; -+ The reply buffer is allocated by the IPC service with size equals to the -+ replyLength parameter provided in message handler registration (see -+ XX_IpcRegisterMsgHandler() function); -+ If replyLength was initially specified as zero during message handler registration, -+ the IPC service may set this pointer to NULL and assume that a reply is not needed; -+ The IPC service is also responsible for freeing the reply buffer after the -+ reply has been sent or dismissed. -+ @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function: -+ [In] equals the replyLength parameter provided in message handler -+ registration (see XX_IpcRegisterMsgHandler() function), and -+ [Out] should be updated by message handler to the actual reply length; if -+ this value is set to zero, the IPC service must assume that a reply should -+ not be sent; -+ Note: If p_Reply is not NULL, p_ReplyLength must not be NULL as well. -+ -+ @Return E_OK on success; Error code otherwise. -+ *//***************************************************************************/ -+typedef t_Error (t_IpcMsgHandler)(t_Handle h_Module, -+ uint8_t *p_Msg, -+ uint32_t msgLength, -+ uint8_t *p_Reply, -+ uint32_t *p_ReplyLength); -+ -+/**************************************************************************//** -+ @Function XX_IpcRegisterMsgHandler -+ -+ @Description IPC mailbox registration. -+ -+ This function is used for registering an IPC message handler in the IPC service. -+ This function is called by each destination endpoint to indicate that it is ready -+ to handle incoming messages. The IPC service invokes the message handler upon receiving -+ a message addressed to the specified destination endpoint. -+ -+ @Param[in] addr - The address name string associated with the destination endpoint; -+ This address must be unique across the IPC service domain to ensure -+ correct message routing. -+ @Param[in] f_MsgHandler - Pointer to the message handler callback for processing incoming -+ message; invoked by the IPC service upon receiving a message -+ addressed to the destination endpoint specified by the addr -+ parameter. -+ @Param[in] h_Module - Abstract handle to the message handling module, passed unchanged -+ to f_MsgHandler callback function. -+ @Param[in] replyLength - The maximal data length (in bytes) of any reply that the specified message handler -+ may generate; the IPC service provides the message handler with buffer -+ for reply according to the length specified here (refer also to the description -+ of #t_IpcMsgHandler callback function type); -+ This size shall be zero if the message handler never generates replies. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH], -+ t_IpcMsgHandler *f_MsgHandler, -+ t_Handle h_Module, -+ uint32_t replyLength); -+ -+/**************************************************************************//** -+ @Function XX_IpcUnregisterMsgHandler -+ -+ @Description Release IPC mailbox routine. -+ -+ This function is used for unregistering an IPC message handler from the IPC service. -+ This function is called by each destination endpoint to indicate that it is no longer -+ capable of handling incoming messages. -+ -+ @Param[in] addr - The address name string associated with the destination endpoint; -+ This address is the same as was used when the message handler was -+ registered via XX_IpcRegisterMsgHandler(). -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]); -+ -+/**************************************************************************//** -+ @Function XX_IpcInitSession -+ -+ @Description This function is used for creating an IPC session between the source endpoint -+ and the destination endpoint. -+ -+ The actual implementation and representation of a session is left for the IPC service. -+ The function returns an abstract handle to the created session. This handle shall be used -+ by the source endpoint in subsequent calls to XX_IpcSendMessage(). -+ The IPC service assumes that before this function is called, no messages are sent from -+ the specified source endpoint to the specified destination endpoint. -+ -+ The IPC service may use a connection-oriented approach or a connectionless approach (or both) -+ as described below. -+ -+ @par Connection-Oriented Approach -+ -+ The IPC service may implement a session in a connection-oriented approach - when this function is called, -+ the IPC service should take the necessary steps to bring up a source-to-destination channel for messages -+ and a destination-to-source channel for replies. The returned handle should represent the internal -+ representation of these channels. -+ -+ @par Connectionless Approach -+ -+ The IPC service may implement a session in a connectionless approach - when this function is called, the -+ IPC service should not perform any particular steps, but it must store the pair of source and destination -+ addresses in some session representation and return it as a handle. When XX_IpcSendMessage() shall be -+ called, the IPC service may use this handle to provide the necessary identifiers for routing the messages -+ through the connectionless medium. -+ -+ @Param[in] destAddr - The address name string associated with the destination endpoint. -+ @Param[in] srcAddr - The address name string associated with the source endpoint. -+ -+ @Return Abstract handle to the initialized session, or NULL on error. -+*//***************************************************************************/ -+t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH], -+ char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]); -+ -+/**************************************************************************//** -+ @Function XX_IpcFreeSession -+ -+ @Description This function is used for terminating an existing IPC session between a source endpoint -+ and a destination endpoint. -+ -+ The IPC service assumes that after this function is called, no messages shall be sent from -+ the associated source endpoint to the associated destination endpoint. -+ -+ @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally -+ returned by the XX_IpcInitSession() function. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error XX_IpcFreeSession(t_Handle h_Session); -+ -+/**************************************************************************//** -+ @Function XX_IpcSendMessage -+ -+ @Description IPC message send routine. -+ -+ This function may be used by a source endpoint to send an IPC message to a destination -+ endpoint. The source endpoint cannot send a message to the destination endpoint without -+ first initiating a session with that destination endpoint via XX_IpcInitSession() routine. -+ -+ The source endpoint must provide the buffer pointer and length of the outgoing message. -+ Optionally, it may also provide a buffer for an expected reply. In the latter case, the -+ transaction is not considered complete by the IPC service until the reply has been received. -+ If the source endpoint does not provide a reply buffer, the transaction is considered -+ complete after the message has been sent. The source endpoint must keep the message (and -+ optional reply) buffers valid until the transaction is complete. -+ -+ @par Non-blocking mode -+ -+ The source endpoint may request a non-blocking send by providing a non-NULL pointer to a message -+ completion callback function (f_Completion). Upon completion of the IPC transaction (consisting of a -+ message and an optional reply), the IPC service invokes this callback routine to return the message -+ buffer to the sender and to provide the received reply, if requested. -+ -+ @par Blocking mode -+ -+ The source endpoint may request a blocking send by setting f_Completion to NULL. The function is -+ expected to block until the IPC transaction is complete - either the reply has been received or (if no reply -+ was requested) the message has been sent. -+ -+ @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally -+ returned by the XX_IpcInitSession() function. -+ @Param[in] p_Msg - Pointer to message buffer to send. -+ @Param[in] msgLength - Length (in bytes) of actual data in the message buffer. -+ @Param[in] p_Reply - Pointer to reply buffer - if this buffer is not NULL, the IPC service -+ fills this buffer with the received reply data; -+ In blocking mode, the reply data must be valid when the function returns; -+ In non-blocking mode, the reply data is valid when f_Completion is called; -+ If this pointer is NULL, no reply is expected. -+ @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function: -+ [In] specifies the maximal length (in bytes) of the reply buffer pointed by -+ p_Reply, and -+ [Out] in non-blocking mode this value is updated by the IPC service to the -+ actual reply length (in bytes). -+ @Param[in] f_Completion - Pointer to a completion callback to be used in non-blocking send mode; -+ The completion callback is invoked by the IPC service upon -+ completion of the IPC transaction (consisting of a message and an optional -+ reply); -+ If this pointer is NULL, the function is expected to block until the IPC -+ transaction is complete. -+ @Param[in] h_Arg - Abstract handle to the sending module; passed unchanged to the f_Completion -+ callback function as the first argument. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error XX_IpcSendMessage(t_Handle h_Session, -+ uint8_t *p_Msg, -+ uint32_t msgLength, -+ uint8_t *p_Reply, -+ uint32_t *p_ReplyLength, -+ t_IpcMsgCompletion *f_Completion, -+ t_Handle h_Arg); -+ -+ -+/** @} */ /* end of xx_ipc group */ -+/** @} */ /* end of xx_id group */ -+ -+ -+#endif /* __XX_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h -@@ -0,0 +1,56 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __dflags_h -+#define __dflags_h -+ -+ -+#define NCSW_LINUX -+ -+#define LS1043 -+ -+#define DEBUG_ERRORS 1 -+ -+#if defined(DEBUG) -+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO -+ -+#define DEBUG_XX_MALLOC -+#define DEBUG_MEM_LEAKS -+ -+#else -+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING -+#endif /* (DEBUG) */ -+ -+#define REPORT_EVENTS 1 -+#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR -+ -+#endif /* __dflags_h */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -@@ -0,0 +1,53 @@ -+# -+# Makefile config for the Freescale NetcommSW -+# -+NET_DPA = $(srctree)/drivers/net -+DRV_DPA = $(srctree)/drivers/net/ethernet/freescale/sdk_dpaa -+FMAN = $(srctree)/drivers/net/ethernet/freescale/sdk_fman -+ -+ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y") -+ccflags-y +=-include $(FMAN)/p3040_4080_5020_dflags.h -+endif -+ifeq ("$(CONFIG_FMAN_P1023)", "y") -+ccflags-y +=-include $(FMAN)/p1023_dflags.h -+endif -+ifdef CONFIG_FMAN_V3H -+ccflags-y +=-include $(FMAN)/fmanv3h_dflags.h -+endif -+ifdef CONFIG_FMAN_V3L -+ccflags-y +=-include $(FMAN)/fmanv3l_dflags.h -+endif -+ifdef CONFIG_FMAN_ARM -+ccflags-y +=-include $(FMAN)/ls1043_dflags.h -+endif -+ -+ccflags-y += -I$(DRV_DPA)/ -+ccflags-y += -I$(FMAN)/inc -+ccflags-y += -I$(FMAN)/inc/cores -+ccflags-y += -I$(FMAN)/inc/etc -+ccflags-y += -I$(FMAN)/inc/Peripherals -+ccflags-y += -I$(FMAN)/inc/flib -+ -+ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y") -+ccflags-y += -I$(FMAN)/inc/integrations/P3040_P4080_P5020 -+endif -+ifeq ("$(CONFIG_FMAN_P1023)", "y") -+ccflags-y += -I$(FMAN)/inc/integrations/P1023 -+endif -+ifdef CONFIG_FMAN_V3H -+ccflags-y += -I$(FMAN)/inc/integrations/FMANV3H -+endif -+ifdef CONFIG_FMAN_V3L -+ccflags-y += -I$(FMAN)/inc/integrations/FMANV3L -+endif -+ifdef CONFIG_FMAN_ARM -+ccflags-y += -I$(FMAN)/inc/integrations/LS1043 -+endif -+ -+ccflags-y += -I$(FMAN)/src/inc -+ccflags-y += -I$(FMAN)/src/inc/system -+ccflags-y += -I$(FMAN)/src/inc/wrapper -+ccflags-y += -I$(FMAN)/src/inc/xx -+ccflags-y += -I$(srctree)/include/uapi/linux/fmd -+ccflags-y += -I$(srctree)/include/uapi/linux/fmd/Peripherals -+ccflags-y += -I$(srctree)/include/uapi/linux/fmd/integrations ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h -@@ -0,0 +1,65 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __dflags_h -+#define __dflags_h -+ -+ -+#define NCSW_LINUX -+#if 0 -+#define DEBUG -+#endif -+ -+#define P1023 -+#define NCSW_PPC_CORE -+ -+#define DEBUG_ERRORS 1 -+ -+#if defined(DEBUG) -+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO -+ -+#define DEBUG_XX_MALLOC -+#define DEBUG_MEM_LEAKS -+ -+#else -+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING -+#endif /* (DEBUG) */ -+ -+#define REPORT_EVENTS 1 -+#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR -+ -+#ifdef CONFIG_P4080_SIM -+#error "Do not define CONFIG_P4080_SIM..." -+#endif -+ -+ -+#endif /* __dflags_h */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h -@@ -0,0 +1,62 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __dflags_h -+#define __dflags_h -+ -+ -+#define NCSW_LINUX -+ -+#define P4080 -+#define NCSW_PPC_CORE -+ -+#define DEBUG_ERRORS 1 -+ -+#if defined(DEBUG) -+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO -+ -+#define DEBUG_XX_MALLOC -+#define DEBUG_MEM_LEAKS -+ -+#else -+#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING -+#endif /* (DEBUG) */ -+ -+#define REPORT_EVENTS 1 -+#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR -+ -+#ifdef CONFIG_P4080_SIM -+#define SIMULATOR -+#endif /* CONFIG_P4080_SIM */ -+ -+ -+#endif /* __dflags_h */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/Makefile -@@ -0,0 +1,11 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+# -+obj-y += system/ -+obj-y += wrapper/ -+obj-y += xx/ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h -@@ -0,0 +1,118 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __SYS_EXT_H -+#define __SYS_EXT_H -+ -+#include "std_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group sys_grp System Interfaces -+ -+ @Description Linux system programming interfaces. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group sys_gen_grp System General Interface -+ -+ @Description General definitions, structures and routines of the linux -+ system programming interface. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Collection Macros for Advanced Configuration Requests -+ @{ -+*//***************************************************************************/ -+#define SYS_MAX_ADV_CONFIG_ARGS 4 -+ /**< Maximum number of arguments in -+ an advanced configuration entry */ -+/* @} */ -+ -+/**************************************************************************//** -+ @Description System Object Advanced Configuration Entry -+ -+ This structure represents a single request for an advanced -+ configuration call on the initialized object. An array of such -+ requests may be contained in the settings structure of the -+ corresponding object. -+ -+ The maximum number of arguments is limited to #SYS_MAX_ADV_CONFIG_ARGS. -+*//***************************************************************************/ -+typedef struct t_SysObjectAdvConfigEntry -+{ -+ void *p_Function; /**< Pointer to advanced configuration routine */ -+ -+ uintptr_t args[SYS_MAX_ADV_CONFIG_ARGS]; -+ /**< Array of arguments for the specified routine; -+ All arguments should be casted to uint32_t. */ -+} t_SysObjectAdvConfigEntry; -+ -+ -+/** @} */ /* end of sys_gen_grp */ -+/** @} */ /* end of sys_grp */ -+ -+#define NCSW_PARAMS(_num, _params) ADV_CONFIG_PARAMS_##_num _params -+ -+#define ADV_CONFIG_PARAMS_1(_type) \ -+ , (_type)p_Entry->args[0] -+ -+#define SET_ADV_CONFIG_ARGS_1(_arg0) \ -+ p_Entry->args[0] = (uintptr_t )(_arg0); \ -+ -+#define ARGS(_num, _params) SET_ADV_CONFIG_ARGS_##_num _params -+ -+#define ADD_ADV_CONFIG_START(_p_Entries, _maxEntries) \ -+ { \ -+ t_SysObjectAdvConfigEntry *p_Entry; \ -+ t_SysObjectAdvConfigEntry *p_Entrys = (_p_Entries); \ -+ int i=0, max = (_maxEntries); \ -+ -+#define ADD_ADV_CONFIG_END \ -+ } -+ -+#define ADV_CONFIG_CHECK_START(_p_Entry) \ -+ { \ -+ t_SysObjectAdvConfigEntry *p_Entry = _p_Entry; \ -+ t_Error errCode; \ -+ -+#define ADV_CONFIG_CHECK(_handle, _func, _params) \ -+ if (p_Entry->p_Function == _func) \ -+ { \ -+ errCode = _func(_handle _params); \ -+ } else -+ -+#endif /* __SYS_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h -@@ -0,0 +1,46 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __SYS_IO_EXT_H -+#define __SYS_IO_EXT_H -+ -+#include "std_ext.h" -+#include "error_ext.h" -+ -+ -+t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size); -+t_Error SYS_UnregisterIoMap (uint64_t virtAddr); -+uint64_t SYS_PhysToVirt (uint64_t addr); -+uint64_t SYS_VirtToPhys (uint64_t addr); -+ -+ -+#endif /* __SYS_IO_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h -@@ -0,0 +1,208 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __TYPES_LINUX_H__ -+#define __TYPES_LINUX_H__ -+ -+#include -+ -+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) -+#define MODVERSIONS -+#endif -+#ifdef MODVERSIONS -+#include -+#endif /* MODVERSIONS */ -+ -+#include -+#include -+#include -+#include -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) -+ #error "This kernel is probably not supported!!!" -+#elif (!((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) || \ -+ (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)) || \ -+ (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30)))) -+ #warning "This kernel is probably not supported!!! You may need to add some fixes." -+#endif /* LINUX_VERSION_CODE */ -+ -+ -+typedef float float_t; /* Single precision floating point */ -+typedef double double_t; /* Double precision floating point */ -+ -+ -+#define _Packed -+#define _PackedType __attribute__ ((packed)) -+ -+typedef phys_addr_t physAddress_t; -+ -+#define UINT8_MAX 0xFF -+#define UINT8_MIN 0 -+#define UINT16_MAX 0xFFFF -+#define UINT16_MIN 0 -+#define UINT32_MAX 0xFFFFFFFF -+#define UINT32_MIN 0 -+#define UINT64_MAX 0xFFFFFFFFFFFFFFFFLL -+#define UINT64_MIN 0 -+#define INT8_MAX 0x7F -+#define INT8_MIN 0x80 -+#define INT16_MAX 0x7FFF -+#define INT16_MIN 0x8000 -+#define INT32_MAX 0x7FFFFFFF -+#define INT32_MIN 0x80000000 -+#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL -+#define INT64_MIN 0x8000000000000000LL -+ -+#define ON 1 -+#define OFF 0 -+ -+#define FALSE false -+#define TRUE true -+ -+ -+/************************/ -+/* memory access macros */ -+/************************/ -+#ifdef CONFIG_FMAN_ARM -+#define in_be16(a) __be16_to_cpu(__raw_readw(a)) -+#define in_be32(a) __be32_to_cpu(__raw_readl(a)) -+#define out_be16(a, v) __raw_writew(__cpu_to_be16(v), a) -+#define out_be32(a, v) __raw_writel(__cpu_to_be32(v), a) -+#endif -+ -+#define GET_UINT8(arg) *(volatile uint8_t *)(&(arg)) -+#define GET_UINT16(arg) in_be16(&(arg))//*(volatile uint16_t*)(&(arg)) -+#define GET_UINT32(arg) in_be32(&(arg))//*(volatile uint32_t*)(&(arg)) -+#define GET_UINT64(arg) *(volatile uint64_t*)(&(arg)) -+ -+#ifdef VERBOSE_WRITE -+void XX_Print(char *str, ...); -+#define WRITE_UINT8(arg, data) \ -+ do { XX_Print("ADDR: 0x%08x, VAL: 0x%02x\r\n", (uint32_t)&(arg), (data)); *(volatile uint8_t *)(&(arg)) = (data); } while (0) -+#define WRITE_UINT16(arg, data) \ -+ do { XX_Print("ADDR: 0x%08x, VAL: 0x%04x\r\n", (uint32_t)&(arg), (data)); out_be16(&(arg), data); /* *(volatile uint16_t*)(&(arg)) = (data);*/ } while (0) -+#define WRITE_UINT32(arg, data) \ -+ do { XX_Print("ADDR: 0x%08x, VAL: 0x%08x\r\n", (uint32_t)&(arg), (data)); out_be32(&(arg), data); /* *(volatile uint32_t*)(&(arg)) = (data);*/ } while (0) -+#define WRITE_UINT64(arg, data) \ -+ do { XX_Print("ADDR: 0x%08x, VAL: 0x%016llx\r\n", (uint32_t)&(arg), (data)); *(volatile uint64_t*)(&(arg)) = (data); } while (0) -+ -+#else /* not VERBOSE_WRITE */ -+#define WRITE_UINT8(arg, data) *(volatile uint8_t *)(&(arg)) = (data) -+#define WRITE_UINT16(arg, data) out_be16(&(arg), data)//*(volatile uint16_t*)(&(arg)) = (data) -+#define WRITE_UINT32(arg, data) out_be32(&(arg), data)//*(volatile unsigned int *)(&(arg)) = (data) -+#define WRITE_UINT64(arg, data) *(volatile uint64_t*)(&(arg)) = (data) -+#endif /* not VERBOSE_WRITE */ -+ -+ -+/*****************************************************************************/ -+/* General stuff */ -+/*****************************************************************************/ -+#ifdef ARRAY_SIZE -+#undef ARRAY_SIZE -+#endif /* ARRAY_SIZE */ -+ -+#ifdef MAJOR -+#undef MAJOR -+#endif /* MAJOR */ -+ -+#ifdef MINOR -+#undef MINOR -+#endif /* MINOR */ -+ -+#ifdef QE_SIZEOF_BD -+#undef QE_SIZEOF_BD -+#endif /* QE_SIZEOF_BD */ -+ -+#ifdef BD_BUFFER_CLEAR -+#undef BD_BUFFER_CLEAR -+#endif /* BD_BUFFER_CLEAR */ -+ -+#ifdef BD_BUFFER -+#undef BD_BUFFER -+#endif /* BD_BUFFER */ -+ -+#ifdef BD_STATUS_AND_LENGTH_SET -+#undef BD_STATUS_AND_LENGTH_SET -+#endif /* BD_STATUS_AND_LENGTH_SET */ -+ -+#ifdef BD_STATUS_AND_LENGTH -+#undef BD_STATUS_AND_LENGTH -+#endif /* BD_STATUS_AND_LENGTH */ -+ -+#ifdef BD_BUFFER_ARG -+#undef BD_BUFFER_ARG -+#endif /* BD_BUFFER_ARG */ -+ -+#ifdef BD_GET_NEXT -+#undef BD_GET_NEXT -+#endif /* BD_GET_NEXT */ -+ -+#ifdef QE_SDEBCR_BA_MASK -+#undef QE_SDEBCR_BA_MASK -+#endif /* QE_SDEBCR_BA_MASK */ -+ -+#ifdef BD_BUFFER_SET -+#undef BD_BUFFER_SET -+#endif /* BD_BUFFER_SET */ -+ -+#ifdef UPGCR_PROTOCOL -+#undef UPGCR_PROTOCOL -+#endif /* UPGCR_PROTOCOL */ -+ -+#ifdef UPGCR_TMS -+#undef UPGCR_TMS -+#endif /* UPGCR_TMS */ -+ -+#ifdef UPGCR_RMS -+#undef UPGCR_RMS -+#endif /* UPGCR_RMS */ -+ -+#ifdef UPGCR_ADDR -+#undef UPGCR_ADDR -+#endif /* UPGCR_ADDR */ -+ -+#ifdef UPGCR_DIAG -+#undef UPGCR_DIAG -+#endif /* UPGCR_DIAG */ -+ -+#ifdef NCSW_PARAMS -+#undef NCSW_PARAMS -+#endif /* NCSW_PARAMS */ -+ -+#ifdef NO_IRQ -+#undef NO_IRQ -+#endif /* NO_IRQ */ -+ -+#define PRINT_LINE XX_Print("%s:\n %s [%d]\n",__FILE__,__FUNCTION__,__LINE__); -+ -+ -+#endif /* __TYPES_LINUX_H__ */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h -@@ -0,0 +1,84 @@ -+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File fsl_fman_test.h -+ -+ @Description -+*//***************************************************************************/ -+ -+#ifndef __FSL_FMAN_TEST_H -+#define __FSL_FMAN_TEST_H -+ -+#include -+#include /* raw_smp_processor_id() */ -+ -+//#define FMT_K_DBG -+//#define FMT_K_DBG_RUNTIME -+ -+#define _fmt_prk(stage, format, arg...) \ -+ printk(stage "fmt (cpu:%u): " format, raw_smp_processor_id(), ##arg) -+ -+#define _fmt_inf(format, arg...) _fmt_prk(KERN_INFO, format, ##arg) -+#define _fmt_wrn(format, arg...) _fmt_prk(KERN_WARNING, format, ##arg) -+#define _fmt_err(format, arg...) _fmt_prk(KERN_ERR, format, ##arg) -+ -+/* there are two macros for debugging: for runtime and generic. -+ * Helps when the runtime functions are not targeted for debugging, -+ * thus all the unnecessary information will be skipped. -+ */ -+/* used for generic debugging */ -+#if defined(FMT_K_DBG) -+ #define _fmt_dbg(format, arg...) \ -+ printk("fmt [%s:%u](cpu:%u) - " format, \ -+ __func__, __LINE__, raw_smp_processor_id(), ##arg) -+#else -+# define _fmt_dbg(arg...) -+#endif -+ -+/* used for debugging runtime functions */ -+#if defined(FMT_K_DBG_RUNTIME) -+ #define _fmt_dbgr(format, arg...) \ -+ printk("fmt [%s:%u](cpu:%u) - " format, \ -+ __func__, __LINE__, raw_smp_processor_id(), ##arg) -+#else -+# define _fmt_dbgr(arg...) -+#endif -+ -+#define FMT_RX_ERR_Q 0xffffffff -+#define FMT_RX_DFLT_Q 0xfffffffe -+#define FMT_TX_ERR_Q 0xfffffffd -+#define FMT_TX_CONF_Q 0xfffffffc -+ -+#define FMAN_TEST_MAX_TX_FQS 8 -+ -+#endif /* __FSL_FMAN_TEST_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h -@@ -0,0 +1,128 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ @File lnxwrp_exp_sym.h -+ @Description FMan exported routines -+*/ -+ -+#ifndef __LNXWRP_EXP_SYM_H -+#define __LNXWRP_EXP_SYM_H -+ -+#include "fm_port_ext.h" -+#include "fm_pcd_ext.h" -+#include "fm_mac_ext.h" -+ -+ -+/* FMAN Port exported routines */ -+EXPORT_SYMBOL(FM_PORT_Disable); -+EXPORT_SYMBOL(FM_PORT_Enable); -+EXPORT_SYMBOL(FM_PORT_SetPCD); -+EXPORT_SYMBOL(FM_PORT_DeletePCD); -+ -+/* Runtime PCD exported routines */ -+EXPORT_SYMBOL(FM_PCD_Enable); -+EXPORT_SYMBOL(FM_PCD_Disable); -+EXPORT_SYMBOL(FM_PCD_GetCounter); -+EXPORT_SYMBOL(FM_PCD_PrsLoadSw); -+EXPORT_SYMBOL(FM_PCD_KgSetDfltValue); -+EXPORT_SYMBOL(FM_PCD_KgSetAdditionalDataAfterParsing); -+EXPORT_SYMBOL(FM_PCD_SetException); -+EXPORT_SYMBOL(FM_PCD_ModifyCounter); -+EXPORT_SYMBOL(FM_PCD_SetPlcrStatistics); -+EXPORT_SYMBOL(FM_PCD_SetPrsStatistics); -+EXPORT_SYMBOL(FM_PCD_ForceIntr); -+EXPORT_SYMBOL(FM_PCD_HcTxConf); -+ -+EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsSet); -+EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsDelete); -+EXPORT_SYMBOL(FM_PCD_KgSchemeSet); -+EXPORT_SYMBOL(FM_PCD_KgSchemeDelete); -+EXPORT_SYMBOL(FM_PCD_KgSchemeGetCounter); -+EXPORT_SYMBOL(FM_PCD_KgSchemeSetCounter); -+EXPORT_SYMBOL(FM_PCD_CcRootBuild); -+EXPORT_SYMBOL(FM_PCD_CcRootDelete); -+EXPORT_SYMBOL(FM_PCD_MatchTableSet); -+EXPORT_SYMBOL(FM_PCD_MatchTableDelete); -+EXPORT_SYMBOL(FM_PCD_CcRootModifyNextEngine); -+EXPORT_SYMBOL(FM_PCD_MatchTableModifyNextEngine); -+EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyNextEngine); -+EXPORT_SYMBOL(FM_PCD_MatchTableModifyMissNextEngine); -+EXPORT_SYMBOL(FM_PCD_MatchTableRemoveKey); -+EXPORT_SYMBOL(FM_PCD_MatchTableFindNRemoveKey); -+EXPORT_SYMBOL(FM_PCD_MatchTableAddKey); -+EXPORT_SYMBOL(FM_PCD_MatchTableModifyKeyAndNextEngine); -+EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKeyAndNextEngine); -+EXPORT_SYMBOL(FM_PCD_MatchTableModifyKey); -+EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKey); -+EXPORT_SYMBOL(FM_PCD_MatchTableGetIndexedHashBucket); -+EXPORT_SYMBOL(FM_PCD_MatchTableGetNextEngine); -+EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyCounter); -+EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyStatistics); -+EXPORT_SYMBOL(FM_PCD_MatchTableFindNGetKeyStatistics); -+EXPORT_SYMBOL(FM_PCD_MatchTableGetMissStatistics); -+EXPORT_SYMBOL(FM_PCD_HashTableGetMissStatistics); -+EXPORT_SYMBOL(FM_PCD_HashTableSet); -+EXPORT_SYMBOL(FM_PCD_HashTableDelete); -+EXPORT_SYMBOL(FM_PCD_HashTableAddKey); -+EXPORT_SYMBOL(FM_PCD_HashTableRemoveKey); -+EXPORT_SYMBOL(FM_PCD_HashTableModifyNextEngine); -+EXPORT_SYMBOL(FM_PCD_HashTableModifyMissNextEngine); -+EXPORT_SYMBOL(FM_PCD_HashTableGetMissNextEngine); -+EXPORT_SYMBOL(FM_PCD_HashTableFindNGetKeyStatistics); -+EXPORT_SYMBOL(FM_PCD_PlcrProfileSet); -+EXPORT_SYMBOL(FM_PCD_PlcrProfileDelete); -+EXPORT_SYMBOL(FM_PCD_PlcrProfileGetCounter); -+EXPORT_SYMBOL(FM_PCD_PlcrProfileSetCounter); -+EXPORT_SYMBOL(FM_PCD_ManipNodeSet); -+EXPORT_SYMBOL(FM_PCD_ManipNodeDelete); -+EXPORT_SYMBOL(FM_PCD_ManipGetStatistics); -+EXPORT_SYMBOL(FM_PCD_ManipNodeReplace); -+#if (DPAA_VERSION >= 11) -+EXPORT_SYMBOL(FM_PCD_FrmReplicSetGroup); -+EXPORT_SYMBOL(FM_PCD_FrmReplicDeleteGroup); -+EXPORT_SYMBOL(FM_PCD_FrmReplicAddMember); -+EXPORT_SYMBOL(FM_PCD_FrmReplicRemoveMember); -+#endif /* DPAA_VERSION >= 11 */ -+ -+#ifdef FM_CAPWAP_SUPPORT -+EXPORT_SYMBOL(FM_PCD_StatisticsSetNode); -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+EXPORT_SYMBOL(FM_PCD_SetAdvancedOffloadSupport); -+ -+/* FMAN MAC exported routines */ -+EXPORT_SYMBOL(FM_MAC_GetStatistics); -+ -+EXPORT_SYMBOL(FM_GetSpecialOperationCoding); -+ -+#endif /* __LNXWRP_EXP_SYM_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h -@@ -0,0 +1,163 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File lnxwrp_fm_ext.h -+ -+ @Description TODO -+*//***************************************************************************/ -+ -+#ifndef __LNXWRP_FM_EXT_H -+#define __LNXWRP_FM_EXT_H -+ -+#include "std_ext.h" -+#include "sys_ext.h" -+#include "fm_ext.h" -+#include "fm_muram_ext.h" -+#include "fm_pcd_ext.h" -+#include "fm_port_ext.h" -+#include "fm_mac_ext.h" -+#include "fm_rtc_ext.h" -+ -+ -+/**************************************************************************//** -+ @Group FM_LnxKern_grp Frame Manager Linux wrapper API -+ -+ @Description FM API functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_LnxKern_init_grp Initialization Unit -+ -+ @Description Initialization Unit -+ -+ Initialization Flow: -+ Initialization of the FM Module will be carried out by the Linux -+ kernel according to the following sequence: -+ a. Calling the initialization routine with no parameters. -+ b. The driver will register to the Device-Tree. -+ c. The Linux Device-Tree will initiate a call to the driver for -+ initialization. -+ d. The driver will read the appropriate information from the Device-Tree -+ e. [Optional] Calling the advance initialization routines to change -+ driver's defaults. -+ f. Initialization of the device will be automatically upon using it. -+ -+ @{ -+*//***************************************************************************/ -+ -+typedef struct t_WrpFmDevSettings -+{ -+ t_FmParams param; -+ t_SysObjectAdvConfigEntry *advConfig; -+} t_WrpFmDevSettings; -+ -+typedef struct t_WrpFmPcdDevSettings -+{ -+ t_FmPcdParams param; -+ t_SysObjectAdvConfigEntry *advConfig; -+} t_WrpFmPcdDevSettings; -+ -+typedef struct t_WrpFmPortDevSettings -+{ -+ bool frag_enabled; -+ t_FmPortParams param; -+ t_SysObjectAdvConfigEntry *advConfig; -+} t_WrpFmPortDevSettings; -+ -+typedef struct t_WrpFmMacDevSettings -+{ -+ t_FmMacParams param; -+ t_SysObjectAdvConfigEntry *advConfig; -+} t_WrpFmMacDevSettings; -+ -+ -+/**************************************************************************//** -+ @Function LNXWRP_FM_Init -+ -+ @Description Initialize the FM linux wrapper. -+ -+ @Return A handle (descriptor) of the newly created FM Linux wrapper -+ structure. -+*//***************************************************************************/ -+t_Handle LNXWRP_FM_Init(void); -+ -+/**************************************************************************//** -+ @Function LNXWRP_FM_Free -+ -+ @Description Free the FM linux wrapper. -+ -+ @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper. -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm); -+ -+/**************************************************************************//** -+ @Function LNXWRP_FM_GetMacHandle -+ -+ @Description Get the FM-MAC LLD handle from the FM linux wrapper. -+ -+ @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper. -+ @Param[in] fmId - Index of the FM device to get the MAC handle from. -+ @Param[in] macId - Index of the mac handle. -+ -+ @Return A handle of the LLD compressor. -+*//***************************************************************************/ -+t_Handle LNXWRP_FM_GetMacHandle(t_Handle h_LnxWrpFm, uint8_t fmId, uint8_t macId); -+ -+#ifdef CONFIG_FSL_SDK_FMAN_TEST -+t_Handle LNXWRP_FM_TEST_Init(void); -+t_Error LNXWRP_FM_TEST_Free(t_Handle h_FmTestLnxWrp); -+#endif /* CONFIG_FSL_SDK_FMAN_TEST */ -+ -+/** @} */ /* end of FM_LnxKern_init_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group FM_LnxKern_ctrl_grp Control Unit -+ -+ @Description Control Unit -+ -+ TODO -+ @{ -+*//***************************************************************************/ -+ -+#include "lnxwrp_fsl_fman.h" -+ -+/** @} */ /* end of FM_LnxKern_ctrl_grp group */ -+/** @} */ /* end of FM_LnxKern_grp group */ -+ -+ -+#endif /* __LNXWRP_FM_EXT_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h -@@ -0,0 +1,921 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File lnxwrp_fsl_fman.h -+ -+ @Description Linux internal kernel API -+*//***************************************************************************/ -+ -+#ifndef __LNXWRP_FSL_FMAN_H -+#define __LNXWRP_FSL_FMAN_H -+ -+#include -+#include /* struct device */ -+#include /* struct qman_fq */ -+#include "dpaa_integration_ext.h" -+#include "fm_port_ext.h" -+#include "fm_mac_ext.h" -+#include "fm_macsec_ext.h" -+#include "fm_rtc_ext.h" -+ -+/**************************************************************************//** -+ @Group FM_LnxKern_grp Frame Manager Linux wrapper API -+ -+ @Description FM API functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group FM_LnxKern_ctrl_grp Control Unit -+ -+ @Description Control Unit -+ -+ Internal Kernel Control Unit API -+ @{ -+*//***************************************************************************/ -+ -+/*****************************************************************************/ -+/* Internal Linux kernel routines */ -+/*****************************************************************************/ -+ -+/**************************************************************************//** -+ @Description MACSEC Exceptions wrapper -+*//***************************************************************************/ -+typedef enum fm_macsec_exception { -+ SINGLE_BIT_ECC = e_FM_MACSEC_EX_SINGLE_BIT_ECC, -+ MULTI_BIT_ECC = e_FM_MACSEC_EX_MULTI_BIT_ECC -+} fm_macsec_exception; -+ -+/**************************************************************************//** -+ @Description Unknown sci frame treatment wrapper -+*//***************************************************************************/ -+typedef enum fm_macsec_unknown_sci_frame_treatment { -+ SCI_DISCARD_BOTH = e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH, -+ SCI_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \ -+ e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, -+ SCI_DELIVER_UNCTRL_DISCARD_CTRL = \ -+ e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, -+ SCI_DELIVER_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \ -+ e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED -+} fm_macsec_unknown_sci_frame_treatment; -+ -+/**************************************************************************//** -+ @Description Untag frame treatment wrapper -+*//***************************************************************************/ -+typedef enum fm_macsec_untag_frame_treatment { -+ UNTAG_DELIVER_UNCTRL_DISCARD_CTRL = \ -+ e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, -+ UNTAG_DISCARD_BOTH = e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, -+ UNTAG_DISCARD_UNCTRL_DELIVER_CTRL_UNMODIFIED = \ -+ e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED -+} fm_macsec_untag_frame_treatment; -+ -+/**************************************************************************//** -+@Description MACSEC SECY Cipher Suite wrapper -+*//***************************************************************************/ -+typedef enum fm_macsec_secy_cipher_suite { -+ SECY_GCM_AES_128 = e_FM_MACSEC_SECY_GCM_AES_128, /**< GCM-AES-128 */ -+#if (DPAA_VERSION >= 11) -+ SECY_GCM_AES_256 = e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */ -+#endif /* (DPAA_VERSION >= 11) */ -+} fm_macsec_secy_cipher_suite; -+ -+/**************************************************************************//** -+ @Description MACSEC SECY Exceptions wrapper -+*//***************************************************************************/ -+typedef enum fm_macsec_secy_exception { -+ SECY_EX_FRAME_DISCARDED = e_FM_MACSEC_SECY_EX_FRAME_DISCARDED -+} fm_macsec_secy_exception; -+ -+/**************************************************************************//** -+ @Description MACSEC SECY Events wrapper -+*//***************************************************************************/ -+typedef enum fm_macsec_secy_event { -+ SECY_EV_NEXT_PN = e_FM_MACSEC_SECY_EV_NEXT_PN -+} fm_macsec_secy_event; -+ -+/**************************************************************************//** -+ @Description Valid frame behaviors wrapper -+*//***************************************************************************/ -+typedef enum fm_macsec_valid_frame_behavior { -+ VALID_FRAME_BEHAVIOR_DISABLE = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE, -+ VALID_FRAME_BEHAVIOR_CHECK = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, -+ VALID_FRAME_BEHAVIOR_STRICT = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT -+} fm_macsec_valid_frame_behavior; -+ -+/**************************************************************************//** -+ @Description SCI insertion modes wrapper -+*//***************************************************************************/ -+typedef enum fm_macsec_sci_insertion_mode { -+ SCI_INSERTION_MODE_EXPLICIT_SECTAG = \ -+ e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG, -+ SCI_INSERTION_MODE_EXPLICIT_MAC_SA = \ -+ e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, -+ SCI_INSERTION_MODE_IMPLICT_PTP = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP -+} fm_macsec_sci_insertion_mode; -+ -+typedef macsecSAKey_t macsec_sa_key_t; -+typedef macsecSCI_t macsec_sci_t; -+typedef macsecAN_t macsec_an_t; -+typedef t_Handle handle_t; -+ -+/**************************************************************************//** -+ @Function fm_macsec_secy_exception_callback wrapper -+ @Description Exceptions user callback routine, will be called upon an -+ exception passing the exception identification. -+ @Param[in] app_h A handle to an application layer object; This handle -+ will be passed by the driver upon calling this callback. -+ @Param[in] exception The exception. -+*//***************************************************************************/ -+typedef void (fm_macsec_secy_exception_callback) (handle_t app_h, -+ fm_macsec_secy_exception exception); -+ -+/**************************************************************************//** -+ @Function fm_macsec_secy_event_callback wrapper -+ @Description Events user callback routine, will be called upon an -+ event passing the event identification. -+ @Param[in] app_h A handle to an application layer object; This handle -+ will be passed by the driver upon calling this callback. -+ @Param[in] event The event. -+*//***************************************************************************/ -+typedef void (fm_macsec_secy_event_callback) (handle_t app_h, -+ fm_macsec_secy_event event); -+ -+/**************************************************************************//** -+ @Function fm_macsec_exception_callback wrapper -+ @Description Exceptions user callback routine, will be called upon an -+ exception passing the exception identification. -+ @Param[in] app_h A handle to an application layer object; This handle -+ will be passed by the driver upon calling this callback. -+ @Param[in] exception The exception. -+*//***************************************************************************/ -+typedef void (fm_macsec_exception_callback) (handle_t app_h, -+ fm_macsec_exception exception); -+ -+/**************************************************************************//** -+ @Description MACSEC SecY SC Params wrapper -+*//***************************************************************************/ -+struct fm_macsec_secy_sc_params { -+ macsec_sci_t sci; -+ fm_macsec_secy_cipher_suite cipher_suite; -+}; -+ -+/**************************************************************************//** -+ @Description FM MACSEC SecY config input wrapper -+*//***************************************************************************/ -+struct fm_macsec_secy_params { -+ handle_t fm_macsec_h; -+ struct fm_macsec_secy_sc_params tx_sc_params; -+ uint32_t num_receive_channels; -+ fm_macsec_secy_exception_callback *exception_f; -+ fm_macsec_secy_event_callback *event_f; -+ handle_t app_h; -+}; -+ -+/**************************************************************************//** -+ @Description FM MACSEC config input wrapper -+*//***************************************************************************/ -+struct fm_macsec_params { -+ handle_t fm_h; -+ bool guest_mode; -+ -+ union { -+ struct { -+ uint8_t fm_mac_id; -+ } guest_params; -+ -+ struct { -+ uintptr_t base_addr; -+ handle_t fm_mac_h; -+ fm_macsec_exception_callback *exception_f; -+ handle_t app_h; -+ } non_guest_params; -+ }; -+ -+}; -+ -+/**************************************************************************//** -+ @Description FM device opaque structure used for type checking -+*//***************************************************************************/ -+struct fm; -+ -+/**************************************************************************//** -+ @Description FM MAC device opaque structure used for type checking -+*//***************************************************************************/ -+struct fm_mac_dev; -+ -+/**************************************************************************//** -+ @Description FM MACSEC device opaque structure used for type checking -+*//***************************************************************************/ -+struct fm_macsec_dev; -+struct fm_macsec_secy_dev; -+ -+/**************************************************************************//** -+ @Description A structure .., -+*//***************************************************************************/ -+struct fm_port; -+ -+typedef int (*alloc_pcd_fqids)(struct device *dev, uint32_t num, -+ uint8_t alignment, uint32_t *base_fqid); -+ -+typedef int (*free_pcd_fqids)(struct device *dev, uint32_t base_fqid); -+ -+struct fm_port_pcd_param { -+ alloc_pcd_fqids cba; -+ free_pcd_fqids cbf; -+ struct device *dev; -+}; -+ -+/**************************************************************************//** -+ @Description A structure of information about each of the external -+ buffer pools used by the port, -+*//***************************************************************************/ -+struct fm_port_pool_param { -+ uint8_t id; /**< External buffer pool id */ -+ uint16_t size; /**< External buffer pool buffer size */ -+}; -+ -+/**************************************************************************//** -+ @Description structure for additional port parameters -+*//***************************************************************************/ -+struct fm_port_params { -+ uint32_t errq; /**< Error Queue Id. */ -+ uint32_t defq; /**< For Tx and HC - Default Confirmation queue, -+ 0 means no Tx conf for processed frames. -+ For Rx and OP - default Rx queue. */ -+ uint8_t num_pools; /**< Number of pools use by this port */ -+ struct fm_port_pool_param pool_param[FM_PORT_MAX_NUM_OF_EXT_POOLS]; -+ /**< Parameters for each pool */ -+ uint16_t priv_data_size; /**< Area that user may save for his own -+ need (E.g. save the SKB) */ -+ bool parse_results; /**< Put the parser-results in the Rx/Tx buffer */ -+ bool hash_results; /**< Put the hash-results in the Rx/Tx buffer */ -+ bool time_stamp; /**< Put the time-stamp in the Rx/Tx buffer */ -+ bool frag_enable; /**< Fragmentation support, for OP only */ -+ uint16_t data_align; /**< value for selecting a data alignment (must be a power of 2); -+ if write optimization is used, must be >= 16. */ -+ uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size); -+ Note that this field impacts the size of the buffer-prefix -+ (i.e. it pushes the data offset); */ -+}; -+ -+/**************************************************************************//** -+ @Function fm_bind -+ -+ @Description Bind to a specific FM device. -+ -+ @Param[in] fm_dev - the OF handle of the FM device. -+ -+ @Return A handle of the FM device. -+ -+ @Cautions Allowed only after the port was created. -+*//***************************************************************************/ -+struct fm *fm_bind(struct device *fm_dev); -+ -+/**************************************************************************//** -+ @Function fm_unbind -+ -+ @Description Un-bind from a specific FM device. -+ -+ @Param[in] fm - A handle of the FM device. -+ -+ @Cautions Allowed only after the port was created. -+*//***************************************************************************/ -+void fm_unbind(struct fm *fm); -+ -+void *fm_get_handle(struct fm *fm); -+void *fm_get_rtc_handle(struct fm *fm); -+struct resource *fm_get_mem_region(struct fm *fm); -+ -+/**************************************************************************//** -+ @Function fm_port_bind -+ -+ @Description Bind to a specific FM-port device (may be Rx or Tx port). -+ -+ @Param[in] fm_port_dev - the OF handle of the FM port device. -+ -+ @Return A handle of the FM port device. -+ -+ @Cautions Allowed only after the port was created. -+*//***************************************************************************/ -+struct fm_port *fm_port_bind(struct device *fm_port_dev); -+ -+/**************************************************************************//** -+ @Function fm_port_unbind -+ -+ @Description Un-bind from a specific FM-port device (may be Rx or Tx port). -+ -+ @Param[in] port - A handle of the FM port device. -+ -+ @Cautions Allowed only after the port was created. -+*//***************************************************************************/ -+void fm_port_unbind(struct fm_port *port); -+ -+/**************************************************************************//** -+ @Function fm_set_rx_port_params -+ -+ @Description Configure parameters for a specific Rx FM-port device. -+ -+ @Param[in] port - A handle of the FM port device. -+ @Param[in] params - Rx port parameters -+ -+ @Cautions Allowed only after the port is binded. -+*//***************************************************************************/ -+void fm_set_rx_port_params(struct fm_port *port, -+ struct fm_port_params *params); -+ -+/**************************************************************************//** -+ @Function fm_port_pcd_bind -+ -+ @Description Bind as a listener on a port PCD. -+ -+ @Param[in] port - A handle of the FM port device. -+ @Param[in] params - PCD port parameters -+ -+ @Cautions Allowed only after the port is binded. -+*//***************************************************************************/ -+void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params); -+ -+/**************************************************************************//** -+ @Function fm_port_get_buff_layout_ext_params -+ -+ @Description Get data_align and manip_extra_space from the device tree -+ chosen node if applied. -+ This function will only update these two parameters. -+ When this port has no such parameters in the device tree -+ values will be set to 0. -+ -+ @Param[in] port - A handle of the FM port device. -+ @Param[in] params - PCD port parameters -+ -+ @Cautions Allowed only after the port is binded. -+*//***************************************************************************/ -+void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params); -+ -+/**************************************************************************//** -+ @Function fm_get_tx_port_channel -+ -+ @Description Get qman-channel number for this Tx port. -+ -+ @Param[in] port - A handle of the FM port device. -+ -+ @Return qman-channel number for this Tx port. -+ -+ @Cautions Allowed only after the port is binded. -+*//***************************************************************************/ -+uint16_t fm_get_tx_port_channel(struct fm_port *port); -+ -+/**************************************************************************//** -+ @Function fm_set_tx_port_params -+ -+ @Description Configure parameters for a specific Tx FM-port device -+ -+ @Param[in] port - A handle of the FM port device. -+ @Param[in] params - Tx port parameters -+ -+ @Cautions Allowed only after the port is binded. -+*//***************************************************************************/ -+void fm_set_tx_port_params(struct fm_port *port, struct fm_port_params *params); -+ -+ -+/**************************************************************************//** -+ @Function fm_mac_set_handle -+ -+ @Description Set mac handle -+ -+ @Param[in] h_lnx_wrp_fm_dev - A handle of the LnxWrp FM device. -+ @Param[in] h_fm_mac - A handle of the LnxWrp FM MAC device. -+ @Param[in] mac_id - MAC id. -+*//***************************************************************************/ -+void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev, t_Handle h_fm_mac, -+ int mac_id); -+ -+/**************************************************************************//** -+ @Function fm_port_enable -+ -+ @Description Enable specific FM-port device (may be Rx or Tx port). -+ -+ @Param[in] port - A handle of the FM port device. -+ -+ @Cautions Allowed only after the port is initialized. -+*//***************************************************************************/ -+int fm_port_enable(struct fm_port *port); -+ -+/**************************************************************************//** -+ @Function fm_port_disable -+ -+ @Description Disable specific FM-port device (may be Rx or Tx port). -+ -+ @Param[in] port - A handle of the FM port device. -+ -+ @Cautions Allowed only after the port is initialized. -+*//***************************************************************************/ -+int fm_port_disable(struct fm_port *port); -+ -+void *fm_port_get_handle(const struct fm_port *port); -+ -+u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port, -+ const void *data); -+ -+/**************************************************************************//** -+ @Function fm_port_get_base_address -+ -+ @Description Get base address of this port. Useful for accessing -+ port-specific registers (i.e., not common ones). -+ -+ @Param[in] port - A handle of the FM port device. -+ -+ @Param[out] base_addr - The port's base addr (virtual address). -+*//***************************************************************************/ -+void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr); -+ -+/**************************************************************************//** -+ @Function fm_mutex_lock -+ -+ @Description Lock function required before any FMD/LLD call. -+*//***************************************************************************/ -+void fm_mutex_lock(void); -+ -+/**************************************************************************//** -+ @Function fm_mutex_unlock -+ -+ @Description Unlock function required after any FMD/LLD call. -+*//***************************************************************************/ -+void fm_mutex_unlock(void); -+ -+/**************************************************************************//** -+ @Function fm_get_max_frm -+ -+ @Description Get the maximum frame size -+*//***************************************************************************/ -+int fm_get_max_frm(void); -+ -+/**************************************************************************//** -+ @Function fm_get_rx_extra_headroom -+ -+ @Description Get the extra headroom size -+*//***************************************************************************/ -+int fm_get_rx_extra_headroom(void); -+ -+/**************************************************************************//** -+@Function fm_port_set_rate_limit -+ -+@Description Configure Shaper parameter on FM-port device (Tx port). -+ -+@Param[in] port - A handle of the FM port device. -+@Param[in] max_burst_size - Value of maximum burst size allowed. -+@Param[in] rate_limit - The required rate value. -+ -+@Cautions Allowed only after the port is initialized. -+*//***************************************************************************/ -+int fm_port_set_rate_limit(struct fm_port *port, -+ uint16_t max_burst_size, -+ uint32_t rate_limit); -+/**************************************************************************//** -+@Function fm_port_set_rate_limit -+ -+@Description Delete Shaper configuration on FM-port device (Tx port). -+ -+@Param[in] port - A handle of the FM port device. -+ -+@Cautions Allowed only after the port is initialized. -+*//***************************************************************************/ -+int fm_port_del_rate_limit(struct fm_port *port); -+ -+struct auto_res_tables_sizes -+{ -+ uint16_t max_num_of_arp_entries; -+ uint16_t max_num_of_echo_ipv4_entries; -+ uint16_t max_num_of_ndp_entries; -+ uint16_t max_num_of_echo_ipv6_entries; -+ uint16_t max_num_of_snmp_ipv4_entries; -+ uint16_t max_num_of_snmp_ipv6_entries; -+ uint16_t max_num_of_snmp_oid_entries; -+ uint16_t max_num_of_snmp_char; /* total amount of character needed -+ for the snmp table */ -+ uint16_t max_num_of_ip_prot_filtering; -+ uint16_t max_num_of_tcp_port_filtering; -+ uint16_t max_num_of_udp_port_filtering; -+}; -+/* ARP */ -+struct auto_res_arp_entry -+{ -+ uint32_t ip_address; -+ uint8_t mac[6]; -+ bool is_vlan; -+ uint16_t vid; -+}; -+struct auto_res_arp_info -+{ -+ uint8_t table_size; -+ struct auto_res_arp_entry *auto_res_table; -+ bool enable_conflict_detection; /* when TRUE -+ Conflict Detection will be checked and wake the host if -+ needed */ -+}; -+ -+/* NDP */ -+struct auto_res_ndp_entry -+{ -+ uint32_t ip_address[4]; -+ uint8_t mac[6]; -+ bool is_vlan; -+ uint16_t vid; -+}; -+struct auto_res_ndp_info -+{ -+ uint32_t multicast_group; -+ uint8_t table_size_assigned; -+ struct auto_res_ndp_entry *auto_res_table_assigned; /* This list -+ refer to solicitation IP addresses. Note that all IP adresses -+ must be from the same multicast group. This will be checked and -+ if not operation will fail. */ -+ uint8_t table_size_tmp; -+ struct auto_res_ndp_entry *auto_res_table_tmp; /* This list -+ refer to temp IP addresses. Note that all temp IP adresses must -+ be from the same multicast group. This will be checked and if -+ not operation will fail. */ -+ -+ bool enable_conflict_detection; /* when TRUE -+ Conflict Detection will be checked and wake the host if -+ needed */ -+}; -+ -+/* ICMP ECHO */ -+struct auto_res_echo_ipv4_info -+{ -+ uint8_t table_size; -+ struct auto_res_arp_entry *auto_res_table; -+}; -+ -+struct auto_res_echo_ipv6_info -+{ -+ uint8_t table_size; -+ struct auto_res_ndp_entry *auto_res_table; -+}; -+ -+/* SNMP */ -+struct auto_res_snmp_entry -+{ -+ uint16_t oidSize; -+ uint8_t *oidVal; /* only the oid string */ -+ uint16_t resSize; -+ uint8_t *resVal; /* resVal will be the entire reply, -+ i.e. "Type|Length|Value" */ -+}; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry -+ Refer to the FMan Controller spec for more details. -+*//***************************************************************************/ -+struct auto_res_snmp_ipv4addr_tbl_entry -+{ -+ uint32_t ipv4addr; /*!< 32 bit IPv4 Address. */ -+ bool is_vlan; -+ uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ -+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ -+}; -+ -+/**************************************************************************//** -+ @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry -+ Refer to the FMan Controller spec for more details. -+*//***************************************************************************/ -+struct auto_res_snmp_ipv6addr_tbl_entry -+{ -+ uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */ -+ bool isVlan; -+ uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */ -+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */ -+}; -+ -+struct auto_res_snmp_info -+{ -+ uint16_t control; /**< Control bits [0-15]. */ -+ uint16_t max_snmp_msg_length; /**< Maximal allowed SNMP message length. */ -+ uint16_t num_ipv4_addresses; /**< Number of entries in IPv4 addresses table. */ -+ uint16_t num_ipv6_addresses; /**< Number of entries in IPv6 addresses table. */ -+ struct auto_res_snmp_ipv4addr_tbl_entry *ipv4addr_tbl; /**< Pointer to IPv4 addresses table. */ -+ struct auto_res_snmp_ipv6addr_tbl_entry *ipv6addr_tbl; /**< Pointer to IPv6 addresses table. */ -+ char *community_read_write_string; -+ char *community_read_only_string; -+ struct auto_res_snmp_entry *oid_table; -+ uint32_t oid_table_size; -+ uint32_t *statistics; -+}; -+ -+/* Filtering */ -+struct auto_res_port_filtering_entry -+{ -+ uint16_t src_port; -+ uint16_t dst_port; -+ uint16_t src_port_mask; -+ uint16_t dst_port_mask; -+}; -+struct auto_res_filtering_info -+{ -+ /* IP protocol filtering parameters */ -+ uint8_t ip_prot_table_size; -+ uint8_t *ip_prot_table_ptr; -+ bool ip_prot_pass_on_hit; /* when TRUE, miss in the table will -+ cause the packet to be droped, hit will pass the packet to -+ UDP/TCP filters if needed and if not to the classification -+ tree. If the classification tree will pass the packet to a -+ queue it will cause a wake interupt. When FALSE it the other -+ way around. */ -+ /* UDP port filtering parameters */ -+ uint8_t udp_ports_table_size; -+ struct auto_res_port_filtering_entry *udp_ports_table_ptr; -+ bool udp_port_pass_on_hit; /* when TRUE, miss in the table will -+ cause the packet to be droped, hit will pass the packet to -+ classification tree. If the classification tree will pass the -+ packet to a queue it will cause a wake interupt. When FALSE it -+ the other way around. */ -+ /* TCP port filtering parameters */ -+ uint16_t tcp_flags_mask; -+ uint8_t tcp_ports_table_size; -+ struct auto_res_port_filtering_entry *tcp_ports_table_ptr; -+ bool tcp_port_pass_on_hit; /* when TRUE, miss in the table will -+ cause the packet to be droped, hit will pass the packet to -+ classification tree. If the classification tree will pass the -+ packet to a queue it will cause a wake interupt. When FALSE it -+ the other way around. */ -+}; -+ -+struct auto_res_port_params -+{ -+ t_Handle h_FmPortTx; -+ struct auto_res_arp_info *p_auto_res_arp_info; -+ struct auto_res_echo_ipv4_info *p_auto_res_echo_ipv4_info; -+ struct auto_res_ndp_info *p_auto_res_ndp_info; -+ struct auto_res_echo_ipv6_info *p_auto_res_echo_ipv6_info; -+ struct auto_res_snmp_info *p_auto_res_snmp_info; -+ struct auto_res_filtering_info *p_auto_res_filtering_info; -+}; -+ -+struct auto_res_port_stats -+{ -+ uint32_t arp_ar_cnt; -+ uint32_t echo_icmpv4_ar_cnt; -+ uint32_t ndp_ar_cnt; -+ uint32_t echo_icmpv6_ar_cnt; -+}; -+ -+int fm_port_config_autores_for_deepsleep_support(struct fm_port *port, -+ struct auto_res_tables_sizes *params); -+ -+int fm_port_enter_autores_for_deepsleep(struct fm_port *port, -+ struct auto_res_port_params *params); -+ -+void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx, -+ struct fm_port *port_tx); -+ -+bool fm_port_is_in_auto_res_mode(struct fm_port *port); -+ -+struct auto_res_tables_sizes *fm_port_get_autores_maxsize( -+ struct fm_port *port); -+ -+int fm_port_get_autores_stats(struct fm_port *port, struct auto_res_port_stats -+ *stats); -+ -+int fm_port_resume(struct fm_port *port); -+ -+int fm_port_suspend(struct fm_port *port); -+ -+#ifdef CONFIG_FMAN_PFC -+/**************************************************************************//** -+@Function fm_port_set_pfc_priorities_mapping_to_qman_wq -+ -+@Description Associate a QMan Work Queue with a PFC priority on this -+ FM-port device (Tx port). -+ -+@Param[in] port - A handle of the FM port device. -+ -+@Param[in] prio - The PFC priority. -+ -+@Param[in] wq - The Work Queue associated with the PFC priority. -+ -+@Cautions Allowed only after the port is initialized. -+*//***************************************************************************/ -+int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port, -+ uint8_t prio, uint8_t wq); -+#endif -+ -+/**************************************************************************//** -+@Function fm_mac_set_exception -+ -+@Description Set MAC exception state. -+ -+@Param[in] fm_mac_dev - A handle of the FM MAC device. -+@Param[in] exception - FM MAC exception type. -+@Param[in] enable - new state. -+ -+*//***************************************************************************/ -+int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev, -+ e_FmMacExceptions exception, bool enable); -+ -+int fm_mac_free(struct fm_mac_dev *fm_mac_dev); -+ -+struct fm_mac_dev *fm_mac_config(t_FmMacParams *params); -+ -+int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev, -+ int len); -+ -+int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable); -+ -+int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable); -+ -+int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable); -+ -+int fm_mac_init(struct fm_mac_dev *fm_mac_dev); -+ -+int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version); -+ -+int fm_mac_enable(struct fm_mac_dev *fm_mac_dev); -+ -+int fm_mac_disable(struct fm_mac_dev *fm_mac_dev); -+ -+int fm_mac_resume(struct fm_mac_dev *fm_mac_dev); -+ -+int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev, -+ bool enable); -+ -+int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev, -+ t_EnetAddr *mac_addr); -+ -+int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev, -+ t_EnetAddr *mac_addr); -+ -+int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev, -+ uint8_t *addr); -+ -+int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev, -+ bool link, int speed, bool duplex); -+ -+int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev); -+ -+int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev); -+ -+int fm_mac_set_rx_pause_frames( -+ struct fm_mac_dev *fm_mac_dev, bool en); -+ -+int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev, -+ bool en); -+ -+int fm_rtc_enable(struct fm *fm_dev); -+ -+int fm_rtc_disable(struct fm *fm_dev); -+ -+int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts); -+ -+int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts); -+ -+int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift); -+ -+int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift); -+ -+int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id, -+ uint64_t time); -+ -+int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id, -+ uint64_t fiper); -+ -+int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, -+ bool en); -+ -+/**************************************************************************//** -+@Function fm_macsec_set_exception -+ -+@Description Set MACSEC exception state. -+ -+@Param[in] fm_macsec_dev - A handle of the FM MACSEC device. -+@Param[in] exception - FM MACSEC exception type. -+@Param[in] enable - new state. -+ -+*//***************************************************************************/ -+ -+int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev, -+ fm_macsec_exception exception, bool enable); -+int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev); -+struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params); -+int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev); -+int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev -+ *fm_macsec_dev, -+ fm_macsec_unknown_sci_frame_treatment treat_mode); -+int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev, -+ bool deliver_uncontrolled); -+int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev, -+ bool discard_uncontrolled); -+int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev, -+ fm_macsec_untag_frame_treatment treat_mode); -+int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev, -+ uint32_t pnExhThr); -+int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev); -+int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev); -+int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev, -+ fm_macsec_exception exception, bool enable); -+int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev, -+ int *macsec_revision); -+int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev); -+int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev); -+ -+ -+int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ fm_macsec_secy_exception exception, -+ bool enable); -+int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev); -+struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params); -+int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev); -+int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ fm_macsec_sci_insertion_mode sci_insertion_mode); -+int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ bool protect_frames); -+int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ bool replay_protect, uint32_t replay_window); -+int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ fm_macsec_valid_frame_behavior validate_frames); -+int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ bool confidentiality_enable, -+ uint32_t confidentiality_offset); -+int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev); -+int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ fm_macsec_secy_event event, -+ bool enable); -+struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct fm_macsec_secy_sc_params *params); -+int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc); -+int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, macsec_an_t an, -+ uint32_t lowest_pn, macsec_sa_key_t key); -+int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, macsec_an_t an); -+int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, -+ macsec_an_t an); -+int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, -+ macsec_an_t an); -+int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, -+ macsec_an_t an, uint32_t updt_next_pn); -+int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, -+ macsec_an_t an, uint32_t updt_lowest_pn); -+int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, -+ macsec_an_t an, macsec_sa_key_t key); -+int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ macsec_an_t an, macsec_sa_key_t key); -+int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ macsec_an_t an); -+int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ macsec_an_t next_active_an, -+ macsec_sa_key_t key); -+int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ macsec_an_t an); -+int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ macsec_an_t *p_an); -+int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, uint32_t *sc_phys_id); -+int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ uint32_t *sc_phys_id); -+ -+/** @} */ /* end of FM_LnxKern_ctrl_grp group */ -+/** @} */ /* end of FM_LnxKern_grp group */ -+ -+/* default values for initializing PTP 1588 timer clock */ -+#define DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT 2 /* power of 2 for better performance */ -+#define DPA_PTP_NOMINAL_FREQ_PERIOD_NS (1 << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT) /* 4ns,250MHz */ -+ -+#endif /* __LNXWRP_FSL_FMAN_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h -@@ -0,0 +1,50 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __XX_H -+#define __XX_H -+ -+#include "xx_ext.h" -+ -+void * xx_Malloc(uint32_t n); -+void xx_Free(void *p); -+ -+void *xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t align); -+void xx_FreeSmart(void *p); -+ -+/* never used: */ -+#define GetDeviceName(irq) ((char *)NULL) -+ -+int GetDeviceIrqNum(int irq); -+ -+ -+#endif /* __XX_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile -@@ -0,0 +1,10 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+# -+ -+obj-y += sys_io.o ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c -@@ -0,0 +1,171 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+ -+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) -+#define MODVERSIONS -+#endif -+#ifdef MODVERSIONS -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+#include -+#else -+#include -+#endif /* LINUX_VERSION_CODE */ -+#endif /* MODVERSIONS */ -+ -+#include -+#include -+ -+#include -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "string_ext.h" -+#include "list_ext.h" -+#include "sys_io_ext.h" -+ -+ -+#define __ERR_MODULE__ MODULE_UNKNOWN -+ -+ -+typedef struct { -+ uint64_t virtAddr; -+ uint64_t physAddr; -+ uint32_t size; -+ t_List node; -+} t_IoMap; -+#define IOMAP_OBJECT(ptr) LIST_OBJECT(ptr, t_IoMap, node) -+ -+LIST(mapsList); -+ -+ -+static void EnqueueIoMap(t_IoMap *p_IoMap) -+{ -+ uint32_t intFlags; -+ -+ intFlags = XX_DisableAllIntr(); -+ LIST_AddToTail(&p_IoMap->node, &mapsList); -+ XX_RestoreAllIntr(intFlags); -+} -+ -+static t_IoMap * FindIoMapByVirtAddr(uint64_t addr) -+{ -+ t_IoMap *p_IoMap; -+ t_List *p_Pos; -+ -+ LIST_FOR_EACH(p_Pos, &mapsList) -+ { -+ p_IoMap = IOMAP_OBJECT(p_Pos); -+ if ((addr >= p_IoMap->virtAddr) && (addr < p_IoMap->virtAddr+p_IoMap->size)) -+ return p_IoMap; -+ } -+ -+ return NULL; -+} -+ -+static t_IoMap * FindIoMapByPhysAddr(uint64_t addr) -+{ -+ t_IoMap *p_IoMap; -+ t_List *p_Pos; -+ -+ LIST_FOR_EACH(p_Pos, &mapsList) -+ { -+ p_IoMap = IOMAP_OBJECT(p_Pos); -+ if ((addr >= p_IoMap->physAddr) && (addr < p_IoMap->physAddr+p_IoMap->size)) -+ return p_IoMap; -+ } -+ -+ return NULL; -+} -+ -+t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size) -+{ -+ t_IoMap *p_IoMap; -+ -+ p_IoMap = (t_IoMap*)XX_Malloc(sizeof(t_IoMap)); -+ if (!p_IoMap) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!")); -+ memset(p_IoMap, 0, sizeof(t_IoMap)); -+ -+ p_IoMap->virtAddr = virtAddr; -+ p_IoMap->physAddr = physAddr; -+ p_IoMap->size = size; -+ -+ INIT_LIST(&p_IoMap->node); -+ EnqueueIoMap(p_IoMap); -+ -+ return E_OK; -+} -+ -+t_Error SYS_UnregisterIoMap (uint64_t virtAddr) -+{ -+ t_IoMap *p_IoMap = FindIoMapByVirtAddr(virtAddr); -+ if (!p_IoMap) -+ RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!")); -+ -+ LIST_Del(&p_IoMap->node); -+ XX_Free(p_IoMap); -+ -+ return E_OK; -+} -+ -+uint64_t SYS_PhysToVirt(uint64_t addr) -+{ -+ t_IoMap *p_IoMap = FindIoMapByPhysAddr(addr); -+ if (p_IoMap) -+ { -+ /* This is optimization - put the latest in the list-head - like a cache */ -+ if (mapsList.p_Next != &p_IoMap->node) -+ { -+ uint32_t intFlags = XX_DisableAllIntr(); -+ LIST_DelAndInit(&p_IoMap->node); -+ LIST_Add(&p_IoMap->node, &mapsList); -+ XX_RestoreAllIntr(intFlags); -+ } -+ return (uint64_t)(addr - p_IoMap->physAddr + p_IoMap->virtAddr); -+ } -+ return PTR_TO_UINT(phys_to_virt((unsigned long)addr)); -+} -+ -+uint64_t SYS_VirtToPhys(uint64_t addr) -+{ -+ t_IoMap *p_IoMap; -+ -+ if (addr == 0) -+ return 0; -+ -+ p_IoMap = FindIoMapByVirtAddr(addr); -+ if (p_IoMap) -+ return (uint64_t)(addr - p_IoMap->virtAddr + p_IoMap->physAddr); -+ return (uint64_t)virt_to_phys(UINT_TO_PTR(addr)); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile -@@ -0,0 +1,19 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ -+NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc -+ -+ccflags-y += -I$(NCSW_FM_INC) -+ccflags-y += -I$(NET_DPA) -+ -+obj-y += fsl-ncsw-PFM.o -+obj-$(CONFIG_FSL_SDK_FMAN_TEST) += fman_test.o -+ -+fsl-ncsw-PFM-objs := lnxwrp_fm.o lnxwrp_fm_port.o lnxwrp_ioctls_fm.o \ -+ lnxwrp_sysfs.o lnxwrp_sysfs_fm.o lnxwrp_sysfs_fm_port.o -+obj-$(CONFIG_COMPAT) += lnxwrp_ioctls_fm_compat.o ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c -@@ -0,0 +1,1665 @@ -+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ @File fman_test.c -+ @Authors Pistirica Sorin Andrei -+ @Description FM Linux test environment -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* private headers */ -+#include "fm_ext.h" -+#include "lnxwrp_fsl_fman.h" -+#include "fm_port_ext.h" -+#if (DPAA_VERSION == 11) -+#include "../../Peripherals/FM/MAC/memac.h" -+#endif -+#include "fm_test_ioctls.h" -+#include "fsl_fman_test.h" -+ -+#include "dpaa_eth.h" -+#include "dpaa_eth_common.h" -+ -+#define FMT_FRM_WATERMARK 0xdeadbeefdeadbeeaLL -+ -+struct fmt_frame_s { -+ ioc_fmt_buff_desc_t buff; -+ struct list_head list; -+}; -+ -+struct fmt_fqs_s { -+ struct qman_fq fq_base; -+ bool init; -+ struct fmt_port_s *fmt_port_priv; -+}; -+ -+struct fmt_port_pcd_s { -+ int num_queues; -+ struct fmt_fqs_s *fmt_pcd_fqs; -+ uint32_t fqid_base; -+}; -+ -+/* char dev structure: fm test port */ -+struct fmt_port_s { -+ bool valid; -+ uint8_t id; -+ ioc_fmt_port_type port_type; -+ ioc_diag_mode diag; -+ bool compat_test_type; -+ -+ /* fm ports */ -+ /* ! for oh ports p_tx_fm_port_dev == p_rx_fm_port_dev && -+ * p_tx_port == p_rx_port */ -+ /* t_LnxWrpFmPortDev */ -+ struct fm_port *p_tx_port; -+ /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */ -+ void *p_tx_fm_port_dev; -+ /* t_LnxWrpFmPortDev */ -+ struct fm_port *p_rx_port; -+ /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */ -+ void *p_rx_fm_port_dev; -+ -+ void *p_mac_dev; -+ uint64_t fm_phys_base_addr; -+ -+ /* read/write queue manipulation */ -+ spinlock_t rx_q_lock; -+ struct list_head rx_q; -+ -+ /* tx queuee for injecting traffic */ -+ int num_of_tx_fqs; -+ struct fmt_fqs_s p_tx_fqs[FMAN_TEST_MAX_TX_FQS]; -+ -+ /* pcd private queues manipulation */ -+ struct fmt_port_pcd_s fmt_port_pcd; -+ -+ /* debugging stuff */ -+ -+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME) -+ atomic_t enqueue_to_qman_frm; -+ atomic_t enqueue_to_rxq; -+ atomic_t dequeue_from_rxq; -+ atomic_t not_enqueue_to_rxq_wrong_frm; -+#endif -+ -+}; -+ -+/* The devices. */ -+struct fmt_s { -+ int major; -+ struct fmt_port_s ports[IOC_FMT_MAX_NUM_OF_PORTS]; -+ struct class *fmt_class; -+}; -+ -+/* fm test structure */ -+static struct fmt_s fm_test; -+ -+#if (DPAA_VERSION == 11) -+struct mac_priv_s { -+ t_Handle mac; -+}; -+#endif -+ -+#define DTSEC_BASE_ADDR 0x000e0000 -+#define DTSEC_MEM_RANGE 0x00002000 -+#define MAC_1G_MACCFG1 0x00000100 -+#define MAC_1G_LOOP_MASK 0x00000100 -+static int set_1gmac_loopback( -+ struct fmt_port_s *fmt_port, -+ bool en) -+{ -+#if (DPAA_VERSION <= 10) -+ uint32_t dtsec_idx = fmt_port->id; /* dtsec for which port */ -+ uint32_t dtsec_idx_off = dtsec_idx * DTSEC_MEM_RANGE; -+ phys_addr_t maccfg1_hw; -+ void *maccfg1_map; -+ uint32_t maccfg1_val; -+ -+ /* compute the maccfg1 register address */ -+ maccfg1_hw = fmt_port->fm_phys_base_addr + -+ (phys_addr_t)(DTSEC_BASE_ADDR + -+ dtsec_idx_off + -+ MAC_1G_MACCFG1); -+ -+ /* map register */ -+ maccfg1_map = ioremap(maccfg1_hw, sizeof(u32)); -+ -+ /* set register */ -+ maccfg1_val = in_be32(maccfg1_map); -+ if (en) -+ maccfg1_val |= MAC_1G_LOOP_MASK; -+ else -+ maccfg1_val &= ~MAC_1G_LOOP_MASK; -+ out_be32(maccfg1_map, maccfg1_val); -+ -+ /* unmap register */ -+ iounmap(maccfg1_map); -+#else -+ struct mac_device *mac_dev; -+ struct mac_priv_s *priv; -+ t_Memac *p_memac; -+ -+ if (!fmt_port) -+ return -EINVAL; -+ -+ mac_dev = (struct mac_device *)fmt_port->p_mac_dev; -+ -+ if (!mac_dev) -+ return -EINVAL; -+ -+ priv = macdev_priv(mac_dev); -+ -+ if (!priv) -+ return -EINVAL; -+ -+ p_memac = priv->mac; -+ -+ if (!p_memac) -+ return -EINVAL; -+ -+ memac_set_loopback(p_memac->p_MemMap, en); -+#endif -+ return 0; -+} -+ -+/* TODO: re-write this function */ -+static int set_10gmac_int_loopback( -+ struct fmt_port_s *fmt_port, -+ bool en) -+{ -+#ifndef FM_10G_MAC_NO_CTRL_LOOPBACK -+#define FM_10GMAC0_OFFSET 0x000f0000 -+#define FM_10GMAC_CMD_CONF_CTRL_OFFSET 0x8 -+#define CMD_CFG_LOOPBACK_EN 0x00000400 -+ -+ uint64_t base_addr, reg_addr; -+ uint32_t tmp_val; -+ -+ base_addr = fmt_port->fm_phys_base_addr + (FM_10GMAC0_OFFSET + -+ ((fmt_port->id-FM_MAX_NUM_OF_1G_RX_PORTS)*0x2000)); -+ -+ base_addr = PTR_TO_UINT(ioremap(base_addr, 0x1000)); -+ -+ reg_addr = base_addr + FM_10GMAC_CMD_CONF_CTRL_OFFSET; -+ tmp_val = GET_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr))); -+ if (en) -+ tmp_val |= CMD_CFG_LOOPBACK_EN; -+ else -+ tmp_val &= ~CMD_CFG_LOOPBACK_EN; -+ WRITE_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)), tmp_val); -+ -+ iounmap(UINT_TO_PTR(base_addr)); -+ -+ return 0; -+#else -+ _fmt_err("TGEC don't have internal-loopback.\n"); -+ return -EPERM; -+#endif -+} -+ -+static int set_mac_int_loopback(struct fmt_port_s *fmt_port, bool en) -+{ -+ int _err = 0; -+ -+ switch (fmt_port->port_type) { -+ -+ case e_IOC_FMT_PORT_T_RXTX: -+ /* 1G port */ -+ if (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS) -+ _err = set_1gmac_loopback(fmt_port, en); -+ /* 10g port */ -+ else if ((fmt_port->id >= FM_MAX_NUM_OF_1G_RX_PORTS) && -+ (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS + -+ FM_MAX_NUM_OF_10G_RX_PORTS)) { -+ -+ _err = set_10gmac_int_loopback(fmt_port, en); -+ } else -+ _err = -EINVAL; -+ break; -+ /* op port does not have MAC (loopback mode) */ -+ case e_IOC_FMT_PORT_T_OP: -+ -+ _err = 0; -+ break; -+ default: -+ -+ _err = -EPERM; -+ break; -+ } -+ -+ return _err; -+} -+ -+static void enqueue_fmt_frame( -+ struct fmt_port_s *fmt_port, -+ struct fmt_frame_s *p_fmt_frame) -+{ -+ spinlock_t *rx_q_lock = NULL; -+ -+ rx_q_lock = &fmt_port->rx_q_lock; -+ -+ spin_lock(rx_q_lock); -+ list_add_tail(&p_fmt_frame->list, &fmt_port->rx_q); -+ spin_unlock(rx_q_lock); -+ -+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME) -+ atomic_inc(&fmt_port->enqueue_to_rxq); -+#endif -+} -+ -+static struct fmt_frame_s *dequeue_fmt_frame( -+ struct fmt_port_s *fmt_port) -+{ -+ struct fmt_frame_s *p_fmt_frame = NULL; -+ spinlock_t *rx_q_lock = NULL; -+ -+ rx_q_lock = &fmt_port->rx_q_lock; -+ -+ spin_lock(rx_q_lock); -+ -+#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member) -+ -+ if (!list_empty(&fmt_port->rx_q)) { -+ p_fmt_frame = list_last_entry(&fmt_port->rx_q, -+ struct fmt_frame_s, -+ list); -+ list_del(&p_fmt_frame->list); -+ -+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME) -+ atomic_inc(&fmt_port->dequeue_from_rxq); -+#endif -+ } -+ -+ spin_unlock(rx_q_lock); -+ -+ return p_fmt_frame; -+} -+ -+/* eth-dev -to- fmt port association */ -+struct fmt_port_s *match_dpa_to_fmt_port( -+ struct dpa_priv_s *dpa_priv) { -+ struct mac_device *mac_dev = dpa_priv->mac_dev; -+ struct fm_port *fm_port = (struct fm_port *) mac_dev; -+ struct fmt_port_s *fmt_port = NULL; -+ int i; -+ -+ _fmt_dbgr("calling...\n"); -+ -+ /* find the FM-test-port object */ -+ for (i = 0; i < IOC_FMT_MAX_NUM_OF_PORTS; i++) -+ if ((fm_test.ports[i].p_mac_dev && -+ mac_dev == fm_test.ports[i].p_mac_dev) || -+ fm_port == fm_test.ports[i].p_tx_port) { -+ -+ fmt_port = &fm_test.ports[i]; -+ break; -+ } -+ -+ _fmt_dbgr("called\n"); -+ return fmt_port; -+} -+ -+void dump_frame( -+ uint8_t *buffer, -+ uint32_t size) -+{ -+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME) -+ unsigned int i; -+ -+ for (i = 0; i < size; i++) { -+ if (i%16 == 0) -+ printk(KERN_DEBUG "\n"); -+ printk(KERN_DEBUG "%2x ", *(buffer+i)); -+ } -+#endif -+ return; -+} -+ -+bool test_and_steal_frame(struct fmt_port_s *fmt_port, -+ uint32_t fqid, -+ uint8_t *buffer, -+ uint32_t size) -+{ -+ struct fmt_frame_s *p_fmt_frame = NULL; -+ bool test_and_steal_frame_frame; -+ uint32_t data_offset; -+ uint32_t i; -+ -+ _fmt_dbgr("calling...\n"); -+ -+ if (!fmt_port || !fmt_port->p_rx_fm_port_dev) -+ return false; -+ -+ /* check watermark */ -+ test_and_steal_frame_frame = false; -+ for (i = 0; i < size; i++) { -+ uint64_t temp = *((uint64_t *)(buffer + i)); -+ -+ if (temp == (uint64_t) FMT_FRM_WATERMARK) { -+ _fmt_dbgr("watermark found!\n"); -+ test_and_steal_frame_frame = true; -+ break; -+ } -+ } -+ -+ if (!test_and_steal_frame_frame) { -+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME) -+ atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm); -+#endif -+ _fmt_dbgr("NOT watermark found!\n"); -+ return false; -+ } -+ -+ /* do not enqueue the tx conf/err frames */ -+ if ((fqid == FMT_TX_CONF_Q) || (fqid == FMT_TX_ERR_Q)) -+ goto _test_and_steal_frame_return_true; -+ -+ _fmt_dbgr("on port %d got FMUC frame\n", fmt_port->id); -+ data_offset = FM_PORT_GetBufferDataOffset( -+ fmt_port->p_rx_fm_port_dev); -+ -+ p_fmt_frame = kmalloc(sizeof(struct fmt_frame_s), GFP_KERNEL); -+ -+ /* dump frame... no more space left on device */ -+ if (p_fmt_frame == NULL) { -+ _fmt_err("no space left on device!\n"); -+ goto _test_and_steal_frame_return_true; -+ } -+ -+ memset(p_fmt_frame, 0, sizeof(struct fmt_frame_s)); -+ p_fmt_frame->buff.p_data = kmalloc(size * sizeof(uint8_t), GFP_KERNEL); -+ -+ /* No more space left on device*/ -+ if (p_fmt_frame->buff.p_data == NULL) { -+ _fmt_err("no space left on device!\n"); -+ kfree(p_fmt_frame); -+ goto _test_and_steal_frame_return_true; -+ } -+ -+ p_fmt_frame->buff.size = size-data_offset; -+ p_fmt_frame->buff.qid = fqid; -+ -+ memcpy(p_fmt_frame->buff.p_data, -+ (uint8_t *)PTR_MOVE(buffer, data_offset), -+ p_fmt_frame->buff.size); -+ -+ memcpy(p_fmt_frame->buff.buff_context.fm_prs_res, -+ FM_PORT_GetBufferPrsResult(fmt_port->p_rx_fm_port_dev, -+ (char *)buffer), -+ 32); -+ -+ /* enqueue frame - this frame will go to us */ -+ enqueue_fmt_frame(fmt_port, p_fmt_frame); -+ -+_test_and_steal_frame_return_true: -+ return true; -+} -+ -+static int fmt_fq_release(const struct qm_fd *fd) -+{ -+ struct dpa_bp *_dpa_bp; -+ struct bm_buffer _bmb; -+ -+ if (fd->format == qm_fd_contig) { -+ _dpa_bp = dpa_bpid2pool(fd->bpid); -+ BUG_ON(IS_ERR(_dpa_bp)); -+ -+ _bmb.hi = fd->addr_hi; -+ _bmb.lo = fd->addr_lo; -+ -+ while (bman_release(_dpa_bp->pool, &_bmb, 1, 0)) -+ cpu_relax(); -+ -+ } else { -+ _fmt_err("frame not supported !\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+/* sync it w/ dpaa_eth.c: DPA_BP_HEAD */ -+#define DPA_BP_HEADROOM (DPA_TX_PRIV_DATA_SIZE + \ -+ fm_get_rx_extra_headroom() + \ -+ DPA_PARSE_RESULTS_SIZE + \ -+ DPA_HASH_RESULTS_SIZE) -+#define MAC_HEADER_LENGTH 14 -+#define L2_AND_HEADROOM_OFF ((DPA_BP_HEADROOM) + (MAC_HEADER_LENGTH)) -+ -+/* dpa ingress hooks definition */ -+enum dpaa_eth_hook_result fmt_rx_default_hook( -+ struct sk_buff *skb, -+ struct net_device *net_dev, -+ u32 fqid) -+{ -+ struct dpa_priv_s *dpa_priv = NULL; -+ struct fmt_port_s *fmt_port = NULL; -+ uint8_t *buffer; -+ uint32_t buffer_len; -+ -+ _fmt_dbgr("calling...\n"); -+ -+ dpa_priv = netdev_priv(net_dev); -+ fmt_port = match_dpa_to_fmt_port(dpa_priv); -+ -+ /* conversion from skb to fd: -+ * skb cames processed for L3, so we need to go back for -+ * layer 2 offset */ -+ buffer = (uint8_t *)(skb->data - ((int)L2_AND_HEADROOM_OFF)); -+ buffer_len = skb->len + ((int)L2_AND_HEADROOM_OFF); -+ -+ /* if is not out frame let dpa to handle it */ -+ if (test_and_steal_frame(fmt_port, -+ FMT_RX_DFLT_Q, -+ buffer, -+ buffer_len)) -+ goto _fmt_rx_default_hook_stolen; -+ -+ _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n"); -+ return DPAA_ETH_CONTINUE; -+ -+_fmt_rx_default_hook_stolen: -+ dev_kfree_skb(skb); -+ -+ _fmt_dbgr("called:DPAA_ETH_STOLEN.\n"); -+ return DPAA_ETH_STOLEN; -+} -+ -+enum dpaa_eth_hook_result fmt_rx_error_hook( -+ struct net_device *net_dev, -+ const struct qm_fd *fd, -+ u32 fqid) -+{ -+ struct dpa_priv_s *dpa_priv = NULL; -+ struct dpa_bp *dpa_bp = NULL; -+ struct fmt_port_s *fmt_port = NULL; -+ void *fd_virt_addr = NULL; -+ dma_addr_t addr = qm_fd_addr(fd); -+ -+ _fmt_dbgr("calling...\n"); -+ -+ dpa_priv = netdev_priv(net_dev); -+ fmt_port = match_dpa_to_fmt_port(dpa_priv); -+ -+ /* dpaa doesn't do this... we have to do it here */ -+ dpa_bp = dpa_bpid2pool(fd->bpid); -+ dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL); -+ -+ fd_virt_addr = phys_to_virt(addr); -+ /* if is not out frame let dpa to handle it */ -+ if (test_and_steal_frame(fmt_port, -+ FMT_RX_ERR_Q, -+ fd_virt_addr, -+ fd->length20 + fd->offset)) { -+ goto _fmt_rx_error_hook_stolen; -+ } -+ -+ _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n"); -+ return DPAA_ETH_CONTINUE; -+ -+_fmt_rx_error_hook_stolen: -+ /* the frame data doesn't matter, -+ * so, no mapping is needed */ -+ fmt_fq_release(fd); -+ -+ _fmt_dbgr("called:DPAA_ETH_STOLEN.\n"); -+ return DPAA_ETH_STOLEN; -+} -+ -+enum dpaa_eth_hook_result fmt_tx_confirm_hook( -+ struct net_device *net_dev, -+ const struct qm_fd *fd, -+ u32 fqid) -+{ -+ struct dpa_priv_s *dpa_priv = NULL; -+ struct fmt_port_s *fmt_port = NULL; -+ dma_addr_t addr = qm_fd_addr(fd); -+ void *fd_virt_addr = NULL; -+ uint32_t fd_len = 0; -+ -+ _fmt_dbgr("calling...\n"); -+ -+ dpa_priv = netdev_priv(net_dev); -+ fmt_port = match_dpa_to_fmt_port(dpa_priv); -+ -+ fd_virt_addr = phys_to_virt(addr); -+ fd_len = fd->length20 + fd->offset; -+ -+ if (fd_len > fm_get_max_frm()) { -+ _fmt_err("tx confirm bad frame size: %u!\n", fd_len); -+ goto _fmt_tx_confirm_hook_continue; -+ } -+ -+ if (test_and_steal_frame(fmt_port, -+ FMT_TX_CONF_Q, -+ fd_virt_addr, -+ fd_len)) -+ goto _fmt_tx_confirm_hook_stolen; -+ -+_fmt_tx_confirm_hook_continue: -+ _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n"); -+ return DPAA_ETH_CONTINUE; -+ -+_fmt_tx_confirm_hook_stolen: -+ kfree(fd_virt_addr); -+ -+ _fmt_dbgr("called:DPAA_ETH_STOLEN.\n"); -+ return DPAA_ETH_STOLEN; -+} -+ -+enum dpaa_eth_hook_result fmt_tx_confirm_error_hook( -+ struct net_device *net_dev, -+ const struct qm_fd *fd, -+ u32 fqid) -+{ -+ struct dpa_priv_s *dpa_priv = NULL; -+ struct fmt_port_s *fmt_port = NULL; -+ dma_addr_t addr = qm_fd_addr(fd); -+ void *fd_virt_addr = NULL; -+ uint32_t fd_len = 0; -+ -+ _fmt_dbgr("calling...\n"); -+ -+ dpa_priv = netdev_priv(net_dev); -+ fmt_port = match_dpa_to_fmt_port(dpa_priv); -+ -+ fd_virt_addr = phys_to_virt(addr); -+ fd_len = fd->length20 + fd->offset; -+ -+ if (fd_len > fm_get_max_frm()) { -+ _fmt_err("tx confirm err bad frame size: %u !\n", fd_len); -+ goto _priv_ingress_tx_err_continue; -+ } -+ -+ if (test_and_steal_frame(fmt_port, FMT_TX_ERR_Q, fd_virt_addr, fd_len)) -+ goto _priv_ingress_tx_err_stolen; -+ -+_priv_ingress_tx_err_continue: -+ _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n"); -+ return DPAA_ETH_CONTINUE; -+ -+_priv_ingress_tx_err_stolen: -+ kfree(fd_virt_addr); -+ -+ _fmt_dbgr("called:DPAA_ETH_STOLEN.\n"); -+ return DPAA_ETH_STOLEN; -+} -+ -+/* egress callbacks definition */ -+enum qman_cb_dqrr_result fmt_egress_dqrr( -+ struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry *dqrr) -+{ -+ /* this callback should never be called */ -+ BUG(); -+ return qman_cb_dqrr_consume; -+} -+ -+static void fmt_egress_error_dqrr( -+ struct qman_portal *p, -+ struct qman_fq *fq, -+ const struct qm_mr_entry *msg) -+{ -+ uint8_t *fd_virt_addr = NULL; -+ -+ /* tx failure, on the ern callback - release buffer */ -+ fd_virt_addr = (uint8_t *)phys_to_virt(qm_fd_addr(&msg->ern.fd)); -+ kfree(fd_virt_addr); -+ -+ return; -+} -+ -+static const struct qman_fq fmt_egress_fq = { -+ .cb = { .dqrr = fmt_egress_dqrr, -+ .ern = fmt_egress_error_dqrr, -+ .fqs = NULL} -+}; -+ -+int fmt_fq_alloc( -+ struct fmt_fqs_s *fmt_fqs, -+ const struct qman_fq *qman_fq, -+ uint32_t fqid, uint32_t flags, -+ uint16_t channel, uint8_t wq) -+{ -+ int _errno = 0; -+ -+ _fmt_dbg("calling...\n"); -+ -+ fmt_fqs->fq_base = *qman_fq; -+ -+ if (fqid == 0) { -+ flags |= QMAN_FQ_FLAG_DYNAMIC_FQID; -+ flags &= ~QMAN_FQ_FLAG_NO_MODIFY; -+ } else -+ flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID; -+ -+ fmt_fqs->init = !(flags & QMAN_FQ_FLAG_NO_MODIFY); -+ -+ _errno = qman_create_fq(fqid, flags, &fmt_fqs->fq_base); -+ if (_errno < 0) { -+ _fmt_err("frame queues create failed.\n"); -+ return -EINVAL; -+ } -+ -+ if (fmt_fqs->init) { -+ struct qm_mcc_initfq initfq; -+ -+ initfq.we_mask = QM_INITFQ_WE_DESTWQ; -+ initfq.fqd.dest.channel = channel; -+ initfq.fqd.dest.wq = wq; -+ -+ _errno = qman_init_fq(&fmt_fqs->fq_base, -+ QMAN_INITFQ_FLAG_SCHED, -+ &initfq); -+ if (_errno < 0) { -+ _fmt_err("frame queues init erorr.\n"); -+ qman_destroy_fq(&fmt_fqs->fq_base, 0); -+ return -EINVAL; -+ } -+ } -+ -+ _fmt_dbg("called.\n"); -+ return 0; -+} -+ -+static int fmt_fq_free(struct fmt_fqs_s *fmt_fq) -+{ -+ int _err = 0; -+ -+ _fmt_dbg("calling...\n"); -+ -+ if (fmt_fq->init) { -+ _err = qman_retire_fq(&fmt_fq->fq_base, NULL); -+ if (unlikely(_err < 0)) -+ _fmt_err("qman_retire_fq(%u) = %d\n", -+ qman_fq_fqid(&fmt_fq->fq_base), _err); -+ -+ _err = qman_oos_fq(&fmt_fq->fq_base); -+ if (unlikely(_err < 0)) -+ _fmt_err("qman_oos_fq(%u) = %d\n", -+ qman_fq_fqid(&fmt_fq->fq_base), _err); -+ } -+ -+ qman_destroy_fq(&fmt_fq->fq_base, 0); -+ -+ _fmt_dbg("called.\n"); -+ return _err; -+} -+ -+/* private pcd dqrr calbacks */ -+static enum qman_cb_dqrr_result fmt_pcd_dqrr( -+ struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry *dq) -+{ -+ struct dpa_bp *dpa_bp = NULL; -+ dma_addr_t addr = qm_fd_addr(&dq->fd); -+ uint8_t *fd_virt_addr = NULL; -+ struct fmt_port_s *fmt_port; -+ struct fmt_port_pcd_s *fmt_port_pcd; -+ uint32_t relative_fqid = 0; -+ uint32_t fd_len = 0; -+ -+ _fmt_dbgr("calling...\n"); -+ -+ /* upcast - from pcd_alloc_fq */ -+ fmt_port = ((struct fmt_fqs_s *)fq)->fmt_port_priv; -+ if (!fmt_port) { -+ _fmt_err(" wrong fmt port -to- fq match.\n"); -+ goto _fmt_pcd_dqrr_return; -+ } -+ fmt_port_pcd = &fmt_port->fmt_port_pcd; -+ -+ relative_fqid = dq->fqid - fmt_port_pcd->fqid_base; -+ _fmt_dbgr("pcd dqrr got frame on relative fq:%u@base:%u\n", -+ relative_fqid, fmt_port_pcd->fqid_base); -+ -+ fd_len = dq->fd.length20 + dq->fd.offset; -+ -+ if (fd_len > fm_get_max_frm()) { -+ _fmt_err("pcd dqrr wrong frame size: %u (%u:%u)!\n", -+ fd_len, dq->fd.length20, dq->fd.offset); -+ goto _fmt_pcd_dqrr_return; -+ } -+ -+ dpa_bp = dpa_bpid2pool(dq->fd.bpid); -+ dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL); -+ -+ fd_virt_addr = phys_to_virt(addr); -+ if (!test_and_steal_frame(fmt_port, relative_fqid, fd_virt_addr, -+ fd_len)) { -+ -+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME) -+ atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm); -+#endif -+ _fmt_wrn("pcd dqrr unrecognized frame@fqid: %u," -+ " frame len: %u (dropped).\n", -+ dq->fqid, dq->fd.length20); -+ dump_frame(fd_virt_addr, fd_len); -+ } -+ -+_fmt_pcd_dqrr_return: -+ /* no need to map again here */ -+ fmt_fq_release(&dq->fd); -+ -+ _fmt_dbgr("calle.\n"); -+ return qman_cb_dqrr_consume; -+} -+ -+static void fmt_pcd_err_dqrr( -+ struct qman_portal *qm, -+ struct qman_fq *fq, -+ const struct qm_mr_entry *msg) -+{ -+ _fmt_err("this callback should never be called.\n"); -+ BUG(); -+ return; -+} -+ -+static void fmt_pcd_fqs_dqrr( -+ struct qman_portal *qm, -+ struct qman_fq *fq, -+ const struct qm_mr_entry *msg) -+{ -+ _fmt_dbg(" fq state(0x%x)@fqid(%u.\n", msg->fq.fqs, msg->fq.fqid); -+ return; -+} -+ -+/* private pcd queue template */ -+static const struct qman_fq pcd_fq = { -+ .cb = { .dqrr = fmt_pcd_dqrr, -+ .ern = fmt_pcd_err_dqrr, -+ .fqs = fmt_pcd_fqs_dqrr} -+}; -+ -+/* defined as weak in dpaa driver. */ -+/* ! parameters come from IOCTL call - US */ -+int dpa_alloc_pcd_fqids( -+ struct device *dev, -+ uint32_t num, uint8_t alignment, -+ uint32_t *base_fqid) -+{ -+ int _err = 0, i; -+ struct net_device *net_dev = NULL; -+ struct dpa_priv_s *dpa_priv = NULL; -+ struct fmt_port_pcd_s *fmt_port_pcd = NULL; -+ struct fmt_fqs_s *fmt_fqs = NULL; -+ struct fmt_port_s *fmt_port = NULL; -+ int num_allocated = 0; -+ -+ _fmt_dbg("calling...\n"); -+ -+ net_dev = (typeof(net_dev))dev_get_drvdata(dev); -+ dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev); -+ -+ if (!netif_msg_probe(dpa_priv)) { -+ _fmt_err("dpa not probe.\n"); -+ _err = -ENODEV; -+ goto _pcd_alloc_fqs_err; -+ } -+ -+ fmt_port = match_dpa_to_fmt_port(dpa_priv); -+ if (!fmt_port) { -+ _fmt_err("fmt port not found."); -+ _err = -EINVAL; -+ goto _pcd_alloc_fqs_err; -+ } -+ -+ fmt_port_pcd = &fmt_port->fmt_port_pcd; -+ -+ num_allocated = qman_alloc_fqid_range(base_fqid, num, alignment, 0); -+ -+ if ((num_allocated <= 0) || -+ (num_allocated < num) || -+ (alignment && (*base_fqid) % alignment)) { -+ *base_fqid = 0; -+ _fmt_err("Failed to alloc pcd fqs rang.\n"); -+ _err = -EINVAL; -+ goto _pcd_alloc_fqs_err; -+ } -+ -+ _fmt_dbg("wanted %d fqs(align %d), got %d fqids@%u.\n", -+ num, alignment, num_allocated, *base_fqid); -+ -+ /* alloc pcd queues */ -+ fmt_port_pcd->fmt_pcd_fqs = kmalloc(num_allocated * -+ sizeof(struct fmt_fqs_s), -+ GFP_KERNEL); -+ fmt_port_pcd->num_queues = num_allocated; -+ fmt_port_pcd->fqid_base = *base_fqid; -+ fmt_fqs = fmt_port_pcd->fmt_pcd_fqs; -+ -+ /* alloc the pcd queues */ -+ for (i = 0; i < num_allocated; i++, fmt_fqs++) { -+ _err = fmt_fq_alloc( -+ fmt_fqs, -+ &pcd_fq, -+ (*base_fqid) + i, QMAN_FQ_FLAG_NO_ENQUEUE, -+ dpa_priv->channel, 7); -+ -+ if (_err < 0) -+ goto _pcd_alloc_fqs_err; -+ -+ /* upcast to identify from where the frames came from */ -+ fmt_fqs->fmt_port_priv = fmt_port; -+ } -+ -+ _fmt_dbg("called.\n"); -+ return _err; -+_pcd_alloc_fqs_err: -+ if (num_allocated > 0) -+ qman_release_fqid_range(*base_fqid, num_allocated); -+ /*TODO: free fmt_pcd_fqs if are any */ -+ -+ _fmt_dbg("called(_err:%d).\n", _err); -+ return _err; -+} -+ -+/* defined as weak in dpaa driver. */ -+int dpa_free_pcd_fqids( -+ struct device *dev, -+ uint32_t base_fqid) -+{ -+ -+ int _err = 0, i; -+ struct net_device *net_dev = NULL; -+ struct dpa_priv_s *dpa_priv = NULL; -+ struct fmt_port_pcd_s *fmt_port_pcd = NULL; -+ struct fmt_fqs_s *fmt_fqs = NULL; -+ struct fmt_port_s *fmt_port = NULL; -+ int num_allocated = 0; -+ -+ _fmt_dbg("calling...\n"); -+ -+ net_dev = (typeof(net_dev))dev_get_drvdata(dev); -+ dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev); -+ -+ if (!netif_msg_probe(dpa_priv)) { -+ _fmt_err("dpa not probe.\n"); -+ _err = -ENODEV; -+ goto _pcd_free_fqs_err; -+ } -+ -+ fmt_port = match_dpa_to_fmt_port(dpa_priv); -+ if (!fmt_port) { -+ _fmt_err("fmt port not found."); -+ _err = -EINVAL; -+ goto _pcd_free_fqs_err; -+ } -+ -+ fmt_port_pcd = &fmt_port->fmt_port_pcd; -+ num_allocated = fmt_port_pcd->num_queues; -+ fmt_fqs = fmt_port_pcd->fmt_pcd_fqs; -+ -+ for (i = 0; i < num_allocated; i++, fmt_fqs++) -+ fmt_fq_free(fmt_fqs); -+ -+ qman_release_fqid_range(base_fqid,num_allocated); -+ -+ kfree(fmt_port_pcd->fmt_pcd_fqs); -+ memset(fmt_port_pcd, 0, sizeof(*fmt_port_pcd)); -+ -+ /* debugging stuff */ -+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME) -+ _fmt_dbg(" portid: %u.\n", fmt_port->id); -+ _fmt_dbg(" frames enqueue to qman: %u.\n", -+ atomic_read(&fmt_port->enqueue_to_qman_frm)); -+ _fmt_dbg(" frames enqueue to rxq: %u.\n", -+ atomic_read(&fmt_port->enqueue_to_rxq)); -+ _fmt_dbg(" frames dequeue from rxq: %u.\n", -+ atomic_read(&fmt_port->dequeue_from_rxq)); -+ _fmt_dbg(" frames not enqueue to rxq - wrong frm: %u.\n", -+ atomic_read(&fmt_port->not_enqueue_to_rxq_wrong_frm)); -+ atomic_set(&fmt_port->enqueue_to_qman_frm, 0); -+ atomic_set(&fmt_port->enqueue_to_rxq, 0); -+ atomic_set(&fmt_port->dequeue_from_rxq, 0); -+ atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0); -+#endif -+ return 0; -+ -+_pcd_free_fqs_err: -+ return _err; -+} -+ -+static int fmt_port_init( -+ struct fmt_port_s *fmt_port, -+ ioc_fmt_port_param_t *p_Params) -+{ -+ struct device_node *fm_node, *fm_port_node; -+ const uint32_t *uint32_prop; -+ int _errno = 0, lenp = 0, i; -+ static struct of_device_id fm_node_of_match[] = { -+ { .compatible = "fsl,fman", }, -+ { /* end of list */ }, -+ }; -+ -+ _fmt_dbg("calling...\n"); -+ -+ /* init send/receive tu US list */ -+ INIT_LIST_HEAD(&fmt_port->rx_q); -+ -+ /* check parameters */ -+ if (p_Params->num_tx_queues > FMAN_TEST_MAX_TX_FQS || -+ p_Params->fm_port_id > IOC_FMT_MAX_NUM_OF_PORTS) { -+ _fmt_dbg("wrong test parameters.\n"); -+ return -EINVAL; -+ } -+ -+ /* set port parameters */ -+ fmt_port->num_of_tx_fqs = p_Params->num_tx_queues; -+ fmt_port->id = p_Params->fm_port_id; -+ fmt_port->port_type = p_Params->fm_port_type; -+ fmt_port->diag = e_IOC_DIAG_MODE_NONE; -+ -+ /* init debugging stuff */ -+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME) -+ atomic_set(&fmt_port->enqueue_to_qman_frm, 0); -+ atomic_set(&fmt_port->enqueue_to_rxq, 0); -+ atomic_set(&fmt_port->dequeue_from_rxq, 0); -+ atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0); -+#endif -+ -+ /* TODO: This should be done at probe time not at runtime -+ * very ugly function */ -+ /* fill fmt port properties from dts */ -+ for_each_matching_node(fm_node, fm_node_of_match) { -+ -+ uint32_prop = (uint32_t *)of_get_property(fm_node, -+ "cell-index", &lenp); -+ if (unlikely(uint32_prop == NULL)) { -+ _fmt_wrn("of_get_property(%s, cell-index) invalid", -+ fm_node->full_name); -+ return -EINVAL; -+ } -+ if (WARN_ON(lenp != sizeof(uint32_t))) { -+ _fmt_wrn("of_get_property(%s, cell-index) invalid", -+ fm_node->full_name); -+ return -EINVAL; -+ } -+ -+ if (*uint32_prop == p_Params->fm_id) { -+ struct resource res; -+ -+ /* Get the FM address */ -+ _errno = of_address_to_resource(fm_node, 0, &res); -+ if (unlikely(_errno < 0)) { -+ _fmt_wrn("of_address_to_resource() = %u.\n", _errno); -+ return -EINVAL; -+ } -+ -+ fmt_port->fm_phys_base_addr = res.start; -+ -+ for_each_child_of_node(fm_node, fm_port_node) { -+ struct platform_device *of_dev; -+ -+ if (!of_device_is_available(fm_port_node)) -+ continue; -+ -+ uint32_prop = (uint32_t *)of_get_property( -+ fm_port_node, -+ "cell-index", -+ &lenp); -+ if (uint32_prop == NULL) -+ continue; -+ -+ if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-port-oh") && -+ (fmt_port->port_type == e_IOC_FMT_PORT_T_OP)) { -+ -+ if (*uint32_prop == fmt_port->id) { -+ of_dev = of_find_device_by_node(fm_port_node); -+ if (unlikely(of_dev == NULL)) { -+ _fmt_wrn("fm id invalid\n"); -+ return -EINVAL; -+ } -+ -+ fmt_port->p_tx_port = -+ fm_port_bind(&of_dev->dev); -+ fmt_port->p_tx_fm_port_dev = -+ (void *)fm_port_get_handle( -+ fmt_port->p_tx_port); -+ fmt_port->p_rx_port = -+ fmt_port->p_tx_port; -+ fmt_port->p_rx_fm_port_dev = -+ fmt_port->p_tx_fm_port_dev; -+ fmt_port->p_mac_dev = NULL; -+ break; -+ } -+ } else if ((*uint32_prop == fmt_port->id) && -+ fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) { -+ -+ of_dev = of_find_device_by_node(fm_port_node); -+ if (unlikely(of_dev == NULL)) { -+ _fmt_wrn("dtb fm id invalid value"); -+ return -EINVAL; -+ } -+ -+ if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-port-1g-tx")) { -+ fmt_port->p_tx_port = -+ fm_port_bind(&of_dev->dev); -+ fmt_port->p_tx_fm_port_dev = (void *) -+ fm_port_get_handle( -+ fmt_port->p_tx_port); -+ } else if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-port-1g-rx")) { -+ fmt_port->p_rx_port = -+ fm_port_bind(&of_dev->dev); -+ fmt_port->p_rx_fm_port_dev = (void *) -+ fm_port_get_handle( -+ fmt_port->p_rx_port); -+ } else if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-1g-mac") || -+ of_device_is_compatible(fm_port_node, -+ "fsl,fman-memac")) -+ fmt_port->p_mac_dev = -+ (typeof(fmt_port->p_mac_dev)) -+ dev_get_drvdata(&of_dev->dev); -+ else -+ continue; -+ -+ if (fmt_port->p_tx_fm_port_dev && -+ fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev) -+ break; -+ } else if (((*uint32_prop + FM_MAX_NUM_OF_1G_RX_PORTS) == -+ fmt_port->id) && -+ fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) { -+ -+ of_dev = of_find_device_by_node(fm_port_node); -+ if (unlikely(of_dev == NULL)) { -+ _fmt_wrn("dtb fm id invalid value\n"); -+ return -EINVAL; -+ } -+ -+ if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-port-10g-tx")) { -+ fmt_port->p_tx_port = -+ fm_port_bind(&of_dev->dev); -+ fmt_port->p_tx_fm_port_dev = (void *) -+ fm_port_get_handle( -+ fmt_port->p_tx_port); -+ } else if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-port-10g-rx")) { -+ fmt_port->p_rx_port = -+ fm_port_bind(&of_dev->dev); -+ fmt_port->p_rx_fm_port_dev = (void *) -+ fm_port_get_handle( -+ fmt_port->p_rx_port); -+ } else if (of_device_is_compatible(fm_port_node, -+ "fsl,fman-10g-mac") || -+ of_device_is_compatible(fm_port_node, -+ "fsl,fman-memac")) -+ fmt_port->p_mac_dev = -+ (typeof(fmt_port->p_mac_dev)) -+ dev_get_drvdata(&of_dev->dev); -+ else -+ continue; -+ -+ if (fmt_port->p_tx_fm_port_dev && -+ fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev) -+ break; -+ } -+ } /* for_each_child */ -+ } -+ } /* for each matching node */ -+ -+ if (fmt_port->p_tx_fm_port_dev == 0 || -+ fmt_port->p_rx_fm_port_dev == 0) { -+ -+ _fmt_err("bad fm port pointers.\n"); -+ return -EINVAL; -+ } -+ -+ _fmt_dbg("alloc %u tx queues.\n", fmt_port->num_of_tx_fqs); -+ -+ /* init fman test egress dynamic frame queues */ -+ for (i = 0; i < fmt_port->num_of_tx_fqs; i++) { -+ int _errno; -+ _errno = fmt_fq_alloc( -+ &fmt_port->p_tx_fqs[i], -+ &fmt_egress_fq, -+ 0, -+ QMAN_FQ_FLAG_TO_DCPORTAL, -+ fm_get_tx_port_channel(fmt_port->p_tx_port), -+ i); -+ -+ if (_errno < 0) { -+ _fmt_err("tx queues allocation failed.\n"); -+ /* TODO: memory leak here if 1 queue is allocated and -+ * next queues are failing ... */ -+ return -EINVAL; -+ } -+ } -+ -+ /* port is valid and ready to use. */ -+ fmt_port->valid = TRUE; -+ -+ _fmt_dbg("called.\n"); -+ return 0; -+} -+ -+/* fm test chardev functions */ -+static int fmt_open(struct inode *inode, struct file *file) -+{ -+ unsigned int minor = iminor(inode); -+ -+ _fmt_dbg("calling...\n"); -+ -+ if (file->private_data != NULL) -+ return 0; -+ -+ /* The minor represent the port number. -+ * Set the port structure accordingly, thus all the operations -+ * will be done on this port. */ -+ if ((minor >= DEV_FM_TEST_PORTS_MINOR_BASE) && -+ (minor < DEV_FM_TEST_MAX_MINORS)) -+ file->private_data = &fm_test.ports[minor]; -+ else -+ return -ENXIO; -+ -+ _fmt_dbg("called.\n"); -+ return 0; -+} -+ -+static int fmt_close(struct inode *inode, struct file *file) -+{ -+ struct fmt_port_s *fmt_port = NULL; -+ struct fmt_frame_s *fmt_frame = NULL; -+ -+ int err = 0; -+ -+ _fmt_dbg("calling...\n"); -+ -+ fmt_port = file->private_data; -+ if (!fmt_port) -+ return -ENODEV; -+ -+ /* Close the current test port by invalidating it. */ -+ fmt_port->valid = FALSE; -+ -+ /* clean the fmt port queue */ -+ while ((fmt_frame = dequeue_fmt_frame(fmt_port)) != NULL) { -+ if (fmt_frame && fmt_frame->buff.p_data){ -+ kfree(fmt_frame->buff.p_data); -+ kfree(fmt_frame); -+ } -+ } -+ -+ /* !!! the qman queues are cleaning from fm_ioctl... -+ * - very ugly */ -+ -+ _fmt_dbg("called.\n"); -+ return err; -+} -+ -+static int fmt_ioctls(unsigned int minor, -+ struct file *file, -+ unsigned int cmd, -+ unsigned long arg, -+ bool compat) -+{ -+ struct fmt_port_s *fmt_port = NULL; -+ -+ _fmt_dbg("IOCTL minor:%u " -+ " arg:0x%08lx ioctl cmd (0x%08x):(0x%02x:0x%02x.\n", -+ minor, arg, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); -+ -+ fmt_port = file->private_data; -+ if (!fmt_port) { -+ _fmt_err("invalid fmt port.\n"); -+ return -ENODEV; -+ } -+ -+ /* set test type properly */ -+ if (compat) -+ fmt_port->compat_test_type = true; -+ else -+ fmt_port->compat_test_type = false; -+ -+ switch (cmd) { -+ case FMT_PORT_IOC_INIT: -+ { -+ ioc_fmt_port_param_t param; -+ -+ if (fmt_port->valid) { -+ _fmt_wrn("port is already initialized.\n"); -+ return -EFAULT; -+ } -+#if defined(CONFIG_COMPAT) -+ if (compat) { -+ if (copy_from_user(¶m, -+ (ioc_fmt_port_param_t *)compat_ptr(arg), -+ sizeof(ioc_fmt_port_param_t))) -+ -+ return -EFAULT; -+ } else -+#endif -+ { -+ if (copy_from_user(¶m, -+ (ioc_fmt_port_param_t *) arg, -+ sizeof(ioc_fmt_port_param_t))) -+ -+ return -EFAULT; -+ } -+ -+ return fmt_port_init(fmt_port, ¶m); -+ } -+ -+ case FMT_PORT_IOC_SET_DIAG_MODE: -+ if (get_user(fmt_port->diag, (ioc_diag_mode *)arg)) -+ return -EFAULT; -+ -+ if (fmt_port->diag == e_IOC_DIAG_MODE_CTRL_LOOPBACK) -+ return set_mac_int_loopback(fmt_port, TRUE); -+ else -+ return set_mac_int_loopback(fmt_port, FALSE); -+ break; -+ -+ case FMT_PORT_IOC_SET_DPAECHO_MODE: -+ case FMT_PORT_IOC_SET_IP_HEADER_MANIP: -+ default: -+ _fmt_wrn("ioctl unimplemented minor:%u@ioctl" -+ " cmd:0x%08x(type:0x%02x, nr:0x%02x.\n", -+ minor, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)); -+ return -EFAULT; -+ } -+ -+ return 0; -+} -+ -+#ifdef CONFIG_COMPAT -+static long fmt_compat_ioctl( -+ struct file *file, -+ unsigned int cmd, -+ unsigned long arg) -+{ -+ unsigned int minor = iminor(file->f_path.dentry->d_inode); -+ -+ _fmt_dbg("calling...\n"); -+ return fmt_ioctls(minor, file, cmd, arg, true); -+} -+#endif -+ -+static long fmt_ioctl( -+ struct file *file, -+ unsigned int cmd, -+ unsigned long arg) -+{ -+ unsigned int minor = iminor(file->f_path.dentry->d_inode); -+ unsigned int res; -+ -+ _fmt_dbg("calling...\n"); -+ -+ fm_mutex_lock(); -+ res = fmt_ioctls(minor, file, cmd, arg, false); -+ fm_mutex_unlock(); -+ -+ _fmt_dbg("called.\n"); -+ -+ return res; -+} -+ -+#ifdef CONFIG_COMPAT -+void copy_compat_test_frame_buffer( -+ ioc_fmt_buff_desc_t *buff, -+ ioc_fmt_compat_buff_desc_t *compat_buff) -+{ -+ compat_buff->qid = buff->qid; -+ compat_buff->p_data = ptr_to_compat(buff->p_data); -+ compat_buff->size = buff->size; -+ compat_buff->status = buff->status; -+ -+ compat_buff->buff_context.p_user_priv = -+ ptr_to_compat(buff->buff_context.p_user_priv); -+ memcpy(compat_buff->buff_context.fm_prs_res, -+ buff->buff_context.fm_prs_res, -+ FM_PRS_MAX * sizeof(uint8_t)); -+ memcpy(compat_buff->buff_context.fm_time_stamp, -+ buff->buff_context.fm_time_stamp, -+ FM_TIME_STAMP_MAX * sizeof(uint8_t)); -+} -+#endif -+ -+ssize_t fmt_read( -+ struct file *file, -+ char __user *buf, -+ size_t size, -+ loff_t *ppos) -+{ -+ struct fmt_port_s *fmt_port = NULL; -+ struct fmt_frame_s *p_fmt_frame = NULL; -+ ssize_t cnt = 0; -+ -+ fmt_port = file->private_data; -+ if (!fmt_port || !fmt_port->valid) { -+ _fmt_err("fmt port not valid!\n"); -+ return -ENODEV; -+ } -+ -+ p_fmt_frame = dequeue_fmt_frame(fmt_port); -+ if (p_fmt_frame == NULL) -+ return 0; -+ -+ _fmt_dbgr("calling...\n"); -+ -+#ifdef CONFIG_COMPAT -+ if (fmt_port->compat_test_type){ -+ cnt = sizeof(ioc_fmt_compat_buff_desc_t); -+ } -+ else -+#endif -+ { -+ cnt = sizeof(ioc_fmt_buff_desc_t); -+ } -+ -+ if (size < cnt) { -+ _fmt_err("illegal buffer-size!\n"); -+ cnt = 0; -+ goto _fmt_read_return; -+ } -+ -+ /* Copy structure */ -+#ifdef CONFIG_COMPAT -+ if (fmt_port->compat_test_type) { -+ { -+ ioc_fmt_compat_buff_desc_t compat_buff; -+ copy_compat_test_frame_buffer(&p_fmt_frame->buff, -+ &compat_buff); -+ -+ if (copy_to_user(buf, &compat_buff, cnt)) { -+ _fmt_err("copy_to_user failed!\n"); -+ goto _fmt_read_return; -+ } -+ } -+ -+ ((ioc_fmt_compat_buff_desc_t *)buf)->p_data = -+ ptr_to_compat(buf+sizeof(ioc_fmt_compat_buff_desc_t)); -+ cnt += MIN(p_fmt_frame->buff.size, size-cnt); -+ } else -+#endif -+ { -+ if (copy_to_user(buf, &p_fmt_frame->buff, cnt)) { -+ _fmt_err("copy_to_user failed!\n"); -+ goto _fmt_read_return; -+ } -+ -+ ((ioc_fmt_buff_desc_t *)buf)->p_data = -+ buf + sizeof(ioc_fmt_buff_desc_t); -+ cnt += MIN(p_fmt_frame->buff.size, size-cnt); -+ } -+ -+ if (size < cnt) { -+ _fmt_err("illegal buffer-size!\n"); -+ goto _fmt_read_return; -+ } -+ -+ /* copy frame */ -+#ifdef CONFIG_COMPAT -+ if (fmt_port->compat_test_type) { -+ if (copy_to_user(buf+sizeof(ioc_fmt_compat_buff_desc_t), -+ p_fmt_frame->buff.p_data, cnt)) { -+ _fmt_err("copy_to_user failed!\n"); -+ goto _fmt_read_return; -+ } -+ } else -+#endif -+ { -+ if (copy_to_user(buf+sizeof(ioc_fmt_buff_desc_t), -+ p_fmt_frame->buff.p_data, cnt)) { -+ _fmt_err("copy_to_user failed!\n"); -+ goto _fmt_read_return; -+ } -+ } -+ -+_fmt_read_return: -+ kfree(p_fmt_frame->buff.p_data); -+ kfree(p_fmt_frame); -+ -+ _fmt_dbgr("called.\n"); -+ return cnt; -+} -+ -+ssize_t fmt_write( -+ struct file *file, -+ const char __user *buf, -+ size_t size, -+ loff_t *ppos) -+{ -+ struct fmt_port_s *fmt_port = NULL; -+ ioc_fmt_buff_desc_t buff_desc; -+#ifdef CONFIG_COMPAT -+ ioc_fmt_compat_buff_desc_t buff_desc_compat; -+#endif -+ uint8_t *p_data = NULL; -+ uint32_t data_offset; -+ int _errno; -+ t_DpaaFD fd; -+ -+ _fmt_dbgr("calling...\n"); -+ -+ fmt_port = file->private_data; -+ if (!fmt_port || !fmt_port->valid) { -+ _fmt_err("fmt port not valid.\n"); -+ return -EINVAL; -+ } -+ -+ /* If Compat (32B UserSpace - 64B KernelSpace) */ -+#ifdef CONFIG_COMPAT -+ if (fmt_port->compat_test_type) { -+ if (size < sizeof(ioc_fmt_compat_buff_desc_t)) { -+ _fmt_err("invalid buff_desc size.\n"); -+ return -EFAULT; -+ } -+ -+ if (copy_from_user(&buff_desc_compat, buf, -+ sizeof(ioc_fmt_compat_buff_desc_t))) -+ return -EFAULT; -+ -+ buff_desc.qid = buff_desc_compat.qid; -+ buff_desc.p_data = compat_ptr(buff_desc_compat.p_data); -+ buff_desc.size = buff_desc_compat.size; -+ buff_desc.status = buff_desc_compat.status; -+ -+ buff_desc.buff_context.p_user_priv = -+ compat_ptr(buff_desc_compat.buff_context.p_user_priv); -+ memcpy(buff_desc.buff_context.fm_prs_res, -+ buff_desc_compat.buff_context.fm_prs_res, -+ FM_PRS_MAX * sizeof(uint8_t)); -+ memcpy(buff_desc.buff_context.fm_time_stamp, -+ buff_desc_compat.buff_context.fm_time_stamp, -+ FM_TIME_STAMP_MAX * sizeof(uint8_t)); -+ } else -+#endif -+ { -+ if (size < sizeof(ioc_fmt_buff_desc_t)) { -+ _fmt_err("invalid buff_desc size.\n"); -+ return -EFAULT; -+ } -+ -+ if (copy_from_user(&buff_desc, (ioc_fmt_buff_desc_t *)buf, -+ sizeof(ioc_fmt_buff_desc_t))) -+ return -EFAULT; -+ } -+ -+ data_offset = FM_PORT_GetBufferDataOffset(fmt_port->p_tx_fm_port_dev); -+ p_data = kmalloc(buff_desc.size+data_offset, GFP_KERNEL); -+ if (!p_data) -+ return -ENOMEM; -+ -+ /* If Compat (32UserSpace - 64KernelSpace) the buff_desc.p_data is ok */ -+ if (copy_from_user((uint8_t *)PTR_MOVE(p_data, data_offset), -+ buff_desc.p_data, -+ buff_desc.size)) { -+ kfree(p_data); -+ return -EFAULT; -+ } -+ -+ /* TODO: dma_map_single here (cannot access the bpool struct) */ -+ -+ /* prepare fd */ -+ memset(&fd, 0, sizeof(fd)); -+ DPAA_FD_SET_ADDR(&fd, p_data); -+ DPAA_FD_SET_OFFSET(&fd, data_offset); -+ DPAA_FD_SET_LENGTH(&fd, buff_desc.size); -+ -+ _errno = qman_enqueue(&fmt_port->p_tx_fqs[buff_desc.qid].fq_base, -+ (struct qm_fd *)&fd, 0); -+ if (_errno) { -+ buff_desc.status = (uint32_t)_errno; -+ if (copy_to_user((ioc_fmt_buff_desc_t *)buf, &buff_desc, -+ sizeof(ioc_fmt_buff_desc_t))) { -+ kfree(p_data); -+ return -EFAULT; -+ } -+ } -+ -+ /* for debugging */ -+#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME) -+ atomic_inc(&fmt_port->enqueue_to_qman_frm); -+#endif -+ _fmt_dbgr("called.\n"); -+ return buff_desc.size; -+} -+ -+/* fm test character device definition */ -+static const struct file_operations fmt_fops = -+{ -+ .owner = THIS_MODULE, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = fmt_compat_ioctl, -+#endif -+ .unlocked_ioctl = fmt_ioctl, -+ .open = fmt_open, -+ .release = fmt_close, -+ .read = fmt_read, -+ .write = fmt_write, -+}; -+ -+static int fmt_init(void) -+{ -+ int id; -+ -+ _fmt_dbg("calling...\n"); -+ -+ /* Register to the /dev for IOCTL API */ -+ /* Register dynamically a new major number for the character device: */ -+ fm_test.major = register_chrdev(0, DEV_FM_TEST_NAME, &fmt_fops); -+ if (fm_test.major <= 0) { -+ _fmt_wrn("Failed to allocate major number for device %s.\n", -+ DEV_FM_TEST_NAME); -+ return -ENODEV; -+ } -+ -+ /* Creating class for FMan_test */ -+ fm_test.fmt_class = class_create(THIS_MODULE, DEV_FM_TEST_NAME); -+ if (IS_ERR(fm_test.fmt_class)) { -+ unregister_chrdev(fm_test.major, DEV_FM_TEST_NAME); -+ _fmt_wrn("Error creating %s class.\n", DEV_FM_TEST_NAME); -+ return -ENODEV; -+ } -+ -+ for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++) -+ if (NULL == device_create(fm_test.fmt_class, NULL, -+ MKDEV(fm_test.major, -+ DEV_FM_TEST_PORTS_MINOR_BASE + id), NULL, -+ DEV_FM_TEST_NAME "%d", id)) { -+ -+ _fmt_err("Error creating %s device.\n", -+ DEV_FM_TEST_NAME); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static void fmt_free(void) -+{ -+ int id; -+ -+ for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++) -+ device_destroy(fm_test.fmt_class, MKDEV(fm_test.major, -+ DEV_FM_TEST_PORTS_MINOR_BASE + id)); -+ class_destroy(fm_test.fmt_class); -+} -+ -+static int __init __cold fmt_load(void) -+{ -+ struct dpaa_eth_hooks_s priv_dpaa_eth_hooks; -+ -+ /* set dpaa hooks for default queues */ -+ memset(&priv_dpaa_eth_hooks, 0, sizeof(priv_dpaa_eth_hooks)); -+ priv_dpaa_eth_hooks.rx_default = fmt_rx_default_hook; -+ priv_dpaa_eth_hooks.rx_error = fmt_rx_error_hook; -+ priv_dpaa_eth_hooks.tx_confirm = fmt_tx_confirm_hook; -+ priv_dpaa_eth_hooks.tx_error = fmt_tx_confirm_error_hook; -+ -+ fsl_dpaa_eth_set_hooks(&priv_dpaa_eth_hooks); -+ -+ /* initialize the fman test environment */ -+ if (fmt_init() < 0) { -+ _fmt_err("Failed to init FM-test modul.\n"); -+ fmt_free(); -+ return -ENODEV; -+ } -+ -+ _fmt_inf("FSL FM test module loaded.\n"); -+ -+ return 0; -+} -+ -+static void __exit __cold fmt_unload(void) -+{ -+ fmt_free(); -+ _fmt_inf("FSL FM test module unloaded.\n"); -+} -+ -+module_init(fmt_load); -+module_exit(fmt_unload); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -@@ -0,0 +1,2908 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ @File lnxwrp_fm.c -+ @Author Shlomi Gridish -+ @Description FM Linux wrapper functions. -+*/ -+ -+#include -+#include -+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) -+#define MODVERSIONS -+#endif -+#ifdef MODVERSIONS -+#include -+#endif /* MODVERSIONS */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifndef CONFIG_FMAN_ARM -+#include -+#include -+#include -+#endif -+#include /* For file access mask */ -+#include -+#include -+ -+/* NetCommSw Headers --------------- */ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "sprint_ext.h" -+#include "debug_ext.h" -+#include "sys_io_ext.h" -+ -+#include "fm_ioctls.h" -+ -+#include "lnxwrp_fm.h" -+#include "lnxwrp_resources.h" -+#include "lnxwrp_sysfs_fm.h" -+#include "lnxwrp_sysfs_fm_port.h" -+#include "lnxwrp_exp_sym.h" -+#include "fm_common.h" -+#include "../../sdk_fman/Peripherals/FM/fm.h" -+#define __ERR_MODULE__ MODULE_FM -+ -+extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node, -+ e_FmPortType portType, -+ uint8_t portId); -+ -+#define PROC_PRINT(args...) offset += sprintf(buf+offset,args) -+ -+#define ADD_ADV_CONFIG_NO_RET(_func, _param) \ -+ do { \ -+ if (ip_Function = _func; \ -+ _param \ -+ i++; \ -+ } \ -+ else \ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,\ -+ ("Number of advanced-configuration entries exceeded"));\ -+ } while (0) -+ -+/* Bootarg used to override the Kconfig FSL_FM_MAX_FRAME_SIZE value */ -+#define FSL_FM_MAX_FRM_BOOTARG "fsl_fm_max_frm" -+ -+/* Bootarg used to override FSL_FM_RX_EXTRA_HEADROOM Kconfig value */ -+#define FSL_FM_RX_EXTRA_HEADROOM_BOOTARG "fsl_fm_rx_extra_headroom" -+ -+/* Minimum and maximum value for the fsl_fm_rx_extra_headroom bootarg */ -+#define FSL_FM_RX_EXTRA_HEADROOM_MIN 16 -+#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384 -+ -+#define FSL_FM_PAUSE_TIME_ENABLE 0xf000 -+#define FSL_FM_PAUSE_TIME_DISABLE 0 -+#define FSL_FM_PAUSE_THRESH_DEFAULT 0 -+ -+/* -+ * Max frame size, across all interfaces. -+ * Configurable from Kconfig or bootargs, to avoid allocating -+ * oversized (socket) buffers when not using jumbo frames. -+ * Must be large enough to accommodate the network MTU, but small enough -+ * to avoid wasting skb memory. -+ * -+ * Could be overridden once, at boot-time, via the -+ * fm_set_max_frm() callback. -+ */ -+int fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE; -+ -+/* -+ * Extra headroom for Rx buffers. -+ * FMan is instructed to allocate, on the Rx path, this amount of -+ * space at the beginning of a data buffer, beside the DPA private -+ * data area and the IC fields. -+ * Does not impact Tx buffer layout. -+ * -+ * Configurable from Kconfig or bootargs. Zero by default, it's needed -+ * on particular forwarding scenarios that add extra headers to the -+ * forwarded frame. -+ */ -+int fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM; -+ -+#ifdef CONFIG_FMAN_PFC -+static int fsl_fm_pfc_quanta[] = { -+ CONFIG_FMAN_PFC_QUANTA_0, -+ CONFIG_FMAN_PFC_QUANTA_1, -+ CONFIG_FMAN_PFC_QUANTA_2, -+ CONFIG_FMAN_PFC_QUANTA_3 -+}; -+#endif -+ -+static t_LnxWrpFm lnxWrpFm; -+ -+int fm_get_max_frm() -+{ -+ return fsl_fm_max_frm; -+} -+EXPORT_SYMBOL(fm_get_max_frm); -+ -+int fm_get_rx_extra_headroom() -+{ -+ return ALIGN(fsl_fm_rx_extra_headroom, 16); -+} -+EXPORT_SYMBOL(fm_get_rx_extra_headroom); -+ -+static int __init fm_set_max_frm(char *str) -+{ -+ int ret = 0; -+ -+ ret = get_option(&str, &fsl_fm_max_frm); -+ if (ret != 1) { -+ /* -+ * This will only work if CONFIG_EARLY_PRINTK is compiled in, -+ * and something like "earlyprintk=serial,uart0,115200" is -+ * specified in the bootargs -+ */ -+ printk(KERN_WARNING "No suitable %s= prop in bootargs; " -+ "will use the default FSL_FM_MAX_FRAME_SIZE (%d) " -+ "from Kconfig.\n", FSL_FM_MAX_FRM_BOOTARG, -+ CONFIG_FSL_FM_MAX_FRAME_SIZE); -+ -+ fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE; -+ return 1; -+ } -+ -+ /* Don't allow invalid bootargs; fallback to the Kconfig value */ -+ if (fsl_fm_max_frm < 64 || fsl_fm_max_frm > 9600) { -+ printk(KERN_WARNING "Invalid %s=%d in bootargs, valid range is " -+ "64-9600. Falling back to the FSL_FM_MAX_FRAME_SIZE (%d) " -+ "from Kconfig.\n", -+ FSL_FM_MAX_FRM_BOOTARG, fsl_fm_max_frm, -+ CONFIG_FSL_FM_MAX_FRAME_SIZE); -+ -+ fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE; -+ return 1; -+ } -+ -+ printk(KERN_INFO "Using fsl_fm_max_frm=%d from bootargs\n", -+ fsl_fm_max_frm); -+ return 0; -+} -+early_param(FSL_FM_MAX_FRM_BOOTARG, fm_set_max_frm); -+ -+static int __init fm_set_rx_extra_headroom(char *str) -+{ -+ int ret; -+ -+ ret = get_option(&str, &fsl_fm_rx_extra_headroom); -+ -+ if (ret != 1) { -+ printk(KERN_WARNING "No suitable %s= prop in bootargs; " -+ "will use the default FSL_FM_RX_EXTRA_HEADROOM (%d) " -+ "from Kconfig.\n", FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, -+ CONFIG_FSL_FM_RX_EXTRA_HEADROOM); -+ fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM; -+ -+ return 1; -+ } -+ -+ if (fsl_fm_rx_extra_headroom < FSL_FM_RX_EXTRA_HEADROOM_MIN || -+ fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX) { -+ printk(KERN_WARNING "Invalid value for %s=%d prop in " -+ "bootargs; will use the default " -+ "FSL_FM_RX_EXTRA_HEADROOM (%d) from Kconfig.\n", -+ FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, -+ fsl_fm_rx_extra_headroom, -+ CONFIG_FSL_FM_RX_EXTRA_HEADROOM); -+ fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM; -+ } -+ -+ printk(KERN_INFO "Using fsl_fm_rx_extra_headroom=%d from bootargs\n", -+ fsl_fm_rx_extra_headroom); -+ -+ return 0; -+} -+early_param(FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, fm_set_rx_extra_headroom); -+ -+static irqreturn_t fm_irq(int irq, void *_dev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev; -+#ifdef CONFIG_PM_SLEEP -+ t_Fm *p_Fm = (t_Fm*)p_LnxWrpFmDev->h_Dev; -+#endif -+ if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev) -+ return IRQ_NONE; -+ -+#ifdef CONFIG_PM_SLEEP -+ if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP) -+ { -+ pm_wakeup_event(p_LnxWrpFmDev->dev, 200); -+ } -+#endif -+ FM_EventIsr(p_LnxWrpFmDev->h_Dev); -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t fm_err_irq(int irq, void *_dev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev; -+ -+ if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev) -+ return IRQ_NONE; -+ -+ if (FM_ErrorIsr(p_LnxWrpFmDev->h_Dev) == E_OK) -+ return IRQ_HANDLED; -+ -+ return IRQ_NONE; -+} -+ -+/* used to protect FMD/LLD from concurrent calls in functions fm_mutex_lock / fm_mutex_unlock */ -+static struct mutex lnxwrp_mutex; -+ -+static t_LnxWrpFmDev * CreateFmDev(uint8_t id) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ int j; -+ -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *)XX_Malloc(sizeof(t_LnxWrpFmDev)); -+ if (!p_LnxWrpFmDev) -+ { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ return NULL; -+ } -+ -+ memset(p_LnxWrpFmDev, 0, sizeof(t_LnxWrpFmDev)); -+ p_LnxWrpFmDev->fmDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)); -+ memset(p_LnxWrpFmDev->fmDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry))); -+ p_LnxWrpFmDev->fmPcdDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)); -+ memset(p_LnxWrpFmDev->fmPcdDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry))); -+ p_LnxWrpFmDev->hcPort.settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)); -+ memset(p_LnxWrpFmDev->hcPort.settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry))); -+ for (j=0; jrxPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)); -+ memset(p_LnxWrpFmDev->rxPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry))); -+ } -+ for (j=0; jtxPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)); -+ memset(p_LnxWrpFmDev->txPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry))); -+ } -+ for (j=0; jopPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)); -+ memset(p_LnxWrpFmDev->opPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry))); -+ } -+ -+ return p_LnxWrpFmDev; -+} -+ -+static void DestroyFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev) -+{ -+ int j; -+ -+ for (j=0; jopPorts[j].settings.advConfig) -+ XX_Free(p_LnxWrpFmDev->opPorts[j].settings.advConfig); -+ for (j=0; jtxPorts[j].settings.advConfig) -+ XX_Free(p_LnxWrpFmDev->txPorts[j].settings.advConfig); -+ for (j=0; jrxPorts[j].settings.advConfig) -+ XX_Free(p_LnxWrpFmDev->rxPorts[j].settings.advConfig); -+ if (p_LnxWrpFmDev->hcPort.settings.advConfig) -+ XX_Free(p_LnxWrpFmDev->hcPort.settings.advConfig); -+ if (p_LnxWrpFmDev->fmPcdDevSettings.advConfig) -+ XX_Free(p_LnxWrpFmDev->fmPcdDevSettings.advConfig); -+ if (p_LnxWrpFmDev->fmDevSettings.advConfig) -+ XX_Free(p_LnxWrpFmDev->fmDevSettings.advConfig); -+ -+ XX_Free(p_LnxWrpFmDev); -+} -+ -+static t_Error FillRestFmInfo(t_LnxWrpFmDev *p_LnxWrpFmDev) -+{ -+#define FM_BMI_PPIDS_OFFSET 0x00080304 -+#define FM_DMA_PLR_OFFSET 0x000c2060 -+#define FM_FPM_IP_REV_1_OFFSET 0x000c30c4 -+#define DMA_HIGH_LIODN_MASK 0x0FFF0000 -+#define DMA_LOW_LIODN_MASK 0x00000FFF -+#define DMA_LIODN_SHIFT 16 -+ -+typedef _Packed struct { -+ uint32_t plr[32]; -+} _PackedType t_Plr; -+ -+typedef _Packed struct { -+ volatile uint32_t fmbm_ppid[63]; -+} _PackedType t_Ppids; -+ -+ t_Plr *p_Plr; -+ t_Ppids *p_Ppids; -+ int i,j; -+ uint32_t fmRev; -+ -+ static const uint8_t phys1GRxPortId[] = {0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf}; -+ static const uint8_t phys10GRxPortId[] = {0x10,0x11}; -+#if (DPAA_VERSION >= 11) -+ static const uint8_t physOhPortId[] = {/* 0x1, */0x2,0x3,0x4,0x5,0x6,0x7}; -+#else -+ static const uint8_t physOhPortId[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7}; -+#endif -+ static const uint8_t phys1GTxPortId[] = {0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f}; -+ static const uint8_t phys10GTxPortId[] = {0x30,0x31}; -+ -+ fmRev = (uint32_t)(*((volatile uint32_t *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_FPM_IP_REV_1_OFFSET))); -+ fmRev &= 0xffff; -+ -+ p_Plr = (t_Plr *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_DMA_PLR_OFFSET); -+#ifdef MODULE -+ for (i=0;iplr[i] = 0; -+#endif /* MODULE */ -+ -+ for (i=0; iplr[i/2] & DMA_LOW_LIODN_MASK) : -+ ((p_Plr->plr[i/2] & DMA_HIGH_LIODN_MASK) >> DMA_LIODN_SHIFT)); -+#ifdef FM_PARTITION_ARRAY -+ /* TODO: this was .liodnPerPartition[i] = liodnBase; is the index meaning the same? */ -+ p_LnxWrpFmDev->fmDevSettings.param.liodnBasePerPort[i] = liodnBase; -+#endif /* FM_PARTITION_ARRAY */ -+ -+ if ((i >= phys1GRxPortId[0]) && -+ (i <= phys1GRxPortId[FM_MAX_NUM_OF_1G_RX_PORTS-1])) -+ { -+ for (j=0; jrxPorts[j].settings.param.liodnBase = liodnBase; -+ } -+ else if (FM_MAX_NUM_OF_10G_RX_PORTS && -+ (i >= phys10GRxPortId[0]) && -+ (i <= phys10GRxPortId[FM_MAX_NUM_OF_10G_RX_PORTS-1])) -+ { -+ for (j=0; jrxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+j].settings.param.liodnBase = liodnBase; -+ } -+ else if ((i >= physOhPortId[0]) && -+ (i <= physOhPortId[FM_MAX_NUM_OF_OH_PORTS-1])) -+ { -+ for (j=0; jhcPort.settings.param.liodnBase = liodnBase; -+ else -+ p_LnxWrpFmDev->opPorts[j - 1].settings.param.liodnBase = liodnBase; -+ } -+ else if ((i >= phys1GTxPortId[0]) && -+ (i <= phys1GTxPortId[FM_MAX_NUM_OF_1G_TX_PORTS-1])) -+ { -+ for (j=0; jtxPorts[j].settings.param.liodnBase = liodnBase; -+ } -+ else if (FM_MAX_NUM_OF_10G_TX_PORTS && -+ (i >= phys10GTxPortId[0]) && -+ (i <= phys10GTxPortId[FM_MAX_NUM_OF_10G_TX_PORTS-1])) -+ { -+ for (j=0; jtxPorts[FM_MAX_NUM_OF_1G_TX_PORTS+j].settings.param.liodnBase = liodnBase; -+ } -+ } -+ -+ p_Ppids = (t_Ppids *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_BMI_PPIDS_OFFSET); -+ -+ for (i=0; irxPorts[i].settings.param.specificParams.rxParams.liodnOffset = -+ p_Ppids->fmbm_ppid[phys1GRxPortId[i]-1]; -+ -+ for (i=0; irxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+i].settings.param.specificParams.rxParams.liodnOffset = -+ p_Ppids->fmbm_ppid[phys10GRxPortId[i]-1]; -+ -+ return E_OK; -+} -+ -+/* Structure that defines QE firmware binary files. -+ * -+ * See Documentation/powerpc/qe_firmware.txt for a description of these -+ * fields. -+ */ -+struct qe_firmware { -+ struct qe_header { -+ __be32 length; /* Length of the entire structure, in bytes */ -+ u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */ -+ u8 version; /* Version of this layout. First ver is '1' */ -+ } header; -+ u8 id[62]; /* Null-terminated identifier string */ -+ u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */ -+ u8 count; /* Number of microcode[] structures */ -+ struct { -+ __be16 model; /* The SOC model */ -+ u8 major; /* The SOC revision major */ -+ u8 minor; /* The SOC revision minor */ -+ } __attribute__ ((packed)) soc; -+ u8 padding[4]; /* Reserved, for alignment */ -+ __be64 extended_modes; /* Extended modes */ -+ __be32 vtraps[8]; /* Virtual trap addresses */ -+ u8 reserved[4]; /* Reserved, for future expansion */ -+ struct qe_microcode { -+ u8 id[32]; /* Null-terminated identifier */ -+ __be32 traps[16]; /* Trap addresses, 0 == ignore */ -+ __be32 eccr; /* The value for the ECCR register */ -+ __be32 iram_offset; /* Offset into I-RAM for the code */ -+ __be32 count; /* Number of 32-bit words of the code */ -+ __be32 code_offset; /* Offset of the actual microcode */ -+ u8 major; /* The microcode version major */ -+ u8 minor; /* The microcode version minor */ -+ u8 revision; /* The microcode version revision */ -+ u8 padding; /* Reserved, for alignment */ -+ u8 reserved[4]; /* Reserved, for future expansion */ -+ } __attribute__ ((packed)) microcode[1]; -+ /* All microcode binaries should be located here */ -+ /* CRC32 should be located here, after the microcode binaries */ -+} __attribute__ ((packed)); -+ -+ -+/** -+ * FindFmanMicrocode - find the Fman microcode -+ * -+ * This function returns a pointer to the QE Firmware blob that holds -+ * the Fman microcode. We use the QE Firmware structure because Fman microcode -+ * is similar to QE microcode, so there's no point in defining a new layout. -+ * -+ * Current versions of U-Boot embed the Fman firmware into the device tree, -+ * so we check for that first. Each Fman node in the device tree contains a -+ * node or a pointer to node that holds the firmware. Technically, we should -+ * be fetching the firmware node for the current Fman, but we don't have that -+ * information any more, so we assume that there is only one firmware node in -+ * the device tree, and that all Fmen use the same firmware. -+ */ -+static const struct qe_firmware *FindFmanMicrocode(void) -+{ -+ static const struct qe_firmware *P4080_UCPatch; -+ struct device_node *np; -+ -+ if (P4080_UCPatch) -+ return P4080_UCPatch; -+ -+ /* The firmware should be inside the device tree. */ -+ np = of_find_compatible_node(NULL, NULL, "fsl,fman-firmware"); -+ if (np) { -+ P4080_UCPatch = of_get_property(np, "fsl,firmware", NULL); -+ of_node_put(np); -+ if (P4080_UCPatch) -+ return P4080_UCPatch; -+ else -+ REPORT_ERROR(WARNING, E_NOT_FOUND, ("firmware node is incomplete")); -+ } -+ -+ /* Returning NULL here forces the reuse of the IRAM content */ -+ return NULL; -+} -+#define SVR_SECURITY_MASK 0x00080000 -+#define SVR_PERSONALITY_MASK 0x0000FF00 -+#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK) -+#define SVR_B4860_REV1_VALUE 0x86800010 -+#define SVR_B4860_REV2_VALUE 0x86800020 -+#define SVR_T4240_VALUE 0x82400000 -+#define SVR_T4120_VALUE 0x82400100 -+#define SVR_T4160_VALUE 0x82410000 -+#define SVR_T4080_VALUE 0x82410200 -+#define SVR_T4_DEVICE_ID 0x82400000 -+#define SVR_DEVICE_ID_MASK 0xFFF00000 -+ -+#define OF_DEV_ID_NUM 2 /* one used, another one zeroed */ -+ -+/* searches for a subnode with the given name/compatible */ -+static bool HasFmPcdOfNode(struct device_node *fm_node, -+ struct of_device_id *ids, -+ const char *name, -+ const char *compatible) -+{ -+ struct device_node *dev_node; -+ bool ret = false; -+ -+ memset(ids, 0, OF_DEV_ID_NUM*sizeof(struct of_device_id)); -+ if (WARN_ON(strlen(name) >= sizeof(ids[0].name))) -+ return false; -+ strcpy(ids[0].name, name); -+ if (WARN_ON(strlen(compatible) >= sizeof(ids[0].compatible))) -+ return false; -+ strcpy(ids[0].compatible, compatible); -+ for_each_child_of_node(fm_node, dev_node) -+ if (of_match_node(ids, dev_node) != NULL) -+ ret = true; -+ return ret; -+} -+ -+static t_LnxWrpFmDev * ReadFmDevTreeNode (struct platform_device *of_dev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ struct device_node *fm_node, *dev_node; -+ struct of_device_id ids[OF_DEV_ID_NUM]; -+ struct resource res; -+ struct clk *clk; -+ u32 clk_rate; -+ const uint32_t *uint32_prop; -+ int _errno=0, lenp; -+ uint32_t tmp_prop; -+ -+ fm_node = of_node_get(of_dev->dev.of_node); -+ -+ uint32_prop = (uint32_t *)of_get_property(fm_node, "cell-index", &lenp); -+ if (unlikely(uint32_prop == NULL)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_get_property(%s, cell-index) failed", fm_node->full_name)); -+ return NULL; -+ } -+ tmp_prop = be32_to_cpu(*uint32_prop); -+ -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ -+ if (tmp_prop > INTG_MAX_NUM_OF_FM) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!")); -+ return NULL; -+ } -+ p_LnxWrpFmDev = CreateFmDev(tmp_prop); -+ if (!p_LnxWrpFmDev) { -+ REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG); -+ return NULL; -+ } -+ p_LnxWrpFmDev->dev = &of_dev->dev; -+ p_LnxWrpFmDev->id = tmp_prop; -+ -+ /* Get the FM interrupt */ -+ p_LnxWrpFmDev->irq = of_irq_to_resource(fm_node, 0, NULL); -+ if (unlikely(p_LnxWrpFmDev->irq == /*NO_IRQ*/0)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ)); -+ DestroyFmDev(p_LnxWrpFmDev); -+ return NULL; -+ } -+ -+ /* Get the FM error interrupt */ -+ p_LnxWrpFmDev->err_irq = of_irq_to_resource(fm_node, 1, NULL); -+ -+ if (unlikely(p_LnxWrpFmDev->err_irq == /*NO_IRQ*/0)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ)); -+ DestroyFmDev(p_LnxWrpFmDev); -+ return NULL; -+ } -+ -+ /* Get the FM address */ -+ _errno = of_address_to_resource(fm_node, 0, &res); -+ if (unlikely(_errno < 0)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno)); -+ DestroyFmDev(p_LnxWrpFmDev); -+ return NULL; -+ } -+ -+ -+ p_LnxWrpFmDev->fmBaseAddr = 0; -+ p_LnxWrpFmDev->fmPhysBaseAddr = res.start; -+ p_LnxWrpFmDev->fmMemSize = res.end + 1 - res.start; -+ -+ clk = of_clk_get(fm_node, 0); -+ if (IS_ERR(clk)) { -+ dev_err(&of_dev->dev, "%s: Failed to get FM clock structure\n", -+ __func__); -+ of_node_put(fm_node); -+ DestroyFmDev(p_LnxWrpFmDev); -+ return NULL; -+ } -+ -+ clk_rate = clk_get_rate(clk); -+ if (!clk_rate) { -+ dev_err(&of_dev->dev, "%s: Failed to determine FM clock rate\n", -+ __func__); -+ of_node_put(fm_node); -+ DestroyFmDev(p_LnxWrpFmDev); -+ return NULL; -+ } -+ -+ p_LnxWrpFmDev->fmDevSettings.param.fmClkFreq = DIV_ROUND_UP(clk_rate, 1000000); /* In MHz, rounded */ -+ /* Get the MURAM base address and size */ -+ memset(ids, 0, sizeof(ids)); -+ if (WARN_ON(strlen("muram") >= sizeof(ids[0].name))) -+ return NULL; -+ strcpy(ids[0].name, "muram"); -+ if (WARN_ON(strlen("fsl,fman-muram") >= sizeof(ids[0].compatible))) -+ return NULL; -+ strcpy(ids[0].compatible, "fsl,fman-muram"); -+ for_each_child_of_node(fm_node, dev_node) { -+ if (likely(of_match_node(ids, dev_node) != NULL)) { -+ _errno = of_address_to_resource(dev_node, 0, &res); -+ if (unlikely(_errno < 0)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno)); -+ DestroyFmDev(p_LnxWrpFmDev); -+ return NULL; -+ } -+ -+ p_LnxWrpFmDev->fmMuramBaseAddr = 0; -+ p_LnxWrpFmDev->fmMuramPhysBaseAddr = res.start; -+ p_LnxWrpFmDev->fmMuramMemSize = res.end + 1 - res.start; -+ -+#ifndef CONFIG_FMAN_ARM -+ { -+ uint32_t svr; -+ svr = mfspr(SPRN_SVR); -+ -+ if ((svr & ~SVR_VER_IGNORE_MASK) >= SVR_B4860_REV2_VALUE) -+ p_LnxWrpFmDev->fmMuramMemSize = 0x80000; -+ } -+#endif -+ } -+ } -+ -+ /* Get the RTC base address and size */ -+ memset(ids, 0, sizeof(ids)); -+ if (WARN_ON(strlen("rtc") >= sizeof(ids[0].name))) -+ return NULL; -+ strcpy(ids[0].name, "rtc"); -+ if (WARN_ON(strlen("fsl,fman-rtc") >= sizeof(ids[0].compatible))) -+ return NULL; -+ strcpy(ids[0].compatible, "fsl,fman-rtc"); -+ for_each_child_of_node(fm_node, dev_node) { -+ if (likely(of_match_node(ids, dev_node) != NULL)) { -+ _errno = of_address_to_resource(dev_node, 0, &res); -+ if (unlikely(_errno < 0)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno)); -+ DestroyFmDev(p_LnxWrpFmDev); -+ return NULL; -+ } -+ -+ p_LnxWrpFmDev->fmRtcBaseAddr = 0; -+ p_LnxWrpFmDev->fmRtcPhysBaseAddr = res.start; -+ p_LnxWrpFmDev->fmRtcMemSize = res.end + 1 - res.start; -+ } -+ } -+ -+#if (DPAA_VERSION >= 11) -+ /* Get the VSP base address */ -+ for_each_child_of_node(fm_node, dev_node) { -+ if (of_device_is_compatible(dev_node, "fsl,fman-vsps")) { -+ _errno = of_address_to_resource(dev_node, 0, &res); -+ if (unlikely(_errno < 0)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno)); -+ DestroyFmDev(p_LnxWrpFmDev); -+ return NULL; -+ } -+ p_LnxWrpFmDev->fmVspBaseAddr = 0; -+ p_LnxWrpFmDev->fmVspPhysBaseAddr = res.start; -+ p_LnxWrpFmDev->fmVspMemSize = res.end + 1 - res.start; -+ } -+ } -+#endif -+ -+ /* Get all PCD nodes */ -+ p_LnxWrpFmDev->prsActive = HasFmPcdOfNode(fm_node, ids, "parser", "fsl,fman-parser"); -+ p_LnxWrpFmDev->kgActive = HasFmPcdOfNode(fm_node, ids, "keygen", "fsl,fman-keygen"); -+ p_LnxWrpFmDev->ccActive = HasFmPcdOfNode(fm_node, ids, "cc", "fsl,fman-cc"); -+ p_LnxWrpFmDev->plcrActive = HasFmPcdOfNode(fm_node, ids, "policer", "fsl,fman-policer"); -+ -+ if (p_LnxWrpFmDev->prsActive || p_LnxWrpFmDev->kgActive || -+ p_LnxWrpFmDev->ccActive || p_LnxWrpFmDev->plcrActive) -+ p_LnxWrpFmDev->pcdActive = TRUE; -+ -+ if (p_LnxWrpFmDev->pcdActive) -+ { -+ const char *str_prop = (char *)of_get_property(fm_node, "fsl,default-pcd", &lenp); -+ if (str_prop) { -+ if (strncmp(str_prop, "3-tuple", strlen("3-tuple")) == 0) -+ p_LnxWrpFmDev->defPcd = e_FM_PCD_3_TUPLE; -+ } -+ else -+ p_LnxWrpFmDev->defPcd = e_NO_PCD; -+ } -+ -+ of_node_put(fm_node); -+ -+ p_LnxWrpFmDev->hcCh = -+ qman_affine_channel(cpumask_first(qman_affine_cpus())); -+ -+ p_LnxWrpFmDev->active = TRUE; -+ -+ return p_LnxWrpFmDev; -+} -+ -+struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx) -+{ -+ struct device_node *dev_node; -+ const uint32_t *uint32_prop; -+ int lenp; -+ uint32_t tmp_prop; -+ -+ for_each_compatible_node(dev_node, NULL, "fsl,fman-extended-args") { -+ uint32_prop = (uint32_t *)of_get_property(dev_node, "cell-index", &lenp); -+ if (unlikely(uint32_prop == NULL)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("of_get_property(%s, cell-index) failed", -+ dev_node->full_name)); -+ return NULL; -+ } -+ tmp_prop = be32_to_cpu(*uint32_prop); -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ if (tmp_prop > INTG_MAX_NUM_OF_FM) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!")); -+ return NULL; -+ } -+ if (fmIndx == tmp_prop) -+ return dev_node; -+ } -+ -+ return NULL; -+} -+ -+static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev) -+{ -+ struct device_node *dev_node; -+ t_Error err = E_INVALID_VALUE; -+ const uint32_t *uint32_prop; -+ const char *str_prop; -+ int lenp; -+ uint32_t tmp_prop; -+ -+ dev_node = GetFmAdvArgsDevTreeNode(p_LnxWrpFmDev->id); -+ if (!dev_node) /* no advance parameters for FMan */ -+ return E_OK; -+ -+ str_prop = (char *)of_get_property(dev_node, "dma-aid-mode", &lenp); -+ if (str_prop) { -+ if (strcmp(str_prop, "port") == 0) -+ err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_PORT_ID); -+ else if (strcmp(str_prop, "tnum") == 0) -+ err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_TNUM); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ uint32_prop = (uint32_t *)of_get_property(dev_node, -+ "total-fifo-size", &lenp); -+ if (uint32_prop) { -+ tmp_prop = be32_to_cpu(*uint32_prop); -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ -+ if (FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev, -+ tmp_prop) != E_OK) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ } -+ -+ uint32_prop = (uint32_t *)of_get_property(dev_node, "tnum-aging-period", -+ &lenp); -+ if (uint32_prop) { -+ tmp_prop = be32_to_cpu(*uint32_prop); -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ -+ err = FM_ConfigTnumAgingPeriod(p_LnxWrpFmDev->h_Dev, -+ (uint16_t)tmp_prop/*tnumAgingPeriod*/); -+ -+ if (err != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ of_node_put(dev_node); -+ -+ return E_OK; -+} -+ -+static void LnxwrpFmDevExceptionsCb(t_Handle h_App, e_FmExceptions exception) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App; -+ -+ ASSERT_COND(p_LnxWrpFmDev); -+ -+ DBG(INFO, ("got fm exception %d", exception)); -+ -+ /* do nothing */ -+ UNUSED(exception); -+} -+ -+static void LnxwrpFmDevBusErrorCb(t_Handle h_App, -+ e_FmPortType portType, -+ uint8_t portId, -+ uint64_t addr, -+ uint8_t tnum, -+ uint16_t liodn) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App; -+ -+ ASSERT_COND(p_LnxWrpFmDev); -+ -+ /* do nothing */ -+ UNUSED(portType);UNUSED(portId);UNUSED(addr);UNUSED(tnum);UNUSED(liodn); -+} -+ -+static t_Error ConfigureFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev) -+{ -+ struct resource *dev_res; -+ int _errno; -+ -+ if (!p_LnxWrpFmDev->active) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!")); -+ -+#ifndef MODULE -+ _errno = can_request_irq(p_LnxWrpFmDev->irq, 0); -+ if (unlikely(_errno < 0)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno)); -+#endif -+ _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, 0, "fman", p_LnxWrpFmDev); -+ if (unlikely(_errno < 0)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->irq, _errno)); -+ -+ enable_irq_wake(p_LnxWrpFmDev->irq); -+ -+ if (p_LnxWrpFmDev->err_irq != 0) { -+#ifndef MODULE -+ _errno = can_request_irq(p_LnxWrpFmDev->err_irq, 0); -+ if (unlikely(_errno < 0)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno)); -+#endif -+ _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, fm_err_irq, IRQF_SHARED, "fman-err", p_LnxWrpFmDev); -+ if (unlikely(_errno < 0)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->err_irq, _errno)); -+ -+ enable_irq_wake(p_LnxWrpFmDev->err_irq); -+ } -+ -+ p_LnxWrpFmDev->res = devm_request_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize, "fman"); -+ if (unlikely(p_LnxWrpFmDev->res == NULL)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_mem_region() failed")); -+ -+ p_LnxWrpFmDev->fmBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize)); -+ if (unlikely(p_LnxWrpFmDev->fmBaseAddr == 0)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed")); -+ -+ if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmBaseAddr, (uint64_t)p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM memory map")); -+ -+ dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize, "fman-muram"); -+ if (unlikely(dev_res == NULL)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed")); -+ -+ p_LnxWrpFmDev->fmMuramBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize)); -+ if (unlikely(p_LnxWrpFmDev->fmMuramBaseAddr == 0)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed")); -+ -+ if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmMuramBaseAddr, (uint64_t)p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM MURAM memory map")); -+ -+ if (p_LnxWrpFmDev->fmRtcPhysBaseAddr) -+ { -+ dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-rtc"); -+ if (unlikely(dev_res == NULL)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed")); -+ -+ p_LnxWrpFmDev->fmRtcBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize)); -+ if (unlikely(p_LnxWrpFmDev->fmRtcBaseAddr == 0)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed")); -+ -+ if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmRtcBaseAddr, (uint64_t)p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC memory map")); -+ } -+ -+#if (DPAA_VERSION >= 11) -+ if (p_LnxWrpFmDev->fmVspPhysBaseAddr) { -+ dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize, "fman-vsp"); -+ if (unlikely(dev_res == NULL)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed")); -+ -+ p_LnxWrpFmDev->fmVspBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize)); -+ if (unlikely(p_LnxWrpFmDev->fmVspBaseAddr == 0)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed")); -+ } -+#endif -+ -+ p_LnxWrpFmDev->fmDevSettings.param.baseAddr = p_LnxWrpFmDev->fmBaseAddr; -+ p_LnxWrpFmDev->fmDevSettings.param.fmId = p_LnxWrpFmDev->id; -+ p_LnxWrpFmDev->fmDevSettings.param.irq = NO_IRQ; -+ p_LnxWrpFmDev->fmDevSettings.param.errIrq = NO_IRQ; -+ p_LnxWrpFmDev->fmDevSettings.param.f_Exception = LnxwrpFmDevExceptionsCb; -+ p_LnxWrpFmDev->fmDevSettings.param.f_BusError = LnxwrpFmDevBusErrorCb; -+ p_LnxWrpFmDev->fmDevSettings.param.h_App = p_LnxWrpFmDev; -+ -+ return FillRestFmInfo(p_LnxWrpFmDev); -+} -+ -+#ifndef CONFIG_FMAN_ARM -+/* -+ * Table for matching compatible strings, for device tree -+ * guts node, for QorIQ SOCs. -+ * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4 -+ * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0" -+ * string would be used. -+*/ -+static const struct of_device_id guts_device_ids[] = { -+ { .compatible = "fsl,qoriq-device-config-1.0", }, -+ { .compatible = "fsl,qoriq-device-config-2.0", }, -+ {} -+}; -+ -+static unsigned int get_rcwsr(int regnum) -+{ -+ struct ccsr_guts __iomem *guts_regs = NULL; -+ struct device_node *guts_node; -+ -+ guts_node = of_find_matching_node(NULL, guts_device_ids); -+ if (!guts_node) { -+ pr_err("could not find GUTS node\n"); -+ return 0; -+ } -+ guts_regs = of_iomap(guts_node, 0); -+ of_node_put(guts_node); -+ if (!guts_regs) { -+ pr_err("ioremap of GUTS node failed\n"); -+ return 0; -+ } -+ -+ return ioread32be(&guts_regs->rcwsr[regnum]); -+} -+ -+#define FMAN1_ALL_MACS_MASK 0xFCC00000 -+#define FMAN2_ALL_MACS_MASK 0x000FCC00 -+ -+/** -+ * @Function ResetOnInitErrata_A007273 -+ * -+ * @Description Workaround for Errata A-007273 -+ * This workaround is required to avoid a FMan hang during reset on initialization. -+ * Enable all MACs in guts.devdisr2 register, -+ * then perform a regular FMan reset and then restore MACs to their original state. -+ * -+ * @Param[in] h_Fm - FM module descriptor -+ * -+ * @Return None. -+ */ -+void ResetOnInitErrata_A007273(t_Handle h_Fm) -+{ -+ struct ccsr_guts __iomem *guts_regs = NULL; -+ struct device_node *guts_node; -+ u32 devdisr2, enableMacs; -+ -+ /* Get guts registers */ -+ guts_node = of_find_matching_node(NULL, guts_device_ids); -+ if (!guts_node) { -+ pr_err("could not find GUTS node\n"); -+ return; -+ } -+ guts_regs = of_iomap(guts_node, 0); -+ of_node_put(guts_node); -+ if (!guts_regs) { -+ pr_err("ioremap of GUTS node failed\n"); -+ return; -+ } -+ -+ /* Read current state */ -+ devdisr2 = ioread32be(&guts_regs->devdisr2); -+ -+ if (FmGetId(h_Fm) == 0) -+ enableMacs = devdisr2 & ~FMAN1_ALL_MACS_MASK; -+ else -+ enableMacs = devdisr2 & ~FMAN2_ALL_MACS_MASK; -+ -+ /* Enable all MACs */ -+ iowrite32be(enableMacs, &guts_regs->devdisr2); -+ -+ /* Perform standard FMan reset */ -+ FmReset(h_Fm); -+ -+ /* Restore devdisr2 value */ -+ iowrite32be(devdisr2, &guts_regs->devdisr2); -+ -+ iounmap(guts_regs); -+} -+#endif -+ -+static t_Error InitFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev) -+{ -+ const struct qe_firmware *fw; -+ -+ if (!p_LnxWrpFmDev->active) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!")); -+ -+ if ((p_LnxWrpFmDev->h_MuramDev = FM_MURAM_ConfigAndInit(p_LnxWrpFmDev->fmMuramBaseAddr, p_LnxWrpFmDev->fmMuramMemSize)) == NULL) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM!")); -+ -+ /* Loading the fman-controller code */ -+ fw = FindFmanMicrocode(); -+ -+ if (!fw) { -+ /* this forces the reuse of the current IRAM content */ -+ p_LnxWrpFmDev->fmDevSettings.param.firmware.size = 0; -+ p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = NULL; -+ } else { -+ p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = -+ (void *) fw + be32_to_cpu(fw->microcode[0].code_offset); -+ p_LnxWrpFmDev->fmDevSettings.param.firmware.size = -+ sizeof(u32) * be32_to_cpu(fw->microcode[0].count); -+ DBG(INFO, ("Loading fman-controller code version %d.%d.%d", -+ fw->microcode[0].major, -+ fw->microcode[0].minor, -+ fw->microcode[0].revision)); -+ } -+ -+#ifdef CONFIG_FMAN_ARM -+ { /* endianness adjustments: byteswap the ucode retrieved from the f/w blob */ -+ int i; -+ int usz = p_LnxWrpFmDev->fmDevSettings.param.firmware.size; -+ void * p_Code = p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code; -+ u32 *dest = kzalloc(usz, GFP_KERNEL); -+ -+ if (p_Code && dest) -+ for(i=0; i < usz / 4; ++i) -+ dest[i] = be32_to_cpu(((u32 *)p_Code)[i]); -+ -+ p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = dest; -+ } -+#endif -+ -+ p_LnxWrpFmDev->fmDevSettings.param.h_FmMuram = p_LnxWrpFmDev->h_MuramDev; -+ -+#if (DPAA_VERSION >= 11) -+ if (p_LnxWrpFmDev->fmVspBaseAddr) { -+ p_LnxWrpFmDev->fmDevSettings.param.vspBaseAddr = p_LnxWrpFmDev->fmVspBaseAddr; -+ p_LnxWrpFmDev->fmDevSettings.param.partVSPBase = 0; -+ p_LnxWrpFmDev->fmDevSettings.param.partNumOfVSPs = FM_VSP_MAX_NUM_OF_ENTRIES; -+ } -+#endif -+ -+#ifdef CONFIG_FMAN_ARM -+ p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1; -+#else -+ if(p_LnxWrpFmDev->fmDevSettings.param.fmId == 0) -+ p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = -+ !!(get_rcwsr(4) & 0x2); /* RCW[FM_MAC_RAT0] */ -+ else -+ p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = -+ !!(get_rcwsr(4) & 0x1); /* RCW[FM_MAC_RAT1] */ -+ -+ { -+ /* T4 Devices ClkRatio is always 1 regardless of RCW[FM_MAC_RAT1] */ -+ uint32_t svr; -+ svr = mfspr(SPRN_SVR); -+ -+ if ((svr & SVR_DEVICE_ID_MASK) == SVR_T4_DEVICE_ID) -+ p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1; -+ } -+#endif /* CONFIG_FMAN_ARM */ -+ -+ if ((p_LnxWrpFmDev->h_Dev = FM_Config(&p_LnxWrpFmDev->fmDevSettings.param)) == NULL) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM")); -+ -+ -+ if (FM_ConfigResetOnInit(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM")); -+ -+#ifndef CONFIG_FMAN_ARM -+#ifdef FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 -+ if (FM_ConfigResetOnInitOverrideCallback(p_LnxWrpFmDev->h_Dev, ResetOnInitErrata_A007273) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM")); -+#endif /* FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 */ -+#endif /* CONFIG_FMAN_ARM */ -+ -+#ifdef CONFIG_FMAN_P1023 -+ if (FM_ConfigDmaAidOverride(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM")); -+#endif -+ -+ -+ CheckNConfigFmAdvArgs(p_LnxWrpFmDev); -+ -+ if (FM_Init(p_LnxWrpFmDev->h_Dev) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM")); -+ -+ /* TODO: Why we mask these interrupts? */ -+ if (p_LnxWrpFmDev->err_irq == 0) { -+ FM_SetException(p_LnxWrpFmDev->h_Dev, e_FM_EX_DMA_BUS_ERROR,FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_READ_ECC,FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SYSTEM_WRITE_ECC,FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_FM_WRITE_ECC,FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SINGLE_PORT_ECC, FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_STALL_ON_TASKS , FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_SINGLE_ECC, FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_DOUBLE_ECC,FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_SINGLE_ECC, FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DOUBLE_ECC,FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_LIST_RAM_ECC,FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STORAGE_PROFILE_ECC, FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STATISTICS_RAM_ECC, FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_DISPATCH_RAM_ECC, FALSE); -+ FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_IRAM_ECC,FALSE); -+ /* TODO: FmDisableRamsEcc assert for ramsEccOwners. -+ * FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_MURAM_ECC,FALSE);*/ -+ } -+ -+ if (p_LnxWrpFmDev->fmRtcBaseAddr) -+ { -+ t_FmRtcParams fmRtcParam; -+ -+ memset(&fmRtcParam, 0, sizeof(fmRtcParam)); -+ fmRtcParam.h_App = p_LnxWrpFmDev; -+ fmRtcParam.h_Fm = p_LnxWrpFmDev->h_Dev; -+ fmRtcParam.baseAddress = p_LnxWrpFmDev->fmRtcBaseAddr; -+ -+ if(!(p_LnxWrpFmDev->h_RtcDev = FM_RTC_Config(&fmRtcParam))) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-RTC")); -+ -+ if (FM_RTC_ConfigPeriod(p_LnxWrpFmDev->h_RtcDev, DPA_PTP_NOMINAL_FREQ_PERIOD_NS) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC")); -+ -+ if (FM_RTC_Init(p_LnxWrpFmDev->h_RtcDev) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC")); -+ } -+ -+ return E_OK; -+} -+ -+/* TODO: to be moved back here */ -+extern void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev); -+ -+static void FreeFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev) -+{ -+ if (!p_LnxWrpFmDev->active) -+ return; -+ -+ FreeFmPcdDev(p_LnxWrpFmDev); -+ -+ if (p_LnxWrpFmDev->h_RtcDev) -+ FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev); -+ -+ if (p_LnxWrpFmDev->h_Dev) -+ FM_Free(p_LnxWrpFmDev->h_Dev); -+ -+ if (p_LnxWrpFmDev->h_MuramDev) -+ FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev); -+ -+ if (p_LnxWrpFmDev->fmRtcBaseAddr) -+ { -+ SYS_UnregisterIoMap(p_LnxWrpFmDev->fmRtcBaseAddr); -+ devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmRtcBaseAddr)); -+ __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize); -+ } -+ SYS_UnregisterIoMap(p_LnxWrpFmDev->fmMuramBaseAddr); -+ devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmMuramBaseAddr)); -+ __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize); -+ SYS_UnregisterIoMap(p_LnxWrpFmDev->fmBaseAddr); -+ devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr)); -+ devm_release_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize); -+ if (p_LnxWrpFmDev->err_irq != 0) { -+ devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, p_LnxWrpFmDev); -+ } -+ -+ devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, p_LnxWrpFmDev); -+} -+ -+/* FMan character device file operations */ -+extern struct file_operations fm_fops; -+ -+static int /*__devinit*/ fm_probe(struct platform_device *of_dev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ -+ if ((p_LnxWrpFmDev = ReadFmDevTreeNode(of_dev)) == NULL) -+ return -EIO; -+ if (ConfigureFmDev(p_LnxWrpFmDev) != E_OK) -+ return -EIO; -+ if (InitFmDev(p_LnxWrpFmDev) != E_OK) -+ return -EIO; -+ -+ /* IOCTL ABI checking */ -+ LnxWrpPCDIOCTLEnumChecking(); -+ LnxWrpPCDIOCTLTypeChecking(); -+ -+ Sprint (p_LnxWrpFmDev->name, "%s%d", DEV_FM_NAME, p_LnxWrpFmDev->id); -+ -+ /* Register to the /dev for IOCTL API */ -+ /* Register dynamically a new major number for the character device: */ -+ if ((p_LnxWrpFmDev->major = register_chrdev(0, p_LnxWrpFmDev->name, &fm_fops)) <= 0) { -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Failed to allocate a major number for device \"%s\"", p_LnxWrpFmDev->name)); -+ return -EIO; -+ } -+ -+ /* Creating classes for FM */ -+ DBG(TRACE ,("class_create fm_class")); -+ p_LnxWrpFmDev->fm_class = class_create(THIS_MODULE, p_LnxWrpFmDev->name); -+ if (IS_ERR(p_LnxWrpFmDev->fm_class)) { -+ unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("class_create error fm_class")); -+ return -EIO; -+ } -+ -+ device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE), NULL, -+ "fm%d", p_LnxWrpFmDev->id); -+ device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE), NULL, -+ "fm%d-pcd", p_LnxWrpFmDev->id); -+ dev_set_drvdata(p_LnxWrpFmDev->dev, p_LnxWrpFmDev); -+ -+ /* create sysfs entries for stats and regs */ -+ if ( fm_sysfs_create(p_LnxWrpFmDev->dev) !=0 ) -+ { -+ FreeFmDev(p_LnxWrpFmDev); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unable to create sysfs entry - fm!!!")); -+ return -EIO; -+ } -+ -+#ifdef CONFIG_PM -+ device_set_wakeup_capable(p_LnxWrpFmDev->dev, true); -+#endif -+ -+ DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id)); -+ -+ return 0; -+} -+ -+static int fm_remove(struct platform_device *of_dev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ struct device *dev; -+ -+ dev = &of_dev->dev; -+ p_LnxWrpFmDev = dev_get_drvdata(dev); -+ -+ fm_sysfs_destroy(dev); -+ -+ DBG(TRACE, ("destroy fm_class")); -+ device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE)); -+ device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE)); -+ class_destroy(p_LnxWrpFmDev->fm_class); -+ -+ /* Destroy chardev */ -+ unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name); -+ -+ FreeFmDev(p_LnxWrpFmDev); -+ -+ DestroyFmDev(p_LnxWrpFmDev); -+ -+ dev_set_drvdata(dev, NULL); -+ -+ return 0; -+} -+ -+static const struct of_device_id fm_match[] = { -+ { -+ .compatible = "fsl,fman" -+ }, -+ {} -+}; -+#ifndef MODULE -+MODULE_DEVICE_TABLE(of, fm_match); -+#endif /* !MODULE */ -+ -+#ifdef CONFIG_PM -+ -+#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C -+#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000 -+#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000 -+ -+struct device *g_fm_dev; -+ -+static int fm_soc_suspend(struct device *dev) -+{ -+ int err = 0; -+ uint32_t *fmclk; -+ t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev)); -+ g_fm_dev = dev; -+ fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4); -+ WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL); -+ if (p_LnxWrpFmDev->h_DsarRxPort) -+ { -+#ifdef CONFIG_FSL_QORIQ_PM -+ device_set_wakeup_enable(p_LnxWrpFmDev->dev, 1); -+#endif -+ err = FM_PORT_EnterDsarFinal(p_LnxWrpFmDev->h_DsarRxPort, -+ p_LnxWrpFmDev->h_DsarTxPort); -+ } -+ return err; -+} -+ -+static int fm_soc_resume(struct device *dev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev)); -+ uint32_t *fmclk; -+ fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4); -+ WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL); -+ if (p_LnxWrpFmDev->h_DsarRxPort) -+ { -+#ifdef CONFIG_FSL_QORIQ_PM -+ device_set_wakeup_enable(p_LnxWrpFmDev->dev, 0); -+#endif -+ FM_PORT_ExitDsar(p_LnxWrpFmDev->h_DsarRxPort, -+ p_LnxWrpFmDev->h_DsarTxPort); -+ p_LnxWrpFmDev->h_DsarRxPort = 0; -+ p_LnxWrpFmDev->h_DsarTxPort = 0; -+ } -+ return 0; -+} -+ -+static const struct dev_pm_ops fm_pm_ops = { -+ .suspend = fm_soc_suspend, -+ .resume = fm_soc_resume, -+}; -+ -+#define FM_PM_OPS (&fm_pm_ops) -+ -+#else /* CONFIG_PM */ -+ -+#define FM_PM_OPS NULL -+ -+#endif /* CONFIG_PM */ -+ -+static struct platform_driver fm_driver = { -+ .driver = { -+ .name = "fsl-fman", -+ .of_match_table = fm_match, -+ .owner = THIS_MODULE, -+ .pm = FM_PM_OPS, -+ }, -+ .probe = fm_probe, -+ .remove = fm_remove -+}; -+ -+t_Handle LNXWRP_FM_Init(void) -+{ -+ memset(&lnxWrpFm, 0, sizeof(lnxWrpFm)); -+ mutex_init(&lnxwrp_mutex); -+ -+ /* Register to the DTB for basic FM API */ -+ platform_driver_register(&fm_driver); -+ -+ return &lnxWrpFm; -+} -+ -+t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm) -+{ -+ platform_driver_unregister(&fm_driver); -+ mutex_destroy(&lnxwrp_mutex); -+ -+ return E_OK; -+} -+ -+ -+struct fm * fm_bind(struct device *fm_dev) -+{ -+ return (struct fm *)(dev_get_drvdata(get_device(fm_dev))); -+} -+EXPORT_SYMBOL(fm_bind); -+ -+void fm_unbind(struct fm *fm) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm; -+ -+ put_device(p_LnxWrpFmDev->dev); -+} -+EXPORT_SYMBOL(fm_unbind); -+ -+struct resource * fm_get_mem_region(struct fm *fm) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm; -+ -+ return p_LnxWrpFmDev->res; -+} -+EXPORT_SYMBOL(fm_get_mem_region); -+ -+void * fm_get_handle(struct fm *fm) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm; -+ -+ return (void *)p_LnxWrpFmDev->h_Dev; -+} -+EXPORT_SYMBOL(fm_get_handle); -+ -+void * fm_get_rtc_handle(struct fm *fm) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm; -+ -+ return (void *)p_LnxWrpFmDev->h_RtcDev; -+} -+EXPORT_SYMBOL(fm_get_rtc_handle); -+ -+struct fm_port * fm_port_bind (struct device *fm_port_dev) -+{ -+ return (struct fm_port *)(dev_get_drvdata(get_device(fm_port_dev))); -+} -+EXPORT_SYMBOL(fm_port_bind); -+ -+void fm_port_unbind(struct fm_port *port) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port; -+ -+ put_device(p_LnxWrpFmPortDev->dev); -+} -+EXPORT_SYMBOL(fm_port_unbind); -+ -+void *fm_port_get_handle(const struct fm_port *port) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port; -+ -+ return (void *)p_LnxWrpFmPortDev->h_Dev; -+} -+EXPORT_SYMBOL(fm_port_get_handle); -+ -+u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port, -+ const void *data) -+{ -+ return FM_PORT_GetBufferTimeStamp(fm_port_get_handle(port), -+ (void *)data); -+} -+EXPORT_SYMBOL(fm_port_get_buffer_time_stamp); -+ -+void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port; -+ -+ *base_addr = p_LnxWrpFmPortDev->settings.param.baseAddr; -+} -+EXPORT_SYMBOL(fm_port_get_base_addr); -+ -+void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port; -+ -+ p_LnxWrpFmPortDev->pcd_owner_params.cba = params->cba; -+ p_LnxWrpFmPortDev->pcd_owner_params.cbf = params->cbf; -+ p_LnxWrpFmPortDev->pcd_owner_params.dev = params->dev; -+} -+EXPORT_SYMBOL(fm_port_pcd_bind); -+ -+void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port; -+ struct device_node *fm_node, *port_node; -+ const uint32_t *uint32_prop; -+ int lenp; -+ -+ params->data_align = 0; -+ params->manip_extra_space = 0; -+ -+ fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id); -+ if (!fm_node) /* no advance parameters for FMan */ -+ return; -+ -+ port_node = GetFmPortAdvArgsDevTreeNode(fm_node, -+ p_LnxWrpFmPortDev->settings.param.portType, -+ p_LnxWrpFmPortDev->settings.param.portId); -+ if (!port_node) /* no advance parameters for FMan-Port */ -+ return; -+ -+ uint32_prop = (uint32_t *)of_get_property(port_node, "buffer-layout", &lenp); -+ if (uint32_prop) { -+ if (WARN_ON(lenp != sizeof(uint32_t)*2)) -+ return; -+ -+ params->manip_extra_space = (uint8_t)be32_to_cpu(uint32_prop[0]); -+ params->data_align = (uint16_t)be32_to_cpu(uint32_prop[1]); -+ } -+ -+ of_node_put(port_node); -+ of_node_put(fm_node); -+} -+EXPORT_SYMBOL(fm_port_get_buff_layout_ext_params); -+ -+uint16_t fm_get_tx_port_channel(struct fm_port *port) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port; -+ -+ return p_LnxWrpFmPortDev->txCh; -+} -+EXPORT_SYMBOL(fm_get_tx_port_channel); -+ -+int fm_port_enable (struct fm_port *port) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port; -+ t_Error err = FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev); -+ -+ return GET_ERROR_TYPE(err); -+} -+EXPORT_SYMBOL(fm_port_enable); -+ -+int fm_port_disable(struct fm_port *port) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port; -+ t_Error err = FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev); -+ -+ return GET_ERROR_TYPE(err); -+} -+EXPORT_SYMBOL(fm_port_disable); -+ -+int fm_port_set_rate_limit(struct fm_port *port, -+ uint16_t max_burst_size, -+ uint32_t rate_limit) -+{ -+ t_FmPortRateLimit param; -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port; -+ int err = 0; -+ -+ param.maxBurstSize = max_burst_size; -+ param.rateLimit = rate_limit; -+ param.rateLimitDivider = 0; -+ -+ err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, ¶m); -+ return err; -+} -+EXPORT_SYMBOL(fm_port_set_rate_limit); -+ -+int fm_port_del_rate_limit(struct fm_port *port) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port; -+ -+ FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev); -+ return 0; -+} -+EXPORT_SYMBOL(fm_port_del_rate_limit); -+ -+void FM_PORT_Dsar_DumpRegs(void); -+int ar_showmem(struct file *file, const char __user *buffer, -+ unsigned long count, void *data) -+{ -+ FM_PORT_Dsar_DumpRegs(); -+ return 2; -+} -+ -+struct auto_res_tables_sizes *fm_port_get_autores_maxsize( -+ struct fm_port *port) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port; -+ return &p_LnxWrpFmPortDev->dsar_table_sizes; -+} -+EXPORT_SYMBOL(fm_port_get_autores_maxsize); -+ -+int fm_port_enter_autores_for_deepsleep(struct fm_port *port, -+ struct auto_res_port_params *params) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port; -+ t_LnxWrpFmDev* p_LnxWrpFmDev = (t_LnxWrpFmDev*)p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ p_LnxWrpFmDev->h_DsarRxPort = p_LnxWrpFmPortDev->h_Dev; -+ p_LnxWrpFmDev->h_DsarTxPort = params->h_FmPortTx; -+ -+ /*Register other under /proc/autoresponse */ -+ if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params))) -+ return -EFAULT; -+ -+ FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params); -+ return 0; -+} -+EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep); -+ -+void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx, -+ struct fm_port *port_tx) -+{ -+} -+EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep); -+ -+int fm_port_get_autores_stats(struct fm_port *port, -+ struct auto_res_port_stats *stats) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port; -+ if (WARN_ON(sizeof(t_FmPortDsarStats) != sizeof(struct auto_res_port_stats))) -+ return -EFAULT; -+ return FM_PORT_GetDsarStats(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarStats*)stats); -+} -+EXPORT_SYMBOL(fm_port_get_autores_stats); -+ -+int fm_port_suspend(struct fm_port *port) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port; -+ if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) -+ return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev); -+ else -+ return 0; -+} -+EXPORT_SYMBOL(fm_port_suspend); -+ -+int fm_port_resume(struct fm_port *port) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port; -+ if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) -+ return FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev); -+ else -+ return 0; -+} -+EXPORT_SYMBOL(fm_port_resume); -+ -+bool fm_port_is_in_auto_res_mode(struct fm_port *port) -+{ -+ return FM_PORT_IsInDsar(port); -+} -+EXPORT_SYMBOL(fm_port_is_in_auto_res_mode); -+ -+#ifdef CONFIG_FMAN_PFC -+int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port, -+ uint8_t prio, uint8_t wq) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port; -+ int err; -+ int _errno; -+ -+ err = FM_PORT_SetPfcPrioritiesMappingToQmanWQ(p_LnxWrpFmPortDev->h_Dev, -+ prio, wq); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_PORT_SetPfcPrioritiesMappingToQmanWQ() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_port_set_pfc_priorities_mapping_to_qman_wq); -+#endif -+ -+int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev, -+ e_FmMacExceptions exception, bool enable) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MAC_SetException(fm_mac_dev, exception, enable); -+ -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_SetException() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_set_exception); -+ -+int fm_mac_free(struct fm_mac_dev *fm_mac_dev) -+{ -+ int err; -+ int _error; -+ -+ err = FM_MAC_Free(fm_mac_dev); -+ _error = -GET_ERROR_TYPE(err); -+ -+ if (unlikely(_error < 0)) -+ pr_err("FM_MAC_Free() = 0x%08x\n", err); -+ -+ return _error; -+} -+EXPORT_SYMBOL(fm_mac_free); -+ -+struct fm_mac_dev *fm_mac_config(t_FmMacParams *params) -+{ -+ struct fm_mac_dev *fm_mac_dev; -+ -+ fm_mac_dev = FM_MAC_Config(params); -+ if (unlikely(fm_mac_dev == NULL)) -+ pr_err("FM_MAC_Config() failed\n"); -+ -+ return fm_mac_dev; -+} -+EXPORT_SYMBOL(fm_mac_config); -+ -+int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev, -+ int len) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MAC_ConfigMaxFrameLength(fm_mac_dev, len); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_config_max_frame_length); -+ -+int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MAC_ConfigPadAndCrc(fm_mac_dev, enable); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_ConfigPadAndCrc() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_config_pad_and_crc); -+ -+int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MAC_ConfigHalfDuplex(fm_mac_dev, enable); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_ConfigHalfDuplex() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_config_half_duplex); -+ -+int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MAC_ConfigResetOnInit(fm_mac_dev, enable); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_ConfigResetOnInit() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_config_reset_on_init); -+ -+int fm_mac_init(struct fm_mac_dev *fm_mac_dev) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MAC_Init(fm_mac_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_Init() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_init); -+ -+int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MAC_GetVesrion(fm_mac_dev, version); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_GetVesrion() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_get_version); -+ -+int fm_mac_enable(struct fm_mac_dev *fm_mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_MAC_Enable(fm_mac_dev, e_COMM_MODE_RX_AND_TX); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_Enable() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_enable); -+ -+int fm_mac_disable(struct fm_mac_dev *fm_mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_MAC_Disable(fm_mac_dev, e_COMM_MODE_RX_AND_TX); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_Disable() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_disable); -+ -+int fm_mac_resume(struct fm_mac_dev *fm_mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_MAC_Resume(fm_mac_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_Resume() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_resume); -+ -+int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev, -+ bool enable) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_MAC_SetPromiscuous(fm_mac_dev, enable); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_SetPromiscuous() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_set_promiscuous); -+ -+int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev, -+ t_EnetAddr *mac_addr) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_MAC_RemoveHashMacAddr(fm_mac_dev, mac_addr); -+ _errno = -GET_ERROR_TYPE(err); -+ if (_errno < 0) { -+ pr_err("FM_MAC_RemoveHashMacAddr() = 0x%08x\n", err); -+ return _errno; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(fm_mac_remove_hash_mac_addr); -+ -+int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev, -+ t_EnetAddr *mac_addr) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_MAC_AddHashMacAddr(fm_mac_dev, mac_addr); -+ _errno = -GET_ERROR_TYPE(err); -+ if (_errno < 0) { -+ pr_err("FM_MAC_AddHashMacAddr() = 0x%08x\n", err); -+ return _errno; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(fm_mac_add_hash_mac_addr); -+ -+int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev, -+ uint8_t *addr) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_MAC_ModifyMacAddr(fm_mac_dev, (t_EnetAddr *)addr); -+ _errno = -GET_ERROR_TYPE(err); -+ if (_errno < 0) -+ pr_err("FM_MAC_ModifyMacAddr() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_modify_mac_addr); -+ -+int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev, -+ bool link, int speed, bool duplex) -+{ -+ int _errno; -+ t_Error err; -+ -+ if (!link) { -+#if (DPAA_VERSION < 11) -+ FM_MAC_RestartAutoneg(fm_mac_dev); -+#endif -+ return 0; -+ } -+ -+ err = FM_MAC_AdjustLink(fm_mac_dev, speed, duplex); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_AdjustLink() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_adjust_link); -+ -+int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_MAC_Enable1588TimeStamp(fm_mac_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_Enable1588TimeStamp() = 0x%08x\n", err); -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_enable_1588_time_stamp); -+ -+int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_MAC_Disable1588TimeStamp(fm_mac_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_Disable1588TimeStamp() = 0x%08x\n", err); -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_disable_1588_time_stamp); -+ -+int fm_mac_set_rx_pause_frames( -+ struct fm_mac_dev *fm_mac_dev, bool en) -+{ -+ int _errno; -+ t_Error err; -+ -+ /* if rx pause is enabled, do NOT ignore pause frames */ -+ err = FM_MAC_SetRxIgnorePauseFrames(fm_mac_dev, !en); -+ -+ _errno = -GET_ERROR_TYPE(err); -+ if (_errno < 0) -+ pr_err("FM_MAC_SetRxIgnorePauseFrames() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_set_rx_pause_frames); -+ -+#ifdef CONFIG_FMAN_PFC -+int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev, -+ bool en) -+{ -+ int _errno, i; -+ t_Error err; -+ -+ if (en) -+ for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) { -+ err = FM_MAC_SetTxPauseFrames(fm_mac_dev, -+ i, fsl_fm_pfc_quanta[i], -+ FSL_FM_PAUSE_THRESH_DEFAULT); -+ _errno = -GET_ERROR_TYPE(err); -+ if (_errno < 0) { -+ pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err); -+ return _errno; -+ } -+ } -+ else -+ for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) { -+ err = FM_MAC_SetTxPauseFrames(fm_mac_dev, -+ i, FSL_FM_PAUSE_TIME_DISABLE, -+ FSL_FM_PAUSE_THRESH_DEFAULT); -+ _errno = -GET_ERROR_TYPE(err); -+ if (_errno < 0) { -+ pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err); -+ return _errno; -+ } -+ } -+ -+ return _errno; -+} -+#else -+int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev, -+ bool en) -+{ -+ int _errno; -+ t_Error err; -+ -+ if (en) -+ err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev, -+ FSL_FM_PAUSE_TIME_ENABLE); -+ else -+ err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev, -+ FSL_FM_PAUSE_TIME_DISABLE); -+ -+ _errno = -GET_ERROR_TYPE(err); -+ if (_errno < 0) -+ pr_err("FM_MAC_SetTxAutoPauseFrames() = 0x%08x\n", err); -+ -+ return _errno; -+} -+#endif -+EXPORT_SYMBOL(fm_mac_set_tx_pause_frames); -+ -+int fm_rtc_enable(struct fm *fm_dev) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_Enable(fm_get_rtc_handle(fm_dev), 0); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_RTC_Enable = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_rtc_enable); -+ -+int fm_rtc_disable(struct fm *fm_dev) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_Disable(fm_get_rtc_handle(fm_dev)); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_RTC_Disable = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_rtc_disable); -+ -+int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_GetCurrentTime(fm_get_rtc_handle(fm_dev), ts); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_RTC_GetCurrentTime = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_rtc_get_cnt); -+ -+int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_SetCurrentTime(fm_get_rtc_handle(fm_dev), ts); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_RTC_SetCurrentTime = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_rtc_set_cnt); -+ -+int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_GetFreqCompensation(fm_get_rtc_handle(fm_dev), -+ drift); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_RTC_GetFreqCompensation = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_rtc_get_drift); -+ -+int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_SetFreqCompensation(fm_get_rtc_handle(fm_dev), -+ drift); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_RTC_SetFreqCompensation = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_rtc_set_drift); -+ -+int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id, -+ uint64_t time) -+{ -+ t_FmRtcAlarmParams alarm; -+ int _errno; -+ t_Error err; -+ -+ alarm.alarmId = id; -+ alarm.alarmTime = time; -+ alarm.f_AlarmCallback = NULL; -+ err = FM_RTC_SetAlarm(fm_get_rtc_handle(fm_dev), -+ &alarm); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_RTC_SetAlarm = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_rtc_set_alarm); -+ -+int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id, -+ uint64_t fiper) -+{ -+ t_FmRtcPeriodicPulseParams pp; -+ int _errno; -+ t_Error err; -+ -+ pp.periodicPulseId = id; -+ pp.periodicPulsePeriod = fiper; -+ pp.f_PeriodicPulseCallback = NULL; -+ err = FM_RTC_SetPeriodicPulse(fm_get_rtc_handle(fm_dev), &pp); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_RTC_SetPeriodicPulse = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_rtc_set_fiper); -+ -+#ifdef CONFIG_PTP_1588_CLOCK_DPAA -+int fm_rtc_enable_interrupt(struct fm *fm_dev, uint32_t events) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_EnableInterrupt(fm_get_rtc_handle(fm_dev), -+ events); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_RTC_EnableInterrupt = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_rtc_enable_interrupt); -+ -+int fm_rtc_disable_interrupt(struct fm *fm_dev, uint32_t events) -+{ -+ int _errno; -+ t_Error err; -+ -+ err = FM_RTC_DisableInterrupt(fm_get_rtc_handle(fm_dev), -+ events); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_RTC_DisableInterrupt = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_rtc_disable_interrupt); -+#endif -+ -+int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, bool en) -+{ -+ int _errno; -+ t_Error err; -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port; -+ -+ /* Do not set WoL on AR ports */ -+ if (FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) { -+ printk(KERN_WARNING "Port is AutoResponse enabled! WoL will not be set on this port!\n"); -+ return 0; -+ } -+ -+ err = FM_MAC_SetWakeOnLan(fm_mac_dev, en); -+ -+ _errno = -GET_ERROR_TYPE(err); -+ if (_errno < 0) -+ pr_err("FM_MAC_SetWakeOnLan() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_mac_set_wol); -+ -+void fm_mutex_lock(void) -+{ -+ mutex_lock(&lnxwrp_mutex); -+} -+EXPORT_SYMBOL(fm_mutex_lock); -+ -+void fm_mutex_unlock(void) -+{ -+ mutex_unlock(&lnxwrp_mutex); -+} -+EXPORT_SYMBOL(fm_mutex_unlock); -+ -+/*Macsec wrapper functions*/ -+struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params) -+{ -+ struct fm_macsec_dev *fm_macsec_dev; -+ -+ fm_macsec_dev = FM_MACSEC_Config((t_FmMacsecParams *)fm_params); -+ if (unlikely(fm_macsec_dev == NULL)) -+ pr_err("FM_MACSEC_Config() failed\n"); -+ -+ return fm_macsec_dev; -+} -+EXPORT_SYMBOL(fm_macsec_config); -+ -+int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_Init(fm_macsec_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_Init() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_init); -+ -+int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev) -+{ -+ int err; -+ int _error; -+ -+ err = FM_MACSEC_Free(fm_macsec_dev); -+ _error = -GET_ERROR_TYPE(err); -+ -+ if (unlikely(_error < 0)) -+ pr_err("FM_MACSEC_Free() = 0x%08x\n", err); -+ -+ return _error; -+} -+EXPORT_SYMBOL(fm_macsec_free); -+ -+int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev -+ *fm_macsec_dev, -+ fm_macsec_unknown_sci_frame_treatment treat_mode) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_ConfigUnknownSciFrameTreatment(fm_macsec_dev, -+ treat_mode); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_ConfigUnknownSciFrameTreatmen() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_config_unknown_sci_frame_treatment); -+ -+int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev, -+ bool deliver_uncontrolled) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_ConfigInvalidTagsFrameTreatment(fm_macsec_dev, -+ deliver_uncontrolled); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_config_invalid_tags_frame_treatment); -+ -+int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev, -+ bool discard_uncontrolled) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(fm_macsec_dev, -+ discard_uncontrolled); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatmen() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_config_kay_frame_treatment); -+ -+int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev, -+ fm_macsec_untag_frame_treatment treat_mode) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_ConfigUntagFrameTreatment(fm_macsec_dev, treat_mode); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_ConfigUntagFrameTreatment() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_config_untag_frame_treatment); -+ -+int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev, -+ uint32_t pn_exh_thr) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_ConfigPnExhaustionThreshold(fm_macsec_dev, pn_exh_thr); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_ConfigPnExhaustionThreshold() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_config_pn_exhaustion_threshold); -+ -+int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_ConfigKeysUnreadable(fm_macsec_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_ConfigKeysUnreadable() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_config_keys_unreadable); -+ -+int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_ConfigSectagWithoutSCI(fm_macsec_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_ConfigSectagWithoutSCI() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_config_sectag_without_sci); -+ -+int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev, -+ fm_macsec_exception exception, bool enable) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_ConfigException(fm_macsec_dev, exception, enable); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_ConfigException() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_config_exception); -+ -+int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev, -+ int *macsec_revision) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_GetRevision(fm_macsec_dev, macsec_revision); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_GetRevision() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_get_revision); -+ -+int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_Enable(fm_macsec_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_Enable() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_enable); -+ -+int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_Disable(fm_macsec_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_Disable() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_disable); -+ -+int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev, -+ fm_macsec_exception exception, bool enable) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SetException(fm_macsec_dev, exception, enable); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SetException() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_set_exception); -+ -+/* Macsec SECY wrapper API */ -+struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params) -+{ -+ struct fm_macsec_secy_dev *fm_macsec_secy; -+ -+ fm_macsec_secy = FM_MACSEC_SECY_Config((t_FmMacsecSecYParams *)secy_params); -+ if (unlikely(fm_macsec_secy < 0)) -+ pr_err("FM_MACSEC_SECY_Config() failed\n"); -+ -+ return fm_macsec_secy; -+} -+EXPORT_SYMBOL(fm_macsec_secy_config); -+ -+int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_Init(fm_macsec_secy_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_Init() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_init); -+ -+int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_Free(fm_macsec_secy_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_Free() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_free); -+ -+int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ fm_macsec_sci_insertion_mode sci_insertion_mode) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_ConfigSciInsertionMode(fm_macsec_secy_dev, -+ sci_insertion_mode); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_ConfigSciInsertionMode() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_config_sci_insertion_mode); -+ -+int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ bool protect_frames) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_ConfigProtectFrames(fm_macsec_secy_dev, -+ protect_frames); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_ConfigProtectFrames() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_config_protect_frames); -+ -+int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ bool replay_protect, uint32_t replay_window) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_ConfigReplayWindow(fm_macsec_secy_dev, -+ replay_protect, replay_window); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_ConfigReplayWindow() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_config_replay_window); -+ -+int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ fm_macsec_valid_frame_behavior validate_frames) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_ConfigValidationMode(fm_macsec_secy_dev, -+ validate_frames); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_ConfigValidationMode() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_config_validation_mode); -+ -+int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ bool confidentiality_enable, -+ uint32_t confidentiality_offset) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_ConfigConfidentiality(fm_macsec_secy_dev, -+ confidentiality_enable, -+ confidentiality_offset); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_ConfigConfidentiality() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_config_confidentiality); -+ -+int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_ConfigPointToPoint(fm_macsec_secy_dev); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_ConfigPointToPoint() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_config_point_to_point); -+ -+int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ fm_macsec_secy_exception exception, -+ bool enable) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_ConfigException(fm_macsec_secy_dev, exception, -+ enable); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_ConfigException() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_config_exception); -+ -+int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ fm_macsec_secy_event event, -+ bool enable) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_ConfigEvent(fm_macsec_secy_dev, event, enable); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_ConfigEvent() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_config_event); -+ -+struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct fm_macsec_secy_sc_params *params) -+{ -+ struct rx_sc_dev *rx_sc_dev; -+ -+ rx_sc_dev = FM_MACSEC_SECY_CreateRxSc(fm_macsec_secy_dev, (t_FmMacsecSecYSCParams *)params); -+ if (unlikely(rx_sc_dev == NULL)) -+ pr_err("FM_MACSEC_SECY_CreateRxSc() failed\n"); -+ -+ return rx_sc_dev; -+} -+EXPORT_SYMBOL(fm_macsec_secy_create_rxsc); -+ -+int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_DeleteRxSc(fm_macsec_secy_dev, sc); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_DeleteRxSc() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_delete_rxsc); -+ -+int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, macsec_an_t an, -+ uint32_t lowest_pn, macsec_sa_key_t key) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_CreateRxSa(fm_macsec_secy_dev, sc, an, -+ lowest_pn, key); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_CreateRxSa() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_create_rx_sa); -+ -+int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, macsec_an_t an) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_DeleteRxSa(fm_macsec_secy_dev, sc, an); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_DeleteRxSa() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_delete_rx_sa); -+ -+int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, -+ macsec_an_t an) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_RxSaEnableReceive(fm_macsec_secy_dev, sc, an); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_RxSaEnableReceive() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_rxsa_enable_receive); -+ -+int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, -+ macsec_an_t an) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_RxSaDisableReceive(fm_macsec_secy_dev, sc, an); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_RxSaDisableReceive() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_rxsa_disable_receive); -+ -+int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, -+ macsec_an_t an, uint32_t updt_next_pn) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_RxSaUpdateNextPn(fm_macsec_secy_dev, sc, an, -+ updt_next_pn); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_RxSaUpdateNextPn() = 0x%08x\n", err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_next_pn); -+ -+int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, -+ macsec_an_t an, uint32_t updt_lowest_pn) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_RxSaUpdateLowestPn(fm_macsec_secy_dev, sc, an, -+ updt_lowest_pn); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_RxSaUpdateLowestPn() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_lowest_pn); -+ -+int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, -+ macsec_an_t an, macsec_sa_key_t key) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_RxSaModifyKey(fm_macsec_secy_dev, sc, an, key); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_RxSaModifyKey() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_rxsa_modify_key); -+ -+int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ macsec_an_t an, macsec_sa_key_t key) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_CreateTxSa(fm_macsec_secy_dev, an, key); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_CreateTxSa() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_create_tx_sa); -+ -+int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ macsec_an_t an) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_DeleteTxSa(fm_macsec_secy_dev, an); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_DeleteTxSa() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_delete_tx_sa); -+ -+int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ macsec_an_t next_active_an, -+ macsec_sa_key_t key) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_TxSaModifyKey(fm_macsec_secy_dev, next_active_an, -+ key); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_TxSaModifyKey() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_txsa_modify_key); -+ -+int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ macsec_an_t an) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_TxSaSetActive(fm_macsec_secy_dev, an); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_TxSaSetActive() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_txsa_set_active); -+ -+int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ macsec_an_t *p_an) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_TxSaGetActive(fm_macsec_secy_dev, p_an); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_TxSaGetActive() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_txsa_get_active); -+ -+int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ struct rx_sc_dev *sc, uint32_t *sc_phys_id) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_GetRxScPhysId(fm_macsec_secy_dev, sc, sc_phys_id); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_GetRxScPhysId() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_get_rxsc_phys_id); -+ -+int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev, -+ uint32_t *sc_phys_id) -+{ -+ int err; -+ int _errno; -+ -+ err = FM_MACSEC_SECY_GetTxScPhysId(fm_macsec_secy_dev, sc_phys_id); -+ _errno = -GET_ERROR_TYPE(err); -+ if (unlikely(_errno < 0)) -+ pr_err("FM_MACSEC_SECY_GetTxScPhysId() = 0x%08x\n", -+ err); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(fm_macsec_secy_get_txsc_phys_id); -+ -+static t_Handle h_FmLnxWrp; -+ -+static int __init __cold fm_load (void) -+{ -+ if ((h_FmLnxWrp = LNXWRP_FM_Init()) == NULL) -+ { -+ printk("Failed to init FM wrapper!\n"); -+ return -ENODEV; -+ } -+ -+ printk(KERN_CRIT "Freescale FM module," \ -+ " FMD API version %d.%d.%d\n", -+ FMD_API_VERSION_MAJOR, -+ FMD_API_VERSION_MINOR, -+ FMD_API_VERSION_RESPIN); -+ return 0; -+} -+ -+static void __exit __cold fm_unload (void) -+{ -+ if (h_FmLnxWrp) -+ LNXWRP_FM_Free(h_FmLnxWrp); -+} -+ -+module_init (fm_load); -+module_exit (fm_unload); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h -@@ -0,0 +1,294 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ @File lnxwrp_fm.h -+ -+ @Author Shlomi Gridish -+ -+ @Description FM Linux wrapper functions. -+ -+*/ -+ -+#ifndef __LNXWRP_FM_H__ -+#define __LNXWRP_FM_H__ -+ -+#include /* struct qman_fq */ -+ -+#include "std_ext.h" -+#include "error_ext.h" -+#include "list_ext.h" -+ -+#include "lnxwrp_fm_ext.h" -+ -+#define FM_MAX_NUM_OF_ADV_SETTINGS 10 -+ -+#define LNXWRP_FM_NUM_OF_SHARED_PROFILES 16 -+ -+#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES) -+#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */ -+#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */ -+#else -+#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */ -+#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */ -+#endif -+#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */ -+#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */ -+ -+#define FRAG_MANIP_SPACE 128 -+#define FRAG_DATA_ALIGN 64 -+ -+#ifndef CONFIG_FSL_FM_MAX_FRAME_SIZE -+#define CONFIG_FSL_FM_MAX_FRAME_SIZE 0 -+#endif -+ -+#ifndef CONFIG_FSL_FM_RX_EXTRA_HEADROOM -+#define CONFIG_FSL_FM_RX_EXTRA_HEADROOM 16 -+#endif -+ -+typedef enum { -+ e_NO_PCD = 0, -+ e_FM_PCD_3_TUPLE -+} e_LnxWrpFmPortPcdDefUseCase; -+ -+ -+typedef struct t_FmTestFq { -+ struct qman_fq fq_base; -+ t_Handle h_Arg; -+} t_FmTestFq; -+ -+typedef struct { -+ uint8_t id; /* sw port id, see SW_PORT_ID_TO_HW_PORT_ID() in fm_common.h */ -+ int minor; -+ char name[20]; -+ bool active; -+ uint64_t phys_baseAddr; -+ uint64_t baseAddr; /* Port's *virtual* address */ -+ uint32_t memSize; -+ t_WrpFmPortDevSettings settings; -+ t_FmExtPools opExtPools; -+ uint8_t totalNumOfSchemes; -+ uint8_t schemesBase; -+ uint8_t numOfSchemesUsed; -+ uint32_t pcdBaseQ; -+ uint16_t pcdNumOfQs; -+ struct fm_port_pcd_param pcd_owner_params; -+ e_LnxWrpFmPortPcdDefUseCase defPcd; -+ t_Handle h_DefNetEnv; -+ t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; -+ t_FmBufferPrefixContent buffPrefixContent; -+ t_Handle h_Dev; -+ t_Handle h_DfltVsp; -+ t_Handle h_LnxWrpFmDev; -+ uint16_t txCh; -+ struct device *dev; -+ struct device_attribute *dev_attr_stats; -+ struct device_attribute *dev_attr_regs; -+ struct device_attribute *dev_attr_bmi_regs; -+ struct device_attribute *dev_attr_qmi_regs; -+#if (DPAA_VERSION >= 11) -+ struct device_attribute *dev_attr_ipv4_opt; -+#endif -+ struct device_attribute *dev_attr_dsar_regs; -+ struct device_attribute *dev_attr_dsar_mem; -+ struct auto_res_tables_sizes dsar_table_sizes; -+} t_LnxWrpFmPortDev; -+ -+typedef struct { -+ uint8_t id; -+ bool active; -+ uint64_t baseAddr; -+ uint32_t memSize; -+ t_WrpFmMacDevSettings settings; -+ t_Handle h_Dev; -+ t_Handle h_LnxWrpFmDev; -+} t_LnxWrpFmMacDev; -+ -+/* information about all active ports for an FMan. -+ * !Some ports may be disabled by u-boot, thus will not be available */ -+struct fm_active_ports { -+ uint32_t num_oh_ports; -+ uint32_t num_tx_ports; -+ uint32_t num_rx_ports; -+ uint32_t num_tx25_ports; -+ uint32_t num_rx25_ports; -+ uint32_t num_tx10_ports; -+ uint32_t num_rx10_ports; -+}; -+ -+/* FMan resources precalculated at fm probe based -+ * on available FMan port. */ -+struct fm_resource_settings { -+ /* buffers - fifo sizes */ -+ uint32_t tx1g_num_buffers; -+ uint32_t rx1g_num_buffers; -+ uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */ -+ uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */ -+ uint32_t tx10g_num_buffers; -+ uint32_t rx10g_num_buffers; -+ uint32_t oh_num_buffers; -+ uint32_t shared_ext_buffers; -+ -+ /* open DMAs */ -+ uint32_t tx_1g_dmas; -+ uint32_t rx_1g_dmas; -+ uint32_t tx_2g5_dmas; /* Not supported yet by LLD */ -+ uint32_t rx_2g5_dmas; /* Not supported yet by LLD */ -+ uint32_t tx_10g_dmas; -+ uint32_t rx_10g_dmas; -+ uint32_t oh_dmas; -+ uint32_t shared_ext_open_dma; -+ -+ /* Tnums */ -+ uint32_t tx_1g_tnums; -+ uint32_t rx_1g_tnums; -+ uint32_t tx_2g5_tnums; /* Not supported yet by LLD */ -+ uint32_t rx_2g5_tnums; /* Not supported yet by LLD */ -+ uint32_t tx_10g_tnums; -+ uint32_t rx_10g_tnums; -+ uint32_t oh_tnums; -+ uint32_t shared_ext_tnums; -+}; -+ -+typedef struct { -+ uint8_t id; -+ char name[10]; -+ bool active; -+ bool pcdActive; -+ bool prsActive; -+ bool kgActive; -+ bool ccActive; -+ bool plcrActive; -+ e_LnxWrpFmPortPcdDefUseCase defPcd; -+ uint32_t usedSchemes; -+ uint8_t totalNumOfSharedSchemes; -+ uint8_t sharedSchemesBase; -+ uint8_t numOfSchemesUsed; -+ uint8_t defNetEnvId; -+ uint64_t fmPhysBaseAddr; -+ uint64_t fmBaseAddr; -+ uint32_t fmMemSize; -+ uint64_t fmMuramPhysBaseAddr; -+ uint64_t fmMuramBaseAddr; -+ uint32_t fmMuramMemSize; -+ uint64_t fmRtcPhysBaseAddr; -+ uint64_t fmRtcBaseAddr; -+ uint32_t fmRtcMemSize; -+ uint64_t fmVspPhysBaseAddr; -+ uint64_t fmVspBaseAddr; -+ uint32_t fmVspMemSize; -+ int irq; -+ int err_irq; -+ t_WrpFmDevSettings fmDevSettings; -+ t_WrpFmPcdDevSettings fmPcdDevSettings; -+ t_Handle h_Dev; -+ uint16_t hcCh; -+ -+ t_Handle h_MuramDev; -+ t_Handle h_PcdDev; -+ t_Handle h_RtcDev; -+ -+ t_Handle h_DsarRxPort; -+ t_Handle h_DsarTxPort; -+ -+ t_LnxWrpFmPortDev hcPort; -+ t_LnxWrpFmPortDev opPorts[FM_MAX_NUM_OF_OH_PORTS-1]; -+ t_LnxWrpFmPortDev rxPorts[FM_MAX_NUM_OF_RX_PORTS]; -+ t_LnxWrpFmPortDev txPorts[FM_MAX_NUM_OF_TX_PORTS]; -+ t_LnxWrpFmMacDev macs[FM_MAX_NUM_OF_MACS]; -+ struct fm_active_ports fm_active_ports_info; -+ struct fm_resource_settings fm_resource_settings_info; -+ -+ struct device *dev; -+ struct resource *res; -+ int major; -+ struct class *fm_class; -+ struct device_attribute *dev_attr_stats; -+ struct device_attribute *dev_attr_regs; -+ struct device_attribute *dev_attr_risc_load; -+ -+ struct device_attribute *dev_pcd_attr_stats; -+ struct device_attribute *dev_plcr_attr_regs; -+ struct device_attribute *dev_prs_attr_regs; -+ struct device_attribute *dev_fm_fpm_attr_regs; -+ struct device_attribute *dev_fm_kg_attr_regs; -+ struct device_attribute *dev_fm_kg_pe_attr_regs; -+ struct device_attribute *dev_attr_muram_free_size; -+ struct device_attribute *dev_attr_fm_ctrl_code_ver; -+ -+ -+ struct qman_fq *hc_tx_conf_fq, *hc_tx_err_fq, *hc_tx_fq; -+} t_LnxWrpFmDev; -+ -+typedef struct { -+ t_LnxWrpFmDev *p_FmDevs[INTG_MAX_NUM_OF_FM]; -+} t_LnxWrpFm; -+#define LNXWRP_FM_OBJECT(ptr) LIST_OBJECT(ptr, t_LnxWrpFm, fms[((t_LnxWrpFmDev *)ptr)->id]) -+ -+ -+t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat); -+t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat); -+ -+ -+#if 0 -+static __inline__ t_Error AllocSchemesForPort(t_LnxWrpFmDev *p_LnxWrpFmDev, uint8_t numSchemes, uint8_t *p_BaseSchemeNum) -+{ -+ uint32_t schemeMask; -+ uint8_t i; -+ -+ if (!numSchemes) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ -+ schemeMask = 0x80000000; -+ *p_BaseSchemeNum = 0xff; -+ -+ for (i=0; schemeMask && numSchemes; schemeMask>>=1, i++) -+ if ((p_LnxWrpFmDev->usedSchemes & schemeMask) == 0) -+ { -+ p_LnxWrpFmDev->usedSchemes |= schemeMask; -+ numSchemes--; -+ if (*p_BaseSchemeNum==0xff) -+ *p_BaseSchemeNum = i; -+ } -+ else if (*p_BaseSchemeNum!=0xff) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("Fragmentation on schemes array!!!")); -+ -+ if (numSchemes) -+ RETURN_ERROR(MINOR, E_FULL, ("schemes!!!")); -+ return E_OK; -+} -+#endif -+ -+void LnxWrpPCDIOCTLTypeChecking(void); -+void LnxWrpPCDIOCTLEnumChecking(void); -+ -+#endif /* __LNXWRP_FM_H__ */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c -@@ -0,0 +1,1480 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ @File lnxwrp_fm_port.c -+ -+ @Description FMD wrapper - FMan port functions. -+ -+*/ -+ -+#include -+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) -+#define MODVERSIONS -+#endif -+#ifdef MODVERSIONS -+#include -+#endif /* MODVERSIONS */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifndef CONFIG_FMAN_ARM -+#include -+#endif -+#include -+ -+#include "sprint_ext.h" -+#include "fm_common.h" -+#include "lnxwrp_fsl_fman.h" -+#include "fm_port_ext.h" -+#if (DPAA_VERSION >= 11) -+#include "fm_vsp_ext.h" -+#endif /* DPAA_VERSION >= 11 */ -+#include "fm_ioctls.h" -+#include "lnxwrp_resources.h" -+#include "lnxwrp_sysfs_fm_port.h" -+ -+#define __ERR_MODULE__ MODULE_FM -+ -+extern struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx); -+ -+/* TODO: duplicated, see lnxwrp_fm.c */ -+#define ADD_ADV_CONFIG_NO_RET(_func, _param)\ -+do {\ -+ if (i < max) {\ -+ p_Entry = &p_Entrys[i];\ -+ p_Entry->p_Function = _func;\ -+ _param\ -+ i++;\ -+ } else {\ -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE,\ -+ ("Number of advanced-configuration entries exceeded"));\ -+ } \ -+} while (0) -+ -+#ifndef CONFIG_FMAN_ARM -+#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \ -+ SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023) -+#endif -+ -+static volatile int hcFrmRcv/* = 0 */; -+static spinlock_t lock; -+ -+static enum qman_cb_dqrr_result qm_tx_conf_dqrr_cb(struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry -+ *dq) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_FmTestFq *) fq)->h_Arg; -+ unsigned long flags; -+ -+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -+{ -+ /* extract the HC frame address */ -+ uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *)&dq->fd)); -+ int hcf_l = ((struct qm_fd *)&dq->fd)->length20; -+ int i; -+ -+ /* 32b byteswap of all data in the HC Frame */ -+ for(i = 0; i < hcf_l / 4; ++i) -+ hcf_va[i] = -+ ___constant_swab32(hcf_va[i]); -+} -+#endif -+ FM_PCD_HcTxConf(p_LnxWrpFmDev->h_PcdDev, (t_DpaaFD *)&dq->fd); -+ spin_lock_irqsave(&lock, flags); -+ hcFrmRcv--; -+ spin_unlock_irqrestore(&lock, flags); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+static enum qman_cb_dqrr_result qm_tx_dqrr_cb(struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry *dq) -+{ -+ WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__, -+ __func__); -+ return qman_cb_dqrr_consume; -+} -+ -+static void qm_err_cb(struct qman_portal *portal, -+ struct qman_fq *fq, const struct qm_mr_entry *msg) -+{ -+ WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__, -+ __func__); -+} -+ -+static struct qman_fq *FqAlloc(t_LnxWrpFmDev * p_LnxWrpFmDev, -+ uint32_t fqid, -+ uint32_t flags, uint16_t channel, uint8_t wq) -+{ -+ int _errno; -+ struct qman_fq *fq = NULL; -+ t_FmTestFq *p_FmtFq; -+ struct qm_mcc_initfq initfq; -+ -+ p_FmtFq = (t_FmTestFq *) XX_Malloc(sizeof(t_FmTestFq)); -+ if (!p_FmtFq) { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!")); -+ return NULL; -+ } -+ -+ p_FmtFq->fq_base.cb.dqrr = ((flags & QMAN_FQ_FLAG_NO_ENQUEUE) -+ ? qm_tx_conf_dqrr_cb -+ : qm_tx_dqrr_cb); -+ p_FmtFq->fq_base.cb.ern = qm_err_cb; -+ /* p_FmtFq->fq_base.cb.fqs = qm_err_cb; */ -+ /* qm_err_cb wrongly called when the FQ is parked */ -+ p_FmtFq->fq_base.cb.fqs = NULL; -+ p_FmtFq->h_Arg = (t_Handle) p_LnxWrpFmDev; -+ if (fqid == 0) { -+ flags |= QMAN_FQ_FLAG_DYNAMIC_FQID; -+ flags &= ~QMAN_FQ_FLAG_NO_MODIFY; -+ } else { -+ flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID; -+ } -+ -+ if (qman_create_fq(fqid, flags, &p_FmtFq->fq_base)) { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj - qman_new_fq!!!")); -+ XX_Free(p_FmtFq); -+ return NULL; -+ } -+ fq = &p_FmtFq->fq_base; -+ -+ if (!(flags & QMAN_FQ_FLAG_NO_MODIFY)) { -+ initfq.we_mask = QM_INITFQ_WE_DESTWQ; -+ initfq.fqd.dest.channel = channel; -+ initfq.fqd.dest.wq = wq; -+ -+ _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq); -+ if (unlikely(_errno < 0)) { -+ REPORT_ERROR(MAJOR, E_NO_MEMORY, -+ ("FQ obj - qman_init_fq!!!")); -+ qman_destroy_fq(fq, 0); -+ XX_Free(p_FmtFq); -+ return NULL; -+ } -+ } -+ -+ DBG(TRACE, -+ ("fqid %d, flags 0x%08x, channel %d, wq %d", qman_fq_fqid(fq), -+ flags, channel, wq)); -+ -+ return fq; -+} -+ -+static void FqFree(struct qman_fq *fq) -+{ -+ int _errno; -+ -+ _errno = qman_retire_fq(fq, NULL); -+ if (unlikely(_errno < 0)) -+ printk(KERN_WARNING "qman_retire_fq(%u) = %d\n", qman_fq_fqid(fq), _errno); -+ -+ _errno = qman_oos_fq(fq); -+ if (unlikely(_errno < 0)) -+ printk(KERN_WARNING "qman_oos_fq(%u) = %d\n", qman_fq_fqid(fq), _errno); -+ -+ qman_destroy_fq(fq, 0); -+ XX_Free((t_FmTestFq *) fq); -+} -+ -+static t_Error QmEnqueueCB(t_Handle h_Arg, void *p_Fd) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_Arg; -+ int _errno, timeout = 1000000; -+ unsigned long flags; -+ -+ ASSERT_COND(p_LnxWrpFmDev); -+ -+ spin_lock_irqsave(&lock, flags); -+ hcFrmRcv++; -+ spin_unlock_irqrestore(&lock, flags); -+ -+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -+{ -+ /* extract the HC frame address */ -+ uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *) p_Fd)); -+ int hcf_l = ((struct qm_fd *)p_Fd)->length20; -+ int i; -+ -+ /* 32b byteswap of all data in the HC Frame */ -+ for(i = 0; i < hcf_l / 4; ++i) -+ hcf_va[i] = -+ ___constant_swab32(hcf_va[i]); -+} -+#endif -+ -+ _errno = qman_enqueue(p_LnxWrpFmDev->hc_tx_fq, (struct qm_fd *) p_Fd, -+ 0); -+ if (_errno) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, -+ ("qman_enqueue() failed")); -+ -+ while (hcFrmRcv && --timeout) { -+ udelay(1); -+ cpu_relax(); -+ } -+ if (timeout == 0) { -+ dump_stack(); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, -+ ("timeout waiting for Tx confirmation")); -+ return E_WRITE_FAILED; -+ } -+ -+ return E_OK; -+} -+ -+static t_LnxWrpFmPortDev *ReadFmPortDevTreeNode(struct platform_device -+ *of_dev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+ struct device_node *fm_node, *port_node; -+ struct resource res; -+ const uint32_t *uint32_prop; -+ int _errno = 0, lenp; -+ uint32_t tmp_prop; -+ -+#ifdef CONFIG_FMAN_P1023 -+ static unsigned char have_oh_port/* = 0 */; -+#endif -+ -+ port_node = of_node_get(of_dev->dev.of_node); -+ -+ /* Get the FM node */ -+ fm_node = of_get_parent(port_node); -+ if (unlikely(fm_node == NULL)) { -+ REPORT_ERROR(MAJOR, E_NO_DEVICE, -+ ("of_get_parent() = %d", _errno)); -+ return NULL; -+ } -+ -+ p_LnxWrpFmDev = -+ dev_get_drvdata(&of_find_device_by_node(fm_node)->dev); -+ of_node_put(fm_node); -+ -+ /* if fm_probe() failed, no point in going further with port probing */ -+ if (p_LnxWrpFmDev == NULL) -+ return NULL; -+ -+ uint32_prop = -+ (uint32_t *) of_get_property(port_node, "cell-index", &lenp); -+ if (unlikely(uint32_prop == NULL)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("of_get_property(%s, cell-index) failed", -+ port_node->full_name)); -+ return NULL; -+ } -+ tmp_prop = be32_to_cpu(*uint32_prop); -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ if (of_device_is_compatible(port_node, "fsl,fman-port-oh")) { -+ if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("of_get_property(%s, cell-index) failed", -+ port_node->full_name)); -+ return NULL; -+ } -+ -+#ifdef CONFIG_FMAN_P1023 -+ /* Beware, this can be done when there is only -+ one FMan to be initialized */ -+ if (!have_oh_port) { -+ have_oh_port = 1; /* first OP/HC port -+ is used for host command */ -+#else -+ /* Here it is hardcoded the use of the OH port 1 -+ (with cell-index 0) */ -+ if (tmp_prop == 0) { -+#endif -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort; -+ p_LnxWrpFmPortDev->id = 0; -+ /* -+ p_LnxWrpFmPortDev->id = *uint32_prop-1; -+ p_LnxWrpFmPortDev->id = *uint32_prop; -+ */ -+ p_LnxWrpFmPortDev->settings.param.portType = -+ e_FM_PORT_TYPE_OH_HOST_COMMAND; -+ } else { -+ p_LnxWrpFmPortDev = -+ &p_LnxWrpFmDev->opPorts[tmp_prop - 1]; -+ p_LnxWrpFmPortDev->id = tmp_prop- 1; -+ p_LnxWrpFmPortDev->settings.param.portType = -+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING; -+ } -+ p_LnxWrpFmPortDev->settings.param.portId = tmp_prop; -+ -+ uint32_prop = -+ (uint32_t *) of_get_property(port_node, -+ "fsl,qman-channel-id", -+ &lenp); -+ if (uint32_prop == NULL) { -+ /* -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("missing fsl,qman-channel-id")); -+ */ -+ XX_Print("FM warning: missing fsl,qman-channel-id" -+ " for OH port.\n"); -+ return NULL; -+ } -+ tmp_prop = be32_to_cpu(*uint32_prop); -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ p_LnxWrpFmPortDev->txCh = tmp_prop; -+ -+ p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams. -+ qmChannel = p_LnxWrpFmPortDev->txCh; -+ } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-tx")) { -+ tmp_prop -= 0x28; -+ if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_TX_PORTS)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("of_get_property(%s, cell-index) failed", -+ port_node->full_name)); -+ return NULL; -+ } -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop]; -+ -+ p_LnxWrpFmPortDev->id = tmp_prop; -+ p_LnxWrpFmPortDev->settings.param.portId = -+ p_LnxWrpFmPortDev->id; -+ p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_TX; -+ -+ uint32_prop = (uint32_t *) of_get_property(port_node, -+ "fsl,qman-channel-id", &lenp); -+ if (uint32_prop == NULL) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("missing fsl,qman-channel-id")); -+ return NULL; -+ } -+ tmp_prop = be32_to_cpu(*uint32_prop); -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ p_LnxWrpFmPortDev->txCh = tmp_prop; -+ p_LnxWrpFmPortDev-> -+ settings.param.specificParams.nonRxParams.qmChannel = -+ p_LnxWrpFmPortDev->txCh; -+ } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) { -+ tmp_prop -= 0x30; -+ if (unlikely(tmp_prop>= FM_MAX_NUM_OF_10G_TX_PORTS)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("of_get_property(%s, cell-index) failed", -+ port_node->full_name)); -+ return NULL; -+ } -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop + -+ FM_MAX_NUM_OF_1G_TX_PORTS]; -+#ifndef CONFIG_FMAN_ARM -+ if (IS_T1023_T1024) -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[*uint32_prop]; -+#endif -+ -+ p_LnxWrpFmPortDev->id = tmp_prop; -+ p_LnxWrpFmPortDev->settings.param.portId = -+ p_LnxWrpFmPortDev->id; -+ p_LnxWrpFmPortDev->settings.param.portType = -+ e_FM_PORT_TYPE_TX_10G; -+ uint32_prop = (uint32_t *) of_get_property(port_node, -+ "fsl,qman-channel-id", &lenp); -+ if (uint32_prop == NULL) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("missing fsl,qman-channel-id")); -+ return NULL; -+ } -+ tmp_prop = be32_to_cpu(*uint32_prop); -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ p_LnxWrpFmPortDev->txCh = tmp_prop; -+ p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams. -+ qmChannel = p_LnxWrpFmPortDev->txCh; -+ } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-rx")) { -+ tmp_prop -= 0x08; -+ if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_RX_PORTS)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("of_get_property(%s, cell-index) failed", -+ port_node->full_name)); -+ return NULL; -+ } -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop]; -+ -+ p_LnxWrpFmPortDev->id = tmp_prop; -+ p_LnxWrpFmPortDev->settings.param.portId = -+ p_LnxWrpFmPortDev->id; -+ p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_RX; -+ if (p_LnxWrpFmDev->pcdActive) -+ p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd; -+ } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-rx")) { -+ tmp_prop -= 0x10; -+ if (unlikely(tmp_prop >= FM_MAX_NUM_OF_10G_RX_PORTS)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("of_get_property(%s, cell-index) failed", -+ port_node->full_name)); -+ return NULL; -+ } -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop + -+ FM_MAX_NUM_OF_1G_RX_PORTS]; -+ -+#ifndef CONFIG_FMAN_ARM -+ if (IS_T1023_T1024) -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[*uint32_prop]; -+#endif -+ -+ p_LnxWrpFmPortDev->id = tmp_prop; -+ p_LnxWrpFmPortDev->settings.param.portId = -+ p_LnxWrpFmPortDev->id; -+ p_LnxWrpFmPortDev->settings.param.portType = -+ e_FM_PORT_TYPE_RX_10G; -+ if (p_LnxWrpFmDev->pcdActive) -+ p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd; -+ } else { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type")); -+ return NULL; -+ } -+ -+ _errno = of_address_to_resource(port_node, 0, &res); -+ if (unlikely(_errno < 0)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("of_address_to_resource() = %d", _errno)); -+ return NULL; -+ } -+ -+ p_LnxWrpFmPortDev->dev = &of_dev->dev; -+ p_LnxWrpFmPortDev->baseAddr = 0; -+ p_LnxWrpFmPortDev->phys_baseAddr = res.start; -+ p_LnxWrpFmPortDev->memSize = res.end + 1 - res.start; -+ p_LnxWrpFmPortDev->settings.param.h_Fm = p_LnxWrpFmDev->h_Dev; -+ p_LnxWrpFmPortDev->h_LnxWrpFmDev = (t_Handle) p_LnxWrpFmDev; -+ -+ of_node_put(port_node); -+ -+ p_LnxWrpFmPortDev->active = TRUE; -+ -+#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES) -+ /* for performance mode no OH port available. */ -+ if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ p_LnxWrpFmPortDev->active = FALSE; -+#endif -+ -+ return p_LnxWrpFmPortDev; -+} -+ -+struct device_node * GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node, -+ e_FmPortType portType, -+ uint8_t portId) -+{ -+ struct device_node *port_node; -+ const uint32_t *uint32_prop; -+ int lenp; -+ char *portTypeString; -+ uint32_t tmp_prop; -+ -+ switch(portType) { -+ case e_FM_PORT_TYPE_OH_OFFLINE_PARSING: -+ portTypeString = "fsl,fman-port-op-extended-args"; -+ break; -+ case e_FM_PORT_TYPE_TX: -+ portTypeString = "fsl,fman-port-1g-tx-extended-args"; -+ break; -+ case e_FM_PORT_TYPE_TX_10G: -+ portTypeString = "fsl,fman-port-10g-tx-extended-args"; -+ break; -+ case e_FM_PORT_TYPE_RX: -+ portTypeString = "fsl,fman-port-1g-rx-extended-args"; -+ break; -+ case e_FM_PORT_TYPE_RX_10G: -+ portTypeString = "fsl,fman-port-10g-rx-extended-args"; -+ break; -+ default: -+ return NULL; -+ } -+ -+ for_each_child_of_node(fm_node, port_node) { -+ uint32_prop = (uint32_t *)of_get_property(port_node, "cell-index", &lenp); -+ if (unlikely(uint32_prop == NULL)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, -+ ("of_get_property(%s, cell-index) failed", -+ port_node->full_name)); -+ return NULL; -+ } -+ tmp_prop = be32_to_cpu(*uint32_prop); -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ return NULL; -+ if ((portId == tmp_prop) && -+ (of_device_is_compatible(port_node, portTypeString))) { -+ return port_node; -+ } -+ } -+ -+ return NULL; -+} -+ -+static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev) -+{ -+ struct device_node *fm_node, *port_node; -+ t_Error err; -+ t_FmPortRsrc portRsrc; -+ const uint32_t *uint32_prop; -+ /*const char *str_prop;*/ -+ int lenp; -+#ifdef CONFIG_FMAN_PFC -+ uint8_t i, id, num_pools; -+ t_FmBufPoolDepletion poolDepletion; -+ -+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX || -+ p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) { -+ memset(&poolDepletion, 0, sizeof(t_FmBufPoolDepletion)); -+ poolDepletion.singlePoolModeEnable = true; -+ num_pools = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams. -+ extBufPools.numOfPoolsUsed; -+ for (i = 0; i < num_pools; i++) { -+ id = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams. -+ extBufPools.extBufPool[i].id; -+ poolDepletion.poolsToConsiderForSingleMode[id] = true; -+ } -+ -+ for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) -+ poolDepletion.pfcPrioritiesEn[i] = true; -+ -+ err = FM_PORT_ConfigPoolDepletion(p_LnxWrpFmPortDev->h_Dev, -+ &poolDepletion); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, ("FM_PORT_ConfigPoolDepletion() failed")); -+ } -+#endif -+ -+ fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id); -+ if (!fm_node) /* no advance parameters for FMan */ -+ return E_OK; -+ -+ port_node = GetFmPortAdvArgsDevTreeNode(fm_node, -+ p_LnxWrpFmPortDev->settings.param.portType, -+ p_LnxWrpFmPortDev->settings.param.portId); -+ if (!port_node) /* no advance parameters for FMan-Port */ -+ return E_OK; -+ -+ uint32_prop = (uint32_t *)of_get_property(port_node, "num-tnums", &lenp); -+ if (uint32_prop) { -+ if (WARN_ON(lenp != sizeof(uint32_t)*2)) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ -+ portRsrc.num = be32_to_cpu(uint32_prop[0]); -+ portRsrc.extra = be32_to_cpu(uint32_prop[1]); -+ -+ if ((err = FM_PORT_ConfigNumOfTasks(p_LnxWrpFmPortDev->h_Dev, -+ &portRsrc)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ uint32_prop = (uint32_t *)of_get_property(port_node, "num-dmas", &lenp); -+ if (uint32_prop) { -+ if (WARN_ON(lenp != sizeof(uint32_t)*2)) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ -+ portRsrc.num = be32_to_cpu(uint32_prop[0]); -+ portRsrc.extra = be32_to_cpu(uint32_prop[1]); -+ -+ if ((err = FM_PORT_ConfigNumOfOpenDmas(p_LnxWrpFmPortDev->h_Dev, -+ &portRsrc)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ uint32_prop = (uint32_t *)of_get_property(port_node, "fifo-size", &lenp); -+ if (uint32_prop) { -+ if (WARN_ON(lenp != sizeof(uint32_t)*2)) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ -+ portRsrc.num = be32_to_cpu(uint32_prop[0]); -+ portRsrc.extra = be32_to_cpu(uint32_prop[1]); -+ -+ if ((err = FM_PORT_ConfigSizeOfFifo(p_LnxWrpFmPortDev->h_Dev, -+ &portRsrc)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ uint32_prop = (uint32_t *)of_get_property(port_node, "errors-to-discard", &lenp); -+ if (uint32_prop) { -+ if (WARN_ON(lenp != sizeof(uint32_t))) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ if ((err = FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, -+ be32_to_cpu(uint32_prop[0]))) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes", -+ &lenp); -+ if (uint32_prop) { -+ -+ if (WARN_ON(lenp != sizeof(uint32_t)*8)) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType != -+ e_FM_PORT_TYPE_RX) && -+ (p_LnxWrpFmPortDev->settings.param.portType != -+ e_FM_PORT_TYPE_RX_10G)) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, -+ ("Auto Response is an Rx port atribute.")); -+ -+ memset(&p_LnxWrpFmPortDev->dsar_table_sizes, 0, sizeof(struct auto_res_tables_sizes)); -+ -+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_arp_entries = -+ (uint16_t)be32_to_cpu(uint32_prop[0]); -+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv4_entries = -+ (uint16_t)be32_to_cpu(uint32_prop[1]); -+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ndp_entries = -+ (uint16_t)be32_to_cpu(uint32_prop[2]); -+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv6_entries = -+ (uint16_t)be32_to_cpu(uint32_prop[3]); -+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv4_entries = -+ (uint16_t)be32_to_cpu(uint32_prop[4]); -+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv6_entries = -+ (uint16_t)be32_to_cpu(uint32_prop[5]); -+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_oid_entries = -+ (uint16_t)be32_to_cpu(uint32_prop[6]); -+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_char = -+ (uint16_t)be32_to_cpu(uint32_prop[7]); -+ -+ uint32_prop = (uint32_t *)of_get_property(port_node, -+ "ar-filters-sizes", &lenp); -+ if (uint32_prop) { -+ if (WARN_ON(lenp != sizeof(uint32_t)*3)) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ -+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering = -+ (uint16_t)be32_to_cpu(uint32_prop[0]); -+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering = -+ (uint16_t)be32_to_cpu(uint32_prop[1]); -+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering = -+ (uint16_t)be32_to_cpu(uint32_prop[2]); -+ } -+ -+ if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev, -+ (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+ -+ of_node_put(port_node); -+ of_node_put(fm_node); -+ -+ return E_OK; -+} -+ -+static t_Error CheckNSetFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev) -+{ -+ struct device_node *fm_node, *port_node; -+ t_Error err; -+ const uint32_t *uint32_prop; -+ /*const char *str_prop;*/ -+ int lenp; -+ -+ fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id); -+ if (!fm_node) /* no advance parameters for FMan */ -+ return E_OK; -+ -+ port_node = GetFmPortAdvArgsDevTreeNode(fm_node, -+ p_LnxWrpFmPortDev->settings.param.portType, -+ p_LnxWrpFmPortDev->settings.param.portId); -+ if (!port_node) /* no advance parameters for FMan-Port */ -+ return E_OK; -+ -+#if (DPAA_VERSION >= 11) -+ uint32_prop = (uint32_t *)of_get_property(port_node, "vsp-window", &lenp); -+ if (uint32_prop) { -+ t_FmPortVSPAllocParams portVSPAllocParams; -+ t_FmVspParams fmVspParams; -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ uint8_t portId; -+ -+ p_LnxWrpFmDev = ((t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev); -+ -+ if (WARN_ON(lenp != sizeof(uint32_t)*2)) -+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -+ -+ if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) || -+ (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX_10G) || -+ ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) && -+ p_LnxWrpFmPortDev->settings.frag_enabled)) -+ return E_OK; -+ -+ memset(&portVSPAllocParams, 0, sizeof(portVSPAllocParams)); -+ memset(&fmVspParams, 0, sizeof(fmVspParams)); -+ -+ portVSPAllocParams.numOfProfiles = (uint8_t)be32_to_cpu(uint32_prop[0]); -+ portVSPAllocParams.dfltRelativeId = (uint8_t)be32_to_cpu(uint32_prop[1]); -+ fmVspParams.h_Fm = p_LnxWrpFmDev->h_Dev; -+ -+ fmVspParams.portParams.portType = p_LnxWrpFmPortDev->settings.param.portType; -+ fmVspParams.portParams.portId = p_LnxWrpFmPortDev->settings.param.portId; -+ fmVspParams.relativeProfileId = portVSPAllocParams.dfltRelativeId; -+ -+ if (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING) -+ { -+ portId = fmVspParams.portParams.portId; -+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G){ -+#ifndef CONFIG_FMAN_ARM -+ if (!(IS_T1023_T1024)) -+#endif -+ portId += FM_MAX_NUM_OF_1G_RX_PORTS; -+ } -+ portVSPAllocParams.h_FmTxPort = -+ p_LnxWrpFmDev->txPorts[portId].h_Dev; -+ fmVspParams.liodnOffset = -+ p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset; -+ memcpy(&fmVspParams.extBufPools, -+ &p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools, -+ sizeof(t_FmExtPools)); -+ } -+ else -+ { -+ memcpy(&fmVspParams.extBufPools, -+ &p_LnxWrpFmPortDev->opExtPools, -+ sizeof(t_FmExtPools)); -+ } -+ -+ if ((err = FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev, -+ &portVSPAllocParams)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ /* We're initializing only the default VSP that are being used by the Linux-Ethernet-driver */ -+ if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) && -+ !p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed) -+ return E_OK; -+ -+ p_LnxWrpFmPortDev->h_DfltVsp = FM_VSP_Config(&fmVspParams); -+ if (!p_LnxWrpFmPortDev->h_DfltVsp) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("default-VSP for port!")); -+ -+ if ((err = FM_VSP_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_DfltVsp, -+ &p_LnxWrpFmPortDev->buffPrefixContent)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ -+ if ((err = FM_VSP_Init(p_LnxWrpFmPortDev->h_DfltVsp)) != E_OK) -+ RETURN_ERROR(MINOR, err, NO_MSG); -+ } -+#else -+UNUSED(err); UNUSED(uint32_prop); UNUSED(lenp); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ of_node_put(port_node); -+ of_node_put(fm_node); -+ -+ return E_OK; -+} -+ -+static t_Error ConfigureFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = -+ (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ struct resource *dev_res; -+ -+ if (!p_LnxWrpFmPortDev->active) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("FM port not configured!!!")); -+ -+ dev_res = -+ __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, -+ p_LnxWrpFmPortDev->phys_baseAddr, -+ p_LnxWrpFmPortDev->memSize, -+ "fman-port-hc"); -+ if (unlikely(dev_res == NULL)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, -+ ("__devm_request_region() failed")); -+ p_LnxWrpFmPortDev->baseAddr = -+ PTR_TO_UINT(devm_ioremap -+ (p_LnxWrpFmDev->dev, -+ p_LnxWrpFmPortDev->phys_baseAddr, -+ p_LnxWrpFmPortDev->memSize)); -+ if (unlikely(p_LnxWrpFmPortDev->baseAddr == 0)) -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, -+ ("devm_ioremap() failed")); -+ -+ p_LnxWrpFmPortDev->settings.param.baseAddr = -+ p_LnxWrpFmPortDev->baseAddr; -+ -+ return E_OK; -+} -+ -+static t_Error InitFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev) -+{ -+#define MY_ADV_CONFIG_CHECK_END \ -+ RETURN_ERROR(MAJOR, E_INVALID_SELECTION,\ -+ ("Advanced configuration routine"));\ -+ if (errCode != E_OK)\ -+ RETURN_ERROR(MAJOR, errCode, NO_MSG);\ -+ } -+ -+ int i = 0; -+ -+ if (!p_LnxWrpFmPortDev->active || p_LnxWrpFmPortDev->h_Dev) -+ return E_INVALID_STATE; -+ -+ p_LnxWrpFmPortDev->h_Dev = -+ FM_PORT_Config(&p_LnxWrpFmPortDev->settings.param); -+ if (p_LnxWrpFmPortDev->h_Dev == NULL) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-port")); -+ -+#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT -+ if ((p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_TX_10G) -+ || (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_TX)) { -+ t_Error errCode = E_OK; -+ errCode = -+ FM_PORT_ConfigDeqHighPriority(p_LnxWrpFmPortDev->h_Dev, -+ TRUE); -+ if (errCode != E_OK) -+ RETURN_ERROR(MAJOR, errCode, NO_MSG); -+ errCode = -+ FM_PORT_ConfigDeqPrefetchOption(p_LnxWrpFmPortDev->h_Dev, -+ e_FM_PORT_DEQ_FULL_PREFETCH); -+ if (errCode -+ != E_OK) -+ RETURN_ERROR(MAJOR, errCode, NO_MSG); -+ } -+#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */ -+ -+#ifndef CONFIG_FMAN_ARM -+#ifdef FM_BCB_ERRATA_BMI_SW001 -+/* Configure BCB workaround on Rx ports, only for B4860 rev1 */ -+#define SVR_SECURITY_MASK 0x00080000 -+#define SVR_PERSONALITY_MASK 0x0000FF00 -+#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK) -+#define SVR_B4860_REV1_VALUE 0x86800010 -+ -+ if ((p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_RX_10G) || -+ (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_RX)) { -+ unsigned int svr; -+ -+ svr = mfspr(SPRN_SVR); -+ -+ if ((svr & ~SVR_VER_IGNORE_MASK) == SVR_B4860_REV1_VALUE) -+ FM_PORT_ConfigBCBWorkaround(p_LnxWrpFmPortDev->h_Dev); -+ } -+#endif /* FM_BCB_ERRATA_BMI_SW001 */ -+#endif /* CONFIG_FMAN_ARM */ -+/* Call the driver's advanced configuration routines, if requested: -+ Compare the function pointer of each entry to the available routines, -+ and invoke the matching routine with proper casting of arguments. */ -+ while (p_LnxWrpFmPortDev->settings.advConfig[i].p_Function -+ && (i < FM_MAX_NUM_OF_ADV_SETTINGS)) { -+ -+/* TODO: Change this MACRO */ -+ ADV_CONFIG_CHECK_START( -+ &(p_LnxWrpFmPortDev->settings.advConfig[i])) -+ -+ ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev, -+ FM_PORT_ConfigBufferPrefixContent, -+ NCSW_PARAMS(1, -+ (t_FmBufferPrefixContent *))) -+ -+ if ((p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING) && -+ (p_LnxWrpFmPortDev->settings.frag_enabled == TRUE)) { -+ -+ ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev, -+ FM_PORT_ConfigExtBufPools, -+ NCSW_PARAMS(1, (t_FmExtPools *))) -+ -+ /* this define contains an else */ -+ MY_ADV_CONFIG_CHECK_END -+ } -+ -+ /* Advance to next advanced configuration entry */ -+ i++; -+ } -+ -+ -+ if ((p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX) && -+ (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX_10G)) { -+ if (FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, (FM_PORT_FRM_ERR_IPRE | -+ FM_PORT_FRM_ERR_IPR_NCSP | -+ FM_PORT_FRM_ERR_CLS_DISCARD)) !=E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ } -+ -+ if (CheckNConfigFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ if (FM_PORT_Init(p_LnxWrpFmPortDev->h_Dev) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+ if (CheckNSetFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+ -+/* FMan Fifo sizes behind the scene": -+ * Using the following formulae (*), under a set of simplifying assumptions (.): -+ * . all ports are configured in Normal Mode (rather than Independent Mode) -+ * . the DPAA Eth driver allocates buffers of size: -+ * . MAXFRM + NET_IP_ALIGN + DPA_PRIV_DATA_SIZE + DPA_PARSE_RESULTS_SIZE -+ * + DPA_HASH_RESULTS_SIZE, i.e.: -+ * MAXFRM + 2 + 16 + sizeof(t_FmPrsResult) + 16, i.e.: -+ * MAXFRM + 66 -+ * . excessive buffer pools not accounted for -+ * -+ * * for Rx ports on P4080: -+ * . IFSZ = ceil(max(FMBM_EBMPI[PBS]) / 256) * 256 + 7 * 256 -+ * . no internal frame offset (FMBM_RIM[FOF] == 0) - otherwise, -+ * add up to 256 to the above -+ * -+ * * for Rx ports on P1023: -+ * . IFSZ = ceil(second_largest(FMBM_EBMPI[PBS] / 256)) * 256 + 7 * 256, -+ * if at least 2 bpools are configured -+ * . IFSZ = 8 * 256, if only a single bpool is configured -+ * -+ * * for Tx ports: -+ * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256 -+ * + FMBM_TFP[DPDE] * 256, i.e.: -+ * IFSZ = ceil(MAXFRM / 256) * 256 + 3 x 256 + FMBM_TFP[DPDE] * 256 -+ * -+ * * for OH ports on P4080: -+ * . IFSZ = ceil(frame_size / 256) * 256 + 1 * 256 + FMBM_PP[MXT] * 256 -+ * * for OH ports on P1023: -+ * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256 + FMBM_TFP[DPDE] * 256 -+ * * for both P4080 and P1023: -+ * . (conservative decisions, assuming that BMI must bring the entire -+ * frame, not only the frame header) -+ * . no internal frame offset (FMBM_OIM[FOF] == 0) - otherwise, -+ * add up to 256 to the above -+ * -+ * . for P4080/P5020/P3041/P2040, DPDE is: -+ * > 0 or 1, for 1Gb ports, HW default: 0 -+ * > 2..7 (recommended: 3..7) for 10Gb ports, HW default: 3 -+ * . for P1023, DPDE should be 1 -+ * -+ * . for P1023, MXT is in range (0..31) -+ * . for P4080, MXT is in range (0..63) -+ * -+ */ -+#if 0 -+ if ((p_LnxWrpFmPortDev->defPcd != e_NO_PCD) && -+ (InitFmPort3TupleDefPcd(p_LnxWrpFmPortDev) != E_OK)) -+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG); -+#endif -+ return E_OK; -+} -+ -+void fm_set_rx_port_params(struct fm_port *port, -+ struct fm_port_params *params) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port; -+ int i; -+ -+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.errFqid = -+ params->errq; -+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.dfltFqid = -+ params->defq; -+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools. -+ numOfPoolsUsed = params->num_pools; -+ for (i = 0; i < params->num_pools; i++) { -+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams. -+ extBufPools.extBufPool[i].id = -+ params->pool_param[i].id; -+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams. -+ extBufPools.extBufPool[i].size = -+ params->pool_param[i].size; -+ } -+ -+ p_LnxWrpFmPortDev->buffPrefixContent.privDataSize = -+ params->priv_data_size; -+ p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult = -+ params->parse_results; -+ p_LnxWrpFmPortDev->buffPrefixContent.passHashResult = -+ params->hash_results; -+ p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp = -+ params->time_stamp; -+ p_LnxWrpFmPortDev->buffPrefixContent.dataAlign = -+ params->data_align; -+ p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace = -+ params->manip_extra_space; -+ -+ ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig, -+ FM_MAX_NUM_OF_ADV_SETTINGS) -+ -+ ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent, -+ ARGS(1, -+ (&p_LnxWrpFmPortDev-> -+ buffPrefixContent))); -+ -+ ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev); -+} -+EXPORT_SYMBOL(fm_set_rx_port_params); -+ -+/* this function is called from oh_probe as well, thus it contains oh port -+ * specific parameters (make sure everything is checked) */ -+void fm_set_tx_port_params(struct fm_port *port, -+ struct fm_port_params *params) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port; -+ -+ p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.errFqid = -+ params->errq; -+ p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams. -+ dfltFqid = params->defq; -+ -+ p_LnxWrpFmPortDev->buffPrefixContent.privDataSize = -+ params->priv_data_size; -+ p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult = -+ params->parse_results; -+ p_LnxWrpFmPortDev->buffPrefixContent.passHashResult = -+ params->hash_results; -+ p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp = -+ params->time_stamp; -+ p_LnxWrpFmPortDev->settings.frag_enabled = -+ params->frag_enable; -+ p_LnxWrpFmPortDev->buffPrefixContent.dataAlign = -+ params->data_align; -+ p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace = -+ params->manip_extra_space; -+ -+ ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig, -+ FM_MAX_NUM_OF_ADV_SETTINGS) -+ -+ ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent, -+ ARGS(1, -+ (&p_LnxWrpFmPortDev-> -+ buffPrefixContent))); -+ -+ /* oh port specific parameter (for fragmentation only) */ -+ if ((p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING) && -+ params->num_pools) { -+ int i; -+ -+ p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed = params->num_pools; -+ for (i = 0; i < params->num_pools; i++) { -+ p_LnxWrpFmPortDev->opExtPools.extBufPool[i].id = params->pool_param[i].id; -+ p_LnxWrpFmPortDev->opExtPools.extBufPool[i].size = params->pool_param[i].size; -+ } -+ -+ if (p_LnxWrpFmPortDev->settings.frag_enabled) -+ ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigExtBufPools, -+ ARGS(1, (&p_LnxWrpFmPortDev->opExtPools))); -+ } -+ -+ ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev); -+} -+EXPORT_SYMBOL(fm_set_tx_port_params); -+ -+void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev, -+ t_Handle h_fm_mac, -+ int mac_id) -+{ -+ t_LnxWrpFmDev *p_lnx_wrp_fm_dev = (t_LnxWrpFmDev *)h_lnx_wrp_fm_dev; -+ -+ p_lnx_wrp_fm_dev->macs[mac_id].h_Dev = h_fm_mac; -+ p_lnx_wrp_fm_dev->macs[mac_id].h_LnxWrpFmDev = h_lnx_wrp_fm_dev; -+} -+EXPORT_SYMBOL(fm_mac_set_handle); -+ -+static void LnxwrpFmPcdDevExceptionsCb(t_Handle h_App, -+ e_FmPcdExceptions exception) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App; -+ -+ ASSERT_COND(p_LnxWrpFmDev); -+ -+ DBG(INFO, ("got fm-pcd exception %d", exception)); -+ -+ /* do nothing */ -+ UNUSED(exception); -+} -+ -+static void LnxwrpFmPcdDevIndexedExceptionsCb(t_Handle h_App, -+ e_FmPcdExceptions exception, -+ uint16_t index) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App; -+ -+ ASSERT_COND(p_LnxWrpFmDev); -+ -+ DBG(INFO, -+ ("got fm-pcd-indexed exception %d, indx %d", exception, index)); -+ -+ /* do nothing */ -+ UNUSED(exception); -+ UNUSED(index); -+} -+ -+static t_Error InitFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev) -+{ -+ spin_lock_init(&lock); -+ -+ if (p_LnxWrpFmDev->pcdActive) { -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort; -+ t_FmPcdParams fmPcdParams; -+ t_Error err; -+ -+ memset(&fmPcdParams, 0, sizeof(fmPcdParams)); -+ fmPcdParams.h_Fm = p_LnxWrpFmDev->h_Dev; -+ fmPcdParams.prsSupport = p_LnxWrpFmDev->prsActive; -+ fmPcdParams.kgSupport = p_LnxWrpFmDev->kgActive; -+ fmPcdParams.plcrSupport = p_LnxWrpFmDev->plcrActive; -+ fmPcdParams.ccSupport = p_LnxWrpFmDev->ccActive; -+ fmPcdParams.numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES; -+ -+#ifndef CONFIG_GUEST_PARTITION -+ fmPcdParams.f_Exception = LnxwrpFmPcdDevExceptionsCb; -+ if (fmPcdParams.kgSupport) -+ fmPcdParams.f_ExceptionId = -+ LnxwrpFmPcdDevIndexedExceptionsCb; -+ fmPcdParams.h_App = p_LnxWrpFmDev; -+#endif /* !CONFIG_GUEST_PARTITION */ -+ -+#ifdef CONFIG_MULTI_PARTITION_SUPPORT -+ fmPcdParams.numOfSchemes = 0; -+ fmPcdParams.numOfClsPlanEntries = 0; -+ fmPcdParams.partitionId = 0; -+#endif /* CONFIG_MULTI_PARTITION_SUPPORT */ -+ fmPcdParams.useHostCommand = TRUE; -+ -+ p_LnxWrpFmDev->hc_tx_fq = -+ FqAlloc(p_LnxWrpFmDev, -+ 0, -+ QMAN_FQ_FLAG_TO_DCPORTAL, -+ p_LnxWrpFmPortDev->txCh, 0); -+ if (!p_LnxWrpFmDev->hc_tx_fq) -+ RETURN_ERROR(MAJOR, E_NULL_POINTER, -+ ("Frame queue allocation failed...")); -+ -+ p_LnxWrpFmDev->hc_tx_conf_fq = -+ FqAlloc(p_LnxWrpFmDev, -+ 0, -+ QMAN_FQ_FLAG_NO_ENQUEUE, -+ p_LnxWrpFmDev->hcCh, 1); -+ if (!p_LnxWrpFmDev->hc_tx_conf_fq) -+ RETURN_ERROR(MAJOR, E_NULL_POINTER, -+ ("Frame queue allocation failed...")); -+ -+ p_LnxWrpFmDev->hc_tx_err_fq = -+ FqAlloc(p_LnxWrpFmDev, -+ 0, -+ QMAN_FQ_FLAG_NO_ENQUEUE, -+ p_LnxWrpFmDev->hcCh, 2); -+ if (!p_LnxWrpFmDev->hc_tx_err_fq) -+ RETURN_ERROR(MAJOR, E_NULL_POINTER, -+ ("Frame queue allocation failed...")); -+ -+ fmPcdParams.hc.portBaseAddr = p_LnxWrpFmPortDev->baseAddr; -+ fmPcdParams.hc.portId = -+ p_LnxWrpFmPortDev->settings.param.portId; -+ fmPcdParams.hc.liodnBase = -+ p_LnxWrpFmPortDev->settings.param.liodnBase; -+ fmPcdParams.hc.errFqid = -+ qman_fq_fqid(p_LnxWrpFmDev->hc_tx_err_fq); -+ fmPcdParams.hc.confFqid = -+ qman_fq_fqid(p_LnxWrpFmDev->hc_tx_conf_fq); -+ fmPcdParams.hc.qmChannel = p_LnxWrpFmPortDev->txCh; -+ fmPcdParams.hc.f_QmEnqueue = QmEnqueueCB; -+ fmPcdParams.hc.h_QmArg = (t_Handle) p_LnxWrpFmDev; -+ -+ p_LnxWrpFmDev->h_PcdDev = FM_PCD_Config(&fmPcdParams); -+ if (!p_LnxWrpFmDev->h_PcdDev) -+ RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM PCD!")); -+ -+ err = -+ FM_PCD_ConfigPlcrNumOfSharedProfiles(p_LnxWrpFmDev->h_PcdDev, -+ LNXWRP_FM_NUM_OF_SHARED_PROFILES); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ err = FM_PCD_Init(p_LnxWrpFmDev->h_PcdDev); -+ if (err != E_OK) -+ RETURN_ERROR(MAJOR, err, NO_MSG); -+ -+ if (p_LnxWrpFmDev->err_irq == 0) { -+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, -+ e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, -+ FALSE); -+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, -+ e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, -+ FALSE); -+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, -+ e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, -+ FALSE); -+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, -+ e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, -+ FALSE); -+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, -+ e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, -+ FALSE); -+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, -+ e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, -+ FALSE); -+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, -+ e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, -+ FALSE); -+ FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, -+ e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC, -+ FALSE); -+ } -+ } -+ -+ return E_OK; -+} -+ -+void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev) -+{ -+ -+ if (p_LnxWrpFmDev->h_PcdDev) -+ FM_PCD_Free(p_LnxWrpFmDev->h_PcdDev); -+ -+ if (p_LnxWrpFmDev->hc_tx_err_fq) -+ FqFree(p_LnxWrpFmDev->hc_tx_err_fq); -+ -+ if (p_LnxWrpFmDev->hc_tx_conf_fq) -+ FqFree(p_LnxWrpFmDev->hc_tx_conf_fq); -+ -+ if (p_LnxWrpFmDev->hc_tx_fq) -+ FqFree(p_LnxWrpFmDev->hc_tx_fq); -+} -+ -+static void FreeFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = -+ (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ -+ if (!p_LnxWrpFmPortDev->active) -+ return; -+ -+ if (p_LnxWrpFmPortDev->h_Dev) -+ FM_PORT_Free(p_LnxWrpFmPortDev->h_Dev); -+ -+ devm_iounmap(p_LnxWrpFmDev->dev, -+ UINT_TO_PTR(p_LnxWrpFmPortDev->baseAddr)); -+ __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, -+ p_LnxWrpFmPortDev->phys_baseAddr, -+ p_LnxWrpFmPortDev->memSize); -+} -+ -+static int /*__devinit*/ fm_port_probe(struct platform_device *of_dev) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ struct device *dev; -+ -+ dev = &of_dev->dev; -+ -+ p_LnxWrpFmPortDev = ReadFmPortDevTreeNode(of_dev); -+ if (p_LnxWrpFmPortDev == NULL) -+ return -EIO; -+ /* Port can be inactive, thus will not be probed: -+ - in performance mode, OH ports are disabled -+ ... -+ */ -+ if (!p_LnxWrpFmPortDev->active) -+ return 0; -+ -+ if (ConfigureFmPortDev(p_LnxWrpFmPortDev) != E_OK) -+ return -EIO; -+ -+ dev_set_drvdata(dev, p_LnxWrpFmPortDev); -+ -+ if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_OH_HOST_COMMAND) -+ InitFmPcdDev((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev); -+ -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ -+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX) { -+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d", -+ p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id); -+ p_LnxWrpFmPortDev->minor = -+ p_LnxWrpFmPortDev->id + DEV_FM_RX_PORTS_MINOR_BASE; -+ } else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_RX_10G) { -+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d", -+ p_LnxWrpFmDev->name, -+ p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS); -+ p_LnxWrpFmPortDev->minor = -+ p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS + -+ DEV_FM_RX_PORTS_MINOR_BASE; -+#ifndef CONFIG_FMAN_ARM -+ if (IS_T1023_T1024) { -+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d", -+ p_LnxWrpFmDev->name, -+ p_LnxWrpFmPortDev->id); -+ p_LnxWrpFmPortDev->minor = -+ p_LnxWrpFmPortDev->id + -+ DEV_FM_RX_PORTS_MINOR_BASE; -+ } -+#endif -+ } else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_TX) { -+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d", -+ p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id); -+ p_LnxWrpFmPortDev->minor = -+ p_LnxWrpFmPortDev->id + DEV_FM_TX_PORTS_MINOR_BASE; -+ } else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_TX_10G) { -+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d", -+ p_LnxWrpFmDev->name, -+ p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS); -+ p_LnxWrpFmPortDev->minor = -+ p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS + -+ DEV_FM_TX_PORTS_MINOR_BASE; -+#ifndef CONFIG_FMAN_ARM -+ if (IS_T1023_T1024) { -+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d", -+ p_LnxWrpFmDev->name, -+ p_LnxWrpFmPortDev->id); -+ p_LnxWrpFmPortDev->minor = -+ p_LnxWrpFmPortDev->id + -+ DEV_FM_TX_PORTS_MINOR_BASE; -+ } -+#endif -+ } else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_OH_HOST_COMMAND) { -+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d", -+ p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id); -+ p_LnxWrpFmPortDev->minor = -+ p_LnxWrpFmPortDev->id + DEV_FM_OH_PORTS_MINOR_BASE; -+ } else if (p_LnxWrpFmPortDev->settings.param.portType == -+ e_FM_PORT_TYPE_OH_OFFLINE_PARSING) { -+ Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d", -+ p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id + 1); -+ p_LnxWrpFmPortDev->minor = -+ p_LnxWrpFmPortDev->id + 1 + -+ DEV_FM_OH_PORTS_MINOR_BASE; -+ } -+ -+ device_create(p_LnxWrpFmDev->fm_class, NULL, -+ MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor), -+ NULL, p_LnxWrpFmPortDev->name); -+ -+ /* create sysfs entries for stats and regs */ -+ -+ if (fm_port_sysfs_create(dev) != 0) { -+ FreeFmPortDev(p_LnxWrpFmPortDev); -+ REPORT_ERROR(MAJOR, E_INVALID_STATE, -+ ("Unable to create sys entry - fm port!!!")); -+ return -EIO; -+ } -+ -+#ifdef FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 -+ FM_DisableRamsEcc(p_LnxWrpFmDev->h_Dev); -+#endif /* FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 */ -+ -+ DBG(TRACE, ("%s probed", p_LnxWrpFmPortDev->name)); -+ -+ return 0; -+} -+ -+static int fm_port_remove(struct platform_device *of_dev) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ struct device *dev; -+ -+ dev = &of_dev->dev; -+ p_LnxWrpFmPortDev = dev_get_drvdata(dev); -+ -+ fm_port_sysfs_destroy(dev); -+ -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ device_destroy(p_LnxWrpFmDev->fm_class, -+ MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor)); -+ -+ FreeFmPortDev(p_LnxWrpFmPortDev); -+ -+ dev_set_drvdata(dev, NULL); -+ -+ return 0; -+} -+ -+static const struct of_device_id fm_port_match[] = { -+ { -+ .compatible = "fsl,fman-port-oh"}, -+ { -+ .compatible = "fsl,fman-port-1g-rx"}, -+ { -+ .compatible = "fsl,fman-port-10g-rx"}, -+ { -+ .compatible = "fsl,fman-port-1g-tx"}, -+ { -+ .compatible = "fsl,fman-port-10g-tx"}, -+ {} -+}; -+ -+#ifndef MODULE -+MODULE_DEVICE_TABLE(of, fm_port_match); -+#endif /* !MODULE */ -+ -+static struct platform_driver fm_port_driver = { -+ -+ .driver = { -+ .name = "fsl-fman-port", -+ .of_match_table = fm_port_match, -+ .owner = THIS_MODULE, -+ }, -+ .probe = fm_port_probe, -+ .remove = fm_port_remove -+}; -+ -+ -+t_Error LNXWRP_FM_Port_Init(void) -+{ -+ /* Register to the DTB for basic FM port API */ -+ if (platform_driver_register(&fm_port_driver)) -+ return E_NO_DEVICE; -+ -+ return E_OK; -+} -+ -+void LNXWRP_FM_Port_Free(void) -+{ -+ platform_driver_unregister(&fm_port_driver); -+} -+ -+static int __init __cold fm_port_load(void) -+{ -+ if (LNXWRP_FM_Port_Init() != E_OK) { -+ printk(KERN_CRIT "Failed to init FM Ports wrapper!\n"); -+ return -ENODEV; -+ } -+ -+ printk(KERN_CRIT "Freescale FM Ports module\n"); -+ -+ return 0; -+} -+ -+static void __exit __cold fm_port_unload(void) -+{ -+ LNXWRP_FM_Port_Free(); -+} -+ -+module_init(fm_port_load); -+module_exit(fm_port_unload); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c -@@ -0,0 +1,4813 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ @File lnxwrp_ioctls_fm.c -+ @Author Shlomi Gridish -+ @Description FM Linux wrapper functions. -+*/ -+ -+/* Linux Headers ------------------- */ -+#include -+ -+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) -+#define MODVERSIONS -+#endif -+#ifdef MODVERSIONS -+#include -+#endif /* MODVERSIONS */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifndef CONFIG_FMAN_ARM -+#include -+#include -+#endif -+ -+#if defined(CONFIG_COMPAT) -+#include -+#endif -+ -+#include "part_ext.h" -+#include "fm_ioctls.h" -+#include "fm_pcd_ioctls.h" -+#include "fm_port_ioctls.h" -+#include "fm_vsp_ext.h" -+ -+#ifndef CONFIG_FMAN_ARM -+#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \ -+ SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023) -+#endif -+ -+#define __ERR_MODULE__ MODULE_FM -+ -+#if defined(CONFIG_COMPAT) -+#include "lnxwrp_ioctls_fm_compat.h" -+#endif -+ -+#include "lnxwrp_fm.h" -+ -+#define CMP_IOC_DEFINE(def) (IOC_##def != def) -+ -+/* fm_pcd_ioctls.h === fm_pcd_ext.h assertions */ -+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_PRIVATE_HDRS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_HDRS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_GENERIC_REGS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_EXTRACT_MASKS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_DEFAULT_GROUPS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_LABELS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_SW_PRS_SIZE) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if DPAA_VERSION >= 11 -+#if CMP_IOC_DEFINE(FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES) -+#error Error: please synchronize IOC_ defines! -+#endif -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_TREES) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_GROUPS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_UNITS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_KEYS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_MAX_SIZE_OF_KEY) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(FM_PCD_LAST_KEY_INDEX) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+/* net_ioctls.h === net_ext.h assertions */ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_PID) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_COMPRESSED) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPoE_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ETH_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv4_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv6_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ICMP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IGMP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_TCP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_DCCP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPHC_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv2_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_VLAN_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_NLPID_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SNAP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS) -+#warning Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ARP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_RFC2684_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_GRE_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MINENCAP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MACSEC_ALL_FIELDS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+/* fm_ioctls.h === fm_ext.h assertions */ -+#if CMP_IOC_DEFINE(FM_MAX_NUM_OF_VALID_PORTS) -+#error Error: please synchronize IOC_ defines! -+#endif -+ -+void LnxWrpPCDIOCTLTypeChecking(void) -+{ -+ /* fm_ext.h == fm_ioctls.h */ -+ ASSERT_COND(sizeof(ioc_fm_port_bandwidth_params) == sizeof(t_FmPortsBandwidthParams)); -+ ASSERT_COND(sizeof(ioc_fm_revision_info_t) == sizeof(t_FmRevisionInfo)); -+ -+ /* fm_pcd_ext.h == fm_pcd_ioctls.h */ -+ /*ioc_fm_pcd_counters_params_t : NOT USED */ -+ /*ioc_fm_pcd_exception_params_t : private */ -+#if (DPAA_VERSION >= 11) -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_params_t) == sizeof(t_FmPcdManipFragCapwapParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_params_t) == sizeof(t_FmPcdManipReassemCapwapParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t) == sizeof(t_FmPcdManipHdrInsrtByHdrParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_ip_params_t) == sizeof(t_FmPcdManipHdrInsrtIpParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_t) == sizeof(t_FmPcdManipHdrInsrt)); -+ ASSERT_COND(sizeof(ioc_fm_manip_hdr_info_t) == sizeof(t_FmManipHdrInfo)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t) == sizeof(t_FmPcdManipHdrRmvByHdrParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_capwap_params_t) == sizeof(t_FmPcdManipSpecialOffloadCapwapParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_stats_t) == sizeof(t_FmPcdManipFragCapwapStats)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_stats_t) == sizeof(t_FmPcdManipReassemCapwapStats)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams)); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ ASSERT_COND(sizeof(ioc_fm_pcd_prs_label_params_t) == sizeof(t_FmPcdPrsLabelParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_prs_sw_params_t) == sizeof(t_FmPcdPrsSwParams)); -+ /*ioc_fm_pcd_kg_dflt_value_params_t : private */ -+ ASSERT_COND(sizeof(ioc_fm_pcd_hdr_protocol_opt_u) == sizeof(u_FmPcdHdrProtocolOpt)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_fields_u) == sizeof(t_FmPcdFields)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_from_hdr_t) == sizeof(t_FmPcdFromHdr)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_from_field_t) == sizeof(t_FmPcdFromField)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_distinction_unit_t) == sizeof(t_FmPcdDistinctionUnit)); -+ -+#if defined(CONFIG_ARM64) -+ /* different alignment */ -+ ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *) + 4); -+#else -+#if !defined(CONFIG_COMPAT) -+ /* different alignment */ -+ ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *)); -+#endif -+#endif -+ ASSERT_COND(sizeof(ioc_fm_pcd_extract_entry_t) == sizeof(t_FmPcdExtractEntry)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_mask_t) == sizeof(t_FmPcdKgExtractMask)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_dflt_t) == sizeof(t_FmPcdKgExtractDflt)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t) == sizeof(t_FmPcdKgKeyExtractAndHashParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_extracted_or_params_t) == sizeof(t_FmPcdKgExtractedOrParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_counter_t) == sizeof(t_FmPcdKgSchemeCounter)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_plcr_profile_t) == sizeof(t_FmPcdKgPlcrProfile)); -+#if (DPAA_VERSION >= 11) -+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_storage_profile_t) == sizeof(t_FmPcdKgStorageProfile)); -+#endif -+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_cc_t) == sizeof(t_FmPcdKgCc)); -+#if !defined(CONFIG_COMPAT) -+ /* different alignment */ -+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_params_t) == sizeof(t_FmPcdKgSchemeParams) + sizeof(void *)); -+#endif -+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_cc_params_t) == sizeof(t_FmPcdCcNextCcParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_plcr_params_t) == sizeof(t_FmPcdCcNextPlcrParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_enqueue_params_t) == sizeof(t_FmPcdCcNextEnqueueParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_kg_params_t) == sizeof(t_FmPcdCcNextKgParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_engine_params_t) == sizeof(t_FmPcdCcNextEngineParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_key_params_t) == sizeof(t_FmPcdCcKeyParams)); -+ ASSERT_COND(sizeof(ioc_keys_params_t) == sizeof(t_KeysParams)); -+#if !defined(CONFIG_COMPAT) -+ /* different alignment */ -+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_node_params_t) == sizeof(t_FmPcdCcNodeParams) + sizeof(void *)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_hash_table_params_t) == sizeof(t_FmPcdHashTableParams) + sizeof(void *)); -+#endif -+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_grp_params_t) == sizeof(t_FmPcdCcGrpParams)); -+#if !defined(CONFIG_COMPAT) -+ /* different alignment */ -+ ASSERT_COND(sizeof(ioc_fm_pcd_cc_tree_params_t) == sizeof(t_FmPcdCcTreeParams) + sizeof(void *)); -+#endif -+ ASSERT_COND(sizeof(ioc_fm_pcd_plcr_byte_rate_mode_param_t) == sizeof(t_FmPcdPlcrByteRateModeParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t) == sizeof(t_FmPcdPlcrNonPassthroughAlgParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_plcr_next_engine_params_u) == sizeof(u_FmPcdPlcrNextEngineParams)); -+ /*ioc_fm_pcd_port_params_t : private */ -+ ASSERT_COND(sizeof(ioc_fm_pcd_plcr_profile_params_t) == sizeof(t_FmPcdPlcrProfileParams) + sizeof(void *)); -+ /*ioc_fm_pcd_cc_tree_modify_next_engine_params_t : private */ -+ -+#ifdef FM_CAPWAP_SUPPORT -+#error TODO: unsupported feature -+/* -+ ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipHdrInsrtByTemplateParams)); -+ ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapFragmentationParams)); -+ ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapReassemblyParams)); -+*/ -+#endif -+ -+ /*ioc_fm_pcd_cc_node_modify_next_engine_params_t : private */ -+ /*ioc_fm_pcd_cc_node_remove_key_params_t : private */ -+ /*ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t : private */ -+ /*ioc_fm_pcd_cc_node_modify_key_params_t : private */ -+ /*ioc_fm_manip_hdr_info_t : private */ -+ /*ioc_fm_pcd_hash_table_set_t : private */ -+ -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_params_t) == sizeof(t_FmPcdManipFragIpParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_params_t) == sizeof(t_FmPcdManipReassemIpParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_ipsec_params_t) == sizeof(t_FmPcdManipSpecialOffloadIPSecParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_params_t) == sizeof(t_FmPcdManipSpecialOffloadParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_generic_params_t) == sizeof(t_FmPcdManipHdrRmvGenericParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_generic_params_t) == sizeof(t_FmPcdManipHdrInsrtGenericParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_params_t) == sizeof(t_FmPcdManipHdrInsrtParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_params_t) == sizeof(t_FmPcdManipHdrRmvParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_params_t) == sizeof(t_FmPcdManipHdrParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_params_t) == sizeof(t_FmPcdManipReassemParams)); -+#if !defined(CONFIG_COMPAT) -+ /* different alignment */ -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_params_t) == sizeof(t_FmPcdManipParams) + sizeof(void *)); -+#endif -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_stats_t) == sizeof(t_FmPcdManipReassemIpStats)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_stats_t) == sizeof(t_FmPcdManipFragIpStats)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_stats_t) == sizeof(t_FmPcdManipReassemStats)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_stats_t) == sizeof(t_FmPcdManipFragStats)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_manip_stats_t) == sizeof(t_FmPcdManipStats)); -+#if DPAA_VERSION >= 11 -+ ASSERT_COND(sizeof(ioc_fm_pcd_frm_replic_group_params_t) == sizeof(t_FmPcdFrmReplicGroupParams) + sizeof(void *)); -+#endif -+ -+ /* fm_port_ext.h == fm_port_ioctls.h */ -+ ASSERT_COND(sizeof(ioc_fm_port_rate_limit_t) == sizeof(t_FmPortRateLimit)); -+ ASSERT_COND(sizeof(ioc_fm_port_pcd_params_t) == sizeof(t_FmPortPcdParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_select_t) == sizeof(t_FmPcdKgSchemeSelect)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_port_schemes_params_t) == sizeof(t_FmPcdPortSchemesParams)); -+ ASSERT_COND(sizeof(ioc_fm_pcd_prs_start_t) == sizeof(t_FmPcdPrsStart)); -+ -+ return; -+} -+ -+#define ASSERT_IOC_NET_ENUM(def) ASSERT_COND((unsigned long)e_IOC_NET_##def == (unsigned long)def) -+ -+void LnxWrpPCDIOCTLEnumChecking(void) -+{ -+ /* net_ext.h == net_ioctls.h : sampling checks */ -+ ASSERT_IOC_NET_ENUM(HEADER_TYPE_MACSEC); -+ ASSERT_IOC_NET_ENUM(HEADER_TYPE_PPP); -+ ASSERT_IOC_NET_ENUM(MAX_HEADER_TYPE_COUNT); -+ -+ /* fm_ext.h == fm_ioctls.h */ -+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_TYPE_DUMMY == (unsigned long)e_FM_PORT_TYPE_DUMMY); -+ ASSERT_COND((unsigned long)e_IOC_EX_MURAM_ECC == (unsigned long)e_FM_EX_MURAM_ECC); -+ ASSERT_COND((unsigned long)e_IOC_FM_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_COUNTERS_DEQ_CONFIRM); -+ -+ /* fm_pcd_ext.h == fm_pcd_ioctls.h */ -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES == (unsigned long)e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC == (unsigned long)e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS == (unsigned long)e_FM_PCD_PRS); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FULL_FIELD == (unsigned long)e_FM_PCD_EXTRACT_FULL_FIELD); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID == (unsigned long)e_FM_PCD_EXTRACT_FROM_FLOW_ID); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO == (unsigned long)e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_DFLT_ILLEGAL == (unsigned long)e_FM_PCD_KG_DFLT_ILLEGAL); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA == (unsigned long)e_FM_PCD_KG_GENERIC_NOT_FROM_DATA); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_HDR_INDEX_LAST == (unsigned long)e_FM_PCD_HDR_INDEX_LAST); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_SHARED == (unsigned long)e_FM_PCD_PLCR_SHARED); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_RFC_4115 == (unsigned long)e_FM_PCD_PLCR_RFC_4115); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_COLOR_AWARE == (unsigned long)e_FM_PCD_PLCR_COLOR_AWARE); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_OVERRIDE == (unsigned long)e_FM_PCD_PLCR_OVERRIDE); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_FULL_FRM_LEN); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PACKET_MODE == (unsigned long)e_FM_PCD_PLCR_PACKET_MODE); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_DROP_FRAME == (unsigned long)e_FM_PCD_DROP_FRAME); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER == (unsigned long)e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP == (unsigned long)e_FM_PCD_ACTION_INDEXED_LOOKUP); -+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR == (unsigned long)e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR); -+#if !defined(FM_CAPWAP_SUPPORT) -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_GENERIC == (unsigned long)e_FM_PCD_MANIP_INSRT_GENERIC); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_GENERIC == (unsigned long)e_FM_PCD_MANIP_RMV_GENERIC); -+#else -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE == (unsigned long)e_FM_PCD_MANIP_INSRT_BY_TEMPLATE); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START); -+#endif -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG == (unsigned long)e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH == (unsigned long)e_FM_PCD_MANIP_EIGHT_WAYS_HASH); -+ -+#ifdef FM_CAPWAP_SUPPORT -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_STATS_PER_FLOWID == (unsigned long)e_FM_PCD_STATS_PER_FLOWID); -+#endif -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_CC_STATS_MODE_FRAME == (unsigned long)e_FM_PCD_CC_STATS_MODE_FRAME); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG == (unsigned long)e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG); -+ ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC); -+ -+ /* fm_port_ext.h == fm_port_ioctls.h */ -+#if !defined(FM_CAPWAP_SUPPORT) -+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR == (unsigned long)e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR); -+#else -+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR == (unsigned long)e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR); -+#endif -+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_PORT_COUNTERS_DEQ_CONFIRM); -+ ASSERT_COND((unsigned long)e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 == (unsigned long)e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8); -+ -+ return; -+} -+ -+static t_Error LnxwrpFmPcdIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat) -+{ -+ t_Error err = E_OK; -+ -+/* -+Status: PCD API to fmlib (file: drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h): -+ -+ FM_PCD_PrsLoadSw -+ FM_PCD_SetAdvancedOffloadSupport -+ FM_PCD_Enable -+ FM_PCD_Disable -+ FM_PCD_ForceIntr -+ FM_PCD_SetException -+ FM_PCD_KgSetAdditionalDataAfterParsing -+ FM_PCD_KgSetDfltValue -+ FM_PCD_NetEnvCharacteristicsSet -+ FM_PCD_NetEnvCharacteristicsDelete -+ FM_PCD_KgSchemeSet -+ FM_PCD_KgSchemeDelete -+ FM_PCD_MatchTableSet -+ FM_PCD_MatchTableDelete -+ FM_PCD_CcRootBuild -+ FM_PCD_CcRootDelete -+ FM_PCD_PlcrProfileSet -+ FM_PCD_PlcrProfileDelete -+ FM_PCD_CcRootModifyNextEngine -+ FM_PCD_MatchTableModifyNextEngine -+ FM_PCD_MatchTableModifyMissNextEngine -+ FM_PCD_MatchTableRemoveKey -+ FM_PCD_MatchTableAddKey -+ FM_PCD_MatchTableModifyKeyAndNextEngine -+ FM_PCD_HashTableSet -+ FM_PCD_HashTableDelete -+ FM_PCD_HashTableAddKey -+ FM_PCD_HashTableRemoveKey -+ FM_PCD_MatchTableModifyKey -+ FM_PCD_ManipNodeReplace -+ FM_PCD_ManipNodeSet -+ FM_PCD_ManipNodeDelete -+ -+Status: not exported, should be thru sysfs -+ FM_PCD_KgSchemeGetCounter -+ FM_PCD_KgSchemeSetCounter -+ FM_PCD_PlcrProfileGetCounter -+ FM_PCD_PlcrProfileSetCounter -+ -+Status: not exported -+ FM_PCD_MatchTableFindNRemoveKey -+ FM_PCD_MatchTableFindNModifyNextEngine -+ FM_PCD_MatchTableFindNModifyKeyAndNextEngine -+ FM_PCD_MatchTableFindNModifyKey -+ FM_PCD_MatchTableGetIndexedHashBucket -+ FM_PCD_MatchTableGetNextEngine -+ FM_PCD_MatchTableGetKeyCounter -+ -+Status: not exported, would be nice to have -+ FM_PCD_HashTableModifyNextEngine -+ FM_PCD_HashTableModifyMissNextEngine -+ FM_PCD_HashTableGetMissNextEngine -+ FM_PCD_ManipGetStatistics -+ -+Status: not exported -+#if DPAA_VERSION >= 11 -+ -+ FM_VSP_GetStatistics -- it's not available yet -+#endif -+ -+Status: feature not supported -+#ifdef FM_CAPWAP_SUPPORT -+#error unsupported feature -+ FM_PCD_StatisticsSetNode -+#endif -+ -+ */ -+ _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n", -+ cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 20); -+ -+ switch (cmd) -+ { -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_PRS_LOAD_SW_COMPAT: -+#endif -+ case FM_PCD_IOC_PRS_LOAD_SW: -+ { -+ ioc_fm_pcd_prs_sw_params_t *param; -+ uint8_t *p_code; -+ -+ param = (ioc_fm_pcd_prs_sw_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_prs_sw_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_prs_sw_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_prs_sw_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_prs_sw_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_prs_sw_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_prs_sw_params_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_prs_sw_params_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_prs_sw_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_fm_pcd_prs_sw(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_prs_sw_params_t *)arg, -+ sizeof(ioc_fm_pcd_prs_sw_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ if (!param->p_code || !param->size) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ p_code = (uint8_t *) XX_Malloc(param->size); -+ if (!p_code) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(p_code, 0, param->size); -+ if (copy_from_user(p_code, param->p_code, param->size)) -+ { -+ XX_Free(p_code); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->p_code = p_code; -+ -+ err = FM_PCD_PrsLoadSw(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPrsSwParams*)param); -+ -+ XX_Free(p_code); -+ XX_Free(param); -+ break; -+ } -+ -+ case FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT: -+ err = FM_PCD_SetAdvancedOffloadSupport(p_LnxWrpFmDev->h_PcdDev); -+ break; -+ -+ case FM_PCD_IOC_ENABLE: -+ err = FM_PCD_Enable(p_LnxWrpFmDev->h_PcdDev); -+ break; -+ -+ case FM_PCD_IOC_DISABLE: -+ err = FM_PCD_Disable(p_LnxWrpFmDev->h_PcdDev); -+ break; -+ -+ case FM_PCD_IOC_FORCE_INTR: -+ { -+ int exception; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (get_user(exception, (int *) compat_ptr(arg))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ else -+#endif -+ { -+ if (get_user(exception, (int *)arg)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PCD_ForceIntr(p_LnxWrpFmDev->h_PcdDev, (e_FmPcdExceptions)exception); -+ break; -+ } -+ -+ case FM_PCD_IOC_SET_EXCEPTION: -+ { -+ ioc_fm_pcd_exception_params_t *param; -+ -+ param = (ioc_fm_pcd_exception_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_exception_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_exception_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)compat_ptr(arg), -+ sizeof(ioc_fm_pcd_exception_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)arg, -+ sizeof(ioc_fm_pcd_exception_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, param->exception, param->enable); -+ -+ XX_Free(param); -+ break; -+ } -+ -+ case FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING: -+ { -+ uint8_t payloadOffset; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (get_user(payloadOffset, (uint8_t*) compat_ptr(arg))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ else -+#endif -+ { -+ if (get_user(payloadOffset, (uint8_t*) arg)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PCD_KgSetAdditionalDataAfterParsing(p_LnxWrpFmDev->h_PcdDev, payloadOffset); -+ break; -+ } -+ -+ case FM_PCD_IOC_KG_SET_DFLT_VALUE: -+ { -+ ioc_fm_pcd_kg_dflt_value_params_t *param; -+ -+ param = (ioc_fm_pcd_kg_dflt_value_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_kg_dflt_value_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_kg_dflt_value_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)compat_ptr(arg), -+ sizeof(ioc_fm_pcd_kg_dflt_value_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)arg, -+ sizeof(ioc_fm_pcd_kg_dflt_value_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PCD_KgSetDfltValue(p_LnxWrpFmDev->h_PcdDev, param->valueId, param->value); -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT: -+#endif -+ case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET: -+ { -+ ioc_fm_pcd_net_env_params_t *param; -+ -+ param = (ioc_fm_pcd_net_env_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_net_env_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_net_env_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_net_env_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_net_env_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t)); -+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_net_env_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_US_TO_K); -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_net_env_params_t *) arg, -+ sizeof(ioc_fm_pcd_net_env_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ param->id = FM_PCD_NetEnvCharacteristicsSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdNetEnvParams*)param); -+ -+ if (!param->id) -+ { -+ XX_Free(param); -+ err = E_INVALID_VALUE; -+ /* Since the LLD has no errno-style error reporting, -+ we're left here with no other option than to report -+ a generic E_INVALID_VALUE */ -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_net_env_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_net_env_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t)); -+ compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_K_TO_US); -+ -+ if (copy_to_user((ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_net_env_params_t))) -+ err = E_READ_FAILED; -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_pcd_net_env_params_t *)arg, -+ param, -+ sizeof(ioc_fm_pcd_net_env_params_t))) -+ err = E_READ_FAILED; -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT: -+#endif -+ case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0 , sizeof(ioc_fm_obj_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_obj_delete(&compat_id, &id); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PCD_NetEnvCharacteristicsDelete(id.obj); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_KG_SCHEME_SET_COMPAT: -+#endif -+ case FM_PCD_IOC_KG_SCHEME_SET: -+ { -+ ioc_fm_pcd_kg_scheme_params_t *param; -+ -+ param = (ioc_fm_pcd_kg_scheme_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_kg_scheme_params_t *compat_param = NULL; -+ -+ compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)); -+ -+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_params_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_kg_scheme_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_params_t *)arg, -+ sizeof(ioc_fm_pcd_kg_scheme_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ param->id = FM_PCD_KgSchemeSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdKgSchemeParams*)param); -+ -+ if (!param->id) -+ { -+ XX_Free(param); -+ err = E_INVALID_VALUE; -+ /* Since the LLD has no errno-style error reporting, -+ we're left here with no other option than to report -+ a generic E_INVALID_VALUE */ -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_kg_scheme_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)); -+ compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_K_TO_US); -+ if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_params_t *)compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_kg_scheme_params_t))) -+ err = E_READ_FAILED; -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_pcd_kg_scheme_params_t *)arg, -+ param, -+ sizeof(ioc_fm_pcd_kg_scheme_params_t))) -+ err = E_READ_FAILED; -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT: -+#endif -+ case FM_PCD_IOC_KG_SCHEME_GET_CNTR: -+ { -+ ioc_fm_pcd_kg_scheme_spc_t *param; -+ -+ param = (ioc_fm_pcd_kg_scheme_spc_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_spc_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_spc_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param = NULL; -+ -+ compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)); -+ -+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_spc_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_spc_t *)arg, -+ sizeof(ioc_fm_pcd_kg_scheme_spc_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ param->val = FM_PCD_KgSchemeGetCounter((t_Handle)param->id); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)); -+ compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_K_TO_US); -+ if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_spc_t *)compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t))) -+ err = E_READ_FAILED; -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_pcd_kg_scheme_spc_t *)arg, -+ param, -+ sizeof(ioc_fm_pcd_kg_scheme_spc_t))) -+ err = E_READ_FAILED; -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT: -+#endif -+ case FM_PCD_IOC_KG_SCHEME_DELETE: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0 , sizeof(ioc_fm_obj_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_obj_delete(&compat_id, &id); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PCD_KgSchemeDelete(id.obj); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MATCH_TABLE_SET_COMPAT: -+#endif -+ case FM_PCD_IOC_MATCH_TABLE_SET: -+ { -+ ioc_fm_pcd_cc_node_params_t *param; -+ uint8_t *keys; -+ uint8_t *masks; -+ int i,k; -+ -+ param = (ioc_fm_pcd_cc_node_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_cc_node_params_t) + -+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_params_t) + -+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY); -+ -+ keys = (uint8_t *) (param + 1); -+ masks = keys + IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_node_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_node_params_t) + -+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) + -+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY); -+ -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_node_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_params_t *)arg, sizeof(ioc_fm_pcd_cc_node_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ ASSERT_COND(param->keys_params.num_of_keys <= IOC_FM_PCD_MAX_NUM_OF_KEYS); -+ ASSERT_COND(param->keys_params.key_size <= IOC_FM_PCD_MAX_SIZE_OF_KEY); -+ -+ /* support for indexed lookup */ -+ if( !(param->extract_cc_params.type == e_IOC_FM_PCD_EXTRACT_NON_HDR && -+ param->extract_cc_params.extract_params.extract_non_hdr.src == e_IOC_FM_PCD_EXTRACT_FROM_HASH && -+ param->extract_cc_params.extract_params.extract_non_hdr.action == e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP)) -+ { -+ for (i=0, k=0; -+ i < param->keys_params.num_of_keys; -+ i++, k += IOC_FM_PCD_MAX_SIZE_OF_KEY) -+ { -+ if (param->keys_params.key_params[i].p_key && -+ param->keys_params.key_size) -+ { -+ if (copy_from_user(&keys[k], -+ param->keys_params.key_params[i].p_key, -+ param->keys_params.key_size)) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->keys_params.key_params[i].p_key = &keys[k]; -+ } -+ -+ if (param->keys_params.key_params[i].p_mask) -+ { -+ if (copy_from_user(&masks[k], -+ param->keys_params.key_params[i].p_mask, -+ param->keys_params.key_size)) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->keys_params.key_params[i].p_mask = &masks[k]; -+ } -+ } -+ } -+ -+ param->id = FM_PCD_MatchTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcNodeParams*)param); -+ -+ if (!param->id) { -+ XX_Free(param); -+ err = E_INVALID_VALUE; -+ /* Since the LLD has no errno-style error reporting, -+ we're left here with no other option than to report -+ a generic E_INVALID_VALUE */ -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_node_params_t *compat_param; -+ compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_node_params_t) + -+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) + -+ 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY); -+ compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_K_TO_US); -+ -+ if (copy_to_user((ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_cc_node_params_t))) -+ err = E_READ_FAILED; -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_pcd_cc_node_params_t *)arg, -+ param, -+ sizeof(ioc_fm_pcd_cc_node_params_t))) -+ err = E_READ_FAILED; -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT: -+#endif -+ case FM_PCD_IOC_MATCH_TABLE_DELETE: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0 , sizeof(ioc_fm_obj_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_obj_delete(&compat_id, &id); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PCD_MatchTableDelete(id.obj); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_CC_ROOT_BUILD_COMPAT: -+#endif -+ case FM_PCD_IOC_CC_ROOT_BUILD: -+ { -+ ioc_fm_pcd_cc_tree_params_t *param; -+ -+ param = (ioc_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_cc_tree_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_tree_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_tree_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_tree_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_cc_tree_params_t *)arg, -+ sizeof(ioc_fm_pcd_cc_tree_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ param->id = FM_PCD_CcRootBuild(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcTreeParams*)param); -+ -+ if (!param->id) { -+ XX_Free(param); -+ err = E_INVALID_VALUE; -+ /* Since the LLD has no errno-style error reporting, -+ we're left here with no other option than to report -+ a generic E_INVALID_VALUE */ -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_tree_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_compat_fm_pcd_cc_tree_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t)); -+ -+ compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_K_TO_US); -+ -+ if (copy_to_user((ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_cc_tree_params_t))) -+ err = E_READ_FAILED; -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_pcd_cc_tree_params_t *)arg, -+ param, -+ sizeof(ioc_fm_pcd_cc_tree_params_t))) -+ err = E_READ_FAILED; -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_CC_ROOT_DELETE_COMPAT: -+#endif -+ case FM_PCD_IOC_CC_ROOT_DELETE: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0 , sizeof(ioc_fm_obj_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_obj_delete(&compat_id, &id); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PCD_CcRootDelete(id.obj); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT: -+#endif -+ case FM_PCD_IOC_PLCR_PROFILE_SET: -+ { -+ ioc_fm_pcd_plcr_profile_params_t *param; -+ -+ param = (ioc_fm_pcd_plcr_profile_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_plcr_profile_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_plcr_profile_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_plcr_profile_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)); -+ if (copy_from_user(compat_param, ( -+ ioc_compat_fm_pcd_plcr_profile_params_t *)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_plcr_profile_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_plcr_profile_params_t *)arg, -+ sizeof(ioc_fm_pcd_plcr_profile_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ if (!param->modify && -+ (((t_FmPcdPlcrProfileParams*)param)->id.newParams.profileType != e_FM_PCD_PLCR_SHARED)) -+ { -+ t_Handle h_Port; -+ ioc_fm_pcd_port_params_t *port_params; -+ -+ port_params = (ioc_fm_pcd_port_params_t*) XX_Malloc(sizeof(ioc_fm_pcd_port_params_t)); -+ if (!port_params) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(port_params, 0, sizeof(ioc_fm_pcd_port_params_t)); -+ if (copy_from_user(port_params, (ioc_fm_pcd_port_params_t*)((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort, -+ sizeof(ioc_fm_pcd_port_params_t))) -+ { -+ XX_Free(port_params); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ switch(port_params->port_type) -+ { -+ case (e_IOC_FM_PORT_TYPE_RX): -+ if (port_params->port_id < FM_MAX_NUM_OF_1G_RX_PORTS) { -+ h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev; -+ break; -+ } -+ goto invalid_port_id; -+ -+ case (e_IOC_FM_PORT_TYPE_RX_10G): -+ if (port_params->port_id < FM_MAX_NUM_OF_10G_RX_PORTS) { -+#ifndef CONFIG_FMAN_ARM -+ if (IS_T1023_T1024) { -+ h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev; -+ } else { -+#else -+ { -+#endif -+ h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id + FM_MAX_NUM_OF_1G_RX_PORTS].h_Dev; -+ } -+ break; -+ } -+ goto invalid_port_id; -+ -+ case (e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ if (port_params->port_id && port_params->port_id < FM_MAX_NUM_OF_OH_PORTS) { -+ h_Port = p_LnxWrpFmDev->opPorts[port_params->port_id - 1].h_Dev; -+ break; -+ } -+ goto invalid_port_id; -+ -+ default: -+invalid_port_id: -+ XX_Free(port_params); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG); -+ } -+ -+ ((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort = h_Port; -+ XX_Free(port_params); -+ } -+ -+ param->id = FM_PCD_PlcrProfileSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPlcrProfileParams*)param); -+ -+ if (!param->id) { -+ XX_Free(param); -+ err = E_INVALID_VALUE; -+ /* Since the LLD has no errno-style error reporting, -+ we're left here with no other option than to report -+ a generic E_INVALID_VALUE */ -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_plcr_profile_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)); -+ compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_K_TO_US); -+ if (copy_to_user((ioc_compat_fm_pcd_plcr_profile_params_t *) compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_plcr_profile_params_t))) -+ err = E_READ_FAILED; -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_pcd_plcr_profile_params_t *)arg, -+ param, -+ sizeof(ioc_fm_pcd_plcr_profile_params_t))) -+ err = E_READ_FAILED; -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT: -+#endif -+ case FM_PCD_IOC_PLCR_PROFILE_DELETE: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0 , sizeof(ioc_fm_obj_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_obj_delete(&compat_id, &id); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PCD_PlcrProfileDelete(id.obj); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT: -+#endif -+ case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE: -+ { -+ ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param; -+ -+ param = (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)); -+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_fm_pcd_cc_tree_modify_next_engine(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *)arg, -+ sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PCD_CcRootModifyNextEngine(param->id, -+ param->grp_indx, -+ param->indx, -+ (t_FmPcdCcNextEngineParams*)(¶m->cc_next_engine_params)); -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT: -+#endif -+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE: -+ { -+ ioc_fm_pcd_cc_node_modify_next_engine_params_t *param; -+ -+ param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)); -+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *)arg, -+ sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PCD_MatchTableModifyNextEngine(param->id, -+ param->key_indx, -+ (t_FmPcdCcNextEngineParams*)(¶m->cc_next_engine_params)); -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT: -+#endif -+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE: -+ { -+ ioc_fm_pcd_cc_node_modify_next_engine_params_t *param; -+ -+ param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)); -+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) arg, -+ sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PCD_MatchTableModifyMissNextEngine(param->id, -+ (t_FmPcdCcNextEngineParams*)(¶m->cc_next_engine_params)); -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT: -+#endif -+ case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY: -+ { -+ ioc_fm_pcd_cc_node_remove_key_params_t *param; -+ -+ param = (ioc_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_cc_node_remove_key_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_remove_key_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_node_remove_key_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_cc_node_remove_key_params_t *)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->id = compat_ptr(compat_param->id); -+ param->key_indx = compat_param->key_indx; -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_remove_key_params_t *) arg, -+ sizeof(ioc_fm_pcd_cc_node_remove_key_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PCD_MatchTableRemoveKey(param->id, param->key_indx); -+ -+ XX_Free(param); -+ break; -+ } -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT: -+#endif -+ case FM_PCD_IOC_MATCH_TABLE_ADD_KEY: -+ { -+ ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param; -+ -+ param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg, -+ sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ if (param->key_size) -+ { -+ int size = 0; -+ -+ if (param->key_params.p_key) size += param->key_size; -+ if (param->key_params.p_mask) size += param->key_size; -+ -+ if (size) -+ { -+ uint8_t *p_tmp; -+ -+ p_tmp = (uint8_t*) XX_Malloc(size); -+ if (!p_tmp) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask")); -+ } -+ -+ if (param->key_params.p_key) -+ { -+ if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size)) -+ { -+ XX_Free(p_tmp); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->key_params.p_key = p_tmp; -+ } -+ -+ if (param->key_params.p_mask) -+ { -+ p_tmp += param->key_size; -+ if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size)) -+ { -+ XX_Free(p_tmp - param->key_size); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->key_params.p_mask = p_tmp; -+ } -+ } -+ } -+ -+ err = FM_PCD_MatchTableAddKey( -+ param->id, -+ param->key_indx, -+ param->key_size, -+ (t_FmPcdCcKeyParams*)¶m->key_params); -+ -+ if (param->key_params.p_key) -+ XX_Free(param->key_params.p_key); -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT: -+#endif -+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE: -+ { -+ ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param; -+ -+ param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg, -+ sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PCD_MatchTableModifyKeyAndNextEngine(param->id, -+ param->key_indx, -+ param->key_size, -+ (t_FmPcdCcKeyParams*)(¶m->key_params)); -+ -+ XX_Free(param); -+ break; -+ } -+ -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT: -+#endif -+ case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT: -+ { -+ ioc_fm_pcd_cc_tbl_get_stats_t param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ if (!compat_param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))) -+ { -+ XX_Free(compat_param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, ¶m, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(¶m, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg, -+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ -+ err = FM_PCD_MatchTableGetKeyStatistics((t_Handle) param.id, -+ param.key_index, -+ (t_FmPcdCcKeyStatistics *) ¶m.statistics); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ if (!compat_param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, ¶m, COMPAT_K_TO_US); -+ if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){ -+ XX_Free(compat_param); -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ } -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg, -+ ¶m, -+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t))) -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ } -+ -+ break; -+ } -+ -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT: -+#endif -+ case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT: -+ { -+ ioc_fm_pcd_cc_tbl_get_stats_t param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ if (!compat_param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))) -+ { -+ XX_Free(compat_param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, ¶m, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(¶m, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg, -+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ -+ err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id, -+ (t_FmPcdCcKeyStatistics *) ¶m.statistics); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ if (!compat_param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, ¶m, COMPAT_K_TO_US); -+ if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){ -+ XX_Free(compat_param); -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ } -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg, -+ ¶m, -+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t))) -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ } -+ -+ break; -+ } -+ -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT: -+#endif -+ case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT: -+ { -+ ioc_fm_pcd_cc_tbl_get_stats_t param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ if (!compat_param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))) -+ { -+ XX_Free(compat_param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, ¶m, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(¶m, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg, -+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ -+ err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id, -+ (t_FmPcdCcKeyStatistics *) ¶m.statistics); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ if (!compat_param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)); -+ compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, ¶m, COMPAT_K_TO_US); -+ if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){ -+ XX_Free(compat_param); -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ } -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg, -+ ¶m, -+ sizeof(ioc_fm_pcd_cc_tbl_get_stats_t))) -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ } -+ -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_HASH_TABLE_SET_COMPAT: -+#endif -+ case FM_PCD_IOC_HASH_TABLE_SET: -+ { -+ ioc_fm_pcd_hash_table_params_t *param; -+ -+ param = (ioc_fm_pcd_hash_table_params_t*) XX_Malloc( -+ sizeof(ioc_fm_pcd_hash_table_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_hash_table_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_hash_table_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_hash_table_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_hash_table_params_t*)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_hash_table_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_hash_table_params_t *)arg, -+ sizeof(ioc_fm_pcd_hash_table_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ param->id = FM_PCD_HashTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdHashTableParams *) param); -+ -+ if (!param->id) -+ { -+ XX_Free(param); -+ err = E_INVALID_VALUE; -+ /* Since the LLD has no errno-style error reporting, -+ we're left here with no other option than to report -+ a generic E_INVALID_VALUE */ -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_hash_table_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_hash_table_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t)); -+ compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_K_TO_US); -+ if (copy_to_user((ioc_compat_fm_pcd_hash_table_params_t*) compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_hash_table_params_t))) -+ err = E_READ_FAILED; -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg, -+ param, -+ sizeof(ioc_fm_pcd_hash_table_params_t))) -+ err = E_READ_FAILED; -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT: -+#endif -+ case FM_PCD_IOC_HASH_TABLE_DELETE: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0, sizeof(ioc_fm_obj_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ id.obj = compat_pcd_id2ptr(compat_id.obj); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PCD_HashTableDelete(id.obj); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT: -+#endif -+ case FM_PCD_IOC_HASH_TABLE_ADD_KEY: -+ { -+ ioc_fm_pcd_hash_table_add_key_params_t *param = NULL; -+ -+ param = (ioc_fm_pcd_hash_table_add_key_params_t*) XX_Malloc( -+ sizeof(ioc_fm_pcd_hash_table_add_key_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_hash_table_add_key_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_hash_table_add_key_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_hash_table_add_key_params_t*) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_hash_table_add_key_params_t*) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ if (compat_param->key_size) -+ { -+ param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl); -+ param->key_size = compat_param->key_size; -+ -+ compat_copy_fm_pcd_cc_key(&compat_param->key_params, ¶m->key_params, COMPAT_US_TO_K); -+ } -+ else -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ err = E_INVALID_VALUE; -+ break; -+ } -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_hash_table_add_key_params_t*) arg, -+ sizeof(ioc_fm_pcd_hash_table_add_key_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ if (param->key_size) -+ { -+ int size = 0; -+ -+ if (param->key_params.p_key) size += param->key_size; -+ if (param->key_params.p_mask) size += param->key_size; -+ -+ if (size) -+ { -+ uint8_t *p_tmp; -+ -+ p_tmp = (uint8_t*) XX_Malloc(size); -+ if (!p_tmp) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask")); -+ } -+ -+ if (param->key_params.p_key) -+ { -+ if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size)) -+ { -+ XX_Free(p_tmp); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->key_params.p_key = p_tmp; -+ } -+ -+ if (param->key_params.p_mask) -+ { -+ p_tmp += param->key_size; -+ if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size)) -+ { -+ XX_Free(p_tmp - param->key_size); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->key_params.p_mask = p_tmp; -+ } -+ } -+ } -+ -+ err = FM_PCD_HashTableAddKey( -+ param->p_hash_tbl, -+ param->key_size, -+ (t_FmPcdCcKeyParams*)¶m->key_params); -+ -+ if (param->key_params.p_key) -+ XX_Free(param->key_params.p_key); -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT: -+#endif -+ case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY: -+ { -+ ioc_fm_pcd_hash_table_remove_key_params_t *param = NULL; -+ -+ param = (ioc_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc( -+ sizeof(ioc_fm_pcd_hash_table_remove_key_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_hash_table_remove_key_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_hash_table_remove_key_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl); -+ param->key_size = compat_param->key_size; -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_hash_table_remove_key_params_t*)arg, -+ sizeof(ioc_fm_pcd_hash_table_remove_key_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ if (param->key_size) -+ { -+ uint8_t *p_key; -+ -+ p_key = (uint8_t*) XX_Malloc(param->key_size); -+ if (!p_key) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ if (param->p_key && copy_from_user(p_key, param->p_key, param->key_size)) -+ { -+ XX_Free(p_key); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ param->p_key = p_key; -+ } -+ -+ err = FM_PCD_HashTableRemoveKey( -+ param->p_hash_tbl, -+ param->key_size, -+ param->p_key); -+ -+ if (param->p_key) -+ XX_Free(param->p_key); -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT: -+#endif -+ case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY: -+ { -+ ioc_fm_pcd_cc_node_modify_key_params_t *param; -+ -+ param = (ioc_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_cc_node_modify_key_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t)); -+ if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_key_params_t *)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_cc_node_modify_key(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_params_t *)arg, -+ sizeof(ioc_fm_pcd_cc_node_modify_key_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ if (param->key_size) -+ { -+ int size = 0; -+ -+ if (param->p_key) size += param->key_size; -+ if (param->p_mask) size += param->key_size; -+ -+ if (size) -+ { -+ uint8_t *p_tmp; -+ -+ p_tmp = (uint8_t*) XX_Malloc(size); -+ if (!p_tmp) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask")); -+ } -+ -+ if (param->p_key) -+ { -+ if (copy_from_user(p_tmp, param->p_key, param->key_size)) -+ { -+ XX_Free(p_tmp); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->p_key = p_tmp; -+ } -+ -+ if (param->p_mask) -+ { -+ p_tmp += param->key_size; -+ if (copy_from_user(p_tmp, param->p_mask, param->key_size)) -+ { -+ XX_Free(p_tmp - param->key_size); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->p_mask = p_tmp; -+ } -+ } -+ } -+ -+ err = FM_PCD_MatchTableModifyKey(param->id, -+ param->key_indx, -+ param->key_size, -+ param->p_key, -+ param->p_mask); -+ -+ if (param->p_key) -+ XX_Free(param->p_key); -+ else if (param->p_mask) -+ XX_Free(param->p_mask); -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MANIP_NODE_SET_COMPAT: -+#endif -+ case FM_PCD_IOC_MANIP_NODE_SET: -+ { -+ ioc_fm_pcd_manip_params_t *param; -+ uint8_t *p_data = NULL; -+ uint8_t size; -+ -+ param = (ioc_fm_pcd_manip_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_manip_params_t)); -+ -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_manip_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_manip_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_manip_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_manip_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_manip_params_t *)arg, -+ sizeof(ioc_fm_pcd_manip_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ if (param->type == e_IOC_FM_PCD_MANIP_HDR) -+ { -+ size = param->u.hdr.insrt_params.u.generic.size; -+ p_data = (uint8_t *) XX_Malloc(size); -+ if (!p_data ) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, NO_MSG); -+ } -+ -+ if (param->u.hdr.insrt_params.u.generic.p_data && -+ copy_from_user(p_data, -+ param->u.hdr.insrt_params.u.generic.p_data, size)) -+ { -+ XX_Free(p_data); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ param->u.hdr.insrt_params.u.generic.p_data = p_data; -+ } -+ -+ if (param->id) -+ { -+ /* Security Hole: the user can pass any piece of garbage -+ in 'param->id', and that will go straight through to the LLD, -+ no checks being done by the wrapper! */ -+ err = FM_PCD_ManipNodeReplace( -+ (t_Handle) param->id, -+ (t_FmPcdManipParams*) param); -+ if (err) -+ { -+ if (p_data) -+ XX_Free(p_data); -+ XX_Free(param); -+ break; -+ } -+ } -+ else -+ { -+ param->id = FM_PCD_ManipNodeSet( -+ p_LnxWrpFmDev->h_PcdDev, -+ (t_FmPcdManipParams*) param); -+ if (!param->id) -+ { -+ if (p_data) -+ XX_Free(p_data); -+ XX_Free(param); -+ err = E_INVALID_VALUE; -+ /* Since the LLD has no errno-style error reporting, -+ we're left here with no other option than to report -+ a generic E_INVALID_VALUE */ -+ break; -+ } -+ } -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_manip_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_manip_params_t)); -+ if (!compat_param) -+ { -+ if (p_data) -+ XX_Free(p_data); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t)); -+ -+ compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_K_TO_US); -+ -+ if (copy_to_user((ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_manip_params_t))) -+ err = E_READ_FAILED; -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_pcd_manip_params_t *)arg, -+ param, sizeof(ioc_fm_pcd_manip_params_t))) -+ err = E_READ_FAILED; -+ } -+ -+ if (p_data) -+ XX_Free(p_data); -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT: -+#endif -+ case FM_PCD_IOC_MANIP_NODE_DELETE: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0, sizeof(ioc_fm_obj_t)); -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_obj_delete(&compat_id, &id); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PCD_ManipNodeDelete(id.obj); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_MANIP_GET_STATS_COMPAT: -+#endif -+ case FM_PCD_IOC_MANIP_GET_STATS: -+ { -+ ioc_fm_pcd_manip_get_stats_t param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_manip_get_stats_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_manip_get_stats_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_manip_get_stats_t)); -+ if (!compat_param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_manip_get_stats_t *)compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_manip_get_stats_t))) -+ { -+ XX_Free(compat_param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_manip_get_stats(compat_param, ¶m, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(¶m, (ioc_fm_pcd_manip_get_stats_t *)arg, -+ sizeof(ioc_fm_pcd_manip_get_stats_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PCD_ManipGetStatistics((t_Handle) param.id, -+ (t_FmPcdManipStats*) ¶m.stats); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_manip_get_stats_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_manip_get_stats_t*) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_manip_get_stats_t)); -+ if (!compat_param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t)); -+ compat_copy_fm_pcd_manip_get_stats(compat_param, ¶m, COMPAT_K_TO_US); -+ if (copy_to_user((ioc_compat_fm_pcd_manip_get_stats_t*) compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_manip_get_stats_t))){ -+ XX_Free(compat_param); -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ } -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ if (copy_to_user((ioc_fm_pcd_manip_get_stats_t *)arg, -+ ¶m, -+ sizeof(ioc_fm_pcd_manip_get_stats_t))) -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ -+ break; -+ } -+ -+#if (DPAA_VERSION >= 11) -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT: -+#endif -+ case FM_PCD_IOC_FRM_REPLIC_GROUP_SET: -+ { -+ ioc_fm_pcd_frm_replic_group_params_t *param; -+ -+ param = (ioc_fm_pcd_frm_replic_group_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_frm_replic_group_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_frm_replic_group_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_frm_replic_group_params_t -+ *compat_param; -+ -+ compat_param = -+ (ioc_compat_fm_pcd_frm_replic_group_params_t *) -+ XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, -+ ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_frm_replic_group_params_t *) -+ compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t))) { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_frm_replic_group_params(compat_param, -+ param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, -+ (ioc_fm_pcd_frm_replic_group_params_t *)arg, -+ sizeof(ioc_fm_pcd_frm_replic_group_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ } -+ } -+ -+ param->id = FM_PCD_FrmReplicSetGroup(p_LnxWrpFmDev->h_PcdDev, -+ (t_FmPcdFrmReplicGroupParams*)param); -+ -+ if (!param->id) { -+ XX_Free(param); -+ err = E_INVALID_VALUE; -+ /* -+ * Since the LLD has no errno-style error reporting, -+ * we're left here with no other option than to report -+ * a generic E_INVALID_VALUE -+ */ -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_frm_replic_group_params_t -+ *compat_param; -+ -+ compat_param = -+ (ioc_compat_fm_pcd_frm_replic_group_params_t *) -+ XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, -+ ("IOCTL FM PCD")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)); -+ compat_copy_fm_pcd_frm_replic_group_params(compat_param, -+ param, COMPAT_K_TO_US); -+ if (copy_to_user( -+ (ioc_compat_fm_pcd_frm_replic_group_params_t *) -+ compat_ptr(arg), -+ compat_param, -+ sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t))) -+ err = E_WRITE_FAILED; -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_to_user( -+ (ioc_fm_pcd_frm_replic_group_params_t *)arg, -+ param, -+ sizeof(ioc_fm_pcd_frm_replic_group_params_t))) -+ err = E_WRITE_FAILED; -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ break; -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT: -+#endif -+ case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0, sizeof(ioc_fm_obj_t)); -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, -+ (ioc_compat_fm_obj_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_obj_t))) -+ break; -+ compat_obj_delete(&compat_id, &id); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, -+ sizeof(ioc_fm_obj_t))) -+ break; -+ } -+ -+ return FM_PCD_FrmReplicDeleteGroup(id.obj); -+ } -+ break; -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT: -+#endif -+ case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD: -+ { -+ ioc_fm_pcd_frm_replic_member_params_t param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_frm_replic_member_params_t compat_param; -+ -+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_copy_fm_pcd_frm_replic_member_params(&compat_param, ¶m, COMPAT_US_TO_K); -+ } -+ else -+#endif -+ if (copy_from_user(¶m, (void *)arg, sizeof(param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ return FM_PCD_FrmReplicAddMember(param.member.h_replic_group, -+ param.member.member_index, -+ (t_FmPcdCcNextEngineParams*)¶m.next_engine_params); -+ } -+ break; -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT: -+#endif -+ case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE: -+ { -+ ioc_fm_pcd_frm_replic_member_t param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_frm_replic_member_t compat_param; -+ -+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_copy_fm_pcd_frm_replic_member(&compat_param, ¶m, COMPAT_US_TO_K); -+ } -+ else -+#endif -+ if (copy_from_user(¶m, (void *)arg, sizeof(param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ return FM_PCD_FrmReplicRemoveMember(param.h_replic_group, param.member_index); -+ } -+ break; -+ -+#if defined(CONFIG_COMPAT) -+ case FM_IOC_VSP_CONFIG_COMPAT: -+#endif -+ case FM_IOC_VSP_CONFIG: -+ { -+ ioc_fm_vsp_params_t param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_vsp_params_t compat_param; -+ -+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_copy_fm_vsp_params(&compat_param, ¶m, COMPAT_US_TO_K); -+ } -+ else -+#endif -+ if (copy_from_user(¶m, (void *)arg, sizeof(param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ { -+ uint8_t portId = param.port_params.port_id; -+ param.liodn_offset = -+ p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset; -+ } -+ param.p_fm = p_LnxWrpFmDev->h_Dev; -+ param.id = FM_VSP_Config((t_FmVspParams *)¶m); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_vsp_params_t compat_param; -+ -+ memset(&compat_param, 0, sizeof(compat_param)); -+ compat_copy_fm_vsp_params(&compat_param, ¶m, COMPAT_K_TO_US); -+ -+ if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ else -+#endif -+ if (copy_to_user((void *)arg, ¶m, sizeof(param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_IOC_VSP_INIT_COMPAT: -+#endif -+ case FM_IOC_VSP_INIT: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0, sizeof(ioc_fm_obj_t)); -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, -+ (ioc_compat_fm_obj_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_obj_t))) -+ break; -+ id.obj = compat_pcd_id2ptr(compat_id.obj); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, -+ sizeof(ioc_fm_obj_t))) -+ break; -+ } -+ -+ return FM_VSP_Init(id.obj); -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_IOC_VSP_FREE_COMPAT: -+#endif -+ case FM_IOC_VSP_FREE: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0, sizeof(ioc_fm_obj_t)); -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, -+ (ioc_compat_fm_obj_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_obj_t))) -+ break; -+ compat_obj_delete(&compat_id, &id); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, -+ sizeof(ioc_fm_obj_t))) -+ break; -+ } -+ -+ return FM_VSP_Free(id.obj); -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT: -+#endif -+ case FM_IOC_VSP_CONFIG_POOL_DEPLETION: -+ { -+ ioc_fm_buf_pool_depletion_params_t param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_buf_pool_depletion_params_t compat_param; -+ -+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_copy_fm_buf_pool_depletion_params(&compat_param, ¶m, COMPAT_US_TO_K); -+ } -+ else -+#endif -+ if (copy_from_user(¶m, (void *)arg, sizeof(param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ if (FM_VSP_ConfigPoolDepletion(param.p_fm_vsp, -+ (t_FmBufPoolDepletion *)¶m.fm_buf_pool_depletion)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ break; -+ } -+ -+ -+#if defined(CONFIG_COMPAT) -+ case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT: -+#endif -+ case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT: -+ { -+ ioc_fm_buffer_prefix_content_params_t param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_buffer_prefix_content_params_t compat_param; -+ -+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_copy_fm_buffer_prefix_content_params(&compat_param, ¶m, COMPAT_US_TO_K); -+ } -+ else -+#endif -+ if (copy_from_user(¶m, (void *)arg, sizeof(param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ if (FM_VSP_ConfigBufferPrefixContent(param.p_fm_vsp, -+ (t_FmBufferPrefixContent *)¶m.fm_buffer_prefix_content)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_IOC_VSP_CONFIG_NO_SG_COMPAT: -+#endif -+ case FM_IOC_VSP_CONFIG_NO_SG: -+ { -+ ioc_fm_vsp_config_no_sg_params_t param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_vsp_config_no_sg_params_t compat_param; -+ -+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_copy_fm_vsp_config_no_sg_params(&compat_param, ¶m, COMPAT_US_TO_K); -+ } -+ else -+#endif -+ if (copy_from_user(¶m, (void *)arg, sizeof(param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ if (FM_VSP_ConfigNoScatherGather(param.p_fm_vsp, param.no_sg)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT: -+#endif -+ case FM_IOC_VSP_GET_BUFFER_PRS_RESULT: -+ { -+ ioc_fm_vsp_prs_result_params_t param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_vsp_prs_result_params_t compat_param; -+ -+ if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_copy_fm_vsp_prs_result_params(&compat_param, ¶m, COMPAT_US_TO_K); -+ } -+ else -+#endif -+ if (copy_from_user(¶m, (void *)arg, sizeof(param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ /* this call just adds the parse results offset to p_data */ -+ param.p_data = FM_VSP_GetBufferPrsResult(param.p_fm_vsp, param.p_data); -+ -+ if (!param.p_data) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_vsp_prs_result_params_t compat_param; -+ -+ memset(&compat_param, 0, sizeof(compat_param)); -+ compat_copy_fm_vsp_prs_result_params(&compat_param, ¶m, COMPAT_K_TO_US); -+ -+ if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ else -+#endif -+ if (copy_to_user((void *)arg, ¶m, sizeof(param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ break; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+#ifdef FM_CAPWAP_SUPPORT -+#warning "feature not supported!" -+#if defined(CONFIG_COMPAT) -+ case FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT: -+#endif -+ case FM_PCD_IOC_STATISTICS_SET_NODE: -+ { -+/* ioc_fm_pcd_stats_params_t param; -+ ... -+ param->id = FM_PCD_StatisticsSetNode(p_LnxWrpFmDev->h_PcdDev, -+ (t_FmPcdStatsParams *)¶m); -+*/ -+ err = E_NOT_SUPPORTED; -+ break; -+ } -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, -+ ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr: %d.\n", -+ cmd, _IOC_TYPE(cmd), _IOC_NR(cmd))); -+ } -+ -+ if (err) -+ RETURN_ERROR(MINOR, err, ("IOCTL FM PCD")); -+ -+ return E_OK; -+} -+ -+void FM_Get_Api_Version(ioc_fm_api_version_t *p_version) -+{ -+ p_version->version.major = FMD_API_VERSION_MAJOR; -+ p_version->version.minor = FMD_API_VERSION_MINOR; -+ p_version->version.respin = FMD_API_VERSION_RESPIN; -+ p_version->version.reserved = 0; -+} -+ -+t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat) -+{ -+ t_Error err = E_OK; -+ -+ switch (cmd) -+ { -+ case FM_IOC_SET_PORTS_BANDWIDTH: -+ { -+ ioc_fm_port_bandwidth_params *param; -+ -+ param = (ioc_fm_port_bandwidth_params*) XX_Malloc(sizeof(ioc_fm_port_bandwidth_params)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_port_bandwidth_params)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)compat_ptr(arg), sizeof(ioc_fm_port_bandwidth_params))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)arg, sizeof(ioc_fm_port_bandwidth_params))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_SetPortsBandwidth(p_LnxWrpFmDev->h_Dev, (t_FmPortsBandwidthParams*) param); -+ -+ XX_Free(param); -+ break; -+ } -+ -+ case FM_IOC_GET_REVISION: -+ { -+ ioc_fm_revision_info_t *param; -+ -+ param = (ioc_fm_revision_info_t *) XX_Malloc(sizeof(ioc_fm_revision_info_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ FM_GetRevision(p_LnxWrpFmDev->h_Dev, (t_FmRevisionInfo*)param); -+ /* This one never returns anything other than E_OK */ -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_to_user((ioc_fm_revision_info_t *)compat_ptr(arg), -+ param, -+ sizeof(ioc_fm_revision_info_t))){ -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ } -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_revision_info_t *)arg, -+ param, -+ sizeof(ioc_fm_revision_info_t))){ -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG); -+ } -+ } -+ XX_Free(param); -+ break; -+ } -+ -+ case FM_IOC_SET_COUNTER: -+ { -+ ioc_fm_counters_params_t *param; -+ -+ param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_counters_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_ModifyCounter(p_LnxWrpFmDev->h_Dev, param->cnt, param->val); -+ -+ XX_Free(param); -+ break; -+ } -+ -+ case FM_IOC_GET_COUNTER: -+ { -+ ioc_fm_counters_params_t *param; -+ -+ param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD")); -+ -+ memset(param, 0, sizeof(ioc_fm_counters_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ param->val = FM_GetCounter(p_LnxWrpFmDev->h_Dev, param->cnt); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_to_user((ioc_fm_counters_params_t *)compat_ptr(arg), param, sizeof(ioc_fm_counters_params_t))) -+ err = E_READ_FAILED; -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_counters_params_t *)arg, param, sizeof(ioc_fm_counters_params_t))) -+ err = E_READ_FAILED; -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ -+ case FM_IOC_FORCE_INTR: -+ { -+ ioc_fm_exceptions param; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (get_user(param, (ioc_fm_exceptions*) compat_ptr(arg))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ else -+#endif -+ { -+ if (get_user(param, (ioc_fm_exceptions*)arg)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_ForceIntr(p_LnxWrpFmDev->h_Dev, (e_FmExceptions)param); -+ break; -+ } -+ -+ case FM_IOC_GET_API_VERSION: -+ { -+ ioc_fm_api_version_t version; -+ -+ FM_Get_Api_Version(&version); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_to_user( -+ (ioc_fm_api_version_t *)compat_ptr(arg), -+ &version, sizeof(version))) -+ err = E_READ_FAILED; -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_api_version_t *)arg, -+ &version, sizeof(version))) -+ err = E_READ_FAILED; -+ } -+ } -+ break; -+ -+ case FM_IOC_CTRL_MON_START: -+ { -+ FM_CtrlMonStart(p_LnxWrpFmDev->h_Dev); -+ } -+ break; -+ -+ case FM_IOC_CTRL_MON_STOP: -+ { -+ FM_CtrlMonStop(p_LnxWrpFmDev->h_Dev); -+ } -+ break; -+ -+#if defined(CONFIG_COMPAT) -+ case FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT: -+#endif -+ case FM_IOC_CTRL_MON_GET_COUNTERS: -+ { -+ ioc_fm_ctrl_mon_counters_params_t param; -+ t_FmCtrlMon mon; -+ -+#if defined(CONFIG_COMPAT) -+ ioc_compat_fm_ctrl_mon_counters_params_t compat_param; -+ -+ if (compat) -+ { -+ if (copy_from_user(&compat_param, (void *)compat_ptr(arg), -+ sizeof(compat_param))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ param.fm_ctrl_index = compat_param.fm_ctrl_index; -+ param.p_mon = (fm_ctrl_mon_t *)compat_ptr(compat_param.p_mon); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(¶m, (void *)arg, sizeof(ioc_fm_ctrl_mon_counters_params_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ if (FM_CtrlMonGetCounters(p_LnxWrpFmDev->h_Dev, param.fm_ctrl_index, &mon)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ if (copy_to_user(param.p_mon, &mon, sizeof(t_FmCtrlMon))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ break; -+ -+ default: -+ return LnxwrpFmPcdIOCTL(p_LnxWrpFmDev, cmd, arg, compat); -+ } -+ -+ if (err) -+ RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM")); -+ -+ return E_OK; -+} -+ -+t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat) -+{ -+ t_Error err = E_OK; -+ -+ _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n", -+ cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 70); -+ -+ switch (cmd) -+ { -+ case FM_PORT_IOC_DISABLE: -+ FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev); -+ /* deliberately ignoring error codes here */ -+ return E_OK; -+ -+ case FM_PORT_IOC_ENABLE: -+ FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev); -+ /* deliberately ignoring error codes here */ -+ return E_OK; -+ -+ case FM_PORT_IOC_SET_ERRORS_ROUTE: -+ { -+ ioc_fm_port_frame_err_select_t errs; -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (get_user(errs, (ioc_fm_port_frame_err_select_t*)compat_ptr(arg))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ else -+#endif -+ { -+ if (get_user(errs, (ioc_fm_port_frame_err_select_t*)arg)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PORT_SetErrorsRoute(p_LnxWrpFmPortDev->h_Dev, (fmPortFrameErrSelect_t)errs); -+ break; -+ } -+ -+ case FM_PORT_IOC_SET_RATE_LIMIT: -+ { -+ ioc_fm_port_rate_limit_t *param; -+ -+ param = (ioc_fm_port_rate_limit_t *) XX_Malloc(sizeof(ioc_fm_port_rate_limit_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ -+ memset(param, 0, sizeof(ioc_fm_port_rate_limit_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)compat_ptr(arg), sizeof(ioc_fm_port_rate_limit_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)arg, sizeof(ioc_fm_port_rate_limit_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, (t_FmPortRateLimit *)param); -+ -+ XX_Free(param); -+ break; -+ } -+ -+ case FM_PORT_IOC_REMOVE_RATE_LIMIT: -+ FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev); -+ /* deliberately ignoring error codes here */ -+ return E_OK; -+ -+ case FM_PORT_IOC_ALLOC_PCD_FQIDS: -+ { -+ ioc_fm_port_pcd_fqids_params_t *param; -+ -+ if (!p_LnxWrpFmPortDev->pcd_owner_params.cba) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!")); -+ -+ param = (ioc_fm_port_pcd_fqids_params_t *) XX_Malloc(sizeof(ioc_fm_port_pcd_fqids_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ -+ memset(param, 0, sizeof(ioc_fm_port_pcd_fqids_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg), -+ sizeof(ioc_fm_port_pcd_fqids_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)arg, -+ sizeof(ioc_fm_port_pcd_fqids_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ if (p_LnxWrpFmPortDev->pcd_owner_params.cba(p_LnxWrpFmPortDev->pcd_owner_params.dev, -+ param->num_fqids, -+ param->alignment, -+ ¶m->base_fqid)) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("can't allocate fqids for PCD!!!")); -+ } -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg), -+ param, sizeof(ioc_fm_port_pcd_fqids_params_t))) -+ err = E_READ_FAILED; -+ } -+ else -+#endif -+ { -+ if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)arg, -+ param, sizeof(ioc_fm_port_pcd_fqids_params_t))) -+ err = E_READ_FAILED; -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ -+ case FM_PORT_IOC_FREE_PCD_FQIDS: -+ { -+ uint32_t base_fqid; -+ -+ if (!p_LnxWrpFmPortDev->pcd_owner_params.cbf) -+ RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!")); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (get_user(base_fqid, (uint32_t*) compat_ptr(arg))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ else -+#endif -+ { -+ if (get_user(base_fqid, (uint32_t*)arg)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ if (p_LnxWrpFmPortDev->pcd_owner_params.cbf(p_LnxWrpFmPortDev->pcd_owner_params.dev, base_fqid)) -+ err = E_WRITE_FAILED; -+ -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PORT_IOC_SET_PCD_COMPAT: -+#endif -+ case FM_PORT_IOC_SET_PCD: -+ { -+ ioc_fm_port_pcd_params_t *port_pcd_params; -+ ioc_fm_port_pcd_prs_params_t *port_pcd_prs_params; -+ ioc_fm_port_pcd_cc_params_t *port_pcd_cc_params; -+ ioc_fm_port_pcd_kg_params_t *port_pcd_kg_params; -+ ioc_fm_port_pcd_plcr_params_t *port_pcd_plcr_params; -+ -+ port_pcd_params = (ioc_fm_port_pcd_params_t *) XX_Malloc( -+ sizeof(ioc_fm_port_pcd_params_t) + -+ sizeof(ioc_fm_port_pcd_prs_params_t) + -+ sizeof(ioc_fm_port_pcd_cc_params_t) + -+ sizeof(ioc_fm_port_pcd_kg_params_t) + -+ sizeof(ioc_fm_port_pcd_plcr_params_t)); -+ if (!port_pcd_params) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ -+ memset(port_pcd_params, 0, -+ sizeof(ioc_fm_port_pcd_params_t) + -+ sizeof(ioc_fm_port_pcd_prs_params_t) + -+ sizeof(ioc_fm_port_pcd_cc_params_t) + -+ sizeof(ioc_fm_port_pcd_kg_params_t) + -+ sizeof(ioc_fm_port_pcd_plcr_params_t)); -+ -+ port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (port_pcd_params + 1); -+ port_pcd_cc_params = (ioc_fm_port_pcd_cc_params_t *) (port_pcd_prs_params + 1); -+ port_pcd_kg_params = (ioc_fm_port_pcd_kg_params_t *) (port_pcd_cc_params + 1); -+ port_pcd_plcr_params = (ioc_fm_port_pcd_plcr_params_t *) (port_pcd_kg_params + 1); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_port_pcd_params_t *compat_port_pcd_params; -+ ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params; -+ ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params; -+ ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params; -+ ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params; -+ -+ compat_port_pcd_params = (ioc_compat_fm_port_pcd_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_port_pcd_params_t) + -+ sizeof(ioc_fm_port_pcd_prs_params_t) + -+ sizeof(ioc_compat_fm_port_pcd_cc_params_t) + -+ sizeof(ioc_compat_fm_port_pcd_kg_params_t) + -+ sizeof(ioc_compat_fm_port_pcd_plcr_params_t)); -+ if (!compat_port_pcd_params) -+ { -+ XX_Free(port_pcd_params); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ } -+ -+ memset(compat_port_pcd_params, 0, -+ sizeof(ioc_compat_fm_port_pcd_params_t) + -+ sizeof(ioc_fm_port_pcd_prs_params_t) + -+ sizeof(ioc_compat_fm_port_pcd_cc_params_t) + -+ sizeof(ioc_compat_fm_port_pcd_kg_params_t) + -+ sizeof(ioc_compat_fm_port_pcd_plcr_params_t)); -+ same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_port_pcd_params + 1); -+ compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1); -+ compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1); -+ compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1); -+ -+ if (copy_from_user(compat_port_pcd_params, -+ (ioc_compat_fm_port_pcd_params_t*) compat_ptr(arg), -+ sizeof(ioc_compat_fm_port_pcd_params_t))) -+ err = E_WRITE_FAILED; -+ -+ while (!err) /* pseudo-while */ -+ { -+ /* set pointers from where to copy from: */ -+ port_pcd_params->p_prs_params = compat_ptr(compat_port_pcd_params->p_prs_params); /* same structure */ -+ port_pcd_params->p_cc_params = compat_ptr(compat_port_pcd_params->p_cc_params); -+ port_pcd_params->p_kg_params = compat_ptr(compat_port_pcd_params->p_kg_params); -+ port_pcd_params->p_plcr_params = compat_ptr(compat_port_pcd_params->p_plcr_params); -+ port_pcd_params->p_ip_reassembly_manip = compat_ptr(compat_port_pcd_params->p_ip_reassembly_manip); -+#if (DPAA_VERSION >= 11) -+ port_pcd_params->p_capwap_reassembly_manip = compat_ptr(compat_port_pcd_params->p_capwap_reassembly_manip); -+#endif -+ /* the prs member is the same, no compat structure...memcpy only */ -+ if (port_pcd_params->p_prs_params) -+ { -+ if (copy_from_user(same_port_pcd_prs_params, -+ port_pcd_params->p_prs_params, -+ sizeof(ioc_fm_port_pcd_prs_params_t))) -+ { -+ err = E_WRITE_FAILED; -+ break; /* from pseudo-while */ -+ } -+ -+ memcpy(port_pcd_prs_params, same_port_pcd_prs_params, sizeof(ioc_fm_port_pcd_prs_params_t)); -+ port_pcd_params->p_prs_params = port_pcd_prs_params; -+ } -+ -+ if (port_pcd_params->p_cc_params) -+ { -+ if (copy_from_user(compat_port_pcd_cc_params, -+ port_pcd_params->p_cc_params, -+ sizeof(ioc_compat_fm_port_pcd_cc_params_t))) -+ { -+ err = E_WRITE_FAILED; -+ break; /* from pseudo-while */ -+ } -+ -+ port_pcd_params->p_cc_params = port_pcd_cc_params; -+ } -+ -+ if (port_pcd_params->p_kg_params) -+ { -+ if (copy_from_user(compat_port_pcd_kg_params, -+ port_pcd_params->p_kg_params, -+ sizeof(ioc_compat_fm_port_pcd_kg_params_t))) -+ { -+ err = E_WRITE_FAILED; -+ break; /* from pseudo-while */ -+ } -+ -+ port_pcd_params->p_kg_params = port_pcd_kg_params; -+ } -+ -+ if (port_pcd_params->p_plcr_params) -+ { -+ if (copy_from_user(compat_port_pcd_plcr_params, -+ port_pcd_params->p_plcr_params, -+ sizeof(ioc_compat_fm_port_pcd_plcr_params_t))) -+ { -+ err = E_WRITE_FAILED; -+ break; /* from pseudo-while */ -+ } -+ -+ port_pcd_params->p_plcr_params = port_pcd_plcr_params; -+ } -+ -+ break; /* pseudo-while: always run once! */ -+ } -+ -+ if (!err) -+ compat_copy_fm_port_pcd(compat_port_pcd_params, port_pcd_params, COMPAT_US_TO_K); -+ -+ XX_Free(compat_port_pcd_params); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(port_pcd_params, -+ (ioc_fm_port_pcd_params_t*) arg, -+ sizeof(ioc_fm_port_pcd_params_t))) -+ err = E_WRITE_FAILED; -+ -+ while (!err) /* pseudo-while */ -+ { -+ if (port_pcd_params->p_prs_params) -+ { -+ if (copy_from_user(port_pcd_prs_params, -+ port_pcd_params->p_prs_params, -+ sizeof(ioc_fm_port_pcd_prs_params_t))) -+ { -+ err = E_WRITE_FAILED; -+ break; /* from pseudo-while */ -+ } -+ -+ port_pcd_params->p_prs_params = port_pcd_prs_params; -+ } -+ -+ if (port_pcd_params->p_cc_params) -+ { -+ if (copy_from_user(port_pcd_cc_params, -+ port_pcd_params->p_cc_params, -+ sizeof(ioc_fm_port_pcd_cc_params_t))) -+ { -+ err = E_WRITE_FAILED; -+ break; /* from pseudo-while */ -+ } -+ -+ port_pcd_params->p_cc_params = port_pcd_cc_params; -+ } -+ -+ if (port_pcd_params->p_kg_params) -+ { -+ if (copy_from_user(port_pcd_kg_params, -+ port_pcd_params->p_kg_params, -+ sizeof(ioc_fm_port_pcd_kg_params_t))) -+ { -+ err = E_WRITE_FAILED; -+ break; /* from pseudo-while */ -+ } -+ -+ port_pcd_params->p_kg_params = port_pcd_kg_params; -+ } -+ -+ if (port_pcd_params->p_plcr_params) -+ { -+ if (copy_from_user(port_pcd_plcr_params, -+ port_pcd_params->p_plcr_params, -+ sizeof(ioc_fm_port_pcd_plcr_params_t))) -+ { -+ err = E_WRITE_FAILED; -+ break; /* from pseudo-while */ -+ } -+ -+ port_pcd_params->p_plcr_params = port_pcd_plcr_params; -+ } -+ -+ break; /* pseudo-while: always run once! */ -+ } -+ } -+ -+ if (!err) -+ err = FM_PORT_SetPCD(p_LnxWrpFmPortDev->h_Dev, (t_FmPortPcdParams*) port_pcd_params); -+ -+ XX_Free(port_pcd_params); -+ break; -+ } -+ -+ case FM_PORT_IOC_DELETE_PCD: -+ err = FM_PORT_DeletePCD(p_LnxWrpFmPortDev->h_Dev); -+ break; -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT: -+#endif -+ case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME: -+ { -+ ioc_fm_pcd_kg_scheme_select_t *param; -+ -+ param = (ioc_fm_pcd_kg_scheme_select_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_kg_scheme_select_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ -+ memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_select_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_kg_scheme_select_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_pcd_kg_scheme_select_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_pcd_kg_scheme_select_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_select_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_pcd_kg_scheme_select_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_kg_scheme_select_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_kg_scheme_select(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_select_t *)arg, -+ sizeof(ioc_fm_pcd_kg_scheme_select_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PORT_PcdKgModifyInitialScheme(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdKgSchemeSelect *)param); -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT: -+#endif -+ case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0 , sizeof(ioc_fm_obj_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ id.obj = compat_ptr(compat_id.obj); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PORT_PcdPlcrModifyInitialProfile(p_LnxWrpFmPortDev->h_Dev, id.obj); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT: -+#endif -+ case FM_PORT_IOC_PCD_KG_BIND_SCHEMES: -+ { -+ ioc_fm_pcd_port_schemes_params_t *param; -+ -+ param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_port_schemes_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ -+ memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_port_schemes_params_t compat_param; -+ -+ if (copy_from_user(&compat_param, -+ (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_port_schemes_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg, -+ sizeof(ioc_fm_pcd_port_schemes_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PORT_PcdKgBindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param); -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT: -+#endif -+ case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES: -+ { -+ ioc_fm_pcd_port_schemes_params_t *param; -+ -+ param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc( -+ sizeof(ioc_fm_pcd_port_schemes_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ -+ memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_pcd_port_schemes_params_t compat_param; -+ -+ if (copy_from_user(&compat_param, -+ (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_pcd_port_schemes_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg, -+ sizeof(ioc_fm_pcd_port_schemes_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = FM_PORT_PcdKgUnbindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param); -+ -+ XX_Free(param); -+ break; -+ } -+ -+ case FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES: -+ { -+ uint16_t num; -+ if (get_user(num, (uint16_t*) arg)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ err = FM_PORT_PcdPlcrAllocProfiles(p_LnxWrpFmPortDev->h_Dev, num); -+ break; -+ } -+ -+ case FM_PORT_IOC_PCD_PLCR_FREE_PROFILES: -+ err = FM_PORT_PcdPlcrFreeProfiles(p_LnxWrpFmPortDev->h_Dev); -+ break; -+ -+ case FM_PORT_IOC_DETACH_PCD: -+ err = FM_PORT_DetachPCD(p_LnxWrpFmPortDev->h_Dev); -+ break; -+ -+ case FM_PORT_IOC_ATTACH_PCD: -+ err = FM_PORT_AttachPCD(p_LnxWrpFmPortDev->h_Dev); -+ break; -+ -+#if defined(CONFIG_COMPAT) -+ case FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT: -+#endif -+ case FM_PORT_IOC_PCD_CC_MODIFY_TREE: -+ { -+ ioc_fm_obj_t id; -+ -+ memset(&id, 0 , sizeof(ioc_fm_obj_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_obj_t compat_id; -+ -+ if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ compat_copy_fm_port_pcd_modify_tree(&compat_id, &id, COMPAT_US_TO_K); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ err = FM_PORT_PcdCcModifyTree(p_LnxWrpFmPortDev->h_Dev, id.obj); -+ break; -+ } -+ -+ case FM_PORT_IOC_ADD_CONGESTION_GRPS: -+ case FM_PORT_IOC_REMOVE_CONGESTION_GRPS: -+ { -+ ioc_fm_port_congestion_groups_t *param; -+ -+ param = (ioc_fm_port_congestion_groups_t*) XX_Malloc(sizeof(ioc_fm_port_congestion_groups_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ -+ memset(param, 0, sizeof(ioc_fm_port_congestion_groups_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_from_user(param, (t_FmPortCongestionGrps*) compat_ptr(arg), -+ sizeof(t_FmPortCongestionGrps))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ else -+#endif /* CONFIG_COMPAT */ -+ { -+ if (copy_from_user(param, (t_FmPortCongestionGrps*) arg, -+ sizeof(t_FmPortCongestionGrps))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ err = (cmd == FM_PORT_IOC_ADD_CONGESTION_GRPS) -+ ? FM_PORT_AddCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param) -+ : FM_PORT_RemoveCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param) -+ ; -+ -+ XX_Free(param); -+ break; -+ } -+ -+ case FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR: -+ case FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR: -+ { -+ ioc_fm_port_mac_addr_params_t *param; -+ -+ param = (ioc_fm_port_mac_addr_params_t*) XX_Malloc( -+ sizeof(ioc_fm_port_mac_addr_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ -+ memset(param, 0, sizeof(ioc_fm_port_mac_addr_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) compat_ptr(arg), -+ sizeof(ioc_fm_port_mac_addr_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ else -+#endif /* CONFIG_COMPAT */ -+ { -+ if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) arg, -+ sizeof(ioc_fm_port_mac_addr_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ if (p_LnxWrpFmPortDev->pcd_owner_params.dev) -+ { -+ int id = -1; -+ -+ switch(p_LnxWrpFmPortDev->settings.param.portType) -+ { -+ case e_FM_PORT_TYPE_RX: -+ case e_FM_PORT_TYPE_TX: -+ id = p_LnxWrpFmPortDev->id; -+ break; -+ case e_FM_PORT_TYPE_RX_10G: -+ case e_FM_PORT_TYPE_TX_10G: -+ id = p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_MACS; -+ break; -+ default: -+ err = E_NOT_AVAILABLE; -+ REPORT_ERROR(MINOR, err, ("Attempt to add/remove hash MAC addr. to/from MAC-less port!")); -+ } -+ if (id >= 0) -+ { -+ t_LnxWrpFmDev *fm = (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ t_Handle mac_handle = fm->macs[id].h_Dev; -+ -+ err = (cmd == FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR) -+ ? FM_MAC_AddHashMacAddr(mac_handle, (t_EnetAddr*) param) -+ : FM_MAC_RemoveHashMacAddr(mac_handle, (t_EnetAddr*) param); -+ } -+ } -+ else -+ { -+ err = E_NOT_AVAILABLE; -+ REPORT_ERROR(MINOR, err, ("Port not initialized or other error!?!?")); -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ -+ case FM_PORT_IOC_SET_TX_PAUSE_FRAMES: -+ { -+ t_LnxWrpFmDev *p_LnxWrpFmDev = -+ (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ ioc_fm_port_tx_pause_frames_params_t param; -+ int mac_id = p_LnxWrpFmPortDev->id; -+ -+ if(&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev) -+ mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */ -+ -+ if (copy_from_user(¶m, (ioc_fm_port_tx_pause_frames_params_t *)arg, -+ sizeof(ioc_fm_port_tx_pause_frames_params_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ if (p_LnxWrpFmDev && p_LnxWrpFmDev->macs[mac_id].h_Dev) -+ { -+ FM_MAC_SetTxPauseFrames(p_LnxWrpFmDev->macs[mac_id].h_Dev, -+ param.priority, -+ param.pause_time, -+ param.thresh_time); -+ } -+ else -+ { -+ err = E_NOT_AVAILABLE; -+ REPORT_ERROR(MINOR, err, ("Port not initialized or other error!")); -+ } -+ -+ break; -+ } -+ -+ case FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT: -+ { -+ ioc_fm_buffer_prefix_content_t *param; -+ -+ param = (ioc_fm_buffer_prefix_content_t*) XX_Malloc(sizeof(ioc_fm_buffer_prefix_content_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ -+ memset(param, 0, sizeof(ioc_fm_buffer_prefix_content_t)); -+ -+ if (copy_from_user(param, (ioc_fm_buffer_prefix_content_t*) arg, -+ sizeof(ioc_fm_buffer_prefix_content_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ if (FM_PORT_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_Dev, -+ (t_FmBufferPrefixContent *)param)) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ XX_Free(param); -+ break; -+ } -+ -+#if (DPAA_VERSION >= 11) -+#if defined(CONFIG_COMPAT) -+ case FM_PORT_IOC_VSP_ALLOC_COMPAT: -+#endif -+ case FM_PORT_IOC_VSP_ALLOC: -+ { -+ ioc_fm_port_vsp_alloc_params_t *param; -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ t_LnxWrpFmPortDev *p_LnxWrpFmTxPortDev; -+ -+ param = (ioc_fm_port_vsp_alloc_params_t *) XX_Malloc( -+ sizeof(ioc_fm_port_vsp_alloc_params_t)); -+ if (!param) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ -+ memset(param, 0, sizeof(ioc_fm_port_vsp_alloc_params_t)); -+ -+#if defined(CONFIG_COMPAT) -+ if (compat) -+ { -+ ioc_compat_fm_port_vsp_alloc_params_t *compat_param; -+ -+ compat_param = (ioc_compat_fm_port_vsp_alloc_params_t *) XX_Malloc( -+ sizeof(ioc_compat_fm_port_vsp_alloc_params_t)); -+ if (!compat_param) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT")); -+ } -+ -+ memset(compat_param, 0, sizeof(ioc_compat_fm_port_vsp_alloc_params_t)); -+ if (copy_from_user(compat_param, -+ (ioc_compat_fm_port_vsp_alloc_params_t *) compat_ptr(arg), -+ sizeof(ioc_compat_fm_port_vsp_alloc_params_t))) -+ { -+ XX_Free(compat_param); -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ compat_copy_fm_port_vsp_alloc_params(compat_param, param, COMPAT_US_TO_K); -+ -+ XX_Free(compat_param); -+ } -+ else -+#endif -+ { -+ if (copy_from_user(param, (ioc_fm_port_vsp_alloc_params_t *)arg, -+ sizeof(ioc_fm_port_vsp_alloc_params_t))) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ } -+ -+ /* Userspace may not have the Tx port t_handle when issuing the IOCTL */ -+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX || -+ p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) -+ { -+ /* Determine the Tx port t_Handle from the Rx port id */ -+ p_LnxWrpFmDev = p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ p_LnxWrpFmTxPortDev = &p_LnxWrpFmDev->txPorts[p_LnxWrpFmPortDev->id]; -+ param->p_fm_tx_port = p_LnxWrpFmTxPortDev->h_Dev; -+ } -+ -+ if (FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev, (t_FmPortVSPAllocParams *)param)) -+ { -+ XX_Free(param); -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ } -+ -+ XX_Free(param); -+ break; -+ } -+#endif /* (DPAA_VERSION >= 11) */ -+ -+ case FM_PORT_IOC_GET_MAC_STATISTICS: -+ { -+ t_LnxWrpFmDev *p_LnxWrpFmDev = -+ (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ ioc_fm_port_mac_statistics_t param; -+ int mac_id = p_LnxWrpFmPortDev->id; -+ -+ if (!p_LnxWrpFmDev) -+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!")); -+ -+ if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev && -+ &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev) -+ mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */ -+ -+ if (!p_LnxWrpFmDev->macs[mac_id].h_Dev) -+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!")); -+ -+ if (FM_MAC_GetStatistics(p_LnxWrpFmDev->macs[mac_id].h_Dev, -+ (t_FmMacStatistics *)¶m)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ if (copy_to_user((ioc_fm_port_mac_statistics_t *)arg, ¶m, -+ sizeof(ioc_fm_port_mac_statistics_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ break; -+ } -+ -+ case FM_PORT_IOC_GET_BMI_COUNTERS: -+ { -+ t_LnxWrpFmDev *p_LnxWrpFmDev = -+ (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ ioc_fm_port_bmi_stats_t param; -+ -+ if (!p_LnxWrpFmDev) -+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!")); -+ -+ if (FM_PORT_GetBmiCounters(p_LnxWrpFmPortDev->h_Dev, -+ (t_FmPortBmiStats *)¶m)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ if (copy_to_user((ioc_fm_port_bmi_stats_t *)arg, ¶m, -+ sizeof(ioc_fm_port_bmi_stats_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ break; -+ } -+ -+ default: -+ RETURN_ERROR(MINOR, E_INVALID_SELECTION, -+ ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr:0x%02x.\n", -+ cmd, _IOC_TYPE(cmd), _IOC_NR(cmd))); -+ } -+ -+ if (err) -+ RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM PORT")); -+ -+ return E_OK; -+} -+ -+/*****************************************************************************/ -+/* API routines for the FM Linux Device */ -+/*****************************************************************************/ -+ -+static int fm_open(struct inode *inode, struct file *file) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev = NULL; -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL; -+ unsigned int major = imajor(inode); -+ unsigned int minor = iminor(inode); -+ struct device_node *fm_node; -+ static struct of_device_id fm_node_of_match[] = { -+ { .compatible = "fsl,fman", }, -+ { /* end of list */ }, -+ }; -+ -+ DBG(TRACE, ("Opening minor - %d - ", minor)); -+ -+ if (file->private_data != NULL) -+ return 0; -+ -+ /* Get all the FM nodes */ -+ for_each_matching_node(fm_node, fm_node_of_match) { -+ struct platform_device *of_dev; -+ -+ of_dev = of_find_device_by_node(fm_node); -+ if (unlikely(of_dev == NULL)) { -+ REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!")); -+ return -ENXIO; -+ } -+ -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *)fm_bind(&of_dev->dev); -+ if (p_LnxWrpFmDev->major == major) -+ break; -+ fm_unbind((struct fm *)p_LnxWrpFmDev); -+ p_LnxWrpFmDev = NULL; -+ } -+ -+ if (!p_LnxWrpFmDev) -+ return -ENODEV; -+ -+ if (minor == DEV_FM_MINOR_BASE) -+ file->private_data = p_LnxWrpFmDev; -+ else if (minor == DEV_FM_PCD_MINOR_BASE) -+ file->private_data = p_LnxWrpFmDev; -+ else { -+ if (minor == DEV_FM_OH_PORTS_MINOR_BASE) -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort; -+ else if ((minor > DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->opPorts[minor-DEV_FM_OH_PORTS_MINOR_BASE-1]; -+ else if ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[minor-DEV_FM_RX_PORTS_MINOR_BASE]; -+ else if ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)) -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[minor-DEV_FM_TX_PORTS_MINOR_BASE]; -+ else -+ return -EINVAL; -+ -+ /* if trying to open port, check if it initialized */ -+ if (!p_LnxWrpFmPortDev->h_Dev) -+ return -ENODEV; -+ -+ p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)fm_port_bind(p_LnxWrpFmPortDev->dev); -+ file->private_data = p_LnxWrpFmPortDev; -+ fm_unbind((struct fm *)p_LnxWrpFmDev); -+ } -+ -+ if (file->private_data == NULL) -+ return -ENXIO; -+ -+ return 0; -+} -+ -+static int fm_close(struct inode *inode, struct file *file) -+{ -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+ unsigned int minor = iminor(inode); -+ int err = 0; -+ -+ DBG(TRACE, ("Closing minor - %d - ", minor)); -+ -+ if ((minor == DEV_FM_MINOR_BASE) || -+ (minor == DEV_FM_PCD_MINOR_BASE)) -+ { -+ p_LnxWrpFmDev = (t_LnxWrpFmDev*)file->private_data; -+ if (!p_LnxWrpFmDev) -+ return -ENODEV; -+ fm_unbind((struct fm *)p_LnxWrpFmDev); -+ } -+ else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) || -+ ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) || -+ ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS))) -+ { -+ p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)file->private_data; -+ if (!p_LnxWrpFmPortDev) -+ return -ENODEV; -+ fm_port_unbind((struct fm_port *)p_LnxWrpFmPortDev); -+ } -+ -+ return err; -+} -+ -+static int fm_ioctls(unsigned int minor, struct file *file, unsigned int cmd, unsigned long arg, bool compat) -+{ -+ DBG(TRACE, ("IOCTL minor - %u, cmd - 0x%08x, arg - 0x%08lx \n", minor, cmd, arg)); -+ -+ if ((minor == DEV_FM_MINOR_BASE) || -+ (minor == DEV_FM_PCD_MINOR_BASE)) -+ { -+ t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_LnxWrpFmDev*)file->private_data); -+ if (!p_LnxWrpFmDev) -+ return -ENODEV; -+ if (LnxwrpFmIOCTL(p_LnxWrpFmDev, cmd, arg, compat)) -+ return -EFAULT; -+ } -+ else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) || -+ ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) || -+ ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS))) -+ { -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = ((t_LnxWrpFmPortDev*)file->private_data); -+ if (!p_LnxWrpFmPortDev) -+ return -ENODEV; -+ if (LnxwrpFmPortIOCTL(p_LnxWrpFmPortDev, cmd, arg, compat)) -+ return -EFAULT; -+ } -+ else -+ { -+ REPORT_ERROR(MINOR, E_INVALID_VALUE, ("minor")); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+#ifdef CONFIG_COMPAT -+static long fm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ unsigned int minor = iminor(file->f_path.dentry->d_inode); -+ long res; -+ -+ fm_mutex_lock(); -+ res = fm_ioctls(minor, file, cmd, arg, true); -+ fm_mutex_unlock(); -+ -+ return res; -+} -+#endif -+ -+static long fm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ unsigned int minor = iminor(file->f_path.dentry->d_inode); -+ long res; -+ -+ fm_mutex_lock(); -+ res = fm_ioctls(minor, file, cmd, arg, false); -+ fm_mutex_unlock(); -+ -+ return res; -+} -+ -+/* Globals for FM character device */ -+struct file_operations fm_fops = -+{ -+ .owner = THIS_MODULE, -+ .unlocked_ioctl = fm_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = fm_compat_ioctl, -+#endif -+ .open = fm_open, -+ .release = fm_close, -+}; ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c -@@ -0,0 +1,1297 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ @File lnxwrp_fm_compat_ioctls.c -+ -+ @Description FM PCD compat functions -+ -+*/ -+ -+#if !defined(CONFIG_COMPAT) -+#error "missing COMPAT layer..." -+#endif -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifndef CONFIG_FMAN_ARM -+#include -+#endif -+ -+#include "part_ext.h" -+#include "fm_ioctls.h" -+#include "fm_pcd_ioctls.h" -+#include "fm_port_ioctls.h" -+#include "lnxwrp_ioctls_fm_compat.h" -+ -+#if defined(FM_COMPAT_DBG) -+static void hex_dump(void * p_addr, unsigned int size) -+{ -+ int i; -+ -+ for(i=0; i\n", p); -+ -+ if(!p) -+ return 0; -+ -+ for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++) -+ if(compat_ptr2id_array[k].ptr == NULL) -+ { -+ compat_ptr2id_array[k].ptr = p; -+ compat_ptr2id_array[k].node_type = node_type; -+ _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x \n", k | COMPAT_PTR2ID_WATERMARK); -+ return k | COMPAT_PTR2ID_WATERMARK; -+ } -+ -+ printk(KERN_WARNING "FMan map list full! No more PCD space on kernel!\n"); -+ return 0; -+} -+EXPORT_SYMBOL(compat_add_ptr2id); -+ -+compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type node_type) -+{ -+ compat_uptr_t k; -+ -+ _fm_cpt_dbg(COMPAT_GENERIC, " (%p) get -> \n", p); -+ -+ for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++) -+ if(compat_ptr2id_array[k].ptr == p && -+ compat_ptr2id_array[k].node_type == node_type) { -+ -+ _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x\n", k | COMPAT_PTR2ID_WATERMARK); -+ return k | COMPAT_PTR2ID_WATERMARK; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(compat_get_ptr2id); -+ -+void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type node_type) -+{ -+ -+ _fm_cpt_dbg(COMPAT_GENERIC, " (0x%08x) get -> \n", comp); -+ -+ if((COMPAT_PTR2ID_WM_MASK & comp) != COMPAT_PTR2ID_WATERMARK) { -+ _fm_cpt_dbg(COMPAT_GENERIC, "Error, invalid watermark (0x%08x)!\n\n", comp); -+ dump_stack(); -+ return compat_ptr(comp); -+ } -+ -+ comp &= ~COMPAT_PTR2ID_WM_MASK; -+ -+ if(((0 < comp) && (comp < COMPAT_PTR2ID_ARRAY_MAX) && (compat_ptr2id_array[comp].ptr != NULL) -+ && compat_ptr2id_array[comp].node_type == node_type)) { -+ _fm_cpt_dbg(COMPAT_GENERIC, "%p\n", compat_ptr2id_array[comp].ptr); -+ return compat_ptr2id_array[comp].ptr; -+ } -+ return NULL; -+} -+EXPORT_SYMBOL(compat_get_id2ptr); -+/* } maping kernel pointers w/ UserSpace id's */ -+ -+void compat_obj_delete( -+ ioc_compat_fm_obj_t *compat_id, -+ ioc_fm_obj_t *id) -+{ -+ id->obj = compat_pcd_id2ptr(compat_id->obj); -+ compat_del_ptr2id(id->obj, FM_MAP_TYPE_PCD_NODE); -+} -+ -+static inline void compat_copy_fm_pcd_plcr_next_engine( -+ ioc_compat_fm_pcd_plcr_next_engine_params_u *compat_param, -+ ioc_fm_pcd_plcr_next_engine_params_u *param, -+ ioc_fm_pcd_engine next_engine, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ switch (next_engine) -+ { -+ case e_IOC_FM_PCD_PLCR: -+ if (compat == COMPAT_US_TO_K) -+ param->p_profile = compat_pcd_id2ptr(compat_param->p_profile); -+ else -+ compat_param->p_profile = compat_pcd_ptr2id(param->p_profile); -+ break; -+ case e_IOC_FM_PCD_KG: -+ if (compat == COMPAT_US_TO_K) -+ param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme); -+ else -+ compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme); -+ break; -+ default: -+ if (compat == COMPAT_US_TO_K) -+ param->action = compat_param->action; -+ else -+ compat_param->action = param->action; -+ break; -+ } -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+void compat_copy_fm_pcd_plcr_profile( -+ ioc_compat_fm_pcd_plcr_profile_params_t *compat_param, -+ ioc_fm_pcd_plcr_profile_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->modify = compat_param->modify; -+ -+ /* profile_select */ -+ if (!compat_param->modify) -+ { -+ param->profile_select.new_params.profile_type = -+ compat_param->profile_select.new_params.profile_type; -+ param->profile_select.new_params.p_fm_port = -+ compat_ptr(compat_param->profile_select.new_params.p_fm_port); -+ param->profile_select.new_params.relative_profile_id = -+ compat_param->profile_select.new_params.relative_profile_id; -+ } -+ else -+ param->profile_select.p_profile = -+ compat_pcd_id2ptr(compat_param->profile_select.p_profile); -+ -+ param->alg_selection = compat_param->alg_selection; -+ param->color_mode = compat_param->color_mode; -+ -+ /* both parameters in the union has the same size, so memcpy works */ -+ memcpy(¶m->color, &compat_param->color, sizeof(param->color)); -+ -+ memcpy(¶m->non_passthrough_alg_param, -+ &compat_param->non_passthrough_alg_param, -+ sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t)); -+ -+ param->next_engine_on_green = compat_param->next_engine_on_green; -+ param->next_engine_on_yellow = compat_param->next_engine_on_yellow; -+ param->next_engine_on_red = compat_param->next_engine_on_red; -+ -+ param->trap_profile_on_flow_A = compat_param->trap_profile_on_flow_A; -+ param->trap_profile_on_flow_B = compat_param->trap_profile_on_flow_B; -+ param->trap_profile_on_flow_C = compat_param->trap_profile_on_flow_C; -+ } -+ else -+ { -+ compat_param->modify = param->modify; -+ -+ /* profile_select */ -+ if (!param->modify) -+ { -+ compat_param->profile_select.new_params.profile_type = -+ param->profile_select.new_params.profile_type; -+ compat_param->profile_select.new_params.p_fm_port = -+ ptr_to_compat(param->profile_select.new_params.p_fm_port); -+ compat_param->profile_select.new_params.relative_profile_id = -+ param->profile_select.new_params.relative_profile_id; -+ } -+ else -+ compat_param->profile_select.p_profile = -+ compat_pcd_ptr2id(param->profile_select.p_profile); -+ -+ compat_param->alg_selection = param->alg_selection; -+ compat_param->color_mode = param->color_mode; -+ -+ /* both parameters in the union has the same size, so memcpy works */ -+ memcpy(&compat_param->color, ¶m->color, sizeof(compat_param->color)); -+ -+ memcpy(&compat_param->non_passthrough_alg_param, -+ ¶m->non_passthrough_alg_param, -+ sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t)); -+ -+ compat_param->next_engine_on_green = param->next_engine_on_green; -+ compat_param->next_engine_on_yellow = param->next_engine_on_yellow; -+ compat_param->next_engine_on_red = param->next_engine_on_red; -+ -+ compat_param->trap_profile_on_flow_A = param->trap_profile_on_flow_A; -+ compat_param->trap_profile_on_flow_B = param->trap_profile_on_flow_B; -+ compat_param->trap_profile_on_flow_C = param->trap_profile_on_flow_C; -+ -+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE); -+ } -+ -+ compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_green, -+ ¶m->params_on_green, param->next_engine_on_green, compat); -+ -+ compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_yellow, -+ ¶m->params_on_yellow, param->next_engine_on_yellow, compat); -+ -+ compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_red, -+ ¶m->params_on_red, param->next_engine_on_red, compat); -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+static inline void compat_copy_fm_pcd_cc_next_kg( -+ ioc_compat_fm_pcd_cc_next_kg_params_t *compat_param, -+ ioc_fm_pcd_cc_next_kg_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->new_fqid = compat_param->new_fqid; -+ param->override_fqid = compat_param->override_fqid; -+#if DPAA_VERSION >= 11 -+ param->new_relative_storage_profile_id = compat_param->new_relative_storage_profile_id; -+#endif -+ param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme); -+ } -+ else -+ { -+ compat_param->new_fqid = param->new_fqid; -+ compat_param->override_fqid = param->override_fqid; -+#if DPAA_VERSION >= 11 -+ compat_param->new_relative_storage_profile_id = param->new_relative_storage_profile_id; -+#endif -+ compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme); -+ } -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+static inline void compat_copy_fm_pcd_cc_next_cc( -+ ioc_compat_fm_pcd_cc_next_cc_params_t *compat_param, -+ ioc_fm_pcd_cc_next_cc_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ param->cc_node_id = compat_pcd_id2ptr(compat_param->cc_node_id); -+ else -+ compat_param->cc_node_id = compat_pcd_ptr2id(param->cc_node_id); -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+static inline void compat_copy_fm_pcd_cc_next_engine( -+ ioc_compat_fm_pcd_cc_next_engine_params_t *compat_param, -+ ioc_fm_pcd_cc_next_engine_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->next_engine = compat_param->next_engine; -+ if (param->next_engine != e_IOC_FM_PCD_INVALID ) -+ _fm_cpt_dbg(compat, " param->next_engine = %i \n", param->next_engine); -+ -+ switch (param->next_engine) -+ { -+#if DPAA_VERSION >= 11 -+ case e_IOC_FM_PCD_FR: -+ param->params.fr_params.frm_replic_id = compat_pcd_id2ptr(compat_param->params.fr_params.frm_replic_id); -+ break; -+#endif /* DPAA_VERSION >= 11 */ -+ case e_IOC_FM_PCD_CC: -+ param->manip_id = compat_pcd_id2ptr(compat_param->manip_id); -+ compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, ¶m->params.cc_params, compat); -+ break; -+ case e_IOC_FM_PCD_KG: -+ param->manip_id = compat_pcd_id2ptr(compat_param->manip_id); -+ compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, ¶m->params.kg_params, compat); -+ break; -+ case e_IOC_FM_PCD_DONE: -+ case e_IOC_FM_PCD_PLCR: -+ param->manip_id = compat_pcd_id2ptr(compat_param->manip_id); -+ default: -+ memcpy(¶m->params, &compat_param->params, sizeof(param->params)); -+ } -+ param->statistics_en = compat_param->statistics_en; -+ } -+ else -+ { -+ compat_param->next_engine = param->next_engine; -+ -+ switch (compat_param->next_engine) -+ { -+#if DPAA_VERSION >= 11 -+ case e_IOC_FM_PCD_FR: -+ compat_param->params.fr_params.frm_replic_id = compat_pcd_ptr2id(param->params.fr_params.frm_replic_id); -+ break; -+#endif /* DPAA_VERSION >= 11 */ -+ case e_IOC_FM_PCD_CC: -+ compat_param->manip_id = compat_pcd_ptr2id(param->manip_id); -+ compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, ¶m->params.cc_params, compat); -+ break; -+ case e_IOC_FM_PCD_KG: -+ compat_param->manip_id = compat_pcd_ptr2id(param->manip_id); -+ compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, ¶m->params.kg_params, compat); -+ break; -+ case e_IOC_FM_PCD_DONE: -+ case e_IOC_FM_PCD_PLCR: -+ compat_param->manip_id = compat_pcd_ptr2id(param->manip_id); -+ default: -+ memcpy(&compat_param->params, ¶m->params, sizeof(compat_param->params)); -+ } -+ compat_param->statistics_en = param->statistics_en; -+ } -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+void compat_copy_fm_pcd_cc_key( -+ ioc_compat_fm_pcd_cc_key_params_t *compat_param, -+ ioc_fm_pcd_cc_key_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->p_key = compat_ptr(compat_param->p_key); -+ param->p_mask = compat_ptr(compat_param->p_mask); -+ } -+ else -+ { -+ compat_param->p_key = ptr_to_compat(param->p_key); -+ compat_param->p_mask = ptr_to_compat(param->p_mask); -+ } -+ -+ compat_copy_fm_pcd_cc_next_engine( -+ &compat_param->cc_next_engine_params, -+ ¶m->cc_next_engine_params, -+ compat); -+} -+ -+void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine( -+ ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param, -+ ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->id = compat_pcd_id2ptr(compat_param->id); -+ param->key_indx = compat_param->key_indx; -+ param->key_size = compat_param->key_size; -+ compat_copy_fm_pcd_cc_key( -+ &compat_param->key_params, -+ ¶m->key_params, -+ compat); -+ } -+ else -+ { -+ compat_param->id = compat_pcd_ptr2id(param->id); -+ compat_param->key_indx = param->key_indx; -+ compat_param->key_size = param->key_size; -+ compat_copy_fm_pcd_cc_key( -+ &compat_param->key_params, -+ ¶m->key_params, -+ compat); -+ } -+} -+ -+void compat_copy_fm_pcd_cc_node_modify_next_engine( -+ ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param, -+ ioc_fm_pcd_cc_node_modify_next_engine_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->id = compat_pcd_id2ptr(compat_param->id); -+ param->key_indx = compat_param->key_indx; -+ param->key_size = compat_param->key_size; -+ } -+ else -+ { -+ compat_param->id = compat_pcd_ptr2id(param->id); -+ compat_param->key_indx = param->key_indx; -+ compat_param->key_size = param->key_size; -+ } -+ -+ compat_copy_fm_pcd_cc_next_engine( -+ &compat_param->cc_next_engine_params, -+ ¶m->cc_next_engine_params, -+ compat); -+} -+ -+void compat_fm_pcd_cc_tree_modify_next_engine( -+ ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param, -+ ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->id = compat_pcd_id2ptr(compat_param->id); -+ param->grp_indx = compat_param->grp_indx; -+ param->indx = compat_param->indx; -+ } -+ else -+ { -+ compat_param->id = compat_pcd_ptr2id(param->id); -+ compat_param->grp_indx = param->grp_indx; -+ compat_param->indx = param->indx; -+ } -+ -+ compat_copy_fm_pcd_cc_next_engine( -+ &compat_param->cc_next_engine_params, -+ ¶m->cc_next_engine_params, -+ compat); -+} -+ -+void compat_copy_fm_pcd_hash_table( -+ ioc_compat_fm_pcd_hash_table_params_t *compat_param, -+ ioc_fm_pcd_hash_table_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->max_num_of_keys = compat_param->max_num_of_keys; -+ param->statistics_mode = compat_param->statistics_mode; -+ param->kg_hash_shift = compat_param->kg_hash_shift; -+ param->hash_res_mask = compat_param->hash_res_mask; -+ param->hash_shift = compat_param->hash_shift; -+ param->match_key_size = compat_param->match_key_size; -+ param->id = compat_pcd_id2ptr(compat_param->id); -+ } -+ else -+ { -+ compat_param->max_num_of_keys = param->max_num_of_keys; -+ compat_param->statistics_mode = param->statistics_mode; -+ compat_param->kg_hash_shift = param->kg_hash_shift; -+ compat_param->hash_res_mask = param->hash_res_mask; -+ compat_param->hash_shift = param->hash_shift; -+ compat_param->match_key_size = param->match_key_size; -+ -+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE); -+ } -+ -+ compat_copy_fm_pcd_cc_next_engine( -+ &compat_param->cc_next_engine_params_for_miss, -+ ¶m->cc_next_engine_params_for_miss, -+ compat); -+} -+ -+void compat_copy_fm_pcd_cc_grp( -+ ioc_compat_fm_pcd_cc_grp_params_t *compat_param, -+ ioc_fm_pcd_cc_grp_params_t *param, -+ uint8_t compat) -+{ -+ int k; -+ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->num_of_distinction_units = compat_param->num_of_distinction_units; -+ memcpy(param->unit_ids, compat_param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS); -+ } -+ else -+ { -+ compat_param->num_of_distinction_units = param->num_of_distinction_units; -+ memcpy(compat_param->unit_ids, param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS); -+ } -+ -+ for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP; k++) -+ compat_copy_fm_pcd_cc_next_engine( -+ &compat_param->next_engine_per_entries_in_grp[k], -+ ¶m->next_engine_per_entries_in_grp[k], -+ compat); -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+void compat_copy_fm_pcd_cc_tree( -+ ioc_compat_fm_pcd_cc_tree_params_t *compat_param, -+ ioc_fm_pcd_cc_tree_params_t *param, -+ uint8_t compat) -+{ -+ int k; -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id); -+ param->num_of_groups = compat_param->num_of_groups; -+ } -+ else -+ { -+ compat_param->net_env_id = compat_pcd_ptr2id(param->net_env_id); -+ compat_param->num_of_groups = param->num_of_groups; -+ -+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE); -+ } -+ -+ for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS; k++) -+ compat_copy_fm_pcd_cc_grp( -+ &compat_param->fm_pcd_cc_group_params[k], -+ ¶m->fm_pcd_cc_group_params[k], -+ compat); -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+void compat_fm_pcd_prs_sw( -+ ioc_compat_fm_pcd_prs_sw_params_t *compat_param, -+ ioc_fm_pcd_prs_sw_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->override = compat_param->override; -+ param->size = compat_param->size; -+ param->base = compat_param->base; -+ param->p_code = compat_ptr(compat_param->p_code); -+ memcpy(param->sw_prs_data_params,compat_param->sw_prs_data_params,IOC_FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t)); -+ param->num_of_labels = compat_param->num_of_labels; -+ memcpy(param->labels_table,compat_param->labels_table,IOC_FM_PCD_PRS_NUM_OF_LABELS*sizeof(ioc_fm_pcd_prs_label_params_t)); -+ } -+} -+ -+void compat_copy_fm_pcd_kg_scheme( -+ ioc_compat_fm_pcd_kg_scheme_params_t *compat_param, -+ ioc_fm_pcd_kg_scheme_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg(compat," {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->modify = compat_param->modify; -+ -+ /* scm_id */ -+ if (compat_param->modify) -+ { -+ param->scm_id.scheme_id = compat_pcd_id2ptr(compat_param->scm_id.scheme_id); -+ _fm_cpt_dbg(compat," param->scm_id.scheme_id = %p \n", param->scm_id.scheme_id); -+ } -+ else -+ param->scm_id.relative_scheme_id = compat_param->scm_id.relative_scheme_id; -+ -+ param->always_direct = compat_param->always_direct; -+ /* net_env_params */ -+ param->net_env_params.net_env_id = compat_pcd_id2ptr(compat_param->net_env_params.net_env_id); -+ param->net_env_params.num_of_distinction_units = compat_param->net_env_params.num_of_distinction_units; -+ memcpy(param->net_env_params.unit_ids, -+ compat_param->net_env_params.unit_ids, -+ IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); -+ -+ param->use_hash = compat_param->use_hash; -+ memcpy(¶m->key_extract_and_hash_params, -+ &compat_param->key_extract_and_hash_params, -+ sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t)); -+ param->bypass_fqid_generation = compat_param->bypass_fqid_generation; -+ param->base_fqid = compat_param->base_fqid; -+#if DPAA_VERSION >= 11 -+ param->override_storage_profile = -+ compat_param->override_storage_profile; -+ param->storage_profile = compat_param->storage_profile; -+#endif -+ param->num_of_used_extracted_ors = compat_param->num_of_used_extracted_ors; -+ memcpy(param->extracted_ors, -+ compat_param->extracted_ors, -+ IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t)); -+ param->next_engine = compat_param->next_engine; -+ -+ /* kg_next_engine_params */ -+ if (param->next_engine == e_IOC_FM_PCD_CC) -+ { -+ param->kg_next_engine_params.cc.tree_id = compat_pcd_id2ptr(compat_param->kg_next_engine_params.cc.tree_id); -+ param->kg_next_engine_params.cc.grp_id = compat_param->kg_next_engine_params.cc.grp_id; -+ param->kg_next_engine_params.cc.plcr_next = compat_param->kg_next_engine_params.cc.plcr_next; -+ param->kg_next_engine_params.cc.bypass_plcr_profile_generation -+ = compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation; -+ memcpy(¶m->kg_next_engine_params.cc.plcr_profile, -+ &compat_param->kg_next_engine_params.cc.plcr_profile, -+ sizeof(ioc_fm_pcd_kg_plcr_profile_t)); -+ } -+ else -+ memcpy(¶m->kg_next_engine_params, -+ &compat_param->kg_next_engine_params, -+ sizeof(param->kg_next_engine_params)); -+ -+ memcpy(¶m->scheme_counter, -+ &compat_param->scheme_counter, -+ sizeof(ioc_fm_pcd_kg_scheme_counter_t)); -+ } -+ else -+ { -+ compat_param->modify = param->modify; -+ -+ /* scm_id */ -+ if (param->modify) -+ compat_param->scm_id.scheme_id = compat_pcd_ptr2id(param->scm_id.scheme_id); -+ else -+ compat_param->scm_id.relative_scheme_id = param->scm_id.relative_scheme_id; -+ -+ compat_param->always_direct = param->always_direct; -+ -+ /* net_env_params */ -+ compat_param->net_env_params.net_env_id = compat_pcd_ptr2id(param->net_env_params.net_env_id); -+ compat_param->net_env_params.num_of_distinction_units = param->net_env_params.num_of_distinction_units; -+ memcpy(compat_param->net_env_params.unit_ids, param->net_env_params.unit_ids, IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); -+ -+ compat_param->use_hash = param->use_hash; -+ memcpy(&compat_param->key_extract_and_hash_params, ¶m->key_extract_and_hash_params, sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t)); -+ compat_param->bypass_fqid_generation = param->bypass_fqid_generation; -+ compat_param->base_fqid = param->base_fqid; -+#if DPAA_VERSION >= 11 -+ compat_param->override_storage_profile = -+ param->override_storage_profile; -+ compat_param->storage_profile = param->storage_profile; -+#endif -+ compat_param->num_of_used_extracted_ors = param->num_of_used_extracted_ors; -+ memcpy(compat_param->extracted_ors, param->extracted_ors, IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t)); -+ compat_param->next_engine = param->next_engine; -+ -+ /* kg_next_engine_params */ -+ if (compat_param->next_engine == e_IOC_FM_PCD_CC) -+ { -+ compat_param->kg_next_engine_params.cc.tree_id = compat_pcd_ptr2id(param->kg_next_engine_params.cc.tree_id); -+ compat_param->kg_next_engine_params.cc.grp_id = param->kg_next_engine_params.cc.grp_id; -+ compat_param->kg_next_engine_params.cc.plcr_next = param->kg_next_engine_params.cc.plcr_next; -+ compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation -+ = param->kg_next_engine_params.cc.bypass_plcr_profile_generation; -+ memcpy(&compat_param->kg_next_engine_params.cc.plcr_profile, -+ ¶m->kg_next_engine_params.cc.plcr_profile, -+ sizeof(ioc_fm_pcd_kg_plcr_profile_t)); -+ } -+ else -+ memcpy(¶m->kg_next_engine_params, &compat_param->kg_next_engine_params, sizeof(compat_param->kg_next_engine_params)); -+ -+ memcpy(&compat_param->scheme_counter, ¶m->scheme_counter, sizeof(ioc_fm_pcd_kg_scheme_counter_t)); -+ -+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE); -+ } -+ -+ _fm_cpt_dbg(compat," ...->}\n"); -+} -+ -+void compat_copy_fm_pcd_kg_scheme_spc( -+ ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param, -+ ioc_fm_pcd_kg_scheme_spc_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->id = compat_pcd_id2ptr(compat_param->id); -+ param->val = compat_param->val; -+ } else { -+ compat_param->id = compat_pcd_ptr2id(param->id); -+ compat_param->val = param->val; -+ } -+} -+ -+ -+void compat_copy_fm_pcd_kg_scheme_select( -+ ioc_compat_fm_pcd_kg_scheme_select_t *compat_param, -+ ioc_fm_pcd_kg_scheme_select_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->direct = compat_param->direct; -+ if (param->direct) -+ param->scheme_id = compat_pcd_id2ptr(compat_param->scheme_id); -+ } -+} -+ -+void compat_copy_fm_pcd_kg_schemes_params( -+ ioc_compat_fm_pcd_port_schemes_params_t *compat_param, -+ ioc_fm_pcd_port_schemes_params_t *param, -+ uint8_t compat) -+{ -+ int k; -+ -+ if (compat == COMPAT_US_TO_K) { -+ param->num_of_schemes = compat_param->num_of_schemes; -+ for(k=0; k < compat_param->num_of_schemes; k++) -+ param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]); -+ } -+} -+ -+void compat_copy_fm_port_pcd_cc( -+ ioc_compat_fm_port_pcd_cc_params_t *compat_cc_params , -+ ioc_fm_port_pcd_cc_params_t *p_cc_params, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K){ -+ p_cc_params->cc_tree_id = compat_pcd_id2ptr(compat_cc_params->cc_tree_id); -+ } -+} -+ -+void compat_copy_fm_port_pcd_kg( -+ ioc_compat_fm_port_pcd_kg_params_t *compat_param, -+ ioc_fm_port_pcd_kg_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K){ -+ uint8_t k; -+ -+ param->num_of_schemes = compat_param->num_of_schemes; -+ for(k=0; knum_of_schemes; k++) -+ param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]); -+ -+ param->direct_scheme = compat_param->direct_scheme; -+ if (param->direct_scheme) -+ param->direct_scheme_id = compat_pcd_id2ptr(compat_param->direct_scheme_id); -+ } -+} -+ -+void compat_copy_fm_port_pcd( -+ ioc_compat_fm_port_pcd_params_t *compat_param, -+ ioc_fm_port_pcd_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params; -+ ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params; -+ ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params; -+ ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params; -+ -+ same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_param + 1); -+ compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1); -+ compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1); -+ compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1); -+ -+ _fm_cpt_dbg(compat,"\n param->p_prs_params=%p \n", param->p_prs_params); -+ _fm_cpt_dbg(compat," param->p_cc_params=%p \n", param->p_cc_params); -+ _fm_cpt_dbg(compat," param->p_kg_params=%p \n", param->p_kg_params); -+ _fm_cpt_dbg(compat," param->p_plcr_params=%p \n", param->p_plcr_params); -+ _fm_cpt_dbg(compat," param->p_ip_reassembly_manip=%p \n", param->p_ip_reassembly_manip); -+#if (DPAA_VERSION >= 11) -+ _fm_cpt_dbg(compat," param->p_capwap_reassembly_manip=%p \n", param->p_capwap_reassembly_manip); -+#endif -+ param->pcd_support = compat_param->pcd_support; -+ param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id); -+ -+ if (param->p_cc_params) -+ compat_copy_fm_port_pcd_cc(compat_port_pcd_cc_params, param->p_cc_params, COMPAT_US_TO_K); -+ if (param->p_kg_params) -+ compat_copy_fm_port_pcd_kg(compat_port_pcd_kg_params, param->p_kg_params, COMPAT_US_TO_K); -+ if (param->p_plcr_params) -+ param->p_plcr_params->plcr_profile_id = compat_pcd_id2ptr(compat_port_pcd_plcr_params->plcr_profile_id); -+ param->p_ip_reassembly_manip = compat_pcd_id2ptr(compat_param->p_ip_reassembly_manip); -+#if (DPAA_VERSION >= 11) -+ param->p_capwap_reassembly_manip = compat_pcd_id2ptr(compat_param->p_capwap_reassembly_manip); -+#endif -+ } -+} -+ -+void compat_copy_fm_port_pcd_modify_tree( -+ ioc_compat_fm_obj_t *compat_id, -+ ioc_fm_obj_t *id, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ id->obj = compat_pcd_id2ptr(compat_id->obj); -+} -+ -+#if (DPAA_VERSION >= 11) -+void compat_copy_fm_port_vsp_alloc_params( -+ ioc_compat_fm_port_vsp_alloc_params_t *compat_param, -+ ioc_fm_port_vsp_alloc_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ _fm_cpt_dbg(compat," param->p_fm_tx_port=%p \n", param->p_fm_tx_port); -+ -+ param->dflt_relative_id = compat_param->dflt_relative_id; -+ param->num_of_profiles = compat_param->num_of_profiles; -+ param->p_fm_tx_port = compat_pcd_id2ptr(compat_param->p_fm_tx_port); -+ } -+} -+#endif /* (DPAA_VERSION >= 11) */ -+ -+void compat_copy_fm_pcd_cc_tbl_get_stats( -+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param, -+ ioc_fm_pcd_cc_tbl_get_stats_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->id = compat_pcd_id2ptr(compat_param->id); -+ param->key_index = compat_param->key_index; -+ memcpy(¶m->statistics, &compat_param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t)); -+ } else { -+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE); -+ compat_param->key_index = param->key_index; -+ memcpy(&compat_param->statistics, ¶m->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t)); -+ } -+} -+ -+ -+void compat_copy_fm_pcd_net_env( -+ ioc_compat_fm_pcd_net_env_params_t *compat_param, -+ ioc_fm_pcd_net_env_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->num_of_distinction_units = compat_param->num_of_distinction_units; -+ memcpy(param->units, compat_param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); -+ param->id = NULL; /* to avoid passing garbage to the kernel */ -+ } -+ else -+ { -+ compat_param->num_of_distinction_units = param->num_of_distinction_units; -+ memcpy(compat_param->units, param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS); -+ -+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE); -+ } -+} -+ -+void compat_copy_fm_pcd_cc_node_modify_key( -+ ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param, -+ ioc_fm_pcd_cc_node_modify_key_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->key_indx = compat_param->key_indx; -+ param->key_size = compat_param->key_size; -+ param->p_key = (uint8_t *)compat_ptr(compat_param->p_key); -+ _fm_cpt_dbg(compat," param->p_key = %p \n", param->p_key); -+ param->p_mask = (uint8_t *)compat_ptr(compat_param->p_mask); -+ _fm_cpt_dbg(compat," param->p_mask = %p\n", param->p_mask); -+ param->id = compat_pcd_id2ptr(compat_param->id); -+ _fm_cpt_dbg(compat," param->id = %p \n", param->id); -+ } -+ else -+ { -+ compat_param->key_indx = param->key_indx; -+ compat_param->key_size = param->key_size; -+ compat_param->p_key = ptr_to_compat((void *)param->p_key); -+ compat_param->p_mask = ptr_to_compat((void *)param->p_mask); -+ -+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE); -+ } -+} -+ -+void compat_copy_keys( -+ ioc_compat_keys_params_t *compat_param, -+ ioc_keys_params_t *param, -+ uint8_t compat) -+{ -+ int k = 0; -+ -+ _fm_cpt_dbg(compat," {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) { -+ param->max_num_of_keys = compat_param->max_num_of_keys; -+ param->mask_support = compat_param->mask_support; -+ param->statistics_mode = compat_param->statistics_mode; -+ param->num_of_keys = compat_param->num_of_keys; -+ param->key_size = compat_param->key_size; -+#if (DPAA_VERSION >= 11) -+ memcpy(¶m->frame_length_ranges, -+ &compat_param->frame_length_ranges, -+ sizeof(param->frame_length_ranges[0]) * -+ IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR); -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ else { -+ compat_param->max_num_of_keys = param->max_num_of_keys; -+ compat_param->mask_support = param->mask_support; -+ compat_param->statistics_mode = param->statistics_mode; -+ compat_param->num_of_keys = param->num_of_keys; -+ compat_param->key_size = param->key_size; -+#if (DPAA_VERSION >= 11) -+ memcpy(&compat_param->frame_length_ranges, -+ ¶m->frame_length_ranges, -+ sizeof(compat_param->frame_length_ranges[0]) * -+ IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR); -+#endif /* (DPAA_VERSION >= 11) */ -+ } -+ -+ for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_KEYS; k++) -+ compat_copy_fm_pcd_cc_key( -+ &compat_param->key_params[k], -+ ¶m->key_params[k], -+ compat); -+ -+ compat_copy_fm_pcd_cc_next_engine( -+ &compat_param->cc_next_engine_params_for_miss, -+ ¶m->cc_next_engine_params_for_miss, -+ compat); -+ -+ _fm_cpt_dbg(compat," ...->}\n"); -+} -+ -+void compat_copy_fm_pcd_cc_node( -+ ioc_compat_fm_pcd_cc_node_params_t *compat_param, -+ ioc_fm_pcd_cc_node_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg(compat," {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ memcpy(¶m->extract_cc_params, &compat_param->extract_cc_params, sizeof(ioc_fm_pcd_extract_entry_t)); -+ -+ else -+ { -+ compat_copy_keys(&compat_param->keys_params, ¶m->keys_params, compat); -+ -+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE); -+ _fm_cpt_dbg(compat," param->id = %p \n", param->id); -+ } -+ -+ compat_copy_keys(&compat_param->keys_params, ¶m->keys_params, compat); -+ -+ _fm_cpt_dbg(compat," ...->}\n"); -+} -+ -+void compat_fm_pcd_manip_set_node( -+ ioc_compat_fm_pcd_manip_params_t *compat_param, -+ ioc_fm_pcd_manip_params_t *param, -+ uint8_t compat) -+{ -+ if (compat == COMPAT_US_TO_K) { -+ param->type = compat_param->type; -+ switch (param->type) { -+ case e_IOC_FM_PCD_MANIP_HDR: -+ param->u.hdr.rmv = compat_param->u.hdr.rmv; -+ memcpy(¶m->u.hdr.rmv_params, -+ &compat_param->u.hdr.rmv_params, -+ sizeof(param->u.hdr.rmv_params)); -+ -+ param->u.hdr.insrt = compat_param->u.hdr.insrt; -+ param->u.hdr.insrt_params.type = -+ compat_param->u.hdr.insrt_params.type; -+ switch (compat_param->u.hdr.insrt_params.type) -+ { -+ case e_IOC_FM_PCD_MANIP_INSRT_GENERIC: -+ param->u.hdr.insrt_params.u.generic.offset = -+ compat_param->u.hdr.insrt_params.u.generic.offset; -+ param->u.hdr.insrt_params.u.generic.size = -+ compat_param->u.hdr.insrt_params.u.generic.size; -+ param->u.hdr.insrt_params.u.generic.replace = -+ compat_param->u.hdr.insrt_params.u.generic.replace; -+ param->u.hdr.insrt_params.u.generic.p_data = -+ compat_ptr(compat_param->u.hdr.insrt_params.u.generic.p_data); -+ break; -+ case e_IOC_FM_PCD_MANIP_INSRT_BY_HDR: -+ param->u.hdr.insrt_params.u.by_hdr.type = -+ compat_param->u.hdr.insrt_params.u.by_hdr.type; -+ param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2 = -+ compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2; -+ param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update = -+ compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update; -+ param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size = -+ compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size; -+ param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data = -+ compat_ptr(compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data); -+ break; -+ default: -+ _fm_cpt_err("Unsupported type: %d", compat_param->u.hdr.insrt_params.type); -+ } -+ -+ param->u.hdr.field_update = compat_param->u.hdr.field_update; -+ memcpy(¶m->u.hdr.field_update_params, -+ &compat_param->u.hdr.field_update_params, -+ sizeof(param->u.hdr.field_update_params)); -+ -+ param->u.hdr.custom = compat_param->u.hdr.custom; -+ memcpy(¶m->u.hdr.custom_params, -+ &compat_param->u.hdr.custom_params, -+ sizeof(param->u.hdr.custom_params)); -+ -+ param->u.hdr.dont_parse_after_manip = -+ compat_param->u.hdr.dont_parse_after_manip; -+ break; -+ case e_IOC_FM_PCD_MANIP_REASSEM: -+ memcpy(¶m->u.reassem, &compat_param->u.reassem, sizeof(param->u.reassem)); -+ break; -+ case e_IOC_FM_PCD_MANIP_FRAG: -+ memcpy(¶m->u.frag, &compat_param->u.frag, sizeof(param->u.frag)); -+ break; -+ case e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD: -+ memcpy(¶m->u.special_offload, -+ &compat_param->u.special_offload, -+ sizeof(param->u.special_offload)); -+ break; -+ } -+ -+ param->p_next_manip = compat_pcd_id2ptr(compat_param->p_next_manip); -+ param->id = compat_pcd_id2ptr(compat_param->id); -+ } -+ else { -+ compat_param->type = param->type; -+ memcpy(&compat_param->u, ¶m->u, sizeof(compat_param->u)); -+ -+ if (param->type == e_IOC_FM_PCD_MANIP_HDR && -+ param->u.hdr.insrt_params.type == e_IOC_FM_PCD_MANIP_INSRT_GENERIC) -+ compat_param->u.hdr.insrt_params.u.generic.p_data = -+ ptr_to_compat(param->u.hdr.insrt_params.u.generic.p_data); -+ -+ compat_param->p_next_manip = compat_pcd_ptr2id(param->id); -+ /* ... should be one that was added previously by the very call to -+ compat_add_ptr2id() below: */ -+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE); -+ } -+} -+ -+void compat_copy_fm_pcd_manip_get_stats( -+ ioc_compat_fm_pcd_manip_get_stats_t *compat_param, -+ ioc_fm_pcd_manip_get_stats_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->id = compat_pcd_id2ptr(compat_param->id); -+ memcpy(¶m->stats, &compat_param->stats, -+ sizeof(ioc_fm_pcd_manip_stats_t)); -+ } -+ else -+ { -+ compat_param->id = compat_add_ptr2id(param->id, -+ FM_MAP_TYPE_PCD_NODE); -+ memcpy(&compat_param->stats, ¶m->stats, -+ sizeof(ioc_fm_pcd_manip_stats_t)); -+ } -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+#if (DPAA_VERSION >= 11) -+void compat_copy_fm_pcd_frm_replic_group_params( -+ ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param, -+ ioc_fm_pcd_frm_replic_group_params_t *param, -+ uint8_t compat) -+{ -+ int k; -+ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->max_num_of_entries = compat_param->max_num_of_entries; -+ param->num_of_entries = compat_param->num_of_entries; -+ param->id = compat_pcd_id2ptr(compat_param->id); -+ } -+ else -+ { -+ compat_param->max_num_of_entries = param->max_num_of_entries; -+ compat_param->num_of_entries = param->num_of_entries; -+ compat_param->id = compat_add_ptr2id(param->id, -+ FM_MAP_TYPE_PCD_NODE); -+ } -+ -+ for (k=0; k < IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES; k++) -+ compat_copy_fm_pcd_cc_next_engine( -+ &compat_param->next_engine_params[k], -+ ¶m->next_engine_params[k], -+ compat); -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+void compat_copy_fm_pcd_frm_replic_member( -+ ioc_compat_fm_pcd_frm_replic_member_t *compat_param, -+ ioc_fm_pcd_frm_replic_member_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->h_replic_group = compat_pcd_id2ptr(compat_param->h_replic_group); -+ param->member_index = compat_param->member_index; -+ } -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+void compat_copy_fm_pcd_frm_replic_member_params( -+ ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param, -+ ioc_fm_pcd_frm_replic_member_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ compat_copy_fm_pcd_frm_replic_member(&compat_param->member, -+ ¶m->member, compat); -+ -+ compat_copy_fm_pcd_cc_next_engine(&compat_param->next_engine_params, -+ ¶m->next_engine_params, compat); -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+void compat_copy_fm_vsp_params( -+ ioc_compat_fm_vsp_params_t *compat_param, -+ ioc_fm_vsp_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ memcpy(¶m->ext_buf_pools, &compat_param->ext_buf_pools, sizeof(ioc_fm_ext_pools)); -+ param->liodn_offset = compat_param->liodn_offset; -+ param->port_params.port_id = compat_param->port_params.port_id; -+ param->port_params.port_type = compat_param->port_params.port_type; -+ param->relative_profile_id = compat_param->relative_profile_id; -+ } -+ else -+ { -+ memcpy(&compat_param->ext_buf_pools, ¶m->ext_buf_pools, sizeof(ioc_fm_ext_pools)); -+ compat_param->liodn_offset = param->liodn_offset; -+ compat_param->port_params.port_id = param->port_params.port_id; -+ compat_param->port_params.port_type = param->port_params.port_type; -+ compat_param->relative_profile_id = param->relative_profile_id; -+ compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE); -+ } -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+void compat_copy_fm_buf_pool_depletion_params( -+ ioc_compat_fm_buf_pool_depletion_params_t *compat_param, -+ ioc_fm_buf_pool_depletion_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp); -+ memcpy(¶m->fm_buf_pool_depletion, -+ &compat_param->fm_buf_pool_depletion, -+ sizeof(ioc_fm_buf_pool_depletion_t)); -+ } -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+void compat_copy_fm_buffer_prefix_content_params( -+ ioc_compat_fm_buffer_prefix_content_params_t *compat_param, -+ ioc_fm_buffer_prefix_content_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp); -+ memcpy(¶m->fm_buffer_prefix_content, -+ &compat_param->fm_buffer_prefix_content, -+ sizeof(ioc_fm_buffer_prefix_content_t)); -+ } -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+void compat_copy_fm_vsp_config_no_sg_params( -+ ioc_compat_fm_vsp_config_no_sg_params_t *compat_param, -+ ioc_fm_vsp_config_no_sg_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp); -+ param->no_sg = compat_param->no_sg; -+ } -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+ -+void compat_copy_fm_vsp_prs_result_params( -+ ioc_compat_fm_vsp_prs_result_params_t *compat_param, -+ ioc_fm_vsp_prs_result_params_t *param, -+ uint8_t compat) -+{ -+ _fm_cpt_dbg (compat, " {->...\n"); -+ -+ if (compat == COMPAT_US_TO_K) -+ { -+ param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp); -+ /* p_data is an user-space pointer that needs to remain unmodified */ -+ param->p_data = (void *)(unsigned long long)compat_param->p_data; -+ } -+ else -+ { -+ compat_param->p_fm_vsp = compat_pcd_ptr2id(param->p_fm_vsp); -+ /* p_data is an user-space pointer that needs to remain unmodified */ -+ compat_param->p_data = (compat_uptr_t)((unsigned long long)param->p_data & 0xFFFFFFFF); -+ } -+ -+ _fm_cpt_dbg (compat, " ...->}\n"); -+} -+#endif /* (DPAA_VERSION >= 11) */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h -@@ -0,0 +1,755 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ @File lnxwrp_ioctls_fm_compat.h -+ -+ @Description FM PCD compat structures definition. -+ -+*/ -+ -+#ifndef __FM_COMPAT_IOCTLS_H -+#define __FM_COMPAT_IOCTLS_H -+ -+#include -+ -+#define COMPAT_K_TO_US 0 /* copy from Kernel to User */ -+#define COMPAT_US_TO_K 1 /* copy from User to Kernel */ -+#define COMPAT_GENERIC 2 -+ -+#define COMPAT_COPY_K2US(dest, src, type) compat_copy_##type(src, dest, 0) -+#define COMPAT_COPY_US2K(dest, src, type) compat_copy_##type(dest, src, 1) -+ -+/* mapping kernel pointers w/ UserSpace id's { */ -+/* Because compat_ptr(ptr_to_compat(X)) != X, this way we cannot exchange pointers -+ back and forth (US - KS). compat_ptr is a cast and pointers are broken. */ -+#define COMPAT_PTR2ID_ARRAY_MAX (512+1) /* first location is not used */ -+#define COMPAT_PTR2ID_WATERMARK 0xface0000 -+#define COMPAT_PTR2ID_WM_MASK 0xffff0000 -+ -+/* define it for debug trace */ -+/*#define FM_COMPAT_DBG*/ -+ -+#define _fm_cpt_prk(stage, format, arg...) \ -+ printk(stage "fm_cpt (cpu:%u): " format, raw_smp_processor_id(), ##arg) -+ -+#define _fm_cpt_inf(format, arg...) _fm_cpt_prk(KERN_INFO, format, ##arg) -+#define _fm_cpt_wrn(format, arg...) _fm_cpt_prk(KERN_WARNING, format, ##arg) -+#define _fm_cpt_err(format, arg...) _fm_cpt_prk(KERN_ERR, format, ##arg) -+ -+/* used for compat IOCTL debugging */ -+#if defined(FM_COMPAT_DBG) -+ #define _fm_cpt_dbg(from, format, arg...) \ -+ do{ \ -+ if (from == COMPAT_US_TO_K) \ -+ printk("fm_cpt to KS [%s:%u](cpu:%u) - " format, \ -+ __func__, __LINE__, raw_smp_processor_id(), ##arg); \ -+ else if (from == COMPAT_K_TO_US) \ -+ printk("fm_cpt to US [%s:%u](cpu:%u) - " format, \ -+ __func__, __LINE__, raw_smp_processor_id(), ##arg); \ -+ else \ -+ printk("fm_cpt [%s:%u](cpu:%u) - " format, \ -+ __func__, __LINE__, raw_smp_processor_id(), ##arg); \ -+ }while(0) -+#else -+# define _fm_cpt_dbg(arg...) -+#endif -+ -+/*TODO: per FMan module: -+ * -+ * Parser: FM_MAP_TYPE_PARSER_NODE, -+ * Kg: FM_MAP_TYPE_KG_NODE, -+ * Policer: FM_MAP_TYPE_POLICER_NODE -+ * Manip: FM_MAP_TYPE_MANIP_NODE -+ **/ -+enum fm_map_node_type { -+ FM_MAP_TYPE_UNSPEC = 0, -+ FM_MAP_TYPE_PCD_NODE, -+ -+ /* add types here, update the policy */ -+ -+ __FM_MAP_TYPE_AFTER_LAST, -+ FM_MAP_TYPE_MAX = __FM_MAP_TYPE_AFTER_LAST - 1 -+}; -+ -+void compat_del_ptr2id(void *p, enum fm_map_node_type); -+compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type); -+compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type); -+void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type); -+ -+static inline compat_uptr_t compat_pcd_ptr2id(void *ptr) { -+ return (ptr)? compat_get_ptr2id(ptr, FM_MAP_TYPE_PCD_NODE) -+ : (compat_uptr_t) 0; -+} -+ -+static inline void *compat_pcd_id2ptr(compat_uptr_t id) { -+ return (id) ? compat_get_id2ptr(id, FM_MAP_TYPE_PCD_NODE) -+ : NULL; -+} -+ -+/* other similar inlines may be added as new nodes are added -+ to enum fm_map_node_type above... */ -+/* } mapping kernel pointers w/ UserSpace id's */ -+ -+/* pcd compat structures { */ -+typedef struct ioc_compat_fm_pcd_cc_node_remove_key_params_t { -+ compat_uptr_t id; -+ uint16_t key_indx; -+} ioc_compat_fm_pcd_cc_node_remove_key_params_t; -+ -+typedef union ioc_compat_fm_pcd_plcr_next_engine_params_u { -+ ioc_fm_pcd_done_action action; -+ compat_uptr_t p_profile; -+ compat_uptr_t p_direct_scheme; -+} ioc_compat_fm_pcd_plcr_next_engine_params_u; -+ -+typedef struct ioc_compat_fm_pcd_plcr_profile_params_t { -+ bool modify; -+ union { -+ struct { -+ ioc_fm_pcd_profile_type_selection profile_type; -+ compat_uptr_t p_fm_port; -+ uint16_t relative_profile_id; -+ } new_params; -+ compat_uptr_t p_profile; -+ } profile_select; -+ ioc_fm_pcd_plcr_algorithm_selection alg_selection; -+ ioc_fm_pcd_plcr_color_mode color_mode; -+ -+ union { -+ ioc_fm_pcd_plcr_color dflt_color; -+ ioc_fm_pcd_plcr_color override; -+ } color; -+ -+ ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param; -+ -+ ioc_fm_pcd_engine next_engine_on_green; -+ ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_green; -+ -+ ioc_fm_pcd_engine next_engine_on_yellow; -+ ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_yellow; -+ -+ ioc_fm_pcd_engine next_engine_on_red; -+ ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_red; -+ -+ bool trap_profile_on_flow_A; -+ bool trap_profile_on_flow_B; -+ bool trap_profile_on_flow_C; -+ compat_uptr_t id; -+} ioc_compat_fm_pcd_plcr_profile_params_t; -+ -+typedef struct ioc_compat_fm_obj_t { -+ compat_uptr_t obj; -+} ioc_compat_fm_obj_t; -+ -+typedef struct ioc_compat_fm_pcd_kg_scheme_select_t { -+ bool direct; -+ compat_uptr_t scheme_id; -+} ioc_compat_fm_pcd_kg_scheme_select_t; -+ -+typedef struct ioc_compat_fm_pcd_port_schemes_params_t { -+ uint8_t num_of_schemes; -+ compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; -+} ioc_compat_fm_pcd_port_schemes_params_t; -+ -+#if (DPAA_VERSION >= 11) -+typedef struct ioc_compat_fm_port_vsp_alloc_params_t { -+ uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */ -+ uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port -+ The same default Virtual-Storage-Profile-id will be for coupled Tx port -+ if relevant function called for Rx port */ -+ compat_uptr_t p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */ -+}ioc_compat_fm_port_vsp_alloc_params_t; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+typedef struct ioc_compat_fm_pcd_net_env_params_t { -+ uint8_t num_of_distinction_units; -+ ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* same structure*/ -+ compat_uptr_t id; -+} ioc_compat_fm_pcd_net_env_params_t; -+ -+typedef struct ioc_compat_fm_pcd_prs_sw_params_t { -+ bool override; -+ uint32_t size; -+ uint16_t base; -+ compat_uptr_t p_code; -+ uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS]; -+ uint8_t num_of_labels; -+ ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS]; -+} ioc_compat_fm_pcd_prs_sw_params_t; -+ -+typedef struct ioc_compat_fm_pcd_cc_next_kg_params_t { -+ bool override_fqid; -+ uint32_t new_fqid; -+#if DPAA_VERSION >= 11 -+ uint8_t new_relative_storage_profile_id; -+#endif -+ compat_uptr_t p_direct_scheme; -+} ioc_compat_fm_pcd_cc_next_kg_params_t; -+ -+typedef struct ioc_compat_fm_pcd_cc_next_cc_params_t { -+ compat_uptr_t cc_node_id; -+} ioc_compat_fm_pcd_cc_next_cc_params_t; -+ -+#if DPAA_VERSION >= 11 -+typedef struct ioc_compat_fm_pcd_cc_next_fr_params_t { -+ compat_uptr_t frm_replic_id; -+} ioc_compat_fm_pcd_cc_next_fr_params_t; -+#endif /* DPAA_VERSION >= 11 */ -+ -+typedef struct ioc_compat_fm_pcd_cc_next_engine_params_t { -+ ioc_fm_pcd_engine next_engine; -+ union { -+ ioc_compat_fm_pcd_cc_next_cc_params_t cc_params; /**< compat structure*/ -+ ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< same structure*/ -+ ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< same structure*/ -+ ioc_compat_fm_pcd_cc_next_kg_params_t kg_params; /**< compat structure*/ -+#if DPAA_VERSION >= 11 -+ ioc_compat_fm_pcd_cc_next_fr_params_t fr_params; /**< compat structure*/ -+#endif /* DPAA_VERSION >= 11 */ -+ } params; -+ compat_uptr_t manip_id; -+ bool statistics_en; -+} ioc_compat_fm_pcd_cc_next_engine_params_t; -+ -+typedef struct ioc_compat_fm_pcd_cc_grp_params_t { -+ uint8_t num_of_distinction_units; -+ uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS]; -+ ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP]; -+} ioc_compat_fm_pcd_cc_grp_params_t; -+ -+typedef struct ioc_compat_fm_pcd_cc_tree_params_t { -+ compat_uptr_t net_env_id; -+ uint8_t num_of_groups; -+ ioc_compat_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS]; -+ compat_uptr_t id; -+} ioc_compat_fm_pcd_cc_tree_params_t; -+ -+typedef struct ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t { -+ compat_uptr_t id; -+ uint8_t grp_indx; -+ uint8_t indx; -+ ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; -+} ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t; -+ -+typedef struct ioc_compat_fm_pcd_cc_key_params_t { -+ compat_uptr_t p_key; -+ compat_uptr_t p_mask; -+ ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; /**< compat structure*/ -+} ioc_compat_fm_pcd_cc_key_params_t; -+ -+typedef struct ioc_compat_keys_params_t { -+ uint16_t max_num_of_keys; -+ bool mask_support; -+ ioc_fm_pcd_cc_stats_mode statistics_mode; -+#if (DPAA_VERSION >= 11) -+ uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR]; -+#endif /* (DPAA_VERSION >= 11) */ -+ uint16_t num_of_keys; -+ uint8_t key_size; -+ ioc_compat_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; /**< compat structure*/ -+ ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; /**< compat structure*/ -+} ioc_compat_keys_params_t; -+ -+typedef struct ioc_compat_fm_pcd_cc_node_params_t { -+ ioc_fm_pcd_extract_entry_t extract_cc_params; /**< same structure*/ -+ ioc_compat_keys_params_t keys_params; /**< compat structure*/ -+ compat_uptr_t id; -+} ioc_compat_fm_pcd_cc_node_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a hash table -+*//***************************************************************************/ -+typedef struct ioc_compat_fm_pcd_hash_table_params_t { -+ uint16_t max_num_of_keys; -+ ioc_fm_pcd_cc_stats_mode statistics_mode; -+ uint8_t kg_hash_shift; -+ uint16_t hash_res_mask; -+ uint8_t hash_shift; -+ uint8_t match_key_size; -+ ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; -+ compat_uptr_t id; -+} ioc_compat_fm_pcd_hash_table_params_t; -+ -+typedef struct ioc_compat_fm_pcd_hash_table_add_key_params_t { -+ compat_uptr_t p_hash_tbl; -+ uint8_t key_size; -+ ioc_compat_fm_pcd_cc_key_params_t key_params; -+} ioc_compat_fm_pcd_hash_table_add_key_params_t; -+ -+typedef struct ioc_compat_fm_pcd_cc_node_modify_key_params_t { -+ compat_uptr_t id; -+ uint16_t key_indx; -+ uint8_t key_size; -+ compat_uptr_t p_key; -+ compat_uptr_t p_mask; -+} ioc_compat_fm_pcd_cc_node_modify_key_params_t; -+ -+typedef struct ioc_compat_fm_pcd_hash_table_remove_key_params_t { -+ compat_uptr_t p_hash_tbl; -+ uint8_t key_size; -+ compat_uptr_t p_key; -+} ioc_compat_fm_pcd_hash_table_remove_key_params_t; -+ -+typedef struct ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t { -+ compat_uptr_t id; -+ uint16_t key_indx; -+ uint8_t key_size; -+ ioc_compat_fm_pcd_cc_key_params_t key_params; -+} ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t; -+ -+typedef struct ioc_compat_fm_port_pcd_plcr_params_t { -+ compat_uptr_t plcr_profile_id; -+} ioc_compat_fm_port_pcd_plcr_params_t; -+ -+typedef struct ioc_compat_fm_port_pcd_cc_params_t { -+ compat_uptr_t cc_tree_id; -+} ioc_compat_fm_port_pcd_cc_params_t; -+ -+typedef struct ioc_compat_fm_port_pcd_kg_params_t { -+ uint8_t num_of_schemes; -+ compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; -+ bool direct_scheme; -+ compat_uptr_t direct_scheme_id; -+} ioc_compat_fm_port_pcd_kg_params_t; -+ -+typedef struct ioc_compat_fm_port_pcd_params_t { -+ ioc_fm_port_pcd_support pcd_support; -+ compat_uptr_t net_env_id; -+ compat_uptr_t p_prs_params; -+ compat_uptr_t p_cc_params; -+ compat_uptr_t p_kg_params; -+ compat_uptr_t p_plcr_params; -+ compat_uptr_t p_ip_reassembly_manip; -+#if DPAA_VERSION >= 11 -+ compat_uptr_t p_capwap_reassembly_manip; -+#endif -+} ioc_compat_fm_port_pcd_params_t; -+ -+typedef struct ioc_compat_fm_pcd_kg_cc_t { -+ compat_uptr_t tree_id; -+ uint8_t grp_id; -+ bool plcr_next; -+ bool bypass_plcr_profile_generation; -+ ioc_fm_pcd_kg_plcr_profile_t plcr_profile; -+} ioc_compat_fm_pcd_kg_cc_t; -+ -+typedef struct ioc_compat_fm_pcd_kg_scheme_params_t { -+ bool modify; -+ union { -+ uint8_t relative_scheme_id; -+ compat_uptr_t scheme_id; -+ } scm_id; -+ bool always_direct; -+ struct { -+ compat_uptr_t net_env_id; -+ uint8_t num_of_distinction_units; -+ uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; -+ } net_env_params; -+ bool use_hash; -+ ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params; -+ bool bypass_fqid_generation; -+ uint32_t base_fqid; -+ uint8_t num_of_used_extracted_ors; -+ ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS]; -+#if DPAA_VERSION >= 11 -+ bool override_storage_profile; -+ ioc_fm_pcd_kg_storage_profile_t storage_profile; -+#endif /* DPAA_VERSION >= 11 */ -+ ioc_fm_pcd_engine next_engine; -+ union{ -+ ioc_fm_pcd_done_action done_action; -+ ioc_fm_pcd_kg_plcr_profile_t plcr_profile; -+ ioc_compat_fm_pcd_kg_cc_t cc; -+ } kg_next_engine_params; -+ ioc_fm_pcd_kg_scheme_counter_t scheme_counter; -+ compat_uptr_t id; -+} ioc_compat_fm_pcd_kg_scheme_params_t; -+ -+typedef struct ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t { -+ compat_uptr_t id; -+ uint16_t key_indx; -+ uint8_t key_size; -+ ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; -+} ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t; -+ -+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t { -+ uint8_t offset; -+ uint8_t size; -+ bool replace; -+ compat_uptr_t p_data; -+} ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t; -+ -+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t { -+ ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2; -+ bool update; -+ uint8_t size; -+ compat_uptr_t p_data; -+} ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t; -+ -+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_t { -+ uint8_t size; /**< size of inserted section */ -+ compat_uptr_t p_data; /**< data to be inserted */ -+} ioc_compat_fm_pcd_manip_hdr_insrt_t; -+ -+#if (DPAA_VERSION >= 11) -+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t { -+ bool calc_l4_checksum; /**< Calculate L4 checksum. */ -+ ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */ -+ uint8_t last_pid_offset; /**< the offset of the last Protocol within -+ the inserted header */ -+ uint16_t id; /**< 16 bit New IP ID */ -+ bool dont_frag_overwrite; -+ /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte. -+ * This byte is configured to be overwritten when RPD is set. */ -+ uint8_t last_dst_offset; -+ /**< IPv6 only. if routing extension exist, user should set the offset of the destination address -+ * in order to calculate UDP checksum pseudo header; -+ * Otherwise set it to '0'. */ -+ ioc_compat_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */ -+} ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t { -+ ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type; -+ union { -+ ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params; -+#if (DPAA_VERSION >= 11) -+ ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t ip_params; -+ ioc_compat_fm_pcd_manip_hdr_insrt_t insrt; -+#endif /* (DPAA_VERSION >= 11) */ -+ } u; -+} ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t; -+ -+typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_params_t { -+ ioc_fm_pcd_manip_hdr_insrt_type type; -+ union { -+ ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr; -+ ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t generic; -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+#error "FM_CAPWAP_SUPPORT feature not supported!" -+ ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template; -+#endif /* FM_CAPWAP_SUPPORT */ -+ } u; -+} ioc_compat_fm_pcd_manip_hdr_insrt_params_t; -+ -+typedef struct ioc_compat_fm_pcd_manip_hdr_params_t { -+ bool rmv; -+ ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params; -+ bool insrt; -+ ioc_compat_fm_pcd_manip_hdr_insrt_params_t insrt_params; -+ bool field_update; -+ ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params; -+ bool custom; -+ ioc_fm_pcd_manip_hdr_custom_params_t custom_params; -+ bool dont_parse_after_manip; -+} ioc_compat_fm_pcd_manip_hdr_params_t; -+ -+typedef struct ioc_compat_fm_pcd_manip_special_offload_params_t { -+ bool decryption; -+ bool ecn_copy; -+ bool dscp_copy; -+ bool variable_ip_hdr_len; -+ bool variable_ip_version; -+ uint8_t outer_ip_hdr_len; -+ uint16_t arw_size; -+ compat_uptr_t arw_addr; -+} ioc_compat_fm_pcd_manip_special_offload_params_t; -+ -+typedef struct ioc_compat_fm_pcd_manip_params_t { -+ ioc_fm_pcd_manip_type type; -+ union { -+ ioc_compat_fm_pcd_manip_hdr_params_t hdr; -+ ioc_fm_pcd_manip_reassem_params_t reassem; -+ ioc_fm_pcd_manip_frag_params_t frag; -+ ioc_compat_fm_pcd_manip_special_offload_params_t special_offload; -+ } u; -+ compat_uptr_t p_next_manip; -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+#error "FM_CAPWAP_SUPPORT feature not supported!" -+ bool frag_or_reasm; -+ ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params; -+#endif /* FM_CAPWAP_SUPPORT */ -+ compat_uptr_t id; -+} ioc_compat_fm_pcd_manip_params_t; -+ -+typedef struct ioc_compat_fm_pcd_manip_get_stats_t { -+ compat_uptr_t id; -+ ioc_fm_pcd_manip_stats_t stats; -+} ioc_compat_fm_pcd_manip_get_stats_t; -+ -+#if (DPAA_VERSION >= 11) -+typedef struct ioc_compat_fm_pcd_frm_replic_group_params_t { -+ uint8_t max_num_of_entries; -+ uint8_t num_of_entries; -+ ioc_compat_fm_pcd_cc_next_engine_params_t -+ next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES]; -+ compat_uptr_t id; -+} ioc_compat_fm_pcd_frm_replic_group_params_t; -+ -+typedef struct ioc_compat_fm_pcd_frm_replic_member_t { -+ compat_uptr_t h_replic_group; -+ uint16_t member_index; -+} ioc_compat_fm_pcd_frm_replic_member_t; -+ -+typedef struct ioc_compat_fm_pcd_frm_replic_member_params_t { -+ ioc_compat_fm_pcd_frm_replic_member_t member; -+ ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_params; -+} ioc_compat_fm_pcd_frm_replic_member_params_t; -+ -+typedef struct ioc_compat_fm_vsp_params_t { -+ compat_uptr_t p_fm; /**< A handle to the FM object this VSP related to */ -+ ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used -+ (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. -+ parameter associated with Rx / OP port */ -+ uint16_t liodn_offset; /**< VSP's LIODN offset */ -+ struct { -+ ioc_fm_port_type port_type; /**< Port type */ -+ uint8_t port_id; /**< Port Id - relative to type */ -+ } port_params; -+ uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range -+ defined in relevant FM object */ -+ compat_uptr_t id; /**< return value */ -+} ioc_compat_fm_vsp_params_t; -+ -+typedef struct ioc_compat_fm_buf_pool_depletion_params_t { -+ compat_uptr_t p_fm_vsp; -+ ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion; -+} ioc_compat_fm_buf_pool_depletion_params_t; -+ -+typedef struct ioc_compat_fm_buffer_prefix_content_params_t { -+ compat_uptr_t p_fm_vsp; -+ ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content; -+} ioc_compat_fm_buffer_prefix_content_params_t; -+ -+typedef struct ioc_compat_fm_vsp_config_no_sg_params_t { -+ compat_uptr_t p_fm_vsp; -+ bool no_sg; -+} ioc_compat_fm_vsp_config_no_sg_params_t; -+ -+typedef struct ioc_compat_fm_vsp_prs_result_params_t { -+ compat_uptr_t p_fm_vsp; -+ compat_uptr_t p_data; -+} ioc_compat_fm_vsp_prs_result_params_t; -+ -+#endif /* (DPAA_VERSION >= 11) */ -+typedef struct ioc_compat_fm_pcd_kg_scheme_spc_t { -+ uint32_t val; -+ compat_uptr_t id; -+} ioc_compat_fm_pcd_kg_scheme_spc_t; -+ -+typedef struct ioc_compat_fm_ctrl_mon_counters_params_t { -+ uint8_t fm_ctrl_index; -+ compat_uptr_t p_mon; -+} ioc_compat_fm_ctrl_mon_counters_params_t; -+ -+typedef struct ioc_compat_fm_pcd_cc_tbl_get_stats_t { -+ compat_uptr_t id; -+ uint16_t key_index; -+ ioc_fm_pcd_cc_key_statistics_t statistics; -+} ioc_compat_fm_pcd_cc_tbl_get_stats_t; -+ -+ -+/* } pcd compat structures */ -+ -+void compat_obj_delete( -+ ioc_compat_fm_obj_t *compat_id, -+ ioc_fm_obj_t *id); -+ -+/* pcd compat functions { */ -+void compat_copy_fm_pcd_plcr_profile( -+ ioc_compat_fm_pcd_plcr_profile_params_t *compat_param, -+ ioc_fm_pcd_plcr_profile_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_cc_key( -+ ioc_compat_fm_pcd_cc_key_params_t *compat_param, -+ ioc_fm_pcd_cc_key_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine( -+ ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param, -+ ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_cc_node_modify_next_engine( -+ ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param, -+ ioc_fm_pcd_cc_node_modify_next_engine_params_t *param, -+ uint8_t compat); -+ -+void compat_fm_pcd_cc_tree_modify_next_engine( -+ ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param, -+ ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_hash_table( -+ ioc_compat_fm_pcd_hash_table_params_t *compat_param, -+ ioc_fm_pcd_hash_table_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_cc_grp( -+ ioc_compat_fm_pcd_cc_grp_params_t *compat_param, -+ ioc_fm_pcd_cc_grp_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_cc_tree( -+ ioc_compat_fm_pcd_cc_tree_params_t *compat_param, -+ ioc_fm_pcd_cc_tree_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_cc_tbl_get_stats( -+ ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param, -+ ioc_fm_pcd_cc_tbl_get_stats_t *param, -+ uint8_t compat); -+ -+void compat_fm_pcd_prs_sw( -+ ioc_compat_fm_pcd_prs_sw_params_t *compat_param, -+ ioc_fm_pcd_prs_sw_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_kg_scheme( -+ ioc_compat_fm_pcd_kg_scheme_params_t *compat_param, -+ ioc_fm_pcd_kg_scheme_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_kg_scheme_select( -+ ioc_compat_fm_pcd_kg_scheme_select_t *compat_param, -+ ioc_fm_pcd_kg_scheme_select_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_kg_schemes_params( -+ ioc_compat_fm_pcd_port_schemes_params_t *compat_param, -+ ioc_fm_pcd_port_schemes_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_port_pcd_kg( -+ ioc_compat_fm_port_pcd_kg_params_t *compat_param, -+ ioc_fm_port_pcd_kg_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_port_pcd( -+ ioc_compat_fm_port_pcd_params_t *compat_param, -+ ioc_fm_port_pcd_params_t *param, -+ uint8_t compat); -+ -+#if (DPAA_VERSION >= 11) -+void compat_copy_fm_port_vsp_alloc_params( -+ ioc_compat_fm_port_vsp_alloc_params_t *compat_param, -+ ioc_fm_port_vsp_alloc_params_t *param, -+ uint8_t compat); -+#endif /* (DPAA_VERSION >= 11) */ -+ -+void compat_copy_fm_pcd_net_env( -+ ioc_compat_fm_pcd_net_env_params_t *compat_param, -+ ioc_fm_pcd_net_env_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_cc_node_modify_key( -+ ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param, -+ ioc_fm_pcd_cc_node_modify_key_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_keys( -+ ioc_compat_keys_params_t *compat_param, -+ ioc_keys_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_cc_node( -+ ioc_compat_fm_pcd_cc_node_params_t *compat_param, -+ ioc_fm_pcd_cc_node_params_t *param, -+ uint8_t compat); -+ -+void compat_fm_pcd_manip_set_node( -+ ioc_compat_fm_pcd_manip_params_t *compat_param, -+ ioc_fm_pcd_manip_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_manip_get_stats( -+ ioc_compat_fm_pcd_manip_get_stats_t *compat_param, -+ ioc_fm_pcd_manip_get_stats_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_port_pcd_modify_tree( -+ ioc_compat_fm_obj_t *compat_id, -+ ioc_fm_obj_t *id, -+ uint8_t compat); -+ -+#if (DPAA_VERSION >= 11) -+void compat_copy_fm_pcd_frm_replic_group_params( -+ ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param, -+ ioc_fm_pcd_frm_replic_group_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_frm_replic_member( -+ ioc_compat_fm_pcd_frm_replic_member_t *compat_param, -+ ioc_fm_pcd_frm_replic_member_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_pcd_frm_replic_member_params( -+ ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param, -+ ioc_fm_pcd_frm_replic_member_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_vsp_params( -+ ioc_compat_fm_vsp_params_t *compat_param, -+ ioc_fm_vsp_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_buf_pool_depletion_params( -+ ioc_compat_fm_buf_pool_depletion_params_t *compat_param, -+ ioc_fm_buf_pool_depletion_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_buffer_prefix_content_params( -+ ioc_compat_fm_buffer_prefix_content_params_t *compat_param, -+ ioc_fm_buffer_prefix_content_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_vsp_config_no_sg_params( -+ ioc_compat_fm_vsp_config_no_sg_params_t *compat_param, -+ ioc_fm_vsp_config_no_sg_params_t *param, -+ uint8_t compat); -+ -+void compat_copy_fm_vsp_prs_result_params( -+ ioc_compat_fm_vsp_prs_result_params_t *compat_param, -+ ioc_fm_vsp_prs_result_params_t *param, -+ uint8_t compat); -+ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+void compat_copy_fm_pcd_kg_scheme_spc( -+ ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param, -+ ioc_fm_pcd_kg_scheme_spc_t *param, -+ uint8_t compat); -+ -+/* } pcd compat functions */ -+#endif ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h -@@ -0,0 +1,121 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ @File lnxwrp_resources.h -+ -+ @Description FMD wrapper resource allocation functions. -+ -+*/ -+ -+#ifndef LNXWRP_RESOURCES_H_ -+#define LNXWRP_RESOURCES_H_ -+ -+#if !defined(FMAN_RESOURCES_UNIT_TEST) -+#include "lnxwrp_fm.h" -+#else -+#include "lnxwrp_resources_ut.h" -+#endif -+ -+#define ROUND(X) ((2*(X)+1)/2) -+#define CEIL(X) ((X)+1) -+/* #define ROUND_DIV(X, Y) (((X)+(Y)/2)/(Y)) */ -+#define ROUND_DIV(X, Y) ((2*(X)+(Y))/(2*(Y))) -+#define CEIL_DIV(X, Y) (((X)+(Y)-1)/(Y)) -+ -+/* used for resource calculus */ -+#define DPDE_1G 2 /* DQDP 1g - from LLD: -+ DEFAULT_PORT_txFifoDeqPipelineDepth_1G */ -+#define DPDE_10G 8 /* DQDP 10g - from LLD: -+ DEFAULT_PORT_txFifoDeqPipelineDepth_10G */ -+ -+int fm_set_active_fman_ports(struct platform_device *of_dev, -+ t_LnxWrpFmDev *p_LnxWrpFmDev); -+ -+/* Calculate the fifosize based on MURAM allocation, number of ports, dpde -+ * value and s/g software support (! Kernel does not suport s/g). -+ * -+ * Algorithm summary: -+ * - Calculate the the minimum fifosize required for every type of port -+ * (TX,RX for 1G, 2.5G and 10G). -+ * - Set TX the minimum fifosize required. -+ * - Distribute the remaining buffers (after all TX were set) to RX ports -+ * based on: -+ * 1G RX = Remaining_buffers * 1/(1+2.5+10) -+ * 2.5G RX = Remaining_buffers * 2.5/(1+2.5+10) -+ * 10G RX = Remaining_buffers * 10/(1+2.5+10) -+ * - if the RX is smaller than the minimum required, then set the minimum -+ * required -+ * - In the end distribuite the leftovers if there are any (due to -+ * unprecise calculus) or if over allocation cat some buffers from all RX -+ * ports w/o pass over minimum required treshold, but if there must be -+ * pass the treshold in order to cat the over allocation ,then this -+ * configuration can not be set - KERN_ALERT. -+*/ -+int fm_precalculate_fifosizes(t_LnxWrpFmDev *p_LnxWrpFmDev, -+ int muram_fifo_size); -+ -+#if !defined(FMAN_RESOURCES_UNIT_TEST) -+int fm_config_precalculate_fifosize(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev); -+#endif -+ -+/* Compute FMan open DMA based on total number of open DMAs and -+ * number of available fman ports. -+ * -+ * By default 10g ports are set to input parameters. The other ports -+ * tries to keep the proportion rx=2tx open dmas or tresholds. -+ * -+ * If leftovers, then those will be set as shared. -+ * -+ * If after computing overflow appears, then it decrements open dma -+ * for all ports w/o cross the tresholds. If the tresholds are meet -+ * and is still overflow, then it returns error. -+*/ -+int fm_precalculate_open_dma(t_LnxWrpFmDev *p_LnxWrpFmDev, -+ int max_fm_open_dma, -+ int default_tx_10g_dmas, -+ int default_rx_10g_dmas, -+ int min_tx_10g_treshold, int min_rx_10g_treshold); -+ -+#if !defined(FMAN_RESOURCES_UNIT_TEST) -+int fm_config_precalculate_open_dma(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev); -+#endif -+ -+/* Compute FMan tnums based on available tnums and number of ports. -+ * Set defaults (minim tresholds) and then distribute leftovers.*/ -+int fm_precalculate_tnums(t_LnxWrpFmDev *p_LnxWrpFmDev, int max_fm_tnums); -+ -+#if !defined(FMAN_RESOURCES_UNIT_TEST) -+int fm_config_precalculate_tnums(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev); -+#endif -+ -+#endif /* LNXWRP_RESOURCES_H_ */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c -@@ -0,0 +1,191 @@ -+/* Copyright (c) 2012 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "lnxwrp_resources.h" -+#include "lnxwrp_resources_ut.h" -+ -+#define KILOBYTE 0x400 /* 1024 */ -+ -+typedef enum e_board_type { -+ e_p3041, -+ e_p4080, -+ e_p5020, -+ e_p1023 -+} e_board_type; -+ -+uint8_t board_type; -+uint32_t muram_size = 0; -+uint32_t dmas_num = 0; -+uint32_t task_num = 0; -+uint32_t frame_size = 0; -+uint32_t oh_num = 0; -+uint32_t num_ports_1g = 0; -+uint32_t num_ports_10g = 0; -+uint32_t num_ports_2g5 = 0; -+uint32_t fsl_fman_phy_maxfrm = 0; -+uint32_t dpa_rx_extra_headroom = 0; -+ -+void show_help(void){ -+ printf(" help: \n"); -+ printf(" -b -f -o -g1" -+ " -g10 -g25 \n"); -+ printf(" Maxim num of DMAS availbale: P3/P4/P5:32 , P1023:16 \n"); -+ printf(" Maxim num of TNUMs availbale: P3/P4/P5:128, P1023:32 \n"); -+ printf(" Muram size: P3/P4/P5:160K, P1023:64K \n"); -+ printf(" Number of ports:\n"); -+ printf(" P3/P5: 5p 1g, 1p 10g, 7p oh \n"); -+ printf(" P4 : 4p 1g, 1p 10g, 7p oh \n"); -+ printf(" P1 : 2p 1g, 0p 10g, 4p oh \n"); -+ printf(" MTU: Default:1522, Jumbo:9600 \n"); -+} -+ -+int fm_set_param(t_LnxWrpFmDev *p_LnxWrpFmDev) { -+ struct fm_active_ports *fm_active_ports_info = NULL; -+ fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info; -+ -+ switch(board_type){ -+ case e_p3041: -+ case e_p5020: -+ muram_size = 160*KILOBYTE; -+ dmas_num = 32; -+ task_num = 128; -+ if ((num_ports_1g+num_ports_2g5) > 5 || num_ports_10g > 1 || oh_num > 7) -+ goto err_fm_set_param; -+ break; -+ case e_p4080: -+ muram_size = 160*KILOBYTE; -+ dmas_num = 32; -+ task_num = 128; -+ if ((num_ports_1g+num_ports_2g5) > 4 || num_ports_10g > 1 || oh_num > 7) -+ goto err_fm_set_param; -+ break; -+ case e_p1023: -+ muram_size = 64*KILOBYTE; -+ dmas_num = 16; -+ task_num = 128; -+ if ((num_ports_1g+num_ports_2g5) > 2 || oh_num > 4) -+ goto err_fm_set_param; -+ break; -+ default: -+ goto err_fm_set_param; -+ break; -+ } -+ -+ p_LnxWrpFmDev->id = 0; -+ fsl_fman_phy_maxfrm = frame_size; -+ dpa_rx_extra_headroom = 0; /* ATTENTION: can be != 0 */ -+ fm_active_ports_info->num_oh_ports = oh_num; -+ fm_active_ports_info->num_tx_ports = num_ports_1g; -+ fm_active_ports_info->num_rx_ports = num_ports_1g; -+ fm_active_ports_info->num_tx25_ports = num_ports_2g5; -+ fm_active_ports_info->num_rx25_ports = num_ports_2g5; -+ fm_active_ports_info->num_tx10_ports = num_ports_10g; -+ fm_active_ports_info->num_rx10_ports = num_ports_10g; -+ -+ return 0; -+ -+err_fm_set_param: -+ printf(" ERR: To many ports!!! \n"); -+ return -1; -+} -+ -+int main (int argc, char *argv[]){ -+ t_LnxWrpFmDev LnxWrpFmDev; -+ t_LnxWrpFmDev *p_LnxWrpFmDev = &LnxWrpFmDev; -+ int tokens_cnt = 1; -+ -+ char *token = NULL; -+ -+ while(tokens_cnt < argc) -+ { -+ token = argv[tokens_cnt++]; -+ if (strcmp(token, "-b") == 0){ -+ if(strcmp(argv[tokens_cnt],"p3") == 0) -+ board_type = e_p3041; -+ else if(strcmp(argv[tokens_cnt],"p4") == 0) -+ board_type = e_p4080; -+ else if(strcmp(argv[tokens_cnt],"p5") == 0) -+ board_type = e_p5020; -+ else if(strcmp(argv[tokens_cnt],"p1") == 0) -+ board_type = e_p1023; -+ else -+ show_help(); -+ tokens_cnt++; -+ } -+ else if(strcmp(token, "-d") == 0){ -+ dmas_num = atoi(argv[tokens_cnt++]); -+ } -+ else if(strcmp(token, "-t") == 0) -+ task_num = atoi(argv[tokens_cnt++]); -+ else if(strcmp(token, "-f") == 0) -+ frame_size = atoi(argv[tokens_cnt++]); -+ else if(strcmp(token, "-o") == 0) -+ oh_num = atoi(argv[tokens_cnt++]); -+ else if(strcmp(token, "-g1") == 0) -+ num_ports_1g = atoi(argv[tokens_cnt++]); -+ else if(strcmp(token, "-g10") == 0) -+ num_ports_10g = atoi(argv[tokens_cnt++]); -+ else if(strcmp(token, "-g25") == 0) -+ num_ports_2g5 = atoi(argv[tokens_cnt++]); -+ else { -+ show_help(); -+ return -1; -+ } -+ } -+ -+ if(fm_set_param(p_LnxWrpFmDev) < 0){ -+ show_help(); -+ return -1; -+ } -+ -+ if(fm_precalculate_fifosizes( -+ p_LnxWrpFmDev, -+ 128*KILOBYTE) -+ != 0) -+ return -1; -+ if(fm_precalculate_open_dma( -+ p_LnxWrpFmDev, -+ dmas_num, /* max open dmas:dpaa_integration_ext.h */ -+ FM_DEFAULT_TX10G_OPENDMA, /* default TX 10g open dmas */ -+ FM_DEFAULT_RX10G_OPENDMA, /* default RX 10g open dmas */ -+ FM_10G_OPENDMA_MIN_TRESHOLD,/* TX 10g minimum treshold */ -+ FM_10G_OPENDMA_MIN_TRESHOLD)/* RX 10g minimum treshold */ -+ != 0) -+ return -1; -+ if(fm_precalculate_tnums( -+ p_LnxWrpFmDev, -+ task_num) /* max TNUMS: dpa integration file. */ -+ != 0) -+ return -1; -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h -@@ -0,0 +1,144 @@ -+/* Copyright (c) 2012 Freescale Semiconductor, Inc -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef FM_RESS_TEST_H_ -+#define FM_RESS_TEST_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define _Packed -+#define _PackedType __attribute__ ((packed)) -+#define MAX(x, y) (((x) > (y)) ? (x) : (y)) -+#define MIN(x, y) (((x) < (y)) ? (x) : (y)) -+#define KERN_ALERT "" -+#define KERN_INFO "" -+#define ASSERT_COND assert -+#define printk printf -+#define NET_IP_ALIGN 0 -+#define FM_FIFO_ALLOCATION_OLD_ALG -+ -+#if defined(CONFIG_FMAN_DISABLE_OH_AND_DISTRIBUTE_RESOURCES) -+#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */ -+#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */ -+#else -+#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */ -+#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */ -+#endif -+#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */ -+#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */ -+ -+/* information about all active ports for an FMan. -+ * !Some ports may be disabled by u-boot, thus will not be available */ -+struct fm_active_ports { -+ uint32_t num_oh_ports; -+ uint32_t num_tx_ports; -+ uint32_t num_rx_ports; -+ uint32_t num_tx25_ports; -+ uint32_t num_rx25_ports; -+ uint32_t num_tx10_ports; -+ uint32_t num_rx10_ports; -+}; -+ -+/* FMan resources precalculated at fm probe based -+ * on available FMan port. */ -+struct fm_resource_settings { -+ /* buffers - fifo sizes */ -+ uint32_t tx1g_num_buffers; -+ uint32_t rx1g_num_buffers; -+ uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */ -+ uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */ -+ uint32_t tx10g_num_buffers; -+ uint32_t rx10g_num_buffers; -+ uint32_t oh_num_buffers; -+ uint32_t shared_ext_buffers; -+ -+ -+ /* open DMAs */ -+ uint32_t tx_1g_dmas; -+ uint32_t rx_1g_dmas; -+ uint32_t tx_2g5_dmas; /* Not supported yet by LLD */ -+ uint32_t rx_2g5_dmas; /* Not supported yet by LLD */ -+ uint32_t tx_10g_dmas; -+ uint32_t rx_10g_dmas; -+ uint32_t oh_dmas; -+ uint32_t shared_ext_open_dma; -+ -+ /* Tnums */ -+ uint32_t tx_1g_tnums; -+ uint32_t rx_1g_tnums; -+ uint32_t tx_2g5_tnums; /* Not supported yet by LLD */ -+ uint32_t rx_2g5_tnums; /* Not supported yet by LLD */ -+ uint32_t tx_10g_tnums; -+ uint32_t rx_10g_tnums; -+ uint32_t oh_tnums; -+ uint32_t shared_ext_tnums; -+}; -+ -+typedef struct { -+ uint8_t id; -+ struct fm_active_ports fm_active_ports_info; -+ struct fm_resource_settings fm_resource_settings_info; -+} t_LnxWrpFmDev; -+ -+typedef struct { -+ uint8_t id; -+} t_LnxWrpFmPortDev; -+ -+typedef _Packed struct t_FmPrsResult { -+ volatile uint8_t lpid; /**< Logical port id */ -+ volatile uint8_t shimr; /**< Shim header result */ -+ volatile uint16_t l2r; /**< Layer 2 result */ -+ volatile uint16_t l3r; /**< Layer 3 result */ -+ volatile uint8_t l4r; /**< Layer 4 result */ -+ volatile uint8_t cplan; /**< Classification plan id */ -+ volatile uint16_t nxthdr; /**< Next Header */ -+ volatile uint16_t cksum; /**< Checksum */ -+ volatile uint32_t lcv; /**< LCV */ -+ volatile uint8_t shim_off[3]; /**< Shim offset */ -+ volatile uint8_t eth_off; /**< ETH offset */ -+ volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */ -+ volatile uint8_t vlan_off[2]; /**< VLAN offset */ -+ volatile uint8_t etype_off; /**< ETYPE offset */ -+ volatile uint8_t pppoe_off; /**< PPP offset */ -+ volatile uint8_t mpls_off[2]; /**< MPLS offset */ -+ volatile uint8_t ip_off[2]; /**< IP offset */ -+ volatile uint8_t gre_off; /**< GRE offset */ -+ volatile uint8_t l4_off; /**< Layer 4 offset */ -+ volatile uint8_t nxthdr_off; /**< Parser end point */ -+} _PackedType t_FmPrsResult; -+ -+#endif ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make -@@ -0,0 +1,28 @@ -+CC=gcc -+ -+LNXWRP_RESS_UT=lnxwrp_resources_ut -+OBJ=lnxwrp_resources -+ -+INC_PATH= -+LIB_PATH= -+ -+INC=$(addprefix -I,$(INC_PATH)) -+LIB=$(addprefix -L,$(LIB_PATH)) -+ -+CFLAGS= -gdwarf-2 -g -O0 -Wall -+XFLAGS= -DFMAN_RESOURCES_UNIT_TEST -+ -+all: $(LNXWRP_RESS_UT) -+ -+$(LNXWRP_RESS_UT):$(addsuffix .o,$(OBJ)) $(LNXWRP_RESS_UT).o -+ $(CC) -o $(LNXWRP_RESS_UT) $(LNXWRP_RESS_UT).o $(addsuffix .o,$(OBJ)) -+ -+%.o: %.c -+ @(echo " (CC) $@") -+ @($(CC) $(INC) $(CFLAGS) $(XFLAGS) -o $(@) -c $<) -+ -+.PHONY: clean -+ -+clean: -+ rm -f *.o -+ rm -f $(LNXWRP_RESS_UT) ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c -@@ -0,0 +1,60 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ @File lnxwrp_sysfs.c -+ -+ @Description FM wrapper sysfs related functions. -+ -+*/ -+ -+#include -+#include "lnxwrp_sysfs.h" -+ -+uint8_t fm_find_statistic_counter_by_name(const char *attr_name, -+ const struct sysfs_stats_t *sysfs_stats, -+ uint8_t *offset) -+{ -+ int i = 0; -+ -+ while (sysfs_stats[i].stat_name != NULL) { -+ if (strcmp(sysfs_stats[i].stat_name, attr_name) == 0) { -+ if (offset != NULL) -+ *offset = i; -+ return sysfs_stats[i].stat_counter; -+ } -+ -+ i++; -+ } -+ WARN(1, "FMD: Should never get here!"); -+ return 0; -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h -@@ -0,0 +1,60 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef LNXWRP_SYSFS_H_ -+#define LNXWRP_SYSFS_H_ -+ -+/* Linux Headers ------------------- */ -+#include -+ -+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) -+#define MODVERSIONS -+#endif -+#ifdef MODVERSIONS -+#include -+#endif /* MODVERSIONS */ -+ -+#include -+#include -+#include -+#include -+ -+struct sysfs_stats_t { -+ const char *stat_name; -+ uint8_t stat_counter; -+}; -+ -+uint8_t fm_find_statistic_counter_by_name(const char *attr_name, -+ const struct sysfs_stats_t *sysfs_stats, -+ uint8_t *offset); -+ -+#endif /* LNXWRP_SYSFS_H_ */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c -@@ -0,0 +1,1855 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "lnxwrp_sysfs.h" -+#include "lnxwrp_sysfs_fm.h" -+#include "lnxwrp_fm.h" -+ -+#include "../../sdk_fman/Peripherals/FM/inc/fm_common.h" -+#include "../../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h" -+#include "../../sdk_fman/Peripherals/FM/Pcd/fm_kg.h" -+#include "../../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h" -+ -+#if defined(__ERR_MODULE__) -+#undef __ERR_MODULE__ -+#endif -+ -+#include "../../sdk_fman/Peripherals/FM/fm.h" -+#include -+ -+ -+static int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val); -+ -+enum fm_dma_match_stats { -+ FM_DMA_COUNTERS_CMQ_NOT_EMPTY, -+ FM_DMA_COUNTERS_BUS_ERROR, -+ FM_DMA_COUNTERS_READ_BUF_ECC_ERROR, -+ FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR, -+ FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR -+}; -+ -+static const struct sysfs_stats_t fm_sysfs_stats[] = { -+ /* FM statistics */ -+ { -+ .stat_name = "enq_total_frame", -+ .stat_counter = e_FM_COUNTERS_ENQ_TOTAL_FRAME, -+ }, -+ { -+ .stat_name = "deq_total_frame", -+ .stat_counter = e_FM_COUNTERS_DEQ_TOTAL_FRAME, -+ }, -+ { -+ .stat_name = "deq_0", -+ .stat_counter = e_FM_COUNTERS_DEQ_0, -+ }, -+ { -+ .stat_name = "deq_1", -+ .stat_counter = e_FM_COUNTERS_DEQ_1, -+ }, -+ { -+ .stat_name = "deq_2", -+ .stat_counter = e_FM_COUNTERS_DEQ_2, -+ }, -+ { -+ .stat_name = "deq_3", -+ .stat_counter = e_FM_COUNTERS_DEQ_3, -+ }, -+ { -+ .stat_name = "deq_from_default", -+ .stat_counter = e_FM_COUNTERS_DEQ_FROM_DEFAULT, -+ }, -+ { -+ .stat_name = "deq_from_context", -+ .stat_counter = e_FM_COUNTERS_DEQ_FROM_CONTEXT, -+ }, -+ { -+ .stat_name = "deq_from_fd", -+ .stat_counter = e_FM_COUNTERS_DEQ_FROM_FD, -+ }, -+ { -+ .stat_name = "deq_confirm", -+ .stat_counter = e_FM_COUNTERS_DEQ_CONFIRM, -+ }, -+ /* FM:DMA statistics */ -+ { -+ .stat_name = "cmq_not_empty", -+ .stat_counter = FM_DMA_COUNTERS_CMQ_NOT_EMPTY, -+ }, -+ { -+ .stat_name = "bus_error", -+ .stat_counter = FM_DMA_COUNTERS_BUS_ERROR, -+ }, -+ { -+ .stat_name = "read_buf_ecc_error", -+ .stat_counter = FM_DMA_COUNTERS_READ_BUF_ECC_ERROR, -+ }, -+ { -+ .stat_name = "write_buf_ecc_sys_error", -+ .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR, -+ }, -+ { -+ .stat_name = "write_buf_ecc_fm_error", -+ .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR, -+ }, -+ /* FM:PCD statistics */ -+ { -+ .stat_name = "pcd_kg_total", -+ .stat_counter = e_FM_PCD_KG_COUNTERS_TOTAL, -+ }, -+ { -+ .stat_name = "pcd_plcr_yellow", -+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_YELLOW, -+ }, -+ { -+ .stat_name = "pcd_plcr_red", -+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_RED, -+ }, -+ { -+ .stat_name = "pcd_plcr_recolored_to_red", -+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, -+ }, -+ { -+ .stat_name = "pcd_plcr_recolored_to_yellow", -+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, -+ }, -+ { -+ .stat_name = "pcd_plcr_total", -+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_TOTAL, -+ }, -+ { -+ .stat_name = "pcd_plcr_length_mismatch", -+ .stat_counter = e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, -+ }, -+ { -+ .stat_name = "pcd_prs_parse_dispatch", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, -+ }, -+ { -+ .stat_name = "pcd_prs_l2_parse_result_returned", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, -+ }, -+ { -+ .stat_name = "pcd_prs_l3_parse_result_returned", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, -+ }, -+ { -+ .stat_name = "pcd_prs_l4_parse_result_returned", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, -+ }, -+ { -+ .stat_name = "pcd_prs_shim_parse_result_returned", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, -+ }, -+ { -+ .stat_name = "pcd_prs_l2_parse_result_returned_with_err", -+ .stat_counter = -+ e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR, -+ }, -+ { -+ .stat_name = "pcd_prs_l3_parse_result_returned_with_err", -+ .stat_counter = -+ e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR, -+ }, -+ { -+ .stat_name = "pcd_prs_l4_parse_result_returned_with_err", -+ .stat_counter = -+ e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR, -+ }, -+ { -+ .stat_name = "pcd_prs_shim_parse_result_returned_with_err", -+ .stat_counter = -+ e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR, -+ }, -+ { -+ .stat_name = "pcd_prs_soft_prs_cycles", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, -+ }, -+ { -+ .stat_name = "pcd_prs_soft_prs_stall_cycles", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES, -+ }, -+ { -+ .stat_name = "pcd_prs_hard_prs_cycle_incl_stall_cycles", -+ .stat_counter = -+ e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES, -+ }, -+ { -+ .stat_name = "pcd_prs_muram_read_cycles", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, -+ }, -+ { -+ .stat_name = "pcd_prs_muram_read_stall_cycles", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, -+ }, -+ { -+ .stat_name = "pcd_prs_muram_write_cycles", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, -+ }, -+ { -+ .stat_name = "pcd_prs_muram_write_stall_cycles", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, -+ }, -+ { -+ .stat_name = "pcd_prs_fpm_command_stall_cycles", -+ .stat_counter = e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES, -+ }, -+ {} -+}; -+ -+ -+static ssize_t show_fm_risc_load(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+ unsigned long flags; -+ int m =0; -+ int err =0; -+ unsigned n = 0; -+ t_FmCtrlMon util; -+ uint8_t i =0 ; -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev) -+ return -EIO; -+ -+ local_irq_save(flags); -+ -+ /* Calculate risc load */ -+ FM_CtrlMonStart(p_wrp_fm_dev->h_Dev); -+ msleep(1000); -+ FM_CtrlMonStop(p_wrp_fm_dev->h_Dev); -+ -+ for (i = 0; i < FM_NUM_OF_CTRL; i++) { -+ err |= FM_CtrlMonGetCounters(p_wrp_fm_dev->h_Dev, i, &util); -+ m = snprintf(&buf[n],PAGE_SIZE,"\tRisc%u: util-%u%%, efficiency-%u%%\n", -+ i, util.percentCnt[0], util.percentCnt[1]); -+ n=m+n; -+ } -+ -+ local_irq_restore(flags); -+ -+ return n; -+} -+ -+/* Fm stats and regs dumps via sysfs */ -+static ssize_t show_fm_dma_stats(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+ t_FmDmaStatus dma_status; -+ unsigned long flags = 0; -+ unsigned n = 0; -+ uint8_t counter_value = 0, counter = 0; -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev) -+ return -EIO; -+ -+ counter = fm_find_statistic_counter_by_name( -+ attr->attr.name, -+ fm_sysfs_stats, NULL); -+ -+ local_irq_save(flags); -+ -+ memset(&dma_status, 0, sizeof(dma_status)); -+ FM_GetDmaStatus(p_wrp_fm_dev->h_Dev, &dma_status); -+ -+ switch (counter) { -+ case FM_DMA_COUNTERS_CMQ_NOT_EMPTY: -+ counter_value = dma_status.cmqNotEmpty; -+ break; -+ case FM_DMA_COUNTERS_BUS_ERROR: -+ counter_value = dma_status.busError; -+ break; -+ case FM_DMA_COUNTERS_READ_BUF_ECC_ERROR: -+ counter_value = dma_status.readBufEccError; -+ break; -+ case FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR: -+ counter_value = dma_status.writeBufEccSysError; -+ break; -+ case FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR: -+ counter_value = dma_status.writeBufEccFmError; -+ break; -+ default: -+ WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__, -+ __func__); -+ break; -+ }; -+ -+ n = snprintf(buf, PAGE_SIZE, "\tFM %u counter: %c\n", -+ p_wrp_fm_dev->id, counter_value ? 'T' : 'F'); -+ -+ local_irq_restore(flags); -+ -+ return n; -+} -+ -+static ssize_t show_fm_stats(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+ unsigned long flags = 0; -+ unsigned n = 0, cnt_e = 0; -+ uint32_t cnt_val; -+ int err; -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev) -+ return -EIO; -+ -+ cnt_e = fm_find_statistic_counter_by_name( -+ attr->attr.name, -+ fm_sysfs_stats, NULL); -+ -+ err = fm_get_counter(p_wrp_fm_dev->h_Dev, -+ (e_FmCounters) cnt_e, &cnt_val); -+ -+ if (err) -+ return err; -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n", -+ p_wrp_fm_dev->id, cnt_val); -+ -+ local_irq_restore(flags); -+ -+ return n; -+} -+ -+static ssize_t show_fm_muram_free_sz(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+ unsigned long flags = 0; -+ unsigned n = 0; -+ uint64_t muram_free_size = 0; -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev) -+ return -EIO; -+ -+ muram_free_size = FM_MURAM_GetFreeMemSize(p_wrp_fm_dev->h_MuramDev); -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "\tFM %d muram_free_size: %lld\n", -+ p_wrp_fm_dev->id, muram_free_size); -+ -+ local_irq_restore(flags); -+ -+ return n; -+} -+ -+static ssize_t show_fm_ctrl_code_ver(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+ unsigned long flags = 0; -+ unsigned n = 0; -+ t_FmCtrlCodeRevisionInfo rv_info; -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev) -+ return -EIO; -+ -+ FM_GetFmanCtrlCodeRevision((t_Fm *)p_wrp_fm_dev->h_Dev, &rv_info); -+ -+ local_irq_save(flags); -+ -+ FM_DMP_LN(buf, n, "- FM %d ctrl code pkg info:\n", p_wrp_fm_dev->id); -+ FM_DMP_LN(buf, n, "Package rev: %d\n", rv_info.packageRev); -+ FM_DMP_LN(buf, n, "major rev: %d\n", rv_info.majorRev); -+ FM_DMP_LN(buf, n, "minor rev: %d\n", rv_info.minorRev); -+ -+ local_irq_restore(flags); -+ -+ return n; -+} -+ -+static ssize_t show_fm_pcd_stats(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+ unsigned long flags = 0; -+ unsigned n = 0, counter = 0; -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev || -+ !p_wrp_fm_dev->h_PcdDev) -+ return -EIO; -+ -+ counter = fm_find_statistic_counter_by_name( -+ attr->attr.name, -+ fm_sysfs_stats, NULL); -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n", -+ p_wrp_fm_dev->id, -+ FM_PCD_GetCounter(p_wrp_fm_dev->h_PcdDev, -+ (e_FmPcdCounters) counter)); -+ -+ local_irq_restore(flags); -+ -+ return n; -+} -+ -+static ssize_t show_fm_tnum_dbg(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ -+ if (!p_wrp_fm_dev->active) -+ return -EIO; -+ else { -+ int tn_s; -+ -+ if (!sscanf(attr->attr.name, "tnum_dbg_%d", &tn_s)) -+ return -EINVAL; -+ -+ n = fm_dump_tnum_dbg(p_wrp_fm_dev->h_Dev, -+ tn_s, tn_s + 15, buf, n); -+ } -+ local_irq_restore(flags); -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ return n; -+} -+ -+static ssize_t show_fm_cls_plan(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "\n FM-KG classification plan dump.\n"); -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev) -+ return -EIO; -+ else { -+ int cpn; -+ -+ if (!sscanf(attr->attr.name, "cls_plan_%d", &cpn)) -+ return -EINVAL; -+ -+ n = fm_dump_cls_plan(p_wrp_fm_dev->h_PcdDev, cpn, buf, n); -+ } -+ local_irq_restore(flags); -+#else -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ return n; -+} -+ -+static ssize_t show_fm_profiles(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "FM policer profile dump.\n"); -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev) -+ return -EIO; -+ else { -+ int pn; -+ -+ if (!sscanf(attr->attr.name, "profile_%d", &pn)) -+ return -EINVAL; -+ -+ n = fm_profile_dump_regs(p_wrp_fm_dev->h_PcdDev, pn, buf, n); -+ } -+ local_irq_restore(flags); -+#else -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ return n; -+} -+ -+static ssize_t show_fm_schemes(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "FM-KG driver schemes dump.\n"); -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev) -+ return -EIO; -+ else { -+ int sn; -+ -+ if (!sscanf(attr->attr.name, "scheme_%d", &sn)) -+ return -EINVAL; -+ -+ n = fm_dump_scheme(p_wrp_fm_dev->h_PcdDev, sn, buf, n); -+ } -+ local_irq_restore(flags); -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ return n; -+} -+ -+/* FM */ -+static DEVICE_ATTR(enq_total_frame, S_IRUGO, show_fm_stats, NULL); -+static DEVICE_ATTR(deq_total_frame, S_IRUGO, show_fm_stats, NULL); -+static DEVICE_ATTR(fm_risc_load_val, S_IRUGO, show_fm_risc_load, NULL); -+static DEVICE_ATTR(deq_0, S_IRUGO, show_fm_stats, NULL); -+static DEVICE_ATTR(deq_1, S_IRUGO, show_fm_stats, NULL); -+static DEVICE_ATTR(deq_2, S_IRUGO, show_fm_stats, NULL); -+static DEVICE_ATTR(deq_3, S_IRUGO, show_fm_stats, NULL); -+static DEVICE_ATTR(deq_from_default, S_IRUGO, show_fm_stats, NULL); -+static DEVICE_ATTR(deq_from_context, S_IRUGO, show_fm_stats, NULL); -+static DEVICE_ATTR(deq_from_fd, S_IRUGO, show_fm_stats, NULL); -+static DEVICE_ATTR(deq_confirm, S_IRUGO, show_fm_stats, NULL); -+/* FM:DMA */ -+static DEVICE_ATTR(cmq_not_empty, S_IRUGO, show_fm_dma_stats, NULL); -+static DEVICE_ATTR(bus_error, S_IRUGO, show_fm_dma_stats, NULL); -+static DEVICE_ATTR(read_buf_ecc_error, S_IRUGO, show_fm_dma_stats, NULL); -+static DEVICE_ATTR(write_buf_ecc_sys_error, S_IRUGO, show_fm_dma_stats, NULL); -+static DEVICE_ATTR(write_buf_ecc_fm_error, S_IRUGO, show_fm_dma_stats, NULL); -+/* FM:PCD */ -+static DEVICE_ATTR(pcd_kg_total, S_IRUGO, show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_plcr_yellow, S_IRUGO, show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_plcr_red, S_IRUGO, show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_plcr_recolored_to_red, S_IRUGO, show_fm_pcd_stats, -+ NULL); -+static DEVICE_ATTR(pcd_plcr_recolored_to_yellow, S_IRUGO, show_fm_pcd_stats, -+ NULL); -+static DEVICE_ATTR(pcd_plcr_total, S_IRUGO, show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_plcr_length_mismatch, S_IRUGO, show_fm_pcd_stats, -+ NULL); -+static DEVICE_ATTR(pcd_prs_parse_dispatch, S_IRUGO, show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_l2_parse_result_returned, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_l3_parse_result_returned, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_l4_parse_result_returned, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_shim_parse_result_returned, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_l2_parse_result_returned_with_err, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_l3_parse_result_returned_with_err, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_l4_parse_result_returned_with_err, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_shim_parse_result_returned_with_err, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_soft_prs_cycles, S_IRUGO, show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_soft_prs_stall_cycles, S_IRUGO, show_fm_pcd_stats, -+ NULL); -+static DEVICE_ATTR(pcd_prs_hard_prs_cycle_incl_stall_cycles, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_muram_read_cycles, S_IRUGO, show_fm_pcd_stats, -+ NULL); -+static DEVICE_ATTR(pcd_prs_muram_read_stall_cycles, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_muram_write_cycles, S_IRUGO, show_fm_pcd_stats, -+ NULL); -+static DEVICE_ATTR(pcd_prs_muram_write_stall_cycles, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+static DEVICE_ATTR(pcd_prs_fpm_command_stall_cycles, S_IRUGO, -+ show_fm_pcd_stats, NULL); -+ -+static DEVICE_ATTR(tnum_dbg_0, S_IRUGO, show_fm_tnum_dbg, NULL); -+static DEVICE_ATTR(tnum_dbg_16, S_IRUGO, show_fm_tnum_dbg, NULL); -+static DEVICE_ATTR(tnum_dbg_32, S_IRUGO, show_fm_tnum_dbg, NULL); -+static DEVICE_ATTR(tnum_dbg_48, S_IRUGO, show_fm_tnum_dbg, NULL); -+static DEVICE_ATTR(tnum_dbg_64, S_IRUGO, show_fm_tnum_dbg, NULL); -+static DEVICE_ATTR(tnum_dbg_80, S_IRUGO, show_fm_tnum_dbg, NULL); -+static DEVICE_ATTR(tnum_dbg_96, S_IRUGO, show_fm_tnum_dbg, NULL); -+static DEVICE_ATTR(tnum_dbg_112, S_IRUGO, show_fm_tnum_dbg, NULL); -+ -+static DEVICE_ATTR(cls_plan_0, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_1, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_2, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_3, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_4, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_5, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_6, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_7, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_8, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_9, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_10, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_11, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_12, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_13, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_14, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_15, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_16, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_17, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_18, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_19, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_20, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_21, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_22, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_23, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_24, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_25, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_26, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_27, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_28, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_29, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_30, S_IRUGO, show_fm_cls_plan, NULL); -+static DEVICE_ATTR(cls_plan_31, S_IRUGO, show_fm_cls_plan, NULL); -+ -+static DEVICE_ATTR(profile_0, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_1, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_2, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_3, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_4, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_5, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_6, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_7, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_8, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_9, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_10, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_11, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_12, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_13, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_14, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_15, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_16, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_17, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_18, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_19, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_20, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_21, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_22, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_23, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_24, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_25, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_26, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_27, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_28, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_29, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_30, S_IRUGO, show_fm_profiles, NULL); -+static DEVICE_ATTR(profile_31, S_IRUGO, show_fm_profiles, NULL); -+ -+static DEVICE_ATTR(scheme_0, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_1, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_2, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_3, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_4, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_5, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_6, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_7, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_8, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_9, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_10, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_11, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_12, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_13, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_14, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_15, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_16, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_17, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_18, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_19, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_20, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_21, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_22, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_23, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_24, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_25, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_26, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_27, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_28, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_29, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_30, S_IRUGO, show_fm_schemes, NULL); -+static DEVICE_ATTR(scheme_31, S_IRUGO, show_fm_schemes, NULL); -+ -+ -+static struct attribute *fm_dev_stats_attributes[] = { -+ &dev_attr_enq_total_frame.attr, -+ &dev_attr_deq_total_frame.attr, -+ &dev_attr_deq_0.attr, -+ &dev_attr_deq_1.attr, -+ &dev_attr_deq_2.attr, -+ &dev_attr_deq_3.attr, -+ &dev_attr_deq_from_default.attr, -+ &dev_attr_deq_from_context.attr, -+ &dev_attr_deq_from_fd.attr, -+ &dev_attr_deq_confirm.attr, -+ &dev_attr_cmq_not_empty.attr, -+ &dev_attr_bus_error.attr, -+ &dev_attr_read_buf_ecc_error.attr, -+ &dev_attr_write_buf_ecc_sys_error.attr, -+ &dev_attr_write_buf_ecc_fm_error.attr, -+ &dev_attr_pcd_kg_total.attr, -+ &dev_attr_pcd_plcr_yellow.attr, -+ &dev_attr_pcd_plcr_red.attr, -+ &dev_attr_pcd_plcr_recolored_to_red.attr, -+ &dev_attr_pcd_plcr_recolored_to_yellow.attr, -+ &dev_attr_pcd_plcr_total.attr, -+ &dev_attr_pcd_plcr_length_mismatch.attr, -+ &dev_attr_pcd_prs_parse_dispatch.attr, -+ &dev_attr_pcd_prs_l2_parse_result_returned.attr, -+ &dev_attr_pcd_prs_l3_parse_result_returned.attr, -+ &dev_attr_pcd_prs_l4_parse_result_returned.attr, -+ &dev_attr_pcd_prs_shim_parse_result_returned.attr, -+ &dev_attr_pcd_prs_l2_parse_result_returned_with_err.attr, -+ &dev_attr_pcd_prs_l3_parse_result_returned_with_err.attr, -+ &dev_attr_pcd_prs_l4_parse_result_returned_with_err.attr, -+ &dev_attr_pcd_prs_shim_parse_result_returned_with_err.attr, -+ &dev_attr_pcd_prs_soft_prs_cycles.attr, -+ &dev_attr_pcd_prs_soft_prs_stall_cycles.attr, -+ &dev_attr_pcd_prs_hard_prs_cycle_incl_stall_cycles.attr, -+ &dev_attr_pcd_prs_muram_read_cycles.attr, -+ &dev_attr_pcd_prs_muram_read_stall_cycles.attr, -+ &dev_attr_pcd_prs_muram_write_cycles.attr, -+ &dev_attr_pcd_prs_muram_write_stall_cycles.attr, -+ &dev_attr_pcd_prs_fpm_command_stall_cycles.attr, -+ NULL -+}; -+ -+static struct attribute *fm_dev_tnums_dbg_attributes[] = { -+ &dev_attr_tnum_dbg_0.attr, -+ &dev_attr_tnum_dbg_16.attr, -+ &dev_attr_tnum_dbg_32.attr, -+ &dev_attr_tnum_dbg_48.attr, -+ &dev_attr_tnum_dbg_64.attr, -+ &dev_attr_tnum_dbg_80.attr, -+ &dev_attr_tnum_dbg_96.attr, -+ &dev_attr_tnum_dbg_112.attr, -+ NULL -+}; -+ -+static struct attribute *fm_dev_cls_plans_attributes[] = { -+ &dev_attr_cls_plan_0.attr, -+ &dev_attr_cls_plan_1.attr, -+ &dev_attr_cls_plan_2.attr, -+ &dev_attr_cls_plan_3.attr, -+ &dev_attr_cls_plan_4.attr, -+ &dev_attr_cls_plan_5.attr, -+ &dev_attr_cls_plan_6.attr, -+ &dev_attr_cls_plan_7.attr, -+ &dev_attr_cls_plan_8.attr, -+ &dev_attr_cls_plan_9.attr, -+ &dev_attr_cls_plan_10.attr, -+ &dev_attr_cls_plan_11.attr, -+ &dev_attr_cls_plan_12.attr, -+ &dev_attr_cls_plan_13.attr, -+ &dev_attr_cls_plan_14.attr, -+ &dev_attr_cls_plan_15.attr, -+ &dev_attr_cls_plan_16.attr, -+ &dev_attr_cls_plan_17.attr, -+ &dev_attr_cls_plan_18.attr, -+ &dev_attr_cls_plan_19.attr, -+ &dev_attr_cls_plan_20.attr, -+ &dev_attr_cls_plan_21.attr, -+ &dev_attr_cls_plan_22.attr, -+ &dev_attr_cls_plan_23.attr, -+ &dev_attr_cls_plan_24.attr, -+ &dev_attr_cls_plan_25.attr, -+ &dev_attr_cls_plan_26.attr, -+ &dev_attr_cls_plan_27.attr, -+ &dev_attr_cls_plan_28.attr, -+ &dev_attr_cls_plan_29.attr, -+ &dev_attr_cls_plan_30.attr, -+ &dev_attr_cls_plan_31.attr, -+ NULL -+}; -+ -+static struct attribute *fm_dev_profiles_attributes[] = { -+ &dev_attr_profile_0.attr, -+ &dev_attr_profile_1.attr, -+ &dev_attr_profile_2.attr, -+ &dev_attr_profile_3.attr, -+ &dev_attr_profile_4.attr, -+ &dev_attr_profile_5.attr, -+ &dev_attr_profile_6.attr, -+ &dev_attr_profile_7.attr, -+ &dev_attr_profile_8.attr, -+ &dev_attr_profile_9.attr, -+ &dev_attr_profile_10.attr, -+ &dev_attr_profile_11.attr, -+ &dev_attr_profile_12.attr, -+ &dev_attr_profile_13.attr, -+ &dev_attr_profile_14.attr, -+ &dev_attr_profile_15.attr, -+ &dev_attr_profile_16.attr, -+ &dev_attr_profile_17.attr, -+ &dev_attr_profile_18.attr, -+ &dev_attr_profile_19.attr, -+ &dev_attr_profile_20.attr, -+ &dev_attr_profile_21.attr, -+ &dev_attr_profile_22.attr, -+ &dev_attr_profile_23.attr, -+ &dev_attr_profile_24.attr, -+ &dev_attr_profile_25.attr, -+ &dev_attr_profile_26.attr, -+ &dev_attr_profile_27.attr, -+ &dev_attr_profile_28.attr, -+ &dev_attr_profile_29.attr, -+ &dev_attr_profile_30.attr, -+ &dev_attr_profile_31.attr, -+ NULL -+}; -+ -+static struct attribute *fm_dev_schemes_attributes[] = { -+ &dev_attr_scheme_0.attr, -+ &dev_attr_scheme_1.attr, -+ &dev_attr_scheme_2.attr, -+ &dev_attr_scheme_3.attr, -+ &dev_attr_scheme_4.attr, -+ &dev_attr_scheme_5.attr, -+ &dev_attr_scheme_6.attr, -+ &dev_attr_scheme_7.attr, -+ &dev_attr_scheme_8.attr, -+ &dev_attr_scheme_9.attr, -+ &dev_attr_scheme_10.attr, -+ &dev_attr_scheme_11.attr, -+ &dev_attr_scheme_12.attr, -+ &dev_attr_scheme_13.attr, -+ &dev_attr_scheme_14.attr, -+ &dev_attr_scheme_15.attr, -+ &dev_attr_scheme_16.attr, -+ &dev_attr_scheme_17.attr, -+ &dev_attr_scheme_18.attr, -+ &dev_attr_scheme_19.attr, -+ &dev_attr_scheme_20.attr, -+ &dev_attr_scheme_21.attr, -+ &dev_attr_scheme_22.attr, -+ &dev_attr_scheme_23.attr, -+ &dev_attr_scheme_24.attr, -+ &dev_attr_scheme_25.attr, -+ &dev_attr_scheme_26.attr, -+ &dev_attr_scheme_27.attr, -+ &dev_attr_scheme_28.attr, -+ &dev_attr_scheme_29.attr, -+ &dev_attr_scheme_30.attr, -+ &dev_attr_scheme_31.attr, -+ NULL -+}; -+ -+static const struct attribute_group fm_dev_stats_attr_grp = { -+ .name = "statistics", -+ .attrs = fm_dev_stats_attributes -+}; -+ -+static const struct attribute_group fm_dev_tnums_dbg_attr_grp = { -+ .name = "tnums_dbg", -+ .attrs = fm_dev_tnums_dbg_attributes -+}; -+ -+static const struct attribute_group fm_dev_cls_plans_attr_grp = { -+ .name = "cls_plans", -+ .attrs = fm_dev_cls_plans_attributes -+}; -+ -+static const struct attribute_group fm_dev_schemes_attr_grp = { -+ .name = "schemes", -+ .attrs = fm_dev_schemes_attributes -+}; -+ -+static const struct attribute_group fm_dev_profiles_attr_grp = { -+ .name = "profiles", -+ .attrs = fm_dev_profiles_attributes -+}; -+ -+static ssize_t show_fm_regs(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+#endif -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n"); -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev) -+ return -EIO; -+ else -+ n = fm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n); -+ -+ local_irq_restore(flags); -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ return n; -+} -+ -+static ssize_t show_fm_kg_pe_regs(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, -+ "\n FM-KG Port Partition Config registers dump.\n"); -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev) -+ return -EIO; -+ else -+ n = fm_kg_pe_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n); -+ -+ local_irq_restore(flags); -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ return n; -+} -+ -+static ssize_t show_fm_kg_regs(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "FM-KG registers dump.\n"); -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev) -+ return -EIO; -+ else -+ n = fm_kg_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n); -+ -+ local_irq_restore(flags); -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ return n; -+} -+ -+ -+static ssize_t show_fm_fpm_regs(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ -+ n = snprintf(buf, PAGE_SIZE, "FM-FPM registers dump.\n"); -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev) -+ return -EIO; -+ else -+ n = fm_fpm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n); -+ -+ local_irq_restore(flags); -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ return n; -+} -+ -+static ssize_t show_prs_regs(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n"); -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev) -+ return -EIO; -+ else -+ n = fm_prs_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n); -+ -+ local_irq_restore(flags); -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+ -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ return n; -+} -+ -+static ssize_t show_plcr_regs(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n"); -+ -+ if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev) -+ return -EIO; -+ else -+ n = fm_plcr_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n); -+ -+ local_irq_restore(flags); -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+ -+#endif /* (defined(DEBUG_ERRORS) && ... */ -+ -+ return n; -+} -+ -+static DEVICE_ATTR(fm_regs, S_IRUGO, show_fm_regs, NULL); -+static DEVICE_ATTR(fm_fpm_regs, S_IRUGO, show_fm_fpm_regs, NULL); -+static DEVICE_ATTR(fm_kg_regs, S_IRUGO, show_fm_kg_regs, NULL); -+static DEVICE_ATTR(fm_kg_pe_regs, S_IRUGO, show_fm_kg_pe_regs, NULL); -+static DEVICE_ATTR(fm_plcr_regs, S_IRUGO, show_plcr_regs, NULL); -+static DEVICE_ATTR(fm_prs_regs, S_IRUGO, show_prs_regs, NULL); -+static DEVICE_ATTR(fm_muram_free_size, S_IRUGO, show_fm_muram_free_sz, NULL); -+static DEVICE_ATTR(fm_ctrl_code_ver, S_IRUGO, show_fm_ctrl_code_ver, NULL); -+ -+int fm_sysfs_create(struct device *dev) -+{ -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+ -+ if (dev == NULL) -+ return -EIO; -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ -+ /* store to remove them when module is disabled */ -+ p_wrp_fm_dev->dev_attr_regs = &dev_attr_fm_regs; -+ p_wrp_fm_dev->dev_attr_risc_load = &dev_attr_fm_risc_load_val; -+ p_wrp_fm_dev->dev_fm_fpm_attr_regs = &dev_attr_fm_fpm_regs; -+ p_wrp_fm_dev->dev_fm_kg_attr_regs = &dev_attr_fm_kg_regs; -+ p_wrp_fm_dev->dev_fm_kg_pe_attr_regs = &dev_attr_fm_kg_pe_regs; -+ p_wrp_fm_dev->dev_plcr_attr_regs = &dev_attr_fm_plcr_regs; -+ p_wrp_fm_dev->dev_prs_attr_regs = &dev_attr_fm_prs_regs; -+ p_wrp_fm_dev->dev_attr_muram_free_size = &dev_attr_fm_muram_free_size; -+ p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver = &dev_attr_fm_ctrl_code_ver; -+ -+ /* Create sysfs statistics group for FM module */ -+ if (sysfs_create_group(&dev->kobj, &fm_dev_stats_attr_grp) != 0) -+ return -EIO; -+ -+ if (sysfs_create_group(&dev->kobj, &fm_dev_schemes_attr_grp) != 0) -+ return -EIO; -+ -+ if (sysfs_create_group(&dev->kobj, &fm_dev_profiles_attr_grp) != 0) -+ return -EIO; -+ -+ if (sysfs_create_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp) != 0) -+ return -EIO; -+ -+ if (sysfs_create_group(&dev->kobj, &fm_dev_cls_plans_attr_grp) != 0) -+ return -EIO; -+ -+ /* Registers dump entry - in future will be moved to debugfs */ -+ if (device_create_file(dev, &dev_attr_fm_regs) != 0) -+ return -EIO; -+ -+ if (device_create_file(dev, &dev_attr_fm_risc_load_val) != 0) -+ return -EIO; -+ -+ if (device_create_file(dev, &dev_attr_fm_fpm_regs) != 0) -+ return -EIO; -+ -+ if (device_create_file(dev, &dev_attr_fm_kg_regs) != 0) -+ return -EIO; -+ -+ if (device_create_file(dev, &dev_attr_fm_kg_pe_regs) != 0) -+ return -EIO; -+ -+ if (device_create_file(dev, &dev_attr_fm_plcr_regs) != 0) -+ return -EIO; -+ -+ if (device_create_file(dev, &dev_attr_fm_prs_regs) != 0) -+ return -EIO; -+ -+ /* muram free size */ -+ if (device_create_file(dev, &dev_attr_fm_muram_free_size) != 0) -+ return -EIO; -+ -+ /* fm ctrl code version */ -+ if (device_create_file(dev, &dev_attr_fm_ctrl_code_ver) != 0) -+ return -EIO; -+ -+ return 0; -+} -+ -+void fm_sysfs_destroy(struct device *dev) -+{ -+ t_LnxWrpFmDev *p_wrp_fm_dev = NULL; -+ -+ if (WARN_ON(dev == NULL)) -+ return; -+ -+ p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_wrp_fm_dev == NULL)) -+ return; -+ -+ sysfs_remove_group(&dev->kobj, &fm_dev_stats_attr_grp); -+ sysfs_remove_group(&dev->kobj, &fm_dev_schemes_attr_grp); -+ sysfs_remove_group(&dev->kobj, &fm_dev_profiles_attr_grp); -+ sysfs_remove_group(&dev->kobj, &fm_dev_cls_plans_attr_grp); -+ sysfs_remove_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp); -+ device_remove_file(dev, p_wrp_fm_dev->dev_attr_regs); -+ device_remove_file(dev, p_wrp_fm_dev->dev_fm_fpm_attr_regs); -+ device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_attr_regs); -+ device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_pe_attr_regs); -+ device_remove_file(dev, p_wrp_fm_dev->dev_plcr_attr_regs); -+ device_remove_file(dev, p_wrp_fm_dev->dev_prs_attr_regs); -+ device_remove_file(dev, p_wrp_fm_dev->dev_attr_muram_free_size); -+ device_remove_file(dev, p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver); -+} -+ -+int fm_dump_regs(void *h_fm, char *buf, int nn) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_fm; -+ uint8_t i = 0; -+ int n = nn; -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ FM_DMP_TITLE(buf, n, p_Fm->p_FmDmaRegs, "FM-DMA Regs"); -+ -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsr); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmemsr); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmmr); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtr); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmhy); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsetr); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtah); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtal); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtcid); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmra); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmrd); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmwcr); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmebcr); -+ FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmdcr); -+ -+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr, "fmdmplr"); -+ -+ for (i = 0; i < FM_MAX_NUM_OF_HW_PORT_IDS / 2 ; ++i) -+ FM_DMP_MEM_32(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[i]); -+ -+ FM_DMP_TITLE(buf, n, p_Fm->p_FmBmiRegs, "FM-BMI COMMON Regs"); -+ FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_init); -+ FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg1); -+ FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg2); -+ FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ievr); -+ FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ier); -+ -+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb, "fmbm_arb"); -+ for (i = 0; i < 8 ; ++i) -+ FM_DMP_MEM_32(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb[i]); -+ -+ FM_DMP_TITLE(buf, n, p_Fm->p_FmQmiRegs, "FM-QMI COMMON Regs"); -+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gc); -+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eie); -+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eien); -+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eif); -+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ie); -+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ien); -+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_if); -+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gs); -+ FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_etfc); -+ -+ return n; -+} -+ -+int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn) -+{ -+ t_Fm *p_Fm = (t_Fm *)h_fm; -+ uint8_t i, j = 0; -+ int n = nn; -+ -+ FM_DMP_TITLE(buf, n, NULL, "Tnums and Tnum dbg regs %d - %d", -+ tn_s, tn_e); -+ -+ iowrite32be(tn_s << 24, &p_Fm->p_FmFpmRegs->fmfp_dra); -+ -+ mb(); -+ -+ for (j = tn_s; j <= tn_e; j++) { -+ FM_DMP_LN(buf, n, "> fmfp_ts[%d]\n", j); -+ FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ts[j]); -+ FM_DMP_V32(buf, n, p_Fm->p_FmFpmRegs, fmfp_dra); -+ FM_DMP_LN(buf, n, "> fmfp_drd[0-3]\n"); -+ -+ for (i = 0; i < 4 ; ++i) -+ FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_drd[i]); -+ -+ FM_DMP_LN(buf, n, "\n"); -+ -+ } -+ -+ return n; -+} -+ -+int fm_dump_cls_plan(void *h_fm_pcd, int cpn, char *buf, int nn) -+{ -+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd; -+ int i = 0; -+ uint32_t tmp; -+ unsigned long i_flg; -+ int n = nn; -+ u_FmPcdKgIndirectAccessRegs *idac; -+ spinlock_t *p_lk; -+ -+ p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock; -+ idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs; -+ -+ spin_lock_irqsave(p_lk, i_flg); -+ -+ /* Read ClsPlan Block Action Regs */ -+ tmp = (uint32_t)(FM_KG_KGAR_GO | -+ FM_KG_KGAR_READ | -+ FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY | -+ DUMMY_PORT_ID | -+ ((uint32_t)cpn << FM_PCD_KG_KGAR_NUM_SHIFT) | -+ FM_PCD_KG_KGAR_WSEL_MASK); -+ -+ if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp)) { -+ FM_DMP_LN(buf, nn, "Keygen scheme access violation"); -+ spin_unlock_irqrestore(p_lk, i_flg); -+ return nn; -+ } -+ FM_DMP_TITLE(buf, n, &idac->clsPlanRegs, -+ "ClsPlan %d Indirect Access Regs", cpn); -+ -+ for (i = 0; i < 8; i++) -+ FM_DMP_MEM_32(buf, n, &idac->clsPlanRegs.kgcpe[i]); -+ -+ spin_unlock_irqrestore(p_lk, i_flg); -+ -+ return n; -+} -+ -+int fm_profile_dump_regs(void *h_fm_pcd, int ppn, char *buf, int nn) -+{ -+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd; -+ t_FmPcdPlcrProfileRegs *p_prof_regs; -+ t_FmPcdPlcrRegs *p_plcr_regs; -+ t_FmPcdPlcr *p_plcr; -+ uint32_t tmp; -+ unsigned long i_flg; -+ int n = nn; -+ int toc = 10; -+ spinlock_t *p_lk; -+ -+ p_plcr = p_pcd->p_FmPcdPlcr; -+ p_prof_regs = &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs; -+ p_plcr_regs = p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs; -+ -+ p_lk = (spinlock_t *)((t_FmPcdPlcr *)p_plcr)->h_HwSpinlock; -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_TITLE(buf, n, p_plcr_regs, "FM-PCD policer-profile regs"); -+ -+ tmp = (uint32_t)(FM_PCD_PLCR_PAR_GO | -+ FM_PCD_PLCR_PAR_R | -+ ((uint32_t)ppn << FM_PCD_PLCR_PAR_PNUM_SHIFT) | -+ FM_PCD_PLCR_PAR_PWSEL_MASK); -+ -+ spin_lock_irqsave(p_lk, i_flg); -+ -+ iowrite32be(tmp, &p_plcr_regs->fmpl_par); -+ -+ mb(); -+ -+ /* wait for the porfile regs to be present */ -+ do { -+ --toc; -+ udelay(10); -+ if (!toc) { -+ /* looks like PLCR_PAR_GO refuses to clear */ -+ spin_unlock_irqrestore(p_lk, i_flg); -+ FM_DMP_LN(buf, n, "Profile regs not accessible -"); -+ FM_DMP_LN(buf, n, " check profile init process\n"); -+ return n; -+ } -+ } while ((ioread32be(&p_plcr_regs->fmpl_par) & FM_PCD_PLCR_PAR_GO)); -+ -+ FM_DMP_TITLE(buf, n, p_prof_regs, "Profile %d regs", ppn); -+ -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pemode); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegnia); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_peynia); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pernia); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecir); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecbs); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepepir_eir); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepbs_ebs); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pelts); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pects); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepts_ets); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegpc); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_peypc); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_perpc); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_perypc); -+ FM_DMP_V32(buf, n, p_prof_regs, fmpl_perrpc); -+ -+ spin_unlock_irqrestore(p_lk, i_flg); -+ -+ return n; -+} -+ -+int fm_dump_scheme(void *h_fm_pcd, int scnum, char *buf, int nn) -+{ -+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd; -+ uint32_t tmp_ar; -+ unsigned long i_flg; -+ int i, n = nn; -+ spinlock_t *p_lk; -+ u_FmPcdKgIndirectAccessRegs *idac; -+ -+ idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs; -+ p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock; -+ -+ spin_lock_irqsave(p_lk, i_flg); -+ -+ tmp_ar = FmPcdKgBuildReadSchemeActionReg((uint8_t)scnum); -+ if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp_ar)) { -+ FM_DMP_LN(buf, nn, -+ "Keygen scheme access violation or no such scheme"); -+ spin_unlock_irqrestore(p_lk, i_flg); -+ return nn; -+ } -+ -+ FM_DMP_TITLE(buf, n, &idac->schemeRegs, -+ "Scheme %d Indirect Access Regs", scnum); -+ -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mode); -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekfc); -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekdv); -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmch); -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmcl); -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_fqb); -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_hc); -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ppc); -+ -+ FM_DMP_TITLE(buf, n, &idac->schemeRegs.kgse_gec, "kgse_gec"); -+ -+ for (i = 0; i < FM_KG_NUM_OF_GENERIC_REGS; i++) -+ FM_DMP_MEM_32(buf, n, &idac->schemeRegs.kgse_gec[i]); -+ -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_spc); -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv0); -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv1); -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ccbs); -+ FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mv); -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ spin_unlock_irqrestore(p_lk, i_flg); -+ -+ return n; -+} -+ -+int fm_kg_pe_dump_regs(void *h_fm_pcd, char *buf, int nn) -+{ -+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd; -+ int i = 0; -+ uint8_t prt_id = 0; -+ uint32_t tmp_ar; -+ unsigned long i_flg; -+ int n = nn; -+ u_FmPcdKgIndirectAccessRegs *idac; -+ t_FmPcdKg *p_kg; -+ spinlock_t *p_lk; -+ -+ p_kg = p_pcd->p_FmPcdKg; -+ idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs; -+ p_lk = (spinlock_t *)p_kg->h_HwSpinlock; -+ -+ spin_lock_irqsave(p_lk, i_flg); -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) { -+ SW_PORT_INDX_TO_HW_PORT_ID(prt_id, i); -+ -+ tmp_ar = FmPcdKgBuildReadPortSchemeBindActionReg(prt_id); -+ -+ if (fman_kg_write_ar_wait(p_kg->p_FmPcdKgRegs, tmp_ar)) { -+ FM_DMP_LN(buf, nn, "Keygen scheme access violation"); -+ spin_unlock_irqrestore(p_lk, i_flg); -+ return nn; -+ } -+ FM_DMP_TITLE(buf, n, &idac->portRegs, "Port %d regs", prt_id); -+ FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_sp); -+ FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_cpp); -+ } -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ spin_unlock_irqrestore(p_lk, i_flg); -+ -+ return n; -+} -+ -+int fm_kg_dump_regs(void *h_fm_pcd, char *buf, int nn) -+{ -+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd; -+ int n = nn; -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, -+ "FmPcdKgRegs Regs"); -+ -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gcr); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eer); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eeer); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seer); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seeer); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gsr); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_tpc); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_serc); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_fdor); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv0r); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv1r); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_feer); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_ar); -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ return n; -+} -+ -+ -+int fm_fpm_dump_regs(void *h_fm, char *buf, int nn) -+{ -+ t_Fm *p_fm = (t_Fm *)h_fm; -+ uint8_t i; -+ int n = nn; -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ FM_DMP_TITLE(buf, n, p_fm->p_FmFpmRegs, "FM-FPM Regs"); -+ -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tnc); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_prc); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_brkc); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_mxd); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist1); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist2); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_epi); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rie); -+ -+ FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev, "fmfp_fcev"); -+ for (i = 0; i < 4; ++i) -+ FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev[i]); -+ -+ FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee, "fmfp_cee"); -+ for (i = 0; i < 4; ++i) -+ FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee[i]); -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc1); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc2); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsp); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsf); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rcr); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_extc); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext1); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext2); -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_1); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_2); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rstc); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_cld); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_npi); -+ FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ee); -+ -+ FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev, "fmfp_cev"); -+ for (i = 0; i < 4; ++i) -+ FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev[i]); -+ -+ FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps, "fmfp_ps"); -+ for (i = 0; i < 64; ++i) -+ FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps[i]); -+ -+ return n; -+} -+ -+int fm_prs_dump_regs(void *h_fm_pcd, char *buf, int nn) -+{ -+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd; -+ int n = nn; -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, -+ "FM-PCD parser regs"); -+ -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpclim); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpimac); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, pmeec); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pevr); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pever); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perr); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perer); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_ppsc); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pds); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rrs); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rrs); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rrs); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srrs); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rres); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rres); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rres); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srres); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spcs); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spscs); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_hxscs); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrcs); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwcs); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrscs); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwscs); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_fcscs); -+ -+ return n; -+} -+ -+int fm_plcr_dump_regs(void *h_fm_pcd, char *buf, int nn) -+{ -+ t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd; -+ int i = 0; -+ int n = nn; -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ FM_DMP_TITLE(buf, n, -+ p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, -+ "FM policer regs"); -+ -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gcr); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gsr); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_evr); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ier); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ifr); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eevr); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eier); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eifr); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rpcnt); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ypcnt); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rrpcnt); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rypcnt); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_tpcnt); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_flmcnt); -+ -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_serc); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_upcr); -+ FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_dpmr); -+ -+ FM_DMP_TITLE(buf, n, -+ &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr, -+ "fmpl_pmr"); -+ -+ for (i = 0; i < 63; ++i) -+ FM_DMP_MEM_32(buf, n, -+ &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i]); -+ -+ return n; -+} -+ -+int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val) -+{ -+ t_Fm *p_fm = (t_Fm *)h_fm; -+ -+ /* When applicable (when there is an "enable counters" bit), -+ check that counters are enabled */ -+ -+ switch (cnt_e) { -+ case (e_FM_COUNTERS_DEQ_1): -+ case (e_FM_COUNTERS_DEQ_2): -+ case (e_FM_COUNTERS_DEQ_3): -+ if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6) -+ return -EINVAL; /* counter not available */ -+ -+ case (e_FM_COUNTERS_ENQ_TOTAL_FRAME): -+ case (e_FM_COUNTERS_DEQ_TOTAL_FRAME): -+ case (e_FM_COUNTERS_DEQ_0): -+ case (e_FM_COUNTERS_DEQ_FROM_DEFAULT): -+ case (e_FM_COUNTERS_DEQ_FROM_CONTEXT): -+ case (e_FM_COUNTERS_DEQ_FROM_FD): -+ case (e_FM_COUNTERS_DEQ_CONFIRM): -+ if (!(ioread32be(&p_fm->p_FmQmiRegs->fmqm_gc) & -+ QMI_CFG_EN_COUNTERS)) -+ return -EINVAL; /* Requested counter not available */ -+ break; -+ default: -+ break; -+ } -+ -+ switch (cnt_e) { -+ case (e_FM_COUNTERS_ENQ_TOTAL_FRAME): -+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_etfc); -+ return 0; -+ case (e_FM_COUNTERS_DEQ_TOTAL_FRAME): -+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dtfc); -+ return 0; -+ case (e_FM_COUNTERS_DEQ_0): -+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc0); -+ return 0; -+ case (e_FM_COUNTERS_DEQ_1): -+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc1); -+ return 0; -+ case (e_FM_COUNTERS_DEQ_2): -+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc2); -+ return 0; -+ case (e_FM_COUNTERS_DEQ_3): -+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc3); -+ return 0; -+ case (e_FM_COUNTERS_DEQ_FROM_DEFAULT): -+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfdc); -+ return 0; -+ case (e_FM_COUNTERS_DEQ_FROM_CONTEXT): -+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfcc); -+ return 0; -+ case (e_FM_COUNTERS_DEQ_FROM_FD): -+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dffc); -+ return 0; -+ case (e_FM_COUNTERS_DEQ_CONFIRM): -+ *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dcc); -+ return 0; -+ } -+ /* should never get here */ -+ return -EINVAL; /* counter not available */ -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h -@@ -0,0 +1,136 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+#ifndef LNXWRP_SYSFS_FM_H_ -+#define LNXWRP_SYSFS_FM_H_ -+ -+#include "lnxwrp_sysfs.h" -+ -+int fm_sysfs_create(struct device *dev); -+void fm_sysfs_destroy(struct device *dev); -+int fm_dump_regs(void *h_dev, char *buf, int nn); -+int fm_fpm_dump_regs(void *h_dev, char *buf, int nn); -+int fm_kg_dump_regs(void *h_pcd, char *buf, int nn); -+int fm_kg_pe_dump_regs(void *h_pcd, char *buf, int nn); -+int fm_dump_scheme(void *h_pcd, int scnum, char *buf, int nn); -+int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn); -+int fm_dump_cls_plan(void *h_pcd, int cpn, char *buf, int nn); -+int fm_plcr_dump_regs(void *h_pcd, char *buf, int nn); -+int fm_prs_dump_regs(void *h_pcd, char *buf, int nn); -+int fm_profile_dump_regs(void *h_pcd, int ppnum, char *buf, int nn); -+ -+#define FM_DMP_PGSZ_ERR { \ -+ snprintf(&buf[PAGE_SIZE - 80], 70, \ -+ "\n Err: current sysfs buffer reached PAGE_SIZE\n");\ -+ n = PAGE_SIZE - 2; \ -+ } -+ -+#define FM_DMP_LN(buf, n, ...) \ -+ do { \ -+ int k, m = n; \ -+ m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \ -+ if (k < 0 || m > PAGE_SIZE - 90) \ -+ FM_DMP_PGSZ_ERR \ -+ n = m; \ -+ } while (0) -+ -+#define FM_DMP_TITLE(buf, n, addr, ...) \ -+ do { \ -+ int k, m = n; \ -+ m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \ -+ if (k < 0 || m > PAGE_SIZE - 90) \ -+ FM_DMP_PGSZ_ERR \ -+ m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \ -+ if (k < 0 || m > PAGE_SIZE - 90) \ -+ FM_DMP_PGSZ_ERR \ -+ if (addr) { \ -+ phys_addr_t pa; \ -+ pa = virt_to_phys(addr); \ -+ m += k = \ -+ snprintf(&buf[m], PAGE_SIZE - m, " (0x%lX)", \ -+ (long unsigned int)(pa)); \ -+ if (k < 0 || m > PAGE_SIZE - 90) \ -+ FM_DMP_PGSZ_ERR \ -+ } \ -+ m += k = snprintf(&buf[m], PAGE_SIZE - m, \ -+ "\n----------------------------------------\n\n"); \ -+ if (k < 0 || m > PAGE_SIZE - 90) \ -+ FM_DMP_PGSZ_ERR \ -+ n = m; \ -+ } while (0) -+ -+#define FM_DMP_SUBTITLE(buf, n, ...) \ -+ do { \ -+ int k, m = n; \ -+ m += k = snprintf(&buf[m], PAGE_SIZE - m, "------- "); \ -+ if (k < 0 || m > PAGE_SIZE - 90) \ -+ FM_DMP_PGSZ_ERR \ -+ m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \ -+ if (k < 0 || m > PAGE_SIZE - 90) \ -+ FM_DMP_PGSZ_ERR \ -+ m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \ -+ if (k < 0 || m > PAGE_SIZE - 90) \ -+ FM_DMP_PGSZ_ERR \ -+ n = m; \ -+ } while (0) -+ -+#define FM_DMP_MEM_32(buf, n, addr) \ -+ { \ -+ uint32_t val; \ -+ phys_addr_t pa; \ -+ int k, m = n; \ -+ pa = virt_to_phys(addr); \ -+ val = ioread32be((addr)); \ -+ do { \ -+ m += k = snprintf(&buf[m], \ -+ PAGE_SIZE - m, "0x%010llX: 0x%08x\n", \ -+ pa, val); \ -+ if (k < 0 || m > PAGE_SIZE - 90) \ -+ FM_DMP_PGSZ_ERR \ -+ n += k; \ -+ } while (0) ;\ -+ } -+ -+#define FM_DMP_V32(buf, n, st, phrase) \ -+ do { \ -+ int k, m = n; \ -+ phys_addr_t pa = virt_to_phys(&((st)->phrase)); \ -+ k = snprintf(&buf[m], PAGE_SIZE - m, \ -+ "0x%010llX: 0x%08x%8s\t%s\n", (unsigned long long) pa, \ -+ ioread32be((uint32_t *)&((st)->phrase)), "", #phrase); \ -+ if (k < 0 || m > PAGE_SIZE - 90) \ -+ FM_DMP_PGSZ_ERR \ -+ n += k; \ -+ } while (0) -+ -+#endif /* LNXWRP_SYSFS_FM_H_ */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c -@@ -0,0 +1,1268 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "lnxwrp_sysfs.h" -+#include "lnxwrp_fm.h" -+#include "debug_ext.h" -+#include "lnxwrp_sysfs_fm_port.h" -+#include "lnxwrp_sysfs_fm.h" -+ -+#include "../../sdk_fman/Peripherals/FM/Port/fm_port.h" -+#include "../../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h" -+ -+#if defined(__ERR_MODULE__) -+#undef __ERR_MODULE__ -+#endif -+ -+#include "../../sdk_fman/Peripherals/FM/fm.h" -+ -+static const struct sysfs_stats_t portSysfsStats[] = { -+ /* RX/TX/OH common statistics */ -+ { -+ .stat_name = "port_frame", -+ .stat_counter = e_FM_PORT_COUNTERS_FRAME, -+ }, -+ { -+ .stat_name = "port_discard_frame", -+ .stat_counter = e_FM_PORT_COUNTERS_DISCARD_FRAME, -+ }, -+ { -+ .stat_name = "port_dealloc_buf", -+ .stat_counter = e_FM_PORT_COUNTERS_DEALLOC_BUF, -+ }, -+ { -+ .stat_name = "port_enq_total", -+ .stat_counter = e_FM_PORT_COUNTERS_ENQ_TOTAL, -+ }, -+ /* TX/OH */ -+ { -+ .stat_name = "port_length_err", -+ .stat_counter = e_FM_PORT_COUNTERS_LENGTH_ERR, -+ }, -+ { -+ .stat_name = "port_unsupprted_format", -+ .stat_counter = e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, -+ }, -+ { -+ .stat_name = "port_deq_total", -+ .stat_counter = e_FM_PORT_COUNTERS_DEQ_TOTAL, -+ }, -+ { -+ .stat_name = "port_deq_from_default", -+ .stat_counter = e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, -+ }, -+ { -+ .stat_name = "port_deq_confirm", -+ .stat_counter = e_FM_PORT_COUNTERS_DEQ_CONFIRM, -+ }, -+ /* RX/OH */ -+ { -+ .stat_name = "port_rx_bad_frame", -+ .stat_counter = e_FM_PORT_COUNTERS_RX_BAD_FRAME, -+ }, -+ { -+ .stat_name = "port_rx_large_frame", -+ .stat_counter = e_FM_PORT_COUNTERS_RX_LARGE_FRAME, -+ }, -+ { -+ .stat_name = "port_rx_out_of_buffers_discard", -+ .stat_counter = e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, -+ }, -+ { -+ .stat_name = "port_rx_filter_frame", -+ .stat_counter = e_FM_PORT_COUNTERS_RX_FILTER_FRAME, -+ }, -+ /* TODO: Particular statistics for OH ports */ -+ {} -+}; -+ -+static ssize_t show_fm_port_stats(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+ t_LnxWrpFmDev *p_LnxWrpFmDev; -+ unsigned long flags; -+ int n = 0; -+ uint8_t counter = 0; -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+ p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_LnxWrpFmPortDev == NULL)) -+ return -EINVAL; -+ -+ p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ if (WARN_ON(p_LnxWrpFmDev == NULL)) -+ return -EINVAL; -+ -+ if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev) -+ return -EIO; -+ -+ if (!p_LnxWrpFmPortDev->h_Dev) { -+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n"); -+ return n; -+ } -+ -+ counter = fm_find_statistic_counter_by_name( -+ attr->attr.name, -+ portSysfsStats, NULL); -+ -+ if (counter == e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR) { -+ uint32_t fmRev = 0; -+ fmRev = 0xffff & -+ ioread32(UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr + -+ 0x000c30c4)); -+ -+ if (fmRev == 0x0100) { -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "counter not available for revision 1\n"); -+ local_irq_restore(flags); -+ } -+ return n; -+ } -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, "\t%s counter: %u\n", -+ p_LnxWrpFmPortDev->name, -+ FM_PORT_GetCounter(p_LnxWrpFmPortDev->h_Dev, -+ (e_FmPortCounters) counter)); -+ local_irq_restore(flags); -+ -+ return n; -+} -+ -+/* FM PORT RX/TX/OH statistics */ -+static DEVICE_ATTR(port_frame, S_IRUGO, show_fm_port_stats, NULL); -+static DEVICE_ATTR(port_discard_frame, S_IRUGO, show_fm_port_stats, NULL); -+static DEVICE_ATTR(port_dealloc_buf, S_IRUGO, show_fm_port_stats, NULL); -+static DEVICE_ATTR(port_enq_total, S_IRUGO, show_fm_port_stats, NULL); -+/* FM PORT TX/OH statistics */ -+static DEVICE_ATTR(port_length_err, S_IRUGO, show_fm_port_stats, NULL); -+static DEVICE_ATTR(port_unsupprted_format, S_IRUGO, show_fm_port_stats, NULL); -+static DEVICE_ATTR(port_deq_total, S_IRUGO, show_fm_port_stats, NULL); -+static DEVICE_ATTR(port_deq_from_default, S_IRUGO, show_fm_port_stats, NULL); -+static DEVICE_ATTR(port_deq_confirm, S_IRUGO, show_fm_port_stats, NULL); -+/* FM PORT RX/OH statistics */ -+static DEVICE_ATTR(port_rx_bad_frame, S_IRUGO, show_fm_port_stats, NULL); -+static DEVICE_ATTR(port_rx_large_frame, S_IRUGO, show_fm_port_stats, NULL); -+static DEVICE_ATTR(port_rx_out_of_buffers_discard, S_IRUGO, -+ show_fm_port_stats, NULL); -+static DEVICE_ATTR(port_rx_filter_frame, S_IRUGO, show_fm_port_stats, NULL); -+ -+/* FM PORT TX statistics */ -+static struct attribute *fm_tx_port_dev_stats_attributes[] = { -+ &dev_attr_port_frame.attr, -+ &dev_attr_port_discard_frame.attr, -+ &dev_attr_port_dealloc_buf.attr, -+ &dev_attr_port_enq_total.attr, -+ &dev_attr_port_length_err.attr, -+ &dev_attr_port_unsupprted_format.attr, -+ &dev_attr_port_deq_total.attr, -+ &dev_attr_port_deq_from_default.attr, -+ &dev_attr_port_deq_confirm.attr, -+ NULL -+}; -+ -+static const struct attribute_group fm_tx_port_dev_stats_attr_grp = { -+ .name = "statistics", -+ .attrs = fm_tx_port_dev_stats_attributes -+}; -+ -+/* FM PORT RX statistics */ -+static struct attribute *fm_rx_port_dev_stats_attributes[] = { -+ &dev_attr_port_frame.attr, -+ &dev_attr_port_discard_frame.attr, -+ &dev_attr_port_dealloc_buf.attr, -+ &dev_attr_port_enq_total.attr, -+ &dev_attr_port_rx_bad_frame.attr, -+ &dev_attr_port_rx_large_frame.attr, -+ &dev_attr_port_rx_out_of_buffers_discard.attr, -+ &dev_attr_port_rx_filter_frame.attr, -+ NULL -+}; -+ -+static const struct attribute_group fm_rx_port_dev_stats_attr_grp = { -+ .name = "statistics", -+ .attrs = fm_rx_port_dev_stats_attributes -+}; -+ -+/* TODO: add particular OH ports statistics */ -+static struct attribute *fm_oh_port_dev_stats_attributes[] = { -+ &dev_attr_port_frame.attr, -+ &dev_attr_port_discard_frame.attr, -+ &dev_attr_port_dealloc_buf.attr, -+ &dev_attr_port_enq_total.attr, -+ /*TX*/ &dev_attr_port_length_err.attr, -+ &dev_attr_port_unsupprted_format.attr, -+ &dev_attr_port_deq_total.attr, -+ &dev_attr_port_deq_from_default.attr, -+ &dev_attr_port_deq_confirm.attr, -+ /* &dev_attr_port_rx_bad_frame.attr, */ -+ /* &dev_attr_port_rx_large_frame.attr, */ -+ &dev_attr_port_rx_out_of_buffers_discard.attr, -+ /*&dev_attr_port_rx_filter_frame.attr, */ -+ NULL -+}; -+ -+static const struct attribute_group fm_oh_port_dev_stats_attr_grp = { -+ .name = "statistics", -+ .attrs = fm_oh_port_dev_stats_attributes -+}; -+ -+static ssize_t show_fm_port_regs(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+#endif -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_LnxWrpFmPortDev = -+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev); -+ -+ -+ local_irq_save(flags); -+ -+ if (!p_LnxWrpFmPortDev->h_Dev) { -+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n"); -+ return n; -+ } else { -+ n = snprintf(buf, PAGE_SIZE, -+ "FM port driver registers dump.\n"); -+ n = fm_port_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n); -+ } -+ -+ local_irq_restore(flags); -+ -+ return n; -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+ -+ return n; -+#endif -+} -+static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn) -+{ -+ t_FmPort *p_FmPort; -+ t_Fm *p_Fm; -+ uint8_t hardwarePortId; -+ uint32_t *param_page; -+ t_ArCommonDesc *ArCommonDescPtr; -+ uint32_t *mem; -+ int i, n = nn; -+ -+ p_FmPort = (t_FmPort *)h_dev; -+ hardwarePortId = p_FmPort->hardwarePortId; -+ p_Fm = (t_Fm *)p_FmPort->h_Fm; -+ -+ if (!FM_PORT_IsInDsar(p_FmPort)) -+ { -+ FM_DMP_LN(buf, n, "port %u is not a DSAR port\n", -+ hardwarePortId); -+ return n; -+ } -+ FM_DMP_LN(buf, n, "port %u DSAR mem\n", hardwarePortId); -+ FM_DMP_LN(buf, n, "========================\n"); -+ -+ /* do I need request_mem_region here? */ -+ param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4); -+ ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), 300*4)); /* this should be changed*/ -+ mem = (uint32_t*)ArCommonDescPtr; -+ for (i = 0; i < 300; i+=4) -+ FM_DMP_LN(buf, n, "%08x: %08x %08x %08x %08x\n", i*4, mem[i], mem[i + 1], mem[i + 2], mem[i + 3]); -+ iounmap(ArCommonDescPtr); -+ iounmap(param_page); -+ return n; -+} -+ -+static int fm_port_dsar_dump_regs(void *h_dev, char *buf, int nn) -+{ -+ t_FmPort *p_FmPort; -+ t_Fm *p_Fm; -+ uint8_t hardwarePortId; -+ uint32_t *param_page; -+ t_ArCommonDesc *ArCommonDescPtr; -+ int i, n = nn; -+ -+ p_FmPort = (t_FmPort *)h_dev; -+ hardwarePortId = p_FmPort->hardwarePortId; -+ p_Fm = (t_Fm *)p_FmPort->h_Fm; -+ -+ if (!FM_PORT_IsInDsar(p_FmPort)) -+ { -+ FM_DMP_LN(buf, n, "port %u is not a DSAR port\n", -+ hardwarePortId); -+ return n; -+ } -+ FM_DMP_LN(buf, n, "port %u DSAR information\n", hardwarePortId); -+ FM_DMP_LN(buf, n, "========================\n"); -+ -+ /* do I need request_mem_region here? */ -+ param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4); -+ ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/ -+ FM_DMP_LN(buf, n, "Tx port: 0x%x\n", ArCommonDescPtr->arTxPort); -+ FM_DMP_LN(buf, n, "Active HPNIA: 0x%08x\n", ArCommonDescPtr->activeHPNIA); -+ FM_DMP_LN(buf, n, "Snmp port: 0x%x\n", ArCommonDescPtr->snmpPort); -+ FM_DMP_LN(buf, n, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ArCommonDescPtr->macStationAddr[0], -+ ArCommonDescPtr->macStationAddr[1], ArCommonDescPtr->macStationAddr[2], -+ ArCommonDescPtr->macStationAddr[3], ArCommonDescPtr->macStationAddr[4], -+ ArCommonDescPtr->macStationAddr[5]); -+ FM_DMP_LN(buf, n, "filterControl: 0x%02x\n", ArCommonDescPtr->filterControl); -+ FM_DMP_LN(buf, n, "tcpControlPass: 0x%04x\n", ArCommonDescPtr->tcpControlPass); -+ FM_DMP_LN(buf, n, "ipProtocolTblSize: 0x%x\n", ArCommonDescPtr->ipProtocolTblSize); -+ FM_DMP_LN(buf, n, "udpPortTblSize: 0x%x\n", ArCommonDescPtr->udpPortTblSize); -+ FM_DMP_LN(buf, n, "tcpPortTblSize: 0x%x\n", ArCommonDescPtr->tcpPortTblSize); -+ if (ArCommonDescPtr->p_ArStats) -+ { -+ t_ArStatistics *arStatistics = (t_ArStatistics*) -+ ioremap(ioread32be(&ArCommonDescPtr->p_ArStats) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ sizeof (t_ArStatistics)); -+ FM_DMP_LN(buf, n, "\nDSAR statistics\n"); -+ FM_DMP_LN(buf, n, "DSAR_Discarded: 0x%x\n", arStatistics->dsarDiscarded); -+ FM_DMP_LN(buf, n, "DSAR_Err_Discarded: 0x%x\n", arStatistics->dsarErrDiscarded); -+ FM_DMP_LN(buf, n, "DSAR_Frag_Discarded: 0x%x\n", arStatistics->dsarFragDiscarded); -+ FM_DMP_LN(buf, n, "DSAR_Tunnel_Discarded: 0x%x\n", arStatistics->dsarTunnelDiscarded); -+ FM_DMP_LN(buf, n, "DSAR_ARP_Discarded: 0x%x\n", arStatistics->dsarArpDiscarded); -+ FM_DMP_LN(buf, n, "DSAR_IP_Discarded: 0x%x\n", arStatistics->dsarIpDiscarded); -+ FM_DMP_LN(buf, n, "DSAR_TCP_Discarded: 0x%x\n", arStatistics->dsarTcpDiscarded); -+ FM_DMP_LN(buf, n, "DSAR_UDP_Discarded: 0x%x\n", arStatistics->dsarUdpDiscarded); -+ FM_DMP_LN(buf, n, "DSAR_ICMPv6_Checksum_Err: 0x%x\n", arStatistics->dsarIcmpV6ChecksumErr); -+ FM_DMP_LN(buf, n, "DSAR_ICMPv6_Other_Type: 0x%x\n", arStatistics->dsarIcmpV6OtherType); -+ FM_DMP_LN(buf, n, "DSAR_ICMPv4_Other_Type: 0x%x\n", arStatistics->dsarIcmpV4OtherType); -+ -+ iounmap(arStatistics); -+ } -+ if (ArCommonDescPtr->p_ArpDescriptor) -+ { -+ t_DsarArpDescriptor* ArpDescriptor = (t_DsarArpDescriptor*) -+ ioremap(ioread32be(&ArCommonDescPtr->p_ArpDescriptor) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ sizeof (t_DsarArpDescriptor)); -+ FM_DMP_LN(buf, n, "\nARP\n"); -+ FM_DMP_LN(buf, n, "===\n"); -+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", ArpDescriptor->control); -+ if (ArpDescriptor->numOfBindings) -+ { -+ char ip_str[100]; -+ t_DsarArpBindingEntry* bindings = ioremap( -+ ioread32be(&ArpDescriptor->p_Bindings) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ ArpDescriptor->numOfBindings * -+ sizeof(t_DsarArpBindingEntry)); -+ uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr; -+ FM_DMP_LN(buf, n, " ip vlan id\n"); -+ for (i = 0; i < ArpDescriptor->numOfBindings; i++) -+ { -+ n += snprintf(ip_str, 100, "%d.%d.%d.%d", -+ ip_addr[0], ip_addr[1], -+ ip_addr[2], ip_addr[3]); -+ FM_DMP_LN(buf, n, "%-15s 0x%x\n", -+ ip_str, bindings->vlanId); -+ } -+ iounmap(bindings); -+ } -+ if (ArpDescriptor->p_Statistics) -+ { -+ t_DsarArpStatistics* arpStats = ioremap( -+ ioread32be(&ArpDescriptor->p_Statistics) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ sizeof(t_DsarArpStatistics)); -+ FM_DMP_LN(buf, n, "statistics\n"); -+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", arpStats->invalCnt); -+ FM_DMP_LN(buf, n, "ECHO_CNT: 0x%x\n", arpStats->echoCnt); -+ FM_DMP_LN(buf, n, "CD_CNT: 0x%x\n", arpStats->cdCnt); -+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", arpStats->arCnt); -+ FM_DMP_LN(buf, n, "RATM_CNT: 0x%x\n", arpStats->ratmCnt); -+ FM_DMP_LN(buf, n, "UKOP_CNT: 0x%x\n", arpStats->ukopCnt); -+ FM_DMP_LN(buf, n, "NMTP_CNT: 0x%x\n", arpStats->nmtpCnt); -+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", arpStats->nmVlanCnt); -+ iounmap(arpStats); -+ } -+ -+ iounmap(ArpDescriptor); -+ } -+ if (ArCommonDescPtr->p_IcmpV4Descriptor) -+ { -+ t_DsarIcmpV4Descriptor* ICMPV4Descriptor = -+ (t_DsarIcmpV4Descriptor*)ioremap(ioread32be( -+ &ArCommonDescPtr->p_IcmpV4Descriptor) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ sizeof (t_DsarIcmpV4Descriptor)); -+ FM_DMP_LN(buf, n, "\nEcho ICMPv4\n"); -+ FM_DMP_LN(buf, n, "===========\n"); -+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV4Descriptor->control); -+ if (ICMPV4Descriptor->numOfBindings) -+ { -+ char ip_str[100]; -+ t_DsarArpBindingEntry* bindings = ioremap( -+ ioread32be(&ICMPV4Descriptor->p_Bindings) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ ICMPV4Descriptor->numOfBindings * -+ sizeof(t_DsarArpBindingEntry)); -+ uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr; -+ FM_DMP_LN(buf, n, " ip vlan id\n"); -+ for (i = 0; i < ICMPV4Descriptor->numOfBindings; i++) -+ { -+ n += snprintf(ip_str, 100, "%d.%d.%d.%d", -+ ip_addr[0], ip_addr[1], -+ ip_addr[2], ip_addr[3]); -+ FM_DMP_LN(buf, n, "%-15s 0x%x\n", -+ ip_str, bindings->vlanId); -+ } -+ iounmap(bindings); -+ } -+ if (ICMPV4Descriptor->p_Statistics) -+ { -+ t_DsarIcmpV4Statistics* icmpv4Stats = ioremap( -+ ioread32be(&ICMPV4Descriptor->p_Statistics) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ sizeof(t_DsarIcmpV4Statistics)); -+ FM_DMP_LN(buf, n, "statistics\n"); -+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv4Stats->invalCnt); -+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv4Stats->nmVlanCnt); -+ FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv4Stats->nmIpCnt); -+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv4Stats->arCnt); -+ FM_DMP_LN(buf, n, "CSERR_CNT: 0x%x\n", icmpv4Stats->cserrCnt); -+ iounmap(icmpv4Stats); -+ } -+ iounmap(ICMPV4Descriptor); -+ } -+ if (ArCommonDescPtr->p_NdDescriptor) -+ { -+ t_DsarNdDescriptor *NDDescriptor = -+ (t_DsarNdDescriptor*)ioremap(ioread32be( -+ &ArCommonDescPtr->p_NdDescriptor) + p_FmPort-> -+ fmMuramPhysBaseAddr, sizeof (t_DsarNdDescriptor)); -+ FM_DMP_LN(buf, n, "\nNDP\n"); -+ FM_DMP_LN(buf, n, "===\n"); -+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", NDDescriptor->control); -+ FM_DMP_LN(buf, n, "solicited address 0x%08x\n", NDDescriptor->solicitedAddr); -+ if (NDDescriptor->numOfBindings) -+ { -+ char ip_str[100]; -+ t_DsarIcmpV6BindingEntry* bindings = ioremap( -+ ioread32be(&NDDescriptor->p_Bindings) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ NDDescriptor->numOfBindings * -+ sizeof(t_DsarIcmpV6BindingEntry)); -+ uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr; -+ FM_DMP_LN(buf, n, " ip vlan id\n"); -+ for (i = 0; i < NDDescriptor->numOfBindings; i++) -+ { -+ n += snprintf(ip_str, 100, -+ "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", -+ ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], -+ ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]); -+ FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId); -+ } -+ iounmap(bindings); -+ } -+ if (NDDescriptor->p_Statistics) -+ { -+ t_NdStatistics* ndStats = ioremap( -+ ioread32be(&NDDescriptor->p_Statistics) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ sizeof(t_NdStatistics)); -+ FM_DMP_LN(buf, n, "statistics\n"); -+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", ndStats->invalCnt); -+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", ndStats->nmVlanCnt); -+ FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", ndStats->nmIpCnt); -+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", ndStats->arCnt); -+ FM_DMP_LN(buf, n, "USADVERT_CNT: 0x%x\n", ndStats->usadvertCnt); -+ FM_DMP_LN(buf, n, "NMMCAST_CNT: 0x%x\n", ndStats->nmmcastCnt); -+ FM_DMP_LN(buf, n, "NSLLA_CNT: 0x%x\n", ndStats->nsllaCnt); -+ iounmap(ndStats); -+ } -+ iounmap(NDDescriptor); -+ } -+ if (ArCommonDescPtr->p_IcmpV6Descriptor) -+ { -+ t_DsarIcmpV6Descriptor *ICMPV6Descriptor = -+ (t_DsarIcmpV6Descriptor*)ioremap(ioread32be( -+ &ArCommonDescPtr->p_IcmpV6Descriptor) + p_FmPort-> -+ fmMuramPhysBaseAddr, sizeof (t_DsarIcmpV6Descriptor)); -+ FM_DMP_LN(buf, n, "\nEcho ICMPv6\n"); -+ FM_DMP_LN(buf, n, "===========\n"); -+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV6Descriptor->control); -+ if (ICMPV6Descriptor->numOfBindings) -+ { -+ char ip_str[100]; -+ t_DsarIcmpV6BindingEntry* bindings = ioremap( -+ ioread32be(&ICMPV6Descriptor->p_Bindings) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ ICMPV6Descriptor->numOfBindings * -+ sizeof(t_DsarIcmpV6BindingEntry)); -+ uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr; -+ FM_DMP_LN(buf, n, " ip vlan id\n"); -+ for (i = 0; i < ICMPV6Descriptor->numOfBindings; i++) -+ { -+ n += snprintf(ip_str, 100, -+ "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", -+ ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3], -+ ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]); -+ FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId); -+ } -+ iounmap(bindings); -+ } -+ if (ICMPV6Descriptor->p_Statistics) -+ { -+ t_DsarIcmpV6Statistics* icmpv6Stats = ioremap( -+ ioread32be(&ICMPV6Descriptor->p_Statistics) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ sizeof(t_DsarIcmpV6Statistics)); -+ FM_DMP_LN(buf, n, "statistics\n"); -+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv6Stats->invalCnt); -+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv6Stats->nmVlanCnt); -+ FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv6Stats->nmIpCnt); -+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv6Stats->arCnt); -+ iounmap(icmpv6Stats); -+ } -+ iounmap(ICMPV6Descriptor); -+ } -+ if (ArCommonDescPtr->p_SnmpDescriptor) -+ { -+ t_DsarSnmpDescriptor *SnmpDescriptor = -+ (t_DsarSnmpDescriptor*)ioremap(ioread32be( -+ &ArCommonDescPtr->p_SnmpDescriptor) + p_FmPort-> -+ fmMuramPhysBaseAddr, sizeof (t_DsarSnmpDescriptor)); -+ FM_DMP_LN(buf, n, "\nSNMP\n"); -+ FM_DMP_LN(buf, n, "===========\n"); -+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", SnmpDescriptor->control); -+ FM_DMP_LN(buf, n, "max message length 0x%04x\n", SnmpDescriptor->maxSnmpMsgLength); -+ if (SnmpDescriptor->numOfIpv4Addresses) -+ { -+ char ip_str[100]; -+ t_DsarSnmpIpv4AddrTblEntry* addrs = ioremap( -+ ioread32be(&SnmpDescriptor->p_Ipv4AddrTbl) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ SnmpDescriptor->numOfIpv4Addresses * -+ sizeof(t_DsarSnmpIpv4AddrTblEntry)); -+ uint8_t* ip_addr = (uint8_t*)&addrs->ipv4Addr; -+ FM_DMP_LN(buf, n, " ip vlan id\n"); -+ for (i = 0; i < SnmpDescriptor->numOfIpv4Addresses; i++) -+ { -+ n += snprintf(ip_str, 100, "%d.%d.%d.%d", -+ ip_addr[0], ip_addr[1], -+ ip_addr[2], ip_addr[3]); -+ FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, addrs->vlanId); -+ } -+ iounmap(addrs); -+ } -+ if (SnmpDescriptor->p_Statistics) -+ { -+ t_DsarSnmpStatistics* snmpStats = ioremap( -+ ioread32be(&SnmpDescriptor->p_Statistics) + -+ p_FmPort->fmMuramPhysBaseAddr, -+ sizeof(t_DsarSnmpStatistics)); -+ FM_DMP_LN(buf, n, "statistics\n"); -+ FM_DMP_LN(buf, n, "snmpErrCnt: 0x%x\n", snmpStats->snmpErrCnt); -+ FM_DMP_LN(buf, n, "snmpCommunityErrCnt: 0x%x\n", snmpStats->snmpCommunityErrCnt); -+ FM_DMP_LN(buf, n, "snmpTotalDiscardCnt: 0x%x\n", snmpStats->snmpTotalDiscardCnt); -+ FM_DMP_LN(buf, n, "snmpGetReqCnt: 0x%x\n", snmpStats->snmpGetReqCnt); -+ FM_DMP_LN(buf, n, "snmpGetNextReqCnt: 0x%x\n", snmpStats->snmpGetNextReqCnt); -+ iounmap(snmpStats); -+ } -+ iounmap(SnmpDescriptor); -+ } -+ iounmap(ArCommonDescPtr); -+ iounmap(param_page); -+ return n; -+} -+ -+static ssize_t show_fm_port_dsar_mem(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+#endif -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_LnxWrpFmPortDev = -+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev); -+ -+ local_irq_save(flags); -+ -+ if (!p_LnxWrpFmPortDev->h_Dev) { -+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n"); -+ return n; -+ } else { -+ n = snprintf(buf, PAGE_SIZE, -+ "FM port driver registers dump.\n"); -+ n = fm_port_dsar_dump_mem(p_LnxWrpFmPortDev->h_Dev, buf, n); -+ } -+ -+ local_irq_restore(flags); -+ -+ return n; -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+ -+ return n; -+#endif -+} -+ -+static ssize_t show_fm_port_dsar_regs(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+#endif -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_LnxWrpFmPortDev = -+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev); -+ -+ local_irq_save(flags); -+ -+ if (!p_LnxWrpFmPortDev->h_Dev) { -+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n"); -+ return n; -+ } else { -+ n = snprintf(buf, PAGE_SIZE, -+ "FM port driver registers dump.\n"); -+ n = fm_port_dsar_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n); -+ } -+ -+ local_irq_restore(flags); -+ -+ return n; -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+ -+ return n; -+#endif -+} -+ -+#if (DPAA_VERSION >= 11) -+static ssize_t show_fm_port_ipv4_options(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_LnxWrpFmPortDev = -+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev); -+ -+ local_irq_save(flags); -+ -+ if (!p_LnxWrpFmPortDev->h_Dev) { -+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n"); -+ return n; -+ } else if (((t_FmPort *)p_LnxWrpFmPortDev->h_Dev)->p_ParamsPage -+ == NULL) { -+ n = snprintf(buf, PAGE_SIZE, -+ "\tPort: FMan-controller params page not set\n"); -+ return n; -+ } else { -+ n = snprintf(buf, PAGE_SIZE, -+ "Counter for fragmented pkt with IP header options\n"); -+ n = fm_port_dump_ipv4_opt(p_LnxWrpFmPortDev->h_Dev, buf, n); -+ } -+ -+ local_irq_restore(flags); -+ -+ return n; -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+ -+ return n; -+#endif -+} -+ -+#endif -+ -+static ssize_t show_fm_port_bmi_regs(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_LnxWrpFmPortDev = -+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev); -+ -+ local_irq_save(flags); -+ -+ if (!p_LnxWrpFmPortDev->h_Dev) { -+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n"); -+ return n; -+ } else { -+ n = snprintf(buf, PAGE_SIZE, -+ "FM port driver registers dump.\n"); -+ n = fm_port_dump_regs_bmi(p_LnxWrpFmPortDev->h_Dev, buf, n); -+ } -+ -+ local_irq_restore(flags); -+ -+ return n; -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+ -+ return n; -+#endif -+} -+ -+static ssize_t show_fm_port_qmi_regs(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ unsigned long flags; -+ unsigned n = 0; -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+#endif -+ -+ if (attr == NULL || buf == NULL || dev == NULL) -+ return -EINVAL; -+ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ p_LnxWrpFmPortDev = -+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev); -+ -+ local_irq_save(flags); -+ -+ if (!p_LnxWrpFmPortDev->h_Dev) { -+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n"); -+ return n; -+ } else { -+ n = snprintf(buf, PAGE_SIZE, -+ "FM port driver registers dump.\n"); -+ n = fm_port_dump_regs_qmi(p_LnxWrpFmPortDev->h_Dev, buf, n); -+ } -+ -+ local_irq_restore(flags); -+ -+ return n; -+#else -+ -+ local_irq_save(flags); -+ n = snprintf(buf, PAGE_SIZE, -+ "Debug level is too low to dump registers!!!\n"); -+ local_irq_restore(flags); -+ -+ return n; -+#endif -+} -+ -+static DEVICE_ATTR(fm_port_regs, S_IRUGO | S_IRUSR, show_fm_port_regs, NULL); -+static DEVICE_ATTR(fm_port_qmi_regs, S_IRUGO | S_IRUSR, show_fm_port_qmi_regs, NULL); -+static DEVICE_ATTR(fm_port_bmi_regs, S_IRUGO | S_IRUSR, show_fm_port_bmi_regs, NULL); -+#if (DPAA_VERSION >= 11) -+static DEVICE_ATTR(fm_port_ipv4_opt, S_IRUGO | S_IRUSR, show_fm_port_ipv4_options, NULL); -+#endif -+static DEVICE_ATTR(fm_port_dsar_regs, S_IRUGO | S_IRUSR, show_fm_port_dsar_regs, NULL); -+static DEVICE_ATTR(fm_port_dsar_mem, S_IRUGO | S_IRUSR, show_fm_port_dsar_mem, NULL); -+ -+int fm_port_sysfs_create(struct device *dev) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev; -+ -+ if (dev == NULL) -+ return -EINVAL; -+ -+ p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_LnxWrpFmPortDev == NULL)) -+ return -EINVAL; -+ -+ /* store to remove them when module is disabled */ -+ p_LnxWrpFmPortDev->dev_attr_regs = &dev_attr_fm_port_regs; -+ p_LnxWrpFmPortDev->dev_attr_qmi_regs = &dev_attr_fm_port_qmi_regs; -+ p_LnxWrpFmPortDev->dev_attr_bmi_regs = &dev_attr_fm_port_bmi_regs; -+#if (DPAA_VERSION >= 11) -+ p_LnxWrpFmPortDev->dev_attr_ipv4_opt = &dev_attr_fm_port_ipv4_opt; -+#endif -+ p_LnxWrpFmPortDev->dev_attr_dsar_regs = &dev_attr_fm_port_dsar_regs; -+ p_LnxWrpFmPortDev->dev_attr_dsar_mem = &dev_attr_fm_port_dsar_mem; -+ /* Registers dump entry - in future will be moved to debugfs */ -+ if (device_create_file(dev, &dev_attr_fm_port_regs) != 0) -+ return -EIO; -+ if (device_create_file(dev, &dev_attr_fm_port_qmi_regs) != 0) -+ return -EIO; -+ if (device_create_file(dev, &dev_attr_fm_port_bmi_regs) != 0) -+ return -EIO; -+#if (DPAA_VERSION >= 11) -+ if (device_create_file(dev, &dev_attr_fm_port_ipv4_opt) != 0) -+ return -EIO; -+#endif -+ if (device_create_file(dev, &dev_attr_fm_port_dsar_regs) != 0) -+ return -EIO; -+ if (device_create_file(dev, &dev_attr_fm_port_dsar_mem) != 0) -+ return -EIO; -+ -+ /* FM Ports statistics */ -+ switch (p_LnxWrpFmPortDev->settings.param.portType) { -+ case e_FM_PORT_TYPE_TX: -+ case e_FM_PORT_TYPE_TX_10G: -+ if (sysfs_create_group -+ (&dev->kobj, &fm_tx_port_dev_stats_attr_grp) != 0) -+ return -EIO; -+ break; -+ case e_FM_PORT_TYPE_RX: -+ case e_FM_PORT_TYPE_RX_10G: -+ if (sysfs_create_group -+ (&dev->kobj, &fm_rx_port_dev_stats_attr_grp) != 0) -+ return -EIO; -+ break; -+ case e_FM_PORT_TYPE_DUMMY: -+ case e_FM_PORT_TYPE_OH_OFFLINE_PARSING: -+ if (sysfs_create_group -+ (&dev->kobj, &fm_oh_port_dev_stats_attr_grp) != 0) -+ return -EIO; -+ break; -+ default: -+ WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__, -+ __func__); -+ return -EINVAL; -+ break; -+ }; -+ -+ return 0; -+} -+ -+void fm_port_sysfs_destroy(struct device *dev) -+{ -+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL; -+ -+ /* this function has never been tested !!! */ -+ -+ if (WARN_ON(dev == NULL)) -+ return; -+ -+ p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev); -+ if (WARN_ON(p_LnxWrpFmPortDev == NULL)) -+ return; -+ -+ /* The name attribute will be freed also by these 2 functions? */ -+ switch (p_LnxWrpFmPortDev->settings.param.portType) { -+ case e_FM_PORT_TYPE_TX: -+ case e_FM_PORT_TYPE_TX_10G: -+ sysfs_remove_group(&dev->kobj, &fm_tx_port_dev_stats_attr_grp); -+ break; -+ case e_FM_PORT_TYPE_RX: -+ case e_FM_PORT_TYPE_RX_10G: -+ sysfs_remove_group(&dev->kobj, &fm_rx_port_dev_stats_attr_grp); -+ break; -+ case e_FM_PORT_TYPE_DUMMY: -+ case e_FM_PORT_TYPE_OH_OFFLINE_PARSING: -+ sysfs_remove_group(&dev->kobj, &fm_oh_port_dev_stats_attr_grp); -+ break; -+ default: -+ WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__, -+ __func__); -+ break; -+ }; -+ -+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_regs); -+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_qmi_regs); -+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_bmi_regs); -+#if (DPAA_VERSION >= 11) -+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_ipv4_opt); -+#endif -+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_regs); -+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_mem); -+} -+ -+ -+int fm_port_dump_regs(void *h_dev, char *buf, int nn) -+{ -+ t_FmPort *p_FmPort; -+ t_Fm *p_Fm; -+ uint8_t hardwarePortId; -+ int n = nn; -+ -+ p_FmPort = (t_FmPort *)h_dev; -+ hardwarePortId = p_FmPort->hardwarePortId; -+ p_Fm = (t_Fm *)p_FmPort->h_Fm; -+ -+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1], -+ "fmbm_pp for port %u", hardwarePortId); -+ FM_DMP_MEM_32(buf, n, -+ &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1]); -+ -+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1], -+ "fmbm_pfs for port %u", hardwarePortId); -+ FM_DMP_MEM_32(buf, n, -+ &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1]); -+ -+ FM_DMP_TITLE(buf, n, -+ &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1], -+ "fmbm_spliodn for port %u", hardwarePortId); -+ FM_DMP_MEM_32(buf, n, -+ &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1]); -+ -+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], -+ "fmfp_psfor port %u", hardwarePortId); -+ FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]); -+ -+ FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2], -+ "fmdmplrfor port %u", hardwarePortId); -+ FM_DMP_MEM_32(buf, n, -+ &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2]); -+ return n; -+} -+ -+#if (DPAA_VERSION >= 11) -+ -+int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int nn) -+{ -+ t_FmPort *p_FmPort; -+ int n = nn; -+ -+ p_FmPort = (t_FmPort *)h_dev; -+ -+ FM_DMP_V32(buf, n, p_FmPort->p_ParamsPage, ipfOptionsCounter); -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ return n; -+} -+#endif -+ -+int fm_port_dump_regs_bmi(void *h_dev, char *buf, int nn) -+{ -+ t_FmPort *p_FmPort; -+ u_FmPortBmiRegs *p_bmi; -+ -+ char arr[20]; -+ uint8_t flag; -+ int i = 0; -+ int n = nn; -+ -+ p_FmPort = (t_FmPort *)h_dev; -+ p_bmi = p_FmPort->p_FmPortBmiRegs; -+ -+ memset(arr, 0, sizeof(arr)); -+ switch (p_FmPort->portType) { -+ case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING): -+ strcpy(arr, "OFFLINE-PARSING"); -+ flag = 0; -+ break; -+ case (e_FM_PORT_TYPE_OH_HOST_COMMAND): -+ strcpy(arr, "HOST-COMMAND"); -+ flag = 0; -+ break; -+ case (e_FM_PORT_TYPE_RX): -+ strcpy(arr, "RX"); -+ flag = 1; -+ break; -+ case (e_FM_PORT_TYPE_RX_10G): -+ strcpy(arr, "RX-10G"); -+ flag = 1; -+ break; -+ case (e_FM_PORT_TYPE_TX): -+ strcpy(arr, "TX"); -+ flag = 2; -+ break; -+ case (e_FM_PORT_TYPE_TX_10G): -+ strcpy(arr, "TX-10G"); -+ flag = 2; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ FM_DMP_TITLE(buf, n, NULL, -+ "FMan-Port (%s #%d) registers:", -+ arr, p_FmPort->portId); -+ -+ FM_DMP_TITLE(buf, n, p_bmi, "Bmi Port Regs"); -+ -+ switch (flag) { -+ case (0): -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocfg); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ost); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oda); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oicp); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdne); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofne); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofca); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofpne); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opso); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opp); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occb); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oim); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofp); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofed); -+ -+ FM_DMP_TITLE(buf, n, -+ &(p_bmi->ohPortBmiRegs.fmbm_oprai), "fmbm_oprai"); -+ for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) { -+ FM_DMP_MEM_32(buf, n, -+ &(p_bmi->ohPortBmiRegs.fmbm_oprai[i])); -+ } -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofqid); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oefqid); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsdm); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsem); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofene); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmts); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmt); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocmne); -+ { -+#ifndef FM_NO_OP_OBSERVED_POOLS -+ if (p_FmPort->fmRevInfo.majorRev == 4) { -+ FM_DMP_TITLE(buf, n, -+ &p_bmi->ohPortBmiRegs.fmbm_oebmpi, -+ "fmbm_oebmpi"); -+ -+ for (i = 0; i < FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS; ++i) { -+ FM_DMP_MEM_32(buf, n, -+ &(p_bmi->ohPortBmiRegs.fmbm_oebmpi[i])); -+ } -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocgm); -+ } -+#endif /* !FM_NO_OP_OBSERVED_POOLS */ -+ } -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ostc); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofrc); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdc); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofledc); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofufdc); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_offc); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofwdc); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofldec); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opc); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opcp); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occn); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_otuc); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oduc); -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofuc); -+ FM_DMP_TITLE(buf, n, &(p_bmi->ohPortBmiRegs.fmbm_odcfg), -+ "fmbm_odcfg"); -+ for (i = 0; i < 3; ++i) { -+ FM_DMP_MEM_32(buf, n, -+ &(p_bmi->ohPortBmiRegs.fmbm_odcfg[i])); -+ } -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ogpr); -+ break; -+ case (1): -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcfg); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rst); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rda); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfp); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_reth); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfed); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_ricp); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rebm); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfne); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfca); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfpne); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpso); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpp); -+ FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rprai), -+ "fmbm_rprai"); -+ for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) { -+ FM_DMP_MEM_32(buf, n, -+ &(p_bmi->rxPortBmiRegs.fmbm_rprai[i])); -+ } -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfqid); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_refqid); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsdm); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsem); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfene); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcmne); -+ FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_ebmpi, -+ "fmbm_ebmpi"); -+ for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) { -+ FM_DMP_MEM_32(buf, n, -+ &(p_bmi->rxPortBmiRegs.fmbm_ebmpi[i])); -+ } -+ FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_acnt, -+ "fmbm_acnt"); -+ for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) { -+ FM_DMP_MEM_32(buf, n, -+ &(p_bmi->rxPortBmiRegs.fmbm_acnt[i])); -+ } -+ FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_rcgm, -+ "fmbm_rcgm"); -+ for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS / 32; ++i) { -+ FM_DMP_MEM_32(buf, n, -+ &(p_bmi->rxPortBmiRegs.fmbm_rcgm[i])); -+ } -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rmpd); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rstc); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfrc); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfbc); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rlfc); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rffc); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfcd); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfldec); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rodc); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpc); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpcp); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rccn); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rtuc); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rrquc); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rduc); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfuc); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpac); -+ FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rdcfg), -+ "fmbm_rdcfg"); -+ for (i = 0; i < 3; ++i) { -+ FM_DMP_MEM_32(buf, n, -+ &(p_bmi->rxPortBmiRegs.fmbm_rdcfg[i])); -+ } -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rgpr); -+ break; -+ case (2): -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfg); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tst); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tda); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfp); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfed); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ticp); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdne); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfca); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfqid); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfeqid); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfene); -+#if (DPAA_VERSION >= 11) -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfne); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcmne); -+#endif /* (DPAA_VERSION >= 11) */ -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmts); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmt); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tstc); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfrc); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdc); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfledc); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfufdc); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpc); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpcp); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tccn); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttuc); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttcquc); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tduc); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfuc); -+ FM_DMP_TITLE(buf, n, &(p_bmi->txPortBmiRegs.fmbm_tdcfg), -+ "fmbm_tdcfg"); -+ for (i = 0; i < 3 ; ++i) { -+ FM_DMP_MEM_32(buf, n, -+ &(p_bmi->txPortBmiRegs.fmbm_tdcfg[i])); -+ } -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tgpr); -+ break; -+ } -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ return n; -+} -+ -+int fm_port_dump_regs_qmi(void *h_dev, char *buf, int nn) -+{ -+ t_FmPort *p_FmPort; -+ int n = nn; -+ -+ p_FmPort = (t_FmPort *)h_dev; -+ -+ FM_DMP_TITLE(buf, n, p_FmPort->p_FmPortQmiRegs, "Qmi Port Regs"); -+ -+ FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnc); -+ FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pns); -+ FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnts); -+ FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnen); -+ FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnetfc); -+ FM_DMP_V32(buf, n, -+ &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndn); -+ FM_DMP_V32(buf, n, -+ &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndc); -+ FM_DMP_V32(buf, n, -+ &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndtfc); -+ FM_DMP_V32(buf, n, -+ &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndfdc); -+ FM_DMP_V32(buf, n, -+ &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndcc); -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ return n; -+} -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h -@@ -0,0 +1,56 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ @File lnxwrp_sysfs_fm_port.h -+ -+ @Description FM port sysfs functions. -+ -+*/ -+ -+#ifndef LNXWRP_SYSFS_FM_PORT_H_ -+#define LNXWRP_SYSFS_FM_PORT_H_ -+ -+#include "lnxwrp_sysfs.h" -+ -+int fm_port_sysfs_create(struct device *dev); -+void fm_port_sysfs_destroy(struct device *dev); -+ -+int fm_port_dump_regs(void *h_dev, char *buf, int n); -+int fm_port_dump_regs_bmi(void *h_dev, char *buf, int n); -+int fm_port_dump_regs_qmi(void *h_dev, char *buf, int n); -+ -+#if (DPAA_VERSION >= 11) -+int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int n); -+#endif -+ -+#endif /* LNXWRP_SYSFS_FM_PORT_H_ */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile -@@ -0,0 +1,18 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+#Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ -+obj-y += fsl-ncsw-xx.o -+ -+ifneq ($(CONFIG_FMAN_ARM),y) -+fsl-ncsw-xx-objs := xx_linux.o \ -+ module_strings.o -+else -+fsl-ncsw-xx-objs := xx_arm_linux.o \ -+ module_strings.o -+endif -+ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c -@@ -0,0 +1,46 @@ -+/* -+ * Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* Module names for debug messages */ -+const char *moduleStrings[] = -+{ -+ "", /* MODULE_UNKNOWN */ -+ "FM", /* MODULE_FM */ -+ "FM-MURAM", /* MODULE_FM_MURAM */ -+ "FM-PCD", /* MODULE_FM_PCD */ -+ "FM-RTC", /* MODULE_FM_RTC */ -+ "FM-MAC", /* MODULE_FM_MAC */ -+ "FM-Port", /* MODULE_FM_PORT */ -+ "MM", /* MODULE_MM */ -+ "FM-SP", /* MODULE_FM_SP */ -+ "FM-MACSEC" /* MODULE_FM_MACSEC */ -+}; ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c -@@ -0,0 +1,905 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ @File xx_arm_linux.c -+ -+ @Description XX routines implementation for Linux. -+*//***************************************************************************/ -+#include -+ -+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) -+#define MODVERSIONS -+#endif -+#ifdef MODVERSIONS -+#include -+#endif /* MODVERSIONS */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#ifdef BIGPHYSAREA_ENABLE -+#include -+#endif /* BIGPHYSAREA_ENABLE */ -+ -+//#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "list_ext.h" -+#include "mm_ext.h" -+#include "sys_io_ext.h" -+#include "xx.h" -+ -+ -+#define __ERR_MODULE__ MODULE_UNKNOWN -+ -+#ifdef BIGPHYSAREA_ENABLE -+#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */ -+ -+ -+/* TODO: large allocations => use big phys area */ -+/****************************************************************************** -+ * routine: get_nr_pages -+ * -+ * description: -+ * calculates the number of memory pages for a given size (in bytes) -+ * -+ * arguments: -+ * size - the number of bytes -+ * -+ * return code: -+ * The number of pages -+ * -+ *****************************************************************************/ -+static __inline__ uint32_t get_nr_pages (uint32_t size) -+{ -+ return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0)); -+} -+ -+static bool in_big_phys_area (uint32_t addr) -+{ -+ uint32_t base, size; -+ -+ bigphysarea_get_details (&base, &size); -+ return ((addr >= base) && (addr < base + size)); -+} -+#endif /* BIGPHYSAREA_ENABLE */ -+ -+void * xx_Malloc(uint32_t n) -+{ -+ void *a; -+ uint32_t flags; -+ -+ flags = XX_DisableAllIntr(); -+#ifdef BIGPHYSAREA_ENABLE -+ if (n >= MAX_ALLOCATION_SIZE) -+ a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC); -+ else -+#endif /* BIGPHYSAREA_ENABLE */ -+ a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC); -+ if (!a) -+ XX_Print("No memory for XX_Malloc\n"); -+ XX_RestoreAllIntr(flags); -+ -+ return a; -+} -+ -+void xx_Free(void *p) -+{ -+#ifdef BIGPHYSAREA_ENABLE -+ if (in_big_phys_area ((uint32_t)p)) -+ bigphysarea_free_pages(p); -+ else -+#endif /* BIGPHYSAREA_ENABLE */ -+ kfree(p); -+} -+ -+void XX_Exit(int status) -+{ -+ WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n"); -+} -+ -+#define BUF_SIZE 512 -+void XX_Print(char *str, ...) -+{ -+ va_list args; -+#ifdef CONFIG_SMP -+ char buf[BUF_SIZE]; -+#endif /* CONFIG_SMP */ -+ -+ va_start(args, str); -+#ifdef CONFIG_SMP -+ if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE) -+ printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE); -+ printk(KERN_CRIT "cpu %d: %s", raw_smp_processor_id(), buf); -+#else -+ vprintk(str, args); -+#endif /* CONFIG_SMP */ -+ va_end(args); -+} -+ -+void XX_Fprint(void *file, char *str, ...) -+{ -+ va_list args; -+#ifdef CONFIG_SMP -+ char buf[BUF_SIZE]; -+#endif /* CONFIG_SMP */ -+ -+ va_start(args, str); -+#ifdef CONFIG_SMP -+ if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE) -+ printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE); -+ printk (KERN_CRIT "cpu %d: %s", smp_processor_id(), buf); -+ -+#else -+ vprintk(str, args); -+#endif /* CONFIG_SMP */ -+ va_end(args); -+} -+ -+#ifdef DEBUG_XX_MALLOC -+typedef void (*t_ffn)(void *); -+typedef struct { -+ t_ffn f_free; -+ void *mem; -+ char *fname; -+ int fline; -+ uint32_t size; -+ t_List node; -+} t_MemDebug; -+#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node) -+ -+LIST(memDbgLst); -+ -+ -+void * XX_MallocDebug(uint32_t size, char *fname, int line) -+{ -+ void *mem; -+ t_MemDebug *p_MemDbg; -+ -+ p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug)); -+ if (p_MemDbg == NULL) -+ return NULL; -+ -+ mem = xx_Malloc(size); -+ if (mem == NULL) -+ { -+ XX_Free(p_MemDbg); -+ return NULL; -+ } -+ -+ INIT_LIST(&p_MemDbg->node); -+ p_MemDbg->f_free = xx_Free; -+ p_MemDbg->mem = mem; -+ p_MemDbg->fname = fname; -+ p_MemDbg->fline = line; -+ p_MemDbg->size = size+sizeof(t_MemDebug); -+ LIST_AddToTail(&p_MemDbg->node, &memDbgLst); -+ -+ return mem; -+} -+ -+void * XX_MallocSmartDebug(uint32_t size, -+ int memPartitionId, -+ uint32_t align, -+ char *fname, -+ int line) -+{ -+ void *mem; -+ t_MemDebug *p_MemDbg; -+ -+ p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug)); -+ if (p_MemDbg == NULL) -+ return NULL; -+ -+ mem = xx_MallocSmart((uint32_t)size, memPartitionId, align); -+ if (mem == NULL) -+ { -+ XX_Free(p_MemDbg); -+ return NULL; -+ } -+ -+ INIT_LIST(&p_MemDbg->node); -+ p_MemDbg->f_free = xx_FreeSmart; -+ p_MemDbg->mem = mem; -+ p_MemDbg->fname = fname; -+ p_MemDbg->fline = line; -+ p_MemDbg->size = size+sizeof(t_MemDebug); -+ LIST_AddToTail(&p_MemDbg->node, &memDbgLst); -+ -+ return mem; -+} -+ -+static void debug_free(void *mem) -+{ -+ t_List *p_MemDbgLh = NULL; -+ t_MemDebug *p_MemDbg; -+ bool found = FALSE; -+ -+ if (LIST_IsEmpty(&memDbgLst)) -+ { -+ REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem)); -+ return; -+ } -+ -+ LIST_FOR_EACH(p_MemDbgLh, &memDbgLst) -+ { -+ p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh); -+ if (p_MemDbg->mem == mem) -+ { -+ found = TRUE; -+ break; -+ } -+ } -+ -+ if (!found) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_FOUND, -+ ("Attempt to free unallocated address (0x%08x)",mem)); -+ dump_stack(); -+ return; -+ } -+ -+ LIST_Del(p_MemDbgLh); -+ p_MemDbg->f_free(mem); -+ p_MemDbg->f_free(p_MemDbg); -+} -+ -+void XX_FreeSmart(void *p) -+{ -+ debug_free(p); -+} -+ -+ -+void XX_Free(void *p) -+{ -+ debug_free(p); -+} -+ -+#else /* not DEBUG_XX_MALLOC */ -+void * XX_Malloc(uint32_t size) -+{ -+ return xx_Malloc(size); -+} -+ -+void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment) -+{ -+ return xx_MallocSmart(size,memPartitionId, alignment); -+} -+ -+void XX_FreeSmart(void *p) -+{ -+ xx_FreeSmart(p); -+} -+ -+ -+void XX_Free(void *p) -+{ -+ xx_Free(p); -+} -+#endif /* not DEBUG_XX_MALLOC */ -+ -+ -+#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0)) -+void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg) -+{ -+ e_Event eventCode = (e_Event)event; -+ -+ UNUSED(eventCode); -+ UNUSED(appId); -+ UNUSED(flags); -+ UNUSED(msg); -+} -+#endif /* (defined(REPORT_EVENTS) && ... */ -+ -+ -+uint32_t XX_DisableAllIntr(void) -+{ -+ unsigned long flags; -+ -+#ifdef local_irq_save_nort -+ local_irq_save_nort(flags); -+#else -+ local_irq_save(flags); -+#endif -+ -+ return (uint32_t)flags; -+} -+ -+void XX_RestoreAllIntr(uint32_t flags) -+{ -+#ifdef local_irq_restore_nort -+ local_irq_restore_nort((unsigned long)flags); -+#else -+ local_irq_restore((unsigned long)flags); -+#endif -+} -+ -+t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags ) -+{ -+ UNUSED(qid); -+ UNUSED(appId); -+ UNUSED(flags); -+ -+ return f(id); -+} -+ -+int XX_IsICacheEnable(void) -+{ -+ return TRUE; -+} -+ -+int XX_IsDCacheEnable(void) -+{ -+ return TRUE; -+} -+ -+ -+typedef struct { -+ t_Isr *f_Isr; -+ t_Handle handle; -+} t_InterruptHandler; -+ -+ -+t_Handle interruptHandlers[0x00010000]; -+ -+static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id) -+{ -+ t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id; -+ p_IntrHndl->f_Isr(p_IntrHndl->handle); -+ return IRQ_HANDLED; -+} -+ -+t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle) -+{ -+ const char *device; -+ t_InterruptHandler *p_IntrHndl; -+ -+ device = GetDeviceName(irq); -+ if (device == NULL) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq)); -+ -+ p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler)); -+ if (p_IntrHndl == NULL) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ p_IntrHndl->f_Isr = f_Isr; -+ p_IntrHndl->handle = handle; -+ interruptHandlers[irq] = p_IntrHndl; -+ -+ if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0) -+ RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device)); -+ disable_irq(GetDeviceIrqNum(irq)); -+ -+ return E_OK; -+} -+ -+t_Error XX_FreeIntr(int irq) -+{ -+ t_InterruptHandler *p_IntrHndl = interruptHandlers[irq]; -+ free_irq(GetDeviceIrqNum(irq), p_IntrHndl); -+ XX_Free(p_IntrHndl); -+ interruptHandlers[irq] = 0; -+ return E_OK; -+} -+ -+t_Error XX_EnableIntr(int irq) -+{ -+ enable_irq(GetDeviceIrqNum(irq)); -+ return E_OK; -+} -+ -+t_Error XX_DisableIntr(int irq) -+{ -+ disable_irq(GetDeviceIrqNum(irq)); -+ return E_OK; -+} -+ -+ -+/*****************************************************************************/ -+/* Tasklet Service Routines */ -+/*****************************************************************************/ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+typedef struct -+{ -+ t_Handle h_Data; -+ void (*f_Callback) (void *); -+ struct delayed_work dwork; -+} t_Tasklet; -+ -+static void GenericTaskletCallback(struct work_struct *p_Work) -+{ -+ t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work); -+ -+ p_Task->f_Callback(p_Task->h_Data); -+} -+#endif /* LINUX_VERSION_CODE */ -+ -+ -+t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ struct work_struct *p_Task; -+ p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct)); -+ INIT_WORK(p_Task, routine, data); -+#else -+ t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet)); -+ p_Task->h_Data = data; -+ p_Task->f_Callback = routine; -+ INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback); -+#endif /* LINUX_VERSION_CODE */ -+ -+ return (t_TaskletHandle)p_Task; -+} -+ -+ -+void XX_FreeTasklet (t_TaskletHandle h_Tasklet) -+{ -+ if (h_Tasklet) -+ XX_Free(h_Tasklet); -+} -+ -+int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate) -+{ -+ int ans; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ if (immediate) -+ ans = schedule_work(h_Tasklet); -+ else -+ ans = schedule_delayed_work(h_Tasklet, 1); -+#else -+ if (immediate) -+ ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0); -+ else -+ ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ); -+#endif /* LINUX_VERSION_CODE */ -+ -+ return ans; -+} -+ -+void XX_FlushScheduledTasks(void) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ flush_scheduled_tasks(); -+#else -+ flush_scheduled_work(); -+#endif /* LINUX_VERSION_CODE */ -+} -+ -+int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ return (int)(((struct work_struct *)h_Tasklet)->pending); -+#else -+ return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork); -+#endif /* LINUX_VERSION_CODE */ -+} -+ -+void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ ((struct tq_struct *)h_Tasklet)->data = data; -+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ ((struct work_struct *)h_Tasklet)->data = data; -+#else -+ ((t_Tasklet *)h_Tasklet)->h_Data = data; -+#endif /* LINUX_VERSION_CODE */ -+} -+ -+t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ return (t_Handle)(((struct work_struct *)h_Tasklet)->data); -+#else -+ return ((t_Tasklet *)h_Tasklet)->h_Data; -+#endif /* LINUX_VERSION_CODE */ -+} -+ -+ -+/*****************************************************************************/ -+/* Spinlock Service Routines */ -+/*****************************************************************************/ -+ -+t_Handle XX_InitSpinlock(void) -+{ -+ spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t)); -+ if (!p_Spinlock) -+ return NULL; -+ -+ spin_lock_init(p_Spinlock); -+ -+ return (t_Handle)p_Spinlock; -+} -+ -+void XX_FreeSpinlock(t_Handle h_Spinlock) -+{ -+ if (h_Spinlock) -+ XX_Free(h_Spinlock); -+} -+ -+void XX_LockSpinlock(t_Handle h_Spinlock) -+{ -+ spin_lock((spinlock_t *)h_Spinlock); -+} -+ -+void XX_UnlockSpinlock(t_Handle h_Spinlock) -+{ -+ spin_unlock((spinlock_t *)h_Spinlock); -+} -+ -+uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock) -+{ -+ unsigned long intrFlags; -+ spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags); -+ return intrFlags; -+} -+ -+void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags) -+{ -+ spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags); -+} -+ -+ -+/*****************************************************************************/ -+/* Timers Service Routines */ -+/*****************************************************************************/ -+/* The time now is in mili sec. resolution */ -+uint32_t XX_CurrentTime(void) -+{ -+ return (jiffies*1000)/HZ; -+} -+ -+ -+t_Handle XX_CreateTimer(void) -+{ -+ struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list)); -+ if (p_Timer) -+ { -+ memset(p_Timer, 0, sizeof(struct timer_list)); -+ init_timer(p_Timer); -+ } -+ return (t_Handle)p_Timer; -+} -+ -+void XX_FreeTimer(t_Handle h_Timer) -+{ -+ if (h_Timer) -+ XX_Free(h_Timer); -+} -+ -+void XX_StartTimer(t_Handle h_Timer, -+ uint32_t msecs, -+ bool periodic, -+ void (*f_TimerExpired)(t_Handle), -+ t_Handle h_Arg) -+{ -+ int tmp_jiffies = (msecs*HZ)/1000; -+ struct timer_list *p_Timer = (struct timer_list *)h_Timer; -+ -+ SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED); -+ -+ p_Timer->function = (void (*)(unsigned long))f_TimerExpired; -+ p_Timer->data = (unsigned long)h_Arg; -+ if ((msecs*HZ)%1000) -+ tmp_jiffies++; -+ p_Timer->expires = (jiffies + tmp_jiffies); -+ -+ add_timer((struct timer_list *)h_Timer); -+} -+ -+void XX_SetTimerData(t_Handle h_Timer, t_Handle data) -+{ -+ struct timer_list *p_Timer = (struct timer_list *)h_Timer; -+ -+ p_Timer->data = (unsigned long)data; -+} -+ -+t_Handle XX_GetTimerData(t_Handle h_Timer) -+{ -+ struct timer_list *p_Timer = (struct timer_list *)h_Timer; -+ -+ return (t_Handle)p_Timer->data; -+} -+ -+uint32_t XX_GetExpirationTime(t_Handle h_Timer) -+{ -+ struct timer_list *p_Timer = (struct timer_list *)h_Timer; -+ -+ return (uint32_t)p_Timer->expires; -+} -+ -+void XX_StopTimer(t_Handle h_Timer) -+{ -+ del_timer((struct timer_list *)h_Timer); -+} -+ -+void XX_ModTimer(t_Handle h_Timer, uint32_t msecs) -+{ -+ int tmp_jiffies = (msecs*HZ)/1000; -+ -+ if ((msecs*HZ)%1000) -+ tmp_jiffies++; -+ mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies); -+} -+ -+int XX_TimerIsActive(t_Handle h_Timer) -+{ -+ return timer_pending((struct timer_list *)h_Timer); -+} -+ -+uint32_t XX_Sleep(uint32_t msecs) -+{ -+ int tmp_jiffies = (msecs*HZ)/1000; -+ -+ if ((msecs*HZ)%1000) -+ tmp_jiffies++; -+ return schedule_timeout(tmp_jiffies); -+} -+ -+/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/ -+void XX_UDelay(uint32_t usecs) -+{ -+ udelay(usecs); -+} -+ -+/* TODO: verify that these are correct */ -+#define MSG_BODY_SIZE 512 -+typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]); -+typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]); -+t_Error XX_SendMessage(char *p_DestAddr, -+ uint32_t msgId, -+ uint8_t msgBody[MSG_BODY_SIZE], -+ t_MsgCompletionCB *f_CompletionCB, -+ t_Handle h_CBArg); -+ -+typedef struct { -+ char *p_Addr; -+ t_MsgHandler *f_MsgHandlerCB; -+ t_Handle h_Mod; -+ t_List node; -+} t_MsgHndlr; -+#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node) -+ -+LIST(msgHndlrList); -+ -+static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr) -+{ -+ uint32_t intFlags; -+ -+ intFlags = XX_DisableAllIntr(); -+ LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList); -+ XX_RestoreAllIntr(intFlags); -+} -+/* TODO: add this for multi-platform support -+static t_MsgHndlr * DequeueMsgHndlr(void) -+{ -+ t_MsgHndlr *p_MsgHndlr = NULL; -+ uint32_t intFlags; -+ -+ intFlags = XX_DisableAllIntr(); -+ if (!LIST_IsEmpty(&msgHndlrList)) -+ { -+ p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next); -+ LIST_DelAndInit(&p_MsgHndlr->node); -+ } -+ XX_RestoreAllIntr(intFlags); -+ -+ return p_MsgHndlr; -+} -+*/ -+static t_MsgHndlr * FindMsgHndlr(char *p_Addr) -+{ -+ t_MsgHndlr *p_MsgHndlr; -+ t_List *p_Pos; -+ -+ LIST_FOR_EACH(p_Pos, &msgHndlrList) -+ { -+ p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos); -+ if (strstr(p_MsgHndlr->p_Addr, p_Addr)) -+ return p_MsgHndlr; -+ } -+ -+ return NULL; -+} -+ -+t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod) -+{ -+ t_MsgHndlr *p_MsgHndlr; -+ uint32_t len; -+ -+ p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr)); -+ if (!p_MsgHndlr) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!")); -+ memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr)); -+ -+ len = strlen(p_Addr); -+ p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1); -+ strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1)); -+ -+ p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB; -+ p_MsgHndlr->h_Mod = h_Mod; -+ INIT_LIST(&p_MsgHndlr->node); -+ EnqueueMsgHndlr(p_MsgHndlr); -+ -+ return E_OK; -+} -+ -+t_Error XX_UnregisterMessageHandler (char *p_Addr) -+{ -+ t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr); -+ if (!p_MsgHndlr) -+ RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!")); -+ -+ LIST_Del(&p_MsgHndlr->node); -+ XX_Free(p_MsgHndlr->p_Addr); -+ XX_Free(p_MsgHndlr); -+ -+ return E_OK; -+} -+ -+t_Error XX_SendMessage(char *p_DestAddr, -+ uint32_t msgId, -+ uint8_t msgBody[MSG_BODY_SIZE], -+ t_MsgCompletionCB *f_CompletionCB, -+ t_Handle h_CBArg) -+{ -+ t_Error ans; -+ t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr); -+ if (!p_MsgHndlr) -+ RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!")); -+ -+ ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody); -+ -+ if (f_CompletionCB) -+ f_CompletionCB(h_CBArg, msgBody); -+ -+ return ans; -+} -+ -+t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH], -+ t_IpcMsgHandler *f_MsgHandler, -+ t_Handle h_Module, -+ uint32_t replyLength) -+{ -+ UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength); -+ return E_OK; -+} -+ -+t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]) -+{ -+ UNUSED(addr); -+ return E_OK; -+} -+ -+ -+t_Error XX_IpcSendMessage(t_Handle h_Session, -+ uint8_t *p_Msg, -+ uint32_t msgLength, -+ uint8_t *p_Reply, -+ uint32_t *p_ReplyLength, -+ t_IpcMsgCompletion *f_Completion, -+ t_Handle h_Arg) -+{ -+ UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply); -+ UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg); -+ return E_OK; -+} -+ -+t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH], -+ char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]) -+{ -+ UNUSED(destAddr); UNUSED(srcAddr); -+ return E_OK; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+int GetDeviceIrqNum(int irq) -+{ -+ struct device_node *iPar; -+ struct irq_domain *irqHost; -+ uint32_t hwIrq; -+ -+ /* Get the interrupt controller */ -+ iPar = of_find_node_by_name(NULL, "mpic"); -+ hwIrq = 0; -+ -+ ASSERT_COND(iPar != NULL); -+ /* Get the irq host */ -+ irqHost = irq_find_host(iPar); -+ of_node_put(iPar); -+ -+ /* Create irq mapping */ -+ return irq_create_mapping(irqHost, hwIrq); -+} -+#else -+#error "kernel not supported!!!" -+#endif /* LINUX_VERSION_CODE */ -+ -+void * XX_PhysToVirt(physAddress_t addr) -+{ -+ return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr)); -+} -+ -+physAddress_t XX_VirtToPhys(void * addr) -+{ -+ return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr)); -+} -+ -+void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment) -+{ -+ uintptr_t *returnCode, tmp; -+ -+ if (alignment < sizeof(uintptr_t)) -+ alignment = sizeof(uintptr_t); -+ size += alignment + sizeof(returnCode); -+ tmp = (uintptr_t)xx_Malloc(size); -+ if (tmp == 0) -+ return NULL; -+ returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1)); -+ *(returnCode - 1) = tmp; -+ -+ return (void*)returnCode; -+} -+ -+void xx_FreeSmart(void *p) -+{ -+ xx_Free((void*)(*((uintptr_t *)(p) - 1))); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c -@@ -0,0 +1,918 @@ -+/* -+ * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ @File xx_linux.c -+ -+ @Description XX routines implementation for Linux. -+*//***************************************************************************/ -+#include -+ -+#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) -+#define MODVERSIONS -+#endif -+#ifdef MODVERSIONS -+#include -+#endif /* MODVERSIONS */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_FMAN_ARM -+#include -+#endif -+ -+#include -+ -+#ifdef BIGPHYSAREA_ENABLE -+#include -+#endif /* BIGPHYSAREA_ENABLE */ -+ -+#ifndef CONFIG_FMAN_ARM -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "error_ext.h" -+#include "std_ext.h" -+#include "list_ext.h" -+#include "mm_ext.h" -+#include "sys_io_ext.h" -+#include "xx.h" -+ -+ -+#define __ERR_MODULE__ MODULE_UNKNOWN -+ -+#ifdef BIGPHYSAREA_ENABLE -+#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */ -+ -+ -+/* TODO: large allocations => use big phys area */ -+/****************************************************************************** -+ * routine: get_nr_pages -+ * -+ * description: -+ * calculates the number of memory pages for a given size (in bytes) -+ * -+ * arguments: -+ * size - the number of bytes -+ * -+ * return code: -+ * The number of pages -+ * -+ *****************************************************************************/ -+static __inline__ uint32_t get_nr_pages (uint32_t size) -+{ -+ return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0)); -+} -+ -+static bool in_big_phys_area (uint32_t addr) -+{ -+ uint32_t base, size; -+ -+ bigphysarea_get_details (&base, &size); -+ return ((addr >= base) && (addr < base + size)); -+} -+#endif /* BIGPHYSAREA_ENABLE */ -+ -+void * xx_Malloc(uint32_t n) -+{ -+ void *a; -+ uint32_t flags; -+ -+ flags = XX_DisableAllIntr(); -+#ifdef BIGPHYSAREA_ENABLE -+ if (n >= MAX_ALLOCATION_SIZE) -+ a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC); -+ else -+#endif /* BIGPHYSAREA_ENABLE */ -+ a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC); -+ if (!a) -+ XX_Print("No memory for XX_Malloc\n"); -+ XX_RestoreAllIntr(flags); -+ -+ return a; -+} -+ -+void xx_Free(void *p) -+{ -+#ifdef BIGPHYSAREA_ENABLE -+ if (in_big_phys_area ((uint32_t)p)) -+ bigphysarea_free_pages(p); -+ else -+#endif /* BIGPHYSAREA_ENABLE */ -+ kfree(p); -+} -+ -+void XX_Exit(int status) -+{ -+ WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n"); -+} -+ -+#define BUF_SIZE 512 -+void XX_Print(char *str, ...) -+{ -+ va_list args; -+#ifdef CONFIG_SMP -+ char buf[BUF_SIZE]; -+#endif /* CONFIG_SMP */ -+ -+ va_start(args, str); -+#ifdef CONFIG_SMP -+ if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE) -+ printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE); -+ printk(KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf); -+#else -+ vprintk(str, args); -+#endif /* CONFIG_SMP */ -+ va_end(args); -+} -+ -+void XX_Fprint(void *file, char *str, ...) -+{ -+ va_list args; -+#ifdef CONFIG_SMP -+ char buf[BUF_SIZE]; -+#endif /* CONFIG_SMP */ -+ -+ va_start(args, str); -+#ifdef CONFIG_SMP -+ if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE) -+ printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE); -+ printk (KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf); -+ -+#else -+ vprintk(str, args); -+#endif /* CONFIG_SMP */ -+ va_end(args); -+} -+ -+#ifdef DEBUG_XX_MALLOC -+typedef void (*t_ffn)(void *); -+typedef struct { -+ t_ffn f_free; -+ void *mem; -+ char *fname; -+ int fline; -+ uint32_t size; -+ t_List node; -+} t_MemDebug; -+#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node) -+ -+LIST(memDbgLst); -+ -+ -+void * XX_MallocDebug(uint32_t size, char *fname, int line) -+{ -+ void *mem; -+ t_MemDebug *p_MemDbg; -+ -+ p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug)); -+ if (p_MemDbg == NULL) -+ return NULL; -+ -+ mem = xx_Malloc(size); -+ if (mem == NULL) -+ { -+ XX_Free(p_MemDbg); -+ return NULL; -+ } -+ -+ INIT_LIST(&p_MemDbg->node); -+ p_MemDbg->f_free = xx_Free; -+ p_MemDbg->mem = mem; -+ p_MemDbg->fname = fname; -+ p_MemDbg->fline = line; -+ p_MemDbg->size = size+sizeof(t_MemDebug); -+ LIST_AddToTail(&p_MemDbg->node, &memDbgLst); -+ -+ return mem; -+} -+ -+void * XX_MallocSmartDebug(uint32_t size, -+ int memPartitionId, -+ uint32_t align, -+ char *fname, -+ int line) -+{ -+ void *mem; -+ t_MemDebug *p_MemDbg; -+ -+ p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug)); -+ if (p_MemDbg == NULL) -+ return NULL; -+ -+ mem = xx_MallocSmart((uint32_t)size, memPartitionId, align); -+ if (mem == NULL) -+ { -+ XX_Free(p_MemDbg); -+ return NULL; -+ } -+ -+ INIT_LIST(&p_MemDbg->node); -+ p_MemDbg->f_free = xx_FreeSmart; -+ p_MemDbg->mem = mem; -+ p_MemDbg->fname = fname; -+ p_MemDbg->fline = line; -+ p_MemDbg->size = size+sizeof(t_MemDebug); -+ LIST_AddToTail(&p_MemDbg->node, &memDbgLst); -+ -+ return mem; -+} -+ -+static void debug_free(void *mem) -+{ -+ t_List *p_MemDbgLh = NULL; -+ t_MemDebug *p_MemDbg; -+ bool found = FALSE; -+ -+ if (LIST_IsEmpty(&memDbgLst)) -+ { -+ REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem)); -+ return; -+ } -+ -+ LIST_FOR_EACH(p_MemDbgLh, &memDbgLst) -+ { -+ p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh); -+ if (p_MemDbg->mem == mem) -+ { -+ found = TRUE; -+ break; -+ } -+ } -+ -+ if (!found) -+ { -+ REPORT_ERROR(MAJOR, E_NOT_FOUND, -+ ("Attempt to free unallocated address (0x%08x)",mem)); -+ dump_stack(); -+ return; -+ } -+ -+ LIST_Del(p_MemDbgLh); -+ p_MemDbg->f_free(mem); -+ p_MemDbg->f_free(p_MemDbg); -+} -+ -+void XX_FreeSmart(void *p) -+{ -+ debug_free(p); -+} -+ -+ -+void XX_Free(void *p) -+{ -+ debug_free(p); -+} -+ -+#else /* not DEBUG_XX_MALLOC */ -+void * XX_Malloc(uint32_t size) -+{ -+ return xx_Malloc(size); -+} -+ -+void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment) -+{ -+ return xx_MallocSmart(size,memPartitionId, alignment); -+} -+ -+void XX_FreeSmart(void *p) -+{ -+ xx_FreeSmart(p); -+} -+ -+ -+void XX_Free(void *p) -+{ -+ xx_Free(p); -+} -+#endif /* not DEBUG_XX_MALLOC */ -+ -+ -+#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0)) -+void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg) -+{ -+ e_Event eventCode = (e_Event)event; -+ -+ UNUSED(eventCode); -+ UNUSED(appId); -+ UNUSED(flags); -+ UNUSED(msg); -+} -+#endif /* (defined(REPORT_EVENTS) && ... */ -+ -+ -+uint32_t XX_DisableAllIntr(void) -+{ -+ unsigned long flags; -+ -+#ifdef local_irq_save_nort -+ local_irq_save_nort(flags); -+#else -+ local_irq_save(flags); -+#endif -+ -+ return (uint32_t)flags; -+} -+ -+void XX_RestoreAllIntr(uint32_t flags) -+{ -+#ifdef local_irq_restore_nort -+ local_irq_restore_nort((unsigned long)flags); -+#else -+ local_irq_restore((unsigned long)flags); -+#endif -+} -+ -+t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags ) -+{ -+ UNUSED(qid); -+ UNUSED(appId); -+ UNUSED(flags); -+ -+ return f(id); -+} -+ -+int XX_IsICacheEnable(void) -+{ -+ return TRUE; -+} -+ -+int XX_IsDCacheEnable(void) -+{ -+ return TRUE; -+} -+ -+ -+typedef struct { -+ t_Isr *f_Isr; -+ t_Handle handle; -+} t_InterruptHandler; -+ -+ -+t_Handle interruptHandlers[0x00010000]; -+ -+#ifdef CONFIG_FMAN_ARM -+static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id) -+{ -+ t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id; -+ p_IntrHndl->f_Isr(p_IntrHndl->handle); -+ return IRQ_HANDLED; -+} -+#endif -+ -+t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle) -+{ -+#ifdef CONFIG_FMAN_ARM -+ const char *device; -+ t_InterruptHandler *p_IntrHndl; -+ -+ device = GetDeviceName(irq); -+ if (device == NULL) -+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq)); -+ -+ p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler)); -+ if (p_IntrHndl == NULL) -+ RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); -+ p_IntrHndl->f_Isr = f_Isr; -+ p_IntrHndl->handle = handle; -+ interruptHandlers[irq] = p_IntrHndl; -+ -+ if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0) -+ RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device)); -+ disable_irq(GetDeviceIrqNum(irq)); -+#endif -+ return E_OK; -+} -+ -+t_Error XX_FreeIntr(int irq) -+{ -+ t_InterruptHandler *p_IntrHndl = interruptHandlers[irq]; -+ free_irq(GetDeviceIrqNum(irq), p_IntrHndl); -+ XX_Free(p_IntrHndl); -+ interruptHandlers[irq] = 0; -+ return E_OK; -+} -+ -+t_Error XX_EnableIntr(int irq) -+{ -+ enable_irq(GetDeviceIrqNum(irq)); -+ return E_OK; -+} -+ -+t_Error XX_DisableIntr(int irq) -+{ -+ disable_irq(GetDeviceIrqNum(irq)); -+ return E_OK; -+} -+ -+ -+/*****************************************************************************/ -+/* Tasklet Service Routines */ -+/*****************************************************************************/ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) -+typedef struct -+{ -+ t_Handle h_Data; -+ void (*f_Callback) (void *); -+ struct delayed_work dwork; -+} t_Tasklet; -+ -+static void GenericTaskletCallback(struct work_struct *p_Work) -+{ -+ t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work); -+ -+ p_Task->f_Callback(p_Task->h_Data); -+} -+#endif /* LINUX_VERSION_CODE */ -+ -+ -+t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ struct work_struct *p_Task; -+ p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct)); -+ INIT_WORK(p_Task, routine, data); -+#else -+ t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet)); -+ p_Task->h_Data = data; -+ p_Task->f_Callback = routine; -+ INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback); -+#endif /* LINUX_VERSION_CODE */ -+ -+ return (t_TaskletHandle)p_Task; -+} -+ -+ -+void XX_FreeTasklet (t_TaskletHandle h_Tasklet) -+{ -+ if (h_Tasklet) -+ XX_Free(h_Tasklet); -+} -+ -+int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate) -+{ -+ int ans; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ if (immediate) -+ ans = schedule_work(h_Tasklet); -+ else -+ ans = schedule_delayed_work(h_Tasklet, 1); -+#else -+ if (immediate) -+ ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0); -+ else -+ ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ); -+#endif /* LINUX_VERSION_CODE */ -+ -+ return ans; -+} -+ -+void XX_FlushScheduledTasks(void) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ flush_scheduled_tasks(); -+#else -+ flush_scheduled_work(); -+#endif /* LINUX_VERSION_CODE */ -+} -+ -+int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ return (int)(((struct work_struct *)h_Tasklet)->pending); -+#else -+ return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork); -+#endif /* LINUX_VERSION_CODE */ -+} -+ -+void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ ((struct tq_struct *)h_Tasklet)->data = data; -+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ ((struct work_struct *)h_Tasklet)->data = data; -+#else -+ ((t_Tasklet *)h_Tasklet)->h_Data = data; -+#endif /* LINUX_VERSION_CODE */ -+} -+ -+t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet) -+{ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) -+ return (t_Handle)(((struct work_struct *)h_Tasklet)->data); -+#else -+ return ((t_Tasklet *)h_Tasklet)->h_Data; -+#endif /* LINUX_VERSION_CODE */ -+} -+ -+ -+/*****************************************************************************/ -+/* Spinlock Service Routines */ -+/*****************************************************************************/ -+ -+t_Handle XX_InitSpinlock(void) -+{ -+ spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t)); -+ if (!p_Spinlock) -+ return NULL; -+ -+ spin_lock_init(p_Spinlock); -+ -+ return (t_Handle)p_Spinlock; -+} -+ -+void XX_FreeSpinlock(t_Handle h_Spinlock) -+{ -+ if (h_Spinlock) -+ XX_Free(h_Spinlock); -+} -+ -+void XX_LockSpinlock(t_Handle h_Spinlock) -+{ -+ spin_lock((spinlock_t *)h_Spinlock); -+} -+ -+void XX_UnlockSpinlock(t_Handle h_Spinlock) -+{ -+ spin_unlock((spinlock_t *)h_Spinlock); -+} -+ -+uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock) -+{ -+ unsigned long intrFlags; -+ spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags); -+ return intrFlags; -+} -+ -+void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags) -+{ -+ spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags); -+} -+ -+ -+/*****************************************************************************/ -+/* Timers Service Routines */ -+/*****************************************************************************/ -+/* The time now is in mili sec. resolution */ -+uint32_t XX_CurrentTime(void) -+{ -+ return (jiffies*1000)/HZ; -+} -+ -+ -+t_Handle XX_CreateTimer(void) -+{ -+ struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list)); -+ if (p_Timer) -+ { -+ memset(p_Timer, 0, sizeof(struct timer_list)); -+ init_timer(p_Timer); -+ } -+ return (t_Handle)p_Timer; -+} -+ -+void XX_FreeTimer(t_Handle h_Timer) -+{ -+ if (h_Timer) -+ XX_Free(h_Timer); -+} -+ -+void XX_StartTimer(t_Handle h_Timer, -+ uint32_t msecs, -+ bool periodic, -+ void (*f_TimerExpired)(t_Handle), -+ t_Handle h_Arg) -+{ -+ int tmp_jiffies = (msecs*HZ)/1000; -+ struct timer_list *p_Timer = (struct timer_list *)h_Timer; -+ -+ SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED); -+ -+ p_Timer->function = (void (*)(unsigned long))f_TimerExpired; -+ p_Timer->data = (unsigned long)h_Arg; -+ if ((msecs*HZ)%1000) -+ tmp_jiffies++; -+ p_Timer->expires = (jiffies + tmp_jiffies); -+ -+ add_timer((struct timer_list *)h_Timer); -+} -+ -+void XX_SetTimerData(t_Handle h_Timer, t_Handle data) -+{ -+ struct timer_list *p_Timer = (struct timer_list *)h_Timer; -+ -+ p_Timer->data = (unsigned long)data; -+} -+ -+t_Handle XX_GetTimerData(t_Handle h_Timer) -+{ -+ struct timer_list *p_Timer = (struct timer_list *)h_Timer; -+ -+ return (t_Handle)p_Timer->data; -+} -+ -+uint32_t XX_GetExpirationTime(t_Handle h_Timer) -+{ -+ struct timer_list *p_Timer = (struct timer_list *)h_Timer; -+ -+ return (uint32_t)p_Timer->expires; -+} -+ -+void XX_StopTimer(t_Handle h_Timer) -+{ -+ del_timer((struct timer_list *)h_Timer); -+} -+ -+void XX_ModTimer(t_Handle h_Timer, uint32_t msecs) -+{ -+ int tmp_jiffies = (msecs*HZ)/1000; -+ -+ if ((msecs*HZ)%1000) -+ tmp_jiffies++; -+ mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies); -+} -+ -+int XX_TimerIsActive(t_Handle h_Timer) -+{ -+ return timer_pending((struct timer_list *)h_Timer); -+} -+ -+uint32_t XX_Sleep(uint32_t msecs) -+{ -+ int tmp_jiffies = (msecs*HZ)/1000; -+ -+ if ((msecs*HZ)%1000) -+ tmp_jiffies++; -+ return schedule_timeout(tmp_jiffies); -+} -+ -+/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/ -+void XX_UDelay(uint32_t usecs) -+{ -+ udelay(usecs); -+} -+ -+/* TODO: verify that these are correct */ -+#define MSG_BODY_SIZE 512 -+typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]); -+typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]); -+t_Error XX_SendMessage(char *p_DestAddr, -+ uint32_t msgId, -+ uint8_t msgBody[MSG_BODY_SIZE], -+ t_MsgCompletionCB *f_CompletionCB, -+ t_Handle h_CBArg); -+ -+typedef struct { -+ char *p_Addr; -+ t_MsgHandler *f_MsgHandlerCB; -+ t_Handle h_Mod; -+ t_List node; -+} t_MsgHndlr; -+#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node) -+ -+LIST(msgHndlrList); -+ -+static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr) -+{ -+ uint32_t intFlags; -+ -+ intFlags = XX_DisableAllIntr(); -+ LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList); -+ XX_RestoreAllIntr(intFlags); -+} -+/* TODO: add this for multi-platform support -+static t_MsgHndlr * DequeueMsgHndlr(void) -+{ -+ t_MsgHndlr *p_MsgHndlr = NULL; -+ uint32_t intFlags; -+ -+ intFlags = XX_DisableAllIntr(); -+ if (!LIST_IsEmpty(&msgHndlrList)) -+ { -+ p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next); -+ LIST_DelAndInit(&p_MsgHndlr->node); -+ } -+ XX_RestoreAllIntr(intFlags); -+ -+ return p_MsgHndlr; -+} -+*/ -+static t_MsgHndlr * FindMsgHndlr(char *p_Addr) -+{ -+ t_MsgHndlr *p_MsgHndlr; -+ t_List *p_Pos; -+ -+ LIST_FOR_EACH(p_Pos, &msgHndlrList) -+ { -+ p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos); -+ if (strstr(p_MsgHndlr->p_Addr, p_Addr)) -+ return p_MsgHndlr; -+ } -+ -+ return NULL; -+} -+ -+t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod) -+{ -+ t_MsgHndlr *p_MsgHndlr; -+ uint32_t len; -+ -+ p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr)); -+ if (!p_MsgHndlr) -+ RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!")); -+ memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr)); -+ -+ len = strlen(p_Addr); -+ p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1); -+ strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1)); -+ -+ p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB; -+ p_MsgHndlr->h_Mod = h_Mod; -+ INIT_LIST(&p_MsgHndlr->node); -+ EnqueueMsgHndlr(p_MsgHndlr); -+ -+ return E_OK; -+} -+ -+t_Error XX_UnregisterMessageHandler (char *p_Addr) -+{ -+ t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr); -+ if (!p_MsgHndlr) -+ RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!")); -+ -+ LIST_Del(&p_MsgHndlr->node); -+ XX_Free(p_MsgHndlr->p_Addr); -+ XX_Free(p_MsgHndlr); -+ -+ return E_OK; -+} -+ -+t_Error XX_SendMessage(char *p_DestAddr, -+ uint32_t msgId, -+ uint8_t msgBody[MSG_BODY_SIZE], -+ t_MsgCompletionCB *f_CompletionCB, -+ t_Handle h_CBArg) -+{ -+ t_Error ans; -+ t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr); -+ if (!p_MsgHndlr) -+ RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!")); -+ -+ ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody); -+ -+ if (f_CompletionCB) -+ f_CompletionCB(h_CBArg, msgBody); -+ -+ return ans; -+} -+ -+t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH], -+ t_IpcMsgHandler *f_MsgHandler, -+ t_Handle h_Module, -+ uint32_t replyLength) -+{ -+ UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength); -+ return E_OK; -+} -+ -+t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]) -+{ -+ UNUSED(addr); -+ return E_OK; -+} -+ -+ -+t_Error XX_IpcSendMessage(t_Handle h_Session, -+ uint8_t *p_Msg, -+ uint32_t msgLength, -+ uint8_t *p_Reply, -+ uint32_t *p_ReplyLength, -+ t_IpcMsgCompletion *f_Completion, -+ t_Handle h_Arg) -+{ -+ UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply); -+ UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg); -+ return E_OK; -+} -+ -+t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH], -+ char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]) -+{ -+ UNUSED(destAddr); UNUSED(srcAddr); -+ return E_OK; -+} -+ -+/*Forced to introduce due to PRINT_FMT_PARAMS define*/ -+uint32_t E500_GetId(void) -+{ -+ return raw_smp_processor_id(); -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+int GetDeviceIrqNum(int irq) -+{ -+ struct device_node *iPar; -+ struct irq_domain *irqHost; -+ uint32_t hwIrq; -+ -+ /* Get the interrupt controller */ -+ iPar = of_find_node_by_name(NULL, "mpic"); -+ hwIrq = 0; -+ -+ ASSERT_COND(iPar != NULL); -+ /* Get the irq host */ -+ irqHost = irq_find_host(iPar); -+ of_node_put(iPar); -+ -+ /* Create irq mapping */ -+ return irq_create_mapping(irqHost, hwIrq); -+} -+#else -+#error "kernel not supported!!!" -+#endif /* LINUX_VERSION_CODE */ -+ -+void * XX_PhysToVirt(physAddress_t addr) -+{ -+ return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr)); -+} -+ -+physAddress_t XX_VirtToPhys(void * addr) -+{ -+ return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr)); -+} -+ -+void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment) -+{ -+ uintptr_t *returnCode, tmp; -+ -+ if (alignment < sizeof(uintptr_t)) -+ alignment = sizeof(uintptr_t); -+ size += alignment + sizeof(returnCode); -+ tmp = (uintptr_t)xx_Malloc(size); -+ if (tmp == 0) -+ return NULL; -+ returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1)); -+ *(returnCode - 1) = tmp; -+ -+ return (void*)returnCode; -+} -+ -+void xx_FreeSmart(void *p) -+{ -+ xx_Free((void*)(*((uintptr_t *)(p) - 1))); -+} ---- /dev/null -+++ b/include/linux/fsl/svr.h -@@ -0,0 +1,97 @@ -+/* -+ * MPC85xx cpu type detection -+ * -+ * Copyright 2011-2012 Freescale Semiconductor, Inc. -+ * -+ * This is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#ifndef FSL_SVR_H -+#define FSL_SVR_H -+ -+#define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */ -+#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/ -+#define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/ -+ -+/* Some parts define SVR[0:23] as the SOC version */ -+#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFF7FF) /* SOC Version fields */ -+ -+#define SVR_8533 0x803400 -+#define SVR_8535 0x803701 -+#define SVR_8536 0x803700 -+#define SVR_8540 0x803000 -+#define SVR_8541 0x807200 -+#define SVR_8543 0x803200 -+#define SVR_8544 0x803401 -+#define SVR_8545 0x803102 -+#define SVR_8547 0x803101 -+#define SVR_8548 0x803100 -+#define SVR_8555 0x807100 -+#define SVR_8560 0x807000 -+#define SVR_8567 0x807501 -+#define SVR_8568 0x807500 -+#define SVR_8569 0x808000 -+#define SVR_8572 0x80E000 -+#define SVR_P1010 0x80F100 -+#define SVR_P1011 0x80E500 -+#define SVR_P1012 0x80E501 -+#define SVR_P1013 0x80E700 -+#define SVR_P1014 0x80F101 -+#define SVR_P1017 0x80F700 -+#define SVR_P1020 0x80E400 -+#define SVR_P1021 0x80E401 -+#define SVR_P1022 0x80E600 -+#define SVR_P1023 0x80F600 -+#define SVR_P1024 0x80E402 -+#define SVR_P1025 0x80E403 -+#define SVR_P2010 0x80E300 -+#define SVR_P2020 0x80E200 -+#define SVR_P2040 0x821000 -+#define SVR_P2041 0x821001 -+#define SVR_P3041 0x821103 -+#define SVR_P4040 0x820100 -+#define SVR_P4080 0x820000 -+#define SVR_P5010 0x822100 -+#define SVR_P5020 0x822000 -+#define SVR_P5021 0X820500 -+#define SVR_P5040 0x820400 -+#define SVR_T4240 0x824000 -+#define SVR_T4120 0x824001 -+#define SVR_T4160 0x824100 -+#define SVR_T4080 0x824102 -+#define SVR_C291 0x850000 -+#define SVR_C292 0x850020 -+#define SVR_C293 0x850030 -+#define SVR_B4860 0X868000 -+#define SVR_G4860 0x868001 -+#define SVR_G4060 0x868003 -+#define SVR_B4440 0x868100 -+#define SVR_G4440 0x868101 -+#define SVR_B4420 0x868102 -+#define SVR_B4220 0x868103 -+#define SVR_T1040 0x852000 -+#define SVR_T1041 0x852001 -+#define SVR_T1042 0x852002 -+#define SVR_T1020 0x852100 -+#define SVR_T1021 0x852101 -+#define SVR_T1022 0x852102 -+#define SVR_T1023 0x854100 -+#define SVR_T1024 0x854000 -+#define SVR_T2080 0x853000 -+#define SVR_T2081 0x853100 -+ -+#define SVR_8610 0x80A000 -+#define SVR_8641 0x809000 -+#define SVR_8641D 0x809001 -+ -+#define SVR_9130 0x860001 -+#define SVR_9131 0x860000 -+#define SVR_9132 0x861000 -+#define SVR_9232 0x861400 -+ -+#define SVR_Unknown 0xFFFFFF -+ -+#endif ---- /dev/null -+++ b/include/uapi/linux/fmd/Kbuild -@@ -0,0 +1,5 @@ -+header-y += integrations/ -+header-y += Peripherals/ -+ -+header-y += ioctls.h -+header-y += net_ioctls.h ---- /dev/null -+++ b/include/uapi/linux/fmd/Peripherals/Kbuild -@@ -0,0 +1,4 @@ -+header-y += fm_ioctls.h -+header-y += fm_port_ioctls.h -+header-y += fm_pcd_ioctls.h -+header-y += fm_test_ioctls.h ---- /dev/null -+++ b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h -@@ -0,0 +1,628 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ @File fm_ioctls.h -+ -+ @Description FM Char device ioctls -+*//***************************************************************************/ -+#ifndef __FM_IOCTLS_H -+#define __FM_IOCTLS_H -+ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API -+ -+ @Description FM Linux ioctls definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Collection FM IOCTL device ('/dev') definitions -+*//***************************************************************************/ -+#define DEV_FM_NAME "fm" /**< Name of the FM chardev */ -+ -+#define DEV_FM_MINOR_BASE 0 -+#define DEV_FM_PCD_MINOR_BASE (DEV_FM_MINOR_BASE + 1) /*/dev/fmx-pcd */ -+#define DEV_FM_OH_PORTS_MINOR_BASE (DEV_FM_PCD_MINOR_BASE + 1) /*/dev/fmx-port-ohy */ -+#define DEV_FM_RX_PORTS_MINOR_BASE (DEV_FM_OH_PORTS_MINOR_BASE + FM_MAX_NUM_OF_OH_PORTS) /*/dev/fmx-port-rxy */ -+#define DEV_FM_TX_PORTS_MINOR_BASE (DEV_FM_RX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_RX_PORTS) /*/dev/fmx-port-txy */ -+#define DEV_FM_MAX_MINORS (DEV_FM_TX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_TX_PORTS) -+ -+#define FM_IOC_NUM(n) (n) -+#define FM_PCD_IOC_NUM(n) (n+20) -+#define FM_PORT_IOC_NUM(n) (n+70) -+/* @} */ -+ -+#define IOC_FM_MAX_NUM_OF_PORTS 64 -+ -+ -+/**************************************************************************//** -+ @Description Enum for defining port types -+ (must match enum e_FmPortType defined in fm_ext.h) -+*//***************************************************************************/ -+typedef enum ioc_fm_port_type { -+ e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */ -+ e_IOC_FM_PORT_TYPE_RX, /**< 1G Rx port */ -+ e_IOC_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */ -+ e_IOC_FM_PORT_TYPE_TX, /**< 1G Tx port */ -+ e_IOC_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */ -+ e_IOC_FM_PORT_TYPE_DUMMY -+} ioc_fm_port_type; -+ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FM_lib_grp FM library -+ -+ @Description FM API functions, definitions and enums -+ The FM module is the main driver module and is a mandatory module -+ for FM driver users. Before any further module initialization, -+ this module must be initialized. -+ The FM is a "single-tone" module. It is responsible of the common -+ HW modules: FPM, DMA, common QMI, common BMI initializations and -+ run-time control routines. This module must be initialized always -+ when working with any of the FM modules. -+ NOTE - We assumes that the FML will be initialize only by core No. 0! -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description FM Exceptions -+*//***************************************************************************/ -+typedef enum ioc_fm_exceptions { -+ e_IOC_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */ -+ e_IOC_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/ -+ e_IOC_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/ -+ e_IOC_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/ -+ e_IOC_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/ -+ e_IOC_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */ -+ e_IOC_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */ -+ e_IOC_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */ -+ e_IOC_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */ -+ e_IOC_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */ -+ e_IOC_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */ -+ e_IOC_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */ -+ e_IOC_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */ -+ e_IOC_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */ -+ e_IOC_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */ -+ e_IOC_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/ -+ e_IOC_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/ -+} ioc_fm_exceptions; -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FM_runtime_control_grp FM Runtime Control Unit -+ -+ @Description FM Runtime control unit API functions, definitions and enums. -+ The FM driver provides a set of control routines for each module. -+ These routines may only be called after the module was fully -+ initialized (both configuration and initialization routines were -+ called). They are typically used to get information from hardware -+ (status, counters/statistics, revision etc.), to modify a current -+ state or to force/enable a required action. Run-time control may -+ be called whenever necessary and as many times as needed. -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Collection General FM defines. -+ *//***************************************************************************/ -+#define IOC_FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \ -+ FM_MAX_NUM_OF_1G_RX_PORTS + \ -+ FM_MAX_NUM_OF_10G_RX_PORTS + \ -+ FM_MAX_NUM_OF_1G_TX_PORTS + \ -+ FM_MAX_NUM_OF_10G_TX_PORTS) -+/* @} */ -+ -+/**************************************************************************//** -+ @Description Structure for Port bandwidth requirement. Port is identified -+ by type and relative id. -+ (must be identical to t_FmPortBandwidth defined in fm_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_port_bandwidth_t { -+ ioc_fm_port_type type; /**< FM port type */ -+ uint8_t relative_port_id; /**< Type relative port id */ -+ uint8_t bandwidth; /**< bandwidth - (in term of percents) */ -+} ioc_fm_port_bandwidth_t; -+ -+/**************************************************************************//** -+ @Description A Structure containing an array of Port bandwidth requirements. -+ The user should state the ports requiring bandwidth in terms of -+ percentage - i.e. all port's bandwidths in the array must add -+ up to 100. -+ (must be identical to t_FmPortsBandwidthParams defined in fm_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_port_bandwidth_params { -+ uint8_t num_of_ports; -+ /**< num of ports listed in the array below */ -+ ioc_fm_port_bandwidth_t ports_bandwidths[IOC_FM_MAX_NUM_OF_VALID_PORTS]; -+ /**< for each port, it's bandwidth (all port's -+ bandwidths must add up to 100.*/ -+} ioc_fm_port_bandwidth_params; -+ -+/**************************************************************************//** -+ @Description enum for defining FM counters -+*//***************************************************************************/ -+typedef enum ioc_fm_counters { -+ e_IOC_FM_COUNTERS_ENQ_TOTAL_FRAME, /**< QMI total enqueued frames counter */ -+ e_IOC_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */ -+ e_IOC_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */ -+ e_IOC_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */ -+ e_IOC_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */ -+ e_IOC_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */ -+ e_IOC_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */ -+ e_IOC_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */ -+ e_IOC_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */ -+ e_IOC_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */ -+} ioc_fm_counters; -+ -+typedef struct ioc_fm_obj_t { -+ void *obj; -+} ioc_fm_obj_t; -+ -+/**************************************************************************//** -+ @Description A structure for returning revision information -+ (must match struct t_FmRevisionInfo declared in fm_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_revision_info_t { -+ uint8_t major; /**< Major revision */ -+ uint8_t minor; /**< Minor revision */ -+} ioc_fm_revision_info_t; -+ -+/**************************************************************************//** -+ @Description A structure for FM counters -+*//***************************************************************************/ -+typedef struct ioc_fm_counters_params_t { -+ ioc_fm_counters cnt; /**< The requested counter */ -+ uint32_t val; /**< The requested value to get/set from/into the counter */ -+} ioc_fm_counters_params_t; -+ -+typedef union ioc_fm_api_version_t { -+ struct { -+ uint8_t major; -+ uint8_t minor; -+ uint8_t respin; -+ uint8_t reserved; -+ } version; -+ uint32_t ver; -+} ioc_fm_api_version_t; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description A structure of information about each of the external -+ buffer pools used by a port or storage-profile. -+ (must be identical to t_FmExtPoolParams defined in fm_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_ext_pool_params { -+ uint8_t id; /**< External buffer pool id */ -+ uint16_t size; /**< External buffer pool buffer size */ -+} ioc_fm_ext_pool_params; -+ -+/**************************************************************************//** -+ @Description A structure for informing the driver about the external -+ buffer pools allocated in the BM and used by a port or a -+ storage-profile. -+ (must be identical to t_FmExtPools defined in fm_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_ext_pools { -+ uint8_t num_of_pools_used; /**< Number of pools use by this port */ -+ ioc_fm_ext_pool_params ext_buf_pool[FM_PORT_MAX_NUM_OF_EXT_POOLS]; -+ /**< Parameters for each port */ -+} ioc_fm_ext_pools; -+ -+typedef struct ioc_fm_vsp_params_t { -+ void *p_fm; /**< A handle to the FM object this VSP related to */ -+ ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used -+ (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. -+ parameter associated with Rx / OP port */ -+ uint16_t liodn_offset; /**< VSP's LIODN offset */ -+ struct { -+ ioc_fm_port_type port_type; /**< Port type */ -+ uint8_t port_id; /**< Port Id - relative to type */ -+ } port_params; -+ uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range -+ defined in relevant FM object */ -+ void *id; /**< return value */ -+} ioc_fm_vsp_params_t; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Description A structure for defining BM pool depletion criteria -+*//***************************************************************************/ -+typedef struct ioc_fm_buf_pool_depletion_t { -+ bool pools_grp_mode_enable; /**< select mode in which pause frames will be sent after -+ a number of pools (all together!) are depleted */ -+ uint8_t num_of_pools; /**< the number of depleted pools that will invoke -+ pause frames transmission. */ -+ bool pools_to_consider[BM_MAX_NUM_OF_POOLS]; -+ /**< For each pool, TRUE if it should be considered for -+ depletion (Note - this pool must be used by this port!). */ -+ bool single_pool_mode_enable; /**< select mode in which pause frames will be sent after -+ a single-pool is depleted; */ -+ bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS]; -+ /**< For each pool, TRUE if it should be considered for -+ depletion (Note - this pool must be used by this port!) */ -+#if (DPAA_VERSION >= 11) -+ bool pfc_priorities_en[FM_MAX_NUM_OF_PFC_PRIORITIES]; -+ /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame -+ which is transmitted */ -+#endif /* (DPAA_VERSION >= 11) */ -+} ioc_fm_buf_pool_depletion_t; -+ -+#if (DPAA_VERSION >= 11) -+typedef struct ioc_fm_buf_pool_depletion_params_t { -+ void *p_fm_vsp; -+ ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion; -+} ioc_fm_buf_pool_depletion_params_t; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+typedef struct ioc_fm_buffer_prefix_content_t { -+ uint16_t priv_data_size; /**< Number of bytes to be left at the beginning -+ of the external buffer; Note that the private-area will -+ start from the base of the buffer address. */ -+ bool pass_prs_result; /**< TRUE to pass the parse result to/from the FM; -+ User may use FM_PORT_GetBufferPrsResult() in order to -+ get the parser-result from a buffer. */ -+ bool pass_time_stamp; /**< TRUE to pass the timeStamp to/from the FM -+ User may use FM_PORT_GetBufferTimeStamp() in order to -+ get the parser-result from a buffer. */ -+ bool pass_hash_result; /**< TRUE to pass the KG hash result to/from the FM -+ User may use FM_PORT_GetBufferHashResult() in order to -+ get the parser-result from a buffer. */ -+ bool pass_all_other_pcd_info; /**< Add all other Internal-Context information: -+ AD, hash-result, key, etc. */ -+ uint16_t data_align; /**< 0 to use driver's default alignment [64], -+ other value for selecting a data alignment (must be a power of 2); -+ if write optimization is used, must be >= 16. */ -+ uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size); -+ Note that this field impacts the size of the buffer-prefix -+ (i.e. it pushes the data offset); -+ This field is irrelevant if DPAA_VERSION==10 */ -+} ioc_fm_buffer_prefix_content_t; -+ -+typedef struct ioc_fm_buffer_prefix_content_params_t { -+ void *p_fm_vsp; -+ ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content; -+} ioc_fm_buffer_prefix_content_params_t; -+ -+#if (DPAA_VERSION >= 11) -+typedef struct ioc_fm_vsp_config_no_sg_params_t { -+ void *p_fm_vsp; -+ bool no_sg; -+} ioc_fm_vsp_config_no_sg_params_t; -+ -+typedef struct ioc_fm_vsp_prs_result_params_t { -+ void *p_fm_vsp; -+ void *p_data; -+} ioc_fm_vsp_prs_result_params_t; -+#endif -+ -+typedef struct fm_ctrl_mon_t { -+ uint8_t percent_cnt[2]; -+} fm_ctrl_mon_t; -+ -+typedef struct ioc_fm_ctrl_mon_counters_params_t { -+ uint8_t fm_ctrl_index; -+ fm_ctrl_mon_t *p_mon; -+} ioc_fm_ctrl_mon_counters_params_t; -+ -+/**************************************************************************//** -+ @Function FM_IOC_SET_PORTS_BANDWIDTH -+ -+ @Description Sets relative weights between ports when accessing common resources. -+ -+ @Param[in] ioc_fm_port_bandwidth_params Port bandwidth percentages, -+ their sum must equal 100. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+#define FM_IOC_SET_PORTS_BANDWIDTH _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(2), ioc_fm_port_bandwidth_params) -+ -+/**************************************************************************//** -+ @Function FM_IOC_GET_REVISION -+ -+ @Description Returns the FM revision -+ -+ @Param[out] ioc_fm_revision_info_t A structure of revision information parameters. -+ -+ @Return None. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+#define FM_IOC_GET_REVISION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(3), ioc_fm_revision_info_t) -+ -+/**************************************************************************//** -+ @Function FM_IOC_GET_COUNTER -+ -+ @Description Reads one of the FM counters. -+ -+ @Param[in,out] ioc_fm_counters_params_t The requested counter parameters. -+ -+ @Return Counter's current value. -+ -+ @Cautions Allowed only following FM_Init(). -+ Note that it is user's responsibilty to call this routine only -+ for enabled counters, and there will be no indication if a -+ disabled counter is accessed. -+*//***************************************************************************/ -+#define FM_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(4), ioc_fm_counters_params_t) -+ -+/**************************************************************************//** -+ @Function FM_IOC_SET_COUNTER -+ -+ @Description Sets a value to an enabled counter. Use "0" to reset the counter. -+ -+ @Param[in] ioc_fm_counters_params_t The requested counter parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+#define FM_IOC_SET_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(5), ioc_fm_counters_params_t) -+ -+/**************************************************************************//** -+ @Function FM_IOC_FORCE_INTR -+ -+ @Description Causes an interrupt event on the requested source. -+ -+ @Param[in] ioc_fm_exceptions An exception to be forced. -+ -+ @Return E_OK on success; Error code if the exception is not enabled, -+ or is not able to create interrupt. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+#define FM_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(6), ioc_fm_exceptions) -+ -+/**************************************************************************//** -+ @Function FM_IOC_GET_API_VERSION -+ -+ @Description Reads the FMD IOCTL API version. -+ -+ @Param[in,out] ioc_fm_api_version_t The requested counter parameters. -+ -+ @Return Version's value. -+*//***************************************************************************/ -+#define FM_IOC_GET_API_VERSION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(7), ioc_fm_api_version_t) -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Function FM_VSP_Config -+ -+ @Description Creates descriptor for the FM VSP module. -+ -+ The routine returns a handle (descriptor) to the FM VSP object. -+ This descriptor must be passed as first parameter to all other -+ FM VSP function calls. -+ -+ No actual initialization or configuration of FM hardware is -+ done by this routine. -+ -+@Param[in] p_FmVspParams Pointer to data structure of parameters -+ -+ @Retval Handle to FM VSP object, or NULL for Failure. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_IOC_VSP_CONFIG_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_compat_fm_vsp_params_t) -+#endif -+#define FM_IOC_VSP_CONFIG _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_fm_vsp_params_t) -+ -+/**************************************************************************//** -+ @Function FM_VSP_Init -+ -+ @Description Initializes the FM VSP module -+ -+ @Param[in] h_FmVsp - FM VSP module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_IOC_VSP_INIT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_compat_fm_obj_t) -+#endif -+#define FM_IOC_VSP_INIT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_VSP_Free -+ -+ @Description Frees all resources that were assigned to FM VSP module. -+ -+ Calling this routine invalidates the descriptor. -+ -+ @Param[in] h_FmVsp - FM VSP module descriptor -+ -+ @Return E_OK on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_IOC_VSP_FREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_compat_fm_obj_t) -+#endif -+#define FM_IOC_VSP_FREE _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigPoolDepletion -+ -+ @Description Calling this routine enables pause frame generation depending on the -+ depletion status of BM pools. It also defines the conditions to activate -+ this functionality. By default, this functionality is disabled. -+ -+ @Param[in] ioc_fm_buf_pool_depletion_params_t A structure holding the required parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_compat_fm_buf_pool_depletion_params_t) -+#endif -+#define FM_IOC_VSP_CONFIG_POOL_DEPLETION _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_fm_buf_pool_depletion_params_t) -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigBufferPrefixContent -+ -+ @Description Defines the structure, size and content of the application buffer. -+ -+ The prefix will -+ In VSPs defined for Tx ports, if 'passPrsResult', the application -+ should set a value to their offsets in the prefix of -+ the FM will save the first 'privDataSize', than, -+ depending on 'passPrsResult' and 'passTimeStamp', copy parse result -+ and timeStamp, and the packet itself (in this order), to the -+ application buffer, and to offset. -+ -+ Calling this routine changes the buffer margins definitions -+ in the internal driver data base from its default -+ configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize] -+ Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult]. -+ Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp]. -+ -+ @Param[in] ioc_fm_buffer_prefix_content_params_t A structure holding the required parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_compat_fm_buffer_prefix_content_params_t) -+#endif -+#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_fm_buffer_prefix_content_params_t) -+ -+/**************************************************************************//** -+ @Function FM_VSP_ConfigNoScatherGather -+ -+ @Description Calling this routine changes the possibility to receive S/G frame -+ in the internal driver data base -+ from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather] -+ -+ @Param[in] ioc_fm_vsp_config_no_sg_params_t A structure holding the required parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_IOC_VSP_CONFIG_NO_SG_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_compat_fm_vsp_config_no_sg_params_t) -+#endif -+#define FM_IOC_VSP_CONFIG_NO_SG _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_fm_vsp_config_no_sg_params_t) -+ -+/**************************************************************************//** -+ @Function FM_VSP_GetBufferPrsResult -+ -+ @Description Returns the pointer to the parse result in the data buffer. -+ In Rx ports this is relevant after reception, if parse -+ result is configured to be part of the data passed to the -+ application. For non Rx ports it may be used to get the pointer -+ of the area in the buffer where parse result should be -+ initialized - if so configured. -+ See FM_VSP_ConfigBufferPrefixContent for data buffer prefix -+ configuration. -+ -+ @Param[in] ioc_fm_vsp_prs_result_params_t A structure holding the required parameters. -+ -+ @Return Parse result pointer on success, NULL if parse result was not -+ configured for this port. -+ -+ @Cautions Allowed only following FM_VSP_Init(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_compat_fm_vsp_prs_result_params_t) -+#endif -+#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_fm_vsp_prs_result_params_t) -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Function FM_CtrlMonStart -+ -+ @Description Start monitoring utilization of all available FM controllers. -+ -+ In order to obtain FM controllers utilization the following sequence -+ should be used: -+ -# FM_CtrlMonStart() -+ -# FM_CtrlMonStop() -+ -# FM_CtrlMonGetCounters() - issued for each FM controller -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+#define FM_IOC_CTRL_MON_START _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(15)) -+ -+ -+/**************************************************************************//** -+ @Function FM_CtrlMonStop -+ -+ @Description Stop monitoring utilization of all available FM controllers. -+ -+ In order to obtain FM controllers utilization the following sequence -+ should be used: -+ -# FM_CtrlMonStart() -+ -# FM_CtrlMonStop() -+ -# FM_CtrlMonGetCounters() - issued for each FM controller -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+#define FM_IOC_CTRL_MON_STOP _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(16)) -+ -+/**************************************************************************//** -+ @Function FM_CtrlMonGetCounters -+ -+ @Description Obtain FM controller utilization parameters. -+ -+ In order to obtain FM controllers utilization the following sequence -+ should be used: -+ -# FM_CtrlMonStart() -+ -# FM_CtrlMonStop() -+ -# FM_CtrlMonGetCounters() - issued for each FM controller -+ -+ @Param[in] ioc_fm_ctrl_mon_counters_params_t A structure holding the required parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_compat_fm_ctrl_mon_counters_params_t) -+#endif -+#define FM_IOC_CTRL_MON_GET_COUNTERS _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_fm_ctrl_mon_counters_params_t) -+ -+/** @} */ /* end of lnx_ioctl_FM_runtime_control_grp group */ -+/** @} */ /* end of lnx_ioctl_FM_lib_grp group */ -+/** @} */ /* end of lnx_ioctl_FM_grp */ -+ -+#define FMD_API_VERSION_MAJOR 21 -+#define FMD_API_VERSION_MINOR 1 -+#define FMD_API_VERSION_RESPIN 0 -+ -+#endif /* __FM_IOCTLS_H */ ---- /dev/null -+++ b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h -@@ -0,0 +1,3084 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/****************************************************************************** -+ @File fm_pcd_ioctls.h -+ -+ @Description FM PCD ... -+*//***************************************************************************/ -+#ifndef __FM_PCD_IOCTLS_H -+#define __FM_PCD_IOCTLS_H -+ -+#include "net_ioctls.h" -+#include "fm_ioctls.h" -+ -+ -+/**************************************************************************//** -+ -+ @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API -+ -+ @Description Frame Manager Linux ioctls definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FM_PCD_grp FM PCD -+ -+ @Description Frame Manager PCD API functions, definitions and enums -+ -+ The FM PCD module is responsible for the initialization of all -+ global classifying FM modules. This includes the parser general and -+ common registers, the key generator global and common registers, -+ and the policer global and common registers. -+ In addition, the FM PCD SW module will initialize all required -+ key generator schemes, coarse classification flows, and policer -+ profiles. When an FM module is configured to work with one of these -+ entities, it will register to it using the FM PORT API. The PCD -+ module will manage the PCD resources - i.e. resource management of -+ KeyGen schemes, etc. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Collection General PCD defines -+*//***************************************************************************/ -+#define IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */ -+ -+#define IOC_FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */ -+#define IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS) -+ /**< Number of distinction units is limited by -+ register size (32 bits) minus reserved bits -+ for private headers. */ -+#define IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers -+ in a distinction unit */ -+#define IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KeyGen registers */ -+#define IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration; -+ For HW implementation reasons, in most -+ cases less than this will be allowed; The -+ driver will return an initialization error -+ if resource is unavailable. */ -+#define IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */ -+#define IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */ -+ -+#define IOC_FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */ -+#define IOC_FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */ -+ -+#define IOC_FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for -+ insert manipulation */ -+ -+#if DPAA_VERSION >= 11 -+#define IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */ -+#endif /* DPAA_VERSION >= 11 */ -+/* @} */ -+ -+#ifdef FM_CAPWAP_SUPPORT -+#error "FM_CAPWAP_SUPPORT not implemented!" -+#endif -+ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FM_PCD_init_grp FM PCD Initialization Unit -+ -+ @Description Frame Manager PCD Initialization Unit API -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description PCD counters -+ (must match enum e_FmPcdCounters defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_counters { -+ e_IOC_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */ -+ e_IOC_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */ -+ e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */ -+ e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer; -+ This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */ -+ e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer; -+ This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */ -+ e_IOC_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */ -+ e_IOC_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */ -+ e_IOC_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */ -+ e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */ -+ e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */ -+ e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */ -+ e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */ -+ e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L2 parse result is returned with errors. */ -+ e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L3 parse result is returned with errors. */ -+ e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L4 parse result is returned with errors. */ -+ e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times SHIM parse result is returned with errors. */ -+ e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */ -+ e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES, /**< Parser counter - counts the number of cycles stalled waiting for parser internal memory reads while executing soft parser instruction. */ -+ e_IOC_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES, /**< Parser counter - counts the number of cycles spent executing hard parser (including stall cycles). */ -+ e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */ -+ e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */ -+ e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */ -+ e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */ -+ e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */ -+} ioc_fm_pcd_counters; -+ -+/**************************************************************************//** -+ @Description PCD interrupts -+ (must match enum e_FmPcdExceptions defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_exceptions { -+ e_IOC_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */ -+ e_IOC_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */ -+ e_IOC_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */ -+ e_IOC_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */ -+ e_IOC_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */ -+ e_IOC_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */ -+ e_IOC_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */ -+ e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */ -+} ioc_fm_pcd_exceptions; -+ -+/** @} */ /* end of lnx_ioctl_FM_PCD_init_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FM_PCD_Runtime_grp FM PCD Runtime Unit -+ -+ @Description Frame Manager PCD Runtime Unit -+ -+ The runtime control allows creation of PCD infrastructure modules -+ such as Network Environment Characteristics, Classification Plan -+ Groups and Coarse Classification Trees. -+ It also allows on-the-fly initialization, modification and removal -+ of PCD modules such as KeyGen schemes, coarse classification nodes -+ and Policer profiles. -+ -+ In order to explain the programming model of the PCD driver interface -+ a few terms should be explained, and will be used below. -+ - Distinction Header - One of the 16 protocols supported by the FM parser, -+ or one of the SHIM headers (1 or 2). May be a header with a special -+ option (see below). -+ - Interchangeable Headers Group - This is a group of Headers recognized -+ by either one of them. For example, if in a specific context the user -+ chooses to treat IPv4 and IPV6 in the same way, they may create an -+ interchangeable Headers Unit consisting of these 2 headers. -+ - A Distinction Unit - a Distinction Header or an Interchangeable Headers -+ Group. -+ - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and -+ IPv6, includes multicast, broadcast and other protocol specific options. -+ In terms of hardware it relates to the options available in the classification -+ plan. -+ - Network Environment Characteristics - a set of Distinction Units that define -+ the total recognizable header selection for a certain environment. This is -+ NOT the list of all headers that will ever appear in a flow, but rather -+ everything that needs distinction in a flow, where distinction is made by KeyGen -+ schemes and coarse classification action descriptors. -+ -+ The PCD runtime modules initialization is done in stages. The first stage after -+ initializing the PCD module itself is to establish a Network Flows Environment -+ Definition. The application may choose to establish one or more such environments. -+ Later, when needed, the application will have to state, for some of its modules, -+ to which single environment it belongs. -+ -+ @{ -+*//***************************************************************************/ -+ -+ -+/**************************************************************************//** -+ @Description structure for FM counters -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_counters_params_t { -+ ioc_fm_pcd_counters cnt; /**< The requested counter */ -+ uint32_t val; /**< The requested value to get/set from/into the counter */ -+} ioc_fm_pcd_counters_params_t; -+ -+/**************************************************************************//** -+ @Description structure for FM exception definitios -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_exception_params_t { -+ ioc_fm_pcd_exceptions exception; /**< The requested exception */ -+ bool enable; /**< TRUE to enable interrupt, FALSE to mask it. */ -+} ioc_fm_pcd_exception_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for SW parser labels -+ (must be identical to struct t_FmPcdPrsLabelParams defined in fm_pcd_ext.h) -+ *//***************************************************************************/ -+typedef struct ioc_fm_pcd_prs_label_params_t { -+ uint32_t instruction_offset; /**< SW parser label instruction offset (2 bytes -+ resolution), relative to Parser RAM. */ -+ ioc_net_header_type hdr; /**< The existence of this header will invoke -+ the SW parser code. */ -+ uint8_t index_per_hdr; /**< Normally 0, if more than one SW parser -+ attachments for the same header, use this -+ index to distinguish between them. */ -+} ioc_fm_pcd_prs_label_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for SW parser -+ (Must match struct t_FmPcdPrsSwParams defined in fm_pcd_ext.h) -+ *//***************************************************************************/ -+typedef struct ioc_fm_pcd_prs_sw_params_t { -+ bool override; /**< FALSE to invoke a check that nothing else -+ was loaded to this address, including -+ internal patches. -+ TRUE to override any existing code.*/ -+ uint32_t size; /**< SW parser code size */ -+ uint16_t base; /**< SW parser base (in instruction counts! -+ must be larger than 0x20)*/ -+ uint8_t *p_code; /**< SW parser code */ -+ uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS]; -+ /**< SW parser data (parameters) */ -+ uint8_t num_of_labels; /**< Number of labels for SW parser. */ -+ ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS]; -+ /**< SW parser labels table, -+ containing num_of_labels entries */ -+} ioc_fm_pcd_prs_sw_params_t; -+ -+/**************************************************************************//** -+ @Description A structure to set the a KeyGen default value -+ *//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_dflt_value_params_t { -+ uint8_t valueId; /**< 0,1 - one of 2 global default values */ -+ uint32_t value; /**< The requested default value */ -+} ioc_fm_pcd_kg_dflt_value_params_t; -+ -+ -+/**************************************************************************//** -+ @Function FM_PCD_Enable -+ -+ @Description This routine should be called after PCD is initialized for enabling all -+ PCD engines according to their existing configuration. -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only when PCD is disabled. -+*//***************************************************************************/ -+#define FM_PCD_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(1)) -+ -+/**************************************************************************//** -+ @Function FM_PCD_Disable -+ -+ @Description This routine may be called when PCD is enabled in order to -+ disable all PCD engines. It may be called -+ only when none of the ports in the system are using the PCD. -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only when PCD is enabled. -+*//***************************************************************************/ -+#define FM_PCD_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(2)) -+ -+ /**************************************************************************//** -+ @Function FM_PCD_PrsLoadSw -+ -+ @Description This routine may be called only when all ports in the -+ system are actively using the classification plan scheme. -+ In such cases it is recommended in order to save resources. -+ The driver automatically saves 8 classification plans for -+ ports that do NOT use the classification plan mechanism, to -+ avoid this (in order to save those entries) this routine may -+ be called. -+ -+ @Param[in] ioc_fm_pcd_prs_sw_params_t A pointer to the image of the software parser code. -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only when PCD is disabled. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_PRS_LOAD_SW_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_compat_fm_pcd_prs_sw_params_t) -+#endif -+#define FM_PCD_IOC_PRS_LOAD_SW _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_fm_pcd_prs_sw_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_KgSetDfltValue -+ -+ @Description Calling this routine sets a global default value to be used -+ by the KeyGen when parser does not recognize a required -+ field/header. -+ By default default values are 0. -+ -+ @Param[in] ioc_fm_pcd_kg_dflt_value_params_t A pointer to a structure with the relevant parameters -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only when PCD is disabled. -+*//***************************************************************************/ -+#define FM_PCD_IOC_KG_SET_DFLT_VALUE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(6), ioc_fm_pcd_kg_dflt_value_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_KgSetAdditionalDataAfterParsing -+ -+ @Description Calling this routine allows the keygen to access data past -+ the parser finishing point. -+ -+ @Param[in] uint8_t payload-offset; the number of bytes beyond the parser location. -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only when PCD is disabled. -+*//***************************************************************************/ -+#define FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(7), uint8_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_SetException -+ -+ @Description Calling this routine enables/disables PCD interrupts. -+ -+ @Param[in] ioc_fm_pcd_exception_params_t Arguments struct with exception to be enabled/disabled. -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#define FM_PCD_IOC_SET_EXCEPTION _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(8), ioc_fm_pcd_exception_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_GetCounter -+ -+ @Description Reads one of the FM PCD counters. -+ -+ @Param[in,out] ioc_fm_pcd_counters_params_t The requested counter parameters. -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Note that it is user's responsibilty to call this routine only -+ for enabled counters, and there will be no indication if a -+ disabled counter is accessed. -+*//***************************************************************************/ -+#define FM_PCD_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(9), ioc_fm_pcd_counters_params_t) -+ -+/**************************************************************************//** -+ -+ @Function FM_PCD_KgSchemeGetCounter -+ -+ @Description Reads scheme packet counter. -+ -+ @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet(). -+ -+ @Return Counter's current value. -+ -+ @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT _IOR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(4), ioc_compat_fm_pcd_kg_scheme_spc_t) -+#endif -+#define FM_PCD_IOC_KG_SCHEME_GET_CNTR _IOR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(4), ioc_fm_pcd_kg_scheme_spc_t) -+ -+#if 0 -+TODO: unused IOCTL -+/**************************************************************************//** -+ @Function FM_PCD_ModifyCounter -+ -+ @Description Writes a value to an enabled counter. Use "0" to reset the counter. -+ -+ @Param[in] ioc_fm_pcd_counters_params_t - The requested counter parameters. -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#define FM_PCD_IOC_MODIFY_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(10), ioc_fm_pcd_counters_params_t) -+#define FM_PCD_IOC_SET_COUNTER FM_PCD_IOC_MODIFY_COUNTER -+#endif -+ -+/**************************************************************************//** -+ @Function FM_PCD_ForceIntr -+ -+ @Description Causes an interrupt event on the requested source. -+ -+ @Param[in] ioc_fm_pcd_exceptions - An exception to be forced. -+ -+ @Return 0 on success; error code if the exception is not enabled, -+ or is not able to create interrupt. -+*//***************************************************************************/ -+#define FM_PCD_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(11), ioc_fm_pcd_exceptions) -+ -+/**************************************************************************//** -+ @Collection Definitions of coarse classification parameters as required by KeyGen -+ (when coarse classification is the next engine after this scheme). -+*//***************************************************************************/ -+#define IOC_FM_PCD_MAX_NUM_OF_CC_TREES 8 -+#define IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS 16 -+#define IOC_FM_PCD_MAX_NUM_OF_CC_UNITS 4 -+#define IOC_FM_PCD_MAX_NUM_OF_KEYS 256 -+#define IOC_FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE) -+#define IOC_FM_PCD_MAX_SIZE_OF_KEY 56 -+#define IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16 -+#define IOC_FM_PCD_LAST_KEY_INDEX 0xffff -+#define IOC_FM_PCD_MANIP_DSCP_VALUES 64 -+/* @} */ -+ -+/**************************************************************************//** -+ @Collection A set of definitions to allow protocol -+ special option description. -+*//***************************************************************************/ -+typedef uint32_t ioc_protocol_opt_t; /**< A general type to define a protocol option. */ -+ -+typedef ioc_protocol_opt_t ioc_eth_protocol_opt_t; /**< Ethernet protocol options. */ -+#define IOC_ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */ -+#define IOC_ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */ -+ -+typedef ioc_protocol_opt_t ioc_vlan_protocol_opt_t; /**< Vlan protocol options. */ -+#define IOC_VLAN_STACKED 0x20000000 /**< Stacked VLAN. */ -+ -+typedef ioc_protocol_opt_t ioc_mpls_protocol_opt_t; /**< MPLS protocol options. */ -+#define IOC_MPLS_STACKED 0x10000000 /**< Stacked MPLS. */ -+ -+typedef ioc_protocol_opt_t ioc_ipv4_protocol_opt_t; /**< IPv4 protocol options. */ -+#define IOC_IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */ -+#define IOC_IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */ -+#define IOC_IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */ -+#define IOC_IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */ -+ -+#define IOC_IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option. -+ IPV4 Reassembly manipulation requires network -+ environment with IPV4 header and IPV4_FRAG_1 option */ -+ -+typedef ioc_protocol_opt_t ioc_ipv6_protocol_opt_t; /**< IPv6 protocol options. */ -+#define IOC_IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */ -+#define IOC_IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */ -+#define IOC_IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */ -+ -+#define IOC_IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option. -+ IPV6 Reassembly manipulation requires network -+ environment with IPV6 header and IPV6_FRAG_1 option */ -+#if (DPAA_VERSION >= 11) -+typedef ioc_protocol_opt_t ioc_capwap_protocol_opt_t; /**< CAPWAP protocol options. */ -+#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option. -+ CAPWAP Reassembly manipulation requires network -+ environment with CAPWAP header and CAPWAP_FRAG_1 option; -+ in case where fragment found, the fragment-extension offset -+ may be found at 'shim2' (in parser-result). */ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/* @} */ -+ -+#define IOC_FM_PCD_MANIP_MAX_HDR_SIZE 256 -+#define IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64 -+/**************************************************************************//** -+ @Collection A set of definitions to support Header Manipulation selection. -+*//***************************************************************************/ -+typedef uint32_t ioc_hdr_manip_flags_t; /**< A general type to define a HMan update command flags. */ -+ -+typedef ioc_hdr_manip_flags_t ioc_ipv4_hdr_manip_update_flags_t; /**< IPv4 protocol HMan update command flags. */ -+ -+#define IOC_HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field -+ of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */ -+#define IOC_HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field -+ of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */ -+#define IOC_HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */ -+#define IOC_HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value -+ ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */ -+#define IOC_HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value -+ ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */ -+ -+typedef ioc_hdr_manip_flags_t ioc_ipv6_hdr_manip_update_flags_t; /**< IPv6 protocol HMan update command flags. */ -+ -+#define IOC_HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value -+ ('traffic_class' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */ -+#define IOC_HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */ -+#define IOC_HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value -+ ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */ -+#define IOC_HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value -+ ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */ -+ -+typedef ioc_hdr_manip_flags_t ioc_tcp_udp_hdr_manip_update_flags_t;/**< TCP/UDP protocol HMan update command flags. */ -+ -+#define IOC_HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value -+ ('src' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */ -+#define IOC_HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value -+ ('dst' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */ -+#define IOC_HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */ -+ -+/* @} */ -+ -+/**************************************************************************//** -+ @Description A type used for returning the order of the key extraction. -+ each value in this array represents the index of the extraction -+ command as defined by the user in the initialization extraction array. -+ The valid size of this array is the user define number of extractions -+ required (also marked by the second '0' in this array). -+*//***************************************************************************/ -+typedef uint8_t ioc_fm_pcd_kg_key_order_t [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; -+ -+/**************************************************************************//** -+ @Description All PCD engines -+ (must match enum e_FmPcdEngine defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_engine { -+ e_IOC_FM_PCD_INVALID = 0, /**< Invalid PCD engine */ -+ e_IOC_FM_PCD_DONE, /**< No PCD Engine indicated */ -+ e_IOC_FM_PCD_KG, /**< KeyGen */ -+ e_IOC_FM_PCD_CC, /**< Coarse Classifier */ -+ e_IOC_FM_PCD_PLCR, /**< Policer */ -+ e_IOC_FM_PCD_PRS, /**< Parser */ -+#if DPAA_VERSION >= 11 -+ e_IOC_FM_PCD_FR, /**< Frame Replicator */ -+#endif /* DPAA_VERSION >= 11 */ -+ e_IOC_FM_PCD_HASH /**< Hash Table */ -+} ioc_fm_pcd_engine; -+ -+/**************************************************************************//** -+ @Description An enum for selecting extraction by header types -+ (Must match enum e_FmPcdExtractByHdrType defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_extract_by_hdr_type { -+ e_IOC_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */ -+ e_IOC_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */ -+ e_IOC_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */ -+} ioc_fm_pcd_extract_by_hdr_type; -+ -+/**************************************************************************//** -+ @Description An enum for selecting extraction source (when it is not the header) -+ (Must match enum e_FmPcdExtractFrom defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_extract_from { -+ e_IOC_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */ -+ e_IOC_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */ -+ e_IOC_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */ -+ e_IOC_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */ -+ e_IOC_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */ -+ e_IOC_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */ -+ e_IOC_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */ -+ e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */ -+} ioc_fm_pcd_extract_from; -+ -+/**************************************************************************//** -+ @Description An enum for selecting extraction type -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_extract_type { -+ e_IOC_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */ -+ e_IOC_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */ -+ e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */ -+} ioc_fm_pcd_extract_type; -+ -+/**************************************************************************//** -+ @Description An enum for selecting a default -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_kg_extract_dflt_select { -+ e_IOC_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */ -+ e_IOC_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */ -+ e_IOC_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */ -+ e_IOC_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */ -+ e_IOC_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */ -+} ioc_fm_pcd_kg_extract_dflt_select; -+ -+/**************************************************************************//** -+ @Description Enumeration type defining all default groups - each group shares -+ a default value, one of four user-initialized values. -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_kg_known_fields_dflt_types { -+ e_IOC_FM_PCD_KG_MAC_ADDR, /**< MAC Address */ -+ e_IOC_FM_PCD_KG_TCI, /**< TCI field */ -+ e_IOC_FM_PCD_KG_ENET_TYPE, /**< ENET Type */ -+ e_IOC_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */ -+ e_IOC_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */ -+ e_IOC_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */ -+ e_IOC_FM_PCD_KG_IP_ADDR, /**< IP addr */ -+ e_IOC_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */ -+ e_IOC_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */ -+ e_IOC_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */ -+ e_IOC_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */ -+ e_IOC_FM_PCD_KG_L4_PORT, /**< L4 Port */ -+ e_IOC_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */ -+ e_IOC_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW, -+ any data extraction that is not the full -+ field described above */ -+ e_IOC_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW, -+ any data extraction without validation */ -+ e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW, -+ extraction from parser result or -+ direct use of default value */ -+} ioc_fm_pcd_kg_known_fields_dflt_types; -+ -+/**************************************************************************//** -+ @Description Enumeration type for defining header index for scenarios with -+ multiple (tunneled) headers -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_hdr_index { -+ e_IOC_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also -+ to specify regular IP (not tunneled). */ -+ e_IOC_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */ -+ e_IOC_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */ -+ e_IOC_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */ -+ e_IOC_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */ -+} ioc_fm_pcd_hdr_index; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the policer profile functional type -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_profile_type_selection { -+ e_IOC_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */ -+ e_IOC_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */ -+} ioc_fm_pcd_profile_type_selection; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the policer profile algorithm -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_plcr_algorithm_selection { -+ e_IOC_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */ -+ e_IOC_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */ -+ e_IOC_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */ -+} ioc_fm_pcd_plcr_algorithm_selection; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting a policer profile color mode -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_plcr_color_mode { -+ e_IOC_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */ -+ e_IOC_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */ -+} ioc_fm_pcd_plcr_color_mode; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting a policer profile color -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_plcr_color { -+ e_IOC_FM_PCD_PLCR_GREEN, /**< Green */ -+ e_IOC_FM_PCD_PLCR_YELLOW, /**< Yellow */ -+ e_IOC_FM_PCD_PLCR_RED, /**< Red */ -+ e_IOC_FM_PCD_PLCR_OVERRIDE /**< Color override */ -+} ioc_fm_pcd_plcr_color; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the policer profile packet frame length selector -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_plcr_frame_length_select { -+ e_IOC_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */ -+ e_IOC_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */ -+ e_IOC_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */ -+ e_IOC_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */ -+} ioc_fm_pcd_plcr_frame_length_select; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting roll-back frame -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_plcr_roll_back_frame_select { -+ e_IOC_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */ -+ e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */ -+} ioc_fm_pcd_plcr_roll_back_frame_select; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the policer profile packet or byte mode -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_plcr_rate_mode { -+ e_IOC_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */ -+ e_IOC_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */ -+} ioc_fm_pcd_plcr_rate_mode; -+ -+/**************************************************************************//** -+ @Description Enumeration type for defining action of frame -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_done_action { -+ e_IOC_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */ -+ e_IOC_FM_PCD_DROP_FRAME /**< Drop frame */ -+} ioc_fm_pcd_done_action; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the policer counter -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_plcr_profile_counters { -+ e_IOC_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */ -+ e_IOC_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */ -+ e_IOC_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */ -+ e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */ -+ e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */ -+} ioc_fm_pcd_plcr_profile_counters; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting the PCD action after extraction -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_action { -+ e_IOC_FM_PCD_ACTION_NONE, /**< NONE */ -+ e_IOC_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/ -+ e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/ -+} ioc_fm_pcd_action; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of insert manipulation -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_insrt_type { -+ e_IOC_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */ -+ e_IOC_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */ -+#endif /* FM_CAPWAP_SUPPORT */ -+} ioc_fm_pcd_manip_hdr_insrt_type; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of remove manipulation -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_rmv_type { -+ e_IOC_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */ -+ e_IOC_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */ -+} ioc_fm_pcd_manip_hdr_rmv_type; -+ -+/**************************************************************************//** -+ @Description An enum for selecting specific L2 fields removal -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_rmv_specific_l2 { -+ e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */ -+ e_IOC_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */ -+ e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until -+ the header which follows the MPLS header */ -+ e_IOC_FM_PCD_MANIP_HDR_RMV_MPLS /**< Remove MPLS header (Unlimited MPLS labels) */ -+} ioc_fm_pcd_manip_hdr_rmv_specific_l2; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting specific fields updates -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_field_update_type { -+ e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */ -+ e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */ -+ e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */ -+ e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */ -+} ioc_fm_pcd_manip_hdr_field_update_type; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting VLAN updates -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_field_update_vlan { -+ e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */ -+ e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */ -+} ioc_fm_pcd_manip_hdr_field_update_vlan; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting specific L2 fields removal -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_insrt_specific_l2 { -+ e_IOC_FM_PCD_MANIP_HDR_INSRT_MPLS /**< Insert MPLS header (Unlimited MPLS labels) */ -+} ioc_fm_pcd_manip_hdr_insrt_specific_l2; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Enumeration type for selecting QoS mapping mode -+ -+ Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE' -+ User should instruct the port to read the parser-result -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_qos_mapping_mode { -+ e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */ -+ e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the parser-result. */ -+} ioc_fm_pcd_manip_hdr_qos_mapping_mode; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting QoS source -+ -+ Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE' -+ User should left room for the parser-result on input/output buffer -+ and instruct the port to read/write the parser-result to the buffer (RPD should be set) -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_qos_src { -+ e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */ -+ e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the parser-result. */ -+} ioc_fm_pcd_manip_hdr_qos_src; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of header insertion -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_insrt_by_hdr_type { -+ e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */ -+#if (DPAA_VERSION >= 11) -+ e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */ -+ e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */ -+ e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */ -+ e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */ -+#endif /* (DPAA_VERSION >= 11) */ -+} ioc_fm_pcd_manip_hdr_insrt_by_hdr_type; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting specific custom command -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_custom_type { -+ e_IOC_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */ -+} ioc_fm_pcd_manip_hdr_custom_type; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting specific custom command -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_custom_ip_replace { -+ e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */ -+ e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */ -+} ioc_fm_pcd_manip_hdr_custom_ip_replace; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of header removal -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_hdr_rmv_by_hdr_type { -+ e_IOC_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */ -+#if (DPAA_VERSION >= 11) -+ e_IOC_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */ -+#endif /* (DPAA_VERSION >= 11) */ -+#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+ e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */ -+#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */ -+} ioc_fm_pcd_manip_hdr_rmv_by_hdr_type; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of timeout mode -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_reassem_time_out_mode { -+ e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process -+ from the first fragment to the last */ -+ e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */ -+} ioc_fm_pcd_manip_reassem_time_out_mode; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of WaysNumber mode -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_reassem_ways_number { -+ e_IOC_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */ -+ e_IOC_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */ -+ e_IOC_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */ -+ e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */ -+ e_IOC_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */ -+ e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */ -+ e_IOC_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */ -+ e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */ -+} ioc_fm_pcd_manip_reassem_ways_number; -+ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of statistics mode -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_stats { -+ e_IOC_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */ -+} ioc_fm_pcd_stats; -+#endif -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting manipulation type -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_type { -+ e_IOC_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */ -+ e_IOC_FM_PCD_MANIP_REASSEM, /**< Reassembly */ -+ e_IOC_FM_PCD_MANIP_FRAG, /**< Fragmentation */ -+ e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */ -+} ioc_fm_pcd_manip_type; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of statistics mode -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_cc_stats_mode { -+ e_IOC_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */ -+ e_IOC_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */ -+ e_IOC_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */ -+#if (DPAA_VERSION >= 11) -+ e_IOC_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics */ -+#endif /* (DPAA_VERSION >= 11) */ -+} ioc_fm_pcd_cc_stats_mode; -+ -+/**************************************************************************//** -+ @Description Enumeration type for determining the action in case an IP packet -+ is larger than MTU but its DF (Don't Fragment) bit is set. -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_dont_frag_action { -+ e_IOC_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */ -+ e_IOC_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_IOC_FM_PCD_MANIP_DISCARD_PACKET, -+ /**< Obsolete, cannot enqueue to error queue; -+ In practice, selects to discard packets; -+ Will be removed in the future */ -+ e_IOC_FM_PCD_MANIP_FRAGMENT_PACKECT, /**< Fragment packet and continue normal processing */ -+ e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */ -+} ioc_fm_pcd_manip_dont_frag_action; -+ -+/**************************************************************************//** -+ @Description Enumeration type for selecting type of special offload manipulation -+*//***************************************************************************/ -+typedef enum ioc_fm_pcd_manip_special_offload_type { -+ e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */ -+#if (DPAA_VERSION >= 11) -+ e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */ -+#endif /* (DPAA_VERSION >= 11) */ -+} ioc_fm_pcd_manip_special_offload_type; -+ -+/**************************************************************************//** -+ @Description A union of protocol dependent special options -+ (Must match union u_FmPcdHdrProtocolOpt defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef union ioc_fm_pcd_hdr_protocol_opt_u { -+ ioc_eth_protocol_opt_t eth_opt; /**< Ethernet options */ -+ ioc_vlan_protocol_opt_t vlan_opt; /**< Vlan options */ -+ ioc_mpls_protocol_opt_t mpls_opt; /**< MPLS options */ -+ ioc_ipv4_protocol_opt_t ipv4_opt; /**< IPv4 options */ -+ ioc_ipv6_protocol_opt_t ipv6_opt; /**< IPv6 options */ -+#if (DPAA_VERSION >= 11) -+ ioc_capwap_protocol_opt_t capwap_opt; /**< CAPWAP options */ -+#endif /* (DPAA_VERSION >= 11) */ -+} ioc_fm_pcd_hdr_protocol_opt_u; -+ -+/**************************************************************************//** -+ @Description A union holding all known protocol fields -+*//***************************************************************************/ -+typedef union ioc_fm_pcd_fields_u { -+ ioc_header_field_eth_t eth; /**< Ethernet */ -+ ioc_header_field_vlan_t vlan; /**< VLAN */ -+ ioc_header_field_llc_snap_t llc_snap; /**< LLC SNAP */ -+ ioc_header_field_pppoe_t pppoe; /**< PPPoE */ -+ ioc_header_field_mpls_t mpls; /**< MPLS */ -+ ioc_header_field_ip_t ip; /**< IP */ -+ ioc_header_field_ipv4_t ipv4; /**< IPv4 */ -+ ioc_header_field_ipv6_t ipv6; /**< IPv6 */ -+ ioc_header_field_udp_t udp; /**< UDP */ -+ ioc_header_field_udp_lite_t udp_lite; /**< UDP_Lite */ -+ ioc_header_field_tcp_t tcp; /**< TCP */ -+ ioc_header_field_sctp_t sctp; /**< SCTP */ -+ ioc_header_field_dccp_t dccp; /**< DCCP */ -+ ioc_header_field_gre_t gre; /**< GRE */ -+ ioc_header_field_minencap_t minencap; /**< Minimal Encapsulation */ -+ ioc_header_field_ipsec_ah_t ipsec_ah; /**< IPSec AH */ -+ ioc_header_field_ipsec_esp_t ipsec_esp; /**< IPSec ESP */ -+ ioc_header_field_udp_encap_esp_t udp_encap_esp; /**< UDP Encapsulation ESP */ -+} ioc_fm_pcd_fields_u; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header extraction for key generation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_from_hdr_t { -+ uint8_t size; /**< Size in byte */ -+ uint8_t offset; /**< Byte offset */ -+} ioc_fm_pcd_from_hdr_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining field extraction for key generation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_from_field_t { -+ ioc_fm_pcd_fields_u field; /**< Field selection */ -+ uint8_t size; /**< Size in byte */ -+ uint8_t offset; /**< Byte offset */ -+} ioc_fm_pcd_from_field_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a single network environment unit -+ A distinction unit should be defined if it will later be used -+ by one or more PCD engines to distinguish between flows. -+ (Must match struct t_FmPcdDistinctionUnit defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_distinction_unit_t { -+ struct { -+ ioc_net_header_type hdr; /**< One of the headers supported by the FM */ -+ ioc_fm_pcd_hdr_protocol_opt_u opt; /**< Select only one option! */ -+ } hdrs[IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS]; -+} ioc_fm_pcd_distinction_unit_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining all different distinction units supported -+ by a specific PCD Network Environment Characteristics module. -+ -+ Each unit represent a protocol or a group of protocols that may -+ be used later by the different PCD engines to distinguish between flows. -+ (Must match struct t_FmPcdNetEnvParams defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_net_env_params_t { -+ uint8_t num_of_distinction_units;/**< Number of different units to be identified */ -+ ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; -+ /**< An array of num_of_distinction_units of the -+ different units to be identified */ -+ void *id; /**< Output parameter; Returns the net-env Id to be used */ -+} ioc_fm_pcd_net_env_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a single extraction action when -+ creating a key -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_extract_entry_t { -+ ioc_fm_pcd_extract_type type; /**< Extraction type select */ -+ union { -+ struct { -+ ioc_net_header_type hdr; /**< Header selection */ -+ bool ignore_protocol_validation; -+ /**< Ignore protocol validation */ -+ ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled -+ IP. Otherwise should be cleared.*/ -+ ioc_fm_pcd_extract_by_hdr_type type; /**< Header extraction type select */ -+ union { -+ ioc_fm_pcd_from_hdr_t from_hdr; /**< Extract bytes from header parameters */ -+ ioc_fm_pcd_from_field_t from_field; /**< Extract bytes from field parameters */ -+ ioc_fm_pcd_fields_u full_field; /**< Extract full field parameters */ -+ } extract_by_hdr_type; -+ } extract_by_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */ -+ struct { -+ ioc_fm_pcd_extract_from src; /**< Non-header extraction source */ -+ ioc_fm_pcd_action action; /**< Relevant for CC Only */ -+ uint16_t ic_indx_mask; /**< Relevant only for CC when -+ action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP; -+ Note that the number of bits that are set within -+ this mask must be log2 of the CC-node 'num_of_keys'. -+ Note that the mask cannot be set on the lower bits. */ -+ uint8_t offset; /**< Byte offset */ -+ uint8_t size; /**< Size in bytes */ -+ } extract_non_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */ -+ } extract_params; -+} ioc_fm_pcd_extract_entry_t; -+ -+/**************************************************************************//** -+ @Description A structure for defining masks for each extracted -+ field in the key. -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_extract_mask_t { -+ uint8_t extract_array_index; /**< Index in the extraction array, as initialized by user */ -+ uint8_t offset; /**< Byte offset */ -+ uint8_t mask; /**< A byte mask (selected bits will be ignored) */ -+} ioc_fm_pcd_kg_extract_mask_t; -+ -+/**************************************************************************//** -+ @Description A structure for defining default selection per groups -+ of fields -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_extract_dflt_t { -+ ioc_fm_pcd_kg_known_fields_dflt_types type; /**< Default type select*/ -+ ioc_fm_pcd_kg_extract_dflt_select dflt_select; /**< Default register select */ -+} ioc_fm_pcd_kg_extract_dflt_t; -+ -+ -+/**************************************************************************//** -+ @Description A structure for defining all parameters needed for -+ generation a key and using a hash function -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_key_extract_and_hash_params_t { -+ uint32_t private_dflt0; /**< Scheme default register 0 */ -+ uint32_t private_dflt1; /**< Scheme default register 1 */ -+ uint8_t num_of_used_extracts; /**< defines the valid size of the following array */ -+ ioc_fm_pcd_extract_entry_t extract_array [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; -+ /**< An array of extraction definitions. */ -+ uint8_t num_of_used_dflts; /**< defines the valid size of the following array */ -+ ioc_fm_pcd_kg_extract_dflt_t dflts[IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS]; -+ /**< For each extraction used in this scheme, specify the required -+ default register to be used when header is not found. -+ types not specified in this array will get undefined value. */ -+ uint8_t num_of_used_masks; /**< Defines the valid size of the following array */ -+ ioc_fm_pcd_kg_extract_mask_t masks[IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS]; -+ uint8_t hash_shift; /**< Hash result right shift. -+ Selects the 24 bits out of the 64 hash result. -+ 0 means using the 24 LSB's, otherwise use the -+ 24 LSB's after shifting right.*/ -+ uint32_t hash_distribution_num_of_fqids; /**< must be > 1 and a power of 2. Represents the range -+ of queues for the key and hash functionality */ -+ uint8_t hash_distribution_fqids_shift; /**< selects the FQID bits that will be effected by the hash */ -+ bool symmetric_hash; /**< TRUE to generate the same hash for frames with swapped source and -+ destination fields on all layers; If TRUE, driver will check that for -+ all layers, if SRC extraction is selected, DST extraction must also be -+ selected, and vice versa. */ -+} ioc_fm_pcd_kg_key_extract_and_hash_params_t; -+ -+/**************************************************************************//** -+ @Description A structure of parameters for defining a single -+ Qid mask (extracted OR). -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_extracted_or_params_t { -+ ioc_fm_pcd_extract_type type; /**< Extraction type select */ -+ union { -+ struct { /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */ -+ ioc_net_header_type hdr; -+ ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled -+ IP. Otherwise should be cleared.*/ -+ bool ignore_protocol_validation; -+ -+ } extract_by_hdr; -+ ioc_fm_pcd_extract_from src; /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */ -+ } extract_params; -+ uint8_t extraction_offset; /**< Offset for extraction */ -+ ioc_fm_pcd_kg_extract_dflt_select dflt_value; /**< Select register from which extraction is taken if -+ field not found */ -+ uint8_t mask; /**< Mask LSB byte of extraction (specified bits are ignored) */ -+ uint8_t bit_offset_in_fqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using -+ the extracted byte; Assume byte is placed as the 8 MSB's in -+ a 32 bit word where the lower bits -+ are the FQID; i.e if bitOffsetInFqid=1 than its LSB -+ will effect the FQID MSB, if bitOffsetInFqid=24 than the -+ extracted byte will effect the 8 LSB's of the FQID, -+ if bitOffsetInFqid=31 than the byte's MSB will effect -+ the FQID's LSB; 0 means - no effect on FQID; -+ Note that one, and only one of -+ bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e, -+ extracted byte must effect either FQID or Policer profile).*/ -+ uint8_t bit_offset_in_plcr_profile; -+ /**< 0-15, Selects which bits of the 8 policer profile id bits to -+ effect using the extracted byte; Assume byte is placed -+ as the 8 MSB's in a 16 bit word where the lower bits -+ are the policer profile id; i.e if bitOffsetInPlcrProfile=1 -+ than its LSB will effect the profile MSB, if bitOffsetInFqid=8 -+ than the extracted byte will effect the whole policer profile id, -+ if bitOffsetInFqid=15 than the byte's MSB will effect -+ the Policer Profile id's LSB; -+ 0 means - no effect on policer profile; Note that one, and only one of -+ bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e, -+ extracted byte must effect either FQID or Policer profile).*/ -+} ioc_fm_pcd_kg_extracted_or_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for configuring scheme counter -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_scheme_counter_t { -+ bool update; /**< FALSE to keep the current counter state -+ and continue from that point, TRUE to update/reset -+ the counter when the scheme is written. */ -+ uint32_t value; /**< If update=TRUE, this value will be written into the -+ counter; clear this field to reset the counter. */ -+} ioc_fm_pcd_kg_scheme_counter_t; -+ -+ -+/**************************************************************************//** -+ @Description A structure for retrieving FMKG_SE_SPC -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_scheme_spc_t { -+ uint32_t val; /**< return value */ -+ void *id; /**< scheme handle */ -+} ioc_fm_pcd_kg_scheme_spc_t; -+ -+/**************************************************************************//** -+ @Description A structure for defining policer profile parameters as required by keygen -+ (when policer is the next engine after this scheme). -+ (Must match struct t_FmPcdKgPlcrProfile defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_plcr_profile_t { -+ bool shared_profile; /**< TRUE if this profile is shared between ports -+ (i.e. managed by master partition) May not be TRUE -+ if profile is after Coarse Classification*/ -+ bool direct; /**< If TRUE, direct_relative_profile_id only selects the profile -+ id, if FALSE fqid_offset_relative_profile_id_base is used -+ together with fqid_offset_shift and num_of_profiles -+ parameters, to define a range of profiles from -+ which the KeyGen result will determine the -+ destination policer profile. */ -+ union { -+ uint16_t direct_relative_profile_id; /**< Used if 'direct' is TRUE, to select policer profile. -+ This parameter should indicate the policer profile offset within the port's -+ policer profiles or SHARED window. */ -+ struct { -+ uint8_t fqid_offset_shift; /**< Shift of KG results without the qid base */ -+ uint8_t fqid_offset_relative_profile_id_base; -+ /**< OR of KG results without the qid base -+ This parameter should indicate the policer profile -+ offset within the port's policer profiles window -+ or SHARED window depends on shared_profile */ -+ uint8_t num_of_profiles; /**< Range of profiles starting at base */ -+ } indirect_profile; /**< Indirect profile parameters */ -+ } profile_select; /**< Direct/indirect profile selection and parameters */ -+} ioc_fm_pcd_kg_plcr_profile_t; -+ -+#if DPAA_VERSION >= 11 -+/**************************************************************************//** -+ @Description Parameters for configuring a storage profile for a KeyGen scheme. -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_storage_profile_t { -+ bool direct; /**< If TRUE, directRelativeProfileId only selects the -+ profile id; -+ If FALSE, fqidOffsetRelativeProfileIdBase is used -+ together with fqidOffsetShift and numOfProfiles -+ parameters to define a range of profiles from which -+ the KeyGen result will determine the destination -+ storage profile. */ -+ union { -+ uint16_t direct_relative_profileId; /**< Used when 'direct' is TRUE, to select a storage profile; -+ should indicate the storage profile offset within the -+ port's storage profiles window. */ -+ struct { -+ uint8_t fqid_offset_shift; /**< Shift of KeyGen results without the FQID base */ -+ uint8_t fqid_offset_relative_profile_id_base; -+ /**< OR of KeyGen results without the FQID base; -+ should indicate the policer profile offset within the -+ port's storage profiles window. */ -+ uint8_t num_of_profiles; /**< Range of profiles starting at base. */ -+ } indirect_profile; /**< Indirect profile parameters. */ -+ } profile_select; /**< Direct/indirect profile selection and parameters. */ -+} ioc_fm_pcd_kg_storage_profile_t; -+#endif /* DPAA_VERSION >= 11 */ -+ -+/**************************************************************************//** -+ @Description Parameters for defining CC as the next engine after KeyGen -+ (Must match struct t_FmPcdKgCc defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_cc_t { -+ void *tree_id; /**< CC Tree id */ -+ uint8_t grp_id; /**< CC group id within the CC tree */ -+ bool plcr_next; /**< TRUE if after CC, in case of data frame, -+ policing is required. */ -+ bool bypass_plcr_profile_generation; -+ /**< TRUE to bypass KeyGen policer profile generation; -+ selected profile is the one set at port initialization. */ -+ ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Valid only if plcr_next = TRUE and -+ bypass_plcr_profile_generation = FALSE */ -+} ioc_fm_pcd_kg_cc_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining initializing a KeyGen scheme -+ (Must match struct t_FmPcdKgSchemeParams defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_scheme_params_t { -+ bool modify; /**< TRUE to change an existing scheme */ -+ union { -+ uint8_t relative_scheme_id; -+ /**< if modify=FALSE: partition-relative scheme id */ -+ void *scheme_id; /**< if modify=TRUE: the id of an existing scheme */ -+ } scm_id; -+ bool always_direct; /**< This scheme is reached only directly, i.e. no need -+ for match vector; KeyGen will ignore it when matching */ -+ struct { /**< HL relevant only if always_direct=FALSE */ -+ void *net_env_id; /**< The id of the Network Environment as returned -+ by FM_PCD_NetEnvCharacteristicsSet() */ -+ uint8_t num_of_distinction_units; -+ /**< Number of NetEnv units listed in unit_ids array */ -+ uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; -+ /**< Indexes as passed to SetNetEnvCharacteristics (?) array */ -+ } net_env_params; -+ bool use_hash; /**< use the KG Hash functionality */ -+ ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params; -+ /**< used only if useHash = TRUE */ -+ bool bypass_fqid_generation; -+ /**< Normally - FALSE, TRUE to avoid FQID update in the IC; -+ In such a case FQID after KG will be the default FQID -+ defined for the relevant port, or the FQID defined by CC -+ in cases where CC was the previous engine. */ -+ uint32_t base_fqid; /**< Base FQID; Relevant only if bypass_fqid_generation = FALSE; -+ If hash is used and an even distribution is expected -+ according to hash_distribution_num_of_fqids, base_fqid must be aligned to -+ hash_distribution_num_of_fqids. */ -+ uint8_t num_of_used_extracted_ors; -+ /**< Number of FQID masks listed in extracted_ors array*/ -+ ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS]; -+ /**< IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS -+ registers are shared between qid_masks -+ functionality and some of the extraction -+ actions; Normally only some will be used -+ for qid_mask. Driver will return error if -+ resource is full at initialization time. */ -+#if DPAA_VERSION >= 11 -+ bool override_storage_profile; -+ /**< TRUE if KeyGen override previously decided storage profile */ -+ ioc_fm_pcd_kg_storage_profile_t storage_profile;/**< Used when override_storage_profile=TRUE */ -+#endif /* DPAA_VERSION >= 11 */ -+ ioc_fm_pcd_engine next_engine; /**< may be BMI, PLCR or CC */ -+ union { /**< depends on nextEngine */ -+ ioc_fm_pcd_done_action done_action; /**< Used when next engine is BMI (done) */ -+ ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Used when next engine is PLCR */ -+ ioc_fm_pcd_kg_cc_t cc; /**< Used when next engine is CC */ -+ } kg_next_engine_params; -+ ioc_fm_pcd_kg_scheme_counter_t scheme_counter; /**< A structure of parameters for updating -+ the scheme counter */ -+ void *id; /**< Returns the scheme Id to be used */ -+} ioc_fm_pcd_kg_scheme_params_t; -+ -+/**************************************************************************//** -+ @Collection -+*//***************************************************************************/ -+#if DPAA_VERSION >= 11 -+#define IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */ -+#define IOC_FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */ -+#endif /* DPAA_VERSION >= 11 */ -+#define IOC_FM_PCD_CC_STATS_FLR_COUNT_SIZE 4 /* Size in bytes of a frame length range counter */ -+/* @} */ -+ -+/**************************************************************************//** -+ @Description Parameters for defining CC as the next engine after a CC node. -+ (Must match struct t_FmPcdCcNextCcParams defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_next_cc_params_t { -+ void *cc_node_id; /**< Id of the next CC node */ -+} ioc_fm_pcd_cc_next_cc_params_t; -+ -+#if DPAA_VERSION >= 11 -+/**************************************************************************//** -+ @Description A structure for defining Frame Replicator as the next engine after a CC node. -+ (Must match struct t_FmPcdCcNextFrParams defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_next_fr_params_t { -+ void* frm_replic_id; /**< The id of the next frame replicator group */ -+} ioc_fm_pcd_cc_next_fr_params_t; -+#endif /* DPAA_VERSION >= 11 */ -+ -+/**************************************************************************//** -+ @Description A structure for defining PLCR params when PLCR is the -+ next engine after a CC node -+ (Must match struct t_FmPcdCcNextPlcrParams defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_next_plcr_params_t { -+ bool override_params; /**< TRUE if CC override previously decided parameters*/ -+ bool shared_profile; /**< Relevant only if overrideParams=TRUE: -+ TRUE if this profile is shared between ports */ -+ uint16_t new_relative_profile_id; /**< Relevant only if overrideParams=TRUE: -+ (otherwise profile id is taken from keygen); -+ This parameter should indicate the policer -+ profile offset within the port's -+ policer profiles or from SHARED window.*/ -+ uint32_t new_fqid; /**< Relevant only if overrideParams=TRUE: -+ FQID for enquing the frame; -+ In earlier chips if policer next engine is KEYGEN, -+ this parameter can be 0, because the KEYGEN always decides -+ the enqueue FQID.*/ -+#if DPAA_VERSION >= 11 -+ uint8_t new_relative_storage_profile_id; -+ /**< Indicates the relative storage profile offset within -+ the port's storage profiles window; -+ Relevant only if the port was configured with VSP. */ -+#endif /* DPAA_VERSION >= 11 */ -+} ioc_fm_pcd_cc_next_plcr_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for defining enqueue params when BMI is the -+ next engine after a CC node -+ (Must match struct t_FmPcdCcNextEnqueueParams defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_next_enqueue_params_t { -+ ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */ -+ bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid, -+ relevant if action = e_IOC_FM_PCD_ENQ_FRAME */ -+ uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame -+ (otherwise FQID is taken from KeyGen), -+ relevant if action = e_IOC_FM_PCD_ENQ_FRAME*/ -+#if DPAA_VERSION >= 11 -+ uint8_t new_relative_storage_profile_id; -+ /**< Valid if override_fqid=TRUE, Indicates the relative virtual -+ storage profile offset within the port's storage profiles -+ window; Relevant only if the port was configured with VSP. */ -+#endif /* DPAA_VERSION >= 11 */ -+ -+} ioc_fm_pcd_cc_next_enqueue_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for defining KG params when KG is the next engine after a CC node -+ (Must match struct t_FmPcdCcNextKgParams defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_next_kg_params_t { -+ bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid, -+ Note - this parameters are irrelevant for earlier chips */ -+ uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame -+ (otherwise FQID is taken from KeyGen), -+ Note - this parameters are irrelevant for earlier chips */ -+#if DPAA_VERSION >= 11 -+ uint8_t new_relative_storage_profile_id; -+ /**< Valid if override_fqid=TRUE, Indicates the relative virtual -+ storage profile offset within the port's storage profiles -+ window; Relevant only if the port was configured with VSP. */ -+#endif /* DPAA_VERSION >= 11 */ -+ void *p_direct_scheme; /**< Direct scheme id to go to. */ -+} ioc_fm_pcd_cc_next_kg_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining the next engine after a CC node. -+ (Must match struct t_FmPcdCcNextEngineParams defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_next_engine_params_t { -+ ioc_fm_pcd_engine next_engine; /**< User has to initialize parameters -+ according to nextEngine definition */ -+ union { -+ ioc_fm_pcd_cc_next_cc_params_t cc_params; /**< Parameters in case next engine is CC */ -+ ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< Parameters in case next engine is PLCR */ -+ ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< Parameters in case next engine is BMI */ -+ ioc_fm_pcd_cc_next_kg_params_t kg_params; /**< Parameters in case next engine is KG */ -+#if DPAA_VERSION >= 11 -+ ioc_fm_pcd_cc_next_fr_params_t fr_params; /**< Parameters in case next engine is FR */ -+#endif /* DPAA_VERSION >= 11 */ -+ } params; /**< Union used for all the next-engine parameters options */ -+ void *manip_id; /**< Handle to Manipulation object. -+ Relevant if next engine is of type result -+ (e_IOC_FM_PCD_PLCR, e_IOC_FM_PCD_KG, e_IOC_FM_PCD_DONE) */ -+ bool statistics_en; /**< If TRUE, statistics counters are incremented -+ for each frame passing through this -+ Coarse Classification entry. */ -+} ioc_fm_pcd_cc_next_engine_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a single CC key -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_key_params_t { -+ uint8_t *p_key; /**< pointer to the key of the size defined in key_size */ -+ uint8_t *p_mask; /**< pointer to the Mask per key of the size defined -+ in keySize. p_key and p_mask (if defined) has to be -+ of the same size defined in the key_size */ -+ ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params; -+ /**< parameters for the next for the defined Key in p_key */ -+ -+} ioc_fm_pcd_cc_key_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining CC keys parameters -+ The driver supports two methods for CC node allocation: dynamic and static. -+ Static mode was created in order to prevent runtime alloc/free -+ of FMan memory (MURAM), which may cause fragmentation; in this mode, -+ the driver automatically allocates the memory according to -+ 'max_num_of_keys' parameter. The driver calculates the maximal memory -+ size that may be used for this CC-Node taking into consideration -+ 'mask_support' and 'statistics_mode' parameters. -+ When 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction -+ parameters of this node, 'max_num_of_keys' must be equal to 'num_of_keys'. -+ In dynamic mode, 'max_num_of_keys' must be zero. At initialization, -+ all required structures are allocated according to 'num_of_keys' -+ parameter. During runtime modification, these structures are -+ re-allocated according to the updated number of keys. -+ -+ Please note that 'action' and 'ic_indx_mask' mentioned in the -+ specific parameter explanations are passed in the extraction -+ parameters of the node (fields of extractccparams.extractnonhdr). -+*//***************************************************************************/ -+typedef struct ioc_keys_params_t { -+ uint16_t max_num_of_keys;/**< Maximum number of keys that will (ever) be used in this CC-Node; -+ A value of zero may be used for dynamic memory allocation. */ -+ bool mask_support; /**< This parameter is relevant only if a node is initialized with -+ action = e_IOC_FM_PCD_ACTION_EXACT_MATCH and max_num_of_keys > 0; -+ Should be TRUE to reserve table memory for key masks, even if -+ initial keys do not contain masks, or if the node was initialized -+ as 'empty' (without keys); this will allow user to add keys with -+ masks at runtime. */ -+ ioc_fm_pcd_cc_stats_mode statistics_mode;/**< Determines the supported statistics mode for all node's keys. -+ To enable statistics gathering, statistics should be enabled per -+ every key, using 'statistics_en' in next engine parameters structure -+ of that key; -+ If 'max_num_of_keys' is set, all required structures will be -+ preallocated for all keys. */ -+#if (DPAA_VERSION >= 11) -+ uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR]; -+ /**< Relevant only for 'RMON' statistics mode -+ (this feature is supported only on B4860 device); -+ Holds a list of programmable thresholds. For each received frame, -+ its length in bytes is examined against these range thresholds and -+ the appropriate counter is incremented by 1. For example, to belong -+ to range i, the following should hold: -+ range i-1 threshold < frame length <= range i threshold -+ Each range threshold must be larger then its preceding range -+ threshold. Last range threshold must be 0xFFFF. */ -+#endif /* (DPAA_VERSION >= 11) */ -+ uint16_t num_of_keys; /**< Number of initial keys; -+ Note that in case of 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, -+ this field should be power-of-2 of the number of bits that are -+ set in 'ic_indx_mask'. */ -+ uint8_t key_size; /**< Size of key - for extraction of type FULL_FIELD, 'key_size' has -+ to be the standard size of the selected key; For other extraction -+ types, 'key_size' has to be as size of extraction; When 'action' = -+ e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */ -+ ioc_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; -+ /**< An array with 'num_of_keys' entries, each entry specifies the -+ corresponding key parameters; -+ When 'action' = e_IOC_FM_PCD_ACTION_EXACT_MATCH, this value must not -+ exceed 255 (IOC_FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved -+ for the 'miss' entry. */ -+ ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; -+ /**< Parameters for defining the next engine when a key is not matched; -+ Not relevant if action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP. */ -+} ioc_keys_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a CC node -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_node_params_t { -+ ioc_fm_pcd_extract_entry_t extract_cc_params; /**< Extraction parameters */ -+ ioc_keys_params_t keys_params; /**< Keys definition matching the selected extraction */ -+ void *id; /**< Output parameter; returns the CC node Id to be used */ -+} ioc_fm_pcd_cc_node_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a hash table -+ (Must match struct t_FmPcdHashTableParams defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_hash_table_params_t { -+ uint16_t max_num_of_keys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */ -+ ioc_fm_pcd_cc_stats_mode statistics_mode; /**< If not e_IOC_FM_PCD_CC_STATS_MODE_NONE, the required structures for the -+ requested statistics mode will be allocated according to max_num_of_keys. */ -+ uint8_t kg_hash_shift; /**< KG-Hash-shift as it was configured in the KG-scheme -+ that leads to this hash-table. */ -+ uint16_t hash_res_mask; /**< Mask that will be used on the hash-result; -+ The number-of-sets for this hash will be calculated -+ as (2^(number of bits set in 'hash_res_mask')); -+ The 4 lower bits must be cleared. */ -+ uint8_t hash_shift; /**< Byte offset from the beginning of the KeyGen hash result to the -+ 2-bytes to be used as hash index. */ -+ uint8_t match_key_size; /**< Size of the exact match keys held by the hash buckets */ -+ -+ ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; -+ /**< Parameters for defining the next engine when a key is not matched */ -+ void *id; -+} ioc_fm_pcd_hash_table_params_t; -+ -+/**************************************************************************//** -+ @Description A structure with the arguments for the FM_PCD_HashTableAddKey ioctl() call -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_hash_table_add_key_params_t { -+ void *p_hash_tbl; -+ uint8_t key_size; -+ ioc_fm_pcd_cc_key_params_t key_params; -+} ioc_fm_pcd_hash_table_add_key_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a CC tree group. -+ -+ This structure defines a CC group in terms of NetEnv units -+ and the action to be taken in each case. The unit_ids list must -+ be given in order from low to high indices. -+ -+ ioc_fm_pcd_cc_next_engine_params_t is a list of 2^num_of_distinction_units -+ structures where each defines the next action to be taken for -+ each units combination. for example: -+ num_of_distinction_units = 2 -+ unit_ids = {1,3} -+ next_engine_per_entries_in_grp[0] = ioc_fm_pcd_cc_next_engine_params_t for the case that -+ unit 1 - not found; unit 3 - not found; -+ next_engine_per_entries_in_grp[1] = ioc_fm_pcd_cc_next_engine_params_t for the case that -+ unit 1 - not found; unit 3 - found; -+ next_engine_per_entries_in_grp[2] = ioc_fm_pcd_cc_next_engine_params_t for the case that -+ unit 1 - found; unit 3 - not found; -+ next_engine_per_entries_in_grp[3] = ioc_fm_pcd_cc_next_engine_params_t for the case that -+ unit 1 - found; unit 3 - found; -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_grp_params_t { -+ uint8_t num_of_distinction_units; /**< Up to 4 */ -+ uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS]; -+ /**< Indexes of the units as defined in -+ FM_PCD_NetEnvCharacteristicsSet() */ -+ ioc_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP]; -+ /**< Maximum entries per group is 16 */ -+} ioc_fm_pcd_cc_grp_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining the CC tree groups -+ (Must match struct t_FmPcdCcTreeParams defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_tree_params_t { -+ void *net_env_id; /**< Id of the Network Environment as returned -+ by FM_PCD_NetEnvCharacteristicsSet() */ -+ uint8_t num_of_groups; /**< Number of CC groups within the CC tree */ -+ ioc_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS]; -+ /**< Parameters for each group. */ -+ void *id; /**< Output parameter; Returns the tree Id to be used */ -+} ioc_fm_pcd_cc_tree_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining policer byte rate -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_plcr_byte_rate_mode_param_t { -+ ioc_fm_pcd_plcr_frame_length_select frame_length_selection; /**< Frame length selection */ -+ ioc_fm_pcd_plcr_roll_back_frame_select roll_back_frame_selection; /**< relevant option only e_IOC_FM_PCD_PLCR_L2_FRM_LEN, -+ e_IOC_FM_PCD_PLCR_FULL_FRM_LEN */ -+} ioc_fm_pcd_plcr_byte_rate_mode_param_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining the policer profile (based on -+ RFC-2698 or RFC-4115 attributes). -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_plcr_non_passthrough_alg_param_t { -+ ioc_fm_pcd_plcr_rate_mode rate_mode; /**< Byte / Packet */ -+ ioc_fm_pcd_plcr_byte_rate_mode_param_t byte_mode_param; /**< Valid for Byte NULL for Packet */ -+ uint32_t committed_info_rate; /**< KBits/Sec or Packets/Sec */ -+ uint32_t committed_burst_size; /**< KBits or Packets */ -+ uint32_t peak_or_excess_info_rate; /**< KBits/Sec or Packets/Sec */ -+ uint32_t peak_or_excess_burst_size; /**< KBits or Packets */ -+} ioc_fm_pcd_plcr_non_passthrough_alg_param_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining the next engine after policer -+*//***************************************************************************/ -+typedef union ioc_fm_pcd_plcr_next_engine_params_u { -+ ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */ -+ void *p_profile; /**< Policer profile handle - used when next engine -+ is PLCR, must be a SHARED profile */ -+ void *p_direct_scheme; /**< Direct scheme select - when next engine is Keygen */ -+} ioc_fm_pcd_plcr_next_engine_params_u; -+ -+typedef struct ioc_fm_pcd_port_params_t { -+ ioc_fm_port_type port_type; /**< Type of port for this profile */ -+ uint8_t port_id; /**< FM-Port id of port for this profile */ -+} ioc_fm_pcd_port_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining the policer profile entry -+ (Must match struct t_FmPcdPlcrProfileParams defined in fm_pcd_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_plcr_profile_params_t { -+ bool modify; /**< TRUE to change an existing profile */ -+ union { -+ struct { -+ ioc_fm_pcd_profile_type_selection profile_type; /**< Type of policer profile */ -+ ioc_fm_pcd_port_params_t *p_fm_port; /**< Relevant for per-port profiles only */ -+ uint16_t relative_profile_id; /**< Profile id - relative to shared group or to port */ -+ } new_params; /**< Use it when modify = FALSE */ -+ void *p_profile; /**< A handle to a profile - use it when modify=TRUE */ -+ } profile_select; -+ ioc_fm_pcd_plcr_algorithm_selection alg_selection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */ -+ ioc_fm_pcd_plcr_color_mode color_mode; /**< COLOR_BLIND, COLOR_AWARE */ -+ -+ union { -+ ioc_fm_pcd_plcr_color dflt_color; /**< For Color-Blind Pass-Through mode; the policer will re-color -+ any incoming packet with the default value. */ -+ ioc_fm_pcd_plcr_color override; /**< For Color-Aware modes; the profile response to a -+ pre-color value of 2'b11. */ -+ } color; -+ -+ ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param; /**< RFC2698 or RFC4115 parameters */ -+ -+ ioc_fm_pcd_engine next_engine_on_green; /**< Next engine for green-colored frames */ -+ ioc_fm_pcd_plcr_next_engine_params_u params_on_green; /**< Next engine parameters for green-colored frames */ -+ -+ ioc_fm_pcd_engine next_engine_on_yellow; /**< Next engine for yellow-colored frames */ -+ ioc_fm_pcd_plcr_next_engine_params_u params_on_yellow; /**< Next engine parameters for yellow-colored frames */ -+ -+ ioc_fm_pcd_engine next_engine_on_red; /**< Next engine for red-colored frames */ -+ ioc_fm_pcd_plcr_next_engine_params_u params_on_red; /**< Next engine parameters for red-colored frames */ -+ -+ bool trap_profile_on_flow_A; /**< Obsolete - do not use */ -+ bool trap_profile_on_flow_B; /**< Obsolete - do not use */ -+ bool trap_profile_on_flow_C; /**< Obsolete - do not use */ -+ -+ void *id; /**< output parameter; Returns the profile Id to be used */ -+} ioc_fm_pcd_plcr_profile_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for modifying CC tree next engine -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_tree_modify_next_engine_params_t { -+ void *id; /**< CC tree Id to be used */ -+ uint8_t grp_indx; /**< A Group index in the tree */ -+ uint8_t indx; /**< Entry index in the group defined by grp_index */ -+ ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params; -+ /**< Parameters for the next for the defined Key in the p_Key */ -+} ioc_fm_pcd_cc_tree_modify_next_engine_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for modifying CC node next engine -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_node_modify_next_engine_params_t { -+ void *id; /**< CC node Id to be used */ -+ uint16_t key_indx; /**< Key index for Next Engine Params modifications; -+ NOTE: This parameter is IGNORED for miss-key! */ -+ uint8_t key_size; /**< Key size of added key */ -+ ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params; -+ /**< parameters for the next for the defined Key in the p_Key */ -+} ioc_fm_pcd_cc_node_modify_next_engine_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for remove CC node key -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_node_remove_key_params_t { -+ void *id; /**< CC node Id to be used */ -+ uint16_t key_indx; /**< Key index for Next Engine Params modifications; -+ NOTE: This parameter is IGNORED for miss-key! */ -+} ioc_fm_pcd_cc_node_remove_key_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for modifying CC node key and next engine -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t { -+ void *id; /**< CC node Id to be used */ -+ uint16_t key_indx; /**< Key index for Next Engine Params modifications; -+ NOTE: This parameter is IGNORED for miss-key! */ -+ uint8_t key_size; /**< Key size of added key */ -+ ioc_fm_pcd_cc_key_params_t key_params; /**< it's array with numOfKeys entries each entry in -+ the array of the type ioc_fm_pcd_cc_key_params_t */ -+} ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for modifying CC node key -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_cc_node_modify_key_params_t { -+ void *id; /**< CC node Id to be used */ -+ uint16_t key_indx; /**< Key index for Next Engine Params modifications; -+ NOTE: This parameter is IGNORED for miss-key! */ -+ uint8_t key_size; /**< Key size of added key */ -+ uint8_t *p_key; /**< Pointer to the key of the size defined in key_size */ -+ uint8_t *p_mask; /**< Pointer to the Mask per key of the size defined -+ in keySize. p_Key and p_Mask (if defined) have to be -+ of the same size as defined in the key_size */ -+} ioc_fm_pcd_cc_node_modify_key_params_t; -+ -+/**************************************************************************//** -+ @Description A structure with the arguments for the FM_PCD_HashTableRemoveKey ioctl() call -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_hash_table_remove_key_params_t { -+ void *p_hash_tbl; /**< The id of the hash table */ -+ uint8_t key_size; /**< The size of the key to remove */ -+ uint8_t *p_key; /**< Pointer to the key to remove */ -+} ioc_fm_pcd_hash_table_remove_key_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for selecting a location for requested manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_manip_hdr_info_t { -+ ioc_net_header_type hdr; /**< Header selection */ -+ ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */ -+ bool by_field; /**< TRUE if the location of manipulation is according to some field in the specific header*/ -+ ioc_fm_pcd_fields_u full_field; /**< Relevant only when by_field = TRUE: Extract field */ -+} ioc_fm_manip_hdr_info_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header removal by header type -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t { -+ ioc_fm_pcd_manip_hdr_rmv_by_hdr_type type; /**< Selection of header removal location */ -+ union { -+#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) -+ struct { -+ bool include;/**< If FALSE, remove until the specified header (not including the header); -+ If TRUE, remove also the specified header. */ -+ ioc_fm_manip_hdr_info_t hdr_info; -+ } from_start_by_hdr; /**< Relevant when type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */ -+#endif /* FM_CAPWAP_SUPPORT */ -+#if (DPAA_VERSION >= 11) -+ ioc_fm_manip_hdr_info_t hdr_info; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */ -+#endif /* (DPAA_VERSION >= 11) */ -+ ioc_fm_pcd_manip_hdr_rmv_specific_l2 specific_l2;/**< Relevant when type = e_IOC_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2; -+ Defines which L2 headers to remove. */ -+ } u; -+} ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for configuring IP fragmentation manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_frag_ip_params_t { -+ uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value, -+ IP fragmentation will be executed.*/ -+#if DPAA_VERSION == 10 -+ uint8_t scratch_bpid; /**< Absolute buffer pool id according to BM configuration.*/ -+#endif /* DPAA_VERSION == 10 */ -+ bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation; -+ If disabled, the Scatter/Gather buffer will be allocated from the same pool as the -+ received frame's buffer. */ -+ uint8_t sg_bpid; /**< Scatter/Gather buffer pool id; -+ This parameter is relevant when 'sg_bpid_en=TRUE'; -+ Same LIODN number is used for these buffers as for the received frames buffers, so buffers -+ of this pool need to be allocated in the same memory area as the received buffers. -+ If the received buffers arrive from different sources, the Scatter/Gather BP id should be -+ mutual to all these sources. */ -+ ioc_fm_pcd_manip_dont_frag_action dont_frag_action; /**< Dont Fragment Action - If an IP packet is larger -+ than MTU and its DF bit is set, then this field will -+ determine the action to be taken.*/ -+} ioc_fm_pcd_manip_frag_ip_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for configuring IP reassembly manipulation. -+ -+ This is a common structure for both IPv4 and IPv6 reassembly -+ manipulation. For reassembly of both IPv4 and IPv6, make sure to -+ set the 'hdr' field in ioc_fm_pcd_manip_reassem_params_t to IOC_HEADER_TYPE_IPv6. -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_reassem_ip_params_t { -+ uint8_t relative_scheme_id[2]; /**< Partition relative scheme id: -+ relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation; -+ relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation; -+ NOTE: The following comment is relevant only for FMAN v2 devices: -+ Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than -+ the user schemes id to ensure that the reassembly's schemes will be first match. -+ The remaining schemes, if defined, should have higher relative scheme ID. */ -+#if DPAA_VERSION >= 11 -+ uint32_t non_consistent_sp_fqid; /**< In case that other fragments of the frame corresponds to different storage -+ profile than the opening fragment (Non-Consistent-SP state) -+ then one of two possible scenarios occurs: -+ if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to -+ this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/ -+#else -+ uint8_t sg_bpid; /**< Buffer pool id for the S/G frame created by the reassembly process */ -+#endif /* DPAA_VERSION >= 11 */ -+ uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */ -+ uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */ -+ uint16_t min_frag_size[2]; /**< Minimum fragment size: -+ minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */ -+ ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry[2]; -+ /**< Number of frames per hash entry needed for reassembly process: -+ numOfFramesPerHashEntry[0] - for ipv4 (max value is e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH); -+ numOfFramesPerHashEntry[1] - for ipv6 (max value is e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH). */ -+ uint16_t max_num_frames_in_process;/**< Number of frames which can be processed by Reassembly in the same time; -+ Must be power of 2; -+ In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, -+ maxNumFramesInProcess has to be in the range of 4 - 512; -+ In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH, -+ maxNumFramesInProcess has to be in the range of 8 - 2048. */ -+ ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */ -+ uint32_t fqid_for_time_out_frames;/**< FQID in which time out frames will enqueue during Time Out Process */ -+ uint32_t timeout_threshold_for_reassm_process; -+ /**< Represents the time interval in microseconds which defines -+ if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/ -+} ioc_fm_pcd_manip_reassem_ip_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining IPSEC manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_special_offload_ipsec_params_t { -+ bool decryption; /**< TRUE if being used in decryption direction; -+ FALSE if being used in encryption direction. */ -+ bool ecn_copy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner -+ (direction depends on the 'decryption' field). */ -+ bool dscp_copy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner -+ (direction depends on the 'decryption' field). */ -+ bool variable_ip_hdr_len; /**< TRUE for supporting variable IP header length in decryption. */ -+ bool variable_ip_version; /**< TRUE for supporting both IP version on the same SA in encryption */ -+ uint8_t outer_ip_hdr_len; /**< If 'variable_ip_version == TRUE' than this field must be set to non-zero value; -+ It is specifies the length of the outer IP header that was configured in the -+ corresponding SA. */ -+ uint16_t arw_size; /**< if <> '0' then will perform ARW check for this SA; -+ The value must be a multiplication of 16 */ -+ void *arw_addr; /**< if arwSize <> '0' then this field must be set to non-zero value; -+ MUST be allocated from FMAN's MURAM that the post-sec op-port belong -+ Must be 4B aligned. Required MURAM size is '(NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */ -+} ioc_fm_pcd_manip_special_offload_ipsec_params_t; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Parameters for configuring CAPWAP fragmentation manipulation -+ -+ Restrictions: -+ - Maximum number of fragments per frame is 16. -+ - Transmit confirmation is not supported. -+ - Fragmentation nodes must be set as the last PCD action (i.e. the -+ corresponding CC node key must have next engine set to e_FM_PCD_DONE). -+ - Only BMan buffers shall be used for frames to be fragmented. -+ - NOTE: The following comment is relevant only for FMAN v3 devices: IPF -+ does not support VSP. Therefore, on the same port where we have IPF we -+ cannot support VSP. -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_frag_capwap_params_t { -+ uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value, -+ CAPWAP fragmentation will be executed.*/ -+ bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation; -+ If disabled, the Scatter/Gather buffer will be allocated from the same pool as the -+ received frame's buffer. */ -+ uint8_t sg_bpid; /**< Scatter/Gather buffer pool id; -+ This parameters is relevant when 'sgBpidEn=TRUE'; -+ Same LIODN number is used for these buffers as for the received frames buffers, so buffers -+ of this pool need to be allocated in the same memory area as the received buffers. -+ If the received buffers arrive from different sources, the Scatter/Gather BP id should be -+ mutual to all these sources. */ -+ bool compress_mode_en; /**< CAPWAP Header Options Compress Enable mode; -+ When this mode is enabled then only the first fragment include the CAPWAP header options -+ field (if user provides it in the input frame) and all other fragments exclude the CAPWAP -+ options field (CAPWAP header is updated accordingly).*/ -+} ioc_fm_pcd_manip_frag_capwap_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for configuring CAPWAP reassembly manipulation. -+ -+ Restrictions: -+ - Application must define one scheme to catch the reassembled frames. -+ - Maximum number of fragments per frame is 16. -+ -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_reassem_capwap_params_t { -+ uint8_t relative_scheme_id; /**< Partition relative scheme id; -+ NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match; -+ Rest schemes, if defined, should have higher relative scheme ID. */ -+ uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */ -+ uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */ -+ uint16_t max_reassembled_frame_length;/**< The maximum CAPWAP reassembled frame length in bytes; -+ If maxReassembledFrameLength == 0, any successful reassembled frame length is -+ considered as a valid length; -+ if maxReassembledFrameLength > 0, a successful reassembled frame which its length -+ exceeds this value is considered as an error frame (FD status[CRE] bit is set). */ -+ ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry; -+ /**< Number of frames per hash entry needed for reassembly process */ -+ uint16_t max_num_frames_in_process; /**< Number of frames which can be processed by reassembly in the same time; -+ Must be power of 2; -+ In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH, -+ maxNumFramesInProcess has to be in the range of 4 - 512; -+ In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH, -+ maxNumFramesInProcess has to be in the range of 8 - 2048. */ -+ ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */ -+ uint32_t fqid_for_time_out_frames; /**< FQID in which time out frames will enqueue during Time Out Process; -+ Recommended value for this field is 0; in this way timed-out frames will be discarded */ -+ uint32_t timeout_threshold_for_reassm_process; -+ /**< Represents the time interval in microseconds which defines -+ if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/ -+} ioc_fm_pcd_manip_reassem_capwap_params_t; -+ -+/**************************************************************************//** -+ @Description structure for defining CAPWAP manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_special_offload_capwap_params_t { -+ bool dtls; /**< TRUE if continue to SEC DTLS encryption */ -+ ioc_fm_pcd_manip_hdr_qos_src qos_src; /**< TODO */ -+} ioc_fm_pcd_manip_special_offload_capwap_params_t; -+ -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Description Parameters for defining special offload manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_special_offload_params_t { -+ ioc_fm_pcd_manip_special_offload_type type; /**< Type of special offload manipulation */ -+ union -+ { -+ ioc_fm_pcd_manip_special_offload_ipsec_params_t ipsec; /**< Parameters for IPSec; Relevant when -+ type = e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */ -+ -+#if (DPAA_VERSION >= 11) -+ ioc_fm_pcd_manip_special_offload_capwap_params_t capwap; /**< Parameters for CAPWAP; Relevant when -+ type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */ -+#endif /* (DPAA_VERSION >= 11) */ -+ } u; -+} ioc_fm_pcd_manip_special_offload_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining generic removal manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_rmv_generic_params_t { -+ uint8_t offset; /**< Offset from beginning of header to the start -+ location of the removal */ -+ uint8_t size; /**< Size of removed section */ -+} ioc_fm_pcd_manip_hdr_rmv_generic_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining insertion manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_insrt_t { -+ uint8_t size; /**< size of inserted section */ -+ uint8_t *p_data; /**< data to be inserted */ -+} ioc_fm_pcd_manip_hdr_insrt_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining generic insertion manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_insrt_generic_params_t { -+ uint8_t offset; /**< Offset from beginning of header to the start -+ location of the insertion */ -+ uint8_t size; /**< Size of inserted section */ -+ bool replace; /**< TRUE to override (replace) existing data at -+ 'offset', FALSE to insert */ -+ uint8_t *p_data; /**< Pointer to data to be inserted */ -+} ioc_fm_pcd_manip_hdr_insrt_generic_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t { -+ uint8_t dscp_to_vpri_table[IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS]; -+ /**< A table of VPri values for each DSCP value; -+ The index is the D_SCP value (0-0x3F) and the -+ value is the corresponding VPRI (0-15). */ -+ uint8_t vpri_def_val; /**< 0-7, Relevant only if if update_type = -+ e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN, -+ this field is the Q Tag default value if the -+ IP header is not found. */ -+} ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation VLAN fields updates -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_t { -+ ioc_fm_pcd_manip_hdr_field_update_vlan update_type; /**< Selects VLAN update type */ -+ union { -+ uint8_t vpri; /**< 0-7, Relevant only if If update_type = -+ e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this -+ is the new VLAN pri. */ -+ ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t dscp_to_vpri; -+ /**< Parameters structure, Relevant only if update_type = -+ e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */ -+ } u; -+} ioc_fm_pcd_manip_hdr_field_update_vlan_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation IPV4 fields updates -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv4_t { -+ ioc_ipv4_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */ -+ uint8_t tos; /**< 8 bit New TOS; Relevant if valid_updates contains -+ IOC_HDR_MANIP_IPV4_TOS */ -+ uint16_t id; /**< 16 bit New IP ID; Relevant only if valid_updates -+ contains IOC_HDR_MANIP_IPV4_ID */ -+ uint32_t src; /**< 32 bit New IP SRC; Relevant only if valid_updates -+ contains IOC_HDR_MANIP_IPV4_SRC */ -+ uint32_t dst; /**< 32 bit New IP DST; Relevant only if valid_updates -+ contains IOC_HDR_MANIP_IPV4_DST */ -+} ioc_fm_pcd_manip_hdr_field_update_ipv4_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation IPV6 fields updates -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv6_t { -+ ioc_ipv6_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */ -+ uint8_t traffic_class; /**< 8 bit New Traffic Class; Relevant if valid_updates contains -+ IOC_HDR_MANIP_IPV6_TC */ -+ uint8_t src[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE]; -+ /**< 16 byte new IP SRC; Relevant only if valid_updates -+ contains IOC_HDR_MANIP_IPV6_SRC */ -+ uint8_t dst[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE]; -+ /**< 16 byte new IP DST; Relevant only if valid_updates -+ contains IOC_HDR_MANIP_IPV6_DST */ -+} ioc_fm_pcd_manip_hdr_field_update_ipv6_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation TCP/UDP fields updates -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t { -+ ioc_tcp_udp_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */ -+ uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if valid_updates -+ contains IOC_HDR_MANIP_TCP_UDP_SRC */ -+ uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if valid_updates -+ contains IOC_HDR_MANIP_TCP_UDP_DST */ -+} ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation fields updates -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_field_update_params_t { -+ ioc_fm_pcd_manip_hdr_field_update_type type; /**< Type of header field update manipulation */ -+ union { -+ ioc_fm_pcd_manip_hdr_field_update_vlan_t vlan; /**< Parameters for VLAN update. Relevant when -+ type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */ -+ ioc_fm_pcd_manip_hdr_field_update_ipv4_t ipv4; /**< Parameters for IPv4 update. Relevant when -+ type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */ -+ ioc_fm_pcd_manip_hdr_field_update_ipv6_t ipv6; /**< Parameters for IPv6 update. Relevant when -+ type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */ -+ ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t tcp_udp;/**< Parameters for TCP/UDP update. Relevant when -+ type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */ -+ } u; -+} ioc_fm_pcd_manip_hdr_field_update_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining custom header manipulation for IP replacement -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t { -+ ioc_fm_pcd_manip_hdr_custom_ip_replace replace_type; /**< Selects replace update type */ -+ bool dec_ttl_hl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */ -+ bool update_ipv4_id; /**< Relevant when replace_type = -+ e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */ -+ uint16_t id; /**< 16 bit New IP ID; Relevant only if -+ update_ipv4_id = TRUE */ -+ uint8_t hdr_size; /**< The size of the new IP header */ -+ uint8_t hdr[IOC_FM_PCD_MANIP_MAX_HDR_SIZE]; -+ /**< The new IP header */ -+} ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining custom header manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_custom_params_t { -+ ioc_fm_pcd_manip_hdr_custom_type type; /**< Type of header field update manipulation */ -+ union { -+ ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t ip_hdr_replace; -+ /**< Parameters IP header replacement */ -+ } u; -+} ioc_fm_pcd_manip_hdr_custom_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining specific L2 insertion manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t { -+ ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2; /**< Selects which L2 headers to insert */ -+ bool update; /**< TRUE to update MPLS header */ -+ uint8_t size; /**< size of inserted section */ -+ uint8_t *p_data; /**< data to be inserted */ -+} ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Parameters for defining IP insertion manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_insrt_ip_params_t { -+ bool calc_l4_checksum; /**< Calculate L4 checksum. */ -+ ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */ -+ uint8_t last_pid_offset; /**< the offset of the last Protocol within -+ the inserted header */ -+ uint16_t id; /**< 16 bit New IP ID */ -+ bool dont_frag_overwrite; -+ /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte. -+ * This byte is configured to be overwritten when RPD is set. */ -+ uint8_t last_dst_offset; -+ /**< IPv6 only. if routing extension exist, user should set the offset of the destination address -+ * in order to calculate UDP checksum pseudo header; -+ * Otherwise set it to '0'. */ -+ ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */ -+} ioc_fm_pcd_manip_hdr_insrt_ip_params_t; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Description Parameters for defining header insertion manipulation by header type -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t { -+ ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type; /**< Selects manipulation type */ -+ union { -+ ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params; -+ /**< Used when type = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2: -+ Selects which L2 headers to remove */ -+#if (DPAA_VERSION >= 11) -+ ioc_fm_pcd_manip_hdr_insrt_ip_params_t ip_params; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */ -+ ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, -+ e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or -+ e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */ -+#endif /* (DPAA_VERSION >= 11) */ -+ } u; -+} ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header insertion manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_insrt_params_t { -+ ioc_fm_pcd_manip_hdr_insrt_type type; /**< Type of insertion manipulation */ -+ union { -+ ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr; /**< Parameters for defining header insertion manipulation by header type, -+ relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR */ -+ ioc_fm_pcd_manip_hdr_insrt_generic_params_t generic;/**< Parameters for defining generic header insertion manipulation, -+ relevant if type = e_IOC_FM_PCD_MANIP_INSRT_GENERIC */ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template; -+ /**< Parameters for defining header insertion manipulation by template, -+ relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE */ -+#endif /* FM_CAPWAP_SUPPORT */ -+ } u; -+} ioc_fm_pcd_manip_hdr_insrt_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header removal manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_rmv_params_t { -+ ioc_fm_pcd_manip_hdr_rmv_type type; /**< Type of header removal manipulation */ -+ union { -+ ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t by_hdr; /**< Parameters for defining header removal manipulation by header type, -+ relevant if type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR */ -+ ioc_fm_pcd_manip_hdr_rmv_generic_params_t generic; /**< Parameters for defining generic header removal manipulation, -+ relevant if type = e_IOC_FM_PCD_MANIP_RMV_GENERIC */ -+ } u; -+} ioc_fm_pcd_manip_hdr_rmv_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining header manipulation node -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_hdr_params_t { -+ bool rmv; /**< TRUE, to define removal manipulation */ -+ ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */ -+ -+ bool insrt; /**< TRUE, to define insertion manipulation */ -+ ioc_fm_pcd_manip_hdr_insrt_params_t insrt_params; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */ -+ -+ bool field_update; /**< TRUE, to define field update manipulation */ -+ ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */ -+ -+ bool custom; /**< TRUE, to define custom manipulation */ -+ ioc_fm_pcd_manip_hdr_custom_params_t custom_params; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */ -+ -+ bool dont_parse_after_manip;/**< FALSE to activate the parser a second time after -+ completing the manipulation on the frame */ -+} ioc_fm_pcd_manip_hdr_params_t; -+ -+ -+/**************************************************************************//** -+ @Description structure for defining fragmentation manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_frag_params_t { -+ ioc_net_header_type hdr; /**< Header selection */ -+ union { -+#if (DPAA_VERSION >= 11) -+ ioc_fm_pcd_manip_frag_capwap_params_t capwap_frag; /**< Parameters for defining CAPWAP fragmentation, -+ relevant if 'hdr' = HEADER_TYPE_CAPWAP */ -+#endif /* (DPAA_VERSION >= 11) */ -+ ioc_fm_pcd_manip_frag_ip_params_t ip_frag; /**< Parameters for defining IP fragmentation, -+ relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */ -+ } u; -+} ioc_fm_pcd_manip_frag_params_t; -+ -+/**************************************************************************//** -+ @Description structure for defining reassemble manipulation -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_reassem_params_t { -+ ioc_net_header_type hdr; /**< Header selection */ -+ union { -+#if (DPAA_VERSION >= 11) -+ ioc_fm_pcd_manip_reassem_capwap_params_t capwap_reassem; /**< Parameters for defining CAPWAP reassembly, -+ relevant if 'hdr' = HEADER_TYPE_CAPWAP */ -+#endif /* (DPAA_VERSION >= 11) */ -+ ioc_fm_pcd_manip_reassem_ip_params_t ip_reassem; /**< Parameters for defining IP reassembly, -+ relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */ -+ } u; -+} ioc_fm_pcd_manip_reassem_params_t; -+ -+/**************************************************************************//** -+ @Description Parameters for defining a manipulation node -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_params_t { -+ ioc_fm_pcd_manip_type type; /**< Selects type of manipulation node */ -+ union { -+ ioc_fm_pcd_manip_hdr_params_t hdr; /**< Parameters for defining header manipulation node */ -+ ioc_fm_pcd_manip_reassem_params_t reassem;/**< Parameters for defining reassembly manipulation node */ -+ ioc_fm_pcd_manip_frag_params_t frag; /**< Parameters for defining fragmentation manipulation node */ -+ ioc_fm_pcd_manip_special_offload_params_t special_offload;/**< Parameters for defining special offload manipulation node */ -+ } u; -+ void *p_next_manip;/**< Handle to another (previously defined) manipulation node; -+ Allows concatenation of manipulation actions -+ This parameter is optional and may be NULL. */ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ bool frag_or_reasm;/**< TRUE, if defined fragmentation/reassembly manipulation */ -+ ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;/**< Parameters for fragmentation/reassembly manipulation, -+ relevant if frag_or_reasm = TRUE */ -+#endif /* FM_CAPWAP_SUPPORT */ -+ void *id; -+} ioc_fm_pcd_manip_params_t; -+ -+/**************************************************************************//** -+ @Description Structure for retrieving IP reassembly statistics -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_reassem_ip_stats_t { -+ /* common counters for both IPv4 and IPv6 */ -+ uint32_t timeout; /**< Counts the number of TimeOut occurrences */ -+ uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate -+ a Reassembly Frame Descriptor */ -+ uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */ -+ uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */ -+ uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */ -+ uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */ -+#if (DPAA_VERSION >= 11) -+ uint32_t non_consistent_sp; /**< Counts the number of Non Consistent Storage Profile events for -+ successfully reassembled frames */ -+#endif /* (DPAA_VERSION >= 11) */ -+struct { -+ uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */ -+ uint32_t valid_fragments; /**< Counts the total number of valid fragments that -+ have been processed for all frames */ -+ uint32_t processed_fragments; /**< Counts the number of processed fragments -+ (valid and error fragments) for all frames */ -+ uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */ -+ uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */ -+ uint32_t auto_learn_busy; /**< Counts the number of times a busy condition occurs when attempting -+ to access an IP-Reassembly Automatic Learning Hash set */ -+ uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame -+ exceeds 16 */ -+ } specific_hdr_statistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */ -+} ioc_fm_pcd_manip_reassem_ip_stats_t; -+ -+/**************************************************************************//** -+ @Description Structure for retrieving IP fragmentation statistics -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_frag_ip_stats_t { -+ uint32_t total_frames; /**< Number of frames that passed through the manipulation node */ -+ uint32_t fragmented_frames; /**< Number of frames that were fragmented */ -+ uint32_t generated_fragments; /**< Number of fragments that were generated */ -+} ioc_fm_pcd_manip_frag_ip_stats_t; -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Description Structure for retrieving CAPWAP reassembly statistics -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_reassem_capwap_stats_t { -+ uint32_t timeout; /**< Counts the number of timeout occurrences */ -+ uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate -+ a Reassembly Frame Descriptor */ -+ uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */ -+ uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */ -+ uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */ -+ uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */ -+ uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */ -+ uint32_t valid_fragments; /**< Counts the total number of valid fragments that -+ have been processed for all frames */ -+ uint32_t processed_fragments; /**< Counts the number of processed fragments -+ (valid and error fragments) for all frames */ -+ uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */ -+ uint32_t autoLearn_busy; /**< Counts the number of times a busy condition occurs when attempting -+ to access an Reassembly Automatic Learning Hash set */ -+ uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */ -+ uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame -+ exceeds 16 */ -+ uint32_t exceed_max_reassembly_frame_len;/**< ounts the number of times that a successful reassembled frame -+ length exceeds MaxReassembledFrameLength value */ -+} ioc_fm_pcd_manip_reassem_capwap_stats_t; -+ -+/**************************************************************************//** -+ @Description Structure for retrieving CAPWAP fragmentation statistics -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_frag_capwap_stats_t { -+ uint32_t total_frames; /**< Number of frames that passed through the manipulation node */ -+ uint32_t fragmented_frames; /**< Number of frames that were fragmented */ -+ uint32_t generated_fragments; /**< Number of fragments that were generated */ -+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) -+ uint8_t sg_allocation_failure; /**< Number of allocation failure of s/g buffers */ -+#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */ -+} ioc_fm_pcd_manip_frag_capwap_stats_t; -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Description Structure for retrieving reassembly statistics -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_reassem_stats_t { -+ union { -+ ioc_fm_pcd_manip_reassem_ip_stats_t ip_reassem; /**< Structure for IP reassembly statistics */ -+#if (DPAA_VERSION >= 11) -+ ioc_fm_pcd_manip_reassem_capwap_stats_t capwap_reassem; /**< Structure for CAPWAP reassembly statistics */ -+#endif /* (DPAA_VERSION >= 11) */ -+ } u; -+} ioc_fm_pcd_manip_reassem_stats_t; -+ -+/**************************************************************************//** -+ @Description structure for retrieving fragmentation statistics -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_frag_stats_t { -+ union { -+ ioc_fm_pcd_manip_frag_ip_stats_t ip_frag; /**< Structure for IP fragmentation statistics */ -+#if (DPAA_VERSION >= 11) -+ ioc_fm_pcd_manip_frag_capwap_stats_t capwap_frag; /**< Structure for CAPWAP fragmentation statistics */ -+#endif /* (DPAA_VERSION >= 11) */ -+ } u; -+} ioc_fm_pcd_manip_frag_stats_t; -+ -+/**************************************************************************//** -+ @Description structure for defining manipulation statistics -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_stats_t { -+ union { -+ ioc_fm_pcd_manip_reassem_stats_t reassem; /**< Structure for reassembly statistics */ -+ ioc_fm_pcd_manip_frag_stats_t frag; /**< Structure for fragmentation statistics */ -+ } u; -+} ioc_fm_pcd_manip_stats_t; -+ -+/**************************************************************************//** -+ @Description Parameters for acquiring manipulation statistics -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_manip_get_stats_t { -+ void *id; -+ ioc_fm_pcd_manip_stats_t stats; -+} ioc_fm_pcd_manip_get_stats_t; -+ -+#if DPAA_VERSION >= 11 -+/**************************************************************************//** -+ @Description Parameters for defining frame replicator group and its members -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_frm_replic_group_params_t { -+ uint8_t max_num_of_entries; /**< Maximal number of members in the group - must be at least two */ -+ uint8_t num_of_entries; /**< Number of members in the group - must be at least 1 */ -+ ioc_fm_pcd_cc_next_engine_params_t next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES]; -+ /**< Array of members' parameters */ -+ void *id; -+} ioc_fm_pcd_frm_replic_group_params_t; -+ -+typedef struct ioc_fm_pcd_frm_replic_member_t { -+ void *h_replic_group; -+ uint16_t member_index; -+} ioc_fm_pcd_frm_replic_member_t; -+ -+typedef struct ioc_fm_pcd_frm_replic_member_params_t { -+ ioc_fm_pcd_frm_replic_member_t member; -+ ioc_fm_pcd_cc_next_engine_params_t next_engine_params; -+} ioc_fm_pcd_frm_replic_member_params_t; -+#endif /* DPAA_VERSION >= 11 */ -+ -+ -+typedef struct ioc_fm_pcd_cc_key_statistics_t { -+ uint32_t byte_count; /**< This counter reflects byte count of frames that -+ were matched by this key. */ -+ uint32_t frame_count; /**< This counter reflects count of frames that -+ were matched by this key. */ -+#if (DPAA_VERSION >= 11) -+ uint32_t frame_length_range_count[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR]; -+ /**< These counters reflect how many frames matched -+ this key in 'RMON' statistics mode: -+ Each counter holds the number of frames of a -+ specific frames length range, according to the -+ ranges provided at initialization. */ -+#endif /* (DPAA_VERSION >= 11) */ -+} ioc_fm_pcd_cc_key_statistics_t; -+ -+ -+typedef struct ioc_fm_pcd_cc_tbl_get_stats_t { -+ void *id; -+ uint16_t key_index; -+ ioc_fm_pcd_cc_key_statistics_t statistics; -+} ioc_fm_pcd_cc_tbl_get_stats_t; -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableGetKeyStatistics -+ -+ @Description This routine may be used to get statistics counters of specific key -+ in a CC Node. -+ -+ If 'e_FM_PCD_CC_STATS_MODE_FRAME' and -+ 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, -+ these counters reflect how many frames passed that were matched -+ this key; The total frames count will be returned in the counter -+ of the first range (as only one frame length range was defined). -+ If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total -+ frame count will be separated to frame length counters, based on -+ provided frame length ranges. -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[in] keyIndex Key index for adding -+ @Param[out] p_KeyStatistics Key statistics counters -+ -+ @Return The specific key statistics. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet(). -+*//***************************************************************************/ -+ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(12), ioc_compat_fm_pcd_cc_tbl_get_stats_t) -+#endif -+#define FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(12), ioc_fm_pcd_cc_tbl_get_stats_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableGetMissStatistics -+ -+ @Description This routine may be used to get statistics counters of miss entry -+ in a CC Node. -+ -+ If 'e_FM_PCD_CC_STATS_MODE_FRAME' and -+ 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, -+ these counters reflect how many frames were not matched to any -+ existing key and therefore passed through the miss entry; The -+ total frames count will be returned in the counter of the -+ first range (as only one frame length range was defined). -+ -+ @Param[in] h_CcNode A handle to the node -+ @Param[out] p_MissStatistics Statistics counters for 'miss' -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet(). -+*//***************************************************************************/ -+ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(13), ioc_compat_fm_pcd_cc_tbl_get_stats_t) -+#endif -+#define FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(13), ioc_fm_pcd_cc_tbl_get_stats_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableGetMissStatistics -+ -+ @Description This routine may be used to get statistics counters of 'miss' -+ entry of the a hash table. -+ -+ If 'e_FM_PCD_CC_STATS_MODE_FRAME' and -+ 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node, -+ these counters reflect how many frames were not matched to any -+ existing key and therefore passed through the miss entry; -+ -+ @Param[in] h_HashTbl A handle to a hash table -+ @Param[out] p_MissStatistics Statistics counters for 'miss' -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+*//***************************************************************************/ -+ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(14), ioc_compat_fm_pcd_cc_tbl_get_stats_t) -+#endif -+#define FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(14), ioc_fm_pcd_cc_tbl_get_stats_t) -+ -+ -+/**************************************************************************//** -+ @Function FM_PCD_NetEnvCharacteristicsSet -+ -+ @Description Define a set of Network Environment Characteristics. -+ -+ When setting an environment it is important to understand its -+ application. It is not meant to describe the flows that will run -+ on the ports using this environment, but what the user means TO DO -+ with the PCD mechanisms in order to parse-classify-distribute those -+ frames. -+ By specifying a distinction unit, the user means it would use that option -+ for distinction between frames at either a KeyGen scheme or a coarse -+ classification action descriptor. Using interchangeable headers to define a -+ unit means that the user is indifferent to which of the interchangeable -+ headers is present in the frame, and wants the distinction to be based -+ on the presence of either one of them. -+ -+ Depending on context, there are limitations to the use of environments. A -+ port using the PCD functionality is bound to an environment. Some or even -+ all ports may share an environment but also an environment per port is -+ possible. When initializing a scheme, a classification plan group (see below), -+ or a coarse classification tree, one of the initialized environments must be -+ stated and related to. When a port is bound to a scheme, a classification -+ plan group, or a coarse classification tree, it MUST be bound to the same -+ environment. -+ -+ The different PCD modules, may relate (for flows definition) ONLY on -+ distinction units as defined by their environment. When initializing a -+ scheme for example, it may not choose to select IPV4 as a match for -+ recognizing flows unless it was defined in the relating environment. In -+ fact, to guide the user through the configuration of the PCD, each module's -+ characterization in terms of flows is not done using protocol names, but using -+ environment indexes. -+ -+ In terms of HW implementation, the list of distinction units sets the LCV vectors -+ and later used for match vector, classification plan vectors and coarse classification -+ indexing. -+ -+ @Param[in,out] ioc_fm_pcd_net_env_params_t A structure defining the distiction units for this configuration. -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(20), ioc_compat_fm_pcd_net_env_params_t) -+#endif -+#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(20), ioc_fm_pcd_net_env_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_NetEnvCharacteristicsDelete -+ -+ @Description Deletes a set of Network Environment Charecteristics. -+ -+ @Param[in] ioc_fm_obj_t - The id of a Network Environment object. -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_compat_fm_obj_t) -+#endif -+#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_KgSchemeSet -+ -+ @Description Initializing or modifying and enabling a scheme for the KeyGen. -+ This routine should be called for adding or modifying a scheme. -+ When a scheme needs modifying, the API requires that it will be -+ rewritten. In such a case 'modify' should be TRUE. If the -+ routine is called for a valid scheme and 'modify' is FALSE, -+ it will return error. -+ -+ @Param[in,out] ioc_fm_pcd_kg_scheme_params_t A structure of parameters for defining the scheme -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_KG_SCHEME_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_compat_fm_pcd_kg_scheme_params_t) -+#endif -+#define FM_PCD_IOC_KG_SCHEME_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_fm_pcd_kg_scheme_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_KgSchemeDelete -+ -+ @Description Deleting an initialized scheme. -+ -+ @Param[in] ioc_fm_obj_t scheme id as initalized by application at FM_PCD_IOC_KG_SET_SCHEME -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_compat_fm_obj_t) -+#endif -+#define FM_PCD_IOC_KG_SCHEME_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_CcRootBuild -+ -+ @Description This routine must be called to define a complete coarse -+ classification tree. This is the way to define coarse -+ classification to a certain flow - the KeyGen schemes -+ may point only to trees defined in this way. -+ -+ @Param[in,out] ioc_fm_pcd_cc_tree_params_t A structure of parameters to define the tree. -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_CC_ROOT_BUILD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), compat_uptr_t) -+#endif -+#define FM_PCD_IOC_CC_ROOT_BUILD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), void *) /* workaround ...*/ -+ -+/**************************************************************************//** -+ @Function FM_PCD_CcRootDelete -+ -+ @Description Deleting a built tree. -+ -+ @Param[in] ioc_fm_obj_t - The id of a CC tree. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_CC_ROOT_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_compat_fm_obj_t) -+#endif -+#define FM_PCD_IOC_CC_ROOT_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableSet -+ -+ @Description This routine should be called for each CC (coarse classification) -+ node. The whole CC tree should be built bottom up so that each -+ node points to already defined nodes. p_NodeId returns the node -+ Id to be used by other nodes. -+ -+ @Param[in,out] ioc_fm_pcd_cc_node_params_t A structure for defining the CC node params -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MATCH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), compat_uptr_t) -+#endif -+#define FM_PCD_IOC_MATCH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), void *) /* workaround ...*/ -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableDelete -+ -+ @Description Deleting a built node. -+ -+ @Param[in] ioc_fm_obj_t - The id of a CC node. -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_compat_fm_obj_t) -+#endif -+#define FM_PCD_IOC_MATCH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_CcRootModifyNextEngine -+ -+ @Description Modify the Next Engine Parameters in the entry of the tree. -+ -+ @Param[in] ioc_fm_pcd_cc_tree_modify_next_engine_params_t - Pointer to a structure with the relevant parameters -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_CcRootBuild(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(30), ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t) -+#endif -+#define FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(30), ioc_fm_pcd_cc_tree_modify_next_engine_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableModifyNextEngine -+ -+ @Description Modify the Next Engine Parameters in the relevant key entry of the node. -+ -+ @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t A pointer to a structure with the relevant parameters -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(31), ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t) -+#endif -+#define FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(31), ioc_fm_pcd_cc_node_modify_next_engine_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableModifyMissNextEngine -+ -+ @Description Modify the Next Engine Parameters of the Miss key case of the node. -+ -+ @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t - Pointer to a structure with the relevant parameters -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(32), ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t) -+#endif -+#define FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(32), ioc_fm_pcd_cc_node_modify_next_engine_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableRemoveKey -+ -+ @Description Remove the key (including next engine parameters of this key) -+ defined by the index of the relevant node. -+ -+ @Param[in] ioc_fm_pcd_cc_node_remove_key_params_t A pointer to a structure with the relevant parameters -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this -+ node and for all of the nodes that lead to it. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(33), ioc_compat_fm_pcd_cc_node_remove_key_params_t) -+#endif -+#define FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(33), ioc_fm_pcd_cc_node_remove_key_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableAddKey -+ -+ @Description Add the key (including next engine parameters of this key in the -+ index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX' -+ may be used when the user doesn't care about the position of the -+ key in the table - in that case, the key will be automatically -+ added by the driver in the last available entry. -+ -+ @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this -+ node and for all of the nodes that lead to it. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(34), ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t) -+#endif -+#define FM_PCD_IOC_MATCH_TABLE_ADD_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(34), ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableModifyKeyAndNextEngine -+ -+ @Description Modify the key and Next Engine Parameters of this key in the index defined by key_index. -+ -+ @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_MatchTableSet() not only of the relevnt node but also -+ the node that points to this node -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(35), ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t) -+#endif -+#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(35), ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_MatchTableModifyKey -+ -+ @Description Modify the key at the index defined by key_index. -+ -+ @Param[in] ioc_fm_pcd_cc_node_modify_key_params_t - Pointer to a structure with the relevant parameters -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this -+ node and for all of the nodes that lead to it. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(36), ioc_compat_fm_pcd_cc_node_modify_key_params_t) -+#endif -+#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(36), ioc_fm_pcd_cc_node_modify_key_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableSet -+ -+ @Description This routine initializes a hash table structure. -+ KeyGen hash result determines the hash bucket. -+ Next, KeyGen key is compared against all keys of this -+ bucket (exact match). -+ Number of sets (number of buckets) of the hash equals to the -+ number of 1-s in 'hash_res_mask' in the provided parameters. -+ Number of hash table ways is then calculated by dividing -+ 'max_num_of_keys' equally between the hash sets. This is the maximal -+ number of keys that a hash bucket may hold. -+ The hash table is initialized empty and keys may be -+ added to it following the initialization. Keys masks are not -+ supported in current hash table implementation. -+ The initialized hash table can be integrated as a node in a -+ CC tree. -+ -+ @Param[in,out] ioc_fm_pcd_hash_table_params_t - Pointer to a structure with the relevant parameters -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_HASH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_pcd_hash_table_params_t) -+#endif -+#define FM_PCD_IOC_HASH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_pcd_hash_table_params_t) -+ -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableDelete -+ -+ @Description This routine deletes the provided hash table and released all -+ its allocated resources. -+ -+ @Param[in] ioc_fm_obj_t - The ID of a hash table. -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_obj_t) -+#endif -+#define FM_PCD_IOC_HASH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableAddKey -+ -+ @Description This routine adds the provided key (including next engine -+ parameters of this key) to the hash table. -+ The key is added as the last key of the bucket that it is -+ mapped to. -+ -+ @Param[in] ioc_fm_pcd_hash_table_add_key_params_t - Pointer to a structure with the relevant parameters -+ -+ @Return 0 on success; error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(39), ioc_compat_fm_pcd_hash_table_add_key_params_t) -+#endif -+#define FM_PCD_IOC_HASH_TABLE_ADD_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(39), ioc_fm_pcd_hash_table_add_key_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_HashTableRemoveKey -+ -+ @Description This routine removes the requested key (including next engine -+ parameters of this key) from the hash table. -+ -+ @Param[in] ioc_fm_pcd_hash_table_remove_key_params_t - Pointer to a structure with the relevant parameters -+ -+ @Return 0 on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_HashTableSet(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(40), ioc_compat_fm_pcd_hash_table_remove_key_params_t) -+#endif -+#define FM_PCD_IOC_HASH_TABLE_REMOVE_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(40), ioc_fm_pcd_hash_table_remove_key_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_PlcrProfileSet -+ -+ @Description Sets a profile entry in the policer profile table. -+ The routine overrides any existing value. -+ -+ @Param[in,out] ioc_fm_pcd_plcr_profile_params_t A structure of parameters for defining a -+ policer profile entry. -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_pcd_plcr_profile_params_t) -+#endif -+#define FM_PCD_IOC_PLCR_PROFILE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_pcd_plcr_profile_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_PlcrProfileDelete -+ -+ @Description Delete a profile entry in the policer profile table. -+ The routine set entry to invalid. -+ -+ @Param[in] ioc_fm_obj_t The id of a policer profile. -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_obj_t) -+#endif -+#define FM_PCD_IOC_PLCR_PROFILE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_ManipNodeSet -+ -+ @Description This routine should be called for defining a manipulation -+ node. A manipulation node must be defined before the CC node -+ that precedes it. -+ -+ @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation -+ -+ @Return A handle to the initialized object on success; NULL code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MANIP_NODE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_compat_fm_pcd_manip_params_t) -+#endif -+#define FM_PCD_IOC_MANIP_NODE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_fm_pcd_manip_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_ManipNodeReplace -+ -+ @Description Change existing manipulation node to be according to new requirement. -+ (Here, it's implemented as a variant of the same IOCTL as for -+ FM_PCD_ManipNodeSet(), and one that when called, the 'id' member -+ in its 'ioc_fm_pcd_manip_params_t' argument is set to contain -+ the manip node's handle) -+ -+ @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation -+ -+ @Return 0 on success; error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_ManipNodeSet(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MANIP_NODE_REPLACE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT -+#endif -+#define FM_PCD_IOC_MANIP_NODE_REPLACE FM_PCD_IOC_MANIP_NODE_SET -+ -+/**************************************************************************//** -+ @Function FM_PCD_ManipNodeDelete -+ -+ @Description Delete an existing manipulation node. -+ -+ @Param[in] ioc_fm_obj_t The id of the manipulation node to delete. -+ -+ @Return 0 on success; error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_ManipNodeSet(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_compat_fm_obj_t) -+#endif -+#define FM_PCD_IOC_MANIP_NODE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_ManipGetStatistics -+ -+ @Description Retrieve the manipulation statistics. -+ -+ @Param[in] h_ManipNode A handle to a manipulation node. -+ @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_ManipNodeSet(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_MANIP_GET_STATS_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_compat_fm_pcd_manip_get_stats_t) -+#endif -+#define FM_PCD_IOC_MANIP_GET_STATS _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_fm_pcd_manip_get_stats_t) -+ -+/**************************************************************************//** -+@Function FM_PCD_SetAdvancedOffloadSupport -+ -+@Description This routine must be called in order to support the following features: -+ IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator. -+ -+@Param[in] h_FmPcd FM PCD module descriptor. -+ -+@Return 0 on success; error code otherwise. -+ -+@Cautions Allowed only when PCD is disabled. -+*//***************************************************************************/ -+#define FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45)) -+ -+#if (DPAA_VERSION >= 11) -+/**************************************************************************//** -+ @Function FM_PCD_FrmReplicSetGroup -+ -+ @Description Initialize a Frame Replicator group. -+ -+ @Param[in] h_FmPcd FM PCD module descriptor. -+ @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of -+ the frame replicator group. -+ -+ @Return A handle to the initialized object on success; NULL code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_Init(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(46), ioc_compat_fm_pcd_frm_replic_group_params_t) -+#endif -+#define FM_PCD_IOC_FRM_REPLIC_GROUP_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(46), ioc_fm_pcd_frm_replic_group_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_FrmReplicDeleteGroup -+ -+ @Description Delete a Frame Replicator group. -+ -+ @Param[in] h_FrmReplicGroup A handle to the frame replicator group. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_FrmReplicSetGroup(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_compat_fm_obj_t) -+#endif -+#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_FrmReplicAddMember -+ -+ @Description Add the member in the index defined by the memberIndex. -+ -+ @Param[in] h_FrmReplicGroup A handle to the frame replicator group. -+ @Param[in] memberIndex member index for adding. -+ @Param[in] p_MemberParams A pointer to the new member parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(48), ioc_compat_fm_pcd_frm_replic_member_params_t) -+#endif -+#define FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(48), ioc_fm_pcd_frm_replic_member_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PCD_FrmReplicRemoveMember -+ -+ @Description Remove the member defined by the index from the relevant group. -+ -+ @Param[in] h_FrmReplicGroup A handle to the frame replicator group. -+ @Param[in] memberIndex member index for removing. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(49), ioc_compat_fm_pcd_frm_replic_member_t) -+#endif -+#define FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(49), ioc_fm_pcd_frm_replic_member_t) -+ -+#endif -+ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+/**************************************************************************//** -+ @Function FM_PCD_StatisticsSetNode -+ -+ @Description This routine should be called for defining a statistics node. -+ -+ @Param[in,out] ioc_fm_pcd_stats_params_t A structure of parameters defining the statistics -+ -+ @Return 0 on success; Error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *) -+#endif -+#define FM_PCD_IOC_STATISTICS_SET_NODE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *) -+ -+#endif /* FM_CAPWAP_SUPPORT */ -+ -+#ifdef NCSW_BACKWARD_COMPATIBLE_API -+#if defined(CONFIG_COMPAT) -+#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS_COMPAT \ -+ FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT -+#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS_COMPAT \ -+ FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT -+#define FM_PCD_IOC_KG_SET_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_SET_COMPAT -+#define FM_PCD_IOC_KG_DEL_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT -+#define FM_PCD_IOC_CC_BUILD_TREE_COMPAT FM_PCD_IOC_CC_ROOT_BUILD_COMPAT -+#define FM_PCD_IOC_CC_DELETE_TREE_COMPAT FM_PCD_IOC_CC_ROOT_DELETE_COMPAT -+#define FM_PCD_IOC_CC_DELETE_NODE_COMPAT FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT -+#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE_COMPAT \ -+ FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT -+#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE_COMPAT \ -+ FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT -+#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE_COMPAT \ -+ FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT -+#define FM_PCD_IOC_CC_NODE_REMOVE_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT -+#define FM_PCD_IOC_CC_NODE_ADD_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT -+#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT \ -+ FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT -+#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT -+#define FM_PCD_IOC_PLCR_SET_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT -+#define FM_PCD_IOC_PLCR_DEL_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT -+#define FM_PCD_IOC_MANIP_SET_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT -+#define FM_PCD_IOC_MANIP_DELETE_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT -+#endif -+#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET -+#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS \ -+ FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE -+#define FM_PCD_IOC_KG_SET_SCHEME FM_PCD_IOC_KG_SCHEME_SET -+#define FM_PCD_IOC_KG_DEL_SCHEME FM_PCD_IOC_KG_SCHEME_DELETE -+#define FM_PCD_IOC_CC_BUILD_TREE FM_PCD_IOC_CC_ROOT_BUILD -+#define FM_PCD_IOC_CC_DELETE_TREE FM_PCD_IOC_CC_ROOT_DELETE -+#define FM_PCD_IOC_CC_DELETE_NODE FM_PCD_IOC_MATCH_TABLE_DELETE -+#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE -+#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE -+#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE \ -+ FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE -+#define FM_PCD_IOC_CC_NODE_REMOVE_KEY FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY -+#define FM_PCD_IOC_CC_NODE_ADD_KEY FM_PCD_IOC_MATCH_TABLE_ADD_KEY -+#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE \ -+ FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE -+#define FM_PCD_IOC_CC_NODE_MODIFY_KEY FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY -+#define FM_PCD_IOC_PLCR_SET_PROFILE FM_PCD_IOC_PLCR_PROFILE_SET -+#define FM_PCD_IOC_PLCR_DEL_PROFILE FM_PCD_IOC_PLCR_PROFILE_DELETE -+#define FM_PCD_IOC_MANIP_SET_NODE FM_PCD_IOC_MANIP_NODE_SET -+#define FM_PCD_IOC_MANIP_DELETE_NODE FM_PCD_IOC_MANIP_NODE_DELETE -+#endif /* NCSW_BACKWARD_COMPATIBLE_API */ -+ -+#endif /* __FM_PCD_IOCTLS_H */ -+/** @} */ /* end of lnx_ioctl_FM_PCD_Runtime_grp group */ -+/** @} */ /* end of lnx_ioctl_FM_PCD_grp group */ -+/** @} */ /* end of lnx_ioctl_FM_grp group */ ---- /dev/null -+++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h -@@ -0,0 +1,948 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/****************************************************************************** -+ @File fm_port_ioctls.h -+ -+ @Description FM Port routines -+*//***************************************************************************/ -+#ifndef __FM_PORT_IOCTLS_H -+#define __FM_PORT_IOCTLS_H -+ -+#include "enet_ext.h" -+#include "net_ioctls.h" -+#include "fm_ioctls.h" -+#include "fm_pcd_ioctls.h" -+ -+ -+/**************************************************************************//** -+ -+ @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API -+ -+ @Description FM Linux ioctls definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FM_PORT_grp FM Port -+ -+ @Description FM Port API -+ -+ The FM uses a general module called "port" to represent a Tx port -+ (MAC), an Rx port (MAC), offline parsing flow or host command -+ flow. There may be up to 17 (may change) ports in an FM - 5 Tx -+ ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7 -+ Host command/Offline parsing ports. The SW driver manages these -+ ports as sub-modules of the FM, i.e. after an FM is initialized, -+ its ports may be initialized and operated upon. -+ -+ The port is initialized aware of its type, but other functions on -+ a port may be indifferent to its type. When necessary, the driver -+ verifies coherency and returns error if applicable. -+ -+ On initialization, user specifies the port type and it's index -+ (relative to the port's type). Host command and Offline parsing -+ ports share the same id range, I.e user may not initialized host -+ command port 0 and offline parsing port 0. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description An enum for defining port PCD modes. -+ (Must match enum e_FmPortPcdSupport defined in fm_port_ext.h) -+ -+ This enum defines the superset of PCD engines support - i.e. not -+ all engines have to be used, but all have to be enabled. The real -+ flow of a specific frame depends on the PCD configuration and the -+ frame headers and payload. -+ Note: the first engine and the first engine after the parser (if -+ exists) should be in order, the order is important as it will -+ define the flow of the port. However, as for the rest engines -+ (the ones that follows), the order is not important anymore as -+ it is defined by the PCD graph itself. -+*//***************************************************************************/ -+typedef enum ioc_fm_port_pcd_support { -+ e_IOC_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */ -+ , e_IOC_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */ -+ , e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */ -+ , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */ -+ , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */ -+ , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */ -+ , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR -+ /**< Use all PCD engines */ -+ , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */ -+ , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */ -+ , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */ -+ , e_IOC_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */ -+#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) -+ , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */ -+ , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */ -+#endif /* FM_CAPWAP_SUPPORT */ -+} ioc_fm_port_pcd_support; -+ -+ -+/**************************************************************************//** -+ @Collection FM Frame error -+*//***************************************************************************/ -+typedef uint32_t ioc_fm_port_frame_err_select_t; /**< typedef for defining Frame Descriptor errors */ -+ -+/* @} */ -+ -+ -+/**************************************************************************//** -+ @Description An enum for defining Dual Tx rate limiting scale. -+ (Must match e_FmPortDualRateLimiterScaleDown defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef enum ioc_fm_port_dual_rate_limiter_scale_down { -+ e_IOC_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */ -+ e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */ -+ e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */ -+ e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */ -+} ioc_fm_port_dual_rate_limiter_scale_down; -+ -+/**************************************************************************//** -+ @Description A structure for defining Tx rate limiting -+ (Must match struct t_FmPortRateLimit defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_port_rate_limit_t { -+ uint16_t max_burst_size; /**< in KBytes for Tx ports, in frames -+ for offline parsing ports. (note that -+ for early chips burst size is -+ rounded up to a multiply of 1000 frames).*/ -+ uint32_t rate_limit; /**< in Kb/sec for Tx ports, in frame/sec for -+ offline parsing ports. Rate limit refers to -+ data rate (rather than line rate). */ -+ ioc_fm_port_dual_rate_limiter_scale_down rate_limit_divider; /**< For offline parsing ports only. Not-valid -+ for some earlier chip revisions */ -+} ioc_fm_port_rate_limit_t; -+ -+ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FM_PORT_runtime_control_grp FM Port Runtime Control Unit -+ -+ @Description FM Port Runtime control unit API functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description An enum for defining FM Port counters. -+ (Must match enum e_FmPortCounters defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef enum ioc_fm_port_counters { -+ e_IOC_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */ -+ e_IOC_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */ -+ e_IOC_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */ -+ e_IOC_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */ -+ e_IOC_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */ -+ e_IOC_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */ -+ e_IOC_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */ -+ e_IOC_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */ -+ e_IOC_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */ -+ e_IOC_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */ -+ e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */ -+} ioc_fm_port_counters; -+ -+typedef struct ioc_fm_port_bmi_stats_t { -+ uint32_t cnt_cycle; -+ uint32_t cnt_task_util; -+ uint32_t cnt_queue_util; -+ uint32_t cnt_dma_util; -+ uint32_t cnt_fifo_util; -+ uint32_t cnt_rx_pause_activation; -+ uint32_t cnt_frame; -+ uint32_t cnt_discard_frame; -+ uint32_t cnt_dealloc_buf; -+ uint32_t cnt_rx_bad_frame; -+ uint32_t cnt_rx_large_frame; -+ uint32_t cnt_rx_filter_frame; -+ uint32_t cnt_rx_list_dma_err; -+ uint32_t cnt_rx_out_of_buffers_discard; -+ uint32_t cnt_wred_discard; -+ uint32_t cnt_length_err; -+ uint32_t cnt_unsupported_format; -+} ioc_fm_port_bmi_stats_t; -+ -+/**************************************************************************//** -+ @Description Structure for Port id parameters. -+ (Description may be inaccurate; -+ must match struct t_FmPortCongestionGrps defined in fm_port_ext.h) -+ -+ Fields commented 'IN' are passed by the port module to be used -+ by the FM module. -+ Fields commented 'OUT' will be filled by FM before returning to port. -+*//***************************************************************************/ -+typedef struct ioc_fm_port_congestion_groups_t { -+ uint16_t num_of_congestion_grps_to_consider; /**< The number of required congestion groups -+ to define the size of the following array */ -+ uint8_t congestion_grps_to_consider [FM_PORT_NUM_OF_CONGESTION_GRPS]; -+ /**< An array of CG indexes; -+ Note that the size of the array should be -+ 'num_of_congestion_grps_to_consider'. */ -+#if DPAA_VERSION >= 11 -+ bool pfc_priorities_enable[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES]; -+ /**< A matrix that represents the map between the CG ids -+ defined in 'congestion_grps_to_consider' to the priorities -+ mapping array. */ -+#endif /* DPAA_VERSION >= 11 */ -+} ioc_fm_port_congestion_groups_t; -+ -+ -+ -+/**************************************************************************//** -+ @Function FM_PORT_Disable -+ -+ @Description Gracefully disable an FM port. The port will not start new tasks after all -+ tasks associated with the port are terminated. -+ -+ @Return 0 on success; error code otherwise. -+ -+ @Cautions This is a blocking routine, it returns after port is -+ gracefully stopped, i.e. the port will not except new frames, -+ but it will finish all frames or tasks which were already began -+*//***************************************************************************/ -+#define FM_PORT_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(1)) -+ -+/**************************************************************************//** -+ @Function FM_PORT_Enable -+ -+ @Description A runtime routine provided to allow disable/enable of port. -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#define FM_PORT_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(2)) -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetRateLimit -+ -+ @Description Calling this routine enables rate limit algorithm. -+ By default, this functionality is disabled. -+ Note that rate-limit mechanism uses the FM time stamp. -+ The selected rate limit specified here would be -+ rounded DOWN to the nearest 16M. -+ -+ May be used for Tx and offline parsing ports only -+ -+ @Param[in] ioc_fm_port_rate_limit A structure of rate limit parameters -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#define FM_PORT_IOC_SET_RATE_LIMIT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(3), ioc_fm_port_rate_limit_t) -+ -+/**************************************************************************//** -+ @Function FM_PORT_DeleteRateLimit -+ -+ @Description Calling this routine disables the previously enabled rate limit. -+ -+ May be used for Tx and offline parsing ports only -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#define FM_PORT_IOC_DELETE_RATE_LIMIT _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(5)) -+#define FM_PORT_IOC_REMOVE_RATE_LIMIT FM_PORT_IOC_DELETE_RATE_LIMIT -+ -+ -+/**************************************************************************//** -+ @Function FM_PORT_AddCongestionGrps -+ -+ @Description This routine effects the corresponding Tx port. -+ It should be called in order to enable pause -+ frame transmission in case of congestion in one or more -+ of the congestion groups relevant to this port. -+ Each call to this routine may add one or more congestion -+ groups to be considered relevant to this port. -+ -+ May be used for Rx, or RX+OP ports only (depending on chip) -+ -+ @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of -+ congestion group ids to consider. -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#define FM_PORT_IOC_ADD_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(34), ioc_fm_port_congestion_groups_t) -+ -+/**************************************************************************//** -+ @Function FM_PORT_RemoveCongestionGrps -+ -+ @Description This routine effects the corresponding Tx port. It should be -+ called when congestion groups were -+ defined for this port and are no longer relevant, or pause -+ frames transmitting is not required on their behalf. -+ Each call to this routine may remove one or more congestion -+ groups to be considered relevant to this port. -+ -+ May be used for Rx, or RX+OP ports only (depending on chip) -+ -+ @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of -+ congestion group ids to consider. -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#define FM_PORT_IOC_REMOVE_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(35), ioc_fm_port_congestion_groups_t) -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetErrorsRoute -+ -+ @Description Errors selected for this routine will cause a frame with that error -+ to be enqueued to error queue. -+ Errors not selected for this routine will cause a frame with that error -+ to be enqueued to the one of the other port queues. -+ By default all errors are defined to be enqueued to error queue. -+ Errors that were configured to be discarded (at initialization) -+ may not be selected here. -+ -+ May be used for Rx and offline parsing ports only -+ -+ @Param[in] ioc_fm_port_frame_err_select_t A list of errors to enqueue to error queue -+ -+ @Return 0 on success; error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+ (szbs001: How is it possible to have one function that needs to be -+ called BEFORE FM_PORT_Init() implemented as an ioctl, -+ which will ALWAYS be called AFTER the FM_PORT_Init() -+ for that port!?!?!?!???!?!??!?!?) -+*//***************************************************************************/ -+#define FM_PORT_IOC_SET_ERRORS_ROUTE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(4), ioc_fm_port_frame_err_select_t) -+ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit -+ -+ @Description FM Port PCD Runtime control unit API functions, definitions and enums. -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description A structure defining the KG scheme after the parser. -+ (Must match struct t_FmPcdKgSchemeSelect defined in fm_port_ext.h) -+ -+ This is relevant only to change scheme selection mode - from -+ direct to indirect and vice versa, or when the scheme is selected directly, -+ to select the scheme id. -+ -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_kg_scheme_select_t { -+ bool direct; /**< TRUE to use 'scheme_id' directly, FALSE to use LCV.*/ -+ void *scheme_id; /**< Relevant for 'direct'=TRUE only. -+ 'scheme_id' selects the scheme after parser. */ -+} ioc_fm_pcd_kg_scheme_select_t; -+ -+/**************************************************************************//** -+ @Description Scheme IDs structure -+ (Must match struct t_FmPcdPortSchemesParams defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_port_schemes_params_t { -+ uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */ -+ void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'num_of_schemes' schemes for the -+ port to be bound to */ -+} ioc_fm_pcd_port_schemes_params_t; -+ -+/**************************************************************************//** -+ @Description A union for defining port protocol parameters for parser -+ (Must match union u_FmPcdHdrPrsOpts defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef union ioc_fm_pcd_hdr_prs_opts_u { -+ /* MPLS */ -+ struct { -+ bool label_interpretation_enable;/**< When this bit is set, the last MPLS label will be -+ interpreted as described in HW spec table. When the bit -+ is cleared, the parser will advance to MPLS next parse */ -+ ioc_net_header_type next_parse; /**< must be equal or higher than IPv4 */ -+ } mpls_prs_options; -+ -+ /* VLAN */ -+ struct { -+ uint16_t tag_protocol_id1; /**< User defined Tag Protocol Identifier, to be recognized -+ on VLAN TAG on top of 0x8100 and 0x88A8 */ -+ uint16_t tag_protocol_id2; /**< User defined Tag Protocol Identifier, to be recognized -+ on VLAN TAG on top of 0x8100 and 0x88A8 */ -+ } vlan_prs_options; -+ -+ /* PPP */ -+ struct{ -+ bool enable_mtu_check; /**< Check validity of MTU according to RFC2516 */ -+ } pppoe_prs_options; -+ -+ /* IPV6 */ -+ struct { -+ bool routing_hdr_disable; /**< Disable routing header */ -+ } ipv6_prs_options; -+ -+ /* UDP */ -+ struct { -+ bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */ -+ } udp_prs_options; -+ -+ /* TCP */ -+ struct { -+ bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */ -+ } tcp_prs_options; -+} ioc_fm_pcd_hdr_prs_opts_u; -+ -+/**************************************************************************//** -+ @Description A structure for defining each header for the parser -+ (must match struct t_FmPcdPrsAdditionalHdrParams defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_prs_additional_hdr_params_t { -+ ioc_net_header_type hdr; /**< Selected header */ -+ bool err_disable; /**< TRUE to disable error indication */ -+ bool soft_prs_enable; /**< Enable jump to SW parser when this -+ header is recognized by the HW parser. */ -+ uint8_t index_per_hdr; /**< Normally 0, if more than one sw parser -+ attachments exists for the same header, -+ (in the main sw parser code) use this -+ index to distinguish between them. */ -+ bool use_prs_opts; /**< TRUE to use parser options. */ -+ ioc_fm_pcd_hdr_prs_opts_u prs_opts; /**< A unuion according to header type, -+ defining the parser options selected.*/ -+} ioc_fm_pcd_prs_additional_hdr_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for defining port PCD parameters -+ (Must match t_FmPortPcdPrsParams defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_port_pcd_prs_params_t { -+ uint8_t prs_res_priv_info; /**< The private info provides a method of inserting -+ port information into the parser result. This information -+ may be extracted by KeyGen and be used for frames -+ distribution when a per-port distinction is required, -+ it may also be used as a port logical id for analyzing -+ incoming frames. */ -+ uint8_t parsing_offset; /**< Number of bytes from begining of packet to start parsing */ -+ ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at 'parsing_offset' */ -+ bool include_in_prs_statistics; /**< TRUE to include this port in the parser statistics */ -+ uint8_t num_of_hdrs_with_additional_params; -+ /**< Normally 0, some headers may get special parameters */ -+ ioc_fm_pcd_prs_additional_hdr_params_t additional_params[IOC_FM_PCD_PRS_NUM_OF_HDRS]; -+ /**< 'num_of_hdrs_with_additional_params' structures -+ additional parameters for each header that requires them */ -+ bool set_vlan_tpid1; /**< TRUE to configure user selection of Ethertype to -+ indicate a VLAN tag (in addition to the TPID values -+ 0x8100 and 0x88A8). */ -+ uint16_t vlan_tpid1; /**< extra tag to use if set_vlan_tpid1=TRUE. */ -+ bool set_vlan_tpid2; /**< TRUE to configure user selection of Ethertype to -+ indicate a VLAN tag (in addition to the TPID values -+ 0x8100 and 0x88A8). */ -+ uint16_t vlan_tpid2; /**< extra tag to use if set_vlan_tpid1=TRUE. */ -+} ioc_fm_port_pcd_prs_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for defining coarse alassification parameters -+ (Must match t_FmPortPcdCcParams defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_port_pcd_cc_params_t { -+ void *cc_tree_id; /**< CC tree id */ -+} ioc_fm_port_pcd_cc_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for defining keygen parameters -+ (Must match t_FmPortPcdKgParams defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_port_pcd_kg_params_t { -+ uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */ -+ void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; -+ /**< Array of 'num_of_schemes' schemes for the -+ port to be bound to */ -+ bool direct_scheme; /**< TRUE for going from parser to a specific scheme, -+ regardless of parser result */ -+ void *direct_scheme_id; /**< Scheme id, as returned by FM_PCD_KgSetScheme; -+ relevant only if direct=TRUE. */ -+} ioc_fm_port_pcd_kg_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for defining policer parameters -+ (Must match t_FmPortPcdPlcrParams defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_port_pcd_plcr_params_t { -+ void *plcr_profile_id; /**< Selected profile handle; -+ relevant in one of the following cases: -+ e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY or -+ e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected, -+ or if any flow uses a KG scheme where policer -+ profile is not generated (bypass_plcr_profile_generation selected) */ -+} ioc_fm_port_pcd_plcr_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for defining port PCD parameters -+ (Must match struct t_FmPortPcdParams defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_port_pcd_params_t { -+ ioc_fm_port_pcd_support pcd_support; /**< Relevant for Rx and offline ports only. -+ Describes the active PCD engines for this port. */ -+ void *net_env_id; /**< HL Unused in PLCR only mode */ -+ ioc_fm_port_pcd_prs_params_t *p_prs_params; /**< Parser parameters for this port */ -+ ioc_fm_port_pcd_cc_params_t *p_cc_params; /**< Coarse classification parameters for this port */ -+ ioc_fm_port_pcd_kg_params_t *p_kg_params; /**< Keygen parameters for this port */ -+ ioc_fm_port_pcd_plcr_params_t *p_plcr_params; /**< Policer parameters for this port */ -+ void *p_ip_reassembly_manip;/**< IP Reassembly manipulation */ -+#if (DPAA_VERSION >= 11) -+ void *p_capwap_reassembly_manip;/**< CAPWAP Reassembly manipulation */ -+#endif /* (DPAA_VERSION >= 11) */ -+} ioc_fm_port_pcd_params_t; -+ -+/**************************************************************************//** -+ @Description A structure for defining the Parser starting point -+ (Must match struct t_FmPcdPrsStart defined in fm_port_ext.h) -+*//***************************************************************************/ -+typedef struct ioc_fm_pcd_prs_start_t { -+ uint8_t parsing_offset; /**< Number of bytes from begining of packet to -+ start parsing */ -+ ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at -+ 'parsing_offset' */ -+} ioc_fm_pcd_prs_start_t; -+ -+ -+/**************************************************************************//** -+ @Description FQID parameters structure -+*//***************************************************************************/ -+typedef struct ioc_fm_port_pcd_fqids_params_t { -+ uint32_t num_fqids; /**< Number of fqids to be allocated for the port */ -+ uint8_t alignment; /**< Alignment required for this port */ -+ uint32_t base_fqid; /**< output parameter - the base fqid */ -+} ioc_fm_port_pcd_fqids_params_t; -+ -+ -+/**************************************************************************//** -+ @Function FM_PORT_IOC_ALLOC_PCD_FQIDS -+ -+ @Description Allocates FQID's -+ -+ May be used for Rx and offline parsing ports only -+ -+ @Param[in,out] ioc_fm_port_pcd_fqids_params_t Parameters for allocating FQID's -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#define FM_PORT_IOC_ALLOC_PCD_FQIDS _IOWR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), ioc_fm_port_pcd_fqids_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PORT_IOC_FREE_PCD_FQIDS -+ -+ @Description Frees previously-allocated FQIDs -+ -+ May be used for Rx and offline parsing ports only -+ -+ @Param[in] uint32_t Base FQID of previously allocated range. -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#define FM_PORT_IOC_FREE_PCD_FQIDS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), uint32_t) -+ -+ -+/**************************************************************************//** -+ @Function FM_PORT_SetPCD -+ -+ @Description Calling this routine defines the port's PCD configuration. -+ It changes it from its default configuration which is PCD -+ disabled (BMI to BMI) and configures it according to the passed -+ parameters. -+ -+ May be used for Rx and offline parsing ports only -+ -+ @Param[in] ioc_fm_port_pcd_params_t A Structure of parameters defining the port's PCD -+ configuration. -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PORT_IOC_SET_PCD_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_compat_fm_port_pcd_params_t) -+#endif -+#define FM_PORT_IOC_SET_PCD _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_fm_port_pcd_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PORT_DeletePCD -+ -+ @Description Calling this routine releases the port's PCD configuration. -+ The port returns to its default configuration which is PCD -+ disabled (BMI to BMI) and all PCD configuration is removed. -+ -+ May be used for Rx and offline parsing ports which are -+ in PCD mode only -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#define FM_PORT_IOC_DELETE_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(21)) -+ -+/**************************************************************************//** -+ @Function FM_PORT_AttachPCD -+ -+ @Description This routine may be called after FM_PORT_DetachPCD was called, -+ to return to the originally configured PCD support flow. -+ The couple of routines are used to allow PCD configuration changes -+ that demand that PCD will not be used while changes take place. -+ -+ May be used for Rx and offline parsing ports which are -+ in PCD mode only -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#define FM_PORT_IOC_ATTACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(23)) -+ -+/**************************************************************************//** -+ @Function FM_PORT_DetachPCD -+ -+ @Description Calling this routine detaches the port from its PCD functionality. -+ The port returns to its default flow which is BMI to BMI. -+ -+ May be used for Rx and offline parsing ports which are -+ in PCD mode only -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#define FM_PORT_IOC_DETACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(22)) -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdPlcrAllocProfiles -+ -+ @Description This routine may be called only for ports that use the Policer in -+ order to allocate private policer profiles. -+ -+ @Param[in] uint16_t The number of required policer profiles -+ -+ @Return 0 on success; error code otherwise. -+ -+ @Cautions Allowed before FM_PORT_SetPCD() only. -+*//***************************************************************************/ -+#define FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(24), uint16_t) -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdPlcrFreeProfiles -+ -+ @Description This routine should be called for freeing private policer profiles. -+ -+ @Return 0 on success; error code otherwise. -+ -+ @Cautions Allowed before FM_PORT_SetPCD() only. -+*//***************************************************************************/ -+#define FM_PORT_IOC_PCD_PLCR_FREE_PROFILES _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(25)) -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdKgModifyInitialScheme -+ -+ @Description This routine may be called only for ports that use the keygen in -+ order to change the initial scheme frame should be routed to. -+ The change may be of a scheme id (in case of direct mode), -+ from direct to indirect, or from indirect to direct - specifying the scheme id. -+ -+ @Param[in] ioc_fm_pcd_kg_scheme_select_t A structure of parameters for defining whether -+ a scheme is direct/indirect, and if direct - scheme id. -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(26), ioc_compat_fm_pcd_kg_scheme_select_t) -+#endif -+#define FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(26), ioc_fm_pcd_kg_scheme_select_t) -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdPlcrModifyInitialProfile -+ -+ @Description This routine may be called for ports with flows -+ e_IOC_FM_PCD_SUPPORT_PLCR_ONLY or e_IOC_FM_PCD_SUPPORT_PRS_AND_PLCR only, -+ to change the initial Policer profile frame should be routed to. -+ The change may be of a profile and/or absolute/direct mode selection. -+ -+ @Param[in] ioc_fm_obj_t Policer profile Id as returned from FM_PCD_PlcrSetProfile. -+ -+ @Return 0 on success; error code otherwise. -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_compat_fm_obj_t) -+#endif -+#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdCcModifyTree -+ -+ @Description This routine may be called to change this port connection to -+ a pre-initializes coarse classification Tree. -+ -+ @Param[in] ioc_fm_obj_t Id of new coarse classification tree selected for this port. -+ -+ @Return 0 on success; error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_SetPCD() and FM_PORT_DetachPCD() -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_compat_fm_obj_t) -+#endif -+#define FM_PORT_IOC_PCD_CC_MODIFY_TREE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_fm_obj_t) -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdKgBindSchemes -+ -+ @Description These routines may be called for modifying the binding of ports -+ to schemes. The scheme itself is not added, -+ just this specific port starts using it. -+ -+ @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre -+ -+ @Return 0 on success; error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_SetPCD(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(30), ioc_compat_fm_pcd_port_schemes_params_t) -+#endif -+#define FM_PORT_IOC_PCD_KG_BIND_SCHEMES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(30), ioc_fm_pcd_port_schemes_params_t) -+ -+/**************************************************************************//** -+ @Function FM_PORT_PcdKgUnbindSchemes -+ -+ @Description These routines may be called for modifying the binding of ports -+ to schemes. The scheme itself is not removed or invalidated, -+ just this specific port stops using it. -+ -+ @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre -+ -+ @Return 0 on success; error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_SetPCD(). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(31), ioc_compat_fm_pcd_port_schemes_params_t) -+#endif -+#define FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(31), ioc_fm_pcd_port_schemes_params_t) -+ -+typedef struct ioc_fm_port_mac_addr_params_t { -+ uint8_t addr[ENET_NUM_OCTETS_PER_ADDRESS]; -+} ioc_fm_port_mac_addr_params_t; -+ -+/**************************************************************************//** -+ @Function FM_MAC_AddHashMacAddr -+ -+ @Description Add an Address to the hash table. This is for filter purpose only. -+ -+ @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). It is a filter only address. -+ @Cautions Some address need to be filtered out in upper FM blocks. -+*//***************************************************************************/ -+#define FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(36), ioc_fm_port_mac_addr_params_t) -+ -+/**************************************************************************//** -+ @Function FM_MAC_RemoveHashMacAddr -+ -+ @Description Delete an Address to the hash table. This is for filter purpose only. -+ -+ @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+*//***************************************************************************/ -+#define FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(37), ioc_fm_port_mac_addr_params_t) -+ -+typedef struct ioc_fm_port_tx_pause_frames_params_t { -+ uint8_t priority; -+ uint16_t pause_time; -+ uint16_t thresh_time; -+} ioc_fm_port_tx_pause_frames_params_t; -+ -+/**************************************************************************//** -+ @Function FM_MAC_SetTxPauseFrames -+ -+ @Description Enable/Disable transmission of Pause-Frames. -+ The routine changes the default configuration: -+ pause-time - [0xf000] -+ threshold-time - [0] -+ -+ @Param[in] ioc_fm_port_tx_pause_frames_params_t A structure holding the required parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_MAC_Init(). -+ PFC is supported only on new mEMAC; i.e. in MACs that don't have -+ PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC' -+ in the 'priority' field. -+*//***************************************************************************/ -+#define FM_PORT_IOC_SET_TX_PAUSE_FRAMES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(40), ioc_fm_port_tx_pause_frames_params_t) -+ -+typedef struct ioc_fm_port_mac_statistics_t { -+ /* RMON */ -+ uint64_t e_stat_pkts_64; /**< r-10G tr-DT 64 byte frame counter */ -+ uint64_t e_stat_pkts_65_to_127; /**< r-10G 65 to 127 byte frame counter */ -+ uint64_t e_stat_pkts_128_to_255; /**< r-10G 128 to 255 byte frame counter */ -+ uint64_t e_stat_pkts_256_to_511; /**< r-10G 256 to 511 byte frame counter */ -+ uint64_t e_stat_pkts_512_to_1023; /**< r-10G 512 to 1023 byte frame counter */ -+ uint64_t e_stat_pkts_1024_to_1518; /**< r-10G 1024 to 1518 byte frame counter */ -+ uint64_t e_stat_pkts_1519_to_1522; /**< r-10G 1519 to 1522 byte good frame count */ -+ /* */ -+ uint64_t e_stat_fragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/ -+ uint64_t e_stat_jabbers; /**< Total number of packets longer than valid maximum length octets */ -+ uint64_t e_stat_drop_events; /**< number of dropped packets due to internal errors of the MAC Client (during recieve). */ -+ uint64_t e_stat_CRC_align_errors; /**< Incremented when frames of correct length but with CRC error are received.*/ -+ uint64_t e_stat_undersize_pkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed; -+ This count does not include range length errors */ -+ uint64_t e_stat_oversize_pkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains -+ a valid FCS and otherwise well formed */ -+ /* Pause */ -+ uint64_t te_stat_pause; /**< Pause MAC Control received */ -+ uint64_t re_stat_pause; /**< Pause MAC Control sent */ -+ /* MIB II */ -+ uint64_t if_in_octets; /**< Total number of byte received. */ -+ uint64_t if_in_pkts; /**< Total number of packets received.*/ -+ uint64_t if_in_ucast_pkts; /**< Total number of unicast frame received; -+ NOTE: this counter is not supported on dTSEC MAC */ -+ uint64_t if_in_mcast_pkts; /**< Total number of multicast frame received*/ -+ uint64_t if_in_bcast_pkts; /**< Total number of broadcast frame received */ -+ uint64_t if_in_discards; /**< Frames received, but discarded due to problems within the MAC RX. */ -+ uint64_t if_in_errors; /**< Number of frames received with error: -+ - FIFO Overflow Error -+ - CRC Error -+ - Frame Too Long Error -+ - Alignment Error -+ - The dedicated Error Code (0xfe, not a code error) was received */ -+ uint64_t if_out_octets; /**< Total number of byte sent. */ -+ uint64_t if_out_pkts; /**< Total number of packets sent .*/ -+ uint64_t if_out_ucast_pkts; /**< Total number of unicast frame sent; -+ NOTE: this counter is not supported on dTSEC MAC */ -+ uint64_t if_out_mcast_pkts; /**< Total number of multicast frame sent */ -+ uint64_t if_out_bcast_pkts; /**< Total number of multicast frame sent */ -+ uint64_t if_out_discards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/ -+ uint64_t if_out_errors; /**< Number of frames transmitted with error: -+ - FIFO Overflow Error -+ - FIFO Underflow Error -+ - Other */ -+} ioc_fm_port_mac_statistics_t; -+ -+/**************************************************************************//** -+ @Function FM_MAC_GetStatistics -+ -+ @Description get all MAC statistics counters -+ -+ @Param[out] ioc_fm_port_mac_statistics_t A structure holding the statistics -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+#define FM_PORT_IOC_GET_MAC_STATISTICS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(41), ioc_fm_port_mac_statistics_t) -+ -+/**************************************************************************//** -+ @Function FM_PORT_ConfigBufferPrefixContent -+ -+ @Description Defines the structure, size and content of the application buffer. -+ The prefix will -+ In Tx ports, if 'passPrsResult', the application -+ should set a value to their offsets in the prefix of -+ the FM will save the first 'privDataSize', than, -+ depending on 'passPrsResult' and 'passTimeStamp', copy parse result -+ and timeStamp, and the packet itself (in this order), to the -+ application buffer, and to offset. -+ Calling this routine changes the buffer margins definitions -+ in the internal driver data base from its default -+ configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize] -+ Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult]. -+ Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp]. -+ -+ May be used for all ports -+ -+ @Param[in] ioc_fm_buffer_prefix_content_t A structure holding the required parameters. -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init(). -+*//***************************************************************************/ -+#define FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(39), ioc_fm_buffer_prefix_content_t) -+ -+#if (DPAA_VERSION >= 11) -+typedef struct ioc_fm_port_vsp_alloc_params_t { -+ uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */ -+ uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port -+ The same default Virtual-Storage-Profile-id will be for coupled Tx port -+ if relevant function called for Rx port */ -+ void *p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */ -+}ioc_fm_port_vsp_alloc_params_t; -+ -+/**************************************************************************//** -+ @Function FM_PORT_VSPAlloc -+ -+ @Description This routine allocated VSPs per port and forces the port to work -+ in VSP mode. Note that the port is initialized by default with the -+ physical-storage-profile only. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[in] p_Params A structure of parameters for allocation VSP's per port -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD() -+ and also before FM_PORT_Enable() (i.e. the port should be disabled). -+*//***************************************************************************/ -+#if defined(CONFIG_COMPAT) -+#define FM_PORT_IOC_VSP_ALLOC_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_compat_fm_port_vsp_alloc_params_t) -+#endif -+#define FM_PORT_IOC_VSP_ALLOC _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_fm_port_vsp_alloc_params_t) -+#endif /* (DPAA_VERSION >= 11) */ -+ -+/**************************************************************************//** -+ @Function FM_PORT_GetBmiCounters -+ -+ @Description Read port's BMI stat counters and place them into -+ a designated structure of counters. -+ -+ @Param[in] h_FmPort A handle to a FM Port module. -+ @Param[out] p_BmiStats counters structure -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_PORT_Init(). -+*//***************************************************************************/ -+ -+#define FM_PORT_IOC_GET_BMI_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(42), ioc_fm_port_bmi_stats_t) -+ -+ -+/** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */ -+/** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */ -+ -+/** @} */ /* end of lnx_ioctl_FM_PORT_grp group */ -+/** @} */ /* end of lnx_ioctl_FM_grp group */ -+#endif /* __FM_PORT_IOCTLS_H */ ---- /dev/null -+++ b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h -@@ -0,0 +1,208 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ @File fm_test_ioctls.h -+ -+ @Description FM Char device ioctls -+*//***************************************************************************/ -+#ifndef __FM_TEST_IOCTLS_H -+#define __FM_TEST_IOCTLS_H -+ -+#include "ioctls.h" -+ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FMT_grp Frame Manager Test Linux IOCTL API -+ -+ @Description FM-Test Linux ioctls definitions and enums -+ -+ @{ -+*//***************************************************************************/ -+ -+#define IOC_FMT_MAX_NUM_OF_PORTS 26 -+ -+/**************************************************************************//** -+ @Collection TEST Parameters -+*//***************************************************************************/ -+/**************************************************************************//** -+ @Description: Name of the FM-Test chardev -+*//***************************************************************************/ -+#define DEV_FM_TEST_NAME "fm-test-port" -+ -+#define DEV_FM_TEST_PORTS_MINOR_BASE 0 -+#define DEV_FM_TEST_MAX_MINORS (DEV_FM_TEST_PORTS_MINOR_BASE + IOC_FMT_MAX_NUM_OF_PORTS) -+ -+#define FMT_PORT_IOC_NUM(n) n -+/* @} */ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FMT_lib_grp FM-Test library -+ -+ @Description TODO -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description TODO -+*//***************************************************************************/ -+typedef uint8_t ioc_fmt_xxx_t; -+ -+#define FM_PRS_MAX 32 -+#define FM_TIME_STAMP_MAX 8 -+ -+/**************************************************************************//** -+ @Description FM Port buffer content description -+*//***************************************************************************/ -+typedef struct ioc_fmt_buff_context_t { -+ void *p_user_priv; -+ uint8_t fm_prs_res[FM_PRS_MAX]; -+ uint8_t fm_time_stamp[FM_TIME_STAMP_MAX]; -+} ioc_fmt_buff_context_t; -+ -+#if defined(__KERNEL__) && defined(CONFIG_COMPAT) -+typedef struct ioc_fmt_compat_buff_context_t { -+ compat_uptr_t p_user_priv; -+ uint8_t fm_prs_res[FM_PRS_MAX]; -+ uint8_t fm_time_stamp[FM_TIME_STAMP_MAX]; -+} ioc_fmt_compat_buff_context_t; -+#endif -+ -+/**************************************************************************//** -+ @Description Buffer descriptor -+*//***************************************************************************/ -+typedef struct ioc_fmt_buff_desc_t { -+ uint32_t qid; -+ void *p_data; -+ uint32_t size; -+ uint32_t status; -+ ioc_fmt_buff_context_t buff_context; -+} ioc_fmt_buff_desc_t; -+ -+#if defined(__KERNEL__) && defined(CONFIG_COMPAT) -+typedef struct ioc_fmt_compat_buff_desc_t { -+ uint32_t qid; -+ compat_uptr_t p_data; -+ uint32_t size; -+ uint32_t status; -+ ioc_fmt_compat_buff_context_t buff_context; -+} ioc_fmt_compat_buff_desc_t; -+#endif -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FMT_runtime_control_grp FM-Test Runtime Control Unit -+ -+ @Description TODO -+ @{ -+*//***************************************************************************/ -+ -+/** @} */ /* end of lnx_ioctl_FMT_runtime_control_grp group */ -+ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_FMTP_lib_grp FM-Port-Test library -+ -+ @Description TODO -+ -+ @{ -+*//***************************************************************************/ -+ -+/**************************************************************************//** -+ @Description FM-Test FM port type -+*//***************************************************************************/ -+typedef enum ioc_fmt_port_type { -+ e_IOC_FMT_PORT_T_RXTX, /**< Standard port */ -+ e_IOC_FMT_PORT_T_OP, /**< Offline-parsing port */ -+} ioc_fmt_port_type; -+ -+/**************************************************************************//** -+ @Description TODO -+*//***************************************************************************/ -+typedef struct ioc_fmt_port_param_t { -+ uint8_t fm_id; -+ ioc_fmt_port_type fm_port_type; -+ uint8_t fm_port_id; -+ uint32_t num_tx_queues; -+} ioc_fmt_port_param_t; -+ -+ -+/**************************************************************************//** -+ @Function FMT_PORT_IOC_INIT -+ -+ @Description TODO -+ -+ @Param[in] ioc_fmt_port_param_t TODO -+ -+ @Cautions Allowed only after the FM equivalent port is already initialized. -+*//***************************************************************************/ -+#define FMT_PORT_IOC_INIT _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(0), ioc_fmt_port_param_t) -+ -+/**************************************************************************//** -+ @Function FMT_PORT_IOC_SET_DIAG_MODE -+ -+ @Description TODO -+ -+ @Param[in] ioc_diag_mode TODO -+ -+ @Cautions Allowed only following FMT_PORT_IOC_INIT(). -+*//***************************************************************************/ -+#define FMT_PORT_IOC_SET_DIAG_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(1), ioc_diag_mode) -+ -+/**************************************************************************//** -+ @Function FMT_PORT_IOC_SET_IP_HEADER_MANIP -+ -+ @Description Set IP header manipulations for this port. -+ -+ @Param[in] int 1 to enable; 0 to disable -+ -+ @Cautions Allowed only following FMT_PORT_IOC_INIT(). -+*//***************************************************************************/ -+#define FMT_PORT_IOC_SET_IP_HEADER_MANIP _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(2), int) -+ -+/**************************************************************************//** -+ @Function FMT_PORT_IOC_SET_DPAECHO_MODE -+ -+ @Description Set DPA in echo mode - all frame are sent back. -+ -+ @Param[in] int 1 to enable; 0 to disable -+ -+ @Cautions Allowed only following FMT_PORT_IOC_INIT(). -+*//***************************************************************************/ -+#define FMT_PORT_IOC_SET_DPAECHO_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(3), int) -+ -+/** @} */ /* end of lnx_ioctl_FMTP_lib_grp group */ -+/** @} */ /* end of lnx_ioctl_FMT_lib_grp group */ -+/** @} */ /* end of lnx_ioctl_FMT_grp */ -+ -+ -+#endif /* __FM_TEST_IOCTLS_H */ ---- /dev/null -+++ b/include/uapi/linux/fmd/integrations/Kbuild -@@ -0,0 +1 @@ -+header-y += integration_ioctls.h ---- /dev/null -+++ b/include/uapi/linux/fmd/integrations/integration_ioctls.h -@@ -0,0 +1,56 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ @File integration_ioctls.h -+ -+ @Description External header file for Integration unit routines. -+*//***************************************************************************/ -+ -+#ifndef __INTG_IOCTLS_H -+#define __INTG_IOCTLS_H -+ -+ -+#define FM_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+1) -+#define FMT_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+3) -+ -+/*#define FM_IOCTL_DBG*/ -+ -+#if defined(FM_IOCTL_DBG) -+ #define _fm_ioctl_dbg(format, arg...) \ -+ printk("fm ioctl [%s:%u](cpu:%u) - " format, \ -+ __func__, __LINE__, smp_processor_id(), ##arg) -+#else -+# define _fm_ioctl_dbg(arg...) -+#endif -+ -+#endif /* __INTG_IOCTLS_H */ ---- /dev/null -+++ b/include/uapi/linux/fmd/ioctls.h -@@ -0,0 +1,96 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/**************************************************************************//** -+ @File ioctls.h -+ -+ @Description Structures and definitions for Command Relay Ioctls -+*//***************************************************************************/ -+ -+#ifndef __IOCTLS_H__ -+#define __IOCTLS_H__ -+ -+#include -+ -+#include "integration_ioctls.h" -+ -+ -+/**************************************************************************//** -+ @Group lnx_ioctl_ncsw_grp NetCommSw Linux User-Space (IOCTL) API -+ @{ -+*//***************************************************************************/ -+ -+#define NCSW_IOC_TYPE_BASE 0xe0 /**< defines the IOCTL type for all -+ the NCSW Linux module commands */ -+ -+ -+/**************************************************************************//** -+ @Description IOCTL Memory allocation types. -+*//***************************************************************************/ -+typedef enum ioc_mem_type { -+ e_IOC_MEM_INVALID = 0x00000000, /**< Invalid memory type (error) */ -+ e_IOC_MEM_CACHABLE_SYS = 0x00000001, /**< Primary DDR, cacheable segment */ -+ e_IOC_MEM_NOCACHE_SYS = 0x00000004, /**< Primary DDR, non-cacheable segment */ -+ e_IOC_MEM_SECONDARY = 0x00000002, /**< Either secondary DDR or SDRAM */ -+ e_IOC_MEM_PRAM = 0x00000008 /**< Multi-user RAM identifier */ -+} ioc_mem_type; -+ -+/**************************************************************************//** -+ @Description Enumeration (bit flags) of communication modes (Transmit, -+ receive or both). -+*//***************************************************************************/ -+typedef enum ioc_comm_mode { -+ e_IOC_COMM_MODE_NONE = 0 /**< No transmit/receive communication */ -+ , e_IOC_COMM_MODE_RX = 1 /**< Only receive communication */ -+ , e_IOC_COMM_MODE_TX = 2 /**< Only transmit communication */ -+ , e_IOC_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */ -+} ioc_comm_mode; -+ -+/**************************************************************************//** -+ @Description General Diagnostic Mode -+*//***************************************************************************/ -+typedef enum ioc_diag_mode -+{ -+ e_IOC_DIAG_MODE_NONE = 0, -+ e_IOC_DIAG_MODE_CTRL_LOOPBACK, /**< loopback in the controller; E.g. MAC, TDM, etc. */ -+ e_IOC_DIAG_MODE_CHIP_LOOPBACK, /**< loopback in the chip but not in controller; -+ E.g. IO-pins, SerDes, etc. */ -+ e_IOC_DIAG_MODE_PHY_LOOPBACK, /**< loopback in the external PHY */ -+ e_IOC_DIAG_MODE_LINE_LOOPBACK, /**< loopback in the external line */ -+ e_IOC_DIAG_MODE_CTRL_ECHO, /**< */ -+ e_IOC_DIAG_MODE_PHY_ECHO /**< */ -+} ioc_diag_mode; -+ -+/** @} */ /* end of lnx_ioctl_ncsw_grp */ -+ -+ -+#endif /* __IOCTLS_H__ */ ---- /dev/null -+++ b/include/uapi/linux/fmd/net_ioctls.h -@@ -0,0 +1,430 @@ -+/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+ -+/**************************************************************************//** -+ @File net_ioctls.h -+ -+ @Description This file contains common and general netcomm headers definitions. -+*//***************************************************************************/ -+#ifndef __NET_IOCTLS_H -+#define __NET_IOCTLS_H -+ -+#include "ioctls.h" -+ -+ -+typedef uint8_t ioc_header_field_ppp_t; -+ -+#define IOC_NET_HEADER_FIELD_PPP_PID (1) -+#define IOC_NET_HEADER_FIELD_PPP_COMPRESSED (IOC_NET_HEADER_FIELD_PPP_PID << 1) -+#define IOC_NET_HEADER_FIELD_PPP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPP_PID << 2) - 1) -+ -+ -+typedef uint8_t ioc_header_field_pppoe_t; -+ -+#define IOC_NET_HEADER_FIELD_PPPoE_VER (1) -+#define IOC_NET_HEADER_FIELD_PPPoE_TYPE (IOC_NET_HEADER_FIELD_PPPoE_VER << 1) -+#define IOC_NET_HEADER_FIELD_PPPoE_CODE (IOC_NET_HEADER_FIELD_PPPoE_VER << 2) -+#define IOC_NET_HEADER_FIELD_PPPoE_SID (IOC_NET_HEADER_FIELD_PPPoE_VER << 3) -+#define IOC_NET_HEADER_FIELD_PPPoE_LEN (IOC_NET_HEADER_FIELD_PPPoE_VER << 4) -+#define IOC_NET_HEADER_FIELD_PPPoE_SESSION (IOC_NET_HEADER_FIELD_PPPoE_VER << 5) -+#define IOC_NET_HEADER_FIELD_PPPoE_PID (IOC_NET_HEADER_FIELD_PPPoE_VER << 6) -+#define IOC_NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPoE_VER << 7) - 1) -+ -+#define IOC_NET_HEADER_FIELD_PPPMUX_PID (1) -+#define IOC_NET_HEADER_FIELD_PPPMUX_CKSUM (IOC_NET_HEADER_FIELD_PPPMUX_PID << 1) -+#define IOC_NET_HEADER_FIELD_PPPMUX_COMPRESSED (IOC_NET_HEADER_FIELD_PPPMUX_PID << 2) -+#define IOC_NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_PID << 3) - 1) -+ -+#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1) -+#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1) -+#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2) -+#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3) -+#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4) -+#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1) -+ -+ -+typedef uint8_t ioc_header_field_eth_t; -+ -+#define IOC_NET_HEADER_FIELD_ETH_DA (1) -+#define IOC_NET_HEADER_FIELD_ETH_SA (IOC_NET_HEADER_FIELD_ETH_DA << 1) -+#define IOC_NET_HEADER_FIELD_ETH_LENGTH (IOC_NET_HEADER_FIELD_ETH_DA << 2) -+#define IOC_NET_HEADER_FIELD_ETH_TYPE (IOC_NET_HEADER_FIELD_ETH_DA << 3) -+#define IOC_NET_HEADER_FIELD_ETH_FINAL_CKSUM (IOC_NET_HEADER_FIELD_ETH_DA << 4) -+#define IOC_NET_HEADER_FIELD_ETH_PADDING (IOC_NET_HEADER_FIELD_ETH_DA << 5) -+#define IOC_NET_HEADER_FIELD_ETH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ETH_DA << 6) - 1) -+ -+#define IOC_NET_HEADER_FIELD_ETH_ADDR_SIZE 6 -+ -+typedef uint16_t ioc_header_field_ip_t; -+ -+#define IOC_NET_HEADER_FIELD_IP_VER (1) -+#define IOC_NET_HEADER_FIELD_IP_DSCP (IOC_NET_HEADER_FIELD_IP_VER << 2) -+#define IOC_NET_HEADER_FIELD_IP_ECN (IOC_NET_HEADER_FIELD_IP_VER << 3) -+#define IOC_NET_HEADER_FIELD_IP_PROTO (IOC_NET_HEADER_FIELD_IP_VER << 4) -+ -+#define IOC_NET_HEADER_FIELD_IP_PROTO_SIZE 1 -+ -+typedef uint16_t ioc_header_field_ipv4_t; -+ -+#define IOC_NET_HEADER_FIELD_IPv4_VER (1) -+#define IOC_NET_HEADER_FIELD_IPv4_HDR_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 1) -+#define IOC_NET_HEADER_FIELD_IPv4_TOS (IOC_NET_HEADER_FIELD_IPv4_VER << 2) -+#define IOC_NET_HEADER_FIELD_IPv4_TOTAL_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 3) -+#define IOC_NET_HEADER_FIELD_IPv4_ID (IOC_NET_HEADER_FIELD_IPv4_VER << 4) -+#define IOC_NET_HEADER_FIELD_IPv4_FLAG_D (IOC_NET_HEADER_FIELD_IPv4_VER << 5) -+#define IOC_NET_HEADER_FIELD_IPv4_FLAG_M (IOC_NET_HEADER_FIELD_IPv4_VER << 6) -+#define IOC_NET_HEADER_FIELD_IPv4_OFFSET (IOC_NET_HEADER_FIELD_IPv4_VER << 7) -+#define IOC_NET_HEADER_FIELD_IPv4_TTL (IOC_NET_HEADER_FIELD_IPv4_VER << 8) -+#define IOC_NET_HEADER_FIELD_IPv4_PROTO (IOC_NET_HEADER_FIELD_IPv4_VER << 9) -+#define IOC_NET_HEADER_FIELD_IPv4_CKSUM (IOC_NET_HEADER_FIELD_IPv4_VER << 10) -+#define IOC_NET_HEADER_FIELD_IPv4_SRC_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 11) -+#define IOC_NET_HEADER_FIELD_IPv4_DST_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 12) -+#define IOC_NET_HEADER_FIELD_IPv4_OPTS (IOC_NET_HEADER_FIELD_IPv4_VER << 13) -+#define IOC_NET_HEADER_FIELD_IPv4_OPTS_COUNT (IOC_NET_HEADER_FIELD_IPv4_VER << 14) -+#define IOC_NET_HEADER_FIELD_IPv4_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv4_VER << 15) - 1) -+ -+#define IOC_NET_HEADER_FIELD_IPv4_ADDR_SIZE 4 -+#define IOC_NET_HEADER_FIELD_IPv4_PROTO_SIZE 1 -+ -+ -+typedef uint8_t ioc_header_field_ipv6_t; -+ -+#define IOC_NET_HEADER_FIELD_IPv6_VER (1) -+#define IOC_NET_HEADER_FIELD_IPv6_TC (IOC_NET_HEADER_FIELD_IPv6_VER << 1) -+#define IOC_NET_HEADER_FIELD_IPv6_SRC_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 2) -+#define IOC_NET_HEADER_FIELD_IPv6_DST_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 3) -+#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR (IOC_NET_HEADER_FIELD_IPv6_VER << 4) -+#define IOC_NET_HEADER_FIELD_IPv6_FL (IOC_NET_HEADER_FIELD_IPv6_VER << 5) -+#define IOC_NET_HEADER_FIELD_IPv6_HOP_LIMIT (IOC_NET_HEADER_FIELD_IPv6_VER << 6) -+#define IOC_NET_HEADER_FIELD_IPv6_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv6_VER << 7) - 1) -+ -+#define IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE 16 -+#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1 -+ -+#define IOC_NET_HEADER_FIELD_ICMP_TYPE (1) -+#define IOC_NET_HEADER_FIELD_ICMP_CODE (IOC_NET_HEADER_FIELD_ICMP_TYPE << 1) -+#define IOC_NET_HEADER_FIELD_ICMP_CKSUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 2) -+#define IOC_NET_HEADER_FIELD_ICMP_ID (IOC_NET_HEADER_FIELD_ICMP_TYPE << 3) -+#define IOC_NET_HEADER_FIELD_ICMP_SQ_NUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 4) -+#define IOC_NET_HEADER_FIELD_ICMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ICMP_TYPE << 5) - 1) -+ -+#define IOC_NET_HEADER_FIELD_ICMP_CODE_SIZE 1 -+#define IOC_NET_HEADER_FIELD_ICMP_TYPE_SIZE 1 -+ -+#define IOC_NET_HEADER_FIELD_IGMP_VERSION (1) -+#define IOC_NET_HEADER_FIELD_IGMP_TYPE (IOC_NET_HEADER_FIELD_IGMP_VERSION << 1) -+#define IOC_NET_HEADER_FIELD_IGMP_CKSUM (IOC_NET_HEADER_FIELD_IGMP_VERSION << 2) -+#define IOC_NET_HEADER_FIELD_IGMP_DATA (IOC_NET_HEADER_FIELD_IGMP_VERSION << 3) -+#define IOC_NET_HEADER_FIELD_IGMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IGMP_VERSION << 4) - 1) -+ -+ -+typedef uint16_t ioc_header_field_tcp_t; -+ -+#define IOC_NET_HEADER_FIELD_TCP_PORT_SRC (1) -+#define IOC_NET_HEADER_FIELD_TCP_PORT_DST (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 1) -+#define IOC_NET_HEADER_FIELD_TCP_SEQ (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 2) -+#define IOC_NET_HEADER_FIELD_TCP_ACK (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 3) -+#define IOC_NET_HEADER_FIELD_TCP_OFFSET (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 4) -+#define IOC_NET_HEADER_FIELD_TCP_FLAGS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 5) -+#define IOC_NET_HEADER_FIELD_TCP_WINDOW (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 6) -+#define IOC_NET_HEADER_FIELD_TCP_CKSUM (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 7) -+#define IOC_NET_HEADER_FIELD_TCP_URGPTR (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 8) -+#define IOC_NET_HEADER_FIELD_TCP_OPTS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 9) -+#define IOC_NET_HEADER_FIELD_TCP_OPTS_COUNT (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 10) -+#define IOC_NET_HEADER_FIELD_TCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1) -+ -+#define IOC_NET_HEADER_FIELD_TCP_PORT_SIZE 2 -+ -+ -+typedef uint8_t ioc_header_field_sctp_t; -+ -+#define IOC_NET_HEADER_FIELD_SCTP_PORT_SRC (1) -+#define IOC_NET_HEADER_FIELD_SCTP_PORT_DST (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 1) -+#define IOC_NET_HEADER_FIELD_SCTP_VER_TAG (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 2) -+#define IOC_NET_HEADER_FIELD_SCTP_CKSUM (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 3) -+#define IOC_NET_HEADER_FIELD_SCTP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1) -+ -+#define IOC_NET_HEADER_FIELD_SCTP_PORT_SIZE 2 -+ -+typedef uint8_t ioc_header_field_dccp_t; -+ -+#define IOC_NET_HEADER_FIELD_DCCP_PORT_SRC (1) -+#define IOC_NET_HEADER_FIELD_DCCP_PORT_DST (IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 1) -+#define IOC_NET_HEADER_FIELD_DCCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1) -+ -+#define IOC_NET_HEADER_FIELD_DCCP_PORT_SIZE 2 -+ -+ -+typedef uint8_t ioc_header_field_udp_t; -+ -+#define IOC_NET_HEADER_FIELD_UDP_PORT_SRC (1) -+#define IOC_NET_HEADER_FIELD_UDP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 1) -+#define IOC_NET_HEADER_FIELD_UDP_LEN (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 2) -+#define IOC_NET_HEADER_FIELD_UDP_CKSUM (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 3) -+#define IOC_NET_HEADER_FIELD_UDP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1) -+ -+#define IOC_NET_HEADER_FIELD_UDP_PORT_SIZE 2 -+ -+typedef uint8_t ioc_header_field_udp_lite_t; -+ -+#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1) -+#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_DST (IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1) -+#define IOC_NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1) -+ -+#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2 -+ -+typedef uint8_t ioc_header_field_udp_encap_esp_t; -+ -+#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1) -+#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1) -+#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2) -+#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3) -+#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4) -+#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5) -+#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1) -+ -+#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2 -+#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4 -+ -+#define IOC_NET_HEADER_FIELD_IPHC_CID (1) -+#define IOC_NET_HEADER_FIELD_IPHC_CID_TYPE (IOC_NET_HEADER_FIELD_IPHC_CID << 1) -+#define IOC_NET_HEADER_FIELD_IPHC_HCINDEX (IOC_NET_HEADER_FIELD_IPHC_CID << 2) -+#define IOC_NET_HEADER_FIELD_IPHC_GEN (IOC_NET_HEADER_FIELD_IPHC_CID << 3) -+#define IOC_NET_HEADER_FIELD_IPHC_D_BIT (IOC_NET_HEADER_FIELD_IPHC_CID << 4) -+#define IOC_NET_HEADER_FIELD_IPHC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPHC_CID << 5) - 1) -+ -+#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1) -+#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1) -+#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2) -+#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3) -+#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4) -+#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5) -+#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6) -+#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7) -+#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8) -+#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9) -+#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1) -+ -+#define IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1) -+#define IOC_NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1) -+#define IOC_NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2) -+#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3) -+#define IOC_NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4) -+#define IOC_NET_HEADER_FIELD_L2TPv2_VERSION (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5) -+#define IOC_NET_HEADER_FIELD_L2TPv2_LEN (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6) -+#define IOC_NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7) -+#define IOC_NET_HEADER_FIELD_L2TPv2_SESSION_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8) -+#define IOC_NET_HEADER_FIELD_L2TPv2_NS (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9) -+#define IOC_NET_HEADER_FIELD_L2TPv2_NR (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10) -+#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11) -+#define IOC_NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12) -+#define IOC_NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1) -+ -+#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1) -+#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1) -+#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2) -+#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3) -+#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4) -+#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5) -+#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SENT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6) -+#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_RECV (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7) -+#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8) -+#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1) -+ -+#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1) -+#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1) -+#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ID (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2) -+#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3) -+#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1) -+ -+ -+typedef uint8_t ioc_header_field_vlan_t; -+ -+#define IOC_NET_HEADER_FIELD_VLAN_VPRI (1) -+#define IOC_NET_HEADER_FIELD_VLAN_CFI (IOC_NET_HEADER_FIELD_VLAN_VPRI << 1) -+#define IOC_NET_HEADER_FIELD_VLAN_VID (IOC_NET_HEADER_FIELD_VLAN_VPRI << 2) -+#define IOC_NET_HEADER_FIELD_VLAN_LENGTH (IOC_NET_HEADER_FIELD_VLAN_VPRI << 3) -+#define IOC_NET_HEADER_FIELD_VLAN_TYPE (IOC_NET_HEADER_FIELD_VLAN_VPRI << 4) -+#define IOC_NET_HEADER_FIELD_VLAN_ALL_FIELDS ((IOC_NET_HEADER_FIELD_VLAN_VPRI << 5) - 1) -+ -+#define IOC_NET_HEADER_FIELD_VLAN_TCI (IOC_NET_HEADER_FIELD_VLAN_VPRI | \ -+ IOC_NET_HEADER_FIELD_VLAN_CFI | \ -+ IOC_NET_HEADER_FIELD_VLAN_VID) -+ -+ -+typedef uint8_t ioc_header_field_llc_t; -+ -+#define IOC_NET_HEADER_FIELD_LLC_DSAP (1) -+#define IOC_NET_HEADER_FIELD_LLC_SSAP (IOC_NET_HEADER_FIELD_LLC_DSAP << 1) -+#define IOC_NET_HEADER_FIELD_LLC_CTRL (IOC_NET_HEADER_FIELD_LLC_DSAP << 2) -+#define IOC_NET_HEADER_FIELD_LLC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_DSAP << 3) - 1) -+ -+#define IOC_NET_HEADER_FIELD_NLPID_NLPID (1) -+#define IOC_NET_HEADER_FIELD_NLPID_ALL_FIELDS ((IOC_NET_HEADER_FIELD_NLPID_NLPID << 1) - 1) -+ -+ -+typedef uint8_t ioc_header_field_snap_t; -+ -+#define IOC_NET_HEADER_FIELD_SNAP_OUI (1) -+#define IOC_NET_HEADER_FIELD_SNAP_PID (IOC_NET_HEADER_FIELD_SNAP_OUI << 1) -+#define IOC_NET_HEADER_FIELD_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SNAP_OUI << 2) - 1) -+ -+ -+typedef uint8_t ioc_header_field_llc_snap_t; -+ -+#define IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE (1) -+#define IOC_NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1) -+ -+#define IOC_NET_HEADER_FIELD_ARP_HTYPE (1) -+#define IOC_NET_HEADER_FIELD_ARP_PTYPE (IOC_NET_HEADER_FIELD_ARP_HTYPE << 1) -+#define IOC_NET_HEADER_FIELD_ARP_HLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 2) -+#define IOC_NET_HEADER_FIELD_ARP_PLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 3) -+#define IOC_NET_HEADER_FIELD_ARP_OPER (IOC_NET_HEADER_FIELD_ARP_HTYPE << 4) -+#define IOC_NET_HEADER_FIELD_ARP_SHA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 5) -+#define IOC_NET_HEADER_FIELD_ARP_SPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 6) -+#define IOC_NET_HEADER_FIELD_ARP_THA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 7) -+#define IOC_NET_HEADER_FIELD_ARP_TPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 8) -+#define IOC_NET_HEADER_FIELD_ARP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ARP_HTYPE << 9) - 1) -+ -+#define IOC_NET_HEADER_FIELD_RFC2684_LLC (1) -+#define IOC_NET_HEADER_FIELD_RFC2684_NLPID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 1) -+#define IOC_NET_HEADER_FIELD_RFC2684_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 2) -+#define IOC_NET_HEADER_FIELD_RFC2684_PID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 3) -+#define IOC_NET_HEADER_FIELD_RFC2684_VPN_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 4) -+#define IOC_NET_HEADER_FIELD_RFC2684_VPN_IDX (IOC_NET_HEADER_FIELD_RFC2684_LLC << 5) -+#define IOC_NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((IOC_NET_HEADER_FIELD_RFC2684_LLC << 6) - 1) -+ -+#define IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1) -+#define IOC_NET_HEADER_FIELD_USER_DEFINED_PCDID (IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1) -+#define IOC_NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1) -+ -+#define IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER (1) -+#define IOC_NET_HEADER_FIELD_PAYLOAD_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 1) -+#define IOC_NET_HEADER_FIELD_MAX_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 2) -+#define IOC_NET_HEADER_FIELD_MIN_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 3) -+#define IOC_NET_HEADER_FIELD_PAYLOAD_TYPE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 4) -+#define IOC_NET_HEADER_FIELD_FRAME_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 5) -+#define IOC_NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1) -+ -+ -+typedef uint8_t ioc_header_field_gre_t; -+ -+#define IOC_NET_HEADER_FIELD_GRE_TYPE (1) -+#define IOC_NET_HEADER_FIELD_GRE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_GRE_TYPE << 1) - 1) -+ -+ -+typedef uint8_t ioc_header_field_minencap_t; -+ -+#define IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP (1) -+#define IOC_NET_HEADER_FIELD_MINENCAP_DST_IP (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 1) -+#define IOC_NET_HEADER_FIELD_MINENCAP_TYPE (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 2) -+#define IOC_NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1) -+ -+ -+typedef uint8_t ioc_header_field_ipsec_ah_t; -+ -+#define IOC_NET_HEADER_FIELD_IPSEC_AH_SPI (1) -+#define IOC_NET_HEADER_FIELD_IPSEC_AH_NH (IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 1) -+#define IOC_NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1) -+ -+ -+typedef uint8_t ioc_header_field_ipsec_esp_t; -+ -+#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI (1) -+#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 1) -+#define IOC_NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1) -+ -+#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4 -+ -+ -+typedef uint8_t ioc_header_field_mpls_t; -+ -+#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK (1) -+#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1) -+ -+ -+typedef uint8_t ioc_header_field_macsec_t; -+ -+#define IOC_NET_HEADER_FIELD_MACSEC_SECTAG (1) -+#define IOC_NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1) -+ -+ -+typedef enum { -+ e_IOC_NET_HEADER_TYPE_NONE = 0, -+ e_IOC_NET_HEADER_TYPE_PAYLOAD, -+ e_IOC_NET_HEADER_TYPE_ETH, -+ e_IOC_NET_HEADER_TYPE_VLAN, -+ e_IOC_NET_HEADER_TYPE_IPv4, -+ e_IOC_NET_HEADER_TYPE_IPv6, -+ e_IOC_NET_HEADER_TYPE_IP, -+ e_IOC_NET_HEADER_TYPE_TCP, -+ e_IOC_NET_HEADER_TYPE_UDP, -+ e_IOC_NET_HEADER_TYPE_UDP_LITE, -+ e_IOC_NET_HEADER_TYPE_IPHC, -+ e_IOC_NET_HEADER_TYPE_SCTP, -+ e_IOC_NET_HEADER_TYPE_SCTP_CHUNK_DATA, -+ e_IOC_NET_HEADER_TYPE_PPPoE, -+ e_IOC_NET_HEADER_TYPE_PPP, -+ e_IOC_NET_HEADER_TYPE_PPPMUX, -+ e_IOC_NET_HEADER_TYPE_PPPMUX_SUBFRAME, -+ e_IOC_NET_HEADER_TYPE_L2TPv2, -+ e_IOC_NET_HEADER_TYPE_L2TPv3_CTRL, -+ e_IOC_NET_HEADER_TYPE_L2TPv3_SESS, -+ e_IOC_NET_HEADER_TYPE_LLC, -+ e_IOC_NET_HEADER_TYPE_LLC_SNAP, -+ e_IOC_NET_HEADER_TYPE_NLPID, -+ e_IOC_NET_HEADER_TYPE_SNAP, -+ e_IOC_NET_HEADER_TYPE_MPLS, -+ e_IOC_NET_HEADER_TYPE_IPSEC_AH, -+ e_IOC_NET_HEADER_TYPE_IPSEC_ESP, -+ e_IOC_NET_HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */ -+ e_IOC_NET_HEADER_TYPE_MACSEC, -+ e_IOC_NET_HEADER_TYPE_GRE, -+ e_IOC_NET_HEADER_TYPE_MINENCAP, -+ e_IOC_NET_HEADER_TYPE_DCCP, -+ e_IOC_NET_HEADER_TYPE_ICMP, -+ e_IOC_NET_HEADER_TYPE_IGMP, -+ e_IOC_NET_HEADER_TYPE_ARP, -+ e_IOC_NET_HEADER_TYPE_CAPWAP, -+ e_IOC_NET_HEADER_TYPE_CAPWAP_DTLS, -+ e_IOC_NET_HEADER_TYPE_RFC2684, -+ e_IOC_NET_HEADER_TYPE_USER_DEFINED_L2, -+ e_IOC_NET_HEADER_TYPE_USER_DEFINED_L3, -+ e_IOC_NET_HEADER_TYPE_USER_DEFINED_L4, -+ e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM1, -+ e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM2, -+ e_IOC_NET_MAX_HEADER_TYPE_COUNT -+} ioc_net_header_type; -+ -+ -+#endif /* __NET_IOCTLS_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0009-dpa-SDK-DPAA-1.x-Ethernet-driver.patch b/target/linux/layerscape/patches-5.4/701-net-0009-dpa-SDK-DPAA-1.x-Ethernet-driver.patch deleted file mode 100644 index 8dbcb0654f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0009-dpa-SDK-DPAA-1.x-Ethernet-driver.patch +++ /dev/null @@ -1,12966 +0,0 @@ -From f7f94b1e7e9c6044a23bab1c5e773f6259f2d3e0 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Wed, 10 May 2017 16:39:42 +0300 -Subject: [PATCH] dpa: SDK DPAA 1.x Ethernet driver - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_dpaa/Kconfig | 173 ++ - drivers/net/ethernet/freescale/sdk_dpaa/Makefile | 46 + - .../net/ethernet/freescale/sdk_dpaa/dpaa_1588.c | 580 ++++++ - .../net/ethernet/freescale/sdk_dpaa/dpaa_1588.h | 138 ++ - .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c | 180 ++ - .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h | 43 + - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 1210 ++++++++++++ - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 697 +++++++ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.c | 263 +++ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.h | 50 + - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 1991 ++++++++++++++++++++ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h | 236 +++ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 1812 ++++++++++++++++++ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 226 +++ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c | 381 ++++ - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 1113 +++++++++++ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c | 278 +++ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h | 144 ++ - .../net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c | 544 ++++++ - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c | 290 +++ - drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c | 909 +++++++++ - drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 489 +++++ - drivers/net/ethernet/freescale/sdk_dpaa/mac.h | 135 ++ - .../net/ethernet/freescale/sdk_dpaa/offline_port.c | 848 +++++++++ - .../net/ethernet/freescale/sdk_dpaa/offline_port.h | 59 + - 25 files changed, 12835 insertions(+) - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Makefile - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.h - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c - create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h - ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig -@@ -0,0 +1,173 @@ -+menuconfig FSL_SDK_DPAA_ETH -+ tristate "DPAA Ethernet" -+ depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && FSL_SDK_FMAN && !FSL_DPAA_ETH -+ select PHYLIB -+ help -+ Data Path Acceleration Architecture Ethernet driver, -+ supporting the Freescale QorIQ chips. -+ Depends on Freescale Buffer Manager and Queue Manager -+ driver and Frame Manager Driver. -+ -+if FSL_SDK_DPAA_ETH -+ -+config FSL_DPAA_HOOKS -+ bool "DPAA Ethernet driver hooks" -+ -+config FSL_DPAA_CEETM -+ bool "DPAA CEETM QoS" -+ depends on NET_SCHED -+ default n -+ help -+ Enable QoS offloading support through the CEETM hardware block. -+ -+config FSL_DPAA_OFFLINE_PORTS -+ bool "Offline Ports support" -+ depends on FSL_SDK_DPAA_ETH -+ default y -+ help -+ The Offline Parsing / Host Command ports (short: OH ports, of Offline ports) provide -+ most of the functionality of the regular, online ports, except they receive their -+ frames from a core or an accelerator on the SoC, via QMan frame queues, -+ rather than directly from the network. -+ Offline ports are configured via PCD (Parse-Classify-Distribute) schemes, just like -+ any online FMan port. They deliver the processed frames to frame queues, according -+ to the applied PCD configurations. -+ -+ Choosing this feature will not impact the functionality and/or performance of the system, -+ so it is safe to have it. -+ -+config FSL_DPAA_ADVANCED_DRIVERS -+ bool "Advanced DPAA Ethernet drivers" -+ depends on FSL_SDK_DPAA_ETH -+ default y -+ help -+ Besides the standard DPAA Ethernet driver the DPAA Proxy initialization driver -+ is needed to support advanced scenarios. Select this to also build the advanced -+ drivers. -+ -+config FSL_DPAA_ETH_JUMBO_FRAME -+ bool "Optimize for jumbo frames" -+ default n -+ help -+ Optimize the DPAA Ethernet driver throughput for large frames -+ termination traffic (e.g. 4K and above). -+ NOTE: This option can only be used if FSL_FM_MAX_FRAME_SIZE -+ is set to 9600 bytes. -+ Using this option in combination with small frames increases -+ significantly the driver's memory footprint and may even deplete -+ the system memory. Also, the skb truesize is altered and messages -+ from the stack that warn against this are bypassed. -+ This option is not available on LS1043. -+ -+config FSL_DPAA_TS -+ bool "Linux compliant timestamping" -+ depends on FSL_SDK_DPAA_ETH -+ default n -+ help -+ Enable Linux API compliant timestamping support. -+ -+config FSL_DPAA_1588 -+ bool "IEEE 1588-compliant timestamping" -+ depends on FSL_SDK_DPAA_ETH -+ select FSL_DPAA_TS -+ default n -+ help -+ Enable IEEE1588 support code. -+ -+config FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -+ bool "Use driver's Tx queue selection mechanism" -+ default y -+ depends on FSL_SDK_DPAA_ETH -+ help -+ The DPAA-Ethernet driver defines a ndo_select_queue() callback for optimal selection -+ of the egress FQ. That will override the XPS support for this netdevice. -+ If for whatever reason you want to be in control of the egress FQ-to-CPU selection and mapping, -+ or simply don't want to use the driver's ndo_select_queue() callback, then unselect this -+ and use the standard XPS support instead. -+ -+config FSL_DPAA_ETH_MAX_BUF_COUNT -+ int "Maximum nuber of buffers in private bpool" -+ depends on FSL_SDK_DPAA_ETH -+ range 64 2048 -+ default "128" -+ help -+ The maximum number of buffers to be by default allocated in the DPAA-Ethernet private port's -+ buffer pool. One needn't normally modify this, as it has probably been tuned for performance -+ already. This cannot be lower than DPAA_ETH_REFILL_THRESHOLD. -+ -+config FSL_DPAA_ETH_REFILL_THRESHOLD -+ int "Private bpool refill threshold" -+ depends on FSL_SDK_DPAA_ETH -+ range 32 FSL_DPAA_ETH_MAX_BUF_COUNT -+ default "80" -+ help -+ The DPAA-Ethernet driver will start replenishing buffer pools whose count -+ falls below this threshold. This must be related to DPAA_ETH_MAX_BUF_COUNT. One needn't normally -+ modify this value unless one has very specific performance reasons. -+ -+config FSL_DPAA_CS_THRESHOLD_1G -+ hex "Egress congestion threshold on 1G ports" -+ depends on FSL_SDK_DPAA_ETH -+ range 0x1000 0x10000000 -+ default "0x06000000" -+ help -+ The size in bytes of the egress Congestion State notification threshold on 1G ports. -+ The 1G dTSECs can quite easily be flooded by cores doing Tx in a tight loop -+ (e.g. by sending UDP datagrams at "while(1) speed"), -+ and the larger the frame size, the more acute the problem. -+ So we have to find a balance between these factors: -+ - avoiding the device staying congested for a prolonged time (risking -+ the netdev watchdog to fire - see also the tx_timeout module param); -+ - affecting performance of protocols such as TCP, which otherwise -+ behave well under the congestion notification mechanism; -+ - preventing the Tx cores from tightly-looping (as if the congestion -+ threshold was too low to be effective); -+ - running out of memory if the CS threshold is set too high. -+ -+config FSL_DPAA_CS_THRESHOLD_10G -+ hex "Egress congestion threshold on 10G ports" -+ depends on FSL_SDK_DPAA_ETH -+ range 0x1000 0x20000000 -+ default "0x10000000" -+ help -+ The size in bytes of the egress Congestion State notification threshold on 10G ports. -+ -+config FSL_DPAA_INGRESS_CS_THRESHOLD -+ hex "Ingress congestion threshold on FMan ports" -+ depends on FSL_SDK_DPAA_ETH -+ default "0x10000000" -+ help -+ The size in bytes of the ingress tail-drop threshold on FMan ports. -+ Traffic piling up above this value will be rejected by QMan and discarded by FMan. -+ -+config FSL_DPAA_ETH_DEBUGFS -+ bool "DPAA Ethernet debugfs interface" -+ depends on DEBUG_FS && FSL_SDK_DPAA_ETH -+ default y -+ help -+ This option compiles debugfs code for the DPAA Ethernet driver. -+ -+config FSL_DPAA_ETH_DEBUG -+ bool "DPAA Ethernet Debug Support" -+ depends on FSL_SDK_DPAA_ETH -+ default n -+ help -+ This option compiles debug code for the DPAA Ethernet driver. -+ -+config FSL_DPAA_DBG_LOOP -+ bool "DPAA Ethernet Debug loopback" -+ depends on FSL_DPAA_ETH_DEBUGFS && FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -+ default n -+ help -+ This option allows to divert all received traffic on a certain interface A towards a -+ selected interface B. This option is used to benchmark the HW + Ethernet driver in -+ isolation from the Linux networking stack. The loops are controlled by debugfs entries, -+ one for each interface. By default all loops are disabled (target value is -1). I.e. to -+ change the loop setting for interface 4 and divert all received traffic to interface 5 -+ write Tx interface number in the receive interface debugfs file: -+ # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop -+ 4->-1 -+ # echo 5 > /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop -+ # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop -+ 4->5 -+endif # FSL_SDK_DPAA_ETH ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile -@@ -0,0 +1,46 @@ -+# -+# Makefile for the Freescale Ethernet controllers -+# -+ccflags-y += -DVERSION=\"\" -+# -+# Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ -+ccflags-y += -I$(NET_DPA) -+ -+obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_mac.o fsl_dpa.o -+obj-$(CONFIG_PTP_1588_CLOCK_DPAA) += dpaa_ptp.o -+ -+fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o -+ifeq ($(CONFIG_FSL_DPAA_DBG_LOOP),y) -+fsl_dpa-objs += dpaa_debugfs.o -+endif -+ifeq ($(CONFIG_FSL_DPAA_1588),y) -+fsl_dpa-objs += dpaa_1588.o -+endif -+ifeq ($(CONFIG_FSL_DPAA_CEETM),y) -+ccflags-y += -Idrivers/net/ethernet/freescale/sdk_fman/src/wrapper -+fsl_dpa-objs += dpaa_eth_ceetm.o -+endif -+ -+fsl_mac-objs += mac.o mac-api.o -+ -+# Advanced drivers -+ifeq ($(CONFIG_FSL_DPAA_ADVANCED_DRIVERS),y) -+obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_advanced.o -+obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_proxy.o -+ -+fsl_advanced-objs += dpaa_eth_base.o -+# suport for multiple drivers per kernel module comes in kernel 3.14 -+# so we are forced to generate several modules for the advanced drivers -+fsl_proxy-objs += dpaa_eth_proxy.o -+ -+ifeq ($(CONFIG_FSL_DPAA_OFFLINE_PORTS),y) -+obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_oh.o -+ -+fsl_oh-objs += offline_port.o -+endif -+endif -+ -+# Needed by the tracing framework -+CFLAGS_dpaa_eth.o := -I$(src) ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c -@@ -0,0 +1,580 @@ -+/* Copyright (C) 2011 Freescale Semiconductor, Inc. -+ * Copyright (C) 2009 IXXAT Automation, GmbH -+ * -+ * DPAA Ethernet Driver -- IEEE 1588 interface functionality -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "dpaa_eth.h" -+#include "dpaa_eth_common.h" -+#include "dpaa_1588.h" -+#include "mac.h" -+ -+static int dpa_ptp_init_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size) -+{ -+ struct circ_buf *circ_buf = &ptp_buf->circ_buf; -+ -+ circ_buf->buf = vmalloc(sizeof(struct dpa_ptp_data) * size); -+ if (!circ_buf->buf) -+ return 1; -+ -+ circ_buf->head = 0; -+ circ_buf->tail = 0; -+ ptp_buf->size = size; -+ spin_lock_init(&ptp_buf->ptp_lock); -+ -+ return 0; -+} -+ -+static void dpa_ptp_reset_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size) -+{ -+ struct circ_buf *circ_buf = &ptp_buf->circ_buf; -+ -+ circ_buf->head = 0; -+ circ_buf->tail = 0; -+ ptp_buf->size = size; -+} -+ -+static int dpa_ptp_insert(struct dpa_ptp_circ_buf *ptp_buf, -+ struct dpa_ptp_data *data) -+{ -+ struct circ_buf *circ_buf = &ptp_buf->circ_buf; -+ int size = ptp_buf->size; -+ struct dpa_ptp_data *tmp; -+ unsigned long flags; -+ int head, tail; -+ -+ spin_lock_irqsave(&ptp_buf->ptp_lock, flags); -+ -+ head = circ_buf->head; -+ tail = circ_buf->tail; -+ -+ if (CIRC_SPACE(head, tail, size) <= 0) -+ circ_buf->tail = (tail + 1) & (size - 1); -+ -+ tmp = (struct dpa_ptp_data *)(circ_buf->buf) + head; -+ memcpy(tmp, data, sizeof(struct dpa_ptp_data)); -+ -+ circ_buf->head = (head + 1) & (size - 1); -+ -+ spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags); -+ -+ return 0; -+} -+ -+static int dpa_ptp_is_ident_match(struct dpa_ptp_ident *dst, -+ struct dpa_ptp_ident *src) -+{ -+ int ret; -+ -+ if ((dst->version != src->version) || (dst->msg_type != src->msg_type)) -+ return 0; -+ -+ if ((dst->netw_prot == src->netw_prot) -+ || src->netw_prot == DPA_PTP_PROT_DONTCARE) { -+ if (dst->seq_id != src->seq_id) -+ return 0; -+ -+ ret = memcmp(dst->snd_port_id, src->snd_port_id, -+ DPA_PTP_SOURCE_PORT_LENGTH); -+ if (ret) -+ return 0; -+ else -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static int dpa_ptp_find_and_remove(struct dpa_ptp_circ_buf *ptp_buf, -+ struct dpa_ptp_ident *ident, -+ struct dpa_ptp_time *ts) -+{ -+ struct circ_buf *circ_buf = &ptp_buf->circ_buf; -+ int size = ptp_buf->size; -+ int head, tail, idx; -+ unsigned long flags; -+ struct dpa_ptp_data *tmp, *tmp2; -+ struct dpa_ptp_ident *tmp_ident; -+ -+ spin_lock_irqsave(&ptp_buf->ptp_lock, flags); -+ -+ head = circ_buf->head; -+ tail = idx = circ_buf->tail; -+ -+ if (CIRC_CNT(head, tail, size) == 0) { -+ spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags); -+ return 1; -+ } -+ -+ while (idx != head) { -+ tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx; -+ tmp_ident = &tmp->ident; -+ if (dpa_ptp_is_ident_match(tmp_ident, ident)) -+ break; -+ idx = (idx + 1) & (size - 1); -+ } -+ -+ if (idx == head) { -+ spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags); -+ return 1; -+ } -+ -+ ts->sec = tmp->ts.sec; -+ ts->nsec = tmp->ts.nsec; -+ -+ if (idx != tail) { -+ if (CIRC_CNT(idx, tail, size) > TS_ACCUMULATION_THRESHOLD) { -+ tail = circ_buf->tail = -+ (idx - TS_ACCUMULATION_THRESHOLD) & (size - 1); -+ } -+ -+ while (CIRC_CNT(idx, tail, size) > 0) { -+ tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx; -+ idx = (idx - 1) & (size - 1); -+ tmp2 = (struct dpa_ptp_data *)(circ_buf->buf) + idx; -+ *tmp = *tmp2; -+ } -+ } -+ circ_buf->tail = (tail + 1) & (size - 1); -+ -+ spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags); -+ -+ return 0; -+} -+ -+/* Parse the PTP packets -+ * -+ * The PTP header can be found in an IPv4 packet, IPv6 patcket or in -+ * an IEEE802.3 ethernet frame. This function returns the position of -+ * the PTP packet or NULL if no PTP found -+ */ -+static u8 *dpa_ptp_parse_packet(struct sk_buff *skb, u16 *eth_type) -+{ -+ u8 *pos = skb->data + ETH_ALEN + ETH_ALEN; -+ u8 *ptp_loc = NULL; -+ u8 msg_type; -+ u32 access_len = ETH_ALEN + ETH_ALEN + DPA_ETYPE_LEN; -+ struct iphdr *iph; -+ struct udphdr *udph; -+ struct ipv6hdr *ipv6h; -+ -+ /* when we can receive S/G frames we need to check the data we want to -+ * access is in the linear skb buffer -+ */ -+ if (!pskb_may_pull(skb, access_len)) -+ return NULL; -+ -+ *eth_type = *((u16 *)pos); -+ -+ /* Check if inner tag is here */ -+ if (*eth_type == ETH_P_8021Q) { -+ access_len += DPA_VLAN_TAG_LEN; -+ -+ if (!pskb_may_pull(skb, access_len)) -+ return NULL; -+ -+ pos += DPA_VLAN_TAG_LEN; -+ *eth_type = *((u16 *)pos); -+ } -+ -+ pos += DPA_ETYPE_LEN; -+ -+ switch (*eth_type) { -+ /* Transport of PTP over Ethernet */ -+ case ETH_P_1588: -+ ptp_loc = pos; -+ -+ if (!pskb_may_pull(skb, access_len + PTP_OFFS_MSG_TYPE + 1)) -+ return NULL; -+ -+ msg_type = *((u8 *)(ptp_loc + PTP_OFFS_MSG_TYPE)) & 0xf; -+ if ((msg_type == PTP_MSGTYPE_SYNC) -+ || (msg_type == PTP_MSGTYPE_DELREQ) -+ || (msg_type == PTP_MSGTYPE_PDELREQ) -+ || (msg_type == PTP_MSGTYPE_PDELRESP)) -+ return ptp_loc; -+ break; -+ /* Transport of PTP over IPv4 */ -+ case ETH_P_IP: -+ iph = (struct iphdr *)pos; -+ access_len += sizeof(struct iphdr); -+ -+ if (!pskb_may_pull(skb, access_len)) -+ return NULL; -+ -+ if (ntohs(iph->protocol) != IPPROTO_UDP) -+ return NULL; -+ -+ access_len += iph->ihl * 4 - sizeof(struct iphdr) + -+ sizeof(struct udphdr); -+ -+ if (!pskb_may_pull(skb, access_len)) -+ return NULL; -+ -+ pos += iph->ihl * 4; -+ udph = (struct udphdr *)pos; -+ if (ntohs(udph->dest) != 319) -+ return NULL; -+ ptp_loc = pos + sizeof(struct udphdr); -+ break; -+ /* Transport of PTP over IPv6 */ -+ case ETH_P_IPV6: -+ ipv6h = (struct ipv6hdr *)pos; -+ -+ access_len += sizeof(struct ipv6hdr) + sizeof(struct udphdr); -+ -+ if (ntohs(ipv6h->nexthdr) != IPPROTO_UDP) -+ return NULL; -+ -+ pos += sizeof(struct ipv6hdr); -+ udph = (struct udphdr *)pos; -+ if (ntohs(udph->dest) != 319) -+ return NULL; -+ ptp_loc = pos + sizeof(struct udphdr); -+ break; -+ default: -+ break; -+ } -+ -+ return ptp_loc; -+} -+ -+static int dpa_ptp_store_stamp(const struct dpa_priv_s *priv, -+ struct sk_buff *skb, void *data, enum port_type rx_tx, -+ struct dpa_ptp_data *ptp_data) -+{ -+ u64 nsec; -+ u32 mod; -+ u8 *ptp_loc; -+ u16 eth_type; -+ -+ ptp_loc = dpa_ptp_parse_packet(skb, ð_type); -+ if (!ptp_loc) -+ return -EINVAL; -+ -+ switch (eth_type) { -+ case ETH_P_IP: -+ ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV4; -+ break; -+ case ETH_P_IPV6: -+ ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV6; -+ break; -+ case ETH_P_1588: -+ ptp_data->ident.netw_prot = DPA_PTP_PROT_802_3; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (!pskb_may_pull(skb, ptp_loc - skb->data + PTP_OFFS_SEQ_ID + 2)) -+ return -EINVAL; -+ -+ ptp_data->ident.version = *(ptp_loc + PTP_OFFS_VER_PTP) & 0xf; -+ ptp_data->ident.msg_type = *(ptp_loc + PTP_OFFS_MSG_TYPE) & 0xf; -+ ptp_data->ident.seq_id = *((u16 *)(ptp_loc + PTP_OFFS_SEQ_ID)); -+ memcpy(ptp_data->ident.snd_port_id, ptp_loc + PTP_OFFS_SRCPRTID, -+ DPA_PTP_SOURCE_PORT_LENGTH); -+ -+ nsec = dpa_get_timestamp_ns(priv, rx_tx, data); -+ mod = do_div(nsec, NANOSEC_PER_SECOND); -+ ptp_data->ts.sec = nsec; -+ ptp_data->ts.nsec = mod; -+ -+ return 0; -+} -+ -+void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv, -+ struct sk_buff *skb, void *data) -+{ -+ struct dpa_ptp_tsu *tsu = priv->tsu; -+ struct dpa_ptp_data ptp_tx_data; -+ -+ if (dpa_ptp_store_stamp(priv, skb, data, TX, &ptp_tx_data)) -+ return; -+ -+ dpa_ptp_insert(&tsu->tx_timestamps, &ptp_tx_data); -+} -+ -+void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv, -+ struct sk_buff *skb, void *data) -+{ -+ struct dpa_ptp_tsu *tsu = priv->tsu; -+ struct dpa_ptp_data ptp_rx_data; -+ -+ if (dpa_ptp_store_stamp(priv, skb, data, RX, &ptp_rx_data)) -+ return; -+ -+ dpa_ptp_insert(&tsu->rx_timestamps, &ptp_rx_data); -+} -+ -+static uint8_t dpa_get_tx_timestamp(struct dpa_ptp_tsu *ptp_tsu, -+ struct dpa_ptp_ident *ident, -+ struct dpa_ptp_time *ts) -+{ -+ struct dpa_ptp_tsu *tsu = ptp_tsu; -+ struct dpa_ptp_time tmp; -+ int flag; -+ -+ flag = dpa_ptp_find_and_remove(&tsu->tx_timestamps, ident, &tmp); -+ if (!flag) { -+ ts->sec = tmp.sec; -+ ts->nsec = tmp.nsec; -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static uint8_t dpa_get_rx_timestamp(struct dpa_ptp_tsu *ptp_tsu, -+ struct dpa_ptp_ident *ident, -+ struct dpa_ptp_time *ts) -+{ -+ struct dpa_ptp_tsu *tsu = ptp_tsu; -+ struct dpa_ptp_time tmp; -+ int flag; -+ -+ flag = dpa_ptp_find_and_remove(&tsu->rx_timestamps, ident, &tmp); -+ if (!flag) { -+ ts->sec = tmp.sec; -+ ts->nsec = tmp.nsec; -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static void dpa_set_fiper_alarm(struct dpa_ptp_tsu *tsu, -+ struct dpa_ptp_time *cnt_time) -+{ -+ struct mac_device *mac_dev = tsu->dpa_priv->mac_dev; -+ u64 tmp, fiper; -+ -+ if (mac_dev->fm_rtc_disable) -+ mac_dev->fm_rtc_disable(get_fm_handle(tsu->dpa_priv->net_dev)); -+ -+ /* TMR_FIPER1 will pulse every second after ALARM1 expired */ -+ tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec; -+ fiper = NANOSEC_PER_SECOND - DPA_PTP_NOMINAL_FREQ_PERIOD_NS; -+ if (mac_dev->fm_rtc_set_alarm) -+ mac_dev->fm_rtc_set_alarm(get_fm_handle(tsu->dpa_priv->net_dev), -+ 0, tmp); -+ if (mac_dev->fm_rtc_set_fiper) -+ mac_dev->fm_rtc_set_fiper(get_fm_handle(tsu->dpa_priv->net_dev), -+ 0, fiper); -+ -+ if (mac_dev->fm_rtc_enable) -+ mac_dev->fm_rtc_enable(get_fm_handle(tsu->dpa_priv->net_dev)); -+} -+ -+static void dpa_get_curr_cnt(struct dpa_ptp_tsu *tsu, -+ struct dpa_ptp_time *curr_time) -+{ -+ struct mac_device *mac_dev = tsu->dpa_priv->mac_dev; -+ u64 tmp; -+ u32 mod; -+ -+ if (mac_dev->fm_rtc_get_cnt) -+ mac_dev->fm_rtc_get_cnt(get_fm_handle(tsu->dpa_priv->net_dev), -+ &tmp); -+ -+ mod = do_div(tmp, NANOSEC_PER_SECOND); -+ curr_time->sec = (u32)tmp; -+ curr_time->nsec = mod; -+} -+ -+static void dpa_set_1588cnt(struct dpa_ptp_tsu *tsu, -+ struct dpa_ptp_time *cnt_time) -+{ -+ struct mac_device *mac_dev = tsu->dpa_priv->mac_dev; -+ u64 tmp; -+ -+ tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec; -+ -+ if (mac_dev->fm_rtc_set_cnt) -+ mac_dev->fm_rtc_set_cnt(get_fm_handle(tsu->dpa_priv->net_dev), -+ tmp); -+ -+ /* Restart fiper two seconds later */ -+ cnt_time->sec += 2; -+ cnt_time->nsec = 0; -+ dpa_set_fiper_alarm(tsu, cnt_time); -+} -+ -+static void dpa_get_drift(struct dpa_ptp_tsu *tsu, u32 *addend) -+{ -+ struct mac_device *mac_dev = tsu->dpa_priv->mac_dev; -+ u32 drift; -+ -+ if (mac_dev->fm_rtc_get_drift) -+ mac_dev->fm_rtc_get_drift(get_fm_handle(tsu->dpa_priv->net_dev), -+ &drift); -+ -+ *addend = drift; -+} -+ -+static void dpa_set_drift(struct dpa_ptp_tsu *tsu, u32 addend) -+{ -+ struct mac_device *mac_dev = tsu->dpa_priv->mac_dev; -+ -+ if (mac_dev->fm_rtc_set_drift) -+ mac_dev->fm_rtc_set_drift(get_fm_handle(tsu->dpa_priv->net_dev), -+ addend); -+} -+ -+static void dpa_flush_timestamp(struct dpa_ptp_tsu *tsu) -+{ -+ dpa_ptp_reset_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ); -+ dpa_ptp_reset_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ); -+} -+ -+int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ struct dpa_priv_s *priv = netdev_priv(dev); -+ struct dpa_ptp_tsu *tsu = priv->tsu; -+ struct mac_device *mac_dev = priv->mac_dev; -+ struct dpa_ptp_data ptp_data; -+ struct dpa_ptp_data *ptp_data_user; -+ struct dpa_ptp_time act_time; -+ u32 addend; -+ int retval = 0; -+ -+ if (!tsu || !tsu->valid) -+ return -ENODEV; -+ -+ switch (cmd) { -+ case PTP_ENBL_TXTS_IOCTL: -+ tsu->hwts_tx_en_ioctl = 1; -+ if (mac_dev->fm_rtc_enable) -+ mac_dev->fm_rtc_enable(get_fm_handle(dev)); -+ if (mac_dev->ptp_enable) -+ mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev)); -+ break; -+ case PTP_DSBL_TXTS_IOCTL: -+ tsu->hwts_tx_en_ioctl = 0; -+ if (mac_dev->fm_rtc_disable) -+ mac_dev->fm_rtc_disable(get_fm_handle(dev)); -+ if (mac_dev->ptp_disable) -+ mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev)); -+ break; -+ case PTP_ENBL_RXTS_IOCTL: -+ tsu->hwts_rx_en_ioctl = 1; -+ break; -+ case PTP_DSBL_RXTS_IOCTL: -+ tsu->hwts_rx_en_ioctl = 0; -+ break; -+ case PTP_GET_RX_TIMESTAMP: -+ ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data; -+ if (copy_from_user(&ptp_data.ident, -+ &ptp_data_user->ident, sizeof(ptp_data.ident))) -+ return -EINVAL; -+ -+ if (dpa_get_rx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts)) -+ return -EAGAIN; -+ -+ if (copy_to_user((void __user *)&ptp_data_user->ts, -+ &ptp_data.ts, sizeof(ptp_data.ts))) -+ return -EFAULT; -+ break; -+ case PTP_GET_TX_TIMESTAMP: -+ ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data; -+ if (copy_from_user(&ptp_data.ident, -+ &ptp_data_user->ident, sizeof(ptp_data.ident))) -+ return -EINVAL; -+ -+ if (dpa_get_tx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts)) -+ return -EAGAIN; -+ -+ if (copy_to_user((void __user *)&ptp_data_user->ts, -+ &ptp_data.ts, sizeof(ptp_data.ts))) -+ return -EFAULT; -+ break; -+ case PTP_GET_TIME: -+ dpa_get_curr_cnt(tsu, &act_time); -+ if (copy_to_user(ifr->ifr_data, &act_time, sizeof(act_time))) -+ return -EFAULT; -+ break; -+ case PTP_SET_TIME: -+ if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time))) -+ return -EINVAL; -+ dpa_set_1588cnt(tsu, &act_time); -+ break; -+ case PTP_GET_ADJ: -+ dpa_get_drift(tsu, &addend); -+ if (copy_to_user(ifr->ifr_data, &addend, sizeof(addend))) -+ return -EFAULT; -+ break; -+ case PTP_SET_ADJ: -+ if (copy_from_user(&addend, ifr->ifr_data, sizeof(addend))) -+ return -EINVAL; -+ dpa_set_drift(tsu, addend); -+ break; -+ case PTP_SET_FIPER_ALARM: -+ if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time))) -+ return -EINVAL; -+ dpa_set_fiper_alarm(tsu, &act_time); -+ break; -+ case PTP_CLEANUP_TS: -+ dpa_flush_timestamp(tsu); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return retval; -+} -+ -+int dpa_ptp_init(struct dpa_priv_s *priv) -+{ -+ struct dpa_ptp_tsu *tsu; -+ -+ /* Allocate memory for PTP structure */ -+ tsu = kzalloc(sizeof(struct dpa_ptp_tsu), GFP_KERNEL); -+ if (!tsu) -+ return -ENOMEM; -+ -+ tsu->valid = TRUE; -+ tsu->dpa_priv = priv; -+ -+ dpa_ptp_init_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ); -+ dpa_ptp_init_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ); -+ -+ priv->tsu = tsu; -+ -+ return 0; -+} -+EXPORT_SYMBOL(dpa_ptp_init); -+ -+void dpa_ptp_cleanup(struct dpa_priv_s *priv) -+{ -+ struct dpa_ptp_tsu *tsu = priv->tsu; -+ -+ tsu->valid = FALSE; -+ vfree(tsu->rx_timestamps.circ_buf.buf); -+ vfree(tsu->tx_timestamps.circ_buf.buf); -+ -+ kfree(tsu); -+} -+EXPORT_SYMBOL(dpa_ptp_cleanup); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h -@@ -0,0 +1,138 @@ -+/* Copyright (C) 2011 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ */ -+#ifndef __DPAA_1588_H__ -+#define __DPAA_1588_H__ -+ -+#include -+#include -+#include -+#include -+ -+#define DEFAULT_PTP_RX_BUF_SZ 256 -+#define DEFAULT_PTP_TX_BUF_SZ 256 -+ -+/* 1588 private ioctl calls */ -+#define PTP_ENBL_TXTS_IOCTL SIOCDEVPRIVATE -+#define PTP_DSBL_TXTS_IOCTL (SIOCDEVPRIVATE + 1) -+#define PTP_ENBL_RXTS_IOCTL (SIOCDEVPRIVATE + 2) -+#define PTP_DSBL_RXTS_IOCTL (SIOCDEVPRIVATE + 3) -+#define PTP_GET_TX_TIMESTAMP (SIOCDEVPRIVATE + 4) -+#define PTP_GET_RX_TIMESTAMP (SIOCDEVPRIVATE + 5) -+#define PTP_SET_TIME (SIOCDEVPRIVATE + 6) -+#define PTP_GET_TIME (SIOCDEVPRIVATE + 7) -+#define PTP_SET_FIPER_ALARM (SIOCDEVPRIVATE + 8) -+#define PTP_SET_ADJ (SIOCDEVPRIVATE + 9) -+#define PTP_GET_ADJ (SIOCDEVPRIVATE + 10) -+#define PTP_CLEANUP_TS (SIOCDEVPRIVATE + 11) -+ -+/* PTP V2 message type */ -+enum { -+ PTP_MSGTYPE_SYNC = 0x0, -+ PTP_MSGTYPE_DELREQ = 0x1, -+ PTP_MSGTYPE_PDELREQ = 0x2, -+ PTP_MSGTYPE_PDELRESP = 0x3, -+ PTP_MSGTYPE_FLWUP = 0x8, -+ PTP_MSGTYPE_DELRESP = 0x9, -+ PTP_MSGTYPE_PDELRES_FLWUP = 0xA, -+ PTP_MSGTYPE_ANNOUNCE = 0xB, -+ PTP_MSGTYPE_SGNLNG = 0xC, -+ PTP_MSGTYPE_MNGMNT = 0xD, -+}; -+ -+/* Byte offset of data in the PTP V2 headers */ -+#define PTP_OFFS_MSG_TYPE 0 -+#define PTP_OFFS_VER_PTP 1 -+#define PTP_OFFS_MSG_LEN 2 -+#define PTP_OFFS_DOM_NMB 4 -+#define PTP_OFFS_FLAGS 6 -+#define PTP_OFFS_CORFIELD 8 -+#define PTP_OFFS_SRCPRTID 20 -+#define PTP_OFFS_SEQ_ID 30 -+#define PTP_OFFS_CTRL 32 -+#define PTP_OFFS_LOGMEAN 33 -+ -+#define PTP_IP_OFFS 14 -+#define PTP_UDP_OFFS 34 -+#define PTP_HEADER_OFFS 42 -+#define PTP_MSG_TYPE_OFFS (PTP_HEADER_OFFS + PTP_OFFS_MSG_TYPE) -+#define PTP_SPORT_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SRCPRTID) -+#define PTP_SEQ_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SEQ_ID) -+#define PTP_CTRL_OFFS (PTP_HEADER_OFFS + PTP_OFFS_CTRL) -+ -+/* 1588-2008 network protocol enumeration values */ -+#define DPA_PTP_PROT_IPV4 1 -+#define DPA_PTP_PROT_IPV6 2 -+#define DPA_PTP_PROT_802_3 3 -+#define DPA_PTP_PROT_DONTCARE 0xFFFF -+ -+#define DPA_PTP_SOURCE_PORT_LENGTH 10 -+#define DPA_PTP_HEADER_SZE 34 -+#define DPA_ETYPE_LEN 2 -+#define DPA_VLAN_TAG_LEN 4 -+#define NANOSEC_PER_SECOND 1000000000 -+ -+/* The threshold between the current found one and the oldest one */ -+#define TS_ACCUMULATION_THRESHOLD 50 -+ -+/* Struct needed to identify a timestamp */ -+struct dpa_ptp_ident { -+ u8 version; -+ u8 msg_type; -+ u16 netw_prot; -+ u16 seq_id; -+ u8 snd_port_id[DPA_PTP_SOURCE_PORT_LENGTH]; -+}; -+ -+/* Timestamp format in 1588-2008 */ -+struct dpa_ptp_time { -+ u64 sec; /* just 48 bit used */ -+ u32 nsec; -+}; -+ -+/* needed for timestamp data over ioctl */ -+struct dpa_ptp_data { -+ struct dpa_ptp_ident ident; -+ struct dpa_ptp_time ts; -+}; -+ -+struct dpa_ptp_circ_buf { -+ struct circ_buf circ_buf; -+ u32 size; -+ spinlock_t ptp_lock; -+}; -+ -+/* PTP TSU control structure */ -+struct dpa_ptp_tsu { -+ struct dpa_priv_s *dpa_priv; -+ bool valid; -+ struct dpa_ptp_circ_buf rx_timestamps; -+ struct dpa_ptp_circ_buf tx_timestamps; -+ -+ /* HW timestamping over ioctl enabled flag */ -+ int hwts_tx_en_ioctl; -+ int hwts_rx_en_ioctl; -+}; -+ -+extern int dpa_ptp_init(struct dpa_priv_s *priv); -+extern void dpa_ptp_cleanup(struct dpa_priv_s *priv); -+extern void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv, -+ struct sk_buff *skb, void *data); -+extern void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv, -+ struct sk_buff *skb, void *data); -+extern int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd); -+#endif ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c -@@ -0,0 +1,180 @@ -+/* Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include /* struct qm_mcr_querycgr */ -+#include -+#include "dpaa_debugfs.h" -+#include "dpaa_eth.h" /* struct dpa_priv_s, dpa_percpu_priv_s, dpa_bp */ -+ -+#define DPA_DEBUGFS_DESCRIPTION "FSL DPAA Ethernet debugfs entries" -+#define DPA_ETH_DEBUGFS_ROOT "fsl_dpa" -+ -+static struct dentry *dpa_debugfs_root; -+ -+static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file); -+static ssize_t dpa_loop_write(struct file *f, -+ const char __user *buf, size_t count, loff_t *off); -+ -+static const struct file_operations dpa_debugfs_lp_fops = { -+ .open = dpa_debugfs_loop_open, -+ .write = dpa_loop_write, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static int dpa_debugfs_loop_show(struct seq_file *file, void *offset) -+{ -+ struct dpa_priv_s *priv; -+ -+ BUG_ON(offset == NULL); -+ -+ priv = netdev_priv((struct net_device *)file->private); -+ seq_printf(file, "%d->%d\n", priv->loop_id, priv->loop_to); -+ -+ return 0; -+} -+ -+static int user_input_convert(const char __user *user_buf, size_t count, -+ long *val) -+{ -+ char buf[12]; -+ -+ if (count > sizeof(buf) - 1) -+ return -EINVAL; -+ if (copy_from_user(buf, user_buf, count)) -+ return -EFAULT; -+ buf[count] = '\0'; -+ if (kstrtol(buf, 0, val)) -+ return -EINVAL; -+ return 0; -+} -+ -+static ssize_t dpa_loop_write(struct file *f, -+ const char __user *buf, size_t count, loff_t *off) -+{ -+ struct dpa_priv_s *priv; -+ struct net_device *netdev; -+ struct seq_file *sf; -+ int ret; -+ long val; -+ -+ ret = user_input_convert(buf, count, &val); -+ if (ret) -+ return ret; -+ -+ sf = (struct seq_file *)f->private_data; -+ netdev = (struct net_device *)sf->private; -+ priv = netdev_priv(netdev); -+ -+ priv->loop_to = ((val < 0) || (val > 20)) ? -1 : val; -+ -+ return count; -+} -+ -+static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file) -+{ -+ int _errno; -+ const struct net_device *net_dev; -+ -+ _errno = single_open(file, dpa_debugfs_loop_show, inode->i_private); -+ if (unlikely(_errno < 0)) { -+ net_dev = (struct net_device *)inode->i_private; -+ -+ if (netif_msg_drv((struct dpa_priv_s *)netdev_priv(net_dev))) -+ netdev_err(net_dev, "single_open() = %d\n", -+ _errno); -+ } -+ -+ return _errno; -+} -+ -+ -+int dpa_netdev_debugfs_create(struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ static int cnt; -+ char loop_file_name[100]; -+ -+ if (unlikely(dpa_debugfs_root == NULL)) { -+ pr_err(KBUILD_MODNAME ": %s:%hu:%s(): \t%s\n", -+ KBUILD_BASENAME".c", __LINE__, __func__, -+ "root debugfs missing, possible module ordering issue"); -+ return -ENOMEM; -+ } -+ -+ sprintf(loop_file_name, "eth%d_loop", ++cnt); -+ priv->debugfs_loop_file = debugfs_create_file(loop_file_name, -+ S_IRUGO, -+ dpa_debugfs_root, -+ net_dev, -+ &dpa_debugfs_lp_fops); -+ if (unlikely(priv->debugfs_loop_file == NULL)) { -+ netdev_err(net_dev, "debugfs_create_file(%s/%s)", -+ dpa_debugfs_root->d_iname, -+ loop_file_name); -+ -+ return -ENOMEM; -+ } -+ return 0; -+} -+ -+void dpa_netdev_debugfs_remove(struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ -+ debugfs_remove(priv->debugfs_loop_file); -+} -+ -+int __init dpa_debugfs_module_init(void) -+{ -+ int _errno = 0; -+ -+ pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION "\n"); -+ -+ dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT, NULL); -+ -+ if (unlikely(dpa_debugfs_root == NULL)) { -+ _errno = -ENOMEM; -+ pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n", -+ KBUILD_BASENAME".c", __LINE__, __func__); -+ pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n", -+ DPA_ETH_DEBUGFS_ROOT, _errno); -+ } -+ -+ return _errno; -+} -+ -+void __exit dpa_debugfs_module_exit(void) -+{ -+ debugfs_remove(dpa_debugfs_root); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h -@@ -0,0 +1,43 @@ -+/* Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef DPAA_DEBUGFS_H_ -+#define DPAA_DEBUGFS_H_ -+ -+#include -+#include /* struct dentry needed in dpaa_eth.h */ -+ -+int dpa_netdev_debugfs_create(struct net_device *net_dev); -+void dpa_netdev_debugfs_remove(struct net_device *net_dev); -+int __init dpa_debugfs_module_init(void); -+void __exit dpa_debugfs_module_exit(void); -+ -+#endif /* DPAA_DEBUGFS_H_ */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -@@ -0,0 +1,1210 @@ -+/* Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifdef CONFIG_FSL_DPAA_ETH_DEBUG -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+#else -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": " fmt -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include /* arp_hdr_len() */ -+#include /* VLAN_HLEN */ -+#include /* struct icmphdr */ -+#include /* struct iphdr */ -+#include /* struct ipv6hdr */ -+#include /* struct udphdr */ -+#include /* struct tcphdr */ -+#include /* net_ratelimit() */ -+#include /* ETH_P_IP and ETH_P_IPV6 */ -+#include -+#include -+#include -+#include -+#ifdef CONFIG_SOC_BUS -+#include /* soc_device_match */ -+#endif -+ -+#include "fsl_fman.h" -+#include "fm_ext.h" -+#include "fm_port_ext.h" -+ -+#include "mac.h" -+#include "dpaa_eth.h" -+#include "dpaa_eth_common.h" -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+#include "dpaa_debugfs.h" -+#endif /* CONFIG_FSL_DPAA_DBG_LOOP */ -+ -+/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files -+ * using trace events only need to #include -+ */ -+#define CREATE_TRACE_POINTS -+#include "dpaa_eth_trace.h" -+ -+#define DPA_NAPI_WEIGHT 64 -+ -+/* Valid checksum indication */ -+#define DPA_CSUM_VALID 0xFFFF -+ -+#define DPA_DESCRIPTION "FSL DPAA Ethernet driver" -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+ -+MODULE_AUTHOR("Andy Fleming "); -+ -+MODULE_DESCRIPTION(DPA_DESCRIPTION); -+ -+static uint8_t debug = -1; -+module_param(debug, byte, S_IRUGO); -+MODULE_PARM_DESC(debug, "Module/Driver verbosity level"); -+ -+/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */ -+static uint16_t tx_timeout = 1000; -+module_param(tx_timeout, ushort, S_IRUGO); -+MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms"); -+ -+static const char rtx[][3] = { -+ [RX] = "RX", -+ [TX] = "TX" -+}; -+ -+#ifndef CONFIG_PPC -+bool dpaa_errata_a010022; -+EXPORT_SYMBOL(dpaa_errata_a010022); -+#endif -+ -+/* BM */ -+ -+#define DPAA_ETH_MAX_PAD (L1_CACHE_BYTES * 8) -+ -+static uint8_t dpa_priv_common_bpid; -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+struct net_device *dpa_loop_netdevs[20]; -+#endif -+ -+#ifdef CONFIG_PM -+ -+static int dpaa_suspend(struct device *dev) -+{ -+ struct net_device *net_dev; -+ struct dpa_priv_s *priv; -+ struct mac_device *mac_dev; -+ int err = 0; -+ -+ net_dev = dev_get_drvdata(dev); -+ -+ if (net_dev->flags & IFF_UP) { -+ priv = netdev_priv(net_dev); -+ mac_dev = priv->mac_dev; -+ -+ if (priv->wol & DPAA_WOL_MAGIC) { -+ err = priv->mac_dev->set_wol(mac_dev->port_dev[RX], -+ priv->mac_dev->get_mac_handle(mac_dev), true); -+ if (err) { -+ netdev_err(net_dev, "set_wol() = %d\n", err); -+ goto set_wol_failed; -+ } -+ } -+ -+ err = fm_port_suspend(mac_dev->port_dev[RX]); -+ if (err) { -+ netdev_err(net_dev, "fm_port_suspend(RX) = %d\n", err); -+ goto rx_port_suspend_failed; -+ } -+ -+ err = fm_port_suspend(mac_dev->port_dev[TX]); -+ if (err) { -+ netdev_err(net_dev, "fm_port_suspend(TX) = %d\n", err); -+ goto tx_port_suspend_failed; -+ } -+ } -+ -+ return 0; -+ -+tx_port_suspend_failed: -+ fm_port_resume(mac_dev->port_dev[RX]); -+rx_port_suspend_failed: -+ if (priv->wol & DPAA_WOL_MAGIC) { -+ priv->mac_dev->set_wol(mac_dev->port_dev[RX], -+ priv->mac_dev->get_mac_handle(mac_dev), false); -+ } -+set_wol_failed: -+ return err; -+} -+ -+static int dpaa_resume(struct device *dev) -+{ -+ struct net_device *net_dev; -+ struct dpa_priv_s *priv; -+ struct mac_device *mac_dev; -+ int err = 0; -+ -+ net_dev = dev_get_drvdata(dev); -+ -+ if (net_dev->flags & IFF_UP) { -+ priv = netdev_priv(net_dev); -+ mac_dev = priv->mac_dev; -+ -+ err = fm_mac_resume(mac_dev->get_mac_handle(mac_dev)); -+ if (err) { -+ netdev_err(net_dev, "fm_mac_resume = %d\n", err); -+ goto resume_failed; -+ } -+ -+ err = fm_port_resume(mac_dev->port_dev[TX]); -+ if (err) { -+ netdev_err(net_dev, "fm_port_resume(TX) = %d\n", err); -+ goto resume_failed; -+ } -+ -+ err = fm_port_resume(mac_dev->port_dev[RX]); -+ if (err) { -+ netdev_err(net_dev, "fm_port_resume(RX) = %d\n", err); -+ goto resume_failed; -+ } -+ -+ if (priv->wol & DPAA_WOL_MAGIC) { -+ err = priv->mac_dev->set_wol(mac_dev->port_dev[RX], -+ priv->mac_dev->get_mac_handle(mac_dev), false); -+ if (err) { -+ netdev_err(net_dev, "set_wol() = %d\n", err); -+ goto resume_failed; -+ } -+ } -+ } -+ -+ return 0; -+ -+resume_failed: -+ return err; -+} -+ -+static const struct dev_pm_ops dpaa_pm_ops = { -+ .suspend = dpaa_suspend, -+ .resume = dpaa_resume, -+}; -+ -+#define DPAA_PM_OPS (&dpaa_pm_ops) -+ -+#else /* CONFIG_PM */ -+ -+#define DPAA_PM_OPS NULL -+ -+#endif /* CONFIG_PM */ -+ -+/* Checks whether the checksum field in Parse Results array is valid -+ * (equals 0xFFFF) and increments the .cse counter otherwise -+ */ -+static inline void -+dpa_csum_validation(const struct dpa_priv_s *priv, -+ struct dpa_percpu_priv_s *percpu_priv, -+ const struct qm_fd *fd) -+{ -+ dma_addr_t addr = qm_fd_addr(fd); -+ struct dpa_bp *dpa_bp = priv->dpa_bp; -+ void *frm = phys_to_virt(addr); -+ fm_prs_result_t *parse_result; -+ -+ if (unlikely(!frm)) -+ return; -+ -+ dma_sync_single_for_cpu(dpa_bp->dev, addr, DPA_RX_PRIV_DATA_SIZE + -+ DPA_PARSE_RESULTS_SIZE, DMA_BIDIRECTIONAL); -+ -+ parse_result = (fm_prs_result_t *)(frm + DPA_RX_PRIV_DATA_SIZE); -+ -+ if (parse_result->cksum != DPA_CSUM_VALID) -+ percpu_priv->rx_errors.cse++; -+} -+ -+static void _dpa_rx_error(struct net_device *net_dev, -+ const struct dpa_priv_s *priv, -+ struct dpa_percpu_priv_s *percpu_priv, -+ const struct qm_fd *fd, -+ u32 fqid) -+{ -+ /* limit common, possibly innocuous Rx FIFO Overflow errors' -+ * interference with zero-loss convergence benchmark results. -+ */ -+ if (likely(fd->status & FM_FD_STAT_ERR_PHYSICAL)) -+ pr_warn_once("fsl-dpa: non-zero error counters in fman statistics (sysfs)\n"); -+ else -+ if (netif_msg_hw(priv) && net_ratelimit()) -+ netdev_dbg(net_dev, "Err FD status = 0x%08x\n", -+ fd->status & FM_FD_STAT_RX_ERRORS); -+#ifdef CONFIG_FSL_DPAA_HOOKS -+ if (dpaa_eth_hooks.rx_error && -+ dpaa_eth_hooks.rx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN) -+ /* it's up to the hook to perform resource cleanup */ -+ return; -+#endif -+ percpu_priv->stats.rx_errors++; -+ -+ if (fd->status & FM_PORT_FRM_ERR_DMA) -+ percpu_priv->rx_errors.dme++; -+ if (fd->status & FM_PORT_FRM_ERR_PHYSICAL) -+ percpu_priv->rx_errors.fpe++; -+ if (fd->status & FM_PORT_FRM_ERR_SIZE) -+ percpu_priv->rx_errors.fse++; -+ if (fd->status & FM_PORT_FRM_ERR_PRS_HDR_ERR) -+ percpu_priv->rx_errors.phe++; -+ if (fd->status & FM_FD_STAT_L4CV) -+ dpa_csum_validation(priv, percpu_priv, fd); -+ -+ dpa_fd_release(net_dev, fd); -+} -+ -+static void _dpa_tx_error(struct net_device *net_dev, -+ const struct dpa_priv_s *priv, -+ struct dpa_percpu_priv_s *percpu_priv, -+ const struct qm_fd *fd, -+ u32 fqid) -+{ -+ struct sk_buff *skb; -+ -+ if (netif_msg_hw(priv) && net_ratelimit()) -+ netdev_warn(net_dev, "FD status = 0x%08x\n", -+ fd->status & FM_FD_STAT_TX_ERRORS); -+#ifdef CONFIG_FSL_DPAA_HOOKS -+ if (dpaa_eth_hooks.tx_error && -+ dpaa_eth_hooks.tx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN) -+ /* now the hook must ensure proper cleanup */ -+ return; -+#endif -+ percpu_priv->stats.tx_errors++; -+ -+ /* If we intended the buffers from this frame to go into the bpools -+ * when the FMan transmit was done, we need to put it in manually. -+ */ -+ if (fd->bpid != 0xff) { -+ dpa_fd_release(net_dev, fd); -+ return; -+ } -+ -+ skb = _dpa_cleanup_tx_fd(priv, fd); -+ dev_kfree_skb(skb); -+} -+ -+/* Helper function to factor out frame validation logic on all Rx paths. Its -+ * purpose is to extract from the Parse Results structure information about -+ * the integrity of the frame, its checksum, the length of the parsed headers -+ * and whether the frame is suitable for GRO. -+ * -+ * Assumes no parser errors, since any error frame is dropped before this -+ * function is called. -+ * -+ * @skb will have its ip_summed field overwritten; -+ * @use_gro will only be written with 0, if the frame is definitely not -+ * GRO-able; otherwise, it will be left unchanged; -+ * @hdr_size will be written with a safe value, at least the size of the -+ * headers' length. -+ */ -+void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results, -+ const struct qm_fd *fd, -+ struct sk_buff *skb, int *use_gro) -+{ -+ if (fd->status & FM_FD_STAT_L4CV) { -+ /* The parser has run and performed L4 checksum validation. -+ * We know there were no parser errors (and implicitly no -+ * L4 csum error), otherwise we wouldn't be here. -+ */ -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ -+ /* Don't go through GRO for certain types of traffic that -+ * we know are not GRO-able, such as dgram-based protocols. -+ * In the worst-case scenarios, such as small-pkt terminating -+ * UDP, the extra GRO processing would be overkill. -+ * -+ * The only protocol the Parser supports that is also GRO-able -+ * is currently TCP. -+ */ -+ if (!fm_l4_frame_is_tcp(parse_results)) -+ *use_gro = 0; -+ -+ return; -+ } -+ -+ /* We're here because either the parser didn't run or the L4 checksum -+ * was not verified. This may include the case of a UDP frame with -+ * checksum zero or an L4 proto other than TCP/UDP -+ */ -+ skb->ip_summed = CHECKSUM_NONE; -+ -+ /* Bypass GRO for unknown traffic or if no PCDs are applied */ -+ *use_gro = 0; -+} -+ -+int dpaa_eth_poll(struct napi_struct *napi, int budget) -+{ -+ struct dpa_napi_portal *np = -+ container_of(napi, struct dpa_napi_portal, napi); -+ -+ int cleaned = qman_p_poll_dqrr(np->p, budget); -+ -+ if (cleaned < budget) { -+ int tmp; -+ napi_complete(napi); -+ tmp = qman_p_irqsource_add(np->p, QM_PIRQ_DQRI); -+ DPA_BUG_ON(tmp); -+ } -+ -+ return cleaned; -+} -+EXPORT_SYMBOL(dpaa_eth_poll); -+ -+static void __hot _dpa_tx_conf(struct net_device *net_dev, -+ const struct dpa_priv_s *priv, -+ struct dpa_percpu_priv_s *percpu_priv, -+ const struct qm_fd *fd, -+ u32 fqid) -+{ -+ struct sk_buff *skb; -+ -+ /* do we need the timestamp for the error frames? */ -+ -+ if (unlikely(fd->status & FM_FD_STAT_TX_ERRORS) != 0) { -+ if (netif_msg_hw(priv) && net_ratelimit()) -+ netdev_warn(net_dev, "FD status = 0x%08x\n", -+ fd->status & FM_FD_STAT_TX_ERRORS); -+ -+ percpu_priv->stats.tx_errors++; -+ } -+ -+ /* hopefully we need not get the timestamp before the hook */ -+#ifdef CONFIG_FSL_DPAA_HOOKS -+ if (dpaa_eth_hooks.tx_confirm && dpaa_eth_hooks.tx_confirm(net_dev, -+ fd, fqid) == DPAA_ETH_STOLEN) -+ /* it's the hook that must now perform cleanup */ -+ return; -+#endif -+ /* This might not perfectly reflect the reality, if the core dequeuing -+ * the Tx confirmation is different from the one that did the enqueue, -+ * but at least it'll show up in the total count. -+ */ -+ percpu_priv->tx_confirm++; -+ -+ skb = _dpa_cleanup_tx_fd(priv, fd); -+ -+ dev_kfree_skb(skb); -+} -+ -+enum qman_cb_dqrr_result -+priv_rx_error_dqrr(struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry *dq) -+{ -+ struct net_device *net_dev; -+ struct dpa_priv_s *priv; -+ struct dpa_percpu_priv_s *percpu_priv; -+ int *count_ptr; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ -+ percpu_priv = raw_cpu_ptr(priv->percpu_priv); -+ count_ptr = raw_cpu_ptr(priv->dpa_bp->percpu_count); -+ -+ if (dpaa_eth_napi_schedule(percpu_priv, portal)) -+ return qman_cb_dqrr_stop; -+ -+ if (unlikely(dpaa_eth_refill_bpools(priv->dpa_bp, count_ptr))) -+ /* Unable to refill the buffer pool due to insufficient -+ * system memory. Just release the frame back into the pool, -+ * otherwise we'll soon end up with an empty buffer pool. -+ */ -+ dpa_fd_release(net_dev, &dq->fd); -+ else -+ _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+ -+enum qman_cb_dqrr_result __hot -+priv_rx_default_dqrr(struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry *dq) -+{ -+ struct net_device *net_dev; -+ struct dpa_priv_s *priv; -+ struct dpa_percpu_priv_s *percpu_priv; -+ int *count_ptr; -+ struct dpa_bp *dpa_bp; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ dpa_bp = priv->dpa_bp; -+ -+ /* Trace the Rx fd */ -+ trace_dpa_rx_fd(net_dev, fq, &dq->fd); -+ -+ /* IRQ handler, non-migratable; safe to use raw_cpu_ptr here */ -+ percpu_priv = raw_cpu_ptr(priv->percpu_priv); -+ count_ptr = raw_cpu_ptr(dpa_bp->percpu_count); -+ -+ if (unlikely(dpaa_eth_napi_schedule(percpu_priv, portal))) -+ return qman_cb_dqrr_stop; -+ -+ /* Vale of plenty: make sure we didn't run out of buffers */ -+ -+ if (unlikely(dpaa_eth_refill_bpools(dpa_bp, count_ptr))) -+ /* Unable to refill the buffer pool due to insufficient -+ * system memory. Just release the frame back into the pool, -+ * otherwise we'll soon end up with an empty buffer pool. -+ */ -+ dpa_fd_release(net_dev, &dq->fd); -+ else -+ _dpa_rx(net_dev, portal, priv, percpu_priv, &dq->fd, fq->fqid, -+ count_ptr); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+enum qman_cb_dqrr_result -+priv_tx_conf_error_dqrr(struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry *dq) -+{ -+ struct net_device *net_dev; -+ struct dpa_priv_s *priv; -+ struct dpa_percpu_priv_s *percpu_priv; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ -+ percpu_priv = raw_cpu_ptr(priv->percpu_priv); -+ -+ if (dpaa_eth_napi_schedule(percpu_priv, portal)) -+ return qman_cb_dqrr_stop; -+ -+ _dpa_tx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+enum qman_cb_dqrr_result __hot -+priv_tx_conf_default_dqrr(struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_dqrr_entry *dq) -+{ -+ struct net_device *net_dev; -+ struct dpa_priv_s *priv; -+ struct dpa_percpu_priv_s *percpu_priv; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ -+ /* Trace the fd */ -+ trace_dpa_tx_conf_fd(net_dev, fq, &dq->fd); -+ -+ /* Non-migratable context, safe to use raw_cpu_ptr */ -+ percpu_priv = raw_cpu_ptr(priv->percpu_priv); -+ -+ if (dpaa_eth_napi_schedule(percpu_priv, portal)) -+ return qman_cb_dqrr_stop; -+ -+ _dpa_tx_conf(net_dev, priv, percpu_priv, &dq->fd, fq->fqid); -+ -+ return qman_cb_dqrr_consume; -+} -+ -+void priv_ern(struct qman_portal *portal, -+ struct qman_fq *fq, -+ const struct qm_mr_entry *msg) -+{ -+ struct net_device *net_dev; -+ const struct dpa_priv_s *priv; -+ struct sk_buff *skb; -+ struct dpa_percpu_priv_s *percpu_priv; -+ struct qm_fd fd = msg->ern.fd; -+ -+ net_dev = ((struct dpa_fq *)fq)->net_dev; -+ priv = netdev_priv(net_dev); -+ /* Non-migratable context, safe to use raw_cpu_ptr */ -+ percpu_priv = raw_cpu_ptr(priv->percpu_priv); -+ -+ percpu_priv->stats.tx_dropped++; -+ percpu_priv->stats.tx_fifo_errors++; -+ count_ern(percpu_priv, msg); -+ -+ /* If we intended this buffer to go into the pool -+ * when the FM was done, we need to put it in -+ * manually. -+ */ -+ if (msg->ern.fd.bpid != 0xff) { -+ dpa_fd_release(net_dev, &fd); -+ return; -+ } -+ -+ skb = _dpa_cleanup_tx_fd(priv, &fd); -+ dev_kfree_skb_any(skb); -+} -+ -+const struct dpa_fq_cbs_t private_fq_cbs = { -+ .rx_defq = { .cb = { .dqrr = priv_rx_default_dqrr } }, -+ .tx_defq = { .cb = { .dqrr = priv_tx_conf_default_dqrr } }, -+ .rx_errq = { .cb = { .dqrr = priv_rx_error_dqrr } }, -+ .tx_errq = { .cb = { .dqrr = priv_tx_conf_error_dqrr } }, -+ .egress_ern = { .cb = { .ern = priv_ern } } -+}; -+EXPORT_SYMBOL(private_fq_cbs); -+ -+static void dpaa_eth_napi_enable(struct dpa_priv_s *priv) -+{ -+ struct dpa_percpu_priv_s *percpu_priv; -+ int i, j; -+ -+ for_each_possible_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ -+ for (j = 0; j < qman_portal_max; j++) -+ napi_enable(&percpu_priv->np[j].napi); -+ } -+} -+ -+static void dpaa_eth_napi_disable(struct dpa_priv_s *priv) -+{ -+ struct dpa_percpu_priv_s *percpu_priv; -+ int i, j; -+ -+ for_each_possible_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ -+ for (j = 0; j < qman_portal_max; j++) -+ napi_disable(&percpu_priv->np[j].napi); -+ } -+} -+ -+static int __cold dpa_eth_priv_start(struct net_device *net_dev) -+{ -+ int err; -+ struct dpa_priv_s *priv; -+ -+ priv = netdev_priv(net_dev); -+ -+ dpaa_eth_napi_enable(priv); -+ -+ err = dpa_start(net_dev); -+ if (err < 0) -+ dpaa_eth_napi_disable(priv); -+ -+ return err; -+} -+ -+ -+ -+static int __cold dpa_eth_priv_stop(struct net_device *net_dev) -+{ -+ int _errno; -+ struct dpa_priv_s *priv; -+ -+ _errno = dpa_stop(net_dev); -+ /* Allow NAPI to consume any frame still in the Rx/TxConfirm -+ * ingress queues. This is to avoid a race between the current -+ * context and ksoftirqd which could leave NAPI disabled while -+ * in fact there's still Rx traffic to be processed. -+ */ -+ usleep_range(5000, 10000); -+ -+ priv = netdev_priv(net_dev); -+ dpaa_eth_napi_disable(priv); -+ -+ return _errno; -+} -+ -+#ifdef CONFIG_NET_POLL_CONTROLLER -+static void dpaa_eth_poll_controller(struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct dpa_percpu_priv_s *percpu_priv = -+ raw_cpu_ptr(priv->percpu_priv); -+ struct qman_portal *p; -+ const struct qman_portal_config *pc; -+ struct dpa_napi_portal *np; -+ -+ p = (struct qman_portal *)qman_get_affine_portal(smp_processor_id()); -+ pc = qman_p_get_portal_config(p); -+ np = &percpu_priv->np[pc->index]; -+ -+ qman_p_irqsource_remove(np->p, QM_PIRQ_DQRI); -+ qman_p_poll_dqrr(np->p, np->napi.weight); -+ qman_p_irqsource_add(np->p, QM_PIRQ_DQRI); -+} -+#endif -+ -+static const struct net_device_ops dpa_private_ops = { -+ .ndo_open = dpa_eth_priv_start, -+ .ndo_start_xmit = dpa_tx, -+ .ndo_stop = dpa_eth_priv_stop, -+ .ndo_tx_timeout = dpa_timeout, -+ .ndo_get_stats64 = dpa_get_stats64, -+ .ndo_set_mac_address = dpa_set_mac_address, -+ .ndo_validate_addr = eth_validate_addr, -+#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -+ .ndo_select_queue = dpa_select_queue, -+#endif -+ .ndo_change_mtu = dpa_change_mtu, -+ .ndo_set_rx_mode = dpa_set_rx_mode, -+ .ndo_init = dpa_ndo_init, -+ .ndo_set_features = dpa_set_features, -+ .ndo_fix_features = dpa_fix_features, -+ .ndo_do_ioctl = dpa_ioctl, -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ .ndo_poll_controller = dpaa_eth_poll_controller, -+#endif -+}; -+ -+static int dpa_private_napi_add(struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct dpa_percpu_priv_s *percpu_priv; -+ int i, cpu; -+ -+ for_each_possible_cpu(cpu) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu); -+ -+ percpu_priv->np = devm_kzalloc(net_dev->dev.parent, -+ qman_portal_max * sizeof(struct dpa_napi_portal), -+ GFP_KERNEL); -+ -+ if (unlikely(percpu_priv->np == NULL)) { -+ dev_err(net_dev->dev.parent, "devm_kzalloc() failed\n"); -+ return -ENOMEM; -+ } -+ -+ for (i = 0; i < qman_portal_max; i++) -+ netif_napi_add(net_dev, &percpu_priv->np[i].napi, -+ dpaa_eth_poll, DPA_NAPI_WEIGHT); -+ } -+ -+ return 0; -+} -+ -+void dpa_private_napi_del(struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct dpa_percpu_priv_s *percpu_priv; -+ int i, cpu; -+ -+ for_each_possible_cpu(cpu) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu); -+ -+ if (percpu_priv->np) { -+ for (i = 0; i < qman_portal_max; i++) -+ netif_napi_del(&percpu_priv->np[i].napi); -+ -+ devm_kfree(net_dev->dev.parent, percpu_priv->np); -+ } -+ } -+} -+EXPORT_SYMBOL(dpa_private_napi_del); -+ -+static int dpa_private_netdev_init(struct net_device *net_dev) -+{ -+ int i; -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct dpa_percpu_priv_s *percpu_priv; -+ const uint8_t *mac_addr; -+ -+ /* Although we access another CPU's private data here -+ * we do it at initialization so it is safe -+ */ -+ for_each_possible_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ percpu_priv->net_dev = net_dev; -+ } -+ -+ net_dev->netdev_ops = &dpa_private_ops; -+ mac_addr = priv->mac_dev->addr; -+ -+ net_dev->mem_start = priv->mac_dev->res->start; -+ net_dev->mem_end = priv->mac_dev->res->end; -+ -+ net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | -+ NETIF_F_LLTX); -+ -+ /* Advertise S/G and HIGHDMA support for private interfaces */ -+ net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA; -+ /* Recent kernels enable GSO automatically, if -+ * we declare NETIF_F_SG. For conformity, we'll -+ * still declare GSO explicitly. -+ */ -+ net_dev->features |= NETIF_F_GSO; -+ -+ /* Advertise GRO support */ -+ net_dev->features |= NETIF_F_GRO; -+ -+ return dpa_netdev_init(net_dev, mac_addr, tx_timeout); -+} -+ -+static struct dpa_bp * __cold -+dpa_priv_bp_probe(struct device *dev) -+{ -+ struct dpa_bp *dpa_bp; -+ -+ dpa_bp = devm_kzalloc(dev, sizeof(*dpa_bp), GFP_KERNEL); -+ if (unlikely(dpa_bp == NULL)) { -+ dev_err(dev, "devm_kzalloc() failed\n"); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ dpa_bp->percpu_count = devm_alloc_percpu(dev, *dpa_bp->percpu_count); -+ dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT; -+ -+ dpa_bp->seed_cb = dpa_bp_priv_seed; -+ dpa_bp->free_buf_cb = _dpa_bp_free_pf; -+ -+ return dpa_bp; -+} -+ -+/* Place all ingress FQs (Rx Default, Rx Error, PCD FQs) in a dedicated CGR. -+ * We won't be sending congestion notifications to FMan; for now, we just use -+ * this CGR to generate enqueue rejections to FMan in order to drop the frames -+ * before they reach our ingress queues and eat up memory. -+ */ -+static int dpaa_eth_priv_ingress_cgr_init(struct dpa_priv_s *priv) -+{ -+ struct qm_mcc_initcgr initcgr; -+ u32 cs_th; -+ int err; -+ -+ err = qman_alloc_cgrid(&priv->ingress_cgr.cgrid); -+ if (err < 0) { -+ pr_err("Error %d allocating CGR ID\n", err); -+ goto out_error; -+ } -+ -+ /* Enable CS TD, but disable Congestion State Change Notifications. */ -+ initcgr.we_mask = QM_CGR_WE_CS_THRES; -+ initcgr.cgr.cscn_en = QM_CGR_EN; -+ cs_th = CONFIG_FSL_DPAA_INGRESS_CS_THRESHOLD; -+ qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1); -+ -+ initcgr.we_mask |= QM_CGR_WE_CSTD_EN; -+ initcgr.cgr.cstd_en = QM_CGR_EN; -+ -+ /* This is actually a hack, because this CGR will be associated with -+ * our affine SWP. However, we'll place our ingress FQs in it. -+ */ -+ err = qman_create_cgr(&priv->ingress_cgr, QMAN_CGR_FLAG_USE_INIT, -+ &initcgr); -+ if (err < 0) { -+ pr_err("Error %d creating ingress CGR with ID %d\n", err, -+ priv->ingress_cgr.cgrid); -+ qman_release_cgrid(priv->ingress_cgr.cgrid); -+ goto out_error; -+ } -+ pr_debug("Created ingress CGR %d for netdev with hwaddr %pM\n", -+ priv->ingress_cgr.cgrid, priv->mac_dev->addr); -+ -+ /* struct qman_cgr allows special cgrid values (i.e. outside the 0..255 -+ * range), but we have no common initialization path between the -+ * different variants of the DPAA Eth driver, so we do it here rather -+ * than modifying every other variant than "private Eth". -+ */ -+ priv->use_ingress_cgr = true; -+ -+out_error: -+ return err; -+} -+ -+static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp, -+ size_t count) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ int i; -+ -+ if (netif_msg_probe(priv)) -+ dev_dbg(net_dev->dev.parent, -+ "Using private BM buffer pools\n"); -+ -+ priv->bp_count = count; -+ -+ for (i = 0; i < count; i++) { -+ int err; -+ err = dpa_bp_alloc(&dpa_bp[i]); -+ if (err < 0) { -+ dpa_bp_free(priv); -+ priv->dpa_bp = NULL; -+ return err; -+ } -+ -+ priv->dpa_bp = &dpa_bp[i]; -+ } -+ -+ dpa_priv_common_bpid = priv->dpa_bp->bpid; -+ return 0; -+} -+ -+static const struct of_device_id dpa_match[]; -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+static int dpa_new_loop_id(void) -+{ -+ static int if_id; -+ -+ return if_id++; -+} -+#endif -+ -+static int -+dpaa_eth_priv_probe(struct platform_device *_of_dev) -+{ -+ int err = 0, i, channel; -+ struct device *dev; -+ struct device_node *dpa_node; -+ struct dpa_bp *dpa_bp; -+ size_t count = 1; -+ struct net_device *net_dev = NULL; -+ struct dpa_priv_s *priv = NULL; -+ struct dpa_percpu_priv_s *percpu_priv; -+ struct fm_port_fqs port_fqs; -+ struct dpa_buffer_layout_s *buf_layout = NULL; -+ struct mac_device *mac_dev; -+ -+ dev = &_of_dev->dev; -+ -+ dpa_node = dev->of_node; -+ -+ if (!of_device_is_available(dpa_node)) -+ return -ENODEV; -+ -+ /* Get the buffer pools assigned to this interface; -+ * run only once the default pool probing code -+ */ -+ dpa_bp = (dpa_bpid2pool(dpa_priv_common_bpid)) ? : -+ dpa_priv_bp_probe(dev); -+ if (IS_ERR(dpa_bp)) -+ return PTR_ERR(dpa_bp); -+ -+ /* Allocate this early, so we can store relevant information in -+ * the private area (needed by 1588 code in dpa_mac_probe) -+ */ -+ net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES); -+ if (!net_dev) { -+ dev_err(dev, "alloc_etherdev_mq() failed\n"); -+ goto alloc_etherdev_mq_failed; -+ } -+ -+ /* Do this here, so we can be verbose early */ -+ SET_NETDEV_DEV(net_dev, dev); -+ dev_set_drvdata(dev, net_dev); -+ -+ priv = netdev_priv(net_dev); -+ priv->net_dev = net_dev; -+ strcpy(priv->if_type, "private"); -+ -+ priv->msg_enable = netif_msg_init(debug, -1); -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+ priv->loop_id = dpa_new_loop_id(); -+ priv->loop_to = -1; /* disabled by default */ -+ dpa_loop_netdevs[priv->loop_id] = net_dev; -+#endif -+ -+ mac_dev = dpa_mac_probe(_of_dev); -+ if (IS_ERR(mac_dev) || !mac_dev) { -+ err = PTR_ERR(mac_dev); -+ goto mac_probe_failed; -+ } -+ -+ /* We have physical ports, so we need to establish -+ * the buffer layout. -+ */ -+ buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout), -+ GFP_KERNEL); -+ if (!buf_layout) { -+ dev_err(dev, "devm_kzalloc() failed\n"); -+ goto alloc_failed; -+ } -+ dpa_set_buffers_layout(mac_dev, buf_layout); -+ -+ /* For private ports, need to compute the size of the default -+ * buffer pool, based on FMan port buffer layout;also update -+ * the maximum buffer size for private ports if necessary -+ */ -+ dpa_bp->size = dpa_bp_size(&buf_layout[RX]); -+ -+#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME -+ /* We only want to use jumbo frame optimization if we actually have -+ * L2 MAX FRM set for jumbo frames as well. -+ */ -+#ifndef CONFIG_PPC -+ if (likely(!dpaa_errata_a010022)) -+#endif -+ if(fm_get_max_frm() < 9600) -+ dev_warn(dev, -+ "Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n"); -+#endif -+ -+ INIT_LIST_HEAD(&priv->dpa_fq_list); -+ -+ memset(&port_fqs, 0, sizeof(port_fqs)); -+ -+ err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs, true, RX); -+ if (!err) -+ err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, -+ &port_fqs, true, TX); -+ -+ if (err < 0) -+ goto fq_probe_failed; -+ -+ /* bp init */ -+ -+ err = dpa_priv_bp_create(net_dev, dpa_bp, count); -+ -+ if (err < 0) -+ goto bp_create_failed; -+ -+ priv->mac_dev = mac_dev; -+ -+ channel = dpa_get_channel(); -+ -+ if (channel < 0) { -+ err = channel; -+ goto get_channel_failed; -+ } -+ -+ priv->channel = (uint16_t)channel; -+ dpaa_eth_add_channel(priv->channel); -+ -+ dpa_fq_setup(priv, &private_fq_cbs, priv->mac_dev->port_dev[TX]); -+ -+ /* Create a congestion group for this netdev, with -+ * dynamically-allocated CGR ID. -+ * Must be executed after probing the MAC, but before -+ * assigning the egress FQs to the CGRs. -+ */ -+ err = dpaa_eth_cgr_init(priv); -+ if (err < 0) { -+ dev_err(dev, "Error initializing CGR\n"); -+ goto tx_cgr_init_failed; -+ } -+ err = dpaa_eth_priv_ingress_cgr_init(priv); -+ if (err < 0) { -+ dev_err(dev, "Error initializing ingress CGR\n"); -+ goto rx_cgr_init_failed; -+ } -+ -+ /* Add the FQs to the interface, and make them active */ -+ err = dpa_fqs_init(dev, &priv->dpa_fq_list, false); -+ if (err < 0) -+ goto fq_alloc_failed; -+ -+ priv->buf_layout = buf_layout; -+ priv->tx_headroom = dpa_get_headroom(&priv->buf_layout[TX]); -+ priv->rx_headroom = dpa_get_headroom(&priv->buf_layout[RX]); -+ -+ /* All real interfaces need their ports initialized */ -+ dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs, -+ buf_layout, dev); -+ -+#ifdef CONFIG_FMAN_PFC -+ for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) { -+ err = fm_port_set_pfc_priorities_mapping_to_qman_wq( -+ mac_dev->port_dev[TX], i, i); -+ if (unlikely(err != 0)) { -+ dev_err(dev, "Error maping PFC %u to WQ %u\n", i, i); -+ goto pfc_mapping_failed; -+ } -+ } -+#endif -+ -+ priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv); -+ -+ if (priv->percpu_priv == NULL) { -+ dev_err(dev, "devm_alloc_percpu() failed\n"); -+ err = -ENOMEM; -+ goto alloc_percpu_failed; -+ } -+ for_each_possible_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ memset(percpu_priv, 0, sizeof(*percpu_priv)); -+ } -+ -+ /* Initialize NAPI */ -+ err = dpa_private_napi_add(net_dev); -+ -+ if (err < 0) -+ goto napi_add_failed; -+ -+ err = dpa_private_netdev_init(net_dev); -+ -+ if (err < 0) -+ goto netdev_init_failed; -+ -+ dpaa_eth_sysfs_init(&net_dev->dev); -+ -+#ifdef CONFIG_PM -+ device_set_wakeup_capable(dev, true); -+#endif -+ -+ pr_info("fsl_dpa: Probed interface %s\n", net_dev->name); -+ -+ return 0; -+ -+netdev_init_failed: -+napi_add_failed: -+ dpa_private_napi_del(net_dev); -+alloc_percpu_failed: -+#ifdef CONFIG_FMAN_PFC -+pfc_mapping_failed: -+#endif -+ dpa_fq_free(dev, &priv->dpa_fq_list); -+fq_alloc_failed: -+ qman_delete_cgr_safe(&priv->ingress_cgr); -+ qman_release_cgrid(priv->ingress_cgr.cgrid); -+rx_cgr_init_failed: -+ qman_delete_cgr_safe(&priv->cgr_data.cgr); -+ qman_release_cgrid(priv->cgr_data.cgr.cgrid); -+tx_cgr_init_failed: -+get_channel_failed: -+ dpa_bp_free(priv); -+bp_create_failed: -+fq_probe_failed: -+alloc_failed: -+mac_probe_failed: -+ dev_set_drvdata(dev, NULL); -+ free_netdev(net_dev); -+alloc_etherdev_mq_failed: -+ if (atomic_read(&dpa_bp->refs) == 0) -+ devm_kfree(dev, dpa_bp); -+ -+ return err; -+} -+ -+static const struct of_device_id dpa_match[] = { -+ { -+ .compatible = "fsl,dpa-ethernet" -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, dpa_match); -+ -+static struct platform_driver dpa_driver = { -+ .driver = { -+ .name = KBUILD_MODNAME, -+ .of_match_table = dpa_match, -+ .owner = THIS_MODULE, -+ .pm = DPAA_PM_OPS, -+ }, -+ .probe = dpaa_eth_priv_probe, -+ .remove = dpa_remove -+}; -+ -+#ifndef CONFIG_PPC -+static bool __init __cold soc_has_errata_a010022(void) -+{ -+#ifdef CONFIG_SOC_BUS -+ const struct soc_device_attribute soc_msi_matches[] = { -+ { .family = "QorIQ LS1043A", -+ .data = NULL }, -+ { }, -+ }; -+ -+ if (soc_device_match(soc_msi_matches)) -+ return true; -+ -+ return false; -+#else -+ return true; /* cannot identify SoC */ -+#endif -+} -+#endif -+ -+static int __init __cold dpa_load(void) -+{ -+ int _errno; -+ -+ pr_info(DPA_DESCRIPTION "\n"); -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+ dpa_debugfs_module_init(); -+#endif /* CONFIG_FSL_DPAA_DBG_LOOP */ -+ -+ /* initialise dpaa_eth mirror values */ -+ dpa_rx_extra_headroom = fm_get_rx_extra_headroom(); -+ dpa_max_frm = fm_get_max_frm(); -+ dpa_num_cpus = num_possible_cpus(); -+ -+#ifndef CONFIG_PPC -+ /* Detect if the current SoC requires the 4K alignment workaround */ -+ dpaa_errata_a010022 = soc_has_errata_a010022(); -+#endif -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+ memset(dpa_loop_netdevs, 0, sizeof(dpa_loop_netdevs)); -+#endif -+ -+ _errno = platform_driver_register(&dpa_driver); -+ if (unlikely(_errno < 0)) { -+ pr_err(KBUILD_MODNAME -+ ": %s:%hu:%s(): platform_driver_register() = %d\n", -+ KBUILD_BASENAME".c", __LINE__, __func__, _errno); -+ } -+ -+ pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -+ KBUILD_BASENAME".c", __func__); -+ -+ return _errno; -+} -+module_init(dpa_load); -+ -+static void __exit __cold dpa_unload(void) -+{ -+ pr_debug(KBUILD_MODNAME ": -> %s:%s()\n", -+ KBUILD_BASENAME".c", __func__); -+ -+ platform_driver_unregister(&dpa_driver); -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+ dpa_debugfs_module_exit(); -+#endif /* CONFIG_FSL_DPAA_DBG_LOOP */ -+ -+ /* Only one channel is used and needs to be relased after all -+ * interfaces are removed -+ */ -+ dpa_release_channel(); -+ -+ pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -+ KBUILD_BASENAME".c", __func__); -+} -+module_exit(dpa_unload); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -0,0 +1,697 @@ -+/* Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __DPA_H -+#define __DPA_H -+ -+#include -+#include /* struct qman_fq */ -+ -+#include "fm_ext.h" -+#include "dpaa_eth_trace.h" -+ -+extern int dpa_rx_extra_headroom; -+extern int dpa_max_frm; -+extern int dpa_num_cpus; -+ -+#define dpa_get_rx_extra_headroom() dpa_rx_extra_headroom -+#define dpa_get_max_frm() dpa_max_frm -+ -+#define dpa_get_max_mtu() \ -+ (dpa_get_max_frm() - (VLAN_ETH_HLEN + ETH_FCS_LEN)) -+ -+#define __hot -+ -+/* Simple enum of FQ types - used for array indexing */ -+enum port_type {RX, TX}; -+ -+/* TODO: This structure should be renamed & moved to the FMD wrapper */ -+struct dpa_buffer_layout_s { -+ uint16_t priv_data_size; -+ bool parse_results; -+ bool time_stamp; -+ bool hash_results; -+ uint8_t manip_extra_space; -+ uint16_t data_align; -+}; -+ -+#ifdef CONFIG_FSL_DPAA_ETH_DEBUG -+#define DPA_BUG_ON(cond) BUG_ON(cond) -+#else -+#define DPA_BUG_ON(cond) -+#endif -+ -+#define DPA_TX_PRIV_DATA_SIZE 16 -+#define DPA_PARSE_RESULTS_SIZE sizeof(fm_prs_result_t) -+#define DPA_TIME_STAMP_SIZE 8 -+#define DPA_HASH_RESULTS_SIZE 8 -+#define DPA_RX_PRIV_DATA_SIZE (DPA_TX_PRIV_DATA_SIZE + \ -+ dpa_get_rx_extra_headroom()) -+ -+#define FM_FD_STAT_RX_ERRORS \ -+ (FM_PORT_FRM_ERR_DMA | FM_PORT_FRM_ERR_PHYSICAL | \ -+ FM_PORT_FRM_ERR_SIZE | FM_PORT_FRM_ERR_CLS_DISCARD | \ -+ FM_PORT_FRM_ERR_EXTRACTION | FM_PORT_FRM_ERR_NO_SCHEME | \ -+ FM_PORT_FRM_ERR_ILL_PLCR | FM_PORT_FRM_ERR_PRS_TIMEOUT | \ -+ FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | FM_PORT_FRM_ERR_PRS_HDR_ERR) -+ -+#define FM_FD_STAT_TX_ERRORS \ -+ (FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT | \ -+ FM_PORT_FRM_ERR_LENGTH | FM_PORT_FRM_ERR_DMA) -+ -+#ifndef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME -+/* The raw buffer size must be cacheline aligned. -+ * Normally we use 2K buffers. -+ */ -+#define DPA_BP_RAW_SIZE 2048 -+#else -+/* For jumbo frame optimizations, use buffers large enough to accommodate -+ * 9.6K frames, FD maximum offset, skb sh_info overhead and some extra -+ * space to account for further alignments. -+ */ -+#define DPA_MAX_FRM_SIZE 9600 -+#ifdef CONFIG_PPC -+#define DPA_BP_RAW_SIZE \ -+ ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \ -+ sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1)) -+#else /* CONFIG_PPC */ -+#define DPA_BP_RAW_SIZE ((unlikely(dpaa_errata_a010022)) ? 2048 : \ -+ ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \ -+ sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1))) -+#endif /* CONFIG_PPC */ -+#endif /* CONFIG_FSL_DPAA_ETH_JUMBO_FRAME */ -+ -+/* This is what FMan is ever allowed to use. -+ * FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is -+ * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that, -+ * via SKB_WITH_OVERHEAD(). We can't rely on netdev_alloc_frag() giving us -+ * half-page-aligned buffers (can we?), so we reserve some more space -+ * for start-of-buffer alignment. -+ */ -+#define dpa_bp_size(buffer_layout) (SKB_WITH_OVERHEAD(DPA_BP_RAW_SIZE) - \ -+ SMP_CACHE_BYTES) -+/* We must ensure that skb_shinfo is always cacheline-aligned. */ -+#define DPA_SKB_SIZE(size) ((size) & ~(SMP_CACHE_BYTES - 1)) -+ -+/* Maximum size of a buffer for which recycling is allowed. -+ * We need an upper limit such that forwarded skbs that get reallocated on Tx -+ * aren't allowed to grow unboundedly. On the other hand, we need to make sure -+ * that skbs allocated by us will not fail to be recycled due to their size. -+ * -+ * For a requested size, the kernel allocator provides the next power of two -+ * sized block, which the stack will use as is, regardless of the actual size -+ * it required; since we must accommodate at most 9.6K buffers (L2 maximum -+ * supported frame size), set the recycling upper limit to 16K. -+ */ -+#define DPA_RECYCLE_MAX_SIZE 16384 -+ -+#if defined(CONFIG_FSL_SDK_FMAN_TEST) -+/*TODO: temporary for fman pcd testing */ -+#define FMAN_PCD_TESTS_MAX_NUM_RANGES 20 -+#endif -+ -+#define DPAA_ETH_FQ_DELTA 0x10000 -+ -+#define DPAA_ETH_PCD_FQ_BASE(device_addr) \ -+ (((device_addr) & 0x1fffff) >> 6) -+ -+#define DPAA_ETH_PCD_FQ_HI_PRIO_BASE(device_addr) \ -+ (DPAA_ETH_FQ_DELTA + DPAA_ETH_PCD_FQ_BASE(device_addr)) -+ -+/* Largest value that the FQD's OAL field can hold. -+ * This is DPAA-1.x specific. -+ * TODO: This rather belongs in fsl_qman.h -+ */ -+#define FSL_QMAN_MAX_OAL 127 -+ -+/* Maximum offset value for a contig or sg FD (represented on 9 bits) */ -+#define DPA_MAX_FD_OFFSET ((1 << 9) - 1) -+ -+/* Default alignment for start of data in an Rx FD */ -+#define DPA_FD_DATA_ALIGNMENT 16 -+ -+/* Values for the L3R field of the FM Parse Results -+ */ -+/* L3 Type field: First IP Present IPv4 */ -+#define FM_L3_PARSE_RESULT_IPV4 0x8000 -+/* L3 Type field: First IP Present IPv6 */ -+#define FM_L3_PARSE_RESULT_IPV6 0x4000 -+ -+/* Values for the L4R field of the FM Parse Results -+ * See $8.8.4.7.20 - L4 HXS - L4 Results from DPAA-Rev2 Reference Manual. -+ */ -+/* L4 Type field: UDP */ -+#define FM_L4_PARSE_RESULT_UDP 0x40 -+/* L4 Type field: TCP */ -+#define FM_L4_PARSE_RESULT_TCP 0x20 -+/* FD status field indicating whether the FM Parser has attempted to validate -+ * the L4 csum of the frame. -+ * Note that having this bit set doesn't necessarily imply that the checksum -+ * is valid. One would have to check the parse results to find that out. -+ */ -+#define FM_FD_STAT_L4CV 0x00000004 -+ -+ -+#define FM_FD_STAT_ERR_PHYSICAL FM_PORT_FRM_ERR_PHYSICAL -+ -+/* Check if the parsed frame was found to be a TCP segment. -+ * -+ * @parse_result_ptr must be of type (fm_prs_result_t *). -+ */ -+#define fm_l4_frame_is_tcp(parse_result_ptr) \ -+ ((parse_result_ptr)->l4r & FM_L4_PARSE_RESULT_TCP) -+ -+/* number of Tx queues to FMan */ -+#ifdef CONFIG_FMAN_PFC -+#define DPAA_ETH_TX_QUEUES (NR_CPUS * CONFIG_FMAN_PFC_COS_COUNT) -+#else -+#define DPAA_ETH_TX_QUEUES NR_CPUS -+#endif -+ -+#define DPAA_ETH_RX_QUEUES 128 -+ -+/* Convenience macros for storing/retrieving the skb back-pointers. They must -+ * accommodate both recycling and confirmation paths - i.e. cases when the buf -+ * was allocated by ourselves, respectively by the stack. In the former case, -+ * we could store the skb at negative offset; in the latter case, we can't, -+ * so we'll use 0 as offset. -+ * -+ * NB: @off is an offset from a (struct sk_buff **) pointer! -+ */ -+#define DPA_WRITE_SKB_PTR(skb, skbh, addr, off) \ -+{ \ -+ skbh = (struct sk_buff **)addr; \ -+ *(skbh + (off)) = skb; \ -+} -+#define DPA_READ_SKB_PTR(skb, skbh, addr, off) \ -+{ \ -+ skbh = (struct sk_buff **)addr; \ -+ skb = *(skbh + (off)); \ -+} -+ -+#ifdef CONFIG_PM -+/* Magic Packet wakeup */ -+#define DPAA_WOL_MAGIC 0x00000001 -+#endif -+ -+#if defined(CONFIG_FSL_SDK_FMAN_TEST) -+struct pcd_range { -+ uint32_t base; -+ uint32_t count; -+}; -+#endif -+ -+/* More detailed FQ types - used for fine-grained WQ assignments */ -+enum dpa_fq_type { -+ FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */ -+ FQ_TYPE_RX_ERROR, /* Rx Error FQs */ -+ FQ_TYPE_RX_PCD, /* User-defined PCDs */ -+ FQ_TYPE_TX, /* "Real" Tx FQs */ -+ FQ_TYPE_TX_CONFIRM, /* Tx default Conf FQ (actually an Rx FQ) */ -+ FQ_TYPE_TX_CONF_MQ, /* Tx conf FQs (one for each Tx FQ) */ -+ FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */ -+ FQ_TYPE_RX_PCD_HI_PRIO, /* User-defined high-priority PCDs */ -+}; -+ -+struct dpa_fq { -+ struct qman_fq fq_base; -+ struct list_head list; -+ struct net_device *net_dev; -+ bool init; -+ uint32_t fqid; -+ uint32_t flags; -+ uint16_t channel; -+ uint8_t wq; -+ enum dpa_fq_type fq_type; -+}; -+ -+struct dpa_fq_cbs_t { -+ struct qman_fq rx_defq; -+ struct qman_fq tx_defq; -+ struct qman_fq rx_errq; -+ struct qman_fq tx_errq; -+ struct qman_fq egress_ern; -+}; -+ -+struct fqid_cell { -+ uint32_t start; -+ uint32_t count; -+}; -+ -+struct dpa_bp { -+ struct bman_pool *pool; -+ uint8_t bpid; -+ struct device *dev; -+ union { -+ /* The buffer pools used for the private ports are initialized -+ * with target_count buffers for each CPU; at runtime the -+ * number of buffers per CPU is constantly brought back to this -+ * level -+ */ -+ int target_count; -+ /* The configured value for the number of buffers in the pool, -+ * used for shared port buffer pools -+ */ -+ int config_count; -+ }; -+ size_t size; -+ bool seed_pool; -+ /* physical address of the contiguous memory used by the pool to store -+ * the buffers -+ */ -+ dma_addr_t paddr; -+ /* virtual address of the contiguous memory used by the pool to store -+ * the buffers -+ */ -+ void __iomem *vaddr; -+ /* current number of buffers in the bpool alloted to this CPU */ -+ int __percpu *percpu_count; -+ atomic_t refs; -+ /* some bpools need to be seeded before use by this cb */ -+ int (*seed_cb)(struct dpa_bp *); -+ /* some bpools need to be emptied before freeing; this cb is used -+ * for freeing of individual buffers taken from the pool -+ */ -+ void (*free_buf_cb)(void *addr); -+}; -+ -+struct dpa_rx_errors { -+ u64 dme; /* DMA Error */ -+ u64 fpe; /* Frame Physical Error */ -+ u64 fse; /* Frame Size Error */ -+ u64 phe; /* Header Error */ -+ u64 cse; /* Checksum Validation Error */ -+}; -+ -+/* Counters for QMan ERN frames - one counter per rejection code */ -+struct dpa_ern_cnt { -+ u64 cg_tdrop; /* Congestion group taildrop */ -+ u64 wred; /* WRED congestion */ -+ u64 err_cond; /* Error condition */ -+ u64 early_window; /* Order restoration, frame too early */ -+ u64 late_window; /* Order restoration, frame too late */ -+ u64 fq_tdrop; /* FQ taildrop */ -+ u64 fq_retired; /* FQ is retired */ -+ u64 orp_zero; /* ORP disabled */ -+}; -+ -+struct dpa_napi_portal { -+ struct napi_struct napi; -+ struct qman_portal *p; -+}; -+ -+struct dpa_percpu_priv_s { -+ struct net_device *net_dev; -+ struct dpa_napi_portal *np; -+ u64 in_interrupt; -+ u64 tx_returned; -+ u64 tx_confirm; -+ /* fragmented (non-linear) skbuffs received from the stack */ -+ u64 tx_frag_skbuffs; -+ /* number of S/G frames received */ -+ u64 rx_sg; -+ -+ struct rtnl_link_stats64 stats; -+ struct dpa_rx_errors rx_errors; -+ struct dpa_ern_cnt ern_cnt; -+}; -+ -+struct dpa_priv_s { -+ struct dpa_percpu_priv_s __percpu *percpu_priv; -+ struct dpa_bp *dpa_bp; -+ /* Store here the needed Tx headroom for convenience and speed -+ * (even though it can be computed based on the fields of buf_layout) -+ */ -+ uint16_t tx_headroom; -+ struct net_device *net_dev; -+ struct mac_device *mac_dev; -+ struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES]; -+ struct qman_fq *conf_fqs[DPAA_ETH_TX_QUEUES]; -+ -+ size_t bp_count; -+ -+ uint16_t channel; /* "fsl,qman-channel-id" */ -+ struct list_head dpa_fq_list; -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+ struct dentry *debugfs_loop_file; -+#endif -+ -+ uint32_t msg_enable; /* net_device message level */ -+#ifdef CONFIG_FSL_DPAA_1588 -+ struct dpa_ptp_tsu *tsu; -+#endif -+ -+#if defined(CONFIG_FSL_SDK_FMAN_TEST) -+/* TODO: this is temporary until pcd support is implemented in dpaa */ -+ int priv_pcd_num_ranges; -+ struct pcd_range priv_pcd_ranges[FMAN_PCD_TESTS_MAX_NUM_RANGES]; -+#endif -+ -+ struct { -+ /** -+ * All egress queues to a given net device belong to one -+ * (and the same) congestion group. -+ */ -+ struct qman_cgr cgr; -+ /* If congested, when it began. Used for performance stats. */ -+ u32 congestion_start_jiffies; -+ /* Number of jiffies the Tx port was congested. */ -+ u32 congested_jiffies; -+ /** -+ * Counter for the number of times the CGR -+ * entered congestion state -+ */ -+ u32 cgr_congested_count; -+ } cgr_data; -+ /* Use a per-port CGR for ingress traffic. */ -+ bool use_ingress_cgr; -+ struct qman_cgr ingress_cgr; -+ -+#ifdef CONFIG_FSL_DPAA_TS -+ bool ts_tx_en; /* Tx timestamping enabled */ -+ bool ts_rx_en; /* Rx timestamping enabled */ -+#endif /* CONFIG_FSL_DPAA_TS */ -+ -+ struct dpa_buffer_layout_s *buf_layout; -+ uint16_t rx_headroom; -+ char if_type[30]; -+ -+ void *peer; -+#ifdef CONFIG_PM -+ u32 wol; -+#endif -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+ int loop_id; -+ int loop_to; -+#endif -+#ifdef CONFIG_FSL_DPAA_CEETM -+ bool ceetm_en; /* CEETM QoS enabled */ -+#endif -+}; -+ -+struct fm_port_fqs { -+ struct dpa_fq *tx_defq; -+ struct dpa_fq *tx_errq; -+ struct dpa_fq *rx_defq; -+ struct dpa_fq *rx_errq; -+}; -+ -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+extern struct net_device *dpa_loop_netdevs[20]; -+#endif -+ -+/* functions with different implementation for SG and non-SG: */ -+int dpa_bp_priv_seed(struct dpa_bp *dpa_bp); -+int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *count_ptr); -+void __hot _dpa_rx(struct net_device *net_dev, -+ struct qman_portal *portal, -+ const struct dpa_priv_s *priv, -+ struct dpa_percpu_priv_s *percpu_priv, -+ const struct qm_fd *fd, -+ u32 fqid, -+ int *count_ptr); -+int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev); -+int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev, -+ struct qman_fq *egress_fq, struct qman_fq *conf_fq); -+struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv, -+ const struct qm_fd *fd); -+void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results, -+ const struct qm_fd *fd, -+ struct sk_buff *skb, -+ int *use_gro); -+#ifndef CONFIG_FSL_DPAA_TS -+bool dpa_skb_is_recyclable(struct sk_buff *skb); -+bool dpa_buf_is_recyclable(struct sk_buff *skb, -+ uint32_t min_size, -+ uint16_t min_offset, -+ unsigned char **new_buf_start); -+#endif -+int __hot skb_to_contig_fd(struct dpa_priv_s *priv, -+ struct sk_buff *skb, struct qm_fd *fd, -+ int *count_ptr, int *offset); -+int __hot skb_to_sg_fd(struct dpa_priv_s *priv, -+ struct sk_buff *skb, struct qm_fd *fd); -+int __cold __attribute__((nonnull)) -+ _dpa_fq_free(struct device *dev, struct qman_fq *fq); -+ -+/* Turn on HW checksum computation for this outgoing frame. -+ * If the current protocol is not something we support in this regard -+ * (or if the stack has already computed the SW checksum), we do nothing. -+ * -+ * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value -+ * otherwise. -+ * -+ * Note that this function may modify the fd->cmd field and the skb data buffer -+ * (the Parse Results area). -+ */ -+int dpa_enable_tx_csum(struct dpa_priv_s *priv, -+ struct sk_buff *skb, struct qm_fd *fd, char *parse_results); -+ -+static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv, -+ struct qman_portal *portal) -+{ -+ /* In case of threaded ISR for RT enable kernel, -+ * in_irq() does not return appropriate value, so use -+ * in_serving_softirq to distinguish softirq or irq context. -+ */ -+ if (unlikely(in_irq() || !in_serving_softirq())) { -+ /* Disable QMan IRQ and invoke NAPI */ -+ int ret = qman_p_irqsource_remove(portal, QM_PIRQ_DQRI); -+ if (likely(!ret)) { -+ const struct qman_portal_config *pc = -+ qman_p_get_portal_config(portal); -+ struct dpa_napi_portal *np = -+ &percpu_priv->np[pc->index]; -+ -+ np->p = portal; -+ napi_schedule(&np->napi); -+ percpu_priv->in_interrupt++; -+ return 1; -+ } -+ } -+ return 0; -+} -+ -+static inline ssize_t __const __must_check __attribute__((nonnull)) -+dpa_fd_length(const struct qm_fd *fd) -+{ -+ return fd->length20; -+} -+ -+static inline ssize_t __const __must_check __attribute__((nonnull)) -+dpa_fd_offset(const struct qm_fd *fd) -+{ -+ return fd->offset; -+} -+ -+/* Verifies if the skb length is below the interface MTU */ -+static inline int dpa_check_rx_mtu(struct sk_buff *skb, int mtu) -+{ -+ if (unlikely(skb->len > mtu)) -+ if ((skb->protocol != htons(ETH_P_8021Q)) -+ || (skb->len > mtu + 4)) -+ return -1; -+ -+ return 0; -+} -+ -+static inline uint16_t dpa_get_headroom(struct dpa_buffer_layout_s *bl) -+{ -+ uint16_t headroom; -+ /* The frame headroom must accommodate: -+ * - the driver private data area -+ * - parse results, hash results, timestamp if selected -+ * - manip extra space -+ * If either hash results or time stamp are selected, both will -+ * be copied to/from the frame headroom, as TS is located between PR and -+ * HR in the IC and IC copy size has a granularity of 16bytes -+ * (see description of FMBM_RICP and FMBM_TICP registers in DPAARM) -+ * -+ * Also make sure the headroom is a multiple of data_align bytes -+ */ -+ headroom = (uint16_t)(bl->priv_data_size + -+ (bl->parse_results ? DPA_PARSE_RESULTS_SIZE : 0) + -+ (bl->hash_results || bl->time_stamp ? -+ DPA_TIME_STAMP_SIZE + DPA_HASH_RESULTS_SIZE : 0) + -+ bl->manip_extra_space); -+ -+ return bl->data_align ? ALIGN(headroom, bl->data_align) : headroom; -+} -+ -+int fm_mac_dump_regs(struct mac_device *h_dev, char *buf, int n); -+int fm_mac_dump_rx_stats(struct mac_device *h_dev, char *buf, int n); -+int fm_mac_dump_tx_stats(struct mac_device *h_dev, char *buf, int n); -+ -+void dpaa_eth_sysfs_remove(struct device *dev); -+void dpaa_eth_sysfs_init(struct device *dev); -+int dpaa_eth_poll(struct napi_struct *napi, int budget); -+ -+void dpa_private_napi_del(struct net_device *net_dev); -+ -+/* Equivalent to a memset(0), but works faster */ -+static inline void clear_fd(struct qm_fd *fd) -+{ -+ fd->opaque_addr = 0; -+ fd->opaque = 0; -+ fd->cmd = 0; -+} -+ -+static inline int _dpa_tx_fq_to_id(const struct dpa_priv_s *priv, -+ struct qman_fq *tx_fq) -+{ -+ int i; -+ -+ for (i = 0; i < DPAA_ETH_TX_QUEUES; i++) -+ if (priv->egress_fqs[i] == tx_fq) -+ return i; -+ -+ return -EINVAL; -+} -+ -+static inline int __hot dpa_xmit(struct dpa_priv_s *priv, -+ struct rtnl_link_stats64 *percpu_stats, -+ struct qm_fd *fd, struct qman_fq *egress_fq, -+ struct qman_fq *conf_fq) -+{ -+ int err, i; -+ -+ if (fd->bpid == 0xff) -+ fd->cmd |= qman_fq_fqid(conf_fq); -+ -+ /* Trace this Tx fd */ -+ trace_dpa_tx_fd(priv->net_dev, egress_fq, fd); -+ -+ for (i = 0; i < 100000; i++) { -+ err = qman_enqueue(egress_fq, fd, 0); -+ if (err != -EBUSY) -+ break; -+ } -+ -+ if (unlikely(err < 0)) { -+ /* TODO differentiate b/w -EBUSY (EQCR full) and other codes? */ -+ percpu_stats->tx_errors++; -+ percpu_stats->tx_fifo_errors++; -+ return err; -+ } -+ -+ percpu_stats->tx_packets++; -+ percpu_stats->tx_bytes += dpa_fd_length(fd); -+ -+ return 0; -+} -+ -+/* Use multiple WQs for FQ assignment: -+ * - Tx Confirmation queues go to WQ1. -+ * - Rx Default, Tx and PCD queues go to WQ3 (no differentiation between -+ * Rx and Tx traffic, or between Rx Default and Rx PCD frames). -+ * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance -+ * to be scheduled, in case there are many more FQs in WQ3). -+ * This ensures that Tx-confirmed buffers are timely released. In particular, -+ * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they -+ * are greatly outnumbered by other FQs in the system (usually PCDs), while -+ * dequeue scheduling is round-robin. -+ */ -+static inline void _dpa_assign_wq(struct dpa_fq *fq) -+{ -+ switch (fq->fq_type) { -+ case FQ_TYPE_TX_CONFIRM: -+ case FQ_TYPE_TX_CONF_MQ: -+ fq->wq = 1; -+ break; -+ case FQ_TYPE_RX_DEFAULT: -+ case FQ_TYPE_TX: -+ fq->wq = 3; -+ break; -+ case FQ_TYPE_RX_ERROR: -+ case FQ_TYPE_TX_ERROR: -+ case FQ_TYPE_RX_PCD_HI_PRIO: -+ fq->wq = 2; -+ break; -+ case FQ_TYPE_RX_PCD: -+ fq->wq = 5; -+ break; -+ default: -+ WARN(1, "Invalid FQ type %d for FQID %d!\n", -+ fq->fq_type, fq->fqid); -+ } -+} -+ -+#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -+/* Use in lieu of skb_get_queue_mapping() */ -+#ifdef CONFIG_FMAN_PFC -+#define dpa_get_queue_mapping(skb) \ -+ (((skb)->priority < CONFIG_FMAN_PFC_COS_COUNT) ? \ -+ ((skb)->priority * dpa_num_cpus + smp_processor_id()) : \ -+ ((CONFIG_FMAN_PFC_COS_COUNT - 1) * \ -+ dpa_num_cpus + smp_processor_id())); -+ -+#else -+#define dpa_get_queue_mapping(skb) \ -+ raw_smp_processor_id() -+#endif -+#else -+/* Use the queue selected by XPS */ -+#define dpa_get_queue_mapping(skb) \ -+ skb_get_queue_mapping(skb) -+#endif -+ -+#ifdef CONFIG_PTP_1588_CLOCK_DPAA -+struct ptp_priv_s { -+ struct device_node *node; -+ struct platform_device *of_dev; -+ struct mac_device *mac_dev; -+}; -+extern struct ptp_priv_s ptp_priv; -+#endif -+ -+static inline void _dpa_bp_free_pf(void *addr) -+{ -+ put_page(virt_to_head_page(addr)); -+} -+ -+/* TODO: LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue -+ * manifests itself at high traffic rates when frames exceed 4K memory -+ * boundaries; For the moment, we use a SW workaround to avoid frames larger -+ * than 4K or that exceed 4K alignments. -+ */ -+ -+#ifndef CONFIG_PPC -+extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */ -+ -+#define HAS_DMA_ISSUE(start, size) \ -+ (((u64)(start) + (size)) > (((u64)(start) + 0x1000) & ~0xFFF)) -+#define BOUNDARY_4K(start, size) (((u64)(start) + (u64)(size)) & ~0xFFF) -+ -+#endif /* !CONFIG_PPC */ -+ -+#endif /* __DPA_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c -@@ -0,0 +1,263 @@ -+/* Copyright 2008-2013 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifdef CONFIG_FSL_DPAA_ETH_DEBUG -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+#else -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": " fmt -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "dpaa_eth.h" -+#include "dpaa_eth_common.h" -+#include "dpaa_eth_base.h" -+ -+#define DPA_DESCRIPTION "FSL DPAA Advanced drivers:" -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+ -+uint8_t advanced_debug = -1; -+module_param(advanced_debug, byte, S_IRUGO); -+MODULE_PARM_DESC(advanced_debug, "Module/Driver verbosity level"); -+EXPORT_SYMBOL(advanced_debug); -+ -+static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1) -+{ -+ return ((struct dpa_bp *)dpa_bp0)->size - -+ ((struct dpa_bp *)dpa_bp1)->size; -+} -+ -+struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */ -+dpa_bp_probe(struct platform_device *_of_dev, size_t *count) -+{ -+ int i, lenp, na, ns, err; -+ struct device *dev; -+ struct device_node *dev_node; -+ const __be32 *bpool_cfg; -+ struct dpa_bp *dpa_bp; -+ u32 bpid; -+ -+ dev = &_of_dev->dev; -+ -+ *count = of_count_phandle_with_args(dev->of_node, -+ "fsl,bman-buffer-pools", NULL); -+ if (*count < 1) { -+ dev_err(dev, "missing fsl,bman-buffer-pools device tree entry\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL); -+ if (dpa_bp == NULL) { -+ dev_err(dev, "devm_kzalloc() failed\n"); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ dev_node = of_find_node_by_path("/"); -+ if (unlikely(dev_node == NULL)) { -+ dev_err(dev, "of_find_node_by_path(/) failed\n"); -+ return ERR_PTR(-EINVAL); -+ } -+ -+ na = of_n_addr_cells(dev_node); -+ ns = of_n_size_cells(dev_node); -+ -+ for (i = 0; i < *count; i++) { -+ of_node_put(dev_node); -+ -+ dev_node = of_parse_phandle(dev->of_node, -+ "fsl,bman-buffer-pools", i); -+ if (dev_node == NULL) { -+ dev_err(dev, "of_find_node_by_phandle() failed\n"); -+ return ERR_PTR(-EFAULT); -+ } -+ -+ if (unlikely(!of_device_is_compatible(dev_node, "fsl,bpool"))) { -+ dev_err(dev, -+ "!of_device_is_compatible(%s, fsl,bpool)\n", -+ dev_node->full_name); -+ dpa_bp = ERR_PTR(-EINVAL); -+ goto _return_of_node_put; -+ } -+ -+ err = of_property_read_u32(dev_node, "fsl,bpid", &bpid); -+ if (err) { -+ dev_err(dev, "Cannot find buffer pool ID in the device tree\n"); -+ dpa_bp = ERR_PTR(-EINVAL); -+ goto _return_of_node_put; -+ } -+ dpa_bp[i].bpid = (uint8_t)bpid; -+ -+ bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg", -+ &lenp); -+ if (bpool_cfg && (lenp == (2 * ns + na) * sizeof(*bpool_cfg))) { -+ const uint32_t *seed_pool; -+ -+ dpa_bp[i].config_count = -+ (int)of_read_number(bpool_cfg, ns); -+ dpa_bp[i].size = -+ (size_t)of_read_number(bpool_cfg + ns, ns); -+ dpa_bp[i].paddr = -+ of_read_number(bpool_cfg + 2 * ns, na); -+ -+ seed_pool = of_get_property(dev_node, -+ "fsl,bpool-ethernet-seeds", &lenp); -+ dpa_bp[i].seed_pool = !!seed_pool; -+ -+ } else { -+ dev_err(dev, -+ "Missing/invalid fsl,bpool-ethernet-cfg device tree entry for node %s\n", -+ dev_node->full_name); -+ dpa_bp = ERR_PTR(-EINVAL); -+ goto _return_of_node_put; -+ } -+ } -+ -+ sort(dpa_bp, *count, sizeof(*dpa_bp), dpa_bp_cmp, NULL); -+ -+ return dpa_bp; -+ -+_return_of_node_put: -+ if (dev_node) -+ of_node_put(dev_node); -+ -+ return dpa_bp; -+} -+EXPORT_SYMBOL(dpa_bp_probe); -+ -+int dpa_bp_shared_port_seed(struct dpa_bp *bp) -+{ -+ void __iomem **ptr; -+ -+ /* In MAC-less and Shared-MAC scenarios the physical -+ * address of the buffer pool in device tree is set -+ * to 0 to specify that another entity (USDPAA) will -+ * allocate and seed the buffers -+ */ -+ if (!bp->paddr) -+ return 0; -+ -+ /* allocate memory region for buffers */ -+ devm_request_mem_region(bp->dev, bp->paddr, -+ bp->size * bp->config_count, KBUILD_MODNAME); -+ /* managed ioremap unmapping */ -+ ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); -+ if (!ptr) -+ return -EIO; -+#ifndef CONFIG_PPC -+ bp->vaddr = ioremap_cache_ns(bp->paddr, bp->size * bp->config_count); -+#else -+ bp->vaddr = ioremap_prot(bp->paddr, bp->size * bp->config_count, 0); -+#endif -+ if (bp->vaddr == NULL) { -+ pr_err("Could not map memory for pool %d\n", bp->bpid); -+ devres_free(ptr); -+ return -EIO; -+ } -+ *ptr = bp->vaddr; -+ devres_add(bp->dev, ptr); -+ -+ /* seed pool with buffers from that memory region */ -+ if (bp->seed_pool) { -+ int count = bp->target_count; -+ dma_addr_t addr = bp->paddr; -+ -+ while (count) { -+ struct bm_buffer bufs[8]; -+ uint8_t num_bufs = 0; -+ -+ do { -+ BUG_ON(addr > 0xffffffffffffull); -+ bufs[num_bufs].bpid = bp->bpid; -+ bm_buffer_set64(&bufs[num_bufs++], addr); -+ addr += bp->size; -+ -+ } while (--count && (num_bufs < 8)); -+ -+ while (bman_release(bp->pool, bufs, num_bufs, 0)) -+ cpu_relax(); -+ } -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(dpa_bp_shared_port_seed); -+ -+int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp, -+ size_t count) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ int i; -+ -+ priv->dpa_bp = dpa_bp; -+ priv->bp_count = count; -+ -+ for (i = 0; i < count; i++) { -+ int err; -+ err = dpa_bp_alloc(&dpa_bp[i]); -+ if (err < 0) { -+ dpa_bp_free(priv); -+ priv->dpa_bp = NULL; -+ return err; -+ } -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(dpa_bp_create); -+ -+static int __init __cold dpa_advanced_load(void) -+{ -+ pr_info(DPA_DESCRIPTION "\n"); -+ -+ return 0; -+} -+module_init(dpa_advanced_load); -+ -+static void __exit __cold dpa_advanced_unload(void) -+{ -+ pr_debug(KBUILD_MODNAME ": -> %s:%s()\n", -+ KBUILD_BASENAME".c", __func__); -+ -+} -+module_exit(dpa_advanced_unload); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h -@@ -0,0 +1,50 @@ -+/* Copyright 2008-2013 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __DPAA_ETH_BASE_H -+#define __DPAA_ETH_BASE_H -+ -+#include /* struct net_device */ -+#include /* struct bm_buffer */ -+#include /* struct platform_device */ -+#include /* struct hwtstamp_config */ -+ -+extern uint8_t advanced_debug; -+extern const struct dpa_fq_cbs_t shared_fq_cbs; -+extern int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev); -+ -+struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */ -+dpa_bp_probe(struct platform_device *_of_dev, size_t *count); -+int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp, -+ size_t count); -+int dpa_bp_shared_port_seed(struct dpa_bp *bp); -+ -+#endif /* __DPAA_ETH_BASE_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -0,0 +1,1991 @@ -+/* Copyright 2008-2016 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include "dpaa_eth_ceetm.h" -+ -+#define DPA_CEETM_DESCRIPTION "FSL DPAA CEETM qdisc" -+ -+const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1] = { -+ [TCA_CEETM_COPT] = { .len = sizeof(struct tc_ceetm_copt) }, -+ [TCA_CEETM_QOPS] = { .len = sizeof(struct tc_ceetm_qopt) }, -+}; -+ -+struct Qdisc_ops ceetm_qdisc_ops; -+ -+/* Obtain the DCP and the SP ids from the FMan port */ -+static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id, -+ unsigned int *sp_id) -+{ -+ uint32_t channel; -+ t_LnxWrpFmPortDev *port_dev; -+ struct dpa_priv_s *dpa_priv = netdev_priv(dev); -+ struct mac_device *mac_dev = dpa_priv->mac_dev; -+ -+ port_dev = (t_LnxWrpFmPortDev *)mac_dev->port_dev[TX]; -+ channel = port_dev->txCh; -+ -+ *sp_id = channel & CHANNEL_SP_MASK; -+ pr_debug(KBUILD_BASENAME " : FM sub-portal ID %d\n", *sp_id); -+ -+ if (channel < DCP0_MAX_CHANNEL) { -+ *dcp_id = qm_dc_portal_fman0; -+ pr_debug(KBUILD_BASENAME " : DCP ID 0\n"); -+ } else { -+ *dcp_id = qm_dc_portal_fman1; -+ pr_debug(KBUILD_BASENAME " : DCP ID 1\n"); -+ } -+} -+ -+/* Enqueue Rejection Notification callback */ -+static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq, -+ const struct qm_mr_entry *msg) -+{ -+ struct net_device *net_dev; -+ struct ceetm_class *cls; -+ struct ceetm_class_stats *cstats = NULL; -+ const struct dpa_priv_s *dpa_priv; -+ struct dpa_percpu_priv_s *dpa_percpu_priv; -+ struct sk_buff *skb; -+ struct qm_fd fd = msg->ern.fd; -+ -+ net_dev = ((struct ceetm_fq *)fq)->net_dev; -+ dpa_priv = netdev_priv(net_dev); -+ dpa_percpu_priv = raw_cpu_ptr(dpa_priv->percpu_priv); -+ -+ /* Increment DPA counters */ -+ dpa_percpu_priv->stats.tx_dropped++; -+ dpa_percpu_priv->stats.tx_fifo_errors++; -+ -+ /* Increment CEETM counters */ -+ cls = ((struct ceetm_fq *)fq)->ceetm_cls; -+ switch (cls->type) { -+ case CEETM_PRIO: -+ cstats = this_cpu_ptr(cls->prio.cstats); -+ break; -+ case CEETM_WBFS: -+ cstats = this_cpu_ptr(cls->wbfs.cstats); -+ break; -+ } -+ -+ if (cstats) -+ cstats->ern_drop_count++; -+ -+ if (fd.bpid != 0xff) { -+ dpa_fd_release(net_dev, &fd); -+ return; -+ } -+ -+ skb = _dpa_cleanup_tx_fd(dpa_priv, &fd); -+ dev_kfree_skb_any(skb); -+} -+ -+/* Congestion State Change Notification callback */ -+static void ceetm_cscn(struct qm_ceetm_ccg *ccg, void *cb_ctx, int congested) -+{ -+ struct ceetm_fq *ceetm_fq = (struct ceetm_fq *)cb_ctx; -+ struct dpa_priv_s *dpa_priv = netdev_priv(ceetm_fq->net_dev); -+ struct ceetm_class *cls = ceetm_fq->ceetm_cls; -+ struct ceetm_class_stats *cstats = NULL; -+ -+ switch (cls->type) { -+ case CEETM_PRIO: -+ cstats = this_cpu_ptr(cls->prio.cstats); -+ break; -+ case CEETM_WBFS: -+ cstats = this_cpu_ptr(cls->wbfs.cstats); -+ break; -+ } -+ -+ if (congested) { -+ dpa_priv->cgr_data.congestion_start_jiffies = jiffies; -+ netif_tx_stop_all_queues(dpa_priv->net_dev); -+ dpa_priv->cgr_data.cgr_congested_count++; -+ if (cstats) -+ cstats->congested_count++; -+ } else { -+ dpa_priv->cgr_data.congested_jiffies += -+ (jiffies - dpa_priv->cgr_data.congestion_start_jiffies); -+ netif_tx_wake_all_queues(dpa_priv->net_dev); -+ } -+} -+ -+/* Allocate a ceetm fq */ -+static int ceetm_alloc_fq(struct ceetm_fq **fq, struct net_device *dev, -+ struct ceetm_class *cls) -+{ -+ *fq = kzalloc(sizeof(**fq), GFP_KERNEL); -+ if (!*fq) -+ return -ENOMEM; -+ -+ (*fq)->net_dev = dev; -+ (*fq)->ceetm_cls = cls; -+ return 0; -+} -+ -+/* Configure a ceetm Class Congestion Group */ -+static int ceetm_config_ccg(struct qm_ceetm_ccg **ccg, -+ struct qm_ceetm_channel *channel, unsigned int id, -+ struct ceetm_fq *fq, struct dpa_priv_s *dpa_priv) -+{ -+ int err; -+ u32 cs_th; -+ u16 ccg_mask; -+ struct qm_ceetm_ccg_params ccg_params; -+ -+ err = qman_ceetm_ccg_claim(ccg, channel, id, ceetm_cscn, fq); -+ if (err) -+ return err; -+ -+ /* Configure the count mode (frames/bytes), enable congestion state -+ * notifications, configure the congestion entry and exit thresholds, -+ * enable tail-drop, configure the tail-drop mode, and set the -+ * overhead accounting limit -+ */ -+ ccg_mask = QM_CCGR_WE_MODE | -+ QM_CCGR_WE_CSCN_EN | -+ QM_CCGR_WE_CS_THRES_IN | QM_CCGR_WE_CS_THRES_OUT | -+ QM_CCGR_WE_TD_EN | QM_CCGR_WE_TD_MODE | -+ QM_CCGR_WE_OAL; -+ -+ ccg_params.mode = 0; /* count bytes */ -+ ccg_params.cscn_en = 1; /* generate notifications */ -+ ccg_params.td_en = 1; /* enable tail-drop */ -+ ccg_params.td_mode = 0; /* tail-drop on congestion state */ -+ ccg_params.oal = (signed char)(min(sizeof(struct sk_buff) + -+ dpa_priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL)); -+ -+ /* Set the congestion state thresholds according to the link speed */ -+ if (dpa_priv->mac_dev->if_support & SUPPORTED_10000baseT_Full) -+ cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G; -+ else -+ cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G; -+ -+ qm_cgr_cs_thres_set64(&ccg_params.cs_thres_in, cs_th, 1); -+ qm_cgr_cs_thres_set64(&ccg_params.cs_thres_out, -+ cs_th * CEETM_CCGR_RATIO, 1); -+ -+ err = qman_ceetm_ccg_set(*ccg, ccg_mask, &ccg_params); -+ if (err) -+ return err; -+ -+ return 0; -+} -+ -+/* Configure a ceetm Logical Frame Queue */ -+static int ceetm_config_lfq(struct qm_ceetm_cq *cq, struct ceetm_fq *fq, -+ struct qm_ceetm_lfq **lfq) -+{ -+ int err; -+ u64 context_a; -+ u32 context_b; -+ -+ err = qman_ceetm_lfq_claim(lfq, cq); -+ if (err) -+ return err; -+ -+ /* Get the former contexts in order to preserve context B */ -+ err = qman_ceetm_lfq_get_context(*lfq, &context_a, &context_b); -+ if (err) -+ return err; -+ -+ context_a = CEETM_CONTEXT_A; -+ err = qman_ceetm_lfq_set_context(*lfq, context_a, context_b); -+ if (err) -+ return err; -+ -+ (*lfq)->ern = ceetm_ern; -+ -+ err = qman_ceetm_create_fq(*lfq, &fq->fq); -+ if (err) -+ return err; -+ -+ return 0; -+} -+ -+/* Configure a prio ceetm class */ -+static int ceetm_config_prio_cls(struct ceetm_class *cls, -+ struct net_device *dev, -+ struct qm_ceetm_channel *channel, -+ unsigned int id) -+{ -+ int err; -+ struct dpa_priv_s *dpa_priv = netdev_priv(dev); -+ -+ err = ceetm_alloc_fq(&cls->prio.fq, dev, cls); -+ if (err) -+ return err; -+ -+ /* Claim and configure the CCG */ -+ err = ceetm_config_ccg(&cls->prio.ccg, channel, id, cls->prio.fq, -+ dpa_priv); -+ if (err) -+ return err; -+ -+ /* Claim and configure the CQ */ -+ err = qman_ceetm_cq_claim(&cls->prio.cq, channel, id, cls->prio.ccg); -+ if (err) -+ return err; -+ -+ if (cls->shaped) { -+ err = qman_ceetm_channel_set_cq_cr_eligibility(channel, id, 1); -+ if (err) -+ return err; -+ -+ err = qman_ceetm_channel_set_cq_er_eligibility(channel, id, 1); -+ if (err) -+ return err; -+ } -+ -+ /* Claim and configure a LFQ */ -+ err = ceetm_config_lfq(cls->prio.cq, cls->prio.fq, &cls->prio.lfq); -+ if (err) -+ return err; -+ -+ return 0; -+} -+ -+/* Configure a wbfs ceetm class */ -+static int ceetm_config_wbfs_cls(struct ceetm_class *cls, -+ struct net_device *dev, -+ struct qm_ceetm_channel *channel, -+ unsigned int id, int type) -+{ -+ int err; -+ struct dpa_priv_s *dpa_priv = netdev_priv(dev); -+ -+ err = ceetm_alloc_fq(&cls->wbfs.fq, dev, cls); -+ if (err) -+ return err; -+ -+ /* Claim and configure the CCG */ -+ err = ceetm_config_ccg(&cls->wbfs.ccg, channel, id, cls->wbfs.fq, -+ dpa_priv); -+ if (err) -+ return err; -+ -+ /* Claim and configure the CQ */ -+ if (type == WBFS_GRP_B) -+ err = qman_ceetm_cq_claim_B(&cls->wbfs.cq, channel, id, -+ cls->wbfs.ccg); -+ else -+ err = qman_ceetm_cq_claim_A(&cls->wbfs.cq, channel, id, -+ cls->wbfs.ccg); -+ if (err) -+ return err; -+ -+ /* Configure the CQ weight: real number multiplied by 100 to get rid -+ * of the fraction -+ */ -+ err = qman_ceetm_set_queue_weight_in_ratio(cls->wbfs.cq, -+ cls->wbfs.weight * 100); -+ if (err) -+ return err; -+ -+ /* Claim and configure a LFQ */ -+ err = ceetm_config_lfq(cls->wbfs.cq, cls->wbfs.fq, &cls->wbfs.lfq); -+ if (err) -+ return err; -+ -+ return 0; -+} -+ -+/* Find class in qdisc hash table using given handle */ -+static inline struct ceetm_class *ceetm_find(u32 handle, struct Qdisc *sch) -+{ -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct Qdisc_class_common *clc; -+ -+ pr_debug(KBUILD_BASENAME " : %s : find class %X in qdisc %X\n", -+ __func__, handle, sch->handle); -+ -+ clc = qdisc_class_find(&priv->clhash, handle); -+ return clc ? container_of(clc, struct ceetm_class, common) : NULL; -+} -+ -+/* Insert a class in the qdisc's class hash */ -+static void ceetm_link_class(struct Qdisc *sch, -+ struct Qdisc_class_hash *clhash, -+ struct Qdisc_class_common *common) -+{ -+ sch_tree_lock(sch); -+ qdisc_class_hash_insert(clhash, common); -+ sch_tree_unlock(sch); -+ qdisc_class_hash_grow(sch, clhash); -+} -+ -+/* Destroy a ceetm class */ -+static void ceetm_cls_destroy(struct Qdisc *sch, struct ceetm_class *cl) -+{ -+ if (!cl) -+ return; -+ -+ pr_debug(KBUILD_BASENAME " : %s : destroy class %X from under %X\n", -+ __func__, cl->common.classid, sch->handle); -+ -+ switch (cl->type) { -+ case CEETM_ROOT: -+ if (cl->root.child) { -+ qdisc_destroy(cl->root.child); -+ cl->root.child = NULL; -+ } -+ -+ if (cl->root.ch && qman_ceetm_channel_release(cl->root.ch)) -+ pr_err(KBUILD_BASENAME -+ " : %s : error releasing the channel %d\n", -+ __func__, cl->root.ch->idx); -+ -+ break; -+ -+ case CEETM_PRIO: -+ if (cl->prio.child) { -+ qdisc_destroy(cl->prio.child); -+ cl->prio.child = NULL; -+ } -+ -+ if (cl->prio.lfq && qman_ceetm_lfq_release(cl->prio.lfq)) -+ pr_err(KBUILD_BASENAME -+ " : %s : error releasing the LFQ %d\n", -+ __func__, cl->prio.lfq->idx); -+ -+ if (cl->prio.cq && qman_ceetm_cq_release(cl->prio.cq)) -+ pr_err(KBUILD_BASENAME -+ " : %s : error releasing the CQ %d\n", -+ __func__, cl->prio.cq->idx); -+ -+ if (cl->prio.ccg && qman_ceetm_ccg_release(cl->prio.ccg)) -+ pr_err(KBUILD_BASENAME -+ " : %s : error releasing the CCG %d\n", -+ __func__, cl->prio.ccg->idx); -+ -+ kfree(cl->prio.fq); -+ -+ if (cl->prio.cstats) -+ free_percpu(cl->prio.cstats); -+ -+ break; -+ -+ case CEETM_WBFS: -+ if (cl->wbfs.lfq && qman_ceetm_lfq_release(cl->wbfs.lfq)) -+ pr_err(KBUILD_BASENAME -+ " : %s : error releasing the LFQ %d\n", -+ __func__, cl->wbfs.lfq->idx); -+ -+ if (cl->wbfs.cq && qman_ceetm_cq_release(cl->wbfs.cq)) -+ pr_err(KBUILD_BASENAME -+ " : %s : error releasing the CQ %d\n", -+ __func__, cl->wbfs.cq->idx); -+ -+ if (cl->wbfs.ccg && qman_ceetm_ccg_release(cl->wbfs.ccg)) -+ pr_err(KBUILD_BASENAME -+ " : %s : error releasing the CCG %d\n", -+ __func__, cl->wbfs.ccg->idx); -+ -+ kfree(cl->wbfs.fq); -+ -+ if (cl->wbfs.cstats) -+ free_percpu(cl->wbfs.cstats); -+ } -+ -+ tcf_destroy_chain(&cl->filter_list); -+ kfree(cl); -+} -+ -+/* Destroy a ceetm qdisc */ -+static void ceetm_destroy(struct Qdisc *sch) -+{ -+ unsigned int ntx, i; -+ struct hlist_node *next; -+ struct ceetm_class *cl; -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct net_device *dev = qdisc_dev(sch); -+ -+ pr_debug(KBUILD_BASENAME " : %s : destroy qdisc %X\n", -+ __func__, sch->handle); -+ -+ /* All filters need to be removed before destroying the classes */ -+ tcf_destroy_chain(&priv->filter_list); -+ -+ for (i = 0; i < priv->clhash.hashsize; i++) { -+ hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) -+ tcf_destroy_chain(&cl->filter_list); -+ } -+ -+ for (i = 0; i < priv->clhash.hashsize; i++) { -+ hlist_for_each_entry_safe(cl, next, &priv->clhash.hash[i], -+ common.hnode) -+ ceetm_cls_destroy(sch, cl); -+ } -+ -+ qdisc_class_hash_destroy(&priv->clhash); -+ -+ switch (priv->type) { -+ case CEETM_ROOT: -+ dpa_disable_ceetm(dev); -+ -+ if (priv->root.lni && qman_ceetm_lni_release(priv->root.lni)) -+ pr_err(KBUILD_BASENAME -+ " : %s : error releasing the LNI %d\n", -+ __func__, priv->root.lni->idx); -+ -+ if (priv->root.sp && qman_ceetm_sp_release(priv->root.sp)) -+ pr_err(KBUILD_BASENAME -+ " : %s : error releasing the SP %d\n", -+ __func__, priv->root.sp->idx); -+ -+ if (priv->root.qstats) -+ free_percpu(priv->root.qstats); -+ -+ if (!priv->root.qdiscs) -+ break; -+ -+ /* Remove the pfifo qdiscs */ -+ for (ntx = 0; ntx < dev->num_tx_queues; ntx++) -+ if (priv->root.qdiscs[ntx]) -+ qdisc_destroy(priv->root.qdiscs[ntx]); -+ -+ kfree(priv->root.qdiscs); -+ break; -+ -+ case CEETM_PRIO: -+ if (priv->prio.parent) -+ priv->prio.parent->root.child = NULL; -+ break; -+ -+ case CEETM_WBFS: -+ if (priv->wbfs.parent) -+ priv->wbfs.parent->prio.child = NULL; -+ break; -+ } -+} -+ -+static int ceetm_dump(struct Qdisc *sch, struct sk_buff *skb) -+{ -+ struct Qdisc *qdisc; -+ unsigned int ntx, i; -+ struct nlattr *nest; -+ struct tc_ceetm_qopt qopt; -+ struct ceetm_qdisc_stats *qstats; -+ struct net_device *dev = qdisc_dev(sch); -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ sch_tree_lock(sch); -+ memset(&qopt, 0, sizeof(qopt)); -+ qopt.type = priv->type; -+ qopt.shaped = priv->shaped; -+ -+ switch (priv->type) { -+ case CEETM_ROOT: -+ /* Gather statistics from the underlying pfifo qdiscs */ -+ sch->q.qlen = 0; -+ memset(&sch->bstats, 0, sizeof(sch->bstats)); -+ memset(&sch->qstats, 0, sizeof(sch->qstats)); -+ -+ for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { -+ qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping; -+ sch->q.qlen += qdisc->q.qlen; -+ sch->bstats.bytes += qdisc->bstats.bytes; -+ sch->bstats.packets += qdisc->bstats.packets; -+ sch->qstats.qlen += qdisc->qstats.qlen; -+ sch->qstats.backlog += qdisc->qstats.backlog; -+ sch->qstats.drops += qdisc->qstats.drops; -+ sch->qstats.requeues += qdisc->qstats.requeues; -+ sch->qstats.overlimits += qdisc->qstats.overlimits; -+ } -+ -+ for_each_online_cpu(i) { -+ qstats = per_cpu_ptr(priv->root.qstats, i); -+ sch->qstats.drops += qstats->drops; -+ } -+ -+ qopt.rate = priv->root.rate; -+ qopt.ceil = priv->root.ceil; -+ qopt.overhead = priv->root.overhead; -+ break; -+ -+ case CEETM_PRIO: -+ qopt.qcount = priv->prio.qcount; -+ break; -+ -+ case CEETM_WBFS: -+ qopt.qcount = priv->wbfs.qcount; -+ qopt.cr = priv->wbfs.cr; -+ qopt.er = priv->wbfs.er; -+ break; -+ -+ default: -+ pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__); -+ sch_tree_unlock(sch); -+ return -EINVAL; -+ } -+ -+ nest = nla_nest_start(skb, TCA_OPTIONS); -+ if (!nest) -+ goto nla_put_failure; -+ if (nla_put(skb, TCA_CEETM_QOPS, sizeof(qopt), &qopt)) -+ goto nla_put_failure; -+ nla_nest_end(skb, nest); -+ -+ sch_tree_unlock(sch); -+ return skb->len; -+ -+nla_put_failure: -+ sch_tree_unlock(sch); -+ nla_nest_cancel(skb, nest); -+ return -EMSGSIZE; -+} -+ -+/* Configure a root ceetm qdisc */ -+static int ceetm_init_root(struct Qdisc *sch, struct ceetm_qdisc *priv, -+ struct tc_ceetm_qopt *qopt) -+{ -+ struct netdev_queue *dev_queue; -+ struct Qdisc *qdisc; -+ enum qm_dc_portal dcp_id; -+ unsigned int i, sp_id, parent_id; -+ int err; -+ u64 bps; -+ struct qm_ceetm_sp *sp; -+ struct qm_ceetm_lni *lni; -+ struct net_device *dev = qdisc_dev(sch); -+ struct dpa_priv_s *dpa_priv = netdev_priv(dev); -+ struct mac_device *mac_dev = dpa_priv->mac_dev; -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ /* Validate inputs */ -+ if (sch->parent != TC_H_ROOT) { -+ pr_err("CEETM: a root ceetm qdisc can not be attached to a class\n"); -+ tcf_destroy_chain(&priv->filter_list); -+ qdisc_class_hash_destroy(&priv->clhash); -+ return -EINVAL; -+ } -+ -+ if (!mac_dev) { -+ pr_err("CEETM: the interface is lacking a mac\n"); -+ err = -EINVAL; -+ goto err_init_root; -+ } -+ -+ /* pre-allocate underlying pfifo qdiscs */ -+ priv->root.qdiscs = kcalloc(dev->num_tx_queues, -+ sizeof(priv->root.qdiscs[0]), -+ GFP_KERNEL); -+ if (!priv->root.qdiscs) { -+ err = -ENOMEM; -+ goto err_init_root; -+ } -+ -+ for (i = 0; i < dev->num_tx_queues; i++) { -+ dev_queue = netdev_get_tx_queue(dev, i); -+ parent_id = TC_H_MAKE(TC_H_MAJ(sch->handle), -+ TC_H_MIN(i + PFIFO_MIN_OFFSET)); -+ -+ qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops, -+ parent_id); -+ if (!qdisc) { -+ err = -ENOMEM; -+ goto err_init_root; -+ } -+ -+ priv->root.qdiscs[i] = qdisc; -+ qdisc->flags |= TCQ_F_ONETXQUEUE; -+ } -+ -+ sch->flags |= TCQ_F_MQROOT; -+ -+ priv->root.qstats = alloc_percpu(struct ceetm_qdisc_stats); -+ if (!priv->root.qstats) { -+ pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n", -+ __func__); -+ err = -ENOMEM; -+ goto err_init_root; -+ } -+ -+ priv->shaped = qopt->shaped; -+ priv->root.rate = qopt->rate; -+ priv->root.ceil = qopt->ceil; -+ priv->root.overhead = qopt->overhead; -+ -+ /* Claim the SP */ -+ get_dcp_and_sp(dev, &dcp_id, &sp_id); -+ err = qman_ceetm_sp_claim(&sp, dcp_id, sp_id); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to claim the SP\n", -+ __func__); -+ goto err_init_root; -+ } -+ -+ priv->root.sp = sp; -+ -+ /* Claim the LNI - will use the same id as the SP id since SPs 0-7 -+ * are connected to the TX FMan ports -+ */ -+ err = qman_ceetm_lni_claim(&lni, dcp_id, sp_id); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to claim the LNI\n", -+ __func__); -+ goto err_init_root; -+ } -+ -+ priv->root.lni = lni; -+ -+ err = qman_ceetm_sp_set_lni(sp, lni); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to link the SP and LNI\n", -+ __func__); -+ goto err_init_root; -+ } -+ -+ lni->sp = sp; -+ -+ /* Configure the LNI shaper */ -+ if (priv->shaped) { -+ err = qman_ceetm_lni_enable_shaper(lni, 1, priv->root.overhead); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n", -+ __func__); -+ goto err_init_root; -+ } -+ -+ bps = priv->root.rate << 3; /* Bps -> bps */ -+ err = qman_ceetm_lni_set_commit_rate_bps(lni, bps, dev->mtu); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n", -+ __func__); -+ goto err_init_root; -+ } -+ -+ bps = priv->root.ceil << 3; /* Bps -> bps */ -+ err = qman_ceetm_lni_set_excess_rate_bps(lni, bps, dev->mtu); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n", -+ __func__); -+ goto err_init_root; -+ } -+ } -+ -+ /* TODO default configuration */ -+ -+ dpa_enable_ceetm(dev); -+ return 0; -+ -+err_init_root: -+ ceetm_destroy(sch); -+ return err; -+} -+ -+/* Configure a prio ceetm qdisc */ -+static int ceetm_init_prio(struct Qdisc *sch, struct ceetm_qdisc *priv, -+ struct tc_ceetm_qopt *qopt) -+{ -+ int err; -+ unsigned int i; -+ struct ceetm_class *parent_cl, *child_cl; -+ struct Qdisc *parent_qdisc; -+ struct net_device *dev = qdisc_dev(sch); -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ if (sch->parent == TC_H_ROOT) { -+ pr_err("CEETM: a prio ceetm qdisc can not be root\n"); -+ err = -EINVAL; -+ goto err_init_prio; -+ } -+ -+ parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent)); -+ if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) { -+ pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n"); -+ err = -EINVAL; -+ goto err_init_prio; -+ } -+ -+ /* Obtain the parent root ceetm_class */ -+ parent_cl = ceetm_find(sch->parent, parent_qdisc); -+ -+ if (!parent_cl || parent_cl->type != CEETM_ROOT) { -+ pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n"); -+ err = -EINVAL; -+ goto err_init_prio; -+ } -+ -+ priv->prio.parent = parent_cl; -+ parent_cl->root.child = sch; -+ -+ priv->shaped = parent_cl->shaped; -+ priv->prio.qcount = qopt->qcount; -+ -+ /* Create and configure qcount child classes */ -+ for (i = 0; i < priv->prio.qcount; i++) { -+ child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL); -+ if (!child_cl) { -+ pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n", -+ __func__); -+ err = -ENOMEM; -+ goto err_init_prio; -+ } -+ -+ child_cl->prio.cstats = alloc_percpu(struct ceetm_class_stats); -+ if (!child_cl->prio.cstats) { -+ pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n", -+ __func__); -+ err = -ENOMEM; -+ goto err_init_prio_cls; -+ } -+ -+ child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1)); -+ child_cl->refcnt = 1; -+ child_cl->parent = sch; -+ child_cl->type = CEETM_PRIO; -+ child_cl->shaped = priv->shaped; -+ child_cl->prio.child = NULL; -+ -+ /* All shaped CQs have CR and ER enabled by default */ -+ child_cl->prio.cr = child_cl->shaped; -+ child_cl->prio.er = child_cl->shaped; -+ child_cl->prio.fq = NULL; -+ child_cl->prio.cq = NULL; -+ -+ /* Configure the corresponding hardware CQ */ -+ err = ceetm_config_prio_cls(child_cl, dev, -+ parent_cl->root.ch, i); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n", -+ __func__, child_cl->common.classid); -+ goto err_init_prio_cls; -+ } -+ -+ /* Add class handle in Qdisc */ -+ ceetm_link_class(sch, &priv->clhash, &child_cl->common); -+ pr_debug(KBUILD_BASENAME " : %s : added ceetm prio class %X associated with CQ %d and CCG %d\n", -+ __func__, child_cl->common.classid, -+ child_cl->prio.cq->idx, child_cl->prio.ccg->idx); -+ } -+ -+ return 0; -+ -+err_init_prio_cls: -+ ceetm_cls_destroy(sch, child_cl); -+err_init_prio: -+ ceetm_destroy(sch); -+ return err; -+} -+ -+/* Configure a wbfs ceetm qdisc */ -+static int ceetm_init_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv, -+ struct tc_ceetm_qopt *qopt) -+{ -+ int err, group_b, small_group; -+ unsigned int i, id, prio_a, prio_b; -+ struct ceetm_class *parent_cl, *child_cl, *root_cl; -+ struct Qdisc *parent_qdisc; -+ struct ceetm_qdisc *parent_priv; -+ struct qm_ceetm_channel *channel; -+ struct net_device *dev = qdisc_dev(sch); -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ /* Validate inputs */ -+ if (sch->parent == TC_H_ROOT) { -+ pr_err("CEETM: a wbfs ceetm qdiscs can not be root\n"); -+ err = -EINVAL; -+ goto err_init_wbfs; -+ } -+ -+ /* Obtain the parent prio ceetm qdisc */ -+ parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent)); -+ if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) { -+ pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n"); -+ err = -EINVAL; -+ goto err_init_wbfs; -+ } -+ -+ /* Obtain the parent prio ceetm class */ -+ parent_cl = ceetm_find(sch->parent, parent_qdisc); -+ parent_priv = qdisc_priv(parent_qdisc); -+ -+ if (!parent_cl || parent_cl->type != CEETM_PRIO) { -+ pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n"); -+ err = -EINVAL; -+ goto err_init_wbfs; -+ } -+ -+ if (!qopt->qcount || !qopt->qweight[0]) { -+ pr_err("CEETM: qcount and qweight are mandatory for a wbfs ceetm qdisc\n"); -+ err = -EINVAL; -+ goto err_init_wbfs; -+ } -+ -+ priv->shaped = parent_cl->shaped; -+ -+ if (!priv->shaped && (qopt->cr || qopt->er)) { -+ pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n"); -+ err = -EINVAL; -+ goto err_init_wbfs; -+ } -+ -+ if (priv->shaped && !(qopt->cr || qopt->er)) { -+ pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n"); -+ err = -EINVAL; -+ goto err_init_wbfs; -+ } -+ -+ /* Obtain the parent root ceetm class */ -+ root_cl = parent_priv->prio.parent; -+ if ((root_cl->root.wbfs_grp_a && root_cl->root.wbfs_grp_b) || -+ root_cl->root.wbfs_grp_large) { -+ pr_err("CEETM: no more wbfs classes are available\n"); -+ err = -EINVAL; -+ goto err_init_wbfs; -+ } -+ -+ if ((root_cl->root.wbfs_grp_a || root_cl->root.wbfs_grp_b) && -+ qopt->qcount == CEETM_MAX_WBFS_QCOUNT) { -+ pr_err("CEETM: only %d wbfs classes are available\n", -+ CEETM_MIN_WBFS_QCOUNT); -+ err = -EINVAL; -+ goto err_init_wbfs; -+ } -+ -+ priv->wbfs.parent = parent_cl; -+ parent_cl->prio.child = sch; -+ -+ priv->wbfs.qcount = qopt->qcount; -+ priv->wbfs.cr = qopt->cr; -+ priv->wbfs.er = qopt->er; -+ -+ channel = root_cl->root.ch; -+ -+ /* Configure the hardware wbfs channel groups */ -+ if (priv->wbfs.qcount == CEETM_MAX_WBFS_QCOUNT) { -+ /* Configure the large group A */ -+ priv->wbfs.group_type = WBFS_GRP_LARGE; -+ small_group = false; -+ group_b = false; -+ prio_a = TC_H_MIN(parent_cl->common.classid) - 1; -+ prio_b = prio_a; -+ -+ } else if (root_cl->root.wbfs_grp_a) { -+ /* Configure the group B */ -+ priv->wbfs.group_type = WBFS_GRP_B; -+ -+ err = qman_ceetm_channel_get_group(channel, &small_group, -+ &prio_a, &prio_b); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to get group details\n", -+ __func__); -+ goto err_init_wbfs; -+ } -+ -+ small_group = true; -+ group_b = true; -+ prio_b = TC_H_MIN(parent_cl->common.classid) - 1; -+ /* If group A isn't configured, configure it as group B */ -+ prio_a = prio_a ? : prio_b; -+ -+ } else { -+ /* Configure the small group A */ -+ priv->wbfs.group_type = WBFS_GRP_A; -+ -+ err = qman_ceetm_channel_get_group(channel, &small_group, -+ &prio_a, &prio_b); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to get group details\n", -+ __func__); -+ goto err_init_wbfs; -+ } -+ -+ small_group = true; -+ group_b = false; -+ prio_a = TC_H_MIN(parent_cl->common.classid) - 1; -+ /* If group B isn't configured, configure it as group A */ -+ prio_b = prio_b ? : prio_a; -+ } -+ -+ err = qman_ceetm_channel_set_group(channel, small_group, prio_a, -+ prio_b); -+ if (err) -+ goto err_init_wbfs; -+ -+ if (priv->shaped) { -+ err = qman_ceetm_channel_set_group_cr_eligibility(channel, -+ group_b, -+ priv->wbfs.cr); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to set group CR eligibility\n", -+ __func__); -+ goto err_init_wbfs; -+ } -+ -+ err = qman_ceetm_channel_set_group_er_eligibility(channel, -+ group_b, -+ priv->wbfs.er); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to set group ER eligibility\n", -+ __func__); -+ goto err_init_wbfs; -+ } -+ } -+ -+ /* Create qcount child classes */ -+ for (i = 0; i < priv->wbfs.qcount; i++) { -+ child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL); -+ if (!child_cl) { -+ pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n", -+ __func__); -+ err = -ENOMEM; -+ goto err_init_wbfs; -+ } -+ -+ child_cl->wbfs.cstats = alloc_percpu(struct ceetm_class_stats); -+ if (!child_cl->wbfs.cstats) { -+ pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n", -+ __func__); -+ err = -ENOMEM; -+ goto err_init_wbfs_cls; -+ } -+ -+ child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1)); -+ child_cl->refcnt = 1; -+ child_cl->parent = sch; -+ child_cl->type = CEETM_WBFS; -+ child_cl->shaped = priv->shaped; -+ child_cl->wbfs.fq = NULL; -+ child_cl->wbfs.cq = NULL; -+ child_cl->wbfs.weight = qopt->qweight[i]; -+ -+ if (priv->wbfs.group_type == WBFS_GRP_B) -+ id = WBFS_GRP_B_OFFSET + i; -+ else -+ id = WBFS_GRP_A_OFFSET + i; -+ -+ err = ceetm_config_wbfs_cls(child_cl, dev, channel, id, -+ priv->wbfs.group_type); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n", -+ __func__, child_cl->common.classid); -+ goto err_init_wbfs_cls; -+ } -+ -+ /* Add class handle in Qdisc */ -+ ceetm_link_class(sch, &priv->clhash, &child_cl->common); -+ pr_debug(KBUILD_BASENAME " : %s : added ceetm wbfs class %X associated with CQ %d and CCG %d\n", -+ __func__, child_cl->common.classid, -+ child_cl->wbfs.cq->idx, child_cl->wbfs.ccg->idx); -+ } -+ -+ /* Signal the root class that a group has been configured */ -+ switch (priv->wbfs.group_type) { -+ case WBFS_GRP_LARGE: -+ root_cl->root.wbfs_grp_large = true; -+ break; -+ case WBFS_GRP_A: -+ root_cl->root.wbfs_grp_a = true; -+ break; -+ case WBFS_GRP_B: -+ root_cl->root.wbfs_grp_b = true; -+ break; -+ } -+ -+ return 0; -+ -+err_init_wbfs_cls: -+ ceetm_cls_destroy(sch, child_cl); -+err_init_wbfs: -+ ceetm_destroy(sch); -+ return err; -+} -+ -+/* Configure a generic ceetm qdisc */ -+static int ceetm_init(struct Qdisc *sch, struct nlattr *opt) -+{ -+ struct tc_ceetm_qopt *qopt; -+ struct nlattr *tb[TCA_CEETM_QOPS + 1]; -+ int ret; -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct net_device *dev = qdisc_dev(sch); -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ if (!netif_is_multiqueue(dev)) -+ return -EOPNOTSUPP; -+ -+ if (!opt) { -+ pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); -+ return -EINVAL; -+ } -+ -+ ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy); -+ if (ret < 0) { -+ pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); -+ return ret; -+ } -+ -+ if (!tb[TCA_CEETM_QOPS]) { -+ pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); -+ return -EINVAL; -+ } -+ -+ if (TC_H_MIN(sch->handle)) { -+ pr_err("CEETM: a qdisc should not have a minor\n"); -+ return -EINVAL; -+ } -+ -+ qopt = nla_data(tb[TCA_CEETM_QOPS]); -+ -+ /* Initialize the class hash list. Each qdisc has its own class hash */ -+ ret = qdisc_class_hash_init(&priv->clhash); -+ if (ret < 0) { -+ pr_err(KBUILD_BASENAME " : %s : qdisc_class_hash_init failed\n", -+ __func__); -+ return ret; -+ } -+ -+ priv->type = qopt->type; -+ -+ switch (priv->type) { -+ case CEETM_ROOT: -+ ret = ceetm_init_root(sch, priv, qopt); -+ break; -+ case CEETM_PRIO: -+ ret = ceetm_init_prio(sch, priv, qopt); -+ break; -+ case CEETM_WBFS: -+ ret = ceetm_init_wbfs(sch, priv, qopt); -+ break; -+ default: -+ pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__); -+ ceetm_destroy(sch); -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+ -+/* Edit a root ceetm qdisc */ -+static int ceetm_change_root(struct Qdisc *sch, struct ceetm_qdisc *priv, -+ struct net_device *dev, -+ struct tc_ceetm_qopt *qopt) -+{ -+ int err = 0; -+ u64 bps; -+ -+ if (priv->shaped != (bool)qopt->shaped) { -+ pr_err("CEETM: qdisc %X is %s\n", sch->handle, -+ priv->shaped ? "shaped" : "unshaped"); -+ return -EINVAL; -+ } -+ -+ /* Nothing to modify for unshaped qdiscs */ -+ if (!priv->shaped) -+ return 0; -+ -+ /* Configure the LNI shaper */ -+ if (priv->root.overhead != qopt->overhead) { -+ err = qman_ceetm_lni_enable_shaper(priv->root.lni, 1, -+ qopt->overhead); -+ if (err) -+ goto change_err; -+ priv->root.overhead = qopt->overhead; -+ } -+ -+ if (priv->root.rate != qopt->rate) { -+ bps = qopt->rate << 3; /* Bps -> bps */ -+ err = qman_ceetm_lni_set_commit_rate_bps(priv->root.lni, bps, -+ dev->mtu); -+ if (err) -+ goto change_err; -+ priv->root.rate = qopt->rate; -+ } -+ -+ if (priv->root.ceil != qopt->ceil) { -+ bps = qopt->ceil << 3; /* Bps -> bps */ -+ err = qman_ceetm_lni_set_excess_rate_bps(priv->root.lni, bps, -+ dev->mtu); -+ if (err) -+ goto change_err; -+ priv->root.ceil = qopt->ceil; -+ } -+ -+ return 0; -+ -+change_err: -+ pr_err(KBUILD_BASENAME " : %s : failed to configure the root ceetm qdisc %X\n", -+ __func__, sch->handle); -+ return err; -+} -+ -+/* Edit a wbfs ceetm qdisc */ -+static int ceetm_change_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv, -+ struct tc_ceetm_qopt *qopt) -+{ -+ int err; -+ bool group_b; -+ struct qm_ceetm_channel *channel; -+ struct ceetm_class *prio_class, *root_class; -+ struct ceetm_qdisc *prio_qdisc; -+ -+ if (qopt->qcount) { -+ pr_err("CEETM: the qcount can not be modified\n"); -+ return -EINVAL; -+ } -+ -+ if (qopt->qweight[0]) { -+ pr_err("CEETM: the qweight can be modified through the wbfs classes\n"); -+ return -EINVAL; -+ } -+ -+ if (!priv->shaped && (qopt->cr || qopt->er)) { -+ pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n"); -+ return -EINVAL; -+ } -+ -+ if (priv->shaped && !(qopt->cr || qopt->er)) { -+ pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n"); -+ return -EINVAL; -+ } -+ -+ /* Nothing to modify for unshaped qdiscs */ -+ if (!priv->shaped) -+ return 0; -+ -+ prio_class = priv->wbfs.parent; -+ prio_qdisc = qdisc_priv(prio_class->parent); -+ root_class = prio_qdisc->prio.parent; -+ channel = root_class->root.ch; -+ group_b = priv->wbfs.group_type == WBFS_GRP_B; -+ -+ if (qopt->cr != priv->wbfs.cr) { -+ err = qman_ceetm_channel_set_group_cr_eligibility(channel, -+ group_b, -+ qopt->cr); -+ if (err) -+ goto change_err; -+ priv->wbfs.cr = qopt->cr; -+ } -+ -+ if (qopt->er != priv->wbfs.er) { -+ err = qman_ceetm_channel_set_group_er_eligibility(channel, -+ group_b, -+ qopt->er); -+ if (err) -+ goto change_err; -+ priv->wbfs.er = qopt->er; -+ } -+ -+ return 0; -+ -+change_err: -+ pr_err(KBUILD_BASENAME " : %s : failed to configure the wbfs ceetm qdisc %X\n", -+ __func__, sch->handle); -+ return err; -+} -+ -+/* Edit a ceetm qdisc */ -+static int ceetm_change(struct Qdisc *sch, struct nlattr *opt) -+{ -+ struct tc_ceetm_qopt *qopt; -+ struct nlattr *tb[TCA_CEETM_QOPS + 1]; -+ int ret; -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct net_device *dev = qdisc_dev(sch); -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy); -+ if (ret < 0) { -+ pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); -+ return ret; -+ } -+ -+ if (!tb[TCA_CEETM_QOPS]) { -+ pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); -+ return -EINVAL; -+ } -+ -+ if (TC_H_MIN(sch->handle)) { -+ pr_err("CEETM: a qdisc should not have a minor\n"); -+ return -EINVAL; -+ } -+ -+ qopt = nla_data(tb[TCA_CEETM_QOPS]); -+ -+ if (priv->type != qopt->type) { -+ pr_err("CEETM: qdisc %X is not of the provided type\n", -+ sch->handle); -+ return -EINVAL; -+ } -+ -+ switch (priv->type) { -+ case CEETM_ROOT: -+ ret = ceetm_change_root(sch, priv, dev, qopt); -+ break; -+ case CEETM_PRIO: -+ pr_err("CEETM: prio qdiscs can not be modified\n"); -+ ret = -EINVAL; -+ break; -+ case CEETM_WBFS: -+ ret = ceetm_change_wbfs(sch, priv, qopt); -+ break; -+ default: -+ pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__); -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+ -+/* Attach the underlying pfifo qdiscs */ -+static void ceetm_attach(struct Qdisc *sch) -+{ -+ struct net_device *dev = qdisc_dev(sch); -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct Qdisc *qdisc, *old_qdisc; -+ unsigned int i; -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ for (i = 0; i < dev->num_tx_queues; i++) { -+ qdisc = priv->root.qdiscs[i]; -+ old_qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc); -+ if (old_qdisc) -+ qdisc_destroy(old_qdisc); -+ } -+} -+ -+static unsigned long ceetm_cls_get(struct Qdisc *sch, u32 classid) -+{ -+ struct ceetm_class *cl; -+ -+ pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n", -+ __func__, classid, sch->handle); -+ cl = ceetm_find(classid, sch); -+ -+ if (cl) -+ cl->refcnt++; /* Will decrement in put() */ -+ return (unsigned long)cl; -+} -+ -+static void ceetm_cls_put(struct Qdisc *sch, unsigned long arg) -+{ -+ struct ceetm_class *cl = (struct ceetm_class *)arg; -+ -+ pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n", -+ __func__, cl->common.classid, sch->handle); -+ cl->refcnt--; -+ -+ if (cl->refcnt == 0) -+ ceetm_cls_destroy(sch, cl); -+} -+ -+static int ceetm_cls_change_root(struct ceetm_class *cl, -+ struct tc_ceetm_copt *copt, -+ struct net_device *dev) -+{ -+ int err; -+ u64 bps; -+ -+ if ((bool)copt->shaped != cl->shaped) { -+ pr_err("CEETM: class %X is %s\n", cl->common.classid, -+ cl->shaped ? "shaped" : "unshaped"); -+ return -EINVAL; -+ } -+ -+ if (cl->shaped && cl->root.rate != copt->rate) { -+ bps = copt->rate << 3; /* Bps -> bps */ -+ err = qman_ceetm_channel_set_commit_rate_bps(cl->root.ch, bps, -+ dev->mtu); -+ if (err) -+ goto change_cls_err; -+ cl->root.rate = copt->rate; -+ } -+ -+ if (cl->shaped && cl->root.ceil != copt->ceil) { -+ bps = copt->ceil << 3; /* Bps -> bps */ -+ err = qman_ceetm_channel_set_excess_rate_bps(cl->root.ch, bps, -+ dev->mtu); -+ if (err) -+ goto change_cls_err; -+ cl->root.ceil = copt->ceil; -+ } -+ -+ if (!cl->shaped && cl->root.tbl != copt->tbl) { -+ err = qman_ceetm_channel_set_weight(cl->root.ch, copt->tbl); -+ if (err) -+ goto change_cls_err; -+ cl->root.tbl = copt->tbl; -+ } -+ -+ return 0; -+ -+change_cls_err: -+ pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm root class %X\n", -+ __func__, cl->common.classid); -+ return err; -+} -+ -+static int ceetm_cls_change_prio(struct ceetm_class *cl, -+ struct tc_ceetm_copt *copt) -+{ -+ int err; -+ -+ if (!cl->shaped && (copt->cr || copt->er)) { -+ pr_err("CEETM: only shaped classes can have CR and ER enabled\n"); -+ return -EINVAL; -+ } -+ -+ if (cl->prio.cr != (bool)copt->cr) { -+ err = qman_ceetm_channel_set_cq_cr_eligibility( -+ cl->prio.cq->parent, -+ cl->prio.cq->idx, -+ copt->cr); -+ if (err) -+ goto change_cls_err; -+ cl->prio.cr = copt->cr; -+ } -+ -+ if (cl->prio.er != (bool)copt->er) { -+ err = qman_ceetm_channel_set_cq_er_eligibility( -+ cl->prio.cq->parent, -+ cl->prio.cq->idx, -+ copt->er); -+ if (err) -+ goto change_cls_err; -+ cl->prio.er = copt->er; -+ } -+ -+ return 0; -+ -+change_cls_err: -+ pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n", -+ __func__, cl->common.classid); -+ return err; -+} -+ -+static int ceetm_cls_change_wbfs(struct ceetm_class *cl, -+ struct tc_ceetm_copt *copt) -+{ -+ int err; -+ -+ if (copt->weight != cl->wbfs.weight) { -+ /* Configure the CQ weight: real number multiplied by 100 to -+ * get rid of the fraction -+ */ -+ err = qman_ceetm_set_queue_weight_in_ratio(cl->wbfs.cq, -+ copt->weight * 100); -+ -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n", -+ __func__, cl->common.classid); -+ return err; -+ } -+ -+ cl->wbfs.weight = copt->weight; -+ } -+ -+ return 0; -+} -+ -+/* Add a ceetm root class or configure a ceetm root/prio/wbfs class */ -+static int ceetm_cls_change(struct Qdisc *sch, u32 classid, u32 parentid, -+ struct nlattr **tca, unsigned long *arg) -+{ -+ int err; -+ u64 bps; -+ struct ceetm_qdisc *priv; -+ struct ceetm_class *cl = (struct ceetm_class *)*arg; -+ struct nlattr *opt = tca[TCA_OPTIONS]; -+ struct nlattr *tb[__TCA_CEETM_MAX]; -+ struct tc_ceetm_copt *copt; -+ struct qm_ceetm_channel *channel; -+ struct net_device *dev = qdisc_dev(sch); -+ -+ pr_debug(KBUILD_BASENAME " : %s : classid %X under qdisc %X\n", -+ __func__, classid, sch->handle); -+ -+ if (strcmp(sch->ops->id, ceetm_qdisc_ops.id)) { -+ pr_err("CEETM: a ceetm class can not be attached to other qdisc/class types\n"); -+ return -EINVAL; -+ } -+ -+ priv = qdisc_priv(sch); -+ -+ if (!opt) { -+ pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); -+ return -EINVAL; -+ } -+ -+ if (!cl && sch->handle != parentid) { -+ pr_err("CEETM: classes can be attached to the root ceetm qdisc only\n"); -+ return -EINVAL; -+ } -+ -+ if (!cl && priv->type != CEETM_ROOT) { -+ pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n"); -+ return -EINVAL; -+ } -+ -+ err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy); -+ if (err < 0) { -+ pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); -+ return -EINVAL; -+ } -+ -+ if (!tb[TCA_CEETM_COPT]) { -+ pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); -+ return -EINVAL; -+ } -+ -+ if (TC_H_MIN(classid) >= PFIFO_MIN_OFFSET) { -+ pr_err("CEETM: only minors 0x01 to 0x20 can be used for ceetm root classes\n"); -+ return -EINVAL; -+ } -+ -+ copt = nla_data(tb[TCA_CEETM_COPT]); -+ -+ /* Configure an existing ceetm class */ -+ if (cl) { -+ if (copt->type != cl->type) { -+ pr_err("CEETM: class %X is not of the provided type\n", -+ cl->common.classid); -+ return -EINVAL; -+ } -+ -+ switch (copt->type) { -+ case CEETM_ROOT: -+ return ceetm_cls_change_root(cl, copt, dev); -+ -+ case CEETM_PRIO: -+ return ceetm_cls_change_prio(cl, copt); -+ -+ case CEETM_WBFS: -+ return ceetm_cls_change_wbfs(cl, copt); -+ -+ default: -+ pr_err(KBUILD_BASENAME " : %s : invalid class\n", -+ __func__); -+ return -EINVAL; -+ } -+ } -+ -+ /* Add a new root ceetm class */ -+ if (copt->type != CEETM_ROOT) { -+ pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n"); -+ return -EINVAL; -+ } -+ -+ if (copt->shaped && !priv->shaped) { -+ pr_err("CEETM: can not add a shaped ceetm root class under an unshaped ceetm root qdisc\n"); -+ return -EINVAL; -+ } -+ -+ cl = kzalloc(sizeof(*cl), GFP_KERNEL); -+ if (!cl) -+ return -ENOMEM; -+ -+ cl->type = copt->type; -+ cl->shaped = copt->shaped; -+ cl->root.rate = copt->rate; -+ cl->root.ceil = copt->ceil; -+ cl->root.tbl = copt->tbl; -+ -+ cl->common.classid = classid; -+ cl->refcnt = 1; -+ cl->parent = sch; -+ cl->root.child = NULL; -+ cl->root.wbfs_grp_a = false; -+ cl->root.wbfs_grp_b = false; -+ cl->root.wbfs_grp_large = false; -+ -+ /* Claim a CEETM channel */ -+ err = qman_ceetm_channel_claim(&channel, priv->root.lni); -+ if (err) { -+ pr_err(KBUILD_BASENAME " : %s : failed to claim a channel\n", -+ __func__); -+ goto claim_err; -+ } -+ -+ cl->root.ch = channel; -+ -+ if (cl->shaped) { -+ /* Configure the channel shaper */ -+ err = qman_ceetm_channel_enable_shaper(channel, 1); -+ if (err) -+ goto channel_err; -+ -+ bps = cl->root.rate << 3; /* Bps -> bps */ -+ err = qman_ceetm_channel_set_commit_rate_bps(channel, bps, -+ dev->mtu); -+ if (err) -+ goto channel_err; -+ -+ bps = cl->root.ceil << 3; /* Bps -> bps */ -+ err = qman_ceetm_channel_set_excess_rate_bps(channel, bps, -+ dev->mtu); -+ if (err) -+ goto channel_err; -+ -+ } else { -+ /* Configure the uFQ algorithm */ -+ err = qman_ceetm_channel_set_weight(channel, cl->root.tbl); -+ if (err) -+ goto channel_err; -+ } -+ -+ /* Add class handle in Qdisc */ -+ ceetm_link_class(sch, &priv->clhash, &cl->common); -+ -+ pr_debug(KBUILD_BASENAME " : %s : configured class %X associated with channel %d\n", -+ __func__, classid, channel->idx); -+ *arg = (unsigned long)cl; -+ return 0; -+ -+channel_err: -+ pr_err(KBUILD_BASENAME " : %s : failed to configure the channel %d\n", -+ __func__, channel->idx); -+ if (qman_ceetm_channel_release(channel)) -+ pr_err(KBUILD_BASENAME " : %s : failed to release the channel %d\n", -+ __func__, channel->idx); -+claim_err: -+ kfree(cl); -+ return err; -+} -+ -+static void ceetm_cls_walk(struct Qdisc *sch, struct qdisc_walker *arg) -+{ -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct ceetm_class *cl; -+ unsigned int i; -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ if (arg->stop) -+ return; -+ -+ for (i = 0; i < priv->clhash.hashsize; i++) { -+ hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) { -+ if (arg->count < arg->skip) { -+ arg->count++; -+ continue; -+ } -+ if (arg->fn(sch, (unsigned long)cl, arg) < 0) { -+ arg->stop = 1; -+ return; -+ } -+ arg->count++; -+ } -+ } -+} -+ -+static int ceetm_cls_dump(struct Qdisc *sch, unsigned long arg, -+ struct sk_buff *skb, struct tcmsg *tcm) -+{ -+ struct ceetm_class *cl = (struct ceetm_class *)arg; -+ struct nlattr *nest; -+ struct tc_ceetm_copt copt; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", -+ __func__, cl->common.classid, sch->handle); -+ -+ sch_tree_lock(sch); -+ -+ tcm->tcm_parent = ((struct Qdisc *)cl->parent)->handle; -+ tcm->tcm_handle = cl->common.classid; -+ -+ memset(&copt, 0, sizeof(copt)); -+ -+ copt.shaped = cl->shaped; -+ copt.type = cl->type; -+ -+ switch (cl->type) { -+ case CEETM_ROOT: -+ if (cl->root.child) -+ tcm->tcm_info = cl->root.child->handle; -+ -+ copt.rate = cl->root.rate; -+ copt.ceil = cl->root.ceil; -+ copt.tbl = cl->root.tbl; -+ break; -+ -+ case CEETM_PRIO: -+ if (cl->prio.child) -+ tcm->tcm_info = cl->prio.child->handle; -+ -+ copt.cr = cl->prio.cr; -+ copt.er = cl->prio.er; -+ break; -+ -+ case CEETM_WBFS: -+ copt.weight = cl->wbfs.weight; -+ break; -+ } -+ -+ nest = nla_nest_start(skb, TCA_OPTIONS); -+ if (!nest) -+ goto nla_put_failure; -+ if (nla_put(skb, TCA_CEETM_COPT, sizeof(copt), &copt)) -+ goto nla_put_failure; -+ nla_nest_end(skb, nest); -+ sch_tree_unlock(sch); -+ return skb->len; -+ -+nla_put_failure: -+ sch_tree_unlock(sch); -+ nla_nest_cancel(skb, nest); -+ return -EMSGSIZE; -+} -+ -+static int ceetm_cls_delete(struct Qdisc *sch, unsigned long arg) -+{ -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct ceetm_class *cl = (struct ceetm_class *)arg; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", -+ __func__, cl->common.classid, sch->handle); -+ -+ sch_tree_lock(sch); -+ qdisc_class_hash_remove(&priv->clhash, &cl->common); -+ cl->refcnt--; -+ -+ /* The refcnt should be at least 1 since we have incremented it in -+ * get(). Will decrement again in put() where we will call destroy() -+ * to actually free the memory if it reaches 0. -+ */ -+ WARN_ON(cl->refcnt == 0); -+ -+ sch_tree_unlock(sch); -+ return 0; -+} -+ -+/* Get the class' child qdisc, if any */ -+static struct Qdisc *ceetm_cls_leaf(struct Qdisc *sch, unsigned long arg) -+{ -+ struct ceetm_class *cl = (struct ceetm_class *)arg; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", -+ __func__, cl->common.classid, sch->handle); -+ -+ switch (cl->type) { -+ case CEETM_ROOT: -+ return cl->root.child; -+ -+ case CEETM_PRIO: -+ return cl->prio.child; -+ } -+ -+ return NULL; -+} -+ -+static int ceetm_cls_graft(struct Qdisc *sch, unsigned long arg, -+ struct Qdisc *new, struct Qdisc **old) -+{ -+ if (new && strcmp(new->ops->id, ceetm_qdisc_ops.id)) { -+ pr_err("CEETM: only ceetm qdiscs can be attached to ceetm classes\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ -+static int ceetm_cls_dump_stats(struct Qdisc *sch, unsigned long arg, -+ struct gnet_dump *d) -+{ -+ unsigned int i; -+ struct ceetm_class *cl = (struct ceetm_class *)arg; -+ struct gnet_stats_basic_packed tmp_bstats; -+ struct ceetm_class_stats *cstats = NULL; -+ struct qm_ceetm_cq *cq = NULL; -+ struct tc_ceetm_xstats xstats; -+ -+ memset(&xstats, 0, sizeof(xstats)); -+ memset(&tmp_bstats, 0, sizeof(tmp_bstats)); -+ -+ switch (cl->type) { -+ case CEETM_ROOT: -+ return 0; -+ case CEETM_PRIO: -+ cq = cl->prio.cq; -+ break; -+ case CEETM_WBFS: -+ cq = cl->wbfs.cq; -+ break; -+ } -+ -+ for_each_online_cpu(i) { -+ switch (cl->type) { -+ case CEETM_PRIO: -+ cstats = per_cpu_ptr(cl->prio.cstats, i); -+ break; -+ case CEETM_WBFS: -+ cstats = per_cpu_ptr(cl->wbfs.cstats, i); -+ break; -+ } -+ -+ if (cstats) { -+ xstats.ern_drop_count += cstats->ern_drop_count; -+ xstats.congested_count += cstats->congested_count; -+ tmp_bstats.bytes += cstats->bstats.bytes; -+ tmp_bstats.packets += cstats->bstats.packets; -+ } -+ } -+ -+ if (gnet_stats_copy_basic(d, NULL, &tmp_bstats) < 0) -+ return -1; -+ -+ if (cq && qman_ceetm_cq_get_dequeue_statistics(cq, 0, -+ &xstats.frame_count, -+ &xstats.byte_count)) -+ return -1; -+ -+ return gnet_stats_copy_app(d, &xstats, sizeof(xstats)); -+} -+ -+static struct tcf_proto **ceetm_tcf_chain(struct Qdisc *sch, unsigned long arg) -+{ -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct ceetm_class *cl = (struct ceetm_class *)arg; -+ struct tcf_proto **fl = cl ? &cl->filter_list : &priv->filter_list; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__, -+ cl ? cl->common.classid : 0, sch->handle); -+ return fl; -+} -+ -+static unsigned long ceetm_tcf_bind(struct Qdisc *sch, unsigned long parent, -+ u32 classid) -+{ -+ struct ceetm_class *cl = ceetm_find(classid, sch); -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__, -+ cl ? cl->common.classid : 0, sch->handle); -+ return (unsigned long)cl; -+} -+ -+static void ceetm_tcf_unbind(struct Qdisc *sch, unsigned long arg) -+{ -+ struct ceetm_class *cl = (struct ceetm_class *)arg; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__, -+ cl ? cl->common.classid : 0, sch->handle); -+} -+ -+const struct Qdisc_class_ops ceetm_cls_ops = { -+ .graft = ceetm_cls_graft, -+ .leaf = ceetm_cls_leaf, -+ .get = ceetm_cls_get, -+ .put = ceetm_cls_put, -+ .change = ceetm_cls_change, -+ .delete = ceetm_cls_delete, -+ .walk = ceetm_cls_walk, -+ .tcf_chain = ceetm_tcf_chain, -+ .bind_tcf = ceetm_tcf_bind, -+ .unbind_tcf = ceetm_tcf_unbind, -+ .dump = ceetm_cls_dump, -+ .dump_stats = ceetm_cls_dump_stats, -+}; -+ -+struct Qdisc_ops ceetm_qdisc_ops __read_mostly = { -+ .id = "ceetm", -+ .priv_size = sizeof(struct ceetm_qdisc), -+ .cl_ops = &ceetm_cls_ops, -+ .init = ceetm_init, -+ .destroy = ceetm_destroy, -+ .change = ceetm_change, -+ .dump = ceetm_dump, -+ .attach = ceetm_attach, -+ .owner = THIS_MODULE, -+}; -+ -+/* Run the filters and classifiers attached to the qdisc on the provided skb */ -+static struct ceetm_class *ceetm_classify(struct sk_buff *skb, -+ struct Qdisc *sch, int *qerr, -+ bool *act_drop) -+{ -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct ceetm_class *cl = NULL, *wbfs_cl; -+ struct tcf_result res; -+ struct tcf_proto *tcf; -+ int result; -+ -+ *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; -+ tcf = priv->filter_list; -+ while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) { -+#ifdef CONFIG_NET_CLS_ACT -+ switch (result) { -+ case TC_ACT_QUEUED: -+ case TC_ACT_STOLEN: -+ *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; -+ case TC_ACT_SHOT: -+ /* No valid class found due to action */ -+ *act_drop = true; -+ return NULL; -+ } -+#endif -+ cl = (void *)res.class; -+ if (!cl) { -+ if (res.classid == sch->handle) { -+ /* The filter leads to the qdisc */ -+ /* TODO default qdisc */ -+ return NULL; -+ } -+ -+ cl = ceetm_find(res.classid, sch); -+ if (!cl) -+ /* The filter leads to an invalid class */ -+ break; -+ } -+ -+ /* The class might have its own filters attached */ -+ tcf = cl->filter_list; -+ } -+ -+ if (!cl) { -+ /* No valid class found */ -+ /* TODO default qdisc */ -+ return NULL; -+ } -+ -+ switch (cl->type) { -+ case CEETM_ROOT: -+ if (cl->root.child) { -+ /* Run the prio qdisc classifiers */ -+ return ceetm_classify(skb, cl->root.child, qerr, -+ act_drop); -+ } else { -+ /* The root class does not have a child prio qdisc */ -+ /* TODO default qdisc */ -+ return NULL; -+ } -+ case CEETM_PRIO: -+ if (cl->prio.child) { -+ /* If filters lead to a wbfs class, return it. -+ * Otherwise, return the prio class -+ */ -+ wbfs_cl = ceetm_classify(skb, cl->prio.child, qerr, -+ act_drop); -+ /* A NULL result might indicate either an erroneous -+ * filter, or no filters at all. We will assume the -+ * latter -+ */ -+ return wbfs_cl ? : cl; -+ } -+ } -+ -+ /* For wbfs and childless prio classes, return the class directly */ -+ return cl; -+} -+ -+int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev) -+{ -+ int ret; -+ bool act_drop = false; -+ struct Qdisc *sch = net_dev->qdisc; -+ struct ceetm_class *cl; -+ struct dpa_priv_s *priv_dpa; -+ struct qman_fq *egress_fq, *conf_fq; -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct ceetm_qdisc_stats *qstats = this_cpu_ptr(priv->root.qstats); -+ struct ceetm_class_stats *cstats; -+ const int queue_mapping = dpa_get_queue_mapping(skb); -+ spinlock_t *root_lock = qdisc_lock(sch); -+ -+ spin_lock(root_lock); -+ cl = ceetm_classify(skb, sch, &ret, &act_drop); -+ spin_unlock(root_lock); -+ -+#ifdef CONFIG_NET_CLS_ACT -+ if (act_drop) { -+ if (ret & __NET_XMIT_BYPASS) -+ qstats->drops++; -+ goto drop; -+ } -+#endif -+ /* TODO default class */ -+ if (unlikely(!cl)) { -+ qstats->drops++; -+ goto drop; -+ } -+ -+ priv_dpa = netdev_priv(net_dev); -+ conf_fq = priv_dpa->conf_fqs[queue_mapping]; -+ -+ /* Choose the proper tx fq and update the basic stats (bytes and -+ * packets sent by the class) -+ */ -+ switch (cl->type) { -+ case CEETM_PRIO: -+ egress_fq = &cl->prio.fq->fq; -+ cstats = this_cpu_ptr(cl->prio.cstats); -+ break; -+ case CEETM_WBFS: -+ egress_fq = &cl->wbfs.fq->fq; -+ cstats = this_cpu_ptr(cl->wbfs.cstats); -+ break; -+ default: -+ qstats->drops++; -+ goto drop; -+ } -+ -+ bstats_update(&cstats->bstats, skb); -+ return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq); -+ -+drop: -+ dev_kfree_skb_any(skb); -+ return NET_XMIT_SUCCESS; -+} -+ -+static int __init ceetm_register(void) -+{ -+ int _errno = 0; -+ -+ pr_info(KBUILD_MODNAME ": " DPA_CEETM_DESCRIPTION "\n"); -+ -+ _errno = register_qdisc(&ceetm_qdisc_ops); -+ if (unlikely(_errno)) -+ pr_err(KBUILD_MODNAME -+ ": %s:%hu:%s(): register_qdisc() = %d\n", -+ KBUILD_BASENAME ".c", __LINE__, __func__, _errno); -+ -+ return _errno; -+} -+ -+static void __exit ceetm_unregister(void) -+{ -+ pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -+ KBUILD_BASENAME ".c", __func__); -+ -+ unregister_qdisc(&ceetm_qdisc_ops); -+} -+ -+module_init(ceetm_register); -+module_exit(ceetm_unregister); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h -@@ -0,0 +1,236 @@ -+/* Copyright 2008-2016 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __DPAA_ETH_CEETM_H -+#define __DPAA_ETH_CEETM_H -+ -+#include -+#include -+#include -+ -+#include "mac.h" -+#include "dpaa_eth_common.h" -+ -+/* Mask to determine the sub-portal id from a channel number */ -+#define CHANNEL_SP_MASK 0x1f -+/* The number of the last channel that services DCP0, connected to FMan 0. -+ * Value validated for B4 and T series platforms. -+ */ -+#define DCP0_MAX_CHANNEL 0x80f -+/* A2V=1 - field A2 is valid -+ * A0V=1 - field A0 is valid - enables frame confirmation -+ * OVOM=1 - override operation mode bits with values from A2 -+ * EBD=1 - external buffers are deallocated at the end of the FMan flow -+ * NL=0 - the BMI releases all the internal buffers -+ */ -+#define CEETM_CONTEXT_A 0x1a00000080000000 -+/* The ratio between the superior and inferior congestion state thresholds. The -+ * lower threshold is set to 7/8 of the superior one (as the default for WQ -+ * scheduling). -+ */ -+#define CEETM_CCGR_RATIO 0.875 -+/* For functional purposes, there are num_tx_queues pfifo qdiscs through which -+ * frames reach the driver. Their handles start from 1:21. Handles 1:1 to 1:20 -+ * are reserved for the maximum 32 CEETM channels (majors and minors are in -+ * hex). -+ */ -+#define PFIFO_MIN_OFFSET 0x21 -+ -+/* A maximum of 8 CQs can be linked to a CQ channel or to a WBFS scheduler. */ -+#define CEETM_MAX_PRIO_QCOUNT 8 -+#define CEETM_MAX_WBFS_QCOUNT 8 -+#define CEETM_MIN_WBFS_QCOUNT 4 -+ -+/* The id offsets of the CQs belonging to WBFS groups (ids 8-11/15 for group A -+ * and/or 12-15 for group B). -+ */ -+#define WBFS_GRP_A_OFFSET 8 -+#define WBFS_GRP_B_OFFSET 12 -+ -+#define WBFS_GRP_A 1 -+#define WBFS_GRP_B 2 -+#define WBFS_GRP_LARGE 3 -+ -+enum { -+ TCA_CEETM_UNSPEC, -+ TCA_CEETM_COPT, -+ TCA_CEETM_QOPS, -+ __TCA_CEETM_MAX, -+}; -+ -+/* CEETM configuration types */ -+enum { -+ CEETM_ROOT = 1, -+ CEETM_PRIO, -+ CEETM_WBFS -+}; -+ -+#define TCA_CEETM_MAX (__TCA_CEETM_MAX - 1) -+extern const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1]; -+ -+struct ceetm_class; -+struct ceetm_qdisc_stats; -+struct ceetm_class_stats; -+ -+struct ceetm_fq { -+ struct qman_fq fq; -+ struct net_device *net_dev; -+ struct ceetm_class *ceetm_cls; -+}; -+ -+struct root_q { -+ struct Qdisc **qdiscs; -+ __u16 overhead; -+ __u32 rate; -+ __u32 ceil; -+ struct qm_ceetm_sp *sp; -+ struct qm_ceetm_lni *lni; -+ struct ceetm_qdisc_stats __percpu *qstats; -+}; -+ -+struct prio_q { -+ __u16 qcount; -+ struct ceetm_class *parent; -+}; -+ -+struct wbfs_q { -+ __u16 qcount; -+ int group_type; -+ struct ceetm_class *parent; -+ __u16 cr; -+ __u16 er; -+}; -+ -+struct ceetm_qdisc { -+ int type; /* LNI/CHNL/WBFS */ -+ bool shaped; -+ union { -+ struct root_q root; -+ struct prio_q prio; -+ struct wbfs_q wbfs; -+ }; -+ struct Qdisc_class_hash clhash; -+ struct tcf_proto *filter_list; /* qdisc attached filters */ -+}; -+ -+/* CEETM Qdisc configuration parameters */ -+struct tc_ceetm_qopt { -+ __u32 type; -+ __u16 shaped; -+ __u16 qcount; -+ __u16 overhead; -+ __u32 rate; -+ __u32 ceil; -+ __u16 cr; -+ __u16 er; -+ __u8 qweight[CEETM_MAX_WBFS_QCOUNT]; -+}; -+ -+struct root_c { -+ unsigned int rate; -+ unsigned int ceil; -+ unsigned int tbl; -+ bool wbfs_grp_a; -+ bool wbfs_grp_b; -+ bool wbfs_grp_large; -+ struct Qdisc *child; -+ struct qm_ceetm_channel *ch; -+}; -+ -+struct prio_c { -+ bool cr; -+ bool er; -+ struct ceetm_fq *fq; /* Hardware FQ instance Handle */ -+ struct qm_ceetm_lfq *lfq; -+ struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */ -+ struct qm_ceetm_ccg *ccg; -+ /* only one wbfs can be linked to one priority CQ */ -+ struct Qdisc *child; -+ struct ceetm_class_stats __percpu *cstats; -+}; -+ -+struct wbfs_c { -+ __u8 weight; /* The weight of the class between 1 and 248 */ -+ struct ceetm_fq *fq; /* Hardware FQ instance Handle */ -+ struct qm_ceetm_lfq *lfq; -+ struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */ -+ struct qm_ceetm_ccg *ccg; -+ struct ceetm_class_stats __percpu *cstats; -+}; -+ -+struct ceetm_class { -+ struct Qdisc_class_common common; -+ int refcnt; /* usage count of this class */ -+ struct tcf_proto *filter_list; /* class attached filters */ -+ struct Qdisc *parent; -+ bool shaped; -+ int type; /* ROOT/PRIO/WBFS */ -+ union { -+ struct root_c root; -+ struct prio_c prio; -+ struct wbfs_c wbfs; -+ }; -+}; -+ -+/* CEETM Class configuration parameters */ -+struct tc_ceetm_copt { -+ __u32 type; -+ __u16 shaped; -+ __u32 rate; -+ __u32 ceil; -+ __u16 tbl; -+ __u16 cr; -+ __u16 er; -+ __u8 weight; -+}; -+ -+/* CEETM stats */ -+struct ceetm_qdisc_stats { -+ __u32 drops; -+}; -+ -+struct ceetm_class_stats { -+ /* Software counters */ -+ struct gnet_stats_basic_packed bstats; -+ __u32 ern_drop_count; -+ __u32 congested_count; -+}; -+ -+struct tc_ceetm_xstats { -+ __u32 ern_drop_count; -+ __u32 congested_count; -+ /* Hardware counters */ -+ __u64 frame_count; -+ __u64 byte_count; -+}; -+ -+int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev); -+#endif ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -0,0 +1,1812 @@ -+/* Copyright 2008-2013 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include /* vlan_eth_hdr */ -+#include "dpaa_eth.h" -+#include "dpaa_eth_common.h" -+#ifdef CONFIG_FSL_DPAA_1588 -+#include "dpaa_1588.h" -+#endif -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+#include "dpaa_debugfs.h" -+#endif /* CONFIG_FSL_DPAA_DBG_LOOP */ -+#include "mac.h" -+ -+/* Size in bytes of the FQ taildrop threshold */ -+#define DPA_FQ_TD 0x200000 -+ -+#ifdef CONFIG_PTP_1588_CLOCK_DPAA -+struct ptp_priv_s ptp_priv; -+#endif -+ -+static struct dpa_bp *dpa_bp_array[64]; -+ -+int dpa_max_frm; -+EXPORT_SYMBOL(dpa_max_frm); -+ -+int dpa_rx_extra_headroom; -+EXPORT_SYMBOL(dpa_rx_extra_headroom); -+ -+int dpa_num_cpus = NR_CPUS; -+ -+static const struct fqid_cell tx_confirm_fqids[] = { -+ {0, DPAA_ETH_TX_QUEUES} -+}; -+ -+static struct fqid_cell default_fqids[][3] = { -+ [RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} }, -+ [TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} } -+}; -+ -+static const char fsl_qman_frame_queues[][25] = { -+ [RX] = "fsl,qman-frame-queues-rx", -+ [TX] = "fsl,qman-frame-queues-tx" -+}; -+#ifdef CONFIG_FSL_DPAA_HOOKS -+/* A set of callbacks for hooking into the fastpath at different points. */ -+struct dpaa_eth_hooks_s dpaa_eth_hooks; -+EXPORT_SYMBOL(dpaa_eth_hooks); -+/* This function should only be called on the probe paths, since it makes no -+ * effort to guarantee consistency of the destination hooks structure. -+ */ -+void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks) -+{ -+ if (hooks) -+ dpaa_eth_hooks = *hooks; -+ else -+ pr_err("NULL pointer to hooks!\n"); -+} -+EXPORT_SYMBOL(fsl_dpaa_eth_set_hooks); -+#endif -+ -+int dpa_netdev_init(struct net_device *net_dev, -+ const uint8_t *mac_addr, -+ uint16_t tx_timeout) -+{ -+ int err; -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct device *dev = net_dev->dev.parent; -+ -+ net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; -+ -+ net_dev->features |= net_dev->hw_features; -+ net_dev->vlan_features = net_dev->features; -+ -+ memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len); -+ memcpy(net_dev->dev_addr, mac_addr, net_dev->addr_len); -+ -+ net_dev->ethtool_ops = &dpa_ethtool_ops; -+ -+ net_dev->needed_headroom = priv->tx_headroom; -+ net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout); -+ -+ err = register_netdev(net_dev); -+ if (err < 0) { -+ dev_err(dev, "register_netdev() = %d\n", err); -+ return err; -+ } -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+ /* create debugfs entry for this net_device */ -+ err = dpa_netdev_debugfs_create(net_dev); -+ if (err) { -+ unregister_netdev(net_dev); -+ return err; -+ } -+#endif /* CONFIG_FSL_DPAA_DBG_LOOP */ -+ -+ return 0; -+} -+EXPORT_SYMBOL(dpa_netdev_init); -+ -+int __cold dpa_start(struct net_device *net_dev) -+{ -+ int err, i; -+ struct dpa_priv_s *priv; -+ struct mac_device *mac_dev; -+ -+ priv = netdev_priv(net_dev); -+ mac_dev = priv->mac_dev; -+ -+ err = mac_dev->init_phy(net_dev, priv->mac_dev); -+ if (err < 0) { -+ if (netif_msg_ifup(priv)) -+ netdev_err(net_dev, "init_phy() = %d\n", err); -+ return err; -+ } -+ -+ for_each_port_device(i, mac_dev->port_dev) { -+ err = fm_port_enable(mac_dev->port_dev[i]); -+ if (err) -+ goto mac_start_failed; -+ } -+ -+ err = priv->mac_dev->start(mac_dev); -+ if (err < 0) { -+ if (netif_msg_ifup(priv)) -+ netdev_err(net_dev, "mac_dev->start() = %d\n", err); -+ goto mac_start_failed; -+ } -+ -+ netif_tx_start_all_queues(net_dev); -+ -+ return 0; -+ -+mac_start_failed: -+ for_each_port_device(i, mac_dev->port_dev) -+ fm_port_disable(mac_dev->port_dev[i]); -+ -+ return err; -+} -+EXPORT_SYMBOL(dpa_start); -+ -+int __cold dpa_stop(struct net_device *net_dev) -+{ -+ int _errno, i, err; -+ struct dpa_priv_s *priv; -+ struct mac_device *mac_dev; -+ -+ priv = netdev_priv(net_dev); -+ mac_dev = priv->mac_dev; -+ -+ netif_tx_stop_all_queues(net_dev); -+ /* Allow the Fman (Tx) port to process in-flight frames before we -+ * try switching it off. -+ */ -+ usleep_range(5000, 10000); -+ -+ _errno = mac_dev->stop(mac_dev); -+ if (unlikely(_errno < 0)) -+ if (netif_msg_ifdown(priv)) -+ netdev_err(net_dev, "mac_dev->stop() = %d\n", -+ _errno); -+ -+ for_each_port_device(i, mac_dev->port_dev) { -+ err = fm_port_disable(mac_dev->port_dev[i]); -+ _errno = err ? err : _errno; -+ } -+ -+ if (mac_dev->phy_dev) -+ phy_disconnect(mac_dev->phy_dev); -+ mac_dev->phy_dev = NULL; -+ -+ return _errno; -+} -+EXPORT_SYMBOL(dpa_stop); -+ -+void __cold dpa_timeout(struct net_device *net_dev) -+{ -+ const struct dpa_priv_s *priv; -+ struct dpa_percpu_priv_s *percpu_priv; -+ -+ priv = netdev_priv(net_dev); -+ percpu_priv = raw_cpu_ptr(priv->percpu_priv); -+ -+ if (netif_msg_timer(priv)) -+ netdev_crit(net_dev, "Transmit timeout!\n"); -+ -+ percpu_priv->stats.tx_errors++; -+} -+EXPORT_SYMBOL(dpa_timeout); -+ -+/* net_device */ -+ -+/** -+ * @param net_dev the device for which statistics are calculated -+ * @param stats the function fills this structure with the device's statistics -+ * @return the address of the structure containing the statistics -+ * -+ * Calculates the statistics for the given device by adding the statistics -+ * collected by each CPU. -+ */ -+void __cold -+dpa_get_stats64(struct net_device *net_dev, -+ struct rtnl_link_stats64 *stats) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ u64 *cpustats; -+ u64 *netstats = (u64 *)stats; -+ int i, j; -+ struct dpa_percpu_priv_s *percpu_priv; -+ int numstats = sizeof(struct rtnl_link_stats64) / sizeof(u64); -+ -+ for_each_possible_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ -+ cpustats = (u64 *)&percpu_priv->stats; -+ -+ for (j = 0; j < numstats; j++) -+ netstats[j] += cpustats[j]; -+ } -+} -+EXPORT_SYMBOL(dpa_get_stats64); -+ -+int dpa_change_mtu(struct net_device *net_dev, int new_mtu) -+{ -+ const int max_mtu = dpa_get_max_mtu(); -+ -+ /* Make sure we don't exceed the Ethernet controller's MAXFRM */ -+ if (new_mtu < 68 || new_mtu > max_mtu) { -+ netdev_err(net_dev, "Invalid L3 mtu %d (must be between %d and %d).\n", -+ new_mtu, 68, max_mtu); -+ return -EINVAL; -+ } -+ net_dev->mtu = new_mtu; -+ -+ return 0; -+} -+EXPORT_SYMBOL(dpa_change_mtu); -+ -+/* .ndo_init callback */ -+int dpa_ndo_init(struct net_device *net_dev) -+{ -+ /* If fsl_fm_max_frm is set to a higher value than the all-common 1500, -+ * we choose conservatively and let the user explicitly set a higher -+ * MTU via ifconfig. Otherwise, the user may end up with different MTUs -+ * in the same LAN. -+ * If on the other hand fsl_fm_max_frm has been chosen below 1500, -+ * start with the maximum allowed. -+ */ -+ int init_mtu = min(dpa_get_max_mtu(), ETH_DATA_LEN); -+ -+ pr_debug("Setting initial MTU on net device: %d\n", init_mtu); -+ net_dev->mtu = init_mtu; -+ -+ return 0; -+} -+EXPORT_SYMBOL(dpa_ndo_init); -+ -+int dpa_set_features(struct net_device *dev, netdev_features_t features) -+{ -+ /* Not much to do here for now */ -+ dev->features = features; -+ return 0; -+} -+EXPORT_SYMBOL(dpa_set_features); -+ -+netdev_features_t dpa_fix_features(struct net_device *dev, -+ netdev_features_t features) -+{ -+ netdev_features_t unsupported_features = 0; -+ -+ /* In theory we should never be requested to enable features that -+ * we didn't set in netdev->features and netdev->hw_features at probe -+ * time, but double check just to be on the safe side. -+ * We don't support enabling Rx csum through ethtool yet -+ */ -+ unsupported_features |= NETIF_F_RXCSUM; -+ -+ features &= ~unsupported_features; -+ -+ return features; -+} -+EXPORT_SYMBOL(dpa_fix_features); -+ -+#ifdef CONFIG_FSL_DPAA_TS -+u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx, -+ const void *data) -+{ -+ u64 *ts, ns; -+ -+ ts = fm_port_get_buffer_time_stamp(priv->mac_dev->port_dev[rx_tx], -+ data); -+ -+ if (!ts || *ts == 0) -+ return 0; -+ -+ be64_to_cpus(ts); -+ -+ /* multiple DPA_PTP_NOMINAL_FREQ_PERIOD_NS for case of non power of 2 */ -+ ns = *ts << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT; -+ -+ return ns; -+} -+ -+int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx, -+ struct skb_shared_hwtstamps *shhwtstamps, const void *data) -+{ -+ u64 ns; -+ -+ ns = dpa_get_timestamp_ns(priv, rx_tx, data); -+ -+ if (ns == 0) -+ return -EINVAL; -+ -+ memset(shhwtstamps, 0, sizeof(*shhwtstamps)); -+ shhwtstamps->hwtstamp = ns_to_ktime(ns); -+ -+ return 0; -+} -+ -+static void dpa_ts_tx_enable(struct net_device *dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(dev); -+ struct mac_device *mac_dev = priv->mac_dev; -+ -+ if (mac_dev->fm_rtc_enable) -+ mac_dev->fm_rtc_enable(get_fm_handle(dev)); -+ if (mac_dev->ptp_enable) -+ mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev)); -+ -+ priv->ts_tx_en = true; -+} -+ -+static void dpa_ts_tx_disable(struct net_device *dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(dev); -+ -+#if 0 -+/* the RTC might be needed by the Rx Ts, cannot disable here -+ * no separate ptp_disable API for Rx/Tx, cannot disable here -+ */ -+ struct mac_device *mac_dev = priv->mac_dev; -+ -+ if (mac_dev->fm_rtc_disable) -+ mac_dev->fm_rtc_disable(get_fm_handle(dev)); -+ -+ if (mac_dev->ptp_disable) -+ mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev)); -+#endif -+ -+ priv->ts_tx_en = false; -+} -+ -+static void dpa_ts_rx_enable(struct net_device *dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(dev); -+ struct mac_device *mac_dev = priv->mac_dev; -+ -+ if (mac_dev->fm_rtc_enable) -+ mac_dev->fm_rtc_enable(get_fm_handle(dev)); -+ if (mac_dev->ptp_enable) -+ mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev)); -+ -+ priv->ts_rx_en = true; -+} -+ -+static void dpa_ts_rx_disable(struct net_device *dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(dev); -+ -+#if 0 -+/* the RTC might be needed by the Tx Ts, cannot disable here -+ * no separate ptp_disable API for Rx/Tx, cannot disable here -+ */ -+ struct mac_device *mac_dev = priv->mac_dev; -+ -+ if (mac_dev->fm_rtc_disable) -+ mac_dev->fm_rtc_disable(get_fm_handle(dev)); -+ -+ if (mac_dev->ptp_disable) -+ mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev)); -+#endif -+ -+ priv->ts_rx_en = false; -+} -+ -+static int dpa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -+{ -+ struct hwtstamp_config config; -+ -+ if (copy_from_user(&config, rq->ifr_data, sizeof(config))) -+ return -EFAULT; -+ -+ switch (config.tx_type) { -+ case HWTSTAMP_TX_OFF: -+ dpa_ts_tx_disable(dev); -+ break; -+ case HWTSTAMP_TX_ON: -+ dpa_ts_tx_enable(dev); -+ break; -+ default: -+ return -ERANGE; -+ } -+ -+ if (config.rx_filter == HWTSTAMP_FILTER_NONE) -+ dpa_ts_rx_disable(dev); -+ else { -+ dpa_ts_rx_enable(dev); -+ /* TS is set for all frame types, not only those requested */ -+ config.rx_filter = HWTSTAMP_FILTER_ALL; -+ } -+ -+ return copy_to_user(rq->ifr_data, &config, sizeof(config)) ? -+ -EFAULT : 0; -+} -+#endif /* CONFIG_FSL_DPAA_TS */ -+ -+int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -+{ -+#ifdef CONFIG_FSL_DPAA_1588 -+ struct dpa_priv_s *priv = netdev_priv(dev); -+#endif -+ int ret = 0; -+ -+ /* at least one timestamping feature must be enabled */ -+#ifdef CONFIG_FSL_DPAA_TS -+ if (!netif_running(dev)) -+#endif -+ return -EINVAL; -+ -+#ifdef CONFIG_FSL_DPAA_TS -+ if (cmd == SIOCSHWTSTAMP) -+ return dpa_ts_ioctl(dev, rq, cmd); -+#endif /* CONFIG_FSL_DPAA_TS */ -+ -+#ifdef CONFIG_FSL_DPAA_1588 -+ if ((cmd >= PTP_ENBL_TXTS_IOCTL) && (cmd <= PTP_CLEANUP_TS)) { -+ if (priv->tsu && priv->tsu->valid) -+ ret = dpa_ioctl_1588(dev, rq, cmd); -+ else -+ ret = -ENODEV; -+ } -+#endif -+ -+ return ret; -+} -+EXPORT_SYMBOL(dpa_ioctl); -+ -+int __cold dpa_remove(struct platform_device *of_dev) -+{ -+ int err; -+ struct device *dev; -+ struct net_device *net_dev; -+ struct dpa_priv_s *priv; -+ -+ dev = &of_dev->dev; -+ net_dev = dev_get_drvdata(dev); -+ -+ priv = netdev_priv(net_dev); -+ -+ dpaa_eth_sysfs_remove(dev); -+ -+ dev_set_drvdata(dev, NULL); -+ unregister_netdev(net_dev); -+ -+ err = dpa_fq_free(dev, &priv->dpa_fq_list); -+ -+ qman_delete_cgr_safe(&priv->ingress_cgr); -+ qman_release_cgrid(priv->ingress_cgr.cgrid); -+ qman_delete_cgr_safe(&priv->cgr_data.cgr); -+ qman_release_cgrid(priv->cgr_data.cgr.cgrid); -+ -+ dpa_private_napi_del(net_dev); -+ -+ dpa_bp_free(priv); -+ -+ if (priv->buf_layout) -+ devm_kfree(dev, priv->buf_layout); -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+ /* remove debugfs entry for this net_device */ -+ dpa_netdev_debugfs_remove(net_dev); -+#endif /* CONFIG_FSL_DPAA_DBG_LOOP */ -+ -+#ifdef CONFIG_FSL_DPAA_1588 -+ if (priv->tsu && priv->tsu->valid) -+ dpa_ptp_cleanup(priv); -+#endif -+ -+ free_netdev(net_dev); -+ -+ return err; -+} -+EXPORT_SYMBOL(dpa_remove); -+ -+struct mac_device * __cold __must_check -+__attribute__((nonnull)) -+dpa_mac_probe(struct platform_device *_of_dev) -+{ -+ struct device *dpa_dev, *dev; -+ struct device_node *mac_node; -+ struct platform_device *of_dev; -+ struct mac_device *mac_dev; -+#ifdef CONFIG_FSL_DPAA_1588 -+ int lenp; -+ const phandle *phandle_prop; -+ struct net_device *net_dev = NULL; -+ struct dpa_priv_s *priv = NULL; -+ struct device_node *timer_node; -+#endif -+ dpa_dev = &_of_dev->dev; -+ -+ mac_node = of_parse_phandle(_of_dev->dev.of_node, "fsl,fman-mac", 0); -+ if (unlikely(mac_node == NULL)) { -+ dev_err(dpa_dev, "Cannot find MAC device device tree node\n"); -+ return ERR_PTR(-EFAULT); -+ } -+ -+ of_dev = of_find_device_by_node(mac_node); -+ if (unlikely(of_dev == NULL)) { -+ dev_err(dpa_dev, "of_find_device_by_node(%s) failed\n", -+ mac_node->full_name); -+ of_node_put(mac_node); -+ return ERR_PTR(-EINVAL); -+ } -+ of_node_put(mac_node); -+ -+ dev = &of_dev->dev; -+ -+ mac_dev = dev_get_drvdata(dev); -+ if (unlikely(mac_dev == NULL)) { -+ dev_err(dpa_dev, "dev_get_drvdata(%s) failed\n", -+ dev_name(dev)); -+ return ERR_PTR(-EINVAL); -+ } -+ -+#ifdef CONFIG_FSL_DPAA_1588 -+ phandle_prop = of_get_property(mac_node, "ptimer-handle", &lenp); -+ if (phandle_prop && ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) || -+ ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) && -+ (mac_dev->speed == SPEED_1000)))) { -+ timer_node = of_find_node_by_phandle(*phandle_prop); -+ if (timer_node) -+ net_dev = dev_get_drvdata(dpa_dev); -+ if (timer_node && net_dev) { -+ priv = netdev_priv(net_dev); -+ if (!dpa_ptp_init(priv)) -+ dev_info(dev, "%s: ptp 1588 is initialized.\n", -+ mac_node->full_name); -+ } -+ } -+#endif -+ -+#ifdef CONFIG_PTP_1588_CLOCK_DPAA -+ if ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) || -+ ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) && -+ (mac_dev->speed == SPEED_1000))) { -+ ptp_priv.node = of_parse_phandle(mac_node, "ptimer-handle", 0); -+ if (ptp_priv.node) { -+ ptp_priv.of_dev = of_find_device_by_node(ptp_priv.node); -+ if (unlikely(ptp_priv.of_dev == NULL)) { -+ dev_err(dpa_dev, -+ "Cannot find device represented by timer_node\n"); -+ of_node_put(ptp_priv.node); -+ return ERR_PTR(-EINVAL); -+ } -+ ptp_priv.mac_dev = mac_dev; -+ } -+ } -+#endif -+ return mac_dev; -+} -+EXPORT_SYMBOL(dpa_mac_probe); -+ -+int dpa_set_mac_address(struct net_device *net_dev, void *addr) -+{ -+ const struct dpa_priv_s *priv; -+ int _errno; -+ struct mac_device *mac_dev; -+ -+ priv = netdev_priv(net_dev); -+ -+ _errno = eth_mac_addr(net_dev, addr); -+ if (_errno < 0) { -+ if (netif_msg_drv(priv)) -+ netdev_err(net_dev, -+ "eth_mac_addr() = %d\n", -+ _errno); -+ return _errno; -+ } -+ -+ mac_dev = priv->mac_dev; -+ -+ _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev), -+ net_dev->dev_addr); -+ if (_errno < 0) { -+ if (netif_msg_drv(priv)) -+ netdev_err(net_dev, -+ "mac_dev->change_addr() = %d\n", -+ _errno); -+ return _errno; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(dpa_set_mac_address); -+ -+void dpa_set_rx_mode(struct net_device *net_dev) -+{ -+ int _errno; -+ const struct dpa_priv_s *priv; -+ -+ priv = netdev_priv(net_dev); -+ -+ if (!!(net_dev->flags & IFF_PROMISC) != priv->mac_dev->promisc) { -+ priv->mac_dev->promisc = !priv->mac_dev->promisc; -+ _errno = priv->mac_dev->set_promisc( -+ priv->mac_dev->get_mac_handle(priv->mac_dev), -+ priv->mac_dev->promisc); -+ if (unlikely(_errno < 0) && netif_msg_drv(priv)) -+ netdev_err(net_dev, -+ "mac_dev->set_promisc() = %d\n", -+ _errno); -+ } -+ -+ _errno = priv->mac_dev->set_multi(net_dev, priv->mac_dev); -+ if (unlikely(_errno < 0) && netif_msg_drv(priv)) -+ netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno); -+} -+EXPORT_SYMBOL(dpa_set_rx_mode); -+ -+void dpa_set_buffers_layout(struct mac_device *mac_dev, -+ struct dpa_buffer_layout_s *layout) -+{ -+ struct fm_port_params params; -+ -+ /* Rx */ -+ layout[RX].priv_data_size = (uint16_t)DPA_RX_PRIV_DATA_SIZE; -+ layout[RX].parse_results = true; -+ layout[RX].hash_results = true; -+#ifdef CONFIG_FSL_DPAA_TS -+ layout[RX].time_stamp = true; -+#endif -+ fm_port_get_buff_layout_ext_params(mac_dev->port_dev[RX], ¶ms); -+ layout[RX].manip_extra_space = params.manip_extra_space; -+ /* a value of zero for data alignment means "don't care", so align to -+ * a non-zero value to prevent FMD from using its own default -+ */ -+ layout[RX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT; -+ -+ /* Tx */ -+ layout[TX].priv_data_size = DPA_TX_PRIV_DATA_SIZE; -+ layout[TX].parse_results = true; -+ layout[TX].hash_results = true; -+#ifdef CONFIG_FSL_DPAA_TS -+ layout[TX].time_stamp = true; -+#endif -+ fm_port_get_buff_layout_ext_params(mac_dev->port_dev[TX], ¶ms); -+ layout[TX].manip_extra_space = params.manip_extra_space; -+ layout[TX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT; -+} -+EXPORT_SYMBOL(dpa_set_buffers_layout); -+ -+int __attribute__((nonnull)) -+dpa_bp_alloc(struct dpa_bp *dpa_bp) -+{ -+ int err; -+ struct bman_pool_params bp_params; -+ struct platform_device *pdev; -+ -+ if (dpa_bp->size == 0 || dpa_bp->config_count == 0) { -+ pr_err("Buffer pool is not properly initialized! Missing size or initial number of buffers"); -+ return -EINVAL; -+ } -+ -+ memset(&bp_params, 0, sizeof(struct bman_pool_params)); -+#ifdef CONFIG_FMAN_PFC -+ bp_params.flags = BMAN_POOL_FLAG_THRESH; -+ bp_params.thresholds[0] = bp_params.thresholds[2] = -+ CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD; -+ bp_params.thresholds[1] = bp_params.thresholds[3] = -+ CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT; -+#endif -+ -+ /* If the pool is already specified, we only create one per bpid */ -+ if (dpa_bpid2pool_use(dpa_bp->bpid)) -+ return 0; -+ -+ if (dpa_bp->bpid == 0) -+ bp_params.flags |= BMAN_POOL_FLAG_DYNAMIC_BPID; -+ else -+ bp_params.bpid = dpa_bp->bpid; -+ -+ dpa_bp->pool = bman_new_pool(&bp_params); -+ if (unlikely(dpa_bp->pool == NULL)) { -+ pr_err("bman_new_pool() failed\n"); -+ return -ENODEV; -+ } -+ -+ dpa_bp->bpid = (uint8_t)bman_get_params(dpa_bp->pool)->bpid; -+ -+ pdev = platform_device_register_simple("dpaa_eth_bpool", -+ dpa_bp->bpid, NULL, 0); -+ if (IS_ERR(pdev)) { -+ pr_err("platform_device_register_simple() failed\n"); -+ err = PTR_ERR(pdev); -+ goto pdev_register_failed; -+ } -+ { -+ struct dma_map_ops *ops = get_dma_ops(&pdev->dev); -+ ops->dma_supported = NULL; -+ } -+ err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40)); -+ if (err) { -+ pr_err("dma_coerce_mask_and_coherent() failed\n"); -+ goto pdev_mask_failed; -+ } -+#ifdef CONFIG_FMAN_ARM -+ /* force coherency */ -+ pdev->dev.archdata.dma_coherent = true; -+ arch_setup_dma_ops(&pdev->dev, 0, 0, NULL, true); -+#endif -+ -+ dpa_bp->dev = &pdev->dev; -+ -+ if (dpa_bp->seed_cb) { -+ err = dpa_bp->seed_cb(dpa_bp); -+ if (err) -+ goto pool_seed_failed; -+ } -+ -+ dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp); -+ -+ return 0; -+ -+pool_seed_failed: -+pdev_mask_failed: -+ platform_device_unregister(pdev); -+pdev_register_failed: -+ bman_free_pool(dpa_bp->pool); -+ -+ return err; -+} -+EXPORT_SYMBOL(dpa_bp_alloc); -+ -+void dpa_bp_drain(struct dpa_bp *bp) -+{ -+ int ret, num = 8; -+ -+ do { -+ struct bm_buffer bmb[8]; -+ int i; -+ -+ ret = bman_acquire(bp->pool, bmb, num, 0); -+ if (ret < 0) { -+ if (num == 8) { -+ /* we have less than 8 buffers left; -+ * drain them one by one -+ */ -+ num = 1; -+ ret = 1; -+ continue; -+ } else { -+ /* Pool is fully drained */ -+ break; -+ } -+ } -+ -+ for (i = 0; i < num; i++) { -+ dma_addr_t addr = bm_buf_addr(&bmb[i]); -+ -+ dma_unmap_single(bp->dev, addr, bp->size, -+ DMA_BIDIRECTIONAL); -+ -+ bp->free_buf_cb(phys_to_virt(addr)); -+ } -+ } while (ret > 0); -+} -+EXPORT_SYMBOL(dpa_bp_drain); -+ -+static void __cold __attribute__((nonnull)) -+_dpa_bp_free(struct dpa_bp *dpa_bp) -+{ -+ struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid); -+ -+ /* the mapping between bpid and dpa_bp is done very late in the -+ * allocation procedure; if something failed before the mapping, the bp -+ * was not configured, therefore we don't need the below instructions -+ */ -+ if (!bp) -+ return; -+ -+ if (!atomic_dec_and_test(&bp->refs)) -+ return; -+ -+ if (bp->free_buf_cb) -+ dpa_bp_drain(bp); -+ -+ dpa_bp_array[bp->bpid] = NULL; -+ bman_free_pool(bp->pool); -+ -+ if (bp->dev) -+ platform_device_unregister(to_platform_device(bp->dev)); -+} -+ -+void __cold __attribute__((nonnull)) -+dpa_bp_free(struct dpa_priv_s *priv) -+{ -+ int i; -+ -+ if (priv->dpa_bp) -+ for (i = 0; i < priv->bp_count; i++) -+ _dpa_bp_free(&priv->dpa_bp[i]); -+} -+EXPORT_SYMBOL(dpa_bp_free); -+ -+struct dpa_bp *dpa_bpid2pool(int bpid) -+{ -+ return dpa_bp_array[bpid]; -+} -+EXPORT_SYMBOL(dpa_bpid2pool); -+ -+void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp) -+{ -+ dpa_bp_array[bpid] = dpa_bp; -+ atomic_set(&dpa_bp->refs, 1); -+} -+ -+bool dpa_bpid2pool_use(int bpid) -+{ -+ if (dpa_bpid2pool(bpid)) { -+ atomic_inc(&dpa_bp_array[bpid]->refs); -+ return true; -+ } -+ -+ return false; -+} -+ -+#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -+u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb, -+ struct net_device *sb_dev, -+ select_queue_fallback_t fallback) -+{ -+ return dpa_get_queue_mapping(skb); -+} -+EXPORT_SYMBOL(dpa_select_queue); -+#endif -+ -+struct dpa_fq *dpa_fq_alloc(struct device *dev, -+ u32 fq_start, -+ u32 fq_count, -+ struct list_head *list, -+ enum dpa_fq_type fq_type) -+{ -+ int i; -+ struct dpa_fq *dpa_fq; -+ -+ dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fq_count, GFP_KERNEL); -+ if (dpa_fq == NULL) -+ return NULL; -+ -+ for (i = 0; i < fq_count; i++) { -+ dpa_fq[i].fq_type = fq_type; -+ if (fq_type == FQ_TYPE_RX_PCD_HI_PRIO) -+ dpa_fq[i].fqid = fq_start ? -+ DPAA_ETH_FQ_DELTA + fq_start + i : 0; -+ else -+ dpa_fq[i].fqid = fq_start ? fq_start + i : 0; -+ -+ list_add_tail(&dpa_fq[i].list, list); -+ } -+ -+#ifdef CONFIG_FMAN_PFC -+ if (fq_type == FQ_TYPE_TX) -+ for (i = 0; i < fq_count; i++) -+ dpa_fq[i].wq = i / dpa_num_cpus; -+ else -+#endif -+ for (i = 0; i < fq_count; i++) -+ _dpa_assign_wq(dpa_fq + i); -+ -+ return dpa_fq; -+} -+EXPORT_SYMBOL(dpa_fq_alloc); -+ -+/* Probing of FQs for MACful ports */ -+int dpa_fq_probe_mac(struct device *dev, struct list_head *list, -+ struct fm_port_fqs *port_fqs, -+ bool alloc_tx_conf_fqs, -+ enum port_type ptype) -+{ -+ struct fqid_cell *fqids = NULL; -+ const void *fqids_off = NULL; -+ struct dpa_fq *dpa_fq = NULL; -+ struct device_node *np = dev->of_node; -+ int num_ranges; -+ int i, lenp; -+ -+ if (ptype == TX && alloc_tx_conf_fqs) { -+ if (!dpa_fq_alloc(dev, tx_confirm_fqids->start, -+ tx_confirm_fqids->count, list, -+ FQ_TYPE_TX_CONF_MQ)) -+ goto fq_alloc_failed; -+ } -+ -+ fqids_off = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp); -+ if (fqids_off == NULL) { -+ /* No dts definition, so use the defaults. */ -+ fqids = default_fqids[ptype]; -+ num_ranges = 3; -+ } else { -+ num_ranges = lenp / sizeof(*fqids); -+ -+ fqids = devm_kzalloc(dev, sizeof(*fqids) * num_ranges, -+ GFP_KERNEL); -+ if (fqids == NULL) -+ goto fqids_alloc_failed; -+ -+ /* convert to CPU endianess */ -+ for (i = 0; i < num_ranges; i++) { -+ fqids[i].start = be32_to_cpup(fqids_off + -+ i * sizeof(*fqids)); -+ fqids[i].count = be32_to_cpup(fqids_off + -+ i * sizeof(*fqids) + sizeof(__be32)); -+ } -+ } -+ -+ for (i = 0; i < num_ranges; i++) { -+ switch (i) { -+ case 0: -+ /* The first queue is the error queue */ -+ if (fqids[i].count != 1) -+ goto invalid_error_queue; -+ -+ dpa_fq = dpa_fq_alloc(dev, fqids[i].start, -+ fqids[i].count, list, -+ ptype == RX ? -+ FQ_TYPE_RX_ERROR : -+ FQ_TYPE_TX_ERROR); -+ if (dpa_fq == NULL) -+ goto fq_alloc_failed; -+ -+ if (ptype == RX) -+ port_fqs->rx_errq = &dpa_fq[0]; -+ else -+ port_fqs->tx_errq = &dpa_fq[0]; -+ break; -+ case 1: -+ /* the second queue is the default queue */ -+ if (fqids[i].count != 1) -+ goto invalid_default_queue; -+ -+ dpa_fq = dpa_fq_alloc(dev, fqids[i].start, -+ fqids[i].count, list, -+ ptype == RX ? -+ FQ_TYPE_RX_DEFAULT : -+ FQ_TYPE_TX_CONFIRM); -+ if (dpa_fq == NULL) -+ goto fq_alloc_failed; -+ -+ if (ptype == RX) -+ port_fqs->rx_defq = &dpa_fq[0]; -+ else -+ port_fqs->tx_defq = &dpa_fq[0]; -+ break; -+ default: -+ /* all subsequent queues are either RX* PCD or Tx */ -+ if (ptype == RX) { -+ if (!dpa_fq_alloc(dev, fqids[i].start, -+ fqids[i].count, list, -+ FQ_TYPE_RX_PCD) || -+ !dpa_fq_alloc(dev, fqids[i].start, -+ fqids[i].count, list, -+ FQ_TYPE_RX_PCD_HI_PRIO)) -+ goto fq_alloc_failed; -+ } else { -+ if (!dpa_fq_alloc(dev, fqids[i].start, -+ fqids[i].count, list, -+ FQ_TYPE_TX)) -+ goto fq_alloc_failed; -+ } -+ break; -+ } -+ } -+ -+ return 0; -+ -+fq_alloc_failed: -+fqids_alloc_failed: -+ dev_err(dev, "Cannot allocate memory for frame queues\n"); -+ return -ENOMEM; -+ -+invalid_default_queue: -+invalid_error_queue: -+ dev_err(dev, "Too many default or error queues\n"); -+ return -EINVAL; -+} -+EXPORT_SYMBOL(dpa_fq_probe_mac); -+ -+static u32 rx_pool_channel; -+static DEFINE_SPINLOCK(rx_pool_channel_init); -+ -+int dpa_get_channel(void) -+{ -+ spin_lock(&rx_pool_channel_init); -+ if (!rx_pool_channel) { -+ u32 pool; -+ int ret = qman_alloc_pool(&pool); -+ if (!ret) -+ rx_pool_channel = pool; -+ } -+ spin_unlock(&rx_pool_channel_init); -+ if (!rx_pool_channel) -+ return -ENOMEM; -+ return rx_pool_channel; -+} -+EXPORT_SYMBOL(dpa_get_channel); -+ -+void dpa_release_channel(void) -+{ -+ qman_release_pool(rx_pool_channel); -+} -+EXPORT_SYMBOL(dpa_release_channel); -+ -+void dpaa_eth_add_channel(u16 channel) -+{ -+ const cpumask_t *cpus = qman_affine_cpus(); -+ u32 pool = QM_SDQCR_CHANNELS_POOL_CONV(channel); -+ int cpu; -+ struct qman_portal *portal; -+ -+ for_each_cpu(cpu, cpus) { -+ portal = (struct qman_portal *)qman_get_affine_portal(cpu); -+ qman_p_static_dequeue_add(portal, pool); -+ } -+} -+EXPORT_SYMBOL(dpaa_eth_add_channel); -+ -+/** -+ * Congestion group state change notification callback. -+ * Stops the device's egress queues while they are congested and -+ * wakes them upon exiting congested state. -+ * Also updates some CGR-related stats. -+ */ -+static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr, -+ -+ int congested) -+{ -+ struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr, -+ struct dpa_priv_s, cgr_data.cgr); -+ -+ if (congested) { -+ priv->cgr_data.congestion_start_jiffies = jiffies; -+ netif_tx_stop_all_queues(priv->net_dev); -+ priv->cgr_data.cgr_congested_count++; -+ } else { -+ priv->cgr_data.congested_jiffies += -+ (jiffies - priv->cgr_data.congestion_start_jiffies); -+ netif_tx_wake_all_queues(priv->net_dev); -+ } -+} -+ -+int dpaa_eth_cgr_init(struct dpa_priv_s *priv) -+{ -+ struct qm_mcc_initcgr initcgr; -+ u32 cs_th; -+ int err; -+ -+ err = qman_alloc_cgrid(&priv->cgr_data.cgr.cgrid); -+ if (err < 0) { -+ pr_err("Error %d allocating CGR ID\n", err); -+ goto out_error; -+ } -+ priv->cgr_data.cgr.cb = dpaa_eth_cgscn; -+ -+ /* Enable Congestion State Change Notifications and CS taildrop */ -+ initcgr.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES; -+ initcgr.cgr.cscn_en = QM_CGR_EN; -+ -+ /* Set different thresholds based on the MAC speed. -+ * TODO: this may turn suboptimal if the MAC is reconfigured at a speed -+ * lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link. -+ * In such cases, we ought to reconfigure the threshold, too. -+ */ -+ if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full) -+ cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G; -+ else -+ cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G; -+ qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1); -+ -+ initcgr.we_mask |= QM_CGR_WE_CSTD_EN; -+ initcgr.cgr.cstd_en = QM_CGR_EN; -+ -+ err = qman_create_cgr(&priv->cgr_data.cgr, QMAN_CGR_FLAG_USE_INIT, -+ &initcgr); -+ if (err < 0) { -+ pr_err("Error %d creating CGR with ID %d\n", err, -+ priv->cgr_data.cgr.cgrid); -+ qman_release_cgrid(priv->cgr_data.cgr.cgrid); -+ goto out_error; -+ } -+ pr_debug("Created CGR %d for netdev with hwaddr %pM on QMan channel %d\n", -+ priv->cgr_data.cgr.cgrid, priv->mac_dev->addr, -+ priv->cgr_data.cgr.chan); -+ -+out_error: -+ return err; -+} -+EXPORT_SYMBOL(dpaa_eth_cgr_init); -+ -+static inline void dpa_setup_ingress(const struct dpa_priv_s *priv, -+ struct dpa_fq *fq, -+ const struct qman_fq *template) -+{ -+ fq->fq_base = *template; -+ fq->net_dev = priv->net_dev; -+ -+ fq->flags = QMAN_FQ_FLAG_NO_ENQUEUE; -+ fq->channel = priv->channel; -+} -+ -+static inline void dpa_setup_egress(const struct dpa_priv_s *priv, -+ struct dpa_fq *fq, -+ struct fm_port *port, -+ const struct qman_fq *template) -+{ -+ fq->fq_base = *template; -+ fq->net_dev = priv->net_dev; -+ -+ if (port) { -+ fq->flags = QMAN_FQ_FLAG_TO_DCPORTAL; -+ fq->channel = (uint16_t)fm_get_tx_port_channel(port); -+ } else { -+ fq->flags = QMAN_FQ_FLAG_NO_MODIFY; -+ } -+} -+ -+void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs, -+ struct fm_port *tx_port) -+{ -+ struct dpa_fq *fq; -+ uint16_t portals[NR_CPUS]; -+ int cpu, portal_cnt = 0, num_portals = 0; -+ uint32_t pcd_fqid, pcd_fqid_hi_prio; -+ const cpumask_t *affine_cpus = qman_affine_cpus(); -+ int egress_cnt = 0, conf_cnt = 0; -+ -+ /* Prepare for PCD FQs init */ -+ for_each_cpu(cpu, affine_cpus) -+ portals[num_portals++] = qman_affine_channel(cpu); -+ if (num_portals == 0) -+ dev_err(priv->net_dev->dev.parent, -+ "No Qman software (affine) channels found"); -+ -+ pcd_fqid = (priv->mac_dev) ? -+ DPAA_ETH_PCD_FQ_BASE(priv->mac_dev->res->start) : 0; -+ pcd_fqid_hi_prio = (priv->mac_dev) ? -+ DPAA_ETH_PCD_FQ_HI_PRIO_BASE(priv->mac_dev->res->start) : 0; -+ -+ /* Initialize each FQ in the list */ -+ list_for_each_entry(fq, &priv->dpa_fq_list, list) { -+ switch (fq->fq_type) { -+ case FQ_TYPE_RX_DEFAULT: -+ BUG_ON(!priv->mac_dev); -+ dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq); -+ break; -+ case FQ_TYPE_RX_ERROR: -+ BUG_ON(!priv->mac_dev); -+ dpa_setup_ingress(priv, fq, &fq_cbs->rx_errq); -+ break; -+ case FQ_TYPE_RX_PCD: -+ /* For MACless we can't have dynamic Rx queues */ -+ BUG_ON(!priv->mac_dev && !fq->fqid); -+ dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq); -+ if (!fq->fqid) -+ fq->fqid = pcd_fqid++; -+ fq->channel = portals[portal_cnt]; -+ portal_cnt = (portal_cnt + 1) % num_portals; -+ break; -+ case FQ_TYPE_RX_PCD_HI_PRIO: -+ /* For MACless we can't have dynamic Hi Pri Rx queues */ -+ BUG_ON(!priv->mac_dev && !fq->fqid); -+ dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq); -+ if (!fq->fqid) -+ fq->fqid = pcd_fqid_hi_prio++; -+ fq->channel = portals[portal_cnt]; -+ portal_cnt = (portal_cnt + 1) % num_portals; -+ break; -+ case FQ_TYPE_TX: -+ dpa_setup_egress(priv, fq, tx_port, -+ &fq_cbs->egress_ern); -+ /* If we have more Tx queues than the number of cores, -+ * just ignore the extra ones. -+ */ -+ if (egress_cnt < DPAA_ETH_TX_QUEUES) -+ priv->egress_fqs[egress_cnt++] = &fq->fq_base; -+ break; -+ case FQ_TYPE_TX_CONFIRM: -+ BUG_ON(!priv->mac_dev); -+ dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq); -+ break; -+ case FQ_TYPE_TX_CONF_MQ: -+ BUG_ON(!priv->mac_dev); -+ dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq); -+ priv->conf_fqs[conf_cnt++] = &fq->fq_base; -+ break; -+ case FQ_TYPE_TX_ERROR: -+ BUG_ON(!priv->mac_dev); -+ dpa_setup_ingress(priv, fq, &fq_cbs->tx_errq); -+ break; -+ default: -+ dev_warn(priv->net_dev->dev.parent, -+ "Unknown FQ type detected!\n"); -+ break; -+ } -+ } -+ -+ /* The number of Tx queues may be smaller than the number of cores, if -+ * the Tx queue range is specified in the device tree instead of being -+ * dynamically allocated. -+ * Make sure all CPUs receive a corresponding Tx queue. -+ */ -+ while (egress_cnt < DPAA_ETH_TX_QUEUES) { -+ list_for_each_entry(fq, &priv->dpa_fq_list, list) { -+ if (fq->fq_type != FQ_TYPE_TX) -+ continue; -+ priv->egress_fqs[egress_cnt++] = &fq->fq_base; -+ if (egress_cnt == DPAA_ETH_TX_QUEUES) -+ break; -+ } -+ } -+} -+EXPORT_SYMBOL(dpa_fq_setup); -+ -+int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable) -+{ -+ int _errno; -+ const struct dpa_priv_s *priv; -+ struct device *dev; -+ struct qman_fq *fq; -+ struct qm_mcc_initfq initfq; -+ struct qman_fq *confq; -+ int queue_id; -+ -+ priv = netdev_priv(dpa_fq->net_dev); -+ dev = dpa_fq->net_dev->dev.parent; -+ -+ if (dpa_fq->fqid == 0) -+ dpa_fq->flags |= QMAN_FQ_FLAG_DYNAMIC_FQID; -+ -+ dpa_fq->init = !(dpa_fq->flags & QMAN_FQ_FLAG_NO_MODIFY); -+ -+ _errno = qman_create_fq(dpa_fq->fqid, dpa_fq->flags, &dpa_fq->fq_base); -+ if (_errno) { -+ dev_err(dev, "qman_create_fq() failed\n"); -+ return _errno; -+ } -+ fq = &dpa_fq->fq_base; -+ -+ if (dpa_fq->init) { -+ memset(&initfq, 0, sizeof(initfq)); -+ -+ initfq.we_mask = QM_INITFQ_WE_FQCTRL; -+ /* FIXME: why would we want to keep an empty FQ in cache? */ -+ initfq.fqd.fq_ctrl = QM_FQCTRL_PREFERINCACHE; -+ -+ /* Try to reduce the number of portal interrupts for -+ * Tx Confirmation FQs. -+ */ -+ if (dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM) -+ initfq.fqd.fq_ctrl |= QM_FQCTRL_HOLDACTIVE; -+ -+ /* FQ placement */ -+ initfq.we_mask |= QM_INITFQ_WE_DESTWQ; -+ -+ initfq.fqd.dest.channel = dpa_fq->channel; -+ initfq.fqd.dest.wq = dpa_fq->wq; -+ -+ /* Put all egress queues in a congestion group of their own. -+ * Sensu stricto, the Tx confirmation queues are Rx FQs, -+ * rather than Tx - but they nonetheless account for the -+ * memory footprint on behalf of egress traffic. We therefore -+ * place them in the netdev's CGR, along with the Tx FQs. -+ */ -+ if (dpa_fq->fq_type == FQ_TYPE_TX || -+ dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM || -+ dpa_fq->fq_type == FQ_TYPE_TX_CONF_MQ) { -+ initfq.we_mask |= QM_INITFQ_WE_CGID; -+ initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE; -+ initfq.fqd.cgid = (uint8_t)priv->cgr_data.cgr.cgrid; -+ /* Set a fixed overhead accounting, in an attempt to -+ * reduce the impact of fixed-size skb shells and the -+ * driver's needed headroom on system memory. This is -+ * especially the case when the egress traffic is -+ * composed of small datagrams. -+ * Unfortunately, QMan's OAL value is capped to an -+ * insufficient value, but even that is better than -+ * no overhead accounting at all. -+ */ -+ initfq.we_mask |= QM_INITFQ_WE_OAC; -+ initfq.fqd.oac_init.oac = QM_OAC_CG; -+ initfq.fqd.oac_init.oal = -+ (signed char)(min(sizeof(struct sk_buff) + -+ priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL)); -+ } -+ -+ if (td_enable) { -+ initfq.we_mask |= QM_INITFQ_WE_TDTHRESH; -+ qm_fqd_taildrop_set(&initfq.fqd.td, -+ DPA_FQ_TD, 1); -+ initfq.fqd.fq_ctrl = QM_FQCTRL_TDE; -+ } -+ -+ /* Configure the Tx confirmation queue, now that we know -+ * which Tx queue it pairs with. -+ */ -+ if (dpa_fq->fq_type == FQ_TYPE_TX) { -+ queue_id = _dpa_tx_fq_to_id(priv, &dpa_fq->fq_base); -+ if (queue_id >= 0) { -+ confq = priv->conf_fqs[queue_id]; -+ if (confq) { -+ initfq.we_mask |= QM_INITFQ_WE_CONTEXTA; -+ /* ContextA: OVOM=1 (use contextA2 bits instead of ICAD) -+ * A2V=1 (contextA A2 field is valid) -+ * A0V=1 (contextA A0 field is valid) -+ * B0V=1 (contextB field is valid) -+ * ContextA A2: EBD=1 (deallocate buffers inside FMan) -+ * ContextB B0(ASPID): 0 (absolute Virtual Storage ID) -+ */ -+ initfq.fqd.context_a.hi = 0x1e000000; -+ initfq.fqd.context_a.lo = 0x80000000; -+ } -+ } -+ } -+ -+ /* Put all *private* ingress queues in our "ingress CGR". */ -+ if (priv->use_ingress_cgr && -+ (dpa_fq->fq_type == FQ_TYPE_RX_DEFAULT || -+ dpa_fq->fq_type == FQ_TYPE_RX_ERROR || -+ dpa_fq->fq_type == FQ_TYPE_RX_PCD || -+ dpa_fq->fq_type == FQ_TYPE_RX_PCD_HI_PRIO)) { -+ initfq.we_mask |= QM_INITFQ_WE_CGID; -+ initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE; -+ initfq.fqd.cgid = (uint8_t)priv->ingress_cgr.cgrid; -+ /* Set a fixed overhead accounting, just like for the -+ * egress CGR. -+ */ -+ initfq.we_mask |= QM_INITFQ_WE_OAC; -+ initfq.fqd.oac_init.oac = QM_OAC_CG; -+ initfq.fqd.oac_init.oal = -+ (signed char)(min(sizeof(struct sk_buff) + -+ priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL)); -+ } -+ -+ /* Initialization common to all ingress queues */ -+ if (dpa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) { -+ initfq.we_mask |= QM_INITFQ_WE_CONTEXTA; -+ initfq.fqd.fq_ctrl |= -+ QM_FQCTRL_CTXASTASHING | QM_FQCTRL_AVOIDBLOCK; -+ initfq.fqd.context_a.stashing.exclusive = -+ QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX | -+ QM_STASHING_EXCL_ANNOTATION; -+ initfq.fqd.context_a.stashing.data_cl = 2; -+ initfq.fqd.context_a.stashing.annotation_cl = 1; -+ initfq.fqd.context_a.stashing.context_cl = -+ DIV_ROUND_UP(sizeof(struct qman_fq), 64); -+ } -+ -+ _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq); -+ if (_errno < 0) { -+ if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno)) { -+ dpa_fq->init = 0; -+ } else { -+ dev_err(dev, "qman_init_fq(%u) = %d\n", -+ qman_fq_fqid(fq), _errno); -+ qman_destroy_fq(fq, 0); -+ } -+ return _errno; -+ } -+ } -+ -+ dpa_fq->fqid = qman_fq_fqid(fq); -+ -+ return 0; -+} -+EXPORT_SYMBOL(dpa_fq_init); -+ -+int __cold __attribute__((nonnull)) -+_dpa_fq_free(struct device *dev, struct qman_fq *fq) -+{ -+ int _errno, __errno; -+ struct dpa_fq *dpa_fq; -+ const struct dpa_priv_s *priv; -+ -+ _errno = 0; -+ -+ dpa_fq = container_of(fq, struct dpa_fq, fq_base); -+ priv = netdev_priv(dpa_fq->net_dev); -+ -+ if (dpa_fq->init) { -+ _errno = qman_retire_fq(fq, NULL); -+ if (unlikely(_errno < 0) && netif_msg_drv(priv)) -+ dev_err(dev, "qman_retire_fq(%u) = %d\n", -+ qman_fq_fqid(fq), _errno); -+ -+ __errno = qman_oos_fq(fq); -+ if (unlikely(__errno < 0) && netif_msg_drv(priv)) { -+ dev_err(dev, "qman_oos_fq(%u) = %d\n", -+ qman_fq_fqid(fq), __errno); -+ if (_errno >= 0) -+ _errno = __errno; -+ } -+ } -+ -+ qman_destroy_fq(fq, 0); -+ list_del(&dpa_fq->list); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(_dpa_fq_free); -+ -+int __cold __attribute__((nonnull)) -+dpa_fq_free(struct device *dev, struct list_head *list) -+{ -+ int _errno, __errno; -+ struct dpa_fq *dpa_fq, *tmp; -+ -+ _errno = 0; -+ list_for_each_entry_safe(dpa_fq, tmp, list, list) { -+ __errno = _dpa_fq_free(dev, (struct qman_fq *)dpa_fq); -+ if (unlikely(__errno < 0) && _errno >= 0) -+ _errno = __errno; -+ } -+ -+ return _errno; -+} -+EXPORT_SYMBOL(dpa_fq_free); -+ -+int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable) -+{ -+ int _errno, __errno; -+ struct dpa_fq *dpa_fq, *tmp; -+ static bool print_msg __read_mostly; -+ -+ _errno = 0; -+ print_msg = true; -+ list_for_each_entry_safe(dpa_fq, tmp, list, list) { -+ __errno = dpa_fq_init(dpa_fq, td_enable); -+ if (unlikely(__errno < 0) && _errno >= 0) { -+ if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, __errno)) { -+ if (print_msg) { -+ dev_warn(dev, -+ "Skip RX PCD High Priority FQs initialization\n"); -+ print_msg = false; -+ } -+ if (_dpa_fq_free(dev, (struct qman_fq *)dpa_fq)) -+ dev_warn(dev, -+ "Error freeing frame queues\n"); -+ } else { -+ _errno = __errno; -+ break; -+ } -+ } -+ } -+ -+ return _errno; -+} -+EXPORT_SYMBOL(dpa_fqs_init); -+static void -+dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq, -+ struct dpa_fq *defq, struct dpa_buffer_layout_s *buf_layout) -+{ -+ struct fm_port_params tx_port_param; -+ bool frag_enabled = false; -+ -+ memset(&tx_port_param, 0, sizeof(tx_port_param)); -+ dpaa_eth_init_port(tx, port, tx_port_param, errq->fqid, defq->fqid, -+ buf_layout, frag_enabled); -+} -+ -+static void -+dpaa_eth_init_rx_port(struct fm_port *port, struct dpa_bp *bp, size_t count, -+ struct dpa_fq *errq, struct dpa_fq *defq, -+ struct dpa_buffer_layout_s *buf_layout) -+{ -+ struct fm_port_params rx_port_param; -+ int i; -+ bool frag_enabled = false; -+ -+ memset(&rx_port_param, 0, sizeof(rx_port_param)); -+ count = min(ARRAY_SIZE(rx_port_param.pool_param), count); -+ rx_port_param.num_pools = (uint8_t)count; -+ for (i = 0; i < count; i++) { -+ if (i >= rx_port_param.num_pools) -+ break; -+ rx_port_param.pool_param[i].id = bp[i].bpid; -+ rx_port_param.pool_param[i].size = (uint16_t)bp[i].size; -+ } -+ -+ dpaa_eth_init_port(rx, port, rx_port_param, errq->fqid, defq->fqid, -+ buf_layout, frag_enabled); -+} -+ -+#if defined(CONFIG_FSL_SDK_FMAN_TEST) -+/* Defined as weak, to be implemented by fman pcd tester. */ -+int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *) -+__attribute__((weak)); -+ -+int dpa_free_pcd_fqids(struct device *, uint32_t) __attribute__((weak)); -+#else -+int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *); -+ -+int dpa_free_pcd_fqids(struct device *, uint32_t); -+ -+#endif /* CONFIG_FSL_SDK_FMAN_TEST */ -+ -+ -+int dpa_alloc_pcd_fqids(struct device *dev, uint32_t num, -+ uint8_t alignment, uint32_t *base_fqid) -+{ -+ dev_crit(dev, "callback not implemented!\n"); -+ -+ return 0; -+} -+ -+int dpa_free_pcd_fqids(struct device *dev, uint32_t base_fqid) -+{ -+ -+ dev_crit(dev, "callback not implemented!\n"); -+ -+ return 0; -+} -+ -+void dpaa_eth_init_ports(struct mac_device *mac_dev, -+ struct dpa_bp *bp, size_t count, -+ struct fm_port_fqs *port_fqs, -+ struct dpa_buffer_layout_s *buf_layout, -+ struct device *dev) -+{ -+ struct fm_port_pcd_param rx_port_pcd_param; -+ struct fm_port *rxport = mac_dev->port_dev[RX]; -+ struct fm_port *txport = mac_dev->port_dev[TX]; -+ -+ dpaa_eth_init_tx_port(txport, port_fqs->tx_errq, -+ port_fqs->tx_defq, &buf_layout[TX]); -+ dpaa_eth_init_rx_port(rxport, bp, count, port_fqs->rx_errq, -+ port_fqs->rx_defq, &buf_layout[RX]); -+ -+ rx_port_pcd_param.cba = dpa_alloc_pcd_fqids; -+ rx_port_pcd_param.cbf = dpa_free_pcd_fqids; -+ rx_port_pcd_param.dev = dev; -+ fm_port_pcd_bind(rxport, &rx_port_pcd_param); -+} -+EXPORT_SYMBOL(dpaa_eth_init_ports); -+ -+void dpa_release_sgt(struct qm_sg_entry *sgt) -+{ -+ struct dpa_bp *dpa_bp; -+ struct bm_buffer bmb[DPA_BUFF_RELEASE_MAX]; -+ uint8_t i = 0, j; -+ -+ memset(bmb, 0, DPA_BUFF_RELEASE_MAX * sizeof(struct bm_buffer)); -+ -+ do { -+ dpa_bp = dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i])); -+ DPA_BUG_ON(!dpa_bp); -+ -+ j = 0; -+ do { -+ DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i])); -+ bm_buffer_set64(&bmb[j], qm_sg_addr(&sgt[i])); -+ -+ j++; i++; -+ } while (j < ARRAY_SIZE(bmb) && -+ !qm_sg_entry_get_final(&sgt[i-1]) && -+ qm_sg_entry_get_bpid(&sgt[i-1]) == -+ qm_sg_entry_get_bpid(&sgt[i])); -+ -+ while (bman_release(dpa_bp->pool, bmb, j, 0)) -+ cpu_relax(); -+ } while (!qm_sg_entry_get_final(&sgt[i-1])); -+} -+EXPORT_SYMBOL(dpa_release_sgt); -+ -+void __attribute__((nonnull)) -+dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd) -+{ -+ struct qm_sg_entry *sgt; -+ struct dpa_bp *dpa_bp; -+ struct bm_buffer bmb; -+ dma_addr_t addr; -+ void *vaddr; -+ -+ bmb.opaque = 0; -+ bm_buffer_set64(&bmb, qm_fd_addr(fd)); -+ -+ dpa_bp = dpa_bpid2pool(fd->bpid); -+ DPA_BUG_ON(!dpa_bp); -+ -+ if (fd->format == qm_fd_sg) { -+ vaddr = phys_to_virt(qm_fd_addr(fd)); -+ sgt = vaddr + dpa_fd_offset(fd); -+ -+ dma_unmap_single(dpa_bp->dev, qm_fd_addr(fd), dpa_bp->size, -+ DMA_BIDIRECTIONAL); -+ -+ dpa_release_sgt(sgt); -+ addr = dma_map_single(dpa_bp->dev, vaddr, dpa_bp->size, -+ DMA_BIDIRECTIONAL); -+ if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) { -+ dev_err(dpa_bp->dev, "DMA mapping failed"); -+ return; -+ } -+ bm_buffer_set64(&bmb, addr); -+ } -+ -+ while (bman_release(dpa_bp->pool, &bmb, 1, 0)) -+ cpu_relax(); -+} -+EXPORT_SYMBOL(dpa_fd_release); -+ -+void count_ern(struct dpa_percpu_priv_s *percpu_priv, -+ const struct qm_mr_entry *msg) -+{ -+ switch (msg->ern.rc & QM_MR_RC_MASK) { -+ case QM_MR_RC_CGR_TAILDROP: -+ percpu_priv->ern_cnt.cg_tdrop++; -+ break; -+ case QM_MR_RC_WRED: -+ percpu_priv->ern_cnt.wred++; -+ break; -+ case QM_MR_RC_ERROR: -+ percpu_priv->ern_cnt.err_cond++; -+ break; -+ case QM_MR_RC_ORPWINDOW_EARLY: -+ percpu_priv->ern_cnt.early_window++; -+ break; -+ case QM_MR_RC_ORPWINDOW_LATE: -+ percpu_priv->ern_cnt.late_window++; -+ break; -+ case QM_MR_RC_FQ_TAILDROP: -+ percpu_priv->ern_cnt.fq_tdrop++; -+ break; -+ case QM_MR_RC_ORPWINDOW_RETIRED: -+ percpu_priv->ern_cnt.fq_retired++; -+ break; -+ case QM_MR_RC_ORP_ZERO: -+ percpu_priv->ern_cnt.orp_zero++; -+ break; -+ } -+} -+EXPORT_SYMBOL(count_ern); -+ -+/** -+ * Turn on HW checksum computation for this outgoing frame. -+ * If the current protocol is not something we support in this regard -+ * (or if the stack has already computed the SW checksum), we do nothing. -+ * -+ * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value -+ * otherwise. -+ * -+ * Note that this function may modify the fd->cmd field and the skb data buffer -+ * (the Parse Results area). -+ */ -+int dpa_enable_tx_csum(struct dpa_priv_s *priv, -+ struct sk_buff *skb, struct qm_fd *fd, char *parse_results) -+{ -+ fm_prs_result_t *parse_result; -+ struct iphdr *iph; -+ struct ipv6hdr *ipv6h = NULL; -+ u8 l4_proto; -+ u16 ethertype = ntohs(skb->protocol); -+ int retval = 0; -+ -+ if (skb->ip_summed != CHECKSUM_PARTIAL) -+ return 0; -+ -+ /* Note: L3 csum seems to be already computed in sw, but we can't choose -+ * L4 alone from the FM configuration anyway. -+ */ -+ -+ /* Fill in some fields of the Parse Results array, so the FMan -+ * can find them as if they came from the FMan Parser. -+ */ -+ parse_result = (fm_prs_result_t *)parse_results; -+ -+ /* If we're dealing with VLAN, get the real Ethernet type */ -+ if (ethertype == ETH_P_8021Q) { -+ /* We can't always assume the MAC header is set correctly -+ * by the stack, so reset to beginning of skb->data -+ */ -+ skb_reset_mac_header(skb); -+ ethertype = ntohs(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto); -+ } -+ -+ /* Fill in the relevant L3 parse result fields -+ * and read the L4 protocol type -+ */ -+ switch (ethertype) { -+ case ETH_P_IP: -+ parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV4); -+ iph = ip_hdr(skb); -+ DPA_BUG_ON(iph == NULL); -+ l4_proto = iph->protocol; -+ break; -+ case ETH_P_IPV6: -+ parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV6); -+ ipv6h = ipv6_hdr(skb); -+ DPA_BUG_ON(ipv6h == NULL); -+ l4_proto = ipv6h->nexthdr; -+ break; -+ default: -+ /* We shouldn't even be here */ -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ netdev_alert(priv->net_dev, -+ "Can't compute HW csum for L3 proto 0x%x\n", -+ ntohs(skb->protocol)); -+ retval = -EIO; -+ goto return_error; -+ } -+ -+ /* Fill in the relevant L4 parse result fields */ -+ switch (l4_proto) { -+ case IPPROTO_UDP: -+ parse_result->l4r = FM_L4_PARSE_RESULT_UDP; -+ break; -+ case IPPROTO_TCP: -+ parse_result->l4r = FM_L4_PARSE_RESULT_TCP; -+ break; -+ default: -+ /* This can as well be a BUG() */ -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ netdev_alert(priv->net_dev, -+ "Can't compute HW csum for L4 proto 0x%x\n", -+ l4_proto); -+ retval = -EIO; -+ goto return_error; -+ } -+ -+ /* At index 0 is IPOffset_1 as defined in the Parse Results */ -+ parse_result->ip_off[0] = (uint8_t)skb_network_offset(skb); -+ parse_result->l4_off = (uint8_t)skb_transport_offset(skb); -+ -+ /* Enable L3 (and L4, if TCP or UDP) HW checksum. */ -+ fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC; -+ -+ /* On P1023 and similar platforms fd->cmd interpretation could -+ * be disabled by setting CONTEXT_A bit ICMD; currently this bit -+ * is not set so we do not need to check; in the future, if/when -+ * using context_a we need to check this bit -+ */ -+ -+return_error: -+ return retval; -+} -+EXPORT_SYMBOL(dpa_enable_tx_csum); -+ -+#ifdef CONFIG_FSL_DPAA_CEETM -+void dpa_enable_ceetm(struct net_device *dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(dev); -+ priv->ceetm_en = true; -+} -+EXPORT_SYMBOL(dpa_enable_ceetm); -+ -+void dpa_disable_ceetm(struct net_device *dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(dev); -+ priv->ceetm_en = false; -+} -+EXPORT_SYMBOL(dpa_disable_ceetm); -+#endif ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h -@@ -0,0 +1,226 @@ -+/* Copyright 2008-2013 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __DPAA_ETH_COMMON_H -+#define __DPAA_ETH_COMMON_H -+ -+#include /* struct net_device */ -+#include /* struct bm_buffer */ -+#include /* struct platform_device */ -+#include /* struct hwtstamp_config */ -+ -+#include "dpaa_eth.h" -+#include "lnxwrp_fsl_fman.h" -+ -+#define dpaa_eth_init_port(type, port, param, errq_id, defq_id, buf_layout,\ -+ frag_enabled) \ -+{ \ -+ param.errq = errq_id; \ -+ param.defq = defq_id; \ -+ param.priv_data_size = buf_layout->priv_data_size; \ -+ param.parse_results = buf_layout->parse_results; \ -+ param.hash_results = buf_layout->hash_results; \ -+ param.frag_enable = frag_enabled; \ -+ param.time_stamp = buf_layout->time_stamp; \ -+ param.manip_extra_space = buf_layout->manip_extra_space; \ -+ param.data_align = buf_layout->data_align; \ -+ fm_set_##type##_port_params(port, ¶m); \ -+} -+ -+#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */ -+ -+#define DPA_SGT_ENTRIES_THRESHOLD DPA_SGT_MAX_ENTRIES -+ -+#define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */ -+ -+#define DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno) \ -+ (((dpa_fq)->fq_type == FQ_TYPE_RX_PCD_HI_PRIO) && \ -+ (_errno == -EIO)) -+/* return codes for the dpaa-eth hooks */ -+enum dpaa_eth_hook_result { -+ /* fd/skb was retained by the hook. -+ * -+ * On the Rx path, this means the Ethernet driver will _not_ -+ * deliver the skb to the stack. Instead, the hook implementation -+ * is expected to properly dispose of the skb. -+ * -+ * On the Tx path, the Ethernet driver's dpa_tx() function will -+ * immediately return NETDEV_TX_OK. The hook implementation is expected -+ * to free the skb. *DO*NOT* release it to BMan, or enqueue it to FMan, -+ * unless you know exactly what you're doing! -+ * -+ * On the confirmation/error paths, the Ethernet driver will _not_ -+ * perform any fd cleanup, nor update the interface statistics. -+ */ -+ DPAA_ETH_STOLEN, -+ /* fd/skb was returned to the Ethernet driver for regular processing. -+ * The hook is not allowed to, for instance, reallocate the skb (as if -+ * by linearizing, copying, cloning or reallocating the headroom). -+ */ -+ DPAA_ETH_CONTINUE -+}; -+ -+typedef enum dpaa_eth_hook_result (*dpaa_eth_ingress_hook_t)( -+ struct sk_buff *skb, struct net_device *net_dev, u32 fqid); -+typedef enum dpaa_eth_hook_result (*dpaa_eth_egress_hook_t)( -+ struct sk_buff *skb, struct net_device *net_dev); -+typedef enum dpaa_eth_hook_result (*dpaa_eth_confirm_hook_t)( -+ struct net_device *net_dev, const struct qm_fd *fd, u32 fqid); -+ -+/* used in napi related functions */ -+extern u16 qman_portal_max; -+ -+/* from dpa_ethtool.c */ -+extern const struct ethtool_ops dpa_ethtool_ops; -+ -+#ifdef CONFIG_FSL_DPAA_HOOKS -+/* Various hooks used for unit-testing and/or fastpath optimizations. -+ * Currently only one set of such hooks is supported. -+ */ -+struct dpaa_eth_hooks_s { -+ /* Invoked on the Tx private path, immediately after receiving the skb -+ * from the stack. -+ */ -+ dpaa_eth_egress_hook_t tx; -+ -+ /* Invoked on the Rx private path, right before passing the skb -+ * up the stack. At that point, the packet's protocol id has already -+ * been set. The skb's data pointer is now at the L3 header, and -+ * skb->mac_header points to the L2 header. skb->len has been adjusted -+ * to be the length of L3+payload (i.e., the length of the -+ * original frame minus the L2 header len). -+ * For more details on what the skb looks like, see eth_type_trans(). -+ */ -+ dpaa_eth_ingress_hook_t rx_default; -+ -+ /* Driver hook for the Rx error private path. */ -+ dpaa_eth_confirm_hook_t rx_error; -+ /* Driver hook for the Tx confirmation private path. */ -+ dpaa_eth_confirm_hook_t tx_confirm; -+ /* Driver hook for the Tx error private path. */ -+ dpaa_eth_confirm_hook_t tx_error; -+}; -+ -+void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks); -+ -+extern struct dpaa_eth_hooks_s dpaa_eth_hooks; -+#endif -+ -+int dpa_netdev_init(struct net_device *net_dev, -+ const uint8_t *mac_addr, -+ uint16_t tx_timeout); -+int __cold dpa_start(struct net_device *net_dev); -+int __cold dpa_stop(struct net_device *net_dev); -+void __cold dpa_timeout(struct net_device *net_dev); -+void __cold -+dpa_get_stats64(struct net_device *net_dev, -+ struct rtnl_link_stats64 *stats); -+int dpa_change_mtu(struct net_device *net_dev, int new_mtu); -+int dpa_ndo_init(struct net_device *net_dev); -+int dpa_set_features(struct net_device *dev, netdev_features_t features); -+netdev_features_t dpa_fix_features(struct net_device *dev, -+ netdev_features_t features); -+#ifdef CONFIG_FSL_DPAA_TS -+u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, -+ enum port_type rx_tx, const void *data); -+/* Updates the skb shared hw timestamp from the hardware timestamp */ -+int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx, -+ struct skb_shared_hwtstamps *shhwtstamps, const void *data); -+#endif /* CONFIG_FSL_DPAA_TS */ -+int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -+int __cold dpa_remove(struct platform_device *of_dev); -+struct mac_device * __cold __must_check -+__attribute__((nonnull)) dpa_mac_probe(struct platform_device *_of_dev); -+int dpa_set_mac_address(struct net_device *net_dev, void *addr); -+void dpa_set_rx_mode(struct net_device *net_dev); -+void dpa_set_buffers_layout(struct mac_device *mac_dev, -+ struct dpa_buffer_layout_s *layout); -+int __attribute__((nonnull)) -+dpa_bp_alloc(struct dpa_bp *dpa_bp); -+void __cold __attribute__((nonnull)) -+dpa_bp_free(struct dpa_priv_s *priv); -+struct dpa_bp *dpa_bpid2pool(int bpid); -+void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp); -+bool dpa_bpid2pool_use(int bpid); -+void dpa_bp_drain(struct dpa_bp *bp); -+#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -+u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb, -+ struct net_device *sb_dev, -+ select_queue_fallback_t fallback); -+#endif -+struct dpa_fq *dpa_fq_alloc(struct device *dev, -+ u32 fq_start, -+ u32 fq_count, -+ struct list_head *list, -+ enum dpa_fq_type fq_type); -+int dpa_fq_probe_mac(struct device *dev, struct list_head *list, -+ struct fm_port_fqs *port_fqs, -+ bool tx_conf_fqs_per_core, -+ enum port_type ptype); -+int dpa_get_channel(void); -+void dpa_release_channel(void); -+void dpaa_eth_add_channel(u16 channel); -+int dpaa_eth_cgr_init(struct dpa_priv_s *priv); -+void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs, -+ struct fm_port *tx_port); -+int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable); -+int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable); -+int __cold __attribute__((nonnull)) -+dpa_fq_free(struct device *dev, struct list_head *list); -+void dpaa_eth_init_ports(struct mac_device *mac_dev, -+ struct dpa_bp *bp, size_t count, -+ struct fm_port_fqs *port_fqs, -+ struct dpa_buffer_layout_s *buf_layout, -+ struct device *dev); -+void dpa_release_sgt(struct qm_sg_entry *sgt); -+void __attribute__((nonnull)) -+dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd); -+void count_ern(struct dpa_percpu_priv_s *percpu_priv, -+ const struct qm_mr_entry *msg); -+int dpa_enable_tx_csum(struct dpa_priv_s *priv, -+ struct sk_buff *skb, struct qm_fd *fd, char *parse_results); -+#ifdef CONFIG_FSL_DPAA_CEETM -+void dpa_enable_ceetm(struct net_device *dev); -+void dpa_disable_ceetm(struct net_device *dev); -+#endif -+struct proxy_device { -+ struct mac_device *mac_dev; -+}; -+ -+/* mac device control functions exposed by proxy interface*/ -+int dpa_proxy_start(struct net_device *net_dev); -+int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev); -+int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev, -+ struct net_device *net_dev); -+int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev, -+ struct net_device *net_dev); -+ -+#endif /* __DPAA_ETH_COMMON_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c -@@ -0,0 +1,381 @@ -+/* Copyright 2008-2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifdef CONFIG_FSL_DPAA_ETH_DEBUG -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+#else -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": " fmt -+#endif -+ -+#include -+#include -+#include -+#include "dpaa_eth.h" -+#include "dpaa_eth_common.h" -+#include "dpaa_eth_base.h" -+#include "lnxwrp_fsl_fman.h" /* fm_get_rx_extra_headroom(), fm_get_max_frm() */ -+#include "mac.h" -+ -+#define DPA_DESCRIPTION "FSL DPAA Proxy initialization driver" -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+ -+MODULE_DESCRIPTION(DPA_DESCRIPTION); -+ -+static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev); -+#ifdef CONFIG_PM -+ -+static int proxy_suspend(struct device *dev) -+{ -+ struct proxy_device *proxy_dev = dev_get_drvdata(dev); -+ struct mac_device *mac_dev = proxy_dev->mac_dev; -+ int err = 0; -+ -+ err = fm_port_suspend(mac_dev->port_dev[RX]); -+ if (err) -+ goto port_suspend_failed; -+ -+ err = fm_port_suspend(mac_dev->port_dev[TX]); -+ if (err) -+ err = fm_port_resume(mac_dev->port_dev[RX]); -+ -+port_suspend_failed: -+ return err; -+} -+ -+static int proxy_resume(struct device *dev) -+{ -+ struct proxy_device *proxy_dev = dev_get_drvdata(dev); -+ struct mac_device *mac_dev = proxy_dev->mac_dev; -+ int err = 0; -+ -+ err = fm_port_resume(mac_dev->port_dev[TX]); -+ if (err) -+ goto port_resume_failed; -+ -+ err = fm_port_resume(mac_dev->port_dev[RX]); -+ if (err) -+ err = fm_port_suspend(mac_dev->port_dev[TX]); -+ -+port_resume_failed: -+ return err; -+} -+ -+static const struct dev_pm_ops proxy_pm_ops = { -+ .suspend = proxy_suspend, -+ .resume = proxy_resume, -+}; -+ -+#define PROXY_PM_OPS (&proxy_pm_ops) -+ -+#else /* CONFIG_PM */ -+ -+#define PROXY_PM_OPS NULL -+ -+#endif /* CONFIG_PM */ -+ -+static int dpaa_eth_proxy_probe(struct platform_device *_of_dev) -+{ -+ int err = 0, i; -+ struct device *dev; -+ struct device_node *dpa_node; -+ struct dpa_bp *dpa_bp; -+ struct list_head proxy_fq_list; -+ size_t count; -+ struct fm_port_fqs port_fqs; -+ struct dpa_buffer_layout_s *buf_layout = NULL; -+ struct mac_device *mac_dev; -+ struct proxy_device *proxy_dev; -+ -+ dev = &_of_dev->dev; -+ -+ dpa_node = dev->of_node; -+ -+ if (!of_device_is_available(dpa_node)) -+ return -ENODEV; -+ -+ /* Get the buffer pools assigned to this interface */ -+ dpa_bp = dpa_bp_probe(_of_dev, &count); -+ if (IS_ERR(dpa_bp)) -+ return PTR_ERR(dpa_bp); -+ -+ mac_dev = dpa_mac_probe(_of_dev); -+ if (IS_ERR(mac_dev)) -+ return PTR_ERR(mac_dev); -+ -+ proxy_dev = devm_kzalloc(dev, sizeof(*proxy_dev), GFP_KERNEL); -+ if (!proxy_dev) { -+ dev_err(dev, "devm_kzalloc() failed\n"); -+ return -ENOMEM; -+ } -+ -+ proxy_dev->mac_dev = mac_dev; -+ dev_set_drvdata(dev, proxy_dev); -+ -+ /* We have physical ports, so we need to establish -+ * the buffer layout. -+ */ -+ buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout), -+ GFP_KERNEL); -+ if (!buf_layout) { -+ dev_err(dev, "devm_kzalloc() failed\n"); -+ return -ENOMEM; -+ } -+ dpa_set_buffers_layout(mac_dev, buf_layout); -+ -+ INIT_LIST_HEAD(&proxy_fq_list); -+ -+ memset(&port_fqs, 0, sizeof(port_fqs)); -+ -+ err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true, RX); -+ if (!err) -+ err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true, -+ TX); -+ if (err < 0) { -+ devm_kfree(dev, buf_layout); -+ return err; -+ } -+ -+ /* Proxy initializer - Just configures the MAC on behalf of -+ * another partition. -+ */ -+ dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs, -+ buf_layout, dev); -+ -+ /* Proxy interfaces need to be started, and the allocated -+ * memory freed -+ */ -+ devm_kfree(dev, buf_layout); -+ devm_kfree(dev, dpa_bp); -+ -+ /* Free FQ structures */ -+ devm_kfree(dev, port_fqs.rx_defq); -+ devm_kfree(dev, port_fqs.rx_errq); -+ devm_kfree(dev, port_fqs.tx_defq); -+ devm_kfree(dev, port_fqs.tx_errq); -+ -+ for_each_port_device(i, mac_dev->port_dev) { -+ err = fm_port_enable(mac_dev->port_dev[i]); -+ if (err) -+ goto port_enable_fail; -+ } -+ -+ dev_info(dev, "probed MAC device with MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n", -+ mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2], -+ mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]); -+ -+ return 0; /* Proxy interface initialization ended */ -+ -+port_enable_fail: -+ for_each_port_device(i, mac_dev->port_dev) -+ fm_port_disable(mac_dev->port_dev[i]); -+ dpa_eth_proxy_remove(_of_dev); -+ -+ return err; -+} -+ -+int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev, -+ struct net_device *net_dev) -+{ -+ struct mac_device *mac_dev; -+ int _errno; -+ -+ mac_dev = proxy_dev->mac_dev; -+ -+ _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev), -+ net_dev->dev_addr); -+ if (_errno < 0) -+ return _errno; -+ -+ return 0; -+} -+EXPORT_SYMBOL(dpa_proxy_set_mac_address); -+ -+int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev, -+ struct net_device *net_dev) -+{ -+ struct mac_device *mac_dev = proxy_dev->mac_dev; -+ int _errno; -+ -+ if (!!(net_dev->flags & IFF_PROMISC) != mac_dev->promisc) { -+ mac_dev->promisc = !mac_dev->promisc; -+ _errno = mac_dev->set_promisc(mac_dev->get_mac_handle(mac_dev), -+ mac_dev->promisc); -+ if (unlikely(_errno < 0)) -+ netdev_err(net_dev, "mac_dev->set_promisc() = %d\n", -+ _errno); -+ } -+ -+ _errno = mac_dev->set_multi(net_dev, mac_dev); -+ if (unlikely(_errno < 0)) -+ return _errno; -+ -+ return 0; -+} -+EXPORT_SYMBOL(dpa_proxy_set_rx_mode); -+ -+int dpa_proxy_start(struct net_device *net_dev) -+{ -+ struct mac_device *mac_dev; -+ const struct dpa_priv_s *priv; -+ struct proxy_device *proxy_dev; -+ int _errno; -+ int i; -+ -+ priv = netdev_priv(net_dev); -+ proxy_dev = (struct proxy_device *)priv->peer; -+ mac_dev = proxy_dev->mac_dev; -+ -+ _errno = mac_dev->init_phy(net_dev, mac_dev); -+ if (_errno < 0) { -+ if (netif_msg_drv(priv)) -+ netdev_err(net_dev, "init_phy() = %d\n", -+ _errno); -+ return _errno; -+ } -+ -+ for_each_port_device(i, mac_dev->port_dev) { -+ _errno = fm_port_enable(mac_dev->port_dev[i]); -+ if (_errno) -+ goto port_enable_fail; -+ } -+ -+ _errno = mac_dev->start(mac_dev); -+ if (_errno < 0) { -+ if (netif_msg_drv(priv)) -+ netdev_err(net_dev, "mac_dev->start() = %d\n", -+ _errno); -+ goto port_enable_fail; -+ } -+ -+ return _errno; -+ -+port_enable_fail: -+ for_each_port_device(i, mac_dev->port_dev) -+ fm_port_disable(mac_dev->port_dev[i]); -+ -+ return _errno; -+} -+EXPORT_SYMBOL(dpa_proxy_start); -+ -+int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev) -+{ -+ struct mac_device *mac_dev = proxy_dev->mac_dev; -+ const struct dpa_priv_s *priv = netdev_priv(net_dev); -+ int _errno, i, err; -+ -+ _errno = mac_dev->stop(mac_dev); -+ if (_errno < 0) { -+ if (netif_msg_drv(priv)) -+ netdev_err(net_dev, "mac_dev->stop() = %d\n", -+ _errno); -+ return _errno; -+ } -+ -+ for_each_port_device(i, mac_dev->port_dev) { -+ err = fm_port_disable(mac_dev->port_dev[i]); -+ _errno = err ? err : _errno; -+ } -+ -+ if (mac_dev->phy_dev) -+ phy_disconnect(mac_dev->phy_dev); -+ mac_dev->phy_dev = NULL; -+ -+ return _errno; -+} -+EXPORT_SYMBOL(dpa_proxy_stop); -+ -+static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev) -+{ -+ struct device *dev = &of_dev->dev; -+ struct proxy_device *proxy_dev = dev_get_drvdata(dev); -+ -+ kfree(proxy_dev); -+ -+ dev_set_drvdata(dev, NULL); -+ -+ return 0; -+} -+ -+static const struct of_device_id dpa_proxy_match[] = { -+ { -+ .compatible = "fsl,dpa-ethernet-init" -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, dpa_proxy_match); -+ -+static struct platform_driver dpa_proxy_driver = { -+ .driver = { -+ .name = KBUILD_MODNAME "-proxy", -+ .of_match_table = dpa_proxy_match, -+ .owner = THIS_MODULE, -+ .pm = PROXY_PM_OPS, -+ }, -+ .probe = dpaa_eth_proxy_probe, -+ .remove = dpa_eth_proxy_remove -+}; -+ -+static int __init __cold dpa_proxy_load(void) -+{ -+ int _errno; -+ -+ pr_info(DPA_DESCRIPTION "\n"); -+ -+ /* Initialize dpaa_eth mirror values */ -+ dpa_rx_extra_headroom = fm_get_rx_extra_headroom(); -+ dpa_max_frm = fm_get_max_frm(); -+ -+ _errno = platform_driver_register(&dpa_proxy_driver); -+ if (unlikely(_errno < 0)) { -+ pr_err(KBUILD_MODNAME -+ ": %s:%hu:%s(): platform_driver_register() = %d\n", -+ KBUILD_BASENAME".c", __LINE__, __func__, _errno); -+ } -+ -+ pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -+ KBUILD_BASENAME".c", __func__); -+ -+ return _errno; -+} -+module_init(dpa_proxy_load); -+ -+static void __exit __cold dpa_proxy_unload(void) -+{ -+ platform_driver_unregister(&dpa_proxy_driver); -+ -+ pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -+ KBUILD_BASENAME".c", __func__); -+} -+module_exit(dpa_proxy_unload); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -0,0 +1,1113 @@ -+/* Copyright 2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifdef CONFIG_FSL_DPAA_ETH_DEBUG -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+#else -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": " fmt -+#endif -+ -+#include -+#include -+#include -+#include -+ -+#include "dpaa_eth.h" -+#include "dpaa_eth_common.h" -+#ifdef CONFIG_FSL_DPAA_1588 -+#include "dpaa_1588.h" -+#endif -+#ifdef CONFIG_FSL_DPAA_CEETM -+#include "dpaa_eth_ceetm.h" -+#endif -+ -+/* DMA map and add a page frag back into the bpool. -+ * @vaddr fragment must have been allocated with netdev_alloc_frag(), -+ * specifically for fitting into @dpa_bp. -+ */ -+static void dpa_bp_recycle_frag(struct dpa_bp *dpa_bp, unsigned long vaddr, -+ int *count_ptr) -+{ -+ struct bm_buffer bmb; -+ dma_addr_t addr; -+ -+ bmb.opaque = 0; -+ -+ addr = dma_map_single(dpa_bp->dev, (void *)vaddr, dpa_bp->size, -+ DMA_BIDIRECTIONAL); -+ if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) { -+ dev_err(dpa_bp->dev, "DMA mapping failed"); -+ return; -+ } -+ -+ bm_buffer_set64(&bmb, addr); -+ -+ while (bman_release(dpa_bp->pool, &bmb, 1, 0)) -+ cpu_relax(); -+ -+ (*count_ptr)++; -+} -+ -+static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp) -+{ -+ struct bm_buffer bmb[8]; -+ void *new_buf; -+ dma_addr_t addr; -+ uint8_t i; -+ struct device *dev = dpa_bp->dev; -+ struct sk_buff *skb, **skbh; -+ -+ memset(bmb, 0, sizeof(struct bm_buffer) * 8); -+ -+ for (i = 0; i < 8; i++) { -+ /* We'll prepend the skb back-pointer; can't use the DPA -+ * priv space, because FMan will overwrite it (from offset 0) -+ * if it ends up being the second, third, etc. fragment -+ * in a S/G frame. -+ * -+ * We only need enough space to store a pointer, but allocate -+ * an entire cacheline for performance reasons. -+ */ -+#ifndef CONFIG_PPC -+ if (unlikely(dpaa_errata_a010022)) -+ new_buf = page_address(alloc_page(GFP_ATOMIC)); -+ else -+#endif -+ new_buf = netdev_alloc_frag(SMP_CACHE_BYTES + DPA_BP_RAW_SIZE); -+ -+ if (unlikely(!new_buf)) -+ goto netdev_alloc_failed; -+ new_buf = PTR_ALIGN(new_buf + SMP_CACHE_BYTES, SMP_CACHE_BYTES); -+ -+ skb = build_skb(new_buf, DPA_SKB_SIZE(dpa_bp->size) + -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); -+ if (unlikely(!skb)) { -+ put_page(virt_to_head_page(new_buf)); -+ goto build_skb_failed; -+ } -+ DPA_WRITE_SKB_PTR(skb, skbh, new_buf, -1); -+ -+ addr = dma_map_single(dev, new_buf, -+ dpa_bp->size, DMA_BIDIRECTIONAL); -+ if (unlikely(dma_mapping_error(dev, addr))) -+ goto dma_map_failed; -+ -+ bm_buffer_set64(&bmb[i], addr); -+ } -+ -+release_bufs: -+ /* Release the buffers. In case bman is busy, keep trying -+ * until successful. bman_release() is guaranteed to succeed -+ * in a reasonable amount of time -+ */ -+ while (unlikely(bman_release(dpa_bp->pool, bmb, i, 0))) -+ cpu_relax(); -+ return i; -+ -+dma_map_failed: -+ kfree_skb(skb); -+ -+build_skb_failed: -+netdev_alloc_failed: -+ net_err_ratelimited("dpa_bp_add_8_bufs() failed\n"); -+ WARN_ONCE(1, "Memory allocation failure on Rx\n"); -+ -+ bm_buffer_set64(&bmb[i], 0); -+ /* Avoid releasing a completely null buffer; bman_release() requires -+ * at least one buffer. -+ */ -+ if (likely(i)) -+ goto release_bufs; -+ -+ return 0; -+} -+ -+/* Cold path wrapper over _dpa_bp_add_8_bufs(). */ -+static void dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp, int cpu) -+{ -+ int *count_ptr = per_cpu_ptr(dpa_bp->percpu_count, cpu); -+ *count_ptr += _dpa_bp_add_8_bufs(dpa_bp); -+} -+ -+int dpa_bp_priv_seed(struct dpa_bp *dpa_bp) -+{ -+ int i; -+ -+ /* Give each CPU an allotment of "config_count" buffers */ -+ for_each_possible_cpu(i) { -+ int j; -+ -+ /* Although we access another CPU's counters here -+ * we do it at boot time so it is safe -+ */ -+ for (j = 0; j < dpa_bp->config_count; j += 8) -+ dpa_bp_add_8_bufs(dpa_bp, i); -+ } -+ return 0; -+} -+EXPORT_SYMBOL(dpa_bp_priv_seed); -+ -+/* Add buffers/(pages) for Rx processing whenever bpool count falls below -+ * REFILL_THRESHOLD. -+ */ -+int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *countptr) -+{ -+ int count = *countptr; -+ int new_bufs; -+ -+ if (unlikely(count < CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD)) { -+ do { -+ new_bufs = _dpa_bp_add_8_bufs(dpa_bp); -+ if (unlikely(!new_bufs)) { -+ /* Avoid looping forever if we've temporarily -+ * run out of memory. We'll try again at the -+ * next NAPI cycle. -+ */ -+ break; -+ } -+ count += new_bufs; -+ } while (count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT); -+ -+ *countptr = count; -+ if (unlikely(count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT)) -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(dpaa_eth_refill_bpools); -+ -+/* Cleanup function for outgoing frame descriptors that were built on Tx path, -+ * either contiguous frames or scatter/gather ones. -+ * Skb freeing is not handled here. -+ * -+ * This function may be called on error paths in the Tx function, so guard -+ * against cases when not all fd relevant fields were filled in. -+ * -+ * Return the skb backpointer, since for S/G frames the buffer containing it -+ * gets freed here. -+ */ -+struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv, -+ const struct qm_fd *fd) -+{ -+ const struct qm_sg_entry *sgt; -+ int i; -+ struct dpa_bp *dpa_bp = priv->dpa_bp; -+ dma_addr_t addr = qm_fd_addr(fd); -+ dma_addr_t sg_addr; -+ struct sk_buff **skbh; -+ struct sk_buff *skb = NULL; -+ const enum dma_data_direction dma_dir = DMA_TO_DEVICE; -+ int nr_frags; -+ int sg_len; -+ -+ /* retrieve skb back pointer */ -+ DPA_READ_SKB_PTR(skb, skbh, phys_to_virt(addr), 0); -+ -+ if (unlikely(fd->format == qm_fd_sg)) { -+ nr_frags = skb_shinfo(skb)->nr_frags; -+ dma_unmap_single(dpa_bp->dev, addr, dpa_fd_offset(fd) + -+ sizeof(struct qm_sg_entry) * (1 + nr_frags), -+ dma_dir); -+ -+ /* The sgt buffer has been allocated with netdev_alloc_frag(), -+ * it's from lowmem. -+ */ -+ sgt = phys_to_virt(addr + dpa_fd_offset(fd)); -+#ifdef CONFIG_FSL_DPAA_1588 -+ if (priv->tsu && priv->tsu->valid && -+ priv->tsu->hwts_tx_en_ioctl) -+ dpa_ptp_store_txstamp(priv, skb, (void *)skbh); -+#endif -+#ifdef CONFIG_FSL_DPAA_TS -+ if (unlikely(priv->ts_tx_en && -+ skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { -+ struct skb_shared_hwtstamps shhwtstamps; -+ -+ dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh); -+ skb_tstamp_tx(skb, &shhwtstamps); -+ } -+#endif /* CONFIG_FSL_DPAA_TS */ -+ -+ /* sgt[0] is from lowmem, was dma_map_single()-ed */ -+ sg_addr = qm_sg_addr(&sgt[0]); -+ sg_len = qm_sg_entry_get_len(&sgt[0]); -+ dma_unmap_single(dpa_bp->dev, sg_addr, sg_len, dma_dir); -+ -+ /* remaining pages were mapped with dma_map_page() */ -+ for (i = 1; i <= nr_frags; i++) { -+ DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i])); -+ sg_addr = qm_sg_addr(&sgt[i]); -+ sg_len = qm_sg_entry_get_len(&sgt[i]); -+ dma_unmap_page(dpa_bp->dev, sg_addr, sg_len, dma_dir); -+ } -+ -+ /* Free the page frag that we allocated on Tx */ -+ put_page(virt_to_head_page(sgt)); -+ } else { -+ dma_unmap_single(dpa_bp->dev, addr, -+ skb_tail_pointer(skb) - (u8 *)skbh, dma_dir); -+#ifdef CONFIG_FSL_DPAA_TS -+ /* get the timestamp for non-SG frames */ -+#ifdef CONFIG_FSL_DPAA_1588 -+ if (priv->tsu && priv->tsu->valid && -+ priv->tsu->hwts_tx_en_ioctl) -+ dpa_ptp_store_txstamp(priv, skb, (void *)skbh); -+#endif -+ if (unlikely(priv->ts_tx_en && -+ skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { -+ struct skb_shared_hwtstamps shhwtstamps; -+ -+ dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh); -+ skb_tstamp_tx(skb, &shhwtstamps); -+ } -+#endif -+ } -+ -+ return skb; -+} -+EXPORT_SYMBOL(_dpa_cleanup_tx_fd); -+ -+#ifndef CONFIG_FSL_DPAA_TS -+bool dpa_skb_is_recyclable(struct sk_buff *skb) -+{ -+ /* No recycling possible if skb buffer is kmalloc'ed */ -+ if (skb->head_frag == 0) -+ return false; -+ -+ /* or if it's an userspace buffer */ -+ if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) -+ return false; -+ -+ /* or if it's cloned or shared */ -+ if (skb_shared(skb) || skb_cloned(skb) || -+ skb->fclone != SKB_FCLONE_UNAVAILABLE) -+ return false; -+ -+ return true; -+} -+EXPORT_SYMBOL(dpa_skb_is_recyclable); -+ -+bool dpa_buf_is_recyclable(struct sk_buff *skb, -+ uint32_t min_size, -+ uint16_t min_offset, -+ unsigned char **new_buf_start) -+{ -+ unsigned char *new; -+ -+ /* In order to recycle a buffer, the following conditions must be met: -+ * - buffer size no less than the buffer pool size -+ * - buffer size no higher than an upper limit (to avoid moving too much -+ * system memory to the buffer pools) -+ * - buffer address aligned to cacheline bytes -+ * - offset of data from start of buffer no lower than a minimum value -+ * - offset of data from start of buffer no higher than a maximum value -+ */ -+ new = min(skb_end_pointer(skb) - min_size, skb->data - min_offset); -+ -+ /* left align to the nearest cacheline */ -+ new = (unsigned char *)((unsigned long)new & ~(SMP_CACHE_BYTES - 1)); -+ -+ if (likely(new >= skb->head && -+ new >= (skb->data - DPA_MAX_FD_OFFSET) && -+ skb_end_pointer(skb) - new <= DPA_RECYCLE_MAX_SIZE)) { -+ *new_buf_start = new; -+ return true; -+ } -+ -+ return false; -+} -+EXPORT_SYMBOL(dpa_buf_is_recyclable); -+#endif -+ -+/* Build a linear skb around the received buffer. -+ * We are guaranteed there is enough room at the end of the data buffer to -+ * accommodate the shared info area of the skb. -+ */ -+static struct sk_buff *__hot contig_fd_to_skb(const struct dpa_priv_s *priv, -+ const struct qm_fd *fd, int *use_gro) -+{ -+ dma_addr_t addr = qm_fd_addr(fd); -+ ssize_t fd_off = dpa_fd_offset(fd); -+ void *vaddr; -+ const fm_prs_result_t *parse_results; -+ struct sk_buff *skb = NULL, **skbh; -+ -+ vaddr = phys_to_virt(addr); -+ DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES)); -+ -+ /* Retrieve the skb and adjust data and tail pointers, to make sure -+ * forwarded skbs will have enough space on Tx if extra headers -+ * are added. -+ */ -+ DPA_READ_SKB_PTR(skb, skbh, vaddr, -1); -+ -+#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME -+ /* When using jumbo Rx buffers, we risk having frames dropped due to -+ * the socket backlog reaching its maximum allowed size. -+ * Use the frame length for the skb truesize instead of the buffer -+ * size, as this is the size of the data that actually gets copied to -+ * userspace. -+ * The stack may increase the payload. In this case, it will want to -+ * warn us that the frame length is larger than the truesize. We -+ * bypass the warning. -+ */ -+#ifndef CONFIG_PPC -+ /* We do not support Jumbo frames on LS1043 and thus we edit -+ * the skb truesize only when the 4k errata is not present. -+ */ -+ if (likely(!dpaa_errata_a010022)) -+#endif -+ skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd)); -+#endif -+ -+ DPA_BUG_ON(fd_off != priv->rx_headroom); -+ skb_reserve(skb, fd_off); -+ skb_put(skb, dpa_fd_length(fd)); -+ -+ /* Peek at the parse results for csum validation */ -+ parse_results = (const fm_prs_result_t *)(vaddr + -+ DPA_RX_PRIV_DATA_SIZE); -+ _dpa_process_parse_results(parse_results, fd, skb, use_gro); -+ -+#ifdef CONFIG_FSL_DPAA_1588 -+ if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl) -+ dpa_ptp_store_rxstamp(priv, skb, vaddr); -+#endif -+#ifdef CONFIG_FSL_DPAA_TS -+ if (priv->ts_rx_en) -+ dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr); -+#endif /* CONFIG_FSL_DPAA_TS */ -+ -+ return skb; -+} -+ -+ -+/* Build an skb with the data of the first S/G entry in the linear portion and -+ * the rest of the frame as skb fragments. -+ * -+ * The page fragment holding the S/G Table is recycled here. -+ */ -+static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv, -+ const struct qm_fd *fd, int *use_gro, -+ int *count_ptr) -+{ -+ const struct qm_sg_entry *sgt; -+ dma_addr_t addr = qm_fd_addr(fd); -+ ssize_t fd_off = dpa_fd_offset(fd); -+ dma_addr_t sg_addr; -+ void *vaddr, *sg_vaddr; -+ struct dpa_bp *dpa_bp; -+ struct page *page, *head_page; -+ int frag_offset, frag_len; -+ int page_offset; -+ int i; -+ const fm_prs_result_t *parse_results; -+ struct sk_buff *skb = NULL, *skb_tmp, **skbh; -+ -+ vaddr = phys_to_virt(addr); -+ DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES)); -+ -+ dpa_bp = priv->dpa_bp; -+ /* Iterate through the SGT entries and add data buffers to the skb */ -+ sgt = vaddr + fd_off; -+ for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) { -+ /* Extension bit is not supported */ -+ DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i])); -+ -+ /* We use a single global Rx pool */ -+ DPA_BUG_ON(dpa_bp != -+ dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i]))); -+ -+ sg_addr = qm_sg_addr(&sgt[i]); -+ sg_vaddr = phys_to_virt(sg_addr); -+ DPA_BUG_ON(!IS_ALIGNED((unsigned long)sg_vaddr, -+ SMP_CACHE_BYTES)); -+ -+ dma_unmap_single(dpa_bp->dev, sg_addr, dpa_bp->size, -+ DMA_BIDIRECTIONAL); -+ if (i == 0) { -+ DPA_READ_SKB_PTR(skb, skbh, sg_vaddr, -1); -+ DPA_BUG_ON(skb->head != sg_vaddr); -+#ifdef CONFIG_FSL_DPAA_1588 -+ if (priv->tsu && priv->tsu->valid && -+ priv->tsu->hwts_rx_en_ioctl) -+ dpa_ptp_store_rxstamp(priv, skb, vaddr); -+#endif -+#ifdef CONFIG_FSL_DPAA_TS -+ if (priv->ts_rx_en) -+ dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr); -+#endif /* CONFIG_FSL_DPAA_TS */ -+ -+ /* In the case of a SG frame, FMan stores the Internal -+ * Context in the buffer containing the sgt. -+ * Inspect the parse results before anything else. -+ */ -+ parse_results = (const fm_prs_result_t *)(vaddr + -+ DPA_RX_PRIV_DATA_SIZE); -+ _dpa_process_parse_results(parse_results, fd, skb, -+ use_gro); -+ -+ /* Make sure forwarded skbs will have enough space -+ * on Tx, if extra headers are added. -+ */ -+ DPA_BUG_ON(fd_off != priv->rx_headroom); -+ skb_reserve(skb, fd_off); -+ skb_put(skb, qm_sg_entry_get_len(&sgt[i])); -+ } else { -+ /* Not the first S/G entry; all data from buffer will -+ * be added in an skb fragment; fragment index is offset -+ * by one since first S/G entry was incorporated in the -+ * linear part of the skb. -+ * -+ * Caution: 'page' may be a tail page. -+ */ -+ DPA_READ_SKB_PTR(skb_tmp, skbh, sg_vaddr, -1); -+ page = virt_to_page(sg_vaddr); -+ head_page = virt_to_head_page(sg_vaddr); -+ -+ /* Free (only) the skbuff shell because its data buffer -+ * is already a frag in the main skb. -+ */ -+ get_page(head_page); -+ dev_kfree_skb(skb_tmp); -+ -+ /* Compute offset in (possibly tail) page */ -+ page_offset = ((unsigned long)sg_vaddr & -+ (PAGE_SIZE - 1)) + -+ (page_address(page) - page_address(head_page)); -+ /* page_offset only refers to the beginning of sgt[i]; -+ * but the buffer itself may have an internal offset. -+ */ -+ frag_offset = qm_sg_entry_get_offset(&sgt[i]) + -+ page_offset; -+ frag_len = qm_sg_entry_get_len(&sgt[i]); -+ /* skb_add_rx_frag() does no checking on the page; if -+ * we pass it a tail page, we'll end up with -+ * bad page accounting and eventually with segafults. -+ */ -+ skb_add_rx_frag(skb, i - 1, head_page, frag_offset, -+ frag_len, dpa_bp->size); -+ } -+ /* Update the pool count for the current {cpu x bpool} */ -+ (*count_ptr)--; -+ -+ if (qm_sg_entry_get_final(&sgt[i])) -+ break; -+ } -+ WARN_ONCE(i == DPA_SGT_MAX_ENTRIES, "No final bit on SGT\n"); -+ -+ /* recycle the SGT fragment */ -+ DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid)); -+ dpa_bp_recycle_frag(dpa_bp, (unsigned long)vaddr, count_ptr); -+ return skb; -+} -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+static inline int dpa_skb_loop(const struct dpa_priv_s *priv, -+ struct sk_buff *skb) -+{ -+ if (unlikely(priv->loop_to < 0)) -+ return 0; /* loop disabled by default */ -+ -+ skb_push(skb, ETH_HLEN); /* compensate for eth_type_trans */ -+ dpa_tx(skb, dpa_loop_netdevs[priv->loop_to]); -+ -+ return 1; /* Frame Tx on the selected interface */ -+} -+#endif -+ -+void __hot _dpa_rx(struct net_device *net_dev, -+ struct qman_portal *portal, -+ const struct dpa_priv_s *priv, -+ struct dpa_percpu_priv_s *percpu_priv, -+ const struct qm_fd *fd, -+ u32 fqid, -+ int *count_ptr) -+{ -+ struct dpa_bp *dpa_bp; -+ struct sk_buff *skb; -+ dma_addr_t addr = qm_fd_addr(fd); -+ u32 fd_status = fd->status; -+ unsigned int skb_len; -+ struct rtnl_link_stats64 *percpu_stats = &percpu_priv->stats; -+ int use_gro = net_dev->features & NETIF_F_GRO; -+ -+ if (unlikely(fd_status & FM_FD_STAT_RX_ERRORS) != 0) { -+ if (netif_msg_hw(priv) && net_ratelimit()) -+ netdev_warn(net_dev, "FD status = 0x%08x\n", -+ fd_status & FM_FD_STAT_RX_ERRORS); -+ -+ percpu_stats->rx_errors++; -+ goto _release_frame; -+ } -+ -+ dpa_bp = priv->dpa_bp; -+ DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid)); -+ -+ /* prefetch the first 64 bytes of the frame or the SGT start */ -+ dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL); -+ prefetch(phys_to_virt(addr) + dpa_fd_offset(fd)); -+ -+ /* The only FD types that we may receive are contig and S/G */ -+ DPA_BUG_ON((fd->format != qm_fd_contig) && (fd->format != qm_fd_sg)); -+ -+ if (likely(fd->format == qm_fd_contig)) { -+#ifdef CONFIG_FSL_DPAA_HOOKS -+ /* Execute the Rx processing hook, if it exists. */ -+ if (dpaa_eth_hooks.rx_default && -+ dpaa_eth_hooks.rx_default((void *)fd, net_dev, -+ fqid) == DPAA_ETH_STOLEN) { -+ /* won't count the rx bytes in */ -+ return; -+ } -+#endif -+ skb = contig_fd_to_skb(priv, fd, &use_gro); -+ } else { -+ skb = sg_fd_to_skb(priv, fd, &use_gro, count_ptr); -+ percpu_priv->rx_sg++; -+ } -+ -+ /* Account for either the contig buffer or the SGT buffer (depending on -+ * which case we were in) having been removed from the pool. -+ */ -+ (*count_ptr)--; -+ skb->protocol = eth_type_trans(skb, net_dev); -+ -+ /* IP Reassembled frames are allowed to be larger than MTU */ -+ if (unlikely(dpa_check_rx_mtu(skb, net_dev->mtu) && -+ !(fd_status & FM_FD_IPR))) { -+ percpu_stats->rx_dropped++; -+ goto drop_bad_frame; -+ } -+ -+ skb_len = skb->len; -+ -+#ifdef CONFIG_FSL_DPAA_DBG_LOOP -+ if (dpa_skb_loop(priv, skb)) { -+ percpu_stats->rx_packets++; -+ percpu_stats->rx_bytes += skb_len; -+ return; -+ } -+#endif -+ -+ if (use_gro) { -+ gro_result_t gro_result; -+ const struct qman_portal_config *pc = -+ qman_p_get_portal_config(portal); -+ struct dpa_napi_portal *np = &percpu_priv->np[pc->index]; -+ -+ np->p = portal; -+ gro_result = napi_gro_receive(&np->napi, skb); -+ /* If frame is dropped by the stack, rx_dropped counter is -+ * incremented automatically, so no need for us to update it -+ */ -+ if (unlikely(gro_result == GRO_DROP)) -+ goto packet_dropped; -+ } else if (unlikely(netif_receive_skb(skb) == NET_RX_DROP)) -+ goto packet_dropped; -+ -+ percpu_stats->rx_packets++; -+ percpu_stats->rx_bytes += skb_len; -+ -+packet_dropped: -+ return; -+ -+drop_bad_frame: -+ dev_kfree_skb(skb); -+ return; -+ -+_release_frame: -+ dpa_fd_release(net_dev, fd); -+} -+ -+int __hot skb_to_contig_fd(struct dpa_priv_s *priv, -+ struct sk_buff *skb, struct qm_fd *fd, -+ int *count_ptr, int *offset) -+{ -+ struct sk_buff **skbh; -+ dma_addr_t addr; -+ struct dpa_bp *dpa_bp = priv->dpa_bp; -+ struct net_device *net_dev = priv->net_dev; -+ int err; -+ enum dma_data_direction dma_dir; -+ unsigned char *buffer_start; -+ int dma_map_size; -+ -+#ifndef CONFIG_FSL_DPAA_TS -+ /* Check recycling conditions; only if timestamp support is not -+ * enabled, otherwise we need the fd back on tx confirmation -+ */ -+ -+ /* We can recycle the buffer if: -+ * - the pool is not full -+ * - the buffer meets the skb recycling conditions -+ * - the buffer meets our own (size, offset, align) conditions -+ */ -+ if (likely((*count_ptr < dpa_bp->target_count) && -+ dpa_skb_is_recyclable(skb) && -+ dpa_buf_is_recyclable(skb, dpa_bp->size, -+ priv->tx_headroom, &buffer_start))) { -+ /* Buffer is recyclable; use the new start address -+ * and set fd parameters and DMA mapping direction -+ */ -+ fd->bpid = dpa_bp->bpid; -+ DPA_BUG_ON(skb->data - buffer_start > DPA_MAX_FD_OFFSET); -+ fd->offset = (uint16_t)(skb->data - buffer_start); -+ dma_dir = DMA_BIDIRECTIONAL; -+ dma_map_size = dpa_bp->size; -+ -+ DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, -1); -+ *offset = skb_headroom(skb) - fd->offset; -+ } else -+#endif -+ { -+ /* Not recyclable. -+ * We are guaranteed to have at least tx_headroom bytes -+ * available, so just use that for offset. -+ */ -+ fd->bpid = 0xff; -+ buffer_start = skb->data - priv->tx_headroom; -+ fd->offset = priv->tx_headroom; -+ dma_dir = DMA_TO_DEVICE; -+ dma_map_size = skb_tail_pointer(skb) - buffer_start; -+ -+ /* The buffer will be Tx-confirmed, but the TxConf cb must -+ * necessarily look at our Tx private data to retrieve the -+ * skbuff. (In short: can't use DPA_WRITE_SKB_PTR() here.) -+ */ -+ DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, 0); -+ } -+ -+ /* Enable L3/L4 hardware checksum computation. -+ * -+ * We must do this before dma_map_single(DMA_TO_DEVICE), because we may -+ * need to write into the skb. -+ */ -+ err = dpa_enable_tx_csum(priv, skb, fd, -+ ((char *)skbh) + DPA_TX_PRIV_DATA_SIZE); -+ if (unlikely(err < 0)) { -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ netdev_err(net_dev, "HW csum error: %d\n", err); -+ return err; -+ } -+ -+ /* Fill in the rest of the FD fields */ -+ fd->format = qm_fd_contig; -+ fd->length20 = skb->len; -+ fd->cmd |= FM_FD_CMD_FCO; -+ -+ /* Map the entire buffer size that may be seen by FMan, but no more */ -+ addr = dma_map_single(dpa_bp->dev, skbh, dma_map_size, dma_dir); -+ if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) { -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ netdev_err(net_dev, "dma_map_single() failed\n"); -+ return -EINVAL; -+ } -+ qm_fd_addr_set64(fd, addr); -+ -+ return 0; -+} -+EXPORT_SYMBOL(skb_to_contig_fd); -+ -+#ifndef CONFIG_PPC -+struct sk_buff *split_skb_at_4k_boundaries(struct sk_buff *skb) -+{ -+ unsigned int length, nr_frags, moved_len = 0; -+ u64 page_start; -+ struct page *page; -+ skb_frag_t *frag; -+ int i = 0, j = 0; -+ -+ /* make sure skb is not shared */ -+ skb = skb_share_check(skb, GFP_ATOMIC); -+ if (!skb) -+ return NULL; -+ -+ nr_frags = skb_shinfo(skb)->nr_frags; -+ page_start = (u64)skb->data; -+ -+ /* split the linear part at the first 4k boundary and create one (big) -+ * fragment with the rest -+ */ -+ if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb))) { -+ /* we'll add one more frag, make sure there's room */ -+ if (nr_frags + 1 > DPA_SGT_MAX_ENTRIES) -+ return NULL; -+ -+ /* next page boundary */ -+ page_start = (page_start + 0x1000) & ~0xFFF; -+ page = virt_to_page(page_start); -+ -+ /* move the rest of fragments to make room for a new one at j */ -+ for (i = nr_frags - 1; i >= j; i--) -+ skb_shinfo(skb)->frags[i + 1] = skb_shinfo(skb)->frags[i]; -+ -+ /* move length bytes to a paged fragment at j */ -+ length = min((u64)0x1000, -+ (u64)skb->data + skb_headlen(skb) - page_start); -+ skb->data_len += length; -+ moved_len += length; -+ skb_fill_page_desc(skb, j++, page, 0, length); -+ get_page(page); -+ skb_shinfo(skb)->nr_frags = ++nr_frags; -+ } -+ /* adjust the tail pointer */ -+ skb->tail -= moved_len; -+ j = 0; -+ -+ /* split any paged fragment that crosses a 4K boundary */ -+ while (j < nr_frags) { -+ frag = &skb_shinfo(skb)->frags[j]; -+ -+ /* if there is a 4K boundary between the fragment's offset and end */ -+ if (HAS_DMA_ISSUE(frag->page_offset, frag->size)) { -+ /* we'll add one more frag, make sure there's room */ -+ if (nr_frags + 1 > DPA_SGT_MAX_ENTRIES) -+ return NULL; -+ -+ /* new page boundary */ -+ page_start = (u64)page_address(skb_frag_page(frag)) + -+ frag->page_offset + 0x1000; -+ page_start = (u64)page_start & ~0xFFF; -+ page = virt_to_page(page_start); -+ -+ /* move the rest of fragments to make room for a new one at j+1 */ -+ for (i = nr_frags - 1; i > j; i--) -+ skb_shinfo(skb)->frags[i + 1] = -+ skb_shinfo(skb)->frags[i]; -+ -+ /* move length bytes to a new paged fragment at j+1 */ -+ length = (u64)page_address(skb_frag_page(frag)) + -+ frag->page_offset + frag->size - page_start; -+ frag->size -= length; -+ skb_fill_page_desc(skb, j + 1, page, 0, length); -+ get_page(page); -+ skb_shinfo(skb)->nr_frags = ++nr_frags; -+ } -+ -+ /* move to next frag */ -+ j++; -+ } -+ -+ return skb; -+} -+#endif -+ -+int __hot skb_to_sg_fd(struct dpa_priv_s *priv, -+ struct sk_buff *skb, struct qm_fd *fd) -+{ -+ struct dpa_bp *dpa_bp = priv->dpa_bp; -+ dma_addr_t addr; -+ dma_addr_t sg_addr; -+ struct sk_buff **skbh; -+ struct net_device *net_dev = priv->net_dev; -+ int sg_len, sgt_size; -+ int err; -+ -+ struct qm_sg_entry *sgt; -+ void *sgt_buf; -+ skb_frag_t *frag; -+ int i = 0, j = 0; -+ int nr_frags; -+ const enum dma_data_direction dma_dir = DMA_TO_DEVICE; -+ -+ nr_frags = skb_shinfo(skb)->nr_frags; -+ fd->format = qm_fd_sg; -+ -+ sgt_size = sizeof(struct qm_sg_entry) * (1 + nr_frags); -+ -+ /* Get a page frag to store the SGTable, or a full page if the errata -+ * is in place and we need to avoid crossing a 4k boundary. -+ */ -+#ifndef CONFIG_PPC -+ if (unlikely(dpaa_errata_a010022)) -+ sgt_buf = page_address(alloc_page(GFP_ATOMIC)); -+ else -+#endif -+ sgt_buf = netdev_alloc_frag(priv->tx_headroom + sgt_size); -+ if (unlikely(!sgt_buf)) { -+ dev_err(dpa_bp->dev, "netdev_alloc_frag() failed\n"); -+ return -ENOMEM; -+ } -+ -+ /* it seems that the memory allocator does not zero the allocated mem */ -+ memset(sgt_buf, 0, priv->tx_headroom + sgt_size); -+ -+ /* Enable L3/L4 hardware checksum computation. -+ * -+ * We must do this before dma_map_single(DMA_TO_DEVICE), because we may -+ * need to write into the skb. -+ */ -+ err = dpa_enable_tx_csum(priv, skb, fd, -+ sgt_buf + DPA_TX_PRIV_DATA_SIZE); -+ if (unlikely(err < 0)) { -+ if (netif_msg_tx_err(priv) && net_ratelimit()) -+ netdev_err(net_dev, "HW csum error: %d\n", err); -+ goto csum_failed; -+ } -+ -+ /* Assign the data from skb->data to the first SG list entry */ -+ sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom); -+ sg_len = skb_headlen(skb); -+ qm_sg_entry_set_bpid(&sgt[0], 0xff); -+ qm_sg_entry_set_offset(&sgt[0], 0); -+ qm_sg_entry_set_len(&sgt[0], sg_len); -+ qm_sg_entry_set_ext(&sgt[0], 0); -+ qm_sg_entry_set_final(&sgt[0], 0); -+ -+ addr = dma_map_single(dpa_bp->dev, skb->data, sg_len, dma_dir); -+ if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) { -+ dev_err(dpa_bp->dev, "DMA mapping failed"); -+ err = -EINVAL; -+ goto sg0_map_failed; -+ } -+ -+ qm_sg_entry_set64(&sgt[0], addr); -+ -+ /* populate the rest of SGT entries */ -+ for (i = 1; i <= nr_frags; i++) { -+ frag = &skb_shinfo(skb)->frags[i - 1]; -+ qm_sg_entry_set_bpid(&sgt[i], 0xff); -+ qm_sg_entry_set_offset(&sgt[i], 0); -+ qm_sg_entry_set_len(&sgt[i], frag->size); -+ qm_sg_entry_set_ext(&sgt[i], 0); -+ -+ if (i == nr_frags) -+ qm_sg_entry_set_final(&sgt[i], 1); -+ else -+ qm_sg_entry_set_final(&sgt[i], 0); -+ -+ DPA_BUG_ON(!skb_frag_page(frag)); -+ addr = skb_frag_dma_map(dpa_bp->dev, frag, 0, frag->size, -+ dma_dir); -+ if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) { -+ dev_err(dpa_bp->dev, "DMA mapping failed"); -+ err = -EINVAL; -+ goto sg_map_failed; -+ } -+ -+ /* keep the offset in the address */ -+ qm_sg_entry_set64(&sgt[i], addr); -+ } -+ -+ fd->length20 = skb->len; -+ fd->offset = priv->tx_headroom; -+ -+ /* DMA map the SGT page */ -+ DPA_WRITE_SKB_PTR(skb, skbh, sgt_buf, 0); -+ addr = dma_map_single(dpa_bp->dev, sgt_buf, -+ priv->tx_headroom + sgt_size, -+ dma_dir); -+ -+ if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) { -+ dev_err(dpa_bp->dev, "DMA mapping failed"); -+ err = -EINVAL; -+ goto sgt_map_failed; -+ } -+ -+ qm_fd_addr_set64(fd, addr); -+ fd->bpid = 0xff; -+ fd->cmd |= FM_FD_CMD_FCO; -+ -+ return 0; -+ -+sgt_map_failed: -+sg_map_failed: -+ for (j = 0; j < i; j++) { -+ sg_addr = qm_sg_addr(&sgt[j]); -+ dma_unmap_page(dpa_bp->dev, sg_addr, -+ qm_sg_entry_get_len(&sgt[j]), dma_dir); -+ } -+sg0_map_failed: -+csum_failed: -+ put_page(virt_to_head_page(sgt_buf)); -+ -+ return err; -+} -+EXPORT_SYMBOL(skb_to_sg_fd); -+ -+int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv; -+ const int queue_mapping = dpa_get_queue_mapping(skb); -+ struct qman_fq *egress_fq, *conf_fq; -+ -+#ifdef CONFIG_FSL_DPAA_HOOKS -+ /* If there is a Tx hook, run it. */ -+ if (dpaa_eth_hooks.tx && -+ dpaa_eth_hooks.tx(skb, net_dev) == DPAA_ETH_STOLEN) -+ /* won't update any Tx stats */ -+ return NETDEV_TX_OK; -+#endif -+ -+ priv = netdev_priv(net_dev); -+ -+#ifdef CONFIG_FSL_DPAA_CEETM -+ if (priv->ceetm_en) -+ return ceetm_tx(skb, net_dev); -+#endif -+ -+ egress_fq = priv->egress_fqs[queue_mapping]; -+ conf_fq = priv->conf_fqs[queue_mapping]; -+ -+ return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq); -+} -+ -+int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev, -+ struct qman_fq *egress_fq, struct qman_fq *conf_fq) -+{ -+ struct dpa_priv_s *priv; -+ struct qm_fd fd; -+ struct dpa_percpu_priv_s *percpu_priv; -+ struct rtnl_link_stats64 *percpu_stats; -+ int err = 0; -+ const bool nonlinear = skb_is_nonlinear(skb); -+ int *countptr, offset = 0; -+ -+ priv = netdev_priv(net_dev); -+ /* Non-migratable context, safe to use raw_cpu_ptr */ -+ percpu_priv = raw_cpu_ptr(priv->percpu_priv); -+ percpu_stats = &percpu_priv->stats; -+ countptr = raw_cpu_ptr(priv->dpa_bp->percpu_count); -+ -+ clear_fd(&fd); -+ -+#ifdef CONFIG_FSL_DPAA_1588 -+ if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl) -+ fd.cmd |= FM_FD_CMD_UPD; -+#endif -+#ifdef CONFIG_FSL_DPAA_TS -+ if (unlikely(priv->ts_tx_en && -+ skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) -+ fd.cmd |= FM_FD_CMD_UPD; -+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; -+#endif /* CONFIG_FSL_DPAA_TS */ -+ -+#ifndef CONFIG_PPC -+ if (unlikely(dpaa_errata_a010022)) { -+ skb = split_skb_at_4k_boundaries(skb); -+ if (!skb) -+ goto skb_to_fd_failed; -+ } -+#endif -+ -+ /* MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure -+ * we don't feed FMan with more fragments than it supports. -+ * Btw, we're using the first sgt entry to store the linear part of -+ * the skb, so we're one extra frag short. -+ */ -+ if (nonlinear && -+ likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) { -+ /* Just create a S/G fd based on the skb */ -+ err = skb_to_sg_fd(priv, skb, &fd); -+ percpu_priv->tx_frag_skbuffs++; -+ } else { -+ /* Make sure we have enough headroom to accommodate private -+ * data, parse results, etc. Normally this shouldn't happen if -+ * we're here via the standard kernel stack. -+ */ -+ if (unlikely(skb_headroom(skb) < priv->tx_headroom)) { -+ struct sk_buff *skb_new; -+ -+ skb_new = skb_realloc_headroom(skb, priv->tx_headroom); -+ if (unlikely(!skb_new)) { -+ dev_kfree_skb(skb); -+ percpu_stats->tx_errors++; -+ return NETDEV_TX_OK; -+ } -+ dev_kfree_skb(skb); -+ skb = skb_new; -+ } -+ -+ /* We're going to store the skb backpointer at the beginning -+ * of the data buffer, so we need a privately owned skb -+ */ -+ -+ /* Code borrowed from skb_unshare(). */ -+ if (skb_cloned(skb)) { -+ struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC); -+ kfree_skb(skb); -+ skb = nskb; -+ /* skb_copy() has now linearized the skbuff. */ -+ } else if (unlikely(nonlinear)) { -+ /* We are here because the egress skb contains -+ * more fragments than we support. In this case, -+ * we have no choice but to linearize it ourselves. -+ */ -+ err = __skb_linearize(skb); -+ } -+ if (unlikely(!skb || err < 0)) -+ /* Common out-of-memory error path */ -+ goto enomem; -+ -+ err = skb_to_contig_fd(priv, skb, &fd, countptr, &offset); -+ } -+ if (unlikely(err < 0)) -+ goto skb_to_fd_failed; -+ -+ if (fd.bpid != 0xff) { -+ skb_recycle(skb); -+ /* skb_recycle() reserves NET_SKB_PAD as skb headroom, -+ * but we need the skb to look as if returned by build_skb(). -+ * We need to manually adjust the tailptr as well. -+ */ -+ skb->data = skb->head + offset; -+ skb_reset_tail_pointer(skb); -+ -+ (*countptr)++; -+ percpu_priv->tx_returned++; -+ } -+ -+ if (unlikely(dpa_xmit(priv, percpu_stats, &fd, egress_fq, conf_fq) < 0)) -+ goto xmit_failed; -+ -+ return NETDEV_TX_OK; -+ -+xmit_failed: -+ if (fd.bpid != 0xff) { -+ (*countptr)--; -+ percpu_priv->tx_returned--; -+ dpa_fd_release(net_dev, &fd); -+ percpu_stats->tx_errors++; -+ return NETDEV_TX_OK; -+ } -+ _dpa_cleanup_tx_fd(priv, &fd); -+skb_to_fd_failed: -+enomem: -+ percpu_stats->tx_errors++; -+ dev_kfree_skb(skb); -+ return NETDEV_TX_OK; -+} -+EXPORT_SYMBOL(dpa_tx_extended); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c -@@ -0,0 +1,278 @@ -+/* Copyright 2008-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "dpaa_eth.h" -+#include "mac.h" /* struct mac_device */ -+#ifdef CONFIG_FSL_DPAA_1588 -+#include "dpaa_1588.h" -+#endif -+ -+static ssize_t dpaa_eth_show_addr(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ struct mac_device *mac_dev = priv->mac_dev; -+ -+ if (mac_dev) -+ return sprintf(buf, "%llx", -+ (unsigned long long)mac_dev->res->start); -+ else -+ return sprintf(buf, "none"); -+} -+ -+static ssize_t dpaa_eth_show_type(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ ssize_t res = 0; -+ -+ if (priv) -+ res = sprintf(buf, "%s", priv->if_type); -+ -+ return res; -+} -+ -+static ssize_t dpaa_eth_show_fqids(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ ssize_t bytes = 0; -+ int i = 0; -+ char *str; -+ struct dpa_fq *fq; -+ struct dpa_fq *tmp; -+ struct dpa_fq *prev = NULL; -+ u32 first_fqid = 0; -+ u32 last_fqid = 0; -+ char *prevstr = NULL; -+ -+ list_for_each_entry_safe(fq, tmp, &priv->dpa_fq_list, list) { -+ switch (fq->fq_type) { -+ case FQ_TYPE_RX_DEFAULT: -+ str = "Rx default"; -+ break; -+ case FQ_TYPE_RX_ERROR: -+ str = "Rx error"; -+ break; -+ case FQ_TYPE_RX_PCD: -+ str = "Rx PCD"; -+ break; -+ case FQ_TYPE_TX_CONFIRM: -+ str = "Tx default confirmation"; -+ break; -+ case FQ_TYPE_TX_CONF_MQ: -+ str = "Tx confirmation (mq)"; -+ break; -+ case FQ_TYPE_TX_ERROR: -+ str = "Tx error"; -+ break; -+ case FQ_TYPE_TX: -+ str = "Tx"; -+ break; -+ case FQ_TYPE_RX_PCD_HI_PRIO: -+ str ="Rx PCD High Priority"; -+ break; -+ default: -+ str = "Unknown"; -+ } -+ -+ if (prev && (abs(fq->fqid - prev->fqid) != 1 || -+ str != prevstr)) { -+ if (last_fqid == first_fqid) -+ bytes += sprintf(buf + bytes, -+ "%s: %d\n", prevstr, prev->fqid); -+ else -+ bytes += sprintf(buf + bytes, -+ "%s: %d - %d\n", prevstr, -+ first_fqid, last_fqid); -+ } -+ -+ if (prev && abs(fq->fqid - prev->fqid) == 1 && str == prevstr) -+ last_fqid = fq->fqid; -+ else -+ first_fqid = last_fqid = fq->fqid; -+ -+ prev = fq; -+ prevstr = str; -+ i++; -+ } -+ -+ if (prev) { -+ if (last_fqid == first_fqid) -+ bytes += sprintf(buf + bytes, "%s: %d\n", prevstr, -+ prev->fqid); -+ else -+ bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr, -+ first_fqid, last_fqid); -+ } -+ -+ return bytes; -+} -+ -+static ssize_t dpaa_eth_show_bpids(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ ssize_t bytes = 0; -+ struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ struct dpa_bp *dpa_bp = priv->dpa_bp; -+ int i = 0; -+ -+ for (i = 0; i < priv->bp_count; i++) -+ bytes += snprintf(buf + bytes, PAGE_SIZE, "%u\n", -+ dpa_bp[i].bpid); -+ -+ return bytes; -+} -+ -+static ssize_t dpaa_eth_show_mac_regs(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ struct mac_device *mac_dev = priv->mac_dev; -+ int n = 0; -+ -+ if (mac_dev) -+ n = fm_mac_dump_regs(mac_dev, buf, n); -+ else -+ return sprintf(buf, "no mac registers\n"); -+ -+ return n; -+} -+ -+static ssize_t dpaa_eth_show_mac_rx_stats(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ struct mac_device *mac_dev = priv->mac_dev; -+ int n = 0; -+ -+ if (mac_dev) -+ n = fm_mac_dump_rx_stats(mac_dev, buf, n); -+ else -+ return sprintf(buf, "no mac rx stats\n"); -+ -+ return n; -+} -+ -+static ssize_t dpaa_eth_show_mac_tx_stats(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ struct mac_device *mac_dev = priv->mac_dev; -+ int n = 0; -+ -+ if (mac_dev) -+ n = fm_mac_dump_tx_stats(mac_dev, buf, n); -+ else -+ return sprintf(buf, "no mac tx stats\n"); -+ -+ return n; -+} -+ -+#ifdef CONFIG_FSL_DPAA_1588 -+static ssize_t dpaa_eth_show_ptp_1588(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ -+ if (priv->tsu && priv->tsu->valid) -+ return sprintf(buf, "1\n"); -+ else -+ return sprintf(buf, "0\n"); -+} -+ -+static ssize_t dpaa_eth_set_ptp_1588(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ unsigned int num; -+ unsigned long flags; -+ -+ if (kstrtouint(buf, 0, &num) < 0) -+ return -EINVAL; -+ -+ local_irq_save(flags); -+ -+ if (num) { -+ if (priv->tsu) -+ priv->tsu->valid = TRUE; -+ } else { -+ if (priv->tsu) -+ priv->tsu->valid = FALSE; -+ } -+ -+ local_irq_restore(flags); -+ -+ return count; -+} -+#endif -+ -+static struct device_attribute dpaa_eth_attrs[] = { -+ __ATTR(device_addr, S_IRUGO, dpaa_eth_show_addr, NULL), -+ __ATTR(device_type, S_IRUGO, dpaa_eth_show_type, NULL), -+ __ATTR(fqids, S_IRUGO, dpaa_eth_show_fqids, NULL), -+ __ATTR(bpids, S_IRUGO, dpaa_eth_show_bpids, NULL), -+ __ATTR(mac_regs, S_IRUGO, dpaa_eth_show_mac_regs, NULL), -+ __ATTR(mac_rx_stats, S_IRUGO, dpaa_eth_show_mac_rx_stats, NULL), -+ __ATTR(mac_tx_stats, S_IRUGO, dpaa_eth_show_mac_tx_stats, NULL), -+#ifdef CONFIG_FSL_DPAA_1588 -+ __ATTR(ptp_1588, S_IRUGO | S_IWUSR, dpaa_eth_show_ptp_1588, -+ dpaa_eth_set_ptp_1588), -+#endif -+}; -+ -+void dpaa_eth_sysfs_init(struct device *dev) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++) -+ if (device_create_file(dev, &dpaa_eth_attrs[i])) { -+ dev_err(dev, "Error creating sysfs file\n"); -+ while (i > 0) -+ device_remove_file(dev, &dpaa_eth_attrs[--i]); -+ return; -+ } -+} -+EXPORT_SYMBOL(dpaa_eth_sysfs_init); -+ -+void dpaa_eth_sysfs_remove(struct device *dev) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++) -+ device_remove_file(dev, &dpaa_eth_attrs[i]); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h -@@ -0,0 +1,144 @@ -+/* Copyright 2013 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM dpaa_eth -+ -+#if !defined(_DPAA_ETH_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _DPAA_ETH_TRACE_H -+ -+#include -+#include -+#include "dpaa_eth.h" -+#include -+ -+#define fd_format_name(format) { qm_fd_##format, #format } -+#define fd_format_list \ -+ fd_format_name(contig), \ -+ fd_format_name(sg) -+#define TR_FMT "[%s] fqid=%d, fd: addr=0x%llx, format=%s, off=%u, len=%u," \ -+ " status=0x%08x" -+ -+/* This is used to declare a class of events. -+ * individual events of this type will be defined below. -+ */ -+ -+/* Store details about a frame descriptor and the FQ on which it was -+ * transmitted/received. -+ */ -+DECLARE_EVENT_CLASS(dpaa_eth_fd, -+ /* Trace function prototype */ -+ TP_PROTO(struct net_device *netdev, -+ struct qman_fq *fq, -+ const struct qm_fd *fd), -+ -+ /* Repeat argument list here */ -+ TP_ARGS(netdev, fq, fd), -+ -+ /* A structure containing the relevant information we want to record. -+ * Declare name and type for each normal element, name, type and size -+ * for arrays. Use __string for variable length strings. -+ */ -+ TP_STRUCT__entry( -+ __field(u32, fqid) -+ __field(u64, fd_addr) -+ __field(u8, fd_format) -+ __field(u16, fd_offset) -+ __field(u32, fd_length) -+ __field(u32, fd_status) -+ __string(name, netdev->name) -+ ), -+ -+ /* The function that assigns values to the above declared fields */ -+ TP_fast_assign( -+ __entry->fqid = fq->fqid; -+ __entry->fd_addr = qm_fd_addr_get64(fd); -+ __entry->fd_format = fd->format; -+ __entry->fd_offset = dpa_fd_offset(fd); -+ __entry->fd_length = dpa_fd_length(fd); -+ __entry->fd_status = fd->status; -+ __assign_str(name, netdev->name); -+ ), -+ -+ /* This is what gets printed when the trace event is triggered */ -+ /* TODO: print the status using __print_flags() */ -+ TP_printk(TR_FMT, -+ __get_str(name), __entry->fqid, __entry->fd_addr, -+ __print_symbolic(__entry->fd_format, fd_format_list), -+ __entry->fd_offset, __entry->fd_length, __entry->fd_status) -+); -+ -+/* Now declare events of the above type. Format is: -+ * DEFINE_EVENT(class, name, proto, args), with proto and args same as for class -+ */ -+ -+/* Tx (egress) fd */ -+DEFINE_EVENT(dpaa_eth_fd, dpa_tx_fd, -+ -+ TP_PROTO(struct net_device *netdev, -+ struct qman_fq *fq, -+ const struct qm_fd *fd), -+ -+ TP_ARGS(netdev, fq, fd) -+); -+ -+/* Rx fd */ -+DEFINE_EVENT(dpaa_eth_fd, dpa_rx_fd, -+ -+ TP_PROTO(struct net_device *netdev, -+ struct qman_fq *fq, -+ const struct qm_fd *fd), -+ -+ TP_ARGS(netdev, fq, fd) -+); -+ -+/* Tx confirmation fd */ -+DEFINE_EVENT(dpaa_eth_fd, dpa_tx_conf_fd, -+ -+ TP_PROTO(struct net_device *netdev, -+ struct qman_fq *fq, -+ const struct qm_fd *fd), -+ -+ TP_ARGS(netdev, fq, fd) -+); -+ -+/* If only one event of a certain type needs to be declared, use TRACE_EVENT(). -+ * The syntax is the same as for DECLARE_EVENT_CLASS(). -+ */ -+ -+#endif /* _DPAA_ETH_TRACE_H */ -+ -+/* This must be outside ifdef _DPAA_ETH_TRACE_H */ -+#undef TRACE_INCLUDE_PATH -+#define TRACE_INCLUDE_PATH . -+#undef TRACE_INCLUDE_FILE -+#define TRACE_INCLUDE_FILE dpaa_eth_trace -+#include ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c -@@ -0,0 +1,544 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifdef CONFIG_FSL_DPAA_ETH_DEBUG -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+#else -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": " fmt -+#endif -+ -+#include -+ -+#include "dpaa_eth.h" -+#include "mac.h" /* struct mac_device */ -+#include "dpaa_eth_common.h" -+ -+static const char dpa_stats_percpu[][ETH_GSTRING_LEN] = { -+ "interrupts", -+ "rx packets", -+ "tx packets", -+ "tx recycled", -+ "tx confirm", -+ "tx S/G", -+ "rx S/G", -+ "tx error", -+ "rx error", -+ "bp count" -+}; -+ -+static char dpa_stats_global[][ETH_GSTRING_LEN] = { -+ /* dpa rx errors */ -+ "rx dma error", -+ "rx frame physical error", -+ "rx frame size error", -+ "rx header error", -+ "rx csum error", -+ -+ /* demultiplexing errors */ -+ "qman cg_tdrop", -+ "qman wred", -+ "qman error cond", -+ "qman early window", -+ "qman late window", -+ "qman fq tdrop", -+ "qman fq retired", -+ "qman orp disabled", -+ -+ /* congestion related stats */ -+ "congestion time (ms)", -+ "entered congestion", -+ "congested (0/1)" -+}; -+ -+#define DPA_STATS_PERCPU_LEN ARRAY_SIZE(dpa_stats_percpu) -+#define DPA_STATS_GLOBAL_LEN ARRAY_SIZE(dpa_stats_global) -+ -+static int __cold dpa_get_settings(struct net_device *net_dev, -+ struct ethtool_cmd *et_cmd) -+{ -+ int _errno; -+ struct dpa_priv_s *priv; -+ -+ priv = netdev_priv(net_dev); -+ -+ if (priv->mac_dev == NULL) { -+ netdev_info(net_dev, "This is a MAC-less interface\n"); -+ return -ENODEV; -+ } -+ if (unlikely(priv->mac_dev->phy_dev == NULL)) { -+ netdev_dbg(net_dev, "phy device not initialized\n"); -+ return 0; -+ } -+ -+ _errno = phy_ethtool_gset(priv->mac_dev->phy_dev, et_cmd); -+ if (unlikely(_errno < 0)) -+ netdev_err(net_dev, "phy_ethtool_gset() = %d\n", _errno); -+ -+ return _errno; -+} -+ -+static int __cold dpa_set_settings(struct net_device *net_dev, -+ struct ethtool_cmd *et_cmd) -+{ -+ int _errno; -+ struct dpa_priv_s *priv; -+ -+ priv = netdev_priv(net_dev); -+ -+ if (priv->mac_dev == NULL) { -+ netdev_info(net_dev, "This is a MAC-less interface\n"); -+ return -ENODEV; -+ } -+ if (unlikely(priv->mac_dev->phy_dev == NULL)) { -+ netdev_err(net_dev, "phy device not initialized\n"); -+ return -ENODEV; -+ } -+ -+ _errno = phy_ethtool_sset(priv->mac_dev->phy_dev, et_cmd); -+ if (unlikely(_errno < 0)) -+ netdev_err(net_dev, "phy_ethtool_sset() = %d\n", _errno); -+ -+ return _errno; -+} -+ -+static void __cold dpa_get_drvinfo(struct net_device *net_dev, -+ struct ethtool_drvinfo *drvinfo) -+{ -+ int _errno; -+ -+ strncpy(drvinfo->driver, KBUILD_MODNAME, -+ sizeof(drvinfo->driver) - 1)[sizeof(drvinfo->driver)-1] = 0; -+ _errno = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), -+ "%X", 0); -+ -+ if (unlikely(_errno >= sizeof(drvinfo->fw_version))) { -+ /* Truncated output */ -+ netdev_notice(net_dev, "snprintf() = %d\n", _errno); -+ } else if (unlikely(_errno < 0)) { -+ netdev_warn(net_dev, "snprintf() = %d\n", _errno); -+ memset(drvinfo->fw_version, 0, sizeof(drvinfo->fw_version)); -+ } -+ strncpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent), -+ sizeof(drvinfo->bus_info)-1)[sizeof(drvinfo->bus_info)-1] = 0; -+} -+ -+static uint32_t __cold dpa_get_msglevel(struct net_device *net_dev) -+{ -+ return ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable; -+} -+ -+static void __cold dpa_set_msglevel(struct net_device *net_dev, -+ uint32_t msg_enable) -+{ -+ ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable = msg_enable; -+} -+ -+static int __cold dpa_nway_reset(struct net_device *net_dev) -+{ -+ int _errno; -+ struct dpa_priv_s *priv; -+ -+ priv = netdev_priv(net_dev); -+ -+ if (priv->mac_dev == NULL) { -+ netdev_info(net_dev, "This is a MAC-less interface\n"); -+ return -ENODEV; -+ } -+ if (unlikely(priv->mac_dev->phy_dev == NULL)) { -+ netdev_err(net_dev, "phy device not initialized\n"); -+ return -ENODEV; -+ } -+ -+ _errno = 0; -+ if (priv->mac_dev->phy_dev->autoneg) { -+ _errno = phy_start_aneg(priv->mac_dev->phy_dev); -+ if (unlikely(_errno < 0)) -+ netdev_err(net_dev, "phy_start_aneg() = %d\n", -+ _errno); -+ } -+ -+ return _errno; -+} -+ -+static void __cold dpa_get_pauseparam(struct net_device *net_dev, -+ struct ethtool_pauseparam *epause) -+{ -+ struct dpa_priv_s *priv; -+ struct mac_device *mac_dev; -+ struct phy_device *phy_dev; -+ -+ priv = netdev_priv(net_dev); -+ mac_dev = priv->mac_dev; -+ -+ if (mac_dev == NULL) { -+ netdev_info(net_dev, "This is a MAC-less interface\n"); -+ return; -+ } -+ -+ phy_dev = mac_dev->phy_dev; -+ if (unlikely(phy_dev == NULL)) { -+ netdev_err(net_dev, "phy device not initialized\n"); -+ return; -+ } -+ -+ epause->autoneg = mac_dev->autoneg_pause; -+ epause->rx_pause = mac_dev->rx_pause_active; -+ epause->tx_pause = mac_dev->tx_pause_active; -+} -+ -+static int __cold dpa_set_pauseparam(struct net_device *net_dev, -+ struct ethtool_pauseparam *epause) -+{ -+ struct dpa_priv_s *priv; -+ struct mac_device *mac_dev; -+ struct phy_device *phy_dev; -+ int _errno; -+ u32 newadv, oldadv; -+ bool rx_pause, tx_pause; -+ -+ priv = netdev_priv(net_dev); -+ mac_dev = priv->mac_dev; -+ -+ if (mac_dev == NULL) { -+ netdev_info(net_dev, "This is a MAC-less interface\n"); -+ return -ENODEV; -+ } -+ -+ phy_dev = mac_dev->phy_dev; -+ if (unlikely(phy_dev == NULL)) { -+ netdev_err(net_dev, "phy device not initialized\n"); -+ return -ENODEV; -+ } -+ -+ if (!(phy_dev->supported & SUPPORTED_Pause) || -+ (!(phy_dev->supported & SUPPORTED_Asym_Pause) && -+ (epause->rx_pause != epause->tx_pause))) -+ return -EINVAL; -+ -+ /* The MAC should know how to handle PAUSE frame autonegotiation before -+ * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE -+ * settings. -+ */ -+ mac_dev->autoneg_pause = !!epause->autoneg; -+ mac_dev->rx_pause_req = !!epause->rx_pause; -+ mac_dev->tx_pause_req = !!epause->tx_pause; -+ -+ /* Determine the sym/asym advertised PAUSE capabilities from the desired -+ * rx/tx pause settings. -+ */ -+ newadv = 0; -+ if (epause->rx_pause) -+ newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause; -+ if (epause->tx_pause) -+ newadv |= ADVERTISED_Asym_Pause; -+ -+ oldadv = phy_dev->advertising & -+ (ADVERTISED_Pause | ADVERTISED_Asym_Pause); -+ -+ /* If there are differences between the old and the new advertised -+ * values, restart PHY autonegotiation and advertise the new values. -+ */ -+ if (oldadv != newadv) { -+ phy_dev->advertising &= ~(ADVERTISED_Pause -+ | ADVERTISED_Asym_Pause); -+ phy_dev->advertising |= newadv; -+ if (phy_dev->autoneg) { -+ _errno = phy_start_aneg(phy_dev); -+ if (unlikely(_errno < 0)) -+ netdev_err(net_dev, "phy_start_aneg() = %d\n", -+ _errno); -+ } -+ } -+ -+ get_pause_cfg(mac_dev, &rx_pause, &tx_pause); -+ _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause); -+ if (unlikely(_errno < 0)) -+ netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno); -+ -+ return _errno; -+} -+ -+#ifdef CONFIG_PM -+static void dpa_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ -+ wol->supported = 0; -+ wol->wolopts = 0; -+ -+ if (!priv->wol || !device_can_wakeup(net_dev->dev.parent)) -+ return; -+ -+ if (priv->wol & DPAA_WOL_MAGIC) { -+ wol->supported = WAKE_MAGIC; -+ wol->wolopts = WAKE_MAGIC; -+ } -+} -+ -+static int dpa_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ -+ if (priv->mac_dev == NULL) { -+ netdev_info(net_dev, "This is a MAC-less interface\n"); -+ return -ENODEV; -+ } -+ -+ if (unlikely(priv->mac_dev->phy_dev == NULL)) { -+ netdev_dbg(net_dev, "phy device not initialized\n"); -+ return -ENODEV; -+ } -+ -+ if (!device_can_wakeup(net_dev->dev.parent) || -+ (wol->wolopts & ~WAKE_MAGIC)) -+ return -EOPNOTSUPP; -+ -+ priv->wol = 0; -+ -+ if (wol->wolopts & WAKE_MAGIC) { -+ priv->wol = DPAA_WOL_MAGIC; -+ device_set_wakeup_enable(net_dev->dev.parent, 1); -+ } else { -+ device_set_wakeup_enable(net_dev->dev.parent, 0); -+ } -+ -+ return 0; -+} -+#endif -+ -+static int dpa_get_eee(struct net_device *net_dev, struct ethtool_eee *et_eee) -+{ -+ struct dpa_priv_s *priv; -+ -+ priv = netdev_priv(net_dev); -+ if (priv->mac_dev == NULL) { -+ netdev_info(net_dev, "This is a MAC-less interface\n"); -+ return -ENODEV; -+ } -+ -+ if (unlikely(priv->mac_dev->phy_dev == NULL)) { -+ netdev_err(net_dev, "phy device not initialized\n"); -+ return -ENODEV; -+ } -+ -+ return phy_ethtool_get_eee(priv->mac_dev->phy_dev, et_eee); -+} -+ -+static int dpa_set_eee(struct net_device *net_dev, struct ethtool_eee *et_eee) -+{ -+ struct dpa_priv_s *priv; -+ -+ priv = netdev_priv(net_dev); -+ if (priv->mac_dev == NULL) { -+ netdev_info(net_dev, "This is a MAC-less interface\n"); -+ return -ENODEV; -+ } -+ -+ if (unlikely(priv->mac_dev->phy_dev == NULL)) { -+ netdev_err(net_dev, "phy device not initialized\n"); -+ return -ENODEV; -+ } -+ -+ return phy_ethtool_set_eee(priv->mac_dev->phy_dev, et_eee); -+} -+ -+static int dpa_get_sset_count(struct net_device *net_dev, int type) -+{ -+ unsigned int total_stats, num_stats; -+ -+ num_stats = num_online_cpus() + 1; -+ total_stats = num_stats * DPA_STATS_PERCPU_LEN + DPA_STATS_GLOBAL_LEN; -+ -+ switch (type) { -+ case ETH_SS_STATS: -+ return total_stats; -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static void copy_stats(struct dpa_percpu_priv_s *percpu_priv, int num_cpus, -+ int crr_cpu, u64 bp_count, u64 *data) -+{ -+ int num_stat_values = num_cpus + 1; -+ int crr_stat = 0; -+ -+ /* update current CPU's stats and also add them to the total values */ -+ data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->in_interrupt; -+ data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->in_interrupt; -+ -+ data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_packets; -+ data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_packets; -+ -+ data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_packets; -+ data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_packets; -+ -+ data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_returned; -+ data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_returned; -+ -+ data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_confirm; -+ data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_confirm; -+ -+ data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_frag_skbuffs; -+ data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_frag_skbuffs; -+ -+ data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->rx_sg; -+ data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->rx_sg; -+ -+ data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_errors; -+ data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_errors; -+ -+ data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_errors; -+ data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_errors; -+ -+ data[crr_stat * num_stat_values + crr_cpu] = bp_count; -+ data[crr_stat++ * num_stat_values + num_cpus] += bp_count; -+} -+ -+static void dpa_get_ethtool_stats(struct net_device *net_dev, -+ struct ethtool_stats *stats, u64 *data) -+{ -+ u64 bp_count, cg_time, cg_num, cg_status; -+ struct dpa_percpu_priv_s *percpu_priv; -+ struct qm_mcr_querycgr query_cgr; -+ struct dpa_rx_errors rx_errors; -+ struct dpa_ern_cnt ern_cnt; -+ struct dpa_priv_s *priv; -+ unsigned int num_cpus, offset; -+ struct dpa_bp *dpa_bp; -+ int total_stats, i; -+ -+ total_stats = dpa_get_sset_count(net_dev, ETH_SS_STATS); -+ priv = netdev_priv(net_dev); -+ dpa_bp = priv->dpa_bp; -+ num_cpus = num_online_cpus(); -+ bp_count = 0; -+ -+ memset(&rx_errors, 0, sizeof(struct dpa_rx_errors)); -+ memset(&ern_cnt, 0, sizeof(struct dpa_ern_cnt)); -+ memset(data, 0, total_stats * sizeof(u64)); -+ -+ for_each_online_cpu(i) { -+ percpu_priv = per_cpu_ptr(priv->percpu_priv, i); -+ -+ if (dpa_bp->percpu_count) -+ bp_count = *(per_cpu_ptr(dpa_bp->percpu_count, i)); -+ -+ rx_errors.dme += percpu_priv->rx_errors.dme; -+ rx_errors.fpe += percpu_priv->rx_errors.fpe; -+ rx_errors.fse += percpu_priv->rx_errors.fse; -+ rx_errors.phe += percpu_priv->rx_errors.phe; -+ rx_errors.cse += percpu_priv->rx_errors.cse; -+ -+ ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop; -+ ern_cnt.wred += percpu_priv->ern_cnt.wred; -+ ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond; -+ ern_cnt.early_window += percpu_priv->ern_cnt.early_window; -+ ern_cnt.late_window += percpu_priv->ern_cnt.late_window; -+ ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop; -+ ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired; -+ ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero; -+ -+ copy_stats(percpu_priv, num_cpus, i, bp_count, data); -+ } -+ -+ offset = (num_cpus + 1) * DPA_STATS_PERCPU_LEN; -+ memcpy(data + offset, &rx_errors, sizeof(struct dpa_rx_errors)); -+ -+ offset += sizeof(struct dpa_rx_errors) / sizeof(u64); -+ memcpy(data + offset, &ern_cnt, sizeof(struct dpa_ern_cnt)); -+ -+ /* gather congestion related counters */ -+ cg_num = 0; -+ cg_status = 0; -+ cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies); -+ if (qman_query_cgr(&priv->cgr_data.cgr, &query_cgr) == 0) { -+ cg_num = priv->cgr_data.cgr_congested_count; -+ cg_status = query_cgr.cgr.cs; -+ -+ /* reset congestion stats (like QMan API does */ -+ priv->cgr_data.congested_jiffies = 0; -+ priv->cgr_data.cgr_congested_count = 0; -+ } -+ -+ offset += sizeof(struct dpa_ern_cnt) / sizeof(u64); -+ data[offset++] = cg_time; -+ data[offset++] = cg_num; -+ data[offset++] = cg_status; -+} -+ -+static void dpa_get_strings(struct net_device *net_dev, u32 stringset, u8 *data) -+{ -+ unsigned int i, j, num_cpus, size; -+ char stat_string_cpu[ETH_GSTRING_LEN]; -+ u8 *strings; -+ -+ strings = data; -+ num_cpus = num_online_cpus(); -+ size = DPA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN; -+ -+ for (i = 0; i < DPA_STATS_PERCPU_LEN; i++) { -+ for (j = 0; j < num_cpus; j++) { -+ snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", dpa_stats_percpu[i], j); -+ memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN); -+ strings += ETH_GSTRING_LEN; -+ } -+ snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", dpa_stats_percpu[i]); -+ memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN); -+ strings += ETH_GSTRING_LEN; -+ } -+ memcpy(strings, dpa_stats_global, size); -+} -+ -+const struct ethtool_ops dpa_ethtool_ops = { -+ .get_settings = dpa_get_settings, -+ .set_settings = dpa_set_settings, -+ .get_drvinfo = dpa_get_drvinfo, -+ .get_msglevel = dpa_get_msglevel, -+ .set_msglevel = dpa_set_msglevel, -+ .nway_reset = dpa_nway_reset, -+ .get_pauseparam = dpa_get_pauseparam, -+ .set_pauseparam = dpa_set_pauseparam, -+ .self_test = NULL, /* TODO invoke the cold-boot unit-test? */ -+ .get_link = ethtool_op_get_link, -+ .get_eee = dpa_get_eee, -+ .set_eee = dpa_set_eee, -+ .get_sset_count = dpa_get_sset_count, -+ .get_ethtool_stats = dpa_get_ethtool_stats, -+ .get_strings = dpa_get_strings, -+#ifdef CONFIG_PM -+ .get_wol = dpa_get_wol, -+ .set_wol = dpa_set_wol, -+#endif -+}; ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c -@@ -0,0 +1,290 @@ -+/* -+ * DPAA Ethernet Driver -- PTP 1588 clock using the dTSEC -+ * -+ * Author: Yangbo Lu -+ * -+ * Copyright 2014 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "dpaa_eth.h" -+#include "mac.h" -+ -+struct ptp_clock *clock; -+ -+static struct mac_device *mac_dev; -+static u32 freqCompensation; -+ -+/* Bit definitions for the TMR_CTRL register */ -+#define ALM1P (1<<31) /* Alarm1 output polarity */ -+#define ALM2P (1<<30) /* Alarm2 output polarity */ -+#define FS (1<<28) /* FIPER start indication */ -+#define PP1L (1<<27) /* Fiper1 pulse loopback mode enabled. */ -+#define PP2L (1<<26) /* Fiper2 pulse loopback mode enabled. */ -+#define TCLK_PERIOD_SHIFT (16) /* 1588 timer reference clock period. */ -+#define TCLK_PERIOD_MASK (0x3ff) -+#define RTPE (1<<15) /* Record Tx Timestamp to PAL Enable. */ -+#define FRD (1<<14) /* FIPER Realignment Disable */ -+#define ESFDP (1<<11) /* External Tx/Rx SFD Polarity. */ -+#define ESFDE (1<<10) /* External Tx/Rx SFD Enable. */ -+#define ETEP2 (1<<9) /* External trigger 2 edge polarity */ -+#define ETEP1 (1<<8) /* External trigger 1 edge polarity */ -+#define COPH (1<<7) /* Generated clock output phase. */ -+#define CIPH (1<<6) /* External oscillator input clock phase */ -+#define TMSR (1<<5) /* Timer soft reset. */ -+#define BYP (1<<3) /* Bypass drift compensated clock */ -+#define TE (1<<2) /* 1588 timer enable. */ -+#define CKSEL_SHIFT (0) /* 1588 Timer reference clock source */ -+#define CKSEL_MASK (0x3) -+ -+/* Bit definitions for the TMR_TEVENT register */ -+#define ETS2 (1<<25) /* External trigger 2 timestamp sampled */ -+#define ETS1 (1<<24) /* External trigger 1 timestamp sampled */ -+#define ALM2 (1<<17) /* Current time = alarm time register 2 */ -+#define ALM1 (1<<16) /* Current time = alarm time register 1 */ -+#define PP1 (1<<7) /* periodic pulse generated on FIPER1 */ -+#define PP2 (1<<6) /* periodic pulse generated on FIPER2 */ -+#define PP3 (1<<5) /* periodic pulse generated on FIPER3 */ -+ -+/* Bit definitions for the TMR_TEMASK register */ -+#define ETS2EN (1<<25) /* External trigger 2 timestamp enable */ -+#define ETS1EN (1<<24) /* External trigger 1 timestamp enable */ -+#define ALM2EN (1<<17) /* Timer ALM2 event enable */ -+#define ALM1EN (1<<16) /* Timer ALM1 event enable */ -+#define PP1EN (1<<7) /* Periodic pulse event 1 enable */ -+#define PP2EN (1<<6) /* Periodic pulse event 2 enable */ -+ -+/* Bit definitions for the TMR_PEVENT register */ -+#define TXP2 (1<<9) /* PTP transmitted timestamp im TXTS2 */ -+#define TXP1 (1<<8) /* PTP transmitted timestamp in TXTS1 */ -+#define RXP (1<<0) /* PTP frame has been received */ -+ -+/* Bit definitions for the TMR_PEMASK register */ -+#define TXP2EN (1<<9) /* Transmit PTP packet event 2 enable */ -+#define TXP1EN (1<<8) /* Transmit PTP packet event 1 enable */ -+#define RXPEN (1<<0) /* Receive PTP packet event enable */ -+ -+/* Bit definitions for the TMR_STAT register */ -+#define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */ -+#define STAT_VEC_MASK (0x3f) -+ -+/* Bit definitions for the TMR_PRSC register */ -+#define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */ -+#define PRSC_OCK_MASK (0xffff) -+ -+ -+#define N_EXT_TS 2 -+ -+static void set_alarm(void) -+{ -+ u64 ns; -+ -+ if (mac_dev->fm_rtc_get_cnt) -+ mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns); -+ ns += 1500000000ULL; -+ ns = div_u64(ns, 1000000000UL) * 1000000000ULL; -+ ns -= DPA_PTP_NOMINAL_FREQ_PERIOD_NS; -+ if (mac_dev->fm_rtc_set_alarm) -+ mac_dev->fm_rtc_set_alarm(mac_dev->fm_dev, 0, ns); -+} -+ -+static void set_fipers(void) -+{ -+ u64 fiper; -+ -+ if (mac_dev->fm_rtc_disable) -+ mac_dev->fm_rtc_disable(mac_dev->fm_dev); -+ -+ set_alarm(); -+ fiper = 1000000000ULL - DPA_PTP_NOMINAL_FREQ_PERIOD_NS; -+ if (mac_dev->fm_rtc_set_fiper) -+ mac_dev->fm_rtc_set_fiper(mac_dev->fm_dev, 0, fiper); -+ -+ if (mac_dev->fm_rtc_enable) -+ mac_dev->fm_rtc_enable(mac_dev->fm_dev); -+} -+ -+/* PTP clock operations */ -+ -+static int ptp_dpa_adjfreq(struct ptp_clock_info *ptp, s32 ppb) -+{ -+ u64 adj; -+ u32 diff, tmr_add; -+ int neg_adj = 0; -+ -+ if (ppb < 0) { -+ neg_adj = 1; -+ ppb = -ppb; -+ } -+ -+ tmr_add = freqCompensation; -+ adj = tmr_add; -+ adj *= ppb; -+ diff = div_u64(adj, 1000000000ULL); -+ -+ tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff; -+ -+ if (mac_dev->fm_rtc_set_drift) -+ mac_dev->fm_rtc_set_drift(mac_dev->fm_dev, tmr_add); -+ -+ return 0; -+} -+ -+static int ptp_dpa_adjtime(struct ptp_clock_info *ptp, s64 delta) -+{ -+ s64 now; -+ -+ if (mac_dev->fm_rtc_get_cnt) -+ mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &now); -+ -+ now += delta; -+ -+ if (mac_dev->fm_rtc_set_cnt) -+ mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, now); -+ set_fipers(); -+ -+ return 0; -+} -+ -+static int ptp_dpa_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) -+{ -+ u64 ns; -+ u32 remainder; -+ -+ if (mac_dev->fm_rtc_get_cnt) -+ mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns); -+ -+ ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder); -+ ts->tv_nsec = remainder; -+ return 0; -+} -+ -+static int ptp_dpa_settime(struct ptp_clock_info *ptp, -+ const struct timespec64 *ts) -+{ -+ u64 ns; -+ -+ ns = ts->tv_sec * 1000000000ULL; -+ ns += ts->tv_nsec; -+ -+ if (mac_dev->fm_rtc_set_cnt) -+ mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, ns); -+ set_fipers(); -+ return 0; -+} -+ -+static int ptp_dpa_enable(struct ptp_clock_info *ptp, -+ struct ptp_clock_request *rq, int on) -+{ -+ u32 bit; -+ -+ switch (rq->type) { -+ case PTP_CLK_REQ_EXTTS: -+ switch (rq->extts.index) { -+ case 0: -+ bit = ETS1EN; -+ break; -+ case 1: -+ bit = ETS2EN; -+ break; -+ default: -+ return -EINVAL; -+ } -+ if (on) { -+ if (mac_dev->fm_rtc_enable_interrupt) -+ mac_dev->fm_rtc_enable_interrupt( -+ mac_dev->fm_dev, bit); -+ } else { -+ if (mac_dev->fm_rtc_disable_interrupt) -+ mac_dev->fm_rtc_disable_interrupt( -+ mac_dev->fm_dev, bit); -+ } -+ return 0; -+ -+ case PTP_CLK_REQ_PPS: -+ if (on) { -+ if (mac_dev->fm_rtc_enable_interrupt) -+ mac_dev->fm_rtc_enable_interrupt( -+ mac_dev->fm_dev, PP1EN); -+ } else { -+ if (mac_dev->fm_rtc_disable_interrupt) -+ mac_dev->fm_rtc_disable_interrupt( -+ mac_dev->fm_dev, PP1EN); -+ } -+ return 0; -+ -+ default: -+ break; -+ } -+ -+ return -EOPNOTSUPP; -+} -+ -+static struct ptp_clock_info ptp_dpa_caps = { -+ .owner = THIS_MODULE, -+ .name = "dpaa clock", -+ .max_adj = 512000, -+ .n_alarm = 0, -+ .n_ext_ts = N_EXT_TS, -+ .n_per_out = 0, -+ .pps = 1, -+ .adjfreq = ptp_dpa_adjfreq, -+ .adjtime = ptp_dpa_adjtime, -+ .gettime64 = ptp_dpa_gettime, -+ .settime64 = ptp_dpa_settime, -+ .enable = ptp_dpa_enable, -+}; -+ -+static int __init __cold dpa_ptp_load(void) -+{ -+ struct device *ptp_dev; -+ struct timespec64 now; -+ int dpa_phc_index; -+ int err; -+ -+ if (!(ptp_priv.of_dev && ptp_priv.mac_dev)) -+ return -ENODEV; -+ -+ ptp_dev = &ptp_priv.of_dev->dev; -+ mac_dev = ptp_priv.mac_dev; -+ -+ if (mac_dev->fm_rtc_get_drift) -+ mac_dev->fm_rtc_get_drift(mac_dev->fm_dev, &freqCompensation); -+ -+ getnstimeofday64(&now); -+ ptp_dpa_settime(&ptp_dpa_caps, &now); -+ -+ clock = ptp_clock_register(&ptp_dpa_caps, ptp_dev); -+ if (IS_ERR(clock)) { -+ err = PTR_ERR(clock); -+ return err; -+ } -+ dpa_phc_index = ptp_clock_index(clock); -+ return 0; -+} -+module_init(dpa_ptp_load); -+ -+static void __exit __cold dpa_ptp_unload(void) -+{ -+ if (mac_dev->fm_rtc_disable_interrupt) -+ mac_dev->fm_rtc_disable_interrupt(mac_dev->fm_dev, 0xffffffff); -+ ptp_clock_unregister(clock); -+} -+module_exit(dpa_ptp_unload); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c -@@ -0,0 +1,909 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifdef CONFIG_FSL_DPAA_ETH_DEBUG -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+#else -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": " fmt -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dpaa_eth.h" -+#include "mac.h" -+#include "lnxwrp_fsl_fman.h" -+ -+#include "error_ext.h" /* GET_ERROR_TYPE, E_OK */ -+ -+#include "fsl_fman_dtsec.h" -+#include "fsl_fman_tgec.h" -+#include "fsl_fman_memac.h" -+#include "../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h" -+ -+#define MAC_DESCRIPTION "FSL FMan MAC API based driver" -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+ -+MODULE_AUTHOR("Emil Medve "); -+ -+MODULE_DESCRIPTION(MAC_DESCRIPTION); -+ -+struct mac_priv_s { -+ struct fm_mac_dev *fm_mac; -+}; -+ -+const char *mac_driver_description __initconst = MAC_DESCRIPTION; -+const size_t mac_sizeof_priv[] = { -+ [DTSEC] = sizeof(struct mac_priv_s), -+ [XGMAC] = sizeof(struct mac_priv_s), -+ [MEMAC] = sizeof(struct mac_priv_s) -+}; -+ -+static const enet_mode_t _100[] = { -+ [PHY_INTERFACE_MODE_MII] = e_ENET_MODE_MII_100, -+ [PHY_INTERFACE_MODE_RMII] = e_ENET_MODE_RMII_100 -+}; -+ -+static const enet_mode_t _1000[] = { -+ [PHY_INTERFACE_MODE_GMII] = e_ENET_MODE_GMII_1000, -+ [PHY_INTERFACE_MODE_SGMII] = e_ENET_MODE_SGMII_1000, -+ [PHY_INTERFACE_MODE_QSGMII] = e_ENET_MODE_QSGMII_1000, -+ [PHY_INTERFACE_MODE_TBI] = e_ENET_MODE_TBI_1000, -+ [PHY_INTERFACE_MODE_RGMII] = e_ENET_MODE_RGMII_1000, -+ [PHY_INTERFACE_MODE_RGMII_ID] = e_ENET_MODE_RGMII_1000, -+ [PHY_INTERFACE_MODE_RGMII_RXID] = e_ENET_MODE_RGMII_1000, -+ [PHY_INTERFACE_MODE_RGMII_TXID] = e_ENET_MODE_RGMII_1000, -+ [PHY_INTERFACE_MODE_RTBI] = e_ENET_MODE_RTBI_1000 -+}; -+ -+static enet_mode_t __cold __attribute__((nonnull)) -+macdev2enetinterface(const struct mac_device *mac_dev) -+{ -+ switch (mac_dev->max_speed) { -+ case SPEED_100: -+ return _100[mac_dev->phy_if]; -+ case SPEED_1000: -+ return _1000[mac_dev->phy_if]; -+ case SPEED_2500: -+ return e_ENET_MODE_SGMII_2500; -+ case SPEED_10000: -+ return e_ENET_MODE_XGMII_10000; -+ default: -+ return e_ENET_MODE_MII_100; -+ } -+} -+ -+static void mac_exception(handle_t _mac_dev, e_FmMacExceptions exception) -+{ -+ struct mac_device *mac_dev; -+ -+ mac_dev = (struct mac_device *)_mac_dev; -+ -+ if (e_FM_MAC_EX_10G_RX_FIFO_OVFL == exception) { -+ /* don't flag RX FIFO after the first */ -+ fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev), -+ e_FM_MAC_EX_10G_RX_FIFO_OVFL, false); -+ dev_err(mac_dev->dev, "10G MAC got RX FIFO Error = %x\n", -+ exception); -+ } -+ -+ dev_dbg(mac_dev->dev, "%s:%s() -> %d\n", KBUILD_BASENAME".c", __func__, -+ exception); -+} -+ -+static int __cold init(struct mac_device *mac_dev) -+{ -+ int _errno; -+ struct mac_priv_s *priv; -+ t_FmMacParams param; -+ uint32_t version; -+ -+ priv = macdev_priv(mac_dev); -+ -+ param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap( -+ mac_dev->dev, mac_dev->res->start, 0x2000); -+ param.enetMode = macdev2enetinterface(mac_dev); -+ memcpy(¶m.addr, mac_dev->addr, min(sizeof(param.addr), -+ sizeof(mac_dev->addr))); -+ param.macId = mac_dev->cell_index; -+ param.h_Fm = (handle_t)mac_dev->fm; -+ param.mdioIrq = NO_IRQ; -+ param.f_Exception = mac_exception; -+ param.f_Event = mac_exception; -+ param.h_App = mac_dev; -+ -+ priv->fm_mac = fm_mac_config(¶m); -+ if (unlikely(priv->fm_mac == NULL)) { -+ _errno = -EINVAL; -+ goto _return; -+ } -+ -+ fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac, -+ (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ? -+ param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS); -+ -+ _errno = fm_mac_config_max_frame_length(priv->fm_mac, -+ fm_get_max_frm()); -+ if (unlikely(_errno < 0)) -+ goto _return_fm_mac_free; -+ -+ if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) { -+ /* 10G always works with pad and CRC */ -+ _errno = fm_mac_config_pad_and_crc(priv->fm_mac, true); -+ if (unlikely(_errno < 0)) -+ goto _return_fm_mac_free; -+ -+ _errno = fm_mac_config_half_duplex(priv->fm_mac, -+ mac_dev->half_duplex); -+ if (unlikely(_errno < 0)) -+ goto _return_fm_mac_free; -+ } else { -+ _errno = fm_mac_config_reset_on_init(priv->fm_mac, true); -+ if (unlikely(_errno < 0)) -+ goto _return_fm_mac_free; -+ } -+ -+ _errno = fm_mac_init(priv->fm_mac); -+ if (unlikely(_errno < 0)) -+ goto _return_fm_mac_free; -+ -+#ifndef CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN -+ /* For 1G MAC, disable by default the MIB counters overflow interrupt */ -+ if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) { -+ _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev), -+ e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL, FALSE); -+ if (unlikely(_errno < 0)) -+ goto _return_fm_mac_free; -+ } -+#endif /* !CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN */ -+ -+ /* For 10G MAC, disable Tx ECC exception */ -+ if (macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) { -+ _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev), -+ e_FM_MAC_EX_10G_1TX_ECC_ER, FALSE); -+ if (unlikely(_errno < 0)) -+ goto _return_fm_mac_free; -+ } -+ -+ _errno = fm_mac_get_version(priv->fm_mac, &version); -+ if (unlikely(_errno < 0)) -+ goto _return_fm_mac_free; -+ -+ dev_info(mac_dev->dev, "FMan %s version: 0x%08x\n", -+ ((macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ? -+ "dTSEC" : "XGEC"), version); -+ -+ goto _return; -+ -+ -+_return_fm_mac_free: -+ fm_mac_free(mac_dev->get_mac_handle(mac_dev)); -+ -+_return: -+ return _errno; -+} -+ -+static int __cold memac_init(struct mac_device *mac_dev) -+{ -+ int _errno; -+ struct mac_priv_s *priv; -+ t_FmMacParams param; -+ -+ priv = macdev_priv(mac_dev); -+ -+ param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap( -+ mac_dev->dev, mac_dev->res->start, 0x2000); -+ param.enetMode = macdev2enetinterface(mac_dev); -+ memcpy(¶m.addr, mac_dev->addr, sizeof(mac_dev->addr)); -+ param.macId = mac_dev->cell_index; -+ param.h_Fm = (handle_t)mac_dev->fm; -+ param.mdioIrq = NO_IRQ; -+ param.f_Exception = mac_exception; -+ param.f_Event = mac_exception; -+ param.h_App = mac_dev; -+ -+ priv->fm_mac = fm_mac_config(¶m); -+ if (unlikely(priv->fm_mac == NULL)) { -+ _errno = -EINVAL; -+ goto _return; -+ } -+ -+ fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac, -+ (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ? -+ param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS); -+ -+ _errno = fm_mac_config_max_frame_length(priv->fm_mac, fm_get_max_frm()); -+ if (unlikely(_errno < 0)) -+ goto _return_fm_mac_free; -+ -+ _errno = fm_mac_config_reset_on_init(priv->fm_mac, true); -+ if (unlikely(_errno < 0)) -+ goto _return_fm_mac_free; -+ -+ _errno = fm_mac_init(priv->fm_mac); -+ if (unlikely(_errno < 0)) -+ goto _return_fm_mac_free; -+ -+ dev_info(mac_dev->dev, "FMan MEMAC\n"); -+ -+ goto _return; -+ -+_return_fm_mac_free: -+ fm_mac_free(priv->fm_mac); -+ -+_return: -+ return _errno; -+} -+ -+static int __cold start(struct mac_device *mac_dev) -+{ -+ int _errno; -+ struct phy_device *phy_dev = mac_dev->phy_dev; -+ -+ _errno = fm_mac_enable(mac_dev->get_mac_handle(mac_dev)); -+ -+ if (!_errno && phy_dev) -+ phy_start(phy_dev); -+ -+ return _errno; -+} -+ -+static int __cold stop(struct mac_device *mac_dev) -+{ -+ if (mac_dev->phy_dev) -+ phy_stop(mac_dev->phy_dev); -+ -+ return fm_mac_disable(mac_dev->get_mac_handle(mac_dev)); -+} -+ -+static int __cold set_multi(struct net_device *net_dev, -+ struct mac_device *mac_dev) -+{ -+ struct mac_priv_s *mac_priv; -+ struct mac_address *old_addr, *tmp; -+ struct netdev_hw_addr *ha; -+ int _errno; -+ -+ mac_priv = macdev_priv(mac_dev); -+ -+ /* Clear previous address list */ -+ list_for_each_entry_safe(old_addr, tmp, &mac_dev->mc_addr_list, list) { -+ _errno = fm_mac_remove_hash_mac_addr(mac_priv->fm_mac, -+ (t_EnetAddr *)old_addr->addr); -+ if (_errno < 0) -+ return _errno; -+ -+ list_del(&old_addr->list); -+ kfree(old_addr); -+ } -+ -+ /* Add all the addresses from the new list */ -+ netdev_for_each_mc_addr(ha, net_dev) { -+ _errno = fm_mac_add_hash_mac_addr(mac_priv->fm_mac, -+ (t_EnetAddr *)ha->addr); -+ if (_errno < 0) -+ return _errno; -+ -+ tmp = kmalloc(sizeof(struct mac_address), GFP_ATOMIC); -+ if (!tmp) { -+ dev_err(mac_dev->dev, "Out of memory\n"); -+ return -ENOMEM; -+ } -+ memcpy(tmp->addr, ha->addr, ETH_ALEN); -+ list_add(&tmp->list, &mac_dev->mc_addr_list); -+ } -+ return 0; -+} -+ -+/* Avoid redundant calls to FMD, if the MAC driver already contains the desired -+ * active PAUSE settings. Otherwise, the new active settings should be reflected -+ * in FMan. -+ */ -+int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx) -+{ -+ struct fm_mac_dev *fm_mac_dev = mac_dev->get_mac_handle(mac_dev); -+ int _errno = 0; -+ -+ if (unlikely(rx != mac_dev->rx_pause_active)) { -+ _errno = fm_mac_set_rx_pause_frames(fm_mac_dev, rx); -+ if (likely(_errno == 0)) -+ mac_dev->rx_pause_active = rx; -+ } -+ -+ if (unlikely(tx != mac_dev->tx_pause_active)) { -+ _errno = fm_mac_set_tx_pause_frames(fm_mac_dev, tx); -+ if (likely(_errno == 0)) -+ mac_dev->tx_pause_active = tx; -+ } -+ -+ return _errno; -+} -+EXPORT_SYMBOL(set_mac_active_pause); -+ -+/* Determine the MAC RX/TX PAUSE frames settings based on PHY -+ * autonegotiation or values set by eththool. -+ */ -+void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause) -+{ -+ struct phy_device *phy_dev = mac_dev->phy_dev; -+ u16 lcl_adv, rmt_adv; -+ u8 flowctrl; -+ -+ *rx_pause = *tx_pause = false; -+ -+ if (!phy_dev->duplex) -+ return; -+ -+ /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings -+ * are those set by ethtool. -+ */ -+ if (!mac_dev->autoneg_pause) { -+ *rx_pause = mac_dev->rx_pause_req; -+ *tx_pause = mac_dev->tx_pause_req; -+ return; -+ } -+ -+ /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE -+ * settings depend on the result of the link negotiation. -+ */ -+ -+ /* get local capabilities */ -+ lcl_adv = 0; -+ if (phy_dev->advertising & ADVERTISED_Pause) -+ lcl_adv |= ADVERTISE_PAUSE_CAP; -+ if (phy_dev->advertising & ADVERTISED_Asym_Pause) -+ lcl_adv |= ADVERTISE_PAUSE_ASYM; -+ -+ /* get link partner capabilities */ -+ rmt_adv = 0; -+ if (phy_dev->pause) -+ rmt_adv |= LPA_PAUSE_CAP; -+ if (phy_dev->asym_pause) -+ rmt_adv |= LPA_PAUSE_ASYM; -+ -+ /* Calculate TX/RX settings based on local and peer advertised -+ * symmetric/asymmetric PAUSE capabilities. -+ */ -+ flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); -+ if (flowctrl & FLOW_CTRL_RX) -+ *rx_pause = true; -+ if (flowctrl & FLOW_CTRL_TX) -+ *tx_pause = true; -+} -+EXPORT_SYMBOL(get_pause_cfg); -+ -+static void adjust_link_void(struct net_device *net_dev) -+{ -+} -+ -+static void adjust_link(struct net_device *net_dev) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct mac_device *mac_dev = priv->mac_dev; -+ struct phy_device *phy_dev = mac_dev->phy_dev; -+ struct fm_mac_dev *fm_mac_dev; -+ bool rx_pause, tx_pause; -+ int _errno; -+ -+ fm_mac_dev = mac_dev->get_mac_handle(mac_dev); -+ fm_mac_adjust_link(fm_mac_dev, phy_dev->link, phy_dev->speed, -+ phy_dev->duplex); -+ -+ get_pause_cfg(mac_dev, &rx_pause, &tx_pause); -+ _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause); -+ if (unlikely(_errno < 0)) -+ netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno); -+} -+ -+/* Initializes driver's PHY state, and attaches to the PHY. -+ * Returns 0 on success. -+ */ -+static int dtsec_init_phy(struct net_device *net_dev, -+ struct mac_device *mac_dev) -+{ -+ struct phy_device *phy_dev; -+ -+ if (of_phy_is_fixed_link(mac_dev->phy_node)) -+ phy_dev = of_phy_attach(net_dev, mac_dev->phy_node, -+ 0, mac_dev->phy_if); -+ else -+ phy_dev = of_phy_connect(net_dev, mac_dev->phy_node, -+ &adjust_link, 0, mac_dev->phy_if); -+ if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) { -+ netdev_err(net_dev, "Could not connect to PHY %s\n", -+ mac_dev->phy_node ? -+ mac_dev->phy_node->full_name : -+ mac_dev->fixed_bus_id); -+ return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev); -+ } -+ -+ /* Remove any features not supported by the controller */ -+ phy_dev->supported &= mac_dev->if_support; -+ /* Enable the symmetric and asymmetric PAUSE frame advertisements, -+ * as most of the PHY drivers do not enable them by default. -+ */ -+ phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause); -+ phy_dev->advertising = phy_dev->supported; -+ -+ mac_dev->phy_dev = phy_dev; -+ -+ return 0; -+} -+ -+static int xgmac_init_phy(struct net_device *net_dev, -+ struct mac_device *mac_dev) -+{ -+ struct phy_device *phy_dev; -+ -+ if (of_phy_is_fixed_link(mac_dev->phy_node)) -+ phy_dev = of_phy_attach(net_dev, mac_dev->phy_node, -+ 0, mac_dev->phy_if); -+ else -+ phy_dev = of_phy_connect(net_dev, mac_dev->phy_node, -+ &adjust_link_void, 0, mac_dev->phy_if); -+ if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) { -+ netdev_err(net_dev, "Could not attach to PHY %s\n", -+ mac_dev->phy_node ? -+ mac_dev->phy_node->full_name : -+ mac_dev->fixed_bus_id); -+ return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev); -+ } -+ -+ phy_dev->supported &= mac_dev->if_support; -+ /* Enable the symmetric and asymmetric PAUSE frame advertisements, -+ * as most of the PHY drivers do not enable them by default. -+ */ -+ phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause); -+ phy_dev->advertising = phy_dev->supported; -+ -+ mac_dev->phy_dev = phy_dev; -+ -+ return 0; -+} -+ -+static int memac_init_phy(struct net_device *net_dev, -+ struct mac_device *mac_dev) -+{ -+ struct phy_device *phy_dev; -+ -+ if (of_phy_is_fixed_link(mac_dev->phy_node)) { -+ phy_dev = of_phy_attach(net_dev, mac_dev->phy_node, -+ 0, mac_dev->phy_if); -+ } else if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) || -+ (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500)) { -+ phy_dev = of_phy_connect(net_dev, mac_dev->phy_node, -+ &adjust_link_void, 0, -+ mac_dev->phy_if); -+ } else { -+ phy_dev = of_phy_connect(net_dev, mac_dev->phy_node, -+ &adjust_link, 0, mac_dev->phy_if); -+ } -+ -+ if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) { -+ netdev_err(net_dev, "Could not connect to PHY %s\n", -+ mac_dev->phy_node ? -+ mac_dev->phy_node->full_name : -+ mac_dev->fixed_bus_id); -+ return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev); -+ } -+ -+ /* Remove any features not supported by the controller */ -+ phy_dev->supported &= mac_dev->if_support; -+ /* Enable the symmetric and asymmetric PAUSE frame advertisements, -+ * as most of the PHY drivers do not enable them by default. -+ */ -+ phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause); -+ phy_dev->advertising = phy_dev->supported; -+ -+ mac_dev->phy_dev = phy_dev; -+ -+ return 0; -+} -+ -+static int __cold uninit(struct fm_mac_dev *fm_mac_dev) -+{ -+ int _errno, __errno; -+ -+ _errno = fm_mac_disable(fm_mac_dev); -+ __errno = fm_mac_free(fm_mac_dev); -+ -+ if (unlikely(__errno < 0)) -+ _errno = __errno; -+ -+ return _errno; -+} -+ -+static struct fm_mac_dev *get_mac_handle(struct mac_device *mac_dev) -+{ -+ const struct mac_priv_s *priv; -+ priv = macdev_priv(mac_dev); -+ return priv->fm_mac; -+} -+ -+static int dtsec_dump_regs(struct mac_device *h_mac, char *buf, int nn) -+{ -+ struct dtsec_regs *p_mm = (struct dtsec_regs *) h_mac->vaddr; -+ int i = 0, n = nn; -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ -+ FM_DMP_TITLE(buf, n, p_mm, "FM MAC - DTSEC-%d", h_mac->cell_index); -+ -+ FM_DMP_V32(buf, n, p_mm, tsec_id); -+ FM_DMP_V32(buf, n, p_mm, tsec_id2); -+ FM_DMP_V32(buf, n, p_mm, ievent); -+ FM_DMP_V32(buf, n, p_mm, imask); -+ FM_DMP_V32(buf, n, p_mm, ecntrl); -+ FM_DMP_V32(buf, n, p_mm, ptv); -+ FM_DMP_V32(buf, n, p_mm, tmr_ctrl); -+ FM_DMP_V32(buf, n, p_mm, tmr_pevent); -+ FM_DMP_V32(buf, n, p_mm, tmr_pemask); -+ FM_DMP_V32(buf, n, p_mm, tctrl); -+ FM_DMP_V32(buf, n, p_mm, rctrl); -+ FM_DMP_V32(buf, n, p_mm, maccfg1); -+ FM_DMP_V32(buf, n, p_mm, maccfg2); -+ FM_DMP_V32(buf, n, p_mm, ipgifg); -+ FM_DMP_V32(buf, n, p_mm, hafdup); -+ FM_DMP_V32(buf, n, p_mm, maxfrm); -+ -+ FM_DMP_V32(buf, n, p_mm, macstnaddr1); -+ FM_DMP_V32(buf, n, p_mm, macstnaddr2); -+ -+ for (i = 0; i < 7; ++i) { -+ FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match1); -+ FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match2); -+ } -+ -+ FM_DMP_V32(buf, n, p_mm, car1); -+ FM_DMP_V32(buf, n, p_mm, car2); -+ -+ return n; -+} -+ -+static int xgmac_dump_regs(struct mac_device *h_mac, char *buf, int nn) -+{ -+ struct tgec_regs *p_mm = (struct tgec_regs *) h_mac->vaddr; -+ int n = nn; -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_TITLE(buf, n, p_mm, "FM MAC - TGEC -%d", h_mac->cell_index); -+ -+ FM_DMP_V32(buf, n, p_mm, tgec_id); -+ FM_DMP_V32(buf, n, p_mm, command_config); -+ FM_DMP_V32(buf, n, p_mm, mac_addr_0); -+ FM_DMP_V32(buf, n, p_mm, mac_addr_1); -+ FM_DMP_V32(buf, n, p_mm, maxfrm); -+ FM_DMP_V32(buf, n, p_mm, pause_quant); -+ FM_DMP_V32(buf, n, p_mm, rx_fifo_sections); -+ FM_DMP_V32(buf, n, p_mm, tx_fifo_sections); -+ FM_DMP_V32(buf, n, p_mm, rx_fifo_almost_f_e); -+ FM_DMP_V32(buf, n, p_mm, tx_fifo_almost_f_e); -+ FM_DMP_V32(buf, n, p_mm, hashtable_ctrl); -+ FM_DMP_V32(buf, n, p_mm, mdio_cfg_status); -+ FM_DMP_V32(buf, n, p_mm, mdio_command); -+ FM_DMP_V32(buf, n, p_mm, mdio_data); -+ FM_DMP_V32(buf, n, p_mm, mdio_regaddr); -+ FM_DMP_V32(buf, n, p_mm, status); -+ FM_DMP_V32(buf, n, p_mm, tx_ipg_len); -+ FM_DMP_V32(buf, n, p_mm, mac_addr_2); -+ FM_DMP_V32(buf, n, p_mm, mac_addr_3); -+ FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_rd); -+ FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_wr); -+ FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_rd); -+ FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_wr); -+ FM_DMP_V32(buf, n, p_mm, imask); -+ FM_DMP_V32(buf, n, p_mm, ievent); -+ -+ return n; -+} -+ -+static int memac_dump_regs(struct mac_device *h_mac, char *buf, int nn) -+{ -+ struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr; -+ int i = 0, n = nn; -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d", h_mac->cell_index); -+ -+ FM_DMP_V32(buf, n, p_mm, command_config); -+ FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_l); -+ FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_u); -+ FM_DMP_V32(buf, n, p_mm, maxfrm); -+ FM_DMP_V32(buf, n, p_mm, hashtable_ctrl); -+ FM_DMP_V32(buf, n, p_mm, ievent); -+ FM_DMP_V32(buf, n, p_mm, tx_ipg_length); -+ FM_DMP_V32(buf, n, p_mm, imask); -+ -+ for (i = 0; i < 4; ++i) -+ FM_DMP_V32(buf, n, p_mm, pause_quanta[i]); -+ -+ for (i = 0; i < 4; ++i) -+ FM_DMP_V32(buf, n, p_mm, pause_thresh[i]); -+ -+ FM_DMP_V32(buf, n, p_mm, rx_pause_status); -+ -+ for (i = 0; i < MEMAC_NUM_OF_PADDRS; ++i) { -+ FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_l); -+ FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_u); -+ } -+ -+ FM_DMP_V32(buf, n, p_mm, lpwake_timer); -+ FM_DMP_V32(buf, n, p_mm, sleep_timer); -+ FM_DMP_V32(buf, n, p_mm, statn_config); -+ FM_DMP_V32(buf, n, p_mm, if_mode); -+ FM_DMP_V32(buf, n, p_mm, if_status); -+ FM_DMP_V32(buf, n, p_mm, hg_config); -+ FM_DMP_V32(buf, n, p_mm, hg_pause_quanta); -+ FM_DMP_V32(buf, n, p_mm, hg_pause_thresh); -+ FM_DMP_V32(buf, n, p_mm, hgrx_pause_status); -+ FM_DMP_V32(buf, n, p_mm, hg_fifos_status); -+ FM_DMP_V32(buf, n, p_mm, rhm); -+ FM_DMP_V32(buf, n, p_mm, thm); -+ -+ return n; -+} -+ -+static int memac_dump_regs_rx(struct mac_device *h_mac, char *buf, int nn) -+{ -+ struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr; -+ int n = nn; -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Rx stats", h_mac->cell_index); -+ -+ /* Rx Statistics Counter */ -+ FM_DMP_V32(buf, n, p_mm, reoct_l); -+ FM_DMP_V32(buf, n, p_mm, reoct_u); -+ FM_DMP_V32(buf, n, p_mm, roct_l); -+ FM_DMP_V32(buf, n, p_mm, roct_u); -+ FM_DMP_V32(buf, n, p_mm, raln_l); -+ FM_DMP_V32(buf, n, p_mm, raln_u); -+ FM_DMP_V32(buf, n, p_mm, rxpf_l); -+ FM_DMP_V32(buf, n, p_mm, rxpf_u); -+ FM_DMP_V32(buf, n, p_mm, rfrm_l); -+ FM_DMP_V32(buf, n, p_mm, rfrm_u); -+ FM_DMP_V32(buf, n, p_mm, rfcs_l); -+ FM_DMP_V32(buf, n, p_mm, rfcs_u); -+ FM_DMP_V32(buf, n, p_mm, rvlan_l); -+ FM_DMP_V32(buf, n, p_mm, rvlan_u); -+ FM_DMP_V32(buf, n, p_mm, rerr_l); -+ FM_DMP_V32(buf, n, p_mm, rerr_u); -+ FM_DMP_V32(buf, n, p_mm, ruca_l); -+ FM_DMP_V32(buf, n, p_mm, ruca_u); -+ FM_DMP_V32(buf, n, p_mm, rmca_l); -+ FM_DMP_V32(buf, n, p_mm, rmca_u); -+ FM_DMP_V32(buf, n, p_mm, rbca_l); -+ FM_DMP_V32(buf, n, p_mm, rbca_u); -+ FM_DMP_V32(buf, n, p_mm, rdrp_l); -+ FM_DMP_V32(buf, n, p_mm, rdrp_u); -+ FM_DMP_V32(buf, n, p_mm, rpkt_l); -+ FM_DMP_V32(buf, n, p_mm, rpkt_u); -+ FM_DMP_V32(buf, n, p_mm, rund_l); -+ FM_DMP_V32(buf, n, p_mm, rund_u); -+ FM_DMP_V32(buf, n, p_mm, r64_l); -+ FM_DMP_V32(buf, n, p_mm, r64_u); -+ FM_DMP_V32(buf, n, p_mm, r127_l); -+ FM_DMP_V32(buf, n, p_mm, r127_u); -+ FM_DMP_V32(buf, n, p_mm, r255_l); -+ FM_DMP_V32(buf, n, p_mm, r255_u); -+ FM_DMP_V32(buf, n, p_mm, r511_l); -+ FM_DMP_V32(buf, n, p_mm, r511_u); -+ FM_DMP_V32(buf, n, p_mm, r1023_l); -+ FM_DMP_V32(buf, n, p_mm, r1023_u); -+ FM_DMP_V32(buf, n, p_mm, r1518_l); -+ FM_DMP_V32(buf, n, p_mm, r1518_u); -+ FM_DMP_V32(buf, n, p_mm, r1519x_l); -+ FM_DMP_V32(buf, n, p_mm, r1519x_u); -+ FM_DMP_V32(buf, n, p_mm, rovr_l); -+ FM_DMP_V32(buf, n, p_mm, rovr_u); -+ FM_DMP_V32(buf, n, p_mm, rjbr_l); -+ FM_DMP_V32(buf, n, p_mm, rjbr_u); -+ FM_DMP_V32(buf, n, p_mm, rfrg_l); -+ FM_DMP_V32(buf, n, p_mm, rfrg_u); -+ FM_DMP_V32(buf, n, p_mm, rcnp_l); -+ FM_DMP_V32(buf, n, p_mm, rcnp_u); -+ FM_DMP_V32(buf, n, p_mm, rdrntp_l); -+ FM_DMP_V32(buf, n, p_mm, rdrntp_u); -+ -+ return n; -+} -+ -+static int memac_dump_regs_tx(struct mac_device *h_mac, char *buf, int nn) -+{ -+ struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr; -+ int n = nn; -+ -+ FM_DMP_SUBTITLE(buf, n, "\n"); -+ FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Tx stats", h_mac->cell_index); -+ -+ -+ /* Tx Statistics Counter */ -+ FM_DMP_V32(buf, n, p_mm, teoct_l); -+ FM_DMP_V32(buf, n, p_mm, teoct_u); -+ FM_DMP_V32(buf, n, p_mm, toct_l); -+ FM_DMP_V32(buf, n, p_mm, toct_u); -+ FM_DMP_V32(buf, n, p_mm, txpf_l); -+ FM_DMP_V32(buf, n, p_mm, txpf_u); -+ FM_DMP_V32(buf, n, p_mm, tfrm_l); -+ FM_DMP_V32(buf, n, p_mm, tfrm_u); -+ FM_DMP_V32(buf, n, p_mm, tfcs_l); -+ FM_DMP_V32(buf, n, p_mm, tfcs_u); -+ FM_DMP_V32(buf, n, p_mm, tvlan_l); -+ FM_DMP_V32(buf, n, p_mm, tvlan_u); -+ FM_DMP_V32(buf, n, p_mm, terr_l); -+ FM_DMP_V32(buf, n, p_mm, terr_u); -+ FM_DMP_V32(buf, n, p_mm, tuca_l); -+ FM_DMP_V32(buf, n, p_mm, tuca_u); -+ FM_DMP_V32(buf, n, p_mm, tmca_l); -+ FM_DMP_V32(buf, n, p_mm, tmca_u); -+ FM_DMP_V32(buf, n, p_mm, tbca_l); -+ FM_DMP_V32(buf, n, p_mm, tbca_u); -+ FM_DMP_V32(buf, n, p_mm, tpkt_l); -+ FM_DMP_V32(buf, n, p_mm, tpkt_u); -+ FM_DMP_V32(buf, n, p_mm, tund_l); -+ FM_DMP_V32(buf, n, p_mm, tund_u); -+ FM_DMP_V32(buf, n, p_mm, t64_l); -+ FM_DMP_V32(buf, n, p_mm, t64_u); -+ FM_DMP_V32(buf, n, p_mm, t127_l); -+ FM_DMP_V32(buf, n, p_mm, t127_u); -+ FM_DMP_V32(buf, n, p_mm, t255_l); -+ FM_DMP_V32(buf, n, p_mm, t255_u); -+ FM_DMP_V32(buf, n, p_mm, t511_l); -+ FM_DMP_V32(buf, n, p_mm, t511_u); -+ FM_DMP_V32(buf, n, p_mm, t1023_l); -+ FM_DMP_V32(buf, n, p_mm, t1023_u); -+ FM_DMP_V32(buf, n, p_mm, t1518_l); -+ FM_DMP_V32(buf, n, p_mm, t1518_u); -+ FM_DMP_V32(buf, n, p_mm, t1519x_l); -+ FM_DMP_V32(buf, n, p_mm, t1519x_u); -+ FM_DMP_V32(buf, n, p_mm, tcnp_l); -+ FM_DMP_V32(buf, n, p_mm, tcnp_u); -+ -+ return n; -+} -+ -+int fm_mac_dump_regs(struct mac_device *h_mac, char *buf, int nn) -+{ -+ int n = nn; -+ -+ n = h_mac->dump_mac_regs(h_mac, buf, n); -+ -+ return n; -+} -+EXPORT_SYMBOL(fm_mac_dump_regs); -+ -+int fm_mac_dump_rx_stats(struct mac_device *h_mac, char *buf, int nn) -+{ -+ int n = nn; -+ -+ if(h_mac->dump_mac_rx_stats) -+ n = h_mac->dump_mac_rx_stats(h_mac, buf, n); -+ -+ return n; -+} -+EXPORT_SYMBOL(fm_mac_dump_rx_stats); -+ -+int fm_mac_dump_tx_stats(struct mac_device *h_mac, char *buf, int nn) -+{ -+ int n = nn; -+ -+ if(h_mac->dump_mac_tx_stats) -+ n = h_mac->dump_mac_tx_stats(h_mac, buf, n); -+ -+ return n; -+} -+EXPORT_SYMBOL(fm_mac_dump_tx_stats); -+ -+static void __cold setup_dtsec(struct mac_device *mac_dev) -+{ -+ mac_dev->init_phy = dtsec_init_phy; -+ mac_dev->init = init; -+ mac_dev->start = start; -+ mac_dev->stop = stop; -+ mac_dev->set_promisc = fm_mac_set_promiscuous; -+ mac_dev->change_addr = fm_mac_modify_mac_addr; -+ mac_dev->set_multi = set_multi; -+ mac_dev->uninit = uninit; -+ mac_dev->ptp_enable = fm_mac_enable_1588_time_stamp; -+ mac_dev->ptp_disable = fm_mac_disable_1588_time_stamp; -+ mac_dev->get_mac_handle = get_mac_handle; -+ mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames; -+ mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames; -+ mac_dev->fm_rtc_enable = fm_rtc_enable; -+ mac_dev->fm_rtc_disable = fm_rtc_disable; -+ mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt; -+ mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt; -+ mac_dev->fm_rtc_get_drift = fm_rtc_get_drift; -+ mac_dev->fm_rtc_set_drift = fm_rtc_set_drift; -+ mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm; -+ mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper; -+ mac_dev->set_wol = fm_mac_set_wol; -+ mac_dev->dump_mac_regs = dtsec_dump_regs; -+} -+ -+static void __cold setup_xgmac(struct mac_device *mac_dev) -+{ -+ mac_dev->init_phy = xgmac_init_phy; -+ mac_dev->init = init; -+ mac_dev->start = start; -+ mac_dev->stop = stop; -+ mac_dev->set_promisc = fm_mac_set_promiscuous; -+ mac_dev->change_addr = fm_mac_modify_mac_addr; -+ mac_dev->set_multi = set_multi; -+ mac_dev->uninit = uninit; -+ mac_dev->get_mac_handle = get_mac_handle; -+ mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames; -+ mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames; -+ mac_dev->set_wol = fm_mac_set_wol; -+ mac_dev->dump_mac_regs = xgmac_dump_regs; -+} -+ -+static void __cold setup_memac(struct mac_device *mac_dev) -+{ -+ mac_dev->init_phy = memac_init_phy; -+ mac_dev->init = memac_init; -+ mac_dev->start = start; -+ mac_dev->stop = stop; -+ mac_dev->set_promisc = fm_mac_set_promiscuous; -+ mac_dev->change_addr = fm_mac_modify_mac_addr; -+ mac_dev->set_multi = set_multi; -+ mac_dev->uninit = uninit; -+ mac_dev->get_mac_handle = get_mac_handle; -+ mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames; -+ mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames; -+ mac_dev->fm_rtc_enable = fm_rtc_enable; -+ mac_dev->fm_rtc_disable = fm_rtc_disable; -+ mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt; -+ mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt; -+ mac_dev->fm_rtc_get_drift = fm_rtc_get_drift; -+ mac_dev->fm_rtc_set_drift = fm_rtc_set_drift; -+ mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm; -+ mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper; -+ mac_dev->set_wol = fm_mac_set_wol; -+ mac_dev->dump_mac_regs = memac_dump_regs; -+ mac_dev->dump_mac_rx_stats = memac_dump_regs_rx; -+ mac_dev->dump_mac_tx_stats = memac_dump_regs_tx; -+} -+ -+void (*const mac_setup[])(struct mac_device *mac_dev) = { -+ [DTSEC] = setup_dtsec, -+ [XGMAC] = setup_xgmac, -+ [MEMAC] = setup_memac -+}; ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c -@@ -0,0 +1,486 @@ -+/* Copyright 2008-2012 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifdef CONFIG_FSL_DPAA_ETH_DEBUG -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+#else -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": " fmt -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "lnxwrp_fm_ext.h" -+ -+#include "mac.h" -+ -+#define DTSEC_SUPPORTED \ -+ (SUPPORTED_10baseT_Half \ -+ | SUPPORTED_10baseT_Full \ -+ | SUPPORTED_100baseT_Half \ -+ | SUPPORTED_100baseT_Full \ -+ | SUPPORTED_Autoneg \ -+ | SUPPORTED_Pause \ -+ | SUPPORTED_Asym_Pause \ -+ | SUPPORTED_MII) -+ -+static const char phy_str[][11] = { -+ [PHY_INTERFACE_MODE_MII] = "mii", -+ [PHY_INTERFACE_MODE_GMII] = "gmii", -+ [PHY_INTERFACE_MODE_SGMII] = "sgmii", -+ [PHY_INTERFACE_MODE_QSGMII] = "qsgmii", -+ [PHY_INTERFACE_MODE_TBI] = "tbi", -+ [PHY_INTERFACE_MODE_RMII] = "rmii", -+ [PHY_INTERFACE_MODE_RGMII] = "rgmii", -+ [PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id", -+ [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid", -+ [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid", -+ [PHY_INTERFACE_MODE_RTBI] = "rtbi", -+ [PHY_INTERFACE_MODE_XGMII] = "xgmii", -+ [PHY_INTERFACE_MODE_SGMII_2500] = "sgmii-2500", -+}; -+ -+static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(phy_str); i++) -+ if (strcmp(str, phy_str[i]) == 0) -+ return (phy_interface_t)i; -+ -+ return PHY_INTERFACE_MODE_MII; -+} -+ -+static const uint16_t phy2speed[] = { -+ [PHY_INTERFACE_MODE_MII] = SPEED_100, -+ [PHY_INTERFACE_MODE_GMII] = SPEED_1000, -+ [PHY_INTERFACE_MODE_SGMII] = SPEED_1000, -+ [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000, -+ [PHY_INTERFACE_MODE_TBI] = SPEED_1000, -+ [PHY_INTERFACE_MODE_RMII] = SPEED_100, -+ [PHY_INTERFACE_MODE_RGMII] = SPEED_1000, -+ [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000, -+ [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000, -+ [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000, -+ [PHY_INTERFACE_MODE_RTBI] = SPEED_1000, -+ [PHY_INTERFACE_MODE_XGMII] = SPEED_10000, -+ [PHY_INTERFACE_MODE_SGMII_2500] = SPEED_2500, -+}; -+ -+static struct mac_device * __cold -+alloc_macdev(struct device *dev, size_t sizeof_priv, -+ void (*setup)(struct mac_device *mac_dev)) -+{ -+ struct mac_device *mac_dev; -+ -+ mac_dev = devm_kzalloc(dev, sizeof(*mac_dev) + sizeof_priv, GFP_KERNEL); -+ if (unlikely(mac_dev == NULL)) -+ mac_dev = ERR_PTR(-ENOMEM); -+ else { -+ mac_dev->dev = dev; -+ dev_set_drvdata(dev, mac_dev); -+ setup(mac_dev); -+ } -+ -+ return mac_dev; -+} -+ -+static int __cold free_macdev(struct mac_device *mac_dev) -+{ -+ dev_set_drvdata(mac_dev->dev, NULL); -+ -+ return mac_dev->uninit(mac_dev->get_mac_handle(mac_dev)); -+} -+ -+static const struct of_device_id mac_match[] = { -+ [DTSEC] = { -+ .compatible = "fsl,fman-1g-mac" -+ }, -+ [XGMAC] = { -+ .compatible = "fsl,fman-10g-mac" -+ }, -+ [MEMAC] = { -+ .compatible = "fsl,fman-memac" -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, mac_match); -+ -+static int __cold mac_probe(struct platform_device *_of_dev) -+{ -+ int _errno, i; -+ struct device *dev; -+ struct device_node *mac_node, *dev_node; -+ struct mac_device *mac_dev; -+ struct platform_device *of_dev; -+ struct resource res; -+ const char *char_prop; -+ int nph; -+ u32 cell_index; -+ const struct of_device_id *match; -+ -+ dev = &_of_dev->dev; -+ mac_node = dev->of_node; -+ -+ match = of_match_device(mac_match, dev); -+ if (!match) -+ return -EINVAL; -+ -+ for (i = 0; i < ARRAY_SIZE(mac_match) - 1 && match != mac_match + i; -+ i++) -+ ; -+ BUG_ON(i >= ARRAY_SIZE(mac_match) - 1); -+ -+ mac_dev = alloc_macdev(dev, mac_sizeof_priv[i], mac_setup[i]); -+ if (IS_ERR(mac_dev)) { -+ _errno = PTR_ERR(mac_dev); -+ dev_err(dev, "alloc_macdev() = %d\n", _errno); -+ goto _return; -+ } -+ -+ INIT_LIST_HEAD(&mac_dev->mc_addr_list); -+ -+ /* Get the FM node */ -+ dev_node = of_get_parent(mac_node); -+ if (unlikely(dev_node == NULL)) { -+ dev_err(dev, "of_get_parent(%s) failed\n", -+ mac_node->full_name); -+ _errno = -EINVAL; -+ goto _return_dev_set_drvdata; -+ } -+ -+ of_dev = of_find_device_by_node(dev_node); -+ if (unlikely(of_dev == NULL)) { -+ dev_err(dev, "of_find_device_by_node(%s) failed\n", -+ dev_node->full_name); -+ _errno = -EINVAL; -+ goto _return_of_node_put; -+ } -+ -+ mac_dev->fm_dev = fm_bind(&of_dev->dev); -+ if (unlikely(mac_dev->fm_dev == NULL)) { -+ dev_err(dev, "fm_bind(%s) failed\n", dev_node->full_name); -+ _errno = -ENODEV; -+ goto _return_of_node_put; -+ } -+ -+ mac_dev->fm = (void *)fm_get_handle(mac_dev->fm_dev); -+ of_node_put(dev_node); -+ -+ /* Get the address of the memory mapped registers */ -+ _errno = of_address_to_resource(mac_node, 0, &res); -+ if (unlikely(_errno < 0)) { -+ dev_err(dev, "of_address_to_resource(%s) = %d\n", -+ mac_node->full_name, _errno); -+ goto _return_dev_set_drvdata; -+ } -+ -+ mac_dev->res = __devm_request_region( -+ dev, -+ fm_get_mem_region(mac_dev->fm_dev), -+ res.start, res.end + 1 - res.start, "mac"); -+ if (unlikely(mac_dev->res == NULL)) { -+ dev_err(dev, "__devm_request_mem_region(mac) failed\n"); -+ _errno = -EBUSY; -+ goto _return_dev_set_drvdata; -+ } -+ -+ mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start, -+ mac_dev->res->end + 1 -+ - mac_dev->res->start); -+ if (unlikely(mac_dev->vaddr == NULL)) { -+ dev_err(dev, "devm_ioremap() failed\n"); -+ _errno = -EIO; -+ goto _return_dev_set_drvdata; -+ } -+ -+#define TBIPA_OFFSET 0x1c -+#define TBIPA_DEFAULT_ADDR 5 /* override if used as external PHY addr. */ -+ mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0); -+ if (mac_dev->tbi_node) { -+ u32 tbiaddr = TBIPA_DEFAULT_ADDR; -+ const __be32 *tbi_reg; -+ void __iomem *addr; -+ -+ tbi_reg = of_get_property(mac_dev->tbi_node, "reg", NULL); -+ if (tbi_reg) -+ tbiaddr = be32_to_cpup(tbi_reg); -+ addr = mac_dev->vaddr + TBIPA_OFFSET; -+ /* TODO: out_be32 does not exist on ARM */ -+ out_be32(addr, tbiaddr); -+ } -+ -+ if (!of_device_is_available(mac_node)) { -+ devm_iounmap(dev, mac_dev->vaddr); -+ __devm_release_region(dev, fm_get_mem_region(mac_dev->fm_dev), -+ res.start, res.end + 1 - res.start); -+ fm_unbind(mac_dev->fm_dev); -+ devm_kfree(dev, mac_dev); -+ dev_set_drvdata(dev, NULL); -+ return -ENODEV; -+ } -+ -+ /* Get the cell-index */ -+ _errno = of_property_read_u32(mac_node, "cell-index", &cell_index); -+ if (unlikely(_errno)) { -+ dev_err(dev, "Cannot read cell-index of mac node %s from device tree\n", -+ mac_node->full_name); -+ goto _return_dev_set_drvdata; -+ } -+ mac_dev->cell_index = (uint8_t)cell_index; -+ if (mac_dev->cell_index >= 8) -+ mac_dev->cell_index -= 8; -+ -+ /* Get the MAC address */ -+ _errno = of_get_mac_address(mac_node, mac_dev->addr); -+ if (unlikely(_errno)) { -+ dev_err(dev, "of_get_mac_address(%s) failed\n", -+ mac_node->full_name); -+ goto _return_dev_set_drvdata; -+ } -+ -+ /* Verify the number of port handles */ -+ nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL); -+ if (unlikely(nph < 0)) { -+ dev_err(dev, "Cannot read port handles of mac node %s from device tree\n", -+ mac_node->full_name); -+ _errno = nph; -+ goto _return_dev_set_drvdata; -+ } -+ -+ if (nph != ARRAY_SIZE(mac_dev->port_dev)) { -+ dev_err(dev, "Not supported number of port handles of mac node %s from device tree\n", -+ mac_node->full_name); -+ _errno = -EINVAL; -+ goto _return_dev_set_drvdata; -+ } -+ -+ for_each_port_device(i, mac_dev->port_dev) { -+ dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i); -+ if (unlikely(dev_node == NULL)) { -+ dev_err(dev, "Cannot find port node referenced by mac node %s from device tree\n", -+ mac_node->full_name); -+ _errno = -EINVAL; -+ goto _return_of_node_put; -+ } -+ -+ of_dev = of_find_device_by_node(dev_node); -+ if (unlikely(of_dev == NULL)) { -+ dev_err(dev, "of_find_device_by_node(%s) failed\n", -+ dev_node->full_name); -+ _errno = -EINVAL; -+ goto _return_of_node_put; -+ } -+ -+ mac_dev->port_dev[i] = fm_port_bind(&of_dev->dev); -+ if (unlikely(mac_dev->port_dev[i] == NULL)) { -+ dev_err(dev, "dev_get_drvdata(%s) failed\n", -+ dev_node->full_name); -+ _errno = -EINVAL; -+ goto _return_of_node_put; -+ } -+ of_node_put(dev_node); -+ } -+ -+ /* Get the PHY connection type */ -+ _errno = of_property_read_string(mac_node, "phy-connection-type", -+ &char_prop); -+ if (unlikely(_errno)) { -+ dev_warn(dev, -+ "Cannot read PHY connection type of mac node %s from device tree. Defaulting to MII\n", -+ mac_node->full_name); -+ mac_dev->phy_if = PHY_INTERFACE_MODE_MII; -+ } else -+ mac_dev->phy_if = str2phy(char_prop); -+ -+ mac_dev->link = false; -+ mac_dev->half_duplex = false; -+ mac_dev->speed = phy2speed[mac_dev->phy_if]; -+ mac_dev->max_speed = mac_dev->speed; -+ mac_dev->if_support = DTSEC_SUPPORTED; -+ /* We don't support half-duplex in SGMII mode */ -+ if (strstr(char_prop, "sgmii") || strstr(char_prop, "qsgmii") || -+ strstr(char_prop, "sgmii-2500")) -+ mac_dev->if_support &= ~(SUPPORTED_10baseT_Half | -+ SUPPORTED_100baseT_Half); -+ -+ /* Gigabit support (no half-duplex) */ -+ if (mac_dev->max_speed == SPEED_1000 || -+ mac_dev->max_speed == SPEED_2500) -+ mac_dev->if_support |= SUPPORTED_1000baseT_Full; -+ -+ /* The 10G interface only supports one mode */ -+ if (strstr(char_prop, "xgmii")) -+ mac_dev->if_support = SUPPORTED_10000baseT_Full; -+ -+ /* Get the rest of the PHY information */ -+ mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0); -+ if (!mac_dev->phy_node) { -+ struct phy_device *phy; -+ -+ if (!of_phy_is_fixed_link(mac_node)) { -+ dev_err(dev, "Wrong PHY information of mac node %s\n", -+ mac_node->full_name); -+ goto _return_dev_set_drvdata; -+ } -+ -+ _errno = of_phy_register_fixed_link(mac_node); -+ if (_errno) -+ goto _return_dev_set_drvdata; -+ -+ mac_dev->fixed_link = devm_kzalloc(mac_dev->dev, -+ sizeof(*mac_dev->fixed_link), -+ GFP_KERNEL); -+ if (!mac_dev->fixed_link) -+ goto _return_dev_set_drvdata; -+ -+ mac_dev->phy_node = of_node_get(mac_node); -+ phy = of_phy_find_device(mac_dev->phy_node); -+ if (!phy) -+ goto _return_dev_set_drvdata; -+ -+ mac_dev->fixed_link->link = phy->link; -+ mac_dev->fixed_link->speed = phy->speed; -+ mac_dev->fixed_link->duplex = phy->duplex; -+ mac_dev->fixed_link->pause = phy->pause; -+ mac_dev->fixed_link->asym_pause = phy->asym_pause; -+ } -+ -+ _errno = mac_dev->init(mac_dev); -+ if (unlikely(_errno < 0)) { -+ dev_err(dev, "mac_dev->init() = %d\n", _errno); -+ goto _return_dev_set_drvdata; -+ } -+ -+ /* pause frame autonegotiation enabled*/ -+ mac_dev->autoneg_pause = true; -+ -+ /* by intializing the values to false, force FMD to enable PAUSE frames -+ * on RX and TX -+ */ -+ mac_dev->rx_pause_req = mac_dev->tx_pause_req = true; -+ mac_dev->rx_pause_active = mac_dev->tx_pause_active = false; -+ _errno = set_mac_active_pause(mac_dev, true, true); -+ if (unlikely(_errno < 0)) -+ dev_err(dev, "set_mac_active_pause() = %d\n", _errno); -+ -+ dev_info(dev, -+ "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n", -+ mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2], -+ mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]); -+ -+ goto _return; -+ -+_return_of_node_put: -+ of_node_put(dev_node); -+_return_dev_set_drvdata: -+ dev_set_drvdata(dev, NULL); -+_return: -+ return _errno; -+} -+ -+static int __cold mac_remove(struct platform_device *of_dev) -+{ -+ int i, _errno; -+ struct device *dev; -+ struct mac_device *mac_dev; -+ -+ dev = &of_dev->dev; -+ mac_dev = (struct mac_device *)dev_get_drvdata(dev); -+ -+ for_each_port_device(i, mac_dev->port_dev) -+ fm_port_unbind(mac_dev->port_dev[i]); -+ -+ fm_unbind(mac_dev->fm_dev); -+ -+ _errno = free_macdev(mac_dev); -+ -+ return _errno; -+} -+ -+static struct platform_driver mac_driver = { -+ .driver = { -+ .name = KBUILD_MODNAME, -+ .of_match_table = mac_match, -+ .owner = THIS_MODULE, -+ }, -+ .probe = mac_probe, -+ .remove = mac_remove -+}; -+ -+static int __init __cold mac_load(void) -+{ -+ int _errno; -+ -+ pr_debug(KBUILD_MODNAME ": -> %s:%s()\n", -+ KBUILD_BASENAME".c", __func__); -+ -+ pr_info(KBUILD_MODNAME ": %s\n", mac_driver_description); -+ -+ _errno = platform_driver_register(&mac_driver); -+ if (unlikely(_errno < 0)) { -+ pr_err(KBUILD_MODNAME ": %s:%hu:%s(): platform_driver_register() = %d\n", -+ KBUILD_BASENAME".c", __LINE__, __func__, _errno); -+ goto _return; -+ } -+ -+ goto _return; -+ -+_return: -+ pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -+ KBUILD_BASENAME".c", __func__); -+ -+ return _errno; -+} -+module_init(mac_load); -+ -+static void __exit __cold mac_unload(void) -+{ -+ pr_debug(KBUILD_MODNAME ": -> %s:%s()\n", -+ KBUILD_BASENAME".c", __func__); -+ -+ platform_driver_unregister(&mac_driver); -+ -+ pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -+ KBUILD_BASENAME".c", __func__); -+} -+module_exit(mac_unload); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h -@@ -0,0 +1,135 @@ -+/* Copyright 2008-2011 Freescale Semiconductor, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __MAC_H -+#define __MAC_H -+ -+#include /* struct device, BUS_ID_SIZE */ -+#include /* ETH_ALEN */ -+#include /* phy_interface_t, struct phy_device */ -+#include -+ -+#include "lnxwrp_fsl_fman.h" /* struct port_device */ -+ -+enum {DTSEC, XGMAC, MEMAC}; -+ -+struct mac_device { -+ struct device *dev; -+ void *priv; -+ uint8_t cell_index; -+ struct resource *res; -+ void __iomem *vaddr; -+ uint8_t addr[ETH_ALEN]; -+ bool promisc; -+ -+ struct fm *fm_dev; -+ struct fm_port *port_dev[2]; -+ -+ phy_interface_t phy_if; -+ u32 if_support; -+ bool link; -+ bool half_duplex; -+ uint16_t speed; -+ uint16_t max_speed; -+ struct device_node *phy_node; -+ char fixed_bus_id[MII_BUS_ID_SIZE + 3]; -+ struct device_node *tbi_node; -+ struct phy_device *phy_dev; -+ void *fm; -+ /* List of multicast addresses */ -+ struct list_head mc_addr_list; -+ struct fixed_phy_status *fixed_link; -+ -+ bool autoneg_pause; -+ bool rx_pause_req; -+ bool tx_pause_req; -+ bool rx_pause_active; -+ bool tx_pause_active; -+ -+ struct fm_mac_dev *(*get_mac_handle)(struct mac_device *mac_dev); -+ int (*init_phy)(struct net_device *net_dev, struct mac_device *mac_dev); -+ int (*init)(struct mac_device *mac_dev); -+ int (*start)(struct mac_device *mac_dev); -+ int (*stop)(struct mac_device *mac_dev); -+ int (*set_promisc)(struct fm_mac_dev *fm_mac_dev, bool enable); -+ int (*change_addr)(struct fm_mac_dev *fm_mac_dev, uint8_t *addr); -+ int (*set_multi)(struct net_device *net_dev, -+ struct mac_device *mac_dev); -+ int (*uninit)(struct fm_mac_dev *fm_mac_dev); -+ int (*ptp_enable)(struct fm_mac_dev *fm_mac_dev); -+ int (*ptp_disable)(struct fm_mac_dev *fm_mac_dev); -+ int (*set_rx_pause)(struct fm_mac_dev *fm_mac_dev, bool en); -+ int (*set_tx_pause)(struct fm_mac_dev *fm_mac_dev, bool en); -+ int (*fm_rtc_enable)(struct fm *fm_dev); -+ int (*fm_rtc_disable)(struct fm *fm_dev); -+ int (*fm_rtc_get_cnt)(struct fm *fm_dev, uint64_t *ts); -+ int (*fm_rtc_set_cnt)(struct fm *fm_dev, uint64_t ts); -+ int (*fm_rtc_get_drift)(struct fm *fm_dev, uint32_t *drift); -+ int (*fm_rtc_set_drift)(struct fm *fm_dev, uint32_t drift); -+ int (*fm_rtc_set_alarm)(struct fm *fm_dev, uint32_t id, uint64_t time); -+ int (*fm_rtc_set_fiper)(struct fm *fm_dev, uint32_t id, -+ uint64_t fiper); -+#ifdef CONFIG_PTP_1588_CLOCK_DPAA -+ int (*fm_rtc_enable_interrupt)(struct fm *fm_dev, uint32_t events); -+ int (*fm_rtc_disable_interrupt)(struct fm *fm_dev, uint32_t events); -+#endif -+ int (*set_wol)(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, -+ bool en); -+ int (*dump_mac_regs)(struct mac_device *h_mac, char *buf, int nn); -+ int (*dump_mac_rx_stats)(struct mac_device *h_mac, char *buf, int nn); -+ int (*dump_mac_tx_stats)(struct mac_device *h_mac, char *buf, int nn); -+}; -+ -+struct mac_address { -+ uint8_t addr[ETH_ALEN]; -+ struct list_head list; -+}; -+ -+#define get_fm_handle(net_dev) \ -+ (((struct dpa_priv_s *)netdev_priv(net_dev))->mac_dev->fm_dev) -+ -+#define for_each_port_device(i, port_dev) \ -+ for (i = 0; i < ARRAY_SIZE(port_dev); i++) -+ -+static inline __attribute((nonnull)) void *macdev_priv( -+ const struct mac_device *mac_dev) -+{ -+ return (void *)mac_dev + sizeof(*mac_dev); -+} -+ -+extern const char *mac_driver_description; -+extern const size_t mac_sizeof_priv[]; -+extern void (*const mac_setup[])(struct mac_device *mac_dev); -+ -+int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx); -+void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause); -+ -+#endif /* __MAC_H */ ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c -@@ -0,0 +1,848 @@ -+/* Copyright 2011-2012 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* Offline Parsing / Host Command port driver for FSL QorIQ FMan. -+ * Validates device-tree configuration and sets up the offline ports. -+ */ -+ -+#ifdef CONFIG_FSL_DPAA_ETH_DEBUG -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": %s:%hu:%s() " fmt, \ -+ KBUILD_BASENAME".c", __LINE__, __func__ -+#else -+#define pr_fmt(fmt) \ -+ KBUILD_MODNAME ": " fmt -+#endif -+ -+ -+#include -+#include -+#include -+#include -+ -+#include "offline_port.h" -+#include "dpaa_eth.h" -+#include "dpaa_eth_common.h" -+ -+#define OH_MOD_DESCRIPTION "FSL FMan Offline Parsing port driver" -+/* Manip extra space and data alignment for fragmentation */ -+#define FRAG_MANIP_SPACE 128 -+#define FRAG_DATA_ALIGN 64 -+ -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_AUTHOR("Bogdan Hamciuc "); -+MODULE_DESCRIPTION(OH_MOD_DESCRIPTION); -+ -+ -+static const struct of_device_id oh_port_match_table[] = { -+ { -+ .compatible = "fsl,dpa-oh" -+ }, -+ { -+ .compatible = "fsl,dpa-oh-shared" -+ }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, oh_port_match_table); -+ -+#ifdef CONFIG_PM -+ -+static int oh_suspend(struct device *dev) -+{ -+ struct dpa_oh_config_s *oh_config; -+ -+ oh_config = dev_get_drvdata(dev); -+ return fm_port_suspend(oh_config->oh_port); -+} -+ -+static int oh_resume(struct device *dev) -+{ -+ struct dpa_oh_config_s *oh_config; -+ -+ oh_config = dev_get_drvdata(dev); -+ return fm_port_resume(oh_config->oh_port); -+} -+ -+static const struct dev_pm_ops oh_pm_ops = { -+ .suspend = oh_suspend, -+ .resume = oh_resume, -+}; -+ -+#define OH_PM_OPS (&oh_pm_ops) -+ -+#else /* CONFIG_PM */ -+ -+#define OH_PM_OPS NULL -+ -+#endif /* CONFIG_PM */ -+ -+/* Creates Frame Queues */ -+static uint32_t oh_fq_create(struct qman_fq *fq, -+ uint32_t fq_id, uint16_t channel, -+ uint16_t wq_id) -+{ -+ struct qm_mcc_initfq fq_opts; -+ uint32_t create_flags, init_flags; -+ uint32_t ret = 0; -+ -+ if (fq == NULL) -+ return 1; -+ -+ /* Set flags for FQ create */ -+ create_flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_TO_DCPORTAL; -+ -+ /* Create frame queue */ -+ ret = qman_create_fq(fq_id, create_flags, fq); -+ if (ret != 0) -+ return 1; -+ -+ /* Set flags for FQ init */ -+ init_flags = QMAN_INITFQ_FLAG_SCHED; -+ -+ /* Set FQ init options. Specify destination WQ ID and channel */ -+ fq_opts.we_mask = QM_INITFQ_WE_DESTWQ; -+ fq_opts.fqd.dest.wq = wq_id; -+ fq_opts.fqd.dest.channel = channel; -+ -+ /* Initialize frame queue */ -+ ret = qman_init_fq(fq, init_flags, &fq_opts); -+ if (ret != 0) { -+ qman_destroy_fq(fq, 0); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static void dump_fq(struct device *dev, int fqid, uint16_t channel) -+{ -+ if (channel) { -+ /* display fqs with a valid (!= 0) destination channel */ -+ dev_info(dev, "FQ ID:%d Channel ID:%d\n", fqid, channel); -+ } -+} -+ -+static void dump_fq_duple(struct device *dev, struct qman_fq *fqs, -+ int fqs_count, uint16_t channel_id) -+{ -+ int i; -+ for (i = 0; i < fqs_count; i++) -+ dump_fq(dev, (fqs + i)->fqid, channel_id); -+} -+ -+static void dump_oh_config(struct device *dev, struct dpa_oh_config_s *conf) -+{ -+ struct list_head *fq_list; -+ struct fq_duple *fqd; -+ int i; -+ -+ dev_info(dev, "Default egress frame queue: %d\n", conf->default_fqid); -+ dev_info(dev, "Default error frame queue: %d\n", conf->error_fqid); -+ -+ /* TX queues (old initialization) */ -+ dev_info(dev, "Initialized queues:"); -+ for (i = 0; i < conf->egress_cnt; i++) -+ dump_fq_duple(dev, conf->egress_fqs, conf->egress_cnt, -+ conf->channel); -+ -+ /* initialized ingress queues */ -+ list_for_each(fq_list, &conf->fqs_ingress_list) { -+ fqd = list_entry(fq_list, struct fq_duple, fq_list); -+ dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id); -+ } -+ -+ /* initialized egress queues */ -+ list_for_each(fq_list, &conf->fqs_egress_list) { -+ fqd = list_entry(fq_list, struct fq_duple, fq_list); -+ dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id); -+ } -+} -+ -+/* Destroys Frame Queues */ -+static void oh_fq_destroy(struct qman_fq *fq) -+{ -+ int _errno = 0; -+ -+ _errno = qman_retire_fq(fq, NULL); -+ if (unlikely(_errno < 0)) -+ pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_retire_fq(%u)=%d\n", -+ KBUILD_BASENAME".c", __LINE__, __func__, -+ qman_fq_fqid(fq), _errno); -+ -+ _errno = qman_oos_fq(fq); -+ if (unlikely(_errno < 0)) { -+ pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_oos_fq(%u)=%d\n", -+ KBUILD_BASENAME".c", __LINE__, __func__, -+ qman_fq_fqid(fq), _errno); -+ } -+ -+ qman_destroy_fq(fq, 0); -+} -+ -+/* Allocation code for the OH port's PCD frame queues */ -+static int __cold oh_alloc_pcd_fqids(struct device *dev, -+ uint32_t num, -+ uint8_t alignment, -+ uint32_t *base_fqid) -+{ -+ dev_crit(dev, "callback not implemented!\n"); -+ BUG(); -+ -+ return 0; -+} -+ -+static int __cold oh_free_pcd_fqids(struct device *dev, uint32_t base_fqid) -+{ -+ dev_crit(dev, "callback not implemented!\n"); -+ BUG(); -+ -+ return 0; -+} -+ -+static void oh_set_buffer_layout(struct fm_port *port, -+ struct dpa_buffer_layout_s *layout) -+{ -+ struct fm_port_params params; -+ -+ layout->priv_data_size = DPA_TX_PRIV_DATA_SIZE; -+ layout->parse_results = true; -+ layout->hash_results = true; -+ layout->time_stamp = false; -+ -+ fm_port_get_buff_layout_ext_params(port, ¶ms); -+ layout->manip_extra_space = params.manip_extra_space; -+ layout->data_align = params.data_align; -+} -+ -+static int -+oh_port_probe(struct platform_device *_of_dev) -+{ -+ struct device *dpa_oh_dev; -+ struct device_node *dpa_oh_node; -+ int lenp, _errno = 0, fq_idx, duple_idx; -+ int n_size, i, j, ret, duples_count; -+ struct platform_device *oh_of_dev; -+ struct device_node *oh_node, *bpool_node = NULL, *root_node; -+ struct device *oh_dev; -+ struct dpa_oh_config_s *oh_config = NULL; -+ const __be32 *oh_all_queues; -+ const __be32 *channel_ids; -+ const __be32 *oh_tx_queues; -+ uint32_t queues_count; -+ uint32_t crt_fqid_base; -+ uint32_t crt_fq_count; -+ bool frag_enabled = false; -+ struct fm_port_params oh_port_tx_params; -+ struct fm_port_pcd_param oh_port_pcd_params; -+ struct dpa_buffer_layout_s buf_layout; -+ -+ /* True if the current partition owns the OH port. */ -+ bool init_oh_port; -+ -+ const struct of_device_id *match; -+ int crt_ext_pools_count; -+ u32 ext_pool_size; -+ u32 port_id; -+ u32 channel_id; -+ -+ int channel_ids_count; -+ int channel_idx; -+ struct fq_duple *fqd; -+ struct list_head *fq_list, *fq_list_tmp; -+ -+ const __be32 *bpool_cfg; -+ uint32_t bpid; -+ -+ memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params)); -+ dpa_oh_dev = &_of_dev->dev; -+ dpa_oh_node = dpa_oh_dev->of_node; -+ BUG_ON(dpa_oh_node == NULL); -+ -+ match = of_match_device(oh_port_match_table, dpa_oh_dev); -+ if (!match) -+ return -EINVAL; -+ -+ dev_dbg(dpa_oh_dev, "Probing OH port...\n"); -+ -+ /* Find the referenced OH node */ -+ oh_node = of_parse_phandle(dpa_oh_node, "fsl,fman-oh-port", 0); -+ if (oh_node == NULL) { -+ dev_err(dpa_oh_dev, -+ "Can't find OH node referenced from node %s\n", -+ dpa_oh_node->full_name); -+ return -EINVAL; -+ } -+ dev_info(dpa_oh_dev, "Found OH node handle compatible with %s\n", -+ match->compatible); -+ -+ _errno = of_property_read_u32(oh_node, "cell-index", &port_id); -+ if (_errno) { -+ dev_err(dpa_oh_dev, "No port id found in node %s\n", -+ dpa_oh_node->full_name); -+ goto return_kfree; -+ } -+ -+ _errno = of_property_read_u32(oh_node, "fsl,qman-channel-id", -+ &channel_id); -+ if (_errno) { -+ dev_err(dpa_oh_dev, "No channel id found in node %s\n", -+ dpa_oh_node->full_name); -+ goto return_kfree; -+ } -+ -+ oh_of_dev = of_find_device_by_node(oh_node); -+ BUG_ON(oh_of_dev == NULL); -+ oh_dev = &oh_of_dev->dev; -+ -+ /* The OH port must be initialized exactly once. -+ * The following scenarios are of interest: -+ * - the node is Linux-private (will always initialize it); -+ * - the node is shared between two Linux partitions -+ * (only one of them will initialize it); -+ * - the node is shared between a Linux and a LWE partition -+ * (Linux will initialize it) - "fsl,dpa-oh-shared" -+ */ -+ -+ /* Check if the current partition owns the OH port -+ * and ought to initialize it. It may be the case that we leave this -+ * to another (also Linux) partition. -+ */ -+ init_oh_port = strcmp(match->compatible, "fsl,dpa-oh-shared"); -+ -+ /* If we aren't the "owner" of the OH node, we're done here. */ -+ if (!init_oh_port) { -+ dev_dbg(dpa_oh_dev, -+ "Not owning the shared OH port %s, will not initialize it.\n", -+ oh_node->full_name); -+ of_node_put(oh_node); -+ return 0; -+ } -+ -+ /* Allocate OH dev private data */ -+ oh_config = devm_kzalloc(dpa_oh_dev, sizeof(*oh_config), GFP_KERNEL); -+ if (oh_config == NULL) { -+ dev_err(dpa_oh_dev, -+ "Can't allocate private data for OH node %s referenced from node %s!\n", -+ oh_node->full_name, dpa_oh_node->full_name); -+ _errno = -ENOMEM; -+ goto return_kfree; -+ } -+ -+ INIT_LIST_HEAD(&oh_config->fqs_ingress_list); -+ INIT_LIST_HEAD(&oh_config->fqs_egress_list); -+ -+ /* FQs that enter OH port */ -+ lenp = 0; -+ oh_all_queues = of_get_property(dpa_oh_node, -+ "fsl,qman-frame-queues-ingress", &lenp); -+ if (lenp % (2 * sizeof(*oh_all_queues))) { -+ dev_warn(dpa_oh_dev, -+ "Wrong ingress queues format for OH node %s referenced from node %s!\n", -+ oh_node->full_name, dpa_oh_node->full_name); -+ /* just ignore the last unpaired value */ -+ } -+ -+ duples_count = lenp / (2 * sizeof(*oh_all_queues)); -+ dev_err(dpa_oh_dev, "Allocating %d ingress frame queues duples\n", -+ duples_count); -+ for (duple_idx = 0; duple_idx < duples_count; duple_idx++) { -+ crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]); -+ crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]); -+ -+ fqd = devm_kzalloc(dpa_oh_dev, -+ sizeof(struct fq_duple), GFP_KERNEL); -+ if (!fqd) { -+ dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n", -+ oh_node->full_name, -+ dpa_oh_node->full_name); -+ _errno = -ENOMEM; -+ goto return_kfree; -+ } -+ -+ fqd->fqs = devm_kzalloc(dpa_oh_dev, -+ crt_fq_count * sizeof(struct qman_fq), -+ GFP_KERNEL); -+ if (!fqd->fqs) { -+ dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n", -+ oh_node->full_name, -+ dpa_oh_node->full_name); -+ _errno = -ENOMEM; -+ goto return_kfree; -+ } -+ -+ for (j = 0; j < crt_fq_count; j++) -+ (fqd->fqs + j)->fqid = crt_fqid_base + j; -+ fqd->fqs_count = crt_fq_count; -+ fqd->channel_id = (uint16_t)channel_id; -+ list_add(&fqd->fq_list, &oh_config->fqs_ingress_list); -+ } -+ -+ /* create the ingress queues */ -+ list_for_each(fq_list, &oh_config->fqs_ingress_list) { -+ fqd = list_entry(fq_list, struct fq_duple, fq_list); -+ -+ for (j = 0; j < fqd->fqs_count; j++) { -+ ret = oh_fq_create(fqd->fqs + j, -+ (fqd->fqs + j)->fqid, -+ fqd->channel_id, 3); -+ if (ret != 0) { -+ dev_err(dpa_oh_dev, "Unable to create ingress frame queue %d for OH node %s referenced from node %s!\n", -+ (fqd->fqs + j)->fqid, -+ oh_node->full_name, -+ dpa_oh_node->full_name); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ } -+ } -+ -+ /* FQs that exit OH port */ -+ lenp = 0; -+ oh_all_queues = of_get_property(dpa_oh_node, -+ "fsl,qman-frame-queues-egress", &lenp); -+ if (lenp % (2 * sizeof(*oh_all_queues))) { -+ dev_warn(dpa_oh_dev, -+ "Wrong egress queues format for OH node %s referenced from node %s!\n", -+ oh_node->full_name, dpa_oh_node->full_name); -+ /* just ignore the last unpaired value */ -+ } -+ -+ duples_count = lenp / (2 * sizeof(*oh_all_queues)); -+ dev_dbg(dpa_oh_dev, "Allocating %d egress frame queues duples\n", -+ duples_count); -+ for (duple_idx = 0; duple_idx < duples_count; duple_idx++) { -+ crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]); -+ crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]); -+ -+ fqd = devm_kzalloc(dpa_oh_dev, -+ sizeof(struct fq_duple), GFP_KERNEL); -+ if (!fqd) { -+ dev_err(dpa_oh_dev, "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n", -+ oh_node->full_name, -+ dpa_oh_node->full_name); -+ _errno = -ENOMEM; -+ goto return_kfree; -+ } -+ -+ fqd->fqs = devm_kzalloc(dpa_oh_dev, -+ crt_fq_count * sizeof(struct qman_fq), -+ GFP_KERNEL); -+ if (!fqd->fqs) { -+ dev_err(dpa_oh_dev, -+ "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n", -+ oh_node->full_name, -+ dpa_oh_node->full_name); -+ _errno = -ENOMEM; -+ goto return_kfree; -+ } -+ -+ for (j = 0; j < crt_fq_count; j++) -+ (fqd->fqs + j)->fqid = crt_fqid_base + j; -+ fqd->fqs_count = crt_fq_count; -+ /* channel ID is specified in another attribute */ -+ fqd->channel_id = 0; -+ list_add_tail(&fqd->fq_list, &oh_config->fqs_egress_list); -+ -+ /* allocate the queue */ -+ -+ } -+ -+ /* channel_ids for FQs that exit OH port */ -+ lenp = 0; -+ channel_ids = of_get_property(dpa_oh_node, -+ "fsl,qman-channel-ids-egress", &lenp); -+ -+ channel_ids_count = lenp / (sizeof(*channel_ids)); -+ if (channel_ids_count != duples_count) { -+ dev_warn(dpa_oh_dev, -+ "Not all egress queues have a channel id for OH node %s referenced from node %s!\n", -+ oh_node->full_name, dpa_oh_node->full_name); -+ /* just ignore the queues that do not have a Channel ID */ -+ } -+ -+ channel_idx = 0; -+ list_for_each(fq_list, &oh_config->fqs_egress_list) { -+ if (channel_idx + 1 > channel_ids_count) -+ break; -+ fqd = list_entry(fq_list, struct fq_duple, fq_list); -+ fqd->channel_id = -+ (uint16_t)be32_to_cpu(channel_ids[channel_idx++]); -+ } -+ -+ /* create egress queues */ -+ list_for_each(fq_list, &oh_config->fqs_egress_list) { -+ fqd = list_entry(fq_list, struct fq_duple, fq_list); -+ -+ if (fqd->channel_id == 0) { -+ /* missing channel id in dts */ -+ continue; -+ } -+ -+ for (j = 0; j < fqd->fqs_count; j++) { -+ ret = oh_fq_create(fqd->fqs + j, -+ (fqd->fqs + j)->fqid, -+ fqd->channel_id, 3); -+ if (ret != 0) { -+ dev_err(dpa_oh_dev, "Unable to create egress frame queue %d for OH node %s referenced from node %s!\n", -+ (fqd->fqs + j)->fqid, -+ oh_node->full_name, -+ dpa_oh_node->full_name); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ } -+ } -+ -+ /* Read FQ ids/nums for the DPA OH node */ -+ oh_all_queues = of_get_property(dpa_oh_node, -+ "fsl,qman-frame-queues-oh", &lenp); -+ if (oh_all_queues == NULL) { -+ dev_err(dpa_oh_dev, -+ "No frame queues have been defined for OH node %s referenced from node %s\n", -+ oh_node->full_name, dpa_oh_node->full_name); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ -+ /* Check that the OH error and default FQs are there */ -+ BUG_ON(lenp % (2 * sizeof(*oh_all_queues))); -+ queues_count = lenp / (2 * sizeof(*oh_all_queues)); -+ if (queues_count != 2) { -+ dev_err(dpa_oh_dev, -+ "Error and Default queues must be defined for OH node %s referenced from node %s\n", -+ oh_node->full_name, dpa_oh_node->full_name); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ -+ /* Read the FQIDs defined for this OH port */ -+ dev_dbg(dpa_oh_dev, "Reading %d queues...\n", queues_count); -+ fq_idx = 0; -+ -+ /* Error FQID - must be present */ -+ crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]); -+ crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]); -+ if (crt_fq_count != 1) { -+ dev_err(dpa_oh_dev, -+ "Only 1 Error FQ allowed in OH node %s referenced from node %s (read: %d FQIDs).\n", -+ oh_node->full_name, dpa_oh_node->full_name, -+ crt_fq_count); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ oh_config->error_fqid = crt_fqid_base; -+ dev_dbg(dpa_oh_dev, "Read Error FQID 0x%x for OH port %s.\n", -+ oh_config->error_fqid, oh_node->full_name); -+ -+ /* Default FQID - must be present */ -+ crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]); -+ crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]); -+ if (crt_fq_count != 1) { -+ dev_err(dpa_oh_dev, -+ "Only 1 Default FQ allowed in OH node %s referenced from %s (read: %d FQIDs).\n", -+ oh_node->full_name, dpa_oh_node->full_name, -+ crt_fq_count); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ oh_config->default_fqid = crt_fqid_base; -+ dev_dbg(dpa_oh_dev, "Read Default FQID 0x%x for OH port %s.\n", -+ oh_config->default_fqid, oh_node->full_name); -+ -+ /* TX FQID - presence is optional */ -+ oh_tx_queues = of_get_property(dpa_oh_node, "fsl,qman-frame-queues-tx", -+ &lenp); -+ if (oh_tx_queues == NULL) { -+ dev_dbg(dpa_oh_dev, -+ "No tx queues have been defined for OH node %s referenced from node %s\n", -+ oh_node->full_name, dpa_oh_node->full_name); -+ goto config_port; -+ } -+ -+ /* Check that queues-tx has only a base and a count defined */ -+ BUG_ON(lenp % (2 * sizeof(*oh_tx_queues))); -+ queues_count = lenp / (2 * sizeof(*oh_tx_queues)); -+ if (queues_count != 1) { -+ dev_err(dpa_oh_dev, -+ "TX queues must be defined in only one tuple for OH node %s referenced from node %s\n", -+ oh_node->full_name, dpa_oh_node->full_name); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ -+ fq_idx = 0; -+ crt_fqid_base = be32_to_cpu(oh_tx_queues[fq_idx++]); -+ crt_fq_count = be32_to_cpu(oh_tx_queues[fq_idx++]); -+ oh_config->egress_cnt = crt_fq_count; -+ -+ /* Allocate TX queues */ -+ dev_dbg(dpa_oh_dev, "Allocating %d queues for TX...\n", crt_fq_count); -+ oh_config->egress_fqs = devm_kzalloc(dpa_oh_dev, -+ crt_fq_count * sizeof(struct qman_fq), GFP_KERNEL); -+ if (oh_config->egress_fqs == NULL) { -+ dev_err(dpa_oh_dev, -+ "Can't allocate private data for TX queues for OH node %s referenced from node %s!\n", -+ oh_node->full_name, dpa_oh_node->full_name); -+ _errno = -ENOMEM; -+ goto return_kfree; -+ } -+ -+ /* Create TX queues */ -+ for (i = 0; i < crt_fq_count; i++) { -+ ret = oh_fq_create(oh_config->egress_fqs + i, -+ crt_fqid_base + i, (uint16_t)channel_id, 3); -+ if (ret != 0) { -+ dev_err(dpa_oh_dev, -+ "Unable to create TX frame queue %d for OH node %s referenced from node %s!\n", -+ crt_fqid_base + i, oh_node->full_name, -+ dpa_oh_node->full_name); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ } -+ -+config_port: -+ /* Get a handle to the fm_port so we can set -+ * its configuration params -+ */ -+ oh_config->oh_port = fm_port_bind(oh_dev); -+ if (oh_config->oh_port == NULL) { -+ dev_err(dpa_oh_dev, "NULL drvdata from fm port dev %s!\n", -+ oh_node->full_name); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ -+ oh_set_buffer_layout(oh_config->oh_port, &buf_layout); -+ -+ /* read the pool handlers */ -+ crt_ext_pools_count = of_count_phandle_with_args(dpa_oh_node, -+ "fsl,bman-buffer-pools", NULL); -+ if (crt_ext_pools_count <= 0) { -+ dev_info(dpa_oh_dev, -+ "OH port %s has no buffer pool. Fragmentation will not be enabled\n", -+ oh_node->full_name); -+ goto init_port; -+ } -+ -+ /* used for reading ext_pool_size*/ -+ root_node = of_find_node_by_path("/"); -+ if (root_node == NULL) { -+ dev_err(dpa_oh_dev, "of_find_node_by_path(/) failed\n"); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ -+ n_size = of_n_size_cells(root_node); -+ of_node_put(root_node); -+ -+ dev_dbg(dpa_oh_dev, "OH port number of pools = %d\n", -+ crt_ext_pools_count); -+ -+ oh_port_tx_params.num_pools = (uint8_t)crt_ext_pools_count; -+ -+ for (i = 0; i < crt_ext_pools_count; i++) { -+ bpool_node = of_parse_phandle(dpa_oh_node, -+ "fsl,bman-buffer-pools", i); -+ if (bpool_node == NULL) { -+ dev_err(dpa_oh_dev, "Invalid Buffer pool node\n"); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ -+ _errno = of_property_read_u32(bpool_node, "fsl,bpid", &bpid); -+ if (_errno) { -+ dev_err(dpa_oh_dev, "Invalid Buffer Pool ID\n"); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ -+ oh_port_tx_params.pool_param[i].id = (uint8_t)bpid; -+ dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", bpid); -+ -+ bpool_cfg = of_get_property(bpool_node, -+ "fsl,bpool-ethernet-cfg", &lenp); -+ if (bpool_cfg == NULL) { -+ dev_err(dpa_oh_dev, "Invalid Buffer pool config params\n"); -+ _errno = -EINVAL; -+ goto return_kfree; -+ } -+ -+ ext_pool_size = of_read_number(bpool_cfg + n_size, n_size); -+ oh_port_tx_params.pool_param[i].size = (uint16_t)ext_pool_size; -+ dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n", -+ ext_pool_size); -+ of_node_put(bpool_node); -+ -+ } -+ -+ if (buf_layout.data_align != FRAG_DATA_ALIGN || -+ buf_layout.manip_extra_space != FRAG_MANIP_SPACE) -+ goto init_port; -+ -+ frag_enabled = true; -+ dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d", -+ port_id); -+ -+init_port: -+ of_node_put(oh_node); -+ /* Set Tx params */ -+ dpaa_eth_init_port(tx, oh_config->oh_port, oh_port_tx_params, -+ oh_config->error_fqid, oh_config->default_fqid, (&buf_layout), -+ frag_enabled); -+ /* Set PCD params */ -+ oh_port_pcd_params.cba = oh_alloc_pcd_fqids; -+ oh_port_pcd_params.cbf = oh_free_pcd_fqids; -+ oh_port_pcd_params.dev = dpa_oh_dev; -+ fm_port_pcd_bind(oh_config->oh_port, &oh_port_pcd_params); -+ -+ dev_set_drvdata(dpa_oh_dev, oh_config); -+ -+ /* Enable the OH port */ -+ _errno = fm_port_enable(oh_config->oh_port); -+ if (_errno) -+ goto return_kfree; -+ -+ dev_info(dpa_oh_dev, "OH port %s enabled.\n", oh_node->full_name); -+ -+ /* print of all referenced & created queues */ -+ dump_oh_config(dpa_oh_dev, oh_config); -+ -+ return 0; -+ -+return_kfree: -+ if (bpool_node) -+ of_node_put(bpool_node); -+ if (oh_node) -+ of_node_put(oh_node); -+ if (oh_config && oh_config->egress_fqs) -+ devm_kfree(dpa_oh_dev, oh_config->egress_fqs); -+ -+ list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_ingress_list) { -+ fqd = list_entry(fq_list, struct fq_duple, fq_list); -+ list_del(fq_list); -+ devm_kfree(dpa_oh_dev, fqd->fqs); -+ devm_kfree(dpa_oh_dev, fqd); -+ } -+ -+ list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_egress_list) { -+ fqd = list_entry(fq_list, struct fq_duple, fq_list); -+ list_del(fq_list); -+ devm_kfree(dpa_oh_dev, fqd->fqs); -+ devm_kfree(dpa_oh_dev, fqd); -+ } -+ -+ devm_kfree(dpa_oh_dev, oh_config); -+ return _errno; -+} -+ -+static int __cold oh_port_remove(struct platform_device *_of_dev) -+{ -+ int _errno = 0, i; -+ struct dpa_oh_config_s *oh_config; -+ -+ pr_info("Removing OH port...\n"); -+ -+ oh_config = dev_get_drvdata(&_of_dev->dev); -+ if (oh_config == NULL) { -+ pr_err(KBUILD_MODNAME -+ ": %s:%hu:%s(): No OH config in device private data!\n", -+ KBUILD_BASENAME".c", __LINE__, __func__); -+ _errno = -ENODEV; -+ goto return_error; -+ } -+ -+ if (oh_config->egress_fqs) -+ for (i = 0; i < oh_config->egress_cnt; i++) -+ oh_fq_destroy(oh_config->egress_fqs + i); -+ -+ if (oh_config->oh_port == NULL) { -+ pr_err(KBUILD_MODNAME -+ ": %s:%hu:%s(): No fm port in device private data!\n", -+ KBUILD_BASENAME".c", __LINE__, __func__); -+ _errno = -EINVAL; -+ goto free_egress_fqs; -+ } -+ -+ _errno = fm_port_disable(oh_config->oh_port); -+ -+free_egress_fqs: -+ if (oh_config->egress_fqs) -+ devm_kfree(&_of_dev->dev, oh_config->egress_fqs); -+ devm_kfree(&_of_dev->dev, oh_config); -+ dev_set_drvdata(&_of_dev->dev, NULL); -+ -+return_error: -+ return _errno; -+} -+ -+static struct platform_driver oh_port_driver = { -+ .driver = { -+ .name = KBUILD_MODNAME, -+ .of_match_table = oh_port_match_table, -+ .owner = THIS_MODULE, -+ .pm = OH_PM_OPS, -+ }, -+ .probe = oh_port_probe, -+ .remove = oh_port_remove -+}; -+ -+static int __init __cold oh_port_load(void) -+{ -+ int _errno; -+ -+ pr_info(OH_MOD_DESCRIPTION "\n"); -+ -+ _errno = platform_driver_register(&oh_port_driver); -+ if (_errno < 0) { -+ pr_err(KBUILD_MODNAME -+ ": %s:%hu:%s(): platform_driver_register() = %d\n", -+ KBUILD_BASENAME".c", __LINE__, __func__, _errno); -+ } -+ -+ pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -+ KBUILD_BASENAME".c", __func__); -+ return _errno; -+} -+module_init(oh_port_load); -+ -+static void __exit __cold oh_port_unload(void) -+{ -+ pr_debug(KBUILD_MODNAME ": -> %s:%s()\n", -+ KBUILD_BASENAME".c", __func__); -+ -+ platform_driver_unregister(&oh_port_driver); -+ -+ pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -+ KBUILD_BASENAME".c", __func__); -+} -+module_exit(oh_port_unload); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h -@@ -0,0 +1,59 @@ -+/* Copyright 2011 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __OFFLINE_PORT_H -+#define __OFFLINE_PORT_H -+ -+struct fm_port; -+struct qman_fq; -+ -+/* fqs are defined in duples (base_fq, fq_count) */ -+struct fq_duple { -+ struct qman_fq *fqs; -+ int fqs_count; -+ uint16_t channel_id; -+ struct list_head fq_list; -+}; -+ -+/* OH port configuration */ -+struct dpa_oh_config_s { -+ uint32_t error_fqid; -+ uint32_t default_fqid; -+ struct fm_port *oh_port; -+ uint32_t egress_cnt; -+ struct qman_fq *egress_fqs; -+ uint16_t channel; -+ -+ struct list_head fqs_ingress_list; -+ struct list_head fqs_egress_list; -+}; -+ -+#endif /* __OFFLINE_PORT_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0010-dpaa_eth-ls1043a-errata-check-if-the-skb-is-linear-a.patch b/target/linux/layerscape/patches-5.4/701-net-0010-dpaa_eth-ls1043a-errata-check-if-the-skb-is-linear-a.patch deleted file mode 100644 index e601766bd9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0010-dpaa_eth-ls1043a-errata-check-if-the-skb-is-linear-a.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 62fbf7ebdc28867ae613c3be9c62b30bc36edb1d Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 27 Feb 2017 17:35:24 +0200 -Subject: [PATCH] dpaa_eth: ls1043a errata: check if the skb is linear after 4k - splitting - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -993,7 +993,7 @@ int __hot dpa_tx_extended(struct sk_buff - struct dpa_percpu_priv_s *percpu_priv; - struct rtnl_link_stats64 *percpu_stats; - int err = 0; -- const bool nonlinear = skb_is_nonlinear(skb); -+ bool nonlinear; - int *countptr, offset = 0; - - priv = netdev_priv(net_dev); -@@ -1023,6 +1023,8 @@ int __hot dpa_tx_extended(struct sk_buff - } - #endif - -+ nonlinear = skb_is_nonlinear(skb); -+ - /* MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure - * we don't feed FMan with more fragments than it supports. - * Btw, we're using the first sgt entry to store the linear part of diff --git a/target/linux/layerscape/patches-5.4/701-net-0011-dpaa_eth-ceetm-adapt-to-net-sched-API-changes.patch b/target/linux/layerscape/patches-5.4/701-net-0011-dpaa_eth-ceetm-adapt-to-net-sched-API-changes.patch deleted file mode 100644 index b7e970d341..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0011-dpaa_eth-ceetm-adapt-to-net-sched-API-changes.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 23057cf5bf562358918a219083a4b022d36c4b73 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 13 Jun 2017 14:40:54 +0300 -Subject: [PATCH] dpaa_eth: ceetm: adapt to net/sched API changes - -The tc_classify and tc_classify_compat calls have been merged. Adapt to -the new API. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -1839,7 +1839,7 @@ static struct ceetm_class *ceetm_classif - - *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; - tcf = priv->filter_list; -- while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) { -+ while (tcf && (result = tc_classify(skb, tcf, &res, false)) >= 0) { - #ifdef CONFIG_NET_CLS_ACT - switch (result) { - case TC_ACT_QUEUED: diff --git a/target/linux/layerscape/patches-5.4/701-net-0012-dpaa_eth-ceetm-adapt-to-the-new-gnet-stats-API.patch b/target/linux/layerscape/patches-5.4/701-net-0012-dpaa_eth-ceetm-adapt-to-the-new-gnet-stats-API.patch deleted file mode 100644 index 0580541da2..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0012-dpaa_eth-ceetm-adapt-to-the-new-gnet-stats-API.patch +++ /dev/null @@ -1,22 +0,0 @@ -From e7db22d2a5f57c41ec0a211b5d03b8768a173139 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 13 Jun 2017 16:26:00 +0300 -Subject: [PATCH] dpaa_eth: ceetm: adapt to the new gnet stats API - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -1759,7 +1759,8 @@ static int ceetm_cls_dump_stats(struct Q - } - } - -- if (gnet_stats_copy_basic(d, NULL, &tmp_bstats) < 0) -+ if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch), -+ d, NULL, &tmp_bstats) < 0) - return -1; - - if (cq && qman_ceetm_cq_get_dequeue_statistics(cq, 0, diff --git a/target/linux/layerscape/patches-5.4/701-net-0013-dpaa_eth-ceetm-update-include-paths-for-tc-filters.patch b/target/linux/layerscape/patches-5.4/701-net-0013-dpaa_eth-ceetm-update-include-paths-for-tc-filters.patch deleted file mode 100644 index d413739229..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0013-dpaa_eth-ceetm-update-include-paths-for-tc-filters.patch +++ /dev/null @@ -1,22 +0,0 @@ -From eb4edd5a72383c960801b2c3302036a1d3932775 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 13 Jun 2017 16:29:37 +0300 -Subject: [PATCH] dpaa_eth: ceetm: update include paths for tc filters - -The tcf_destroy_chain call prototype has been moved. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h -@@ -33,6 +33,7 @@ - #define __DPAA_ETH_CEETM_H - - #include -+#include - #include - #include - diff --git a/target/linux/layerscape/patches-5.4/701-net-0014-dpa_eth-remove-unused-code.patch b/target/linux/layerscape/patches-5.4/701-net-0014-dpa_eth-remove-unused-code.patch deleted file mode 100644 index 7d3ff7a7c4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0014-dpa_eth-remove-unused-code.patch +++ /dev/null @@ -1,87 +0,0 @@ -From fb2390ac7b8fc635bc136a400419fd3eec1d006f Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Wed, 7 Jun 2017 16:10:34 +0300 -Subject: [PATCH] dpa_eth: remove unused code - -Signed-off-by: Madalin Bucur ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.c | 58 ---------------------- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.h | 1 - - 2 files changed, 59 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c -@@ -165,64 +165,6 @@ _return_of_node_put: - } - EXPORT_SYMBOL(dpa_bp_probe); - --int dpa_bp_shared_port_seed(struct dpa_bp *bp) --{ -- void __iomem **ptr; -- -- /* In MAC-less and Shared-MAC scenarios the physical -- * address of the buffer pool in device tree is set -- * to 0 to specify that another entity (USDPAA) will -- * allocate and seed the buffers -- */ -- if (!bp->paddr) -- return 0; -- -- /* allocate memory region for buffers */ -- devm_request_mem_region(bp->dev, bp->paddr, -- bp->size * bp->config_count, KBUILD_MODNAME); -- /* managed ioremap unmapping */ -- ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); -- if (!ptr) -- return -EIO; --#ifndef CONFIG_PPC -- bp->vaddr = ioremap_cache_ns(bp->paddr, bp->size * bp->config_count); --#else -- bp->vaddr = ioremap_prot(bp->paddr, bp->size * bp->config_count, 0); --#endif -- if (bp->vaddr == NULL) { -- pr_err("Could not map memory for pool %d\n", bp->bpid); -- devres_free(ptr); -- return -EIO; -- } -- *ptr = bp->vaddr; -- devres_add(bp->dev, ptr); -- -- /* seed pool with buffers from that memory region */ -- if (bp->seed_pool) { -- int count = bp->target_count; -- dma_addr_t addr = bp->paddr; -- -- while (count) { -- struct bm_buffer bufs[8]; -- uint8_t num_bufs = 0; -- -- do { -- BUG_ON(addr > 0xffffffffffffull); -- bufs[num_bufs].bpid = bp->bpid; -- bm_buffer_set64(&bufs[num_bufs++], addr); -- addr += bp->size; -- -- } while (--count && (num_bufs < 8)); -- -- while (bman_release(bp->pool, bufs, num_bufs, 0)) -- cpu_relax(); -- } -- } -- -- return 0; --} --EXPORT_SYMBOL(dpa_bp_shared_port_seed); -- - int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp, - size_t count) - { ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h -@@ -45,6 +45,5 @@ struct dpa_bp * __cold __must_check /* _ - dpa_bp_probe(struct platform_device *_of_dev, size_t *count); - int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp, - size_t count); --int dpa_bp_shared_port_seed(struct dpa_bp *bp); - - #endif /* __DPAA_ETH_BASE_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0015-fmd-use-ptp-timer-for-Fman-RTC-node-name.patch b/target/linux/layerscape/patches-5.4/701-net-0015-fmd-use-ptp-timer-for-Fman-RTC-node-name.patch deleted file mode 100644 index 4a68c1f4ce..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0015-fmd-use-ptp-timer-for-Fman-RTC-node-name.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 7a31dff8328002acd4fdc76287bf9923c3392b02 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Sat, 17 Jun 2017 16:29:13 +0800 -Subject: [PATCH] fmd: use ptp-timer for Fman RTC node name - -Layerscape DPAA platforms have updated dts to use ptp-timer -instead of rtc for Fman RTC node name. This patch is to -update it in driver. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -@@ -684,9 +684,9 @@ static t_LnxWrpFmDev * ReadFmDevTreeNode - - /* Get the RTC base address and size */ - memset(ids, 0, sizeof(ids)); -- if (WARN_ON(strlen("rtc") >= sizeof(ids[0].name))) -+ if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name))) - return NULL; -- strcpy(ids[0].name, "rtc"); -+ strcpy(ids[0].name, "ptp-timer"); - if (WARN_ON(strlen("fsl,fman-rtc") >= sizeof(ids[0].compatible))) - return NULL; - strcpy(ids[0].compatible, "fsl,fman-rtc"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0016-dpaa_eth-use-ptp-timer-phandle-instead-of-ptimer-han.patch b/target/linux/layerscape/patches-5.4/701-net-0016-dpaa_eth-use-ptp-timer-phandle-instead-of-ptimer-han.patch deleted file mode 100644 index 6995700f3e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0016-dpaa_eth-use-ptp-timer-phandle-instead-of-ptimer-han.patch +++ /dev/null @@ -1,34 +0,0 @@ -From b022befd58e4f7306069c6d9831179e0c3a9b1b1 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Sat, 17 Jun 2017 16:16:58 +0800 -Subject: [PATCH] dpaa_eth: use ptp-timer phandle instead of ptimer-handle - -Layerscape DPAA platforms have updated dts to use ptp-timer phandle -instead of ptimer-handle for Fman RTC node. This patch is to -update it in driver. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -575,7 +575,7 @@ dpa_mac_probe(struct platform_device *_o - } - - #ifdef CONFIG_FSL_DPAA_1588 -- phandle_prop = of_get_property(mac_node, "ptimer-handle", &lenp); -+ phandle_prop = of_get_property(mac_node, "ptp-timer", &lenp); - if (phandle_prop && ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) || - ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) && - (mac_dev->speed == SPEED_1000)))) { -@@ -595,7 +595,7 @@ dpa_mac_probe(struct platform_device *_o - if ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) || - ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) && - (mac_dev->speed == SPEED_1000))) { -- ptp_priv.node = of_parse_phandle(mac_node, "ptimer-handle", 0); -+ ptp_priv.node = of_parse_phandle(mac_node, "ptp-timer", 0); - if (ptp_priv.node) { - ptp_priv.of_dev = of_find_device_by_node(ptp_priv.node); - if (unlikely(ptp_priv.of_dev == NULL)) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0017-dpaa_eth-move-global-variable-clock-into-ptp_priv_s-.patch b/target/linux/layerscape/patches-5.4/701-net-0017-dpaa_eth-move-global-variable-clock-into-ptp_priv_s-.patch deleted file mode 100644 index 617d3e5313..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0017-dpaa_eth-move-global-variable-clock-into-ptp_priv_s-.patch +++ /dev/null @@ -1,52 +0,0 @@ -From bbb23c33bbfc0fdb6098f0c61950f4a7c03379aa Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Mon, 19 Jun 2017 18:46:04 +0800 -Subject: [PATCH] dpaa_eth: move global variable 'clock' into ptp_priv_s struct - -This patch is to move global variable 'clock' for DPAA PTP -clock pointer into ptp_priv_s struct. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 1 + - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c | 5 +++-- - 2 files changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -669,6 +669,7 @@ static inline void _dpa_assign_wq(struct - struct ptp_priv_s { - struct device_node *node; - struct platform_device *of_dev; -+ struct ptp_clock *clock; - struct mac_device *mac_dev; - }; - extern struct ptp_priv_s ptp_priv; ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c -@@ -27,8 +27,6 @@ - #include "dpaa_eth.h" - #include "mac.h" - --struct ptp_clock *clock; -- - static struct mac_device *mac_dev; - static u32 freqCompensation; - -@@ -256,6 +254,7 @@ static int __init __cold dpa_ptp_load(vo - { - struct device *ptp_dev; - struct timespec64 now; -+ struct ptp_clock *clock = ptp_priv.clock; - int dpa_phc_index; - int err; - -@@ -283,6 +282,8 @@ module_init(dpa_ptp_load); - - static void __exit __cold dpa_ptp_unload(void) - { -+ struct ptp_clock *clock = ptp_priv.clock; -+ - if (mac_dev->fm_rtc_disable_interrupt) - mac_dev->fm_rtc_disable_interrupt(mac_dev->fm_dev, 0xffffffff); - ptp_clock_unregister(clock); diff --git a/target/linux/layerscape/patches-5.4/701-net-0018-sdk_dpaa-use-new-api-ethtool_ksettings_-get-set.patch b/target/linux/layerscape/patches-5.4/701-net-0018-sdk_dpaa-use-new-api-ethtool_ksettings_-get-set.patch deleted file mode 100644 index 0df382e7d9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0018-sdk_dpaa-use-new-api-ethtool_ksettings_-get-set.patch +++ /dev/null @@ -1,65 +0,0 @@ -From c77e142beed7241a1360f2dedbe34e2f697512c9 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Tue, 29 Aug 2017 09:51:45 +0300 -Subject: [PATCH] sdk_dpaa: use new api ethtool_ksettings_{get|set} - -Signed-off-by: Madalin Bucur ---- - .../net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c | 20 +++++++++----------- - 1 file changed, 9 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c -@@ -84,8 +84,8 @@ static char dpa_stats_global[][ETH_GSTRI - #define DPA_STATS_PERCPU_LEN ARRAY_SIZE(dpa_stats_percpu) - #define DPA_STATS_GLOBAL_LEN ARRAY_SIZE(dpa_stats_global) - --static int __cold dpa_get_settings(struct net_device *net_dev, -- struct ethtool_cmd *et_cmd) -+static int __cold dpa_get_ksettings(struct net_device *net_dev, -+ struct ethtool_link_ksettings *cmd) - { - int _errno; - struct dpa_priv_s *priv; -@@ -101,15 +101,13 @@ static int __cold dpa_get_settings(struc - return 0; - } - -- _errno = phy_ethtool_gset(priv->mac_dev->phy_dev, et_cmd); -- if (unlikely(_errno < 0)) -- netdev_err(net_dev, "phy_ethtool_gset() = %d\n", _errno); -+ phy_ethtool_ksettings_get(priv->mac_dev->phy_dev, cmd); - - return _errno; - } - --static int __cold dpa_set_settings(struct net_device *net_dev, -- struct ethtool_cmd *et_cmd) -+static int __cold dpa_set_ksettings(struct net_device *net_dev, -+ struct ethtool_link_ksettings *cmd) - { - int _errno; - struct dpa_priv_s *priv; -@@ -125,9 +123,9 @@ static int __cold dpa_set_settings(struc - return -ENODEV; - } - -- _errno = phy_ethtool_sset(priv->mac_dev->phy_dev, et_cmd); -+ _errno = phy_ethtool_ksettings_set(priv->mac_dev->phy_dev, cmd); - if (unlikely(_errno < 0)) -- netdev_err(net_dev, "phy_ethtool_sset() = %d\n", _errno); -+ netdev_err(net_dev, "phy_ethtool_ksettings_set() = %d\n", _errno); - - return _errno; - } -@@ -522,8 +520,8 @@ static void dpa_get_strings(struct net_d - } - - const struct ethtool_ops dpa_ethtool_ops = { -- .get_settings = dpa_get_settings, -- .set_settings = dpa_set_settings, -+ .get_link_ksettings = dpa_get_ksettings, -+ .set_link_ksettings = dpa_set_ksettings, - .get_drvinfo = dpa_get_drvinfo, - .get_msglevel = dpa_get_msglevel, - .set_msglevel = dpa_set_msglevel, diff --git a/target/linux/layerscape/patches-5.4/701-net-0019-sdk_dpaa-fix-dpa_set_ksettings.patch b/target/linux/layerscape/patches-5.4/701-net-0019-sdk_dpaa-fix-dpa_set_ksettings.patch deleted file mode 100644 index 432591e88d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0019-sdk_dpaa-fix-dpa_set_ksettings.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 3ffb14b6f3ddd9d8befe08482e31bc34103cf953 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Thu, 31 Aug 2017 09:08:15 +0300 -Subject: [PATCH] sdk_dpaa: fix dpa_set_ksettings - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c -@@ -107,7 +107,7 @@ static int __cold dpa_get_ksettings(stru - } - - static int __cold dpa_set_ksettings(struct net_device *net_dev, -- struct ethtool_link_ksettings *cmd) -+ const struct ethtool_link_ksettings *cmd) - { - int _errno; - struct dpa_priv_s *priv; diff --git a/target/linux/layerscape/patches-5.4/701-net-0020-dpaa_eth-memac-set-adjust_link-callback-for-fixed-li.patch b/target/linux/layerscape/patches-5.4/701-net-0020-dpaa_eth-memac-set-adjust_link-callback-for-fixed-li.patch deleted file mode 100644 index c2a76ae657..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0020-dpaa_eth-memac-set-adjust_link-callback-for-fixed-li.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 47113bd7cb07c2399f536a2dd8f4b3a6c599dfcd Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Thu, 31 Aug 2017 13:16:47 +0300 -Subject: [PATCH] dpaa_eth: memac: set adjust_link callback for fixed link - interfaces - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c -@@ -503,11 +503,9 @@ static int memac_init_phy(struct net_dev - { - struct phy_device *phy_dev; - -- if (of_phy_is_fixed_link(mac_dev->phy_node)) { -- phy_dev = of_phy_attach(net_dev, mac_dev->phy_node, -- 0, mac_dev->phy_if); -- } else if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) || -- (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500)) { -+ if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) || -+ (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500) || -+ of_phy_is_fixed_link(mac_dev->phy_node)) { - phy_dev = of_phy_connect(net_dev, mac_dev->phy_node, - &adjust_link_void, 0, - mac_dev->phy_if); diff --git a/target/linux/layerscape/patches-5.4/701-net-0021-sdk_dpaa-ls1043a-errata-resplit-the-skb-after-copy.patch b/target/linux/layerscape/patches-5.4/701-net-0021-sdk_dpaa-ls1043a-errata-resplit-the-skb-after-copy.patch deleted file mode 100644 index a9512cc808..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0021-sdk_dpaa-ls1043a-errata-resplit-the-skb-after-copy.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 3532c45dc451d2bb7d88a33a554a86422828c9aa Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Thu, 13 Jul 2017 17:26:02 +0300 -Subject: [PATCH] sdk_dpaa: ls1043a errata: resplit the skb after copy - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -1016,6 +1016,7 @@ int __hot dpa_tx_extended(struct sk_buff - #endif /* CONFIG_FSL_DPAA_TS */ - - #ifndef CONFIG_PPC -+resplit_4k: - if (unlikely(dpaa_errata_a010022)) { - skb = split_skb_at_4k_boundaries(skb); - if (!skb) -@@ -1062,6 +1063,10 @@ int __hot dpa_tx_extended(struct sk_buff - struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC); - kfree_skb(skb); - skb = nskb; -+#ifndef CONFIG_PPC -+ if (unlikely(dpaa_errata_a010022)) -+ goto resplit_4k; -+#endif - /* skb_copy() has now linearized the skbuff. */ - } else if (unlikely(nonlinear)) { - /* We are here because the egress skb contains diff --git a/target/linux/layerscape/patches-5.4/701-net-0022-sdk_dpaa-ls1043a-errata-realign-and-linearize-egress.patch b/target/linux/layerscape/patches-5.4/701-net-0022-sdk_dpaa-ls1043a-errata-realign-and-linearize-egress.patch deleted file mode 100644 index 3e89b3d7b6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0022-sdk_dpaa-ls1043a-errata-realign-and-linearize-egress.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 9821d27a36704d19c57d4b6c52585b9868703633 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 4 Sep 2017 13:41:17 +0300 -Subject: [PATCH] sdk_dpaa: ls1043a errata: realign and linearize egress skbs - -Allocate a new page and copy the skb's contents to it in order to -guarantee that 4k boundary crossings do not occur. - -Signed-off-by: Camelia Groza ---- - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 159 +++++++++++---------- - 1 file changed, 84 insertions(+), 75 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -742,86 +742,94 @@ int __hot skb_to_contig_fd(struct dpa_pr - EXPORT_SYMBOL(skb_to_contig_fd); - - #ifndef CONFIG_PPC --struct sk_buff *split_skb_at_4k_boundaries(struct sk_buff *skb) -+/* Verify the conditions that trigger the A010022 errata: 4K memory address -+ * crossings. -+ */ -+bool a010022_check_skb(struct sk_buff *skb) - { -- unsigned int length, nr_frags, moved_len = 0; -- u64 page_start; -- struct page *page; -+ int nr_frags, i = 0; - skb_frag_t *frag; -- int i = 0, j = 0; - -- /* make sure skb is not shared */ -- skb = skb_share_check(skb, GFP_ATOMIC); -- if (!skb) -- return NULL; -+ /* Check if the headroom crosses a boundary */ -+ if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb))) -+ return true; -+ -+ /* Check if the non-paged data crosses a boundary */ -+ if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb))) -+ return true; -+ -+ /* Check if the entire linear skb crosses a boundary */ -+ if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb))) -+ return true; - - nr_frags = skb_shinfo(skb)->nr_frags; -- page_start = (u64)skb->data; - -- /* split the linear part at the first 4k boundary and create one (big) -- * fragment with the rest -- */ -- if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb))) { -- /* we'll add one more frag, make sure there's room */ -- if (nr_frags + 1 > DPA_SGT_MAX_ENTRIES) -- return NULL; -- -- /* next page boundary */ -- page_start = (page_start + 0x1000) & ~0xFFF; -- page = virt_to_page(page_start); -- -- /* move the rest of fragments to make room for a new one at j */ -- for (i = nr_frags - 1; i >= j; i--) -- skb_shinfo(skb)->frags[i + 1] = skb_shinfo(skb)->frags[i]; -- -- /* move length bytes to a paged fragment at j */ -- length = min((u64)0x1000, -- (u64)skb->data + skb_headlen(skb) - page_start); -- skb->data_len += length; -- moved_len += length; -- skb_fill_page_desc(skb, j++, page, 0, length); -- get_page(page); -- skb_shinfo(skb)->nr_frags = ++nr_frags; -+ while (i < nr_frags) { -+ frag = &skb_shinfo(skb)->frags[i]; -+ -+ /* Check if the paged fragment crosses a boundary from its -+ * offset to its end. -+ */ -+ if (HAS_DMA_ISSUE(frag->page_offset, frag->size)) -+ return true; -+ -+ i++; - } -- /* adjust the tail pointer */ -- skb->tail -= moved_len; -- j = 0; -- -- /* split any paged fragment that crosses a 4K boundary */ -- while (j < nr_frags) { -- frag = &skb_shinfo(skb)->frags[j]; -- -- /* if there is a 4K boundary between the fragment's offset and end */ -- if (HAS_DMA_ISSUE(frag->page_offset, frag->size)) { -- /* we'll add one more frag, make sure there's room */ -- if (nr_frags + 1 > DPA_SGT_MAX_ENTRIES) -- return NULL; -- -- /* new page boundary */ -- page_start = (u64)page_address(skb_frag_page(frag)) + -- frag->page_offset + 0x1000; -- page_start = (u64)page_start & ~0xFFF; -- page = virt_to_page(page_start); -- -- /* move the rest of fragments to make room for a new one at j+1 */ -- for (i = nr_frags - 1; i > j; i--) -- skb_shinfo(skb)->frags[i + 1] = -- skb_shinfo(skb)->frags[i]; -- -- /* move length bytes to a new paged fragment at j+1 */ -- length = (u64)page_address(skb_frag_page(frag)) + -- frag->page_offset + frag->size - page_start; -- frag->size -= length; -- skb_fill_page_desc(skb, j + 1, page, 0, length); -- get_page(page); -- skb_shinfo(skb)->nr_frags = ++nr_frags; -- } - -- /* move to next frag */ -- j++; -+ return false; -+} -+ -+/* Realign the skb by copying its contents at the start of a newly allocated -+ * page. Build a new skb around the new buffer and release the old one. -+ * A performance drop should be expected. -+ */ -+struct sk_buff *a010022_realign_skb(struct sk_buff *skb) -+{ -+ int headroom = skb_headroom(skb); -+ struct sk_buff *nskb = NULL; -+ struct page *npage; -+ void *npage_addr; -+ int nsize; -+ -+ npage = alloc_page(GFP_ATOMIC); -+ if (unlikely(!npage)) { -+ WARN_ONCE(1, "Memory allocation failure\n"); -+ return NULL; -+ } -+ npage_addr = page_address(npage); -+ -+ /* For the new skb we only need the old one's data (both non-paged and -+ * paged) and a headroom large enough to fit our private info. We can -+ * skip the old tailroom. -+ * -+ * Make sure the new linearized buffer will not exceed a page's size. -+ */ -+ nsize = headroom + skb->len + -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ if (unlikely(nsize > 4096)) -+ goto err; -+ -+ nskb = build_skb(npage_addr, nsize); -+ if (unlikely(!nskb)) -+ goto err; -+ -+ /* Code borrowed and adapted from skb_copy() */ -+ skb_reserve(nskb, headroom); -+ skb_put(nskb, skb->len); -+ if (skb_copy_bits(skb, 0, nskb->data, skb->len)) { -+ WARN_ONCE(1, "skb parsing failure\n"); -+ goto err; - } -+ copy_skb_header(nskb, skb); -+ -+ dev_kfree_skb(skb); -+ return nskb; - -- return skb; -+err: -+ if (nskb) -+ dev_kfree_skb(nskb); -+ put_page(npage); -+ return NULL; - } - #endif - -@@ -1016,9 +1024,9 @@ int __hot dpa_tx_extended(struct sk_buff - #endif /* CONFIG_FSL_DPAA_TS */ - - #ifndef CONFIG_PPC --resplit_4k: -- if (unlikely(dpaa_errata_a010022)) { -- skb = split_skb_at_4k_boundaries(skb); -+realign_4k: -+ if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb)) { -+ skb = a010022_realign_skb(skb); - if (!skb) - goto skb_to_fd_failed; - } -@@ -1064,8 +1072,9 @@ resplit_4k: - kfree_skb(skb); - skb = nskb; - #ifndef CONFIG_PPC -- if (unlikely(dpaa_errata_a010022)) -- goto resplit_4k; -+ if (unlikely(dpaa_errata_a010022) && -+ a010022_check_skb(skb)) -+ goto realign_4k; - #endif - /* skb_copy() has now linearized the skbuff. */ - } else if (unlikely(nonlinear)) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0023-sdk_dpaa-ls1043a-errata-realign-skb-in-place-if-need.patch b/target/linux/layerscape/patches-5.4/701-net-0023-sdk_dpaa-ls1043a-errata-realign-skb-in-place-if-need.patch deleted file mode 100644 index 1eda4aee46..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0023-sdk_dpaa-ls1043a-errata-realign-skb-in-place-if-need.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 5a2ba8a9c6b2686aa94a8d5ac35beddf38cba24a Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 4 Sep 2017 13:46:00 +0300 -Subject: [PATCH] sdk_dpaa: ls1043a errata: realign skb in place if needed - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -1024,7 +1024,6 @@ int __hot dpa_tx_extended(struct sk_buff - #endif /* CONFIG_FSL_DPAA_TS */ - - #ifndef CONFIG_PPC --realign_4k: - if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb)) { - skb = a010022_realign_skb(skb); - if (!skb) -@@ -1073,8 +1072,11 @@ realign_4k: - skb = nskb; - #ifndef CONFIG_PPC - if (unlikely(dpaa_errata_a010022) && -- a010022_check_skb(skb)) -- goto realign_4k; -+ a010022_check_skb(skb)) { -+ skb = realign_skb(skb); -+ if (!skb) -+ goto skb_to_fd_failed; -+ } - #endif - /* skb_copy() has now linearized the skbuff. */ - } else if (unlikely(nonlinear)) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0024-sdk_dpaa-ls1043a-errata-verify-and-resize-headroom-a.patch b/target/linux/layerscape/patches-5.4/701-net-0024-sdk_dpaa-ls1043a-errata-verify-and-resize-headroom-a.patch deleted file mode 100644 index 6014de951f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0024-sdk_dpaa-ls1043a-errata-verify-and-resize-headroom-a.patch +++ /dev/null @@ -1,106 +0,0 @@ -From f6413a7e32d1f98a258e0ed9abd4df3159902fd3 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 4 Sep 2017 13:57:21 +0300 -Subject: [PATCH] sdk_dpaa: ls1043a errata: verify and resize headroom - alignment - -If the skb's headroom isn't aligned to 16 bytes, reallocate the entire -skb and resize its headroom to priv->tx_headroom. Update the pointers -to the network and transport headers accordingly. - -Signed-off-by: Camelia Groza ---- - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 38 +++++++++++++++------- - 1 file changed, 27 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -742,14 +742,19 @@ int __hot skb_to_contig_fd(struct dpa_pr - EXPORT_SYMBOL(skb_to_contig_fd); - - #ifndef CONFIG_PPC --/* Verify the conditions that trigger the A010022 errata: 4K memory address -- * crossings. -+/* Verify the conditions that trigger the A010022 errata: data unaligned to -+ * 16 bytes and 4K memory address crossings. - */ --bool a010022_check_skb(struct sk_buff *skb) -+static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv) - { - int nr_frags, i = 0; - skb_frag_t *frag; - -+ /* Check if the headroom is aligned */ -+ if (((u16)skb->data - priv->tx_headroom) % -+ priv->buf_layout[TX].data_align != 0) -+ return true; -+ - /* Check if the headroom crosses a boundary */ - if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb))) - return true; -@@ -767,7 +772,7 @@ bool a010022_check_skb(struct sk_buff *s - while (i < nr_frags) { - frag = &skb_shinfo(skb)->frags[i]; - -- /* Check if the paged fragment crosses a boundary from its -+ /* Check if a paged fragment crosses a boundary from its - * offset to its end. - */ - if (HAS_DMA_ISSUE(frag->page_offset, frag->size)) -@@ -783,13 +788,17 @@ bool a010022_check_skb(struct sk_buff *s - * page. Build a new skb around the new buffer and release the old one. - * A performance drop should be expected. - */ --struct sk_buff *a010022_realign_skb(struct sk_buff *skb) -+static struct sk_buff *a010022_realign_skb(struct sk_buff *skb, -+ struct dpa_priv_s *priv) - { -- int headroom = skb_headroom(skb); -+ int trans_offset = skb_transport_offset(skb); -+ int net_offset = skb_network_offset(skb); - struct sk_buff *nskb = NULL; -+ int nsize, headroom; - struct page *npage; - void *npage_addr; -- int nsize; -+ -+ headroom = priv->tx_headroom; - - npage = alloc_page(GFP_ATOMIC); - if (unlikely(!npage)) { -@@ -822,6 +831,13 @@ struct sk_buff *a010022_realign_skb(stru - } - copy_skb_header(nskb, skb); - -+ /* We move the headroom when we align it so we have to reset the -+ * network and transport header offsets relative to the new data -+ * pointer. The checksum offload relies on these offsets. -+ */ -+ skb_set_network_header(nskb, net_offset); -+ skb_set_transport_header(nskb, trans_offset); -+ - dev_kfree_skb(skb); - return nskb; - -@@ -1024,8 +1040,8 @@ int __hot dpa_tx_extended(struct sk_buff - #endif /* CONFIG_FSL_DPAA_TS */ - - #ifndef CONFIG_PPC -- if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb)) { -- skb = a010022_realign_skb(skb); -+ if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) { -+ skb = a010022_realign_skb(skb, priv); - if (!skb) - goto skb_to_fd_failed; - } -@@ -1072,8 +1088,8 @@ int __hot dpa_tx_extended(struct sk_buff - skb = nskb; - #ifndef CONFIG_PPC - if (unlikely(dpaa_errata_a010022) && -- a010022_check_skb(skb)) { -- skb = realign_skb(skb); -+ a010022_check_skb(skb, priv)) { -+ skb = a010022_realign_skb(skb, priv); - if (!skb) - goto skb_to_fd_failed; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0025-sdk_dpaa-ls1043a-errata-do-not-recycle-the-realigned.patch b/target/linux/layerscape/patches-5.4/701-net-0025-sdk_dpaa-ls1043a-errata-do-not-recycle-the-realigned.patch deleted file mode 100644 index 4030385be5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0025-sdk_dpaa-ls1043a-errata-do-not-recycle-the-realigned.patch +++ /dev/null @@ -1,61 +0,0 @@ -From e8c0a77a831843a66b3ac0048aa6c76bc39b0332 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 4 Sep 2017 14:03:01 +0300 -Subject: [PATCH] sdk_dpaa: ls1043a errata: do not recycle the realigned - buffers - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 10 ++++++---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 9 +++++++++ - 2 files changed, 15 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -680,15 +680,17 @@ static inline void _dpa_bp_free_pf(void - put_page(virt_to_head_page(addr)); - } - --/* TODO: LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue -- * manifests itself at high traffic rates when frames exceed 4K memory -- * boundaries; For the moment, we use a SW workaround to avoid frames larger -- * than 4K or that exceed 4K alignments. -+/* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue -+ * manifests itself at high traffic rates when frames cross 4K memory -+ * boundaries or when they are not aligned to 16 bytes; For the moment, we -+ * use a SW workaround to avoid frames larger than 4K or that exceed 4K -+ * alignments and to realign the frames to 16 bytes. - */ - - #ifndef CONFIG_PPC - extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */ - -+#define NONREC_MARK 0x01 - #define HAS_DMA_ISSUE(start, size) \ - (((u64)(start) + (size)) > (((u64)(start) + 0x1000) & ~0xFFF)) - #define BOUNDARY_4K(start, size) (((u64)(start) + (u64)(size)) & ~0xFFF) ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -302,6 +302,12 @@ EXPORT_SYMBOL(_dpa_cleanup_tx_fd); - #ifndef CONFIG_FSL_DPAA_TS - bool dpa_skb_is_recyclable(struct sk_buff *skb) - { -+#ifndef CONFIG_PPC -+ /* Do no recycle skbs realigned by the errata workaround */ -+ if (unlikely(dpaa_errata_a010022) && skb->mark == NONREC_MARK) -+ return false; -+#endif -+ - /* No recycling possible if skb buffer is kmalloc'ed */ - if (skb->head_frag == 0) - return false; -@@ -838,6 +844,9 @@ static struct sk_buff *a010022_realign_s - skb_set_network_header(nskb, net_offset); - skb_set_transport_header(nskb, trans_offset); - -+ /* We don't want the buffer to be recycled so we mark it accordingly */ -+ nskb->mark = NONREC_MARK; -+ - dev_kfree_skb(skb); - return nskb; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0026-sdk_dpaa-ls1043a-errata-fix-arm32-build.patch b/target/linux/layerscape/patches-5.4/701-net-0026-sdk_dpaa-ls1043a-errata-fix-arm32-build.patch deleted file mode 100644 index 3799f8ac37..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0026-sdk_dpaa-ls1043a-errata-fix-arm32-build.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 211d0b5127a468cf0e2db20b4854252e6784cf08 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 4 Sep 2017 14:35:21 +0300 -Subject: [PATCH] sdk_dpaa: ls1043a errata: fix arm32 build - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 6 ++---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 2 +- - 2 files changed, 3 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -689,12 +689,10 @@ static inline void _dpa_bp_free_pf(void - - #ifndef CONFIG_PPC - extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */ -- - #define NONREC_MARK 0x01 - #define HAS_DMA_ISSUE(start, size) \ -- (((u64)(start) + (size)) > (((u64)(start) + 0x1000) & ~0xFFF)) --#define BOUNDARY_4K(start, size) (((u64)(start) + (u64)(size)) & ~0xFFF) -- -+ (((uintptr_t)(start) + (size)) > \ -+ (((uintptr_t)(start) + 0x1000) & ~0xFFF)) - #endif /* !CONFIG_PPC */ - - #endif /* __DPA_H */ ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -757,7 +757,7 @@ static bool a010022_check_skb(struct sk_ - skb_frag_t *frag; - - /* Check if the headroom is aligned */ -- if (((u16)skb->data - priv->tx_headroom) % -+ if (((uintptr_t)skb->data - priv->tx_headroom) % - priv->buf_layout[TX].data_align != 0) - return true; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0027-drivers-staging-fsl_qbman-Fix-SWP-Mask-in-Error-Hand.patch b/target/linux/layerscape/patches-5.4/701-net-0027-drivers-staging-fsl_qbman-Fix-SWP-Mask-in-Error-Hand.patch deleted file mode 100644 index 7d04535973..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0027-drivers-staging-fsl_qbman-Fix-SWP-Mask-in-Error-Hand.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 456090fba3aabfe929be7532dbac9de82918e2ad Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Tue, 5 Sep 2017 16:47:49 -0400 -Subject: [PATCH] drivers/staging/fsl_qbman: Fix SWP Mask in Error Handling - -If an ECC error occurs QBMan stores data in a register for -debug purposes. If the memory is software portal memory then -15 bits are used. This patch adjusts the mask to be correct. - -Signed-off-by: Roy Pledge ---- - drivers/staging/fsl_qbman/qman_config.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/fsl_qbman/qman_config.c -+++ b/drivers/staging/fsl_qbman/qman_config.c -@@ -254,7 +254,7 @@ static const struct qman_error_info_mdat - QMAN_ERR_MDATA(0x01FF, 72, "WQ context memory"), - QMAN_ERR_MDATA(0x00FF, 240, "CGR memory"), - QMAN_ERR_MDATA(0x00FF, 302, "Internal Order Restoration List memory"), -- QMAN_ERR_MDATA(0x01FF, 256, "SW portal ring memory"), -+ QMAN_ERR_MDATA(0x7FFF, 256, "SW portal ring memory"), - QMAN_ERR_MDATA(0x07FF, 181, "CEETM class queue descriptor memory"), - QMAN_ERR_MDATA(0x0FFF, 140, "CEETM extended SFDR memory"), - QMAN_ERR_MDATA(0x0FFF, 25, "CEETM logical FQ mapping memory"), diff --git a/target/linux/layerscape/patches-5.4/701-net-0028-sdk_dpaa-avoid-crashing-on-OOM.patch b/target/linux/layerscape/patches-5.4/701-net-0028-sdk_dpaa-avoid-crashing-on-OOM.patch deleted file mode 100644 index 3e42322d63..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0028-sdk_dpaa-avoid-crashing-on-OOM.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 8254c87e00992f6b14472076f435cba52ad9ff9d Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Thu, 31 Aug 2017 17:42:07 +0300 -Subject: [PATCH] sdk_dpaa: avoid crashing on OOM - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -100,8 +100,12 @@ static int _dpa_bp_add_8_bufs(const stru - * an entire cacheline for performance reasons. - */ - #ifndef CONFIG_PPC -- if (unlikely(dpaa_errata_a010022)) -- new_buf = page_address(alloc_page(GFP_ATOMIC)); -+ if (unlikely(dpaa_errata_a010022)) { -+ struct page *new_page = alloc_page(GFP_ATOMIC); -+ if (unlikely(!new_page)) -+ goto netdev_alloc_failed; -+ new_buf = page_address(new_page); -+ } - else - #endif - new_buf = netdev_alloc_frag(SMP_CACHE_BYTES + DPA_BP_RAW_SIZE); diff --git a/target/linux/layerscape/patches-5.4/701-net-0029-sdk_dpaa-update-the-xmit-timestamp-to-avoid-watchdog.patch b/target/linux/layerscape/patches-5.4/701-net-0029-sdk_dpaa-update-the-xmit-timestamp-to-avoid-watchdog.patch deleted file mode 100644 index 044e7013a0..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0029-sdk_dpaa-update-the-xmit-timestamp-to-avoid-watchdog.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 7207c6eaead4fbcf6dfec2a185550cd30aba5071 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Thu, 7 Sep 2017 14:49:09 +0300 -Subject: [PATCH] sdk_dpaa: update the xmit timestamp to avoid watchdog - timeouts - -Update txq0's trans_start in order to prevent the netdev watchdog from -triggering too quickly. Since we set the LLTX flag, the stack won't update -the jiffies for other tx queues. Prevent the watchdog from checking the -other tx queues by adding the NETIF_HW_ACCEL_MQ flag. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 3 +++ - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 1 + - include/linux/netdev_features.h | 2 ++ - net/sched/sch_generic.c | 7 +++++++ - 4 files changed, 13 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -@@ -772,6 +772,9 @@ static int dpa_private_netdev_init(struc - /* Advertise GRO support */ - net_dev->features |= NETIF_F_GRO; - -+ /* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */ -+ net_dev->features |= NETIF_F_HW_ACCEL_MQ; -+ - return dpa_netdev_init(net_dev, mac_addr, tx_timeout); - } - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -1140,6 +1140,7 @@ int __hot dpa_tx_extended(struct sk_buff - if (unlikely(dpa_xmit(priv, percpu_stats, &fd, egress_fq, conf_fq) < 0)) - goto xmit_failed; - -+ netif_trans_update(net_dev); - return NETDEV_TX_OK; - - xmit_failed: ---- a/include/linux/netdev_features.h -+++ b/include/linux/netdev_features.h -@@ -77,6 +77,7 @@ enum { - NETIF_F_RX_UDP_TUNNEL_PORT_BIT, /* Offload of RX port for UDP tunnels */ - NETIF_F_HW_TLS_TX_BIT, /* Hardware TLS TX offload */ - NETIF_F_HW_TLS_RX_BIT, /* Hardware TLS RX offload */ -+ NETIF_F_HW_ACCEL_MQ_BIT, /* Hardware-accelerated multiqueue */ - - NETIF_F_GRO_HW_BIT, /* Hardware Generic receive offload */ - NETIF_F_HW_TLS_RECORD_BIT, /* Offload TLS record */ -@@ -150,6 +151,7 @@ enum { - #define NETIF_F_GSO_UDP_L4 __NETIF_F(GSO_UDP_L4) - #define NETIF_F_HW_TLS_TX __NETIF_F(HW_TLS_TX) - #define NETIF_F_HW_TLS_RX __NETIF_F(HW_TLS_RX) -+#define NETIF_F_HW_ACCEL_MQ __NETIF_F(HW_ACCEL_MQ) - - /* Finds the next feature with the highest number of the range of start till 0. - */ ---- a/net/sched/sch_generic.c -+++ b/net/sched/sch_generic.c -@@ -465,6 +465,13 @@ static void dev_watchdog(struct timer_li - txq->trans_timeout++; - break; - } -+ -+ /* Devices with HW_ACCEL_MQ have multiple txqs -+ * but update only the first one's transmission -+ * timestamp so avoid checking the rest. -+ */ -+ if (dev->features & NETIF_F_HW_ACCEL_MQ) -+ break; - } - - if (some_queue_timedout) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0030-sdk_fman-resolve-arm32-compilation-issues-for-linux-.patch b/target/linux/layerscape/patches-5.4/701-net-0030-sdk_fman-resolve-arm32-compilation-issues-for-linux-.patch deleted file mode 100644 index 6c0db1eadc..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0030-sdk_fman-resolve-arm32-compilation-issues-for-linux-.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 1a1f2bd221d72f8e4fcb66b6b6763a158965f746 Mon Sep 17 00:00:00 2001 -From: Iordache Florinel-R70177 -Date: Mon, 11 Sep 2017 16:10:58 +0300 -Subject: [PATCH] sdk_fman: resolve arm32 compilation issues for linux-4.13 - -Signed-off-by: Iordache Florinel-R70177 ---- - drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c | 2 ++ - .../ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c | 2 ++ - .../ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c | 2 ++ - drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c | 2 ++ - drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c | 2 ++ - drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c | 2 ++ - 6 files changed, 12 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c -@@ -31,6 +31,8 @@ - */ - - -+#include "std_ext.h" -+#include "error_ext.h" - #include "fsl_fman_dtsec.h" - - ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c -@@ -31,6 +31,8 @@ - */ - - -+#include "std_ext.h" -+#include "error_ext.h" - #include "common/general.h" - #include "fsl_fman_dtsec_mii_acc.h" - ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c -@@ -31,6 +31,8 @@ - */ - - -+#include "std_ext.h" -+#include "error_ext.h" - #include "fsl_fman_memac_mii_acc.h" - - static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs, ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c -@@ -30,6 +30,8 @@ - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -+#include "std_ext.h" -+#include "error_ext.h" - #include "fsl_fman_kg.h" - - /****************************************/ ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c -@@ -31,6 +31,8 @@ - */ - - -+#include "std_ext.h" -+#include "error_ext.h" - #include "common/general.h" - - #include "fman_common.h" ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c -@@ -31,6 +31,8 @@ - */ - - -+#include "std_ext.h" -+#include "error_ext.h" - #include - #include "fsl_fman.h" - #include "dpaa_integration_ext.h" diff --git a/target/linux/layerscape/patches-5.4/701-net-0031-sdk_dpaa-ls1043a-errata-maintain-timestamp-info.patch b/target/linux/layerscape/patches-5.4/701-net-0031-sdk_dpaa-ls1043a-errata-maintain-timestamp-info.patch deleted file mode 100644 index e7fd78cae1..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0031-sdk_dpaa-ls1043a-errata-maintain-timestamp-info.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 2af4c8f51e2a55173f412ea51d5715378bba15be Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Thu, 14 Sep 2017 10:40:53 +0300 -Subject: [PATCH] sdk_dpaa: ls1043a errata: maintain timestamp info - -When creating a new skb for the errata workaround, maintain the socket -and timestamp configurations for timestamp hardware offloading. - -Signed-off-by: Camelia Groza ---- - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 44 +++++++++++++++------- - 1 file changed, 31 insertions(+), 13 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -42,6 +42,7 @@ - #include - #include - #include -+#include - - #include "dpaa_eth.h" - #include "dpaa_eth_common.h" -@@ -808,7 +809,11 @@ static struct sk_buff *a010022_realign_s - struct page *npage; - void *npage_addr; - -- headroom = priv->tx_headroom; -+ /* Guarantee the minimum required headroom */ -+ if (skb_headroom(skb) >= priv->tx_headroom) -+ headroom = skb_headroom(skb); -+ else -+ headroom = priv->tx_headroom; - - npage = alloc_page(GFP_ATOMIC); - if (unlikely(!npage)) { -@@ -832,8 +837,11 @@ static struct sk_buff *a010022_realign_s - if (unlikely(!nskb)) - goto err; - -- /* Code borrowed and adapted from skb_copy() */ -- skb_reserve(nskb, headroom); -+ /* Reserve only the needed headroom in order to guarantee the data's -+ * alignment. -+ * Code borrowed and adapted from skb_copy(). -+ */ -+ skb_reserve(nskb, priv->tx_headroom); - skb_put(nskb, skb->len); - if (skb_copy_bits(skb, 0, nskb->data, skb->len)) { - WARN_ONCE(1, "skb parsing failure\n"); -@@ -841,6 +849,16 @@ static struct sk_buff *a010022_realign_s - } - copy_skb_header(nskb, skb); - -+#ifdef CONFIG_FSL_DPAA_TS -+ /* Copy relevant timestamp info from the old skb to the new */ -+ if (priv->ts_tx_en) { -+ skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags; -+ skb_shinfo(nskb)->hwtstamps = skb_shinfo(skb)->hwtstamps; -+ skb_shinfo(nskb)->tskey = skb_shinfo(skb)->tskey; -+ if (skb->sk) -+ skb_set_owner_w(nskb, skb->sk); -+ } -+#endif - /* We move the headroom when we align it so we have to reset the - * network and transport header offsets relative to the new data - * pointer. The checksum offload relies on these offsets. -@@ -1041,6 +1059,16 @@ int __hot dpa_tx_extended(struct sk_buff - - clear_fd(&fd); - -+#ifndef CONFIG_PPC -+ if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) { -+ skb = a010022_realign_skb(skb, priv); -+ if (!skb) -+ goto skb_to_fd_failed; -+ } -+#endif -+ -+ nonlinear = skb_is_nonlinear(skb); -+ - #ifdef CONFIG_FSL_DPAA_1588 - if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl) - fd.cmd |= FM_FD_CMD_UPD; -@@ -1052,16 +1080,6 @@ int __hot dpa_tx_extended(struct sk_buff - skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; - #endif /* CONFIG_FSL_DPAA_TS */ - --#ifndef CONFIG_PPC -- if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) { -- skb = a010022_realign_skb(skb, priv); -- if (!skb) -- goto skb_to_fd_failed; -- } --#endif -- -- nonlinear = skb_is_nonlinear(skb); -- - /* MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure - * we don't feed FMan with more fragments than it supports. - * Btw, we're using the first sgt entry to store the linear part of diff --git a/target/linux/layerscape/patches-5.4/701-net-0032-sdk_dpaa-ls1043a-errata-restrict-the-max-mtu.patch b/target/linux/layerscape/patches-5.4/701-net-0032-sdk_dpaa-ls1043a-errata-restrict-the-max-mtu.patch deleted file mode 100644 index 7b70452a08..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0032-sdk_dpaa-ls1043a-errata-restrict-the-max-mtu.patch +++ /dev/null @@ -1,33 +0,0 @@ -From b204d76e9a64ec99f0151b7ca018f3b6df2bb1b7 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 19 Sep 2017 11:30:50 +0300 -Subject: [PATCH] sdk_dpaa: ls1043a errata: restrict the max mtu - -We can not allow for Jumbo frames and large MTU values on LS1043A due to -the A-010022 FMan errata. All outgoing frames larger than 4K bytes are dropped. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -263,7 +263,16 @@ EXPORT_SYMBOL(dpa_get_stats64); - - int dpa_change_mtu(struct net_device *net_dev, int new_mtu) - { -- const int max_mtu = dpa_get_max_mtu(); -+ int max_mtu = dpa_get_max_mtu(); -+ -+#ifndef CONFIG_PPC -+ /* Due to the A010022 FMan errata, we can not use contig frames larger -+ * than 4K, nor S/G frames. We need to prevent the user from setting a -+ * large MTU. -+ */ -+ if (unlikely(dpaa_errata_a010022)) -+ max_mtu = DPA_BP_RAW_SIZE; -+#endif - - /* Make sure we don't exceed the Ethernet controller's MAXFRM */ - if (new_mtu < 68 || new_mtu > max_mtu) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0033-sdk_dpaa-adapt-to-the-new-API-for-MTU-changes.patch b/target/linux/layerscape/patches-5.4/701-net-0033-sdk_dpaa-adapt-to-the-new-API-for-MTU-changes.patch deleted file mode 100644 index a69e4c51c5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0033-sdk_dpaa-adapt-to-the-new-API-for-MTU-changes.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 828ec34f1fade88f1e751b7000959aaddfe44e5c Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Thu, 21 Sep 2017 10:50:57 +0300 -Subject: [PATCH] sdk_dpaa: adapt to the new API for MTU changes - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 14 +++++++++++- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 25 ---------------------- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 1 - - 3 files changed, 13 insertions(+), 27 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -@@ -681,7 +681,6 @@ static const struct net_device_ops dpa_p - #ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE - .ndo_select_queue = dpa_select_queue, - #endif -- .ndo_change_mtu = dpa_change_mtu, - .ndo_set_rx_mode = dpa_set_rx_mode, - .ndo_init = dpa_ndo_init, - .ndo_set_features = dpa_set_features, -@@ -758,6 +757,19 @@ static int dpa_private_netdev_init(struc - net_dev->mem_start = priv->mac_dev->res->start; - net_dev->mem_end = priv->mac_dev->res->end; - -+ /* Configure the maximum MTU according to the FMan's MAXFRM */ -+ net_dev->min_mtu = ETH_MIN_MTU; -+ net_dev->max_mtu = dpa_get_max_mtu(); -+ -+#ifndef CONFIG_PPC -+ /* Due to the A010022 FMan errata, we can not use contig frames larger -+ * than 4K, nor S/G frames. We need to prevent the user from setting a -+ * large MTU. -+ */ -+ if (unlikely(dpaa_errata_a010022)) -+ net_dev->max_mtu = DPA_BP_RAW_SIZE; -+#endif -+ - net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_LLTX); - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -261,31 +261,6 @@ dpa_get_stats64(struct net_device *net_d - } - EXPORT_SYMBOL(dpa_get_stats64); - --int dpa_change_mtu(struct net_device *net_dev, int new_mtu) --{ -- int max_mtu = dpa_get_max_mtu(); -- --#ifndef CONFIG_PPC -- /* Due to the A010022 FMan errata, we can not use contig frames larger -- * than 4K, nor S/G frames. We need to prevent the user from setting a -- * large MTU. -- */ -- if (unlikely(dpaa_errata_a010022)) -- max_mtu = DPA_BP_RAW_SIZE; --#endif -- -- /* Make sure we don't exceed the Ethernet controller's MAXFRM */ -- if (new_mtu < 68 || new_mtu > max_mtu) { -- netdev_err(net_dev, "Invalid L3 mtu %d (must be between %d and %d).\n", -- new_mtu, 68, max_mtu); -- return -EINVAL; -- } -- net_dev->mtu = new_mtu; -- -- return 0; --} --EXPORT_SYMBOL(dpa_change_mtu); -- - /* .ndo_init callback */ - int dpa_ndo_init(struct net_device *net_dev) - { ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h -@@ -143,7 +143,6 @@ void __cold dpa_timeout(struct net_devic - void __cold - dpa_get_stats64(struct net_device *net_dev, - struct rtnl_link_stats64 *stats); --int dpa_change_mtu(struct net_device *net_dev, int new_mtu); - int dpa_ndo_init(struct net_device *net_dev); - int dpa_set_features(struct net_device *dev, netdev_features_t features); - netdev_features_t dpa_fix_features(struct net_device *dev, diff --git a/target/linux/layerscape/patches-5.4/701-net-0034-Extend-FM-MAC-Statistics-with-frame-size-counters-re.patch b/target/linux/layerscape/patches-5.4/701-net-0034-Extend-FM-MAC-Statistics-with-frame-size-counters-re.patch deleted file mode 100644 index d880cc8aa6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0034-Extend-FM-MAC-Statistics-with-frame-size-counters-re.patch +++ /dev/null @@ -1,406 +0,0 @@ -From 60f5101cdfbabd4cc29c02d69aa43a84fab52cf7 Mon Sep 17 00:00:00 2001 -From: Iordache Florinel-R70177 -Date: Thu, 12 Oct 2017 11:13:41 +0300 -Subject: [PATCH] Extend FM MAC Statistics with frame size counters (request - from Nokia) - -Signed-off-by: Iordache Florinel-R70177 ---- - .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c | 1 + - .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c | 16 ++++++ - .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h | 1 + - .../sdk_fman/Peripherals/FM/MAC/fman_memac.c | 21 ++++++++ - .../freescale/sdk_fman/Peripherals/FM/MAC/memac.c | 57 ++++++++++++++++++++++ - .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.c | 42 ++++++++++++++++ - .../sdk_fman/inc/Peripherals/fm_mac_ext.h | 28 +++++++++++ - .../freescale/sdk_fman/inc/flib/fsl_fman_memac.h | 7 +++ - .../sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h | 2 + - .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c | 41 ++++++++++++++++ - .../uapi/linux/fmd/Peripherals/fm_port_ioctls.h | 25 ++++++++++ - 11 files changed, 241 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c -@@ -1389,6 +1389,7 @@ static void InitFmMacControllerDriver(t_ - - p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters; - p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics; -+ p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = NULL; - - p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress; - p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress; ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c -@@ -461,6 +461,22 @@ t_Error FM_MAC_GetStatistics (t_Handle h - - /* ......................................................................... */ - -+t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type) -+{ -+ t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE); -+ -+ memset(p_FrameSizeCounters, 0, sizeof(t_FmMacFrameSizeCounters)); -+ -+ if (p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters) -+ return p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters(h_FmMac, p_FrameSizeCounters, type); -+ -+ RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG); -+} -+ -+/* ......................................................................... */ -+ - t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr) - { - t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac; ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h -@@ -106,6 +106,7 @@ typedef struct { - - t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac); - t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics); -+ t_Error (*f_FM_MAC_GetFrameSizeCounters) (t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type); - - t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); - t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr); ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c -@@ -360,24 +360,45 @@ uint64_t fman_memac_get_counter(struct m - case E_MEMAC_COUNTER_R64: - ret_val = GET_MEMAC_CNTR_64(r64); - break; -+ case E_MEMAC_COUNTER_T64: -+ ret_val = GET_MEMAC_CNTR_64(t64); -+ break; - case E_MEMAC_COUNTER_R127: - ret_val = GET_MEMAC_CNTR_64(r127); - break; -+ case E_MEMAC_COUNTER_T127: -+ ret_val = GET_MEMAC_CNTR_64(t127); -+ break; - case E_MEMAC_COUNTER_R255: - ret_val = GET_MEMAC_CNTR_64(r255); - break; -+ case E_MEMAC_COUNTER_T255: -+ ret_val = GET_MEMAC_CNTR_64(t255); -+ break; - case E_MEMAC_COUNTER_R511: - ret_val = GET_MEMAC_CNTR_64(r511); - break; -+ case E_MEMAC_COUNTER_T511: -+ ret_val = GET_MEMAC_CNTR_64(t511); -+ break; - case E_MEMAC_COUNTER_R1023: - ret_val = GET_MEMAC_CNTR_64(r1023); - break; -+ case E_MEMAC_COUNTER_T1023: -+ ret_val = GET_MEMAC_CNTR_64(t1023); -+ break; - case E_MEMAC_COUNTER_R1518: - ret_val = GET_MEMAC_CNTR_64(r1518); - break; -+ case E_MEMAC_COUNTER_T1518: -+ ret_val = GET_MEMAC_CNTR_64(t1518); -+ break; - case E_MEMAC_COUNTER_R1519X: - ret_val = GET_MEMAC_CNTR_64(r1519x); - break; -+ case E_MEMAC_COUNTER_T1519X: -+ ret_val = GET_MEMAC_CNTR_64(t1519x); -+ break; - case E_MEMAC_COUNTER_RFRG: - ret_val = GET_MEMAC_CNTR_64(rfrg); - break; ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c -@@ -593,6 +593,62 @@ static t_Error MemacGetStatistics(t_Hand - - /* ......................................................................... */ - -+static t_Error MemacGetFrameSizeCounters(t_Handle h_Memac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type) -+{ -+ t_Memac *p_Memac = (t_Memac *)h_Memac; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER); -+ -+ switch (type) -+ { -+ case e_COMM_MODE_NONE: -+ break; -+ -+ case e_COMM_MODE_RX: -+ p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64); -+ p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127); -+ p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255); -+ p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511); -+ p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023); -+ p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518); -+ p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X); -+ break; -+ -+ case e_COMM_MODE_TX: -+ p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64); -+ p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127); -+ p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255); -+ p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511); -+ p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023); -+ p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518); -+ p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X); -+ break; -+ -+ case e_COMM_MODE_RX_AND_TX: -+ p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64) -+ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64); -+ p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127) -+ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127); -+ p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255) -+ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255); -+ p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511) -+ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511); -+ p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023) -+ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023); -+ p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518) -+ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518); -+ p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X) -+ + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X); -+ break; -+ } -+ -+ return E_OK; -+} -+ -+/* ......................................................................... */ -+ - static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr) - { - t_Memac *p_Memac = (t_Memac *)h_Memac; -@@ -1025,6 +1081,7 @@ static void InitFmMacControllerDriver(t_ - - p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters; - p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics; -+ p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = MemacGetFrameSizeCounters; - - p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress; - p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress; ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c -@@ -438,6 +438,47 @@ static t_Error TgecGetStatistics(t_Handl - - /* ......................................................................... */ - -+static t_Error TgecGetFrameSizeCounters(t_Handle h_Tgec, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type) -+{ -+ t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -+ struct tgec_regs *p_TgecMemMap; -+ -+ SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER); -+ SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE); -+ SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER); -+ -+ p_TgecMemMap = p_Tgec->p_MemMap; -+ -+ switch (type) -+ { -+ case e_COMM_MODE_NONE: -+ break; -+ -+ case e_COMM_MODE_RX: -+ p_FrameSizeCounters->count_pkts_64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64); -+ p_FrameSizeCounters->count_pkts_65_to_127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127); -+ p_FrameSizeCounters->count_pkts_128_to_255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255); -+ p_FrameSizeCounters->count_pkts_256_to_511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511); -+ p_FrameSizeCounters->count_pkts_512_to_1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023); -+ p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518); -+ p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X); -+ break; -+ -+ case e_COMM_MODE_TX: -+ //Tx counters not supported -+ break; -+ -+ case e_COMM_MODE_RX_AND_TX: -+ //Tx counters not supported -+ break; -+ } -+ -+ return E_OK; -+} -+ -+ -+/* ......................................................................... */ -+ - static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec) - { - t_Tgec *p_Tgec = (t_Tgec *)h_Tgec; -@@ -905,6 +946,7 @@ static void InitFmMacControllerDriver(t_ - - p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters; - p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics; -+ p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = TgecGetFrameSizeCounters; - - p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress; - p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress; ---- a/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h -@@ -197,6 +197,19 @@ typedef struct t_FmMacStatistics { - - Other */ - } t_FmMacStatistics; - -+/**************************************************************************//** -+ @Description FM MAC Frame Size Counters -+*//***************************************************************************/ -+typedef struct t_FmMacFrameSizeCounters { -+ -+ uint64_t count_pkts_64; /**< 64 byte frame counter */ -+ uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */ -+ uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */ -+ uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */ -+ uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */ -+ uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */ -+ uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */ -+} t_FmMacFrameSizeCounters; - - /**************************************************************************//** - @Group FM_mac_init_grp FM MAC Initialization Unit -@@ -654,6 +667,21 @@ t_Error FM_MAC_SetStatistics(t_Handle h_ - t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics); - - /**************************************************************************//** -+ @Function FM_MAC_GetFrameSizeCounters -+ -+ @Description get MAC statistics counters for different frame size -+ -+ @Param[in] h_FmMac - A handle to a FM MAC Module. -+ @Param[in] p_FrameSizeCounters - Structure with counters -+ @Param[in] type - Type of counters to be read -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type); -+ -+/**************************************************************************//** - @Function FM_MAC_ModifyMacAddr - - @Description Replace the main MAC Address ---- a/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h -@@ -146,12 +146,19 @@ _val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; - - enum memac_counters { - E_MEMAC_COUNTER_R64, -+ E_MEMAC_COUNTER_T64, - E_MEMAC_COUNTER_R127, -+ E_MEMAC_COUNTER_T127, - E_MEMAC_COUNTER_R255, -+ E_MEMAC_COUNTER_T255, - E_MEMAC_COUNTER_R511, -+ E_MEMAC_COUNTER_T511, - E_MEMAC_COUNTER_R1023, -+ E_MEMAC_COUNTER_T1023, - E_MEMAC_COUNTER_R1518, -+ E_MEMAC_COUNTER_T1518, - E_MEMAC_COUNTER_R1519X, -+ E_MEMAC_COUNTER_T1519X, - E_MEMAC_COUNTER_RFRG, - E_MEMAC_COUNTER_RJBR, - E_MEMAC_COUNTER_RDRP, ---- a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h -@@ -123,6 +123,8 @@ EXPORT_SYMBOL(FM_PCD_SetAdvancedOffloadS - /* FMAN MAC exported routines */ - EXPORT_SYMBOL(FM_MAC_GetStatistics); - -+EXPORT_SYMBOL(FM_MAC_GetFrameSizeCounters); -+ - EXPORT_SYMBOL(FM_GetSpecialOperationCoding); - - #endif /* __LNXWRP_EXP_SYM_H */ ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c -@@ -4608,6 +4608,47 @@ t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPort - break; - } - -+ case FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS: -+ { -+ t_LnxWrpFmDev *p_LnxWrpFmDev = -+ (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev; -+ ioc_fm_port_mac_frame_size_counters_t param; -+ t_FmMacFrameSizeCounters frameSizeCounters; -+ int mac_id = p_LnxWrpFmPortDev->id; -+ -+ if (!p_LnxWrpFmDev) -+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!")); -+ -+ if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev && -+ &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev) -+ mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */ -+ -+ if (!p_LnxWrpFmDev->macs[mac_id].h_Dev) -+ RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!")); -+ -+ if (copy_from_user(¶m, (ioc_fm_port_mac_frame_size_counters_t *)arg, -+ sizeof(ioc_fm_port_mac_frame_size_counters_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ if (FM_MAC_GetFrameSizeCounters(p_LnxWrpFmDev->macs[mac_id].h_Dev, -+ &frameSizeCounters, param.type)) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ param.count_pkts_64 = frameSizeCounters.count_pkts_64; -+ param.count_pkts_65_to_127 = frameSizeCounters.count_pkts_65_to_127; -+ param.count_pkts_128_to_255 = frameSizeCounters.count_pkts_128_to_255; -+ param.count_pkts_256_to_511 = frameSizeCounters.count_pkts_256_to_511; -+ param.count_pkts_512_to_1023 = frameSizeCounters.count_pkts_512_to_1023; -+ param.count_pkts_1024_to_1518 = frameSizeCounters.count_pkts_1024_to_1518; -+ param.count_pkts_1519_to_1522 = frameSizeCounters.count_pkts_1519_to_1522; -+ -+ if (copy_to_user((ioc_fm_port_mac_frame_size_counters_t *)arg, ¶m, -+ sizeof(ioc_fm_port_mac_frame_size_counters_t))) -+ RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG); -+ -+ break; -+ } -+ - case FM_PORT_IOC_GET_BMI_COUNTERS: - { - t_LnxWrpFmDev *p_LnxWrpFmDev = ---- a/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h -+++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h -@@ -939,6 +939,31 @@ typedef struct ioc_fm_port_vsp_alloc_par - - #define FM_PORT_IOC_GET_BMI_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(42), ioc_fm_port_bmi_stats_t) - -+typedef struct ioc_fm_port_mac_frame_size_counters_t { -+ -+ e_CommMode type; -+ uint64_t count_pkts_64; /**< 64 byte frame counter */ -+ uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */ -+ uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */ -+ uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */ -+ uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */ -+ uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */ -+ uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */ -+} ioc_fm_port_mac_frame_size_counters_t; -+ -+/**************************************************************************//** -+ @Function FM_MAC_GetFrameSizeCounters -+ -+ @Description get MAC statistics counters for different frame size -+ -+ @Param[out] ioc_fm_port_mac_frame_size_counters_t A structure holding the counters -+ -+ @Return E_OK on success; Error code otherwise. -+ -+ @Cautions Allowed only following FM_Init(). -+*//***************************************************************************/ -+#define FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(43), ioc_fm_port_mac_frame_size_counters_t) -+ - - /** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */ - /** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0035-sdk_dpaa-accept-frames-on-RX-even-if-larger-than-MTU.patch b/target/linux/layerscape/patches-5.4/701-net-0035-sdk_dpaa-accept-frames-on-RX-even-if-larger-than-MTU.patch deleted file mode 100644 index d868498de4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0035-sdk_dpaa-accept-frames-on-RX-even-if-larger-than-MTU.patch +++ /dev/null @@ -1,64 +0,0 @@ -From ab1371fec54bdd16b5f6c56c76d817404c696d4b Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 18 Oct 2017 16:38:30 +0300 -Subject: [PATCH] sdk_dpaa: accept frames on RX even if larger than MTU - -Documentation/networking/netdevices.txt mentions that interfaces must -be able to receive frames at least the size of the configured MTU. The -behavior for received frames larger than the MTU is unspecified. We have -been dropping these frames in software. Remove this behavior and accept -them. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 11 ----------- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 11 ----------- - 2 files changed, 22 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -514,17 +514,6 @@ dpa_fd_offset(const struct qm_fd *fd) - return fd->offset; - } - --/* Verifies if the skb length is below the interface MTU */ --static inline int dpa_check_rx_mtu(struct sk_buff *skb, int mtu) --{ -- if (unlikely(skb->len > mtu)) -- if ((skb->protocol != htons(ETH_P_8021Q)) -- || (skb->len > mtu + 4)) -- return -1; -- -- return 0; --} -- - static inline uint16_t dpa_get_headroom(struct dpa_buffer_layout_s *bl) - { - uint16_t headroom; ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -616,13 +616,6 @@ void __hot _dpa_rx(struct net_device *ne - (*count_ptr)--; - skb->protocol = eth_type_trans(skb, net_dev); - -- /* IP Reassembled frames are allowed to be larger than MTU */ -- if (unlikely(dpa_check_rx_mtu(skb, net_dev->mtu) && -- !(fd_status & FM_FD_IPR))) { -- percpu_stats->rx_dropped++; -- goto drop_bad_frame; -- } -- - skb_len = skb->len; - - #ifdef CONFIG_FSL_DPAA_DBG_LOOP -@@ -655,10 +648,6 @@ void __hot _dpa_rx(struct net_device *ne - packet_dropped: - return; - --drop_bad_frame: -- dev_kfree_skb(skb); -- return; -- - _release_frame: - dpa_fd_release(net_dev, fd); - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0036-sdk-dpa-use-netdev-dev-for-DMA-mapping.patch b/target/linux/layerscape/patches-5.4/701-net-0036-sdk-dpa-use-netdev-dev-for-DMA-mapping.patch deleted file mode 100644 index 39631c32f0..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0036-sdk-dpa-use-netdev-dev-for-DMA-mapping.patch +++ /dev/null @@ -1,121 +0,0 @@ -From e1ae30545347709590bab5f4a3c27e7f639c6ead Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Wed, 18 Oct 2017 19:36:59 +0300 -Subject: [PATCH] sdk: dpa: use netdev dev for DMA mapping - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 2 +- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.c | 2 +- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 35 ++++------------------ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 2 +- - 4 files changed, 9 insertions(+), 32 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -@@ -875,7 +875,7 @@ static int dpa_priv_bp_create(struct net - - for (i = 0; i < count; i++) { - int err; -- err = dpa_bp_alloc(&dpa_bp[i]); -+ err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent); - if (err < 0) { - dpa_bp_free(priv); - priv->dpa_bp = NULL; ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c -@@ -176,7 +176,7 @@ int dpa_bp_create(struct net_device *net - - for (i = 0; i < count; i++) { - int err; -- err = dpa_bp_alloc(&dpa_bp[i]); -+ err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent); - if (err < 0) { - dpa_bp_free(priv); - priv->dpa_bp = NULL; ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -686,11 +686,10 @@ void dpa_set_buffers_layout(struct mac_d - EXPORT_SYMBOL(dpa_set_buffers_layout); - - int __attribute__((nonnull)) --dpa_bp_alloc(struct dpa_bp *dpa_bp) -+dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev) - { - int err; - struct bman_pool_params bp_params; -- struct platform_device *pdev; - - if (dpa_bp->size == 0 || dpa_bp->config_count == 0) { - pr_err("Buffer pool is not properly initialized! Missing size or initial number of buffers"); -@@ -723,44 +722,25 @@ dpa_bp_alloc(struct dpa_bp *dpa_bp) - - dpa_bp->bpid = (uint8_t)bman_get_params(dpa_bp->pool)->bpid; - -- pdev = platform_device_register_simple("dpaa_eth_bpool", -- dpa_bp->bpid, NULL, 0); -- if (IS_ERR(pdev)) { -- pr_err("platform_device_register_simple() failed\n"); -- err = PTR_ERR(pdev); -- goto pdev_register_failed; -- } -- { -- struct dma_map_ops *ops = get_dma_ops(&pdev->dev); -- ops->dma_supported = NULL; -- } -- err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40)); -+ err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40)); - if (err) { - pr_err("dma_coerce_mask_and_coherent() failed\n"); -- goto pdev_mask_failed; -+ goto bman_free_pool; - } --#ifdef CONFIG_FMAN_ARM -- /* force coherency */ -- pdev->dev.archdata.dma_coherent = true; -- arch_setup_dma_ops(&pdev->dev, 0, 0, NULL, true); --#endif - -- dpa_bp->dev = &pdev->dev; -+ dpa_bp->dev = dev; - - if (dpa_bp->seed_cb) { - err = dpa_bp->seed_cb(dpa_bp); - if (err) -- goto pool_seed_failed; -+ goto bman_free_pool; - } - - dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp); - - return 0; - --pool_seed_failed: --pdev_mask_failed: -- platform_device_unregister(pdev); --pdev_register_failed: -+bman_free_pool: - bman_free_pool(dpa_bp->pool); - - return err; -@@ -822,9 +802,6 @@ _dpa_bp_free(struct dpa_bp *dpa_bp) - - dpa_bp_array[bp->bpid] = NULL; - bman_free_pool(bp->pool); -- -- if (bp->dev) -- platform_device_unregister(to_platform_device(bp->dev)); - } - - void __cold __attribute__((nonnull)) ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h -@@ -163,7 +163,7 @@ void dpa_set_rx_mode(struct net_device * - void dpa_set_buffers_layout(struct mac_device *mac_dev, - struct dpa_buffer_layout_s *layout); - int __attribute__((nonnull)) --dpa_bp_alloc(struct dpa_bp *dpa_bp); -+dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev); - void __cold __attribute__((nonnull)) - dpa_bp_free(struct dpa_priv_s *priv); - struct dpa_bp *dpa_bpid2pool(int bpid); diff --git a/target/linux/layerscape/patches-5.4/701-net-0037-Added-MII-IOCTL-support-for-SIOCGMIIREG.patch b/target/linux/layerscape/patches-5.4/701-net-0037-Added-MII-IOCTL-support-for-SIOCGMIIREG.patch deleted file mode 100644 index 77c192713c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0037-Added-MII-IOCTL-support-for-SIOCGMIIREG.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 7f87217ebf1ca84ad63d995d88eda45341273fad Mon Sep 17 00:00:00 2001 -From: Vicentiu Galanopulo -Date: Tue, 7 Nov 2017 16:15:03 +0200 -Subject: [PATCH] Added MII IOCTL support for SIOCGMIIREG - -Signed-off-by: Vicentiu Galanopulo ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -444,14 +444,18 @@ int dpa_ioctl(struct net_device *dev, st - #ifdef CONFIG_FSL_DPAA_1588 - struct dpa_priv_s *priv = netdev_priv(dev); - #endif -- int ret = 0; -+ int ret = -EINVAL; - -- /* at least one timestamping feature must be enabled */ --#ifdef CONFIG_FSL_DPAA_TS - if (!netif_running(dev)) --#endif - return -EINVAL; - -+ if (cmd == SIOCGMIIREG) { -+ if (!dev->phydev) -+ ret = -EINVAL; -+ else -+ ret = phy_mii_ioctl(dev->phydev, rq, cmd); -+ } -+ - #ifdef CONFIG_FSL_DPAA_TS - if (cmd == SIOCSHWTSTAMP) - return dpa_ts_ioctl(dev, rq, cmd); diff --git a/target/linux/layerscape/patches-5.4/701-net-0038-sdk_dpaa-ls1043a-errata-stop-advertising-S-G-and-GSO.patch b/target/linux/layerscape/patches-5.4/701-net-0038-sdk_dpaa-ls1043a-errata-stop-advertising-S-G-and-GSO.patch deleted file mode 100644 index a7c87086eb..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0038-sdk_dpaa-ls1043a-errata-stop-advertising-S-G-and-GSO.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 4dc65101fc94270fec94599701343128c77da8fb Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 8 Nov 2017 14:37:27 +0200 -Subject: [PATCH] sdk_dpaa: ls1043a errata: stop advertising S/G and GSO - support - -The errata prevents us from transmitting S/G frames. Instead of -linearizing them ourselves, stop advertising S/G support and have the -stack do it for us. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -@@ -761,15 +761,6 @@ static int dpa_private_netdev_init(struc - net_dev->min_mtu = ETH_MIN_MTU; - net_dev->max_mtu = dpa_get_max_mtu(); - --#ifndef CONFIG_PPC -- /* Due to the A010022 FMan errata, we can not use contig frames larger -- * than 4K, nor S/G frames. We need to prevent the user from setting a -- * large MTU. -- */ -- if (unlikely(dpaa_errata_a010022)) -- net_dev->max_mtu = DPA_BP_RAW_SIZE; --#endif -- - net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_LLTX); - -@@ -787,6 +778,18 @@ static int dpa_private_netdev_init(struc - /* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */ - net_dev->features |= NETIF_F_HW_ACCEL_MQ; - -+#ifndef CONFIG_PPC -+ /* Due to the A010022 FMan errata, we can not use contig frames larger -+ * than 4K, nor S/G frames. We need to prevent the user from setting a -+ * large MTU. We also stop advertising S/G and GSO support. -+ */ -+ if (unlikely(dpaa_errata_a010022)) { -+ net_dev->max_mtu = DPA_BP_RAW_SIZE; -+ net_dev->hw_features &= ~NETIF_F_SG; -+ net_dev->features &= ~NETIF_F_GSO; -+ } -+#endif -+ - return dpa_netdev_init(net_dev, mac_addr, tx_timeout); - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0039-staging-fsl_qbman-Calculate-valid-bit-from-MC-RR.patch b/target/linux/layerscape/patches-5.4/701-net-0039-staging-fsl_qbman-Calculate-valid-bit-from-MC-RR.patch deleted file mode 100644 index 1e4cfe8069..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0039-staging-fsl_qbman-Calculate-valid-bit-from-MC-RR.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 5ebee96094c5a97a89a986108242cca9d853ff55 Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Wed, 27 Sep 2017 14:50:08 -0400 -Subject: [PATCH] staging/fsl_qbman: Calculate valid bit from MC-RR - -Use the management commmand response registers to determine -the next expected valid bit when initializing a software -portal. This avoids using the wrong valid bit in cases -where a command was partially written but then not -completed. - -Signed-off-by: Roy Pledge ---- - drivers/staging/fsl_qbman/qman_low.h | 19 +++++++++++++++++-- - 1 file changed, 17 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl_qbman/qman_low.h -+++ b/drivers/staging/fsl_qbman/qman_low.h -@@ -1095,11 +1095,26 @@ static inline void qm_mr_set_ithresh(str - - static inline int qm_mc_init(struct qm_portal *portal) - { -+ u8 rr0, rr1; - register struct qm_mc *mc = &portal->mc; -+ - mc->cr = portal->addr.addr_ce + QM_CL_CR; - mc->rr = portal->addr.addr_ce + QM_CL_RR0; -- mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) & -- QM_MCC_VERB_VBIT) ? 0 : 1; -+ -+ /* -+ * The expected valid bit polarity for the next CR command is 0 -+ * if RR1 contains a valid response, and is 1 if RR0 contains a -+ * valid response. If both RR contain all 0, this indicates either -+ * that no command has been executed since reset (in which case the -+ * expected valid bit polarity is 1) -+ */ -+ rr0 = __raw_readb(&mc->rr->verb); -+ rr1 = __raw_readb(&(mc->rr+1)->verb); -+ if ((rr0 == 0 && rr1 == 0) || rr0 != 0) -+ mc->rridx = 1; -+ else -+ mc->rridx = 0; -+ - mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0; - #ifdef CONFIG_FSL_DPA_CHECKING - mc->state = qman_mc_idle; diff --git a/target/linux/layerscape/patches-5.4/701-net-0040-fsl_qbman-usdpaa-Invalidate-software-portals-before-.patch b/target/linux/layerscape/patches-5.4/701-net-0040-fsl_qbman-usdpaa-Invalidate-software-portals-before-.patch deleted file mode 100644 index 5148f444dc..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0040-fsl_qbman-usdpaa-Invalidate-software-portals-before-.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 6506f95ad4d47500275c2f3a48abb7f3de11c54b Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Thu, 25 May 2017 16:59:08 -0400 -Subject: [PATCH] fsl_qbman/usdpaa: Invalidate software portals before use - -Invalidate the cache for the software portals before using them -since the portals are non coherent. This ensures that the core -using the portal is seeing the most up to date information in -case the cache contained older data. This is important during -the cleanup phase if cleanup occurs on a differnt core than -what the application was using. - -Signed-off-by: Roy Pledge ---- - drivers/staging/fsl_qbman/fsl_usdpaa.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - ---- a/drivers/staging/fsl_qbman/fsl_usdpaa.c -+++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c -@@ -371,6 +371,16 @@ static int usdpaa_open(struct inode *ino - - #define DQRR_MAXFILL 15 - -+ -+/* Invalidate a portal */ -+void dbci_portal(void *addr) -+{ -+ int i; -+ -+ for (i = 0; i < 0x4000; i += 64) -+ dcbi(addr + i); -+} -+ - /* Reset a QMan portal to its default state */ - static int init_qm_portal(struct qm_portal_config *config, - struct qm_portal *portal) -@@ -384,6 +394,13 @@ static int init_qm_portal(struct qm_port - /* Make sure interrupts are inhibited */ - qm_out(IIR, 1); - -+ /* -+ * Invalidate the entire CE portal are to ensure no stale -+ * cachelines are present. This should be done on all -+ * cores as the portal is mapped as M=0 (non-coherent). -+ */ -+ on_each_cpu(dbci_portal, portal->addr.addr_ce, 1); -+ - /* Initialize the DQRR. This will stop any dequeue - commands that are in progress */ - if (qm_dqrr_init(portal, config, qm_dqrr_dpush, qm_dqrr_pvb, -@@ -435,6 +452,13 @@ static int init_bm_portal(struct bm_port - portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE]; - portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI]; - -+ /* -+ * Invalidate the entire CE portal are to ensure no stale -+ * cachelines are present. This should be done on all -+ * cores as the portal is mapped as M=0 (non-coherent). -+ */ -+ on_each_cpu(dbci_portal, portal->addr.addr_ce, 1); -+ - if (bm_rcr_init(portal, bm_rcr_pvb, bm_rcr_cce)) { - pr_err("Bman RCR initialisation failed\n"); - return 1; diff --git a/target/linux/layerscape/patches-5.4/701-net-0041-net-ethernet-Rename-PHY_INTERFACE_MODE_SGMII_2500.patch b/target/linux/layerscape/patches-5.4/701-net-0041-net-ethernet-Rename-PHY_INTERFACE_MODE_SGMII_2500.patch deleted file mode 100644 index 1dd0d9f43b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0041-net-ethernet-Rename-PHY_INTERFACE_MODE_SGMII_2500.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 15096410c230acd29b2b1bf7958b71e1f990414a Mon Sep 17 00:00:00 2001 -From: Bhaskar Upadhaya -Date: Wed, 29 Nov 2017 06:48:54 +0530 -Subject: [PATCH] net: ethernet: Rename PHY_INTERFACE_MODE_SGMII_2500 - -Rename PHY_INTERFACE_MODE_SGMII_2500 to PHY_INTERFACE_MODE_2500SGMII -Convention is to put the number(2500) first and then the -interface mode(SGMII) - -Signed-off-by: Bhaskar Upadhaya ---- - drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/mac.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c -@@ -76,7 +76,7 @@ static const char phy_str[][11] = { - [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid", - [PHY_INTERFACE_MODE_RTBI] = "rtbi", - [PHY_INTERFACE_MODE_XGMII] = "xgmii", -- [PHY_INTERFACE_MODE_SGMII_2500] = "sgmii-2500", -+ [PHY_INTERFACE_MODE_2500SGMII] = "sgmii-2500", - }; - - static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str) -@@ -103,7 +103,7 @@ static const uint16_t phy2speed[] = { - [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000, - [PHY_INTERFACE_MODE_RTBI] = SPEED_1000, - [PHY_INTERFACE_MODE_XGMII] = SPEED_10000, -- [PHY_INTERFACE_MODE_SGMII_2500] = SPEED_2500, -+ [PHY_INTERFACE_MODE_2500SGMII] = SPEED_2500, - }; - - static struct mac_device * __cold diff --git a/target/linux/layerscape/patches-5.4/701-net-0042-sdk_dpaa-ceetm-add-independent-CEETM-congestion-thre.patch b/target/linux/layerscape/patches-5.4/701-net-0042-sdk_dpaa-ceetm-add-independent-CEETM-congestion-thre.patch deleted file mode 100644 index 461280baf6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0042-sdk_dpaa-ceetm-add-independent-CEETM-congestion-thre.patch +++ /dev/null @@ -1,61 +0,0 @@ -From aa54d82b06962bb620852ed20270f7783be68897 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Fri, 24 Nov 2017 10:29:12 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: add independent CEETM congestion thresholds - -Configure the CEETM egress congestion thresholds independently from the -default Ethernet driver's Work Queues. Allow the user to edit the -thresholds through menuconfig. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/Kconfig | 23 ++++++++++++++++++++++ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 4 ++-- - 2 files changed, 25 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig -@@ -20,6 +20,29 @@ config FSL_DPAA_CEETM - help - Enable QoS offloading support through the CEETM hardware block. - -+config FSL_DPAA_CEETM_CCS_THRESHOLD_1G -+ hex "CEETM egress congestion threshold on 1G ports" -+ depends on FSL_DPAA_CEETM -+ range 0x1000 0x10000000 -+ default "0x000a0000" -+ help -+ The size in bytes of the CEETM egress Class Congestion State threshold on 1G ports. -+ The threshold needs to be configured keeping in mind the following factors: -+ - A threshold too large will buffer frames for a long time in the TX queues, -+ when a small shaping rate is configured. This will cause buffer pool depletion -+ or out of memory errors. This in turn will cause frame loss on RX; -+ - A threshold too small will cause unnecessary frame loss by entering -+ congestion too often. -+ -+config FSL_DPAA_CEETM_CCS_THRESHOLD_10G -+ hex "CEETM egress congestion threshold on 10G ports" -+ depends on FSL_DPAA_CEETM -+ range 0x1000 0x20000000 -+ default "0x00640000" -+ help -+ The size in bytes of the CEETM egress Class Congestion State threshold on 10G ports. -+ See FSL_DPAA_CEETM_CCS_THRESHOLD_1G for details. -+ - config FSL_DPAA_OFFLINE_PORTS - bool "Offline Ports support" - depends on FSL_SDK_DPAA_ETH ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -185,9 +185,9 @@ static int ceetm_config_ccg(struct qm_ce - - /* Set the congestion state thresholds according to the link speed */ - if (dpa_priv->mac_dev->if_support & SUPPORTED_10000baseT_Full) -- cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G; -+ cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_10G; - else -- cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G; -+ cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_1G; - - qm_cgr_cs_thres_set64(&ccg_params.cs_thres_in, cs_th, 1); - qm_cgr_cs_thres_set64(&ccg_params.cs_thres_out, diff --git a/target/linux/layerscape/patches-5.4/701-net-0043-sdk_dpaa-ceetm-stop-transmitting-frames-when-the-CQ-.patch b/target/linux/layerscape/patches-5.4/701-net-0043-sdk_dpaa-ceetm-stop-transmitting-frames-when-the-CQ-.patch deleted file mode 100644 index 1f1afe329a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0043-sdk_dpaa-ceetm-stop-transmitting-frames-when-the-CQ-.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 3aa939c73c176690a9ebe646612cd097f281efe5 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Fri, 24 Nov 2017 10:48:31 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: stop transmitting frames when the CQ is - congested - -When the egress CQ is congested, drop the frames instead of enqueueing -them. This is more efficient than enqueueing and receiving them back on -the ERN queue. - -We also can't stop the netdev queues because that would affect all the CQs -and would hinder prioritization. - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 22 ++++++++++++++++------ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h | 1 + - 2 files changed, 17 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -125,16 +125,16 @@ static void ceetm_cscn(struct qm_ceetm_c - break; - } - -+ ceetm_fq->congested = congested; -+ - if (congested) { - dpa_priv->cgr_data.congestion_start_jiffies = jiffies; -- netif_tx_stop_all_queues(dpa_priv->net_dev); - dpa_priv->cgr_data.cgr_congested_count++; - if (cstats) - cstats->congested_count++; - } else { - dpa_priv->cgr_data.congested_jiffies += - (jiffies - dpa_priv->cgr_data.congestion_start_jiffies); -- netif_tx_wake_all_queues(dpa_priv->net_dev); - } - } - -@@ -148,6 +148,7 @@ static int ceetm_alloc_fq(struct ceetm_f - - (*fq)->net_dev = dev; - (*fq)->ceetm_cls = cls; -+ (*fq)->congested = 0; - return 0; - } - -@@ -1913,7 +1914,8 @@ int __hot ceetm_tx(struct sk_buff *skb, - struct Qdisc *sch = net_dev->qdisc; - struct ceetm_class *cl; - struct dpa_priv_s *priv_dpa; -- struct qman_fq *egress_fq, *conf_fq; -+ struct ceetm_fq *ceetm_fq; -+ struct qman_fq *conf_fq; - struct ceetm_qdisc *priv = qdisc_priv(sch); - struct ceetm_qdisc_stats *qstats = this_cpu_ptr(priv->root.qstats); - struct ceetm_class_stats *cstats; -@@ -1945,11 +1947,11 @@ int __hot ceetm_tx(struct sk_buff *skb, - */ - switch (cl->type) { - case CEETM_PRIO: -- egress_fq = &cl->prio.fq->fq; -+ ceetm_fq = cl->prio.fq; - cstats = this_cpu_ptr(cl->prio.cstats); - break; - case CEETM_WBFS: -- egress_fq = &cl->wbfs.fq->fq; -+ ceetm_fq = cl->wbfs.fq; - cstats = this_cpu_ptr(cl->wbfs.cstats); - break; - default: -@@ -1957,8 +1959,16 @@ int __hot ceetm_tx(struct sk_buff *skb, - goto drop; - } - -+ /* If the FQ is congested, avoid enqueuing the frame and dropping it -+ * when it returns on the ERN path. Drop it here directly instead. -+ */ -+ if (unlikely(ceetm_fq->congested)) { -+ qstats->drops++; -+ goto drop; -+ } -+ - bstats_update(&cstats->bstats, skb); -- return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq); -+ return dpa_tx_extended(skb, net_dev, &ceetm_fq->fq, conf_fq); - - drop: - dev_kfree_skb_any(skb); ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h -@@ -105,6 +105,7 @@ struct ceetm_fq { - struct qman_fq fq; - struct net_device *net_dev; - struct ceetm_class *ceetm_cls; -+ int congested; /* Congestion status */ - }; - - struct root_q { diff --git a/target/linux/layerscape/patches-5.4/701-net-0044-sdk_dpaa-ceetm-coding-style-fixes-and-added-comments.patch b/target/linux/layerscape/patches-5.4/701-net-0044-sdk_dpaa-ceetm-coding-style-fixes-and-added-comments.patch deleted file mode 100644 index 982344d86e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0044-sdk_dpaa-ceetm-coding-style-fixes-and-added-comments.patch +++ /dev/null @@ -1,91 +0,0 @@ -From e21cd0d3ef6f039c674b9e22581aaaabdf3a40f7 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Fri, 24 Nov 2017 11:55:51 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: coding style fixes and added comments - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 38 ++++++++++++++-------- - 1 file changed, 24 insertions(+), 14 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -69,15 +69,17 @@ static void get_dcp_and_sp(struct net_de - static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq, - const struct qm_mr_entry *msg) - { -- struct net_device *net_dev; -- struct ceetm_class *cls; -+ struct dpa_percpu_priv_s *dpa_percpu_priv; - struct ceetm_class_stats *cstats = NULL; - const struct dpa_priv_s *dpa_priv; -- struct dpa_percpu_priv_s *dpa_percpu_priv; -- struct sk_buff *skb; - struct qm_fd fd = msg->ern.fd; -+ struct net_device *net_dev; -+ struct ceetm_fq *ceetm_fq; -+ struct ceetm_class *cls; -+ struct sk_buff *skb; - -- net_dev = ((struct ceetm_fq *)fq)->net_dev; -+ ceetm_fq = container_of(fq, struct ceetm_fq, fq); -+ net_dev = ceetm_fq->net_dev; - dpa_priv = netdev_priv(net_dev); - dpa_percpu_priv = raw_cpu_ptr(dpa_priv->percpu_priv); - -@@ -86,7 +88,7 @@ static void ceetm_ern(struct qman_portal - dpa_percpu_priv->stats.tx_fifo_errors++; - - /* Increment CEETM counters */ -- cls = ((struct ceetm_fq *)fq)->ceetm_cls; -+ cls = ceetm_fq->ceetm_cls; - switch (cls->type) { - case CEETM_PRIO: - cstats = this_cpu_ptr(cls->prio.cstats); -@@ -99,11 +101,15 @@ static void ceetm_ern(struct qman_portal - if (cstats) - cstats->ern_drop_count++; - -+ /* Release the buffers that were supposed to be recycled. */ - if (fd.bpid != 0xff) { - dpa_fd_release(net_dev, &fd); - return; - } - -+ /* Release the frames that were supposed to return on the -+ * confirmation path. -+ */ - skb = _dpa_cleanup_tx_fd(dpa_priv, &fd); - dev_kfree_skb_any(skb); - } -@@ -1909,18 +1915,22 @@ static struct ceetm_class *ceetm_classif - - int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev) - { -- int ret; -- bool act_drop = false; -+ const int queue_mapping = dpa_get_queue_mapping(skb); - struct Qdisc *sch = net_dev->qdisc; -- struct ceetm_class *cl; -+ struct ceetm_class_stats *cstats; -+ struct ceetm_qdisc_stats *qstats; - struct dpa_priv_s *priv_dpa; - struct ceetm_fq *ceetm_fq; -+ struct ceetm_qdisc *priv; - struct qman_fq *conf_fq; -- struct ceetm_qdisc *priv = qdisc_priv(sch); -- struct ceetm_qdisc_stats *qstats = this_cpu_ptr(priv->root.qstats); -- struct ceetm_class_stats *cstats; -- const int queue_mapping = dpa_get_queue_mapping(skb); -- spinlock_t *root_lock = qdisc_lock(sch); -+ struct ceetm_class *cl; -+ spinlock_t *root_lock; -+ bool act_drop = false; -+ int ret; -+ -+ root_lock = qdisc_lock(sch); -+ priv = qdisc_priv(sch); -+ qstats = this_cpu_ptr(priv->root.qstats); - - spin_lock(root_lock); - cl = ceetm_classify(skb, sch, &ret, &act_drop); diff --git a/target/linux/layerscape/patches-5.4/701-net-0045-sdk_dpaa-ceetm-increment-the-interface-s-ern-counter.patch b/target/linux/layerscape/patches-5.4/701-net-0045-sdk_dpaa-ceetm-increment-the-interface-s-ern-counter.patch deleted file mode 100644 index f15e529a52..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0045-sdk_dpaa-ceetm-increment-the-interface-s-ern-counter.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 0f57c89199c5664a14e9a4c88a382d642e9398a1 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Thu, 7 Dec 2017 17:49:34 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: increment the interface's ern counters when - needed - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -86,6 +86,7 @@ static void ceetm_ern(struct qman_portal - /* Increment DPA counters */ - dpa_percpu_priv->stats.tx_dropped++; - dpa_percpu_priv->stats.tx_fifo_errors++; -+ count_ern(dpa_percpu_priv, msg); - - /* Increment CEETM counters */ - cls = ceetm_fq->ceetm_cls; diff --git a/target/linux/layerscape/patches-5.4/701-net-0046-sdk_dpaa-update-buffer-recycling-conditions.patch b/target/linux/layerscape/patches-5.4/701-net-0046-sdk_dpaa-update-buffer-recycling-conditions.patch deleted file mode 100644 index daad07483c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0046-sdk_dpaa-update-buffer-recycling-conditions.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b95f457bb7ba38f03a71b474e35f53670322f0db Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 15 Jan 2018 17:41:01 +0200 -Subject: [PATCH] sdk_dpaa: update buffer recycling conditions - -Guarantee there is enough space inside the skb's headroom to store the -skb back-pointer before recycling the buffer. The back-pointer is stored -right before the buffer's start. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -350,7 +350,13 @@ bool dpa_buf_is_recyclable(struct sk_buf - /* left align to the nearest cacheline */ - new = (unsigned char *)((unsigned long)new & ~(SMP_CACHE_BYTES - 1)); - -- if (likely(new >= skb->head && -+ /* Make sure there is enough space to store the skb back-pointer in -+ * the headroom, right before the start of the buffer. -+ * -+ * Guarantee that both maximum size and maximum data offsets aren't -+ * crossed. -+ */ -+ if (likely(new >= (skb->head + sizeof(void *)) && - new >= (skb->data - DPA_MAX_FD_OFFSET) && - skb_end_pointer(skb) - new <= DPA_RECYCLE_MAX_SIZE)) { - *new_buf_start = new; diff --git a/target/linux/layerscape/patches-5.4/701-net-0047-sdk_dpaa-update-comments-about-recycling-and-back-po.patch b/target/linux/layerscape/patches-5.4/701-net-0047-sdk_dpaa-update-comments-about-recycling-and-back-po.patch deleted file mode 100644 index a54dce9f28..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0047-sdk_dpaa-update-comments-about-recycling-and-back-po.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 2d7b6e7daf076b63f461ce9c4ec6022ddc3d15bb Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 15 Jan 2018 17:42:42 +0200 -Subject: [PATCH] sdk_dpaa: update comments about recycling and back-pointer - storage - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -121,6 +121,10 @@ static int _dpa_bp_add_8_bufs(const stru - put_page(virt_to_head_page(new_buf)); - goto build_skb_failed; - } -+ -+ /* Store the skb back-pointer before the start of the buffer. -+ * Otherwise it will be overwritten by the FMan. -+ */ - DPA_WRITE_SKB_PTR(skb, skbh, new_buf, -1); - - addr = dma_map_single(dev, new_buf, -@@ -344,7 +348,10 @@ bool dpa_buf_is_recyclable(struct sk_buf - * - buffer address aligned to cacheline bytes - * - offset of data from start of buffer no lower than a minimum value - * - offset of data from start of buffer no higher than a maximum value -+ * - the skb back-pointer is stored safely - */ -+ -+ /* guarantee both the minimum size and the minimum data offset */ - new = min(skb_end_pointer(skb) - min_size, skb->data - min_offset); - - /* left align to the nearest cacheline */ -@@ -694,6 +701,9 @@ int __hot skb_to_contig_fd(struct dpa_pr - dma_dir = DMA_BIDIRECTIONAL; - dma_map_size = dpa_bp->size; - -+ /* Store the skb back-pointer before the start of the buffer. -+ * Otherwise it will be overwritten by the FMan. -+ */ - DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, -1); - *offset = skb_headroom(skb) - fd->offset; - } else -@@ -711,7 +721,7 @@ int __hot skb_to_contig_fd(struct dpa_pr - - /* The buffer will be Tx-confirmed, but the TxConf cb must - * necessarily look at our Tx private data to retrieve the -- * skbuff. (In short: can't use DPA_WRITE_SKB_PTR() here.) -+ * skbuff. Store the back-pointer inside the buffer. - */ - DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, 0); - } -@@ -975,7 +985,11 @@ int __hot skb_to_sg_fd(struct dpa_priv_s - fd->length20 = skb->len; - fd->offset = priv->tx_headroom; - -- /* DMA map the SGT page */ -+ /* DMA map the SGT page -+ * -+ * It's safe to store the skb back-pointer inside the buffer since -+ * S/G frames are non-recyclable. -+ */ - DPA_WRITE_SKB_PTR(skb, skbh, sgt_buf, 0); - addr = dma_map_single(dpa_bp->dev, sgt_buf, - priv->tx_headroom + sgt_size, diff --git a/target/linux/layerscape/patches-5.4/701-net-0048-sdk_dpaa-ceetm-pass-extended-ACK-struct-to-parsing-f.patch b/target/linux/layerscape/patches-5.4/701-net-0048-sdk_dpaa-ceetm-pass-extended-ACK-struct-to-parsing-f.patch deleted file mode 100644 index d0c12a4391..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0048-sdk_dpaa-ceetm-pass-extended-ACK-struct-to-parsing-f.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 62fedbc6ed6f4117168af52a7ff12e3450809d30 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 17 Jan 2018 16:31:57 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: pass extended ACK struct to parsing - functions - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -1053,7 +1053,7 @@ static int ceetm_init(struct Qdisc *sch, - return -EINVAL; - } - -- ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy); -+ ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL); - if (ret < 0) { - pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); - return ret; -@@ -1230,7 +1230,7 @@ static int ceetm_change(struct Qdisc *sc - - pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); - -- ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy); -+ ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL); - if (ret < 0) { - pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); - return ret; -@@ -1463,7 +1463,7 @@ static int ceetm_cls_change(struct Qdisc - return -EINVAL; - } - -- err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy); -+ err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy, NULL); - if (err < 0) { - pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); - return -EINVAL; diff --git a/target/linux/layerscape/patches-5.4/701-net-0049-sdk_dpaa-ceetm-adapt-to-new-tcf-classify-API.patch b/target/linux/layerscape/patches-5.4/701-net-0049-sdk_dpaa-ceetm-adapt-to-new-tcf-classify-API.patch deleted file mode 100644 index 454cfe3f20..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0049-sdk_dpaa-ceetm-adapt-to-new-tcf-classify-API.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 9befbfedde09b0e3abdc56d8f98e2111af39e872 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 17 Jan 2018 16:36:05 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: adapt to new tcf classify API - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -1848,7 +1848,7 @@ static struct ceetm_class *ceetm_classif - - *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; - tcf = priv->filter_list; -- while (tcf && (result = tc_classify(skb, tcf, &res, false)) >= 0) { -+ while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) { - #ifdef CONFIG_NET_CLS_ACT - switch (result) { - case TC_ACT_QUEUED: diff --git a/target/linux/layerscape/patches-5.4/701-net-0050-sdk_dpaa-ceetm-introduce-a-TRAP-control-action.patch b/target/linux/layerscape/patches-5.4/701-net-0050-sdk_dpaa-ceetm-introduce-a-TRAP-control-action.patch deleted file mode 100644 index 4b3122113a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0050-sdk_dpaa-ceetm-introduce-a-TRAP-control-action.patch +++ /dev/null @@ -1,20 +0,0 @@ -From e71adc0bb320c602791fa08a14626704a57bbb4d Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 17 Jan 2018 16:38:09 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: introduce a TRAP control action - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -1853,6 +1853,7 @@ static struct ceetm_class *ceetm_classif - switch (result) { - case TC_ACT_QUEUED: - case TC_ACT_STOLEN: -+ case TC_ACT_TRAP: - *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; - case TC_ACT_SHOT: - /* No valid class found due to action */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0051-sdk_dpaa-ceetm-use-the-tcf-block-infrastructure.patch b/target/linux/layerscape/patches-5.4/701-net-0051-sdk_dpaa-ceetm-use-the-tcf-block-infrastructure.patch deleted file mode 100644 index 0e3d0166bf..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0051-sdk_dpaa-ceetm-use-the-tcf-block-infrastructure.patch +++ /dev/null @@ -1,126 +0,0 @@ -From ae72322610af7eb13fc9a67567fdac610d3d3d3d Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 17 Jan 2018 16:44:19 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: use the tcf block infrastructure - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 31 +++++++++++++++------- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h | 2 ++ - 2 files changed, 24 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -423,7 +423,7 @@ static void ceetm_cls_destroy(struct Qdi - free_percpu(cl->wbfs.cstats); - } - -- tcf_destroy_chain(&cl->filter_list); -+ tcf_block_put(cl->block); - kfree(cl); - } - -@@ -440,11 +440,13 @@ static void ceetm_destroy(struct Qdisc * - __func__, sch->handle); - - /* All filters need to be removed before destroying the classes */ -- tcf_destroy_chain(&priv->filter_list); -+ tcf_block_put(priv->block); - - for (i = 0; i < priv->clhash.hashsize; i++) { -- hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) -- tcf_destroy_chain(&cl->filter_list); -+ hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) { -+ tcf_block_put(cl->block); -+ cl->block = NULL; -+ } - } - - for (i = 0; i < priv->clhash.hashsize; i++) { -@@ -594,7 +596,7 @@ static int ceetm_init_root(struct Qdisc - /* Validate inputs */ - if (sch->parent != TC_H_ROOT) { - pr_err("CEETM: a root ceetm qdisc can not be attached to a class\n"); -- tcf_destroy_chain(&priv->filter_list); -+ tcf_block_put(priv->block); - qdisc_class_hash_destroy(&priv->clhash); - return -EINVAL; - } -@@ -1053,6 +1055,10 @@ static int ceetm_init(struct Qdisc *sch, - return -EINVAL; - } - -+ ret = tcf_block_get(&priv->block, &priv->filter_list); -+ if (ret) -+ return ret; -+ - ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL); - if (ret < 0) { - pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); -@@ -1521,6 +1527,12 @@ static int ceetm_cls_change(struct Qdisc - if (!cl) - return -ENOMEM; - -+ err = tcf_block_get(&cl->block, &cl->filter_list); -+ if (err) { -+ kfree(cl); -+ return err; -+ } -+ - cl->type = copt->type; - cl->shaped = copt->shaped; - cl->root.rate = copt->rate; -@@ -1585,6 +1597,7 @@ channel_err: - pr_err(KBUILD_BASENAME " : %s : failed to release the channel %d\n", - __func__, channel->idx); - claim_err: -+ tcf_block_put(cl->block); - kfree(cl); - return err; - } -@@ -1779,15 +1792,15 @@ static int ceetm_cls_dump_stats(struct Q - return gnet_stats_copy_app(d, &xstats, sizeof(xstats)); - } - --static struct tcf_proto **ceetm_tcf_chain(struct Qdisc *sch, unsigned long arg) -+static struct tcf_block *ceetm_tcf_block(struct Qdisc *sch, unsigned long arg) - { - struct ceetm_qdisc *priv = qdisc_priv(sch); - struct ceetm_class *cl = (struct ceetm_class *)arg; -- struct tcf_proto **fl = cl ? &cl->filter_list : &priv->filter_list; -+ struct tcf_block *block = cl ? cl->block : priv->block; - - pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__, - cl ? cl->common.classid : 0, sch->handle); -- return fl; -+ return block; - } - - static unsigned long ceetm_tcf_bind(struct Qdisc *sch, unsigned long parent, -@@ -1816,7 +1829,7 @@ const struct Qdisc_class_ops ceetm_cls_o - .change = ceetm_cls_change, - .delete = ceetm_cls_delete, - .walk = ceetm_cls_walk, -- .tcf_chain = ceetm_tcf_chain, -+ .tcf_block = ceetm_tcf_block, - .bind_tcf = ceetm_tcf_bind, - .unbind_tcf = ceetm_tcf_unbind, - .dump = ceetm_cls_dump, ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h -@@ -141,6 +141,7 @@ struct ceetm_qdisc { - }; - struct Qdisc_class_hash clhash; - struct tcf_proto *filter_list; /* qdisc attached filters */ -+ struct tcf_block *block; - }; - - /* CEETM Qdisc configuration parameters */ -@@ -192,6 +193,7 @@ struct ceetm_class { - struct Qdisc_class_common common; - int refcnt; /* usage count of this class */ - struct tcf_proto *filter_list; /* class attached filters */ -+ struct tcf_block *block; - struct Qdisc *parent; - bool shaped; - int type; /* ROOT/PRIO/WBFS */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0052-sdk_dpaa-ceetm-remove-tc-class-reference-counting.patch b/target/linux/layerscape/patches-5.4/701-net-0052-sdk_dpaa-ceetm-remove-tc-class-reference-counting.patch deleted file mode 100644 index 473720b41f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0052-sdk_dpaa-ceetm-remove-tc-class-reference-counting.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 024d664114310fe103c2c31f2253bed58238951d Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 17 Jan 2018 16:47:07 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: remove tc class reference counting - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 38 +++------------------- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h | 1 - - 2 files changed, 4 insertions(+), 35 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -774,7 +774,6 @@ static int ceetm_init_prio(struct Qdisc - } - - child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1)); -- child_cl->refcnt = 1; - child_cl->parent = sch; - child_cl->type = CEETM_PRIO; - child_cl->shaped = priv->shaped; -@@ -986,7 +985,6 @@ static int ceetm_init_wbfs(struct Qdisc - } - - child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1)); -- child_cl->refcnt = 1; - child_cl->parent = sch; - child_cl->type = CEETM_WBFS; - child_cl->shaped = priv->shaped; -@@ -1297,29 +1295,9 @@ static void ceetm_attach(struct Qdisc *s - } - } - --static unsigned long ceetm_cls_get(struct Qdisc *sch, u32 classid) -+static unsigned long ceetm_cls_search(struct Qdisc *sch, u32 handle) - { -- struct ceetm_class *cl; -- -- pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n", -- __func__, classid, sch->handle); -- cl = ceetm_find(classid, sch); -- -- if (cl) -- cl->refcnt++; /* Will decrement in put() */ -- return (unsigned long)cl; --} -- --static void ceetm_cls_put(struct Qdisc *sch, unsigned long arg) --{ -- struct ceetm_class *cl = (struct ceetm_class *)arg; -- -- pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n", -- __func__, cl->common.classid, sch->handle); -- cl->refcnt--; -- -- if (cl->refcnt == 0) -- ceetm_cls_destroy(sch, cl); -+ return (unsigned long)ceetm_find(handle, sch); - } - - static int ceetm_cls_change_root(struct ceetm_class *cl, -@@ -1540,7 +1518,6 @@ static int ceetm_cls_change(struct Qdisc - cl->root.tbl = copt->tbl; - - cl->common.classid = classid; -- cl->refcnt = 1; - cl->parent = sch; - cl->root.child = NULL; - cl->root.wbfs_grp_a = false; -@@ -1696,15 +1673,9 @@ static int ceetm_cls_delete(struct Qdisc - - sch_tree_lock(sch); - qdisc_class_hash_remove(&priv->clhash, &cl->common); -- cl->refcnt--; -- -- /* The refcnt should be at least 1 since we have incremented it in -- * get(). Will decrement again in put() where we will call destroy() -- * to actually free the memory if it reaches 0. -- */ -- WARN_ON(cl->refcnt == 0); - - sch_tree_unlock(sch); -+ ceetm_cls_destroy(sch, cl); - return 0; - } - -@@ -1824,8 +1795,7 @@ static void ceetm_tcf_unbind(struct Qdis - const struct Qdisc_class_ops ceetm_cls_ops = { - .graft = ceetm_cls_graft, - .leaf = ceetm_cls_leaf, -- .get = ceetm_cls_get, -- .put = ceetm_cls_put, -+ .find = ceetm_cls_search, - .change = ceetm_cls_change, - .delete = ceetm_cls_delete, - .walk = ceetm_cls_walk, ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h -@@ -191,7 +191,6 @@ struct wbfs_c { - - struct ceetm_class { - struct Qdisc_class_common common; -- int refcnt; /* usage count of this class */ - struct tcf_proto *filter_list; /* class attached filters */ - struct tcf_block *block; - struct Qdisc *parent; diff --git a/target/linux/layerscape/patches-5.4/701-net-0053-sdk_dpaa-ceetm-store-Qdisc-pointer-in-struct-block.patch b/target/linux/layerscape/patches-5.4/701-net-0053-sdk_dpaa-ceetm-store-Qdisc-pointer-in-struct-block.patch deleted file mode 100644 index 7c826cf2b9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0053-sdk_dpaa-ceetm-store-Qdisc-pointer-in-struct-block.patch +++ /dev/null @@ -1,30 +0,0 @@ -From c041c49fc99382976c916438994c3a1caf4ab066 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 17 Jan 2018 17:10:29 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: store Qdisc pointer in struct block - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -1053,7 +1053,7 @@ static int ceetm_init(struct Qdisc *sch, - return -EINVAL; - } - -- ret = tcf_block_get(&priv->block, &priv->filter_list); -+ ret = tcf_block_get(&priv->block, &priv->filter_list, sch); - if (ret) - return ret; - -@@ -1505,7 +1505,7 @@ static int ceetm_cls_change(struct Qdisc - if (!cl) - return -ENOMEM; - -- err = tcf_block_get(&cl->block, &cl->filter_list); -+ err = tcf_block_get(&cl->block, &cl->filter_list, sch); - if (err) { - kfree(cl); - return err; diff --git a/target/linux/layerscape/patches-5.4/701-net-0054-dpaa_eth-workaround-for-ERR010022.patch b/target/linux/layerscape/patches-5.4/701-net-0054-dpaa_eth-workaround-for-ERR010022.patch deleted file mode 100644 index 3c66e5a5f5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0054-dpaa_eth-workaround-for-ERR010022.patch +++ /dev/null @@ -1,299 +0,0 @@ -From fced03d891377fa04153fb0538bc8ca95ba05020 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Tue, 14 Nov 2017 08:12:12 +0200 -Subject: [PATCH] dpaa_eth: workaround for ERR010022 - -On LS1043A SoC there is a known erratum ERR010022 that results in split DMA -transfers in the FMan under certain conditions. This, combined with a fixed -size FIFO of ongoing DMA transfers that may overflow when a split occurs, -results in the FMan stalling DMA transfers under high traffic. To avoid the -problem, one needs to prevent the DMA transfer splits to occur by preparing -the buffers as follows. - -In order to prevent split transactions, all frames need to be aligned to 16 -bytes and not cross 4K address boundaries. To allow Jumbo frames (up to -9.6K), all data must be aligned to 256 byes. This way, 4K boundary crossings -will not trigger any transaction splits. - -The errata is prevented from manifesting by realigning all outgoing frames to -256 byte boundaries. In the process, all S/G frames are linearized. - -Signed-off-by: Madalin Bucur -Signed-off-by: Camelia Groza -[rebase] -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 204 +++++++++++++++++++++++-- - 1 file changed, 194 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -54,6 +54,10 @@ - #include - #include - #include -+#if !defined(CONFIG_PPC) && defined(CONFIG_SOC_BUS) -+#include /* soc_device_match */ -+#endif -+ - #include "fman.h" - #include "fman_port.h" - #include "mac.h" -@@ -73,6 +77,10 @@ static u16 tx_timeout = 1000; - module_param(tx_timeout, ushort, 0444); - MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms"); - -+#ifndef CONFIG_PPC -+bool dpaa_errata_a010022; -+#endif -+ - #define FM_FD_STAT_RX_ERRORS \ - (FM_FD_ERR_DMA | FM_FD_ERR_PHYSICAL | \ - FM_FD_ERR_SIZE | FM_FD_ERR_CLS_DISCARD | \ -@@ -1495,7 +1503,19 @@ static int dpaa_bp_add_8_bufs(const stru - u8 i; - - for (i = 0; i < 8; i++) { -+#ifndef CONFIG_PPC -+ if (dpaa_errata_a010022) { -+ struct page *page = alloc_page(GFP_KERNEL); -+ -+ if (unlikely(!page)) -+ goto release_previous_buffs; -+ new_buf = page_address(page); -+ } else { -+ new_buf = netdev_alloc_frag(dpaa_bp->raw_size); -+ } -+#else - new_buf = netdev_alloc_frag(dpaa_bp->raw_size); -+#endif - if (unlikely(!new_buf)) { - dev_err(dev, "netdev_alloc_frag() failed, size %zu\n", - dpaa_bp->raw_size); -@@ -1663,9 +1683,15 @@ static struct sk_buff *dpaa_cleanup_tx_f - } - } - -- if (qm_fd_get_format(fd) == qm_fd_sg) -- /* Free the page frag that we allocated on Tx */ -- skb_free_frag(phys_to_virt(addr)); -+ if (qm_fd_get_format(fd) == qm_fd_sg) { -+#ifndef CONFIG_PPC -+ if (dpaa_errata_a010022) -+ put_page(virt_to_page(sgt)); -+ else -+#endif -+ /* Free the page frag that we allocated on Tx */ -+ skb_free_frag(phys_to_virt(addr)); -+ } - - return skb; - } -@@ -1922,14 +1948,26 @@ static int skb_to_sg_fd(struct dpaa_priv - size_t frag_len; - void *sgt_buf; - -- /* get a page frag to store the SGTable */ -- sz = SKB_DATA_ALIGN(priv->tx_headroom + DPAA_SGT_SIZE); -- sgt_buf = netdev_alloc_frag(sz); -- if (unlikely(!sgt_buf)) { -- netdev_err(net_dev, "netdev_alloc_frag() failed for size %d\n", -- sz); -- return -ENOMEM; -+#ifndef CONFIG_PPC -+ if (unlikely(dpaa_errata_a010022)) { -+ struct page *page = alloc_page(GFP_ATOMIC); -+ if (unlikely(!page)) -+ return -ENOMEM; -+ sgt_buf = page_address(page); -+ } else { -+#endif -+ /* get a page frag to store the SGTable */ -+ sz = SKB_DATA_ALIGN(priv->tx_headroom + DPAA_SGT_SIZE); -+ sgt_buf = netdev_alloc_frag(sz); -+ if (unlikely(!sgt_buf)) { -+ netdev_err(net_dev, -+ "netdev_alloc_frag() failed for size %d\n", -+ sz); -+ return -ENOMEM; -+ } -+#ifndef CONFIG_PPC - } -+#endif - - /* Enable L3/L4 hardware checksum computation. - * -@@ -2049,6 +2087,122 @@ static inline int dpaa_xmit(struct dpaa_ - return 0; - } - -+#ifndef CONFIG_PPC -+/* On LS1043A SoC there is a known erratum ERR010022 that results in split DMA -+ * transfers in the FMan under certain conditions. This, combined with a fixed -+ * size FIFO of ongoing DMA transfers that may overflow when a split occurs, -+ * results in the FMan stalling DMA transfers under high traffic. To avoid the -+ * problem, one needs to prevent the DMA transfer splits to occur by preparing -+ * the buffers -+ */ -+ -+#define DPAA_A010022_HEADROOM 256 -+#define CROSS_4K_BOUND(start, size) \ -+ (((start) + (size)) > (((start) + 0x1000) & ~0xFFF)) -+ -+static bool dpaa_errata_a010022_has_dma_issue(struct sk_buff *skb, -+ struct dpaa_priv *priv) -+{ -+ int nr_frags, i = 0; -+ skb_frag_t *frag; -+ -+ /* Transfers that do not start at 16B aligned addresses will be split; -+ * Transfers that cross a 4K page boundary will also be split -+ */ -+ -+ /* Check if the frame data is aligned to 16 bytes */ -+ if ((uintptr_t)skb->data % DPAA_FD_DATA_ALIGNMENT) -+ return true; -+ -+ /* Check if the headroom crosses a boundary */ -+ if (CROSS_4K_BOUND((uintptr_t)skb->head, skb_headroom(skb))) -+ return true; -+ -+ /* Check if the non-paged data crosses a boundary */ -+ if (CROSS_4K_BOUND((uintptr_t)skb->data, skb_headlen(skb))) -+ return true; -+ -+ nr_frags = skb_shinfo(skb)->nr_frags; -+ -+ while (i < nr_frags) { -+ frag = &skb_shinfo(skb)->frags[i]; -+ -+ /* Check if a paged fragment crosses a boundary from its -+ * offset to its end. -+ */ -+ if (CROSS_4K_BOUND((uintptr_t)frag->page_offset, frag->size)) -+ return true; -+ -+ i++; -+ } -+ -+ return false; -+} -+ -+static struct sk_buff *dpaa_errata_a010022_prevent(struct sk_buff *skb, -+ struct dpaa_priv *priv) -+{ -+ int trans_offset = skb_transport_offset(skb); -+ int net_offset = skb_network_offset(skb); -+ int nsize, npage_order, headroom; -+ struct sk_buff *nskb = NULL; -+ struct page *npage; -+ void *npage_addr; -+ -+ if (!dpaa_errata_a010022_has_dma_issue(skb, priv)) -+ return skb; -+ -+ /* For the new skb we only need the old one's data (both non-paged and -+ * paged). We can skip the old tailroom. -+ * -+ * The headroom also needs to fit our private info (64 bytes) but we -+ * reserve 256 bytes instead in order to guarantee that the data is -+ * aligned to 256. -+ */ -+ headroom = DPAA_A010022_HEADROOM; -+ nsize = headroom + skb->len + -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -+ -+ /* Reserve enough memory to accommodate Jumbo frames */ -+ npage_order = (nsize - 1) / PAGE_SIZE; -+ npage = alloc_pages(GFP_ATOMIC | __GFP_COMP, npage_order); -+ if (unlikely(!npage)) { -+ WARN_ONCE(1, "Memory allocation failure\n"); -+ return NULL; -+ } -+ npage_addr = page_address(npage); -+ -+ nskb = build_skb(npage_addr, nsize); -+ if (unlikely(!nskb)) -+ goto err; -+ -+ /* Code borrowed and adapted from skb_copy() */ -+ skb_reserve(nskb, headroom); -+ skb_put(nskb, skb->len); -+ if (skb_copy_bits(skb, 0, nskb->data, skb->len)) { -+ WARN_ONCE(1, "skb parsing failure\n"); -+ goto err; -+ } -+ copy_skb_header(nskb, skb); -+ -+ /* We move the headroom when we align it so we have to reset the -+ * network and transport header offsets relative to the new data -+ * pointer. The checksum offload relies on these offsets. -+ */ -+ skb_set_network_header(nskb, net_offset); -+ skb_set_transport_header(nskb, trans_offset); -+ -+ dev_kfree_skb(skb); -+ return nskb; -+ -+err: -+ if (nskb) -+ dev_kfree_skb(nskb); -+ put_page(npage); -+ return NULL; -+} -+#endif -+ - static netdev_tx_t - dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev) - { -@@ -2095,6 +2249,15 @@ dpaa_start_xmit(struct sk_buff *skb, str - nonlinear = skb_is_nonlinear(skb); - } - -+#ifndef CONFIG_PPC -+ if (unlikely(dpaa_errata_a010022)) { -+ skb = dpaa_errata_a010022_prevent(skb, priv); -+ if (!skb) -+ goto enomem; -+ nonlinear = skb_is_nonlinear(skb); -+ } -+#endif -+ - if (nonlinear) { - /* Just create a S/G fd based on the skb */ - err = skb_to_sg_fd(priv, skb, &fd); -@@ -2992,6 +3155,23 @@ static int dpaa_remove(struct platform_d - return err; - } - -+#ifndef CONFIG_PPC -+static bool __init soc_has_errata_a010022(void) -+{ -+#ifdef CONFIG_SOC_BUS -+ const struct soc_device_attribute soc_msi_matches[] = { -+ { .family = "QorIQ LS1043A", -+ .data = NULL }, -+ { }, -+ }; -+ -+ if (!soc_device_match(soc_msi_matches)) -+ return false; -+#endif -+ return true; /* cannot identify SoC or errata applies */ -+} -+#endif -+ - static const struct platform_device_id dpaa_devtype[] = { - { - .name = "dpaa-ethernet", -@@ -3016,6 +3196,10 @@ static int __init dpaa_load(void) - - pr_debug("FSL DPAA Ethernet driver\n"); - -+#ifndef CONFIG_PPC -+ /* Detect if the current SoC requires the DMA transfer alignment workaround */ -+ dpaa_errata_a010022 = soc_has_errata_a010022(); -+#endif - /* initialize dpaa_eth mirror values */ - dpaa_rx_extra_headroom = fman_get_rx_extra_headroom(); - dpaa_max_frm = fman_get_max_frm(); diff --git a/target/linux/layerscape/patches-5.4/701-net-0055-sdk_fman-DPAA-dTSEC-ports-fail-to-work-when-link-cha.patch b/target/linux/layerscape/patches-5.4/701-net-0055-sdk_fman-DPAA-dTSEC-ports-fail-to-work-when-link-cha.patch deleted file mode 100644 index e17c2a7a4d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0055-sdk_fman-DPAA-dTSEC-ports-fail-to-work-when-link-cha.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 2b3d05ed1cb560b3a0b0721435c2fd73a19bd9bc Mon Sep 17 00:00:00 2001 -From: Iordache Florinel-R70177 -Date: Mon, 29 May 2017 09:25:24 +0300 -Subject: [PATCH] sdk_fman: DPAA-dTSEC ports fail to work when link changes - -Signed-off-by: Iordache Florinel-R70177 ---- - .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c | 57 ++++++++++++++++++---- - 1 file changed, 48 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c -@@ -386,6 +386,7 @@ static void FreeInitResources(t_Dtsec *p - static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode) - { - struct dtsec_regs *p_MemMap; -+ int pollTimeout = 0; - - ASSERT_COND(p_Dtsec); - -@@ -408,16 +409,32 @@ static t_Error GracefulStop(t_Dtsec *p_D - } - - if (mode & e_COMM_MODE_TX) --#if defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012) -- if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2) -- DBG(INFO, ("GTS not supported due to DTSEC_A004 errata.")); --#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) ||... */ --#ifdef FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 -- DBG(INFO, ("GTS not supported due to DTSEC_A0014 errata.")); --#else /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */ -+ { -+#if defined(FM_GTS_ERRATA_DTSEC_A004) -+ if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2) -+ DBG(INFO, ("GTS not supported due to DTSEC_A004 errata.")); -+#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) */ -+ - fman_dtsec_stop_tx(p_MemMap); --#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */ --#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) ||... */ -+ -+#if defined(FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012) -+ XX_UDelay(10); -+#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 || FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012 */ -+#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) */ -+ } -+ -+ /* Poll GRSC/GTSC bits in IEVENT register until both are set */ -+#if defined(FM_GRS_ERRATA_DTSEC_A002) || defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012) || defined(FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014) || defined(FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839) -+ XX_UDelay(10); -+#else -+ while (fman_dtsec_get_event(p_MemMap, DTSEC_IMASK_GRSCEN | DTSEC_IMASK_GTSCEN) != (DTSEC_IMASK_GRSCEN | DTSEC_IMASK_GTSCEN)) -+ { -+ if (pollTimeout == 100) -+ break; -+ XX_UDelay(1); -+ pollTimeout++; -+ } -+#endif - - return E_OK; - } -@@ -632,7 +649,12 @@ static t_Error DtsecSetTxPauseFrames(t_H - " value should be greater than 320.")); - #endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */ - -+ GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX); -+ - fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime); -+ -+ GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX); -+ - return E_OK; - } - -@@ -653,8 +675,12 @@ static t_Error DtsecRxIgnoreMacPause(t_H - SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - -+ GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX); -+ - fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause); - -+ GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX); -+ - return E_OK; - } - -@@ -787,8 +813,13 @@ static t_Error DtsecModifyMacAddress (t_ - /* Initialize MAC Station Address registers (1 & 2) */ - /* Station address have to be swapped (big endian to little endian */ - p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr); -+ -+ GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX); -+ - fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr)); - -+ GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX); -+ - return E_OK; - } - -@@ -1076,8 +1107,12 @@ static t_Error DtsecSetWakeOnLan(t_Handl - SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE); - SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE); - -+ GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX); -+ - fman_dtsec_set_wol(p_Dtsec->p_MemMap, en); - -+ GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX); -+ - return E_OK; - } - -@@ -1098,11 +1133,15 @@ static t_Error DtsecAdjustLink(t_Handle - enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode); - p_Dtsec->halfDuplex = !fullDuplex; - -+ GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX); -+ - err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex); - - if (err == -EINVAL) - RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode")); - -+ GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX); -+ - return (t_Error)err; - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0056-sdk-dpa-adapt-compatibles-to-upstream-binding-docume.patch b/target/linux/layerscape/patches-5.4/701-net-0056-sdk-dpa-adapt-compatibles-to-upstream-binding-docume.patch deleted file mode 100644 index c1903a2bb3..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0056-sdk-dpa-adapt-compatibles-to-upstream-binding-docume.patch +++ /dev/null @@ -1,25 +0,0 @@ -From d3ec1bf411a208028d06ffbb0f0ed461096977a8 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Fri, 20 Oct 2017 16:42:26 +0300 -Subject: [PATCH] sdk: dpa: adapt compatibles to upstream binding document - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/mac.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c -@@ -133,10 +133,10 @@ static int __cold free_macdev(struct mac - - static const struct of_device_id mac_match[] = { - [DTSEC] = { -- .compatible = "fsl,fman-1g-mac" -+ .compatible = "fsl,fman-dtsec" - }, - [XGMAC] = { -- .compatible = "fsl,fman-10g-mac" -+ .compatible = "fsl,fman-xgec" - }, - [MEMAC] = { - .compatible = "fsl,fman-memac" diff --git a/target/linux/layerscape/patches-5.4/701-net-0057-sdk_fman-fix-probing-of-10G-ports-on-T102x.patch b/target/linux/layerscape/patches-5.4/701-net-0057-sdk_fman-fix-probing-of-10G-ports-on-T102x.patch deleted file mode 100644 index e772c95977..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0057-sdk_fman-fix-probing-of-10G-ports-on-T102x.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 7dd27606d9b7f28a7367e4b9444bed7d573f4b6c Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Fri, 23 Mar 2018 16:33:19 +0200 -Subject: [PATCH] sdk_fman: fix probing of 10G ports on T102x - -Signed-off-by: Camelia Groza ---- - .../sdk_fman/src/wrapper/lnxwrp_fm_port.c | 24 +++++++++++++++++----- - 1 file changed, 19 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c -@@ -388,7 +388,14 @@ static t_LnxWrpFmPortDev *ReadFmPortDevT - settings.param.specificParams.nonRxParams.qmChannel = - p_LnxWrpFmPortDev->txCh; - } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) { -+#ifndef CONFIG_FMAN_ARM -+ /* On T102x, the 10G TX port IDs start from 0x28 */ -+ if (IS_T1023_T1024) -+ tmp_prop -= 0x28; -+ else -+#endif - tmp_prop -= 0x30; -+ - if (unlikely(tmp_prop>= FM_MAX_NUM_OF_10G_TX_PORTS)) { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, - ("of_get_property(%s, cell-index) failed", -@@ -399,7 +406,7 @@ static t_LnxWrpFmPortDev *ReadFmPortDevT - FM_MAX_NUM_OF_1G_TX_PORTS]; - #ifndef CONFIG_FMAN_ARM - if (IS_T1023_T1024) -- p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[*uint32_prop]; -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop]; - #endif - - p_LnxWrpFmPortDev->id = tmp_prop; -@@ -437,7 +444,14 @@ static t_LnxWrpFmPortDev *ReadFmPortDevT - if (p_LnxWrpFmDev->pcdActive) - p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd; - } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-rx")) { -+#ifndef CONFIG_FMAN_ARM -+ /* On T102x, the 10G RX port IDs start from 0x08 */ -+ if (IS_T1023_T1024) -+ tmp_prop -= 0x8; -+ else -+#endif - tmp_prop -= 0x10; -+ - if (unlikely(tmp_prop >= FM_MAX_NUM_OF_10G_RX_PORTS)) { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, - ("of_get_property(%s, cell-index) failed", -@@ -449,7 +463,7 @@ static t_LnxWrpFmPortDev *ReadFmPortDevT - - #ifndef CONFIG_FMAN_ARM - if (IS_T1023_T1024) -- p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[*uint32_prop]; -+ p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop]; - #endif - - p_LnxWrpFmPortDev->id = tmp_prop; -@@ -637,7 +651,7 @@ static t_Error CheckNConfigFmPortAdvArgs - uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes", - &lenp); - if (uint32_prop) { -- -+ - if (WARN_ON(lenp != sizeof(uint32_t)*8)) - RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); - if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType != -@@ -671,7 +685,7 @@ static t_Error CheckNConfigFmPortAdvArgs - if (uint32_prop) { - if (WARN_ON(lenp != sizeof(uint32_t)*3)) - RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG); -- -+ - p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering = - (uint16_t)be32_to_cpu(uint32_prop[0]); - p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering = -@@ -679,7 +693,7 @@ static t_Error CheckNConfigFmPortAdvArgs - p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering = - (uint16_t)be32_to_cpu(uint32_prop[2]); - } -- -+ - if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev, - (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK) - RETURN_ERROR(MINOR, err, NO_MSG); diff --git a/target/linux/layerscape/patches-5.4/701-net-0058-sdk_fman-probe-OH-ports-on-PPC.patch b/target/linux/layerscape/patches-5.4/701-net-0058-sdk_fman-probe-OH-ports-on-PPC.patch deleted file mode 100644 index 31d86dd59e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0058-sdk_fman-probe-OH-ports-on-PPC.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 11a68a2d48fee4524163c5ce36477bafb6515a98 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 26 Mar 2018 10:48:19 +0300 -Subject: [PATCH] sdk_fman: probe OH ports on PPC - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c -@@ -303,7 +303,13 @@ static t_LnxWrpFmPortDev *ReadFmPortDevT - tmp_prop = be32_to_cpu(*uint32_prop); - if (WARN_ON(lenp != sizeof(uint32_t))) - return NULL; -- if (of_device_is_compatible(port_node, "fsl,fman-port-oh")) { -+ if (of_device_is_compatible(port_node, "fsl,fman-port-oh") || -+ of_device_is_compatible(port_node, "fsl,fman-v2-port-oh") || -+ of_device_is_compatible(port_node, "fsl,fman-v3-port-oh")) { -+#ifndef CONFIG_FMAN_ARM -+ /* On PPC, OH ports start from cell-index 0x2 */ -+ tmp_prop -= 0x2; -+#endif - if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, - ("of_get_property(%s, cell-index) failed", -@@ -1433,6 +1439,10 @@ static const struct of_device_id fm_port - { - .compatible = "fsl,fman-port-oh"}, - { -+ .compatible = "fsl,fman-v2-port-oh"}, -+ { -+ .compatible = "fsl,fman-v3-port-oh"}, -+ { - .compatible = "fsl,fman-port-1g-rx"}, - { - .compatible = "fsl,fman-port-10g-rx"}, diff --git a/target/linux/layerscape/patches-5.4/701-net-0059-sdk_fman-on-P-series-platforms-the-OH-ports-start-at.patch b/target/linux/layerscape/patches-5.4/701-net-0059-sdk_fman-on-P-series-platforms-the-OH-ports-start-at.patch deleted file mode 100644 index 6afc1c07f7..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0059-sdk_fman-on-P-series-platforms-the-OH-ports-start-at.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 7eb5f0a192efbe1fa94490881858ed45c5373233 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 2 Apr 2018 18:19:27 +0300 -Subject: [PATCH] sdk_fman: on P-series platforms, the OH ports start at offset - 1 - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c -@@ -307,9 +307,17 @@ static t_LnxWrpFmPortDev *ReadFmPortDevT - of_device_is_compatible(port_node, "fsl,fman-v2-port-oh") || - of_device_is_compatible(port_node, "fsl,fman-v3-port-oh")) { - #ifndef CONFIG_FMAN_ARM -- /* On PPC, OH ports start from cell-index 0x2 */ -+#ifdef CONFIG_FMAN_P3040_P4080_P5020 -+ /* On PPC FMan v2, OH ports start from cell-index 0x1 */ -+ tmp_prop -= 0x1; -+#else -+ /* On PPC FMan v3 (Low and High), OH ports start from -+ * cell-index 0x2 -+ */ - tmp_prop -= 0x2; --#endif -+#endif // CONFIG_FMAN_P3040_P4080_P5020 -+#endif // CONFIG_FMAN_ARM -+ - if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) { - REPORT_ERROR(MAJOR, E_INVALID_VALUE, - ("of_get_property(%s, cell-index) failed", diff --git a/target/linux/layerscape/patches-5.4/701-net-0060-sdk_fman-disable-timer-code.patch b/target/linux/layerscape/patches-5.4/701-net-0060-sdk_fman-disable-timer-code.patch deleted file mode 100644 index 6b8df304c5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0060-sdk_fman-disable-timer-code.patch +++ /dev/null @@ -1,32 +0,0 @@ -From de27589a9862f51d2f62eda586f18dfc128af143 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Wed, 18 Apr 2018 08:58:09 +0300 -Subject: [PATCH] sdk_fman: disable timer code - -The (unused) timer code is no longer compatible with the newer -kernel API. Disabling the incompatible code. - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c -@@ -614,7 +614,7 @@ uint32_t XX_CurrentTime(void) - return (jiffies*1000)/HZ; - } - -- -+#if 0 - t_Handle XX_CreateTimer(void) - { - struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list)); -@@ -691,6 +691,7 @@ int XX_TimerIsActive(t_Handle h_Timer) - { - return timer_pending((struct timer_list *)h_Timer); - } -+#endif - - uint32_t XX_Sleep(uint32_t msecs) - { diff --git a/target/linux/layerscape/patches-5.4/701-net-0061-sdk_fman-disable-timer-code-in-arm-code.patch b/target/linux/layerscape/patches-5.4/701-net-0061-sdk_fman-disable-timer-code-in-arm-code.patch deleted file mode 100644 index 9822f525ef..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0061-sdk_fman-disable-timer-code-in-arm-code.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 796f8a61e866183425a54fd8b45d5ccaebadad78 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Wed, 18 Apr 2018 23:02:36 +0300 -Subject: [PATCH] sdk_fman: disable timer code in arm code - -The (unused) timer code is no longer compatible with the newer -kernel API. Disabling the incompatible code in the arm64 code. - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c -@@ -607,7 +607,7 @@ uint32_t XX_CurrentTime(void) - return (jiffies*1000)/HZ; - } - -- -+#if 0 - t_Handle XX_CreateTimer(void) - { - struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list)); -@@ -684,6 +684,7 @@ int XX_TimerIsActive(t_Handle h_Timer) - { - return timer_pending((struct timer_list *)h_Timer); - } -+#endif - - uint32_t XX_Sleep(uint32_t msecs) - { diff --git a/target/linux/layerscape/patches-5.4/701-net-0062-sdk_dpa-adapt-ceetm-code-to-new-kernel-API.patch b/target/linux/layerscape/patches-5.4/701-net-0062-sdk_dpa-adapt-ceetm-code-to-new-kernel-API.patch deleted file mode 100644 index 0df0aaedb9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0062-sdk_dpa-adapt-ceetm-code-to-new-kernel-API.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 4026225a854760fa355e393a386b6c96d794bce2 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Tue, 24 Apr 2018 17:07:25 +0300 -Subject: [PATCH] sdk_dpa: adapt ceetm code to new kernel API - -Signed-off-by: Madalin Bucur ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 26 +++++++++++++--------- - 1 file changed, 16 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -577,7 +577,8 @@ nla_put_failure: - - /* Configure a root ceetm qdisc */ - static int ceetm_init_root(struct Qdisc *sch, struct ceetm_qdisc *priv, -- struct tc_ceetm_qopt *qopt) -+ struct tc_ceetm_qopt *qopt, -+ struct netlink_ext_ack *extack) - { - struct netdev_queue *dev_queue; - struct Qdisc *qdisc; -@@ -622,7 +623,7 @@ static int ceetm_init_root(struct Qdisc - TC_H_MIN(i + PFIFO_MIN_OFFSET)); - - qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops, -- parent_id); -+ parent_id, extack); - if (!qdisc) { - err = -ENOMEM; - goto err_init_root; -@@ -1035,7 +1036,8 @@ err_init_wbfs: - } - - /* Configure a generic ceetm qdisc */ --static int ceetm_init(struct Qdisc *sch, struct nlattr *opt) -+static int ceetm_init(struct Qdisc *sch, struct nlattr *opt, -+ struct netlink_ext_ack *extack) - { - struct tc_ceetm_qopt *qopt; - struct nlattr *tb[TCA_CEETM_QOPS + 1]; -@@ -1053,7 +1055,7 @@ static int ceetm_init(struct Qdisc *sch, - return -EINVAL; - } - -- ret = tcf_block_get(&priv->block, &priv->filter_list, sch); -+ ret = tcf_block_get(&priv->block, &priv->filter_list, sch, extack); - if (ret) - return ret; - -@@ -1087,7 +1089,7 @@ static int ceetm_init(struct Qdisc *sch, - - switch (priv->type) { - case CEETM_ROOT: -- ret = ceetm_init_root(sch, priv, qopt); -+ ret = ceetm_init_root(sch, priv, qopt, extack); - break; - case CEETM_PRIO: - ret = ceetm_init_prio(sch, priv, qopt); -@@ -1224,7 +1226,8 @@ change_err: - } - - /* Edit a ceetm qdisc */ --static int ceetm_change(struct Qdisc *sch, struct nlattr *opt) -+static int ceetm_change(struct Qdisc *sch, struct nlattr *opt, -+ struct netlink_ext_ack *extack) - { - struct tc_ceetm_qopt *qopt; - struct nlattr *tb[TCA_CEETM_QOPS + 1]; -@@ -1410,7 +1413,8 @@ static int ceetm_cls_change_wbfs(struct - - /* Add a ceetm root class or configure a ceetm root/prio/wbfs class */ - static int ceetm_cls_change(struct Qdisc *sch, u32 classid, u32 parentid, -- struct nlattr **tca, unsigned long *arg) -+ struct nlattr **tca, unsigned long *arg, -+ struct netlink_ext_ack *extack) - { - int err; - u64 bps; -@@ -1505,7 +1509,7 @@ static int ceetm_cls_change(struct Qdisc - if (!cl) - return -ENOMEM; - -- err = tcf_block_get(&cl->block, &cl->filter_list, sch); -+ err = tcf_block_get(&cl->block, &cl->filter_list, sch, extack); - if (err) { - kfree(cl); - return err; -@@ -1699,7 +1703,8 @@ static struct Qdisc *ceetm_cls_leaf(stru - } - - static int ceetm_cls_graft(struct Qdisc *sch, unsigned long arg, -- struct Qdisc *new, struct Qdisc **old) -+ struct Qdisc *new, struct Qdisc **old, -+ struct netlink_ext_ack *extack) - { - if (new && strcmp(new->ops->id, ceetm_qdisc_ops.id)) { - pr_err("CEETM: only ceetm qdiscs can be attached to ceetm classes\n"); -@@ -1763,7 +1768,8 @@ static int ceetm_cls_dump_stats(struct Q - return gnet_stats_copy_app(d, &xstats, sizeof(xstats)); - } - --static struct tcf_block *ceetm_tcf_block(struct Qdisc *sch, unsigned long arg) -+static struct tcf_block *ceetm_tcf_block(struct Qdisc *sch, unsigned long arg, -+ struct netlink_ext_ack *extack) - { - struct ceetm_qdisc *priv = qdisc_priv(sch); - struct ceetm_class *cl = (struct ceetm_class *)arg; diff --git a/target/linux/layerscape/patches-5.4/701-net-0063-sdk_dpaa-propagate-the-skb-ownership-information.patch b/target/linux/layerscape/patches-5.4/701-net-0063-sdk_dpaa-propagate-the-skb-ownership-information.patch deleted file mode 100644 index f906dc9771..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0063-sdk_dpaa-propagate-the-skb-ownership-information.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 1a5fe4c83c7ba997a7fc433fcfc4818d48689ecc Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Wed, 25 Apr 2018 18:49:32 +0300 -Subject: [PATCH] sdk_dpaa: propagate the skb ownership information - -Some skbs on the Tx path may be reallocated by the driver -due to insufficient headroom, in which case the socket -value gets lost. - -Make sure we propagate the skb ownership information to the -new skb, since it's needed by the Tx timestamp function in -the kernel. - -Signed-off-by: Ioana Radulescu -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -1113,6 +1113,11 @@ int __hot dpa_tx_extended(struct sk_buff - percpu_stats->tx_errors++; - return NETDEV_TX_OK; - } -+ -+ /* propagate the skb ownership information */ -+ if (skb->sk) -+ skb_set_owner_w(skb_new, skb->sk); -+ - dev_kfree_skb(skb); - skb = skb_new; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0064-memac_init_phy-RGMII-fixed-link-pass-adjust_link-cal.patch b/target/linux/layerscape/patches-5.4/701-net-0064-memac_init_phy-RGMII-fixed-link-pass-adjust_link-cal.patch deleted file mode 100644 index 7271c34ab5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0064-memac_init_phy-RGMII-fixed-link-pass-adjust_link-cal.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 79eacb8b197f7459a75c7d3ec33ceef88475d5a1 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Fri, 4 May 2018 19:23:59 +0300 -Subject: [PATCH] memac_init_phy: RGMII fixed-link: pass adjust_link callback - to of_phy_connect - -* The mEMAC configuration for RGMII is held in the IF_MODE register -* In the driver, IF_MODE is configured in 2 places (both in fman_memac.c): - - fman_memac_init: sets the IF_MODE bit macro IF_MODE_RGMII_AUTO - (this translates to setting ENA = 1 - Enable automatic speed selection - - RGMII PHY in-band status information is used to select the speed - of operation). - - fman_memac_adjust_link: brings the RGMII port in ENA = 0 mode - (link speed not determined autonomously by the MAC, but set according - to SSP). -* The issue with the current code is that in the case of RGMII fixed-link, - the of_phy_attach function is being called, instead of of_phy_connect - with a callback that calls fman_memac_adjust_link. -* For this reason, the RGMII port is left in a state with ENA = 1. In - most (if not all) RGMII fixed-link setups, the link partner will not - send any in-bank link speed information that is expected by the mEMAC. -* The effect is that the link speed setting will probably not be correct - (and will definitely not be according to the "fixed-link" property in - the DTS). -* The adjust_link callback seems to be called by the PHY state machine, - even for fixed links, exactly once: on "link up". Therefore, this - patch ensures that on link up, RGMII fixed links are configured to the - link speed that is set in the DTS, and not left with IF_MODE[ENA] = 1. - -Signed-off-by: Vladimir Oltean ---- - drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c | 38 ++++++++++++++++++----- - 1 file changed, 31 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c -@@ -502,17 +502,41 @@ static int memac_init_phy(struct net_dev - struct mac_device *mac_dev) - { - struct phy_device *phy_dev; -+ void (*adjust_link_handler)(struct net_device *); - - if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) || -- (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500) || -- of_phy_is_fixed_link(mac_dev->phy_node)) { -- phy_dev = of_phy_connect(net_dev, mac_dev->phy_node, -- &adjust_link_void, 0, -- mac_dev->phy_if); -+ (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500)) { -+ /* Pass a void link state handler to the PHY state machine -+ * for XGMII (10G) and SGMII 2.5G, as the hardware does not -+ * permit dynamic link speed adjustments. */ -+ adjust_link_handler = adjust_link_void; -+ } else if (macdev2enetinterface(mac_dev) & e_ENET_IF_RGMII) { -+ /* Regular RGMII ports connected to a PHY, as well as -+ * ports that are marked as "fixed-link" in the DTS, -+ * will have the adjust_link callback. This calls -+ * fman_memac_adjust_link in order to configure the -+ * IF_MODE register, which is needed in both cases. -+ */ -+ adjust_link_handler = adjust_link; -+ } else if (of_phy_is_fixed_link(mac_dev->phy_node)) { -+ /* Pass a void link state handler for fixed-link -+ * interfaces that are not RGMII. Only RGMII has been -+ * tested and confirmed to work with fixed-link. Other -+ * MII interfaces may need further work. -+ * TODO: Change this as needed. -+ */ -+ adjust_link_handler = adjust_link_void; - } else { -- phy_dev = of_phy_connect(net_dev, mac_dev->phy_node, -- &adjust_link, 0, mac_dev->phy_if); -+ /* MII, RMII, SMII, GMII, SGMII, BASEX ports, -+ * that are NOT fixed-link. -+ * TODO: May not be needed for interfaces that -+ * pass through the SerDes block (*SGMII, XFI). -+ */ -+ adjust_link_handler = adjust_link; - } -+ phy_dev = of_phy_connect(net_dev, mac_dev->phy_node, -+ adjust_link_handler, 0, -+ mac_dev->phy_if); - - if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) { - netdev_err(net_dev, "Could not connect to PHY %s\n", diff --git a/target/linux/layerscape/patches-5.4/701-net-0065-sdk_dpaa-ceetm-avoid-use-after-free-scenarios.patch b/target/linux/layerscape/patches-5.4/701-net-0065-sdk_dpaa-ceetm-avoid-use-after-free-scenarios.patch deleted file mode 100644 index f3d591ec0e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0065-sdk_dpaa-ceetm-avoid-use-after-free-scenarios.patch +++ /dev/null @@ -1,67 +0,0 @@ -From fad6f73dc4367adb852ce6953f93f12cbb97b894 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Fri, 18 May 2018 10:33:37 +0300 -Subject: [PATCH] sdk_dpaa: ceetm: avoid use-after-free scenarios - -Once the pfiofo qdiscs are grafted to the netdev queues, they are destroyed -by the kernel when required. Remove references to the pfifo qdiscs after -grafting, in order to avoid double free scenarios. - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 23 +++++++++++++++++++--- - 1 file changed, 20 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -477,7 +477,9 @@ static void ceetm_destroy(struct Qdisc * - if (!priv->root.qdiscs) - break; - -- /* Remove the pfifo qdiscs */ -+ /* Destroy the pfifo qdiscs in case they haven't been attached -+ * to the netdev queues yet. -+ */ - for (ntx = 0; ntx < dev->num_tx_queues; ntx++) - if (priv->root.qdiscs[ntx]) - qdisc_destroy(priv->root.qdiscs[ntx]); -@@ -608,7 +610,16 @@ static int ceetm_init_root(struct Qdisc - goto err_init_root; - } - -- /* pre-allocate underlying pfifo qdiscs */ -+ /* Pre-allocate underlying pfifo qdiscs. -+ * -+ * We want to offload shaping and scheduling decisions to the hardware. -+ * The pfifo qdiscs will be attached to the netdev queues and will -+ * guide the traffic from the IP stack down to the driver with minimum -+ * interference. -+ * -+ * The CEETM qdiscs and classes will be crossed when the traffic -+ * reaches the driver. -+ */ - priv->root.qdiscs = kcalloc(dev->num_tx_queues, - sizeof(priv->root.qdiscs[0]), - GFP_KERNEL); -@@ -1280,7 +1291,10 @@ static int ceetm_change(struct Qdisc *sc - return ret; - } - --/* Attach the underlying pfifo qdiscs */ -+/* Graft the underlying pfifo qdiscs to the netdev queues. -+ * It's safe to remove our references at this point, since the kernel will -+ * destroy the qdiscs on its own and no cleanup from our part is required. -+ */ - static void ceetm_attach(struct Qdisc *sch) - { - struct net_device *dev = qdisc_dev(sch); -@@ -1296,6 +1310,9 @@ static void ceetm_attach(struct Qdisc *s - if (old_qdisc) - qdisc_destroy(old_qdisc); - } -+ -+ kfree(priv->root.qdiscs); -+ priv->root.qdiscs = NULL; - } - - static unsigned long ceetm_cls_search(struct Qdisc *sch, u32 handle) diff --git a/target/linux/layerscape/patches-5.4/701-net-0066-sdk_dpaa-ceetm-stop-the-netdev-queues-when-switching.patch b/target/linux/layerscape/patches-5.4/701-net-0066-sdk_dpaa-ceetm-stop-the-netdev-queues-when-switching.patch deleted file mode 100644 index 49c0e2e630..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0066-sdk_dpaa-ceetm-stop-the-netdev-queues-when-switching.patch +++ /dev/null @@ -1,23 +0,0 @@ -From ceecb6c2de60f19c674d4e59dde2523db7a9099b Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 19 Mar 2018 18:39:59 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: stop the netdev queues when switching ceetm - on - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -1100,7 +1100,9 @@ static int ceetm_init(struct Qdisc *sch, - - switch (priv->type) { - case CEETM_ROOT: -+ netif_tx_stop_all_queues(dev); - ret = ceetm_init_root(sch, priv, qopt, extack); -+ netif_tx_wake_all_queues(dev); - break; - case CEETM_PRIO: - ret = ceetm_init_prio(sch, priv, qopt); diff --git a/target/linux/layerscape/patches-5.4/701-net-0067-fsl_qbman-ceetm-export-the-qman_ceetm_query_cq-call.patch b/target/linux/layerscape/patches-5.4/701-net-0067-fsl_qbman-ceetm-export-the-qman_ceetm_query_cq-call.patch deleted file mode 100644 index da4a48040a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0067-fsl_qbman-ceetm-export-the-qman_ceetm_query_cq-call.patch +++ /dev/null @@ -1,31 +0,0 @@ -From d4ef67474d985f6a95ea54a7e0c11d6d0ffa9fe9 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 26 Mar 2018 17:12:17 +0300 -Subject: [PATCH] fsl_qbman: ceetm: export the qman_ceetm_query_cq call - -Signed-off-by: Camelia Groza ---- - include/linux/fsl_qman.h | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/include/linux/fsl_qman.h -+++ b/include/linux/fsl_qman.h -@@ -3813,6 +3813,18 @@ int qman_ceetm_query_lfqmt(int lfqid, - struct qm_mcr_ceetm_lfqmt_query *lfqmt_query); - - /** -+ * qman_ceetm_query_cq - Queries a CEETM CQ -+ * @cqid: the channel ID (first byte) followed by the CQ idx -+ * @dcpid: CEETM portal ID -+ * @cq_query: storage for the queried CQ fields -+ * -+ * Returns zero for success or -EIO if the query command returns error. -+ * -+*/ -+int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid, -+ struct qm_mcr_ceetm_cq_query *cq_query); -+ -+/** - * qman_ceetm_query_write_statistics - Query (and optionally write) statistics - * @cid: Target ID (CQID or CCGRID) - * @dcp_idx: CEETM portal ID diff --git a/target/linux/layerscape/patches-5.4/701-net-0068-sdk_dpaa-ceetm-propagate-the-ceetm-channel-through-t.patch b/target/linux/layerscape/patches-5.4/701-net-0068-sdk_dpaa-ceetm-propagate-the-ceetm-channel-through-t.patch deleted file mode 100644 index f10670241c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0068-sdk_dpaa-ceetm-propagate-the-ceetm-channel-through-t.patch +++ /dev/null @@ -1,298 +0,0 @@ -From dfd2deb8bc482588999a4f03b5ab5d049e50fdb0 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 30 May 2018 14:51:35 +0300 -Subject: [PATCH] sdk_dpaa: ceetm: propagate the ceetm channel through the - qdisc tree - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 61 +++++++++------------- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h | 4 +- - 2 files changed, 29 insertions(+), 36 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -242,7 +242,6 @@ static int ceetm_config_lfq(struct qm_ce - /* Configure a prio ceetm class */ - static int ceetm_config_prio_cls(struct ceetm_class *cls, - struct net_device *dev, -- struct qm_ceetm_channel *channel, - unsigned int id) - { - int err; -@@ -253,22 +252,22 @@ static int ceetm_config_prio_cls(struct - return err; - - /* Claim and configure the CCG */ -- err = ceetm_config_ccg(&cls->prio.ccg, channel, id, cls->prio.fq, -+ err = ceetm_config_ccg(&cls->prio.ccg, cls->ch, id, cls->prio.fq, - dpa_priv); - if (err) - return err; - - /* Claim and configure the CQ */ -- err = qman_ceetm_cq_claim(&cls->prio.cq, channel, id, cls->prio.ccg); -+ err = qman_ceetm_cq_claim(&cls->prio.cq, cls->ch, id, cls->prio.ccg); - if (err) - return err; - - if (cls->shaped) { -- err = qman_ceetm_channel_set_cq_cr_eligibility(channel, id, 1); -+ err = qman_ceetm_channel_set_cq_cr_eligibility(cls->ch, id, 1); - if (err) - return err; - -- err = qman_ceetm_channel_set_cq_er_eligibility(channel, id, 1); -+ err = qman_ceetm_channel_set_cq_er_eligibility(cls->ch, id, 1); - if (err) - return err; - } -@@ -284,7 +283,6 @@ static int ceetm_config_prio_cls(struct - /* Configure a wbfs ceetm class */ - static int ceetm_config_wbfs_cls(struct ceetm_class *cls, - struct net_device *dev, -- struct qm_ceetm_channel *channel, - unsigned int id, int type) - { - int err; -@@ -295,17 +293,17 @@ static int ceetm_config_wbfs_cls(struct - return err; - - /* Claim and configure the CCG */ -- err = ceetm_config_ccg(&cls->wbfs.ccg, channel, id, cls->wbfs.fq, -+ err = ceetm_config_ccg(&cls->wbfs.ccg, cls->ch, id, cls->wbfs.fq, - dpa_priv); - if (err) - return err; - - /* Claim and configure the CQ */ - if (type == WBFS_GRP_B) -- err = qman_ceetm_cq_claim_B(&cls->wbfs.cq, channel, id, -+ err = qman_ceetm_cq_claim_B(&cls->wbfs.cq, cls->ch, id, - cls->wbfs.ccg); - else -- err = qman_ceetm_cq_claim_A(&cls->wbfs.cq, channel, id, -+ err = qman_ceetm_cq_claim_A(&cls->wbfs.cq, cls->ch, id, - cls->wbfs.ccg); - if (err) - return err; -@@ -366,10 +364,10 @@ static void ceetm_cls_destroy(struct Qdi - cl->root.child = NULL; - } - -- if (cl->root.ch && qman_ceetm_channel_release(cl->root.ch)) -+ if (cl->ch && qman_ceetm_channel_release(cl->ch)) - pr_err(KBUILD_BASENAME - " : %s : error releasing the channel %d\n", -- __func__, cl->root.ch->idx); -+ __func__, cl->ch->idx); - - break; - -@@ -766,6 +764,7 @@ static int ceetm_init_prio(struct Qdisc - - priv->shaped = parent_cl->shaped; - priv->prio.qcount = qopt->qcount; -+ priv->prio.ch = parent_cl->ch; - - /* Create and configure qcount child classes */ - for (i = 0; i < priv->prio.qcount; i++) { -@@ -790,6 +789,7 @@ static int ceetm_init_prio(struct Qdisc - child_cl->type = CEETM_PRIO; - child_cl->shaped = priv->shaped; - child_cl->prio.child = NULL; -+ child_cl->ch = priv->prio.ch; - - /* All shaped CQs have CR and ER enabled by default */ - child_cl->prio.cr = child_cl->shaped; -@@ -798,8 +798,7 @@ static int ceetm_init_prio(struct Qdisc - child_cl->prio.cq = NULL; - - /* Configure the corresponding hardware CQ */ -- err = ceetm_config_prio_cls(child_cl, dev, -- parent_cl->root.ch, i); -+ err = ceetm_config_prio_cls(child_cl, dev, i); - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n", - __func__, child_cl->common.classid); -@@ -831,7 +830,6 @@ static int ceetm_init_wbfs(struct Qdisc - struct ceetm_class *parent_cl, *child_cl, *root_cl; - struct Qdisc *parent_qdisc; - struct ceetm_qdisc *parent_priv; -- struct qm_ceetm_channel *channel; - struct net_device *dev = qdisc_dev(sch); - - pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -@@ -904,8 +902,7 @@ static int ceetm_init_wbfs(struct Qdisc - priv->wbfs.qcount = qopt->qcount; - priv->wbfs.cr = qopt->cr; - priv->wbfs.er = qopt->er; -- -- channel = root_cl->root.ch; -+ priv->wbfs.ch = parent_cl->ch; - - /* Configure the hardware wbfs channel groups */ - if (priv->wbfs.qcount == CEETM_MAX_WBFS_QCOUNT) { -@@ -920,7 +917,7 @@ static int ceetm_init_wbfs(struct Qdisc - /* Configure the group B */ - priv->wbfs.group_type = WBFS_GRP_B; - -- err = qman_ceetm_channel_get_group(channel, &small_group, -+ err = qman_ceetm_channel_get_group(priv->wbfs.ch, &small_group, - &prio_a, &prio_b); - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to get group details\n", -@@ -938,7 +935,7 @@ static int ceetm_init_wbfs(struct Qdisc - /* Configure the small group A */ - priv->wbfs.group_type = WBFS_GRP_A; - -- err = qman_ceetm_channel_get_group(channel, &small_group, -+ err = qman_ceetm_channel_get_group(priv->wbfs.ch, &small_group, - &prio_a, &prio_b); - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to get group details\n", -@@ -953,13 +950,13 @@ static int ceetm_init_wbfs(struct Qdisc - prio_b = prio_b ? : prio_a; - } - -- err = qman_ceetm_channel_set_group(channel, small_group, prio_a, -+ err = qman_ceetm_channel_set_group(priv->wbfs.ch, small_group, prio_a, - prio_b); - if (err) - goto err_init_wbfs; - - if (priv->shaped) { -- err = qman_ceetm_channel_set_group_cr_eligibility(channel, -+ err = qman_ceetm_channel_set_group_cr_eligibility(priv->wbfs.ch, - group_b, - priv->wbfs.cr); - if (err) { -@@ -968,7 +965,7 @@ static int ceetm_init_wbfs(struct Qdisc - goto err_init_wbfs; - } - -- err = qman_ceetm_channel_set_group_er_eligibility(channel, -+ err = qman_ceetm_channel_set_group_er_eligibility(priv->wbfs.ch, - group_b, - priv->wbfs.er); - if (err) { -@@ -1003,13 +1000,14 @@ static int ceetm_init_wbfs(struct Qdisc - child_cl->wbfs.fq = NULL; - child_cl->wbfs.cq = NULL; - child_cl->wbfs.weight = qopt->qweight[i]; -+ child_cl->ch = priv->wbfs.ch; - - if (priv->wbfs.group_type == WBFS_GRP_B) - id = WBFS_GRP_B_OFFSET + i; - else - id = WBFS_GRP_A_OFFSET + i; - -- err = ceetm_config_wbfs_cls(child_cl, dev, channel, id, -+ err = ceetm_config_wbfs_cls(child_cl, dev, id, - priv->wbfs.group_type); - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n", -@@ -1178,9 +1176,6 @@ static int ceetm_change_wbfs(struct Qdis - { - int err; - bool group_b; -- struct qm_ceetm_channel *channel; -- struct ceetm_class *prio_class, *root_class; -- struct ceetm_qdisc *prio_qdisc; - - if (qopt->qcount) { - pr_err("CEETM: the qcount can not be modified\n"); -@@ -1206,14 +1201,10 @@ static int ceetm_change_wbfs(struct Qdis - if (!priv->shaped) - return 0; - -- prio_class = priv->wbfs.parent; -- prio_qdisc = qdisc_priv(prio_class->parent); -- root_class = prio_qdisc->prio.parent; -- channel = root_class->root.ch; - group_b = priv->wbfs.group_type == WBFS_GRP_B; - - if (qopt->cr != priv->wbfs.cr) { -- err = qman_ceetm_channel_set_group_cr_eligibility(channel, -+ err = qman_ceetm_channel_set_group_cr_eligibility(priv->wbfs.ch, - group_b, - qopt->cr); - if (err) -@@ -1222,7 +1213,7 @@ static int ceetm_change_wbfs(struct Qdis - } - - if (qopt->er != priv->wbfs.er) { -- err = qman_ceetm_channel_set_group_er_eligibility(channel, -+ err = qman_ceetm_channel_set_group_er_eligibility(priv->wbfs.ch, - group_b, - qopt->er); - if (err) -@@ -1337,7 +1328,7 @@ static int ceetm_cls_change_root(struct - - if (cl->shaped && cl->root.rate != copt->rate) { - bps = copt->rate << 3; /* Bps -> bps */ -- err = qman_ceetm_channel_set_commit_rate_bps(cl->root.ch, bps, -+ err = qman_ceetm_channel_set_commit_rate_bps(cl->ch, bps, - dev->mtu); - if (err) - goto change_cls_err; -@@ -1346,7 +1337,7 @@ static int ceetm_cls_change_root(struct - - if (cl->shaped && cl->root.ceil != copt->ceil) { - bps = copt->ceil << 3; /* Bps -> bps */ -- err = qman_ceetm_channel_set_excess_rate_bps(cl->root.ch, bps, -+ err = qman_ceetm_channel_set_excess_rate_bps(cl->ch, bps, - dev->mtu); - if (err) - goto change_cls_err; -@@ -1354,7 +1345,7 @@ static int ceetm_cls_change_root(struct - } - - if (!cl->shaped && cl->root.tbl != copt->tbl) { -- err = qman_ceetm_channel_set_weight(cl->root.ch, copt->tbl); -+ err = qman_ceetm_channel_set_weight(cl->ch, copt->tbl); - if (err) - goto change_cls_err; - cl->root.tbl = copt->tbl; -@@ -1555,7 +1546,7 @@ static int ceetm_cls_change(struct Qdisc - goto claim_err; - } - -- cl->root.ch = channel; -+ cl->ch = channel; - - if (cl->shaped) { - /* Configure the channel shaper */ ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h -@@ -121,12 +121,14 @@ struct root_q { - struct prio_q { - __u16 qcount; - struct ceetm_class *parent; -+ struct qm_ceetm_channel *ch; - }; - - struct wbfs_q { - __u16 qcount; - int group_type; - struct ceetm_class *parent; -+ struct qm_ceetm_channel *ch; - __u16 cr; - __u16 er; - }; -@@ -165,7 +167,6 @@ struct root_c { - bool wbfs_grp_b; - bool wbfs_grp_large; - struct Qdisc *child; -- struct qm_ceetm_channel *ch; - }; - - struct prio_c { -@@ -194,6 +195,7 @@ struct ceetm_class { - struct tcf_proto *filter_list; /* class attached filters */ - struct tcf_block *block; - struct Qdisc *parent; -+ struct qm_ceetm_channel *ch; - bool shaped; - int type; /* ROOT/PRIO/WBFS */ - union { diff --git a/target/linux/layerscape/patches-5.4/701-net-0069-sdk_dpaa-ceetm-reset-the-wbfs-groups-and-priorities-.patch b/target/linux/layerscape/patches-5.4/701-net-0069-sdk_dpaa-ceetm-reset-the-wbfs-groups-and-priorities-.patch deleted file mode 100644 index fb6ac756d5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0069-sdk_dpaa-ceetm-reset-the-wbfs-groups-and-priorities-.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 3aa80007715ecfd944e02029b59fec5c74c8598e Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 30 May 2018 15:04:37 +0300 -Subject: [PATCH] sdk_dpaa: ceetm: reset the wbfs groups and priorities on - teardown - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -491,6 +491,10 @@ static void ceetm_destroy(struct Qdisc * - break; - - case CEETM_WBFS: -+ /* Reset the WBFS groups and priorities */ -+ if (priv->wbfs.ch) -+ qman_ceetm_channel_set_group(priv->wbfs.ch, 1, 0, 0); -+ - if (priv->wbfs.parent) - priv->wbfs.parent->prio.child = NULL; - break; diff --git a/target/linux/layerscape/patches-5.4/701-net-0070-sdk_dpaa-ceetm-WQ-CEETM-mode-switchover-cleanup.patch b/target/linux/layerscape/patches-5.4/701-net-0070-sdk_dpaa-ceetm-WQ-CEETM-mode-switchover-cleanup.patch deleted file mode 100644 index 76c0ecacbc..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0070-sdk_dpaa-ceetm-WQ-CEETM-mode-switchover-cleanup.patch +++ /dev/null @@ -1,54 +0,0 @@ -From c095bbc29eeae597c47c90d41fab472be9e14ca6 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 30 May 2018 15:26:47 +0300 -Subject: [PATCH] sdk_dpaa: ceetm: WQ/CEETM mode switchover cleanup - -Wait for the WQ TX FQs to empty before switching from WQ to CEETM mode. - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 26 ++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -65,6 +65,31 @@ static void get_dcp_and_sp(struct net_de - } - } - -+/* Wait for the DPAA Eth driver WQ TX FQs to empty */ -+static void dpaa_drain_fqs(struct net_device *dev) -+{ -+ const struct dpa_priv_s *priv = netdev_priv(dev); -+ struct qm_mcr_queryfq_np np; -+ struct qman_fq *fq; -+ int ret, i; -+ -+ for (i = 0; i < DPAA_ETH_TX_QUEUES; i ++) { -+ fq = priv->egress_fqs[i]; -+ while (true) { -+ ret = qman_query_fq_np(fq, &np); -+ if (unlikely(ret)) { -+ pr_err(KBUILD_BASENAME -+ " : %s : unable to query FQ %x: %d\n", -+ __func__, fq->fqid, ret); -+ break; -+ } -+ -+ if (np.frm_cnt == 0) -+ break; -+ } -+ } -+} -+ - /* Enqueue Rejection Notification callback */ - static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq, - const struct qm_mr_entry *msg) -@@ -1103,6 +1128,7 @@ static int ceetm_init(struct Qdisc *sch, - switch (priv->type) { - case CEETM_ROOT: - netif_tx_stop_all_queues(dev); -+ dpaa_drain_fqs(dev); - ret = ceetm_init_root(sch, priv, qopt, extack); - netif_tx_wake_all_queues(dev); - break; diff --git a/target/linux/layerscape/patches-5.4/701-net-0071-sdk_dpaa-ceetm-drain-the-ceetm-CQs-on-destroy.patch b/target/linux/layerscape/patches-5.4/701-net-0071-sdk_dpaa-ceetm-drain-the-ceetm-CQs-on-destroy.patch deleted file mode 100644 index bdca2361a0..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0071-sdk_dpaa-ceetm-drain-the-ceetm-CQs-on-destroy.patch +++ /dev/null @@ -1,116 +0,0 @@ -From fe7ed61721646077de5eb06a105e60634374a00c Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Thu, 31 May 2018 10:45:50 +0300 -Subject: [PATCH] sdk_dpaa: ceetm: drain the ceetm CQs on destroy - -The CEETM CQs must be empty when configured. To guarantee this, stop all -transmissions and wait for them to drain before releasing them. On the -next configuration, we are certain they will be empty. - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 62 ++++++++++++++++++++++ - 1 file changed, 62 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -90,6 +90,51 @@ static void dpaa_drain_fqs(struct net_de - } - } - -+/* Wait for the DPAA CEETM TX CQs to empty */ -+static void ceetm_drain_class(struct ceetm_class *cl) -+{ -+ struct qm_mcr_ceetm_cq_query cq_query; -+ struct qm_ceetm_cq *cq; -+ unsigned int idx; -+ int ret; -+ -+ if (!cl) -+ return; -+ -+ switch (cl->type) { -+ case CEETM_ROOT: -+ /* The ROOT classes aren't directly linked to CEETM CQs */ -+ return; -+ case CEETM_PRIO: -+ cq = (struct qm_ceetm_cq*)cl->prio.cq; -+ break; -+ case CEETM_WBFS: -+ cq = (struct qm_ceetm_cq*)cl->wbfs.cq; -+ break; -+ } -+ -+ if (!cq || !cl->ch) -+ return; -+ -+ /* Build the query CQID by merging the channel and the CQ IDs */ -+ idx = (cq->parent->idx << 4) | cq->idx; -+ -+ while (true) { -+ ret = qman_ceetm_query_cq(idx, -+ cl->ch->dcp_idx, -+ &cq_query); -+ if (unlikely(ret)) { -+ pr_err(KBUILD_BASENAME -+ " : %s : unable to query CQ %x: %d\n", -+ __func__, idx, ret); -+ break; -+ } -+ -+ if (cq_query.frm_cnt == 0) -+ break; -+ } -+} -+ - /* Enqueue Rejection Notification callback */ - static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq, - const struct qm_mr_entry *msg) -@@ -376,6 +421,8 @@ static void ceetm_link_class(struct Qdis - /* Destroy a ceetm class */ - static void ceetm_cls_destroy(struct Qdisc *sch, struct ceetm_class *cl) - { -+ struct net_device *dev = qdisc_dev(sch); -+ - if (!cl) - return; - -@@ -402,6 +449,12 @@ static void ceetm_cls_destroy(struct Qdi - cl->prio.child = NULL; - } - -+ /* We must make sure the CQ is empty before releasing it. -+ * Pause all transmissions while we wait for it to drain. -+ */ -+ netif_tx_stop_all_queues(dev); -+ ceetm_drain_class(cl); -+ - if (cl->prio.lfq && qman_ceetm_lfq_release(cl->prio.lfq)) - pr_err(KBUILD_BASENAME - " : %s : error releasing the LFQ %d\n", -@@ -422,9 +475,16 @@ static void ceetm_cls_destroy(struct Qdi - if (cl->prio.cstats) - free_percpu(cl->prio.cstats); - -+ netif_tx_wake_all_queues(dev); - break; - - case CEETM_WBFS: -+ /* We must make sure the CQ is empty before releasing it. -+ * Pause all transmissions while we wait for it to drain. -+ */ -+ netif_tx_stop_all_queues(dev); -+ ceetm_drain_class(cl); -+ - if (cl->wbfs.lfq && qman_ceetm_lfq_release(cl->wbfs.lfq)) - pr_err(KBUILD_BASENAME - " : %s : error releasing the LFQ %d\n", -@@ -444,6 +504,8 @@ static void ceetm_cls_destroy(struct Qdi - - if (cl->wbfs.cstats) - free_percpu(cl->wbfs.cstats); -+ -+ netif_tx_wake_all_queues(dev); - } - - tcf_block_put(cl->block); diff --git a/target/linux/layerscape/patches-5.4/701-net-0072-sdk_dpaa-ls1043a-errata-adapt-to-new-skb-copy-API.patch b/target/linux/layerscape/patches-5.4/701-net-0072-sdk_dpaa-ls1043a-errata-adapt-to-new-skb-copy-API.patch deleted file mode 100644 index fa3fe9e0b2..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0072-sdk_dpaa-ls1043a-errata-adapt-to-new-skb-copy-API.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 6589b195949605efaa26c71baa2beb3bbf77ee5d Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 3 Jul 2018 10:03:05 +0300 -Subject: [PATCH] sdk_dpaa: ls1043a errata: adapt to new skb copy API - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -852,7 +852,7 @@ static struct sk_buff *a010022_realign_s - WARN_ONCE(1, "skb parsing failure\n"); - goto err; - } -- copy_skb_header(nskb, skb); -+ skb_copy_header(nskb, skb); - - #ifdef CONFIG_FSL_DPAA_TS - /* Copy relevant timestamp info from the old skb to the new */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0073-dpaa_eth-ERR010022-adapt-to-new-skb-copy-API.patch b/target/linux/layerscape/patches-5.4/701-net-0073-dpaa_eth-ERR010022-adapt-to-new-skb-copy-API.patch deleted file mode 100644 index 581292267c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0073-dpaa_eth-ERR010022-adapt-to-new-skb-copy-API.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 41047fc3ae025e75a8ac9da8714dbaaef6e63aec Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 3 Jul 2018 10:04:12 +0300 -Subject: [PATCH] dpaa_eth: ERR010022: adapt to new skb copy API - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -2183,7 +2183,7 @@ static struct sk_buff *dpaa_errata_a0100 - WARN_ONCE(1, "skb parsing failure\n"); - goto err; - } -- copy_skb_header(nskb, skb); -+ skb_copy_header(nskb, skb); - - /* We move the headroom when we align it so we have to reset the - * network and transport header offsets relative to the new data diff --git a/target/linux/layerscape/patches-5.4/701-net-0074-sdk_dpaa-enable-Jumbo-frame-support-on-LS1043A.patch b/target/linux/layerscape/patches-5.4/701-net-0074-sdk_dpaa-enable-Jumbo-frame-support-on-LS1043A.patch deleted file mode 100644 index 37da91aeb4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0074-sdk_dpaa-enable-Jumbo-frame-support-on-LS1043A.patch +++ /dev/null @@ -1,154 +0,0 @@ -From fcf41cba6f3ac0f33a5e9e0c7d79dbbbff586271 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 15 May 2018 11:48:42 +0300 -Subject: [PATCH] sdk_dpaa: enable Jumbo frame support on LS1043A - -Due to the A010022 errata restrictions, Jumbo frames on LS1043A require two -conditions to be met: -- on TX, the data is stored in a contiguous buffer of up to 9600 bytes -- the data is aligned to 256 bytes - -The conditions are met by realigning all outgoing frames to 256 bytes. -Also, compound pages of varying orders are allocated to accommodate the -outgoing contiguous buffers. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/Kconfig | 1 - - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 9 ++--- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 5 +-- - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 40 ++++++++-------------- - 4 files changed, 20 insertions(+), 35 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig -@@ -80,7 +80,6 @@ config FSL_DPAA_ETH_JUMBO_FRAME - significantly the driver's memory footprint and may even deplete - the system memory. Also, the skb truesize is altered and messages - from the stack that warn against this are bypassed. -- This option is not available on LS1043. - - config FSL_DPAA_TS - bool "Linux compliant timestamping" ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -@@ -779,12 +779,10 @@ static int dpa_private_netdev_init(struc - net_dev->features |= NETIF_F_HW_ACCEL_MQ; - - #ifndef CONFIG_PPC -- /* Due to the A010022 FMan errata, we can not use contig frames larger -- * than 4K, nor S/G frames. We need to prevent the user from setting a -- * large MTU. We also stop advertising S/G and GSO support. -+ /* Due to the A010022 FMan errata, we can not use S/G frames. We need -+ * to stop advertising S/G and GSO support. - */ - if (unlikely(dpaa_errata_a010022)) { -- net_dev->max_mtu = DPA_BP_RAW_SIZE; - net_dev->hw_features &= ~NETIF_F_SG; - net_dev->features &= ~NETIF_F_GSO; - } -@@ -985,9 +983,6 @@ dpaa_eth_priv_probe(struct platform_devi - /* We only want to use jumbo frame optimization if we actually have - * L2 MAX FRM set for jumbo frames as well. - */ --#ifndef CONFIG_PPC -- if (likely(!dpaa_errata_a010022)) --#endif - if(fm_get_max_frm() < 9600) - dev_warn(dev, - "Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n"); ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -672,8 +672,8 @@ static inline void _dpa_bp_free_pf(void - /* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue - * manifests itself at high traffic rates when frames cross 4K memory - * boundaries or when they are not aligned to 16 bytes; For the moment, we -- * use a SW workaround to avoid frames larger than 4K or that exceed 4K -- * alignments and to realign the frames to 16 bytes. -+ * use a SW workaround that realigns frames to 256 bytes. Scatter/Gather -+ * frames aren't supported on egress. - */ - - #ifndef CONFIG_PPC -@@ -682,6 +682,7 @@ extern bool dpaa_errata_a010022; /* SoC - #define HAS_DMA_ISSUE(start, size) \ - (((uintptr_t)(start) + (size)) > \ - (((uintptr_t)(start) + 0x1000) & ~0xFFF)) -+#define DPAA_A010022_HEADROOM 256 - #endif /* !CONFIG_PPC */ - - #endif /* __DPA_H */ ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -407,12 +407,6 @@ static struct sk_buff *__hot contig_fd_t - * warn us that the frame length is larger than the truesize. We - * bypass the warning. - */ --#ifndef CONFIG_PPC -- /* We do not support Jumbo frames on LS1043 and thus we edit -- * the skb truesize only when the 4k errata is not present. -- */ -- if (likely(!dpaa_errata_a010022)) --#endif - skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd)); - #endif - -@@ -809,35 +803,31 @@ static struct sk_buff *a010022_realign_s - { - int trans_offset = skb_transport_offset(skb); - int net_offset = skb_network_offset(skb); -+ int nsize, headroom, npage_order; - struct sk_buff *nskb = NULL; -- int nsize, headroom; - struct page *npage; - void *npage_addr; - -- /* Guarantee the minimum required headroom */ -- if (skb_headroom(skb) >= priv->tx_headroom) -- headroom = skb_headroom(skb); -- else -- headroom = priv->tx_headroom; -+ /* The headroom needs to accommodate our private data (64 bytes) but -+ * we reserve 256 bytes instead to guarantee 256 data alignment. -+ */ -+ headroom = DPAA_A010022_HEADROOM; -+ -+ /* For the new skb we only need the old one's data (both non-paged and -+ * paged). We can skip the old tailroom. -+ */ -+ nsize = headroom + skb->len + -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - -- npage = alloc_page(GFP_ATOMIC); -+ /* Reserve enough memory to accommodate Jumbo frames */ -+ npage_order = (nsize - 1) / PAGE_SIZE; -+ npage = alloc_pages(GFP_ATOMIC | __GFP_COMP, npage_order); - if (unlikely(!npage)) { - WARN_ONCE(1, "Memory allocation failure\n"); - return NULL; - } - npage_addr = page_address(npage); - -- /* For the new skb we only need the old one's data (both non-paged and -- * paged) and a headroom large enough to fit our private info. We can -- * skip the old tailroom. -- * -- * Make sure the new linearized buffer will not exceed a page's size. -- */ -- nsize = headroom + skb->len + -- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); -- if (unlikely(nsize > 4096)) -- goto err; -- - nskb = build_skb(npage_addr, nsize); - if (unlikely(!nskb)) - goto err; -@@ -846,7 +836,7 @@ static struct sk_buff *a010022_realign_s - * alignment. - * Code borrowed and adapted from skb_copy(). - */ -- skb_reserve(nskb, priv->tx_headroom); -+ skb_reserve(nskb, headroom); - skb_put(nskb, skb->len); - if (skb_copy_bits(skb, 0, nskb->data, skb->len)) { - WARN_ONCE(1, "skb parsing failure\n"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0075-sdk_dpaa-reserve-256-bytes-for-the-SGT-on-TX.patch b/target/linux/layerscape/patches-5.4/701-net-0075-sdk_dpaa-reserve-256-bytes-for-the-SGT-on-TX.patch deleted file mode 100644 index 2056276472..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0075-sdk_dpaa-reserve-256-bytes-for-the-SGT-on-TX.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 29757ae2e4a0e8e1e816c9eeef59121908320669 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 20 Jun 2018 18:00:42 +0300 -Subject: [PATCH] sdk_dpaa: reserve 256 bytes for the SGT on TX - -The FMan reads 256 bytes from the start of the SGT regardless of its -size. We reserve the same amount of memory on TX to access. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 6 ++++-- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 10 +++++++--- - 2 files changed, 11 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h -@@ -55,10 +55,12 @@ - fm_set_##type##_port_params(port, ¶m); \ - } - -+/* The SGT needs to be 256 bytes long. Even if the table has only one entry, -+ * the FMan will read 256 bytes from its start. -+ */ -+#define DPA_SGT_SIZE 256 - #define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */ - --#define DPA_SGT_ENTRIES_THRESHOLD DPA_SGT_MAX_ENTRIES -- - #define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */ - - #define DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno) \ ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -246,8 +246,8 @@ struct sk_buff *_dpa_cleanup_tx_fd(const - - if (unlikely(fd->format == qm_fd_sg)) { - nr_frags = skb_shinfo(skb)->nr_frags; -- dma_unmap_single(dpa_bp->dev, addr, dpa_fd_offset(fd) + -- sizeof(struct qm_sg_entry) * (1 + nr_frags), -+ dma_unmap_single(dpa_bp->dev, addr, -+ dpa_fd_offset(fd) + DPA_SGT_SIZE, - dma_dir); - - /* The sgt buffer has been allocated with netdev_alloc_frag(), -@@ -896,7 +896,11 @@ int __hot skb_to_sg_fd(struct dpa_priv_s - nr_frags = skb_shinfo(skb)->nr_frags; - fd->format = qm_fd_sg; - -- sgt_size = sizeof(struct qm_sg_entry) * (1 + nr_frags); -+ /* The FMan reads 256 bytes from the start of the SGT regardless of -+ * its size. In accordance, we reserve the same amount of memory as -+ * well. -+ */ -+ sgt_size = DPA_SGT_SIZE; - - /* Get a page frag to store the SGTable, or a full page if the errata - * is in place and we need to avoid crossing a 4k boundary. diff --git a/target/linux/layerscape/patches-5.4/701-net-0076-fsl_qbman-usdpaa-change-to-debug-print-in-interrupt-.patch b/target/linux/layerscape/patches-5.4/701-net-0076-fsl_qbman-usdpaa-change-to-debug-print-in-interrupt-.patch deleted file mode 100644 index 71c327b09a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0076-fsl_qbman-usdpaa-change-to-debug-print-in-interrupt-.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 9be590a85edd0298fb9ad21a26d849ccbadb7530 Mon Sep 17 00:00:00 2001 -From: Nipun Gupta -Date: Wed, 8 Aug 2018 13:04:18 +0530 -Subject: [PATCH] fsl_qbman/usdpaa: change to debug print in interrupt handler - -Signed-off-by: Nipun Gupta ---- - drivers/staging/fsl_qbman/fsl_usdpaa_irq.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c -+++ b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c -@@ -102,7 +102,7 @@ static irqreturn_t usdpaa_irq_handler(in - /* Set the inhibit register. This will be reenabled - once the USDPAA code handles the IRQ */ - out_be32(ctx->inhibit_addr, 0x1); -- pr_info("Inhibit at %p count %d", ctx->inhibit_addr, ctx->irq_count); -+ pr_debug("Inhibit at %p count %d", ctx->inhibit_addr, ctx->irq_count); - return IRQ_HANDLED; - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0077-staging-fsl_qbman-Consume-all-frames-in-DQRR-during-.patch b/target/linux/layerscape/patches-5.4/701-net-0077-staging-fsl_qbman-Consume-all-frames-in-DQRR-during-.patch deleted file mode 100644 index ec79adc56e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0077-staging-fsl_qbman-Consume-all-frames-in-DQRR-during-.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 9b4ae951eeabc09fda80e446434ef8f03849522e Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Fri, 22 Jun 2018 15:47:07 -0400 -Subject: [PATCH] staging/fsl_qbman: Consume all frames in DQRR during init - -The qm_dqrr_cdc_consume_n() function takes a bitmask, not an index. - -Signed-off-by: Roy Pledge ---- - drivers/staging/fsl_qbman/qman_low.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/fsl_qbman/qman_low.h -+++ b/drivers/staging/fsl_qbman/qman_low.h -@@ -658,7 +658,7 @@ static inline int qm_dqrr_init(struct qm - qm_dqrr_cce_consume(portal, dqrr->fill); - break; - case qm_dqrr_cdc: -- qm_dqrr_cdc_consume_n(portal, (QM_DQRR_SIZE - 1)); -+ qm_dqrr_cdc_consume_n(portal, (1< -Date: Wed, 8 Aug 2018 17:13:48 -0400 -Subject: [PATCH] staging/fsl_qbman: Recalcuate cursor after consuming ring - -If the dqrr_init() function consumes frames during init -the cursor needs to be updated before anything starts -to use the ring. - -Signed-off-by: Roy Pledge ---- - drivers/staging/fsl_qbman/qman_low.h | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/staging/fsl_qbman/qman_low.h -+++ b/drivers/staging/fsl_qbman/qman_low.h -@@ -682,6 +682,9 @@ static inline int qm_dqrr_init(struct qm - (0 ? 0x10 : 0); /* Ignore SP */ - qm_out(CFG, cfg); - qm_dqrr_set_maxfill(portal, max_fill); -+ -+ /* Recalculate cursor as we may have consumed frames */ -+ dqrr->cursor = dqrr->ring + dqrr->ci; - return 0; - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0079-fmd-use-fsl-fman-ptp-timer-compatible-for-ptp-probe.patch b/target/linux/layerscape/patches-5.4/701-net-0079-fmd-use-fsl-fman-ptp-timer-compatible-for-ptp-probe.patch deleted file mode 100644 index 2748089ee7..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0079-fmd-use-fsl-fman-ptp-timer-compatible-for-ptp-probe.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 3fa6171fbe38125b2841d7947e976b172db47c45 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 5 Sep 2018 14:50:10 +0800 -Subject: [PATCH] fmd: use "fsl,fman-ptp-timer" compatible for ptp probe - -Current ptp compatible "fsl,fman-rtc" used for ptp probe -in fmd driver couldn't involve PowerPC DPAA FMan PTP timer. -Let's use "fsl,fman-ptp-timer" instead to support DPAA FMan -PTP timer of both ARM and PowerPC. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -@@ -687,9 +687,9 @@ static t_LnxWrpFmDev * ReadFmDevTreeNode - if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name))) - return NULL; - strcpy(ids[0].name, "ptp-timer"); -- if (WARN_ON(strlen("fsl,fman-rtc") >= sizeof(ids[0].compatible))) -+ if (WARN_ON(strlen("fsl,fman-ptp-timer") >= sizeof(ids[0].compatible))) - return NULL; -- strcpy(ids[0].compatible, "fsl,fman-rtc"); -+ strcpy(ids[0].compatible, "fsl,fman-ptp-timer"); - for_each_child_of_node(fm_node, dev_node) { - if (likely(of_match_node(ids, dev_node) != NULL)) { - _errno = of_address_to_resource(dev_node, 0, &res); -@@ -920,7 +920,7 @@ static t_Error ConfigureFmDev(t_LnxWrpFm - - if (p_LnxWrpFmDev->fmRtcPhysBaseAddr) - { -- dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-rtc"); -+ dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-ptp-timer"); - if (unlikely(dev_res == NULL)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed")); - diff --git a/target/linux/layerscape/patches-5.4/701-net-0080-sdk_dpaa-store-the-skb-backpointer-in-the-skb-headro.patch b/target/linux/layerscape/patches-5.4/701-net-0080-sdk_dpaa-store-the-skb-backpointer-in-the-skb-headro.patch deleted file mode 100644 index 12e5d15795..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0080-sdk_dpaa-store-the-skb-backpointer-in-the-skb-headro.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 1f00fa355829b510beb900ce1136f40802e6076e Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 10 Sep 2018 14:31:05 +0300 -Subject: [PATCH] sdk_dpaa: store the skb backpointer in the skb headroom - -The skb backpointer is stored right before the FMan buffer, in order to -avoid overwriting. The memory area storing the backpointer was outside of -the skb. This made it hard to guarantee its size. - -This patch changes the layout of the skb at buffer seed time: the area -reserved for storing the skb backpointer is part of the skb's headroom. -This makes it easier to track if the backpointer can be safely stored -when recycling the buffer. - -Signed-off-by: Camelia Groza ---- - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 33 ++++++++++++++++------ - 1 file changed, 24 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -82,8 +82,8 @@ static void dpa_bp_recycle_frag(struct d - - static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp) - { -+ void *new_buf, *fman_buf; - struct bm_buffer bmb[8]; -- void *new_buf; - dma_addr_t addr; - uint8_t i; - struct device *dev = dpa_bp->dev; -@@ -113,21 +113,37 @@ static int _dpa_bp_add_8_bufs(const stru - - if (unlikely(!new_buf)) - goto netdev_alloc_failed; -- new_buf = PTR_ALIGN(new_buf + SMP_CACHE_BYTES, SMP_CACHE_BYTES); -+ new_buf = PTR_ALIGN(new_buf, SMP_CACHE_BYTES); - -- skb = build_skb(new_buf, DPA_SKB_SIZE(dpa_bp->size) + -- SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); -+ /* Apart from the buffer that will be used by the FMan, the -+ * skb also guarantees enough space to hold the backpointer -+ * in the headroom and the shared info at the end. -+ */ -+ skb = build_skb(new_buf, -+ SMP_CACHE_BYTES + DPA_SKB_SIZE(dpa_bp->size) + -+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); - if (unlikely(!skb)) { - put_page(virt_to_head_page(new_buf)); - goto build_skb_failed; - } - -- /* Store the skb back-pointer before the start of the buffer. -- * Otherwise it will be overwritten by the FMan. -+ /* Reserve SMP_CACHE_BYTES in the skb's headroom to store the -+ * backpointer. This area will not be synced to, or -+ * overwritten by, the FMan. -+ */ -+ skb_reserve(skb, SMP_CACHE_BYTES); -+ -+ /* We don't sync the first SMP_CACHE_BYTES of the buffer to -+ * the FMan. The skb backpointer is stored at the end of the -+ * reserved headroom. Otherwise it will be overwritten by the -+ * FMan. -+ * The buffer synced with the FMan starts right after the -+ * reserved headroom. - */ -- DPA_WRITE_SKB_PTR(skb, skbh, new_buf, -1); -+ fman_buf = new_buf + SMP_CACHE_BYTES; -+ DPA_WRITE_SKB_PTR(skb, skbh, fman_buf, -1); - -- addr = dma_map_single(dev, new_buf, -+ addr = dma_map_single(dev, fman_buf, - dpa_bp->size, DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(dev, addr))) - goto dma_map_failed; -@@ -477,7 +493,6 @@ static struct sk_buff *__hot sg_fd_to_sk - DMA_BIDIRECTIONAL); - if (i == 0) { - DPA_READ_SKB_PTR(skb, skbh, sg_vaddr, -1); -- DPA_BUG_ON(skb->head != sg_vaddr); - #ifdef CONFIG_FSL_DPAA_1588 - if (priv->tsu && priv->tsu->valid && - priv->tsu->hwts_rx_en_ioctl) diff --git a/target/linux/layerscape/patches-5.4/701-net-0081-sdk_dpaa-ls1043a-errata-align-skb_shinfo.patch b/target/linux/layerscape/patches-5.4/701-net-0081-sdk_dpaa-ls1043a-errata-align-skb_shinfo.patch deleted file mode 100644 index 3c224c62a4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0081-sdk_dpaa-ls1043a-errata-align-skb_shinfo.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 7c96998ebc8cc9c71216b80de3f77114f29b148a Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 17 Sep 2018 12:39:24 +0300 -Subject: [PATCH] sdk_dpaa: ls1043a errata: align skb_shinfo - -Make sure the skb shared info is cache-line aligned when realigning -egress frames. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -830,8 +830,10 @@ static struct sk_buff *a010022_realign_s - - /* For the new skb we only need the old one's data (both non-paged and - * paged). We can skip the old tailroom. -+ * -+ * Make sure the skb_shinfo is cache-line aligned. - */ -- nsize = headroom + skb->len + -+ nsize = SMP_CACHE_BYTES + DPA_SKB_SIZE(headroom + skb->len) + - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - - /* Reserve enough memory to accommodate Jumbo frames */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0082-sdk_dpaa-ls1043a-errata-move-comment.patch b/target/linux/layerscape/patches-5.4/701-net-0082-sdk_dpaa-ls1043a-errata-move-comment.patch deleted file mode 100644 index 05875d2e5b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0082-sdk_dpaa-ls1043a-errata-move-comment.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 182afda3f2537022ac2e0b7f421977ba96ce864e Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 17 Sep 2018 12:44:51 +0300 -Subject: [PATCH] sdk_dpaa: ls1043a errata: move comment - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 3 +++ - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 3 --- - 2 files changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -682,6 +682,9 @@ extern bool dpaa_errata_a010022; /* SoC - #define HAS_DMA_ISSUE(start, size) \ - (((uintptr_t)(start) + (size)) > \ - (((uintptr_t)(start) + 0x1000) & ~0xFFF)) -+/* The headroom needs to accommodate our private data (64 bytes) but -+ * we reserve 256 bytes instead to guarantee 256 data alignment. -+ */ - #define DPAA_A010022_HEADROOM 256 - #endif /* !CONFIG_PPC */ - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -823,9 +823,6 @@ static struct sk_buff *a010022_realign_s - struct page *npage; - void *npage_addr; - -- /* The headroom needs to accommodate our private data (64 bytes) but -- * we reserve 256 bytes instead to guarantee 256 data alignment. -- */ - headroom = DPAA_A010022_HEADROOM; - - /* For the new skb we only need the old one's data (both non-paged and diff --git a/target/linux/layerscape/patches-5.4/701-net-0083-sdk_dpaa-ceetm-lower-the-default-congestion-threshol.patch b/target/linux/layerscape/patches-5.4/701-net-0083-sdk_dpaa-ceetm-lower-the-default-congestion-threshol.patch deleted file mode 100644 index 81881fa717..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0083-sdk_dpaa-ceetm-lower-the-default-congestion-threshol.patch +++ /dev/null @@ -1,39 +0,0 @@ -From c18056f0a2648457cdaf06450addd217091f4bea Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 2 Oct 2018 16:49:28 +0300 -Subject: [PATCH] sdk_dpaa: ceetm: lower the default congestion thresholds - -The congestion thresholds need to be set in such a way that: - a) the threshold is high enough so that frames aren't dropped - unnecessarily - b) the threshold is low enough so that the latency isn't too big - -The current thresholds are set too high. In forwarding scenarios, the -latency is too large and frames are dropped on ingress due to a lack of -buffers. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/Kconfig | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig -@@ -24,7 +24,7 @@ config FSL_DPAA_CEETM_CCS_THRESHOLD_1G - hex "CEETM egress congestion threshold on 1G ports" - depends on FSL_DPAA_CEETM - range 0x1000 0x10000000 -- default "0x000a0000" -+ default "0x00005000" - help - The size in bytes of the CEETM egress Class Congestion State threshold on 1G ports. - The threshold needs to be configured keeping in mind the following factors: -@@ -38,7 +38,7 @@ config FSL_DPAA_CEETM_CCS_THRESHOLD_10G - hex "CEETM egress congestion threshold on 10G ports" - depends on FSL_DPAA_CEETM - range 0x1000 0x20000000 -- default "0x00640000" -+ default "0x00032000" - help - The size in bytes of the CEETM egress Class Congestion State threshold on 10G ports. - See FSL_DPAA_CEETM_CCS_THRESHOLD_1G for details. diff --git a/target/linux/layerscape/patches-5.4/701-net-0084-staging-fsl_qbman-remove-bootmem-header.patch b/target/linux/layerscape/patches-5.4/701-net-0084-staging-fsl_qbman-remove-bootmem-header.patch deleted file mode 100644 index a7e1afc865..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0084-staging-fsl_qbman-remove-bootmem-header.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 1e42763e2e015dd98ee0fbfe30de4c0124251cb1 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 9 Oct 2018 17:49:07 +0300 -Subject: [PATCH] staging/fsl_qbman: remove bootmem header - -The bootmem allocator was removed in [1]. The memblock allocator is -supposed to be used directly instead. We already include it. - -[1] afd505b ("mm: remove include/linux/bootmem.h") - -Signed-off-by: Camelia Groza ---- - drivers/staging/fsl_qbman/dpa_sys.h | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/staging/fsl_qbman/dpa_sys.h -+++ b/drivers/staging/fsl_qbman/dpa_sys.h -@@ -36,7 +36,6 @@ - #include - #include - #include --#include - #include - #include - #include diff --git a/target/linux/layerscape/patches-5.4/701-net-0085-staging-fsl_qbman-stop-using-current_kernel_time.patch b/target/linux/layerscape/patches-5.4/701-net-0085-staging-fsl_qbman-stop-using-current_kernel_time.patch deleted file mode 100644 index 71f16e9e60..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0085-staging-fsl_qbman-stop-using-current_kernel_time.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 91c2f372e3f70ab5b5afff5af60348fd5656d739 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 10 Oct 2018 17:30:18 +0300 -Subject: [PATCH] staging/fsl_qbman: stop using current_kernel_time() - -The current_kernel_time() call was removed in [1] in order to avoid -overflows in 2038. Use ktime_get_coarse_real_ts64() instead. - -[1] 9765164 ("y2038: remove unused time interfaces") - -Signed-off-by: Camelia Groza ---- - drivers/staging/fsl_qbman/qbman_driver.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl_qbman/qbman_driver.c -+++ b/drivers/staging/fsl_qbman/qbman_driver.c -@@ -57,7 +57,10 @@ static __init int qbman_init(void) - }; - struct qm_mcr_queryfq_np np; - int err, retry = CONFIG_FSL_QMAN_INIT_TIMEOUT; -- struct timespec nowts, diffts, startts = current_kernel_time(); -+ struct timespec64 nowts, diffts, startts; -+ -+ ktime_get_coarse_real_ts64(&startts); -+ - /* Loop while querying given fqid succeeds or time out */ - while (1) { - err = qman_query_fq_np(&fq, &np); -@@ -68,8 +71,8 @@ static __init int qbman_init(void) - pr_err("QMan: I/O error, continuing anyway\n"); - break; - } -- nowts = current_kernel_time(); -- diffts = timespec_sub(nowts, startts); -+ ktime_get_coarse_real_ts64(&nowts); -+ diffts = timespec64_sub(nowts, startts); - if (diffts.tv_sec > 0) { - if (!retry--) { - pr_err("QMan: time out, control-plane" diff --git a/target/linux/layerscape/patches-5.4/701-net-0086-sdk_dpaa-ceetm-avoid-double-frees-on-error-paths.patch b/target/linux/layerscape/patches-5.4/701-net-0086-sdk_dpaa-ceetm-avoid-double-frees-on-error-paths.patch deleted file mode 100644 index efab833cf7..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0086-sdk_dpaa-ceetm-avoid-double-frees-on-error-paths.patch +++ /dev/null @@ -1,334 +0,0 @@ -From 1ffba0c4d1122688268e59832a5e2bbc0917cac7 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 3 Oct 2018 16:37:06 +0300 -Subject: [PATCH] sdk_dpaa: ceetm: avoid double frees on error paths - -The stack calls the destroy() callback when a qdisc init() fails. -We stop calling it ourselves and trust the stack do the cleanup. - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 94 ++++++++-------------- - 1 file changed, 34 insertions(+), 60 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -687,16 +687,13 @@ static int ceetm_init_root(struct Qdisc - - /* Validate inputs */ - if (sch->parent != TC_H_ROOT) { -- pr_err("CEETM: a root ceetm qdisc can not be attached to a class\n"); -- tcf_block_put(priv->block); -- qdisc_class_hash_destroy(&priv->clhash); -+ pr_err("CEETM: a root ceetm qdisc must be root\n"); - return -EINVAL; - } - - if (!mac_dev) { - pr_err("CEETM: the interface is lacking a mac\n"); -- err = -EINVAL; -- goto err_init_root; -+ return -EINVAL; - } - - /* Pre-allocate underlying pfifo qdiscs. -@@ -713,8 +710,7 @@ static int ceetm_init_root(struct Qdisc - sizeof(priv->root.qdiscs[0]), - GFP_KERNEL); - if (!priv->root.qdiscs) { -- err = -ENOMEM; -- goto err_init_root; -+ return -ENOMEM; - } - - for (i = 0; i < dev->num_tx_queues; i++) { -@@ -724,10 +720,8 @@ static int ceetm_init_root(struct Qdisc - - qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops, - parent_id, extack); -- if (!qdisc) { -- err = -ENOMEM; -- goto err_init_root; -- } -+ if (!qdisc) -+ return -ENOMEM; - - priv->root.qdiscs[i] = qdisc; - qdisc->flags |= TCQ_F_ONETXQUEUE; -@@ -739,8 +733,7 @@ static int ceetm_init_root(struct Qdisc - if (!priv->root.qstats) { - pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n", - __func__); -- err = -ENOMEM; -- goto err_init_root; -+ return -ENOMEM; - } - - priv->shaped = qopt->shaped; -@@ -754,7 +747,7 @@ static int ceetm_init_root(struct Qdisc - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to claim the SP\n", - __func__); -- goto err_init_root; -+ return err; - } - - priv->root.sp = sp; -@@ -766,7 +759,7 @@ static int ceetm_init_root(struct Qdisc - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to claim the LNI\n", - __func__); -- goto err_init_root; -+ return err; - } - - priv->root.lni = lni; -@@ -775,7 +768,7 @@ static int ceetm_init_root(struct Qdisc - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to link the SP and LNI\n", - __func__); -- goto err_init_root; -+ return err; - } - - lni->sp = sp; -@@ -786,7 +779,7 @@ static int ceetm_init_root(struct Qdisc - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n", - __func__); -- goto err_init_root; -+ return err; - } - - bps = priv->root.rate << 3; /* Bps -> bps */ -@@ -794,7 +787,7 @@ static int ceetm_init_root(struct Qdisc - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n", - __func__); -- goto err_init_root; -+ return err; - } - - bps = priv->root.ceil << 3; /* Bps -> bps */ -@@ -802,7 +795,7 @@ static int ceetm_init_root(struct Qdisc - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n", - __func__); -- goto err_init_root; -+ return err; - } - } - -@@ -810,10 +803,6 @@ static int ceetm_init_root(struct Qdisc - - dpa_enable_ceetm(dev); - return 0; -- --err_init_root: -- ceetm_destroy(sch); -- return err; - } - - /* Configure a prio ceetm qdisc */ -@@ -830,15 +819,13 @@ static int ceetm_init_prio(struct Qdisc - - if (sch->parent == TC_H_ROOT) { - pr_err("CEETM: a prio ceetm qdisc can not be root\n"); -- err = -EINVAL; -- goto err_init_prio; -+ return -EINVAL; - } - - parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent)); - if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) { - pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n"); -- err = -EINVAL; -- goto err_init_prio; -+ return -EINVAL; - } - - /* Obtain the parent root ceetm_class */ -@@ -846,8 +833,7 @@ static int ceetm_init_prio(struct Qdisc - - if (!parent_cl || parent_cl->type != CEETM_ROOT) { - pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n"); -- err = -EINVAL; -- goto err_init_prio; -+ return -EINVAL; - } - - priv->prio.parent = parent_cl; -@@ -863,8 +849,7 @@ static int ceetm_init_prio(struct Qdisc - if (!child_cl) { - pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n", - __func__); -- err = -ENOMEM; -- goto err_init_prio; -+ return -ENOMEM; - } - - child_cl->prio.cstats = alloc_percpu(struct ceetm_class_stats); -@@ -907,8 +892,7 @@ static int ceetm_init_prio(struct Qdisc - - err_init_prio_cls: - ceetm_cls_destroy(sch, child_cl); --err_init_prio: -- ceetm_destroy(sch); -+ /* Note: ceetm_destroy() will be called by our caller */ - return err; - } - -@@ -928,16 +912,14 @@ static int ceetm_init_wbfs(struct Qdisc - /* Validate inputs */ - if (sch->parent == TC_H_ROOT) { - pr_err("CEETM: a wbfs ceetm qdiscs can not be root\n"); -- err = -EINVAL; -- goto err_init_wbfs; -+ return -EINVAL; - } - - /* Obtain the parent prio ceetm qdisc */ - parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent)); - if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) { - pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n"); -- err = -EINVAL; -- goto err_init_wbfs; -+ return -EINVAL; - } - - /* Obtain the parent prio ceetm class */ -@@ -946,28 +928,24 @@ static int ceetm_init_wbfs(struct Qdisc - - if (!parent_cl || parent_cl->type != CEETM_PRIO) { - pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n"); -- err = -EINVAL; -- goto err_init_wbfs; -+ return -EINVAL; - } - - if (!qopt->qcount || !qopt->qweight[0]) { - pr_err("CEETM: qcount and qweight are mandatory for a wbfs ceetm qdisc\n"); -- err = -EINVAL; -- goto err_init_wbfs; -+ return -EINVAL; - } - - priv->shaped = parent_cl->shaped; - - if (!priv->shaped && (qopt->cr || qopt->er)) { - pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n"); -- err = -EINVAL; -- goto err_init_wbfs; -+ return -EINVAL; - } - - if (priv->shaped && !(qopt->cr || qopt->er)) { - pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n"); -- err = -EINVAL; -- goto err_init_wbfs; -+ return -EINVAL; - } - - /* Obtain the parent root ceetm class */ -@@ -975,16 +953,14 @@ static int ceetm_init_wbfs(struct Qdisc - if ((root_cl->root.wbfs_grp_a && root_cl->root.wbfs_grp_b) || - root_cl->root.wbfs_grp_large) { - pr_err("CEETM: no more wbfs classes are available\n"); -- err = -EINVAL; -- goto err_init_wbfs; -+ return -EINVAL; - } - - if ((root_cl->root.wbfs_grp_a || root_cl->root.wbfs_grp_b) && - qopt->qcount == CEETM_MAX_WBFS_QCOUNT) { - pr_err("CEETM: only %d wbfs classes are available\n", - CEETM_MIN_WBFS_QCOUNT); -- err = -EINVAL; -- goto err_init_wbfs; -+ return -EINVAL; - } - - priv->wbfs.parent = parent_cl; -@@ -1013,7 +989,7 @@ static int ceetm_init_wbfs(struct Qdisc - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to get group details\n", - __func__); -- goto err_init_wbfs; -+ return err; - } - - small_group = true; -@@ -1031,7 +1007,7 @@ static int ceetm_init_wbfs(struct Qdisc - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to get group details\n", - __func__); -- goto err_init_wbfs; -+ return err; - } - - small_group = true; -@@ -1044,7 +1020,7 @@ static int ceetm_init_wbfs(struct Qdisc - err = qman_ceetm_channel_set_group(priv->wbfs.ch, small_group, prio_a, - prio_b); - if (err) -- goto err_init_wbfs; -+ return err; - - if (priv->shaped) { - err = qman_ceetm_channel_set_group_cr_eligibility(priv->wbfs.ch, -@@ -1053,7 +1029,7 @@ static int ceetm_init_wbfs(struct Qdisc - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to set group CR eligibility\n", - __func__); -- goto err_init_wbfs; -+ return err; - } - - err = qman_ceetm_channel_set_group_er_eligibility(priv->wbfs.ch, -@@ -1062,7 +1038,7 @@ static int ceetm_init_wbfs(struct Qdisc - if (err) { - pr_err(KBUILD_BASENAME " : %s : failed to set group ER eligibility\n", - __func__); -- goto err_init_wbfs; -+ return err; - } - } - -@@ -1072,8 +1048,7 @@ static int ceetm_init_wbfs(struct Qdisc - if (!child_cl) { - pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n", - __func__); -- err = -ENOMEM; -- goto err_init_wbfs; -+ return -ENOMEM; - } - - child_cl->wbfs.cstats = alloc_percpu(struct ceetm_class_stats); -@@ -1130,8 +1105,7 @@ static int ceetm_init_wbfs(struct Qdisc - - err_init_wbfs_cls: - ceetm_cls_destroy(sch, child_cl); --err_init_wbfs: -- ceetm_destroy(sch); -+ /* Note: ceetm_destroy() will be called by our caller */ - return err; - } - -@@ -1202,7 +1176,7 @@ static int ceetm_init(struct Qdisc *sch, - break; - default: - pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__); -- ceetm_destroy(sch); -+ /* Note: ceetm_destroy() will be called by our caller */ - ret = -EINVAL; - } - -@@ -1549,7 +1523,7 @@ static int ceetm_cls_change(struct Qdisc - } - - if (!cl && priv->type != CEETM_ROOT) { -- pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n"); -+ pr_err("CEETM: root ceetm classes can be attached to the root ceetm qdisc only\n"); - return -EINVAL; - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0087-sdk_dpaa-ceetm-rename-qdisc_destroy-to-qdisc_put.patch b/target/linux/layerscape/patches-5.4/701-net-0087-sdk_dpaa-ceetm-rename-qdisc_destroy-to-qdisc_put.patch deleted file mode 100644 index 745952ba87..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0087-sdk_dpaa-ceetm-rename-qdisc_destroy-to-qdisc_put.patch +++ /dev/null @@ -1,48 +0,0 @@ -From b8f8c14491160043dd880d1e62c01903402352b2 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 24 Oct 2018 13:35:16 +0300 -Subject: [PATCH] sdk_dpaa: ceetm: rename qdisc_destroy() to qdisc_put() - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -432,7 +432,7 @@ static void ceetm_cls_destroy(struct Qdi - switch (cl->type) { - case CEETM_ROOT: - if (cl->root.child) { -- qdisc_destroy(cl->root.child); -+ qdisc_put(cl->root.child); - cl->root.child = NULL; - } - -@@ -445,7 +445,7 @@ static void ceetm_cls_destroy(struct Qdi - - case CEETM_PRIO: - if (cl->prio.child) { -- qdisc_destroy(cl->prio.child); -+ qdisc_put(cl->prio.child); - cl->prio.child = NULL; - } - -@@ -567,7 +567,7 @@ static void ceetm_destroy(struct Qdisc * - */ - for (ntx = 0; ntx < dev->num_tx_queues; ntx++) - if (priv->root.qdiscs[ntx]) -- qdisc_destroy(priv->root.qdiscs[ntx]); -+ qdisc_put(priv->root.qdiscs[ntx]); - - kfree(priv->root.qdiscs); - break; -@@ -1367,7 +1367,7 @@ static void ceetm_attach(struct Qdisc *s - qdisc = priv->root.qdiscs[i]; - old_qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc); - if (old_qdisc) -- qdisc_destroy(old_qdisc); -+ qdisc_put(old_qdisc); - } - - kfree(priv->root.qdiscs); diff --git a/target/linux/layerscape/patches-5.4/701-net-0088-sdk_dpaa-remove-FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE.patch b/target/linux/layerscape/patches-5.4/701-net-0088-sdk_dpaa-remove-FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE.patch deleted file mode 100644 index dbbe46d5a9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0088-sdk_dpaa-remove-FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 357ab2939dbddfb6849c55be9de577db078d9037 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Fri, 12 Oct 2018 16:56:57 +0300 -Subject: [PATCH] sdk_dpaa: remove FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE - -Remove FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE and record the -receive CPU in skb queue mapping to maintain the same CPU -for tx in forwarding scenarios. - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_dpaa/Kconfig | 13 +------------ - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 2 +- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 12 ++---------- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 3 +-- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 2 +- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 2 ++ - 6 files changed, 8 insertions(+), 26 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig -@@ -96,17 +96,6 @@ config FSL_DPAA_1588 - help - Enable IEEE1588 support code. - --config FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -- bool "Use driver's Tx queue selection mechanism" -- default y -- depends on FSL_SDK_DPAA_ETH -- help -- The DPAA-Ethernet driver defines a ndo_select_queue() callback for optimal selection -- of the egress FQ. That will override the XPS support for this netdevice. -- If for whatever reason you want to be in control of the egress FQ-to-CPU selection and mapping, -- or simply don't want to use the driver's ndo_select_queue() callback, then unselect this -- and use the standard XPS support instead. -- - config FSL_DPAA_ETH_MAX_BUF_COUNT - int "Maximum nuber of buffers in private bpool" - depends on FSL_SDK_DPAA_ETH -@@ -178,7 +167,7 @@ config FSL_DPAA_ETH_DEBUG - - config FSL_DPAA_DBG_LOOP - bool "DPAA Ethernet Debug loopback" -- depends on FSL_DPAA_ETH_DEBUGFS && FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -+ depends on FSL_DPAA_ETH_DEBUGFS - default n - help - This option allows to divert all received traffic on a certain interface A towards a ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -@@ -678,7 +678,7 @@ static const struct net_device_ops dpa_p - .ndo_get_stats64 = dpa_get_stats64, - .ndo_set_mac_address = dpa_set_mac_address, - .ndo_validate_addr = eth_validate_addr, --#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -+#ifdef CONFIG_FMAN_PFC - .ndo_select_queue = dpa_select_queue, - #endif - .ndo_set_rx_mode = dpa_set_rx_mode, ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -635,23 +635,15 @@ static inline void _dpa_assign_wq(struct - } - } - --#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE --/* Use in lieu of skb_get_queue_mapping() */ - #ifdef CONFIG_FMAN_PFC -+/* Use in lieu of skb_get_queue_mapping() */ - #define dpa_get_queue_mapping(skb) \ - (((skb)->priority < CONFIG_FMAN_PFC_COS_COUNT) ? \ - ((skb)->priority * dpa_num_cpus + smp_processor_id()) : \ - ((CONFIG_FMAN_PFC_COS_COUNT - 1) * \ - dpa_num_cpus + smp_processor_id())); -- - #else --#define dpa_get_queue_mapping(skb) \ -- raw_smp_processor_id() --#endif --#else --/* Use the queue selected by XPS */ --#define dpa_get_queue_mapping(skb) \ -- skb_get_queue_mapping(skb) -+#define dpa_get_queue_mapping(skb) skb_get_queue_mapping(skb) - #endif - - #ifdef CONFIG_PTP_1588_CLOCK_DPAA ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -841,14 +841,13 @@ bool dpa_bpid2pool_use(int bpid) - return false; - } - --#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -+#ifdef CONFIG_FMAN_PFC - u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb, - struct net_device *sb_dev, - select_queue_fallback_t fallback) - { - return dpa_get_queue_mapping(skb); - } --EXPORT_SYMBOL(dpa_select_queue); - #endif - - struct dpa_fq *dpa_fq_alloc(struct device *dev, ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h -@@ -172,7 +172,7 @@ struct dpa_bp *dpa_bpid2pool(int bpid); - void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp); - bool dpa_bpid2pool_use(int bpid); - void dpa_bp_drain(struct dpa_bp *bp); --#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE -+#ifdef CONFIG_FMAN_PFC - u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb, - struct net_device *sb_dev, - select_queue_fallback_t fallback); ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -648,6 +648,8 @@ void __hot _dpa_rx(struct net_device *ne - } - #endif - -+ skb_record_rx_queue(skb, raw_smp_processor_id()); -+ - if (use_gro) { - gro_result_t gro_result; - const struct qman_portal_config *pc = diff --git a/target/linux/layerscape/patches-5.4/701-net-0089-fsl-fman-backup-and-restore-ICID-registers.patch b/target/linux/layerscape/patches-5.4/701-net-0089-fsl-fman-backup-and-restore-ICID-registers.patch deleted file mode 100644 index a1ac7af5c3..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0089-fsl-fman-backup-and-restore-ICID-registers.patch +++ /dev/null @@ -1,116 +0,0 @@ -From ef2b0593c906a85ca59ed5957ae7a7361974349c Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 6 Feb 2018 16:21:17 +0200 -Subject: [PATCH] fsl/fman: backup and restore ICID registers - -During probing, FMAN is reset thus losing all its register -settings. Backup port ICID registers before reset and restore -them after, similarly to how it's done on powerpc / PAMU based -platforms. -This also has the side effect of disabling the old code path -(liodn backup/restore handling) that obviously make no sense -in the context of SMMU on ARMs. - -Signed-off-by: Laurentiu Tudor -Acked-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/fman/fman.c | 35 +++++++++++++++++++++++++++++- - drivers/net/ethernet/freescale/fman/fman.h | 4 ++++ - 2 files changed, 38 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/fman/fman.c -+++ b/drivers/net/ethernet/freescale/fman/fman.c -@@ -634,6 +634,7 @@ static void set_port_order_restoration(s - iowrite32be(tmp, &fpm_rg->fmfp_prc); - } - -+#ifdef CONFIG_PPC - static void set_port_liodn(struct fman *fman, u8 port_id, - u32 liodn_base, u32 liodn_ofst) - { -@@ -651,6 +652,27 @@ static void set_port_liodn(struct fman * - iowrite32be(tmp, &fman->dma_regs->fmdmplr[port_id / 2]); - iowrite32be(liodn_ofst, &fman->bmi_regs->fmbm_spliodn[port_id - 1]); - } -+#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+static void save_restore_port_icids(struct fman *fman, bool save) -+{ -+ int port_idxes[] = { -+ 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, -+ 0xd, 0xe, 0xf, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, -+ 0x10, 0x11, 0x30, 0x31 -+ }; -+ int idx, i; -+ -+ for (i = 0; i < ARRAY_SIZE(port_idxes); i++) { -+ idx = port_idxes[i]; -+ if (save) -+ fman->sp_icids[idx] = -+ ioread32be(&fman->bmi_regs->fmbm_spliodn[idx]); -+ else -+ iowrite32be(fman->sp_icids[idx], -+ &fman->bmi_regs->fmbm_spliodn[idx]); -+ } -+} -+#endif - - static void enable_rams_ecc(struct fman_fpm_regs __iomem *fpm_rg) - { -@@ -1918,7 +1940,10 @@ _return: - static int fman_init(struct fman *fman) - { - struct fman_cfg *cfg = NULL; -- int err = 0, i, count; -+ int err = 0, count; -+#ifdef CONFIG_PPC -+ int i; -+#endif - - if (is_init_done(fman->cfg)) - return -EINVAL; -@@ -1938,6 +1963,7 @@ static int fman_init(struct fman *fman) - memset_io((void __iomem *)(fman->base_addr + CGP_OFFSET), 0, - fman->state->fm_port_num_of_cg); - -+#ifdef CONFIG_PPC - /* Save LIODN info before FMan reset - * Skipping non-existent port 0 (i = 1) - */ -@@ -1957,6 +1983,9 @@ static int fman_init(struct fman *fman) - } - fman->liodn_base[i] = liodn_base; - } -+#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ save_restore_port_icids(fman, true); -+#endif - - err = fman_reset(fman); - if (err) -@@ -2185,8 +2214,12 @@ int fman_set_port_params(struct fman *fm - if (err) - goto return_err; - -+#ifdef CONFIG_PPC - set_port_liodn(fman, port_id, fman->liodn_base[port_id], - fman->liodn_offset[port_id]); -+#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ save_restore_port_icids(fman, false); -+#endif - - if (fman->state->rev_info.major < 6) - set_port_order_restoration(fman->fpm_regs, port_id); ---- a/drivers/net/ethernet/freescale/fman/fman.h -+++ b/drivers/net/ethernet/freescale/fman/fman.h -@@ -347,8 +347,12 @@ struct fman { - unsigned long fifo_offset; - size_t fifo_size; - -+#ifdef CONFIG_PPC - u32 liodn_base[64]; - u32 liodn_offset[64]; -+#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64) -+ u32 sp_icids[64]; -+#endif - - struct fman_dts_params dts_params; - }; diff --git a/target/linux/layerscape/patches-5.4/701-net-0090-fsl-fman-add-API-to-get-the-device-behind-a-fman-por.patch b/target/linux/layerscape/patches-5.4/701-net-0090-fsl-fman-add-API-to-get-the-device-behind-a-fman-por.patch deleted file mode 100644 index 58ed29c04f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0090-fsl-fman-add-API-to-get-the-device-behind-a-fman-por.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 975717f04388a052cab9d3c3b6828d065372b82a Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 3 Apr 2018 17:11:07 +0300 -Subject: [PATCH] fsl/fman: add API to get the device behind a fman port - -Add an API that retrieves the 'struct device' that the specified fman -port probed against. The new API will be used in a subsequent iommu -enablement related patch. - -Signed-off-by: Laurentiu Tudor -Acked-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/fman/fman_port.c | 14 ++++++++++++++ - drivers/net/ethernet/freescale/fman/fman_port.h | 2 ++ - 2 files changed, 16 insertions(+) - ---- a/drivers/net/ethernet/freescale/fman/fman_port.c -+++ b/drivers/net/ethernet/freescale/fman/fman_port.c -@@ -1728,6 +1728,20 @@ u32 fman_port_get_qman_channel_id(struct - } - EXPORT_SYMBOL(fman_port_get_qman_channel_id); - -+/** -+ * fman_port_get_device -+ * port: Pointer to the FMan port device -+ * -+ * Get the 'struct device' associated to the specified FMan port device -+ * -+ * Return: pointer to associated 'struct device' -+ */ -+struct device *fman_port_get_device(struct fman_port *port) -+{ -+ return port->dev; -+} -+EXPORT_SYMBOL(fman_port_get_device); -+ - int fman_port_get_hash_result_offset(struct fman_port *port, u32 *offset) - { - if (port->buffer_offsets.hash_result_offset == ILLEGAL_BASE) ---- a/drivers/net/ethernet/freescale/fman/fman_port.h -+++ b/drivers/net/ethernet/freescale/fman/fman_port.h -@@ -157,4 +157,6 @@ int fman_port_get_tstamp(struct fman_por - - struct fman_port *fman_port_bind(struct device *dev); - -+struct device *fman_port_get_device(struct fman_port *port); -+ - #endif /* __FMAN_PORT_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0091-dpaa_eth-defer-probing-after-qbman.patch b/target/linux/layerscape/patches-5.4/701-net-0091-dpaa_eth-defer-probing-after-qbman.patch deleted file mode 100644 index a86f7d9edb..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0091-dpaa_eth-defer-probing-after-qbman.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 9e1f89c4c637087dc8dc1a3f9f6bda5bff66e4ac Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 6 Feb 2018 14:40:32 +0200 -Subject: [PATCH] dpaa_eth: defer probing after qbman - -Enabling SMMU altered the order of device probing causing the dpaa1 -ethernet driver to get probed before qbman and causing a boot crash. -Add predictability in the probing order by deferring the ethernet -driver probe after qbman and portals by using the recently introduced -qbman APIs. - -Signed-off-by: Laurentiu Tudor -Acked-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 31 ++++++++++++++++++++++++++ - 1 file changed, 31 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -2947,6 +2947,37 @@ static int dpaa_eth_probe(struct platfor - int err = 0, i, channel; - struct device *dev; - -+ err = bman_is_probed(); -+ if (!err) -+ return -EPROBE_DEFER; -+ if (err < 0) { -+ dev_err(&pdev->dev, "failing probe due to bman probe error\n"); -+ return -ENODEV; -+ } -+ err = qman_is_probed(); -+ if (!err) -+ return -EPROBE_DEFER; -+ if (err < 0) { -+ dev_err(&pdev->dev, "failing probe due to qman probe error\n"); -+ return -ENODEV; -+ } -+ err = bman_portals_probed(); -+ if (!err) -+ return -EPROBE_DEFER; -+ if (err < 0) { -+ dev_err(&pdev->dev, -+ "failing probe due to bman portals probe error\n"); -+ return -ENODEV; -+ } -+ err = qman_portals_probed(); -+ if (!err) -+ return -EPROBE_DEFER; -+ if (err < 0) { -+ dev_err(&pdev->dev, -+ "failing probe due to qman portals probe error\n"); -+ return -ENODEV; -+ } -+ - /* device used for DMA mapping */ - dev = pdev->dev.parent; - err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40)); diff --git a/target/linux/layerscape/patches-5.4/701-net-0092-dpaa_eth-base-dma-mappings-on-the-fman-rx-port.patch b/target/linux/layerscape/patches-5.4/701-net-0092-dpaa_eth-base-dma-mappings-on-the-fman-rx-port.patch deleted file mode 100644 index 01cb5ed62b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0092-dpaa_eth-base-dma-mappings-on-the-fman-rx-port.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 13296e938da191216395952cf49ddda96e67359c Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Thu, 5 Apr 2018 12:37:57 +0300 -Subject: [PATCH] dpaa_eth: base dma mappings on the fman rx port - -The dma transactions initiator is the rx fman port so that's the device -that the dma mappings should be done. Previously the mappings were done -through the MAC device which makes no sense because it's neither dma-able -nor connected in any way to smmu. - -Signed-off-by: Laurentiu Tudor -Acked-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -2978,8 +2978,15 @@ static int dpaa_eth_probe(struct platfor - return -ENODEV; - } - -+ mac_dev = dpaa_mac_dev_get(pdev); -+ if (IS_ERR(mac_dev)) { -+ dev_err(&pdev->dev, "dpaa_mac_dev_get() failed\n"); -+ err = PTR_ERR(mac_dev); -+ goto probe_err; -+ } -+ - /* device used for DMA mapping */ -- dev = pdev->dev.parent; -+ dev = fman_port_get_device(mac_dev->port[RX]); - err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40)); - if (err) { - dev_err(dev, "dma_coerce_mask_and_coherent() failed\n"); -@@ -3004,13 +3011,6 @@ static int dpaa_eth_probe(struct platfor - - priv->msg_enable = netif_msg_init(debug, DPAA_MSG_DEFAULT); - -- mac_dev = dpaa_mac_dev_get(pdev); -- if (IS_ERR(mac_dev)) { -- dev_err(dev, "dpaa_mac_dev_get() failed\n"); -- err = PTR_ERR(mac_dev); -- goto free_netdev; -- } -- - /* If fsl_fm_max_frm is set to a higher value than the all-common 1500, - * we choose conservatively and let the user explicitly set a higher - * MTU via ifconfig. Otherwise, the user may end up with different MTUs -@@ -3146,9 +3146,9 @@ delete_egress_cgr: - qman_release_cgrid(priv->cgr_data.cgr.cgrid); - free_dpaa_bps: - dpaa_bps_free(priv); --free_netdev: - dev_set_drvdata(dev, NULL); - free_netdev(net_dev); -+probe_err: - - return err; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0093-dpaa_eth-fix-iova-handling-for-contiguous-frames.patch b/target/linux/layerscape/patches-5.4/701-net-0093-dpaa_eth-fix-iova-handling-for-contiguous-frames.patch deleted file mode 100644 index 430bed1378..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0093-dpaa_eth-fix-iova-handling-for-contiguous-frames.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 39e4cf29431dec8aaad599d9734f7a0468a9c20b Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Wed, 4 Apr 2018 12:31:05 +0300 -Subject: [PATCH] dpaa_eth: fix iova handling for contiguous frames - -The driver relies on the no longer valid assumption that dma addresses -(iovas) are identical to physical addressees and uses phys_to_virt() to -make iova -> vaddr conversions. Fix this by adding a function that does -proper iova -> phys conversions using the iommu api and update the code -to use it. -Also, a dma_unmap_single() call had to be moved further down the code -because iova -> vaddr conversions were required before the unmap. -For now only the contiguous frame case is handled and the SG case is -split in a following patch. -While at it, clean-up a redundant dpaa_bpid2pool() and pass the bp -as parameter. - -Signed-off-by: Laurentiu Tudor -Acked-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 44 ++++++++++++++------------ - 1 file changed, 24 insertions(+), 20 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -50,6 +50,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1615,6 +1616,17 @@ static int dpaa_eth_refill_bpools(struct - return 0; - } - -+static phys_addr_t dpaa_iova_to_phys(struct device *dev, dma_addr_t addr) -+{ -+ struct iommu_domain *domain; -+ -+ domain = iommu_get_domain_for_dev(dev); -+ if (domain) -+ return iommu_iova_to_phys(domain, addr); -+ else -+ return addr; -+} -+ - /* Cleanup function for outgoing frame descriptors that were built on Tx path, - * either contiguous frames or scatter/gather ones. - * Skb freeing is not handled here. -@@ -1639,7 +1651,7 @@ static struct sk_buff *dpaa_cleanup_tx_f - int nr_frags, i; - u64 ns; - -- skbh = (struct sk_buff **)phys_to_virt(addr); -+ skbh = (struct sk_buff **)phys_to_virt(dpaa_iova_to_phys(dev, addr)); - skb = *skbh; - - if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) { -@@ -1718,25 +1730,21 @@ static u8 rx_csum_offload(const struct d - * accommodate the shared info area of the skb. - */ - static struct sk_buff *contig_fd_to_skb(const struct dpaa_priv *priv, -- const struct qm_fd *fd) -+ const struct qm_fd *fd, -+ struct dpaa_bp *dpaa_bp, -+ void *vaddr) - { - ssize_t fd_off = qm_fd_get_offset(fd); -- dma_addr_t addr = qm_fd_addr(fd); -- struct dpaa_bp *dpaa_bp; - struct sk_buff *skb; -- void *vaddr; - -- vaddr = phys_to_virt(addr); - WARN_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES)); - -- dpaa_bp = dpaa_bpid2pool(fd->bpid); -- if (!dpaa_bp) -- goto free_buffer; -- - skb = build_skb(vaddr, dpaa_bp->size + - SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); -- if (WARN_ONCE(!skb, "Build skb failure on Rx\n")) -- goto free_buffer; -+ if (WARN_ONCE(!skb, "Build skb failure on Rx\n")) { -+ skb_free_frag(vaddr); -+ return NULL; -+ } - WARN_ON(fd_off != priv->rx_headroom); - skb_reserve(skb, fd_off); - skb_put(skb, qm_fd_get_length(fd)); -@@ -1744,10 +1752,6 @@ static struct sk_buff *contig_fd_to_skb( - skb->ip_summed = rx_csum_offload(priv, fd); - - return skb; -- --free_buffer: -- skb_free_frag(vaddr); -- return NULL; - } - - /* Build an skb with the data of the first S/G entry in the linear portion and -@@ -2476,12 +2480,12 @@ static enum qman_cb_dqrr_result rx_defau - if (!dpaa_bp) - return qman_cb_dqrr_consume; - -- dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE); -- - /* prefetch the first 64 bytes of the frame or the SGT start */ -- vaddr = phys_to_virt(addr); -+ vaddr = phys_to_virt(dpaa_iova_to_phys(dpaa_bp->dev, addr)); - prefetch(vaddr + qm_fd_get_offset(fd)); - -+ dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE); -+ - /* The only FD types that we may receive are contig and S/G */ - WARN_ON((fd_format != qm_fd_contig) && (fd_format != qm_fd_sg)); - -@@ -2492,7 +2496,7 @@ static enum qman_cb_dqrr_result rx_defau - (*count_ptr)--; - - if (likely(fd_format == qm_fd_contig)) -- skb = contig_fd_to_skb(priv, fd); -+ skb = contig_fd_to_skb(priv, fd, dpaa_bp, vaddr); - else - skb = sg_fd_to_skb(priv, fd); - if (!skb) diff --git a/target/linux/layerscape/patches-5.4/701-net-0094-dpaa_eth-fix-iova-handling-for-sg-frames.patch b/target/linux/layerscape/patches-5.4/701-net-0094-dpaa_eth-fix-iova-handling-for-sg-frames.patch deleted file mode 100644 index 273d7e5ea8..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0094-dpaa_eth-fix-iova-handling-for-sg-frames.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 73cc32aace5fe123182337c3abd769a1d6edd9fe Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Wed, 4 Apr 2018 15:12:28 +0300 -Subject: [PATCH] dpaa_eth: fix iova handling for sg frames - -The driver relies on the no longer valid assumption that dma addresses -(iovas) are identical to physical addressees and uses phys_to_virt() to -make iova -> vaddr conversions. Fix this also for scatter-gather frames -using the iova -> phys conversion function added in the previous patch. -While at it, clean-up a redundant dpaa_bpid2pool() and pass the bp -as parameter. - -Signed-off-by: Laurentiu Tudor -Acked-by: Madalin Bucur -[rebase] -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 41 +++++++++++++++----------- - 1 file changed, 24 insertions(+), 17 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -1656,14 +1656,17 @@ static struct sk_buff *dpaa_cleanup_tx_f - - if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) { - nr_frags = skb_shinfo(skb)->nr_frags; -- dma_unmap_single(dev, addr, -- qm_fd_get_offset(fd) + DPAA_SGT_SIZE, -- dma_dir); - - /* The sgt buffer has been allocated with netdev_alloc_frag(), - * it's from lowmem. - */ -- sgt = phys_to_virt(addr + qm_fd_get_offset(fd)); -+ sgt = phys_to_virt(dpaa_iova_to_phys(dev, -+ addr + -+ qm_fd_get_offset(fd))); -+ -+ dma_unmap_single(dev, addr, -+ qm_fd_get_offset(fd) + DPAA_SGT_SIZE, -+ dma_dir); - - /* sgt[0] is from lowmem, was dma_map_single()-ed */ - dma_unmap_single(dev, qm_sg_addr(&sgt[0]), -@@ -1702,7 +1705,7 @@ static struct sk_buff *dpaa_cleanup_tx_f - else - #endif - /* Free the page frag that we allocated on Tx */ -- skb_free_frag(phys_to_virt(addr)); -+ skb_free_frag(phys_to_virt(skbh)); - } - - return skb; -@@ -1760,14 +1763,14 @@ static struct sk_buff *contig_fd_to_skb( - * The page fragment holding the S/G Table is recycled here. - */ - static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, -- const struct qm_fd *fd) -+ const struct qm_fd *fd, -+ struct dpaa_bp *dpaa_bp, -+ void *vaddr) - { - ssize_t fd_off = qm_fd_get_offset(fd); -- dma_addr_t addr = qm_fd_addr(fd); - const struct qm_sg_entry *sgt; - struct page *page, *head_page; -- struct dpaa_bp *dpaa_bp; -- void *vaddr, *sg_vaddr; -+ void *sg_vaddr; - int frag_off, frag_len; - struct sk_buff *skb; - dma_addr_t sg_addr; -@@ -1776,7 +1779,6 @@ static struct sk_buff *sg_fd_to_skb(cons - int *count_ptr; - int i; - -- vaddr = phys_to_virt(addr); - WARN_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES)); - - /* Iterate through the SGT entries and add data buffers to the skb */ -@@ -1787,14 +1789,18 @@ static struct sk_buff *sg_fd_to_skb(cons - WARN_ON(qm_sg_entry_is_ext(&sgt[i])); - - sg_addr = qm_sg_addr(&sgt[i]); -- sg_vaddr = phys_to_virt(sg_addr); -- WARN_ON(!IS_ALIGNED((unsigned long)sg_vaddr, -- SMP_CACHE_BYTES)); - - /* We may use multiple Rx pools */ - dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); -- if (!dpaa_bp) -+ if (!dpaa_bp) { -+ pr_info("%s: fail to get dpaa_bp for sg bpid %d\n", -+ __func__, sgt[i].bpid); - goto free_buffers; -+ } -+ sg_vaddr = phys_to_virt(dpaa_iova_to_phys(dpaa_bp->dev, -+ sg_addr)); -+ WARN_ON(!IS_ALIGNED((unsigned long)sg_vaddr, -+ SMP_CACHE_BYTES)); - - count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); - dma_unmap_single(dpaa_bp->dev, sg_addr, dpaa_bp->size, -@@ -1866,10 +1872,11 @@ free_buffers: - /* free all the SG entries */ - for (i = 0; i < DPAA_SGT_MAX_ENTRIES ; i++) { - sg_addr = qm_sg_addr(&sgt[i]); -- sg_vaddr = phys_to_virt(sg_addr); -- skb_free_frag(sg_vaddr); - dpaa_bp = dpaa_bpid2pool(sgt[i].bpid); - if (dpaa_bp) { -+ sg_addr = dpaa_iova_to_phys(dpaa_bp->dev, sg_addr); -+ sg_vaddr = phys_to_virt(sg_addr); -+ skb_free_frag(sg_vaddr); - count_ptr = this_cpu_ptr(dpaa_bp->percpu_count); - (*count_ptr)--; - } -@@ -2498,7 +2505,7 @@ static enum qman_cb_dqrr_result rx_defau - if (likely(fd_format == qm_fd_contig)) - skb = contig_fd_to_skb(priv, fd, dpaa_bp, vaddr); - else -- skb = sg_fd_to_skb(priv, fd); -+ skb = sg_fd_to_skb(priv, fd, dpaa_bp, vaddr); - if (!skb) - return qman_cb_dqrr_consume; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0095-sdk_dpaa-ceetm-guard-against-an-out-of-bounds-queue-.patch b/target/linux/layerscape/patches-5.4/701-net-0095-sdk_dpaa-ceetm-guard-against-an-out-of-bounds-queue-.patch deleted file mode 100644 index 6c41d0f7af..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0095-sdk_dpaa-ceetm-guard-against-an-out-of-bounds-queue-.patch +++ /dev/null @@ -1,34 +0,0 @@ -From cfda91fdd3396b97f2c08f0d8ed7749fbd87bb7b Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 30 Oct 2018 17:34:31 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: guard against an out of bounds queue index - -Make sure the queue mapping recorded in the skb is not larger than our -egress queue count. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -1982,7 +1982,7 @@ static struct ceetm_class *ceetm_classif - - int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev) - { -- const int queue_mapping = dpa_get_queue_mapping(skb); -+ int queue_mapping = dpa_get_queue_mapping(skb); - struct Qdisc *sch = net_dev->qdisc; - struct ceetm_class_stats *cstats; - struct ceetm_qdisc_stats *qstats; -@@ -2016,6 +2016,9 @@ int __hot ceetm_tx(struct sk_buff *skb, - goto drop; - } - -+ if (unlikely(queue_mapping >= DPAA_ETH_TX_QUEUES)) -+ queue_mapping = queue_mapping % DPAA_ETH_TX_QUEUES; -+ - priv_dpa = netdev_priv(net_dev); - conf_fq = priv_dpa->conf_fqs[queue_mapping]; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0096-sdk_dpaa-guard-against-an-out-of-bounds-queue-index.patch b/target/linux/layerscape/patches-5.4/701-net-0096-sdk_dpaa-guard-against-an-out-of-bounds-queue-index.patch deleted file mode 100644 index 9616177009..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0096-sdk_dpaa-guard-against-an-out-of-bounds-queue-index.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 56203e34ec05e39a088036b5d9db7fde7a7af742 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 30 Oct 2018 18:18:30 +0200 -Subject: [PATCH] sdk_dpaa: guard against an out of bounds queue index - -Make sure the queue mapping recorded in the skb is not larger than our -egress queue count. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -1035,7 +1035,7 @@ EXPORT_SYMBOL(skb_to_sg_fd); - int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev) - { - struct dpa_priv_s *priv; -- const int queue_mapping = dpa_get_queue_mapping(skb); -+ int queue_mapping = dpa_get_queue_mapping(skb); - struct qman_fq *egress_fq, *conf_fq; - - #ifdef CONFIG_FSL_DPAA_HOOKS -@@ -1053,6 +1053,9 @@ int __hot dpa_tx(struct sk_buff *skb, st - return ceetm_tx(skb, net_dev); - #endif - -+ if (unlikely(queue_mapping >= DPAA_ETH_TX_QUEUES)) -+ queue_mapping = queue_mapping % DPAA_ETH_TX_QUEUES; -+ - egress_fq = priv->egress_fqs[queue_mapping]; - conf_fq = priv->conf_fqs[queue_mapping]; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0097-sdk_dpaa-set-the-skb-queue-mapping-when-looping.patch b/target/linux/layerscape/patches-5.4/701-net-0097-sdk_dpaa-set-the-skb-queue-mapping-when-looping.patch deleted file mode 100644 index f4a0b3e302..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0097-sdk_dpaa-set-the-skb-queue-mapping-when-looping.patch +++ /dev/null @@ -1,26 +0,0 @@ -From ae59df58bacb7d3daf2cf736f286a368ee703778 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 30 Oct 2018 18:18:57 +0200 -Subject: [PATCH] sdk_dpaa: set the skb queue mapping when looping - -Save the current CPU ID on ingress, when FSL_DPAA_DBG_LOOP is set. -Use the skb_set_queue_mapping() call instead of skb_record_rx_queue() -because the stack isn't involved and won't compensate for the additional -offset. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -575,6 +575,8 @@ static inline int dpa_skb_loop(const str - return 0; /* loop disabled by default */ - - skb_push(skb, ETH_HLEN); /* compensate for eth_type_trans */ -+ /* Save the current CPU ID in order to maintain core affinity */ -+ skb_set_queue_mapping(skb, raw_smp_processor_id()); - dpa_tx(skb, dpa_loop_netdevs[priv->loop_to]); - - return 1; /* Frame Tx on the selected interface */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0098-sdk_dpaa-remove-ptp-clock-driver.patch b/target/linux/layerscape/patches-5.4/701-net-0098-sdk_dpaa-remove-ptp-clock-driver.patch deleted file mode 100644 index a34d952f7e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0098-sdk_dpaa-remove-ptp-clock-driver.patch +++ /dev/null @@ -1,392 +0,0 @@ -From 0738b02f733717693226db401784e884a0714d41 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 31 Oct 2018 16:59:01 +0800 -Subject: [PATCH] sdk_dpaa: remove ptp clock driver - -Removed dpaa_ptp driver since we could use common -ptp_qoriq driver in drivers/ptp/ instead. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/sdk_dpaa/Makefile | 1 - - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 10 - - .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 21 -- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c | 291 --------------------- - drivers/net/ethernet/freescale/sdk_dpaa/mac.h | 3 +- - 5 files changed, 1 insertion(+), 325 deletions(-) - delete mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/Makefile -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile -@@ -9,7 +9,6 @@ include $(srctree)/drivers/net/ethernet/ - ccflags-y += -I$(NET_DPA) - - obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_mac.o fsl_dpa.o --obj-$(CONFIG_PTP_1588_CLOCK_DPAA) += dpaa_ptp.o - - fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o - ifeq ($(CONFIG_FSL_DPAA_DBG_LOOP),y) ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -646,16 +646,6 @@ static inline void _dpa_assign_wq(struct - #define dpa_get_queue_mapping(skb) skb_get_queue_mapping(skb) - #endif - --#ifdef CONFIG_PTP_1588_CLOCK_DPAA --struct ptp_priv_s { -- struct device_node *node; -- struct platform_device *of_dev; -- struct ptp_clock *clock; -- struct mac_device *mac_dev; --}; --extern struct ptp_priv_s ptp_priv; --#endif -- - static inline void _dpa_bp_free_pf(void *addr) - { - put_page(virt_to_head_page(addr)); ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -55,10 +55,6 @@ - /* Size in bytes of the FQ taildrop threshold */ - #define DPA_FQ_TD 0x200000 - --#ifdef CONFIG_PTP_1588_CLOCK_DPAA --struct ptp_priv_s ptp_priv; --#endif -- - static struct dpa_bp *dpa_bp_array[64]; - - int dpa_max_frm; -@@ -579,23 +575,6 @@ dpa_mac_probe(struct platform_device *_o - } - #endif - --#ifdef CONFIG_PTP_1588_CLOCK_DPAA -- if ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) || -- ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) && -- (mac_dev->speed == SPEED_1000))) { -- ptp_priv.node = of_parse_phandle(mac_node, "ptp-timer", 0); -- if (ptp_priv.node) { -- ptp_priv.of_dev = of_find_device_by_node(ptp_priv.node); -- if (unlikely(ptp_priv.of_dev == NULL)) { -- dev_err(dpa_dev, -- "Cannot find device represented by timer_node\n"); -- of_node_put(ptp_priv.node); -- return ERR_PTR(-EINVAL); -- } -- ptp_priv.mac_dev = mac_dev; -- } -- } --#endif - return mac_dev; - } - EXPORT_SYMBOL(dpa_mac_probe); ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c -+++ /dev/null -@@ -1,291 +0,0 @@ --/* -- * DPAA Ethernet Driver -- PTP 1588 clock using the dTSEC -- * -- * Author: Yangbo Lu -- * -- * Copyright 2014 Freescale Semiconductor, Inc. -- * -- * This program is free software; you can redistribute it and/or modify it -- * under the terms of the GNU General Public License as published by the -- * Free Software Foundation; either version 2 of the License, or (at your -- * option) any later version. --*/ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --#include "dpaa_eth.h" --#include "mac.h" -- --static struct mac_device *mac_dev; --static u32 freqCompensation; -- --/* Bit definitions for the TMR_CTRL register */ --#define ALM1P (1<<31) /* Alarm1 output polarity */ --#define ALM2P (1<<30) /* Alarm2 output polarity */ --#define FS (1<<28) /* FIPER start indication */ --#define PP1L (1<<27) /* Fiper1 pulse loopback mode enabled. */ --#define PP2L (1<<26) /* Fiper2 pulse loopback mode enabled. */ --#define TCLK_PERIOD_SHIFT (16) /* 1588 timer reference clock period. */ --#define TCLK_PERIOD_MASK (0x3ff) --#define RTPE (1<<15) /* Record Tx Timestamp to PAL Enable. */ --#define FRD (1<<14) /* FIPER Realignment Disable */ --#define ESFDP (1<<11) /* External Tx/Rx SFD Polarity. */ --#define ESFDE (1<<10) /* External Tx/Rx SFD Enable. */ --#define ETEP2 (1<<9) /* External trigger 2 edge polarity */ --#define ETEP1 (1<<8) /* External trigger 1 edge polarity */ --#define COPH (1<<7) /* Generated clock output phase. */ --#define CIPH (1<<6) /* External oscillator input clock phase */ --#define TMSR (1<<5) /* Timer soft reset. */ --#define BYP (1<<3) /* Bypass drift compensated clock */ --#define TE (1<<2) /* 1588 timer enable. */ --#define CKSEL_SHIFT (0) /* 1588 Timer reference clock source */ --#define CKSEL_MASK (0x3) -- --/* Bit definitions for the TMR_TEVENT register */ --#define ETS2 (1<<25) /* External trigger 2 timestamp sampled */ --#define ETS1 (1<<24) /* External trigger 1 timestamp sampled */ --#define ALM2 (1<<17) /* Current time = alarm time register 2 */ --#define ALM1 (1<<16) /* Current time = alarm time register 1 */ --#define PP1 (1<<7) /* periodic pulse generated on FIPER1 */ --#define PP2 (1<<6) /* periodic pulse generated on FIPER2 */ --#define PP3 (1<<5) /* periodic pulse generated on FIPER3 */ -- --/* Bit definitions for the TMR_TEMASK register */ --#define ETS2EN (1<<25) /* External trigger 2 timestamp enable */ --#define ETS1EN (1<<24) /* External trigger 1 timestamp enable */ --#define ALM2EN (1<<17) /* Timer ALM2 event enable */ --#define ALM1EN (1<<16) /* Timer ALM1 event enable */ --#define PP1EN (1<<7) /* Periodic pulse event 1 enable */ --#define PP2EN (1<<6) /* Periodic pulse event 2 enable */ -- --/* Bit definitions for the TMR_PEVENT register */ --#define TXP2 (1<<9) /* PTP transmitted timestamp im TXTS2 */ --#define TXP1 (1<<8) /* PTP transmitted timestamp in TXTS1 */ --#define RXP (1<<0) /* PTP frame has been received */ -- --/* Bit definitions for the TMR_PEMASK register */ --#define TXP2EN (1<<9) /* Transmit PTP packet event 2 enable */ --#define TXP1EN (1<<8) /* Transmit PTP packet event 1 enable */ --#define RXPEN (1<<0) /* Receive PTP packet event enable */ -- --/* Bit definitions for the TMR_STAT register */ --#define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */ --#define STAT_VEC_MASK (0x3f) -- --/* Bit definitions for the TMR_PRSC register */ --#define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */ --#define PRSC_OCK_MASK (0xffff) -- -- --#define N_EXT_TS 2 -- --static void set_alarm(void) --{ -- u64 ns; -- -- if (mac_dev->fm_rtc_get_cnt) -- mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns); -- ns += 1500000000ULL; -- ns = div_u64(ns, 1000000000UL) * 1000000000ULL; -- ns -= DPA_PTP_NOMINAL_FREQ_PERIOD_NS; -- if (mac_dev->fm_rtc_set_alarm) -- mac_dev->fm_rtc_set_alarm(mac_dev->fm_dev, 0, ns); --} -- --static void set_fipers(void) --{ -- u64 fiper; -- -- if (mac_dev->fm_rtc_disable) -- mac_dev->fm_rtc_disable(mac_dev->fm_dev); -- -- set_alarm(); -- fiper = 1000000000ULL - DPA_PTP_NOMINAL_FREQ_PERIOD_NS; -- if (mac_dev->fm_rtc_set_fiper) -- mac_dev->fm_rtc_set_fiper(mac_dev->fm_dev, 0, fiper); -- -- if (mac_dev->fm_rtc_enable) -- mac_dev->fm_rtc_enable(mac_dev->fm_dev); --} -- --/* PTP clock operations */ -- --static int ptp_dpa_adjfreq(struct ptp_clock_info *ptp, s32 ppb) --{ -- u64 adj; -- u32 diff, tmr_add; -- int neg_adj = 0; -- -- if (ppb < 0) { -- neg_adj = 1; -- ppb = -ppb; -- } -- -- tmr_add = freqCompensation; -- adj = tmr_add; -- adj *= ppb; -- diff = div_u64(adj, 1000000000ULL); -- -- tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff; -- -- if (mac_dev->fm_rtc_set_drift) -- mac_dev->fm_rtc_set_drift(mac_dev->fm_dev, tmr_add); -- -- return 0; --} -- --static int ptp_dpa_adjtime(struct ptp_clock_info *ptp, s64 delta) --{ -- s64 now; -- -- if (mac_dev->fm_rtc_get_cnt) -- mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &now); -- -- now += delta; -- -- if (mac_dev->fm_rtc_set_cnt) -- mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, now); -- set_fipers(); -- -- return 0; --} -- --static int ptp_dpa_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) --{ -- u64 ns; -- u32 remainder; -- -- if (mac_dev->fm_rtc_get_cnt) -- mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns); -- -- ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder); -- ts->tv_nsec = remainder; -- return 0; --} -- --static int ptp_dpa_settime(struct ptp_clock_info *ptp, -- const struct timespec64 *ts) --{ -- u64 ns; -- -- ns = ts->tv_sec * 1000000000ULL; -- ns += ts->tv_nsec; -- -- if (mac_dev->fm_rtc_set_cnt) -- mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, ns); -- set_fipers(); -- return 0; --} -- --static int ptp_dpa_enable(struct ptp_clock_info *ptp, -- struct ptp_clock_request *rq, int on) --{ -- u32 bit; -- -- switch (rq->type) { -- case PTP_CLK_REQ_EXTTS: -- switch (rq->extts.index) { -- case 0: -- bit = ETS1EN; -- break; -- case 1: -- bit = ETS2EN; -- break; -- default: -- return -EINVAL; -- } -- if (on) { -- if (mac_dev->fm_rtc_enable_interrupt) -- mac_dev->fm_rtc_enable_interrupt( -- mac_dev->fm_dev, bit); -- } else { -- if (mac_dev->fm_rtc_disable_interrupt) -- mac_dev->fm_rtc_disable_interrupt( -- mac_dev->fm_dev, bit); -- } -- return 0; -- -- case PTP_CLK_REQ_PPS: -- if (on) { -- if (mac_dev->fm_rtc_enable_interrupt) -- mac_dev->fm_rtc_enable_interrupt( -- mac_dev->fm_dev, PP1EN); -- } else { -- if (mac_dev->fm_rtc_disable_interrupt) -- mac_dev->fm_rtc_disable_interrupt( -- mac_dev->fm_dev, PP1EN); -- } -- return 0; -- -- default: -- break; -- } -- -- return -EOPNOTSUPP; --} -- --static struct ptp_clock_info ptp_dpa_caps = { -- .owner = THIS_MODULE, -- .name = "dpaa clock", -- .max_adj = 512000, -- .n_alarm = 0, -- .n_ext_ts = N_EXT_TS, -- .n_per_out = 0, -- .pps = 1, -- .adjfreq = ptp_dpa_adjfreq, -- .adjtime = ptp_dpa_adjtime, -- .gettime64 = ptp_dpa_gettime, -- .settime64 = ptp_dpa_settime, -- .enable = ptp_dpa_enable, --}; -- --static int __init __cold dpa_ptp_load(void) --{ -- struct device *ptp_dev; -- struct timespec64 now; -- struct ptp_clock *clock = ptp_priv.clock; -- int dpa_phc_index; -- int err; -- -- if (!(ptp_priv.of_dev && ptp_priv.mac_dev)) -- return -ENODEV; -- -- ptp_dev = &ptp_priv.of_dev->dev; -- mac_dev = ptp_priv.mac_dev; -- -- if (mac_dev->fm_rtc_get_drift) -- mac_dev->fm_rtc_get_drift(mac_dev->fm_dev, &freqCompensation); -- -- getnstimeofday64(&now); -- ptp_dpa_settime(&ptp_dpa_caps, &now); -- -- clock = ptp_clock_register(&ptp_dpa_caps, ptp_dev); -- if (IS_ERR(clock)) { -- err = PTR_ERR(clock); -- return err; -- } -- dpa_phc_index = ptp_clock_index(clock); -- return 0; --} --module_init(dpa_ptp_load); -- --static void __exit __cold dpa_ptp_unload(void) --{ -- struct ptp_clock *clock = ptp_priv.clock; -- -- if (mac_dev->fm_rtc_disable_interrupt) -- mac_dev->fm_rtc_disable_interrupt(mac_dev->fm_dev, 0xffffffff); -- ptp_clock_unregister(clock); --} --module_exit(dpa_ptp_unload); ---- a/drivers/net/ethernet/freescale/sdk_dpaa/mac.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h -@@ -97,10 +97,9 @@ struct mac_device { - int (*fm_rtc_set_alarm)(struct fm *fm_dev, uint32_t id, uint64_t time); - int (*fm_rtc_set_fiper)(struct fm *fm_dev, uint32_t id, - uint64_t fiper); --#ifdef CONFIG_PTP_1588_CLOCK_DPAA - int (*fm_rtc_enable_interrupt)(struct fm *fm_dev, uint32_t events); - int (*fm_rtc_disable_interrupt)(struct fm *fm_dev, uint32_t events); --#endif -+ - int (*set_wol)(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, - bool en); - int (*dump_mac_regs)(struct mac_device *h_mac, char *buf, int nn); diff --git a/target/linux/layerscape/patches-5.4/701-net-0099-sdk_fman-suspend-the-FMan-to-Deep-Sleep-on-PPC-only.patch b/target/linux/layerscape/patches-5.4/701-net-0099-sdk_fman-suspend-the-FMan-to-Deep-Sleep-on-PPC-only.patch deleted file mode 100644 index 677dbbc077..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0099-sdk_fman-suspend-the-FMan-to-Deep-Sleep-on-PPC-only.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 2223efd48766e22bbf56ba6000078af9e32c7772 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 17 Dec 2018 15:20:42 +0200 -Subject: [PATCH] sdk_fman: suspend the FMan to Deep Sleep on PPC only - -The SCFG_FMCLKDPSLPCR register is present on PPC targets only. This -feature does not apply to ARM SoCs. - -Signed-off-by: Camelia Groza ---- - .../net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -@@ -251,7 +251,7 @@ static irqreturn_t fm_irq(int irq, void - #ifdef CONFIG_PM_SLEEP - if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP) - { -- pm_wakeup_event(p_LnxWrpFmDev->dev, 200); -+ pm_wakeup_event(p_LnxWrpFmDev->dev, 200); - } - #endif - FM_EventIsr(p_LnxWrpFmDev->h_Dev); -@@ -1107,7 +1107,7 @@ static t_Error InitFmDev(t_LnxWrpFmDev - p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = - !!(get_rcwsr(4) & 0x1); /* RCW[FM_MAC_RAT1] */ - -- { -+ { - /* T4 Devices ClkRatio is always 1 regardless of RCW[FM_MAC_RAT1] */ - uint32_t svr; - svr = mfspr(SPRN_SVR); -@@ -1320,7 +1320,7 @@ static const struct of_device_id fm_matc - MODULE_DEVICE_TABLE(of, fm_match); - #endif /* !MODULE */ - --#ifdef CONFIG_PM -+#if defined CONFIG_PM && (defined CONFIG_PPC || defined CONFIG_PPC64) - - #define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C - #define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000 -@@ -1373,11 +1373,11 @@ static const struct dev_pm_ops fm_pm_ops - - #define FM_PM_OPS (&fm_pm_ops) - --#else /* CONFIG_PM */ -+#else /* CONFIG_PM && (CONFIG_PPC || CONFIG_PPC64) */ - - #define FM_PM_OPS NULL - --#endif /* CONFIG_PM */ -+#endif /* CONFIG_PM && (CONFIG_PPC || CONFIG_PPC64) */ - - static struct platform_driver fm_driver = { - .driver = { diff --git a/target/linux/layerscape/patches-5.4/701-net-0100-sdk_fman-disable-ptp-timer-probe.patch b/target/linux/layerscape/patches-5.4/701-net-0100-sdk_fman-disable-ptp-timer-probe.patch deleted file mode 100644 index 6976abe912..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0100-sdk_fman-disable-ptp-timer-probe.patch +++ /dev/null @@ -1,36 +0,0 @@ -From c96c8b30729c5e3ab2dc36d344f4d1a1a2ae400c Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 31 Oct 2018 17:07:40 +0800 -Subject: [PATCH] sdk_fman: disable ptp timer probe - -DPAA PTP timer was managed by ptp_qoriq driver in drivers/ptp/. -We will no longer manage it in sdk_fman driver and use related -APIs. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -@@ -682,6 +682,11 @@ static t_LnxWrpFmDev * ReadFmDevTreeNode - } - } - -+/* DPAA PTP timer was managed by ptp_qoriq driver in drivers/ptp/. -+ * We will no longer manage it in sdk_fman driver and use related -+ * APIs. -+ */ -+#if 0 - /* Get the RTC base address and size */ - memset(ids, 0, sizeof(ids)); - if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name))) -@@ -704,6 +709,7 @@ static t_LnxWrpFmDev * ReadFmDevTreeNode - p_LnxWrpFmDev->fmRtcMemSize = res.end + 1 - res.start; - } - } -+#endif - - #if (DPAA_VERSION >= 11) - /* Get the VSP base address */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0101-sdk_dpaa-add-the-get_ts_info-interface-for-ethtool.patch b/target/linux/layerscape/patches-5.4/701-net-0101-sdk_dpaa-add-the-get_ts_info-interface-for-ethtool.patch deleted file mode 100644 index 2343fba9a0..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0101-sdk_dpaa-add-the-get_ts_info-interface-for-ethtool.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 0ade532080c8cc777cd2af78b11040a353b89880 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Thu, 1 Nov 2018 10:34:52 +0800 -Subject: [PATCH] sdk_dpaa: add the get_ts_info interface for ethtool - -Added the get_ts_info interface for ethtool to check -the timestamping capability. - -Signed-off-by: Yangbo Lu ---- - .../net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c | 45 ++++++++++++++++++++++ - 1 file changed, 45 insertions(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c -@@ -39,6 +39,9 @@ - #endif - - #include -+#include -+#include -+#include - - #include "dpaa_eth.h" - #include "mac.h" /* struct mac_device */ -@@ -519,6 +522,47 @@ static void dpa_get_strings(struct net_d - memcpy(strings, dpa_stats_global, size); - } - -+static int dpaa_get_ts_info(struct net_device *net_dev, -+ struct ethtool_ts_info *info) -+{ -+ struct dpa_priv_s *priv = netdev_priv(net_dev); -+ struct device *dev = priv->mac_dev->dev; -+ struct device_node *mac_node = dev->of_node; -+ struct device_node *fman_node = NULL, *ptp_node = NULL; -+ struct platform_device *ptp_dev = NULL; -+ struct qoriq_ptp *ptp = NULL; -+ -+ info->phc_index = -1; -+ -+ fman_node = of_get_parent(mac_node); -+ if (fman_node) -+ ptp_node = of_parse_phandle(fman_node, "ptimer-handle", 0); -+ -+ if (ptp_node) -+ ptp_dev = of_find_device_by_node(ptp_node); -+ -+ if (ptp_dev) -+ ptp = platform_get_drvdata(ptp_dev); -+ -+ if (ptp) -+ info->phc_index = ptp->phc_index; -+ -+#ifdef CONFIG_FSL_DPAA_TS -+ info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | -+ SOF_TIMESTAMPING_RX_HARDWARE | -+ SOF_TIMESTAMPING_RAW_HARDWARE; -+ info->tx_types = (1 << HWTSTAMP_TX_OFF) | -+ (1 << HWTSTAMP_TX_ON); -+ info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) | -+ (1 << HWTSTAMP_FILTER_ALL); -+#else -+ info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | -+ SOF_TIMESTAMPING_SOFTWARE; -+#endif -+ -+ return 0; -+} -+ - const struct ethtool_ops dpa_ethtool_ops = { - .get_link_ksettings = dpa_get_ksettings, - .set_link_ksettings = dpa_set_ksettings, -@@ -539,4 +583,5 @@ const struct ethtool_ops dpa_ethtool_ops - .get_wol = dpa_get_wol, - .set_wol = dpa_set_wol, - #endif -+ .get_ts_info = dpaa_get_ts_info, - }; diff --git a/target/linux/layerscape/patches-5.4/701-net-0102-sdk_fman-share-the-event-interrupt.patch b/target/linux/layerscape/patches-5.4/701-net-0102-sdk_fman-share-the-event-interrupt.patch deleted file mode 100644 index 2dc042e811..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0102-sdk_fman-share-the-event-interrupt.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 078d5cda5fc94e1d40d8d44bc4a0067341f02e72 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Thu, 1 Nov 2018 12:10:59 +0800 -Subject: [PATCH] sdk_fman: share the event interrupt - -This patch is to share fman event interrupt because -the 1588 timer driver will also use this interrupt. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -@@ -883,7 +883,7 @@ static t_Error ConfigureFmDev(t_LnxWrpFm - if (unlikely(_errno < 0)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno)); - #endif -- _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, 0, "fman", p_LnxWrpFmDev); -+ _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, IRQF_SHARED, "fman", p_LnxWrpFmDev); - if (unlikely(_errno < 0)) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->irq, _errno)); - diff --git a/target/linux/layerscape/patches-5.4/701-net-0103-sdk_dpaa-fix-hardware-timestamp-value.patch b/target/linux/layerscape/patches-5.4/701-net-0103-sdk_dpaa-fix-hardware-timestamp-value.patch deleted file mode 100644 index e219c39739..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0103-sdk_dpaa-fix-hardware-timestamp-value.patch +++ /dev/null @@ -1,37 +0,0 @@ -From c96c65930fb5a348d96b88f4edeea1ddf8229c28 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Thu, 1 Nov 2018 15:34:17 +0800 -Subject: [PATCH] sdk_dpaa: fix hardware timestamp value - -The hardware timestamp value got didn't need to be multiplied -by nominal frequency since ptp_qoriq driver initialized the -counter to add clock period, not the clock tick. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -306,7 +306,7 @@ EXPORT_SYMBOL(dpa_fix_features); - u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx, - const void *data) - { -- u64 *ts, ns; -+ u64 *ts; - - ts = fm_port_get_buffer_time_stamp(priv->mac_dev->port_dev[rx_tx], - data); -@@ -316,10 +316,7 @@ u64 dpa_get_timestamp_ns(const struct dp - - be64_to_cpus(ts); - -- /* multiple DPA_PTP_NOMINAL_FREQ_PERIOD_NS for case of non power of 2 */ -- ns = *ts << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT; -- -- return ns; -+ return *ts; - } - - int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx, diff --git a/target/linux/layerscape/patches-5.4/701-net-0104-sdk_dpaa-remove-useless-1588-timer-enablement.patch b/target/linux/layerscape/patches-5.4/701-net-0104-sdk_dpaa-remove-useless-1588-timer-enablement.patch deleted file mode 100644 index 7454be5286..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0104-sdk_dpaa-remove-useless-1588-timer-enablement.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 988cd7a6bcbb738d6ad334a94fda07c965da862e Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 5 Dec 2018 16:31:13 +0800 -Subject: [PATCH] sdk_dpaa: remove useless 1588 timer enablement - -1588 timer had been enabled to run at ptp_qoriq driver -probing stage. So removed the useless enablement. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 4 ---- - 1 file changed, 4 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -340,8 +340,6 @@ static void dpa_ts_tx_enable(struct net_ - struct dpa_priv_s *priv = netdev_priv(dev); - struct mac_device *mac_dev = priv->mac_dev; - -- if (mac_dev->fm_rtc_enable) -- mac_dev->fm_rtc_enable(get_fm_handle(dev)); - if (mac_dev->ptp_enable) - mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev)); - -@@ -373,8 +371,6 @@ static void dpa_ts_rx_enable(struct net_ - struct dpa_priv_s *priv = netdev_priv(dev); - struct mac_device *mac_dev = priv->mac_dev; - -- if (mac_dev->fm_rtc_enable) -- mac_dev->fm_rtc_enable(get_fm_handle(dev)); - if (mac_dev->ptp_enable) - mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev)); - diff --git a/target/linux/layerscape/patches-5.4/701-net-0105-sdk-qbman-fix-issue-in-qman_delete_cgr_safe.patch b/target/linux/layerscape/patches-5.4/701-net-0105-sdk-qbman-fix-issue-in-qman_delete_cgr_safe.patch deleted file mode 100644 index 830a2ec05b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0105-sdk-qbman-fix-issue-in-qman_delete_cgr_safe.patch +++ /dev/null @@ -1,60 +0,0 @@ -From a16c129c9dfae01921faaed98587d318459d5cfc Mon Sep 17 00:00:00 2001 -From: Zhao Qiang -Date: Wed, 30 May 2018 17:09:02 +0800 -Subject: [PATCH] sdk/qbman: fix issue in qman_delete_cgr_safe() - -The wait_for_completion() call in qman_delete_cgr_safe() -was triggering a scheduling while atomic bug, replacing the -kthread with a smp_call_function_single() call to fix it. - -Signed-off-by: Madalin Bucur -Signed-off-by: Zhao Qiang ---- - drivers/staging/fsl_qbman/qman_high.c | 29 ++++++----------------------- - 1 file changed, 6 insertions(+), 23 deletions(-) - ---- a/drivers/staging/fsl_qbman/qman_high.c -+++ b/drivers/staging/fsl_qbman/qman_high.c -@@ -3075,36 +3075,19 @@ struct cgr_comp { - struct completion completion; - }; - --static int qman_delete_cgr_thread(void *p) -+static void qman_delete_cgr_smp_call(void *p) - { -- struct cgr_comp *cgr_comp = (struct cgr_comp *)p; -- int res; -- -- res = qman_delete_cgr((struct qman_cgr *)cgr_comp->cgr); -- complete(&cgr_comp->completion); -- -- return res; -+ qman_delete_cgr((struct qman_cgr *)p); - } - - void qman_delete_cgr_safe(struct qman_cgr *cgr) - { -- struct task_struct *thread; -- struct cgr_comp cgr_comp; -- - preempt_disable(); - if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) { -- init_completion(&cgr_comp.completion); -- cgr_comp.cgr = cgr; -- thread = kthread_create(qman_delete_cgr_thread, &cgr_comp, -- "cgr_del"); -- -- if (likely(!IS_ERR(thread))) { -- kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]); -- wake_up_process(thread); -- wait_for_completion(&cgr_comp.completion); -- preempt_enable(); -- return; -- } -+ smp_call_function_single(qman_cgr_cpus[cgr->cgrid], -+ qman_delete_cgr_smp_call, cgr, true); -+ preempt_enable(); -+ return; - } - qman_delete_cgr(cgr); - preempt_enable(); diff --git a/target/linux/layerscape/patches-5.4/701-net-0106-sdk_fman-avoid-array-overflow-error-in-fman-port-ini.patch b/target/linux/layerscape/patches-5.4/701-net-0106-sdk_fman-avoid-array-overflow-error-in-fman-port-ini.patch deleted file mode 100644 index 4490bc322c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0106-sdk_fman-avoid-array-overflow-error-in-fman-port-ini.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 5dc04d9dc9ac5d6eca6f1602a7b1c3b5a61625f4 Mon Sep 17 00:00:00 2001 -From: Florinel Iordache -Date: Mon, 4 Feb 2019 09:45:54 +0200 -Subject: [PATCH] sdk_fman: avoid array overflow error in fman port init - -Perform a verification of external buffer pools used which can cause array -overflow error in port init function SetExtBufferPools() if it was set to -value 1 via fman port API - -Signed-off-by: Florinel Iordache ---- - drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c -@@ -581,7 +581,8 @@ static t_Error SetExtBufferPools(t_FmPor - p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed; - p_FmPort->rxPoolsParams.largestBufSize = - sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]]; -- p_FmPort->rxPoolsParams.secondLargestBufSize = -+ if (p_ExtBufPools->numOfPoolsUsed > 1) -+ p_FmPort->rxPoolsParams.secondLargestBufSize = - sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]]; - - /* FMBM_RMPD reg. - pool depletion */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0107-fsl_qbman-Adjust-platform-device-creation-for-QMan-p.patch b/target/linux/layerscape/patches-5.4/701-net-0107-fsl_qbman-Adjust-platform-device-creation-for-QMan-p.patch deleted file mode 100644 index cd81c007c1..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0107-fsl_qbman-Adjust-platform-device-creation-for-QMan-p.patch +++ /dev/null @@ -1,103 +0,0 @@ -From fddd729bd2150e83365528cefb9f1fef581e04c5 Mon Sep 17 00:00:00 2001 -From: Vakul Garg -Date: Sun, 6 Jan 2019 19:05:37 +0530 -Subject: [PATCH] fsl_qbman: Adjust platform device creation for QMan portals - -Fix the platform device creation in QMan portals such that -dma mappings are done properly. - -Signed-off-by: Vakul Garg -Signed-off-by: Roy Pledge ---- - drivers/staging/fsl_qbman/qman_high.c | 47 +++++++++++++++++++---------------- - 1 file changed, 25 insertions(+), 22 deletions(-) - ---- a/drivers/staging/fsl_qbman/qman_high.c -+++ b/drivers/staging/fsl_qbman/qman_high.c -@@ -575,6 +575,7 @@ struct qman_portal *qman_create_portal( - char buf[16]; - int ret; - u32 isdr; -+ struct platform_device_info pdev_info; - - if (!portal) { - portal = kmalloc(sizeof(*portal), GFP_KERNEL); -@@ -671,27 +672,22 @@ struct qman_portal *qman_create_portal( - portal->dqrr_disable_ref = 0; - portal->cb_dc_ern = NULL; - sprintf(buf, "qportal-%d", config->public_cfg.channel); -- portal->pdev = platform_device_alloc(buf, -1); -+ -+ memset(&pdev_info, 0, sizeof(pdev_info)); -+ pdev_info.name = buf; -+ pdev_info.id = PLATFORM_DEVID_NONE; -+ pdev_info.dma_mask = DMA_BIT_MASK(40); -+ -+ portal->pdev = platform_device_register_full(&pdev_info); - if (!portal->pdev) { - pr_err("qman_portal - platform_device_alloc() failed\n"); -- goto fail_devalloc; -- } --#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) -- portal->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40); -- portal->pdev->dev.dma_mask = &portal->pdev->dev.coherent_dma_mask; --#else -- if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) { -- pr_err("qman_portal - dma_set_mask() failed\n"); -- goto fail_devadd; -+ goto fail_devregister; - } --#endif -+ -+ arch_setup_dma_ops(&portal->pdev->dev, 0, 0, NULL, true); -+ - portal->pdev->dev.pm_domain = &qman_portal_device_pm_domain; - portal->pdev->dev.platform_data = portal; -- ret = platform_device_add(portal->pdev); -- if (ret) { -- pr_err("qman_portal - platform_device_add() failed\n"); -- goto fail_devadd; -- } - dpa_rbtree_init(&portal->retire_table); - isdr = 0xffffffff; - qm_isr_disable_write(__p, isdr); -@@ -751,10 +747,8 @@ fail_eqcr_empty: - fail_affinity: - free_irq(config->public_cfg.irq, portal); - fail_irq: -- platform_device_del(portal->pdev); --fail_devadd: -- platform_device_put(portal->pdev); --fail_devalloc: -+ platform_device_unregister(portal->pdev); -+fail_devregister: - if (num_ceetms) - for (ret = 0; ret < num_ceetms; ret++) - kfree(portal->ccgrs[ret]); -@@ -852,8 +846,7 @@ void qman_destroy_portal(struct qman_por - qm_dqrr_finish(&qm->p); - qm_eqcr_finish(&qm->p); - -- platform_device_del(qm->pdev); -- platform_device_put(qm->pdev); -+ platform_device_unregister(qm->pdev); - - qm->config = NULL; - if (qm->alloced) -@@ -1809,6 +1802,16 @@ int qman_init_fq(struct qman_fq *fq, u32 - } else { - phys_fq = dma_map_single(&p->pdev->dev, fq, sizeof(*fq), - DMA_TO_DEVICE); -+ if (dma_mapping_error(&p->pdev->dev, phys_fq)) { -+ dev_err(&p->pdev->dev, -+ "dma_map_single failed for fqid: %u\n", -+ fq->fqid); -+ FQUNLOCK(fq); -+ PORTAL_IRQ_UNLOCK(p, irqflags); -+ put_affine_portal(); -+ return -EIO; -+ } -+ - qm_fqd_stashing_set64(&mcc->initfq.fqd, phys_fq); - } - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0108-sdk_dpaa-ls1043a-errata-impose-S-G-frame-realignment.patch b/target/linux/layerscape/patches-5.4/701-net-0108-sdk_dpaa-ls1043a-errata-impose-S-G-frame-realignment.patch deleted file mode 100644 index 8de280212f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0108-sdk_dpaa-ls1043a-errata-impose-S-G-frame-realignment.patch +++ /dev/null @@ -1,81 +0,0 @@ -From bfc02cc199dc6259c2f4e2af8f77c88fe8ba4cc5 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 5 Mar 2019 11:55:54 +0200 -Subject: [PATCH] sdk_dpaa: ls1043a errata: impose S/G frame realignment - -Scatter/Gather frames are not support on LS1043A beacuse they trigger -the A010022 errata. - -Even though we do not advertise S/G support to the stack, we need to -make sure that if S/G frames do reach the driver somehow, they trigger -the errata workaround. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 7 ++++--- - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 23 +++++----------------- - 2 files changed, 9 insertions(+), 21 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -653,9 +653,10 @@ static inline void _dpa_bp_free_pf(void - - /* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue - * manifests itself at high traffic rates when frames cross 4K memory -- * boundaries or when they are not aligned to 16 bytes; For the moment, we -- * use a SW workaround that realigns frames to 256 bytes. Scatter/Gather -- * frames aren't supported on egress. -+ * boundaries, when they are not aligned to 16 bytes or when they have -+ * Scatter/Gather fragments; For the moment, we use a SW workaround that -+ * realigns frames to 256 bytes. Scatter/Gather frames aren't supported -+ * on egress. - */ - - #ifndef CONFIG_PPC ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -772,18 +772,19 @@ EXPORT_SYMBOL(skb_to_contig_fd); - - #ifndef CONFIG_PPC - /* Verify the conditions that trigger the A010022 errata: data unaligned to -- * 16 bytes and 4K memory address crossings. -+ * 16 bytes, 4K memory address crossings and S/G fragments. - */ - static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv) - { -- int nr_frags, i = 0; -- skb_frag_t *frag; -- - /* Check if the headroom is aligned */ - if (((uintptr_t)skb->data - priv->tx_headroom) % - priv->buf_layout[TX].data_align != 0) - return true; - -+ /* Check for paged data in the skb. We do not support S/G fragments */ -+ if (skb_is_nonlinear(skb)) -+ return true; -+ - /* Check if the headroom crosses a boundary */ - if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb))) - return true; -@@ -796,20 +797,6 @@ static bool a010022_check_skb(struct sk_ - if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb))) - return true; - -- nr_frags = skb_shinfo(skb)->nr_frags; -- -- while (i < nr_frags) { -- frag = &skb_shinfo(skb)->frags[i]; -- -- /* Check if a paged fragment crosses a boundary from its -- * offset to its end. -- */ -- if (HAS_DMA_ISSUE(frag->page_offset, frag->size)) -- return true; -- -- i++; -- } -- - return false; - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0109-sdk_dpaa-remove-the-QM_FQCTRL_PREFERINCACHE-flag.patch b/target/linux/layerscape/patches-5.4/701-net-0109-sdk_dpaa-remove-the-QM_FQCTRL_PREFERINCACHE-flag.patch deleted file mode 100644 index e96f873ea9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0109-sdk_dpaa-remove-the-QM_FQCTRL_PREFERINCACHE-flag.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 3cf2ff1c53b41c60fcb7667a11c4947fe5136de7 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Thu, 7 Mar 2019 16:33:37 +0200 -Subject: [PATCH] sdk_dpaa: remove the QM_FQCTRL_PREFERINCACHE flag - -Only a limited number of FQs can be in the cache, setting the -QM_FQCTRL_PREFERINCACHE flag for all FQs is not useful. - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c -@@ -1237,8 +1237,6 @@ int dpa_fq_init(struct dpa_fq *dpa_fq, b - memset(&initfq, 0, sizeof(initfq)); - - initfq.we_mask = QM_INITFQ_WE_FQCTRL; -- /* FIXME: why would we want to keep an empty FQ in cache? */ -- initfq.fqd.fq_ctrl = QM_FQCTRL_PREFERINCACHE; - - /* Try to reduce the number of portal interrupts for - * Tx Confirmation FQs. diff --git a/target/linux/layerscape/patches-5.4/701-net-0110-sdk_dpaa-adapt-to-kernel-5.1.0-rc1.patch b/target/linux/layerscape/patches-5.4/701-net-0110-sdk_dpaa-adapt-to-kernel-5.1.0-rc1.patch deleted file mode 100644 index 72fa196479..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0110-sdk_dpaa-adapt-to-kernel-5.1.0-rc1.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 68b77d267414d790e5cbd76f46a77501559e5748 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 26 Mar 2019 18:27:11 +0200 -Subject: [PATCH] sdk_dpaa: adapt to kernel 5.1.0 rc1 - -Apply fixes corresponding to the following upstream patches: -3c1bcc8 net: ethernet: Convert phydev advertize and supported from u32 to link mode -1e562c8 ptp_qoriq: make structure/function names more consistent -70814e8 net: ethernet: Add helper for set_pauseparam for Asym Pause -22b7d29 net: ethernet: Add helper to determine if pause configuration is supported - -Signed-off-by: Camelia Groza ---- - .../net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c | 31 +++------------------- - drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c | 27 +++++++++---------- - 2 files changed, 16 insertions(+), 42 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c -@@ -225,7 +225,6 @@ static int __cold dpa_set_pauseparam(str - struct mac_device *mac_dev; - struct phy_device *phy_dev; - int _errno; -- u32 newadv, oldadv; - bool rx_pause, tx_pause; - - priv = netdev_priv(net_dev); -@@ -242,9 +241,7 @@ static int __cold dpa_set_pauseparam(str - return -ENODEV; - } - -- if (!(phy_dev->supported & SUPPORTED_Pause) || -- (!(phy_dev->supported & SUPPORTED_Asym_Pause) && -- (epause->rx_pause != epause->tx_pause))) -+ if (!phy_validate_pause(phy_dev, epause)) - return -EINVAL; - - /* The MAC should know how to handle PAUSE frame autonegotiation before -@@ -258,29 +255,7 @@ static int __cold dpa_set_pauseparam(str - /* Determine the sym/asym advertised PAUSE capabilities from the desired - * rx/tx pause settings. - */ -- newadv = 0; -- if (epause->rx_pause) -- newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause; -- if (epause->tx_pause) -- newadv |= ADVERTISED_Asym_Pause; -- -- oldadv = phy_dev->advertising & -- (ADVERTISED_Pause | ADVERTISED_Asym_Pause); -- -- /* If there are differences between the old and the new advertised -- * values, restart PHY autonegotiation and advertise the new values. -- */ -- if (oldadv != newadv) { -- phy_dev->advertising &= ~(ADVERTISED_Pause -- | ADVERTISED_Asym_Pause); -- phy_dev->advertising |= newadv; -- if (phy_dev->autoneg) { -- _errno = phy_start_aneg(phy_dev); -- if (unlikely(_errno < 0)) -- netdev_err(net_dev, "phy_start_aneg() = %d\n", -- _errno); -- } -- } -+ phy_set_asym_pause(phy_dev, epause->rx_pause, epause->tx_pause); - - get_pause_cfg(mac_dev, &rx_pause, &tx_pause); - _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause); -@@ -530,7 +505,7 @@ static int dpaa_get_ts_info(struct net_d - struct device_node *mac_node = dev->of_node; - struct device_node *fman_node = NULL, *ptp_node = NULL; - struct platform_device *ptp_dev = NULL; -- struct qoriq_ptp *ptp = NULL; -+ struct ptp_qoriq *ptp = NULL; - - info->phc_index = -1; - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c -@@ -385,11 +385,7 @@ void get_pause_cfg(struct mac_device *ma - */ - - /* get local capabilities */ -- lcl_adv = 0; -- if (phy_dev->advertising & ADVERTISED_Pause) -- lcl_adv |= ADVERTISE_PAUSE_CAP; -- if (phy_dev->advertising & ADVERTISED_Asym_Pause) -- lcl_adv |= ADVERTISE_PAUSE_ASYM; -+ lcl_adv = linkmode_adv_to_lcl_adv_t(phy_dev->advertising); - - /* get link partner capabilities */ - rmt_adv = 0; -@@ -439,6 +435,7 @@ static int dtsec_init_phy(struct net_dev - struct mac_device *mac_dev) - { - struct phy_device *phy_dev; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - - if (of_phy_is_fixed_link(mac_dev->phy_node)) - phy_dev = of_phy_attach(net_dev, mac_dev->phy_node, -@@ -455,12 +452,12 @@ static int dtsec_init_phy(struct net_dev - } - - /* Remove any features not supported by the controller */ -- phy_dev->supported &= mac_dev->if_support; -+ ethtool_convert_legacy_u32_to_link_mode(mask, mac_dev->if_support); -+ linkmode_and(phy_dev->supported, phy_dev->supported, mask); - /* Enable the symmetric and asymmetric PAUSE frame advertisements, - * as most of the PHY drivers do not enable them by default. - */ -- phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause); -- phy_dev->advertising = phy_dev->supported; -+ phy_support_asym_pause(phy_dev); - - mac_dev->phy_dev = phy_dev; - -@@ -471,6 +468,7 @@ static int xgmac_init_phy(struct net_dev - struct mac_device *mac_dev) - { - struct phy_device *phy_dev; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - - if (of_phy_is_fixed_link(mac_dev->phy_node)) - phy_dev = of_phy_attach(net_dev, mac_dev->phy_node, -@@ -486,12 +484,12 @@ static int xgmac_init_phy(struct net_dev - return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev); - } - -- phy_dev->supported &= mac_dev->if_support; -+ ethtool_convert_legacy_u32_to_link_mode(mask, mac_dev->if_support); -+ linkmode_and(phy_dev->supported, phy_dev->supported, mask); - /* Enable the symmetric and asymmetric PAUSE frame advertisements, - * as most of the PHY drivers do not enable them by default. - */ -- phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause); -- phy_dev->advertising = phy_dev->supported; -+ phy_support_asym_pause(phy_dev); - - mac_dev->phy_dev = phy_dev; - -@@ -502,6 +500,7 @@ static int memac_init_phy(struct net_dev - struct mac_device *mac_dev) - { - struct phy_device *phy_dev; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - void (*adjust_link_handler)(struct net_device *); - - if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) || -@@ -547,12 +546,12 @@ static int memac_init_phy(struct net_dev - } - - /* Remove any features not supported by the controller */ -- phy_dev->supported &= mac_dev->if_support; -+ ethtool_convert_legacy_u32_to_link_mode(mask, mac_dev->if_support); -+ linkmode_and(phy_dev->supported, phy_dev->supported, mask); - /* Enable the symmetric and asymmetric PAUSE frame advertisements, - * as most of the PHY drivers do not enable them by default. - */ -- phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause); -- phy_dev->advertising = phy_dev->supported; -+ phy_support_asym_pause(phy_dev); - - mac_dev->phy_dev = phy_dev; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0111-sdk_qbman-Avoid-variable-length-array-in-USDPAA.patch b/target/linux/layerscape/patches-5.4/701-net-0111-sdk_qbman-Avoid-variable-length-array-in-USDPAA.patch deleted file mode 100644 index 39cfc2d0be..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0111-sdk_qbman-Avoid-variable-length-array-in-USDPAA.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 0ad840e46732e95df274a84b042dcb210be9f946 Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Thu, 28 Mar 2019 09:56:35 -0400 -Subject: [PATCH] sdk_qbman: Avoid variable length array in USDPAA - -As of Linux 5.0 variable length arrays on the stack are no -longer allowed. Change to a dynamic array and create a common -exit point in the function for cleanup. - -Signed-off-by: Roy Pledge ---- - drivers/staging/fsl_qbman/fsl_usdpaa.c | 36 +++++++++++++++++----------------- - 1 file changed, 18 insertions(+), 18 deletions(-) - ---- a/drivers/staging/fsl_qbman/fsl_usdpaa.c -+++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c -@@ -559,6 +559,7 @@ static bool check_portal_channel(void *c - - static int usdpaa_release(struct inode *inode, struct file *filp) - { -+ int err = 0; - struct ctx *ctx = filp->private_data; - struct mem_mapping *map, *tmpmap; - struct portal_mapping *portal, *tmpportal; -@@ -569,9 +570,14 @@ static int usdpaa_release(struct inode * - struct qm_portal_config *qm_alloced_portal = NULL; - struct bm_portal_config *bm_alloced_portal = NULL; - -- struct qm_portal *portal_array[qman_portal_max]; -+ struct qm_portal **portal_array; - int portal_count = 0; - -+ portal_array = kmalloc_array(qman_portal_max, -+ sizeof(struct qm_portal *), GFP_KERNEL); -+ if (!portal_array) -+ return -ENOMEM; -+ - /* Ensure the release operation cannot be migrated to another - CPU as CPU specific variables may be needed during cleanup */ - #ifdef CONFIG_PREEMPT_RT_FULL -@@ -612,18 +618,14 @@ static int usdpaa_release(struct inode * - qm_alloced_portal = qm_get_unused_portal(); - if (!qm_alloced_portal) { - pr_crit("No QMan portal avalaible for cleanup\n"); --#ifdef CONFIG_PREEMPT_RT_FULL -- migrate_enable(); --#endif -- return -1; -+ err = -1; -+ goto done; - } - qm_cleanup_portal = kmalloc(sizeof(struct qm_portal), - GFP_KERNEL); - if (!qm_cleanup_portal) { --#ifdef CONFIG_PREEMPT_RT_FULL -- migrate_enable(); --#endif -- return -ENOMEM; -+ err = -ENOMEM; -+ goto done; - } - init_qm_portal(qm_alloced_portal, qm_cleanup_portal); - portal_array[portal_count] = qm_cleanup_portal; -@@ -633,18 +635,14 @@ static int usdpaa_release(struct inode * - bm_alloced_portal = bm_get_unused_portal(); - if (!bm_alloced_portal) { - pr_crit("No BMan portal avalaible for cleanup\n"); --#ifdef CONFIG_PREEMPT_RT_FULL -- migrate_enable(); --#endif -- return -1; -+ err = -1; -+ goto done; - } - bm_cleanup_portal = kmalloc(sizeof(struct bm_portal), - GFP_KERNEL); - if (!bm_cleanup_portal) { --#ifdef CONFIG_PREEMPT_RT_FULL -- migrate_enable(); --#endif -- return -ENOMEM; -+ err = -ENOMEM; -+ goto done; - } - init_bm_portal(bm_alloced_portal, bm_cleanup_portal); - } -@@ -721,10 +719,12 @@ static int usdpaa_release(struct inode * - } - - kfree(ctx); -+done: - #ifdef CONFIG_PREEMPT_RT_FULL - migrate_enable(); - #endif -- return 0; -+ kfree(portal_array); -+ return err; - } - - static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma, diff --git a/target/linux/layerscape/patches-5.4/701-net-0112-sdk_dpaa-Rework-QBMan-portal-mappings.patch b/target/linux/layerscape/patches-5.4/701-net-0112-sdk_dpaa-Rework-QBMan-portal-mappings.patch deleted file mode 100644 index 1752d1e304..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0112-sdk_dpaa-Rework-QBMan-portal-mappings.patch +++ /dev/null @@ -1,65 +0,0 @@ -From d0e3e315f49a0a35c7e0bdae934f33ee6b3042a0 Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Wed, 1 May 2019 16:08:53 -0400 -Subject: [PATCH] sdk_dpaa: Rework QBMan portal mappings - -Rework the QBMan portal mappings in the SDK driver to -match the mechanism used in the upstream varient. - -Signed-off-by: Roy Pledge ---- - drivers/staging/fsl_qbman/bman_driver.c | 16 ++++++++-------- - drivers/staging/fsl_qbman/qman_driver.c | 17 +++++++++-------- - 2 files changed, 17 insertions(+), 16 deletions(-) - ---- a/drivers/staging/fsl_qbman/bman_driver.c -+++ b/drivers/staging/fsl_qbman/bman_driver.c -@@ -199,14 +199,14 @@ static struct bm_portal_config * __init - resource_size(&pcfg->addr_phys[DPA_PORTAL_CI])); - - #else -- pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot( -- pcfg->addr_phys[DPA_PORTAL_CE].start, -- (unsigned long)len, -- 0); -- pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot( -- pcfg->addr_phys[DPA_PORTAL_CI].start, -- resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]), -- _PAGE_GUARDED | _PAGE_NO_CACHE); -+ pcfg->addr_virt[DPA_PORTAL_CE] = -+ memremap(pcfg->addr_phys[DPA_PORTAL_CE].start, -+ (unsigned long)len, MEMREMAP_WB); -+ -+ pcfg->addr_virt[DPA_PORTAL_CI] = -+ ioremap(pcfg->addr_phys[DPA_PORTAL_CI].start, -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CI])); -+ - #endif - /* disable bp depletion */ - __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(0)); ---- a/drivers/staging/fsl_qbman/qman_driver.c -+++ b/drivers/staging/fsl_qbman/qman_driver.c -@@ -459,14 +459,15 @@ static struct qm_portal_config * __init - pcfg->addr_phys[DPA_PORTAL_CI].start, - resource_size(&pcfg->addr_phys[DPA_PORTAL_CI])); - #else -- pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot( -- pcfg->addr_phys[DPA_PORTAL_CE].start, -- (unsigned long)len, -- 0); -- pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot( -- pcfg->addr_phys[DPA_PORTAL_CI].start, -- resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]), -- _PAGE_GUARDED | _PAGE_NO_CACHE); -+ -+ pcfg->addr_virt[DPA_PORTAL_CE] = -+ memremap(pcfg->addr_phys[DPA_PORTAL_CE].start, -+ (unsigned long)len, MEMREMAP_WB); -+ -+ pcfg->addr_virt[DPA_PORTAL_CI] = -+ ioremap(pcfg->addr_phys[DPA_PORTAL_CI].start, -+ resource_size(&pcfg->addr_phys[DPA_PORTAL_CI])); -+ - #endif - return pcfg; - err: diff --git a/target/linux/layerscape/patches-5.4/701-net-0113-sdk_qbman-Fix-error-in-IP-revision-comparison.patch b/target/linux/layerscape/patches-5.4/701-net-0113-sdk_qbman-Fix-error-in-IP-revision-comparison.patch deleted file mode 100644 index e2cd46a9c4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0113-sdk_qbman-Fix-error-in-IP-revision-comparison.patch +++ /dev/null @@ -1,28 +0,0 @@ -From e180239ef07855f44f3bab4cfa5ac47c6775d822 Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Mon, 6 May 2019 11:18:57 -0400 -Subject: [PATCH] sdk_qbman: Fix error in IP revision comparison - -The comparison for QMAN_REV31 was incorrect as it -would always fail due to the wrong mask. - -This fixes the following error in newer GCC versions: -"error: bitwise comparison always evaluates to false - [-Werror=tautological-compare]" - -Signed-off-by: Roy Pledge ---- - drivers/staging/fsl_qbman/qman_config.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/fsl_qbman/qman_config.c -+++ b/drivers/staging/fsl_qbman/qman_config.c -@@ -812,7 +812,7 @@ int qman_set_sdest(u16 channel, unsigned - - if (!qman_have_ccsr()) - return -ENODEV; -- if ((qman_ip_rev & 0xFF00) == QMAN_REV31) { -+ if ((qman_ip_rev & 0xFFFF) == QMAN_REV31) { - /* LS1043A - only one L2 cache */ - cpu_idx = 0; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0114-sdk_dpaa-SGMII-2500-needs-AN-disabled.patch b/target/linux/layerscape/patches-5.4/701-net-0114-sdk_dpaa-SGMII-2500-needs-AN-disabled.patch deleted file mode 100644 index b986d3517a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0114-sdk_dpaa-SGMII-2500-needs-AN-disabled.patch +++ /dev/null @@ -1,58 +0,0 @@ -From e36f12a1d319b53d5f52b91671188a74e0a1fb41 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Tue, 23 Apr 2019 16:38:19 +0300 -Subject: [PATCH] sdk_dpaa: SGMII 2500 needs AN disabled - -Signed-off-by: Madalin Bucur ---- - .../ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c | 14 ++++++++++---- - .../ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h | 1 + - 2 files changed, 11 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c -@@ -84,6 +84,7 @@ static void SetupSgmiiInternalPhy(t_Mema - { - uint16_t tmpReg16; - e_EnetMode enetMode; -+ bool autoneg_disabled = p_Memac->enetMode == e_ENET_MODE_SGMII_2500; - - /* In case the higher MACs are used (i.e. the MACs that should support 10G), - speed=10000 is provided for SGMII ports. Temporary modify enet mode -@@ -92,8 +93,9 @@ static void SetupSgmiiInternalPhy(t_Mema - - /* SGMII mode + AN enable */ - tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII; -- if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500) -- tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII; -+ /* unless SGMII 2500 where AN needs to be disabled */ -+ if (autoneg_disabled) -+ tmpReg16 = PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII; - - p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000); - MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16); -@@ -116,8 +118,12 @@ static void SetupSgmiiInternalPhy(t_Mema - MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007); - MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120); - -- /* Restart AN */ -- tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN; -+ if (!autoneg_disabled) -+ /* Restart AN */ -+ tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN; -+ else -+ /* Disable AN */ -+ tmpReg16 = PHY_SGMII_CR_DEF_VAL & ~PHY_SGMII_CR_AN_EN; - MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16); - - /* Restore original enet mode */ ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h -@@ -93,6 +93,7 @@ typedef struct - #define PHY_SGMII_CR_PHY_RESET 0x8000 - #define PHY_SGMII_CR_RESET_AN 0x0200 - #define PHY_SGMII_CR_DEF_VAL 0x1140 -+#define PHY_SGMII_CR_AN_EN 0x1000 - #define PHY_SGMII_DEV_ABILITY_SGMII 0x4001 - #define PHY_SGMII_DEV_ABILITY_1000X 0x01A0 - #define PHY_SGMII_IF_SPEED_GIGABIT 0x0008 diff --git a/target/linux/layerscape/patches-5.4/701-net-0115-sdk_qbman-Update-cpus_allowed-to-cpus_mask-to-cope-w.patch b/target/linux/layerscape/patches-5.4/701-net-0115-sdk_qbman-Update-cpus_allowed-to-cpus_mask-to-cope-w.patch deleted file mode 100644 index 900747b3f3..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0115-sdk_qbman-Update-cpus_allowed-to-cpus_mask-to-cope-w.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0bd330ec1fd657b5d04f0ab668b9fbaf7473fe8c Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Tue, 11 Jun 2019 18:51:31 -0500 -Subject: [PATCH] sdk_qbman: Update cpus_allowed to cpus_mask to cope with - upstream change - -Signed-off-by: Li Yang ---- - drivers/staging/fsl_qbman/fsl_usdpaa_irq.c | 4 ++-- - drivers/staging/fsl_qbman/qman_driver.c | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c -+++ b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c -@@ -145,11 +145,11 @@ static int map_irq(struct file *fp, stru - fput(ctx->usdpaa_filp); - return ret; - } -- ret = irq_set_affinity(ctx->irq_num, ¤t->cpus_allowed); -+ ret = irq_set_affinity(ctx->irq_num, ¤t->cpus_mask); - if (ret) - pr_err("USDPAA irq_set_affinity() failed, ret= %d\n", ret); - -- ret = irq_set_affinity_hint(ctx->irq_num, ¤t->cpus_allowed); -+ ret = irq_set_affinity_hint(ctx->irq_num, ¤t->cpus_mask); - if (ret) - pr_err("USDPAA irq_set_affinity_hint() failed, ret= %d\n", ret); - ---- a/drivers/staging/fsl_qbman/qman_driver.c -+++ b/drivers/staging/fsl_qbman/qman_driver.c -@@ -646,7 +646,7 @@ static struct qman_portal *init_pcfg(str - static void init_slave(int cpu) - { - struct qman_portal *p; -- struct cpumask oldmask = current->cpus_allowed; -+ struct cpumask oldmask = current->cpus_mask; - set_cpus_allowed_ptr(current, get_cpu_mask(cpu)); - p = qman_create_affine_slave(shared_portals[shared_portals_idx++], cpu); - if (!p) diff --git a/target/linux/layerscape/patches-5.4/701-net-0116-sdk_dpaa-ceetm-align-to-upstream-API-changes.patch b/target/linux/layerscape/patches-5.4/701-net-0116-sdk_dpaa-ceetm-align-to-upstream-API-changes.patch deleted file mode 100644 index c96a8f41ba..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0116-sdk_dpaa-ceetm-align-to-upstream-API-changes.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 17a9864b376f8ad0e19736ce53a3d7798679a0b8 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 3 Jul 2019 15:27:01 +0300 -Subject: [PATCH] sdk_dpaa: ceetm: align to upstream API changes - -Align to the following upstream patches: -8cb0817 netlink: make validation more configurable for future strictness -ae0be8d netlink: make nla_nest_start() add NLA_F_NESTED flag - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -650,7 +650,7 @@ static int ceetm_dump(struct Qdisc *sch, - return -EINVAL; - } - -- nest = nla_nest_start(skb, TCA_OPTIONS); -+ nest = nla_nest_start_noflag(skb, TCA_OPTIONS); - if (!nest) - goto nla_put_failure; - if (nla_put(skb, TCA_CEETM_QOPS, sizeof(qopt), &qopt)) -@@ -1133,7 +1133,7 @@ static int ceetm_init(struct Qdisc *sch, - if (ret) - return ret; - -- ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL); -+ ret = nla_parse_nested_deprecated(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL); - if (ret < 0) { - pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); - return ret; -@@ -1307,7 +1307,7 @@ static int ceetm_change(struct Qdisc *sc - - pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); - -- ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL); -+ ret = nla_parse_nested_deprecated(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL); - if (ret < 0) { - pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); - return ret; -@@ -1527,7 +1527,7 @@ static int ceetm_cls_change(struct Qdisc - return -EINVAL; - } - -- err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy, NULL); -+ err = nla_parse_nested_deprecated(tb, TCA_CEETM_COPT, opt, ceetm_policy, NULL); - if (err < 0) { - pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); - return -EINVAL; -@@ -1728,7 +1728,7 @@ static int ceetm_cls_dump(struct Qdisc * - break; - } - -- nest = nla_nest_start(skb, TCA_OPTIONS); -+ nest = nla_nest_start_noflag(skb, TCA_OPTIONS); - if (!nest) - goto nla_put_failure; - if (nla_put(skb, TCA_CEETM_COPT, sizeof(copt), &copt)) diff --git a/target/linux/layerscape/patches-5.4/701-net-0117-dpaa_eth-ERR010022-align-skb_shinfo.patch b/target/linux/layerscape/patches-5.4/701-net-0117-dpaa_eth-ERR010022-align-skb_shinfo.patch deleted file mode 100644 index fbf1254db3..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0117-dpaa_eth-ERR010022-align-skb_shinfo.patch +++ /dev/null @@ -1,23 +0,0 @@ -From d640266a4307a4c857b27c90d56c9161dd615bcb Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 22 Jul 2019 14:50:10 +0300 -Subject: [PATCH] dpaa_eth: ERR010022: align skb_shinfo - -Cache-line align the new skb's shared info field. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -2171,7 +2171,7 @@ static struct sk_buff *dpaa_errata_a0100 - * aligned to 256. - */ - headroom = DPAA_A010022_HEADROOM; -- nsize = headroom + skb->len + -+ nsize = ALIGN(headroom + skb->len, SMP_CACHE_BYTES) + - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - - /* Reserve enough memory to accommodate Jumbo frames */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0118-dpaa_eth-ERR010022-preserve-timestamping.patch b/target/linux/layerscape/patches-5.4/701-net-0118-dpaa_eth-ERR010022-preserve-timestamping.patch deleted file mode 100644 index cd4f6f422b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0118-dpaa_eth-ERR010022-preserve-timestamping.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 2039a9ff462d50251fd800ce4418f76230373783 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 22 Jul 2019 14:50:36 +0300 -Subject: [PATCH] dpaa_eth: ERR010022: preserve timestamping - -Maintain all timestamping fields when copying the skb. - -Signed-off-by: Camelia Groza -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -2196,6 +2196,15 @@ static struct sk_buff *dpaa_errata_a0100 - } - skb_copy_header(nskb, skb); - -+ /* Copy relevant timestamp info from the old skb to the new */ -+ if (priv->tx_tstamp) { -+ skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags; -+ skb_shinfo(nskb)->hwtstamps = skb_shinfo(skb)->hwtstamps; -+ skb_shinfo(nskb)->tskey = skb_shinfo(skb)->tskey; -+ if (skb->sk) -+ skb_set_owner_w(nskb, skb->sk); -+ } -+ - /* We move the headroom when we align it so we have to reset the - * network and transport header offsets relative to the new data - * pointer. The checksum offload relies on these offsets. diff --git a/target/linux/layerscape/patches-5.4/701-net-0119-sdk_dpaa-ceetm-update-Makefile-to-use-absolute-inclu.patch b/target/linux/layerscape/patches-5.4/701-net-0119-sdk_dpaa-ceetm-update-Makefile-to-use-absolute-inclu.patch deleted file mode 100644 index e163f99537..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0119-sdk_dpaa-ceetm-update-Makefile-to-use-absolute-inclu.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 1d862091e7b7f49eb8533c74b6f7de34d6feb56c Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 12 Aug 2019 15:58:07 +0300 -Subject: [PATCH] sdk_dpaa: ceetm: update Makefile to use absolute include - paths - -Explicitly mention the root source tree directory when building. This -allows the build process to start from a different location. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/Makefile -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile -@@ -18,7 +18,7 @@ ifeq ($(CONFIG_FSL_DPAA_1588),y) - fsl_dpa-objs += dpaa_1588.o - endif - ifeq ($(CONFIG_FSL_DPAA_CEETM),y) --ccflags-y += -Idrivers/net/ethernet/freescale/sdk_fman/src/wrapper -+ccflags-y += -I$(srctree)/drivers/net/ethernet/freescale/sdk_fman/src/wrapper - fsl_dpa-objs += dpaa_eth_ceetm.o - endif - diff --git a/target/linux/layerscape/patches-5.4/701-net-0120-sdk_dpaa-net-Rename-skb_frag_t-size-to-bv_len.patch b/target/linux/layerscape/patches-5.4/701-net-0120-sdk_dpaa-net-Rename-skb_frag_t-size-to-bv_len.patch deleted file mode 100644 index 4d22250b94..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0120-sdk_dpaa-net-Rename-skb_frag_t-size-to-bv_len.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 1af9f383a9448da530de9f681e8fccf12435aac8 Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Tue, 27 Aug 2019 19:03:59 -0500 -Subject: [PATCH] sdk_dpaa: net: Rename skb_frag_t size to bv_len - -Update for upstream data structure change similar to - -commit b8b576a16f79efbdde49348147f491b176537d88 -Author: Matthew Wilcox (Oracle) -Date: Mon Jul 22 20:08:30 2019 -0700 - - net: Rename skb_frag_t size to bv_len - -Signed-off-by: Li Yang ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -960,7 +960,7 @@ int __hot skb_to_sg_fd(struct dpa_priv_s - frag = &skb_shinfo(skb)->frags[i - 1]; - qm_sg_entry_set_bpid(&sgt[i], 0xff); - qm_sg_entry_set_offset(&sgt[i], 0); -- qm_sg_entry_set_len(&sgt[i], frag->size); -+ qm_sg_entry_set_len(&sgt[i], frag->bv_len); - qm_sg_entry_set_ext(&sgt[i], 0); - - if (i == nr_frags) -@@ -969,7 +969,7 @@ int __hot skb_to_sg_fd(struct dpa_priv_s - qm_sg_entry_set_final(&sgt[i], 0); - - DPA_BUG_ON(!skb_frag_page(frag)); -- addr = skb_frag_dma_map(dpa_bp->dev, frag, 0, frag->size, -+ addr = skb_frag_dma_map(dpa_bp->dev, frag, 0, frag->bv_len, - dma_dir); - if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) { - dev_err(dpa_bp->dev, "DMA mapping failed"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0121-dpaa_eth-Rename-skb_frag_t-size-to-bv_len.patch b/target/linux/layerscape/patches-5.4/701-net-0121-dpaa_eth-Rename-skb_frag_t-size-to-bv_len.patch deleted file mode 100644 index c9236871b9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0121-dpaa_eth-Rename-skb_frag_t-size-to-bv_len.patch +++ /dev/null @@ -1,21 +0,0 @@ -From e282d30e20d34d8d543866b662fdc16a5499a0ab Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Sat, 7 Sep 2019 18:29:45 -0500 -Subject: [PATCH] dpaa_eth: Rename skb_frag_t size to bv_len - -Signed-off-by: Li Yang ---- - drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -2141,7 +2141,7 @@ static bool dpaa_errata_a010022_has_dma_ - /* Check if a paged fragment crosses a boundary from its - * offset to its end. - */ -- if (CROSS_4K_BOUND((uintptr_t)frag->page_offset, frag->size)) -+ if (CROSS_4K_BOUND((uintptr_t)frag->page_offset, frag->bv_len)) - return true; - - i++; diff --git a/target/linux/layerscape/patches-5.4/701-net-0122-config-enable-SDK-FMan-driver.patch b/target/linux/layerscape/patches-5.4/701-net-0122-config-enable-SDK-FMan-driver.patch deleted file mode 100644 index 49cece6fb7..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0122-config-enable-SDK-FMan-driver.patch +++ /dev/null @@ -1,20 +0,0 @@ -From d6b59a9bf9d88cbfe41b96603824ffffea305b0f Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Fri, 19 May 2017 09:08:36 +0300 -Subject: [PATCH] config: enable SDK FMan driver - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/Kconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/freescale/Kconfig -+++ b/drivers/net/ethernet/freescale/Kconfig -@@ -97,6 +97,7 @@ config GIANFAR - This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx, - and MPC86xx family of chips, the eTSEC on LS1021A and the FEC - on the 8540. -+source "drivers/net/ethernet/freescale/sdk_fman/Kconfig" - - source "drivers/net/ethernet/freescale/dpaa/Kconfig" - source "drivers/net/ethernet/freescale/dpaa2/Kconfig" diff --git a/target/linux/layerscape/patches-5.4/701-net-0123-config-enable-SDK-DPAA-driver.patch b/target/linux/layerscape/patches-5.4/701-net-0123-config-enable-SDK-DPAA-driver.patch deleted file mode 100644 index 05b1aee807..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0123-config-enable-SDK-DPAA-driver.patch +++ /dev/null @@ -1,21 +0,0 @@ -From d3d61dea25b1e122353895d8154c2e5f51c11a5a Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Fri, 19 May 2017 09:30:19 +0300 -Subject: [PATCH] config: enable SDK DPAA driver - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/Kconfig -+++ b/drivers/net/ethernet/freescale/Kconfig -@@ -98,7 +98,7 @@ config GIANFAR - and MPC86xx family of chips, the eTSEC on LS1021A and the FEC - on the 8540. - source "drivers/net/ethernet/freescale/sdk_fman/Kconfig" -- -+source "drivers/net/ethernet/freescale/sdk_dpaa/Kconfig" - source "drivers/net/ethernet/freescale/dpaa/Kconfig" - source "drivers/net/ethernet/freescale/dpaa2/Kconfig" - source "drivers/net/ethernet/freescale/enetc/Kconfig" diff --git a/target/linux/layerscape/patches-5.4/701-net-0124-config-enable-SDK-QBMan.patch b/target/linux/layerscape/patches-5.4/701-net-0124-config-enable-SDK-QBMan.patch deleted file mode 100644 index 14eb62c4a1..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0124-config-enable-SDK-QBMan.patch +++ /dev/null @@ -1,21 +0,0 @@ -From b784a6d9b093b7bfd4e47a5b34aac73d1f46b476 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Fri, 19 May 2017 11:35:21 +0300 -Subject: [PATCH] config: enable SDK QBMan - -Signed-off-by: Madalin Bucur -[ Aisheng: fix minor conflcit due to removed vboxsf/Kconfig ] -Signed-off-by: Dong Aisheng ---- - drivers/staging/Kconfig | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/staging/Kconfig -+++ b/drivers/staging/Kconfig -@@ -125,4 +125,6 @@ source "drivers/staging/exfat/Kconfig" - - source "drivers/staging/qlge/Kconfig" - -+source "drivers/staging/fsl_qbman/Kconfig" -+ - endif # STAGING diff --git a/target/linux/layerscape/patches-5.4/701-net-0125-config-add-SDK-QBMan-driver.patch b/target/linux/layerscape/patches-5.4/701-net-0125-config-add-SDK-QBMan-driver.patch deleted file mode 100644 index c89ecfabde..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0125-config-add-SDK-QBMan-driver.patch +++ /dev/null @@ -1,19 +0,0 @@ -From c9c1e4d58aa598440904280e3261760fa6f0864e Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Fri, 19 May 2017 11:39:25 +0300 -Subject: [PATCH] config: add SDK QBMan driver - -Signed-off-by: Madalin Bucur -[ Aisheng: fix minor conflict due to removed CONFIG_VBOXSF_FS ] -Signed-off-by: Dong Aisheng ---- - drivers/staging/Makefile | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/staging/Makefile -+++ b/drivers/staging/Makefile -@@ -53,3 +53,4 @@ obj-$(CONFIG_UWB) += uwb/ - obj-$(CONFIG_USB_WUSB) += wusbcore/ - obj-$(CONFIG_EXFAT_FS) += exfat/ - obj-$(CONFIG_QLGE) += qlge/ -+obj-$(CONFIG_FSL_SDK_DPA) += fsl_qbman/ diff --git a/target/linux/layerscape/patches-5.4/701-net-0126-net-Makefile-re-add-DPAA-SDK-drivers.patch b/target/linux/layerscape/patches-5.4/701-net-0126-net-Makefile-re-add-DPAA-SDK-drivers.patch deleted file mode 100644 index 9aa4c463e0..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0126-net-Makefile-re-add-DPAA-SDK-drivers.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 67d8e64b7f996a6398ff3aef6834e12540d3f51f Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Fri, 30 Jun 2017 09:19:52 +0300 -Subject: [PATCH] net: Makefile: re-add DPAA SDK drivers - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/Makefile | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/net/ethernet/freescale/Makefile -+++ b/drivers/net/ethernet/freescale/Makefile -@@ -19,6 +19,9 @@ gianfar_driver-objs := gianfar.o \ - obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o - ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o - -+obj-$(if $(CONFIG_FSL_SDK_FMAN),y) += sdk_fman/ -+obj-$(if $(CONFIG_FSL_SDK_DPAA_ETH),y) += sdk_dpaa/ -+ - obj-$(CONFIG_FSL_FMAN) += fman/ - obj-$(CONFIG_FSL_DPAA_ETH) += dpaa/ - diff --git a/target/linux/layerscape/patches-5.4/701-net-0127-ptp-support-ptp_qoriq-for-sdk-dpaa.patch b/target/linux/layerscape/patches-5.4/701-net-0127-ptp-support-ptp_qoriq-for-sdk-dpaa.patch deleted file mode 100644 index 831b368ad0..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0127-ptp-support-ptp_qoriq-for-sdk-dpaa.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 46b406426b67d869176d4a4b4b321f71f28753dc Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Thu, 17 Jan 2019 14:34:51 +0800 -Subject: [PATCH] ptp: support ptp_qoriq for sdk dpaa - -The ptp_qoriq driver could be used for both sdk version -dpaa driver and upstream version dpaa driver. So added -sdk dpaa dependency for ptp_qoriq driver. - -Signed-off-by: Yangbo Lu ---- - drivers/ptp/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/ptp/Kconfig -+++ b/drivers/ptp/Kconfig -@@ -44,7 +44,7 @@ config PTP_1588_CLOCK_DTE - - config PTP_1588_CLOCK_QORIQ - tristate "Freescale QorIQ 1588 timer as PTP clock" -- depends on GIANFAR || FSL_DPAA_ETH || FSL_DPAA2_ETH || FSL_ENETC || FSL_ENETC_VF || COMPILE_TEST -+ depends on GIANFAR || FSL_DPAA_ETH || FSL_SDK_DPAA_ETH || FSL_DPAA2_ETH || FSL_ENETC || FSL_ENETC_VF || COMPILE_TEST - depends on PTP_1588_CLOCK - default y - help diff --git a/target/linux/layerscape/patches-5.4/701-net-0128-net-dpaa-fix-build-failure-due-to-skb_frag_t-struct-.patch b/target/linux/layerscape/patches-5.4/701-net-0128-net-dpaa-fix-build-failure-due-to-skb_frag_t-struct-.patch deleted file mode 100644 index 2a6ccab470..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0128-net-dpaa-fix-build-failure-due-to-skb_frag_t-struct-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From bd9aa7c077105fda307bbc685949d5bb01ed1bd8 Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Sun, 29 Sep 2019 22:38:34 +0800 -Subject: [PATCH] net: dpaa: fix build failure due to skb_frag_t struct change -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We met below build break due to new kernel change: -8842d285bafa ("net: Convert skb_frag_t to bio_vec") - -../drivers/net/ethernet/freescale/dpaa/dpaa_eth.c: In function ‘dpaa_errata_a010022_has_dma_issue’: -../drivers/net/ethernet/freescale/dpaa/dpaa_eth.c:2137:37: error: ‘skb_frag_t’ has no member named ‘page_offset’ - if (CROSS_4K_BOUND((uintptr_t)frag->page_offset, frag->bv_len)) - ^ -../drivers/net/ethernet/freescale/dpaa/dpaa_eth.c:2105:5: note: in definition of macro ‘CROSS_4K_BOUND’ - (((start) + (size)) > (((start) + 0x1000) & ~0xFFF)) - ^ -../drivers/net/ethernet/freescale/dpaa/dpaa_eth.c:2137:37: error: ‘skb_frag_t’ has no member named ‘page_offset’ - if (CROSS_4K_BOUND((uintptr_t)frag->page_offset, frag->bv_len)) - ^ -../drivers/net/ethernet/freescale/dpaa/dpaa_eth.c:2105:27: note: in definition of macro ‘CROSS_4K_BOUND’ - (((start) + (size)) > (((start) + 0x1000) & ~0xFFF)) - -Signed-off-by: Dong Aisheng ---- - drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c -@@ -2141,7 +2141,7 @@ static bool dpaa_errata_a010022_has_dma_ - /* Check if a paged fragment crosses a boundary from its - * offset to its end. - */ -- if (CROSS_4K_BOUND((uintptr_t)frag->page_offset, frag->bv_len)) -+ if (CROSS_4K_BOUND(skb_frag_off(frag), skb_frag_size(frag))) - return true; - - i++; diff --git a/target/linux/layerscape/patches-5.4/701-net-0129-sdk_dpa-align-to-upstream-PHY_INTERFACE_MODE.patch b/target/linux/layerscape/patches-5.4/701-net-0129-sdk_dpa-align-to-upstream-PHY_INTERFACE_MODE.patch deleted file mode 100644 index 171ef614b6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0129-sdk_dpa-align-to-upstream-PHY_INTERFACE_MODE.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 3343551eb8a692aafcbf1a7eaf0b79965aa60ba9 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Wed, 16 Oct 2019 11:53:54 +0300 -Subject: [PATCH] sdk_dpa: align to upstream PHY_INTERFACE_MODE - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/mac.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c -@@ -76,7 +76,7 @@ static const char phy_str[][11] = { - [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid", - [PHY_INTERFACE_MODE_RTBI] = "rtbi", - [PHY_INTERFACE_MODE_XGMII] = "xgmii", -- [PHY_INTERFACE_MODE_2500SGMII] = "sgmii-2500", -+ [PHY_INTERFACE_MODE_2500BASEX] = "sgmii-2500", - }; - - static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str) -@@ -103,7 +103,7 @@ static const uint16_t phy2speed[] = { - [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000, - [PHY_INTERFACE_MODE_RTBI] = SPEED_1000, - [PHY_INTERFACE_MODE_XGMII] = SPEED_10000, -- [PHY_INTERFACE_MODE_2500SGMII] = SPEED_2500, -+ [PHY_INTERFACE_MODE_2500BASEX] = SPEED_2500, - }; - - static struct mac_device * __cold diff --git a/target/linux/layerscape/patches-5.4/701-net-0130-bus-fsl-mc-move-fsl_mc_command-struct-in-a-uapi-head.patch b/target/linux/layerscape/patches-5.4/701-net-0130-bus-fsl-mc-move-fsl_mc_command-struct-in-a-uapi-head.patch deleted file mode 100644 index 5aa85bf51c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0130-bus-fsl-mc-move-fsl_mc_command-struct-in-a-uapi-head.patch +++ /dev/null @@ -1,86 +0,0 @@ -From c2939a719ebc7b39453f47ad2d8d30fc06ef4be6 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Tue, 13 Mar 2018 13:57:00 +0200 -Subject: [PATCH] bus: fsl-mc: move fsl_mc_command struct in a uapi header - -Define "struct fsl_mc_command" as a structure that can cross the -user/kernel boundary. - -Signed-off-by: Ioana Ciornei ---- - MAINTAINERS | 2 ++ - include/linux/fsl/mc.h | 8 +------- - include/uapi/linux/fsl_mc.h | 25 +++++++++++++++++++++++++ - 3 files changed, 28 insertions(+), 7 deletions(-) - create mode 100644 include/uapi/linux/fsl_mc.h - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -13438,6 +13438,8 @@ S: Maintained - F: drivers/bus/fsl-mc/ - F: Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt - F: Documentation/networking/device_drivers/freescale/dpaa2/overview.rst -+F: Documentation/networking/dpaa2/overview.rst -+F: include/uapi/linux/fsl_mc.h - - QT1010 MEDIA DRIVER - M: Antti Palosaari ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - - #define FSL_MC_VENDOR_FREESCALE 0x1957 - -@@ -199,8 +200,6 @@ struct fsl_mc_device { - #define to_fsl_mc_device(_dev) \ - container_of(_dev, struct fsl_mc_device, dev) - --#define MC_CMD_NUM_OF_PARAMS 7 -- - struct mc_cmd_header { - u8 src_id; - u8 flags_hw; -@@ -210,11 +209,6 @@ struct mc_cmd_header { - __le16 cmd_id; - }; - --struct fsl_mc_command { -- __le64 header; -- __le64 params[MC_CMD_NUM_OF_PARAMS]; --}; -- - enum mc_cmd_status { - MC_CMD_STATUS_OK = 0x0, /* Completed successfully */ - MC_CMD_STATUS_READY = 0x1, /* Ready to be processed */ ---- /dev/null -+++ b/include/uapi/linux/fsl_mc.h -@@ -0,0 +1,25 @@ -+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -+/* -+ * Management Complex (MC) userspace public interface -+ * -+ * Copyright 2018 NXP -+ * -+ */ -+#ifndef _UAPI_FSL_MC_H_ -+#define _UAPI_FSL_MC_H_ -+ -+#include -+ -+#define MC_CMD_NUM_OF_PARAMS 7 -+ -+/** -+ * struct fsl_mc_command - Management Complex (MC) command structure -+ * @header: MC command header -+ * @params: MC command parameters -+ */ -+struct fsl_mc_command { -+ __le64 header; -+ __le64 params[MC_CMD_NUM_OF_PARAMS]; -+}; -+ -+#endif /* _UAPI_FSL_MC_H_ */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0131-bus-fsl-mc-add-fsl-mc-userspace-support.patch b/target/linux/layerscape/patches-5.4/701-net-0131-bus-fsl-mc-add-fsl-mc-userspace-support.patch deleted file mode 100644 index 106ce0dd8e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0131-bus-fsl-mc-add-fsl-mc-userspace-support.patch +++ /dev/null @@ -1,371 +0,0 @@ -From 5b5567547d0088ec96160634c4e342bb06e52f19 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Wed, 14 Mar 2018 19:25:27 +0200 -Subject: [PATCH] bus: fsl-mc: add fsl-mc userspace support - -Adding userspace support for the MC (Management Complex) means exporting -an ioctl capable device file representing the root resource container. - -This new functionality in the fsl-mc bus driver intends to provide -userspace applications an interface to interact with the MC firmware. - -Commands that are composed in userspace are sent to the MC firmware -through the FSL_MC_SEND_MC_COMMAND ioctl. By default the implicit MC -I/O portal is used for this operation, but if the implicit one is busy, -a dynamic portal is allocated and then freed upon execution. - -Signed-off-by: Ioana Ciornei ---- - Documentation/ioctl/ioctl-number.rst | 1 + - drivers/bus/fsl-mc/Kconfig | 7 ++ - drivers/bus/fsl-mc/Makefile | 3 + - drivers/bus/fsl-mc/dprc-driver.c | 14 ++- - drivers/bus/fsl-mc/fsl-mc-private.h | 39 ++++++++ - drivers/bus/fsl-mc/fsl-mc-uapi.c | 168 +++++++++++++++++++++++++++++++++++ - include/uapi/linux/fsl_mc.h | 9 ++ - 7 files changed, 240 insertions(+), 1 deletion(-) - create mode 100644 drivers/bus/fsl-mc/fsl-mc-uapi.c - ---- a/Documentation/ioctl/ioctl-number.rst -+++ b/Documentation/ioctl/ioctl-number.rst -@@ -180,6 +180,7 @@ Code Seq# Include File - 'R' 00-1F linux/random.h conflict! - 'R' 01 linux/rfkill.h conflict! - 'R' C0-DF net/bluetooth/rfcomm.h -+'R' E0 uapi/linux/fsl_mc.h - 'S' all linux/cdrom.h conflict! - 'S' 80-81 scsi/scsi_ioctl.h conflict! - 'S' 82-FF scsi/scsi.h conflict! ---- a/drivers/bus/fsl-mc/Kconfig -+++ b/drivers/bus/fsl-mc/Kconfig -@@ -14,3 +14,10 @@ config FSL_MC_BUS - architecture. The fsl-mc bus driver handles discovery of - DPAA2 objects (which are represented as Linux devices) and - binding objects to drivers. -+ -+config FSL_MC_UAPI_SUPPORT -+ bool "Management Complex (MC) userspace support" -+ depends on FSL_MC_BUS -+ help -+ Provides userspace support for creating/destroying/configuring -+ DPAA2 objects in the Management Complex. ---- a/drivers/bus/fsl-mc/Makefile -+++ b/drivers/bus/fsl-mc/Makefile -@@ -16,3 +16,6 @@ mc-bus-driver-objs := fsl-mc-bus.o \ - fsl-mc-allocator.o \ - fsl-mc-msi.o \ - dpmcp.o -+ -+# MC userspace support -+obj-$(CONFIG_FSL_MC_UAPI_SUPPORT) += fsl-mc-uapi.o ---- a/drivers/bus/fsl-mc/dprc-driver.c -+++ b/drivers/bus/fsl-mc/dprc-driver.c -@@ -647,6 +647,12 @@ static int dprc_probe(struct fsl_mc_devi - } else { - dev_set_msi_domain(&mc_dev->dev, mc_msi_domain); - msi_domain_set = true; -+ -+ error = fsl_mc_uapi_create_device_file(mc_bus); -+ if (error < 0) { -+ error = -EPROBE_DEFER; -+ goto error_cleanup_msi_domain; -+ } - } - } - -@@ -654,7 +660,7 @@ static int dprc_probe(struct fsl_mc_devi - &mc_dev->mc_handle); - if (error < 0) { - dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error); -- goto error_cleanup_msi_domain; -+ goto error_cleanup_uapi; - } - - error = dprc_get_attributes(mc_dev->mc_io, 0, mc_dev->mc_handle, -@@ -706,6 +712,10 @@ static int dprc_probe(struct fsl_mc_devi - error_cleanup_open: - (void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle); - -+error_cleanup_uapi: -+ if (fsl_mc_is_root_dprc(&mc_dev->dev)) -+ fsl_mc_uapi_remove_device_file(mc_bus); -+ - error_cleanup_msi_domain: - if (msi_domain_set) - dev_set_msi_domain(&mc_dev->dev, NULL); -@@ -774,6 +784,8 @@ static int dprc_remove(struct fsl_mc_dev - if (!fsl_mc_is_root_dprc(&mc_dev->dev)) { - fsl_destroy_mc_io(mc_dev->mc_io); - mc_dev->mc_io = NULL; -+ } else { -+ fsl_mc_uapi_remove_device_file(mc_bus); - } - - dev_info(&mc_dev->dev, "DPRC device unbound from driver"); ---- a/drivers/bus/fsl-mc/fsl-mc-private.h -+++ b/drivers/bus/fsl-mc/fsl-mc-private.h -@@ -10,6 +10,8 @@ - - #include - #include -+#include -+#include - - /* - * Data Path Management Complex (DPMNG) General API -@@ -505,6 +507,22 @@ struct fsl_mc_resource_pool { - }; - - /** -+ * struct fsl_mc_uapi - information associated with a device file -+ * @misc: struct miscdevice linked to the root dprc -+ * @device: newly created device in /dev -+ * @mutex: mutex lock to serialize the open/release operations -+ * @local_instance_in_use: local MC I/O instance in use or not -+ * @static_mc_io: pointer to the static MC I/O object -+ */ -+struct fsl_mc_uapi { -+ struct miscdevice misc; -+ struct device *device; -+ struct mutex mutex; /* serialize open/release operations */ -+ u32 local_instance_in_use; -+ struct fsl_mc_io *static_mc_io; -+}; -+ -+/** - * struct fsl_mc_bus - logical bus that corresponds to a physical DPRC - * @mc_dev: fsl-mc device for the bus device itself. - * @resource_pools: array of resource pools (one pool per resource type) -@@ -513,6 +531,7 @@ struct fsl_mc_resource_pool { - * @irq_resources: Pointer to array of IRQ objects for the IRQ pool - * @scan_mutex: Serializes bus scanning - * @dprc_attr: DPRC attributes -+ * @uapi_misc: struct that abstracts the interaction with userspace - */ - struct fsl_mc_bus { - struct fsl_mc_device mc_dev; -@@ -520,6 +539,7 @@ struct fsl_mc_bus { - struct fsl_mc_device_irq *irq_resources; - struct mutex scan_mutex; /* serializes bus scanning */ - struct dprc_attributes dprc_attr; -+ struct fsl_mc_uapi uapi_misc; - }; - - #define to_fsl_mc_bus(_mc_dev) \ -@@ -574,4 +594,23 @@ void fsl_destroy_mc_io(struct fsl_mc_io - - bool fsl_mc_is_root_dprc(struct device *dev); - -+#ifdef CONFIG_FSL_MC_UAPI_SUPPORT -+ -+int fsl_mc_uapi_create_device_file(struct fsl_mc_bus *mc_bus); -+ -+void fsl_mc_uapi_remove_device_file(struct fsl_mc_bus *mc_bus); -+ -+#else -+ -+static inline int fsl_mc_uapi_create_device_file(struct fsl_mc_bus *mc_bus) -+{ -+ return 0; -+} -+ -+static inline void fsl_mc_uapi_remove_device_file(struct fsl_mc_bus *mc_bus) -+{ -+} -+ -+#endif -+ - #endif /* _FSL_MC_PRIVATE_H_ */ ---- /dev/null -+++ b/drivers/bus/fsl-mc/fsl-mc-uapi.c -@@ -0,0 +1,168 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Management Complex (MC) userspace support -+ * -+ * Copyright 2018 NXP -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "fsl-mc-private.h" -+ -+struct uapi_priv_data { -+ struct fsl_mc_uapi *uapi; -+ struct fsl_mc_io *mc_io; -+}; -+ -+static int fsl_mc_uapi_send_command(unsigned long arg, -+ struct fsl_mc_io *mc_io) -+{ -+ struct fsl_mc_command mc_cmd; -+ int error; -+ -+ error = copy_from_user(&mc_cmd, (void __user *)arg, sizeof(mc_cmd)); -+ if (error) -+ return -EFAULT; -+ -+ error = mc_send_command(mc_io, &mc_cmd); -+ if (error) -+ return error; -+ -+ error = copy_to_user((void __user *)arg, &mc_cmd, sizeof(mc_cmd)); -+ if (error) -+ return -EFAULT; -+ -+ return 0; -+} -+ -+static int fsl_mc_uapi_dev_open(struct inode *inode, struct file *filep) -+{ -+ struct fsl_mc_device *root_mc_device; -+ struct uapi_priv_data *priv_data; -+ struct fsl_mc_io *dynamic_mc_io; -+ struct fsl_mc_uapi *mc_uapi; -+ struct fsl_mc_bus *mc_bus; -+ int error; -+ -+ priv_data = kzalloc(sizeof(*priv_data), GFP_KERNEL); -+ if (!priv_data) -+ return -ENOMEM; -+ -+ mc_uapi = container_of(filep->private_data, struct fsl_mc_uapi, misc); -+ mc_bus = container_of(mc_uapi, struct fsl_mc_bus, uapi_misc); -+ root_mc_device = &mc_bus->mc_dev; -+ -+ mutex_lock(&mc_uapi->mutex); -+ -+ if (!mc_uapi->local_instance_in_use) { -+ priv_data->mc_io = mc_uapi->static_mc_io; -+ mc_uapi->local_instance_in_use = 1; -+ } else { -+ error = fsl_mc_portal_allocate(root_mc_device, 0, -+ &dynamic_mc_io); -+ if (error) { -+ dev_dbg(&root_mc_device->dev, -+ "Could not allocate MC portal\n"); -+ goto error_portal_allocate; -+ } -+ -+ priv_data->mc_io = dynamic_mc_io; -+ } -+ priv_data->uapi = mc_uapi; -+ filep->private_data = priv_data; -+ -+ mutex_unlock(&mc_uapi->mutex); -+ -+ return 0; -+ -+error_portal_allocate: -+ mutex_unlock(&mc_uapi->mutex); -+ -+ return error; -+} -+ -+static int fsl_mc_uapi_dev_release(struct inode *inode, struct file *filep) -+{ -+ struct uapi_priv_data *priv_data; -+ struct fsl_mc_uapi *mc_uapi; -+ struct fsl_mc_io *mc_io; -+ -+ priv_data = filep->private_data; -+ mc_uapi = priv_data->uapi; -+ mc_io = priv_data->mc_io; -+ -+ mutex_lock(&mc_uapi->mutex); -+ -+ if (mc_io == mc_uapi->static_mc_io) -+ mc_uapi->local_instance_in_use = 0; -+ else -+ fsl_mc_portal_free(mc_io); -+ -+ kfree(filep->private_data); -+ filep->private_data = NULL; -+ -+ mutex_unlock(&mc_uapi->mutex); -+ -+ return 0; -+} -+ -+static long fsl_mc_uapi_dev_ioctl(struct file *file, -+ unsigned int cmd, -+ unsigned long arg) -+{ -+ struct uapi_priv_data *priv_data = file->private_data; -+ struct fsl_mc_device *root_mc_device; -+ struct fsl_mc_bus *mc_bus; -+ int error; -+ -+ mc_bus = container_of(priv_data->uapi, struct fsl_mc_bus, uapi_misc); -+ root_mc_device = &mc_bus->mc_dev; -+ -+ switch (cmd) { -+ case FSL_MC_SEND_MC_COMMAND: -+ error = fsl_mc_uapi_send_command(arg, priv_data->mc_io); -+ break; -+ default: -+ dev_dbg(&root_mc_device->dev, "unexpected ioctl call number\n"); -+ error = -EINVAL; -+ } -+ -+ return error; -+} -+ -+static const struct file_operations fsl_mc_uapi_dev_fops = { -+ .owner = THIS_MODULE, -+ .open = fsl_mc_uapi_dev_open, -+ .release = fsl_mc_uapi_dev_release, -+ .unlocked_ioctl = fsl_mc_uapi_dev_ioctl, -+}; -+ -+int fsl_mc_uapi_create_device_file(struct fsl_mc_bus *mc_bus) -+{ -+ struct fsl_mc_device *mc_dev = &mc_bus->mc_dev; -+ struct fsl_mc_uapi *mc_uapi = &mc_bus->uapi_misc; -+ int error; -+ -+ mc_uapi->misc.minor = MISC_DYNAMIC_MINOR; -+ mc_uapi->misc.name = dev_name(&mc_dev->dev); -+ mc_uapi->misc.fops = &fsl_mc_uapi_dev_fops; -+ -+ error = misc_register(&mc_uapi->misc); -+ if (error) -+ return error; -+ -+ mc_uapi->static_mc_io = mc_bus->mc_dev.mc_io; -+ -+ mutex_init(&mc_uapi->mutex); -+ -+ return 0; -+} -+ -+void fsl_mc_uapi_remove_device_file(struct fsl_mc_bus *mc_bus) -+{ -+ misc_deregister(&mc_bus->uapi_misc.misc); -+} ---- a/include/uapi/linux/fsl_mc.h -+++ b/include/uapi/linux/fsl_mc.h -@@ -16,10 +16,19 @@ - * struct fsl_mc_command - Management Complex (MC) command structure - * @header: MC command header - * @params: MC command parameters -+ * -+ * Used by FSL_MC_SEND_MC_COMMAND - */ - struct fsl_mc_command { - __le64 header; - __le64 params[MC_CMD_NUM_OF_PARAMS]; - }; - -+#define FSL_MC_SEND_CMD_IOCTL_TYPE 'R' -+#define FSL_MC_SEND_CMD_IOCTL_SEQ 0xE0 -+ -+#define FSL_MC_SEND_MC_COMMAND \ -+ _IOWR(FSL_MC_SEND_CMD_IOCTL_TYPE, FSL_MC_SEND_CMD_IOCTL_SEQ, \ -+ struct fsl_mc_command) -+ - #endif /* _UAPI_FSL_MC_H_ */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0132-bus-fsl-mc-add-root-dprc-rescan-attribute.patch b/target/linux/layerscape/patches-5.4/701-net-0132-bus-fsl-mc-add-root-dprc-rescan-attribute.patch deleted file mode 100644 index 8fd964993e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0132-bus-fsl-mc-add-root-dprc-rescan-attribute.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 64bd4f6f266110d908e51787a81ed0bc9d325941 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Mon, 5 Mar 2018 18:37:32 +0200 -Subject: [PATCH] bus: fsl-mc: add root dprc rescan attribute - -Introduce the rescan attribute as a device attribute to -synchronize the fsl-mc bus objects and the MC firmware. - -To rescan the root dprc only, e.g. -echo 1 > /sys/bus/fsl-mc/devices/dprc.1/rescan - -Signed-off-by: Ioana Ciornei ---- - Documentation/ABI/stable/sysfs-bus-fsl-mc | 9 ++++++++ - MAINTAINERS | 1 + - drivers/bus/fsl-mc/dprc-driver.c | 36 +++++++++++++++++++++++++++++++ - 3 files changed, 46 insertions(+) - create mode 100644 Documentation/ABI/stable/sysfs-bus-fsl-mc - ---- /dev/null -+++ b/Documentation/ABI/stable/sysfs-bus-fsl-mc -@@ -0,0 +1,9 @@ -+What: /sys/bus/fsl-mc/devices/dprc.*/rescan -+Date: November 2018 -+KernelVersion: 5.0 -+Contact: Ioana Ciornei -+Description: Writing a non-zero value to this attribute will -+ force a rescan of dprc.X container in the system and -+ synchronize the objects under dprc.X and the -+ Management Complex firmware. -+Users: Userspace drivers and management tools ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -13440,6 +13440,7 @@ F: Documentation/devicetree/bindings/mis - F: Documentation/networking/device_drivers/freescale/dpaa2/overview.rst - F: Documentation/networking/dpaa2/overview.rst - F: include/uapi/linux/fsl_mc.h -+F: Documentation/ABI/stable/sysfs-bus-fsl-mc - - QT1010 MEDIA DRIVER - M: Antti Palosaari ---- a/drivers/bus/fsl-mc/dprc-driver.c -+++ b/drivers/bus/fsl-mc/dprc-driver.c -@@ -354,6 +354,33 @@ static int dprc_scan_container(struct fs - return 0; - } - -+static ssize_t rescan_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct fsl_mc_device *root_mc_dev; -+ struct fsl_mc_bus *root_mc_bus; -+ unsigned long val; -+ -+ if (!fsl_mc_is_root_dprc(dev)) -+ return -EINVAL; -+ -+ root_mc_dev = to_fsl_mc_device(dev); -+ root_mc_bus = to_fsl_mc_bus(root_mc_dev); -+ -+ if (kstrtoul(buf, 0, &val) < 0) -+ return -EINVAL; -+ -+ if (val) { -+ mutex_lock(&root_mc_bus->scan_mutex); -+ dprc_scan_objects(root_mc_dev, NULL); -+ mutex_unlock(&root_mc_bus->scan_mutex); -+ } -+ -+ return count; -+} -+static DEVICE_ATTR_WO(rescan); -+ - /** - * dprc_irq0_handler - Regular ISR for DPRC interrupt 0 - * -@@ -692,6 +719,13 @@ static int dprc_probe(struct fsl_mc_devi - - mutex_init(&mc_bus->scan_mutex); - -+ error = device_create_file(&mc_dev->dev, &dev_attr_rescan); -+ if (error < 0) { -+ dev_err(&mc_dev->dev, "device_create_file() failed: %d\n", -+ error); -+ goto error_cleanup_open; -+ } -+ - /* - * Discover MC objects in DPRC object: - */ -@@ -788,6 +822,8 @@ static int dprc_remove(struct fsl_mc_dev - fsl_mc_uapi_remove_device_file(mc_bus); - } - -+ device_remove_file(&mc_dev->dev, &dev_attr_rescan); -+ - dev_info(&mc_dev->dev, "DPRC device unbound from driver"); - return 0; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0133-bus-fsl-mc-add-bus-rescan-attribute.patch b/target/linux/layerscape/patches-5.4/701-net-0133-bus-fsl-mc-add-bus-rescan-attribute.patch deleted file mode 100644 index ea22ddb3fc..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0133-bus-fsl-mc-add-bus-rescan-attribute.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 4eba1e0209a52798e1b6a233840a28fc5132cd9c Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Mon, 5 Mar 2018 18:38:46 +0200 -Subject: [PATCH] bus: fsl-mc: add bus rescan attribute - -Introduce the rescan attribute as a bus attribute to -synchronize the fsl-mc bus objects and the MC firmware. - -To rescan the fsl-mc bus, e.g., -echo 1 > /sys/bus/fsl-mc/rescan - -Signed-off-by: Ioana Ciornei ---- - Documentation/ABI/stable/sysfs-bus-fsl-mc | 10 ++++++++ - drivers/bus/fsl-mc/dprc-driver.c | 4 +-- - drivers/bus/fsl-mc/fsl-mc-bus.c | 41 +++++++++++++++++++++++++++++++ - drivers/bus/fsl-mc/fsl-mc-private.h | 2 ++ - 4 files changed, 55 insertions(+), 2 deletions(-) - ---- a/Documentation/ABI/stable/sysfs-bus-fsl-mc -+++ b/Documentation/ABI/stable/sysfs-bus-fsl-mc -@@ -7,3 +7,13 @@ Description: Writing a non-zero value to - synchronize the objects under dprc.X and the - Management Complex firmware. - Users: Userspace drivers and management tools -+ -+What: /sys/bus/fsl-mc/rescan -+Date: November 2018 -+KernelVersion: 5.0 -+Contact: Ioana Ciornei -+Description: Writing a non-zero value to this attribute will -+ force a rescan of fsl-mc bus in the system and -+ synchronize the objects under fsl-mc bus and the -+ Management Complex firmware. -+Users: Userspace drivers and management tools ---- a/drivers/bus/fsl-mc/dprc-driver.c -+++ b/drivers/bus/fsl-mc/dprc-driver.c -@@ -214,8 +214,8 @@ static void dprc_add_new_devices(struct - * populated before they can get allocation requests from probe callbacks - * of the device drivers for the non-allocatable devices. - */ --static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, -- unsigned int *total_irq_count) -+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, -+ unsigned int *total_irq_count) - { - int num_child_objects; - int dprc_get_obj_failures; ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -154,12 +154,53 @@ static struct attribute *fsl_mc_dev_attr - - ATTRIBUTE_GROUPS(fsl_mc_dev); - -+static int scan_fsl_mc_bus(struct device *dev, void *data) -+{ -+ struct fsl_mc_device *root_mc_dev; -+ struct fsl_mc_bus *root_mc_bus; -+ -+ if (!fsl_mc_is_root_dprc(dev)) -+ goto exit; -+ -+ root_mc_dev = to_fsl_mc_device(dev); -+ root_mc_bus = to_fsl_mc_bus(root_mc_dev); -+ mutex_lock(&root_mc_bus->scan_mutex); -+ dprc_scan_objects(root_mc_dev, NULL); -+ mutex_unlock(&root_mc_bus->scan_mutex); -+ -+exit: -+ return 0; -+} -+ -+static ssize_t rescan_store(struct bus_type *bus, -+ const char *buf, size_t count) -+{ -+ unsigned long val; -+ -+ if (kstrtoul(buf, 0, &val) < 0) -+ return -EINVAL; -+ -+ if (val) -+ bus_for_each_dev(bus, NULL, NULL, scan_fsl_mc_bus); -+ -+ return count; -+} -+static BUS_ATTR_WO(rescan); -+ -+static struct attribute *fsl_mc_bus_attrs[] = { -+ &bus_attr_rescan.attr, -+ NULL, -+}; -+ -+ATTRIBUTE_GROUPS(fsl_mc_bus); -+ - struct bus_type fsl_mc_bus_type = { - .name = "fsl-mc", - .match = fsl_mc_bus_match, - .uevent = fsl_mc_bus_uevent, - .dma_configure = fsl_mc_dma_configure, - .dev_groups = fsl_mc_dev_groups, -+ .bus_groups = fsl_mc_bus_groups, - }; - EXPORT_SYMBOL_GPL(fsl_mc_bus_type); - ---- a/drivers/bus/fsl-mc/fsl-mc-private.h -+++ b/drivers/bus/fsl-mc/fsl-mc-private.h -@@ -556,6 +556,8 @@ int __init dprc_driver_init(void); - - void dprc_driver_exit(void); - -+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, -+ unsigned int *total_irq_count); - int __init fsl_mc_allocator_driver_init(void); - - void fsl_mc_allocator_driver_exit(void); diff --git a/target/linux/layerscape/patches-5.4/701-net-0134-bus-fsl-mc-Add-dprc-reset-container-support.patch b/target/linux/layerscape/patches-5.4/701-net-0134-bus-fsl-mc-Add-dprc-reset-container-support.patch deleted file mode 100644 index a609905a9e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0134-bus-fsl-mc-Add-dprc-reset-container-support.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 350201cc09a58dcf5c49f636238b01637f5ee06d Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Fri, 13 Apr 2018 11:35:10 +0300 -Subject: [PATCH] bus: fsl-mc: Add dprc-reset-container support - -DPRC-reset is required for VFIO and is missing from -mc-bus support. -This patch added reset-container support. - -Signed-off-by: Bharat Bhushan -Signed-off-by: Laurentiu Tudor ---- - drivers/bus/fsl-mc/dprc.c | 41 +++++++++++++++++++++++++++++++++++++ - drivers/bus/fsl-mc/fsl-mc-private.h | 10 +++++++++ - 2 files changed, 51 insertions(+) - ---- a/drivers/bus/fsl-mc/dprc.c -+++ b/drivers/bus/fsl-mc/dprc.c -@@ -73,6 +73,47 @@ int dprc_close(struct fsl_mc_io *mc_io, - EXPORT_SYMBOL_GPL(dprc_close); - - /** -+ * dprc_reset_container - Reset child container. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPRC object -+ * @child_container_id: ID of the container to reset -+ * -+ * In case a software context crashes or becomes non-responsive, the parent -+ * may wish to reset its resources container before the software context is -+ * restarted. -+ * -+ * This routine informs all objects assigned to the child container that the -+ * container is being reset, so they may perform any cleanup operations that are -+ * needed. All objects handles that were owned by the child container shall be -+ * closed. -+ * -+ * Note that such request may be submitted even if the child software context -+ * has not crashed, but the resulting object cleanup operations will not be -+ * aware of that. -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dprc_reset_container(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ int child_container_id) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dprc_cmd_reset_container *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_RESET_CONT, -+ cmd_flags, token); -+ cmd_params = (struct dprc_cmd_reset_container *)cmd.params; -+ cmd_params->child_container_id = cpu_to_le32(child_container_id); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+EXPORT_SYMBOL_GPL(dprc_reset_container); -+ -+/** - * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' ---- a/drivers/bus/fsl-mc/fsl-mc-private.h -+++ b/drivers/bus/fsl-mc/fsl-mc-private.h -@@ -93,6 +93,7 @@ int dpmcp_reset(struct fsl_mc_io *mc_io, - #define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05) - - #define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004) -+#define DPRC_CMDID_RESET_CONT DPRC_CMD(0x005) - - #define DPRC_CMDID_SET_IRQ DPRC_CMD(0x010) - #define DPRC_CMDID_SET_IRQ_ENABLE DPRC_CMD(0x012) -@@ -111,6 +112,10 @@ struct dprc_cmd_open { - __le32 container_id; - }; - -+struct dprc_cmd_reset_container { -+ __le32 child_container_id; -+}; -+ - struct dprc_cmd_set_irq { - /* cmd word 0 */ - __le32 irq_val; -@@ -394,6 +399,11 @@ int dprc_get_container_id(struct fsl_mc_ - u32 cmd_flags, - int *container_id); - -+int dprc_reset_container(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ int child_container_id); -+ - /* - * Data Path Buffer Pool (DPBP) API - */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0135-bus-fsl-mc-Propagate-driver_override-for-a-child-DPR.patch b/target/linux/layerscape/patches-5.4/701-net-0135-bus-fsl-mc-Propagate-driver_override-for-a-child-DPR.patch deleted file mode 100644 index b750c72664..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0135-bus-fsl-mc-Propagate-driver_override-for-a-child-DPR.patch +++ /dev/null @@ -1,196 +0,0 @@ -From ab5ad879bf30318213a717ab50944b5590bc09c1 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Fri, 13 Apr 2018 11:52:44 +0300 -Subject: [PATCH] bus: fsl-mc: Propagate driver_override for a child DPRC's - children - -When a child DPRC is bound to the vfio_fsl_mc driver via -driver_override, its own children should not be bound to corresponding -host kernel drivers, but instead should be bound to the vfio_fsl_mc -driver as well. - -Currently, when a child container is scanned by the vfio_fsl_mc -driver, child devices found are automatically bound to corresponding -host kernel drivers (e.g., DPMCP and DPBP objects are bound to the -fsl_mc_allocator driver, DPNI objects are bound to the ldpaa_eth -driver, etc), Then, the user has to manually unbind these child -devices from their drivers, set the driver_override sysfs attribute -to vfio_fsl_mc driver, for each of them and rebind them. - -Signed-off-by: J. German Rivera -Signed-off-by: Stuart Yoder -Signed-off-by: Bharat Bhushan -Signed-off-by: Laurentiu Tudor ---- - drivers/bus/fsl-mc/dprc-driver.c | 16 +++++++++++----- - drivers/bus/fsl-mc/fsl-mc-bus.c | 19 +++++++++++++++++-- - drivers/bus/fsl-mc/fsl-mc-private.h | 2 ++ - include/linux/fsl/mc.h | 2 ++ - 4 files changed, 32 insertions(+), 7 deletions(-) - ---- a/drivers/bus/fsl-mc/dprc-driver.c -+++ b/drivers/bus/fsl-mc/dprc-driver.c -@@ -156,6 +156,8 @@ static void check_plugged_state_change(s - * dprc_add_new_devices - Adds devices to the logical bus for a DPRC - * - * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object -+ * @driver_override: driver override to apply to new objects found in the -+ * DPRC, or NULL, if none. - * @obj_desc_array: array of device descriptors for child devices currently - * present in the physical DPRC. - * @num_child_objects_in_mc: number of entries in obj_desc_array -@@ -165,6 +167,7 @@ static void check_plugged_state_change(s - * in the physical DPRC. - */ - static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev, -+ const char *driver_override, - struct fsl_mc_obj_desc *obj_desc_array, - int num_child_objects_in_mc) - { -@@ -189,7 +192,7 @@ static void dprc_add_new_devices(struct - } - - error = fsl_mc_device_add(obj_desc, NULL, &mc_bus_dev->dev, -- &child_dev); -+ driver_override, &child_dev); - if (error < 0) - continue; - } -@@ -199,6 +202,8 @@ static void dprc_add_new_devices(struct - * dprc_scan_objects - Discover objects in a DPRC - * - * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object -+ * @driver_override: driver override to apply to new objects found in the -+ * DPRC, or NULL, if none. - * @total_irq_count: If argument is provided the function populates the - * total number of IRQs created by objects in the DPRC. - * -@@ -215,6 +220,7 @@ static void dprc_add_new_devices(struct - * of the device drivers for the non-allocatable devices. - */ - int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, -+ const char *driver_override, - unsigned int *total_irq_count) - { - int num_child_objects; -@@ -315,7 +321,7 @@ int dprc_scan_objects(struct fsl_mc_devi - dprc_remove_devices(mc_bus_dev, child_obj_desc_array, - num_child_objects); - -- dprc_add_new_devices(mc_bus_dev, child_obj_desc_array, -+ dprc_add_new_devices(mc_bus_dev, driver_override, child_obj_desc_array, - num_child_objects); - - if (child_obj_desc_array) -@@ -344,7 +350,7 @@ static int dprc_scan_container(struct fs - * Discover objects in the DPRC: - */ - mutex_lock(&mc_bus->scan_mutex); -- error = dprc_scan_objects(mc_bus_dev, NULL); -+ error = dprc_scan_objects(mc_bus_dev, NULL, NULL); - mutex_unlock(&mc_bus->scan_mutex); - if (error < 0) { - fsl_mc_cleanup_all_resource_pools(mc_bus_dev); -@@ -373,7 +379,7 @@ static ssize_t rescan_store(struct devic - - if (val) { - mutex_lock(&root_mc_bus->scan_mutex); -- dprc_scan_objects(root_mc_dev, NULL); -+ dprc_scan_objects(root_mc_dev, NULL, NULL); - mutex_unlock(&root_mc_bus->scan_mutex); - } - -@@ -442,7 +448,7 @@ static irqreturn_t dprc_irq0_handler_thr - DPRC_IRQ_EVENT_OBJ_CREATED)) { - unsigned int irq_count; - -- error = dprc_scan_objects(mc_dev, &irq_count); -+ error = dprc_scan_objects(mc_dev, NULL, &irq_count); - if (error < 0) { - /* - * If the error is -ENXIO, we ignore it, as it indicates ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -165,7 +165,7 @@ static int scan_fsl_mc_bus(struct device - root_mc_dev = to_fsl_mc_device(dev); - root_mc_bus = to_fsl_mc_bus(root_mc_dev); - mutex_lock(&root_mc_bus->scan_mutex); -- dprc_scan_objects(root_mc_dev, NULL); -+ dprc_scan_objects(root_mc_dev, NULL, NULL); - mutex_unlock(&root_mc_bus->scan_mutex); - - exit: -@@ -597,6 +597,7 @@ static void fsl_mc_device_release(struct - int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, - struct fsl_mc_io *mc_io, - struct device *parent_dev, -+ const char *driver_override, - struct fsl_mc_device **new_mc_dev) - { - int error; -@@ -629,6 +630,19 @@ int fsl_mc_device_add(struct fsl_mc_obj_ - - mc_dev->obj_desc = *obj_desc; - mc_dev->mc_io = mc_io; -+ -+ if (driver_override) { -+ /* -+ * We trust driver_override, so we don't need to use -+ * kstrndup() here -+ */ -+ mc_dev->driver_override = kstrdup(driver_override, GFP_KERNEL); -+ if (!mc_dev->driver_override) { -+ error = -ENOMEM; -+ goto error_cleanup_dev; -+ } -+ } -+ - device_initialize(&mc_dev->dev); - mc_dev->dev.parent = parent_dev; - mc_dev->dev.bus = &fsl_mc_bus_type; -@@ -924,7 +938,8 @@ static int fsl_mc_bus_probe(struct platf - obj_desc.irq_count = 1; - obj_desc.region_count = 0; - -- error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev); -+ error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, NULL, -+ &mc_bus_dev); - if (error < 0) - goto error_cleanup_mc_io; - ---- a/drivers/bus/fsl-mc/fsl-mc-private.h -+++ b/drivers/bus/fsl-mc/fsl-mc-private.h -@@ -558,6 +558,7 @@ struct fsl_mc_bus { - int __must_check fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, - struct fsl_mc_io *mc_io, - struct device *parent_dev, -+ const char *driver_override, - struct fsl_mc_device **new_mc_dev); - - void fsl_mc_device_remove(struct fsl_mc_device *mc_dev); -@@ -567,6 +568,7 @@ int __init dprc_driver_init(void); - void dprc_driver_exit(void); - - int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, -+ const char *driver_override, - unsigned int *total_irq_count); - int __init fsl_mc_allocator_driver_init(void); - ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -162,6 +162,7 @@ struct fsl_mc_obj_desc { - * @regions: pointer to array of MMIO region entries - * @irqs: pointer to array of pointers to interrupts allocated to this device - * @resource: generic resource associated with this MC object device, if any. -+ * @driver_override: Driver name to force a match - * - * Generic device object for MC object devices that are "attached" to a - * MC bus. -@@ -195,6 +196,7 @@ struct fsl_mc_device { - struct fsl_mc_device_irq **irqs; - struct fsl_mc_resource *resource; - struct device_link *consumer_link; -+ const char *driver_override; - }; - - #define to_fsl_mc_device(_dev) \ diff --git a/target/linux/layerscape/patches-5.4/701-net-0136-bus-fsl-mc-add-device-binding-path-driver_override.patch b/target/linux/layerscape/patches-5.4/701-net-0136-bus-fsl-mc-add-device-binding-path-driver_override.patch deleted file mode 100644 index 23a0e9b361..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0136-bus-fsl-mc-add-device-binding-path-driver_override.patch +++ /dev/null @@ -1,106 +0,0 @@ -From f2991d30ff590bf932483a6dfc16c7ebe2f83341 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Fri, 13 Apr 2018 12:42:40 +0300 -Subject: [PATCH] bus: fsl-mc: add device binding path 'driver_override' - -This patch is required for vfio-fsl-mc meta driver to successfully bind -layerscape container devices for device passthrough. This patch adds -a mechanism to allow a layerscape device to specify a driver rather than -a layerscape driver provide a device match. - -This patch is based on following proposed patches for PCI and platform -devices -- https://lkml.org/lkml/2014/4/8/571 :- For Platform devices -- http://lists-archives.com/linux-kernel/28030441-pci-introduce-new-device-binding-path-using-pci_dev-driver_override.html -:- For PCI devices - -Example to allow a device (dprc.1) to specifically bind -with driver (vfio-fsl-mc):- - - echo vfio-fsl-mc > /sys/bus/fsl-mc/devices/dprc.1/driver_override - - echo dprc.1 > /sys/bus/fsl-mc/drivers/fsl_mc_dprc/unbind - - echo dprc.1 > /sys/bus/fsl-mc/drivers/vfio-fsl-mc/bind - -Signed-off-by: Bharat Bhushan -Signed-off-by: Laurentiu Tudor ---- - drivers/bus/fsl-mc/fsl-mc-bus.c | 53 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 53 insertions(+) - ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -83,6 +83,12 @@ static int fsl_mc_bus_match(struct devic - struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv); - bool found = false; - -+ /* When driver_override is set, only bind to the matching driver */ -+ if (mc_dev->driver_override) { -+ found = !strcmp(mc_dev->driver_override, mc_drv->driver.name); -+ goto out; -+ } -+ - if (!mc_drv->match_id_table) - goto out; - -@@ -147,8 +153,52 @@ static ssize_t modalias_show(struct devi - } - static DEVICE_ATTR_RO(modalias); - -+static ssize_t driver_override_store(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); -+ const char *driver_override, *old = mc_dev->driver_override; -+ char *cp; -+ -+ if (WARN_ON(dev->bus != &fsl_mc_bus_type)) -+ return -EINVAL; -+ -+ if (count >= (PAGE_SIZE - 1)) -+ return -EINVAL; -+ -+ driver_override = kstrndup(buf, count, GFP_KERNEL); -+ if (!driver_override) -+ return -ENOMEM; -+ -+ cp = strchr(driver_override, '\n'); -+ if (cp) -+ *cp = '\0'; -+ -+ if (strlen(driver_override)) { -+ mc_dev->driver_override = driver_override; -+ } else { -+ kfree(driver_override); -+ mc_dev->driver_override = NULL; -+ } -+ -+ kfree(old); -+ -+ return count; -+} -+ -+static ssize_t driver_override_show(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); -+ -+ return snprintf(buf, PAGE_SIZE, "%s\n", mc_dev->driver_override); -+} -+static DEVICE_ATTR_RW(driver_override); -+ - static struct attribute *fsl_mc_dev_attrs[] = { - &dev_attr_modalias.attr, -+ &dev_attr_driver_override.attr, - NULL, - }; - -@@ -749,6 +799,9 @@ EXPORT_SYMBOL_GPL(fsl_mc_device_add); - */ - void fsl_mc_device_remove(struct fsl_mc_device *mc_dev) - { -+ kfree(mc_dev->driver_override); -+ mc_dev->driver_override = NULL; -+ - /* - * The device-specific remove callback will get invoked by device_del() - */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0137-bus-fsl-mc-move-fsl_mc_device_remove-to-common-heade.patch b/target/linux/layerscape/patches-5.4/701-net-0137-bus-fsl-mc-move-fsl_mc_device_remove-to-common-heade.patch deleted file mode 100644 index 81536485fe..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0137-bus-fsl-mc-move-fsl_mc_device_remove-to-common-heade.patch +++ /dev/null @@ -1,37 +0,0 @@ -From b5beccaa8629e69acbae8332e84532958e1f24cc Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Fri, 13 Apr 2018 13:25:04 +0300 -Subject: [PATCH] bus: fsl-mc: move fsl_mc_device_remove to common header - -VFIO fsl-mc driver need this function on device remove, -moving this to common header file - -Signed-off-by: Bharat Bhushan -Signed-off-by: Laurentiu Tudor ---- - drivers/bus/fsl-mc/fsl-mc-private.h | 2 -- - include/linux/fsl/mc.h | 2 ++ - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/bus/fsl-mc/fsl-mc-private.h -+++ b/drivers/bus/fsl-mc/fsl-mc-private.h -@@ -561,8 +561,6 @@ int __must_check fsl_mc_device_add(struc - const char *driver_override, - struct fsl_mc_device **new_mc_dev); - --void fsl_mc_device_remove(struct fsl_mc_device *mc_dev); -- - int __init dprc_driver_init(void); - - void dprc_driver_exit(void); ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -366,6 +366,8 @@ int mc_send_command(struct fsl_mc_io *mc - module_driver(__fsl_mc_driver, fsl_mc_driver_register, \ - fsl_mc_driver_unregister) - -+void fsl_mc_device_remove(struct fsl_mc_device *mc_dev); -+ - /* - * Macro to avoid include chaining to get THIS_MODULE - */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0138-bus-fsl-mc-increase-MC_CMD_COMPLETION_TIMEOUT_MS-val.patch b/target/linux/layerscape/patches-5.4/701-net-0138-bus-fsl-mc-increase-MC_CMD_COMPLETION_TIMEOUT_MS-val.patch deleted file mode 100644 index 2bf3b15f2e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0138-bus-fsl-mc-increase-MC_CMD_COMPLETION_TIMEOUT_MS-val.patch +++ /dev/null @@ -1,27 +0,0 @@ -From a41f550c0252dc24892b463212379c41b1e10fec Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Fri, 13 Apr 2018 13:27:31 +0300 -Subject: [PATCH] bus: fsl-mc: increase MC_CMD_COMPLETION_TIMEOUT_MS value to - 15s - -With recent MC release, a timeout of 500ms is not enough in most -circumstances. If MC firmware will respond faster, we should -decrease this value. - -Signed-off-by: Ioana Ciornei -Signed-off-by: Laurentiu Tudor ---- - drivers/bus/fsl-mc/mc-sys.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/bus/fsl-mc/mc-sys.c -+++ b/drivers/bus/fsl-mc/mc-sys.c -@@ -19,7 +19,7 @@ - /** - * Timeout in milliseconds to wait for the completion of an MC command - */ --#define MC_CMD_COMPLETION_TIMEOUT_MS 500 -+#define MC_CMD_COMPLETION_TIMEOUT_MS 15000 - - /* - * usleep_range() min and max values used to throttle down polling diff --git a/target/linux/layerscape/patches-5.4/701-net-0139-bus-fsl-mc-added-missing-fields-to-dprc_rsp_get_obj_.patch b/target/linux/layerscape/patches-5.4/701-net-0139-bus-fsl-mc-added-missing-fields-to-dprc_rsp_get_obj_.patch deleted file mode 100644 index cfadd798fd..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0139-bus-fsl-mc-added-missing-fields-to-dprc_rsp_get_obj_.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 7c72e64115a9145df5b8faf2182ef17b065261a9 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Fri, 13 Apr 2018 15:04:45 +0300 -Subject: [PATCH] bus: fsl-mc: added missing fields to dprc_rsp_get_obj_region - structure - -'type' and 'flags' fields were missing from dprc_rsp_get_obj_region -structure therefore the MC Bus driver was not receiving proper flags -from MC like DPRC_REGION_CACHEABLE. - -Signed-off-by: Cristian Sovaiala -Signed-off-by: Laurentiu Tudor ---- - drivers/bus/fsl-mc/dprc.c | 2 ++ - drivers/bus/fsl-mc/fsl-mc-private.h | 5 +++-- - 2 files changed, 5 insertions(+), 2 deletions(-) - ---- a/drivers/bus/fsl-mc/dprc.c -+++ b/drivers/bus/fsl-mc/dprc.c -@@ -524,6 +524,8 @@ int dprc_get_obj_region(struct fsl_mc_io - rsp_params = (struct dprc_rsp_get_obj_region *)cmd.params; - region_desc->base_offset = le64_to_cpu(rsp_params->base_offset); - region_desc->size = le32_to_cpu(rsp_params->size); -+ region_desc->type = rsp_params->type; -+ region_desc->flags = le32_to_cpu(rsp_params->flags); - if (major_ver > 6 || (major_ver == 6 && minor_ver >= 3)) - region_desc->base_address = le64_to_cpu(rsp_params->base_addr); - else ---- a/drivers/bus/fsl-mc/fsl-mc-private.h -+++ b/drivers/bus/fsl-mc/fsl-mc-private.h -@@ -207,12 +207,13 @@ struct dprc_cmd_get_obj_region { - - struct dprc_rsp_get_obj_region { - /* response word 0 */ -- __le64 pad; -+ __le64 pad0; - /* response word 1 */ - __le64 base_offset; - /* response word 2 */ - __le32 size; -- __le32 pad2; -+ u8 type; -+ u8 pad2[3]; - /* response word 3 */ - __le32 flags; - __le32 pad3; diff --git a/target/linux/layerscape/patches-5.4/701-net-0140-bus-fsl-mc-define-macros-for-iommu-enablement-for-fs.patch b/target/linux/layerscape/patches-5.4/701-net-0140-bus-fsl-mc-define-macros-for-iommu-enablement-for-fs.patch deleted file mode 100644 index b29ae0746e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0140-bus-fsl-mc-define-macros-for-iommu-enablement-for-fs.patch +++ /dev/null @@ -1,29 +0,0 @@ -From e6c39c2219f9d308ea57c09fc1b0b5b151b52b7d Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Mon, 16 Apr 2018 11:33:11 +0300 -Subject: [PATCH] bus: fsl-mc: define macros for iommu enablement for fsl-mc - bus - -Macros to get coherency and the container device of the devices on -fsl-mc bus are required to suport SMMU for this bus. This patch -defines the same. - -Signed-off-by: Nipun Gupta -Signed-off-by: Laurentiu Tudor ---- - include/linux/fsl/mc.h | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -356,6 +356,10 @@ int mc_send_command(struct fsl_mc_io *mc - #define fsl_mc_cont_dev(_dev) (fsl_mc_is_cont_dev(_dev) ? \ - (_dev) : (_dev)->parent) - -+#define fsl_mc_is_dev_coherent(_dev) \ -+ (!((to_fsl_mc_device(_dev))->obj_desc.flags & \ -+ FSL_MC_OBJ_FLAG_NO_MEM_SHAREABILITY)) -+ - /* - * module_fsl_mc_driver() - Helper macro for drivers that don't do - * anything special in module init/exit. This eliminates a lot of diff --git a/target/linux/layerscape/patches-5.4/701-net-0141-bus-fsl-mc-Extend-ICID-size-from-16bit-to-32bit.patch b/target/linux/layerscape/patches-5.4/701-net-0141-bus-fsl-mc-Extend-ICID-size-from-16bit-to-32bit.patch deleted file mode 100644 index c7d25f5b58..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0141-bus-fsl-mc-Extend-ICID-size-from-16bit-to-32bit.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 7c5fca3084c38905df08b8f33cf14ad21ab41b77 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Mon, 16 Apr 2018 11:54:46 +0300 -Subject: [PATCH] bus: fsl-mc: Extend ICID size from 16bit to 32bit - -Extend the ICID from 16-bit to 32-bit. -Primary reason for this is enabling DPAA2 drivers -in Virtual Machine where device-id range is defined -for DPAA2 devices is 0x10000-0x20000. - -Signed-off-by: Bharat Bhushan -Signed-off-by: Laurentiu Tudor ---- - drivers/bus/fsl-mc/dprc.c | 2 +- - drivers/bus/fsl-mc/fsl-mc-bus.c | 2 +- - drivers/bus/fsl-mc/fsl-mc-private.h | 5 ++--- - include/linux/fsl/mc.h | 2 +- - 4 files changed, 5 insertions(+), 6 deletions(-) - ---- a/drivers/bus/fsl-mc/dprc.c -+++ b/drivers/bus/fsl-mc/dprc.c -@@ -322,7 +322,7 @@ int dprc_get_attributes(struct fsl_mc_io - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_attributes *)cmd.params; - attr->container_id = le32_to_cpu(rsp_params->container_id); -- attr->icid = le16_to_cpu(rsp_params->icid); -+ attr->icid = le32_to_cpu(rsp_params->icid); - attr->options = le32_to_cpu(rsp_params->options); - attr->portal_id = le32_to_cpu(rsp_params->portal_id); - ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -489,7 +489,7 @@ common_cleanup: - } - - static int get_dprc_icid(struct fsl_mc_io *mc_io, -- int container_id, u16 *icid) -+ int container_id, u32 *icid) - { - struct dprc_attributes attr; - int error; ---- a/drivers/bus/fsl-mc/fsl-mc-private.h -+++ b/drivers/bus/fsl-mc/fsl-mc-private.h -@@ -157,8 +157,7 @@ struct dprc_cmd_clear_irq_status { - struct dprc_rsp_get_attributes { - /* response word 0 */ - __le32 container_id; -- __le16 icid; -- __le16 pad; -+ __le32 icid; - /* response word 1 */ - __le32 options; - __le32 portal_id; -@@ -320,7 +319,7 @@ int dprc_clear_irq_status(struct fsl_mc_ - */ - struct dprc_attributes { - int container_id; -- u16 icid; -+ u32 icid; - int portal_id; - u64 options; - }; ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -188,7 +188,7 @@ struct fsl_mc_device { - struct device dev; - u64 dma_mask; - u16 flags; -- u16 icid; -+ u32 icid; - u16 mc_handle; - struct fsl_mc_io *mc_io; - struct fsl_mc_obj_desc obj_desc; diff --git a/target/linux/layerscape/patches-5.4/701-net-0142-bus-fsl-mc-Some-apis-are-made-public-for-vfio.patch b/target/linux/layerscape/patches-5.4/701-net-0142-bus-fsl-mc-Some-apis-are-made-public-for-vfio.patch deleted file mode 100644 index 74d1c2a4eb..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0142-bus-fsl-mc-Some-apis-are-made-public-for-vfio.patch +++ /dev/null @@ -1,960 +0,0 @@ -From e8dd5b8ee227cc60f10073faaa0f74b36aa4f40f Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Mon, 16 Apr 2018 12:26:38 +0300 -Subject: [PATCH] bus: fsl-mc: Some apis are made public for vfio - -Some of the APIs and data-structures are required for VFIO. -This patch moves dprc.h to public header files. -Also some APIs of mc-bus are made public for vfio. - -Signed-off-by: Bharat Bhushan -Signed-off-by: Laurentiu Tudor ---- - drivers/bus/fsl-mc/fsl-mc-allocator.c | 2 + - drivers/bus/fsl-mc/fsl-mc-bus.c | 5 +- - drivers/bus/fsl-mc/fsl-mc-private.h | 414 --------------------------------- - include/linux/fsl/mc.h | 420 ++++++++++++++++++++++++++++++++++ - 4 files changed, 425 insertions(+), 416 deletions(-) - ---- a/drivers/bus/fsl-mc/fsl-mc-allocator.c -+++ b/drivers/bus/fsl-mc/fsl-mc-allocator.c -@@ -549,6 +549,7 @@ void fsl_mc_init_all_resource_pools(stru - mutex_init(&res_pool->mutex); - } - } -+EXPORT_SYMBOL_GPL(fsl_mc_init_all_resource_pools); - - static void fsl_mc_cleanup_resource_pool(struct fsl_mc_device *mc_bus_dev, - enum fsl_mc_pool_type pool_type) -@@ -573,6 +574,7 @@ void fsl_mc_cleanup_all_resource_pools(s - for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++) - fsl_mc_cleanup_resource_pool(mc_bus_dev, pool_type); - } -+EXPORT_SYMBOL_GPL(fsl_mc_cleanup_all_resource_pools); - - /** - * fsl_mc_allocator_probe - callback invoked when an allocatable device is ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -447,8 +447,8 @@ static int mc_get_version(struct fsl_mc_ - /** - * fsl_mc_get_root_dprc - function to traverse to the root dprc - */ --static void fsl_mc_get_root_dprc(struct device *dev, -- struct device **root_dprc_dev) -+void fsl_mc_get_root_dprc(struct device *dev, -+ struct device **root_dprc_dev) - { - if (!dev) { - *root_dprc_dev = NULL; -@@ -460,6 +460,7 @@ static void fsl_mc_get_root_dprc(struct - *root_dprc_dev = (*root_dprc_dev)->parent; - } - } -+EXPORT_SYMBOL_GPL(fsl_mc_get_root_dprc); - - static int get_dprc_attr(struct fsl_mc_io *mc_io, - int container_id, struct dprc_attributes *attr) ---- a/drivers/bus/fsl-mc/fsl-mc-private.h -+++ b/drivers/bus/fsl-mc/fsl-mc-private.h -@@ -10,8 +10,6 @@ - - #include - #include --#include --#include - - /* - * Data Path Management Complex (DPMNG) General API -@@ -72,339 +70,6 @@ int dpmcp_reset(struct fsl_mc_io *mc_io, - u16 token); - - /* -- * Data Path Resource Container (DPRC) API -- */ -- --/* Minimal supported DPRC Version */ --#define DPRC_MIN_VER_MAJOR 6 --#define DPRC_MIN_VER_MINOR 0 -- --/* DPRC command versioning */ --#define DPRC_CMD_BASE_VERSION 1 --#define DPRC_CMD_2ND_VERSION 2 --#define DPRC_CMD_ID_OFFSET 4 -- --#define DPRC_CMD(id) (((id) << DPRC_CMD_ID_OFFSET) | DPRC_CMD_BASE_VERSION) --#define DPRC_CMD_V2(id) (((id) << DPRC_CMD_ID_OFFSET) | DPRC_CMD_2ND_VERSION) -- --/* DPRC command IDs */ --#define DPRC_CMDID_CLOSE DPRC_CMD(0x800) --#define DPRC_CMDID_OPEN DPRC_CMD(0x805) --#define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05) -- --#define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004) --#define DPRC_CMDID_RESET_CONT DPRC_CMD(0x005) -- --#define DPRC_CMDID_SET_IRQ DPRC_CMD(0x010) --#define DPRC_CMDID_SET_IRQ_ENABLE DPRC_CMD(0x012) --#define DPRC_CMDID_SET_IRQ_MASK DPRC_CMD(0x014) --#define DPRC_CMDID_GET_IRQ_STATUS DPRC_CMD(0x016) --#define DPRC_CMDID_CLEAR_IRQ_STATUS DPRC_CMD(0x017) -- --#define DPRC_CMDID_GET_CONT_ID DPRC_CMD(0x830) --#define DPRC_CMDID_GET_OBJ_COUNT DPRC_CMD(0x159) --#define DPRC_CMDID_GET_OBJ DPRC_CMD(0x15A) --#define DPRC_CMDID_GET_OBJ_REG DPRC_CMD(0x15E) --#define DPRC_CMDID_GET_OBJ_REG_V2 DPRC_CMD_V2(0x15E) --#define DPRC_CMDID_SET_OBJ_IRQ DPRC_CMD(0x15F) -- --struct dprc_cmd_open { -- __le32 container_id; --}; -- --struct dprc_cmd_reset_container { -- __le32 child_container_id; --}; -- --struct dprc_cmd_set_irq { -- /* cmd word 0 */ -- __le32 irq_val; -- u8 irq_index; -- u8 pad[3]; -- /* cmd word 1 */ -- __le64 irq_addr; -- /* cmd word 2 */ -- __le32 irq_num; --}; -- --#define DPRC_ENABLE 0x1 -- --struct dprc_cmd_set_irq_enable { -- u8 enable; -- u8 pad[3]; -- u8 irq_index; --}; -- --struct dprc_cmd_set_irq_mask { -- __le32 mask; -- u8 irq_index; --}; -- --struct dprc_cmd_get_irq_status { -- __le32 status; -- u8 irq_index; --}; -- --struct dprc_rsp_get_irq_status { -- __le32 status; --}; -- --struct dprc_cmd_clear_irq_status { -- __le32 status; -- u8 irq_index; --}; -- --struct dprc_rsp_get_attributes { -- /* response word 0 */ -- __le32 container_id; -- __le32 icid; -- /* response word 1 */ -- __le32 options; -- __le32 portal_id; --}; -- --struct dprc_rsp_get_obj_count { -- __le32 pad; -- __le32 obj_count; --}; -- --struct dprc_cmd_get_obj { -- __le32 obj_index; --}; -- --struct dprc_rsp_get_obj { -- /* response word 0 */ -- __le32 pad0; -- __le32 id; -- /* response word 1 */ -- __le16 vendor; -- u8 irq_count; -- u8 region_count; -- __le32 state; -- /* response word 2 */ -- __le16 version_major; -- __le16 version_minor; -- __le16 flags; -- __le16 pad1; -- /* response word 3-4 */ -- u8 type[16]; -- /* response word 5-6 */ -- u8 label[16]; --}; -- --struct dprc_cmd_get_obj_region { -- /* cmd word 0 */ -- __le32 obj_id; -- __le16 pad0; -- u8 region_index; -- u8 pad1; -- /* cmd word 1-2 */ -- __le64 pad2[2]; -- /* cmd word 3-4 */ -- u8 obj_type[16]; --}; -- --struct dprc_rsp_get_obj_region { -- /* response word 0 */ -- __le64 pad0; -- /* response word 1 */ -- __le64 base_offset; -- /* response word 2 */ -- __le32 size; -- u8 type; -- u8 pad2[3]; -- /* response word 3 */ -- __le32 flags; -- __le32 pad3; -- /* response word 4 */ -- /* base_addr may be zero if older MC firmware is used */ -- __le64 base_addr; --}; -- --struct dprc_cmd_set_obj_irq { -- /* cmd word 0 */ -- __le32 irq_val; -- u8 irq_index; -- u8 pad[3]; -- /* cmd word 1 */ -- __le64 irq_addr; -- /* cmd word 2 */ -- __le32 irq_num; -- __le32 obj_id; -- /* cmd word 3-4 */ -- u8 obj_type[16]; --}; -- --/* -- * DPRC API for managing and querying DPAA resources -- */ --int dprc_open(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- int container_id, -- u16 *token); -- --int dprc_close(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token); -- --/* DPRC IRQ events */ -- --/* IRQ event - Indicates that a new object added to the container */ --#define DPRC_IRQ_EVENT_OBJ_ADDED 0x00000001 --/* IRQ event - Indicates that an object was removed from the container */ --#define DPRC_IRQ_EVENT_OBJ_REMOVED 0x00000002 --/* -- * IRQ event - Indicates that one of the descendant containers that opened by -- * this container is destroyed -- */ --#define DPRC_IRQ_EVENT_CONTAINER_DESTROYED 0x00000010 -- --/* -- * IRQ event - Indicates that on one of the container's opened object is -- * destroyed -- */ --#define DPRC_IRQ_EVENT_OBJ_DESTROYED 0x00000020 -- --/* Irq event - Indicates that object is created at the container */ --#define DPRC_IRQ_EVENT_OBJ_CREATED 0x00000040 -- --/** -- * struct dprc_irq_cfg - IRQ configuration -- * @paddr: Address that must be written to signal a message-based interrupt -- * @val: Value to write into irq_addr address -- * @irq_num: A user defined number associated with this IRQ -- */ --struct dprc_irq_cfg { -- phys_addr_t paddr; -- u32 val; -- int irq_num; --}; -- --int dprc_set_irq(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- u8 irq_index, -- struct dprc_irq_cfg *irq_cfg); -- --int dprc_set_irq_enable(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- u8 irq_index, -- u8 en); -- --int dprc_set_irq_mask(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- u8 irq_index, -- u32 mask); -- --int dprc_get_irq_status(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- u8 irq_index, -- u32 *status); -- --int dprc_clear_irq_status(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- u8 irq_index, -- u32 status); -- --/** -- * struct dprc_attributes - Container attributes -- * @container_id: Container's ID -- * @icid: Container's ICID -- * @portal_id: Container's portal ID -- * @options: Container's options as set at container's creation -- */ --struct dprc_attributes { -- int container_id; -- u32 icid; -- int portal_id; -- u64 options; --}; -- --int dprc_get_attributes(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- struct dprc_attributes *attributes); -- --int dprc_get_obj_count(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- int *obj_count); -- --int dprc_get_obj(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- int obj_index, -- struct fsl_mc_obj_desc *obj_desc); -- --int dprc_set_obj_irq(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- char *obj_type, -- int obj_id, -- u8 irq_index, -- struct dprc_irq_cfg *irq_cfg); -- --/* Region flags */ --/* Cacheable - Indicates that region should be mapped as cacheable */ --#define DPRC_REGION_CACHEABLE 0x00000001 --#define DPRC_REGION_SHAREABLE 0x00000002 -- --/** -- * enum dprc_region_type - Region type -- * @DPRC_REGION_TYPE_MC_PORTAL: MC portal region -- * @DPRC_REGION_TYPE_QBMAN_PORTAL: Qbman portal region -- */ --enum dprc_region_type { -- DPRC_REGION_TYPE_MC_PORTAL, -- DPRC_REGION_TYPE_QBMAN_PORTAL, -- DPRC_REGION_TYPE_QBMAN_MEM_BACKED_PORTAL --}; -- --/** -- * struct dprc_region_desc - Mappable region descriptor -- * @base_offset: Region offset from region's base address. -- * For DPMCP and DPRC objects, region base is offset from SoC MC portals -- * base address; For DPIO, region base is offset from SoC QMan portals -- * base address -- * @size: Region size (in bytes) -- * @flags: Region attributes -- * @type: Portal region type -- */ --struct dprc_region_desc { -- u32 base_offset; -- u32 size; -- u32 flags; -- enum dprc_region_type type; -- u64 base_address; --}; -- --int dprc_get_obj_region(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- char *obj_type, -- int obj_id, -- u8 region_index, -- struct dprc_region_desc *region_desc); -- --int dprc_get_api_version(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 *major_ver, -- u16 *minor_ver); -- --int dprc_get_container_id(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- int *container_id); -- --int dprc_reset_container(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- int child_container_id); -- --/* - * Data Path Buffer Pool (DPBP) API - */ - -@@ -491,70 +156,6 @@ struct dpcon_cmd_set_notification { - __le64 user_ctx; - }; - --/** -- * Maximum number of total IRQs that can be pre-allocated for an MC bus' -- * IRQ pool -- */ --#define FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS 256 -- --/** -- * struct fsl_mc_resource_pool - Pool of MC resources of a given -- * type -- * @type: type of resources in the pool -- * @max_count: maximum number of resources in the pool -- * @free_count: number of free resources in the pool -- * @mutex: mutex to serialize access to the pool's free list -- * @free_list: anchor node of list of free resources in the pool -- * @mc_bus: pointer to the MC bus that owns this resource pool -- */ --struct fsl_mc_resource_pool { -- enum fsl_mc_pool_type type; -- int max_count; -- int free_count; -- struct mutex mutex; /* serializes access to free_list */ -- struct list_head free_list; -- struct fsl_mc_bus *mc_bus; --}; -- --/** -- * struct fsl_mc_uapi - information associated with a device file -- * @misc: struct miscdevice linked to the root dprc -- * @device: newly created device in /dev -- * @mutex: mutex lock to serialize the open/release operations -- * @local_instance_in_use: local MC I/O instance in use or not -- * @static_mc_io: pointer to the static MC I/O object -- */ --struct fsl_mc_uapi { -- struct miscdevice misc; -- struct device *device; -- struct mutex mutex; /* serialize open/release operations */ -- u32 local_instance_in_use; -- struct fsl_mc_io *static_mc_io; --}; -- --/** -- * struct fsl_mc_bus - logical bus that corresponds to a physical DPRC -- * @mc_dev: fsl-mc device for the bus device itself. -- * @resource_pools: array of resource pools (one pool per resource type) -- * for this MC bus. These resources represent allocatable entities -- * from the physical DPRC. -- * @irq_resources: Pointer to array of IRQ objects for the IRQ pool -- * @scan_mutex: Serializes bus scanning -- * @dprc_attr: DPRC attributes -- * @uapi_misc: struct that abstracts the interaction with userspace -- */ --struct fsl_mc_bus { -- struct fsl_mc_device mc_dev; -- struct fsl_mc_resource_pool resource_pools[FSL_MC_NUM_POOL_TYPES]; -- struct fsl_mc_device_irq *irq_resources; -- struct mutex scan_mutex; /* serializes bus scanning */ -- struct dprc_attributes dprc_attr; -- struct fsl_mc_uapi uapi_misc; --}; -- --#define to_fsl_mc_bus(_mc_dev) \ -- container_of(_mc_dev, struct fsl_mc_bus, mc_dev) -- - int __must_check fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, - struct fsl_mc_io *mc_io, - struct device *parent_dev, -@@ -565,17 +166,10 @@ int __init dprc_driver_init(void); - - void dprc_driver_exit(void); - --int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, -- const char *driver_override, -- unsigned int *total_irq_count); - int __init fsl_mc_allocator_driver_init(void); - - void fsl_mc_allocator_driver_exit(void); - --void fsl_mc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev); -- --void fsl_mc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev); -- - int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus, - enum fsl_mc_pool_type pool_type, - struct fsl_mc_resource -@@ -588,14 +182,6 @@ int fsl_mc_msi_domain_alloc_irqs(struct - - void fsl_mc_msi_domain_free_irqs(struct device *dev); - --int fsl_mc_find_msi_domain(struct device *mc_platform_dev, -- struct irq_domain **mc_msi_domain); -- --int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus, -- unsigned int irq_count); -- --void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus); -- - int __must_check fsl_create_mc_io(struct device *dev, - phys_addr_t mc_portal_phys_addr, - u32 mc_portal_size, ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -12,6 +12,8 @@ - #include - #include - #include -+#include -+#include - #include - - #define FSL_MC_VENDOR_FREESCALE 0x1957 -@@ -49,6 +51,9 @@ struct fsl_mc_driver { - #define to_fsl_mc_driver(_drv) \ - container_of(_drv, struct fsl_mc_driver, driver) - -+#define to_fsl_mc_bus(_mc_dev) \ -+ container_of(_mc_dev, struct fsl_mc_bus, mc_dev) -+ - /** - * enum fsl_mc_pool_type - Types of allocatable MC bus resources - * -@@ -469,6 +474,339 @@ static inline bool is_fsl_mc_bus_dpseci( - } - - /* -+ * Data Path Resource Container (DPRC) API -+ */ -+ -+/* Minimal supported DPRC Version */ -+#define DPRC_MIN_VER_MAJOR 6 -+#define DPRC_MIN_VER_MINOR 0 -+ -+/* DPRC command versioning */ -+#define DPRC_CMD_BASE_VERSION 1 -+#define DPRC_CMD_2ND_VERSION 2 -+#define DPRC_CMD_ID_OFFSET 4 -+ -+#define DPRC_CMD(id) (((id) << DPRC_CMD_ID_OFFSET) | DPRC_CMD_BASE_VERSION) -+#define DPRC_CMD_V2(id) (((id) << DPRC_CMD_ID_OFFSET) | DPRC_CMD_2ND_VERSION) -+ -+/* DPRC command IDs */ -+#define DPRC_CMDID_CLOSE DPRC_CMD(0x800) -+#define DPRC_CMDID_OPEN DPRC_CMD(0x805) -+#define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05) -+ -+#define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004) -+#define DPRC_CMDID_RESET_CONT DPRC_CMD(0x005) -+ -+#define DPRC_CMDID_SET_IRQ DPRC_CMD(0x010) -+#define DPRC_CMDID_SET_IRQ_ENABLE DPRC_CMD(0x012) -+#define DPRC_CMDID_SET_IRQ_MASK DPRC_CMD(0x014) -+#define DPRC_CMDID_GET_IRQ_STATUS DPRC_CMD(0x016) -+#define DPRC_CMDID_CLEAR_IRQ_STATUS DPRC_CMD(0x017) -+ -+#define DPRC_CMDID_GET_CONT_ID DPRC_CMD(0x830) -+#define DPRC_CMDID_GET_OBJ_COUNT DPRC_CMD(0x159) -+#define DPRC_CMDID_GET_OBJ DPRC_CMD(0x15A) -+#define DPRC_CMDID_GET_OBJ_REG DPRC_CMD(0x15E) -+#define DPRC_CMDID_GET_OBJ_REG_V2 DPRC_CMD_V2(0x15E) -+#define DPRC_CMDID_SET_OBJ_IRQ DPRC_CMD(0x15F) -+ -+struct dprc_cmd_open { -+ __le32 container_id; -+}; -+ -+struct dprc_cmd_reset_container { -+ __le32 child_container_id; -+}; -+ -+struct dprc_cmd_set_irq { -+ /* cmd word 0 */ -+ __le32 irq_val; -+ u8 irq_index; -+ u8 pad[3]; -+ /* cmd word 1 */ -+ __le64 irq_addr; -+ /* cmd word 2 */ -+ __le32 irq_num; -+}; -+ -+#define DPRC_ENABLE 0x1 -+ -+struct dprc_cmd_set_irq_enable { -+ u8 enable; -+ u8 pad[3]; -+ u8 irq_index; -+}; -+ -+struct dprc_cmd_set_irq_mask { -+ __le32 mask; -+ u8 irq_index; -+}; -+ -+struct dprc_cmd_get_irq_status { -+ __le32 status; -+ u8 irq_index; -+}; -+ -+struct dprc_rsp_get_irq_status { -+ __le32 status; -+}; -+ -+struct dprc_cmd_clear_irq_status { -+ __le32 status; -+ u8 irq_index; -+}; -+ -+struct dprc_rsp_get_attributes { -+ /* response word 0 */ -+ __le32 container_id; -+ __le32 icid; -+ /* response word 1 */ -+ __le32 options; -+ __le32 portal_id; -+}; -+ -+struct dprc_rsp_get_obj_count { -+ __le32 pad; -+ __le32 obj_count; -+}; -+ -+struct dprc_cmd_get_obj { -+ __le32 obj_index; -+}; -+ -+struct dprc_rsp_get_obj { -+ /* response word 0 */ -+ __le32 pad0; -+ __le32 id; -+ /* response word 1 */ -+ __le16 vendor; -+ u8 irq_count; -+ u8 region_count; -+ __le32 state; -+ /* response word 2 */ -+ __le16 version_major; -+ __le16 version_minor; -+ __le16 flags; -+ __le16 pad1; -+ /* response word 3-4 */ -+ u8 type[16]; -+ /* response word 5-6 */ -+ u8 label[16]; -+}; -+ -+struct dprc_cmd_get_obj_region { -+ /* cmd word 0 */ -+ __le32 obj_id; -+ __le16 pad0; -+ u8 region_index; -+ u8 pad1; -+ /* cmd word 1-2 */ -+ __le64 pad2[2]; -+ /* cmd word 3-4 */ -+ u8 obj_type[16]; -+}; -+ -+struct dprc_rsp_get_obj_region { -+ /* response word 0 */ -+ __le64 pad0; -+ /* response word 1 */ -+ __le64 base_offset; -+ /* response word 2 */ -+ __le32 size; -+ u8 type; -+ u8 pad2[3]; -+ /* response word 3 */ -+ __le32 flags; -+ __le32 pad3; -+ /* response word 4 */ -+ /* base_addr may be zero if older MC firmware is used */ -+ __le64 base_addr; -+}; -+ -+struct dprc_cmd_set_obj_irq { -+ /* cmd word 0 */ -+ __le32 irq_val; -+ u8 irq_index; -+ u8 pad[3]; -+ /* cmd word 1 */ -+ __le64 irq_addr; -+ /* cmd word 2 */ -+ __le32 irq_num; -+ __le32 obj_id; -+ /* cmd word 3-4 */ -+ u8 obj_type[16]; -+}; -+ -+/* -+ * DPRC API for managing and querying DPAA resources -+ */ -+int dprc_open(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ int container_id, -+ u16 *token); -+ -+int dprc_close(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token); -+ -+/* DPRC IRQ events */ -+ -+/* IRQ event - Indicates that a new object added to the container */ -+#define DPRC_IRQ_EVENT_OBJ_ADDED 0x00000001 -+/* IRQ event - Indicates that an object was removed from the container */ -+#define DPRC_IRQ_EVENT_OBJ_REMOVED 0x00000002 -+/* -+ * IRQ event - Indicates that one of the descendant containers that opened by -+ * this container is destroyed -+ */ -+#define DPRC_IRQ_EVENT_CONTAINER_DESTROYED 0x00000010 -+ -+/* -+ * IRQ event - Indicates that on one of the container's opened object is -+ * destroyed -+ */ -+#define DPRC_IRQ_EVENT_OBJ_DESTROYED 0x00000020 -+ -+/* Irq event - Indicates that object is created at the container */ -+#define DPRC_IRQ_EVENT_OBJ_CREATED 0x00000040 -+ -+/** -+ * struct dprc_irq_cfg - IRQ configuration -+ * @paddr: Address that must be written to signal a message-based interrupt -+ * @val: Value to write into irq_addr address -+ * @irq_num: A user defined number associated with this IRQ -+ */ -+struct dprc_irq_cfg { -+ phys_addr_t paddr; -+ u32 val; -+ int irq_num; -+}; -+ -+int dprc_set_irq(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ struct dprc_irq_cfg *irq_cfg); -+ -+int dprc_set_irq_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u8 en); -+ -+int dprc_set_irq_mask(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 mask); -+ -+int dprc_get_irq_status(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 *status); -+ -+int dprc_clear_irq_status(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 status); -+ -+/** -+ * struct dprc_attributes - Container attributes -+ * @container_id: Container's ID -+ * @icid: Container's ICID -+ * @portal_id: Container's portal ID -+ * @options: Container's options as set at container's creation -+ */ -+struct dprc_attributes { -+ int container_id; -+ u32 icid; -+ int portal_id; -+ u64 options; -+}; -+ -+int dprc_get_attributes(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dprc_attributes *attributes); -+ -+int dprc_get_obj_count(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ int *obj_count); -+ -+int dprc_get_obj(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ int obj_index, -+ struct fsl_mc_obj_desc *obj_desc); -+ -+int dprc_set_obj_irq(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ char *obj_type, -+ int obj_id, -+ u8 irq_index, -+ struct dprc_irq_cfg *irq_cfg); -+ -+/* Region flags */ -+/* Cacheable - Indicates that region should be mapped as cacheable */ -+#define DPRC_REGION_CACHEABLE 0x00000001 -+#define DPRC_REGION_SHAREABLE 0x00000002 -+ -+/** -+ * enum dprc_region_type - Region type -+ * @DPRC_REGION_TYPE_MC_PORTAL: MC portal region -+ * @DPRC_REGION_TYPE_QBMAN_PORTAL: Qbman portal region -+ */ -+enum dprc_region_type { -+ DPRC_REGION_TYPE_MC_PORTAL, -+ DPRC_REGION_TYPE_QBMAN_PORTAL, -+ DPRC_REGION_TYPE_QBMAN_MEM_BACKED_PORTAL -+}; -+ -+/** -+ * struct dprc_region_desc - Mappable region descriptor -+ * @base_offset: Region offset from region's base address. -+ * For DPMCP and DPRC objects, region base is offset from SoC MC portals -+ * base address; For DPIO, region base is offset from SoC QMan portals -+ * base address -+ * @size: Region size (in bytes) -+ * @flags: Region attributes -+ * @type: Portal region type -+ */ -+struct dprc_region_desc { -+ u32 base_offset; -+ u32 size; -+ u32 flags; -+ enum dprc_region_type type; -+ u64 base_address; -+}; -+ -+int dprc_get_obj_region(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ char *obj_type, -+ int obj_id, -+ u8 region_index, -+ struct dprc_region_desc *region_desc); -+ -+int dprc_get_api_version(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 *major_ver, -+ u16 *minor_ver); -+ -+int dprc_get_container_id(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ int *container_id); -+ -+int dprc_reset_container(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ int child_container_id); -+ -+/* - * Data Path Buffer Pool (DPBP) API - * Contains initialization APIs and runtime control APIs for DPBP - */ -@@ -576,4 +914,86 @@ int dpcon_set_notification(struct fsl_mc - u16 token, - struct dpcon_notification_cfg *cfg); - -+struct irq_domain; -+struct msi_domain_info; -+ -+/** -+ * Maximum number of total IRQs that can be pre-allocated for an MC bus' -+ * IRQ pool -+ */ -+#define FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS 256 -+ -+/** -+ * struct fsl_mc_resource_pool - Pool of MC resources of a given -+ * type -+ * @type: type of resources in the pool -+ * @max_count: maximum number of resources in the pool -+ * @free_count: number of free resources in the pool -+ * @mutex: mutex to serialize access to the pool's free list -+ * @free_list: anchor node of list of free resources in the pool -+ * @mc_bus: pointer to the MC bus that owns this resource pool -+ */ -+struct fsl_mc_resource_pool { -+ enum fsl_mc_pool_type type; -+ int max_count; -+ int free_count; -+ struct mutex mutex; /* serializes access to free_list */ -+ struct list_head free_list; -+ struct fsl_mc_bus *mc_bus; -+}; -+ -+/** -+ * struct fsl_mc_uapi - information associated with a device file -+ * @misc: struct miscdevice linked to the root dprc -+ * @device: newly created device in /dev -+ * @mutex: mutex lock to serialize the open/release operations -+ * @local_instance_in_use: local MC I/O instance in use or not -+ * @static_mc_io: pointer to the static MC I/O object -+ */ -+struct fsl_mc_uapi { -+ struct miscdevice misc; -+ struct device *device; -+ struct mutex mutex; /* serialize open/release operations */ -+ u32 local_instance_in_use; -+ struct fsl_mc_io *static_mc_io; -+}; -+ -+/** -+ * struct fsl_mc_bus - logical bus that corresponds to a physical DPRC -+ * @mc_dev: fsl-mc device for the bus device itself. -+ * @resource_pools: array of resource pools (one pool per resource type) -+ * for this MC bus. These resources represent allocatable entities -+ * from the physical DPRC. -+ * @irq_resources: Pointer to array of IRQ objects for the IRQ pool -+ * @scan_mutex: Serializes bus scanning -+ * @dprc_attr: DPRC attributes -+ * @uapi_misc: struct that abstracts the interaction with userspace -+ */ -+struct fsl_mc_bus { -+ struct fsl_mc_device mc_dev; -+ struct fsl_mc_resource_pool resource_pools[FSL_MC_NUM_POOL_TYPES]; -+ struct fsl_mc_device_irq *irq_resources; -+ struct mutex scan_mutex; /* serializes bus scanning */ -+ struct dprc_attributes dprc_attr; -+ struct fsl_mc_uapi uapi_misc; -+}; -+ -+int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, -+ const char *driver_override, -+ unsigned int *total_irq_count); -+ -+int fsl_mc_find_msi_domain(struct device *mc_platform_dev, -+ struct irq_domain **mc_msi_domain); -+ -+int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus, -+ unsigned int irq_count); -+ -+void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus); -+ -+void fsl_mc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev); -+ -+void fsl_mc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev); -+ -+void fsl_mc_get_root_dprc(struct device *dev, struct device **root_dprc_dev); -+ - #endif /* _FSL_MC_H_ */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0143-bus-fsl-mc-add-support-for-dpdmux-device-type.patch b/target/linux/layerscape/patches-5.4/701-net-0143-bus-fsl-mc-add-support-for-dpdmux-device-type.patch deleted file mode 100644 index d5cf3c5b7d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0143-bus-fsl-mc-add-support-for-dpdmux-device-type.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 5b4e5d281abfa29cf3808b4a3a3ab994f80d6cca Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Tue, 24 Apr 2018 14:51:56 +0300 -Subject: [PATCH] bus: fsl-mc: add support for dpdmux device type - -Signed-off-by: Razvan Stefanescu ---- - drivers/bus/fsl-mc/fsl-mc-bus.c | 5 +++++ - include/linux/fsl/mc.h | 6 ++++++ - 2 files changed, 11 insertions(+) - ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -270,6 +270,10 @@ struct device_type fsl_mc_bus_dpsw_type - .name = "fsl_mc_bus_dpsw" - }; - -+struct device_type fsl_mc_bus_dpdmux_type = { -+ .name = "fsl_mc_bus_dpdmux" -+}; -+ - struct device_type fsl_mc_bus_dpbp_type = { - .name = "fsl_mc_bus_dpbp" - }; -@@ -304,6 +308,7 @@ static struct device_type *fsl_mc_get_de - { &fsl_mc_bus_dpni_type, "dpni" }, - { &fsl_mc_bus_dpio_type, "dpio" }, - { &fsl_mc_bus_dpsw_type, "dpsw" }, -+ { &fsl_mc_bus_dpdmux_type, "dpdmux" }, - { &fsl_mc_bus_dpbp_type, "dpbp" }, - { &fsl_mc_bus_dpcon_type, "dpcon" }, - { &fsl_mc_bus_dpmcp_type, "dpmcp" }, ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -416,6 +416,7 @@ extern struct device_type fsl_mc_bus_dpr - extern struct device_type fsl_mc_bus_dpni_type; - extern struct device_type fsl_mc_bus_dpio_type; - extern struct device_type fsl_mc_bus_dpsw_type; -+extern struct device_type fsl_mc_bus_dpdmux_type; - extern struct device_type fsl_mc_bus_dpbp_type; - extern struct device_type fsl_mc_bus_dpcon_type; - extern struct device_type fsl_mc_bus_dpmcp_type; -@@ -443,6 +444,11 @@ static inline bool is_fsl_mc_bus_dpsw(co - return mc_dev->dev.type == &fsl_mc_bus_dpsw_type; - } - -+static inline bool is_fsl_mc_bus_dpdmux(const struct fsl_mc_device *mc_dev) -+{ -+ return mc_dev->dev.type == &fsl_mc_bus_dpdmux_type; -+} -+ - static inline bool is_fsl_mc_bus_dpbp(const struct fsl_mc_device *mc_dev) - { - return mc_dev->dev.type == &fsl_mc_bus_dpbp_type; diff --git a/target/linux/layerscape/patches-5.4/701-net-0144-bus-fsl-mc-add-support-for-dpdcei-device-type.patch b/target/linux/layerscape/patches-5.4/701-net-0144-bus-fsl-mc-add-support-for-dpdcei-device-type.patch deleted file mode 100644 index 0ab2421c47..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0144-bus-fsl-mc-add-support-for-dpdcei-device-type.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 6de672cdae08f6dbd94c115481f3472a7af50c19 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Wed, 25 Apr 2018 13:35:16 +0300 -Subject: [PATCH] bus: fsl-mc: add support for dpdcei device type - -Signed-off-by: Ioana Ciornei ---- - drivers/bus/fsl-mc/fsl-mc-bus.c | 5 +++++ - include/linux/fsl/mc.h | 6 ++++++ - 2 files changed, 11 insertions(+) - ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -298,6 +298,10 @@ struct device_type fsl_mc_bus_dpseci_typ - .name = "fsl_mc_bus_dpseci" - }; - -+struct device_type fsl_mc_bus_dpdcei_type = { -+ .name = "fsl_mc_bus_dpdcei" -+}; -+ - static struct device_type *fsl_mc_get_device_type(const char *type) - { - static const struct { -@@ -315,6 +319,7 @@ static struct device_type *fsl_mc_get_de - { &fsl_mc_bus_dpmac_type, "dpmac" }, - { &fsl_mc_bus_dprtc_type, "dprtc" }, - { &fsl_mc_bus_dpseci_type, "dpseci" }, -+ { &fsl_mc_bus_dpdcei_type, "dpdcei" }, - { NULL, NULL } - }; - int i; ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -423,6 +423,7 @@ extern struct device_type fsl_mc_bus_dpm - extern struct device_type fsl_mc_bus_dpmac_type; - extern struct device_type fsl_mc_bus_dprtc_type; - extern struct device_type fsl_mc_bus_dpseci_type; -+extern struct device_type fsl_mc_bus_dpdcei_type; - - static inline bool is_fsl_mc_bus_dprc(const struct fsl_mc_device *mc_dev) - { -@@ -479,6 +480,11 @@ static inline bool is_fsl_mc_bus_dpseci( - return mc_dev->dev.type == &fsl_mc_bus_dpseci_type; - } - -+static inline bool is_fsl_mc_bus_dpdcei(const struct fsl_mc_device *mc_dev) -+{ -+ return mc_dev->dev.type == &fsl_mc_bus_dpdcei_type; -+} -+ - /* - * Data Path Resource Container (DPRC) API - */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0145-bus-fsl-mc-add-support-for-dpaiop-dpci-and-dpdmai-de.patch b/target/linux/layerscape/patches-5.4/701-net-0145-bus-fsl-mc-add-support-for-dpaiop-dpci-and-dpdmai-de.patch deleted file mode 100644 index c57d16e496..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0145-bus-fsl-mc-add-support-for-dpaiop-dpci-and-dpdmai-de.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 0b8b5f7ff79b83ccfcb82fe0f571ddd77f577d19 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Thu, 3 May 2018 15:37:04 +0300 -Subject: [PATCH] bus: fsl-mc: add support for dpaiop, dpci and dpdmai device - type - -Signed-off-by: Ioana Ciornei ---- - drivers/bus/fsl-mc/fsl-mc-bus.c | 15 +++++++++++++++ - include/linux/fsl/mc.h | 18 ++++++++++++++++++ - 2 files changed, 33 insertions(+) - ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -302,6 +302,18 @@ struct device_type fsl_mc_bus_dpdcei_typ - .name = "fsl_mc_bus_dpdcei" - }; - -+struct device_type fsl_mc_bus_dpaiop_type = { -+ .name = "fsl_mc_bus_dpaiop" -+}; -+ -+struct device_type fsl_mc_bus_dpci_type = { -+ .name = "fsl_mc_bus_dpci" -+}; -+ -+struct device_type fsl_mc_bus_dpdmai_type = { -+ .name = "fsl_mc_bus_dpdmai" -+}; -+ - static struct device_type *fsl_mc_get_device_type(const char *type) - { - static const struct { -@@ -320,6 +332,9 @@ static struct device_type *fsl_mc_get_de - { &fsl_mc_bus_dprtc_type, "dprtc" }, - { &fsl_mc_bus_dpseci_type, "dpseci" }, - { &fsl_mc_bus_dpdcei_type, "dpdcei" }, -+ { &fsl_mc_bus_dpaiop_type, "dpaiop" }, -+ { &fsl_mc_bus_dpci_type, "dpci" }, -+ { &fsl_mc_bus_dpdmai_type, "dpdmai" }, - { NULL, NULL } - }; - int i; ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -424,6 +424,9 @@ extern struct device_type fsl_mc_bus_dpm - extern struct device_type fsl_mc_bus_dprtc_type; - extern struct device_type fsl_mc_bus_dpseci_type; - extern struct device_type fsl_mc_bus_dpdcei_type; -+extern struct device_type fsl_mc_bus_dpaiop_type; -+extern struct device_type fsl_mc_bus_dpci_type; -+extern struct device_type fsl_mc_bus_dpdmai_type; - - static inline bool is_fsl_mc_bus_dprc(const struct fsl_mc_device *mc_dev) - { -@@ -485,6 +488,21 @@ static inline bool is_fsl_mc_bus_dpdcei( - return mc_dev->dev.type == &fsl_mc_bus_dpdcei_type; - } - -+static inline bool is_fsl_mc_bus_dpaiop(const struct fsl_mc_device *mc_dev) -+{ -+ return mc_dev->dev.type == &fsl_mc_bus_dpaiop_type; -+} -+ -+static inline bool is_fsl_mc_bus_dpci(const struct fsl_mc_device *mc_dev) -+{ -+ return mc_dev->dev.type == &fsl_mc_bus_dpci_type; -+} -+ -+static inline bool is_fsl_mc_bus_dpdmai(const struct fsl_mc_device *mc_dev) -+{ -+ return mc_dev->dev.type == &fsl_mc_bus_dpdmai_type; -+} -+ - /* - * Data Path Resource Container (DPRC) API - */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0146-bus-fsl-mc-DMA-configure-to-have-force-dma-as-defaul.patch b/target/linux/layerscape/patches-5.4/701-net-0146-bus-fsl-mc-DMA-configure-to-have-force-dma-as-defaul.patch deleted file mode 100644 index c0a4d019a5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0146-bus-fsl-mc-DMA-configure-to-have-force-dma-as-defaul.patch +++ /dev/null @@ -1,27 +0,0 @@ -From b6b91c9f49f8459eab973aa3b52b4e8a3a00daa1 Mon Sep 17 00:00:00 2001 -From: Bharat Bhushan -Date: Mon, 27 Aug 2018 13:22:34 +0530 -Subject: [PATCH] bus: fsl-mc: DMA configure to have force-dma as default - -Implicit dma setting from bus works when dma-ranges -specified but not otherwise. We need to continue -to go for force_dma as default for cases dma-ranges not -specified. Example dynamic device tree generation for -generic kvm virtual machines. - -Signed-off-by: Bharat Bhushan ---- - drivers/bus/fsl-mc/fsl-mc-bus.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -140,7 +140,7 @@ static int fsl_mc_dma_configure(struct d - while (dev_is_fsl_mc(dma_dev)) - dma_dev = dma_dev->parent; - -- return of_dma_configure(dev, dma_dev->of_node, 0); -+ return of_dma_configure(dev, dma_dev->of_node, 1); - } - - static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, diff --git a/target/linux/layerscape/patches-5.4/701-net-0147-bus-fsl-mc-Allocate-mc-portal-from-root-dprc-contain.patch b/target/linux/layerscape/patches-5.4/701-net-0147-bus-fsl-mc-Allocate-mc-portal-from-root-dprc-contain.patch deleted file mode 100644 index 8fd2bb2738..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0147-bus-fsl-mc-Allocate-mc-portal-from-root-dprc-contain.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 703972946a42cf1f83bf50cf389d618d61b69500 Mon Sep 17 00:00:00 2001 -From: Bharat Bhushan -Date: Mon, 10 Dec 2018 14:42:51 +0530 -Subject: [PATCH] bus: fsl-mc: Allocate mc-portal from root dprc container - -Root dprc container have allocate-able mc-portals which -can be allocated by kernel drivers. - -As per current design mc-portal is allocated from parent -dprc container if requesting device is not root-dprc. -This works fine if the requesting device is child of -root dprc container, because their parent is root-dprc -container. But if request device is grandchild of root -dprc container then it tries to allocate from it's parent -root dprc-container and it fails. - -Signed-off-by: Ioana Ciornei -Signed-off-by: Bharat Bhushan ---- - drivers/bus/fsl-mc/mc-io.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - ---- a/drivers/bus/fsl-mc/mc-io.c -+++ b/drivers/bus/fsl-mc/mc-io.c -@@ -174,14 +174,16 @@ int __must_check fsl_mc_portal_allocate( - int error = -EINVAL; - struct fsl_mc_resource *resource = NULL; - struct fsl_mc_io *mc_io = NULL; -+ struct device *root_dprc_dev; - -- if (mc_dev->flags & FSL_MC_IS_DPRC) { -+ if (fsl_mc_is_root_dprc(&mc_dev->dev)) { - mc_bus_dev = mc_dev; - } else { -- if (!dev_is_fsl_mc(mc_dev->dev.parent)) -- return error; -+ fsl_mc_get_root_dprc(&mc_dev->dev, &root_dprc_dev); -+ if (WARN_ON(!root_dprc_dev)) -+ return -EINVAL; - -- mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); -+ mc_bus_dev = to_fsl_mc_device(root_dprc_dev); - } - - mc_bus = to_fsl_mc_bus(mc_bus_dev); diff --git a/target/linux/layerscape/patches-5.4/701-net-0148-bus-fsl-mc-use-raw-spin-lock-to-serialize-mc-cmds.patch b/target/linux/layerscape/patches-5.4/701-net-0148-bus-fsl-mc-use-raw-spin-lock-to-serialize-mc-cmds.patch deleted file mode 100644 index 42934e2245..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0148-bus-fsl-mc-use-raw-spin-lock-to-serialize-mc-cmds.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 035546179039d430b32b2cace256552455abf061 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Thu, 29 Aug 2019 11:39:45 +0300 -Subject: [PATCH] bus: fsl-mc: use raw spin lock to serialize mc cmds - -Replace the spinlock that serializes the MC commands with a raw -spinlock. This is needed for the RT kernel because there are MC -commands sent in interrupt context. - -Signed-off-by: Laurentiu Tudor ---- - drivers/bus/fsl-mc/mc-io.c | 2 +- - drivers/bus/fsl-mc/mc-sys.c | 4 ++-- - include/linux/fsl/mc.h | 2 +- - 3 files changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/bus/fsl-mc/mc-io.c -+++ b/drivers/bus/fsl-mc/mc-io.c -@@ -82,7 +82,7 @@ int __must_check fsl_create_mc_io(struct - mc_io->portal_phys_addr = mc_portal_phys_addr; - mc_io->portal_size = mc_portal_size; - if (flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL) -- spin_lock_init(&mc_io->spinlock); -+ raw_spin_lock_init(&mc_io->spinlock); - else - mutex_init(&mc_io->mutex); - ---- a/drivers/bus/fsl-mc/mc-sys.c -+++ b/drivers/bus/fsl-mc/mc-sys.c -@@ -251,7 +251,7 @@ int mc_send_command(struct fsl_mc_io *mc - return -EINVAL; - - if (mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL) -- spin_lock_irqsave(&mc_io->spinlock, irq_flags); -+ raw_spin_lock_irqsave(&mc_io->spinlock, irq_flags); - else - mutex_lock(&mc_io->mutex); - -@@ -287,7 +287,7 @@ int mc_send_command(struct fsl_mc_io *mc - error = 0; - common_exit: - if (mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL) -- spin_unlock_irqrestore(&mc_io->spinlock, irq_flags); -+ raw_spin_unlock_irqrestore(&mc_io->spinlock, irq_flags); - else - mutex_unlock(&mc_io->mutex); - ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -340,7 +340,7 @@ struct fsl_mc_io { - * This field is only meaningful if the - * FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag is set - */ -- spinlock_t spinlock; /* serializes mc_send_command() */ -+ raw_spinlock_t spinlock; /* serializes mc_send_command() */ - }; - }; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0149-soc-fsl-dpio-change-CENA-regs-to-be-cacheable.patch b/target/linux/layerscape/patches-5.4/701-net-0149-soc-fsl-dpio-change-CENA-regs-to-be-cacheable.patch deleted file mode 100644 index eba8a12007..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0149-soc-fsl-dpio-change-CENA-regs-to-be-cacheable.patch +++ /dev/null @@ -1,61 +0,0 @@ -From e2b0ebb44e91e3492f26d21218fb7ea5e14190ec Mon Sep 17 00:00:00 2001 -From: Haiying Wang -Date: Thu, 20 Apr 2017 11:54:22 -0400 -Subject: [PATCH] soc: fsl: dpio: change CENA regs to be cacheable - -Change cache enabled regsiter accessed to be cacheable -plus non-shareable to meet the performance requirement. -QMan's CENA region contains registers and structures that -are 64byte in size and are inteneded to be accessed using a -single 64 byte bus transaction, therefore this portal -memory should be configured as cache-enabled. Also because -the write allocate stash transcations of QBMan should be -issued as cachable and non-coherent(non-sharable), we -need to configure this region to be non-shareable. - -Signed-off-by: Haiying Wang ---- - drivers/soc/fsl/dpio/dpio-driver.c | 17 ++++++++++------- - 1 file changed, 10 insertions(+), 7 deletions(-) - ---- a/drivers/soc/fsl/dpio/dpio-driver.c -+++ b/drivers/soc/fsl/dpio/dpio-driver.c -@@ -27,6 +27,11 @@ MODULE_LICENSE("Dual BSD/GPL"); - MODULE_AUTHOR("Freescale Semiconductor, Inc"); - MODULE_DESCRIPTION("DPIO Driver"); - -+#define PROT_NORMAL_NS (PTE_TYPE_PAGE | PTE_AF | PTE_PXN | PTE_UXN | PTE_DIRTY | PTE_WRITE | PTE_ATTRINDX(MT_NORMAL)) -+ -+#define ioremap_cache_ns(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NS)) -+ -+ - struct dpio_priv { - struct dpaa2_io *io; - }; -@@ -197,13 +202,11 @@ static int dpaa2_dpio_probe(struct fsl_m - if (dpio_dev->obj_desc.region_count < 3) { - /* No support for DDR backed portals, use classic mapping */ - /* -- * Set the CENA regs to be the cache inhibited area of the -- * portal to avoid coherency issues if a user migrates to -- * another core. -+ * Set the CENA regs to be the cache enabled area of the portal to -+ * achieve the best performance. - */ -- desc.regs_cena = devm_memremap(dev, dpio_dev->regions[1].start, -- resource_size(&dpio_dev->regions[1]), -- MEMREMAP_WC); -+ desc.regs_cena = ioremap_cache_ns(dpio_dev->regions[0].start, -+ resource_size(&dpio_dev->regions[0])); - } else { - desc.regs_cena = devm_memremap(dev, dpio_dev->regions[2].start, - resource_size(&dpio_dev->regions[2]), -@@ -211,7 +214,7 @@ static int dpaa2_dpio_probe(struct fsl_m - } - - if (IS_ERR(desc.regs_cena)) { -- dev_err(dev, "devm_memremap failed\n"); -+ dev_err(dev, "ioremap_cache_ns failed\n"); - err = PTR_ERR(desc.regs_cena); - goto err_allocate_irqs; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0150-soc-fsl-dpio-enable-qbman-CENA-portal-memory-access.patch b/target/linux/layerscape/patches-5.4/701-net-0150-soc-fsl-dpio-enable-qbman-CENA-portal-memory-access.patch deleted file mode 100644 index d246046c79..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0150-soc-fsl-dpio-enable-qbman-CENA-portal-memory-access.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 8464c7b6e7c491ae06b18103881611c98678cf1f Mon Sep 17 00:00:00 2001 -From: Haiying Wang -Date: Thu, 13 Apr 2017 14:54:01 -0400 -Subject: [PATCH] soc: fsl: dpio: enable qbman CENA portal memory access - -Once we enable the cacheable portal memory, we need to do -cache flush for enqueue, vdq, buffer release, and management -commands, as well as invalidate and prefetch for the valid bit -of management command response and next index of dqrr. - -Signed-off-by: Haiying Wang ---- - drivers/soc/fsl/dpio/qbman-portal.c | 23 +++++++++++++++++------ - 1 file changed, 17 insertions(+), 6 deletions(-) - ---- a/drivers/soc/fsl/dpio/qbman-portal.c -+++ b/drivers/soc/fsl/dpio/qbman-portal.c -@@ -90,6 +90,14 @@ enum qbman_sdqcr_fc { - qbman_sdqcr_fc_up_to_3 = 1 - }; - -+#define dccvac(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); } -+#define dcivac(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); } -+static inline void qbman_inval_prefetch(struct qbman_swp *p, uint32_t offset) -+{ -+ dcivac(p->addr_cena + offset); -+ prefetch(p->addr_cena + offset); -+} -+ - /* Portal Access */ - - static inline u32 qbman_read_register(struct qbman_swp *p, u32 offset) -@@ -190,7 +198,7 @@ struct qbman_swp *qbman_swp_init(const s - memset(p->addr_cena, 0, 64 * 1024); - - reg = qbman_set_swp_cfg(p->dqrr.dqrr_size, -- 1, /* Writes Non-cacheable */ -+ 0, /* Writes cacheable */ - 0, /* EQCR_CI stashing threshold */ - 3, /* RPM: Valid bit mode, RCR in array mode */ - 2, /* DCM: Discrete consumption ack mode */ -@@ -329,6 +337,7 @@ void qbman_swp_mc_submit(struct qbman_sw - if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { - dma_wmb(); - *v = cmd_verb | p->mc.valid_bit; -+ dccvac(cmd); - } else { - *v = cmd_verb | p->mc.valid_bit; - dma_wmb(); -@@ -345,6 +354,7 @@ void *qbman_swp_mc_result(struct qbman_s - u32 *ret, verb; - - if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { -+ qbman_inval_prefetch(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit)); - ret = qbman_get_cmd(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit)); - /* Remove the valid-bit - command completed if the rest - * is non-zero. -@@ -481,6 +491,7 @@ int qbman_swp_enqueue(struct qbman_swp * - /* Set the verb byte, have to substitute in the valid-bit */ - dma_wmb(); - p->verb = d->verb | EQAR_VB(eqar); -+ dccvac(p); - } else { - p->verb = d->verb | EQAR_VB(eqar); - dma_wmb(); -@@ -677,6 +688,7 @@ int qbman_swp_pull(struct qbman_swp *s, - /* Set the verb byte, have to substitute in the valid-bit */ - p->verb = d->verb | s->vdq.valid_bit; - s->vdq.valid_bit ^= QB_VALID_BIT; -+ dccvac(p); - } else { - p->verb = d->verb | s->vdq.valid_bit; - s->vdq.valid_bit ^= QB_VALID_BIT; -@@ -736,8 +748,7 @@ const struct dpaa2_dq *qbman_swp_dqrr_ne - s->dqrr.next_idx, pi); - s->dqrr.reset_bug = 0; - } -- prefetch(qbman_get_cmd(s, -- QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx))); -+ qbman_inval_prefetch(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); - } - - if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) -@@ -755,8 +766,7 @@ const struct dpaa2_dq *qbman_swp_dqrr_ne - * knew from reading PI. - */ - if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) { -- prefetch(qbman_get_cmd(s, -- QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx))); -+ qbman_inval_prefetch(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); - return NULL; - } - /* -@@ -779,7 +789,7 @@ const struct dpaa2_dq *qbman_swp_dqrr_ne - (flags & DPAA2_DQ_STAT_EXPIRED)) - atomic_inc(&s->vdq.available); - -- prefetch(qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx))); -+ qbman_inval_prefetch(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); - - return p; - } -@@ -911,6 +921,7 @@ int qbman_swp_release(struct qbman_swp * - */ - dma_wmb(); - p->verb = d->verb | RAR_VB(rar) | num_buffers; -+ dccvac(p); - } else { - p->verb = d->verb | RAR_VB(rar) | num_buffers; - dma_wmb(); diff --git a/target/linux/layerscape/patches-5.4/701-net-0151-soc-fsl-dpio-Prefer-the-CPU-affine-DPIO.patch b/target/linux/layerscape/patches-5.4/701-net-0151-soc-fsl-dpio-Prefer-the-CPU-affine-DPIO.patch deleted file mode 100644 index e9fdc7d0da..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0151-soc-fsl-dpio-Prefer-the-CPU-affine-DPIO.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 33b7977ba754b6ec4e65aaae34de92d4086ea0bd Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Wed, 13 Sep 2017 17:03:06 -0400 -Subject: [PATCH] soc: fsl: dpio: Prefer the CPU affine DPIO - -Use the cpu affine DPIO unless there isn't one which can happen -if less DPIOs than cores are assign to the kernel. - -Signed-off-by: Roy Pledge ---- - drivers/soc/fsl/dpio/dpio-service.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/soc/fsl/dpio/dpio-service.c -+++ b/drivers/soc/fsl/dpio/dpio-service.c -@@ -58,7 +58,7 @@ static inline struct dpaa2_io *service_s - * If cpu == -1, choose the current cpu, with no guarantees about - * potentially being migrated away. - */ -- if (unlikely(cpu < 0)) -+ if (cpu < 0) - cpu = smp_processor_id(); - - /* If a specific cpu was requested, pick it up immediately */ -@@ -70,6 +70,10 @@ static inline struct dpaa2_io *service_s - if (d) - return d; - -+ d = service_select_by_cpu(d, -1); -+ if (d) -+ return d; -+ - spin_lock(&dpio_list_lock); - d = list_entry(dpio_list.next, struct dpaa2_io, node); - list_del(&d->node); diff --git a/target/linux/layerscape/patches-5.4/701-net-0152-soc-fsl-dpio-Add-Support-for-Order-Restoration.patch b/target/linux/layerscape/patches-5.4/701-net-0152-soc-fsl-dpio-Add-Support-for-Order-Restoration.patch deleted file mode 100644 index a03f3e23a6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0152-soc-fsl-dpio-Add-Support-for-Order-Restoration.patch +++ /dev/null @@ -1,214 +0,0 @@ -From c91f8c8c94c5e8a25d0d46d6cb26c0c48ba04f8f Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Wed, 4 Oct 2017 15:36:06 -0400 -Subject: [PATCH] soc: fsl: dpio: Add Support for Order Restoration - -Add DPIO support for HW assisted order restoration - -Signed-off-by: Roy Pledge ---- - drivers/soc/fsl/dpio/dpio-service.c | 105 ++++++++++++++++++++++++++++++++++++ - drivers/soc/fsl/dpio/qbman-portal.c | 37 +++++++++++++ - drivers/soc/fsl/dpio/qbman-portal.h | 3 ++ - include/soc/fsl/dpaa2-io.h | 14 ++++- - 4 files changed, 158 insertions(+), 1 deletion(-) - ---- a/drivers/soc/fsl/dpio/dpio-service.c -+++ b/drivers/soc/fsl/dpio/dpio-service.c -@@ -707,3 +707,108 @@ int dpaa2_io_query_bp_count(struct dpaa2 - return 0; - } - EXPORT_SYMBOL_GPL(dpaa2_io_query_bp_count); -+ -+/** -+ * dpaa2_io_service_enqueue_orp_fq() - Enqueue a frame to a frame queue with -+ * order restoration -+ * @d: the given DPIO service. -+ * @fqid: the given frame queue id. -+ * @fd: the frame descriptor which is enqueued. -+ * @orpid: the order restoration point ID -+ * @seqnum: the order sequence number -+ * @last: must be set for the final frame if seqnum is shared (spilt frame) -+ * -+ * Performs an enqueue to a frame queue using the specified order restoration -+ * point. The QMan device will ensure the order of frames placed on the -+ * queue will be ordered as per the sequence number. -+ * -+ * In the case a frame is split it is possible to enqueue using the same -+ * sequence number more than once. The final frame in a shared sequence number -+ * most be indicated by setting last = 1. For non shared sequence numbers -+ * last = 1 must always be set. -+ * -+ * Return 0 for successful enqueue, or -EBUSY if the enqueue ring is not ready, -+ * or -ENODEV if there is no dpio service. -+ */ -+int dpaa2_io_service_enqueue_orp_fq(struct dpaa2_io *d, u32 fqid, -+ const struct dpaa2_fd *fd, u16 orpid, -+ u16 seqnum, int last) -+{ -+ struct qbman_eq_desc ed; -+ -+ d = service_select(d); -+ if (!d) -+ return -ENODEV; -+ qbman_eq_desc_clear(&ed); -+ qbman_eq_desc_set_orp(&ed, 0, orpid, seqnum, !last); -+ qbman_eq_desc_set_fq(&ed, fqid); -+ return qbman_swp_enqueue(d->swp, &ed, fd); -+} -+EXPORT_SYMBOL(dpaa2_io_service_enqueue_orp_fq); -+ -+/** -+ * dpaa2_io_service_enqueue_orp_qd() - Enqueue a frame to a queueing destination -+ * with order restoration -+ * @d: the given DPIO service. -+ * @qdid: the given queuing destination id. -+ * @fd: the frame descriptor which is enqueued. -+ * @orpid: the order restoration point ID -+ * @seqnum: the order sequence number -+ * @last: must be set for the final frame if seqnum is shared (spilt frame) -+ * -+ * Performs an enqueue to a frame queue using the specified order restoration -+ * point. The QMan device will ensure the order of frames placed on the -+ * queue will be ordered as per the sequence number. -+ * -+ * In the case a frame is split it is possible to enqueue using the same -+ * sequence number more than once. The final frame in a shared sequence number -+ * most be indicated by setting last = 1. For non shared sequence numbers -+ * last = 1 must always be set. -+ * -+ * Return 0 for successful enqueue, or -EBUSY if the enqueue ring is not ready, -+ * or -ENODEV if there is no dpio service. -+ */ -+int dpaa2_io_service_enqueue_orp_qd(struct dpaa2_io *d, u32 qdid, u8 prio, -+ u16 qdbin, const struct dpaa2_fd *fd, -+ u16 orpid, u16 seqnum, int last) -+{ -+ struct qbman_eq_desc ed; -+ -+ d = service_select(d); -+ if (!d) -+ return -ENODEV; -+ qbman_eq_desc_clear(&ed); -+ qbman_eq_desc_set_orp(&ed, 0, orpid, seqnum, !last); -+ qbman_eq_desc_set_qd(&ed, qdid, qdbin, prio); -+ return qbman_swp_enqueue(d->swp, &ed, fd); -+} -+EXPORT_SYMBOL_GPL(dpaa2_io_service_enqueue_orp_qd); -+ -+/** -+ * dpaa2_io_service_orp_seqnum_drop() - Remove a sequence number from -+ * an order restoration list -+ * @d: the given DPIO service. -+ * @orpid: Order restoration point to remove a sequence number from -+ * @seqnum: Sequence number to remove -+ * -+ * Removes a frames sequence number from an order restoration point without -+ * enqueing the frame. Used to indicate that the order restoration hardware -+ * should not expect to see this sequence number. Typically used to indicate -+ * a frame was terminated or dropped from a flow. -+ * -+ * Return 0 for successful enqueue, or -EBUSY if the enqueue ring is not ready, -+ * or -ENODEV if there is no dpio service. -+ */ -+int dpaa2_io_service_orp_seqnum_drop(struct dpaa2_io *d, u16 orpid, u16 seqnum) -+{ -+ struct qbman_eq_desc ed; -+ struct dpaa2_fd fd; -+ -+ d = service_select(d); -+ if (!d) -+ return -ENODEV; -+ qbman_eq_desc_clear(&ed); -+ qbman_eq_desc_set_orp_hole(&ed, orpid, seqnum); -+ return qbman_swp_enqueue(d->swp, &ed, &fd); -+} -+EXPORT_SYMBOL_GPL(dpaa2_io_service_orp_seqnum_drop); ---- a/drivers/soc/fsl/dpio/qbman-portal.c -+++ b/drivers/soc/fsl/dpio/qbman-portal.c -@@ -413,6 +413,43 @@ void qbman_eq_desc_set_no_orp(struct qbm - d->verb |= enqueue_rejects_to_fq; - } - -+/** -+ * qbman_eq_desc_set_orp() - Set order-restoration in the enqueue descriptor -+ * @d: the enqueue descriptor. -+ * @response_success: 1 = enqueue with response always; 0 = enqueue with -+ * rejections returned on a FQ. -+ * @oprid: the order point record id. -+ * @seqnum: the order restoration sequence number. -+ * @incomplete: indicates whether this is the last fragments using the same -+ * sequence number. -+ */ -+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success, -+ u16 oprid, u16 seqnum, int incomplete) -+{ -+ d->verb |= (1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT); -+ if (respond_success) -+ d->verb |= enqueue_response_always; -+ else -+ d->verb |= enqueue_rejects_to_fq; -+ d->orpid = cpu_to_le16(oprid); -+ d->seqnum = cpu_to_le16((!!incomplete << 14) | seqnum); -+} -+ -+/** -+ * qbman_eq_desc_set_orp_hole() - fill a hole in the order-restoration sequence -+ * without any enqueue -+ * @d: the enqueue descriptor. -+ * @oprid: the order point record id. -+ * @seqnum: the order restoration sequence number. -+ */ -+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, u16 oprid, -+ u16 seqnum) -+{ -+ d->verb |= (1 << QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT) | enqueue_empty; -+ d->orpid = cpu_to_le16(oprid); -+ d->seqnum = cpu_to_le16(seqnum); -+} -+ - /* - * Exactly one of the following descriptor "targets" should be set. (Calling any - * one of these will replace the effect of any prior call to one of these.) ---- a/drivers/soc/fsl/dpio/qbman-portal.h -+++ b/drivers/soc/fsl/dpio/qbman-portal.h -@@ -167,6 +167,9 @@ int qbman_result_has_new_result(struct q - - void qbman_eq_desc_clear(struct qbman_eq_desc *d); - void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success); -+void qbman_eq_desc_set_orp(struct qbman_eq_desc *d, int respond_success, -+ u16 oprid, u16 seqnum, int incomplete); -+void qbman_eq_desc_set_orp_hole(struct qbman_eq_desc *d, u16 oprid, u16 seqnum); - void qbman_eq_desc_set_token(struct qbman_eq_desc *d, u8 token); - void qbman_eq_desc_set_fq(struct qbman_eq_desc *d, u32 fqid); - void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid, ---- a/include/soc/fsl/dpaa2-io.h -+++ b/include/soc/fsl/dpaa2-io.h -@@ -1,7 +1,7 @@ - /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ - /* - * Copyright 2014-2016 Freescale Semiconductor Inc. -- * Copyright NXP -+ * Copyright 2017 NXP - * - */ - #ifndef __FSL_DPAA2_IO_H -@@ -121,6 +121,18 @@ struct dpaa2_io_store *dpaa2_io_store_cr - void dpaa2_io_store_destroy(struct dpaa2_io_store *s); - struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last); - -+/* Order Restoration Support */ -+int dpaa2_io_service_enqueue_orp_fq(struct dpaa2_io *d, u32 fqid, -+ const struct dpaa2_fd *fd, u16 orpid, -+ u16 seqnum, int last); -+ -+int dpaa2_io_service_enqueue_orp_qd(struct dpaa2_io *d, u32 qdid, u8 prio, -+ u16 qdbin, const struct dpaa2_fd *fd, -+ u16 orpid, u16 seqnum, int last); -+ -+int dpaa2_io_service_orp_seqnum_drop(struct dpaa2_io *d, u16 orpid, -+ u16 seqnum); -+ - int dpaa2_io_query_fq_count(struct dpaa2_io *d, u32 fqid, - u32 *fcnt, u32 *bcnt); - int dpaa2_io_query_bp_count(struct dpaa2_io *d, u16 bpid, diff --git a/target/linux/layerscape/patches-5.4/701-net-0153-soc-fsl-dpio-Fix-order-restoration-API-for-QBMan-5.0.patch b/target/linux/layerscape/patches-5.4/701-net-0153-soc-fsl-dpio-Fix-order-restoration-API-for-QBMan-5.0.patch deleted file mode 100644 index 6ca8b59518..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0153-soc-fsl-dpio-Fix-order-restoration-API-for-QBMan-5.0.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 72a6312eda9b142ac5910e5f4b652fa8ae8d222d Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Thu, 25 Oct 2018 16:55:53 -0400 -Subject: [PATCH] soc: fsl: dpio: Fix order restoration API for QBMan 5.0 - -The mechanism for indicating to HW that a frame was dropped -when performing HW order restoration changed in QBMan 5.0 to -use a management command instead of a special enqueue command. -This patch implements that change when running on a QBMan 5.0 -and above device. - -Signed-off-by: Roy Pledge ---- - drivers/soc/fsl/dpio/dpio-service.c | 10 +++++++ - drivers/soc/fsl/dpio/qbman-portal.c | 59 ++++++++++++++++++++++++++++++++----- - drivers/soc/fsl/dpio/qbman-portal.h | 9 ++++++ - 3 files changed, 71 insertions(+), 7 deletions(-) - ---- a/drivers/soc/fsl/dpio/dpio-service.c -+++ b/drivers/soc/fsl/dpio/dpio-service.c -@@ -803,10 +803,20 @@ int dpaa2_io_service_orp_seqnum_drop(str - { - struct qbman_eq_desc ed; - struct dpaa2_fd fd; -+ unsigned long irqflags; -+ int ret; - - d = service_select(d); - if (!d) - return -ENODEV; -+ -+ if ((d->swp->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) { -+ spin_lock_irqsave(&d->lock_mgmt_cmd, irqflags); -+ ret = qbman_orp_drop(d->swp, orpid, seqnum); -+ spin_unlock_irqrestore(&d->lock_mgmt_cmd, irqflags); -+ return ret; -+ } -+ - qbman_eq_desc_clear(&ed); - qbman_eq_desc_set_orp_hole(&ed, orpid, seqnum); - return qbman_swp_enqueue(d->swp, &ed, &fd); ---- a/drivers/soc/fsl/dpio/qbman-portal.c -+++ b/drivers/soc/fsl/dpio/qbman-portal.c -@@ -12,19 +12,13 @@ - - #include "qbman-portal.h" - --#define QMAN_REV_4000 0x04000000 --#define QMAN_REV_4100 0x04010000 --#define QMAN_REV_4101 0x04010001 --#define QMAN_REV_5000 0x05000000 -- --#define QMAN_REV_MASK 0xffff0000 -- - /* All QBMan command and result structures use this "valid bit" encoding */ - #define QB_VALID_BIT ((u32)0x80) - - /* QBMan portal management command codes */ - #define QBMAN_MC_ACQUIRE 0x30 - #define QBMAN_WQCHAN_CONFIGURE 0x46 -+#define QBMAN_MC_ORP 0x63 - - /* CINH register offsets */ - #define QBMAN_CINH_SWP_EQCR_PI 0x800 -@@ -1246,3 +1240,54 @@ u32 qbman_bp_info_num_free_bufs(struct q - { - return le32_to_cpu(a->fill); - } -+ -+struct qbman_orp_cmd_desc { -+ u8 verb; -+ u8 reserved; -+ u8 cid; -+ u8 reserved2; -+ u16 orpid; -+ u16 seqnum; -+ u8 reserved3[56]; -+}; -+ -+struct qbman_orp_cmd_rslt { -+ u8 verb; -+ u8 rslt; -+ u8 cid; -+ u8 reserved1[61]; -+}; -+ -+int qbman_orp_drop(struct qbman_swp *s, u16 orpid, u16 seqnum) -+{ -+ struct qbman_orp_cmd_desc *p; -+ struct qbman_orp_cmd_rslt *r; -+ void *resp; -+ -+ p = (struct qbman_orp_cmd_desc *)qbman_swp_mc_start(s); -+ if (!p) -+ return -EBUSY; -+ -+ p->cid = 0x7; -+ p->orpid = cpu_to_le16(orpid); -+ p->seqnum = cpu_to_le16(seqnum); -+ -+ resp = qbman_swp_mc_complete(s, p, QBMAN_MC_ORP); -+ if (!resp) { -+ pr_err("qbman: Drop sequence num %d orpid 0x%x failed, no response\n", -+ seqnum, orpid); -+ return -EIO; -+ } -+ r = (struct qbman_orp_cmd_rslt *)resp; -+ /* Decode the outcome */ -+ WARN_ON((r->verb & QBMAN_RESPONSE_VERB_MASK) != QBMAN_MC_ORP); -+ -+ /* Determine success or failure */ -+ if (r->rslt != QBMAN_MC_RSLT_OK) { -+ pr_err("Drop seqnum %d of prpid 0x%x failed, code=0x%02x\n", -+ seqnum, orpid, r->rslt); -+ return -EIO; -+ } -+ -+ return 0; -+} ---- a/drivers/soc/fsl/dpio/qbman-portal.h -+++ b/drivers/soc/fsl/dpio/qbman-portal.h -@@ -9,6 +9,13 @@ - - #include - -+#define QMAN_REV_4000 0x04000000 -+#define QMAN_REV_4100 0x04010000 -+#define QMAN_REV_4101 0x04010001 -+#define QMAN_REV_5000 0x05000000 -+ -+#define QMAN_REV_MASK 0xffff0000 -+ - struct dpaa2_dq; - struct qbman_swp; - -@@ -178,6 +185,8 @@ void qbman_eq_desc_set_qd(struct qbman_e - int qbman_swp_enqueue(struct qbman_swp *p, const struct qbman_eq_desc *d, - const struct dpaa2_fd *fd); - -+int qbman_orp_drop(struct qbman_swp *s, u16 orpid, u16 seqnum); -+ - void qbman_release_desc_clear(struct qbman_release_desc *d); - void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid); - void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable); diff --git a/target/linux/layerscape/patches-5.4/701-net-0154-soc-fsl-dpio-add-support-for-opr.patch b/target/linux/layerscape/patches-5.4/701-net-0154-soc-fsl-dpio-add-support-for-opr.patch deleted file mode 100644 index 8bd1e547d7..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0154-soc-fsl-dpio-add-support-for-opr.patch +++ /dev/null @@ -1,100 +0,0 @@ -From a0fd93952b6f0b408d96b29a0b9beb8bb2d8a24d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Wed, 10 Oct 2018 15:59:55 +0300 -Subject: [PATCH] soc: fsl: dpio: add support for opr -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Order preservation is a feature that will be supported -in dpni, dpseci and dpci devices. -This is a preliminary patch for the changes to be -introduced in the corresponding drivers. - -Signed-off-by: Radu Alexe -Signed-off-by: Horia Geantă ---- - include/soc/fsl/dpaa2-global.h | 74 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 74 insertions(+) - ---- a/include/soc/fsl/dpaa2-global.h -+++ b/include/soc/fsl/dpaa2-global.h -@@ -189,4 +189,78 @@ static inline bool dpaa2_cscn_state_cong - return !!(cscn->scn.state & DPAA2_CSCN_STATE_CG); - } - -+/* Data Path Order Restoration API -+ * Contains initialization APIs and runtime APIs for the Order Restoration -+ */ -+ -+/** Order Restoration properties */ -+ -+/** -+ * Create a new Order Point Record option -+ */ -+#define OPR_OPT_CREATE 0x1 -+/** -+ * Retire an existing Order Point Record option -+ */ -+#define OPR_OPT_RETIRE 0x2 -+ -+/** -+ * struct opr_cfg - Structure representing OPR configuration -+ * @oprrws: Order point record (OPR) restoration window size (0 to 5) -+ * 0 - Window size is 32 frames. -+ * 1 - Window size is 64 frames. -+ * 2 - Window size is 128 frames. -+ * 3 - Window size is 256 frames. -+ * 4 - Window size is 512 frames. -+ * 5 - Window size is 1024 frames. -+ * @oa: OPR auto advance NESN window size (0 disabled, 1 enabled) -+ * @olws: OPR acceptable late arrival window size (0 to 3) -+ * 0 - Disabled. Late arrivals are always rejected. -+ * 1 - Window size is 32 frames. -+ * 2 - Window size is the same as the OPR restoration -+ * window size configured in the OPRRWS field. -+ * 3 - Window size is 8192 frames. Late arrivals are -+ * always accepted. -+ * @oeane: Order restoration list (ORL) resource exhaustion -+ * advance NESN enable (0 disabled, 1 enabled) -+ * @oloe: OPR loose ordering enable (0 disabled, 1 enabled) -+ */ -+struct opr_cfg { -+ u8 oprrws; -+ u8 oa; -+ u8 olws; -+ u8 oeane; -+ u8 oloe; -+}; -+ -+/** -+ * struct opr_qry - Structure representing OPR configuration -+ * @enable: Enabled state -+ * @rip: Retirement In Progress -+ * @ndsn: Next dispensed sequence number -+ * @nesn: Next expected sequence number -+ * @ea_hseq: Early arrival head sequence number -+ * @hseq_nlis: HSEQ not last in sequence -+ * @ea_tseq: Early arrival tail sequence number -+ * @tseq_nlis: TSEQ not last in sequence -+ * @ea_tptr: Early arrival tail pointer -+ * @ea_hptr: Early arrival head pointer -+ * @opr_id: Order Point Record ID -+ * @opr_vid: Order Point Record Virtual ID -+ */ -+struct opr_qry { -+ char enable; -+ char rip; -+ u16 ndsn; -+ u16 nesn; -+ u16 ea_hseq; -+ char hseq_nlis; -+ u16 ea_tseq; -+ char tseq_nlis; -+ u16 ea_tptr; -+ u16 ea_hptr; -+ u16 opr_id; -+ u16 opr_vid; -+}; -+ - #endif /* __FSL_DPAA2_GLOBAL_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0155-soc-fsl-dpio-aligned-access-of-qbman-cacheable-regio.patch b/target/linux/layerscape/patches-5.4/701-net-0155-soc-fsl-dpio-aligned-access-of-qbman-cacheable-regio.patch deleted file mode 100644 index 92e4dca643..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0155-soc-fsl-dpio-aligned-access-of-qbman-cacheable-regio.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 353725d455cc27aa2008456c2711e7fae2b8a631 Mon Sep 17 00:00:00 2001 -From: Bharat Bhushan -Date: Wed, 7 Mar 2018 21:35:37 +0530 -Subject: [PATCH] soc: fsl: dpio: aligned access of qbman cacheable region - -Alignment requirement on ARM is lenient (In Linux) for regions -mapped as "Memory Type" but have very strict policy for regions -mapped as "Device Type". Unaligned access to regions mapped -as "Device Type" will always result to unaligned fault. - -DPIO driver have un-aligned access to QBman cacheable region -and the Linux driver maps the region as "Memory Type". On Host -Linux this works because MMU Stage-1 configured by driver allows -unaligned access. In Virtual Machine cases, final region mapping type -is governed by combination of Stage-1 and Stage-2 MMU mapping. - -Linux driver in VM controls maps the region as "Memory Type" in -Stage-1 MMU while Stage-2 is controlled by KVM. And current KVM -implementation does not allow device region to be mapped as -"Memory Type". Till we have a working/upstream-able solution -for Virtual Machine, we need to change un-aligned access in DPIO -driver to be aligned - -While we reached to this point as we observed below alignment -exception in Virtual Machine when accessing qbman cacheable region. - - kvm [2347]: Unsupported FSC: EC=0x24 xFSC=0x21 - ESR_EL2=0x92000061 - error: kvm run failed Bad address - PC=ffff000008398e78 SP=ffff800009bcb540 - X00=ffff000008041000 X01=ffff800009bcb580 X02=ffff800009bcb650 - X03=0000000000000180 - X04=ffff000008041001 X05=ffff800009bcb581 X06=0200000000000000 - X07=0000000000000000 - X08=0000000000000000 X09=ffff000008041000 X10=0000000000000001 - X11=0000000000de6cb0 - X12=00000000fa83b2da X13=0000000000000001 X14=000000007f605ec8 - X15=00000000e26f5d5e - X16=000000008521af1e X17=000000001076277e X18=ffff800009bcb5c0 - X19=ffff800079da2b00 - X20=ffff800009bcb650 X21=0000000000000002 X22=0000000000000000 - X23=0000000000000000 - X24=0000000000000000 X25=ffff8000099e7440 X26=ffff000008da6000 - X27=ffff000008e7f000 - X28=00000000499e7440 X29=ffff800009bcb540 X30=ffff00000839a160 - PSTATE=20000145 --C- EL1h - -Signed-off-by: Bharat Bhushan ---- - drivers/soc/fsl/dpio/qbman-portal.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - ---- a/drivers/soc/fsl/dpio/qbman-portal.c -+++ b/drivers/soc/fsl/dpio/qbman-portal.c -@@ -515,7 +515,17 @@ int qbman_swp_enqueue(struct qbman_swp * - return -EBUSY; - - p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar))); -- memcpy(&p->dca, &d->dca, 31); -+ /* This is mapped as DEVICE type memory, writes are -+ * with address alignment: -+ * desc.dca address alignment = 1 -+ * desc.seqnum address alignment = 2 -+ * desc.orpid address alignment = 4 -+ * desc.tgtid address alignment = 8 -+ */ -+ p->dca = d->dca; -+ p->seqnum = d->seqnum; -+ p->orpid = d->orpid; -+ memcpy(&p->tgtid, &d->tgtid, 24); - memcpy(&p->fd, fd, sizeof(*fd)); - - if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0156-staging-fsl-dpaa2-mac-Add-APIs-for-DPMAC-objects.patch b/target/linux/layerscape/patches-5.4/701-net-0156-staging-fsl-dpaa2-mac-Add-APIs-for-DPMAC-objects.patch deleted file mode 100644 index 110d5dab90..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0156-staging-fsl-dpaa2-mac-Add-APIs-for-DPMAC-objects.patch +++ /dev/null @@ -1,1162 +0,0 @@ -From 344af44442388ea7f34cb4c4d88fa1162f8d4ddf Mon Sep 17 00:00:00 2001 -From: Bogdan Purcareata -Date: Wed, 12 Apr 2017 12:38:57 +0000 -Subject: [PATCH] staging: fsl-dpaa2/mac: Add APIs for DPMAC objects - -Add the command build/parse APIs for operating on DPMAC -objects through the DPAA2 Management Complex. - -Signed-off-by: Bogdan Hamciuc -Signed-off-by: Bogdan Purcareata ---- - drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h | 172 +++++++++ - drivers/staging/fsl-dpaa2/mac/dpmac.c | 620 ++++++++++++++++++++++++++++++ - drivers/staging/fsl-dpaa2/mac/dpmac.h | 342 ++++++++++++++++ - 3 files changed, 1134 insertions(+) - create mode 100644 drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h - create mode 100644 drivers/staging/fsl-dpaa2/mac/dpmac.c - create mode 100644 drivers/staging/fsl-dpaa2/mac/dpmac.h - ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h -@@ -0,0 +1,172 @@ -+/* Copyright 2013-2016 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of the above-listed copyright holders nor the -+ * names of any contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -+ * POSSIBILITY OF SUCH DAMAGE. -+ */ -+#ifndef _FSL_DPMAC_CMD_H -+#define _FSL_DPMAC_CMD_H -+ -+/* DPMAC Version */ -+#define DPMAC_VER_MAJOR 4 -+#define DPMAC_VER_MINOR 2 -+#define DPMAC_CMD_BASE_VERSION 1 -+#define DPMAC_CMD_ID_OFFSET 4 -+ -+#define DPMAC_CMD(id) (((id) << DPMAC_CMD_ID_OFFSET) | DPMAC_CMD_BASE_VERSION) -+ -+/* Command IDs */ -+#define DPMAC_CMDID_CLOSE DPMAC_CMD(0x800) -+#define DPMAC_CMDID_OPEN DPMAC_CMD(0x80c) -+#define DPMAC_CMDID_CREATE DPMAC_CMD(0x90c) -+#define DPMAC_CMDID_DESTROY DPMAC_CMD(0x98c) -+#define DPMAC_CMDID_GET_API_VERSION DPMAC_CMD(0xa0c) -+ -+#define DPMAC_CMDID_GET_ATTR DPMAC_CMD(0x004) -+#define DPMAC_CMDID_RESET DPMAC_CMD(0x005) -+ -+#define DPMAC_CMDID_SET_IRQ_ENABLE DPMAC_CMD(0x012) -+#define DPMAC_CMDID_GET_IRQ_ENABLE DPMAC_CMD(0x013) -+#define DPMAC_CMDID_SET_IRQ_MASK DPMAC_CMD(0x014) -+#define DPMAC_CMDID_GET_IRQ_MASK DPMAC_CMD(0x015) -+#define DPMAC_CMDID_GET_IRQ_STATUS DPMAC_CMD(0x016) -+#define DPMAC_CMDID_CLEAR_IRQ_STATUS DPMAC_CMD(0x017) -+ -+#define DPMAC_CMDID_GET_LINK_CFG DPMAC_CMD(0x0c2) -+#define DPMAC_CMDID_SET_LINK_STATE DPMAC_CMD(0x0c3) -+#define DPMAC_CMDID_GET_COUNTER DPMAC_CMD(0x0c4) -+ -+#define DPMAC_CMDID_SET_PORT_MAC_ADDR DPMAC_CMD(0x0c5) -+ -+/* Macros for accessing command fields smaller than 1byte */ -+#define DPMAC_MASK(field) \ -+ GENMASK(DPMAC_##field##_SHIFT + DPMAC_##field##_SIZE - 1, \ -+ DPMAC_##field##_SHIFT) -+#define dpmac_set_field(var, field, val) \ -+ ((var) |= (((val) << DPMAC_##field##_SHIFT) & DPMAC_MASK(field))) -+#define dpmac_get_field(var, field) \ -+ (((var) & DPMAC_MASK(field)) >> DPMAC_##field##_SHIFT) -+ -+struct dpmac_cmd_open { -+ u32 dpmac_id; -+}; -+ -+struct dpmac_cmd_create { -+ u32 mac_id; -+}; -+ -+struct dpmac_cmd_destroy { -+ u32 dpmac_id; -+}; -+ -+struct dpmac_cmd_set_irq_enable { -+ u8 enable; -+ u8 pad[3]; -+ u8 irq_index; -+}; -+ -+struct dpmac_cmd_get_irq_enable { -+ u32 pad; -+ u8 irq_index; -+}; -+ -+struct dpmac_rsp_get_irq_enable { -+ u8 enabled; -+}; -+ -+struct dpmac_cmd_set_irq_mask { -+ u32 mask; -+ u8 irq_index; -+}; -+ -+struct dpmac_cmd_get_irq_mask { -+ u32 pad; -+ u8 irq_index; -+}; -+ -+struct dpmac_rsp_get_irq_mask { -+ u32 mask; -+}; -+ -+struct dpmac_cmd_get_irq_status { -+ u32 status; -+ u8 irq_index; -+}; -+ -+struct dpmac_rsp_get_irq_status { -+ u32 status; -+}; -+ -+struct dpmac_cmd_clear_irq_status { -+ u32 status; -+ u8 irq_index; -+}; -+ -+struct dpmac_rsp_get_attributes { -+ u8 eth_if; -+ u8 link_type; -+ u16 id; -+ u32 max_rate; -+}; -+ -+struct dpmac_rsp_get_link_cfg { -+ u64 options; -+ u32 rate; -+}; -+ -+#define DPMAC_STATE_SIZE 1 -+#define DPMAC_STATE_SHIFT 0 -+ -+struct dpmac_cmd_set_link_state { -+ u64 options; -+ u32 rate; -+ u32 pad; -+ /* only least significant bit is valid */ -+ u8 up; -+}; -+ -+struct dpmac_cmd_get_counter { -+ u8 type; -+}; -+ -+struct dpmac_rsp_get_counter { -+ u64 pad; -+ u64 counter; -+}; -+ -+struct dpmac_rsp_get_api_version { -+ u16 major; -+ u16 minor; -+}; -+ -+struct dpmac_cmd_set_port_mac_addr { -+ u8 pad[2]; -+ u8 addr[6]; -+}; -+ -+#endif /* _FSL_DPMAC_CMD_H */ ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/mac/dpmac.c -@@ -0,0 +1,620 @@ -+/* Copyright 2013-2016 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of the above-listed copyright holders nor the -+ * names of any contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -+ * POSSIBILITY OF SUCH DAMAGE. -+ */ -+#include "../../fsl-mc/include/mc-sys.h" -+#include "../../fsl-mc/include/mc-cmd.h" -+#include "dpmac.h" -+#include "dpmac-cmd.h" -+ -+/** -+ * dpmac_open() - Open a control session for the specified object. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @dpmac_id: DPMAC unique ID -+ * @token: Returned token; use in subsequent API calls -+ * -+ * This function can be used to open a control session for an -+ * already created object; an object may have been declared in -+ * the DPL or by calling the dpmac_create function. -+ * This function returns a unique authentication token, -+ * associated with the specific object ID and the specific MC -+ * portal; this token must be used in all subsequent commands for -+ * this specific object -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_open(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ int dpmac_id, -+ u16 *token) -+{ -+ struct dpmac_cmd_open *cmd_params; -+ struct mc_command cmd = { 0 }; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_OPEN, -+ cmd_flags, -+ 0); -+ cmd_params = (struct dpmac_cmd_open *)cmd.params; -+ cmd_params->dpmac_id = cpu_to_le32(dpmac_id); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ *token = mc_cmd_hdr_read_token(&cmd); -+ -+ return err; -+} -+ -+/** -+ * dpmac_close() - Close the control session of the object -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * -+ * After this function is called, no further operations are -+ * allowed on the object without opening a new control session. -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_close(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token) -+{ -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLOSE, cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpmac_create() - Create the DPMAC object. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @dprc_token: Parent container token; '0' for default container -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @cfg: Configuration structure -+ * @obj_id: Returned object id -+ * -+ * Create the DPMAC object, allocate required resources and -+ * perform required initialization. -+ * -+ * The function accepts an authentication token of a parent -+ * container that this object should be assigned to. The token -+ * can be '0' so the object will be assigned to the default container. -+ * The newly created object can be opened with the returned -+ * object id and using the container's associated tokens and MC portals. -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_create(struct fsl_mc_io *mc_io, -+ u16 dprc_token, -+ u32 cmd_flags, -+ const struct dpmac_cfg *cfg, -+ u32 *obj_id) -+{ -+ struct dpmac_cmd_create *cmd_params; -+ struct mc_command cmd = { 0 }; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CREATE, -+ cmd_flags, -+ dprc_token); -+ cmd_params = (struct dpmac_cmd_create *)cmd.params; -+ cmd_params->mac_id = cpu_to_le32(cfg->mac_id); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ *obj_id = mc_cmd_read_object_id(&cmd); -+ -+ return 0; -+} -+ -+/** -+ * dpmac_destroy() - Destroy the DPMAC object and release all its resources. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @dprc_token: Parent container token; '0' for default container -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @object_id: The object id; it must be a valid id within the container that -+ * created this object; -+ * -+ * The function accepts the authentication token of the parent container that -+ * created the object (not the one that currently owns the object). The object -+ * is searched within parent using the provided 'object_id'. -+ * All tokens to the object must be closed before calling destroy. -+ * -+ * Return: '0' on Success; error code otherwise. -+ */ -+int dpmac_destroy(struct fsl_mc_io *mc_io, -+ u16 dprc_token, -+ u32 cmd_flags, -+ u32 object_id) -+{ -+ struct dpmac_cmd_destroy *cmd_params; -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_DESTROY, -+ cmd_flags, -+ dprc_token); -+ cmd_params = (struct dpmac_cmd_destroy *)cmd.params; -+ cmd_params->dpmac_id = cpu_to_le32(object_id); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpmac_set_irq_enable() - Set overall interrupt state. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @irq_index: The interrupt index to configure -+ * @en: Interrupt state - enable = 1, disable = 0 -+ * -+ * Allows GPP software to control when interrupts are generated. -+ * Each interrupt can have up to 32 causes. The enable/disable control's the -+ * overall interrupt state. if the interrupt is disabled no causes will cause -+ * an interrupt. -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_set_irq_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u8 en) -+{ -+ struct dpmac_cmd_set_irq_enable *cmd_params; -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_IRQ_ENABLE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpmac_cmd_set_irq_enable *)cmd.params; -+ cmd_params->irq_index = irq_index; -+ cmd_params->enable = en; -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpmac_get_irq_enable() - Get overall interrupt state -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @irq_index: The interrupt index to configure -+ * @en: Returned interrupt state - enable = 1, disable = 0 -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_get_irq_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u8 *en) -+{ -+ struct dpmac_cmd_get_irq_enable *cmd_params; -+ struct dpmac_rsp_get_irq_enable *rsp_params; -+ struct mc_command cmd = { 0 }; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_IRQ_ENABLE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpmac_cmd_get_irq_enable *)cmd.params; -+ cmd_params->irq_index = irq_index; -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpmac_rsp_get_irq_enable *)cmd.params; -+ *en = rsp_params->enabled; -+ -+ return 0; -+} -+ -+/** -+ * dpmac_set_irq_mask() - Set interrupt mask. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @irq_index: The interrupt index to configure -+ * @mask: Event mask to trigger interrupt; -+ * each bit: -+ * 0 = ignore event -+ * 1 = consider event for asserting IRQ -+ * -+ * Every interrupt can have up to 32 causes and the interrupt model supports -+ * masking/unmasking each cause independently -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_set_irq_mask(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 mask) -+{ -+ struct dpmac_cmd_set_irq_mask *cmd_params; -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_IRQ_MASK, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpmac_cmd_set_irq_mask *)cmd.params; -+ cmd_params->mask = cpu_to_le32(mask); -+ cmd_params->irq_index = irq_index; -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpmac_get_irq_mask() - Get interrupt mask. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @irq_index: The interrupt index to configure -+ * @mask: Returned event mask to trigger interrupt -+ * -+ * Every interrupt can have up to 32 causes and the interrupt model supports -+ * masking/unmasking each cause independently -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_get_irq_mask(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 *mask) -+{ -+ struct dpmac_cmd_get_irq_mask *cmd_params; -+ struct dpmac_rsp_get_irq_mask *rsp_params; -+ struct mc_command cmd = { 0 }; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_IRQ_MASK, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpmac_cmd_get_irq_mask *)cmd.params; -+ cmd_params->irq_index = irq_index; -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpmac_rsp_get_irq_mask *)cmd.params; -+ *mask = le32_to_cpu(rsp_params->mask); -+ -+ return 0; -+} -+ -+/** -+ * dpmac_get_irq_status() - Get the current status of any pending interrupts. -+ * -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @irq_index: The interrupt index to configure -+ * @status: Returned interrupts status - one bit per cause: -+ * 0 = no interrupt pending -+ * 1 = interrupt pending -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_get_irq_status(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 *status) -+{ -+ struct dpmac_cmd_get_irq_status *cmd_params; -+ struct dpmac_rsp_get_irq_status *rsp_params; -+ struct mc_command cmd = { 0 }; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_IRQ_STATUS, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpmac_cmd_get_irq_status *)cmd.params; -+ cmd_params->status = cpu_to_le32(*status); -+ cmd_params->irq_index = irq_index; -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpmac_rsp_get_irq_status *)cmd.params; -+ *status = le32_to_cpu(rsp_params->status); -+ -+ return 0; -+} -+ -+/** -+ * dpmac_clear_irq_status() - Clear a pending interrupt's status -+ * -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @irq_index: The interrupt index to configure -+ * @status: Bits to clear (W1C) - one bit per cause: -+ * 0 = don't change -+ * 1 = clear status bit -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_clear_irq_status(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 status) -+{ -+ struct dpmac_cmd_clear_irq_status *cmd_params; -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLEAR_IRQ_STATUS, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpmac_cmd_clear_irq_status *)cmd.params; -+ cmd_params->status = cpu_to_le32(status); -+ cmd_params->irq_index = irq_index; -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpmac_get_attributes - Retrieve DPMAC attributes. -+ * -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @attr: Returned object's attributes -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_get_attributes(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpmac_attr *attr) -+{ -+ struct dpmac_rsp_get_attributes *rsp_params; -+ struct mc_command cmd = { 0 }; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_ATTR, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpmac_rsp_get_attributes *)cmd.params; -+ attr->eth_if = rsp_params->eth_if; -+ attr->link_type = rsp_params->link_type; -+ attr->id = le16_to_cpu(rsp_params->id); -+ attr->max_rate = le32_to_cpu(rsp_params->max_rate); -+ -+ return 0; -+} -+ -+/** -+ * dpmac_get_link_cfg() - Get Ethernet link configuration -+ * @mc_io: Pointer to opaque I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @cfg: Returned structure with the link configuration -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_get_link_cfg(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpmac_link_cfg *cfg) -+{ -+ struct dpmac_rsp_get_link_cfg *rsp_params; -+ struct mc_command cmd = { 0 }; -+ int err = 0; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_LINK_CFG, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ rsp_params = (struct dpmac_rsp_get_link_cfg *)cmd.params; -+ cfg->options = le64_to_cpu(rsp_params->options); -+ cfg->rate = le32_to_cpu(rsp_params->rate); -+ -+ return 0; -+} -+ -+/** -+ * dpmac_set_link_state() - Set the Ethernet link status -+ * @mc_io: Pointer to opaque I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @link_state: Link state configuration -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_set_link_state(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpmac_link_state *link_state) -+{ -+ struct dpmac_cmd_set_link_state *cmd_params; -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_LINK_STATE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpmac_cmd_set_link_state *)cmd.params; -+ cmd_params->options = cpu_to_le64(link_state->options); -+ cmd_params->rate = cpu_to_le32(link_state->rate); -+ cmd_params->up = dpmac_get_field(link_state->up, STATE); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpmac_get_counter() - Read a specific DPMAC counter -+ * @mc_io: Pointer to opaque I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @type: The requested counter -+ * @counter: Returned counter value -+ * -+ * Return: The requested counter; '0' otherwise. -+ */ -+int dpmac_get_counter(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ enum dpmac_counter type, -+ u64 *counter) -+{ -+ struct dpmac_cmd_get_counter *dpmac_cmd; -+ struct dpmac_rsp_get_counter *dpmac_rsp; -+ struct mc_command cmd = { 0 }; -+ int err = 0; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_COUNTER, -+ cmd_flags, -+ token); -+ dpmac_cmd = (struct dpmac_cmd_get_counter *)cmd.params; -+ dpmac_cmd->type = type; -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ dpmac_rsp = (struct dpmac_rsp_get_counter *)cmd.params; -+ *counter = le64_to_cpu(dpmac_rsp->counter); -+ -+ return 0; -+} -+ -+/* untested */ -+int dpmac_set_port_mac_addr(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const u8 addr[6]) -+{ -+ struct dpmac_cmd_set_port_mac_addr *dpmac_cmd; -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_PORT_MAC_ADDR, -+ cmd_flags, -+ token); -+ dpmac_cmd = (struct dpmac_cmd_set_port_mac_addr *)cmd.params; -+ dpmac_cmd->addr[0] = addr[5]; -+ dpmac_cmd->addr[1] = addr[4]; -+ dpmac_cmd->addr[2] = addr[3]; -+ dpmac_cmd->addr[3] = addr[2]; -+ dpmac_cmd->addr[4] = addr[1]; -+ dpmac_cmd->addr[5] = addr[0]; -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpmac_get_api_version() - Get Data Path MAC version -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @major_ver: Major version of data path mac API -+ * @minor_ver: Minor version of data path mac API -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_get_api_version(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 *major_ver, -+ u16 *minor_ver) -+{ -+ struct dpmac_rsp_get_api_version *rsp_params; -+ struct mc_command cmd = { 0 }; -+ int err; -+ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_API_VERSION, -+ cmd_flags, -+ 0); -+ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ rsp_params = (struct dpmac_rsp_get_api_version *)cmd.params; -+ *major_ver = le16_to_cpu(rsp_params->major); -+ *minor_ver = le16_to_cpu(rsp_params->minor); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/mac/dpmac.h -@@ -0,0 +1,342 @@ -+/* Copyright 2013-2016 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of the above-listed copyright holders nor the -+ * names of any contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -+ * POSSIBILITY OF SUCH DAMAGE. -+ */ -+#ifndef __FSL_DPMAC_H -+#define __FSL_DPMAC_H -+ -+/* Data Path MAC API -+ * Contains initialization APIs and runtime control APIs for DPMAC -+ */ -+ -+struct fsl_mc_io; -+ -+int dpmac_open(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ int dpmac_id, -+ u16 *token); -+ -+int dpmac_close(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token); -+ -+/** -+ * enum dpmac_link_type - DPMAC link type -+ * @DPMAC_LINK_TYPE_NONE: No link -+ * @DPMAC_LINK_TYPE_FIXED: Link is fixed type -+ * @DPMAC_LINK_TYPE_PHY: Link by PHY ID -+ * @DPMAC_LINK_TYPE_BACKPLANE: Backplane link type -+ */ -+enum dpmac_link_type { -+ DPMAC_LINK_TYPE_NONE, -+ DPMAC_LINK_TYPE_FIXED, -+ DPMAC_LINK_TYPE_PHY, -+ DPMAC_LINK_TYPE_BACKPLANE -+}; -+ -+/** -+ * enum dpmac_eth_if - DPMAC Ethrnet interface -+ * @DPMAC_ETH_IF_MII: MII interface -+ * @DPMAC_ETH_IF_RMII: RMII interface -+ * @DPMAC_ETH_IF_SMII: SMII interface -+ * @DPMAC_ETH_IF_GMII: GMII interface -+ * @DPMAC_ETH_IF_RGMII: RGMII interface -+ * @DPMAC_ETH_IF_SGMII: SGMII interface -+ * @DPMAC_ETH_IF_QSGMII: QSGMII interface -+ * @DPMAC_ETH_IF_XAUI: XAUI interface -+ * @DPMAC_ETH_IF_XFI: XFI interface -+ */ -+enum dpmac_eth_if { -+ DPMAC_ETH_IF_MII, -+ DPMAC_ETH_IF_RMII, -+ DPMAC_ETH_IF_SMII, -+ DPMAC_ETH_IF_GMII, -+ DPMAC_ETH_IF_RGMII, -+ DPMAC_ETH_IF_SGMII, -+ DPMAC_ETH_IF_QSGMII, -+ DPMAC_ETH_IF_XAUI, -+ DPMAC_ETH_IF_XFI -+}; -+ -+/** -+ * struct dpmac_cfg - Structure representing DPMAC configuration -+ * @mac_id: Represents the Hardware MAC ID; in case of multiple WRIOP, -+ * the MAC IDs are continuous. -+ * For example: 2 WRIOPs, 16 MACs in each: -+ * MAC IDs for the 1st WRIOP: 1-16, -+ * MAC IDs for the 2nd WRIOP: 17-32. -+ */ -+struct dpmac_cfg { -+ u16 mac_id; -+}; -+ -+int dpmac_create(struct fsl_mc_io *mc_io, -+ u16 dprc_token, -+ u32 cmd_flags, -+ const struct dpmac_cfg *cfg, -+ u32 *obj_id); -+ -+int dpmac_destroy(struct fsl_mc_io *mc_io, -+ u16 dprc_token, -+ u32 cmd_flags, -+ u32 object_id); -+ -+/** -+ * DPMAC IRQ Index and Events -+ */ -+ -+/** -+ * IRQ index -+ */ -+#define DPMAC_IRQ_INDEX 0 -+/** -+ * IRQ event - indicates a change in link state -+ */ -+#define DPMAC_IRQ_EVENT_LINK_CFG_REQ 0x00000001 -+/** -+ * IRQ event - Indicates that the link state changed -+ */ -+#define DPMAC_IRQ_EVENT_LINK_CHANGED 0x00000002 -+ -+int dpmac_set_irq_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u8 en); -+ -+int dpmac_get_irq_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u8 *en); -+ -+int dpmac_set_irq_mask(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 mask); -+ -+int dpmac_get_irq_mask(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 *mask); -+ -+int dpmac_get_irq_status(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 *status); -+ -+int dpmac_clear_irq_status(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 status); -+ -+/** -+ * struct dpmac_attr - Structure representing DPMAC attributes -+ * @id: DPMAC object ID -+ * @max_rate: Maximum supported rate - in Mbps -+ * @eth_if: Ethernet interface -+ * @link_type: link type -+ */ -+struct dpmac_attr { -+ u16 id; -+ u32 max_rate; -+ enum dpmac_eth_if eth_if; -+ enum dpmac_link_type link_type; -+}; -+ -+int dpmac_get_attributes(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpmac_attr *attr); -+ -+/** -+ * DPMAC link configuration/state options -+ */ -+ -+/** -+ * Enable auto-negotiation -+ */ -+#define DPMAC_LINK_OPT_AUTONEG 0x0000000000000001ULL -+/** -+ * Enable half-duplex mode -+ */ -+#define DPMAC_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL -+/** -+ * Enable pause frames -+ */ -+#define DPMAC_LINK_OPT_PAUSE 0x0000000000000004ULL -+/** -+ * Enable a-symmetric pause frames -+ */ -+#define DPMAC_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL -+ -+/** -+ * struct dpmac_link_cfg - Structure representing DPMAC link configuration -+ * @rate: Link's rate - in Mbps -+ * @options: Enable/Disable DPMAC link cfg features (bitmap) -+ */ -+struct dpmac_link_cfg { -+ u32 rate; -+ u64 options; -+}; -+ -+int dpmac_get_link_cfg(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpmac_link_cfg *cfg); -+ -+/** -+ * struct dpmac_link_state - DPMAC link configuration request -+ * @rate: Rate in Mbps -+ * @options: Enable/Disable DPMAC link cfg features (bitmap) -+ * @up: Link state -+ */ -+struct dpmac_link_state { -+ u32 rate; -+ u64 options; -+ int up; -+}; -+ -+int dpmac_set_link_state(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpmac_link_state *link_state); -+ -+/** -+ * enum dpmac_counter - DPMAC counter types -+ * @DPMAC_CNT_ING_FRAME_64: counts 64-bytes frames, good or bad. -+ * @DPMAC_CNT_ING_FRAME_127: counts 65- to 127-bytes frames, good or bad. -+ * @DPMAC_CNT_ING_FRAME_255: counts 128- to 255-bytes frames, good or bad. -+ * @DPMAC_CNT_ING_FRAME_511: counts 256- to 511-bytes frames, good or bad. -+ * @DPMAC_CNT_ING_FRAME_1023: counts 512- to 1023-bytes frames, good or bad. -+ * @DPMAC_CNT_ING_FRAME_1518: counts 1024- to 1518-bytes frames, good or bad. -+ * @DPMAC_CNT_ING_FRAME_1519_MAX: counts 1519-bytes frames and larger -+ * (up to max frame length specified), -+ * good or bad. -+ * @DPMAC_CNT_ING_FRAG: counts frames which are shorter than 64 bytes received -+ * with a wrong CRC -+ * @DPMAC_CNT_ING_JABBER: counts frames longer than the maximum frame length -+ * specified, with a bad frame check sequence. -+ * @DPMAC_CNT_ING_FRAME_DISCARD: counts dropped frames due to internal errors. -+ * Occurs when a receive FIFO overflows. -+ * Includes also frames truncated as a result of -+ * the receive FIFO overflow. -+ * @DPMAC_CNT_ING_ALIGN_ERR: counts frames with an alignment error -+ * (optional used for wrong SFD). -+ * @DPMAC_CNT_EGR_UNDERSIZED: counts frames transmitted that was less than 64 -+ * bytes long with a good CRC. -+ * @DPMAC_CNT_ING_OVERSIZED: counts frames longer than the maximum frame length -+ * specified, with a good frame check sequence. -+ * @DPMAC_CNT_ING_VALID_PAUSE_FRAME: counts valid pause frames (regular and PFC) -+ * @DPMAC_CNT_EGR_VALID_PAUSE_FRAME: counts valid pause frames transmitted -+ * (regular and PFC). -+ * @DPMAC_CNT_ING_BYTE: counts bytes received except preamble for all valid -+ * frames and valid pause frames. -+ * @DPMAC_CNT_ING_MCAST_FRAME: counts received multicast frames. -+ * @DPMAC_CNT_ING_BCAST_FRAME: counts received broadcast frames. -+ * @DPMAC_CNT_ING_ALL_FRAME: counts each good or bad frames received. -+ * @DPMAC_CNT_ING_UCAST_FRAME: counts received unicast frames. -+ * @DPMAC_CNT_ING_ERR_FRAME: counts frames received with an error -+ * (except for undersized/fragment frame). -+ * @DPMAC_CNT_EGR_BYTE: counts bytes transmitted except preamble for all valid -+ * frames and valid pause frames transmitted. -+ * @DPMAC_CNT_EGR_MCAST_FRAME: counts transmitted multicast frames. -+ * @DPMAC_CNT_EGR_BCAST_FRAME: counts transmitted broadcast frames. -+ * @DPMAC_CNT_EGR_UCAST_FRAME: counts transmitted unicast frames. -+ * @DPMAC_CNT_EGR_ERR_FRAME: counts frames transmitted with an error. -+ * @DPMAC_CNT_ING_GOOD_FRAME: counts frames received without error, including -+ * pause frames. -+ * @DPMAC_CNT_ENG_GOOD_FRAME: counts frames transmitted without error, including -+ * pause frames. -+ */ -+enum dpmac_counter { -+ DPMAC_CNT_ING_FRAME_64, -+ DPMAC_CNT_ING_FRAME_127, -+ DPMAC_CNT_ING_FRAME_255, -+ DPMAC_CNT_ING_FRAME_511, -+ DPMAC_CNT_ING_FRAME_1023, -+ DPMAC_CNT_ING_FRAME_1518, -+ DPMAC_CNT_ING_FRAME_1519_MAX, -+ DPMAC_CNT_ING_FRAG, -+ DPMAC_CNT_ING_JABBER, -+ DPMAC_CNT_ING_FRAME_DISCARD, -+ DPMAC_CNT_ING_ALIGN_ERR, -+ DPMAC_CNT_EGR_UNDERSIZED, -+ DPMAC_CNT_ING_OVERSIZED, -+ DPMAC_CNT_ING_VALID_PAUSE_FRAME, -+ DPMAC_CNT_EGR_VALID_PAUSE_FRAME, -+ DPMAC_CNT_ING_BYTE, -+ DPMAC_CNT_ING_MCAST_FRAME, -+ DPMAC_CNT_ING_BCAST_FRAME, -+ DPMAC_CNT_ING_ALL_FRAME, -+ DPMAC_CNT_ING_UCAST_FRAME, -+ DPMAC_CNT_ING_ERR_FRAME, -+ DPMAC_CNT_EGR_BYTE, -+ DPMAC_CNT_EGR_MCAST_FRAME, -+ DPMAC_CNT_EGR_BCAST_FRAME, -+ DPMAC_CNT_EGR_UCAST_FRAME, -+ DPMAC_CNT_EGR_ERR_FRAME, -+ DPMAC_CNT_ING_GOOD_FRAME, -+ DPMAC_CNT_ENG_GOOD_FRAME -+}; -+ -+int dpmac_get_counter(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ enum dpmac_counter type, -+ u64 *counter); -+ -+/** -+ * dpmac_set_port_mac_addr() - Set a MAC address associated with the physical -+ * port. This is not used for filtering, MAC is always in -+ * promiscuous mode, it is passed to DPNIs through DPNI API for -+ * application used. -+ * @mc_io: Pointer to opaque I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @addr: MAC address to set -+ * -+ * Return: The requested counter; '0' otherwise. -+ */ -+int dpmac_set_port_mac_addr(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const u8 addr[6]); -+ -+int dpmac_get_api_version(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 *major_ver, -+ u16 *minor_ver); -+ -+#endif /* __FSL_DPMAC_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0157-staging-fsl-dpaa2-mac-Add-Freescale-DPAA2-mac-driver.patch b/target/linux/layerscape/patches-5.4/701-net-0157-staging-fsl-dpaa2-mac-Add-Freescale-DPAA2-mac-driver.patch deleted file mode 100644 index 750c6ce317..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0157-staging-fsl-dpaa2-mac-Add-Freescale-DPAA2-mac-driver.patch +++ /dev/null @@ -1,765 +0,0 @@ -From 50ba3c63dc3f4fbeac32fc5675a00756723d786d Mon Sep 17 00:00:00 2001 -From: Bogdan Purcareata -Date: Wed, 12 Apr 2017 12:42:07 +0000 -Subject: [PATCH] staging: fsl-dpaa2/mac: Add Freescale DPAA2 mac driver - -Introduce the DPAA2 mac driver, which manages Datapath -Media Access Control (DPMAC) objects discovered on the -MC bus. - -This driver works as a proxy between phylib including phy -drivers and the Management Complex firmware. It receives -updates on link state changes from PHY lib and forwards -them to the Management Complex and receives interrupts -from the Management Complex whenever a request is made to -change the link state. - -This is a squashed commit containing contributions of the -following owners: -Signed-off-by: Ioana Radulescu -Signed-off-by: Alex Marginean -Signed-off-by: Bogdan Hamciuc -Signed-off-by: Razvan Stefanescu -Signed-off-by: Stuart Yoder -Signed-off-by: J. German Rivera -Signed-off-by: Itai Katz - -Signed-off-by: Bogdan Purcareata ---- - drivers/staging/fsl-dpaa2/Kconfig | 2 + - drivers/staging/fsl-dpaa2/Makefile | 1 + - drivers/staging/fsl-dpaa2/mac/Kconfig | 23 ++ - drivers/staging/fsl-dpaa2/mac/Makefile | 10 + - drivers/staging/fsl-dpaa2/mac/mac.c | 670 +++++++++++++++++++++++++++++++++ - 5 files changed, 706 insertions(+) - create mode 100644 drivers/staging/fsl-dpaa2/mac/Kconfig - create mode 100644 drivers/staging/fsl-dpaa2/mac/Makefile - create mode 100644 drivers/staging/fsl-dpaa2/mac/mac.c - ---- a/drivers/staging/fsl-dpaa2/Kconfig -+++ b/drivers/staging/fsl-dpaa2/Kconfig -@@ -17,3 +17,5 @@ config FSL_DPAA2_ETHSW - help - Driver for Freescale DPAA2 Ethernet Switch. Select - BRIDGE to have support for bridge tools. -+ -+source "drivers/staging/fsl-dpaa2/mac/Kconfig" ---- a/drivers/staging/fsl-dpaa2/Makefile -+++ b/drivers/staging/fsl-dpaa2/Makefile -@@ -4,3 +4,4 @@ - # - - obj-$(CONFIG_FSL_DPAA2_ETHSW) += ethsw/ -+obj-$(CONFIG_FSL_DPAA2_MAC) += mac/ ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/mac/Kconfig -@@ -0,0 +1,23 @@ -+config FSL_DPAA2_MAC -+ tristate "DPAA2 MAC / PHY interface" -+ depends on FSL_MC_BUS && FSL_DPAA2 -+ select MDIO_BUS_MUX_MMIOREG -+ select FSL_XGMAC_MDIO -+ select FIXED_PHY -+ ---help--- -+ Prototype driver for DPAA2 MAC / PHY interface object. -+ This driver works as a proxy between phylib including phy drivers and -+ the MC firmware. It receives updates on link state changes from PHY -+ lib and forwards them to MC and receives interrupt from MC whenever -+ a request is made to change the link state. -+ -+ -+config FSL_DPAA2_MAC_NETDEVS -+ bool "Expose net interfaces for PHYs" -+ default n -+ depends on FSL_DPAA2_MAC -+ ---help--- -+ Exposes macX net interfaces which allow direct control over MACs and -+ PHYs. -+ . -+ Leave disabled if unsure. ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/mac/Makefile -@@ -0,0 +1,10 @@ -+ -+obj-$(CONFIG_FSL_DPAA2_MAC) += dpaa2-mac.o -+ -+dpaa2-mac-objs := mac.o dpmac.o -+ -+all: -+ make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules -+ -+clean: -+ make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -0,0 +1,670 @@ -+/* Copyright 2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "../../fsl-mc/include/mc.h" -+#include "../../fsl-mc/include/mc-sys.h" -+ -+#include "dpmac.h" -+#include "dpmac-cmd.h" -+ -+struct dpaa2_mac_priv { -+ struct net_device *netdev; -+ struct fsl_mc_device *mc_dev; -+ struct dpmac_attr attr; -+ struct dpmac_link_state old_state; -+}; -+ -+/* TODO: fix the 10G modes, mapping can't be right: -+ * XGMII is paralel -+ * XAUI is serial, using 8b/10b encoding -+ * XFI is also serial but using 64b/66b encoding -+ * they can't all map to XGMII... -+ * -+ * This must be kept in sync with enum dpmac_eth_if. -+ */ -+static phy_interface_t dpaa2_mac_iface_mode[] = { -+ PHY_INTERFACE_MODE_MII, /* DPMAC_ETH_IF_MII */ -+ PHY_INTERFACE_MODE_RMII, /* DPMAC_ETH_IF_RMII */ -+ PHY_INTERFACE_MODE_SMII, /* DPMAC_ETH_IF_SMII */ -+ PHY_INTERFACE_MODE_GMII, /* DPMAC_ETH_IF_GMII */ -+ PHY_INTERFACE_MODE_RGMII, /* DPMAC_ETH_IF_RGMII */ -+ PHY_INTERFACE_MODE_SGMII, /* DPMAC_ETH_IF_SGMII */ -+ PHY_INTERFACE_MODE_QSGMII, /* DPMAC_ETH_IF_QSGMII */ -+ PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_XAUI */ -+ PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_XFI */ -+}; -+ -+static void dpaa2_mac_link_changed(struct net_device *netdev) -+{ -+ struct phy_device *phydev; -+ struct dpmac_link_state state = { 0 }; -+ struct dpaa2_mac_priv *priv = netdev_priv(netdev); -+ int err; -+ -+ /* the PHY just notified us of link state change */ -+ phydev = netdev->phydev; -+ -+ state.up = !!phydev->link; -+ if (phydev->link) { -+ state.rate = phydev->speed; -+ -+ if (!phydev->duplex) -+ state.options |= DPMAC_LINK_OPT_HALF_DUPLEX; -+ if (phydev->autoneg) -+ state.options |= DPMAC_LINK_OPT_AUTONEG; -+ -+ netif_carrier_on(netdev); -+ } else { -+ netif_carrier_off(netdev); -+ } -+ -+ if (priv->old_state.up != state.up || -+ priv->old_state.rate != state.rate || -+ priv->old_state.options != state.options) { -+ priv->old_state = state; -+ phy_print_status(phydev); -+ } -+ -+ /* We must interrogate MC at all times, because we don't know -+ * when and whether a potential DPNI may have read the link state. -+ */ -+ err = dpmac_set_link_state(priv->mc_dev->mc_io, 0, -+ priv->mc_dev->mc_handle, &state); -+ if (unlikely(err)) -+ dev_err(&priv->mc_dev->dev, "dpmac_set_link_state: %d\n", err); -+} -+ -+#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS -+static netdev_tx_t dpaa2_mac_drop_frame(struct sk_buff *skb, -+ struct net_device *dev) -+{ -+ /* we don't support I/O for now, drop the frame */ -+ dev_kfree_skb_any(skb); -+ return NETDEV_TX_OK; -+} -+ -+static int dpaa2_mac_open(struct net_device *netdev) -+{ -+ /* start PHY state machine */ -+ phy_start(netdev->phydev); -+ -+ return 0; -+} -+ -+static int dpaa2_mac_stop(struct net_device *netdev) -+{ -+ if (!netdev->phydev) -+ goto done; -+ -+ /* stop PHY state machine */ -+ phy_stop(netdev->phydev); -+ -+ /* signal link down to firmware */ -+ netdev->phydev->link = 0; -+ dpaa2_mac_link_changed(netdev); -+ -+done: -+ return 0; -+} -+ -+static int dpaa2_mac_get_settings(struct net_device *netdev, -+ struct ethtool_cmd *cmd) -+{ -+ return phy_ethtool_gset(netdev->phydev, cmd); -+} -+ -+static int dpaa2_mac_set_settings(struct net_device *netdev, -+ struct ethtool_cmd *cmd) -+{ -+ return phy_ethtool_sset(netdev->phydev, cmd); -+} -+ -+static void dpaa2_mac_get_stats(struct net_device *netdev, -+ struct rtnl_link_stats64 *storage) -+{ -+ struct dpaa2_mac_priv *priv = netdev_priv(netdev); -+ u64 tmp; -+ int err; -+ -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_EGR_MCAST_FRAME, -+ &storage->tx_packets); -+ if (err) -+ goto error; -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_EGR_BCAST_FRAME, &tmp); -+ if (err) -+ goto error; -+ storage->tx_packets += tmp; -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_EGR_UCAST_FRAME, &tmp); -+ if (err) -+ goto error; -+ storage->tx_packets += tmp; -+ -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_EGR_UNDERSIZED, &storage->tx_dropped); -+ if (err) -+ goto error; -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_EGR_BYTE, &storage->tx_bytes); -+ if (err) -+ goto error; -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_EGR_ERR_FRAME, &storage->tx_errors); -+ if (err) -+ goto error; -+ -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_ING_ALL_FRAME, &storage->rx_packets); -+ if (err) -+ goto error; -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_ING_MCAST_FRAME, &storage->multicast); -+ if (err) -+ goto error; -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_ING_FRAME_DISCARD, -+ &storage->rx_dropped); -+ if (err) -+ goto error; -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_ING_ALIGN_ERR, &storage->rx_errors); -+ if (err) -+ goto error; -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_ING_OVERSIZED, &tmp); -+ if (err) -+ goto error; -+ storage->rx_errors += tmp; -+ err = dpmac_get_counter(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle, -+ DPMAC_CNT_ING_BYTE, &storage->rx_bytes); -+ if (err) -+ goto error; -+ -+ return; -+error: -+ netdev_err(netdev, "dpmac_get_counter err %d\n", err); -+} -+ -+static struct { -+ enum dpmac_counter id; -+ char name[ETH_GSTRING_LEN]; -+} dpaa2_mac_counters[] = { -+ {DPMAC_CNT_ING_ALL_FRAME, "rx all frames"}, -+ {DPMAC_CNT_ING_GOOD_FRAME, "rx frames ok"}, -+ {DPMAC_CNT_ING_ERR_FRAME, "rx frame errors"}, -+ {DPMAC_CNT_ING_FRAME_DISCARD, "rx frame discards"}, -+ {DPMAC_CNT_ING_UCAST_FRAME, "rx u-cast"}, -+ {DPMAC_CNT_ING_BCAST_FRAME, "rx b-cast"}, -+ {DPMAC_CNT_ING_MCAST_FRAME, "rx m-cast"}, -+ {DPMAC_CNT_ING_FRAME_64, "rx 64 bytes"}, -+ {DPMAC_CNT_ING_FRAME_127, "rx 65-127 bytes"}, -+ {DPMAC_CNT_ING_FRAME_255, "rx 128-255 bytes"}, -+ {DPMAC_CNT_ING_FRAME_511, "rx 256-511 bytes"}, -+ {DPMAC_CNT_ING_FRAME_1023, "rx 512-1023 bytes"}, -+ {DPMAC_CNT_ING_FRAME_1518, "rx 1024-1518 bytes"}, -+ {DPMAC_CNT_ING_FRAME_1519_MAX, "rx 1519-max bytes"}, -+ {DPMAC_CNT_ING_FRAG, "rx frags"}, -+ {DPMAC_CNT_ING_JABBER, "rx jabber"}, -+ {DPMAC_CNT_ING_ALIGN_ERR, "rx align errors"}, -+ {DPMAC_CNT_ING_OVERSIZED, "rx oversized"}, -+ {DPMAC_CNT_ING_VALID_PAUSE_FRAME, "rx pause"}, -+ {DPMAC_CNT_ING_BYTE, "rx bytes"}, -+ {DPMAC_CNT_ENG_GOOD_FRAME, "tx frames ok"}, -+ {DPMAC_CNT_EGR_UCAST_FRAME, "tx u-cast"}, -+ {DPMAC_CNT_EGR_MCAST_FRAME, "tx m-cast"}, -+ {DPMAC_CNT_EGR_BCAST_FRAME, "tx b-cast"}, -+ {DPMAC_CNT_EGR_ERR_FRAME, "tx frame errors"}, -+ {DPMAC_CNT_EGR_UNDERSIZED, "tx undersized"}, -+ {DPMAC_CNT_EGR_VALID_PAUSE_FRAME, "tx b-pause"}, -+ {DPMAC_CNT_EGR_BYTE, "tx bytes"}, -+ -+}; -+ -+static void dpaa2_mac_get_strings(struct net_device *netdev, -+ u32 stringset, u8 *data) -+{ -+ int i; -+ -+ switch (stringset) { -+ case ETH_SS_STATS: -+ for (i = 0; i < ARRAY_SIZE(dpaa2_mac_counters); i++) -+ memcpy(data + i * ETH_GSTRING_LEN, -+ dpaa2_mac_counters[i].name, -+ ETH_GSTRING_LEN); -+ break; -+ } -+} -+ -+static void dpaa2_mac_get_ethtool_stats(struct net_device *netdev, -+ struct ethtool_stats *stats, -+ u64 *data) -+{ -+ struct dpaa2_mac_priv *priv = netdev_priv(netdev); -+ int i; -+ int err; -+ -+ for (i = 0; i < ARRAY_SIZE(dpaa2_mac_counters); i++) { -+ err = dpmac_get_counter(priv->mc_dev->mc_io, -+ 0, -+ priv->mc_dev->mc_handle, -+ dpaa2_mac_counters[i].id, &data[i]); -+ if (err) -+ netdev_err(netdev, "dpmac_get_counter[%s] err %d\n", -+ dpaa2_mac_counters[i].name, err); -+ } -+} -+ -+static int dpaa2_mac_get_sset_count(struct net_device *dev, int sset) -+{ -+ switch (sset) { -+ case ETH_SS_STATS: -+ return ARRAY_SIZE(dpaa2_mac_counters); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static const struct net_device_ops dpaa2_mac_ndo_ops = { -+ .ndo_start_xmit = &dpaa2_mac_drop_frame, -+ .ndo_open = &dpaa2_mac_open, -+ .ndo_stop = &dpaa2_mac_stop, -+ .ndo_get_stats64 = &dpaa2_mac_get_stats, -+}; -+ -+static const struct ethtool_ops dpaa2_mac_ethtool_ops = { -+ .get_settings = &dpaa2_mac_get_settings, -+ .set_settings = &dpaa2_mac_set_settings, -+ .get_strings = &dpaa2_mac_get_strings, -+ .get_ethtool_stats = &dpaa2_mac_get_ethtool_stats, -+ .get_sset_count = &dpaa2_mac_get_sset_count, -+}; -+#endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */ -+ -+static void configure_link(struct dpaa2_mac_priv *priv, -+ struct dpmac_link_cfg *cfg) -+{ -+ struct phy_device *phydev = priv->netdev->phydev; -+ -+ if (unlikely(!phydev)) -+ return; -+ -+ phydev->speed = cfg->rate; -+ phydev->duplex = !!(cfg->options & DPMAC_LINK_OPT_HALF_DUPLEX); -+ -+ if (cfg->options & DPMAC_LINK_OPT_AUTONEG) { -+ phydev->autoneg = 1; -+ phydev->advertising |= ADVERTISED_Autoneg; -+ } else { -+ phydev->autoneg = 0; -+ phydev->advertising &= ~ADVERTISED_Autoneg; -+ } -+ -+ phy_start_aneg(phydev); -+} -+ -+static irqreturn_t dpaa2_mac_irq_handler(int irq_num, void *arg) -+{ -+ struct device *dev = (struct device *)arg; -+ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); -+ struct dpaa2_mac_priv *priv = dev_get_drvdata(dev); -+ struct dpmac_link_cfg link_cfg; -+ u32 status; -+ int err; -+ -+ err = dpmac_get_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle, -+ DPMAC_IRQ_INDEX, &status); -+ if (unlikely(err || !status)) -+ return IRQ_NONE; -+ -+ /* DPNI-initiated link configuration; 'ifconfig up' also calls this */ -+ if (status & DPMAC_IRQ_EVENT_LINK_CFG_REQ) { -+ err = dpmac_get_link_cfg(mc_dev->mc_io, 0, mc_dev->mc_handle, -+ &link_cfg); -+ if (unlikely(err)) -+ goto out; -+ -+ configure_link(priv, &link_cfg); -+ } -+ -+out: -+ dpmac_clear_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle, -+ DPMAC_IRQ_INDEX, status); -+ -+ return IRQ_HANDLED; -+} -+ -+static int setup_irqs(struct fsl_mc_device *mc_dev) -+{ -+ int err = 0; -+ struct fsl_mc_device_irq *irq; -+ -+ err = fsl_mc_allocate_irqs(mc_dev); -+ if (err) { -+ dev_err(&mc_dev->dev, "fsl_mc_allocate_irqs err %d\n", err); -+ return err; -+ } -+ -+ irq = mc_dev->irqs[0]; -+ err = devm_request_threaded_irq(&mc_dev->dev, irq->msi_desc->irq, -+ NULL, &dpaa2_mac_irq_handler, -+ IRQF_NO_SUSPEND | IRQF_ONESHOT, -+ dev_name(&mc_dev->dev), &mc_dev->dev); -+ if (err) { -+ dev_err(&mc_dev->dev, "devm_request_threaded_irq err %d\n", -+ err); -+ goto free_irq; -+ } -+ -+ err = dpmac_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle, -+ DPMAC_IRQ_INDEX, DPMAC_IRQ_EVENT_LINK_CFG_REQ); -+ if (err) { -+ dev_err(&mc_dev->dev, "dpmac_set_irq_mask err %d\n", err); -+ goto free_irq; -+ } -+ err = dpmac_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle, -+ DPMAC_IRQ_INDEX, 1); -+ if (err) { -+ dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err); -+ goto free_irq; -+ } -+ -+ return 0; -+ -+free_irq: -+ fsl_mc_free_irqs(mc_dev); -+ -+ return err; -+} -+ -+static void teardown_irqs(struct fsl_mc_device *mc_dev) -+{ -+ int err; -+ -+ err = dpmac_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle, -+ DPMAC_IRQ_INDEX, 0); -+ if (err) -+ dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err); -+ -+ fsl_mc_free_irqs(mc_dev); -+} -+ -+static struct device_node *find_dpmac_node(struct device *dev, u16 dpmac_id) -+{ -+ struct device_node *dpmacs, *dpmac = NULL; -+ struct device_node *mc_node = dev->of_node; -+ u32 id; -+ int err; -+ -+ dpmacs = of_find_node_by_name(mc_node, "dpmacs"); -+ if (!dpmacs) { -+ dev_err(dev, "No dpmacs subnode in device-tree\n"); -+ return NULL; -+ } -+ -+ while ((dpmac = of_get_next_child(dpmacs, dpmac))) { -+ err = of_property_read_u32(dpmac, "reg", &id); -+ if (err) -+ continue; -+ if (id == dpmac_id) -+ return dpmac; -+ } -+ -+ return NULL; -+} -+ -+static int dpaa2_mac_probe(struct fsl_mc_device *mc_dev) -+{ -+ struct device *dev; -+ struct dpaa2_mac_priv *priv = NULL; -+ struct device_node *phy_node, *dpmac_node; -+ struct net_device *netdev; -+ phy_interface_t if_mode; -+ int err = 0; -+ -+ dev = &mc_dev->dev; -+ -+ /* prepare a net_dev structure to make the phy lib API happy */ -+ netdev = alloc_etherdev(sizeof(*priv)); -+ if (!netdev) { -+ dev_err(dev, "alloc_etherdev error\n"); -+ err = -ENOMEM; -+ goto err_exit; -+ } -+ priv = netdev_priv(netdev); -+ priv->mc_dev = mc_dev; -+ priv->netdev = netdev; -+ -+ SET_NETDEV_DEV(netdev, dev); -+ -+#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS -+ snprintf(netdev->name, IFNAMSIZ, "mac%d", mc_dev->obj_desc.id); -+#endif -+ -+ dev_set_drvdata(dev, priv); -+ -+ err = fsl_mc_portal_allocate(mc_dev, 0, &mc_dev->mc_io); -+ if (err || !mc_dev->mc_io) { -+ dev_err(dev, "fsl_mc_portal_allocate error: %d\n", err); -+ err = -ENODEV; -+ goto err_free_netdev; -+ } -+ -+ err = dpmac_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, -+ &mc_dev->mc_handle); -+ if (err || !mc_dev->mc_handle) { -+ dev_err(dev, "dpmac_open error: %d\n", err); -+ err = -ENODEV; -+ goto err_free_mcp; -+ } -+ -+ err = dpmac_get_attributes(mc_dev->mc_io, 0, -+ mc_dev->mc_handle, &priv->attr); -+ if (err) { -+ dev_err(dev, "dpmac_get_attributes err %d\n", err); -+ err = -EINVAL; -+ goto err_close; -+ } -+ -+ /* Look up the DPMAC node in the device-tree. */ -+ dpmac_node = find_dpmac_node(dev, priv->attr.id); -+ if (!dpmac_node) { -+ dev_err(dev, "No dpmac@%d subnode found.\n", priv->attr.id); -+ err = -ENODEV; -+ goto err_close; -+ } -+ -+ err = setup_irqs(mc_dev); -+ if (err) { -+ err = -EFAULT; -+ goto err_close; -+ } -+ -+#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS -+ /* OPTIONAL, register netdev just to make it visible to the user */ -+ netdev->netdev_ops = &dpaa2_mac_ndo_ops; -+ netdev->ethtool_ops = &dpaa2_mac_ethtool_ops; -+ -+ /* phy starts up enabled so netdev should be up too */ -+ netdev->flags |= IFF_UP; -+ -+ err = register_netdev(priv->netdev); -+ if (err < 0) { -+ dev_err(dev, "register_netdev error %d\n", err); -+ err = -ENODEV; -+ goto err_free_irq; -+ } -+#endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */ -+ -+ /* probe the PHY as a fixed-link if the link type declared in DPC -+ * explicitly mandates this -+ */ -+ if (priv->attr.link_type == DPMAC_LINK_TYPE_FIXED) -+ goto probe_fixed_link; -+ -+ if (priv->attr.eth_if < ARRAY_SIZE(dpaa2_mac_iface_mode)) { -+ if_mode = dpaa2_mac_iface_mode[priv->attr.eth_if]; -+ dev_dbg(dev, "\tusing if mode %s for eth_if %d\n", -+ phy_modes(if_mode), priv->attr.eth_if); -+ } else { -+ dev_warn(dev, "Unexpected interface mode %d, will probe as fixed link\n", -+ priv->attr.eth_if); -+ goto probe_fixed_link; -+ } -+ -+ /* try to connect to the PHY */ -+ phy_node = of_parse_phandle(dpmac_node, "phy-handle", 0); -+ if (!phy_node) { -+ if (!phy_node) { -+ dev_err(dev, "dpmac node has no phy-handle property\n"); -+ err = -ENODEV; -+ goto err_no_phy; -+ } -+ } -+ netdev->phydev = of_phy_connect(netdev, phy_node, -+ &dpaa2_mac_link_changed, 0, if_mode); -+ if (!netdev->phydev) { -+ /* No need for dev_err(); the kernel's loud enough as it is. */ -+ dev_dbg(dev, "Can't of_phy_connect() now.\n"); -+ /* We might be waiting for the MDIO MUX to probe, so defer -+ * our own probing. -+ */ -+ err = -EPROBE_DEFER; -+ goto err_defer; -+ } -+ dev_info(dev, "Connected to %s PHY.\n", phy_modes(if_mode)); -+ -+probe_fixed_link: -+ if (!netdev->phydev) { -+ struct fixed_phy_status status = { -+ .link = 1, -+ /* fixed-phys don't support 10Gbps speed for now */ -+ .speed = 1000, -+ .duplex = 1, -+ }; -+ -+ /* try to register a fixed link phy */ -+ netdev->phydev = fixed_phy_register(PHY_POLL, &status, NULL); -+ if (!netdev->phydev || IS_ERR(netdev->phydev)) { -+ dev_err(dev, "error trying to register fixed PHY\n"); -+ /* So we don't crash unregister_netdev() later on */ -+ netdev->phydev = NULL; -+ err = -EFAULT; -+ goto err_no_phy; -+ } -+ dev_info(dev, "Registered fixed PHY.\n"); -+ } -+ -+ /* start PHY state machine */ -+#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS -+ dpaa2_mac_open(netdev); -+#else /* CONFIG_FSL_DPAA2_MAC_NETDEVS */ -+ phy_start(netdev->phydev); -+#endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */ -+ return 0; -+ -+err_defer: -+err_no_phy: -+#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS -+ unregister_netdev(netdev); -+err_free_irq: -+#endif -+ teardown_irqs(mc_dev); -+err_close: -+ dpmac_close(mc_dev->mc_io, 0, mc_dev->mc_handle); -+err_free_mcp: -+ fsl_mc_portal_free(mc_dev->mc_io); -+err_free_netdev: -+ free_netdev(netdev); -+err_exit: -+ return err; -+} -+ -+static int dpaa2_mac_remove(struct fsl_mc_device *mc_dev) -+{ -+ struct device *dev = &mc_dev->dev; -+ struct dpaa2_mac_priv *priv = dev_get_drvdata(dev); -+ -+#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS -+ unregister_netdev(priv->netdev); -+#endif -+ teardown_irqs(priv->mc_dev); -+ dpmac_close(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle); -+ fsl_mc_portal_free(priv->mc_dev->mc_io); -+ free_netdev(priv->netdev); -+ -+ dev_set_drvdata(dev, NULL); -+ kfree(priv); -+ -+ return 0; -+} -+ -+static const struct fsl_mc_device_id dpaa2_mac_match_id_table[] = { -+ { -+ .vendor = FSL_MC_VENDOR_FREESCALE, -+ .obj_type = "dpmac", -+ }, -+ { .vendor = 0x0 } -+}; -+MODULE_DEVICE_TABLE(fslmc, dpaa2_mac_match_id_table); -+ -+static struct fsl_mc_driver dpaa2_mac_drv = { -+ .driver = { -+ .name = KBUILD_MODNAME, -+ .owner = THIS_MODULE, -+ }, -+ .probe = dpaa2_mac_probe, -+ .remove = dpaa2_mac_remove, -+ .match_id_table = dpaa2_mac_match_id_table, -+}; -+ -+module_fsl_mc_driver(dpaa2_mac_drv); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("DPAA2 PHY proxy interface driver"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0158-staging-fsl-dpaa2-mac-Remove-link-type-from-phy-sel-.patch b/target/linux/layerscape/patches-5.4/701-net-0158-staging-fsl-dpaa2-mac-Remove-link-type-from-phy-sel-.patch deleted file mode 100644 index 8a51f15b14..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0158-staging-fsl-dpaa2-mac-Remove-link-type-from-phy-sel-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 01fc2236f7fe0c094c26635e738331abec0ac103 Mon Sep 17 00:00:00 2001 -From: costi -Date: Tue, 7 Mar 2017 16:13:07 +0200 -Subject: [PATCH] staging: fsl-dpaa2/mac: Remove link type from phy sel logic - -Signed-off-by: Constantin Tudor ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 13 ++++--------- - 1 file changed, 4 insertions(+), 9 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -545,8 +545,11 @@ static int dpaa2_mac_probe(struct fsl_mc - /* probe the PHY as a fixed-link if the link type declared in DPC - * explicitly mandates this - */ -- if (priv->attr.link_type == DPMAC_LINK_TYPE_FIXED) -+ -+ phy_node = of_parse_phandle(dpmac_node, "phy-handle", 0); -+ if (!phy_node) { - goto probe_fixed_link; -+ } - - if (priv->attr.eth_if < ARRAY_SIZE(dpaa2_mac_iface_mode)) { - if_mode = dpaa2_mac_iface_mode[priv->attr.eth_if]; -@@ -559,14 +562,6 @@ static int dpaa2_mac_probe(struct fsl_mc - } - - /* try to connect to the PHY */ -- phy_node = of_parse_phandle(dpmac_node, "phy-handle", 0); -- if (!phy_node) { -- if (!phy_node) { -- dev_err(dev, "dpmac node has no phy-handle property\n"); -- err = -ENODEV; -- goto err_no_phy; -- } -- } - netdev->phydev = of_phy_connect(netdev, phy_node, - &dpaa2_mac_link_changed, 0, if_mode); - if (!netdev->phydev) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0159-staging-fsl-dpaa2-mac-Update-ethtool-ops.patch b/target/linux/layerscape/patches-5.4/701-net-0159-staging-fsl-dpaa2-mac-Update-ethtool-ops.patch deleted file mode 100644 index 5276ee1c2a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0159-staging-fsl-dpaa2-mac-Update-ethtool-ops.patch +++ /dev/null @@ -1,55 +0,0 @@ -From f964e8840c12e0659c4cfe7aa7d66b310e09ca51 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Tue, 22 Aug 2017 15:00:29 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: Update ethtool ops - -Ethtool ops get/set_settings() are deprecated, so implement -get/set_link_ksettings() instead. - -These now call the corresponding phy_ethtool_ksettings_* -generic functions, as the old ones also got deprecated -and removed from the kernel entirely. - -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 18 ++++++++++-------- - 1 file changed, 10 insertions(+), 8 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -152,16 +152,18 @@ done: - return 0; - } - --static int dpaa2_mac_get_settings(struct net_device *netdev, -- struct ethtool_cmd *cmd) -+static int dpaa2_mac_get_link_ksettings(struct net_device *netdev, -+ struct ethtool_link_ksettings *ks) - { -- return phy_ethtool_gset(netdev->phydev, cmd); -+ phy_ethtool_ksettings_get(netdev->phydev, ks); -+ -+ return 0; - } - --static int dpaa2_mac_set_settings(struct net_device *netdev, -- struct ethtool_cmd *cmd) -+static int dpaa2_mac_set_link_ksettings(struct net_device *netdev, -+ const struct ethtool_link_ksettings *ks) - { -- return phy_ethtool_sset(netdev->phydev, cmd); -+ return phy_ethtool_ksettings_set(netdev->phydev, ks); - } - - static void dpaa2_mac_get_stats(struct net_device *netdev, -@@ -319,8 +321,8 @@ static const struct net_device_ops dpaa2 - }; - - static const struct ethtool_ops dpaa2_mac_ethtool_ops = { -- .get_settings = &dpaa2_mac_get_settings, -- .set_settings = &dpaa2_mac_set_settings, -+ .get_link_ksettings = &dpaa2_mac_get_link_ksettings, -+ .set_link_ksettings = &dpaa2_mac_set_link_ksettings, - .get_strings = &dpaa2_mac_get_strings, - .get_ethtool_stats = &dpaa2_mac_get_ethtool_stats, - .get_sset_count = &dpaa2_mac_get_sset_count, diff --git a/target/linux/layerscape/patches-5.4/701-net-0160-staging-fsl-dpaa2-mac-Comply-with-mc-bus-header-upda.patch b/target/linux/layerscape/patches-5.4/701-net-0160-staging-fsl-dpaa2-mac-Comply-with-mc-bus-header-upda.patch deleted file mode 100644 index 7b101f2ec8..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0160-staging-fsl-dpaa2-mac-Comply-with-mc-bus-header-upda.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ed2efc45fb3130739ac3d9578054c67ee8ec6470 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 23 Aug 2017 17:51:23 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: Comply with mc bus header updates - -The fsl-mc bus driver reorganized some of its headers, so -update our includes accordingly. - -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/dpmac.c | 3 +-- - drivers/staging/fsl-dpaa2/mac/mac.c | 1 - - 2 files changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/dpmac.c -+++ b/drivers/staging/fsl-dpaa2/mac/dpmac.c -@@ -29,8 +29,7 @@ - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ --#include "../../fsl-mc/include/mc-sys.h" --#include "../../fsl-mc/include/mc-cmd.h" -+#include "../../fsl-mc/include/mc.h" - #include "dpmac.h" - #include "dpmac-cmd.h" - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -47,7 +47,6 @@ - #include - - #include "../../fsl-mc/include/mc.h" --#include "../../fsl-mc/include/mc-sys.h" - - #include "dpmac.h" - #include "dpmac-cmd.h" diff --git a/target/linux/layerscape/patches-5.4/701-net-0161-staging-fsl-dpaa2-mac-Request-atomic-context-MC-port.patch b/target/linux/layerscape/patches-5.4/701-net-0161-staging-fsl-dpaa2-mac-Request-atomic-context-MC-port.patch deleted file mode 100644 index 95d0fb6fbe..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0161-staging-fsl-dpaa2-mac-Request-atomic-context-MC-port.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 001bad547937cdd667adee45b5c7ebe78a1de1d0 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Fri, 22 Sep 2017 12:20:02 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: Request atomic context MC portals - -The MAC driver may need to issue MC commands while in atomic -context (e.g. dpaa2_mac_get_stats can be called from a critical -section), so we need to use MC portals that don't sleep while -waiting for a command response to arrive. - -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -490,7 +490,9 @@ static int dpaa2_mac_probe(struct fsl_mc - - dev_set_drvdata(dev, priv); - -- err = fsl_mc_portal_allocate(mc_dev, 0, &mc_dev->mc_io); -+ /* We may need to issue MC commands while in atomic context */ -+ err = fsl_mc_portal_allocate(mc_dev, FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, -+ &mc_dev->mc_io); - if (err || !mc_dev->mc_io) { - dev_err(dev, "fsl_mc_portal_allocate error: %d\n", err); - err = -ENODEV; diff --git a/target/linux/layerscape/patches-5.4/701-net-0162-staging-fsl-dpaa2-mac-Remove-redundant-free.patch b/target/linux/layerscape/patches-5.4/701-net-0162-staging-fsl-dpaa2-mac-Remove-redundant-free.patch deleted file mode 100644 index 30a85abbd5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0162-staging-fsl-dpaa2-mac-Remove-redundant-free.patch +++ /dev/null @@ -1,24 +0,0 @@ -From c21f8562457b994b7e4ba46cba9fd05dc0e25e20 Mon Sep 17 00:00:00 2001 -From: Bogdan Purcareata -Date: Thu, 28 Sep 2017 10:58:24 +0000 -Subject: [PATCH] staging: fsl-dpaa2/mac: Remove redundant free - -free_netdev (put_device) already handles freeing the private data -structure, and KASAN will complain due to a free after free if we -explicitly do the same afterwards. - -Signed-off-by: Bogdan Purcareata ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -638,7 +638,6 @@ static int dpaa2_mac_remove(struct fsl_m - free_netdev(priv->netdev); - - dev_set_drvdata(dev, NULL); -- kfree(priv); - - return 0; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0163-staging-fsl-dpaa2-mac-Cleanup-code.patch b/target/linux/layerscape/patches-5.4/701-net-0163-staging-fsl-dpaa2-mac-Cleanup-code.patch deleted file mode 100644 index 7aa7b281d9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0163-staging-fsl-dpaa2-mac-Cleanup-code.patch +++ /dev/null @@ -1,89 +0,0 @@ -From c2dfd6095bd7f812c9a1aa4d381022579702af4d Mon Sep 17 00:00:00 2001 -From: Bogdan Purcareata -Date: Thu, 5 Oct 2017 08:05:55 +0000 -Subject: [PATCH] staging: fsl-dpaa2/mac: Cleanup code - -- move dpaa2_mac_open and dpaa2_mac_stop out of - CONFIG_FSL_DPAA2_MAC_NETDEVS, since their implementation is necessary - regardless of it -- reorder ndo ops to match function implementation order -- update comment to describe the phy connection mode that's to be used - - it no longer depends on DPC, but on the device tree - -Signed-off-by: Bogdan Purcareata ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 31 +++++++++++++------------------ - 1 file changed, 13 insertions(+), 18 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -118,15 +118,6 @@ static void dpaa2_mac_link_changed(struc - dev_err(&priv->mc_dev->dev, "dpmac_set_link_state: %d\n", err); - } - --#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS --static netdev_tx_t dpaa2_mac_drop_frame(struct sk_buff *skb, -- struct net_device *dev) --{ -- /* we don't support I/O for now, drop the frame */ -- dev_kfree_skb_any(skb); -- return NETDEV_TX_OK; --} -- - static int dpaa2_mac_open(struct net_device *netdev) - { - /* start PHY state machine */ -@@ -151,6 +142,15 @@ done: - return 0; - } - -+#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS -+static netdev_tx_t dpaa2_mac_drop_frame(struct sk_buff *skb, -+ struct net_device *dev) -+{ -+ /* we don't support I/O for now, drop the frame */ -+ dev_kfree_skb_any(skb); -+ return NETDEV_TX_OK; -+} -+ - static int dpaa2_mac_get_link_ksettings(struct net_device *netdev, - struct ethtool_link_ksettings *ks) - { -@@ -313,9 +313,9 @@ static int dpaa2_mac_get_sset_count(stru - } - - static const struct net_device_ops dpaa2_mac_ndo_ops = { -- .ndo_start_xmit = &dpaa2_mac_drop_frame, - .ndo_open = &dpaa2_mac_open, - .ndo_stop = &dpaa2_mac_stop, -+ .ndo_start_xmit = &dpaa2_mac_drop_frame, - .ndo_get_stats64 = &dpaa2_mac_get_stats, - }; - -@@ -545,10 +545,9 @@ static int dpaa2_mac_probe(struct fsl_mc - } - #endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */ - -- /* probe the PHY as a fixed-link if the link type declared in DPC -- * explicitly mandates this -+ /* probe the PHY as a fixed-link if there's a phy-handle defined -+ * in the device tree - */ -- - phy_node = of_parse_phandle(dpmac_node, "phy-handle", 0); - if (!phy_node) { - goto probe_fixed_link; -@@ -599,12 +598,8 @@ probe_fixed_link: - dev_info(dev, "Registered fixed PHY.\n"); - } - -- /* start PHY state machine */ --#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS - dpaa2_mac_open(netdev); --#else /* CONFIG_FSL_DPAA2_MAC_NETDEVS */ -- phy_start(netdev->phydev); --#endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */ -+ - return 0; - - err_defer: diff --git a/target/linux/layerscape/patches-5.4/701-net-0164-staging-fsl-dpaa2-mac-Free-phydev-on-unbind.patch b/target/linux/layerscape/patches-5.4/701-net-0164-staging-fsl-dpaa2-mac-Free-phydev-on-unbind.patch deleted file mode 100644 index 62cce28fee..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0164-staging-fsl-dpaa2-mac-Free-phydev-on-unbind.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 665b0217a4c99c14b680878f87bfa83c664de737 Mon Sep 17 00:00:00 2001 -From: Bogdan Purcareata -Date: Thu, 28 Sep 2017 11:07:33 +0000 -Subject: [PATCH] staging: fsl-dpaa2/mac: Free phydev on unbind - -Stop polling and unregister / disconnect the phydev structure on DPAA2 -mac driver unbind. - -Signed-off-by: Bogdan Purcareata ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -623,6 +623,15 @@ static int dpaa2_mac_remove(struct fsl_m - { - struct device *dev = &mc_dev->dev; - struct dpaa2_mac_priv *priv = dev_get_drvdata(dev); -+ struct net_device *netdev = priv->netdev; -+ -+ dpaa2_mac_stop(netdev); -+ -+ if (phy_is_pseudo_fixed_link(netdev->phydev)) -+ fixed_phy_unregister(netdev->phydev); -+ else -+ phy_disconnect(netdev->phydev); -+ netdev->phydev = NULL; - - #ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS - unregister_netdev(priv->netdev); diff --git a/target/linux/layerscape/patches-5.4/701-net-0165-staging-fsl-dpaa2-mac-defer-probe-if-no-mc-portal-is.patch b/target/linux/layerscape/patches-5.4/701-net-0165-staging-fsl-dpaa2-mac-defer-probe-if-no-mc-portal-is.patch deleted file mode 100644 index 083e7427ad..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0165-staging-fsl-dpaa2-mac-defer-probe-if-no-mc-portal-is.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 8bfccd1f7b096d5e5a6db2cda9d5e983b4422da2 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 29 Nov 2017 17:39:05 +0200 -Subject: [PATCH] staging: fsl-dpaa2/mac: defer probe if no mc portal is found - -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -494,8 +494,8 @@ static int dpaa2_mac_probe(struct fsl_mc - err = fsl_mc_portal_allocate(mc_dev, FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, - &mc_dev->mc_io); - if (err || !mc_dev->mc_io) { -- dev_err(dev, "fsl_mc_portal_allocate error: %d\n", err); -- err = -ENODEV; -+ dev_dbg(dev, "fsl_mc_portal_allocate error: %d\n", err); -+ err = -EPROBE_DEFER; - goto err_free_netdev; - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0166-staging-fsl-dpaa2-mac-make-compatible-with-upstream-.patch b/target/linux/layerscape/patches-5.4/701-net-0166-staging-fsl-dpaa2-mac-make-compatible-with-upstream-.patch deleted file mode 100644 index d2e5bf4544..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0166-staging-fsl-dpaa2-mac-make-compatible-with-upstream-.patch +++ /dev/null @@ -1,180 +0,0 @@ -From 642686661c3324b4ae6c14f1cdbd2ea613525f09 Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Fri, 13 Apr 2018 09:57:12 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: make compatible with upstream MC bus - -Update the mc.h include path. -Rename struct mc_command to struct fsl_mc_command. - -Signed-off-by: Razvan Stefanescu ---- - drivers/staging/fsl-dpaa2/mac/dpmac.c | 34 +++++++++++++++++----------------- - drivers/staging/fsl-dpaa2/mac/mac.c | 2 +- - 2 files changed, 18 insertions(+), 18 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/dpmac.c -+++ b/drivers/staging/fsl-dpaa2/mac/dpmac.c -@@ -29,7 +29,7 @@ - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ --#include "../../fsl-mc/include/mc.h" -+#include - #include "dpmac.h" - #include "dpmac-cmd.h" - -@@ -56,7 +56,7 @@ int dpmac_open(struct fsl_mc_io *mc_io, - u16 *token) - { - struct dpmac_cmd_open *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - int err; - - /* prepare command */ -@@ -92,7 +92,7 @@ int dpmac_close(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLOSE, cmd_flags, -@@ -128,7 +128,7 @@ int dpmac_create(struct fsl_mc_io *mc_io - u32 *obj_id) - { - struct dpmac_cmd_create *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - int err; - - /* prepare command */ -@@ -170,7 +170,7 @@ int dpmac_destroy(struct fsl_mc_io *mc_i - u32 object_id) - { - struct dpmac_cmd_destroy *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMAC_CMDID_DESTROY, -@@ -205,7 +205,7 @@ int dpmac_set_irq_enable(struct fsl_mc_i - u8 en) - { - struct dpmac_cmd_set_irq_enable *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_IRQ_ENABLE, -@@ -237,7 +237,7 @@ int dpmac_get_irq_enable(struct fsl_mc_i - { - struct dpmac_cmd_get_irq_enable *cmd_params; - struct dpmac_rsp_get_irq_enable *rsp_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - int err; - - /* prepare command */ -@@ -282,7 +282,7 @@ int dpmac_set_irq_mask(struct fsl_mc_io - u32 mask) - { - struct dpmac_cmd_set_irq_mask *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_IRQ_MASK, -@@ -317,7 +317,7 @@ int dpmac_get_irq_mask(struct fsl_mc_io - { - struct dpmac_cmd_get_irq_mask *cmd_params; - struct dpmac_rsp_get_irq_mask *rsp_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - int err; - - /* prepare command */ -@@ -360,7 +360,7 @@ int dpmac_get_irq_status(struct fsl_mc_i - { - struct dpmac_cmd_get_irq_status *cmd_params; - struct dpmac_rsp_get_irq_status *rsp_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - int err; - - /* prepare command */ -@@ -403,7 +403,7 @@ int dpmac_clear_irq_status(struct fsl_mc - u32 status) - { - struct dpmac_cmd_clear_irq_status *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLEAR_IRQ_STATUS, -@@ -433,7 +433,7 @@ int dpmac_get_attributes(struct fsl_mc_i - struct dpmac_attr *attr) - { - struct dpmac_rsp_get_attributes *rsp_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - int err; - - /* prepare command */ -@@ -471,7 +471,7 @@ int dpmac_get_link_cfg(struct fsl_mc_io - struct dpmac_link_cfg *cfg) - { - struct dpmac_rsp_get_link_cfg *rsp_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - int err = 0; - - /* prepare command */ -@@ -506,7 +506,7 @@ int dpmac_set_link_state(struct fsl_mc_i - struct dpmac_link_state *link_state) - { - struct dpmac_cmd_set_link_state *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_LINK_STATE, -@@ -539,7 +539,7 @@ int dpmac_get_counter(struct fsl_mc_io * - { - struct dpmac_cmd_get_counter *dpmac_cmd; - struct dpmac_rsp_get_counter *dpmac_rsp; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - int err = 0; - - /* prepare command */ -@@ -567,7 +567,7 @@ int dpmac_set_port_mac_addr(struct fsl_m - const u8 addr[6]) - { - struct dpmac_cmd_set_port_mac_addr *dpmac_cmd; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_PORT_MAC_ADDR, -@@ -600,7 +600,7 @@ int dpmac_get_api_version(struct fsl_mc_ - u16 *minor_ver) - { - struct dpmac_rsp_get_api_version *rsp_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - int err; - - cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_API_VERSION, ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -46,7 +46,7 @@ - #include - #include - --#include "../../fsl-mc/include/mc.h" -+#include - - #include "dpmac.h" - #include "dpmac-cmd.h" diff --git a/target/linux/layerscape/patches-5.4/701-net-0167-staging-fsl-dpaa2-mac-probe-phy-as-fixed-link-based-.patch b/target/linux/layerscape/patches-5.4/701-net-0167-staging-fsl-dpaa2-mac-probe-phy-as-fixed-link-based-.patch deleted file mode 100644 index f46bfeec98..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0167-staging-fsl-dpaa2-mac-probe-phy-as-fixed-link-based-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From fc7b4295a24771be99eb1afb374608562706f4d8 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Thu, 18 Oct 2018 20:02:44 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: probe phy as fixed link based on - dpmac properties - -Keep in sync the PHY type settings in DPC and Linux device tree. - -If the dpmac is connected to a fixed link PHY based on dpc config, -treat it as a fixed-link device, regardless of whether the "phy-handle" -property is present in the device tree node or not. - -Signed-off-by: Pankaj Bansal -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -545,9 +545,11 @@ static int dpaa2_mac_probe(struct fsl_mc - } - #endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */ - -- /* probe the PHY as a fixed-link if there's a phy-handle defined -- * in the device tree -- */ -+ /* probe the PHY as fixed-link if the DPMAC attribute indicates so */ -+ if (priv->attr.link_type == DPMAC_LINK_TYPE_FIXED) -+ goto probe_fixed_link; -+ -+ /* or if there's no phy-handle defined in the device tree */ - phy_node = of_parse_phandle(dpmac_node, "phy-handle", 0); - if (!phy_node) { - goto probe_fixed_link; diff --git a/target/linux/layerscape/patches-5.4/701-net-0168-staging-fsl-dpaa2-mac-Fix-uninitialized-variable.patch b/target/linux/layerscape/patches-5.4/701-net-0168-staging-fsl-dpaa2-mac-Fix-uninitialized-variable.patch deleted file mode 100644 index 6cad0a94e8..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0168-staging-fsl-dpaa2-mac-Fix-uninitialized-variable.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 8d1d6c6778c00d47eee8073bb991c6799d757c35 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Fri, 19 Oct 2018 17:00:17 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: Fix uninitialized variable - -Reported by coverity. - -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -355,7 +355,7 @@ static irqreturn_t dpaa2_mac_irq_handler - struct device *dev = (struct device *)arg; - struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); - struct dpaa2_mac_priv *priv = dev_get_drvdata(dev); -- struct dpmac_link_cfg link_cfg; -+ struct dpmac_link_cfg link_cfg = { 0 }; - u32 status; - int err; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0169-staging-fsl-dpaa2-mac-read-phy-mode-from-device-tree.patch b/target/linux/layerscape/patches-5.4/701-net-0169-staging-fsl-dpaa2-mac-read-phy-mode-from-device-tree.patch deleted file mode 100644 index 1833319da6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0169-staging-fsl-dpaa2-mac-read-phy-mode-from-device-tree.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 781d22f6cf6aded86e80be995b5c875c61512567 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Thu, 18 Oct 2018 20:12:38 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: read phy mode from device tree - -If the a dpmac node defines its phy mode in the device tree using -the 'phy-mode' or the 'phy-connection-type' attributes this will take -precedence over the interface mode reported by the MC in the -dpmac attributes structure. - -Signed-off-by: Ioana Ciornei -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -466,7 +466,7 @@ static int dpaa2_mac_probe(struct fsl_mc - struct dpaa2_mac_priv *priv = NULL; - struct device_node *phy_node, *dpmac_node; - struct net_device *netdev; -- phy_interface_t if_mode; -+ int if_mode; - int err = 0; - - dev = &mc_dev->dev; -@@ -555,6 +555,13 @@ static int dpaa2_mac_probe(struct fsl_mc - goto probe_fixed_link; - } - -+ if_mode = of_get_phy_mode(dpmac_node); -+ if (if_mode >= 0) { -+ dev_dbg(dev, "\tusing if mode %s for eth_if %d\n", -+ phy_modes(if_mode), priv->attr.eth_if); -+ goto phy_connect; -+ } -+ - if (priv->attr.eth_if < ARRAY_SIZE(dpaa2_mac_iface_mode)) { - if_mode = dpaa2_mac_iface_mode[priv->attr.eth_if]; - dev_dbg(dev, "\tusing if mode %s for eth_if %d\n", -@@ -565,6 +572,7 @@ static int dpaa2_mac_probe(struct fsl_mc - goto probe_fixed_link; - } - -+phy_connect: - /* try to connect to the PHY */ - netdev->phydev = of_phy_connect(netdev, phy_node, - &dpaa2_mac_link_changed, 0, if_mode); diff --git a/target/linux/layerscape/patches-5.4/701-net-0170-staging-fsl-dpaa2-mac-Add-more-PHY-modes.patch b/target/linux/layerscape/patches-5.4/701-net-0170-staging-fsl-dpaa2-mac-Add-more-PHY-modes.patch deleted file mode 100644 index 376b508d1d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0170-staging-fsl-dpaa2-mac-Add-more-PHY-modes.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 8b85f5295ffa083516fc496343d4328cf1deb605 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Fri, 19 Oct 2018 13:22:12 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: Add more PHY modes - -Add support for CAUI, USXGMII and 1000BASE-X. - -Signed-off-by: Florin Chiculita -Signed-off-by: Valentin Catalin Neacsu -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -76,6 +76,9 @@ static phy_interface_t dpaa2_mac_iface_m - PHY_INTERFACE_MODE_QSGMII, /* DPMAC_ETH_IF_QSGMII */ - PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_XAUI */ - PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_XFI */ -+ PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_CAUI */ -+ PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_1000BASEX */ -+ PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_USXGMII */ - }; - - static void dpaa2_mac_link_changed(struct net_device *netdev) diff --git a/target/linux/layerscape/patches-5.4/701-net-0171-staging-fsl-dpaa2-mac-Check-DPMAC-version.patch b/target/linux/layerscape/patches-5.4/701-net-0171-staging-fsl-dpaa2-mac-Check-DPMAC-version.patch deleted file mode 100644 index ca3506b0db..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0171-staging-fsl-dpaa2-mac-Check-DPMAC-version.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 2dc96021dc08d24eed822f66cb8fb5a454fee236 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Fri, 19 Oct 2018 16:20:07 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: Check DPMAC version - -Read the current API version exposed by the DPMAC object. -Add a check at probe time to make sure it is compatible with -the set of MC commands we intend to use on it. -Also, print the version number through ethtool driver info. - -Signed-off-by: Catalin Neacsu -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 39 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 39 insertions(+) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -56,6 +56,8 @@ struct dpaa2_mac_priv { - struct fsl_mc_device *mc_dev; - struct dpmac_attr attr; - struct dpmac_link_state old_state; -+ u16 dpmac_ver_major; -+ u16 dpmac_ver_minor; - }; - - /* TODO: fix the 10G modes, mapping can't be right: -@@ -81,6 +83,14 @@ static phy_interface_t dpaa2_mac_iface_m - PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_USXGMII */ - }; - -+static int cmp_dpmac_ver(struct dpaa2_mac_priv *priv, -+ u16 ver_major, u16 ver_minor) -+{ -+ if (priv->dpmac_ver_major == ver_major) -+ return priv->dpmac_ver_minor - ver_minor; -+ return priv->dpmac_ver_major - ver_major; -+} -+ - static void dpaa2_mac_link_changed(struct net_device *netdev) - { - struct phy_device *phydev; -@@ -154,6 +164,18 @@ static netdev_tx_t dpaa2_mac_drop_frame( - return NETDEV_TX_OK; - } - -+static void dpaa2_mac_get_drvinfo(struct net_device *net_dev, -+ struct ethtool_drvinfo *drvinfo) -+{ -+ struct dpaa2_mac_priv *priv = netdev_priv(net_dev); -+ -+ strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); -+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), -+ "%u.%u", priv->dpmac_ver_major, priv->dpmac_ver_minor); -+ strlcpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent), -+ sizeof(drvinfo->bus_info)); -+} -+ - static int dpaa2_mac_get_link_ksettings(struct net_device *netdev, - struct ethtool_link_ksettings *ks) - { -@@ -323,6 +345,7 @@ static const struct net_device_ops dpaa2 - }; - - static const struct ethtool_ops dpaa2_mac_ethtool_ops = { -+ .get_drvinfo = &dpaa2_mac_get_drvinfo, - .get_link_ksettings = &dpaa2_mac_get_link_ksettings, - .set_link_ksettings = &dpaa2_mac_set_link_ksettings, - .get_strings = &dpaa2_mac_get_strings, -@@ -510,6 +533,21 @@ static int dpaa2_mac_probe(struct fsl_mc - goto err_free_mcp; - } - -+ err = dpmac_get_api_version(mc_dev->mc_io, 0, &priv->dpmac_ver_major, -+ &priv->dpmac_ver_minor); -+ if (err) { -+ dev_err(dev, "dpmac_get_api_version failed\n"); -+ goto err_version; -+ } -+ -+ if (cmp_dpmac_ver(priv, DPMAC_VER_MAJOR, DPMAC_VER_MINOR) < 0) { -+ dev_err(dev, "DPMAC version %u.%u lower than supported %u.%u\n", -+ priv->dpmac_ver_major, priv->dpmac_ver_minor, -+ DPMAC_VER_MAJOR, DPMAC_VER_MINOR); -+ err = -ENOTSUPP; -+ goto err_version; -+ } -+ - err = dpmac_get_attributes(mc_dev->mc_io, 0, - mc_dev->mc_handle, &priv->attr); - if (err) { -@@ -622,6 +660,7 @@ err_no_phy: - err_free_irq: - #endif - teardown_irqs(mc_dev); -+err_version: - err_close: - dpmac_close(mc_dev->mc_io, 0, mc_dev->mc_handle); - err_free_mcp: diff --git a/target/linux/layerscape/patches-5.4/701-net-0172-staging-fsl-dpaa2-mac-Fix-dpmac_set_link_state-comma.patch b/target/linux/layerscape/patches-5.4/701-net-0172-staging-fsl-dpaa2-mac-Fix-dpmac_set_link_state-comma.patch deleted file mode 100644 index 867dbf1af0..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0172-staging-fsl-dpaa2-mac-Fix-dpmac_set_link_state-comma.patch +++ /dev/null @@ -1,24 +0,0 @@ -From c27bca038be891762760c5e4b3a79368c663b47b Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Fri, 19 Oct 2018 17:45:50 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: Fix dpmac_set_link_state() command - -The instruction writing link state value in the MC command -structure wasn't correct, but it happened to work nonetheless. - -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/dpmac.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/fsl-dpaa2/mac/dpmac.c -+++ b/drivers/staging/fsl-dpaa2/mac/dpmac.c -@@ -515,7 +515,7 @@ int dpmac_set_link_state(struct fsl_mc_i - cmd_params = (struct dpmac_cmd_set_link_state *)cmd.params; - cmd_params->options = cpu_to_le64(link_state->options); - cmd_params->rate = cpu_to_le32(link_state->rate); -- cmd_params->up = dpmac_get_field(link_state->up, STATE); -+ dpmac_set_field(cmd_params->up, STATE, link_state->up); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); diff --git a/target/linux/layerscape/patches-5.4/701-net-0173-staging-fsl-dpaa2-mac-Add-support-for-new-link-state.patch b/target/linux/layerscape/patches-5.4/701-net-0173-staging-fsl-dpaa2-mac-Add-support-for-new-link-state.patch deleted file mode 100644 index 601a4bf6aa..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0173-staging-fsl-dpaa2-mac-Add-support-for-new-link-state.patch +++ /dev/null @@ -1,235 +0,0 @@ -From d84bd24a4d6e5b05f7eb1a544dfd0bd98c7f5bb1 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 17 Oct 2018 20:14:24 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: Add support for new link state APIs - -Add v2 of dpmac_set_link_state() and dpmac_get_link_cfg() commands. -The new version allows setting & getting advertised and supported -link options. - -Signed-off-by: Valentin Catalin Neacsu -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h | 24 +++++++++++ - drivers/staging/fsl-dpaa2/mac/dpmac.c | 70 +++++++++++++++++++++++++++++++ - drivers/staging/fsl-dpaa2/mac/dpmac.h | 32 ++++++++++++++ - 3 files changed, 126 insertions(+) - ---- a/drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h -+++ b/drivers/staging/fsl-dpaa2/mac/dpmac-cmd.h -@@ -36,9 +36,11 @@ - #define DPMAC_VER_MAJOR 4 - #define DPMAC_VER_MINOR 2 - #define DPMAC_CMD_BASE_VERSION 1 -+#define DPMAC_CMD_2ND_VERSION 2 - #define DPMAC_CMD_ID_OFFSET 4 - - #define DPMAC_CMD(id) (((id) << DPMAC_CMD_ID_OFFSET) | DPMAC_CMD_BASE_VERSION) -+#define DPMAC_CMD_V2(id) (((id) << DPMAC_CMD_ID_OFFSET) | DPMAC_CMD_2ND_VERSION) - - /* Command IDs */ - #define DPMAC_CMDID_CLOSE DPMAC_CMD(0x800) -@@ -58,7 +60,9 @@ - #define DPMAC_CMDID_CLEAR_IRQ_STATUS DPMAC_CMD(0x017) - - #define DPMAC_CMDID_GET_LINK_CFG DPMAC_CMD(0x0c2) -+#define DPMAC_CMDID_GET_LINK_CFG_V2 DPMAC_CMD_V2(0x0c2) - #define DPMAC_CMDID_SET_LINK_STATE DPMAC_CMD(0x0c3) -+#define DPMAC_CMDID_SET_LINK_STATE_V2 DPMAC_CMD_V2(0x0c3) - #define DPMAC_CMDID_GET_COUNTER DPMAC_CMD(0x0c4) - - #define DPMAC_CMDID_SET_PORT_MAC_ADDR DPMAC_CMD(0x0c5) -@@ -139,8 +143,17 @@ struct dpmac_rsp_get_link_cfg { - u32 rate; - }; - -+struct dpmac_rsp_get_link_cfg_v2 { -+ u64 options; -+ u32 rate; -+ u32 pad; -+ u64 advertising; -+}; -+ - #define DPMAC_STATE_SIZE 1 - #define DPMAC_STATE_SHIFT 0 -+#define DPMAC_STATE_VALID_SIZE 1 -+#define DPMAC_STATE_VALID_SHIFT 1 - - struct dpmac_cmd_set_link_state { - u64 options; -@@ -150,6 +163,17 @@ struct dpmac_cmd_set_link_state { - u8 up; - }; - -+struct dpmac_cmd_set_link_state_v2 { -+ u64 options; -+ u32 rate; -+ u32 pad0; -+ /* from lsb: up:1, state_valid:1 */ -+ u8 state; -+ u8 pad1[7]; -+ u64 supported; -+ u64 advertising; -+}; -+ - struct dpmac_cmd_get_counter { - u8 type; - }; ---- a/drivers/staging/fsl-dpaa2/mac/dpmac.c -+++ b/drivers/staging/fsl-dpaa2/mac/dpmac.c -@@ -492,6 +492,42 @@ int dpmac_get_link_cfg(struct fsl_mc_io - } - - /** -+ * dpmac_get_link_cfg_v2() - Get Ethernet link configuration -+ * @mc_io: Pointer to opaque I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @cfg: Returned structure with the link configuration -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_get_link_cfg_v2(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpmac_link_cfg *cfg) -+{ -+ struct dpmac_rsp_get_link_cfg_v2 *rsp_params; -+ struct fsl_mc_command cmd = { 0 }; -+ int err = 0; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_LINK_CFG_V2, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ rsp_params = (struct dpmac_rsp_get_link_cfg_v2 *)cmd.params; -+ cfg->options = le64_to_cpu(rsp_params->options); -+ cfg->rate = le32_to_cpu(rsp_params->rate); -+ cfg->advertising = le64_to_cpu(rsp_params->advertising); -+ -+ return 0; -+} -+ -+/** - * dpmac_set_link_state() - Set the Ethernet link status - * @mc_io: Pointer to opaque I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -@@ -519,6 +555,40 @@ int dpmac_set_link_state(struct fsl_mc_i - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpmac_set_link_state_v2() - Set the Ethernet link status -+ * @mc_io: Pointer to opaque I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPMAC object -+ * @link_state: Link state configuration -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpmac_set_link_state_v2(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpmac_link_state *link_state) -+{ -+ struct dpmac_cmd_set_link_state_v2 *cmd_params; -+ struct fsl_mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_LINK_STATE_V2, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpmac_cmd_set_link_state_v2 *)cmd.params; -+ cmd_params->options = cpu_to_le64(link_state->options); -+ cmd_params->rate = cpu_to_le32(link_state->rate); -+ dpmac_set_field(cmd_params->state, STATE, link_state->up); -+ dpmac_set_field(cmd_params->state, STATE_VALID, -+ link_state->state_valid); -+ cmd_params->supported = cpu_to_le64(link_state->supported); -+ cmd_params->advertising = cpu_to_le64(link_state->advertising); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); - } - - /** ---- a/drivers/staging/fsl-dpaa2/mac/dpmac.h -+++ b/drivers/staging/fsl-dpaa2/mac/dpmac.h -@@ -202,13 +202,29 @@ int dpmac_get_attributes(struct fsl_mc_i - #define DPMAC_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL - - /** -+ * Advertised link speeds -+ */ -+#define DPMAC_ADVERTISED_10BASET_FULL 0x0000000000000001ULL -+#define DPMAC_ADVERTISED_100BASET_FULL 0x0000000000000002ULL -+#define DPMAC_ADVERTISED_1000BASET_FULL 0x0000000000000004ULL -+#define DPMAC_ADVERTISED_10000BASET_FULL 0x0000000000000010ULL -+#define DPMAC_ADVERTISED_2500BASEX_FULL 0x0000000000000020ULL -+ -+/** -+ * Advertise auto-negotiation enable -+ */ -+#define DPMAC_ADVERTISED_AUTONEG 0x0000000000000008ULL -+ -+/** - * struct dpmac_link_cfg - Structure representing DPMAC link configuration - * @rate: Link's rate - in Mbps - * @options: Enable/Disable DPMAC link cfg features (bitmap) -+ * @advertising: Speeds that are advertised for autoneg (bitmap) - */ - struct dpmac_link_cfg { - u32 rate; - u64 options; -+ u64 advertising; - }; - - int dpmac_get_link_cfg(struct fsl_mc_io *mc_io, -@@ -216,16 +232,27 @@ int dpmac_get_link_cfg(struct fsl_mc_io - u16 token, - struct dpmac_link_cfg *cfg); - -+int dpmac_get_link_cfg_v2(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpmac_link_cfg *cfg); -+ - /** - * struct dpmac_link_state - DPMAC link configuration request - * @rate: Rate in Mbps - * @options: Enable/Disable DPMAC link cfg features (bitmap) - * @up: Link state -+ * @state_valid: Ignore/Update the state of the link -+ * @supported: Speeds capability of the phy (bitmap) -+ * @advertising: Speeds that are advertised for autoneg (bitmap) - */ - struct dpmac_link_state { - u32 rate; - u64 options; - int up; -+ int state_valid; -+ u64 supported; -+ u64 advertising; - }; - - int dpmac_set_link_state(struct fsl_mc_io *mc_io, -@@ -233,6 +260,11 @@ int dpmac_set_link_state(struct fsl_mc_i - u16 token, - struct dpmac_link_state *link_state); - -+int dpmac_set_link_state_v2(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpmac_link_state *link_state); -+ - /** - * enum dpmac_counter - DPMAC counter types - * @DPMAC_CNT_ING_FRAME_64: counts 64-bytes frames, good or bad. diff --git a/target/linux/layerscape/patches-5.4/701-net-0174-staging-fsl-dpaa2-mac-Add-autoneg-support.patch b/target/linux/layerscape/patches-5.4/701-net-0174-staging-fsl-dpaa2-mac-Add-autoneg-support.patch deleted file mode 100644 index fb296c55e2..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0174-staging-fsl-dpaa2-mac-Add-autoneg-support.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 52ab0053f3f8ab374c48630dd03e44fec8138113 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Thu, 18 Oct 2018 18:59:41 +0300 -Subject: [PATCH] staging: fsl-dpaa2/mac: Add autoneg support - -For MC versions that support it, use the new DPMAC link APIs, which -allow setting/getting of advertised and supported link modes. - -A mapping between DPMAC link modes and phydev ones is created to -help converting from one to the other. - -Signed-off-by: Ioana Radulescu -Signed-off-by: Valentin Catalin Neacsu ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 78 +++++++++++++++++++++++++++++++------ - 1 file changed, 67 insertions(+), 11 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -1,4 +1,5 @@ - /* Copyright 2015 Freescale Semiconductor Inc. -+ * Copyright 2018 NXP - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: -@@ -91,6 +92,43 @@ static int cmp_dpmac_ver(struct dpaa2_ma - return priv->dpmac_ver_major - ver_major; - } - -+#define DPMAC_LINK_AUTONEG_VER_MAJOR 4 -+#define DPMAC_LINK_AUTONEG_VER_MINOR 3 -+ -+struct dpaa2_mac_link_mode_map { -+ u64 dpmac_lm; -+ u64 ethtool_lm; -+}; -+ -+static const struct dpaa2_mac_link_mode_map dpaa2_mac_lm_map[] = { -+ {DPMAC_ADVERTISED_10BASET_FULL, ETHTOOL_LINK_MODE_10baseT_Full_BIT}, -+ {DPMAC_ADVERTISED_100BASET_FULL, ETHTOOL_LINK_MODE_100baseT_Full_BIT}, -+ {DPMAC_ADVERTISED_1000BASET_FULL, ETHTOOL_LINK_MODE_1000baseT_Full_BIT}, -+ {DPMAC_ADVERTISED_10000BASET_FULL, ETHTOOL_LINK_MODE_10000baseT_Full_BIT}, -+ {DPMAC_ADVERTISED_2500BASEX_FULL, ETHTOOL_LINK_MODE_2500baseT_Full_BIT}, -+ {DPMAC_ADVERTISED_AUTONEG, ETHTOOL_LINK_MODE_Autoneg_BIT}, -+}; -+ -+static void link_mode_dpmac2phydev(u64 dpmac_lm, unsigned long *phydev_lm) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dpaa2_mac_lm_map); i++) { -+ if (dpmac_lm & dpaa2_mac_lm_map[i].dpmac_lm) -+ linkmode_set_bit(dpaa2_mac_lm_map[i].ethtool_lm, phydev_lm); -+ } -+} -+ -+static void link_mode_phydev2dpmac(unsigned long *phydev_lm, u64 *dpni_lm) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dpaa2_mac_lm_map); i++) { -+ if (linkmode_test_bit(dpaa2_mac_lm_map[i].ethtool_lm, phydev_lm)) -+ *dpni_lm |= dpaa2_mac_lm_map[i].dpmac_lm; -+ } -+} -+ - static void dpaa2_mac_link_changed(struct net_device *netdev) - { - struct phy_device *phydev; -@@ -122,11 +160,18 @@ static void dpaa2_mac_link_changed(struc - phy_print_status(phydev); - } - -- /* We must interrogate MC at all times, because we don't know -- * when and whether a potential DPNI may have read the link state. -- */ -- err = dpmac_set_link_state(priv->mc_dev->mc_io, 0, -- priv->mc_dev->mc_handle, &state); -+ if (cmp_dpmac_ver(priv, DPMAC_LINK_AUTONEG_VER_MAJOR, -+ DPMAC_LINK_AUTONEG_VER_MINOR) < 0) { -+ err = dpmac_set_link_state(priv->mc_dev->mc_io, 0, -+ priv->mc_dev->mc_handle, &state); -+ } else { -+ link_mode_phydev2dpmac(phydev->supported, &state.supported); -+ link_mode_phydev2dpmac(phydev->advertising, &state.advertising); -+ state.state_valid = 1; -+ -+ err = dpmac_set_link_state_v2(priv->mc_dev->mc_io, 0, -+ priv->mc_dev->mc_handle, &state); -+ } - if (unlikely(err)) - dev_err(&priv->mc_dev->dev, "dpmac_set_link_state: %d\n", err); - } -@@ -365,12 +410,17 @@ static void configure_link(struct dpaa2_ - phydev->speed = cfg->rate; - phydev->duplex = !!(cfg->options & DPMAC_LINK_OPT_HALF_DUPLEX); - -+ if (cfg->advertising != 0) { -+ linkmode_zero(phydev->advertising); -+ link_mode_dpmac2phydev(cfg->advertising, phydev->advertising); -+ } -+ - if (cfg->options & DPMAC_LINK_OPT_AUTONEG) { -- phydev->autoneg = 1; -- phydev->advertising |= ADVERTISED_Autoneg; -+ phydev->autoneg = AUTONEG_ENABLE; -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->advertising); - } else { -- phydev->autoneg = 0; -- phydev->advertising &= ~ADVERTISED_Autoneg; -+ phydev->autoneg = AUTONEG_DISABLE; -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->advertising); - } - - phy_start_aneg(phydev); -@@ -392,8 +442,14 @@ static irqreturn_t dpaa2_mac_irq_handler - - /* DPNI-initiated link configuration; 'ifconfig up' also calls this */ - if (status & DPMAC_IRQ_EVENT_LINK_CFG_REQ) { -- err = dpmac_get_link_cfg(mc_dev->mc_io, 0, mc_dev->mc_handle, -- &link_cfg); -+ if (cmp_dpmac_ver(priv, DPMAC_LINK_AUTONEG_VER_MAJOR, -+ DPMAC_LINK_AUTONEG_VER_MINOR) < 0) -+ err = dpmac_get_link_cfg(mc_dev->mc_io, 0, -+ mc_dev->mc_handle, &link_cfg); -+ else -+ err = dpmac_get_link_cfg_v2(mc_dev->mc_io, 0, -+ mc_dev->mc_handle, -+ &link_cfg); - if (unlikely(err)) - goto out; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0175-staging-fsl-dpaa2-mac-connect-to-the-fixed-phy.patch b/target/linux/layerscape/patches-5.4/701-net-0175-staging-fsl-dpaa2-mac-connect-to-the-fixed-phy.patch deleted file mode 100644 index 8d0e122b12..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0175-staging-fsl-dpaa2-mac-connect-to-the-fixed-phy.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 69e35d8266713d36ad31b04d9b7cb32913d243c0 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Tue, 27 Nov 2018 15:23:47 +0200 -Subject: [PATCH] staging: fsl-dpaa2/mac: connect to the fixed phy - -This patch is formed from 2 parts: - - first it moves the code that determines the if_mode to the - beginning so that it's used for both fixed link and phy mode. - - secondly, when in fixed link mode, call the phy_connect_phy - function as needed. - -Signed-off-by: Ioana Ciornei ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 39 ++++++++++++++++++++++++------------- - 1 file changed, 25 insertions(+), 14 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -642,21 +642,12 @@ static int dpaa2_mac_probe(struct fsl_mc - } - #endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */ - -- /* probe the PHY as fixed-link if the DPMAC attribute indicates so */ -- if (priv->attr.link_type == DPMAC_LINK_TYPE_FIXED) -- goto probe_fixed_link; -- -- /* or if there's no phy-handle defined in the device tree */ -- phy_node = of_parse_phandle(dpmac_node, "phy-handle", 0); -- if (!phy_node) { -- goto probe_fixed_link; -- } -- -+ /* get the interface mode from the dpmac of node or from the MC attributes */ - if_mode = of_get_phy_mode(dpmac_node); - if (if_mode >= 0) { - dev_dbg(dev, "\tusing if mode %s for eth_if %d\n", - phy_modes(if_mode), priv->attr.eth_if); -- goto phy_connect; -+ goto link_type; - } - - if (priv->attr.eth_if < ARRAY_SIZE(dpaa2_mac_iface_mode)) { -@@ -664,12 +655,23 @@ static int dpaa2_mac_probe(struct fsl_mc - dev_dbg(dev, "\tusing if mode %s for eth_if %d\n", - phy_modes(if_mode), priv->attr.eth_if); - } else { -- dev_warn(dev, "Unexpected interface mode %d, will probe as fixed link\n", -- priv->attr.eth_if); -+ dev_err(dev, "Unexpected interface mode %d\n", -+ priv->attr.eth_if); -+ err = -EINVAL; -+ goto err_no_if_mode; -+ } -+ -+link_type: -+ /* probe the PHY as fixed-link if the DPMAC attribute indicates so */ -+ if (priv->attr.link_type == DPMAC_LINK_TYPE_FIXED) -+ goto probe_fixed_link; -+ -+ /* or if there's no phy-handle defined in the device tree */ -+ phy_node = of_parse_phandle(dpmac_node, "phy-handle", 0); -+ if (!phy_node) { - goto probe_fixed_link; - } - --phy_connect: - /* try to connect to the PHY */ - netdev->phydev = of_phy_connect(netdev, phy_node, - &dpaa2_mac_link_changed, 0, if_mode); -@@ -702,6 +704,14 @@ probe_fixed_link: - err = -EFAULT; - goto err_no_phy; - } -+ -+ err = phy_connect_direct(netdev, netdev->phydev, -+ &dpaa2_mac_link_changed, if_mode); -+ if (err) { -+ dev_err(dev, "error trying to connect to PHY\n"); -+ goto err_no_phy; -+ } -+ - dev_info(dev, "Registered fixed PHY.\n"); - } - -@@ -709,6 +719,7 @@ probe_fixed_link: - - return 0; - -+err_no_if_mode: - err_defer: - err_no_phy: - #ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS diff --git a/target/linux/layerscape/patches-5.4/701-net-0176-staging-fsl-dpaa2-mac-add-pause-frames-support-for-m.patch b/target/linux/layerscape/patches-5.4/701-net-0176-staging-fsl-dpaa2-mac-add-pause-frames-support-for-m.patch deleted file mode 100644 index 24c978b5cc..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0176-staging-fsl-dpaa2-mac-add-pause-frames-support-for-m.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 182bf3ddfc0168ca2df3da477b143bab17543b65 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 13 Mar 2019 19:12:47 +0200 -Subject: [PATCH] staging: fsl-dpaa2/mac: add pause frames support for managed - phys - -Read the configured dpmac options and depending on the supported -features set the according advertising bit. - -Signed-off-by: Ioana Ciornei -Signed-off-by: Bogdan Purcareata -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -148,6 +148,11 @@ static void dpaa2_mac_link_changed(struc - if (phydev->autoneg) - state.options |= DPMAC_LINK_OPT_AUTONEG; - -+ if (phydev->pause && linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising)) -+ state.options |= DPMAC_LINK_OPT_PAUSE; -+ if (phydev->pause && linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising)) -+ state.options |= DPMAC_LINK_OPT_ASYM_PAUSE; -+ - netif_carrier_on(netdev); - } else { - netif_carrier_off(netdev); -@@ -415,6 +420,20 @@ static void configure_link(struct dpaa2_ - link_mode_dpmac2phydev(cfg->advertising, phydev->advertising); - } - -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported)) { -+ if (cfg->options & DPMAC_LINK_OPT_PAUSE) -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising); -+ else -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising); -+ } -+ -+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported)) { -+ if (cfg->options & DPMAC_LINK_OPT_ASYM_PAUSE) -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising); -+ else -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising); -+ } -+ - if (cfg->options & DPMAC_LINK_OPT_AUTONEG) { - phydev->autoneg = AUTONEG_ENABLE; - linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->advertising); diff --git a/target/linux/layerscape/patches-5.4/701-net-0177-staging-dpaa2-mac-Update-interface-mode-array.patch b/target/linux/layerscape/patches-5.4/701-net-0177-staging-dpaa2-mac-Update-interface-mode-array.patch deleted file mode 100644 index 1b1d6a7a15..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0177-staging-dpaa2-mac-Update-interface-mode-array.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3548421e09d714c23eb74ed7302221df8274d356 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 24 Jul 2019 20:26:06 +0300 -Subject: [PATCH] staging: dpaa2-mac: Update interface mode array - -We used to set PHY_INTERFACE_MODE_XGMII as a placeholder -for interface modes listed by MC but not defined in the -linux kernel. Some of these modes have been added in upstream, -so update the interface mode array to better match actual PHYs. - -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -77,11 +77,11 @@ static phy_interface_t dpaa2_mac_iface_m - PHY_INTERFACE_MODE_RGMII, /* DPMAC_ETH_IF_RGMII */ - PHY_INTERFACE_MODE_SGMII, /* DPMAC_ETH_IF_SGMII */ - PHY_INTERFACE_MODE_QSGMII, /* DPMAC_ETH_IF_QSGMII */ -- PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_XAUI */ -+ PHY_INTERFACE_MODE_XAUI, /* DPMAC_ETH_IF_XAUI */ - PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_XFI */ - PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_CAUI */ -- PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_1000BASEX */ -- PHY_INTERFACE_MODE_XGMII, /* DPMAC_ETH_IF_USXGMII */ -+ PHY_INTERFACE_MODE_1000BASEX, /* DPMAC_ETH_IF_1000BASEX */ -+ PHY_INTERFACE_MODE_USXGMII, /* DPMAC_ETH_IF_USXGMII */ - }; - - static int cmp_dpmac_ver(struct dpaa2_mac_priv *priv, diff --git a/target/linux/layerscape/patches-5.4/701-net-0178-staging-dpaa2-mac-add-link-up-down-events-for-dpmac.patch b/target/linux/layerscape/patches-5.4/701-net-0178-staging-dpaa2-mac-add-link-up-down-events-for-dpmac.patch deleted file mode 100644 index 9fbd8c79ab..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0178-staging-dpaa2-mac-add-link-up-down-events-for-dpmac.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 3b07b109823a593f43e794cbf44ba3a84ceefbdb Mon Sep 17 00:00:00 2001 -From: Florin Chiculita -Date: Fri, 23 Aug 2019 18:02:27 +0300 -Subject: [PATCH] staging: dpaa2-mac: add link up/down events for dpmac - -Fix a limitation that affects the networking behavior when the user -issues ifconfig down/up on a DPNI and the link remains down. -The actual problem was that the mac driver was not aware of the -dpni link change event. Now, the event is sent by firmware and -phylib state machine is manipulated conveniently. - -Signed-off-by: Florin Chiculita -Signed-off-by: Ioana Ciornei ---- - drivers/staging/fsl-dpaa2/mac/dpmac.h | 5 +++++ - drivers/staging/fsl-dpaa2/mac/mac.c | 15 ++++++++++++--- - 2 files changed, 17 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/dpmac.h -+++ b/drivers/staging/fsl-dpaa2/mac/dpmac.h -@@ -124,6 +124,11 @@ int dpmac_destroy(struct fsl_mc_io *mc_i - * IRQ event - Indicates that the link state changed - */ - #define DPMAC_IRQ_EVENT_LINK_CHANGED 0x00000002 -+/** -+ * IRQ event - Indicate if the phy needs to suspend or resume -+ */ -+#define DPMAC_IRQ_EVENT_LINK_UP_REQ 0x00000004 -+#define DPMAC_IRQ_EVENT_LINK_DOWN_REQ 0x00000008 - - int dpmac_set_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -181,6 +181,7 @@ static void dpaa2_mac_link_changed(struc - dev_err(&priv->mc_dev->dev, "dpmac_set_link_state: %d\n", err); - } - -+#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS - static int dpaa2_mac_open(struct net_device *netdev) - { - /* start PHY state machine */ -@@ -188,6 +189,7 @@ static int dpaa2_mac_open(struct net_dev - - return 0; - } -+#endif - - static int dpaa2_mac_stop(struct net_device *netdev) - { -@@ -450,6 +452,7 @@ static irqreturn_t dpaa2_mac_irq_handler - struct device *dev = (struct device *)arg; - struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); - struct dpaa2_mac_priv *priv = dev_get_drvdata(dev); -+ struct net_device *ndev = priv->netdev; - struct dpmac_link_cfg link_cfg = { 0 }; - u32 status; - int err; -@@ -475,6 +478,12 @@ static irqreturn_t dpaa2_mac_irq_handler - configure_link(priv, &link_cfg); - } - -+ if (status & DPMAC_IRQ_EVENT_LINK_UP_REQ) -+ phy_start(ndev->phydev); -+ -+ if (status & DPMAC_IRQ_EVENT_LINK_DOWN_REQ) -+ phy_stop(ndev->phydev); -+ - out: - dpmac_clear_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle, - DPMAC_IRQ_INDEX, status); -@@ -505,7 +514,9 @@ static int setup_irqs(struct fsl_mc_devi - } - - err = dpmac_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle, -- DPMAC_IRQ_INDEX, DPMAC_IRQ_EVENT_LINK_CFG_REQ); -+ DPMAC_IRQ_INDEX, DPMAC_IRQ_EVENT_LINK_CFG_REQ | -+ DPMAC_IRQ_EVENT_LINK_UP_REQ | -+ DPMAC_IRQ_EVENT_LINK_DOWN_REQ); - if (err) { - dev_err(&mc_dev->dev, "dpmac_set_irq_mask err %d\n", err); - goto free_irq; -@@ -734,8 +745,6 @@ probe_fixed_link: - dev_info(dev, "Registered fixed PHY.\n"); - } - -- dpaa2_mac_open(netdev); -- - return 0; - - err_no_if_mode: diff --git a/target/linux/layerscape/patches-5.4/701-net-0179-staging-dpaa2-evb-Add-Edge-Virtual-Bridge-driver.patch b/target/linux/layerscape/patches-5.4/701-net-0179-staging-dpaa2-evb-Add-Edge-Virtual-Bridge-driver.patch deleted file mode 100644 index 51d10b370f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0179-staging-dpaa2-evb-Add-Edge-Virtual-Bridge-driver.patch +++ /dev/null @@ -1,3182 +0,0 @@ -From 5d027b67938155d14814437c89fc535dff94cc10 Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Thu, 13 Apr 2017 16:03:37 +0300 -Subject: [PATCH] staging: dpaa2-evb: Add Edge Virtual Bridge driver - -This contains the following patches migrated from sdk-v2.0.x branch: - -dpaa2-evb: Added Edge Virtual Bridge driver -dpaa2-evb: Add VLAN_8021Q dependency -dpaa2-evb: Update dpdmux binary interface to 5.0 -dpaa2-evb: Add support to set max frame length. -dpaa2-evb: Fix interrupt handling -dpaa2-evb: Add object version check -staging: dpaa2-evb: update dpdmux command ids set for MC v10.x -dpaa2-evb: replace uintX_t types by kernel preferred kernel uX types -dpaa2-evb: uprev binary interface to v6.0 -dpaa2-evb: move comments from declaration to definition -dpaa2-evb: delete extraneous tabs -dpaa2-evb: align function parameters -dpaa2-evb: convert mc command build/parse to use C structs - -Initial patches have been signed-off by: -Alex Marginean -J. German Rivera -Bogdan Hamciuc -Mihaela Panescu -Catalin Horghidan -Ioana Ciornei -Stuart Yoder - -Updated FLIBs to the latest available for MC 10.x and fixed check-patch -warnings. Updated maintainer to myself and removed the DPAA2 Ethernet -dependency. - -Signed-off-by: Razvan Stefanescu ---- - drivers/staging/fsl-dpaa2/Kconfig | 1 + - drivers/staging/fsl-dpaa2/Makefile | 1 + - drivers/staging/fsl-dpaa2/evb/Kconfig | 7 + - drivers/staging/fsl-dpaa2/evb/Makefile | 10 + - drivers/staging/fsl-dpaa2/evb/dpdmux-cmd.h | 279 +++++++ - drivers/staging/fsl-dpaa2/evb/dpdmux.c | 1111 +++++++++++++++++++++++++ - drivers/staging/fsl-dpaa2/evb/dpdmux.h | 453 ++++++++++ - drivers/staging/fsl-dpaa2/evb/evb.c | 1238 ++++++++++++++++++++++++++++ - 8 files changed, 3100 insertions(+) - create mode 100644 drivers/staging/fsl-dpaa2/evb/Kconfig - create mode 100644 drivers/staging/fsl-dpaa2/evb/Makefile - create mode 100644 drivers/staging/fsl-dpaa2/evb/dpdmux-cmd.h - create mode 100644 drivers/staging/fsl-dpaa2/evb/dpdmux.c - create mode 100644 drivers/staging/fsl-dpaa2/evb/dpdmux.h - create mode 100644 drivers/staging/fsl-dpaa2/evb/evb.c - ---- a/drivers/staging/fsl-dpaa2/Kconfig -+++ b/drivers/staging/fsl-dpaa2/Kconfig -@@ -19,3 +19,4 @@ config FSL_DPAA2_ETHSW - BRIDGE to have support for bridge tools. - - source "drivers/staging/fsl-dpaa2/mac/Kconfig" -+source "drivers/staging/fsl-dpaa2/evb/Kconfig" ---- a/drivers/staging/fsl-dpaa2/Makefile -+++ b/drivers/staging/fsl-dpaa2/Makefile -@@ -5,3 +5,4 @@ - - obj-$(CONFIG_FSL_DPAA2_ETHSW) += ethsw/ - obj-$(CONFIG_FSL_DPAA2_MAC) += mac/ -+obj-$(CONFIG_FSL_DPAA2_EVB) += evb/ ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/evb/Kconfig -@@ -0,0 +1,7 @@ -+config FSL_DPAA2_EVB -+ tristate "DPAA2 Edge Virtual Bridge" -+ depends on FSL_MC_BUS && FSL_DPAA2 -+ select VLAN_8021Q -+ default y -+ ---help--- -+ Prototype driver for DPAA2 Edge Virtual Bridge. ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/evb/Makefile -@@ -0,0 +1,10 @@ -+ -+obj-$(CONFIG_FSL_DPAA2_EVB) += dpaa2-evb.o -+ -+dpaa2-evb-objs := evb.o dpdmux.o -+ -+all: -+ make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules -+ -+clean: -+ make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/evb/dpdmux-cmd.h -@@ -0,0 +1,279 @@ -+/* Copyright 2013-2016 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of the above-listed copyright holders nor the -+ * names of any contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -+ * POSSIBILITY OF SUCH DAMAGE. -+ */ -+#ifndef _FSL_DPDMUX_CMD_H -+#define _FSL_DPDMUX_CMD_H -+ -+/* DPDMUX Version */ -+#define DPDMUX_VER_MAJOR 6 -+#define DPDMUX_VER_MINOR 1 -+ -+#define DPDMUX_CMD_BASE_VER 1 -+#define DPDMUX_CMD_ID_OFFSET 4 -+ -+#define DPDMUX_CMD(id) (((id) << DPDMUX_CMD_ID_OFFSET) | DPDMUX_CMD_BASE_VER) -+ -+/* Command IDs */ -+#define DPDMUX_CMDID_CLOSE DPDMUX_CMD(0x800) -+#define DPDMUX_CMDID_OPEN DPDMUX_CMD(0x806) -+#define DPDMUX_CMDID_CREATE DPDMUX_CMD(0x906) -+#define DPDMUX_CMDID_DESTROY DPDMUX_CMD(0x986) -+#define DPDMUX_CMDID_GET_API_VERSION DPDMUX_CMD(0xa06) -+ -+#define DPDMUX_CMDID_ENABLE DPDMUX_CMD(0x002) -+#define DPDMUX_CMDID_DISABLE DPDMUX_CMD(0x003) -+#define DPDMUX_CMDID_GET_ATTR DPDMUX_CMD(0x004) -+#define DPDMUX_CMDID_RESET DPDMUX_CMD(0x005) -+#define DPDMUX_CMDID_IS_ENABLED DPDMUX_CMD(0x006) -+ -+#define DPDMUX_CMDID_SET_IRQ_ENABLE DPDMUX_CMD(0x012) -+#define DPDMUX_CMDID_GET_IRQ_ENABLE DPDMUX_CMD(0x013) -+#define DPDMUX_CMDID_SET_IRQ_MASK DPDMUX_CMD(0x014) -+#define DPDMUX_CMDID_GET_IRQ_MASK DPDMUX_CMD(0x015) -+#define DPDMUX_CMDID_GET_IRQ_STATUS DPDMUX_CMD(0x016) -+#define DPDMUX_CMDID_CLEAR_IRQ_STATUS DPDMUX_CMD(0x017) -+ -+#define DPDMUX_CMDID_SET_MAX_FRAME_LENGTH DPDMUX_CMD(0x0a1) -+ -+#define DPDMUX_CMDID_UL_RESET_COUNTERS DPDMUX_CMD(0x0a3) -+ -+#define DPDMUX_CMDID_IF_SET_ACCEPTED_FRAMES DPDMUX_CMD(0x0a7) -+#define DPDMUX_CMDID_IF_GET_ATTR DPDMUX_CMD(0x0a8) -+#define DPDMUX_CMDID_IF_ENABLE DPDMUX_CMD(0x0a9) -+#define DPDMUX_CMDID_IF_DISABLE DPDMUX_CMD(0x0aa) -+ -+#define DPDMUX_CMDID_IF_ADD_L2_RULE DPDMUX_CMD(0x0b0) -+#define DPDMUX_CMDID_IF_REMOVE_L2_RULE DPDMUX_CMD(0x0b1) -+#define DPDMUX_CMDID_IF_GET_COUNTER DPDMUX_CMD(0x0b2) -+#define DPDMUX_CMDID_IF_SET_LINK_CFG DPDMUX_CMD(0x0b3) -+#define DPDMUX_CMDID_IF_GET_LINK_STATE DPDMUX_CMD(0x0b4) -+ -+#define DPDMUX_CMDID_SET_CUSTOM_KEY DPDMUX_CMD(0x0b5) -+#define DPDMUX_CMDID_ADD_CUSTOM_CLS_ENTRY DPDMUX_CMD(0x0b6) -+#define DPDMUX_CMDID_REMOVE_CUSTOM_CLS_ENTRY DPDMUX_CMD(0x0b7) -+ -+#define DPDMUX_MASK(field) \ -+ GENMASK(DPDMUX_##field##_SHIFT + DPDMUX_##field##_SIZE - 1, \ -+ DPDMUX_##field##_SHIFT) -+#define dpdmux_set_field(var, field, val) \ -+ ((var) |= (((val) << DPDMUX_##field##_SHIFT) & DPDMUX_MASK(field))) -+#define dpdmux_get_field(var, field) \ -+ (((var) & DPDMUX_MASK(field)) >> DPDMUX_##field##_SHIFT) -+ -+struct dpdmux_cmd_open { -+ u32 dpdmux_id; -+}; -+ -+struct dpdmux_cmd_create { -+ u8 method; -+ u8 manip; -+ u16 num_ifs; -+ u32 pad; -+ -+ u16 adv_max_dmat_entries; -+ u16 adv_max_mc_groups; -+ u16 adv_max_vlan_ids; -+ u16 pad1; -+ -+ u64 options; -+}; -+ -+struct dpdmux_cmd_destroy { -+ u32 dpdmux_id; -+}; -+ -+#define DPDMUX_ENABLE_SHIFT 0 -+#define DPDMUX_ENABLE_SIZE 1 -+ -+struct dpdmux_rsp_is_enabled { -+ u8 en; -+}; -+ -+struct dpdmux_cmd_set_irq_enable { -+ u8 enable; -+ u8 pad[3]; -+ u8 irq_index; -+}; -+ -+struct dpdmux_cmd_get_irq_enable { -+ u32 pad; -+ u8 irq_index; -+}; -+ -+struct dpdmux_rsp_get_irq_enable { -+ u8 enable; -+}; -+ -+struct dpdmux_cmd_set_irq_mask { -+ u32 mask; -+ u8 irq_index; -+}; -+ -+struct dpdmux_cmd_get_irq_mask { -+ u32 pad; -+ u8 irq_index; -+}; -+ -+struct dpdmux_rsp_get_irq_mask { -+ u32 mask; -+}; -+ -+struct dpdmux_cmd_get_irq_status { -+ u32 status; -+ u8 irq_index; -+}; -+ -+struct dpdmux_rsp_get_irq_status { -+ u32 status; -+}; -+ -+struct dpdmux_cmd_clear_irq_status { -+ u32 status; -+ u8 irq_index; -+}; -+ -+struct dpdmux_rsp_get_attr { -+ u8 method; -+ u8 manip; -+ u16 num_ifs; -+ u16 mem_size; -+ u16 pad; -+ -+ u64 pad1; -+ -+ u32 id; -+ u32 pad2; -+ -+ u64 options; -+}; -+ -+struct dpdmux_cmd_set_max_frame_length { -+ u16 max_frame_length; -+}; -+ -+#define DPDMUX_ACCEPTED_FRAMES_TYPE_SHIFT 0 -+#define DPDMUX_ACCEPTED_FRAMES_TYPE_SIZE 4 -+#define DPDMUX_UNACCEPTED_FRAMES_ACTION_SHIFT 4 -+#define DPDMUX_UNACCEPTED_FRAMES_ACTION_SIZE 4 -+ -+struct dpdmux_cmd_if_set_accepted_frames { -+ u16 if_id; -+ u8 frames_options; -+}; -+ -+struct dpdmux_cmd_if { -+ u16 if_id; -+}; -+ -+struct dpdmux_rsp_if_get_attr { -+ u8 pad[3]; -+ u8 enabled; -+ u8 pad1[3]; -+ u8 accepted_frames_type; -+ u32 rate; -+}; -+ -+struct dpdmux_cmd_if_l2_rule { -+ u16 if_id; -+ u8 mac_addr5; -+ u8 mac_addr4; -+ u8 mac_addr3; -+ u8 mac_addr2; -+ u8 mac_addr1; -+ u8 mac_addr0; -+ -+ u32 pad; -+ u16 vlan_id; -+}; -+ -+struct dpdmux_cmd_if_get_counter { -+ u16 if_id; -+ u8 counter_type; -+}; -+ -+struct dpdmux_rsp_if_get_counter { -+ u64 pad; -+ u64 counter; -+}; -+ -+struct dpdmux_cmd_if_set_link_cfg { -+ u16 if_id; -+ u16 pad[3]; -+ -+ u32 rate; -+ u32 pad1; -+ -+ u64 options; -+}; -+ -+struct dpdmux_cmd_if_get_link_state { -+ u16 if_id; -+}; -+ -+struct dpdmux_rsp_if_get_link_state { -+ u32 pad; -+ u8 up; -+ u8 pad1[3]; -+ -+ u32 rate; -+ u32 pad2; -+ -+ u64 options; -+}; -+ -+struct dpdmux_rsp_get_api_version { -+ u16 major; -+ u16 minor; -+}; -+ -+struct dpdmux_set_custom_key { -+ u64 pad[6]; -+ u64 key_cfg_iova; -+}; -+ -+struct dpdmux_cmd_add_custom_cls_entry { -+ u8 pad[3]; -+ u8 key_size; -+ u16 pad1; -+ u16 dest_if; -+ u64 key_iova; -+ u64 mask_iova; -+}; -+ -+struct dpdmux_cmd_remove_custom_cls_entry { -+ u8 pad[3]; -+ u8 key_size; -+ u32 pad1; -+ u64 key_iova; -+ u64 mask_iova; -+}; -+ -+#endif /* _FSL_DPDMUX_CMD_H */ ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/evb/dpdmux.c -@@ -0,0 +1,1111 @@ -+/* Copyright 2013-2016 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of the above-listed copyright holders nor the -+ * names of any contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -+ * POSSIBILITY OF SUCH DAMAGE. -+ */ -+#include "../../fsl-mc/include/mc.h" -+#include "dpdmux.h" -+#include "dpdmux-cmd.h" -+ -+/** -+ * dpdmux_open() - Open a control session for the specified object -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @dpdmux_id: DPDMUX unique ID -+ * @token: Returned token; use in subsequent API calls -+ * -+ * This function can be used to open a control session for an -+ * already created object; an object may have been declared in -+ * the DPL or by calling the dpdmux_create() function. -+ * This function returns a unique authentication token, -+ * associated with the specific object ID and the specific MC -+ * portal; this token must be used in all subsequent commands for -+ * this specific object. -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_open(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ int dpdmux_id, -+ u16 *token) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_open *cmd_params; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_OPEN, -+ cmd_flags, -+ 0); -+ cmd_params = (struct dpdmux_cmd_open *)cmd.params; -+ cmd_params->dpdmux_id = cpu_to_le32(dpdmux_id); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ *token = mc_cmd_hdr_read_token(&cmd); -+ -+ return 0; -+} -+ -+/** -+ * dpdmux_close() - Close the control session of the object -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * -+ * After this function is called, no further operations are -+ * allowed on the object without opening a new control session. -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_close(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token) -+{ -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_CLOSE, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_create() - Create the DPDMUX object -+ * @mc_io: Pointer to MC portal's I/O object -+ * @dprc_token: Parent container token; '0' for default container -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @cfg: Configuration structure -+ * @obj_id: returned object id -+ * -+ * Create the DPDMUX object, allocate required resources and -+ * perform required initialization. -+ * -+ * The object can be created either by declaring it in the -+ * DPL file, or by calling this function. -+ * -+ * The function accepts an authentication token of a parent -+ * container that this object should be assigned to. The token -+ * can be '0' so the object will be assigned to the default container. -+ * The newly created object can be opened with the returned -+ * object id and using the container's associated tokens and MC portals. -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_create(struct fsl_mc_io *mc_io, -+ u16 dprc_token, -+ u32 cmd_flags, -+ const struct dpdmux_cfg *cfg, -+ u32 *obj_id) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_create *cmd_params; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_CREATE, -+ cmd_flags, -+ dprc_token); -+ cmd_params = (struct dpdmux_cmd_create *)cmd.params; -+ cmd_params->method = cfg->method; -+ cmd_params->manip = cfg->manip; -+ cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs); -+ cmd_params->adv_max_dmat_entries = -+ cpu_to_le16(cfg->adv.max_dmat_entries); -+ cmd_params->adv_max_mc_groups = cpu_to_le16(cfg->adv.max_mc_groups); -+ cmd_params->adv_max_vlan_ids = cpu_to_le16(cfg->adv.max_vlan_ids); -+ cmd_params->options = cpu_to_le64(cfg->adv.options); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ *obj_id = mc_cmd_hdr_read_token(&cmd); -+ -+ return 0; -+} -+ -+/** -+ * dpdmux_destroy() - Destroy the DPDMUX object and release all its resources. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @dprc_token: Parent container token; '0' for default container -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @object_id: The object id; it must be a valid id within the container that -+ * created this object; -+ * -+ * The function accepts the authentication token of the parent container that -+ * created the object (not the one that currently owns the object). The object -+ * is searched within parent using the provided 'object_id'. -+ * All tokens to the object must be closed before calling destroy. -+ * -+ * Return: '0' on Success; error code otherwise. -+ */ -+int dpdmux_destroy(struct fsl_mc_io *mc_io, -+ u16 dprc_token, -+ u32 cmd_flags, -+ u32 object_id) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_destroy *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_DESTROY, -+ cmd_flags, -+ dprc_token); -+ cmd_params = (struct dpdmux_cmd_destroy *)cmd.params; -+ cmd_params->dpdmux_id = cpu_to_le32(object_id); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_enable() - Enable DPDMUX functionality -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token) -+{ -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_ENABLE, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_disable() - Disable DPDMUX functionality -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_disable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token) -+{ -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_DISABLE, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_is_enabled() - Check if the DPDMUX is enabled. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @en: Returns '1' if object is enabled; '0' otherwise -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_is_enabled(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ int *en) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_rsp_is_enabled *rsp_params; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IS_ENABLED, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpdmux_rsp_is_enabled *)cmd.params; -+ *en = dpdmux_get_field(rsp_params->en, ENABLE); -+ -+ return 0; -+} -+ -+/** -+ * dpdmux_reset() - Reset the DPDMUX, returns the object to initial state. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_reset(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token) -+{ -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_RESET, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_set_irq_enable() - Set overall interrupt state. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @irq_index: The interrupt index to configure -+ * @en: Interrupt state - enable = 1, disable = 0 -+ * -+ * Allows GPP software to control when interrupts are generated. -+ * Each interrupt can have up to 32 causes. The enable/disable control's the -+ * overall interrupt state. if the interrupt is disabled no causes will cause -+ * an interrupt. -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_set_irq_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u8 en) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_set_irq_enable *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_SET_IRQ_ENABLE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_set_irq_enable *)cmd.params; -+ cmd_params->enable = en; -+ cmd_params->irq_index = irq_index; -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_get_irq_enable() - Get overall interrupt state. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @irq_index: The interrupt index to configure -+ * @en: Returned interrupt state - enable = 1, disable = 0 -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_get_irq_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u8 *en) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_get_irq_enable *cmd_params; -+ struct dpdmux_rsp_get_irq_enable *rsp_params; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_GET_IRQ_ENABLE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_get_irq_enable *)cmd.params; -+ cmd_params->irq_index = irq_index; -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpdmux_rsp_get_irq_enable *)cmd.params; -+ *en = rsp_params->enable; -+ -+ return 0; -+} -+ -+/** -+ * dpdmux_set_irq_mask() - Set interrupt mask. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @irq_index: The interrupt index to configure -+ * @mask: event mask to trigger interrupt; -+ * each bit: -+ * 0 = ignore event -+ * 1 = consider event for asserting IRQ -+ * -+ * Every interrupt can have up to 32 causes and the interrupt model supports -+ * masking/unmasking each cause independently -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_set_irq_mask(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 mask) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_set_irq_mask *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_SET_IRQ_MASK, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_set_irq_mask *)cmd.params; -+ cmd_params->mask = cpu_to_le32(mask); -+ cmd_params->irq_index = irq_index; -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_get_irq_mask() - Get interrupt mask. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @irq_index: The interrupt index to configure -+ * @mask: Returned event mask to trigger interrupt -+ * -+ * Every interrupt can have up to 32 causes and the interrupt model supports -+ * masking/unmasking each cause independently -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_get_irq_mask(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 *mask) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_get_irq_mask *cmd_params; -+ struct dpdmux_rsp_get_irq_mask *rsp_params; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_GET_IRQ_MASK, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_get_irq_mask *)cmd.params; -+ cmd_params->irq_index = irq_index; -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpdmux_rsp_get_irq_mask *)cmd.params; -+ *mask = le32_to_cpu(rsp_params->mask); -+ -+ return 0; -+} -+ -+/** -+ * dpdmux_get_irq_status() - Get the current status of any pending interrupts. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @irq_index: The interrupt index to configure -+ * @status: Returned interrupts status - one bit per cause: -+ * 0 = no interrupt pending -+ * 1 = interrupt pending -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_get_irq_status(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 *status) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_get_irq_status *cmd_params; -+ struct dpdmux_rsp_get_irq_status *rsp_params; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_GET_IRQ_STATUS, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_get_irq_status *)cmd.params; -+ cmd_params->status = cpu_to_le32(*status); -+ cmd_params->irq_index = irq_index; -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpdmux_rsp_get_irq_status *)cmd.params; -+ *status = le32_to_cpu(rsp_params->status); -+ -+ return 0; -+} -+ -+/** -+ * dpdmux_clear_irq_status() - Clear a pending interrupt's status -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @irq_index: The interrupt index to configure -+ * @status: bits to clear (W1C) - one bit per cause: -+ * 0 = don't change -+ * 1 = clear status bit -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_clear_irq_status(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 status) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_clear_irq_status *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_CLEAR_IRQ_STATUS, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_clear_irq_status *)cmd.params; -+ cmd_params->status = cpu_to_le32(status); -+ cmd_params->irq_index = irq_index; -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_get_attributes() - Retrieve DPDMUX attributes -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @attr: Returned object's attributes -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_get_attributes(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpdmux_attr *attr) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_rsp_get_attr *rsp_params; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_GET_ATTR, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpdmux_rsp_get_attr *)cmd.params; -+ attr->id = le32_to_cpu(rsp_params->id); -+ attr->options = le64_to_cpu(rsp_params->options); -+ attr->method = rsp_params->method; -+ attr->manip = rsp_params->manip; -+ attr->num_ifs = le16_to_cpu(rsp_params->num_ifs); -+ attr->mem_size = le16_to_cpu(rsp_params->mem_size); -+ -+ return 0; -+} -+ -+/** -+ * dpdmux_if_enable() - Enable Interface -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @if_id: Interface Identifier -+ * -+ * Return: Completion status. '0' on Success; Error code otherwise. -+ */ -+int dpdmux_if_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id) -+{ -+ struct dpdmux_cmd_if *cmd_params; -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_ENABLE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_if *)cmd.params; -+ cmd_params->if_id = cpu_to_le16(if_id); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_if_disable() - Disable Interface -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @if_id: Interface Identifier -+ * -+ * Return: Completion status. '0' on Success; Error code otherwise. -+ */ -+int dpdmux_if_disable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id) -+{ -+ struct dpdmux_cmd_if *cmd_params; -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_DISABLE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_if *)cmd.params; -+ cmd_params->if_id = cpu_to_le16(if_id); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_set_max_frame_length() - Set the maximum frame length in DPDMUX -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @max_frame_length: The required maximum frame length -+ * -+ * Update the maximum frame length on all DMUX interfaces. -+ * In case of VEPA, the maximum frame length on all dmux interfaces -+ * will be updated with the minimum value of the mfls of the connected -+ * dpnis and the actual value of dmux mfl. -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_set_max_frame_length(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 max_frame_length) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_set_max_frame_length *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_SET_MAX_FRAME_LENGTH, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_set_max_frame_length *)cmd.params; -+ cmd_params->max_frame_length = cpu_to_le16(max_frame_length); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_ul_reset_counters() - Function resets the uplink counter -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_ul_reset_counters(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token) -+{ -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_UL_RESET_COUNTERS, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_if_set_accepted_frames() - Set the accepted frame types -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @if_id: Interface ID (0 for uplink, or 1-num_ifs); -+ * @cfg: Frame types configuration -+ * -+ * if 'DPDMUX_ADMIT_ONLY_VLAN_TAGGED' is set - untagged frames or -+ * priority-tagged frames are discarded. -+ * if 'DPDMUX_ADMIT_ONLY_UNTAGGED' is set - untagged frames or -+ * priority-tagged frames are accepted. -+ * if 'DPDMUX_ADMIT_ALL' is set (default mode) - all VLAN tagged, -+ * untagged and priority-tagged frame are accepted; -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_if_set_accepted_frames(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ const struct dpdmux_accepted_frames *cfg) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_if_set_accepted_frames *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_SET_ACCEPTED_FRAMES, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_if_set_accepted_frames *)cmd.params; -+ cmd_params->if_id = cpu_to_le16(if_id); -+ dpdmux_set_field(cmd_params->frames_options, ACCEPTED_FRAMES_TYPE, -+ cfg->type); -+ dpdmux_set_field(cmd_params->frames_options, UNACCEPTED_FRAMES_ACTION, -+ cfg->unaccept_act); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_if_get_attributes() - Obtain DPDMUX interface attributes -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @if_id: Interface ID (0 for uplink, or 1-num_ifs); -+ * @attr: Interface attributes -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_if_get_attributes(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ struct dpdmux_if_attr *attr) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_if *cmd_params; -+ struct dpdmux_rsp_if_get_attr *rsp_params; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_GET_ATTR, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_if *)cmd.params; -+ cmd_params->if_id = cpu_to_le16(if_id); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpdmux_rsp_if_get_attr *)cmd.params; -+ attr->rate = le32_to_cpu(rsp_params->rate); -+ attr->enabled = dpdmux_get_field(rsp_params->enabled, ENABLE); -+ attr->accept_frame_type = -+ dpdmux_get_field(rsp_params->accepted_frames_type, -+ ACCEPTED_FRAMES_TYPE); -+ -+ return 0; -+} -+ -+/** -+ * dpdmux_if_remove_l2_rule() - Remove L2 rule from DPDMUX table -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @if_id: Destination interface ID -+ * @rule: L2 rule -+ * -+ * Function removes a L2 rule from DPDMUX table -+ * or adds an interface to an existing multicast address -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_if_remove_l2_rule(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ const struct dpdmux_l2_rule *rule) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_if_l2_rule *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_REMOVE_L2_RULE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_if_l2_rule *)cmd.params; -+ cmd_params->if_id = cpu_to_le16(if_id); -+ cmd_params->vlan_id = cpu_to_le16(rule->vlan_id); -+ cmd_params->mac_addr5 = rule->mac_addr[5]; -+ cmd_params->mac_addr4 = rule->mac_addr[4]; -+ cmd_params->mac_addr3 = rule->mac_addr[3]; -+ cmd_params->mac_addr2 = rule->mac_addr[2]; -+ cmd_params->mac_addr1 = rule->mac_addr[1]; -+ cmd_params->mac_addr0 = rule->mac_addr[0]; -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_if_add_l2_rule() - Add L2 rule into DPDMUX table -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @if_id: Destination interface ID -+ * @rule: L2 rule -+ * -+ * Function adds a L2 rule into DPDMUX table -+ * or adds an interface to an existing multicast address -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_if_add_l2_rule(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ const struct dpdmux_l2_rule *rule) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_if_l2_rule *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_ADD_L2_RULE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_if_l2_rule *)cmd.params; -+ cmd_params->if_id = cpu_to_le16(if_id); -+ cmd_params->vlan_id = cpu_to_le16(rule->vlan_id); -+ cmd_params->mac_addr5 = rule->mac_addr[5]; -+ cmd_params->mac_addr4 = rule->mac_addr[4]; -+ cmd_params->mac_addr3 = rule->mac_addr[3]; -+ cmd_params->mac_addr2 = rule->mac_addr[2]; -+ cmd_params->mac_addr1 = rule->mac_addr[1]; -+ cmd_params->mac_addr0 = rule->mac_addr[0]; -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_if_get_counter() - Functions obtains specific counter of an interface -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPDMUX object -+ * @if_id: Interface Id -+ * @counter_type: counter type -+ * @counter: Returned specific counter information -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_if_get_counter(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ enum dpdmux_counter_type counter_type, -+ u64 *counter) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_if_get_counter *cmd_params; -+ struct dpdmux_rsp_if_get_counter *rsp_params; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_GET_COUNTER, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_if_get_counter *)cmd.params; -+ cmd_params->if_id = cpu_to_le16(if_id); -+ cmd_params->counter_type = counter_type; -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpdmux_rsp_if_get_counter *)cmd.params; -+ *counter = le64_to_cpu(rsp_params->counter); -+ -+ return 0; -+} -+ -+/** -+ * dpdmux_if_set_link_cfg() - set the link configuration. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSW object -+ * @if_id: interface id -+ * @cfg: Link configuration -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_if_set_link_cfg(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ struct dpdmux_link_cfg *cfg) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_if_set_link_cfg *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_SET_LINK_CFG, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_if_set_link_cfg *)cmd.params; -+ cmd_params->if_id = cpu_to_le16(if_id); -+ cmd_params->rate = cpu_to_le32(cfg->rate); -+ cmd_params->options = cpu_to_le64(cfg->options); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_if_get_link_state - Return the link state -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSW object -+ * @if_id: interface id -+ * @state: link state -+ * -+ * @returns '0' on Success; Error code otherwise. -+ */ -+int dpdmux_if_get_link_state(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ struct dpdmux_link_state *state) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_cmd_if_get_link_state *cmd_params; -+ struct dpdmux_rsp_if_get_link_state *rsp_params; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_GET_LINK_STATE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_if_get_link_state *)cmd.params; -+ cmd_params->if_id = cpu_to_le16(if_id); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpdmux_rsp_if_get_link_state *)cmd.params; -+ state->rate = le32_to_cpu(rsp_params->rate); -+ state->options = le64_to_cpu(rsp_params->options); -+ state->up = dpdmux_get_field(rsp_params->up, ENABLE); -+ -+ return 0; -+} -+ -+/** -+ * dpdmux_set_custom_key - Set a custom classification key. -+ * -+ * This API is only available for DPDMUX instance created with -+ * DPDMUX_METHOD_CUSTOM. This API must be called before populating the -+ * classification table using dpdmux_add_custom_cls_entry. -+ * -+ * Calls to dpdmux_set_custom_key remove all existing classification entries -+ * that may have been added previously using dpdmux_add_custom_cls_entry. -+ * -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSW object -+ * @if_id: interface id -+ * @key_cfg_iova: DMA address of a configuration structure set up using -+ * dpkg_prepare_key_cfg. Maximum key size is 24 bytes. -+ * -+ * @returns '0' on Success; Error code otherwise. -+ */ -+int dpdmux_set_custom_key(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u64 key_cfg_iova) -+{ -+ struct dpdmux_set_custom_key *cmd_params; -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_SET_CUSTOM_KEY, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_set_custom_key *)cmd.params; -+ cmd_params->key_cfg_iova = cpu_to_le64(key_cfg_iova); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_add_custom_cls_entry - Adds a custom classification entry. -+ * -+ * This API is only available for DPDMUX instances created with -+ * DPDMUX_METHOD_CUSTOM. Before calling this function a classification key -+ * composition rule must be set up using dpdmux_set_custom_key. -+ * -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSW object -+ * @rule: Classification rule to insert. Rules cannot be duplicated, if a -+ * matching rule already exists, the action will be replaced. -+ * @action: Action to perform for matching traffic. -+ * -+ * @returns '0' on Success; Error code otherwise. -+ */ -+int dpdmux_add_custom_cls_entry(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpdmux_rule_cfg *rule, -+ struct dpdmux_cls_action *action) -+{ -+ struct dpdmux_cmd_add_custom_cls_entry *cmd_params; -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_ADD_CUSTOM_CLS_ENTRY, -+ cmd_flags, -+ token); -+ -+ cmd_params = (struct dpdmux_cmd_add_custom_cls_entry *)cmd.params; -+ cmd_params->key_size = rule->key_size; -+ cmd_params->dest_if = cpu_to_le16(action->dest_if); -+ cmd_params->key_iova = cpu_to_le64(rule->key_iova); -+ cmd_params->mask_iova = cpu_to_le64(rule->mask_iova); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_remove_custom_cls_entry - Removes a custom classification entry. -+ * -+ * This API is only available for DPDMUX instances created with -+ * DPDMUX_METHOD_CUSTOM. The API can be used to remove classification -+ * entries previously inserted using dpdmux_add_custom_cls_entry. -+ * -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSW object -+ * @rule: Classification rule to remove -+ * -+ * @returns '0' on Success; Error code otherwise. -+ */ -+int dpdmux_remove_custom_cls_entry(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpdmux_rule_cfg *rule) -+{ -+ struct dpdmux_cmd_remove_custom_cls_entry *cmd_params; -+ struct mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_REMOVE_CUSTOM_CLS_ENTRY, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpdmux_cmd_remove_custom_cls_entry *)cmd.params; -+ cmd_params->key_size = rule->key_size; -+ cmd_params->key_iova = cpu_to_le64(rule->key_iova); -+ cmd_params->mask_iova = cpu_to_le64(rule->mask_iova); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpdmux_get_api_version() - Get Data Path Demux API version -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @major_ver: Major version of data path demux API -+ * @minor_ver: Minor version of data path demux API -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpdmux_get_api_version(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 *major_ver, -+ u16 *minor_ver) -+{ -+ struct mc_command cmd = { 0 }; -+ struct dpdmux_rsp_get_api_version *rsp_params; -+ int err; -+ -+ cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_GET_API_VERSION, -+ cmd_flags, -+ 0); -+ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ rsp_params = (struct dpdmux_rsp_get_api_version *)cmd.params; -+ *major_ver = le16_to_cpu(rsp_params->major); -+ *minor_ver = le16_to_cpu(rsp_params->minor); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/evb/dpdmux.h -@@ -0,0 +1,453 @@ -+/* Copyright 2013-2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of the above-listed copyright holders nor the -+ * names of any contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -+ * POSSIBILITY OF SUCH DAMAGE. -+ */ -+#ifndef __FSL_DPDMUX_H -+#define __FSL_DPDMUX_H -+ -+struct fsl_mc_io; -+ -+/* Data Path Demux API -+ * Contains API for handling DPDMUX topology and functionality -+ */ -+ -+int dpdmux_open(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ int dpdmux_id, -+ u16 *token); -+ -+int dpdmux_close(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token); -+ -+/** -+ * DPDMUX general options -+ */ -+ -+/** -+ * Enable bridging between internal interfaces -+ */ -+#define DPDMUX_OPT_BRIDGE_EN 0x0000000000000002ULL -+ -+/** -+ * Mask support for classification -+ */ -+#define DPDMUX_OPT_CLS_MASK_SUPPORT 0x0000000000000020ULL -+ -+#define DPDMUX_IRQ_INDEX_IF 0x0000 -+#define DPDMUX_IRQ_INDEX 0x0001 -+ -+/** -+ * IRQ event - Indicates that the link state changed -+ */ -+#define DPDMUX_IRQ_EVENT_LINK_CHANGED 0x0001 -+ -+/** -+ * enum dpdmux_manip - DPDMUX manipulation operations -+ * @DPDMUX_MANIP_NONE: No manipulation on frames -+ * @DPDMUX_MANIP_ADD_REMOVE_S_VLAN: Add S-VLAN on egress, remove it on ingress -+ */ -+enum dpdmux_manip { -+ DPDMUX_MANIP_NONE = 0x0, -+ DPDMUX_MANIP_ADD_REMOVE_S_VLAN = 0x1 -+}; -+ -+/** -+ * enum dpdmux_method - DPDMUX method options -+ * @DPDMUX_METHOD_NONE: no DPDMUX method -+ * @DPDMUX_METHOD_C_VLAN_MAC: DPDMUX based on C-VLAN and MAC address -+ * @DPDMUX_METHOD_MAC: DPDMUX based on MAC address -+ * @DPDMUX_METHOD_C_VLAN: DPDMUX based on C-VLAN -+ * @DPDMUX_METHOD_S_VLAN: DPDMUX based on S-VLAN -+ */ -+enum dpdmux_method { -+ DPDMUX_METHOD_NONE = 0x0, -+ DPDMUX_METHOD_C_VLAN_MAC = 0x1, -+ DPDMUX_METHOD_MAC = 0x2, -+ DPDMUX_METHOD_C_VLAN = 0x3, -+ DPDMUX_METHOD_S_VLAN = 0x4, -+ DPDMUX_METHOD_CUSTOM = 0x5 -+}; -+ -+/** -+ * struct dpdmux_cfg - DPDMUX configuration parameters -+ * @method: Defines the operation method for the DPDMUX address table -+ * @manip: Required manipulation operation -+ * @num_ifs: Number of interfaces (excluding the uplink interface) -+ * @adv: Advanced parameters; default is all zeros; -+ * use this structure to change default settings -+ */ -+struct dpdmux_cfg { -+ enum dpdmux_method method; -+ enum dpdmux_manip manip; -+ u16 num_ifs; -+ /** -+ * struct adv - Advanced parameters -+ * @options: DPDMUX options - combination of 'DPDMUX_OPT_' flags -+ * @max_dmat_entries: Maximum entries in DPDMUX address table -+ * 0 - indicates default: 64 entries per interface. -+ * @max_mc_groups: Number of multicast groups in DPDMUX table -+ * 0 - indicates default: 32 multicast groups -+ * @max_vlan_ids: max vlan ids allowed in the system - -+ * relevant only case of working in mac+vlan method. -+ * 0 - indicates default 16 vlan ids. -+ */ -+ struct { -+ u64 options; -+ u16 max_dmat_entries; -+ u16 max_mc_groups; -+ u16 max_vlan_ids; -+ } adv; -+}; -+ -+int dpdmux_create(struct fsl_mc_io *mc_io, -+ u16 dprc_token, -+ u32 cmd_flags, -+ const struct dpdmux_cfg *cfg, -+ u32 *obj_id); -+ -+int dpdmux_destroy(struct fsl_mc_io *mc_io, -+ u16 dprc_token, -+ u32 cmd_flags, -+ u32 object_id); -+ -+int dpdmux_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token); -+ -+int dpdmux_disable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token); -+ -+int dpdmux_is_enabled(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ int *en); -+ -+int dpdmux_reset(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token); -+ -+int dpdmux_set_irq_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u8 en); -+ -+int dpdmux_get_irq_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u8 *en); -+ -+int dpdmux_set_irq_mask(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 mask); -+ -+int dpdmux_get_irq_mask(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 *mask); -+ -+int dpdmux_get_irq_status(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 *status); -+ -+int dpdmux_clear_irq_status(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u8 irq_index, -+ u32 status); -+ -+/** -+ * struct dpdmux_attr - Structure representing DPDMUX attributes -+ * @id: DPDMUX object ID -+ * @options: Configuration options (bitmap) -+ * @method: DPDMUX address table method -+ * @manip: DPDMUX manipulation type -+ * @num_ifs: Number of interfaces (excluding the uplink interface) -+ * @mem_size: DPDMUX frame storage memory size -+ */ -+struct dpdmux_attr { -+ int id; -+ u64 options; -+ enum dpdmux_method method; -+ enum dpdmux_manip manip; -+ u16 num_ifs; -+ u16 mem_size; -+}; -+ -+int dpdmux_get_attributes(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpdmux_attr *attr); -+ -+int dpdmux_set_max_frame_length(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 max_frame_length); -+ -+/** -+ * enum dpdmux_counter_type - Counter types -+ * @DPDMUX_CNT_ING_FRAME: Counts ingress frames -+ * @DPDMUX_CNT_ING_BYTE: Counts ingress bytes -+ * @DPDMUX_CNT_ING_FLTR_FRAME: Counts filtered ingress frames -+ * @DPDMUX_CNT_ING_FRAME_DISCARD: Counts discarded ingress frames -+ * @DPDMUX_CNT_ING_MCAST_FRAME: Counts ingress multicast frames -+ * @DPDMUX_CNT_ING_MCAST_BYTE: Counts ingress multicast bytes -+ * @DPDMUX_CNT_ING_BCAST_FRAME: Counts ingress broadcast frames -+ * @DPDMUX_CNT_ING_BCAST_BYTES: Counts ingress broadcast bytes -+ * @DPDMUX_CNT_EGR_FRAME: Counts egress frames -+ * @DPDMUX_CNT_EGR_BYTE: Counts egress bytes -+ * @DPDMUX_CNT_EGR_FRAME_DISCARD: Counts discarded egress frames -+ */ -+enum dpdmux_counter_type { -+ DPDMUX_CNT_ING_FRAME = 0x0, -+ DPDMUX_CNT_ING_BYTE = 0x1, -+ DPDMUX_CNT_ING_FLTR_FRAME = 0x2, -+ DPDMUX_CNT_ING_FRAME_DISCARD = 0x3, -+ DPDMUX_CNT_ING_MCAST_FRAME = 0x4, -+ DPDMUX_CNT_ING_MCAST_BYTE = 0x5, -+ DPDMUX_CNT_ING_BCAST_FRAME = 0x6, -+ DPDMUX_CNT_ING_BCAST_BYTES = 0x7, -+ DPDMUX_CNT_EGR_FRAME = 0x8, -+ DPDMUX_CNT_EGR_BYTE = 0x9, -+ DPDMUX_CNT_EGR_FRAME_DISCARD = 0xa -+}; -+ -+/** -+ * enum dpdmux_accepted_frames_type - DPDMUX frame types -+ * @DPDMUX_ADMIT_ALL: The device accepts VLAN tagged, untagged and -+ * priority-tagged frames -+ * @DPDMUX_ADMIT_ONLY_VLAN_TAGGED: The device discards untagged frames or -+ * priority-tagged frames that are received on this -+ * interface -+ * @DPDMUX_ADMIT_ONLY_UNTAGGED: Untagged frames or priority-tagged frames -+ * received on this interface are accepted -+ */ -+enum dpdmux_accepted_frames_type { -+ DPDMUX_ADMIT_ALL = 0, -+ DPDMUX_ADMIT_ONLY_VLAN_TAGGED = 1, -+ DPDMUX_ADMIT_ONLY_UNTAGGED = 2 -+}; -+ -+/** -+ * enum dpdmux_action - DPDMUX action for un-accepted frames -+ * @DPDMUX_ACTION_DROP: Drop un-accepted frames -+ * @DPDMUX_ACTION_REDIRECT_TO_CTRL: Redirect un-accepted frames to the -+ * control interface -+ */ -+enum dpdmux_action { -+ DPDMUX_ACTION_DROP = 0, -+ DPDMUX_ACTION_REDIRECT_TO_CTRL = 1 -+}; -+ -+/** -+ * struct dpdmux_accepted_frames - Frame types configuration -+ * @type: Defines ingress accepted frames -+ * @unaccept_act: Defines action on frames not accepted -+ */ -+struct dpdmux_accepted_frames { -+ enum dpdmux_accepted_frames_type type; -+ enum dpdmux_action unaccept_act; -+}; -+ -+int dpdmux_if_set_accepted_frames(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ const struct dpdmux_accepted_frames *cfg); -+ -+/** -+ * struct dpdmux_if_attr - Structure representing frame types configuration -+ * @rate: Configured interface rate (in bits per second) -+ * @enabled: Indicates if interface is enabled -+ * @accept_frame_type: Indicates type of accepted frames for the interface -+ */ -+struct dpdmux_if_attr { -+ u32 rate; -+ int enabled; -+ enum dpdmux_accepted_frames_type accept_frame_type; -+}; -+ -+int dpdmux_if_get_attributes(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ struct dpdmux_if_attr *attr); -+ -+int dpdmux_if_enable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id); -+ -+int dpdmux_if_disable(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id); -+ -+/** -+ * struct dpdmux_l2_rule - Structure representing L2 rule -+ * @mac_addr: MAC address -+ * @vlan_id: VLAN ID -+ */ -+struct dpdmux_l2_rule { -+ u8 mac_addr[6]; -+ u16 vlan_id; -+}; -+ -+int dpdmux_if_remove_l2_rule(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ const struct dpdmux_l2_rule *rule); -+ -+int dpdmux_if_add_l2_rule(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ const struct dpdmux_l2_rule *rule); -+ -+int dpdmux_if_get_counter(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ enum dpdmux_counter_type counter_type, -+ u64 *counter); -+ -+int dpdmux_ul_reset_counters(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token); -+ -+/** -+ * Enable auto-negotiation -+ */ -+#define DPDMUX_LINK_OPT_AUTONEG 0x0000000000000001ULL -+/** -+ * Enable half-duplex mode -+ */ -+#define DPDMUX_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL -+/** -+ * Enable pause frames -+ */ -+#define DPDMUX_LINK_OPT_PAUSE 0x0000000000000004ULL -+/** -+ * Enable a-symmetric pause frames -+ */ -+#define DPDMUX_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL -+ -+/** -+ * struct dpdmux_link_cfg - Structure representing DPDMUX link configuration -+ * @rate: Rate -+ * @options: Mask of available options; use 'DPDMUX_LINK_OPT_' values -+ */ -+struct dpdmux_link_cfg { -+ u32 rate; -+ u64 options; -+}; -+ -+int dpdmux_if_set_link_cfg(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ struct dpdmux_link_cfg *cfg); -+/** -+ * struct dpdmux_link_state - Structure representing DPDMUX link state -+ * @rate: Rate -+ * @options: Mask of available options; use 'DPDMUX_LINK_OPT_' values -+ * @up: 0 - down, 1 - up -+ */ -+struct dpdmux_link_state { -+ u32 rate; -+ u64 options; -+ int up; -+}; -+ -+int dpdmux_if_get_link_state(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u16 if_id, -+ struct dpdmux_link_state *state); -+ -+int dpdmux_set_custom_key(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ u64 key_cfg_iova); -+ -+/** -+ * struct dpdmux_rule_cfg - Custom classification rule. -+ * -+ * @key_iova: DMA address of buffer storing the look-up value -+ * @mask_iova: DMA address of the mask used for TCAM classification -+ * @key_size: size, in bytes, of the look-up value. This must match the size -+ * of the look-up key defined using dpdmux_set_custom_key, otherwise the -+ * entry will never be hit -+ */ -+struct dpdmux_rule_cfg { -+ u64 key_iova; -+ u64 mask_iova; -+ u8 key_size; -+}; -+ -+/** -+ * struct dpdmux_cls_action - Action to execute for frames matching the -+ * classification entry -+ * -+ * @dest_if: Interface to forward the frames to. Port numbering is similar to -+ * the one used to connect interfaces: -+ * - 0 is the uplink port, -+ * - all others are downlink ports. -+ */ -+struct dpdmux_cls_action { -+ u16 dest_if; -+}; -+ -+int dpdmux_add_custom_cls_entry(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpdmux_rule_cfg *rule, -+ struct dpdmux_cls_action *action); -+ -+int dpdmux_remove_custom_cls_entry(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpdmux_rule_cfg *rule); -+ -+int dpdmux_get_api_version(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 *major_ver, -+ u16 *minor_ver); -+ -+#endif /* __FSL_DPDMUX_H */ ---- /dev/null -+++ b/drivers/staging/fsl-dpaa2/evb/evb.c -@@ -0,0 +1,1238 @@ -+/* Copyright 2015 Freescale Semiconductor Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "../../fsl-mc/include/mc.h" -+ -+#include "dpdmux.h" -+#include "dpdmux-cmd.h" -+ -+/* Minimal supported DPDMUX version */ -+#define DPDMUX_MIN_VER_MAJOR 6 -+#define DPDMUX_MIN_VER_MINOR 0 -+ -+/* IRQ index */ -+#define DPDMUX_MAX_IRQ_NUM 2 -+ -+/* MAX FRAME LENGTH (currently 10k) */ -+#define EVB_MAX_FRAME_LENGTH (10 * 1024) -+/* MIN FRAME LENGTH (64 bytes + 4 bytes CRC) */ -+#define EVB_MIN_FRAME_LENGTH 68 -+ -+struct evb_port_priv { -+ struct net_device *netdev; -+ struct list_head list; -+ u16 port_index; -+ struct evb_priv *evb_priv; -+ u8 vlans[VLAN_VID_MASK + 1]; -+}; -+ -+struct evb_priv { -+ /* keep first */ -+ struct evb_port_priv uplink; -+ -+ struct fsl_mc_io *mc_io; -+ struct list_head port_list; -+ struct dpdmux_attr attr; -+ u16 mux_handle; -+ int dev_id; -+}; -+ -+static int _evb_port_carrier_state_sync(struct net_device *netdev) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ struct dpdmux_link_state state; -+ int err; -+ -+ err = dpdmux_if_get_link_state(port_priv->evb_priv->mc_io, 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, &state); -+ if (unlikely(err)) { -+ netdev_err(netdev, "dpdmux_if_get_link_state() err %d\n", err); -+ return err; -+ } -+ -+ WARN_ONCE(state.up > 1, "Garbage read into link_state"); -+ -+ if (state.up) -+ netif_carrier_on(port_priv->netdev); -+ else -+ netif_carrier_off(port_priv->netdev); -+ -+ return 0; -+} -+ -+static int evb_port_open(struct net_device *netdev) -+{ -+ int err; -+ -+ /* FIXME: enable port when support added */ -+ -+ err = _evb_port_carrier_state_sync(netdev); -+ if (err) { -+ netdev_err(netdev, "ethsw_port_carrier_state_sync err %d\n", -+ err); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static netdev_tx_t evb_dropframe(struct sk_buff *skb, struct net_device *dev) -+{ -+ /* we don't support I/O for now, drop the frame */ -+ dev_kfree_skb_any(skb); -+ return NETDEV_TX_OK; -+} -+ -+static int evb_links_state_update(struct evb_priv *priv) -+{ -+ struct evb_port_priv *port_priv; -+ struct list_head *pos; -+ int err; -+ -+ list_for_each(pos, &priv->port_list) { -+ port_priv = list_entry(pos, struct evb_port_priv, list); -+ -+ err = _evb_port_carrier_state_sync(port_priv->netdev); -+ if (err) -+ netdev_err(port_priv->netdev, -+ "_evb_port_carrier_state_sync err %d\n", -+ err); -+ } -+ -+ return 0; -+} -+ -+static irqreturn_t evb_irq0_handler(int irq_num, void *arg) -+{ -+ return IRQ_WAKE_THREAD; -+} -+ -+static irqreturn_t _evb_irq0_handler_thread(int irq_num, void *arg) -+{ -+ struct device *dev = (struct device *)arg; -+ struct fsl_mc_device *evb_dev = to_fsl_mc_device(dev); -+ struct net_device *netdev = dev_get_drvdata(dev); -+ struct evb_priv *priv = netdev_priv(netdev); -+ struct fsl_mc_io *io = priv->mc_io; -+ u16 token = priv->mux_handle; -+ int irq_index = DPDMUX_IRQ_INDEX_IF; -+ -+ /* Mask the events and the if_id reserved bits to be cleared on read */ -+ u32 status = DPDMUX_IRQ_EVENT_LINK_CHANGED | 0xFFFF0000; -+ int err; -+ -+ /* Sanity check */ -+ if (WARN_ON(!evb_dev || !evb_dev->irqs || !evb_dev->irqs[irq_index])) -+ goto out; -+ if (WARN_ON(evb_dev->irqs[irq_index]->msi_desc->irq != irq_num)) -+ goto out; -+ -+ err = dpdmux_get_irq_status(io, 0, token, irq_index, &status); -+ if (unlikely(err)) { -+ netdev_err(netdev, "Can't get irq status (err %d)", err); -+ err = dpdmux_clear_irq_status(io, 0, token, irq_index, -+ 0xFFFFFFFF); -+ if (unlikely(err)) -+ netdev_err(netdev, "Can't clear irq status (err %d)", -+ err); -+ goto out; -+ } -+ -+ if (status & DPDMUX_IRQ_EVENT_LINK_CHANGED) { -+ err = evb_links_state_update(priv); -+ if (unlikely(err)) -+ goto out; -+ } -+ -+out: -+ return IRQ_HANDLED; -+} -+ -+static int evb_setup_irqs(struct fsl_mc_device *evb_dev) -+{ -+ struct device *dev = &evb_dev->dev; -+ struct net_device *netdev = dev_get_drvdata(dev); -+ struct evb_priv *priv = netdev_priv(netdev); -+ int err = 0; -+ struct fsl_mc_device_irq *irq; -+ const int irq_index = DPDMUX_IRQ_INDEX_IF; -+ u32 mask = DPDMUX_IRQ_EVENT_LINK_CHANGED; -+ -+ err = fsl_mc_allocate_irqs(evb_dev); -+ if (unlikely(err)) { -+ dev_err(dev, "MC irqs allocation failed\n"); -+ return err; -+ } -+ -+ if (WARN_ON(evb_dev->obj_desc.irq_count != DPDMUX_MAX_IRQ_NUM)) { -+ err = -EINVAL; -+ goto free_irq; -+ } -+ -+ err = dpdmux_set_irq_enable(priv->mc_io, 0, priv->mux_handle, -+ irq_index, 0); -+ if (unlikely(err)) { -+ dev_err(dev, "dpdmux_set_irq_enable err %d\n", err); -+ goto free_irq; -+ } -+ -+ irq = evb_dev->irqs[irq_index]; -+ -+ err = devm_request_threaded_irq(dev, irq->msi_desc->irq, -+ evb_irq0_handler, -+ _evb_irq0_handler_thread, -+ IRQF_NO_SUSPEND | IRQF_ONESHOT, -+ dev_name(dev), dev); -+ if (unlikely(err)) { -+ dev_err(dev, "devm_request_threaded_irq(): %d", err); -+ goto free_irq; -+ } -+ -+ err = dpdmux_set_irq_mask(priv->mc_io, 0, priv->mux_handle, -+ irq_index, mask); -+ if (unlikely(err)) { -+ dev_err(dev, "dpdmux_set_irq_mask(): %d", err); -+ goto free_devm_irq; -+ } -+ -+ err = dpdmux_set_irq_enable(priv->mc_io, 0, priv->mux_handle, -+ irq_index, 1); -+ if (unlikely(err)) { -+ dev_err(dev, "dpdmux_set_irq_enable(): %d", err); -+ goto free_devm_irq; -+ } -+ -+ return 0; -+ -+free_devm_irq: -+ devm_free_irq(dev, irq->msi_desc->irq, dev); -+free_irq: -+ fsl_mc_free_irqs(evb_dev); -+ return err; -+} -+ -+static void evb_teardown_irqs(struct fsl_mc_device *evb_dev) -+{ -+ struct device *dev = &evb_dev->dev; -+ struct net_device *netdev = dev_get_drvdata(dev); -+ struct evb_priv *priv = netdev_priv(netdev); -+ -+ dpdmux_set_irq_enable(priv->mc_io, 0, priv->mux_handle, -+ DPDMUX_IRQ_INDEX_IF, 0); -+ -+ devm_free_irq(dev, -+ evb_dev->irqs[DPDMUX_IRQ_INDEX_IF]->msi_desc->irq, -+ dev); -+ fsl_mc_free_irqs(evb_dev); -+} -+ -+static int evb_port_add_rule(struct net_device *netdev, -+ const unsigned char *addr, u16 vid) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ struct dpdmux_l2_rule rule = { .vlan_id = vid }; -+ int err; -+ -+ if (addr) -+ ether_addr_copy(rule.mac_addr, addr); -+ -+ err = dpdmux_if_add_l2_rule(port_priv->evb_priv->mc_io, -+ 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, &rule); -+ if (unlikely(err)) -+ netdev_err(netdev, "dpdmux_if_add_l2_rule err %d\n", err); -+ return err; -+} -+ -+static int evb_port_del_rule(struct net_device *netdev, -+ const unsigned char *addr, u16 vid) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ struct dpdmux_l2_rule rule = { .vlan_id = vid }; -+ int err; -+ -+ if (addr) -+ ether_addr_copy(rule.mac_addr, addr); -+ -+ err = dpdmux_if_remove_l2_rule(port_priv->evb_priv->mc_io, -+ 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, &rule); -+ if (unlikely(err)) -+ netdev_err(netdev, "dpdmux_if_remove_l2_rule err %d\n", err); -+ return err; -+} -+ -+static bool _lookup_address(struct net_device *netdev, -+ const unsigned char *addr) -+{ -+ struct netdev_hw_addr *ha; -+ struct netdev_hw_addr_list *list = (is_unicast_ether_addr(addr)) ? -+ &netdev->uc : &netdev->mc; -+ -+ netif_addr_lock_bh(netdev); -+ list_for_each_entry(ha, &list->list, list) { -+ if (ether_addr_equal(ha->addr, addr)) { -+ netif_addr_unlock_bh(netdev); -+ return true; -+ } -+ } -+ netif_addr_unlock_bh(netdev); -+ return false; -+} -+ -+static inline int evb_port_fdb_prep(struct nlattr *tb[], -+ struct net_device *netdev, -+ const unsigned char *addr, u16 *vid, -+ bool del) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ struct evb_priv *evb_priv = port_priv->evb_priv; -+ -+ *vid = 0; -+ -+ if (evb_priv->attr.method != DPDMUX_METHOD_MAC && -+ evb_priv->attr.method != DPDMUX_METHOD_C_VLAN_MAC) { -+ netdev_err(netdev, -+ "EVB mode does not support MAC classification\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ /* check if the address is configured on this port */ -+ if (_lookup_address(netdev, addr)) { -+ if (!del) -+ return -EEXIST; -+ } else { -+ if (del) -+ return -ENOENT; -+ } -+ -+ if (tb[NDA_VLAN] && evb_priv->attr.method == DPDMUX_METHOD_C_VLAN_MAC) { -+ if (nla_len(tb[NDA_VLAN]) != sizeof(unsigned short)) { -+ netdev_err(netdev, "invalid vlan size %d\n", -+ nla_len(tb[NDA_VLAN])); -+ return -EINVAL; -+ } -+ -+ *vid = nla_get_u16(tb[NDA_VLAN]); -+ -+ if (!*vid || *vid >= VLAN_VID_MASK) { -+ netdev_err(netdev, "invalid vid value 0x%04x\n", *vid); -+ return -EINVAL; -+ } -+ } else if (evb_priv->attr.method == DPDMUX_METHOD_C_VLAN_MAC) { -+ netdev_err(netdev, -+ "EVB mode requires explicit VLAN configuration\n"); -+ return -EINVAL; -+ } else if (tb[NDA_VLAN]) { -+ netdev_warn(netdev, "VLAN not supported, argument ignored\n"); -+ } -+ -+ return 0; -+} -+ -+static int evb_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], -+ struct net_device *netdev, -+ const unsigned char *addr, u16 vid, u16 flags, -+ struct netlink_ext_ack *extack) -+{ -+ u16 _vid; -+ int err; -+ -+ /* TODO: add replace support when added to iproute bridge */ -+ if (!(flags & NLM_F_REQUEST)) { -+ netdev_err(netdev, -+ "evb_port_fdb_add unexpected flags value %08x\n", -+ flags); -+ return -EINVAL; -+ } -+ -+ err = evb_port_fdb_prep(tb, netdev, addr, &_vid, 0); -+ if (unlikely(err)) -+ return err; -+ -+ err = evb_port_add_rule(netdev, addr, _vid); -+ if (unlikely(err)) -+ return err; -+ -+ if (is_unicast_ether_addr(addr)) { -+ err = dev_uc_add(netdev, addr); -+ if (unlikely(err)) { -+ netdev_err(netdev, "dev_uc_add err %d\n", err); -+ return err; -+ } -+ } else { -+ err = dev_mc_add(netdev, addr); -+ if (unlikely(err)) { -+ netdev_err(netdev, "dev_mc_add err %d\n", err); -+ return err; -+ } -+ } -+ -+ return 0; -+} -+ -+static int evb_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], -+ struct net_device *netdev, -+ const unsigned char *addr, u16 vid) -+{ -+ u16 _vid; -+ int err; -+ -+ err = evb_port_fdb_prep(tb, netdev, addr, &_vid, 1); -+ if (unlikely(err)) -+ return err; -+ -+ err = evb_port_del_rule(netdev, addr, _vid); -+ if (unlikely(err)) -+ return err; -+ -+ if (is_unicast_ether_addr(addr)) { -+ err = dev_uc_del(netdev, addr); -+ if (unlikely(err)) { -+ netdev_err(netdev, "dev_uc_del err %d\n", err); -+ return err; -+ } -+ } else { -+ err = dev_mc_del(netdev, addr); -+ if (unlikely(err)) { -+ netdev_err(netdev, "dev_mc_del err %d\n", err); -+ return err; -+ } -+ } -+ -+ return 0; -+} -+ -+static int evb_change_mtu(struct net_device *netdev, -+ int mtu) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ struct evb_priv *evb_priv = port_priv->evb_priv; -+ struct list_head *pos; -+ int err = 0; -+ -+ /* This operation is not permitted on downlinks */ -+ if (port_priv->port_index > 0) -+ return -EPERM; -+ -+ if (mtu < EVB_MIN_FRAME_LENGTH || mtu > EVB_MAX_FRAME_LENGTH) { -+ netdev_err(netdev, "Invalid MTU %d. Valid range is: %d..%d\n", -+ mtu, EVB_MIN_FRAME_LENGTH, EVB_MAX_FRAME_LENGTH); -+ return -EINVAL; -+ } -+ -+ err = dpdmux_set_max_frame_length(evb_priv->mc_io, -+ 0, -+ evb_priv->mux_handle, -+ (uint16_t)mtu); -+ -+ if (unlikely(err)) { -+ netdev_err(netdev, "dpdmux_ul_set_max_frame_length err %d\n", -+ err); -+ return err; -+ } -+ -+ /* Update the max frame length for downlinks */ -+ list_for_each(pos, &evb_priv->port_list) { -+ port_priv = list_entry(pos, struct evb_port_priv, list); -+ port_priv->netdev->mtu = mtu; -+ } -+ -+ netdev->mtu = mtu; -+ return 0; -+} -+ -+static const struct nla_policy ifla_br_policy[IFLA_MAX + 1] = { -+ [IFLA_BRIDGE_FLAGS] = { .type = NLA_U16 }, -+ [IFLA_BRIDGE_MODE] = { .type = NLA_U16 }, -+ [IFLA_BRIDGE_VLAN_INFO] = { .type = NLA_BINARY, -+ .len = sizeof(struct bridge_vlan_info), }, -+}; -+ -+static int evb_setlink_af_spec(struct net_device *netdev, -+ struct nlattr **tb) -+{ -+ struct bridge_vlan_info *vinfo; -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ int err = 0; -+ -+ if (!tb[IFLA_BRIDGE_VLAN_INFO]) { -+ netdev_err(netdev, "no VLAN INFO in nlmsg\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ vinfo = nla_data(tb[IFLA_BRIDGE_VLAN_INFO]); -+ -+ if (!vinfo->vid || vinfo->vid > VLAN_VID_MASK) -+ return -EINVAL; -+ -+ err = evb_port_add_rule(netdev, NULL, vinfo->vid); -+ if (unlikely(err)) -+ return err; -+ -+ port_priv->vlans[vinfo->vid] = 1; -+ -+ return 0; -+} -+ -+static int evb_setlink(struct net_device *netdev, -+ struct nlmsghdr *nlh, -+ u16 flags, -+ struct netlink_ext_ack *extack) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ struct evb_priv *evb_priv = port_priv->evb_priv; -+ struct nlattr *attr; -+ struct nlattr *tb[(IFLA_BRIDGE_MAX > IFLA_BRPORT_MAX) ? -+ IFLA_BRIDGE_MAX : IFLA_BRPORT_MAX + 1]; -+ int err = 0; -+ -+ if (evb_priv->attr.method != DPDMUX_METHOD_C_VLAN && -+ evb_priv->attr.method != DPDMUX_METHOD_S_VLAN) { -+ netdev_err(netdev, -+ "EVB mode does not support VLAN only classification\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ attr = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); -+ if (attr) { -+ err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, attr, -+ ifla_br_policy); -+ if (unlikely(err)) { -+ netdev_err(netdev, -+ "nla_parse_nested for br_policy err %d\n", -+ err); -+ return err; -+ } -+ -+ err = evb_setlink_af_spec(netdev, tb); -+ return err; -+ } -+ -+ netdev_err(netdev, "nlmsg_find_attr found no AF_SPEC\n"); -+ return -EOPNOTSUPP; -+} -+ -+static int __nla_put_netdev(struct sk_buff *skb, struct net_device *netdev) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ struct evb_priv *evb_priv = port_priv->evb_priv; -+ u8 operstate = netif_running(netdev) ? -+ netdev->operstate : IF_OPER_DOWN; -+ int iflink; -+ int err; -+ -+ err = nla_put_string(skb, IFLA_IFNAME, netdev->name); -+ if (unlikely(err)) -+ goto nla_put_err; -+ err = nla_put_u32(skb, IFLA_MASTER, evb_priv->uplink.netdev->ifindex); -+ if (unlikely(err)) -+ goto nla_put_err; -+ err = nla_put_u32(skb, IFLA_MTU, netdev->mtu); -+ if (unlikely(err)) -+ goto nla_put_err; -+ err = nla_put_u8(skb, IFLA_OPERSTATE, operstate); -+ if (unlikely(err)) -+ goto nla_put_err; -+ if (netdev->addr_len) { -+ err = nla_put(skb, IFLA_ADDRESS, netdev->addr_len, -+ netdev->dev_addr); -+ if (unlikely(err)) -+ goto nla_put_err; -+ } -+ -+ iflink = dev_get_iflink(netdev); -+ if (netdev->ifindex != iflink) { -+ err = nla_put_u32(skb, IFLA_LINK, iflink); -+ if (unlikely(err)) -+ goto nla_put_err; -+ } -+ -+ return 0; -+ -+nla_put_err: -+ netdev_err(netdev, "nla_put_ err %d\n", err); -+ return err; -+} -+ -+static int __nla_put_port(struct sk_buff *skb, struct net_device *netdev) -+{ -+ struct nlattr *nest; -+ int err; -+ -+ nest = nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED); -+ if (!nest) { -+ netdev_err(netdev, "nla_nest_start failed\n"); -+ return -ENOMEM; -+ } -+ -+ err = nla_put_u8(skb, IFLA_BRPORT_STATE, BR_STATE_FORWARDING); -+ if (unlikely(err)) -+ goto nla_put_err; -+ err = nla_put_u16(skb, IFLA_BRPORT_PRIORITY, 0); -+ if (unlikely(err)) -+ goto nla_put_err; -+ err = nla_put_u32(skb, IFLA_BRPORT_COST, 0); -+ if (unlikely(err)) -+ goto nla_put_err; -+ err = nla_put_u8(skb, IFLA_BRPORT_MODE, 0); -+ if (unlikely(err)) -+ goto nla_put_err; -+ err = nla_put_u8(skb, IFLA_BRPORT_GUARD, 0); -+ if (unlikely(err)) -+ goto nla_put_err; -+ err = nla_put_u8(skb, IFLA_BRPORT_PROTECT, 0); -+ if (unlikely(err)) -+ goto nla_put_err; -+ err = nla_put_u8(skb, IFLA_BRPORT_FAST_LEAVE, 0); -+ if (unlikely(err)) -+ goto nla_put_err; -+ err = nla_put_u8(skb, IFLA_BRPORT_LEARNING, 0); -+ if (unlikely(err)) -+ goto nla_put_err; -+ err = nla_put_u8(skb, IFLA_BRPORT_UNICAST_FLOOD, 1); -+ if (unlikely(err)) -+ goto nla_put_err; -+ nla_nest_end(skb, nest); -+ -+ return 0; -+ -+nla_put_err: -+ netdev_err(netdev, "nla_put_ err %d\n", err); -+ nla_nest_cancel(skb, nest); -+ return err; -+} -+ -+static int __nla_put_vlan(struct sk_buff *skb, struct net_device *netdev) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ struct nlattr *nest; -+ struct bridge_vlan_info vinfo; -+ const u8 *vlans = port_priv->vlans; -+ u16 i; -+ int err; -+ -+ nest = nla_nest_start(skb, IFLA_AF_SPEC); -+ if (!nest) { -+ netdev_err(netdev, "nla_nest_start failed"); -+ return -ENOMEM; -+ } -+ -+ for (i = 0; i < VLAN_VID_MASK + 1; i++) { -+ if (!vlans[i]) -+ continue; -+ -+ vinfo.flags = 0; -+ vinfo.vid = i; -+ -+ err = nla_put(skb, IFLA_BRIDGE_VLAN_INFO, -+ sizeof(vinfo), &vinfo); -+ if (unlikely(err)) -+ goto nla_put_err; -+ } -+ -+ nla_nest_end(skb, nest); -+ -+ return 0; -+ -+nla_put_err: -+ netdev_err(netdev, "nla_put_ err %d\n", err); -+ nla_nest_cancel(skb, nest); -+ return err; -+} -+ -+static int evb_getlink(struct sk_buff *skb, u32 pid, u32 seq, -+ struct net_device *netdev, u32 filter_mask, int nlflags) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ struct evb_priv *evb_priv = port_priv->evb_priv; -+ struct ifinfomsg *hdr; -+ struct nlmsghdr *nlh; -+ int err; -+ -+ if (evb_priv->attr.method != DPDMUX_METHOD_C_VLAN && -+ evb_priv->attr.method != DPDMUX_METHOD_S_VLAN) { -+ return 0; -+ } -+ -+ nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*hdr), NLM_F_MULTI); -+ if (!nlh) -+ return -EMSGSIZE; -+ -+ hdr = nlmsg_data(nlh); -+ memset(hdr, 0, sizeof(*hdr)); -+ hdr->ifi_family = AF_BRIDGE; -+ hdr->ifi_type = netdev->type; -+ hdr->ifi_index = netdev->ifindex; -+ hdr->ifi_flags = dev_get_flags(netdev); -+ -+ err = __nla_put_netdev(skb, netdev); -+ if (unlikely(err)) -+ goto nla_put_err; -+ -+ err = __nla_put_port(skb, netdev); -+ if (unlikely(err)) -+ goto nla_put_err; -+ -+ /* Check if the VID information is requested */ -+ if (filter_mask & RTEXT_FILTER_BRVLAN) { -+ err = __nla_put_vlan(skb, netdev); -+ if (unlikely(err)) -+ goto nla_put_err; -+ } -+ -+ nlmsg_end(skb, nlh); -+ return skb->len; -+ -+nla_put_err: -+ nlmsg_cancel(skb, nlh); -+ return -EMSGSIZE; -+} -+ -+static int evb_dellink(struct net_device *netdev, -+ struct nlmsghdr *nlh, -+ u16 flags) -+{ -+ struct nlattr *tb[IFLA_BRIDGE_MAX + 1]; -+ struct nlattr *spec; -+ struct bridge_vlan_info *vinfo; -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ int err = 0; -+ -+ spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); -+ if (!spec) -+ return 0; -+ -+ err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, spec, ifla_br_policy); -+ if (unlikely(err)) -+ return err; -+ -+ if (!tb[IFLA_BRIDGE_VLAN_INFO]) -+ return -EOPNOTSUPP; -+ -+ vinfo = nla_data(tb[IFLA_BRIDGE_VLAN_INFO]); -+ -+ if (!vinfo->vid || vinfo->vid > VLAN_VID_MASK) -+ return -EINVAL; -+ -+ err = evb_port_del_rule(netdev, NULL, vinfo->vid); -+ if (unlikely(err)) { -+ netdev_err(netdev, "evb_port_del_rule err %d\n", err); -+ return err; -+ } -+ port_priv->vlans[vinfo->vid] = 0; -+ -+ return 0; -+} -+ -+void evb_port_get_stats(struct net_device *netdev, -+ struct rtnl_link_stats64 *storage) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ u64 tmp; -+ int err; -+ -+ err = dpdmux_if_get_counter(port_priv->evb_priv->mc_io, -+ 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ DPDMUX_CNT_ING_FRAME, &storage->rx_packets); -+ if (unlikely(err)) -+ goto error; -+ -+ err = dpdmux_if_get_counter(port_priv->evb_priv->mc_io, -+ 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ DPDMUX_CNT_ING_BYTE, &storage->rx_bytes); -+ if (unlikely(err)) -+ goto error; -+ -+ err = dpdmux_if_get_counter(port_priv->evb_priv->mc_io, -+ 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ DPDMUX_CNT_ING_FLTR_FRAME, &tmp); -+ if (unlikely(err)) -+ goto error; -+ -+ err = dpdmux_if_get_counter(port_priv->evb_priv->mc_io, -+ 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ DPDMUX_CNT_ING_FRAME_DISCARD, -+ &storage->rx_dropped); -+ if (unlikely(err)) { -+ storage->rx_dropped = tmp; -+ goto error; -+ } -+ storage->rx_dropped += tmp; -+ -+ err = dpdmux_if_get_counter(port_priv->evb_priv->mc_io, -+ 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ DPDMUX_CNT_ING_MCAST_FRAME, -+ &storage->multicast); -+ if (unlikely(err)) -+ goto error; -+ -+ err = dpdmux_if_get_counter(port_priv->evb_priv->mc_io, -+ 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ DPDMUX_CNT_EGR_FRAME, &storage->tx_packets); -+ if (unlikely(err)) -+ goto error; -+ -+ err = dpdmux_if_get_counter(port_priv->evb_priv->mc_io, -+ 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ DPDMUX_CNT_EGR_BYTE, &storage->tx_bytes); -+ if (unlikely(err)) -+ goto error; -+ -+ err = dpdmux_if_get_counter(port_priv->evb_priv->mc_io, -+ 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ DPDMUX_CNT_EGR_FRAME_DISCARD, -+ &storage->tx_dropped); -+ if (unlikely(err)) -+ goto error; -+ -+ return; -+ -+error: -+ netdev_err(netdev, "dpdmux_if_get_counter err %d\n", err); -+} -+ -+static const struct net_device_ops evb_port_ops = { -+ .ndo_open = &evb_port_open, -+ -+ .ndo_start_xmit = &evb_dropframe, -+ -+ .ndo_fdb_add = &evb_port_fdb_add, -+ .ndo_fdb_del = &evb_port_fdb_del, -+ -+ .ndo_get_stats64 = &evb_port_get_stats, -+ .ndo_change_mtu = &evb_change_mtu, -+}; -+ -+static struct { -+ enum dpdmux_counter_type id; -+ char name[ETH_GSTRING_LEN]; -+} evb_ethtool_counters[] = { -+ {DPDMUX_CNT_ING_FRAME, "rx frames"}, -+ {DPDMUX_CNT_ING_BYTE, "rx bytes"}, -+ {DPDMUX_CNT_ING_FLTR_FRAME, "rx filtered frames"}, -+ {DPDMUX_CNT_ING_FRAME_DISCARD, "rx discarded frames"}, -+ {DPDMUX_CNT_ING_BCAST_FRAME, "rx b-cast frames"}, -+ {DPDMUX_CNT_ING_BCAST_BYTES, "rx b-cast bytes"}, -+ {DPDMUX_CNT_ING_MCAST_FRAME, "rx m-cast frames"}, -+ {DPDMUX_CNT_ING_MCAST_BYTE, "rx m-cast bytes"}, -+ {DPDMUX_CNT_EGR_FRAME, "tx frames"}, -+ {DPDMUX_CNT_EGR_BYTE, "tx bytes"}, -+ {DPDMUX_CNT_EGR_FRAME_DISCARD, "tx discarded frames"}, -+}; -+ -+static int evb_ethtool_get_sset_count(struct net_device *dev, int sset) -+{ -+ switch (sset) { -+ case ETH_SS_STATS: -+ return ARRAY_SIZE(evb_ethtool_counters); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+static void evb_ethtool_get_strings(struct net_device *netdev, -+ u32 stringset, u8 *data) -+{ -+ int i; -+ -+ switch (stringset) { -+ case ETH_SS_STATS: -+ for (i = 0; i < ARRAY_SIZE(evb_ethtool_counters); i++) -+ memcpy(data + i * ETH_GSTRING_LEN, -+ evb_ethtool_counters[i].name, ETH_GSTRING_LEN); -+ break; -+ } -+} -+ -+static void evb_ethtool_get_stats(struct net_device *netdev, -+ struct ethtool_stats *stats, -+ u64 *data) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ int i; -+ int err; -+ -+ for (i = 0; i < ARRAY_SIZE(evb_ethtool_counters); i++) { -+ err = dpdmux_if_get_counter(port_priv->evb_priv->mc_io, -+ 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ evb_ethtool_counters[i].id, -+ &data[i]); -+ if (err) -+ netdev_err(netdev, "dpdmux_if_get_counter[%s] err %d\n", -+ evb_ethtool_counters[i].name, err); -+ } -+} -+ -+static const struct ethtool_ops evb_port_ethtool_ops = { -+ .get_strings = &evb_ethtool_get_strings, -+ .get_ethtool_stats = &evb_ethtool_get_stats, -+ .get_sset_count = &evb_ethtool_get_sset_count, -+}; -+ -+static int evb_open(struct net_device *netdev) -+{ -+ struct evb_priv *priv = netdev_priv(netdev); -+ int err = 0; -+ -+ err = dpdmux_enable(priv->mc_io, 0, priv->mux_handle); -+ if (unlikely(err)) -+ netdev_err(netdev, "dpdmux_enable err %d\n", err); -+ -+ return err; -+} -+ -+static int evb_close(struct net_device *netdev) -+{ -+ struct evb_priv *priv = netdev_priv(netdev); -+ int err = 0; -+ -+ err = dpdmux_disable(priv->mc_io, 0, priv->mux_handle); -+ if (unlikely(err)) -+ netdev_err(netdev, "dpdmux_disable err %d\n", err); -+ -+ return err; -+} -+ -+static const struct net_device_ops evb_ops = { -+ .ndo_start_xmit = &evb_dropframe, -+ .ndo_open = &evb_open, -+ .ndo_stop = &evb_close, -+ -+ .ndo_bridge_setlink = &evb_setlink, -+ .ndo_bridge_getlink = &evb_getlink, -+ .ndo_bridge_dellink = &evb_dellink, -+ -+ .ndo_get_stats64 = &evb_port_get_stats, -+ .ndo_change_mtu = &evb_change_mtu, -+}; -+ -+static int evb_takedown(struct fsl_mc_device *evb_dev) -+{ -+ struct device *dev = &evb_dev->dev; -+ struct net_device *netdev = dev_get_drvdata(dev); -+ struct evb_priv *priv = netdev_priv(netdev); -+ int err; -+ -+ err = dpdmux_close(priv->mc_io, 0, priv->mux_handle); -+ if (unlikely(err)) -+ dev_warn(dev, "dpdmux_close err %d\n", err); -+ -+ return 0; -+} -+ -+static int evb_init(struct fsl_mc_device *evb_dev) -+{ -+ struct device *dev = &evb_dev->dev; -+ struct net_device *netdev = dev_get_drvdata(dev); -+ struct evb_priv *priv = netdev_priv(netdev); -+ u16 version_major; -+ u16 version_minor; -+ int err = 0; -+ -+ priv->dev_id = evb_dev->obj_desc.id; -+ -+ err = dpdmux_open(priv->mc_io, 0, priv->dev_id, &priv->mux_handle); -+ if (unlikely(err)) { -+ dev_err(dev, "dpdmux_open err %d\n", err); -+ goto err_exit; -+ } -+ if (!priv->mux_handle) { -+ dev_err(dev, "dpdmux_open returned null handle but no error\n"); -+ err = -EFAULT; -+ goto err_exit; -+ } -+ -+ err = dpdmux_get_attributes(priv->mc_io, 0, priv->mux_handle, -+ &priv->attr); -+ if (unlikely(err)) { -+ dev_err(dev, "dpdmux_get_attributes err %d\n", err); -+ goto err_close; -+ } -+ -+ err = dpdmux_get_api_version(priv->mc_io, 0, -+ &version_major, -+ &version_minor); -+ if (unlikely(err)) { -+ dev_err(dev, "dpdmux_get_api_version err %d\n", err); -+ goto err_close; -+ } -+ -+ /* Minimum supported DPDMUX version check */ -+ if (version_major < DPDMUX_MIN_VER_MAJOR || -+ (version_major == DPDMUX_MIN_VER_MAJOR && -+ version_minor < DPDMUX_MIN_VER_MINOR)) { -+ dev_err(dev, "DPDMUX version %d.%d not supported. Use %d.%d or greater.\n", -+ version_major, version_minor, -+ DPDMUX_MIN_VER_MAJOR, DPDMUX_MIN_VER_MAJOR); -+ err = -ENOTSUPP; -+ goto err_close; -+ } -+ -+ err = dpdmux_reset(priv->mc_io, 0, priv->mux_handle); -+ if (unlikely(err)) { -+ dev_err(dev, "dpdmux_reset err %d\n", err); -+ goto err_close; -+ } -+ -+ return 0; -+ -+err_close: -+ dpdmux_close(priv->mc_io, 0, priv->mux_handle); -+err_exit: -+ return err; -+} -+ -+static int evb_remove(struct fsl_mc_device *evb_dev) -+{ -+ struct device *dev = &evb_dev->dev; -+ struct net_device *netdev = dev_get_drvdata(dev); -+ struct evb_priv *priv = netdev_priv(netdev); -+ struct evb_port_priv *port_priv; -+ struct list_head *pos; -+ -+ list_for_each(pos, &priv->port_list) { -+ port_priv = list_entry(pos, struct evb_port_priv, list); -+ -+ rtnl_lock(); -+ netdev_upper_dev_unlink(port_priv->netdev, netdev); -+ rtnl_unlock(); -+ -+ unregister_netdev(port_priv->netdev); -+ free_netdev(port_priv->netdev); -+ } -+ -+ evb_teardown_irqs(evb_dev); -+ -+ unregister_netdev(netdev); -+ -+ evb_takedown(evb_dev); -+ fsl_mc_portal_free(priv->mc_io); -+ -+ dev_set_drvdata(dev, NULL); -+ free_netdev(netdev); -+ -+ return 0; -+} -+ -+static int evb_probe(struct fsl_mc_device *evb_dev) -+{ -+ struct device *dev; -+ struct evb_priv *priv = NULL; -+ struct net_device *netdev = NULL; -+ char port_name[IFNAMSIZ]; -+ int i; -+ int err = 0; -+ -+ dev = &evb_dev->dev; -+ -+ /* register switch device, it's for management only - no I/O */ -+ netdev = alloc_etherdev(sizeof(*priv)); -+ if (!netdev) { -+ dev_err(dev, "alloc_etherdev error\n"); -+ return -ENOMEM; -+ } -+ netdev->netdev_ops = &evb_ops; -+ -+ dev_set_drvdata(dev, netdev); -+ -+ priv = netdev_priv(netdev); -+ -+ err = fsl_mc_portal_allocate(evb_dev, 0, &priv->mc_io); -+ if (unlikely(err)) { -+ dev_err(dev, "fsl_mc_portal_allocate err %d\n", err); -+ goto err_free_netdev; -+ } -+ if (!priv->mc_io) { -+ dev_err(dev, "fsl_mc_portal_allocate returned null handle but no error\n"); -+ err = -EFAULT; -+ goto err_free_netdev; -+ } -+ -+ err = evb_init(evb_dev); -+ if (unlikely(err)) { -+ dev_err(dev, "evb init err %d\n", err); -+ goto err_free_cmdport; -+ } -+ -+ INIT_LIST_HEAD(&priv->port_list); -+ netdev->flags |= IFF_PROMISC | IFF_MASTER; -+ -+ dev_alloc_name(netdev, "evb%d"); -+ -+ /* register switch ports */ -+ snprintf(port_name, IFNAMSIZ, "%sp%%d", netdev->name); -+ -+ /* only register downlinks? */ -+ for (i = 0; i < priv->attr.num_ifs + 1; i++) { -+ struct net_device *port_netdev; -+ struct evb_port_priv *port_priv; -+ -+ if (i) { -+ port_netdev = -+ alloc_etherdev(sizeof(struct evb_port_priv)); -+ if (!port_netdev) { -+ dev_err(dev, "alloc_etherdev error\n"); -+ goto err_takedown; -+ } -+ -+ port_priv = netdev_priv(port_netdev); -+ -+ port_netdev->flags |= IFF_PROMISC | IFF_SLAVE; -+ -+ dev_alloc_name(port_netdev, port_name); -+ } else { -+ port_netdev = netdev; -+ port_priv = &priv->uplink; -+ } -+ -+ port_priv->netdev = port_netdev; -+ port_priv->evb_priv = priv; -+ port_priv->port_index = i; -+ -+ SET_NETDEV_DEV(port_netdev, dev); -+ -+ if (i) { -+ port_netdev->netdev_ops = &evb_port_ops; -+ -+ err = register_netdev(port_netdev); -+ if (err < 0) { -+ dev_err(dev, "register_netdev err %d\n", err); -+ free_netdev(port_netdev); -+ goto err_takedown; -+ } -+ -+ rtnl_lock(); -+ err = netdev_master_upper_dev_link(port_netdev, netdev, -+ NULL, NULL); -+ if (unlikely(err)) { -+ dev_err(dev, "netdev_master_upper_dev_link err %d\n", -+ err); -+ unregister_netdev(port_netdev); -+ free_netdev(port_netdev); -+ rtnl_unlock(); -+ goto err_takedown; -+ } -+ rtmsg_ifinfo(RTM_NEWLINK, port_netdev, -+ IFF_SLAVE, GFP_KERNEL); -+ rtnl_unlock(); -+ -+ list_add(&port_priv->list, &priv->port_list); -+ } else { -+ err = register_netdev(netdev); -+ -+ if (err < 0) { -+ dev_err(dev, "register_netdev error %d\n", err); -+ goto err_takedown; -+ } -+ } -+ -+ port_netdev->ethtool_ops = &evb_port_ethtool_ops; -+ -+ /* ports are up from init */ -+ rtnl_lock(); -+ err = dev_open(port_netdev, NULL); -+ rtnl_unlock(); -+ if (unlikely(err)) -+ dev_warn(dev, "dev_open err %d\n", err); -+ } -+ -+ /* setup irqs */ -+ err = evb_setup_irqs(evb_dev); -+ if (unlikely(err)) { -+ dev_warn(dev, "evb_setup_irqs err %d\n", err); -+ goto err_takedown; -+ } -+ -+ dev_info(dev, "probed evb device with %d ports\n", -+ priv->attr.num_ifs); -+ return 0; -+ -+err_takedown: -+ evb_remove(evb_dev); -+err_free_cmdport: -+ fsl_mc_portal_free(priv->mc_io); -+err_free_netdev: -+ return err; -+} -+ -+static const struct fsl_mc_device_id evb_match_id_table[] = { -+ { -+ .vendor = FSL_MC_VENDOR_FREESCALE, -+ .obj_type = "dpdmux", -+ }, -+ {} -+}; -+ -+static struct fsl_mc_driver evb_drv = { -+ .driver = { -+ .name = KBUILD_MODNAME, -+ .owner = THIS_MODULE, -+ }, -+ .probe = evb_probe, -+ .remove = evb_remove, -+ .match_id_table = evb_match_id_table, -+}; -+ -+module_fsl_mc_driver(evb_drv); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Layerscape DPAA Edge Virtual Bridge driver (prototype)"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0180-staging-dpaa2-evb-Fix-W-1-warnings.patch b/target/linux/layerscape/patches-5.4/701-net-0180-staging-dpaa2-evb-Fix-W-1-warnings.patch deleted file mode 100644 index 7f1ffdb122..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0180-staging-dpaa2-evb-Fix-W-1-warnings.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 18d400e71c415adc8a5e5c91e461968907d26606 Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Thu, 6 Apr 2017 11:02:57 +0300 -Subject: [PATCH] staging: dpaa2-evb: Fix W=1 warnings - -Fix warnings triggered by '-Wsign-compare' flag. - -Signed-off-by: Razvan Stefanescu ---- - drivers/staging/fsl-dpaa2/evb/evb.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/evb/evb.c -+++ b/drivers/staging/fsl-dpaa2/evb/evb.c -@@ -162,7 +162,7 @@ static irqreturn_t _evb_irq0_handler_thr - /* Sanity check */ - if (WARN_ON(!evb_dev || !evb_dev->irqs || !evb_dev->irqs[irq_index])) - goto out; -- if (WARN_ON(evb_dev->irqs[irq_index]->msi_desc->irq != irq_num)) -+ if (WARN_ON(evb_dev->irqs[irq_index]->msi_desc->irq != (u32)irq_num)) - goto out; - - err = dpdmux_get_irq_status(io, 0, token, irq_index, &status); -@@ -890,7 +890,7 @@ static int evb_ethtool_get_sset_count(st - static void evb_ethtool_get_strings(struct net_device *netdev, - u32 stringset, u8 *data) - { -- int i; -+ u32 i; - - switch (stringset) { - case ETH_SS_STATS: -@@ -906,7 +906,7 @@ static void evb_ethtool_get_stats(struct - u64 *data) - { - struct evb_port_priv *port_priv = netdev_priv(netdev); -- int i; -+ u32 i; - int err; - - for (i = 0; i < ARRAY_SIZE(evb_ethtool_counters); i++) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0181-staging-dpaa2-evb-Improve-ethtool-support.patch b/target/linux/layerscape/patches-5.4/701-net-0181-staging-dpaa2-evb-Improve-ethtool-support.patch deleted file mode 100644 index 5a566ee8f7..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0181-staging-dpaa2-evb-Improve-ethtool-support.patch +++ /dev/null @@ -1,153 +0,0 @@ -From b505f9a736c3850aa1dfefd7a803d797c2233aab Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Thu, 13 Apr 2017 13:10:34 +0300 -Subject: [PATCH] staging: dpaa2-evb: Improve ethtool support - -Improve ethtool support by adding ops for: -- driver info -- link status -- auto-negotiation setting and result -- speed setting and result - -Signed-off-by: Razvan Stefanescu ---- - drivers/staging/fsl-dpaa2/evb/evb.c | 114 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 114 insertions(+) - ---- a/drivers/staging/fsl-dpaa2/evb/evb.c -+++ b/drivers/staging/fsl-dpaa2/evb/evb.c -@@ -43,6 +43,8 @@ - #include "dpdmux.h" - #include "dpdmux-cmd.h" - -+static const char evb_drv_version[] = "0.1"; -+ - /* Minimal supported DPDMUX version */ - #define DPDMUX_MIN_VER_MAJOR 6 - #define DPDMUX_MIN_VER_MINOR 0 -@@ -860,6 +862,114 @@ static const struct net_device_ops evb_p - .ndo_change_mtu = &evb_change_mtu, - }; - -+static void evb_get_drvinfo(struct net_device *netdev, -+ struct ethtool_drvinfo *drvinfo) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ u16 version_major, version_minor; -+ int err; -+ -+ strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); -+ strlcpy(drvinfo->version, evb_drv_version, sizeof(drvinfo->version)); -+ -+ err = dpdmux_get_api_version(port_priv->evb_priv->mc_io, 0, -+ &version_major, -+ &version_minor); -+ if (err) -+ strlcpy(drvinfo->fw_version, "N/A", -+ sizeof(drvinfo->fw_version)); -+ else -+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), -+ "%u.%u", version_major, version_minor); -+ -+ strlcpy(drvinfo->bus_info, dev_name(netdev->dev.parent->parent), -+ sizeof(drvinfo->bus_info)); -+} -+ -+static int evb_get_link_ksettings(struct net_device *netdev, -+ struct ethtool_link_ksettings *link_settings) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ struct dpdmux_link_state state = {0}; -+ int err = 0; -+ -+ err = dpdmux_if_get_link_state(port_priv->evb_priv->mc_io, 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ &state); -+ if (err) { -+ netdev_err(netdev, "ERROR %d getting link state", err); -+ goto out; -+ } -+ -+ /* At the moment, we have no way of interrogating the DPMAC -+ * from the DPDMUX side or there may not exist a DPMAC at all. -+ * Report only autoneg state, duplexity and speed. -+ */ -+ if (state.options & DPDMUX_LINK_OPT_AUTONEG) -+ link_settings->base.autoneg = AUTONEG_ENABLE; -+ if (!(state.options & DPDMUX_LINK_OPT_HALF_DUPLEX)) -+ link_settings->base.duplex = DUPLEX_FULL; -+ link_settings->base.speed = state.rate; -+ -+out: -+ return err; -+} -+ -+static int evb_set_link_ksettings(struct net_device *netdev, -+ const struct ethtool_link_ksettings *link_settings) -+{ -+ struct evb_port_priv *port_priv = netdev_priv(netdev); -+ struct dpdmux_link_state state = {0}; -+ struct dpdmux_link_cfg cfg = {0}; -+ int err = 0; -+ -+ netdev_dbg(netdev, "Setting link parameters..."); -+ -+ err = dpdmux_if_get_link_state(port_priv->evb_priv->mc_io, 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ &state); -+ if (err) { -+ netdev_err(netdev, "ERROR %d getting link state", err); -+ goto out; -+ } -+ -+ /* Due to a temporary MC limitation, the DPDMUX port must be down -+ * in order to be able to change link settings. Taking steps to let -+ * the user know that. -+ */ -+ if (netif_running(netdev)) { -+ netdev_info(netdev, -+ "Sorry, interface must be brought down first.\n"); -+ return -EACCES; -+ } -+ -+ cfg.options = state.options; -+ cfg.rate = link_settings->base.speed; -+ if (link_settings->base.autoneg == AUTONEG_ENABLE) -+ cfg.options |= DPDMUX_LINK_OPT_AUTONEG; -+ else -+ cfg.options &= ~DPDMUX_LINK_OPT_AUTONEG; -+ if (link_settings->base.duplex == DUPLEX_HALF) -+ cfg.options |= DPDMUX_LINK_OPT_HALF_DUPLEX; -+ else -+ cfg.options &= ~DPDMUX_LINK_OPT_HALF_DUPLEX; -+ -+ err = dpdmux_if_set_link_cfg(port_priv->evb_priv->mc_io, 0, -+ port_priv->evb_priv->mux_handle, -+ port_priv->port_index, -+ &cfg); -+ if (err) -+ /* ethtool will be loud enough if we return an error; no point -+ * in putting our own error message on the console by default -+ */ -+ netdev_dbg(netdev, "ERROR %d setting link cfg", err); -+ -+out: -+ return err; -+} -+ - static struct { - enum dpdmux_counter_type id; - char name[ETH_GSTRING_LEN]; -@@ -923,6 +1033,10 @@ static void evb_ethtool_get_stats(struct - } - - static const struct ethtool_ops evb_port_ethtool_ops = { -+ .get_drvinfo = &evb_get_drvinfo, -+ .get_link = ðtool_op_get_link, -+ .get_link_ksettings = &evb_get_link_ksettings, -+ .set_link_ksettings = &evb_set_link_ksettings, - .get_strings = &evb_ethtool_get_strings, - .get_ethtool_stats = &evb_ethtool_get_stats, - .get_sset_count = &evb_ethtool_get_sset_count, diff --git a/target/linux/layerscape/patches-5.4/701-net-0182-staging-dpaa2-evb-Update-MTU-update-procedure.patch b/target/linux/layerscape/patches-5.4/701-net-0182-staging-dpaa2-evb-Update-MTU-update-procedure.patch deleted file mode 100644 index a3c87ead19..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0182-staging-dpaa2-evb-Update-MTU-update-procedure.patch +++ /dev/null @@ -1,57 +0,0 @@ -From e9c0434a55a0ddf28b1e7868890eb7557b2c28f9 Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Thu, 17 Aug 2017 19:47:22 +0300 -Subject: [PATCH] staging: dpaa2-evb: Update MTU update procedure - -Set limits on the MTU to accommodate netdevice update. There is no need to -check the limits before setting the new value. - -Signed-off-by: Razvan Stefanescu ---- - drivers/staging/fsl-dpaa2/evb/evb.c | 18 ++++++++---------- - 1 file changed, 8 insertions(+), 10 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/evb/evb.c -+++ b/drivers/staging/fsl-dpaa2/evb/evb.c -@@ -53,9 +53,9 @@ static const char evb_drv_version[] = "0 - #define DPDMUX_MAX_IRQ_NUM 2 - - /* MAX FRAME LENGTH (currently 10k) */ --#define EVB_MAX_FRAME_LENGTH (10 * 1024) --/* MIN FRAME LENGTH (64 bytes + 4 bytes CRC) */ --#define EVB_MIN_FRAME_LENGTH 68 -+#define EVB_MAX_FRAME_LENGTH (10 * 1024) -+#define EVB_MAX_MTU (EVB_MAX_FRAME_LENGTH - VLAN_ETH_HLEN) -+#define EVB_MIN_MTU 68 - - struct evb_port_priv { - struct net_device *netdev; -@@ -457,16 +457,10 @@ static int evb_change_mtu(struct net_dev - if (port_priv->port_index > 0) - return -EPERM; - -- if (mtu < EVB_MIN_FRAME_LENGTH || mtu > EVB_MAX_FRAME_LENGTH) { -- netdev_err(netdev, "Invalid MTU %d. Valid range is: %d..%d\n", -- mtu, EVB_MIN_FRAME_LENGTH, EVB_MAX_FRAME_LENGTH); -- return -EINVAL; -- } -- - err = dpdmux_set_max_frame_length(evb_priv->mc_io, - 0, - evb_priv->mux_handle, -- (uint16_t)mtu); -+ (uint16_t)(mtu + VLAN_ETH_HLEN)); - - if (unlikely(err)) { - netdev_err(netdev, "dpdmux_ul_set_max_frame_length err %d\n", -@@ -1291,6 +1285,10 @@ static int evb_probe(struct fsl_mc_devic - - list_add(&port_priv->list, &priv->port_list); - } else { -+ /* Set MTU limits only on uplink */ -+ port_netdev->min_mtu = EVB_MIN_MTU; -+ port_netdev->max_mtu = EVB_MAX_MTU; -+ - err = register_netdev(netdev); - - if (err < 0) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0183-staging-dpaa2-evb-Update-netlink-parsing-parameters.patch b/target/linux/layerscape/patches-5.4/701-net-0183-staging-dpaa2-evb-Update-netlink-parsing-parameters.patch deleted file mode 100644 index fd647cd1c8..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0183-staging-dpaa2-evb-Update-netlink-parsing-parameters.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 49c58cd6735d5f8f6683543ea66bb348aaa91321 Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Fri, 18 Aug 2017 12:34:24 +0300 -Subject: [PATCH] staging: dpaa2-evb: Update netlink parsing parameters - -Accommodate extended ACL reporting addded to netlink parsing functions. - -Signed-off-by: Razvan Stefanescu ---- - drivers/staging/fsl-dpaa2/evb/evb.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/evb/evb.c -+++ b/drivers/staging/fsl-dpaa2/evb/evb.c -@@ -533,7 +533,7 @@ static int evb_setlink(struct net_device - attr = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); - if (attr) { - err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, attr, -- ifla_br_policy); -+ ifla_br_policy, NULL); - if (unlikely(err)) { - netdev_err(netdev, - "nla_parse_nested for br_policy err %d\n", -@@ -739,7 +739,7 @@ static int evb_dellink(struct net_device - if (!spec) - return 0; - -- err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, spec, ifla_br_policy); -+ err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, spec, ifla_br_policy, NULL); - if (unlikely(err)) - return err; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0184-staging-dpaa2-evb-Update-netdev_master_upper_dev_lin.patch b/target/linux/layerscape/patches-5.4/701-net-0184-staging-dpaa2-evb-Update-netdev_master_upper_dev_lin.patch deleted file mode 100644 index bfc6759802..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0184-staging-dpaa2-evb-Update-netdev_master_upper_dev_lin.patch +++ /dev/null @@ -1,22 +0,0 @@ -From e8fcf855b73cd52ff51d3b99d0bf8afdf6267c2f Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Fri, 20 Oct 2017 16:14:38 +0300 -Subject: [PATCH] staging: dpaa2-evb: Update netdev_master_upper_dev_link - parameters - -Signed-off-by: Razvan Stefanescu ---- - drivers/staging/fsl-dpaa2/evb/evb.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/fsl-dpaa2/evb/evb.c -+++ b/drivers/staging/fsl-dpaa2/evb/evb.c -@@ -1270,7 +1270,7 @@ static int evb_probe(struct fsl_mc_devic - - rtnl_lock(); - err = netdev_master_upper_dev_link(port_netdev, netdev, -- NULL, NULL); -+ NULL, NULL, NULL); - if (unlikely(err)) { - dev_err(dev, "netdev_master_upper_dev_link err %d\n", - err); diff --git a/target/linux/layerscape/patches-5.4/701-net-0185-staging-dpaa2-evb-Use-MC-portal-in-atomic-context.patch b/target/linux/layerscape/patches-5.4/701-net-0185-staging-dpaa2-evb-Use-MC-portal-in-atomic-context.patch deleted file mode 100644 index dae6a0bf84..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0185-staging-dpaa2-evb-Use-MC-portal-in-atomic-context.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 918a96ed5ff4cbb499242279e3c76ab7bee43c88 Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Tue, 3 Apr 2018 13:53:00 +0300 -Subject: [PATCH] staging: dpaa2-evb: Use MC portal in atomic context - -Avoid triggering stack trace when retrieving interface counters via -ifconfig by allocating MC portal with atomic I/O enabled. - -Signed-off-by: Razvan Stefanescu ---- - drivers/staging/fsl-dpaa2/evb/evb.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/staging/fsl-dpaa2/evb/evb.c -+++ b/drivers/staging/fsl-dpaa2/evb/evb.c -@@ -1204,7 +1204,8 @@ static int evb_probe(struct fsl_mc_devic - - priv = netdev_priv(netdev); - -- err = fsl_mc_portal_allocate(evb_dev, 0, &priv->mc_io); -+ err = fsl_mc_portal_allocate(evb_dev, FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, -+ &priv->mc_io); - if (unlikely(err)) { - dev_err(dev, "fsl_mc_portal_allocate err %d\n", err); - goto err_free_netdev; diff --git a/target/linux/layerscape/patches-5.4/701-net-0186-staging-dpaa2-evb-change-mc_command-in-fsl_mc_comman.patch b/target/linux/layerscape/patches-5.4/701-net-0186-staging-dpaa2-evb-change-mc_command-in-fsl_mc_comman.patch deleted file mode 100644 index a6e080d5c2..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0186-staging-dpaa2-evb-change-mc_command-in-fsl_mc_comman.patch +++ /dev/null @@ -1,284 +0,0 @@ -From 92ee95e52191107f8c8adea810232920358ae0e0 Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Thu, 12 Apr 2018 15:19:10 +0300 -Subject: [PATCH] staging: dpaa2-evb: change mc_command in fsl_mc_command - -Adapt to the upstream changes. - -Signed-off-by: Razvan Stefanescu ---- - drivers/staging/fsl-dpaa2/evb/dpdmux.c | 60 +++++++++++++++++----------------- - 1 file changed, 30 insertions(+), 30 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/evb/dpdmux.c -+++ b/drivers/staging/fsl-dpaa2/evb/dpdmux.c -@@ -55,7 +55,7 @@ int dpdmux_open(struct fsl_mc_io *mc_io, - int dpdmux_id, - u16 *token) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_open *cmd_params; - int err; - -@@ -92,7 +92,7 @@ int dpdmux_close(struct fsl_mc_io *mc_io - u32 cmd_flags, - u16 token) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_CLOSE, -@@ -131,7 +131,7 @@ int dpdmux_create(struct fsl_mc_io *mc_i - const struct dpdmux_cfg *cfg, - u32 *obj_id) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_create *cmd_params; - int err; - -@@ -180,7 +180,7 @@ int dpdmux_destroy(struct fsl_mc_io *mc_ - u32 cmd_flags, - u32 object_id) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_destroy *cmd_params; - - /* prepare command */ -@@ -206,7 +206,7 @@ int dpdmux_enable(struct fsl_mc_io *mc_i - u32 cmd_flags, - u16 token) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_ENABLE, -@@ -229,7 +229,7 @@ int dpdmux_disable(struct fsl_mc_io *mc_ - u32 cmd_flags, - u16 token) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_DISABLE, -@@ -254,7 +254,7 @@ int dpdmux_is_enabled(struct fsl_mc_io * - u16 token, - int *en) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_rsp_is_enabled *rsp_params; - int err; - -@@ -287,7 +287,7 @@ int dpdmux_reset(struct fsl_mc_io *mc_io - u32 cmd_flags, - u16 token) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_RESET, -@@ -319,7 +319,7 @@ int dpdmux_set_irq_enable(struct fsl_mc_ - u8 irq_index, - u8 en) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_set_irq_enable *cmd_params; - - /* prepare command */ -@@ -350,7 +350,7 @@ int dpdmux_get_irq_enable(struct fsl_mc_ - u8 irq_index, - u8 *en) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_get_irq_enable *cmd_params; - struct dpdmux_rsp_get_irq_enable *rsp_params; - int err; -@@ -396,7 +396,7 @@ int dpdmux_set_irq_mask(struct fsl_mc_io - u8 irq_index, - u32 mask) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_set_irq_mask *cmd_params; - - /* prepare command */ -@@ -430,7 +430,7 @@ int dpdmux_get_irq_mask(struct fsl_mc_io - u8 irq_index, - u32 *mask) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_get_irq_mask *cmd_params; - struct dpdmux_rsp_get_irq_mask *rsp_params; - int err; -@@ -472,7 +472,7 @@ int dpdmux_get_irq_status(struct fsl_mc_ - u8 irq_index, - u32 *status) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_get_irq_status *cmd_params; - struct dpdmux_rsp_get_irq_status *rsp_params; - int err; -@@ -515,7 +515,7 @@ int dpdmux_clear_irq_status(struct fsl_m - u8 irq_index, - u32 status) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_clear_irq_status *cmd_params; - - /* prepare command */ -@@ -544,7 +544,7 @@ int dpdmux_get_attributes(struct fsl_mc_ - u16 token, - struct dpdmux_attr *attr) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_rsp_get_attr *rsp_params; - int err; - -@@ -585,7 +585,7 @@ int dpdmux_if_enable(struct fsl_mc_io *m - u16 if_id) - { - struct dpdmux_cmd_if *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_ENABLE, -@@ -613,7 +613,7 @@ int dpdmux_if_disable(struct fsl_mc_io * - u16 if_id) - { - struct dpdmux_cmd_if *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_IF_DISABLE, -@@ -645,7 +645,7 @@ int dpdmux_set_max_frame_length(struct f - u16 token, - u16 max_frame_length) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_set_max_frame_length *cmd_params; - - /* prepare command */ -@@ -671,7 +671,7 @@ int dpdmux_ul_reset_counters(struct fsl_ - u32 cmd_flags, - u16 token) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_UL_RESET_COUNTERS, -@@ -705,7 +705,7 @@ int dpdmux_if_set_accepted_frames(struct - u16 if_id, - const struct dpdmux_accepted_frames *cfg) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_if_set_accepted_frames *cmd_params; - - /* prepare command */ -@@ -739,7 +739,7 @@ int dpdmux_if_get_attributes(struct fsl_ - u16 if_id, - struct dpdmux_if_attr *attr) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_if *cmd_params; - struct dpdmux_rsp_if_get_attr *rsp_params; - int err; -@@ -786,7 +786,7 @@ int dpdmux_if_remove_l2_rule(struct fsl_ - u16 if_id, - const struct dpdmux_l2_rule *rule) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_if_l2_rule *cmd_params; - - /* prepare command */ -@@ -826,7 +826,7 @@ int dpdmux_if_add_l2_rule(struct fsl_mc_ - u16 if_id, - const struct dpdmux_l2_rule *rule) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_if_l2_rule *cmd_params; - - /* prepare command */ -@@ -865,7 +865,7 @@ int dpdmux_if_get_counter(struct fsl_mc_ - enum dpdmux_counter_type counter_type, - u64 *counter) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_if_get_counter *cmd_params; - struct dpdmux_rsp_if_get_counter *rsp_params; - int err; -@@ -906,7 +906,7 @@ int dpdmux_if_set_link_cfg(struct fsl_mc - u16 if_id, - struct dpdmux_link_cfg *cfg) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_if_set_link_cfg *cmd_params; - - /* prepare command */ -@@ -938,7 +938,7 @@ int dpdmux_if_get_link_state(struct fsl_ - u16 if_id, - struct dpdmux_link_state *state) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_cmd_if_get_link_state *cmd_params; - struct dpdmux_rsp_if_get_link_state *rsp_params; - int err; -@@ -989,7 +989,7 @@ int dpdmux_set_custom_key(struct fsl_mc_ - u64 key_cfg_iova) - { - struct dpdmux_set_custom_key *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_SET_CUSTOM_KEY, -@@ -1025,7 +1025,7 @@ int dpdmux_add_custom_cls_entry(struct f - struct dpdmux_cls_action *action) - { - struct dpdmux_cmd_add_custom_cls_entry *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_ADD_CUSTOM_CLS_ENTRY, -@@ -1062,7 +1062,7 @@ int dpdmux_remove_custom_cls_entry(struc - struct dpdmux_rule_cfg *rule) - { - struct dpdmux_cmd_remove_custom_cls_entry *cmd_params; -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPDMUX_CMDID_REMOVE_CUSTOM_CLS_ENTRY, -@@ -1091,7 +1091,7 @@ int dpdmux_get_api_version(struct fsl_mc - u16 *major_ver, - u16 *minor_ver) - { -- struct mc_command cmd = { 0 }; -+ struct fsl_mc_command cmd = { 0 }; - struct dpdmux_rsp_get_api_version *rsp_params; - int err; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0187-staging-dpaa2-evb-Fix-MC-bus-include.patch b/target/linux/layerscape/patches-5.4/701-net-0187-staging-dpaa2-evb-Fix-MC-bus-include.patch deleted file mode 100644 index f5cb38e14b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0187-staging-dpaa2-evb-Fix-MC-bus-include.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 64be51568219eb436b46d7f6d0c85fd81bce4fde Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Thu, 12 Apr 2018 15:55:30 +0300 -Subject: [PATCH] staging: dpaa2-evb: Fix MC bus include - -Adapt to upstream changes. - -Signed-off-by: Razvan Stefanescu ---- - drivers/staging/fsl-dpaa2/evb/dpdmux.c | 2 +- - drivers/staging/fsl-dpaa2/evb/evb.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/evb/dpdmux.c -+++ b/drivers/staging/fsl-dpaa2/evb/dpdmux.c -@@ -29,7 +29,7 @@ - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ --#include "../../fsl-mc/include/mc.h" -+#include - #include "dpdmux.h" - #include "dpdmux-cmd.h" - ---- a/drivers/staging/fsl-dpaa2/evb/evb.c -+++ b/drivers/staging/fsl-dpaa2/evb/evb.c -@@ -38,7 +38,7 @@ - #include - #include - --#include "../../fsl-mc/include/mc.h" -+#include - - #include "dpdmux.h" - #include "dpdmux-cmd.h" diff --git a/target/linux/layerscape/patches-5.4/701-net-0188-staging-dpaa2-evb-Defer-probe-if-no-mc-portal-is-fou.patch b/target/linux/layerscape/patches-5.4/701-net-0188-staging-dpaa2-evb-Defer-probe-if-no-mc-portal-is-fou.patch deleted file mode 100644 index d95ecf8a90..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0188-staging-dpaa2-evb-Defer-probe-if-no-mc-portal-is-fou.patch +++ /dev/null @@ -1,29 +0,0 @@ -From ac03137b2283c45ad0538188728d9691fa7a4883 Mon Sep 17 00:00:00 2001 -From: Razvan Stefanescu -Date: Mon, 30 Apr 2018 11:27:27 +0300 -Subject: [PATCH] staging: dpaa2-evb: Defer probe if no mc portal is found - -Signed-off-by: Razvan Stefanescu ---- - drivers/staging/fsl-dpaa2/evb/evb.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/evb/evb.c -+++ b/drivers/staging/fsl-dpaa2/evb/evb.c -@@ -1206,10 +1206,14 @@ static int evb_probe(struct fsl_mc_devic - - err = fsl_mc_portal_allocate(evb_dev, FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, - &priv->mc_io); -- if (unlikely(err)) { -- dev_err(dev, "fsl_mc_portal_allocate err %d\n", err); -+ if (err) { -+ if (err == -ENXIO) -+ err = -EPROBE_DEFER; -+ else -+ dev_err(dev, "fsl_mc_portal_allocate err %d\n", err); - goto err_free_netdev; - } -+ - if (!priv->mc_io) { - dev_err(dev, "fsl_mc_portal_allocate returned null handle but no error\n"); - err = -EFAULT; diff --git a/target/linux/layerscape/patches-5.4/701-net-0189-staging-dpaa2-evb-Update-netlink-attributes-API.patch b/target/linux/layerscape/patches-5.4/701-net-0189-staging-dpaa2-evb-Update-netlink-attributes-API.patch deleted file mode 100644 index 5db172e4ae..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0189-staging-dpaa2-evb-Update-netlink-attributes-API.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 50a9c893a750c4eef7fbf60f5b6eb4833e35a943 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 24 Jul 2019 21:43:49 +0300 -Subject: [PATCH] staging: dpaa2-evb: Update netlink attributes API - -Account for upstream changes in some nla functions. - -Signed-off-by: Ioana Radulescu ---- - drivers/staging/fsl-dpaa2/evb/evb.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/evb/evb.c -+++ b/drivers/staging/fsl-dpaa2/evb/evb.c -@@ -532,8 +532,8 @@ static int evb_setlink(struct net_device - - attr = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); - if (attr) { -- err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, attr, -- ifla_br_policy, NULL); -+ err = nla_parse_nested_deprecated(tb, IFLA_BRIDGE_MAX, attr, -+ ifla_br_policy, NULL); - if (unlikely(err)) { - netdev_err(netdev, - "nla_parse_nested for br_policy err %d\n", -@@ -596,7 +596,7 @@ static int __nla_put_port(struct sk_buff - struct nlattr *nest; - int err; - -- nest = nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED); -+ nest = nla_nest_start_noflag(skb, IFLA_PROTINFO | NLA_F_NESTED); - if (!nest) { - netdev_err(netdev, "nla_nest_start failed\n"); - return -ENOMEM; -@@ -648,7 +648,7 @@ static int __nla_put_vlan(struct sk_buff - u16 i; - int err; - -- nest = nla_nest_start(skb, IFLA_AF_SPEC); -+ nest = nla_nest_start_noflag(skb, IFLA_AF_SPEC); - if (!nest) { - netdev_err(netdev, "nla_nest_start failed"); - return -ENOMEM; -@@ -739,7 +739,8 @@ static int evb_dellink(struct net_device - if (!spec) - return 0; - -- err = nla_parse_nested(tb, IFLA_BRIDGE_MAX, spec, ifla_br_policy, NULL); -+ err = nla_parse_nested_deprecated(tb, IFLA_BRIDGE_MAX, spec, -+ ifla_br_policy, NULL); - if (unlikely(err)) - return err; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0190-dpaa2-eth-Cleanup-dead-code.patch b/target/linux/layerscape/patches-5.4/701-net-0190-dpaa2-eth-Cleanup-dead-code.patch deleted file mode 100644 index 18dc4e1353..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0190-dpaa2-eth-Cleanup-dead-code.patch +++ /dev/null @@ -1,35 +0,0 @@ -From f56f2b85c6a670c74f28daad249920d4ee4161a9 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Tue, 3 Sep 2019 21:20:07 +0300 -Subject: [PATCH] dpaa2-eth: Cleanup dead code - -Remove one function call whose result was not used anywhere. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -2046,7 +2046,6 @@ static struct fsl_mc_device *setup_dpcon - { - struct fsl_mc_device *dpcon; - struct device *dev = priv->net_dev->dev.parent; -- struct dpcon_attr attrs; - int err; - - err = fsl_mc_object_allocate(to_fsl_mc_device(dev), -@@ -2071,12 +2070,6 @@ static struct fsl_mc_device *setup_dpcon - goto close; - } - -- err = dpcon_get_attributes(priv->mc_io, 0, dpcon->mc_handle, &attrs); -- if (err) { -- dev_err(dev, "dpcon_get_attributes() failed\n"); -- goto close; -- } -- - err = dpcon_enable(priv->mc_io, 0, dpcon->mc_handle); - if (err) { - dev_err(dev, "dpcon_enable() failed\n"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0191-dpaa2-eth-Avoid-unbounded-while-loops.patch b/target/linux/layerscape/patches-5.4/701-net-0191-dpaa2-eth-Avoid-unbounded-while-loops.patch deleted file mode 100644 index 72b41a45bb..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0191-dpaa2-eth-Avoid-unbounded-while-loops.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 3420c5bf9d08df074b67c7feda8a37d951d0b232 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 18 Sep 2019 13:31:07 +0300 -Subject: [PATCH] dpaa2-eth: Avoid unbounded while loops - -Throughout the driver there are several places where we wait -indefinitely for DPIO portal commands to be executed, while -the portal returns a busy response code. - -Even though in theory we are guaranteed the portals become -available eventually, in practice the QBMan hardware module -may become unresponsive in various corner cases. - -Make sure we can never get stuck in an infinite while loop -by adding a retry counter for all portal commands. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 30 ++++++++++++++++++++---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 8 +++++++ - 2 files changed, 33 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -221,6 +221,7 @@ static void xdp_release_buf(struct dpaa2 - struct dpaa2_eth_channel *ch, - dma_addr_t addr) - { -+ int retries = 0; - int err; - - ch->xdp.drop_bufs[ch->xdp.drop_cnt++] = addr; -@@ -229,8 +230,11 @@ static void xdp_release_buf(struct dpaa2 - - while ((err = dpaa2_io_service_release(ch->dpio, priv->bpid, - ch->xdp.drop_bufs, -- ch->xdp.drop_cnt)) == -EBUSY) -+ ch->xdp.drop_cnt)) == -EBUSY) { -+ if (retries++ >= DPAA2_ETH_SWP_BUSY_RETRIES) -+ break; - cpu_relax(); -+ } - - if (err) { - free_bufs(priv, ch->xdp.drop_bufs, ch->xdp.drop_cnt); -@@ -458,7 +462,7 @@ static int consume_frames(struct dpaa2_e - struct dpaa2_eth_fq *fq = NULL; - struct dpaa2_dq *dq; - const struct dpaa2_fd *fd; -- int cleaned = 0; -+ int cleaned = 0, retries = 0; - int is_last; - - do { -@@ -469,6 +473,11 @@ static int consume_frames(struct dpaa2_e - * the store until we get some sort of valid response - * token (either a valid frame or an "empty dequeue") - */ -+ if (retries++ >= DPAA2_ETH_SWP_BUSY_RETRIES) { -+ netdev_err_once(priv->net_dev, -+ "Unable to read a valid dequeue response\n"); -+ return 0; -+ } - continue; - } - -@@ -477,6 +486,7 @@ static int consume_frames(struct dpaa2_e - - fq->consume(priv, ch, fd, fq); - cleaned++; -+ retries = 0; - } while (!is_last); - - if (!cleaned) -@@ -949,6 +959,7 @@ static int add_bufs(struct dpaa2_eth_pri - u64 buf_array[DPAA2_ETH_BUFS_PER_CMD]; - struct page *page; - dma_addr_t addr; -+ int retries = 0; - int i, err; - - for (i = 0; i < DPAA2_ETH_BUFS_PER_CMD; i++) { -@@ -980,8 +991,11 @@ static int add_bufs(struct dpaa2_eth_pri - release_bufs: - /* In case the portal is busy, retry until successful */ - while ((err = dpaa2_io_service_release(ch->dpio, bpid, -- buf_array, i)) == -EBUSY) -+ buf_array, i)) == -EBUSY) { -+ if (retries++ >= DPAA2_ETH_SWP_BUSY_RETRIES) -+ break; - cpu_relax(); -+ } - - /* If release command failed, clean up and bail out; - * not much else we can do about it -@@ -1032,16 +1046,21 @@ static int seed_pool(struct dpaa2_eth_pr - static void drain_bufs(struct dpaa2_eth_priv *priv, int count) - { - u64 buf_array[DPAA2_ETH_BUFS_PER_CMD]; -+ int retries = 0; - int ret; - - do { - ret = dpaa2_io_service_acquire(NULL, priv->bpid, - buf_array, count); - if (ret < 0) { -+ if (ret == -EBUSY && -+ retries++ >= DPAA2_ETH_SWP_BUSY_RETRIES) -+ continue; - netdev_err(priv->net_dev, "dpaa2_io_service_acquire() failed\n"); - return; - } - free_bufs(priv, buf_array, ret); -+ retries = 0; - } while (ret); - } - -@@ -1094,7 +1113,7 @@ static int pull_channel(struct dpaa2_eth - ch->store); - dequeues++; - cpu_relax(); -- } while (err == -EBUSY); -+ } while (err == -EBUSY && dequeues < DPAA2_ETH_SWP_BUSY_RETRIES); - - ch->stats.dequeue_portal_busy += dequeues; - if (unlikely(err)) -@@ -1118,6 +1137,7 @@ static int dpaa2_eth_poll(struct napi_st - struct netdev_queue *nq; - int store_cleaned, work_done; - struct list_head rx_list; -+ int retries = 0; - int err; - - ch = container_of(napi, struct dpaa2_eth_channel, napi); -@@ -1163,7 +1183,7 @@ static int dpaa2_eth_poll(struct napi_st - do { - err = dpaa2_io_service_rearm(ch->dpio, &ch->nctx); - cpu_relax(); -- } while (err == -EBUSY); -+ } while (err == -EBUSY && retries++ < DPAA2_ETH_SWP_BUSY_RETRIES); - WARN_ONCE(err, "CDAN notifications rearm failed on core %d", - ch->nctx.desired_cpu); - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -245,6 +245,14 @@ static inline struct dpaa2_faead *dpaa2_ - */ - #define DPAA2_ETH_ENQUEUE_RETRIES 10 - -+/* Number of times to retry DPIO portal operations while waiting -+ * for portal to finish executing current command and become -+ * available. We want to avoid being stuck in a while loop in case -+ * hardware becomes unresponsive, but not give up too easily if -+ * the portal really is busy for valid reasons -+ */ -+#define DPAA2_ETH_SWP_BUSY_RETRIES 1000 -+ - /* Driver statistics, other than those in struct rtnl_link_stats64. - * These are usually collected per-CPU and aggregated by ethtool. - */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0192-dpaa2-eth-Add-support-for-Rx-traffic-classes.patch b/target/linux/layerscape/patches-5.4/701-net-0192-dpaa2-eth-Add-support-for-Rx-traffic-classes.patch deleted file mode 100644 index 0ec6133fca..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0192-dpaa2-eth-Add-support-for-Rx-traffic-classes.patch +++ /dev/null @@ -1,263 +0,0 @@ -From 936ce2452068cb0f6d48ca7d77d6b975802c19ae Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Tue, 3 Sep 2019 14:13:32 +0300 -Subject: [PATCH] dpaa2-eth: Add support for Rx traffic classes - -The firmware reserves for each DPNI a number of RX frame queues -equal to the number of configured flows x number of configured -traffic classes. - -Current driver configuration directs all incoming traffic to -FQs corresponding to TC0, leaving all other priority levels unused. - -Start adding support for multiple ingress traffic classes, by -configuring the FQs associated with all priority levels, not just -TC0. All settings that are per-TC, such as those related to -hashing and flow steering, are also updated. - -Signed-off-by: Ioana Radulescu ---- - .../ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c | 7 ++- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 70 +++++++++++++++------- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 4 +- - .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 19 ++++-- - 4 files changed, 68 insertions(+), 32 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c -@@ -81,8 +81,8 @@ static int dpaa2_dbg_fqs_show(struct seq - int i, err; - - seq_printf(file, "FQ stats for %s:\n", priv->net_dev->name); -- seq_printf(file, "%s%16s%16s%16s%16s\n", -- "VFQID", "CPU", "Type", "Frames", "Pending frames"); -+ seq_printf(file, "%s%16s%16s%16s%16s%16s\n", -+ "VFQID", "CPU", "TC", "Type", "Frames", "Pending frames"); - - for (i = 0; i < priv->num_fqs; i++) { - fq = &priv->fq[i]; -@@ -90,9 +90,10 @@ static int dpaa2_dbg_fqs_show(struct seq - if (err) - fcnt = 0; - -- seq_printf(file, "%5d%16d%16s%16llu%16u\n", -+ seq_printf(file, "%5d%16d%16d%16s%16llu%16u\n", - fq->fqid, - fq->target_cpu, -+ fq->tc, - fq_type_to_str(fq), - fq->stats.frames, - fcnt); ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -1231,6 +1231,7 @@ static void disable_ch_napi(struct dpaa2 - static void dpaa2_eth_set_rx_taildrop(struct dpaa2_eth_priv *priv, bool enable) - { - struct dpni_taildrop td = {0}; -+ struct dpaa2_eth_fq *fq; - int i, err; - - if (priv->rx_td_enabled == enable) -@@ -1240,11 +1241,12 @@ static void dpaa2_eth_set_rx_taildrop(st - td.threshold = DPAA2_ETH_TAILDROP_THRESH; - - for (i = 0; i < priv->num_fqs; i++) { -- if (priv->fq[i].type != DPAA2_RX_FQ) -+ fq = &priv->fq[i]; -+ if (fq->type != DPAA2_RX_FQ) - continue; - err = dpni_set_taildrop(priv->mc_io, 0, priv->mc_token, -- DPNI_CP_QUEUE, DPNI_QUEUE_RX, 0, -- priv->fq[i].flowid, &td); -+ DPNI_CP_QUEUE, DPNI_QUEUE_RX, -+ fq->tc, fq->flowid, &td); - if (err) { - netdev_err(priv->net_dev, - "dpni_set_taildrop() failed\n"); -@@ -2338,7 +2340,7 @@ static void set_fq_affinity(struct dpaa2 - - static void setup_fqs(struct dpaa2_eth_priv *priv) - { -- int i; -+ int i, j; - - /* We have one TxConf FQ per Tx flow. - * The number of Tx and Rx queues is the same. -@@ -2350,10 +2352,13 @@ static void setup_fqs(struct dpaa2_eth_p - priv->fq[priv->num_fqs++].flowid = (u16)i; - } - -- for (i = 0; i < dpaa2_eth_queue_count(priv); i++) { -- priv->fq[priv->num_fqs].type = DPAA2_RX_FQ; -- priv->fq[priv->num_fqs].consume = dpaa2_eth_rx; -- priv->fq[priv->num_fqs++].flowid = (u16)i; -+ for (j = 0; j < dpaa2_eth_tc_count(priv); j++) { -+ for (i = 0; i < dpaa2_eth_queue_count(priv); i++) { -+ priv->fq[priv->num_fqs].type = DPAA2_RX_FQ; -+ priv->fq[priv->num_fqs].consume = dpaa2_eth_rx; -+ priv->fq[priv->num_fqs].tc = (u8)j; -+ priv->fq[priv->num_fqs++].flowid = (u16)i; -+ } - } - - /* For each FQ, decide on which core to process incoming frames */ -@@ -2701,7 +2706,7 @@ static int setup_rx_flow(struct dpaa2_et - int err; - - err = dpni_get_queue(priv->mc_io, 0, priv->mc_token, -- DPNI_QUEUE_RX, 0, fq->flowid, &queue, &qid); -+ DPNI_QUEUE_RX, fq->tc, fq->flowid, &queue, &qid); - if (err) { - dev_err(dev, "dpni_get_queue(RX) failed\n"); - return err; -@@ -2714,7 +2719,7 @@ static int setup_rx_flow(struct dpaa2_et - queue.destination.priority = 1; - queue.user_context = (u64)(uintptr_t)fq; - err = dpni_set_queue(priv->mc_io, 0, priv->mc_token, -- DPNI_QUEUE_RX, 0, fq->flowid, -+ DPNI_QUEUE_RX, fq->tc, fq->flowid, - DPNI_QUEUE_OPT_USER_CTX | DPNI_QUEUE_OPT_DEST, - &queue); - if (err) { -@@ -2723,6 +2728,10 @@ static int setup_rx_flow(struct dpaa2_et - } - - /* xdp_rxq setup */ -+ /* only once for each channel */ -+ if (fq->tc > 0) -+ return 0; -+ - err = xdp_rxq_info_reg(&fq->channel->xdp_rxq, priv->net_dev, - fq->flowid); - if (err) { -@@ -2860,7 +2869,7 @@ static int config_legacy_hash_key(struct - { - struct device *dev = priv->net_dev->dev.parent; - struct dpni_rx_tc_dist_cfg dist_cfg; -- int err; -+ int i, err = 0; - - memset(&dist_cfg, 0, sizeof(dist_cfg)); - -@@ -2868,9 +2877,14 @@ static int config_legacy_hash_key(struct - dist_cfg.dist_size = dpaa2_eth_queue_count(priv); - dist_cfg.dist_mode = DPNI_DIST_MODE_HASH; - -- err = dpni_set_rx_tc_dist(priv->mc_io, 0, priv->mc_token, 0, &dist_cfg); -- if (err) -- dev_err(dev, "dpni_set_rx_tc_dist failed\n"); -+ for (i = 0; i < dpaa2_eth_tc_count(priv); i++) { -+ err = dpni_set_rx_tc_dist(priv->mc_io, 0, priv->mc_token, -+ i, &dist_cfg); -+ if (err) { -+ dev_err(dev, "dpni_set_rx_tc_dist failed\n"); -+ break; -+ } -+ } - - return err; - } -@@ -2880,7 +2894,7 @@ static int config_hash_key(struct dpaa2_ - { - struct device *dev = priv->net_dev->dev.parent; - struct dpni_rx_dist_cfg dist_cfg; -- int err; -+ int i, err = 0; - - memset(&dist_cfg, 0, sizeof(dist_cfg)); - -@@ -2888,9 +2902,15 @@ static int config_hash_key(struct dpaa2_ - dist_cfg.dist_size = dpaa2_eth_queue_count(priv); - dist_cfg.enable = 1; - -- err = dpni_set_rx_hash_dist(priv->mc_io, 0, priv->mc_token, &dist_cfg); -- if (err) -- dev_err(dev, "dpni_set_rx_hash_dist failed\n"); -+ for (i = 0; i < dpaa2_eth_tc_count(priv); i++) { -+ dist_cfg.tc = i; -+ err = dpni_set_rx_hash_dist(priv->mc_io, 0, priv->mc_token, -+ &dist_cfg); -+ if (err) { -+ dev_err(dev, "dpni_set_rx_hash_dist failed\n"); -+ break; -+ } -+ } - - return err; - } -@@ -2900,7 +2920,7 @@ static int config_cls_key(struct dpaa2_e - { - struct device *dev = priv->net_dev->dev.parent; - struct dpni_rx_dist_cfg dist_cfg; -- int err; -+ int i, err = 0; - - memset(&dist_cfg, 0, sizeof(dist_cfg)); - -@@ -2908,9 +2928,15 @@ static int config_cls_key(struct dpaa2_e - dist_cfg.dist_size = dpaa2_eth_queue_count(priv); - dist_cfg.enable = 1; - -- err = dpni_set_rx_fs_dist(priv->mc_io, 0, priv->mc_token, &dist_cfg); -- if (err) -- dev_err(dev, "dpni_set_rx_fs_dist failed\n"); -+ for (i = 0; i < dpaa2_eth_tc_count(priv); i++) { -+ dist_cfg.tc = i; -+ err = dpni_set_rx_fs_dist(priv->mc_io, 0, priv->mc_token, -+ &dist_cfg); -+ if (err) { -+ dev_err(dev, "dpni_set_rx_fs_dist failed\n"); -+ break; -+ } -+ } - - return err; - } ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -291,7 +291,9 @@ struct dpaa2_eth_ch_stats { - - /* Maximum number of queues associated with a DPNI */ - #define DPAA2_ETH_MAX_TCS 8 --#define DPAA2_ETH_MAX_RX_QUEUES 16 -+#define DPAA2_ETH_MAX_RX_QUEUES_PER_TC 16 -+#define DPAA2_ETH_MAX_RX_QUEUES \ -+ (DPAA2_ETH_MAX_RX_QUEUES_PER_TC * DPAA2_ETH_MAX_TCS) - #define DPAA2_ETH_MAX_TX_QUEUES 16 - #define DPAA2_ETH_MAX_QUEUES (DPAA2_ETH_MAX_RX_QUEUES + \ - DPAA2_ETH_MAX_TX_QUEUES) ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -@@ -502,7 +502,7 @@ static int do_cls_rule(struct net_device - dma_addr_t key_iova; - u64 fields = 0; - void *key_buf; -- int err; -+ int i, err; - - if (fs->ring_cookie != RX_CLS_FLOW_DISC && - fs->ring_cookie >= dpaa2_eth_queue_count(priv)) -@@ -562,11 +562,18 @@ static int do_cls_rule(struct net_device - fs_act.options |= DPNI_FS_OPT_DISCARD; - else - fs_act.flow_id = fs->ring_cookie; -- err = dpni_add_fs_entry(priv->mc_io, 0, priv->mc_token, 0, -- fs->location, &rule_cfg, &fs_act); -- } else { -- err = dpni_remove_fs_entry(priv->mc_io, 0, priv->mc_token, 0, -- &rule_cfg); -+ } -+ for (i = 0; i < dpaa2_eth_tc_count(priv); i++) { -+ if (add) -+ err = dpni_add_fs_entry(priv->mc_io, 0, priv->mc_token, -+ i, fs->location, &rule_cfg, -+ &fs_act); -+ else -+ err = dpni_remove_fs_entry(priv->mc_io, 0, -+ priv->mc_token, i, -+ &rule_cfg); -+ if (err) -+ break; - } - - dma_unmap_single(dev, key_iova, rule_cfg.key_size * 2, DMA_TO_DEVICE); diff --git a/target/linux/layerscape/patches-5.4/701-net-0193-dpaa2-eth-Trim-debugfs-FQ-stats.patch b/target/linux/layerscape/patches-5.4/701-net-0193-dpaa2-eth-Trim-debugfs-FQ-stats.patch deleted file mode 100644 index 1327b37e64..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0193-dpaa2-eth-Trim-debugfs-FQ-stats.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 2b19aa3f602c9d9d71959c6306c385927fb9578c Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Tue, 17 Sep 2019 16:53:03 +0300 -Subject: [PATCH] dpaa2-eth: Trim debugfs FQ stats - -With the addition of multiple traffic classes support, the number -of available frame queues grew significantly, overly inflating the -debugfs FQ statistics entry. Update it to only show the queues -which are actually in use (i.e. have a non-zero frame counter). - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c -@@ -90,6 +90,10 @@ static int dpaa2_dbg_fqs_show(struct seq - if (err) - fcnt = 0; - -+ /* Skip FQs with no traffic */ -+ if (!fq->stats.frames && !fcnt) -+ continue; -+ - seq_printf(file, "%5d%16d%16d%16s%16llu%16u\n", - fq->fqid, - fq->target_cpu, diff --git a/target/linux/layerscape/patches-5.4/701-net-0194-dpaa2-eth-Distribute-ingress-frames-based-on-VLAN-pr.patch b/target/linux/layerscape/patches-5.4/701-net-0194-dpaa2-eth-Distribute-ingress-frames-based-on-VLAN-pr.patch deleted file mode 100644 index 80e6afed34..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0194-dpaa2-eth-Distribute-ingress-frames-based-on-VLAN-pr.patch +++ /dev/null @@ -1,397 +0,0 @@ -From ea2e3b62b170e0f896aa837c8fec8085fb1063f8 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Tue, 3 Sep 2019 21:11:35 +0300 -Subject: [PATCH] dpaa2-eth: Distribute ingress frames based on VLAN prio - -Configure static ingress classification based on VLAN PCP field. -If the DPNI doesn't have enough traffic classes to accommodate all -priority levels, the lowest ones end up on TC 0 (default on miss). - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 116 ++++++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 1 + - drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 34 ++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.c | 131 +++++++++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.h | 36 +++++++ - 5 files changed, 318 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -2608,6 +2608,118 @@ out_err: - priv->enqueue = dpaa2_eth_enqueue_qd; - } - -+/* Configure ingress classification based on VLAN PCP */ -+static int set_vlan_qos(struct dpaa2_eth_priv *priv) -+{ -+ struct device *dev = priv->net_dev->dev.parent; -+ struct dpkg_profile_cfg kg_cfg = {0}; -+ struct dpni_qos_tbl_cfg qos_cfg = {0}; -+ struct dpni_rule_cfg key_params; -+ void *dma_mem, *key, *mask; -+ u8 key_size = 2; /* VLAN TCI field */ -+ int i, pcp, err; -+ -+ /* VLAN-based classification only makes sense if we have multiple -+ * traffic classes. -+ * Also, we need to extract just the 3-bit PCP field from the VLAN -+ * header and we can only do that by using a mask -+ */ -+ if (dpaa2_eth_tc_count(priv) == 1 || !dpaa2_eth_fs_mask_enabled(priv)) { -+ dev_dbg(dev, "VLAN-based QoS classification not supported\n"); -+ return -ENOTSUPP; -+ } -+ -+ dma_mem = kzalloc(DPAA2_CLASSIFIER_DMA_SIZE, GFP_KERNEL); -+ if (!dma_mem) -+ return -ENOMEM; -+ -+ kg_cfg.num_extracts = 1; -+ kg_cfg.extracts[0].type = DPKG_EXTRACT_FROM_HDR; -+ kg_cfg.extracts[0].extract.from_hdr.prot = NET_PROT_VLAN; -+ kg_cfg.extracts[0].extract.from_hdr.type = DPKG_FULL_FIELD; -+ kg_cfg.extracts[0].extract.from_hdr.field = NH_FLD_VLAN_TCI; -+ -+ err = dpni_prepare_key_cfg(&kg_cfg, dma_mem); -+ if (err) { -+ dev_err(dev, "dpni_prepare_key_cfg failed\n"); -+ goto out_free_tbl; -+ } -+ -+ /* set QoS table */ -+ qos_cfg.default_tc = 0; -+ qos_cfg.discard_on_miss = 0; -+ qos_cfg.key_cfg_iova = dma_map_single(dev, dma_mem, -+ DPAA2_CLASSIFIER_DMA_SIZE, -+ DMA_TO_DEVICE); -+ if (dma_mapping_error(dev, qos_cfg.key_cfg_iova)) { -+ dev_err(dev, "QoS table DMA mapping failed\n"); -+ err = -ENOMEM; -+ goto out_free_tbl; -+ } -+ -+ err = dpni_set_qos_table(priv->mc_io, 0, priv->mc_token, &qos_cfg); -+ if (err) { -+ dev_err(dev, "dpni_set_qos_table failed\n"); -+ goto out_unmap_tbl; -+ } -+ -+ /* Add QoS table entries */ -+ key = kzalloc(key_size * 2, GFP_KERNEL); -+ if (!key) { -+ err = -ENOMEM; -+ goto out_unmap_tbl; -+ } -+ mask = key + key_size; -+ *(u16 *)mask = cpu_to_be16(VLAN_PRIO_MASK); -+ -+ key_params.key_iova = dma_map_single(dev, key, key_size * 2, -+ DMA_TO_DEVICE); -+ if (dma_mapping_error(dev, key_params.key_iova)) { -+ dev_err(dev, "Qos table entry DMA mapping failed\n"); -+ err = -ENOMEM; -+ goto out_free_key; -+ } -+ -+ key_params.mask_iova = key_params.key_iova + key_size; -+ key_params.key_size = key_size; -+ -+ /* We add rules for PCP-based distribution starting with highest -+ * priority (VLAN PCP = 7). If this DPNI doesn't have enough traffic -+ * classes to accommodate all priority levels, the lowest ones end up -+ * on TC 0 which was configured as default -+ */ -+ for (i = dpaa2_eth_tc_count(priv) - 1, pcp = 7; i >= 0; i--, pcp--) { -+ *(u16 *)key = cpu_to_be16(pcp << VLAN_PRIO_SHIFT); -+ dma_sync_single_for_device(dev, key_params.key_iova, -+ key_size * 2, DMA_TO_DEVICE); -+ -+ err = dpni_add_qos_entry(priv->mc_io, 0, priv->mc_token, -+ &key_params, i, i); -+ if (err) { -+ dev_err(dev, "dpni_add_qos_entry failed\n"); -+ dpni_clear_qos_table(priv->mc_io, 0, priv->mc_token); -+ goto out_unmap_key; -+ } -+ } -+ -+ priv->vlan_cls_enabled = true; -+ -+ /* Table and key memory is not persistent, clean everything up after -+ * configuration is finished -+ */ -+out_unmap_key: -+ dma_unmap_single(dev, key_params.key_iova, key_size * 2, DMA_TO_DEVICE); -+out_free_key: -+ kfree(key); -+out_unmap_tbl: -+ dma_unmap_single(dev, qos_cfg.key_cfg_iova, DPAA2_CLASSIFIER_DMA_SIZE, -+ DMA_TO_DEVICE); -+out_free_tbl: -+ kfree(dma_mem); -+ -+ return err; -+} -+ - /* Configure the DPNI object this interface is associated with */ - static int setup_dpni(struct fsl_mc_device *ls_dev) - { -@@ -2670,6 +2782,10 @@ static int setup_dpni(struct fsl_mc_devi - goto close; - } - -+ err = set_vlan_qos(priv); -+ if (err && err != -ENOTSUPP) -+ goto close; -+ - priv->cls_rules = devm_kzalloc(dev, sizeof(struct dpaa2_eth_cls_rule) * - dpaa2_eth_fs_count(priv), GFP_KERNEL); - if (!priv->cls_rules) { ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -414,6 +414,7 @@ struct dpaa2_eth_priv { - u64 rx_cls_fields; - struct dpaa2_eth_cls_rule *cls_rules; - u8 rx_cls_enabled; -+ u8 vlan_cls_enabled; - struct bpf_prog *xdp_prog; - #ifdef CONFIG_DEBUG_FS - struct dpaa2_debugfs dbg; ---- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -@@ -59,6 +59,10 @@ - - #define DPNI_CMDID_SET_RX_TC_DIST DPNI_CMD(0x235) - -+#define DPNI_CMDID_SET_QOS_TBL DPNI_CMD(0x240) -+#define DPNI_CMDID_ADD_QOS_ENT DPNI_CMD(0x241) -+#define DPNI_CMDID_REMOVE_QOS_ENT DPNI_CMD(0x242) -+#define DPNI_CMDID_CLR_QOS_TBL DPNI_CMD(0x243) - #define DPNI_CMDID_ADD_FS_ENT DPNI_CMD(0x244) - #define DPNI_CMDID_REMOVE_FS_ENT DPNI_CMD(0x245) - #define DPNI_CMDID_CLR_FS_ENT DPNI_CMD(0x246) -@@ -567,4 +571,34 @@ struct dpni_cmd_remove_fs_entry { - __le64 mask_iova; - }; - -+#define DPNI_DISCARD_ON_MISS_SHIFT 0 -+#define DPNI_DISCARD_ON_MISS_SIZE 1 -+ -+struct dpni_cmd_set_qos_table { -+ __le32 pad; -+ u8 default_tc; -+ /* only the LSB */ -+ u8 discard_on_miss; -+ __le16 pad1[21]; -+ __le64 key_cfg_iova; -+}; -+ -+struct dpni_cmd_add_qos_entry { -+ __le16 pad; -+ u8 tc_id; -+ u8 key_size; -+ __le16 index; -+ __le16 pad1; -+ __le64 key_iova; -+ __le64 mask_iova; -+}; -+ -+struct dpni_cmd_remove_qos_entry { -+ u8 pad[3]; -+ u8 key_size; -+ __le32 pad1; -+ __le64 key_iova; -+ __le64 mask_iova; -+}; -+ - #endif /* _FSL_DPNI_CMD_H */ ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c -@@ -1786,3 +1786,134 @@ int dpni_remove_fs_entry(struct fsl_mc_i - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); - } -+ -+/** -+ * dpni_set_qos_table() - Set QoS mapping table -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPNI object -+ * @cfg: QoS table configuration -+ * -+ * This function and all QoS-related functions require that -+ *'max_tcs > 1' was set at DPNI creation. -+ * -+ * warning: Before calling this function, call dpkg_prepare_key_cfg() to -+ * prepare the key_cfg_iova parameter -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpni_set_qos_table(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_qos_tbl_cfg *cfg) -+{ -+ struct dpni_cmd_set_qos_table *cmd_params; -+ struct fsl_mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QOS_TBL, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpni_cmd_set_qos_table *)cmd.params; -+ cmd_params->default_tc = cfg->default_tc; -+ cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova); -+ dpni_set_field(cmd_params->discard_on_miss, DISCARD_ON_MISS, -+ cfg->discard_on_miss); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpni_add_qos_entry() - Add QoS mapping entry (to select a traffic class) -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPNI object -+ * @cfg: QoS rule to add -+ * @tc_id: Traffic class selection (0-7) -+ * @index: Location in the QoS table where to insert the entry. -+ * Only relevant if MASKING is enabled for QoS classification on -+ * this DPNI, it is ignored for exact match. -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpni_add_qos_entry(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_rule_cfg *cfg, -+ u8 tc_id, -+ u16 index) -+{ -+ struct dpni_cmd_add_qos_entry *cmd_params; -+ struct fsl_mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_QOS_ENT, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpni_cmd_add_qos_entry *)cmd.params; -+ cmd_params->tc_id = tc_id; -+ cmd_params->key_size = cfg->key_size; -+ cmd_params->index = cpu_to_le16(index); -+ cmd_params->key_iova = cpu_to_le64(cfg->key_iova); -+ cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpni_remove_qos_entry() - Remove QoS mapping entry -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPNI object -+ * @cfg: QoS rule to remove -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpni_remove_qos_entry(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_rule_cfg *cfg) -+{ -+ struct dpni_cmd_remove_qos_entry *cmd_params; -+ struct fsl_mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_QOS_ENT, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpni_cmd_remove_qos_entry *)cmd.params; -+ cmd_params->key_size = cfg->key_size; -+ cmd_params->key_iova = cpu_to_le64(cfg->key_iova); -+ cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpni_clear_qos_table() - Clear all QoS mapping entries -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPNI object -+ * -+ * Following this function call, all frames are directed to -+ * the default traffic class (0) -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpni_clear_qos_table(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_QOS_TBL, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h -@@ -716,6 +716,26 @@ int dpni_set_rx_hash_dist(struct fsl_mc_ - const struct dpni_rx_dist_cfg *cfg); - - /** -+ * struct dpni_qos_tbl_cfg - Structure representing QOS table configuration -+ * @key_cfg_iova: I/O virtual address of 256 bytes DMA-able memory filled with -+ * key extractions to be used as the QoS criteria by calling -+ * dpkg_prepare_key_cfg() -+ * @discard_on_miss: Set to '1' to discard frames in case of no match (miss); -+ * '0' to use the 'default_tc' in such cases -+ * @default_tc: Used in case of no-match and 'discard_on_miss'= 0 -+ */ -+struct dpni_qos_tbl_cfg { -+ u64 key_cfg_iova; -+ int discard_on_miss; -+ u8 default_tc; -+}; -+ -+int dpni_set_qos_table(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_qos_tbl_cfg *cfg); -+ -+/** - * enum dpni_dest - DPNI destination types - * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and - * does not generate FQDAN notifications; user is expected to -@@ -961,6 +981,22 @@ int dpni_remove_fs_entry(struct fsl_mc_i - u8 tc_id, - const struct dpni_rule_cfg *cfg); - -+int dpni_add_qos_entry(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_rule_cfg *cfg, -+ u8 tc_id, -+ u16 index); -+ -+int dpni_remove_qos_entry(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_rule_cfg *cfg); -+ -+int dpni_clear_qos_table(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token); -+ - int dpni_get_api_version(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 *major_ver, diff --git a/target/linux/layerscape/patches-5.4/701-net-0195-dpaa2-eth-Add-helper-functions.patch b/target/linux/layerscape/patches-5.4/701-net-0195-dpaa2-eth-Add-helper-functions.patch deleted file mode 100644 index 37cbbca727..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0195-dpaa2-eth-Add-helper-functions.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 1ffb57beaefe23ceeb526bc238351f7725502571 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Mon, 16 Sep 2019 21:04:49 +0300 -Subject: [PATCH] dpaa2-eth: Add helper functions - -Add convenient helper functions that determines whether Rx/Tx pause -frames are enabled based on link state flags received from firmware. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 3 +-- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 11 +++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 5 ++--- - 3 files changed, 14 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -1276,8 +1276,7 @@ static int link_state_update(struct dpaa - * Rx FQ taildrop configuration as well. We configure taildrop - * only when pause frame generation is disabled. - */ -- tx_pause = !!(state.options & DPNI_LINK_OPT_PAUSE) ^ -- !!(state.options & DPNI_LINK_OPT_ASYM_PAUSE); -+ tx_pause = dpaa2_eth_tx_pause_enabled(state.options); - dpaa2_eth_set_rx_taildrop(priv, !tx_pause); - - /* Chech link state; speed / duplex changes are not treated yet */ ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -495,6 +495,17 @@ enum dpaa2_eth_rx_dist { - (dpaa2_eth_cmp_dpni_ver((priv), DPNI_PAUSE_VER_MAJOR, \ - DPNI_PAUSE_VER_MINOR) >= 0) - -+static inline bool dpaa2_eth_tx_pause_enabled(u64 link_options) -+{ -+ return !!(link_options & DPNI_LINK_OPT_PAUSE) ^ -+ !!(link_options & DPNI_LINK_OPT_ASYM_PAUSE); -+} -+ -+static inline bool dpaa2_eth_rx_pause_enabled(u64 link_options) -+{ -+ return !!(link_options & DPNI_LINK_OPT_PAUSE); -+} -+ - static inline - unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv, - struct sk_buff *skb) ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -@@ -99,9 +99,8 @@ static void dpaa2_eth_get_pauseparam(str - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); - u64 link_options = priv->link_state.options; - -- pause->rx_pause = !!(link_options & DPNI_LINK_OPT_PAUSE); -- pause->tx_pause = pause->rx_pause ^ -- !!(link_options & DPNI_LINK_OPT_ASYM_PAUSE); -+ pause->rx_pause = dpaa2_eth_rx_pause_enabled(link_options); -+ pause->tx_pause = dpaa2_eth_tx_pause_enabled(link_options); - pause->autoneg = AUTONEG_DISABLE; - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0196-dpaa2-eth-Minor-cleanup-in-dpaa2_eth_set_rx_taildrop.patch b/target/linux/layerscape/patches-5.4/701-net-0196-dpaa2-eth-Minor-cleanup-in-dpaa2_eth_set_rx_taildrop.patch deleted file mode 100644 index 03c7ad5344..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0196-dpaa2-eth-Minor-cleanup-in-dpaa2_eth_set_rx_taildrop.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 965b47cbf16a6d1bc8235e1bff038abc9b4cf142 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 4 Sep 2019 19:45:01 +0300 -Subject: [PATCH] dpaa2-eth: Minor cleanup in dpaa2_eth_set_rx_taildrop() - -Make clear the setting refers to FQ-based taildrop and the threshold -value is given in bytes (the default option). - -Reverse the logic of the second argument (pass tx_pause transparently). -This will be helpful further on. - -Also don't set the device's Rx taildrop flag unless configuration -succeeds. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 19 +++++++++++-------- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 4 ++-- - 2 files changed, 13 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -1228,17 +1228,20 @@ static void disable_ch_napi(struct dpaa2 - } - } - --static void dpaa2_eth_set_rx_taildrop(struct dpaa2_eth_priv *priv, bool enable) -+static void dpaa2_eth_set_rx_taildrop(struct dpaa2_eth_priv *priv, -+ bool tx_pause) - { - struct dpni_taildrop td = {0}; - struct dpaa2_eth_fq *fq; - int i, err; - -- if (priv->rx_td_enabled == enable) -+ td.enable = !tx_pause; -+ if (priv->rx_td_enabled == td.enable) - return; - -- td.enable = enable; -- td.threshold = DPAA2_ETH_TAILDROP_THRESH; -+ /* FQ taildrop: thrshold is in bytes, per frame queue */ -+ td.threshold = DPAA2_ETH_FQ_TAILDROP_THRESH; -+ td.units = DPNI_CONGESTION_UNIT_BYTES; - - for (i = 0; i < priv->num_fqs; i++) { - fq = &priv->fq[i]; -@@ -1249,12 +1252,12 @@ static void dpaa2_eth_set_rx_taildrop(st - fq->tc, fq->flowid, &td); - if (err) { - netdev_err(priv->net_dev, -- "dpni_set_taildrop() failed\n"); -- break; -+ "dpni_set_taildrop(FQ) failed\n"); -+ return; - } - } - -- priv->rx_td_enabled = enable; -+ priv->rx_td_enabled = td.enable; - } - - static void update_tx_fqids(struct dpaa2_eth_priv *priv); -@@ -1277,7 +1280,7 @@ static int link_state_update(struct dpaa - * only when pause frame generation is disabled. - */ - tx_pause = dpaa2_eth_tx_pause_enabled(state.options); -- dpaa2_eth_set_rx_taildrop(priv, !tx_pause); -+ dpaa2_eth_set_rx_taildrop(priv, tx_pause); - - /* Chech link state; speed / duplex changes are not treated yet */ - if (priv->link_state.up == state.up) ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -39,7 +39,7 @@ - * frames in the Rx queues (length of the current frame is not - * taken into account when making the taildrop decision) - */ --#define DPAA2_ETH_TAILDROP_THRESH (64 * 1024) -+#define DPAA2_ETH_FQ_TAILDROP_THRESH (64 * 1024) - - /* Maximum number of Tx confirmation frames to be processed - * in a single NAPI call -@@ -51,7 +51,7 @@ - * how many 64B frames fit inside the taildrop threshold and add a margin - * to accommodate the buffer refill delay. - */ --#define DPAA2_ETH_MAX_FRAMES_PER_QUEUE (DPAA2_ETH_TAILDROP_THRESH / 64) -+#define DPAA2_ETH_MAX_FRAMES_PER_QUEUE (DPAA2_ETH_FQ_TAILDROP_THRESH / 64) - #define DPAA2_ETH_NUM_BUFS (DPAA2_ETH_MAX_FRAMES_PER_QUEUE + 256) - #define DPAA2_ETH_REFILL_THRESH \ - (DPAA2_ETH_NUM_BUFS - DPAA2_ETH_BUFS_PER_CMD) diff --git a/target/linux/layerscape/patches-5.4/701-net-0197-dpaa2-eth-Add-congestion-group-taildrop.patch b/target/linux/layerscape/patches-5.4/701-net-0197-dpaa2-eth-Add-congestion-group-taildrop.patch deleted file mode 100644 index 9125b94351..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0197-dpaa2-eth-Add-congestion-group-taildrop.patch +++ /dev/null @@ -1,64 +0,0 @@ -From fa204fc76c3936c55315ba9423fa7c920af2f9a9 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 4 Sep 2019 20:32:56 +0300 -Subject: [PATCH] dpaa2-eth: Add congestion group taildrop - -The increase in number of ingress frame queues means we now risk -depleting the buffer pool before the FQ taildrop kicks in. - -Congestion group taildrop allows us to control the number of frames -that can accumulate on a group of Rx frame queues belonging to the -same traffic class. - -This setting coexists with the frame queue based taildrop: whichever -limit gets hit first triggers the frame drop. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 16 ++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 9 +++++++++ - 2 files changed, 25 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -1257,6 +1257,22 @@ static void dpaa2_eth_set_rx_taildrop(st - } - } - -+ /* Congestion group taildrop: threshold is in frames, per group -+ * of FQs belonging to the same traffic class -+ */ -+ td.threshold = DPAA2_ETH_CG_TAILDROP_THRESH(priv); -+ td.units = DPNI_CONGESTION_UNIT_FRAMES; -+ for (i = 0; i < dpaa2_eth_tc_count(priv); i++) { -+ err = dpni_set_taildrop(priv->mc_io, 0, priv->mc_token, -+ DPNI_CP_GROUP, DPNI_QUEUE_RX, -+ i, 0, &td); -+ if (err) { -+ netdev_err(priv->net_dev, -+ "dpni_set_taildrop(CG) failed\n"); -+ return; -+ } -+ } -+ - priv->rx_td_enabled = td.enable; - } - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -56,6 +56,15 @@ - #define DPAA2_ETH_REFILL_THRESH \ - (DPAA2_ETH_NUM_BUFS - DPAA2_ETH_BUFS_PER_CMD) - -+/* Congestion group taildrop threshold: number of frames allowed to accumulate -+ * at any moment in a group of Rx queues belonging to the same traffic class. -+ * Choose value such that we don't risk depleting the buffer pool before the -+ * taildrop kicks in -+ */ -+#define DPAA2_ETH_CG_TAILDROP_THRESH(priv) \ -+ (DPAA2_ETH_MAX_FRAMES_PER_QUEUE * dpaa2_eth_queue_count(priv) / \ -+ dpaa2_eth_tc_count(priv)) -+ - /* Maximum number of buffers that can be acquired/released through a single - * QBMan command - */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0198-dpaa2-eth-Update-FQ-taildrop-threshold-and-buffer-po.patch b/target/linux/layerscape/patches-5.4/701-net-0198-dpaa2-eth-Update-FQ-taildrop-threshold-and-buffer-po.patch deleted file mode 100644 index d9f025f963..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0198-dpaa2-eth-Update-FQ-taildrop-threshold-and-buffer-po.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 0c7cb8b132f28cd150eb578a73c959de736364a2 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Mon, 16 Sep 2019 13:15:02 +0300 -Subject: [PATCH] dpaa2-eth: Update FQ taildrop threshold and buffer pool count - -Now that we have congestion group taildrop configured at all -times, we can afford to increase the frame queue taildrop -threshold; this will ensure a better response when receiving -bursts of large-sized frames. - -Also decouple the buffer pool count from the Rx FQ taildrop -threshold, as above change would increase it too much. Instead, -keep the old count as a hardcoded value. - -With the new limits, we try to ensure that: -* we allow enough leeway for large frame bursts (by buffering -enough of them in queues to avoid heavy dropping in case of -bursty traffic, but when overall ingress bandwidth is manageable) -* allow pending frames to be evenly spread between ingress FQs, -regardless of frame size -* avoid dropping frames due to the buffer pool being empty; this -is not a bad behaviour per se, but system overall response is -more linear and predictable when frames are dropped at frame -queue/group level. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 23 +++++++++++------------ - 1 file changed, 11 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -35,24 +35,24 @@ - /* Convert L3 MTU to L2 MFL */ - #define DPAA2_ETH_L2_MAX_FRM(mtu) ((mtu) + VLAN_ETH_HLEN) - --/* Set the taildrop threshold (in bytes) to allow the enqueue of several jumbo -- * frames in the Rx queues (length of the current frame is not -- * taken into account when making the taildrop decision) -+/* Set the taildrop threshold (in bytes) to allow the enqueue of a large -+ * enuough number of jumbo frames in the Rx queues (length of the current -+ * frame is not taken into account when making the taildrop decision) - */ --#define DPAA2_ETH_FQ_TAILDROP_THRESH (64 * 1024) -+#define DPAA2_ETH_FQ_TAILDROP_THRESH (1024 * 1024) - - /* Maximum number of Tx confirmation frames to be processed - * in a single NAPI call - */ - #define DPAA2_ETH_TXCONF_PER_NAPI 256 - --/* Buffer quota per queue. Must be large enough such that for minimum sized -- * frames taildrop kicks in before the bpool gets depleted, so we compute -- * how many 64B frames fit inside the taildrop threshold and add a margin -- * to accommodate the buffer refill delay. -+/* Buffer qouta per channel. We want to keep in check number of ingress frames -+ * in flight: for small sized frames, congestion group taildrop may kick in -+ * first; for large sizes, Rx FQ taildrop threshold will ensure only a -+ * reasonable number of frames will be pending at any given time. -+ * Ingress frame drop due to buffer pool depletion should be a corner case only - */ --#define DPAA2_ETH_MAX_FRAMES_PER_QUEUE (DPAA2_ETH_FQ_TAILDROP_THRESH / 64) --#define DPAA2_ETH_NUM_BUFS (DPAA2_ETH_MAX_FRAMES_PER_QUEUE + 256) -+#define DPAA2_ETH_NUM_BUFS 1280 - #define DPAA2_ETH_REFILL_THRESH \ - (DPAA2_ETH_NUM_BUFS - DPAA2_ETH_BUFS_PER_CMD) - -@@ -62,8 +62,7 @@ - * taildrop kicks in - */ - #define DPAA2_ETH_CG_TAILDROP_THRESH(priv) \ -- (DPAA2_ETH_MAX_FRAMES_PER_QUEUE * dpaa2_eth_queue_count(priv) / \ -- dpaa2_eth_tc_count(priv)) -+ (1024 * dpaa2_eth_queue_count(priv) / dpaa2_eth_tc_count(priv)) - - /* Maximum number of buffers that can be acquired/released through a single - * QBMan command diff --git a/target/linux/layerscape/patches-5.4/701-net-0199-dpaa2-eth-Add-DCB-ops.patch b/target/linux/layerscape/patches-5.4/701-net-0199-dpaa2-eth-Add-DCB-ops.patch deleted file mode 100644 index 965212ed54..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0199-dpaa2-eth-Add-DCB-ops.patch +++ /dev/null @@ -1,154 +0,0 @@ -From a893019278e8030fbe251cdaa9d93b8257d1c083 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Thu, 5 Sep 2019 19:31:32 +0300 -Subject: [PATCH] dpaa2-eth: Add DCB ops - -Add a skeleton implementation of DCB PFC ops. Actual hardware -configuration to be added in further commits. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/Kconfig | 9 +++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 84 ++++++++++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 5 ++ - 3 files changed, 98 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa2/Kconfig -+++ b/drivers/net/ethernet/freescale/dpaa2/Kconfig -@@ -8,6 +8,15 @@ config FSL_DPAA2_ETH - The driver manages network objects discovered on the Freescale - MC bus. - -+if FSL_DPAA2_ETH -+config FSL_DPAA2_ETH_DCB -+ bool "Data Center Bridging (DCB) Support" -+ default n -+ depends on DCB -+ help -+ Enable Priority-Based Flow Control (PFC) support in the driver -+endif -+ - config FSL_DPAA2_PTP_CLOCK - tristate "Freescale DPAA2 PTP Clock" - depends on FSL_DPAA2_ETH && PTP_1588_CLOCK_QORIQ ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -3614,6 +3614,81 @@ static void del_ch_napi(struct dpaa2_eth - } - } - -+#ifdef CONFIG_FSL_DPAA2_ETH_DCB -+static int dpaa2_eth_dcbnl_ieee_getpfc(struct net_device *net_dev, -+ struct ieee_pfc *pfc) -+{ -+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -+ -+ memcpy(pfc, &priv->pfc, sizeof(priv->pfc)); -+ pfc->pfc_cap = dpaa2_eth_tc_count(priv); -+ -+ return 0; -+} -+ -+static int dpaa2_eth_dcbnl_ieee_setpfc(struct net_device *net_dev, -+ struct ieee_pfc *pfc) -+{ -+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -+ -+ if (pfc->mbc || pfc->delay) -+ return -EOPNOTSUPP; -+ -+ /* If same PFC enabled mask, nothing to do */ -+ if (priv->pfc.pfc_en == pfc->pfc_en) -+ return 0; -+ -+ memcpy(&priv->pfc, pfc, sizeof(priv->pfc)); -+ -+ return 0; -+} -+ -+static u8 dpaa2_eth_dcbnl_getdcbx(struct net_device *net_dev) -+{ -+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -+ -+ return priv->dcbx_mode; -+} -+ -+static u8 dpaa2_eth_dcbnl_setdcbx(struct net_device *net_dev, u8 mode) -+{ -+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -+ -+ priv->dcbx_mode = mode; -+ return 0; -+} -+ -+static u8 dpaa2_eth_dcbnl_getcap(struct net_device *net_dev, int capid, u8 *cap) -+{ -+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -+ -+ switch (capid) { -+ case DCB_CAP_ATTR_PFC: -+ *cap = true; -+ break; -+ case DCB_CAP_ATTR_PFC_TCS: -+ *cap = 1 << (dpaa2_eth_tc_count(priv) - 1); -+ break; -+ case DCB_CAP_ATTR_DCBX: -+ *cap = priv->dcbx_mode; -+ break; -+ default: -+ *cap = false; -+ break; -+ } -+ -+ return 0; -+} -+ -+const struct dcbnl_rtnl_ops dpaa2_eth_dcbnl_ops = { -+ .ieee_getpfc = dpaa2_eth_dcbnl_ieee_getpfc, -+ .ieee_setpfc = dpaa2_eth_dcbnl_ieee_setpfc, -+ .getdcbx = dpaa2_eth_dcbnl_getdcbx, -+ .setdcbx = dpaa2_eth_dcbnl_setdcbx, -+ .getcap = dpaa2_eth_dcbnl_getcap, -+}; -+#endif -+ - static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev) - { - struct device *dev; -@@ -3703,6 +3778,15 @@ static int dpaa2_eth_probe(struct fsl_mc - if (err) - goto err_alloc_rings; - -+#ifdef CONFIG_FSL_DPAA2_ETH_DCB -+ if (dpaa2_eth_has_pause_support(priv) && priv->vlan_cls_enabled) { -+ priv->dcbx_mode = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE; -+ net_dev->dcbnl_ops = &dpaa2_eth_dcbnl_ops; -+ } else { -+ dev_dbg(dev, "PFC not supported\n"); -+ } -+#endif -+ - err = setup_irqs(dpni_dev); - if (err) { - netdev_warn(net_dev, "Failed to set link interrupt, fall back to polling\n"); ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -6,6 +6,7 @@ - #ifndef __DPAA2_ETH_H - #define __DPAA2_ETH_H - -+#include - #include - #include - #include -@@ -423,6 +424,10 @@ struct dpaa2_eth_priv { - struct dpaa2_eth_cls_rule *cls_rules; - u8 rx_cls_enabled; - u8 vlan_cls_enabled; -+#ifdef CONFIG_FSL_DPAA2_ETH_DCB -+ u8 dcbx_mode; -+ struct ieee_pfc pfc; -+#endif - struct bpf_prog *xdp_prog; - #ifdef CONFIG_DEBUG_FS - struct dpaa2_debugfs dbg; diff --git a/target/linux/layerscape/patches-5.4/701-net-0200-dpaa2-eth-Enable-Rx-PFC.patch b/target/linux/layerscape/patches-5.4/701-net-0200-dpaa2-eth-Enable-Rx-PFC.patch deleted file mode 100644 index 4396f2ea8e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0200-dpaa2-eth-Enable-Rx-PFC.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 7a342f60e569047e1632f6af91f503993769a2ec Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Tue, 17 Sep 2019 19:51:15 +0300 -Subject: [PATCH] dpaa2-eth: Enable Rx PFC - -Instruct the hardware to respond to received PFC frames. - -Current firmware doesn't allow us to selectively enable PFC -on the Rx side for some priorities only, so we will react to -all incoming PFC frames (and stop transmitting on the traffic -classes specified in the frame). - -PFC depends on the PAUSE flag also being set in link options. -Don't set it implicitly when user configures PFC, but issue -a warning if the two settings are not in sync. - -For the Tx side, setting the PFC_PAUSE flag in the link options -is necessary but not sufficient, so PFC frame generation is -not enabled yet. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 23 +++++++++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.h | 5 +++++ - 2 files changed, 28 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -3620,6 +3620,9 @@ static int dpaa2_eth_dcbnl_ieee_getpfc(s - { - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); - -+ if (!(priv->link_state.options & DPNI_LINK_OPT_PFC_PAUSE)) -+ return 0; -+ - memcpy(pfc, &priv->pfc, sizeof(priv->pfc)); - pfc->pfc_cap = dpaa2_eth_tc_count(priv); - -@@ -3630,6 +3633,8 @@ static int dpaa2_eth_dcbnl_ieee_setpfc(s - struct ieee_pfc *pfc) - { - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -+ struct dpni_link_cfg link_cfg = {0}; -+ int err; - - if (pfc->mbc || pfc->delay) - return -EOPNOTSUPP; -@@ -3638,6 +3643,24 @@ static int dpaa2_eth_dcbnl_ieee_setpfc(s - if (priv->pfc.pfc_en == pfc->pfc_en) - return 0; - -+ /* We allow PFC configuration even if it won't have any effect until -+ * general pause frames are enabled -+ */ -+ if (!dpaa2_eth_rx_pause_enabled(priv->link_state.options)) -+ netdev_warn(net_dev, "Pause support must be enabled in order for PFC to work!\n"); -+ -+ link_cfg.rate = priv->link_state.rate; -+ link_cfg.options = priv->link_state.options; -+ if (pfc->pfc_en) -+ link_cfg.options |= DPNI_LINK_OPT_PFC_PAUSE; -+ else -+ link_cfg.options &= ~DPNI_LINK_OPT_PFC_PAUSE; -+ err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &link_cfg); -+ if (err) { -+ netdev_err(net_dev, "dpni_set_link_cfg failed\n"); -+ return err; -+ } -+ - memcpy(&priv->pfc, pfc, sizeof(priv->pfc)); - - return 0; ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h -@@ -514,6 +514,11 @@ int dpni_get_statistics(struct fsl_mc_io - #define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL - - /** -+ * Enable priority flow control pause frames -+ */ -+#define DPNI_LINK_OPT_PFC_PAUSE 0x0000000000000010ULL -+ -+/** - * struct - Structure representing DPNI link configuration - * @rate: Rate - * @options: Mask of available options; use 'DPNI_LINK_OPT_' values diff --git a/target/linux/layerscape/patches-5.4/701-net-0201-dpaa2-eth-Enable-Tx-PFC.patch b/target/linux/layerscape/patches-5.4/701-net-0201-dpaa2-eth-Enable-Tx-PFC.patch deleted file mode 100644 index 7d18504070..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0201-dpaa2-eth-Enable-Tx-PFC.patch +++ /dev/null @@ -1,263 +0,0 @@ -From 07fb72fb5b3d2faeeb742ae573aa54a4a1eeee12 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Tue, 17 Sep 2019 20:36:08 +0300 -Subject: [PATCH] dpaa2-eth: Enable Tx PFC - -Configure the hardware to generate PFC frames based on Rx congestion -notifications. When a certain number of frames accumulate in the -ingress queues corresponding to a traffic class, priority flow control -frames are generated for that TC. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 49 ++++++++++++++++++++- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 11 +++++ - drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 25 +++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.c | 46 +++++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.h | 56 ++++++++++++++++++++++++ - 5 files changed, 186 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -3629,6 +3629,47 @@ static int dpaa2_eth_dcbnl_ieee_getpfc(s - return 0; - } - -+static inline bool is_prio_enabled(u8 pfc_en, u8 tc) -+{ -+ return !!(pfc_en & (1 << tc)); -+} -+ -+static int set_pfc_cn(struct dpaa2_eth_priv *priv, u8 pfc_en) -+{ -+ struct dpni_congestion_notification_cfg cfg = {0}; -+ int i, err; -+ -+ cfg.notification_mode = DPNI_CONG_OPT_FLOW_CONTROL; -+ cfg.units = DPNI_CONGESTION_UNIT_FRAMES; -+ cfg.message_iova = 0ULL; -+ cfg.message_ctx = 0ULL; -+ -+ for (i = 0; i < dpaa2_eth_tc_count(priv); i++) { -+ if (is_prio_enabled(pfc_en, i)) { -+ cfg.threshold_entry = DPAA2_ETH_CN_THRESH_ENTRY(priv); -+ cfg.threshold_exit = DPAA2_ETH_CN_THRESH_EXIT(priv); -+ } else { -+ /* For priorities not set in the pfc_en mask, we leave -+ * the congestion thresholds at zero, which effectively -+ * disables generation of PFC frames for them -+ */ -+ cfg.threshold_entry = 0; -+ cfg.threshold_exit = 0; -+ } -+ -+ err = dpni_set_congestion_notification(priv->mc_io, 0, -+ priv->mc_token, -+ DPNI_QUEUE_RX, i, &cfg); -+ if (err) { -+ netdev_err(priv->net_dev, -+ "dpni_set_congestion_notification failed\n"); -+ return err; -+ } -+ } -+ -+ return 0; -+} -+ - static int dpaa2_eth_dcbnl_ieee_setpfc(struct net_device *net_dev, - struct ieee_pfc *pfc) - { -@@ -3646,7 +3687,8 @@ static int dpaa2_eth_dcbnl_ieee_setpfc(s - /* We allow PFC configuration even if it won't have any effect until - * general pause frames are enabled - */ -- if (!dpaa2_eth_rx_pause_enabled(priv->link_state.options)) -+ if (!dpaa2_eth_rx_pause_enabled(priv->link_state.options) || -+ !dpaa2_eth_tx_pause_enabled(priv->link_state.options)) - netdev_warn(net_dev, "Pause support must be enabled in order for PFC to work!\n"); - - link_cfg.rate = priv->link_state.rate; -@@ -3661,6 +3703,11 @@ static int dpaa2_eth_dcbnl_ieee_setpfc(s - return err; - } - -+ /* Configure congestion notifications for the enabled priorities */ -+ err = set_pfc_cn(priv, pfc->pfc_en); -+ if (err) -+ return err; -+ - memcpy(&priv->pfc, pfc, sizeof(priv->pfc)); - - return 0; ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -65,6 +65,17 @@ - #define DPAA2_ETH_CG_TAILDROP_THRESH(priv) \ - (1024 * dpaa2_eth_queue_count(priv) / dpaa2_eth_tc_count(priv)) - -+/* Congestion group notification threshold: when this many frames accumulate -+ * on the Rx queues belonging to the same TC, the MAC is instructed to send -+ * PFC frames for that TC. -+ * When number of pending frames drops below exit threshold transmission of -+ * PFC frames is stopped. -+ */ -+#define DPAA2_ETH_CN_THRESH_ENTRY(priv) \ -+ (DPAA2_ETH_CG_TAILDROP_THRESH(priv) / 2) -+#define DPAA2_ETH_CN_THRESH_EXIT(priv) \ -+ (DPAA2_ETH_CN_THRESH_ENTRY(priv) * 3 / 4) -+ - /* Maximum number of buffers that can be acquired/released through a single - * QBMan command - */ ---- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -@@ -601,4 +601,29 @@ struct dpni_cmd_remove_qos_entry { - __le64 mask_iova; - }; - -+#define DPNI_DEST_TYPE_SHIFT 0 -+#define DPNI_DEST_TYPE_SIZE 4 -+#define DPNI_CONG_UNITS_SHIFT 4 -+#define DPNI_CONG_UNITS_SIZE 2 -+ -+struct dpni_cmd_set_congestion_notification { -+ /* cmd word 0 */ -+ u8 qtype; -+ u8 tc; -+ u8 pad[6]; -+ /* cmd word 1 */ -+ __le32 dest_id; -+ __le16 notification_mode; -+ u8 dest_priority; -+ /* from LSB: dest_type: 4 units:2 */ -+ u8 type_units; -+ /* cmd word 2 */ -+ __le64 message_iova; -+ /* cmd word 3 */ -+ __le64 message_ctx; -+ /* cmd word 4 */ -+ __le32 threshold_entry; -+ __le32 threshold_exit; -+}; -+ - #endif /* _FSL_DPNI_CMD_H */ ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c -@@ -1355,6 +1355,52 @@ int dpni_set_rx_tc_dist(struct fsl_mc_io - } - - /** -+ * dpni_set_congestion_notification() - Set traffic class congestion -+ * notification configuration -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPNI object -+ * @qtype: Type of queue - Rx, Tx and Tx confirm types are supported -+ * @tc_id: Traffic class selection (0-7) -+ * @cfg: Congestion notification configuration -+ * -+ * Return: '0' on Success; error code otherwise. -+ */ -+int dpni_set_congestion_notification( -+ struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ enum dpni_queue_type qtype, -+ u8 tc_id, -+ const struct dpni_congestion_notification_cfg *cfg) -+{ -+ struct dpni_cmd_set_congestion_notification *cmd_params; -+ struct fsl_mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = -+ mc_encode_cmd_header(DPNI_CMDID_SET_CONGESTION_NOTIFICATION, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpni_cmd_set_congestion_notification *)cmd.params; -+ cmd_params->qtype = qtype; -+ cmd_params->tc = tc_id; -+ cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id); -+ cmd_params->notification_mode = cpu_to_le16(cfg->notification_mode); -+ cmd_params->dest_priority = cfg->dest_cfg.priority; -+ dpni_set_field(cmd_params->type_units, DEST_TYPE, -+ cfg->dest_cfg.dest_type); -+ dpni_set_field(cmd_params->type_units, CONG_UNITS, cfg->units); -+ cmd_params->message_iova = cpu_to_le64(cfg->message_iova); -+ cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx); -+ cmd_params->threshold_entry = cpu_to_le32(cfg->threshold_entry); -+ cmd_params->threshold_exit = cpu_to_le32(cfg->threshold_exit); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** - * dpni_set_queue() - Set queue parameters - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h -@@ -883,6 +883,62 @@ enum dpni_congestion_point { - }; - - /** -+ * struct dpni_dest_cfg - Structure representing DPNI destination parameters -+ * @dest_type: Destination type -+ * @dest_id: Either DPIO ID or DPCON ID, depending on the destination type -+ * @priority: Priority selection within the DPIO or DPCON channel; valid -+ * values are 0-1 or 0-7, depending on the number of priorities -+ * in that channel; not relevant for 'DPNI_DEST_NONE' option -+ */ -+struct dpni_dest_cfg { -+ enum dpni_dest dest_type; -+ int dest_id; -+ u8 priority; -+}; -+ -+/* DPNI congestion options */ -+ -+/** -+ * This congestion will trigger flow control or priority flow control. -+ * This will have effect only if flow control is enabled with -+ * dpni_set_link_cfg(). -+ */ -+#define DPNI_CONG_OPT_FLOW_CONTROL 0x00000040 -+ -+/** -+ * struct dpni_congestion_notification_cfg - congestion notification -+ * configuration -+ * @units: Units type -+ * @threshold_entry: Above this threshold we enter a congestion state. -+ * set it to '0' to disable it -+ * @threshold_exit: Below this threshold we exit the congestion state. -+ * @message_ctx: The context that will be part of the CSCN message -+ * @message_iova: I/O virtual address (must be in DMA-able memory), -+ * must be 16B aligned; valid only if 'DPNI_CONG_OPT_WRITE_MEM_' -+ * is contained in 'options' -+ * @dest_cfg: CSCN can be send to either DPIO or DPCON WQ channel -+ * @notification_mode: Mask of available options; use 'DPNI_CONG_OPT_' values -+ */ -+ -+struct dpni_congestion_notification_cfg { -+ enum dpni_congestion_unit units; -+ u32 threshold_entry; -+ u32 threshold_exit; -+ u64 message_ctx; -+ u64 message_iova; -+ struct dpni_dest_cfg dest_cfg; -+ u16 notification_mode; -+}; -+ -+int dpni_set_congestion_notification( -+ struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ enum dpni_queue_type qtype, -+ u8 tc_id, -+ const struct dpni_congestion_notification_cfg *cfg); -+ -+/** - * struct dpni_taildrop - Structure representing the taildrop - * @enable: Indicates whether the taildrop is active or not. - * @units: Indicates the unit of THRESHOLD. Queue taildrop only supports diff --git a/target/linux/layerscape/patches-5.4/701-net-0202-dpaa2-eth-Keep-congestion-group-taildrop-enabled-whe.patch b/target/linux/layerscape/patches-5.4/701-net-0202-dpaa2-eth-Keep-congestion-group-taildrop-enabled-whe.patch deleted file mode 100644 index 9a0024636d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0202-dpaa2-eth-Keep-congestion-group-taildrop-enabled-whe.patch +++ /dev/null @@ -1,138 +0,0 @@ -From b58fa682dceaee9e2576f9ba3f36942c650414ae Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Tue, 17 Sep 2019 21:14:04 +0300 -Subject: [PATCH] dpaa2-eth: Keep congestion group taildrop enabled when PFC on - -Leave congestion group taildrop enabled for all traffic classes -when PFC is enabled. Notification threshold is low enough such -that it will be hit first and this also ensures that FQs on -traffic classes which are not PFC enabled won't drain the buffer -pool. - -FQ taildrop threshold is kept disabled as long as any form of -flow control is on. Since FQ taildrop works with bytes, not number -of frames, we can't guarantee it will not interfere with the -congestion notification mechanism for all frame sizes. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 35 ++++++++++++++++++------ - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 4 ++- - 2 files changed, 30 insertions(+), 9 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -1229,17 +1229,21 @@ static void disable_ch_napi(struct dpaa2 - } - - static void dpaa2_eth_set_rx_taildrop(struct dpaa2_eth_priv *priv, -- bool tx_pause) -+ bool tx_pause, bool pfc) - { - struct dpni_taildrop td = {0}; - struct dpaa2_eth_fq *fq; - int i, err; - -+ /* FQ taildrop: threshold is in bytes, per frame queue. Enabled if -+ * flow control is disabled (as it might interfere with either the -+ * buffer pool depletion trigger for pause frames or with the group -+ * congestion trigger for PFC frames) -+ */ - td.enable = !tx_pause; -- if (priv->rx_td_enabled == td.enable) -- return; -+ if (priv->rx_fqtd_enabled == td.enable) -+ goto set_cgtd; - -- /* FQ taildrop: thrshold is in bytes, per frame queue */ - td.threshold = DPAA2_ETH_FQ_TAILDROP_THRESH; - td.units = DPNI_CONGESTION_UNIT_BYTES; - -@@ -1257,9 +1261,20 @@ static void dpaa2_eth_set_rx_taildrop(st - } - } - -+ priv->rx_fqtd_enabled = td.enable; -+ -+set_cgtd: - /* Congestion group taildrop: threshold is in frames, per group - * of FQs belonging to the same traffic class -+ * Enabled if general Tx pause disabled or if PFCs are enabled -+ * (congestion group threhsold for PFC generation is lower than the -+ * CG taildrop threshold, so it won't interfere with it; we also -+ * want frames in non-PFC enabled traffic classes to be kept in check) - */ -+ td.enable = !tx_pause || (tx_pause && pfc); -+ if (priv->rx_cgtd_enabled == td.enable) -+ return; -+ - td.threshold = DPAA2_ETH_CG_TAILDROP_THRESH(priv); - td.units = DPNI_CONGESTION_UNIT_FRAMES; - for (i = 0; i < dpaa2_eth_tc_count(priv); i++) { -@@ -1273,7 +1288,7 @@ static void dpaa2_eth_set_rx_taildrop(st - } - } - -- priv->rx_td_enabled = td.enable; -+ priv->rx_cgtd_enabled = td.enable; - } - - static void update_tx_fqids(struct dpaa2_eth_priv *priv); -@@ -1296,7 +1311,7 @@ static int link_state_update(struct dpaa - * only when pause frame generation is disabled. - */ - tx_pause = dpaa2_eth_tx_pause_enabled(state.options); -- dpaa2_eth_set_rx_taildrop(priv, tx_pause); -+ dpaa2_eth_set_rx_taildrop(priv, tx_pause, priv->pfc_enabled); - - /* Chech link state; speed / duplex changes are not treated yet */ - if (priv->link_state.up == state.up) -@@ -3675,6 +3690,7 @@ static int dpaa2_eth_dcbnl_ieee_setpfc(s - { - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); - struct dpni_link_cfg link_cfg = {0}; -+ bool tx_pause; - int err; - - if (pfc->mbc || pfc->delay) -@@ -3687,8 +3703,8 @@ static int dpaa2_eth_dcbnl_ieee_setpfc(s - /* We allow PFC configuration even if it won't have any effect until - * general pause frames are enabled - */ -- if (!dpaa2_eth_rx_pause_enabled(priv->link_state.options) || -- !dpaa2_eth_tx_pause_enabled(priv->link_state.options)) -+ tx_pause = dpaa2_eth_tx_pause_enabled(priv->link_state.options); -+ if (!dpaa2_eth_rx_pause_enabled(priv->link_state.options) || !tx_pause) - netdev_warn(net_dev, "Pause support must be enabled in order for PFC to work!\n"); - - link_cfg.rate = priv->link_state.rate; -@@ -3709,6 +3725,9 @@ static int dpaa2_eth_dcbnl_ieee_setpfc(s - return err; - - memcpy(&priv->pfc, pfc, sizeof(priv->pfc)); -+ priv->pfc_enabled = !!pfc->pfc_en; -+ -+ dpaa2_eth_set_rx_taildrop(priv, tx_pause, priv->pfc_enabled); - - return 0; - } ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -423,7 +423,8 @@ struct dpaa2_eth_priv { - struct dpaa2_eth_drv_stats __percpu *percpu_extras; - - u16 mc_token; -- u8 rx_td_enabled; -+ u8 rx_fqtd_enabled; -+ u8 rx_cgtd_enabled; - - struct dpni_link_state link_state; - bool do_link_poll; -@@ -435,6 +436,7 @@ struct dpaa2_eth_priv { - struct dpaa2_eth_cls_rule *cls_rules; - u8 rx_cls_enabled; - u8 vlan_cls_enabled; -+ u8 pfc_enabled; - #ifdef CONFIG_FSL_DPAA2_ETH_DCB - u8 dcbx_mode; - struct ieee_pfc pfc; diff --git a/target/linux/layerscape/patches-5.4/701-net-0203-dpaa2-eth-Add-Tx-shaping-API.patch b/target/linux/layerscape/patches-5.4/701-net-0203-dpaa2-eth-Add-Tx-shaping-API.patch deleted file mode 100644 index f1bbc5546d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0203-dpaa2-eth-Add-Tx-shaping-API.patch +++ /dev/null @@ -1,94 +0,0 @@ -From bec2af878c58bbd12f9009948d4fc58ad9c7c1d3 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Fri, 5 May 2017 18:45:50 +0300 -Subject: [PATCH] dpaa2-eth: Add Tx shaping API - -DPNIs can be configured to accept a maximum Tx rate and -burst size. Add the MC API for controlling these parameters. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 8 +++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.c | 29 +++++++++++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.h | 15 +++++++++++++ - 3 files changed, 52 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -@@ -315,6 +315,14 @@ struct dpni_rsp_get_link_state { - __le64 options; - }; - -+struct dpni_cmd_set_tx_shaping { -+ /* cmd word 0 */ -+ __le16 max_burst_size; -+ __le16 pad[3]; -+ /* cmd word 1 */ -+ __le32 rate_limit; -+}; -+ - struct dpni_cmd_set_max_frame_length { - __le16 max_frame_length; - }; ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c -@@ -926,6 +926,35 @@ int dpni_get_link_state(struct fsl_mc_io - } - - /** -+ * dpni_set_tx_shaping() - Set the transmit shaping -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPNI object -+ * @tx_shaper: Tx shaping configuration -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpni_set_tx_shaping(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_tx_shaping_cfg *tx_shaper) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpni_cmd_set_tx_shaping *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_SHAPING, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpni_cmd_set_tx_shaping *)cmd.params; -+ cmd_params->max_burst_size = cpu_to_le16(tx_shaper->max_burst_size); -+ cmd_params->rate_limit = cpu_to_le32(tx_shaper->rate_limit); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** - * dpni_set_max_frame_length() - Set the maximum received frame length. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h -@@ -555,6 +555,21 @@ int dpni_get_link_state(struct fsl_mc_io - u16 token, - struct dpni_link_state *state); - -+/** -+ * struct dpni_tx_shaping - Structure representing DPNI tx shaping configuration -+ * @rate_limit: rate in Mbps -+ * @max_burst_size: burst size in bytes (up to 64KB) -+ */ -+struct dpni_tx_shaping_cfg { -+ u32 rate_limit; -+ u16 max_burst_size; -+}; -+ -+int dpni_set_tx_shaping(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_tx_shaping_cfg *tx_shaper); -+ - int dpni_set_max_frame_length(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, diff --git a/target/linux/layerscape/patches-5.4/701-net-0204-dpaa2-eth-Add-Tx-shaping-support.patch b/target/linux/layerscape/patches-5.4/701-net-0204-dpaa2-eth-Add-Tx-shaping-support.patch deleted file mode 100644 index 4974362d71..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0204-dpaa2-eth-Add-Tx-shaping-support.patch +++ /dev/null @@ -1,142 +0,0 @@ -From ef0cc7d01f3eeca37c6bf864903af1c0cf0a792d Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Fri, 5 May 2017 18:11:08 +0300 -Subject: [PATCH] dpaa2-eth: Add Tx shaping support - -Add support in sysfs for controlling DPNI Tx shaping -parameters: rate limit (in Mbps) and max burst size (in bytes). -The settings are per port. - -TODO: See how to integrate Tx shaping support using -standard Linux tools (ethtool) - -Signed-off-by: Ioana Radulescu -Signed-off-by: Bogdan Purcareata ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 80 ++++++++++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 4 ++ - 2 files changed, 84 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -3778,6 +3778,83 @@ const struct dcbnl_rtnl_ops dpaa2_eth_dc - }; - #endif - -+/* SysFS support */ -+static ssize_t dpaa2_eth_show_tx_shaping(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct dpaa2_eth_priv *priv = netdev_priv(to_net_dev(dev)); -+ /* No MC API for getting the shaping config. We're stateful. */ -+ struct dpni_tx_shaping_cfg *scfg = &priv->shaping_cfg; -+ -+ return sprintf(buf, "%u %hu\n", scfg->rate_limit, scfg->max_burst_size); -+} -+ -+static ssize_t dpaa2_eth_write_tx_shaping(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, -+ size_t count) -+{ -+ int err, items; -+ struct dpaa2_eth_priv *priv = netdev_priv(to_net_dev(dev)); -+ struct dpni_tx_shaping_cfg scfg; -+ -+ items = sscanf(buf, "%u %hu", &scfg.rate_limit, &scfg.max_burst_size); -+ if (items != 2) { -+ pr_err("Expected format: \"rate_limit(Mbps) max_burst_size(bytes)\"\n"); -+ return -EINVAL; -+ } -+ /* Size restriction as per MC API documentation */ -+ if (scfg.max_burst_size > DPAA2_ETH_MAX_BURST_SIZE) { -+ pr_err("max_burst_size must be <= %d\n", -+ DPAA2_ETH_MAX_BURST_SIZE); -+ return -EINVAL; -+ } -+ -+ err = dpni_set_tx_shaping(priv->mc_io, 0, priv->mc_token, &scfg); -+ if (err) { -+ dev_err(dev, "dpni_set_tx_shaping() failed\n"); -+ return -EPERM; -+ } -+ /* If successful, save the current configuration for future inquiries */ -+ priv->shaping_cfg = scfg; -+ -+ return count; -+} -+ -+static struct device_attribute dpaa2_eth_attrs[] = { -+ __ATTR(tx_shaping, -+ 0600, -+ dpaa2_eth_show_tx_shaping, -+ dpaa2_eth_write_tx_shaping), -+}; -+ -+static void dpaa2_eth_sysfs_init(struct device *dev) -+{ -+ int i, err; -+ -+ for (i = 0; i < ARRAY_SIZE(dpaa2_eth_attrs); i++) { -+ err = device_create_file(dev, &dpaa2_eth_attrs[i]); -+ if (err) { -+ dev_err(dev, "ERROR creating sysfs file\n"); -+ goto undo; -+ } -+ } -+ return; -+ -+undo: -+ while (i > 0) -+ device_remove_file(dev, &dpaa2_eth_attrs[--i]); -+} -+ -+static void dpaa2_eth_sysfs_remove(struct device *dev) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dpaa2_eth_attrs); i++) -+ device_remove_file(dev, &dpaa2_eth_attrs[i]); -+} -+ - static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev) - { - struct device *dev; -@@ -3897,6 +3974,7 @@ static int dpaa2_eth_probe(struct fsl_mc - #ifdef CONFIG_DEBUG_FS - dpaa2_dbg_add(priv); - #endif -+ dpaa2_eth_sysfs_init(&net_dev->dev); - - dev_info(dev, "Probed interface %s\n", net_dev->name); - return 0; -@@ -3944,6 +4022,8 @@ static int dpaa2_eth_remove(struct fsl_m - #ifdef CONFIG_DEBUG_FS - dpaa2_dbg_remove(priv); - #endif -+ dpaa2_eth_sysfs_remove(&net_dev->dev); -+ - unregister_netdev(net_dev); - - if (priv->do_link_poll) ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -42,6 +42,9 @@ - */ - #define DPAA2_ETH_FQ_TAILDROP_THRESH (1024 * 1024) - -+/* Maximum burst size value for Tx shaping */ -+#define DPAA2_ETH_MAX_BURST_SIZE 0xF7FF -+ - /* Maximum number of Tx confirmation frames to be processed - * in a single NAPI call - */ -@@ -445,6 +448,7 @@ struct dpaa2_eth_priv { - #ifdef CONFIG_DEBUG_FS - struct dpaa2_debugfs dbg; - #endif -+ struct dpni_tx_shaping_cfg shaping_cfg; - }; - - #define DPAA2_RXH_SUPPORTED (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO \ diff --git a/target/linux/layerscape/patches-5.4/701-net-0205-dpaa2-eth-Add-Rx-error-queue.patch b/target/linux/layerscape/patches-5.4/701-net-0205-dpaa2-eth-Add-Rx-error-queue.patch deleted file mode 100644 index 5d5d8f5fd5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0205-dpaa2-eth-Add-Rx-error-queue.patch +++ /dev/null @@ -1,202 +0,0 @@ -From 73b0aa73b401810424afa90bf58663a56ad9d51a Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Fri, 5 May 2017 19:07:50 +0300 -Subject: [PATCH] dpaa2-eth: Add Rx error queue - -Until now all error frames on the ingress path were discarded -in hardware. For debug purposes, add an option to have these -frames delivered to the cpu, on a dedicated queue. - -TODO: Remove Kconfig option, find another way to enable -Rx error queue support - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/Kconfig | 10 +++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 97 ++++++++++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 5 +- - 3 files changed, 111 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/Kconfig -+++ b/drivers/net/ethernet/freescale/dpaa2/Kconfig -@@ -15,6 +15,16 @@ config FSL_DPAA2_ETH_DCB - depends on DCB - help - Enable Priority-Based Flow Control (PFC) support in the driver -+ -+config FSL_DPAA2_ETH_USE_ERR_QUEUE -+ bool "Enable Rx error queue" -+ default n -+ help -+ Allow Rx error frames to be enqueued on an error queue -+ and processed by the driver (by default they are dropped -+ in hardware). -+ This may impact performance, recommended for debugging -+ purposes only. - endif - - config FSL_DPAA2_PTP_CLOCK ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -449,6 +449,53 @@ err_frame_format: - percpu_stats->rx_dropped++; - } - -+#ifdef CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE -+/* Processing of Rx frames received on the error FQ -+ * We check and print the error bits and then free the frame -+ */ -+static void dpaa2_eth_rx_err(struct dpaa2_eth_priv *priv, -+ struct dpaa2_eth_channel *ch, -+ const struct dpaa2_fd *fd, -+ struct dpaa2_eth_fq *fq __always_unused) -+{ -+ struct device *dev = priv->net_dev->dev.parent; -+ dma_addr_t addr = dpaa2_fd_get_addr(fd); -+ void *vaddr; -+ struct rtnl_link_stats64 *percpu_stats; -+ struct dpaa2_fas *fas; -+ u32 status = 0; -+ u32 fd_errors; -+ bool has_fas_errors = false; -+ -+ vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr); -+ dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE, DMA_BIDIRECTIONAL); -+ -+ /* check frame errors in the FD field */ -+ fd_errors = dpaa2_fd_get_ctrl(fd) & DPAA2_FD_RX_ERR_MASK; -+ if (likely(fd_errors)) { -+ has_fas_errors = (fd_errors & FD_CTRL_FAERR) && -+ !!(dpaa2_fd_get_frc(fd) & DPAA2_FD_FRC_FASV); -+ if (net_ratelimit()) -+ netdev_dbg(priv->net_dev, "RX frame FD err: %08x\n", -+ fd_errors); -+ } -+ -+ /* check frame errors in the FAS field */ -+ if (has_fas_errors) { -+ fas = dpaa2_get_fas(vaddr, false); -+ status = le32_to_cpu(fas->status); -+ if (net_ratelimit()) -+ netdev_dbg(priv->net_dev, "Rx frame FAS err: 0x%08x\n", -+ status & DPAA2_FAS_RX_ERR_MASK); -+ } -+ free_rx_fd(priv, fd, vaddr); -+ -+ percpu_stats = this_cpu_ptr(priv->percpu_stats); -+ percpu_stats->rx_errors++; -+ ch->buf_count--; -+} -+#endif -+ - /* Consume all frames pull-dequeued into the store. This is the simplest way to - * make sure we don't accidentally issue another volatile dequeue which would - * overwrite (leak) frames already in the store. -@@ -2351,6 +2398,7 @@ static void set_fq_affinity(struct dpaa2 - fq = &priv->fq[i]; - switch (fq->type) { - case DPAA2_RX_FQ: -+ case DPAA2_RX_ERR_FQ: - fq->target_cpu = rx_cpu; - rx_cpu = cpumask_next(rx_cpu, &priv->dpio_cpumask); - if (rx_cpu >= nr_cpu_ids) -@@ -2394,6 +2442,12 @@ static void setup_fqs(struct dpaa2_eth_p - } - } - -+#ifdef CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE -+ /* We have exactly one Rx error queue per DPNI */ -+ priv->fq[priv->num_fqs].type = DPAA2_RX_ERR_FQ; -+ priv->fq[priv->num_fqs++].consume = dpaa2_eth_rx_err; -+#endif -+ - /* For each FQ, decide on which core to process incoming frames */ - set_fq_affinity(priv); - } -@@ -2946,6 +3000,40 @@ static int setup_tx_flow(struct dpaa2_et - return 0; - } - -+#ifdef CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE -+static int setup_rx_err_flow(struct dpaa2_eth_priv *priv, -+ struct dpaa2_eth_fq *fq) -+{ -+ struct device *dev = priv->net_dev->dev.parent; -+ struct dpni_queue q = { { 0 } }; -+ struct dpni_queue_id qid; -+ u8 q_opt = DPNI_QUEUE_OPT_USER_CTX | DPNI_QUEUE_OPT_DEST; -+ int err; -+ -+ err = dpni_get_queue(priv->mc_io, 0, priv->mc_token, -+ DPNI_QUEUE_RX_ERR, 0, 0, &q, &qid); -+ if (err) { -+ dev_err(dev, "dpni_get_queue() failed (%d)\n", err); -+ return err; -+ } -+ -+ fq->fqid = qid.fqid; -+ -+ q.destination.id = fq->channel->dpcon_id; -+ q.destination.type = DPNI_DEST_DPCON; -+ q.destination.priority = 1; -+ q.user_context = (u64)fq; -+ err = dpni_set_queue(priv->mc_io, 0, priv->mc_token, -+ DPNI_QUEUE_RX_ERR, 0, 0, q_opt, &q); -+ if (err) { -+ dev_err(dev, "dpni_set_queue() failed (%d)\n", err); -+ return err; -+ } -+ -+ return 0; -+} -+#endif -+ - /* Supported header fields for Rx hash distribution key */ - static const struct dpaa2_eth_dist_fields dist_fields[] = { - { -@@ -3315,7 +3403,11 @@ static int bind_dpni(struct dpaa2_eth_pr - /* Configure handling of error frames */ - err_cfg.errors = DPAA2_FAS_RX_ERR_MASK; - err_cfg.set_frame_annotation = 1; -+#ifdef CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE -+ err_cfg.error_action = DPNI_ERROR_ACTION_SEND_TO_ERROR_QUEUE; -+#else - err_cfg.error_action = DPNI_ERROR_ACTION_DISCARD; -+#endif - err = dpni_set_errors_behavior(priv->mc_io, 0, priv->mc_token, - &err_cfg); - if (err) { -@@ -3332,6 +3424,11 @@ static int bind_dpni(struct dpaa2_eth_pr - case DPAA2_TX_CONF_FQ: - err = setup_tx_flow(priv, &priv->fq[i]); - break; -+#ifdef CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE -+ case DPAA2_RX_ERR_FQ: -+ err = setup_rx_err_flow(priv, &priv->fq[i]); -+ break; -+#endif - default: - dev_err(dev, "Invalid FQ type %d\n", priv->fq[i].type); - return -EINVAL; ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -318,8 +318,10 @@ struct dpaa2_eth_ch_stats { - #define DPAA2_ETH_MAX_RX_QUEUES \ - (DPAA2_ETH_MAX_RX_QUEUES_PER_TC * DPAA2_ETH_MAX_TCS) - #define DPAA2_ETH_MAX_TX_QUEUES 16 -+#define DPAA2_ETH_MAX_RX_ERR_QUEUES 1 - #define DPAA2_ETH_MAX_QUEUES (DPAA2_ETH_MAX_RX_QUEUES + \ -- DPAA2_ETH_MAX_TX_QUEUES) -+ DPAA2_ETH_MAX_TX_QUEUES + \ -+ DPAA2_ETH_MAX_RX_ERR_QUEUES) - #define DPAA2_ETH_MAX_NETDEV_QUEUES \ - (DPAA2_ETH_MAX_TX_QUEUES * DPAA2_ETH_MAX_TCS) - -@@ -328,6 +330,7 @@ struct dpaa2_eth_ch_stats { - enum dpaa2_eth_fq_type { - DPAA2_RX_FQ = 0, - DPAA2_TX_CONF_FQ, -+ DPAA2_RX_ERR_FQ - }; - - struct dpaa2_eth_priv; diff --git a/target/linux/layerscape/patches-5.4/701-net-0206-dpaa2-eth-Add-API-for-counters-reset.patch b/target/linux/layerscape/patches-5.4/701-net-0206-dpaa2-eth-Add-API-for-counters-reset.patch deleted file mode 100644 index 30f9208616..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0206-dpaa2-eth-Add-API-for-counters-reset.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 991c03df1b0543ed02a5d4e803ac8fa9d993fb8e Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Tue, 9 May 2017 16:36:39 +0300 -Subject: [PATCH] dpaa2-eth: Add API for counters reset - -Add DPNI object API function for resetting interface -hardware counters. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 1 + - drivers/net/ethernet/freescale/dpaa2/dpni.c | 23 +++++++++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.h | 4 ++++ - 3 files changed, 28 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -@@ -68,6 +68,7 @@ - #define DPNI_CMDID_CLR_FS_ENT DPNI_CMD(0x246) - - #define DPNI_CMDID_GET_STATISTICS DPNI_CMD(0x25D) -+#define DPNI_CMDID_RESET_STATISTICS DPNI_CMD(0x25E) - #define DPNI_CMDID_GET_QUEUE DPNI_CMD(0x25F) - #define DPNI_CMDID_SET_QUEUE DPNI_CMD(0x260) - #define DPNI_CMDID_GET_TAILDROP DPNI_CMD(0x261) ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c -@@ -1582,6 +1582,29 @@ int dpni_get_statistics(struct fsl_mc_io - } - - /** -+ * dpni_reset_statistics() - Clears DPNI statistics -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPNI object -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpni_reset_statistics(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** - * dpni_set_taildrop() - Set taildrop per queue or TC - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h -@@ -496,6 +496,10 @@ int dpni_get_statistics(struct fsl_mc_io - u8 page, - union dpni_statistics *stat); - -+int dpni_reset_statistics(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token); -+ - /** - * Enable auto-negotiation - */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0207-dpaa2-eth-Add-reset-controls-for-debugfs-stats.patch b/target/linux/layerscape/patches-5.4/701-net-0207-dpaa2-eth-Add-reset-controls-for-debugfs-stats.patch deleted file mode 100644 index 01d7b01c28..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0207-dpaa2-eth-Add-reset-controls-for-debugfs-stats.patch +++ /dev/null @@ -1,92 +0,0 @@ -From aa80ddbb30e9ffd75e2dcaa58abf6383a5520942 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 13 Feb 2019 12:23:41 +0200 -Subject: [PATCH] dpaa2-eth: Add reset controls for debugfs stats - -Allow the user to reset statistics counters through debugfs entries. - -Signed-off-by: Ioana Radulescu ---- - .../ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c | 64 ++++++++++++++++++++++ - 1 file changed, 64 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c -@@ -167,6 +167,62 @@ static const struct file_operations dpaa - .release = single_release, - }; - -+static ssize_t dpaa2_dbg_reset_write(struct file *file, const char __user *buf, -+ size_t count, loff_t *offset) -+{ -+ struct dpaa2_eth_priv *priv = file->private_data; -+ struct rtnl_link_stats64 *percpu_stats; -+ struct dpaa2_eth_drv_stats *percpu_extras; -+ struct dpaa2_eth_fq *fq; -+ struct dpaa2_eth_channel *ch; -+ int i; -+ -+ for_each_online_cpu(i) { -+ percpu_stats = per_cpu_ptr(priv->percpu_stats, i); -+ memset(percpu_stats, 0, sizeof(*percpu_stats)); -+ -+ percpu_extras = per_cpu_ptr(priv->percpu_extras, i); -+ memset(percpu_extras, 0, sizeof(*percpu_extras)); -+ } -+ -+ for (i = 0; i < priv->num_fqs; i++) { -+ fq = &priv->fq[i]; -+ memset(&fq->stats, 0, sizeof(fq->stats)); -+ } -+ -+ for (i = 0; i < priv->num_channels; i++) { -+ ch = priv->channel[i]; -+ memset(&ch->stats, 0, sizeof(ch->stats)); -+ } -+ -+ return count; -+} -+ -+static const struct file_operations dpaa2_dbg_reset_ops = { -+ .open = simple_open, -+ .write = dpaa2_dbg_reset_write, -+}; -+ -+static ssize_t dpaa2_dbg_reset_mc_write(struct file *file, -+ const char __user *buf, -+ size_t count, loff_t *offset) -+{ -+ struct dpaa2_eth_priv *priv = file->private_data; -+ int err; -+ -+ err = dpni_reset_statistics(priv->mc_io, 0, priv->mc_token); -+ if (err) -+ netdev_err(priv->net_dev, -+ "dpni_reset_statistics() failed %d\n", err); -+ -+ return count; -+} -+ -+static const struct file_operations dpaa2_dbg_reset_mc_ops = { -+ .open = simple_open, -+ .write = dpaa2_dbg_reset_mc_write, -+}; -+ - void dpaa2_dbg_add(struct dpaa2_eth_priv *priv) - { - struct dentry *dir; -@@ -183,6 +239,14 @@ void dpaa2_dbg_add(struct dpaa2_eth_priv - - /* per-fq stats file */ - debugfs_create_file("ch_stats", 0444, dir, priv, &dpaa2_dbg_ch_ops); -+ -+ /* reset stats */ -+ debugfs_create_file("reset_stats", 0200, dir, priv, -+ &dpaa2_dbg_reset_ops); -+ -+ /* reset MC stats */ -+ debugfs_create_file("reset_mc_stats", 0222, dir, priv, -+ &dpaa2_dbg_reset_mc_ops); - } - - void dpaa2_dbg_remove(struct dpaa2_eth_priv *priv) diff --git a/target/linux/layerscape/patches-5.4/701-net-0208-dpaa2-eth-Add-channel-stat.patch b/target/linux/layerscape/patches-5.4/701-net-0208-dpaa2-eth-Add-channel-stat.patch deleted file mode 100644 index 074078ec06..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0208-dpaa2-eth-Add-channel-stat.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 5a43b0405561fb6feffb7042493b58014ac27a4d Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Tue, 12 Feb 2019 22:05:16 +0200 -Subject: [PATCH] dpaa2-eth: Add channel stat - -Compute average number of frames processed for each CDAN -received on a channel and print it in the detailed channel -stats. - -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c | 8 +++++--- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 1 + - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 2 ++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 2 +- - 4 files changed, 9 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-debugfs.c -@@ -132,16 +132,18 @@ static int dpaa2_dbg_ch_show(struct seq_ - int i; - - seq_printf(file, "Channel stats for %s:\n", priv->net_dev->name); -- seq_printf(file, "%s%16s%16s%16s%16s\n", -- "CHID", "CPU", "Deq busy", "CDANs", "Buf count"); -+ seq_printf(file, "%s%16s%16s%16s%16s%16s%16s\n", -+ "CHID", "CPU", "Deq busy", "Frames", "CDANs", "Avg Frm/CDAN", "Buf count"); - - for (i = 0; i < priv->num_channels; i++) { - ch = priv->channel[i]; -- seq_printf(file, "%4d%16d%16llu%16llu%16d\n", -+ seq_printf(file, "%4d%16d%16llu%16llu%16llu%16llu%16d\n", - ch->ch_id, - ch->nctx.desired_cpu, - ch->stats.dequeue_portal_busy, -+ ch->stats.frames, - ch->stats.cdan, -+ ch->stats.frames / ch->stats.cdan, - ch->buf_count); - } - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -540,6 +540,7 @@ static int consume_frames(struct dpaa2_e - return 0; - - fq->stats.frames += cleaned; -+ ch->stats.frames += cleaned; - - /* A dequeue operation only pulls frames from a single queue - * into the store. Return the frame queue as an out param. ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -310,6 +310,8 @@ struct dpaa2_eth_ch_stats { - __u64 xdp_tx; - __u64 xdp_tx_err; - __u64 xdp_redirect; -+ /* Must be last, does not show up in ethtool stats */ -+ __u64 frames; - }; - - /* Maximum number of queues associated with a DPNI */ ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -@@ -234,7 +234,7 @@ static void dpaa2_eth_get_ethtool_stats( - /* Per-channel stats */ - for (k = 0; k < priv->num_channels; k++) { - ch_stats = &priv->channel[k]->stats; -- for (j = 0; j < sizeof(*ch_stats) / sizeof(__u64); j++) -+ for (j = 0; j < sizeof(*ch_stats) / sizeof(__u64) - 1; j++) - *((__u64 *)data + i + j) += *((__u64 *)ch_stats + j); - } - i += j; diff --git a/target/linux/layerscape/patches-5.4/701-net-0209-dpaa2-eth-Update-dpni_set_tx_shaping-cmd-to-v2.patch b/target/linux/layerscape/patches-5.4/701-net-0209-dpaa2-eth-Update-dpni_set_tx_shaping-cmd-to-v2.patch deleted file mode 100644 index bb80578cdd..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0209-dpaa2-eth-Update-dpni_set_tx_shaping-cmd-to-v2.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 81efe5fd6fac6db454ccccb1e6c280419d0885c4 Mon Sep 17 00:00:00 2001 -From: Bogdan Purcareata -Date: Mon, 13 Nov 2017 17:29:21 +0200 -Subject: [PATCH] dpaa2-eth: Update dpni_set_tx_shaping cmd to v2 - -Support dual rate shaping (committed, excess) and the coupled parameter. - -Signed-off-by: Bogdan Purcareata ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 5 +++-- - drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 18 ++++++++++++++---- - drivers/net/ethernet/freescale/dpaa2/dpni.c | 23 ++++++++++++++++------- - drivers/net/ethernet/freescale/dpaa2/dpni.h | 10 ++++++---- - 4 files changed, 39 insertions(+), 17 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -3895,7 +3895,7 @@ static ssize_t dpaa2_eth_write_tx_shapin - { - int err, items; - struct dpaa2_eth_priv *priv = netdev_priv(to_net_dev(dev)); -- struct dpni_tx_shaping_cfg scfg; -+ struct dpni_tx_shaping_cfg scfg, ercfg = {0}; - - items = sscanf(buf, "%u %hu", &scfg.rate_limit, &scfg.max_burst_size); - if (items != 2) { -@@ -3909,7 +3909,8 @@ static ssize_t dpaa2_eth_write_tx_shapin - return -EINVAL; - } - -- err = dpni_set_tx_shaping(priv->mc_io, 0, priv->mc_token, &scfg); -+ err = dpni_set_tx_shaping(priv->mc_io, 0, priv->mc_token, &scfg, -+ &ercfg, 0); - if (err) { - dev_err(dev, "dpni_set_tx_shaping() failed\n"); - return -EPERM; ---- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -@@ -11,9 +11,11 @@ - #define DPNI_VER_MAJOR 7 - #define DPNI_VER_MINOR 0 - #define DPNI_CMD_BASE_VERSION 1 -+#define DPNI_CMD_2ND_VERSION 2 - #define DPNI_CMD_ID_OFFSET 4 - - #define DPNI_CMD(id) (((id) << DPNI_CMD_ID_OFFSET) | DPNI_CMD_BASE_VERSION) -+#define DPNI_CMD_V2(id) (((id) << DPNI_CMD_ID_OFFSET) | DPNI_CMD_2ND_VERSION) - - #define DPNI_CMDID_OPEN DPNI_CMD(0x801) - #define DPNI_CMDID_CLOSE DPNI_CMD(0x800) -@@ -45,7 +47,7 @@ - #define DPNI_CMDID_SET_MAX_FRAME_LENGTH DPNI_CMD(0x216) - #define DPNI_CMDID_GET_MAX_FRAME_LENGTH DPNI_CMD(0x217) - #define DPNI_CMDID_SET_LINK_CFG DPNI_CMD(0x21A) --#define DPNI_CMDID_SET_TX_SHAPING DPNI_CMD(0x21B) -+#define DPNI_CMDID_SET_TX_SHAPING DPNI_CMD_V2(0x21B) - - #define DPNI_CMDID_SET_MCAST_PROMISC DPNI_CMD(0x220) - #define DPNI_CMDID_GET_MCAST_PROMISC DPNI_CMD(0x221) -@@ -316,12 +318,20 @@ struct dpni_rsp_get_link_state { - __le64 options; - }; - -+#define DPNI_COUPLED_SHIFT 0 -+#define DPNI_COUPLED_SIZE 1 -+ - struct dpni_cmd_set_tx_shaping { - /* cmd word 0 */ -- __le16 max_burst_size; -- __le16 pad[3]; -+ __le16 tx_cr_max_burst_size; -+ __le16 tx_er_max_burst_size; -+ __le32 pad; - /* cmd word 1 */ -- __le32 rate_limit; -+ __le32 tx_cr_rate_limit; -+ __le32 tx_er_rate_limit; -+ /* cmd word 2 */ -+ /* from LSB: coupled:1 */ -+ u8 coupled; - }; - - struct dpni_cmd_set_max_frame_length { ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c -@@ -927,17 +927,21 @@ int dpni_get_link_state(struct fsl_mc_io - - /** - * dpni_set_tx_shaping() - Set the transmit shaping -- * @mc_io: Pointer to MC portal's I/O object -- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -- * @token: Token of DPNI object -- * @tx_shaper: Tx shaping configuration -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPNI object -+ * @tx_cr_shaper: TX committed rate shaping configuration -+ * @tx_er_shaper: TX excess rate shaping configuration -+ * @coupled: Committed and excess rate shapers are coupled - * - * Return: '0' on Success; Error code otherwise. - */ - int dpni_set_tx_shaping(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, -- const struct dpni_tx_shaping_cfg *tx_shaper) -+ const struct dpni_tx_shaping_cfg *tx_cr_shaper, -+ const struct dpni_tx_shaping_cfg *tx_er_shaper, -+ int coupled) - { - struct fsl_mc_command cmd = { 0 }; - struct dpni_cmd_set_tx_shaping *cmd_params; -@@ -947,8 +951,13 @@ int dpni_set_tx_shaping(struct fsl_mc_io - cmd_flags, - token); - cmd_params = (struct dpni_cmd_set_tx_shaping *)cmd.params; -- cmd_params->max_burst_size = cpu_to_le16(tx_shaper->max_burst_size); -- cmd_params->rate_limit = cpu_to_le32(tx_shaper->rate_limit); -+ cmd_params->tx_cr_max_burst_size = -+ cpu_to_le16(tx_cr_shaper->max_burst_size); -+ cmd_params->tx_er_max_burst_size = -+ cpu_to_le16(tx_er_shaper->max_burst_size); -+ cmd_params->tx_cr_rate_limit = cpu_to_le32(tx_cr_shaper->rate_limit); -+ cmd_params->tx_er_rate_limit = cpu_to_le32(tx_er_shaper->rate_limit); -+ dpni_set_field(cmd_params->coupled, COUPLED, coupled); - - /* send command to mc*/ - return mc_send_command(mc_io, &cmd); ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h -@@ -569,10 +569,12 @@ struct dpni_tx_shaping_cfg { - u16 max_burst_size; - }; - --int dpni_set_tx_shaping(struct fsl_mc_io *mc_io, -- u32 cmd_flags, -- u16 token, -- const struct dpni_tx_shaping_cfg *tx_shaper); -+int dpni_set_tx_shaping(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_tx_shaping_cfg *tx_cr_shaper, -+ const struct dpni_tx_shaping_cfg *tx_er_shaper, -+ int coupled); - - int dpni_set_max_frame_length(struct fsl_mc_io *mc_io, - u32 cmd_flags, diff --git a/target/linux/layerscape/patches-5.4/701-net-0210-dpaa2-eth-Add-dpni_set_tx_priorities-API.patch b/target/linux/layerscape/patches-5.4/701-net-0210-dpaa2-eth-Add-dpni_set_tx_priorities-API.patch deleted file mode 100644 index 4ce16b6fd9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0210-dpaa2-eth-Add-dpni_set_tx_priorities-API.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 97308e74e2ae781d37437137686965395b94327b Mon Sep 17 00:00:00 2001 -From: Bogdan Purcareata -Date: Mon, 16 Oct 2017 15:27:55 +0000 -Subject: [PATCH] dpaa2-eth: Add dpni_set_tx_priorities API - -Signed-off-by: Bogdan Purcareata ---- - drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 19 ++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.c | 49 +++++++++++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.h | 44 ++++++++++++++++++++++ - 3 files changed, 112 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -@@ -69,6 +69,7 @@ - #define DPNI_CMDID_REMOVE_FS_ENT DPNI_CMD(0x245) - #define DPNI_CMDID_CLR_FS_ENT DPNI_CMD(0x246) - -+#define DPNI_CMDID_SET_TX_PRIORITIES DPNI_CMD_V2(0x250) - #define DPNI_CMDID_GET_STATISTICS DPNI_CMD(0x25D) - #define DPNI_CMDID_RESET_STATISTICS DPNI_CMD(0x25E) - #define DPNI_CMDID_GET_QUEUE DPNI_CMD(0x25F) -@@ -393,6 +394,24 @@ struct dpni_cmd_clear_mac_filters { - u8 flags; - }; - -+#define DPNI_SEPARATE_GRP_SHIFT 0 -+#define DPNI_SEPARATE_GRP_SIZE 1 -+#define DPNI_MODE_1_SHIFT 0 -+#define DPNI_MODE_1_SIZE 4 -+#define DPNI_MODE_2_SHIFT 4 -+#define DPNI_MODE_2_SIZE 4 -+ -+struct dpni_cmd_set_tx_priorities { -+ __le16 flags; -+ u8 prio_group_A; -+ u8 prio_group_B; -+ __le32 pad0; -+ u8 modes[4]; -+ __le32 pad1; -+ __le64 pad2; -+ __le16 delta_bandwidth[8]; -+}; -+ - #define DPNI_DIST_MODE_SHIFT 0 - #define DPNI_DIST_MODE_SIZE 4 - #define DPNI_MISS_ACTION_SHIFT 4 ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c -@@ -1355,6 +1355,55 @@ int dpni_clear_mac_filters(struct fsl_mc - } - - /** -+ * dpni_set_tx_priorities() - Set transmission TC priority configuration -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPNI object -+ * @cfg: Transmission selection configuration -+ * -+ * warning: Allowed only when DPNI is disabled -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpni_set_tx_priorities(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_tx_priorities_cfg *cfg) -+{ -+ struct dpni_cmd_set_tx_priorities *cmd_params; -+ struct fsl_mc_command cmd = { 0 }; -+ int i; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_PRIORITIES, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpni_cmd_set_tx_priorities *)cmd.params; -+ dpni_set_field(cmd_params->flags, -+ SEPARATE_GRP, -+ cfg->separate_groups); -+ cmd_params->prio_group_A = cfg->prio_group_A; -+ cmd_params->prio_group_B = cfg->prio_group_B; -+ -+ for (i = 0; i + 1 < DPNI_MAX_TC; i += 2) { -+ dpni_set_field(cmd_params->modes[i / 2], -+ MODE_1, -+ cfg->tc_sched[i].mode); -+ dpni_set_field(cmd_params->modes[i / 2], -+ MODE_2, -+ cfg->tc_sched[i + 1].mode); -+ } -+ -+ for (i = 0; i < DPNI_MAX_TC; i++) { -+ cmd_params->delta_bandwidth[i] = -+ cpu_to_le16(cfg->tc_sched[i].delta_bandwidth); -+ } -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** - * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h -@@ -677,6 +677,50 @@ int dpni_prepare_key_cfg(const struct dp - u8 *key_cfg_buf); - - /** -+ * enum dpni_tx_schedule_mode - DPNI Tx scheduling mode -+ * @DPNI_TX_SCHED_STRICT_PRIORITY: strict priority -+ * @DPNI_TX_SCHED_WEIGHTED_A: weighted based scheduling in group A -+ * @DPNI_TX_SCHED_WEIGHTED_B: weighted based scheduling in group B -+ */ -+enum dpni_tx_schedule_mode { -+ DPNI_TX_SCHED_STRICT_PRIORITY = 0, -+ DPNI_TX_SCHED_WEIGHTED_A, -+ DPNI_TX_SCHED_WEIGHTED_B, -+}; -+ -+/** -+ * struct dpni_tx_schedule_cfg - Structure representing Tx scheduling conf -+ * @mode: Scheduling mode -+ * @delta_bandwidth: Bandwidth represented in weights from 100 to 10000; -+ * not applicable for 'strict-priority' mode; -+ */ -+struct dpni_tx_schedule_cfg { -+ enum dpni_tx_schedule_mode mode; -+ u16 delta_bandwidth; -+}; -+ -+/** -+ * struct dpni_tx_priorities_cfg - Structure representing transmission -+ * priorities for DPNI TCs -+ * @tc_sched: An array of traffic-classes -+ * @prio_group_A: Priority of group A -+ * @prio_group_B: Priority of group B -+ * @separate_groups: Treat A and B groups as separate -+ * @ceetm_ch_idx: ceetm channel index to apply the changes -+ */ -+struct dpni_tx_priorities_cfg { -+ struct dpni_tx_schedule_cfg tc_sched[DPNI_MAX_TC]; -+ u8 prio_group_A; -+ u8 prio_group_B; -+ u8 separate_groups; -+}; -+ -+int dpni_set_tx_priorities(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_tx_priorities_cfg *cfg); -+ -+/** - * struct dpni_rx_tc_dist_cfg - Rx traffic class distribution configuration - * @dist_size: Set the distribution size; - * supported values: 1,2,3,4,6,7,8,12,14,16,24,28,32,48,56,64,96, diff --git a/target/linux/layerscape/patches-5.4/701-net-0211-dpaa2-eth-Update-dpni_get_statistics.patch b/target/linux/layerscape/patches-5.4/701-net-0211-dpaa2-eth-Update-dpni_get_statistics.patch deleted file mode 100644 index f04674affb..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0211-dpaa2-eth-Update-dpni_get_statistics.patch +++ /dev/null @@ -1,95 +0,0 @@ -From fa4e59c0fe5e6e2fd8ba29cdcaa03988b3d301c6 Mon Sep 17 00:00:00 2001 -From: Bogdan Purcareata -Date: Mon, 23 Oct 2017 08:31:25 +0000 -Subject: [PATCH] dpaa2-eth: Update dpni_get_statistics - -Statistics struct now contains an addditional page, with CEETM stats. -Also update the cmd version, and the call where it's used. - -Signed-off-by: Bogdan Purcareata ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 2 +- - drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 2 +- - drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 3 ++- - drivers/net/ethernet/freescale/dpaa2/dpni.c | 4 ++++ - drivers/net/ethernet/freescale/dpaa2/dpni.h | 1 + - 5 files changed, 9 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -1479,7 +1479,7 @@ static void wait_for_egress_fq_empty(str - goto out; - - do { -- err = dpni_get_statistics(priv->mc_io, 0, priv->mc_token, 6, -+ err = dpni_get_statistics(priv->mc_io, 0, priv->mc_token, 6, 0, - &stats); - if (err) - goto out; ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -@@ -211,7 +211,7 @@ static void dpaa2_eth_get_ethtool_stats( - if (j == 4 || j == 5) - continue; - err = dpni_get_statistics(priv->mc_io, 0, priv->mc_token, -- j, &dpni_stats); -+ j, 0, &dpni_stats); - if (err == -EINVAL) - /* Older firmware versions don't support all pages */ - memset(&dpni_stats, 0, sizeof(dpni_stats)); ---- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -@@ -70,7 +70,7 @@ - #define DPNI_CMDID_CLR_FS_ENT DPNI_CMD(0x246) - - #define DPNI_CMDID_SET_TX_PRIORITIES DPNI_CMD_V2(0x250) --#define DPNI_CMDID_GET_STATISTICS DPNI_CMD(0x25D) -+#define DPNI_CMDID_GET_STATISTICS DPNI_CMD_V2(0x25D) - #define DPNI_CMDID_RESET_STATISTICS DPNI_CMD(0x25E) - #define DPNI_CMDID_GET_QUEUE DPNI_CMD(0x25F) - #define DPNI_CMDID_SET_QUEUE DPNI_CMD(0x260) -@@ -287,6 +287,7 @@ struct dpni_rsp_get_tx_data_offset { - - struct dpni_cmd_get_statistics { - u8 page_number; -+ u8 param; - }; - - struct dpni_rsp_get_statistics { ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c -@@ -1604,6 +1604,8 @@ int dpni_get_queue(struct fsl_mc_io *mc_ - * @token: Token of DPNI object - * @page: Selects the statistics page to retrieve, see - * DPNI_GET_STATISTICS output. Pages are numbered 0 to 6. -+ * @param: Custom parameter for some pages used to select a certain -+ * statistic source, for example the TC. - * @stat: Structure containing the statistics - * - * Return: '0' on Success; Error code otherwise. -@@ -1612,6 +1614,7 @@ int dpni_get_statistics(struct fsl_mc_io - u32 cmd_flags, - u16 token, - u8 page, -+ u8 param, - union dpni_statistics *stat) - { - struct fsl_mc_command cmd = { 0 }; -@@ -1625,6 +1628,7 @@ int dpni_get_statistics(struct fsl_mc_io - token); - cmd_params = (struct dpni_cmd_get_statistics *)cmd.params; - cmd_params->page_number = page; -+ cmd_params->param = param; - - /* send command to mc */ - err = mc_send_command(mc_io, &cmd); ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h -@@ -494,6 +494,7 @@ int dpni_get_statistics(struct fsl_mc_io - u32 cmd_flags, - u16 token, - u8 page, -+ u8 param, - union dpni_statistics *stat); - - int dpni_reset_statistics(struct fsl_mc_io *mc_io, diff --git a/target/linux/layerscape/patches-5.4/701-net-0212-dpaa2-eth-Add-API-for-ceetm_id-tc-in-set-congestion.patch b/target/linux/layerscape/patches-5.4/701-net-0212-dpaa2-eth-Add-API-for-ceetm_id-tc-in-set-congestion.patch deleted file mode 100644 index 719f4c06b2..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0212-dpaa2-eth-Add-API-for-ceetm_id-tc-in-set-congestion.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 551cd6add98fb3bde24ee8e4ffa76aec9fd9d40c Mon Sep 17 00:00:00 2001 -From: Bogdan Purcareata -Date: Mon, 2 Oct 2017 14:45:56 +0000 -Subject: [PATCH] dpaa2-eth: Add API for ceetm_id + tc in set congestion - -Signed-off-by: Bogdan Purcareata ---- - drivers/net/ethernet/freescale/dpaa2/dpni.c | 15 ++++++++++++--- - drivers/net/ethernet/freescale/dpaa2/dpni.h | 6 ++++++ - 2 files changed, 18 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c -@@ -1448,7 +1448,10 @@ int dpni_set_rx_tc_dist(struct fsl_mc_io - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPNI object - * @qtype: Type of queue - Rx, Tx and Tx confirm types are supported -- * @tc_id: Traffic class selection (0-7) -+ * @tc_id: bits 7-4 contain ceetm channel index (valid only for TX); -+ * bits 3-0 contain traffic class. -+ * Use macro DPNI_BUILD_CH_TC() to build correct value for -+ * tc_id parameter - * @cfg: Congestion notification configuration - * - * Return: '0' on Success; error code otherwise. -@@ -1674,7 +1677,10 @@ int dpni_reset_statistics(struct fsl_mc_ - * @cg_point: Congestion point - * @q_type: Queue type on which the taildrop is configured. - * Only Rx queues are supported for now -- * @tc: Traffic class to apply this taildrop to -+ * @tc: bits 7-4 contain ceetm channel index (valid only for TX); -+ * bits 3-0 contain traffic class. -+ * Use macro DPNI_BUILD_CH_TC() to build correct value for -+ * tc parameter. - * @q_index: Index of the queue if the DPNI supports multiple queues for - * traffic distribution. Ignored if CONGESTION_POINT is not 0. - * @taildrop: Taildrop structure -@@ -1718,7 +1724,10 @@ int dpni_set_taildrop(struct fsl_mc_io * - * @cg_point: Congestion point - * @q_type: Queue type on which the taildrop is configured. - * Only Rx queues are supported for now -- * @tc: Traffic class to apply this taildrop to -+ * @tc: bits 7-4 contain ceetm channel index (valid only for TX); -+ * bits 3-0 contain traffic class. -+ * Use macro DPNI_BUILD_CH_TC() to build correct value for -+ * tc parameter. - * @q_index: Index of the queue if the DPNI supports multiple queues for - * traffic distribution. Ignored if CONGESTION_POINT is not 0. - * @taildrop: Taildrop structure ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h -@@ -996,6 +996,12 @@ struct dpni_congestion_notification_cfg - u16 notification_mode; - }; - -+/** Compose TC parameter for function dpni_set_congestion_notification() -+ * and dpni_get_congestion_notification(). -+ */ -+#define DPNI_BUILD_CH_TC(ceetm_ch_idx, tc) \ -+ ((((ceetm_ch_idx) & 0x0F) << 4) | ((tc) & 0x0F)) -+ - int dpni_set_congestion_notification( - struct fsl_mc_io *mc_io, - u32 cmd_flags, diff --git a/target/linux/layerscape/patches-5.4/701-net-0213-dpaa2-eth-Add-CEETM-qdisc-support.patch b/target/linux/layerscape/patches-5.4/701-net-0213-dpaa2-eth-Add-CEETM-qdisc-support.patch deleted file mode 100644 index ca06007dfe..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0213-dpaa2-eth-Add-CEETM-qdisc-support.patch +++ /dev/null @@ -1,1619 +0,0 @@ -From 68622c8bb029f9fd4c83ffa3bd979fa62a3599d0 Mon Sep 17 00:00:00 2001 -From: Bogdan Purcareata -Date: Mon, 13 Nov 2017 17:26:13 +0200 -Subject: [PATCH] dpaa2-eth: Add CEETM qdisc support - -Features include: -- dual rate shaping support -- per-channel shaping and classification -- strict / weighted scheduling among num_tc classes -- TD enabled for configured class queues -- prio class (leaf) firmware statistics support -- weights normalized based on max -- tc filters based classification - -Only 1 CEETM ch supported, only channel shaping supported. - -Signed-off-by: Bogdan Purcareata -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/dpaa2/Kconfig | 7 + - drivers/net/ethernet/freescale/dpaa2/Makefile | 1 + - .../net/ethernet/freescale/dpaa2/dpaa2-eth-ceetm.c | 1219 ++++++++++++++++++++ - .../net/ethernet/freescale/dpaa2/dpaa2-eth-ceetm.h | 207 ++++ - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 53 +- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 7 + - 6 files changed, 1482 insertions(+), 12 deletions(-) - create mode 100644 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-ceetm.c - create mode 100644 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-ceetm.h - ---- a/drivers/net/ethernet/freescale/dpaa2/Kconfig -+++ b/drivers/net/ethernet/freescale/dpaa2/Kconfig -@@ -25,6 +25,13 @@ config FSL_DPAA2_ETH_USE_ERR_QUEUE - in hardware). - This may impact performance, recommended for debugging - purposes only. -+ -+config FSL_DPAA2_ETH_CEETM -+ depends on NET_SCHED -+ bool "DPAA2 Ethernet CEETM QoS" -+ default n -+ help -+ Enable QoS offloading support through the CEETM hardware block. - endif - - config FSL_DPAA2_PTP_CLOCK ---- a/drivers/net/ethernet/freescale/dpaa2/Makefile -+++ b/drivers/net/ethernet/freescale/dpaa2/Makefile -@@ -8,6 +8,7 @@ obj-$(CONFIG_FSL_DPAA2_PTP_CLOCK) += fsl - - fsl-dpaa2-eth-objs := dpaa2-eth.o dpaa2-ethtool.o dpni.o - fsl-dpaa2-eth-${CONFIG_DEBUG_FS} += dpaa2-eth-debugfs.o -+fsl-dpaa2-eth-${CONFIG_FSL_DPAA2_ETH_CEETM} += dpaa2-eth-ceetm.o - fsl-dpaa2-ptp-objs := dpaa2-ptp.o dprtc.o - - # Needed by the tracing framework ---- /dev/null -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-ceetm.c -@@ -0,0 +1,1219 @@ -+/* Copyright 2017 NXP -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include -+#include -+ -+#include "dpaa2-eth-ceetm.h" -+#include "dpaa2-eth.h" -+ -+#define DPAA2_CEETM_DESCRIPTION "FSL DPAA2 CEETM qdisc" -+/* Conversion formula from userspace passed Bps to expected Mbit */ -+#define dpaa2_eth_bps_to_mbit(rate) (rate >> 17) -+ -+static const struct nla_policy dpaa2_ceetm_policy[DPAA2_CEETM_TCA_MAX] = { -+ [DPAA2_CEETM_TCA_COPT] = { .len = sizeof(struct dpaa2_ceetm_tc_copt) }, -+ [DPAA2_CEETM_TCA_QOPS] = { .len = sizeof(struct dpaa2_ceetm_tc_qopt) }, -+}; -+ -+struct Qdisc_ops dpaa2_ceetm_qdisc_ops; -+ -+static inline int dpaa2_eth_set_ch_shaping(struct dpaa2_eth_priv *priv, -+ struct dpni_tx_shaping_cfg *scfg, -+ struct dpni_tx_shaping_cfg *ecfg, -+ int coupled, int ch_id) -+{ -+ int err = 0; -+ -+ netdev_dbg(priv->net_dev, "%s: ch_id %d rate %d mbps\n", __func__, -+ ch_id, scfg->rate_limit); -+ err = dpni_set_tx_shaping(priv->mc_io, 0, priv->mc_token, scfg, -+ ecfg, coupled); -+ if (err) -+ netdev_err(priv->net_dev, "dpni_set_tx_shaping err\n"); -+ -+ return err; -+} -+ -+static inline int dpaa2_eth_reset_ch_shaping(struct dpaa2_eth_priv *priv, -+ int ch_id) -+{ -+ struct dpni_tx_shaping_cfg cfg = { 0 }; -+ -+ return dpaa2_eth_set_ch_shaping(priv, &cfg, &cfg, 0, ch_id); -+} -+ -+static inline int -+dpaa2_eth_update_shaping_cfg(struct net_device *dev, -+ struct dpaa2_ceetm_shaping_cfg cfg, -+ struct dpni_tx_shaping_cfg *scfg, -+ struct dpni_tx_shaping_cfg *ecfg) -+{ -+ scfg->rate_limit = dpaa2_eth_bps_to_mbit(cfg.cir); -+ ecfg->rate_limit = dpaa2_eth_bps_to_mbit(cfg.eir); -+ -+ if (cfg.cbs > DPAA2_ETH_MAX_BURST_SIZE) { -+ netdev_err(dev, "Committed burst size must be under %d\n", -+ DPAA2_ETH_MAX_BURST_SIZE); -+ return -EINVAL; -+ } -+ -+ scfg->max_burst_size = cfg.cbs; -+ -+ if (cfg.ebs > DPAA2_ETH_MAX_BURST_SIZE) { -+ netdev_err(dev, "Excess burst size must be under %d\n", -+ DPAA2_ETH_MAX_BURST_SIZE); -+ return -EINVAL; -+ } -+ -+ ecfg->max_burst_size = cfg.ebs; -+ -+ if ((!cfg.cir || !cfg.eir) && cfg.coupled) { -+ netdev_err(dev, "Coupling can be set when both CIR and EIR are finite\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+enum update_tx_prio { -+ DPAA2_ETH_ADD_CQ, -+ DPAA2_ETH_DEL_CQ, -+}; -+ -+/* Normalize weights based on max passed value */ -+static inline int dpaa2_eth_normalize_tx_prio(struct dpaa2_ceetm_qdisc *priv) -+{ -+ struct dpni_tx_schedule_cfg *sched_cfg; -+ struct dpaa2_ceetm_class *cl; -+ u32 qpri; -+ u16 weight_max = 0, increment; -+ int i; -+ -+ /* Check the boundaries of the provided values */ -+ for (i = 0; i < priv->clhash.hashsize; i++) -+ hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) -+ weight_max = (weight_max == 0 ? cl->prio.weight : -+ (weight_max < cl->prio.weight ? -+ cl->prio.weight : weight_max)); -+ -+ /* If there are no elements, there's nothing to do */ -+ if (weight_max == 0) -+ return 0; -+ -+ increment = (DPAA2_CEETM_MAX_WEIGHT - DPAA2_CEETM_MIN_WEIGHT) / -+ weight_max; -+ -+ for (i = 0; i < priv->clhash.hashsize; i++) { -+ hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) { -+ if (cl->prio.mode == STRICT_PRIORITY) -+ continue; -+ -+ qpri = cl->prio.qpri; -+ sched_cfg = &priv->prio.tx_prio_cfg.tc_sched[qpri]; -+ -+ sched_cfg->delta_bandwidth = -+ DPAA2_CEETM_MIN_WEIGHT + -+ (cl->prio.weight * increment); -+ -+ pr_debug("%s: Normalized CQ qpri %d weight to %d\n", -+ __func__, qpri, sched_cfg->delta_bandwidth); -+ } -+ } -+ -+ return 0; -+} -+ -+static inline int dpaa2_eth_update_tx_prio(struct dpaa2_eth_priv *priv, -+ struct dpaa2_ceetm_class *cl, -+ enum update_tx_prio type) -+{ -+ struct dpaa2_ceetm_qdisc *sch = qdisc_priv(cl->parent); -+ struct dpni_tx_schedule_cfg *sched_cfg; -+ struct dpni_taildrop td = {0}; -+ u8 ch_id = 0, tc_id = 0; -+ u32 qpri = 0; -+ int err = 0; -+ -+ qpri = cl->prio.qpri; -+ tc_id = DPNI_BUILD_CH_TC(ch_id, qpri); -+ -+ switch (type) { -+ case DPAA2_ETH_ADD_CQ: -+ /* Enable taildrop */ -+ td.enable = 1; -+ td.units = DPNI_CONGESTION_UNIT_FRAMES; -+ td.threshold = DPAA2_CEETM_TD_THRESHOLD; -+ err = dpni_set_taildrop(priv->mc_io, 0, priv->mc_token, -+ DPNI_CP_GROUP, DPNI_QUEUE_TX, tc_id, -+ 0, &td); -+ if (err) { -+ netdev_err(priv->net_dev, "Error enabling Tx taildrop %d\n", -+ err); -+ return err; -+ } -+ break; -+ case DPAA2_ETH_DEL_CQ: -+ /* Disable taildrop */ -+ td.enable = 0; -+ err = dpni_set_taildrop(priv->mc_io, 0, priv->mc_token, -+ DPNI_CP_GROUP, DPNI_QUEUE_TX, tc_id, -+ 0, &td); -+ if (err) { -+ netdev_err(priv->net_dev, "Error disabling Tx taildrop %d\n", -+ err); -+ return err; -+ } -+ break; -+ } -+ -+ /* We can zero out the structure in the tx_prio_conf array */ -+ if (type == DPAA2_ETH_DEL_CQ) { -+ sched_cfg = &sch->prio.tx_prio_cfg.tc_sched[qpri]; -+ memset(sched_cfg, 0, sizeof(*sched_cfg)); -+ } -+ -+ /* Normalize priorities */ -+ err = dpaa2_eth_normalize_tx_prio(sch); -+ -+ /* Debug print goes here */ -+ print_hex_dump_debug("tx_prio: ", DUMP_PREFIX_OFFSET, 16, 1, -+ &sch->prio.tx_prio_cfg, -+ sizeof(sch->prio.tx_prio_cfg), 0); -+ -+ /* Call dpni_set_tx_priorities for the entire prio qdisc */ -+ err = dpni_set_tx_priorities(priv->mc_io, 0, priv->mc_token, -+ &sch->prio.tx_prio_cfg); -+ if (err) -+ netdev_err(priv->net_dev, "dpni_set_tx_priorities err %d\n", -+ err); -+ -+ return err; -+} -+ -+static void dpaa2_eth_ceetm_enable(struct dpaa2_eth_priv *priv) -+{ -+ priv->ceetm_en = true; -+} -+ -+static void dpaa2_eth_ceetm_disable(struct dpaa2_eth_priv *priv) -+{ -+ priv->ceetm_en = false; -+} -+ -+/* Find class in qdisc hash table using given handle */ -+static inline struct dpaa2_ceetm_class *dpaa2_ceetm_find(u32 handle, -+ struct Qdisc *sch) -+{ -+ struct dpaa2_ceetm_qdisc *priv = qdisc_priv(sch); -+ struct Qdisc_class_common *clc; -+ -+ pr_debug(KBUILD_BASENAME " : %s : find class %X in qdisc %X\n", -+ __func__, handle, sch->handle); -+ -+ clc = qdisc_class_find(&priv->clhash, handle); -+ return clc ? container_of(clc, struct dpaa2_ceetm_class, common) : NULL; -+} -+ -+/* Insert a class in the qdisc's class hash */ -+static void dpaa2_ceetm_link_class(struct Qdisc *sch, -+ struct Qdisc_class_hash *clhash, -+ struct Qdisc_class_common *common) -+{ -+ sch_tree_lock(sch); -+ qdisc_class_hash_insert(clhash, common); -+ sch_tree_unlock(sch); -+ qdisc_class_hash_grow(sch, clhash); -+} -+ -+/* Destroy a ceetm class */ -+static void dpaa2_ceetm_cls_destroy(struct Qdisc *sch, -+ struct dpaa2_ceetm_class *cl) -+{ -+ struct net_device *dev = qdisc_dev(sch); -+ struct dpaa2_eth_priv *priv = netdev_priv(dev); -+ -+ if (!cl) -+ return; -+ -+ pr_debug(KBUILD_BASENAME " : %s : destroy class %X from under %X\n", -+ __func__, cl->common.classid, sch->handle); -+ -+ /* Recurse into child first */ -+ if (cl->child) { -+ qdisc_put(cl->child); -+ cl->child = NULL; -+ } -+ -+ switch (cl->type) { -+ case CEETM_ROOT: -+ if (dpaa2_eth_reset_ch_shaping(priv, cl->root.ch_id)) -+ netdev_err(dev, "Error resetting channel shaping\n"); -+ -+ break; -+ -+ case CEETM_PRIO: -+ if (dpaa2_eth_update_tx_prio(priv, cl, DPAA2_ETH_DEL_CQ)) -+ netdev_err(dev, "Error resetting tx_priorities\n"); -+ -+ if (cl->prio.cstats) -+ free_percpu(cl->prio.cstats); -+ -+ break; -+ } -+ -+ tcf_block_put(cl->block); -+ kfree(cl); -+} -+ -+/* Destroy a ceetm qdisc */ -+static void dpaa2_ceetm_destroy(struct Qdisc *sch) -+{ -+ unsigned int i; -+ struct hlist_node *next; -+ struct dpaa2_ceetm_class *cl; -+ struct dpaa2_ceetm_qdisc *priv = qdisc_priv(sch); -+ struct net_device *dev = qdisc_dev(sch); -+ struct dpaa2_eth_priv *priv_eth = netdev_priv(dev); -+ -+ pr_debug(KBUILD_BASENAME " : %s : destroy qdisc %X\n", -+ __func__, sch->handle); -+ -+ /* All filters need to be removed before destroying the classes */ -+ tcf_block_put(priv->block); -+ -+ for (i = 0; i < priv->clhash.hashsize; i++) { -+ hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) -+ tcf_block_put(cl->block); -+ } -+ -+ for (i = 0; i < priv->clhash.hashsize; i++) { -+ hlist_for_each_entry_safe(cl, next, &priv->clhash.hash[i], -+ common.hnode) -+ dpaa2_ceetm_cls_destroy(sch, cl); -+ } -+ -+ qdisc_class_hash_destroy(&priv->clhash); -+ -+ switch (priv->type) { -+ case CEETM_ROOT: -+ dpaa2_eth_ceetm_disable(priv_eth); -+ -+ if (priv->root.qstats) -+ free_percpu(priv->root.qstats); -+ -+ if (!priv->root.qdiscs) -+ break; -+ -+ /* Destroy the pfifo qdiscs in case they haven't been attached -+ * to the netdev queues yet. -+ */ -+ for (i = 0; i < dev->num_tx_queues; i++) -+ if (priv->root.qdiscs[i]) -+ qdisc_put(priv->root.qdiscs[i]); -+ -+ kfree(priv->root.qdiscs); -+ break; -+ -+ case CEETM_PRIO: -+ if (priv->prio.parent) -+ priv->prio.parent->child = NULL; -+ break; -+ } -+} -+ -+static int dpaa2_ceetm_dump(struct Qdisc *sch, struct sk_buff *skb) -+{ -+ struct Qdisc *qdisc; -+ unsigned int ntx, i; -+ struct nlattr *nest; -+ struct dpaa2_ceetm_tc_qopt qopt; -+ struct dpaa2_ceetm_qdisc_stats *qstats; -+ struct net_device *dev = qdisc_dev(sch); -+ struct dpaa2_ceetm_qdisc *priv = qdisc_priv(sch); -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ sch_tree_lock(sch); -+ memset(&qopt, 0, sizeof(qopt)); -+ qopt.type = priv->type; -+ qopt.shaped = priv->shaped; -+ -+ switch (priv->type) { -+ case CEETM_ROOT: -+ /* Gather statistics from the underlying pfifo qdiscs */ -+ sch->q.qlen = 0; -+ memset(&sch->bstats, 0, sizeof(sch->bstats)); -+ memset(&sch->qstats, 0, sizeof(sch->qstats)); -+ -+ for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { -+ qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping; -+ sch->q.qlen += qdisc->q.qlen; -+ sch->bstats.bytes += qdisc->bstats.bytes; -+ sch->bstats.packets += qdisc->bstats.packets; -+ sch->qstats.qlen += qdisc->qstats.qlen; -+ sch->qstats.backlog += qdisc->qstats.backlog; -+ sch->qstats.drops += qdisc->qstats.drops; -+ sch->qstats.requeues += qdisc->qstats.requeues; -+ sch->qstats.overlimits += qdisc->qstats.overlimits; -+ } -+ -+ for_each_online_cpu(i) { -+ qstats = per_cpu_ptr(priv->root.qstats, i); -+ sch->qstats.drops += qstats->drops; -+ } -+ -+ break; -+ -+ case CEETM_PRIO: -+ qopt.prio_group_A = priv->prio.tx_prio_cfg.prio_group_A; -+ qopt.prio_group_B = priv->prio.tx_prio_cfg.prio_group_B; -+ qopt.separate_groups = priv->prio.tx_prio_cfg.separate_groups; -+ break; -+ -+ default: -+ pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__); -+ sch_tree_unlock(sch); -+ return -EINVAL; -+ } -+ -+ nest = nla_nest_start_noflag(skb, TCA_OPTIONS); -+ if (!nest) -+ goto nla_put_failure; -+ if (nla_put(skb, DPAA2_CEETM_TCA_QOPS, sizeof(qopt), &qopt)) -+ goto nla_put_failure; -+ nla_nest_end(skb, nest); -+ -+ sch_tree_unlock(sch); -+ return skb->len; -+ -+nla_put_failure: -+ sch_tree_unlock(sch); -+ nla_nest_cancel(skb, nest); -+ return -EMSGSIZE; -+} -+ -+static int dpaa2_ceetm_change_prio(struct Qdisc *sch, -+ struct dpaa2_ceetm_qdisc *priv, -+ struct dpaa2_ceetm_tc_qopt *qopt) -+{ -+ /* TODO: Once LX2 support is added */ -+ /* priv->shaped = parent_cl->shaped; */ -+ priv->prio.tx_prio_cfg.prio_group_A = qopt->prio_group_A; -+ priv->prio.tx_prio_cfg.prio_group_B = qopt->prio_group_B; -+ priv->prio.tx_prio_cfg.separate_groups = qopt->separate_groups; -+ -+ return 0; -+} -+ -+/* Edit a ceetm qdisc */ -+static int dpaa2_ceetm_change(struct Qdisc *sch, struct nlattr *opt, -+ struct netlink_ext_ack *extack) -+{ -+ struct dpaa2_ceetm_qdisc *priv = qdisc_priv(sch); -+ struct nlattr *tb[DPAA2_CEETM_TCA_QOPS + 1]; -+ struct dpaa2_ceetm_tc_qopt *qopt; -+ int err; -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ err = nla_parse_nested_deprecated(tb, DPAA2_CEETM_TCA_QOPS, opt, -+ dpaa2_ceetm_policy, extack); -+ if (err < 0) { -+ pr_err(KBUILD_BASENAME " : %s : tc error in %s\n", __func__, -+ "nla_parse_nested_deprecated"); -+ return err; -+ } -+ -+ if (!tb[DPAA2_CEETM_TCA_QOPS]) { -+ pr_err(KBUILD_BASENAME " : %s : tc error in %s\n", __func__, -+ "tb"); -+ return -EINVAL; -+ } -+ -+ if (TC_H_MIN(sch->handle)) { -+ pr_err("CEETM: a qdisc should not have a minor\n"); -+ return -EINVAL; -+ } -+ -+ qopt = nla_data(tb[DPAA2_CEETM_TCA_QOPS]); -+ -+ if (priv->type != qopt->type) { -+ pr_err("CEETM: qdisc %X is not of the provided type\n", -+ sch->handle); -+ return -EINVAL; -+ } -+ -+ switch (priv->type) { -+ case CEETM_PRIO: -+ err = dpaa2_ceetm_change_prio(sch, priv, qopt); -+ break; -+ default: -+ pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__); -+ err = -EINVAL; -+ } -+ -+ return err; -+} -+ -+/* Configure a root ceetm qdisc */ -+static int dpaa2_ceetm_init_root(struct Qdisc *sch, -+ struct dpaa2_ceetm_qdisc *priv, -+ struct dpaa2_ceetm_tc_qopt *qopt, -+ struct netlink_ext_ack *extack) -+{ -+ struct net_device *dev = qdisc_dev(sch); -+ struct dpaa2_eth_priv *priv_eth = netdev_priv(dev); -+ struct netdev_queue *dev_queue; -+ unsigned int i, parent_id; -+ struct Qdisc *qdisc; -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ /* Validate inputs */ -+ if (sch->parent != TC_H_ROOT) { -+ pr_err("CEETM: a root ceetm qdisc must be root\n"); -+ return -EINVAL; -+ } -+ -+ /* Pre-allocate underlying pfifo qdiscs. -+ * -+ * We want to offload shaping and scheduling decisions to the hardware. -+ * The pfifo qdiscs will be attached to the netdev queues and will -+ * guide the traffic from the IP stack down to the driver with minimum -+ * interference. -+ * -+ * The CEETM qdiscs and classes will be crossed when the traffic -+ * reaches the driver. -+ */ -+ priv->root.qdiscs = kcalloc(dev->num_tx_queues, -+ sizeof(priv->root.qdiscs[0]), -+ GFP_KERNEL); -+ if (!priv->root.qdiscs) -+ return -ENOMEM; -+ -+ for (i = 0; i < dev->num_tx_queues; i++) { -+ dev_queue = netdev_get_tx_queue(dev, i); -+ parent_id = TC_H_MAKE(TC_H_MAJ(sch->handle), -+ TC_H_MIN(i + PFIFO_MIN_OFFSET)); -+ -+ qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops, -+ parent_id, extack); -+ if (!qdisc) -+ return -ENOMEM; -+ -+ priv->root.qdiscs[i] = qdisc; -+ qdisc->flags |= TCQ_F_ONETXQUEUE; -+ } -+ -+ sch->flags |= TCQ_F_MQROOT; -+ -+ priv->root.qstats = alloc_percpu(struct dpaa2_ceetm_qdisc_stats); -+ if (!priv->root.qstats) { -+ pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n", -+ __func__); -+ return -ENOMEM; -+ } -+ -+ dpaa2_eth_ceetm_enable(priv_eth); -+ return 0; -+} -+ -+/* Configure a prio ceetm qdisc */ -+static int dpaa2_ceetm_init_prio(struct Qdisc *sch, -+ struct dpaa2_ceetm_qdisc *priv, -+ struct dpaa2_ceetm_tc_qopt *qopt) -+{ -+ struct net_device *dev = qdisc_dev(sch); -+ struct dpaa2_ceetm_class *parent_cl; -+ struct Qdisc *parent_qdisc; -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ if (sch->parent == TC_H_ROOT) { -+ pr_err("CEETM: a prio ceetm qdisc can not be root\n"); -+ return -EINVAL; -+ } -+ -+ parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent)); -+ if (strcmp(parent_qdisc->ops->id, dpaa2_ceetm_qdisc_ops.id)) { -+ pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n"); -+ return -EINVAL; -+ } -+ -+ /* Obtain the parent root ceetm_class */ -+ parent_cl = dpaa2_ceetm_find(sch->parent, parent_qdisc); -+ -+ if (!parent_cl || parent_cl->type != CEETM_ROOT) { -+ pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n"); -+ return -EINVAL; -+ } -+ -+ priv->prio.parent = parent_cl; -+ parent_cl->child = sch; -+ -+ return dpaa2_ceetm_change_prio(sch, priv, qopt); -+} -+ -+/* Configure a generic ceetm qdisc */ -+static int dpaa2_ceetm_init(struct Qdisc *sch, struct nlattr *opt, -+ struct netlink_ext_ack *extack) -+{ -+ struct dpaa2_ceetm_qdisc *priv = qdisc_priv(sch); -+ struct net_device *dev = qdisc_dev(sch); -+ struct nlattr *tb[DPAA2_CEETM_TCA_QOPS + 1]; -+ struct dpaa2_ceetm_tc_qopt *qopt; -+ int err; -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ if (!netif_is_multiqueue(dev)) -+ return -EOPNOTSUPP; -+ -+ err = tcf_block_get(&priv->block, &priv->filter_list, sch, extack); -+ if (err) { -+ pr_err("CEETM: unable to get tcf_block\n"); -+ return err; -+ } -+ -+ if (!opt) { -+ pr_err(KBUILD_BASENAME " : %s : tc error - opt = NULL\n", -+ __func__); -+ return -EINVAL; -+ } -+ -+ err = nla_parse_nested_deprecated(tb, DPAA2_CEETM_TCA_QOPS, opt, -+ dpaa2_ceetm_policy, extack); -+ if (err < 0) { -+ pr_err(KBUILD_BASENAME " : %s : tc error in %s\n", __func__, -+ "nla_parse_nested_deprecated"); -+ return err; -+ } -+ -+ if (!tb[DPAA2_CEETM_TCA_QOPS]) { -+ pr_err(KBUILD_BASENAME " : %s : tc error in %s\n", __func__, -+ "tb"); -+ return -EINVAL; -+ } -+ -+ if (TC_H_MIN(sch->handle)) { -+ pr_err("CEETM: a qdisc should not have a minor\n"); -+ return -EINVAL; -+ } -+ -+ qopt = nla_data(tb[DPAA2_CEETM_TCA_QOPS]); -+ -+ /* Initialize the class hash list. Each qdisc has its own class hash */ -+ err = qdisc_class_hash_init(&priv->clhash); -+ if (err < 0) { -+ pr_err(KBUILD_BASENAME " : %s : qdisc_class_hash_init failed\n", -+ __func__); -+ return err; -+ } -+ -+ priv->type = qopt->type; -+ priv->shaped = qopt->shaped; -+ -+ switch (priv->type) { -+ case CEETM_ROOT: -+ err = dpaa2_ceetm_init_root(sch, priv, qopt, extack); -+ break; -+ case CEETM_PRIO: -+ err = dpaa2_ceetm_init_prio(sch, priv, qopt); -+ break; -+ default: -+ pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__); -+ /* Note: dpaa2_ceetm_destroy() will be called by our caller */ -+ err = -EINVAL; -+ } -+ -+ return err; -+} -+ -+/* Attach the underlying pfifo qdiscs */ -+static void dpaa2_ceetm_attach(struct Qdisc *sch) -+{ -+ struct net_device *dev = qdisc_dev(sch); -+ struct dpaa2_ceetm_qdisc *priv = qdisc_priv(sch); -+ struct Qdisc *qdisc, *old_qdisc; -+ unsigned int i; -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ for (i = 0; i < dev->num_tx_queues; i++) { -+ qdisc = priv->root.qdiscs[i]; -+ old_qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc); -+ if (old_qdisc) -+ qdisc_put(old_qdisc); -+ } -+ -+ /* Remove the references to the pfifo qdiscs since the kernel will -+ * destroy them when needed. No cleanup from our part is required from -+ * this point on. -+ */ -+ kfree(priv->root.qdiscs); -+ priv->root.qdiscs = NULL; -+} -+ -+static unsigned long dpaa2_ceetm_cls_find(struct Qdisc *sch, u32 classid) -+{ -+ struct dpaa2_ceetm_class *cl; -+ -+ pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n", -+ __func__, classid, sch->handle); -+ cl = dpaa2_ceetm_find(classid, sch); -+ -+ return (unsigned long)cl; -+} -+ -+static int dpaa2_ceetm_cls_change_root(struct dpaa2_ceetm_class *cl, -+ struct dpaa2_ceetm_tc_copt *copt, -+ struct net_device *dev) -+{ -+ struct dpaa2_eth_priv *priv = netdev_priv(dev); -+ struct dpni_tx_shaping_cfg scfg = { 0 }, ecfg = { 0 }; -+ int err = 0; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X\n", __func__, -+ cl->common.classid); -+ -+ if (!cl->shaped) -+ return 0; -+ -+ if (dpaa2_eth_update_shaping_cfg(dev, copt->shaping_cfg, -+ &scfg, &ecfg)) -+ return -EINVAL; -+ -+ err = dpaa2_eth_set_ch_shaping(priv, &scfg, &ecfg, -+ copt->shaping_cfg.coupled, -+ cl->root.ch_id); -+ if (err) -+ return err; -+ -+ memcpy(&cl->root.shaping_cfg, &copt->shaping_cfg, -+ sizeof(struct dpaa2_ceetm_shaping_cfg)); -+ -+ return err; -+} -+ -+static int dpaa2_ceetm_cls_change_prio(struct dpaa2_ceetm_class *cl, -+ struct dpaa2_ceetm_tc_copt *copt, -+ struct net_device *dev) -+{ -+ struct dpaa2_ceetm_qdisc *sch = qdisc_priv(cl->parent); -+ struct dpni_tx_schedule_cfg *sched_cfg; -+ struct dpaa2_eth_priv *priv = netdev_priv(dev); -+ int err; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X mode %d weight %d\n", -+ __func__, cl->common.classid, copt->mode, copt->weight); -+ -+ if (!cl->prio.cstats) { -+ cl->prio.cstats = alloc_percpu(struct dpaa2_ceetm_class_stats); -+ if (!cl->prio.cstats) { -+ pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n", -+ __func__); -+ return -ENOMEM; -+ } -+ } -+ -+ cl->prio.mode = copt->mode; -+ cl->prio.weight = copt->weight; -+ -+ sched_cfg = &sch->prio.tx_prio_cfg.tc_sched[cl->prio.qpri]; -+ -+ switch (copt->mode) { -+ case STRICT_PRIORITY: -+ sched_cfg->mode = DPNI_TX_SCHED_STRICT_PRIORITY; -+ break; -+ case WEIGHTED_A: -+ sched_cfg->mode = DPNI_TX_SCHED_WEIGHTED_A; -+ break; -+ case WEIGHTED_B: -+ sched_cfg->mode = DPNI_TX_SCHED_WEIGHTED_B; -+ break; -+ } -+ -+ err = dpaa2_eth_update_tx_prio(priv, cl, DPAA2_ETH_ADD_CQ); -+ -+ return err; -+} -+ -+/* Add a new ceetm class */ -+static int dpaa2_ceetm_cls_add(struct Qdisc *sch, u32 classid, -+ struct dpaa2_ceetm_tc_copt *copt, -+ unsigned long *arg, -+ struct netlink_ext_ack *extack) -+{ -+ struct dpaa2_ceetm_qdisc *priv = qdisc_priv(sch); -+ struct net_device *dev = qdisc_dev(sch); -+ struct dpaa2_eth_priv *priv_eth = netdev_priv(dev); -+ struct dpaa2_ceetm_class *cl; -+ int err; -+ -+ if (copt->type == CEETM_ROOT && -+ priv->clhash.hashelems == dpaa2_eth_ch_count(priv_eth)) { -+ pr_err("CEETM: only %d channel%s per DPNI allowed, sorry\n", -+ dpaa2_eth_ch_count(priv_eth), -+ dpaa2_eth_ch_count(priv_eth) == 1 ? "" : "s"); -+ return -EINVAL; -+ } -+ -+ if (copt->type == CEETM_PRIO && -+ priv->clhash.hashelems == dpaa2_eth_tc_count(priv_eth)) { -+ pr_err("CEETM: only %d queue%s per channel allowed, sorry\n", -+ dpaa2_eth_tc_count(priv_eth), -+ dpaa2_eth_tc_count(priv_eth) == 1 ? "" : "s"); -+ return -EINVAL; -+ } -+ -+ cl = kzalloc(sizeof(*cl), GFP_KERNEL); -+ if (!cl) -+ return -ENOMEM; -+ -+ err = tcf_block_get(&cl->block, &cl->filter_list, sch, extack); -+ if (err) { -+ pr_err("%s: Unable to set new root class\n", __func__); -+ goto out_free; -+ } -+ -+ cl->common.classid = classid; -+ cl->parent = sch; -+ cl->child = NULL; -+ -+ /* Add class handle in Qdisc */ -+ dpaa2_ceetm_link_class(sch, &priv->clhash, &cl->common); -+ -+ cl->shaped = copt->shaped; -+ cl->type = copt->type; -+ -+ /* Claim a CEETM channel / tc - DPAA2. will assume transition from -+ * classid to qdid/qpri, starting from qdid / qpri 0 -+ */ -+ switch (copt->type) { -+ case CEETM_ROOT: -+ cl->root.ch_id = classid - sch->handle - 1; -+ err = dpaa2_ceetm_cls_change_root(cl, copt, dev); -+ break; -+ case CEETM_PRIO: -+ cl->prio.qpri = classid - sch->handle - 1; -+ err = dpaa2_ceetm_cls_change_prio(cl, copt, dev); -+ break; -+ } -+ -+ if (err) { -+ pr_err("%s: Unable to set new %s class\n", __func__, -+ (copt->type == CEETM_ROOT ? "root" : "prio")); -+ goto out_free; -+ } -+ -+ switch (copt->type) { -+ case CEETM_ROOT: -+ pr_debug(KBUILD_BASENAME " : %s : configured root class %X associated with channel qdid %d\n", -+ __func__, classid, cl->root.ch_id); -+ break; -+ case CEETM_PRIO: -+ pr_debug(KBUILD_BASENAME " : %s : configured prio class %X associated with queue qpri %d\n", -+ __func__, classid, cl->prio.qpri); -+ break; -+ } -+ -+ *arg = (unsigned long)cl; -+ return 0; -+ -+out_free: -+ kfree(cl); -+ return err; -+} -+ -+/* Add or configure a ceetm class */ -+static int dpaa2_ceetm_cls_change(struct Qdisc *sch, u32 classid, u32 parentid, -+ struct nlattr **tca, unsigned long *arg, -+ struct netlink_ext_ack *extack) -+{ -+ struct dpaa2_ceetm_qdisc *priv; -+ struct dpaa2_ceetm_class *cl = (struct dpaa2_ceetm_class *)*arg; -+ struct nlattr *opt = tca[TCA_OPTIONS]; -+ struct nlattr *tb[DPAA2_CEETM_TCA_MAX]; -+ struct dpaa2_ceetm_tc_copt *copt; -+ struct net_device *dev = qdisc_dev(sch); -+ int err; -+ -+ pr_debug(KBUILD_BASENAME " : %s : classid %X under qdisc %X\n", -+ __func__, classid, sch->handle); -+ -+ if (strcmp(sch->ops->id, dpaa2_ceetm_qdisc_ops.id)) { -+ pr_err("CEETM: a ceetm class can not be attached to other qdisc/class types\n"); -+ return -EINVAL; -+ } -+ -+ priv = qdisc_priv(sch); -+ -+ if (!opt) { -+ pr_err(KBUILD_BASENAME " : %s : tc error NULL opt\n", __func__); -+ return -EINVAL; -+ } -+ -+ err = nla_parse_nested_deprecated(tb, DPAA2_CEETM_TCA_COPT, opt, -+ dpaa2_ceetm_policy, extack); -+ if (err < 0) { -+ pr_err(KBUILD_BASENAME " : %s : tc error in %s\n", __func__, -+ "nla_parse_nested_deprecated"); -+ return -EINVAL; -+ } -+ -+ if (!tb[DPAA2_CEETM_TCA_COPT]) { -+ pr_err(KBUILD_BASENAME " : %s : tc error in %s\n", __func__, -+ "tb"); -+ return -EINVAL; -+ } -+ -+ copt = nla_data(tb[DPAA2_CEETM_TCA_COPT]); -+ -+ /* Configure an existing ceetm class */ -+ if (cl) { -+ if (copt->type != cl->type) { -+ pr_err("CEETM: class %X is not of the provided type\n", -+ cl->common.classid); -+ return -EINVAL; -+ } -+ -+ switch (copt->type) { -+ case CEETM_ROOT: -+ return dpaa2_ceetm_cls_change_root(cl, copt, dev); -+ case CEETM_PRIO: -+ return dpaa2_ceetm_cls_change_prio(cl, copt, dev); -+ -+ default: -+ pr_err(KBUILD_BASENAME " : %s : invalid class\n", -+ __func__); -+ return -EINVAL; -+ } -+ } -+ -+ return dpaa2_ceetm_cls_add(sch, classid, copt, arg, extack); -+} -+ -+static void dpaa2_ceetm_cls_walk(struct Qdisc *sch, struct qdisc_walker *arg) -+{ -+ struct dpaa2_ceetm_qdisc *priv = qdisc_priv(sch); -+ struct dpaa2_ceetm_class *cl; -+ unsigned int i; -+ -+ pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -+ -+ if (arg->stop) -+ return; -+ -+ for (i = 0; i < priv->clhash.hashsize; i++) { -+ hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) { -+ if (arg->count < arg->skip) { -+ arg->count++; -+ continue; -+ } -+ if (arg->fn(sch, (unsigned long)cl, arg) < 0) { -+ arg->stop = 1; -+ return; -+ } -+ arg->count++; -+ } -+ } -+} -+ -+static int dpaa2_ceetm_cls_dump(struct Qdisc *sch, unsigned long arg, -+ struct sk_buff *skb, struct tcmsg *tcm) -+{ -+ struct dpaa2_ceetm_class *cl = (struct dpaa2_ceetm_class *)arg; -+ struct nlattr *nest; -+ struct dpaa2_ceetm_tc_copt copt; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", -+ __func__, cl->common.classid, sch->handle); -+ -+ sch_tree_lock(sch); -+ -+ tcm->tcm_parent = ((struct Qdisc *)cl->parent)->handle; -+ tcm->tcm_handle = cl->common.classid; -+ -+ memset(&copt, 0, sizeof(copt)); -+ -+ copt.shaped = cl->shaped; -+ copt.type = cl->type; -+ -+ switch (cl->type) { -+ case CEETM_ROOT: -+ if (cl->child) -+ tcm->tcm_info = cl->child->handle; -+ -+ memcpy(&copt.shaping_cfg, &cl->root.shaping_cfg, -+ sizeof(struct dpaa2_ceetm_shaping_cfg)); -+ -+ break; -+ -+ case CEETM_PRIO: -+ if (cl->child) -+ tcm->tcm_info = cl->child->handle; -+ -+ copt.mode = cl->prio.mode; -+ copt.weight = cl->prio.weight; -+ -+ break; -+ } -+ -+ nest = nla_nest_start_noflag(skb, TCA_OPTIONS); -+ if (!nest) -+ goto nla_put_failure; -+ if (nla_put(skb, DPAA2_CEETM_TCA_COPT, sizeof(copt), &copt)) -+ goto nla_put_failure; -+ nla_nest_end(skb, nest); -+ sch_tree_unlock(sch); -+ return skb->len; -+ -+nla_put_failure: -+ sch_tree_unlock(sch); -+ nla_nest_cancel(skb, nest); -+ return -EMSGSIZE; -+} -+ -+static int dpaa2_ceetm_cls_delete(struct Qdisc *sch, unsigned long arg) -+{ -+ struct dpaa2_ceetm_qdisc *priv = qdisc_priv(sch); -+ struct dpaa2_ceetm_class *cl = (struct dpaa2_ceetm_class *)arg; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", -+ __func__, cl->common.classid, sch->handle); -+ -+ sch_tree_lock(sch); -+ qdisc_class_hash_remove(&priv->clhash, &cl->common); -+ sch_tree_unlock(sch); -+ return 0; -+} -+ -+/* Get the class' child qdisc, if any */ -+static struct Qdisc *dpaa2_ceetm_cls_leaf(struct Qdisc *sch, unsigned long arg) -+{ -+ struct dpaa2_ceetm_class *cl = (struct dpaa2_ceetm_class *)arg; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", -+ __func__, cl->common.classid, sch->handle); -+ -+ switch (cl->type) { -+ case CEETM_ROOT: -+ case CEETM_PRIO: -+ return cl->child; -+ } -+ -+ return NULL; -+} -+ -+static int dpaa2_ceetm_cls_graft(struct Qdisc *sch, unsigned long arg, -+ struct Qdisc *new, struct Qdisc **old, -+ struct netlink_ext_ack *extack) -+{ -+ if (new && strcmp(new->ops->id, dpaa2_ceetm_qdisc_ops.id)) { -+ pr_err("CEETM: only ceetm qdiscs can be attached to ceetm classes\n"); -+ return -EOPNOTSUPP; -+ } -+ -+ return 0; -+} -+ -+static int dpaa2_ceetm_cls_dump_stats(struct Qdisc *sch, unsigned long arg, -+ struct gnet_dump *d) -+{ -+ struct dpaa2_ceetm_class *cl = (struct dpaa2_ceetm_class *)arg; -+ struct gnet_stats_basic_packed tmp_bstats; -+ struct dpaa2_ceetm_tc_xstats xstats; -+ union dpni_statistics dpni_stats; -+ struct net_device *dev = qdisc_dev(sch); -+ struct dpaa2_eth_priv *priv_eth = netdev_priv(dev); -+ u8 ch_id = 0; -+ int err; -+ -+ memset(&xstats, 0, sizeof(xstats)); -+ memset(&tmp_bstats, 0, sizeof(tmp_bstats)); -+ -+ if (cl->type == CEETM_ROOT) -+ return 0; -+ -+ err = dpni_get_statistics(priv_eth->mc_io, 0, priv_eth->mc_token, 3, -+ DPNI_BUILD_CH_TC(ch_id, cl->prio.qpri), -+ &dpni_stats); -+ if (err) -+ netdev_warn(dev, "dpni_get_stats(%d) failed - %d\n", 3, err); -+ -+ xstats.ceetm_dequeue_bytes = dpni_stats.page_3.egress_dequeue_bytes; -+ xstats.ceetm_dequeue_frames = dpni_stats.page_3.egress_dequeue_frames; -+ xstats.ceetm_reject_bytes = dpni_stats.page_3.egress_reject_bytes; -+ xstats.ceetm_reject_frames = dpni_stats.page_3.egress_reject_frames; -+ -+ return gnet_stats_copy_app(d, &xstats, sizeof(xstats)); -+} -+ -+static struct tcf_block *dpaa2_ceetm_tcf_block(struct Qdisc *sch, -+ unsigned long arg, -+ struct netlink_ext_ack *extack) -+{ -+ struct dpaa2_ceetm_qdisc *priv = qdisc_priv(sch); -+ struct dpaa2_ceetm_class *cl = (struct dpaa2_ceetm_class *)arg; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__, -+ cl ? cl->common.classid : 0, sch->handle); -+ return cl ? cl->block : priv->block; -+} -+ -+static unsigned long dpaa2_ceetm_tcf_bind(struct Qdisc *sch, -+ unsigned long parent, -+ u32 classid) -+{ -+ struct dpaa2_ceetm_class *cl = dpaa2_ceetm_find(classid, sch); -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__, -+ cl ? cl->common.classid : 0, sch->handle); -+ return (unsigned long)cl; -+} -+ -+static void dpaa2_ceetm_tcf_unbind(struct Qdisc *sch, unsigned long arg) -+{ -+ struct dpaa2_ceetm_class *cl = (struct dpaa2_ceetm_class *)arg; -+ -+ pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__, -+ cl ? cl->common.classid : 0, sch->handle); -+} -+ -+const struct Qdisc_class_ops dpaa2_ceetm_cls_ops = { -+ .graft = dpaa2_ceetm_cls_graft, -+ .leaf = dpaa2_ceetm_cls_leaf, -+ .find = dpaa2_ceetm_cls_find, -+ .change = dpaa2_ceetm_cls_change, -+ .delete = dpaa2_ceetm_cls_delete, -+ .walk = dpaa2_ceetm_cls_walk, -+ .tcf_block = dpaa2_ceetm_tcf_block, -+ .bind_tcf = dpaa2_ceetm_tcf_bind, -+ .unbind_tcf = dpaa2_ceetm_tcf_unbind, -+ .dump = dpaa2_ceetm_cls_dump, -+ .dump_stats = dpaa2_ceetm_cls_dump_stats, -+}; -+ -+struct Qdisc_ops dpaa2_ceetm_qdisc_ops __read_mostly = { -+ .id = "ceetm", -+ .priv_size = sizeof(struct dpaa2_ceetm_qdisc), -+ .cl_ops = &dpaa2_ceetm_cls_ops, -+ .init = dpaa2_ceetm_init, -+ .destroy = dpaa2_ceetm_destroy, -+ .change = dpaa2_ceetm_change, -+ .dump = dpaa2_ceetm_dump, -+ .attach = dpaa2_ceetm_attach, -+ .owner = THIS_MODULE, -+}; -+ -+/* Run the filters and classifiers attached to the qdisc on the provided skb */ -+int dpaa2_ceetm_classify(struct sk_buff *skb, struct Qdisc *sch, -+ int *qdid, u8 *qpri) -+{ -+ struct dpaa2_ceetm_qdisc *priv = qdisc_priv(sch); -+ struct dpaa2_ceetm_class *cl = NULL; -+ struct tcf_result res; -+ struct tcf_proto *tcf; -+ int result; -+ -+ tcf = rcu_dereference_bh(priv->filter_list); -+ while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) { -+#ifdef CONFIG_NET_CLS_ACT -+ switch (result) { -+ case TC_ACT_QUEUED: -+ case TC_ACT_STOLEN: -+ case TC_ACT_SHOT: -+ /* No valid class found due to action */ -+ return -1; -+ } -+#endif -+ cl = (void *)res.class; -+ if (!cl) { -+ /* The filter leads to the qdisc */ -+ if (res.classid == sch->handle) -+ return 0; -+ -+ cl = dpaa2_ceetm_find(res.classid, sch); -+ /* The filter leads to an invalid class */ -+ if (!cl) -+ break; -+ } -+ -+ /* The class might have its own filters attached */ -+ tcf = rcu_dereference_bh(cl->filter_list); -+ } -+ -+ /* No valid class found */ -+ if (!cl) -+ return 0; -+ -+ switch (cl->type) { -+ case CEETM_ROOT: -+ *qdid = cl->root.ch_id; -+ -+ /* The root class does not have a child prio qdisc */ -+ if (!cl->child) -+ return 0; -+ -+ /* Run the prio qdisc classifiers */ -+ return dpaa2_ceetm_classify(skb, cl->child, qdid, qpri); -+ -+ case CEETM_PRIO: -+ *qpri = cl->prio.qpri; -+ break; -+ } -+ -+ return 0; -+} -+ -+int __init dpaa2_ceetm_register(void) -+{ -+ int err = 0; -+ -+ pr_debug(KBUILD_MODNAME ": " DPAA2_CEETM_DESCRIPTION "\n"); -+ -+ err = register_qdisc(&dpaa2_ceetm_qdisc_ops); -+ if (unlikely(err)) -+ pr_err(KBUILD_MODNAME -+ ": %s:%hu:%s(): register_qdisc() = %d\n", -+ KBUILD_BASENAME ".c", __LINE__, __func__, err); -+ -+ return err; -+} -+ -+void __exit dpaa2_ceetm_unregister(void) -+{ -+ pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -+ KBUILD_BASENAME ".c", __func__); -+ -+ unregister_qdisc(&dpaa2_ceetm_qdisc_ops); -+} ---- /dev/null -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-ceetm.h -@@ -0,0 +1,207 @@ -+/* Copyright 2017 NXP -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * * Neither the name of Freescale Semiconductor nor the -+ * names of its contributors may be used to endorse or promote products -+ * derived from this software without specific prior written permission. -+ * -+ * -+ * ALTERNATIVELY, this software may be distributed under the terms of the -+ * GNU General Public License ("GPL") as published by the Free Software -+ * Foundation, either version 2 of that License or (at your option) any -+ * later version. -+ * -+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY -+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY -+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#ifndef __DPAA2_ETH_CEETM_H -+#define __DPAA2_ETH_CEETM_H -+ -+#include -+#include -+#include -+ -+#include "dpaa2-eth.h" -+ -+/* For functional purposes, there are num_tx_queues pfifo qdiscs through which -+ * frames reach the driver. Their handles start from 1:21. Handles 1:1 to 1:20 -+ * are reserved for the maximum 32 CEETM channels (majors and minors are in -+ * hex). -+ */ -+#define PFIFO_MIN_OFFSET 0x21 -+ -+#define DPAA2_CEETM_MIN_WEIGHT 100 -+#define DPAA2_CEETM_MAX_WEIGHT 24800 -+ -+#define DPAA2_CEETM_TD_THRESHOLD 1000 -+ -+enum wbfs_group_type { -+ WBFS_GRP_A, -+ WBFS_GRP_B, -+ WBFS_GRP_LARGE -+}; -+ -+enum { -+ DPAA2_CEETM_TCA_UNSPEC, -+ DPAA2_CEETM_TCA_COPT, -+ DPAA2_CEETM_TCA_QOPS, -+ DPAA2_CEETM_TCA_MAX, -+}; -+ -+/* CEETM configuration types */ -+enum dpaa2_ceetm_type { -+ CEETM_ROOT = 1, -+ CEETM_PRIO, -+}; -+ -+enum { -+ STRICT_PRIORITY = 0, -+ WEIGHTED_A, -+ WEIGHTED_B, -+}; -+ -+struct dpaa2_ceetm_shaping_cfg { -+ __u64 cir; /* committed information rate */ -+ __u64 eir; /* excess information rate */ -+ __u16 cbs; /* committed burst size */ -+ __u16 ebs; /* excess burst size */ -+ __u8 coupled; /* shaper coupling */ -+}; -+ -+extern const struct nla_policy ceetm_policy[DPAA2_CEETM_TCA_MAX]; -+ -+struct dpaa2_ceetm_class; -+struct dpaa2_ceetm_qdisc_stats; -+struct dpaa2_ceetm_class_stats; -+ -+/* corresponds to CEETM shaping at LNI level */ -+struct dpaa2_root_q { -+ struct Qdisc **qdiscs; -+ struct dpaa2_ceetm_qdisc_stats __percpu *qstats; -+}; -+ -+/* corresponds to the number of priorities a channel serves */ -+struct dpaa2_prio_q { -+ struct dpaa2_ceetm_class *parent; -+ struct dpni_tx_priorities_cfg tx_prio_cfg; -+}; -+ -+struct dpaa2_ceetm_qdisc { -+ struct Qdisc_class_hash clhash; -+ struct tcf_proto *filter_list; /* qdisc attached filters */ -+ struct tcf_block *block; -+ -+ enum dpaa2_ceetm_type type; /* ROOT/PRIO */ -+ bool shaped; -+ union { -+ struct dpaa2_root_q root; -+ struct dpaa2_prio_q prio; -+ }; -+}; -+ -+/* CEETM Qdisc configuration parameters */ -+struct dpaa2_ceetm_tc_qopt { -+ enum dpaa2_ceetm_type type; -+ __u16 shaped; -+ __u8 prio_group_A; -+ __u8 prio_group_B; -+ __u8 separate_groups; -+}; -+ -+/* root class - corresponds to a channel */ -+struct dpaa2_root_c { -+ struct dpaa2_ceetm_shaping_cfg shaping_cfg; -+ u32 ch_id; -+}; -+ -+/* prio class - corresponds to a strict priority queue (group) */ -+struct dpaa2_prio_c { -+ struct dpaa2_ceetm_class_stats __percpu *cstats; -+ u32 qpri; -+ u8 mode; -+ u16 weight; -+}; -+ -+struct dpaa2_ceetm_class { -+ struct Qdisc_class_common common; -+ struct tcf_proto *filter_list; /* class attached filters */ -+ struct tcf_block *block; -+ struct Qdisc *parent; -+ struct Qdisc *child; -+ -+ enum dpaa2_ceetm_type type; /* ROOT/PRIO */ -+ bool shaped; -+ union { -+ struct dpaa2_root_c root; -+ struct dpaa2_prio_c prio; -+ }; -+}; -+ -+/* CEETM Class configuration parameters */ -+struct dpaa2_ceetm_tc_copt { -+ enum dpaa2_ceetm_type type; -+ struct dpaa2_ceetm_shaping_cfg shaping_cfg; -+ __u16 shaped; -+ __u8 mode; -+ __u16 weight; -+}; -+ -+/* CEETM stats */ -+struct dpaa2_ceetm_qdisc_stats { -+ __u32 drops; -+}; -+ -+struct dpaa2_ceetm_class_stats { -+ /* Software counters */ -+ struct gnet_stats_basic_packed bstats; -+ __u32 ern_drop_count; -+}; -+ -+struct dpaa2_ceetm_tc_xstats { -+ __u64 ceetm_dequeue_bytes; -+ __u64 ceetm_dequeue_frames; -+ __u64 ceetm_reject_bytes; -+ __u64 ceetm_reject_frames; -+}; -+ -+#ifdef CONFIG_FSL_DPAA2_ETH_CEETM -+int __init dpaa2_ceetm_register(void); -+void __exit dpaa2_ceetm_unregister(void); -+int dpaa2_ceetm_classify(struct sk_buff *skb, struct Qdisc *sch, -+ int *qdid, u8 *qpri); -+#else -+static inline int dpaa2_ceetm_register(void) -+{ -+ return 0; -+} -+ -+static inline void dpaa2_ceetm_unregister(void) {} -+ -+static inline int dpaa2_ceetm_classify(struct sk_buff *skb, struct Qdisc *sch, -+ int *qdid, u8 *qpri) -+{ -+ return 0; -+} -+#endif -+ -+static inline bool dpaa2_eth_ceetm_is_enabled(struct dpaa2_eth_priv *priv) -+{ -+ return priv->ceetm_en; -+} -+ -+#endif ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -18,6 +18,7 @@ - #include - - #include "dpaa2-eth.h" -+#include "dpaa2-eth-ceetm.h" - - /* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files - * using trace events only need to #include -@@ -816,7 +817,7 @@ static netdev_tx_t dpaa2_eth_tx(struct s - unsigned int needed_headroom; - u32 fd_len; - u8 prio = 0; -- int err, i; -+ int err, i, ch_id = 0; - - percpu_stats = this_cpu_ptr(priv->percpu_stats); - percpu_extras = this_cpu_ptr(priv->percpu_extras); -@@ -887,6 +888,15 @@ static netdev_tx_t dpaa2_eth_tx(struct s - } - fq = &priv->fq[queue_mapping]; - -+ if (dpaa2_eth_ceetm_is_enabled(priv)) { -+ err = dpaa2_ceetm_classify(skb, net_dev->qdisc, &ch_id, &prio); -+ if (err) { -+ free_tx_fd(priv, fq, &fd, false); -+ percpu_stats->tx_dropped++; -+ return NETDEV_TX_OK; -+ } -+ } -+ - fd_len = dpaa2_fd_get_len(&fd); - nq = netdev_get_tx_queue(net_dev, queue_mapping); - netdev_tx_sent_queue(nq, fd_len); -@@ -2075,17 +2085,13 @@ static int update_xps(struct dpaa2_eth_p - return err; - } - --static int dpaa2_eth_setup_tc(struct net_device *net_dev, -- enum tc_setup_type type, void *type_data) -+static int dpaa2_eth_setup_mqprio(struct net_device *net_dev, -+ struct tc_mqprio_qopt *mqprio) - { - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -- struct tc_mqprio_qopt *mqprio = type_data; - u8 num_tc, num_queues; - int i; - -- if (type != TC_SETUP_QDISC_MQPRIO) -- return -EOPNOTSUPP; -- - mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS; - num_queues = dpaa2_eth_queue_count(priv); - num_tc = mqprio->num_tc; -@@ -2117,6 +2123,20 @@ out: - return 0; - } - -+static int dpaa2_eth_setup_tc(struct net_device *net_dev, -+ enum tc_setup_type type, -+ void *type_data) -+{ -+ switch (type) { -+ case TC_SETUP_BLOCK: -+ return 0; -+ case TC_SETUP_QDISC_MQPRIO: -+ return dpaa2_eth_setup_mqprio(net_dev, type_data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ - static const struct net_device_ops dpaa2_eth_ops = { - .ndo_open = dpaa2_eth_open, - .ndo_start_xmit = dpaa2_eth_tx, -@@ -4173,18 +4193,27 @@ static int __init dpaa2_eth_driver_init( - - dpaa2_eth_dbg_init(); - err = fsl_mc_driver_register(&dpaa2_eth_driver); -- if (err) { -- dpaa2_eth_dbg_exit(); -- return err; -- } -+ if (err) -+ goto out_debugfs_err; -+ -+ err = dpaa2_ceetm_register(); -+ if (err) -+ goto out_ceetm_err; - - return 0; -+ -+out_ceetm_err: -+ fsl_mc_driver_unregister(&dpaa2_eth_driver); -+out_debugfs_err: -+ dpaa2_eth_dbg_exit(); -+ return err; - } - - static void __exit dpaa2_eth_driver_exit(void) - { -- dpaa2_eth_dbg_exit(); -+ dpaa2_ceetm_unregister(); - fsl_mc_driver_unregister(&dpaa2_eth_driver); -+ dpaa2_eth_dbg_exit(); - } - - module_init(dpaa2_eth_driver_init); ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -454,6 +454,8 @@ struct dpaa2_eth_priv { - struct dpaa2_debugfs dbg; - #endif - struct dpni_tx_shaping_cfg shaping_cfg; -+ -+ bool ceetm_en; - }; - - #define DPAA2_RXH_SUPPORTED (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO \ -@@ -574,6 +576,11 @@ static inline unsigned int dpaa2_eth_rx_ - return priv->tx_data_offset - DPAA2_ETH_RX_HWA_SIZE; - } - -+static inline int dpaa2_eth_ch_count(struct dpaa2_eth_priv *priv) -+{ -+ return 1; -+} -+ - int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags); - int dpaa2_eth_set_cls(struct net_device *net_dev, u64 key); - int dpaa2_eth_cls_key_size(u64 key); diff --git a/target/linux/layerscape/patches-5.4/701-net-0214-dpaa2-eth-Re-add-get_link_ksettings-ethtool-op.patch b/target/linux/layerscape/patches-5.4/701-net-0214-dpaa2-eth-Re-add-get_link_ksettings-ethtool-op.patch deleted file mode 100644 index 25a9e90fbf..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0214-dpaa2-eth-Re-add-get_link_ksettings-ethtool-op.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0a5243abf168351ea8409caf329448a3e18ab62f Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Tue, 24 Sep 2019 13:24:40 +0300 -Subject: [PATCH] dpaa2-eth: Re-add get_link_ksettings ethtool op - -Which was removed from upstream driver since without a MAC driver -we have no support for changing link parameters there. - -Signed-off-by: Ioana Radulescu ---- - .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 47 +++++++++++++++++++++- - 1 file changed, 46 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -@@ -85,7 +85,8 @@ dpaa2_eth_get_link_ksettings(struct net_ - { - struct dpaa2_eth_priv *priv = netdev_priv(net_dev); - -- link_settings->base.autoneg = AUTONEG_DISABLE; -+ if (priv->link_state.options & DPNI_LINK_OPT_AUTONEG) -+ link_settings->base.autoneg = AUTONEG_ENABLE; - if (!(priv->link_state.options & DPNI_LINK_OPT_HALF_DUPLEX)) - link_settings->base.duplex = DUPLEX_FULL; - link_settings->base.speed = priv->link_state.rate; -@@ -93,6 +94,49 @@ dpaa2_eth_get_link_ksettings(struct net_ - return 0; - } - -+#define DPNI_DYNAMIC_LINK_SET_VER_MAJOR 7 -+#define DPNI_DYNAMIC_LINK_SET_VER_MINOR 1 -+static int -+dpaa2_eth_set_link_ksettings(struct net_device *net_dev, -+ const struct ethtool_link_ksettings *link_settings) -+{ -+ struct dpni_link_cfg cfg = {0}; -+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev); -+ int err = 0; -+ -+ /* If using an older MC version, the DPNI must be down -+ * in order to be able to change link settings. Taking steps to let -+ * the user know that. -+ */ -+ if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_DYNAMIC_LINK_SET_VER_MAJOR, -+ DPNI_DYNAMIC_LINK_SET_VER_MINOR) < 0) { -+ if (netif_running(net_dev)) { -+ netdev_info(net_dev, "Interface must be brought down first.\n"); -+ return -EACCES; -+ } -+ } -+ -+ cfg.rate = link_settings->base.speed; -+ cfg.options = priv->link_state.options; -+ if (link_settings->base.autoneg == AUTONEG_ENABLE) -+ cfg.options |= DPNI_LINK_OPT_AUTONEG; -+ else -+ cfg.options &= ~DPNI_LINK_OPT_AUTONEG; -+ if (link_settings->base.duplex == DUPLEX_HALF) -+ cfg.options |= DPNI_LINK_OPT_HALF_DUPLEX; -+ else -+ cfg.options &= ~DPNI_LINK_OPT_HALF_DUPLEX; -+ -+ err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg); -+ if (err) -+ /* ethtool will be loud enough if we return an error; no point -+ * in putting our own error message on the console by default -+ */ -+ netdev_dbg(net_dev, "ERROR %d setting link cfg\n", err); -+ -+ return err; -+} -+ - static void dpaa2_eth_get_pauseparam(struct net_device *net_dev, - struct ethtool_pauseparam *pause) - { -@@ -734,6 +778,7 @@ const struct ethtool_ops dpaa2_ethtool_o - .get_drvinfo = dpaa2_eth_get_drvinfo, - .get_link = ethtool_op_get_link, - .get_link_ksettings = dpaa2_eth_get_link_ksettings, -+ .set_link_ksettings = dpaa2_eth_set_link_ksettings, - .get_pauseparam = dpaa2_eth_get_pauseparam, - .set_pauseparam = dpaa2_eth_set_pauseparam, - .get_sset_count = dpaa2_eth_get_sset_count, diff --git a/target/linux/layerscape/patches-5.4/701-net-0215-dpaa2-eth-Add-support-for-new-link-state-APIs.patch b/target/linux/layerscape/patches-5.4/701-net-0215-dpaa2-eth-Add-support-for-new-link-state-APIs.patch deleted file mode 100644 index 19aa2e11d2..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0215-dpaa2-eth-Add-support-for-new-link-state-APIs.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 0153f87972bfa3ef33bf369b8e91142f7c2b284a Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Wed, 17 Oct 2018 20:14:24 +0300 -Subject: [PATCH] dpaa2-eth: Add support for new link state APIs - -Add v2 of dpni_get_link_state() and dpni_set_link_cfg() commands. -The new version allows setting & getting advertised and supported -link options. - -Signed-off-by: Valentin Catalin Neacsu -Signed-off-by: Ioana Radulescu ---- - drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h | 33 ++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.c | 70 +++++++++++++++++++++++++ - drivers/net/ethernet/freescale/dpaa2/dpni.h | 27 ++++++++++ - 3 files changed, 130 insertions(+) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h -@@ -44,9 +44,11 @@ - #define DPNI_CMDID_GET_QDID DPNI_CMD(0x210) - #define DPNI_CMDID_GET_TX_DATA_OFFSET DPNI_CMD(0x212) - #define DPNI_CMDID_GET_LINK_STATE DPNI_CMD(0x215) -+#define DPNI_CMDID_GET_LINK_STATE_V2 DPNI_CMD_V2(0x215) - #define DPNI_CMDID_SET_MAX_FRAME_LENGTH DPNI_CMD(0x216) - #define DPNI_CMDID_GET_MAX_FRAME_LENGTH DPNI_CMD(0x217) - #define DPNI_CMDID_SET_LINK_CFG DPNI_CMD(0x21A) -+#define DPNI_CMDID_SET_LINK_CFG_V2 DPNI_CMD_V2(0x21A) - #define DPNI_CMDID_SET_TX_SHAPING DPNI_CMD_V2(0x21B) - - #define DPNI_CMDID_SET_MCAST_PROMISC DPNI_CMD(0x220) -@@ -304,8 +306,22 @@ struct dpni_cmd_link_cfg { - __le64 options; - }; - -+struct dpni_cmd_set_link_cfg_v2 { -+ /* cmd word 0 */ -+ __le64 pad0; -+ /* cmd word 1 */ -+ __le32 rate; -+ __le32 pad1; -+ /* cmd word 2 */ -+ __le64 options; -+ /* cmd word 3 */ -+ __le64 advertising; -+}; -+ - #define DPNI_LINK_STATE_SHIFT 0 - #define DPNI_LINK_STATE_SIZE 1 -+#define DPNI_STATE_VALID_SHIFT 1 -+#define DPNI_STATE_VALID_SIZE 1 - - struct dpni_rsp_get_link_state { - /* response word 0 */ -@@ -320,6 +336,23 @@ struct dpni_rsp_get_link_state { - __le64 options; - }; - -+struct dpni_rsp_get_link_state_v2 { -+ /* response word 0 */ -+ __le32 pad0; -+ /* from LSB: up:1, valid:1 */ -+ u8 flags; -+ u8 pad1[3]; -+ /* response word 1 */ -+ __le32 rate; -+ __le32 pad2; -+ /* response word 2 */ -+ __le64 options; -+ /* cmd word 3 */ -+ __le64 supported; -+ /* cmd word 4 */ -+ __le64 advertising; -+}; -+ - #define DPNI_COUPLED_SHIFT 0 - #define DPNI_COUPLED_SIZE 1 - ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c -@@ -853,6 +853,36 @@ int dpni_set_link_cfg(struct fsl_mc_io * - } - - /** -+ * dpni_set_link_cfg_v2() - set the link configuration. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPNI object -+ * @cfg: Link configuration -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpni_set_link_cfg_v2(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_link_cfg *cfg) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpni_cmd_set_link_cfg_v2 *cmd_params; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG_V2, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpni_cmd_set_link_cfg_v2 *)cmd.params; -+ cmd_params->rate = cpu_to_le32(cfg->rate); -+ cmd_params->options = cpu_to_le64(cfg->options); -+ cmd_params->advertising = cpu_to_le64(cfg->advertising); -+ -+ /* send command to mc*/ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** - * dpni_get_link_cfg() - return the link configuration - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -@@ -924,6 +954,46 @@ int dpni_get_link_state(struct fsl_mc_io - - return 0; - } -+ -+/** -+ * dpni_get_link_state_v2() - Return the link state (either up or down) -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPNI object -+ * @state: Returned link state; -+ * -+ * Return: '0' on Success; Error code otherwise. -+ */ -+int dpni_get_link_state_v2(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpni_link_state *state) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpni_rsp_get_link_state_v2 *rsp_params; -+ int err; -+ -+ /* prepare command */ -+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE_V2, -+ cmd_flags, -+ token); -+ -+ /* send command to mc*/ -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ /* retrieve response parameters */ -+ rsp_params = (struct dpni_rsp_get_link_state_v2 *)cmd.params; -+ state->up = dpni_get_field(rsp_params->flags, LINK_STATE); -+ state->state_valid = dpni_get_field(rsp_params->flags, STATE_VALID); -+ state->rate = le32_to_cpu(rsp_params->rate); -+ state->options = le64_to_cpu(rsp_params->options); -+ state->supported = le64_to_cpu(rsp_params->supported); -+ state->advertising = le64_to_cpu(rsp_params->advertising); -+ -+ return 0; -+} - - /** - * dpni_set_tx_shaping() - Set the transmit shaping ---- a/drivers/net/ethernet/freescale/dpaa2/dpni.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h -@@ -522,6 +522,19 @@ int dpni_reset_statistics(struct fsl_mc_ - * Enable priority flow control pause frames - */ - #define DPNI_LINK_OPT_PFC_PAUSE 0x0000000000000010ULL -+/** -+ * Advertised link speeds -+ */ -+#define DPNI_ADVERTISED_10BASET_FULL 0x0000000000000001ULL -+#define DPNI_ADVERTISED_100BASET_FULL 0x0000000000000002ULL -+#define DPNI_ADVERTISED_1000BASET_FULL 0x0000000000000004ULL -+#define DPNI_ADVERTISED_10000BASET_FULL 0x0000000000000010ULL -+#define DPNI_ADVERTISED_2500BASEX_FULL 0x0000000000000020ULL -+ -+/** -+ * Advertise auto-negotiation enabled -+ */ -+#define DPNI_ADVERTISED_AUTONEG 0x0000000000000008ULL - - /** - * struct - Structure representing DPNI link configuration -@@ -531,6 +544,7 @@ int dpni_reset_statistics(struct fsl_mc_ - struct dpni_link_cfg { - u32 rate; - u64 options; -+ u64 advertising; - }; - - int dpni_set_link_cfg(struct fsl_mc_io *mc_io, -@@ -538,6 +552,11 @@ int dpni_set_link_cfg(struct fsl_mc_io - u16 token, - const struct dpni_link_cfg *cfg); - -+int dpni_set_link_cfg_v2(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ const struct dpni_link_cfg *cfg); -+ - int dpni_get_link_cfg(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, -@@ -552,7 +571,10 @@ int dpni_get_link_cfg(struct fsl_mc_io - struct dpni_link_state { - u32 rate; - u64 options; -+ u64 supported; -+ u64 advertising; - int up; -+ int state_valid; - }; - - int dpni_get_link_state(struct fsl_mc_io *mc_io, -@@ -560,6 +582,11 @@ int dpni_get_link_state(struct fsl_mc_io - u16 token, - struct dpni_link_state *state); - -+int dpni_get_link_state_v2(struct fsl_mc_io *mc_io, -+ u32 cmd_flags, -+ u16 token, -+ struct dpni_link_state *state); -+ - /** - * struct dpni_tx_shaping - Structure representing DPNI tx shaping configuration - * @rate_limit: rate in Mbps diff --git a/target/linux/layerscape/patches-5.4/701-net-0216-dpaa2-eth-Add-autoneg-support.patch b/target/linux/layerscape/patches-5.4/701-net-0216-dpaa2-eth-Add-autoneg-support.patch deleted file mode 100644 index b94fafae6c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0216-dpaa2-eth-Add-autoneg-support.patch +++ /dev/null @@ -1,129 +0,0 @@ -From c6365855a6d9aef3b75e301d26872bc51398c2f3 Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Thu, 18 Oct 2018 18:59:41 +0300 -Subject: [PATCH] dpaa2-eth: Add autoneg support - -For MC versions that support it, use the new DPNI link APIs, which -allow setting/getting of advertised and supported link modes. - -A mapping between DPNI link modes and ethtool ones is created to -help converting from one to the other. - -Signed-off-by: Ioana Radulescu -Signed-off-by: Valentin Catalin Neacsu ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 8 ++- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 3 ++ - .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 57 ++++++++++++++++++++-- - 3 files changed, 62 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -1357,7 +1357,13 @@ static int link_state_update(struct dpaa - bool tx_pause; - int err; - -- err = dpni_get_link_state(priv->mc_io, 0, priv->mc_token, &state); -+ if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_LINK_AUTONEG_VER_MAJOR, -+ DPNI_LINK_AUTONEG_VER_MINOR) < 0) -+ err = dpni_get_link_state(priv->mc_io, 0, priv->mc_token, -+ &state); -+ else -+ err = dpni_get_link_state_v2(priv->mc_io, 0, priv->mc_token, -+ &state); - if (unlikely(err)) { - netdev_err(priv->net_dev, - "dpni_get_link_state() failed\n"); ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -543,6 +543,9 @@ static inline bool dpaa2_eth_rx_pause_en - return !!(link_options & DPNI_LINK_OPT_PAUSE); - } - -+#define DPNI_LINK_AUTONEG_VER_MAJOR 7 -+#define DPNI_LINK_AUTONEG_VER_MINOR 8 -+ - static inline - unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv, - struct sk_buff *skb) ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c -@@ -79,6 +79,41 @@ static void dpaa2_eth_get_drvinfo(struct - sizeof(drvinfo->bus_info)); - } - -+struct dpaa2_eth_link_mode_map { -+ u64 dpni_lm; -+ u64 ethtool_lm; -+}; -+ -+static const struct dpaa2_eth_link_mode_map dpaa2_eth_lm_map[] = { -+ {DPNI_ADVERTISED_10BASET_FULL, ETHTOOL_LINK_MODE_10baseT_Full_BIT}, -+ {DPNI_ADVERTISED_100BASET_FULL, ETHTOOL_LINK_MODE_100baseT_Full_BIT}, -+ {DPNI_ADVERTISED_1000BASET_FULL, ETHTOOL_LINK_MODE_1000baseT_Full_BIT}, -+ {DPNI_ADVERTISED_10000BASET_FULL, ETHTOOL_LINK_MODE_10000baseT_Full_BIT}, -+ {DPNI_ADVERTISED_2500BASEX_FULL, ETHTOOL_LINK_MODE_2500baseT_Full_BIT}, -+ {DPNI_ADVERTISED_AUTONEG, ETHTOOL_LINK_MODE_Autoneg_BIT}, -+}; -+ -+static void link_mode_dpni2ethtool(u64 dpni_lm, unsigned long *ethtool_lm) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dpaa2_eth_lm_map); i++) { -+ if (dpni_lm & dpaa2_eth_lm_map[i].dpni_lm) -+ __set_bit(dpaa2_eth_lm_map[i].ethtool_lm, ethtool_lm); -+ } -+} -+ -+static void link_mode_ethtool2dpni(const unsigned long *ethtool_lm, -+ u64 *dpni_lm) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dpaa2_eth_lm_map); i++) { -+ if (test_bit(dpaa2_eth_lm_map[i].ethtool_lm, ethtool_lm)) -+ *dpni_lm |= dpaa2_eth_lm_map[i].dpni_lm; -+ } -+} -+ - static int - dpaa2_eth_get_link_ksettings(struct net_device *net_dev, - struct ethtool_link_ksettings *link_settings) -@@ -91,6 +126,14 @@ dpaa2_eth_get_link_ksettings(struct net_ - link_settings->base.duplex = DUPLEX_FULL; - link_settings->base.speed = priv->link_state.rate; - -+ if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_LINK_AUTONEG_VER_MAJOR, -+ DPNI_LINK_AUTONEG_VER_MINOR) >= 0) { -+ link_mode_dpni2ethtool(priv->link_state.supported, -+ link_settings->link_modes.supported); -+ link_mode_dpni2ethtool(priv->link_state.advertising, -+ link_settings->link_modes.advertising); -+ } -+ - return 0; - } - -@@ -127,12 +170,16 @@ dpaa2_eth_set_link_ksettings(struct net_ - else - cfg.options &= ~DPNI_LINK_OPT_HALF_DUPLEX; - -- err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg); -+ if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_LINK_AUTONEG_VER_MAJOR, -+ DPNI_LINK_AUTONEG_VER_MINOR) < 0) { -+ err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg); -+ } else { -+ link_mode_ethtool2dpni(link_settings->link_modes.advertising, -+ &cfg.advertising); -+ dpni_set_link_cfg_v2(priv->mc_io, 0, priv->mc_token, &cfg); -+ } - if (err) -- /* ethtool will be loud enough if we return an error; no point -- * in putting our own error message on the console by default -- */ -- netdev_dbg(net_dev, "ERROR %d setting link cfg\n", err); -+ netdev_err(net_dev, "dpni_set_link_cfg failed"); - - return err; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0217-dpaa2-eth-Don-t-use-netif_receive_skb_list-for-TCP-f.patch b/target/linux/layerscape/patches-5.4/701-net-0217-dpaa2-eth-Don-t-use-netif_receive_skb_list-for-TCP-f.patch deleted file mode 100644 index 74b4b6d3c0..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0217-dpaa2-eth-Don-t-use-netif_receive_skb_list-for-TCP-f.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 01e74b70dd8183aa191cd594ec9fa2879357811f Mon Sep 17 00:00:00 2001 -From: Ioana Radulescu -Date: Mon, 22 Jul 2019 18:52:39 +0300 -Subject: [PATCH] dpaa2-eth: Don't use netif_receive_skb_list for TCP frames - -Using Rx skb bulking for all frames may negatively impact the -performance in some TCP termination scenarios, as it effectively -bypasses GRO. - -Look at the hardware parse results of each ingress frame to see -if a TCP header is present or not; for TCP frames fall back to -the old implementation. - -Signed-off-by: Ioana Radulescu -Signed-off-by: Vladimir Oltean ---- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 15 ++++++- - drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 51 ++++++++++++++++++++++++ - 2 files changed, 65 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c -@@ -353,6 +353,16 @@ out: - return xdp_act; - } - -+static bool frame_is_tcp(const struct dpaa2_fd *fd, struct dpaa2_fas *fas) -+{ -+ struct dpaa2_fapr *fapr = dpaa2_get_fapr(fas, false); -+ -+ if (!(dpaa2_fd_get_frc(fd) & DPAA2_FD_FRC_FAPRV)) -+ return false; -+ -+ return !!(fapr->faf_hi & DPAA2_FAF_HI_TCP_PRESENT); -+} -+ - /* Main Rx frame processing routine */ - static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, - struct dpaa2_eth_channel *ch, -@@ -440,7 +450,10 @@ static void dpaa2_eth_rx(struct dpaa2_et - percpu_stats->rx_packets++; - percpu_stats->rx_bytes += dpaa2_fd_get_len(fd); - -- list_add_tail(&skb->list, ch->rx_list); -+ if (frame_is_tcp(fd, fas)) -+ napi_gro_receive(&ch->napi, skb); -+ else -+ list_add_tail(&skb->list, ch->rx_list); - - return; - ---- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h -@@ -178,6 +178,49 @@ struct dpaa2_fas { - */ - #define DPAA2_TS_OFFSET 0x8 - -+/* Frame annotation parse results */ -+struct dpaa2_fapr { -+ /* 64-bit word 1 */ -+ __le32 faf_lo; -+ __le16 faf_ext; -+ __le16 nxt_hdr; -+ /* 64-bit word 2 */ -+ __le64 faf_hi; -+ /* 64-bit word 3 */ -+ u8 last_ethertype_offset; -+ u8 vlan_tci_offset_n; -+ u8 vlan_tci_offset_1; -+ u8 llc_snap_offset; -+ u8 eth_offset; -+ u8 ip1_pid_offset; -+ u8 shim_offset_2; -+ u8 shim_offset_1; -+ /* 64-bit word 4 */ -+ u8 l5_offset; -+ u8 l4_offset; -+ u8 gre_offset; -+ u8 l3_offset_n; -+ u8 l3_offset_1; -+ u8 mpls_offset_n; -+ u8 mpls_offset_1; -+ u8 pppoe_offset; -+ /* 64-bit word 5 */ -+ __le16 running_sum; -+ __le16 gross_running_sum; -+ u8 ipv6_frag_offset; -+ u8 nxt_hdr_offset; -+ u8 routing_hdr_offset_2; -+ u8 routing_hdr_offset_1; -+ /* 64-bit word 6 */ -+ u8 reserved[5]; /* Soft-parsing context */ -+ u8 ip_proto_offset_n; -+ u8 nxt_hdr_frag_offset; -+ u8 parse_error_code; -+}; -+ -+#define DPAA2_FAPR_OFFSET 0x10 -+#define DPAA2_FAPR_SIZE sizeof((struct dpaa2_fapr)) -+ - /* Frame annotation egress action descriptor */ - #define DPAA2_FAEAD_OFFSET 0x58 - -@@ -208,6 +251,11 @@ static inline __le64 *dpaa2_get_ts(void - return dpaa2_get_hwa(buf_addr, swa) + DPAA2_TS_OFFSET; - } - -+static inline struct dpaa2_fapr *dpaa2_get_fapr(void *buf_addr, bool swa) -+{ -+ return dpaa2_get_hwa(buf_addr, swa) + DPAA2_FAPR_OFFSET; -+} -+ - static inline struct dpaa2_faead *dpaa2_get_faead(void *buf_addr, bool swa) - { - return dpaa2_get_hwa(buf_addr, swa) + DPAA2_FAEAD_OFFSET; -@@ -259,6 +307,9 @@ static inline struct dpaa2_faead *dpaa2_ - DPAA2_FAS_L3CE | \ - DPAA2_FAS_L4CE) - -+/* TCP indication in Frame Annotation Parse Results */ -+#define DPAA2_FAF_HI_TCP_PRESENT BIT(23) -+ - /* Time in milliseconds between link state updates */ - #define DPAA2_ETH_LINK_STATE_REFRESH 1000 - diff --git a/target/linux/layerscape/patches-5.4/701-net-0218-bus-fsl-mc-Add-a-new-parameter-to-dprc_scan_objects-.patch b/target/linux/layerscape/patches-5.4/701-net-0218-bus-fsl-mc-Add-a-new-parameter-to-dprc_scan_objects-.patch deleted file mode 100644 index 0fbf3d212d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0218-bus-fsl-mc-Add-a-new-parameter-to-dprc_scan_objects-.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 653fc2595283df6deb92ca3058c8d5dc1e129e91 Mon Sep 17 00:00:00 2001 -From: Diana Craciun -Date: Fri, 13 Sep 2019 17:17:30 +0300 -Subject: [PATCH] bus/fsl-mc: Add a new parameter to dprc_scan_objects function - -Prepare the dprc_scan_objects function to be used by -the VFIO mc driver code. The function is used to scan the mc -objects by the bus driver. The same functionality is -needed by the VFIO mc driver, but in this case the -interrupt configuration is delayed until the userspace -configures them. In order to use the same function in both -drivers add a new parameter. - -Signed-off-by: Diana Craciun ---- - drivers/bus/fsl-mc/dprc-driver.c | 33 +++++++++++++++++++-------------- - drivers/bus/fsl-mc/fsl-mc-bus.c | 2 +- - include/linux/fsl/mc.h | 1 + - 3 files changed, 21 insertions(+), 15 deletions(-) - ---- a/drivers/bus/fsl-mc/dprc-driver.c -+++ b/drivers/bus/fsl-mc/dprc-driver.c -@@ -3,6 +3,7 @@ - * Freescale data path resource container (DPRC) driver - * - * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. -+ * Copyright 2019 NXP - * Author: German Rivera - * - */ -@@ -204,6 +205,8 @@ static void dprc_add_new_devices(struct - * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object - * @driver_override: driver override to apply to new objects found in the - * DPRC, or NULL, if none. -+ * @alloc_interrupts: if true the function allocates the interrupt pool, -+ * otherwise the interrupt allocation is delayed - * @total_irq_count: If argument is provided the function populates the - * total number of IRQs created by objects in the DPRC. - * -@@ -221,6 +224,7 @@ static void dprc_add_new_devices(struct - */ - int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, - const char *driver_override, -+ bool alloc_interrupts, - unsigned int *total_irq_count) - { - int num_child_objects; -@@ -302,19 +306,20 @@ int dprc_scan_objects(struct fsl_mc_devi - * Allocate IRQ's before binding the scanned devices with their - * respective drivers. - */ -- if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) { -- if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) { -- dev_warn(&mc_bus_dev->dev, -- "IRQs needed (%u) exceed IRQs preallocated (%u)\n", -- irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); -- } -+ if (alloc_interrupts) { -+ if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) { -+ if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) { -+ dev_warn(&mc_bus_dev->dev, -+ "IRQs needed (%u) exceed IRQs preallocated (%u)\n", -+ irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); -+ } - -- error = fsl_mc_populate_irq_pool(mc_bus, -- FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); -- if (error < 0) -- return error; -+ error = fsl_mc_populate_irq_pool(mc_bus, -+ FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); -+ if (error < 0) -+ return error; -+ } - } -- - if (total_irq_count) - *total_irq_count = irq_count; - -@@ -350,7 +355,7 @@ static int dprc_scan_container(struct fs - * Discover objects in the DPRC: - */ - mutex_lock(&mc_bus->scan_mutex); -- error = dprc_scan_objects(mc_bus_dev, NULL, NULL); -+ error = dprc_scan_objects(mc_bus_dev, NULL, true, NULL); - mutex_unlock(&mc_bus->scan_mutex); - if (error < 0) { - fsl_mc_cleanup_all_resource_pools(mc_bus_dev); -@@ -379,7 +384,7 @@ static ssize_t rescan_store(struct devic - - if (val) { - mutex_lock(&root_mc_bus->scan_mutex); -- dprc_scan_objects(root_mc_dev, NULL, NULL); -+ dprc_scan_objects(root_mc_dev, NULL, true, NULL); - mutex_unlock(&root_mc_bus->scan_mutex); - } - -@@ -448,7 +453,7 @@ static irqreturn_t dprc_irq0_handler_thr - DPRC_IRQ_EVENT_OBJ_CREATED)) { - unsigned int irq_count; - -- error = dprc_scan_objects(mc_dev, NULL, &irq_count); -+ error = dprc_scan_objects(mc_dev, NULL, true, &irq_count); - if (error < 0) { - /* - * If the error is -ENXIO, we ignore it, as it indicates ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -215,7 +215,7 @@ static int scan_fsl_mc_bus(struct device - root_mc_dev = to_fsl_mc_device(dev); - root_mc_bus = to_fsl_mc_bus(root_mc_dev); - mutex_lock(&root_mc_bus->scan_mutex); -- dprc_scan_objects(root_mc_dev, NULL, NULL); -+ dprc_scan_objects(root_mc_dev, NULL, true, NULL); - mutex_unlock(&root_mc_bus->scan_mutex); - - exit: ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -1010,6 +1010,7 @@ struct fsl_mc_bus { - - int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, - const char *driver_override, -+ bool alloc_interrupts, - unsigned int *total_irq_count); - - int fsl_mc_find_msi_domain(struct device *mc_platform_dev, diff --git a/target/linux/layerscape/patches-5.4/701-net-0219-bus-fsl-mc-Extend-functions-from-the-bus-driver-to-b.patch b/target/linux/layerscape/patches-5.4/701-net-0219-bus-fsl-mc-Extend-functions-from-the-bus-driver-to-b.patch deleted file mode 100644 index 8fcdac5604..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0219-bus-fsl-mc-Extend-functions-from-the-bus-driver-to-b.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 49878e0759161d357782802f954886bae7bcc83b Mon Sep 17 00:00:00 2001 -From: Diana Craciun -Date: Thu, 21 Nov 2019 15:06:47 +0200 -Subject: [PATCH] bus/fsl-mc: Extend functions from the bus driver to be used - by vfio-mc - -The bus/dpcr driver use some common functions, export those -functions to be accessible from the vfio-mc driver. - -Signed-off-by: Diana Craciun ---- - drivers/bus/fsl-mc/fsl-mc-private.h | 8 -------- - include/linux/fsl/mc.h | 8 ++++++++ - 2 files changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/bus/fsl-mc/fsl-mc-private.h -+++ b/drivers/bus/fsl-mc/fsl-mc-private.h -@@ -182,14 +182,6 @@ int fsl_mc_msi_domain_alloc_irqs(struct - - void fsl_mc_msi_domain_free_irqs(struct device *dev); - --int __must_check fsl_create_mc_io(struct device *dev, -- phys_addr_t mc_portal_phys_addr, -- u32 mc_portal_size, -- struct fsl_mc_device *dpmcp_dev, -- u32 flags, struct fsl_mc_io **new_mc_io); -- --void fsl_destroy_mc_io(struct fsl_mc_io *mc_io); -- - bool fsl_mc_is_root_dprc(struct device *dev); - - #ifdef CONFIG_FSL_MC_UAPI_SUPPORT ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -1013,6 +1013,14 @@ int dprc_scan_objects(struct fsl_mc_devi - bool alloc_interrupts, - unsigned int *total_irq_count); - -+int __must_check fsl_create_mc_io(struct device *dev, -+ phys_addr_t mc_portal_phys_addr, -+ u32 mc_portal_size, -+ struct fsl_mc_device *dpmcp_dev, -+ u32 flags, struct fsl_mc_io **new_mc_io); -+ -+void fsl_destroy_mc_io(struct fsl_mc_io *mc_io); -+ - int fsl_mc_find_msi_domain(struct device *mc_platform_dev, - struct irq_domain **mc_msi_domain); - diff --git a/target/linux/layerscape/patches-5.4/701-net-0220-bus-fsl-mc-Set-the-QMAN-BMAN-region-flags.patch b/target/linux/layerscape/patches-5.4/701-net-0220-bus-fsl-mc-Set-the-QMAN-BMAN-region-flags.patch deleted file mode 100644 index f4f53b2bf6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0220-bus-fsl-mc-Set-the-QMAN-BMAN-region-flags.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 3c771fc6111d2703274d269b2b34183ce8be4df4 Mon Sep 17 00:00:00 2001 -From: Diana Craciun -Date: Mon, 18 Nov 2019 11:37:59 +0200 -Subject: [PATCH] bus/fsl-mc: Set the QMAN/BMAN region flags - -The QMAN region can be memory mapped, so it should be -of type IORESOURCE_MEM. Also use the bus specific bits -in order to pass additional information about the region. - -Signed-off-by: Diana Craciun ---- - drivers/bus/fsl-mc/fsl-mc-bus.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -627,11 +627,8 @@ static int fsl_mc_device_get_mmio_region - - regions[i].end = regions[i].start + region_desc.size - 1; - regions[i].name = "fsl-mc object MMIO region"; -- regions[i].flags = IORESOURCE_IO; -- if (region_desc.flags & DPRC_REGION_CACHEABLE) -- regions[i].flags |= IORESOURCE_CACHEABLE; -- if (region_desc.flags & DPRC_REGION_SHAREABLE) -- regions[i].flags |= IORESOURCE_MEM; -+ regions[i].flags = region_desc.flags & IORESOURCE_BITS; -+ regions[i].flags |= IORESOURCE_MEM; - } - - mc_dev->regions = regions; diff --git a/target/linux/layerscape/patches-5.4/701-net-0221-soc-fsl-dpio-Adding-QMAN-multiple-enqueue-interface.patch b/target/linux/layerscape/patches-5.4/701-net-0221-soc-fsl-dpio-Adding-QMAN-multiple-enqueue-interface.patch deleted file mode 100644 index 3c76eefe71..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0221-soc-fsl-dpio-Adding-QMAN-multiple-enqueue-interface.patch +++ /dev/null @@ -1,304 +0,0 @@ -From 1da6ba0350da068295d5bc5556193b21da38a388 Mon Sep 17 00:00:00 2001 -From: Youri Querry -Date: Mon, 4 Nov 2019 10:32:37 -0500 -Subject: [PATCH] soc: fsl: dpio: Adding QMAN multiple enqueue interface. - -Update of QMAN the interface to enqueue frame. We now support multiple -enqueue (qbman_swp_enqueue_multiple) and multiple enqueue with -a table of descriptor (qbman_swp_enqueue_multiple_desc). - -Signed-off-by: Youri Querry ---- - drivers/soc/fsl/dpio/dpio-service.c | 69 ++++++++++++++++++++++++++++++++-- - drivers/soc/fsl/dpio/qbman-portal.c | 75 +++++++++++++++++++++++++++++++------ - drivers/soc/fsl/dpio/qbman-portal.h | 17 +++++++++ - include/soc/fsl/dpaa2-io.h | 6 ++- - 4 files changed, 152 insertions(+), 15 deletions(-) - ---- a/drivers/soc/fsl/dpio/dpio-service.c -+++ b/drivers/soc/fsl/dpio/dpio-service.c -@@ -1,7 +1,7 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) - /* - * Copyright 2014-2016 Freescale Semiconductor Inc. -- * Copyright 2016 NXP -+ * Copyright 2016-2019 NXP - * - */ - #include -@@ -437,6 +437,69 @@ int dpaa2_io_service_enqueue_fq(struct d - EXPORT_SYMBOL(dpaa2_io_service_enqueue_fq); - - /** -+ * dpaa2_io_service_enqueue_multiple_fq() - Enqueue multiple frames -+ * to a frame queue using one fqid. -+ * @d: the given DPIO service. -+ * @fqid: the given frame queue id. -+ * @fd: the frame descriptor which is enqueued. -+ * @nb: number of frames to be enqueud -+ * -+ * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready, -+ * or -ENODEV if there is no dpio service. -+ */ -+int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d, -+ u32 fqid, -+ const struct dpaa2_fd *fd, -+ int nb) -+{ -+ struct qbman_eq_desc ed; -+ -+ d = service_select(d); -+ if (!d) -+ return -ENODEV; -+ -+ qbman_eq_desc_clear(&ed); -+ qbman_eq_desc_set_no_orp(&ed, 0); -+ qbman_eq_desc_set_fq(&ed, fqid); -+ -+ return qbman_swp_enqueue_multiple(d->swp, &ed, fd, 0, nb); -+} -+EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_fq); -+ -+/** -+ * dpaa2_io_service_enqueue_multiple_desc_fq() - Enqueue multiple frames -+ * to different frame queue using a list of fqids. -+ * @d: the given DPIO service. -+ * @fqid: the given list of frame queue ids. -+ * @fd: the frame descriptor which is enqueued. -+ * @nb: number of frames to be enqueud -+ * -+ * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready, -+ * or -ENODEV if there is no dpio service. -+ */ -+int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d, -+ u32 *fqid, -+ const struct dpaa2_fd *fd, -+ int nb) -+{ -+ int i; -+ struct qbman_eq_desc ed[32]; -+ -+ d = service_select(d); -+ if (!d) -+ return -ENODEV; -+ -+ for (i = 0; i < nb; i++) { -+ qbman_eq_desc_clear(&ed[i]); -+ qbman_eq_desc_set_no_orp(&ed[i], 0); -+ qbman_eq_desc_set_fq(&ed[i], fqid[i]); -+ } -+ -+ return qbman_swp_enqueue_multiple_desc(d->swp, &ed[0], fd, nb); -+} -+EXPORT_SYMBOL(dpaa2_io_service_enqueue_multiple_desc_fq); -+ -+/** - * dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD. - * @d: the given DPIO service. - * @qdid: the given queuing destination id. -@@ -530,7 +593,7 @@ EXPORT_SYMBOL_GPL(dpaa2_io_service_acqui - - /** - * dpaa2_io_store_create() - Create the dma memory storage for dequeue result. -- * @max_frames: the maximum number of dequeued result for frames, must be <= 16. -+ * @max_frames: the maximum number of dequeued result for frames, must be <= 32. - * @dev: the device to allow mapping/unmapping the DMAable region. - * - * The size of the storage is "max_frames*sizeof(struct dpaa2_dq)". -@@ -545,7 +608,7 @@ struct dpaa2_io_store *dpaa2_io_store_cr - struct dpaa2_io_store *ret; - size_t size; - -- if (!max_frames || (max_frames > 16)) -+ if (!max_frames || (max_frames > 32)) - return NULL; - - ret = kmalloc(sizeof(*ret), GFP_KERNEL); ---- a/drivers/soc/fsl/dpio/qbman-portal.c -+++ b/drivers/soc/fsl/dpio/qbman-portal.c -@@ -1,7 +1,7 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) - /* - * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. -- * Copyright 2016 NXP -+ * Copyright 2016-2019 NXP - * - */ - -@@ -86,7 +86,7 @@ enum qbman_sdqcr_fc { - - #define dccvac(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); } - #define dcivac(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); } --static inline void qbman_inval_prefetch(struct qbman_swp *p, uint32_t offset) -+static inline void qbman_inval_prefetch(struct qbman_swp *p, u32 offset) - { - dcivac(p->addr_cena + offset); - prefetch(p->addr_cena + offset); -@@ -158,7 +158,7 @@ static inline u32 qbman_set_swp_cfg(u8 m - */ - struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) - { -- struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL); -+ struct qbman_swp *p = kzalloc(sizeof(*p), GFP_KERNEL); - u32 reg; - - if (!p) -@@ -380,7 +380,6 @@ enum qb_enqueue_commands { - }; - - #define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT 2 --#define QB_ENQUEUE_CMD_IRQ_ON_DISPATCH_SHIFT 3 - #define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT 4 - - /** -@@ -508,7 +507,7 @@ static inline void qbman_write_eqcr_am_r - int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d, - const struct dpaa2_fd *fd) - { -- struct qbman_eq_desc *p; -+ struct qbman_eq_desc_with_fd *p; - u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR); - - if (!EQAR_SUCCESS(eqar)) -@@ -522,19 +521,19 @@ int qbman_swp_enqueue(struct qbman_swp * - * desc.orpid address alignment = 4 - * desc.tgtid address alignment = 8 - */ -- p->dca = d->dca; -- p->seqnum = d->seqnum; -- p->orpid = d->orpid; -- memcpy(&p->tgtid, &d->tgtid, 24); -+ p->desc.dca = d->dca; -+ p->desc.seqnum = d->seqnum; -+ p->desc.orpid = d->orpid; -+ memcpy(&p->desc.tgtid, &d->tgtid, 24); - memcpy(&p->fd, fd, sizeof(*fd)); - - if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { - /* Set the verb byte, have to substitute in the valid-bit */ - dma_wmb(); -- p->verb = d->verb | EQAR_VB(eqar); -+ p->desc.verb = d->verb | EQAR_VB(eqar); - dccvac(p); - } else { -- p->verb = d->verb | EQAR_VB(eqar); -+ p->desc.verb = d->verb | EQAR_VB(eqar); - dma_wmb(); - qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar)); - } -@@ -542,6 +541,60 @@ int qbman_swp_enqueue(struct qbman_swp * - return 0; - } - -+/** -+ * qbman_swp_enqueue_multiple() - Issue a multi enqueue command -+ * using one enqueue descriptor -+ * @s: the software portal used for enqueue -+ * @d: the enqueue descriptor -+ * @fd: table pointer of frame descriptor table to be enqueued -+ * @flags: table pointer of flags, not used for the moment -+ * @num_frames: number of fd to be enqueued -+ * -+ * Return the number of fd enqueued, or a negative error number. -+ */ -+int qbman_swp_enqueue_multiple(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ uint32_t *flags, -+ int num_frames) -+{ -+ int count = 0; -+ -+ while (count < num_frames) { -+ if (qbman_swp_enqueue(s, d, fd) != 0) -+ break; -+ count++; -+ } -+ -+ return count; -+} -+ -+/** -+ * qbman_swp_enqueue_multiple_desc() - Issue a multi enqueue command -+ * using multiple enqueue descriptor -+ * @s: the software portal used for enqueue -+ * @d: table of minimal enqueue descriptor -+ * @fd: table pointer of frame descriptor table to be enqueued -+ * @num_frames: number of fd to be enqueued -+ * -+ * Return the number of fd enqueued, or a negative error number. -+ */ -+int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ int num_frames) -+{ -+ int count = 0; -+ -+ while (count < num_frames) { -+ if (qbman_swp_enqueue(s, &(d[count]), fd) != 0) -+ break; -+ count++; -+ } -+ -+ return count; -+} -+ - /* Static (push) dequeue */ - - /** ---- a/drivers/soc/fsl/dpio/qbman-portal.h -+++ b/drivers/soc/fsl/dpio/qbman-portal.h -@@ -88,6 +88,10 @@ struct qbman_eq_desc { - u8 wae; - u8 rspid; - __le64 rsp_addr; -+}; -+ -+struct qbman_eq_desc_with_fd { -+ struct qbman_eq_desc desc; - u8 fd[32]; - }; - -@@ -205,6 +209,19 @@ void *qbman_swp_mc_start(struct qbman_sw - void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb); - void *qbman_swp_mc_result(struct qbman_swp *p); - -+int -+qbman_swp_enqueue_multiple(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ uint32_t *flags, -+ int num_frames); -+ -+int -+qbman_swp_enqueue_multiple_desc(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ int num_frames); -+ - /** - * qbman_result_is_DQ() - check if the dequeue result is a dequeue response - * @dq: the dequeue result to be checked ---- a/include/soc/fsl/dpaa2-io.h -+++ b/include/soc/fsl/dpaa2-io.h -@@ -1,7 +1,7 @@ - /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ - /* - * Copyright 2014-2016 Freescale Semiconductor Inc. -- * Copyright 2017 NXP -+ * Copyright 2017-2019 NXP - * - */ - #ifndef __FSL_DPAA2_IO_H -@@ -109,6 +109,10 @@ int dpaa2_io_service_pull_channel(struct - - int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d, u32 fqid, - const struct dpaa2_fd *fd); -+int dpaa2_io_service_enqueue_multiple_fq(struct dpaa2_io *d, u32 fqid, -+ const struct dpaa2_fd *fd, int number_of_frame); -+int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d, u32 *fqid, -+ const struct dpaa2_fd *fd, int number_of_frame); - int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, u32 qdid, u8 prio, - u16 qdbin, const struct dpaa2_fd *fd); - int dpaa2_io_service_release(struct dpaa2_io *d, u16 bpid, diff --git a/target/linux/layerscape/patches-5.4/701-net-0222-soc-fsl-dpio-QMAN-performance-improvement.-Function-.patch b/target/linux/layerscape/patches-5.4/701-net-0222-soc-fsl-dpio-QMAN-performance-improvement.-Function-.patch deleted file mode 100644 index 79606f7beb..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0222-soc-fsl-dpio-QMAN-performance-improvement.-Function-.patch +++ /dev/null @@ -1,789 +0,0 @@ -From 5c88fa1440b2e4d0bdd46dad5370eb8c2181951b Mon Sep 17 00:00:00 2001 -From: Youri Querry -Date: Mon, 4 Nov 2019 11:00:24 -0500 -Subject: [PATCH] soc: fsl: dpio: QMAN performance improvement. Function - pointer indirection. - -We are making the access decision in the initialization and -setting the function pointers accordingly. - -Signed-off-by: Youri Querry ---- - drivers/soc/fsl/dpio/qbman-portal.c | 455 ++++++++++++++++++++++++++++++------ - drivers/soc/fsl/dpio/qbman-portal.h | 130 ++++++++++- - 2 files changed, 508 insertions(+), 77 deletions(-) - ---- a/drivers/soc/fsl/dpio/qbman-portal.c -+++ b/drivers/soc/fsl/dpio/qbman-portal.c -@@ -84,6 +84,82 @@ enum qbman_sdqcr_fc { - qbman_sdqcr_fc_up_to_3 = 1 - }; - -+/* Internal Function declaration */ -+static int qbman_swp_enqueue_direct(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd); -+static int qbman_swp_enqueue_mem_back(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd); -+static int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ uint32_t *flags, -+ int num_frames); -+static int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ uint32_t *flags, -+ int num_frames); -+static int -+qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ int num_frames); -+static -+int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ int num_frames); -+static int qbman_swp_pull_direct(struct qbman_swp *s, -+ struct qbman_pull_desc *d); -+static int qbman_swp_pull_mem_back(struct qbman_swp *s, -+ struct qbman_pull_desc *d); -+ -+const struct dpaa2_dq *qbman_swp_dqrr_next_direct(struct qbman_swp *s); -+const struct dpaa2_dq *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s); -+ -+static int qbman_swp_release_direct(struct qbman_swp *s, -+ const struct qbman_release_desc *d, -+ const u64 *buffers, -+ unsigned int num_buffers); -+static int qbman_swp_release_mem_back(struct qbman_swp *s, -+ const struct qbman_release_desc *d, -+ const u64 *buffers, -+ unsigned int num_buffers); -+ -+/* Function pointers */ -+int (*qbman_swp_enqueue_ptr)(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd) -+ = qbman_swp_enqueue_direct; -+ -+int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ uint32_t *flags, -+ int num_frames) -+ = qbman_swp_enqueue_multiple_direct; -+ -+int -+(*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ int num_frames) -+ = qbman_swp_enqueue_multiple_desc_direct; -+ -+int (*qbman_swp_pull_ptr)(struct qbman_swp *s, struct qbman_pull_desc *d) -+ = qbman_swp_pull_direct; -+ -+const struct dpaa2_dq *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s) -+ = qbman_swp_dqrr_next_direct; -+ -+int (*qbman_swp_release_ptr)(struct qbman_swp *s, -+ const struct qbman_release_desc *d, -+ const u64 *buffers, -+ unsigned int num_buffers) -+ = qbman_swp_release_direct; -+ - #define dccvac(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); } - #define dcivac(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); } - static inline void qbman_inval_prefetch(struct qbman_swp *p, u32 offset) -@@ -227,6 +303,19 @@ struct qbman_swp *qbman_swp_init(const s - * applied when dequeues from a specific channel are enabled. - */ - qbman_write_register(p, QBMAN_CINH_SWP_SDQCR, 0); -+ -+ if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) { -+ qbman_swp_enqueue_ptr = -+ qbman_swp_enqueue_mem_back; -+ qbman_swp_enqueue_multiple_ptr = -+ qbman_swp_enqueue_multiple_mem_back; -+ qbman_swp_enqueue_multiple_desc_ptr = -+ qbman_swp_enqueue_multiple_desc_mem_back; -+ qbman_swp_pull_ptr = qbman_swp_pull_mem_back; -+ qbman_swp_dqrr_next_ptr = qbman_swp_dqrr_next_mem_back; -+ qbman_swp_release_ptr = qbman_swp_release_mem_back; -+ } -+ - return p; - } - -@@ -494,7 +583,7 @@ static inline void qbman_write_eqcr_am_r - } - - /** -- * qbman_swp_enqueue() - Issue an enqueue command -+ * qbman_swp_enqueue_direct() - Issue an enqueue command - * @s: the software portal used for enqueue - * @d: the enqueue descriptor - * @fd: the frame descriptor to be enqueued -@@ -504,7 +593,7 @@ static inline void qbman_write_eqcr_am_r - * - * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready. - */ --int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d, -+int qbman_swp_enqueue_direct(struct qbman_swp *s, const struct qbman_eq_desc *d, - const struct dpaa2_fd *fd) - { - struct qbman_eq_desc_with_fd *p; -@@ -527,22 +616,58 @@ int qbman_swp_enqueue(struct qbman_swp * - memcpy(&p->desc.tgtid, &d->tgtid, 24); - memcpy(&p->fd, fd, sizeof(*fd)); - -- if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { -- /* Set the verb byte, have to substitute in the valid-bit */ -- dma_wmb(); -- p->desc.verb = d->verb | EQAR_VB(eqar); -- dccvac(p); -- } else { -- p->desc.verb = d->verb | EQAR_VB(eqar); -- dma_wmb(); -- qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar)); -- } -+ /* Set the verb byte, have to substitute in the valid-bit */ -+ dma_wmb(); -+ p->desc.verb = d->verb | EQAR_VB(eqar); -+ dccvac(p); - - return 0; - } - - /** -- * qbman_swp_enqueue_multiple() - Issue a multi enqueue command -+ * qbman_swp_enqueue_mem_back() - Issue an enqueue command -+ * @s: the software portal used for enqueue -+ * @d: the enqueue descriptor -+ * @fd: the frame descriptor to be enqueued -+ * -+ * Please note that 'fd' should only be NULL if the "action" of the -+ * descriptor is "orp_hole" or "orp_nesn". -+ * -+ * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready. -+ */ -+int qbman_swp_enqueue_mem_back(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd) -+{ -+ struct qbman_eq_desc_with_fd *p; -+ u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR); -+ -+ if (!EQAR_SUCCESS(eqar)) -+ return -EBUSY; -+ -+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar))); -+ /* This is mapped as DEVICE type memory, writes are -+ * with address alignment: -+ * desc.dca address alignment = 1 -+ * desc.seqnum address alignment = 2 -+ * desc.orpid address alignment = 4 -+ * desc.tgtid address alignment = 8 -+ */ -+ p->desc.dca = d->dca; -+ p->desc.seqnum = d->seqnum; -+ p->desc.orpid = d->orpid; -+ memcpy(&p->desc.tgtid, &d->tgtid, 24); -+ memcpy(&p->fd, fd, sizeof(*fd)); -+ -+ p->desc.verb = d->verb | EQAR_VB(eqar); -+ dma_wmb(); -+ qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar)); -+ -+ return 0; -+} -+ -+/** -+ * qbman_swp_enqueue_multiple_direct() - Issue a multi enqueue command - * using one enqueue descriptor - * @s: the software portal used for enqueue - * @d: the enqueue descriptor -@@ -552,16 +677,16 @@ int qbman_swp_enqueue(struct qbman_swp * - * - * Return the number of fd enqueued, or a negative error number. - */ --int qbman_swp_enqueue_multiple(struct qbman_swp *s, -- const struct qbman_eq_desc *d, -- const struct dpaa2_fd *fd, -- uint32_t *flags, -- int num_frames) -+int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ uint32_t *flags, -+ int num_frames) - { - int count = 0; - - while (count < num_frames) { -- if (qbman_swp_enqueue(s, d, fd) != 0) -+ if (qbman_swp_enqueue_direct(s, d, fd) != 0) - break; - count++; - } -@@ -570,7 +695,35 @@ int qbman_swp_enqueue_multiple(struct qb - } - - /** -- * qbman_swp_enqueue_multiple_desc() - Issue a multi enqueue command -+ * qbman_swp_enqueue_multiple_mem_back() - Issue a multi enqueue command -+ * using one enqueue descriptor -+ * @s: the software portal used for enqueue -+ * @d: the enqueue descriptor -+ * @fd: table pointer of frame descriptor table to be enqueued -+ * @flags: table pointer of flags, not used for the moment -+ * @num_frames: number of fd to be enqueued -+ * -+ * Return the number of fd enqueued, or a negative error number. -+ */ -+int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ uint32_t *flags, -+ int num_frames) -+{ -+ int count = 0; -+ -+ while (count < num_frames) { -+ if (qbman_swp_enqueue_mem_back(s, d, fd) != 0) -+ break; -+ count++; -+ } -+ -+ return count; -+} -+ -+/** -+ * qbman_swp_enqueue_multiple_desc_direct() - Issue a multi enqueue command - * using multiple enqueue descriptor - * @s: the software portal used for enqueue - * @d: table of minimal enqueue descriptor -@@ -579,15 +732,41 @@ int qbman_swp_enqueue_multiple(struct qb - * - * Return the number of fd enqueued, or a negative error number. - */ --int qbman_swp_enqueue_multiple_desc(struct qbman_swp *s, -- const struct qbman_eq_desc *d, -- const struct dpaa2_fd *fd, -- int num_frames) -+int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ int num_frames) - { - int count = 0; - - while (count < num_frames) { -- if (qbman_swp_enqueue(s, &(d[count]), fd) != 0) -+ if (qbman_swp_enqueue_direct(s, &(d[count]), fd) != 0) -+ break; -+ count++; -+ } -+ -+ return count; -+} -+ -+/** -+ * qbman_swp_enqueue_multiple_desc_mem_back() - Issue a multi enqueue command -+ * using multiple enqueue descriptor -+ * @s: the software portal used for enqueue -+ * @d: table of minimal enqueue descriptor -+ * @fd: table pointer of frame descriptor table to be enqueued -+ * @num_frames: number of fd to be enqueued -+ * -+ * Return the number of fd enqueued, or a negative error number. -+ */ -+int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ int num_frames) -+{ -+ int count = 0; -+ -+ while (count < num_frames) { -+ if (qbman_swp_enqueue_mem_back(s, &(d[count]), fd) != 0) - break; - count++; - } -@@ -750,7 +929,7 @@ void qbman_pull_desc_set_channel(struct - } - - /** -- * qbman_swp_pull() - Issue the pull dequeue command -+ * qbman_swp_pull_direct() - Issue the pull dequeue command - * @s: the software portal object - * @d: the software portal descriptor which has been configured with - * the set of qbman_pull_desc_set_*() calls -@@ -758,7 +937,7 @@ void qbman_pull_desc_set_channel(struct - * Return 0 for success, and -EBUSY if the software portal is not ready - * to do pull dequeue. - */ --int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d) -+int qbman_swp_pull_direct(struct qbman_swp *s, struct qbman_pull_desc *d) - { - struct qbman_pull_desc *p; - -@@ -776,19 +955,46 @@ int qbman_swp_pull(struct qbman_swp *s, - p->dq_src = d->dq_src; - p->rsp_addr = d->rsp_addr; - p->rsp_addr_virt = d->rsp_addr_virt; -+ dma_wmb(); -+ /* Set the verb byte, have to substitute in the valid-bit */ -+ p->verb = d->verb | s->vdq.valid_bit; -+ s->vdq.valid_bit ^= QB_VALID_BIT; -+ dccvac(p); - -- if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { -- dma_wmb(); -- /* Set the verb byte, have to substitute in the valid-bit */ -- p->verb = d->verb | s->vdq.valid_bit; -- s->vdq.valid_bit ^= QB_VALID_BIT; -- dccvac(p); -- } else { -- p->verb = d->verb | s->vdq.valid_bit; -- s->vdq.valid_bit ^= QB_VALID_BIT; -- dma_wmb(); -- qbman_write_register(s, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE); -+ return 0; -+} -+ -+/** -+ * qbman_swp_pull_mem_back() - Issue the pull dequeue command -+ * @s: the software portal object -+ * @d: the software portal descriptor which has been configured with -+ * the set of qbman_pull_desc_set_*() calls -+ * -+ * Return 0 for success, and -EBUSY if the software portal is not ready -+ * to do pull dequeue. -+ */ -+int qbman_swp_pull_mem_back(struct qbman_swp *s, struct qbman_pull_desc *d) -+{ -+ struct qbman_pull_desc *p; -+ -+ if (!atomic_dec_and_test(&s->vdq.available)) { -+ atomic_inc(&s->vdq.available); -+ return -EBUSY; - } -+ s->vdq.storage = (void *)(uintptr_t)d->rsp_addr_virt; -+ if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) -+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR); -+ else -+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR_MEM); -+ p->numf = d->numf; -+ p->tok = QMAN_DQ_TOKEN_VALID; -+ p->dq_src = d->dq_src; -+ p->rsp_addr = d->rsp_addr; -+ p->rsp_addr_virt = d->rsp_addr_virt; -+ p->verb = d->verb | s->vdq.valid_bit; -+ s->vdq.valid_bit ^= QB_VALID_BIT; -+ dma_wmb(); -+ qbman_write_register(s, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE); - - return 0; - } -@@ -796,14 +1002,14 @@ int qbman_swp_pull(struct qbman_swp *s, - #define QMAN_DQRR_PI_MASK 0xf - - /** -- * qbman_swp_dqrr_next() - Get an valid DQRR entry -+ * qbman_swp_dqrr_next_direct() - Get an valid DQRR entry - * @s: the software portal object - * - * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry - * only once, so repeated calls can return a sequence of DQRR entries, without - * requiring they be consumed immediately or in any particular order. - */ --const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s) -+const struct dpaa2_dq *qbman_swp_dqrr_next_direct(struct qbman_swp *s) - { - u32 verb; - u32 response_verb; -@@ -845,10 +1051,97 @@ const struct dpaa2_dq *qbman_swp_dqrr_ne - qbman_inval_prefetch(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); - } - -- if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) -- p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); -- else -- p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx)); -+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); -+ verb = p->dq.verb; -+ -+ /* -+ * If the valid-bit isn't of the expected polarity, nothing there. Note, -+ * in the DQRR reset bug workaround, we shouldn't need to skip these -+ * check, because we've already determined that a new entry is available -+ * and we've invalidated the cacheline before reading it, so the -+ * valid-bit behaviour is repaired and should tell us what we already -+ * knew from reading PI. -+ */ -+ if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) { -+ qbman_inval_prefetch(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); -+ return NULL; -+ } -+ /* -+ * There's something there. Move "next_idx" attention to the next ring -+ * entry (and prefetch it) before returning what we found. -+ */ -+ s->dqrr.next_idx++; -+ s->dqrr.next_idx &= s->dqrr.dqrr_size - 1; /* Wrap around */ -+ if (!s->dqrr.next_idx) -+ s->dqrr.valid_bit ^= QB_VALID_BIT; -+ -+ /* -+ * If this is the final response to a volatile dequeue command -+ * indicate that the vdq is available -+ */ -+ flags = p->dq.stat; -+ response_verb = verb & QBMAN_RESULT_MASK; -+ if ((response_verb == QBMAN_RESULT_DQ) && -+ (flags & DPAA2_DQ_STAT_VOLATILE) && -+ (flags & DPAA2_DQ_STAT_EXPIRED)) -+ atomic_inc(&s->vdq.available); -+ -+ qbman_inval_prefetch(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); -+ -+ return p; -+} -+ -+/** -+ * qbman_swp_dqrr_next_mem_back() - Get an valid DQRR entry -+ * @s: the software portal object -+ * -+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry -+ * only once, so repeated calls can return a sequence of DQRR entries, without -+ * requiring they be consumed immediately or in any particular order. -+ */ -+const struct dpaa2_dq *qbman_swp_dqrr_next_mem_back(struct qbman_swp *s) -+{ -+ u32 verb; -+ u32 response_verb; -+ u32 flags; -+ struct dpaa2_dq *p; -+ -+ /* Before using valid-bit to detect if something is there, we have to -+ * handle the case of the DQRR reset bug... -+ */ -+ if (unlikely(s->dqrr.reset_bug)) { -+ /* -+ * We pick up new entries by cache-inhibited producer index, -+ * which means that a non-coherent mapping would require us to -+ * invalidate and read *only* once that PI has indicated that -+ * there's an entry here. The first trip around the DQRR ring -+ * will be much less efficient than all subsequent trips around -+ * it... -+ */ -+ u8 pi = qbman_read_register(s, QBMAN_CINH_SWP_DQPI) & -+ QMAN_DQRR_PI_MASK; -+ -+ /* there are new entries if pi != next_idx */ -+ if (pi == s->dqrr.next_idx) -+ return NULL; -+ -+ /* -+ * if next_idx is/was the last ring index, and 'pi' is -+ * different, we can disable the workaround as all the ring -+ * entries have now been DMA'd to so valid-bit checking is -+ * repaired. Note: this logic needs to be based on next_idx -+ * (which increments one at a time), rather than on pi (which -+ * can burst and wrap-around between our snapshots of it). -+ */ -+ if (s->dqrr.next_idx == (s->dqrr.dqrr_size - 1)) { -+ pr_debug("next_idx=%d, pi=%d, clear reset bug\n", -+ s->dqrr.next_idx, pi); -+ s->dqrr.reset_bug = 0; -+ } -+ qbman_inval_prefetch(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); -+ } -+ -+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx)); - verb = p->dq.verb; - - /* -@@ -976,7 +1269,7 @@ void qbman_release_desc_set_rcdi(struct - #define RAR_SUCCESS(rar) ((rar) & 0x100) - - /** -- * qbman_swp_release() - Issue a buffer release command -+ * qbman_swp_release_direct() - Issue a buffer release command - * @s: the software portal object - * @d: the release descriptor - * @buffers: a pointer pointing to the buffer address to be released -@@ -984,8 +1277,9 @@ void qbman_release_desc_set_rcdi(struct - * - * Return 0 for success, -EBUSY if the release command ring is not ready. - */ --int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d, -- const u64 *buffers, unsigned int num_buffers) -+int qbman_swp_release_direct(struct qbman_swp *s, -+ const struct qbman_release_desc *d, -+ const u64 *buffers, unsigned int num_buffers) - { - int i; - struct qbman_release_desc *p; -@@ -999,29 +1293,60 @@ int qbman_swp_release(struct qbman_swp * - return -EBUSY; - - /* Start the release command */ -- if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) -- p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar))); -- else -- p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar))); -+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar))); -+ - /* Copy the caller's buffer pointers to the command */ - for (i = 0; i < num_buffers; i++) - p->buf[i] = cpu_to_le64(buffers[i]); - p->bpid = d->bpid; - -- if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { -- /* -- * Set the verb byte, have to substitute in the valid-bit -- * and the number of buffers. -- */ -- dma_wmb(); -- p->verb = d->verb | RAR_VB(rar) | num_buffers; -- dccvac(p); -- } else { -- p->verb = d->verb | RAR_VB(rar) | num_buffers; -- dma_wmb(); -- qbman_write_register(s, QBMAN_CINH_SWP_RCR_AM_RT + -- RAR_IDX(rar) * 4, QMAN_RT_MODE); -- } -+ /* -+ * Set the verb byte, have to substitute in the valid-bit -+ * and the number of buffers. -+ */ -+ dma_wmb(); -+ p->verb = d->verb | RAR_VB(rar) | num_buffers; -+ dccvac(p); -+ -+ return 0; -+} -+ -+/** -+ * qbman_swp_release_mem_back() - Issue a buffer release command -+ * @s: the software portal object -+ * @d: the release descriptor -+ * @buffers: a pointer pointing to the buffer address to be released -+ * @num_buffers: number of buffers to be released, must be less than 8 -+ * -+ * Return 0 for success, -EBUSY if the release command ring is not ready. -+ */ -+int qbman_swp_release_mem_back(struct qbman_swp *s, -+ const struct qbman_release_desc *d, -+ const u64 *buffers, unsigned int num_buffers) -+{ -+ int i; -+ struct qbman_release_desc *p; -+ u32 rar; -+ -+ if (!num_buffers || (num_buffers > 7)) -+ return -EINVAL; -+ -+ rar = qbman_read_register(s, QBMAN_CINH_SWP_RAR); -+ if (!RAR_SUCCESS(rar)) -+ return -EBUSY; -+ -+ /* Start the release command */ -+ p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar))); -+ -+ /* Copy the caller's buffer pointers to the command */ -+ for (i = 0; i < num_buffers; i++) -+ p->buf[i] = cpu_to_le64(buffers[i]); -+ p->bpid = d->bpid; -+ -+ p->verb = d->verb | RAR_VB(rar) | num_buffers; -+ dma_wmb(); -+ qbman_write_register(s, QBMAN_CINH_SWP_RCR_AM_RT + -+ RAR_IDX(rar) * 4, QMAN_RT_MODE); - - return 0; - } ---- a/drivers/soc/fsl/dpio/qbman-portal.h -+++ b/drivers/soc/fsl/dpio/qbman-portal.h -@@ -145,6 +145,33 @@ struct qbman_swp { - } dqrr; - }; - -+/* Function pointers */ -+extern -+int (*qbman_swp_enqueue_ptr)(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd); -+extern -+int (*qbman_swp_enqueue_multiple_ptr)(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ uint32_t *flags, -+ int num_frames); -+extern -+int (*qbman_swp_enqueue_multiple_desc_ptr)(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ int num_frames); -+extern -+int (*qbman_swp_pull_ptr)(struct qbman_swp *s, struct qbman_pull_desc *d); -+extern -+const struct dpaa2_dq *(*qbman_swp_dqrr_next_ptr)(struct qbman_swp *s); -+extern -+int (*qbman_swp_release_ptr)(struct qbman_swp *s, -+ const struct qbman_release_desc *d, -+ const u64 *buffers, -+ unsigned int num_buffers); -+ -+/* Functions */ - struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d); - void qbman_swp_finish(struct qbman_swp *p); - u32 qbman_swp_interrupt_read_status(struct qbman_swp *p); -@@ -169,9 +196,6 @@ void qbman_pull_desc_set_wq(struct qbman - void qbman_pull_desc_set_channel(struct qbman_pull_desc *d, u32 chid, - enum qbman_pull_type_e dct); - --int qbman_swp_pull(struct qbman_swp *p, struct qbman_pull_desc *d); -- --const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s); - void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct dpaa2_dq *dq); - - int qbman_result_has_new_result(struct qbman_swp *p, const struct dpaa2_dq *dq); -@@ -186,17 +210,12 @@ void qbman_eq_desc_set_fq(struct qbman_e - void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid, - u32 qd_bin, u32 qd_prio); - --int qbman_swp_enqueue(struct qbman_swp *p, const struct qbman_eq_desc *d, -- const struct dpaa2_fd *fd); -- - int qbman_orp_drop(struct qbman_swp *s, u16 orpid, u16 seqnum); - - void qbman_release_desc_clear(struct qbman_release_desc *d); - void qbman_release_desc_set_bpid(struct qbman_release_desc *d, u16 bpid); - void qbman_release_desc_set_rcdi(struct qbman_release_desc *d, int enable); - --int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d, -- const u64 *buffers, unsigned int num_buffers); - int qbman_swp_acquire(struct qbman_swp *s, u16 bpid, u64 *buffers, - unsigned int num_buffers); - int qbman_swp_alt_fq_state(struct qbman_swp *s, u32 fqid, -@@ -209,18 +228,60 @@ void *qbman_swp_mc_start(struct qbman_sw - void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb); - void *qbman_swp_mc_result(struct qbman_swp *p); - --int -+/** -+ * qbman_swp_enqueue() - Issue an enqueue command -+ * @s: the software portal used for enqueue -+ * @d: the enqueue descriptor -+ * @fd: the frame descriptor to be enqueued -+ * -+ * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready. -+ */ -+static inline int -+qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd) -+{ -+ return qbman_swp_enqueue_ptr(s, d, fd); -+} -+ -+/** -+ * qbman_swp_enqueue_multiple() - Issue a multi enqueue command -+ * using one enqueue descriptor -+ * @s: the software portal used for enqueue -+ * @d: the enqueue descriptor -+ * @fd: table pointer of frame descriptor table to be enqueued -+ * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL -+ * @num_frames: number of fd to be enqueued -+ * -+ * Return the number of fd enqueued, or a negative error number. -+ */ -+static inline int - qbman_swp_enqueue_multiple(struct qbman_swp *s, - const struct qbman_eq_desc *d, - const struct dpaa2_fd *fd, - uint32_t *flags, -- int num_frames); -+ int num_frames) -+{ -+ return qbman_swp_enqueue_multiple_ptr(s, d, fd, flags, num_frames); -+} - --int -+/** -+ * qbman_swp_enqueue_multiple_desc() - Issue a multi enqueue command -+ * using multiple enqueue descriptor -+ * @s: the software portal used for enqueue -+ * @d: table of minimal enqueue descriptor -+ * @fd: table pointer of frame descriptor table to be enqueued -+ * @num_frames: number of fd to be enqueued -+ * -+ * Return the number of fd enqueued, or a negative error number. -+ */ -+static inline int - qbman_swp_enqueue_multiple_desc(struct qbman_swp *s, - const struct qbman_eq_desc *d, - const struct dpaa2_fd *fd, -- int num_frames); -+ int num_frames) -+{ -+ return qbman_swp_enqueue_multiple_desc_ptr(s, d, fd, num_frames); -+} - - /** - * qbman_result_is_DQ() - check if the dequeue result is a dequeue response -@@ -533,4 +594,49 @@ int qbman_bp_query(struct qbman_swp *s, - - u32 qbman_bp_info_num_free_bufs(struct qbman_bp_query_rslt *a); - -+/** -+ * qbman_swp_release() - Issue a buffer release command -+ * @s: the software portal object -+ * @d: the release descriptor -+ * @buffers: a pointer pointing to the buffer address to be released -+ * @num_buffers: number of buffers to be released, must be less than 8 -+ * -+ * Return 0 for success, -EBUSY if the release command ring is not ready. -+ */ -+static inline int qbman_swp_release(struct qbman_swp *s, -+ const struct qbman_release_desc *d, -+ const u64 *buffers, -+ unsigned int num_buffers) -+{ -+ return qbman_swp_release_ptr(s, d, buffers, num_buffers); -+} -+ -+/** -+ * qbman_swp_pull() - Issue the pull dequeue command -+ * @s: the software portal object -+ * @d: the software portal descriptor which has been configured with -+ * the set of qbman_pull_desc_set_*() calls -+ * -+ * Return 0 for success, and -EBUSY if the software portal is not ready -+ * to do pull dequeue. -+ */ -+static inline int qbman_swp_pull(struct qbman_swp *s, -+ struct qbman_pull_desc *d) -+{ -+ return qbman_swp_pull_ptr(s, d); -+} -+ -+/** -+ * qbman_swp_dqrr_next() - Get an valid DQRR entry -+ * @s: the software portal object -+ * -+ * Return NULL if there are no unconsumed DQRR entries. Return a DQRR entry -+ * only once, so repeated calls can return a sequence of DQRR entries, without -+ * requiring they be consumed immediately or in any particular order. -+ */ -+static inline const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s) -+{ -+ return qbman_swp_dqrr_next_ptr(s); -+} -+ - #endif /* __FSL_QBMAN_PORTAL_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0223-soc-fsl-dpio-Replace-QMAN-array-mode-by-ring-mode-en.patch b/target/linux/layerscape/patches-5.4/701-net-0223-soc-fsl-dpio-Replace-QMAN-array-mode-by-ring-mode-en.patch deleted file mode 100644 index f287cab97f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0223-soc-fsl-dpio-Replace-QMAN-array-mode-by-ring-mode-en.patch +++ /dev/null @@ -1,649 +0,0 @@ -From 0b8c6bbb0a561f15598f6701089a992bdea3963c Mon Sep 17 00:00:00 2001 -From: Youri Querry -Date: Mon, 4 Nov 2019 11:03:09 -0500 -Subject: [PATCH] soc: fsl: dpio: Replace QMAN array mode by ring mode enqueue. - -This change of algorithm will enable faster bulk enqueue. -This will grately benefit XDP bulk enqueue. - -Signed-off-by: Youri Querry ---- - drivers/soc/fsl/dpio/qbman-portal.c | 420 +++++++++++++++++++++++++++--------- - drivers/soc/fsl/dpio/qbman-portal.h | 13 ++ - 2 files changed, 335 insertions(+), 98 deletions(-) - ---- a/drivers/soc/fsl/dpio/qbman-portal.c -+++ b/drivers/soc/fsl/dpio/qbman-portal.c -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - - #include "qbman-portal.h" -@@ -22,6 +23,7 @@ - - /* CINH register offsets */ - #define QBMAN_CINH_SWP_EQCR_PI 0x800 -+#define QBMAN_CINH_SWP_EQCR_CI 0x840 - #define QBMAN_CINH_SWP_EQAR 0x8c0 - #define QBMAN_CINH_SWP_CR_RT 0x900 - #define QBMAN_CINH_SWP_VDQCR_RT 0x940 -@@ -45,6 +47,8 @@ - #define QBMAN_CENA_SWP_CR 0x600 - #define QBMAN_CENA_SWP_RR(vb) (0x700 + ((u32)(vb) >> 1)) - #define QBMAN_CENA_SWP_VDQCR 0x780 -+#define QBMAN_CENA_SWP_EQCR_CI 0x840 -+#define QBMAN_CENA_SWP_EQCR_CI_MEMBACK 0x1840 - - /* CENA register offsets in memory-backed mode */ - #define QBMAN_CENA_SWP_DQRR_MEM(n) (0x800 + ((u32)(n) << 6)) -@@ -72,6 +76,12 @@ - /* opaque token for static dequeues */ - #define QMAN_SDQCR_TOKEN 0xbb - -+#define QBMAN_EQCR_DCA_IDXMASK 0x0f -+#define QBMAN_ENQUEUE_FLAG_DCA (1ULL << 31) -+ -+#define EQ_DESC_SIZE_WITHOUT_FD 29 -+#define EQ_DESC_SIZE_FD_START 32 -+ - enum qbman_sdqcr_dct { - qbman_sdqcr_dct_null = 0, - qbman_sdqcr_dct_prio_ics, -@@ -224,6 +234,15 @@ static inline u32 qbman_set_swp_cfg(u8 m - - #define QMAN_RT_MODE 0x00000100 - -+static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last) -+{ -+ /* 'first' is included, 'last' is excluded */ -+ if (first <= last) -+ return last - first; -+ else -+ return (2 * ringsize) - (first - last); -+} -+ - /** - * qbman_swp_init() - Create a functional object representing the given - * QBMan portal descriptor. -@@ -236,6 +255,10 @@ struct qbman_swp *qbman_swp_init(const s - { - struct qbman_swp *p = kzalloc(sizeof(*p), GFP_KERNEL); - u32 reg; -+ u32 mask_size; -+ u32 eqcr_pi; -+ -+ spin_lock_init(&p->access_spinlock); - - if (!p) - return NULL; -@@ -264,25 +287,38 @@ struct qbman_swp *qbman_swp_init(const s - p->addr_cena = d->cena_bar; - p->addr_cinh = d->cinh_bar; - -- if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) -- memset(p->addr_cena, 0, 64 * 1024); -+ if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { - -- reg = qbman_set_swp_cfg(p->dqrr.dqrr_size, -- 0, /* Writes cacheable */ -- 0, /* EQCR_CI stashing threshold */ -- 3, /* RPM: Valid bit mode, RCR in array mode */ -- 2, /* DCM: Discrete consumption ack mode */ -- 3, /* EPM: Valid bit mode, EQCR in array mode */ -- 1, /* mem stashing drop enable == TRUE */ -- 1, /* mem stashing priority == TRUE */ -- 1, /* mem stashing enable == TRUE */ -- 1, /* dequeue stashing priority == TRUE */ -- 0, /* dequeue stashing enable == FALSE */ -- 0); /* EQCR_CI stashing priority == FALSE */ -- if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) -+ reg = qbman_set_swp_cfg(p->dqrr.dqrr_size, -+ 0, /* Writes Non-cacheable */ -+ 0, /* EQCR_CI stashing threshold */ -+ 3, /* RPM: RCR in array mode */ -+ 2, /* DCM: Discrete consumption ack */ -+ 2, /* EPM: EQCR in ring mode */ -+ 1, /* mem stashing drop enable enable */ -+ 1, /* mem stashing priority enable */ -+ 1, /* mem stashing enable */ -+ 1, /* dequeue stashing priority enable */ -+ 0, /* dequeue stashing enable enable */ -+ 0); /* EQCR_CI stashing priority enable */ -+ } else { -+ memset(p->addr_cena, 0, 64 * 1024); -+ reg = qbman_set_swp_cfg(p->dqrr.dqrr_size, -+ 0, /* Writes Non-cacheable */ -+ 1, /* EQCR_CI stashing threshold */ -+ 3, /* RPM: RCR in array mode */ -+ 2, /* DCM: Discrete consumption ack */ -+ 0, /* EPM: EQCR in ring mode */ -+ 1, /* mem stashing drop enable */ -+ 1, /* mem stashing priority enable */ -+ 1, /* mem stashing enable */ -+ 1, /* dequeue stashing priority enable */ -+ 0, /* dequeue stashing enable */ -+ 0); /* EQCR_CI stashing priority enable */ - reg |= 1 << SWP_CFG_CPBS_SHIFT | /* memory-backed mode */ - 1 << SWP_CFG_VPM_SHIFT | /* VDQCR read triggered mode */ - 1 << SWP_CFG_CPM_SHIFT; /* CR read triggered mode */ -+ } - - qbman_write_register(p, QBMAN_CINH_SWP_CFG, reg); - reg = qbman_read_register(p, QBMAN_CINH_SWP_CFG); -@@ -304,7 +340,9 @@ struct qbman_swp *qbman_swp_init(const s - */ - qbman_write_register(p, QBMAN_CINH_SWP_SDQCR, 0); - -+ p->eqcr.pi_ring_size = 8; - if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) { -+ p->eqcr.pi_ring_size = 32; - qbman_swp_enqueue_ptr = - qbman_swp_enqueue_mem_back; - qbman_swp_enqueue_multiple_ptr = -@@ -316,6 +354,15 @@ struct qbman_swp *qbman_swp_init(const s - qbman_swp_release_ptr = qbman_swp_release_mem_back; - } - -+ for (mask_size = p->eqcr.pi_ring_size; mask_size > 0; mask_size >>= 1) -+ p->eqcr.pi_ci_mask = (p->eqcr.pi_ci_mask << 1) + 1; -+ eqcr_pi = qbman_read_register(p, QBMAN_CINH_SWP_EQCR_PI); -+ p->eqcr.pi = eqcr_pi & p->eqcr.pi_ci_mask; -+ p->eqcr.pi_vb = eqcr_pi & QB_VALID_BIT; -+ p->eqcr.ci = qbman_read_register(p, QBMAN_CINH_SWP_EQCR_CI) -+ & p->eqcr.pi_ci_mask; -+ p->eqcr.available = p->eqcr.pi_ring_size; -+ - return p; - } - -@@ -468,8 +515,9 @@ enum qb_enqueue_commands { - enqueue_rejects_to_fq = 2 - }; - --#define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT 2 --#define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT 4 -+#define QB_ENQUEUE_CMD_ORP_ENABLE_SHIFT 2 -+#define QB_ENQUEUE_CMD_TARGET_TYPE_SHIFT 4 -+#define QB_ENQUEUE_CMD_DCA_EN_SHIFT 7 - - /** - * qbman_eq_desc_clear() - Clear the contents of a descriptor to -@@ -582,6 +630,7 @@ static inline void qbman_write_eqcr_am_r - QMAN_RT_MODE); - } - -+#define QB_RT_BIT ((u32)0x100) - /** - * qbman_swp_enqueue_direct() - Issue an enqueue command - * @s: the software portal used for enqueue -@@ -593,35 +642,19 @@ static inline void qbman_write_eqcr_am_r - * - * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready. - */ --int qbman_swp_enqueue_direct(struct qbman_swp *s, const struct qbman_eq_desc *d, -- const struct dpaa2_fd *fd) -+static -+int qbman_swp_enqueue_direct(struct qbman_swp *s, -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd) - { -- struct qbman_eq_desc_with_fd *p; -- u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR); -- -- if (!EQAR_SUCCESS(eqar)) -- return -EBUSY; -+ int flags = 0; -+ int ret = qbman_swp_enqueue_multiple_direct(s, d, fd, &flags, 1); - -- p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar))); -- /* This is mapped as DEVICE type memory, writes are -- * with address alignment: -- * desc.dca address alignment = 1 -- * desc.seqnum address alignment = 2 -- * desc.orpid address alignment = 4 -- * desc.tgtid address alignment = 8 -- */ -- p->desc.dca = d->dca; -- p->desc.seqnum = d->seqnum; -- p->desc.orpid = d->orpid; -- memcpy(&p->desc.tgtid, &d->tgtid, 24); -- memcpy(&p->fd, fd, sizeof(*fd)); -- -- /* Set the verb byte, have to substitute in the valid-bit */ -- dma_wmb(); -- p->desc.verb = d->verb | EQAR_VB(eqar); -- dccvac(p); -- -- return 0; -+ if (ret >= 0) -+ ret = 0; -+ else -+ ret = -EBUSY; -+ return ret; - } - - /** -@@ -635,35 +668,19 @@ int qbman_swp_enqueue_direct(struct qbma - * - * Return 0 for successful enqueue, -EBUSY if the EQCR is not ready. - */ -+static - int qbman_swp_enqueue_mem_back(struct qbman_swp *s, - const struct qbman_eq_desc *d, - const struct dpaa2_fd *fd) - { -- struct qbman_eq_desc_with_fd *p; -- u32 eqar = qbman_read_register(s, QBMAN_CINH_SWP_EQAR); -- -- if (!EQAR_SUCCESS(eqar)) -- return -EBUSY; -- -- p = qbman_get_cmd(s, QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar))); -- /* This is mapped as DEVICE type memory, writes are -- * with address alignment: -- * desc.dca address alignment = 1 -- * desc.seqnum address alignment = 2 -- * desc.orpid address alignment = 4 -- * desc.tgtid address alignment = 8 -- */ -- p->desc.dca = d->dca; -- p->desc.seqnum = d->seqnum; -- p->desc.orpid = d->orpid; -- memcpy(&p->desc.tgtid, &d->tgtid, 24); -- memcpy(&p->fd, fd, sizeof(*fd)); -- -- p->desc.verb = d->verb | EQAR_VB(eqar); -- dma_wmb(); -- qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar)); -+ int flags = 0; -+ int ret = qbman_swp_enqueue_multiple_mem_back(s, d, fd, &flags, 1); - -- return 0; -+ if (ret >= 0) -+ ret = 0; -+ else -+ ret = -EBUSY; -+ return ret; - } - - /** -@@ -672,26 +689,84 @@ int qbman_swp_enqueue_mem_back(struct qb - * @s: the software portal used for enqueue - * @d: the enqueue descriptor - * @fd: table pointer of frame descriptor table to be enqueued -- * @flags: table pointer of flags, not used for the moment -+ * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL - * @num_frames: number of fd to be enqueued - * - * Return the number of fd enqueued, or a negative error number. - */ -+static - int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s, - const struct qbman_eq_desc *d, - const struct dpaa2_fd *fd, - uint32_t *flags, - int num_frames) - { -- int count = 0; -+ uint32_t *p = NULL; -+ const uint32_t *cl = (uint32_t *)d; -+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; -+ int i, num_enqueued = 0; -+ uint64_t addr_cena; -+ -+ spin_lock(&s->access_spinlock); -+ half_mask = (s->eqcr.pi_ci_mask>>1); -+ full_mask = s->eqcr.pi_ci_mask; -+ -+ if (!s->eqcr.available) { -+ eqcr_ci = s->eqcr.ci; -+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI; -+ s->eqcr.ci = qbman_read_register(s, QBMAN_CINH_SWP_EQCR_CI); -+ -+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, -+ eqcr_ci, s->eqcr.ci); -+ if (!s->eqcr.available) { -+ spin_unlock(&s->access_spinlock); -+ return 0; -+ } -+ } - -- while (count < num_frames) { -- if (qbman_swp_enqueue_direct(s, d, fd) != 0) -- break; -- count++; -+ eqcr_pi = s->eqcr.pi; -+ num_enqueued = (s->eqcr.available < num_frames) ? -+ s->eqcr.available : num_frames; -+ s->eqcr.available -= num_enqueued; -+ /* Fill in the EQCR ring */ -+ for (i = 0; i < num_enqueued; i++) { -+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); -+ /* Skip copying the verb */ -+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1); -+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)], -+ &fd[i], sizeof(*fd)); -+ eqcr_pi++; - } - -- return count; -+ dma_wmb(); -+ -+ /* Set the verb byte, have to substitute in the valid-bit */ -+ eqcr_pi = s->eqcr.pi; -+ for (i = 0; i < num_enqueued; i++) { -+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); -+ p[0] = cl[0] | s->eqcr.pi_vb; -+ if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { -+ struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; -+ -+ d->dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | -+ ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); -+ } -+ eqcr_pi++; -+ if (!(eqcr_pi & half_mask)) -+ s->eqcr.pi_vb ^= QB_VALID_BIT; -+ } -+ -+ /* Flush all the cacheline without load/store in between */ -+ eqcr_pi = s->eqcr.pi; -+ addr_cena = (size_t)s->addr_cena; -+ for (i = 0; i < num_enqueued; i++) { -+ dccvac((addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask))); -+ eqcr_pi++; -+ } -+ s->eqcr.pi = eqcr_pi & full_mask; -+ spin_unlock(&s->access_spinlock); -+ -+ return num_enqueued; - } - - /** -@@ -700,26 +775,80 @@ int qbman_swp_enqueue_multiple_direct(st - * @s: the software portal used for enqueue - * @d: the enqueue descriptor - * @fd: table pointer of frame descriptor table to be enqueued -- * @flags: table pointer of flags, not used for the moment -+ * @flags: table pointer of QBMAN_ENQUEUE_FLAG_DCA flags, not used if NULL - * @num_frames: number of fd to be enqueued - * - * Return the number of fd enqueued, or a negative error number. - */ -+static - int qbman_swp_enqueue_multiple_mem_back(struct qbman_swp *s, -- const struct qbman_eq_desc *d, -- const struct dpaa2_fd *fd, -- uint32_t *flags, -- int num_frames) --{ -- int count = 0; -+ const struct qbman_eq_desc *d, -+ const struct dpaa2_fd *fd, -+ uint32_t *flags, -+ int num_frames) -+{ -+ uint32_t *p = NULL; -+ const uint32_t *cl = (uint32_t *)(d); -+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; -+ int i, num_enqueued = 0; -+ unsigned long irq_flags; -+ -+ spin_lock(&s->access_spinlock); -+ local_irq_save(irq_flags); -+ -+ half_mask = (s->eqcr.pi_ci_mask>>1); -+ full_mask = s->eqcr.pi_ci_mask; -+ if (!s->eqcr.available) { -+ eqcr_ci = s->eqcr.ci; -+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK; -+ s->eqcr.ci = __raw_readl(p) & full_mask; -+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, -+ eqcr_ci, s->eqcr.ci); -+ if (!s->eqcr.available) { -+ local_irq_restore(irq_flags); -+ spin_unlock(&s->access_spinlock); -+ return 0; -+ } -+ } -+ -+ eqcr_pi = s->eqcr.pi; -+ num_enqueued = (s->eqcr.available < num_frames) ? -+ s->eqcr.available : num_frames; -+ s->eqcr.available -= num_enqueued; -+ /* Fill in the EQCR ring */ -+ for (i = 0; i < num_enqueued; i++) { -+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); -+ /* Skip copying the verb */ -+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1); -+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)], -+ &fd[i], sizeof(*fd)); -+ eqcr_pi++; -+ } - -- while (count < num_frames) { -- if (qbman_swp_enqueue_mem_back(s, d, fd) != 0) -- break; -- count++; -+ /* Set the verb byte, have to substitute in the valid-bit */ -+ eqcr_pi = s->eqcr.pi; -+ for (i = 0; i < num_enqueued; i++) { -+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); -+ p[0] = cl[0] | s->eqcr.pi_vb; -+ if (flags && (flags[i] & QBMAN_ENQUEUE_FLAG_DCA)) { -+ struct qbman_eq_desc *d = (struct qbman_eq_desc *)p; -+ -+ d->dca = (1 << QB_ENQUEUE_CMD_DCA_EN_SHIFT) | -+ ((flags[i]) & QBMAN_EQCR_DCA_IDXMASK); -+ } -+ eqcr_pi++; -+ if (!(eqcr_pi & half_mask)) -+ s->eqcr.pi_vb ^= QB_VALID_BIT; - } -+ s->eqcr.pi = eqcr_pi & full_mask; -+ -+ dma_wmb(); -+ qbman_write_register(s, QBMAN_CINH_SWP_EQCR_PI, -+ (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb); -+ local_irq_restore(irq_flags); -+ spin_unlock(&s->access_spinlock); - -- return count; -+ return num_enqueued; - } - - /** -@@ -732,20 +861,69 @@ int qbman_swp_enqueue_multiple_mem_back( - * - * Return the number of fd enqueued, or a negative error number. - */ -+static - int qbman_swp_enqueue_multiple_desc_direct(struct qbman_swp *s, - const struct qbman_eq_desc *d, - const struct dpaa2_fd *fd, - int num_frames) - { -- int count = 0; -+ uint32_t *p; -+ const uint32_t *cl; -+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; -+ int i, num_enqueued = 0; -+ uint64_t addr_cena; -+ -+ half_mask = (s->eqcr.pi_ci_mask>>1); -+ full_mask = s->eqcr.pi_ci_mask; -+ if (!s->eqcr.available) { -+ eqcr_ci = s->eqcr.ci; -+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI; -+ s->eqcr.ci = qbman_read_register(s, QBMAN_CINH_SWP_EQCR_CI); -+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, -+ eqcr_ci, s->eqcr.ci); -+ if (!s->eqcr.available) -+ return 0; -+ } - -- while (count < num_frames) { -- if (qbman_swp_enqueue_direct(s, &(d[count]), fd) != 0) -- break; -- count++; -+ eqcr_pi = s->eqcr.pi; -+ num_enqueued = (s->eqcr.available < num_frames) ? -+ s->eqcr.available : num_frames; -+ s->eqcr.available -= num_enqueued; -+ /* Fill in the EQCR ring */ -+ for (i = 0; i < num_enqueued; i++) { -+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); -+ cl = (uint32_t *)(&d[i]); -+ /* Skip copying the verb */ -+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1); -+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)], -+ &fd[i], sizeof(*fd)); -+ eqcr_pi++; - } - -- return count; -+ dma_wmb(); -+ -+ /* Set the verb byte, have to substitute in the valid-bit */ -+ eqcr_pi = s->eqcr.pi; -+ for (i = 0; i < num_enqueued; i++) { -+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); -+ cl = (uint32_t *)(&d[i]); -+ p[0] = cl[0] | s->eqcr.pi_vb; -+ eqcr_pi++; -+ if (!(eqcr_pi & half_mask)) -+ s->eqcr.pi_vb ^= QB_VALID_BIT; -+ } -+ -+ /* Flush all the cacheline without load/store in between */ -+ eqcr_pi = s->eqcr.pi; -+ addr_cena = (uint64_t)s->addr_cena; -+ for (i = 0; i < num_enqueued; i++) { -+ dccvac((uint64_t *)(addr_cena + -+ QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask))); -+ eqcr_pi++; -+ } -+ s->eqcr.pi = eqcr_pi & full_mask; -+ -+ return num_enqueued; - } - - /** -@@ -758,20 +936,62 @@ int qbman_swp_enqueue_multiple_desc_dire - * - * Return the number of fd enqueued, or a negative error number. - */ -+static - int qbman_swp_enqueue_multiple_desc_mem_back(struct qbman_swp *s, - const struct qbman_eq_desc *d, - const struct dpaa2_fd *fd, - int num_frames) - { -- int count = 0; -+ uint32_t *p; -+ const uint32_t *cl; -+ uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask; -+ int i, num_enqueued = 0; -+ -+ half_mask = (s->eqcr.pi_ci_mask>>1); -+ full_mask = s->eqcr.pi_ci_mask; -+ if (!s->eqcr.available) { -+ eqcr_ci = s->eqcr.ci; -+ p = s->addr_cena + QBMAN_CENA_SWP_EQCR_CI_MEMBACK; -+ s->eqcr.ci = __raw_readl(p) & full_mask; -+ s->eqcr.available = qm_cyc_diff(s->eqcr.pi_ring_size, -+ eqcr_ci, s->eqcr.ci); -+ if (!s->eqcr.available) -+ return 0; -+ } - -- while (count < num_frames) { -- if (qbman_swp_enqueue_mem_back(s, &(d[count]), fd) != 0) -- break; -- count++; -+ eqcr_pi = s->eqcr.pi; -+ num_enqueued = (s->eqcr.available < num_frames) ? -+ s->eqcr.available : num_frames; -+ s->eqcr.available -= num_enqueued; -+ /* Fill in the EQCR ring */ -+ for (i = 0; i < num_enqueued; i++) { -+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); -+ cl = (uint32_t *)(&d[i]); -+ /* Skip copying the verb */ -+ memcpy(&p[1], &cl[1], EQ_DESC_SIZE_WITHOUT_FD - 1); -+ memcpy(&p[EQ_DESC_SIZE_FD_START/sizeof(uint32_t)], -+ &fd[i], sizeof(*fd)); -+ eqcr_pi++; - } - -- return count; -+ /* Set the verb byte, have to substitute in the valid-bit */ -+ eqcr_pi = s->eqcr.pi; -+ for (i = 0; i < num_enqueued; i++) { -+ p = (s->addr_cena + QBMAN_CENA_SWP_EQCR(eqcr_pi & half_mask)); -+ cl = (uint32_t *)(&d[i]); -+ p[0] = cl[0] | s->eqcr.pi_vb; -+ eqcr_pi++; -+ if (!(eqcr_pi & half_mask)) -+ s->eqcr.pi_vb ^= QB_VALID_BIT; -+ } -+ -+ s->eqcr.pi = eqcr_pi & full_mask; -+ -+ dma_wmb(); -+ qbman_write_register(s, QBMAN_CINH_SWP_EQCR_PI, -+ (QB_RT_BIT)|(s->eqcr.pi)|s->eqcr.pi_vb); -+ -+ return num_enqueued; - } - - /* Static (push) dequeue */ -@@ -937,6 +1157,7 @@ void qbman_pull_desc_set_channel(struct - * Return 0 for success, and -EBUSY if the software portal is not ready - * to do pull dequeue. - */ -+static - int qbman_swp_pull_direct(struct qbman_swp *s, struct qbman_pull_desc *d) - { - struct qbman_pull_desc *p; -@@ -973,6 +1194,7 @@ int qbman_swp_pull_direct(struct qbman_s - * Return 0 for success, and -EBUSY if the software portal is not ready - * to do pull dequeue. - */ -+static - int qbman_swp_pull_mem_back(struct qbman_swp *s, struct qbman_pull_desc *d) - { - struct qbman_pull_desc *p; -@@ -991,6 +1213,8 @@ int qbman_swp_pull_mem_back(struct qbman - p->dq_src = d->dq_src; - p->rsp_addr = d->rsp_addr; - p->rsp_addr_virt = d->rsp_addr_virt; -+ -+ /* Set the verb byte, have to substitute in the valid-bit */ - p->verb = d->verb | s->vdq.valid_bit; - s->vdq.valid_bit ^= QB_VALID_BIT; - dma_wmb(); ---- a/drivers/soc/fsl/dpio/qbman-portal.h -+++ b/drivers/soc/fsl/dpio/qbman-portal.h -@@ -143,6 +143,19 @@ struct qbman_swp { - u8 dqrr_size; - int reset_bug; /* indicates dqrr reset workaround is needed */ - } dqrr; -+ -+ struct { -+ u32 pi; -+ u32 pi_vb; -+ u32 pi_ring_size; -+ u32 pi_ci_mask; -+ u32 ci; -+ int available; -+ u32 pend; -+ u32 no_pfdr; -+ } eqcr; -+ -+ spinlock_t access_spinlock; - }; - - /* Function pointers */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0224-bus-fsl-mc-add-autorescan-sysfs.patch b/target/linux/layerscape/patches-5.4/701-net-0224-bus-fsl-mc-add-autorescan-sysfs.patch deleted file mode 100644 index 6128e7d0b4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0224-bus-fsl-mc-add-autorescan-sysfs.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 02e92b21edb4df7285f27ea5f0403377dcabe22d Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Tue, 29 Oct 2019 22:48:55 +0200 -Subject: [PATCH] bus: fsl-mc: add autorescan sysfs - -Add the autorescan sysfs in order to enable/disable the DPRC IRQs on -which automatic rescan of the bus is performed. This is important when -dynamic creation of objects is needed to happen in a timely manner because -object creation can be bundled together. - -Signed-off-by: Ioana Ciornei ---- - drivers/bus/fsl-mc/dprc-driver.c | 17 ++++++++++-- - drivers/bus/fsl-mc/fsl-mc-bus.c | 55 +++++++++++++++++++++++++++++++++++++ - drivers/bus/fsl-mc/fsl-mc-private.h | 4 +++ - include/linux/fsl/mc.h | 1 + - 4 files changed, 75 insertions(+), 2 deletions(-) - ---- a/drivers/bus/fsl-mc/dprc-driver.c -+++ b/drivers/bus/fsl-mc/dprc-driver.c -@@ -484,8 +484,9 @@ out: - /* - * Disable and clear interrupt for a given DPRC object - */ --static int disable_dprc_irq(struct fsl_mc_device *mc_dev) -+int disable_dprc_irq(struct fsl_mc_device *mc_dev) - { -+ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); - int error; - struct fsl_mc_io *mc_io = mc_dev->mc_io; - -@@ -522,9 +523,18 @@ static int disable_dprc_irq(struct fsl_m - return error; - } - -+ mc_bus->irq_enabled = 0; -+ - return 0; - } - -+int get_dprc_irq_state(struct fsl_mc_device *mc_dev) -+{ -+ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); -+ -+ return mc_bus->irq_enabled; -+} -+ - static int register_dprc_irq_handler(struct fsl_mc_device *mc_dev) - { - int error; -@@ -551,8 +561,9 @@ static int register_dprc_irq_handler(str - return 0; - } - --static int enable_dprc_irq(struct fsl_mc_device *mc_dev) -+int enable_dprc_irq(struct fsl_mc_device *mc_dev) - { -+ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); - int error; - - /* -@@ -580,6 +591,8 @@ static int enable_dprc_irq(struct fsl_mc - return error; - } - -+ mc_bus->irq_enabled = 1; -+ - return 0; - } - ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -237,8 +237,63 @@ static ssize_t rescan_store(struct bus_t - } - static BUS_ATTR_WO(rescan); - -+static int fsl_mc_bus_set_autorescan(struct device *dev, void *data) -+{ -+ struct fsl_mc_device *root_mc_dev; -+ unsigned long val; -+ char *buf = data; -+ -+ if (!fsl_mc_is_root_dprc(dev)) -+ goto exit; -+ -+ root_mc_dev = to_fsl_mc_device(dev); -+ -+ if (kstrtoul(buf, 0, &val) < 0) -+ return -EINVAL; -+ -+ if (val) -+ enable_dprc_irq(root_mc_dev); -+ else -+ disable_dprc_irq(root_mc_dev); -+ -+exit: -+ return 0; -+} -+ -+static int fsl_mc_bus_get_autorescan(struct device *dev, void *data) -+{ -+ struct fsl_mc_device *root_mc_dev; -+ char *buf = data; -+ -+ if (!fsl_mc_is_root_dprc(dev)) -+ goto exit; -+ -+ root_mc_dev = to_fsl_mc_device(dev); -+ -+ sprintf(buf, "%d\n", get_dprc_irq_state(root_mc_dev)); -+exit: -+ return 0; -+} -+ -+static ssize_t autorescan_store(struct bus_type *bus, -+ const char *buf, size_t count) -+{ -+ bus_for_each_dev(bus, NULL, (void *)buf, fsl_mc_bus_set_autorescan); -+ -+ return count; -+} -+ -+static ssize_t autorescan_show(struct bus_type *bus, char *buf) -+{ -+ bus_for_each_dev(bus, NULL, (void *)buf, fsl_mc_bus_get_autorescan); -+ return strlen(buf); -+} -+ -+static BUS_ATTR_RW(autorescan); -+ - static struct attribute *fsl_mc_bus_attrs[] = { - &bus_attr_rescan.attr, -+ &bus_attr_autorescan.attr, - NULL, - }; - ---- a/drivers/bus/fsl-mc/fsl-mc-private.h -+++ b/drivers/bus/fsl-mc/fsl-mc-private.h -@@ -203,4 +203,8 @@ static inline void fsl_mc_uapi_remove_de - - #endif - -+int disable_dprc_irq(struct fsl_mc_device *mc_dev); -+int enable_dprc_irq(struct fsl_mc_device *mc_dev); -+int get_dprc_irq_state(struct fsl_mc_device *mc_dev); -+ - #endif /* _FSL_MC_PRIVATE_H_ */ ---- a/include/linux/fsl/mc.h -+++ b/include/linux/fsl/mc.h -@@ -1006,6 +1006,7 @@ struct fsl_mc_bus { - struct mutex scan_mutex; /* serializes bus scanning */ - struct dprc_attributes dprc_attr; - struct fsl_mc_uapi uapi_misc; -+ int irq_enabled; - }; - - int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, diff --git a/target/linux/layerscape/patches-5.4/701-net-0225-enetc-Configure-the-Time-Aware-Scheduler-via-tc-tapr.patch b/target/linux/layerscape/patches-5.4/701-net-0225-enetc-Configure-the-Time-Aware-Scheduler-via-tc-tapr.patch deleted file mode 100644 index e516e1d5b6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0225-enetc-Configure-the-Time-Aware-Scheduler-via-tc-tapr.patch +++ /dev/null @@ -1,378 +0,0 @@ -From 6ee2331a3a5627b062daf76aa5ed9f64fbbfa303 Mon Sep 17 00:00:00 2001 -From: Po Liu -Date: Fri, 15 Nov 2019 03:33:33 +0000 -Subject: [PATCH] enetc: Configure the Time-Aware Scheduler via tc-taprio - offload - -ENETC supports in hardware for time-based egress shaping according -to IEEE 802.1Qbv. This patch implement the Qbv enablement by the -hardware offload method qdisc tc-taprio method. -Also update cbdr writeback to up level since control bd ring may -writeback data to control bd ring. - -Signed-off-by: Po Liu -Signed-off-by: Vladimir Oltean -Signed-off-by: Claudiu Manoil -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/freescale/enetc/Kconfig | 10 ++ - drivers/net/ethernet/freescale/enetc/Makefile | 2 + - drivers/net/ethernet/freescale/enetc/enetc.c | 19 ++- - drivers/net/ethernet/freescale/enetc/enetc.h | 7 ++ - drivers/net/ethernet/freescale/enetc/enetc_cbdr.c | 5 +- - drivers/net/ethernet/freescale/enetc/enetc_hw.h | 84 ++++++++++--- - drivers/net/ethernet/freescale/enetc/enetc_qos.c | 138 ++++++++++++++++++++++ - 7 files changed, 243 insertions(+), 22 deletions(-) - create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_qos.c - ---- a/drivers/net/ethernet/freescale/enetc/Kconfig -+++ b/drivers/net/ethernet/freescale/enetc/Kconfig -@@ -50,3 +50,13 @@ config FSL_ENETC_HW_TIMESTAMPING - allocation has not been supported and it is too expensive to use - extended RX BDs if timestamping is not used, this option enables - extended RX BDs in order to support hardware timestamping. -+ -+config FSL_ENETC_QOS -+ bool "ENETC hardware Time-sensitive Network support" -+ depends on (FSL_ENETC || FSL_ENETC_VF) && NET_SCH_TAPRIO -+ help -+ There are Time-Sensitive Network(TSN) capabilities(802.1Qbv/802.1Qci -+ /802.1Qbu etc.) supported by ENETC. These TSN capabilities can be set -+ enable/disable from user space via Qos commands(tc). In the kernel -+ side, it can be loaded by Qos driver. Currently, it is only support -+ taprio(802.1Qbv). ---- a/drivers/net/ethernet/freescale/enetc/Makefile -+++ b/drivers/net/ethernet/freescale/enetc/Makefile -@@ -5,9 +5,11 @@ common-objs := enetc.o enetc_cbdr.o enet - obj-$(CONFIG_FSL_ENETC) += fsl-enetc.o - fsl-enetc-y := enetc_pf.o enetc_mdio.o $(common-objs) - fsl-enetc-$(CONFIG_PCI_IOV) += enetc_msg.o -+fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o - - obj-$(CONFIG_FSL_ENETC_VF) += fsl-enetc-vf.o - fsl-enetc-vf-y := enetc_vf.o $(common-objs) -+fsl-enetc-vf-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o - - obj-$(CONFIG_FSL_ENETC_MDIO) += fsl-enetc-mdio.o - fsl-enetc-mdio-y := enetc_pci_mdio.o enetc_mdio.o ---- a/drivers/net/ethernet/freescale/enetc/enetc.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc.c -@@ -1419,8 +1419,7 @@ int enetc_close(struct net_device *ndev) - return 0; - } - --int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type, -- void *type_data) -+int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data) - { - struct enetc_ndev_priv *priv = netdev_priv(ndev); - struct tc_mqprio_qopt *mqprio = type_data; -@@ -1428,9 +1427,6 @@ int enetc_setup_tc(struct net_device *nd - u8 num_tc; - int i; - -- if (type != TC_SETUP_QDISC_MQPRIO) -- return -EOPNOTSUPP; -- - mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS; - num_tc = mqprio->num_tc; - -@@ -1475,6 +1471,19 @@ int enetc_setup_tc(struct net_device *nd - return 0; - } - -+int enetc_setup_tc(struct net_device *ndev, enum tc_setup_type type, -+ void *type_data) -+{ -+ switch (type) { -+ case TC_SETUP_QDISC_MQPRIO: -+ return enetc_setup_tc_mqprio(ndev, type_data); -+ case TC_SETUP_QDISC_TAPRIO: -+ return enetc_setup_tc_taprio(ndev, type_data); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ - struct net_device_stats *enetc_get_stats(struct net_device *ndev) - { - struct enetc_ndev_priv *priv = netdev_priv(ndev); ---- a/drivers/net/ethernet/freescale/enetc/enetc.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc.h -@@ -249,3 +249,10 @@ int enetc_set_fs_entry(struct enetc_si * - void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes); - int enetc_get_rss_table(struct enetc_si *si, u32 *table, int count); - int enetc_set_rss_table(struct enetc_si *si, const u32 *table, int count); -+int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd); -+ -+#ifdef CONFIG_FSL_ENETC_QOS -+int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data); -+#else -+#define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP -+#endif ---- a/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_cbdr.c -@@ -32,7 +32,7 @@ static int enetc_cbd_unused(struct enetc - r->bd_count; - } - --static int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd) -+int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd) - { - struct enetc_cbdr *ring = &si->cbd_ring; - int timeout = ENETC_CBDR_TIMEOUT; -@@ -66,6 +66,9 @@ static int enetc_send_cmd(struct enetc_s - if (!timeout) - return -EBUSY; - -+ /* CBD may writeback data, feedback up level */ -+ *cbd = *dest_cbd; -+ - enetc_clean_cbdr(si); - - return 0; ---- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h -@@ -18,6 +18,7 @@ - #define ENETC_SICTR0 0x18 - #define ENETC_SICTR1 0x1c - #define ENETC_SIPCAPR0 0x20 -+#define ENETC_SIPCAPR0_QBV BIT(4) - #define ENETC_SIPCAPR0_RSS BIT(8) - #define ENETC_SIPCAPR1 0x24 - #define ENETC_SITGTGR 0x30 -@@ -446,22 +447,6 @@ union enetc_rx_bd { - #define EMETC_MAC_ADDR_FILT_RES 3 /* # of reserved entries at the beginning */ - #define ENETC_MAX_NUM_VFS 2 - --struct enetc_cbd { -- union { -- struct { -- __le32 addr[2]; -- __le32 opt[4]; -- }; -- __le32 data[6]; -- }; -- __le16 index; -- __le16 length; -- u8 cmd; -- u8 cls; -- u8 _res; -- u8 status_flags; --}; -- - #define ENETC_CBD_FLAGS_SF BIT(7) /* short format */ - #define ENETC_CBD_STATUS_MASK 0xf - -@@ -560,3 +545,70 @@ static inline void enetc_set_bdr_prio(st - val |= ENETC_TBMR_SET_PRIO(prio); - enetc_txbdr_wr(hw, bdr_idx, ENETC_TBMR, val); - } -+ -+enum bdcr_cmd_class { -+ BDCR_CMD_UNSPEC = 0, -+ BDCR_CMD_MAC_FILTER, -+ BDCR_CMD_VLAN_FILTER, -+ BDCR_CMD_RSS, -+ BDCR_CMD_RFS, -+ BDCR_CMD_PORT_GCL, -+ BDCR_CMD_RECV_CLASSIFIER, -+ __BDCR_CMD_MAX_LEN, -+ BDCR_CMD_MAX_LEN = __BDCR_CMD_MAX_LEN - 1, -+}; -+ -+/* class 5, command 0 */ -+struct tgs_gcl_conf { -+ u8 atc; /* init gate value */ -+ u8 res[7]; -+ struct { -+ u8 res1[4]; -+ __le16 acl_len; -+ u8 res2[2]; -+ }; -+}; -+ -+/* gate control list entry */ -+struct gce { -+ __le32 period; -+ u8 gate; -+ u8 res[3]; -+}; -+ -+/* tgs_gcl_conf address point to this data space */ -+struct tgs_gcl_data { -+ __le32 btl; -+ __le32 bth; -+ __le32 ct; -+ __le32 cte; -+ struct gce entry[0]; -+}; -+ -+struct enetc_cbd { -+ union{ -+ struct { -+ __le32 addr[2]; -+ union { -+ __le32 opt[4]; -+ struct tgs_gcl_conf gcl_conf; -+ }; -+ }; /* Long format */ -+ __le32 data[6]; -+ }; -+ __le16 index; -+ __le16 length; -+ u8 cmd; -+ u8 cls; -+ u8 _res; -+ u8 status_flags; -+}; -+ -+/* port time gating control register */ -+#define ENETC_QBV_PTGCR_OFFSET 0x11a00 -+#define ENETC_QBV_TGE BIT(31) -+#define ENETC_QBV_TGPE BIT(30) -+ -+/* Port time gating capability register */ -+#define ENETC_QBV_PTGCAPR_OFFSET 0x11a08 -+#define ENETC_QBV_MAX_GCL_LEN_MASK GENMASK(15, 0) ---- /dev/null -+++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c -@@ -0,0 +1,138 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* Copyright 2019 NXP */ -+ -+#include "enetc.h" -+ -+#include -+ -+static u16 enetc_get_max_gcl_len(struct enetc_hw *hw) -+{ -+ return enetc_rd(hw, ENETC_QBV_PTGCAPR_OFFSET) -+ & ENETC_QBV_MAX_GCL_LEN_MASK; -+} -+ -+static int enetc_setup_taprio(struct net_device *ndev, -+ struct tc_taprio_qopt_offload *admin_conf) -+{ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ struct enetc_cbd cbd = {.cmd = 0}; -+ struct tgs_gcl_conf *gcl_config; -+ struct tgs_gcl_data *gcl_data; -+ struct gce *gce; -+ dma_addr_t dma; -+ u16 data_size; -+ u16 gcl_len; -+ u32 tge; -+ int err; -+ int i; -+ -+ if (admin_conf->num_entries > enetc_get_max_gcl_len(&priv->si->hw)) -+ return -EINVAL; -+ gcl_len = admin_conf->num_entries; -+ -+ tge = enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET); -+ if (!admin_conf->enable) { -+ enetc_wr(&priv->si->hw, -+ ENETC_QBV_PTGCR_OFFSET, -+ tge & (~ENETC_QBV_TGE)); -+ return 0; -+ } -+ -+ if (admin_conf->cycle_time > U32_MAX || -+ admin_conf->cycle_time_extension > U32_MAX) -+ return -EINVAL; -+ -+ /* Configure the (administrative) gate control list using the -+ * control BD descriptor. -+ */ -+ gcl_config = &cbd.gcl_conf; -+ -+ data_size = struct_size(gcl_data, entry, gcl_len); -+ gcl_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!gcl_data) -+ return -ENOMEM; -+ -+ gce = (struct gce *)(gcl_data + 1); -+ -+ /* Set all gates open as default */ -+ gcl_config->atc = 0xff; -+ gcl_config->acl_len = cpu_to_le16(gcl_len); -+ -+ if (!admin_conf->base_time) { -+ gcl_data->btl = -+ cpu_to_le32(enetc_rd(&priv->si->hw, ENETC_SICTR0)); -+ gcl_data->bth = -+ cpu_to_le32(enetc_rd(&priv->si->hw, ENETC_SICTR1)); -+ } else { -+ gcl_data->btl = -+ cpu_to_le32(lower_32_bits(admin_conf->base_time)); -+ gcl_data->bth = -+ cpu_to_le32(upper_32_bits(admin_conf->base_time)); -+ } -+ -+ gcl_data->ct = cpu_to_le32(admin_conf->cycle_time); -+ gcl_data->cte = cpu_to_le32(admin_conf->cycle_time_extension); -+ -+ for (i = 0; i < gcl_len; i++) { -+ struct tc_taprio_sched_entry *temp_entry; -+ struct gce *temp_gce = gce + i; -+ -+ temp_entry = &admin_conf->entries[i]; -+ -+ temp_gce->gate = (u8)temp_entry->gate_mask; -+ temp_gce->period = cpu_to_le32(temp_entry->interval); -+ } -+ -+ cbd.length = cpu_to_le16(data_size); -+ cbd.status_flags = 0; -+ -+ dma = dma_map_single(&priv->si->pdev->dev, gcl_data, -+ data_size, DMA_TO_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ kfree(gcl_data); -+ return -ENOMEM; -+ } -+ -+ cbd.addr[0] = lower_32_bits(dma); -+ cbd.addr[1] = upper_32_bits(dma); -+ cbd.cls = BDCR_CMD_PORT_GCL; -+ cbd.status_flags = 0; -+ -+ enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET, -+ tge | ENETC_QBV_TGE); -+ -+ err = enetc_send_cmd(priv->si, &cbd); -+ if (err) -+ enetc_wr(&priv->si->hw, -+ ENETC_QBV_PTGCR_OFFSET, -+ tge & (~ENETC_QBV_TGE)); -+ -+ dma_unmap_single(&priv->si->pdev->dev, dma, data_size, DMA_TO_DEVICE); -+ kfree(gcl_data); -+ -+ return err; -+} -+ -+int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data) -+{ -+ struct tc_taprio_qopt_offload *taprio = type_data; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ int err; -+ int i; -+ -+ for (i = 0; i < priv->num_tx_rings; i++) -+ enetc_set_bdr_prio(&priv->si->hw, -+ priv->tx_ring[i]->index, -+ taprio->enable ? i : 0); -+ -+ err = enetc_setup_taprio(ndev, taprio); -+ -+ if (err) -+ for (i = 0; i < priv->num_tx_rings; i++) -+ enetc_set_bdr_prio(&priv->si->hw, -+ priv->tx_ring[i]->index, -+ taprio->enable ? 0 : i); -+ -+ return err; -+} diff --git a/target/linux/layerscape/patches-5.4/701-net-0226-enetc-update-TSN-Qbv-PSPEED-set-according-to-adjust-.patch b/target/linux/layerscape/patches-5.4/701-net-0226-enetc-update-TSN-Qbv-PSPEED-set-according-to-adjust-.patch deleted file mode 100644 index b2f229e002..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0226-enetc-update-TSN-Qbv-PSPEED-set-according-to-adjust-.patch +++ /dev/null @@ -1,171 +0,0 @@ -From 877119a3f6bce2d9091faa4e51490917be8a3158 Mon Sep 17 00:00:00 2001 -From: Po Liu -Date: Fri, 15 Nov 2019 03:33:41 +0000 -Subject: [PATCH] enetc: update TSN Qbv PSPEED set according to adjust link - speed - -ENETC has a register PSPEED to indicate the link speed of hardware. -It is need to update accordingly. PSPEED field needs to be updated -with the port speed for QBV scheduling purposes. Or else there is -chance for gate slot not free by frame taking the MAC if PSPEED and -phy speed not match. So update PSPEED when link adjust. This is -implement by the adjust_link. - -Signed-off-by: Po Liu -Signed-off-by: Claudiu Manoil -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/freescale/enetc/enetc.c | 13 +++++++-- - drivers/net/ethernet/freescale/enetc/enetc.h | 8 ++++++ - drivers/net/ethernet/freescale/enetc/enetc_hw.h | 5 ++++ - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 3 +++ - drivers/net/ethernet/freescale/enetc/enetc_qos.c | 34 ++++++++++++++++++++++++ - 5 files changed, 61 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc.c -@@ -742,9 +742,14 @@ void enetc_get_si_caps(struct enetc_si * - si->num_rss = 0; - val = enetc_rd(hw, ENETC_SIPCAPR0); - if (val & ENETC_SIPCAPR0_RSS) { -- val = enetc_rd(hw, ENETC_SIRSSCAPR); -- si->num_rss = ENETC_SIRSSCAPR_GET_NUM_RSS(val); -+ u32 rss; -+ -+ rss = enetc_rd(hw, ENETC_SIRSSCAPR); -+ si->num_rss = ENETC_SIRSSCAPR_GET_NUM_RSS(rss); - } -+ -+ if (val & ENETC_SIPCAPR0_QBV) -+ si->hw_features |= ENETC_SI_F_QBV; - } - - static int enetc_dma_alloc_bdr(struct enetc_bdr *r, size_t bd_size) -@@ -1306,8 +1311,12 @@ static void enetc_disable_interrupts(str - - static void adjust_link(struct net_device *ndev) - { -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); - struct phy_device *phydev = ndev->phydev; - -+ if (priv->active_offloads & ENETC_F_QBV) -+ enetc_sched_speed_set(ndev); -+ - phy_print_status(phydev); - } - ---- a/drivers/net/ethernet/freescale/enetc/enetc.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc.h -@@ -118,6 +118,8 @@ enum enetc_errata { - ENETC_ERR_UCMCSWP = BIT(2), - }; - -+#define ENETC_SI_F_QBV BIT(0) -+ - /* PCI IEP device data */ - struct enetc_si { - struct pci_dev *pdev; -@@ -133,6 +135,7 @@ struct enetc_si { - int num_fs_entries; - int num_rss; /* number of RSS buckets */ - unsigned short pad; -+ int hw_features; - }; - - #define ENETC_SI_ALIGN 32 -@@ -173,6 +176,7 @@ struct enetc_cls_rule { - enum enetc_active_offloads { - ENETC_F_RX_TSTAMP = BIT(0), - ENETC_F_TX_TSTAMP = BIT(1), -+ ENETC_F_QBV = BIT(2), - }; - - struct enetc_ndev_priv { -@@ -188,6 +192,8 @@ struct enetc_ndev_priv { - u16 msg_enable; - int active_offloads; - -+ u32 speed; /* store speed for compare update pspeed */ -+ - struct enetc_bdr *tx_ring[16]; - struct enetc_bdr *rx_ring[16]; - -@@ -253,6 +259,8 @@ int enetc_send_cmd(struct enetc_si *si, - - #ifdef CONFIG_FSL_ENETC_QOS - int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data); -+void enetc_sched_speed_set(struct net_device *ndev); - #else - #define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP -+#define enetc_sched_speed_set(ndev) (void)0 - #endif ---- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h -@@ -149,6 +149,11 @@ enum enetc_bdr_type {TX, RX}; - #define ENETC_PORT_BASE 0x10000 - #define ENETC_PMR 0x0000 - #define ENETC_PMR_EN GENMASK(18, 16) -+#define ENETC_PMR_PSPEED_MASK GENMASK(11, 8) -+#define ENETC_PMR_PSPEED_10M 0 -+#define ENETC_PMR_PSPEED_100M BIT(8) -+#define ENETC_PMR_PSPEED_1000M BIT(9) -+#define ENETC_PMR_PSPEED_2500M BIT(10) - #define ENETC_PSR 0x0004 /* RO */ - #define ENETC_PSIPMR 0x0018 - #define ENETC_PSIPMR_SET_UP(n) BIT(n) /* n = SI index */ ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -742,6 +742,9 @@ static void enetc_pf_netdev_setup(struct - - ndev->priv_flags |= IFF_UNICAST_FLT; - -+ if (si->hw_features & ENETC_SI_F_QBV) -+ priv->active_offloads |= ENETC_F_QBV; -+ - /* pick up primary MAC address from SI */ - enetc_get_primary_mac_addr(&si->hw, ndev->dev_addr); - } ---- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c -@@ -11,6 +11,40 @@ static u16 enetc_get_max_gcl_len(struct - & ENETC_QBV_MAX_GCL_LEN_MASK; - } - -+void enetc_sched_speed_set(struct net_device *ndev) -+{ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ struct phy_device *phydev = ndev->phydev; -+ u32 old_speed = priv->speed; -+ u32 speed, pspeed; -+ -+ if (phydev->speed == old_speed) -+ return; -+ -+ speed = phydev->speed; -+ switch (speed) { -+ case SPEED_1000: -+ pspeed = ENETC_PMR_PSPEED_1000M; -+ break; -+ case SPEED_2500: -+ pspeed = ENETC_PMR_PSPEED_2500M; -+ break; -+ case SPEED_100: -+ pspeed = ENETC_PMR_PSPEED_100M; -+ break; -+ case SPEED_10: -+ default: -+ pspeed = ENETC_PMR_PSPEED_10M; -+ netdev_err(ndev, "Qbv PSPEED set speed link down.\n"); -+ } -+ -+ priv->speed = speed; -+ enetc_port_wr(&priv->si->hw, ENETC_PMR, -+ (enetc_port_rd(&priv->si->hw, ENETC_PMR) -+ & (~ENETC_PMR_PSPEED_MASK)) -+ | pspeed); -+} -+ - static int enetc_setup_taprio(struct net_device *ndev, - struct tc_taprio_qopt_offload *admin_conf) - { diff --git a/target/linux/layerscape/patches-5.4/701-net-0227-enetc-Fix-if_mode-extraction.patch b/target/linux/layerscape/patches-5.4/701-net-0227-enetc-Fix-if_mode-extraction.patch deleted file mode 100644 index 37cbcd9777..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0227-enetc-Fix-if_mode-extraction.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 7b75e86c2cfc9fa48b582b04e939f18a54bdfa2e Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Tue, 13 Aug 2019 13:59:24 +0300 -Subject: [PATCH] enetc: Fix if_mode extraction - -If if_mode not found then just handle it as fixed link -(i.e mac2mac connection). - -Signed-off-by: Claudiu Manoil ---- - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 17 ++++++----------- - 1 file changed, 6 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -754,6 +754,7 @@ static int enetc_of_get_phy(struct enetc - struct enetc_pf *pf = enetc_si_priv(priv->si); - struct device_node *np = priv->dev->of_node; - struct device_node *mdio_np; -+ int phy_mode; - int err; - - if (!np) { -@@ -787,17 +788,11 @@ static int enetc_of_get_phy(struct enetc - } - } - -- priv->if_mode = of_get_phy_mode(np); -- if ((int)priv->if_mode < 0) { -- dev_err(priv->dev, "missing phy type\n"); -- of_node_put(priv->phy_node); -- if (of_phy_is_fixed_link(np)) -- of_phy_deregister_fixed_link(np); -- else -- enetc_mdio_remove(pf); -- -- return -EINVAL; -- } -+ phy_mode = of_get_phy_mode(np); -+ if (phy_mode < 0) -+ priv->if_mode = PHY_INTERFACE_MODE_NA; /* fixed link */ -+ else -+ priv->if_mode = phy_mode; - - return 0; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0228-enetc-Make-mdio-accessors-more-generic.patch b/target/linux/layerscape/patches-5.4/701-net-0228-enetc-Make-mdio-accessors-more-generic.patch deleted file mode 100644 index e83a0f9f66..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0228-enetc-Make-mdio-accessors-more-generic.patch +++ /dev/null @@ -1,221 +0,0 @@ -From 141fc778365ac0f1584ade0fd419af871e681646 Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Mon, 12 Aug 2019 20:26:42 +0300 -Subject: [PATCH] enetc: Make mdio accessors more generic - -Refactoring needed to support multiple MDIO buses. -'mdio_base' - MDIO registers base address - is being parameterized. -The MDIO accessors are made more generic to be able to work with -different MDIO register bases. -Some includes get cleaned up in the process. - -Signed-off-by: Claudiu Manoil ---- - drivers/net/ethernet/freescale/enetc/enetc_hw.h | 1 + - drivers/net/ethernet/freescale/enetc/enetc_mdio.c | 60 +++++++++++++--------- - drivers/net/ethernet/freescale/enetc/enetc_mdio.h | 2 +- - .../net/ethernet/freescale/enetc/enetc_pci_mdio.c | 2 + - 4 files changed, 39 insertions(+), 26 deletions(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h -@@ -200,6 +200,7 @@ enum enetc_bdr_type {TX, RX}; - #define ENETC_PFPMR 0x1900 - #define ENETC_PFPMR_PMACE BIT(1) - #define ENETC_PFPMR_MWLM BIT(0) -+#define ENETC_EMDIO_BASE 0x1c00 - #define ENETC_PSIUMHFR0(n, err) (((err) ? 0x1d08 : 0x1d00) + (n) * 0x10) - #define ENETC_PSIUMHFR1(n) (0x1d04 + (n) * 0x10) - #define ENETC_PSIMMHFR0(n, err) (((err) ? 0x1d00 : 0x1d08) + (n) * 0x10) ---- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_mdio.c -@@ -6,19 +6,30 @@ - #include - #include - -+#include "enetc_pf.h" - #include "enetc_mdio.h" - --#define ENETC_MDIO_REG_OFFSET 0x1c00 - #define ENETC_MDIO_CFG 0x0 /* MDIO configuration and status */ - #define ENETC_MDIO_CTL 0x4 /* MDIO control */ - #define ENETC_MDIO_DATA 0x8 /* MDIO data */ - #define ENETC_MDIO_ADDR 0xc /* MDIO address */ - --#define enetc_mdio_rd(hw, off) \ -- enetc_port_rd(hw, ENETC_##off + ENETC_MDIO_REG_OFFSET) --#define enetc_mdio_wr(hw, off, val) \ -- enetc_port_wr(hw, ENETC_##off + ENETC_MDIO_REG_OFFSET, val) --#define enetc_mdio_rd_reg(off) enetc_mdio_rd(hw, off) -+static inline u32 _enetc_mdio_rd(struct enetc_mdio_priv *mdio_priv, int off) -+{ -+ return enetc_port_rd(mdio_priv->hw, mdio_priv->mdio_base + off); -+} -+ -+static inline void _enetc_mdio_wr(struct enetc_mdio_priv *mdio_priv, int off, -+ u32 val) -+{ -+ enetc_port_wr(mdio_priv->hw, mdio_priv->mdio_base + off, val); -+} -+ -+#define enetc_mdio_rd(mdio_priv, off) \ -+ _enetc_mdio_rd(mdio_priv, ENETC_##off) -+#define enetc_mdio_wr(mdio_priv, off, val) \ -+ _enetc_mdio_wr(mdio_priv, ENETC_##off, val) -+#define enetc_mdio_rd_reg(off) enetc_mdio_rd(mdio_priv, off) - - #define ENETC_MDC_DIV 258 - -@@ -35,7 +46,7 @@ - #define MDIO_DATA(x) ((x) & 0xffff) - - #define TIMEOUT 1000 --static int enetc_mdio_wait_complete(struct enetc_hw *hw) -+static int enetc_mdio_wait_complete(struct enetc_mdio_priv *mdio_priv) - { - u32 val; - -@@ -46,7 +57,6 @@ static int enetc_mdio_wait_complete(stru - int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value) - { - struct enetc_mdio_priv *mdio_priv = bus->priv; -- struct enetc_hw *hw = mdio_priv->hw; - u32 mdio_ctl, mdio_cfg; - u16 dev_addr; - int ret; -@@ -61,29 +71,29 @@ int enetc_mdio_write(struct mii_bus *bus - mdio_cfg &= ~MDIO_CFG_ENC45; - } - -- enetc_mdio_wr(hw, MDIO_CFG, mdio_cfg); -+ enetc_mdio_wr(mdio_priv, MDIO_CFG, mdio_cfg); - -- ret = enetc_mdio_wait_complete(hw); -+ ret = enetc_mdio_wait_complete(mdio_priv); - if (ret) - return ret; - - /* set port and dev addr */ - mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr); -- enetc_mdio_wr(hw, MDIO_CTL, mdio_ctl); -+ enetc_mdio_wr(mdio_priv, MDIO_CTL, mdio_ctl); - - /* set the register address */ - if (regnum & MII_ADDR_C45) { -- enetc_mdio_wr(hw, MDIO_ADDR, regnum & 0xffff); -+ enetc_mdio_wr(mdio_priv, MDIO_ADDR, regnum & 0xffff); - -- ret = enetc_mdio_wait_complete(hw); -+ ret = enetc_mdio_wait_complete(mdio_priv); - if (ret) - return ret; - } - - /* write the value */ -- enetc_mdio_wr(hw, MDIO_DATA, MDIO_DATA(value)); -+ enetc_mdio_wr(mdio_priv, MDIO_DATA, MDIO_DATA(value)); - -- ret = enetc_mdio_wait_complete(hw); -+ ret = enetc_mdio_wait_complete(mdio_priv); - if (ret) - return ret; - -@@ -93,7 +103,6 @@ int enetc_mdio_write(struct mii_bus *bus - int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum) - { - struct enetc_mdio_priv *mdio_priv = bus->priv; -- struct enetc_hw *hw = mdio_priv->hw; - u32 mdio_ctl, mdio_cfg; - u16 dev_addr, value; - int ret; -@@ -107,41 +116,41 @@ int enetc_mdio_read(struct mii_bus *bus, - mdio_cfg &= ~MDIO_CFG_ENC45; - } - -- enetc_mdio_wr(hw, MDIO_CFG, mdio_cfg); -+ enetc_mdio_wr(mdio_priv, MDIO_CFG, mdio_cfg); - -- ret = enetc_mdio_wait_complete(hw); -+ ret = enetc_mdio_wait_complete(mdio_priv); - if (ret) - return ret; - - /* set port and device addr */ - mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr); -- enetc_mdio_wr(hw, MDIO_CTL, mdio_ctl); -+ enetc_mdio_wr(mdio_priv, MDIO_CTL, mdio_ctl); - - /* set the register address */ - if (regnum & MII_ADDR_C45) { -- enetc_mdio_wr(hw, MDIO_ADDR, regnum & 0xffff); -+ enetc_mdio_wr(mdio_priv, MDIO_ADDR, regnum & 0xffff); - -- ret = enetc_mdio_wait_complete(hw); -+ ret = enetc_mdio_wait_complete(mdio_priv); - if (ret) - return ret; - } - - /* initiate the read */ -- enetc_mdio_wr(hw, MDIO_CTL, mdio_ctl | MDIO_CTL_READ); -+ enetc_mdio_wr(mdio_priv, MDIO_CTL, mdio_ctl | MDIO_CTL_READ); - -- ret = enetc_mdio_wait_complete(hw); -+ ret = enetc_mdio_wait_complete(mdio_priv); - if (ret) - return ret; - - /* return all Fs if nothing was there */ -- if (enetc_mdio_rd(hw, MDIO_CFG) & MDIO_CFG_RD_ER) { -+ if (enetc_mdio_rd(mdio_priv, MDIO_CFG) & MDIO_CFG_RD_ER) { - dev_dbg(&bus->dev, - "Error while reading PHY%d reg at %d.%hhu\n", - phy_id, dev_addr, regnum); - return 0xffff; - } - -- value = enetc_mdio_rd(hw, MDIO_DATA) & 0xffff; -+ value = enetc_mdio_rd(mdio_priv, MDIO_DATA) & 0xffff; - - return value; - } -@@ -164,6 +173,7 @@ int enetc_mdio_probe(struct enetc_pf *pf - bus->parent = dev; - mdio_priv = bus->priv; - mdio_priv->hw = &pf->si->hw; -+ mdio_priv->mdio_base = ENETC_EMDIO_BASE; - snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev)); - - np = of_get_child_by_name(dev->of_node, "mdio"); ---- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_mdio.h -@@ -2,10 +2,10 @@ - /* Copyright 2019 NXP */ - - #include --#include "enetc_pf.h" - - struct enetc_mdio_priv { - struct enetc_hw *hw; -+ int mdio_base; - }; - - int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value); ---- a/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c -@@ -1,6 +1,7 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) - /* Copyright 2019 NXP */ - #include -+#include "enetc_pf.h" - #include "enetc_mdio.h" - - #define ENETC_MDIO_DEV_ID 0xee01 -@@ -31,6 +32,7 @@ static int enetc_pci_mdio_probe(struct p - bus->parent = dev; - mdio_priv = bus->priv; - mdio_priv->hw = hw; -+ mdio_priv->mdio_base = ENETC_EMDIO_BASE; - snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev)); - - pcie_flr(pdev); diff --git a/target/linux/layerscape/patches-5.4/701-net-0229-enetc-Initialize-SerDes-for-SGMII-and-SXGMII-protoco.patch b/target/linux/layerscape/patches-5.4/701-net-0229-enetc-Initialize-SerDes-for-SGMII-and-SXGMII-protoco.patch deleted file mode 100644 index a7e8c6860e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0229-enetc-Initialize-SerDes-for-SGMII-and-SXGMII-protoco.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 6943ed031ee75f13a950e293f92db68ea2ec2786 Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Wed, 14 Aug 2019 14:34:47 +0300 -Subject: [PATCH] enetc: Initialize SerDes for SGMII and SXGMII protocols - -ENETC has ethernet MACs capable of SGMII and SXGMII but -in order to use these protocols some serdes configurations -need to be performed. -The serdes is configurable via an internal MDIO bus -connected to an internal PCS device, all reads/writes are -performed at address 0. -This patch basically removes the dependecy on a bootloader -regarding serdes initialization. - -Signed-off-by: Alex Marginean -Signed-off-by: Claudiu Manoil ---- - drivers/net/ethernet/freescale/enetc/enetc_hw.h | 17 +++++++ - drivers/net/ethernet/freescale/enetc/enetc_mdio.c | 24 +++++++++ - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 59 +++++++++++++++++++++++ - drivers/net/ethernet/freescale/enetc/enetc_pf.h | 2 + - 4 files changed, 102 insertions(+) - ---- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h -@@ -223,6 +223,23 @@ enum enetc_bdr_type {TX, RX}; - #define ENETC_PM0_MAXFRM 0x8014 - #define ENETC_SET_TX_MTU(val) ((val) << 16) - #define ENETC_SET_MAXFRM(val) ((val) & 0xffff) -+ -+#define ENETC_PM_IMDIO_BASE 0x8030 -+/* PCS registers */ -+#define ENETC_PCS_CR 0x0 -+#define ENETC_PCS_CR_RESET_AN 0x1200 -+#define ENETC_PCS_CR_DEF_VAL 0x0140 -+#define ENETC_PCS_CR_LANE_RESET 0x8000 -+#define ENETC_PCS_DEV_ABILITY 0x04 -+#define ENETC_PCS_DEV_ABILITY_SGMII 0x4001 -+#define ENETC_PCS_DEV_ABILITY_SXGMII 0x5001 -+#define ENETC_PCS_LINK_TIMER1 0x12 -+#define ENETC_PCS_LINK_TIMER1_VAL 0x06a0 -+#define ENETC_PCS_LINK_TIMER2 0x13 -+#define ENETC_PCS_LINK_TIMER2_VAL 0x0003 -+#define ENETC_PCS_IF_MODE 0x14 -+#define ENETC_PCS_IF_MODE_SGMII_AN 0x0003 -+ - #define ENETC_PM0_IF_MODE 0x8300 - #define ENETC_PMO_IFM_RG BIT(2) - #define ENETC_PM0_IFM_RLP (BIT(5) | BIT(11)) ---- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_mdio.c -@@ -200,3 +200,27 @@ void enetc_mdio_remove(struct enetc_pf * - if (pf->mdio) - mdiobus_unregister(pf->mdio); - } -+ -+int enetc_imdio_init(struct enetc_pf *pf) -+{ -+ struct device *dev = &pf->si->pdev->dev; -+ struct enetc_mdio_priv *mdio_priv; -+ struct mii_bus *bus; -+ -+ bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv)); -+ if (!bus) -+ return -ENOMEM; -+ -+ bus->name = "FSL ENETC internal MDIO Bus"; -+ bus->read = enetc_mdio_read; -+ bus->write = enetc_mdio_write; -+ bus->parent = dev; -+ mdio_priv = bus->priv; -+ mdio_priv->hw = &pf->si->hw; -+ mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev)); -+ -+ pf->imdio = bus; -+ -+ return 0; -+} ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -872,6 +872,61 @@ static void enetc_init_unused_port(struc - enetc_free_cbdr(dev, &si->cbd_ring); - } - -+static void enetc_configure_sgmii(struct mii_bus *imdio) -+{ -+ /* Set to SGMII mode, use AN */ -+ imdio->write(imdio, 0, ENETC_PCS_IF_MODE, -+ ENETC_PCS_IF_MODE_SGMII_AN); -+ -+ /* Dev ability - SGMII */ -+ imdio->write(imdio, 0, ENETC_PCS_DEV_ABILITY, -+ ENETC_PCS_DEV_ABILITY_SGMII); -+ -+ /* Adjust link timer for SGMII */ -+ imdio->write(imdio, 0, ENETC_PCS_LINK_TIMER1, -+ ENETC_PCS_LINK_TIMER1_VAL); -+ imdio->write(imdio, 0, ENETC_PCS_LINK_TIMER2, -+ ENETC_PCS_LINK_TIMER2_VAL); -+ -+ /* restart PCS AN */ -+ imdio->write(imdio, 0, ENETC_PCS_CR, -+ ENETC_PCS_CR_RESET_AN | ENETC_PCS_CR_DEF_VAL); -+} -+ -+static void enetc_configure_sxgmii(struct mii_bus *imdio) -+{ -+ /* Dev ability - SXGMII */ -+ imdio->write(imdio, 0, MII_ADDR_C45 | (MDIO_MMD_VEND2 << 16) | -+ ENETC_PCS_DEV_ABILITY, ENETC_PCS_DEV_ABILITY_SXGMII); -+ -+ /* Restart PCS AN */ -+ imdio->write(imdio, 0, MII_ADDR_C45 | (MDIO_MMD_VEND2 << 16) | -+ ENETC_PCS_CR, -+ ENETC_PCS_CR_LANE_RESET | ENETC_PCS_CR_RESET_AN); -+} -+ -+static int enetc_configure_serdes(struct enetc_ndev_priv *priv) -+{ -+ struct enetc_pf *pf = enetc_si_priv(priv->si); -+ int err; -+ -+ if (priv->if_mode != PHY_INTERFACE_MODE_SGMII && -+ priv->if_mode != PHY_INTERFACE_MODE_XGMII) -+ return 0; -+ -+ err = enetc_imdio_init(pf); -+ if (err) -+ return err; -+ -+ if (priv->if_mode == PHY_INTERFACE_MODE_SGMII) -+ enetc_configure_sgmii(pf->imdio); -+ -+ if (priv->if_mode == PHY_INTERFACE_MODE_XGMII) -+ enetc_configure_sxgmii(pf->imdio); -+ -+ return 0; -+} -+ - static int enetc_pf_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) - { -@@ -956,6 +1011,10 @@ static int enetc_pf_probe(struct pci_dev - if (err) - dev_warn(&pdev->dev, "Fallback to PHY-less operation\n"); - -+ err = enetc_configure_serdes(priv); -+ if (err) -+ dev_warn(&pdev->dev, "Attempted serdes config but failed\n"); -+ - err = register_netdev(ndev); - if (err) - goto err_reg_netdev; ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h -@@ -44,6 +44,7 @@ struct enetc_pf { - DECLARE_BITMAP(active_vlans, VLAN_N_VID); - - struct mii_bus *mdio; /* saved for cleanup */ -+ struct mii_bus *imdio; - }; - - int enetc_msg_psi_init(struct enetc_pf *pf); -@@ -53,3 +54,4 @@ void enetc_msg_handle_rxmsg(struct enetc - /* MDIO */ - int enetc_mdio_probe(struct enetc_pf *pf); - void enetc_mdio_remove(struct enetc_pf *pf); -+int enetc_imdio_init(struct enetc_pf *pf); diff --git a/target/linux/layerscape/patches-5.4/701-net-0230-enetc-Drop-redundant-device-node-check.patch b/target/linux/layerscape/patches-5.4/701-net-0230-enetc-Drop-redundant-device-node-check.patch deleted file mode 100644 index a67124116f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0230-enetc-Drop-redundant-device-node-check.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 219e330d8b6b5e3f84a7a593969f948bf2fec558 Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Fri, 6 Sep 2019 16:17:20 +0300 -Subject: [PATCH] enetc: Drop redundant device node check - -The existence of the DT port node is the first thing checked -at probe time, and probing won't continue if the node is missing. - -Signed-off-by: Claudiu Manoil ---- - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 5 ----- - 1 file changed, 5 deletions(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -757,11 +757,6 @@ static int enetc_of_get_phy(struct enetc - int phy_mode; - int err; - -- if (!np) { -- dev_err(priv->dev, "missing ENETC port node\n"); -- return -ENODEV; -- } -- - priv->phy_node = of_parse_phandle(np, "phy-handle", 0); - if (!priv->phy_node) { - if (!of_phy_is_fixed_link(np)) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0231-enetc-Use-DT-protocol-information-to-set-up-the-port.patch b/target/linux/layerscape/patches-5.4/701-net-0231-enetc-Use-DT-protocol-information-to-set-up-the-port.patch deleted file mode 100644 index 8c3ea7fbbe..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0231-enetc-Use-DT-protocol-information-to-set-up-the-port.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 98f64a89977a32df96cdb8aaf3884086b2309924 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 27 Aug 2019 15:14:11 +0300 -Subject: [PATCH] enetc: Use DT protocol information to set up the ports - -Use DT information rather than in-band information from bootloader to -set up MAC for XGMII. For RGMII use the DT indication in addition to -RGMII defaults in hardware. -However, this implies that PHY connection information needs to be -extracted before netdevice creation, when the ENETC Port MAC is -being configured. - -Signed-off-by: Alex Marginean -Signed-off-by: Claudiu Manoil ---- - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 55 ++++++++++++++----------- - drivers/net/ethernet/freescale/enetc/enetc_pf.h | 3 ++ - 2 files changed, 33 insertions(+), 25 deletions(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -507,7 +507,8 @@ static void enetc_port_si_configure(stru - enetc_port_wr(hw, ENETC_PSIVLANFMR, ENETC_PSIVLANFMR_VS); - } - --static void enetc_configure_port_mac(struct enetc_hw *hw) -+static void enetc_configure_port_mac(struct enetc_hw *hw, -+ phy_interface_t phy_mode) - { - enetc_port_wr(hw, ENETC_PM0_MAXFRM, - ENETC_SET_MAXFRM(ENETC_RX_MAXFRM_SIZE)); -@@ -523,9 +524,11 @@ static void enetc_configure_port_mac(str - ENETC_PM0_CMD_TXP | ENETC_PM0_PROMISC | - ENETC_PM0_TX_EN | ENETC_PM0_RX_EN); - /* set auto-speed for RGMII */ -- if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG) -+ if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG || -+ phy_mode == PHY_INTERFACE_MODE_RGMII) - enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO); -- if (enetc_global_rd(hw, ENETC_G_EPFBLPR(1)) == ENETC_G_EPFBLPR1_XGMII) -+ -+ if (phy_mode == PHY_INTERFACE_MODE_XGMII) - enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII); - } - -@@ -549,7 +552,7 @@ static void enetc_configure_port(struct - - enetc_configure_port_pmac(hw); - -- enetc_configure_port_mac(hw); -+ enetc_configure_port_mac(hw, pf->if_mode); - - enetc_port_si_configure(pf->si); - -@@ -749,28 +752,28 @@ static void enetc_pf_netdev_setup(struct - enetc_get_primary_mac_addr(&si->hw, ndev->dev_addr); - } - --static int enetc_of_get_phy(struct enetc_ndev_priv *priv) -+static int enetc_of_get_phy(struct enetc_pf *pf) - { -- struct enetc_pf *pf = enetc_si_priv(priv->si); -- struct device_node *np = priv->dev->of_node; -+ struct device *dev = &pf->si->pdev->dev; -+ struct device_node *np = dev->of_node; - struct device_node *mdio_np; - int phy_mode; - int err; - -- priv->phy_node = of_parse_phandle(np, "phy-handle", 0); -- if (!priv->phy_node) { -+ pf->phy_node = of_parse_phandle(np, "phy-handle", 0); -+ if (!pf->phy_node) { - if (!of_phy_is_fixed_link(np)) { -- dev_err(priv->dev, "PHY not specified\n"); -+ dev_err(dev, "PHY not specified\n"); - return -ENODEV; - } - - err = of_phy_register_fixed_link(np); - if (err < 0) { -- dev_err(priv->dev, "fixed link registration failed\n"); -+ dev_err(dev, "fixed link registration failed\n"); - return err; - } - -- priv->phy_node = of_node_get(np); -+ pf->phy_node = of_node_get(np); - } - - mdio_np = of_get_child_by_name(np, "mdio"); -@@ -778,28 +781,28 @@ static int enetc_of_get_phy(struct enetc - of_node_put(mdio_np); - err = enetc_mdio_probe(pf); - if (err) { -- of_node_put(priv->phy_node); -+ of_node_put(pf->phy_node); - return err; - } - } - - phy_mode = of_get_phy_mode(np); - if (phy_mode < 0) -- priv->if_mode = PHY_INTERFACE_MODE_NA; /* fixed link */ -+ pf->if_mode = PHY_INTERFACE_MODE_NA; /* fixed link */ - else -- priv->if_mode = phy_mode; -+ pf->if_mode = phy_mode; - - return 0; - } - --static void enetc_of_put_phy(struct enetc_ndev_priv *priv) -+static void enetc_of_put_phy(struct enetc_pf *pf) - { -- struct device_node *np = priv->dev->of_node; -+ struct device_node *np = pf->si->pdev->dev.of_node; - - if (np && of_phy_is_fixed_link(np)) - of_phy_deregister_fixed_link(np); -- if (priv->phy_node) -- of_node_put(priv->phy_node); -+ if (pf->phy_node) -+ of_node_put(pf->phy_node); - } - - /* Initialize the entire shared memory for the flow steering entries -@@ -955,6 +958,10 @@ static int enetc_pf_probe(struct pci_dev - pf->si = si; - pf->total_vfs = pci_sriov_get_totalvfs(pdev); - -+ err = enetc_of_get_phy(pf); -+ if (err) -+ dev_warn(&pdev->dev, "Fallback to PHY-less operation\n"); -+ - enetc_configure_port(pf); - - enetc_get_si_caps(si); -@@ -969,6 +976,8 @@ static int enetc_pf_probe(struct pci_dev - enetc_pf_netdev_setup(si, ndev, &enetc_ndev_ops); - - priv = netdev_priv(ndev); -+ priv->phy_node = pf->phy_node; -+ priv->if_mode = pf->if_mode; - - enetc_init_si_rings_params(priv); - -@@ -1002,10 +1011,6 @@ static int enetc_pf_probe(struct pci_dev - goto err_alloc_msix; - } - -- err = enetc_of_get_phy(priv); -- if (err) -- dev_warn(&pdev->dev, "Fallback to PHY-less operation\n"); -- - err = enetc_configure_serdes(priv); - if (err) - dev_warn(&pdev->dev, "Attempted serdes config but failed\n"); -@@ -1023,7 +1028,6 @@ static int enetc_pf_probe(struct pci_dev - - err_reg_netdev: - enetc_mdio_remove(pf); -- enetc_of_put_phy(priv); - enetc_free_msix(priv); - err_config_si: - err_init_port_rss: -@@ -1034,6 +1038,7 @@ err_alloc_si_res: - si->ndev = NULL; - free_netdev(ndev); - err_alloc_netdev: -+ enetc_of_put_phy(pf); - err_device_disabled: - err_map_pf_space: - enetc_pci_remove(pdev); -@@ -1057,7 +1062,7 @@ static void enetc_pf_remove(struct pci_d - unregister_netdev(si->ndev); - - enetc_mdio_remove(pf); -- enetc_of_put_phy(priv); -+ enetc_of_put_phy(pf); - - enetc_free_msix(priv); - ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h -@@ -45,6 +45,9 @@ struct enetc_pf { - - struct mii_bus *mdio; /* saved for cleanup */ - struct mii_bus *imdio; -+ -+ struct device_node *phy_node; -+ phy_interface_t if_mode; - }; - - int enetc_msg_psi_init(struct enetc_pf *pf); diff --git a/target/linux/layerscape/patches-5.4/701-net-0232-enetc-Handle-USXGMII-protocol.patch b/target/linux/layerscape/patches-5.4/701-net-0232-enetc-Handle-USXGMII-protocol.patch deleted file mode 100644 index 8d4db97a26..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0232-enetc-Handle-USXGMII-protocol.patch +++ /dev/null @@ -1,45 +0,0 @@ -From bb700603e66a1294049aa479ad560443496c893b Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Fri, 20 Sep 2019 19:41:10 +0300 -Subject: [PATCH] enetc: Handle USXGMII protocol - -Adds USXGMII protocol which is now supported in Linux. XGMII is kept for -compatibility although there is no plain XGMII support in ENETC. - -Signed-off-by: Alex Marginean ---- - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -528,7 +528,8 @@ static void enetc_configure_port_mac(str - phy_mode == PHY_INTERFACE_MODE_RGMII) - enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO); - -- if (phy_mode == PHY_INTERFACE_MODE_XGMII) -+ if (phy_mode == PHY_INTERFACE_MODE_XGMII || -+ phy_mode == PHY_INTERFACE_MODE_USXGMII) - enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII); - } - -@@ -909,7 +910,8 @@ static int enetc_configure_serdes(struct - int err; - - if (priv->if_mode != PHY_INTERFACE_MODE_SGMII && -- priv->if_mode != PHY_INTERFACE_MODE_XGMII) -+ priv->if_mode != PHY_INTERFACE_MODE_XGMII && -+ priv->if_mode != PHY_INTERFACE_MODE_USXGMII) - return 0; - - err = enetc_imdio_init(pf); -@@ -919,7 +921,8 @@ static int enetc_configure_serdes(struct - if (priv->if_mode == PHY_INTERFACE_MODE_SGMII) - enetc_configure_sgmii(pf->imdio); - -- if (priv->if_mode == PHY_INTERFACE_MODE_XGMII) -+ if (priv->if_mode == PHY_INTERFACE_MODE_XGMII || -+ priv->if_mode == PHY_INTERFACE_MODE_USXGMII) - enetc_configure_sxgmii(pf->imdio); - - return 0; diff --git a/target/linux/layerscape/patches-5.4/701-net-0233-enetc-Enable-live-mac-addr-change-for-PF.patch b/target/linux/layerscape/patches-5.4/701-net-0233-enetc-Enable-live-mac-addr-change-for-PF.patch deleted file mode 100644 index 20b59685d2..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0233-enetc-Enable-live-mac-addr-change-for-PF.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 9a963c982be787902892354a6ad669a5644b8338 Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Mon, 16 Sep 2019 19:22:08 +0300 -Subject: [PATCH] enetc: Enable live mac addr change for PF - -Use device flag IFF_LIVE_ADDR_CHANGE to signal that -the device supports changing the primary mac address -for a ENETC port, when the PF eth interface is running. -This capability is required by certain applications, -like bonding mode 6 (Adaptive Load Balancing). - -Signed-off-by: Claudiu Manoil ---- - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -744,7 +744,7 @@ static void enetc_pf_netdev_setup(struct - ndev->features &= ~NETIF_F_HW_CSUM; - } - -- ndev->priv_flags |= IFF_UNICAST_FLT; -+ ndev->priv_flags |= IFF_UNICAST_FLT | IFF_LIVE_ADDR_CHANGE; - - if (si->hw_features & ENETC_SI_F_QBV) - priv->active_offloads |= ENETC_F_QBV; diff --git a/target/linux/layerscape/patches-5.4/701-net-0234-enetc-WA-for-MDIO-register-access-issue.patch b/target/linux/layerscape/patches-5.4/701-net-0234-enetc-WA-for-MDIO-register-access-issue.patch deleted file mode 100644 index 73dbdc752a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0234-enetc-WA-for-MDIO-register-access-issue.patch +++ /dev/null @@ -1,409 +0,0 @@ -From 0f62a794b41ad14a962c70445844d61a8097805e Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 20 Aug 2019 12:34:22 +0300 -Subject: [PATCH] enetc: WA for MDIO register access issue - -Due to a hardware issue access to MDIO registers concurrent with other -ENETC register access may lead to the MDIO access being dropped or -corrupted. The workaround introduces locking for all register access in -ENETC space. To reduce performance impact, code except MDIO uses per-cpu -locks, MDIO code having to acquire all per-CPU locks to perform an access. -To further reduce the performance impact, datapath functions acquire the -per-cpu lock fewer times and use _hot accessors. All the rest of the code -uses the _wa accessors which lock every time a register is accessed. - -Signed-off-by: Alex Marginean ---- - drivers/net/ethernet/freescale/enetc/enetc.c | 85 ++++++++++++++---- - drivers/net/ethernet/freescale/enetc/enetc_hw.h | 105 +++++++++++++++++++++- - drivers/net/ethernet/freescale/enetc/enetc_mdio.c | 4 +- - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 3 + - 4 files changed, 176 insertions(+), 21 deletions(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc.c -@@ -20,8 +20,13 @@ netdev_tx_t enetc_xmit(struct sk_buff *s - { - struct enetc_ndev_priv *priv = netdev_priv(ndev); - struct enetc_bdr *tx_ring; -+ unsigned long flags; -+ /* pointer to per-cpu ENETC lock for register access issue WA */ -+ spinlock_t *lock; - int count; - -+ lock = this_cpu_ptr(&enetc_gregs); -+ - tx_ring = priv->tx_ring[skb->queue_mapping]; - - if (unlikely(skb_shinfo(skb)->nr_frags > ENETC_MAX_SKB_FRAGS)) -@@ -34,7 +39,12 @@ netdev_tx_t enetc_xmit(struct sk_buff *s - return NETDEV_TX_BUSY; - } - -+ spin_lock_irqsave(lock, flags); -+ - count = enetc_map_tx_buffs(tx_ring, skb, priv->active_offloads); -+ -+ spin_unlock_irqrestore(lock, flags); -+ - if (unlikely(!count)) - goto drop_packet_err; - -@@ -228,7 +238,7 @@ static int enetc_map_tx_buffs(struct ene - tx_ring->next_to_use = i; - - /* let H/W know BD ring has been updated */ -- enetc_wr_reg(tx_ring->tpir, i); /* includes wmb() */ -+ enetc_wr_reg_hot(tx_ring->tpir, i); /* includes wmb() */ - - return count; - -@@ -249,13 +259,21 @@ dma_err: - static irqreturn_t enetc_msix(int irq, void *data) - { - struct enetc_int_vector *v = data; -+ unsigned long flags; -+ /* pointer to per-cpu ENETC lock for register access issue WA */ -+ spinlock_t *lock; - int i; - -+ lock = this_cpu_ptr(&enetc_gregs); -+ spin_lock_irqsave(lock, flags); -+ - /* disable interrupts */ -- enetc_wr_reg(v->rbier, 0); -+ enetc_wr_reg_hot(v->rbier, 0); - - for_each_set_bit(i, &v->tx_rings_map, ENETC_MAX_NUM_TXQS) -- enetc_wr_reg(v->tbier_base + ENETC_BDR_OFF(i), 0); -+ enetc_wr_reg_hot(v->tbier_base + ENETC_BDR_OFF(i), 0); -+ -+ spin_unlock_irqrestore(lock, flags); - - napi_schedule_irqoff(&v->napi); - -@@ -271,6 +289,9 @@ static int enetc_poll(struct napi_struct - struct enetc_int_vector - *v = container_of(napi, struct enetc_int_vector, napi); - bool complete = true; -+ unsigned long flags; -+ /* pointer to per-cpu ENETC lock for register access issue WA */ -+ spinlock_t *lock; - int work_done; - int i; - -@@ -287,19 +308,24 @@ static int enetc_poll(struct napi_struct - - napi_complete_done(napi, work_done); - -+ lock = this_cpu_ptr(&enetc_gregs); -+ spin_lock_irqsave(lock, flags); -+ - /* enable interrupts */ -- enetc_wr_reg(v->rbier, ENETC_RBIER_RXTIE); -+ enetc_wr_reg_hot(v->rbier, ENETC_RBIER_RXTIE); - - for_each_set_bit(i, &v->tx_rings_map, ENETC_MAX_NUM_TXQS) -- enetc_wr_reg(v->tbier_base + ENETC_BDR_OFF(i), -- ENETC_TBIER_TXTIE); -+ enetc_wr_reg_hot(v->tbier_base + ENETC_BDR_OFF(i), -+ ENETC_TBIER_TXTIE); -+ -+ spin_unlock_irqrestore(lock, flags); - - return work_done; - } - - static int enetc_bd_ready_count(struct enetc_bdr *tx_ring, int ci) - { -- int pi = enetc_rd_reg(tx_ring->tcir) & ENETC_TBCIR_IDX_MASK; -+ int pi = enetc_rd_reg_hot(tx_ring->tcir) & ENETC_TBCIR_IDX_MASK; - - return pi >= ci ? pi - ci : tx_ring->bd_count - ci + pi; - } -@@ -337,9 +363,18 @@ static bool enetc_clean_tx_ring(struct e - bool do_tstamp; - u64 tstamp = 0; - -+ unsigned long flags; -+ /* pointer to per-cpu ENETC lock for register access issue WA */ -+ spinlock_t *lock; -+ -+ lock = this_cpu_ptr(&enetc_gregs); -+ - i = tx_ring->next_to_clean; - tx_swbd = &tx_ring->tx_swbd[i]; -+ -+ spin_lock_irqsave(lock, flags); - bds_to_clean = enetc_bd_ready_count(tx_ring, i); -+ spin_unlock_irqrestore(lock, flags); - - do_tstamp = false; - -@@ -382,16 +417,20 @@ static bool enetc_clean_tx_ring(struct e - tx_swbd = tx_ring->tx_swbd; - } - -+ spin_lock_irqsave(lock, flags); -+ - /* BD iteration loop end */ - if (is_eof) { - tx_frm_cnt++; - /* re-arm interrupt source */ -- enetc_wr_reg(tx_ring->idr, BIT(tx_ring->index) | -- BIT(16 + tx_ring->index)); -+ enetc_wr_reg_hot(tx_ring->idr, BIT(tx_ring->index) | -+ BIT(16 + tx_ring->index)); - } - - if (unlikely(!bds_to_clean)) - bds_to_clean = enetc_bd_ready_count(tx_ring, i); -+ -+ spin_unlock_irqrestore(lock, flags); - } - - tx_ring->next_to_clean = i; -@@ -470,13 +509,14 @@ static int enetc_refill_rx_ring(struct e - rx_ring->next_to_alloc = i; /* keep track from page reuse */ - rx_ring->next_to_use = i; - /* update ENETC's consumer index */ -- enetc_wr_reg(rx_ring->rcir, i); -+ enetc_wr_reg_hot(rx_ring->rcir, i); - } - - return j; - } - - #ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING -+/* Must be called with &enetc_gregs spinlock held */ - static void enetc_get_rx_tstamp(struct net_device *ndev, - union enetc_rx_bd *rxbd, - struct sk_buff *skb) -@@ -488,8 +528,8 @@ static void enetc_get_rx_tstamp(struct n - u64 tstamp; - - if (le16_to_cpu(rxbd->r.flags) & ENETC_RXBD_FLAG_TSTMP) { -- lo = enetc_rd(hw, ENETC_SICTR0); -- hi = enetc_rd(hw, ENETC_SICTR1); -+ lo = enetc_rd_reg_hot(hw->reg + ENETC_SICTR0); -+ hi = enetc_rd_reg_hot(hw->reg + ENETC_SICTR1); - tstamp_lo = le32_to_cpu(rxbd->r.tstamp); - if (lo <= tstamp_lo) - hi -= 1; -@@ -627,6 +667,12 @@ static int enetc_clean_rx_ring(struct en - int rx_frm_cnt = 0, rx_byte_cnt = 0; - int cleaned_cnt, i; - -+ unsigned long flags; -+ /* pointer to per-cpu ENETC lock for register access issue WA */ -+ spinlock_t *lock; -+ -+ lock = this_cpu_ptr(&enetc_gregs); -+ - cleaned_cnt = enetc_bd_unused(rx_ring); - /* next descriptor to process */ - i = rx_ring->next_to_clean; -@@ -637,6 +683,8 @@ static int enetc_clean_rx_ring(struct en - u32 bd_status; - u16 size; - -+ spin_lock_irqsave(lock, flags); -+ - if (cleaned_cnt >= ENETC_RXBD_BUNDLE) { - int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt); - -@@ -645,15 +693,19 @@ static int enetc_clean_rx_ring(struct en - - rxbd = ENETC_RXBD(*rx_ring, i); - bd_status = le32_to_cpu(rxbd->r.lstatus); -- if (!bd_status) -+ if (!bd_status) { -+ spin_unlock_irqrestore(lock, flags); - break; -+ } - -- enetc_wr_reg(rx_ring->idr, BIT(rx_ring->index)); -+ enetc_wr_reg_hot(rx_ring->idr, BIT(rx_ring->index)); - dma_rmb(); /* for reading other rxbd fields */ - size = le16_to_cpu(rxbd->r.buf_len); - skb = enetc_map_rx_buff_to_skb(rx_ring, i, size); -- if (!skb) -+ if (!skb) { -+ spin_unlock_irqrestore(lock, flags); - break; -+ } - - enetc_get_offloads(rx_ring, rxbd, skb); - -@@ -667,6 +719,7 @@ static int enetc_clean_rx_ring(struct en - - if (unlikely(bd_status & - ENETC_RXBD_LSTATUS(ENETC_RXBD_ERR_MASK))) { -+ spin_unlock_irqrestore(lock, flags); - dev_kfree_skb(skb); - while (!(bd_status & ENETC_RXBD_LSTATUS_F)) { - dma_rmb(); -@@ -710,6 +763,8 @@ static int enetc_clean_rx_ring(struct en - - enetc_process_skb(rx_ring, skb); - -+ spin_unlock_irqrestore(lock, flags); -+ - napi_gro_receive(napi, skb); - - rx_frm_cnt++; ---- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h -@@ -327,8 +327,15 @@ struct enetc_hw { - }; - - /* general register accessors */ --#define enetc_rd_reg(reg) ioread32((reg)) --#define enetc_wr_reg(reg, val) iowrite32((val), (reg)) -+#define enetc_rd_reg(reg) enetc_rd_reg_wa((reg)) -+#define enetc_wr_reg(reg, val) enetc_wr_reg_wa((reg), (val)) -+ -+/* accessors for data-path, due to MDIO issue on LS1028 these should be called -+ * only under enetc_gregs per-cpu lock -+ */ -+#define enetc_rd_reg_hot(reg) ioread32((reg)) -+#define enetc_wr_reg_hot(reg, val) iowrite32((val), (reg)) -+ - #ifdef ioread64 - #define enetc_rd_reg64(reg) ioread64((reg)) - #else -@@ -347,12 +354,102 @@ static inline u64 enetc_rd_reg64(void __ - } - #endif - -+extern DEFINE_PER_CPU(spinlock_t, enetc_gregs); -+ -+static inline u32 enetc_rd_reg_wa(void *reg) -+{ -+ unsigned long flags; -+ /* pointer to per-cpu ENETC lock for register access issue WA */ -+ spinlock_t *lock; -+ u32 val; -+ -+ lock = this_cpu_ptr(&enetc_gregs); -+ spin_lock_irqsave(lock, flags); -+ val = ioread32(reg); -+ spin_unlock_irqrestore(lock, flags); -+ -+ return val; -+} -+ -+static inline void enetc_wr_reg_wa(void *reg, u32 val) -+{ -+ unsigned long flags; -+ /* pointer to per-cpu ENETC lock for register access issue WA */ -+ spinlock_t *lock; -+ -+ lock = this_cpu_ptr(&enetc_gregs); -+ spin_lock_irqsave(lock, flags); -+ iowrite32(val, reg); -+ spin_unlock_irqrestore(lock, flags); -+} -+ -+/* NR_CPUS=256 in ARM64 defconfig and using it as array size triggers stack -+ * frame warnings for the functions below. Use a custom define of 2 for now, -+ * LS1028 has just two cores. -+ */ -+#define ENETC_NR_CPU_LOCKS 2 -+ -+static inline u32 enetc_rd_reg_wa_single(void *reg) -+{ -+ u32 val; -+ int cpu; -+ /* per-cpu ENETC lock array for register access issue WA */ -+ spinlock_t *lock[ENETC_NR_CPU_LOCKS]; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ preempt_disable(); -+ -+ for_each_online_cpu(cpu) { -+ lock[cpu] = per_cpu_ptr(&enetc_gregs, cpu); -+ spin_lock(lock[cpu]); -+ } -+ -+ val = ioread32(reg); -+ -+ for_each_online_cpu(cpu) -+ spin_unlock(lock[cpu]); -+ local_irq_restore(flags); -+ -+ preempt_enable(); -+ -+ return val; -+} -+ -+static inline void enetc_wr_reg_wa_single(void *reg, u32 val) -+{ -+ int cpu; -+ /* per-cpu ENETC lock array for register access issue WA */ -+ spinlock_t *lock[ENETC_NR_CPU_LOCKS]; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ preempt_disable(); -+ -+ for_each_online_cpu(cpu) { -+ lock[cpu] = per_cpu_ptr(&enetc_gregs, cpu); -+ spin_lock(lock[cpu]); -+ } -+ -+ iowrite32(val, reg); -+ -+ for_each_online_cpu(cpu) -+ spin_unlock(lock[cpu]); -+ local_irq_restore(flags); -+ -+ preempt_enable(); -+} -+ - #define enetc_rd(hw, off) enetc_rd_reg((hw)->reg + (off)) - #define enetc_wr(hw, off, val) enetc_wr_reg((hw)->reg + (off), val) - #define enetc_rd64(hw, off) enetc_rd_reg64((hw)->reg + (off)) - /* port register accessors - PF only */ --#define enetc_port_rd(hw, off) enetc_rd_reg((hw)->port + (off)) --#define enetc_port_wr(hw, off, val) enetc_wr_reg((hw)->port + (off), val) -+#define enetc_port_rd(hw, off) enetc_rd_reg_wa((hw)->port + (off)) -+#define enetc_port_wr(hw, off, val) enetc_wr_reg_wa((hw)->port + (off), val) -+#define enetc_port_rd_single(hw, off) enetc_rd_reg_wa_single(\ -+ (hw)->port + (off)) -+#define enetc_port_wr_single(hw, off, val) enetc_wr_reg_wa_single(\ -+ (hw)->port + (off), val) - /* global register accessors - PF only */ - #define enetc_global_rd(hw, off) enetc_rd_reg((hw)->global + (off)) - #define enetc_global_wr(hw, off, val) enetc_wr_reg((hw)->global + (off), val) ---- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_mdio.c -@@ -16,13 +16,13 @@ - - static inline u32 _enetc_mdio_rd(struct enetc_mdio_priv *mdio_priv, int off) - { -- return enetc_port_rd(mdio_priv->hw, mdio_priv->mdio_base + off); -+ return enetc_port_rd_single(mdio_priv->hw, mdio_priv->mdio_base + off); - } - - static inline void _enetc_mdio_wr(struct enetc_mdio_priv *mdio_priv, int off, - u32 val) - { -- enetc_port_wr(mdio_priv->hw, mdio_priv->mdio_base + off, val); -+ enetc_port_wr_single(mdio_priv->hw, mdio_priv->mdio_base + off, val); - } - - #define enetc_mdio_rd(mdio_priv, off) \ ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -1076,6 +1076,9 @@ static void enetc_pf_remove(struct pci_d - enetc_pci_remove(pdev); - } - -+DEFINE_PER_CPU(spinlock_t, enetc_gregs); -+EXPORT_PER_CPU_SYMBOL(enetc_gregs); -+ - static const struct pci_device_id enetc_pf_id_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PF) }, - { 0, } /* End of table. */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0235-enetc-Clean-up-of-ehtool-stats-len.patch b/target/linux/layerscape/patches-5.4/701-net-0235-enetc-Clean-up-of-ehtool-stats-len.patch deleted file mode 100644 index 1602feb3bd..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0235-enetc-Clean-up-of-ehtool-stats-len.patch +++ /dev/null @@ -1,44 +0,0 @@ -From a5e4a018cf5c7ed9709141c41ba7b262aa79870d Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Tue, 22 Oct 2019 20:23:38 +0300 -Subject: [PATCH] enetc: Clean up of ehtool stats len - -Just refactoring stats len code to make it easier to -add new stats counters. - -Signed-off-by: Claudiu Manoil ---- - drivers/net/ethernet/freescale/enetc/enetc_ethtool.c | 20 +++++++++++++------- - 1 file changed, 13 insertions(+), 7 deletions(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c -@@ -199,15 +199,21 @@ static const char tx_ring_stats[][ETH_GS - static int enetc_get_sset_count(struct net_device *ndev, int sset) - { - struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ int len; - -- if (sset == ETH_SS_STATS) -- return ARRAY_SIZE(enetc_si_counters) + -- ARRAY_SIZE(tx_ring_stats) * priv->num_tx_rings + -- ARRAY_SIZE(rx_ring_stats) * priv->num_rx_rings + -- (enetc_si_is_pf(priv->si) ? -- ARRAY_SIZE(enetc_port_counters) : 0); -+ if (sset != ETH_SS_STATS) -+ return -EOPNOTSUPP; - -- return -EOPNOTSUPP; -+ len = ARRAY_SIZE(enetc_si_counters) + -+ ARRAY_SIZE(tx_ring_stats) * priv->num_tx_rings + -+ ARRAY_SIZE(rx_ring_stats) * priv->num_rx_rings; -+ -+ if (!enetc_si_is_pf(priv->si)) -+ return len; -+ -+ len += ARRAY_SIZE(enetc_port_counters); -+ -+ return len; - } - - static void enetc_get_strings(struct net_device *ndev, u32 stringset, u8 *data) diff --git a/target/linux/layerscape/patches-5.4/701-net-0236-enetc-Replace-enetc_gregs-with-a-readers-writer-lock.patch b/target/linux/layerscape/patches-5.4/701-net-0236-enetc-Replace-enetc_gregs-with-a-readers-writer-lock.patch deleted file mode 100644 index cb164d4ffb..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0236-enetc-Replace-enetc_gregs-with-a-readers-writer-lock.patch +++ /dev/null @@ -1,385 +0,0 @@ -From 659f899773f9f3fdc8325f61acc1017dd838126c Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 14 Nov 2019 17:30:50 +0200 -Subject: [PATCH] enetc: Replace enetc_gregs with a readers-writer lock - -The LS1028A MDIO errata tells us that any MDIO register access must not -be concurrent with any other ENETC register access. - -That has been handled so far by a number of per-CPU spinlocks over the -ENETC register map. This came as an optimization over a single spinlock, -because the regular register accesses can still be concurrent with one -another, as long as they aren't concurrent with MDIO. - -But this logic is broken in RT, because the enetc_rd_reg_wa and -enetc_wr_reg_wa functions can be preempted in any context, and when they -resume they may not run on the same CPU. - -This renders the logic to take the per-CPU spinlock pointless, since the -spinlock may not be the correct one (corresponding to this CPU) after -preemption has occurred. - -The following splat is telling us the same thing: - -[ 19.073928] BUG: using smp_processor_id() in preemptible [00000000] code: systemd-network/3423 -[ 19.073932] caller is debug_smp_processor_id+0x1c/0x30 -[ 19.073935] CPU: 1 PID: 3423 Comm: systemd-network Not tainted 4.19.68-rt26 #1 -[ 19.073936] Hardware name: LS1028A RDB Board (DT) -[ 19.073938] Call trace: -[ 19.073940] dump_backtrace+0x0/0x1a0 -[ 19.073942] show_stack+0x24/0x30 -[ 19.073945] dump_stack+0x9c/0xdc -[ 19.073948] check_preemption_disabled+0xe0/0x100 -[ 19.073951] debug_smp_processor_id+0x1c/0x30 -[ 19.073954] enetc_open+0x1b0/0xbc0 -[ 19.073957] __dev_open+0xdc/0x160 -[ 19.073960] __dev_change_flags+0x160/0x1d0 -[ 19.073963] dev_change_flags+0x34/0x70 -[ 19.073966] do_setlink+0x2a0/0xcd0 -[ 19.073969] rtnl_setlink+0xe4/0x140 -[ 19.073972] rtnetlink_rcv_msg+0x18c/0x500 -[ 19.073975] netlink_rcv_skb+0x60/0x120 -[ 19.073978] rtnetlink_rcv+0x28/0x40 -[ 19.073982] netlink_unicast+0x194/0x210 -[ 19.073985] netlink_sendmsg+0x194/0x330 -[ 19.073987] sock_sendmsg+0x34/0x50 -[ 19.073990] __sys_sendto+0xe4/0x150 -[ 19.073992] __arm64_sys_sendto+0x30/0x40 -[ 19.073996] el0_svc_common+0xa4/0x1a0 -[ 19.073999] el0_svc_handler+0x38/0x80 -[ 19.074002] el0_svc+0x8/0xc - -But there already exists a spinlock optimized for the single writer, -multiple readers case: the rwlock_t. The writer in this case is the MDIO -access code (irrelevant whether that MDIO access is a register read or -write), and the reader is everybody else. - -This patch also fixes two more existing bugs in the errata workaround: -- The MDIO access code was not unlocking the per-CPU spinlocks in the - reverse order of their locking order. -- The per-CPU spinlock array was not initialized. - -Fixes: 5ec0d668d62e ("enetc: WA for MDIO register access issue") -Signed-off-by: Vladimir Oltean -Signed-off-by: Claudiu Manoil ---- - drivers/net/ethernet/freescale/enetc/enetc.c | 59 ++++++---------------- - drivers/net/ethernet/freescale/enetc/enetc_hw.h | 67 ++++--------------------- - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 5 +- - 3 files changed, 30 insertions(+), 101 deletions(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc.c -@@ -20,13 +20,8 @@ netdev_tx_t enetc_xmit(struct sk_buff *s - { - struct enetc_ndev_priv *priv = netdev_priv(ndev); - struct enetc_bdr *tx_ring; -- unsigned long flags; -- /* pointer to per-cpu ENETC lock for register access issue WA */ -- spinlock_t *lock; - int count; - -- lock = this_cpu_ptr(&enetc_gregs); -- - tx_ring = priv->tx_ring[skb->queue_mapping]; - - if (unlikely(skb_shinfo(skb)->nr_frags > ENETC_MAX_SKB_FRAGS)) -@@ -39,11 +34,9 @@ netdev_tx_t enetc_xmit(struct sk_buff *s - return NETDEV_TX_BUSY; - } - -- spin_lock_irqsave(lock, flags); -- -+ read_lock(&enetc_mdio_lock); - count = enetc_map_tx_buffs(tx_ring, skb, priv->active_offloads); -- -- spin_unlock_irqrestore(lock, flags); -+ read_unlock(&enetc_mdio_lock); - - if (unlikely(!count)) - goto drop_packet_err; -@@ -259,13 +252,9 @@ dma_err: - static irqreturn_t enetc_msix(int irq, void *data) - { - struct enetc_int_vector *v = data; -- unsigned long flags; -- /* pointer to per-cpu ENETC lock for register access issue WA */ -- spinlock_t *lock; - int i; - -- lock = this_cpu_ptr(&enetc_gregs); -- spin_lock_irqsave(lock, flags); -+ read_lock(&enetc_mdio_lock); - - /* disable interrupts */ - enetc_wr_reg_hot(v->rbier, 0); -@@ -273,7 +262,7 @@ static irqreturn_t enetc_msix(int irq, v - for_each_set_bit(i, &v->tx_rings_map, ENETC_MAX_NUM_TXQS) - enetc_wr_reg_hot(v->tbier_base + ENETC_BDR_OFF(i), 0); - -- spin_unlock_irqrestore(lock, flags); -+ read_unlock(&enetc_mdio_lock); - - napi_schedule_irqoff(&v->napi); - -@@ -289,9 +278,6 @@ static int enetc_poll(struct napi_struct - struct enetc_int_vector - *v = container_of(napi, struct enetc_int_vector, napi); - bool complete = true; -- unsigned long flags; -- /* pointer to per-cpu ENETC lock for register access issue WA */ -- spinlock_t *lock; - int work_done; - int i; - -@@ -308,8 +294,7 @@ static int enetc_poll(struct napi_struct - - napi_complete_done(napi, work_done); - -- lock = this_cpu_ptr(&enetc_gregs); -- spin_lock_irqsave(lock, flags); -+ read_lock(&enetc_mdio_lock); - - /* enable interrupts */ - enetc_wr_reg_hot(v->rbier, ENETC_RBIER_RXTIE); -@@ -318,7 +303,7 @@ static int enetc_poll(struct napi_struct - enetc_wr_reg_hot(v->tbier_base + ENETC_BDR_OFF(i), - ENETC_TBIER_TXTIE); - -- spin_unlock_irqrestore(lock, flags); -+ read_unlock(&enetc_mdio_lock); - - return work_done; - } -@@ -363,18 +348,12 @@ static bool enetc_clean_tx_ring(struct e - bool do_tstamp; - u64 tstamp = 0; - -- unsigned long flags; -- /* pointer to per-cpu ENETC lock for register access issue WA */ -- spinlock_t *lock; -- -- lock = this_cpu_ptr(&enetc_gregs); -- - i = tx_ring->next_to_clean; - tx_swbd = &tx_ring->tx_swbd[i]; - -- spin_lock_irqsave(lock, flags); -+ read_lock(&enetc_mdio_lock); - bds_to_clean = enetc_bd_ready_count(tx_ring, i); -- spin_unlock_irqrestore(lock, flags); -+ read_unlock(&enetc_mdio_lock); - - do_tstamp = false; - -@@ -417,7 +396,7 @@ static bool enetc_clean_tx_ring(struct e - tx_swbd = tx_ring->tx_swbd; - } - -- spin_lock_irqsave(lock, flags); -+ read_lock(&enetc_mdio_lock); - - /* BD iteration loop end */ - if (is_eof) { -@@ -430,7 +409,7 @@ static bool enetc_clean_tx_ring(struct e - if (unlikely(!bds_to_clean)) - bds_to_clean = enetc_bd_ready_count(tx_ring, i); - -- spin_unlock_irqrestore(lock, flags); -+ read_unlock(&enetc_mdio_lock); - } - - tx_ring->next_to_clean = i; -@@ -516,7 +495,7 @@ static int enetc_refill_rx_ring(struct e - } - - #ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING --/* Must be called with &enetc_gregs spinlock held */ -+/* Must be called with the read-side enetc_mdio_lock held */ - static void enetc_get_rx_tstamp(struct net_device *ndev, - union enetc_rx_bd *rxbd, - struct sk_buff *skb) -@@ -667,12 +646,6 @@ static int enetc_clean_rx_ring(struct en - int rx_frm_cnt = 0, rx_byte_cnt = 0; - int cleaned_cnt, i; - -- unsigned long flags; -- /* pointer to per-cpu ENETC lock for register access issue WA */ -- spinlock_t *lock; -- -- lock = this_cpu_ptr(&enetc_gregs); -- - cleaned_cnt = enetc_bd_unused(rx_ring); - /* next descriptor to process */ - i = rx_ring->next_to_clean; -@@ -683,7 +656,7 @@ static int enetc_clean_rx_ring(struct en - u32 bd_status; - u16 size; - -- spin_lock_irqsave(lock, flags); -+ read_lock(&enetc_mdio_lock); - - if (cleaned_cnt >= ENETC_RXBD_BUNDLE) { - int count = enetc_refill_rx_ring(rx_ring, cleaned_cnt); -@@ -694,7 +667,7 @@ static int enetc_clean_rx_ring(struct en - rxbd = ENETC_RXBD(*rx_ring, i); - bd_status = le32_to_cpu(rxbd->r.lstatus); - if (!bd_status) { -- spin_unlock_irqrestore(lock, flags); -+ read_unlock(&enetc_mdio_lock); - break; - } - -@@ -703,7 +676,7 @@ static int enetc_clean_rx_ring(struct en - size = le16_to_cpu(rxbd->r.buf_len); - skb = enetc_map_rx_buff_to_skb(rx_ring, i, size); - if (!skb) { -- spin_unlock_irqrestore(lock, flags); -+ read_unlock(&enetc_mdio_lock); - break; - } - -@@ -719,7 +692,7 @@ static int enetc_clean_rx_ring(struct en - - if (unlikely(bd_status & - ENETC_RXBD_LSTATUS(ENETC_RXBD_ERR_MASK))) { -- spin_unlock_irqrestore(lock, flags); -+ read_unlock(&enetc_mdio_lock); - dev_kfree_skb(skb); - while (!(bd_status & ENETC_RXBD_LSTATUS_F)) { - dma_rmb(); -@@ -763,7 +736,7 @@ static int enetc_clean_rx_ring(struct en - - enetc_process_skb(rx_ring, skb); - -- spin_unlock_irqrestore(lock, flags); -+ read_unlock(&enetc_mdio_lock); - - napi_gro_receive(napi, skb); - ---- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h -@@ -331,7 +331,7 @@ struct enetc_hw { - #define enetc_wr_reg(reg, val) enetc_wr_reg_wa((reg), (val)) - - /* accessors for data-path, due to MDIO issue on LS1028 these should be called -- * only under enetc_gregs per-cpu lock -+ * only under the rwlock_t enetc_mdio_lock - */ - #define enetc_rd_reg_hot(reg) ioread32((reg)) - #define enetc_wr_reg_hot(reg, val) iowrite32((val), (reg)) -@@ -354,90 +354,45 @@ static inline u64 enetc_rd_reg64(void __ - } - #endif - --extern DEFINE_PER_CPU(spinlock_t, enetc_gregs); -+extern rwlock_t enetc_mdio_lock; - - static inline u32 enetc_rd_reg_wa(void *reg) - { -- unsigned long flags; -- /* pointer to per-cpu ENETC lock for register access issue WA */ -- spinlock_t *lock; - u32 val; - -- lock = this_cpu_ptr(&enetc_gregs); -- spin_lock_irqsave(lock, flags); -+ read_lock(&enetc_mdio_lock); - val = ioread32(reg); -- spin_unlock_irqrestore(lock, flags); -+ read_unlock(&enetc_mdio_lock); - - return val; - } - - static inline void enetc_wr_reg_wa(void *reg, u32 val) - { -- unsigned long flags; -- /* pointer to per-cpu ENETC lock for register access issue WA */ -- spinlock_t *lock; -- -- lock = this_cpu_ptr(&enetc_gregs); -- spin_lock_irqsave(lock, flags); -+ read_lock(&enetc_mdio_lock); - iowrite32(val, reg); -- spin_unlock_irqrestore(lock, flags); -+ read_unlock(&enetc_mdio_lock); - } - --/* NR_CPUS=256 in ARM64 defconfig and using it as array size triggers stack -- * frame warnings for the functions below. Use a custom define of 2 for now, -- * LS1028 has just two cores. -- */ --#define ENETC_NR_CPU_LOCKS 2 -- - static inline u32 enetc_rd_reg_wa_single(void *reg) - { -- u32 val; -- int cpu; -- /* per-cpu ENETC lock array for register access issue WA */ -- spinlock_t *lock[ENETC_NR_CPU_LOCKS]; - unsigned long flags; -+ u32 val; - -- local_irq_save(flags); -- preempt_disable(); -- -- for_each_online_cpu(cpu) { -- lock[cpu] = per_cpu_ptr(&enetc_gregs, cpu); -- spin_lock(lock[cpu]); -- } -- -+ write_lock_irqsave(&enetc_mdio_lock, flags); - val = ioread32(reg); -- -- for_each_online_cpu(cpu) -- spin_unlock(lock[cpu]); -- local_irq_restore(flags); -- -- preempt_enable(); -+ write_unlock_irqrestore(&enetc_mdio_lock, flags); - - return val; - } - - static inline void enetc_wr_reg_wa_single(void *reg, u32 val) - { -- int cpu; -- /* per-cpu ENETC lock array for register access issue WA */ -- spinlock_t *lock[ENETC_NR_CPU_LOCKS]; - unsigned long flags; - -- local_irq_save(flags); -- preempt_disable(); -- -- for_each_online_cpu(cpu) { -- lock[cpu] = per_cpu_ptr(&enetc_gregs, cpu); -- spin_lock(lock[cpu]); -- } -- -+ write_lock_irqsave(&enetc_mdio_lock, flags); - iowrite32(val, reg); -- -- for_each_online_cpu(cpu) -- spin_unlock(lock[cpu]); -- local_irq_restore(flags); -- -- preempt_enable(); -+ write_unlock_irqrestore(&enetc_mdio_lock, flags); - } - - #define enetc_rd(hw, off) enetc_rd_reg((hw)->reg + (off)) ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -1076,8 +1076,9 @@ static void enetc_pf_remove(struct pci_d - enetc_pci_remove(pdev); - } - --DEFINE_PER_CPU(spinlock_t, enetc_gregs); --EXPORT_PER_CPU_SYMBOL(enetc_gregs); -+/* Lock for MDIO access errata on LS1028A */ -+DEFINE_RWLOCK(enetc_mdio_lock); -+EXPORT_SYMBOL_GPL(enetc_mdio_lock); - - static const struct pci_device_id enetc_pf_id_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PF) }, diff --git a/target/linux/layerscape/patches-5.4/701-net-0237-enetc-Remove-mdio-bus-on-PF-probe-error-path.patch b/target/linux/layerscape/patches-5.4/701-net-0237-enetc-Remove-mdio-bus-on-PF-probe-error-path.patch deleted file mode 100644 index 064621eaea..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0237-enetc-Remove-mdio-bus-on-PF-probe-error-path.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 73204b342fbee1fd9364365c1213815cc715eee2 Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Thu, 14 Nov 2019 16:22:39 +0200 -Subject: [PATCH] enetc: Remove mdio bus on PF probe error path - -Fixes following kernel panic on the probing error -path, when pci=nomsi bootarg is used (which is -not supporrted by the enetc dirver): - -fsl_enetc 0000:00:00.0: MSIX alloc failed -------------[ cut here ]------------ -kernel BUG at drivers/net/phy/mdio_bus.c:487! -Internal error: Oops - BUG: 0 [#1] PREEMPT SMP -Modules linked in: -Process swapper/0 (pid: 1, stack limit = 0x(____ptrval____)) -CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.68-00004-g85dc4876e6e6 #1 -Hardware name: LS1028A RDB Board (DT) -pstate: 80000005 (Nzcv daif -PAN -UAO) -pc : mdiobus_free+0x5c/0x60 -lr : _devm_mdiobus_free+0x20/0x30 -[...] -Call trace: - mdiobus_free+0x5c/0x60 - _devm_mdiobus_free+0x20/0x30 - release_nodes+0x148/0x238 - devres_release_all+0x3c/0x68 - really_probe+0x90/0x2a0 - driver_probe_device+0x5c/0x100 - __driver_attach+0xf0/0xf8 - bus_for_each_dev+0x84/0xd8 - driver_attach+0x30/0x40 - bus_add_driver+0x1c4/0x230 - driver_register+0x64/0x110 - __pci_register_driver+0x58/0x68 - enetc_pf_driver_init+0x28/0x30 - do_one_initcall+0x54/0x268 - kernel_init_freeable+0x2d0/0x37c - kernel_init+0x18/0x118 - ret_from_fork+0x10/0x1c -Code: 97e0dd79 f9400bf3 a8c27bfd d65f03c0 (d4210000) ----[ end trace 1e4e5729f059b773 ]--- - -Fixes: ebfcb23d62ab ("enetc: Add ENETC PF level external MDIO support") -Signed-off-by: Claudiu Manoil ---- - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -1041,6 +1041,7 @@ err_alloc_si_res: - si->ndev = NULL; - free_netdev(ndev); - err_alloc_netdev: -+ enetc_mdio_remove(pf); - enetc_of_put_phy(pf); - err_device_disabled: - err_map_pf_space: diff --git a/target/linux/layerscape/patches-5.4/701-net-0238-net-mscc-ocelot-break-apart-ocelot_vlan_port_apply.patch b/target/linux/layerscape/patches-5.4/701-net-0238-net-mscc-ocelot-break-apart-ocelot_vlan_port_apply.patch deleted file mode 100644 index f3db7da458..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0238-net-mscc-ocelot-break-apart-ocelot_vlan_port_apply.patch +++ /dev/null @@ -1,314 +0,0 @@ -From d00ac78e74e433109307f365ba90d34cd73aaf20 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:47 +0200 -Subject: [PATCH] net: mscc: ocelot: break apart ocelot_vlan_port_apply - -This patch transforms the ocelot_vlan_port_apply function ("apply -what?") into 3 standalone functions: - -- ocelot_port_vlan_filtering -- ocelot_port_set_native_vlan -- ocelot_port_set_pvid - -These functions have a prototype that is better aligned to the DSA API. - -The function also had some static initialization (TPID, drop frames with -multicast source MAC) which was not being changed from any place, so -that was just moved to ocelot_probe_port (one of the 6 callers of -ocelot_vlan_port_apply). - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 168 ++++++++++++++++++++++--------------- - 1 file changed, 100 insertions(+), 68 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -185,65 +185,97 @@ static void ocelot_vlan_mode(struct ocel - ocelot_write(ocelot, val, ANA_VLANMASK); - } - --static void ocelot_vlan_port_apply(struct ocelot *ocelot, -- struct ocelot_port *port) -+static void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, -+ bool vlan_aware) - { -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; - u32 val; - -- /* Ingress clasification (ANA_PORT_VLAN_CFG) */ -- /* Default vlan to clasify for untagged frames (may be zero) */ -- val = ANA_PORT_VLAN_CFG_VLAN_VID(port->pvid); -- if (port->vlan_aware) -- val |= ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA | -- ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1); -- -+ if (vlan_aware) -+ val = ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA | -+ ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1); -+ else -+ val = 0; - ocelot_rmw_gix(ocelot, val, -- ANA_PORT_VLAN_CFG_VLAN_VID_M | - ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA | - ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M, -- ANA_PORT_VLAN_CFG, port->chip_port); -+ ANA_PORT_VLAN_CFG, port); - -- /* Drop frames with multicast source address */ -- val = ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA; -- if (port->vlan_aware && !port->vid) -+ if (vlan_aware && !ocelot_port->vid) - /* If port is vlan-aware and tagged, drop untagged and priority - * tagged frames. - */ -- val |= ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA | -+ val = ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA | -+ ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA | -+ ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA; -+ else -+ val = 0; -+ ocelot_rmw_gix(ocelot, val, -+ ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA | - ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA | -- ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA; -- ocelot_write_gix(ocelot, val, ANA_PORT_DROP_CFG, port->chip_port); -- -- /* Egress configuration (REW_TAG_CFG): VLAN tag type to 8021Q. */ -- val = REW_TAG_CFG_TAG_TPID_CFG(0); -+ ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA, -+ ANA_PORT_DROP_CFG, port); - -- if (port->vlan_aware) { -- if (port->vid) -+ if (vlan_aware) { -+ if (ocelot_port->vid) - /* Tag all frames except when VID == DEFAULT_VLAN */ - val |= REW_TAG_CFG_TAG_CFG(1); - else - /* Tag all frames */ - val |= REW_TAG_CFG_TAG_CFG(3); -+ } else { -+ /* Port tagging disabled. */ -+ val = REW_TAG_CFG_TAG_CFG(0); - } - ocelot_rmw_gix(ocelot, val, -- REW_TAG_CFG_TAG_TPID_CFG_M | - REW_TAG_CFG_TAG_CFG_M, -- REW_TAG_CFG, port->chip_port); -+ REW_TAG_CFG, port); - -- /* Set default VLAN and tag type to 8021Q. */ -- val = REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q) | -- REW_PORT_VLAN_CFG_PORT_VID(port->vid); -- ocelot_rmw_gix(ocelot, val, -- REW_PORT_VLAN_CFG_PORT_TPID_M | -+ ocelot_port->vlan_aware = vlan_aware; -+} -+ -+static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port, -+ u16 vid) -+{ -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ -+ if (ocelot_port->vid != vid) { -+ /* Always permit deleting the native VLAN (vid = 0) */ -+ if (ocelot_port->vid && vid) { -+ dev_err(ocelot->dev, -+ "Port already has a native VLAN: %d\n", -+ ocelot_port->vid); -+ return -EBUSY; -+ } -+ ocelot_port->vid = vid; -+ } -+ -+ ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_VID(vid), - REW_PORT_VLAN_CFG_PORT_VID_M, -- REW_PORT_VLAN_CFG, port->chip_port); -+ REW_PORT_VLAN_CFG, port); -+ -+ return 0; -+} -+ -+/* Default vlan to clasify for untagged frames (may be zero) */ -+static void ocelot_port_set_pvid(struct ocelot *ocelot, int port, u16 pvid) -+{ -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ -+ ocelot_rmw_gix(ocelot, -+ ANA_PORT_VLAN_CFG_VLAN_VID(pvid), -+ ANA_PORT_VLAN_CFG_VLAN_VID_M, -+ ANA_PORT_VLAN_CFG, port); -+ -+ ocelot_port->pvid = pvid; - } - - static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid, - bool untagged) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot *ocelot = ocelot_port->ocelot; -+ int port = ocelot_port->chip_port; - int ret; - - /* Add the port MAC address to with the right VLAN information */ -@@ -251,35 +283,30 @@ static int ocelot_vlan_vid_add(struct ne - ENTRYTYPE_LOCKED); - - /* Make the port a member of the VLAN */ -- ocelot->vlan_mask[vid] |= BIT(port->chip_port); -+ ocelot->vlan_mask[vid] |= BIT(port); - ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]); - if (ret) - return ret; - - /* Default ingress vlan classification */ - if (pvid) -- port->pvid = vid; -+ ocelot_port_set_pvid(ocelot, port, vid); - - /* Untagged egress vlan clasification */ -- if (untagged && port->vid != vid) { -- if (port->vid) { -- dev_err(ocelot->dev, -- "Port already has a native VLAN: %d\n", -- port->vid); -- return -EBUSY; -- } -- port->vid = vid; -+ if (untagged) { -+ ret = ocelot_port_set_native_vlan(ocelot, port, vid); -+ if (ret) -+ return ret; - } - -- ocelot_vlan_port_apply(ocelot, port); -- - return 0; - } - - static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot *ocelot = ocelot_port->ocelot; -+ int port = ocelot_port->chip_port; - int ret; - - /* 8021q removes VID 0 on module unload for all interfaces -@@ -293,20 +320,18 @@ static int ocelot_vlan_vid_del(struct ne - ocelot_mact_forget(ocelot, dev->dev_addr, vid); - - /* Stop the port from being a member of the vlan */ -- ocelot->vlan_mask[vid] &= ~BIT(port->chip_port); -+ ocelot->vlan_mask[vid] &= ~BIT(port); - ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]); - if (ret) - return ret; - - /* Ingress */ -- if (port->pvid == vid) -- port->pvid = 0; -+ if (ocelot_port->pvid == vid) -+ ocelot_port_set_pvid(ocelot, port, 0); - - /* Egress */ -- if (port->vid == vid) -- port->vid = 0; -- -- ocelot_vlan_port_apply(ocelot, port); -+ if (ocelot_port->vid == vid) -+ ocelot_port_set_native_vlan(ocelot, port, 0); - - return 0; - } -@@ -1303,6 +1328,7 @@ static int ocelot_port_attr_set(struct n - struct switchdev_trans *trans) - { - struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot *ocelot = ocelot_port->ocelot; - int err = 0; - - switch (attr->id) { -@@ -1314,8 +1340,8 @@ static int ocelot_port_attr_set(struct n - ocelot_port_attr_ageing_set(ocelot_port, attr->u.ageing_time); - break; - case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING: -- ocelot_port->vlan_aware = attr->u.vlan_filtering; -- ocelot_vlan_port_apply(ocelot_port->ocelot, ocelot_port); -+ ocelot_port_vlan_filtering(ocelot, ocelot_port->chip_port, -+ attr->u.vlan_filtering); - break; - case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED: - ocelot_port_attr_mc_set(ocelot_port, !attr->u.mc_disabled); -@@ -1517,20 +1543,20 @@ static int ocelot_port_bridge_join(struc - return 0; - } - --static void ocelot_port_bridge_leave(struct ocelot_port *ocelot_port, -- struct net_device *bridge) -+static int ocelot_port_bridge_leave(struct ocelot_port *ocelot_port, -+ struct net_device *bridge) - { - struct ocelot *ocelot = ocelot_port->ocelot; -+ int port = ocelot_port->chip_port; - -- ocelot->bridge_mask &= ~BIT(ocelot_port->chip_port); -+ ocelot->bridge_mask &= ~BIT(port); - - if (!ocelot->bridge_mask) - ocelot->hw_bridge_dev = NULL; - -- /* Clear bridge vlan settings before calling ocelot_vlan_port_apply */ -- ocelot_port->vlan_aware = 0; -- ocelot_port->pvid = 0; -- ocelot_port->vid = 0; -+ ocelot_port_vlan_filtering(ocelot, port, 0); -+ ocelot_port_set_pvid(ocelot, port, 0); -+ return ocelot_port_set_native_vlan(ocelot, port, 0); - } - - static void ocelot_set_aggr_pgids(struct ocelot *ocelot) -@@ -1684,11 +1710,8 @@ static int ocelot_netdevice_port_event(s - err = ocelot_port_bridge_join(ocelot_port, - info->upper_dev); - else -- ocelot_port_bridge_leave(ocelot_port, -- info->upper_dev); -- -- ocelot_vlan_port_apply(ocelot_port->ocelot, -- ocelot_port); -+ err = ocelot_port_bridge_leave(ocelot_port, -+ info->upper_dev); - } - if (netif_is_lag_master(info->upper_dev)) { - if (info->linking) -@@ -2006,6 +2029,7 @@ int ocelot_probe_port(struct ocelot *oce - { - struct ocelot_port *ocelot_port; - struct net_device *dev; -+ u32 val; - int err; - - dev = alloc_etherdev(sizeof(struct ocelot_port)); -@@ -2041,7 +2065,15 @@ int ocelot_probe_port(struct ocelot *oce - } - - /* Basic L2 initialization */ -- ocelot_vlan_port_apply(ocelot, ocelot_port); -+ -+ /* Drop frames with multicast source address */ -+ val = ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA; -+ ocelot_rmw_gix(ocelot, val, val, ANA_PORT_DROP_CFG, port); -+ -+ /* Set default VLAN and tag type to 8021Q. */ -+ ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q), -+ REW_PORT_VLAN_CFG_PORT_TPID_M, -+ REW_PORT_VLAN_CFG, port); - - /* Enable vcap lookups */ - ocelot_vcap_enable(ocelot, ocelot_port); diff --git a/target/linux/layerscape/patches-5.4/701-net-0239-net-mscc-ocelot-break-apart-vlan-operations-into-oce.patch b/target/linux/layerscape/patches-5.4/701-net-0239-net-mscc-ocelot-break-apart-vlan-operations-into-oce.patch deleted file mode 100644 index d2b2cfcc67..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0239-net-mscc-ocelot-break-apart-vlan-operations-into-oce.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 829d9def89b452c4d13d15fd578dea524d9f8521 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:48 +0200 -Subject: [PATCH] net: mscc: ocelot: break apart vlan operations into - ocelot_vlan_{add, del} - -We need an implementation of these functions that is agnostic to the -higher layer (switchdev or dsa). - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 60 ++++++++++++++++++++++++++------------ - 1 file changed, 42 insertions(+), 18 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -270,18 +270,11 @@ static void ocelot_port_set_pvid(struct - ocelot_port->pvid = pvid; - } - --static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid, -- bool untagged) -+static int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, -+ bool untagged) - { -- struct ocelot_port *ocelot_port = netdev_priv(dev); -- struct ocelot *ocelot = ocelot_port->ocelot; -- int port = ocelot_port->chip_port; - int ret; - -- /* Add the port MAC address to with the right VLAN information */ -- ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, vid, -- ENTRYTYPE_LOCKED); -- - /* Make the port a member of the VLAN */ - ocelot->vlan_mask[vid] |= BIT(port); - ret = ocelot_vlant_set_mask(ocelot, vid, ocelot->vlan_mask[vid]); -@@ -302,22 +295,29 @@ static int ocelot_vlan_vid_add(struct ne - return 0; - } - --static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid) -+static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid, -+ bool untagged) - { - struct ocelot_port *ocelot_port = netdev_priv(dev); - struct ocelot *ocelot = ocelot_port->ocelot; - int port = ocelot_port->chip_port; - int ret; - -- /* 8021q removes VID 0 on module unload for all interfaces -- * with VLAN filtering feature. We need to keep it to receive -- * untagged traffic. -- */ -- if (vid == 0) -- return 0; -+ ret = ocelot_vlan_add(ocelot, port, vid, pvid, untagged); -+ if (ret) -+ return ret; - -- /* Del the port MAC address to with the right VLAN information */ -- ocelot_mact_forget(ocelot, dev->dev_addr, vid); -+ /* Add the port MAC address to with the right VLAN information */ -+ ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, vid, -+ ENTRYTYPE_LOCKED); -+ -+ return 0; -+} -+ -+static int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid) -+{ -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ int ret; - - /* Stop the port from being a member of the vlan */ - ocelot->vlan_mask[vid] &= ~BIT(port); -@@ -335,6 +335,30 @@ static int ocelot_vlan_vid_del(struct ne - - return 0; - } -+ -+static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid) -+{ -+ struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot *ocelot = ocelot_port->ocelot; -+ int port = ocelot_port->chip_port; -+ int ret; -+ -+ /* 8021q removes VID 0 on module unload for all interfaces -+ * with VLAN filtering feature. We need to keep it to receive -+ * untagged traffic. -+ */ -+ if (vid == 0) -+ return 0; -+ -+ ret = ocelot_vlan_del(ocelot, port, vid); -+ if (ret) -+ return ret; -+ -+ /* Del the port MAC address to with the right VLAN information */ -+ ocelot_mact_forget(ocelot, dev->dev_addr, vid); -+ -+ return 0; -+} - - static void ocelot_vlan_init(struct ocelot *ocelot) - { diff --git a/target/linux/layerscape/patches-5.4/701-net-0240-net-mscc-ocelot-break-out-fdb-operations-into-abstra.patch b/target/linux/layerscape/patches-5.4/701-net-0240-net-mscc-ocelot-break-out-fdb-operations-into-abstra.patch deleted file mode 100644 index a6f81ba84b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0240-net-mscc-ocelot-break-out-fdb-operations-into-abstra.patch +++ /dev/null @@ -1,251 +0,0 @@ -From 0d1866b8c6f17a55207be651a3b3b93879fbdf1f Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:49 +0200 -Subject: [PATCH] net: mscc: ocelot: break out fdb operations into abstract - implementations - -To be able to implement a DSA front-end over ocelot_fdb_add, -ocelot_fdb_del, ocelot_fdb_dump, these need to have a simple function -prototype that is independent of struct net_device, netlink skb, etc. - -So rename the ndo ops of the ocelot driver into -ocelot_port_fdb_{add,del,dump}, and have them all call the abstract -implementations. At the same time, refactor ocelot_port_fdb_do_dump into -a function whose prototype is compatible with dsa_fdb_dump_cb_t, so that -the do_dump implementations can live together and be called by the -ocelot_fdb_dump through a function pointer. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 124 +++++++++++++++++++++++-------------- - 1 file changed, 78 insertions(+), 46 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include "ocelot.h" - #include "ocelot_ace.h" -@@ -814,21 +815,18 @@ static void ocelot_get_stats64(struct ne - stats->collisions = ocelot_read(ocelot, SYS_COUNT_TX_COLLISION); - } - --static int ocelot_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], -- struct net_device *dev, const unsigned char *addr, -- u16 vid, u16 flags, -- struct netlink_ext_ack *extack) -+static int ocelot_fdb_add(struct ocelot *ocelot, int port, -+ const unsigned char *addr, u16 vid) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; - - if (!vid) { -- if (!port->vlan_aware) -+ if (!ocelot_port->vlan_aware) - /* If the bridge is not VLAN aware and no VID was - * provided, set it to pvid to ensure the MAC entry - * matches incoming untagged packets - */ -- vid = port->pvid; -+ vid = ocelot_port->pvid; - else - /* If the bridge is VLAN aware a VID must be provided as - * otherwise the learnt entry wouldn't match any frame. -@@ -836,20 +834,37 @@ static int ocelot_fdb_add(struct ndmsg * - return -EINVAL; - } - -- return ocelot_mact_learn(ocelot, port->chip_port, addr, vid, -- ENTRYTYPE_LOCKED); -+ return ocelot_mact_learn(ocelot, port, addr, vid, ENTRYTYPE_LOCKED); - } - --static int ocelot_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], -- struct net_device *dev, -- const unsigned char *addr, u16 vid) -+static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], -+ struct net_device *dev, -+ const unsigned char *addr, -+ u16 vid, u16 flags, -+ struct netlink_ext_ack *extack) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot *ocelot = ocelot_port->ocelot; - -+ return ocelot_fdb_add(ocelot, ocelot_port->chip_port, addr, vid); -+} -+ -+static int ocelot_fdb_del(struct ocelot *ocelot, int port, -+ const unsigned char *addr, u16 vid) -+{ - return ocelot_mact_forget(ocelot, addr, vid); - } - -+static int ocelot_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], -+ struct net_device *dev, -+ const unsigned char *addr, u16 vid) -+{ -+ struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot *ocelot = ocelot_port->ocelot; -+ -+ return ocelot_fdb_del(ocelot, ocelot_port->chip_port, addr, vid); -+} -+ - struct ocelot_dump_ctx { - struct net_device *dev; - struct sk_buff *skb; -@@ -857,9 +872,10 @@ struct ocelot_dump_ctx { - int idx; - }; - --static int ocelot_fdb_do_dump(struct ocelot_mact_entry *entry, -- struct ocelot_dump_ctx *dump) -+static int ocelot_port_fdb_do_dump(const unsigned char *addr, u16 vid, -+ bool is_static, void *data) - { -+ struct ocelot_dump_ctx *dump = data; - u32 portid = NETLINK_CB(dump->cb->skb).portid; - u32 seq = dump->cb->nlh->nlmsg_seq; - struct nlmsghdr *nlh; -@@ -880,12 +896,12 @@ static int ocelot_fdb_do_dump(struct oce - ndm->ndm_flags = NTF_SELF; - ndm->ndm_type = 0; - ndm->ndm_ifindex = dump->dev->ifindex; -- ndm->ndm_state = NUD_REACHABLE; -+ ndm->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE; - -- if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, entry->mac)) -+ if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, addr)) - goto nla_put_failure; - -- if (entry->vid && nla_put_u16(dump->skb, NDA_VLAN, entry->vid)) -+ if (vid && nla_put_u16(dump->skb, NDA_VLAN, vid)) - goto nla_put_failure; - - nlmsg_end(dump->skb, nlh); -@@ -899,12 +915,11 @@ nla_put_failure: - return -EMSGSIZE; - } - --static inline int ocelot_mact_read(struct ocelot_port *port, int row, int col, -- struct ocelot_mact_entry *entry) -+static int ocelot_mact_read(struct ocelot *ocelot, int port, int row, int col, -+ struct ocelot_mact_entry *entry) - { -- struct ocelot *ocelot = port->ocelot; -- char mac[ETH_ALEN]; - u32 val, dst, macl, mach; -+ char mac[ETH_ALEN]; - - /* Set row and column to read from */ - ocelot_field_write(ocelot, ANA_TABLES_MACTINDX_M_INDEX, row); -@@ -927,7 +942,7 @@ static inline int ocelot_mact_read(struc - * do not report it. - */ - dst = (val & ANA_TABLES_MACACCESS_DEST_IDX_M) >> 3; -- if (dst != port->chip_port) -+ if (dst != port) - return -EINVAL; - - /* Get the entry's MAC address and VLAN id */ -@@ -947,43 +962,60 @@ static inline int ocelot_mact_read(struc - return 0; - } - --static int ocelot_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, -- struct net_device *dev, -- struct net_device *filter_dev, int *idx) -+static int ocelot_fdb_dump(struct ocelot *ocelot, int port, -+ dsa_fdb_dump_cb_t *cb, void *data) - { -- struct ocelot_port *port = netdev_priv(dev); -- int i, j, ret = 0; -- struct ocelot_dump_ctx dump = { -- .dev = dev, -- .skb = skb, -- .cb = cb, -- .idx = *idx, -- }; -- -- struct ocelot_mact_entry entry; -+ int i, j; - - /* Loop through all the mac tables entries. There are 1024 rows of 4 - * entries. - */ - for (i = 0; i < 1024; i++) { - for (j = 0; j < 4; j++) { -- ret = ocelot_mact_read(port, i, j, &entry); -+ struct ocelot_mact_entry entry; -+ bool is_static; -+ int ret; -+ -+ ret = ocelot_mact_read(ocelot, port, i, j, &entry); - /* If the entry is invalid (wrong port, invalid...), - * skip it. - */ - if (ret == -EINVAL) - continue; - else if (ret) -- goto end; -+ return ret; -+ -+ is_static = (entry.type == ENTRYTYPE_LOCKED); - -- ret = ocelot_fdb_do_dump(&entry, &dump); -+ ret = cb(entry.mac, entry.vid, is_static, data); - if (ret) -- goto end; -+ return ret; - } - } - --end: -+ return 0; -+} -+ -+static int ocelot_port_fdb_dump(struct sk_buff *skb, -+ struct netlink_callback *cb, -+ struct net_device *dev, -+ struct net_device *filter_dev, int *idx) -+{ -+ struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot *ocelot = ocelot_port->ocelot; -+ struct ocelot_dump_ctx dump = { -+ .dev = dev, -+ .skb = skb, -+ .cb = cb, -+ .idx = *idx, -+ }; -+ int ret; -+ -+ ret = ocelot_fdb_dump(ocelot, ocelot_port->chip_port, -+ ocelot_port_fdb_do_dump, &dump); -+ - *idx = dump.idx; -+ - return ret; - } - -@@ -1123,9 +1155,9 @@ static const struct net_device_ops ocelo - .ndo_get_phys_port_name = ocelot_port_get_phys_port_name, - .ndo_set_mac_address = ocelot_port_set_mac_address, - .ndo_get_stats64 = ocelot_get_stats64, -- .ndo_fdb_add = ocelot_fdb_add, -- .ndo_fdb_del = ocelot_fdb_del, -- .ndo_fdb_dump = ocelot_fdb_dump, -+ .ndo_fdb_add = ocelot_port_fdb_add, -+ .ndo_fdb_del = ocelot_port_fdb_del, -+ .ndo_fdb_dump = ocelot_port_fdb_dump, - .ndo_vlan_rx_add_vid = ocelot_vlan_rx_add_vid, - .ndo_vlan_rx_kill_vid = ocelot_vlan_rx_kill_vid, - .ndo_set_features = ocelot_set_features, diff --git a/target/linux/layerscape/patches-5.4/701-net-0241-net-mscc-ocelot-change-prototypes-of-hwtstamping-ioc.patch b/target/linux/layerscape/patches-5.4/701-net-0241-net-mscc-ocelot-change-prototypes-of-hwtstamping-ioc.patch deleted file mode 100644 index 730e6a72ce..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0241-net-mscc-ocelot-change-prototypes-of-hwtstamping-ioc.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 1ba674f7023761476dc39b7b112b780bb86f2f66 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:50 +0200 -Subject: [PATCH] net: mscc: ocelot: change prototypes of hwtstamping ioctls - -This is needed in order to present a simpler prototype to the DSA -front-end of ocelot. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 25 +++++++++++++------------ - 1 file changed, 13 insertions(+), 12 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -1062,17 +1062,17 @@ static int ocelot_get_port_parent_id(str - return 0; - } - --static int ocelot_hwstamp_get(struct ocelot_port *port, struct ifreq *ifr) -+static int ocelot_hwstamp_get(struct ocelot *ocelot, int port, -+ struct ifreq *ifr) - { -- struct ocelot *ocelot = port->ocelot; -- - return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config, - sizeof(ocelot->hwtstamp_config)) ? -EFAULT : 0; - } - --static int ocelot_hwstamp_set(struct ocelot_port *port, struct ifreq *ifr) -+static int ocelot_hwstamp_set(struct ocelot *ocelot, int port, -+ struct ifreq *ifr) - { -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; - struct hwtstamp_config cfg; - - if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) -@@ -1085,16 +1085,16 @@ static int ocelot_hwstamp_set(struct oce - /* Tx type sanity check */ - switch (cfg.tx_type) { - case HWTSTAMP_TX_ON: -- port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP; -+ ocelot_port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP; - break; - case HWTSTAMP_TX_ONESTEP_SYNC: - /* IFH_REW_OP_ONE_STEP_PTP updates the correctional field, we - * need to update the origin time. - */ -- port->ptp_cmd = IFH_REW_OP_ORIGIN_PTP; -+ ocelot_port->ptp_cmd = IFH_REW_OP_ORIGIN_PTP; - break; - case HWTSTAMP_TX_OFF: -- port->ptp_cmd = 0; -+ ocelot_port->ptp_cmd = 0; - break; - default: - return -ERANGE; -@@ -1130,8 +1130,9 @@ static int ocelot_hwstamp_set(struct oce - - static int ocelot_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot *ocelot = ocelot_port->ocelot; -+ int port = ocelot_port->chip_port; - - /* The function is only used for PTP operations for now */ - if (!ocelot->ptp) -@@ -1139,9 +1140,9 @@ static int ocelot_ioctl(struct net_devic - - switch (cmd) { - case SIOCSHWTSTAMP: -- return ocelot_hwstamp_set(port, ifr); -+ return ocelot_hwstamp_set(ocelot, port, ifr); - case SIOCGHWTSTAMP: -- return ocelot_hwstamp_get(port, ifr); -+ return ocelot_hwstamp_get(ocelot, port, ifr); - default: - return -EOPNOTSUPP; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0242-net-mscc-ocelot-change-prototypes-of-switchdev-port-.patch b/target/linux/layerscape/patches-5.4/701-net-0242-net-mscc-ocelot-change-prototypes-of-switchdev-port-.patch deleted file mode 100644 index dc5847c528..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0242-net-mscc-ocelot-change-prototypes-of-switchdev-port-.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 2a07ee2b9608e665872e7d83bebd3acb7e45c2e6 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:51 +0200 -Subject: [PATCH] net: mscc: ocelot: change prototypes of switchdev port - attribute handlers - -This is needed so that the Felix DSA front-end can call the Ocelot -implementations. - -The implementation of the "mc_disabled" switchdev attribute has also -been simplified by using the read-modify-write macro instead of -open-coding that operation. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 88 +++++++++++++++++++------------------- - 1 file changed, 45 insertions(+), 43 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -1282,26 +1282,20 @@ static const struct ethtool_ops ocelot_e - .get_ts_info = ocelot_get_ts_info, - }; - --static int ocelot_port_attr_stp_state_set(struct ocelot_port *ocelot_port, -- struct switchdev_trans *trans, -- u8 state) -+static void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, -+ u8 state) - { -- struct ocelot *ocelot = ocelot_port->ocelot; - u32 port_cfg; -- int port, i; -- -- if (switchdev_trans_ph_prepare(trans)) -- return 0; -+ int p, i; - -- if (!(BIT(ocelot_port->chip_port) & ocelot->bridge_mask)) -- return 0; -+ if (!(BIT(port) & ocelot->bridge_mask)) -+ return; - -- port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, -- ocelot_port->chip_port); -+ port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, port); - - switch (state) { - case BR_STATE_FORWARDING: -- ocelot->bridge_fwd_mask |= BIT(ocelot_port->chip_port); -+ ocelot->bridge_fwd_mask |= BIT(port); - /* Fallthrough */ - case BR_STATE_LEARNING: - port_cfg |= ANA_PORT_PORT_CFG_LEARN_ENA; -@@ -1309,19 +1303,18 @@ static int ocelot_port_attr_stp_state_se - - default: - port_cfg &= ~ANA_PORT_PORT_CFG_LEARN_ENA; -- ocelot->bridge_fwd_mask &= ~BIT(ocelot_port->chip_port); -+ ocelot->bridge_fwd_mask &= ~BIT(port); - break; - } - -- ocelot_write_gix(ocelot, port_cfg, ANA_PORT_PORT_CFG, -- ocelot_port->chip_port); -+ ocelot_write_gix(ocelot, port_cfg, ANA_PORT_PORT_CFG, port); - - /* Apply FWD mask. The loop is needed to add/remove the current port as - * a source for the other ports. - */ -- for (port = 0; port < ocelot->num_phys_ports; port++) { -- if (ocelot->bridge_fwd_mask & BIT(port)) { -- unsigned long mask = ocelot->bridge_fwd_mask & ~BIT(port); -+ for (p = 0; p < ocelot->num_phys_ports; p++) { -+ if (ocelot->bridge_fwd_mask & BIT(p)) { -+ unsigned long mask = ocelot->bridge_fwd_mask & ~BIT(p); - - for (i = 0; i < ocelot->num_phys_ports; i++) { - unsigned long bond_mask = ocelot->lags[i]; -@@ -1329,7 +1322,7 @@ static int ocelot_port_attr_stp_state_se - if (!bond_mask) - continue; - -- if (bond_mask & BIT(port)) { -+ if (bond_mask & BIT(p)) { - mask &= ~bond_mask; - break; - } -@@ -1337,47 +1330,55 @@ static int ocelot_port_attr_stp_state_se - - ocelot_write_rix(ocelot, - BIT(ocelot->num_phys_ports) | mask, -- ANA_PGID_PGID, PGID_SRC + port); -+ ANA_PGID_PGID, PGID_SRC + p); - } else { - /* Only the CPU port, this is compatible with link - * aggregation. - */ - ocelot_write_rix(ocelot, - BIT(ocelot->num_phys_ports), -- ANA_PGID_PGID, PGID_SRC + port); -+ ANA_PGID_PGID, PGID_SRC + p); - } - } -+} -+ -+static void ocelot_port_attr_stp_state_set(struct ocelot *ocelot, int port, -+ struct switchdev_trans *trans, -+ u8 state) -+{ -+ if (switchdev_trans_ph_prepare(trans)) -+ return; - -- return 0; -+ ocelot_bridge_stp_state_set(ocelot, port, state); - } - --static void ocelot_port_attr_ageing_set(struct ocelot_port *ocelot_port, -+static void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs) -+{ -+ ocelot_write(ocelot, ANA_AUTOAGE_AGE_PERIOD(msecs / 2), -+ ANA_AUTOAGE); -+} -+ -+static void ocelot_port_attr_ageing_set(struct ocelot *ocelot, int port, - unsigned long ageing_clock_t) - { -- struct ocelot *ocelot = ocelot_port->ocelot; - unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t); - u32 ageing_time = jiffies_to_msecs(ageing_jiffies) / 1000; - -- ocelot_write(ocelot, ANA_AUTOAGE_AGE_PERIOD(ageing_time / 2), -- ANA_AUTOAGE); -+ ocelot_set_ageing_time(ocelot, ageing_time); - } - --static void ocelot_port_attr_mc_set(struct ocelot_port *port, bool mc) -+static void ocelot_port_attr_mc_set(struct ocelot *ocelot, int port, bool mc) - { -- struct ocelot *ocelot = port->ocelot; -- u32 val = ocelot_read_gix(ocelot, ANA_PORT_CPU_FWD_CFG, -- port->chip_port); -+ u32 cpu_fwd_mcast = ANA_PORT_CPU_FWD_CFG_CPU_IGMP_REDIR_ENA | -+ ANA_PORT_CPU_FWD_CFG_CPU_MLD_REDIR_ENA | -+ ANA_PORT_CPU_FWD_CFG_CPU_IPMC_CTRL_COPY_ENA; -+ u32 val = 0; - - if (mc) -- val |= ANA_PORT_CPU_FWD_CFG_CPU_IGMP_REDIR_ENA | -- ANA_PORT_CPU_FWD_CFG_CPU_MLD_REDIR_ENA | -- ANA_PORT_CPU_FWD_CFG_CPU_IPMC_CTRL_COPY_ENA; -- else -- val &= ~(ANA_PORT_CPU_FWD_CFG_CPU_IGMP_REDIR_ENA | -- ANA_PORT_CPU_FWD_CFG_CPU_MLD_REDIR_ENA | -- ANA_PORT_CPU_FWD_CFG_CPU_IPMC_CTRL_COPY_ENA); -+ val = cpu_fwd_mcast; - -- ocelot_write_gix(ocelot, val, ANA_PORT_CPU_FWD_CFG, port->chip_port); -+ ocelot_rmw_gix(ocelot, val, cpu_fwd_mcast, -+ ANA_PORT_CPU_FWD_CFG, port); - } - - static int ocelot_port_attr_set(struct net_device *dev, -@@ -1386,22 +1387,23 @@ static int ocelot_port_attr_set(struct n - { - struct ocelot_port *ocelot_port = netdev_priv(dev); - struct ocelot *ocelot = ocelot_port->ocelot; -+ int port = ocelot_port->chip_port; - int err = 0; - - switch (attr->id) { - case SWITCHDEV_ATTR_ID_PORT_STP_STATE: -- ocelot_port_attr_stp_state_set(ocelot_port, trans, -+ ocelot_port_attr_stp_state_set(ocelot, port, trans, - attr->u.stp_state); - break; - case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME: -- ocelot_port_attr_ageing_set(ocelot_port, attr->u.ageing_time); -+ ocelot_port_attr_ageing_set(ocelot, port, attr->u.ageing_time); - break; - case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING: -- ocelot_port_vlan_filtering(ocelot, ocelot_port->chip_port, -+ ocelot_port_vlan_filtering(ocelot, port, - attr->u.vlan_filtering); - break; - case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED: -- ocelot_port_attr_mc_set(ocelot_port, !attr->u.mc_disabled); -+ ocelot_port_attr_mc_set(ocelot, port, !attr->u.mc_disabled); - break; - default: - err = -EOPNOTSUPP; diff --git a/target/linux/layerscape/patches-5.4/701-net-0243-net-mscc-ocelot-refactor-struct-ocelot_port-out-of-f.patch b/target/linux/layerscape/patches-5.4/701-net-0243-net-mscc-ocelot-refactor-struct-ocelot_port-out-of-f.patch deleted file mode 100644 index 8850f57103..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0243-net-mscc-ocelot-refactor-struct-ocelot_port-out-of-f.patch +++ /dev/null @@ -1,388 +0,0 @@ -From 9f374df14572a9b4fb0940d8d6721c930bc27da1 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:52 +0200 -Subject: [PATCH] net: mscc: ocelot: refactor struct ocelot_port out of - function prototypes - -The ocelot_port structure has a net_device embedded in it, which makes -it unsuitable for leaving it in the driver implementation functions. - -Leave ocelot_flower.c untouched. In that file, ocelot_port is used as an -interface to the tc shared blocks. That will be addressed in the next -patch. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 79 ++++++++++++++----------------- - drivers/net/ethernet/mscc/ocelot_police.c | 36 +++++++------- - drivers/net/ethernet/mscc/ocelot_police.h | 4 +- - drivers/net/ethernet/mscc/ocelot_tc.c | 5 +- - 4 files changed, 59 insertions(+), 65 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -133,11 +133,11 @@ static void ocelot_mact_init(struct ocel - ocelot_write(ocelot, MACACCESS_CMD_INIT, ANA_TABLES_MACACCESS); - } - --static void ocelot_vcap_enable(struct ocelot *ocelot, struct ocelot_port *port) -+static void ocelot_vcap_enable(struct ocelot *ocelot, int port) - { - ocelot_write_gix(ocelot, ANA_PORT_VCAP_S2_CFG_S2_ENA | - ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG(0xa), -- ANA_PORT_VCAP_S2_CFG, port->chip_port); -+ ANA_PORT_VCAP_S2_CFG, port); - } - - static inline u32 ocelot_vlant_read_vlanaccess(struct ocelot *ocelot) -@@ -170,19 +170,17 @@ static int ocelot_vlant_set_mask(struct - return ocelot_vlant_wait_for_completion(ocelot); - } - --static void ocelot_vlan_mode(struct ocelot_port *port, -+static void ocelot_vlan_mode(struct ocelot *ocelot, int port, - netdev_features_t features) - { -- struct ocelot *ocelot = port->ocelot; -- u8 p = port->chip_port; - u32 val; - - /* Filtering */ - val = ocelot_read(ocelot, ANA_VLANMASK); - if (features & NETIF_F_HW_VLAN_CTAG_FILTER) -- val |= BIT(p); -+ val |= BIT(port); - else -- val &= ~BIT(p); -+ val &= ~BIT(port); - ocelot_write(ocelot, val, ANA_VLANMASK); - } - -@@ -1034,18 +1032,20 @@ static int ocelot_vlan_rx_kill_vid(struc - static int ocelot_set_features(struct net_device *dev, - netdev_features_t features) - { -- struct ocelot_port *port = netdev_priv(dev); - netdev_features_t changed = dev->features ^ features; -+ struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot *ocelot = ocelot_port->ocelot; -+ int port = ocelot_port->chip_port; - - if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) && -- port->tc.offload_cnt) { -+ ocelot_port->tc.offload_cnt) { - netdev_err(dev, - "Cannot disable HW TC offload while offloads active\n"); - return -EBUSY; - } - - if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) -- ocelot_vlan_mode(port, features); -+ ocelot_vlan_mode(ocelot, port, features); - - return 0; - } -@@ -1583,11 +1583,9 @@ static int ocelot_port_obj_del(struct ne - return ret; - } - --static int ocelot_port_bridge_join(struct ocelot_port *ocelot_port, -+static int ocelot_port_bridge_join(struct ocelot *ocelot, int port, - struct net_device *bridge) - { -- struct ocelot *ocelot = ocelot_port->ocelot; -- - if (!ocelot->bridge_mask) { - ocelot->hw_bridge_dev = bridge; - } else { -@@ -1597,17 +1595,14 @@ static int ocelot_port_bridge_join(struc - return -ENODEV; - } - -- ocelot->bridge_mask |= BIT(ocelot_port->chip_port); -+ ocelot->bridge_mask |= BIT(port); - - return 0; - } - --static int ocelot_port_bridge_leave(struct ocelot_port *ocelot_port, -+static int ocelot_port_bridge_leave(struct ocelot *ocelot, int port, - struct net_device *bridge) - { -- struct ocelot *ocelot = ocelot_port->ocelot; -- int port = ocelot_port->chip_port; -- - ocelot->bridge_mask &= ~BIT(port); - - if (!ocelot->bridge_mask) -@@ -1676,14 +1671,12 @@ static void ocelot_setup_lag(struct ocel - } - } - --static int ocelot_port_lag_join(struct ocelot_port *ocelot_port, -+static int ocelot_port_lag_join(struct ocelot *ocelot, int port, - struct net_device *bond) - { -- struct ocelot *ocelot = ocelot_port->ocelot; -- int p = ocelot_port->chip_port; -- int lag, lp; - struct net_device *ndev; - u32 bond_mask = 0; -+ int lag, lp; - - rcu_read_lock(); - for_each_netdev_in_bond_rcu(bond, ndev) { -@@ -1698,17 +1691,17 @@ static int ocelot_port_lag_join(struct o - /* If the new port is the lowest one, use it as the logical port from - * now on - */ -- if (p == lp) { -- lag = p; -- ocelot->lags[p] = bond_mask; -- bond_mask &= ~BIT(p); -+ if (port == lp) { -+ lag = port; -+ ocelot->lags[port] = bond_mask; -+ bond_mask &= ~BIT(port); - if (bond_mask) { - lp = __ffs(bond_mask); - ocelot->lags[lp] = 0; - } - } else { - lag = lp; -- ocelot->lags[lp] |= BIT(p); -+ ocelot->lags[lp] |= BIT(port); - } - - ocelot_setup_lag(ocelot, lag); -@@ -1717,34 +1710,32 @@ static int ocelot_port_lag_join(struct o - return 0; - } - --static void ocelot_port_lag_leave(struct ocelot_port *ocelot_port, -+static void ocelot_port_lag_leave(struct ocelot *ocelot, int port, - struct net_device *bond) - { -- struct ocelot *ocelot = ocelot_port->ocelot; -- int p = ocelot_port->chip_port; - u32 port_cfg; - int i; - - /* Remove port from any lag */ - for (i = 0; i < ocelot->num_phys_ports; i++) -- ocelot->lags[i] &= ~BIT(ocelot_port->chip_port); -+ ocelot->lags[i] &= ~BIT(port); - - /* if it was the logical port of the lag, move the lag config to the - * next port - */ -- if (ocelot->lags[p]) { -- int n = __ffs(ocelot->lags[p]); -+ if (ocelot->lags[port]) { -+ int n = __ffs(ocelot->lags[port]); - -- ocelot->lags[n] = ocelot->lags[p]; -- ocelot->lags[p] = 0; -+ ocelot->lags[n] = ocelot->lags[port]; -+ ocelot->lags[port] = 0; - - ocelot_setup_lag(ocelot, n); - } - -- port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, p); -+ port_cfg = ocelot_read_gix(ocelot, ANA_PORT_PORT_CFG, port); - port_cfg &= ~ANA_PORT_PORT_CFG_PORTID_VAL_M; -- ocelot_write_gix(ocelot, port_cfg | ANA_PORT_PORT_CFG_PORTID_VAL(p), -- ANA_PORT_PORT_CFG, p); -+ ocelot_write_gix(ocelot, port_cfg | ANA_PORT_PORT_CFG_PORTID_VAL(port), -+ ANA_PORT_PORT_CFG, port); - - ocelot_set_aggr_pgids(ocelot); - } -@@ -1760,24 +1751,26 @@ static int ocelot_netdevice_port_event(s - struct netdev_notifier_changeupper_info *info) - { - struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot *ocelot = ocelot_port->ocelot; -+ int port = ocelot_port->chip_port; - int err = 0; - - switch (event) { - case NETDEV_CHANGEUPPER: - if (netif_is_bridge_master(info->upper_dev)) { - if (info->linking) -- err = ocelot_port_bridge_join(ocelot_port, -+ err = ocelot_port_bridge_join(ocelot, port, - info->upper_dev); - else -- err = ocelot_port_bridge_leave(ocelot_port, -+ err = ocelot_port_bridge_leave(ocelot, port, - info->upper_dev); - } - if (netif_is_lag_master(info->upper_dev)) { - if (info->linking) -- err = ocelot_port_lag_join(ocelot_port, -+ err = ocelot_port_lag_join(ocelot, port, - info->upper_dev); - else -- ocelot_port_lag_leave(ocelot_port, -+ ocelot_port_lag_leave(ocelot, port, - info->upper_dev); - } - break; -@@ -2135,7 +2128,7 @@ int ocelot_probe_port(struct ocelot *oce - REW_PORT_VLAN_CFG, port); - - /* Enable vcap lookups */ -- ocelot_vcap_enable(ocelot, ocelot_port); -+ ocelot_vcap_enable(ocelot, port); - - return 0; - ---- a/drivers/net/ethernet/mscc/ocelot_police.c -+++ b/drivers/net/ethernet/mscc/ocelot_police.c -@@ -40,13 +40,12 @@ struct qos_policer_conf { - u8 ipg; /* Size of IPG when MSCC_QOS_RATE_MODE_LINE is chosen */ - }; - --static int qos_policer_conf_set(struct ocelot_port *port, u32 pol_ix, -+static int qos_policer_conf_set(struct ocelot *ocelot, int port, u32 pol_ix, - struct qos_policer_conf *conf) - { - u32 cf = 0, cir_ena = 0, frm_mode = POL_MODE_LINERATE; - u32 cir = 0, cbs = 0, pir = 0, pbs = 0; - bool cir_discard = 0, pir_discard = 0; -- struct ocelot *ocelot = port->ocelot; - u32 pbs_max = 0, cbs_max = 0; - u8 ipg = 20; - u32 value; -@@ -123,22 +122,26 @@ static int qos_policer_conf_set(struct o - - /* Check limits */ - if (pir > GENMASK(15, 0)) { -- netdev_err(port->dev, "Invalid pir\n"); -+ dev_err(ocelot->dev, "Invalid pir for port %d: %u (max %lu)\n", -+ port, pir, GENMASK(15, 0)); - return -EINVAL; - } - - if (cir > GENMASK(15, 0)) { -- netdev_err(port->dev, "Invalid cir\n"); -+ dev_err(ocelot->dev, "Invalid cir for port %d: %u (max %lu)\n", -+ port, cir, GENMASK(15, 0)); - return -EINVAL; - } - - if (pbs > pbs_max) { -- netdev_err(port->dev, "Invalid pbs\n"); -+ dev_err(ocelot->dev, "Invalid pbs for port %d: %u (max %u)\n", -+ port, pbs, pbs_max); - return -EINVAL; - } - - if (cbs > cbs_max) { -- netdev_err(port->dev, "Invalid cbs\n"); -+ dev_err(ocelot->dev, "Invalid cbs for port %d: %u (max %u)\n", -+ port, cbs, cbs_max); - return -EINVAL; - } - -@@ -171,10 +174,9 @@ static int qos_policer_conf_set(struct o - return 0; - } - --int ocelot_port_policer_add(struct ocelot_port *port, -+int ocelot_port_policer_add(struct ocelot *ocelot, int port, - struct ocelot_policer *pol) - { -- struct ocelot *ocelot = port->ocelot; - struct qos_policer_conf pp = { 0 }; - int err; - -@@ -185,11 +187,10 @@ int ocelot_port_policer_add(struct ocelo - pp.pir = pol->rate; - pp.pbs = pol->burst; - -- netdev_dbg(port->dev, -- "%s: port %u pir %u kbps, pbs %u bytes\n", -- __func__, port->chip_port, pp.pir, pp.pbs); -+ dev_dbg(ocelot->dev, "%s: port %u pir %u kbps, pbs %u bytes\n", -+ __func__, port, pp.pir, pp.pbs); - -- err = qos_policer_conf_set(port, POL_IX_PORT + port->chip_port, &pp); -+ err = qos_policer_conf_set(ocelot, port, POL_IX_PORT + port, &pp); - if (err) - return err; - -@@ -198,22 +199,21 @@ int ocelot_port_policer_add(struct ocelo - ANA_PORT_POL_CFG_POL_ORDER(POL_ORDER), - ANA_PORT_POL_CFG_PORT_POL_ENA | - ANA_PORT_POL_CFG_POL_ORDER_M, -- ANA_PORT_POL_CFG, port->chip_port); -+ ANA_PORT_POL_CFG, port); - - return 0; - } - --int ocelot_port_policer_del(struct ocelot_port *port) -+int ocelot_port_policer_del(struct ocelot *ocelot, int port) - { -- struct ocelot *ocelot = port->ocelot; - struct qos_policer_conf pp = { 0 }; - int err; - -- netdev_dbg(port->dev, "%s: port %u\n", __func__, port->chip_port); -+ dev_dbg(ocelot->dev, "%s: port %u\n", __func__, port); - - pp.mode = MSCC_QOS_RATE_MODE_DISABLED; - -- err = qos_policer_conf_set(port, POL_IX_PORT + port->chip_port, &pp); -+ err = qos_policer_conf_set(ocelot, port, POL_IX_PORT + port, &pp); - if (err) - return err; - -@@ -221,7 +221,7 @@ int ocelot_port_policer_del(struct ocelo - ANA_PORT_POL_CFG_POL_ORDER(POL_ORDER), - ANA_PORT_POL_CFG_PORT_POL_ENA | - ANA_PORT_POL_CFG_POL_ORDER_M, -- ANA_PORT_POL_CFG, port->chip_port); -+ ANA_PORT_POL_CFG, port); - - return 0; - } ---- a/drivers/net/ethernet/mscc/ocelot_police.h -+++ b/drivers/net/ethernet/mscc/ocelot_police.h -@@ -14,9 +14,9 @@ struct ocelot_policer { - u32 burst; /* bytes */ - }; - --int ocelot_port_policer_add(struct ocelot_port *port, -+int ocelot_port_policer_add(struct ocelot *ocelot, int port, - struct ocelot_policer *pol); - --int ocelot_port_policer_del(struct ocelot_port *port); -+int ocelot_port_policer_del(struct ocelot *ocelot, int port); - - #endif /* _MSCC_OCELOT_POLICE_H_ */ ---- a/drivers/net/ethernet/mscc/ocelot_tc.c -+++ b/drivers/net/ethernet/mscc/ocelot_tc.c -@@ -58,7 +58,8 @@ static int ocelot_setup_tc_cls_matchall( - PSCHED_NS2TICKS(action->police.burst), - PSCHED_TICKS_PER_SEC); - -- err = ocelot_port_policer_add(port, &pol); -+ err = ocelot_port_policer_add(port->ocelot, port->chip_port, -+ &pol); - if (err) { - NL_SET_ERR_MSG_MOD(extack, "Could not add policer\n"); - return err; -@@ -71,7 +72,7 @@ static int ocelot_setup_tc_cls_matchall( - if (port->tc.police_id != f->cookie) - return -ENOENT; - -- err = ocelot_port_policer_del(port); -+ err = ocelot_port_policer_del(port->ocelot, port->chip_port); - if (err) { - NL_SET_ERR_MSG_MOD(extack, - "Could not delete policer\n"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0244-net-mscc-ocelot-separate-net_device-related-items-ou.patch b/target/linux/layerscape/patches-5.4/701-net-0244-net-mscc-ocelot-separate-net_device-related-items-ou.patch deleted file mode 100644 index 774e8d0bfe..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0244-net-mscc-ocelot-separate-net_device-related-items-ou.patch +++ /dev/null @@ -1,1171 +0,0 @@ -From b0481fbc0d853fd164055293002c621827eba5ad Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:53 +0200 -Subject: [PATCH] net: mscc: ocelot: separate net_device related items out of - ocelot_port - -The ocelot and ocelot_port structures will be used by a new DSA driver, -so the ocelot_board.c file will have to allocate and work with a private -structure (ocelot_port_private), which embeds the generic struct -ocelot_port. This is because in DSA, at least one interface does not -have a net_device, and the DSA driver API does not interact with that -anyway. - -The ocelot_port structure is equivalent to dsa_port, and ocelot to -dsa_switch. The members of ocelot_port which have an equivalent in -dsa_port (such as dp->vlan_filtering) have been moved to -ocelot_port_private. - -We want to enforce the coding convention that "ocelot_port" refers to -the structure, and "port" refers to the integer index. One can retrieve -the structure at any time from ocelot->ports[port]. - -The patch is large but only contains variable renaming and mechanical -movement of fields from one structure to another. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 288 ++++++++++++++++-------------- - drivers/net/ethernet/mscc/ocelot.h | 21 ++- - drivers/net/ethernet/mscc/ocelot_ace.h | 4 +- - drivers/net/ethernet/mscc/ocelot_board.c | 25 ++- - drivers/net/ethernet/mscc/ocelot_flower.c | 32 ++-- - drivers/net/ethernet/mscc/ocelot_tc.c | 57 +++--- - 6 files changed, 235 insertions(+), 192 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -229,8 +229,6 @@ static void ocelot_port_vlan_filtering(s - ocelot_rmw_gix(ocelot, val, - REW_TAG_CFG_TAG_CFG_M, - REW_TAG_CFG, port); -- -- ocelot_port->vlan_aware = vlan_aware; - } - - static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port, -@@ -297,9 +295,10 @@ static int ocelot_vlan_add(struct ocelot - static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid, - bool untagged) - { -- struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot_port *ocelot_port = &priv->port; - struct ocelot *ocelot = ocelot_port->ocelot; -- int port = ocelot_port->chip_port; -+ int port = priv->chip_port; - int ret; - - ret = ocelot_vlan_add(ocelot, port, vid, pvid, untagged); -@@ -337,9 +336,9 @@ static int ocelot_vlan_del(struct ocelot - - static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid) - { -- struct ocelot_port *ocelot_port = netdev_priv(dev); -- struct ocelot *ocelot = ocelot_port->ocelot; -- int port = ocelot_port->chip_port; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - int ret; - - /* 8021q removes VID 0 on module unload for all interfaces -@@ -412,10 +411,11 @@ static u16 ocelot_wm_enc(u16 value) - - static void ocelot_port_adjust_link(struct net_device *dev) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -- u8 p = port->chip_port; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot_port *ocelot_port = &priv->port; -+ struct ocelot *ocelot = ocelot_port->ocelot; - int speed, atop_wm, mode = 0; -+ u8 port = priv->chip_port; - - switch (dev->phydev->speed) { - case SPEED_10: -@@ -444,62 +444,66 @@ static void ocelot_port_adjust_link(stru - return; - - /* Only full duplex supported for now */ -- ocelot_port_writel(port, DEV_MAC_MODE_CFG_FDX_ENA | -+ ocelot_port_writel(ocelot_port, DEV_MAC_MODE_CFG_FDX_ENA | - mode, DEV_MAC_MODE_CFG); - - /* Set MAC IFG Gaps - * FDX: TX_IFG = 5, RX_IFG1 = RX_IFG2 = 0 - * !FDX: TX_IFG = 5, RX_IFG1 = RX_IFG2 = 5 - */ -- ocelot_port_writel(port, DEV_MAC_IFG_CFG_TX_IFG(5), DEV_MAC_IFG_CFG); -+ ocelot_port_writel(ocelot_port, DEV_MAC_IFG_CFG_TX_IFG(5), -+ DEV_MAC_IFG_CFG); - - /* Load seed (0) and set MAC HDX late collision */ -- ocelot_port_writel(port, DEV_MAC_HDX_CFG_LATE_COL_POS(67) | -+ ocelot_port_writel(ocelot_port, DEV_MAC_HDX_CFG_LATE_COL_POS(67) | - DEV_MAC_HDX_CFG_SEED_LOAD, - DEV_MAC_HDX_CFG); - mdelay(1); -- ocelot_port_writel(port, DEV_MAC_HDX_CFG_LATE_COL_POS(67), -+ ocelot_port_writel(ocelot_port, DEV_MAC_HDX_CFG_LATE_COL_POS(67), - DEV_MAC_HDX_CFG); - - /* Disable HDX fast control */ -- ocelot_port_writel(port, DEV_PORT_MISC_HDX_FAST_DIS, DEV_PORT_MISC); -+ ocelot_port_writel(ocelot_port, DEV_PORT_MISC_HDX_FAST_DIS, -+ DEV_PORT_MISC); - - /* SGMII only for now */ -- ocelot_port_writel(port, PCS1G_MODE_CFG_SGMII_MODE_ENA, PCS1G_MODE_CFG); -- ocelot_port_writel(port, PCS1G_SD_CFG_SD_SEL, PCS1G_SD_CFG); -+ ocelot_port_writel(ocelot_port, PCS1G_MODE_CFG_SGMII_MODE_ENA, -+ PCS1G_MODE_CFG); -+ ocelot_port_writel(ocelot_port, PCS1G_SD_CFG_SD_SEL, PCS1G_SD_CFG); - - /* Enable PCS */ -- ocelot_port_writel(port, PCS1G_CFG_PCS_ENA, PCS1G_CFG); -+ ocelot_port_writel(ocelot_port, PCS1G_CFG_PCS_ENA, PCS1G_CFG); - - /* No aneg on SGMII */ -- ocelot_port_writel(port, 0, PCS1G_ANEG_CFG); -+ ocelot_port_writel(ocelot_port, 0, PCS1G_ANEG_CFG); - - /* No loopback */ -- ocelot_port_writel(port, 0, PCS1G_LB_CFG); -+ ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG); - - /* Set Max Length and maximum tags allowed */ -- ocelot_port_writel(port, VLAN_ETH_FRAME_LEN, DEV_MAC_MAXLEN_CFG); -- ocelot_port_writel(port, DEV_MAC_TAGS_CFG_TAG_ID(ETH_P_8021AD) | -+ ocelot_port_writel(ocelot_port, VLAN_ETH_FRAME_LEN, -+ DEV_MAC_MAXLEN_CFG); -+ ocelot_port_writel(ocelot_port, DEV_MAC_TAGS_CFG_TAG_ID(ETH_P_8021AD) | - DEV_MAC_TAGS_CFG_VLAN_AWR_ENA | - DEV_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, - DEV_MAC_TAGS_CFG); - - /* Enable MAC module */ -- ocelot_port_writel(port, DEV_MAC_ENA_CFG_RX_ENA | -+ ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA | - DEV_MAC_ENA_CFG_TX_ENA, DEV_MAC_ENA_CFG); - - /* Take MAC, Port, Phy (intern) and PCS (SGMII/Serdes) clock out of - * reset */ -- ocelot_port_writel(port, DEV_CLOCK_CFG_LINK_SPEED(speed), -+ ocelot_port_writel(ocelot_port, DEV_CLOCK_CFG_LINK_SPEED(speed), - DEV_CLOCK_CFG); - - /* Set SMAC of Pause frame (00:00:00:00:00:00) */ -- ocelot_port_writel(port, 0, DEV_MAC_FC_MAC_HIGH_CFG); -- ocelot_port_writel(port, 0, DEV_MAC_FC_MAC_LOW_CFG); -+ ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_HIGH_CFG); -+ ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_LOW_CFG); - - /* No PFC */ - ocelot_write_gix(ocelot, ANA_PFC_PFC_CFG_FC_LINK_SPEED(speed), -- ANA_PFC_PFC_CFG, p); -+ ANA_PFC_PFC_CFG, port); - - /* Set Pause WM hysteresis - * 152 = 6 * VLAN_ETH_FRAME_LEN / OCELOT_BUFFER_CELL_SZ -@@ -507,13 +511,13 @@ static void ocelot_port_adjust_link(stru - */ - ocelot_write_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA | - SYS_PAUSE_CFG_PAUSE_STOP(101) | -- SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, p); -+ SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, port); - - /* Core: Enable port for frame transfer */ - ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE | - QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) | - QSYS_SWITCH_PORT_MODE_PORT_ENA, -- QSYS_SWITCH_PORT_MODE, p); -+ QSYS_SWITCH_PORT_MODE, port); - - /* Flow control */ - ocelot_write_rix(ocelot, SYS_MAC_FC_CFG_PAUSE_VAL_CFG(0xffff) | -@@ -521,20 +525,21 @@ static void ocelot_port_adjust_link(stru - SYS_MAC_FC_CFG_ZERO_PAUSE_ENA | - SYS_MAC_FC_CFG_FC_LATENCY_CFG(0x7) | - SYS_MAC_FC_CFG_FC_LINK_SPEED(speed), -- SYS_MAC_FC_CFG, p); -- ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, p); -+ SYS_MAC_FC_CFG, port); -+ ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port); - - /* Tail dropping watermark */ - atop_wm = (ocelot->shared_queue_sz - 9 * VLAN_ETH_FRAME_LEN) / OCELOT_BUFFER_CELL_SZ; - ocelot_write_rix(ocelot, ocelot_wm_enc(9 * VLAN_ETH_FRAME_LEN), -- SYS_ATOP, p); -+ SYS_ATOP, port); - ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG); - } - - static int ocelot_port_open(struct net_device *dev) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - int err; - - /* Enable receiving frames on the port, and activate auto-learning of -@@ -542,43 +547,44 @@ static int ocelot_port_open(struct net_d - */ - ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_LEARNAUTO | - ANA_PORT_PORT_CFG_RECV_ENA | -- ANA_PORT_PORT_CFG_PORTID_VAL(port->chip_port), -- ANA_PORT_PORT_CFG, port->chip_port); -+ ANA_PORT_PORT_CFG_PORTID_VAL(port), -+ ANA_PORT_PORT_CFG, port); - -- if (port->serdes) { -- err = phy_set_mode_ext(port->serdes, PHY_MODE_ETHERNET, -- port->phy_mode); -+ if (priv->serdes) { -+ err = phy_set_mode_ext(priv->serdes, PHY_MODE_ETHERNET, -+ priv->phy_mode); - if (err) { - netdev_err(dev, "Could not set mode of SerDes\n"); - return err; - } - } - -- err = phy_connect_direct(dev, port->phy, &ocelot_port_adjust_link, -- port->phy_mode); -+ err = phy_connect_direct(dev, priv->phy, &ocelot_port_adjust_link, -+ priv->phy_mode); - if (err) { - netdev_err(dev, "Could not attach to PHY\n"); - return err; - } - -- dev->phydev = port->phy; -+ dev->phydev = priv->phy; - -- phy_attached_info(port->phy); -- phy_start(port->phy); -+ phy_attached_info(priv->phy); -+ phy_start(priv->phy); - return 0; - } - - static int ocelot_port_stop(struct net_device *dev) - { -- struct ocelot_port *port = netdev_priv(dev); -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot_port *port = &priv->port; - -- phy_disconnect(port->phy); -+ phy_disconnect(priv->phy); - - dev->phydev = NULL; - - ocelot_port_writel(port, 0, DEV_MAC_ENA_CFG); - ocelot_rmw_rix(port->ocelot, 0, QSYS_SWITCH_PORT_MODE_PORT_ENA, -- QSYS_SWITCH_PORT_MODE, port->chip_port); -+ QSYS_SWITCH_PORT_MODE, priv->chip_port); - return 0; - } - -@@ -604,13 +610,15 @@ static int ocelot_gen_ifh(u32 *ifh, stru - - static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) - { -+ struct ocelot_port_private *priv = netdev_priv(dev); - struct skb_shared_info *shinfo = skb_shinfo(skb); -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -- u32 val, ifh[IFH_LEN]; -+ struct ocelot_port *ocelot_port = &priv->port; -+ struct ocelot *ocelot = ocelot_port->ocelot; - struct frame_info info = {}; - u8 grp = 0; /* Send everything on CPU group 0 */ - unsigned int i, count, last; -+ int port = priv->chip_port; -+ u32 val, ifh[IFH_LEN]; - - val = ocelot_read(ocelot, QS_INJ_STATUS); - if (!(val & QS_INJ_STATUS_FIFO_RDY(BIT(grp))) || -@@ -620,15 +628,15 @@ static int ocelot_port_xmit(struct sk_bu - ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) | - QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp); - -- info.port = BIT(port->chip_port); -+ info.port = BIT(port); - info.tag_type = IFH_TAG_TYPE_C; - info.vid = skb_vlan_tag_get(skb); - - /* Check if timestamping is needed */ - if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP) { -- info.rew_op = port->ptp_cmd; -- if (port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) -- info.rew_op |= (port->ts_id % 4) << 3; -+ info.rew_op = ocelot_port->ptp_cmd; -+ if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) -+ info.rew_op |= (ocelot_port->ts_id % 4) << 3; - } - - ocelot_gen_ifh(ifh, &info); -@@ -663,7 +671,7 @@ static int ocelot_port_xmit(struct sk_bu - dev->stats.tx_bytes += skb->len; - - if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP && -- port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) { -+ ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) { - struct ocelot_skb *oskb = - kzalloc(sizeof(struct ocelot_skb), GFP_ATOMIC); - -@@ -673,10 +681,10 @@ static int ocelot_port_xmit(struct sk_bu - skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; - - oskb->skb = skb; -- oskb->id = port->ts_id % 4; -- port->ts_id++; -+ oskb->id = ocelot_port->ts_id % 4; -+ ocelot_port->ts_id++; - -- list_add_tail(&oskb->head, &port->skbs); -+ list_add_tail(&oskb->head, &ocelot_port->skbs); - - return NETDEV_TX_OK; - } -@@ -715,25 +723,29 @@ EXPORT_SYMBOL(ocelot_get_hwtimestamp); - - static int ocelot_mc_unsync(struct net_device *dev, const unsigned char *addr) - { -- struct ocelot_port *port = netdev_priv(dev); -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot_port *ocelot_port = &priv->port; -+ struct ocelot *ocelot = ocelot_port->ocelot; - -- return ocelot_mact_forget(port->ocelot, addr, port->pvid); -+ return ocelot_mact_forget(ocelot, addr, ocelot_port->pvid); - } - - static int ocelot_mc_sync(struct net_device *dev, const unsigned char *addr) - { -- struct ocelot_port *port = netdev_priv(dev); -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot_port *ocelot_port = &priv->port; -+ struct ocelot *ocelot = ocelot_port->ocelot; - -- return ocelot_mact_learn(port->ocelot, PGID_CPU, addr, port->pvid, -+ return ocelot_mact_learn(ocelot, PGID_CPU, addr, ocelot_port->pvid, - ENTRYTYPE_LOCKED); - } - - static void ocelot_set_rx_mode(struct net_device *dev) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -- int i; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; - u32 val; -+ int i; - - /* This doesn't handle promiscuous mode because the bridge core is - * setting IFF_PROMISC on all slave interfaces and all frames would be -@@ -749,10 +761,11 @@ static void ocelot_set_rx_mode(struct ne - static int ocelot_port_get_phys_port_name(struct net_device *dev, - char *buf, size_t len) - { -- struct ocelot_port *port = netdev_priv(dev); -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ int port = priv->chip_port; - int ret; - -- ret = snprintf(buf, len, "p%d", port->chip_port); -+ ret = snprintf(buf, len, "p%d", port); - if (ret >= len) - return -EINVAL; - -@@ -761,15 +774,16 @@ static int ocelot_port_get_phys_port_nam - - static int ocelot_port_set_mac_address(struct net_device *dev, void *p) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot_port *ocelot_port = &priv->port; -+ struct ocelot *ocelot = ocelot_port->ocelot; - const struct sockaddr *addr = p; - - /* Learn the new net device MAC address in the mac table. */ -- ocelot_mact_learn(ocelot, PGID_CPU, addr->sa_data, port->pvid, -+ ocelot_mact_learn(ocelot, PGID_CPU, addr->sa_data, ocelot_port->pvid, - ENTRYTYPE_LOCKED); - /* Then forget the previous one. */ -- ocelot_mact_forget(ocelot, dev->dev_addr, port->pvid); -+ ocelot_mact_forget(ocelot, dev->dev_addr, ocelot_port->pvid); - - ether_addr_copy(dev->dev_addr, addr->sa_data); - return 0; -@@ -778,11 +792,12 @@ static int ocelot_port_set_mac_address(s - static void ocelot_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - - /* Configure the port to read the stats from */ -- ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port->chip_port), -+ ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port), - SYS_STAT_CFG); - - /* Get Rx stats */ -@@ -814,12 +829,13 @@ static void ocelot_get_stats64(struct ne - } - - static int ocelot_fdb_add(struct ocelot *ocelot, int port, -- const unsigned char *addr, u16 vid) -+ const unsigned char *addr, u16 vid, -+ bool vlan_aware) - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; - - if (!vid) { -- if (!ocelot_port->vlan_aware) -+ if (!vlan_aware) - /* If the bridge is not VLAN aware and no VID was - * provided, set it to pvid to ensure the MAC entry - * matches incoming untagged packets -@@ -841,10 +857,11 @@ static int ocelot_port_fdb_add(struct nd - u16 vid, u16 flags, - struct netlink_ext_ack *extack) - { -- struct ocelot_port *ocelot_port = netdev_priv(dev); -- struct ocelot *ocelot = ocelot_port->ocelot; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - -- return ocelot_fdb_add(ocelot, ocelot_port->chip_port, addr, vid); -+ return ocelot_fdb_add(ocelot, port, addr, vid, priv->vlan_aware); - } - - static int ocelot_fdb_del(struct ocelot *ocelot, int port, -@@ -857,10 +874,11 @@ static int ocelot_port_fdb_del(struct nd - struct net_device *dev, - const unsigned char *addr, u16 vid) - { -- struct ocelot_port *ocelot_port = netdev_priv(dev); -- struct ocelot *ocelot = ocelot_port->ocelot; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - -- return ocelot_fdb_del(ocelot, ocelot_port->chip_port, addr, vid); -+ return ocelot_fdb_del(ocelot, port, addr, vid); - } - - struct ocelot_dump_ctx { -@@ -999,18 +1017,18 @@ static int ocelot_port_fdb_dump(struct s - struct net_device *dev, - struct net_device *filter_dev, int *idx) - { -- struct ocelot_port *ocelot_port = netdev_priv(dev); -- struct ocelot *ocelot = ocelot_port->ocelot; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; - struct ocelot_dump_ctx dump = { - .dev = dev, - .skb = skb, - .cb = cb, - .idx = *idx, - }; -+ int port = priv->chip_port; - int ret; - -- ret = ocelot_fdb_dump(ocelot, ocelot_port->chip_port, -- ocelot_port_fdb_do_dump, &dump); -+ ret = ocelot_fdb_dump(ocelot, port, ocelot_port_fdb_do_dump, &dump); - - *idx = dump.idx; - -@@ -1033,12 +1051,12 @@ static int ocelot_set_features(struct ne - netdev_features_t features) - { - netdev_features_t changed = dev->features ^ features; -- struct ocelot_port *ocelot_port = netdev_priv(dev); -- struct ocelot *ocelot = ocelot_port->ocelot; -- int port = ocelot_port->chip_port; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - - if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) && -- ocelot_port->tc.offload_cnt) { -+ priv->tc.offload_cnt) { - netdev_err(dev, - "Cannot disable HW TC offload while offloads active\n"); - return -EBUSY; -@@ -1053,8 +1071,8 @@ static int ocelot_set_features(struct ne - static int ocelot_get_port_parent_id(struct net_device *dev, - struct netdev_phys_item_id *ppid) - { -- struct ocelot_port *ocelot_port = netdev_priv(dev); -- struct ocelot *ocelot = ocelot_port->ocelot; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; - - ppid->id_len = sizeof(ocelot->base_mac); - memcpy(&ppid->id, &ocelot->base_mac, ppid->id_len); -@@ -1130,9 +1148,9 @@ static int ocelot_hwstamp_set(struct oce - - static int ocelot_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) - { -- struct ocelot_port *ocelot_port = netdev_priv(dev); -- struct ocelot *ocelot = ocelot_port->ocelot; -- int port = ocelot_port->chip_port; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - - /* The function is only used for PTP operations for now */ - if (!ocelot->ptp) -@@ -1169,8 +1187,8 @@ static const struct net_device_ops ocelo - - static void ocelot_get_strings(struct net_device *netdev, u32 sset, u8 *data) - { -- struct ocelot_port *port = netdev_priv(netdev); -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port_private *priv = netdev_priv(netdev); -+ struct ocelot *ocelot = priv->port.ocelot; - int i; - - if (sset != ETH_SS_STATS) -@@ -1224,8 +1242,9 @@ static void ocelot_check_stats_work(stru - static void ocelot_get_ethtool_stats(struct net_device *dev, - struct ethtool_stats *stats, u64 *data) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - int i; - - /* check and update now */ -@@ -1233,13 +1252,13 @@ static void ocelot_get_ethtool_stats(str - - /* Copy all counters */ - for (i = 0; i < ocelot->num_stats; i++) -- *data++ = ocelot->stats[port->chip_port * ocelot->num_stats + i]; -+ *data++ = ocelot->stats[port * ocelot->num_stats + i]; - } - - static int ocelot_get_sset_count(struct net_device *dev, int sset) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; - - if (sset != ETH_SS_STATS) - return -EOPNOTSUPP; -@@ -1249,8 +1268,8 @@ static int ocelot_get_sset_count(struct - static int ocelot_get_ts_info(struct net_device *dev, - struct ethtool_ts_info *info) - { -- struct ocelot_port *ocelot_port = netdev_priv(dev); -- struct ocelot *ocelot = ocelot_port->ocelot; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; - - if (!ocelot->ptp) - return ethtool_op_get_ts_info(dev, info); -@@ -1385,9 +1404,9 @@ static int ocelot_port_attr_set(struct n - const struct switchdev_attr *attr, - struct switchdev_trans *trans) - { -- struct ocelot_port *ocelot_port = netdev_priv(dev); -- struct ocelot *ocelot = ocelot_port->ocelot; -- int port = ocelot_port->chip_port; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - int err = 0; - - switch (attr->id) { -@@ -1399,8 +1418,8 @@ static int ocelot_port_attr_set(struct n - ocelot_port_attr_ageing_set(ocelot, port, attr->u.ageing_time); - break; - case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING: -- ocelot_port_vlan_filtering(ocelot, port, -- attr->u.vlan_filtering); -+ priv->vlan_aware = attr->u.vlan_filtering; -+ ocelot_port_vlan_filtering(ocelot, port, priv->vlan_aware); - break; - case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED: - ocelot_port_attr_mc_set(ocelot, port, !attr->u.mc_disabled); -@@ -1465,15 +1484,17 @@ static int ocelot_port_obj_add_mdb(struc - const struct switchdev_obj_port_mdb *mdb, - struct switchdev_trans *trans) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -- struct ocelot_multicast *mc; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot_port *ocelot_port = &priv->port; -+ struct ocelot *ocelot = ocelot_port->ocelot; - unsigned char addr[ETH_ALEN]; -+ struct ocelot_multicast *mc; -+ int port = priv->chip_port; - u16 vid = mdb->vid; - bool new = false; - - if (!vid) -- vid = port->pvid; -+ vid = ocelot_port->pvid; - - mc = ocelot_multicast_get(ocelot, mdb->addr, vid); - if (!mc) { -@@ -1497,7 +1518,7 @@ static int ocelot_port_obj_add_mdb(struc - ocelot_mact_forget(ocelot, addr, vid); - } - -- mc->ports |= BIT(port->chip_port); -+ mc->ports |= BIT(port); - addr[2] = mc->ports << 0; - addr[1] = mc->ports << 8; - -@@ -1507,14 +1528,16 @@ static int ocelot_port_obj_add_mdb(struc - static int ocelot_port_obj_del_mdb(struct net_device *dev, - const struct switchdev_obj_port_mdb *mdb) - { -- struct ocelot_port *port = netdev_priv(dev); -- struct ocelot *ocelot = port->ocelot; -- struct ocelot_multicast *mc; -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot_port *ocelot_port = &priv->port; -+ struct ocelot *ocelot = ocelot_port->ocelot; - unsigned char addr[ETH_ALEN]; -+ struct ocelot_multicast *mc; -+ int port = priv->chip_port; - u16 vid = mdb->vid; - - if (!vid) -- vid = port->pvid; -+ vid = ocelot_port->pvid; - - mc = ocelot_multicast_get(ocelot, mdb->addr, vid); - if (!mc) -@@ -1526,7 +1549,7 @@ static int ocelot_port_obj_del_mdb(struc - addr[0] = 0; - ocelot_mact_forget(ocelot, addr, vid); - -- mc->ports &= ~BIT(port->chip_port); -+ mc->ports &= ~BIT(port); - if (!mc->ports) { - list_del(&mc->list); - devm_kfree(ocelot->dev, mc); -@@ -1680,9 +1703,9 @@ static int ocelot_port_lag_join(struct o - - rcu_read_lock(); - for_each_netdev_in_bond_rcu(bond, ndev) { -- struct ocelot_port *port = netdev_priv(ndev); -+ struct ocelot_port_private *priv = netdev_priv(ndev); - -- bond_mask |= BIT(port->chip_port); -+ bond_mask |= BIT(priv->chip_port); - } - rcu_read_unlock(); - -@@ -1750,20 +1773,23 @@ static int ocelot_netdevice_port_event(s - unsigned long event, - struct netdev_notifier_changeupper_info *info) - { -- struct ocelot_port *ocelot_port = netdev_priv(dev); -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot_port *ocelot_port = &priv->port; - struct ocelot *ocelot = ocelot_port->ocelot; -- int port = ocelot_port->chip_port; -+ int port = priv->chip_port; - int err = 0; - - switch (event) { - case NETDEV_CHANGEUPPER: - if (netif_is_bridge_master(info->upper_dev)) { -- if (info->linking) -+ if (info->linking) { - err = ocelot_port_bridge_join(ocelot, port, - info->upper_dev); -- else -+ } else { - err = ocelot_port_bridge_leave(ocelot, port, - info->upper_dev); -+ priv->vlan_aware = false; -+ } - } - if (netif_is_lag_master(info->upper_dev)) { - if (info->linking) -@@ -2079,21 +2105,23 @@ int ocelot_probe_port(struct ocelot *oce - void __iomem *regs, - struct phy_device *phy) - { -+ struct ocelot_port_private *priv; - struct ocelot_port *ocelot_port; - struct net_device *dev; - u32 val; - int err; - -- dev = alloc_etherdev(sizeof(struct ocelot_port)); -+ dev = alloc_etherdev(sizeof(struct ocelot_port_private)); - if (!dev) - return -ENOMEM; - SET_NETDEV_DEV(dev, ocelot->dev); -- ocelot_port = netdev_priv(dev); -- ocelot_port->dev = dev; -+ priv = netdev_priv(dev); -+ priv->dev = dev; -+ priv->phy = phy; -+ priv->chip_port = port; -+ ocelot_port = &priv->port; - ocelot_port->ocelot = ocelot; - ocelot_port->regs = regs; -- ocelot_port->chip_port = port; -- ocelot_port->phy = phy; - ocelot->ports[port] = ocelot_port; - - dev->netdev_ops = &ocelot_port_netdev_ops; ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -479,11 +479,9 @@ struct ocelot { - }; - - struct ocelot_port { -- struct net_device *dev; - struct ocelot *ocelot; -- struct phy_device *phy; -+ - void __iomem *regs; -- u8 chip_port; - - /* Ingress default VLAN (pvid) */ - u16 pvid; -@@ -491,18 +489,23 @@ struct ocelot_port { - /* Egress default VLAN (vid) */ - u16 vid; - -- u8 vlan_aware; -+ u8 ptp_cmd; -+ struct list_head skbs; -+ u8 ts_id; -+}; - -- u64 *stats; -+struct ocelot_port_private { -+ struct ocelot_port port; -+ struct net_device *dev; -+ struct phy_device *phy; -+ u8 chip_port; -+ -+ u8 vlan_aware; - - phy_interface_t phy_mode; - struct phy *serdes; - - struct ocelot_port_tc tc; -- -- u8 ptp_cmd; -- struct list_head skbs; -- u8 ts_id; - }; - - struct ocelot_skb { ---- a/drivers/net/ethernet/mscc/ocelot_ace.h -+++ b/drivers/net/ethernet/mscc/ocelot_ace.h -@@ -224,9 +224,9 @@ int ocelot_ace_rule_stats_update(struct - int ocelot_ace_init(struct ocelot *ocelot); - void ocelot_ace_deinit(void); - --int ocelot_setup_tc_block_flower_bind(struct ocelot_port *port, -+int ocelot_setup_tc_block_flower_bind(struct ocelot_port_private *priv, - struct flow_block_offload *f); --void ocelot_setup_tc_block_flower_unbind(struct ocelot_port *port, -+void ocelot_setup_tc_block_flower_unbind(struct ocelot_port_private *priv, - struct flow_block_offload *f); - - #endif /* _MSCC_OCELOT_ACE_H_ */ ---- a/drivers/net/ethernet/mscc/ocelot_board.c -+++ b/drivers/net/ethernet/mscc/ocelot_board.c -@@ -95,6 +95,8 @@ static irqreturn_t ocelot_xtr_irq_handle - - do { - struct skb_shared_hwtstamps *shhwtstamps; -+ struct ocelot_port_private *priv; -+ struct ocelot_port *ocelot_port; - u64 tod_in_ns, full_ts_in_ns; - struct frame_info info = {}; - struct net_device *dev; -@@ -122,7 +124,10 @@ static irqreturn_t ocelot_xtr_irq_handle - - ocelot_parse_ifh(ifh, &info); - -- dev = ocelot->ports[info.port]->dev; -+ ocelot_port = ocelot->ports[info.port]; -+ priv = container_of(ocelot_port, struct ocelot_port_private, -+ port); -+ dev = priv->dev; - - skb = netdev_alloc_skb(dev, info.len); - -@@ -371,6 +376,8 @@ static int mscc_ocelot_probe(struct plat - ocelot_init(ocelot); - - for_each_available_child_of_node(ports, portnp) { -+ struct ocelot_port_private *priv; -+ struct ocelot_port *ocelot_port; - struct device_node *phy_node; - struct phy_device *phy; - struct resource *res; -@@ -406,13 +413,17 @@ static int mscc_ocelot_probe(struct plat - goto out_put_ports; - } - -+ ocelot_port = ocelot->ports[port]; -+ priv = container_of(ocelot_port, struct ocelot_port_private, -+ port); -+ - phy_mode = of_get_phy_mode(portnp); - if (phy_mode < 0) -- ocelot->ports[port]->phy_mode = PHY_INTERFACE_MODE_NA; -- else -- ocelot->ports[port]->phy_mode = phy_mode; -+ phy_mode = PHY_INTERFACE_MODE_NA; -+ -+ priv->phy_mode = phy_mode; - -- switch (ocelot->ports[port]->phy_mode) { -+ switch (priv->phy_mode) { - case PHY_INTERFACE_MODE_NA: - continue; - case PHY_INTERFACE_MODE_SGMII: -@@ -421,7 +432,7 @@ static int mscc_ocelot_probe(struct plat - /* Ensure clock signals and speed is set on all - * QSGMII links - */ -- ocelot_port_writel(ocelot->ports[port], -+ ocelot_port_writel(ocelot_port, - DEV_CLOCK_CFG_LINK_SPEED - (OCELOT_SPEED_1000), - DEV_CLOCK_CFG); -@@ -449,7 +460,7 @@ static int mscc_ocelot_probe(struct plat - goto out_put_ports; - } - -- ocelot->ports[port]->serdes = serdes; -+ priv->serdes = serdes; - } - - register_netdevice_notifier(&ocelot_netdevice_nb); ---- a/drivers/net/ethernet/mscc/ocelot_flower.c -+++ b/drivers/net/ethernet/mscc/ocelot_flower.c -@@ -10,7 +10,7 @@ - - struct ocelot_port_block { - struct ocelot_acl_block *block; -- struct ocelot_port *port; -+ struct ocelot_port_private *priv; - }; - - static int ocelot_flower_parse_action(struct flow_cls_offload *f, -@@ -177,8 +177,8 @@ struct ocelot_ace_rule *ocelot_ace_rule_ - if (!rule) - return NULL; - -- rule->port = block->port; -- rule->chip_port = block->port->chip_port; -+ rule->port = &block->priv->port; -+ rule->chip_port = block->priv->chip_port; - return rule; - } - -@@ -202,7 +202,7 @@ static int ocelot_flower_replace(struct - if (ret) - return ret; - -- port_block->port->tc.offload_cnt++; -+ port_block->priv->tc.offload_cnt++; - return 0; - } - -@@ -213,14 +213,14 @@ static int ocelot_flower_destroy(struct - int ret; - - rule.prio = f->common.prio; -- rule.port = port_block->port; -+ rule.port = &port_block->priv->port; - rule.id = f->cookie; - - ret = ocelot_ace_rule_offload_del(&rule); - if (ret) - return ret; - -- port_block->port->tc.offload_cnt--; -+ port_block->priv->tc.offload_cnt--; - return 0; - } - -@@ -231,7 +231,7 @@ static int ocelot_flower_stats_update(st - int ret; - - rule.prio = f->common.prio; -- rule.port = port_block->port; -+ rule.port = &port_block->priv->port; - rule.id = f->cookie; - ret = ocelot_ace_rule_stats_update(&rule); - if (ret) -@@ -261,7 +261,7 @@ static int ocelot_setup_tc_block_cb_flow - { - struct ocelot_port_block *port_block = cb_priv; - -- if (!tc_cls_can_offload_and_chain0(port_block->port->dev, type_data)) -+ if (!tc_cls_can_offload_and_chain0(port_block->priv->dev, type_data)) - return -EOPNOTSUPP; - - switch (type) { -@@ -275,7 +275,7 @@ static int ocelot_setup_tc_block_cb_flow - } - - static struct ocelot_port_block* --ocelot_port_block_create(struct ocelot_port *port) -+ocelot_port_block_create(struct ocelot_port_private *priv) - { - struct ocelot_port_block *port_block; - -@@ -283,7 +283,7 @@ ocelot_port_block_create(struct ocelot_p - if (!port_block) - return NULL; - -- port_block->port = port; -+ port_block->priv = priv; - - return port_block; - } -@@ -300,7 +300,7 @@ static void ocelot_tc_block_unbind(void - ocelot_port_block_destroy(port_block); - } - --int ocelot_setup_tc_block_flower_bind(struct ocelot_port *port, -+int ocelot_setup_tc_block_flower_bind(struct ocelot_port_private *priv, - struct flow_block_offload *f) - { - struct ocelot_port_block *port_block; -@@ -311,14 +311,14 @@ int ocelot_setup_tc_block_flower_bind(st - return -EOPNOTSUPP; - - block_cb = flow_block_cb_lookup(f->block, -- ocelot_setup_tc_block_cb_flower, port); -+ ocelot_setup_tc_block_cb_flower, priv); - if (!block_cb) { -- port_block = ocelot_port_block_create(port); -+ port_block = ocelot_port_block_create(priv); - if (!port_block) - return -ENOMEM; - - block_cb = flow_block_cb_alloc(ocelot_setup_tc_block_cb_flower, -- port, port_block, -+ priv, port_block, - ocelot_tc_block_unbind); - if (IS_ERR(block_cb)) { - ret = PTR_ERR(block_cb); -@@ -339,13 +339,13 @@ err_cb_register: - return ret; - } - --void ocelot_setup_tc_block_flower_unbind(struct ocelot_port *port, -+void ocelot_setup_tc_block_flower_unbind(struct ocelot_port_private *priv, - struct flow_block_offload *f) - { - struct flow_block_cb *block_cb; - - block_cb = flow_block_cb_lookup(f->block, -- ocelot_setup_tc_block_cb_flower, port); -+ ocelot_setup_tc_block_cb_flower, priv); - if (!block_cb) - return; - ---- a/drivers/net/ethernet/mscc/ocelot_tc.c -+++ b/drivers/net/ethernet/mscc/ocelot_tc.c -@@ -9,17 +9,19 @@ - #include "ocelot_ace.h" - #include - --static int ocelot_setup_tc_cls_matchall(struct ocelot_port *port, -+static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv, - struct tc_cls_matchall_offload *f, - bool ingress) - { - struct netlink_ext_ack *extack = f->common.extack; -+ struct ocelot *ocelot = priv->port.ocelot; - struct ocelot_policer pol = { 0 }; - struct flow_action_entry *action; -+ int port = priv->chip_port; - int err; - -- netdev_dbg(port->dev, "%s: port %u command %d cookie %lu\n", -- __func__, port->chip_port, f->command, f->cookie); -+ netdev_dbg(priv->dev, "%s: port %u command %d cookie %lu\n", -+ __func__, port, f->command, f->cookie); - - if (!ingress) { - NL_SET_ERR_MSG_MOD(extack, "Only ingress is supported"); -@@ -34,7 +36,7 @@ static int ocelot_setup_tc_cls_matchall( - return -EOPNOTSUPP; - } - -- if (port->tc.block_shared) { -+ if (priv->tc.block_shared) { - NL_SET_ERR_MSG_MOD(extack, - "Rate limit is not supported on shared blocks"); - return -EOPNOTSUPP; -@@ -47,7 +49,7 @@ static int ocelot_setup_tc_cls_matchall( - return -EOPNOTSUPP; - } - -- if (port->tc.police_id && port->tc.police_id != f->cookie) { -+ if (priv->tc.police_id && priv->tc.police_id != f->cookie) { - NL_SET_ERR_MSG_MOD(extack, - "Only one policer per port is supported\n"); - return -EEXIST; -@@ -58,28 +60,27 @@ static int ocelot_setup_tc_cls_matchall( - PSCHED_NS2TICKS(action->police.burst), - PSCHED_TICKS_PER_SEC); - -- err = ocelot_port_policer_add(port->ocelot, port->chip_port, -- &pol); -+ err = ocelot_port_policer_add(ocelot, port, &pol); - if (err) { - NL_SET_ERR_MSG_MOD(extack, "Could not add policer\n"); - return err; - } - -- port->tc.police_id = f->cookie; -- port->tc.offload_cnt++; -+ priv->tc.police_id = f->cookie; -+ priv->tc.offload_cnt++; - return 0; - case TC_CLSMATCHALL_DESTROY: -- if (port->tc.police_id != f->cookie) -+ if (priv->tc.police_id != f->cookie) - return -ENOENT; - -- err = ocelot_port_policer_del(port->ocelot, port->chip_port); -+ err = ocelot_port_policer_del(ocelot, port); - if (err) { - NL_SET_ERR_MSG_MOD(extack, - "Could not delete policer\n"); - return err; - } -- port->tc.police_id = 0; -- port->tc.offload_cnt--; -+ priv->tc.police_id = 0; -+ priv->tc.offload_cnt--; - return 0; - case TC_CLSMATCHALL_STATS: /* fall through */ - default: -@@ -91,21 +92,21 @@ static int ocelot_setup_tc_block_cb(enum - void *type_data, - void *cb_priv, bool ingress) - { -- struct ocelot_port *port = cb_priv; -+ struct ocelot_port_private *priv = cb_priv; - -- if (!tc_cls_can_offload_and_chain0(port->dev, type_data)) -+ if (!tc_cls_can_offload_and_chain0(priv->dev, type_data)) - return -EOPNOTSUPP; - - switch (type) { - case TC_SETUP_CLSMATCHALL: -- netdev_dbg(port->dev, "tc_block_cb: TC_SETUP_CLSMATCHALL %s\n", -+ netdev_dbg(priv->dev, "tc_block_cb: TC_SETUP_CLSMATCHALL %s\n", - ingress ? "ingress" : "egress"); - -- return ocelot_setup_tc_cls_matchall(port, type_data, ingress); -+ return ocelot_setup_tc_cls_matchall(priv, type_data, ingress); - case TC_SETUP_CLSFLOWER: - return 0; - default: -- netdev_dbg(port->dev, "tc_block_cb: type %d %s\n", -+ netdev_dbg(priv->dev, "tc_block_cb: type %d %s\n", - type, - ingress ? "ingress" : "egress"); - -@@ -131,19 +132,19 @@ static int ocelot_setup_tc_block_cb_eg(e - - static LIST_HEAD(ocelot_block_cb_list); - --static int ocelot_setup_tc_block(struct ocelot_port *port, -+static int ocelot_setup_tc_block(struct ocelot_port_private *priv, - struct flow_block_offload *f) - { - struct flow_block_cb *block_cb; - flow_setup_cb_t *cb; - int err; - -- netdev_dbg(port->dev, "tc_block command %d, binder_type %d\n", -+ netdev_dbg(priv->dev, "tc_block command %d, binder_type %d\n", - f->command, f->binder_type); - - if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) { - cb = ocelot_setup_tc_block_cb_ig; -- port->tc.block_shared = f->block_shared; -+ priv->tc.block_shared = f->block_shared; - } else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) { - cb = ocelot_setup_tc_block_cb_eg; - } else { -@@ -154,14 +155,14 @@ static int ocelot_setup_tc_block(struct - - switch (f->command) { - case FLOW_BLOCK_BIND: -- if (flow_block_cb_is_busy(cb, port, &ocelot_block_cb_list)) -+ if (flow_block_cb_is_busy(cb, priv, &ocelot_block_cb_list)) - return -EBUSY; - -- block_cb = flow_block_cb_alloc(cb, port, port, NULL); -+ block_cb = flow_block_cb_alloc(cb, priv, priv, NULL); - if (IS_ERR(block_cb)) - return PTR_ERR(block_cb); - -- err = ocelot_setup_tc_block_flower_bind(port, f); -+ err = ocelot_setup_tc_block_flower_bind(priv, f); - if (err < 0) { - flow_block_cb_free(block_cb); - return err; -@@ -170,11 +171,11 @@ static int ocelot_setup_tc_block(struct - list_add_tail(&block_cb->driver_list, f->driver_block_list); - return 0; - case FLOW_BLOCK_UNBIND: -- block_cb = flow_block_cb_lookup(f->block, cb, port); -+ block_cb = flow_block_cb_lookup(f->block, cb, priv); - if (!block_cb) - return -ENOENT; - -- ocelot_setup_tc_block_flower_unbind(port, f); -+ ocelot_setup_tc_block_flower_unbind(priv, f); - flow_block_cb_remove(block_cb, f); - list_del(&block_cb->driver_list); - return 0; -@@ -186,11 +187,11 @@ static int ocelot_setup_tc_block(struct - int ocelot_setup_tc(struct net_device *dev, enum tc_setup_type type, - void *type_data) - { -- struct ocelot_port *port = netdev_priv(dev); -+ struct ocelot_port_private *priv = netdev_priv(dev); - - switch (type) { - case TC_SETUP_BLOCK: -- return ocelot_setup_tc_block(port, type_data); -+ return ocelot_setup_tc_block(priv, type_data); - default: - return -EOPNOTSUPP; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0245-net-mscc-ocelot-refactor-ethtool-callbacks.patch b/target/linux/layerscape/patches-5.4/701-net-0245-net-mscc-ocelot-refactor-ethtool-callbacks.patch deleted file mode 100644 index 7b979d556b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0245-net-mscc-ocelot-refactor-ethtool-callbacks.patch +++ /dev/null @@ -1,133 +0,0 @@ -From a155893c9c272b2ed1dc3b236d55ca8f651a6ea1 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:54 +0200 -Subject: [PATCH] net: mscc: ocelot: refactor ethtool callbacks - -Convert them into an implementation that can be called from DSA as well. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 64 ++++++++++++++++++++++++++++---------- - 1 file changed, 47 insertions(+), 17 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -1185,10 +1185,9 @@ static const struct net_device_ops ocelo - .ndo_do_ioctl = ocelot_ioctl, - }; - --static void ocelot_get_strings(struct net_device *netdev, u32 sset, u8 *data) -+static void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, -+ u8 *data) - { -- struct ocelot_port_private *priv = netdev_priv(netdev); -- struct ocelot *ocelot = priv->port.ocelot; - int i; - - if (sset != ETH_SS_STATS) -@@ -1199,6 +1198,16 @@ static void ocelot_get_strings(struct ne - ETH_GSTRING_LEN); - } - -+static void ocelot_port_get_strings(struct net_device *netdev, u32 sset, -+ u8 *data) -+{ -+ struct ocelot_port_private *priv = netdev_priv(netdev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; -+ -+ ocelot_get_strings(ocelot, port, sset, data); -+} -+ - static void ocelot_update_stats(struct ocelot *ocelot) - { - int i, j; -@@ -1239,12 +1248,8 @@ static void ocelot_check_stats_work(stru - OCELOT_STATS_CHECK_DELAY); - } - --static void ocelot_get_ethtool_stats(struct net_device *dev, -- struct ethtool_stats *stats, u64 *data) -+static void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data) - { -- struct ocelot_port_private *priv = netdev_priv(dev); -- struct ocelot *ocelot = priv->port.ocelot; -- int port = priv->chip_port; - int i; - - /* check and update now */ -@@ -1255,25 +1260,37 @@ static void ocelot_get_ethtool_stats(str - *data++ = ocelot->stats[port * ocelot->num_stats + i]; - } - --static int ocelot_get_sset_count(struct net_device *dev, int sset) -+static void ocelot_port_get_ethtool_stats(struct net_device *dev, -+ struct ethtool_stats *stats, -+ u64 *data) - { - struct ocelot_port_private *priv = netdev_priv(dev); - struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - -+ ocelot_get_ethtool_stats(ocelot, port, data); -+} -+ -+static int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset) -+{ - if (sset != ETH_SS_STATS) - return -EOPNOTSUPP; -+ - return ocelot->num_stats; - } - --static int ocelot_get_ts_info(struct net_device *dev, -- struct ethtool_ts_info *info) -+static int ocelot_port_get_sset_count(struct net_device *dev, int sset) - { - struct ocelot_port_private *priv = netdev_priv(dev); - struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - -- if (!ocelot->ptp) -- return ethtool_op_get_ts_info(dev, info); -+ return ocelot_get_sset_count(ocelot, port, sset); -+} - -+static int ocelot_get_ts_info(struct ocelot *ocelot, int port, -+ struct ethtool_ts_info *info) -+{ - info->phc_index = ocelot->ptp_clock ? - ptp_clock_index(ocelot->ptp_clock) : -1; - info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | -@@ -1292,13 +1309,26 @@ static int ocelot_get_ts_info(struct net - return 0; - } - -+static int ocelot_port_get_ts_info(struct net_device *dev, -+ struct ethtool_ts_info *info) -+{ -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; -+ -+ if (!ocelot->ptp) -+ return ethtool_op_get_ts_info(dev, info); -+ -+ return ocelot_get_ts_info(ocelot, port, info); -+} -+ - static const struct ethtool_ops ocelot_ethtool_ops = { -- .get_strings = ocelot_get_strings, -- .get_ethtool_stats = ocelot_get_ethtool_stats, -- .get_sset_count = ocelot_get_sset_count, -+ .get_strings = ocelot_port_get_strings, -+ .get_ethtool_stats = ocelot_port_get_ethtool_stats, -+ .get_sset_count = ocelot_port_get_sset_count, - .get_link_ksettings = phy_ethtool_get_link_ksettings, - .set_link_ksettings = phy_ethtool_set_link_ksettings, -- .get_ts_info = ocelot_get_ts_info, -+ .get_ts_info = ocelot_port_get_ts_info, - }; - - static void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, diff --git a/target/linux/layerscape/patches-5.4/701-net-0246-net-mscc-ocelot-limit-vlan-ingress-filtering-to-actu.patch b/target/linux/layerscape/patches-5.4/701-net-0246-net-mscc-ocelot-limit-vlan-ingress-filtering-to-actu.patch deleted file mode 100644 index 532db74c83..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0246-net-mscc-ocelot-limit-vlan-ingress-filtering-to-actu.patch +++ /dev/null @@ -1,28 +0,0 @@ -From acc105226493e7cfdb6e72d130c36f21e951fc1f Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:55 +0200 -Subject: [PATCH] net: mscc: ocelot: limit vlan ingress filtering to actual - number of ports - -The VSC7514 switch (Ocelot) is a 10-port device, while VSC9959 (Felix) -is 6-port. Therefore the VLAN filtering mask would be out of bounds when -calling for this new switch. Fix that. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -389,7 +389,8 @@ static void ocelot_vlan_init(struct ocel - /* Set vlan ingress filter mask to all ports but the CPU port by - * default. - */ -- ocelot_write(ocelot, GENMASK(9, 0), ANA_VLANMASK); -+ ocelot_write(ocelot, GENMASK(ocelot->num_phys_ports - 1, 0), -+ ANA_VLANMASK); - - for (port = 0; port < ocelot->num_phys_ports; port++) { - ocelot_write_gix(ocelot, 0, REW_PORT_VLAN_CFG, port); diff --git a/target/linux/layerscape/patches-5.4/701-net-0247-net-mscc-ocelot-move-port-initialization-into-separa.patch b/target/linux/layerscape/patches-5.4/701-net-0247-net-mscc-ocelot-move-port-initialization-into-separa.patch deleted file mode 100644 index a6bbdd67fe..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0247-net-mscc-ocelot-move-port-initialization-into-separa.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 66f4bb358787f4f52de0614a92f9e4130d1e0e01 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:56 +0200 -Subject: [PATCH] net: mscc: ocelot: move port initialization into separate - function - -We need a function for the DSA front-end that does none of the -net_device registration, but initializes the hardware ports. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 45 ++++++++++++++++++++------------------ - 1 file changed, 24 insertions(+), 21 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -2132,6 +2132,28 @@ static int ocelot_init_timestamp(struct - return 0; - } - -+static void ocelot_init_port(struct ocelot *ocelot, int port) -+{ -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ -+ INIT_LIST_HEAD(&ocelot_port->skbs); -+ -+ /* Basic L2 initialization */ -+ -+ /* Drop frames with multicast source address */ -+ ocelot_rmw_gix(ocelot, ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA, -+ ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA, -+ ANA_PORT_DROP_CFG, port); -+ -+ /* Set default VLAN and tag type to 8021Q. */ -+ ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q), -+ REW_PORT_VLAN_CFG_PORT_TPID_M, -+ REW_PORT_VLAN_CFG, port); -+ -+ /* Enable vcap lookups */ -+ ocelot_vcap_enable(ocelot, port); -+} -+ - int ocelot_probe_port(struct ocelot *ocelot, u8 port, - void __iomem *regs, - struct phy_device *phy) -@@ -2139,7 +2161,6 @@ int ocelot_probe_port(struct ocelot *oce - struct ocelot_port_private *priv; - struct ocelot_port *ocelot_port; - struct net_device *dev; -- u32 val; - int err; - - dev = alloc_etherdev(sizeof(struct ocelot_port_private)); -@@ -2167,32 +2188,14 @@ int ocelot_probe_port(struct ocelot *oce - ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, ocelot_port->pvid, - ENTRYTYPE_LOCKED); - -- INIT_LIST_HEAD(&ocelot_port->skbs); -+ ocelot_init_port(ocelot, port); - - err = register_netdev(dev); - if (err) { - dev_err(ocelot->dev, "register_netdev failed\n"); -- goto err_register_netdev; -+ free_netdev(dev); - } - -- /* Basic L2 initialization */ -- -- /* Drop frames with multicast source address */ -- val = ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA; -- ocelot_rmw_gix(ocelot, val, val, ANA_PORT_DROP_CFG, port); -- -- /* Set default VLAN and tag type to 8021Q. */ -- ocelot_rmw_gix(ocelot, REW_PORT_VLAN_CFG_PORT_TPID(ETH_P_8021Q), -- REW_PORT_VLAN_CFG_PORT_TPID_M, -- REW_PORT_VLAN_CFG, port); -- -- /* Enable vcap lookups */ -- ocelot_vcap_enable(ocelot, port); -- -- return 0; -- --err_register_netdev: -- free_netdev(dev); - return err; - } - EXPORT_SYMBOL(ocelot_probe_port); diff --git a/target/linux/layerscape/patches-5.4/701-net-0248-net-mscc-ocelot-separate-the-common-implementation-o.patch b/target/linux/layerscape/patches-5.4/701-net-0248-net-mscc-ocelot-separate-the-common-implementation-o.patch deleted file mode 100644 index f0b6393752..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0248-net-mscc-ocelot-separate-the-common-implementation-o.patch +++ /dev/null @@ -1,86 +0,0 @@ -From ac918399cae8b62f58f50b40bf8037d0fa9353eb Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:57 +0200 -Subject: [PATCH] net: mscc: ocelot: separate the common implementation of - ndo_open and ndo_stop - -Allow these functions to be called from the .port_enable and -.port_disable callbacks of DSA. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 36 ++++++++++++++++++++++++++---------- - 1 file changed, 26 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -536,13 +536,9 @@ static void ocelot_port_adjust_link(stru - ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG); - } - --static int ocelot_port_open(struct net_device *dev) -+static void ocelot_port_enable(struct ocelot *ocelot, int port, -+ struct phy_device *phy) - { -- struct ocelot_port_private *priv = netdev_priv(dev); -- struct ocelot *ocelot = priv->port.ocelot; -- int port = priv->chip_port; -- int err; -- - /* Enable receiving frames on the port, and activate auto-learning of - * MAC addresses. - */ -@@ -550,6 +546,14 @@ static int ocelot_port_open(struct net_d - ANA_PORT_PORT_CFG_RECV_ENA | - ANA_PORT_PORT_CFG_PORTID_VAL(port), - ANA_PORT_PORT_CFG, port); -+} -+ -+static int ocelot_port_open(struct net_device *dev) -+{ -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; -+ int err; - - if (priv->serdes) { - err = phy_set_mode_ext(priv->serdes, PHY_MODE_ETHERNET, -@@ -571,21 +575,33 @@ static int ocelot_port_open(struct net_d - - phy_attached_info(priv->phy); - phy_start(priv->phy); -+ -+ ocelot_port_enable(ocelot, port, priv->phy); -+ - return 0; - } - -+static void ocelot_port_disable(struct ocelot *ocelot, int port) -+{ -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ -+ ocelot_port_writel(ocelot_port, 0, DEV_MAC_ENA_CFG); -+ ocelot_rmw_rix(ocelot, 0, QSYS_SWITCH_PORT_MODE_PORT_ENA, -+ QSYS_SWITCH_PORT_MODE, port); -+} -+ - static int ocelot_port_stop(struct net_device *dev) - { - struct ocelot_port_private *priv = netdev_priv(dev); -- struct ocelot_port *port = &priv->port; -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; - - phy_disconnect(priv->phy); - - dev->phydev = NULL; - -- ocelot_port_writel(port, 0, DEV_MAC_ENA_CFG); -- ocelot_rmw_rix(port->ocelot, 0, QSYS_SWITCH_PORT_MODE_PORT_ENA, -- QSYS_SWITCH_PORT_MODE, priv->chip_port); -+ ocelot_port_disable(ocelot, port); -+ - return 0; - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0249-net-mscc-ocelot-initialize-list-of-multicast-address.patch b/target/linux/layerscape/patches-5.4/701-net-0249-net-mscc-ocelot-initialize-list-of-multicast-address.patch deleted file mode 100644 index b0c349ec37..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0249-net-mscc-ocelot-initialize-list-of-multicast-address.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0a7e5a60bdd559d092912adb34bc99c6457d3fb6 Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Sat, 9 Nov 2019 15:02:58 +0200 -Subject: [PATCH] net: mscc: ocelot: initialize list of multicast addresses in - common code - -This is just common path code that belongs to ocelot_init, -it has nothing to do with a specific SoC/board instance. - -Signed-off-by: Claudiu Manoil -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 1 + - drivers/net/ethernet/mscc/ocelot_board.c | 1 - - 2 files changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -2242,6 +2242,7 @@ int ocelot_init(struct ocelot *ocelot) - if (!ocelot->stats_queue) - return -ENOMEM; - -+ INIT_LIST_HEAD(&ocelot->multicast); - ocelot_mact_init(ocelot); - ocelot_vlan_init(ocelot); - ocelot_ace_init(ocelot); ---- a/drivers/net/ethernet/mscc/ocelot_board.c -+++ b/drivers/net/ethernet/mscc/ocelot_board.c -@@ -372,7 +372,6 @@ static int mscc_ocelot_probe(struct plat - ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports, - sizeof(struct ocelot_port *), GFP_KERNEL); - -- INIT_LIST_HEAD(&ocelot->multicast); - ocelot_init(ocelot); - - for_each_available_child_of_node(ports, portnp) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0250-net-mscc-ocelot-refactor-adjust_link-into-a-netdev-i.patch b/target/linux/layerscape/patches-5.4/701-net-0250-net-mscc-ocelot-refactor-adjust_link-into-a-netdev-i.patch deleted file mode 100644 index 7f80cd4a88..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0250-net-mscc-ocelot-refactor-adjust_link-into-a-netdev-i.patch +++ /dev/null @@ -1,72 +0,0 @@ -From f8c221dc7383a50defcc5b96595e092159dbe928 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:02:59 +0200 -Subject: [PATCH] net: mscc: ocelot: refactor adjust_link into a - netdev-independent function - -This will be called from the Felix DSA frontend, which will work in -PHYLIB compatibility mode initially. - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 27 +++++++++++++++++---------- - 1 file changed, 17 insertions(+), 10 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -410,15 +410,13 @@ static u16 ocelot_wm_enc(u16 value) - return value; - } - --static void ocelot_port_adjust_link(struct net_device *dev) -+static void ocelot_adjust_link(struct ocelot *ocelot, int port, -+ struct phy_device *phydev) - { -- struct ocelot_port_private *priv = netdev_priv(dev); -- struct ocelot_port *ocelot_port = &priv->port; -- struct ocelot *ocelot = ocelot_port->ocelot; -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; - int speed, atop_wm, mode = 0; -- u8 port = priv->chip_port; - -- switch (dev->phydev->speed) { -+ switch (phydev->speed) { - case SPEED_10: - speed = OCELOT_SPEED_10; - break; -@@ -434,14 +432,14 @@ static void ocelot_port_adjust_link(stru - mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA; - break; - default: -- netdev_err(dev, "Unsupported PHY speed: %d\n", -- dev->phydev->speed); -+ dev_err(ocelot->dev, "Unsupported PHY speed on port %d: %d\n", -+ port, phydev->speed); - return; - } - -- phy_print_status(dev->phydev); -+ phy_print_status(phydev); - -- if (!dev->phydev->link) -+ if (!phydev->link) - return; - - /* Only full duplex supported for now */ -@@ -536,6 +534,15 @@ static void ocelot_port_adjust_link(stru - ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG); - } - -+static void ocelot_port_adjust_link(struct net_device *dev) -+{ -+ struct ocelot_port_private *priv = netdev_priv(dev); -+ struct ocelot *ocelot = priv->port.ocelot; -+ int port = priv->chip_port; -+ -+ ocelot_adjust_link(ocelot, port, dev->phydev); -+} -+ - static void ocelot_port_enable(struct ocelot *ocelot, int port, - struct phy_device *phy) - { diff --git a/target/linux/layerscape/patches-5.4/701-net-0251-net-mscc-ocelot-split-assignment-of-the-cpu-port-int.patch b/target/linux/layerscape/patches-5.4/701-net-0251-net-mscc-ocelot-split-assignment-of-the-cpu-port-int.patch deleted file mode 100644 index 8fa0bca935..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0251-net-mscc-ocelot-split-assignment-of-the-cpu-port-int.patch +++ /dev/null @@ -1,163 +0,0 @@ -From c6f39379529e74eccbe317e70bb11d18110c63d4 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:03:00 +0200 -Subject: [PATCH] net: mscc: ocelot: split assignment of the cpu port into a - separate function - -Now that the places that configure routing destinations for the CPU port -have been marked as such, allow callers to specify their own CPU port -that is different than ocelot->num_phys_ports. A user will be the Felix -DSA driver, where the CPU port is one of the physical ports (NPI mode). - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 65 +++++++++++++++++++++----------- - drivers/net/ethernet/mscc/ocelot.h | 12 ++++++ - drivers/net/ethernet/mscc/ocelot_board.c | 2 + - 3 files changed, 57 insertions(+), 22 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -380,12 +380,6 @@ static void ocelot_vlan_init(struct ocel - ocelot->vlan_mask[0] = GENMASK(ocelot->num_phys_ports - 1, 0); - ocelot_vlant_set_mask(ocelot, 0, ocelot->vlan_mask[0]); - -- /* Configure the CPU port to be VLAN aware */ -- ocelot_write_gix(ocelot, ANA_PORT_VLAN_CFG_VLAN_VID(0) | -- ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA | -- ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1), -- ANA_PORT_VLAN_CFG, ocelot->num_phys_ports); -- - /* Set vlan ingress filter mask to all ports but the CPU port by - * default. - */ -@@ -2223,11 +2217,52 @@ int ocelot_probe_port(struct ocelot *oce - } - EXPORT_SYMBOL(ocelot_probe_port); - -+void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu, -+ enum ocelot_tag_prefix injection, -+ enum ocelot_tag_prefix extraction) -+{ -+ /* Configure and enable the CPU port. */ -+ ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu); -+ ocelot_write_rix(ocelot, BIT(cpu), ANA_PGID_PGID, PGID_CPU); -+ ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_RECV_ENA | -+ ANA_PORT_PORT_CFG_PORTID_VAL(cpu), -+ ANA_PORT_PORT_CFG, cpu); -+ -+ /* If the CPU port is a physical port, set up the port in Node -+ * Processor Interface (NPI) mode. This is the mode through which -+ * frames can be injected from and extracted to an external CPU. -+ * Only one port can be an NPI at the same time. -+ */ -+ if (cpu < ocelot->num_phys_ports) { -+ ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M | -+ QSYS_EXT_CPU_CFG_EXT_CPU_PORT(cpu), -+ QSYS_EXT_CPU_CFG); -+ } -+ -+ /* CPU port Injection/Extraction configuration */ -+ ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE | -+ QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) | -+ QSYS_SWITCH_PORT_MODE_PORT_ENA, -+ QSYS_SWITCH_PORT_MODE, cpu); -+ ocelot_write_rix(ocelot, SYS_PORT_MODE_INCL_XTR_HDR(extraction) | -+ SYS_PORT_MODE_INCL_INJ_HDR(injection), -+ SYS_PORT_MODE, cpu); -+ -+ /* Configure the CPU port to be VLAN aware */ -+ ocelot_write_gix(ocelot, ANA_PORT_VLAN_CFG_VLAN_VID(0) | -+ ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA | -+ ANA_PORT_VLAN_CFG_VLAN_POP_CNT(1), -+ ANA_PORT_VLAN_CFG, cpu); -+ -+ ocelot->cpu = cpu; -+} -+EXPORT_SYMBOL(ocelot_set_cpu_port); -+ - int ocelot_init(struct ocelot *ocelot) - { -- u32 port; -- int i, ret, cpu = ocelot->num_phys_ports; - char queue_name[32]; -+ int i, ret; -+ u32 port; - - ocelot->lags = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports, - sizeof(u32), GFP_KERNEL); -@@ -2307,13 +2342,6 @@ int ocelot_init(struct ocelot *ocelot) - ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_SRC + port); - } - -- /* Configure and enable the CPU port. */ -- ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu); -- ocelot_write_rix(ocelot, BIT(cpu), ANA_PGID_PGID, PGID_CPU); -- ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_RECV_ENA | -- ANA_PORT_PORT_CFG_PORTID_VAL(cpu), -- ANA_PORT_PORT_CFG, cpu); -- - /* Allow broadcast MAC frames. */ - for (i = ocelot->num_phys_ports + 1; i < PGID_CPU; i++) { - u32 val = ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports - 1, 0)); -@@ -2326,13 +2354,6 @@ int ocelot_init(struct ocelot *ocelot) - ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV4); - ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV6); - -- /* CPU port Injection/Extraction configuration */ -- ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE | -- QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) | -- QSYS_SWITCH_PORT_MODE_PORT_ENA, -- QSYS_SWITCH_PORT_MODE, cpu); -- ocelot_write_rix(ocelot, SYS_PORT_MODE_INCL_XTR_HDR(1) | -- SYS_PORT_MODE_INCL_INJ_HDR(1), SYS_PORT_MODE, cpu); - /* Allow manual injection via DEVCPU_QS registers, and byte swap these - * registers endianness. - */ ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -427,6 +427,13 @@ struct ocelot_multicast { - u16 ports; - }; - -+enum ocelot_tag_prefix { -+ OCELOT_TAG_PREFIX_DISABLED = 0, -+ OCELOT_TAG_PREFIX_NONE, -+ OCELOT_TAG_PREFIX_SHORT, -+ OCELOT_TAG_PREFIX_LONG, -+}; -+ - struct ocelot_port; - - struct ocelot_stat_layout { -@@ -455,6 +462,7 @@ struct ocelot { - - u8 num_phys_ports; - u8 num_cpu_ports; -+ u8 cpu; - struct ocelot_port **ports; - - u32 *lags; -@@ -552,6 +560,10 @@ int ocelot_probe_port(struct ocelot *oce - void __iomem *regs, - struct phy_device *phy); - -+void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu, -+ enum ocelot_tag_prefix injection, -+ enum ocelot_tag_prefix extraction); -+ - extern struct notifier_block ocelot_netdevice_nb; - extern struct notifier_block ocelot_switchdev_nb; - extern struct notifier_block ocelot_switchdev_blocking_nb; ---- a/drivers/net/ethernet/mscc/ocelot_board.c -+++ b/drivers/net/ethernet/mscc/ocelot_board.c -@@ -373,6 +373,8 @@ static int mscc_ocelot_probe(struct plat - sizeof(struct ocelot_port *), GFP_KERNEL); - - ocelot_init(ocelot); -+ ocelot_set_cpu_port(ocelot, ocelot->num_phys_ports, -+ OCELOT_TAG_PREFIX_NONE, OCELOT_TAG_PREFIX_NONE); - - for_each_available_child_of_node(ports, portnp) { - struct ocelot_port_private *priv; diff --git a/target/linux/layerscape/patches-5.4/701-net-0252-net-mscc-ocelot-don-t-hardcode-the-number-of-the-CPU.patch b/target/linux/layerscape/patches-5.4/701-net-0252-net-mscc-ocelot-don-t-hardcode-the-number-of-the-CPU.patch deleted file mode 100644 index 7ddc5753f6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0252-net-mscc-ocelot-don-t-hardcode-the-number-of-the-CPU.patch +++ /dev/null @@ -1,63 +0,0 @@ -From d176f477fd2acded12356088c0f67dee059facb5 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 9 Nov 2019 15:03:01 +0200 -Subject: [PATCH] net: mscc: ocelot: don't hardcode the number of the CPU port - -VSC7514 is a 10-port switch with 2 extra "CPU ports" (targets in the -queuing subsystem for terminating traffic locally). - -There are 2 issues with hardcoding the CPU port as #10: -- It is not clear which snippets of the code are configuring something - for one of the CPU ports, and which snippets are just doing something - related to the number of physical ports. -- Actually any physical port can act as a CPU port connected to an - external CPU (in addition to the local CPU). This is called NPI mode - (Node Processor Interface) and is the way that the 6-port VSC9959 - (Felix) switch is integrated inside NXP LS1028A (the "local management - CPU" functionality is not used there). - -This patch makes it clear that the ocelot_bridge_stp_state_set function -operates on the CPU port (by making it an implicit member of the -bridging domain), and at the same time adds logic for the NPI port (aka -a physical port) to play the role of a CPU port (it shouldn't be part of -bridge_fwd_mask, as it's not explicitly enslaved to a bridge). - -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -1380,7 +1380,7 @@ static void ocelot_bridge_stp_state_set( - * a source for the other ports. - */ - for (p = 0; p < ocelot->num_phys_ports; p++) { -- if (ocelot->bridge_fwd_mask & BIT(p)) { -+ if (p == ocelot->cpu || (ocelot->bridge_fwd_mask & BIT(p))) { - unsigned long mask = ocelot->bridge_fwd_mask & ~BIT(p); - - for (i = 0; i < ocelot->num_phys_ports; i++) { -@@ -1395,15 +1395,18 @@ static void ocelot_bridge_stp_state_set( - } - } - -- ocelot_write_rix(ocelot, -- BIT(ocelot->num_phys_ports) | mask, -+ /* Avoid the NPI port from looping back to itself */ -+ if (p != ocelot->cpu) -+ mask |= BIT(ocelot->cpu); -+ -+ ocelot_write_rix(ocelot, mask, - ANA_PGID_PGID, PGID_SRC + p); - } else { - /* Only the CPU port, this is compatible with link - * aggregation. - */ - ocelot_write_rix(ocelot, -- BIT(ocelot->num_phys_ports), -+ BIT(ocelot->cpu), - ANA_PGID_PGID, PGID_SRC + p); - } - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0253-net-mscc-ocelot-move-resource-ioremap-and-regmap-ini.patch b/target/linux/layerscape/patches-5.4/701-net-0253-net-mscc-ocelot-move-resource-ioremap-and-regmap-ini.patch deleted file mode 100644 index 47f53ebd51..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0253-net-mscc-ocelot-move-resource-ioremap-and-regmap-ini.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 01c0da9c8cd3ff6cbe0ced8e28505d4195f60db4 Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Thu, 14 Nov 2019 17:03:20 +0200 -Subject: [PATCH] net: mscc: ocelot: move resource ioremap and regmap init to - common code - -Let's make this ioremap and regmap init code common. It should not -be platform dependent as it should be usable by PCI devices too. -Use better names where necessary to avoid clashes. - -Signed-off-by: Claudiu Manoil -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.h | 4 +--- - drivers/net/ethernet/mscc/ocelot_board.c | 17 ++++++++++------- - drivers/net/ethernet/mscc/ocelot_io.c | 14 +++++--------- - 3 files changed, 16 insertions(+), 19 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -546,9 +546,7 @@ void ocelot_port_writel(struct ocelot_po - - int ocelot_regfields_init(struct ocelot *ocelot, - const struct reg_field *const regfields); --struct regmap *ocelot_io_platform_init(struct ocelot *ocelot, -- struct platform_device *pdev, -- const char *name); -+struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res); - - #define ocelot_field_write(ocelot, reg, val) regmap_field_write((ocelot)->regfields[(reg)], (val)) - #define ocelot_field_read(ocelot, reg, val) regmap_field_read((ocelot)->regfields[(reg)], (val)) ---- a/drivers/net/ethernet/mscc/ocelot_board.c -+++ b/drivers/net/ethernet/mscc/ocelot_board.c -@@ -276,7 +276,7 @@ static int mscc_ocelot_probe(struct plat - enum ocelot_target id; - char *name; - u8 optional:1; -- } res[] = { -+ } io_target[] = { - { SYS, "sys" }, - { REW, "rew" }, - { QSYS, "qsys" }, -@@ -296,20 +296,23 @@ static int mscc_ocelot_probe(struct plat - platform_set_drvdata(pdev, ocelot); - ocelot->dev = &pdev->dev; - -- for (i = 0; i < ARRAY_SIZE(res); i++) { -+ for (i = 0; i < ARRAY_SIZE(io_target); i++) { - struct regmap *target; -+ struct resource *res; - -- target = ocelot_io_platform_init(ocelot, pdev, res[i].name); -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, -+ io_target[i].name); -+ -+ target = ocelot_regmap_init(ocelot, res); - if (IS_ERR(target)) { -- if (res[i].optional) { -- ocelot->targets[res[i].id] = NULL; -+ if (io_target[i].optional) { -+ ocelot->targets[io_target[i].id] = NULL; - continue; - } -- - return PTR_ERR(target); - } - -- ocelot->targets[res[i].id] = target; -+ ocelot->targets[io_target[i].id] = target; - } - - hsio = syscon_regmap_lookup_by_compatible("mscc,ocelot-hsio"); ---- a/drivers/net/ethernet/mscc/ocelot_io.c -+++ b/drivers/net/ethernet/mscc/ocelot_io.c -@@ -97,20 +97,16 @@ static struct regmap_config ocelot_regma - .reg_stride = 4, - }; - --struct regmap *ocelot_io_platform_init(struct ocelot *ocelot, -- struct platform_device *pdev, -- const char *name) -+struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res) - { -- struct resource *res; - void __iomem *regs; - -- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); - regs = devm_ioremap_resource(ocelot->dev, res); - if (IS_ERR(regs)) - return ERR_CAST(regs); - -- ocelot_regmap_config.name = name; -- return devm_regmap_init_mmio(ocelot->dev, regs, -- &ocelot_regmap_config); -+ ocelot_regmap_config.name = res->name; -+ -+ return devm_regmap_init_mmio(ocelot->dev, regs, &ocelot_regmap_config); - } --EXPORT_SYMBOL(ocelot_io_platform_init); -+EXPORT_SYMBOL(ocelot_regmap_init); diff --git a/target/linux/layerscape/patches-5.4/701-net-0254-net-mscc-ocelot-filter-out-ocelot-SoC-specific-PCS-c.patch b/target/linux/layerscape/patches-5.4/701-net-0254-net-mscc-ocelot-filter-out-ocelot-SoC-specific-PCS-c.patch deleted file mode 100644 index 73a45bb2d6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0254-net-mscc-ocelot-filter-out-ocelot-SoC-specific-PCS-c.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 6960d2c4f5e95ae304a62af249d6c92a2d952601 Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Thu, 14 Nov 2019 17:03:21 +0200 -Subject: [PATCH] net: mscc: ocelot: filter out ocelot SoC specific PCS config - from common path - -The adjust_link routine should be generic enough to be (re)used by -any SoC that integrates a switch core compatible with the Ocelot -core switch driver. Currently all configurations are generic except -for the PCS settings that are SoC specific. Move these out to the -Ocelot SoC/board instance. - -Signed-off-by: Claudiu Manoil -Signed-off-by: Vladimir Oltean -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 19 ++----------------- - drivers/net/ethernet/mscc/ocelot.h | 8 +++++++- - drivers/net/ethernet/mscc/ocelot_board.c | 29 ++++++++++++++++++++++++++++- - drivers/net/ethernet/mscc/ocelot_regs.c | 3 ++- - 4 files changed, 39 insertions(+), 20 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -455,23 +455,8 @@ static void ocelot_adjust_link(struct oc - ocelot_port_writel(ocelot_port, DEV_MAC_HDX_CFG_LATE_COL_POS(67), - DEV_MAC_HDX_CFG); - -- /* Disable HDX fast control */ -- ocelot_port_writel(ocelot_port, DEV_PORT_MISC_HDX_FAST_DIS, -- DEV_PORT_MISC); -- -- /* SGMII only for now */ -- ocelot_port_writel(ocelot_port, PCS1G_MODE_CFG_SGMII_MODE_ENA, -- PCS1G_MODE_CFG); -- ocelot_port_writel(ocelot_port, PCS1G_SD_CFG_SD_SEL, PCS1G_SD_CFG); -- -- /* Enable PCS */ -- ocelot_port_writel(ocelot_port, PCS1G_CFG_PCS_ENA, PCS1G_CFG); -- -- /* No aneg on SGMII */ -- ocelot_port_writel(ocelot_port, 0, PCS1G_ANEG_CFG); -- -- /* No loopback */ -- ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG); -+ if (ocelot->ops->pcs_init) -+ ocelot->ops->pcs_init(ocelot, port); - - /* Set Max Length and maximum tags allowed */ - ocelot_port_writel(ocelot_port, VLAN_ETH_FRAME_LEN, ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -435,13 +435,19 @@ enum ocelot_tag_prefix { - }; - - struct ocelot_port; -+struct ocelot; - - struct ocelot_stat_layout { - u32 offset; - char name[ETH_GSTRING_LEN]; - }; - -+struct ocelot_ops { -+ void (*pcs_init)(struct ocelot *ocelot, int port); -+}; -+ - struct ocelot { -+ const struct ocelot_ops *ops; - struct device *dev; - - struct regmap *targets[TARGET_MAX]; -@@ -553,7 +559,7 @@ struct regmap *ocelot_regmap_init(struct - - int ocelot_init(struct ocelot *ocelot); - void ocelot_deinit(struct ocelot *ocelot); --int ocelot_chip_init(struct ocelot *ocelot); -+int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops); - int ocelot_probe_port(struct ocelot *ocelot, u8 port, - void __iomem *regs, - struct phy_device *phy); ---- a/drivers/net/ethernet/mscc/ocelot_board.c -+++ b/drivers/net/ethernet/mscc/ocelot_board.c -@@ -262,6 +262,33 @@ static const struct of_device_id mscc_oc - }; - MODULE_DEVICE_TABLE(of, mscc_ocelot_match); - -+static void ocelot_port_pcs_init(struct ocelot *ocelot, int port) -+{ -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ -+ /* Disable HDX fast control */ -+ ocelot_port_writel(ocelot_port, DEV_PORT_MISC_HDX_FAST_DIS, -+ DEV_PORT_MISC); -+ -+ /* SGMII only for now */ -+ ocelot_port_writel(ocelot_port, PCS1G_MODE_CFG_SGMII_MODE_ENA, -+ PCS1G_MODE_CFG); -+ ocelot_port_writel(ocelot_port, PCS1G_SD_CFG_SD_SEL, PCS1G_SD_CFG); -+ -+ /* Enable PCS */ -+ ocelot_port_writel(ocelot_port, PCS1G_CFG_PCS_ENA, PCS1G_CFG); -+ -+ /* No aneg on SGMII */ -+ ocelot_port_writel(ocelot_port, 0, PCS1G_ANEG_CFG); -+ -+ /* No loopback */ -+ ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG); -+} -+ -+static const struct ocelot_ops ocelot_ops = { -+ .pcs_init = ocelot_port_pcs_init, -+}; -+ - static int mscc_ocelot_probe(struct platform_device *pdev) - { - struct device_node *np = pdev->dev.of_node; -@@ -323,7 +350,7 @@ static int mscc_ocelot_probe(struct plat - - ocelot->targets[HSIO] = hsio; - -- err = ocelot_chip_init(ocelot); -+ err = ocelot_chip_init(ocelot, &ocelot_ops); - if (err) - return err; - ---- a/drivers/net/ethernet/mscc/ocelot_regs.c -+++ b/drivers/net/ethernet/mscc/ocelot_regs.c -@@ -423,7 +423,7 @@ static void ocelot_pll5_init(struct ocel - HSIO_PLL5G_CFG2_AMPC_SEL(0x10)); - } - --int ocelot_chip_init(struct ocelot *ocelot) -+int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops) - { - int ret; - -@@ -431,6 +431,7 @@ int ocelot_chip_init(struct ocelot *ocel - ocelot->stats_layout = ocelot_stats_layout; - ocelot->num_stats = ARRAY_SIZE(ocelot_stats_layout); - ocelot->shared_queue_sz = 224 * 1024; -+ ocelot->ops = ops; - - ret = ocelot_regfields_init(ocelot, ocelot_regfields); - if (ret) diff --git a/target/linux/layerscape/patches-5.4/701-net-0255-net-mscc-ocelot-move-invariant-configs-out-of-adjust.patch b/target/linux/layerscape/patches-5.4/701-net-0255-net-mscc-ocelot-move-invariant-configs-out-of-adjust.patch deleted file mode 100644 index f0f4aeae5d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0255-net-mscc-ocelot-move-invariant-configs-out-of-adjust.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 861a32edce13ccba86647507fefcfd4910972dd7 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 14 Nov 2019 17:03:22 +0200 -Subject: [PATCH] net: mscc: ocelot: move invariant configs out of adjust_link - -It doesn't make sense to rewrite all these registers every time the PHY -library notifies us about a link state change. - -In a future patch we will customize the MTU for the CPU port, and since -the MTU was previously configured from adjust_link, if we don't make -this change, its value would have got overridden. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 85 +++++++++++++++++++------------------- - 1 file changed, 43 insertions(+), 42 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -408,7 +408,7 @@ static void ocelot_adjust_link(struct oc - struct phy_device *phydev) - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; -- int speed, atop_wm, mode = 0; -+ int speed, mode = 0; - - switch (phydev->speed) { - case SPEED_10: -@@ -440,32 +440,9 @@ static void ocelot_adjust_link(struct oc - ocelot_port_writel(ocelot_port, DEV_MAC_MODE_CFG_FDX_ENA | - mode, DEV_MAC_MODE_CFG); - -- /* Set MAC IFG Gaps -- * FDX: TX_IFG = 5, RX_IFG1 = RX_IFG2 = 0 -- * !FDX: TX_IFG = 5, RX_IFG1 = RX_IFG2 = 5 -- */ -- ocelot_port_writel(ocelot_port, DEV_MAC_IFG_CFG_TX_IFG(5), -- DEV_MAC_IFG_CFG); -- -- /* Load seed (0) and set MAC HDX late collision */ -- ocelot_port_writel(ocelot_port, DEV_MAC_HDX_CFG_LATE_COL_POS(67) | -- DEV_MAC_HDX_CFG_SEED_LOAD, -- DEV_MAC_HDX_CFG); -- mdelay(1); -- ocelot_port_writel(ocelot_port, DEV_MAC_HDX_CFG_LATE_COL_POS(67), -- DEV_MAC_HDX_CFG); -- - if (ocelot->ops->pcs_init) - ocelot->ops->pcs_init(ocelot, port); - -- /* Set Max Length and maximum tags allowed */ -- ocelot_port_writel(ocelot_port, VLAN_ETH_FRAME_LEN, -- DEV_MAC_MAXLEN_CFG); -- ocelot_port_writel(ocelot_port, DEV_MAC_TAGS_CFG_TAG_ID(ETH_P_8021AD) | -- DEV_MAC_TAGS_CFG_VLAN_AWR_ENA | -- DEV_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, -- DEV_MAC_TAGS_CFG); -- - /* Enable MAC module */ - ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA | - DEV_MAC_ENA_CFG_TX_ENA, DEV_MAC_ENA_CFG); -@@ -475,22 +452,10 @@ static void ocelot_adjust_link(struct oc - ocelot_port_writel(ocelot_port, DEV_CLOCK_CFG_LINK_SPEED(speed), - DEV_CLOCK_CFG); - -- /* Set SMAC of Pause frame (00:00:00:00:00:00) */ -- ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_HIGH_CFG); -- ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_LOW_CFG); -- - /* No PFC */ - ocelot_write_gix(ocelot, ANA_PFC_PFC_CFG_FC_LINK_SPEED(speed), - ANA_PFC_PFC_CFG, port); - -- /* Set Pause WM hysteresis -- * 152 = 6 * VLAN_ETH_FRAME_LEN / OCELOT_BUFFER_CELL_SZ -- * 101 = 4 * VLAN_ETH_FRAME_LEN / OCELOT_BUFFER_CELL_SZ -- */ -- ocelot_write_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA | -- SYS_PAUSE_CFG_PAUSE_STOP(101) | -- SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, port); -- - /* Core: Enable port for frame transfer */ - ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE | - QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) | -@@ -505,12 +470,6 @@ static void ocelot_adjust_link(struct oc - SYS_MAC_FC_CFG_FC_LINK_SPEED(speed), - SYS_MAC_FC_CFG, port); - ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port); -- -- /* Tail dropping watermark */ -- atop_wm = (ocelot->shared_queue_sz - 9 * VLAN_ETH_FRAME_LEN) / OCELOT_BUFFER_CELL_SZ; -- ocelot_write_rix(ocelot, ocelot_wm_enc(9 * VLAN_ETH_FRAME_LEN), -- SYS_ATOP, port); -- ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG); - } - - static void ocelot_port_adjust_link(struct net_device *dev) -@@ -2140,11 +2099,53 @@ static int ocelot_init_timestamp(struct - static void ocelot_init_port(struct ocelot *ocelot, int port) - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ int atop_wm; - - INIT_LIST_HEAD(&ocelot_port->skbs); - - /* Basic L2 initialization */ - -+ /* Set MAC IFG Gaps -+ * FDX: TX_IFG = 5, RX_IFG1 = RX_IFG2 = 0 -+ * !FDX: TX_IFG = 5, RX_IFG1 = RX_IFG2 = 5 -+ */ -+ ocelot_port_writel(ocelot_port, DEV_MAC_IFG_CFG_TX_IFG(5), -+ DEV_MAC_IFG_CFG); -+ -+ /* Load seed (0) and set MAC HDX late collision */ -+ ocelot_port_writel(ocelot_port, DEV_MAC_HDX_CFG_LATE_COL_POS(67) | -+ DEV_MAC_HDX_CFG_SEED_LOAD, -+ DEV_MAC_HDX_CFG); -+ mdelay(1); -+ ocelot_port_writel(ocelot_port, DEV_MAC_HDX_CFG_LATE_COL_POS(67), -+ DEV_MAC_HDX_CFG); -+ -+ /* Set Max Length and maximum tags allowed */ -+ ocelot_port_writel(ocelot_port, VLAN_ETH_FRAME_LEN, -+ DEV_MAC_MAXLEN_CFG); -+ ocelot_port_writel(ocelot_port, DEV_MAC_TAGS_CFG_TAG_ID(ETH_P_8021AD) | -+ DEV_MAC_TAGS_CFG_VLAN_AWR_ENA | -+ DEV_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, -+ DEV_MAC_TAGS_CFG); -+ -+ /* Set SMAC of Pause frame (00:00:00:00:00:00) */ -+ ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_HIGH_CFG); -+ ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_LOW_CFG); -+ -+ /* Set Pause WM hysteresis -+ * 152 = 6 * VLAN_ETH_FRAME_LEN / OCELOT_BUFFER_CELL_SZ -+ * 101 = 4 * VLAN_ETH_FRAME_LEN / OCELOT_BUFFER_CELL_SZ -+ */ -+ ocelot_write_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA | -+ SYS_PAUSE_CFG_PAUSE_STOP(101) | -+ SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, port); -+ -+ /* Tail dropping watermark */ -+ atop_wm = (ocelot->shared_queue_sz - 9 * VLAN_ETH_FRAME_LEN) / OCELOT_BUFFER_CELL_SZ; -+ ocelot_write_rix(ocelot, ocelot_wm_enc(9 * VLAN_ETH_FRAME_LEN), -+ SYS_ATOP, port); -+ ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG); -+ - /* Drop frames with multicast source address */ - ocelot_rmw_gix(ocelot, ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA, - ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA, diff --git a/target/linux/layerscape/patches-5.4/701-net-0256-net-mscc-ocelot-create-a-helper-for-changing-the-por.patch b/target/linux/layerscape/patches-5.4/701-net-0256-net-mscc-ocelot-create-a-helper-for-changing-the-por.patch deleted file mode 100644 index 13fe784f24..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0256-net-mscc-ocelot-create-a-helper-for-changing-the-por.patch +++ /dev/null @@ -1,87 +0,0 @@ -From e870793b277eeaf3c455971d9610f039fd9ab160 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 14 Nov 2019 17:03:23 +0200 -Subject: [PATCH] net: mscc: ocelot: create a helper for changing the port MTU - -Since in an NPI/DSA setup, not all ports will have the same MTU, we need -to make sure the watermarks for pause frames and/or tail dropping logic -that existed in the driver is still coherent for the new MTU values. - -We need to do this because the NPI (aka external CPU) port needs an -increased MTU for the DSA tag. This will be done in a future patch. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 40 ++++++++++++++++++++++---------------- - 1 file changed, 23 insertions(+), 17 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -2096,11 +2096,32 @@ static int ocelot_init_timestamp(struct - return 0; - } - --static void ocelot_init_port(struct ocelot *ocelot, int port) -+static void ocelot_port_set_mtu(struct ocelot *ocelot, int port, size_t mtu) - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; - int atop_wm; - -+ ocelot_port_writel(ocelot_port, mtu, DEV_MAC_MAXLEN_CFG); -+ -+ /* Set Pause WM hysteresis -+ * 152 = 6 * mtu / OCELOT_BUFFER_CELL_SZ -+ * 101 = 4 * mtu / OCELOT_BUFFER_CELL_SZ -+ */ -+ ocelot_write_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA | -+ SYS_PAUSE_CFG_PAUSE_STOP(101) | -+ SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, port); -+ -+ /* Tail dropping watermark */ -+ atop_wm = (ocelot->shared_queue_sz - 9 * mtu) / OCELOT_BUFFER_CELL_SZ; -+ ocelot_write_rix(ocelot, ocelot_wm_enc(9 * mtu), -+ SYS_ATOP, port); -+ ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG); -+} -+ -+static void ocelot_init_port(struct ocelot *ocelot, int port) -+{ -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ - INIT_LIST_HEAD(&ocelot_port->skbs); - - /* Basic L2 initialization */ -@@ -2121,8 +2142,7 @@ static void ocelot_init_port(struct ocel - DEV_MAC_HDX_CFG); - - /* Set Max Length and maximum tags allowed */ -- ocelot_port_writel(ocelot_port, VLAN_ETH_FRAME_LEN, -- DEV_MAC_MAXLEN_CFG); -+ ocelot_port_set_mtu(ocelot, port, VLAN_ETH_FRAME_LEN); - ocelot_port_writel(ocelot_port, DEV_MAC_TAGS_CFG_TAG_ID(ETH_P_8021AD) | - DEV_MAC_TAGS_CFG_VLAN_AWR_ENA | - DEV_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, -@@ -2132,20 +2152,6 @@ static void ocelot_init_port(struct ocel - ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_HIGH_CFG); - ocelot_port_writel(ocelot_port, 0, DEV_MAC_FC_MAC_LOW_CFG); - -- /* Set Pause WM hysteresis -- * 152 = 6 * VLAN_ETH_FRAME_LEN / OCELOT_BUFFER_CELL_SZ -- * 101 = 4 * VLAN_ETH_FRAME_LEN / OCELOT_BUFFER_CELL_SZ -- */ -- ocelot_write_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA | -- SYS_PAUSE_CFG_PAUSE_STOP(101) | -- SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, port); -- -- /* Tail dropping watermark */ -- atop_wm = (ocelot->shared_queue_sz - 9 * VLAN_ETH_FRAME_LEN) / OCELOT_BUFFER_CELL_SZ; -- ocelot_write_rix(ocelot, ocelot_wm_enc(9 * VLAN_ETH_FRAME_LEN), -- SYS_ATOP, port); -- ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG); -- - /* Drop frames with multicast source address */ - ocelot_rmw_gix(ocelot, ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA, - ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA, diff --git a/target/linux/layerscape/patches-5.4/701-net-0257-net-mscc-ocelot-export-a-constant-for-the-tag-length.patch b/target/linux/layerscape/patches-5.4/701-net-0257-net-mscc-ocelot-export-a-constant-for-the-tag-length.patch deleted file mode 100644 index 9a45bad301..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0257-net-mscc-ocelot-export-a-constant-for-the-tag-length.patch +++ /dev/null @@ -1,73 +0,0 @@ -From f53826ed84b6ce7c588949263cc9dedf3c577aa6 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 14 Nov 2019 17:03:24 +0200 -Subject: [PATCH] net: mscc: ocelot: export a constant for the tag length in - bytes - -This constant will be used in a future patch to increase the MTU on NPI -ports, and will also be used in the tagger driver for Felix. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 4 ++-- - drivers/net/ethernet/mscc/ocelot.h | 4 ++-- - drivers/net/ethernet/mscc/ocelot_board.c | 2 +- - 3 files changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -576,11 +576,11 @@ static int ocelot_port_xmit(struct sk_bu - struct skb_shared_info *shinfo = skb_shinfo(skb); - struct ocelot_port *ocelot_port = &priv->port; - struct ocelot *ocelot = ocelot_port->ocelot; -+ u32 val, ifh[OCELOT_TAG_LEN / 4]; - struct frame_info info = {}; - u8 grp = 0; /* Send everything on CPU group 0 */ - unsigned int i, count, last; - int port = priv->chip_port; -- u32 val, ifh[IFH_LEN]; - - val = ocelot_read(ocelot, QS_INJ_STATUS); - if (!(val & QS_INJ_STATUS_FIFO_RDY(BIT(grp))) || -@@ -603,7 +603,7 @@ static int ocelot_port_xmit(struct sk_bu - - ocelot_gen_ifh(ifh, &info); - -- for (i = 0; i < IFH_LEN; i++) -+ for (i = 0; i < OCELOT_TAG_LEN / 4; i++) - ocelot_write_rix(ocelot, (__force u32)cpu_to_be32(ifh[i]), - QS_INJ_WR, grp); - ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -43,8 +43,6 @@ - - #define OCELOT_PTP_QUEUE_SZ 128 - --#define IFH_LEN 4 -- - struct frame_info { - u32 len; - u16 port; -@@ -66,6 +64,8 @@ struct frame_info { - #define IFH_REW_OP_TWO_STEP_PTP 0x3 - #define IFH_REW_OP_ORIGIN_PTP 0x5 - -+#define OCELOT_TAG_LEN 16 -+ - #define OCELOT_SPEED_2500 0 - #define OCELOT_SPEED_1000 1 - #define OCELOT_SPEED_100 2 ---- a/drivers/net/ethernet/mscc/ocelot_board.c -+++ b/drivers/net/ethernet/mscc/ocelot_board.c -@@ -105,7 +105,7 @@ static irqreturn_t ocelot_xtr_irq_handle - int sz, len, buf_len; - struct sk_buff *skb; - -- for (i = 0; i < IFH_LEN; i++) { -+ for (i = 0; i < OCELOT_TAG_LEN / 4; i++) { - err = ocelot_rx_frame_word(ocelot, grp, true, &ifh[i]); - if (err != 4) - break; diff --git a/target/linux/layerscape/patches-5.4/701-net-0258-net-mscc-ocelot-adjust-MTU-on-the-CPU-port-in-NPI-mo.patch b/target/linux/layerscape/patches-5.4/701-net-0258-net-mscc-ocelot-adjust-MTU-on-the-CPU-port-in-NPI-mo.patch deleted file mode 100644 index 667be87db0..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0258-net-mscc-ocelot-adjust-MTU-on-the-CPU-port-in-NPI-mo.patch +++ /dev/null @@ -1,54 +0,0 @@ -From b2f7c18c351737c2a053c39c09ef50870fd78c06 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 14 Nov 2019 17:03:25 +0200 -Subject: [PATCH] net: mscc: ocelot: adjust MTU on the CPU port in NPI mode - -When using the NPI port, the DSA tag is passed through Ethernet, so the -switch's MAC needs to accept it as it comes from the DSA master. Increase -the MTU on the external CPU port to account for the length of the -injection header. - -Without this patch, MTU-sized frames are dropped by the switch's CPU -port on xmit, which is especially obvious in TCP sessions. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 9 +++++++++ - drivers/net/ethernet/mscc/ocelot.h | 2 ++ - 2 files changed, 11 insertions(+) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -2229,9 +2229,18 @@ void ocelot_set_cpu_port(struct ocelot * - * Only one port can be an NPI at the same time. - */ - if (cpu < ocelot->num_phys_ports) { -+ int mtu = VLAN_ETH_FRAME_LEN + OCELOT_TAG_LEN; -+ - ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M | - QSYS_EXT_CPU_CFG_EXT_CPU_PORT(cpu), - QSYS_EXT_CPU_CFG); -+ -+ if (injection == OCELOT_TAG_PREFIX_SHORT) -+ mtu += OCELOT_SHORT_PREFIX_LEN; -+ else if (injection == OCELOT_TAG_PREFIX_LONG) -+ mtu += OCELOT_LONG_PREFIX_LEN; -+ -+ ocelot_port_set_mtu(ocelot, cpu, mtu); - } - - /* CPU port Injection/Extraction configuration */ ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -65,6 +65,8 @@ struct frame_info { - #define IFH_REW_OP_ORIGIN_PTP 0x5 - - #define OCELOT_TAG_LEN 16 -+#define OCELOT_SHORT_PREFIX_LEN 4 -+#define OCELOT_LONG_PREFIX_LEN 16 - - #define OCELOT_SPEED_2500 0 - #define OCELOT_SPEED_1000 1 diff --git a/target/linux/layerscape/patches-5.4/701-net-0259-net-mscc-ocelot-separate-the-implementation-of-switc.patch b/target/linux/layerscape/patches-5.4/701-net-0259-net-mscc-ocelot-separate-the-implementation-of-switc.patch deleted file mode 100644 index 3a8e9d6b11..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0259-net-mscc-ocelot-separate-the-implementation-of-switc.patch +++ /dev/null @@ -1,109 +0,0 @@ -From c96a1cff5d03a56f380ce761aec9d11fcf61c7f1 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 14 Nov 2019 17:03:26 +0200 -Subject: [PATCH] net: mscc: ocelot: separate the implementation of switch - reset - -The Felix switch has a different reset procedure, so a function pointer -needs to be created and added to the ocelot_ops structure. - -The reset procedure has been moved into ocelot_init. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 8 +++++++ - drivers/net/ethernet/mscc/ocelot.h | 1 + - drivers/net/ethernet/mscc/ocelot_board.c | 37 +++++++++++++++++++++----------- - 3 files changed, 33 insertions(+), 13 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -2268,6 +2268,14 @@ int ocelot_init(struct ocelot *ocelot) - int i, ret; - u32 port; - -+ if (ocelot->ops->reset) { -+ ret = ocelot->ops->reset(ocelot); -+ if (ret) { -+ dev_err(ocelot->dev, "Switch reset failed\n"); -+ return ret; -+ } -+ } -+ - ocelot->lags = devm_kcalloc(ocelot->dev, ocelot->num_phys_ports, - sizeof(u32), GFP_KERNEL); - if (!ocelot->lags) ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -446,6 +446,7 @@ struct ocelot_stat_layout { - - struct ocelot_ops { - void (*pcs_init)(struct ocelot *ocelot, int port); -+ int (*reset)(struct ocelot *ocelot); - }; - - struct ocelot { ---- a/drivers/net/ethernet/mscc/ocelot_board.c -+++ b/drivers/net/ethernet/mscc/ocelot_board.c -@@ -285,8 +285,32 @@ static void ocelot_port_pcs_init(struct - ocelot_port_writel(ocelot_port, 0, PCS1G_LB_CFG); - } - -+static int ocelot_reset(struct ocelot *ocelot) -+{ -+ int retries = 100; -+ u32 val; -+ -+ regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1); -+ regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1); -+ -+ do { -+ msleep(1); -+ regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], -+ &val); -+ } while (val && --retries); -+ -+ if (!retries) -+ return -ETIMEDOUT; -+ -+ regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1); -+ regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1); -+ -+ return 0; -+} -+ - static const struct ocelot_ops ocelot_ops = { - .pcs_init = ocelot_port_pcs_init, -+ .reset = ocelot_reset, - }; - - static int mscc_ocelot_probe(struct platform_device *pdev) -@@ -297,7 +321,6 @@ static int mscc_ocelot_probe(struct plat - struct ocelot *ocelot; - struct regmap *hsio; - unsigned int i; -- u32 val; - - struct { - enum ocelot_target id; -@@ -377,18 +400,6 @@ static int mscc_ocelot_probe(struct plat - ocelot->ptp = 1; - } - -- regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1); -- regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1); -- -- do { -- msleep(1); -- regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], -- &val); -- } while (val); -- -- regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1); -- regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1); -- - ocelot->num_cpu_ports = 1; /* 1 port on the switch, two groups */ - - ports = of_get_child_by_name(np, "ethernet-ports"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0260-net-mscc-ocelot-publish-structure-definitions-to-inc.patch b/target/linux/layerscape/patches-5.4/701-net-0260-net-mscc-ocelot-publish-structure-definitions-to-inc.patch deleted file mode 100644 index 8529e9825c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0260-net-mscc-ocelot-publish-structure-definitions-to-inc.patch +++ /dev/null @@ -1,1414 +0,0 @@ -From 417b5a156ca8ab4c986c9deacf58309ce4e09410 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 14 Nov 2019 17:03:27 +0200 -Subject: [PATCH] net: mscc: ocelot: publish structure definitions to - include/soc/mscc/ocelot.h - -We will be registering another switch driver based on ocelot, which -lives under drivers/net/dsa. - -Make sure the Felix DSA front-end has the necessary abstractions to -implement a new Ocelot driver instantiation. This includes the function -prototypes for implementing DSA callbacks. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 78 +++--- - drivers/net/ethernet/mscc/ocelot.h | 482 +-------------------------------- - include/soc/mscc/ocelot.h | 539 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 588 insertions(+), 511 deletions(-) - create mode 100644 include/soc/mscc/ocelot.h - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -21,7 +21,6 @@ - #include - #include - #include --#include - - #include "ocelot.h" - #include "ocelot_ace.h" -@@ -184,8 +183,8 @@ static void ocelot_vlan_mode(struct ocel - ocelot_write(ocelot, val, ANA_VLANMASK); - } - --static void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, -- bool vlan_aware) -+void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, -+ bool vlan_aware) - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; - u32 val; -@@ -230,6 +229,7 @@ static void ocelot_port_vlan_filtering(s - REW_TAG_CFG_TAG_CFG_M, - REW_TAG_CFG, port); - } -+EXPORT_SYMBOL(ocelot_port_vlan_filtering); - - static int ocelot_port_set_native_vlan(struct ocelot *ocelot, int port, - u16 vid) -@@ -267,8 +267,8 @@ static void ocelot_port_set_pvid(struct - ocelot_port->pvid = pvid; - } - --static int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, -- bool untagged) -+int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, -+ bool untagged) - { - int ret; - -@@ -291,6 +291,7 @@ static int ocelot_vlan_add(struct ocelot - - return 0; - } -+EXPORT_SYMBOL(ocelot_vlan_add); - - static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid, - bool untagged) -@@ -312,7 +313,7 @@ static int ocelot_vlan_vid_add(struct ne - return 0; - } - --static int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid) -+int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid) - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; - int ret; -@@ -333,6 +334,7 @@ static int ocelot_vlan_del(struct ocelot - - return 0; - } -+EXPORT_SYMBOL(ocelot_vlan_del); - - static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid) - { -@@ -404,8 +406,8 @@ static u16 ocelot_wm_enc(u16 value) - return value; - } - --static void ocelot_adjust_link(struct ocelot *ocelot, int port, -- struct phy_device *phydev) -+void ocelot_adjust_link(struct ocelot *ocelot, int port, -+ struct phy_device *phydev) - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; - int speed, mode = 0; -@@ -471,6 +473,7 @@ static void ocelot_adjust_link(struct oc - SYS_MAC_FC_CFG, port); - ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port); - } -+EXPORT_SYMBOL(ocelot_adjust_link); - - static void ocelot_port_adjust_link(struct net_device *dev) - { -@@ -481,8 +484,8 @@ static void ocelot_port_adjust_link(stru - ocelot_adjust_link(ocelot, port, dev->phydev); - } - --static void ocelot_port_enable(struct ocelot *ocelot, int port, -- struct phy_device *phy) -+void ocelot_port_enable(struct ocelot *ocelot, int port, -+ struct phy_device *phy) - { - /* Enable receiving frames on the port, and activate auto-learning of - * MAC addresses. -@@ -492,6 +495,7 @@ static void ocelot_port_enable(struct oc - ANA_PORT_PORT_CFG_PORTID_VAL(port), - ANA_PORT_PORT_CFG, port); - } -+EXPORT_SYMBOL(ocelot_port_enable); - - static int ocelot_port_open(struct net_device *dev) - { -@@ -526,7 +530,7 @@ static int ocelot_port_open(struct net_d - return 0; - } - --static void ocelot_port_disable(struct ocelot *ocelot, int port) -+void ocelot_port_disable(struct ocelot *ocelot, int port) - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; - -@@ -534,6 +538,7 @@ static void ocelot_port_disable(struct o - ocelot_rmw_rix(ocelot, 0, QSYS_SWITCH_PORT_MODE_PORT_ENA, - QSYS_SWITCH_PORT_MODE, port); - } -+EXPORT_SYMBOL(ocelot_port_disable); - - static int ocelot_port_stop(struct net_device *dev) - { -@@ -790,9 +795,8 @@ static void ocelot_get_stats64(struct ne - stats->collisions = ocelot_read(ocelot, SYS_COUNT_TX_COLLISION); - } - --static int ocelot_fdb_add(struct ocelot *ocelot, int port, -- const unsigned char *addr, u16 vid, -- bool vlan_aware) -+int ocelot_fdb_add(struct ocelot *ocelot, int port, -+ const unsigned char *addr, u16 vid, bool vlan_aware) - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; - -@@ -812,6 +816,7 @@ static int ocelot_fdb_add(struct ocelot - - return ocelot_mact_learn(ocelot, port, addr, vid, ENTRYTYPE_LOCKED); - } -+EXPORT_SYMBOL(ocelot_fdb_add); - - static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, -@@ -826,11 +831,12 @@ static int ocelot_port_fdb_add(struct nd - return ocelot_fdb_add(ocelot, port, addr, vid, priv->vlan_aware); - } - --static int ocelot_fdb_del(struct ocelot *ocelot, int port, -- const unsigned char *addr, u16 vid) -+int ocelot_fdb_del(struct ocelot *ocelot, int port, -+ const unsigned char *addr, u16 vid) - { - return ocelot_mact_forget(ocelot, addr, vid); - } -+EXPORT_SYMBOL(ocelot_fdb_del); - - static int ocelot_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], - struct net_device *dev, -@@ -940,8 +946,8 @@ static int ocelot_mact_read(struct ocelo - return 0; - } - --static int ocelot_fdb_dump(struct ocelot *ocelot, int port, -- dsa_fdb_dump_cb_t *cb, void *data) -+int ocelot_fdb_dump(struct ocelot *ocelot, int port, -+ dsa_fdb_dump_cb_t *cb, void *data) - { - int i, j; - -@@ -973,6 +979,7 @@ static int ocelot_fdb_dump(struct ocelot - - return 0; - } -+EXPORT_SYMBOL(ocelot_fdb_dump); - - static int ocelot_port_fdb_dump(struct sk_buff *skb, - struct netlink_callback *cb, -@@ -1147,8 +1154,7 @@ static const struct net_device_ops ocelo - .ndo_do_ioctl = ocelot_ioctl, - }; - --static void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, -- u8 *data) -+void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data) - { - int i; - -@@ -1159,6 +1165,7 @@ static void ocelot_get_strings(struct oc - memcpy(data + i * ETH_GSTRING_LEN, ocelot->stats_layout[i].name, - ETH_GSTRING_LEN); - } -+EXPORT_SYMBOL(ocelot_get_strings); - - static void ocelot_port_get_strings(struct net_device *netdev, u32 sset, - u8 *data) -@@ -1210,7 +1217,7 @@ static void ocelot_check_stats_work(stru - OCELOT_STATS_CHECK_DELAY); - } - --static void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data) -+void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data) - { - int i; - -@@ -1221,6 +1228,7 @@ static void ocelot_get_ethtool_stats(str - for (i = 0; i < ocelot->num_stats; i++) - *data++ = ocelot->stats[port * ocelot->num_stats + i]; - } -+EXPORT_SYMBOL(ocelot_get_ethtool_stats); - - static void ocelot_port_get_ethtool_stats(struct net_device *dev, - struct ethtool_stats *stats, -@@ -1233,13 +1241,14 @@ static void ocelot_port_get_ethtool_stat - ocelot_get_ethtool_stats(ocelot, port, data); - } - --static int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset) -+int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset) - { - if (sset != ETH_SS_STATS) - return -EOPNOTSUPP; - - return ocelot->num_stats; - } -+EXPORT_SYMBOL(ocelot_get_sset_count); - - static int ocelot_port_get_sset_count(struct net_device *dev, int sset) - { -@@ -1250,8 +1259,8 @@ static int ocelot_port_get_sset_count(st - return ocelot_get_sset_count(ocelot, port, sset); - } - --static int ocelot_get_ts_info(struct ocelot *ocelot, int port, -- struct ethtool_ts_info *info) -+int ocelot_get_ts_info(struct ocelot *ocelot, int port, -+ struct ethtool_ts_info *info) - { - info->phc_index = ocelot->ptp_clock ? - ptp_clock_index(ocelot->ptp_clock) : -1; -@@ -1270,6 +1279,7 @@ static int ocelot_get_ts_info(struct oce - - return 0; - } -+EXPORT_SYMBOL(ocelot_get_ts_info); - - static int ocelot_port_get_ts_info(struct net_device *dev, - struct ethtool_ts_info *info) -@@ -1293,8 +1303,7 @@ static const struct ethtool_ops ocelot_e - .get_ts_info = ocelot_port_get_ts_info, - }; - --static void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, -- u8 state) -+void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state) - { - u32 port_cfg; - int p, i; -@@ -1355,6 +1364,7 @@ static void ocelot_bridge_stp_state_set( - } - } - } -+EXPORT_SYMBOL(ocelot_bridge_stp_state_set); - - static void ocelot_port_attr_stp_state_set(struct ocelot *ocelot, int port, - struct switchdev_trans *trans, -@@ -1366,11 +1376,12 @@ static void ocelot_port_attr_stp_state_s - ocelot_bridge_stp_state_set(ocelot, port, state); - } - --static void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs) -+void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs) - { - ocelot_write(ocelot, ANA_AUTOAGE_AGE_PERIOD(msecs / 2), - ANA_AUTOAGE); - } -+EXPORT_SYMBOL(ocelot_set_ageing_time); - - static void ocelot_port_attr_ageing_set(struct ocelot *ocelot, int port, - unsigned long ageing_clock_t) -@@ -1601,8 +1612,8 @@ static int ocelot_port_obj_del(struct ne - return ret; - } - --static int ocelot_port_bridge_join(struct ocelot *ocelot, int port, -- struct net_device *bridge) -+int ocelot_port_bridge_join(struct ocelot *ocelot, int port, -+ struct net_device *bridge) - { - if (!ocelot->bridge_mask) { - ocelot->hw_bridge_dev = bridge; -@@ -1617,9 +1628,10 @@ static int ocelot_port_bridge_join(struc - - return 0; - } -+EXPORT_SYMBOL(ocelot_port_bridge_join); - --static int ocelot_port_bridge_leave(struct ocelot *ocelot, int port, -- struct net_device *bridge) -+int ocelot_port_bridge_leave(struct ocelot *ocelot, int port, -+ struct net_device *bridge) - { - ocelot->bridge_mask &= ~BIT(port); - -@@ -1630,6 +1642,7 @@ static int ocelot_port_bridge_leave(stru - ocelot_port_set_pvid(ocelot, port, 0); - return ocelot_port_set_native_vlan(ocelot, port, 0); - } -+EXPORT_SYMBOL(ocelot_port_bridge_leave); - - static void ocelot_set_aggr_pgids(struct ocelot *ocelot) - { -@@ -2118,7 +2131,7 @@ static void ocelot_port_set_mtu(struct o - ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG); - } - --static void ocelot_init_port(struct ocelot *ocelot, int port) -+void ocelot_init_port(struct ocelot *ocelot, int port) - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; - -@@ -2165,6 +2178,7 @@ static void ocelot_init_port(struct ocel - /* Enable vcap lookups */ - ocelot_vcap_enable(ocelot, port); - } -+EXPORT_SYMBOL(ocelot_init_port); - - int ocelot_probe_port(struct ocelot *ocelot, u8 port, - void __iomem *regs, ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -18,6 +18,7 @@ - #include - #include - -+#include - #include "ocelot_ana.h" - #include "ocelot_dev.h" - #include "ocelot_qsys.h" -@@ -52,376 +53,6 @@ struct frame_info { - u32 timestamp; /* rew_val */ - }; - --#define IFH_INJ_BYPASS BIT(31) --#define IFH_INJ_POP_CNT_DISABLE (3 << 28) -- --#define IFH_TAG_TYPE_C 0 --#define IFH_TAG_TYPE_S 1 -- --#define IFH_REW_OP_NOOP 0x0 --#define IFH_REW_OP_DSCP 0x1 --#define IFH_REW_OP_ONE_STEP_PTP 0x2 --#define IFH_REW_OP_TWO_STEP_PTP 0x3 --#define IFH_REW_OP_ORIGIN_PTP 0x5 -- --#define OCELOT_TAG_LEN 16 --#define OCELOT_SHORT_PREFIX_LEN 4 --#define OCELOT_LONG_PREFIX_LEN 16 -- --#define OCELOT_SPEED_2500 0 --#define OCELOT_SPEED_1000 1 --#define OCELOT_SPEED_100 2 --#define OCELOT_SPEED_10 3 -- --#define TARGET_OFFSET 24 --#define REG_MASK GENMASK(TARGET_OFFSET - 1, 0) --#define REG(reg, offset) [reg & REG_MASK] = offset -- --enum ocelot_target { -- ANA = 1, -- QS, -- QSYS, -- REW, -- SYS, -- S2, -- HSIO, -- PTP, -- TARGET_MAX, --}; -- --enum ocelot_reg { -- ANA_ADVLEARN = ANA << TARGET_OFFSET, -- ANA_VLANMASK, -- ANA_PORT_B_DOMAIN, -- ANA_ANAGEFIL, -- ANA_ANEVENTS, -- ANA_STORMLIMIT_BURST, -- ANA_STORMLIMIT_CFG, -- ANA_ISOLATED_PORTS, -- ANA_COMMUNITY_PORTS, -- ANA_AUTOAGE, -- ANA_MACTOPTIONS, -- ANA_LEARNDISC, -- ANA_AGENCTRL, -- ANA_MIRRORPORTS, -- ANA_EMIRRORPORTS, -- ANA_FLOODING, -- ANA_FLOODING_IPMC, -- ANA_SFLOW_CFG, -- ANA_PORT_MODE, -- ANA_CUT_THRU_CFG, -- ANA_PGID_PGID, -- ANA_TABLES_ANMOVED, -- ANA_TABLES_MACHDATA, -- ANA_TABLES_MACLDATA, -- ANA_TABLES_STREAMDATA, -- ANA_TABLES_MACACCESS, -- ANA_TABLES_MACTINDX, -- ANA_TABLES_VLANACCESS, -- ANA_TABLES_VLANTIDX, -- ANA_TABLES_ISDXACCESS, -- ANA_TABLES_ISDXTIDX, -- ANA_TABLES_ENTRYLIM, -- ANA_TABLES_PTP_ID_HIGH, -- ANA_TABLES_PTP_ID_LOW, -- ANA_TABLES_STREAMACCESS, -- ANA_TABLES_STREAMTIDX, -- ANA_TABLES_SEQ_HISTORY, -- ANA_TABLES_SEQ_MASK, -- ANA_TABLES_SFID_MASK, -- ANA_TABLES_SFIDACCESS, -- ANA_TABLES_SFIDTIDX, -- ANA_MSTI_STATE, -- ANA_OAM_UPM_LM_CNT, -- ANA_SG_ACCESS_CTRL, -- ANA_SG_CONFIG_REG_1, -- ANA_SG_CONFIG_REG_2, -- ANA_SG_CONFIG_REG_3, -- ANA_SG_CONFIG_REG_4, -- ANA_SG_CONFIG_REG_5, -- ANA_SG_GCL_GS_CONFIG, -- ANA_SG_GCL_TI_CONFIG, -- ANA_SG_STATUS_REG_1, -- ANA_SG_STATUS_REG_2, -- ANA_SG_STATUS_REG_3, -- ANA_PORT_VLAN_CFG, -- ANA_PORT_DROP_CFG, -- ANA_PORT_QOS_CFG, -- ANA_PORT_VCAP_CFG, -- ANA_PORT_VCAP_S1_KEY_CFG, -- ANA_PORT_VCAP_S2_CFG, -- ANA_PORT_PCP_DEI_MAP, -- ANA_PORT_CPU_FWD_CFG, -- ANA_PORT_CPU_FWD_BPDU_CFG, -- ANA_PORT_CPU_FWD_GARP_CFG, -- ANA_PORT_CPU_FWD_CCM_CFG, -- ANA_PORT_PORT_CFG, -- ANA_PORT_POL_CFG, -- ANA_PORT_PTP_CFG, -- ANA_PORT_PTP_DLY1_CFG, -- ANA_PORT_PTP_DLY2_CFG, -- ANA_PORT_SFID_CFG, -- ANA_PFC_PFC_CFG, -- ANA_PFC_PFC_TIMER, -- ANA_IPT_OAM_MEP_CFG, -- ANA_IPT_IPT, -- ANA_PPT_PPT, -- ANA_FID_MAP_FID_MAP, -- ANA_AGGR_CFG, -- ANA_CPUQ_CFG, -- ANA_CPUQ_CFG2, -- ANA_CPUQ_8021_CFG, -- ANA_DSCP_CFG, -- ANA_DSCP_REWR_CFG, -- ANA_VCAP_RNG_TYPE_CFG, -- ANA_VCAP_RNG_VAL_CFG, -- ANA_VRAP_CFG, -- ANA_VRAP_HDR_DATA, -- ANA_VRAP_HDR_MASK, -- ANA_DISCARD_CFG, -- ANA_FID_CFG, -- ANA_POL_PIR_CFG, -- ANA_POL_CIR_CFG, -- ANA_POL_MODE_CFG, -- ANA_POL_PIR_STATE, -- ANA_POL_CIR_STATE, -- ANA_POL_STATE, -- ANA_POL_FLOWC, -- ANA_POL_HYST, -- ANA_POL_MISC_CFG, -- QS_XTR_GRP_CFG = QS << TARGET_OFFSET, -- QS_XTR_RD, -- QS_XTR_FRM_PRUNING, -- QS_XTR_FLUSH, -- QS_XTR_DATA_PRESENT, -- QS_XTR_CFG, -- QS_INJ_GRP_CFG, -- QS_INJ_WR, -- QS_INJ_CTRL, -- QS_INJ_STATUS, -- QS_INJ_ERR, -- QS_INH_DBG, -- QSYS_PORT_MODE = QSYS << TARGET_OFFSET, -- QSYS_SWITCH_PORT_MODE, -- QSYS_STAT_CNT_CFG, -- QSYS_EEE_CFG, -- QSYS_EEE_THRES, -- QSYS_IGR_NO_SHARING, -- QSYS_EGR_NO_SHARING, -- QSYS_SW_STATUS, -- QSYS_EXT_CPU_CFG, -- QSYS_PAD_CFG, -- QSYS_CPU_GROUP_MAP, -- QSYS_QMAP, -- QSYS_ISDX_SGRP, -- QSYS_TIMED_FRAME_ENTRY, -- QSYS_TFRM_MISC, -- QSYS_TFRM_PORT_DLY, -- QSYS_TFRM_TIMER_CFG_1, -- QSYS_TFRM_TIMER_CFG_2, -- QSYS_TFRM_TIMER_CFG_3, -- QSYS_TFRM_TIMER_CFG_4, -- QSYS_TFRM_TIMER_CFG_5, -- QSYS_TFRM_TIMER_CFG_6, -- QSYS_TFRM_TIMER_CFG_7, -- QSYS_TFRM_TIMER_CFG_8, -- QSYS_RED_PROFILE, -- QSYS_RES_QOS_MODE, -- QSYS_RES_CFG, -- QSYS_RES_STAT, -- QSYS_EGR_DROP_MODE, -- QSYS_EQ_CTRL, -- QSYS_EVENTS_CORE, -- QSYS_QMAXSDU_CFG_0, -- QSYS_QMAXSDU_CFG_1, -- QSYS_QMAXSDU_CFG_2, -- QSYS_QMAXSDU_CFG_3, -- QSYS_QMAXSDU_CFG_4, -- QSYS_QMAXSDU_CFG_5, -- QSYS_QMAXSDU_CFG_6, -- QSYS_QMAXSDU_CFG_7, -- QSYS_PREEMPTION_CFG, -- QSYS_CIR_CFG, -- QSYS_EIR_CFG, -- QSYS_SE_CFG, -- QSYS_SE_DWRR_CFG, -- QSYS_SE_CONNECT, -- QSYS_SE_DLB_SENSE, -- QSYS_CIR_STATE, -- QSYS_EIR_STATE, -- QSYS_SE_STATE, -- QSYS_HSCH_MISC_CFG, -- QSYS_TAG_CONFIG, -- QSYS_TAS_PARAM_CFG_CTRL, -- QSYS_PORT_MAX_SDU, -- QSYS_PARAM_CFG_REG_1, -- QSYS_PARAM_CFG_REG_2, -- QSYS_PARAM_CFG_REG_3, -- QSYS_PARAM_CFG_REG_4, -- QSYS_PARAM_CFG_REG_5, -- QSYS_GCL_CFG_REG_1, -- QSYS_GCL_CFG_REG_2, -- QSYS_PARAM_STATUS_REG_1, -- QSYS_PARAM_STATUS_REG_2, -- QSYS_PARAM_STATUS_REG_3, -- QSYS_PARAM_STATUS_REG_4, -- QSYS_PARAM_STATUS_REG_5, -- QSYS_PARAM_STATUS_REG_6, -- QSYS_PARAM_STATUS_REG_7, -- QSYS_PARAM_STATUS_REG_8, -- QSYS_PARAM_STATUS_REG_9, -- QSYS_GCL_STATUS_REG_1, -- QSYS_GCL_STATUS_REG_2, -- REW_PORT_VLAN_CFG = REW << TARGET_OFFSET, -- REW_TAG_CFG, -- REW_PORT_CFG, -- REW_DSCP_CFG, -- REW_PCP_DEI_QOS_MAP_CFG, -- REW_PTP_CFG, -- REW_PTP_DLY1_CFG, -- REW_RED_TAG_CFG, -- REW_DSCP_REMAP_DP1_CFG, -- REW_DSCP_REMAP_CFG, -- REW_STAT_CFG, -- REW_REW_STICKY, -- REW_PPT, -- SYS_COUNT_RX_OCTETS = SYS << TARGET_OFFSET, -- SYS_COUNT_RX_UNICAST, -- SYS_COUNT_RX_MULTICAST, -- SYS_COUNT_RX_BROADCAST, -- SYS_COUNT_RX_SHORTS, -- SYS_COUNT_RX_FRAGMENTS, -- SYS_COUNT_RX_JABBERS, -- SYS_COUNT_RX_CRC_ALIGN_ERRS, -- SYS_COUNT_RX_SYM_ERRS, -- SYS_COUNT_RX_64, -- SYS_COUNT_RX_65_127, -- SYS_COUNT_RX_128_255, -- SYS_COUNT_RX_256_1023, -- SYS_COUNT_RX_1024_1526, -- SYS_COUNT_RX_1527_MAX, -- SYS_COUNT_RX_PAUSE, -- SYS_COUNT_RX_CONTROL, -- SYS_COUNT_RX_LONGS, -- SYS_COUNT_RX_CLASSIFIED_DROPS, -- SYS_COUNT_TX_OCTETS, -- SYS_COUNT_TX_UNICAST, -- SYS_COUNT_TX_MULTICAST, -- SYS_COUNT_TX_BROADCAST, -- SYS_COUNT_TX_COLLISION, -- SYS_COUNT_TX_DROPS, -- SYS_COUNT_TX_PAUSE, -- SYS_COUNT_TX_64, -- SYS_COUNT_TX_65_127, -- SYS_COUNT_TX_128_511, -- SYS_COUNT_TX_512_1023, -- SYS_COUNT_TX_1024_1526, -- SYS_COUNT_TX_1527_MAX, -- SYS_COUNT_TX_AGING, -- SYS_RESET_CFG, -- SYS_SR_ETYPE_CFG, -- SYS_VLAN_ETYPE_CFG, -- SYS_PORT_MODE, -- SYS_FRONT_PORT_MODE, -- SYS_FRM_AGING, -- SYS_STAT_CFG, -- SYS_SW_STATUS, -- SYS_MISC_CFG, -- SYS_REW_MAC_HIGH_CFG, -- SYS_REW_MAC_LOW_CFG, -- SYS_TIMESTAMP_OFFSET, -- SYS_CMID, -- SYS_PAUSE_CFG, -- SYS_PAUSE_TOT_CFG, -- SYS_ATOP, -- SYS_ATOP_TOT_CFG, -- SYS_MAC_FC_CFG, -- SYS_MMGT, -- SYS_MMGT_FAST, -- SYS_EVENTS_DIF, -- SYS_EVENTS_CORE, -- SYS_CNT, -- SYS_PTP_STATUS, -- SYS_PTP_TXSTAMP, -- SYS_PTP_NXT, -- SYS_PTP_CFG, -- SYS_RAM_INIT, -- SYS_CM_ADDR, -- SYS_CM_DATA_WR, -- SYS_CM_DATA_RD, -- SYS_CM_OP, -- SYS_CM_DATA, -- S2_CORE_UPDATE_CTRL = S2 << TARGET_OFFSET, -- S2_CORE_MV_CFG, -- S2_CACHE_ENTRY_DAT, -- S2_CACHE_MASK_DAT, -- S2_CACHE_ACTION_DAT, -- S2_CACHE_CNT_DAT, -- S2_CACHE_TG_DAT, -- PTP_PIN_CFG = PTP << TARGET_OFFSET, -- PTP_PIN_TOD_SEC_MSB, -- PTP_PIN_TOD_SEC_LSB, -- PTP_PIN_TOD_NSEC, -- PTP_CFG_MISC, -- PTP_CLK_CFG_ADJ_CFG, -- PTP_CLK_CFG_ADJ_FREQ, --}; -- --enum ocelot_regfield { -- ANA_ADVLEARN_VLAN_CHK, -- ANA_ADVLEARN_LEARN_MIRROR, -- ANA_ANEVENTS_FLOOD_DISCARD, -- ANA_ANEVENTS_MSTI_DROP, -- ANA_ANEVENTS_ACLKILL, -- ANA_ANEVENTS_ACLUSED, -- ANA_ANEVENTS_AUTOAGE, -- ANA_ANEVENTS_VS2TTL1, -- ANA_ANEVENTS_STORM_DROP, -- ANA_ANEVENTS_LEARN_DROP, -- ANA_ANEVENTS_AGED_ENTRY, -- ANA_ANEVENTS_CPU_LEARN_FAILED, -- ANA_ANEVENTS_AUTO_LEARN_FAILED, -- ANA_ANEVENTS_LEARN_REMOVE, -- ANA_ANEVENTS_AUTO_LEARNED, -- ANA_ANEVENTS_AUTO_MOVED, -- ANA_ANEVENTS_DROPPED, -- ANA_ANEVENTS_CLASSIFIED_DROP, -- ANA_ANEVENTS_CLASSIFIED_COPY, -- ANA_ANEVENTS_VLAN_DISCARD, -- ANA_ANEVENTS_FWD_DISCARD, -- ANA_ANEVENTS_MULTICAST_FLOOD, -- ANA_ANEVENTS_UNICAST_FLOOD, -- ANA_ANEVENTS_DEST_KNOWN, -- ANA_ANEVENTS_BUCKET3_MATCH, -- ANA_ANEVENTS_BUCKET2_MATCH, -- ANA_ANEVENTS_BUCKET1_MATCH, -- ANA_ANEVENTS_BUCKET0_MATCH, -- ANA_ANEVENTS_CPU_OPERATION, -- ANA_ANEVENTS_DMAC_LOOKUP, -- ANA_ANEVENTS_SMAC_LOOKUP, -- ANA_ANEVENTS_SEQ_GEN_ERR_0, -- ANA_ANEVENTS_SEQ_GEN_ERR_1, -- ANA_TABLES_MACACCESS_B_DOM, -- ANA_TABLES_MACTINDX_BUCKET, -- ANA_TABLES_MACTINDX_M_INDEX, -- QSYS_TIMED_FRAME_ENTRY_TFRM_VLD, -- QSYS_TIMED_FRAME_ENTRY_TFRM_FP, -- QSYS_TIMED_FRAME_ENTRY_TFRM_PORTNO, -- QSYS_TIMED_FRAME_ENTRY_TFRM_TM_SEL, -- QSYS_TIMED_FRAME_ENTRY_TFRM_TM_T, -- SYS_RESET_CFG_CORE_ENA, -- SYS_RESET_CFG_MEM_ENA, -- SYS_RESET_CFG_MEM_INIT, -- REGFIELD_MAX --}; -- --enum ocelot_clk_pins { -- ALT_PPS_PIN = 1, -- EXT_CLK_PIN, -- ALT_LDST_PIN, -- TOD_ACC_PIN --}; -- - struct ocelot_multicast { - struct list_head list; - unsigned char addr[ETH_ALEN]; -@@ -429,88 +60,6 @@ struct ocelot_multicast { - u16 ports; - }; - --enum ocelot_tag_prefix { -- OCELOT_TAG_PREFIX_DISABLED = 0, -- OCELOT_TAG_PREFIX_NONE, -- OCELOT_TAG_PREFIX_SHORT, -- OCELOT_TAG_PREFIX_LONG, --}; -- --struct ocelot_port; --struct ocelot; -- --struct ocelot_stat_layout { -- u32 offset; -- char name[ETH_GSTRING_LEN]; --}; -- --struct ocelot_ops { -- void (*pcs_init)(struct ocelot *ocelot, int port); -- int (*reset)(struct ocelot *ocelot); --}; -- --struct ocelot { -- const struct ocelot_ops *ops; -- struct device *dev; -- -- struct regmap *targets[TARGET_MAX]; -- struct regmap_field *regfields[REGFIELD_MAX]; -- const u32 *const *map; -- const struct ocelot_stat_layout *stats_layout; -- unsigned int num_stats; -- -- u8 base_mac[ETH_ALEN]; -- -- struct net_device *hw_bridge_dev; -- u16 bridge_mask; -- u16 bridge_fwd_mask; -- -- struct workqueue_struct *ocelot_owq; -- -- int shared_queue_sz; -- -- u8 num_phys_ports; -- u8 num_cpu_ports; -- u8 cpu; -- struct ocelot_port **ports; -- -- u32 *lags; -- -- /* Keep track of the vlan port masks */ -- u32 vlan_mask[VLAN_N_VID]; -- -- struct list_head multicast; -- -- /* Workqueue to check statistics for overflow with its lock */ -- struct mutex stats_lock; -- u64 *stats; -- struct delayed_work stats_work; -- struct workqueue_struct *stats_queue; -- -- u8 ptp:1; -- struct ptp_clock *ptp_clock; -- struct ptp_clock_info ptp_info; -- struct hwtstamp_config hwtstamp_config; -- struct mutex ptp_lock; /* Protects the PTP interface state */ -- spinlock_t ptp_clock_lock; /* Protects the PTP clock */ --}; -- --struct ocelot_port { -- struct ocelot *ocelot; -- -- void __iomem *regs; -- -- /* Ingress default VLAN (pvid) */ -- u16 pvid; -- -- /* Egress default VLAN (vid) */ -- u16 vid; -- -- u8 ptp_cmd; -- struct list_head skbs; -- u8 ts_id; --}; -- - struct ocelot_port_private { - struct ocelot_port port; - struct net_device *dev; -@@ -531,37 +80,12 @@ struct ocelot_skb { - u8 id; - }; - --u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset); --#define ocelot_read_ix(ocelot, reg, gi, ri) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) --#define ocelot_read_gix(ocelot, reg, gi) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi)) --#define ocelot_read_rix(ocelot, reg, ri) __ocelot_read_ix(ocelot, reg, reg##_RSZ * (ri)) --#define ocelot_read(ocelot, reg) __ocelot_read_ix(ocelot, reg, 0) -- --void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset); --#define ocelot_write_ix(ocelot, val, reg, gi, ri) __ocelot_write_ix(ocelot, val, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) --#define ocelot_write_gix(ocelot, val, reg, gi) __ocelot_write_ix(ocelot, val, reg, reg##_GSZ * (gi)) --#define ocelot_write_rix(ocelot, val, reg, ri) __ocelot_write_ix(ocelot, val, reg, reg##_RSZ * (ri)) --#define ocelot_write(ocelot, val, reg) __ocelot_write_ix(ocelot, val, reg, 0) -- --void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg, -- u32 offset); --#define ocelot_rmw_ix(ocelot, val, m, reg, gi, ri) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) --#define ocelot_rmw_gix(ocelot, val, m, reg, gi) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_GSZ * (gi)) --#define ocelot_rmw_rix(ocelot, val, m, reg, ri) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_RSZ * (ri)) --#define ocelot_rmw(ocelot, val, m, reg) __ocelot_rmw_ix(ocelot, val, m, reg, 0) -- - u32 ocelot_port_readl(struct ocelot_port *port, u32 reg); - void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg); - --int ocelot_regfields_init(struct ocelot *ocelot, -- const struct reg_field *const regfields); --struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res); -- - #define ocelot_field_write(ocelot, reg, val) regmap_field_write((ocelot)->regfields[(reg)], (val)) - #define ocelot_field_read(ocelot, reg, val) regmap_field_read((ocelot)->regfields[(reg)], (val)) - --int ocelot_init(struct ocelot *ocelot); --void ocelot_deinit(struct ocelot *ocelot); - int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops); - int ocelot_probe_port(struct ocelot *ocelot, u8 port, - void __iomem *regs, -@@ -575,7 +99,7 @@ extern struct notifier_block ocelot_netd - extern struct notifier_block ocelot_switchdev_nb; - extern struct notifier_block ocelot_switchdev_blocking_nb; - --int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts); --void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts); -+#define ocelot_field_write(ocelot, reg, val) regmap_field_write((ocelot)->regfields[(reg)], (val)) -+#define ocelot_field_read(ocelot, reg, val) regmap_field_read((ocelot)->regfields[(reg)], (val)) - - #endif ---- /dev/null -+++ b/include/soc/mscc/ocelot.h -@@ -0,0 +1,539 @@ -+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ -+/* Copyright (c) 2017 Microsemi Corporation -+ */ -+ -+#ifndef _SOC_MSCC_OCELOT_H -+#define _SOC_MSCC_OCELOT_H -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define IFH_INJ_BYPASS BIT(31) -+#define IFH_INJ_POP_CNT_DISABLE (3 << 28) -+ -+#define IFH_TAG_TYPE_C 0 -+#define IFH_TAG_TYPE_S 1 -+ -+#define IFH_REW_OP_NOOP 0x0 -+#define IFH_REW_OP_DSCP 0x1 -+#define IFH_REW_OP_ONE_STEP_PTP 0x2 -+#define IFH_REW_OP_TWO_STEP_PTP 0x3 -+#define IFH_REW_OP_ORIGIN_PTP 0x5 -+ -+#define OCELOT_TAG_LEN 16 -+#define OCELOT_SHORT_PREFIX_LEN 4 -+#define OCELOT_LONG_PREFIX_LEN 16 -+ -+#define OCELOT_SPEED_2500 0 -+#define OCELOT_SPEED_1000 1 -+#define OCELOT_SPEED_100 2 -+#define OCELOT_SPEED_10 3 -+ -+#define TARGET_OFFSET 24 -+#define REG_MASK GENMASK(TARGET_OFFSET - 1, 0) -+#define REG(reg, offset) [reg & REG_MASK] = offset -+ -+#define REG_RESERVED_ADDR 0xffffffff -+#define REG_RESERVED(reg) REG(reg, REG_RESERVED_ADDR) -+ -+enum ocelot_target { -+ ANA = 1, -+ QS, -+ QSYS, -+ REW, -+ SYS, -+ S2, -+ HSIO, -+ PTP, -+ GCB, -+ TARGET_MAX, -+}; -+ -+enum ocelot_reg { -+ ANA_ADVLEARN = ANA << TARGET_OFFSET, -+ ANA_VLANMASK, -+ ANA_PORT_B_DOMAIN, -+ ANA_ANAGEFIL, -+ ANA_ANEVENTS, -+ ANA_STORMLIMIT_BURST, -+ ANA_STORMLIMIT_CFG, -+ ANA_ISOLATED_PORTS, -+ ANA_COMMUNITY_PORTS, -+ ANA_AUTOAGE, -+ ANA_MACTOPTIONS, -+ ANA_LEARNDISC, -+ ANA_AGENCTRL, -+ ANA_MIRRORPORTS, -+ ANA_EMIRRORPORTS, -+ ANA_FLOODING, -+ ANA_FLOODING_IPMC, -+ ANA_SFLOW_CFG, -+ ANA_PORT_MODE, -+ ANA_CUT_THRU_CFG, -+ ANA_PGID_PGID, -+ ANA_TABLES_ANMOVED, -+ ANA_TABLES_MACHDATA, -+ ANA_TABLES_MACLDATA, -+ ANA_TABLES_STREAMDATA, -+ ANA_TABLES_MACACCESS, -+ ANA_TABLES_MACTINDX, -+ ANA_TABLES_VLANACCESS, -+ ANA_TABLES_VLANTIDX, -+ ANA_TABLES_ISDXACCESS, -+ ANA_TABLES_ISDXTIDX, -+ ANA_TABLES_ENTRYLIM, -+ ANA_TABLES_PTP_ID_HIGH, -+ ANA_TABLES_PTP_ID_LOW, -+ ANA_TABLES_STREAMACCESS, -+ ANA_TABLES_STREAMTIDX, -+ ANA_TABLES_SEQ_HISTORY, -+ ANA_TABLES_SEQ_MASK, -+ ANA_TABLES_SFID_MASK, -+ ANA_TABLES_SFIDACCESS, -+ ANA_TABLES_SFIDTIDX, -+ ANA_MSTI_STATE, -+ ANA_OAM_UPM_LM_CNT, -+ ANA_SG_ACCESS_CTRL, -+ ANA_SG_CONFIG_REG_1, -+ ANA_SG_CONFIG_REG_2, -+ ANA_SG_CONFIG_REG_3, -+ ANA_SG_CONFIG_REG_4, -+ ANA_SG_CONFIG_REG_5, -+ ANA_SG_GCL_GS_CONFIG, -+ ANA_SG_GCL_TI_CONFIG, -+ ANA_SG_STATUS_REG_1, -+ ANA_SG_STATUS_REG_2, -+ ANA_SG_STATUS_REG_3, -+ ANA_PORT_VLAN_CFG, -+ ANA_PORT_DROP_CFG, -+ ANA_PORT_QOS_CFG, -+ ANA_PORT_VCAP_CFG, -+ ANA_PORT_VCAP_S1_KEY_CFG, -+ ANA_PORT_VCAP_S2_CFG, -+ ANA_PORT_PCP_DEI_MAP, -+ ANA_PORT_CPU_FWD_CFG, -+ ANA_PORT_CPU_FWD_BPDU_CFG, -+ ANA_PORT_CPU_FWD_GARP_CFG, -+ ANA_PORT_CPU_FWD_CCM_CFG, -+ ANA_PORT_PORT_CFG, -+ ANA_PORT_POL_CFG, -+ ANA_PORT_PTP_CFG, -+ ANA_PORT_PTP_DLY1_CFG, -+ ANA_PORT_PTP_DLY2_CFG, -+ ANA_PORT_SFID_CFG, -+ ANA_PFC_PFC_CFG, -+ ANA_PFC_PFC_TIMER, -+ ANA_IPT_OAM_MEP_CFG, -+ ANA_IPT_IPT, -+ ANA_PPT_PPT, -+ ANA_FID_MAP_FID_MAP, -+ ANA_AGGR_CFG, -+ ANA_CPUQ_CFG, -+ ANA_CPUQ_CFG2, -+ ANA_CPUQ_8021_CFG, -+ ANA_DSCP_CFG, -+ ANA_DSCP_REWR_CFG, -+ ANA_VCAP_RNG_TYPE_CFG, -+ ANA_VCAP_RNG_VAL_CFG, -+ ANA_VRAP_CFG, -+ ANA_VRAP_HDR_DATA, -+ ANA_VRAP_HDR_MASK, -+ ANA_DISCARD_CFG, -+ ANA_FID_CFG, -+ ANA_POL_PIR_CFG, -+ ANA_POL_CIR_CFG, -+ ANA_POL_MODE_CFG, -+ ANA_POL_PIR_STATE, -+ ANA_POL_CIR_STATE, -+ ANA_POL_STATE, -+ ANA_POL_FLOWC, -+ ANA_POL_HYST, -+ ANA_POL_MISC_CFG, -+ QS_XTR_GRP_CFG = QS << TARGET_OFFSET, -+ QS_XTR_RD, -+ QS_XTR_FRM_PRUNING, -+ QS_XTR_FLUSH, -+ QS_XTR_DATA_PRESENT, -+ QS_XTR_CFG, -+ QS_INJ_GRP_CFG, -+ QS_INJ_WR, -+ QS_INJ_CTRL, -+ QS_INJ_STATUS, -+ QS_INJ_ERR, -+ QS_INH_DBG, -+ QSYS_PORT_MODE = QSYS << TARGET_OFFSET, -+ QSYS_SWITCH_PORT_MODE, -+ QSYS_STAT_CNT_CFG, -+ QSYS_EEE_CFG, -+ QSYS_EEE_THRES, -+ QSYS_IGR_NO_SHARING, -+ QSYS_EGR_NO_SHARING, -+ QSYS_SW_STATUS, -+ QSYS_EXT_CPU_CFG, -+ QSYS_PAD_CFG, -+ QSYS_CPU_GROUP_MAP, -+ QSYS_QMAP, -+ QSYS_ISDX_SGRP, -+ QSYS_TIMED_FRAME_ENTRY, -+ QSYS_TFRM_MISC, -+ QSYS_TFRM_PORT_DLY, -+ QSYS_TFRM_TIMER_CFG_1, -+ QSYS_TFRM_TIMER_CFG_2, -+ QSYS_TFRM_TIMER_CFG_3, -+ QSYS_TFRM_TIMER_CFG_4, -+ QSYS_TFRM_TIMER_CFG_5, -+ QSYS_TFRM_TIMER_CFG_6, -+ QSYS_TFRM_TIMER_CFG_7, -+ QSYS_TFRM_TIMER_CFG_8, -+ QSYS_RED_PROFILE, -+ QSYS_RES_QOS_MODE, -+ QSYS_RES_CFG, -+ QSYS_RES_STAT, -+ QSYS_EGR_DROP_MODE, -+ QSYS_EQ_CTRL, -+ QSYS_EVENTS_CORE, -+ QSYS_QMAXSDU_CFG_0, -+ QSYS_QMAXSDU_CFG_1, -+ QSYS_QMAXSDU_CFG_2, -+ QSYS_QMAXSDU_CFG_3, -+ QSYS_QMAXSDU_CFG_4, -+ QSYS_QMAXSDU_CFG_5, -+ QSYS_QMAXSDU_CFG_6, -+ QSYS_QMAXSDU_CFG_7, -+ QSYS_PREEMPTION_CFG, -+ QSYS_CIR_CFG, -+ QSYS_EIR_CFG, -+ QSYS_SE_CFG, -+ QSYS_SE_DWRR_CFG, -+ QSYS_SE_CONNECT, -+ QSYS_SE_DLB_SENSE, -+ QSYS_CIR_STATE, -+ QSYS_EIR_STATE, -+ QSYS_SE_STATE, -+ QSYS_HSCH_MISC_CFG, -+ QSYS_TAG_CONFIG, -+ QSYS_TAS_PARAM_CFG_CTRL, -+ QSYS_PORT_MAX_SDU, -+ QSYS_PARAM_CFG_REG_1, -+ QSYS_PARAM_CFG_REG_2, -+ QSYS_PARAM_CFG_REG_3, -+ QSYS_PARAM_CFG_REG_4, -+ QSYS_PARAM_CFG_REG_5, -+ QSYS_GCL_CFG_REG_1, -+ QSYS_GCL_CFG_REG_2, -+ QSYS_PARAM_STATUS_REG_1, -+ QSYS_PARAM_STATUS_REG_2, -+ QSYS_PARAM_STATUS_REG_3, -+ QSYS_PARAM_STATUS_REG_4, -+ QSYS_PARAM_STATUS_REG_5, -+ QSYS_PARAM_STATUS_REG_6, -+ QSYS_PARAM_STATUS_REG_7, -+ QSYS_PARAM_STATUS_REG_8, -+ QSYS_PARAM_STATUS_REG_9, -+ QSYS_GCL_STATUS_REG_1, -+ QSYS_GCL_STATUS_REG_2, -+ REW_PORT_VLAN_CFG = REW << TARGET_OFFSET, -+ REW_TAG_CFG, -+ REW_PORT_CFG, -+ REW_DSCP_CFG, -+ REW_PCP_DEI_QOS_MAP_CFG, -+ REW_PTP_CFG, -+ REW_PTP_DLY1_CFG, -+ REW_RED_TAG_CFG, -+ REW_DSCP_REMAP_DP1_CFG, -+ REW_DSCP_REMAP_CFG, -+ REW_STAT_CFG, -+ REW_REW_STICKY, -+ REW_PPT, -+ SYS_COUNT_RX_OCTETS = SYS << TARGET_OFFSET, -+ SYS_COUNT_RX_UNICAST, -+ SYS_COUNT_RX_MULTICAST, -+ SYS_COUNT_RX_BROADCAST, -+ SYS_COUNT_RX_SHORTS, -+ SYS_COUNT_RX_FRAGMENTS, -+ SYS_COUNT_RX_JABBERS, -+ SYS_COUNT_RX_CRC_ALIGN_ERRS, -+ SYS_COUNT_RX_SYM_ERRS, -+ SYS_COUNT_RX_64, -+ SYS_COUNT_RX_65_127, -+ SYS_COUNT_RX_128_255, -+ SYS_COUNT_RX_256_1023, -+ SYS_COUNT_RX_1024_1526, -+ SYS_COUNT_RX_1527_MAX, -+ SYS_COUNT_RX_PAUSE, -+ SYS_COUNT_RX_CONTROL, -+ SYS_COUNT_RX_LONGS, -+ SYS_COUNT_RX_CLASSIFIED_DROPS, -+ SYS_COUNT_TX_OCTETS, -+ SYS_COUNT_TX_UNICAST, -+ SYS_COUNT_TX_MULTICAST, -+ SYS_COUNT_TX_BROADCAST, -+ SYS_COUNT_TX_COLLISION, -+ SYS_COUNT_TX_DROPS, -+ SYS_COUNT_TX_PAUSE, -+ SYS_COUNT_TX_64, -+ SYS_COUNT_TX_65_127, -+ SYS_COUNT_TX_128_511, -+ SYS_COUNT_TX_512_1023, -+ SYS_COUNT_TX_1024_1526, -+ SYS_COUNT_TX_1527_MAX, -+ SYS_COUNT_TX_AGING, -+ SYS_RESET_CFG, -+ SYS_SR_ETYPE_CFG, -+ SYS_VLAN_ETYPE_CFG, -+ SYS_PORT_MODE, -+ SYS_FRONT_PORT_MODE, -+ SYS_FRM_AGING, -+ SYS_STAT_CFG, -+ SYS_SW_STATUS, -+ SYS_MISC_CFG, -+ SYS_REW_MAC_HIGH_CFG, -+ SYS_REW_MAC_LOW_CFG, -+ SYS_TIMESTAMP_OFFSET, -+ SYS_CMID, -+ SYS_PAUSE_CFG, -+ SYS_PAUSE_TOT_CFG, -+ SYS_ATOP, -+ SYS_ATOP_TOT_CFG, -+ SYS_MAC_FC_CFG, -+ SYS_MMGT, -+ SYS_MMGT_FAST, -+ SYS_EVENTS_DIF, -+ SYS_EVENTS_CORE, -+ SYS_CNT, -+ SYS_PTP_STATUS, -+ SYS_PTP_TXSTAMP, -+ SYS_PTP_NXT, -+ SYS_PTP_CFG, -+ SYS_RAM_INIT, -+ SYS_CM_ADDR, -+ SYS_CM_DATA_WR, -+ SYS_CM_DATA_RD, -+ SYS_CM_OP, -+ SYS_CM_DATA, -+ S2_CORE_UPDATE_CTRL = S2 << TARGET_OFFSET, -+ S2_CORE_MV_CFG, -+ S2_CACHE_ENTRY_DAT, -+ S2_CACHE_MASK_DAT, -+ S2_CACHE_ACTION_DAT, -+ S2_CACHE_CNT_DAT, -+ S2_CACHE_TG_DAT, -+ PTP_PIN_CFG = PTP << TARGET_OFFSET, -+ PTP_PIN_TOD_SEC_MSB, -+ PTP_PIN_TOD_SEC_LSB, -+ PTP_PIN_TOD_NSEC, -+ PTP_CFG_MISC, -+ PTP_CLK_CFG_ADJ_CFG, -+ PTP_CLK_CFG_ADJ_FREQ, -+ GCB_SOFT_RST = GCB << TARGET_OFFSET, -+}; -+ -+enum ocelot_regfield { -+ ANA_ADVLEARN_VLAN_CHK, -+ ANA_ADVLEARN_LEARN_MIRROR, -+ ANA_ANEVENTS_FLOOD_DISCARD, -+ ANA_ANEVENTS_MSTI_DROP, -+ ANA_ANEVENTS_ACLKILL, -+ ANA_ANEVENTS_ACLUSED, -+ ANA_ANEVENTS_AUTOAGE, -+ ANA_ANEVENTS_VS2TTL1, -+ ANA_ANEVENTS_STORM_DROP, -+ ANA_ANEVENTS_LEARN_DROP, -+ ANA_ANEVENTS_AGED_ENTRY, -+ ANA_ANEVENTS_CPU_LEARN_FAILED, -+ ANA_ANEVENTS_AUTO_LEARN_FAILED, -+ ANA_ANEVENTS_LEARN_REMOVE, -+ ANA_ANEVENTS_AUTO_LEARNED, -+ ANA_ANEVENTS_AUTO_MOVED, -+ ANA_ANEVENTS_DROPPED, -+ ANA_ANEVENTS_CLASSIFIED_DROP, -+ ANA_ANEVENTS_CLASSIFIED_COPY, -+ ANA_ANEVENTS_VLAN_DISCARD, -+ ANA_ANEVENTS_FWD_DISCARD, -+ ANA_ANEVENTS_MULTICAST_FLOOD, -+ ANA_ANEVENTS_UNICAST_FLOOD, -+ ANA_ANEVENTS_DEST_KNOWN, -+ ANA_ANEVENTS_BUCKET3_MATCH, -+ ANA_ANEVENTS_BUCKET2_MATCH, -+ ANA_ANEVENTS_BUCKET1_MATCH, -+ ANA_ANEVENTS_BUCKET0_MATCH, -+ ANA_ANEVENTS_CPU_OPERATION, -+ ANA_ANEVENTS_DMAC_LOOKUP, -+ ANA_ANEVENTS_SMAC_LOOKUP, -+ ANA_ANEVENTS_SEQ_GEN_ERR_0, -+ ANA_ANEVENTS_SEQ_GEN_ERR_1, -+ ANA_TABLES_MACACCESS_B_DOM, -+ ANA_TABLES_MACTINDX_BUCKET, -+ ANA_TABLES_MACTINDX_M_INDEX, -+ QSYS_TIMED_FRAME_ENTRY_TFRM_VLD, -+ QSYS_TIMED_FRAME_ENTRY_TFRM_FP, -+ QSYS_TIMED_FRAME_ENTRY_TFRM_PORTNO, -+ QSYS_TIMED_FRAME_ENTRY_TFRM_TM_SEL, -+ QSYS_TIMED_FRAME_ENTRY_TFRM_TM_T, -+ SYS_RESET_CFG_CORE_ENA, -+ SYS_RESET_CFG_MEM_ENA, -+ SYS_RESET_CFG_MEM_INIT, -+ GCB_SOFT_RST_SWC_RST, -+ REGFIELD_MAX -+}; -+ -+enum ocelot_clk_pins { -+ ALT_PPS_PIN = 1, -+ EXT_CLK_PIN, -+ ALT_LDST_PIN, -+ TOD_ACC_PIN -+}; -+ -+struct ocelot_stat_layout { -+ u32 offset; -+ char name[ETH_GSTRING_LEN]; -+}; -+ -+enum ocelot_tag_prefix { -+ OCELOT_TAG_PREFIX_DISABLED = 0, -+ OCELOT_TAG_PREFIX_NONE, -+ OCELOT_TAG_PREFIX_SHORT, -+ OCELOT_TAG_PREFIX_LONG, -+}; -+ -+struct ocelot; -+ -+struct ocelot_ops { -+ void (*pcs_init)(struct ocelot *ocelot, int port); -+ int (*reset)(struct ocelot *ocelot); -+}; -+ -+struct ocelot_port { -+ struct ocelot *ocelot; -+ -+ void __iomem *regs; -+ -+ /* Ingress default VLAN (pvid) */ -+ u16 pvid; -+ -+ /* Egress default VLAN (vid) */ -+ u16 vid; -+ -+ u8 ptp_cmd; -+ struct list_head skbs; -+ u8 ts_id; -+}; -+ -+struct ocelot { -+ struct device *dev; -+ -+ const struct ocelot_ops *ops; -+ struct regmap *targets[TARGET_MAX]; -+ struct regmap_field *regfields[REGFIELD_MAX]; -+ const u32 *const *map; -+ const struct ocelot_stat_layout *stats_layout; -+ unsigned int num_stats; -+ -+ int shared_queue_sz; -+ -+ struct net_device *hw_bridge_dev; -+ u16 bridge_mask; -+ u16 bridge_fwd_mask; -+ -+ struct ocelot_port **ports; -+ -+ u8 base_mac[ETH_ALEN]; -+ -+ /* Keep track of the vlan port masks */ -+ u32 vlan_mask[VLAN_N_VID]; -+ -+ u8 num_phys_ports; -+ u8 num_cpu_ports; -+ u8 cpu; -+ -+ u32 *lags; -+ -+ struct list_head multicast; -+ -+ /* Workqueue to check statistics for overflow with its lock */ -+ struct mutex stats_lock; -+ u64 *stats; -+ struct delayed_work stats_work; -+ struct workqueue_struct *stats_queue; -+ -+ u8 ptp:1; -+ struct ptp_clock *ptp_clock; -+ struct ptp_clock_info ptp_info; -+ struct hwtstamp_config hwtstamp_config; -+ /* Protects the PTP interface state */ -+ struct mutex ptp_lock; -+ /* Protects the PTP clock */ -+ spinlock_t ptp_clock_lock; -+ -+ void (*port_pcs_init)(struct ocelot_port *port); -+}; -+ -+#define ocelot_read_ix(ocelot, reg, gi, ri) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) -+#define ocelot_read_gix(ocelot, reg, gi) __ocelot_read_ix(ocelot, reg, reg##_GSZ * (gi)) -+#define ocelot_read_rix(ocelot, reg, ri) __ocelot_read_ix(ocelot, reg, reg##_RSZ * (ri)) -+#define ocelot_read(ocelot, reg) __ocelot_read_ix(ocelot, reg, 0) -+ -+#define ocelot_write_ix(ocelot, val, reg, gi, ri) __ocelot_write_ix(ocelot, val, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) -+#define ocelot_write_gix(ocelot, val, reg, gi) __ocelot_write_ix(ocelot, val, reg, reg##_GSZ * (gi)) -+#define ocelot_write_rix(ocelot, val, reg, ri) __ocelot_write_ix(ocelot, val, reg, reg##_RSZ * (ri)) -+#define ocelot_write(ocelot, val, reg) __ocelot_write_ix(ocelot, val, reg, 0) -+ -+#define ocelot_rmw_ix(ocelot, val, m, reg, gi, ri) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) -+#define ocelot_rmw_gix(ocelot, val, m, reg, gi) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_GSZ * (gi)) -+#define ocelot_rmw_rix(ocelot, val, m, reg, ri) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_RSZ * (ri)) -+#define ocelot_rmw(ocelot, val, m, reg) __ocelot_rmw_ix(ocelot, val, m, reg, 0) -+ -+/* I/O */ -+u32 ocelot_port_readl(struct ocelot_port *port, u32 reg); -+void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg); -+u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset); -+void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset); -+void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg, -+ u32 offset); -+ -+/* Hardware initialization */ -+int ocelot_regfields_init(struct ocelot *ocelot, -+ const struct reg_field *const regfields); -+struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res); -+void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu, -+ enum ocelot_tag_prefix injection, -+ enum ocelot_tag_prefix extraction); -+int ocelot_init(struct ocelot *ocelot); -+void ocelot_deinit(struct ocelot *ocelot); -+void ocelot_init_port(struct ocelot *ocelot, int port); -+ -+/* DSA callbacks */ -+void ocelot_port_enable(struct ocelot *ocelot, int port, -+ struct phy_device *phy); -+void ocelot_port_disable(struct ocelot *ocelot, int port); -+void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data); -+void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data); -+int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset); -+int ocelot_get_ts_info(struct ocelot *ocelot, int port, -+ struct ethtool_ts_info *info); -+void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs); -+void ocelot_adjust_link(struct ocelot *ocelot, int port, -+ struct phy_device *phydev); -+void ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, -+ bool vlan_aware); -+void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state); -+int ocelot_port_bridge_join(struct ocelot *ocelot, int port, -+ struct net_device *bridge); -+int ocelot_port_bridge_leave(struct ocelot *ocelot, int port, -+ struct net_device *bridge); -+int ocelot_fdb_dump(struct ocelot *ocelot, int port, -+ dsa_fdb_dump_cb_t *cb, void *data); -+int ocelot_fdb_add(struct ocelot *ocelot, int port, -+ const unsigned char *addr, u16 vid, bool vlan_aware); -+int ocelot_fdb_del(struct ocelot *ocelot, int port, -+ const unsigned char *addr, u16 vid); -+int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, -+ bool untagged); -+int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid); -+int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts); -+void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts); -+ -+#endif diff --git a/target/linux/layerscape/patches-5.4/701-net-0261-net-mscc-ocelot-publish-ocelot_sys.h-to-include-soc-.patch b/target/linux/layerscape/patches-5.4/701-net-0261-net-mscc-ocelot-publish-ocelot_sys.h-to-include-soc-.patch deleted file mode 100644 index f65ae631dc..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0261-net-mscc-ocelot-publish-ocelot_sys.h-to-include-soc-.patch +++ /dev/null @@ -1,344 +0,0 @@ -From 53069d6527fc1d2709d559206cdbf0d7357954b7 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 14 Nov 2019 17:03:28 +0200 -Subject: [PATCH] net: mscc: ocelot: publish ocelot_sys.h to include/soc/mscc - -The Felix DSA driver needs to write to SYS_RAM_INIT_RAM_INIT for its own -chip initialization process. - -Also update the MAINTAINERS file such that the headers exported by the -ocelot driver are under the same maintainers' umbrella as the driver -itself. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - MAINTAINERS | 1 + - drivers/net/ethernet/mscc/ocelot.h | 2 +- - drivers/net/ethernet/mscc/ocelot_sys.h | 144 --------------------------------- - include/soc/mscc/ocelot_sys.h | 144 +++++++++++++++++++++++++++++++++ - 4 files changed, 146 insertions(+), 145 deletions(-) - delete mode 100644 drivers/net/ethernet/mscc/ocelot_sys.h - create mode 100644 include/soc/mscc/ocelot_sys.h - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -10826,6 +10826,7 @@ M: Microchip Linux Driver Support ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -18,12 +18,12 @@ - #include - #include - -+#include - #include - #include "ocelot_ana.h" - #include "ocelot_dev.h" - #include "ocelot_qsys.h" - #include "ocelot_rew.h" --#include "ocelot_sys.h" - #include "ocelot_qs.h" - #include "ocelot_tc.h" - #include "ocelot_ptp.h" ---- a/drivers/net/ethernet/mscc/ocelot_sys.h -+++ /dev/null -@@ -1,144 +0,0 @@ --/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ --/* -- * Microsemi Ocelot Switch driver -- * -- * Copyright (c) 2017 Microsemi Corporation -- */ -- --#ifndef _MSCC_OCELOT_SYS_H_ --#define _MSCC_OCELOT_SYS_H_ -- --#define SYS_COUNT_RX_OCTETS_RSZ 0x4 -- --#define SYS_COUNT_TX_OCTETS_RSZ 0x4 -- --#define SYS_PORT_MODE_RSZ 0x4 -- --#define SYS_PORT_MODE_DATA_WO_TS(x) (((x) << 5) & GENMASK(6, 5)) --#define SYS_PORT_MODE_DATA_WO_TS_M GENMASK(6, 5) --#define SYS_PORT_MODE_DATA_WO_TS_X(x) (((x) & GENMASK(6, 5)) >> 5) --#define SYS_PORT_MODE_INCL_INJ_HDR(x) (((x) << 3) & GENMASK(4, 3)) --#define SYS_PORT_MODE_INCL_INJ_HDR_M GENMASK(4, 3) --#define SYS_PORT_MODE_INCL_INJ_HDR_X(x) (((x) & GENMASK(4, 3)) >> 3) --#define SYS_PORT_MODE_INCL_XTR_HDR(x) (((x) << 1) & GENMASK(2, 1)) --#define SYS_PORT_MODE_INCL_XTR_HDR_M GENMASK(2, 1) --#define SYS_PORT_MODE_INCL_XTR_HDR_X(x) (((x) & GENMASK(2, 1)) >> 1) --#define SYS_PORT_MODE_INJ_HDR_ERR BIT(0) -- --#define SYS_FRONT_PORT_MODE_RSZ 0x4 -- --#define SYS_FRONT_PORT_MODE_HDX_MODE BIT(0) -- --#define SYS_FRM_AGING_AGE_TX_ENA BIT(20) --#define SYS_FRM_AGING_MAX_AGE(x) ((x) & GENMASK(19, 0)) --#define SYS_FRM_AGING_MAX_AGE_M GENMASK(19, 0) -- --#define SYS_STAT_CFG_STAT_CLEAR_SHOT(x) (((x) << 10) & GENMASK(16, 10)) --#define SYS_STAT_CFG_STAT_CLEAR_SHOT_M GENMASK(16, 10) --#define SYS_STAT_CFG_STAT_CLEAR_SHOT_X(x) (((x) & GENMASK(16, 10)) >> 10) --#define SYS_STAT_CFG_STAT_VIEW(x) ((x) & GENMASK(9, 0)) --#define SYS_STAT_CFG_STAT_VIEW_M GENMASK(9, 0) -- --#define SYS_SW_STATUS_RSZ 0x4 -- --#define SYS_SW_STATUS_PORT_RX_PAUSED BIT(0) -- --#define SYS_MISC_CFG_PTP_RSRV_CLR BIT(1) --#define SYS_MISC_CFG_PTP_DIS_NEG_RO BIT(0) -- --#define SYS_REW_MAC_HIGH_CFG_RSZ 0x4 -- --#define SYS_REW_MAC_LOW_CFG_RSZ 0x4 -- --#define SYS_TIMESTAMP_OFFSET_ETH_TYPE_CFG(x) (((x) << 6) & GENMASK(21, 6)) --#define SYS_TIMESTAMP_OFFSET_ETH_TYPE_CFG_M GENMASK(21, 6) --#define SYS_TIMESTAMP_OFFSET_ETH_TYPE_CFG_X(x) (((x) & GENMASK(21, 6)) >> 6) --#define SYS_TIMESTAMP_OFFSET_TIMESTAMP_OFFSET(x) ((x) & GENMASK(5, 0)) --#define SYS_TIMESTAMP_OFFSET_TIMESTAMP_OFFSET_M GENMASK(5, 0) -- --#define SYS_PAUSE_CFG_RSZ 0x4 -- --#define SYS_PAUSE_CFG_PAUSE_START(x) (((x) << 10) & GENMASK(18, 10)) --#define SYS_PAUSE_CFG_PAUSE_START_M GENMASK(18, 10) --#define SYS_PAUSE_CFG_PAUSE_START_X(x) (((x) & GENMASK(18, 10)) >> 10) --#define SYS_PAUSE_CFG_PAUSE_STOP(x) (((x) << 1) & GENMASK(9, 1)) --#define SYS_PAUSE_CFG_PAUSE_STOP_M GENMASK(9, 1) --#define SYS_PAUSE_CFG_PAUSE_STOP_X(x) (((x) & GENMASK(9, 1)) >> 1) --#define SYS_PAUSE_CFG_PAUSE_ENA BIT(0) -- --#define SYS_PAUSE_TOT_CFG_PAUSE_TOT_START(x) (((x) << 9) & GENMASK(17, 9)) --#define SYS_PAUSE_TOT_CFG_PAUSE_TOT_START_M GENMASK(17, 9) --#define SYS_PAUSE_TOT_CFG_PAUSE_TOT_START_X(x) (((x) & GENMASK(17, 9)) >> 9) --#define SYS_PAUSE_TOT_CFG_PAUSE_TOT_STOP(x) ((x) & GENMASK(8, 0)) --#define SYS_PAUSE_TOT_CFG_PAUSE_TOT_STOP_M GENMASK(8, 0) -- --#define SYS_ATOP_RSZ 0x4 -- --#define SYS_MAC_FC_CFG_RSZ 0x4 -- --#define SYS_MAC_FC_CFG_FC_LINK_SPEED(x) (((x) << 26) & GENMASK(27, 26)) --#define SYS_MAC_FC_CFG_FC_LINK_SPEED_M GENMASK(27, 26) --#define SYS_MAC_FC_CFG_FC_LINK_SPEED_X(x) (((x) & GENMASK(27, 26)) >> 26) --#define SYS_MAC_FC_CFG_FC_LATENCY_CFG(x) (((x) << 20) & GENMASK(25, 20)) --#define SYS_MAC_FC_CFG_FC_LATENCY_CFG_M GENMASK(25, 20) --#define SYS_MAC_FC_CFG_FC_LATENCY_CFG_X(x) (((x) & GENMASK(25, 20)) >> 20) --#define SYS_MAC_FC_CFG_ZERO_PAUSE_ENA BIT(18) --#define SYS_MAC_FC_CFG_TX_FC_ENA BIT(17) --#define SYS_MAC_FC_CFG_RX_FC_ENA BIT(16) --#define SYS_MAC_FC_CFG_PAUSE_VAL_CFG(x) ((x) & GENMASK(15, 0)) --#define SYS_MAC_FC_CFG_PAUSE_VAL_CFG_M GENMASK(15, 0) -- --#define SYS_MMGT_RELCNT(x) (((x) << 16) & GENMASK(31, 16)) --#define SYS_MMGT_RELCNT_M GENMASK(31, 16) --#define SYS_MMGT_RELCNT_X(x) (((x) & GENMASK(31, 16)) >> 16) --#define SYS_MMGT_FREECNT(x) ((x) & GENMASK(15, 0)) --#define SYS_MMGT_FREECNT_M GENMASK(15, 0) -- --#define SYS_MMGT_FAST_FREEVLD(x) (((x) << 4) & GENMASK(7, 4)) --#define SYS_MMGT_FAST_FREEVLD_M GENMASK(7, 4) --#define SYS_MMGT_FAST_FREEVLD_X(x) (((x) & GENMASK(7, 4)) >> 4) --#define SYS_MMGT_FAST_RELVLD(x) ((x) & GENMASK(3, 0)) --#define SYS_MMGT_FAST_RELVLD_M GENMASK(3, 0) -- --#define SYS_EVENTS_DIF_RSZ 0x4 -- --#define SYS_EVENTS_DIF_EV_DRX(x) (((x) << 6) & GENMASK(8, 6)) --#define SYS_EVENTS_DIF_EV_DRX_M GENMASK(8, 6) --#define SYS_EVENTS_DIF_EV_DRX_X(x) (((x) & GENMASK(8, 6)) >> 6) --#define SYS_EVENTS_DIF_EV_DTX(x) ((x) & GENMASK(5, 0)) --#define SYS_EVENTS_DIF_EV_DTX_M GENMASK(5, 0) -- --#define SYS_EVENTS_CORE_EV_FWR BIT(2) --#define SYS_EVENTS_CORE_EV_ANA(x) ((x) & GENMASK(1, 0)) --#define SYS_EVENTS_CORE_EV_ANA_M GENMASK(1, 0) -- --#define SYS_CNT_GSZ 0x4 -- --#define SYS_PTP_STATUS_PTP_TXSTAMP_OAM BIT(29) --#define SYS_PTP_STATUS_PTP_OVFL BIT(28) --#define SYS_PTP_STATUS_PTP_MESS_VLD BIT(27) --#define SYS_PTP_STATUS_PTP_MESS_ID(x) (((x) << 21) & GENMASK(26, 21)) --#define SYS_PTP_STATUS_PTP_MESS_ID_M GENMASK(26, 21) --#define SYS_PTP_STATUS_PTP_MESS_ID_X(x) (((x) & GENMASK(26, 21)) >> 21) --#define SYS_PTP_STATUS_PTP_MESS_TXPORT(x) (((x) << 16) & GENMASK(20, 16)) --#define SYS_PTP_STATUS_PTP_MESS_TXPORT_M GENMASK(20, 16) --#define SYS_PTP_STATUS_PTP_MESS_TXPORT_X(x) (((x) & GENMASK(20, 16)) >> 16) --#define SYS_PTP_STATUS_PTP_MESS_SEQ_ID(x) ((x) & GENMASK(15, 0)) --#define SYS_PTP_STATUS_PTP_MESS_SEQ_ID_M GENMASK(15, 0) -- --#define SYS_PTP_TXSTAMP_PTP_TXSTAMP(x) ((x) & GENMASK(29, 0)) --#define SYS_PTP_TXSTAMP_PTP_TXSTAMP_M GENMASK(29, 0) --#define SYS_PTP_TXSTAMP_PTP_TXSTAMP_SEC BIT(31) -- --#define SYS_PTP_NXT_PTP_NXT BIT(0) -- --#define SYS_PTP_CFG_PTP_STAMP_WID(x) (((x) << 2) & GENMASK(7, 2)) --#define SYS_PTP_CFG_PTP_STAMP_WID_M GENMASK(7, 2) --#define SYS_PTP_CFG_PTP_STAMP_WID_X(x) (((x) & GENMASK(7, 2)) >> 2) --#define SYS_PTP_CFG_PTP_CF_ROLL_MODE(x) ((x) & GENMASK(1, 0)) --#define SYS_PTP_CFG_PTP_CF_ROLL_MODE_M GENMASK(1, 0) -- --#define SYS_RAM_INIT_RAM_INIT BIT(1) --#define SYS_RAM_INIT_RAM_CFG_HOOK BIT(0) -- --#endif ---- /dev/null -+++ b/include/soc/mscc/ocelot_sys.h -@@ -0,0 +1,144 @@ -+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ -+/* -+ * Microsemi Ocelot Switch driver -+ * -+ * Copyright (c) 2017 Microsemi Corporation -+ */ -+ -+#ifndef _MSCC_OCELOT_SYS_H_ -+#define _MSCC_OCELOT_SYS_H_ -+ -+#define SYS_COUNT_RX_OCTETS_RSZ 0x4 -+ -+#define SYS_COUNT_TX_OCTETS_RSZ 0x4 -+ -+#define SYS_PORT_MODE_RSZ 0x4 -+ -+#define SYS_PORT_MODE_DATA_WO_TS(x) (((x) << 5) & GENMASK(6, 5)) -+#define SYS_PORT_MODE_DATA_WO_TS_M GENMASK(6, 5) -+#define SYS_PORT_MODE_DATA_WO_TS_X(x) (((x) & GENMASK(6, 5)) >> 5) -+#define SYS_PORT_MODE_INCL_INJ_HDR(x) (((x) << 3) & GENMASK(4, 3)) -+#define SYS_PORT_MODE_INCL_INJ_HDR_M GENMASK(4, 3) -+#define SYS_PORT_MODE_INCL_INJ_HDR_X(x) (((x) & GENMASK(4, 3)) >> 3) -+#define SYS_PORT_MODE_INCL_XTR_HDR(x) (((x) << 1) & GENMASK(2, 1)) -+#define SYS_PORT_MODE_INCL_XTR_HDR_M GENMASK(2, 1) -+#define SYS_PORT_MODE_INCL_XTR_HDR_X(x) (((x) & GENMASK(2, 1)) >> 1) -+#define SYS_PORT_MODE_INJ_HDR_ERR BIT(0) -+ -+#define SYS_FRONT_PORT_MODE_RSZ 0x4 -+ -+#define SYS_FRONT_PORT_MODE_HDX_MODE BIT(0) -+ -+#define SYS_FRM_AGING_AGE_TX_ENA BIT(20) -+#define SYS_FRM_AGING_MAX_AGE(x) ((x) & GENMASK(19, 0)) -+#define SYS_FRM_AGING_MAX_AGE_M GENMASK(19, 0) -+ -+#define SYS_STAT_CFG_STAT_CLEAR_SHOT(x) (((x) << 10) & GENMASK(16, 10)) -+#define SYS_STAT_CFG_STAT_CLEAR_SHOT_M GENMASK(16, 10) -+#define SYS_STAT_CFG_STAT_CLEAR_SHOT_X(x) (((x) & GENMASK(16, 10)) >> 10) -+#define SYS_STAT_CFG_STAT_VIEW(x) ((x) & GENMASK(9, 0)) -+#define SYS_STAT_CFG_STAT_VIEW_M GENMASK(9, 0) -+ -+#define SYS_SW_STATUS_RSZ 0x4 -+ -+#define SYS_SW_STATUS_PORT_RX_PAUSED BIT(0) -+ -+#define SYS_MISC_CFG_PTP_RSRV_CLR BIT(1) -+#define SYS_MISC_CFG_PTP_DIS_NEG_RO BIT(0) -+ -+#define SYS_REW_MAC_HIGH_CFG_RSZ 0x4 -+ -+#define SYS_REW_MAC_LOW_CFG_RSZ 0x4 -+ -+#define SYS_TIMESTAMP_OFFSET_ETH_TYPE_CFG(x) (((x) << 6) & GENMASK(21, 6)) -+#define SYS_TIMESTAMP_OFFSET_ETH_TYPE_CFG_M GENMASK(21, 6) -+#define SYS_TIMESTAMP_OFFSET_ETH_TYPE_CFG_X(x) (((x) & GENMASK(21, 6)) >> 6) -+#define SYS_TIMESTAMP_OFFSET_TIMESTAMP_OFFSET(x) ((x) & GENMASK(5, 0)) -+#define SYS_TIMESTAMP_OFFSET_TIMESTAMP_OFFSET_M GENMASK(5, 0) -+ -+#define SYS_PAUSE_CFG_RSZ 0x4 -+ -+#define SYS_PAUSE_CFG_PAUSE_START(x) (((x) << 10) & GENMASK(18, 10)) -+#define SYS_PAUSE_CFG_PAUSE_START_M GENMASK(18, 10) -+#define SYS_PAUSE_CFG_PAUSE_START_X(x) (((x) & GENMASK(18, 10)) >> 10) -+#define SYS_PAUSE_CFG_PAUSE_STOP(x) (((x) << 1) & GENMASK(9, 1)) -+#define SYS_PAUSE_CFG_PAUSE_STOP_M GENMASK(9, 1) -+#define SYS_PAUSE_CFG_PAUSE_STOP_X(x) (((x) & GENMASK(9, 1)) >> 1) -+#define SYS_PAUSE_CFG_PAUSE_ENA BIT(0) -+ -+#define SYS_PAUSE_TOT_CFG_PAUSE_TOT_START(x) (((x) << 9) & GENMASK(17, 9)) -+#define SYS_PAUSE_TOT_CFG_PAUSE_TOT_START_M GENMASK(17, 9) -+#define SYS_PAUSE_TOT_CFG_PAUSE_TOT_START_X(x) (((x) & GENMASK(17, 9)) >> 9) -+#define SYS_PAUSE_TOT_CFG_PAUSE_TOT_STOP(x) ((x) & GENMASK(8, 0)) -+#define SYS_PAUSE_TOT_CFG_PAUSE_TOT_STOP_M GENMASK(8, 0) -+ -+#define SYS_ATOP_RSZ 0x4 -+ -+#define SYS_MAC_FC_CFG_RSZ 0x4 -+ -+#define SYS_MAC_FC_CFG_FC_LINK_SPEED(x) (((x) << 26) & GENMASK(27, 26)) -+#define SYS_MAC_FC_CFG_FC_LINK_SPEED_M GENMASK(27, 26) -+#define SYS_MAC_FC_CFG_FC_LINK_SPEED_X(x) (((x) & GENMASK(27, 26)) >> 26) -+#define SYS_MAC_FC_CFG_FC_LATENCY_CFG(x) (((x) << 20) & GENMASK(25, 20)) -+#define SYS_MAC_FC_CFG_FC_LATENCY_CFG_M GENMASK(25, 20) -+#define SYS_MAC_FC_CFG_FC_LATENCY_CFG_X(x) (((x) & GENMASK(25, 20)) >> 20) -+#define SYS_MAC_FC_CFG_ZERO_PAUSE_ENA BIT(18) -+#define SYS_MAC_FC_CFG_TX_FC_ENA BIT(17) -+#define SYS_MAC_FC_CFG_RX_FC_ENA BIT(16) -+#define SYS_MAC_FC_CFG_PAUSE_VAL_CFG(x) ((x) & GENMASK(15, 0)) -+#define SYS_MAC_FC_CFG_PAUSE_VAL_CFG_M GENMASK(15, 0) -+ -+#define SYS_MMGT_RELCNT(x) (((x) << 16) & GENMASK(31, 16)) -+#define SYS_MMGT_RELCNT_M GENMASK(31, 16) -+#define SYS_MMGT_RELCNT_X(x) (((x) & GENMASK(31, 16)) >> 16) -+#define SYS_MMGT_FREECNT(x) ((x) & GENMASK(15, 0)) -+#define SYS_MMGT_FREECNT_M GENMASK(15, 0) -+ -+#define SYS_MMGT_FAST_FREEVLD(x) (((x) << 4) & GENMASK(7, 4)) -+#define SYS_MMGT_FAST_FREEVLD_M GENMASK(7, 4) -+#define SYS_MMGT_FAST_FREEVLD_X(x) (((x) & GENMASK(7, 4)) >> 4) -+#define SYS_MMGT_FAST_RELVLD(x) ((x) & GENMASK(3, 0)) -+#define SYS_MMGT_FAST_RELVLD_M GENMASK(3, 0) -+ -+#define SYS_EVENTS_DIF_RSZ 0x4 -+ -+#define SYS_EVENTS_DIF_EV_DRX(x) (((x) << 6) & GENMASK(8, 6)) -+#define SYS_EVENTS_DIF_EV_DRX_M GENMASK(8, 6) -+#define SYS_EVENTS_DIF_EV_DRX_X(x) (((x) & GENMASK(8, 6)) >> 6) -+#define SYS_EVENTS_DIF_EV_DTX(x) ((x) & GENMASK(5, 0)) -+#define SYS_EVENTS_DIF_EV_DTX_M GENMASK(5, 0) -+ -+#define SYS_EVENTS_CORE_EV_FWR BIT(2) -+#define SYS_EVENTS_CORE_EV_ANA(x) ((x) & GENMASK(1, 0)) -+#define SYS_EVENTS_CORE_EV_ANA_M GENMASK(1, 0) -+ -+#define SYS_CNT_GSZ 0x4 -+ -+#define SYS_PTP_STATUS_PTP_TXSTAMP_OAM BIT(29) -+#define SYS_PTP_STATUS_PTP_OVFL BIT(28) -+#define SYS_PTP_STATUS_PTP_MESS_VLD BIT(27) -+#define SYS_PTP_STATUS_PTP_MESS_ID(x) (((x) << 21) & GENMASK(26, 21)) -+#define SYS_PTP_STATUS_PTP_MESS_ID_M GENMASK(26, 21) -+#define SYS_PTP_STATUS_PTP_MESS_ID_X(x) (((x) & GENMASK(26, 21)) >> 21) -+#define SYS_PTP_STATUS_PTP_MESS_TXPORT(x) (((x) << 16) & GENMASK(20, 16)) -+#define SYS_PTP_STATUS_PTP_MESS_TXPORT_M GENMASK(20, 16) -+#define SYS_PTP_STATUS_PTP_MESS_TXPORT_X(x) (((x) & GENMASK(20, 16)) >> 16) -+#define SYS_PTP_STATUS_PTP_MESS_SEQ_ID(x) ((x) & GENMASK(15, 0)) -+#define SYS_PTP_STATUS_PTP_MESS_SEQ_ID_M GENMASK(15, 0) -+ -+#define SYS_PTP_TXSTAMP_PTP_TXSTAMP(x) ((x) & GENMASK(29, 0)) -+#define SYS_PTP_TXSTAMP_PTP_TXSTAMP_M GENMASK(29, 0) -+#define SYS_PTP_TXSTAMP_PTP_TXSTAMP_SEC BIT(31) -+ -+#define SYS_PTP_NXT_PTP_NXT BIT(0) -+ -+#define SYS_PTP_CFG_PTP_STAMP_WID(x) (((x) << 2) & GENMASK(7, 2)) -+#define SYS_PTP_CFG_PTP_STAMP_WID_M GENMASK(7, 2) -+#define SYS_PTP_CFG_PTP_STAMP_WID_X(x) (((x) & GENMASK(7, 2)) >> 2) -+#define SYS_PTP_CFG_PTP_CF_ROLL_MODE(x) ((x) & GENMASK(1, 0)) -+#define SYS_PTP_CFG_PTP_CF_ROLL_MODE_M GENMASK(1, 0) -+ -+#define SYS_RAM_INIT_RAM_INIT BIT(1) -+#define SYS_RAM_INIT_RAM_CFG_HOOK BIT(0) -+ -+#endif diff --git a/target/linux/layerscape/patches-5.4/701-net-0262-net-dsa-ocelot-add-tagger-for-Ocelot-Felix-switches.patch b/target/linux/layerscape/patches-5.4/701-net-0262-net-dsa-ocelot-add-tagger-for-Ocelot-Felix-switches.patch deleted file mode 100644 index 5304bbca0a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0262-net-dsa-ocelot-add-tagger-for-Ocelot-Felix-switches.patch +++ /dev/null @@ -1,331 +0,0 @@ -From 0254efd8d7e8f533b57bdf8665991fd5548c65a8 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 14 Nov 2019 17:03:29 +0200 -Subject: [PATCH] net: dsa: ocelot: add tagger for Ocelot/Felix switches - -While it is entirely possible that this tagger format is in fact more -generic than just these 2 switch families, I don't have that knowledge. -The Seville switch in NXP T1040 has a similar frame format, but there -are enough differences (e.g. DEST field starts at bit 57 instead of 56) -that calling this file tag_vitesse.c is a bit of a stretch at the -moment. The frame format has been listed in a comment so that people who -add support for further Vitesse switches can rework this tagger while -keeping compatibility with Felix. - -The "ocelot" name was chosen instead of "felix" because even the Ocelot -switch can act as a DSA device when it is used in NPI mode, and the Felix -tagger format is almost identical. Currently it is only used for the -Felix switch embedded in the NXP LS1028A chip. - -The ABI for this tagger should be considered "not stable" at the moment. -The DSA tag is always placed before the Ethernet header and therefore, -we are using the long prefix for RX tags to avoid putting the DSA master -port in promiscuous mode. Once there will be an API in DSA for drivers -to request DSA masters to be in promiscuous mode unconditionally, we -will switch to the "no prefix" extraction frame header, which will save -16 padding bytes for each RX frame. - -Signed-off-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - MAINTAINERS | 7 ++ - include/net/dsa.h | 2 + - net/dsa/Kconfig | 7 ++ - net/dsa/Makefile | 1 + - net/dsa/tag_ocelot.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 246 insertions(+) - create mode 100644 net/dsa/tag_ocelot.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -17356,6 +17356,13 @@ S: Maintained - F: drivers/input/serio/userio.c - F: include/uapi/linux/userio.h - -+VITESSE FELIX ETHERNET SWITCH DRIVER -+M: Vladimir Oltean -+M: Claudiu Manoil -+L: netdev@vger.kernel.org -+S: Maintained -+F: net/dsa/tag_ocelot.c -+ - VIVID VIRTUAL VIDEO DRIVER - M: Hans Verkuil - L: linux-media@vger.kernel.org ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -42,6 +42,7 @@ struct phylink_link_state; - #define DSA_TAG_PROTO_8021Q_VALUE 12 - #define DSA_TAG_PROTO_SJA1105_VALUE 13 - #define DSA_TAG_PROTO_KSZ8795_VALUE 14 -+#define DSA_TAG_PROTO_OCELOT_VALUE 15 - #define DSA_TAG_PROTO_RTL4_A_VALUE 17 - - enum dsa_tag_protocol { -@@ -60,6 +61,7 @@ enum dsa_tag_protocol { - DSA_TAG_PROTO_8021Q = DSA_TAG_PROTO_8021Q_VALUE, - DSA_TAG_PROTO_SJA1105 = DSA_TAG_PROTO_SJA1105_VALUE, - DSA_TAG_PROTO_KSZ8795 = DSA_TAG_PROTO_KSZ8795_VALUE, -+ DSA_TAG_PROTO_OCELOT = DSA_TAG_PROTO_OCELOT_VALUE, - DSA_TAG_PROTO_RTL4_A = DSA_TAG_PROTO_RTL4_A_VALUE, - }; - ---- a/net/dsa/Kconfig -+++ b/net/dsa/Kconfig -@@ -87,6 +87,13 @@ config NET_DSA_TAG_RTL4_A - Realtek switches with 4 byte protocol A tags, sich as found in - the Realtek RTL8366RB. - -+config NET_DSA_TAG_OCELOT -+ tristate "Tag driver for Ocelot family of switches" -+ select PACKING -+ help -+ Say Y or M if you want to enable support for tagging frames for the -+ Ocelot switches (VSC7511, VSC7512, VSC7513, VSC7514, VSC9959). -+ - config NET_DSA_TAG_QCA - tristate "Tag driver for Qualcomm Atheros QCA8K switches" - help ---- a/net/dsa/Makefile -+++ b/net/dsa/Makefile -@@ -13,6 +13,7 @@ obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz - obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o - obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o - obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o -+obj-$(CONFIG_NET_DSA_TAG_OCELOT) += tag_ocelot.o - obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o - obj-$(CONFIG_NET_DSA_TAG_SJA1105) += tag_sja1105.o - obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o ---- /dev/null -+++ b/net/dsa/tag_ocelot.c -@@ -0,0 +1,229 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Copyright 2019 NXP Semiconductors -+ */ -+#include -+#include -+#include "dsa_priv.h" -+ -+/* The CPU injection header and the CPU extraction header can have 3 types of -+ * prefixes: long, short and no prefix. The format of the header itself is the -+ * same in all 3 cases. -+ * -+ * Extraction with long prefix: -+ * -+ * +-------------------+-------------------+------+------+------------+-------+ -+ * | ff:ff:ff:ff:ff:ff | ff:ff:ff:ff:ff:ff | 8880 | 000a | extraction | frame | -+ * | | | | | header | | -+ * +-------------------+-------------------+------+------+------------+-------+ -+ * 48 bits 48 bits 16 bits 16 bits 128 bits -+ * -+ * Extraction with short prefix: -+ * -+ * +------+------+------------+-------+ -+ * | 8880 | 000a | extraction | frame | -+ * | | | header | | -+ * +------+------+------------+-------+ -+ * 16 bits 16 bits 128 bits -+ * -+ * Extraction with no prefix: -+ * -+ * +------------+-------+ -+ * | extraction | frame | -+ * | header | | -+ * +------------+-------+ -+ * 128 bits -+ * -+ * -+ * Injection with long prefix: -+ * -+ * +-------------------+-------------------+------+------+------------+-------+ -+ * | any dmac | any smac | 8880 | 000a | injection | frame | -+ * | | | | | header | | -+ * +-------------------+-------------------+------+------+------------+-------+ -+ * 48 bits 48 bits 16 bits 16 bits 128 bits -+ * -+ * Injection with short prefix: -+ * -+ * +------+------+------------+-------+ -+ * | 8880 | 000a | injection | frame | -+ * | | | header | | -+ * +------+------+------------+-------+ -+ * 16 bits 16 bits 128 bits -+ * -+ * Injection with no prefix: -+ * -+ * +------------+-------+ -+ * | injection | frame | -+ * | header | | -+ * +------------+-------+ -+ * 128 bits -+ * -+ * The injection header looks like this (network byte order, bit 127 -+ * is part of lowest address byte in memory, bit 0 is part of highest -+ * address byte): -+ * -+ * +------+------+------+------+------+------+------+------+ -+ * 127:120 |BYPASS| MASQ | MASQ_PORT |REW_OP|REW_OP| -+ * +------+------+------+------+------+------+------+------+ -+ * 119:112 | REW_OP | -+ * +------+------+------+------+------+------+------+------+ -+ * 111:104 | REW_VAL | -+ * +------+------+------+------+------+------+------+------+ -+ * 103: 96 | REW_VAL | -+ * +------+------+------+------+------+------+------+------+ -+ * 95: 88 | REW_VAL | -+ * +------+------+------+------+------+------+------+------+ -+ * 87: 80 | REW_VAL | -+ * +------+------+------+------+------+------+------+------+ -+ * 79: 72 | RSV | -+ * +------+------+------+------+------+------+------+------+ -+ * 71: 64 | RSV | DEST | -+ * +------+------+------+------+------+------+------+------+ -+ * 63: 56 | DEST | -+ * +------+------+------+------+------+------+------+------+ -+ * 55: 48 | RSV | -+ * +------+------+------+------+------+------+------+------+ -+ * 47: 40 | RSV | SRC_PORT | RSV |TFRM_TIMER| -+ * +------+------+------+------+------+------+------+------+ -+ * 39: 32 | TFRM_TIMER | RSV | -+ * +------+------+------+------+------+------+------+------+ -+ * 31: 24 | RSV | DP | POP_CNT | CPUQ | -+ * +------+------+------+------+------+------+------+------+ -+ * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE| -+ * +------+------+------+------+------+------+------+------+ -+ * 15: 8 | PCP | DEI | VID | -+ * +------+------+------+------+------+------+------+------+ -+ * 7: 0 | VID | -+ * +------+------+------+------+------+------+------+------+ -+ * -+ * And the extraction header looks like this: -+ * -+ * +------+------+------+------+------+------+------+------+ -+ * 127:120 | RSV | REW_OP | -+ * +------+------+------+------+------+------+------+------+ -+ * 119:112 | REW_OP | REW_VAL | -+ * +------+------+------+------+------+------+------+------+ -+ * 111:104 | REW_VAL | -+ * +------+------+------+------+------+------+------+------+ -+ * 103: 96 | REW_VAL | -+ * +------+------+------+------+------+------+------+------+ -+ * 95: 88 | REW_VAL | -+ * +------+------+------+------+------+------+------+------+ -+ * 87: 80 | REW_VAL | LLEN | -+ * +------+------+------+------+------+------+------+------+ -+ * 79: 72 | LLEN | WLEN | -+ * +------+------+------+------+------+------+------+------+ -+ * 71: 64 | WLEN | RSV | -+ * +------+------+------+------+------+------+------+------+ -+ * 63: 56 | RSV | -+ * +------+------+------+------+------+------+------+------+ -+ * 55: 48 | RSV | -+ * +------+------+------+------+------+------+------+------+ -+ * 47: 40 | RSV | SRC_PORT | ACL_ID | -+ * +------+------+------+------+------+------+------+------+ -+ * 39: 32 | ACL_ID | RSV | SFLOW_ID | -+ * +------+------+------+------+------+------+------+------+ -+ * 31: 24 |ACL_HIT| DP | LRN_FLAGS | CPUQ | -+ * +------+------+------+------+------+------+------+------+ -+ * 23: 16 | CPUQ | QOS_CLASS |TAG_TYPE| -+ * +------+------+------+------+------+------+------+------+ -+ * 15: 8 | PCP | DEI | VID | -+ * +------+------+------+------+------+------+------+------+ -+ * 7: 0 | VID | -+ * +------+------+------+------+------+------+------+------+ -+ */ -+ -+static struct sk_buff *ocelot_xmit(struct sk_buff *skb, -+ struct net_device *netdev) -+{ -+ struct dsa_port *dp = dsa_slave_to_port(netdev); -+ u64 bypass, dest, src, qos_class; -+ struct dsa_switch *ds = dp->ds; -+ int port = dp->index; -+ u8 *injection; -+ -+ if (unlikely(skb_cow_head(skb, OCELOT_TAG_LEN) < 0)) { -+ netdev_err(netdev, "Cannot make room for tag.\n"); -+ return NULL; -+ } -+ -+ injection = skb_push(skb, OCELOT_TAG_LEN); -+ -+ memset(injection, 0, OCELOT_TAG_LEN); -+ -+ src = dsa_upstream_port(ds, port); -+ dest = BIT(port); -+ bypass = true; -+ qos_class = skb->priority; -+ -+ packing(injection, &bypass, 127, 127, OCELOT_TAG_LEN, PACK, 0); -+ packing(injection, &dest, 68, 56, OCELOT_TAG_LEN, PACK, 0); -+ packing(injection, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0); -+ packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0); -+ -+ return skb; -+} -+ -+static struct sk_buff *ocelot_rcv(struct sk_buff *skb, -+ struct net_device *netdev, -+ struct packet_type *pt) -+{ -+ u64 src_port, qos_class; -+ u8 *start = skb->data; -+ u8 *extraction; -+ -+ /* Revert skb->data by the amount consumed by the DSA master, -+ * so it points to the beginning of the frame. -+ */ -+ skb_push(skb, ETH_HLEN); -+ /* We don't care about the long prefix, it is just for easy entrance -+ * into the DSA master's RX filter. Discard it now by moving it into -+ * the headroom. -+ */ -+ skb_pull(skb, OCELOT_LONG_PREFIX_LEN); -+ /* And skb->data now points to the extraction frame header. -+ * Keep a pointer to it. -+ */ -+ extraction = skb->data; -+ /* Now the EFH is part of the headroom as well */ -+ skb_pull(skb, OCELOT_TAG_LEN); -+ /* Reset the pointer to the real MAC header */ -+ skb_reset_mac_header(skb); -+ skb_reset_mac_len(skb); -+ /* And move skb->data to the correct location again */ -+ skb_pull(skb, ETH_HLEN); -+ -+ /* Remove from inet csum the extraction header */ -+ skb_postpull_rcsum(skb, start, OCELOT_LONG_PREFIX_LEN + OCELOT_TAG_LEN); -+ -+ packing(extraction, &src_port, 46, 43, OCELOT_TAG_LEN, UNPACK, 0); -+ packing(extraction, &qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0); -+ -+ skb->dev = dsa_master_find_slave(netdev, 0, src_port); -+ if (!skb->dev) -+ /* The switch will reflect back some frames sent through -+ * sockets opened on the bare DSA master. These will come back -+ * with src_port equal to the index of the CPU port, for which -+ * there is no slave registered. So don't print any error -+ * message here (ignore and drop those frames). -+ */ -+ return NULL; -+ -+ skb->offload_fwd_mark = 1; -+ skb->priority = qos_class; -+ -+ return skb; -+} -+ -+static struct dsa_device_ops ocelot_netdev_ops = { -+ .name = "ocelot", -+ .proto = DSA_TAG_PROTO_OCELOT, -+ .xmit = ocelot_xmit, -+ .rcv = ocelot_rcv, -+ .overhead = OCELOT_TAG_LEN + OCELOT_LONG_PREFIX_LEN, -+}; -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_OCELOT); -+ -+module_dsa_tag_driver(ocelot_netdev_ops); diff --git a/target/linux/layerscape/patches-5.4/701-net-0263-net-dsa-ocelot-add-driver-for-Felix-switch-family.patch b/target/linux/layerscape/patches-5.4/701-net-0263-net-dsa-ocelot-add-driver-for-Felix-switch-family.patch deleted file mode 100644 index 5dc50c5ee6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0263-net-dsa-ocelot-add-driver-for-Felix-switch-family.patch +++ /dev/null @@ -1,1163 +0,0 @@ -From 469b6adff1484015369993dbb86a2936b6517a7d Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 14 Nov 2019 17:03:30 +0200 -Subject: [PATCH] net: dsa: ocelot: add driver for Felix switch family - -This supports an Ethernet switching core from Vitesse / Microsemi / -Microchip (VSC9959) which is part of the Ocelot family (a brand name), -and whose code name is Felix. The switch can be (and is) integrated on -different SoCs as a PCIe endpoint device. - -The functionality is provided by the core of the Ocelot switch driver -(drivers/net/ethernet/mscc). In this regard, the current driver is an -instance of Microsemi's Ocelot core driver, with a DSA front-end. It -inherits its name from VSC9959's code name, to distinguish itself from -the switchdev ocelot driver. - -The patch adds the logic for probing a PCI device and defines the -register map for the VSC9959 switch core, since it has some differences -in register addresses and bitfield mappings compared to the other Ocelot -switches (VSC7511, VSC7512, VSC7513, VSC7514). - -The Felix driver declares the register map as part of the "instance -table". Currently the VSC9959 inside NXP LS1028A is the only instance, -but presumably it can support other switches in the Ocelot family, when -used in DSA mode (Linux running on the external CPU, and not on the -embedded MIPS). - -In a few cases, some h/w operations have to be done differently on -VSC9959 due to missing bitfields. This is the case for the switch core -reset and init. Because for this operation Ocelot uses some bits that -are not present on Felix, the latter has to use a register from the -global registers block (GCB) instead. - -Although it is a PCI driver, it relies on DT bindings for compatibility -with DSA (CPU port link, PHY library). It does not have any custom -device tree bindings, since we would like to minimize its dependency on -device tree though. - -Signed-off-by: Claudiu Manoil -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - MAINTAINERS | 1 + - drivers/net/dsa/Kconfig | 2 + - drivers/net/dsa/Makefile | 1 + - drivers/net/dsa/ocelot/Kconfig | 11 + - drivers/net/dsa/ocelot/Makefile | 6 + - drivers/net/dsa/ocelot/felix.c | 441 +++++++++++++++++++++++++ - drivers/net/dsa/ocelot/felix.h | 37 +++ - drivers/net/dsa/ocelot/felix_vsc9959.c | 567 +++++++++++++++++++++++++++++++++ - 8 files changed, 1066 insertions(+) - create mode 100644 drivers/net/dsa/ocelot/Kconfig - create mode 100644 drivers/net/dsa/ocelot/Makefile - create mode 100644 drivers/net/dsa/ocelot/felix.c - create mode 100644 drivers/net/dsa/ocelot/felix.h - create mode 100644 drivers/net/dsa/ocelot/felix_vsc9959.c - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -17361,6 +17361,7 @@ M: Vladimir Oltean - L: netdev@vger.kernel.org - S: Maintained -+F: drivers/net/dsa/ocelot/* - F: net/dsa/tag_ocelot.c - - VIVID VIRTUAL VIDEO DRIVER ---- a/drivers/net/dsa/Kconfig -+++ b/drivers/net/dsa/Kconfig -@@ -52,6 +52,8 @@ source "drivers/net/dsa/microchip/Kconfi - - source "drivers/net/dsa/mv88e6xxx/Kconfig" - -+source "drivers/net/dsa/ocelot/Kconfig" -+ - source "drivers/net/dsa/sja1105/Kconfig" - - config NET_DSA_QCA8K ---- a/drivers/net/dsa/Makefile -+++ b/drivers/net/dsa/Makefile -@@ -20,4 +20,5 @@ obj-$(CONFIG_NET_DSA_VITESSE_VSC73XX_SPI - obj-y += b53/ - obj-y += microchip/ - obj-y += mv88e6xxx/ -+obj-y += ocelot/ - obj-y += sja1105/ ---- /dev/null -+++ b/drivers/net/dsa/ocelot/Kconfig -@@ -0,0 +1,11 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+config NET_DSA_MSCC_FELIX -+ tristate "Ocelot / Felix Ethernet switch support" -+ depends on NET_DSA && PCI -+ select MSCC_OCELOT_SWITCH -+ select NET_DSA_TAG_OCELOT -+ help -+ This driver supports the VSC9959 network switch, which is a member of -+ the Vitesse / Microsemi / Microchip Ocelot family of switching cores. -+ It is embedded as a PCIe function of the NXP LS1028A ENETC integrated -+ endpoint. ---- /dev/null -+++ b/drivers/net/dsa/ocelot/Makefile -@@ -0,0 +1,6 @@ -+# SPDX-License-Identifier: GPL-2.0-only -+obj-$(CONFIG_NET_DSA_MSCC_FELIX) += mscc_felix.o -+ -+mscc_felix-objs := \ -+ felix.o \ -+ felix_vsc9959.o ---- /dev/null -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -0,0 +1,441 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* Copyright 2019 NXP Semiconductors -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "felix.h" -+ -+static enum dsa_tag_protocol felix_get_tag_protocol(struct dsa_switch *ds, -+ int port) -+{ -+ return DSA_TAG_PROTO_OCELOT; -+} -+ -+static int felix_set_ageing_time(struct dsa_switch *ds, -+ unsigned int ageing_time) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ ocelot_set_ageing_time(ocelot, ageing_time); -+ -+ return 0; -+} -+ -+static void felix_adjust_link(struct dsa_switch *ds, int port, -+ struct phy_device *phydev) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ ocelot_adjust_link(ocelot, port, phydev); -+} -+ -+static int felix_fdb_dump(struct dsa_switch *ds, int port, -+ dsa_fdb_dump_cb_t *cb, void *data) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ return ocelot_fdb_dump(ocelot, port, cb, data); -+} -+ -+static int felix_fdb_add(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid) -+{ -+ struct ocelot *ocelot = ds->priv; -+ bool vlan_aware; -+ -+ vlan_aware = dsa_port_is_vlan_filtering(dsa_to_port(ds, port)); -+ -+ return ocelot_fdb_add(ocelot, port, addr, vid, vlan_aware); -+} -+ -+static int felix_fdb_del(struct dsa_switch *ds, int port, -+ const unsigned char *addr, u16 vid) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ return ocelot_fdb_del(ocelot, port, addr, vid); -+} -+ -+static void felix_bridge_stp_state_set(struct dsa_switch *ds, int port, -+ u8 state) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ return ocelot_bridge_stp_state_set(ocelot, port, state); -+} -+ -+static int felix_bridge_join(struct dsa_switch *ds, int port, -+ struct net_device *br) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ return ocelot_port_bridge_join(ocelot, port, br); -+} -+ -+static void felix_bridge_leave(struct dsa_switch *ds, int port, -+ struct net_device *br) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ ocelot_port_bridge_leave(ocelot, port, br); -+} -+ -+/* This callback needs to be present */ -+static int felix_vlan_prepare(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan) -+{ -+ return 0; -+} -+ -+static int felix_vlan_filtering(struct dsa_switch *ds, int port, bool enabled) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ ocelot_port_vlan_filtering(ocelot, port, enabled); -+ -+ return 0; -+} -+ -+static void felix_vlan_add(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan) -+{ -+ struct ocelot *ocelot = ds->priv; -+ u16 vid; -+ int err; -+ -+ for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { -+ err = ocelot_vlan_add(ocelot, port, vid, -+ vlan->flags & BRIDGE_VLAN_INFO_PVID, -+ vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED); -+ if (err) { -+ dev_err(ds->dev, "Failed to add VLAN %d to port %d: %d\n", -+ vid, port, err); -+ return; -+ } -+ } -+} -+ -+static int felix_vlan_del(struct dsa_switch *ds, int port, -+ const struct switchdev_obj_port_vlan *vlan) -+{ -+ struct ocelot *ocelot = ds->priv; -+ u16 vid; -+ int err; -+ -+ for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { -+ err = ocelot_vlan_del(ocelot, port, vid); -+ if (err) { -+ dev_err(ds->dev, "Failed to remove VLAN %d from port %d: %d\n", -+ vid, port, err); -+ return err; -+ } -+ } -+ return 0; -+} -+ -+static int felix_port_enable(struct dsa_switch *ds, int port, -+ struct phy_device *phy) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ ocelot_port_enable(ocelot, port, phy); -+ -+ return 0; -+} -+ -+static void felix_port_disable(struct dsa_switch *ds, int port) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ return ocelot_port_disable(ocelot, port); -+} -+ -+static void felix_get_strings(struct dsa_switch *ds, int port, -+ u32 stringset, u8 *data) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ return ocelot_get_strings(ocelot, port, stringset, data); -+} -+ -+static void felix_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ ocelot_get_ethtool_stats(ocelot, port, data); -+} -+ -+static int felix_get_sset_count(struct dsa_switch *ds, int port, int sset) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ return ocelot_get_sset_count(ocelot, port, sset); -+} -+ -+static int felix_get_ts_info(struct dsa_switch *ds, int port, -+ struct ethtool_ts_info *info) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ return ocelot_get_ts_info(ocelot, port, info); -+} -+ -+static int felix_init_structs(struct felix *felix, int num_phys_ports) -+{ -+ struct ocelot *ocelot = &felix->ocelot; -+ resource_size_t base; -+ int port, i, err; -+ -+ ocelot->num_phys_ports = num_phys_ports; -+ ocelot->ports = devm_kcalloc(ocelot->dev, num_phys_ports, -+ sizeof(struct ocelot_port *), GFP_KERNEL); -+ if (!ocelot->ports) -+ return -ENOMEM; -+ -+ ocelot->map = felix->info->map; -+ ocelot->stats_layout = felix->info->stats_layout; -+ ocelot->num_stats = felix->info->num_stats; -+ ocelot->shared_queue_sz = felix->info->shared_queue_sz; -+ ocelot->ops = felix->info->ops; -+ -+ base = pci_resource_start(felix->pdev, felix->info->pci_bar); -+ -+ for (i = 0; i < TARGET_MAX; i++) { -+ struct regmap *target; -+ struct resource *res; -+ -+ if (!felix->info->target_io_res[i].name) -+ continue; -+ -+ res = &felix->info->target_io_res[i]; -+ res->flags = IORESOURCE_MEM; -+ res->start += base; -+ res->end += base; -+ -+ target = ocelot_regmap_init(ocelot, res); -+ if (IS_ERR(target)) { -+ dev_err(ocelot->dev, -+ "Failed to map device memory space\n"); -+ return PTR_ERR(target); -+ } -+ -+ ocelot->targets[i] = target; -+ } -+ -+ err = ocelot_regfields_init(ocelot, felix->info->regfields); -+ if (err) { -+ dev_err(ocelot->dev, "failed to init reg fields map\n"); -+ return err; -+ } -+ -+ for (port = 0; port < num_phys_ports; port++) { -+ struct ocelot_port *ocelot_port; -+ void __iomem *port_regs; -+ struct resource *res; -+ -+ ocelot_port = devm_kzalloc(ocelot->dev, -+ sizeof(struct ocelot_port), -+ GFP_KERNEL); -+ if (!ocelot_port) { -+ dev_err(ocelot->dev, -+ "failed to allocate port memory\n"); -+ return -ENOMEM; -+ } -+ -+ res = &felix->info->port_io_res[port]; -+ res->flags = IORESOURCE_MEM; -+ res->start += base; -+ res->end += base; -+ -+ port_regs = devm_ioremap_resource(ocelot->dev, res); -+ if (IS_ERR(port_regs)) { -+ dev_err(ocelot->dev, -+ "failed to map registers for port %d\n", port); -+ return PTR_ERR(port_regs); -+ } -+ -+ ocelot_port->ocelot = ocelot; -+ ocelot_port->regs = port_regs; -+ ocelot->ports[port] = ocelot_port; -+ } -+ -+ return 0; -+} -+ -+/* Hardware initialization done here so that we can allocate structures with -+ * devm without fear of dsa_register_switch returning -EPROBE_DEFER and causing -+ * us to allocate structures twice (leak memory) and map PCI memory twice -+ * (which will not work). -+ */ -+static int felix_setup(struct dsa_switch *ds) -+{ -+ struct ocelot *ocelot = ds->priv; -+ struct felix *felix = ocelot_to_felix(ocelot); -+ int port, err; -+ -+ err = felix_init_structs(felix, ds->num_ports); -+ if (err) -+ return err; -+ -+ ocelot_init(ocelot); -+ -+ for (port = 0; port < ds->num_ports; port++) { -+ ocelot_init_port(ocelot, port); -+ -+ if (port == dsa_upstream_port(ds, port)) -+ ocelot_set_cpu_port(ocelot, port, -+ OCELOT_TAG_PREFIX_NONE, -+ OCELOT_TAG_PREFIX_LONG); -+ } -+ -+ return 0; -+} -+ -+static void felix_teardown(struct dsa_switch *ds) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ /* stop workqueue thread */ -+ ocelot_deinit(ocelot); -+} -+ -+static const struct dsa_switch_ops felix_switch_ops = { -+ .get_tag_protocol = felix_get_tag_protocol, -+ .setup = felix_setup, -+ .teardown = felix_teardown, -+ .set_ageing_time = felix_set_ageing_time, -+ .get_strings = felix_get_strings, -+ .get_ethtool_stats = felix_get_ethtool_stats, -+ .get_sset_count = felix_get_sset_count, -+ .get_ts_info = felix_get_ts_info, -+ .adjust_link = felix_adjust_link, -+ .port_enable = felix_port_enable, -+ .port_disable = felix_port_disable, -+ .port_fdb_dump = felix_fdb_dump, -+ .port_fdb_add = felix_fdb_add, -+ .port_fdb_del = felix_fdb_del, -+ .port_bridge_join = felix_bridge_join, -+ .port_bridge_leave = felix_bridge_leave, -+ .port_stp_state_set = felix_bridge_stp_state_set, -+ .port_vlan_prepare = felix_vlan_prepare, -+ .port_vlan_filtering = felix_vlan_filtering, -+ .port_vlan_add = felix_vlan_add, -+ .port_vlan_del = felix_vlan_del, -+}; -+ -+static struct felix_info *felix_instance_tbl[] = { -+ [FELIX_INSTANCE_VSC9959] = &felix_info_vsc9959, -+}; -+ -+static int felix_pci_probe(struct pci_dev *pdev, -+ const struct pci_device_id *id) -+{ -+ enum felix_instance instance = id->driver_data; -+ struct dsa_switch *ds; -+ struct ocelot *ocelot; -+ struct felix *felix; -+ int err; -+ -+ err = pci_enable_device(pdev); -+ if (err) { -+ dev_err(&pdev->dev, "device enable failed\n"); -+ goto err_pci_enable; -+ } -+ -+ /* set up for high or low dma */ -+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); -+ if (err) { -+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); -+ if (err) { -+ dev_err(&pdev->dev, -+ "DMA configuration failed: 0x%x\n", err); -+ goto err_dma; -+ } -+ } -+ -+ felix = kzalloc(sizeof(struct felix), GFP_KERNEL); -+ if (!felix) { -+ err = -ENOMEM; -+ dev_err(&pdev->dev, "Failed to allocate driver memory\n"); -+ goto err_alloc_felix; -+ } -+ -+ pci_set_drvdata(pdev, felix); -+ ocelot = &felix->ocelot; -+ ocelot->dev = &pdev->dev; -+ felix->pdev = pdev; -+ felix->info = felix_instance_tbl[instance]; -+ -+ pci_set_master(pdev); -+ -+ ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL); -+ if (!ds) { -+ err = -ENOMEM; -+ dev_err(&pdev->dev, "Failed to allocate DSA switch\n"); -+ goto err_alloc_ds; -+ } -+ -+ ds->dev = &pdev->dev; -+ ds->num_ports = felix->info->num_ports; -+ ds->ops = &felix_switch_ops; -+ ds->priv = ocelot; -+ felix->ds = ds; -+ -+ err = dsa_register_switch(ds); -+ if (err) { -+ dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", err); -+ goto err_register_ds; -+ } -+ -+ return 0; -+ -+err_register_ds: -+ kfree(ds); -+err_alloc_ds: -+err_alloc_felix: -+ kfree(felix); -+err_dma: -+ pci_disable_device(pdev); -+err_pci_enable: -+ return err; -+} -+ -+static void felix_pci_remove(struct pci_dev *pdev) -+{ -+ struct felix *felix; -+ -+ felix = pci_get_drvdata(pdev); -+ -+ dsa_unregister_switch(felix->ds); -+ -+ kfree(felix->ds); -+ kfree(felix); -+ -+ pci_disable_device(pdev); -+} -+ -+static struct pci_device_id felix_ids[] = { -+ { -+ /* NXP LS1028A */ -+ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, 0xEEF0), -+ .driver_data = FELIX_INSTANCE_VSC9959, -+ }, -+ { 0, } -+}; -+MODULE_DEVICE_TABLE(pci, felix_ids); -+ -+static struct pci_driver felix_pci_driver = { -+ .name = KBUILD_MODNAME, -+ .id_table = felix_ids, -+ .probe = felix_pci_probe, -+ .remove = felix_pci_remove, -+}; -+ -+module_pci_driver(felix_pci_driver); -+ -+MODULE_DESCRIPTION("Felix Switch driver"); -+MODULE_LICENSE("GPL v2"); ---- /dev/null -+++ b/drivers/net/dsa/ocelot/felix.h -@@ -0,0 +1,37 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* Copyright 2019 NXP Semiconductors -+ */ -+#ifndef _MSCC_FELIX_H -+#define _MSCC_FELIX_H -+ -+#define ocelot_to_felix(o) container_of((o), struct felix, ocelot) -+ -+/* Platform-specific information */ -+struct felix_info { -+ struct resource *target_io_res; -+ struct resource *port_io_res; -+ const struct reg_field *regfields; -+ const u32 *const *map; -+ const struct ocelot_ops *ops; -+ int shared_queue_sz; -+ const struct ocelot_stat_layout *stats_layout; -+ unsigned int num_stats; -+ int num_ports; -+ int pci_bar; -+}; -+ -+extern struct felix_info felix_info_vsc9959; -+ -+enum felix_instance { -+ FELIX_INSTANCE_VSC9959 = 0, -+}; -+ -+/* DSA glue / front-end for struct ocelot */ -+struct felix { -+ struct dsa_switch *ds; -+ struct pci_dev *pdev; -+ struct felix_info *info; -+ struct ocelot ocelot; -+}; -+ -+#endif ---- /dev/null -+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c -@@ -0,0 +1,567 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* Copyright 2017 Microsemi Corporation -+ * Copyright 2018-2019 NXP Semiconductors -+ */ -+#include -+#include -+#include -+#include -+#include "felix.h" -+ -+static const u32 vsc9959_ana_regmap[] = { -+ REG(ANA_ADVLEARN, 0x0089a0), -+ REG(ANA_VLANMASK, 0x0089a4), -+ REG_RESERVED(ANA_PORT_B_DOMAIN), -+ REG(ANA_ANAGEFIL, 0x0089ac), -+ REG(ANA_ANEVENTS, 0x0089b0), -+ REG(ANA_STORMLIMIT_BURST, 0x0089b4), -+ REG(ANA_STORMLIMIT_CFG, 0x0089b8), -+ REG(ANA_ISOLATED_PORTS, 0x0089c8), -+ REG(ANA_COMMUNITY_PORTS, 0x0089cc), -+ REG(ANA_AUTOAGE, 0x0089d0), -+ REG(ANA_MACTOPTIONS, 0x0089d4), -+ REG(ANA_LEARNDISC, 0x0089d8), -+ REG(ANA_AGENCTRL, 0x0089dc), -+ REG(ANA_MIRRORPORTS, 0x0089e0), -+ REG(ANA_EMIRRORPORTS, 0x0089e4), -+ REG(ANA_FLOODING, 0x0089e8), -+ REG(ANA_FLOODING_IPMC, 0x008a08), -+ REG(ANA_SFLOW_CFG, 0x008a0c), -+ REG(ANA_PORT_MODE, 0x008a28), -+ REG(ANA_CUT_THRU_CFG, 0x008a48), -+ REG(ANA_PGID_PGID, 0x008400), -+ REG(ANA_TABLES_ANMOVED, 0x007f1c), -+ REG(ANA_TABLES_MACHDATA, 0x007f20), -+ REG(ANA_TABLES_MACLDATA, 0x007f24), -+ REG(ANA_TABLES_STREAMDATA, 0x007f28), -+ REG(ANA_TABLES_MACACCESS, 0x007f2c), -+ REG(ANA_TABLES_MACTINDX, 0x007f30), -+ REG(ANA_TABLES_VLANACCESS, 0x007f34), -+ REG(ANA_TABLES_VLANTIDX, 0x007f38), -+ REG(ANA_TABLES_ISDXACCESS, 0x007f3c), -+ REG(ANA_TABLES_ISDXTIDX, 0x007f40), -+ REG(ANA_TABLES_ENTRYLIM, 0x007f00), -+ REG(ANA_TABLES_PTP_ID_HIGH, 0x007f44), -+ REG(ANA_TABLES_PTP_ID_LOW, 0x007f48), -+ REG(ANA_TABLES_STREAMACCESS, 0x007f4c), -+ REG(ANA_TABLES_STREAMTIDX, 0x007f50), -+ REG(ANA_TABLES_SEQ_HISTORY, 0x007f54), -+ REG(ANA_TABLES_SEQ_MASK, 0x007f58), -+ REG(ANA_TABLES_SFID_MASK, 0x007f5c), -+ REG(ANA_TABLES_SFIDACCESS, 0x007f60), -+ REG(ANA_TABLES_SFIDTIDX, 0x007f64), -+ REG(ANA_MSTI_STATE, 0x008600), -+ REG(ANA_OAM_UPM_LM_CNT, 0x008000), -+ REG(ANA_SG_ACCESS_CTRL, 0x008a64), -+ REG(ANA_SG_CONFIG_REG_1, 0x007fb0), -+ REG(ANA_SG_CONFIG_REG_2, 0x007fb4), -+ REG(ANA_SG_CONFIG_REG_3, 0x007fb8), -+ REG(ANA_SG_CONFIG_REG_4, 0x007fbc), -+ REG(ANA_SG_CONFIG_REG_5, 0x007fc0), -+ REG(ANA_SG_GCL_GS_CONFIG, 0x007f80), -+ REG(ANA_SG_GCL_TI_CONFIG, 0x007f90), -+ REG(ANA_SG_STATUS_REG_1, 0x008980), -+ REG(ANA_SG_STATUS_REG_2, 0x008984), -+ REG(ANA_SG_STATUS_REG_3, 0x008988), -+ REG(ANA_PORT_VLAN_CFG, 0x007800), -+ REG(ANA_PORT_DROP_CFG, 0x007804), -+ REG(ANA_PORT_QOS_CFG, 0x007808), -+ REG(ANA_PORT_VCAP_CFG, 0x00780c), -+ REG(ANA_PORT_VCAP_S1_KEY_CFG, 0x007810), -+ REG(ANA_PORT_VCAP_S2_CFG, 0x00781c), -+ REG(ANA_PORT_PCP_DEI_MAP, 0x007820), -+ REG(ANA_PORT_CPU_FWD_CFG, 0x007860), -+ REG(ANA_PORT_CPU_FWD_BPDU_CFG, 0x007864), -+ REG(ANA_PORT_CPU_FWD_GARP_CFG, 0x007868), -+ REG(ANA_PORT_CPU_FWD_CCM_CFG, 0x00786c), -+ REG(ANA_PORT_PORT_CFG, 0x007870), -+ REG(ANA_PORT_POL_CFG, 0x007874), -+ REG(ANA_PORT_PTP_CFG, 0x007878), -+ REG(ANA_PORT_PTP_DLY1_CFG, 0x00787c), -+ REG(ANA_PORT_PTP_DLY2_CFG, 0x007880), -+ REG(ANA_PORT_SFID_CFG, 0x007884), -+ REG(ANA_PFC_PFC_CFG, 0x008800), -+ REG_RESERVED(ANA_PFC_PFC_TIMER), -+ REG_RESERVED(ANA_IPT_OAM_MEP_CFG), -+ REG_RESERVED(ANA_IPT_IPT), -+ REG_RESERVED(ANA_PPT_PPT), -+ REG_RESERVED(ANA_FID_MAP_FID_MAP), -+ REG(ANA_AGGR_CFG, 0x008a68), -+ REG(ANA_CPUQ_CFG, 0x008a6c), -+ REG_RESERVED(ANA_CPUQ_CFG2), -+ REG(ANA_CPUQ_8021_CFG, 0x008a74), -+ REG(ANA_DSCP_CFG, 0x008ab4), -+ REG(ANA_DSCP_REWR_CFG, 0x008bb4), -+ REG(ANA_VCAP_RNG_TYPE_CFG, 0x008bf4), -+ REG(ANA_VCAP_RNG_VAL_CFG, 0x008c14), -+ REG_RESERVED(ANA_VRAP_CFG), -+ REG_RESERVED(ANA_VRAP_HDR_DATA), -+ REG_RESERVED(ANA_VRAP_HDR_MASK), -+ REG(ANA_DISCARD_CFG, 0x008c40), -+ REG(ANA_FID_CFG, 0x008c44), -+ REG(ANA_POL_PIR_CFG, 0x004000), -+ REG(ANA_POL_CIR_CFG, 0x004004), -+ REG(ANA_POL_MODE_CFG, 0x004008), -+ REG(ANA_POL_PIR_STATE, 0x00400c), -+ REG(ANA_POL_CIR_STATE, 0x004010), -+ REG_RESERVED(ANA_POL_STATE), -+ REG(ANA_POL_FLOWC, 0x008c48), -+ REG(ANA_POL_HYST, 0x008cb4), -+ REG_RESERVED(ANA_POL_MISC_CFG), -+}; -+ -+static const u32 vsc9959_qs_regmap[] = { -+ REG(QS_XTR_GRP_CFG, 0x000000), -+ REG(QS_XTR_RD, 0x000008), -+ REG(QS_XTR_FRM_PRUNING, 0x000010), -+ REG(QS_XTR_FLUSH, 0x000018), -+ REG(QS_XTR_DATA_PRESENT, 0x00001c), -+ REG(QS_XTR_CFG, 0x000020), -+ REG(QS_INJ_GRP_CFG, 0x000024), -+ REG(QS_INJ_WR, 0x00002c), -+ REG(QS_INJ_CTRL, 0x000034), -+ REG(QS_INJ_STATUS, 0x00003c), -+ REG(QS_INJ_ERR, 0x000040), -+ REG_RESERVED(QS_INH_DBG), -+}; -+ -+static const u32 vsc9959_s2_regmap[] = { -+ REG(S2_CORE_UPDATE_CTRL, 0x000000), -+ REG(S2_CORE_MV_CFG, 0x000004), -+ REG(S2_CACHE_ENTRY_DAT, 0x000008), -+ REG(S2_CACHE_MASK_DAT, 0x000108), -+ REG(S2_CACHE_ACTION_DAT, 0x000208), -+ REG(S2_CACHE_CNT_DAT, 0x000308), -+ REG(S2_CACHE_TG_DAT, 0x000388), -+}; -+ -+static const u32 vsc9959_qsys_regmap[] = { -+ REG(QSYS_PORT_MODE, 0x00f460), -+ REG(QSYS_SWITCH_PORT_MODE, 0x00f480), -+ REG(QSYS_STAT_CNT_CFG, 0x00f49c), -+ REG(QSYS_EEE_CFG, 0x00f4a0), -+ REG(QSYS_EEE_THRES, 0x00f4b8), -+ REG(QSYS_IGR_NO_SHARING, 0x00f4bc), -+ REG(QSYS_EGR_NO_SHARING, 0x00f4c0), -+ REG(QSYS_SW_STATUS, 0x00f4c4), -+ REG(QSYS_EXT_CPU_CFG, 0x00f4e0), -+ REG_RESERVED(QSYS_PAD_CFG), -+ REG(QSYS_CPU_GROUP_MAP, 0x00f4e8), -+ REG_RESERVED(QSYS_QMAP), -+ REG_RESERVED(QSYS_ISDX_SGRP), -+ REG_RESERVED(QSYS_TIMED_FRAME_ENTRY), -+ REG(QSYS_TFRM_MISC, 0x00f50c), -+ REG(QSYS_TFRM_PORT_DLY, 0x00f510), -+ REG(QSYS_TFRM_TIMER_CFG_1, 0x00f514), -+ REG(QSYS_TFRM_TIMER_CFG_2, 0x00f518), -+ REG(QSYS_TFRM_TIMER_CFG_3, 0x00f51c), -+ REG(QSYS_TFRM_TIMER_CFG_4, 0x00f520), -+ REG(QSYS_TFRM_TIMER_CFG_5, 0x00f524), -+ REG(QSYS_TFRM_TIMER_CFG_6, 0x00f528), -+ REG(QSYS_TFRM_TIMER_CFG_7, 0x00f52c), -+ REG(QSYS_TFRM_TIMER_CFG_8, 0x00f530), -+ REG(QSYS_RED_PROFILE, 0x00f534), -+ REG(QSYS_RES_QOS_MODE, 0x00f574), -+ REG(QSYS_RES_CFG, 0x00c000), -+ REG(QSYS_RES_STAT, 0x00c004), -+ REG(QSYS_EGR_DROP_MODE, 0x00f578), -+ REG(QSYS_EQ_CTRL, 0x00f57c), -+ REG_RESERVED(QSYS_EVENTS_CORE), -+ REG(QSYS_QMAXSDU_CFG_0, 0x00f584), -+ REG(QSYS_QMAXSDU_CFG_1, 0x00f5a0), -+ REG(QSYS_QMAXSDU_CFG_2, 0x00f5bc), -+ REG(QSYS_QMAXSDU_CFG_3, 0x00f5d8), -+ REG(QSYS_QMAXSDU_CFG_4, 0x00f5f4), -+ REG(QSYS_QMAXSDU_CFG_5, 0x00f610), -+ REG(QSYS_QMAXSDU_CFG_6, 0x00f62c), -+ REG(QSYS_QMAXSDU_CFG_7, 0x00f648), -+ REG(QSYS_PREEMPTION_CFG, 0x00f664), -+ REG_RESERVED(QSYS_CIR_CFG), -+ REG(QSYS_EIR_CFG, 0x000004), -+ REG(QSYS_SE_CFG, 0x000008), -+ REG(QSYS_SE_DWRR_CFG, 0x00000c), -+ REG_RESERVED(QSYS_SE_CONNECT), -+ REG(QSYS_SE_DLB_SENSE, 0x000040), -+ REG(QSYS_CIR_STATE, 0x000044), -+ REG(QSYS_EIR_STATE, 0x000048), -+ REG_RESERVED(QSYS_SE_STATE), -+ REG(QSYS_HSCH_MISC_CFG, 0x00f67c), -+ REG(QSYS_TAG_CONFIG, 0x00f680), -+ REG(QSYS_TAS_PARAM_CFG_CTRL, 0x00f698), -+ REG(QSYS_PORT_MAX_SDU, 0x00f69c), -+ REG(QSYS_PARAM_CFG_REG_1, 0x00f440), -+ REG(QSYS_PARAM_CFG_REG_2, 0x00f444), -+ REG(QSYS_PARAM_CFG_REG_3, 0x00f448), -+ REG(QSYS_PARAM_CFG_REG_4, 0x00f44c), -+ REG(QSYS_PARAM_CFG_REG_5, 0x00f450), -+ REG(QSYS_GCL_CFG_REG_1, 0x00f454), -+ REG(QSYS_GCL_CFG_REG_2, 0x00f458), -+ REG(QSYS_PARAM_STATUS_REG_1, 0x00f400), -+ REG(QSYS_PARAM_STATUS_REG_2, 0x00f404), -+ REG(QSYS_PARAM_STATUS_REG_3, 0x00f408), -+ REG(QSYS_PARAM_STATUS_REG_4, 0x00f40c), -+ REG(QSYS_PARAM_STATUS_REG_5, 0x00f410), -+ REG(QSYS_PARAM_STATUS_REG_6, 0x00f414), -+ REG(QSYS_PARAM_STATUS_REG_7, 0x00f418), -+ REG(QSYS_PARAM_STATUS_REG_8, 0x00f41c), -+ REG(QSYS_PARAM_STATUS_REG_9, 0x00f420), -+ REG(QSYS_GCL_STATUS_REG_1, 0x00f424), -+ REG(QSYS_GCL_STATUS_REG_2, 0x00f428), -+}; -+ -+static const u32 vsc9959_rew_regmap[] = { -+ REG(REW_PORT_VLAN_CFG, 0x000000), -+ REG(REW_TAG_CFG, 0x000004), -+ REG(REW_PORT_CFG, 0x000008), -+ REG(REW_DSCP_CFG, 0x00000c), -+ REG(REW_PCP_DEI_QOS_MAP_CFG, 0x000010), -+ REG(REW_PTP_CFG, 0x000050), -+ REG(REW_PTP_DLY1_CFG, 0x000054), -+ REG(REW_RED_TAG_CFG, 0x000058), -+ REG(REW_DSCP_REMAP_DP1_CFG, 0x000410), -+ REG(REW_DSCP_REMAP_CFG, 0x000510), -+ REG_RESERVED(REW_STAT_CFG), -+ REG_RESERVED(REW_REW_STICKY), -+ REG_RESERVED(REW_PPT), -+}; -+ -+static const u32 vsc9959_sys_regmap[] = { -+ REG(SYS_COUNT_RX_OCTETS, 0x000000), -+ REG(SYS_COUNT_RX_MULTICAST, 0x000008), -+ REG(SYS_COUNT_RX_SHORTS, 0x000010), -+ REG(SYS_COUNT_RX_FRAGMENTS, 0x000014), -+ REG(SYS_COUNT_RX_JABBERS, 0x000018), -+ REG(SYS_COUNT_RX_64, 0x000024), -+ REG(SYS_COUNT_RX_65_127, 0x000028), -+ REG(SYS_COUNT_RX_128_255, 0x00002c), -+ REG(SYS_COUNT_RX_256_1023, 0x000030), -+ REG(SYS_COUNT_RX_1024_1526, 0x000034), -+ REG(SYS_COUNT_RX_1527_MAX, 0x000038), -+ REG(SYS_COUNT_RX_LONGS, 0x000044), -+ REG(SYS_COUNT_TX_OCTETS, 0x000200), -+ REG(SYS_COUNT_TX_COLLISION, 0x000210), -+ REG(SYS_COUNT_TX_DROPS, 0x000214), -+ REG(SYS_COUNT_TX_64, 0x00021c), -+ REG(SYS_COUNT_TX_65_127, 0x000220), -+ REG(SYS_COUNT_TX_128_511, 0x000224), -+ REG(SYS_COUNT_TX_512_1023, 0x000228), -+ REG(SYS_COUNT_TX_1024_1526, 0x00022c), -+ REG(SYS_COUNT_TX_1527_MAX, 0x000230), -+ REG(SYS_COUNT_TX_AGING, 0x000278), -+ REG(SYS_RESET_CFG, 0x000e00), -+ REG(SYS_SR_ETYPE_CFG, 0x000e04), -+ REG(SYS_VLAN_ETYPE_CFG, 0x000e08), -+ REG(SYS_PORT_MODE, 0x000e0c), -+ REG(SYS_FRONT_PORT_MODE, 0x000e2c), -+ REG(SYS_FRM_AGING, 0x000e44), -+ REG(SYS_STAT_CFG, 0x000e48), -+ REG(SYS_SW_STATUS, 0x000e4c), -+ REG_RESERVED(SYS_MISC_CFG), -+ REG(SYS_REW_MAC_HIGH_CFG, 0x000e6c), -+ REG(SYS_REW_MAC_LOW_CFG, 0x000e84), -+ REG(SYS_TIMESTAMP_OFFSET, 0x000e9c), -+ REG(SYS_PAUSE_CFG, 0x000ea0), -+ REG(SYS_PAUSE_TOT_CFG, 0x000ebc), -+ REG(SYS_ATOP, 0x000ec0), -+ REG(SYS_ATOP_TOT_CFG, 0x000edc), -+ REG(SYS_MAC_FC_CFG, 0x000ee0), -+ REG(SYS_MMGT, 0x000ef8), -+ REG_RESERVED(SYS_MMGT_FAST), -+ REG_RESERVED(SYS_EVENTS_DIF), -+ REG_RESERVED(SYS_EVENTS_CORE), -+ REG_RESERVED(SYS_CNT), -+ REG(SYS_PTP_STATUS, 0x000f14), -+ REG(SYS_PTP_TXSTAMP, 0x000f18), -+ REG(SYS_PTP_NXT, 0x000f1c), -+ REG(SYS_PTP_CFG, 0x000f20), -+ REG(SYS_RAM_INIT, 0x000f24), -+ REG_RESERVED(SYS_CM_ADDR), -+ REG_RESERVED(SYS_CM_DATA_WR), -+ REG_RESERVED(SYS_CM_DATA_RD), -+ REG_RESERVED(SYS_CM_OP), -+ REG_RESERVED(SYS_CM_DATA), -+}; -+ -+static const u32 vsc9959_gcb_regmap[] = { -+ REG(GCB_SOFT_RST, 0x000004), -+}; -+ -+static const u32 *vsc9959_regmap[] = { -+ [ANA] = vsc9959_ana_regmap, -+ [QS] = vsc9959_qs_regmap, -+ [QSYS] = vsc9959_qsys_regmap, -+ [REW] = vsc9959_rew_regmap, -+ [SYS] = vsc9959_sys_regmap, -+ [S2] = vsc9959_s2_regmap, -+ [GCB] = vsc9959_gcb_regmap, -+}; -+ -+/* Addresses are relative to the PCI device's base address and -+ * will be fixed up at ioremap time. -+ */ -+static struct resource vsc9959_target_io_res[] = { -+ [ANA] = { -+ .start = 0x0280000, -+ .end = 0x028ffff, -+ .name = "ana", -+ }, -+ [QS] = { -+ .start = 0x0080000, -+ .end = 0x00800ff, -+ .name = "qs", -+ }, -+ [QSYS] = { -+ .start = 0x0200000, -+ .end = 0x021ffff, -+ .name = "qsys", -+ }, -+ [REW] = { -+ .start = 0x0030000, -+ .end = 0x003ffff, -+ .name = "rew", -+ }, -+ [SYS] = { -+ .start = 0x0010000, -+ .end = 0x001ffff, -+ .name = "sys", -+ }, -+ [S2] = { -+ .start = 0x0060000, -+ .end = 0x00603ff, -+ .name = "s2", -+ }, -+ [GCB] = { -+ .start = 0x0070000, -+ .end = 0x00701ff, -+ .name = "devcpu_gcb", -+ }, -+}; -+ -+static struct resource vsc9959_port_io_res[] = { -+ { -+ .start = 0x0100000, -+ .end = 0x010ffff, -+ .name = "port0", -+ }, -+ { -+ .start = 0x0110000, -+ .end = 0x011ffff, -+ .name = "port1", -+ }, -+ { -+ .start = 0x0120000, -+ .end = 0x012ffff, -+ .name = "port2", -+ }, -+ { -+ .start = 0x0130000, -+ .end = 0x013ffff, -+ .name = "port3", -+ }, -+ { -+ .start = 0x0140000, -+ .end = 0x014ffff, -+ .name = "port4", -+ }, -+ { -+ .start = 0x0150000, -+ .end = 0x015ffff, -+ .name = "port5", -+ }, -+}; -+ -+static const struct reg_field vsc9959_regfields[] = { -+ [ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 6, 6), -+ [ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 5), -+ [ANA_ANEVENTS_FLOOD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 30, 30), -+ [ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 26, 26), -+ [ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 24, 24), -+ [ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 23, 23), -+ [ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 22, 22), -+ [ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 21, 21), -+ [ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 20, 20), -+ [ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 19, 19), -+ [ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 18, 18), -+ [ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 17, 17), -+ [ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 15, 15), -+ [ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 14, 14), -+ [ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 13, 13), -+ [ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 12, 12), -+ [ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 11, 11), -+ [ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 10, 10), -+ [ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 9, 9), -+ [ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 8, 8), -+ [ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 7, 7), -+ [ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6), -+ [ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5), -+ [ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 4, 4), -+ [ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 3, 3), -+ [ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 2, 2), -+ [ANA_ANEVENTS_SEQ_GEN_ERR_0] = REG_FIELD(ANA_ANEVENTS, 1, 1), -+ [ANA_ANEVENTS_SEQ_GEN_ERR_1] = REG_FIELD(ANA_ANEVENTS, 0, 0), -+ [ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 16, 16), -+ [ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 11, 12), -+ [ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 10), -+ [SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 0, 0), -+ [GCB_SOFT_RST_SWC_RST] = REG_FIELD(GCB_SOFT_RST, 0, 0), -+}; -+ -+static const struct ocelot_stat_layout vsc9959_stats_layout[] = { -+ { .offset = 0x00, .name = "rx_octets", }, -+ { .offset = 0x01, .name = "rx_unicast", }, -+ { .offset = 0x02, .name = "rx_multicast", }, -+ { .offset = 0x03, .name = "rx_broadcast", }, -+ { .offset = 0x04, .name = "rx_shorts", }, -+ { .offset = 0x05, .name = "rx_fragments", }, -+ { .offset = 0x06, .name = "rx_jabbers", }, -+ { .offset = 0x07, .name = "rx_crc_align_errs", }, -+ { .offset = 0x08, .name = "rx_sym_errs", }, -+ { .offset = 0x09, .name = "rx_frames_below_65_octets", }, -+ { .offset = 0x0A, .name = "rx_frames_65_to_127_octets", }, -+ { .offset = 0x0B, .name = "rx_frames_128_to_255_octets", }, -+ { .offset = 0x0C, .name = "rx_frames_256_to_511_octets", }, -+ { .offset = 0x0D, .name = "rx_frames_512_to_1023_octets", }, -+ { .offset = 0x0E, .name = "rx_frames_1024_to_1526_octets", }, -+ { .offset = 0x0F, .name = "rx_frames_over_1526_octets", }, -+ { .offset = 0x10, .name = "rx_pause", }, -+ { .offset = 0x11, .name = "rx_control", }, -+ { .offset = 0x12, .name = "rx_longs", }, -+ { .offset = 0x13, .name = "rx_classified_drops", }, -+ { .offset = 0x14, .name = "rx_red_prio_0", }, -+ { .offset = 0x15, .name = "rx_red_prio_1", }, -+ { .offset = 0x16, .name = "rx_red_prio_2", }, -+ { .offset = 0x17, .name = "rx_red_prio_3", }, -+ { .offset = 0x18, .name = "rx_red_prio_4", }, -+ { .offset = 0x19, .name = "rx_red_prio_5", }, -+ { .offset = 0x1A, .name = "rx_red_prio_6", }, -+ { .offset = 0x1B, .name = "rx_red_prio_7", }, -+ { .offset = 0x1C, .name = "rx_yellow_prio_0", }, -+ { .offset = 0x1D, .name = "rx_yellow_prio_1", }, -+ { .offset = 0x1E, .name = "rx_yellow_prio_2", }, -+ { .offset = 0x1F, .name = "rx_yellow_prio_3", }, -+ { .offset = 0x20, .name = "rx_yellow_prio_4", }, -+ { .offset = 0x21, .name = "rx_yellow_prio_5", }, -+ { .offset = 0x22, .name = "rx_yellow_prio_6", }, -+ { .offset = 0x23, .name = "rx_yellow_prio_7", }, -+ { .offset = 0x24, .name = "rx_green_prio_0", }, -+ { .offset = 0x25, .name = "rx_green_prio_1", }, -+ { .offset = 0x26, .name = "rx_green_prio_2", }, -+ { .offset = 0x27, .name = "rx_green_prio_3", }, -+ { .offset = 0x28, .name = "rx_green_prio_4", }, -+ { .offset = 0x29, .name = "rx_green_prio_5", }, -+ { .offset = 0x2A, .name = "rx_green_prio_6", }, -+ { .offset = 0x2B, .name = "rx_green_prio_7", }, -+ { .offset = 0x80, .name = "tx_octets", }, -+ { .offset = 0x81, .name = "tx_unicast", }, -+ { .offset = 0x82, .name = "tx_multicast", }, -+ { .offset = 0x83, .name = "tx_broadcast", }, -+ { .offset = 0x84, .name = "tx_collision", }, -+ { .offset = 0x85, .name = "tx_drops", }, -+ { .offset = 0x86, .name = "tx_pause", }, -+ { .offset = 0x87, .name = "tx_frames_below_65_octets", }, -+ { .offset = 0x88, .name = "tx_frames_65_to_127_octets", }, -+ { .offset = 0x89, .name = "tx_frames_128_255_octets", }, -+ { .offset = 0x8B, .name = "tx_frames_256_511_octets", }, -+ { .offset = 0x8C, .name = "tx_frames_1024_1526_octets", }, -+ { .offset = 0x8D, .name = "tx_frames_over_1526_octets", }, -+ { .offset = 0x8E, .name = "tx_yellow_prio_0", }, -+ { .offset = 0x8F, .name = "tx_yellow_prio_1", }, -+ { .offset = 0x90, .name = "tx_yellow_prio_2", }, -+ { .offset = 0x91, .name = "tx_yellow_prio_3", }, -+ { .offset = 0x92, .name = "tx_yellow_prio_4", }, -+ { .offset = 0x93, .name = "tx_yellow_prio_5", }, -+ { .offset = 0x94, .name = "tx_yellow_prio_6", }, -+ { .offset = 0x95, .name = "tx_yellow_prio_7", }, -+ { .offset = 0x96, .name = "tx_green_prio_0", }, -+ { .offset = 0x97, .name = "tx_green_prio_1", }, -+ { .offset = 0x98, .name = "tx_green_prio_2", }, -+ { .offset = 0x99, .name = "tx_green_prio_3", }, -+ { .offset = 0x9A, .name = "tx_green_prio_4", }, -+ { .offset = 0x9B, .name = "tx_green_prio_5", }, -+ { .offset = 0x9C, .name = "tx_green_prio_6", }, -+ { .offset = 0x9D, .name = "tx_green_prio_7", }, -+ { .offset = 0x9E, .name = "tx_aged", }, -+ { .offset = 0x100, .name = "drop_local", }, -+ { .offset = 0x101, .name = "drop_tail", }, -+ { .offset = 0x102, .name = "drop_yellow_prio_0", }, -+ { .offset = 0x103, .name = "drop_yellow_prio_1", }, -+ { .offset = 0x104, .name = "drop_yellow_prio_2", }, -+ { .offset = 0x105, .name = "drop_yellow_prio_3", }, -+ { .offset = 0x106, .name = "drop_yellow_prio_4", }, -+ { .offset = 0x107, .name = "drop_yellow_prio_5", }, -+ { .offset = 0x108, .name = "drop_yellow_prio_6", }, -+ { .offset = 0x109, .name = "drop_yellow_prio_7", }, -+ { .offset = 0x10A, .name = "drop_green_prio_0", }, -+ { .offset = 0x10B, .name = "drop_green_prio_1", }, -+ { .offset = 0x10C, .name = "drop_green_prio_2", }, -+ { .offset = 0x10D, .name = "drop_green_prio_3", }, -+ { .offset = 0x10E, .name = "drop_green_prio_4", }, -+ { .offset = 0x10F, .name = "drop_green_prio_5", }, -+ { .offset = 0x110, .name = "drop_green_prio_6", }, -+ { .offset = 0x111, .name = "drop_green_prio_7", }, -+}; -+ -+#define VSC9959_INIT_TIMEOUT 50000 -+#define VSC9959_GCB_RST_SLEEP 100 -+#define VSC9959_SYS_RAMINIT_SLEEP 80 -+ -+static int vsc9959_gcb_soft_rst_status(struct ocelot *ocelot) -+{ -+ int val; -+ -+ regmap_field_read(ocelot->regfields[GCB_SOFT_RST_SWC_RST], &val); -+ -+ return val; -+} -+ -+static int vsc9959_sys_ram_init_status(struct ocelot *ocelot) -+{ -+ return ocelot_read(ocelot, SYS_RAM_INIT); -+} -+ -+static int vsc9959_reset(struct ocelot *ocelot) -+{ -+ int val, err; -+ -+ /* soft-reset the switch core */ -+ regmap_field_write(ocelot->regfields[GCB_SOFT_RST_SWC_RST], 1); -+ -+ err = readx_poll_timeout(vsc9959_gcb_soft_rst_status, ocelot, val, !val, -+ VSC9959_GCB_RST_SLEEP, VSC9959_INIT_TIMEOUT); -+ if (err) { -+ dev_err(ocelot->dev, "timeout: switch core reset\n"); -+ return err; -+ } -+ -+ /* initialize switch mem ~40us */ -+ ocelot_write(ocelot, SYS_RAM_INIT_RAM_INIT, SYS_RAM_INIT); -+ err = readx_poll_timeout(vsc9959_sys_ram_init_status, ocelot, val, !val, -+ VSC9959_SYS_RAMINIT_SLEEP, -+ VSC9959_INIT_TIMEOUT); -+ if (err) { -+ dev_err(ocelot->dev, "timeout: switch sram init\n"); -+ return err; -+ } -+ -+ /* enable switch core */ -+ regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1); -+ -+ return 0; -+} -+ -+static const struct ocelot_ops vsc9959_ops = { -+ .reset = vsc9959_reset, -+}; -+ -+struct felix_info felix_info_vsc9959 = { -+ .target_io_res = vsc9959_target_io_res, -+ .port_io_res = vsc9959_port_io_res, -+ .regfields = vsc9959_regfields, -+ .map = vsc9959_regmap, -+ .ops = &vsc9959_ops, -+ .stats_layout = vsc9959_stats_layout, -+ .num_stats = ARRAY_SIZE(vsc9959_stats_layout), -+ .shared_queue_sz = 128 * 1024, -+ .num_ports = 6, -+ .pci_bar = 4, -+}; diff --git a/target/linux/layerscape/patches-5.4/701-net-0264-net-dsa-felix-Fix-CPU-port-assignment-when-not-last-.patch b/target/linux/layerscape/patches-5.4/701-net-0264-net-dsa-felix-Fix-CPU-port-assignment-when-not-last-.patch deleted file mode 100644 index 972ec164f1..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0264-net-dsa-felix-Fix-CPU-port-assignment-when-not-last-.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 93a32fc4f43ae40a2140acd9258faada11a98ec0 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Mon, 18 Nov 2019 20:16:57 +0200 -Subject: [PATCH] net: dsa: felix: Fix CPU port assignment when not last port - -On the NXP LS1028A, there are 2 Ethernet links between the Felix switch -and the ENETC: -- eno2 <-> swp4, at 2.5G -- eno3 <-> swp5, at 1G - -Only one of the above Ethernet port pairs can act as a DSA link for -tagging. - -When adding initial support for the driver, it was tested only on the 1G -eno3 <-> swp5 interface, due to the necessity of using PHYLIB initially -(which treats fixed-link interfaces as emulated C22 PHYs, so it doesn't -support fixed-link speeds higher than 1G). - -After making PHYLINK work, it appears that swp4 still can't act as CPU -port. So it looks like ocelot_set_cpu_port was being called for swp4, -but then it was called again for swp5, overwriting the CPU port assigned -in the DT. - -It appears that when you call dsa_upstream_port for a port that is not -defined in the device tree (such as swp5 when using swp4 as CPU port), -its dp->cpu_dp pointer is not initialized by dsa_tree_setup_default_cpu, -and this trips up the following condition in dsa_upstream_port: - - if (!cpu_dp) - return port; - -So the moral of the story is: don't call dsa_upstream_port for a port -that is not defined in the device tree, and therefore its dsa_port -structure is not completely initialized (ds->num_ports is still 6). - -Fixes: 56051948773e ("net: dsa: ocelot: add driver for Felix switch family") -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/ocelot/felix.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/ocelot/felix.c -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -286,7 +286,7 @@ static int felix_setup(struct dsa_switch - for (port = 0; port < ds->num_ports; port++) { - ocelot_init_port(ocelot, port); - -- if (port == dsa_upstream_port(ds, port)) -+ if (dsa_is_cpu_port(ds, port)) - ocelot_set_cpu_port(ocelot, port, - OCELOT_TAG_PREFIX_NONE, - OCELOT_TAG_PREFIX_LONG); diff --git a/target/linux/layerscape/patches-5.4/701-net-0265-net-mscc-ocelot-export-ocelot_hwstamp_get-set-functi.patch b/target/linux/layerscape/patches-5.4/701-net-0265-net-mscc-ocelot-export-ocelot_hwstamp_get-set-functi.patch deleted file mode 100644 index d6b4e2bc13..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0265-net-mscc-ocelot-export-ocelot_hwstamp_get-set-functi.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 1f7c79cacbb448420929fc3b5261b9616b5d8f6d Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 20 Nov 2019 16:23:14 +0800 -Subject: [PATCH] net: mscc: ocelot: export ocelot_hwstamp_get/set functions - -Export ocelot_hwstamp_get/set functions so that DSA driver -is able to reuse them. - -Signed-off-by: Yangbo Lu -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 8 ++++---- - include/soc/mscc/ocelot.h | 2 ++ - 2 files changed, 6 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -1049,15 +1049,14 @@ static int ocelot_get_port_parent_id(str - return 0; - } - --static int ocelot_hwstamp_get(struct ocelot *ocelot, int port, -- struct ifreq *ifr) -+int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr) - { - return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config, - sizeof(ocelot->hwtstamp_config)) ? -EFAULT : 0; - } -+EXPORT_SYMBOL(ocelot_hwstamp_get); - --static int ocelot_hwstamp_set(struct ocelot *ocelot, int port, -- struct ifreq *ifr) -+int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; - struct hwtstamp_config cfg; -@@ -1114,6 +1113,7 @@ static int ocelot_hwstamp_set(struct oce - - return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; - } -+EXPORT_SYMBOL(ocelot_hwstamp_set); - - static int ocelot_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) - { ---- a/include/soc/mscc/ocelot.h -+++ b/include/soc/mscc/ocelot.h -@@ -533,6 +533,8 @@ int ocelot_fdb_del(struct ocelot *ocelot - int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, - bool untagged); - int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid); -+int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr); -+int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr); - int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts); - void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts); - diff --git a/target/linux/layerscape/patches-5.4/701-net-0266-net-mscc-ocelot-convert-to-use-ocelot_get_txtstamp.patch b/target/linux/layerscape/patches-5.4/701-net-0266-net-mscc-ocelot-convert-to-use-ocelot_get_txtstamp.patch deleted file mode 100644 index 31469bdb3c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0266-net-mscc-ocelot-convert-to-use-ocelot_get_txtstamp.patch +++ /dev/null @@ -1,202 +0,0 @@ -From dd8b8f6baf4917124ed268022f7ce4a08d35cc89 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 20 Nov 2019 16:23:15 +0800 -Subject: [PATCH] net: mscc: ocelot: convert to use ocelot_get_txtstamp() - -The method getting TX timestamp by reading timestamp FIFO and -matching skbs list is common for DSA Felix driver too. -So move code out of ocelot_board.c, convert to use -ocelot_get_txtstamp() function and export it. - -Signed-off-by: Yangbo Lu -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 62 ++++++++++++++++++++++++++++++-- - drivers/net/ethernet/mscc/ocelot.h | 6 ---- - drivers/net/ethernet/mscc/ocelot_board.c | 53 +-------------------------- - include/soc/mscc/ocelot.h | 9 ++++- - 4 files changed, 69 insertions(+), 61 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -661,7 +661,8 @@ out: - return NETDEV_TX_OK; - } - --void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts) -+static void ocelot_get_hwtimestamp(struct ocelot *ocelot, -+ struct timespec64 *ts) - { - unsigned long flags; - u32 val; -@@ -686,7 +687,64 @@ void ocelot_get_hwtimestamp(struct ocelo - - spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags); - } --EXPORT_SYMBOL(ocelot_get_hwtimestamp); -+ -+void ocelot_get_txtstamp(struct ocelot *ocelot) -+{ -+ int budget = OCELOT_PTP_QUEUE_SZ; -+ -+ while (budget--) { -+ struct skb_shared_hwtstamps shhwtstamps; -+ struct list_head *pos, *tmp; -+ struct sk_buff *skb = NULL; -+ struct ocelot_skb *entry; -+ struct ocelot_port *port; -+ struct timespec64 ts; -+ u32 val, id, txport; -+ -+ val = ocelot_read(ocelot, SYS_PTP_STATUS); -+ -+ /* Check if a timestamp can be retrieved */ -+ if (!(val & SYS_PTP_STATUS_PTP_MESS_VLD)) -+ break; -+ -+ WARN_ON(val & SYS_PTP_STATUS_PTP_OVFL); -+ -+ /* Retrieve the ts ID and Tx port */ -+ id = SYS_PTP_STATUS_PTP_MESS_ID_X(val); -+ txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val); -+ -+ /* Retrieve its associated skb */ -+ port = ocelot->ports[txport]; -+ -+ list_for_each_safe(pos, tmp, &port->skbs) { -+ entry = list_entry(pos, struct ocelot_skb, head); -+ if (entry->id != id) -+ continue; -+ -+ skb = entry->skb; -+ -+ list_del(pos); -+ kfree(entry); -+ } -+ -+ /* Next ts */ -+ ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT); -+ -+ if (unlikely(!skb)) -+ continue; -+ -+ /* Get the h/w timestamp */ -+ ocelot_get_hwtimestamp(ocelot, &ts); -+ -+ /* Set the timestamp into the skb */ -+ memset(&shhwtstamps, 0, sizeof(shhwtstamps)); -+ shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec); -+ skb_tstamp_tx(skb, &shhwtstamps); -+ -+ dev_kfree_skb_any(skb); -+ } -+} -+EXPORT_SYMBOL(ocelot_get_txtstamp); - - static int ocelot_mc_unsync(struct net_device *dev, const unsigned char *addr) - { ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -74,12 +74,6 @@ struct ocelot_port_private { - struct ocelot_port_tc tc; - }; - --struct ocelot_skb { -- struct list_head head; -- struct sk_buff *skb; -- u8 id; --}; -- - u32 ocelot_port_readl(struct ocelot_port *port, u32 reg); - void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg); - ---- a/drivers/net/ethernet/mscc/ocelot_board.c -+++ b/drivers/net/ethernet/mscc/ocelot_board.c -@@ -198,60 +198,9 @@ static irqreturn_t ocelot_xtr_irq_handle - - static irqreturn_t ocelot_ptp_rdy_irq_handler(int irq, void *arg) - { -- int budget = OCELOT_PTP_QUEUE_SZ; - struct ocelot *ocelot = arg; - -- while (budget--) { -- struct skb_shared_hwtstamps shhwtstamps; -- struct list_head *pos, *tmp; -- struct sk_buff *skb = NULL; -- struct ocelot_skb *entry; -- struct ocelot_port *port; -- struct timespec64 ts; -- u32 val, id, txport; -- -- val = ocelot_read(ocelot, SYS_PTP_STATUS); -- -- /* Check if a timestamp can be retrieved */ -- if (!(val & SYS_PTP_STATUS_PTP_MESS_VLD)) -- break; -- -- WARN_ON(val & SYS_PTP_STATUS_PTP_OVFL); -- -- /* Retrieve the ts ID and Tx port */ -- id = SYS_PTP_STATUS_PTP_MESS_ID_X(val); -- txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val); -- -- /* Retrieve its associated skb */ -- port = ocelot->ports[txport]; -- -- list_for_each_safe(pos, tmp, &port->skbs) { -- entry = list_entry(pos, struct ocelot_skb, head); -- if (entry->id != id) -- continue; -- -- skb = entry->skb; -- -- list_del(pos); -- kfree(entry); -- } -- -- /* Next ts */ -- ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT); -- -- if (unlikely(!skb)) -- continue; -- -- /* Get the h/w timestamp */ -- ocelot_get_hwtimestamp(ocelot, &ts); -- -- /* Set the timestamp into the skb */ -- memset(&shhwtstamps, 0, sizeof(shhwtstamps)); -- shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec); -- skb_tstamp_tx(skb, &shhwtstamps); -- -- dev_kfree_skb_any(skb); -- } -+ ocelot_get_txtstamp(ocelot); - - return IRQ_HANDLED; - } ---- a/include/soc/mscc/ocelot.h -+++ b/include/soc/mscc/ocelot.h -@@ -406,6 +406,13 @@ struct ocelot_ops { - int (*reset)(struct ocelot *ocelot); - }; - -+struct ocelot_skb { -+ struct list_head head; -+ struct sk_buff *skb; -+ u8 id; -+}; -+ -+ - struct ocelot_port { - struct ocelot *ocelot; - -@@ -536,6 +543,6 @@ int ocelot_vlan_del(struct ocelot *ocelo - int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr); - int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr); - int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts); --void ocelot_get_hwtimestamp(struct ocelot *ocelot, struct timespec64 *ts); -+void ocelot_get_txtstamp(struct ocelot *ocelot); - - #endif diff --git a/target/linux/layerscape/patches-5.4/701-net-0267-net-mscc-ocelot-convert-to-use-ocelot_port_add_txtst.patch b/target/linux/layerscape/patches-5.4/701-net-0267-net-mscc-ocelot-convert-to-use-ocelot_port_add_txtst.patch deleted file mode 100644 index 988c90e79d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0267-net-mscc-ocelot-convert-to-use-ocelot_port_add_txtst.patch +++ /dev/null @@ -1,93 +0,0 @@ -From c0c92f8d9a093faf64397b1874f074e071a5b4e2 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 20 Nov 2019 16:23:16 +0800 -Subject: [PATCH] net: mscc: ocelot: convert to use - ocelot_port_add_txtstamp_skb() - -Convert to use ocelot_port_add_txtstamp_skb() for adding skbs which -require TX timestamp into list. Export it so that DSA Felix driver -could reuse it too. - -Signed-off-by: Yangbo Lu -Reviewed-by: Andrew Lunn -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 43 ++++++++++++++++++++++++-------------- - include/soc/mscc/ocelot.h | 2 ++ - 2 files changed, 29 insertions(+), 16 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -575,6 +575,32 @@ static int ocelot_gen_ifh(u32 *ifh, stru - return 0; - } - -+int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port, -+ struct sk_buff *skb) -+{ -+ struct skb_shared_info *shinfo = skb_shinfo(skb); -+ struct ocelot *ocelot = ocelot_port->ocelot; -+ -+ if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP && -+ ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) { -+ struct ocelot_skb *oskb = -+ kzalloc(sizeof(struct ocelot_skb), GFP_ATOMIC); -+ -+ if (unlikely(!oskb)) -+ return -ENOMEM; -+ -+ shinfo->tx_flags |= SKBTX_IN_PROGRESS; -+ -+ oskb->skb = skb; -+ oskb->id = ocelot_port->ts_id % 4; -+ -+ list_add_tail(&oskb->head, &ocelot_port->skbs); -+ return 0; -+ } -+ return -ENODATA; -+} -+EXPORT_SYMBOL(ocelot_port_add_txtstamp_skb); -+ - static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) - { - struct ocelot_port_private *priv = netdev_priv(dev); -@@ -637,26 +663,11 @@ static int ocelot_port_xmit(struct sk_bu - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; - -- if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP && -- ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) { -- struct ocelot_skb *oskb = -- kzalloc(sizeof(struct ocelot_skb), GFP_ATOMIC); -- -- if (unlikely(!oskb)) -- goto out; -- -- skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; -- -- oskb->skb = skb; -- oskb->id = ocelot_port->ts_id % 4; -+ if (!ocelot_port_add_txtstamp_skb(ocelot_port, skb)) { - ocelot_port->ts_id++; -- -- list_add_tail(&oskb->head, &ocelot_port->skbs); -- - return NETDEV_TX_OK; - } - --out: - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } ---- a/include/soc/mscc/ocelot.h -+++ b/include/soc/mscc/ocelot.h -@@ -543,6 +543,8 @@ int ocelot_vlan_del(struct ocelot *ocelo - int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr); - int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr); - int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts); -+int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port, -+ struct sk_buff *skb); - void ocelot_get_txtstamp(struct ocelot *ocelot); - - #endif diff --git a/target/linux/layerscape/patches-5.4/701-net-0268-net-dsa-ocelot-define-PTP-registers-for-felix_vsc995.patch b/target/linux/layerscape/patches-5.4/701-net-0268-net-dsa-ocelot-define-PTP-registers-for-felix_vsc995.patch deleted file mode 100644 index c3f9263cf1..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0268-net-dsa-ocelot-define-PTP-registers-for-felix_vsc995.patch +++ /dev/null @@ -1,53 +0,0 @@ -From bd8d12b3bc7b5d63132a6d5da0890c6fc3bcad7e Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 20 Nov 2019 16:23:17 +0800 -Subject: [PATCH] net: dsa: ocelot: define PTP registers for felix_vsc9959 - -This patch is to define PTP registers for felix_vsc9959. - -Signed-off-by: Yangbo Lu -Reviewed-by: Florian Fainelli -Signed-off-by: David S. Miller ---- - drivers/net/dsa/ocelot/felix_vsc9959.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - ---- a/drivers/net/dsa/ocelot/felix_vsc9959.c -+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c -@@ -282,6 +282,16 @@ static const u32 vsc9959_sys_regmap[] = - REG_RESERVED(SYS_CM_DATA), - }; - -+static const u32 vsc9959_ptp_regmap[] = { -+ REG(PTP_PIN_CFG, 0x000000), -+ REG(PTP_PIN_TOD_SEC_MSB, 0x000004), -+ REG(PTP_PIN_TOD_SEC_LSB, 0x000008), -+ REG(PTP_PIN_TOD_NSEC, 0x00000c), -+ REG(PTP_CFG_MISC, 0x0000a0), -+ REG(PTP_CLK_CFG_ADJ_CFG, 0x0000a4), -+ REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8), -+}; -+ - static const u32 vsc9959_gcb_regmap[] = { - REG(GCB_SOFT_RST, 0x000004), - }; -@@ -293,6 +303,7 @@ static const u32 *vsc9959_regmap[] = { - [REW] = vsc9959_rew_regmap, - [SYS] = vsc9959_sys_regmap, - [S2] = vsc9959_s2_regmap, -+ [PTP] = vsc9959_ptp_regmap, - [GCB] = vsc9959_gcb_regmap, - }; - -@@ -330,6 +341,11 @@ static struct resource vsc9959_target_io - .end = 0x00603ff, - .name = "s2", - }, -+ [PTP] = { -+ .start = 0x0090000, -+ .end = 0x00900cb, -+ .name = "ptp", -+ }, - [GCB] = { - .start = 0x0070000, - .end = 0x00701ff, diff --git a/target/linux/layerscape/patches-5.4/701-net-0269-net-dsa-ocelot-add-hardware-timestamping-support-for.patch b/target/linux/layerscape/patches-5.4/701-net-0269-net-dsa-ocelot-add-hardware-timestamping-support-for.patch deleted file mode 100644 index d18f27e887..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0269-net-dsa-ocelot-add-hardware-timestamping-support-for.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 34bfb24b8ff5af09b014ea8530e1e8d89bb2a155 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 20 Nov 2019 16:23:18 +0800 -Subject: [PATCH] net: dsa: ocelot: add hardware timestamping support for Felix - -This patch is to reuse ocelot functions as possible to enable PTP -clock and to support hardware timestamping on Felix. -On TX path, timestamping works on packet which requires timestamp. -The injection header will be configured accordingly, and skb clone -requires timestamp will be added into a list. The TX timestamp -is final handled in threaded interrupt handler when PTP timestamp -FIFO is ready. -On RX path, timestamping is always working. The RX timestamp could -be got from extraction header. - -Signed-off-by: Yangbo Lu -Signed-off-by: David S. Miller ---- - drivers/net/dsa/ocelot/felix.c | 89 ++++++++++++++++++++++++++++++++++++++++++ - net/dsa/tag_ocelot.c | 14 ++++++- - 2 files changed, 102 insertions(+), 1 deletion(-) - ---- a/drivers/net/dsa/ocelot/felix.c -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -3,6 +3,7 @@ - */ - #include - #include -+#include - #include - #include - #include -@@ -303,6 +304,62 @@ static void felix_teardown(struct dsa_sw - ocelot_deinit(ocelot); - } - -+static int felix_hwtstamp_get(struct dsa_switch *ds, int port, -+ struct ifreq *ifr) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ return ocelot_hwstamp_get(ocelot, port, ifr); -+} -+ -+static int felix_hwtstamp_set(struct dsa_switch *ds, int port, -+ struct ifreq *ifr) -+{ -+ struct ocelot *ocelot = ds->priv; -+ -+ return ocelot_hwstamp_set(ocelot, port, ifr); -+} -+ -+static bool felix_rxtstamp(struct dsa_switch *ds, int port, -+ struct sk_buff *skb, unsigned int type) -+{ -+ struct skb_shared_hwtstamps *shhwtstamps; -+ struct ocelot *ocelot = ds->priv; -+ u8 *extraction = skb->data - ETH_HLEN - OCELOT_TAG_LEN; -+ u32 tstamp_lo, tstamp_hi; -+ struct timespec64 ts; -+ u64 tstamp, val; -+ -+ ocelot_ptp_gettime64(&ocelot->ptp_info, &ts); -+ tstamp = ktime_set(ts.tv_sec, ts.tv_nsec); -+ -+ packing(extraction, &val, 116, 85, OCELOT_TAG_LEN, UNPACK, 0); -+ tstamp_lo = (u32)val; -+ -+ tstamp_hi = tstamp >> 32; -+ if ((tstamp & 0xffffffff) < tstamp_lo) -+ tstamp_hi--; -+ -+ tstamp = ((u64)tstamp_hi << 32) | tstamp_lo; -+ -+ shhwtstamps = skb_hwtstamps(skb); -+ memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps)); -+ shhwtstamps->hwtstamp = tstamp; -+ return false; -+} -+ -+bool felix_txtstamp(struct dsa_switch *ds, int port, -+ struct sk_buff *clone, unsigned int type) -+{ -+ struct ocelot *ocelot = ds->priv; -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ -+ if (!ocelot_port_add_txtstamp_skb(ocelot_port, clone)) -+ return true; -+ -+ return false; -+} -+ - static const struct dsa_switch_ops felix_switch_ops = { - .get_tag_protocol = felix_get_tag_protocol, - .setup = felix_setup, -@@ -325,12 +382,33 @@ static const struct dsa_switch_ops felix - .port_vlan_filtering = felix_vlan_filtering, - .port_vlan_add = felix_vlan_add, - .port_vlan_del = felix_vlan_del, -+ .port_hwtstamp_get = felix_hwtstamp_get, -+ .port_hwtstamp_set = felix_hwtstamp_set, -+ .port_rxtstamp = felix_rxtstamp, -+ .port_txtstamp = felix_txtstamp, - }; - - static struct felix_info *felix_instance_tbl[] = { - [FELIX_INSTANCE_VSC9959] = &felix_info_vsc9959, - }; - -+static irqreturn_t felix_irq_handler(int irq, void *data) -+{ -+ struct ocelot *ocelot = (struct ocelot *)data; -+ -+ /* The INTB interrupt is used for both PTP TX timestamp interrupt -+ * and preemption status change interrupt on each port. -+ * -+ * - Get txtstamp if have -+ * - TODO: handle preemption. Without handling it, driver may get -+ * interrupt storm. -+ */ -+ -+ ocelot_get_txtstamp(ocelot); -+ -+ return IRQ_HANDLED; -+} -+ - static int felix_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) - { -@@ -372,6 +450,16 @@ static int felix_pci_probe(struct pci_de - - pci_set_master(pdev); - -+ err = devm_request_threaded_irq(&pdev->dev, pdev->irq, NULL, -+ &felix_irq_handler, IRQF_ONESHOT, -+ "felix-intb", ocelot); -+ if (err) { -+ dev_err(&pdev->dev, "Failed to request irq\n"); -+ goto err_alloc_irq; -+ } -+ -+ ocelot->ptp = 1; -+ - ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL); - if (!ds) { - err = -ENOMEM; -@@ -396,6 +484,7 @@ static int felix_pci_probe(struct pci_de - err_register_ds: - kfree(ds); - err_alloc_ds: -+err_alloc_irq: - err_alloc_felix: - kfree(felix); - err_dma: ---- a/net/dsa/tag_ocelot.c -+++ b/net/dsa/tag_ocelot.c -@@ -137,9 +137,11 @@ static struct sk_buff *ocelot_xmit(struc - struct net_device *netdev) - { - struct dsa_port *dp = dsa_slave_to_port(netdev); -- u64 bypass, dest, src, qos_class; -+ u64 bypass, dest, src, qos_class, rew_op; - struct dsa_switch *ds = dp->ds; - int port = dp->index; -+ struct ocelot *ocelot = ds->priv; -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; - u8 *injection; - - if (unlikely(skb_cow_head(skb, OCELOT_TAG_LEN) < 0)) { -@@ -161,6 +163,16 @@ static struct sk_buff *ocelot_xmit(struc - packing(injection, &src, 46, 43, OCELOT_TAG_LEN, PACK, 0); - packing(injection, &qos_class, 19, 17, OCELOT_TAG_LEN, PACK, 0); - -+ if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { -+ rew_op = ocelot_port->ptp_cmd; -+ if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) { -+ rew_op |= (ocelot_port->ts_id % 4) << 3; -+ ocelot_port->ts_id++; -+ } -+ -+ packing(injection, &rew_op, 125, 117, OCELOT_TAG_LEN, PACK, 0); -+ } -+ - return skb; - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0270-net-mscc-ocelot-avoid-incorrect-consuming-in-skbs-li.patch b/target/linux/layerscape/patches-5.4/701-net-0270-net-mscc-ocelot-avoid-incorrect-consuming-in-skbs-li.patch deleted file mode 100644 index 36fbffa2e1..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0270-net-mscc-ocelot-avoid-incorrect-consuming-in-skbs-li.patch +++ /dev/null @@ -1,25 +0,0 @@ -From e6208c23045ece890eebfe0564f73ccc52603867 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 27 Nov 2019 15:27:56 +0800 -Subject: [PATCH] net: mscc: ocelot: avoid incorrect consuming in skbs list - -Break the matching loop when find the matching skb for TX timestamp. -This is to avoid consuming more skbs incorrectly. The timestamp ID -is from 0 to 3 while the FIFO could support 128 timestamps at most. - -Signed-off-by: Yangbo Lu -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -736,6 +736,7 @@ void ocelot_get_txtstamp(struct ocelot * - - list_del(pos); - kfree(entry); -+ break; - } - - /* Next ts */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0271-net-mscc-ocelot-use-skb-queue-instead-of-skbs-list.patch b/target/linux/layerscape/patches-5.4/701-net-0271-net-mscc-ocelot-use-skb-queue-instead-of-skbs-list.patch deleted file mode 100644 index 4ed7c26770..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0271-net-mscc-ocelot-use-skb-queue-instead-of-skbs-list.patch +++ /dev/null @@ -1,158 +0,0 @@ -From e7e0b3b89da97e3186fbe3774a1ca9b77402d893 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 27 Nov 2019 15:27:57 +0800 -Subject: [PATCH] net: mscc: ocelot: use skb queue instead of skbs list - -Convert to use skb queue instead of the list of skbs. -The skb queue could provide protection with lock. - -Signed-off-by: Yangbo Lu -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/mscc/ocelot.c | 54 +++++++++++++------------------------- - include/soc/mscc/ocelot.h | 9 +------ - 2 files changed, 19 insertions(+), 44 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -583,18 +583,10 @@ int ocelot_port_add_txtstamp_skb(struct - - if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP && - ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) { -- struct ocelot_skb *oskb = -- kzalloc(sizeof(struct ocelot_skb), GFP_ATOMIC); -- -- if (unlikely(!oskb)) -- return -ENOMEM; -- - shinfo->tx_flags |= SKBTX_IN_PROGRESS; -- -- oskb->skb = skb; -- oskb->id = ocelot_port->ts_id % 4; -- -- list_add_tail(&oskb->head, &ocelot_port->skbs); -+ /* Store timestamp ID in cb[0] of sk_buff */ -+ skb->cb[0] = ocelot_port->ts_id % 4; -+ skb_queue_tail(&ocelot_port->tx_skbs, skb); - return 0; - } - return -ENODATA; -@@ -704,12 +696,11 @@ void ocelot_get_txtstamp(struct ocelot * - int budget = OCELOT_PTP_QUEUE_SZ; - - while (budget--) { -+ struct sk_buff *skb, *skb_tmp, *skb_match = NULL; - struct skb_shared_hwtstamps shhwtstamps; -- struct list_head *pos, *tmp; -- struct sk_buff *skb = NULL; -- struct ocelot_skb *entry; - struct ocelot_port *port; - struct timespec64 ts; -+ unsigned long flags; - u32 val, id, txport; - - val = ocelot_read(ocelot, SYS_PTP_STATUS); -@@ -727,22 +718,22 @@ void ocelot_get_txtstamp(struct ocelot * - /* Retrieve its associated skb */ - port = ocelot->ports[txport]; - -- list_for_each_safe(pos, tmp, &port->skbs) { -- entry = list_entry(pos, struct ocelot_skb, head); -- if (entry->id != id) -- continue; -+ spin_lock_irqsave(&port->tx_skbs.lock, flags); - -- skb = entry->skb; -- -- list_del(pos); -- kfree(entry); -+ skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) { -+ if (skb->cb[0] != id) -+ continue; -+ __skb_unlink(skb, &port->tx_skbs); -+ skb_match = skb; - break; - } - -+ spin_unlock_irqrestore(&port->tx_skbs.lock, flags); -+ - /* Next ts */ - ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT); - -- if (unlikely(!skb)) -+ if (unlikely(!skb_match)) - continue; - - /* Get the h/w timestamp */ -@@ -751,9 +742,9 @@ void ocelot_get_txtstamp(struct ocelot * - /* Set the timestamp into the skb */ - memset(&shhwtstamps, 0, sizeof(shhwtstamps)); - shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec); -- skb_tstamp_tx(skb, &shhwtstamps); -+ skb_tstamp_tx(skb_match, &shhwtstamps); - -- dev_kfree_skb_any(skb); -+ dev_kfree_skb_any(skb_match); - } - } - EXPORT_SYMBOL(ocelot_get_txtstamp); -@@ -2205,7 +2196,7 @@ void ocelot_init_port(struct ocelot *oce - { - struct ocelot_port *ocelot_port = ocelot->ports[port]; - -- INIT_LIST_HEAD(&ocelot_port->skbs); -+ skb_queue_head_init(&ocelot_port->tx_skbs); - - /* Basic L2 initialization */ - -@@ -2490,9 +2481,7 @@ EXPORT_SYMBOL(ocelot_init); - - void ocelot_deinit(struct ocelot *ocelot) - { -- struct list_head *pos, *tmp; - struct ocelot_port *port; -- struct ocelot_skb *entry; - int i; - - cancel_delayed_work(&ocelot->stats_work); -@@ -2504,14 +2493,7 @@ void ocelot_deinit(struct ocelot *ocelot - - for (i = 0; i < ocelot->num_phys_ports; i++) { - port = ocelot->ports[i]; -- -- list_for_each_safe(pos, tmp, &port->skbs) { -- entry = list_entry(pos, struct ocelot_skb, head); -- -- list_del(pos); -- dev_kfree_skb_any(entry->skb); -- kfree(entry); -- } -+ skb_queue_purge(&port->tx_skbs); - } - } - EXPORT_SYMBOL(ocelot_deinit); ---- a/include/soc/mscc/ocelot.h -+++ b/include/soc/mscc/ocelot.h -@@ -406,13 +406,6 @@ struct ocelot_ops { - int (*reset)(struct ocelot *ocelot); - }; - --struct ocelot_skb { -- struct list_head head; -- struct sk_buff *skb; -- u8 id; --}; -- -- - struct ocelot_port { - struct ocelot *ocelot; - -@@ -425,7 +418,7 @@ struct ocelot_port { - u16 vid; - - u8 ptp_cmd; -- struct list_head skbs; -+ struct sk_buff_head tx_skbs; - u8 ts_id; - }; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0272-net-mscc-ocelot-tsn-configuration-support.patch b/target/linux/layerscape/patches-5.4/701-net-0272-net-mscc-ocelot-tsn-configuration-support.patch deleted file mode 100644 index 953b479a20..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0272-net-mscc-ocelot-tsn-configuration-support.patch +++ /dev/null @@ -1,1986 +0,0 @@ -From eb5556db4c4fb8dff9a7b716c66a1ea3d3e696ce Mon Sep 17 00:00:00 2001 -From: Xiaoliang Yang -Date: Fri, 29 Nov 2019 11:02:43 +0800 -Subject: [PATCH] net: mscc: ocelot: tsn configuration support - -Support TSN configuration for ocelot switch. The TSN configuration -fucntions are based on tsn netlink interface, it can support Qbv, -Qbu, Qci, 802.1CB, and Qav configuration now. - -Signed-off-by: Xiaoliang Yang ---- - drivers/net/ethernet/mscc/Makefile | 1 + - drivers/net/ethernet/mscc/ocelot.c | 11 +- - drivers/net/ethernet/mscc/ocelot.h | 2 + - drivers/net/ethernet/mscc/ocelot_ana.h | 25 +- - drivers/net/ethernet/mscc/ocelot_dev_gmii.h | 153 +++ - drivers/net/ethernet/mscc/ocelot_tsn.c | 1572 +++++++++++++++++++++++++++ - drivers/net/ethernet/mscc/ocelot_tsn.h | 51 + - include/soc/mscc/ocelot.h | 52 +- - 8 files changed, 1857 insertions(+), 10 deletions(-) - create mode 100644 drivers/net/ethernet/mscc/ocelot_dev_gmii.h - create mode 100644 drivers/net/ethernet/mscc/ocelot_tsn.c - create mode 100644 drivers/net/ethernet/mscc/ocelot_tsn.h - ---- a/drivers/net/ethernet/mscc/Makefile -+++ b/drivers/net/ethernet/mscc/Makefile -@@ -2,4 +2,5 @@ - obj-$(CONFIG_MSCC_OCELOT_SWITCH) += mscc_ocelot_common.o - mscc_ocelot_common-y := ocelot.o ocelot_io.o - mscc_ocelot_common-y += ocelot_regs.o ocelot_tc.o ocelot_police.o ocelot_ace.o ocelot_flower.o -+mscc_ocelot_common-y += ocelot_tsn.o - obj-$(CONFIG_MSCC_OCELOT_SWITCH_OCELOT) += ocelot_board.o ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -780,7 +780,7 @@ static void ocelot_set_rx_mode(struct ne - * forwarded to the CPU port. - */ - val = GENMASK(ocelot->num_phys_ports - 1, 0); -- for (i = ocelot->num_phys_ports + 1; i < PGID_CPU; i++) -+ for (i = ocelot->num_phys_ports + 1; i < PGID_MCRED; i++) - ocelot_write_rix(ocelot, val, ANA_PGID_PGID, i); - - __dev_mc_sync(dev, ocelot_mc_sync, ocelot_mc_unsync); -@@ -2407,10 +2407,11 @@ int ocelot_init(struct ocelot *ocelot) - SYS_FRM_AGING_MAX_AGE(307692), SYS_FRM_AGING); - - /* Setup flooding PGIDs */ -- ocelot_write_rix(ocelot, ANA_FLOODING_FLD_MULTICAST(PGID_MC) | -- ANA_FLOODING_FLD_BROADCAST(PGID_MC) | -- ANA_FLOODING_FLD_UNICAST(PGID_UC), -- ANA_FLOODING, 0); -+ for (i = 0; i < 8; i++) -+ ocelot_write_rix(ocelot, ANA_FLOODING_FLD_MULTICAST(PGID_MC) | -+ ANA_FLOODING_FLD_BROADCAST(PGID_MC) | -+ ANA_FLOODING_FLD_UNICAST(PGID_UC), -+ ANA_FLOODING, i); - ocelot_write(ocelot, ANA_FLOODING_IPMC_FLD_MC6_DATA(PGID_MCIPV6) | - ANA_FLOODING_IPMC_FLD_MC6_CTRL(PGID_MC) | - ANA_FLOODING_IPMC_FLD_MC4_DATA(PGID_MCIPV4) | ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -27,11 +27,13 @@ - #include "ocelot_qs.h" - #include "ocelot_tc.h" - #include "ocelot_ptp.h" -+#include "ocelot_dev_gmii.h" - - #define PGID_AGGR 64 - #define PGID_SRC 80 - - /* Reserved PGIDs */ -+#define PGID_MCRED (PGID_AGGR - 25) - #define PGID_CPU (PGID_AGGR - 5) - #define PGID_UC (PGID_AGGR - 4) - #define PGID_MC (PGID_AGGR - 3) ---- a/drivers/net/ethernet/mscc/ocelot_ana.h -+++ b/drivers/net/ethernet/mscc/ocelot_ana.h -@@ -227,6 +227,11 @@ - #define ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(x) ((x) & GENMASK(1, 0)) - #define ANA_TABLES_SFIDACCESS_SFID_TBL_CMD_M GENMASK(1, 0) - -+#define SFIDACCESS_CMD_IDLE 0 -+#define SFIDACCESS_CMD_READ 1 -+#define SFIDACCESS_CMD_WRITE 2 -+#define SFIDACCESS_CMD_INIT 3 -+ - #define ANA_TABLES_SFIDTIDX_SGID_VALID BIT(26) - #define ANA_TABLES_SFIDTIDX_SGID(x) (((x) << 18) & GENMASK(25, 18)) - #define ANA_TABLES_SFIDTIDX_SGID_M GENMASK(25, 18) -@@ -252,15 +257,23 @@ - #define ANA_SG_CONFIG_REG_3_LIST_LENGTH_M GENMASK(18, 16) - #define ANA_SG_CONFIG_REG_3_LIST_LENGTH_X(x) (((x) & GENMASK(18, 16)) >> 16) - #define ANA_SG_CONFIG_REG_3_GATE_ENABLE BIT(20) --#define ANA_SG_CONFIG_REG_3_INIT_IPS(x) (((x) << 24) & GENMASK(27, 24)) --#define ANA_SG_CONFIG_REG_3_INIT_IPS_M GENMASK(27, 24) --#define ANA_SG_CONFIG_REG_3_INIT_IPS_X(x) (((x) & GENMASK(27, 24)) >> 24) --#define ANA_SG_CONFIG_REG_3_INIT_GATE_STATE BIT(28) -+#define ANA_SG_CONFIG_REG_3_INIT_IPS(x) (((x) << 21) & GENMASK(24, 21)) -+#define ANA_SG_CONFIG_REG_3_INIT_IPS_M GENMASK(24, 21) -+#define ANA_SG_CONFIG_REG_3_INIT_IPS_X(x) (((x) & GENMASK(24, 21)) >> 21) -+#define ANA_SG_CONFIG_REG_3_IPV_VALID BIT(24) -+#define ANA_SG_CONFIG_REG_3_IPV_INVALID(x) (((x) << 24) & GENMASK(24, 24)) -+#define ANA_SG_CONFIG_REG_3_INIT_IPV(x) (((x) << 21) & GENMASK(23, 21)) -+#define ANA_SG_CONFIG_REG_3_INIT_IPV_M GENMASK(23, 21) -+#define ANA_SG_CONFIG_REG_3_INIT_IPV_X(x) (((x) & GENMASK(23, 21)) >> 21) -+#define ANA_SG_CONFIG_REG_3_INIT_GATE_STATE BIT(25) - - #define ANA_SG_GCL_GS_CONFIG_RSZ 0x4 - - #define ANA_SG_GCL_GS_CONFIG_IPS(x) ((x) & GENMASK(3, 0)) - #define ANA_SG_GCL_GS_CONFIG_IPS_M GENMASK(3, 0) -+#define ANA_SG_GCL_GS_CONFIG_IPV_VALID BIT(3) -+#define ANA_SG_GCL_GS_CONFIG_IPV(x) ((x) & GENMASK(2, 0)) -+#define ANA_SG_GCL_GS_CONFIG_IPV_M GENMASK(2, 0) - #define ANA_SG_GCL_GS_CONFIG_GATE_STATE BIT(4) - - #define ANA_SG_GCL_TI_CONFIG_RSZ 0x4 -@@ -271,6 +284,10 @@ - #define ANA_SG_STATUS_REG_3_IPS(x) (((x) << 20) & GENMASK(23, 20)) - #define ANA_SG_STATUS_REG_3_IPS_M GENMASK(23, 20) - #define ANA_SG_STATUS_REG_3_IPS_X(x) (((x) & GENMASK(23, 20)) >> 20) -+#define ANA_SG_STATUS_REG_3_IPV_VALID BIT(23) -+#define ANA_SG_STATUS_REG_3_IPV(x) (((x) << 20) & GENMASK(22, 20)) -+#define ANA_SG_STATUS_REG_3_IPV_M GENMASK(22, 20) -+#define ANA_SG_STATUS_REG_3_IPV_X(x) (((x) & GENMASK(22, 20)) >> 20) - #define ANA_SG_STATUS_REG_3_CONFIG_PENDING BIT(24) - - #define ANA_PORT_VLAN_CFG_GSZ 0x100 ---- /dev/null -+++ b/drivers/net/ethernet/mscc/ocelot_dev_gmii.h -@@ -0,0 +1,153 @@ -+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ -+/* Microsemi Ocelot Switch driver -+ * -+ * Copyright (c) 2017 Microsemi Corporation -+ */ -+ -+#ifndef _MSCC_OCELOT_DEV_GMII_H_ -+#define _MSCC_OCELOT_DEV_GMII_H_ -+ -+#define DEV_GMII_PORT_MODE_CLOCK_CFG 0x0 -+ -+#define DEV_GMII_PORT_MODE_CLOCK_CFG_MAC_TX_RST BIT(5) -+#define DEV_GMII_PORT_MODE_CLOCK_CFG_MAC_RX_RST BIT(4) -+#define DEV_GMII_PORT_MODE_CLOCK_CFG_PORT_RST BIT(3) -+#define DEV_GMII_PORT_MODE_CLOCK_CFG_PHY_RST BIT(2) -+#define DEV_GMII_PORT_MODE_CLOCK_CFG_LINK_SPEED(x) ((x) & GENMASK(1, 0)) -+#define DEV_GMII_PORT_MODE_CLOCK_CFG_LINK_SPEED_M GENMASK(1, 0) -+ -+#define DEV_GMII_PORT_MODE_PORT_MISC 0x4 -+ -+#define DEV_GMII_PORT_MODE_PORT_MISC_MPLS_RX_ENA BIT(5) -+#define DEV_GMII_PORT_MODE_PORT_MISC_FWD_ERROR_ENA BIT(4) -+#define DEV_GMII_PORT_MODE_PORT_MISC_FWD_PAUSE_ENA BIT(3) -+#define DEV_GMII_PORT_MODE_PORT_MISC_FWD_CTRL_ENA BIT(2) -+#define DEV_GMII_PORT_MODE_PORT_MISC_GMII_LOOP_ENA BIT(1) -+#define DEV_GMII_PORT_MODE_PORT_MISC_DEV_LOOP_ENA BIT(0) -+ -+#define DEV_GMII_PORT_MODE_EVENTS 0x8 -+ -+#define DEV_GMII_PORT_MODE_EEE_CFG 0xc -+ -+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_ENA BIT(22) -+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_AGE(x) (((x) << 15) & GENMASK(21, 15)) -+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_AGE_M GENMASK(21, 15) -+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_AGE_X(x) (((x) & GENMASK(21, 15)) >> 15) -+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_WAKEUP(x) (((x) << 8) & GENMASK(14, 8)) -+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_WAKEUP_M GENMASK(14, 8) -+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_WAKEUP_X(x) (((x) & GENMASK(14, 8)) >> 8) -+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_HOLDOFF(x) (((x) << 1) & GENMASK(7, 1)) -+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_HOLDOFF_M GENMASK(7, 1) -+#define DEV_GMII_PORT_MODE_EEE_CFG_EEE_TIMER_HOLDOFF_X(x) (((x) & GENMASK(7, 1)) >> 1) -+#define DEV_GMII_PORT_MODE_EEE_CFG_PORT_LPI BIT(0) -+ -+#define DEV_GMII_PORT_MODE_RX_PATH_DELAY 0x10 -+ -+#define DEV_GMII_PORT_MODE_TX_PATH_DELAY 0x14 -+ -+#define DEV_GMII_PORT_MODE_PTP_PREDICT_CFG 0x18 -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_ENA_CFG 0x1c -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_ENA_CFG_RX_ENA BIT(4) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_ENA_CFG_TX_ENA BIT(0) -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_MODE_CFG 0x20 -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_MODE_CFG_FC_WORD_SYNC_ENA BIT(8) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_MODE_CFG_GIGA_MODE_ENA BIT(4) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_MODE_CFG_FDX_ENA BIT(0) -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_MAXLEN_CFG 0x24 -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG 0x28 -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_TAG_ID(x) (((x) << 16) & GENMASK(31, 16)) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_TAG_ID_M GENMASK(31, 16) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_TAG_ID_X(x) (((x) & GENMASK(31, 16)) >> 16) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_PB_ENA BIT(1) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_VLAN_AWR_ENA BIT(0) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA BIT(2) -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_ADV_CHK_CFG 0x2c -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_ADV_CHK_CFG_LEN_DROP_ENA BIT(0) -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG 0x30 -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RESTORE_OLD_IPG_CHECK BIT(17) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_REDUCED_TX_IFG BIT(16) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_TX_IFG(x) (((x) << 8) & GENMASK(12, 8)) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_TX_IFG_M GENMASK(12, 8) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_TX_IFG_X(x) (((x) & GENMASK(12, 8)) >> 8) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RX_IFG2(x) (((x) << 4) & GENMASK(7, 4)) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RX_IFG2_M GENMASK(7, 4) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RX_IFG2_X(x) (((x) & GENMASK(7, 4)) >> 4) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RX_IFG1(x) ((x) & GENMASK(3, 0)) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_IFG_CFG_RX_IFG1_M GENMASK(3, 0) -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG 0x34 -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_BYPASS_COL_SYNC BIT(26) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_OB_ENA BIT(25) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_WEXC_DIS BIT(24) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_SEED(x) (((x) << 16) & GENMASK(23, 16)) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_SEED_M GENMASK(23, 16) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_SEED_X(x) (((x) & GENMASK(23, 16)) >> 16) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_SEED_LOAD BIT(12) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_RETRY_AFTER_EXC_COL_ENA BIT(8) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_LATE_COL_POS(x) ((x) & GENMASK(6, 0)) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_HDX_CFG_LATE_COL_POS_M GENMASK(6, 0) -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_DBG_CFG 0x38 -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_DBG_CFG_TBI_MODE BIT(4) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_DBG_CFG_IFG_CRS_EXT_CHK_ENA BIT(0) -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_FC_MAC_LOW_CFG 0x3c -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_FC_MAC_HIGH_CFG 0x40 -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY 0x44 -+ -+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_RX_IPG_SHRINK_STICKY BIT(9) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_RX_PREAM_SHRINK_STICKY BIT(8) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_RX_CARRIER_EXT_STICKY BIT(7) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_RX_CARRIER_EXT_ERR_STICKY BIT(6) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_RX_JUNK_STICKY BIT(5) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_TX_RETRANSMIT_STICKY BIT(4) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_TX_JAM_STICKY BIT(3) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_TX_FIFO_OFLW_STICKY BIT(2) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_TX_FRM_LEN_OVR_STICKY BIT(1) -+#define DEV_GMII_MAC_CFG_STATUS_MAC_STICKY_TX_ABORT_STICKY BIT(0) -+ -+#define DEV_GMII_MM_CONFIG_ENABLE_CONFIG 0x48 -+ -+#define DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_RX_ENA BIT(0) -+#define DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_TX_ENA BIT(4) -+#define DEV_GMII_MM_CONFIG_ENABLE_CONFIG_KEEP_S_AFTER_D BIT(8) -+ -+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG 0x4c -+ -+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_DIS BIT(0) -+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_TIME(x) (((x) << 4) & GENMASK(11, 4)) -+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_TIME_M GENMASK(11, 4) -+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_PRM_VERIFY_TIME_X(x) (((x) & GENMASK(11, 4)) >> 4) -+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_VERIF_TIMER_UNITS(x) (((x) << 12) & GENMASK(13, 12)) -+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_VERIF_TIMER_UNITS_M GENMASK(13, 12) -+#define DEV_GMII_MM_CONFIG_VERIF_CONFIG_VERIF_TIMER_UNITS_X(x) (((x) & GENMASK(13, 12)) >> 12) -+ -+#define DEV_GMII_MM_STATISTICS_MM_STATUS 0x50 -+ -+#define DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_ACTIVE_STATUS BIT(0) -+#define DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_ACTIVE_STICKY BIT(4) -+#define DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_VERIFY_STATE(x) (((x) << 8) & GENMASK(10, 8)) -+#define DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_VERIFY_STATE_M GENMASK(10, 8) -+#define DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_VERIFY_STATE_X(x) (((x) & GENMASK(10, 8)) >> 8) -+#define DEV_GMII_MM_STATISTICS_MM_STATUS_UNEXP_RX_PFRM_STICKY BIT(12) -+#define DEV_GMII_MM_STATISTICS_MM_STATUS_UNEXP_TX_PFRM_STICKY BIT(16) -+#define DEV_GMII_MM_STATISTICS_MM_STATUS_MM_RX_FRAME_STATUS BIT(20) -+#define DEV_GMII_MM_STATISTICS_MM_STATUS_MM_TX_FRAME_STATUS BIT(24) -+#define DEV_GMII_MM_STATISTICS_MM_STATUS_MM_TX_PRMPT_STATUS BIT(28) -+ -+#endif ---- /dev/null -+++ b/drivers/net/ethernet/mscc/ocelot_tsn.c -@@ -0,0 +1,1572 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* Felix Switch TSN driver -+ * -+ * Copyright (c) 2018 Microsemi Corporation -+ * Copyright 2018-2019 NXP -+ */ -+ -+#include -+#include -+#include -+#include -+#include "ocelot.h" -+#include -+#include "ocelot_ana.h" -+#include "ocelot_qsys.h" -+#include "ocelot_rew.h" -+#include "ocelot_dev_gmii.h" -+#include "ocelot_tsn.h" -+ -+#define MSCC_NUM_OUT_PORT 4 /* Number of physical output ports */ -+#define SE_IX_PORT 64 -+ -+/* MSCC TSN parameters limited */ -+#define NUM_MSCC_QOS_PRIO 8 -+#define MSCC_PSFP_SFID_NUM 176 -+#define MSCC_FRER_SSID_NUM 128 -+ -+/* Using the max number of MSCC_PSFP_SFID_NUM and MSCC_FRER_SSID_NUM */ -+#define MSCC_STREAM_HANDLE_NUM MSCC_PSFP_SFID_NUM -+ -+int streamhandle_map[MSCC_STREAM_HANDLE_NUM] = {0}; -+static struct mscc_switch_capa capa __ro_after_init = { -+ .num_tas_gcl = 64, -+ .tas_ct_min = 100, -+ .tas_ct_max = 1000000000, -+ .tas_cte_max = 999999999, -+ .tas_it_max = 999999999, -+ .tas_it_min = 1000, -+ .num_hsch = 72, -+ .num_psfp_sfid = MSCC_PSFP_SFID_NUM, -+ .num_psfp_sgid = 184, -+ .psfp_fmi_max = 246, -+ .psfp_fmi_min = 63, -+ .num_sgi_gcl = 4, -+ .sgi_ct_min = 5000, -+ .sgi_ct_max = 1000000000, -+ .sgi_cte_max = 999999999, -+ .qos_pol_max = 383, -+ /* Maximum allowed value of committed burst size(CBS) is 240 KB */ -+ .pol_cbs_max = 60, -+ /* Maximum allowed value of excess burst size(EBS) is 240 KB */ -+ .pol_pbs_max = 60, -+ .num_frer_ssid = MSCC_FRER_SSID_NUM, -+ .frer_seq_len_min = 1, -+ .frer_seq_len_max = 28, -+ .frer_his_len_min = 1, -+ .frer_his_len_max = 32, -+ .qos_dscp_max = 63, -+ .qos_cos_max = NUM_MSCC_QOS_PRIO - 1, -+ .qos_dp_max = 1, -+}; -+ -+static int qos_port_tas_gcl_set(struct ocelot *ocelot, const u8 gcl_ix, -+ struct tsn_qbv_entry *control_list) -+{ -+ if (gcl_ix >= capa.num_tas_gcl) { -+ dev_err(ocelot->dev, "Invalid gcl ix %u\n", gcl_ix); -+ return -EINVAL; -+ } -+ if (control_list->time_interval < capa.tas_it_min || -+ control_list->time_interval > capa.tas_it_max) { -+ dev_err(ocelot->dev, "Invalid time_interval %u\n", -+ control_list->time_interval); -+ -+ return -EINVAL; -+ } -+ -+ ocelot_write(ocelot, -+ QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM(gcl_ix) | -+ QSYS_GCL_CFG_REG_1_GATE_STATE(control_list->gate_state), -+ QSYS_GCL_CFG_REG_1); -+ -+ ocelot_write(ocelot, -+ control_list->time_interval, -+ QSYS_GCL_CFG_REG_2); -+ -+ return 0; -+} -+ -+static u32 tas_read_status(struct ocelot *ocelot) -+{ -+ u32 val; -+ -+ val = ocelot_read(ocelot, QSYS_TAS_PARAM_CFG_CTRL); -+ -+ return val; -+} -+ -+int ocelot_qbv_set(struct ocelot *ocelot, int port_id, -+ struct tsn_qbv_conf *shaper_config) -+{ -+ struct tsn_qbv_basic *admin_basic = &shaper_config->admin; -+ struct tsn_qbv_entry *control_list = admin_basic->control_list; -+ u32 base_time_nsec = admin_basic->base_time % 1000000000; -+ u64 base_time_sec = admin_basic->base_time / 1000000000; -+ u64 cur_time; -+ u32 val; -+ u8 speed; -+ int i; -+ int ret; -+ -+ if (admin_basic->control_list_length > capa.num_tas_gcl) { -+ dev_err(ocelot->dev, -+ "Invalid admin_control_list_length %u\n", -+ admin_basic->control_list_length); -+ return -EINVAL; -+ } -+ -+ if ((admin_basic->cycle_time < capa.tas_ct_min || -+ admin_basic->cycle_time > capa.tas_ct_max) && -+ shaper_config->gate_enabled) { -+ dev_err(ocelot->dev, "Invalid admin_cycle_time %u ns\n", -+ admin_basic->cycle_time); -+ return -EINVAL; -+ } -+ if (admin_basic->cycle_time_extension > capa.tas_cte_max) { -+ dev_err(ocelot->dev, -+ "Invalid admin_cycle_time_extension %u\n", -+ admin_basic->cycle_time_extension); -+ return -EINVAL; -+ } -+ -+ cur_time = ocelot_read(ocelot, PTP_CUR_SEC_MSB); -+ cur_time = cur_time << 32; -+ cur_time += ocelot_read(ocelot, PTP_CUR_SEC_LSB); -+ -+ if (base_time_sec < cur_time) { -+ base_time_sec = cur_time; -+ base_time_nsec = ocelot_read(ocelot, PTP_CUR_NSEC); -+ } -+ -+ /* Select port */ -+ ocelot_rmw(ocelot, -+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(port_id), -+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M, -+ QSYS_TAS_PARAM_CFG_CTRL); -+ -+ val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8); -+ if (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING) { -+ ocelot_rmw_rix(ocelot, 0, QSYS_TAG_CONFIG_ENABLE, -+ QSYS_TAG_CONFIG, port_id); -+ } -+ -+ if (!shaper_config->gate_enabled) -+ admin_basic->gate_states = 0xff; -+ -+ val = ocelot_read_gix(ocelot, ANA_PFC_PFC_CFG, port_id); -+ speed = ANA_PFC_PFC_CFG_FC_LINK_SPEED(val); -+ -+ ocelot_rmw_rix(ocelot, -+ (shaper_config->gate_enabled ? -+ QSYS_TAG_CONFIG_ENABLE : 0) | -+ QSYS_TAG_CONFIG_INIT_GATE_STATE(admin_basic->gate_states) | -+ QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES(0xff) | -+ QSYS_TAG_CONFIG_LINK_SPEED(speed), -+ QSYS_TAG_CONFIG_ENABLE | -+ QSYS_TAG_CONFIG_INIT_GATE_STATE_M | -+ QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_M | -+ QSYS_TAG_CONFIG_LINK_SPEED_M, -+ QSYS_TAG_CONFIG, -+ port_id); -+ -+ ocelot_write_rix(ocelot, shaper_config->maxsdu, -+ QSYS_PORT_MAX_SDU, port_id); -+ /* TODO: add queue max SDU set */ -+ -+ if (shaper_config->gate_enabled) { -+ ocelot_write(ocelot, base_time_nsec, -+ QSYS_PARAM_CFG_REG_1); -+ -+ ocelot_write(ocelot, base_time_sec & GENMASK(31, 0), -+ QSYS_PARAM_CFG_REG_2); -+ -+ ocelot_write(ocelot, -+ QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB(base_time_sec >> 32) | -+ QSYS_PARAM_CFG_REG_3_LIST_LENGTH(admin_basic->control_list_length), -+ QSYS_PARAM_CFG_REG_3); -+ -+ ocelot_write(ocelot, admin_basic->cycle_time, -+ QSYS_PARAM_CFG_REG_4); -+ -+ ocelot_write(ocelot, admin_basic->cycle_time_extension, -+ QSYS_PARAM_CFG_REG_5); -+ -+ for (i = 0; i < admin_basic->control_list_length; i++) { -+ qos_port_tas_gcl_set(ocelot, i, control_list); -+ control_list++; -+ } -+ -+ /* Start configuration change */ -+ ocelot_rmw(ocelot, -+ QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE, -+ QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE, -+ QSYS_TAS_PARAM_CFG_CTRL); -+ -+ ret = readx_poll_timeout(tas_read_status, ocelot, val, -+ !(QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE -+ & val), 10, 100000); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+int ocelot_qbv_get(struct ocelot *ocelot, int port_id, -+ struct tsn_qbv_conf *shaper_config) -+{ -+ u32 val, reg; -+ int i; -+ u32 base_timel; -+ u32 base_timeh; -+ struct tsn_qbv_basic *admin = &shaper_config->admin; -+ struct tsn_qbv_entry *list; -+ -+ ocelot_rmw(ocelot, -+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(port_id), -+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M, -+ QSYS_TAS_PARAM_CFG_CTRL); -+ -+ val = ocelot_read_rix(ocelot, QSYS_TAG_CONFIG, port_id); -+ shaper_config->gate_enabled = (val & QSYS_TAG_CONFIG_ENABLE); -+ admin->gate_states = QSYS_TAG_CONFIG_INIT_GATE_STATE_X(val); -+ -+ base_timel = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_1); -+ base_timeh = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_2); -+ reg = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_3); -+ admin->base_time = base_timeh | -+ (((u64)QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB(reg)) << 32); -+ -+ admin->base_time = (admin->base_time * 1000000000) + base_timel; -+ -+ admin->control_list_length = -+ QSYS_PARAM_CFG_REG_3_LIST_LENGTH_X(reg); -+ -+ admin->cycle_time = ocelot_read(ocelot, QSYS_PARAM_CFG_REG_4); -+ admin->cycle_time_extension = -+ ocelot_read(ocelot, QSYS_PARAM_CFG_REG_5); -+ -+ list = kmalloc_array(admin->control_list_length, -+ sizeof(struct tsn_qbv_entry), GFP_KERNEL); -+ admin->control_list = list; -+ -+ for (i = 0; i < admin->control_list_length; i++) { -+ ocelot_rmw(ocelot, -+ QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM(i), -+ QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM_M, -+ QSYS_GCL_CFG_REG_1); -+ -+ list->time_interval = -+ ocelot_read(ocelot, QSYS_GCL_CFG_REG_2); -+ -+ reg = ocelot_read(ocelot, QSYS_GCL_CFG_REG_1); -+ list->gate_state = QSYS_GCL_CFG_REG_1_GATE_STATE_X(reg); -+ -+ list++; -+ } -+ -+ return 0; -+} -+ -+static int qbv_get_gatelist(struct ocelot *ocelot, -+ struct tsn_qbv_basic *oper) -+{ -+ u32 base_timel; -+ u32 base_timeh; -+ u32 val; -+ struct tsn_qbv_entry *glist; -+ int i; -+ -+ base_timel = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_1); -+ base_timeh = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_2); -+ val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_3); -+ oper->base_time = base_timeh; -+ oper->base_time += -+ ((u64)QSYS_PARAM_STATUS_REG_3_BASE_TIME_SEC_MSB(val)) << -+ 32; -+ oper->base_time = (oper->base_time * 1000000000) + base_timel; -+ -+ oper->control_list_length = -+ QSYS_PARAM_STATUS_REG_3_LIST_LENGTH_X(val); -+ -+ oper->cycle_time = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_4); -+ oper->cycle_time_extension = ocelot_read(ocelot, -+ QSYS_PARAM_STATUS_REG_5); -+ -+ val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8); -+ oper->gate_states = QSYS_PARAM_STATUS_REG_8_OPER_GATE_STATE_X(val); -+ -+ glist = kmalloc_array(oper->control_list_length, -+ sizeof(struct tsn_qbv_entry), GFP_KERNEL); -+ -+ oper->control_list = glist; -+ -+ for (i = 0; i < oper->control_list_length; i++) { -+ ocelot_rmw(ocelot, -+ QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM(i), -+ QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM_M, -+ QSYS_GCL_STATUS_REG_1); -+ -+ val = ocelot_read(ocelot, QSYS_GCL_STATUS_REG_2); -+ glist->time_interval = val; -+ val = ocelot_read(ocelot, QSYS_GCL_STATUS_REG_1); -+ glist->gate_state = -+ QSYS_GCL_STATUS_REG_1_GATE_STATE_X(val); -+ -+ glist++; -+ } -+ -+ return 0; -+} -+ -+int ocelot_qbv_get_status(struct ocelot *ocelot, int port_id, -+ struct tsn_qbv_status *qbvstatus) -+{ -+ struct tsn_qbv_basic *oper = &qbvstatus->oper; -+ u32 val; -+ ptptime_t cur_time; -+ -+ ocelot_rmw(ocelot, -+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(port_id), -+ QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M, -+ QSYS_TAS_PARAM_CFG_CTRL); -+ -+ qbvstatus->supported_list_max = capa.num_tas_gcl; -+ -+ val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8); -+ qbvstatus->config_pending = -+ (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING) ? 1 : 0; -+ -+ qbvstatus->config_change_time = -+ ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_7); -+ -+ qbvstatus->config_change_time += -+ ((u64)QSYS_PARAM_STATUS_REG_8_CFG_CHG_TIME_SEC_MSB(val)) << -+ 32; -+ -+ qbvstatus->config_change_time = -+ (qbvstatus->config_change_time * 1000000000) + -+ ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_6); -+ -+ qbvstatus->config_change_error = -+ ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_9); -+ -+ cur_time = ocelot_read(ocelot, PTP_CUR_SEC_MSB); -+ cur_time = cur_time << 32; -+ cur_time += ocelot_read(ocelot, PTP_CUR_SEC_LSB); -+ cur_time = (cur_time * 1000000000) + -+ ocelot_read(ocelot, PTP_CUR_NSEC); -+ -+ qbvstatus->current_time = cur_time; -+ qbv_get_gatelist(ocelot, oper); -+ -+ return 0; -+} -+ -+int ocelot_cut_thru_set(struct ocelot *ocelot, int port_id, u8 cut_thru) -+{ -+ ocelot_write_rix(ocelot, cut_thru, ANA_CUT_THRU_CFG, port_id); -+ -+ return 0; -+} -+ -+static int qos_shaper_conf_set(struct ocelot *ocelot, int port, -+ u32 port_ix, u8 percent) -+{ -+ u32 val; -+ int speed; -+ u32 cbs = 0; -+ u32 cir = 0; -+ -+ if (percent > 100) { -+ dev_err(ocelot->dev, "percentage %d larger than 100\n", -+ percent); -+ return -EINVAL; -+ } -+ if (port_ix >= capa.num_hsch) { -+ dev_err(ocelot->dev, -+ "CIR_CFG: id %d is exceed num of HSCH instance\n", -+ port_ix); -+ return -EINVAL; -+ } -+ -+ val = ocelot_read_gix(ocelot, ANA_PFC_PFC_CFG, port); -+ speed = ANA_PFC_PFC_CFG_FC_LINK_SPEED(val); -+ switch (speed) { -+ case OCELOT_SPEED_10: -+ cir = 10000; -+ break; -+ case OCELOT_SPEED_100: -+ cir = 100000; -+ break; -+ case OCELOT_SPEED_1000: -+ cir = 1000000; -+ break; -+ case OCELOT_SPEED_2500: -+ cir = 2500000; -+ break; -+ } -+ -+ cir = cir * percent / 100; -+ cir = DIV_ROUND_UP(cir, 100); /* Rate unit is 100 kbps */ -+ cir = (cir ? cir : 1); /* Avoid using zero rate */ -+ cbs = DIV_ROUND_UP(cbs, 4096); /* Burst unit is 4kB */ -+ cbs = (cbs ? cbs : 1); /* Avoid using zero burst size */ -+ cir = min_t(u32, GENMASK(15, 0), cir); -+ cbs = min_t(u32, GENMASK(6, 0), cbs); -+ ocelot_write_gix(ocelot, -+ QSYS_CIR_CFG_CIR_RATE(cir) | -+ QSYS_CIR_CFG_CIR_BURST(cbs), -+ QSYS_CIR_CFG, -+ port_ix); -+ -+ return 0; -+} -+ -+static int qos_shaper_conf_get(struct ocelot *ocelot, int port, -+ u32 port_ix) -+{ -+ u32 val; -+ u32 bandwidth = 0; -+ u32 cir = 0; -+ int percentage; -+ int speed; -+ -+ if (port_ix >= capa.num_hsch) { -+ dev_err(ocelot->dev, -+ "CIR_CFG: id %d is exceed num of HSCH instance\n", -+ port_ix); -+ return -EINVAL; -+ } -+ -+ val = ocelot_read_gix(ocelot, ANA_PFC_PFC_CFG, port); -+ speed = ANA_PFC_PFC_CFG_FC_LINK_SPEED(val); -+ switch (speed) { -+ case OCELOT_SPEED_10: -+ bandwidth = 10000; -+ break; -+ case OCELOT_SPEED_100: -+ bandwidth = 100000; -+ break; -+ case OCELOT_SPEED_1000: -+ bandwidth = 1000000; -+ break; -+ case OCELOT_SPEED_2500: -+ bandwidth = 2500000; -+ break; -+ } -+ -+ val = ocelot_read_gix(ocelot, QSYS_CIR_CFG, port_ix); -+ -+ cir = QSYS_CIR_CFG_CIR_RATE_X(val); -+ cir *= 100; -+ percentage = cir * 100 / bandwidth; -+ -+ return percentage; -+} -+ -+int ocelot_cbs_set(struct ocelot *ocelot, int port, u8 tc, u8 bw) -+{ -+ if (tc > capa.qos_cos_max) { -+ dev_err(ocelot->dev, "Invalid tc: %u\n", tc); -+ return -EINVAL; -+ } -+ -+ qos_shaper_conf_set(ocelot, port, port * 8 + tc, bw); -+ -+ ocelot_rmw_gix(ocelot, -+ QSYS_SE_CFG_SE_AVB_ENA, -+ QSYS_SE_CFG_SE_AVB_ENA, -+ QSYS_SE_CFG, -+ port * 8 + tc); -+ -+ return 0; -+} -+ -+int ocelot_cbs_get(struct ocelot *ocelot, int port, u8 tc) -+{ -+ int ret; -+ -+ if (tc > capa.qos_cos_max) { -+ dev_err(ocelot->dev, "Invalid tc: %u\n", tc); -+ return -EINVAL; -+ } -+ -+ ret = qos_shaper_conf_get(ocelot, port, port * 8 + tc); -+ -+ return ret; -+} -+ -+int ocelot_qbu_set(struct ocelot *ocelot, int port, u8 preemptible) -+{ -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ -+ ocelot_port_rmwl(ocelot_port, -+ DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_RX_ENA | -+ DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_TX_ENA, -+ DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_RX_ENA | -+ DEV_GMII_MM_CONFIG_ENABLE_CONFIG_MM_TX_ENA, -+ DEV_GMII_MM_CONFIG_ENABLE_CONFIG); -+ -+ ocelot_rmw_rix(ocelot, -+ QSYS_PREEMPTION_CFG_P_QUEUES(preemptible), -+ QSYS_PREEMPTION_CFG_P_QUEUES_M, -+ QSYS_PREEMPTION_CFG, -+ port); -+ -+ return 0; -+} -+ -+int ocelot_qbu_get(struct ocelot *ocelot, int port, -+ struct tsn_preempt_status *c) -+{ -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ u32 val; -+ -+ val = ocelot_read_rix(ocelot, -+ QSYS_PREEMPTION_CFG, -+ port); -+ -+ c->admin_state = QSYS_PREEMPTION_CFG_P_QUEUES(val); -+ c->hold_advance = QSYS_PREEMPTION_CFG_HOLD_ADVANCE_X(val); -+ -+ val = ocelot_port_readl(ocelot_port, -+ DEV_GMII_MM_STATISTICS_MM_STATUS); -+ c->preemption_active = -+ DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_ACTIVE_STATUS & val; -+ -+ return 0; -+} -+ -+int ocelot_cb_streamid_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_cb_streamid *streamid) -+{ -+ u32 m_index; -+ u32 bucket; -+ u32 val, dst, reg; -+ u64 dmac; -+ u32 ldmac, hdmac; -+ -+ if (index >= MSCC_STREAM_HANDLE_NUM) { -+ dev_err(ocelot->dev, -+ "Invalid stream handle %u, maximum:%u\n", -+ index, MSCC_STREAM_HANDLE_NUM - 1); -+ return -EINVAL; -+ } -+ -+ index = streamhandle_map[index]; -+ m_index = index / 4; -+ bucket = index % 4; -+ streamid->type = 1; -+ regmap_field_write(ocelot->regfields[ANA_TABLES_MACTINDX_BUCKET], -+ bucket); -+ regmap_field_write(ocelot->regfields[ANA_TABLES_MACTINDX_M_INDEX], -+ m_index); -+ -+ /*READ command MACACCESS.VALID(11 bit) must be 0 */ -+ ocelot_write(ocelot, -+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ), -+ ANA_TABLES_MACACCESS); -+ -+ val = ocelot_read(ocelot, ANA_TABLES_MACACCESS); -+ dst = ANA_TABLES_MACACCESS_DEST_IDX_X(val); -+ reg = ocelot_read_rix(ocelot, ANA_PGID_PGID, dst); -+ streamid->ofac_oport = ANA_PGID_PGID_PGID(reg); -+ -+ /*Get the entry's MAC address and VLAN id*/ -+ ldmac = ocelot_read(ocelot, ANA_TABLES_MACLDATA); -+ val = ocelot_read(ocelot, ANA_TABLES_MACHDATA); -+ val &= 0x1fffffff; -+ hdmac = val & 0xffff; -+ dmac = hdmac; -+ dmac = (dmac << 32) | ldmac; -+ streamid->para.nid.dmac = dmac; -+ -+ streamid->para.nid.vid = ANA_TABLES_MACHDATA_VID_X(val); -+ -+ val = ocelot_read(ocelot, ANA_TABLES_STREAMDATA); -+ if (!(val & ANA_TABLES_STREAMDATA_SFID_VALID)) -+ return -EINVAL; -+ -+ streamid->handle = ANA_TABLES_STREAMDATA_SFID(val); -+ -+ return 0; -+} -+ -+static int lookup_mactable(struct ocelot *ocelot, u16 vid, u64 mac) -+{ -+ u32 mach, macl; -+ u32 reg1, reg2; -+ u32 index, bucket; -+ -+ macl = mac & 0xffffffff; -+ mach = (mac >> 32) & 0xffff; -+ ocelot_write(ocelot, macl, ANA_TABLES_MACLDATA); -+ ocelot_write(ocelot, ANA_TABLES_MACHDATA_VID(vid) | -+ ANA_TABLES_MACHDATA_MACHDATA(mach), -+ ANA_TABLES_MACHDATA); -+ -+ ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID | -+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ), -+ ANA_TABLES_MACACCESS); -+ -+ reg1 = ocelot_read(ocelot, ANA_TABLES_MACLDATA); -+ reg2 = ocelot_read(ocelot, ANA_TABLES_MACHDATA); -+ if (reg1 == 0 && reg2 == 0) -+ return -1; -+ -+ regmap_field_read(ocelot->regfields[ANA_TABLES_MACTINDX_BUCKET], -+ &bucket); -+ regmap_field_read(ocelot->regfields[ANA_TABLES_MACTINDX_M_INDEX], -+ &index); -+ -+ index = index * 4 + bucket; -+ -+ return index; -+} -+ -+int ocelot_cb_streamid_set(struct ocelot *ocelot, int port, -+ u32 index, bool enable, -+ struct tsn_cb_streamid *streamid) -+{ -+ struct regmap_field *rf; -+ u16 vid; -+ u64 mac; -+ u32 macl, mach; -+ u32 dst_idx; -+ int idx; -+ u32 reg; -+ int sfid, ssid; -+ u32 m_index, bucket; -+ -+ if (!enable) { -+ if (index >= MSCC_STREAM_HANDLE_NUM) { -+ dev_err(ocelot->dev, -+ "Invalid index %u, maximum:%u\n", -+ index, MSCC_STREAM_HANDLE_NUM - 1); -+ return -EINVAL; -+ } -+ m_index = streamhandle_map[index] / 4; -+ bucket = streamhandle_map[index] % 4; -+ rf = ocelot->regfields[ANA_TABLES_MACTINDX_BUCKET]; -+ regmap_field_write(rf, bucket); -+ rf = ocelot->regfields[ANA_TABLES_MACTINDX_M_INDEX]; -+ regmap_field_write(rf, m_index); -+ -+ /*READ command MACACCESS.VALID(11 bit) must be 0 */ -+ ocelot_write(ocelot, -+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ), -+ ANA_TABLES_MACACCESS); -+ -+ ocelot_write(ocelot, -+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_FORGET), -+ ANA_TABLES_MACACCESS); -+ -+ streamhandle_map[index] = 0; -+ -+ return 0; -+ } -+ -+ if (streamid->type != 1) { -+ dev_err(ocelot->dev, "Invalid stream type\n"); -+ return -EINVAL; -+ } -+ -+ if (streamid->handle >= MSCC_STREAM_HANDLE_NUM) { -+ dev_err(ocelot->dev, -+ "Invalid stream handle %u, maximum:%u\n", -+ streamid->handle, MSCC_STREAM_HANDLE_NUM - 1); -+ return -EINVAL; -+ } -+ -+ sfid = streamid->handle; -+ ssid = (streamid->handle < MSCC_FRER_SSID_NUM ? -+ streamid->handle : (MSCC_FRER_SSID_NUM - 1)); -+ -+ mac = streamid->para.nid.dmac; -+ macl = mac & 0xffffffff; -+ mach = (mac >> 32) & 0xffff; -+ vid = streamid->para.nid.vid; -+ -+ idx = lookup_mactable(ocelot, vid, mac); -+ -+ if (idx < 0) { -+ ocelot_write(ocelot, macl, ANA_TABLES_MACLDATA); -+ ocelot_write(ocelot, ANA_TABLES_MACHDATA_VID(vid) | -+ ANA_TABLES_MACHDATA_MACHDATA(mach), -+ ANA_TABLES_MACHDATA); -+ -+ ocelot_write(ocelot, -+ ANA_TABLES_STREAMDATA_SFID_VALID | -+ ANA_TABLES_STREAMDATA_SFID(sfid) | -+ ANA_TABLES_STREAMDATA_SSID_VALID | -+ ANA_TABLES_STREAMDATA_SSID(ssid), -+ ANA_TABLES_STREAMDATA); -+ -+ dst_idx = port; -+ ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID | -+ ANA_TABLES_MACACCESS_ENTRYTYPE(1) | -+ ANA_TABLES_MACACCESS_DEST_IDX(dst_idx) | -+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN), -+ ANA_TABLES_MACACCESS); -+ -+ ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID | -+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ), -+ ANA_TABLES_MACACCESS); -+ -+ regmap_field_read(ocelot->regfields[ANA_TABLES_MACTINDX_BUCKET], -+ &bucket); -+ regmap_field_read(ocelot->regfields[ANA_TABLES_MACTINDX_M_INDEX], -+ &m_index); -+ -+ m_index = m_index * 4 + bucket; -+ streamhandle_map[streamid->handle] = m_index; -+ -+ return 0; -+ } -+ -+ ocelot_write(ocelot, -+ ANA_TABLES_STREAMDATA_SFID_VALID | -+ ANA_TABLES_STREAMDATA_SFID(sfid) | -+ ANA_TABLES_STREAMDATA_SSID_VALID | -+ ANA_TABLES_STREAMDATA_SSID(ssid), -+ ANA_TABLES_STREAMDATA); -+ -+ reg = ocelot_read(ocelot, ANA_TABLES_MACACCESS); -+ dst_idx = ANA_TABLES_MACACCESS_DEST_IDX_X(reg); -+ ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID | -+ ANA_TABLES_MACACCESS_ENTRYTYPE(1) | -+ ANA_TABLES_MACACCESS_DEST_IDX(dst_idx) | -+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_WRITE), -+ ANA_TABLES_MACACCESS); -+ -+ streamhandle_map[streamid->handle] = idx; -+ -+ return 0; -+} -+ -+static int streamid_multi_forward_set(struct ocelot *ocelot, u32 index, -+ u8 fwdmask) -+{ -+ u32 m_index; -+ u32 bucket; -+ u32 val; -+ int m, n, i; -+ u8 pgid_val, fwdport; -+ u32 dst_idx; -+ -+ m_index = index / 4; -+ bucket = index % 4; -+ -+ regmap_field_write(ocelot->regfields[ANA_TABLES_MACTINDX_BUCKET], -+ bucket); -+ regmap_field_write(ocelot->regfields[ANA_TABLES_MACTINDX_M_INDEX], -+ m_index); -+ -+ /*READ command MACACCESS.VALID(11 bit) must be 0 */ -+ ocelot_write(ocelot, -+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ), -+ ANA_TABLES_MACACCESS); -+ -+ val = ocelot_read(ocelot, ANA_TABLES_MACACCESS); -+ fwdport = ANA_TABLES_MACACCESS_DEST_IDX_X(val); -+ -+ if (fwdport >= MSCC_NUM_OUT_PORT) { -+ dst_idx = fwdport; -+ return 0; -+ } -+ -+ fwdmask |= (1 << fwdport); -+ -+ m = ocelot->num_phys_ports - 1; -+ for (i = m; i >= MSCC_NUM_OUT_PORT; i--) { -+ if (fwdmask & (1 << i)) { -+ dst_idx = PGID_MCRED + -+ (m - i) * MSCC_NUM_OUT_PORT + -+ fwdport; -+ -+ pgid_val = (1 << i) | (1 << fwdport); -+ break; -+ } -+ } -+ -+ if (i < MSCC_NUM_OUT_PORT) { -+ m = PGID_MCRED + -+ (ocelot->num_phys_ports - MSCC_NUM_OUT_PORT) * -+ MSCC_NUM_OUT_PORT; -+ -+ for (; i > 0; i--) { -+ if (fwdmask & (1 << i)) -+ break; -+ -+ m = m + (1 << i) - 1; -+ } -+ n = fwdmask & ((1 << i) - 1); -+ if (n) { -+ dst_idx = m + n; -+ pgid_val = fwdmask & ((1 << MSCC_NUM_OUT_PORT) - 1); -+ } else { -+ dst_idx = fwdport; -+ } -+ } -+ -+ if (dst_idx < PGID_MCRED) -+ return 0; -+ -+ ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID | -+ ANA_TABLES_MACACCESS_ENTRYTYPE(1) | -+ ANA_TABLES_MACACCESS_DEST_IDX(dst_idx) | -+ ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_WRITE), -+ ANA_TABLES_MACACCESS); -+ -+ ocelot_write_rix(ocelot, pgid_val, ANA_PGID_PGID, dst_idx); -+ -+ return 0; -+} -+ -+int ocelot_qci_sfi_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_qci_psfp_sfi_conf *sfi) -+{ -+ u32 val, reg, fmeter_id, max_sdu; -+ u32 sfid = index; -+ -+ if (sfid >= capa.num_psfp_sfid) { -+ dev_err(ocelot->dev, "Invalid index %u, maximum:%u\n", -+ sfid, capa.num_psfp_sfid); -+ return -EINVAL; -+ } -+ -+ ocelot_rmw(ocelot, -+ ANA_TABLES_SFIDTIDX_SFID_INDEX(sfid), -+ ANA_TABLES_SFIDTIDX_SFID_INDEX_M, -+ ANA_TABLES_SFIDTIDX); -+ -+ ocelot_write(ocelot, -+ ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(SFIDACCESS_CMD_READ), -+ ANA_TABLES_SFIDACCESS); -+ -+ val = ocelot_read(ocelot, ANA_TABLES_SFIDTIDX); -+ if (!(val & ANA_TABLES_SFIDTIDX_SGID_VALID)) -+ return -EINVAL; -+ -+ sfi->stream_gate_instance_id = ANA_TABLES_SFIDTIDX_SGID_X(val); -+ fmeter_id = ANA_TABLES_SFIDTIDX_POL_IDX_X(val); -+ sfi->stream_filter.flow_meter_instance_id = fmeter_id; -+ -+ reg = ocelot_read(ocelot, ANA_TABLES_SFIDACCESS); -+ max_sdu = ANA_TABLES_SFIDACCESS_MAX_SDU_LEN_X(reg); -+ sfi->stream_filter.maximum_sdu_size = max_sdu; -+ -+ if (reg & ANA_TABLES_SFIDACCESS_IGR_PRIO_MATCH_ENA) -+ sfi->priority_spec = ANA_TABLES_SFIDACCESS_IGR_PRIO_X(reg); -+ else -+ dev_err(ocelot->dev, "priority not enable\n"); -+ -+ return 0; -+} -+ -+int ocelot_qci_sfi_set(struct ocelot *ocelot, int port, -+ u32 index, bool enable, -+ struct tsn_qci_psfp_sfi_conf *sfi) -+{ -+ int igr_prio = sfi->priority_spec; -+ u16 sgid = sfi->stream_gate_instance_id; -+ u16 pol_idx; -+ int fmid = sfi->stream_filter.flow_meter_instance_id; -+ u16 max_sdu_len = sfi->stream_filter.maximum_sdu_size; -+ int sfid = index; -+ u32 val; -+ -+ if (fmid == -1) -+ pol_idx = capa.psfp_fmi_max; -+ else -+ pol_idx = (u16)fmid; -+ -+ if (sfid >= capa.num_psfp_sfid) { -+ dev_err(ocelot->dev, "Invalid index %u, maximum:%u\n", -+ sfid, capa.num_psfp_sfid); -+ return -EINVAL; -+ } -+ -+ if (!enable) { -+ val = ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(SFIDACCESS_CMD_WRITE); -+ ocelot_write(ocelot, -+ ANA_TABLES_SFIDTIDX_SFID_INDEX(sfid), -+ ANA_TABLES_SFIDTIDX); -+ ocelot_write(ocelot, val, ANA_TABLES_SFIDACCESS); -+ return 0; -+ } -+ -+ if (sgid >= capa.num_psfp_sgid) { -+ dev_err(ocelot->dev, "Invalid sgid %u, maximum:%u\n", -+ sgid, capa.num_psfp_sgid); -+ return -EINVAL; -+ } -+ if (pol_idx > capa.psfp_fmi_max || pol_idx < capa.psfp_fmi_min) { -+ dev_err(ocelot->dev, "Invalid pol_idx %u, range:%d~%d\n", -+ pol_idx, capa.psfp_fmi_min, capa.psfp_fmi_max); -+ return -EINVAL; -+ } -+ -+ ocelot_write(ocelot, ANA_TABLES_SFIDTIDX_SGID_VALID | -+ ANA_TABLES_SFIDTIDX_SGID(sgid) | -+ ((fmid != -1) ? ANA_TABLES_SFIDTIDX_POL_ENA : 0) | -+ ANA_TABLES_SFIDTIDX_POL_IDX(pol_idx) | -+ ANA_TABLES_SFIDTIDX_SFID_INDEX(sfid), -+ ANA_TABLES_SFIDTIDX); -+ -+ ocelot_write(ocelot, -+ ((igr_prio >= 0) ? -+ ANA_TABLES_SFIDACCESS_IGR_PRIO_MATCH_ENA : 0) | -+ ANA_TABLES_SFIDACCESS_IGR_PRIO(igr_prio) | -+ ANA_TABLES_SFIDACCESS_MAX_SDU_LEN(max_sdu_len) | -+ ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(SFIDACCESS_CMD_WRITE), -+ ANA_TABLES_SFIDACCESS); -+ -+ return 0; -+} -+ -+int ocelot_qci_sfi_counters_get(struct ocelot *ocelot, int port, -+ u32 index, -+ struct tsn_qci_psfp_sfi_counters *sfi_cnt) -+{ -+ u32 sfid = index; -+ u32 match, not_pass, not_pass_sdu, red; -+ -+ if (sfid >= capa.num_psfp_sfid) { -+ dev_err(ocelot->dev, "Invalid index %u, maximum:%u\n", -+ sfid, capa.num_psfp_sfid); -+ return -EINVAL; -+ } -+ -+ ocelot_rmw(ocelot, -+ SYS_STAT_CFG_STAT_VIEW(sfid), -+ SYS_STAT_CFG_STAT_VIEW_M, -+ SYS_STAT_CFG); -+ -+ match = ocelot_read_gix(ocelot, SYS_CNT, 0x200); -+ not_pass = ocelot_read_gix(ocelot, SYS_CNT, 0x201); -+ not_pass_sdu = ocelot_read_gix(ocelot, SYS_CNT, 0x202); -+ red = ocelot_read_gix(ocelot, SYS_CNT, 0x203); -+ -+ sfi_cnt->matching_frames_count = match; -+ sfi_cnt->not_passing_frames_count = not_pass; -+ sfi_cnt->not_passing_sdu_count = not_pass_sdu; -+ sfi_cnt->red_frames_count = red; -+ -+ sfi_cnt->passing_frames_count = match - not_pass; -+ sfi_cnt->passing_sdu_count = match - not_pass - not_pass_sdu; -+ -+ return 0; -+} -+ -+int ocelot_qci_max_cap_get(struct ocelot *ocelot, -+ struct tsn_qci_psfp_stream_param *stream_para) -+{ -+ /* MaxStreamFilterInstances */ -+ stream_para->max_sf_instance = capa.num_psfp_sfid; -+ /* MaxStreamGateInstances */ -+ stream_para->max_sg_instance = capa.num_psfp_sgid; -+ /* MaxFlowMeterInstances */ -+ stream_para->max_fm_instance = capa.psfp_fmi_max - -+ capa.psfp_fmi_min + 1; -+ /* SupportedListMax */ -+ stream_para->supported_list_max = capa.num_sgi_gcl; -+ -+ return 0; -+} -+ -+static int sgi_set_glist(struct ocelot *ocelot, -+ struct tsn_qci_psfp_gcl *gcl, uint32_t num) -+{ -+ u32 time_sum = 0; -+ int i; -+ -+ if (num > capa.num_sgi_gcl) -+ return -EINVAL; -+ -+ for (i = 0; i < num; i++) { -+ u32 val = ANA_SG_GCL_GS_CONFIG_IPS((gcl->ipv < 0) ? -+ 0 : gcl->ipv + 8); -+ val |= (gcl->gate_state ? ANA_SG_GCL_GS_CONFIG_GATE_STATE : 0); -+ ocelot_write_rix(ocelot, val, ANA_SG_GCL_GS_CONFIG, i); -+ -+ time_sum += gcl->time_interval; -+ ocelot_write_rix(ocelot, time_sum, ANA_SG_GCL_TI_CONFIG, i); -+ -+ gcl++; -+ } -+ -+ return 0; -+} -+ -+static u32 sgi_read_status(struct ocelot *ocelot) -+{ -+ u32 val; -+ -+ val = ocelot_read(ocelot, ANA_SG_ACCESS_CTRL); -+ -+ return val; -+} -+ -+int ocelot_qci_sgi_set(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_qci_psfp_sgi_conf *sgi_conf) -+{ -+ struct tsn_qci_sg_control *admin_list = &sgi_conf->admin; -+ u32 sgid = index; -+ u32 list_length = sgi_conf->admin.control_list_length; -+ u32 cycle_time = sgi_conf->admin.cycle_time; -+ u32 cycle_time_ex = sgi_conf->admin.cycle_time_extension; -+ u32 l_basetime = sgi_conf->admin.base_time % 1000000000; -+ u64 h_basetime = sgi_conf->admin.base_time / 1000000000; -+ u64 cur_time; -+ u32 val; -+ int ret; -+ -+ if (sgid >= capa.num_psfp_sgid) { -+ dev_err(ocelot->dev, "Invalid sgid %u, maximum:%u\n", -+ sgid, capa.num_psfp_sgid); -+ return -EINVAL; -+ } -+ if ((cycle_time < capa.sgi_ct_min || -+ cycle_time > capa.sgi_ct_max) && -+ sgi_conf->gate_enabled) { -+ dev_err(ocelot->dev, "Invalid cycle_time %u ns\n", -+ cycle_time); -+ return -EINVAL; -+ } -+ if (cycle_time_ex > capa.sgi_cte_max) { -+ dev_err(ocelot->dev, -+ "Invalid cycle_time_extension %u\n", -+ cycle_time_ex); -+ return -EINVAL; -+ } -+ if (list_length > capa.num_sgi_gcl) { -+ dev_err(ocelot->dev, -+ "Invalid sgi_gcl len %u, maximum:%u\n", -+ list_length, capa.num_sgi_gcl); -+ return -EINVAL; -+ } -+ -+ /*configure SGID*/ -+ ocelot_rmw(ocelot, -+ ANA_SG_ACCESS_CTRL_SGID(sgid), -+ ANA_SG_ACCESS_CTRL_SGID_M, -+ ANA_SG_ACCESS_CTRL); -+ -+ /*Disable SG*/ -+ if (!sgi_conf->gate_enabled) { -+ ocelot_rmw(ocelot, -+ ANA_SG_CONFIG_REG_3_INIT_GATE_STATE, -+ ANA_SG_CONFIG_REG_3_INIT_GATE_STATE | -+ ANA_SG_CONFIG_REG_3_GATE_ENABLE, -+ ANA_SG_CONFIG_REG_3); -+ return 0; -+ } -+ -+ /*admin parameters*/ -+ cur_time = ocelot_read(ocelot, PTP_CUR_SEC_MSB); -+ cur_time = cur_time << 32; -+ cur_time += ocelot_read(ocelot, PTP_CUR_SEC_LSB); -+ if (h_basetime < cur_time) { -+ h_basetime = cur_time; -+ l_basetime = ocelot_read(ocelot, PTP_CUR_NSEC); -+ } -+ -+ ocelot_write(ocelot, l_basetime, ANA_SG_CONFIG_REG_1); -+ ocelot_write(ocelot, h_basetime, ANA_SG_CONFIG_REG_2); -+ -+ ocelot_write(ocelot, -+ (sgi_conf->admin.init_ipv < 0 ? -+ 0 : ANA_SG_CONFIG_REG_3_IPV_VALID) | -+ ANA_SG_CONFIG_REG_3_INIT_IPV(sgi_conf->admin.init_ipv) | -+ ANA_SG_CONFIG_REG_3_GATE_ENABLE | -+ ANA_SG_CONFIG_REG_3_LIST_LENGTH(list_length) | -+ (sgi_conf->admin.gate_states > 0 ? -+ ANA_SG_CONFIG_REG_3_INIT_GATE_STATE : 0) | -+ ANA_SG_CONFIG_REG_3_BASE_TIME_SEC_MSB(h_basetime >> 32), -+ ANA_SG_CONFIG_REG_3); -+ -+ ocelot_write(ocelot, cycle_time, ANA_SG_CONFIG_REG_4); -+ ocelot_write(ocelot, cycle_time_ex, ANA_SG_CONFIG_REG_5); -+ -+ ret = sgi_set_glist(ocelot, admin_list->gcl, list_length); -+ if (ret < 0) -+ return ret; -+ -+ /* Start configuration change */ -+ ocelot_rmw(ocelot, -+ ANA_SG_ACCESS_CTRL_CONFIG_CHANGE, -+ ANA_SG_ACCESS_CTRL_CONFIG_CHANGE, -+ ANA_SG_ACCESS_CTRL); -+ -+ ret = readx_poll_timeout(sgi_read_status, ocelot, val, -+ (!(ANA_SG_ACCESS_CTRL_CONFIG_CHANGE & val)), -+ 10, 100000); -+ -+ return ret; -+} -+ -+static int sgi_get_glist(struct ocelot *ocelot, -+ struct tsn_qci_psfp_gcl *gcl, -+ uint32_t num) -+{ -+ int i; -+ u16 val; -+ u32 time = 0; -+ u32 reg; -+ -+ if (num > capa.num_sgi_gcl) -+ return -EINVAL; -+ -+ for (i = 0; i < num; i++) { -+ val = ocelot_read_rix(ocelot, ANA_SG_GCL_GS_CONFIG, i); -+ gcl->gate_state = (val & ANA_SG_GCL_GS_CONFIG_GATE_STATE); -+ -+ if (val & ANA_SG_GCL_GS_CONFIG_IPV_VALID) -+ gcl->ipv = ANA_SG_GCL_GS_CONFIG_IPV(val); -+ else -+ gcl->ipv = -1; -+ -+ reg = ocelot_read_rix(ocelot, ANA_SG_GCL_TI_CONFIG, i); -+ gcl->time_interval = (reg - time); -+ time = reg; -+ -+ gcl++; -+ } -+ -+ return 0; -+} -+ -+int ocelot_qci_sgi_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_qci_psfp_sgi_conf *sgi_conf) -+{ -+ struct tsn_qci_sg_control *admin = &sgi_conf->admin; -+ struct tsn_qci_psfp_gcl *glist; -+ u32 val, reg; -+ u32 list_num; -+ int ret; -+ -+ if (index >= capa.num_psfp_sgid) { -+ dev_err(ocelot->dev, "Invalid sgid %u, maximum:%u\n", -+ index, capa.num_psfp_sgid); -+ return -EINVAL; -+ } -+ -+ ocelot_rmw(ocelot, -+ ANA_SG_ACCESS_CTRL_SGID(index), -+ ANA_SG_ACCESS_CTRL_SGID_M, -+ ANA_SG_ACCESS_CTRL); -+ -+ admin->cycle_time = ocelot_read(ocelot, ANA_SG_CONFIG_REG_4); -+ admin->cycle_time_extension = -+ ocelot_read(ocelot, ANA_SG_CONFIG_REG_5); -+ -+ val = ocelot_read(ocelot, ANA_SG_CONFIG_REG_2); -+ admin->base_time = val; -+ -+ reg = ocelot_read(ocelot, ANA_SG_CONFIG_REG_1); -+ val = ocelot_read(ocelot, ANA_SG_CONFIG_REG_3); -+ -+ admin->base_time += -+ ANA_SG_CONFIG_REG_3_BASE_TIME_SEC_MSB(val) << 32; -+ -+ admin->base_time = admin->base_time * 1000000000 + reg; -+ -+ if (val & ANA_SG_CONFIG_REG_3_IPV_VALID) -+ admin->init_ipv = ANA_SG_CONFIG_REG_3_INIT_IPV_X(val); -+ else -+ admin->init_ipv = -1; -+ -+ if (val & ANA_SG_CONFIG_REG_3_GATE_ENABLE) -+ sgi_conf->gate_enabled = TRUE; -+ -+ admin->control_list_length = ANA_SG_CONFIG_REG_3_LIST_LENGTH_X(val); -+ -+ list_num = admin->control_list_length; -+ -+ glist = kmalloc_array(list_num, sizeof(struct tsn_qci_psfp_gcl), -+ GFP_KERNEL); -+ admin->gcl = glist; -+ -+ ret = sgi_get_glist(ocelot, glist, list_num); -+ -+ return ret; -+} -+ -+int ocelot_qci_sgi_status_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_psfp_sgi_status *sgi_status) -+{ -+ u32 val, reg; -+ -+ if (index >= capa.num_psfp_sgid) { -+ dev_err(ocelot->dev, "Invalid sgid %u, maximum:%u\n", -+ index, capa.num_psfp_sgid); -+ return -EINVAL; -+ } -+ -+ ocelot_rmw(ocelot, -+ ANA_SG_ACCESS_CTRL_SGID(index), -+ ANA_SG_ACCESS_CTRL_SGID_M, -+ ANA_SG_ACCESS_CTRL); -+ -+ val = ocelot_read(ocelot, ANA_SG_STATUS_REG_2); -+ sgi_status->config_change_time = val; -+ -+ reg = ocelot_read(ocelot, ANA_SG_STATUS_REG_1); -+ val = ocelot_read(ocelot, ANA_SG_STATUS_REG_3); -+ sgi_status->config_change_time += -+ ANA_SG_STATUS_REG_3_CFG_CHG_TIME_SEC_MSB(val) << 32; -+ sgi_status->config_change_time = -+ sgi_status->config_change_time * 1000000000 + reg; -+ -+ if (val & ANA_SG_STATUS_REG_3_CONFIG_PENDING) -+ sgi_status->config_pending = TRUE; -+ else -+ sgi_status->config_pending = FALSE; -+ -+ if (val & ANA_SG_STATUS_REG_3_GATE_STATE) -+ sgi_status->oper.gate_states = TRUE; -+ else -+ sgi_status->oper.gate_states = FALSE; -+ /*bit 3 encoding 0:IPV [0:2]is invalid . 1:IPV[0:2] is valid*/ -+ if (val & ANA_SG_STATUS_REG_3_IPV_VALID) -+ sgi_status->oper.init_ipv = ANA_SG_STATUS_REG_3_IPV_X(val); -+ else -+ sgi_status->oper.init_ipv = -1; -+ -+ return 0; -+} -+ -+int ocelot_qci_fmi_set(struct ocelot *ocelot, int port, u32 index, -+ bool enable, struct tsn_qci_psfp_fmi *fmi) -+{ -+ u32 cir = 0, cbs = 0, pir = 0, pbs = 0; -+ u32 cir_ena = 0; -+ u32 pbs_max = 0, cbs_max = 0; -+ bool cir_discard = 0, pir_discard = 0; -+ -+ if (index > capa.qos_pol_max) { -+ dev_err(ocelot->dev, "Invalid pol_idx %u, maximum: %u\n", -+ index, capa.qos_pol_max); -+ return -EINVAL; -+ } -+ -+ if (fmi->mark_red_enable && fmi->mark_red) { -+ fmi->eir = 0; -+ fmi->ebs = 0; -+ fmi->cir = 0; -+ fmi->cbs = 0; -+ } -+ -+ pir = fmi->eir; -+ pbs = fmi->ebs; -+ -+ if (!fmi->drop_on_yellow) -+ cir_ena = 1; -+ -+ if (cir_ena) { -+ cir = fmi->cir; -+ cbs = fmi->cbs; -+ if (cir == 0 && cbs == 0) { -+ cir_discard = 1; -+ } else { -+ cir = DIV_ROUND_UP(cir, 100); -+ cir *= 3; /* Rate unit is 33 1/3 kbps */ -+ cbs = DIV_ROUND_UP(cbs, 4096); -+ cbs = (cbs ? cbs : 1); -+ cbs_max = capa.pol_cbs_max; -+ if (fmi->cf) -+ pir += fmi->cir; -+ } -+ } -+ -+ if (pir == 0 && pbs == 0) { -+ pir_discard = 1; -+ } else { -+ pir = DIV_ROUND_UP(pir, 100); -+ pir *= 3; /* Rate unit is 33 1/3 kbps */ -+ pbs = DIV_ROUND_UP(pbs, 4096); -+ pbs = (pbs ? pbs : 1); -+ pbs_max = capa.pol_pbs_max; -+ } -+ pir = min_t(u32, GENMASK(15, 0), pir); -+ cir = min_t(u32, GENMASK(15, 0), cir); -+ pbs = min(pbs_max, pbs); -+ cbs = min(cbs_max, cbs); -+ -+ ocelot_write_gix(ocelot, (ANA_POL_MODE_CFG_IPG_SIZE(20) | -+ ANA_POL_MODE_CFG_FRM_MODE(1) | -+ (fmi->cf ? ANA_POL_MODE_CFG_DLB_COUPLED : 0) | -+ (cir_ena ? ANA_POL_MODE_CFG_CIR_ENA : 0) | -+ ANA_POL_MODE_CFG_OVERSHOOT_ENA), -+ ANA_POL_MODE_CFG, index); -+ -+ ocelot_write_gix(ocelot, ANA_POL_PIR_CFG_PIR_RATE(pir) | -+ ANA_POL_PIR_CFG_PIR_BURST(pbs), -+ ANA_POL_PIR_CFG, index); -+ -+ ocelot_write_gix(ocelot, -+ (pir_discard ? GENMASK(22, 0) : 0), -+ ANA_POL_PIR_STATE, index); -+ -+ ocelot_write_gix(ocelot, ANA_POL_CIR_CFG_CIR_RATE(cir) | -+ ANA_POL_CIR_CFG_CIR_BURST(cbs), -+ ANA_POL_CIR_CFG, index); -+ -+ ocelot_write_gix(ocelot, -+ (cir_discard ? GENMASK(22, 0) : 0), -+ ANA_POL_CIR_STATE, index); -+ -+ return 0; -+} -+ -+int ocelot_qci_fmi_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_qci_psfp_fmi *fmi, -+ struct tsn_qci_psfp_fmi_counters *counters) -+{ -+ u32 val, reg; -+ -+ if (index > capa.qos_pol_max) { -+ dev_err(ocelot->dev, "Invalid pol_idx %u, maximum: %u\n", -+ index, capa.qos_pol_max); -+ return -EINVAL; -+ } -+ -+ val = ocelot_read_gix(ocelot, ANA_POL_PIR_CFG, index); -+ reg = ocelot_read_gix(ocelot, ANA_POL_CIR_CFG, index); -+ -+ fmi->eir = ANA_POL_PIR_CFG_PIR_RATE_X(val); -+ fmi->eir = fmi->eir * 100 / 3; -+ fmi->ebs = ANA_POL_PIR_CFG_PIR_BURST(val); -+ fmi->ebs *= 4096; -+ fmi->cir = ANA_POL_CIR_CFG_CIR_RATE_X(reg); -+ fmi->cir = fmi->cir * 100 / 3; -+ fmi->cbs = ANA_POL_CIR_CFG_CIR_BURST(reg); -+ fmi->cbs *= 4096; -+ if (!(fmi->eir | fmi->ebs | fmi->cir | fmi->cbs)) -+ fmi->mark_red = TRUE; -+ else -+ fmi->mark_red = FALSE; -+ -+ val = ocelot_read_gix(ocelot, ANA_POL_MODE_CFG, index); -+ if (val & ANA_POL_MODE_CFG_DLB_COUPLED) -+ fmi->cf = TRUE; -+ else -+ fmi->cf = FALSE; -+ if (val & ANA_POL_MODE_CFG_CIR_ENA) -+ fmi->drop_on_yellow = FALSE; -+ else -+ fmi->drop_on_yellow = TRUE; -+ -+ return 0; -+} -+ -+int ocelot_seq_gen_set(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_seq_gen_conf *sg_conf) -+{ -+ u8 iport_mask = sg_conf->iport_mask; -+ u8 split_mask = sg_conf->split_mask; -+ u8 seq_len = sg_conf->seq_len; -+ u32 seq_num = sg_conf->seq_num; -+ -+ if (index >= capa.num_frer_ssid) { -+ dev_err(ocelot->dev, "Invalid SSID %u, maximum:%u\n", -+ index, capa.num_frer_ssid - 1); -+ return -EINVAL; -+ } -+ if (seq_len < capa.frer_seq_len_min || -+ seq_len > capa.frer_seq_len_max) { -+ dev_err(ocelot->dev, -+ "Invalid seq_space_bits num %u,range:%d~%d\n", -+ seq_len, -+ capa.frer_seq_len_min, -+ capa.frer_seq_len_max); -+ return -EINVAL; -+ } -+ -+ streamid_multi_forward_set(ocelot, -+ streamhandle_map[index], -+ split_mask); -+ -+ ocelot_write(ocelot, -+ ANA_TABLES_SEQ_MASK_SPLIT_MASK(split_mask) | -+ ANA_TABLES_SEQ_MASK_INPUT_PORT_MASK(iport_mask), -+ ANA_TABLES_SEQ_MASK); -+ -+ ocelot_write(ocelot, -+ ANA_TABLES_STREAMTIDX_S_INDEX(index) | -+ ANA_TABLES_STREAMTIDX_STREAM_SPLIT | -+ ANA_TABLES_STREAMTIDX_SEQ_SPACE_LOG2(seq_len), -+ ANA_TABLES_STREAMTIDX); -+ -+ ocelot_write(ocelot, -+ ANA_TABLES_STREAMACCESS_GEN_REC_SEQ_NUM(seq_num) | -+ ANA_TABLES_STREAMACCESS_SEQ_GEN_REC_ENA | -+ ANA_TABLES_STREAMACCESS_STREAM_TBL_CMD(SFIDACCESS_CMD_WRITE), -+ ANA_TABLES_STREAMACCESS); -+ -+ return 0; -+} -+ -+int ocelot_seq_rec_set(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_seq_rec_conf *sr_conf) -+{ -+ u8 seq_len = sr_conf->seq_len; -+ u8 hislen = sr_conf->his_len; -+ -+ if (index >= capa.num_frer_ssid) { -+ dev_err(ocelot->dev, "Invalid SSID %u, maximum:%u\n", -+ index, capa.num_frer_ssid - 1); -+ return -EINVAL; -+ } -+ if (seq_len < capa.frer_seq_len_min || -+ seq_len > capa.frer_seq_len_max) { -+ dev_err(ocelot->dev, -+ "Invalid seq_space_bits num %u,range:%d~%d\n", -+ seq_len, -+ capa.frer_seq_len_min, -+ capa.frer_seq_len_max); -+ return -EINVAL; -+ } -+ if (hislen < capa.frer_his_len_min || -+ hislen > capa.frer_his_len_max) { -+ dev_err(ocelot->dev, -+ "Invalid history_bits num %u,range:%d~%d\n", -+ hislen, -+ capa.frer_his_len_min, -+ capa.frer_his_len_max); -+ return -EINVAL; -+ } -+ -+ ocelot_write(ocelot, -+ ANA_TABLES_STREAMTIDX_S_INDEX(index) | -+ ANA_TABLES_STREAMTIDX_FORCE_SF_BEHAVIOUR | -+ ANA_TABLES_STREAMTIDX_SEQ_HISTORY_LEN(hislen) | -+ ANA_TABLES_STREAMTIDX_RESET_ON_ROGUE | -+ (sr_conf->rtag_pop_en ? -+ ANA_TABLES_STREAMTIDX_REDTAG_POP : 0) | -+ ANA_TABLES_STREAMTIDX_SEQ_SPACE_LOG2(seq_len), -+ ANA_TABLES_STREAMTIDX); -+ -+ ocelot_write(ocelot, -+ ANA_TABLES_STREAMACCESS_SEQ_GEN_REC_ENA | -+ ANA_TABLES_STREAMACCESS_GEN_REC_TYPE | -+ ANA_TABLES_STREAMACCESS_STREAM_TBL_CMD(SFIDACCESS_CMD_WRITE), -+ ANA_TABLES_STREAMACCESS); -+ -+ return 0; -+} -+ -+int ocelot_cb_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_cb_status *c) -+{ -+ u32 val; -+ -+ if (index >= capa.num_frer_ssid) { -+ dev_err(ocelot->dev, "Invalid SSID %u, maximum:%u\n", -+ index, capa.num_frer_ssid - 1); -+ return -EINVAL; -+ } -+ -+ ocelot_write(ocelot, -+ ANA_TABLES_STREAMTIDX_S_INDEX(index), -+ ANA_TABLES_STREAMTIDX); -+ -+ ocelot_write(ocelot, -+ ANA_TABLES_STREAMACCESS_STREAM_TBL_CMD(SFIDACCESS_CMD_READ), -+ ANA_TABLES_STREAMACCESS); -+ -+ val = ocelot_read(ocelot, ANA_TABLES_STREAMACCESS); -+ c->gen_rec = (ANA_TABLES_STREAMACCESS_GEN_REC_TYPE & val) >> 2; -+ c->seq_num = ANA_TABLES_STREAMACCESS_GEN_REC_SEQ_NUM_X(val); -+ -+ val = ocelot_read(ocelot, ANA_TABLES_STREAMTIDX); -+ c->err = ANA_TABLES_STREAMTIDX_SEQ_GEN_ERR_STATUS_X(val); -+ c->his_len = ANA_TABLES_STREAMTIDX_SEQ_HISTORY_LEN_X(val); -+ c->seq_len = ANA_TABLES_STREAMTIDX_SEQ_SPACE_LOG2(val); -+ -+ val = ocelot_read(ocelot, ANA_TABLES_SEQ_MASK); -+ c->split_mask = ANA_TABLES_SEQ_MASK_SPLIT_MASK_X(val); -+ c->iport_mask = ANA_TABLES_SEQ_MASK_INPUT_PORT_MASK(val); -+ -+ c->seq_his = ocelot_read(ocelot, ANA_TABLES_SEQ_HISTORY); -+ -+ return 0; -+} -+ -+int ocelot_pcp_map_enable(struct ocelot *ocelot, u8 port) -+{ -+ int i; -+ -+ ocelot_rmw_gix(ocelot, -+ ANA_PORT_QOS_CFG_QOS_PCP_ENA, -+ ANA_PORT_QOS_CFG_QOS_PCP_ENA, -+ ANA_PORT_QOS_CFG, -+ port); -+ -+ for (i = 0; i < NUM_MSCC_QOS_PRIO * 2; i++) { -+ ocelot_rmw_ix(ocelot, -+ (ANA_PORT_PCP_DEI_MAP_DP_PCP_DEI_VAL & i) | -+ ANA_PORT_PCP_DEI_MAP_QOS_PCP_DEI_VAL(i), -+ ANA_PORT_PCP_DEI_MAP_DP_PCP_DEI_VAL | -+ ANA_PORT_PCP_DEI_MAP_QOS_PCP_DEI_VAL_M, -+ ANA_PORT_PCP_DEI_MAP, -+ port, i); -+ } -+ -+ return 0; -+} -+ -+int ocelot_rtag_parse_enable(struct ocelot *ocelot, u8 port) -+{ -+ ocelot_rmw_rix(ocelot, -+ ANA_PORT_MODE_REDTAG_PARSE_CFG, -+ ANA_PORT_MODE_REDTAG_PARSE_CFG, -+ ANA_PORT_MODE, -+ port); -+ -+ return 0; -+} -+ -+int ocelot_dscp_set(struct ocelot *ocelot, int port, -+ bool enable, const u8 dscp_ix, -+ struct tsn_qos_switch_dscp_conf *c) -+{ -+ u32 val, ri = dscp_ix; -+ -+ c->dscp = 0; -+ c->trust = 1; -+ c->remark = 0; -+ -+ if (dscp_ix > capa.qos_dscp_max) { -+ dev_err(ocelot->dev, "Invalid dscp_ix %u\n", dscp_ix); -+ return -EINVAL; -+ } -+ if (c->cos > capa.qos_cos_max) { -+ dev_err(ocelot->dev, "Invalid cos %d\n", c->cos); -+ return -EINVAL; -+ } -+ if (c->dpl > capa.qos_dp_max) { -+ dev_err(ocelot->dev, "Invalid dpl %d\n", c->dpl); -+ return -EINVAL; -+ } -+ -+ ocelot_rmw_gix(ocelot, -+ (enable ? ANA_PORT_QOS_CFG_QOS_DSCP_ENA : 0) | -+ (c->dscp ? ANA_PORT_QOS_CFG_DSCP_TRANSLATE_ENA : 0), -+ ANA_PORT_QOS_CFG_QOS_DSCP_ENA | -+ ANA_PORT_QOS_CFG_DSCP_TRANSLATE_ENA, -+ ANA_PORT_QOS_CFG, -+ port); -+ -+ val = (c->dpl ? ANA_DSCP_CFG_DP_DSCP_VAL : 0) | -+ ANA_DSCP_CFG_QOS_DSCP_VAL(c->cos) | -+ ANA_DSCP_CFG_DSCP_TRANSLATE_VAL(c->dscp) | -+ (c->trust ? ANA_DSCP_CFG_DSCP_TRUST_ENA : 0) | -+ (c->remark ? ANA_DSCP_CFG_DSCP_REWR_ENA : 0); -+ -+ ocelot_write_rix(ocelot, val, ANA_DSCP_CFG, ri); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/net/ethernet/mscc/ocelot_tsn.h -@@ -0,0 +1,51 @@ -+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) -+ * -+ * TSN_SWITCH driver -+ * -+ * Copyright 2018-2019 NXP -+ */ -+ -+#ifndef _MSCC_OCELOT_SWITCH_TSN_H_ -+#define _MSCC_OCELOT_SWITCH_TSN_H_ -+ -+#define TRUE 1 -+#define FALSE 0 -+ -+struct mscc_switch_capa { -+ u8 num_tas_gcl; /* Number of TAS Gate Control Lists */ -+ u32 tas_ct_min; /* Minimum supported TAS CycleTime in nS */ -+ u32 tas_ct_max; /* Maximum supported TAS CycleTime in nS */ -+ u32 tas_cte_max; /* Maximum supported TAS CycleTimeExtension in nS -+ */ -+ u32 tas_it_max; -+ u32 tas_it_min; -+ u8 num_hsch; -+ u8 num_psfp_sfid; -+ u8 num_frer_ssid; -+ u8 num_psfp_sgid; -+ u16 psfp_fmi_max; -+ u16 psfp_fmi_min; -+ u8 num_sgi_gcl; -+ u32 sgi_ct_min; -+ u32 sgi_ct_max; -+ u32 sgi_cte_max; -+ u16 qos_pol_max; -+ u8 pol_cbs_max; -+ u8 pol_pbs_max; -+ u8 frer_seq_len_min; -+ u8 frer_seq_len_max; -+ u8 frer_his_len_min; -+ u8 frer_his_len_max; -+ u8 qos_dscp_max; -+ u8 qos_cos_max; -+ u8 qos_dp_max; -+}; -+ -+static inline void ocelot_port_rmwl(struct ocelot_port *port, u32 val, -+ u32 mask, u32 reg) -+{ -+ u32 cur = ocelot_port_readl(port, reg); -+ -+ ocelot_port_writel(port, (cur & (~mask)) | val, reg); -+} -+#endif ---- a/include/soc/mscc/ocelot.h -+++ b/include/soc/mscc/ocelot.h -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #define IFH_INJ_BYPASS BIT(31) - #define IFH_INJ_POP_CNT_DISABLE (3 << 28) -@@ -328,6 +329,10 @@ enum ocelot_reg { - PTP_CFG_MISC, - PTP_CLK_CFG_ADJ_CFG, - PTP_CLK_CFG_ADJ_FREQ, -+ PTP_CUR_NSF, -+ PTP_CUR_NSEC, -+ PTP_CUR_SEC_LSB, -+ PTP_CUR_SEC_MSB, - GCB_SOFT_RST = GCB << TARGET_OFFSET, - }; - -@@ -539,5 +544,50 @@ int ocelot_ptp_gettime64(struct ptp_cloc - int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port, - struct sk_buff *skb); - void ocelot_get_txtstamp(struct ocelot *ocelot); -- -+int ocelot_qbv_set(struct ocelot *ocelot, int port_id, -+ struct tsn_qbv_conf *shaper_config); -+int ocelot_qbv_get(struct ocelot *ocelot, int port_id, -+ struct tsn_qbv_conf *shaper_config); -+int ocelot_qbv_get_status(struct ocelot *ocelot, int port_id, -+ struct tsn_qbv_status *qbvstatus); -+int ocelot_cut_thru_set(struct ocelot *ocelot, int port_id, u8 cut_thru); -+int ocelot_cbs_set(struct ocelot *ocelot, int port, u8 tc, u8 bw); -+int ocelot_cbs_get(struct ocelot *ocelot, int port, u8 tc); -+int ocelot_qbu_set(struct ocelot *ocelot, int port, u8 preemptible); -+int ocelot_qbu_get(struct ocelot *ocelot, int port, -+ struct tsn_preempt_status *c); -+int ocelot_cb_streamid_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_cb_streamid *streamid); -+int ocelot_cb_streamid_set(struct ocelot *ocelot, int port, u32 index, -+ bool enable, struct tsn_cb_streamid *streamid); -+int ocelot_qci_sfi_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_qci_psfp_sfi_conf *sfi); -+int ocelot_qci_sfi_set(struct ocelot *ocelot, int port, u32 index, -+ bool enable, struct tsn_qci_psfp_sfi_conf *sfi); -+int ocelot_qci_sfi_counters_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_qci_psfp_sfi_counters *sfi_counters); -+int ocelot_qci_max_cap_get(struct ocelot *ocelot, -+ struct tsn_qci_psfp_stream_param *stream_para); -+int ocelot_qci_sgi_set(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_qci_psfp_sgi_conf *sgi_conf); -+int ocelot_qci_sgi_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_qci_psfp_sgi_conf *sgi_conf); -+int ocelot_qci_sgi_status_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_psfp_sgi_status *sgi_status); -+int ocelot_qci_fmi_set(struct ocelot *ocelot, int port, u32 index, -+ bool enable, struct tsn_qci_psfp_fmi *fmi); -+int ocelot_qci_fmi_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_qci_psfp_fmi *fmi, -+ struct tsn_qci_psfp_fmi_counters *counters); -+int ocelot_seq_gen_set(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_seq_gen_conf *sg_conf); -+int ocelot_seq_rec_set(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_seq_rec_conf *sr_conf); -+int ocelot_cb_get(struct ocelot *ocelot, int port, u32 index, -+ struct tsn_cb_status *c); -+int ocelot_pcp_map_enable(struct ocelot *ocelot, u8 port); -+int ocelot_rtag_parse_enable(struct ocelot *ocelot, u8 port); -+int ocelot_dscp_set(struct ocelot *ocelot, int port, -+ bool enable, const u8 dscp_ix, -+ struct tsn_qos_switch_dscp_conf *c); - #endif diff --git a/target/linux/layerscape/patches-5.4/701-net-0273-net-dsa-ocelot-add-tsn-support-for-felix-switch.patch b/target/linux/layerscape/patches-5.4/701-net-0273-net-dsa-ocelot-add-tsn-support-for-felix-switch.patch deleted file mode 100644 index 72b101bfb0..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0273-net-dsa-ocelot-add-tsn-support-for-felix-switch.patch +++ /dev/null @@ -1,671 +0,0 @@ -From 36b446d44d66a6d6a072d3f5e87ebb05e0b88d98 Mon Sep 17 00:00:00 2001 -From: Xiaoliang Yang -Date: Fri, 29 Nov 2019 14:28:37 +0800 -Subject: [PATCH] net: dsa: ocelot: add tsn support for felix switch - -Support tsn capabilities in DSA felix switch driver. This felix tsn -driver is using tsn configuration of ocelot, and registered on each -switch port through DSA port setup. - -Signed-off-by: Xiaoliang Yang ---- - drivers/net/dsa/ocelot/Kconfig | 8 + - drivers/net/dsa/ocelot/Makefile | 2 + - drivers/net/dsa/ocelot/felix.c | 50 ++++ - drivers/net/dsa/ocelot/felix_tsn.c | 432 +++++++++++++++++++++++++++++++++ - drivers/net/dsa/ocelot/felix_tsn.h | 61 +++++ - drivers/net/dsa/ocelot/felix_vsc9959.c | 8 +- - include/net/dsa.h | 1 + - net/dsa/dsa2.c | 4 + - 8 files changed, 564 insertions(+), 2 deletions(-) - create mode 100644 drivers/net/dsa/ocelot/felix_tsn.c - create mode 100644 drivers/net/dsa/ocelot/felix_tsn.h - ---- a/drivers/net/dsa/ocelot/Kconfig -+++ b/drivers/net/dsa/ocelot/Kconfig -@@ -9,3 +9,11 @@ config NET_DSA_MSCC_FELIX - the Vitesse / Microsemi / Microchip Ocelot family of switching cores. - It is embedded as a PCIe function of the NXP LS1028A ENETC integrated - endpoint. -+ -+config MSCC_FELIX_SWITCH_TSN -+ tristate "TSN on FELIX switch driver" -+ depends on NET_DSA_MSCC_FELIX -+ depends on TSN -+ help -+ This driver supports TSN on felix switch. -+ ---- a/drivers/net/dsa/ocelot/Makefile -+++ b/drivers/net/dsa/ocelot/Makefile -@@ -4,3 +4,5 @@ obj-$(CONFIG_NET_DSA_MSCC_FELIX) += mscc - mscc_felix-objs := \ - felix.o \ - felix_vsc9959.o -+ -+obj-$(CONFIG_MSCC_FELIX_SWITCH_TSN) += felix_tsn.o ---- a/drivers/net/dsa/ocelot/felix.c -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -9,6 +9,38 @@ - #include - #include - #include "felix.h" -+#include "felix_tsn.h" -+ -+#ifdef CONFIG_MSCC_FELIX_SWITCH_TSN -+const struct tsn_ops switch_tsn_ops = { -+ .device_init = felix_tsn_init, -+ .get_capability = felix_tsn_get_cap, -+ .qbv_set = felix_qbv_set, -+ .qbv_get = felix_qbv_get, -+ .qbv_get_status = felix_qbv_get_status, -+ .qbu_set = felix_qbu_set, -+ .qbu_get = felix_qbu_get, -+ .cb_streamid_set = felix_cb_streamid_set, -+ .cb_streamid_get = felix_cb_streamid_get, -+ .cb_streamid_counters_get = felix_cb_streamid_counters_get, -+ .qci_sfi_set = felix_qci_sfi_set, -+ .qci_sfi_get = felix_qci_sfi_get, -+ .qci_sfi_counters_get = felix_qci_sfi_counters_get, -+ .qci_get_maxcap = felix_qci_max_cap_get, -+ .qci_sgi_set = felix_qci_sgi_set, -+ .qci_sgi_get = felix_qci_sgi_get, -+ .qci_sgi_status_get = felix_qci_sgi_status_get, -+ .qci_fmi_set = felix_qci_fmi_set, -+ .qci_fmi_get = felix_qci_fmi_get, -+ .cbs_set = felix_cbs_set, -+ .cbs_get = felix_cbs_get, -+ .ct_set = felix_cut_thru_set, -+ .cbgen_set = felix_seq_gen_set, -+ .cbrec_set = felix_seq_rec_set, -+ .cb_get = felix_cb_get, -+ .dscp_set = felix_dscp_set, -+}; -+#endif - - static enum dsa_tag_protocol felix_get_tag_protocol(struct dsa_switch *ds, - int port) -@@ -138,6 +170,21 @@ static int felix_vlan_del(struct dsa_swi - return 0; - } - -+#ifdef CONFIG_MSCC_FELIX_SWITCH_TSN -+static int felix_tsn_enable(struct dsa_port *dp) -+{ -+ struct net_device *dev; -+ -+ if (dp->type == DSA_PORT_TYPE_USER) { -+ dev = dp->slave; -+ tsn_port_register(dev, -+ (struct tsn_ops *)&switch_tsn_ops, -+ GROUP_OFFSET_SWITCH); -+ } -+ return 0; -+} -+#endif -+ - static int felix_port_enable(struct dsa_switch *ds, int port, - struct phy_device *phy) - { -@@ -386,6 +433,9 @@ static const struct dsa_switch_ops felix - .port_hwtstamp_set = felix_hwtstamp_set, - .port_rxtstamp = felix_rxtstamp, - .port_txtstamp = felix_txtstamp, -+#ifdef CONFIG_MSCC_FELIX_SWITCH_TSN -+ .port_tsn_enable = felix_tsn_enable, -+#endif - }; - - static struct felix_info *felix_instance_tbl[] = { ---- /dev/null -+++ b/drivers/net/dsa/ocelot/felix_tsn.c -@@ -0,0 +1,432 @@ -+// SPDX-License-Identifier: (GPL-2.0 OR MIT) -+/* Felix Switch TSN driver -+ * -+ * Copyright 2018-2019 NXP -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "felix.h" -+ -+static struct ocelot *felix_dev_to_ocelot(struct net_device *ndev) -+{ -+ struct pci_dev *pdev; -+ struct felix *felix; -+ -+ pdev = list_entry(ndev->dev.parent, struct pci_dev, dev); -+ felix = pci_get_drvdata(pdev); -+ if (!felix) -+ return NULL; -+ -+ return &felix->ocelot; -+} -+ -+static int felix_dev_to_port(struct net_device *ndev, struct ocelot *ocelot) -+{ -+ struct felix *felix = ocelot_to_felix(ocelot); -+ struct dsa_switch *ds = felix->ds; -+ struct dsa_port *dp; -+ int i; -+ -+ for (i = 0; i < ds->num_ports; i++) { -+ dp = &ds->ports[i]; -+ if (dp->dn == ndev->dev.of_node) -+ return dp->index; -+ } -+ -+ return -ENODEV; -+} -+ -+u32 felix_tsn_get_cap(struct net_device *ndev) -+{ -+ u32 cap = 0; -+ -+ cap = (TSN_CAP_QBV | TSN_CAP_QCI | TSN_CAP_QBU | TSN_CAP_CBS | -+ TSN_CAP_CB | TSN_CAP_TBS | TSN_CAP_CTH); -+ -+ return cap; -+} -+ -+int felix_qbv_set(struct net_device *ndev, -+ struct tsn_qbv_conf *shaper_config) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qbv_set(ocelot, port, shaper_config); -+} -+ -+int felix_qbv_get(struct net_device *ndev, -+ struct tsn_qbv_conf *shaper_config) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qbv_get(ocelot, port, shaper_config); -+} -+ -+int felix_qbv_get_status(struct net_device *ndev, -+ struct tsn_qbv_status *qbvstatus) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qbv_get_status(ocelot, port, qbvstatus); -+} -+ -+int felix_qbu_set(struct net_device *ndev, u8 preemptible) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qbu_set(ocelot, port, preemptible); -+} -+ -+int felix_qbu_get(struct net_device *ndev, struct tsn_preempt_status *c) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qbu_get(ocelot, port, c); -+} -+ -+int felix_cb_streamid_set(struct net_device *ndev, u32 index, bool enable, -+ struct tsn_cb_streamid *streamid) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_cb_streamid_set(ocelot, port, index, enable, streamid); -+} -+ -+int felix_cb_streamid_get(struct net_device *ndev, u32 index, -+ struct tsn_cb_streamid *streamid) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_cb_streamid_get(ocelot, port, index, streamid); -+} -+ -+int felix_cb_streamid_counters_get(struct net_device *ndev, u32 index, -+ struct tsn_cb_streamid_counters *sc) -+{ -+ return 0; -+} -+ -+int felix_qci_sfi_set(struct net_device *ndev, u32 index, bool enable, -+ struct tsn_qci_psfp_sfi_conf *sfi) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qci_sfi_set(ocelot, port, index, enable, sfi); -+} -+ -+int felix_qci_sfi_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sfi_conf *sfi) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qci_sfi_get(ocelot, port, index, sfi); -+} -+ -+int felix_qci_sfi_counters_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sfi_counters *sfi_cnt) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qci_sfi_counters_get(ocelot, port, index, sfi_cnt); -+} -+ -+int felix_qci_max_cap_get(struct net_device *ndev, -+ struct tsn_qci_psfp_stream_param *stream_para) -+{ -+ struct ocelot *ocelot; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ -+ return ocelot_qci_max_cap_get(ocelot, stream_para); -+} -+ -+int felix_qci_sgi_set(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sgi_conf *sgi_conf) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qci_sgi_set(ocelot, port, index, sgi_conf); -+} -+ -+int felix_qci_sgi_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sgi_conf *sgi_conf) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qci_sgi_get(ocelot, port, index, sgi_conf); -+} -+ -+int felix_qci_sgi_status_get(struct net_device *ndev, u32 index, -+ struct tsn_psfp_sgi_status *sgi_status) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qci_sgi_status_get(ocelot, port, index, sgi_status); -+} -+ -+int felix_qci_fmi_set(struct net_device *ndev, u32 index, -+ bool enable, struct tsn_qci_psfp_fmi *fmi) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qci_fmi_set(ocelot, port, index, enable, fmi); -+} -+ -+int felix_qci_fmi_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_fmi *fmi, -+ struct tsn_qci_psfp_fmi_counters *counters) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_qci_fmi_get(ocelot, port, index, fmi, counters); -+} -+ -+int felix_cbs_set(struct net_device *ndev, u8 tc, u8 bw) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_cbs_set(ocelot, port, tc, bw); -+} -+ -+int felix_cbs_get(struct net_device *ndev, u8 tc) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_cbs_get(ocelot, port, tc); -+} -+ -+int felix_cut_thru_set(struct net_device *ndev, u8 cut_thru) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_cut_thru_set(ocelot, port, cut_thru); -+} -+ -+int felix_seq_gen_set(struct net_device *ndev, u32 index, -+ struct tsn_seq_gen_conf *sg_conf) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_seq_gen_set(ocelot, port, index, sg_conf); -+} -+ -+int felix_seq_rec_set(struct net_device *ndev, u32 index, -+ struct tsn_seq_rec_conf *sr_conf) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_seq_rec_set(ocelot, port, index, sr_conf); -+} -+ -+int felix_cb_get(struct net_device *ndev, u32 index, -+ struct tsn_cb_status *c) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_cb_get(ocelot, port, index, c); -+} -+ -+int felix_dscp_set(struct net_device *ndev, bool enable, const u8 dscp_ix, -+ struct tsn_qos_switch_dscp_conf *c) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return -ENODEV; -+ port = felix_dev_to_port(ndev, ocelot); -+ if (port < 0) -+ return -ENODEV; -+ -+ return ocelot_dscp_set(ocelot, port, enable, dscp_ix, c); -+} -+ -+void felix_tsn_init(struct net_device *ndev) -+{ -+ struct ocelot *ocelot; -+ int port; -+ -+ ocelot = felix_dev_to_ocelot(ndev); -+ if (!ocelot) -+ return; -+ port = felix_dev_to_port(ndev, ocelot); -+ -+ ocelot_pcp_map_enable(ocelot, port); -+ ocelot_rtag_parse_enable(ocelot, port); -+} ---- /dev/null -+++ b/drivers/net/dsa/ocelot/felix_tsn.h -@@ -0,0 +1,61 @@ -+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) -+ * -+ * TSN_SWITCH driver -+ * -+ * Copyright 2018-2019 NXP -+ */ -+ -+#ifndef _MSCC_FELIX_SWITCH_TSN_H_ -+#define _MSCC_FELIX_SWITCH_TSN_H_ -+#include -+ -+u32 felix_tsn_get_cap(struct net_device *ndev); -+int felix_qbv_set(struct net_device *ndev, -+ struct tsn_qbv_conf *shaper_config); -+int felix_qbv_get(struct net_device *ndev, -+ struct tsn_qbv_conf *shaper_config); -+int felix_qbv_get_status(struct net_device *ndev, -+ struct tsn_qbv_status *qbvstatus); -+int felix_cut_thru_set(struct net_device *ndev, u8 cut_thru); -+int felix_cbs_set(struct net_device *ndev, u8 tc, u8 bw); -+int felix_cbs_get(struct net_device *ndev, u8 tc); -+int felix_qbu_set(struct net_device *ndev, u8 preemptible); -+int felix_qbu_get(struct net_device *ndev, struct tsn_preempt_status *c); -+int felix_cb_streamid_get(struct net_device *ndev, u32 index, -+ struct tsn_cb_streamid *streamid); -+int felix_cb_streamid_set(struct net_device *ndev, u32 index, -+ bool enable, struct tsn_cb_streamid *streamid); -+int felix_cb_streamid_counters_get(struct net_device *ndev, u32 index, -+ struct tsn_cb_streamid_counters *sc); -+int felix_qci_sfi_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sfi_conf *sfi); -+int felix_qci_sfi_set(struct net_device *ndev, u32 index, -+ bool enable, struct tsn_qci_psfp_sfi_conf *sfi); -+int felix_cb_streamid_counters_get(struct net_device *ndev, u32 index, -+ struct tsn_cb_streamid_counters *s_counters); -+int felix_qci_sfi_counters_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sfi_counters *sfi_counters); -+int felix_qci_max_cap_get(struct net_device *ndev, -+ struct tsn_qci_psfp_stream_param *stream_para); -+int felix_qci_sgi_set(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sgi_conf *sgi_conf); -+int felix_qci_sgi_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sgi_conf *sgi_conf); -+int felix_qci_sgi_status_get(struct net_device *ndev, u16 index, -+ struct tsn_psfp_sgi_status *sgi_status); -+int felix_qci_fmi_set(struct net_device *ndev, u32 index, -+ bool enable, struct tsn_qci_psfp_fmi *fmi); -+int felix_qci_fmi_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_fmi *fmi, -+ struct tsn_qci_psfp_fmi_counters *counters); -+int felix_seq_gen_set(struct net_device *ndev, u32 index, -+ struct tsn_seq_gen_conf *sg_conf); -+int felix_seq_rec_set(struct net_device *ndev, u32 index, -+ struct tsn_seq_rec_conf *sr_conf); -+int felix_cb_get(struct net_device *ndev, u32 index, -+ struct tsn_cb_status *c); -+int felix_dscp_set(struct net_device *ndev, bool enable, const u8 dscp_ix, -+ struct tsn_qos_switch_dscp_conf *c); -+ -+void felix_tsn_init(struct net_device *ndev); -+#endif ---- a/drivers/net/dsa/ocelot/felix_vsc9959.c -+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c -@@ -176,7 +176,7 @@ static const u32 vsc9959_qsys_regmap[] = - REG(QSYS_QMAXSDU_CFG_6, 0x00f62c), - REG(QSYS_QMAXSDU_CFG_7, 0x00f648), - REG(QSYS_PREEMPTION_CFG, 0x00f664), -- REG_RESERVED(QSYS_CIR_CFG), -+ REG(QSYS_CIR_CFG, 0x000000), - REG(QSYS_EIR_CFG, 0x000004), - REG(QSYS_SE_CFG, 0x000008), - REG(QSYS_SE_DWRR_CFG, 0x00000c), -@@ -269,7 +269,7 @@ static const u32 vsc9959_sys_regmap[] = - REG_RESERVED(SYS_MMGT_FAST), - REG_RESERVED(SYS_EVENTS_DIF), - REG_RESERVED(SYS_EVENTS_CORE), -- REG_RESERVED(SYS_CNT), -+ REG(SYS_CNT, 0x000000), - REG(SYS_PTP_STATUS, 0x000f14), - REG(SYS_PTP_TXSTAMP, 0x000f18), - REG(SYS_PTP_NXT, 0x000f1c), -@@ -290,6 +290,10 @@ static const u32 vsc9959_ptp_regmap[] = - REG(PTP_CFG_MISC, 0x0000a0), - REG(PTP_CLK_CFG_ADJ_CFG, 0x0000a4), - REG(PTP_CLK_CFG_ADJ_FREQ, 0x0000a8), -+ REG(PTP_CUR_NSF, 0x0000bc), -+ REG(PTP_CUR_NSEC, 0x0000c0), -+ REG(PTP_CUR_SEC_LSB, 0x0000c4), -+ REG(PTP_CUR_SEC_MSB, 0x0000c8), - }; - - static const u32 vsc9959_gcb_regmap[] = { ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -559,6 +559,7 @@ struct dsa_switch_ops { - */ - netdev_tx_t (*port_deferred_xmit)(struct dsa_switch *ds, int port, - struct sk_buff *skb); -+ int (*port_tsn_enable)(struct dsa_port *dp); - }; - - struct dsa_switch_driver { ---- a/net/dsa/dsa2.c -+++ b/net/dsa/dsa2.c -@@ -323,6 +323,10 @@ static int dsa_port_setup(struct dsa_por - if (err) - break; - -+ /* Enable TSN function on switch port */ -+ if (ds->ops->port_tsn_enable) -+ ds->ops->port_tsn_enable(dp); -+ - devlink_port_type_eth_set(dlp, dp->slave); - break; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0274-net-dsa-ocelot-alloc-memory-for-dsa-switch-instance.patch b/target/linux/layerscape/patches-5.4/701-net-0274-net-dsa-ocelot-alloc-memory-for-dsa-switch-instance.patch deleted file mode 100644 index 97e6f9d515..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0274-net-dsa-ocelot-alloc-memory-for-dsa-switch-instance.patch +++ /dev/null @@ -1,25 +0,0 @@ -From a9848cf13f495e12c55a01d437120efbb70ed747 Mon Sep 17 00:00:00 2001 -From: Xiaoliang Yang -Date: Fri, 29 Nov 2019 15:48:20 +0800 -Subject: [PATCH] net: dsa: ocelot: alloc memory for dsa switch instance - -The dsa switch instance hasn't alloc memory for switch ports in felix -initialization driver, which will cause NULL pointer issue. Using -dsa_switch_alloc to alloc memory for dsa switch instance. - -Signed-off-by: Xiaoliang Yang ---- - drivers/net/dsa/ocelot/felix.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/ocelot/felix.c -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -510,7 +510,7 @@ static int felix_pci_probe(struct pci_de - - ocelot->ptp = 1; - -- ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL); -+ ds = dsa_switch_alloc(&pdev->dev, felix->info->num_ports); - if (!ds) { - err = -ENOMEM; - dev_err(&pdev->dev, "Failed to allocate DSA switch\n"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0284-net-fsl_ppfe-dts-binding-for-ppfe.patch b/target/linux/layerscape/patches-5.4/701-net-0284-net-fsl_ppfe-dts-binding-for-ppfe.patch deleted file mode 100644 index 6659f9b67f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0284-net-fsl_ppfe-dts-binding-for-ppfe.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 08861b67c94a28e3a1bbcfb04a141ab0eafa5dac Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Sat, 16 Sep 2017 07:05:49 +0530 -Subject: [PATCH] net: fsl_ppfe: dts binding for ppfe - -Signed-off-by: Calvin Johnson -Signed-off-by: Anjaneyulu Jagarlmudi ---- - .../devicetree/bindings/net/fsl_ppfe/pfe.txt | 173 +++++++++++++++++++++ - 1 file changed, 173 insertions(+) - create mode 100644 Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt - ---- /dev/null -+++ b/Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt -@@ -0,0 +1,173 @@ -+============================================================================= -+NXP Programmable Packet Forwarding Engine Device Bindings -+ -+CONTENTS -+ - PFE Node -+ - Ethernet Node -+ -+============================================================================= -+PFE Node -+ -+DESCRIPTION -+ -+PFE Node has all the properties associated with Packet Forwarding Engine block. -+ -+PROPERTIES -+ -+- compatible -+ Usage: required -+ Value type: -+ Definition: Must include "fsl,pfe" -+ -+- reg -+ Usage: required -+ Value type: -+ Definition: A standard property. -+ Specifies the offset of the following registers: -+ - PFE configuration registers -+ - DDR memory used by PFE -+ -+- fsl,pfe-num-interfaces -+ Usage: required -+ Value type: -+ Definition: Must be present. Value can be either one or two. -+ -+- interrupts -+ Usage: required -+ Value type: -+ Definition: Three interrupts are specified in this property. -+ - HIF interrupt -+ - HIF NO COPY interrupt -+ - Wake On LAN interrupt -+ -+- interrupt-names -+ Usage: required -+ Value type: -+ Definition: Following strings are defined for the 3 interrupts. -+ "pfe_hif" - HIF interrupt -+ "pfe_hif_nocpy" - HIF NO COPY interrupt -+ "pfe_wol" - Wake On LAN interrupt -+ -+- memory-region -+ Usage: required -+ Value type: -+ Definition: phandle to a node describing reserved memory used by pfe. -+ Refer:- Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt -+ -+- fsl,pfe-scfg -+ Usage: required -+ Value type: -+ Definition: phandle for scfg. -+ -+- fsl,rcpm-wakeup -+ Usage: required -+ Value type: -+ Definition: phandle for rcpm. -+ -+- clocks -+ Usage: required -+ Value type: -+ Definition: phandle for clockgen. -+ -+- clock-names -+ Usage: required -+ Value type: -+ Definition: phandle for clock name. -+ -+EXAMPLE -+ -+pfe: pfe@04000000 { -+ compatible = "fsl,pfe"; -+ reg = <0x0 0x04000000 0x0 0xc00000>, /* AXI 16M */ -+ <0x0 0x83400000 0x0 0xc00000>; /* PFE DDR 12M */ -+ reg-names = "pfe", "pfe-ddr"; -+ fsl,pfe-num-interfaces = <0x2>; -+ interrupts = <0 172 0x4>, /* HIF interrupt */ -+ <0 173 0x4>, /*HIF_NOCPY interrupt */ -+ <0 174 0x4>; /* WoL interrupt */ -+ interrupt-names = "pfe_hif", "pfe_hif_nocpy", "pfe_wol"; -+ memory-region = <&pfe_reserved>; -+ fsl,pfe-scfg = <&scfg 0>; -+ fsl,rcpm-wakeup = <&rcpm 0xf0000020>; -+ clocks = <&clockgen 4 0>; -+ clock-names = "pfe"; -+ -+ status = "okay"; -+ pfe_mac0: ethernet@0 { -+ }; -+ -+ pfe_mac1: ethernet@1 { -+ }; -+}; -+ -+============================================================================= -+Ethernet Node -+ -+DESCRIPTION -+ -+Ethernet Node has all the properties associated with PFE used by platforms to -+connect to PHY: -+ -+PROPERTIES -+ -+- compatible -+ Usage: required -+ Value type: -+ Definition: Must include "fsl,pfe-gemac-port" -+ -+- reg -+ Usage: required -+ Value type: -+ Definition: A standard property. -+ Specifies the gemacid of the interface. -+ -+- fsl,gemac-bus-id -+ Usage: required -+ Value type: -+ Definition: Must be present. Value should be the id of the bus -+ connected to gemac. -+ -+- fsl,gemac-phy-id -+ Usage: required -+ Value type: -+ Definition: Must be present. Value should be the id of the phy -+ connected to gemac. -+ -+- fsl,mdio-mux-val -+ Usage: required -+ Value type: -+ Definition: Must be present. Value can be either 0 or 2 or 3. -+ This value is used to configure the mux to enable mdio. -+ -+- phy-mode -+ Usage: required -+ Value type: -+ Definition: Must include "sgmii" -+ -+- fsl,pfe-phy-if-flags -+ Usage: required -+ Value type: -+ Definition: Must be present. Value should be 0 by default. -+ If there is not phy connected, this need to be 1. -+ -+- mdio -+ optional subnode that specifies the mdio bus. This has reg -+ property which is used to enable/disable the mdio bus. -+ -+EXAMPLE -+ -+ethernet@0 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x0>; /* GEM_ID */ -+ fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -+ fsl,gemac-phy-id = <0x2>; /* PHY_ID */ -+ fsl,mdio-mux-val = <0x0>; -+ phy-mode = "sgmii"; -+ fsl,pfe-phy-if-flags = <0x0>; -+ -+ mdio@0 { -+ reg = <0x1>; /* enabled/disabled */ -+ }; -+}; diff --git a/target/linux/layerscape/patches-5.4/701-net-0285-staging-fsl_ppfe-eth-header-files-for-pfe-driver.patch b/target/linux/layerscape/patches-5.4/701-net-0285-staging-fsl_ppfe-eth-header-files-for-pfe-driver.patch deleted file mode 100644 index b513786910..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0285-staging-fsl_ppfe-eth-header-files-for-pfe-driver.patch +++ /dev/null @@ -1,2622 +0,0 @@ -From d9bd3a5f795f45fd6847f080231e1e760004dca9 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Sat, 16 Sep 2017 14:21:37 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: header files for pfe driver - -This patch has all pfe header files. - -Signed-off-by: Calvin Johnson -Signed-off-by: Anjaneyulu Jagarlmudi ---- - drivers/staging/fsl_ppfe/include/pfe/cbus.h | 78 +++++ - drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h | 55 +++ - .../staging/fsl_ppfe/include/pfe/cbus/class_csr.h | 289 ++++++++++++++++ - .../staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h | 242 ++++++++++++++ - drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h | 86 +++++ - drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h | 100 ++++++ - .../staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h | 50 +++ - .../staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h | 168 ++++++++++ - .../staging/fsl_ppfe/include/pfe/cbus/util_csr.h | 61 ++++ - drivers/staging/fsl_ppfe/include/pfe/pfe.h | 372 +++++++++++++++++++++ - drivers/staging/fsl_ppfe/pfe_ctrl.h | 112 +++++++ - drivers/staging/fsl_ppfe/pfe_debugfs.h | 25 ++ - drivers/staging/fsl_ppfe/pfe_eth.h | 184 ++++++++++ - drivers/staging/fsl_ppfe/pfe_firmware.h | 32 ++ - drivers/staging/fsl_ppfe/pfe_hif.h | 211 ++++++++++++ - drivers/staging/fsl_ppfe/pfe_hif_lib.h | 239 +++++++++++++ - drivers/staging/fsl_ppfe/pfe_hw.h | 27 ++ - drivers/staging/fsl_ppfe/pfe_mod.h | 112 +++++++ - drivers/staging/fsl_ppfe/pfe_perfmon.h | 38 +++ - drivers/staging/fsl_ppfe/pfe_sysfs.h | 29 ++ - 20 files changed, 2510 insertions(+) - create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus.h - create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h - create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h - create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h - create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h - create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h - create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h - create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h - create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h - create mode 100644 drivers/staging/fsl_ppfe/include/pfe/pfe.h - create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.h - create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.h - create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.h - create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.h - create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.h - create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.h - create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.h - create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.h - create mode 100644 drivers/staging/fsl_ppfe/pfe_perfmon.h - create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.h - ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus.h -@@ -0,0 +1,78 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _CBUS_H_ -+#define _CBUS_H_ -+ -+#define EMAC1_BASE_ADDR (CBUS_BASE_ADDR + 0x200000) -+#define EGPI1_BASE_ADDR (CBUS_BASE_ADDR + 0x210000) -+#define EMAC2_BASE_ADDR (CBUS_BASE_ADDR + 0x220000) -+#define EGPI2_BASE_ADDR (CBUS_BASE_ADDR + 0x230000) -+#define BMU1_BASE_ADDR (CBUS_BASE_ADDR + 0x240000) -+#define BMU2_BASE_ADDR (CBUS_BASE_ADDR + 0x250000) -+#define ARB_BASE_ADDR (CBUS_BASE_ADDR + 0x260000) -+#define DDR_CONFIG_BASE_ADDR (CBUS_BASE_ADDR + 0x270000) -+#define HIF_BASE_ADDR (CBUS_BASE_ADDR + 0x280000) -+#define HGPI_BASE_ADDR (CBUS_BASE_ADDR + 0x290000) -+#define LMEM_BASE_ADDR (CBUS_BASE_ADDR + 0x300000) -+#define LMEM_SIZE 0x10000 -+#define LMEM_END (LMEM_BASE_ADDR + LMEM_SIZE) -+#define TMU_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x310000) -+#define CLASS_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x320000) -+#define HIF_NOCPY_BASE_ADDR (CBUS_BASE_ADDR + 0x350000) -+#define UTIL_CSR_BASE_ADDR (CBUS_BASE_ADDR + 0x360000) -+#define CBUS_GPT_BASE_ADDR (CBUS_BASE_ADDR + 0x370000) -+ -+/* -+ * defgroup XXX_MEM_ACCESS_ADDR PE memory access through CSR -+ * XXX_MEM_ACCESS_ADDR register bit definitions. -+ */ -+#define PE_MEM_ACCESS_WRITE BIT(31) /* Internal Memory Write. */ -+#define PE_MEM_ACCESS_IMEM BIT(15) -+#define PE_MEM_ACCESS_DMEM BIT(16) -+ -+/* Byte Enables of the Internal memory access. These are interpred in BE */ -+#define PE_MEM_ACCESS_BYTE_ENABLE(offset, size) \ -+ ({ typeof(size) size_ = (size); \ -+ (((BIT(size_) - 1) << (4 - (offset) - (size_))) & 0xf) << 24; }) -+ -+#include "cbus/emac_mtip.h" -+#include "cbus/gpi.h" -+#include "cbus/bmu.h" -+#include "cbus/hif.h" -+#include "cbus/tmu_csr.h" -+#include "cbus/class_csr.h" -+#include "cbus/hif_nocpy.h" -+#include "cbus/util_csr.h" -+ -+/* PFE cores states */ -+#define CORE_DISABLE 0x00000000 -+#define CORE_ENABLE 0x00000001 -+#define CORE_SW_RESET 0x00000002 -+ -+/* LMEM defines */ -+#define LMEM_HDR_SIZE 0x0010 -+#define LMEM_BUF_SIZE_LN2 0x7 -+#define LMEM_BUF_SIZE BIT(LMEM_BUF_SIZE_LN2) -+ -+/* DDR defines */ -+#define DDR_HDR_SIZE 0x0100 -+#define DDR_BUF_SIZE_LN2 0xb -+#define DDR_BUF_SIZE BIT(DDR_BUF_SIZE_LN2) -+ -+#endif /* _CBUS_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h -@@ -0,0 +1,55 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _BMU_H_ -+#define _BMU_H_ -+ -+#define BMU_VERSION 0x000 -+#define BMU_CTRL 0x004 -+#define BMU_UCAST_CONFIG 0x008 -+#define BMU_UCAST_BASE_ADDR 0x00c -+#define BMU_BUF_SIZE 0x010 -+#define BMU_BUF_CNT 0x014 -+#define BMU_THRES 0x018 -+#define BMU_INT_SRC 0x020 -+#define BMU_INT_ENABLE 0x024 -+#define BMU_ALLOC_CTRL 0x030 -+#define BMU_FREE_CTRL 0x034 -+#define BMU_FREE_ERR_ADDR 0x038 -+#define BMU_CURR_BUF_CNT 0x03c -+#define BMU_MCAST_CNT 0x040 -+#define BMU_MCAST_ALLOC_CTRL 0x044 -+#define BMU_REM_BUF_CNT 0x048 -+#define BMU_LOW_WATERMARK 0x050 -+#define BMU_HIGH_WATERMARK 0x054 -+#define BMU_INT_MEM_ACCESS 0x100 -+ -+struct BMU_CFG { -+ unsigned long baseaddr; -+ u32 count; -+ u32 size; -+ u32 low_watermark; -+ u32 high_watermark; -+}; -+ -+#define BMU1_BUF_SIZE LMEM_BUF_SIZE_LN2 -+#define BMU2_BUF_SIZE DDR_BUF_SIZE_LN2 -+ -+#define BMU2_MCAST_ALLOC_CTRL (BMU2_BASE_ADDR + BMU_MCAST_ALLOC_CTRL) -+ -+#endif /* _BMU_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h -@@ -0,0 +1,289 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _CLASS_CSR_H_ -+#define _CLASS_CSR_H_ -+ -+/* @file class_csr.h. -+ * class_csr - block containing all the classifier control and status register. -+ * Mapped on CBUS and accessible from all PE's and ARM. -+ */ -+#define CLASS_VERSION (CLASS_CSR_BASE_ADDR + 0x000) -+#define CLASS_TX_CTRL (CLASS_CSR_BASE_ADDR + 0x004) -+#define CLASS_INQ_PKTPTR (CLASS_CSR_BASE_ADDR + 0x010) -+ -+/* (ddr_hdr_size[24:16], lmem_hdr_size[5:0]) */ -+#define CLASS_HDR_SIZE (CLASS_CSR_BASE_ADDR + 0x014) -+ -+/* LMEM header size for the Classifier block.\ Data in the LMEM -+ * is written from this offset. -+ */ -+#define CLASS_HDR_SIZE_LMEM(off) ((off) & 0x3f) -+ -+/* DDR header size for the Classifier block.\ Data in the DDR -+ * is written from this offset. -+ */ -+#define CLASS_HDR_SIZE_DDR(off) (((off) & 0x1ff) << 16) -+ -+#define CLASS_PE0_QB_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x020) -+ -+/* DMEM address of first [15:0] and second [31:16] buffers on QB side. */ -+#define CLASS_PE0_QB_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x024) -+ -+/* DMEM address of third [15:0] and fourth [31:16] buffers on QB side. */ -+#define CLASS_PE0_RO_DM_ADDR0 (CLASS_CSR_BASE_ADDR + 0x060) -+ -+/* DMEM address of first [15:0] and second [31:16] buffers on RO side. */ -+#define CLASS_PE0_RO_DM_ADDR1 (CLASS_CSR_BASE_ADDR + 0x064) -+ -+/* DMEM address of third [15:0] and fourth [31:16] buffers on RO side. */ -+ -+/* @name Class PE memory access. Allows external PE's and HOST to -+ * read/write PMEM/DMEM memory ranges for each classifier PE. -+ */ -+/* {sr_pe_mem_cmd[31], csr_pe_mem_wren[27:24], csr_pe_mem_addr[23:0]}, -+ * See \ref XXX_MEM_ACCESS_ADDR for details. -+ */ -+#define CLASS_MEM_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x100) -+ -+/* Internal Memory Access Write Data [31:0] */ -+#define CLASS_MEM_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x104) -+ -+/* Internal Memory Access Read Data [31:0] */ -+#define CLASS_MEM_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x108) -+#define CLASS_TM_INQ_ADDR (CLASS_CSR_BASE_ADDR + 0x114) -+#define CLASS_PE_STATUS (CLASS_CSR_BASE_ADDR + 0x118) -+ -+#define CLASS_PHY1_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x11c) -+#define CLASS_PHY1_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x120) -+#define CLASS_PHY1_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x124) -+#define CLASS_PHY1_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x128) -+#define CLASS_PHY1_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x12c) -+#define CLASS_PHY1_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x130) -+#define CLASS_PHY1_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x134) -+#define CLASS_PHY1_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x138) -+#define CLASS_PHY1_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x13c) -+#define CLASS_PHY1_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x140) -+#define CLASS_PHY2_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x144) -+#define CLASS_PHY2_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x148) -+#define CLASS_PHY2_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x14c) -+#define CLASS_PHY2_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x150) -+#define CLASS_PHY2_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x154) -+#define CLASS_PHY2_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x158) -+#define CLASS_PHY2_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x15c) -+#define CLASS_PHY2_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x160) -+#define CLASS_PHY2_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x164) -+#define CLASS_PHY2_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x168) -+#define CLASS_PHY3_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x16c) -+#define CLASS_PHY3_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x170) -+#define CLASS_PHY3_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x174) -+#define CLASS_PHY3_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x178) -+#define CLASS_PHY3_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x17c) -+#define CLASS_PHY3_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x180) -+#define CLASS_PHY3_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x184) -+#define CLASS_PHY3_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x188) -+#define CLASS_PHY3_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x18c) -+#define CLASS_PHY3_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x190) -+#define CLASS_PHY1_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x194) -+#define CLASS_PHY1_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x198) -+#define CLASS_PHY1_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x19c) -+#define CLASS_PHY1_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a0) -+#define CLASS_PHY2_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a4) -+#define CLASS_PHY2_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1a8) -+#define CLASS_PHY2_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1ac) -+#define CLASS_PHY2_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b0) -+#define CLASS_PHY3_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b4) -+#define CLASS_PHY3_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1b8) -+#define CLASS_PHY3_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1bc) -+#define CLASS_PHY3_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c0) -+#define CLASS_PHY4_ICMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c4) -+#define CLASS_PHY4_IGMP_PKTS (CLASS_CSR_BASE_ADDR + 0x1c8) -+#define CLASS_PHY4_TCP_PKTS (CLASS_CSR_BASE_ADDR + 0x1cc) -+#define CLASS_PHY4_UDP_PKTS (CLASS_CSR_BASE_ADDR + 0x1d0) -+#define CLASS_PHY4_RX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d4) -+#define CLASS_PHY4_TX_PKTS (CLASS_CSR_BASE_ADDR + 0x1d8) -+#define CLASS_PHY4_LP_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1dc) -+#define CLASS_PHY4_INTF_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e0) -+#define CLASS_PHY4_INTF_MATCH_PKTS (CLASS_CSR_BASE_ADDR + 0x1e4) -+#define CLASS_PHY4_L3_FAIL_PKTS (CLASS_CSR_BASE_ADDR + 0x1e8) -+#define CLASS_PHY4_V4_PKTS (CLASS_CSR_BASE_ADDR + 0x1ec) -+#define CLASS_PHY4_V6_PKTS (CLASS_CSR_BASE_ADDR + 0x1f0) -+#define CLASS_PHY4_CHKSUM_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f4) -+#define CLASS_PHY4_TTL_ERR_PKTS (CLASS_CSR_BASE_ADDR + 0x1f8) -+ -+#define CLASS_PE_SYS_CLK_RATIO (CLASS_CSR_BASE_ADDR + 0x200) -+#define CLASS_AFULL_THRES (CLASS_CSR_BASE_ADDR + 0x204) -+#define CLASS_GAP_BETWEEN_READS (CLASS_CSR_BASE_ADDR + 0x208) -+#define CLASS_MAX_BUF_CNT (CLASS_CSR_BASE_ADDR + 0x20c) -+#define CLASS_TSQ_FIFO_THRES (CLASS_CSR_BASE_ADDR + 0x210) -+#define CLASS_TSQ_MAX_CNT (CLASS_CSR_BASE_ADDR + 0x214) -+#define CLASS_IRAM_DATA_0 (CLASS_CSR_BASE_ADDR + 0x218) -+#define CLASS_IRAM_DATA_1 (CLASS_CSR_BASE_ADDR + 0x21c) -+#define CLASS_IRAM_DATA_2 (CLASS_CSR_BASE_ADDR + 0x220) -+#define CLASS_IRAM_DATA_3 (CLASS_CSR_BASE_ADDR + 0x224) -+ -+#define CLASS_BUS_ACCESS_ADDR (CLASS_CSR_BASE_ADDR + 0x228) -+ -+#define CLASS_BUS_ACCESS_WDATA (CLASS_CSR_BASE_ADDR + 0x22c) -+#define CLASS_BUS_ACCESS_RDATA (CLASS_CSR_BASE_ADDR + 0x230) -+ -+/* (route_entry_size[9:0], route_hash_size[23:16] -+ * (this is actually ln2(size))) -+ */ -+#define CLASS_ROUTE_HASH_ENTRY_SIZE (CLASS_CSR_BASE_ADDR + 0x234) -+ -+#define CLASS_ROUTE_ENTRY_SIZE(size) ((size) & 0x1ff) -+#define CLASS_ROUTE_HASH_SIZE(hash_bits) (((hash_bits) & 0xff) << 16) -+ -+#define CLASS_ROUTE_TABLE_BASE (CLASS_CSR_BASE_ADDR + 0x238) -+ -+#define CLASS_ROUTE_MULTI (CLASS_CSR_BASE_ADDR + 0x23c) -+#define CLASS_SMEM_OFFSET (CLASS_CSR_BASE_ADDR + 0x240) -+#define CLASS_LMEM_BUF_SIZE (CLASS_CSR_BASE_ADDR + 0x244) -+#define CLASS_VLAN_ID (CLASS_CSR_BASE_ADDR + 0x248) -+#define CLASS_BMU1_BUF_FREE (CLASS_CSR_BASE_ADDR + 0x24c) -+#define CLASS_USE_TMU_INQ (CLASS_CSR_BASE_ADDR + 0x250) -+#define CLASS_VLAN_ID1 (CLASS_CSR_BASE_ADDR + 0x254) -+ -+#define CLASS_BUS_ACCESS_BASE (CLASS_CSR_BASE_ADDR + 0x258) -+#define CLASS_BUS_ACCESS_BASE_MASK (0xFF000000) -+/* bit 31:24 of PE peripheral address are stored in CLASS_BUS_ACCESS_BASE */ -+ -+#define CLASS_HIF_PARSE (CLASS_CSR_BASE_ADDR + 0x25c) -+ -+#define CLASS_HOST_PE0_GP (CLASS_CSR_BASE_ADDR + 0x260) -+#define CLASS_PE0_GP (CLASS_CSR_BASE_ADDR + 0x264) -+#define CLASS_HOST_PE1_GP (CLASS_CSR_BASE_ADDR + 0x268) -+#define CLASS_PE1_GP (CLASS_CSR_BASE_ADDR + 0x26c) -+#define CLASS_HOST_PE2_GP (CLASS_CSR_BASE_ADDR + 0x270) -+#define CLASS_PE2_GP (CLASS_CSR_BASE_ADDR + 0x274) -+#define CLASS_HOST_PE3_GP (CLASS_CSR_BASE_ADDR + 0x278) -+#define CLASS_PE3_GP (CLASS_CSR_BASE_ADDR + 0x27c) -+#define CLASS_HOST_PE4_GP (CLASS_CSR_BASE_ADDR + 0x280) -+#define CLASS_PE4_GP (CLASS_CSR_BASE_ADDR + 0x284) -+#define CLASS_HOST_PE5_GP (CLASS_CSR_BASE_ADDR + 0x288) -+#define CLASS_PE5_GP (CLASS_CSR_BASE_ADDR + 0x28c) -+ -+#define CLASS_PE_INT_SRC (CLASS_CSR_BASE_ADDR + 0x290) -+#define CLASS_PE_INT_ENABLE (CLASS_CSR_BASE_ADDR + 0x294) -+ -+#define CLASS_TPID0_TPID1 (CLASS_CSR_BASE_ADDR + 0x298) -+#define CLASS_TPID2 (CLASS_CSR_BASE_ADDR + 0x29c) -+ -+#define CLASS_L4_CHKSUM_ADDR (CLASS_CSR_BASE_ADDR + 0x2a0) -+ -+#define CLASS_PE0_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a4) -+#define CLASS_PE1_DEBUG (CLASS_CSR_BASE_ADDR + 0x2a8) -+#define CLASS_PE2_DEBUG (CLASS_CSR_BASE_ADDR + 0x2ac) -+#define CLASS_PE3_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b0) -+#define CLASS_PE4_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b4) -+#define CLASS_PE5_DEBUG (CLASS_CSR_BASE_ADDR + 0x2b8) -+ -+#define CLASS_STATE (CLASS_CSR_BASE_ADDR + 0x2bc) -+ -+/* CLASS defines */ -+#define CLASS_PBUF_SIZE 0x100 /* Fixed by hardware */ -+#define CLASS_PBUF_HEADER_OFFSET 0x80 /* Can be configured */ -+ -+/* Can be configured */ -+#define CLASS_PBUF0_BASE_ADDR 0x000 -+/* Can be configured */ -+#define CLASS_PBUF1_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + CLASS_PBUF_SIZE) -+/* Can be configured */ -+#define CLASS_PBUF2_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + CLASS_PBUF_SIZE) -+/* Can be configured */ -+#define CLASS_PBUF3_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + CLASS_PBUF_SIZE) -+ -+#define CLASS_PBUF0_HEADER_BASE_ADDR (CLASS_PBUF0_BASE_ADDR + \ -+ CLASS_PBUF_HEADER_OFFSET) -+#define CLASS_PBUF1_HEADER_BASE_ADDR (CLASS_PBUF1_BASE_ADDR + \ -+ CLASS_PBUF_HEADER_OFFSET) -+#define CLASS_PBUF2_HEADER_BASE_ADDR (CLASS_PBUF2_BASE_ADDR + \ -+ CLASS_PBUF_HEADER_OFFSET) -+#define CLASS_PBUF3_HEADER_BASE_ADDR (CLASS_PBUF3_BASE_ADDR + \ -+ CLASS_PBUF_HEADER_OFFSET) -+ -+#define CLASS_PE0_RO_DM_ADDR0_VAL ((CLASS_PBUF1_BASE_ADDR << 16) | \ -+ CLASS_PBUF0_BASE_ADDR) -+#define CLASS_PE0_RO_DM_ADDR1_VAL ((CLASS_PBUF3_BASE_ADDR << 16) | \ -+ CLASS_PBUF2_BASE_ADDR) -+ -+#define CLASS_PE0_QB_DM_ADDR0_VAL ((CLASS_PBUF1_HEADER_BASE_ADDR << 16) |\ -+ CLASS_PBUF0_HEADER_BASE_ADDR) -+#define CLASS_PE0_QB_DM_ADDR1_VAL ((CLASS_PBUF3_HEADER_BASE_ADDR << 16) |\ -+ CLASS_PBUF2_HEADER_BASE_ADDR) -+ -+#define CLASS_ROUTE_SIZE 128 -+#define CLASS_MAX_ROUTE_SIZE 256 -+#define CLASS_ROUTE_HASH_BITS 20 -+#define CLASS_ROUTE_HASH_MASK (BIT(CLASS_ROUTE_HASH_BITS) - 1) -+ -+/* Can be configured */ -+#define CLASS_ROUTE0_BASE_ADDR 0x400 -+/* Can be configured */ -+#define CLASS_ROUTE1_BASE_ADDR (CLASS_ROUTE0_BASE_ADDR + CLASS_ROUTE_SIZE) -+/* Can be configured */ -+#define CLASS_ROUTE2_BASE_ADDR (CLASS_ROUTE1_BASE_ADDR + CLASS_ROUTE_SIZE) -+/* Can be configured */ -+#define CLASS_ROUTE3_BASE_ADDR (CLASS_ROUTE2_BASE_ADDR + CLASS_ROUTE_SIZE) -+ -+#define CLASS_SA_SIZE 128 -+#define CLASS_IPSEC_SA0_BASE_ADDR 0x600 -+/* not used */ -+#define CLASS_IPSEC_SA1_BASE_ADDR (CLASS_IPSEC_SA0_BASE_ADDR + CLASS_SA_SIZE) -+/* not used */ -+#define CLASS_IPSEC_SA2_BASE_ADDR (CLASS_IPSEC_SA1_BASE_ADDR + CLASS_SA_SIZE) -+/* not used */ -+#define CLASS_IPSEC_SA3_BASE_ADDR (CLASS_IPSEC_SA2_BASE_ADDR + CLASS_SA_SIZE) -+ -+/* generic purpose free dmem buffer, last portion of 2K dmem pbuf */ -+#define CLASS_GP_DMEM_BUF_SIZE (2048 - (CLASS_PBUF_SIZE * 4) - \ -+ (CLASS_ROUTE_SIZE * 4) - (CLASS_SA_SIZE)) -+#define CLASS_GP_DMEM_BUF ((void *)(CLASS_IPSEC_SA0_BASE_ADDR + \ -+ CLASS_SA_SIZE)) -+ -+#define TWO_LEVEL_ROUTE BIT(0) -+#define PHYNO_IN_HASH BIT(1) -+#define HW_ROUTE_FETCH BIT(3) -+#define HW_BRIDGE_FETCH BIT(5) -+#define IP_ALIGNED BIT(6) -+#define ARC_HIT_CHECK_EN BIT(7) -+#define CLASS_TOE BIT(11) -+#define HASH_NORMAL (0 << 12) -+#define HASH_CRC_PORT BIT(12) -+#define HASH_CRC_IP (2 << 12) -+#define HASH_CRC_PORT_IP (3 << 12) -+#define QB2BUS_LE BIT(15) -+ -+#define TCP_CHKSUM_DROP BIT(0) -+#define UDP_CHKSUM_DROP BIT(1) -+#define IPV4_CHKSUM_DROP BIT(9) -+ -+/*CLASS_HIF_PARSE bits*/ -+#define HIF_PKT_CLASS_EN BIT(0) -+#define HIF_PKT_OFFSET(ofst) (((ofst) & 0xF) << 1) -+ -+struct class_cfg { -+ u32 toe_mode; -+ unsigned long route_table_baseaddr; -+ u32 route_table_hash_bits; -+ u32 pe_sys_clk_ratio; -+ u32 resume; -+}; -+ -+#endif /* _CLASS_CSR_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h -@@ -0,0 +1,242 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _EMAC_H_ -+#define _EMAC_H_ -+ -+#include -+ -+#define EMAC_IEVENT_REG 0x004 -+#define EMAC_IMASK_REG 0x008 -+#define EMAC_R_DES_ACTIVE_REG 0x010 -+#define EMAC_X_DES_ACTIVE_REG 0x014 -+#define EMAC_ECNTRL_REG 0x024 -+#define EMAC_MII_DATA_REG 0x040 -+#define EMAC_MII_CTRL_REG 0x044 -+#define EMAC_MIB_CTRL_STS_REG 0x064 -+#define EMAC_RCNTRL_REG 0x084 -+#define EMAC_TCNTRL_REG 0x0C4 -+#define EMAC_PHY_ADDR_LOW 0x0E4 -+#define EMAC_PHY_ADDR_HIGH 0x0E8 -+#define EMAC_GAUR 0x120 -+#define EMAC_GALR 0x124 -+#define EMAC_TFWR_STR_FWD 0x144 -+#define EMAC_RX_SECTION_FULL 0x190 -+#define EMAC_RX_SECTION_EMPTY 0x194 -+#define EMAC_TX_SECTION_EMPTY 0x1A0 -+#define EMAC_TRUNC_FL 0x1B0 -+ -+#define RMON_T_DROP 0x200 /* Count of frames not cntd correctly */ -+#define RMON_T_PACKETS 0x204 /* RMON TX packet count */ -+#define RMON_T_BC_PKT 0x208 /* RMON TX broadcast pkts */ -+#define RMON_T_MC_PKT 0x20c /* RMON TX multicast pkts */ -+#define RMON_T_CRC_ALIGN 0x210 /* RMON TX pkts with CRC align err */ -+#define RMON_T_UNDERSIZE 0x214 /* RMON TX pkts < 64 bytes, good CRC */ -+#define RMON_T_OVERSIZE 0x218 /* RMON TX pkts > MAX_FL bytes good CRC */ -+#define RMON_T_FRAG 0x21c /* RMON TX pkts < 64 bytes, bad CRC */ -+#define RMON_T_JAB 0x220 /* RMON TX pkts > MAX_FL bytes, bad CRC */ -+#define RMON_T_COL 0x224 /* RMON TX collision count */ -+#define RMON_T_P64 0x228 /* RMON TX 64 byte pkts */ -+#define RMON_T_P65TO127 0x22c /* RMON TX 65 to 127 byte pkts */ -+#define RMON_T_P128TO255 0x230 /* RMON TX 128 to 255 byte pkts */ -+#define RMON_T_P256TO511 0x234 /* RMON TX 256 to 511 byte pkts */ -+#define RMON_T_P512TO1023 0x238 /* RMON TX 512 to 1023 byte pkts */ -+#define RMON_T_P1024TO2047 0x23c /* RMON TX 1024 to 2047 byte pkts */ -+#define RMON_T_P_GTE2048 0x240 /* RMON TX pkts > 2048 bytes */ -+#define RMON_T_OCTETS 0x244 /* RMON TX octets */ -+#define IEEE_T_DROP 0x248 /* Count of frames not counted crtly */ -+#define IEEE_T_FRAME_OK 0x24c /* Frames tx'd OK */ -+#define IEEE_T_1COL 0x250 /* Frames tx'd with single collision */ -+#define IEEE_T_MCOL 0x254 /* Frames tx'd with multiple collision */ -+#define IEEE_T_DEF 0x258 /* Frames tx'd after deferral delay */ -+#define IEEE_T_LCOL 0x25c /* Frames tx'd with late collision */ -+#define IEEE_T_EXCOL 0x260 /* Frames tx'd with excesv collisions */ -+#define IEEE_T_MACERR 0x264 /* Frames tx'd with TX FIFO underrun */ -+#define IEEE_T_CSERR 0x268 /* Frames tx'd with carrier sense err */ -+#define IEEE_T_SQE 0x26c /* Frames tx'd with SQE err */ -+#define IEEE_T_FDXFC 0x270 /* Flow control pause frames tx'd */ -+#define IEEE_T_OCTETS_OK 0x274 /* Octet count for frames tx'd w/o err */ -+#define RMON_R_PACKETS 0x284 /* RMON RX packet count */ -+#define RMON_R_BC_PKT 0x288 /* RMON RX broadcast pkts */ -+#define RMON_R_MC_PKT 0x28c /* RMON RX multicast pkts */ -+#define RMON_R_CRC_ALIGN 0x290 /* RMON RX pkts with CRC alignment err */ -+#define RMON_R_UNDERSIZE 0x294 /* RMON RX pkts < 64 bytes, good CRC */ -+#define RMON_R_OVERSIZE 0x298 /* RMON RX pkts > MAX_FL bytes good CRC */ -+#define RMON_R_FRAG 0x29c /* RMON RX pkts < 64 bytes, bad CRC */ -+#define RMON_R_JAB 0x2a0 /* RMON RX pkts > MAX_FL bytes, bad CRC */ -+#define RMON_R_RESVD_O 0x2a4 /* Reserved */ -+#define RMON_R_P64 0x2a8 /* RMON RX 64 byte pkts */ -+#define RMON_R_P65TO127 0x2ac /* RMON RX 65 to 127 byte pkts */ -+#define RMON_R_P128TO255 0x2b0 /* RMON RX 128 to 255 byte pkts */ -+#define RMON_R_P256TO511 0x2b4 /* RMON RX 256 to 511 byte pkts */ -+#define RMON_R_P512TO1023 0x2b8 /* RMON RX 512 to 1023 byte pkts */ -+#define RMON_R_P1024TO2047 0x2bc /* RMON RX 1024 to 2047 byte pkts */ -+#define RMON_R_P_GTE2048 0x2c0 /* RMON RX pkts > 2048 bytes */ -+#define RMON_R_OCTETS 0x2c4 /* RMON RX octets */ -+#define IEEE_R_DROP 0x2c8 /* Count frames not counted correctly */ -+#define IEEE_R_FRAME_OK 0x2cc /* Frames rx'd OK */ -+#define IEEE_R_CRC 0x2d0 /* Frames rx'd with CRC err */ -+#define IEEE_R_ALIGN 0x2d4 /* Frames rx'd with alignment err */ -+#define IEEE_R_MACERR 0x2d8 /* Receive FIFO overflow count */ -+#define IEEE_R_FDXFC 0x2dc /* Flow control pause frames rx'd */ -+#define IEEE_R_OCTETS_OK 0x2e0 /* Octet cnt for frames rx'd w/o err */ -+ -+#define EMAC_SMAC_0_0 0x500 /*Supplemental MAC Address 0 (RW).*/ -+#define EMAC_SMAC_0_1 0x504 /*Supplemental MAC Address 0 (RW).*/ -+ -+/* GEMAC definitions and settings */ -+ -+#define EMAC_PORT_0 0 -+#define EMAC_PORT_1 1 -+ -+/* GEMAC Bit definitions */ -+#define EMAC_IEVENT_HBERR 0x80000000 -+#define EMAC_IEVENT_BABR 0x40000000 -+#define EMAC_IEVENT_BABT 0x20000000 -+#define EMAC_IEVENT_GRA 0x10000000 -+#define EMAC_IEVENT_TXF 0x08000000 -+#define EMAC_IEVENT_TXB 0x04000000 -+#define EMAC_IEVENT_RXF 0x02000000 -+#define EMAC_IEVENT_RXB 0x01000000 -+#define EMAC_IEVENT_MII 0x00800000 -+#define EMAC_IEVENT_EBERR 0x00400000 -+#define EMAC_IEVENT_LC 0x00200000 -+#define EMAC_IEVENT_RL 0x00100000 -+#define EMAC_IEVENT_UN 0x00080000 -+ -+#define EMAC_IMASK_HBERR 0x80000000 -+#define EMAC_IMASK_BABR 0x40000000 -+#define EMAC_IMASKT_BABT 0x20000000 -+#define EMAC_IMASK_GRA 0x10000000 -+#define EMAC_IMASKT_TXF 0x08000000 -+#define EMAC_IMASK_TXB 0x04000000 -+#define EMAC_IMASKT_RXF 0x02000000 -+#define EMAC_IMASK_RXB 0x01000000 -+#define EMAC_IMASK_MII 0x00800000 -+#define EMAC_IMASK_EBERR 0x00400000 -+#define EMAC_IMASK_LC 0x00200000 -+#define EMAC_IMASKT_RL 0x00100000 -+#define EMAC_IMASK_UN 0x00080000 -+ -+#define EMAC_RCNTRL_MAX_FL_SHIFT 16 -+#define EMAC_RCNTRL_LOOP 0x00000001 -+#define EMAC_RCNTRL_DRT 0x00000002 -+#define EMAC_RCNTRL_MII_MODE 0x00000004 -+#define EMAC_RCNTRL_PROM 0x00000008 -+#define EMAC_RCNTRL_BC_REJ 0x00000010 -+#define EMAC_RCNTRL_FCE 0x00000020 -+#define EMAC_RCNTRL_RGMII 0x00000040 -+#define EMAC_RCNTRL_SGMII 0x00000080 -+#define EMAC_RCNTRL_RMII 0x00000100 -+#define EMAC_RCNTRL_RMII_10T 0x00000200 -+#define EMAC_RCNTRL_CRC_FWD 0x00004000 -+ -+#define EMAC_TCNTRL_GTS 0x00000001 -+#define EMAC_TCNTRL_HBC 0x00000002 -+#define EMAC_TCNTRL_FDEN 0x00000004 -+#define EMAC_TCNTRL_TFC_PAUSE 0x00000008 -+#define EMAC_TCNTRL_RFC_PAUSE 0x00000010 -+ -+#define EMAC_ECNTRL_RESET 0x00000001 /* reset the EMAC */ -+#define EMAC_ECNTRL_ETHER_EN 0x00000002 /* enable the EMAC */ -+#define EMAC_ECNTRL_MAGIC_ENA 0x00000004 -+#define EMAC_ECNTRL_SLEEP 0x00000008 -+#define EMAC_ECNTRL_SPEED 0x00000020 -+#define EMAC_ECNTRL_DBSWAP 0x00000100 -+ -+#define EMAC_X_WMRK_STRFWD 0x00000100 -+ -+#define EMAC_X_DES_ACTIVE_TDAR 0x01000000 -+#define EMAC_R_DES_ACTIVE_RDAR 0x01000000 -+ -+#define EMAC_RX_SECTION_EMPTY_V 0x00010006 -+/* -+ * The possible operating speeds of the MAC, currently supporting 10, 100 and -+ * 1000Mb modes. -+ */ -+enum mac_speed {SPEED_10M, SPEED_100M, SPEED_1000M, SPEED_1000M_PCS}; -+ -+/* MII-related definitios */ -+#define EMAC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */ -+#define EMAC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */ -+#define EMAC_MII_DATA_OP_CL45_RD 0x30000000 /* Perform a read operation */ -+#define EMAC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */ -+#define EMAC_MII_DATA_OP_CL45_WR 0x10000000 /* Perform a write operation */ -+#define EMAC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */ -+#define EMAC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */ -+#define EMAC_MII_DATA_TA 0x00020000 /* Turnaround */ -+#define EMAC_MII_DATA_DATAMSK 0x0000ffff /* PHY data field */ -+ -+#define EMAC_MII_DATA_RA_SHIFT 18 /* MII Register address bits */ -+#define EMAC_MII_DATA_RA_MASK 0x1F /* MII Register address mask */ -+#define EMAC_MII_DATA_PA_SHIFT 23 /* MII PHY address bits */ -+#define EMAC_MII_DATA_PA_MASK 0x1F /* MII PHY address mask */ -+ -+#define EMAC_MII_DATA_RA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \ -+ EMAC_MII_DATA_RA_SHIFT) -+#define EMAC_MII_DATA_PA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \ -+ EMAC_MII_DATA_PA_SHIFT) -+#define EMAC_MII_DATA(v) ((v) & 0xffff) -+ -+#define EMAC_MII_SPEED_SHIFT 1 -+#define EMAC_HOLDTIME_SHIFT 8 -+#define EMAC_HOLDTIME_MASK 0x7 -+#define EMAC_HOLDTIME(v) (((v) & EMAC_HOLDTIME_MASK) << \ -+ EMAC_HOLDTIME_SHIFT) -+ -+/* -+ * The Address organisation for the MAC device. All addresses are split into -+ * two 32-bit register fields. The first one (bottom) is the lower 32-bits of -+ * the address and the other field are the high order bits - this may be 16-bits -+ * in the case of MAC addresses, or 32-bits for the hash address. -+ * In terms of memory storage, the first item (bottom) is assumed to be at a -+ * lower address location than 'top'. i.e. top should be at address location of -+ * 'bottom' + 4 bytes. -+ */ -+struct pfe_mac_addr { -+ u32 bottom; /* Lower 32-bits of address. */ -+ u32 top; /* Upper 32-bits of address. */ -+}; -+ -+/* -+ * The following is the organisation of the address filters section of the MAC -+ * registers. The Cadence MAC contains four possible specific address match -+ * addresses, if an incoming frame corresponds to any one of these four -+ * addresses then the frame will be copied to memory. -+ * It is not necessary for all four of the address match registers to be -+ * programmed, this is application dependent. -+ */ -+struct spec_addr { -+ struct pfe_mac_addr one; /* Specific address register 1. */ -+ struct pfe_mac_addr two; /* Specific address register 2. */ -+ struct pfe_mac_addr three; /* Specific address register 3. */ -+ struct pfe_mac_addr four; /* Specific address register 4. */ -+}; -+ -+struct gemac_cfg { -+ u32 mode; -+ u32 speed; -+ u32 duplex; -+}; -+ -+/* EMAC Hash size */ -+#define EMAC_HASH_REG_BITS 64 -+ -+#define EMAC_SPEC_ADDR_MAX 4 -+ -+#endif /* _EMAC_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h -@@ -0,0 +1,86 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _GPI_H_ -+#define _GPI_H_ -+ -+#define GPI_VERSION 0x00 -+#define GPI_CTRL 0x04 -+#define GPI_RX_CONFIG 0x08 -+#define GPI_HDR_SIZE 0x0c -+#define GPI_BUF_SIZE 0x10 -+#define GPI_LMEM_ALLOC_ADDR 0x14 -+#define GPI_LMEM_FREE_ADDR 0x18 -+#define GPI_DDR_ALLOC_ADDR 0x1c -+#define GPI_DDR_FREE_ADDR 0x20 -+#define GPI_CLASS_ADDR 0x24 -+#define GPI_DRX_FIFO 0x28 -+#define GPI_TRX_FIFO 0x2c -+#define GPI_INQ_PKTPTR 0x30 -+#define GPI_DDR_DATA_OFFSET 0x34 -+#define GPI_LMEM_DATA_OFFSET 0x38 -+#define GPI_TMLF_TX 0x4c -+#define GPI_DTX_ASEQ 0x50 -+#define GPI_FIFO_STATUS 0x54 -+#define GPI_FIFO_DEBUG 0x58 -+#define GPI_TX_PAUSE_TIME 0x5c -+#define GPI_LMEM_SEC_BUF_DATA_OFFSET 0x60 -+#define GPI_DDR_SEC_BUF_DATA_OFFSET 0x64 -+#define GPI_TOE_CHKSUM_EN 0x68 -+#define GPI_OVERRUN_DROPCNT 0x6c -+#define GPI_CSR_MTIP_PAUSE_REG 0x74 -+#define GPI_CSR_MTIP_PAUSE_QUANTUM 0x78 -+#define GPI_CSR_RX_CNT 0x7c -+#define GPI_CSR_TX_CNT 0x80 -+#define GPI_CSR_DEBUG1 0x84 -+#define GPI_CSR_DEBUG2 0x88 -+ -+struct gpi_cfg { -+ u32 lmem_rtry_cnt; -+ u32 tmlf_txthres; -+ u32 aseq_len; -+ u32 mtip_pause_reg; -+}; -+ -+/* GPI commons defines */ -+#define GPI_LMEM_BUF_EN 0x1 -+#define GPI_DDR_BUF_EN 0x1 -+ -+/* EGPI 1 defines */ -+#define EGPI1_LMEM_RTRY_CNT 0x40 -+#define EGPI1_TMLF_TXTHRES 0xBC -+#define EGPI1_ASEQ_LEN 0x50 -+ -+/* EGPI 2 defines */ -+#define EGPI2_LMEM_RTRY_CNT 0x40 -+#define EGPI2_TMLF_TXTHRES 0xBC -+#define EGPI2_ASEQ_LEN 0x40 -+ -+/* EGPI 3 defines */ -+#define EGPI3_LMEM_RTRY_CNT 0x40 -+#define EGPI3_TMLF_TXTHRES 0xBC -+#define EGPI3_ASEQ_LEN 0x40 -+ -+/* HGPI defines */ -+#define HGPI_LMEM_RTRY_CNT 0x40 -+#define HGPI_TMLF_TXTHRES 0xBC -+#define HGPI_ASEQ_LEN 0x40 -+ -+#define EGPI_PAUSE_TIME 0x000007D0 -+#define EGPI_PAUSE_ENABLE 0x40000000 -+#endif /* _GPI_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h -@@ -0,0 +1,100 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _HIF_H_ -+#define _HIF_H_ -+ -+/* @file hif.h. -+ * hif - PFE hif block control and status register. -+ * Mapped on CBUS and accessible from all PE's and ARM. -+ */ -+#define HIF_VERSION (HIF_BASE_ADDR + 0x00) -+#define HIF_TX_CTRL (HIF_BASE_ADDR + 0x04) -+#define HIF_TX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x08) -+#define HIF_TX_ALLOC (HIF_BASE_ADDR + 0x0c) -+#define HIF_TX_BDP_ADDR (HIF_BASE_ADDR + 0x10) -+#define HIF_TX_STATUS (HIF_BASE_ADDR + 0x14) -+#define HIF_RX_CTRL (HIF_BASE_ADDR + 0x20) -+#define HIF_RX_BDP_ADDR (HIF_BASE_ADDR + 0x24) -+#define HIF_RX_STATUS (HIF_BASE_ADDR + 0x30) -+#define HIF_INT_SRC (HIF_BASE_ADDR + 0x34) -+#define HIF_INT_ENABLE (HIF_BASE_ADDR + 0x38) -+#define HIF_POLL_CTRL (HIF_BASE_ADDR + 0x3c) -+#define HIF_RX_CURR_BD_ADDR (HIF_BASE_ADDR + 0x40) -+#define HIF_RX_ALLOC (HIF_BASE_ADDR + 0x44) -+#define HIF_TX_DMA_STATUS (HIF_BASE_ADDR + 0x48) -+#define HIF_RX_DMA_STATUS (HIF_BASE_ADDR + 0x4c) -+#define HIF_INT_COAL (HIF_BASE_ADDR + 0x50) -+ -+/* HIF_INT_SRC/ HIF_INT_ENABLE control bits */ -+#define HIF_INT BIT(0) -+#define HIF_RXBD_INT BIT(1) -+#define HIF_RXPKT_INT BIT(2) -+#define HIF_TXBD_INT BIT(3) -+#define HIF_TXPKT_INT BIT(4) -+ -+/* HIF_TX_CTRL bits */ -+#define HIF_CTRL_DMA_EN BIT(0) -+#define HIF_CTRL_BDP_POLL_CTRL_EN BIT(1) -+#define HIF_CTRL_BDP_CH_START_WSTB BIT(2) -+ -+/* HIF_RX_STATUS bits */ -+#define BDP_CSR_RX_DMA_ACTV BIT(16) -+ -+/* HIF_INT_ENABLE bits */ -+#define HIF_INT_EN BIT(0) -+#define HIF_RXBD_INT_EN BIT(1) -+#define HIF_RXPKT_INT_EN BIT(2) -+#define HIF_TXBD_INT_EN BIT(3) -+#define HIF_TXPKT_INT_EN BIT(4) -+ -+/* HIF_POLL_CTRL bits*/ -+#define HIF_RX_POLL_CTRL_CYCLE 0x0400 -+#define HIF_TX_POLL_CTRL_CYCLE 0x0400 -+ -+/* HIF_INT_COAL bits*/ -+#define HIF_INT_COAL_ENABLE BIT(31) -+ -+/* Buffer descriptor control bits */ -+#define BD_CTRL_BUFLEN_MASK 0x3fff -+#define BD_BUF_LEN(x) ((x) & BD_CTRL_BUFLEN_MASK) -+#define BD_CTRL_CBD_INT_EN BIT(16) -+#define BD_CTRL_PKT_INT_EN BIT(17) -+#define BD_CTRL_LIFM BIT(18) -+#define BD_CTRL_LAST_BD BIT(19) -+#define BD_CTRL_DIR BIT(20) -+#define BD_CTRL_LMEM_CPY BIT(21) /* Valid only for HIF_NOCPY */ -+#define BD_CTRL_PKT_XFER BIT(24) -+#define BD_CTRL_DESC_EN BIT(31) -+#define BD_CTRL_PARSE_DISABLE BIT(25) -+#define BD_CTRL_BRFETCH_DISABLE BIT(26) -+#define BD_CTRL_RTFETCH_DISABLE BIT(27) -+ -+/* Buffer descriptor status bits*/ -+#define BD_STATUS_CONN_ID(x) ((x) & 0xffff) -+#define BD_STATUS_DIR_PROC_ID BIT(16) -+#define BD_STATUS_CONN_ID_EN BIT(17) -+#define BD_STATUS_PE2PROC_ID(x) (((x) & 7) << 18) -+#define BD_STATUS_LE_DATA BIT(21) -+#define BD_STATUS_CHKSUM_EN BIT(22) -+ -+/* HIF Buffer descriptor status bits */ -+#define DIR_PROC_ID BIT(16) -+#define PROC_ID(id) ((id) << 18) -+ -+#endif /* _HIF_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h -@@ -0,0 +1,50 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _HIF_NOCPY_H_ -+#define _HIF_NOCPY_H_ -+ -+#define HIF_NOCPY_VERSION (HIF_NOCPY_BASE_ADDR + 0x00) -+#define HIF_NOCPY_TX_CTRL (HIF_NOCPY_BASE_ADDR + 0x04) -+#define HIF_NOCPY_TX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x08) -+#define HIF_NOCPY_TX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x0c) -+#define HIF_NOCPY_TX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x10) -+#define HIF_NOCPY_TX_STATUS (HIF_NOCPY_BASE_ADDR + 0x14) -+#define HIF_NOCPY_RX_CTRL (HIF_NOCPY_BASE_ADDR + 0x20) -+#define HIF_NOCPY_RX_BDP_ADDR (HIF_NOCPY_BASE_ADDR + 0x24) -+#define HIF_NOCPY_RX_STATUS (HIF_NOCPY_BASE_ADDR + 0x30) -+#define HIF_NOCPY_INT_SRC (HIF_NOCPY_BASE_ADDR + 0x34) -+#define HIF_NOCPY_INT_ENABLE (HIF_NOCPY_BASE_ADDR + 0x38) -+#define HIF_NOCPY_POLL_CTRL (HIF_NOCPY_BASE_ADDR + 0x3c) -+#define HIF_NOCPY_RX_CURR_BD_ADDR (HIF_NOCPY_BASE_ADDR + 0x40) -+#define HIF_NOCPY_RX_ALLOC (HIF_NOCPY_BASE_ADDR + 0x44) -+#define HIF_NOCPY_TX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x48) -+#define HIF_NOCPY_RX_DMA_STATUS (HIF_NOCPY_BASE_ADDR + 0x4c) -+#define HIF_NOCPY_RX_INQ0_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x50) -+#define HIF_NOCPY_RX_INQ1_PKTPTR (HIF_NOCPY_BASE_ADDR + 0x54) -+#define HIF_NOCPY_TX_PORT_NO (HIF_NOCPY_BASE_ADDR + 0x60) -+#define HIF_NOCPY_LMEM_ALLOC_ADDR (HIF_NOCPY_BASE_ADDR + 0x64) -+#define HIF_NOCPY_CLASS_ADDR (HIF_NOCPY_BASE_ADDR + 0x68) -+#define HIF_NOCPY_TMU_PORT0_ADDR (HIF_NOCPY_BASE_ADDR + 0x70) -+#define HIF_NOCPY_TMU_PORT1_ADDR (HIF_NOCPY_BASE_ADDR + 0x74) -+#define HIF_NOCPY_TMU_PORT2_ADDR (HIF_NOCPY_BASE_ADDR + 0x7c) -+#define HIF_NOCPY_TMU_PORT3_ADDR (HIF_NOCPY_BASE_ADDR + 0x80) -+#define HIF_NOCPY_TMU_PORT4_ADDR (HIF_NOCPY_BASE_ADDR + 0x84) -+#define HIF_NOCPY_INT_COAL (HIF_NOCPY_BASE_ADDR + 0x90) -+ -+#endif /* _HIF_NOCPY_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h -@@ -0,0 +1,168 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _TMU_CSR_H_ -+#define _TMU_CSR_H_ -+ -+#define TMU_VERSION (TMU_CSR_BASE_ADDR + 0x000) -+#define TMU_INQ_WATERMARK (TMU_CSR_BASE_ADDR + 0x004) -+#define TMU_PHY_INQ_PKTPTR (TMU_CSR_BASE_ADDR + 0x008) -+#define TMU_PHY_INQ_PKTINFO (TMU_CSR_BASE_ADDR + 0x00c) -+#define TMU_PHY_INQ_FIFO_CNT (TMU_CSR_BASE_ADDR + 0x010) -+#define TMU_SYS_GENERIC_CONTROL (TMU_CSR_BASE_ADDR + 0x014) -+#define TMU_SYS_GENERIC_STATUS (TMU_CSR_BASE_ADDR + 0x018) -+#define TMU_SYS_GEN_CON0 (TMU_CSR_BASE_ADDR + 0x01c) -+#define TMU_SYS_GEN_CON1 (TMU_CSR_BASE_ADDR + 0x020) -+#define TMU_SYS_GEN_CON2 (TMU_CSR_BASE_ADDR + 0x024) -+#define TMU_SYS_GEN_CON3 (TMU_CSR_BASE_ADDR + 0x028) -+#define TMU_SYS_GEN_CON4 (TMU_CSR_BASE_ADDR + 0x02c) -+#define TMU_TEQ_DISABLE_DROPCHK (TMU_CSR_BASE_ADDR + 0x030) -+#define TMU_TEQ_CTRL (TMU_CSR_BASE_ADDR + 0x034) -+#define TMU_TEQ_QCFG (TMU_CSR_BASE_ADDR + 0x038) -+#define TMU_TEQ_DROP_STAT (TMU_CSR_BASE_ADDR + 0x03c) -+#define TMU_TEQ_QAVG (TMU_CSR_BASE_ADDR + 0x040) -+#define TMU_TEQ_WREG_PROB (TMU_CSR_BASE_ADDR + 0x044) -+#define TMU_TEQ_TRANS_STAT (TMU_CSR_BASE_ADDR + 0x048) -+#define TMU_TEQ_HW_PROB_CFG0 (TMU_CSR_BASE_ADDR + 0x04c) -+#define TMU_TEQ_HW_PROB_CFG1 (TMU_CSR_BASE_ADDR + 0x050) -+#define TMU_TEQ_HW_PROB_CFG2 (TMU_CSR_BASE_ADDR + 0x054) -+#define TMU_TEQ_HW_PROB_CFG3 (TMU_CSR_BASE_ADDR + 0x058) -+#define TMU_TEQ_HW_PROB_CFG4 (TMU_CSR_BASE_ADDR + 0x05c) -+#define TMU_TEQ_HW_PROB_CFG5 (TMU_CSR_BASE_ADDR + 0x060) -+#define TMU_TEQ_HW_PROB_CFG6 (TMU_CSR_BASE_ADDR + 0x064) -+#define TMU_TEQ_HW_PROB_CFG7 (TMU_CSR_BASE_ADDR + 0x068) -+#define TMU_TEQ_HW_PROB_CFG8 (TMU_CSR_BASE_ADDR + 0x06c) -+#define TMU_TEQ_HW_PROB_CFG9 (TMU_CSR_BASE_ADDR + 0x070) -+#define TMU_TEQ_HW_PROB_CFG10 (TMU_CSR_BASE_ADDR + 0x074) -+#define TMU_TEQ_HW_PROB_CFG11 (TMU_CSR_BASE_ADDR + 0x078) -+#define TMU_TEQ_HW_PROB_CFG12 (TMU_CSR_BASE_ADDR + 0x07c) -+#define TMU_TEQ_HW_PROB_CFG13 (TMU_CSR_BASE_ADDR + 0x080) -+#define TMU_TEQ_HW_PROB_CFG14 (TMU_CSR_BASE_ADDR + 0x084) -+#define TMU_TEQ_HW_PROB_CFG15 (TMU_CSR_BASE_ADDR + 0x088) -+#define TMU_TEQ_HW_PROB_CFG16 (TMU_CSR_BASE_ADDR + 0x08c) -+#define TMU_TEQ_HW_PROB_CFG17 (TMU_CSR_BASE_ADDR + 0x090) -+#define TMU_TEQ_HW_PROB_CFG18 (TMU_CSR_BASE_ADDR + 0x094) -+#define TMU_TEQ_HW_PROB_CFG19 (TMU_CSR_BASE_ADDR + 0x098) -+#define TMU_TEQ_HW_PROB_CFG20 (TMU_CSR_BASE_ADDR + 0x09c) -+#define TMU_TEQ_HW_PROB_CFG21 (TMU_CSR_BASE_ADDR + 0x0a0) -+#define TMU_TEQ_HW_PROB_CFG22 (TMU_CSR_BASE_ADDR + 0x0a4) -+#define TMU_TEQ_HW_PROB_CFG23 (TMU_CSR_BASE_ADDR + 0x0a8) -+#define TMU_TEQ_HW_PROB_CFG24 (TMU_CSR_BASE_ADDR + 0x0ac) -+#define TMU_TEQ_HW_PROB_CFG25 (TMU_CSR_BASE_ADDR + 0x0b0) -+#define TMU_TDQ_IIFG_CFG (TMU_CSR_BASE_ADDR + 0x0b4) -+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. -+ * This is a global Enable for all schedulers in PHY0 -+ */ -+#define TMU_TDQ0_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x0b8) -+ -+#define TMU_LLM_CTRL (TMU_CSR_BASE_ADDR + 0x0bc) -+#define TMU_LLM_BASE_ADDR (TMU_CSR_BASE_ADDR + 0x0c0) -+#define TMU_LLM_QUE_LEN (TMU_CSR_BASE_ADDR + 0x0c4) -+#define TMU_LLM_QUE_HEADPTR (TMU_CSR_BASE_ADDR + 0x0c8) -+#define TMU_LLM_QUE_TAILPTR (TMU_CSR_BASE_ADDR + 0x0cc) -+#define TMU_LLM_QUE_DROPCNT (TMU_CSR_BASE_ADDR + 0x0d0) -+#define TMU_INT_EN (TMU_CSR_BASE_ADDR + 0x0d4) -+#define TMU_INT_SRC (TMU_CSR_BASE_ADDR + 0x0d8) -+#define TMU_INQ_STAT (TMU_CSR_BASE_ADDR + 0x0dc) -+#define TMU_CTRL (TMU_CSR_BASE_ADDR + 0x0e0) -+ -+/* [31] Mem Access Command. 0 = Internal Memory Read, 1 = Internal memory -+ * Write [27:24] Byte Enables of the Internal memory access [23:0] Address of -+ * the internal memory. This address is used to access both the PM and DM of -+ * all the PE's -+ */ -+#define TMU_MEM_ACCESS_ADDR (TMU_CSR_BASE_ADDR + 0x0e4) -+ -+/* Internal Memory Access Write Data */ -+#define TMU_MEM_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x0e8) -+/* Internal Memory Access Read Data. The commands are blocked -+ * at the mem_access only -+ */ -+#define TMU_MEM_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x0ec) -+ -+/* [31:0] PHY0 in queue address (must be initialized with one of the -+ * xxx_INQ_PKTPTR cbus addresses) -+ */ -+#define TMU_PHY0_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f0) -+/* [31:0] PHY1 in queue address (must be initialized with one of the -+ * xxx_INQ_PKTPTR cbus addresses) -+ */ -+#define TMU_PHY1_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f4) -+/* [31:0] PHY2 in queue address (must be initialized with one of the -+ * xxx_INQ_PKTPTR cbus addresses) -+ */ -+#define TMU_PHY2_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0f8) -+/* [31:0] PHY3 in queue address (must be initialized with one of the -+ * xxx_INQ_PKTPTR cbus addresses) -+ */ -+#define TMU_PHY3_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x0fc) -+#define TMU_BMU_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x100) -+#define TMU_TX_CTRL (TMU_CSR_BASE_ADDR + 0x104) -+ -+#define TMU_BUS_ACCESS_WDATA (TMU_CSR_BASE_ADDR + 0x108) -+#define TMU_BUS_ACCESS (TMU_CSR_BASE_ADDR + 0x10c) -+#define TMU_BUS_ACCESS_RDATA (TMU_CSR_BASE_ADDR + 0x110) -+ -+#define TMU_PE_SYS_CLK_RATIO (TMU_CSR_BASE_ADDR + 0x114) -+#define TMU_PE_STATUS (TMU_CSR_BASE_ADDR + 0x118) -+#define TMU_TEQ_MAX_THRESHOLD (TMU_CSR_BASE_ADDR + 0x11c) -+/* [31:0] PHY4 in queue address (must be initialized with one of the -+ * xxx_INQ_PKTPTR cbus addresses) -+ */ -+#define TMU_PHY4_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x134) -+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. -+ * This is a global Enable for all schedulers in PHY1 -+ */ -+#define TMU_TDQ1_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x138) -+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. -+ * This is a global Enable for all schedulers in PHY2 -+ */ -+#define TMU_TDQ2_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x13c) -+/* [9:0] Scheduler Enable for each of the scheduler in the TDQ. -+ * This is a global Enable for all schedulers in PHY3 -+ */ -+#define TMU_TDQ3_SCH_CTRL (TMU_CSR_BASE_ADDR + 0x140) -+#define TMU_BMU_BUF_SIZE (TMU_CSR_BASE_ADDR + 0x144) -+/* [31:0] PHY5 in queue address (must be initialized with one of the -+ * xxx_INQ_PKTPTR cbus addresses) -+ */ -+#define TMU_PHY5_INQ_ADDR (TMU_CSR_BASE_ADDR + 0x148) -+ -+#define SW_RESET BIT(0) /* Global software reset */ -+#define INQ_RESET BIT(2) -+#define TEQ_RESET BIT(3) -+#define TDQ_RESET BIT(4) -+#define PE_RESET BIT(5) -+#define MEM_INIT BIT(6) -+#define MEM_INIT_DONE BIT(7) -+#define LLM_INIT BIT(8) -+#define LLM_INIT_DONE BIT(9) -+#define ECC_MEM_INIT_DONE BIT(10) -+ -+struct tmu_cfg { -+ u32 pe_sys_clk_ratio; -+ unsigned long llm_base_addr; -+ u32 llm_queue_len; -+}; -+ -+/* Not HW related for pfe_ctrl / pfe common defines */ -+#define DEFAULT_MAX_QDEPTH 80 -+#define DEFAULT_Q0_QDEPTH 511 /*We keep one large queue for host tx qos */ -+#define DEFAULT_TMU3_QDEPTH 127 -+ -+#endif /* _TMU_CSR_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h -@@ -0,0 +1,61 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _UTIL_CSR_H_ -+#define _UTIL_CSR_H_ -+ -+#define UTIL_VERSION (UTIL_CSR_BASE_ADDR + 0x000) -+#define UTIL_TX_CTRL (UTIL_CSR_BASE_ADDR + 0x004) -+#define UTIL_INQ_PKTPTR (UTIL_CSR_BASE_ADDR + 0x010) -+ -+#define UTIL_HDR_SIZE (UTIL_CSR_BASE_ADDR + 0x014) -+ -+#define UTIL_PE0_QB_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x020) -+#define UTIL_PE0_QB_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x024) -+#define UTIL_PE0_RO_DM_ADDR0 (UTIL_CSR_BASE_ADDR + 0x060) -+#define UTIL_PE0_RO_DM_ADDR1 (UTIL_CSR_BASE_ADDR + 0x064) -+ -+#define UTIL_MEM_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x100) -+#define UTIL_MEM_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x104) -+#define UTIL_MEM_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x108) -+ -+#define UTIL_TM_INQ_ADDR (UTIL_CSR_BASE_ADDR + 0x114) -+#define UTIL_PE_STATUS (UTIL_CSR_BASE_ADDR + 0x118) -+ -+#define UTIL_PE_SYS_CLK_RATIO (UTIL_CSR_BASE_ADDR + 0x200) -+#define UTIL_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x204) -+#define UTIL_GAP_BETWEEN_READS (UTIL_CSR_BASE_ADDR + 0x208) -+#define UTIL_MAX_BUF_CNT (UTIL_CSR_BASE_ADDR + 0x20c) -+#define UTIL_TSQ_FIFO_THRES (UTIL_CSR_BASE_ADDR + 0x210) -+#define UTIL_TSQ_MAX_CNT (UTIL_CSR_BASE_ADDR + 0x214) -+#define UTIL_IRAM_DATA_0 (UTIL_CSR_BASE_ADDR + 0x218) -+#define UTIL_IRAM_DATA_1 (UTIL_CSR_BASE_ADDR + 0x21c) -+#define UTIL_IRAM_DATA_2 (UTIL_CSR_BASE_ADDR + 0x220) -+#define UTIL_IRAM_DATA_3 (UTIL_CSR_BASE_ADDR + 0x224) -+ -+#define UTIL_BUS_ACCESS_ADDR (UTIL_CSR_BASE_ADDR + 0x228) -+#define UTIL_BUS_ACCESS_WDATA (UTIL_CSR_BASE_ADDR + 0x22c) -+#define UTIL_BUS_ACCESS_RDATA (UTIL_CSR_BASE_ADDR + 0x230) -+ -+#define UTIL_INQ_AFULL_THRES (UTIL_CSR_BASE_ADDR + 0x234) -+ -+struct util_cfg { -+ u32 pe_sys_clk_ratio; -+}; -+ -+#endif /* _UTIL_CSR_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/include/pfe/pfe.h -@@ -0,0 +1,372 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_H_ -+#define _PFE_H_ -+ -+#include "cbus.h" -+ -+#define CLASS_DMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20)) -+/* -+ * Only valid for mem access register interface -+ */ -+#define CLASS_IMEM_BASE_ADDR(i) (0x00000000 | ((i) << 20)) -+#define CLASS_DMEM_SIZE 0x00002000 -+#define CLASS_IMEM_SIZE 0x00008000 -+ -+#define TMU_DMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20)) -+/* -+ * Only valid for mem access register interface -+ */ -+#define TMU_IMEM_BASE_ADDR(i) (0x00000000 + ((i) << 20)) -+#define TMU_DMEM_SIZE 0x00000800 -+#define TMU_IMEM_SIZE 0x00002000 -+ -+#define UTIL_DMEM_BASE_ADDR 0x00000000 -+#define UTIL_DMEM_SIZE 0x00002000 -+ -+#define PE_LMEM_BASE_ADDR 0xc3010000 -+#define PE_LMEM_SIZE 0x8000 -+#define PE_LMEM_END (PE_LMEM_BASE_ADDR + PE_LMEM_SIZE) -+ -+#define DMEM_BASE_ADDR 0x00000000 -+#define DMEM_SIZE 0x2000 /* TMU has less... */ -+#define DMEM_END (DMEM_BASE_ADDR + DMEM_SIZE) -+ -+#define PMEM_BASE_ADDR 0x00010000 -+#define PMEM_SIZE 0x8000 /* TMU has less... */ -+#define PMEM_END (PMEM_BASE_ADDR + PMEM_SIZE) -+ -+/* These check memory ranges from PE point of view/memory map */ -+#define IS_DMEM(addr, len) \ -+ ({ typeof(addr) addr_ = (addr); \ -+ ((unsigned long)(addr_) >= DMEM_BASE_ADDR) && \ -+ (((unsigned long)(addr_) + (len)) <= DMEM_END); }) -+ -+#define IS_PMEM(addr, len) \ -+ ({ typeof(addr) addr_ = (addr); \ -+ ((unsigned long)(addr_) >= PMEM_BASE_ADDR) && \ -+ (((unsigned long)(addr_) + (len)) <= PMEM_END); }) -+ -+#define IS_PE_LMEM(addr, len) \ -+ ({ typeof(addr) addr_ = (addr); \ -+ ((unsigned long)(addr_) >= \ -+ PE_LMEM_BASE_ADDR) && \ -+ (((unsigned long)(addr_) + \ -+ (len)) <= PE_LMEM_END); }) -+ -+#define IS_PFE_LMEM(addr, len) \ -+ ({ typeof(addr) addr_ = (addr); \ -+ ((unsigned long)(addr_) >= \ -+ CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR)) && \ -+ (((unsigned long)(addr_) + (len)) <= \ -+ CBUS_VIRT_TO_PFE(LMEM_END)); }) -+ -+#define __IS_PHYS_DDR(addr, len) \ -+ ({ typeof(addr) addr_ = (addr); \ -+ ((unsigned long)(addr_) >= \ -+ DDR_PHYS_BASE_ADDR) && \ -+ (((unsigned long)(addr_) + (len)) <= \ -+ DDR_PHYS_END); }) -+ -+#define IS_PHYS_DDR(addr, len) __IS_PHYS_DDR(DDR_PFE_TO_PHYS(addr), len) -+ -+/* -+ * If using a run-time virtual address for the cbus base address use this code -+ */ -+extern void *cbus_base_addr; -+extern void *ddr_base_addr; -+extern unsigned long ddr_phys_base_addr; -+extern unsigned int ddr_size; -+ -+#define CBUS_BASE_ADDR cbus_base_addr -+#define DDR_PHYS_BASE_ADDR ddr_phys_base_addr -+#define DDR_BASE_ADDR ddr_base_addr -+#define DDR_SIZE ddr_size -+ -+#define DDR_PHYS_END (DDR_PHYS_BASE_ADDR + DDR_SIZE) -+ -+#define LS1012A_PFE_RESET_WA /* -+ * PFE doesn't have global reset and re-init -+ * should takecare few things to make PFE -+ * functional after reset -+ */ -+#define PFE_CBUS_PHYS_BASE_ADDR 0xc0000000 /* CBUS physical base address -+ * as seen by PE's. -+ */ -+/* CBUS physical base address as seen by PE's. */ -+#define PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE 0xc0000000 -+ -+#define DDR_PHYS_TO_PFE(p) (((unsigned long int)(p)) & 0x7FFFFFFF) -+#define DDR_PFE_TO_PHYS(p) (((unsigned long int)(p)) | 0x80000000) -+#define CBUS_PHYS_TO_PFE(p) (((p) - PFE_CBUS_PHYS_BASE_ADDR) + \ -+ PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE) -+/* Translates to PFE address map */ -+ -+#define DDR_PHYS_TO_VIRT(p) (((p) - DDR_PHYS_BASE_ADDR) + DDR_BASE_ADDR) -+#define DDR_VIRT_TO_PHYS(v) (((v) - DDR_BASE_ADDR) + DDR_PHYS_BASE_ADDR) -+#define DDR_VIRT_TO_PFE(p) (DDR_PHYS_TO_PFE(DDR_VIRT_TO_PHYS(p))) -+ -+#define CBUS_VIRT_TO_PFE(v) (((v) - CBUS_BASE_ADDR) + \ -+ PFE_CBUS_PHYS_BASE_ADDR) -+#define CBUS_PFE_TO_VIRT(p) (((unsigned long int)(p) - \ -+ PFE_CBUS_PHYS_BASE_ADDR) + CBUS_BASE_ADDR) -+ -+/* The below part of the code is used in QOS control driver from host */ -+#define TMU_APB_BASE_ADDR 0xc1000000 /* TMU base address seen by -+ * pe's -+ */ -+ -+enum { -+ CLASS0_ID = 0, -+ CLASS1_ID, -+ CLASS2_ID, -+ CLASS3_ID, -+ CLASS4_ID, -+ CLASS5_ID, -+ TMU0_ID, -+ TMU1_ID, -+ TMU2_ID, -+ TMU3_ID, -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ UTIL_ID, -+#endif -+ MAX_PE -+}; -+ -+#define CLASS_MASK (BIT(CLASS0_ID) | BIT(CLASS1_ID) |\ -+ BIT(CLASS2_ID) | BIT(CLASS3_ID) |\ -+ BIT(CLASS4_ID) | BIT(CLASS5_ID)) -+#define CLASS_MAX_ID CLASS5_ID -+ -+#define TMU_MASK (BIT(TMU0_ID) | BIT(TMU1_ID) |\ -+ BIT(TMU3_ID)) -+ -+#define TMU_MAX_ID TMU3_ID -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+#define UTIL_MASK BIT(UTIL_ID) -+#endif -+ -+struct pe_status { -+ u32 cpu_state; -+ u32 activity_counter; -+ u32 rx; -+ union { -+ u32 tx; -+ u32 tmu_qstatus; -+ }; -+ u32 drop; -+#if defined(CFG_PE_DEBUG) -+ u32 debug_indicator; -+ u32 debug[16]; -+#endif -+} __aligned(16); -+ -+struct pe_sync_mailbox { -+ u32 stop; -+ u32 stopped; -+}; -+ -+/* Drop counter definitions */ -+ -+#define CLASS_NUM_DROP_COUNTERS 13 -+#define UTIL_NUM_DROP_COUNTERS 8 -+ -+/* PE information. -+ * Structure containing PE's specific information. It is used to create -+ * generic C functions common to all PE's. -+ * Before using the library functions this structure needs to be initialized -+ * with the different registers virtual addresses -+ * (according to the ARM MMU mmaping). The default initialization supports a -+ * virtual == physical mapping. -+ */ -+struct pe_info { -+ u32 dmem_base_addr; /* PE's dmem base address */ -+ u32 pmem_base_addr; /* PE's pmem base address */ -+ u32 pmem_size; /* PE's pmem size */ -+ -+ void *mem_access_wdata; /* PE's _MEM_ACCESS_WDATA register -+ * address -+ */ -+ void *mem_access_addr; /* PE's _MEM_ACCESS_ADDR register -+ * address -+ */ -+ void *mem_access_rdata; /* PE's _MEM_ACCESS_RDATA register -+ * address -+ */ -+}; -+ -+void pe_lmem_read(u32 *dst, u32 len, u32 offset); -+void pe_lmem_write(u32 *src, u32 len, u32 offset); -+ -+void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len); -+void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len); -+ -+u32 pe_pmem_read(int id, u32 addr, u8 size); -+ -+void pe_dmem_write(int id, u32 val, u32 addr, u8 size); -+u32 pe_dmem_read(int id, u32 addr, u8 size); -+void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len); -+void class_pe_lmem_memset(u32 dst, int val, unsigned int len); -+void class_bus_write(u32 val, u32 addr, u8 size); -+u32 class_bus_read(u32 addr, u8 size); -+ -+#define class_bus_readl(addr) class_bus_read(addr, 4) -+#define class_bus_readw(addr) class_bus_read(addr, 2) -+#define class_bus_readb(addr) class_bus_read(addr, 1) -+ -+#define class_bus_writel(val, addr) class_bus_write(val, addr, 4) -+#define class_bus_writew(val, addr) class_bus_write(val, addr, 2) -+#define class_bus_writeb(val, addr) class_bus_write(val, addr, 1) -+ -+#define pe_dmem_readl(id, addr) pe_dmem_read(id, addr, 4) -+#define pe_dmem_readw(id, addr) pe_dmem_read(id, addr, 2) -+#define pe_dmem_readb(id, addr) pe_dmem_read(id, addr, 1) -+ -+#define pe_dmem_writel(id, val, addr) pe_dmem_write(id, val, addr, 4) -+#define pe_dmem_writew(id, val, addr) pe_dmem_write(id, val, addr, 2) -+#define pe_dmem_writeb(id, val, addr) pe_dmem_write(id, val, addr, 1) -+ -+/*int pe_load_elf_section(int id, const void *data, elf32_shdr *shdr); */ -+int pe_load_elf_section(int id, const void *data, struct elf32_shdr *shdr, -+ struct device *dev); -+ -+void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base, -+ unsigned int ddr_size); -+void bmu_init(void *base, struct BMU_CFG *cfg); -+void bmu_reset(void *base); -+void bmu_enable(void *base); -+void bmu_disable(void *base); -+void bmu_set_config(void *base, struct BMU_CFG *cfg); -+ -+/* -+ * An enumerated type for loopback values. This can be one of three values, no -+ * loopback -normal operation, local loopback with internal loopback module of -+ * MAC or PHY loopback which is through the external PHY. -+ */ -+#ifndef __MAC_LOOP_ENUM__ -+#define __MAC_LOOP_ENUM__ -+enum mac_loop {LB_NONE, LB_EXT, LB_LOCAL}; -+#endif -+ -+void gemac_init(void *base, void *config); -+void gemac_disable_rx_checksum_offload(void *base); -+void gemac_enable_rx_checksum_offload(void *base); -+void gemac_set_mdc_div(void *base, int mdc_div); -+void gemac_set_speed(void *base, enum mac_speed gem_speed); -+void gemac_set_duplex(void *base, int duplex); -+void gemac_set_mode(void *base, int mode); -+void gemac_enable(void *base); -+void gemac_tx_disable(void *base); -+void gemac_tx_enable(void *base); -+void gemac_disable(void *base); -+void gemac_reset(void *base); -+void gemac_set_address(void *base, struct spec_addr *addr); -+struct spec_addr gemac_get_address(void *base); -+void gemac_set_loop(void *base, enum mac_loop gem_loop); -+void gemac_set_laddr1(void *base, struct pfe_mac_addr *address); -+void gemac_set_laddr2(void *base, struct pfe_mac_addr *address); -+void gemac_set_laddr3(void *base, struct pfe_mac_addr *address); -+void gemac_set_laddr4(void *base, struct pfe_mac_addr *address); -+void gemac_set_laddrN(void *base, struct pfe_mac_addr *address, -+ unsigned int entry_index); -+void gemac_clear_laddr1(void *base); -+void gemac_clear_laddr2(void *base); -+void gemac_clear_laddr3(void *base); -+void gemac_clear_laddr4(void *base); -+void gemac_clear_laddrN(void *base, unsigned int entry_index); -+struct pfe_mac_addr gemac_get_hash(void *base); -+void gemac_set_hash(void *base, struct pfe_mac_addr *hash); -+struct pfe_mac_addr gem_get_laddr1(void *base); -+struct pfe_mac_addr gem_get_laddr2(void *base); -+struct pfe_mac_addr gem_get_laddr3(void *base); -+struct pfe_mac_addr gem_get_laddr4(void *base); -+struct pfe_mac_addr gem_get_laddrN(void *base, unsigned int entry_index); -+void gemac_set_config(void *base, struct gemac_cfg *cfg); -+void gemac_allow_broadcast(void *base); -+void gemac_no_broadcast(void *base); -+void gemac_enable_1536_rx(void *base); -+void gemac_disable_1536_rx(void *base); -+void gemac_enable_rx_jmb(void *base); -+void gemac_disable_rx_jmb(void *base); -+void gemac_enable_stacked_vlan(void *base); -+void gemac_disable_stacked_vlan(void *base); -+void gemac_enable_pause_rx(void *base); -+void gemac_disable_pause_rx(void *base); -+void gemac_enable_copy_all(void *base); -+void gemac_disable_copy_all(void *base); -+void gemac_set_bus_width(void *base, int width); -+void gemac_set_wol(void *base, u32 wol_conf); -+ -+void gpi_init(void *base, struct gpi_cfg *cfg); -+void gpi_reset(void *base); -+void gpi_enable(void *base); -+void gpi_disable(void *base); -+void gpi_set_config(void *base, struct gpi_cfg *cfg); -+ -+void class_init(struct class_cfg *cfg); -+void class_reset(void); -+void class_enable(void); -+void class_disable(void); -+void class_set_config(struct class_cfg *cfg); -+ -+void tmu_reset(void); -+void tmu_init(struct tmu_cfg *cfg); -+void tmu_enable(u32 pe_mask); -+void tmu_disable(u32 pe_mask); -+u32 tmu_qstatus(u32 if_id); -+u32 tmu_pkts_processed(u32 if_id); -+ -+void util_init(struct util_cfg *cfg); -+void util_reset(void); -+void util_enable(void); -+void util_disable(void); -+ -+void hif_init(void); -+void hif_tx_enable(void); -+void hif_tx_disable(void); -+void hif_rx_enable(void); -+void hif_rx_disable(void); -+ -+/* Get Chip Revision level -+ * -+ */ -+static inline unsigned int CHIP_REVISION(void) -+{ -+ /*For LS1012A return always 1 */ -+ return 1; -+} -+ -+/* Start HIF rx DMA -+ * -+ */ -+static inline void hif_rx_dma_start(void) -+{ -+ writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_RX_CTRL); -+} -+ -+/* Start HIF tx DMA -+ * -+ */ -+static inline void hif_tx_dma_start(void) -+{ -+ writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_TX_CTRL); -+} -+ -+#endif /* _PFE_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_ctrl.h -@@ -0,0 +1,112 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_CTRL_H_ -+#define _PFE_CTRL_H_ -+ -+#include -+ -+#include "pfe_mod.h" -+#include "pfe/pfe.h" -+ -+#define DMA_BUF_SIZE_128 0x80 /* enough for 1 conntracks */ -+#define DMA_BUF_SIZE_256 0x100 -+/* enough for 2 conntracks, 1 bridge entry or 1 multicast entry */ -+#define DMA_BUF_SIZE_512 0x200 -+/* 512bytes dma allocated buffers used by rtp relay feature */ -+#define DMA_BUF_MIN_ALIGNMENT 8 -+#define DMA_BUF_BOUNDARY (4 * 1024) -+/* bursts can not cross 4k boundary */ -+ -+#define CMD_TX_ENABLE 0x0501 -+#define CMD_TX_DISABLE 0x0502 -+ -+#define CMD_RX_LRO 0x0011 -+#define CMD_PKTCAP_ENABLE 0x0d01 -+#define CMD_QM_EXPT_RATE 0x020c -+ -+#define CLASS_DM_SH_STATIC (0x800) -+#define CLASS_DM_CPU_TICKS (CLASS_DM_SH_STATIC) -+#define CLASS_DM_SYNC_MBOX (0x808) -+#define CLASS_DM_MSG_MBOX (0x810) -+#define CLASS_DM_DROP_CNTR (0x820) -+#define CLASS_DM_RESUME (0x854) -+#define CLASS_DM_PESTATUS (0x860) -+ -+#define TMU_DM_SH_STATIC (0x80) -+#define TMU_DM_CPU_TICKS (TMU_DM_SH_STATIC) -+#define TMU_DM_SYNC_MBOX (0x88) -+#define TMU_DM_MSG_MBOX (0x90) -+#define TMU_DM_RESUME (0xA0) -+#define TMU_DM_PESTATUS (0xB0) -+#define TMU_DM_CONTEXT (0x300) -+#define TMU_DM_TX_TRANS (0x480) -+ -+#define UTIL_DM_SH_STATIC (0x0) -+#define UTIL_DM_CPU_TICKS (UTIL_DM_SH_STATIC) -+#define UTIL_DM_SYNC_MBOX (0x8) -+#define UTIL_DM_MSG_MBOX (0x10) -+#define UTIL_DM_DROP_CNTR (0x20) -+#define UTIL_DM_RESUME (0x40) -+#define UTIL_DM_PESTATUS (0x50) -+ -+struct pfe_ctrl { -+ struct mutex mutex; /* to serialize pfe control access */ -+ spinlock_t lock; -+ -+ void *dma_pool; -+ void *dma_pool_512; -+ void *dma_pool_128; -+ -+ struct device *dev; -+ -+ void *hash_array_baseaddr; /* -+ * Virtual base address of -+ * the conntrack hash array -+ */ -+ unsigned long hash_array_phys_baseaddr; /* -+ * Physical base address of -+ * the conntrack hash array -+ */ -+ -+ int (*event_cb)(u16, u16, u16*); -+ -+ unsigned long sync_mailbox_baseaddr[MAX_PE]; /* -+ * Sync mailbox PFE -+ * internal address, -+ * initialized -+ * when parsing elf images -+ */ -+ unsigned long msg_mailbox_baseaddr[MAX_PE]; /* -+ * Msg mailbox PFE internal -+ * address, initialized -+ * when parsing elf images -+ */ -+ unsigned int sys_clk; /* AXI clock value, in KHz */ -+}; -+ -+int pfe_ctrl_init(struct pfe *pfe); -+void pfe_ctrl_exit(struct pfe *pfe); -+int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask); -+void pe_start(struct pfe_ctrl *ctrl, int pe_mask); -+int pe_reset_all(struct pfe_ctrl *ctrl); -+void pfe_ctrl_suspend(struct pfe_ctrl *ctrl); -+void pfe_ctrl_resume(struct pfe_ctrl *ctrl); -+int relax(unsigned long end); -+ -+#endif /* _PFE_CTRL_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_debugfs.h -@@ -0,0 +1,25 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_DEBUGFS_H_ -+#define _PFE_DEBUGFS_H_ -+ -+int pfe_debugfs_init(struct pfe *pfe); -+void pfe_debugfs_exit(struct pfe *pfe); -+ -+#endif /* _PFE_DEBUGFS_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_eth.h -@@ -0,0 +1,184 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_ETH_H_ -+#define _PFE_ETH_H_ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define PFE_ETH_NAPI_STATS -+#define PFE_ETH_TX_STATS -+ -+#define PFE_ETH_FRAGS_MAX (65536 / HIF_RX_PKT_MIN_SIZE) -+#define LRO_LEN_COUNT_MAX 32 -+#define LRO_NB_COUNT_MAX 32 -+ -+#define PFE_PAUSE_FLAG_ENABLE 1 -+#define PFE_PAUSE_FLAG_AUTONEG 2 -+ -+/* GEMAC configured by SW */ -+/* GEMAC configured by phy lines (not for MII/GMII) */ -+ -+#define GEMAC_SW_FULL_DUPLEX BIT(9) -+#define GEMAC_SW_SPEED_10M (0 << 12) -+#define GEMAC_SW_SPEED_100M BIT(12) -+#define GEMAC_SW_SPEED_1G (2 << 12) -+ -+#define GEMAC_NO_PHY BIT(0) -+ -+struct ls1012a_eth_platform_data { -+ /* device specific information */ -+ u32 device_flags; -+ char name[16]; -+ -+ /* board specific information */ -+ u32 mii_config; -+ u32 phy_flags; -+ u32 gem_id; -+ u32 bus_id; -+ u32 phy_id; -+ u32 mdio_muxval; -+ u8 mac_addr[ETH_ALEN]; -+}; -+ -+struct ls1012a_mdio_platform_data { -+ int enabled; -+ int irq[32]; -+ u32 phy_mask; -+ int mdc_div; -+}; -+ -+struct ls1012a_pfe_platform_data { -+ struct ls1012a_eth_platform_data ls1012a_eth_pdata[3]; -+ struct ls1012a_mdio_platform_data ls1012a_mdio_pdata[3]; -+}; -+ -+#define NUM_GEMAC_SUPPORT 2 -+#define DRV_NAME "pfe-eth" -+#define DRV_VERSION "1.0" -+ -+#define LS1012A_TX_FAST_RECOVERY_TIMEOUT_MS 3 -+#define TX_POLL_TIMEOUT_MS 1000 -+ -+#define EMAC_TXQ_CNT 16 -+#define EMAC_TXQ_DEPTH (HIF_TX_DESC_NT) -+ -+#define JUMBO_FRAME_SIZE 10258 -+/* -+ * Client Tx queue threshold, for txQ flush condition. -+ * It must be smaller than the queue size (in case we ever change it in the -+ * future). -+ */ -+#define HIF_CL_TX_FLUSH_MARK 32 -+ -+/* -+ * Max number of TX resources (HIF descriptors or skbs) that will be released -+ * in a single go during batch recycling. -+ * Should be lower than the flush mark so the SW can provide the HW with a -+ * continuous stream of packets instead of bursts. -+ */ -+#define TX_FREE_MAX_COUNT 16 -+#define EMAC_RXQ_CNT 3 -+#define EMAC_RXQ_DEPTH HIF_RX_DESC_NT -+/* make sure clients can receive a full burst of packets */ -+#define EMAC_RMON_TXBYTES_POS 0x00 -+#define EMAC_RMON_RXBYTES_POS 0x14 -+ -+#define EMAC_QUEUENUM_MASK (emac_txq_cnt - 1) -+#define EMAC_MDIO_TIMEOUT 1000 -+#define MAX_UC_SPEC_ADDR_REG 31 -+ -+struct pfe_eth_fast_timer { -+ int queuenum; -+ struct hrtimer timer; -+ void *base; -+}; -+ -+struct pfe_eth_priv_s { -+ struct pfe *pfe; -+ struct hif_client_s client; -+ struct napi_struct lro_napi; -+ struct napi_struct low_napi; -+ struct napi_struct high_napi; -+ int low_tmu_q; -+ int high_tmu_q; -+ struct net_device_stats stats; -+ struct net_device *ndev; -+ int id; -+ int promisc; -+ unsigned int msg_enable; -+ unsigned int usr_features; -+ -+ spinlock_t lock; /* protect member variables */ -+ unsigned int event_status; -+ int irq; -+ void *EMAC_baseaddr; -+ /* This points to the EMAC base from where we access PHY */ -+ void *PHY_baseaddr; -+ void *GPI_baseaddr; -+ /* PHY stuff */ -+ struct phy_device *phydev; -+ int oldspeed; -+ int oldduplex; -+ int oldlink; -+ /* mdio info */ -+ int mdc_div; -+ struct mii_bus *mii_bus; -+ struct clk *gemtx_clk; -+ int wol; -+ int pause_flag; -+ -+ int default_priority; -+ struct pfe_eth_fast_timer fast_tx_timeout[EMAC_TXQ_CNT]; -+ -+ struct ls1012a_eth_platform_data *einfo; -+ struct sk_buff *skb_inflight[EMAC_RXQ_CNT + 6]; -+ -+#ifdef PFE_ETH_TX_STATS -+ unsigned int stop_queue_total[EMAC_TXQ_CNT]; -+ unsigned int stop_queue_hif[EMAC_TXQ_CNT]; -+ unsigned int stop_queue_hif_client[EMAC_TXQ_CNT]; -+ unsigned int stop_queue_credit[EMAC_TXQ_CNT]; -+ unsigned int clean_fail[EMAC_TXQ_CNT]; -+ unsigned int was_stopped[EMAC_TXQ_CNT]; -+#endif -+ -+#ifdef PFE_ETH_NAPI_STATS -+ unsigned int napi_counters[NAPI_MAX_COUNT]; -+#endif -+ unsigned int frags_inflight[EMAC_RXQ_CNT + 6]; -+}; -+ -+struct pfe_eth { -+ struct pfe_eth_priv_s *eth_priv[3]; -+}; -+ -+int pfe_eth_init(struct pfe *pfe); -+void pfe_eth_exit(struct pfe *pfe); -+int pfe_eth_suspend(struct net_device *dev); -+int pfe_eth_resume(struct net_device *dev); -+int pfe_eth_mdio_reset(struct mii_bus *bus); -+ -+#endif /* _PFE_ETH_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_firmware.h -@@ -0,0 +1,32 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_FIRMWARE_H_ -+#define _PFE_FIRMWARE_H_ -+ -+#define CLASS_FIRMWARE_FILENAME "ppfe_class_ls1012a.elf" -+#define TMU_FIRMWARE_FILENAME "ppfe_tmu_ls1012a.elf" -+ -+#define PFE_FW_CHECK_PASS 0 -+#define PFE_FW_CHECK_FAIL 1 -+#define NUM_PFE_FW 3 -+ -+int pfe_firmware_init(struct pfe *pfe); -+void pfe_firmware_exit(struct pfe *pfe); -+ -+#endif /* _PFE_FIRMWARE_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_hif.h -@@ -0,0 +1,211 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_HIF_H_ -+#define _PFE_HIF_H_ -+ -+#include -+ -+#define HIF_NAPI_STATS -+ -+#define HIF_CLIENT_QUEUES_MAX 16 -+#define HIF_RX_POLL_WEIGHT 64 -+ -+#define HIF_RX_PKT_MIN_SIZE 0x800 /* 2KB */ -+#define HIF_RX_PKT_MIN_SIZE_MASK ~(HIF_RX_PKT_MIN_SIZE - 1) -+#define ROUND_MIN_RX_SIZE(_sz) (((_sz) + (HIF_RX_PKT_MIN_SIZE - 1)) \ -+ & HIF_RX_PKT_MIN_SIZE_MASK) -+#define PRESENT_OFST_IN_PAGE(_buf) (((unsigned long int)(_buf) & (PAGE_SIZE \ -+ - 1)) & HIF_RX_PKT_MIN_SIZE_MASK) -+ -+enum { -+ NAPI_SCHED_COUNT = 0, -+ NAPI_POLL_COUNT, -+ NAPI_PACKET_COUNT, -+ NAPI_DESC_COUNT, -+ NAPI_FULL_BUDGET_COUNT, -+ NAPI_CLIENT_FULL_COUNT, -+ NAPI_MAX_COUNT -+}; -+ -+/* -+ * HIF_TX_DESC_NT value should be always greter than 4, -+ * Otherwise HIF_TX_POLL_MARK will become zero. -+ */ -+#define HIF_RX_DESC_NT 256 -+#define HIF_TX_DESC_NT 2048 -+ -+#define HIF_FIRST_BUFFER BIT(0) -+#define HIF_LAST_BUFFER BIT(1) -+#define HIF_DONT_DMA_MAP BIT(2) -+#define HIF_DATA_VALID BIT(3) -+#define HIF_TSO BIT(4) -+ -+enum { -+ PFE_CL_GEM0 = 0, -+ PFE_CL_GEM1, -+ HIF_CLIENTS_MAX -+}; -+ -+/*structure to store client queue info */ -+struct hif_rx_queue { -+ struct rx_queue_desc *base; -+ u32 size; -+ u32 write_idx; -+}; -+ -+struct hif_tx_queue { -+ struct tx_queue_desc *base; -+ u32 size; -+ u32 ack_idx; -+}; -+ -+/*Structure to store the client info */ -+struct hif_client { -+ int rx_qn; -+ struct hif_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX]; -+ int tx_qn; -+ struct hif_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX]; -+}; -+ -+/*HIF hardware buffer descriptor */ -+struct hif_desc { -+ u32 ctrl; -+ u32 status; -+ u32 data; -+ u32 next; -+}; -+ -+struct __hif_desc { -+ u32 ctrl; -+ u32 status; -+ u32 data; -+}; -+ -+struct hif_desc_sw { -+ dma_addr_t data; -+ u16 len; -+ u8 client_id; -+ u8 q_no; -+ u16 flags; -+}; -+ -+struct hif_hdr { -+ u8 client_id; -+ u8 q_num; -+ u16 client_ctrl; -+ u16 client_ctrl1; -+}; -+ -+struct __hif_hdr { -+ union { -+ struct hif_hdr hdr; -+ u32 word[2]; -+ }; -+}; -+ -+struct hif_ipsec_hdr { -+ u16 sa_handle[2]; -+} __packed; -+ -+/* HIF_CTRL_TX... defines */ -+#define HIF_CTRL_TX_CHECKSUM BIT(2) -+ -+/* HIF_CTRL_RX... defines */ -+#define HIF_CTRL_RX_OFFSET_OFST (24) -+#define HIF_CTRL_RX_CHECKSUMMED BIT(2) -+#define HIF_CTRL_RX_CONTINUED BIT(1) -+ -+struct pfe_hif { -+ /* To store registered clients in hif layer */ -+ struct hif_client client[HIF_CLIENTS_MAX]; -+ struct hif_shm *shm; -+ int irq; -+ -+ void *descr_baseaddr_v; -+ unsigned long descr_baseaddr_p; -+ -+ struct hif_desc *rx_base; -+ u32 rx_ring_size; -+ u32 rxtoclean_index; -+ void *rx_buf_addr[HIF_RX_DESC_NT]; -+ int rx_buf_len[HIF_RX_DESC_NT]; -+ unsigned int qno; -+ unsigned int client_id; -+ unsigned int client_ctrl; -+ unsigned int started; -+ -+ struct hif_desc *tx_base; -+ u32 tx_ring_size; -+ u32 txtosend; -+ u32 txtoclean; -+ u32 txavail; -+ u32 txtoflush; -+ struct hif_desc_sw tx_sw_queue[HIF_TX_DESC_NT]; -+ -+/* tx_lock synchronizes hif packet tx as well as pfe_hif structure access */ -+ spinlock_t tx_lock; -+/* lock synchronizes hif rx queue processing */ -+ spinlock_t lock; -+ struct net_device dummy_dev; -+ struct napi_struct napi; -+ struct device *dev; -+ -+#ifdef HIF_NAPI_STATS -+ unsigned int napi_counters[NAPI_MAX_COUNT]; -+#endif -+ struct tasklet_struct tx_cleanup_tasklet; -+}; -+ -+void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int -+ q_no, void *data, u32 len, unsigned int flags); -+int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no, -+ void *data, unsigned int len); -+void __hif_tx_done_process(struct pfe_hif *hif, int count); -+void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int -+ data2); -+int pfe_hif_init(struct pfe *pfe); -+void pfe_hif_exit(struct pfe *pfe); -+void pfe_hif_rx_idle(struct pfe_hif *hif); -+static inline void hif_tx_done_process(struct pfe_hif *hif, int count) -+{ -+ spin_lock_bh(&hif->tx_lock); -+ __hif_tx_done_process(hif, count); -+ spin_unlock_bh(&hif->tx_lock); -+} -+ -+static inline void hif_tx_lock(struct pfe_hif *hif) -+{ -+ spin_lock_bh(&hif->tx_lock); -+} -+ -+static inline void hif_tx_unlock(struct pfe_hif *hif) -+{ -+ spin_unlock_bh(&hif->tx_lock); -+} -+ -+static inline int __hif_tx_avail(struct pfe_hif *hif) -+{ -+ return hif->txavail; -+} -+ -+#define __memcpy8(dst, src) memcpy(dst, src, 8) -+#define __memcpy12(dst, src) memcpy(dst, src, 12) -+#define __memcpy(dst, src, len) memcpy(dst, src, len) -+ -+#endif /* _PFE_HIF_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.h -@@ -0,0 +1,239 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_HIF_LIB_H_ -+#define _PFE_HIF_LIB_H_ -+ -+#include "pfe_hif.h" -+ -+#define HIF_CL_REQ_TIMEOUT 10 -+#define GFP_DMA_PFE 0 -+ -+enum { -+ REQUEST_CL_REGISTER = 0, -+ REQUEST_CL_UNREGISTER, -+ HIF_REQUEST_MAX -+}; -+ -+enum { -+ /* Event to indicate that client rx queue is reached water mark level */ -+ EVENT_HIGH_RX_WM = 0, -+ /* Event to indicate that, packet received for client */ -+ EVENT_RX_PKT_IND, -+ /* Event to indicate that, packet tx done for client */ -+ EVENT_TXDONE_IND, -+ HIF_EVENT_MAX -+}; -+ -+/*structure to store client queue info */ -+ -+/*structure to store client queue info */ -+struct hif_client_rx_queue { -+ struct rx_queue_desc *base; -+ u32 size; -+ u32 read_idx; -+ u32 write_idx; -+}; -+ -+struct hif_client_tx_queue { -+ struct tx_queue_desc *base; -+ u32 size; -+ u32 read_idx; -+ u32 write_idx; -+ u32 tx_pending; -+ unsigned long jiffies_last_packet; -+ u32 nocpy_flag; -+ u32 prev_tmu_tx_pkts; -+ u32 done_tmu_tx_pkts; -+}; -+ -+struct hif_client_s { -+ int id; -+ int tx_qn; -+ int rx_qn; -+ void *rx_qbase; -+ void *tx_qbase; -+ int tx_qsize; -+ int rx_qsize; -+ int cpu_id; -+ struct hif_client_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX]; -+ struct hif_client_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX]; -+ int (*event_handler)(void *priv, int event, int data); -+ unsigned long queue_mask[HIF_EVENT_MAX]; -+ struct pfe *pfe; -+ void *priv; -+}; -+ -+/* -+ * Client specific shared memory -+ * It contains number of Rx/Tx queues, base addresses and queue sizes -+ */ -+struct hif_client_shm { -+ u32 ctrl; /*0-7: number of Rx queues, 8-15: number of tx queues */ -+ unsigned long rx_qbase; /*Rx queue base address */ -+ u32 rx_qsize; /*each Rx queue size, all Rx queues are of same size */ -+ unsigned long tx_qbase; /* Tx queue base address */ -+ u32 tx_qsize; /*each Tx queue size, all Tx queues are of same size */ -+}; -+ -+/*Client shared memory ctrl bit description */ -+#define CLIENT_CTRL_RX_Q_CNT_OFST 0 -+#define CLIENT_CTRL_TX_Q_CNT_OFST 8 -+#define CLIENT_CTRL_RX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_RX_Q_CNT_OFST) \ -+ & 0xFF) -+#define CLIENT_CTRL_TX_Q_CNT(ctrl) (((ctrl) >> CLIENT_CTRL_TX_Q_CNT_OFST) \ -+ & 0xFF) -+ -+/* -+ * Shared memory used to communicate between HIF driver and host/client drivers -+ * Before starting the hif driver rx_buf_pool ans rx_buf_pool_cnt should be -+ * initialized with host buffers and buffers count in the pool. -+ * rx_buf_pool_cnt should be >= HIF_RX_DESC_NT. -+ * -+ */ -+struct hif_shm { -+ u32 rx_buf_pool_cnt; /*Number of rx buffers available*/ -+ /*Rx buffers required to initialize HIF rx descriptors */ -+ void *rx_buf_pool[HIF_RX_DESC_NT]; -+ unsigned long g_client_status[2]; /*Global client status bit mask */ -+ /* Client specific shared memory */ -+ struct hif_client_shm client[HIF_CLIENTS_MAX]; -+}; -+ -+#define CL_DESC_OWN BIT(31) -+/* This sets owner ship to HIF driver */ -+#define CL_DESC_LAST BIT(30) -+/* This indicates last packet for multi buffers handling */ -+#define CL_DESC_FIRST BIT(29) -+/* This indicates first packet for multi buffers handling */ -+ -+#define CL_DESC_BUF_LEN(x) ((x) & 0xFFFF) -+#define CL_DESC_FLAGS(x) (((x) & 0xF) << 16) -+#define CL_DESC_GET_FLAGS(x) (((x) >> 16) & 0xF) -+ -+struct rx_queue_desc { -+ void *data; -+ u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/ -+ u32 client_ctrl; -+}; -+ -+struct tx_queue_desc { -+ void *data; -+ u32 ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/ -+}; -+ -+/* HIF Rx is not working properly for 2-byte aligned buffers and -+ * ip_header should be 4byte aligned for better iperformance. -+ * "ip_header = 64 + 6(hif_header) + 14 (MAC Header)" will be 4byte aligned. -+ */ -+#define PFE_PKT_HEADER_SZ sizeof(struct hif_hdr) -+/* must be big enough for headroom, pkt size and skb shared info */ -+#define PFE_BUF_SIZE 2048 -+#define PFE_PKT_HEADROOM 128 -+ -+#define SKB_SHARED_INFO_SIZE (sizeof(struct skb_shared_info)) -+#define PFE_PKT_SIZE (PFE_BUF_SIZE - PFE_PKT_HEADROOM \ -+ - SKB_SHARED_INFO_SIZE) -+#define MAX_L2_HDR_SIZE 14 /* Not correct for VLAN/PPPoE */ -+#define MAX_L3_HDR_SIZE 20 /* Not correct for IPv6 */ -+#define MAX_L4_HDR_SIZE 60 /* TCP with maximum options */ -+#define MAX_HDR_SIZE (MAX_L2_HDR_SIZE + MAX_L3_HDR_SIZE \ -+ + MAX_L4_HDR_SIZE) -+/* Used in page mode to clamp packet size to the maximum supported by the hif -+ *hw interface (<16KiB) -+ */ -+#define MAX_PFE_PKT_SIZE 16380UL -+ -+extern unsigned int pfe_pkt_size; -+extern unsigned int pfe_pkt_headroom; -+extern unsigned int page_mode; -+extern unsigned int lro_mode; -+extern unsigned int tx_qos; -+extern unsigned int emac_txq_cnt; -+ -+int pfe_hif_lib_init(struct pfe *pfe); -+void pfe_hif_lib_exit(struct pfe *pfe); -+int hif_lib_client_register(struct hif_client_s *client); -+int hif_lib_client_unregister(struct hif_client_s *client); -+void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void -+ *data, unsigned int len, u32 client_ctrl, -+ unsigned int flags, void *client_data); -+int hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data, -+ unsigned int len, u32 client_ctrl, void *client_data); -+void hif_lib_indicate_client(int cl_id, int event, int data); -+int hif_lib_event_handler_start(struct hif_client_s *client, int event, int -+ data); -+int hif_lib_tmu_queue_start(struct hif_client_s *client, int qno); -+int hif_lib_tmu_queue_stop(struct hif_client_s *client, int qno); -+void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, -+ unsigned int *flags, int count); -+void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int -+ *ofst, unsigned int *rx_ctrl, -+ unsigned int *desc_ctrl, void **priv_data); -+void hif_lib_set_rx_cpu_affinity(struct hif_client_s *client, int cpu_id); -+void hif_lib_set_tx_queue_nocpy(struct hif_client_s *client, int qno, int -+ enable); -+static inline int hif_lib_tx_avail(struct hif_client_s *client, unsigned int -+ qno) -+{ -+ struct hif_client_tx_queue *queue = &client->tx_q[qno]; -+ -+ return (queue->size - queue->tx_pending); -+} -+ -+static inline int hif_lib_get_tx_wr_index(struct hif_client_s *client, unsigned -+ int qno) -+{ -+ struct hif_client_tx_queue *queue = &client->tx_q[qno]; -+ -+ return queue->write_idx; -+} -+ -+static inline int hif_lib_tx_pending(struct hif_client_s *client, unsigned int -+ qno) -+{ -+ struct hif_client_tx_queue *queue = &client->tx_q[qno]; -+ -+ return queue->tx_pending; -+} -+ -+#define hif_lib_tx_credit_avail(pfe, id, qno) \ -+ ((pfe)->tmu_credit.tx_credit[id][qno]) -+ -+#define hif_lib_tx_credit_max(pfe, id, qno) \ -+ ((pfe)->tmu_credit.tx_credit_max[id][qno]) -+ -+/* -+ * Test comment -+ */ -+#define hif_lib_tx_credit_use(pfe, id, qno, credit) \ -+ ({ typeof(pfe) pfe_ = pfe; \ -+ typeof(id) id_ = id; \ -+ typeof(qno) qno_ = qno_; \ -+ typeof(credit) credit_ = credit; \ -+ do { \ -+ if (tx_qos) { \ -+ (pfe_)->tmu_credit.tx_credit[id_][qno_]\ -+ -= credit_; \ -+ (pfe_)->tmu_credit.tx_packets[id_][qno_]\ -+ += credit_; \ -+ } \ -+ } while (0); \ -+ }) -+ -+#endif /* _PFE_HIF_LIB_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_hw.h -@@ -0,0 +1,27 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_HW_H_ -+#define _PFE_HW_H_ -+ -+#define PE_SYS_CLK_RATIO 1 /* SYS/AXI = 250MHz, HFE = 500MHz */ -+ -+int pfe_hw_init(struct pfe *pfe, int resume); -+void pfe_hw_exit(struct pfe *pfe); -+ -+#endif /* _PFE_HW_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_mod.h -@@ -0,0 +1,112 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_MOD_H_ -+#define _PFE_MOD_H_ -+ -+#include -+#include -+ -+struct pfe; -+ -+#include "pfe_hw.h" -+#include "pfe_firmware.h" -+#include "pfe_ctrl.h" -+#include "pfe_hif.h" -+#include "pfe_hif_lib.h" -+#include "pfe_eth.h" -+#include "pfe_sysfs.h" -+#include "pfe_perfmon.h" -+#include "pfe_debugfs.h" -+ -+#define PHYID_MAX_VAL 32 -+ -+struct pfe_tmu_credit { -+ /* Number of allowed TX packet in-flight, matches TMU queue size */ -+ unsigned int tx_credit[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT]; -+ unsigned int tx_credit_max[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT]; -+ unsigned int tx_packets[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT]; -+}; -+ -+struct pfe { -+ struct regmap *scfg; -+ unsigned long ddr_phys_baseaddr; -+ void *ddr_baseaddr; -+ unsigned int ddr_size; -+ void *cbus_baseaddr; -+ void *apb_baseaddr; -+ unsigned long iram_phys_baseaddr; -+ void *iram_baseaddr; -+ unsigned long ipsec_phys_baseaddr; -+ void *ipsec_baseaddr; -+ int hif_irq; -+ int wol_irq; -+ int hif_client_irq; -+ struct device *dev; -+ struct dentry *dentry; -+ struct pfe_ctrl ctrl; -+ struct pfe_hif hif; -+ struct pfe_eth eth; -+ struct hif_client_s *hif_client[HIF_CLIENTS_MAX]; -+#if defined(CFG_DIAGS) -+ struct pfe_diags diags; -+#endif -+ struct pfe_tmu_credit tmu_credit; -+ struct pfe_cpumon cpumon; -+ struct pfe_memmon memmon; -+ int wake; -+ int mdio_muxval[PHYID_MAX_VAL]; -+ struct clk *hfe_clock; -+}; -+ -+extern struct pfe *pfe; -+ -+int pfe_probe(struct pfe *pfe); -+int pfe_remove(struct pfe *pfe); -+ -+/* DDR Mapping in reserved memory*/ -+#define ROUTE_TABLE_BASEADDR 0 -+#define ROUTE_TABLE_HASH_BITS 15 /* 32K entries */ -+#define ROUTE_TABLE_SIZE ((1 << ROUTE_TABLE_HASH_BITS) \ -+ * CLASS_ROUTE_SIZE) -+#define BMU2_DDR_BASEADDR (ROUTE_TABLE_BASEADDR + ROUTE_TABLE_SIZE) -+#define BMU2_BUF_COUNT (4096 - 256) -+/* This is to get a total DDR size of 12MiB */ -+#define BMU2_DDR_SIZE (DDR_BUF_SIZE * BMU2_BUF_COUNT) -+#define UTIL_CODE_BASEADDR (BMU2_DDR_BASEADDR + BMU2_DDR_SIZE) -+#define UTIL_CODE_SIZE (128 * SZ_1K) -+#define UTIL_DDR_DATA_BASEADDR (UTIL_CODE_BASEADDR + UTIL_CODE_SIZE) -+#define UTIL_DDR_DATA_SIZE (64 * SZ_1K) -+#define CLASS_DDR_DATA_BASEADDR (UTIL_DDR_DATA_BASEADDR + UTIL_DDR_DATA_SIZE) -+#define CLASS_DDR_DATA_SIZE (32 * SZ_1K) -+#define TMU_DDR_DATA_BASEADDR (CLASS_DDR_DATA_BASEADDR + CLASS_DDR_DATA_SIZE) -+#define TMU_DDR_DATA_SIZE (32 * SZ_1K) -+#define TMU_LLM_BASEADDR (TMU_DDR_DATA_BASEADDR + TMU_DDR_DATA_SIZE) -+#define TMU_LLM_QUEUE_LEN (8 * 512) -+/* Must be power of two and at least 16 * 8 = 128 bytes */ -+#define TMU_LLM_SIZE (4 * 16 * TMU_LLM_QUEUE_LEN) -+/* (4 TMU's x 16 queues x queue_len) */ -+ -+#define DDR_MAX_SIZE (TMU_LLM_BASEADDR + TMU_LLM_SIZE) -+ -+/* LMEM Mapping */ -+#define BMU1_LMEM_BASEADDR 0 -+#define BMU1_BUF_COUNT 256 -+#define BMU1_LMEM_SIZE (LMEM_BUF_SIZE * BMU1_BUF_COUNT) -+ -+#endif /* _PFE_MOD_H */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_perfmon.h -@@ -0,0 +1,38 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_PERFMON_H_ -+#define _PFE_PERFMON_H_ -+ -+#include "pfe/pfe.h" -+ -+#define CT_CPUMON_INTERVAL (1 * TIMER_TICKS_PER_SEC) -+ -+struct pfe_cpumon { -+ u32 cpu_usage_pct[MAX_PE]; -+ u32 class_usage_pct; -+}; -+ -+struct pfe_memmon { -+ u32 kernel_memory_allocated; -+}; -+ -+int pfe_perfmon_init(struct pfe *pfe); -+void pfe_perfmon_exit(struct pfe *pfe); -+ -+#endif /* _PFE_PERFMON_H_ */ ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.h -@@ -0,0 +1,29 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_SYSFS_H_ -+#define _PFE_SYSFS_H_ -+ -+#include -+ -+u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset); -+ -+int pfe_sysfs_init(struct pfe *pfe); -+void pfe_sysfs_exit(struct pfe *pfe); -+ -+#endif /* _PFE_SYSFS_H_ */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0286-staging-fsl_ppfe-eth-introduce-pfe-driver.patch b/target/linux/layerscape/patches-5.4/701-net-0286-staging-fsl_ppfe-eth-introduce-pfe-driver.patch deleted file mode 100644 index 13fd4f90d1..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0286-staging-fsl_ppfe-eth-introduce-pfe-driver.patch +++ /dev/null @@ -1,7994 +0,0 @@ -From fccb0e1e07fc0750fd081ab52ed94ee13f6b360f Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Sat, 16 Sep 2017 14:22:17 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: introduce pfe driver - - This patch introduces Linux support for NXP's LS1012A Packet -Forwarding Engine (pfe_eth). LS1012A uses hardware packet forwarding -engine to provide high performance Ethernet interfaces. The device -includes two Ethernet ports. - -Signed-off-by: Calvin Johnson -Signed-off-by: Anjaneyulu Jagarlmudi ---- - drivers/staging/fsl_ppfe/Kconfig | 20 + - drivers/staging/fsl_ppfe/Makefile | 19 + - drivers/staging/fsl_ppfe/TODO | 2 + - drivers/staging/fsl_ppfe/pfe_ctrl.c | 238 +++ - drivers/staging/fsl_ppfe/pfe_debugfs.c | 111 ++ - drivers/staging/fsl_ppfe/pfe_eth.c | 2434 +++++++++++++++++++++++ - drivers/staging/fsl_ppfe/pfe_firmware.c | 314 +++ - drivers/staging/fsl_ppfe/pfe_hal.c | 1516 ++++++++++++++ - drivers/staging/fsl_ppfe/pfe_hif.c | 1094 ++++++++++ - drivers/staging/fsl_ppfe/pfe_hif_lib.c | 638 ++++++ - drivers/staging/fsl_ppfe/pfe_hw.c | 176 ++ - drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 394 ++++ - drivers/staging/fsl_ppfe/pfe_mod.c | 141 ++ - drivers/staging/fsl_ppfe/pfe_sysfs.c | 818 ++++++++ - 14 files changed, 7915 insertions(+) - create mode 100644 drivers/staging/fsl_ppfe/Kconfig - create mode 100644 drivers/staging/fsl_ppfe/Makefile - create mode 100644 drivers/staging/fsl_ppfe/TODO - create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.c - create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.c - create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.c - create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.c - create mode 100644 drivers/staging/fsl_ppfe/pfe_hal.c - create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.c - create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.c - create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.c - create mode 100644 drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c - create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.c - create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.c - ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/Kconfig -@@ -0,0 +1,20 @@ -+# -+# Freescale Programmable Packet Forwarding Engine driver -+# -+config FSL_PPFE -+ bool "Freescale PPFE Driver" -+ default n -+ ---help--- -+ Freescale LS1012A SoC has a Programmable Packet Forwarding Engine. -+ It provides two high performance ethernet interfaces. -+ This driver initializes, programs and controls the PPFE. -+ Use this driver to enable network connectivity on LS1012A platforms. -+ -+if FSL_PPFE -+ -+config FSL_PPFE_UTIL_DISABLED -+ bool "Disable PPFE UTIL Processor Engine" -+ ---help--- -+ UTIL PE has to be enabled only if required. -+ -+endif # FSL_PPFE ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/Makefile -@@ -0,0 +1,19 @@ -+# -+# Makefile for Freesecale PPFE driver -+# -+ -+ccflags-y += -I$(src)/include -I$(src) -+ -+obj-m += pfe.o -+ -+pfe-y += pfe_mod.o \ -+ pfe_hw.o \ -+ pfe_firmware.o \ -+ pfe_ctrl.o \ -+ pfe_hif.o \ -+ pfe_hif_lib.o\ -+ pfe_eth.o \ -+ pfe_sysfs.o \ -+ pfe_debugfs.o \ -+ pfe_ls1012a_platform.o \ -+ pfe_hal.o ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/TODO -@@ -0,0 +1,2 @@ -+TODO: -+ - provide pfe pe monitoring support ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_ctrl.c -@@ -0,0 +1,238 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "pfe_mod.h" -+#include "pfe_ctrl.h" -+ -+#define TIMEOUT_MS 1000 -+ -+int relax(unsigned long end) -+{ -+ if (time_after(jiffies, end)) { -+ if (time_after(jiffies, end + (TIMEOUT_MS * HZ) / 1000)) -+ return -1; -+ -+ if (need_resched()) -+ schedule(); -+ } -+ -+ return 0; -+} -+ -+void pfe_ctrl_suspend(struct pfe_ctrl *ctrl) -+{ -+ int id; -+ -+ mutex_lock(&ctrl->mutex); -+ -+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) -+ pe_dmem_write(id, cpu_to_be32(0x1), CLASS_DM_RESUME, 4); -+ -+ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) { -+ if (id == TMU2_ID) -+ continue; -+ pe_dmem_write(id, cpu_to_be32(0x1), TMU_DM_RESUME, 4); -+ } -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ pe_dmem_write(UTIL_ID, cpu_to_be32(0x1), UTIL_DM_RESUME, 4); -+#endif -+ mutex_unlock(&ctrl->mutex); -+} -+ -+void pfe_ctrl_resume(struct pfe_ctrl *ctrl) -+{ -+ int pe_mask = CLASS_MASK | TMU_MASK; -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ pe_mask |= UTIL_MASK; -+#endif -+ mutex_lock(&ctrl->mutex); -+ pe_start(&pfe->ctrl, pe_mask); -+ mutex_unlock(&ctrl->mutex); -+} -+ -+/* PE sync stop. -+ * Stops packet processing for a list of PE's (specified using a bitmask). -+ * The caller must hold ctrl->mutex. -+ * -+ * @param ctrl Control context -+ * @param pe_mask Mask of PE id's to stop -+ * -+ */ -+int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask) -+{ -+ struct pe_sync_mailbox *mbox; -+ int pe_stopped = 0; -+ unsigned long end = jiffies + 2; -+ int i; -+ -+ pe_mask &= 0x2FF; /*Exclude Util + TMU2 */ -+ -+ for (i = 0; i < MAX_PE; i++) -+ if (pe_mask & (1 << i)) { -+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; -+ -+ pe_dmem_write(i, cpu_to_be32(0x1), (unsigned -+ long)&mbox->stop, 4); -+ } -+ -+ while (pe_stopped != pe_mask) { -+ for (i = 0; i < MAX_PE; i++) -+ if ((pe_mask & (1 << i)) && !(pe_stopped & (1 << i))) { -+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; -+ -+ if (pe_dmem_read(i, (unsigned -+ long)&mbox->stopped, 4) & -+ cpu_to_be32(0x1)) -+ pe_stopped |= (1 << i); -+ } -+ -+ if (relax(end) < 0) -+ goto err; -+ } -+ -+ return 0; -+ -+err: -+ pr_err("%s: timeout, %x %x\n", __func__, pe_mask, pe_stopped); -+ -+ for (i = 0; i < MAX_PE; i++) -+ if (pe_mask & (1 << i)) { -+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; -+ -+ pe_dmem_write(i, cpu_to_be32(0x0), (unsigned -+ long)&mbox->stop, 4); -+ } -+ -+ return -EIO; -+} -+ -+/* PE start. -+ * Starts packet processing for a list of PE's (specified using a bitmask). -+ * The caller must hold ctrl->mutex. -+ * -+ * @param ctrl Control context -+ * @param pe_mask Mask of PE id's to start -+ * -+ */ -+void pe_start(struct pfe_ctrl *ctrl, int pe_mask) -+{ -+ struct pe_sync_mailbox *mbox; -+ int i; -+ -+ for (i = 0; i < MAX_PE; i++) -+ if (pe_mask & (1 << i)) { -+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; -+ -+ pe_dmem_write(i, cpu_to_be32(0x0), (unsigned -+ long)&mbox->stop, 4); -+ } -+} -+ -+/* This function will ensure all PEs are put in to idle state */ -+int pe_reset_all(struct pfe_ctrl *ctrl) -+{ -+ struct pe_sync_mailbox *mbox; -+ int pe_stopped = 0; -+ unsigned long end = jiffies + 2; -+ int i; -+ int pe_mask = CLASS_MASK | TMU_MASK; -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ pe_mask |= UTIL_MASK; -+#endif -+ -+ for (i = 0; i < MAX_PE; i++) -+ if (pe_mask & (1 << i)) { -+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; -+ -+ pe_dmem_write(i, cpu_to_be32(0x2), (unsigned -+ long)&mbox->stop, 4); -+ } -+ -+ while (pe_stopped != pe_mask) { -+ for (i = 0; i < MAX_PE; i++) -+ if ((pe_mask & (1 << i)) && !(pe_stopped & (1 << i))) { -+ mbox = (void *)ctrl->sync_mailbox_baseaddr[i]; -+ -+ if (pe_dmem_read(i, (unsigned long) -+ &mbox->stopped, 4) & -+ cpu_to_be32(0x1)) -+ pe_stopped |= (1 << i); -+ } -+ -+ if (relax(end) < 0) -+ goto err; -+ } -+ -+ return 0; -+ -+err: -+ pr_err("%s: timeout, %x %x\n", __func__, pe_mask, pe_stopped); -+ return -EIO; -+} -+ -+int pfe_ctrl_init(struct pfe *pfe) -+{ -+ struct pfe_ctrl *ctrl = &pfe->ctrl; -+ int id; -+ -+ pr_info("%s\n", __func__); -+ -+ mutex_init(&ctrl->mutex); -+ spin_lock_init(&ctrl->lock); -+ -+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) { -+ ctrl->sync_mailbox_baseaddr[id] = CLASS_DM_SYNC_MBOX; -+ ctrl->msg_mailbox_baseaddr[id] = CLASS_DM_MSG_MBOX; -+ } -+ -+ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) { -+ if (id == TMU2_ID) -+ continue; -+ ctrl->sync_mailbox_baseaddr[id] = TMU_DM_SYNC_MBOX; -+ ctrl->msg_mailbox_baseaddr[id] = TMU_DM_MSG_MBOX; -+ } -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ ctrl->sync_mailbox_baseaddr[UTIL_ID] = UTIL_DM_SYNC_MBOX; -+ ctrl->msg_mailbox_baseaddr[UTIL_ID] = UTIL_DM_MSG_MBOX; -+#endif -+ -+ ctrl->hash_array_baseaddr = pfe->ddr_baseaddr + ROUTE_TABLE_BASEADDR; -+ ctrl->hash_array_phys_baseaddr = pfe->ddr_phys_baseaddr + -+ ROUTE_TABLE_BASEADDR; -+ -+ ctrl->dev = pfe->dev; -+ -+ pr_info("%s finished\n", __func__); -+ -+ return 0; -+} -+ -+void pfe_ctrl_exit(struct pfe *pfe) -+{ -+ pr_info("%s\n", __func__); -+} ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_debugfs.c -@@ -0,0 +1,111 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include -+#include -+#include -+ -+#include "pfe_mod.h" -+ -+static int dmem_show(struct seq_file *s, void *unused) -+{ -+ u32 dmem_addr, val; -+ int id = (long int)s->private; -+ int i; -+ -+ for (dmem_addr = 0; dmem_addr < CLASS_DMEM_SIZE; dmem_addr += 8 * 4) { -+ seq_printf(s, "%04x:", dmem_addr); -+ -+ for (i = 0; i < 8; i++) { -+ val = pe_dmem_read(id, dmem_addr + i * 4, 4); -+ seq_printf(s, " %02x %02x %02x %02x", val & 0xff, -+ (val >> 8) & 0xff, (val >> 16) & 0xff, -+ (val >> 24) & 0xff); -+ } -+ -+ seq_puts(s, "\n"); -+ } -+ -+ return 0; -+} -+ -+static int dmem_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, dmem_show, inode->i_private); -+} -+ -+static const struct file_operations dmem_fops = { -+ .open = dmem_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+int pfe_debugfs_init(struct pfe *pfe) -+{ -+ struct dentry *d; -+ -+ pr_info("%s\n", __func__); -+ -+ pfe->dentry = debugfs_create_dir("pfe", NULL); -+ if (IS_ERR_OR_NULL(pfe->dentry)) -+ goto err_dir; -+ -+ d = debugfs_create_file("pe0_dmem", 0444, pfe->dentry, (void *)0, -+ &dmem_fops); -+ if (IS_ERR_OR_NULL(d)) -+ goto err_pe; -+ -+ d = debugfs_create_file("pe1_dmem", 0444, pfe->dentry, (void *)1, -+ &dmem_fops); -+ if (IS_ERR_OR_NULL(d)) -+ goto err_pe; -+ -+ d = debugfs_create_file("pe2_dmem", 0444, pfe->dentry, (void *)2, -+ &dmem_fops); -+ if (IS_ERR_OR_NULL(d)) -+ goto err_pe; -+ -+ d = debugfs_create_file("pe3_dmem", 0444, pfe->dentry, (void *)3, -+ &dmem_fops); -+ if (IS_ERR_OR_NULL(d)) -+ goto err_pe; -+ -+ d = debugfs_create_file("pe4_dmem", 0444, pfe->dentry, (void *)4, -+ &dmem_fops); -+ if (IS_ERR_OR_NULL(d)) -+ goto err_pe; -+ -+ d = debugfs_create_file("pe5_dmem", 0444, pfe->dentry, (void *)5, -+ &dmem_fops); -+ if (IS_ERR_OR_NULL(d)) -+ goto err_pe; -+ -+ return 0; -+ -+err_pe: -+ debugfs_remove_recursive(pfe->dentry); -+ -+err_dir: -+ return -1; -+} -+ -+void pfe_debugfs_exit(struct pfe *pfe) -+{ -+ debugfs_remove_recursive(pfe->dentry); -+} ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -0,0 +1,2434 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* @pfe_eth.c. -+ * Ethernet driver for to handle exception path for PFE. -+ * - uses HIF functions to send/receive packets. -+ * - uses ctrl function to start/stop interfaces. -+ * - uses direct register accesses to control phy operation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#if defined(CONFIG_NF_CONNTRACK_MARK) -+#include -+#endif -+ -+#include "pfe_mod.h" -+#include "pfe_eth.h" -+ -+static void *cbus_emac_base[3]; -+static void *cbus_gpi_base[3]; -+ -+/* Forward Declaration */ -+static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv); -+static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv); -+static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int -+ from_tx, int n_desc); -+ -+unsigned int gemac_regs[] = { -+ 0x0004, /* Interrupt event */ -+ 0x0008, /* Interrupt mask */ -+ 0x0024, /* Ethernet control */ -+ 0x0064, /* MIB Control/Status */ -+ 0x0084, /* Receive control/status */ -+ 0x00C4, /* Transmit control */ -+ 0x00E4, /* Physical address low */ -+ 0x00E8, /* Physical address high */ -+ 0x0144, /* Transmit FIFO Watermark and Store and Forward Control*/ -+ 0x0190, /* Receive FIFO Section Full Threshold */ -+ 0x01A0, /* Transmit FIFO Section Empty Threshold */ -+ 0x01B0, /* Frame Truncation Length */ -+}; -+ -+/********************************************************************/ -+/* SYSFS INTERFACE */ -+/********************************************************************/ -+ -+#ifdef PFE_ETH_NAPI_STATS -+/* -+ * pfe_eth_show_napi_stats -+ */ -+static ssize_t pfe_eth_show_napi_stats(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ ssize_t len = 0; -+ -+ len += sprintf(buf + len, "sched: %u\n", -+ priv->napi_counters[NAPI_SCHED_COUNT]); -+ len += sprintf(buf + len, "poll: %u\n", -+ priv->napi_counters[NAPI_POLL_COUNT]); -+ len += sprintf(buf + len, "packet: %u\n", -+ priv->napi_counters[NAPI_PACKET_COUNT]); -+ len += sprintf(buf + len, "budget: %u\n", -+ priv->napi_counters[NAPI_FULL_BUDGET_COUNT]); -+ len += sprintf(buf + len, "desc: %u\n", -+ priv->napi_counters[NAPI_DESC_COUNT]); -+ -+ return len; -+} -+ -+/* -+ * pfe_eth_set_napi_stats -+ */ -+static ssize_t pfe_eth_set_napi_stats(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ -+ memset(priv->napi_counters, 0, sizeof(priv->napi_counters)); -+ -+ return count; -+} -+#endif -+#ifdef PFE_ETH_TX_STATS -+/* pfe_eth_show_tx_stats -+ * -+ */ -+static ssize_t pfe_eth_show_tx_stats(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ ssize_t len = 0; -+ int i; -+ -+ len += sprintf(buf + len, "TX queues stats:\n"); -+ -+ for (i = 0; i < emac_txq_cnt; i++) { -+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, -+ i); -+ -+ len += sprintf(buf + len, "\n"); -+ __netif_tx_lock_bh(tx_queue); -+ -+ hif_tx_lock(&pfe->hif); -+ len += sprintf(buf + len, -+ "Queue %2d : credits = %10d\n" -+ , i, hif_lib_tx_credit_avail(pfe, priv->id, i)); -+ len += sprintf(buf + len, -+ " tx packets = %10d\n" -+ , pfe->tmu_credit.tx_packets[priv->id][i]); -+ hif_tx_unlock(&pfe->hif); -+ -+ /* Don't output additionnal stats if queue never used */ -+ if (!pfe->tmu_credit.tx_packets[priv->id][i]) -+ goto skip; -+ -+ len += sprintf(buf + len, -+ " clean_fail = %10d\n" -+ , priv->clean_fail[i]); -+ len += sprintf(buf + len, -+ " stop_queue = %10d\n" -+ , priv->stop_queue_total[i]); -+ len += sprintf(buf + len, -+ " stop_queue_hif = %10d\n" -+ , priv->stop_queue_hif[i]); -+ len += sprintf(buf + len, -+ " stop_queue_hif_client = %10d\n" -+ , priv->stop_queue_hif_client[i]); -+ len += sprintf(buf + len, -+ " stop_queue_credit = %10d\n" -+ , priv->stop_queue_credit[i]); -+skip: -+ __netif_tx_unlock_bh(tx_queue); -+ } -+ return len; -+} -+ -+/* pfe_eth_set_tx_stats -+ * -+ */ -+static ssize_t pfe_eth_set_tx_stats(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ int i; -+ -+ for (i = 0; i < emac_txq_cnt; i++) { -+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, -+ i); -+ -+ __netif_tx_lock_bh(tx_queue); -+ priv->clean_fail[i] = 0; -+ priv->stop_queue_total[i] = 0; -+ priv->stop_queue_hif[i] = 0; -+ priv->stop_queue_hif_client[i] = 0; -+ priv->stop_queue_credit[i] = 0; -+ __netif_tx_unlock_bh(tx_queue); -+ } -+ -+ return count; -+} -+#endif -+/* pfe_eth_show_txavail -+ * -+ */ -+static ssize_t pfe_eth_show_txavail(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ ssize_t len = 0; -+ int i; -+ -+ for (i = 0; i < emac_txq_cnt; i++) { -+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, -+ i); -+ -+ __netif_tx_lock_bh(tx_queue); -+ -+ len += sprintf(buf + len, "%d", -+ hif_lib_tx_avail(&priv->client, i)); -+ -+ __netif_tx_unlock_bh(tx_queue); -+ -+ if (i == (emac_txq_cnt - 1)) -+ len += sprintf(buf + len, "\n"); -+ else -+ len += sprintf(buf + len, " "); -+ } -+ -+ return len; -+} -+ -+/* pfe_eth_show_default_priority -+ * -+ */ -+static ssize_t pfe_eth_show_default_priority(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ unsigned long flags; -+ int rc; -+ -+ spin_lock_irqsave(&priv->lock, flags); -+ rc = sprintf(buf, "%d\n", priv->default_priority); -+ spin_unlock_irqrestore(&priv->lock, flags); -+ -+ return rc; -+} -+ -+/* pfe_eth_set_default_priority -+ * -+ */ -+ -+static ssize_t pfe_eth_set_default_priority(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev)); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&priv->lock, flags); -+ priv->default_priority = kstrtoul(buf, 0, 0); -+ spin_unlock_irqrestore(&priv->lock, flags); -+ -+ return count; -+} -+ -+static DEVICE_ATTR(txavail, 0444, pfe_eth_show_txavail, NULL); -+static DEVICE_ATTR(default_priority, 0644, pfe_eth_show_default_priority, -+ pfe_eth_set_default_priority); -+ -+#ifdef PFE_ETH_NAPI_STATS -+static DEVICE_ATTR(napi_stats, 0644, pfe_eth_show_napi_stats, -+ pfe_eth_set_napi_stats); -+#endif -+ -+#ifdef PFE_ETH_TX_STATS -+static DEVICE_ATTR(tx_stats, 0644, pfe_eth_show_tx_stats, -+ pfe_eth_set_tx_stats); -+#endif -+ -+/* -+ * pfe_eth_sysfs_init -+ * -+ */ -+static int pfe_eth_sysfs_init(struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ int err; -+ -+ /* Initialize the default values */ -+ -+ /* -+ * By default, packets without conntrack will use this default high -+ * priority queue -+ */ -+ priv->default_priority = 15; -+ -+ /* Create our sysfs files */ -+ err = device_create_file(&ndev->dev, &dev_attr_default_priority); -+ if (err) { -+ netdev_err(ndev, -+ "failed to create default_priority sysfs files\n"); -+ goto err_priority; -+ } -+ -+ err = device_create_file(&ndev->dev, &dev_attr_txavail); -+ if (err) { -+ netdev_err(ndev, -+ "failed to create default_priority sysfs files\n"); -+ goto err_txavail; -+ } -+ -+#ifdef PFE_ETH_NAPI_STATS -+ err = device_create_file(&ndev->dev, &dev_attr_napi_stats); -+ if (err) { -+ netdev_err(ndev, "failed to create napi stats sysfs files\n"); -+ goto err_napi; -+ } -+#endif -+ -+#ifdef PFE_ETH_TX_STATS -+ err = device_create_file(&ndev->dev, &dev_attr_tx_stats); -+ if (err) { -+ netdev_err(ndev, "failed to create tx stats sysfs files\n"); -+ goto err_tx; -+ } -+#endif -+ -+ return 0; -+ -+#ifdef PFE_ETH_TX_STATS -+err_tx: -+#endif -+#ifdef PFE_ETH_NAPI_STATS -+ device_remove_file(&ndev->dev, &dev_attr_napi_stats); -+ -+err_napi: -+#endif -+ device_remove_file(&ndev->dev, &dev_attr_txavail); -+ -+err_txavail: -+ device_remove_file(&ndev->dev, &dev_attr_default_priority); -+ -+err_priority: -+ return -1; -+} -+ -+/* pfe_eth_sysfs_exit -+ * -+ */ -+void pfe_eth_sysfs_exit(struct net_device *ndev) -+{ -+#ifdef PFE_ETH_TX_STATS -+ device_remove_file(&ndev->dev, &dev_attr_tx_stats); -+#endif -+ -+#ifdef PFE_ETH_NAPI_STATS -+ device_remove_file(&ndev->dev, &dev_attr_napi_stats); -+#endif -+ device_remove_file(&ndev->dev, &dev_attr_txavail); -+ device_remove_file(&ndev->dev, &dev_attr_default_priority); -+} -+ -+/*************************************************************************/ -+/* ETHTOOL INTERCAE */ -+/*************************************************************************/ -+ -+/*MTIP GEMAC */ -+static const struct fec_stat { -+ char name[ETH_GSTRING_LEN]; -+ u16 offset; -+} fec_stats[] = { -+ /* RMON TX */ -+ { "tx_dropped", RMON_T_DROP }, -+ { "tx_packets", RMON_T_PACKETS }, -+ { "tx_broadcast", RMON_T_BC_PKT }, -+ { "tx_multicast", RMON_T_MC_PKT }, -+ { "tx_crc_errors", RMON_T_CRC_ALIGN }, -+ { "tx_undersize", RMON_T_UNDERSIZE }, -+ { "tx_oversize", RMON_T_OVERSIZE }, -+ { "tx_fragment", RMON_T_FRAG }, -+ { "tx_jabber", RMON_T_JAB }, -+ { "tx_collision", RMON_T_COL }, -+ { "tx_64byte", RMON_T_P64 }, -+ { "tx_65to127byte", RMON_T_P65TO127 }, -+ { "tx_128to255byte", RMON_T_P128TO255 }, -+ { "tx_256to511byte", RMON_T_P256TO511 }, -+ { "tx_512to1023byte", RMON_T_P512TO1023 }, -+ { "tx_1024to2047byte", RMON_T_P1024TO2047 }, -+ { "tx_GTE2048byte", RMON_T_P_GTE2048 }, -+ { "tx_octets", RMON_T_OCTETS }, -+ -+ /* IEEE TX */ -+ { "IEEE_tx_drop", IEEE_T_DROP }, -+ { "IEEE_tx_frame_ok", IEEE_T_FRAME_OK }, -+ { "IEEE_tx_1col", IEEE_T_1COL }, -+ { "IEEE_tx_mcol", IEEE_T_MCOL }, -+ { "IEEE_tx_def", IEEE_T_DEF }, -+ { "IEEE_tx_lcol", IEEE_T_LCOL }, -+ { "IEEE_tx_excol", IEEE_T_EXCOL }, -+ { "IEEE_tx_macerr", IEEE_T_MACERR }, -+ { "IEEE_tx_cserr", IEEE_T_CSERR }, -+ { "IEEE_tx_sqe", IEEE_T_SQE }, -+ { "IEEE_tx_fdxfc", IEEE_T_FDXFC }, -+ { "IEEE_tx_octets_ok", IEEE_T_OCTETS_OK }, -+ -+ /* RMON RX */ -+ { "rx_packets", RMON_R_PACKETS }, -+ { "rx_broadcast", RMON_R_BC_PKT }, -+ { "rx_multicast", RMON_R_MC_PKT }, -+ { "rx_crc_errors", RMON_R_CRC_ALIGN }, -+ { "rx_undersize", RMON_R_UNDERSIZE }, -+ { "rx_oversize", RMON_R_OVERSIZE }, -+ { "rx_fragment", RMON_R_FRAG }, -+ { "rx_jabber", RMON_R_JAB }, -+ { "rx_64byte", RMON_R_P64 }, -+ { "rx_65to127byte", RMON_R_P65TO127 }, -+ { "rx_128to255byte", RMON_R_P128TO255 }, -+ { "rx_256to511byte", RMON_R_P256TO511 }, -+ { "rx_512to1023byte", RMON_R_P512TO1023 }, -+ { "rx_1024to2047byte", RMON_R_P1024TO2047 }, -+ { "rx_GTE2048byte", RMON_R_P_GTE2048 }, -+ { "rx_octets", RMON_R_OCTETS }, -+ -+ /* IEEE RX */ -+ { "IEEE_rx_drop", IEEE_R_DROP }, -+ { "IEEE_rx_frame_ok", IEEE_R_FRAME_OK }, -+ { "IEEE_rx_crc", IEEE_R_CRC }, -+ { "IEEE_rx_align", IEEE_R_ALIGN }, -+ { "IEEE_rx_macerr", IEEE_R_MACERR }, -+ { "IEEE_rx_fdxfc", IEEE_R_FDXFC }, -+ { "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK }, -+}; -+ -+static void pfe_eth_fill_stats(struct net_device *ndev, struct ethtool_stats -+ *stats, u64 *data) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(fec_stats); i++) -+ data[i] = readl(priv->EMAC_baseaddr + fec_stats[i].offset); -+} -+ -+static void pfe_eth_gstrings(struct net_device *netdev, -+ u32 stringset, u8 *data) -+{ -+ int i; -+ -+ switch (stringset) { -+ case ETH_SS_STATS: -+ for (i = 0; i < ARRAY_SIZE(fec_stats); i++) -+ memcpy(data + i * ETH_GSTRING_LEN, -+ fec_stats[i].name, ETH_GSTRING_LEN); -+ break; -+ } -+} -+ -+static int pfe_eth_stats_count(struct net_device *ndev, int sset) -+{ -+ switch (sset) { -+ case ETH_SS_STATS: -+ return ARRAY_SIZE(fec_stats); -+ default: -+ return -EOPNOTSUPP; -+ } -+} -+ -+/* -+ * pfe_eth_gemac_reglen - Return the length of the register structure. -+ * -+ */ -+static int pfe_eth_gemac_reglen(struct net_device *ndev) -+{ -+ pr_info("%s()\n", __func__); -+ return (sizeof(gemac_regs) / sizeof(u32)); -+} -+ -+/* -+ * pfe_eth_gemac_get_regs - Return the gemac register structure. -+ * -+ */ -+static void pfe_eth_gemac_get_regs(struct net_device *ndev, struct ethtool_regs -+ *regs, void *regbuf) -+{ -+ int i; -+ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ u32 *buf = (u32 *)regbuf; -+ -+ pr_info("%s()\n", __func__); -+ for (i = 0; i < sizeof(gemac_regs) / sizeof(u32); i++) -+ buf[i] = readl(priv->EMAC_baseaddr + gemac_regs[i]); -+} -+ -+/* -+ * pfe_eth_set_wol - Set the magic packet option, in WoL register. -+ * -+ */ -+static int pfe_eth_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ if (wol->wolopts & ~WAKE_MAGIC) -+ return -EOPNOTSUPP; -+ -+ /* for MTIP we store wol->wolopts */ -+ priv->wol = wol->wolopts; -+ -+ device_set_wakeup_enable(&ndev->dev, wol->wolopts & WAKE_MAGIC); -+ -+ return 0; -+} -+ -+/* -+ * -+ * pfe_eth_get_wol - Get the WoL options. -+ * -+ */ -+static void pfe_eth_get_wol(struct net_device *ndev, struct ethtool_wolinfo -+ *wol) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ wol->supported = WAKE_MAGIC; -+ wol->wolopts = 0; -+ -+ if (priv->wol & WAKE_MAGIC) -+ wol->wolopts = WAKE_MAGIC; -+ -+ memset(&wol->sopass, 0, sizeof(wol->sopass)); -+} -+ -+/* -+ * pfe_eth_get_drvinfo - Fills in the drvinfo structure with some basic info -+ * -+ */ -+static void pfe_eth_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo -+ *drvinfo) -+{ -+ strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); -+ strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); -+ strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); -+ strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info)); -+} -+ -+/* -+ * pfe_eth_set_settings - Used to send commands to PHY. -+ * -+ */ -+static int pfe_eth_set_settings(struct net_device *ndev, -+ const struct ethtool_link_ksettings *cmd) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ struct phy_device *phydev = priv->phydev; -+ -+ if (!phydev) -+ return -ENODEV; -+ -+ return phy_ethtool_ksettings_set(phydev, cmd); -+} -+ -+/* -+ * pfe_eth_getsettings - Return the current settings in the ethtool_cmd -+ * structure. -+ * -+ */ -+static int pfe_eth_get_settings(struct net_device *ndev, -+ struct ethtool_link_ksettings *cmd) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ struct phy_device *phydev = priv->phydev; -+ -+ if (!phydev) -+ return -ENODEV; -+ -+ return phy_ethtool_ksettings_get(phydev, cmd); -+} -+ -+/* -+ * pfe_eth_get_msglevel - Gets the debug message mask. -+ * -+ */ -+static uint32_t pfe_eth_get_msglevel(struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ return priv->msg_enable; -+} -+ -+/* -+ * pfe_eth_set_msglevel - Sets the debug message mask. -+ * -+ */ -+static void pfe_eth_set_msglevel(struct net_device *ndev, uint32_t data) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ priv->msg_enable = data; -+} -+ -+#define HIF_RX_COAL_MAX_CLKS (~(1 << 31)) -+#define HIF_RX_COAL_CLKS_PER_USEC (pfe->ctrl.sys_clk / 1000) -+#define HIF_RX_COAL_MAX_USECS (HIF_RX_COAL_MAX_CLKS / \ -+ HIF_RX_COAL_CLKS_PER_USEC) -+ -+/* -+ * pfe_eth_set_coalesce - Sets rx interrupt coalescing timer. -+ * -+ */ -+static int pfe_eth_set_coalesce(struct net_device *ndev, -+ struct ethtool_coalesce *ec) -+{ -+ if (ec->rx_coalesce_usecs > HIF_RX_COAL_MAX_USECS) -+ return -EINVAL; -+ -+ if (!ec->rx_coalesce_usecs) { -+ writel(0, HIF_INT_COAL); -+ return 0; -+ } -+ -+ writel((ec->rx_coalesce_usecs * HIF_RX_COAL_CLKS_PER_USEC) | -+ HIF_INT_COAL_ENABLE, HIF_INT_COAL); -+ -+ return 0; -+} -+ -+/* -+ * pfe_eth_get_coalesce - Gets rx interrupt coalescing timer value. -+ * -+ */ -+static int pfe_eth_get_coalesce(struct net_device *ndev, -+ struct ethtool_coalesce *ec) -+{ -+ int reg_val = readl(HIF_INT_COAL); -+ -+ if (reg_val & HIF_INT_COAL_ENABLE) -+ ec->rx_coalesce_usecs = (reg_val & HIF_RX_COAL_MAX_CLKS) / -+ HIF_RX_COAL_CLKS_PER_USEC; -+ else -+ ec->rx_coalesce_usecs = 0; -+ -+ return 0; -+} -+ -+/* -+ * pfe_eth_set_pauseparam - Sets pause parameters -+ * -+ */ -+static int pfe_eth_set_pauseparam(struct net_device *ndev, -+ struct ethtool_pauseparam *epause) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ if (epause->tx_pause != epause->rx_pause) { -+ netdev_info(ndev, -+ "hardware only support enable/disable both tx and rx\n"); -+ return -EINVAL; -+ } -+ -+ priv->pause_flag = 0; -+ priv->pause_flag |= epause->rx_pause ? PFE_PAUSE_FLAG_ENABLE : 0; -+ priv->pause_flag |= epause->autoneg ? PFE_PAUSE_FLAG_AUTONEG : 0; -+ -+ if (epause->rx_pause || epause->autoneg) { -+ gemac_enable_pause_rx(priv->EMAC_baseaddr); -+ writel((readl(priv->GPI_baseaddr + GPI_TX_PAUSE_TIME) | -+ EGPI_PAUSE_ENABLE), -+ priv->GPI_baseaddr + GPI_TX_PAUSE_TIME); -+ if (priv->phydev) { -+ priv->phydev->supported |= ADVERTISED_Pause | -+ ADVERTISED_Asym_Pause; -+ priv->phydev->advertising |= ADVERTISED_Pause | -+ ADVERTISED_Asym_Pause; -+ } -+ } else { -+ gemac_disable_pause_rx(priv->EMAC_baseaddr); -+ writel((readl(priv->GPI_baseaddr + GPI_TX_PAUSE_TIME) & -+ ~EGPI_PAUSE_ENABLE), -+ priv->GPI_baseaddr + GPI_TX_PAUSE_TIME); -+ if (priv->phydev) { -+ priv->phydev->supported &= ~(ADVERTISED_Pause | -+ ADVERTISED_Asym_Pause); -+ priv->phydev->advertising &= ~(ADVERTISED_Pause | -+ ADVERTISED_Asym_Pause); -+ } -+ } -+ -+ return 0; -+} -+ -+/* -+ * pfe_eth_get_pauseparam - Gets pause parameters -+ * -+ */ -+static void pfe_eth_get_pauseparam(struct net_device *ndev, -+ struct ethtool_pauseparam *epause) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ epause->autoneg = (priv->pause_flag & PFE_PAUSE_FLAG_AUTONEG) != 0; -+ epause->tx_pause = (priv->pause_flag & PFE_PAUSE_FLAG_ENABLE) != 0; -+ epause->rx_pause = epause->tx_pause; -+} -+ -+/* -+ * pfe_eth_get_hash -+ */ -+#define PFE_HASH_BITS 6 /* #bits in hash */ -+#define CRC32_POLY 0xEDB88320 -+ -+static int pfe_eth_get_hash(u8 *addr) -+{ -+ unsigned int i, bit, data, crc, hash; -+ -+ /* calculate crc32 value of mac address */ -+ crc = 0xffffffff; -+ -+ for (i = 0; i < 6; i++) { -+ data = addr[i]; -+ for (bit = 0; bit < 8; bit++, data >>= 1) { -+ crc = (crc >> 1) ^ -+ (((crc ^ data) & 1) ? CRC32_POLY : 0); -+ } -+ } -+ -+ /* -+ * only upper 6 bits (PFE_HASH_BITS) are used -+ * which point to specific bit in the hash registers -+ */ -+ hash = (crc >> (32 - PFE_HASH_BITS)) & 0x3f; -+ -+ return hash; -+} -+ -+const struct ethtool_ops pfe_ethtool_ops = { -+ .get_drvinfo = pfe_eth_get_drvinfo, -+ .get_regs_len = pfe_eth_gemac_reglen, -+ .get_regs = pfe_eth_gemac_get_regs, -+ .get_link = ethtool_op_get_link, -+ .get_wol = pfe_eth_get_wol, -+ .set_wol = pfe_eth_set_wol, -+ .set_pauseparam = pfe_eth_set_pauseparam, -+ .get_pauseparam = pfe_eth_get_pauseparam, -+ .get_strings = pfe_eth_gstrings, -+ .get_sset_count = pfe_eth_stats_count, -+ .get_ethtool_stats = pfe_eth_fill_stats, -+ .get_msglevel = pfe_eth_get_msglevel, -+ .set_msglevel = pfe_eth_set_msglevel, -+ .set_coalesce = pfe_eth_set_coalesce, -+ .get_coalesce = pfe_eth_get_coalesce, -+ .get_link_ksettings = pfe_eth_get_settings, -+ .set_link_ksettings = pfe_eth_set_settings, -+}; -+ -+/* pfe_eth_mdio_reset -+ */ -+int pfe_eth_mdio_reset(struct mii_bus *bus) -+{ -+ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; -+ u32 phy_speed; -+ -+ netif_info(priv, hw, priv->ndev, "%s\n", __func__); -+ -+ mutex_lock(&bus->mdio_lock); -+ -+ /* -+ * Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed) -+ * -+ * The formula for FEC MDC is 'ref_freq / (MII_SPEED x 2)' while -+ * for ENET-MAC is 'ref_freq / ((MII_SPEED + 1) x 2)'. -+ */ -+ phy_speed = (DIV_ROUND_UP((pfe->ctrl.sys_clk * 1000), 4000000) -+ << EMAC_MII_SPEED_SHIFT); -+ phy_speed |= EMAC_HOLDTIME(0x5); -+ __raw_writel(phy_speed, priv->PHY_baseaddr + EMAC_MII_CTRL_REG); -+ -+ mutex_unlock(&bus->mdio_lock); -+ -+ return 0; -+} -+ -+/* pfe_eth_gemac_phy_timeout -+ * -+ */ -+static int pfe_eth_gemac_phy_timeout(struct pfe_eth_priv_s *priv, int timeout) -+{ -+ while (!(__raw_readl(priv->PHY_baseaddr + EMAC_IEVENT_REG) & -+ EMAC_IEVENT_MII)) { -+ if (timeout-- <= 0) -+ return -1; -+ usleep_range(10, 20); -+ } -+ __raw_writel(EMAC_IEVENT_MII, priv->PHY_baseaddr + EMAC_IEVENT_REG); -+ return 0; -+} -+ -+static int pfe_eth_mdio_mux(u8 muxval) -+{ -+ struct i2c_adapter *a; -+ struct i2c_msg msg; -+ unsigned char buf[2]; -+ int ret; -+ -+ a = i2c_get_adapter(0); -+ if (!a) -+ return -ENODEV; -+ -+ /* set bit 1 (the second bit) of chip at 0x09, register 0x13 */ -+ buf[0] = 0x54; /* reg number */ -+ buf[1] = (muxval << 6) | 0x3; /* data */ -+ msg.addr = 0x66; -+ msg.buf = buf; -+ msg.len = 2; -+ msg.flags = 0; -+ ret = i2c_transfer(a, &msg, 1); -+ i2c_put_adapter(a); -+ if (ret != 1) -+ return -ENODEV; -+ return 0; -+} -+ -+static int pfe_eth_mdio_write_addr(struct mii_bus *bus, int mii_id, -+ int dev_addr, int regnum) -+{ -+ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; -+ -+ __raw_writel(EMAC_MII_DATA_PA(mii_id) | -+ EMAC_MII_DATA_RA(dev_addr) | -+ EMAC_MII_DATA_TA | EMAC_MII_DATA(regnum), -+ priv->PHY_baseaddr + EMAC_MII_DATA_REG); -+ -+ if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { -+ netdev_err(priv->ndev, "%s: phy MDIO address write timeout\n", -+ __func__); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum, -+ u16 value) -+{ -+ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; -+ -+ /*To access external PHYs on QDS board mux needs to be configured*/ -+ if ((mii_id) && (pfe->mdio_muxval[mii_id])) -+ pfe_eth_mdio_mux(pfe->mdio_muxval[mii_id]); -+ -+ if (regnum & MII_ADDR_C45) { -+ pfe_eth_mdio_write_addr(bus, mii_id, (regnum >> 16) & 0x1f, -+ regnum & 0xffff); -+ __raw_writel(EMAC_MII_DATA_OP_CL45_WR | -+ EMAC_MII_DATA_PA(mii_id) | -+ EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) | -+ EMAC_MII_DATA_TA | EMAC_MII_DATA(value), -+ priv->PHY_baseaddr + EMAC_MII_DATA_REG); -+ } else { -+ /* start a write op */ -+ __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR | -+ EMAC_MII_DATA_PA(mii_id) | -+ EMAC_MII_DATA_RA(regnum) | -+ EMAC_MII_DATA_TA | EMAC_MII_DATA(value), -+ priv->PHY_baseaddr + EMAC_MII_DATA_REG); -+ } -+ -+ if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { -+ netdev_err(priv->ndev, "%s: phy MDIO write timeout\n", -+ __func__); -+ return -1; -+ } -+ netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__, -+ mii_id, regnum, value); -+ -+ return 0; -+} -+ -+static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum) -+{ -+ struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; -+ u16 value = 0; -+ -+ /*To access external PHYs on QDS board mux needs to be configured*/ -+ if ((mii_id) && (pfe->mdio_muxval[mii_id])) -+ pfe_eth_mdio_mux(pfe->mdio_muxval[mii_id]); -+ -+ if (regnum & MII_ADDR_C45) { -+ pfe_eth_mdio_write_addr(bus, mii_id, (regnum >> 16) & 0x1f, -+ regnum & 0xffff); -+ __raw_writel(EMAC_MII_DATA_OP_CL45_RD | -+ EMAC_MII_DATA_PA(mii_id) | -+ EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) | -+ EMAC_MII_DATA_TA, -+ priv->PHY_baseaddr + EMAC_MII_DATA_REG); -+ } else { -+ /* start a read op */ -+ __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD | -+ EMAC_MII_DATA_PA(mii_id) | -+ EMAC_MII_DATA_RA(regnum) | -+ EMAC_MII_DATA_TA, priv->PHY_baseaddr + -+ EMAC_MII_DATA_REG); -+ } -+ -+ if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { -+ netdev_err(priv->ndev, "%s: phy MDIO read timeout\n", __func__); -+ return -1; -+ } -+ -+ value = EMAC_MII_DATA(__raw_readl(priv->PHY_baseaddr + -+ EMAC_MII_DATA_REG)); -+ netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__, -+ mii_id, regnum, value); -+ return value; -+} -+ -+static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv, -+ struct ls1012a_mdio_platform_data *minfo) -+{ -+ struct mii_bus *bus; -+ int rc; -+ -+ netif_info(priv, drv, priv->ndev, "%s\n", __func__); -+ pr_info("%s\n", __func__); -+ -+ bus = mdiobus_alloc(); -+ if (!bus) { -+ netdev_err(priv->ndev, "mdiobus_alloc() failed\n"); -+ rc = -ENOMEM; -+ goto err0; -+ } -+ -+ bus->name = "ls1012a MDIO Bus"; -+ bus->read = &pfe_eth_mdio_read; -+ bus->write = &pfe_eth_mdio_write; -+ bus->reset = &pfe_eth_mdio_reset; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id); -+ bus->priv = priv; -+ -+ bus->phy_mask = minfo->phy_mask; -+ priv->mdc_div = minfo->mdc_div; -+ -+ if (!priv->mdc_div) -+ priv->mdc_div = 64; -+ -+ bus->irq[0] = minfo->irq[0]; -+ -+ bus->parent = priv->pfe->dev; -+ -+ netif_info(priv, drv, priv->ndev, "%s: mdc_div: %d, phy_mask: %x\n", -+ __func__, priv->mdc_div, bus->phy_mask); -+ rc = mdiobus_register(bus); -+ if (rc) { -+ netdev_err(priv->ndev, "mdiobus_register(%s) failed\n", -+ bus->name); -+ goto err1; -+ } -+ -+ priv->mii_bus = bus; -+ pfe_eth_mdio_reset(bus); -+ -+ return 0; -+ -+err1: -+ mdiobus_free(bus); -+err0: -+ return rc; -+} -+ -+/* pfe_eth_mdio_exit -+ */ -+static void pfe_eth_mdio_exit(struct mii_bus *bus) -+{ -+ if (!bus) -+ return; -+ -+ netif_info((struct pfe_eth_priv_s *)bus->priv, drv, ((struct -+ pfe_eth_priv_s *)(bus->priv))->ndev, "%s\n", __func__); -+ -+ mdiobus_unregister(bus); -+ mdiobus_free(bus); -+} -+ -+/* pfe_get_phydev_speed -+ */ -+static int pfe_get_phydev_speed(struct phy_device *phydev) -+{ -+ switch (phydev->speed) { -+ case 10: -+ return SPEED_10M; -+ case 100: -+ return SPEED_100M; -+ case 1000: -+ default: -+ return SPEED_1000M; -+ } -+} -+ -+/* pfe_set_rgmii_speed -+ */ -+#define RGMIIPCR 0x434 -+/* RGMIIPCR bit definitions*/ -+#define SCFG_RGMIIPCR_EN_AUTO (0x00000008) -+#define SCFG_RGMIIPCR_SETSP_1000M (0x00000004) -+#define SCFG_RGMIIPCR_SETSP_100M (0x00000000) -+#define SCFG_RGMIIPCR_SETSP_10M (0x00000002) -+#define SCFG_RGMIIPCR_SETFD (0x00000001) -+ -+static void pfe_set_rgmii_speed(struct phy_device *phydev) -+{ -+ u32 rgmii_pcr; -+ -+ regmap_read(pfe->scfg, RGMIIPCR, &rgmii_pcr); -+ rgmii_pcr &= ~(SCFG_RGMIIPCR_SETSP_1000M | SCFG_RGMIIPCR_SETSP_10M); -+ -+ switch (phydev->speed) { -+ case 10: -+ rgmii_pcr |= SCFG_RGMIIPCR_SETSP_10M; -+ break; -+ case 1000: -+ rgmii_pcr |= SCFG_RGMIIPCR_SETSP_1000M; -+ break; -+ case 100: -+ default: -+ /* Default is 100M */ -+ break; -+ } -+ regmap_write(pfe->scfg, RGMIIPCR, rgmii_pcr); -+} -+ -+/* pfe_get_phydev_duplex -+ */ -+static int pfe_get_phydev_duplex(struct phy_device *phydev) -+{ -+ /*return (phydev->duplex == DUPLEX_HALF) ? DUP_HALF:DUP_FULL ; */ -+ return DUPLEX_FULL; -+} -+ -+/* pfe_eth_adjust_link -+ */ -+static void pfe_eth_adjust_link(struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ unsigned long flags; -+ struct phy_device *phydev = priv->phydev; -+ int new_state = 0; -+ -+ netif_info(priv, drv, ndev, "%s\n", __func__); -+ -+ spin_lock_irqsave(&priv->lock, flags); -+ -+ if (phydev->link) { -+ /* -+ * Now we make sure that we can be in full duplex mode. -+ * If not, we operate in half-duplex mode. -+ */ -+ if (phydev->duplex != priv->oldduplex) { -+ new_state = 1; -+ gemac_set_duplex(priv->EMAC_baseaddr, -+ pfe_get_phydev_duplex(phydev)); -+ priv->oldduplex = phydev->duplex; -+ } -+ -+ if (phydev->speed != priv->oldspeed) { -+ new_state = 1; -+ gemac_set_speed(priv->EMAC_baseaddr, -+ pfe_get_phydev_speed(phydev)); -+ if (priv->einfo->mii_config == PHY_INTERFACE_MODE_RGMII) -+ pfe_set_rgmii_speed(phydev); -+ priv->oldspeed = phydev->speed; -+ } -+ -+ if (!priv->oldlink) { -+ new_state = 1; -+ priv->oldlink = 1; -+ } -+ -+ } else if (priv->oldlink) { -+ new_state = 1; -+ priv->oldlink = 0; -+ priv->oldspeed = 0; -+ priv->oldduplex = -1; -+ } -+ -+ if (new_state && netif_msg_link(priv)) -+ phy_print_status(phydev); -+ -+ spin_unlock_irqrestore(&priv->lock, flags); -+} -+ -+/* pfe_phy_exit -+ */ -+static void pfe_phy_exit(struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ netif_info(priv, drv, ndev, "%s\n", __func__); -+ -+ phy_disconnect(priv->phydev); -+ priv->phydev = NULL; -+} -+ -+/* pfe_eth_stop -+ */ -+static void pfe_eth_stop(struct net_device *ndev, int wake) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ netif_info(priv, drv, ndev, "%s\n", __func__); -+ -+ if (wake) { -+ gemac_tx_disable(priv->EMAC_baseaddr); -+ } else { -+ gemac_disable(priv->EMAC_baseaddr); -+ gpi_disable(priv->GPI_baseaddr); -+ -+ if (priv->phydev) -+ phy_stop(priv->phydev); -+ } -+} -+ -+/* pfe_eth_start -+ */ -+static int pfe_eth_start(struct pfe_eth_priv_s *priv) -+{ -+ netif_info(priv, drv, priv->ndev, "%s\n", __func__); -+ -+ if (priv->phydev) -+ phy_start(priv->phydev); -+ -+ gpi_enable(priv->GPI_baseaddr); -+ gemac_enable(priv->EMAC_baseaddr); -+ -+ return 0; -+} -+ -+/* -+ * Configure on chip serdes through mdio -+ */ -+static void ls1012a_configure_serdes(struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = pfe->eth.eth_priv[0]; -+ int sgmii_2500 = 0; -+ struct mii_bus *bus = priv->mii_bus; -+ -+ if (priv->einfo->mii_config == PHY_INTERFACE_MODE_SGMII_2500) -+ sgmii_2500 = 1; -+ -+ netif_info(priv, drv, ndev, "%s\n", __func__); -+ /* PCS configuration done with corresponding GEMAC */ -+ -+ pfe_eth_mdio_read(bus, 0, 0); -+ pfe_eth_mdio_read(bus, 0, 1); -+ -+ /*These settings taken from validtion team */ -+ pfe_eth_mdio_write(bus, 0, 0x0, 0x8000); -+ if (sgmii_2500) { -+ pfe_eth_mdio_write(bus, 0, 0x14, 0x9); -+ pfe_eth_mdio_write(bus, 0, 0x4, 0x4001); -+ pfe_eth_mdio_write(bus, 0, 0x12, 0xa120); -+ pfe_eth_mdio_write(bus, 0, 0x13, 0x7); -+ } else { -+ pfe_eth_mdio_write(bus, 0, 0x14, 0xb); -+ pfe_eth_mdio_write(bus, 0, 0x4, 0x1a1); -+ pfe_eth_mdio_write(bus, 0, 0x12, 0x400); -+ pfe_eth_mdio_write(bus, 0, 0x13, 0x0); -+ } -+ -+ pfe_eth_mdio_write(bus, 0, 0x0, 0x1140); -+} -+ -+/* -+ * pfe_phy_init -+ * -+ */ -+static int pfe_phy_init(struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ struct phy_device *phydev; -+ char phy_id[MII_BUS_ID_SIZE + 3]; -+ char bus_id[MII_BUS_ID_SIZE]; -+ phy_interface_t interface; -+ -+ priv->oldlink = 0; -+ priv->oldspeed = 0; -+ priv->oldduplex = -1; -+ -+ snprintf(bus_id, MII_BUS_ID_SIZE, "ls1012a-%d", 0); -+ snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, -+ priv->einfo->phy_id); -+ -+ netif_info(priv, drv, ndev, "%s: %s\n", __func__, phy_id); -+ interface = priv->einfo->mii_config; -+ if ((interface == PHY_INTERFACE_MODE_SGMII) || -+ (interface == PHY_INTERFACE_MODE_SGMII_2500)) { -+ /*Configure SGMII PCS */ -+ if (pfe->scfg) { -+ /*Config MDIO from serdes */ -+ regmap_write(pfe->scfg, 0x484, 0x00000000); -+ } -+ ls1012a_configure_serdes(ndev); -+ } -+ -+ if (pfe->scfg) { -+ /*Config MDIO from PAD */ -+ regmap_write(pfe->scfg, 0x484, 0x80000000); -+ } -+ -+ priv->oldlink = 0; -+ priv->oldspeed = 0; -+ priv->oldduplex = -1; -+ pr_info("%s interface %x\n", __func__, interface); -+ phydev = phy_connect(ndev, phy_id, &pfe_eth_adjust_link, interface); -+ -+ if (IS_ERR(phydev)) { -+ netdev_err(ndev, "phy_connect() failed\n"); -+ return PTR_ERR(phydev); -+ } -+ -+ priv->phydev = phydev; -+ phydev->irq = PHY_POLL; -+ -+ return 0; -+} -+ -+/* pfe_gemac_init -+ */ -+static int pfe_gemac_init(struct pfe_eth_priv_s *priv) -+{ -+ struct gemac_cfg cfg; -+ -+ netif_info(priv, ifup, priv->ndev, "%s\n", __func__); -+ -+ cfg.speed = SPEED_1000M; -+ cfg.duplex = DUPLEX_FULL; -+ -+ gemac_set_config(priv->EMAC_baseaddr, &cfg); -+ gemac_allow_broadcast(priv->EMAC_baseaddr); -+ gemac_enable_1536_rx(priv->EMAC_baseaddr); -+ gemac_enable_rx_jmb(priv->EMAC_baseaddr); -+ gemac_enable_stacked_vlan(priv->EMAC_baseaddr); -+ gemac_enable_pause_rx(priv->EMAC_baseaddr); -+ gemac_set_bus_width(priv->EMAC_baseaddr, 64); -+ -+ /*GEM will perform checksum verifications*/ -+ if (priv->ndev->features & NETIF_F_RXCSUM) -+ gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr); -+ else -+ gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr); -+ -+ return 0; -+} -+ -+/* pfe_eth_event_handler -+ */ -+static int pfe_eth_event_handler(void *data, int event, int qno) -+{ -+ struct pfe_eth_priv_s *priv = data; -+ -+ switch (event) { -+ case EVENT_RX_PKT_IND: -+ -+ if (qno == 0) { -+ if (napi_schedule_prep(&priv->high_napi)) { -+ netif_info(priv, intr, priv->ndev, -+ "%s: schedule high prio poll\n" -+ , __func__); -+ -+#ifdef PFE_ETH_NAPI_STATS -+ priv->napi_counters[NAPI_SCHED_COUNT]++; -+#endif -+ -+ __napi_schedule(&priv->high_napi); -+ } -+ } else if (qno == 1) { -+ if (napi_schedule_prep(&priv->low_napi)) { -+ netif_info(priv, intr, priv->ndev, -+ "%s: schedule low prio poll\n" -+ , __func__); -+ -+#ifdef PFE_ETH_NAPI_STATS -+ priv->napi_counters[NAPI_SCHED_COUNT]++; -+#endif -+ __napi_schedule(&priv->low_napi); -+ } -+ } else if (qno == 2) { -+ if (napi_schedule_prep(&priv->lro_napi)) { -+ netif_info(priv, intr, priv->ndev, -+ "%s: schedule lro prio poll\n" -+ , __func__); -+ -+#ifdef PFE_ETH_NAPI_STATS -+ priv->napi_counters[NAPI_SCHED_COUNT]++; -+#endif -+ __napi_schedule(&priv->lro_napi); -+ } -+ } -+ -+ break; -+ -+ case EVENT_TXDONE_IND: -+ pfe_eth_flush_tx(priv); -+ hif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0); -+ break; -+ case EVENT_HIGH_RX_WM: -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+/* pfe_eth_open -+ */ -+static int pfe_eth_open(struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ struct hif_client_s *client; -+ int rc; -+ -+ netif_info(priv, ifup, ndev, "%s\n", __func__); -+ -+ /* Register client driver with HIF */ -+ client = &priv->client; -+ memset(client, 0, sizeof(*client)); -+ client->id = PFE_CL_GEM0 + priv->id; -+ client->tx_qn = emac_txq_cnt; -+ client->rx_qn = EMAC_RXQ_CNT; -+ client->priv = priv; -+ client->pfe = priv->pfe; -+ client->event_handler = pfe_eth_event_handler; -+ -+ client->tx_qsize = EMAC_TXQ_DEPTH; -+ client->rx_qsize = EMAC_RXQ_DEPTH; -+ -+ rc = hif_lib_client_register(client); -+ if (rc) { -+ netdev_err(ndev, "%s: hif_lib_client_register(%d) failed\n", -+ __func__, client->id); -+ goto err0; -+ } -+ -+ netif_info(priv, drv, ndev, "%s: registered client: %p\n", __func__, -+ client); -+ -+ pfe_gemac_init(priv); -+ -+ if (!is_valid_ether_addr(ndev->dev_addr)) { -+ netdev_err(ndev, "%s: invalid MAC address\n", __func__); -+ rc = -EADDRNOTAVAIL; -+ goto err1; -+ } -+ -+ gemac_set_laddrN(priv->EMAC_baseaddr, -+ (struct pfe_mac_addr *)ndev->dev_addr, 1); -+ -+ napi_enable(&priv->high_napi); -+ napi_enable(&priv->low_napi); -+ napi_enable(&priv->lro_napi); -+ -+ rc = pfe_eth_start(priv); -+ -+ netif_tx_wake_all_queues(ndev); -+ -+ return rc; -+ -+err1: -+ hif_lib_client_unregister(&priv->client); -+ -+err0: -+ return rc; -+} -+ -+/* -+ * pfe_eth_shutdown -+ */ -+int pfe_eth_shutdown(struct net_device *ndev, int wake) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ int i, qstatus; -+ unsigned long next_poll = jiffies + 1, end = jiffies + -+ (TX_POLL_TIMEOUT_MS * HZ) / 1000; -+ int tx_pkts, prv_tx_pkts; -+ -+ netif_info(priv, ifdown, ndev, "%s\n", __func__); -+ -+ for (i = 0; i < emac_txq_cnt; i++) -+ hrtimer_cancel(&priv->fast_tx_timeout[i].timer); -+ -+ netif_tx_stop_all_queues(ndev); -+ -+ do { -+ tx_pkts = 0; -+ pfe_eth_flush_tx(priv); -+ -+ for (i = 0; i < emac_txq_cnt; i++) -+ tx_pkts += hif_lib_tx_pending(&priv->client, i); -+ -+ if (tx_pkts) { -+ /*Don't wait forever, break if we cross max timeout */ -+ if (time_after(jiffies, end)) { -+ pr_err( -+ "(%s)Tx is not complete after %dmsec\n", -+ ndev->name, TX_POLL_TIMEOUT_MS); -+ break; -+ } -+ -+ pr_info("%s : (%s) Waiting for tx packets to free. Pending tx pkts = %d.\n" -+ , __func__, ndev->name, tx_pkts); -+ if (need_resched()) -+ schedule(); -+ } -+ -+ } while (tx_pkts); -+ -+ end = jiffies + (TX_POLL_TIMEOUT_MS * HZ) / 1000; -+ -+ prv_tx_pkts = tmu_pkts_processed(priv->id); -+ /* -+ * Wait till TMU transmits all pending packets -+ * poll tmu_qstatus and pkts processed by TMU for every 10ms -+ * Consider TMU is busy, If we see TMU qeueu pending or any packets -+ * processed by TMU -+ */ -+ while (1) { -+ if (time_after(jiffies, next_poll)) { -+ tx_pkts = tmu_pkts_processed(priv->id); -+ qstatus = tmu_qstatus(priv->id) & 0x7ffff; -+ -+ if (!qstatus && (tx_pkts == prv_tx_pkts)) -+ break; -+ /* Don't wait forever, break if we cross max -+ * timeout(TX_POLL_TIMEOUT_MS) -+ */ -+ if (time_after(jiffies, end)) { -+ pr_err("TMU%d is busy after %dmsec\n", -+ priv->id, TX_POLL_TIMEOUT_MS); -+ break; -+ } -+ prv_tx_pkts = tx_pkts; -+ next_poll++; -+ } -+ if (need_resched()) -+ schedule(); -+ } -+ /* Wait for some more time to complete transmitting packet if any */ -+ next_poll = jiffies + 1; -+ while (1) { -+ if (time_after(jiffies, next_poll)) -+ break; -+ if (need_resched()) -+ schedule(); -+ } -+ -+ pfe_eth_stop(ndev, wake); -+ -+ napi_disable(&priv->lro_napi); -+ napi_disable(&priv->low_napi); -+ napi_disable(&priv->high_napi); -+ -+ hif_lib_client_unregister(&priv->client); -+ -+ return 0; -+} -+ -+/* pfe_eth_close -+ * -+ */ -+static int pfe_eth_close(struct net_device *ndev) -+{ -+ pfe_eth_shutdown(ndev, 0); -+ -+ return 0; -+} -+ -+/* pfe_eth_suspend -+ * -+ * return value : 1 if netdevice is configured to wakeup system -+ * 0 otherwise -+ */ -+int pfe_eth_suspend(struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ int retval = 0; -+ -+ if (priv->wol) { -+ gemac_set_wol(priv->EMAC_baseaddr, priv->wol); -+ retval = 1; -+ } -+ pfe_eth_shutdown(ndev, priv->wol); -+ -+ return retval; -+} -+ -+/* pfe_eth_resume -+ * -+ */ -+int pfe_eth_resume(struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ if (priv->wol) -+ gemac_set_wol(priv->EMAC_baseaddr, 0); -+ gemac_tx_enable(priv->EMAC_baseaddr); -+ -+ return pfe_eth_open(ndev); -+} -+ -+/* pfe_eth_get_queuenum -+ */ -+static int pfe_eth_get_queuenum(struct pfe_eth_priv_s *priv, struct sk_buff -+ *skb) -+{ -+ int queuenum = 0; -+ unsigned long flags; -+ -+ /* Get the Fast Path queue number */ -+ /* -+ * Use conntrack mark (if conntrack exists), then packet mark (if any), -+ * then fallback to default -+ */ -+#if defined(CONFIG_IP_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_MARK) -+ if (skb->_nfct) { -+ enum ip_conntrack_info cinfo; -+ struct nf_conn *ct; -+ -+ ct = nf_ct_get(skb, &cinfo); -+ -+ if (ct) { -+ u32 connmark; -+ -+ connmark = ct->mark; -+ -+ if ((connmark & 0x80000000) && priv->id != 0) -+ connmark >>= 16; -+ -+ queuenum = connmark & EMAC_QUEUENUM_MASK; -+ } -+ } else {/* continued after #endif ... */ -+#endif -+ if (skb->mark) { -+ queuenum = skb->mark & EMAC_QUEUENUM_MASK; -+ } else { -+ spin_lock_irqsave(&priv->lock, flags); -+ queuenum = priv->default_priority & EMAC_QUEUENUM_MASK; -+ spin_unlock_irqrestore(&priv->lock, flags); -+ } -+#if defined(CONFIG_IP_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_MARK) -+ } -+#endif -+ return queuenum; -+} -+ -+/* pfe_eth_might_stop_tx -+ * -+ */ -+static int pfe_eth_might_stop_tx(struct pfe_eth_priv_s *priv, int queuenum, -+ struct netdev_queue *tx_queue, -+ unsigned int n_desc, -+ unsigned int n_segs) -+{ -+ ktime_t kt; -+ -+ if (unlikely((__hif_tx_avail(&pfe->hif) < n_desc) || -+ (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) || -+ (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) < n_segs))) { -+#ifdef PFE_ETH_TX_STATS -+ if (__hif_tx_avail(&pfe->hif) < n_desc) { -+ priv->stop_queue_hif[queuenum]++; -+ } else if (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) { -+ priv->stop_queue_hif_client[queuenum]++; -+ } else if (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) < -+ n_segs) { -+ priv->stop_queue_credit[queuenum]++; -+ } -+ priv->stop_queue_total[queuenum]++; -+#endif -+ netif_tx_stop_queue(tx_queue); -+ -+ kt = ktime_set(0, LS1012A_TX_FAST_RECOVERY_TIMEOUT_MS * -+ NSEC_PER_MSEC); -+ hrtimer_start(&priv->fast_tx_timeout[queuenum].timer, kt, -+ HRTIMER_MODE_REL); -+ return -1; -+ } else { -+ return 0; -+ } -+} -+ -+#define SA_MAX_OP 2 -+/* pfe_hif_send_packet -+ * -+ * At this level if TX fails we drop the packet -+ */ -+static void pfe_hif_send_packet(struct sk_buff *skb, struct pfe_eth_priv_s -+ *priv, int queuenum) -+{ -+ struct skb_shared_info *sh = skb_shinfo(skb); -+ unsigned int nr_frags; -+ u32 ctrl = 0; -+ -+ netif_info(priv, tx_queued, priv->ndev, "%s\n", __func__); -+ -+ if (skb_is_gso(skb)) { -+ priv->stats.tx_dropped++; -+ return; -+ } -+ -+ if (skb->ip_summed == CHECKSUM_PARTIAL) -+ ctrl = HIF_CTRL_TX_CHECKSUM; -+ -+ nr_frags = sh->nr_frags; -+ -+ if (nr_frags) { -+ skb_frag_t *f; -+ int i; -+ -+ __hif_lib_xmit_pkt(&priv->client, queuenum, skb->data, -+ skb_headlen(skb), ctrl, HIF_FIRST_BUFFER, -+ skb); -+ -+ for (i = 0; i < nr_frags - 1; i++) { -+ f = &sh->frags[i]; -+ __hif_lib_xmit_pkt(&priv->client, queuenum, -+ skb_frag_address(f), -+ skb_frag_size(f), -+ 0x0, 0x0, skb); -+ } -+ -+ f = &sh->frags[i]; -+ -+ __hif_lib_xmit_pkt(&priv->client, queuenum, -+ skb_frag_address(f), skb_frag_size(f), -+ 0x0, HIF_LAST_BUFFER | HIF_DATA_VALID, -+ skb); -+ -+ netif_info(priv, tx_queued, priv->ndev, -+ "%s: pkt sent successfully skb:%p nr_frags:%d len:%d\n", -+ __func__, skb, nr_frags, skb->len); -+ } else { -+ __hif_lib_xmit_pkt(&priv->client, queuenum, skb->data, -+ skb->len, ctrl, HIF_FIRST_BUFFER | -+ HIF_LAST_BUFFER | HIF_DATA_VALID, -+ skb); -+ netif_info(priv, tx_queued, priv->ndev, -+ "%s: pkt sent successfully skb:%p len:%d\n", -+ __func__, skb, skb->len); -+ } -+ hif_tx_dma_start(); -+ priv->stats.tx_packets++; -+ priv->stats.tx_bytes += skb->len; -+ hif_lib_tx_credit_use(pfe, priv->id, queuenum, 1); -+} -+ -+/* pfe_eth_flush_txQ -+ */ -+static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int -+ from_tx, int n_desc) -+{ -+ struct sk_buff *skb; -+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, -+ tx_q_num); -+ unsigned int flags; -+ -+ netif_info(priv, tx_done, priv->ndev, "%s\n", __func__); -+ -+ if (!from_tx) -+ __netif_tx_lock_bh(tx_queue); -+ -+ /* Clean HIF and client queue */ -+ while ((skb = hif_lib_tx_get_next_complete(&priv->client, -+ tx_q_num, &flags, -+ HIF_TX_DESC_NT))) { -+ if (flags & HIF_DATA_VALID) -+ dev_kfree_skb_any(skb); -+ } -+ if (!from_tx) -+ __netif_tx_unlock_bh(tx_queue); -+} -+ -+/* pfe_eth_flush_tx -+ */ -+static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv) -+{ -+ int ii; -+ -+ netif_info(priv, tx_done, priv->ndev, "%s\n", __func__); -+ -+ for (ii = 0; ii < emac_txq_cnt; ii++) -+ pfe_eth_flush_txQ(priv, ii, 0, 0); -+} -+ -+void pfe_tx_get_req_desc(struct sk_buff *skb, unsigned int *n_desc, unsigned int -+ *n_segs) -+{ -+ struct skb_shared_info *sh = skb_shinfo(skb); -+ -+ /* Scattered data */ -+ if (sh->nr_frags) { -+ *n_desc = sh->nr_frags + 1; -+ *n_segs = 1; -+ /* Regular case */ -+ } else { -+ *n_desc = 1; -+ *n_segs = 1; -+ } -+} -+ -+/* pfe_eth_send_packet -+ */ -+static int pfe_eth_send_packet(struct sk_buff *skb, struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ int tx_q_num = skb_get_queue_mapping(skb); -+ int n_desc, n_segs; -+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, -+ tx_q_num); -+ -+ netif_info(priv, tx_queued, ndev, "%s\n", __func__); -+ -+ if ((!skb_is_gso(skb)) && (skb_headroom(skb) < (PFE_PKT_HEADER_SZ + -+ sizeof(unsigned long)))) { -+ netif_warn(priv, tx_err, priv->ndev, "%s: copying skb\n", -+ __func__); -+ -+ if (pskb_expand_head(skb, (PFE_PKT_HEADER_SZ + sizeof(unsigned -+ long)), 0, GFP_ATOMIC)) { -+ /* No need to re-transmit, no way to recover*/ -+ kfree_skb(skb); -+ priv->stats.tx_dropped++; -+ return NETDEV_TX_OK; -+ } -+ } -+ -+ pfe_tx_get_req_desc(skb, &n_desc, &n_segs); -+ -+ hif_tx_lock(&pfe->hif); -+ if (unlikely(pfe_eth_might_stop_tx(priv, tx_q_num, tx_queue, n_desc, -+ n_segs))) { -+#ifdef PFE_ETH_TX_STATS -+ if (priv->was_stopped[tx_q_num]) { -+ priv->clean_fail[tx_q_num]++; -+ priv->was_stopped[tx_q_num] = 0; -+ } -+#endif -+ hif_tx_unlock(&pfe->hif); -+ return NETDEV_TX_BUSY; -+ } -+ -+ pfe_hif_send_packet(skb, priv, tx_q_num); -+ -+ hif_tx_unlock(&pfe->hif); -+ -+ tx_queue->trans_start = jiffies; -+ -+#ifdef PFE_ETH_TX_STATS -+ priv->was_stopped[tx_q_num] = 0; -+#endif -+ -+ return NETDEV_TX_OK; -+} -+ -+/* pfe_eth_select_queue -+ * -+ */ -+static u16 pfe_eth_select_queue(struct net_device *ndev, struct sk_buff *skb, -+ struct net_device *sb_dev, -+ select_queue_fallback_t fallback) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ return pfe_eth_get_queuenum(priv, skb); -+} -+ -+/* pfe_eth_get_stats -+ */ -+static struct net_device_stats *pfe_eth_get_stats(struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ netif_info(priv, drv, ndev, "%s\n", __func__); -+ -+ return &priv->stats; -+} -+ -+/* pfe_eth_set_mac_address -+ */ -+static int pfe_eth_set_mac_address(struct net_device *ndev, void *addr) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ struct sockaddr *sa = addr; -+ -+ netif_info(priv, drv, ndev, "%s\n", __func__); -+ -+ if (!is_valid_ether_addr(sa->sa_data)) -+ return -EADDRNOTAVAIL; -+ -+ memcpy(ndev->dev_addr, sa->sa_data, ETH_ALEN); -+ -+ gemac_set_laddrN(priv->EMAC_baseaddr, -+ (struct pfe_mac_addr *)ndev->dev_addr, 1); -+ -+ return 0; -+} -+ -+/* pfe_eth_enet_addr_byte_mac -+ */ -+int pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr, -+ struct pfe_mac_addr *enet_addr) -+{ -+ if (!enet_byte_addr || !enet_addr) { -+ return -1; -+ -+ } else { -+ enet_addr->bottom = enet_byte_addr[0] | -+ (enet_byte_addr[1] << 8) | -+ (enet_byte_addr[2] << 16) | -+ (enet_byte_addr[3] << 24); -+ enet_addr->top = enet_byte_addr[4] | -+ (enet_byte_addr[5] << 8); -+ return 0; -+ } -+} -+ -+/* pfe_eth_set_multi -+ */ -+static void pfe_eth_set_multi(struct net_device *ndev) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ struct pfe_mac_addr hash_addr; /* hash register structure */ -+ /* specific mac address register structure */ -+ struct pfe_mac_addr spec_addr; -+ int result; /* index into hash register to set.. */ -+ int uc_count = 0; -+ struct netdev_hw_addr *ha; -+ -+ if (ndev->flags & IFF_PROMISC) { -+ netif_info(priv, drv, ndev, "entering promiscuous mode\n"); -+ -+ priv->promisc = 1; -+ gemac_enable_copy_all(priv->EMAC_baseaddr); -+ } else { -+ priv->promisc = 0; -+ gemac_disable_copy_all(priv->EMAC_baseaddr); -+ } -+ -+ /* Enable broadcast frame reception if required. */ -+ if (ndev->flags & IFF_BROADCAST) { -+ gemac_allow_broadcast(priv->EMAC_baseaddr); -+ } else { -+ netif_info(priv, drv, ndev, -+ "disabling broadcast frame reception\n"); -+ -+ gemac_no_broadcast(priv->EMAC_baseaddr); -+ } -+ -+ if (ndev->flags & IFF_ALLMULTI) { -+ /* Set the hash to rx all multicast frames */ -+ hash_addr.bottom = 0xFFFFFFFF; -+ hash_addr.top = 0xFFFFFFFF; -+ gemac_set_hash(priv->EMAC_baseaddr, &hash_addr); -+ netdev_for_each_uc_addr(ha, ndev) { -+ if (uc_count >= MAX_UC_SPEC_ADDR_REG) -+ break; -+ pfe_eth_enet_addr_byte_mac(ha->addr, &spec_addr); -+ gemac_set_laddrN(priv->EMAC_baseaddr, &spec_addr, -+ uc_count + 2); -+ uc_count++; -+ } -+ } else if ((netdev_mc_count(ndev) > 0) || (netdev_uc_count(ndev))) { -+ u8 *addr; -+ -+ hash_addr.bottom = 0; -+ hash_addr.top = 0; -+ -+ netdev_for_each_mc_addr(ha, ndev) { -+ addr = ha->addr; -+ -+ netif_info(priv, drv, ndev, -+ "adding multicast address %X:%X:%X:%X:%X:%X to gem filter\n", -+ addr[0], addr[1], addr[2], -+ addr[3], addr[4], addr[5]); -+ -+ result = pfe_eth_get_hash(addr); -+ -+ if (result < EMAC_HASH_REG_BITS) { -+ if (result < 32) -+ hash_addr.bottom |= (1 << result); -+ else -+ hash_addr.top |= (1 << (result - 32)); -+ } else { -+ break; -+ } -+ } -+ -+ uc_count = -1; -+ netdev_for_each_uc_addr(ha, ndev) { -+ addr = ha->addr; -+ -+ if (++uc_count < MAX_UC_SPEC_ADDR_REG) { -+ netdev_info(ndev, -+ "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem filter\n", -+ addr[0], addr[1], addr[2], -+ addr[3], addr[4], addr[5]); -+ pfe_eth_enet_addr_byte_mac(addr, &spec_addr); -+ gemac_set_laddrN(priv->EMAC_baseaddr, -+ &spec_addr, uc_count + 2); -+ } else { -+ netif_info(priv, drv, ndev, -+ "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem hash\n", -+ addr[0], addr[1], addr[2], -+ addr[3], addr[4], addr[5]); -+ -+ result = pfe_eth_get_hash(addr); -+ if (result >= EMAC_HASH_REG_BITS) { -+ break; -+ -+ } else { -+ if (result < 32) -+ hash_addr.bottom |= (1 << -+ result); -+ else -+ hash_addr.top |= (1 << -+ (result - 32)); -+ } -+ } -+ } -+ -+ gemac_set_hash(priv->EMAC_baseaddr, &hash_addr); -+ } -+ -+ if (!(netdev_uc_count(ndev) >= MAX_UC_SPEC_ADDR_REG)) { -+ /* -+ * Check if there are any specific address HW registers that -+ * need to be flushed -+ */ -+ for (uc_count = netdev_uc_count(ndev); uc_count < -+ MAX_UC_SPEC_ADDR_REG; uc_count++) -+ gemac_clear_laddrN(priv->EMAC_baseaddr, uc_count + 2); -+ } -+ -+ if (ndev->flags & IFF_LOOPBACK) -+ gemac_set_loop(priv->EMAC_baseaddr, LB_LOCAL); -+} -+ -+/* pfe_eth_set_features -+ */ -+static int pfe_eth_set_features(struct net_device *ndev, netdev_features_t -+ features) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ int rc = 0; -+ -+ if (features & NETIF_F_RXCSUM) -+ gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr); -+ else -+ gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr); -+ return rc; -+} -+ -+/* pfe_eth_fast_tx_timeout -+ */ -+static enum hrtimer_restart pfe_eth_fast_tx_timeout(struct hrtimer *timer) -+{ -+ struct pfe_eth_fast_timer *fast_tx_timeout = container_of(timer, struct -+ pfe_eth_fast_timer, -+ timer); -+ struct pfe_eth_priv_s *priv = container_of(fast_tx_timeout->base, -+ struct pfe_eth_priv_s, -+ fast_tx_timeout); -+ struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev, -+ fast_tx_timeout->queuenum); -+ -+ if (netif_tx_queue_stopped(tx_queue)) { -+#ifdef PFE_ETH_TX_STATS -+ priv->was_stopped[fast_tx_timeout->queuenum] = 1; -+#endif -+ netif_tx_wake_queue(tx_queue); -+ } -+ -+ return HRTIMER_NORESTART; -+} -+ -+/* pfe_eth_fast_tx_timeout_init -+ */ -+static void pfe_eth_fast_tx_timeout_init(struct pfe_eth_priv_s *priv) -+{ -+ int i; -+ -+ for (i = 0; i < emac_txq_cnt; i++) { -+ priv->fast_tx_timeout[i].queuenum = i; -+ hrtimer_init(&priv->fast_tx_timeout[i].timer, CLOCK_MONOTONIC, -+ HRTIMER_MODE_REL); -+ priv->fast_tx_timeout[i].timer.function = -+ pfe_eth_fast_tx_timeout; -+ priv->fast_tx_timeout[i].base = priv->fast_tx_timeout; -+ } -+} -+ -+static struct sk_buff *pfe_eth_rx_skb(struct net_device *ndev, -+ struct pfe_eth_priv_s *priv, -+ unsigned int qno) -+{ -+ void *buf_addr; -+ unsigned int rx_ctrl; -+ unsigned int desc_ctrl = 0; -+ struct hif_ipsec_hdr *ipsec_hdr = NULL; -+ struct sk_buff *skb; -+ struct sk_buff *skb_frag, *skb_frag_last = NULL; -+ int length = 0, offset; -+ -+ skb = priv->skb_inflight[qno]; -+ -+ if (skb) { -+ skb_frag_last = skb_shinfo(skb)->frag_list; -+ if (skb_frag_last) { -+ while (skb_frag_last->next) -+ skb_frag_last = skb_frag_last->next; -+ } -+ } -+ -+ while (!(desc_ctrl & CL_DESC_LAST)) { -+ buf_addr = hif_lib_receive_pkt(&priv->client, qno, &length, -+ &offset, &rx_ctrl, &desc_ctrl, -+ (void **)&ipsec_hdr); -+ if (!buf_addr) -+ goto incomplete; -+ -+#ifdef PFE_ETH_NAPI_STATS -+ priv->napi_counters[NAPI_DESC_COUNT]++; -+#endif -+ -+ /* First frag */ -+ if (desc_ctrl & CL_DESC_FIRST) { -+ skb = build_skb(buf_addr, 0); -+ if (unlikely(!skb)) -+ goto pkt_drop; -+ -+ skb_reserve(skb, offset); -+ skb_put(skb, length); -+ skb->dev = ndev; -+ -+ if ((ndev->features & NETIF_F_RXCSUM) && (rx_ctrl & -+ HIF_CTRL_RX_CHECKSUMMED)) -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ else -+ skb_checksum_none_assert(skb); -+ -+ } else { -+ /* Next frags */ -+ if (unlikely(!skb)) { -+ pr_err("%s: NULL skb_inflight\n", -+ __func__); -+ goto pkt_drop; -+ } -+ -+ skb_frag = build_skb(buf_addr, 0); -+ -+ if (unlikely(!skb_frag)) { -+ kfree(buf_addr); -+ goto pkt_drop; -+ } -+ -+ skb_reserve(skb_frag, offset); -+ skb_put(skb_frag, length); -+ -+ skb_frag->dev = ndev; -+ -+ if (skb_shinfo(skb)->frag_list) -+ skb_frag_last->next = skb_frag; -+ else -+ skb_shinfo(skb)->frag_list = skb_frag; -+ -+ skb->truesize += skb_frag->truesize; -+ skb->data_len += length; -+ skb->len += length; -+ skb_frag_last = skb_frag; -+ } -+ } -+ -+ priv->skb_inflight[qno] = NULL; -+ return skb; -+ -+incomplete: -+ priv->skb_inflight[qno] = skb; -+ return NULL; -+ -+pkt_drop: -+ priv->skb_inflight[qno] = NULL; -+ -+ if (skb) -+ kfree_skb(skb); -+ else -+ kfree(buf_addr); -+ -+ priv->stats.rx_errors++; -+ -+ return NULL; -+} -+ -+/* pfe_eth_poll -+ */ -+static int pfe_eth_poll(struct pfe_eth_priv_s *priv, struct napi_struct *napi, -+ unsigned int qno, int budget) -+{ -+ struct net_device *ndev = priv->ndev; -+ struct sk_buff *skb; -+ int work_done = 0; -+ unsigned int len; -+ -+ netif_info(priv, intr, priv->ndev, "%s\n", __func__); -+ -+#ifdef PFE_ETH_NAPI_STATS -+ priv->napi_counters[NAPI_POLL_COUNT]++; -+#endif -+ -+ do { -+ skb = pfe_eth_rx_skb(ndev, priv, qno); -+ -+ if (!skb) -+ break; -+ -+ len = skb->len; -+ -+ /* Packet will be processed */ -+ skb->protocol = eth_type_trans(skb, ndev); -+ -+ netif_receive_skb(skb); -+ -+ priv->stats.rx_packets++; -+ priv->stats.rx_bytes += len; -+ -+ work_done++; -+ -+#ifdef PFE_ETH_NAPI_STATS -+ priv->napi_counters[NAPI_PACKET_COUNT]++; -+#endif -+ -+ } while (work_done < budget); -+ -+ /* -+ * If no Rx receive nor cleanup work was done, exit polling mode. -+ * No more netif_running(dev) check is required here , as this is -+ * checked in net/core/dev.c (2.6.33.5 kernel specific). -+ */ -+ if (work_done < budget) { -+ napi_complete(napi); -+ -+ hif_lib_event_handler_start(&priv->client, EVENT_RX_PKT_IND, -+ qno); -+ } -+#ifdef PFE_ETH_NAPI_STATS -+ else -+ priv->napi_counters[NAPI_FULL_BUDGET_COUNT]++; -+#endif -+ -+ return work_done; -+} -+ -+/* -+ * pfe_eth_lro_poll -+ */ -+static int pfe_eth_lro_poll(struct napi_struct *napi, int budget) -+{ -+ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s, -+ lro_napi); -+ -+ netif_info(priv, intr, priv->ndev, "%s\n", __func__); -+ -+ return pfe_eth_poll(priv, napi, 2, budget); -+} -+ -+/* pfe_eth_low_poll -+ */ -+static int pfe_eth_low_poll(struct napi_struct *napi, int budget) -+{ -+ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s, -+ low_napi); -+ -+ netif_info(priv, intr, priv->ndev, "%s\n", __func__); -+ -+ return pfe_eth_poll(priv, napi, 1, budget); -+} -+ -+/* pfe_eth_high_poll -+ */ -+static int pfe_eth_high_poll(struct napi_struct *napi, int budget) -+{ -+ struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s, -+ high_napi); -+ -+ netif_info(priv, intr, priv->ndev, "%s\n", __func__); -+ -+ return pfe_eth_poll(priv, napi, 0, budget); -+} -+ -+static const struct net_device_ops pfe_netdev_ops = { -+ .ndo_open = pfe_eth_open, -+ .ndo_stop = pfe_eth_close, -+ .ndo_start_xmit = pfe_eth_send_packet, -+ .ndo_select_queue = pfe_eth_select_queue, -+ .ndo_get_stats = pfe_eth_get_stats, -+ .ndo_set_mac_address = pfe_eth_set_mac_address, -+ .ndo_set_rx_mode = pfe_eth_set_multi, -+ .ndo_set_features = pfe_eth_set_features, -+ .ndo_validate_addr = eth_validate_addr, -+}; -+ -+/* pfe_eth_init_one -+ */ -+static int pfe_eth_init_one(struct pfe *pfe, int id) -+{ -+ struct net_device *ndev = NULL; -+ struct pfe_eth_priv_s *priv = NULL; -+ struct ls1012a_eth_platform_data *einfo; -+ struct ls1012a_mdio_platform_data *minfo; -+ struct ls1012a_pfe_platform_data *pfe_info; -+ int err; -+ -+ /* Extract pltform data */ -+ pfe_info = (struct ls1012a_pfe_platform_data *) -+ pfe->dev->platform_data; -+ if (!pfe_info) { -+ pr_err( -+ "%s: pfe missing additional platform data\n" -+ , __func__); -+ err = -ENODEV; -+ goto err0; -+ } -+ -+ einfo = (struct ls1012a_eth_platform_data *) -+ pfe_info->ls1012a_eth_pdata; -+ -+ /* einfo never be NULL, but no harm in having this check */ -+ if (!einfo) { -+ pr_err( -+ "%s: pfe missing additional gemacs platform data\n" -+ , __func__); -+ err = -ENODEV; -+ goto err0; -+ } -+ -+ minfo = (struct ls1012a_mdio_platform_data *) -+ pfe_info->ls1012a_mdio_pdata; -+ -+ /* einfo never be NULL, but no harm in having this check */ -+ if (!minfo) { -+ pr_err( -+ "%s: pfe missing additional mdios platform data\n", -+ __func__); -+ err = -ENODEV; -+ goto err0; -+ } -+ -+ /* Create an ethernet device instance */ -+ ndev = alloc_etherdev_mq(sizeof(*priv), emac_txq_cnt); -+ -+ if (!ndev) { -+ pr_err("%s: gemac %d device allocation failed\n", -+ __func__, einfo[id].gem_id); -+ err = -ENOMEM; -+ goto err0; -+ } -+ -+ priv = netdev_priv(ndev); -+ priv->ndev = ndev; -+ priv->id = einfo[id].gem_id; -+ priv->pfe = pfe; -+ -+ SET_NETDEV_DEV(priv->ndev, priv->pfe->dev); -+ -+ pfe->eth.eth_priv[id] = priv; -+ -+ /* Set the info in the priv to the current info */ -+ priv->einfo = &einfo[id]; -+ priv->EMAC_baseaddr = cbus_emac_base[id]; -+ priv->PHY_baseaddr = cbus_emac_base[0]; -+ priv->GPI_baseaddr = cbus_gpi_base[id]; -+ -+#define HIF_GEMAC_TMUQ_BASE 6 -+ priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2); -+ priv->high_tmu_q = priv->low_tmu_q + 1; -+ -+ spin_lock_init(&priv->lock); -+ -+ pfe_eth_fast_tx_timeout_init(priv); -+ -+ /* Copy the station address into the dev structure, */ -+ memcpy(ndev->dev_addr, einfo[id].mac_addr, ETH_ALEN); -+ -+ /* Initialize mdio */ -+ if (minfo[id].enabled) { -+ err = pfe_eth_mdio_init(priv, &minfo[id]); -+ if (err) { -+ netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n", -+ __func__); -+ goto err2; -+ } -+ } -+ -+ ndev->mtu = 1500; -+ -+ /* Set MTU limits */ -+ ndev->min_mtu = ETH_MIN_MTU; -+ ndev->max_mtu = JUMBO_FRAME_SIZE; -+ -+ /* supported features */ -+ ndev->hw_features = NETIF_F_SG; -+ -+ /*Enable after checksum offload is validated */ -+ ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | -+ NETIF_F_IPV6_CSUM | NETIF_F_SG; -+ -+ /* enabled by default */ -+ ndev->features = ndev->hw_features; -+ -+ priv->usr_features = ndev->features; -+ -+ ndev->netdev_ops = &pfe_netdev_ops; -+ -+ ndev->ethtool_ops = &pfe_ethtool_ops; -+ -+ /* Enable basic messages by default */ -+ priv->msg_enable = NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_LINK | -+ NETIF_MSG_PROBE; -+ -+ netif_napi_add(ndev, &priv->low_napi, pfe_eth_low_poll, -+ HIF_RX_POLL_WEIGHT - 16); -+ netif_napi_add(ndev, &priv->high_napi, pfe_eth_high_poll, -+ HIF_RX_POLL_WEIGHT - 16); -+ netif_napi_add(ndev, &priv->lro_napi, pfe_eth_lro_poll, -+ HIF_RX_POLL_WEIGHT - 16); -+ -+ err = register_netdev(ndev); -+ -+ if (err) { -+ netdev_err(ndev, "register_netdev() failed\n"); -+ goto err3; -+ } -+ device_init_wakeup(&ndev->dev, WAKE_MAGIC); -+ -+ if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) { -+ err = pfe_phy_init(ndev); -+ if (err) { -+ netdev_err(ndev, "%s: pfe_phy_init() failed\n", -+ __func__); -+ goto err4; -+ } -+ } -+ -+ netif_carrier_on(ndev); -+ -+ /* Create all the sysfs files */ -+ if (pfe_eth_sysfs_init(ndev)) -+ goto err4; -+ -+ netif_info(priv, probe, ndev, "%s: created interface, baseaddr: %p\n", -+ __func__, priv->EMAC_baseaddr); -+ -+ return 0; -+err4: -+ unregister_netdev(ndev); -+err3: -+ pfe_eth_mdio_exit(priv->mii_bus); -+err2: -+ free_netdev(priv->ndev); -+err0: -+ return err; -+} -+ -+/* pfe_eth_init -+ */ -+int pfe_eth_init(struct pfe *pfe) -+{ -+ int ii = 0; -+ int err; -+ -+ pr_info("%s\n", __func__); -+ -+ cbus_emac_base[0] = EMAC1_BASE_ADDR; -+ cbus_emac_base[1] = EMAC2_BASE_ADDR; -+ -+ cbus_gpi_base[0] = EGPI1_BASE_ADDR; -+ cbus_gpi_base[1] = EGPI2_BASE_ADDR; -+ -+ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) { -+ err = pfe_eth_init_one(pfe, ii); -+ if (err) -+ goto err0; -+ } -+ -+ return 0; -+ -+err0: -+ while (ii--) -+ pfe_eth_exit_one(pfe->eth.eth_priv[ii]); -+ -+ /* Register three network devices in the kernel */ -+ return err; -+} -+ -+/* pfe_eth_exit_one -+ */ -+static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv) -+{ -+ netif_info(priv, probe, priv->ndev, "%s\n", __func__); -+ -+ pfe_eth_sysfs_exit(priv->ndev); -+ -+ unregister_netdev(priv->ndev); -+ -+ if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) -+ pfe_phy_exit(priv->ndev); -+ -+ if (priv->mii_bus) -+ pfe_eth_mdio_exit(priv->mii_bus); -+ -+ free_netdev(priv->ndev); -+} -+ -+/* pfe_eth_exit -+ */ -+void pfe_eth_exit(struct pfe *pfe) -+{ -+ int ii; -+ -+ pr_info("%s\n", __func__); -+ -+ for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--) -+ pfe_eth_exit_one(pfe->eth.eth_priv[ii]); -+} ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_firmware.c -@@ -0,0 +1,314 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* -+ * @file -+ * Contains all the functions to handle parsing and loading of PE firmware -+ * files. -+ */ -+#include -+ -+#include "pfe_mod.h" -+#include "pfe_firmware.h" -+#include "pfe/pfe.h" -+ -+static struct elf32_shdr *get_elf_section_header(const struct firmware *fw, -+ const char *section) -+{ -+ struct elf32_hdr *elf_hdr = (struct elf32_hdr *)fw->data; -+ struct elf32_shdr *shdr; -+ struct elf32_shdr *shdr_shstr; -+ Elf32_Off e_shoff = be32_to_cpu(elf_hdr->e_shoff); -+ Elf32_Half e_shentsize = be16_to_cpu(elf_hdr->e_shentsize); -+ Elf32_Half e_shnum = be16_to_cpu(elf_hdr->e_shnum); -+ Elf32_Half e_shstrndx = be16_to_cpu(elf_hdr->e_shstrndx); -+ Elf32_Off shstr_offset; -+ Elf32_Word sh_name; -+ const char *name; -+ int i; -+ -+ /* Section header strings */ -+ shdr_shstr = (struct elf32_shdr *)(fw->data + e_shoff + e_shstrndx * -+ e_shentsize); -+ shstr_offset = be32_to_cpu(shdr_shstr->sh_offset); -+ -+ for (i = 0; i < e_shnum; i++) { -+ shdr = (struct elf32_shdr *)(fw->data + e_shoff -+ + i * e_shentsize); -+ -+ sh_name = be32_to_cpu(shdr->sh_name); -+ -+ name = (const char *)(fw->data + shstr_offset + sh_name); -+ -+ if (!strcmp(name, section)) -+ return shdr; -+ } -+ -+ pr_err("%s: didn't find section %s\n", __func__, section); -+ -+ return NULL; -+} -+ -+#if defined(CFG_DIAGS) -+static int pfe_get_diags_info(const struct firmware *fw, struct pfe_diags_info -+ *diags_info) -+{ -+ struct elf32_shdr *shdr; -+ unsigned long offset, size; -+ -+ shdr = get_elf_section_header(fw, ".pfe_diags_str"); -+ if (shdr) { -+ offset = be32_to_cpu(shdr->sh_offset); -+ size = be32_to_cpu(shdr->sh_size); -+ diags_info->diags_str_base = be32_to_cpu(shdr->sh_addr); -+ diags_info->diags_str_size = size; -+ diags_info->diags_str_array = kmalloc(size, GFP_KERNEL); -+ memcpy(diags_info->diags_str_array, fw->data + offset, size); -+ -+ return 0; -+ } else { -+ return -1; -+ } -+} -+#endif -+ -+static void pfe_check_version_info(const struct firmware *fw) -+{ -+ /*static char *version = NULL;*/ -+ static char *version; -+ -+ struct elf32_shdr *shdr = get_elf_section_header(fw, ".version"); -+ -+ if (shdr) { -+ if (!version) { -+ /* -+ * this is the first fw we load, use its version -+ * string as reference (whatever it is) -+ */ -+ version = (char *)(fw->data + -+ be32_to_cpu(shdr->sh_offset)); -+ -+ pr_info("PFE binary version: %s\n", version); -+ } else { -+ /* -+ * already have loaded at least one firmware, check -+ * sequence can start now -+ */ -+ if (strcmp(version, (char *)(fw->data + -+ be32_to_cpu(shdr->sh_offset)))) { -+ pr_info( -+ "WARNING: PFE firmware binaries from incompatible version\n"); -+ } -+ } -+ } else { -+ /* -+ * version cannot be verified, a potential issue that should -+ * be reported -+ */ -+ pr_info( -+ "WARNING: PFE firmware binaries from incompatible version\n"); -+ } -+} -+ -+/* PFE elf firmware loader. -+ * Loads an elf firmware image into a list of PE's (specified using a bitmask) -+ * -+ * @param pe_mask Mask of PE id's to load firmware to -+ * @param fw Pointer to the firmware image -+ * -+ * @return 0 on success, a negative value on error -+ * -+ */ -+int pfe_load_elf(int pe_mask, const struct firmware *fw, struct pfe *pfe) -+{ -+ struct elf32_hdr *elf_hdr = (struct elf32_hdr *)fw->data; -+ Elf32_Half sections = be16_to_cpu(elf_hdr->e_shnum); -+ struct elf32_shdr *shdr = (struct elf32_shdr *)(fw->data + -+ be32_to_cpu(elf_hdr->e_shoff)); -+ int id, section; -+ int rc; -+ -+ pr_info("%s\n", __func__); -+ -+ /* Some sanity checks */ -+ if (strncmp(&elf_hdr->e_ident[EI_MAG0], ELFMAG, SELFMAG)) { -+ pr_err("%s: incorrect elf magic number\n", __func__); -+ return -EINVAL; -+ } -+ -+ if (elf_hdr->e_ident[EI_CLASS] != ELFCLASS32) { -+ pr_err("%s: incorrect elf class(%x)\n", __func__, -+ elf_hdr->e_ident[EI_CLASS]); -+ return -EINVAL; -+ } -+ -+ if (elf_hdr->e_ident[EI_DATA] != ELFDATA2MSB) { -+ pr_err("%s: incorrect elf data(%x)\n", __func__, -+ elf_hdr->e_ident[EI_DATA]); -+ return -EINVAL; -+ } -+ -+ if (be16_to_cpu(elf_hdr->e_type) != ET_EXEC) { -+ pr_err("%s: incorrect elf file type(%x)\n", __func__, -+ be16_to_cpu(elf_hdr->e_type)); -+ return -EINVAL; -+ } -+ -+ for (section = 0; section < sections; section++, shdr++) { -+ if (!(be32_to_cpu(shdr->sh_flags) & (SHF_WRITE | SHF_ALLOC | -+ SHF_EXECINSTR))) -+ continue; -+ -+ for (id = 0; id < MAX_PE; id++) -+ if (pe_mask & (1 << id)) { -+ rc = pe_load_elf_section(id, fw->data, shdr, -+ pfe->dev); -+ if (rc < 0) -+ goto err; -+ } -+ } -+ -+ pfe_check_version_info(fw); -+ -+ return 0; -+ -+err: -+ return rc; -+} -+ -+/* PFE firmware initialization. -+ * Loads different firmware files from filesystem. -+ * Initializes PE IMEM/DMEM and UTIL-PE DDR -+ * Initializes control path symbol addresses (by looking them up in the elf -+ * firmware files -+ * Takes PE's out of reset -+ * -+ * @return 0 on success, a negative value on error -+ * -+ */ -+int pfe_firmware_init(struct pfe *pfe) -+{ -+ const struct firmware *class_fw, *tmu_fw; -+ int rc = 0; -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ const char *util_fw_name; -+ const struct firmware *util_fw; -+#endif -+ -+ pr_info("%s\n", __func__); -+ -+ if (request_firmware(&class_fw, CLASS_FIRMWARE_FILENAME, pfe->dev)) { -+ pr_err("%s: request firmware %s failed\n", __func__, -+ CLASS_FIRMWARE_FILENAME); -+ rc = -ETIMEDOUT; -+ goto err0; -+ } -+ -+ if (request_firmware(&tmu_fw, TMU_FIRMWARE_FILENAME, pfe->dev)) { -+ pr_err("%s: request firmware %s failed\n", __func__, -+ TMU_FIRMWARE_FILENAME); -+ rc = -ETIMEDOUT; -+ goto err1; -+} -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ util_fw_name = UTIL_FIRMWARE_FILENAME; -+ -+ if (request_firmware(&util_fw, util_fw_name, pfe->dev)) { -+ pr_err("%s: request firmware %s failed\n", __func__, -+ util_fw_name); -+ rc = -ETIMEDOUT; -+ goto err2; -+ } -+#endif -+ rc = pfe_load_elf(CLASS_MASK, class_fw, pfe); -+ if (rc < 0) { -+ pr_err("%s: class firmware load failed\n", __func__); -+ goto err3; -+ } -+ -+#if defined(CFG_DIAGS) -+ rc = pfe_get_diags_info(class_fw, &pfe->diags.class_diags_info); -+ if (rc < 0) { -+ pr_warn( -+ "PFE diags won't be available for class PEs\n"); -+ rc = 0; -+ } -+#endif -+ -+ rc = pfe_load_elf(TMU_MASK, tmu_fw, pfe); -+ if (rc < 0) { -+ pr_err("%s: tmu firmware load failed\n", __func__); -+ goto err3; -+ } -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ rc = pfe_load_elf(UTIL_MASK, util_fw, pfe); -+ if (rc < 0) { -+ pr_err("%s: util firmware load failed\n", __func__); -+ goto err3; -+ } -+ -+#if defined(CFG_DIAGS) -+ rc = pfe_get_diags_info(util_fw, &pfe->diags.util_diags_info); -+ if (rc < 0) { -+ pr_warn( -+ "PFE diags won't be available for util PE\n"); -+ rc = 0; -+ } -+#endif -+ -+ util_enable(); -+#endif -+ -+ tmu_enable(0xf); -+ class_enable(); -+ -+err3: -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ release_firmware(util_fw); -+ -+err2: -+#endif -+ release_firmware(tmu_fw); -+ -+err1: -+ release_firmware(class_fw); -+ -+err0: -+ return rc; -+} -+ -+/* PFE firmware cleanup -+ * Puts PE's in reset -+ * -+ * -+ */ -+void pfe_firmware_exit(struct pfe *pfe) -+{ -+ pr_info("%s\n", __func__); -+ -+ if (pe_reset_all(&pfe->ctrl) != 0) -+ pr_err("Error: Failed to stop PEs, PFE reload may not work correctly\n"); -+ -+ class_disable(); -+ tmu_disable(0xf); -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ util_disable(); -+#endif -+} ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_hal.c -@@ -0,0 +1,1516 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include "pfe_mod.h" -+#include "pfe/pfe.h" -+ -+void *cbus_base_addr; -+void *ddr_base_addr; -+unsigned long ddr_phys_base_addr; -+unsigned int ddr_size; -+ -+static struct pe_info pe[MAX_PE]; -+ -+/* Initializes the PFE library. -+ * Must be called before using any of the library functions. -+ * -+ * @param[in] cbus_base CBUS virtual base address (as mapped in -+ * the host CPU address space) -+ * @param[in] ddr_base PFE DDR range virtual base address (as -+ * mapped in the host CPU address space) -+ * @param[in] ddr_phys_base PFE DDR range physical base address (as -+ * mapped in platform) -+ * @param[in] size PFE DDR range size (as defined by the host -+ * software) -+ */ -+void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base, -+ unsigned int size) -+{ -+ cbus_base_addr = cbus_base; -+ ddr_base_addr = ddr_base; -+ ddr_phys_base_addr = ddr_phys_base; -+ ddr_size = size; -+ -+ pe[CLASS0_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(0); -+ pe[CLASS0_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(0); -+ pe[CLASS0_ID].pmem_size = CLASS_IMEM_SIZE; -+ pe[CLASS0_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; -+ pe[CLASS0_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; -+ pe[CLASS0_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; -+ -+ pe[CLASS1_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(1); -+ pe[CLASS1_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(1); -+ pe[CLASS1_ID].pmem_size = CLASS_IMEM_SIZE; -+ pe[CLASS1_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; -+ pe[CLASS1_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; -+ pe[CLASS1_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; -+ -+ pe[CLASS2_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(2); -+ pe[CLASS2_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(2); -+ pe[CLASS2_ID].pmem_size = CLASS_IMEM_SIZE; -+ pe[CLASS2_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; -+ pe[CLASS2_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; -+ pe[CLASS2_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; -+ -+ pe[CLASS3_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(3); -+ pe[CLASS3_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(3); -+ pe[CLASS3_ID].pmem_size = CLASS_IMEM_SIZE; -+ pe[CLASS3_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; -+ pe[CLASS3_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; -+ pe[CLASS3_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; -+ -+ pe[CLASS4_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(4); -+ pe[CLASS4_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(4); -+ pe[CLASS4_ID].pmem_size = CLASS_IMEM_SIZE; -+ pe[CLASS4_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; -+ pe[CLASS4_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; -+ pe[CLASS4_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; -+ -+ pe[CLASS5_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(5); -+ pe[CLASS5_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(5); -+ pe[CLASS5_ID].pmem_size = CLASS_IMEM_SIZE; -+ pe[CLASS5_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA; -+ pe[CLASS5_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR; -+ pe[CLASS5_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA; -+ -+ pe[TMU0_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(0); -+ pe[TMU0_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(0); -+ pe[TMU0_ID].pmem_size = TMU_IMEM_SIZE; -+ pe[TMU0_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA; -+ pe[TMU0_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR; -+ pe[TMU0_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA; -+ -+ pe[TMU1_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(1); -+ pe[TMU1_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(1); -+ pe[TMU1_ID].pmem_size = TMU_IMEM_SIZE; -+ pe[TMU1_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA; -+ pe[TMU1_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR; -+ pe[TMU1_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA; -+ -+ pe[TMU3_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(3); -+ pe[TMU3_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(3); -+ pe[TMU3_ID].pmem_size = TMU_IMEM_SIZE; -+ pe[TMU3_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA; -+ pe[TMU3_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR; -+ pe[TMU3_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA; -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ pe[UTIL_ID].dmem_base_addr = UTIL_DMEM_BASE_ADDR; -+ pe[UTIL_ID].mem_access_wdata = UTIL_MEM_ACCESS_WDATA; -+ pe[UTIL_ID].mem_access_addr = UTIL_MEM_ACCESS_ADDR; -+ pe[UTIL_ID].mem_access_rdata = UTIL_MEM_ACCESS_RDATA; -+#endif -+} -+ -+/* Writes a buffer to PE internal memory from the host -+ * through indirect access registers. -+ * -+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, -+ * ..., UTIL_ID) -+ * @param[in] src Buffer source address -+ * @param[in] mem_access_addr DMEM destination address (must be 32bit -+ * aligned) -+ * @param[in] len Number of bytes to copy -+ */ -+void pe_mem_memcpy_to32(int id, u32 mem_access_addr, const void *src, unsigned -+int len) -+{ -+ u32 offset = 0, val, addr; -+ unsigned int len32 = len >> 2; -+ int i; -+ -+ addr = mem_access_addr | PE_MEM_ACCESS_WRITE | -+ PE_MEM_ACCESS_BYTE_ENABLE(0, 4); -+ -+ for (i = 0; i < len32; i++, offset += 4, src += 4) { -+ val = *(u32 *)src; -+ writel(cpu_to_be32(val), pe[id].mem_access_wdata); -+ writel(addr + offset, pe[id].mem_access_addr); -+ } -+ -+ len = (len & 0x3); -+ if (len) { -+ val = 0; -+ -+ addr = (mem_access_addr | PE_MEM_ACCESS_WRITE | -+ PE_MEM_ACCESS_BYTE_ENABLE(0, len)) + offset; -+ -+ for (i = 0; i < len; i++, src++) -+ val |= (*(u8 *)src) << (8 * i); -+ -+ writel(cpu_to_be32(val), pe[id].mem_access_wdata); -+ writel(addr, pe[id].mem_access_addr); -+ } -+} -+ -+/* Writes a buffer to PE internal data memory (DMEM) from the host -+ * through indirect access registers. -+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, -+ * ..., UTIL_ID) -+ * @param[in] src Buffer source address -+ * @param[in] dst DMEM destination address (must be 32bit -+ * aligned) -+ * @param[in] len Number of bytes to copy -+ */ -+void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len) -+{ -+ pe_mem_memcpy_to32(id, pe[id].dmem_base_addr | dst | -+ PE_MEM_ACCESS_DMEM, src, len); -+} -+ -+/* Writes a buffer to PE internal program memory (PMEM) from the host -+ * through indirect access registers. -+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, -+ * ..., TMU3_ID) -+ * @param[in] src Buffer source address -+ * @param[in] dst PMEM destination address (must be 32bit -+ * aligned) -+ * @param[in] len Number of bytes to copy -+ */ -+void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len) -+{ -+ pe_mem_memcpy_to32(id, pe[id].pmem_base_addr | (dst & (pe[id].pmem_size -+ - 1)) | PE_MEM_ACCESS_IMEM, src, len); -+} -+ -+/* Reads PE internal program memory (IMEM) from the host -+ * through indirect access registers. -+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, -+ * ..., TMU3_ID) -+ * @param[in] addr PMEM read address (must be aligned on size) -+ * @param[in] size Number of bytes to read (maximum 4, must not -+ * cross 32bit boundaries) -+ * @return the data read (in PE endianness, i.e BE). -+ */ -+u32 pe_pmem_read(int id, u32 addr, u8 size) -+{ -+ u32 offset = addr & 0x3; -+ u32 mask = 0xffffffff >> ((4 - size) << 3); -+ u32 val; -+ -+ addr = pe[id].pmem_base_addr | ((addr & ~0x3) & (pe[id].pmem_size - 1)) -+ | PE_MEM_ACCESS_IMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size); -+ -+ writel(addr, pe[id].mem_access_addr); -+ val = be32_to_cpu(readl(pe[id].mem_access_rdata)); -+ -+ return (val >> (offset << 3)) & mask; -+} -+ -+/* Writes PE internal data memory (DMEM) from the host -+ * through indirect access registers. -+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, -+ * ..., UTIL_ID) -+ * @param[in] addr DMEM write address (must be aligned on size) -+ * @param[in] val Value to write (in PE endianness, i.e BE) -+ * @param[in] size Number of bytes to write (maximum 4, must not -+ * cross 32bit boundaries) -+ */ -+void pe_dmem_write(int id, u32 val, u32 addr, u8 size) -+{ -+ u32 offset = addr & 0x3; -+ -+ addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_WRITE | -+ PE_MEM_ACCESS_DMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size); -+ -+ /* Indirect access interface is byte swapping data being written */ -+ writel(cpu_to_be32(val << (offset << 3)), pe[id].mem_access_wdata); -+ writel(addr, pe[id].mem_access_addr); -+} -+ -+/* Reads PE internal data memory (DMEM) from the host -+ * through indirect access registers. -+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, -+ * ..., UTIL_ID) -+ * @param[in] addr DMEM read address (must be aligned on size) -+ * @param[in] size Number of bytes to read (maximum 4, must not -+ * cross 32bit boundaries) -+ * @return the data read (in PE endianness, i.e BE). -+ */ -+u32 pe_dmem_read(int id, u32 addr, u8 size) -+{ -+ u32 offset = addr & 0x3; -+ u32 mask = 0xffffffff >> ((4 - size) << 3); -+ u32 val; -+ -+ addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_DMEM | -+ PE_MEM_ACCESS_BYTE_ENABLE(offset, size); -+ -+ writel(addr, pe[id].mem_access_addr); -+ -+ /* Indirect access interface is byte swapping data being read */ -+ val = be32_to_cpu(readl(pe[id].mem_access_rdata)); -+ -+ return (val >> (offset << 3)) & mask; -+} -+ -+/* This function is used to write to CLASS internal bus peripherals (ccu, -+ * pe-lem) from the host -+ * through indirect access registers. -+ * @param[in] val value to write -+ * @param[in] addr Address to write to (must be aligned on size) -+ * @param[in] size Number of bytes to write (1, 2 or 4) -+ * -+ */ -+void class_bus_write(u32 val, u32 addr, u8 size) -+{ -+ u32 offset = addr & 0x3; -+ -+ writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE); -+ -+ addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | PE_MEM_ACCESS_WRITE | -+ (size << 24); -+ -+ writel(cpu_to_be32(val << (offset << 3)), CLASS_BUS_ACCESS_WDATA); -+ writel(addr, CLASS_BUS_ACCESS_ADDR); -+} -+ -+/* Reads from CLASS internal bus peripherals (ccu, pe-lem) from the host -+ * through indirect access registers. -+ * @param[in] addr Address to read from (must be aligned on size) -+ * @param[in] size Number of bytes to read (1, 2 or 4) -+ * @return the read data -+ * -+ */ -+u32 class_bus_read(u32 addr, u8 size) -+{ -+ u32 offset = addr & 0x3; -+ u32 mask = 0xffffffff >> ((4 - size) << 3); -+ u32 val; -+ -+ writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE); -+ -+ addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | (size << 24); -+ -+ writel(addr, CLASS_BUS_ACCESS_ADDR); -+ val = be32_to_cpu(readl(CLASS_BUS_ACCESS_RDATA)); -+ -+ return (val >> (offset << 3)) & mask; -+} -+ -+/* Writes data to the cluster memory (PE_LMEM) -+ * @param[in] dst PE LMEM destination address (must be 32bit aligned) -+ * @param[in] src Buffer source address -+ * @param[in] len Number of bytes to copy -+ */ -+void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len) -+{ -+ u32 len32 = len >> 2; -+ int i; -+ -+ for (i = 0; i < len32; i++, src += 4, dst += 4) -+ class_bus_write(*(u32 *)src, dst, 4); -+ -+ if (len & 0x2) { -+ class_bus_write(*(u16 *)src, dst, 2); -+ src += 2; -+ dst += 2; -+ } -+ -+ if (len & 0x1) { -+ class_bus_write(*(u8 *)src, dst, 1); -+ src++; -+ dst++; -+ } -+} -+ -+/* Writes value to the cluster memory (PE_LMEM) -+ * @param[in] dst PE LMEM destination address (must be 32bit aligned) -+ * @param[in] val Value to write -+ * @param[in] len Number of bytes to write -+ */ -+void class_pe_lmem_memset(u32 dst, int val, unsigned int len) -+{ -+ u32 len32 = len >> 2; -+ int i; -+ -+ val = val | (val << 8) | (val << 16) | (val << 24); -+ -+ for (i = 0; i < len32; i++, dst += 4) -+ class_bus_write(val, dst, 4); -+ -+ if (len & 0x2) { -+ class_bus_write(val, dst, 2); -+ dst += 2; -+ } -+ -+ if (len & 0x1) { -+ class_bus_write(val, dst, 1); -+ dst++; -+ } -+} -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ -+/* Writes UTIL program memory (DDR) from the host. -+ * -+ * @param[in] addr Address to write (virtual, must be aligned on size) -+ * @param[in] val Value to write (in PE endianness, i.e BE) -+ * @param[in] size Number of bytes to write (2 or 4) -+ */ -+static void util_pmem_write(u32 val, void *addr, u8 size) -+{ -+ void *addr64 = (void *)((unsigned long)addr & ~0x7); -+ unsigned long off = 8 - ((unsigned long)addr & 0x7) - size; -+ -+ /* -+ * IMEM should be loaded as a 64bit swapped value in a 64bit aligned -+ * location -+ */ -+ if (size == 4) -+ writel(be32_to_cpu(val), addr64 + off); -+ else -+ writew(be16_to_cpu((u16)val), addr64 + off); -+} -+ -+/* Writes a buffer to UTIL program memory (DDR) from the host. -+ * -+ * @param[in] dst Address to write (virtual, must be at least 16bit -+ * aligned) -+ * @param[in] src Buffer to write (in PE endianness, i.e BE, must have -+ * same alignment as dst) -+ * @param[in] len Number of bytes to write (must be at least 16bit -+ * aligned) -+ */ -+static void util_pmem_memcpy(void *dst, const void *src, unsigned int len) -+{ -+ unsigned int len32; -+ int i; -+ -+ if ((unsigned long)src & 0x2) { -+ util_pmem_write(*(u16 *)src, dst, 2); -+ src += 2; -+ dst += 2; -+ len -= 2; -+ } -+ -+ len32 = len >> 2; -+ -+ for (i = 0; i < len32; i++, dst += 4, src += 4) -+ util_pmem_write(*(u32 *)src, dst, 4); -+ -+ if (len & 0x2) -+ util_pmem_write(*(u16 *)src, dst, len & 0x2); -+} -+#endif -+ -+/* Loads an elf section into pmem -+ * Code needs to be at least 16bit aligned and only PROGBITS sections are -+ * supported -+ * -+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, ..., -+ * TMU3_ID) -+ * @param[in] data pointer to the elf firmware -+ * @param[in] shdr pointer to the elf section header -+ * -+ */ -+static int pe_load_pmem_section(int id, const void *data, -+ struct elf32_shdr *shdr) -+{ -+ u32 offset = be32_to_cpu(shdr->sh_offset); -+ u32 addr = be32_to_cpu(shdr->sh_addr); -+ u32 size = be32_to_cpu(shdr->sh_size); -+ u32 type = be32_to_cpu(shdr->sh_type); -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ if (id == UTIL_ID) { -+ pr_err("%s: unsupported pmem section for UTIL\n", -+ __func__); -+ return -EINVAL; -+ } -+#endif -+ -+ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) { -+ pr_err( -+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n" -+ , __func__, addr, (unsigned long)data + offset); -+ -+ return -EINVAL; -+ } -+ -+ if (addr & 0x1) { -+ pr_err("%s: load address(%x) is not 16bit aligned\n", -+ __func__, addr); -+ return -EINVAL; -+ } -+ -+ if (size & 0x1) { -+ pr_err("%s: load size(%x) is not 16bit aligned\n", -+ __func__, size); -+ return -EINVAL; -+ } -+ -+ switch (type) { -+ case SHT_PROGBITS: -+ pe_pmem_memcpy_to32(id, addr, data + offset, size); -+ -+ break; -+ -+ default: -+ pr_err("%s: unsupported section type(%x)\n", __func__, -+ type); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Loads an elf section into dmem -+ * Data needs to be at least 32bit aligned, NOBITS sections are correctly -+ * initialized to 0 -+ * -+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, -+ * ..., UTIL_ID) -+ * @param[in] data pointer to the elf firmware -+ * @param[in] shdr pointer to the elf section header -+ * -+ */ -+static int pe_load_dmem_section(int id, const void *data, -+ struct elf32_shdr *shdr) -+{ -+ u32 offset = be32_to_cpu(shdr->sh_offset); -+ u32 addr = be32_to_cpu(shdr->sh_addr); -+ u32 size = be32_to_cpu(shdr->sh_size); -+ u32 type = be32_to_cpu(shdr->sh_type); -+ u32 size32 = size >> 2; -+ int i; -+ -+ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) { -+ pr_err( -+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n", -+ __func__, addr, (unsigned long)data + offset); -+ -+ return -EINVAL; -+ } -+ -+ if (addr & 0x3) { -+ pr_err("%s: load address(%x) is not 32bit aligned\n", -+ __func__, addr); -+ return -EINVAL; -+ } -+ -+ switch (type) { -+ case SHT_PROGBITS: -+ pe_dmem_memcpy_to32(id, addr, data + offset, size); -+ break; -+ -+ case SHT_NOBITS: -+ for (i = 0; i < size32; i++, addr += 4) -+ pe_dmem_write(id, 0, addr, 4); -+ -+ if (size & 0x3) -+ pe_dmem_write(id, 0, addr, size & 0x3); -+ -+ break; -+ -+ default: -+ pr_err("%s: unsupported section type(%x)\n", __func__, -+ type); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Loads an elf section into DDR -+ * Data needs to be at least 32bit aligned, NOBITS sections are correctly -+ * initialized to 0 -+ * -+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, -+ * ..., UTIL_ID) -+ * @param[in] data pointer to the elf firmware -+ * @param[in] shdr pointer to the elf section header -+ * -+ */ -+static int pe_load_ddr_section(int id, const void *data, -+ struct elf32_shdr *shdr, -+ struct device *dev) { -+ u32 offset = be32_to_cpu(shdr->sh_offset); -+ u32 addr = be32_to_cpu(shdr->sh_addr); -+ u32 size = be32_to_cpu(shdr->sh_size); -+ u32 type = be32_to_cpu(shdr->sh_type); -+ u32 flags = be32_to_cpu(shdr->sh_flags); -+ -+ switch (type) { -+ case SHT_PROGBITS: -+ if (flags & SHF_EXECINSTR) { -+ if (id <= CLASS_MAX_ID) { -+ /* DO the loading only once in DDR */ -+ if (id == CLASS0_ID) { -+ pr_err( -+ "%s: load address(%x) and elf file address(%lx) rcvd\n", -+ __func__, addr, -+ (unsigned long)data + offset); -+ if (((unsigned long)(data + offset) -+ & 0x3) != (addr & 0x3)) { -+ pr_err( -+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n" -+ , __func__, addr, -+ (unsigned long)data + offset); -+ -+ return -EINVAL; -+ } -+ -+ if (addr & 0x1) { -+ pr_err( -+ "%s: load address(%x) is not 16bit aligned\n" -+ , __func__, addr); -+ return -EINVAL; -+ } -+ -+ if (size & 0x1) { -+ pr_err( -+ "%s: load length(%x) is not 16bit aligned\n" -+ , __func__, size); -+ return -EINVAL; -+ } -+ memcpy(DDR_PHYS_TO_VIRT( -+ DDR_PFE_TO_PHYS(addr)), -+ data + offset, size); -+ } -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ } else if (id == UTIL_ID) { -+ if (((unsigned long)(data + offset) & 0x3) -+ != (addr & 0x3)) { -+ pr_err( -+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n" -+ , __func__, addr, -+ (unsigned long)data + offset); -+ -+ return -EINVAL; -+ } -+ -+ if (addr & 0x1) { -+ pr_err( -+ "%s: load address(%x) is not 16bit aligned\n" -+ , __func__, addr); -+ return -EINVAL; -+ } -+ -+ if (size & 0x1) { -+ pr_err( -+ "%s: load length(%x) is not 16bit aligned\n" -+ , __func__, size); -+ return -EINVAL; -+ } -+ -+ util_pmem_memcpy(DDR_PHYS_TO_VIRT( -+ DDR_PFE_TO_PHYS(addr)), -+ data + offset, size); -+ } -+#endif -+ } else { -+ pr_err( -+ "%s: unsupported ddr section type(%x) for PE(%d)\n" -+ , __func__, type, id); -+ return -EINVAL; -+ } -+ -+ } else { -+ memcpy(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), data -+ + offset, size); -+ } -+ -+ break; -+ -+ case SHT_NOBITS: -+ memset(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), 0, size); -+ -+ break; -+ -+ default: -+ pr_err("%s: unsupported section type(%x)\n", __func__, -+ type); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Loads an elf section into pe lmem -+ * Data needs to be at least 32bit aligned, NOBITS sections are correctly -+ * initialized to 0 -+ * -+ * @param[in] id PE identification (CLASS0_ID,..., CLASS5_ID) -+ * @param[in] data pointer to the elf firmware -+ * @param[in] shdr pointer to the elf section header -+ * -+ */ -+static int pe_load_pe_lmem_section(int id, const void *data, -+ struct elf32_shdr *shdr) -+{ -+ u32 offset = be32_to_cpu(shdr->sh_offset); -+ u32 addr = be32_to_cpu(shdr->sh_addr); -+ u32 size = be32_to_cpu(shdr->sh_size); -+ u32 type = be32_to_cpu(shdr->sh_type); -+ -+ if (id > CLASS_MAX_ID) { -+ pr_err( -+ "%s: unsupported pe-lmem section type(%x) for PE(%d)\n", -+ __func__, type, id); -+ return -EINVAL; -+ } -+ -+ if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) { -+ pr_err( -+ "%s: load address(%x) and elf file address(%lx) don't have the same alignment\n", -+ __func__, addr, (unsigned long)data + offset); -+ -+ return -EINVAL; -+ } -+ -+ if (addr & 0x3) { -+ pr_err("%s: load address(%x) is not 32bit aligned\n", -+ __func__, addr); -+ return -EINVAL; -+ } -+ -+ switch (type) { -+ case SHT_PROGBITS: -+ class_pe_lmem_memcpy_to32(addr, data + offset, size); -+ break; -+ -+ case SHT_NOBITS: -+ class_pe_lmem_memset(addr, 0, size); -+ break; -+ -+ default: -+ pr_err("%s: unsupported section type(%x)\n", __func__, -+ type); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Loads an elf section into a PE -+ * For now only supports loading a section to dmem (all PE's), pmem (class and -+ * tmu PE's), -+ * DDDR (util PE code) -+ * -+ * @param[in] id PE identification (CLASS0_ID, ..., TMU0_ID, -+ * ..., UTIL_ID) -+ * @param[in] data pointer to the elf firmware -+ * @param[in] shdr pointer to the elf section header -+ * -+ */ -+int pe_load_elf_section(int id, const void *data, struct elf32_shdr *shdr, -+ struct device *dev) { -+ u32 addr = be32_to_cpu(shdr->sh_addr); -+ u32 size = be32_to_cpu(shdr->sh_size); -+ -+ if (IS_DMEM(addr, size)) -+ return pe_load_dmem_section(id, data, shdr); -+ else if (IS_PMEM(addr, size)) -+ return pe_load_pmem_section(id, data, shdr); -+ else if (IS_PFE_LMEM(addr, size)) -+ return 0; -+ else if (IS_PHYS_DDR(addr, size)) -+ return pe_load_ddr_section(id, data, shdr, dev); -+ else if (IS_PE_LMEM(addr, size)) -+ return pe_load_pe_lmem_section(id, data, shdr); -+ -+ pr_err("%s: unsupported memory range(%x)\n", __func__, -+ addr); -+ return 0; -+} -+ -+/**************************** BMU ***************************/ -+ -+/* Initializes a BMU block. -+ * @param[in] base BMU block base address -+ * @param[in] cfg BMU configuration -+ */ -+void bmu_init(void *base, struct BMU_CFG *cfg) -+{ -+ bmu_disable(base); -+ -+ bmu_set_config(base, cfg); -+ -+ bmu_reset(base); -+} -+ -+/* Resets a BMU block. -+ * @param[in] base BMU block base address -+ */ -+void bmu_reset(void *base) -+{ -+ writel(CORE_SW_RESET, base + BMU_CTRL); -+ -+ /* Wait for self clear */ -+ while (readl(base + BMU_CTRL) & CORE_SW_RESET) -+ ; -+} -+ -+/* Enabled a BMU block. -+ * @param[in] base BMU block base address -+ */ -+void bmu_enable(void *base) -+{ -+ writel(CORE_ENABLE, base + BMU_CTRL); -+} -+ -+/* Disables a BMU block. -+ * @param[in] base BMU block base address -+ */ -+void bmu_disable(void *base) -+{ -+ writel(CORE_DISABLE, base + BMU_CTRL); -+} -+ -+/* Sets the configuration of a BMU block. -+ * @param[in] base BMU block base address -+ * @param[in] cfg BMU configuration -+ */ -+void bmu_set_config(void *base, struct BMU_CFG *cfg) -+{ -+ writel(cfg->baseaddr, base + BMU_UCAST_BASE_ADDR); -+ writel(cfg->count & 0xffff, base + BMU_UCAST_CONFIG); -+ writel(cfg->size & 0xffff, base + BMU_BUF_SIZE); -+ -+ /* Interrupts are never used */ -+ writel(cfg->low_watermark, base + BMU_LOW_WATERMARK); -+ writel(cfg->high_watermark, base + BMU_HIGH_WATERMARK); -+ writel(0x0, base + BMU_INT_ENABLE); -+} -+ -+/**************************** MTIP GEMAC ***************************/ -+ -+/* Enable Rx Checksum Engine. With this enabled, Frame with bad IP, -+ * TCP or UDP checksums are discarded -+ * -+ * @param[in] base GEMAC base address. -+ */ -+void gemac_enable_rx_checksum_offload(void *base) -+{ -+ /*Do not find configuration to do this */ -+} -+ -+/* Disable Rx Checksum Engine. -+ * -+ * @param[in] base GEMAC base address. -+ */ -+void gemac_disable_rx_checksum_offload(void *base) -+{ -+ /*Do not find configuration to do this */ -+} -+ -+/* GEMAC set speed. -+ * @param[in] base GEMAC base address -+ * @param[in] speed GEMAC speed (10, 100 or 1000 Mbps) -+ */ -+void gemac_set_speed(void *base, enum mac_speed gem_speed) -+{ -+ u32 ecr = readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_SPEED; -+ u32 rcr = readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_RMII_10T; -+ -+ switch (gem_speed) { -+ case SPEED_10M: -+ rcr |= EMAC_RCNTRL_RMII_10T; -+ break; -+ -+ case SPEED_1000M: -+ ecr |= EMAC_ECNTRL_SPEED; -+ break; -+ -+ case SPEED_100M: -+ default: -+ /*It is in 100M mode */ -+ break; -+ } -+ writel(ecr, (base + EMAC_ECNTRL_REG)); -+ writel(rcr, (base + EMAC_RCNTRL_REG)); -+} -+ -+/* GEMAC set duplex. -+ * @param[in] base GEMAC base address -+ * @param[in] duplex GEMAC duplex mode (Full, Half) -+ */ -+void gemac_set_duplex(void *base, int duplex) -+{ -+ if (duplex == DUPLEX_HALF) { -+ writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_FDEN, base -+ + EMAC_TCNTRL_REG); -+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_DRT, (base -+ + EMAC_RCNTRL_REG)); -+ } else{ -+ writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_FDEN, base -+ + EMAC_TCNTRL_REG); -+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_DRT, (base -+ + EMAC_RCNTRL_REG)); -+ } -+} -+ -+/* GEMAC set mode. -+ * @param[in] base GEMAC base address -+ * @param[in] mode GEMAC operation mode (MII, RMII, RGMII, SGMII) -+ */ -+void gemac_set_mode(void *base, int mode) -+{ -+ u32 val = readl(base + EMAC_RCNTRL_REG); -+ -+ /*Remove loopbank*/ -+ val &= ~EMAC_RCNTRL_LOOP; -+ -+ /*Enable flow control and MII mode*/ -+ val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE); -+ -+ writel(val, base + EMAC_RCNTRL_REG); -+} -+ -+/* GEMAC enable function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_enable(void *base) -+{ -+ writel(readl(base + EMAC_ECNTRL_REG) | EMAC_ECNTRL_ETHER_EN, base + -+ EMAC_ECNTRL_REG); -+} -+ -+/* GEMAC disable function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_disable(void *base) -+{ -+ writel(readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_ETHER_EN, base + -+ EMAC_ECNTRL_REG); -+} -+ -+/* GEMAC TX disable function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_tx_disable(void *base) -+{ -+ writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_GTS, base + -+ EMAC_TCNTRL_REG); -+} -+ -+void gemac_tx_enable(void *base) -+{ -+ writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_GTS, base + -+ EMAC_TCNTRL_REG); -+} -+ -+/* Sets the hash register of the MAC. -+ * This register is used for matching unicast and multicast frames. -+ * -+ * @param[in] base GEMAC base address. -+ * @param[in] hash 64-bit hash to be configured. -+ */ -+void gemac_set_hash(void *base, struct pfe_mac_addr *hash) -+{ -+ writel(hash->bottom, base + EMAC_GALR); -+ writel(hash->top, base + EMAC_GAUR); -+} -+ -+void gemac_set_laddrN(void *base, struct pfe_mac_addr *address, -+ unsigned int entry_index) -+{ -+ if ((entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX)) -+ return; -+ -+ entry_index = entry_index - 1; -+ if (entry_index < 1) { -+ writel(htonl(address->bottom), base + EMAC_PHY_ADDR_LOW); -+ writel((htonl(address->top) | 0x8808), base + -+ EMAC_PHY_ADDR_HIGH); -+ } else { -+ writel(htonl(address->bottom), base + ((entry_index - 1) * 8) -+ + EMAC_SMAC_0_0); -+ writel((htonl(address->top) | 0x8808), base + ((entry_index - -+ 1) * 8) + EMAC_SMAC_0_1); -+ } -+} -+ -+void gemac_clear_laddrN(void *base, unsigned int entry_index) -+{ -+ if ((entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX)) -+ return; -+ -+ entry_index = entry_index - 1; -+ if (entry_index < 1) { -+ writel(0, base + EMAC_PHY_ADDR_LOW); -+ writel(0, base + EMAC_PHY_ADDR_HIGH); -+ } else { -+ writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_0); -+ writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_1); -+ } -+} -+ -+/* Set the loopback mode of the MAC. This can be either no loopback for -+ * normal operation, local loopback through MAC internal loopback module or PHY -+ * loopback for external loopback through a PHY. This asserts the external -+ * loop pin. -+ * -+ * @param[in] base GEMAC base address. -+ * @param[in] gem_loop Loopback mode to be enabled. LB_LOCAL - MAC -+ * Loopback, -+ * LB_EXT - PHY Loopback. -+ */ -+void gemac_set_loop(void *base, enum mac_loop gem_loop) -+{ -+ pr_info("%s()\n", __func__); -+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_LOOP, (base + -+ EMAC_RCNTRL_REG)); -+} -+ -+/* GEMAC allow frames -+ * @param[in] base GEMAC base address -+ */ -+void gemac_enable_copy_all(void *base) -+{ -+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_PROM, (base + -+ EMAC_RCNTRL_REG)); -+} -+ -+/* GEMAC do not allow frames -+ * @param[in] base GEMAC base address -+ */ -+void gemac_disable_copy_all(void *base) -+{ -+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_PROM, (base + -+ EMAC_RCNTRL_REG)); -+} -+ -+/* GEMAC allow broadcast function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_allow_broadcast(void *base) -+{ -+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_BC_REJ, base + -+ EMAC_RCNTRL_REG); -+} -+ -+/* GEMAC no broadcast function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_no_broadcast(void *base) -+{ -+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_BC_REJ, base + -+ EMAC_RCNTRL_REG); -+} -+ -+/* GEMAC enable 1536 rx function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_enable_1536_rx(void *base) -+{ -+ /* Set 1536 as Maximum frame length */ -+ writel(readl(base + EMAC_RCNTRL_REG) | (1536 << 16), base + -+ EMAC_RCNTRL_REG); -+} -+ -+/* GEMAC enable jumbo function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_enable_rx_jmb(void *base) -+{ -+ writel(readl(base + EMAC_RCNTRL_REG) | (JUMBO_FRAME_SIZE << 16), base -+ + EMAC_RCNTRL_REG); -+} -+ -+/* GEMAC enable stacked vlan function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_enable_stacked_vlan(void *base) -+{ -+ /* MTIP doesn't support stacked vlan */ -+} -+ -+/* GEMAC enable pause rx function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_enable_pause_rx(void *base) -+{ -+ writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_FCE, -+ base + EMAC_RCNTRL_REG); -+} -+ -+/* GEMAC disable pause rx function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_disable_pause_rx(void *base) -+{ -+ writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_FCE, -+ base + EMAC_RCNTRL_REG); -+} -+ -+/* GEMAC enable pause tx function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_enable_pause_tx(void *base) -+{ -+ writel(EMAC_RX_SECTION_EMPTY_V, base + EMAC_RX_SECTION_EMPTY); -+} -+ -+/* GEMAC disable pause tx function. -+ * @param[in] base GEMAC base address -+ */ -+void gemac_disable_pause_tx(void *base) -+{ -+ writel(0x0, base + EMAC_RX_SECTION_EMPTY); -+} -+ -+/* GEMAC wol configuration -+ * @param[in] base GEMAC base address -+ * @param[in] wol_conf WoL register configuration -+ */ -+void gemac_set_wol(void *base, u32 wol_conf) -+{ -+ u32 val = readl(base + EMAC_ECNTRL_REG); -+ -+ if (wol_conf) -+ val |= (EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP); -+ else -+ val &= ~(EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP); -+ writel(val, base + EMAC_ECNTRL_REG); -+} -+ -+/* Sets Gemac bus width to 64bit -+ * @param[in] base GEMAC base address -+ * @param[in] width gemac bus width to be set possible values are 32/64/128 -+ */ -+void gemac_set_bus_width(void *base, int width) -+{ -+} -+ -+/* Sets Gemac configuration. -+ * @param[in] base GEMAC base address -+ * @param[in] cfg GEMAC configuration -+ */ -+void gemac_set_config(void *base, struct gemac_cfg *cfg) -+{ -+ /*GEMAC config taken from VLSI */ -+ writel(0x00000004, base + EMAC_TFWR_STR_FWD); -+ writel(0x00000005, base + EMAC_RX_SECTION_FULL); -+ writel(0x00003fff, base + EMAC_TRUNC_FL); -+ writel(0x00000030, base + EMAC_TX_SECTION_EMPTY); -+ writel(0x00000000, base + EMAC_MIB_CTRL_STS_REG); -+ -+ gemac_set_mode(base, cfg->mode); -+ -+ gemac_set_speed(base, cfg->speed); -+ -+ gemac_set_duplex(base, cfg->duplex); -+} -+ -+/**************************** GPI ***************************/ -+ -+/* Initializes a GPI block. -+ * @param[in] base GPI base address -+ * @param[in] cfg GPI configuration -+ */ -+void gpi_init(void *base, struct gpi_cfg *cfg) -+{ -+ gpi_reset(base); -+ -+ gpi_disable(base); -+ -+ gpi_set_config(base, cfg); -+} -+ -+/* Resets a GPI block. -+ * @param[in] base GPI base address -+ */ -+void gpi_reset(void *base) -+{ -+ writel(CORE_SW_RESET, base + GPI_CTRL); -+} -+ -+/* Enables a GPI block. -+ * @param[in] base GPI base address -+ */ -+void gpi_enable(void *base) -+{ -+ writel(CORE_ENABLE, base + GPI_CTRL); -+} -+ -+/* Disables a GPI block. -+ * @param[in] base GPI base address -+ */ -+void gpi_disable(void *base) -+{ -+ writel(CORE_DISABLE, base + GPI_CTRL); -+} -+ -+/* Sets the configuration of a GPI block. -+ * @param[in] base GPI base address -+ * @param[in] cfg GPI configuration -+ */ -+void gpi_set_config(void *base, struct gpi_cfg *cfg) -+{ -+ writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_ALLOC_CTRL), base -+ + GPI_LMEM_ALLOC_ADDR); -+ writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_FREE_CTRL), base -+ + GPI_LMEM_FREE_ADDR); -+ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_ALLOC_CTRL), base -+ + GPI_DDR_ALLOC_ADDR); -+ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL), base -+ + GPI_DDR_FREE_ADDR); -+ writel(CBUS_VIRT_TO_PFE(CLASS_INQ_PKTPTR), base + GPI_CLASS_ADDR); -+ writel(DDR_HDR_SIZE, base + GPI_DDR_DATA_OFFSET); -+ writel(LMEM_HDR_SIZE, base + GPI_LMEM_DATA_OFFSET); -+ writel(0, base + GPI_LMEM_SEC_BUF_DATA_OFFSET); -+ writel(0, base + GPI_DDR_SEC_BUF_DATA_OFFSET); -+ writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, base + GPI_HDR_SIZE); -+ writel((DDR_BUF_SIZE << 16) | LMEM_BUF_SIZE, base + GPI_BUF_SIZE); -+ -+ writel(((cfg->lmem_rtry_cnt << 16) | (GPI_DDR_BUF_EN << 1) | -+ GPI_LMEM_BUF_EN), base + GPI_RX_CONFIG); -+ writel(cfg->tmlf_txthres, base + GPI_TMLF_TX); -+ writel(cfg->aseq_len, base + GPI_DTX_ASEQ); -+ writel(1, base + GPI_TOE_CHKSUM_EN); -+ -+ if (cfg->mtip_pause_reg) { -+ writel(cfg->mtip_pause_reg, base + GPI_CSR_MTIP_PAUSE_REG); -+ writel(EGPI_PAUSE_TIME, base + GPI_TX_PAUSE_TIME); -+ } -+} -+ -+/**************************** CLASSIFIER ***************************/ -+ -+/* Initializes CLASSIFIER block. -+ * @param[in] cfg CLASSIFIER configuration -+ */ -+void class_init(struct class_cfg *cfg) -+{ -+ class_reset(); -+ -+ class_disable(); -+ -+ class_set_config(cfg); -+} -+ -+/* Resets CLASSIFIER block. -+ * -+ */ -+void class_reset(void) -+{ -+ writel(CORE_SW_RESET, CLASS_TX_CTRL); -+} -+ -+/* Enables all CLASS-PE's cores. -+ * -+ */ -+void class_enable(void) -+{ -+ writel(CORE_ENABLE, CLASS_TX_CTRL); -+} -+ -+/* Disables all CLASS-PE's cores. -+ * -+ */ -+void class_disable(void) -+{ -+ writel(CORE_DISABLE, CLASS_TX_CTRL); -+} -+ -+/* -+ * Sets the configuration of the CLASSIFIER block. -+ * @param[in] cfg CLASSIFIER configuration -+ */ -+void class_set_config(struct class_cfg *cfg) -+{ -+ u32 val; -+ -+ /* Initialize route table */ -+ if (!cfg->resume) -+ memset(DDR_PHYS_TO_VIRT(cfg->route_table_baseaddr), 0, (1 << -+ cfg->route_table_hash_bits) * CLASS_ROUTE_SIZE); -+ -+#if !defined(LS1012A_PFE_RESET_WA) -+ writel(cfg->pe_sys_clk_ratio, CLASS_PE_SYS_CLK_RATIO); -+#endif -+ -+ writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, CLASS_HDR_SIZE); -+ writel(LMEM_BUF_SIZE, CLASS_LMEM_BUF_SIZE); -+ writel(CLASS_ROUTE_ENTRY_SIZE(CLASS_ROUTE_SIZE) | -+ CLASS_ROUTE_HASH_SIZE(cfg->route_table_hash_bits), -+ CLASS_ROUTE_HASH_ENTRY_SIZE); -+ writel(HIF_PKT_CLASS_EN | HIF_PKT_OFFSET(sizeof(struct hif_hdr)), -+ CLASS_HIF_PARSE); -+ -+ val = HASH_CRC_PORT_IP | QB2BUS_LE; -+ -+#if defined(CONFIG_IP_ALIGNED) -+ val |= IP_ALIGNED; -+#endif -+ -+ /* -+ * Class PE packet steering will only work if TOE mode, bridge fetch or -+ * route fetch are enabled (see class/qb_fet.v). Route fetch would -+ * trigger additional memory copies (likely from DDR because of hash -+ * table size, which cannot be reduced because PE software still -+ * relies on hash value computed in HW), so when not in TOE mode we -+ * simply enable HW bridge fetch even though we don't use it. -+ */ -+ if (cfg->toe_mode) -+ val |= CLASS_TOE; -+ else -+ val |= HW_BRIDGE_FETCH; -+ -+ writel(val, CLASS_ROUTE_MULTI); -+ -+ writel(DDR_PHYS_TO_PFE(cfg->route_table_baseaddr), -+ CLASS_ROUTE_TABLE_BASE); -+ writel(CLASS_PE0_RO_DM_ADDR0_VAL, CLASS_PE0_RO_DM_ADDR0); -+ writel(CLASS_PE0_RO_DM_ADDR1_VAL, CLASS_PE0_RO_DM_ADDR1); -+ writel(CLASS_PE0_QB_DM_ADDR0_VAL, CLASS_PE0_QB_DM_ADDR0); -+ writel(CLASS_PE0_QB_DM_ADDR1_VAL, CLASS_PE0_QB_DM_ADDR1); -+ writel(CBUS_VIRT_TO_PFE(TMU_PHY_INQ_PKTPTR), CLASS_TM_INQ_ADDR); -+ -+ writel(23, CLASS_AFULL_THRES); -+ writel(23, CLASS_TSQ_FIFO_THRES); -+ -+ writel(24, CLASS_MAX_BUF_CNT); -+ writel(24, CLASS_TSQ_MAX_CNT); -+} -+ -+/**************************** TMU ***************************/ -+ -+void tmu_reset(void) -+{ -+ writel(SW_RESET, TMU_CTRL); -+} -+ -+/* Initializes TMU block. -+ * @param[in] cfg TMU configuration -+ */ -+void tmu_init(struct tmu_cfg *cfg) -+{ -+ int q, phyno; -+ -+ tmu_disable(0xF); -+ mdelay(10); -+ -+#if !defined(LS1012A_PFE_RESET_WA) -+ /* keep in soft reset */ -+ writel(SW_RESET, TMU_CTRL); -+#endif -+ writel(0x3, TMU_SYS_GENERIC_CONTROL); -+ writel(750, TMU_INQ_WATERMARK); -+ writel(CBUS_VIRT_TO_PFE(EGPI1_BASE_ADDR + -+ GPI_INQ_PKTPTR), TMU_PHY0_INQ_ADDR); -+ writel(CBUS_VIRT_TO_PFE(EGPI2_BASE_ADDR + -+ GPI_INQ_PKTPTR), TMU_PHY1_INQ_ADDR); -+ writel(CBUS_VIRT_TO_PFE(HGPI_BASE_ADDR + -+ GPI_INQ_PKTPTR), TMU_PHY3_INQ_ADDR); -+ writel(CBUS_VIRT_TO_PFE(HIF_NOCPY_RX_INQ0_PKTPTR), TMU_PHY4_INQ_ADDR); -+ writel(CBUS_VIRT_TO_PFE(UTIL_INQ_PKTPTR), TMU_PHY5_INQ_ADDR); -+ writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL), -+ TMU_BMU_INQ_ADDR); -+ -+ writel(0x3FF, TMU_TDQ0_SCH_CTRL); /* -+ * enabling all 10 -+ * schedulers [9:0] of each TDQ -+ */ -+ writel(0x3FF, TMU_TDQ1_SCH_CTRL); -+ writel(0x3FF, TMU_TDQ3_SCH_CTRL); -+ -+#if !defined(LS1012A_PFE_RESET_WA) -+ writel(cfg->pe_sys_clk_ratio, TMU_PE_SYS_CLK_RATIO); -+#endif -+ -+#if !defined(LS1012A_PFE_RESET_WA) -+ writel(DDR_PHYS_TO_PFE(cfg->llm_base_addr), TMU_LLM_BASE_ADDR); -+ /* Extra packet pointers will be stored from this address onwards */ -+ -+ writel(cfg->llm_queue_len, TMU_LLM_QUE_LEN); -+ writel(5, TMU_TDQ_IIFG_CFG); -+ writel(DDR_BUF_SIZE, TMU_BMU_BUF_SIZE); -+ -+ writel(0x0, TMU_CTRL); -+ -+ /* MEM init */ -+ pr_info("%s: mem init\n", __func__); -+ writel(MEM_INIT, TMU_CTRL); -+ -+ while (!(readl(TMU_CTRL) & MEM_INIT_DONE)) -+ ; -+ -+ /* LLM init */ -+ pr_info("%s: lmem init\n", __func__); -+ writel(LLM_INIT, TMU_CTRL); -+ -+ while (!(readl(TMU_CTRL) & LLM_INIT_DONE)) -+ ; -+#endif -+ /* set up each queue for tail drop */ -+ for (phyno = 0; phyno < 4; phyno++) { -+ if (phyno == 2) -+ continue; -+ for (q = 0; q < 16; q++) { -+ u32 qdepth; -+ -+ writel((phyno << 8) | q, TMU_TEQ_CTRL); -+ writel(1 << 22, TMU_TEQ_QCFG); /*Enable tail drop */ -+ -+ if (phyno == 3) -+ qdepth = DEFAULT_TMU3_QDEPTH; -+ else -+ qdepth = (q == 0) ? DEFAULT_Q0_QDEPTH : -+ DEFAULT_MAX_QDEPTH; -+ -+ /* LOG: 68855 */ -+ /* -+ * The following is a workaround for the reordered -+ * packet and BMU2 buffer leakage issue. -+ */ -+ if (CHIP_REVISION() == 0) -+ qdepth = 31; -+ -+ writel(qdepth << 18, TMU_TEQ_HW_PROB_CFG2); -+ writel(qdepth >> 14, TMU_TEQ_HW_PROB_CFG3); -+ } -+ } -+ -+#ifdef CFG_LRO -+ /* Set TMU-3 queue 5 (LRO) in no-drop mode */ -+ writel((3 << 8) | TMU_QUEUE_LRO, TMU_TEQ_CTRL); -+ writel(0, TMU_TEQ_QCFG); -+#endif -+ -+ writel(0x05, TMU_TEQ_DISABLE_DROPCHK); -+ -+ writel(0x0, TMU_CTRL); -+} -+ -+/* Enables TMU-PE cores. -+ * @param[in] pe_mask TMU PE mask -+ */ -+void tmu_enable(u32 pe_mask) -+{ -+ writel(readl(TMU_TX_CTRL) | (pe_mask & 0xF), TMU_TX_CTRL); -+} -+ -+/* Disables TMU cores. -+ * @param[in] pe_mask TMU PE mask -+ */ -+void tmu_disable(u32 pe_mask) -+{ -+ writel(readl(TMU_TX_CTRL) & ~(pe_mask & 0xF), TMU_TX_CTRL); -+} -+ -+/* This will return the tmu queue status -+ * @param[in] if_id gem interface id or TMU index -+ * @return returns the bit mask of busy queues, zero means all -+ * queues are empty -+ */ -+u32 tmu_qstatus(u32 if_id) -+{ -+ return cpu_to_be32(pe_dmem_read(TMU0_ID + if_id, TMU_DM_PESTATUS + -+ offsetof(struct pe_status, tmu_qstatus), 4)); -+} -+ -+u32 tmu_pkts_processed(u32 if_id) -+{ -+ return cpu_to_be32(pe_dmem_read(TMU0_ID + if_id, TMU_DM_PESTATUS + -+ offsetof(struct pe_status, rx), 4)); -+} -+ -+/**************************** UTIL ***************************/ -+ -+/* Resets UTIL block. -+ */ -+void util_reset(void) -+{ -+ writel(CORE_SW_RESET, UTIL_TX_CTRL); -+} -+ -+/* Initializes UTIL block. -+ * @param[in] cfg UTIL configuration -+ */ -+void util_init(struct util_cfg *cfg) -+{ -+ writel(cfg->pe_sys_clk_ratio, UTIL_PE_SYS_CLK_RATIO); -+} -+ -+/* Enables UTIL-PE core. -+ * -+ */ -+void util_enable(void) -+{ -+ writel(CORE_ENABLE, UTIL_TX_CTRL); -+} -+ -+/* Disables UTIL-PE core. -+ * -+ */ -+void util_disable(void) -+{ -+ writel(CORE_DISABLE, UTIL_TX_CTRL); -+} -+ -+/**************************** HIF ***************************/ -+/* Initializes HIF copy block. -+ * -+ */ -+void hif_init(void) -+{ -+ /*Initialize HIF registers*/ -+ writel((HIF_RX_POLL_CTRL_CYCLE << 16) | HIF_TX_POLL_CTRL_CYCLE, -+ HIF_POLL_CTRL); -+} -+ -+/* Enable hif tx DMA and interrupt -+ * -+ */ -+void hif_tx_enable(void) -+{ -+ writel(HIF_CTRL_DMA_EN, HIF_TX_CTRL); -+ writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_TXPKT_INT_EN), -+ HIF_INT_ENABLE); -+} -+ -+/* Disable hif tx DMA and interrupt -+ * -+ */ -+void hif_tx_disable(void) -+{ -+ u32 hif_int; -+ -+ writel(0, HIF_TX_CTRL); -+ -+ hif_int = readl(HIF_INT_ENABLE); -+ hif_int &= HIF_TXPKT_INT_EN; -+ writel(hif_int, HIF_INT_ENABLE); -+} -+ -+/* Enable hif rx DMA and interrupt -+ * -+ */ -+void hif_rx_enable(void) -+{ -+ hif_rx_dma_start(); -+ writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_RXPKT_INT_EN), -+ HIF_INT_ENABLE); -+} -+ -+/* Disable hif rx DMA and interrupt -+ * -+ */ -+void hif_rx_disable(void) -+{ -+ u32 hif_int; -+ -+ writel(0, HIF_RX_CTRL); -+ -+ hif_int = readl(HIF_INT_ENABLE); -+ hif_int &= HIF_RXPKT_INT_EN; -+ writel(hif_int, HIF_INT_ENABLE); -+} ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_hif.c -@@ -0,0 +1,1094 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "pfe_mod.h" -+ -+#define HIF_INT_MASK (HIF_INT | HIF_RXPKT_INT | HIF_TXPKT_INT) -+ -+unsigned char napi_first_batch; -+ -+static void pfe_tx_do_cleanup(unsigned long data); -+ -+static int pfe_hif_alloc_descr(struct pfe_hif *hif) -+{ -+ void *addr; -+ dma_addr_t dma_addr; -+ int err = 0; -+ -+ pr_info("%s\n", __func__); -+ addr = dma_alloc_coherent(pfe->dev, -+ HIF_RX_DESC_NT * sizeof(struct hif_desc) + -+ HIF_TX_DESC_NT * sizeof(struct hif_desc), -+ &dma_addr, GFP_KERNEL); -+ -+ if (!addr) { -+ pr_err("%s: Could not allocate buffer descriptors!\n" -+ , __func__); -+ err = -ENOMEM; -+ goto err0; -+ } -+ -+ hif->descr_baseaddr_p = dma_addr; -+ hif->descr_baseaddr_v = addr; -+ hif->rx_ring_size = HIF_RX_DESC_NT; -+ hif->tx_ring_size = HIF_TX_DESC_NT; -+ -+ return 0; -+ -+err0: -+ return err; -+} -+ -+#if defined(LS1012A_PFE_RESET_WA) -+static void pfe_hif_disable_rx_desc(struct pfe_hif *hif) -+{ -+ int ii; -+ struct hif_desc *desc = hif->rx_base; -+ -+ /*Mark all descriptors as LAST_BD */ -+ for (ii = 0; ii < hif->rx_ring_size; ii++) { -+ desc->ctrl |= BD_CTRL_LAST_BD; -+ desc++; -+ } -+} -+ -+struct class_rx_hdr_t { -+ u32 next_ptr; /* ptr to the start of the first DDR buffer */ -+ u16 length; /* total packet length */ -+ u16 phyno; /* input physical port number */ -+ u32 status; /* gemac status bits */ -+ u32 status2; /* reserved for software usage */ -+}; -+ -+/* STATUS_BAD_FRAME_ERR is set for all errors (including checksums if enabled) -+ * except overflow -+ */ -+#define STATUS_BAD_FRAME_ERR BIT(16) -+#define STATUS_LENGTH_ERR BIT(17) -+#define STATUS_CRC_ERR BIT(18) -+#define STATUS_TOO_SHORT_ERR BIT(19) -+#define STATUS_TOO_LONG_ERR BIT(20) -+#define STATUS_CODE_ERR BIT(21) -+#define STATUS_MC_HASH_MATCH BIT(22) -+#define STATUS_CUMULATIVE_ARC_HIT BIT(23) -+#define STATUS_UNICAST_HASH_MATCH BIT(24) -+#define STATUS_IP_CHECKSUM_CORRECT BIT(25) -+#define STATUS_TCP_CHECKSUM_CORRECT BIT(26) -+#define STATUS_UDP_CHECKSUM_CORRECT BIT(27) -+#define STATUS_OVERFLOW_ERR BIT(28) /* GPI error */ -+#define MIN_PKT_SIZE 64 -+ -+static inline void copy_to_lmem(u32 *dst, u32 *src, int len) -+{ -+ int i; -+ -+ for (i = 0; i < len; i += sizeof(u32)) { -+ *dst = htonl(*src); -+ dst++; src++; -+ } -+} -+ -+static void send_dummy_pkt_to_hif(void) -+{ -+ void *lmem_ptr, *ddr_ptr, *lmem_virt_addr; -+ u32 physaddr; -+ struct class_rx_hdr_t local_hdr; -+ static u32 dummy_pkt[] = { -+ 0x33221100, 0x2b785544, 0xd73093cb, 0x01000608, -+ 0x04060008, 0x2b780200, 0xd73093cb, 0x0a01a8c0, -+ 0x33221100, 0xa8c05544, 0x00000301, 0x00000000, -+ 0x00000000, 0x00000000, 0x00000000, 0xbe86c51f }; -+ -+ ddr_ptr = (void *)((u64)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL)); -+ if (!ddr_ptr) -+ return; -+ -+ lmem_ptr = (void *)((u64)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL)); -+ if (!lmem_ptr) -+ return; -+ -+ pr_info("Sending a dummy pkt to HIF %p %p\n", ddr_ptr, lmem_ptr); -+ physaddr = (u32)DDR_VIRT_TO_PFE(ddr_ptr); -+ -+ lmem_virt_addr = (void *)CBUS_PFE_TO_VIRT((unsigned long int)lmem_ptr); -+ -+ local_hdr.phyno = htons(0); /* RX_PHY_0 */ -+ local_hdr.length = htons(MIN_PKT_SIZE); -+ -+ local_hdr.next_ptr = htonl((u32)physaddr); -+ /*Mark checksum is correct */ -+ local_hdr.status = htonl((STATUS_IP_CHECKSUM_CORRECT | -+ STATUS_UDP_CHECKSUM_CORRECT | -+ STATUS_TCP_CHECKSUM_CORRECT | -+ STATUS_UNICAST_HASH_MATCH | -+ STATUS_CUMULATIVE_ARC_HIT)); -+ copy_to_lmem((u32 *)lmem_virt_addr, (u32 *)&local_hdr, -+ sizeof(local_hdr)); -+ -+ copy_to_lmem((u32 *)(lmem_virt_addr + LMEM_HDR_SIZE), (u32 *)dummy_pkt, -+ 0x40); -+ -+ writel((unsigned long int)lmem_ptr, CLASS_INQ_PKTPTR); -+} -+ -+void pfe_hif_rx_idle(struct pfe_hif *hif) -+{ -+ int hif_stop_loop = 10; -+ u32 rx_status; -+ -+ pfe_hif_disable_rx_desc(hif); -+ pr_info("Bringing hif to idle state..."); -+ writel(0, HIF_INT_ENABLE); -+ /*If HIF Rx BDP is busy send a dummy packet */ -+ do { -+ rx_status = readl(HIF_RX_STATUS); -+ if (rx_status & BDP_CSR_RX_DMA_ACTV) -+ send_dummy_pkt_to_hif(); -+ -+ usleep_range(100, 150); -+ } while (--hif_stop_loop); -+ -+ if (readl(HIF_RX_STATUS) & BDP_CSR_RX_DMA_ACTV) -+ pr_info("Failed\n"); -+ else -+ pr_info("Done\n"); -+} -+#endif -+ -+static void pfe_hif_free_descr(struct pfe_hif *hif) -+{ -+ pr_info("%s\n", __func__); -+ -+ dma_free_coherent(pfe->dev, -+ hif->rx_ring_size * sizeof(struct hif_desc) + -+ hif->tx_ring_size * sizeof(struct hif_desc), -+ hif->descr_baseaddr_v, hif->descr_baseaddr_p); -+} -+ -+void pfe_hif_desc_dump(struct pfe_hif *hif) -+{ -+ struct hif_desc *desc; -+ unsigned long desc_p; -+ int ii = 0; -+ -+ pr_info("%s\n", __func__); -+ -+ desc = hif->rx_base; -+ desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v + -+ hif->descr_baseaddr_p); -+ -+ pr_info("HIF Rx desc base %p physical %x\n", desc, (u32)desc_p); -+ for (ii = 0; ii < hif->rx_ring_size; ii++) { -+ pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n", -+ readl(&desc->status), readl(&desc->ctrl), -+ readl(&desc->data), readl(&desc->next)); -+ desc++; -+ } -+ -+ desc = hif->tx_base; -+ desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v + -+ hif->descr_baseaddr_p); -+ -+ pr_info("HIF Tx desc base %p physical %x\n", desc, (u32)desc_p); -+ for (ii = 0; ii < hif->tx_ring_size; ii++) { -+ pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n", -+ readl(&desc->status), readl(&desc->ctrl), -+ readl(&desc->data), readl(&desc->next)); -+ desc++; -+ } -+} -+ -+/* pfe_hif_release_buffers */ -+static void pfe_hif_release_buffers(struct pfe_hif *hif) -+{ -+ struct hif_desc *desc; -+ int i = 0; -+ -+ hif->rx_base = hif->descr_baseaddr_v; -+ -+ pr_info("%s\n", __func__); -+ -+ /*Free Rx buffers */ -+ desc = hif->rx_base; -+ for (i = 0; i < hif->rx_ring_size; i++) { -+ if (readl(&desc->data)) { -+ if ((i < hif->shm->rx_buf_pool_cnt) && -+ (!hif->shm->rx_buf_pool[i])) { -+ /* -+ * dma_unmap_single(hif->dev, desc->data, -+ * hif->rx_buf_len[i], DMA_FROM_DEVICE); -+ */ -+ dma_unmap_single(hif->dev, -+ DDR_PFE_TO_PHYS( -+ readl(&desc->data)), -+ hif->rx_buf_len[i], -+ DMA_FROM_DEVICE); -+ hif->shm->rx_buf_pool[i] = hif->rx_buf_addr[i]; -+ } else { -+ pr_err("%s: buffer pool already full\n" -+ , __func__); -+ } -+ } -+ -+ writel(0, &desc->data); -+ writel(0, &desc->status); -+ writel(0, &desc->ctrl); -+ desc++; -+ } -+} -+ -+/* -+ * pfe_hif_init_buffers -+ * This function initializes the HIF Rx/Tx ring descriptors and -+ * initialize Rx queue with buffers. -+ */ -+static int pfe_hif_init_buffers(struct pfe_hif *hif) -+{ -+ struct hif_desc *desc, *first_desc_p; -+ u32 data; -+ int i = 0; -+ -+ pr_info("%s\n", __func__); -+ -+ /* Check enough Rx buffers available in the shared memory */ -+ if (hif->shm->rx_buf_pool_cnt < hif->rx_ring_size) -+ return -ENOMEM; -+ -+ hif->rx_base = hif->descr_baseaddr_v; -+ memset(hif->rx_base, 0, hif->rx_ring_size * sizeof(struct hif_desc)); -+ -+ /*Initialize Rx descriptors */ -+ desc = hif->rx_base; -+ first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p; -+ -+ for (i = 0; i < hif->rx_ring_size; i++) { -+ /* Initialize Rx buffers from the shared memory */ -+ -+ data = (u32)dma_map_single(hif->dev, hif->shm->rx_buf_pool[i], -+ pfe_pkt_size, DMA_FROM_DEVICE); -+ hif->rx_buf_addr[i] = hif->shm->rx_buf_pool[i]; -+ hif->rx_buf_len[i] = pfe_pkt_size; -+ hif->shm->rx_buf_pool[i] = NULL; -+ -+ if (likely(dma_mapping_error(hif->dev, data) == 0)) { -+ writel(DDR_PHYS_TO_PFE(data), &desc->data); -+ } else { -+ pr_err("%s : low on mem\n", __func__); -+ -+ goto err; -+ } -+ -+ writel(0, &desc->status); -+ -+ /* -+ * Ensure everything else is written to DDR before -+ * writing bd->ctrl -+ */ -+ wmb(); -+ -+ writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM -+ | BD_CTRL_DIR | BD_CTRL_DESC_EN -+ | BD_BUF_LEN(pfe_pkt_size)), &desc->ctrl); -+ -+ /* Chain descriptors */ -+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next); -+ desc++; -+ } -+ -+ /* Overwrite last descriptor to chain it to first one*/ -+ desc--; -+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next); -+ -+ hif->rxtoclean_index = 0; -+ -+ /*Initialize Rx buffer descriptor ring base address */ -+ writel(DDR_PHYS_TO_PFE(hif->descr_baseaddr_p), HIF_RX_BDP_ADDR); -+ -+ hif->tx_base = hif->rx_base + hif->rx_ring_size; -+ first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p + -+ hif->rx_ring_size; -+ memset(hif->tx_base, 0, hif->tx_ring_size * sizeof(struct hif_desc)); -+ -+ /*Initialize tx descriptors */ -+ desc = hif->tx_base; -+ -+ for (i = 0; i < hif->tx_ring_size; i++) { -+ /* Chain descriptors */ -+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next); -+ writel(0, &desc->ctrl); -+ desc++; -+ } -+ -+ /* Overwrite last descriptor to chain it to first one */ -+ desc--; -+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next); -+ hif->txavail = hif->tx_ring_size; -+ hif->txtosend = 0; -+ hif->txtoclean = 0; -+ hif->txtoflush = 0; -+ -+ /*Initialize Tx buffer descriptor ring base address */ -+ writel((u32)DDR_PHYS_TO_PFE(first_desc_p), HIF_TX_BDP_ADDR); -+ -+ return 0; -+ -+err: -+ pfe_hif_release_buffers(hif); -+ return -ENOMEM; -+} -+ -+/* -+ * pfe_hif_client_register -+ * -+ * This function used to register a client driver with the HIF driver. -+ * -+ * Return value: -+ * 0 - on Successful registration -+ */ -+static int pfe_hif_client_register(struct pfe_hif *hif, u32 client_id, -+ struct hif_client_shm *client_shm) -+{ -+ struct hif_client *client = &hif->client[client_id]; -+ u32 i, cnt; -+ struct rx_queue_desc *rx_qbase; -+ struct tx_queue_desc *tx_qbase; -+ struct hif_rx_queue *rx_queue; -+ struct hif_tx_queue *tx_queue; -+ int err = 0; -+ -+ pr_info("%s\n", __func__); -+ -+ spin_lock_bh(&hif->tx_lock); -+ -+ if (test_bit(client_id, &hif->shm->g_client_status[0])) { -+ pr_err("%s: client %d already registered\n", -+ __func__, client_id); -+ err = -1; -+ goto unlock; -+ } -+ -+ memset(client, 0, sizeof(struct hif_client)); -+ -+ /* Initialize client Rx queues baseaddr, size */ -+ -+ cnt = CLIENT_CTRL_RX_Q_CNT(client_shm->ctrl); -+ /* Check if client is requesting for more queues than supported */ -+ if (cnt > HIF_CLIENT_QUEUES_MAX) -+ cnt = HIF_CLIENT_QUEUES_MAX; -+ -+ client->rx_qn = cnt; -+ rx_qbase = (struct rx_queue_desc *)client_shm->rx_qbase; -+ for (i = 0; i < cnt; i++) { -+ rx_queue = &client->rx_q[i]; -+ rx_queue->base = rx_qbase + i * client_shm->rx_qsize; -+ rx_queue->size = client_shm->rx_qsize; -+ rx_queue->write_idx = 0; -+ } -+ -+ /* Initialize client Tx queues baseaddr, size */ -+ cnt = CLIENT_CTRL_TX_Q_CNT(client_shm->ctrl); -+ -+ /* Check if client is requesting for more queues than supported */ -+ if (cnt > HIF_CLIENT_QUEUES_MAX) -+ cnt = HIF_CLIENT_QUEUES_MAX; -+ -+ client->tx_qn = cnt; -+ tx_qbase = (struct tx_queue_desc *)client_shm->tx_qbase; -+ for (i = 0; i < cnt; i++) { -+ tx_queue = &client->tx_q[i]; -+ tx_queue->base = tx_qbase + i * client_shm->tx_qsize; -+ tx_queue->size = client_shm->tx_qsize; -+ tx_queue->ack_idx = 0; -+ } -+ -+ set_bit(client_id, &hif->shm->g_client_status[0]); -+ -+unlock: -+ spin_unlock_bh(&hif->tx_lock); -+ -+ return err; -+} -+ -+/* -+ * pfe_hif_client_unregister -+ * -+ * This function used to unregister a client from the HIF driver. -+ * -+ */ -+static void pfe_hif_client_unregister(struct pfe_hif *hif, u32 client_id) -+{ -+ pr_info("%s\n", __func__); -+ -+ /* -+ * Mark client as no longer available (which prevents further packet -+ * receive for this client) -+ */ -+ spin_lock_bh(&hif->tx_lock); -+ -+ if (!test_bit(client_id, &hif->shm->g_client_status[0])) { -+ pr_err("%s: client %d not registered\n", __func__, -+ client_id); -+ -+ spin_unlock_bh(&hif->tx_lock); -+ return; -+ } -+ -+ clear_bit(client_id, &hif->shm->g_client_status[0]); -+ -+ spin_unlock_bh(&hif->tx_lock); -+} -+ -+/* -+ * client_put_rxpacket- -+ * This functions puts the Rx pkt in the given client Rx queue. -+ * It actually swap the Rx pkt in the client Rx descriptor buffer -+ * and returns the free buffer from it. -+ * -+ * If the function returns NULL means client Rx queue is full and -+ * packet couldn't send to client queue. -+ */ -+static void *client_put_rxpacket(struct hif_rx_queue *queue, void *pkt, u32 len, -+ u32 flags, u32 client_ctrl, u32 *rem_len) -+{ -+ void *free_pkt = NULL; -+ struct rx_queue_desc *desc = queue->base + queue->write_idx; -+ -+ if (readl(&desc->ctrl) & CL_DESC_OWN) { -+ if (page_mode) { -+ int rem_page_size = PAGE_SIZE - -+ PRESENT_OFST_IN_PAGE(pkt); -+ int cur_pkt_size = ROUND_MIN_RX_SIZE(len + -+ pfe_pkt_headroom); -+ *rem_len = (rem_page_size - cur_pkt_size); -+ if (*rem_len) { -+ free_pkt = pkt + cur_pkt_size; -+ get_page(virt_to_page(free_pkt)); -+ } else { -+ free_pkt = (void -+ *)__get_free_page(GFP_ATOMIC | GFP_DMA_PFE); -+ *rem_len = pfe_pkt_size; -+ } -+ } else { -+ free_pkt = kmalloc(PFE_BUF_SIZE, GFP_ATOMIC | -+ GFP_DMA_PFE); -+ *rem_len = PFE_BUF_SIZE - pfe_pkt_headroom; -+ } -+ -+ if (free_pkt) { -+ desc->data = pkt; -+ desc->client_ctrl = client_ctrl; -+ /* -+ * Ensure everything else is written to DDR before -+ * writing bd->ctrl -+ */ -+ smp_wmb(); -+ writel(CL_DESC_BUF_LEN(len) | flags, &desc->ctrl); -+ /* queue->write_idx = (queue->write_idx + 1) -+ * & (queue->size - 1); -+ */ -+ free_pkt += pfe_pkt_headroom; -+ } -+ } -+ -+ return free_pkt; -+} -+ -+/* -+ * pfe_hif_rx_process- -+ * This function does pfe hif rx queue processing. -+ * Dequeue packet from Rx queue and send it to corresponding client queue -+ */ -+static int pfe_hif_rx_process(struct pfe_hif *hif, int budget) -+{ -+ struct hif_desc *desc; -+ struct hif_hdr *pkt_hdr; -+ struct __hif_hdr hif_hdr; -+ void *free_buf; -+ int rtc, len, rx_processed = 0; -+ struct __hif_desc local_desc; -+ int flags; -+ unsigned int desc_p; -+ unsigned int buf_size = 0; -+ -+ spin_lock_bh(&hif->lock); -+ -+ rtc = hif->rxtoclean_index; -+ -+ while (rx_processed < budget) { -+ desc = hif->rx_base + rtc; -+ -+ __memcpy12(&local_desc, desc); -+ -+ /* ACK pending Rx interrupt */ -+ if (local_desc.ctrl & BD_CTRL_DESC_EN) { -+ writel(HIF_INT | HIF_RXPKT_INT, HIF_INT_SRC); -+ -+ if (rx_processed == 0) { -+ if (napi_first_batch == 1) { -+ desc_p = hif->descr_baseaddr_p + -+ ((unsigned long int)(desc) - -+ (unsigned long -+ int)hif->descr_baseaddr_v); -+ napi_first_batch = 0; -+ } -+ } -+ -+ __memcpy12(&local_desc, desc); -+ -+ if (local_desc.ctrl & BD_CTRL_DESC_EN) -+ break; -+ } -+ -+ napi_first_batch = 0; -+ -+#ifdef HIF_NAPI_STATS -+ hif->napi_counters[NAPI_DESC_COUNT]++; -+#endif -+ len = BD_BUF_LEN(local_desc.ctrl); -+ /* -+ * dma_unmap_single(hif->dev, DDR_PFE_TO_PHYS(local_desc.data), -+ * hif->rx_buf_len[rtc], DMA_FROM_DEVICE); -+ */ -+ dma_unmap_single(hif->dev, DDR_PFE_TO_PHYS(local_desc.data), -+ hif->rx_buf_len[rtc], DMA_FROM_DEVICE); -+ -+ pkt_hdr = (struct hif_hdr *)hif->rx_buf_addr[rtc]; -+ -+ /* Track last HIF header received */ -+ if (!hif->started) { -+ hif->started = 1; -+ -+ __memcpy8(&hif_hdr, pkt_hdr); -+ -+ hif->qno = hif_hdr.hdr.q_num; -+ hif->client_id = hif_hdr.hdr.client_id; -+ hif->client_ctrl = (hif_hdr.hdr.client_ctrl1 << 16) | -+ hif_hdr.hdr.client_ctrl; -+ flags = CL_DESC_FIRST; -+ -+ } else { -+ flags = 0; -+ } -+ -+ if (local_desc.ctrl & BD_CTRL_LIFM) -+ flags |= CL_DESC_LAST; -+ -+ /* Check for valid client id and still registered */ -+ if ((hif->client_id >= HIF_CLIENTS_MAX) || -+ !(test_bit(hif->client_id, -+ &hif->shm->g_client_status[0]))) { -+ printk_ratelimited("%s: packet with invalid client id %d q_num %d\n", -+ __func__, -+ hif->client_id, -+ hif->qno); -+ -+ free_buf = pkt_hdr; -+ -+ goto pkt_drop; -+ } -+ -+ /* Check to valid queue number */ -+ if (hif->client[hif->client_id].rx_qn <= hif->qno) { -+ pr_info("%s: packet with invalid queue: %d\n" -+ , __func__, hif->qno); -+ hif->qno = 0; -+ } -+ -+ free_buf = -+ client_put_rxpacket(&hif->client[hif->client_id].rx_q[hif->qno], -+ (void *)pkt_hdr, len, flags, -+ hif->client_ctrl, &buf_size); -+ -+ hif_lib_indicate_client(hif->client_id, EVENT_RX_PKT_IND, -+ hif->qno); -+ -+ if (unlikely(!free_buf)) { -+#ifdef HIF_NAPI_STATS -+ hif->napi_counters[NAPI_CLIENT_FULL_COUNT]++; -+#endif -+ /* -+ * If we want to keep in polling mode to retry later, -+ * we need to tell napi that we consumed -+ * the full budget or we will hit a livelock scenario. -+ * The core code keeps this napi instance -+ * at the head of the list and none of the other -+ * instances get to run -+ */ -+ rx_processed = budget; -+ -+ if (flags & CL_DESC_FIRST) -+ hif->started = 0; -+ -+ break; -+ } -+ -+pkt_drop: -+ /*Fill free buffer in the descriptor */ -+ hif->rx_buf_addr[rtc] = free_buf; -+ hif->rx_buf_len[rtc] = min(pfe_pkt_size, buf_size); -+ writel((DDR_PHYS_TO_PFE -+ ((u32)dma_map_single(hif->dev, -+ free_buf, hif->rx_buf_len[rtc], DMA_FROM_DEVICE))), -+ &desc->data); -+ /* -+ * Ensure everything else is written to DDR before -+ * writing bd->ctrl -+ */ -+ wmb(); -+ writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM | BD_CTRL_DIR | -+ BD_CTRL_DESC_EN | BD_BUF_LEN(hif->rx_buf_len[rtc])), -+ &desc->ctrl); -+ -+ rtc = (rtc + 1) & (hif->rx_ring_size - 1); -+ -+ if (local_desc.ctrl & BD_CTRL_LIFM) { -+ if (!(hif->client_ctrl & HIF_CTRL_RX_CONTINUED)) { -+ rx_processed++; -+ -+#ifdef HIF_NAPI_STATS -+ hif->napi_counters[NAPI_PACKET_COUNT]++; -+#endif -+ } -+ hif->started = 0; -+ } -+ } -+ -+ hif->rxtoclean_index = rtc; -+ spin_unlock_bh(&hif->lock); -+ -+ /* we made some progress, re-start rx dma in case it stopped */ -+ hif_rx_dma_start(); -+ -+ return rx_processed; -+} -+ -+/* -+ * client_ack_txpacket- -+ * This function ack the Tx packet in the give client Tx queue by resetting -+ * ownership bit in the descriptor. -+ */ -+static int client_ack_txpacket(struct pfe_hif *hif, unsigned int client_id, -+ unsigned int q_no) -+{ -+ struct hif_tx_queue *queue = &hif->client[client_id].tx_q[q_no]; -+ struct tx_queue_desc *desc = queue->base + queue->ack_idx; -+ -+ if (readl(&desc->ctrl) & CL_DESC_OWN) { -+ writel((readl(&desc->ctrl) & ~CL_DESC_OWN), &desc->ctrl); -+ /* queue->ack_idx = (queue->ack_idx + 1) & (queue->size - 1); */ -+ -+ return 0; -+ -+ } else { -+ /*This should not happen */ -+ pr_err("%s: %d %d %d %d %d %p %d\n", __func__, -+ hif->txtosend, hif->txtoclean, hif->txavail, -+ client_id, q_no, queue, queue->ack_idx); -+ WARN(1, "%s: doesn't own this descriptor", __func__); -+ return 1; -+ } -+} -+ -+void __hif_tx_done_process(struct pfe_hif *hif, int count) -+{ -+ struct hif_desc *desc; -+ struct hif_desc_sw *desc_sw; -+ int ttc, tx_avl; -+ int pkts_done[HIF_CLIENTS_MAX] = {0, 0}; -+ -+ ttc = hif->txtoclean; -+ tx_avl = hif->txavail; -+ -+ while ((tx_avl < hif->tx_ring_size) && count--) { -+ desc = hif->tx_base + ttc; -+ -+ if (readl(&desc->ctrl) & BD_CTRL_DESC_EN) -+ break; -+ -+ desc_sw = &hif->tx_sw_queue[ttc]; -+ -+ if (desc_sw->data) { -+ /* -+ * dmap_unmap_single(hif->dev, desc_sw->data, -+ * desc_sw->len, DMA_TO_DEVICE); -+ */ -+ dma_unmap_single(hif->dev, desc_sw->data, -+ desc_sw->len, DMA_TO_DEVICE); -+ } -+ -+ if (desc_sw->client_id > HIF_CLIENTS_MAX) -+ pr_err("Invalid cl id %d\n", desc_sw->client_id); -+ -+ pkts_done[desc_sw->client_id]++; -+ -+ client_ack_txpacket(hif, desc_sw->client_id, desc_sw->q_no); -+ -+ ttc = (ttc + 1) & (hif->tx_ring_size - 1); -+ tx_avl++; -+ } -+ -+ if (pkts_done[0]) -+ hif_lib_indicate_client(0, EVENT_TXDONE_IND, 0); -+ if (pkts_done[1]) -+ hif_lib_indicate_client(1, EVENT_TXDONE_IND, 0); -+ -+ hif->txtoclean = ttc; -+ hif->txavail = tx_avl; -+ -+ if (!count) { -+ tasklet_schedule(&hif->tx_cleanup_tasklet); -+ } else { -+ /*Enable Tx done interrupt */ -+ writel(readl_relaxed(HIF_INT_ENABLE) | HIF_TXPKT_INT, -+ HIF_INT_ENABLE); -+ } -+} -+ -+static void pfe_tx_do_cleanup(unsigned long data) -+{ -+ struct pfe_hif *hif = (struct pfe_hif *)data; -+ -+ writel(HIF_INT | HIF_TXPKT_INT, HIF_INT_SRC); -+ -+ hif_tx_done_process(hif, 64); -+} -+ -+/* -+ * __hif_xmit_pkt - -+ * This function puts one packet in the HIF Tx queue -+ */ -+void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int -+ q_no, void *data, u32 len, unsigned int flags) -+{ -+ struct hif_desc *desc; -+ struct hif_desc_sw *desc_sw; -+ -+ desc = hif->tx_base + hif->txtosend; -+ desc_sw = &hif->tx_sw_queue[hif->txtosend]; -+ -+ desc_sw->len = len; -+ desc_sw->client_id = client_id; -+ desc_sw->q_no = q_no; -+ desc_sw->flags = flags; -+ -+ if (flags & HIF_DONT_DMA_MAP) { -+ desc_sw->data = 0; -+ writel((u32)DDR_PHYS_TO_PFE(data), &desc->data); -+ } else { -+ desc_sw->data = dma_map_single(hif->dev, data, len, -+ DMA_TO_DEVICE); -+ writel((u32)DDR_PHYS_TO_PFE(desc_sw->data), &desc->data); -+ } -+ -+ hif->txtosend = (hif->txtosend + 1) & (hif->tx_ring_size - 1); -+ hif->txavail--; -+ -+ if ((!((flags & HIF_DATA_VALID) && (flags & -+ HIF_LAST_BUFFER)))) -+ goto skip_tx; -+ -+ /* -+ * Ensure everything else is written to DDR before -+ * writing bd->ctrl -+ */ -+ wmb(); -+ -+ do { -+ desc_sw = &hif->tx_sw_queue[hif->txtoflush]; -+ desc = hif->tx_base + hif->txtoflush; -+ -+ if (desc_sw->flags & HIF_LAST_BUFFER) { -+ writel((BD_CTRL_LIFM | -+ BD_CTRL_BRFETCH_DISABLE | BD_CTRL_RTFETCH_DISABLE -+ | BD_CTRL_PARSE_DISABLE | BD_CTRL_DESC_EN | -+ BD_CTRL_PKT_INT_EN | BD_BUF_LEN(desc_sw->len)), -+ &desc->ctrl); -+ } else { -+ writel((BD_CTRL_DESC_EN | -+ BD_BUF_LEN(desc_sw->len)), &desc->ctrl); -+ } -+ hif->txtoflush = (hif->txtoflush + 1) & (hif->tx_ring_size - 1); -+ } -+ while (hif->txtoflush != hif->txtosend) -+ ; -+ -+skip_tx: -+ return; -+} -+ -+int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no, -+ void *data, unsigned int len) -+{ -+ int rc = 0; -+ -+ spin_lock_bh(&hif->tx_lock); -+ -+ if (!hif->txavail) { -+ rc = 1; -+ } else { -+ __hif_xmit_pkt(hif, client_id, q_no, data, len, -+ HIF_FIRST_BUFFER | HIF_LAST_BUFFER); -+ hif_tx_dma_start(); -+ } -+ -+ if (hif->txavail < (hif->tx_ring_size >> 1)) -+ __hif_tx_done_process(hif, TX_FREE_MAX_COUNT); -+ -+ spin_unlock_bh(&hif->tx_lock); -+ -+ return rc; -+} -+ -+static irqreturn_t wol_isr(int irq, void *dev_id) -+{ -+ pr_info("WoL\n"); -+ gemac_set_wol(EMAC1_BASE_ADDR, 0); -+ gemac_set_wol(EMAC2_BASE_ADDR, 0); -+ return IRQ_HANDLED; -+} -+ -+/* -+ * hif_isr- -+ * This ISR routine processes Rx/Tx done interrupts from the HIF hardware block -+ */ -+static irqreturn_t hif_isr(int irq, void *dev_id) -+{ -+ struct pfe_hif *hif = (struct pfe_hif *)dev_id; -+ int int_status; -+ int int_enable_mask; -+ -+ /*Read hif interrupt source register */ -+ int_status = readl_relaxed(HIF_INT_SRC); -+ int_enable_mask = readl_relaxed(HIF_INT_ENABLE); -+ -+ if ((int_status & HIF_INT) == 0) -+ return IRQ_NONE; -+ -+ int_status &= ~(HIF_INT); -+ -+ if (int_status & HIF_RXPKT_INT) { -+ int_status &= ~(HIF_RXPKT_INT); -+ int_enable_mask &= ~(HIF_RXPKT_INT); -+ -+ napi_first_batch = 1; -+ -+ if (napi_schedule_prep(&hif->napi)) { -+#ifdef HIF_NAPI_STATS -+ hif->napi_counters[NAPI_SCHED_COUNT]++; -+#endif -+ __napi_schedule(&hif->napi); -+ } -+ } -+ if (int_status & HIF_TXPKT_INT) { -+ int_status &= ~(HIF_TXPKT_INT); -+ int_enable_mask &= ~(HIF_TXPKT_INT); -+ /*Schedule tx cleanup tassklet */ -+ tasklet_schedule(&hif->tx_cleanup_tasklet); -+ } -+ -+ /*Disable interrupts, they will be enabled after they are serviced */ -+ writel_relaxed(int_enable_mask, HIF_INT_ENABLE); -+ -+ if (int_status) { -+ pr_info("%s : Invalid interrupt : %d\n", __func__, -+ int_status); -+ writel(int_status, HIF_INT_SRC); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int data2) -+{ -+ unsigned int client_id = data1; -+ -+ if (client_id >= HIF_CLIENTS_MAX) { -+ pr_err("%s: client id %d out of bounds\n", __func__, -+ client_id); -+ return; -+ } -+ -+ switch (req) { -+ case REQUEST_CL_REGISTER: -+ /* Request for register a client */ -+ pr_info("%s: register client_id %d\n", -+ __func__, client_id); -+ pfe_hif_client_register(hif, client_id, (struct -+ hif_client_shm *)&hif->shm->client[client_id]); -+ break; -+ -+ case REQUEST_CL_UNREGISTER: -+ pr_info("%s: unregister client_id %d\n", -+ __func__, client_id); -+ -+ /* Request for unregister a client */ -+ pfe_hif_client_unregister(hif, client_id); -+ -+ break; -+ -+ default: -+ pr_err("%s: unsupported request %d\n", -+ __func__, req); -+ break; -+ } -+ -+ /* -+ * Process client Tx queues -+ * Currently we don't have checking for tx pending -+ */ -+} -+ -+/* -+ * pfe_hif_rx_poll -+ * This function is NAPI poll function to process HIF Rx queue. -+ */ -+static int pfe_hif_rx_poll(struct napi_struct *napi, int budget) -+{ -+ struct pfe_hif *hif = container_of(napi, struct pfe_hif, napi); -+ int work_done; -+ -+#ifdef HIF_NAPI_STATS -+ hif->napi_counters[NAPI_POLL_COUNT]++; -+#endif -+ -+ work_done = pfe_hif_rx_process(hif, budget); -+ -+ if (work_done < budget) { -+ napi_complete(napi); -+ writel(readl_relaxed(HIF_INT_ENABLE) | HIF_RXPKT_INT, -+ HIF_INT_ENABLE); -+ } -+#ifdef HIF_NAPI_STATS -+ else -+ hif->napi_counters[NAPI_FULL_BUDGET_COUNT]++; -+#endif -+ -+ return work_done; -+} -+ -+/* -+ * pfe_hif_init -+ * This function initializes the baseaddresses and irq, etc. -+ */ -+int pfe_hif_init(struct pfe *pfe) -+{ -+ struct pfe_hif *hif = &pfe->hif; -+ int err; -+ -+ pr_info("%s\n", __func__); -+ -+ hif->dev = pfe->dev; -+ hif->irq = pfe->hif_irq; -+ -+ err = pfe_hif_alloc_descr(hif); -+ if (err) -+ goto err0; -+ -+ if (pfe_hif_init_buffers(hif)) { -+ pr_err("%s: Could not initialize buffer descriptors\n" -+ , __func__); -+ err = -ENOMEM; -+ goto err1; -+ } -+ -+ /* Initialize NAPI for Rx processing */ -+ init_dummy_netdev(&hif->dummy_dev); -+ netif_napi_add(&hif->dummy_dev, &hif->napi, pfe_hif_rx_poll, -+ HIF_RX_POLL_WEIGHT); -+ napi_enable(&hif->napi); -+ -+ spin_lock_init(&hif->tx_lock); -+ spin_lock_init(&hif->lock); -+ -+ hif_init(); -+ hif_rx_enable(); -+ hif_tx_enable(); -+ -+ /* Disable tx done interrupt */ -+ writel(HIF_INT_MASK, HIF_INT_ENABLE); -+ -+ gpi_enable(HGPI_BASE_ADDR); -+ -+ err = request_irq(hif->irq, hif_isr, 0, "pfe_hif", hif); -+ if (err) { -+ pr_err("%s: failed to get the hif IRQ = %d\n", -+ __func__, hif->irq); -+ goto err1; -+ } -+ -+ err = request_irq(pfe->wol_irq, wol_isr, 0, "pfe_wol", pfe); -+ if (err) { -+ pr_err("%s: failed to get the wol IRQ = %d\n", -+ __func__, pfe->wol_irq); -+ goto err1; -+ } -+ -+ tasklet_init(&hif->tx_cleanup_tasklet, -+ (void(*)(unsigned long))pfe_tx_do_cleanup, -+ (unsigned long)hif); -+ -+ return 0; -+err1: -+ pfe_hif_free_descr(hif); -+err0: -+ return err; -+} -+ -+/* pfe_hif_exit- */ -+void pfe_hif_exit(struct pfe *pfe) -+{ -+ struct pfe_hif *hif = &pfe->hif; -+ -+ pr_info("%s\n", __func__); -+ -+ tasklet_kill(&hif->tx_cleanup_tasklet); -+ -+ spin_lock_bh(&hif->lock); -+ hif->shm->g_client_status[0] = 0; -+ /* Make sure all clients are disabled*/ -+ hif->shm->g_client_status[1] = 0; -+ -+ spin_unlock_bh(&hif->lock); -+ -+ /*Disable Rx/Tx */ -+ gpi_disable(HGPI_BASE_ADDR); -+ hif_rx_disable(); -+ hif_tx_disable(); -+ -+ napi_disable(&hif->napi); -+ netif_napi_del(&hif->napi); -+ -+ free_irq(pfe->wol_irq, pfe); -+ free_irq(hif->irq, hif); -+ -+ pfe_hif_release_buffers(hif); -+ pfe_hif_free_descr(hif); -+} ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c -@@ -0,0 +1,638 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "pfe_mod.h" -+#include "pfe_hif.h" -+#include "pfe_hif_lib.h" -+ -+unsigned int lro_mode; -+unsigned int page_mode; -+unsigned int tx_qos; -+unsigned int pfe_pkt_size; -+unsigned int pfe_pkt_headroom; -+unsigned int emac_txq_cnt; -+ -+/* -+ * @pfe_hal_lib.c. -+ * Common functions used by HIF client drivers -+ */ -+ -+/*HIF shared memory Global variable */ -+struct hif_shm ghif_shm; -+ -+/* Cleanup the HIF shared memory, release HIF rx_buffer_pool. -+ * This function should be called after pfe_hif_exit -+ * -+ * @param[in] hif_shm Shared memory address location in DDR -+ */ -+static void pfe_hif_shm_clean(struct hif_shm *hif_shm) -+{ -+ int i; -+ void *pkt; -+ -+ for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) { -+ pkt = hif_shm->rx_buf_pool[i]; -+ if (pkt) { -+ hif_shm->rx_buf_pool[i] = NULL; -+ pkt -= pfe_pkt_headroom; -+ -+ if (page_mode) -+ put_page(virt_to_page(pkt)); -+ else -+ kfree(pkt); -+ } -+ } -+} -+ -+/* Initialize shared memory used between HIF driver and clients, -+ * allocate rx_buffer_pool required for HIF Rx descriptors. -+ * This function should be called before initializing HIF driver. -+ * -+ * @param[in] hif_shm Shared memory address location in DDR -+ * @rerurn 0 - on succes, <0 on fail to initialize -+ */ -+static int pfe_hif_shm_init(struct hif_shm *hif_shm) -+{ -+ int i; -+ void *pkt; -+ -+ memset(hif_shm, 0, sizeof(struct hif_shm)); -+ hif_shm->rx_buf_pool_cnt = HIF_RX_DESC_NT; -+ -+ for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) { -+ if (page_mode) { -+ pkt = (void *)__get_free_page(GFP_KERNEL | -+ GFP_DMA_PFE); -+ } else { -+ pkt = kmalloc(PFE_BUF_SIZE, GFP_KERNEL | GFP_DMA_PFE); -+ } -+ -+ if (pkt) -+ hif_shm->rx_buf_pool[i] = pkt + pfe_pkt_headroom; -+ else -+ goto err0; -+ } -+ -+ return 0; -+ -+err0: -+ pr_err("%s Low memory\n", __func__); -+ pfe_hif_shm_clean(hif_shm); -+ return -ENOMEM; -+} -+ -+/*This function sends indication to HIF driver -+ * -+ * @param[in] hif hif context -+ */ -+static void hif_lib_indicate_hif(struct pfe_hif *hif, int req, int data1, int -+ data2) -+{ -+ hif_process_client_req(hif, req, data1, data2); -+} -+ -+void hif_lib_indicate_client(int client_id, int event_type, int qno) -+{ -+ struct hif_client_s *client = pfe->hif_client[client_id]; -+ -+ if (!client || (event_type >= HIF_EVENT_MAX) || (qno >= -+ HIF_CLIENT_QUEUES_MAX)) -+ return; -+ -+ if (!test_and_set_bit(qno, &client->queue_mask[event_type])) -+ client->event_handler(client->priv, event_type, qno); -+} -+ -+/*This function releases Rx queue descriptors memory and pre-filled buffers -+ * -+ * @param[in] client hif_client context -+ */ -+static void hif_lib_client_release_rx_buffers(struct hif_client_s *client) -+{ -+ struct rx_queue_desc *desc; -+ int qno, ii; -+ void *buf; -+ -+ for (qno = 0; qno < client->rx_qn; qno++) { -+ desc = client->rx_q[qno].base; -+ -+ for (ii = 0; ii < client->rx_q[qno].size; ii++) { -+ buf = (void *)desc->data; -+ if (buf) { -+ buf -= pfe_pkt_headroom; -+ -+ if (page_mode) -+ free_page((unsigned long)buf); -+ else -+ kfree(buf); -+ -+ desc->ctrl = 0; -+ } -+ -+ desc++; -+ } -+ } -+ -+ kfree(client->rx_qbase); -+} -+ -+/*This function allocates memory for the rxq descriptors and pre-fill rx queues -+ * with buffers. -+ * @param[in] client client context -+ * @param[in] q_size size of the rxQ, all queues are of same size -+ */ -+static int hif_lib_client_init_rx_buffers(struct hif_client_s *client, int -+ q_size) -+{ -+ struct rx_queue_desc *desc; -+ struct hif_client_rx_queue *queue; -+ int ii, qno; -+ -+ /*Allocate memory for the client queues */ -+ client->rx_qbase = kzalloc(client->rx_qn * q_size * sizeof(struct -+ rx_queue_desc), GFP_KERNEL); -+ if (!client->rx_qbase) -+ goto err; -+ -+ for (qno = 0; qno < client->rx_qn; qno++) { -+ queue = &client->rx_q[qno]; -+ -+ queue->base = client->rx_qbase + qno * q_size * sizeof(struct -+ rx_queue_desc); -+ queue->size = q_size; -+ queue->read_idx = 0; -+ queue->write_idx = 0; -+ -+ pr_debug("rx queue: %d, base: %p, size: %d\n", qno, -+ queue->base, queue->size); -+ } -+ -+ for (qno = 0; qno < client->rx_qn; qno++) { -+ queue = &client->rx_q[qno]; -+ desc = queue->base; -+ -+ for (ii = 0; ii < queue->size; ii++) { -+ desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) | -+ CL_DESC_OWN; -+ desc++; -+ } -+ } -+ -+ return 0; -+ -+err: -+ return 1; -+} -+ -+#define inc_cl_idx(idxname) \ -+ ({ typeof(idxname) idxname_ = (idxname); \ -+ ((idxname_) = (idxname_ + 1) & (queue->size - 1)); }) -+ -+static void hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue) -+{ -+ pr_debug("%s\n", __func__); -+ -+ /* -+ * Check if there are any pending packets. Client must flush the tx -+ * queues before unregistering, by calling by calling -+ * hif_lib_tx_get_next_complete() -+ * -+ * Hif no longer calls since we are no longer registered -+ */ -+ if (queue->tx_pending) -+ pr_err("%s: pending transmit packets\n", __func__); -+} -+ -+static void hif_lib_client_release_tx_buffers(struct hif_client_s *client) -+{ -+ int qno; -+ -+ pr_debug("%s\n", __func__); -+ -+ for (qno = 0; qno < client->tx_qn; qno++) -+ hif_lib_client_cleanup_tx_queue(&client->tx_q[qno]); -+ -+ kfree(client->tx_qbase); -+} -+ -+static int hif_lib_client_init_tx_buffers(struct hif_client_s *client, int -+ q_size) -+{ -+ struct hif_client_tx_queue *queue; -+ int qno; -+ -+ client->tx_qbase = kzalloc(client->tx_qn * q_size * sizeof(struct -+ tx_queue_desc), GFP_KERNEL); -+ if (!client->tx_qbase) -+ return 1; -+ -+ for (qno = 0; qno < client->tx_qn; qno++) { -+ queue = &client->tx_q[qno]; -+ -+ queue->base = client->tx_qbase + qno * q_size * sizeof(struct -+ tx_queue_desc); -+ queue->size = q_size; -+ queue->read_idx = 0; -+ queue->write_idx = 0; -+ queue->tx_pending = 0; -+ queue->nocpy_flag = 0; -+ queue->prev_tmu_tx_pkts = 0; -+ queue->done_tmu_tx_pkts = 0; -+ -+ pr_debug("tx queue: %d, base: %p, size: %d\n", qno, -+ queue->base, queue->size); -+ } -+ -+ return 0; -+} -+ -+static int hif_lib_event_dummy(void *priv, int event_type, int qno) -+{ -+ return 0; -+} -+ -+int hif_lib_client_register(struct hif_client_s *client) -+{ -+ struct hif_shm *hif_shm; -+ struct hif_client_shm *client_shm; -+ int err, i; -+ /* int loop_cnt = 0; */ -+ -+ pr_debug("%s\n", __func__); -+ -+ /*Allocate memory before spin_lock*/ -+ if (hif_lib_client_init_rx_buffers(client, client->rx_qsize)) { -+ err = -ENOMEM; -+ goto err_rx; -+ } -+ -+ if (hif_lib_client_init_tx_buffers(client, client->tx_qsize)) { -+ err = -ENOMEM; -+ goto err_tx; -+ } -+ -+ spin_lock_bh(&pfe->hif.lock); -+ if (!(client->pfe) || (client->id >= HIF_CLIENTS_MAX) || -+ (pfe->hif_client[client->id])) { -+ err = -EINVAL; -+ goto err; -+ } -+ -+ hif_shm = client->pfe->hif.shm; -+ -+ if (!client->event_handler) -+ client->event_handler = hif_lib_event_dummy; -+ -+ /*Initialize client specific shared memory */ -+ client_shm = (struct hif_client_shm *)&hif_shm->client[client->id]; -+ client_shm->rx_qbase = (unsigned long int)client->rx_qbase; -+ client_shm->rx_qsize = client->rx_qsize; -+ client_shm->tx_qbase = (unsigned long int)client->tx_qbase; -+ client_shm->tx_qsize = client->tx_qsize; -+ client_shm->ctrl = (client->tx_qn << CLIENT_CTRL_TX_Q_CNT_OFST) | -+ (client->rx_qn << CLIENT_CTRL_RX_Q_CNT_OFST); -+ /* spin_lock_init(&client->rx_lock); */ -+ -+ for (i = 0; i < HIF_EVENT_MAX; i++) { -+ client->queue_mask[i] = 0; /* -+ * By default all events are -+ * unmasked -+ */ -+ } -+ -+ /*Indicate to HIF driver*/ -+ hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_REGISTER, client->id, 0); -+ -+ pr_debug("%s: client: %p, client_id: %d, tx_qsize: %d, rx_qsize: %d\n", -+ __func__, client, client->id, client->tx_qsize, -+ client->rx_qsize); -+ -+ client->cpu_id = -1; -+ -+ pfe->hif_client[client->id] = client; -+ spin_unlock_bh(&pfe->hif.lock); -+ -+ return 0; -+ -+err: -+ spin_unlock_bh(&pfe->hif.lock); -+ hif_lib_client_release_tx_buffers(client); -+ -+err_tx: -+ hif_lib_client_release_rx_buffers(client); -+ -+err_rx: -+ return err; -+} -+ -+int hif_lib_client_unregister(struct hif_client_s *client) -+{ -+ struct pfe *pfe = client->pfe; -+ u32 client_id = client->id; -+ -+ pr_info( -+ "%s : client: %p, client_id: %d, txQ_depth: %d, rxQ_depth: %d\n" -+ , __func__, client, client->id, client->tx_qsize, -+ client->rx_qsize); -+ -+ spin_lock_bh(&pfe->hif.lock); -+ hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_UNREGISTER, client->id, 0); -+ -+ hif_lib_client_release_tx_buffers(client); -+ hif_lib_client_release_rx_buffers(client); -+ pfe->hif_client[client_id] = NULL; -+ spin_unlock_bh(&pfe->hif.lock); -+ -+ return 0; -+} -+ -+int hif_lib_event_handler_start(struct hif_client_s *client, int event, -+ int qno) -+{ -+ struct hif_client_rx_queue *queue = &client->rx_q[qno]; -+ struct rx_queue_desc *desc = queue->base + queue->read_idx; -+ -+ if ((event >= HIF_EVENT_MAX) || (qno >= HIF_CLIENT_QUEUES_MAX)) { -+ pr_debug("%s: Unsupported event : %d queue number : %d\n", -+ __func__, event, qno); -+ return -1; -+ } -+ -+ test_and_clear_bit(qno, &client->queue_mask[event]); -+ -+ switch (event) { -+ case EVENT_RX_PKT_IND: -+ if (!(desc->ctrl & CL_DESC_OWN)) -+ hif_lib_indicate_client(client->id, -+ EVENT_RX_PKT_IND, qno); -+ break; -+ -+ case EVENT_HIGH_RX_WM: -+ case EVENT_TXDONE_IND: -+ default: -+ break; -+ } -+ -+ return 0; -+} -+ -+/* -+ * This function gets one packet from the specified client queue -+ * It also refill the rx buffer -+ */ -+void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int -+ *ofst, unsigned int *rx_ctrl, -+ unsigned int *desc_ctrl, void **priv_data) -+{ -+ struct hif_client_rx_queue *queue = &client->rx_q[qno]; -+ struct rx_queue_desc *desc; -+ void *pkt = NULL; -+ -+ /* -+ * Following lock is to protect rx queue access from, -+ * hif_lib_event_handler_start. -+ * In general below lock is not required, because hif_lib_xmit_pkt and -+ * hif_lib_event_handler_start are called from napi poll and which is -+ * not re-entrant. But if some client use in different way this lock is -+ * required. -+ */ -+ /*spin_lock_irqsave(&client->rx_lock, flags); */ -+ desc = queue->base + queue->read_idx; -+ if (!(desc->ctrl & CL_DESC_OWN)) { -+ pkt = desc->data - pfe_pkt_headroom; -+ -+ *rx_ctrl = desc->client_ctrl; -+ *desc_ctrl = desc->ctrl; -+ -+ if (desc->ctrl & CL_DESC_FIRST) { -+ u16 size = *rx_ctrl >> HIF_CTRL_RX_OFFSET_OFST; -+ -+ if (size) { -+ *len = CL_DESC_BUF_LEN(desc->ctrl) - -+ PFE_PKT_HEADER_SZ - size; -+ *ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ -+ + size; -+ *priv_data = desc->data + PFE_PKT_HEADER_SZ; -+ } else { -+ *len = CL_DESC_BUF_LEN(desc->ctrl) - -+ PFE_PKT_HEADER_SZ; -+ *ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ; -+ *priv_data = NULL; -+ } -+ -+ } else { -+ *len = CL_DESC_BUF_LEN(desc->ctrl); -+ *ofst = pfe_pkt_headroom; -+ } -+ -+ /* -+ * Needed so we don't free a buffer/page -+ * twice on module_exit -+ */ -+ desc->data = NULL; -+ -+ /* -+ * Ensure everything else is written to DDR before -+ * writing bd->ctrl -+ */ -+ smp_wmb(); -+ -+ desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) | CL_DESC_OWN; -+ inc_cl_idx(queue->read_idx); -+ } -+ -+ /*spin_unlock_irqrestore(&client->rx_lock, flags); */ -+ return pkt; -+} -+ -+static inline void hif_hdr_write(struct hif_hdr *pkt_hdr, unsigned int -+ client_id, unsigned int qno, -+ u32 client_ctrl) -+{ -+ /* Optimize the write since the destinaton may be non-cacheable */ -+ if (!((unsigned long)pkt_hdr & 0x3)) { -+ ((u32 *)pkt_hdr)[0] = (client_ctrl << 16) | (qno << 8) | -+ client_id; -+ } else { -+ ((u16 *)pkt_hdr)[0] = (qno << 8) | (client_id & 0xFF); -+ ((u16 *)pkt_hdr)[1] = (client_ctrl & 0xFFFF); -+ } -+} -+ -+/*This function puts the given packet in the specific client queue */ -+void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void -+ *data, unsigned int len, u32 client_ctrl, -+ unsigned int flags, void *client_data) -+{ -+ struct hif_client_tx_queue *queue = &client->tx_q[qno]; -+ struct tx_queue_desc *desc = queue->base + queue->write_idx; -+ -+ /* First buffer */ -+ if (flags & HIF_FIRST_BUFFER) { -+ data -= sizeof(struct hif_hdr); -+ len += sizeof(struct hif_hdr); -+ -+ hif_hdr_write(data, client->id, qno, client_ctrl); -+ } -+ -+ desc->data = client_data; -+ desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(flags); -+ -+ __hif_xmit_pkt(&pfe->hif, client->id, qno, data, len, flags); -+ -+ inc_cl_idx(queue->write_idx); -+ queue->tx_pending++; -+ queue->jiffies_last_packet = jiffies; -+} -+ -+/*This function puts the given packet in the specific client queue */ -+int hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data, -+ unsigned int len, u32 client_ctrl, void *client_data) -+{ -+ struct hif_client_tx_queue *queue = &client->tx_q[qno]; -+ struct tx_queue_desc *desc = queue->base + queue->write_idx; -+ -+ if (queue->tx_pending < queue->size) { -+ /*Construct pkt header */ -+ -+ data -= sizeof(struct hif_hdr); -+ len += sizeof(struct hif_hdr); -+ -+ hif_hdr_write(data, client->id, qno, client_ctrl); -+ -+ desc->data = client_data; -+ desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(HIF_FIRST_BUFFER | -+ HIF_LAST_BUFFER | HIF_DATA_VALID); -+ -+ if (hif_xmit_pkt(&pfe->hif, client->id, qno, data, len)) -+ return 1; -+ -+ inc_cl_idx(queue->write_idx); -+ queue->tx_pending++; -+ queue->jiffies_last_packet = jiffies; -+ -+ return 0; -+ } -+ -+ pr_debug("%s Tx client %d qno %d is full\n", __func__, client->id, -+ qno); -+ return 1; -+} -+ -+void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, -+ unsigned int *flags, int count) -+{ -+ struct hif_client_tx_queue *queue = &client->tx_q[qno]; -+ struct tx_queue_desc *desc = queue->base + queue->read_idx; -+ -+ pr_debug("%s: qno : %d rd_indx: %d pending:%d\n", __func__, qno, -+ queue->read_idx, queue->tx_pending); -+ -+ if (!queue->tx_pending) -+ return NULL; -+ -+ if (queue->nocpy_flag && !queue->done_tmu_tx_pkts) { -+ u32 tmu_tx_pkts = be32_to_cpu(pe_dmem_read(TMU0_ID + -+ client->id, TMU_DM_TX_TRANS, 4)); -+ -+ if (queue->prev_tmu_tx_pkts > tmu_tx_pkts) -+ queue->done_tmu_tx_pkts = UINT_MAX - -+ queue->prev_tmu_tx_pkts + tmu_tx_pkts; -+ else -+ queue->done_tmu_tx_pkts = tmu_tx_pkts - -+ queue->prev_tmu_tx_pkts; -+ -+ queue->prev_tmu_tx_pkts = tmu_tx_pkts; -+ -+ if (!queue->done_tmu_tx_pkts) -+ return NULL; -+ } -+ -+ if (desc->ctrl & CL_DESC_OWN) -+ return NULL; -+ -+ inc_cl_idx(queue->read_idx); -+ queue->tx_pending--; -+ -+ *flags = CL_DESC_GET_FLAGS(desc->ctrl); -+ -+ if (queue->done_tmu_tx_pkts && (*flags & HIF_LAST_BUFFER)) -+ queue->done_tmu_tx_pkts--; -+ -+ return desc->data; -+} -+ -+static void hif_lib_tmu_credit_init(struct pfe *pfe) -+{ -+ int i, q; -+ -+ for (i = 0; i < NUM_GEMAC_SUPPORT; i++) -+ for (q = 0; q < emac_txq_cnt; q++) { -+ pfe->tmu_credit.tx_credit_max[i][q] = (q == 0) ? -+ DEFAULT_Q0_QDEPTH : DEFAULT_MAX_QDEPTH; -+ pfe->tmu_credit.tx_credit[i][q] = -+ pfe->tmu_credit.tx_credit_max[i][q]; -+ } -+} -+ -+int pfe_hif_lib_init(struct pfe *pfe) -+{ -+ int rc; -+ -+ pr_info("%s\n", __func__); -+ -+ if (lro_mode) { -+ page_mode = 1; -+ pfe_pkt_size = min(PAGE_SIZE, MAX_PFE_PKT_SIZE); -+ pfe_pkt_headroom = 0; -+ } else { -+ page_mode = 0; -+ pfe_pkt_size = PFE_PKT_SIZE; -+ pfe_pkt_headroom = PFE_PKT_HEADROOM; -+ } -+ -+ if (tx_qos) -+ emac_txq_cnt = EMAC_TXQ_CNT / 2; -+ else -+ emac_txq_cnt = EMAC_TXQ_CNT; -+ -+ hif_lib_tmu_credit_init(pfe); -+ pfe->hif.shm = &ghif_shm; -+ rc = pfe_hif_shm_init(pfe->hif.shm); -+ -+ return rc; -+} -+ -+void pfe_hif_lib_exit(struct pfe *pfe) -+{ -+ pr_info("%s\n", __func__); -+ -+ pfe_hif_shm_clean(pfe->hif.shm); -+} ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_hw.c -@@ -0,0 +1,176 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include "pfe_mod.h" -+#include "pfe_hw.h" -+ -+/* Functions to handle most of pfe hw register initialization */ -+int pfe_hw_init(struct pfe *pfe, int resume) -+{ -+ struct class_cfg class_cfg = { -+ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO, -+ .route_table_baseaddr = pfe->ddr_phys_baseaddr + -+ ROUTE_TABLE_BASEADDR, -+ .route_table_hash_bits = ROUTE_TABLE_HASH_BITS, -+ }; -+ -+ struct tmu_cfg tmu_cfg = { -+ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO, -+ .llm_base_addr = pfe->ddr_phys_baseaddr + TMU_LLM_BASEADDR, -+ .llm_queue_len = TMU_LLM_QUEUE_LEN, -+ }; -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ struct util_cfg util_cfg = { -+ .pe_sys_clk_ratio = PE_SYS_CLK_RATIO, -+ }; -+#endif -+ -+ struct BMU_CFG bmu1_cfg = { -+ .baseaddr = CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR + -+ BMU1_LMEM_BASEADDR), -+ .count = BMU1_BUF_COUNT, -+ .size = BMU1_BUF_SIZE, -+ .low_watermark = 10, -+ .high_watermark = 15, -+ }; -+ -+ struct BMU_CFG bmu2_cfg = { -+ .baseaddr = DDR_PHYS_TO_PFE(pfe->ddr_phys_baseaddr + -+ BMU2_DDR_BASEADDR), -+ .count = BMU2_BUF_COUNT, -+ .size = BMU2_BUF_SIZE, -+ .low_watermark = 250, -+ .high_watermark = 253, -+ }; -+ -+ struct gpi_cfg egpi1_cfg = { -+ .lmem_rtry_cnt = EGPI1_LMEM_RTRY_CNT, -+ .tmlf_txthres = EGPI1_TMLF_TXTHRES, -+ .aseq_len = EGPI1_ASEQ_LEN, -+ .mtip_pause_reg = CBUS_VIRT_TO_PFE(EMAC1_BASE_ADDR + -+ EMAC_TCNTRL_REG), -+ }; -+ -+ struct gpi_cfg egpi2_cfg = { -+ .lmem_rtry_cnt = EGPI2_LMEM_RTRY_CNT, -+ .tmlf_txthres = EGPI2_TMLF_TXTHRES, -+ .aseq_len = EGPI2_ASEQ_LEN, -+ .mtip_pause_reg = CBUS_VIRT_TO_PFE(EMAC2_BASE_ADDR + -+ EMAC_TCNTRL_REG), -+ }; -+ -+ struct gpi_cfg hgpi_cfg = { -+ .lmem_rtry_cnt = HGPI_LMEM_RTRY_CNT, -+ .tmlf_txthres = HGPI_TMLF_TXTHRES, -+ .aseq_len = HGPI_ASEQ_LEN, -+ .mtip_pause_reg = 0, -+ }; -+ -+ pr_info("%s\n", __func__); -+ -+#if !defined(LS1012A_PFE_RESET_WA) -+ /* LS1012A needs this to make PE work correctly */ -+ writel(0x3, CLASS_PE_SYS_CLK_RATIO); -+ writel(0x3, TMU_PE_SYS_CLK_RATIO); -+ writel(0x3, UTIL_PE_SYS_CLK_RATIO); -+ usleep_range(10, 20); -+#endif -+ -+ pr_info("CLASS version: %x\n", readl(CLASS_VERSION)); -+ pr_info("TMU version: %x\n", readl(TMU_VERSION)); -+ -+ pr_info("BMU1 version: %x\n", readl(BMU1_BASE_ADDR + -+ BMU_VERSION)); -+ pr_info("BMU2 version: %x\n", readl(BMU2_BASE_ADDR + -+ BMU_VERSION)); -+ -+ pr_info("EGPI1 version: %x\n", readl(EGPI1_BASE_ADDR + -+ GPI_VERSION)); -+ pr_info("EGPI2 version: %x\n", readl(EGPI2_BASE_ADDR + -+ GPI_VERSION)); -+ pr_info("HGPI version: %x\n", readl(HGPI_BASE_ADDR + -+ GPI_VERSION)); -+ -+ pr_info("HIF version: %x\n", readl(HIF_VERSION)); -+ pr_info("HIF NOPCY version: %x\n", readl(HIF_NOCPY_VERSION)); -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ pr_info("UTIL version: %x\n", readl(UTIL_VERSION)); -+#endif -+ while (!(readl(TMU_CTRL) & ECC_MEM_INIT_DONE)) -+ ; -+ -+ hif_rx_disable(); -+ hif_tx_disable(); -+ -+ bmu_init(BMU1_BASE_ADDR, &bmu1_cfg); -+ -+ pr_info("bmu_init(1) done\n"); -+ -+ bmu_init(BMU2_BASE_ADDR, &bmu2_cfg); -+ -+ pr_info("bmu_init(2) done\n"); -+ -+ class_cfg.resume = resume ? 1 : 0; -+ -+ class_init(&class_cfg); -+ -+ pr_info("class_init() done\n"); -+ -+ tmu_init(&tmu_cfg); -+ -+ pr_info("tmu_init() done\n"); -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ util_init(&util_cfg); -+ -+ pr_info("util_init() done\n"); -+#endif -+ gpi_init(EGPI1_BASE_ADDR, &egpi1_cfg); -+ -+ pr_info("gpi_init(1) done\n"); -+ -+ gpi_init(EGPI2_BASE_ADDR, &egpi2_cfg); -+ -+ pr_info("gpi_init(2) done\n"); -+ -+ gpi_init(HGPI_BASE_ADDR, &hgpi_cfg); -+ -+ pr_info("gpi_init(hif) done\n"); -+ -+ bmu_enable(BMU1_BASE_ADDR); -+ -+ pr_info("bmu_enable(1) done\n"); -+ -+ bmu_enable(BMU2_BASE_ADDR); -+ -+ pr_info("bmu_enable(2) done\n"); -+ -+ return 0; -+} -+ -+void pfe_hw_exit(struct pfe *pfe) -+{ -+ pr_info("%s\n", __func__); -+ -+ bmu_disable(BMU1_BASE_ADDR); -+ bmu_reset(BMU1_BASE_ADDR); -+ -+ bmu_disable(BMU2_BASE_ADDR); -+ bmu_reset(BMU2_BASE_ADDR); -+} ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -@@ -0,0 +1,388 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "pfe_mod.h" -+ -+struct ls1012a_pfe_platform_data pfe_platform_data; -+ -+static int pfe_get_gemac_if_proprties(struct device_node *parent, int port, int -+ if_cnt, -+ struct ls1012a_pfe_platform_data -+ *pdata) -+{ -+ struct device_node *gem = NULL, *phy = NULL; -+ int size; -+ int ii = 0, phy_id = 0; -+ const u32 *addr; -+ -+ for (ii = 0; ii < if_cnt; ii++) { -+ gem = of_get_next_child(parent, gem); -+ if (!gem) -+ goto err; -+ addr = of_get_property(gem, "reg", &size); -+ if (addr && (be32_to_cpup(addr) == port)) -+ break; -+ } -+ -+ if (ii >= if_cnt) { -+ pr_err("%s:%d Failed to find interface = %d\n", -+ __func__, __LINE__, if_cnt); -+ goto err; -+ } -+ -+ pdata->ls1012a_eth_pdata[port].gem_id = port; -+ -+ of_get_mac_address(gem, pdata->ls1012a_eth_pdata[port].mac_addr); -+ -+ pdata->ls1012a_eth_pdata[port].mii_config = of_get_phy_mode(gem); -+ -+ if ((pdata->ls1012a_eth_pdata[port].mii_config) < 0) -+ pr_err("%s:%d Incorrect Phy mode....\n", __func__, -+ __LINE__); -+ -+ addr = of_get_property(gem, "fsl,gemac-bus-id", &size); -+ if (!addr) -+ pr_err("%s:%d Invalid gemac-bus-id....\n", __func__, -+ __LINE__); -+ else -+ pdata->ls1012a_eth_pdata[port].bus_id = be32_to_cpup(addr); -+ -+ addr = of_get_property(gem, "fsl,gemac-phy-id", &size); -+ if (!addr) { -+ pr_err("%s:%d Invalid gemac-phy-id....\n", __func__, -+ __LINE__); -+ } else { -+ phy_id = be32_to_cpup(addr); -+ pdata->ls1012a_eth_pdata[port].phy_id = phy_id; -+ pdata->ls1012a_mdio_pdata[0].phy_mask &= ~(1 << phy_id); -+ } -+ -+ addr = of_get_property(gem, "fsl,mdio-mux-val", &size); -+ if (!addr) -+ pr_err("%s: Invalid mdio-mux-val....\n", __func__); -+ else -+ phy_id = be32_to_cpup(addr); -+ pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id; -+ -+ if (pdata->ls1012a_eth_pdata[port].phy_id < 32) -+ pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] = -+ pdata->ls1012a_eth_pdata[port].mdio_muxval; -+ -+ addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size); -+ if (!addr) -+ pr_err("%s:%d Invalid pfe-phy-if-flags....\n", -+ __func__, __LINE__); -+ else -+ pdata->ls1012a_eth_pdata[port].phy_flags = be32_to_cpup(addr); -+ -+ /* If PHY is enabled, read mdio properties */ -+ if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY) -+ goto done; -+ -+ phy = of_get_next_child(gem, NULL); -+ -+ addr = of_get_property(phy, "reg", &size); -+ -+ if (!addr) -+ pr_err("%s:%d Invalid phy enable flag....\n", -+ __func__, __LINE__); -+ else -+ pdata->ls1012a_mdio_pdata[port].enabled = be32_to_cpup(addr); -+ -+ pdata->ls1012a_mdio_pdata[port].irq[0] = PHY_POLL; -+ -+done: -+ -+ return 0; -+ -+err: -+ return -1; -+} -+ -+/* -+ * -+ * pfe_platform_probe - -+ * -+ * -+ */ -+static int pfe_platform_probe(struct platform_device *pdev) -+{ -+ struct resource res; -+ int ii, rc, interface_count = 0, size = 0; -+ const u32 *prop; -+ struct device_node *np; -+ struct clk *pfe_clk; -+ -+ np = pdev->dev.of_node; -+ -+ if (!np) { -+ pr_err("Invalid device node\n"); -+ return -EINVAL; -+ } -+ -+ pfe = kzalloc(sizeof(*pfe), GFP_KERNEL); -+ if (!pfe) { -+ rc = -ENOMEM; -+ goto err_alloc; -+ } -+ -+ platform_set_drvdata(pdev, pfe); -+ -+ dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); -+ -+ if (of_address_to_resource(np, 1, &res)) { -+ rc = -ENOMEM; -+ pr_err("failed to get ddr resource\n"); -+ goto err_ddr; -+ } -+ -+ pfe->ddr_phys_baseaddr = res.start; -+ pfe->ddr_size = resource_size(&res); -+ -+ pfe->ddr_baseaddr = phys_to_virt(res.start); -+ if (!pfe->ddr_baseaddr) { -+ pr_err("ioremap() ddr failed\n"); -+ rc = -ENOMEM; -+ goto err_ddr; -+ } -+ -+ pfe->scfg = -+ syscon_regmap_lookup_by_phandle(pdev->dev.of_node, -+ "fsl,pfe-scfg"); -+ if (IS_ERR(pfe->scfg)) { -+ dev_err(&pdev->dev, "No syscfg phandle specified\n"); -+ return PTR_ERR(pfe->scfg); -+ } -+ -+ pfe->cbus_baseaddr = of_iomap(np, 0); -+ if (!pfe->cbus_baseaddr) { -+ rc = -ENOMEM; -+ pr_err("failed to get axi resource\n"); -+ goto err_axi; -+ } -+ -+ pfe->hif_irq = platform_get_irq(pdev, 0); -+ if (pfe->hif_irq < 0) { -+ pr_err("platform_get_irq for hif failed\n"); -+ rc = pfe->hif_irq; -+ goto err_hif_irq; -+ } -+ -+ pfe->wol_irq = platform_get_irq(pdev, 2); -+ if (pfe->wol_irq < 0) { -+ pr_err("platform_get_irq for WoL failed\n"); -+ rc = pfe->wol_irq; -+ goto err_hif_irq; -+ } -+ -+ /* Read interface count */ -+ prop = of_get_property(np, "fsl,pfe-num-interfaces", &size); -+ if (!prop) { -+ pr_err("Failed to read number of interfaces\n"); -+ rc = -ENXIO; -+ goto err_prop; -+ } -+ -+ interface_count = be32_to_cpup(prop); -+ if (interface_count <= 0) { -+ pr_err("No ethernet interface count : %d\n", -+ interface_count); -+ rc = -ENXIO; -+ goto err_prop; -+ } -+ -+ pfe_platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; -+ -+ for (ii = 0; ii < interface_count; ii++) { -+ pfe_get_gemac_if_proprties(np, ii, interface_count, -+ &pfe_platform_data); -+ } -+ -+ pfe->dev = &pdev->dev; -+ -+ pfe->dev->platform_data = &pfe_platform_data; -+ -+ /* declare WoL capabilities */ -+ device_init_wakeup(&pdev->dev, true); -+ -+ /* find the clocks */ -+ pfe_clk = devm_clk_get(pfe->dev, "pfe"); -+ if (IS_ERR(pfe_clk)) -+ return PTR_ERR(pfe_clk); -+ -+ /* PFE clock is (platform clock / 2) */ -+ /* save sys_clk value as KHz */ -+ pfe->ctrl.sys_clk = clk_get_rate(pfe_clk) / (2 * 1000); -+ -+ rc = pfe_probe(pfe); -+ if (rc < 0) -+ goto err_probe; -+ -+ return 0; -+ -+err_probe: -+err_prop: -+err_hif_irq: -+ iounmap(pfe->cbus_baseaddr); -+ -+err_axi: -+ iounmap(pfe->ddr_baseaddr); -+ -+err_ddr: -+ platform_set_drvdata(pdev, NULL); -+ -+ kfree(pfe); -+ -+err_alloc: -+ return rc; -+} -+ -+/* -+ * pfe_platform_remove - -+ */ -+static int pfe_platform_remove(struct platform_device *pdev) -+{ -+ struct pfe *pfe = platform_get_drvdata(pdev); -+ int rc; -+ -+ pr_info("%s\n", __func__); -+ -+ rc = pfe_remove(pfe); -+ -+ iounmap(pfe->cbus_baseaddr); -+ iounmap(pfe->ddr_baseaddr); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ kfree(pfe); -+ -+ return rc; -+} -+ -+#ifdef CONFIG_PM -+#ifdef CONFIG_PM_SLEEP -+int pfe_platform_suspend(struct device *dev) -+{ -+ struct pfe *pfe = platform_get_drvdata(to_platform_device(dev)); -+ struct net_device *netdev; -+ int i; -+ -+ pfe->wake = 0; -+ -+ for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) { -+ netdev = pfe->eth.eth_priv[i]->ndev; -+ -+ netif_device_detach(netdev); -+ -+ if (netif_running(netdev)) -+ if (pfe_eth_suspend(netdev)) -+ pfe->wake = 1; -+ } -+ -+ /* Shutdown PFE only if we're not waking up the system */ -+ if (!pfe->wake) { -+#if defined(LS1012A_PFE_RESET_WA) -+ pfe_hif_rx_idle(&pfe->hif); -+#endif -+ pfe_ctrl_suspend(&pfe->ctrl); -+ pfe_firmware_exit(pfe); -+ -+ pfe_hif_exit(pfe); -+ pfe_hif_lib_exit(pfe); -+ -+ pfe_hw_exit(pfe); -+ } -+ -+ return 0; -+} -+ -+static int pfe_platform_resume(struct device *dev) -+{ -+ struct pfe *pfe = platform_get_drvdata(to_platform_device(dev)); -+ struct net_device *netdev; -+ int i; -+ -+ if (!pfe->wake) { -+ pfe_hw_init(pfe, 1); -+ pfe_hif_lib_init(pfe); -+ pfe_hif_init(pfe); -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ util_enable(); -+#endif -+ tmu_enable(0xf); -+ class_enable(); -+ pfe_ctrl_resume(&pfe->ctrl); -+ } -+ -+ for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) { -+ netdev = pfe->eth.eth_priv[i]->ndev; -+ -+ if (pfe->eth.eth_priv[i]->mii_bus) -+ pfe_eth_mdio_reset(pfe->eth.eth_priv[i]->mii_bus); -+ -+ if (netif_running(netdev)) -+ pfe_eth_resume(netdev); -+ -+ netif_device_attach(netdev); -+ } -+ return 0; -+} -+#else -+#define pfe_platform_suspend NULL -+#define pfe_platform_resume NULL -+#endif -+ -+static const struct dev_pm_ops pfe_platform_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(pfe_platform_suspend, pfe_platform_resume) -+}; -+#endif -+ -+static const struct of_device_id pfe_match[] = { -+ { -+ .compatible = "fsl,pfe", -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, pfe_match); -+ -+static struct platform_driver pfe_platform_driver = { -+ .probe = pfe_platform_probe, -+ .remove = pfe_platform_remove, -+ .driver = { -+ .name = "pfe", -+ .of_match_table = pfe_match, -+#ifdef CONFIG_PM -+ .pm = &pfe_platform_pm_ops, -+#endif -+ }, -+}; -+ -+module_platform_driver(pfe_platform_driver); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("PFE Ethernet driver"); -+MODULE_AUTHOR("NXP DNCPE"); ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_mod.c -@@ -0,0 +1,141 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include -+#include "pfe_mod.h" -+ -+struct pfe *pfe; -+ -+/* -+ * pfe_probe - -+ */ -+int pfe_probe(struct pfe *pfe) -+{ -+ int rc; -+ -+ if (pfe->ddr_size < DDR_MAX_SIZE) { -+ pr_err("%s: required DDR memory (%x) above platform ddr memory (%x)\n", -+ __func__, (unsigned int)DDR_MAX_SIZE, pfe->ddr_size); -+ rc = -ENOMEM; -+ goto err_hw; -+ } -+ -+ if (((int)(pfe->ddr_phys_baseaddr + BMU2_DDR_BASEADDR) & -+ (8 * SZ_1M - 1)) != 0) { -+ pr_err("%s: BMU2 base address (0x%x) must be aligned on 8MB boundary\n", -+ __func__, (int)pfe->ddr_phys_baseaddr + -+ BMU2_DDR_BASEADDR); -+ rc = -ENOMEM; -+ goto err_hw; -+ } -+ -+ pr_info("cbus_baseaddr: %lx, ddr_baseaddr: %lx, ddr_phys_baseaddr: %lx, ddr_size: %x\n", -+ (unsigned long)pfe->cbus_baseaddr, -+ (unsigned long)pfe->ddr_baseaddr, -+ pfe->ddr_phys_baseaddr, pfe->ddr_size); -+ -+ pfe_lib_init(pfe->cbus_baseaddr, pfe->ddr_baseaddr, -+ pfe->ddr_phys_baseaddr, pfe->ddr_size); -+ -+ rc = pfe_hw_init(pfe, 0); -+ if (rc < 0) -+ goto err_hw; -+ -+ rc = pfe_hif_lib_init(pfe); -+ if (rc < 0) -+ goto err_hif_lib; -+ -+ rc = pfe_hif_init(pfe); -+ if (rc < 0) -+ goto err_hif; -+ -+ rc = pfe_firmware_init(pfe); -+ if (rc < 0) -+ goto err_firmware; -+ -+ rc = pfe_ctrl_init(pfe); -+ if (rc < 0) -+ goto err_ctrl; -+ -+ rc = pfe_eth_init(pfe); -+ if (rc < 0) -+ goto err_eth; -+ -+ rc = pfe_sysfs_init(pfe); -+ if (rc < 0) -+ goto err_sysfs; -+ -+ rc = pfe_debugfs_init(pfe); -+ if (rc < 0) -+ goto err_debugfs; -+ -+ return 0; -+ -+err_debugfs: -+ pfe_sysfs_exit(pfe); -+ -+err_sysfs: -+ pfe_eth_exit(pfe); -+ -+err_eth: -+ pfe_ctrl_exit(pfe); -+ -+err_ctrl: -+ pfe_firmware_exit(pfe); -+ -+err_firmware: -+ pfe_hif_exit(pfe); -+ -+err_hif: -+ pfe_hif_lib_exit(pfe); -+ -+err_hif_lib: -+ pfe_hw_exit(pfe); -+ -+err_hw: -+ return rc; -+} -+ -+/* -+ * pfe_remove - -+ */ -+int pfe_remove(struct pfe *pfe) -+{ -+ pr_info("%s\n", __func__); -+ -+ pfe_debugfs_exit(pfe); -+ -+ pfe_sysfs_exit(pfe); -+ -+ pfe_eth_exit(pfe); -+ -+ pfe_ctrl_exit(pfe); -+ -+#if defined(LS1012A_PFE_RESET_WA) -+ pfe_hif_rx_idle(&pfe->hif); -+#endif -+ pfe_firmware_exit(pfe); -+ -+ pfe_hif_exit(pfe); -+ -+ pfe_hif_lib_exit(pfe); -+ -+ pfe_hw_exit(pfe); -+ -+ return 0; -+} ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.c -@@ -0,0 +1,818 @@ -+/* -+ * Copyright 2015-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#include -+#include -+ -+#include "pfe_mod.h" -+ -+#define PE_EXCEPTION_DUMP_ADDRESS 0x1fa8 -+#define NUM_QUEUES 16 -+ -+static char register_name[20][5] = { -+ "EPC", "ECAS", "EID", "ED", -+ "r0", "r1", "r2", "r3", -+ "r4", "r5", "r6", "r7", -+ "r8", "r9", "r10", "r11", -+ "r12", "r13", "r14", "r15", -+}; -+ -+static char exception_name[14][20] = { -+ "Reset", -+ "HardwareFailure", -+ "NMI", -+ "InstBreakpoint", -+ "DataBreakpoint", -+ "Unsupported", -+ "PrivilegeViolation", -+ "InstBusError", -+ "DataBusError", -+ "AlignmentError", -+ "ArithmeticError", -+ "SystemCall", -+ "MemoryManagement", -+ "Interrupt", -+}; -+ -+static unsigned long class_do_clear; -+static unsigned long tmu_do_clear; -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+static unsigned long util_do_clear; -+#endif -+ -+static ssize_t display_pe_status(char *buf, int id, u32 dmem_addr, unsigned long -+ do_clear) -+{ -+ ssize_t len = 0; -+ u32 val; -+ char statebuf[5]; -+ struct pfe_cpumon *cpumon = &pfe->cpumon; -+ u32 debug_indicator; -+ u32 debug[20]; -+ -+ *(u32 *)statebuf = pe_dmem_read(id, dmem_addr, 4); -+ dmem_addr += 4; -+ -+ statebuf[4] = '\0'; -+ len += sprintf(buf + len, "state=%4s ", statebuf); -+ -+ val = pe_dmem_read(id, dmem_addr, 4); -+ dmem_addr += 4; -+ len += sprintf(buf + len, "ctr=%08x ", cpu_to_be32(val)); -+ -+ val = pe_dmem_read(id, dmem_addr, 4); -+ if (do_clear && val) -+ pe_dmem_write(id, 0, dmem_addr, 4); -+ dmem_addr += 4; -+ len += sprintf(buf + len, "rx=%u ", cpu_to_be32(val)); -+ -+ val = pe_dmem_read(id, dmem_addr, 4); -+ if (do_clear && val) -+ pe_dmem_write(id, 0, dmem_addr, 4); -+ dmem_addr += 4; -+ if (id >= TMU0_ID && id <= TMU_MAX_ID) -+ len += sprintf(buf + len, "qstatus=%x", cpu_to_be32(val)); -+ else -+ len += sprintf(buf + len, "tx=%u", cpu_to_be32(val)); -+ -+ val = pe_dmem_read(id, dmem_addr, 4); -+ if (do_clear && val) -+ pe_dmem_write(id, 0, dmem_addr, 4); -+ dmem_addr += 4; -+ if (val) -+ len += sprintf(buf + len, " drop=%u", cpu_to_be32(val)); -+ -+ len += sprintf(buf + len, " load=%d%%", cpumon->cpu_usage_pct[id]); -+ -+ len += sprintf(buf + len, "\n"); -+ -+ debug_indicator = pe_dmem_read(id, dmem_addr, 4); -+ dmem_addr += 4; -+ if (!strncmp((char *)&debug_indicator, "DBUG", 4)) { -+ int j, last = 0; -+ -+ for (j = 0; j < 16; j++) { -+ debug[j] = pe_dmem_read(id, dmem_addr, 4); -+ if (debug[j]) { -+ if (do_clear) -+ pe_dmem_write(id, 0, dmem_addr, 4); -+ last = j + 1; -+ } -+ dmem_addr += 4; -+ } -+ for (j = 0; j < last; j++) { -+ len += sprintf(buf + len, "%08x%s", -+ cpu_to_be32(debug[j]), -+ (j & 0x7) == 0x7 || j == last - 1 ? "\n" : " "); -+ } -+ } -+ -+ if (!strncmp(statebuf, "DEAD", 4)) { -+ u32 i, dump = PE_EXCEPTION_DUMP_ADDRESS; -+ -+ len += sprintf(buf + len, "Exception details:\n"); -+ for (i = 0; i < 20; i++) { -+ debug[i] = pe_dmem_read(id, dump, 4); -+ dump += 4; -+ if (i == 2) -+ len += sprintf(buf + len, "%4s = %08x (=%s) ", -+ register_name[i], cpu_to_be32(debug[i]), -+ exception_name[min((u32) -+ cpu_to_be32(debug[i]), (u32)13)]); -+ else -+ len += sprintf(buf + len, "%4s = %08x%s", -+ register_name[i], cpu_to_be32(debug[i]), -+ (i & 0x3) == 0x3 || i == 19 ? "\n" : " "); -+ } -+ } -+ -+ return len; -+} -+ -+static ssize_t class_phy_stats(char *buf, int phy) -+{ -+ ssize_t len = 0; -+ int off1 = phy * 0x28; -+ int off2 = phy * 0x10; -+ -+ if (phy == 3) -+ off1 = CLASS_PHY4_RX_PKTS - CLASS_PHY1_RX_PKTS; -+ -+ len += sprintf(buf + len, "phy: %d\n", phy); -+ len += sprintf(buf + len, -+ " rx: %10u, tx: %10u, intf: %10u, ipv4: %10u, ipv6: %10u\n", -+ readl(CLASS_PHY1_RX_PKTS + off1), -+ readl(CLASS_PHY1_TX_PKTS + off1), -+ readl(CLASS_PHY1_INTF_MATCH_PKTS + off1), -+ readl(CLASS_PHY1_V4_PKTS + off1), -+ readl(CLASS_PHY1_V6_PKTS + off1)); -+ -+ len += sprintf(buf + len, -+ " icmp: %10u, igmp: %10u, tcp: %10u, udp: %10u\n", -+ readl(CLASS_PHY1_ICMP_PKTS + off2), -+ readl(CLASS_PHY1_IGMP_PKTS + off2), -+ readl(CLASS_PHY1_TCP_PKTS + off2), -+ readl(CLASS_PHY1_UDP_PKTS + off2)); -+ -+ len += sprintf(buf + len, " err\n"); -+ len += sprintf(buf + len, -+ " lp: %10u, intf: %10u, l3: %10u, chcksum: %10u, ttl: %10u\n", -+ readl(CLASS_PHY1_LP_FAIL_PKTS + off1), -+ readl(CLASS_PHY1_INTF_FAIL_PKTS + off1), -+ readl(CLASS_PHY1_L3_FAIL_PKTS + off1), -+ readl(CLASS_PHY1_CHKSUM_ERR_PKTS + off1), -+ readl(CLASS_PHY1_TTL_ERR_PKTS + off1)); -+ -+ return len; -+} -+ -+/* qm_read_drop_stat -+ * This function is used to read the drop statistics from the TMU -+ * hw drop counter. Since the hw counter is always cleared afer -+ * reading, this function maintains the previous drop count, and -+ * adds the new value to it. That value can be retrieved by -+ * passing a pointer to it with the total_drops arg. -+ * -+ * @param tmu TMU number (0 - 3) -+ * @param queue queue number (0 - 15) -+ * @param total_drops pointer to location to store total drops (or NULL) -+ * @param do_reset if TRUE, clear total drops after updating -+ */ -+u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset) -+{ -+ static u32 qtotal[TMU_MAX_ID + 1][NUM_QUEUES]; -+ u32 val; -+ -+ writel((tmu << 8) | queue, TMU_TEQ_CTRL); -+ writel((tmu << 8) | queue, TMU_LLM_CTRL); -+ val = readl(TMU_TEQ_DROP_STAT); -+ qtotal[tmu][queue] += val; -+ if (total_drops) -+ *total_drops = qtotal[tmu][queue]; -+ if (do_reset) -+ qtotal[tmu][queue] = 0; -+ return val; -+} -+ -+static ssize_t tmu_queue_stats(char *buf, int tmu, int queue) -+{ -+ ssize_t len = 0; -+ u32 drops; -+ -+ len += sprintf(buf + len, "%d-%02d, ", tmu, queue); -+ -+ drops = qm_read_drop_stat(tmu, queue, NULL, 0); -+ -+ /* Select queue */ -+ writel((tmu << 8) | queue, TMU_TEQ_CTRL); -+ writel((tmu << 8) | queue, TMU_LLM_CTRL); -+ -+ len += sprintf(buf + len, -+ "(teq) drop: %10u, tx: %10u (llm) head: %08x, tail: %08x, drop: %10u\n", -+ drops, readl(TMU_TEQ_TRANS_STAT), -+ readl(TMU_LLM_QUE_HEADPTR), readl(TMU_LLM_QUE_TAILPTR), -+ readl(TMU_LLM_QUE_DROPCNT)); -+ -+ return len; -+} -+ -+static ssize_t tmu_queues(char *buf, int tmu) -+{ -+ ssize_t len = 0; -+ int queue; -+ -+ for (queue = 0; queue < 16; queue++) -+ len += tmu_queue_stats(buf + len, tmu, queue); -+ -+ return len; -+} -+ -+static ssize_t block_version(char *buf, void *addr) -+{ -+ ssize_t len = 0; -+ u32 val; -+ -+ val = readl(addr); -+ len += sprintf(buf + len, "revision: %x, version: %x, id: %x\n", -+ (val >> 24) & 0xff, (val >> 16) & 0xff, val & 0xffff); -+ -+ return len; -+} -+ -+static ssize_t bmu(char *buf, int id, void *base) -+{ -+ ssize_t len = 0; -+ -+ len += sprintf(buf + len, "%s: %d\n ", __func__, id); -+ -+ len += block_version(buf + len, base + BMU_VERSION); -+ -+ len += sprintf(buf + len, " buf size: %x\n", (1 << readl(base + -+ BMU_BUF_SIZE))); -+ len += sprintf(buf + len, " buf count: %x\n", readl(base + -+ BMU_BUF_CNT)); -+ len += sprintf(buf + len, " buf rem: %x\n", readl(base + -+ BMU_REM_BUF_CNT)); -+ len += sprintf(buf + len, " buf curr: %x\n", readl(base + -+ BMU_CURR_BUF_CNT)); -+ len += sprintf(buf + len, " free err: %x\n", readl(base + -+ BMU_FREE_ERR_ADDR)); -+ -+ return len; -+} -+ -+static ssize_t gpi(char *buf, int id, void *base) -+{ -+ ssize_t len = 0; -+ u32 val; -+ -+ len += sprintf(buf + len, "%s%d:\n ", __func__, id); -+ len += block_version(buf + len, base + GPI_VERSION); -+ -+ len += sprintf(buf + len, " tx under stick: %x\n", readl(base + -+ GPI_FIFO_STATUS)); -+ val = readl(base + GPI_FIFO_DEBUG); -+ len += sprintf(buf + len, " tx pkts: %x\n", (val >> 23) & -+ 0x3f); -+ len += sprintf(buf + len, " rx pkts: %x\n", (val >> 18) & -+ 0x3f); -+ len += sprintf(buf + len, " tx bytes: %x\n", (val >> 9) & -+ 0x1ff); -+ len += sprintf(buf + len, " rx bytes: %x\n", (val >> 0) & -+ 0x1ff); -+ len += sprintf(buf + len, " overrun: %x\n", readl(base + -+ GPI_OVERRUN_DROPCNT)); -+ -+ return len; -+} -+ -+static ssize_t pfe_set_class(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ class_do_clear = kstrtoul(buf, 0, 0); -+ return count; -+} -+ -+static ssize_t pfe_show_class(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ ssize_t len = 0; -+ int id; -+ u32 val; -+ struct pfe_cpumon *cpumon = &pfe->cpumon; -+ -+ len += block_version(buf + len, CLASS_VERSION); -+ -+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) { -+ len += sprintf(buf + len, "%d: ", id - CLASS0_ID); -+ -+ val = readl(CLASS_PE0_DEBUG + id * 4); -+ len += sprintf(buf + len, "pc=1%04x ", val & 0xffff); -+ -+ len += display_pe_status(buf + len, id, CLASS_DM_PESTATUS, -+ class_do_clear); -+ } -+ len += sprintf(buf + len, "aggregate load=%d%%\n\n", -+ cpumon->class_usage_pct); -+ -+ len += sprintf(buf + len, "pe status: 0x%x\n", -+ readl(CLASS_PE_STATUS)); -+ len += sprintf(buf + len, "max buf cnt: 0x%x afull thres: 0x%x\n", -+ readl(CLASS_MAX_BUF_CNT), readl(CLASS_AFULL_THRES)); -+ len += sprintf(buf + len, "tsq max cnt: 0x%x tsq fifo thres: 0x%x\n", -+ readl(CLASS_TSQ_MAX_CNT), readl(CLASS_TSQ_FIFO_THRES)); -+ len += sprintf(buf + len, "state: 0x%x\n", readl(CLASS_STATE)); -+ -+ len += class_phy_stats(buf + len, 0); -+ len += class_phy_stats(buf + len, 1); -+ len += class_phy_stats(buf + len, 2); -+ len += class_phy_stats(buf + len, 3); -+ -+ return len; -+} -+ -+static ssize_t pfe_set_tmu(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ tmu_do_clear = kstrtoul(buf, 0, 0); -+ return count; -+} -+ -+static ssize_t pfe_show_tmu(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ ssize_t len = 0; -+ int id; -+ u32 val; -+ -+ len += block_version(buf + len, TMU_VERSION); -+ -+ for (id = TMU0_ID; id <= TMU_MAX_ID; id++) { -+ if (id == TMU2_ID) -+ continue; -+ len += sprintf(buf + len, "%d: ", id - TMU0_ID); -+ -+ len += display_pe_status(buf + len, id, TMU_DM_PESTATUS, -+ tmu_do_clear); -+ } -+ -+ len += sprintf(buf + len, "pe status: %x\n", readl(TMU_PE_STATUS)); -+ len += sprintf(buf + len, "inq fifo cnt: %x\n", -+ readl(TMU_PHY_INQ_FIFO_CNT)); -+ val = readl(TMU_INQ_STAT); -+ len += sprintf(buf + len, "inq wr ptr: %x\n", val & 0x3ff); -+ len += sprintf(buf + len, "inq rd ptr: %x\n", val >> 10); -+ -+ return len; -+} -+ -+static unsigned long drops_do_clear; -+static u32 class_drop_counter[CLASS_NUM_DROP_COUNTERS]; -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+static u32 util_drop_counter[UTIL_NUM_DROP_COUNTERS]; -+#endif -+ -+char *class_drop_description[CLASS_NUM_DROP_COUNTERS] = { -+ "ICC", -+ "Host Pkt Error", -+ "Rx Error", -+ "IPsec Outbound", -+ "IPsec Inbound", -+ "EXPT IPsec Error", -+ "Reassembly", -+ "Fragmenter", -+ "NAT-T", -+ "Socket", -+ "Multicast", -+ "NAT-PT", -+ "Tx Disabled", -+}; -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+char *util_drop_description[UTIL_NUM_DROP_COUNTERS] = { -+ "IPsec Outbound", -+ "IPsec Inbound", -+ "IPsec Rate Limiter", -+ "Fragmenter", -+ "Socket", -+ "Tx Disabled", -+ "Rx Error", -+}; -+#endif -+ -+static ssize_t pfe_set_drops(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ drops_do_clear = kstrtoul(buf, 0, 0); -+ return count; -+} -+ -+static u32 tmu_drops[4][16]; -+static ssize_t pfe_show_drops(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ ssize_t len = 0; -+ int id, dropnum; -+ int tmu, queue; -+ u32 val; -+ u32 dmem_addr; -+ int num_class_drops = 0, num_tmu_drops = 0, num_util_drops = 0; -+ struct pfe_ctrl *ctrl = &pfe->ctrl; -+ -+ memset(class_drop_counter, 0, sizeof(class_drop_counter)); -+ for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) { -+ if (drops_do_clear) -+ pe_sync_stop(ctrl, (1 << id)); -+ for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS; -+ dropnum++) { -+ dmem_addr = CLASS_DM_DROP_CNTR; -+ val = be32_to_cpu(pe_dmem_read(id, dmem_addr, 4)); -+ class_drop_counter[dropnum] += val; -+ num_class_drops += val; -+ if (drops_do_clear) -+ pe_dmem_write(id, 0, dmem_addr, 4); -+ } -+ if (drops_do_clear) -+ pe_start(ctrl, (1 << id)); -+ } -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ if (drops_do_clear) -+ pe_sync_stop(ctrl, (1 << UTIL_ID)); -+ for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++) { -+ dmem_addr = UTIL_DM_DROP_CNTR; -+ val = be32_to_cpu(pe_dmem_read(UTIL_ID, dmem_addr, 4)); -+ util_drop_counter[dropnum] = val; -+ num_util_drops += val; -+ if (drops_do_clear) -+ pe_dmem_write(UTIL_ID, 0, dmem_addr, 4); -+ } -+ if (drops_do_clear) -+ pe_start(ctrl, (1 << UTIL_ID)); -+#endif -+ for (tmu = 0; tmu < 4; tmu++) { -+ for (queue = 0; queue < 16; queue++) { -+ qm_read_drop_stat(tmu, queue, &tmu_drops[tmu][queue], -+ drops_do_clear); -+ num_tmu_drops += tmu_drops[tmu][queue]; -+ } -+ } -+ -+ if (num_class_drops == 0 && num_util_drops == 0 && num_tmu_drops == 0) -+ len += sprintf(buf + len, "No PE drops\n\n"); -+ -+ if (num_class_drops > 0) { -+ len += sprintf(buf + len, "Class PE drops --\n"); -+ for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS; -+ dropnum++) { -+ if (class_drop_counter[dropnum] > 0) -+ len += sprintf(buf + len, " %s: %d\n", -+ class_drop_description[dropnum], -+ class_drop_counter[dropnum]); -+ } -+ len += sprintf(buf + len, "\n"); -+ } -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ if (num_util_drops > 0) { -+ len += sprintf(buf + len, "Util PE drops --\n"); -+ for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++) { -+ if (util_drop_counter[dropnum] > 0) -+ len += sprintf(buf + len, " %s: %d\n", -+ util_drop_description[dropnum], -+ util_drop_counter[dropnum]); -+ } -+ len += sprintf(buf + len, "\n"); -+ } -+#endif -+ if (num_tmu_drops > 0) { -+ len += sprintf(buf + len, "TMU drops --\n"); -+ for (tmu = 0; tmu < 4; tmu++) { -+ for (queue = 0; queue < 16; queue++) { -+ if (tmu_drops[tmu][queue] > 0) -+ len += sprintf(buf + len, -+ " TMU%d-Q%d: %d\n" -+ , tmu, queue, tmu_drops[tmu][queue]); -+ } -+ } -+ len += sprintf(buf + len, "\n"); -+ } -+ -+ return len; -+} -+ -+static ssize_t pfe_show_tmu0_queues(struct device *dev, struct device_attribute -+ *attr, char *buf) -+{ -+ return tmu_queues(buf, 0); -+} -+ -+static ssize_t pfe_show_tmu1_queues(struct device *dev, struct device_attribute -+ *attr, char *buf) -+{ -+ return tmu_queues(buf, 1); -+} -+ -+static ssize_t pfe_show_tmu2_queues(struct device *dev, struct device_attribute -+ *attr, char *buf) -+{ -+ return tmu_queues(buf, 2); -+} -+ -+static ssize_t pfe_show_tmu3_queues(struct device *dev, struct device_attribute -+ *attr, char *buf) -+{ -+ return tmu_queues(buf, 3); -+} -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+static ssize_t pfe_set_util(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ util_do_clear = kstrtoul(buf, NULL, 0); -+ return count; -+} -+ -+static ssize_t pfe_show_util(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ ssize_t len = 0; -+ struct pfe_ctrl *ctrl = &pfe->ctrl; -+ -+ len += block_version(buf + len, UTIL_VERSION); -+ -+ pe_sync_stop(ctrl, (1 << UTIL_ID)); -+ len += display_pe_status(buf + len, UTIL_ID, UTIL_DM_PESTATUS, -+ util_do_clear); -+ pe_start(ctrl, (1 << UTIL_ID)); -+ -+ len += sprintf(buf + len, "pe status: %x\n", readl(UTIL_PE_STATUS)); -+ len += sprintf(buf + len, "max buf cnt: %x\n", -+ readl(UTIL_MAX_BUF_CNT)); -+ len += sprintf(buf + len, "tsq max cnt: %x\n", -+ readl(UTIL_TSQ_MAX_CNT)); -+ -+ return len; -+} -+#endif -+ -+static ssize_t pfe_show_bmu(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ ssize_t len = 0; -+ -+ len += bmu(buf + len, 1, BMU1_BASE_ADDR); -+ len += bmu(buf + len, 2, BMU2_BASE_ADDR); -+ -+ return len; -+} -+ -+static ssize_t pfe_show_hif(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ ssize_t len = 0; -+ -+ len += sprintf(buf + len, "hif:\n "); -+ len += block_version(buf + len, HIF_VERSION); -+ -+ len += sprintf(buf + len, " tx curr bd: %x\n", -+ readl(HIF_TX_CURR_BD_ADDR)); -+ len += sprintf(buf + len, " tx status: %x\n", -+ readl(HIF_TX_STATUS)); -+ len += sprintf(buf + len, " tx dma status: %x\n", -+ readl(HIF_TX_DMA_STATUS)); -+ -+ len += sprintf(buf + len, " rx curr bd: %x\n", -+ readl(HIF_RX_CURR_BD_ADDR)); -+ len += sprintf(buf + len, " rx status: %x\n", -+ readl(HIF_RX_STATUS)); -+ len += sprintf(buf + len, " rx dma status: %x\n", -+ readl(HIF_RX_DMA_STATUS)); -+ -+ len += sprintf(buf + len, "hif nocopy:\n "); -+ len += block_version(buf + len, HIF_NOCPY_VERSION); -+ -+ len += sprintf(buf + len, " tx curr bd: %x\n", -+ readl(HIF_NOCPY_TX_CURR_BD_ADDR)); -+ len += sprintf(buf + len, " tx status: %x\n", -+ readl(HIF_NOCPY_TX_STATUS)); -+ len += sprintf(buf + len, " tx dma status: %x\n", -+ readl(HIF_NOCPY_TX_DMA_STATUS)); -+ -+ len += sprintf(buf + len, " rx curr bd: %x\n", -+ readl(HIF_NOCPY_RX_CURR_BD_ADDR)); -+ len += sprintf(buf + len, " rx status: %x\n", -+ readl(HIF_NOCPY_RX_STATUS)); -+ len += sprintf(buf + len, " rx dma status: %x\n", -+ readl(HIF_NOCPY_RX_DMA_STATUS)); -+ -+ return len; -+} -+ -+static ssize_t pfe_show_gpi(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ ssize_t len = 0; -+ -+ len += gpi(buf + len, 0, EGPI1_BASE_ADDR); -+ len += gpi(buf + len, 1, EGPI2_BASE_ADDR); -+ len += gpi(buf + len, 3, HGPI_BASE_ADDR); -+ -+ return len; -+} -+ -+static ssize_t pfe_show_pfemem(struct device *dev, struct device_attribute -+ *attr, char *buf) -+{ -+ ssize_t len = 0; -+ struct pfe_memmon *memmon = &pfe->memmon; -+ -+ len += sprintf(buf + len, "Kernel Memory: %d Bytes (%d KB)\n", -+ memmon->kernel_memory_allocated, -+ (memmon->kernel_memory_allocated + 1023) / 1024); -+ -+ return len; -+} -+ -+#ifdef HIF_NAPI_STATS -+static ssize_t pfe_show_hif_napi_stats(struct device *dev, -+ struct device_attribute *attr, -+ char *buf) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct pfe *pfe = platform_get_drvdata(pdev); -+ ssize_t len = 0; -+ -+ len += sprintf(buf + len, "sched: %u\n", -+ pfe->hif.napi_counters[NAPI_SCHED_COUNT]); -+ len += sprintf(buf + len, "poll: %u\n", -+ pfe->hif.napi_counters[NAPI_POLL_COUNT]); -+ len += sprintf(buf + len, "packet: %u\n", -+ pfe->hif.napi_counters[NAPI_PACKET_COUNT]); -+ len += sprintf(buf + len, "budget: %u\n", -+ pfe->hif.napi_counters[NAPI_FULL_BUDGET_COUNT]); -+ len += sprintf(buf + len, "desc: %u\n", -+ pfe->hif.napi_counters[NAPI_DESC_COUNT]); -+ len += sprintf(buf + len, "full: %u\n", -+ pfe->hif.napi_counters[NAPI_CLIENT_FULL_COUNT]); -+ -+ return len; -+} -+ -+static ssize_t pfe_set_hif_napi_stats(struct device *dev, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct pfe *pfe = platform_get_drvdata(pdev); -+ -+ memset(pfe->hif.napi_counters, 0, sizeof(pfe->hif.napi_counters)); -+ -+ return count; -+} -+ -+static DEVICE_ATTR(hif_napi_stats, 0644, pfe_show_hif_napi_stats, -+ pfe_set_hif_napi_stats); -+#endif -+ -+static DEVICE_ATTR(class, 0644, pfe_show_class, pfe_set_class); -+static DEVICE_ATTR(tmu, 0644, pfe_show_tmu, pfe_set_tmu); -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+static DEVICE_ATTR(util, 0644, pfe_show_util, pfe_set_util); -+#endif -+static DEVICE_ATTR(bmu, 0444, pfe_show_bmu, NULL); -+static DEVICE_ATTR(hif, 0444, pfe_show_hif, NULL); -+static DEVICE_ATTR(gpi, 0444, pfe_show_gpi, NULL); -+static DEVICE_ATTR(drops, 0644, pfe_show_drops, pfe_set_drops); -+static DEVICE_ATTR(tmu0_queues, 0444, pfe_show_tmu0_queues, NULL); -+static DEVICE_ATTR(tmu1_queues, 0444, pfe_show_tmu1_queues, NULL); -+static DEVICE_ATTR(tmu2_queues, 0444, pfe_show_tmu2_queues, NULL); -+static DEVICE_ATTR(tmu3_queues, 0444, pfe_show_tmu3_queues, NULL); -+static DEVICE_ATTR(pfemem, 0444, pfe_show_pfemem, NULL); -+ -+int pfe_sysfs_init(struct pfe *pfe) -+{ -+ if (device_create_file(pfe->dev, &dev_attr_class)) -+ goto err_class; -+ -+ if (device_create_file(pfe->dev, &dev_attr_tmu)) -+ goto err_tmu; -+ -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ if (device_create_file(pfe->dev, &dev_attr_util)) -+ goto err_util; -+#endif -+ -+ if (device_create_file(pfe->dev, &dev_attr_bmu)) -+ goto err_bmu; -+ -+ if (device_create_file(pfe->dev, &dev_attr_hif)) -+ goto err_hif; -+ -+ if (device_create_file(pfe->dev, &dev_attr_gpi)) -+ goto err_gpi; -+ -+ if (device_create_file(pfe->dev, &dev_attr_drops)) -+ goto err_drops; -+ -+ if (device_create_file(pfe->dev, &dev_attr_tmu0_queues)) -+ goto err_tmu0_queues; -+ -+ if (device_create_file(pfe->dev, &dev_attr_tmu1_queues)) -+ goto err_tmu1_queues; -+ -+ if (device_create_file(pfe->dev, &dev_attr_tmu2_queues)) -+ goto err_tmu2_queues; -+ -+ if (device_create_file(pfe->dev, &dev_attr_tmu3_queues)) -+ goto err_tmu3_queues; -+ -+ if (device_create_file(pfe->dev, &dev_attr_pfemem)) -+ goto err_pfemem; -+ -+#ifdef HIF_NAPI_STATS -+ if (device_create_file(pfe->dev, &dev_attr_hif_napi_stats)) -+ goto err_hif_napi_stats; -+#endif -+ -+ return 0; -+ -+#ifdef HIF_NAPI_STATS -+err_hif_napi_stats: -+ device_remove_file(pfe->dev, &dev_attr_pfemem); -+#endif -+ -+err_pfemem: -+ device_remove_file(pfe->dev, &dev_attr_tmu3_queues); -+ -+err_tmu3_queues: -+ device_remove_file(pfe->dev, &dev_attr_tmu2_queues); -+ -+err_tmu2_queues: -+ device_remove_file(pfe->dev, &dev_attr_tmu1_queues); -+ -+err_tmu1_queues: -+ device_remove_file(pfe->dev, &dev_attr_tmu0_queues); -+ -+err_tmu0_queues: -+ device_remove_file(pfe->dev, &dev_attr_drops); -+ -+err_drops: -+ device_remove_file(pfe->dev, &dev_attr_gpi); -+ -+err_gpi: -+ device_remove_file(pfe->dev, &dev_attr_hif); -+ -+err_hif: -+ device_remove_file(pfe->dev, &dev_attr_bmu); -+ -+err_bmu: -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ device_remove_file(pfe->dev, &dev_attr_util); -+ -+err_util: -+#endif -+ device_remove_file(pfe->dev, &dev_attr_tmu); -+ -+err_tmu: -+ device_remove_file(pfe->dev, &dev_attr_class); -+ -+err_class: -+ return -1; -+} -+ -+void pfe_sysfs_exit(struct pfe *pfe) -+{ -+#ifdef HIF_NAPI_STATS -+ device_remove_file(pfe->dev, &dev_attr_hif_napi_stats); -+#endif -+ device_remove_file(pfe->dev, &dev_attr_pfemem); -+ device_remove_file(pfe->dev, &dev_attr_tmu3_queues); -+ device_remove_file(pfe->dev, &dev_attr_tmu2_queues); -+ device_remove_file(pfe->dev, &dev_attr_tmu1_queues); -+ device_remove_file(pfe->dev, &dev_attr_tmu0_queues); -+ device_remove_file(pfe->dev, &dev_attr_drops); -+ device_remove_file(pfe->dev, &dev_attr_gpi); -+ device_remove_file(pfe->dev, &dev_attr_hif); -+ device_remove_file(pfe->dev, &dev_attr_bmu); -+#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED) -+ device_remove_file(pfe->dev, &dev_attr_util); -+#endif -+ device_remove_file(pfe->dev, &dev_attr_tmu); -+ device_remove_file(pfe->dev, &dev_attr_class); -+} diff --git a/target/linux/layerscape/patches-5.4/701-net-0287-staging-fsl_ppfe-eth-fix-RGMII-tx-delay-issue.patch b/target/linux/layerscape/patches-5.4/701-net-0287-staging-fsl_ppfe-eth-fix-RGMII-tx-delay-issue.patch deleted file mode 100644 index 47dc87dbf2..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0287-staging-fsl_ppfe-eth-fix-RGMII-tx-delay-issue.patch +++ /dev/null @@ -1,30 +0,0 @@ -From b62abd01cce8c4548d380d4ff28984a0275ea8fb Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 11 Oct 2017 19:23:38 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: fix RGMII tx delay issue - -Recently logic to enable RGMII tx delay was changed by -below patch. - -https://patchwork.kernel.org/patch/9447581/ - -Based on the patch, appropriate change is made in PFE driver. - -Signed-off-by: Calvin Johnson -Signed-off-by: Anjaneyulu Jagarlmudi ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -1068,7 +1068,8 @@ static void pfe_eth_adjust_link(struct n - new_state = 1; - gemac_set_speed(priv->EMAC_baseaddr, - pfe_get_phydev_speed(phydev)); -- if (priv->einfo->mii_config == PHY_INTERFACE_MODE_RGMII) -+ if (priv->einfo->mii_config == -+ PHY_INTERFACE_MODE_RGMII_TXID) - pfe_set_rgmii_speed(phydev); - priv->oldspeed = phydev->speed; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0288-staging-fsl_ppfe-eth-remove-unused-functions.patch b/target/linux/layerscape/patches-5.4/701-net-0288-staging-fsl_ppfe-eth-remove-unused-functions.patch deleted file mode 100644 index 2e9f4900f4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0288-staging-fsl_ppfe-eth-remove-unused-functions.patch +++ /dev/null @@ -1,96 +0,0 @@ -From accfaecbbcb882dcc2d47660a644c353ae337861 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 18 Oct 2017 14:29:30 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: remove unused functions - -Remove unused functions hif_xmit_pkt & hif_lib_xmit_pkt. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_hif.c | 24 +----------------------- - drivers/staging/fsl_ppfe/pfe_hif_lib.c | 34 ---------------------------------- - 2 files changed, 1 insertion(+), 57 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_hif.c -+++ b/drivers/staging/fsl_ppfe/pfe_hif.c -@@ -844,29 +844,6 @@ skip_tx: - return; - } - --int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no, -- void *data, unsigned int len) --{ -- int rc = 0; -- -- spin_lock_bh(&hif->tx_lock); -- -- if (!hif->txavail) { -- rc = 1; -- } else { -- __hif_xmit_pkt(hif, client_id, q_no, data, len, -- HIF_FIRST_BUFFER | HIF_LAST_BUFFER); -- hif_tx_dma_start(); -- } -- -- if (hif->txavail < (hif->tx_ring_size >> 1)) -- __hif_tx_done_process(hif, TX_FREE_MAX_COUNT); -- -- spin_unlock_bh(&hif->tx_lock); -- -- return rc; --} -- - static irqreturn_t wol_isr(int irq, void *dev_id) - { - pr_info("WoL\n"); -@@ -907,6 +884,7 @@ static irqreturn_t hif_isr(int irq, void - __napi_schedule(&hif->napi); - } - } -+ - if (int_status & HIF_TXPKT_INT) { - int_status &= ~(HIF_TXPKT_INT); - int_enable_mask &= ~(HIF_TXPKT_INT); ---- a/drivers/staging/fsl_ppfe/pfe_hif_lib.c -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c -@@ -512,40 +512,6 @@ void __hif_lib_xmit_pkt(struct hif_clien - queue->jiffies_last_packet = jiffies; - } - --/*This function puts the given packet in the specific client queue */ --int hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data, -- unsigned int len, u32 client_ctrl, void *client_data) --{ -- struct hif_client_tx_queue *queue = &client->tx_q[qno]; -- struct tx_queue_desc *desc = queue->base + queue->write_idx; -- -- if (queue->tx_pending < queue->size) { -- /*Construct pkt header */ -- -- data -= sizeof(struct hif_hdr); -- len += sizeof(struct hif_hdr); -- -- hif_hdr_write(data, client->id, qno, client_ctrl); -- -- desc->data = client_data; -- desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(HIF_FIRST_BUFFER | -- HIF_LAST_BUFFER | HIF_DATA_VALID); -- -- if (hif_xmit_pkt(&pfe->hif, client->id, qno, data, len)) -- return 1; -- -- inc_cl_idx(queue->write_idx); -- queue->tx_pending++; -- queue->jiffies_last_packet = jiffies; -- -- return 0; -- } -- -- pr_debug("%s Tx client %d qno %d is full\n", __func__, client->id, -- qno); -- return 1; --} -- - void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno, - unsigned int *flags, int count) - { diff --git a/target/linux/layerscape/patches-5.4/701-net-0289-staging-fsl_ppfe-eth-fix-read-write-ack-idx-issue.patch b/target/linux/layerscape/patches-5.4/701-net-0289-staging-fsl_ppfe-eth-fix-read-write-ack-idx-issue.patch deleted file mode 100644 index 4ed5b04f50..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0289-staging-fsl_ppfe-eth-fix-read-write-ack-idx-issue.patch +++ /dev/null @@ -1,77 +0,0 @@ -From f44630f1e12462921245feb91fe94d225ba90f9c Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 18 Oct 2017 18:34:41 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: fix read/write/ack idx issue - -While fixing checkpatch errors some of the index increments -were commented out. They are enabled. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_hif.c | 8 ++++---- - drivers/staging/fsl_ppfe/pfe_hif_lib.c | 9 +++------ - 2 files changed, 7 insertions(+), 10 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_hif.c -+++ b/drivers/staging/fsl_ppfe/pfe_hif.c -@@ -511,9 +511,9 @@ static void *client_put_rxpacket(struct - */ - smp_wmb(); - writel(CL_DESC_BUF_LEN(len) | flags, &desc->ctrl); -- /* queue->write_idx = (queue->write_idx + 1) -- * & (queue->size - 1); -- */ -+ queue->write_idx = (queue->write_idx + 1) -+ & (queue->size - 1); -+ - free_pkt += pfe_pkt_headroom; - } - } -@@ -703,7 +703,7 @@ static int client_ack_txpacket(struct pf - - if (readl(&desc->ctrl) & CL_DESC_OWN) { - writel((readl(&desc->ctrl) & ~CL_DESC_OWN), &desc->ctrl); -- /* queue->ack_idx = (queue->ack_idx + 1) & (queue->size - 1); */ -+ queue->ack_idx = (queue->ack_idx + 1) & (queue->size - 1); - - return 0; - ---- a/drivers/staging/fsl_ppfe/pfe_hif_lib.c -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c -@@ -211,9 +211,6 @@ err: - return 1; - } - --#define inc_cl_idx(idxname) \ -- ({ typeof(idxname) idxname_ = (idxname); \ -- ((idxname_) = (idxname_ + 1) & (queue->size - 1)); }) - - static void hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue) - { -@@ -465,7 +462,7 @@ void *hif_lib_receive_pkt(struct hif_cli - smp_wmb(); - - desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) | CL_DESC_OWN; -- inc_cl_idx(queue->read_idx); -+ queue->read_idx = (queue->read_idx + 1) & (queue->size - 1); - } - - /*spin_unlock_irqrestore(&client->rx_lock, flags); */ -@@ -507,7 +504,7 @@ void __hif_lib_xmit_pkt(struct hif_clien - - __hif_xmit_pkt(&pfe->hif, client->id, qno, data, len, flags); - -- inc_cl_idx(queue->write_idx); -+ queue->write_idx = (queue->write_idx + 1) & (queue->size - 1); - queue->tx_pending++; - queue->jiffies_last_packet = jiffies; - } -@@ -544,7 +541,7 @@ void *hif_lib_tx_get_next_complete(struc - if (desc->ctrl & CL_DESC_OWN) - return NULL; - -- inc_cl_idx(queue->read_idx); -+ queue->read_idx = (queue->read_idx + 1) & (queue->size - 1); - queue->tx_pending--; - - *flags = CL_DESC_GET_FLAGS(desc->ctrl); diff --git a/target/linux/layerscape/patches-5.4/701-net-0290-staging-fsl_ppfe-eth-Make-phy_ethtool_ksettings_get-.patch b/target/linux/layerscape/patches-5.4/701-net-0290-staging-fsl_ppfe-eth-Make-phy_ethtool_ksettings_get-.patch deleted file mode 100644 index 59b15fff15..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0290-staging-fsl_ppfe-eth-Make-phy_ethtool_ksettings_get-.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 48d54be45c3b8735f90792e6480e7d6cf0ec1586 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Fri, 27 Oct 2017 11:20:47 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: Make phy_ethtool_ksettings_get return - void - -Make return value void since function never return meaningful value - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -577,7 +577,9 @@ static int pfe_eth_get_settings(struct n - if (!phydev) - return -ENODEV; - -- return phy_ethtool_ksettings_get(phydev, cmd); -+ phy_ethtool_ksettings_get(phydev, cmd); -+ -+ return 0; - } - - /* diff --git a/target/linux/layerscape/patches-5.4/701-net-0291-staging-fsl_ppfe-eth-add-function-to-update-tmu-cred.patch b/target/linux/layerscape/patches-5.4/701-net-0291-staging-fsl_ppfe-eth-add-function-to-update-tmu-cred.patch deleted file mode 100644 index 72152bf786..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0291-staging-fsl_ppfe-eth-add-function-to-update-tmu-cred.patch +++ /dev/null @@ -1,68 +0,0 @@ -From cc230f5618174506889f98ac6b79e72ac9d9d9e4 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 15 Nov 2017 13:45:27 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: add function to update tmu credits - -__hif_lib_update_credit function is used to update the tmu credits. -If tx_qos is set, tmu credit is updated based on the number of packets -transmitted by tmu. - -Signed-off-by: Calvin Johnson -Signed-off-by: Anjaneyulu Jagarlmudi ---- - drivers/staging/fsl_ppfe/pfe_hif_lib.c | 33 +++++++++++++++++++++++++++++++++ - drivers/staging/fsl_ppfe/pfe_hif_lib.h | 1 + - 2 files changed, 34 insertions(+) - ---- a/drivers/staging/fsl_ppfe/pfe_hif_lib.c -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c -@@ -565,6 +565,39 @@ static void hif_lib_tmu_credit_init(stru - } - } - -+/* __hif_lib_update_credit -+ * -+ * @param[in] client hif client context -+ * @param[in] queue queue number in match with TMU -+ */ -+void __hif_lib_update_credit(struct hif_client_s *client, unsigned int queue) -+{ -+ unsigned int tmu_tx_packets, tmp; -+ -+ if (tx_qos) { -+ tmu_tx_packets = be32_to_cpu(pe_dmem_read(TMU0_ID + -+ client->id, TMU_DM_TX_TRANS, 4)); -+ -+ /* tx_packets counter overflowed */ -+ if (tmu_tx_packets > -+ pfe->tmu_credit.tx_packets[client->id][queue]) { -+ tmp = UINT_MAX - tmu_tx_packets + -+ pfe->tmu_credit.tx_packets[client->id][queue]; -+ -+ pfe->tmu_credit.tx_credit[client->id][queue] = -+ pfe->tmu_credit.tx_credit_max[client->id][queue] - tmp; -+ } else { -+ /* TMU tx <= pfe_eth tx, normal case or both OF since -+ * last time -+ */ -+ pfe->tmu_credit.tx_credit[client->id][queue] = -+ pfe->tmu_credit.tx_credit_max[client->id][queue] - -+ (pfe->tmu_credit.tx_packets[client->id][queue] - -+ tmu_tx_packets); -+ } -+ } -+} -+ - int pfe_hif_lib_init(struct pfe *pfe) - { - int rc; ---- a/drivers/staging/fsl_ppfe/pfe_hif_lib.h -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.h -@@ -185,6 +185,7 @@ void *hif_lib_tx_get_next_complete(struc - void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int - *ofst, unsigned int *rx_ctrl, - unsigned int *desc_ctrl, void **priv_data); -+void __hif_lib_update_credit(struct hif_client_s *client, unsigned int queue); - void hif_lib_set_rx_cpu_affinity(struct hif_client_s *client, int cpu_id); - void hif_lib_set_tx_queue_nocpy(struct hif_client_s *client, int qno, int - enable); diff --git a/target/linux/layerscape/patches-5.4/701-net-0292-staging-fsl_ppfe-eth-Avoid-packet-drop-at-TMU-queues.patch b/target/linux/layerscape/patches-5.4/701-net-0292-staging-fsl_ppfe-eth-Avoid-packet-drop-at-TMU-queues.patch deleted file mode 100644 index eeea3740dd..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0292-staging-fsl_ppfe-eth-Avoid-packet-drop-at-TMU-queues.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 8b99b4595d2b5f4d0b2252b16de83572e03b337a Mon Sep 17 00:00:00 2001 -From: Kavi Akhila-B46177 -Date: Thu, 2 Nov 2017 12:05:35 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: Avoid packet drop at TMU queues - -Added flow control between TMU queues and PFE Linux driver, -based on TMU credits availability. -Added tx_qos module parameter to control this behavior. -Use queue-0 as default queue to transmit packets. - -Signed-off-by: Calvin Johnson -Signed-off-by: Akhila Kavi -Signed-off-by: Anjaneyulu Jagarlmudi ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 17 +++++++++++++---- - drivers/staging/fsl_ppfe/pfe_hif_lib.c | 7 +++++-- - 2 files changed, 18 insertions(+), 6 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -293,10 +293,10 @@ static int pfe_eth_sysfs_init(struct net - /* Initialize the default values */ - - /* -- * By default, packets without conntrack will use this default high -+ * By default, packets without conntrack will use this default low - * priority queue - */ -- priv->default_priority = 15; -+ priv->default_priority = 0; - - /* Create our sysfs files */ - err = device_create_file(&ndev->dev, &dev_attr_default_priority); -@@ -1566,10 +1566,17 @@ static int pfe_eth_might_stop_tx(struct - unsigned int n_segs) - { - ktime_t kt; -+ int tried = 0; - -+try_again: - if (unlikely((__hif_tx_avail(&pfe->hif) < n_desc) || -- (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) || -+ (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) || - (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) < n_segs))) { -+ if (!tried) { -+ __hif_lib_update_credit(&priv->client, queuenum); -+ tried = 1; -+ goto try_again; -+ } - #ifdef PFE_ETH_TX_STATS - if (__hif_tx_avail(&pfe->hif) < n_desc) { - priv->stop_queue_hif[queuenum]++; -@@ -1692,8 +1699,10 @@ static void pfe_eth_flush_tx(struct pfe_ - - netif_info(priv, tx_done, priv->ndev, "%s\n", __func__); - -- for (ii = 0; ii < emac_txq_cnt; ii++) -+ for (ii = 0; ii < emac_txq_cnt; ii++) { - pfe_eth_flush_txQ(priv, ii, 0, 0); -+ __hif_lib_update_credit(&priv->client, ii); -+ } - } - - void pfe_tx_get_req_desc(struct sk_buff *skb, unsigned int *n_desc, unsigned int ---- a/drivers/staging/fsl_ppfe/pfe_hif_lib.c -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c -@@ -34,7 +34,10 @@ - - unsigned int lro_mode; - unsigned int page_mode; --unsigned int tx_qos; -+unsigned int tx_qos = 1; -+module_param(tx_qos, uint, 0444); -+MODULE_PARM_DESC(tx_qos, "0: disable ,\n" -+ "1: enable (default), guarantee no packet drop at TMU level\n"); - unsigned int pfe_pkt_size; - unsigned int pfe_pkt_headroom; - unsigned int emac_txq_cnt; -@@ -576,7 +579,7 @@ void __hif_lib_update_credit(struct hif_ - - if (tx_qos) { - tmu_tx_packets = be32_to_cpu(pe_dmem_read(TMU0_ID + -- client->id, TMU_DM_TX_TRANS, 4)); -+ client->id, (TMU_DM_TX_TRANS + (queue * 4)), 4)); - - /* tx_packets counter overflowed */ - if (tmu_tx_packets > diff --git a/target/linux/layerscape/patches-5.4/701-net-0293-staging-fsl_ppfe-eth-Enable-PFE-in-clause-45-mode.patch b/target/linux/layerscape/patches-5.4/701-net-0293-staging-fsl_ppfe-eth-Enable-PFE-in-clause-45-mode.patch deleted file mode 100644 index dac3a93721..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0293-staging-fsl_ppfe-eth-Enable-PFE-in-clause-45-mode.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 666f91f706c167b061ec29f45936a9f24e86e55c Mon Sep 17 00:00:00 2001 -From: Bhaskar Upadhaya -Date: Wed, 29 Nov 2017 12:08:00 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: Enable PFE in clause 45 mode - -when we opearate in clause 45 mode, we need to call -the function get_phy_device() with its 3rd argument as -"true" and then the resultant phy device needs to be -register with phy layer via phy_device_register() - -Signed-off-by: Bhaskar Upadhaya ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 32 +++++++++++++++++++++++++++++--- - 1 file changed, 29 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -923,7 +923,8 @@ static int pfe_eth_mdio_init(struct pfe_ - struct ls1012a_mdio_platform_data *minfo) - { - struct mii_bus *bus; -- int rc; -+ int rc, ii; -+ struct phy_device *phydev; - - netif_info(priv, drv, priv->ndev, "%s\n", __func__); - pr_info("%s\n", __func__); -@@ -962,6 +963,31 @@ static int pfe_eth_mdio_init(struct pfe_ - } - - priv->mii_bus = bus; -+ -+ /* For clause 45 we need to call get_phy_device() with it's -+ * 3rd argument as true and then register the phy device -+ * via phy_device_register() -+ */ -+ -+ if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) { -+ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) { -+ phydev = get_phy_device(priv->mii_bus, -+ priv->einfo->phy_id + ii, true); -+ if (!phydev || IS_ERR(phydev)) { -+ rc = -EIO; -+ netdev_err(priv->ndev, "fail to get device\n"); -+ goto err1; -+ } -+ rc = phy_device_register(phydev); -+ if (rc) { -+ phy_device_free(phydev); -+ netdev_err(priv->ndev, -+ "phy_device_register() failed\n"); -+ goto err1; -+ } -+ } -+ } -+ - pfe_eth_mdio_reset(bus); - - return 0; -@@ -1149,7 +1175,7 @@ static void ls1012a_configure_serdes(str - int sgmii_2500 = 0; - struct mii_bus *bus = priv->mii_bus; - -- if (priv->einfo->mii_config == PHY_INTERFACE_MODE_SGMII_2500) -+ if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) - sgmii_2500 = 1; - - netif_info(priv, drv, ndev, "%s\n", __func__); -@@ -1198,7 +1224,7 @@ static int pfe_phy_init(struct net_devic - netif_info(priv, drv, ndev, "%s: %s\n", __func__, phy_id); - interface = priv->einfo->mii_config; - if ((interface == PHY_INTERFACE_MODE_SGMII) || -- (interface == PHY_INTERFACE_MODE_SGMII_2500)) { -+ (interface == PHY_INTERFACE_MODE_2500SGMII)) { - /*Configure SGMII PCS */ - if (pfe->scfg) { - /*Config MDIO from serdes */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0294-staging-fsl_ppfe-eth-Disable-autonegotiation-for-2.5.patch b/target/linux/layerscape/patches-5.4/701-net-0294-staging-fsl_ppfe-eth-Disable-autonegotiation-for-2.5.patch deleted file mode 100644 index 3c0abc812d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0294-staging-fsl_ppfe-eth-Disable-autonegotiation-for-2.5.patch +++ /dev/null @@ -1,42 +0,0 @@ -From caae8a691922c3702fcb813f5d794f311c0609c6 Mon Sep 17 00:00:00 2001 -From: Bhaskar Upadhaya -Date: Wed, 29 Nov 2017 12:21:43 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: Disable autonegotiation for 2.5G SGMII - -PCS initialization sequence for 2.5G SGMII interface governs -auto negotiation to be in disabled mode - -Signed-off-by: Bhaskar Upadhaya ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -1174,6 +1174,7 @@ static void ls1012a_configure_serdes(str - struct pfe_eth_priv_s *priv = pfe->eth.eth_priv[0]; - int sgmii_2500 = 0; - struct mii_bus *bus = priv->mii_bus; -+ u16 value = 0; - - if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) - sgmii_2500 = 1; -@@ -1191,14 +1192,16 @@ static void ls1012a_configure_serdes(str - pfe_eth_mdio_write(bus, 0, 0x4, 0x4001); - pfe_eth_mdio_write(bus, 0, 0x12, 0xa120); - pfe_eth_mdio_write(bus, 0, 0x13, 0x7); -+ /* Autonegotiation need to be disabled for 2.5G SGMII mode*/ -+ value = 0x0140; -+ pfe_eth_mdio_write(bus, 0, 0x0, value); - } else { - pfe_eth_mdio_write(bus, 0, 0x14, 0xb); - pfe_eth_mdio_write(bus, 0, 0x4, 0x1a1); - pfe_eth_mdio_write(bus, 0, 0x12, 0x400); - pfe_eth_mdio_write(bus, 0, 0x13, 0x0); -+ pfe_eth_mdio_write(bus, 0, 0x0, 0x1140); - } -- -- pfe_eth_mdio_write(bus, 0, 0x0, 0x1140); - } - - /* diff --git a/target/linux/layerscape/patches-5.4/701-net-0295-staging-fsl_ppfe-eth-calculate-PFE_PKT_SIZE-with-SKB.patch b/target/linux/layerscape/patches-5.4/701-net-0295-staging-fsl_ppfe-eth-calculate-PFE_PKT_SIZE-with-SKB.patch deleted file mode 100644 index f42ec78f09..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0295-staging-fsl_ppfe-eth-calculate-PFE_PKT_SIZE-with-SKB.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 2f59069dbb48ee86bee42bf36a4dfafe64028344 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Thu, 8 Mar 2018 13:58:38 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: calculate PFE_PKT_SIZE with - SKB_DATA_ALIGN - -pfe packet size was calculated without considering skb data alignment -and this resulted in jumbo frames crashing kernel when the -cacheline size increased from 64 to 128 bytes with -commit 97303480753e ("arm64: Increase the max granular size"). - -Modify pfe packet size caclulation to include skb data alignment of -sizeof(struct skb_shared_info). - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_hif_lib.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/fsl_ppfe/pfe_hif_lib.h -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.h -@@ -146,7 +146,7 @@ struct tx_queue_desc { - #define PFE_BUF_SIZE 2048 - #define PFE_PKT_HEADROOM 128 - --#define SKB_SHARED_INFO_SIZE (sizeof(struct skb_shared_info)) -+#define SKB_SHARED_INFO_SIZE SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) - #define PFE_PKT_SIZE (PFE_BUF_SIZE - PFE_PKT_HEADROOM \ - - SKB_SHARED_INFO_SIZE) - #define MAX_L2_HDR_SIZE 14 /* Not correct for VLAN/PPPoE */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0296-staging-fsl_ppfe-eth-support-for-userspace-networkin.patch b/target/linux/layerscape/patches-5.4/701-net-0296-staging-fsl_ppfe-eth-support-for-userspace-networkin.patch deleted file mode 100644 index b3f3fe91b3..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0296-staging-fsl_ppfe-eth-support-for-userspace-networkin.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 25d189ea016270d1d7ab67eafc57bc8989b5381c Mon Sep 17 00:00:00 2001 -From: Akhil Goyal -Date: Fri, 13 Apr 2018 15:41:28 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: support for userspace networking - -This patch adds the userspace mode support to fsl_ppfe network driver. -In the new mode, basic hardware initialization is performed in kernel, while -the datapath and HIF handling is the responsibility of the userspace. - -The new command line parameter is added to initialize the ppfe module -in userspace mode. By default the module remains in kernelspace networking -mode. -To enable userspace mode, use "insmod pfe.ko us=1" - -Signed-off-by: Akhil Goyal -Signed-off-by: Gagandeep Singh ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 21 +++++++++++++++++++-- - drivers/staging/fsl_ppfe/pfe_mod.c | 15 +++++++++++++++ - drivers/staging/fsl_ppfe/pfe_mod.h | 2 ++ - 3 files changed, 36 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -2296,6 +2296,8 @@ static int pfe_eth_init_one(struct pfe * - goto err0; - } - -+ if (us) -+ emac_txq_cnt = EMAC_TXQ_CNT; - /* Create an ethernet device instance */ - ndev = alloc_etherdev_mq(sizeof(*priv), emac_txq_cnt); - -@@ -2342,6 +2344,9 @@ static int pfe_eth_init_one(struct pfe * - } - } - -+ if (us) -+ goto phy_init; -+ - ndev->mtu = 1500; - - /* Set MTU limits */ -@@ -2381,6 +2386,8 @@ static int pfe_eth_init_one(struct pfe * - netdev_err(ndev, "register_netdev() failed\n"); - goto err3; - } -+ -+phy_init: - device_init_wakeup(&ndev->dev, WAKE_MAGIC); - - if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) { -@@ -2392,6 +2399,12 @@ static int pfe_eth_init_one(struct pfe * - } - } - -+ if (us) { -+ if (priv->phydev) -+ phy_start(priv->phydev); -+ return 0; -+ } -+ - netif_carrier_on(ndev); - - /* Create all the sysfs files */ -@@ -2403,6 +2416,8 @@ static int pfe_eth_init_one(struct pfe * - - return 0; - err4: -+ if (us) -+ goto err3; - unregister_netdev(ndev); - err3: - pfe_eth_mdio_exit(priv->mii_bus); -@@ -2449,9 +2464,11 @@ static void pfe_eth_exit_one(struct pfe_ - { - netif_info(priv, probe, priv->ndev, "%s\n", __func__); - -- pfe_eth_sysfs_exit(priv->ndev); -+ if (!us) { -+ pfe_eth_sysfs_exit(priv->ndev); - -- unregister_netdev(priv->ndev); -+ unregister_netdev(priv->ndev); -+ } - - if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) - pfe_phy_exit(priv->ndev); ---- a/drivers/staging/fsl_ppfe/pfe_mod.c -+++ b/drivers/staging/fsl_ppfe/pfe_mod.c -@@ -19,6 +19,10 @@ - #include - #include "pfe_mod.h" - -+unsigned int us; -+module_param(us, uint, 0444); -+MODULE_PARM_DESC(us, "0: module enabled for kernel networking (DEFAULT)\n" -+ "1: module enabled for userspace networking\n"); - struct pfe *pfe; - - /* -@@ -56,6 +60,9 @@ int pfe_probe(struct pfe *pfe) - if (rc < 0) - goto err_hw; - -+ if (us) -+ goto firmware_init; -+ - rc = pfe_hif_lib_init(pfe); - if (rc < 0) - goto err_hif_lib; -@@ -64,6 +71,7 @@ int pfe_probe(struct pfe *pfe) - if (rc < 0) - goto err_hif; - -+firmware_init: - rc = pfe_firmware_init(pfe); - if (rc < 0) - goto err_firmware; -@@ -99,6 +107,9 @@ err_ctrl: - pfe_firmware_exit(pfe); - - err_firmware: -+ if (us) -+ goto err_hif_lib; -+ - pfe_hif_exit(pfe); - - err_hif: -@@ -131,10 +142,14 @@ int pfe_remove(struct pfe *pfe) - #endif - pfe_firmware_exit(pfe); - -+ if (us) -+ goto hw_exit; -+ - pfe_hif_exit(pfe); - - pfe_hif_lib_exit(pfe); - -+hw_exit: - pfe_hw_exit(pfe); - - return 0; ---- a/drivers/staging/fsl_ppfe/pfe_mod.h -+++ b/drivers/staging/fsl_ppfe/pfe_mod.h -@@ -22,6 +22,8 @@ - #include - #include - -+extern unsigned int us; -+ - struct pfe; - - #include "pfe_hw.h" diff --git a/target/linux/layerscape/patches-5.4/701-net-0297-staging-fsl_ppfe-eth-unregister-netdev-after-pfe_phy.patch b/target/linux/layerscape/patches-5.4/701-net-0297-staging-fsl_ppfe-eth-unregister-netdev-after-pfe_phy.patch deleted file mode 100644 index 0731329384..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0297-staging-fsl_ppfe-eth-unregister-netdev-after-pfe_phy.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 4ebb4e490dd924d1a8ca7fe693a0dd1cfa150687 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Mon, 30 Apr 2018 11:40:01 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: unregister netdev after pfe_phy_exit - -rmmod pfe.ko throws below warning: - -kernfs: can not remove 'phydev', no directory -------------[ cut here ]------------ -WARNING: CPU: 0 PID: 2230 at fs/kernfs/dir.c:1481 -kernfs_remove_by_name_ns+0x90/0xa0 - -This is caused when the unregistered netdev structure is accessed to -disconnect phy. - -Resolve the issue by unregistering netdev after disconnecting phy. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -2464,15 +2464,15 @@ static void pfe_eth_exit_one(struct pfe_ - { - netif_info(priv, probe, priv->ndev, "%s\n", __func__); - -- if (!us) { -+ if (!us) - pfe_eth_sysfs_exit(priv->ndev); - -- unregister_netdev(priv->ndev); -- } -- - if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) - pfe_phy_exit(priv->ndev); - -+ if (!us) -+ unregister_netdev(priv->ndev); -+ - if (priv->mii_bus) - pfe_eth_mdio_exit(priv->mii_bus); - diff --git a/target/linux/layerscape/patches-5.4/701-net-0298-staging-fsl_ppfe-eth-HW-parse-results-for-DPDK.patch b/target/linux/layerscape/patches-5.4/701-net-0298-staging-fsl_ppfe-eth-HW-parse-results-for-DPDK.patch deleted file mode 100644 index f8ec3495a2..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0298-staging-fsl_ppfe-eth-HW-parse-results-for-DPDK.patch +++ /dev/null @@ -1,47 +0,0 @@ -From fd2bdf555ab192a96a44fa02f701095b24448d47 Mon Sep 17 00:00:00 2001 -From: anuj batham -Date: Fri, 27 Apr 2018 14:38:09 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: HW parse results for DPDK - -HW Parse results are included in the packet headroom. -Length and Offset calculation now accommodates parse info size. - -Signed-off-by: Archana Madhavan ---- - drivers/staging/fsl_ppfe/pfe_hif_lib.c | 7 +++++-- - drivers/staging/fsl_ppfe/pfe_hif_lib.h | 1 + - 2 files changed, 6 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_hif_lib.c -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c -@@ -435,6 +435,7 @@ void *hif_lib_receive_pkt(struct hif_cli - u16 size = *rx_ctrl >> HIF_CTRL_RX_OFFSET_OFST; - - if (size) { -+ size += PFE_PARSE_INFO_SIZE; - *len = CL_DESC_BUF_LEN(desc->ctrl) - - PFE_PKT_HEADER_SZ - size; - *ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ -@@ -442,8 +443,10 @@ void *hif_lib_receive_pkt(struct hif_cli - *priv_data = desc->data + PFE_PKT_HEADER_SZ; - } else { - *len = CL_DESC_BUF_LEN(desc->ctrl) - -- PFE_PKT_HEADER_SZ; -- *ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ; -+ PFE_PKT_HEADER_SZ - PFE_PARSE_INFO_SIZE; -+ *ofst = pfe_pkt_headroom -+ + PFE_PKT_HEADER_SZ -+ + PFE_PARSE_INFO_SIZE; - *priv_data = NULL; - } - ---- a/drivers/staging/fsl_ppfe/pfe_hif_lib.h -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.h -@@ -23,6 +23,7 @@ - - #define HIF_CL_REQ_TIMEOUT 10 - #define GFP_DMA_PFE 0 -+#define PFE_PARSE_INFO_SIZE 16 - - enum { - REQUEST_CL_REGISTER = 0, diff --git a/target/linux/layerscape/patches-5.4/701-net-0299-staging-fsl_ppfe-eth-reorganize-pfe_netdev_ops.patch b/target/linux/layerscape/patches-5.4/701-net-0299-staging-fsl_ppfe-eth-reorganize-pfe_netdev_ops.patch deleted file mode 100644 index f17a53baaa..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0299-staging-fsl_ppfe-eth-reorganize-pfe_netdev_ops.patch +++ /dev/null @@ -1,30 +0,0 @@ -From c4e167b4cd8c5b74b04bf69ebf93796a7be3d83d Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 20 Jun 2018 10:22:32 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: reorganize pfe_netdev_ops - -Reorganize members of struct pfe_netdev_ops to match with the order -of members in struct net_device_ops defined in include/linux/netdevice.h - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -2243,11 +2243,11 @@ static const struct net_device_ops pfe_n - .ndo_stop = pfe_eth_close, - .ndo_start_xmit = pfe_eth_send_packet, - .ndo_select_queue = pfe_eth_select_queue, -- .ndo_get_stats = pfe_eth_get_stats, -- .ndo_set_mac_address = pfe_eth_set_mac_address, - .ndo_set_rx_mode = pfe_eth_set_multi, -- .ndo_set_features = pfe_eth_set_features, -+ .ndo_set_mac_address = pfe_eth_set_mac_address, - .ndo_validate_addr = eth_validate_addr, -+ .ndo_get_stats = pfe_eth_get_stats, -+ .ndo_set_features = pfe_eth_set_features, - }; - - /* pfe_eth_init_one diff --git a/target/linux/layerscape/patches-5.4/701-net-0300-staging-fsl_ppfe-eth-use-mask-for-rx-max-frame-len.patch b/target/linux/layerscape/patches-5.4/701-net-0300-staging-fsl_ppfe-eth-use-mask-for-rx-max-frame-len.patch deleted file mode 100644 index 457bc6882a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0300-staging-fsl_ppfe-eth-use-mask-for-rx-max-frame-len.patch +++ /dev/null @@ -1,46 +0,0 @@ -From f5be11cd83a6d6d4de7bd7cbeb641bb1032c4f84 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 20 Jun 2018 10:22:50 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: use mask for rx max frame len - -Define and use PFE_RCR_MAX_FL_MASK to properly set Rx max frame -length of MAC Receive Control Register. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_hal.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_hal.c -+++ b/drivers/staging/fsl_ppfe/pfe_hal.c -@@ -19,6 +19,8 @@ - #include "pfe_mod.h" - #include "pfe/pfe.h" - -+#define PFE_RCR_MAX_FL_MASK 0xC000FFFF -+ - void *cbus_base_addr; - void *ddr_base_addr; - unsigned long ddr_phys_base_addr; -@@ -1011,8 +1013,8 @@ void gemac_no_broadcast(void *base) - void gemac_enable_1536_rx(void *base) - { - /* Set 1536 as Maximum frame length */ -- writel(readl(base + EMAC_RCNTRL_REG) | (1536 << 16), base + -- EMAC_RCNTRL_REG); -+ writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK) -+ | (1536 << 16), base + EMAC_RCNTRL_REG); - } - - /* GEMAC enable jumbo function. -@@ -1020,8 +1022,8 @@ void gemac_enable_1536_rx(void *base) - */ - void gemac_enable_rx_jmb(void *base) - { -- writel(readl(base + EMAC_RCNTRL_REG) | (JUMBO_FRAME_SIZE << 16), base -- + EMAC_RCNTRL_REG); -+ writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK) -+ | (JUMBO_FRAME_SIZE << 16), base + EMAC_RCNTRL_REG); - } - - /* GEMAC enable stacked vlan function. diff --git a/target/linux/layerscape/patches-5.4/701-net-0301-staging-fsl_ppfe-eth-define-pfe-ndo_change_mtu-funct.patch b/target/linux/layerscape/patches-5.4/701-net-0301-staging-fsl_ppfe-eth-define-pfe-ndo_change_mtu-funct.patch deleted file mode 100644 index f35ea677b6..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0301-staging-fsl_ppfe-eth-define-pfe-ndo_change_mtu-funct.patch +++ /dev/null @@ -1,73 +0,0 @@ -From d9c44cf1a757823fb069dea0c15a830513175bf3 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 20 Jun 2018 10:23:01 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: define pfe ndo_change_mtu function - -Define ndo_change_mtu function for pfe. This sets the max Rx frame -length to the new mtu. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/include/pfe/pfe.h | 1 + - drivers/staging/fsl_ppfe/pfe_eth.c | 12 ++++++++++++ - drivers/staging/fsl_ppfe/pfe_hal.c | 11 +++++++++++ - 3 files changed, 24 insertions(+) - ---- a/drivers/staging/fsl_ppfe/include/pfe/pfe.h -+++ b/drivers/staging/fsl_ppfe/include/pfe/pfe.h -@@ -303,6 +303,7 @@ void gemac_allow_broadcast(void *base); - void gemac_no_broadcast(void *base); - void gemac_enable_1536_rx(void *base); - void gemac_disable_1536_rx(void *base); -+void gemac_set_rx_max_fl(void *base, int mtu); - void gemac_enable_rx_jmb(void *base); - void gemac_disable_rx_jmb(void *base); - void gemac_enable_stacked_vlan(void *base); ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -1345,6 +1345,17 @@ static int pfe_eth_event_handler(void *d - return 0; - } - -+static int pfe_eth_change_mtu(struct net_device *ndev, int new_mtu) -+{ -+ struct pfe_eth_priv_s *priv = netdev_priv(ndev); -+ -+ ndev->mtu = new_mtu; -+ new_mtu += ETH_HLEN + ETH_FCS_LEN; -+ gemac_set_rx_max_fl(priv->EMAC_baseaddr, new_mtu); -+ -+ return 0; -+} -+ - /* pfe_eth_open - */ - static int pfe_eth_open(struct net_device *ndev) -@@ -2246,6 +2257,7 @@ static const struct net_device_ops pfe_n - .ndo_set_rx_mode = pfe_eth_set_multi, - .ndo_set_mac_address = pfe_eth_set_mac_address, - .ndo_validate_addr = eth_validate_addr, -+ .ndo_change_mtu = pfe_eth_change_mtu, - .ndo_get_stats = pfe_eth_get_stats, - .ndo_set_features = pfe_eth_set_features, - }; ---- a/drivers/staging/fsl_ppfe/pfe_hal.c -+++ b/drivers/staging/fsl_ppfe/pfe_hal.c -@@ -1017,6 +1017,17 @@ void gemac_enable_1536_rx(void *base) - | (1536 << 16), base + EMAC_RCNTRL_REG); - } - -+/* GEMAC set rx Max frame length. -+ * @param[in] base GEMAC base address -+ * @param[in] mtu new mtu -+ */ -+void gemac_set_rx_max_fl(void *base, int mtu) -+{ -+ /* Set mtu as Maximum frame length */ -+ writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK) -+ | (mtu << 16), base + EMAC_RCNTRL_REG); -+} -+ - /* GEMAC enable jumbo function. - * @param[in] base GEMAC base address - */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0302-staging-fsl_ppfe-eth-remove-jumbo-frame-enable-from-.patch b/target/linux/layerscape/patches-5.4/701-net-0302-staging-fsl_ppfe-eth-remove-jumbo-frame-enable-from-.patch deleted file mode 100644 index a98c55120c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0302-staging-fsl_ppfe-eth-remove-jumbo-frame-enable-from-.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 162c09cee1b5b00e09fd99273fd2f8c460c0d989 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 20 Jun 2018 10:23:16 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: remove jumbo frame enable from gemac - init - -MAC Receive Control Register was configured to allow jumbo frames. -This is removed as jumbo frames can be supported anytime by changing -mtu which will in turn modify MAX_FL field of MAC RCR. -Jumbo frames caused pfe to hang on LS1012A rev 1.0 Silicon due to -erratum A-010897. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 1 - - drivers/staging/fsl_ppfe/pfe_hal.c | 9 --------- - 2 files changed, 10 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -1272,7 +1272,6 @@ static int pfe_gemac_init(struct pfe_eth - gemac_set_config(priv->EMAC_baseaddr, &cfg); - gemac_allow_broadcast(priv->EMAC_baseaddr); - gemac_enable_1536_rx(priv->EMAC_baseaddr); -- gemac_enable_rx_jmb(priv->EMAC_baseaddr); - gemac_enable_stacked_vlan(priv->EMAC_baseaddr); - gemac_enable_pause_rx(priv->EMAC_baseaddr); - gemac_set_bus_width(priv->EMAC_baseaddr, 64); ---- a/drivers/staging/fsl_ppfe/pfe_hal.c -+++ b/drivers/staging/fsl_ppfe/pfe_hal.c -@@ -1028,15 +1028,6 @@ void gemac_set_rx_max_fl(void *base, int - | (mtu << 16), base + EMAC_RCNTRL_REG); - } - --/* GEMAC enable jumbo function. -- * @param[in] base GEMAC base address -- */ --void gemac_enable_rx_jmb(void *base) --{ -- writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK) -- | (JUMBO_FRAME_SIZE << 16), base + EMAC_RCNTRL_REG); --} -- - /* GEMAC enable stacked vlan function. - * @param[in] base GEMAC base address - */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0303-staging-fsl_ppfe-eth-disable-CRC-removal.patch b/target/linux/layerscape/patches-5.4/701-net-0303-staging-fsl_ppfe-eth-disable-CRC-removal.patch deleted file mode 100644 index c17f8a83d7..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0303-staging-fsl_ppfe-eth-disable-CRC-removal.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 26ddfc3e40c52ca9cb78c6ae4b4608f94d2e8cb5 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 20 Jun 2018 10:23:32 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: disable CRC removal - -Disable CRC removal from the packet, so that packets are forwarded -as is to Linux. -CRC configuration in MAC will be reflected in the packet received -to Linux. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_hal.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_hal.c -+++ b/drivers/staging/fsl_ppfe/pfe_hal.c -@@ -869,8 +869,8 @@ void gemac_set_mode(void *base, int mode - /*Remove loopbank*/ - val &= ~EMAC_RCNTRL_LOOP; - -- /*Enable flow control and MII mode*/ -- val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE); -+ /* Enable flow control and MII mode and terminate received CRC */ -+ val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE | EMAC_RCNTRL_CRC_FWD); - - writel(val, base + EMAC_RCNTRL_REG); - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0304-staging-fsl_ppfe-eth-handle-ls1012a-errata_a010897.patch b/target/linux/layerscape/patches-5.4/701-net-0304-staging-fsl_ppfe-eth-handle-ls1012a-errata_a010897.patch deleted file mode 100644 index d7ee96a388..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0304-staging-fsl_ppfe-eth-handle-ls1012a-errata_a010897.patch +++ /dev/null @@ -1,107 +0,0 @@ -From a563dccef2871e37efcfcb2f3faee7c9f9381f6c Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 20 Jun 2018 10:23:41 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: handle ls1012a errata_a010897 - -On LS1012A rev 1.0, Jumbo frames are not supported as it causes -the PFE controller to hang. A reset of the entire chip is required -to resume normal operation. - -To handle this errata, frames with length > 1900 are truncated for -rev 1.0 of LS1012A. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 20 +++++++++++++++++++- - drivers/staging/fsl_ppfe/pfe_eth.h | 3 ++- - drivers/staging/fsl_ppfe/pfe_hal.c | 10 +++++++++- - 3 files changed, 30 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -44,6 +44,7 @@ - #include - #include - #include -+#include - - #if defined(CONFIG_NF_CONNTRACK_MARK) - #include -@@ -52,6 +53,10 @@ - #include "pfe_mod.h" - #include "pfe_eth.h" - -+#define LS1012A_REV_1_0 0x87040010 -+ -+bool pfe_errata_a010897; -+ - static void *cbus_emac_base[3]; - static void *cbus_gpi_base[3]; - -@@ -2362,7 +2367,15 @@ static int pfe_eth_init_one(struct pfe * - - /* Set MTU limits */ - ndev->min_mtu = ETH_MIN_MTU; -- ndev->max_mtu = JUMBO_FRAME_SIZE; -+ -+/* -+ * Jumbo frames are not supported on LS1012A rev-1.0. -+ * So max mtu should be restricted to supported frame length. -+ */ -+ if (pfe_errata_a010897) -+ ndev->max_mtu = JUMBO_FRAME_SIZE_V1 - ETH_HLEN - ETH_FCS_LEN; -+ else -+ ndev->max_mtu = JUMBO_FRAME_SIZE_V2 - ETH_HLEN - ETH_FCS_LEN; - - /* supported features */ - ndev->hw_features = NETIF_F_SG; -@@ -2453,6 +2466,11 @@ int pfe_eth_init(struct pfe *pfe) - cbus_gpi_base[0] = EGPI1_BASE_ADDR; - cbus_gpi_base[1] = EGPI2_BASE_ADDR; - -+ if (fsl_guts_get_svr() == LS1012A_REV_1_0) -+ pfe_errata_a010897 = true; -+ else -+ pfe_errata_a010897 = false; -+ - for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) { - err = pfe_eth_init_one(pfe, ii); - if (err) ---- a/drivers/staging/fsl_ppfe/pfe_eth.h -+++ b/drivers/staging/fsl_ppfe/pfe_eth.h -@@ -85,7 +85,8 @@ struct ls1012a_pfe_platform_data { - #define EMAC_TXQ_CNT 16 - #define EMAC_TXQ_DEPTH (HIF_TX_DESC_NT) - --#define JUMBO_FRAME_SIZE 10258 -+#define JUMBO_FRAME_SIZE_V1 1900 -+#define JUMBO_FRAME_SIZE_V2 10258 - /* - * Client Tx queue threshold, for txQ flush condition. - * It must be smaller than the queue size (in case we ever change it in the ---- a/drivers/staging/fsl_ppfe/pfe_hal.c -+++ b/drivers/staging/fsl_ppfe/pfe_hal.c -@@ -19,6 +19,9 @@ - #include "pfe_mod.h" - #include "pfe/pfe.h" - -+/* A-010897: Jumbo frame is not supported */ -+extern bool pfe_errata_a010897; -+ - #define PFE_RCR_MAX_FL_MASK 0xC000FFFF - - void *cbus_base_addr; -@@ -1102,7 +1105,12 @@ void gemac_set_config(void *base, struct - /*GEMAC config taken from VLSI */ - writel(0x00000004, base + EMAC_TFWR_STR_FWD); - writel(0x00000005, base + EMAC_RX_SECTION_FULL); -- writel(0x00003fff, base + EMAC_TRUNC_FL); -+ -+ if (pfe_errata_a010897) -+ writel(0x0000076c, base + EMAC_TRUNC_FL); -+ else -+ writel(0x00003fff, base + EMAC_TRUNC_FL); -+ - writel(0x00000030, base + EMAC_TX_SECTION_EMPTY); - writel(0x00000000, base + EMAC_MIB_CTRL_STS_REG); - diff --git a/target/linux/layerscape/patches-5.4/701-net-0305-staging-fsl_ppfe-eth-replace-magic-numbers.patch b/target/linux/layerscape/patches-5.4/701-net-0305-staging-fsl_ppfe-eth-replace-magic-numbers.patch deleted file mode 100644 index 22d865cab4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0305-staging-fsl_ppfe-eth-replace-magic-numbers.patch +++ /dev/null @@ -1,142 +0,0 @@ -From cdebdc900ae5cb29dc1cce1c26865001534ab77d Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Thu, 4 Oct 2018 09:38:34 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: replace magic numbers - -Replace magic numbers and some cosmetic changes. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 83 ++++++++++++++++++++++++++++---------- - 1 file changed, 61 insertions(+), 22 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -66,6 +66,36 @@ static void pfe_eth_flush_tx(struct pfe_ - static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int - from_tx, int n_desc); - -+/* MDIO registers */ -+#define MDIO_SGMII_CR 0x00 -+#define MDIO_SGMII_SR 0x01 -+#define MDIO_SGMII_DEV_ABIL_SGMII 0x04 -+#define MDIO_SGMII_LINK_TMR_L 0x12 -+#define MDIO_SGMII_LINK_TMR_H 0x13 -+#define MDIO_SGMII_IF_MODE 0x14 -+ -+/* SGMII Control defines */ -+#define SGMII_CR_RST 0x8000 -+#define SGMII_CR_AN_EN 0x1000 -+#define SGMII_CR_RESTART_AN 0x0200 -+#define SGMII_CR_FD 0x0100 -+#define SGMII_CR_SPEED_SEL1_1G 0x0040 -+#define SGMII_CR_DEF_VAL (SGMII_CR_AN_EN | SGMII_CR_FD | \ -+ SGMII_CR_SPEED_SEL1_1G) -+ -+/* SGMII IF Mode */ -+#define SGMII_DUPLEX_HALF 0x10 -+#define SGMII_SPEED_10MBPS 0x00 -+#define SGMII_SPEED_100MBPS 0x04 -+#define SGMII_SPEED_1GBPS 0x08 -+#define SGMII_USE_SGMII_AN 0x02 -+#define SGMII_EN 0x01 -+ -+/* SGMII Device Ability for SGMII */ -+#define SGMII_DEV_ABIL_ACK 0x4000 -+#define SGMII_DEV_ABIL_EEE_CLK_STP_EN 0x0100 -+#define SGMII_DEV_ABIL_SGMII 0x0001 -+ - unsigned int gemac_regs[] = { - 0x0004, /* Interrupt event */ - 0x0008, /* Interrupt mask */ -@@ -1042,6 +1072,10 @@ static int pfe_get_phydev_speed(struct p - #define SCFG_RGMIIPCR_SETSP_10M (0x00000002) - #define SCFG_RGMIIPCR_SETFD (0x00000001) - -+#define MDIOSELCR 0x484 -+#define MDIOSEL_SERDES 0x0 -+#define MDIOSEL_EXTPHY 0x80000000 -+ - static void pfe_set_rgmii_speed(struct phy_device *phydev) - { - u32 rgmii_pcr; -@@ -1187,25 +1221,34 @@ static void ls1012a_configure_serdes(str - netif_info(priv, drv, ndev, "%s\n", __func__); - /* PCS configuration done with corresponding GEMAC */ - -- pfe_eth_mdio_read(bus, 0, 0); -- pfe_eth_mdio_read(bus, 0, 1); -+ pfe_eth_mdio_read(bus, 0, MDIO_SGMII_CR); -+ pfe_eth_mdio_read(bus, 0, MDIO_SGMII_SR); -+ -+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, SGMII_CR_RST); - -- /*These settings taken from validtion team */ -- pfe_eth_mdio_write(bus, 0, 0x0, 0x8000); - if (sgmii_2500) { -- pfe_eth_mdio_write(bus, 0, 0x14, 0x9); -- pfe_eth_mdio_write(bus, 0, 0x4, 0x4001); -- pfe_eth_mdio_write(bus, 0, 0x12, 0xa120); -- pfe_eth_mdio_write(bus, 0, 0x13, 0x7); -+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_IF_MODE, SGMII_SPEED_1GBPS -+ | SGMII_EN); -+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_DEV_ABIL_SGMII, -+ SGMII_DEV_ABIL_ACK | SGMII_DEV_ABIL_SGMII); -+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_L, 0xa120); -+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_H, 0x7); - /* Autonegotiation need to be disabled for 2.5G SGMII mode*/ -- value = 0x0140; -- pfe_eth_mdio_write(bus, 0, 0x0, value); -+ value = SGMII_CR_FD | SGMII_CR_SPEED_SEL1_1G; -+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, value); - } else { -- pfe_eth_mdio_write(bus, 0, 0x14, 0xb); -- pfe_eth_mdio_write(bus, 0, 0x4, 0x1a1); -- pfe_eth_mdio_write(bus, 0, 0x12, 0x400); -- pfe_eth_mdio_write(bus, 0, 0x13, 0x0); -- pfe_eth_mdio_write(bus, 0, 0x0, 0x1140); -+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_IF_MODE, -+ SGMII_SPEED_1GBPS -+ | SGMII_USE_SGMII_AN -+ | SGMII_EN); -+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_DEV_ABIL_SGMII, -+ SGMII_DEV_ABIL_EEE_CLK_STP_EN -+ | 0xa0 -+ | SGMII_DEV_ABIL_SGMII); -+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_L, 0x400); -+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_LINK_TMR_H, 0x0); -+ value = SGMII_CR_AN_EN | SGMII_CR_FD | SGMII_CR_SPEED_SEL1_1G; -+ pfe_eth_mdio_write(bus, 0, MDIO_SGMII_CR, value); - } - } - -@@ -1235,15 +1278,15 @@ static int pfe_phy_init(struct net_devic - (interface == PHY_INTERFACE_MODE_2500SGMII)) { - /*Configure SGMII PCS */ - if (pfe->scfg) { -- /*Config MDIO from serdes */ -- regmap_write(pfe->scfg, 0x484, 0x00000000); -+ /* Config MDIO from serdes */ -+ regmap_write(pfe->scfg, MDIOSELCR, MDIOSEL_SERDES); - } - ls1012a_configure_serdes(ndev); - } - - if (pfe->scfg) { - /*Config MDIO from PAD */ -- regmap_write(pfe->scfg, 0x484, 0x80000000); -+ regmap_write(pfe->scfg, MDIOSELCR, MDIOSEL_EXTPHY); - } - - priv->oldlink = 0; -@@ -2339,10 +2382,6 @@ static int pfe_eth_init_one(struct pfe * - priv->PHY_baseaddr = cbus_emac_base[0]; - priv->GPI_baseaddr = cbus_gpi_base[id]; - --#define HIF_GEMAC_TMUQ_BASE 6 -- priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2); -- priv->high_tmu_q = priv->low_tmu_q + 1; -- - spin_lock_init(&priv->lock); - - pfe_eth_fast_tx_timeout_init(priv); diff --git a/target/linux/layerscape/patches-5.4/701-net-0306-staging-fsl_ppfe-eth-resolve-indentation-warning.patch b/target/linux/layerscape/patches-5.4/701-net-0306-staging-fsl_ppfe-eth-resolve-indentation-warning.patch deleted file mode 100644 index d61a448b0b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0306-staging-fsl_ppfe-eth-resolve-indentation-warning.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 1af2e375a76c55d227b7d1b1f1ba1c9cf850946a Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Thu, 4 Oct 2018 09:39:00 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: resolve indentation warning -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Resolve the following indentation warning: - -drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c: -In function ‘pfe_get_gemac_if_proprties’: -drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c:96:2: -warning: this ‘else’ clause does not guard... -[-Wmisleading-indentation] - else - ^~~~ -drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c:98:3: -note: ...this statement, but the latter is misleadingly indented as -if it were guarded by the ‘else’ - pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id; - ^~~~~ - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -@@ -83,11 +83,12 @@ static int pfe_get_gemac_if_proprties(st - } - - addr = of_get_property(gem, "fsl,mdio-mux-val", &size); -- if (!addr) -+ if (!addr) { - pr_err("%s: Invalid mdio-mux-val....\n", __func__); -- else -+ } else { - phy_id = be32_to_cpup(addr); - pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id; -+ } - - if (pdata->ls1012a_eth_pdata[port].phy_id < 32) - pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] = diff --git a/target/linux/layerscape/patches-5.4/701-net-0307-staging-fsl_ppfe-eth-add-fixed-link-support.patch b/target/linux/layerscape/patches-5.4/701-net-0307-staging-fsl_ppfe-eth-add-fixed-link-support.patch deleted file mode 100644 index 900a4513fe..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0307-staging-fsl_ppfe-eth-add-fixed-link-support.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 04373c37df836557ae7ebb769383baa1b57c5ffa Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Thu, 4 Oct 2018 09:38:17 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: add fixed-link support - -In cases where MAC is not connected to a normal MDIO-managed PHY -device, and instead to a switch, it is configured as a "fixed-link". -Code to handle this scenario is added here. - -phy_node in the dtb is checked to identify a fixed-link. -On identification of a fixed-link, it is registered and connected. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 21 ++++++++++++++++++++- - drivers/staging/fsl_ppfe/pfe_eth.h | 2 ++ - drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 4 ++++ - 3 files changed, 26 insertions(+), 1 deletion(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -39,6 +39,9 @@ - #include - #include - -+#include -+#include -+ - #include - #include - #include -@@ -1263,6 +1266,8 @@ static int pfe_phy_init(struct net_devic - char phy_id[MII_BUS_ID_SIZE + 3]; - char bus_id[MII_BUS_ID_SIZE]; - phy_interface_t interface; -+ struct device_node *phy_node; -+ int rc; - - priv->oldlink = 0; - priv->oldspeed = 0; -@@ -1293,7 +1298,20 @@ static int pfe_phy_init(struct net_devic - priv->oldspeed = 0; - priv->oldduplex = -1; - pr_info("%s interface %x\n", __func__, interface); -- phydev = phy_connect(ndev, phy_id, &pfe_eth_adjust_link, interface); -+ -+ if (of_phy_is_fixed_link(priv->phy_node)) { -+ rc = of_phy_register_fixed_link(priv->phy_node); -+ if (rc) -+ return rc; -+ phy_node = of_node_get(priv->phy_node); -+ phydev = of_phy_connect(ndev, phy_node, pfe_eth_adjust_link, 0, -+ priv->einfo->mii_config); -+ of_node_put(phy_node); -+ -+ } else { -+ phydev = phy_connect(ndev, phy_id, -+ &pfe_eth_adjust_link, interface); -+ } - - if (IS_ERR(phydev)) { - netdev_err(ndev, "phy_connect() failed\n"); -@@ -2371,6 +2389,7 @@ static int pfe_eth_init_one(struct pfe * - priv->ndev = ndev; - priv->id = einfo[id].gem_id; - priv->pfe = pfe; -+ priv->phy_node = einfo[id].phy_node; - - SET_NETDEV_DEV(priv->ndev, priv->pfe->dev); - ---- a/drivers/staging/fsl_ppfe/pfe_eth.h -+++ b/drivers/staging/fsl_ppfe/pfe_eth.h -@@ -61,6 +61,7 @@ struct ls1012a_eth_platform_data { - u32 phy_id; - u32 mdio_muxval; - u8 mac_addr[ETH_ALEN]; -+ struct device_node *phy_node; - }; - - struct ls1012a_mdio_platform_data { -@@ -144,6 +145,7 @@ struct pfe_eth_priv_s { - int oldspeed; - int oldduplex; - int oldlink; -+ struct device_node *phy_node; - /* mdio info */ - int mdc_div; - struct mii_bus *mii_bus; ---- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -@@ -18,8 +18,10 @@ - - #include - #include -+#include - #include - #include -+#include - #include - #include - #include -@@ -118,6 +120,8 @@ static int pfe_get_gemac_if_proprties(st - pdata->ls1012a_mdio_pdata[port].irq[0] = PHY_POLL; - - done: -+ if (of_phy_is_fixed_link(gem)) -+ pdata->ls1012a_eth_pdata[port].phy_node = of_node_get(gem); - - return 0; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0308-staging-fsl_ppfe-add-support-for-a-char-dev-for-link.patch b/target/linux/layerscape/patches-5.4/701-net-0308-staging-fsl_ppfe-add-support-for-a-char-dev-for-link.patch deleted file mode 100644 index c445952222..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0308-staging-fsl_ppfe-add-support-for-a-char-dev-for-link.patch +++ /dev/null @@ -1,364 +0,0 @@ -From a41d4af2ed4b02edca9d7f69955893d407274dc2 Mon Sep 17 00:00:00 2001 -From: Shreyansh Jain -Date: Wed, 6 Jun 2018 14:19:34 +0530 -Subject: [PATCH] staging: fsl_ppfe: add support for a char dev for link status - -Read and IOCTL support is added. Application would need to open, -read/ioctl the /dev/pfe_us_cdev device. -select is pending as it requires a wait_queue. - -Signed-off-by: Shreyansh Jain -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/Makefile | 3 +- - drivers/staging/fsl_ppfe/pfe_cdev.c | 207 ++++++++++++++++++++++++++++++++++++ - drivers/staging/fsl_ppfe/pfe_cdev.h | 52 +++++++++ - drivers/staging/fsl_ppfe/pfe_eth.c | 14 +++ - drivers/staging/fsl_ppfe/pfe_mod.c | 14 +++ - 5 files changed, 289 insertions(+), 1 deletion(-) - create mode 100644 drivers/staging/fsl_ppfe/pfe_cdev.c - create mode 100644 drivers/staging/fsl_ppfe/pfe_cdev.h - ---- a/drivers/staging/fsl_ppfe/Makefile -+++ b/drivers/staging/fsl_ppfe/Makefile -@@ -16,4 +16,5 @@ pfe-y += pfe_mod.o \ - pfe_sysfs.o \ - pfe_debugfs.o \ - pfe_ls1012a_platform.o \ -- pfe_hal.o -+ pfe_hal.o \ -+ pfe_cdev.o ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_cdev.c -@@ -0,0 +1,207 @@ -+/* -+ * Copyright 2018 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+/* @pfe_cdev.c. -+ * Dummy device representing the PFE US in userspace. -+ * - used for interacting with the kernel layer for link status -+ */ -+ -+#include "pfe_cdev.h" -+ -+static int pfe_majno; -+static struct class *pfe_char_class; -+static struct device *pfe_char_dev; -+ -+struct pfe_shared_info link_states[PFE_CDEV_ETH_COUNT]; -+ -+static int pfe_cdev_open(struct inode *inp, struct file *fp) -+{ -+ pr_debug("PFE CDEV device opened.\n"); -+ return 0; -+} -+ -+static ssize_t pfe_cdev_read(struct file *fp, char *buf, -+ size_t len, loff_t *off) -+{ -+ int ret = 0; -+ -+ pr_info("PFE CDEV attempt copying (%lu) size of user.\n", -+ sizeof(link_states)); -+ -+ pr_debug("Dump link_state on screen before copy_to_user\n"); -+ for (; ret < PFE_CDEV_ETH_COUNT; ret++) { -+ pr_debug("%u %u", link_states[ret].phy_id, -+ link_states[ret].state); -+ pr_debug("\n"); -+ } -+ -+ /* Copy to user the value in buffer sized len */ -+ ret = copy_to_user(buf, &link_states, sizeof(link_states)); -+ if (ret != 0) { -+ pr_err("Failed to send (%d)bytes of (%lu) requested.\n", -+ ret, len); -+ return -EFAULT; -+ } -+ -+ /* offset set back to 0 as there is contextual reading offset */ -+ *off = 0; -+ pr_debug("Read of (%lu) bytes performed.\n", sizeof(link_states)); -+ -+ return sizeof(link_states); -+} -+ -+/** -+ * This function is for getting some commands from user through non-IOCTL -+ * channel. It can used to configure the device. -+ * TODO: To be filled in future, if require duplex communication with user -+ * space. -+ */ -+static ssize_t pfe_cdev_write(struct file *fp, const char *buf, -+ size_t len, loff_t *off) -+{ -+ pr_info("PFE CDEV Write operation not supported!\n"); -+ -+ return -EFAULT; -+} -+ -+static int pfe_cdev_release(struct inode *inp, struct file *fp) -+{ -+ pr_info("PFE_CDEV: Device successfully closed\n"); -+ return 0; -+} -+ -+static long pfe_cdev_ioctl(struct file *fp, unsigned int cmd, -+ unsigned long arg) -+{ -+ int ret = -EFAULT; -+ int __user *argp = (int __user *)arg; -+ -+ pr_debug("PFE CDEV IOCTL Called with cmd=(%u)\n", cmd); -+ -+ switch (cmd) { -+ case PFE_CDEV_ETH0_STATE_GET: -+ /* Return an unsigned int (link state) for ETH0 */ -+ *argp = link_states[0].state; -+ pr_debug("Returning state=%d for ETH0\n", *argp); -+ ret = 0; -+ break; -+ case PFE_CDEV_ETH1_STATE_GET: -+ /* Return an unsigned int (link state) for ETH0 */ -+ *argp = link_states[1].state; -+ pr_debug("Returning state=%d for ETH1\n", *argp); -+ ret = 0; -+ break; -+ default: -+ pr_info("Unsupport cmd (%d) for PFE CDEV.\n", cmd); -+ break; -+ }; -+ -+ return ret; -+} -+ -+static unsigned int pfe_cdev_poll(struct file *fp, -+ struct poll_table_struct *wait) -+{ -+ pr_info("PFE CDEV poll method not supported\n"); -+ return 0; -+} -+ -+static const struct file_operations pfe_cdev_fops = { -+ .open = pfe_cdev_open, -+ .read = pfe_cdev_read, -+ .write = pfe_cdev_write, -+ .release = pfe_cdev_release, -+ .unlocked_ioctl = pfe_cdev_ioctl, -+ .poll = pfe_cdev_poll, -+}; -+ -+int pfe_cdev_init(void) -+{ -+ int ret; -+ -+ pr_debug("PFE CDEV initialization begin\n"); -+ -+ /* Register the major number for the device */ -+ pfe_majno = register_chrdev(0, PFE_CDEV_NAME, &pfe_cdev_fops); -+ if (pfe_majno < 0) { -+ pr_err("Unable to register PFE CDEV. PFE CDEV not available\n"); -+ ret = pfe_majno; -+ goto cleanup; -+ } -+ -+ pr_debug("PFE CDEV assigned major number: %d\n", pfe_majno); -+ -+ /* Register the class for the device */ -+ pfe_char_class = class_create(THIS_MODULE, PFE_CLASS_NAME); -+ if (IS_ERR(pfe_char_class)) { -+ pr_err( -+ "Failed to init class for PFE CDEV. PFE CDEV not available.\n"); -+ goto cleanup; -+ } -+ -+ pr_debug("PFE CDEV Class created successfully.\n"); -+ -+ /* Create the device without any parent and without any callback data */ -+ pfe_char_dev = device_create(pfe_char_class, NULL, -+ MKDEV(pfe_majno, 0), NULL, -+ PFE_CDEV_NAME); -+ if (IS_ERR(pfe_char_dev)) { -+ pr_err("Unable to PFE CDEV device. PFE CDEV not available.\n"); -+ ret = PTR_ERR(pfe_char_dev); -+ goto cleanup; -+ } -+ -+ /* Information structure being shared with the userspace */ -+ memset(link_states, 0, sizeof(struct pfe_shared_info) * -+ PFE_CDEV_ETH_COUNT); -+ -+ pr_info("PFE CDEV created: %s\n", PFE_CDEV_NAME); -+ -+ ret = 0; -+ return ret; -+ -+cleanup: -+ if (!IS_ERR(pfe_char_class)) -+ class_destroy(pfe_char_class); -+ -+ if (pfe_majno > 0) -+ unregister_chrdev(pfe_majno, PFE_CDEV_NAME); -+ -+ ret = -EFAULT; -+ return ret; -+} -+ -+void pfe_cdev_exit(void) -+{ -+ if (!IS_ERR(pfe_char_dev)) -+ device_destroy(pfe_char_class, MKDEV(pfe_majno, 0)); -+ -+ if (!IS_ERR(pfe_char_class)) { -+ class_unregister(pfe_char_class); -+ class_destroy(pfe_char_class); -+ } -+ -+ if (pfe_majno > 0) -+ unregister_chrdev(pfe_majno, PFE_CDEV_NAME); -+ -+ /* reset the variables */ -+ pfe_majno = 0; -+ pfe_char_class = NULL; -+ pfe_char_dev = NULL; -+ -+ pr_info("PFE CDEV Removed.\n"); -+} ---- /dev/null -+++ b/drivers/staging/fsl_ppfe/pfe_cdev.h -@@ -0,0 +1,52 @@ -+/* -+ * Copyright 2018 NXP -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _PFE_CDEV_H_ -+#define _PFE_CDEV_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define PFE_CDEV_NAME "pfe_us_cdev" -+#define PFE_CLASS_NAME "ppfe_us" -+ -+/* Extracted from ls1012a_pfe_platform_data, there are 3 interfaces which are -+ * supported by PFE driver. Should be updated if number of eth devices are -+ * changed. -+ */ -+#define PFE_CDEV_ETH_COUNT 3 -+ -+struct pfe_shared_info { -+ uint32_t phy_id; /* Link phy ID */ -+ uint8_t state; /* Has either 0 or 1 */ -+}; -+ -+extern struct pfe_shared_info link_states[PFE_CDEV_ETH_COUNT]; -+ -+/* IOCTL Commands */ -+#define PFE_CDEV_ETH0_STATE_GET 0 -+#define PFE_CDEV_ETH1_STATE_GET 1 -+ -+int pfe_cdev_init(void); -+void pfe_cdev_exit(void); -+ -+#endif /* _PFE_CDEV_H_ */ ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -55,6 +55,7 @@ - - #include "pfe_mod.h" - #include "pfe_eth.h" -+#include "pfe_cdev.h" - - #define LS1012A_REV_1_0 0x87040010 - -@@ -1160,6 +1161,19 @@ static void pfe_eth_adjust_link(struct n - phy_print_status(phydev); - - spin_unlock_irqrestore(&priv->lock, flags); -+ -+ /* Now, dump the details to the cdev. -+ * XXX: Locking would be required? (uniprocess arch) -+ * Or, maybe move it in spinlock above -+ */ -+ if (us && priv->einfo->gem_id < PFE_CDEV_ETH_COUNT) { -+ pr_debug("Changing link state from (%u) to (%u) for ID=(%u)\n", -+ link_states[priv->einfo->gem_id].state, -+ phydev->link, -+ priv->einfo->gem_id); -+ link_states[priv->einfo->gem_id].phy_id = priv->einfo->gem_id; -+ link_states[priv->einfo->gem_id].state = phydev->link; -+ } - } - - /* pfe_phy_exit ---- a/drivers/staging/fsl_ppfe/pfe_mod.c -+++ b/drivers/staging/fsl_ppfe/pfe_mod.c -@@ -18,6 +18,7 @@ - - #include - #include "pfe_mod.h" -+#include "pfe_cdev.h" - - unsigned int us; - module_param(us, uint, 0444); -@@ -92,8 +93,18 @@ firmware_init: - if (rc < 0) - goto err_debugfs; - -+ if (us) { -+ /* Creating a character device */ -+ rc = pfe_cdev_init(); -+ if (rc < 0) -+ goto err_cdev; -+ } -+ - return 0; - -+err_cdev: -+ pfe_debugfs_exit(pfe); -+ - err_debugfs: - pfe_sysfs_exit(pfe); - -@@ -129,6 +140,9 @@ int pfe_remove(struct pfe *pfe) - { - pr_info("%s\n", __func__); - -+ if (us) -+ pfe_cdev_exit(); -+ - pfe_debugfs_exit(pfe); - - pfe_sysfs_exit(pfe); diff --git a/target/linux/layerscape/patches-5.4/701-net-0309-staging-fsl_ppfe-enable-hif-event-from-userspace.patch b/target/linux/layerscape/patches-5.4/701-net-0309-staging-fsl_ppfe-enable-hif-event-from-userspace.patch deleted file mode 100644 index 785f316028..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0309-staging-fsl_ppfe-enable-hif-event-from-userspace.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 0c072b46ecc8689be160bfdc750e95ad9879d706 Mon Sep 17 00:00:00 2001 -From: Akhil Goyal -Date: Thu, 5 Jul 2018 20:14:21 +0530 -Subject: [PATCH] staging: fsl_ppfe: enable hif event from userspace - -HIF interrupts are enabled using ioctl from user space, -and epoll wait from user space wakes up when there is an HIF -interrupt. - -Signed-off-by: Akhil Goyal ---- - drivers/staging/fsl_ppfe/pfe_cdev.c | 57 +++++++++++++++++++++++++++++++++++++ - drivers/staging/fsl_ppfe/pfe_cdev.h | 5 ++-- - 2 files changed, 60 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_cdev.c -+++ b/drivers/staging/fsl_ppfe/pfe_cdev.c -@@ -20,11 +20,18 @@ - * - used for interacting with the kernel layer for link status - */ - -+#include -+#include -+#include -+#include -+ - #include "pfe_cdev.h" -+#include "pfe_mod.h" - - static int pfe_majno; - static struct class *pfe_char_class; - static struct device *pfe_char_dev; -+struct eventfd_ctx *g_trigger; - - struct pfe_shared_info link_states[PFE_CDEV_ETH_COUNT]; - -@@ -80,10 +87,44 @@ static ssize_t pfe_cdev_write(struct fil - - static int pfe_cdev_release(struct inode *inp, struct file *fp) - { -+ if (g_trigger) { -+ free_irq(pfe->hif_irq, g_trigger); -+ eventfd_ctx_put(g_trigger); -+ g_trigger = NULL; -+ } -+ - pr_info("PFE_CDEV: Device successfully closed\n"); - return 0; - } - -+/* -+ * hif_us_isr- -+ * This ISR routine processes Rx/Tx done interrupts from the HIF hardware block -+ */ -+static irqreturn_t hif_us_isr(int irq, void *arg) -+{ -+ struct eventfd_ctx *trigger = (struct eventfd_ctx *)arg; -+ int int_status; -+ int int_enable_mask; -+ -+ /*Read hif interrupt source register */ -+ int_status = readl_relaxed(HIF_INT_SRC); -+ int_enable_mask = readl_relaxed(HIF_INT_ENABLE); -+ -+ if ((int_status & HIF_INT) == 0) -+ return IRQ_NONE; -+ -+ if (int_status & HIF_RXPKT_INT) { -+ int_enable_mask &= ~(HIF_RXPKT_INT); -+ eventfd_signal(trigger, 1); -+ } -+ -+ /*Disable interrupts, they will be enabled after they are serviced */ -+ writel_relaxed(int_enable_mask, HIF_INT_ENABLE); -+ -+ return IRQ_HANDLED; -+} -+ - static long pfe_cdev_ioctl(struct file *fp, unsigned int cmd, - unsigned long arg) - { -@@ -105,6 +146,22 @@ static long pfe_cdev_ioctl(struct file * - pr_debug("Returning state=%d for ETH1\n", *argp); - ret = 0; - break; -+ case PFE_CDEV_HIF_INTR_EN: -+ /* Return success/failure */ -+ g_trigger = eventfd_ctx_fdget(*argp); -+ if (IS_ERR(g_trigger)) -+ return PTR_ERR(g_trigger); -+ ret = request_irq(pfe->hif_irq, hif_us_isr, 0, "pfe_hif", -+ g_trigger); -+ if (ret) { -+ pr_err("%s: failed to get the hif IRQ = %d\n", -+ __func__, pfe->hif_irq); -+ eventfd_ctx_put(g_trigger); -+ g_trigger = NULL; -+ } -+ pr_debug("request_irq for hif interrupt: %d\n", pfe->hif_irq); -+ ret = 0; -+ break; - default: - pr_info("Unsupport cmd (%d) for PFE CDEV.\n", cmd); - break; ---- a/drivers/staging/fsl_ppfe/pfe_cdev.h -+++ b/drivers/staging/fsl_ppfe/pfe_cdev.h -@@ -43,8 +43,9 @@ struct pfe_shared_info { - extern struct pfe_shared_info link_states[PFE_CDEV_ETH_COUNT]; - - /* IOCTL Commands */ --#define PFE_CDEV_ETH0_STATE_GET 0 --#define PFE_CDEV_ETH1_STATE_GET 1 -+#define PFE_CDEV_ETH0_STATE_GET _IOR('R', 0, int) -+#define PFE_CDEV_ETH1_STATE_GET _IOR('R', 1, int) -+#define PFE_CDEV_HIF_INTR_EN _IOWR('R', 2, int) - - int pfe_cdev_init(void); - void pfe_cdev_exit(void); diff --git a/target/linux/layerscape/patches-5.4/701-net-0310-staging-fsl_ppfe-performance-tuning-for-user-space.patch b/target/linux/layerscape/patches-5.4/701-net-0310-staging-fsl_ppfe-performance-tuning-for-user-space.patch deleted file mode 100644 index 8eac290b3a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0310-staging-fsl_ppfe-performance-tuning-for-user-space.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 31fa4aeafa41a38c76085af4de7192c572e85119 Mon Sep 17 00:00:00 2001 -From: Akhil Goyal -Date: Fri, 20 Jul 2018 16:43:25 +0530 -Subject: [PATCH] staging: fsl_ppfe: performance tuning for user space - -interrupt coalescing of 100 usec is added. - -Signed-off-by: Akhil Goyal -Signed-off-by: Sachin Saxena ---- - drivers/staging/fsl_ppfe/pfe_cdev.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_cdev.c -+++ b/drivers/staging/fsl_ppfe/pfe_cdev.c -@@ -116,15 +116,18 @@ static irqreturn_t hif_us_isr(int irq, v - - if (int_status & HIF_RXPKT_INT) { - int_enable_mask &= ~(HIF_RXPKT_INT); -+ /* Disable interrupts, they will be enabled after -+ * they are serviced -+ */ -+ writel_relaxed(int_enable_mask, HIF_INT_ENABLE); -+ - eventfd_signal(trigger, 1); - } - -- /*Disable interrupts, they will be enabled after they are serviced */ -- writel_relaxed(int_enable_mask, HIF_INT_ENABLE); -- - return IRQ_HANDLED; - } - -+#define PFE_INTR_COAL_USECS 100 - static long pfe_cdev_ioctl(struct file *fp, unsigned int cmd, - unsigned long arg) - { -@@ -159,6 +162,9 @@ static long pfe_cdev_ioctl(struct file * - eventfd_ctx_put(g_trigger); - g_trigger = NULL; - } -+ writel((PFE_INTR_COAL_USECS * (pfe->ctrl.sys_clk / 1000)) | -+ HIF_INT_COAL_ENABLE, HIF_INT_COAL); -+ - pr_debug("request_irq for hif interrupt: %d\n", pfe->hif_irq); - ret = 0; - break; diff --git a/target/linux/layerscape/patches-5.4/701-net-0311-staging-fsl_ppfe-eth-Update-to-use-SPDX-identifiers.patch b/target/linux/layerscape/patches-5.4/701-net-0311-staging-fsl_ppfe-eth-Update-to-use-SPDX-identifiers.patch deleted file mode 100644 index 139682d4ae..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0311-staging-fsl_ppfe-eth-Update-to-use-SPDX-identifiers.patch +++ /dev/null @@ -1,563 +0,0 @@ -From 9690960751950583eb80ad9d623c45e974359829 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Tue, 20 Nov 2018 21:50:23 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: Update to use SPDX identifiers - -Replace license text with corresponding SPDX identifiers and update the -format of existing SPDX identifiers to follow the new guideline -Documentation/process/license-rules.rst. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_cdev.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_cdev.h | 14 +------------- - drivers/staging/fsl_ppfe/pfe_ctrl.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_ctrl.h | 14 +------------- - drivers/staging/fsl_ppfe/pfe_debugfs.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_debugfs.h | 14 +------------- - drivers/staging/fsl_ppfe/pfe_eth.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_eth.h | 14 +------------- - drivers/staging/fsl_ppfe/pfe_firmware.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_firmware.h | 14 +------------- - drivers/staging/fsl_ppfe/pfe_hal.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_hif.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_hif.h | 14 +------------- - drivers/staging/fsl_ppfe/pfe_hif_lib.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_hif_lib.h | 14 +------------- - drivers/staging/fsl_ppfe/pfe_hw.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_hw.h | 14 +------------- - drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_mod.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_mod.h | 14 +------------- - drivers/staging/fsl_ppfe/pfe_perfmon.h | 14 +------------- - drivers/staging/fsl_ppfe/pfe_sysfs.c | 14 +------------- - drivers/staging/fsl_ppfe/pfe_sysfs.h | 14 +------------- - 23 files changed, 23 insertions(+), 299 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_cdev.c -+++ b/drivers/staging/fsl_ppfe/pfe_cdev.c -@@ -1,18 +1,6 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2018 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - /* @pfe_cdev.c. ---- a/drivers/staging/fsl_ppfe/pfe_cdev.h -+++ b/drivers/staging/fsl_ppfe/pfe_cdev.h -@@ -1,18 +1,6 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ - /* - * Copyright 2018 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #ifndef _PFE_CDEV_H_ ---- a/drivers/staging/fsl_ppfe/pfe_ctrl.c -+++ b/drivers/staging/fsl_ppfe/pfe_ctrl.c -@@ -1,19 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #include ---- a/drivers/staging/fsl_ppfe/pfe_ctrl.h -+++ b/drivers/staging/fsl_ppfe/pfe_ctrl.h -@@ -1,19 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #ifndef _PFE_CTRL_H_ ---- a/drivers/staging/fsl_ppfe/pfe_debugfs.c -+++ b/drivers/staging/fsl_ppfe/pfe_debugfs.c -@@ -1,19 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #include ---- a/drivers/staging/fsl_ppfe/pfe_debugfs.h -+++ b/drivers/staging/fsl_ppfe/pfe_debugfs.h -@@ -1,19 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #ifndef _PFE_DEBUGFS_H_ ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -1,19 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - /* @pfe_eth.c. ---- a/drivers/staging/fsl_ppfe/pfe_eth.h -+++ b/drivers/staging/fsl_ppfe/pfe_eth.h -@@ -1,19 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #ifndef _PFE_ETH_H_ ---- a/drivers/staging/fsl_ppfe/pfe_firmware.c -+++ b/drivers/staging/fsl_ppfe/pfe_firmware.c -@@ -1,19 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - /* ---- a/drivers/staging/fsl_ppfe/pfe_firmware.h -+++ b/drivers/staging/fsl_ppfe/pfe_firmware.h -@@ -1,19 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #ifndef _PFE_FIRMWARE_H_ ---- a/drivers/staging/fsl_ppfe/pfe_hal.c -+++ b/drivers/staging/fsl_ppfe/pfe_hal.c -@@ -1,19 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #include "pfe_mod.h" ---- a/drivers/staging/fsl_ppfe/pfe_hif.c -+++ b/drivers/staging/fsl_ppfe/pfe_hif.c -@@ -1,19 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #include ---- a/drivers/staging/fsl_ppfe/pfe_hif.h -+++ b/drivers/staging/fsl_ppfe/pfe_hif.h -@@ -1,19 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #ifndef _PFE_HIF_H_ ---- a/drivers/staging/fsl_ppfe/pfe_hif_lib.c -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.c -@@ -1,19 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #include ---- a/drivers/staging/fsl_ppfe/pfe_hif_lib.h -+++ b/drivers/staging/fsl_ppfe/pfe_hif_lib.h -@@ -1,19 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #ifndef _PFE_HIF_LIB_H_ ---- a/drivers/staging/fsl_ppfe/pfe_hw.c -+++ b/drivers/staging/fsl_ppfe/pfe_hw.c -@@ -1,19 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #include "pfe_mod.h" ---- a/drivers/staging/fsl_ppfe/pfe_hw.h -+++ b/drivers/staging/fsl_ppfe/pfe_hw.h -@@ -1,19 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #ifndef _PFE_HW_H_ ---- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -@@ -1,19 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #include ---- a/drivers/staging/fsl_ppfe/pfe_mod.c -+++ b/drivers/staging/fsl_ppfe/pfe_mod.c -@@ -1,19 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #include ---- a/drivers/staging/fsl_ppfe/pfe_mod.h -+++ b/drivers/staging/fsl_ppfe/pfe_mod.h -@@ -1,19 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #ifndef _PFE_MOD_H_ ---- a/drivers/staging/fsl_ppfe/pfe_perfmon.h -+++ b/drivers/staging/fsl_ppfe/pfe_perfmon.h -@@ -1,19 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #ifndef _PFE_PERFMON_H_ ---- a/drivers/staging/fsl_ppfe/pfe_sysfs.c -+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.c -@@ -1,19 +1,7 @@ -+// SPDX-License-Identifier: GPL-2.0+ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #include ---- a/drivers/staging/fsl_ppfe/pfe_sysfs.h -+++ b/drivers/staging/fsl_ppfe/pfe_sysfs.h -@@ -1,19 +1,7 @@ -+/* SPDX-License-Identifier: GPL-2.0+ */ - /* - * Copyright 2015-2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program. If not, see . - */ - - #ifndef _PFE_SYSFS_H_ diff --git a/target/linux/layerscape/patches-5.4/701-net-0312-staging-fsl_ppfe-eth-misc-clean-up.patch b/target/linux/layerscape/patches-5.4/701-net-0312-staging-fsl_ppfe-eth-misc-clean-up.patch deleted file mode 100644 index 6f1f7c5d84..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0312-staging-fsl_ppfe-eth-misc-clean-up.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 508121cfde12d0e35716bb7e524dc1f80c82262c Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Tue, 20 Nov 2018 21:50:40 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: misc clean up - -- remove redundant hwfeature init -- remove unused vars from ls1012a_eth_platform_data -- To handle ls1012a errata_a010897, PPFE driver requires GUTS driver -to be compiled in. Select FSL_GUTS when PPFE driver is compiled. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/Kconfig | 1 + - drivers/staging/fsl_ppfe/pfe_eth.c | 3 --- - drivers/staging/fsl_ppfe/pfe_eth.h | 4 ---- - 3 files changed, 1 insertion(+), 7 deletions(-) - ---- a/drivers/staging/fsl_ppfe/Kconfig -+++ b/drivers/staging/fsl_ppfe/Kconfig -@@ -3,6 +3,7 @@ - # - config FSL_PPFE - bool "Freescale PPFE Driver" -+ select FSL_GUTS - default n - ---help--- - Freescale LS1012A SoC has a Programmable Packet Forwarding Engine. ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -2437,9 +2437,6 @@ static int pfe_eth_init_one(struct pfe * - else - ndev->max_mtu = JUMBO_FRAME_SIZE_V2 - ETH_HLEN - ETH_FCS_LEN; - -- /* supported features */ -- ndev->hw_features = NETIF_F_SG; -- - /*Enable after checksum offload is validated */ - ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | NETIF_F_SG; ---- a/drivers/staging/fsl_ppfe/pfe_eth.h -+++ b/drivers/staging/fsl_ppfe/pfe_eth.h -@@ -37,10 +37,6 @@ - #define GEMAC_NO_PHY BIT(0) - - struct ls1012a_eth_platform_data { -- /* device specific information */ -- u32 device_flags; -- char name[16]; -- - /* board specific information */ - u32 mii_config; - u32 phy_flags; diff --git a/target/linux/layerscape/patches-5.4/701-net-0313-staging-fsl_ppfe-eth-reorganize-platform-phy-paramet.patch b/target/linux/layerscape/patches-5.4/701-net-0313-staging-fsl_ppfe-eth-reorganize-platform-phy-paramet.patch deleted file mode 100644 index 8a16edf285..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0313-staging-fsl_ppfe-eth-reorganize-platform-phy-paramet.patch +++ /dev/null @@ -1,156 +0,0 @@ -From bb13c3cfaaac3bb50a7f59d0cfa54ff463c2ca86 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Tue, 20 Nov 2018 21:50:51 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: reorganize platform phy parameters - -- Use "phy-handle" and of_* functions to get phy node and fixed-link -parameters - -- Reorganize phy parameters and initialize them only if phy-handle -or fixed-link is defined in the dtb. - -- correct typo pfe_get_gemac_if_proprties to pfe_get_gemac_if_properties - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 91 ++++++++++++++----------- - 1 file changed, 50 insertions(+), 41 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -@@ -20,12 +20,12 @@ - - struct ls1012a_pfe_platform_data pfe_platform_data; - --static int pfe_get_gemac_if_proprties(struct device_node *parent, int port, int -+static int pfe_get_gemac_if_properties(struct device_node *parent, int port, int - if_cnt, - struct ls1012a_pfe_platform_data - *pdata) - { -- struct device_node *gem = NULL, *phy = NULL; -+ struct device_node *gem = NULL, *phy = NULL, *phy_node = NULL; - int size; - int ii = 0, phy_id = 0; - const u32 *addr; -@@ -49,12 +49,6 @@ static int pfe_get_gemac_if_proprties(st - - of_get_mac_address(gem, pdata->ls1012a_eth_pdata[port].mac_addr); - -- pdata->ls1012a_eth_pdata[port].mii_config = of_get_phy_mode(gem); -- -- if ((pdata->ls1012a_eth_pdata[port].mii_config) < 0) -- pr_err("%s:%d Incorrect Phy mode....\n", __func__, -- __LINE__); -- - addr = of_get_property(gem, "fsl,gemac-bus-id", &size); - if (!addr) - pr_err("%s:%d Invalid gemac-bus-id....\n", __func__, -@@ -62,16 +56,55 @@ static int pfe_get_gemac_if_proprties(st - else - pdata->ls1012a_eth_pdata[port].bus_id = be32_to_cpup(addr); - -- addr = of_get_property(gem, "fsl,gemac-phy-id", &size); -- if (!addr) { -- pr_err("%s:%d Invalid gemac-phy-id....\n", __func__, -- __LINE__); -+ phy_node = of_parse_phandle(gem, "phy-handle", 0); -+ pdata->ls1012a_eth_pdata[port].phy_node = phy_node; -+ if (phy_node) { -+ goto process_phynode; -+ } else if (of_phy_is_fixed_link(gem)) { -+ if (of_phy_register_fixed_link(gem) < 0) { -+ pr_err("broken fixed-link specification\n"); -+ goto err; -+ } -+ phy_node = of_node_get(gem); -+ pdata->ls1012a_eth_pdata[port].phy_node = phy_node; -+ } else if (of_get_property(gem, "fsl,pfe-phy-if-flags", &size)) { -+ /* Use old dts properties for phy handling */ -+ addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size); -+ pdata->ls1012a_eth_pdata[port].phy_flags = be32_to_cpup(addr); -+ -+ addr = of_get_property(gem, "fsl,gemac-phy-id", &size); -+ if (!addr) { -+ pr_err("%s:%d Invalid gemac-phy-id....\n", __func__, -+ __LINE__); -+ } else { -+ phy_id = be32_to_cpup(addr); -+ pdata->ls1012a_eth_pdata[port].phy_id = phy_id; -+ pdata->ls1012a_mdio_pdata[0].phy_mask &= ~(1 << phy_id); -+ } -+ -+ /* If PHY is enabled, read mdio properties */ -+ if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY) -+ goto done; -+ -+ phy = of_get_next_child(gem, NULL); -+ addr = of_get_property(phy, "reg", &size); -+ if (!addr) -+ pr_err("%s:%d Invalid phy enable flag....\n", -+ __func__, __LINE__); -+ else -+ pdata->ls1012a_mdio_pdata[port].enabled = -+ be32_to_cpup(addr); - } else { -- phy_id = be32_to_cpup(addr); -- pdata->ls1012a_eth_pdata[port].phy_id = phy_id; -- pdata->ls1012a_mdio_pdata[0].phy_mask &= ~(1 << phy_id); -+ pr_info("%s: No PHY or fixed-link\n", __func__); -+ return 0; - } - -+process_phynode: -+ pdata->ls1012a_eth_pdata[port].mii_config = of_get_phy_mode(gem); -+ if ((pdata->ls1012a_eth_pdata[port].mii_config) < 0) -+ pr_err("%s:%d Incorrect Phy mode....\n", __func__, -+ __LINE__); -+ - addr = of_get_property(gem, "fsl,mdio-mux-val", &size); - if (!addr) { - pr_err("%s: Invalid mdio-mux-val....\n", __func__); -@@ -84,33 +117,10 @@ static int pfe_get_gemac_if_proprties(st - pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] = - pdata->ls1012a_eth_pdata[port].mdio_muxval; - -- addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size); -- if (!addr) -- pr_err("%s:%d Invalid pfe-phy-if-flags....\n", -- __func__, __LINE__); -- else -- pdata->ls1012a_eth_pdata[port].phy_flags = be32_to_cpup(addr); -- -- /* If PHY is enabled, read mdio properties */ -- if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY) -- goto done; -- -- phy = of_get_next_child(gem, NULL); -- -- addr = of_get_property(phy, "reg", &size); -- -- if (!addr) -- pr_err("%s:%d Invalid phy enable flag....\n", -- __func__, __LINE__); -- else -- pdata->ls1012a_mdio_pdata[port].enabled = be32_to_cpup(addr); - - pdata->ls1012a_mdio_pdata[port].irq[0] = PHY_POLL; - - done: -- if (of_phy_is_fixed_link(gem)) -- pdata->ls1012a_eth_pdata[port].phy_node = of_node_get(gem); -- - return 0; - - err: -@@ -212,8 +222,8 @@ static int pfe_platform_probe(struct pla - pfe_platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; - - for (ii = 0; ii < interface_count; ii++) { -- pfe_get_gemac_if_proprties(np, ii, interface_count, -- &pfe_platform_data); -+ pfe_get_gemac_if_properties(np, ii, interface_count, -+ &pfe_platform_data); - } - - pfe->dev = &pdev->dev; diff --git a/target/linux/layerscape/patches-5.4/701-net-0314-staging-fsl_ppfe-eth-support-single-interface-initia.patch b/target/linux/layerscape/patches-5.4/701-net-0314-staging-fsl_ppfe-eth-support-single-interface-initia.patch deleted file mode 100644 index fefe863647..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0314-staging-fsl_ppfe-eth-support-single-interface-initia.patch +++ /dev/null @@ -1,271 +0,0 @@ -From dff5fdd84a9ace2d9b8b56659c0855542829148a Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Fri, 23 Nov 2018 23:58:28 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: support single interface - initialization - -- arrange members of struct mii_bus in sequence matching phy.h -- if mdio node is defined, use of_mdiobus_register to register - child nodes (phy devices) available on the mdio bus. -- remove of_phy_register_fixed_link from pfe_phy_init as it is being - handled in pfe_get_gemac_if_properties -- remove mdio enabled check -- skip phy init, if no PHY or fixed-link - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 110 +++++++++++++----------- - drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 4 + - 2 files changed, 66 insertions(+), 48 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -47,6 +47,7 @@ - - #define LS1012A_REV_1_0 0x87040010 - -+bool pfe_use_old_dts_phy; - bool pfe_errata_a010897; - - static void *cbus_emac_base[3]; -@@ -950,7 +951,8 @@ static int pfe_eth_mdio_init(struct pfe_ - struct ls1012a_mdio_platform_data *minfo) - { - struct mii_bus *bus; -- int rc, ii; -+ struct device_node *mdio_node; -+ int rc = 0, ii; - struct phy_device *phydev; - - netif_info(priv, drv, priv->ndev, "%s\n", __func__); -@@ -964,25 +966,30 @@ static int pfe_eth_mdio_init(struct pfe_ - } - - bus->name = "ls1012a MDIO Bus"; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id); -+ -+ bus->priv = priv; - bus->read = &pfe_eth_mdio_read; - bus->write = &pfe_eth_mdio_write; - bus->reset = &pfe_eth_mdio_reset; -- snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id); -- bus->priv = priv; -- -+ bus->parent = priv->pfe->dev; - bus->phy_mask = minfo->phy_mask; -- priv->mdc_div = minfo->mdc_div; -+ bus->irq[0] = minfo->irq[0]; - -+ priv->mdc_div = minfo->mdc_div; - if (!priv->mdc_div) - priv->mdc_div = 64; -- -- bus->irq[0] = minfo->irq[0]; -- -- bus->parent = priv->pfe->dev; -- - netif_info(priv, drv, priv->ndev, "%s: mdc_div: %d, phy_mask: %x\n", - __func__, priv->mdc_div, bus->phy_mask); -- rc = mdiobus_register(bus); -+ -+ mdio_node = of_get_child_by_name(priv->pfe->dev->of_node, "mdio"); -+ if (mdio_node) { -+ rc = of_mdiobus_register(bus, mdio_node); -+ of_node_put(mdio_node); -+ } else { -+ rc = mdiobus_register(bus); -+ } -+ - if (rc) { - netdev_err(priv->ndev, "mdiobus_register(%s) failed\n", - bus->name); -@@ -995,7 +1002,6 @@ static int pfe_eth_mdio_init(struct pfe_ - * 3rd argument as true and then register the phy device - * via phy_device_register() - */ -- - if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) { - for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) { - phydev = get_phy_device(priv->mii_bus, -@@ -1268,8 +1274,6 @@ static int pfe_phy_init(struct net_devic - char phy_id[MII_BUS_ID_SIZE + 3]; - char bus_id[MII_BUS_ID_SIZE]; - phy_interface_t interface; -- struct device_node *phy_node; -- int rc; - - priv->oldlink = 0; - priv->oldspeed = 0; -@@ -1278,7 +1282,6 @@ static int pfe_phy_init(struct net_devic - snprintf(bus_id, MII_BUS_ID_SIZE, "ls1012a-%d", 0); - snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, - priv->einfo->phy_id); -- - netif_info(priv, drv, ndev, "%s: %s\n", __func__, phy_id); - interface = priv->einfo->mii_config; - if ((interface == PHY_INTERFACE_MODE_SGMII) || -@@ -1301,23 +1304,22 @@ static int pfe_phy_init(struct net_devic - priv->oldduplex = -1; - pr_info("%s interface %x\n", __func__, interface); - -- if (of_phy_is_fixed_link(priv->phy_node)) { -- rc = of_phy_register_fixed_link(priv->phy_node); -- if (rc) -- return rc; -- phy_node = of_node_get(priv->phy_node); -- phydev = of_phy_connect(ndev, phy_node, pfe_eth_adjust_link, 0, -+ if (priv->phy_node) { -+ phydev = of_phy_connect(ndev, priv->phy_node, -+ pfe_eth_adjust_link, 0, - priv->einfo->mii_config); -- of_node_put(phy_node); -+ if (!(phydev)) { -+ netdev_err(ndev, "Unable to connect to phy\n"); -+ return -ENODEV; -+ } - - } else { - phydev = phy_connect(ndev, phy_id, - &pfe_eth_adjust_link, interface); -- } -- -- if (IS_ERR(phydev)) { -- netdev_err(ndev, "phy_connect() failed\n"); -- return PTR_ERR(phydev); -+ if (IS_ERR(phydev)) { -+ netdev_err(ndev, "Unable to connect to phy\n"); -+ return PTR_ERR(phydev); -+ } - } - - priv->phydev = phydev; -@@ -2411,13 +2413,10 @@ static int pfe_eth_init_one(struct pfe * - memcpy(ndev->dev_addr, einfo[id].mac_addr, ETH_ALEN); - - /* Initialize mdio */ -- if (minfo[id].enabled) { -- err = pfe_eth_mdio_init(priv, &minfo[id]); -- if (err) { -- netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n", -- __func__); -- goto err2; -- } -+ err = pfe_eth_mdio_init(priv, &minfo[id]); -+ if (err) { -+ netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n", __func__); -+ goto err1; - } - - if (us) -@@ -2462,22 +2461,26 @@ static int pfe_eth_init_one(struct pfe * - HIF_RX_POLL_WEIGHT - 16); - - err = register_netdev(ndev); -- - if (err) { - netdev_err(ndev, "register_netdev() failed\n"); -- goto err3; -+ goto err2; -+ } -+ -+ if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) || -+ ((pfe_use_old_dts_phy) && -+ (priv->einfo->phy_flags & GEMAC_NO_PHY))) { -+ pr_info("%s: No PHY or fixed-link\n", __func__); -+ goto skip_phy_init; - } - - phy_init: - device_init_wakeup(&ndev->dev, WAKE_MAGIC); - -- if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) { -- err = pfe_phy_init(ndev); -- if (err) { -- netdev_err(ndev, "%s: pfe_phy_init() failed\n", -- __func__); -- goto err4; -- } -+ err = pfe_phy_init(ndev); -+ if (err) { -+ netdev_err(ndev, "%s: pfe_phy_init() failed\n", -+ __func__); -+ goto err3; - } - - if (us) { -@@ -2488,6 +2491,7 @@ phy_init: - - netif_carrier_on(ndev); - -+skip_phy_init: - /* Create all the sysfs files */ - if (pfe_eth_sysfs_init(ndev)) - goto err4; -@@ -2496,13 +2500,16 @@ phy_init: - __func__, priv->EMAC_baseaddr); - - return 0; -+ - err4: -+ pfe_phy_exit(priv->ndev); -+err3: - if (us) -- goto err3; -+ goto err2; - unregister_netdev(ndev); --err3: -- pfe_eth_mdio_exit(priv->mii_bus); - err2: -+ pfe_eth_mdio_exit(priv->mii_bus); -+err1: - free_netdev(priv->ndev); - err0: - return err; -@@ -2553,9 +2560,16 @@ static void pfe_eth_exit_one(struct pfe_ - if (!us) - pfe_eth_sysfs_exit(priv->ndev); - -- if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) -- pfe_phy_exit(priv->ndev); -+ if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) || -+ ((pfe_use_old_dts_phy) && -+ (priv->einfo->phy_flags & GEMAC_NO_PHY))) { -+ pr_info("%s: No PHY or fixed-link\n", __func__); -+ goto skip_phy_exit; -+ } -+ -+ pfe_phy_exit(priv->ndev); - -+skip_phy_exit: - if (!us) - unregister_netdev(priv->ndev); - ---- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -@@ -18,6 +18,7 @@ - - #include "pfe_mod.h" - -+extern bool pfe_use_old_dts_phy; - struct ls1012a_pfe_platform_data pfe_platform_data; - - static int pfe_get_gemac_if_properties(struct device_node *parent, int port, int -@@ -59,8 +60,10 @@ static int pfe_get_gemac_if_properties(s - phy_node = of_parse_phandle(gem, "phy-handle", 0); - pdata->ls1012a_eth_pdata[port].phy_node = phy_node; - if (phy_node) { -+ pfe_use_old_dts_phy = false; - goto process_phynode; - } else if (of_phy_is_fixed_link(gem)) { -+ pfe_use_old_dts_phy = false; - if (of_phy_register_fixed_link(gem) < 0) { - pr_err("broken fixed-link specification\n"); - goto err; -@@ -68,6 +71,7 @@ static int pfe_get_gemac_if_properties(s - phy_node = of_node_get(gem); - pdata->ls1012a_eth_pdata[port].phy_node = phy_node; - } else if (of_get_property(gem, "fsl,pfe-phy-if-flags", &size)) { -+ pfe_use_old_dts_phy = true; - /* Use old dts properties for phy handling */ - addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size); - pdata->ls1012a_eth_pdata[port].phy_flags = be32_to_cpup(addr); diff --git a/target/linux/layerscape/patches-5.4/701-net-0315-net-fsl_ppfe-update-dts-properties-for-phy.patch b/target/linux/layerscape/patches-5.4/701-net-0315-net-fsl_ppfe-update-dts-properties-for-phy.patch deleted file mode 100644 index 6c74496ec8..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0315-net-fsl_ppfe-update-dts-properties-for-phy.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 153d669864c9280698641a6708c5ddcffbfeda26 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Tue, 20 Nov 2018 21:51:53 +0530 -Subject: [PATCH] net: fsl_ppfe: update dts properties for phy - -Use commonly used phy-handle property and mdio subnode to handle -phy properties. - -Deprecate bindings fsl,gemac-phy-id & fsl,pfe-phy-if-flags. - -Signed-off-by: Calvin Johnson ---- - .../devicetree/bindings/net/fsl_ppfe/pfe.txt | 60 ++++++++++++++++------ - 1 file changed, 43 insertions(+), 17 deletions(-) - ---- a/Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt -+++ b/Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt -@@ -127,11 +127,12 @@ PROPERTIES - Definition: Must be present. Value should be the id of the bus - connected to gemac. - --- fsl,gemac-phy-id -- Usage: required -- Value type: -- Definition: Must be present. Value should be the id of the phy -- connected to gemac. -+- fsl,gemac-phy-id (deprecated binding) -+ Usage: required -+ Value type: -+ Definition: This binding shouldn't be used with new platforms. -+ Must be present. Value should be the id of the phy -+ connected to gemac. - - - fsl,mdio-mux-val - Usage: required -@@ -144,15 +145,20 @@ PROPERTIES - Value type: - Definition: Must include "sgmii" - --- fsl,pfe-phy-if-flags -- Usage: required -- Value type: -- Definition: Must be present. Value should be 0 by default. -- If there is not phy connected, this need to be 1. -+- fsl,pfe-phy-if-flags (deprecated binding) -+ Usage: required -+ Value type: -+ Definition: This binding shouldn't be used with new platforms. -+ Must be present. Value should be 0 by default. -+ If there is not phy connected, this need to be 1. -+ -+- phy-handle -+ Usage: optional -+ Value type: -+ Definition: phandle to the PHY device connected to this device. - --- mdio -- optional subnode that specifies the mdio bus. This has reg -- property which is used to enable/disable the mdio bus. -+- mdio : A required subnode which specifies the mdio bus in the PFE and used as -+a container for phy nodes according to ../phy.txt. - - EXAMPLE - -@@ -162,12 +168,32 @@ ethernet@0 { - #size-cells = <0>; - reg = <0x0>; /* GEM_ID */ - fsl,gemac-bus-id = <0x0>; /* BUS_ID */ -- fsl,gemac-phy-id = <0x2>; /* PHY_ID */ - fsl,mdio-mux-val = <0x0>; - phy-mode = "sgmii"; -- fsl,pfe-phy-if-flags = <0x0>; -+ phy-handle = <&sgmii_phy1>; -+}; -+ -+ -+ethernet@1 { -+ compatible = "fsl,pfe-gemac-port"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <0x1>; /* GEM_ID */ -+ fsl,gemac-bus-id = <0x1>; /* BUS_ID */ -+ fsl,mdio-mux-val = <0x0>; -+ phy-mode = "sgmii"; -+ phy-handle = <&sgmii_phy2>; -+}; -+ -+mdio@0 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ sgmii_phy1: ethernet-phy@2 { -+ reg = <0x2>; -+ }; - -- mdio@0 { -- reg = <0x1>; /* enabled/disabled */ -+ sgmii_phy2: ethernet-phy@1 { -+ reg = <0x1>; - }; - }; diff --git a/target/linux/layerscape/patches-5.4/701-net-0316-staging-fsl_ppfe-eth-remove-unused-code.patch b/target/linux/layerscape/patches-5.4/701-net-0316-staging-fsl_ppfe-eth-remove-unused-code.patch deleted file mode 100644 index 32211953a5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0316-staging-fsl_ppfe-eth-remove-unused-code.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 4fa4a610e4c37741aa1d7763762f2231e4ca1d1d Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Fri, 7 Dec 2018 19:30:03 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: remove unused code - -- remove gemac-bus-id related code that is unused. -- remove unused prototype gemac_set_mdc_div. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/include/pfe/pfe.h | 1 - - drivers/staging/fsl_ppfe/pfe_eth.h | 1 - - drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 7 ------- - 3 files changed, 9 deletions(-) - ---- a/drivers/staging/fsl_ppfe/include/pfe/pfe.h -+++ b/drivers/staging/fsl_ppfe/include/pfe/pfe.h -@@ -268,7 +268,6 @@ enum mac_loop {LB_NONE, LB_EXT, LB_LOCAL - void gemac_init(void *base, void *config); - void gemac_disable_rx_checksum_offload(void *base); - void gemac_enable_rx_checksum_offload(void *base); --void gemac_set_mdc_div(void *base, int mdc_div); - void gemac_set_speed(void *base, enum mac_speed gem_speed); - void gemac_set_duplex(void *base, int duplex); - void gemac_set_mode(void *base, int mode); ---- a/drivers/staging/fsl_ppfe/pfe_eth.h -+++ b/drivers/staging/fsl_ppfe/pfe_eth.h -@@ -41,7 +41,6 @@ struct ls1012a_eth_platform_data { - u32 mii_config; - u32 phy_flags; - u32 gem_id; -- u32 bus_id; - u32 phy_id; - u32 mdio_muxval; - u8 mac_addr[ETH_ALEN]; ---- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -@@ -50,13 +50,6 @@ static int pfe_get_gemac_if_properties(s - - of_get_mac_address(gem, pdata->ls1012a_eth_pdata[port].mac_addr); - -- addr = of_get_property(gem, "fsl,gemac-bus-id", &size); -- if (!addr) -- pr_err("%s:%d Invalid gemac-bus-id....\n", __func__, -- __LINE__); -- else -- pdata->ls1012a_eth_pdata[port].bus_id = be32_to_cpup(addr); -- - phy_node = of_parse_phandle(gem, "phy-handle", 0); - pdata->ls1012a_eth_pdata[port].phy_node = phy_node; - if (phy_node) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0317-staging-fsl_ppfe-eth-separate-mdio-init-from-mac-ini.patch b/target/linux/layerscape/patches-5.4/701-net-0317-staging-fsl_ppfe-eth-separate-mdio-init-from-mac-ini.patch deleted file mode 100644 index 74fb01ce0b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0317-staging-fsl_ppfe-eth-separate-mdio-init-from-mac-ini.patch +++ /dev/null @@ -1,650 +0,0 @@ -From 8848f975ce42674b8bc8dedb5c7b326a42088e99 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Mon, 10 Dec 2018 10:22:33 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: separate mdio init from mac init - -- separate mdio initialization from mac initialization -- Define pfe_mdio_priv_s structure to hold mii_bus structure and other - related data. -- Modify functions to work with the separted mdio init model. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 232 ++++++++++-------------- - drivers/staging/fsl_ppfe/pfe_eth.h | 17 +- - drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 50 ++--- - drivers/staging/fsl_ppfe/pfe_mod.h | 1 + - 4 files changed, 126 insertions(+), 174 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -790,10 +790,9 @@ const struct ethtool_ops pfe_ethtool_ops - */ - int pfe_eth_mdio_reset(struct mii_bus *bus) - { -- struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; -+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv; - u32 phy_speed; - -- netif_info(priv, hw, priv->ndev, "%s\n", __func__); - - mutex_lock(&bus->mdio_lock); - -@@ -806,25 +805,25 @@ int pfe_eth_mdio_reset(struct mii_bus *b - phy_speed = (DIV_ROUND_UP((pfe->ctrl.sys_clk * 1000), 4000000) - << EMAC_MII_SPEED_SHIFT); - phy_speed |= EMAC_HOLDTIME(0x5); -- __raw_writel(phy_speed, priv->PHY_baseaddr + EMAC_MII_CTRL_REG); -+ __raw_writel(phy_speed, priv->mdio_base + EMAC_MII_CTRL_REG); - - mutex_unlock(&bus->mdio_lock); - - return 0; - } - --/* pfe_eth_gemac_phy_timeout -+/* pfe_eth_mdio_timeout - * - */ --static int pfe_eth_gemac_phy_timeout(struct pfe_eth_priv_s *priv, int timeout) -+static int pfe_eth_mdio_timeout(struct pfe_mdio_priv_s *priv, int timeout) - { -- while (!(__raw_readl(priv->PHY_baseaddr + EMAC_IEVENT_REG) & -+ while (!(__raw_readl(priv->mdio_base + EMAC_IEVENT_REG) & - EMAC_IEVENT_MII)) { - if (timeout-- <= 0) - return -1; - usleep_range(10, 20); - } -- __raw_writel(EMAC_IEVENT_MII, priv->PHY_baseaddr + EMAC_IEVENT_REG); -+ __raw_writel(EMAC_IEVENT_MII, priv->mdio_base + EMAC_IEVENT_REG); - return 0; - } - -@@ -856,16 +855,15 @@ static int pfe_eth_mdio_mux(u8 muxval) - static int pfe_eth_mdio_write_addr(struct mii_bus *bus, int mii_id, - int dev_addr, int regnum) - { -- struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; -+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv; - - __raw_writel(EMAC_MII_DATA_PA(mii_id) | - EMAC_MII_DATA_RA(dev_addr) | - EMAC_MII_DATA_TA | EMAC_MII_DATA(regnum), -- priv->PHY_baseaddr + EMAC_MII_DATA_REG); -+ priv->mdio_base + EMAC_MII_DATA_REG); - -- if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { -- netdev_err(priv->ndev, "%s: phy MDIO address write timeout\n", -- __func__); -+ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) { -+ dev_err(&bus->dev, "phy MDIO address write timeout\n"); - return -1; - } - -@@ -875,7 +873,7 @@ static int pfe_eth_mdio_write_addr(struc - static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum, - u16 value) - { -- struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; -+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv; - - /*To access external PHYs on QDS board mux needs to be configured*/ - if ((mii_id) && (pfe->mdio_muxval[mii_id])) -@@ -888,30 +886,26 @@ static int pfe_eth_mdio_write(struct mii - EMAC_MII_DATA_PA(mii_id) | - EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) | - EMAC_MII_DATA_TA | EMAC_MII_DATA(value), -- priv->PHY_baseaddr + EMAC_MII_DATA_REG); -+ priv->mdio_base + EMAC_MII_DATA_REG); - } else { - /* start a write op */ - __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR | - EMAC_MII_DATA_PA(mii_id) | - EMAC_MII_DATA_RA(regnum) | - EMAC_MII_DATA_TA | EMAC_MII_DATA(value), -- priv->PHY_baseaddr + EMAC_MII_DATA_REG); -+ priv->mdio_base + EMAC_MII_DATA_REG); - } - -- if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { -- netdev_err(priv->ndev, "%s: phy MDIO write timeout\n", -- __func__); -+ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) { -+ dev_err(&bus->dev, "%s: phy MDIO write timeout\n", __func__); - return -1; - } -- netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__, -- mii_id, regnum, value); -- - return 0; - } - - static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum) - { -- struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv; -+ struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv; - u16 value = 0; - - /*To access external PHYs on QDS board mux needs to be configured*/ -@@ -925,65 +919,67 @@ static int pfe_eth_mdio_read(struct mii_ - EMAC_MII_DATA_PA(mii_id) | - EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) | - EMAC_MII_DATA_TA, -- priv->PHY_baseaddr + EMAC_MII_DATA_REG); -+ priv->mdio_base + EMAC_MII_DATA_REG); - } else { - /* start a read op */ - __raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD | - EMAC_MII_DATA_PA(mii_id) | - EMAC_MII_DATA_RA(regnum) | -- EMAC_MII_DATA_TA, priv->PHY_baseaddr + -+ EMAC_MII_DATA_TA, priv->mdio_base + - EMAC_MII_DATA_REG); - } - -- if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) { -- netdev_err(priv->ndev, "%s: phy MDIO read timeout\n", __func__); -+ if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) { -+ dev_err(&bus->dev, "%s: phy MDIO read timeout\n", __func__); - return -1; - } - -- value = EMAC_MII_DATA(__raw_readl(priv->PHY_baseaddr + -+ value = EMAC_MII_DATA(__raw_readl(priv->mdio_base + - EMAC_MII_DATA_REG)); -- netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__, -- mii_id, regnum, value); - return value; - } - --static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv, -- struct ls1012a_mdio_platform_data *minfo) -+static int pfe_eth_mdio_init(struct pfe *pfe, -+ struct ls1012a_pfe_platform_data *pfe_info, -+ int ii) - { -+ struct pfe_mdio_priv_s *priv = NULL; -+ struct ls1012a_mdio_platform_data *mdio_info; - struct mii_bus *bus; - struct device_node *mdio_node; -- int rc = 0, ii; -- struct phy_device *phydev; -+ int rc = 0; - -- netif_info(priv, drv, priv->ndev, "%s\n", __func__); -- pr_info("%s\n", __func__); -+ mdio_info = (struct ls1012a_mdio_platform_data *) -+ pfe_info->ls1012a_mdio_pdata; -+ mdio_info->id = ii; - -- bus = mdiobus_alloc(); -+ bus = mdiobus_alloc_size(sizeof(struct pfe_mdio_priv_s)); - if (!bus) { -- netdev_err(priv->ndev, "mdiobus_alloc() failed\n"); -+ pr_err("mdiobus_alloc() failed\n"); - rc = -ENOMEM; -- goto err0; -+ goto err_mdioalloc; - } - - bus->name = "ls1012a MDIO Bus"; -- snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id); -+ snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", mdio_info->id); - -- bus->priv = priv; - bus->read = &pfe_eth_mdio_read; - bus->write = &pfe_eth_mdio_write; - bus->reset = &pfe_eth_mdio_reset; -- bus->parent = priv->pfe->dev; -- bus->phy_mask = minfo->phy_mask; -- bus->irq[0] = minfo->irq[0]; -+ bus->parent = pfe->dev; -+ bus->phy_mask = mdio_info->phy_mask; -+ bus->irq[0] = mdio_info->irq[0]; -+ priv = bus->priv; -+ priv->mdio_base = cbus_emac_base[ii]; - -- priv->mdc_div = minfo->mdc_div; -+ priv->mdc_div = mdio_info->mdc_div; - if (!priv->mdc_div) - priv->mdc_div = 64; -- netif_info(priv, drv, priv->ndev, "%s: mdc_div: %d, phy_mask: %x\n", -- __func__, priv->mdc_div, bus->phy_mask); -+ dev_info(bus->parent, "%s: mdc_div: %d, phy_mask: %x\n", -+ __func__, priv->mdc_div, bus->phy_mask); - -- mdio_node = of_get_child_by_name(priv->pfe->dev->of_node, "mdio"); -- if (mdio_node) { -+ mdio_node = of_get_child_by_name(pfe->dev->of_node, "mdio"); -+ if ((mdio_info->id == 0) && mdio_node) { - rc = of_mdiobus_register(bus, mdio_node); - of_node_put(mdio_node); - } else { -@@ -991,56 +987,34 @@ static int pfe_eth_mdio_init(struct pfe_ - } - - if (rc) { -- netdev_err(priv->ndev, "mdiobus_register(%s) failed\n", -- bus->name); -- goto err1; -+ dev_err(bus->parent, "mdiobus_register(%s) failed\n", -+ bus->name); -+ goto err_mdioregister; - } - - priv->mii_bus = bus; -- -- /* For clause 45 we need to call get_phy_device() with it's -- * 3rd argument as true and then register the phy device -- * via phy_device_register() -- */ -- if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) { -- for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) { -- phydev = get_phy_device(priv->mii_bus, -- priv->einfo->phy_id + ii, true); -- if (!phydev || IS_ERR(phydev)) { -- rc = -EIO; -- netdev_err(priv->ndev, "fail to get device\n"); -- goto err1; -- } -- rc = phy_device_register(phydev); -- if (rc) { -- phy_device_free(phydev); -- netdev_err(priv->ndev, -- "phy_device_register() failed\n"); -- goto err1; -- } -- } -- } -+ pfe->mdio.mdio_priv[ii] = priv; - - pfe_eth_mdio_reset(bus); - - return 0; - --err1: -+err_mdioregister: - mdiobus_free(bus); --err0: -+err_mdioalloc: - return rc; - } - - /* pfe_eth_mdio_exit - */ --static void pfe_eth_mdio_exit(struct mii_bus *bus) -+static void pfe_eth_mdio_exit(struct pfe *pfe, -+ int ii) - { -+ struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[ii]; -+ struct mii_bus *bus = mdio_priv->mii_bus; -+ - if (!bus) - return; -- -- netif_info((struct pfe_eth_priv_s *)bus->priv, drv, ((struct -- pfe_eth_priv_s *)(bus->priv))->ndev, "%s\n", __func__); -- - mdiobus_unregister(bus); - mdiobus_free(bus); - } -@@ -1221,15 +1195,16 @@ static int pfe_eth_start(struct pfe_eth_ - */ - static void ls1012a_configure_serdes(struct net_device *ndev) - { -- struct pfe_eth_priv_s *priv = pfe->eth.eth_priv[0]; -+ struct pfe_eth_priv_s *eth_priv = netdev_priv(ndev); -+ struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[eth_priv->id]; - int sgmii_2500 = 0; -- struct mii_bus *bus = priv->mii_bus; -+ struct mii_bus *bus = mdio_priv->mii_bus; - u16 value = 0; - -- if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) -+ if (eth_priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) - sgmii_2500 = 1; - -- netif_info(priv, drv, ndev, "%s\n", __func__); -+ netif_info(eth_priv, drv, ndev, "%s\n", __func__); - /* PCS configuration done with corresponding GEMAC */ - - pfe_eth_mdio_read(bus, 0, MDIO_SGMII_CR); -@@ -2333,26 +2308,15 @@ static const struct net_device_ops pfe_n - - /* pfe_eth_init_one - */ --static int pfe_eth_init_one(struct pfe *pfe, int id) -+static int pfe_eth_init_one(struct pfe *pfe, -+ struct ls1012a_pfe_platform_data *pfe_info, -+ int id) - { - struct net_device *ndev = NULL; - struct pfe_eth_priv_s *priv = NULL; - struct ls1012a_eth_platform_data *einfo; -- struct ls1012a_mdio_platform_data *minfo; -- struct ls1012a_pfe_platform_data *pfe_info; - int err; - -- /* Extract pltform data */ -- pfe_info = (struct ls1012a_pfe_platform_data *) -- pfe->dev->platform_data; -- if (!pfe_info) { -- pr_err( -- "%s: pfe missing additional platform data\n" -- , __func__); -- err = -ENODEV; -- goto err0; -- } -- - einfo = (struct ls1012a_eth_platform_data *) - pfe_info->ls1012a_eth_pdata; - -@@ -2365,18 +2329,6 @@ static int pfe_eth_init_one(struct pfe * - goto err0; - } - -- minfo = (struct ls1012a_mdio_platform_data *) -- pfe_info->ls1012a_mdio_pdata; -- -- /* einfo never be NULL, but no harm in having this check */ -- if (!minfo) { -- pr_err( -- "%s: pfe missing additional mdios platform data\n", -- __func__); -- err = -ENODEV; -- goto err0; -- } -- - if (us) - emac_txq_cnt = EMAC_TXQ_CNT; - /* Create an ethernet device instance */ -@@ -2402,7 +2354,6 @@ static int pfe_eth_init_one(struct pfe * - /* Set the info in the priv to the current info */ - priv->einfo = &einfo[id]; - priv->EMAC_baseaddr = cbus_emac_base[id]; -- priv->PHY_baseaddr = cbus_emac_base[0]; - priv->GPI_baseaddr = cbus_gpi_base[id]; - - spin_lock_init(&priv->lock); -@@ -2412,13 +2363,6 @@ static int pfe_eth_init_one(struct pfe * - /* Copy the station address into the dev structure, */ - memcpy(ndev->dev_addr, einfo[id].mac_addr, ETH_ALEN); - -- /* Initialize mdio */ -- err = pfe_eth_mdio_init(priv, &minfo[id]); -- if (err) { -- netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n", __func__); -- goto err1; -- } -- - if (us) - goto phy_init; - -@@ -2463,7 +2407,7 @@ static int pfe_eth_init_one(struct pfe * - err = register_netdev(ndev); - if (err) { - netdev_err(ndev, "register_netdev() failed\n"); -- goto err2; -+ goto err1; - } - - if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) || -@@ -2480,7 +2424,7 @@ phy_init: - if (err) { - netdev_err(ndev, "%s: pfe_phy_init() failed\n", - __func__); -- goto err3; -+ goto err2; - } - - if (us) { -@@ -2494,21 +2438,19 @@ phy_init: - skip_phy_init: - /* Create all the sysfs files */ - if (pfe_eth_sysfs_init(ndev)) -- goto err4; -+ goto err3; - - netif_info(priv, probe, ndev, "%s: created interface, baseaddr: %p\n", - __func__, priv->EMAC_baseaddr); - - return 0; - --err4: -- pfe_phy_exit(priv->ndev); - err3: -+ pfe_phy_exit(priv->ndev); -+err2: - if (us) -- goto err2; -+ goto err1; - unregister_netdev(ndev); --err2: -- pfe_eth_mdio_exit(priv->mii_bus); - err1: - free_netdev(priv->ndev); - err0: -@@ -2521,6 +2463,7 @@ int pfe_eth_init(struct pfe *pfe) - { - int ii = 0; - int err; -+ struct ls1012a_pfe_platform_data *pfe_info; - - pr_info("%s\n", __func__); - -@@ -2530,24 +2473,43 @@ int pfe_eth_init(struct pfe *pfe) - cbus_gpi_base[0] = EGPI1_BASE_ADDR; - cbus_gpi_base[1] = EGPI2_BASE_ADDR; - -+ pfe_info = (struct ls1012a_pfe_platform_data *) -+ pfe->dev->platform_data; -+ if (!pfe_info) { -+ pr_err("%s: pfe missing additional platform data\n", __func__); -+ err = -ENODEV; -+ goto err_pdata; -+ } -+ -+ for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) { -+ err = pfe_eth_mdio_init(pfe, pfe_info, ii); -+ if (err) { -+ pr_err("%s: pfe_eth_mdio_init() failed\n", __func__); -+ goto err_mdio_init; -+ } -+ } -+ - if (fsl_guts_get_svr() == LS1012A_REV_1_0) - pfe_errata_a010897 = true; - else - pfe_errata_a010897 = false; - - for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) { -- err = pfe_eth_init_one(pfe, ii); -+ err = pfe_eth_init_one(pfe, pfe_info, ii); - if (err) -- goto err0; -+ goto err_eth_init; - } - - return 0; - --err0: -- while (ii--) -+err_eth_init: -+ while (ii--) { - pfe_eth_exit_one(pfe->eth.eth_priv[ii]); -+ pfe_eth_mdio_exit(pfe, ii); -+ } - -- /* Register three network devices in the kernel */ -+err_mdio_init: -+err_pdata: - return err; - } - -@@ -2573,9 +2535,6 @@ skip_phy_exit: - if (!us) - unregister_netdev(priv->ndev); - -- if (priv->mii_bus) -- pfe_eth_mdio_exit(priv->mii_bus); -- - free_netdev(priv->ndev); - } - -@@ -2589,4 +2548,7 @@ void pfe_eth_exit(struct pfe *pfe) - - for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--) - pfe_eth_exit_one(pfe->eth.eth_priv[ii]); -+ -+ for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--) -+ pfe_eth_mdio_exit(pfe, ii); - } ---- a/drivers/staging/fsl_ppfe/pfe_eth.h -+++ b/drivers/staging/fsl_ppfe/pfe_eth.h -@@ -48,7 +48,7 @@ struct ls1012a_eth_platform_data { - }; - - struct ls1012a_mdio_platform_data { -- int enabled; -+ int id; - int irq[32]; - u32 phy_mask; - int mdc_div; -@@ -120,8 +120,6 @@ struct pfe_eth_priv_s { - unsigned int event_status; - int irq; - void *EMAC_baseaddr; -- /* This points to the EMAC base from where we access PHY */ -- void *PHY_baseaddr; - void *GPI_baseaddr; - /* PHY stuff */ - struct phy_device *phydev; -@@ -129,9 +127,6 @@ struct pfe_eth_priv_s { - int oldduplex; - int oldlink; - struct device_node *phy_node; -- /* mdio info */ -- int mdc_div; -- struct mii_bus *mii_bus; - struct clk *gemtx_clk; - int wol; - int pause_flag; -@@ -161,6 +156,16 @@ struct pfe_eth { - struct pfe_eth_priv_s *eth_priv[3]; - }; - -+struct pfe_mdio_priv_s { -+ void __iomem *mdio_base; -+ int mdc_div; -+ struct mii_bus *mii_bus; -+}; -+ -+struct pfe_mdio { -+ struct pfe_mdio_priv_s *mdio_priv[3]; -+}; -+ - int pfe_eth_init(struct pfe *pfe); - void pfe_eth_exit(struct pfe *pfe); - int pfe_eth_suspend(struct net_device *dev); ---- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -@@ -21,30 +21,17 @@ - extern bool pfe_use_old_dts_phy; - struct ls1012a_pfe_platform_data pfe_platform_data; - --static int pfe_get_gemac_if_properties(struct device_node *parent, int port, int -- if_cnt, -- struct ls1012a_pfe_platform_data -- *pdata) -+static int pfe_get_gemac_if_properties(struct device_node *gem, -+ int port, -+ struct ls1012a_pfe_platform_data *pdata) - { -- struct device_node *gem = NULL, *phy = NULL, *phy_node = NULL; -+ struct device_node *phy_node = NULL; - int size; -- int ii = 0, phy_id = 0; -+ int phy_id = 0; - const u32 *addr; - -- for (ii = 0; ii < if_cnt; ii++) { -- gem = of_get_next_child(parent, gem); -- if (!gem) -- goto err; -- addr = of_get_property(gem, "reg", &size); -- if (addr && (be32_to_cpup(addr) == port)) -- break; -- } -- -- if (ii >= if_cnt) { -- pr_err("%s:%d Failed to find interface = %d\n", -- __func__, __LINE__, if_cnt); -- goto err; -- } -+ addr = of_get_property(gem, "reg", &size); -+ port = be32_to_cpup(addr); - - pdata->ls1012a_eth_pdata[port].gem_id = port; - -@@ -83,14 +70,6 @@ static int pfe_get_gemac_if_properties(s - if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY) - goto done; - -- phy = of_get_next_child(gem, NULL); -- addr = of_get_property(phy, "reg", &size); -- if (!addr) -- pr_err("%s:%d Invalid phy enable flag....\n", -- __func__, __LINE__); -- else -- pdata->ls1012a_mdio_pdata[port].enabled = -- be32_to_cpup(addr); - } else { - pr_info("%s: No PHY or fixed-link\n", __func__); - return 0; -@@ -135,7 +114,7 @@ static int pfe_platform_probe(struct pla - struct resource res; - int ii, rc, interface_count = 0, size = 0; - const u32 *prop; -- struct device_node *np; -+ struct device_node *np, *gem = NULL; - struct clk *pfe_clk; - - np = pdev->dev.of_node; -@@ -219,8 +198,13 @@ static int pfe_platform_probe(struct pla - pfe_platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff; - - for (ii = 0; ii < interface_count; ii++) { -- pfe_get_gemac_if_properties(np, ii, interface_count, -- &pfe_platform_data); -+ gem = of_get_next_child(np, gem); -+ if (gem) -+ pfe_get_gemac_if_properties(gem, ii, -+ &pfe_platform_data); -+ else -+ pr_err("Unable to find interface %d\n", ii); -+ - } - - pfe->dev = &pdev->dev; -@@ -342,8 +326,8 @@ static int pfe_platform_resume(struct de - for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) { - netdev = pfe->eth.eth_priv[i]->ndev; - -- if (pfe->eth.eth_priv[i]->mii_bus) -- pfe_eth_mdio_reset(pfe->eth.eth_priv[i]->mii_bus); -+ if (pfe->mdio.mdio_priv[i]->mii_bus) -+ pfe_eth_mdio_reset(pfe->mdio.mdio_priv[i]->mii_bus); - - if (netif_running(netdev)) - pfe_eth_resume(netdev); ---- a/drivers/staging/fsl_ppfe/pfe_mod.h -+++ b/drivers/staging/fsl_ppfe/pfe_mod.h -@@ -52,6 +52,7 @@ struct pfe { - struct pfe_ctrl ctrl; - struct pfe_hif hif; - struct pfe_eth eth; -+ struct pfe_mdio mdio; - struct hif_client_s *hif_client[HIF_CLIENTS_MAX]; - #if defined(CFG_DIAGS) - struct pfe_diags diags; diff --git a/target/linux/layerscape/patches-5.4/701-net-0318-staging-fsl_ppfe-eth-adapt-to-link-mode-based-phydev.patch b/target/linux/layerscape/patches-5.4/701-net-0318-staging-fsl_ppfe-eth-adapt-to-link-mode-based-phydev.patch deleted file mode 100644 index bf34d39be4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0318-staging-fsl_ppfe-eth-adapt-to-link-mode-based-phydev.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 002297dd2634e993257a00fe4458b0288ec7baea Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 27 Mar 2019 13:25:57 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: adapt to link mode based phydev - changes - -Setting link mode bits have changed with the integration of -commit (3c1bcc8 net: ethernet: Convert phydev advertize and -supported from u32 to link mode). Adapt to the new method of -setting and clearing the link mode bits. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -701,10 +701,14 @@ static int pfe_eth_set_pauseparam(struct - EGPI_PAUSE_ENABLE), - priv->GPI_baseaddr + GPI_TX_PAUSE_TIME); - if (priv->phydev) { -- priv->phydev->supported |= ADVERTISED_Pause | -- ADVERTISED_Asym_Pause; -- priv->phydev->advertising |= ADVERTISED_Pause | -- ADVERTISED_Asym_Pause; -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, -+ priv->phydev->supported); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, -+ priv->phydev->supported); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, -+ priv->phydev->advertising); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, -+ priv->phydev->advertising); - } - } else { - gemac_disable_pause_rx(priv->EMAC_baseaddr); -@@ -712,10 +716,14 @@ static int pfe_eth_set_pauseparam(struct - ~EGPI_PAUSE_ENABLE), - priv->GPI_baseaddr + GPI_TX_PAUSE_TIME); - if (priv->phydev) { -- priv->phydev->supported &= ~(ADVERTISED_Pause | -- ADVERTISED_Asym_Pause); -- priv->phydev->advertising &= ~(ADVERTISED_Pause | -- ADVERTISED_Asym_Pause); -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, -+ priv->phydev->supported); -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, -+ priv->phydev->supported); -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, -+ priv->phydev->advertising); -+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, -+ priv->phydev->advertising); - } - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0319-staging-fsl_ppfe-eth-use-generic-soc_device-infra-in.patch b/target/linux/layerscape/patches-5.4/701-net-0319-staging-fsl_ppfe-eth-use-generic-soc_device-infra-in.patch deleted file mode 100644 index 11bd1fff78..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0319-staging-fsl_ppfe-eth-use-generic-soc_device-infra-in.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 3f64975a822c9144c7134d3cebadd4d8b88fead5 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 27 Mar 2019 19:31:35 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: use generic soc_device infra instead - of fsl_guts_get_svr() - -Commit ("soc: fsl: guts: make fsl_guts_get_svr() static") has -made fsl_guts_get_svr() static and hence use generic soc_device -infrastructure to check SoC revision. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -35,7 +35,7 @@ - #include - #include - #include --#include -+#include - - #if defined(CONFIG_NF_CONNTRACK_MARK) - #include -@@ -104,6 +104,14 @@ unsigned int gemac_regs[] = { - 0x01B0, /* Frame Truncation Length */ - }; - -+const struct soc_device_attribute ls1012a_rev1_soc_attr[] = { -+ { .family = "QorIQ LS1012A", -+ .soc_id = "svr:0x87040010", -+ .revision = "1.0", -+ .data = NULL }, -+ { }, -+}; -+ - /********************************************************************/ - /* SYSFS INTERFACE */ - /********************************************************************/ -@@ -2497,7 +2505,7 @@ int pfe_eth_init(struct pfe *pfe) - } - } - -- if (fsl_guts_get_svr() == LS1012A_REV_1_0) -+ if (soc_device_match(ls1012a_rev1_soc_attr)) - pfe_errata_a010897 = true; - else - pfe_errata_a010897 = false; diff --git a/target/linux/layerscape/patches-5.4/701-net-0320-staging-fsl_ppfe-eth-use-memremap-to-map-RAM-area-us.patch b/target/linux/layerscape/patches-5.4/701-net-0320-staging-fsl_ppfe-eth-use-memremap-to-map-RAM-area-us.patch deleted file mode 100644 index c9c3a7a888..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0320-staging-fsl_ppfe-eth-use-memremap-to-map-RAM-area-us.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 7872505a2194c9766c7986e761c0ae9bdd6e5e57 Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Tue, 26 Mar 2019 16:52:22 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: use memremap() to map RAM area used by - PFE - -RAM area used by PFE should be mapped using memremap() instead of -directly traslating physical addr to virtual. This will ensure proper -checks are done before the area is used. - -Signed-off-by: Calvin Johnson ---- - drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -@@ -143,9 +143,10 @@ static int pfe_platform_probe(struct pla - pfe->ddr_phys_baseaddr = res.start; - pfe->ddr_size = resource_size(&res); - -- pfe->ddr_baseaddr = phys_to_virt(res.start); -+ pfe->ddr_baseaddr = memremap(res.start, resource_size(&res), -+ MEMREMAP_WB); - if (!pfe->ddr_baseaddr) { -- pr_err("ioremap() ddr failed\n"); -+ pr_err("memremap() ddr failed\n"); - rc = -ENOMEM; - goto err_ddr; - } -@@ -235,7 +236,7 @@ err_hif_irq: - iounmap(pfe->cbus_baseaddr); - - err_axi: -- iounmap(pfe->ddr_baseaddr); -+ memunmap(pfe->ddr_baseaddr); - - err_ddr: - platform_set_drvdata(pdev, NULL); -@@ -259,7 +260,8 @@ static int pfe_platform_remove(struct pl - rc = pfe_remove(pfe); - - iounmap(pfe->cbus_baseaddr); -- iounmap(pfe->ddr_baseaddr); -+ -+ memunmap(pfe->ddr_baseaddr); - - platform_set_drvdata(pdev, NULL); - diff --git a/target/linux/layerscape/patches-5.4/701-net-0321-staging-fsl_ppfe-eth-remove-fallback-argument-from-d.patch b/target/linux/layerscape/patches-5.4/701-net-0321-staging-fsl_ppfe-eth-remove-fallback-argument-from-d.patch deleted file mode 100644 index 9d4169e524..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0321-staging-fsl_ppfe-eth-remove-fallback-argument-from-d.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 52f6eea9b70007cb0c5d13b9268d37bfddbaf0f4 Mon Sep 17 00:00:00 2001 -From: Li Yang -Date: Tue, 11 Jun 2019 18:24:37 -0500 -Subject: [PATCH] staging: fsl_ppfe/eth: remove 'fallback' argument from - dev->ndo_select_queue() - -To be consistent with upstream API change. - -Signed-off-by: Li Yang ---- - drivers/staging/fsl_ppfe/pfe_eth.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_eth.c -+++ b/drivers/staging/fsl_ppfe/pfe_eth.c -@@ -1879,8 +1879,7 @@ static int pfe_eth_send_packet(struct sk - * - */ - static u16 pfe_eth_select_queue(struct net_device *ndev, struct sk_buff *skb, -- struct net_device *sb_dev, -- select_queue_fallback_t fallback) -+ struct net_device *sb_dev) - { - struct pfe_eth_priv_s *priv = netdev_priv(ndev); - diff --git a/target/linux/layerscape/patches-5.4/701-net-0322-staging-fsl_ppfe-eth-prefix-header-search-paths-with.patch b/target/linux/layerscape/patches-5.4/701-net-0322-staging-fsl_ppfe-eth-prefix-header-search-paths-with.patch deleted file mode 100644 index 339813aeeb..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0322-staging-fsl_ppfe-eth-prefix-header-search-paths-with.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 9b280449f99b5273b52d88574c7358a874f825a3 Mon Sep 17 00:00:00 2001 -From: Ting Liu -Date: Mon, 17 Jun 2019 09:27:53 +0200 -Subject: [PATCH] staging: fsl_ppfe/eth: prefix header search paths with - $(srctree)/ - -Currently, the rules for configuring search paths in Kbuild have -changed: https://lkml.org/lkml/2019/5/13/37 - -This will lead the below error: - -fatal error: pfe/pfe.h: No such file or directory - -Fix it by adding $(srctree)/ prefix to the search paths. - -Signed-off-by: Ting Liu ---- - drivers/staging/fsl_ppfe/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/staging/fsl_ppfe/Makefile -+++ b/drivers/staging/fsl_ppfe/Makefile -@@ -2,7 +2,7 @@ - # Makefile for Freesecale PPFE driver - # - --ccflags-y += -I$(src)/include -I$(src) -+ccflags-y += -I $(srctree)/$(src)/include -I $(srctree)/$(src) - - obj-m += pfe.o - diff --git a/target/linux/layerscape/patches-5.4/701-net-0323-staging-fsl_ppfe-eth-add-pfe-support-to-Kconfig-and-.patch b/target/linux/layerscape/patches-5.4/701-net-0323-staging-fsl_ppfe-eth-add-pfe-support-to-Kconfig-and-.patch deleted file mode 100644 index d370f728dd..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0323-staging-fsl_ppfe-eth-add-pfe-support-to-Kconfig-and-.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 022999fe6c4008d1ca6ec0f33d7f7c88db97f3fa Mon Sep 17 00:00:00 2001 -From: Calvin Johnson -Date: Wed, 1 Nov 2017 11:11:30 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: add pfe support to Kconfig and - Makefile - -Signed-off-by: Calvin Johnson -[ Aisheng: fix minor conflict due to removed VBOXSF_FS ] -Signed-off-by: Dong Aisheng ---- - MAINTAINERS | 8 ++++++++ - drivers/staging/Kconfig | 1 + - drivers/staging/Makefile | 1 + - 3 files changed, 10 insertions(+) - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -6576,6 +6576,14 @@ F: drivers/ptp/ptp_qoriq_debugfs.c - F: include/linux/fsl/ptp_qoriq.h - F: Documentation/devicetree/bindings/ptp/ptp-qoriq.txt - -+FREESCALE QORIQ PPFE ETHERNET DRIVER -+M: Anji Jagarlmudi -+M: Calvin Johnson -+L: netdev@vger.kernel.org -+S: Maintained -+F: drivers/staging/fsl_ppfe -+F: Documentation/devicetree/bindings/net/fsl_ppfe/pfe.txt -+ - FREESCALE QUAD SPI DRIVER - M: Han Xu - L: linux-spi@vger.kernel.org ---- a/drivers/staging/Kconfig -+++ b/drivers/staging/Kconfig -@@ -126,5 +126,6 @@ source "drivers/staging/exfat/Kconfig" - source "drivers/staging/qlge/Kconfig" - - source "drivers/staging/fsl_qbman/Kconfig" -+source "drivers/staging/fsl_ppfe/Kconfig" - - endif # STAGING ---- a/drivers/staging/Makefile -+++ b/drivers/staging/Makefile -@@ -54,3 +54,4 @@ obj-$(CONFIG_USB_WUSB) += wusbcore/ - obj-$(CONFIG_EXFAT_FS) += exfat/ - obj-$(CONFIG_QLGE) += qlge/ - obj-$(CONFIG_FSL_SDK_DPA) += fsl_qbman/ -+obj-$(CONFIG_FSL_PPFE) += fsl_ppfe/ diff --git a/target/linux/layerscape/patches-5.4/701-net-0324-staging-fsl_ppfe-eth-Disable-termination-of-CRC-fwd.patch b/target/linux/layerscape/patches-5.4/701-net-0324-staging-fsl_ppfe-eth-Disable-termination-of-CRC-fwd.patch deleted file mode 100644 index 3d9870d78b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0324-staging-fsl_ppfe-eth-Disable-termination-of-CRC-fwd.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 6d7e10038aba81d7273f72f36db64c71ae7f8f69 Mon Sep 17 00:00:00 2001 -From: Nagesh Koneti -Date: Wed, 25 Sep 2019 12:01:19 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: Disable termination of CRC fwd. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -LS1012A MAC PCS block has an erratum that is seen with specific PHY AR803x. -The issue is triggered by the (spec-compliant) operation of the AR803x PHY -on the LS1012A-FRWY board.Due to this, good FCS packet is reported as error -packet by MAC, so for these error packets FCS should be validated and -discard only real error packets in PFE Rx packet path. - -Signed-off-by: Nagesh Koneti -Signed-off-by: Nagesh Koneti <“koneti.nagesh@nxp.comâ€> ---- - drivers/staging/fsl_ppfe/pfe_hal.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_hal.c -+++ b/drivers/staging/fsl_ppfe/pfe_hal.c -@@ -860,8 +860,9 @@ void gemac_set_mode(void *base, int mode - /*Remove loopbank*/ - val &= ~EMAC_RCNTRL_LOOP; - -- /* Enable flow control and MII mode and terminate received CRC */ -- val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE | EMAC_RCNTRL_CRC_FWD); -+ /* Enable flow control and MII mode.PFE firmware always expects -+ CRC should be forwarded by MAC to validate CRC in software.*/ -+ val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE); - - writel(val, base + EMAC_RCNTRL_REG); - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0325-net-phy-add-10G-fixed-link-support.patch b/target/linux/layerscape/patches-5.4/701-net-0325-net-phy-add-10G-fixed-link-support.patch deleted file mode 100644 index a227baf1f5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0325-net-phy-add-10G-fixed-link-support.patch +++ /dev/null @@ -1,20 +0,0 @@ -From c8d3576df41025b341eb767168914990598a0caa Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 22 Aug 2017 18:35:11 +0300 -Subject: [PATCH] net: phy: add 10G fixed-link support - -Signed-off-by: Camelia Groza ---- - drivers/net/phy/swphy.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/phy/swphy.c -+++ b/drivers/net/phy/swphy.c -@@ -71,6 +71,7 @@ static const struct swmii_regs duplex[] - static int swphy_decode_speed(int speed) - { - switch (speed) { -+ case 10000: - case 1000: - return SWMII_SPEED_1000; - case 100: diff --git a/target/linux/layerscape/patches-5.4/701-net-0326-phy-Add-2.5G-SGMII-interface-mode.patch b/target/linux/layerscape/patches-5.4/701-net-0326-phy-Add-2.5G-SGMII-interface-mode.patch deleted file mode 100644 index a0c72916d5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0326-phy-Add-2.5G-SGMII-interface-mode.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 457577118b28909a35f62bffc16bb52f73900b53 Mon Sep 17 00:00:00 2001 -From: Bhaskar Upadhaya -Date: Wed, 29 Nov 2017 15:27:57 +0530 -Subject: [PATCH] phy: Add 2.5G SGMII interface mode - -Add 2.5G SGMII interface mode(PHY_INTERFACE_MODE_2500SGMII) -in existing phy_interface list - -Signed-off-by: Bhaskar Upadhaya ---- - include/linux/phy.h | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -102,6 +102,7 @@ typedef enum { - /* 10GBASE-KR, XFI, SFI - single lane 10G Serdes */ - PHY_INTERFACE_MODE_10GKR, - PHY_INTERFACE_MODE_USXGMII, -+ PHY_INTERFACE_MODE_2500SGMII, - PHY_INTERFACE_MODE_MAX, - } phy_interface_t; - -@@ -179,6 +180,8 @@ static inline const char *phy_modes(phy_ - return "10gbase-kr"; - case PHY_INTERFACE_MODE_USXGMII: - return "usxgmii"; -+ case PHY_INTERFACE_MODE_2500SGMII: -+ return "sgmii-2500"; - default: - return "unknown"; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0327-at803x-Address-packet-drops-at-low-traffic-rate-due-.patch b/target/linux/layerscape/patches-5.4/701-net-0327-at803x-Address-packet-drops-at-low-traffic-rate-due-.patch deleted file mode 100644 index babecdecb7..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0327-at803x-Address-packet-drops-at-low-traffic-rate-due-.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 53c3bd0d5a873c23841bb95e7b95c1c3630c50bd Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 12 Jul 2018 13:03:13 +0300 -Subject: [PATCH] at803x: Address packet drops at low traffic rate due to - SmartEEE feature - -* According to the AR8035 datasheet, smartEEE mode (active by default) - makes the PHY enters sleep after a configurable idle time. It does - this autonomously, without LPI (Low Power Idle) signals coming from MAC. -* Tested with ping (default of 1 second interval) over back-to-back - RGMII between 2 boards having AR8035 at both ends: - - Without patch: - 225 packets transmitted, 145 received, 35% packet loss, time 229334ms - - With patch: - 144 packets transmitted, 144 received, 0% packet loss, time 146378ms - -Signed-off-by: Vladimir Oltean ---- - drivers/net/phy/Kconfig | 10 ++++++++++ - drivers/net/phy/at803x.c | 22 ++++++++++++++++++++++ - 2 files changed, 32 insertions(+) - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -363,6 +363,16 @@ config AT803X_PHY - ---help--- - Currently supports the AT8030 and AT8035 model - -+config AT803X_PHY_SMART_EEE -+ depends on AT803X_PHY -+ default n -+ tristate "SmartEEE feature for AT803X PHYs" -+ ---help--- -+ Enables the Atheros SmartEEE feature (not IEEE 802.3az). When 2 PHYs -+ which support this feature are connected back-to-back, they may -+ negotiate a low-power sleep mode autonomously, without the Ethernet -+ controller's knowledge. May cause packet loss. -+ - config BCM63XX_PHY - tristate "Broadcom 63xx SOCs internal PHY" - depends on BCM63XX || COMPILE_TEST ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -62,6 +62,8 @@ - #define AT803X_DEBUG_REG_5 0x05 - #define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) - -+#define AT803X_LPI_EN BIT(8) -+ - #define ATH8030_PHY_ID 0x004dd076 - #define ATH8031_PHY_ID 0x004dd074 - #define ATH8032_PHY_ID 0x004dd023 -@@ -299,10 +301,30 @@ static int at803x_probe(struct phy_devic - return ret; - } - -+static void at803x_enable_smart_eee(struct phy_device *phydev, int on) -+{ -+ int value; -+ -+ /* 5.1.11 Smart_eee control3 */ -+ value = phy_read_mmd(phydev, MDIO_MMD_PCS, 0x805D); -+ if (on) -+ value |= AT803X_LPI_EN; -+ else -+ value &= ~AT803X_LPI_EN; -+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x805D, value); -+} -+ - static int at803x_config_init(struct phy_device *phydev) - { - int ret; - -+ -+#ifdef CONFIG_AT803X_PHY_SMART_EEE -+ at803x_enable_smart_eee(phydev, 1); -+#else -+ at803x_enable_smart_eee(phydev, 0); -+#endif -+ - /* The RX and TX delay default is: - * after HW reset: RX delay enabled and TX delay disabled - * after SW reset: RX delay enabled, while TX delay retains the diff --git a/target/linux/layerscape/patches-5.4/701-net-0328-net-phy-Inphi-IN112525_s03-retimer-support.patch b/target/linux/layerscape/patches-5.4/701-net-0328-net-phy-Inphi-IN112525_s03-retimer-support.patch deleted file mode 100644 index dcb6071e28..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0328-net-phy-Inphi-IN112525_s03-retimer-support.patch +++ /dev/null @@ -1,620 +0,0 @@ -From 630ee8f358d961a7c8295d60a112e27cbfe4478d Mon Sep 17 00:00:00 2001 -From: Florin Chiculita -Date: Fri, 9 Nov 2018 06:20:36 +0200 -Subject: [PATCH] net/phy: Inphi IN112525_s03 retimer support - -Software controller for IN112525_s03 retimer - -Signed-off-by: Florin Chiculita ---- - drivers/net/phy/Kconfig | 5 + - drivers/net/phy/Makefile | 1 + - drivers/net/phy/inphi.c | 578 +++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 584 insertions(+) - create mode 100644 drivers/net/phy/inphi.c - ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -471,6 +471,11 @@ config ICPLUS_PHY - ---help--- - Currently supports the IP175C and IP1001 PHYs. - -+config INPHI_PHY -+ tristate "Inphi CDR 10G/25G Ethernet PHY" -+ ---help--- -+ Currently supports the IN112525_S03 part @ 25G -+ - config INTEL_XWAY_PHY - tristate "Intel XWAY PHYs" - ---help--- ---- a/drivers/net/phy/Makefile -+++ b/drivers/net/phy/Makefile -@@ -86,6 +86,7 @@ obj-$(CONFIG_DP83848_PHY) += dp83848.o - obj-$(CONFIG_DP83867_PHY) += dp83867.o - obj-$(CONFIG_FIXED_PHY) += fixed_phy.o - obj-$(CONFIG_ICPLUS_PHY) += icplus.o -+obj-$(CONFIG_INPHI_PHY) += inphi.o - obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o - obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o - obj-$(CONFIG_LXT_PHY) += lxt.o ---- /dev/null -+++ b/drivers/net/phy/inphi.c -@@ -0,0 +1,578 @@ -+/* -+ * Copyright 2018 NXP -+ * Copyright 2018 INPHI -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -+ * POSSIBILITY OF SUCH DAMAGE. -+ * -+ * Inphi is a registered trademark of Inphi Corporation -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define PHY_ID_IN112525 0x02107440 -+ -+#define INPHI_S03_DEVICE_ID_MSB 0x2 -+#define INPHI_S03_DEVICE_ID_LSB 0x3 -+ -+#define ALL_LANES 4 -+#define INPHI_POLL_DELAY 2500 -+ -+#define PHYCTRL_REG1 0x0012 -+#define PHYCTRL_REG2 0x0014 -+#define PHYCTRL_REG3 0x0120 -+#define PHYCTRL_REG4 0x0121 -+#define PHYCTRL_REG5 0x0180 -+#define PHYCTRL_REG6 0x0580 -+#define PHYCTRL_REG7 0x05C4 -+#define PHYCTRL_REG8 0x01C8 -+#define PHYCTRL_REG9 0x0521 -+ -+#define PHYSTAT_REG1 0x0021 -+#define PHYSTAT_REG2 0x0022 -+#define PHYSTAT_REG3 0x0123 -+ -+#define PHYMISC_REG1 0x0025 -+#define PHYMISC_REG2 0x002c -+#define PHYMISC_REG3 0x00b3 -+#define PHYMISC_REG4 0x0181 -+#define PHYMISC_REG5 0x019D -+#define PHYMISC_REG6 0x0198 -+#define PHYMISC_REG7 0x0199 -+#define PHYMISC_REG8 0x0581 -+#define PHYMISC_REG9 0x0598 -+#define PHYMISC_REG10 0x059c -+#define PHYMISC_REG20 0x01B0 -+#define PHYMISC_REG21 0x01BC -+#define PHYMISC_REG22 0x01C0 -+ -+#define RX_VCO_CODE_OFFSET 5 -+ -+#define mdio_wr(a, b) phy_write_mmd(inphi_phydev, MDIO_MMD_VEND1, (a), (b)) -+#define mdio_rd(a) phy_read_mmd(inphi_phydev, MDIO_MMD_VEND1, (a)) -+ -+#define VCO_CODE 390 -+ -+int vco_codes[ALL_LANES] = { -+ VCO_CODE, -+ VCO_CODE, -+ VCO_CODE, -+ VCO_CODE -+}; -+ -+static void mykmod_work_handler(struct work_struct *w); -+ -+static struct workqueue_struct *wq; -+static DECLARE_DELAYED_WORK(mykmod_work, mykmod_work_handler); -+static unsigned long onesec; -+struct phy_device *inphi_phydev; -+ -+int bit_test(int value, int bit_field) -+{ -+ int result; -+ int bit_mask = (1 << bit_field); -+ -+ result = ((value & bit_mask) == bit_mask); -+ return result; -+} -+ -+int tx_pll_lock_test(int lane) -+{ -+ int i, val, locked = 1; -+ -+ if (lane == ALL_LANES) { -+ for (i = 0; i < ALL_LANES; i++) { -+ val = mdio_rd(i * 0x100 + PHYSTAT_REG3); -+ locked = locked & bit_test(val, 15); -+ } -+ } else { -+ val = mdio_rd(lane * 0x100 + PHYSTAT_REG3); -+ locked = locked & bit_test(val, 15); -+ } -+ -+ return locked; -+} -+ -+void rx_reset_assert(int lane) -+{ -+ int mask, val; -+ -+ if (lane == ALL_LANES) { -+ val = mdio_rd(PHYMISC_REG2); -+ mask = (1 << 15); -+ mdio_wr(PHYMISC_REG2, val + mask); -+ } else { -+ val = mdio_rd(lane * 0x100 + PHYCTRL_REG8); -+ mask = (1 << 6); -+ mdio_wr(lane * 0x100 + PHYCTRL_REG8, val + mask); -+ } -+} -+ -+void rx_reset_de_assert(int lane) -+{ -+ int mask, val; -+ -+ if (lane == ALL_LANES) { -+ val = mdio_rd(PHYMISC_REG2); -+ mask = 0xffff - (1 << 15); -+ mdio_wr(PHYMISC_REG2, val & mask); -+ } else { -+ val = mdio_rd(lane * 0x100 + PHYCTRL_REG8); -+ mask = 0xffff - (1 << 6); -+ mdio_wr(lane * 0x100 + PHYCTRL_REG8, val & mask); -+ } -+} -+ -+void rx_powerdown_assert(int lane) -+{ -+ int mask, val; -+ -+ val = mdio_rd(lane * 0x100 + PHYCTRL_REG8); -+ mask = (1 << 5); -+ mdio_wr(lane * 0x100 + PHYCTRL_REG8, val + mask); -+} -+ -+void rx_powerdown_de_assert(int lane) -+{ -+ int mask, val; -+ -+ val = mdio_rd(lane * 0x100 + PHYCTRL_REG8); -+ mask = 0xffff - (1 << 5); -+ mdio_wr(lane * 0x100 + PHYCTRL_REG8, val & mask); -+} -+ -+void tx_pll_assert(int lane) -+{ -+ int val, recal; -+ -+ if (lane == ALL_LANES) { -+ val = mdio_rd(PHYMISC_REG2); -+ recal = (1 << 12); -+ mdio_wr(PHYMISC_REG2, val | recal); -+ } else { -+ val = mdio_rd(lane * 0x100 + PHYCTRL_REG4); -+ recal = (1 << 15); -+ mdio_wr(lane * 0x100 + PHYCTRL_REG4, val | recal); -+ } -+} -+ -+void tx_pll_de_assert(int lane) -+{ -+ int recal, val; -+ -+ if (lane == ALL_LANES) { -+ val = mdio_rd(PHYMISC_REG2); -+ recal = 0xefff; -+ mdio_wr(PHYMISC_REG2, val & recal); -+ } else { -+ val = mdio_rd(lane * 0x100 + PHYCTRL_REG4); -+ recal = 0x7fff; -+ mdio_wr(lane * 0x100 + PHYCTRL_REG4, val & recal); -+ } -+} -+ -+void tx_core_assert(int lane) -+{ -+ int recal, val, val2, core_reset; -+ -+ if (lane == 4) { -+ val = mdio_rd(PHYMISC_REG2); -+ recal = 1 << 10; -+ mdio_wr(PHYMISC_REG2, val | recal); -+ } else { -+ val2 = mdio_rd(PHYMISC_REG3); -+ core_reset = (1 << (lane + 8)); -+ mdio_wr(PHYMISC_REG3, val2 | core_reset); -+ } -+} -+ -+void lol_disable(int lane) -+{ -+ int val, mask; -+ -+ val = mdio_rd(PHYMISC_REG3); -+ mask = 1 << (lane + 4); -+ mdio_wr(PHYMISC_REG3, val | mask); -+} -+ -+void tx_core_de_assert(int lane) -+{ -+ int val, recal, val2, core_reset; -+ -+ if (lane == ALL_LANES) { -+ val = mdio_rd(PHYMISC_REG2); -+ recal = 0xffff - (1 << 10); -+ mdio_wr(PHYMISC_REG2, val & recal); -+ } else { -+ val2 = mdio_rd(PHYMISC_REG3); -+ core_reset = 0xffff - (1 << (lane + 8)); -+ mdio_wr(PHYMISC_REG3, val2 & core_reset); -+ } -+} -+ -+void tx_restart(int lane) -+{ -+ tx_core_assert(lane); -+ tx_pll_assert(lane); -+ tx_pll_de_assert(lane); -+ usleep_range(1500, 1600); -+ tx_core_de_assert(lane); -+} -+ -+void disable_lane(int lane) -+{ -+ rx_reset_assert(lane); -+ rx_powerdown_assert(lane); -+ tx_core_assert(lane); -+ lol_disable(lane); -+} -+ -+void toggle_reset(int lane) -+{ -+ int reg, val, orig; -+ -+ if (lane == ALL_LANES) { -+ mdio_wr(PHYMISC_REG2, 0x8000); -+ udelay(100); -+ mdio_wr(PHYMISC_REG2, 0x0000); -+ } else { -+ reg = lane * 0x100 + PHYCTRL_REG8; -+ val = (1 << 6); -+ orig = mdio_rd(reg); -+ mdio_wr(reg, orig + val); -+ udelay(100); -+ mdio_wr(reg, orig); -+ } -+} -+ -+int az_complete_test(int lane) -+{ -+ int success = 1, value; -+ -+ if (lane == 0 || lane == ALL_LANES) { -+ value = mdio_rd(PHYCTRL_REG5); -+ success = success & bit_test(value, 2); -+ } -+ if (lane == 1 || lane == ALL_LANES) { -+ value = mdio_rd(PHYCTRL_REG5 + 0x100); -+ success = success & bit_test(value, 2); -+ } -+ if (lane == 2 || lane == ALL_LANES) { -+ value = mdio_rd(PHYCTRL_REG5 + 0x200); -+ success = success & bit_test(value, 2); -+ } -+ if (lane == 3 || lane == ALL_LANES) { -+ value = mdio_rd(PHYCTRL_REG5 + 0x300); -+ success = success & bit_test(value, 2); -+ } -+ -+ return success; -+} -+ -+void save_az_offsets(int lane) -+{ -+ int i; -+ -+#define AZ_OFFSET_LANE_UPDATE(reg, lane) \ -+ mdio_wr((reg) + (lane) * 0x100, \ -+ (mdio_rd((reg) + (lane) * 0x100) >> 8)) -+ -+ if (lane == ALL_LANES) { -+ for (i = 0; i < ALL_LANES; i++) { -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG20, i); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG20 + 1, i); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG20 + 2, i); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG20 + 3, i); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG21, i); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG21 + 1, i); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG21 + 2, i); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG21 + 3, i); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG22, i); -+ } -+ } else { -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG20, lane); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG20 + 1, lane); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG20 + 2, lane); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG20 + 3, lane); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG21, lane); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG21 + 1, lane); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG21 + 2, lane); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG21 + 3, lane); -+ AZ_OFFSET_LANE_UPDATE(PHYMISC_REG22, lane); -+ } -+ -+ mdio_wr(PHYCTRL_REG7, 0x0001); -+} -+ -+void save_vco_codes(int lane) -+{ -+ int i; -+ -+ if (lane == ALL_LANES) { -+ for (i = 0; i < ALL_LANES; i++) { -+ vco_codes[i] = mdio_rd(PHYMISC_REG5 + i * 0x100); -+ mdio_wr(PHYMISC_REG5 + i * 0x100, -+ vco_codes[i] + RX_VCO_CODE_OFFSET); -+ } -+ } else { -+ vco_codes[lane] = mdio_rd(PHYMISC_REG5 + lane * 0x100); -+ mdio_wr(PHYMISC_REG5 + lane * 0x100, -+ vco_codes[lane] + RX_VCO_CODE_OFFSET); -+ } -+} -+ -+int inphi_lane_recovery(int lane) -+{ -+ int i, value, az_pass; -+ -+ switch (lane) { -+ case 0: -+ case 1: -+ case 2: -+ case 3: -+ rx_reset_assert(lane); -+ mdelay(20); -+ break; -+ case ALL_LANES: -+ mdio_wr(PHYMISC_REG2, 0x9C00); -+ mdelay(20); -+ do { -+ value = mdio_rd(PHYMISC_REG2); -+ udelay(10); -+ } while (!bit_test(value, 4)); -+ break; -+ default: -+ dev_err(&inphi_phydev->mdio.dev, -+ "Incorrect usage of APIs in %s driver\n", -+ inphi_phydev->drv->name); -+ break; -+ } -+ -+ if (lane == ALL_LANES) { -+ for (i = 0; i < ALL_LANES; i++) -+ mdio_wr(PHYMISC_REG7 + i * 0x100, VCO_CODE); -+ } else { -+ mdio_wr(PHYMISC_REG7 + lane * 0x100, VCO_CODE); -+ } -+ -+ if (lane == ALL_LANES) -+ for (i = 0; i < ALL_LANES; i++) -+ mdio_wr(PHYCTRL_REG5 + i * 0x100, 0x0418); -+ else -+ mdio_wr(PHYCTRL_REG5 + lane * 0x100, 0x0418); -+ -+ mdio_wr(PHYCTRL_REG7, 0x0000); -+ -+ rx_reset_de_assert(lane); -+ -+ if (lane == ALL_LANES) { -+ for (i = 0; i < ALL_LANES; i++) { -+ mdio_wr(PHYCTRL_REG5 + i * 0x100, 0x0410); -+ mdio_wr(PHYCTRL_REG5 + i * 0x100, 0x0412); -+ } -+ } else { -+ mdio_wr(PHYCTRL_REG5 + lane * 0x100, 0x0410); -+ mdio_wr(PHYCTRL_REG5 + lane * 0x100, 0x0412); -+ } -+ -+ for (i = 0; i < 64; i++) { -+ mdelay(100); -+ az_pass = az_complete_test(lane); -+ if (az_pass) { -+ save_az_offsets(lane); -+ break; -+ } -+ } -+ -+ if (!az_pass) { -+ pr_info("in112525: AZ calibration fail @ lane=%d\n", lane); -+ return -1; -+ } -+ -+ if (lane == ALL_LANES) { -+ mdio_wr(PHYMISC_REG8, 0x0002); -+ mdio_wr(PHYMISC_REG9, 0x2028); -+ mdio_wr(PHYCTRL_REG6, 0x0010); -+ usleep_range(1000, 1200); -+ mdio_wr(PHYCTRL_REG6, 0x0110); -+ mdelay(30); -+ mdio_wr(PHYMISC_REG9, 0x3020); -+ } else { -+ mdio_wr(PHYMISC_REG4 + lane * 0x100, 0x0002); -+ mdio_wr(PHYMISC_REG6 + lane * 0x100, 0x2028); -+ mdio_wr(PHYCTRL_REG5 + lane * 0x100, 0x0010); -+ usleep_range(1000, 1200); -+ mdio_wr(PHYCTRL_REG5 + lane * 0x100, 0x0110); -+ mdelay(30); -+ mdio_wr(PHYMISC_REG6 + lane * 0x100, 0x3020); -+ } -+ -+ if (lane == ALL_LANES) { -+ mdio_wr(PHYMISC_REG2, 0x1C00); -+ mdio_wr(PHYMISC_REG2, 0x0C00); -+ } else { -+ tx_restart(lane); -+ mdelay(11); -+ } -+ -+ if (lane == ALL_LANES) { -+ if (bit_test(mdio_rd(PHYMISC_REG2), 6) == 0) -+ return -1; -+ } else { -+ if (tx_pll_lock_test(lane) == 0) -+ return -1; -+ } -+ -+ save_vco_codes(lane); -+ -+ if (lane == ALL_LANES) { -+ mdio_wr(PHYMISC_REG2, 0x0400); -+ mdio_wr(PHYMISC_REG2, 0x0000); -+ value = mdio_rd(PHYCTRL_REG1); -+ value = value & 0xffbf; -+ mdio_wr(PHYCTRL_REG2, value); -+ } else { -+ tx_core_de_assert(lane); -+ } -+ -+ if (lane == ALL_LANES) { -+ mdio_wr(PHYMISC_REG1, 0x8000); -+ mdio_wr(PHYMISC_REG1, 0x0000); -+ } -+ mdio_rd(PHYMISC_REG1); -+ mdio_rd(PHYMISC_REG1); -+ usleep_range(1000, 1200); -+ mdio_rd(PHYSTAT_REG1); -+ mdio_rd(PHYSTAT_REG2); -+ -+ return 0; -+} -+ -+static void mykmod_work_handler(struct work_struct *w) -+{ -+ int all_lanes_lock, lane0_lock, lane1_lock, lane2_lock, lane3_lock; -+ -+ lane0_lock = bit_test(mdio_rd(0x123), 15); -+ lane1_lock = bit_test(mdio_rd(0x223), 15); -+ lane2_lock = bit_test(mdio_rd(0x323), 15); -+ lane3_lock = bit_test(mdio_rd(0x423), 15); -+ -+ /* check if the chip had any successful lane lock from the previous -+ * stage (e.g. u-boot) -+ */ -+ all_lanes_lock = lane0_lock | lane1_lock | lane2_lock | lane3_lock; -+ -+ if (!all_lanes_lock) { -+ /* start fresh */ -+ inphi_lane_recovery(ALL_LANES); -+ } else { -+ if (!lane0_lock) -+ inphi_lane_recovery(0); -+ if (!lane1_lock) -+ inphi_lane_recovery(1); -+ if (!lane2_lock) -+ inphi_lane_recovery(2); -+ if (!lane3_lock) -+ inphi_lane_recovery(3); -+ } -+ -+ queue_delayed_work(wq, &mykmod_work, onesec); -+} -+ -+int inphi_probe(struct phy_device *phydev) -+{ -+ int phy_id = 0, id_lsb = 0, id_msb = 0; -+ -+ /* Read device id from phy registers */ -+ id_lsb = phy_read_mmd(phydev, MDIO_MMD_VEND1, INPHI_S03_DEVICE_ID_MSB); -+ if (id_lsb < 0) -+ return -ENXIO; -+ -+ phy_id = id_lsb << 16; -+ -+ id_msb = phy_read_mmd(phydev, MDIO_MMD_VEND1, INPHI_S03_DEVICE_ID_LSB); -+ if (id_msb < 0) -+ return -ENXIO; -+ -+ phy_id |= id_msb; -+ -+ /* Make sure the device tree binding matched the driver with the -+ * right device. -+ */ -+ if (phy_id != phydev->drv->phy_id) { -+ dev_err(&phydev->mdio.dev, -+ "Error matching phy with %s driver\n", -+ phydev->drv->name); -+ return -ENODEV; -+ } -+ -+ /* update the local phydev pointer, used inside all APIs */ -+ inphi_phydev = phydev; -+ onesec = msecs_to_jiffies(INPHI_POLL_DELAY); -+ -+ wq = create_singlethread_workqueue("inphi_kmod"); -+ if (wq) { -+ queue_delayed_work(wq, &mykmod_work, onesec); -+ } else { -+ dev_err(&phydev->mdio.dev, -+ "Error creating kernel workqueue for %s driver\n", -+ phydev->drv->name); -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+static struct phy_driver inphi_driver[] = { -+{ -+ .phy_id = PHY_ID_IN112525, -+ .phy_id_mask = 0x0ff0fff0, -+ .name = "Inphi 112525_S03", -+ .features = PHY_GBIT_FEATURES, -+ .probe = &inphi_probe, -+}, -+}; -+ -+module_phy_driver(inphi_driver); -+ -+static struct mdio_device_id __maybe_unused inphi_tbl[] = { -+ { PHY_ID_IN112525, 0x0ff0fff0}, -+ {}, -+}; -+ -+MODULE_DEVICE_TABLE(mdio, inphi_tbl); diff --git a/target/linux/layerscape/patches-5.4/701-net-0329-net-phy-Inphi-IN112525_s03-retimer-updates.patch b/target/linux/layerscape/patches-5.4/701-net-0329-net-phy-Inphi-IN112525_s03-retimer-updates.patch deleted file mode 100644 index 2f38fd0736..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0329-net-phy-Inphi-IN112525_s03-retimer-updates.patch +++ /dev/null @@ -1,74 +0,0 @@ -From a1b049babfd0ae224179dc82ec69cb9bbf585699 Mon Sep 17 00:00:00 2001 -From: Florin Chiculita -Date: Sun, 16 Dec 2018 22:35:44 +0200 -Subject: [PATCH] net/phy: Inphi IN112525_s03 retimer updates - -The retimer doesn't get probed in linux due to the fact that it's a -non-standard clause-45 device. Hardcoding the phyid in device-tree -and adding custom routines for registry read/write operations -solves the issue. - -Signed-off-by: Florin Chiculita ---- - drivers/net/phy/inphi.c | 30 +++++++++++++++++++++++------- - 1 file changed, 23 insertions(+), 7 deletions(-) - ---- a/drivers/net/phy/inphi.c -+++ b/drivers/net/phy/inphi.c -@@ -82,11 +82,7 @@ - #define PHYMISC_REG22 0x01C0 - - #define RX_VCO_CODE_OFFSET 5 -- --#define mdio_wr(a, b) phy_write_mmd(inphi_phydev, MDIO_MMD_VEND1, (a), (b)) --#define mdio_rd(a) phy_read_mmd(inphi_phydev, MDIO_MMD_VEND1, (a)) -- --#define VCO_CODE 390 -+#define VCO_CODE 390 - - int vco_codes[ALL_LANES] = { - VCO_CODE, -@@ -102,6 +98,23 @@ static DECLARE_DELAYED_WORK(mykmod_work, - static unsigned long onesec; - struct phy_device *inphi_phydev; - -+static int mdio_wr(u32 regnum, u16 val) -+{ -+ regnum = MII_ADDR_C45 | (MDIO_MMD_VEND1 << 16) | (regnum & 0xffff); -+ -+ return mdiobus_write(inphi_phydev->mdio.bus, inphi_phydev->mdio.addr, -+ regnum, val); -+} -+ -+static int mdio_rd(u32 regnum) -+{ -+ regnum = MII_ADDR_C45 | (MDIO_MMD_VEND1 << 16) | (regnum & 0xffff); -+ -+ return mdiobus_read(inphi_phydev->mdio.bus, inphi_phydev->mdio.addr, -+ regnum); -+} -+ -+ - int bit_test(int value, int bit_field) - { - int result; -@@ -518,14 +531,17 @@ int inphi_probe(struct phy_device *phyde - { - int phy_id = 0, id_lsb = 0, id_msb = 0; - -+ /* setup the inphi_phydev ptr for mdio_rd/mdio_wr APIs */ -+ inphi_phydev = phydev; -+ - /* Read device id from phy registers */ -- id_lsb = phy_read_mmd(phydev, MDIO_MMD_VEND1, INPHI_S03_DEVICE_ID_MSB); -+ id_lsb = mdio_rd(INPHI_S03_DEVICE_ID_MSB); - if (id_lsb < 0) - return -ENXIO; - - phy_id = id_lsb << 16; - -- id_msb = phy_read_mmd(phydev, MDIO_MMD_VEND1, INPHI_S03_DEVICE_ID_LSB); -+ id_msb = mdio_rd(INPHI_S03_DEVICE_ID_LSB); - if (id_msb < 0) - return -ENXIO; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0330-net-phy-at803x-add-vddio-1v8-and-eee-disable-support.patch b/target/linux/layerscape/patches-5.4/701-net-0330-net-phy-at803x-add-vddio-1v8-and-eee-disable-support.patch deleted file mode 100644 index 7ae1ba3333..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0330-net-phy-at803x-add-vddio-1v8-and-eee-disable-support.patch +++ /dev/null @@ -1,140 +0,0 @@ -From e54e051c0adbe86116ab81c09a208f3a62c84f92 Mon Sep 17 00:00:00 2001 -From: Fugang Duan -Date: Wed, 5 Jun 2019 18:38:51 +0800 -Subject: [PATCH] net: phy: at803x: add vddio-1v8 and eee disable support - -Add new property "at803x,vddio-1p8v" and "at803x,eee-disabled" -support. - -Signed-off-by: Fugang Duan -[ Aisheng: fix small merge conflict ] -Signed-off-by: Dong Aisheng -[rebase] -Signed-off-by: Yangbo Lu ---- - drivers/net/phy/at803x.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 64 insertions(+) - ---- a/drivers/net/phy/at803x.c -+++ b/drivers/net/phy/at803x.c -@@ -44,8 +44,13 @@ - #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C - #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B - #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A -+#define AT803X_SMARTEEE_CTL3_OFFSET 0x805D -+#define AT803X_MMD_ACCESS_CONTROL 0x0D -+#define AT803X_MMD_ACCESS_CONTROL_DATA 0x0E -+#define AT803X_FUNC_DATA 0x4003 - #define AT803X_REG_CHIP_CONFIG 0x1f - #define AT803X_BT_BX_REG_SEL 0x8000 -+#define AT803X_SMARTEEE_DISABLED_VAL 0x1000 - - #define AT803X_DEBUG_ADDR 0x1D - #define AT803X_DEBUG_DATA 0x1E -@@ -64,6 +69,9 @@ - - #define AT803X_LPI_EN BIT(8) - -+#define AT803X_DEBUG_REG_31 0x1f -+#define AT803X_VDDIO_1P8V_EN 0x8 -+ - #define ATH8030_PHY_ID 0x004dd076 - #define ATH8031_PHY_ID 0x004dd074 - #define ATH8032_PHY_ID 0x004dd023 -@@ -74,12 +82,16 @@ - #define AT803X_PAGE_FIBER 0 - #define AT803X_PAGE_COPPER 1 - -+#define AT803X_EEE_FEATURE_DISABLE (1 << 1) -+#define AT803X_VDDIO_1P8V (1 << 2) -+ - MODULE_DESCRIPTION("Atheros 803x PHY driver"); - MODULE_AUTHOR("Matus Ujhelyi"); - MODULE_LICENSE("GPL"); - - struct at803x_priv { - bool phy_reset:1; -+ u32 quirks; - }; - - struct at803x_context { -@@ -172,6 +184,39 @@ static int at803x_disable_tx_delay(struc - AT803X_DEBUG_TX_CLK_DLY_EN, 0); - } - -+static inline int at803x_set_vddio_1p8v(struct phy_device *phydev) -+{ -+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_31, 0, -+ AT803X_VDDIO_1P8V_EN); -+} -+ -+static int at803x_disable_eee(struct phy_device *phydev) -+{ -+ int ret; -+ -+ ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL, -+ AT803X_DEVICE_ADDR); -+ if (ret < 0) -+ return ret; -+ -+ ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA, -+ AT803X_SMARTEEE_CTL3_OFFSET); -+ if (ret < 0) -+ return ret; -+ -+ ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL, -+ AT803X_FUNC_DATA); -+ if (ret < 0) -+ return ret; -+ -+ ret = phy_write(phydev, AT803X_MMD_ACCESS_CONTROL_DATA, -+ AT803X_SMARTEEE_DISABLED_VAL); -+ if (ret < 0) -+ return ret; -+ -+ return 0; -+} -+ - /* save relevant PHY registers to private copy */ - static void at803x_context_save(struct phy_device *phydev, - struct at803x_context *context) -@@ -286,6 +331,12 @@ static int at803x_probe(struct phy_devic - if (!priv) - return -ENOMEM; - -+ if (of_property_read_bool(dev->of_node, "at803x,eee-disabled")) -+ priv->quirks |= AT803X_EEE_FEATURE_DISABLE; -+ -+ if (of_property_read_bool(dev->of_node, "at803x,vddio-1p8v")) -+ priv->quirks |= AT803X_VDDIO_1P8V; -+ - phydev->priv = priv; - - /* Some bootloaders leave the fiber page selected. -@@ -316,6 +367,7 @@ static void at803x_enable_smart_eee(stru - - static int at803x_config_init(struct phy_device *phydev) - { -+ struct at803x_priv *priv = phydev->priv; - int ret; - - -@@ -344,6 +396,18 @@ static int at803x_config_init(struct phy - else - ret = at803x_disable_tx_delay(phydev); - -+ if (priv->quirks & AT803X_VDDIO_1P8V) { -+ ret = at803x_set_vddio_1p8v(phydev); -+ if (ret < 0) -+ return ret; -+ } -+ -+ if (priv->quirks & AT803X_EEE_FEATURE_DISABLE) { -+ ret = at803x_disable_eee(phydev); -+ if (ret < 0) -+ return ret; -+ } -+ - return ret; - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0331-drivers-net-phy-aquantia-enable-AQR112-and-AQR412.patch b/target/linux/layerscape/patches-5.4/701-net-0331-drivers-net-phy-aquantia-enable-AQR112-and-AQR412.patch deleted file mode 100644 index 9140382e5c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0331-drivers-net-phy-aquantia-enable-AQR112-and-AQR412.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 5f62951fba63a9f9cfff564209426bdea5fcc371 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 27 Aug 2019 15:16:56 +0300 -Subject: [PATCH] drivers: net: phy: aquantia: enable AQR112 and AQR412 - -Adds support for AQR112 and AQR412 which is mostly based on existing code -with the addition of code configuring the protocol on system side. -This allows changing the system side protocol without having to deploy a -different firmware on the PHY. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/aquantia_main.c | 88 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 88 insertions(+) - ---- a/drivers/net/phy/aquantia_main.c -+++ b/drivers/net/phy/aquantia_main.c -@@ -22,6 +22,8 @@ - #define PHY_ID_AQR107 0x03a1b4e0 - #define PHY_ID_AQCS109 0x03a1b5c2 - #define PHY_ID_AQR405 0x03a1b4b0 -+#define PHY_ID_AQR112 0x03a1b662 -+#define PHY_ID_AQR412 0x03a1b712 - - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) -@@ -121,6 +123,29 @@ - #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1) - #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0) - -+/* registers in MDIO_MMD_VEND1 region */ -+#define AQUANTIA_VND1_GLOBAL_SC 0x000 -+#define AQUANTIA_VND1_GLOBAL_SC_LP BIT(0xb) -+ -+/* global start rate, the protocol associated with this speed is used by default -+ * on SI. -+ */ -+#define AQUANTIA_VND1_GSTART_RATE 0x31a -+#define AQUANTIA_VND1_GSTART_RATE_OFF 0 -+#define AQUANTIA_VND1_GSTART_RATE_100M 1 -+#define AQUANTIA_VND1_GSTART_RATE_1G 2 -+#define AQUANTIA_VND1_GSTART_RATE_10G 3 -+#define AQUANTIA_VND1_GSTART_RATE_2_5G 4 -+#define AQUANTIA_VND1_GSTART_RATE_5G 5 -+ -+/* SYSCFG registers for 100M, 1G, 2.5G, 5G, 10G */ -+#define AQUANTIA_VND1_GSYSCFG_BASE 0x31b -+#define AQUANTIA_VND1_GSYSCFG_100M 0 -+#define AQUANTIA_VND1_GSYSCFG_1G 1 -+#define AQUANTIA_VND1_GSYSCFG_2_5G 2 -+#define AQUANTIA_VND1_GSYSCFG_5G 3 -+#define AQUANTIA_VND1_GSYSCFG_10G 4 -+ - struct aqr107_hw_stat { - const char *name; - int reg; -@@ -241,6 +266,51 @@ static int aqr_config_aneg(struct phy_de - return genphy_c45_check_and_restart_aneg(phydev, changed); - } - -+static struct { -+ u16 syscfg; -+ int cnt; -+ u16 start_rate; -+} aquantia_syscfg[PHY_INTERFACE_MODE_MAX] = { -+ [PHY_INTERFACE_MODE_SGMII] = {0x04b, AQUANTIA_VND1_GSYSCFG_1G, -+ AQUANTIA_VND1_GSTART_RATE_1G}, -+ [PHY_INTERFACE_MODE_2500BASEX] = {0x144, AQUANTIA_VND1_GSYSCFG_2_5G, -+ AQUANTIA_VND1_GSTART_RATE_2_5G}, -+ [PHY_INTERFACE_MODE_XGMII] = {0x100, AQUANTIA_VND1_GSYSCFG_10G, -+ AQUANTIA_VND1_GSTART_RATE_10G}, -+ [PHY_INTERFACE_MODE_USXGMII] = {0x080, AQUANTIA_VND1_GSYSCFG_10G, -+ AQUANTIA_VND1_GSTART_RATE_10G}, -+}; -+ -+/* Sets up protocol on system side before calling aqr_config_aneg */ -+static int aqr_config_aneg_set_prot(struct phy_device *phydev) -+{ -+ int if_type = phydev->interface; -+ int i; -+ -+ if (!aquantia_syscfg[if_type].cnt) -+ return 0; -+ -+ /* set PHY in low power mode so we can configure protocols */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, -+ AQUANTIA_VND1_GLOBAL_SC_LP); -+ mdelay(10); -+ -+ /* set the default rate to enable the SI link */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE, -+ aquantia_syscfg[if_type].start_rate); -+ -+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, -+ AQUANTIA_VND1_GSYSCFG_BASE + i, -+ aquantia_syscfg[if_type].syscfg); -+ -+ /* wake PHY back up */ -+ phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0); -+ mdelay(10); -+ -+ return aqr_config_aneg(phydev); -+} -+ - static int aqr_config_intr(struct phy_device *phydev) - { - bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED; -@@ -682,6 +752,22 @@ static struct phy_driver aqr_driver[] = - .ack_interrupt = aqr_ack_interrupt, - .read_status = aqr_read_status, - }, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR112), -+ .name = "Aquantia AQR112", -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .ack_interrupt = aqr_ack_interrupt, -+ .read_status = aqr_read_status, -+}, -+{ -+ PHY_ID_MATCH_MODEL(PHY_ID_AQR412), -+ .name = "Aquantia AQR412", -+ .config_aneg = aqr_config_aneg_set_prot, -+ .config_intr = aqr_config_intr, -+ .ack_interrupt = aqr_ack_interrupt, -+ .read_status = aqr_read_status, -+}, - }; - - module_phy_driver(aqr_driver); -@@ -694,6 +780,8 @@ static struct mdio_device_id __maybe_unu - { PHY_ID_MATCH_MODEL(PHY_ID_AQR107) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) }, - { PHY_ID_MATCH_MODEL(PHY_ID_AQR405) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR112) }, -+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR412) }, - { } - }; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0332-drivers-net-phy-aquantia-fix-system-side-protocol-mi.patch b/target/linux/layerscape/patches-5.4/701-net-0332-drivers-net-phy-aquantia-fix-system-side-protocol-mi.patch deleted file mode 100644 index 2c75ec211f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0332-drivers-net-phy-aquantia-fix-system-side-protocol-mi.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 5f008cb22f60da4e10375f22266c1a4e20b1252e Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Fri, 20 Sep 2019 18:22:52 +0300 -Subject: [PATCH] drivers: net: phy: aquantia: fix system side protocol - misconfiguration - -Do not set up protocols for speeds that are not supported by FW. Enabling -these protocols leads to link issues on system side. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/aquantia_main.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/net/phy/aquantia_main.c -+++ b/drivers/net/phy/aquantia_main.c -@@ -299,10 +299,16 @@ static int aqr_config_aneg_set_prot(stru - phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GSTART_RATE, - aquantia_syscfg[if_type].start_rate); - -- for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) -+ for (i = 0; i <= aquantia_syscfg[if_type].cnt; i++) { -+ u16 reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, -+ AQUANTIA_VND1_GSYSCFG_BASE + i); -+ if (!reg) -+ continue; -+ - phy_write_mmd(phydev, MDIO_MMD_VEND1, - AQUANTIA_VND1_GSYSCFG_BASE + i, - aquantia_syscfg[if_type].syscfg); -+ } - - /* wake PHY back up */ - phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0); diff --git a/target/linux/layerscape/patches-5.4/701-net-0333-drivers-net-phy-aquantia-enable-USX-AN-for-USXGMII-p.patch b/target/linux/layerscape/patches-5.4/701-net-0333-drivers-net-phy-aquantia-enable-USX-AN-for-USXGMII-p.patch deleted file mode 100644 index 472dce9f16..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0333-drivers-net-phy-aquantia-enable-USX-AN-for-USXGMII-p.patch +++ /dev/null @@ -1,37 +0,0 @@ -From ca49d3e4820704bfc3d2b48f59238d26a584602d Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Fri, 20 Sep 2019 19:37:19 +0300 -Subject: [PATCH] drivers: net: phy: aquantia: enable USX AN for USXGMII - protocol - -Depending on FW defaults USX AN in AQR PHY must be explicitly enabled when -using USXGMII. Enable it based on interface type. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/aquantia_main.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/net/phy/aquantia_main.c -+++ b/drivers/net/phy/aquantia_main.c -@@ -33,6 +33,9 @@ - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10 - -+#define MDIO_PHYXS_VEND_PROV2 0xC441 -+#define MDIO_PHYXS_VEND_PROV2_USX_AN BIT(3) -+ - #define MDIO_AN_VEND_PROV 0xc400 - #define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) - #define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) -@@ -310,6 +313,10 @@ static int aqr_config_aneg_set_prot(stru - aquantia_syscfg[if_type].syscfg); - } - -+ if (if_type == PHY_INTERFACE_MODE_USXGMII) -+ phy_write_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_PROV2, -+ MDIO_PHYXS_VEND_PROV2_USX_AN); -+ - /* wake PHY back up */ - phy_write_mmd(phydev, MDIO_MMD_VEND1, AQUANTIA_VND1_GLOBAL_SC, 0); - mdelay(10); diff --git a/target/linux/layerscape/patches-5.4/701-net-0334-net-tsn-netlink-interface-for-APP-layer-to-config-TS.patch b/target/linux/layerscape/patches-5.4/701-net-0334-net-tsn-netlink-interface-for-APP-layer-to-config-TS.patch deleted file mode 100644 index 33de677930..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0334-net-tsn-netlink-interface-for-APP-layer-to-config-TS.patch +++ /dev/null @@ -1,5113 +0,0 @@ -From e478ab518612f1a821968e1bb5b08b01b10085b0 Mon Sep 17 00:00:00 2001 -From: Po Liu -Date: Tue, 15 Oct 2019 16:11:40 +0800 -Subject: [PATCH] net:tsn: netlink interface for APP layer to config TSN - capability hardware ports - -This patch provids netlink method to configure the TSN protocols hardwares. -TSN guaranteed packet transport with bounded low latency, low packet delay -variation, and low packet loss by hardware and software methods. - -The three basic components of TSN are: - -1. Time synchronization: This was implement by 8021AS which base on the - IEEE1588 precision Time Protocol. This is configured by the other way - in kernel. - 8021AS not included in this patch. - -2. Scheduling and traffic shaping and per-stream filter policing: - This patch support Qbv/Qci/Qbu/8021CB/Qav etc. - -3. Selection of communication paths: - This patch not support the pure software only TSN protocols(like Qcc) - but hardware related configuration. - -TSN Protocols supports by this patch: Qbv/Qci/Qbu/Credit-base Shaper(Qav). -This patch verified on NXP ls1028ardb board. - -Signed-off-by: Po Liu ---- - include/net/tsn.h | 114 ++ - include/uapi/linux/tsn.h | 1207 +++++++++++++++ - net/Kconfig | 1 + - net/Makefile | 3 + - net/tsn/Kconfig | 15 + - net/tsn/Makefile | 1 + - net/tsn/genl_tsn.c | 3696 ++++++++++++++++++++++++++++++++++++++++++++++ - 7 files changed, 5037 insertions(+) - create mode 100644 include/net/tsn.h - create mode 100644 include/uapi/linux/tsn.h - create mode 100644 net/tsn/Kconfig - create mode 100644 net/tsn/Makefile - create mode 100644 net/tsn/genl_tsn.c - ---- /dev/null -+++ b/include/net/tsn.h -@@ -0,0 +1,114 @@ -+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ -+/* Copyright 2017-2019 NXP */ -+ -+#ifndef __TSN_H__ -+#define __TSN_H__ -+ -+#include -+#include -+ -+enum tsn_notifier_type { -+ TSN_QBV_CONFIGCHANGETIME_ARRIVE = 1, -+}; -+ -+struct tsn_notifier_info { -+ struct net_device *dev; -+ union { -+ struct tsn_qbv_conf qbv_notify; -+ struct tsn_qci_psfp_sgi_conf qci_notify; -+ } ntdata; -+}; -+ -+static inline struct net_device * -+tsn_notifier_info_to_dev(const struct tsn_notifier_info *info) -+{ -+ return info->dev; -+} -+ -+struct tsn_ops { -+ void (*device_init)(struct net_device *ndev); -+ void (*device_deinit)(struct net_device *ndev); -+ u32 (*get_capability)(struct net_device *ndev); -+ /* Qbv standard */ -+ int (*qbv_set)(struct net_device *ndev, struct tsn_qbv_conf *qbvconf); -+ int (*qbv_get)(struct net_device *ndev, struct tsn_qbv_conf *qbvconf); -+ int (*qbv_get_status)(struct net_device *ndev, -+ struct tsn_qbv_status *qbvstat); -+ int (*cb_streamid_set)(struct net_device *ndev, u32 index, -+ bool enable, struct tsn_cb_streamid *sid); -+ int (*cb_streamid_get)(struct net_device *ndev, u32 index, -+ struct tsn_cb_streamid *sid); -+ int (*cb_streamid_counters_get)(struct net_device *ndev, u32 index, -+ struct tsn_cb_streamid_counters *sidcounter); -+ int (*qci_get_maxcap)(struct net_device *ndev, -+ struct tsn_qci_psfp_stream_param *qcicapa); -+ int (*qci_sfi_set)(struct net_device *ndev, u32 index, bool enable, -+ struct tsn_qci_psfp_sfi_conf *sficonf); -+ /* return: 0 stream filter instance not valid -+ * 1 stream filter instance valid -+ * -1 error happened -+ */ -+ int (*qci_sfi_get)(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sfi_conf *sficonf); -+ int (*qci_sfi_counters_get)(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sfi_counters *sficounter); -+ int (*qci_sgi_set)(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sgi_conf *sgiconf); -+ int (*qci_sgi_get)(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sgi_conf *sgiconf); -+ int (*qci_sgi_status_get)(struct net_device *ndev, u16 index, -+ struct tsn_psfp_sgi_status *sgistat); -+ int (*qci_fmi_set)(struct net_device *ndev, u32 index, bool enable, -+ struct tsn_qci_psfp_fmi *fmi); -+ int (*qci_fmi_get)(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_fmi *fmi, -+ struct tsn_qci_psfp_fmi_counters *counters); -+ int (*cbs_set)(struct net_device *ndev, u8 tc, u8 bw); -+ int (*cbs_get)(struct net_device *ndev, u8 tc); -+ /* To set a 8 bits vector shows 8 traffic classes -+ * preemtable(1) or express(0) -+ */ -+ int (*qbu_set)(struct net_device *ndev, u8 ptvector); -+ /* To get port preemtion status */ -+ int (*qbu_get)(struct net_device *ndev, -+ struct tsn_preempt_status *preemptstat); -+ int (*tsd_set)(struct net_device *ndev, struct tsn_tsd *tsd); -+ int (*tsd_get)(struct net_device *ndev, struct tsn_tsd_status *stats); -+ int (*ct_set)(struct net_device *ndev, u8 cut_thru); -+ int (*cbgen_set)(struct net_device *ndev, u32 index, -+ struct tsn_seq_gen_conf *seqgen); -+ int (*cbrec_set)(struct net_device *ndev, u32 index, -+ struct tsn_seq_rec_conf *seqrec); -+ int (*cb_get)(struct net_device *ndev, u32 index, -+ struct tsn_cb_status *c); -+ int (*dscp_set)(struct net_device *ndev, bool enable, -+ const u8 dscp_ix, -+ struct tsn_qos_switch_dscp_conf *c); -+}; -+ -+enum ethdev_type { -+ TSN_SWITCH, -+ TSN_ENDPOINT, -+}; -+ -+#define GROUP_OFFSET_SWITCH 256 -+ -+struct tsn_port { -+ u16 groupid; -+ struct tsn_ops *tsnops; -+ struct net_device *netdev; -+ struct list_head list; -+ enum ethdev_type type; -+ u8 tc_nums; -+ struct tsn_notifier_info nd; -+}; -+ -+struct tsn_port *tsn_get_port(struct net_device *ndev); -+int register_tsn_notifier(struct notifier_block *nb); -+int unregister_tsn_notifier(struct notifier_block *nb); -+int call_tsn_notifiers(unsigned long val, struct net_device *dev, -+ struct tsn_notifier_info *info); -+int tsn_port_register(struct net_device *netdev, -+ struct tsn_ops *tsnops, u16 groupid); -+void tsn_port_unregister(struct net_device *netdev); -+#endif ---- /dev/null -+++ b/include/uapi/linux/tsn.h -@@ -0,0 +1,1207 @@ -+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ -+/* Copyright 2017-2019 NXP */ -+ -+#ifndef __UAPI_GENL_TSN_H -+#define __UAPI_GENL_TSN_H -+ -+#define TSN_GENL_NAME "TSN_GEN_CTRL" -+#define TSN_GENL_VERSION 0x1 -+ -+#define MAX_USER_SIZE 0 -+#define MAX_ATTR_SIZE 3072 -+#define MAX_TOTAL_MSG_SIZE (MAX_USER_SIZE + MAX_ATTR_SIZE) -+#define MAX_ENTRY_SIZE 2048 -+#define MAX_ENTRY_NUMBER 128 -+#define MAX_IFNAME_COUNT 64 -+ -+#define TSN_MULTICAST_GROUP_QBV "qbv" -+#define TSN_MULTICAST_GROUP_QCI "qci" -+ -+/* multicast groups */ -+enum tsn_multicast_groups { -+ TSN_MCGRP_QBV, -+ TSN_MCGRP_QCI, -+ TSN_MCGRP_MAX -+}; -+ -+enum tsn_capability { -+ TSN_CAP_QBV = 0x1, -+ TSN_CAP_QCI = 0x2, -+ TSN_CAP_QBU = 0x4, -+ TSN_CAP_CBS = 0x8, /* Credit-based Shapter Qav */ -+ TSN_CAP_CB = 0x10, /* 8021CB redundancy and replication */ -+ TSN_CAP_TBS = 0x20, /* Time Based schedule */ -+ TSN_CAP_CTH = 0x40, /* cut through */ -+}; -+ -+/* -+ * Commands sent from userspace -+ * Not versioned. New commands should only be inserted at the enum's end -+ * prior to __TSN_CMD_MAX -+ */ -+ -+enum { -+ TSN_CMD_UNSPEC = 0, /* Reserved */ -+ TSN_CMD_QBV_SET, -+ TSN_CMD_QBV_GET, -+ TSN_CMD_QBV_GET_STATUS, -+ TSN_CMD_CB_STREAMID_SET, -+ TSN_CMD_CB_STREAMID_GET, -+ TSN_CMD_CB_STREAMID_GET_COUNTS, -+ TSN_CMD_QCI_CAP_GET, /* Qci capability get length capability get */ -+ TSN_CMD_QCI_SFI_SET, -+ TSN_CMD_QCI_SFI_GET, -+ TSN_CMD_QCI_SFI_GET_COUNTS, -+ TSN_CMD_QCI_SGI_SET, -+ TSN_CMD_QCI_SGI_GET, -+ TSN_CMD_QCI_SGI_GET_STATUS, -+ TSN_CMD_QCI_FMI_SET, -+ TSN_CMD_QCI_FMI_GET, -+ TSN_CMD_CBS_SET, -+ TSN_CMD_CBS_GET, -+ TSN_CMD_QBU_SET, -+ TSN_CMD_QBU_GET_STATUS, -+ TSN_CMD_QAV_SET_CBS, -+ TSN_CMD_QAV_GET_CBS, -+ TSN_CMD_TSD_SET, -+ TSN_CMD_TSD_GET, -+ TSN_CMD_CT_SET, -+ TSN_CMD_CBGEN_SET, -+ TSN_CMD_CBREC_SET, -+ TSN_CMD_CBSTAT_GET, -+ TSN_CMD_PCPMAP_SET_UNUSE, -+ TSN_CMD_DSCP_SET, -+ TSN_CMD_ECHO, /* user->kernel request/get-response */ -+ TSN_CMD_REPLY, /* kernel->user event */ -+ TSN_CMD_CAP_GET, -+ __TSN_CMD_MAX, -+}; -+#define TSN_CMD_MAX (__TSN_CMD_MAX - 1) -+ -+ -+enum { -+ TSN_CMD_ATTR_UNSPEC = 0, -+ TSN_CMD_ATTR_MESG, /* demo message */ -+ TSN_CMD_ATTR_DATA, /* demo data */ -+ TSN_ATTR_IFNAME, -+ TSN_ATTR_PORT_NUMBER, -+ TSN_ATTR_QBV, -+ TSN_ATTR_STREAM_IDENTIFY, /* stream identify */ -+ TSN_ATTR_QCI_SP, /* psfp port capbility parameters */ -+ TSN_ATTR_QCI_SFI, /* psfp stream filter instance */ -+ TSN_ATTR_QCI_SGI, /* psfp stream gate instance */ -+ TSN_ATTR_QCI_FMI, /* psfp flow meter instance */ -+ TSN_ATTR_CBS, /* credit-based shaper */ -+ TSN_ATTR_TSD, /* Time Specific Departure */ -+ TSN_ATTR_QBU, /* preemption */ -+ TSN_ATTR_CT, /* cut through */ -+ TSN_ATTR_CBGEN, /* 802.1CB sequence generate */ -+ TSN_ATTR_CBREC, /* 802.1CB sequence recover */ -+ TSN_ATTR_CBSTAT, /* 802.1CB status */ -+ TSN_ATTR_PCPMAP_UNUSE, -+ TSN_ATTR_DSCP, -+ TSN_ATTR_CAP, /* TSN capbility */ -+ __TSN_CMD_ATTR_MAX, -+}; -+#define TSN_CMD_ATTR_MAX (__TSN_CMD_ATTR_MAX - 1) -+ -+enum { -+ TSN_CAP_ATTR_UNSPEC, -+ TSN_CAP_ATTR_QBV, -+ TSN_CAP_ATTR_QCI, -+ TSN_CAP_ATTR_QBU, -+ TSN_CAP_ATTR_CBS, -+ TSN_CAP_ATTR_CB, -+ TSN_CAP_ATTR_TBS, -+ TSN_CAP_ATTR_CTH, -+ __TSN_CAP_ATTR_MAX, -+ TSN_CAP_ATTR_MAX = __TSN_CAP_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_QBU_ATTR_UNSPEC, -+ TSN_QBU_ATTR_ADMIN_STATE, -+ TSN_QBU_ATTR_HOLD_ADVANCE, -+ TSN_QBU_ATTR_RELEASE_ADVANCE, -+ TSN_QBU_ATTR_ACTIVE, -+ TSN_QBU_ATTR_HOLD_REQUEST, -+ __TSN_QBU_ATTR_MAX, -+ TSN_QBU_ATTR_MAX = __TSN_QBU_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_CBS_ATTR_UNSPEC, -+ TSN_CBS_ATTR_TC_INDEX, -+ TSN_CBS_ATTR_BW, -+ __TSN_CBS_ATTR_MAX, -+ TSN_CBS_ATTR_MAX = __TSN_CBS_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_TSD_ATTR_UNSPEC, -+ TSN_TSD_ATTR_DISABLE, -+ TSN_TSD_ATTR_ENABLE, -+ TSN_TSD_ATTR_PERIOD, -+ TSN_TSD_ATTR_MAX_FRM_NUM, -+ TSN_TSD_ATTR_CYCLE_NUM, -+ TSN_TSD_ATTR_LOSS_STEPS, -+ TSN_TSD_ATTR_SYN_IMME, -+ __TSN_TSD_ATTR_MAX, -+ TSN_TSD_ATTR_MAX = __TSN_TSD_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_STREAMID_ATTR_UNSPEC, -+ TSN_STREAMID_ATTR_INDEX, -+ TSN_STREAMID_ATTR_ENABLE, -+ TSN_STREAMID_ATTR_DISABLE, -+ TSN_STREAMID_ATTR_STREAM_HANDLE, -+ TSN_STREAMID_ATTR_IFOP, -+ TSN_STREAMID_ATTR_OFOP, -+ TSN_STREAMID_ATTR_IFIP, -+ TSN_STREAMID_ATTR_OFIP, -+ TSN_STREAMID_ATTR_TYPE, -+ TSN_STREAMID_ATTR_NDMAC, -+ TSN_STREAMID_ATTR_NTAGGED, -+ TSN_STREAMID_ATTR_NVID, -+ TSN_STREAMID_ATTR_SMAC, -+ TSN_STREAMID_ATTR_STAGGED, -+ TSN_STREAMID_ATTR_SVID, -+ TSN_STREAMID_ATTR_COUNTERS_PSI, -+ TSN_STREAMID_ATTR_COUNTERS_PSO, -+ TSN_STREAMID_ATTR_COUNTERS_PSPPI, -+ TSN_STREAMID_ATTR_COUNTERS_PSPPO, -+ __TSN_STREAMID_ATTR_MAX, -+ TSN_STREAMID_ATTR_MAX = __TSN_STREAMID_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_QCI_STREAM_ATTR_UNSPEC = 0, -+ TSN_QCI_STREAM_ATTR_MAX_SFI, -+ TSN_QCI_STREAM_ATTR_MAX_SGI, -+ TSN_QCI_STREAM_ATTR_MAX_FMI, -+ TSN_QCI_STREAM_ATTR_SLM, -+ __TSN_QCI_STREAM_ATTR_MAX, -+ TSN_QCI_STREAM_ATTR_MAX = __TSN_QCI_STREAM_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_QCI_SFI_ATTR_UNSPEC = 0, -+ TSN_QCI_SFI_ATTR_INDEX, -+ TSN_QCI_SFI_ATTR_ENABLE, -+ TSN_QCI_SFI_ATTR_DISABLE, -+ TSN_QCI_SFI_ATTR_STREAM_HANDLE, -+ TSN_QCI_SFI_ATTR_PRIO_SPEC, -+ TSN_QCI_SFI_ATTR_GATE_ID, -+ TSN_QCI_SFI_ATTR_FILTER_TYPE, -+ TSN_QCI_SFI_ATTR_FLOW_ID, -+ TSN_QCI_SFI_ATTR_MAXSDU, -+ TSN_QCI_SFI_ATTR_COUNTERS, -+ TSN_QCI_SFI_ATTR_OVERSIZE_ENABLE, -+ TSN_QCI_SFI_ATTR_OVERSIZE, -+ __TSN_QCI_SFI_ATTR_MAX, -+ TSN_QCI_SFI_ATTR_MAX = __TSN_QCI_SFI_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_QCI_SFI_ATTR_COUNTERS_UNSPEC = 0, -+ TSN_QCI_SFI_ATTR_MATCH, -+ TSN_QCI_SFI_ATTR_PASS, -+ TSN_QCI_SFI_ATTR_DROP, -+ TSN_QCI_SFI_ATTR_SDU_DROP, -+ TSN_QCI_SFI_ATTR_SDU_PASS, -+ TSN_QCI_SFI_ATTR_RED, -+ __TSN_QCI_SFI_ATTR_COUNT_MAX, -+ TSN_QCI_SFI_ATTR_COUNT_MAX = __TSN_QCI_SFI_ATTR_COUNT_MAX - 1, -+}; -+ -+enum { -+ TSN_QCI_SGI_ATTR_UNSPEC = 0, -+ TSN_QCI_SGI_ATTR_INDEX, -+ TSN_QCI_SGI_ATTR_ENABLE, -+ TSN_QCI_SGI_ATTR_DISABLE, -+ TSN_QCI_SGI_ATTR_CONFCHANGE, -+ TSN_QCI_SGI_ATTR_IRXEN, /* Invalid rx enable*/ -+ TSN_QCI_SGI_ATTR_IRX, -+ TSN_QCI_SGI_ATTR_OEXEN, /* Octet exceed enable */ -+ TSN_QCI_SGI_ATTR_OEX, -+ TSN_QCI_SGI_ATTR_ADMINENTRY, -+ TSN_QCI_SGI_ATTR_OPERENTRY, -+ TSN_QCI_SGI_ATTR_CCTIME, /* config change time */ -+ TSN_QCI_SGI_ATTR_TICKG, -+ TSN_QCI_SGI_ATTR_CUTIME, -+ TSN_QCI_SGI_ATTR_CPENDING, -+ TSN_QCI_SGI_ATTR_CCERROR, -+ __TSN_QCI_SGI_ATTR_MAX, -+ TSN_QCI_SGI_ATTR_MAX = __TSN_QCI_SGI_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_SGI_ATTR_CTRL_UNSPEC = 0, -+ TSN_SGI_ATTR_CTRL_INITSTATE, -+ TSN_SGI_ATTR_CTRL_LEN, -+ TSN_SGI_ATTR_CTRL_CYTIME, -+ TSN_SGI_ATTR_CTRL_CYTIMEEX, -+ TSN_SGI_ATTR_CTRL_BTIME, -+ TSN_SGI_ATTR_CTRL_INITIPV, -+ TSN_SGI_ATTR_CTRL_GCLENTRY, -+ __TSN_SGI_ATTR_CTRL_MAX, -+ TSN_SGI_ATTR_CTRL_MAX = __TSN_SGI_ATTR_CTRL_MAX - 1, -+}; -+ -+enum { -+ TSN_SGI_ATTR_GCL_UNSPEC = 0, -+ TSN_SGI_ATTR_GCL_GATESTATE, -+ TSN_SGI_ATTR_GCL_IPV, -+ TSN_SGI_ATTR_GCL_INTERVAL, -+ TSN_SGI_ATTR_GCL_OCTMAX, -+ __TSN_SGI_ATTR_GCL_MAX, -+ TSN_SGI_ATTR_GCL_MAX = __TSN_SGI_ATTR_GCL_MAX - 1, -+}; -+ -+enum { -+ TSN_QCI_FMI_ATTR_UNSPEC = 0, -+ TSN_QCI_FMI_ATTR_INDEX, -+ TSN_QCI_FMI_ATTR_ENABLE, -+ TSN_QCI_FMI_ATTR_DISABLE, -+ TSN_QCI_FMI_ATTR_CIR, -+ TSN_QCI_FMI_ATTR_CBS, -+ TSN_QCI_FMI_ATTR_EIR, -+ TSN_QCI_FMI_ATTR_EBS, -+ TSN_QCI_FMI_ATTR_CF, -+ TSN_QCI_FMI_ATTR_CM, -+ TSN_QCI_FMI_ATTR_DROPYL, -+ TSN_QCI_FMI_ATTR_MAREDEN, -+ TSN_QCI_FMI_ATTR_MARED, -+ TSN_QCI_FMI_ATTR_COUNTERS, -+ __TSN_QCI_FMI_ATTR_MAX, -+ TSN_QCI_FMI_ATTR_MAX = __TSN_QCI_FMI_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_QBV_ATTR_UNSPEC, -+ TSN_QBV_ATTR_ENABLE, -+ TSN_QBV_ATTR_DISABLE, -+ TSN_QBV_ATTR_CONFIGCHANGE, -+ TSN_QBV_ATTR_CONFIGCHANGETIME, -+ TSN_QBV_ATTR_MAXSDU, -+ TSN_QBV_ATTR_GRANULARITY, -+ TSN_QBV_ATTR_CURRENTTIME, -+ TSN_QBV_ATTR_CONFIGPENDING, -+ TSN_QBV_ATTR_CONFIGCHANGEERROR, -+ TSN_QBV_ATTR_ADMINENTRY, -+ TSN_QBV_ATTR_OPERENTRY, -+ TSN_QBV_ATTR_LISTMAX, -+ __TSN_QBV_ATTR_MAX, -+ TSN_QBV_ATTR_MAX = __TSN_QBV_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_QBV_ATTR_CTRL_UNSPEC, -+ TSN_QBV_ATTR_CTRL_LISTCOUNT, -+ TSN_QBV_ATTR_CTRL_GATESTATE, -+ TSN_QBV_ATTR_CTRL_CYCLETIME, -+ TSN_QBV_ATTR_CTRL_CYCLETIMEEXT, -+ TSN_QBV_ATTR_CTRL_BASETIME, -+ TSN_QBV_ATTR_CTRL_LISTENTRY, -+ __TSN_QBV_ATTR_CTRL_MAX, -+ TSN_QBV_ATTR_CTRL_MAX = __TSN_QBV_ATTR_CTRL_MAX - 1, -+}; -+ -+enum { -+ TSN_QBV_ATTR_ENTRY_UNSPEC, -+ TSN_QBV_ATTR_ENTRY_ID, -+ TSN_QBV_ATTR_ENTRY_GC, -+ TSN_QBV_ATTR_ENTRY_TM, -+ __TSN_QBV_ATTR_ENTRY_MAX, -+ TSN_QBV_ATTR_ENTRY_MAX = __TSN_QBV_ATTR_ENTRY_MAX - 1, -+}; -+ -+enum { -+ TSN_CT_ATTR_UNSPEC, -+ TSN_CT_ATTR_QUEUE_STATE, -+ __TSN_CT_ATTR_MAX, -+ TSN_CT_ATTR_MAX = __TSN_CT_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_CBGEN_ATTR_UNSPEC, -+ TSN_CBGEN_ATTR_INDEX, -+ TSN_CBGEN_ATTR_PORT_MASK, -+ TSN_CBGEN_ATTR_SPLIT_MASK, -+ TSN_CBGEN_ATTR_SEQ_LEN, -+ TSN_CBGEN_ATTR_SEQ_NUM, -+ __TSN_CBGEN_ATTR_MAX, -+ TSN_CBGEN_ATTR_MAX = __TSN_CBGEN_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_CBREC_ATTR_UNSPEC, -+ TSN_CBREC_ATTR_INDEX, -+ TSN_CBREC_ATTR_SEQ_LEN, -+ TSN_CBREC_ATTR_HIS_LEN, -+ TSN_CBREC_ATTR_TAG_POP_EN, -+ __TSN_CBREC_ATTR_MAX, -+ TSN_CBREC_ATTR_MAX = __TSN_CBREC_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_CBSTAT_ATTR_UNSPEC, -+ TSN_CBSTAT_ATTR_INDEX, -+ TSN_CBSTAT_ATTR_GEN_REC, -+ TSN_CBSTAT_ATTR_ERR, -+ TSN_CBSTAT_ATTR_SEQ_NUM, -+ TSN_CBSTAT_ATTR_SEQ_LEN, -+ TSN_CBSTAT_ATTR_SPLIT_MASK, -+ TSN_CBSTAT_ATTR_PORT_MASK, -+ TSN_CBSTAT_ATTR_HIS_LEN, -+ TSN_CBSTAT_ATTR_SEQ_HIS, -+ __TSN_CBSTAT_ATTR_MAX, -+ TSN_CBSTAT_ATTR_MAX = __TSN_CBSTAT_ATTR_MAX - 1, -+}; -+ -+enum { -+ TSN_DSCP_ATTR_UNSPEC, -+ TSN_DSCP_ATTR_DISABLE, -+ TSN_DSCP_ATTR_INDEX, -+ TSN_DSCP_ATTR_COS, -+ TSN_DSCP_ATTR_DPL, -+ __TSN_DSCP_ATTR_MAX, -+ TSN_DSCP_ATTR_MAX = __TSN_DSCP_ATTR_MAX - 1, -+}; -+ -+#define ptptime_t __u64 -+ -+#define MAX_QUEUE_CNT 8 -+ -+struct tsn_preempt_status { -+ /* The value of admin_state shows a 8-bits vector value for showing -+ * the framePreemptionAdminStatus parameter and PreemptionPriority -+ * for the traffic class. Bit-7 is the highest priority traffic class -+ * and the bit-0 is the lowest priority traffic class. -+ * The bit is express (0) and is preemptible (1). -+ */ -+ __u8 admin_state; -+ /* The value of the holdAdvance parameter for the port in nanoseconds. -+ * There is no default value; the holdAdvance is a property of the -+ * underlying MAC." This parameter corresponds to the holdAdvance -+ * parameter in 802.1Qbu. -+ */ -+ __u32 hold_advance; -+ -+ /* The value of the releaseAdvance parameter for the port in -+ * nanoseconds. There is no default value; the releaseAdvance is a -+ * property of the underlying MAC." This parameter corresponds to the -+ * releaseAdvance parameter in 802.1Qbu. -+ */ -+ __u32 release_advance; -+ -+ /* The value is active (TRUE) when preemption is operationally active -+ * for the port, and idle (FALSE) otherwise. This parameter corresponds -+ * to the preemptionActive parameter in 802.1Qbu. -+ */ -+ __u8 preemption_active; -+ -+ /* The value is hold (1) when the sequence of gate operations for -+ * the port has executed a Set-And-Hold-MAC operation, and release -+ * (2) when the sequence of gate operations has executed a -+ * Set-And-Release-MAC operation. The value of this object is release -+ * (FALSE) on system initialization. This parameter corresponds to the -+ * holdRequest parameter in 802.1Qbu. -+ */ -+ __u8 hold_request; -+}; -+ -+enum tsn_tx_mode { -+ TX_MODE_STRICT, -+ TX_MODE_CBS, -+ TX_MODE_ETS, -+ TX_MODE_VENDOR_DEFINE = 255, -+}; -+ -+#define QUEUE_TX_MASK ((1 << TX_MODE_STRICT) | (1 << TX_MODE_CBS) \ -+ | (1 << TX_MODE_ETS) | (1 << TX_MODE_VENDOR_DEFINE)) -+ -+struct cbs_status { -+ __u8 delta_bw; /* percentage, 0~100 */ -+ __u32 idleslope; -+ __s32 sendslope; -+ __u32 maxframesize; -+ __u32 hicredit; -+ __s32 locredit; -+ __u32 maxninference; -+}; -+ -+struct tx_queue { -+ /* tx_queue_capbility shows the queue's capability mask. -+ * refer the enum tsn_tx_mode -+ */ -+ __u8 capability; -+ -+ /* tx_queue_mode is current queue working mode */ -+ __u8 mode; -+ -+ /* prio is showing the queue priority */ -+ __u8 prio; -+ -+ /* mstat shows the status data of cbs or priority */ -+ union { -+ struct cbs_status cbs; -+ }; -+}; -+ -+struct port_status { -+ /* txqueue_cnt shows how many queues in this port */ -+ __u8 queue_cnt; -+ -+ /* max_rate(Mbit/s) is the port transmit rate current port is setting */ -+ __u32 max_rate; -+ -+ /* tsn_capability mask the tsn capability */ -+ __u32 tsn_capability; -+}; -+ -+enum tsn_cb_streamid_type { -+ STREAMID_RESERVED = 0, -+ /* Null Stream identification */ -+ STREAMID_NULL, -+ /* Source MAC and VLAN Stream identification */ -+ STREAMID_SMAC_VLAN, -+ /* Active Destination MAC and VLAN stream identification */ -+ STREAMID_DMAC_VLAN, -+ /* IP stream identification */ -+ STREAMID_IP, -+}; -+ -+/* When instantiating an instance of the Null Stream identification function -+ * 8021CB(6.4) for a particular input Stream, the managed objects in the -+ * following subsections serve as the tsnStreamIdParameters managed object -+ * 8021CB claus(9.1.1.7). -+ */ -+struct tsn_cb_null_streamid { -+ /* tsnCpeNullDownDestMac. Specifies the destination_address that -+ * identifies a packet in an Enhanced Internal Sublayer Service (EISS) -+ * indication primitive, to the Null Stream identification function. -+ */ -+ __u64 dmac; -+ -+ /* tsnCpeNullDownTagged. It can take the following values: -+ * 1 tagged: A frame must have a VLAN tag to be recognized as belonging -+ * to the Stream. -+ * 2 priority: A frame must be untagged, or have a VLAN tag with a VLAN -+ * ID = 0 to be recognized as belonging to the Stream. -+ * 3 all: A frame is recognized as belonging to the Stream whether -+ * tagged or not. -+ */ -+ __u8 tagged; -+ -+ /* tsnCpeNullDownVlan. Specifies the vlan_identifier parameter that -+ * identifies a packet in an EISS indication primitive to the Null -+ * Stream identification function. A value of 0 indicates that the vlan -+ * _identifier parameter is ignored on EISS indication primitives. -+ */ -+ __u16 vid; -+}; -+ -+struct tsn_cb_source_streamid { -+ __u64 smac; -+ __u8 tagged; -+ __u16 vid; -+}; -+ -+struct tsn_cb_dest_streamid { -+ __u64 down_dmac; -+ __u8 down_tagged; -+ __u16 down_vid; -+ __u8 down_prio; -+ __u64 up_dmac; -+ __u8 up_tagged; -+ __u16 up_vid; -+ __u8 up_prio; -+}; -+ -+struct tsn_cb_ip_streamid { -+ __u64 dmac; -+ __u8 tagged; -+ __u16 vid; -+ __u64 siph; -+ __u64 sipl; -+ __u64 diph; -+ __u64 dipl; -+ __u8 dscp; -+ __u8 npt; -+ __u16 sport; -+ __u16 dport; -+}; -+ -+/* 802.1CB stream identify table clause 9.1 */ -+struct tsn_cb_streamid { -+ /* The objects in a given entry of the Stream identity table are used -+ * to control packets whose stream_handle subparameter is equal to the -+ * entry tsnStreamIdHandle object. -+ */ -+ __s32 handle; -+ -+ /* The list of ports on which an in-facing Stream identification -+ * function in the output (towards the system forwarding function) -+ * direction Only Active Destination MAC and VLAN Stream identification -+ * (or nothing) can be configured. -+ */ -+ __u32 ifac_oport; -+ -+ /* The list of ports on which an out-facing Stream identification -+ * function in the output (towards the physical interface) direction. -+ * Only Active Destination MAC and VLAN Stream identification -+ * (or nothing) can be configured. -+ */ -+ __u32 ofac_oport; -+ -+ /* The list of ports on which an in-facing Stream identification -+ * function in the input (coming from the system forwarding function) -+ * direction -+ */ -+ __u32 ifac_iport; -+ -+ /* The list of ports on which an out-facing Stream identification -+ * function in the input (coming from the physical interface) direction -+ * . -+ */ -+ __u32 ofac_iport; -+ -+ /* An enumerated value indicating the method used to identify packets -+ * belonging to the Stream. -+ * The Organizationally Unique Identifier (OUI) or Company Identifier -+ * (CID) to identify the organization defining the enumerated type -+ * should be: 00-80-C2 -+ * 1: null stream identification -+ * 2: source mac and vlan stream identification -+ * 3: activ destination mac and vlan stream identification -+ * 4: ip stream identifaciton -+ */ -+ __u8 type; -+ -+ /* tsnStreamIdParameters The number of controlling parameters for a -+ * Stream identification method, their types and values, are specific -+ * to the tsnStreamIdIdentificationType -+ */ -+ union { -+ struct tsn_cb_null_streamid nid; -+ struct tsn_cb_source_streamid sid; -+ struct tsn_cb_dest_streamid did; -+ struct tsn_cb_ip_streamid iid; -+ } para; -+}; -+ -+/* Following counters are instantiated for each port on which the Stream -+ * identification function (6.2) is configured. The counters are indexed by -+ * port number, facing (in-facing or out-facing), and stream_handle value -+ * (tsnStreamIdHandle, 9.1.1.1). -+ */ -+struct tsn_cb_streamid_counters { -+ struct { -+ __u64 input; -+ __u64 output; -+ } per_stream; -+ -+ struct { -+ __u64 input; -+ __u64 output; -+ } per_streamport[32]; -+}; -+ -+/* 802.1Qci Stream Parameter Table, read from port */ -+struct tsn_qci_psfp_stream_param { -+ /* MaxStreamFilterInstances. -+ * The maximum number of Stream Filter instances supported by this -+ * Bridge component. -+ */ -+ __s32 max_sf_instance; -+ -+ /* MaxStreamGateInstances -+ * The maximum number of Stream Gate instances supported by this Bridge -+ * component. -+ */ -+ __s32 max_sg_instance; -+ -+ /* MaxFlowMeterInstances -+ * The maximum number of Flow Meter instances supported by this Bridge -+ * component. -+ */ -+ __s32 max_fm_instance; -+ -+ /* SupportedListMax -+ * The maximum value supported by this Bridge component of the -+ * AdminControlListLength and OperControlListLength parameters. -+ */ -+ __s32 supported_list_max; -+}; -+ -+/* 802.1Qci Stream Filter Instance Table, counters part only. */ -+struct tsn_qci_psfp_sfi_counters { -+ /* The MatchingFramesCount counter counts received frames that match -+ * this stream filter. -+ */ -+ __u64 matching_frames_count; -+ -+ /* The PassingFramesCount counter counts received frames that pass the -+ * gate associated with this stream filter. -+ */ -+ __u64 passing_frames_count; -+ -+ /* The NotPassingFramesCount counter counts received frames that do not -+ * pass the gate associated with this stream filter. -+ */ -+ __u64 not_passing_frames_count; -+ -+ /* The PassingSDUCount counter counts received frames that pass the SDU -+ * size filter specification associated with this stream filter. -+ */ -+ __u64 passing_sdu_count; -+ -+ /* The NotPassingSDUCount counter counts received frames that do not -+ * pass the SDU size filter specification associated with this stream -+ * filter. -+ */ -+ __u64 not_passing_sdu_count; -+ -+ /* The REDFramesCount counter counts received random early detection -+ * (RED) frames associated with this stream filter. -+ */ -+ __u64 red_frames_count; -+}; -+ -+/* 802.1Qci Stream Filter Instance Table, configuration part only. */ -+struct tsn_qci_psfp_sfi_conf { -+ -+ /* The StreamHandleSpec parameter contains a stream identifier -+ * specification value. A value of -1 denotes the wild card value; zero -+ * or positive values denote stream identifier values. -+ */ -+ __s32 stream_handle_spec; -+ -+ /* The PrioritySpec parameter contains a priority specification value. -+ * A value of -1 denotes the wild card value; zero or positive values -+ * denote priority values. -+ */ -+ __s8 priority_spec; -+ -+ /* The StreamGateInstanceID parameter contains the index of an entry in -+ * the Stream Gate Table. -+ */ -+ __u32 stream_gate_instance_id; -+ -+ /* The filter specifications. The actions specified in a filter -+ * specification can result in a frame passing or failing the specified -+ * filter. Frames that fail a filter are discarded. -+ */ -+ struct { -+ /* The MaximumSDUSize parameter specifies the maximum allowed -+ * frame size for the stream. Any frame exceeding this value -+ * will be dropped. A value of 0 denote that the MaximumSDUSize -+ * filter is disabled for this stream. -+ */ -+ __u16 maximum_sdu_size; -+ -+ /* The FlowMeterInstanceID parameter contains the index of an -+ * entry in the Flow Meter Table. A value of -1 denotes that -+ * no flow meter is assigned; zero or positive values denote -+ * flow meter IDs. -+ */ -+ __s32 flow_meter_instance_id; -+ } stream_filter; -+ -+ /* The StreamBlockedDueToOversizeFrameEnable object contains a Boolean -+ * value that indicates whether the StreamBlockedDueToOversizeFrame -+ * function is enabled (TRUE) or disabled (FALSE). -+ */ -+ __u8 block_oversize_enable; -+ -+ /* The StreamBlockedDueToOversizeFrame object contains a Boolean value -+ * that indicates whether, if the StreamBlockedDueToOversizeFrame -+ * function is enabled, all frames are to be discarded (TRUE) or not -+ * (FALSE). -+ */ -+ __u8 block_oversize; -+}; -+ -+/* 802.1Qci Stream Gate Control List Entry. */ -+struct tsn_qci_psfp_gcl { -+ /* The GateState parameter specifies a desired state, open (true) or -+ * closed (false), for the stream gate. -+ */ -+ __u8 gate_state; -+ -+ /* An IPV is encoded as a signed integer. A negative denotes the null -+ * value; zero or positive values denote internal priority values. -+ */ -+ __s8 ipv; -+ -+ /* A TimeInterval is encoded in 4 octets as a 32-bit unsigned integer, -+ * representing a number of nanoseconds. -+ */ -+ __u32 time_interval; -+ -+ /* The maximum number of octets that are permitted to pass the gate -+ * during the specified TimeInterval. If zero, there is no maximum. -+ */ -+ __u32 octet_max; -+ -+}; -+ -+/* 802.1Qci Stream Gate Admin/Operation common list control parameters */ -+struct tsn_qci_sg_control { -+ /* The administrative/operation value of the GateStates parameter -+ * for the stream gate. A value of false indicates closed; -+ * a value of true indicates open. -+ */ -+ __u8 gate_states; -+ -+ /* The administrative/operation value of the ListMax parameter for the -+ * gate. The integer value indicates the number of entries (TLVs) in -+ * the AdminControlList/OperControlList. -+ */ -+ __u8 control_list_length; -+ -+ /* The administrative/operation value of the CycleTime parameter for -+ * the gate. The value is an unsigned integer number of nanoseconds. -+ */ -+ __u32 cycle_time; -+ -+ /* The administrative/operation value of the CycleTimeExtension -+ * parameter for the gate. The value is an unsigned integer number -+ * of nanoseconds. -+ */ -+ __u32 cycle_time_extension; -+ -+ /* The administrative/operation value of the BaseTime parameter for the -+ * gate. The value is a representation of a PTPtime value, consisting -+ * of a 48-bit integer number of seconds and a 32-bit integer number of -+ * nanoseconds. -+ */ -+ ptptime_t base_time; -+ -+ /* The administrative/operation value of the IPV parameter for the gate. -+ * A value of -1 denotes the null value; zero or positive values denote -+ * internal priority values. -+ */ -+ __s8 init_ipv; -+ -+ /* control_list contend the gate control list of -+ * administrative/operation -+ */ -+ struct tsn_qci_psfp_gcl *gcl; -+}; -+ -+/* 802.1Qci Stream Gate Instance Table, configuration part only. */ -+struct tsn_qci_psfp_sgi_conf { -+ /* The GateEnabled parameter determines whether the stream gate is -+ * active (true) or inactive (false). -+ */ -+ __u8 gate_enabled; -+ -+ /* The ConfigChange parameter signals the start of a configuration -+ * change when it is set to TRUE. This should only be done when the -+ * various administrative parameters are all set to appropriate values. -+ */ -+ __u8 config_change; -+ -+ /* admin control parameters with admin control list */ -+ struct tsn_qci_sg_control admin; -+ -+ /* The GateClosedDueToInvalidRxEnable object contains a Boolean value -+ * that indicates whether the GateClosedDueToInvalidRx function is -+ * enabled (TRUE) or disabled (FALSE). -+ */ -+ __u8 block_invalid_rx_enable; -+ -+ /* The GateClosedDueToInvalidRx object contains a Boolean value that -+ * indicates whether, if the GateClosedDueToInvalidRx function is -+ * enabled, all frames are to be discarded (TRUE) or not (FALSE). -+ */ -+ __u8 block_invalid_rx; -+ -+ /* The GateClosedDueToOctetsExceededEnable object contains a Boolean -+ * value that indicates whether the GateClosedDueToOctetsExceeded -+ * function is enabled (TRUE) or disabled (FALSE). -+ */ -+ __u8 block_octets_exceeded_enable; -+ -+ /* The GateClosedDueToOctetsExceeded object contains a Boolean value -+ * that indicates whether, if the GateClosedDueToOctetsExceeded -+ * function is enabled, all frames are to be discarded (TRUE) or not -+ * (FALSE). -+ */ -+ __u8 block_octets_exceeded; -+}; -+ -+/* 802.1Qci Stream Gate Instance Table, status part only. */ -+struct tsn_psfp_sgi_status { -+ -+ /* admin control parameters with admin control list */ -+ struct tsn_qci_sg_control oper; -+ -+ /* The PTPtime at which the next config change is scheduled to occur. -+ * The value is a representation of a PTPtime value, consisting of a -+ * 48-bit integer number of seconds and a 32-bit integer number of -+ * nanoseconds. -+ */ -+ ptptime_t config_change_time; -+ -+ /* The granularity of the cycle time clock, represented as an unsigned -+ * number of tenths of nanoseconds. -+ */ -+ __u32 tick_granularity; -+ -+ /* The current time, in PTPtime, as maintained by the local system. -+ * The value is a representation of a PTPtime value, consisting of a -+ * 48-bit integer number of seconds and a 32-bit integer number of -+ * nanoseconds. -+ */ -+ ptptime_t current_time; -+ -+ /* The value of the ConfigPending state machine variable. The value is -+ * TRUE if a configuration change is in progress but has not yet -+ * completed. -+ */ -+ __u8 config_pending; -+ -+ /* A counter of the number of times that a re-configuration of the -+ * traffic schedule has been requested with the old schedule still -+ * running and the requested base time was in the past. -+ */ -+ __u64 config_change_error; -+ -+}; -+ -+/* 802.1Qci Flow Meter Instance Table. */ -+struct tsn_qci_psfp_fmi { -+ /* The FlowMeterCIR parameter contains an integer value that represents -+ * the CIR value for the flow meter, in kbit/s. -+ */ -+ __u32 cir; -+ -+ /* The FlowMeterCBS parameter contains an integer value that represents -+ * the CBS value for the flow meter, in octets. -+ */ -+ __u32 cbs; -+ -+ /* The FlowMeterEIR parameter contains an integer value that represents -+ * the EIR value for the flow meter, in kbit/s. -+ */ -+ __u32 eir; -+ -+ /* The FlowMeterEBS parameter contains an integer value that represents -+ * the EBS value for the flow meter, in octets. -+ */ -+ __u32 ebs; -+ -+ /* The FlowMeterCF parameter contains a Boolean value that represents -+ * the CF value for the flow meter, as a Boolean value indicating no -+ * coupling (FALSE) or coupling (TRUE). -+ */ -+ __u8 cf; -+ -+ /* The FlowMeterCM parameter contains a Boolean value that represents -+ * the CM value for the flow meter, as a Boolean value indicating -+ * colorBlind (FALSE) or colorAware (TRUE). -+ */ -+ __u8 cm; -+ -+ /* The FlowMeterDropOnYellow parameter contains a Boolean value that -+ * indicates whether yellow frames are dropped (TRUE) or have -+ * drop_eligible set to TRUE (FALSE). -+ */ -+ __u8 drop_on_yellow; -+ -+ /* The FlowMeterMarkAllFramesRedEnable parameter contains a Boolean -+ * value that indicates whether the MarkAllFramesRed function -+ * is enabled (TRUE) or disabled (FALSE). -+ */ -+ __u8 mark_red_enable; -+ -+ /* The FlowMeterMarkAllFramesRed parameter contains a Boolean value -+ * that indicates whether, if the MarkAllFramesRed function is enabled, -+ * all frames are to be discarded (TRUE) or not (FALSE). -+ */ -+ __u8 mark_red; -+}; -+ -+struct tsn_qci_psfp_fmi_counters { -+ __u64 bytecount; -+ __u64 drop; -+ __u64 dr0_green; -+ __u64 dr1_green; -+ __u64 dr2_yellow; -+ __u64 remark_yellow; -+ __u64 dr3_red; -+ __u64 remark_red; -+}; -+ -+/* 802.1cb */ -+struct tsn_seq_gen_conf { -+ -+ /* The InputPortMask parameter contains a port mask. -+ * If the packet is from input port belonging to this -+ * port mask then it's on known stream and sequence -+ * generation parameters can be applied. -+ */ -+ __u8 iport_mask; -+ -+ /* The SplitMask parameter contains a output port mask -+ * used to add redundant paths. -+ */ -+ __u8 split_mask; -+ -+ /* The SequenceSpaceLenLog parameter is a value to specifies -+ * number of bits to be used for sequence number. -+ */ -+ __u8 seq_len; -+ -+ /* The SequenceNumber parameter is a value to used for -+ * outgoing packet's sequence number generation. -+ */ -+ __u32 seq_num; -+}; -+ -+struct tsn_seq_rec_conf { -+ -+ /* The SequenceSpaceLenLog parameter is a value to specifies -+ * number of bits to be used for sequence number. -+ */ -+ __u8 seq_len; -+ -+ /* The HistorySpaceLenLog parameter is a value to specifies -+ * number of bits to be used for history register. -+ */ -+ __u8 his_len; -+ -+ /* The RTagPopEnable parameter contains a __u8 to enable removal -+ * of redundancy tag from the packet. -+ */ -+ __u8 rtag_pop_en; -+}; -+ -+struct tsn_cb_status { -+ -+ /* The GenRecover parameter contains a value specifies type -+ * of stream sequence parameters: -+ * 0: Stream sequence parameters are for generation. -+ * 1: Stream sequence parameters are for recovery. -+ */ -+ __u8 gen_rec; -+ -+ /* The ErrStatus parameter indicates stream's error status -+ * 1: This switch is expected to sequence the stream, -+ * but the incoming packet has sequence number. -+ * 2: This switch is expected to recover the stream, -+ * but the incoming packet is NONSEQ. -+ */ -+ __u8 err; -+ -+ /* The SequenceNumber parameter is a value to used for -+ * outgoing packet's sequence number generation. -+ */ -+ __u32 seq_num; -+ -+ /* The SequenceSpaceLenLog parameter is a value to specifies -+ * number of bits to be used for sequence number. -+ */ -+ __u8 seq_len; -+ -+ /* The SplitMask parameter contains a output port mask -+ * used to add redundant paths. -+ */ -+ __u8 split_mask; -+ -+ /* The InputPortMask parameter contains a port mask. -+ * If the packet is from input port belonging to this -+ * port mask then it's on known stream and sequence -+ * generation parameters can be applied. -+ */ -+ __u8 iport_mask; -+ -+ /* The HistorySpaceLenLog parameter is a value to specifies -+ * number of bits to be used for history register. -+ */ -+ __u8 his_len; -+ -+ /* The SequenceHistory parameter Maintains history of sequence -+ * numbers of received packets. -+ */ -+ __u32 seq_his; -+}; -+ -+/* An entry for gate control list */ -+struct tsn_qbv_entry { -+ /* Octet represent the gate states for the corresponding traffic -+ * classes. -+ * The MS bit corresponds to traffic class 7. -+ * The LS bit to traffic class 0. -+ * A bit value of 0 indicates closed; -+ * A bit value of 1 indicates open. -+ */ -+ __u8 gate_state; -+ -+ /* A TimeInterval is encoded in 4 octets as a 32-bit unsigned integer, -+ * representing a number of nanoseconds. -+ */ -+ __u32 time_interval; -+}; -+ -+/* The administrative/operation time and gate list */ -+struct tsn_qbv_basic { -+ /* The administrative/operation value of the GateStates parameter for -+ * the Port. -+ * The bits of the octet represent the gate states for the -+ * corresponding traffic classes; the MS bit corresponds to traffic -+ * class 7, the LS bit to traffic class 0. A bit value of 0 indicates -+ * closed; a bit value of 1 indicates open. -+ * The value of this object MUST be retained -+ * across reinitializations of the management system. -+ */ -+ __u8 gate_states; -+ -+ /* The administrative/operation value of the ListMax parameter for the -+ * port. The integer value indicates the number of entries (TLVs) in -+ * the AdminControlList. The value of this object MUST be retained -+ * across reinitializations of the management system. -+ */ -+ __u32 control_list_length; -+ -+ /* The administrative/operation value of the AdminCycleTime -+ * parameter for the Port. The numerator and denominator together -+ * represent the cycle time as a rational number of seconds. The value -+ * of this object MUST be retained across reinitializations of the -+ * management system. -+ */ -+ __u32 cycle_time; -+ -+ /* The administrative/operation value of the CycleTimeExtension -+ * parameter for the Port. The value is an unsigned integer number of -+ * nanoseconds. -+ * The value of this object MUST be retained across reinitializations -+ * of the management system. -+ */ -+ -+ __u32 cycle_time_extension; -+ -+ /* The administrative/operation value of the BaseTime parameter for the -+ * Port. The value is a representation of a PTPtime value, consisting -+ * of a 48-bit integer number of seconds and a 32-bit integer number of -+ * nanoseconds. -+ * The value of this object MUST be retained across reinitializations of -+ * the management system. -+ */ -+ ptptime_t base_time; -+ -+ /* admin_control_list represent the AdminControlList/OperControlList. -+ * The administrative version of the gate control list for the Port. -+ */ -+ struct tsn_qbv_entry *control_list; -+}; -+ -+struct tsn_qbv_conf { -+ /* The GateEnabled parameter determines whether traffic scheduling is -+ * active (true) or inactive (false). The value of this object MUST be -+ * retained across reinitializations of the management system. -+ */ -+ __u8 gate_enabled; -+ -+ /* The maxsdu parameter denoting the maximum SDU size supported by the -+ * queue. -+ */ -+ __u32 maxsdu; -+ -+ /* The ConfigChange parameter signals the start of a configuration -+ * change when it is set to TRUE. This should only be done when the -+ * various administrative parameters are all set to appropriate values. -+ */ -+ __u8 config_change; -+ -+ /* The admin parameter signals the admin relate cycletime, basictime, -+ * gatelist paraters. -+ */ -+ struct tsn_qbv_basic admin; -+}; -+ -+/* 802.1Qbv (Time Aware Shaper) port status */ -+struct tsn_qbv_status { -+ /* The PTPtime at which the next config change is scheduled to occur. -+ * The value is a representation of a PTPtime value, consisting of a -+ * 48-bit integer number of seconds and a 32-bit integer number of -+ * nanoseconds. The value of this object MUST be retained across -+ * reinitializations of the management system. -+ */ -+ ptptime_t config_change_time; -+ -+ /* The granularity of the cycle time clock, represented as an unsigned -+ * number of tenths of nanoseconds. The value of this object MUST be -+ * retained across reinitializations of the management system. -+ */ -+ __u32 tick_granularity; -+ -+ /* The current time, in PTPtime, as maintained by the local system. -+ * The value is a representation of a PTPtime value, consisting of a -+ * 48-bit integer number of seconds and a 32-bit integer number of -+ * nanoseconds. -+ */ -+ ptptime_t current_time; -+ -+ /* The value of the ConfigPending state machine variable. The value is -+ * TRUE if a configuration change is in progress but has not yet -+ * completed. -+ */ -+ __u8 config_pending; -+ -+ /* A counter of the number of times that a re-configuration of the -+ * traffic schedule has been requested with the old schedule still -+ * running and the requested base time was in the past. -+ */ -+ __u64 config_change_error; -+ -+ /* The maximum value supported by this Port of the -+ * AdminControlListLength and OperControlListLength parameters. -+ */ -+ __u32 supported_list_max; -+ -+ /* Operation settings parameters and Oper gate list */ -+ struct tsn_qbv_basic oper; -+}; -+ -+/* Time Specific Departure parameters */ -+struct tsn_tsd { -+ __u8 enable; -+ -+ /* The cycle time, in units of microsecond(us)*/ -+ __u32 period; -+ -+ /* The maximum number of frames which could be transmitted on one cycle -+ * The exceeding frames will be transmitted on next cycle. -+ */ -+ __u32 maxFrameNum; -+ -+ /* Specify the time of the first cycle begins. -+ * 1: begin when the queue get the first frame to transmit. -+ * 2: begin immediately at the end of setting function. -+ */ -+ __u32 syn_flag; -+}; -+ -+struct tsn_tsd_status { -+ __u8 enable; -+ __u32 period; -+ __u32 maxFrameNum; -+ __u32 flag; -+ __u32 cycleNum; -+ __u32 loss_steps; -+}; -+ -+struct tsn_qos_switch_dscp_conf { -+ __u8 trust; -+ __u8 cos; -+ __u8 dpl; -+ __u8 remark; -+ __u8 dscp; /* New ingress translated DSCP value */ -+}; -+ -+#endif /* _UAPI_GENL_TSN_H */ ---- a/net/Kconfig -+++ b/net/Kconfig -@@ -240,6 +240,7 @@ source "net/ieee802154/Kconfig" - source "net/mac802154/Kconfig" - source "net/sched/Kconfig" - source "net/dcb/Kconfig" -+source "net/tsn/Kconfig" - source "net/dns_resolver/Kconfig" - source "net/batman-adv/Kconfig" - source "net/openvswitch/Kconfig" ---- a/net/Makefile -+++ b/net/Makefile -@@ -59,6 +59,9 @@ obj-$(CONFIG_CAIF) += caif/ - ifneq ($(CONFIG_DCB),) - obj-y += dcb/ - endif -+ifneq ($(CONFIG_TSN),) -+obj-y += tsn/ -+endif - obj-$(CONFIG_6LOWPAN) += 6lowpan/ - obj-$(CONFIG_IEEE802154) += ieee802154/ - obj-$(CONFIG_MAC802154) += mac802154/ ---- /dev/null -+++ b/net/tsn/Kconfig -@@ -0,0 +1,15 @@ -+config TSN -+ bool "802.1 Time-Sensitive Networking support" -+ default n -+ depends on VLAN_8021Q && PTP_1588_CLOCK -+ help -+ This enables support for TSN(time sensitive networking) -+ TSN features include: -+ 802.1Qav: -+ 802.1Qbv: -+ 802.1Qci: -+ 802.1Qbu: -+ 802.1AS: -+ 802.1CB: -+ -+ If unsure, say N. ---- /dev/null -+++ b/net/tsn/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_TSN) += genl_tsn.o ---- /dev/null -+++ b/net/tsn/genl_tsn.c -@@ -0,0 +1,3696 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* Copyright 2017-2019 NXP */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define NLA_PARSE_NESTED(a, b, c, d) \ -+ nla_parse_nested_deprecated(a, b, c, d, NULL) -+#define NLA_PUT_U64(a, b, c) nla_put_u64_64bit(a, b, c, NLA_U64) -+ -+static struct genl_family tsn_family; -+ -+LIST_HEAD(port_list); -+ -+static const struct nla_policy tsn_cmd_policy[TSN_CMD_ATTR_MAX + 1] = { -+ [TSN_CMD_ATTR_MESG] = { .type = NLA_STRING }, -+ [TSN_CMD_ATTR_DATA] = { .type = NLA_S32 }, -+ [TSN_ATTR_IFNAME] = { .type = NLA_STRING }, -+ [TSN_ATTR_PORT_NUMBER] = { .type = NLA_U8 }, -+ [TSN_ATTR_CAP] = { .type = NLA_NESTED }, -+ [TSN_ATTR_QBV] = { .type = NLA_NESTED }, -+ [TSN_ATTR_STREAM_IDENTIFY] = { .type = NLA_NESTED }, -+ [TSN_ATTR_QCI_SP] = { .type = NLA_NESTED }, -+ [TSN_ATTR_QCI_SFI] = { .type = NLA_NESTED }, -+ [TSN_ATTR_QCI_SGI] = { .type = NLA_NESTED }, -+ [TSN_ATTR_QCI_FMI] = { .type = NLA_NESTED }, -+ [TSN_ATTR_CBS] = { .type = NLA_NESTED }, -+ [TSN_ATTR_TSD] = { .type = NLA_NESTED }, -+ [TSN_ATTR_QBU] = { .type = NLA_NESTED }, -+ [TSN_ATTR_CT] = { .type = NLA_NESTED }, -+ [TSN_ATTR_CBGEN] = { .type = NLA_NESTED }, -+ [TSN_ATTR_CBREC] = { .type = NLA_NESTED }, -+ [TSN_ATTR_CBSTAT] = { .type = NLA_NESTED }, -+ [TSN_ATTR_DSCP] = { .type = NLA_NESTED }, -+}; -+ -+static const struct nla_policy tsn_cap_policy[TSN_CAP_ATTR_MAX + 1] = { -+ [TSN_CAP_ATTR_QBV] = { .type = NLA_FLAG }, -+ [TSN_CAP_ATTR_QCI] = { .type = NLA_FLAG }, -+ [TSN_CAP_ATTR_QBU] = { .type = NLA_FLAG }, -+ [TSN_CAP_ATTR_CBS] = { .type = NLA_FLAG }, -+ [TSN_CAP_ATTR_CB] = { .type = NLA_FLAG }, -+ [TSN_CAP_ATTR_TBS] = { .type = NLA_FLAG }, -+ [TSN_CAP_ATTR_CTH] = { .type = NLA_FLAG }, -+}; -+ -+static const struct nla_policy qci_cap_policy[TSN_QCI_STREAM_ATTR_MAX + 1] = { -+ [TSN_QCI_STREAM_ATTR_MAX_SFI] = { .type = NLA_U32 }, -+ [TSN_QCI_STREAM_ATTR_MAX_SGI] = { .type = NLA_U32 }, -+ [TSN_QCI_STREAM_ATTR_MAX_FMI] = { .type = NLA_U32 }, -+ [TSN_QCI_STREAM_ATTR_SLM] = { .type = NLA_U32 }, -+}; -+ -+static const struct nla_policy ct_policy[TSN_CT_ATTR_MAX + 1] = { -+ [TSN_CT_ATTR_QUEUE_STATE] = { .type = NLA_U8 } -+}; -+ -+static const struct nla_policy cbgen_policy[TSN_CBGEN_ATTR_MAX + 1] = { -+ [TSN_CBGEN_ATTR_INDEX] = { .type = NLA_U32 }, -+ [TSN_CBGEN_ATTR_PORT_MASK] = { .type = NLA_U8 }, -+ [TSN_CBGEN_ATTR_SPLIT_MASK] = { .type = NLA_U8 }, -+ [TSN_CBGEN_ATTR_SEQ_LEN] = { .type = NLA_U8 }, -+ [TSN_CBGEN_ATTR_SEQ_NUM] = { .type = NLA_U32 }, -+}; -+ -+static const struct nla_policy cbrec_policy[TSN_CBREC_ATTR_MAX + 1] = { -+ [TSN_CBREC_ATTR_INDEX] = { .type = NLA_U32 }, -+ [TSN_CBREC_ATTR_SEQ_LEN] = { .type = NLA_U8 }, -+ [TSN_CBREC_ATTR_HIS_LEN] = { .type = NLA_U8 }, -+ [TSN_CBREC_ATTR_TAG_POP_EN] = { .type = NLA_FLAG }, -+}; -+ -+static const struct nla_policy cbstat_policy[TSN_CBSTAT_ATTR_MAX + 1] = { -+ [TSN_CBSTAT_ATTR_INDEX] = { .type = NLA_U32 }, -+ [TSN_CBSTAT_ATTR_GEN_REC] = { .type = NLA_U8 }, -+ [TSN_CBSTAT_ATTR_ERR] = { .type = NLA_U8 }, -+ [TSN_CBSTAT_ATTR_SEQ_NUM] = { .type = NLA_U32 }, -+ [TSN_CBSTAT_ATTR_SEQ_LEN] = { .type = NLA_U8 }, -+ [TSN_CBSTAT_ATTR_SPLIT_MASK] = { .type = NLA_U8 }, -+ [TSN_CBSTAT_ATTR_PORT_MASK] = { .type = NLA_U8 }, -+ [TSN_CBSTAT_ATTR_HIS_LEN] = { .type = NLA_U8 }, -+ [TSN_CBSTAT_ATTR_SEQ_HIS] = { .type = NLA_U32 }, -+}; -+ -+static const struct nla_policy qbu_policy[TSN_QBU_ATTR_MAX + 1] = { -+ [TSN_QBU_ATTR_ADMIN_STATE] = { .type = NLA_U8 }, -+ [TSN_QBU_ATTR_HOLD_ADVANCE] = { .type = NLA_U32}, -+ [TSN_QBU_ATTR_RELEASE_ADVANCE] = { .type = NLA_U32}, -+ [TSN_QBU_ATTR_ACTIVE] = { .type = NLA_FLAG}, -+ [TSN_QBU_ATTR_HOLD_REQUEST] = { .type = NLA_U8}, -+}; -+ -+static const struct nla_policy cbs_policy[TSN_CBS_ATTR_MAX + 1] = { -+ [TSN_CBS_ATTR_TC_INDEX] = { .type = NLA_U8}, -+ [TSN_CBS_ATTR_BW] = { .type = NLA_U8}, -+}; -+ -+static const struct nla_policy tsd_policy[TSN_TSD_ATTR_MAX + 1] = { -+ [TSN_TSD_ATTR_ENABLE] = { .type = NLA_FLAG}, -+ [TSN_TSD_ATTR_DISABLE] = { .type = NLA_FLAG}, -+ [TSN_TSD_ATTR_PERIOD] = { .type = NLA_U32}, -+ [TSN_TSD_ATTR_MAX_FRM_NUM] = { .type = NLA_U32}, -+ [TSN_TSD_ATTR_CYCLE_NUM] = { .type = NLA_U32}, -+ [TSN_TSD_ATTR_LOSS_STEPS] = { .type = NLA_U32}, -+ [TSN_TSD_ATTR_SYN_IMME] = { .type = NLA_FLAG}, -+}; -+ -+static const struct nla_policy qbv_policy[TSN_QBV_ATTR_MAX + 1] = { -+ [TSN_QBV_ATTR_ADMINENTRY] = { .type = NLA_NESTED}, -+ [TSN_QBV_ATTR_OPERENTRY] = { .type = NLA_NESTED}, -+ [TSN_QBV_ATTR_ENABLE] = { .type = NLA_FLAG}, -+ [TSN_QBV_ATTR_DISABLE] = { .type = NLA_FLAG}, -+ [TSN_QBV_ATTR_CONFIGCHANGE] = { .type = NLA_FLAG}, -+ [TSN_QBV_ATTR_CONFIGCHANGETIME] = { .type = NLA_U64}, -+ [TSN_QBV_ATTR_MAXSDU] = { .type = NLA_U32}, -+ [TSN_QBV_ATTR_GRANULARITY] = { .type = NLA_U32}, -+ [TSN_QBV_ATTR_CURRENTTIME] = { .type = NLA_U64}, -+ [TSN_QBV_ATTR_CONFIGPENDING] = {.type = NLA_FLAG}, -+ [TSN_QBV_ATTR_CONFIGCHANGEERROR] = { .type = NLA_U64}, -+ [TSN_QBV_ATTR_LISTMAX] = { .type = NLA_U32}, -+}; -+ -+static const struct nla_policy qbv_ctrl_policy[TSN_QBV_ATTR_CTRL_MAX + 1] = { -+ [TSN_QBV_ATTR_CTRL_LISTCOUNT] = { .type = NLA_U32}, -+ [TSN_QBV_ATTR_CTRL_GATESTATE] = { .type = NLA_U8}, -+ [TSN_QBV_ATTR_CTRL_CYCLETIME] = { .type = NLA_U32}, -+ [TSN_QBV_ATTR_CTRL_CYCLETIMEEXT] = { .type = NLA_U32}, -+ [TSN_QBV_ATTR_CTRL_BASETIME] = { .type = NLA_U64}, -+ [TSN_QBV_ATTR_CTRL_LISTENTRY] = { .type = NLA_NESTED}, -+}; -+ -+static const struct nla_policy qbv_entry_policy[TSN_QBV_ATTR_ENTRY_MAX + 1] = { -+ [TSN_QBV_ATTR_ENTRY_ID] = { .type = NLA_U32}, -+ [TSN_QBV_ATTR_ENTRY_GC] = { .type = NLA_U8}, -+ [TSN_QBV_ATTR_ENTRY_TM] = { .type = NLA_U32}, -+}; -+ -+static const struct nla_policy cb_streamid_policy[TSN_STREAMID_ATTR_MAX + 1] = { -+ [TSN_STREAMID_ATTR_INDEX] = { .type = NLA_U32}, -+ [TSN_STREAMID_ATTR_ENABLE] = { .type = NLA_FLAG}, -+ [TSN_STREAMID_ATTR_DISABLE] = { .type = NLA_FLAG}, -+ [TSN_STREAMID_ATTR_STREAM_HANDLE] = { .type = NLA_S32}, -+ [TSN_STREAMID_ATTR_IFOP] = { .type = NLA_U32}, -+ [TSN_STREAMID_ATTR_OFOP] = { .type = NLA_U32}, -+ [TSN_STREAMID_ATTR_IFIP] = { .type = NLA_U32}, -+ [TSN_STREAMID_ATTR_OFIP] = { .type = NLA_U32}, -+ [TSN_STREAMID_ATTR_TYPE] = { .type = NLA_U8}, -+ [TSN_STREAMID_ATTR_NDMAC] = { .type = NLA_U64}, -+ [TSN_STREAMID_ATTR_NTAGGED] = { .type = NLA_U8}, -+ [TSN_STREAMID_ATTR_NVID] = { .type = NLA_U16}, -+ [TSN_STREAMID_ATTR_SMAC] = { .type = NLA_U64}, -+ [TSN_STREAMID_ATTR_STAGGED] = { .type = NLA_U8}, -+ [TSN_STREAMID_ATTR_SVID] = { .type = NLA_U16}, -+ [TSN_STREAMID_ATTR_COUNTERS_PSI] = { .type = NLA_U64}, -+ [TSN_STREAMID_ATTR_COUNTERS_PSO] = { .type = NLA_U64}, -+ [TSN_STREAMID_ATTR_COUNTERS_PSPPI] = { .type = NLA_U64}, -+ [TSN_STREAMID_ATTR_COUNTERS_PSPPO] = { .type = NLA_U64}, -+}; -+ -+static const struct nla_policy qci_sfi_policy[TSN_QCI_SFI_ATTR_MAX + 1] = { -+ [TSN_QCI_SFI_ATTR_INDEX] = { .type = NLA_U32}, -+ [TSN_QCI_SFI_ATTR_ENABLE] = { .type = NLA_FLAG}, -+ [TSN_QCI_SFI_ATTR_DISABLE] = { .type = NLA_FLAG}, -+ [TSN_QCI_SFI_ATTR_STREAM_HANDLE] = { .type = NLA_S32}, -+ [TSN_QCI_SFI_ATTR_PRIO_SPEC] = { .type = NLA_S8}, -+ [TSN_QCI_SFI_ATTR_GATE_ID] = { .type = NLA_U32}, -+ [TSN_QCI_SFI_ATTR_FILTER_TYPE] = { .type = NLA_U8}, -+ [TSN_QCI_SFI_ATTR_FLOW_ID] = { .type = NLA_S32}, -+ [TSN_QCI_SFI_ATTR_MAXSDU] = { .type = NLA_U16}, -+ [TSN_QCI_SFI_ATTR_COUNTERS] = { -+ .len = sizeof(struct tsn_qci_psfp_sfi_counters)}, -+ [TSN_QCI_SFI_ATTR_OVERSIZE_ENABLE] = { .type = NLA_FLAG}, -+ [TSN_QCI_SFI_ATTR_OVERSIZE] = { .type = NLA_FLAG}, -+}; -+ -+static const struct nla_policy qci_sgi_policy[] = { -+ [TSN_QCI_SGI_ATTR_INDEX] = { .type = NLA_U32}, -+ [TSN_QCI_SGI_ATTR_ENABLE] = { .type = NLA_FLAG}, -+ [TSN_QCI_SGI_ATTR_DISABLE] = { .type = NLA_FLAG}, -+ [TSN_QCI_SGI_ATTR_CONFCHANGE] = { .type = NLA_FLAG}, -+ [TSN_QCI_SGI_ATTR_IRXEN] = { .type = NLA_FLAG}, -+ [TSN_QCI_SGI_ATTR_IRX] = { .type = NLA_FLAG}, -+ [TSN_QCI_SGI_ATTR_OEXEN] = { .type = NLA_FLAG}, -+ [TSN_QCI_SGI_ATTR_OEX] = { .type = NLA_FLAG}, -+ [TSN_QCI_SGI_ATTR_ADMINENTRY] = { .type = NLA_NESTED}, -+ [TSN_QCI_SGI_ATTR_OPERENTRY] = { .type = NLA_NESTED}, -+ [TSN_QCI_SGI_ATTR_CCTIME] = { .type = NLA_U64}, -+ [TSN_QCI_SGI_ATTR_TICKG] = { .type = NLA_U32}, -+ [TSN_QCI_SGI_ATTR_CUTIME] = { .type = NLA_U64}, -+ [TSN_QCI_SGI_ATTR_CPENDING] = { .type = NLA_FLAG}, -+ [TSN_QCI_SGI_ATTR_CCERROR] = { .type = NLA_U64}, -+}; -+ -+static const struct nla_policy qci_sgi_ctrl_policy[] = { -+ [TSN_SGI_ATTR_CTRL_INITSTATE] = { .type = NLA_FLAG}, -+ [TSN_SGI_ATTR_CTRL_LEN] = { .type = NLA_U8}, -+ [TSN_SGI_ATTR_CTRL_CYTIME] = { .type = NLA_U32}, -+ [TSN_SGI_ATTR_CTRL_CYTIMEEX] = { .type = NLA_U32}, -+ [TSN_SGI_ATTR_CTRL_BTIME] = { .type = NLA_U64}, -+ [TSN_SGI_ATTR_CTRL_INITIPV] = { .type = NLA_S8}, -+ [TSN_SGI_ATTR_CTRL_GCLENTRY] = { .type = NLA_NESTED}, -+}; -+ -+static const struct nla_policy qci_sgi_gcl_policy[] = { -+ [TSN_SGI_ATTR_GCL_GATESTATE] = { .type = NLA_FLAG}, -+ [TSN_SGI_ATTR_GCL_IPV] = { .type = NLA_S8}, -+ [TSN_SGI_ATTR_GCL_INTERVAL] = { .type = NLA_U32}, -+ [TSN_SGI_ATTR_GCL_OCTMAX] = { .type = NLA_U32}, -+}; -+ -+static const struct nla_policy qci_fmi_policy[] = { -+ [TSN_QCI_FMI_ATTR_INDEX] = { .type = NLA_U32}, -+ [TSN_QCI_FMI_ATTR_ENABLE] = { .type = NLA_FLAG}, -+ [TSN_QCI_FMI_ATTR_DISABLE] = { .type = NLA_FLAG}, -+ [TSN_QCI_FMI_ATTR_CIR] = { .type = NLA_U32}, -+ [TSN_QCI_FMI_ATTR_CBS] = { .type = NLA_U32}, -+ [TSN_QCI_FMI_ATTR_EIR] = { .type = NLA_U32}, -+ [TSN_QCI_FMI_ATTR_EBS] = { .type = NLA_U32}, -+ [TSN_QCI_FMI_ATTR_CF] = { .type = NLA_FLAG}, -+ [TSN_QCI_FMI_ATTR_CM] = { .type = NLA_FLAG}, -+ [TSN_QCI_FMI_ATTR_DROPYL] = { .type = NLA_FLAG}, -+ [TSN_QCI_FMI_ATTR_MAREDEN] = { .type = NLA_FLAG}, -+ [TSN_QCI_FMI_ATTR_MARED] = { .type = NLA_FLAG}, -+ [TSN_QCI_FMI_ATTR_COUNTERS] = { -+ .len = sizeof(struct tsn_qci_psfp_fmi_counters)}, -+}; -+ -+static const struct nla_policy dscp_policy[] = { -+ [TSN_DSCP_ATTR_INDEX] = { .type = NLA_U32}, -+ [TSN_DSCP_ATTR_DISABLE] = { .type = NLA_FLAG}, -+ [TSN_DSCP_ATTR_COS] = { .type = NLA_U8}, -+ [TSN_DSCP_ATTR_DPL] = { .type = NLA_U8}, -+}; -+ -+static ATOMIC_NOTIFIER_HEAD(tsn_notif_chain); -+ -+/** -+ * register_tsn_notifier - Register notifier -+ * @nb: notifier_block -+ * -+ * Register switch device notifier. -+ */ -+int register_tsn_notifier(struct notifier_block *nb) -+{ -+ return atomic_notifier_chain_register(&tsn_notif_chain, nb); -+} -+EXPORT_SYMBOL_GPL(register_tsn_notifier); -+ -+/** -+ * unregister_tsn_notifier - Unregister notifier -+ * @nb: notifier_block -+ * -+ * Unregister switch device notifier. -+ */ -+int unregister_tsn_notifier(struct notifier_block *nb) -+{ -+ return atomic_notifier_chain_unregister(&tsn_notif_chain, nb); -+} -+EXPORT_SYMBOL_GPL(unregister_tsn_notifier); -+ -+/** -+ * call_tsn_notifiers - Call notifiers -+ * @val: value passed unmodified to notifier function -+ * @dev: port device -+ * @info: notifier information data -+ * -+ * Call all network notifier blocks. -+ */ -+int call_tsn_notifiers(unsigned long val, struct net_device *dev, -+ struct tsn_notifier_info *info) -+{ -+ info->dev = dev; -+ return atomic_notifier_call_chain(&tsn_notif_chain, val, info); -+} -+EXPORT_SYMBOL_GPL(call_tsn_notifiers); -+ -+struct tsn_port *tsn_get_port(struct net_device *ndev) -+{ -+ struct tsn_port *port; -+ bool tsn_found = false; -+ -+ list_for_each_entry(port, &port_list, list) { -+ if (port->netdev == ndev) { -+ tsn_found = true; -+ break; -+ } -+ } -+ -+ if (!tsn_found) -+ return NULL; -+ -+ return port; -+} -+EXPORT_SYMBOL_GPL(tsn_get_port); -+ -+static int tsn_prepare_reply(struct genl_info *info, u8 cmd, -+ struct sk_buff **skbp, size_t size) -+{ -+ struct sk_buff *skb; -+ void *reply; -+ -+ /* If new attributes are added, please revisit this allocation -+ */ -+ skb = genlmsg_new(size, GFP_KERNEL); -+ if (!skb) -+ return -ENOMEM; -+ -+ if (!info) { -+ nlmsg_free(skb); -+ return -EINVAL; -+ } -+ -+ reply = genlmsg_put_reply(skb, info, &tsn_family, 0, cmd); -+ if (!reply) { -+ nlmsg_free(skb); -+ return -EINVAL; -+ } -+ -+ *skbp = skb; -+ return 0; -+} -+ -+static int tsn_mk_reply(struct sk_buff *skb, int aggr, void *data, int len) -+{ -+ /* add a netlink attribute to a socket buffer */ -+ return nla_put(skb, aggr, len, data); -+} -+ -+static int tsn_send_reply(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct genlmsghdr *genlhdr = nlmsg_data(nlmsg_hdr(skb)); -+ void *reply = genlmsg_data(genlhdr); -+ -+ genlmsg_end(skb, reply); -+ -+ return genlmsg_reply(skb, info); -+} -+ -+static int cmd_attr_echo_message(struct genl_info *info) -+{ -+ struct nlattr *na; -+ char *msg; -+ struct sk_buff *rep_skb; -+ size_t size; -+ int ret; -+ -+ na = info->attrs[TSN_CMD_ATTR_MESG]; -+ if (!na) -+ return -EINVAL; -+ -+ msg = (char *)nla_data(na); -+ pr_info("tsn generic netlink receive echo mesg %s\n", msg); -+ -+ size = nla_total_size(strlen(msg) + 1); -+ -+ ret = tsn_prepare_reply(info, TSN_CMD_REPLY, &rep_skb, -+ size + NLMSG_ALIGN(MAX_USER_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ ret = tsn_mk_reply(rep_skb, TSN_CMD_ATTR_MESG, msg, size); -+ if (ret < 0) -+ goto err; -+ -+ return tsn_send_reply(rep_skb, info); -+ -+err: -+ nlmsg_free(rep_skb); -+ return ret; -+} -+ -+static int cmd_attr_echo_data(struct genl_info *info) -+{ -+ struct nlattr *na; -+ s32 data; -+ struct sk_buff *rep_skb; -+ size_t size; -+ int ret; -+ -+ /*read data */ -+ na = info->attrs[TSN_CMD_ATTR_DATA]; -+ if (!na) -+ return -EINVAL; -+ -+ data = nla_get_s32(info->attrs[TSN_CMD_ATTR_DATA]); -+ pr_info("tsn generic netlink receive echo data %d\n", data); -+ -+ /* send back */ -+ size = nla_total_size(sizeof(s32)); -+ -+ ret = tsn_prepare_reply(info, TSN_CMD_REPLY, &rep_skb, -+ size + NLMSG_ALIGN(MAX_USER_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ /* netlink lib func */ -+ ret = nla_put_s32(rep_skb, TSN_CMD_ATTR_DATA, data); -+ if (ret < 0) -+ goto err; -+ -+ return tsn_send_reply(rep_skb, info); -+ -+err: -+ nlmsg_free(rep_skb); -+ return ret; -+} -+ -+static int tsn_echo_cmd(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_CMD_ATTR_MESG]) -+ return cmd_attr_echo_message(info); -+ else if (info->attrs[TSN_CMD_ATTR_DATA]) -+ return cmd_attr_echo_data(info); -+ -+ return -EINVAL; -+} -+ -+static int tsn_simple_reply(struct genl_info *info, u32 cmd, -+ char *portname, s32 retvalue) -+{ -+ struct sk_buff *rep_skb; -+ size_t size; -+ int ret; -+ -+ /* send back */ -+ size = nla_total_size(strlen(portname) + 1); -+ size += nla_total_size(sizeof(s32)); -+ -+ ret = tsn_prepare_reply(info, cmd, -+ &rep_skb, size + NLMSG_ALIGN(MAX_USER_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ /* netlink lib func */ -+ ret = nla_put_string(rep_skb, TSN_ATTR_IFNAME, portname); -+ if (ret < 0) -+ return ret; -+ -+ ret = nla_put_s32(rep_skb, TSN_CMD_ATTR_DATA, retvalue); -+ if (ret < 0) -+ return ret; -+ -+ return tsn_send_reply(rep_skb, info); -+} -+ -+struct tsn_port *tsn_init_check(struct genl_info *info, -+ struct net_device **ndev) -+{ -+ struct nlattr *na; -+ char *portname; -+ struct net_device *netdev; -+ struct tsn_port *port; -+ bool tsn_found = false; -+ -+ if (!info->attrs[TSN_ATTR_IFNAME]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ "no portname", -EINVAL); -+ return NULL; -+ } -+ -+ na = info->attrs[TSN_ATTR_IFNAME]; -+ -+ portname = (char *)nla_data(na); -+ -+ netdev = __dev_get_by_name(genl_info_net(info), portname); -+ if (!netdev) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ "error device", -ENODEV); -+ return NULL; -+ } -+ -+ list_for_each_entry(port, &port_list, list) { -+ if (port->netdev == netdev) { -+ tsn_found = true; -+ break; -+ } -+ } -+ -+ if (!tsn_found) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -ENODEV); -+ return NULL; -+ } -+ -+ *ndev = netdev; -+ -+ return port; -+} -+ -+static int tsn_cap_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct sk_buff *rep_skb; -+ struct nlattr *tsn_cap_attr; -+ int ret; -+ u32 cap = 0; -+ struct net_device *netdev; -+ struct genlmsghdr *genlhdr; -+ const struct tsn_ops *tsnops; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) { -+ ret = -ENODEV; -+ goto out; -+ } -+ -+ tsnops = port->tsnops; -+ genlhdr = info->genlhdr; -+ if (!tsnops->get_capability) { -+ ret = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ cap = tsnops->get_capability(netdev); -+ if (cap < 0) { -+ ret = cap; -+ goto out; -+ } -+ -+ /* Pad netlink reply data */ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, -+ &rep_skb, NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ goto out; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) { -+ ret = -EMSGSIZE; -+ goto err; -+ } -+ -+ tsn_cap_attr = nla_nest_start_noflag(rep_skb, TSN_ATTR_CAP); -+ if (!tsn_cap_attr) { -+ ret = -EMSGSIZE; -+ goto err; -+ } -+ -+ if (cap & TSN_CAP_QBV) { -+ if (nla_put_flag(rep_skb, TSN_CAP_ATTR_QBV)) -+ goto err; -+ } -+ -+ if (cap & TSN_CAP_QCI) { -+ if (nla_put_flag(rep_skb, TSN_CAP_ATTR_QCI)) -+ goto err; -+ } -+ -+ if (cap & TSN_CAP_QBU) { -+ if (nla_put_flag(rep_skb, TSN_CAP_ATTR_QBU)) -+ goto err; -+ } -+ -+ if (cap & TSN_CAP_CBS) { -+ if (nla_put_flag(rep_skb, TSN_CAP_ATTR_CBS)) -+ goto err; -+ } -+ -+ if (cap & TSN_CAP_CB) { -+ if (nla_put_flag(rep_skb, TSN_CAP_ATTR_CB)) -+ goto err; -+ } -+ -+ if (cap & TSN_CAP_TBS) { -+ if (nla_put_flag(rep_skb, TSN_CAP_ATTR_TBS)) -+ goto err; -+ } -+ -+ if (cap & TSN_CAP_CTH) { -+ if (nla_put_flag(rep_skb, TSN_CAP_ATTR_CTH)) -+ goto err; -+ } -+ -+ nla_nest_end(rep_skb, tsn_cap_attr); -+ -+ tsn_send_reply(rep_skb, info); -+ return 0; -+err: -+ nlmsg_free(rep_skb); -+out: -+ if (ret < 0) -+ tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, ret); -+ return ret; -+} -+ -+static int cmd_cb_streamid_set(struct genl_info *info) -+{ -+ struct nlattr *na, *sid[TSN_STREAMID_ATTR_MAX + 1]; -+ u32 sid_index; -+ u8 iden_type = 1; -+ bool enable; -+ int ret; -+ struct net_device *netdev; -+ struct tsn_cb_streamid sidconf; -+ const struct tsn_ops *tsnops; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ memset(&sidconf, 0, sizeof(struct tsn_cb_streamid)); -+ -+ if (!info->attrs[TSN_ATTR_STREAM_IDENTIFY]) -+ return -EINVAL; -+ -+ na = info->attrs[TSN_ATTR_STREAM_IDENTIFY]; -+ -+ ret = NLA_PARSE_NESTED(sid, TSN_STREAMID_ATTR_MAX, -+ na, cb_streamid_policy); -+ if (ret) -+ return -EINVAL; -+ -+ if (!sid[TSN_STREAMID_ATTR_INDEX]) -+ return -EINVAL; -+ -+ sid_index = nla_get_u32(sid[TSN_STREAMID_ATTR_INDEX]); -+ -+ if (sid[TSN_STREAMID_ATTR_ENABLE]) -+ enable = true; -+ else if (sid[TSN_STREAMID_ATTR_DISABLE]) -+ enable = false; -+ else -+ return -EINVAL; -+ -+ if (!enable) -+ goto loaddev; -+ -+ if (sid[TSN_STREAMID_ATTR_TYPE]) -+ iden_type = nla_get_u8(sid[TSN_STREAMID_ATTR_TYPE]); -+ else -+ return -EINVAL; -+ -+ sidconf.type = iden_type; -+ switch (iden_type) { -+ case STREAMID_NULL: -+ if (!sid[TSN_STREAMID_ATTR_NDMAC] || -+ !sid[TSN_STREAMID_ATTR_NTAGGED] || -+ !sid[TSN_STREAMID_ATTR_NVID]) { -+ return -EINVAL; -+ } -+ -+ sidconf.para.nid.dmac = -+ nla_get_u64(sid[TSN_STREAMID_ATTR_NDMAC]); -+ sidconf.para.nid.tagged = -+ nla_get_u8(sid[TSN_STREAMID_ATTR_NTAGGED]); -+ sidconf.para.nid.vid = -+ nla_get_u16(sid[TSN_STREAMID_ATTR_NVID]); -+ break; -+ case STREAMID_SMAC_VLAN: -+ /* TODO: not supportted yet */ -+ if (!sid[TSN_STREAMID_ATTR_SMAC] || -+ !sid[TSN_STREAMID_ATTR_STAGGED] || -+ !sid[TSN_STREAMID_ATTR_SVID]) { -+ return -EINVAL; -+ } -+ -+ sidconf.para.sid.smac = -+ nla_get_u64(sid[TSN_STREAMID_ATTR_SMAC]); -+ sidconf.para.sid.tagged = -+ nla_get_u8(sid[TSN_STREAMID_ATTR_STAGGED]); -+ sidconf.para.sid.vid = -+ nla_get_u16(sid[TSN_STREAMID_ATTR_SVID]); -+ break; -+ case STREAMID_DMAC_VLAN: -+ -+ case STREAMID_IP: -+ -+ default: -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ if (sid[TSN_STREAMID_ATTR_STREAM_HANDLE]) -+ sidconf.handle = -+ nla_get_s32(sid[TSN_STREAMID_ATTR_STREAM_HANDLE]); -+ -+ if (sid[TSN_STREAMID_ATTR_IFOP]) -+ sidconf.ifac_oport = nla_get_u32(sid[TSN_STREAMID_ATTR_IFOP]); -+ if (sid[TSN_STREAMID_ATTR_OFOP]) -+ sidconf.ofac_oport = nla_get_u32(sid[TSN_STREAMID_ATTR_OFOP]); -+ if (sid[TSN_STREAMID_ATTR_IFIP]) -+ sidconf.ifac_iport = nla_get_u32(sid[TSN_STREAMID_ATTR_IFIP]); -+ if (sid[TSN_STREAMID_ATTR_OFIP]) -+ sidconf.ofac_iport = nla_get_u32(sid[TSN_STREAMID_ATTR_OFIP]); -+ -+loaddev: -+ if (!tsnops->cb_streamid_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -EOPNOTSUPP; -+ } -+ -+ ret = tsnops->cb_streamid_set(netdev, sid_index, enable, &sidconf); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, ret); -+ return ret; -+ } -+ -+ /* simple reply here. To be continue */ -+ if (tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, 0)) -+ return -1; -+ -+ return 0; -+} -+ -+static int tsn_cb_streamid_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmd_cb_streamid_set(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int cmd_cb_streamid_get(struct genl_info *info) -+{ -+ struct nlattr *na, *sidattr, *sid[TSN_STREAMID_ATTR_MAX + 1]; -+ u32 sid_index; -+ struct genlmsghdr *genlhdr; -+ struct sk_buff *rep_skb; -+ int ret, i; -+ int valid; -+ struct net_device *netdev; -+ struct tsn_cb_streamid sidconf; -+ struct tsn_cb_streamid_counters sidcounts; -+ const struct tsn_ops *tsnops; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ memset(&sidconf, 0, sizeof(struct tsn_cb_streamid)); -+ memset(&sidcounts, 0, sizeof(struct tsn_cb_streamid_counters)); -+ -+ if (!info->attrs[TSN_ATTR_STREAM_IDENTIFY]) -+ return -EINVAL; -+ -+ na = info->attrs[TSN_ATTR_STREAM_IDENTIFY]; -+ -+ ret = NLA_PARSE_NESTED(sid, TSN_STREAMID_ATTR_MAX, -+ na, cb_streamid_policy); -+ if (ret) -+ return -EINVAL; -+ -+ if (!sid[TSN_STREAMID_ATTR_INDEX]) -+ return -EINVAL; -+ -+ sid_index = nla_get_u32(sid[TSN_STREAMID_ATTR_INDEX]); -+ -+ if (!tsnops->cb_streamid_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ ret = -EINVAL; -+ goto exit; -+ } else { -+ valid = tsnops->cb_streamid_get(netdev, sid_index, &sidconf); -+ if (valid < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, valid); -+ return valid; -+ } -+ } -+ -+ /* send back */ -+ genlhdr = info->genlhdr; -+ ret = tsn_prepare_reply(info, genlhdr->cmd, &rep_skb, -+ NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ /* input netlink the parameters */ -+ sidattr = nla_nest_start_noflag(rep_skb, TSN_ATTR_STREAM_IDENTIFY); -+ if (!sidattr) { -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ if (nla_put_u32(rep_skb, TSN_STREAMID_ATTR_INDEX, sid_index)) -+ return -EMSGSIZE; -+ -+ if (valid == 1) { -+ nla_put_flag(rep_skb, TSN_STREAMID_ATTR_ENABLE); -+ } else if (valid == 0) { -+ nla_put_flag(rep_skb, TSN_STREAMID_ATTR_DISABLE); -+ } else { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ goto err; -+ } -+ -+ if (nla_put_s32(rep_skb, -+ TSN_STREAMID_ATTR_STREAM_HANDLE, sidconf.handle) || -+ nla_put_u32(rep_skb, TSN_STREAMID_ATTR_IFOP, sidconf.ifac_oport) || -+ nla_put_u32(rep_skb, TSN_STREAMID_ATTR_OFOP, sidconf.ofac_oport) || -+ nla_put_u32(rep_skb, TSN_STREAMID_ATTR_IFIP, sidconf.ifac_iport) || -+ nla_put_u32(rep_skb, TSN_STREAMID_ATTR_OFIP, sidconf.ofac_iport) || -+ nla_put_u8(rep_skb, TSN_STREAMID_ATTR_TYPE, sidconf.type)) -+ return -EMSGSIZE; -+ -+ switch (sidconf.type) { -+ case STREAMID_NULL: -+ if (NLA_PUT_U64(rep_skb, TSN_STREAMID_ATTR_NDMAC, -+ sidconf.para.nid.dmac) || -+ nla_put_u16(rep_skb, TSN_STREAMID_ATTR_NVID, -+ sidconf.para.nid.vid) || -+ nla_put_u8(rep_skb, TSN_STREAMID_ATTR_NTAGGED, -+ sidconf.para.nid.tagged)) -+ return -EMSGSIZE; -+ break; -+ case STREAMID_SMAC_VLAN: -+ if (NLA_PUT_U64(rep_skb, TSN_STREAMID_ATTR_SMAC, -+ sidconf.para.sid.smac) || -+ nla_put_u16(rep_skb, TSN_STREAMID_ATTR_SVID, -+ sidconf.para.sid.vid) || -+ nla_put_u8(rep_skb, TSN_STREAMID_ATTR_STAGGED, -+ sidconf.para.sid.tagged)) -+ return -EMSGSIZE; -+ break; -+ case STREAMID_DMAC_VLAN: -+ case STREAMID_IP: -+ default: -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ goto err; -+ } -+ -+ if (!tsnops->cb_streamid_counters_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ goto err; -+ } else { -+ ret = tsnops->cb_streamid_counters_get(netdev, -+ sid_index, -+ &sidcounts); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ goto err; -+ } -+ } -+ -+ if (NLA_PUT_U64(rep_skb, TSN_STREAMID_ATTR_COUNTERS_PSI, -+ sidcounts.per_stream.input) || -+ NLA_PUT_U64(rep_skb, TSN_STREAMID_ATTR_COUNTERS_PSO, -+ sidcounts.per_stream.output)) -+ return -EMSGSIZE; -+ -+ for (i = 0; i < 32; i++) { -+ if (NLA_PUT_U64(rep_skb, TSN_STREAMID_ATTR_COUNTERS_PSPPI, -+ sidcounts.per_streamport[i].input) || -+ NLA_PUT_U64(rep_skb, TSN_STREAMID_ATTR_COUNTERS_PSPPO, -+ sidcounts.per_streamport[i].output)) -+ return -EMSGSIZE; -+ } -+ -+ nla_nest_end(rep_skb, sidattr); -+ /* end netlink input the parameters */ -+ -+ /* netlink lib func */ -+ ret = nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name); -+ if (ret < 0) -+ goto err; -+ -+ ret = nla_put_s32(rep_skb, TSN_CMD_ATTR_DATA, 0); -+ if (ret < 0) -+ goto err; -+ -+ return tsn_send_reply(rep_skb, info); -+ -+err: -+ nlmsg_free(rep_skb); -+exit: -+ return ret; -+} -+ -+static int tsn_cb_streamid_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmd_cb_streamid_get(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int cmb_cb_streamid_counters_get(struct genl_info *info) -+{ -+ return 0; -+} -+ -+static int tsn_cb_streamid_counters_get(struct sk_buff *skb, -+ struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmb_cb_streamid_counters_get(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int tsn_qci_cap_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *qci_cap; -+ struct sk_buff *rep_skb; -+ int ret; -+ struct net_device *netdev; -+ struct genlmsghdr *genlhdr; -+ struct tsn_qci_psfp_stream_param qci_cap_status; -+ const struct tsn_ops *tsnops; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ tsnops = port->tsnops; -+ -+ genlhdr = info->genlhdr; -+ -+ memset(&qci_cap_status, 0, sizeof(qci_cap_status)); -+ -+ if (!tsnops->qci_get_maxcap) { -+ ret = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ ret = tsnops->qci_get_maxcap(netdev, &qci_cap_status); -+ if (ret < 0) -+ goto out; -+ -+ /* Pad netlink reply data */ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, -+ &rep_skb, NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ goto out; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) { -+ ret = -EMSGSIZE; -+ goto err; -+ } -+ -+ qci_cap = nla_nest_start_noflag(rep_skb, TSN_ATTR_QCI_SP); -+ if (!qci_cap) { -+ ret = -EMSGSIZE; -+ goto err; -+ } -+ -+ if (nla_put_u32(rep_skb, TSN_QCI_STREAM_ATTR_MAX_SFI, -+ qci_cap_status.max_sf_instance) || -+ nla_put_u32(rep_skb, TSN_QCI_STREAM_ATTR_MAX_SGI, -+ qci_cap_status.max_sg_instance) || -+ nla_put_u32(rep_skb, TSN_QCI_STREAM_ATTR_MAX_FMI, -+ qci_cap_status.max_fm_instance) || -+ nla_put_u32(rep_skb, TSN_QCI_STREAM_ATTR_SLM, -+ qci_cap_status.supported_list_max)) { -+ ret = -EMSGSIZE; -+ goto err; -+ } -+ -+ nla_nest_end(rep_skb, qci_cap); -+ -+ tsn_send_reply(rep_skb, info); -+ -+ return 0; -+err: -+ nlmsg_free(rep_skb); -+out: -+ if (ret < 0) -+ tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, ret); -+ -+ return ret; -+} -+ -+static int cmd_qci_sfi_set(struct genl_info *info) -+{ -+ struct nlattr *na, *sfi[TSN_QCI_SFI_ATTR_MAX + 1]; -+ u32 sfi_handle; -+ bool enable; -+ int ret; -+ struct net_device *netdev; -+ struct tsn_qci_psfp_sfi_conf sficonf; -+ const struct tsn_ops *tsnops; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ memset(&sficonf, 0, sizeof(struct tsn_qci_psfp_sfi_conf)); -+ -+ if (!info->attrs[TSN_ATTR_QCI_SFI]) -+ return -EINVAL; -+ -+ na = info->attrs[TSN_ATTR_QCI_SFI]; -+ -+ ret = NLA_PARSE_NESTED(sfi, TSN_QCI_SFI_ATTR_MAX, na, qci_sfi_policy); -+ if (ret) { -+ pr_info("tsn: parse value TSN_QCI_SFI_ATTR_MAX error."); -+ return -EINVAL; -+ } -+ -+ if (!sfi[TSN_QCI_SFI_ATTR_INDEX]) -+ return -EINVAL; -+ -+ sfi_handle = nla_get_u32(sfi[TSN_QCI_SFI_ATTR_INDEX]); -+ -+ if (sfi[TSN_QCI_SFI_ATTR_ENABLE]) { -+ enable = true; -+ } else if (sfi[TSN_QCI_SFI_ATTR_DISABLE]) { -+ enable = false; -+ goto loaddrive; -+ } else { -+ pr_err("tsn: must provde ENABLE or DISABLE attribute.\n"); -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ if (!sfi[TSN_QCI_SFI_ATTR_GATE_ID]) { -+ pr_err("tsn: must provide stream gate index\n"); -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ if (!sfi[TSN_QCI_SFI_ATTR_STREAM_HANDLE]) -+ sficonf.stream_handle_spec = -1; -+ else -+ sficonf.stream_handle_spec = -+ nla_get_s32(sfi[TSN_QCI_SFI_ATTR_STREAM_HANDLE]); -+ -+ if (!sfi[TSN_QCI_SFI_ATTR_PRIO_SPEC]) -+ sficonf.priority_spec = -1; -+ else -+ sficonf.priority_spec = -+ nla_get_s8(sfi[TSN_QCI_SFI_ATTR_PRIO_SPEC]); -+ -+ sficonf.stream_gate_instance_id = -+ nla_get_u32(sfi[TSN_QCI_SFI_ATTR_GATE_ID]); -+ -+ if (sfi[TSN_QCI_SFI_ATTR_MAXSDU]) -+ sficonf.stream_filter.maximum_sdu_size = -+ nla_get_u16(sfi[TSN_QCI_SFI_ATTR_MAXSDU]); -+ else -+ sficonf.stream_filter.maximum_sdu_size = 0; -+ -+ if (sfi[TSN_QCI_SFI_ATTR_FLOW_ID]) -+ sficonf.stream_filter.flow_meter_instance_id = -+ nla_get_s32(sfi[TSN_QCI_SFI_ATTR_FLOW_ID]); -+ else -+ sficonf.stream_filter.flow_meter_instance_id = -1; -+ -+ if (sfi[TSN_QCI_SFI_ATTR_OVERSIZE_ENABLE]) -+ sficonf.block_oversize_enable = true; -+ -+ if (sfi[TSN_QCI_SFI_ATTR_OVERSIZE]) -+ sficonf.block_oversize = true; -+ -+loaddrive: -+ if (!tsnops->qci_sfi_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -EINVAL; -+ } -+ -+ ret = tsnops->qci_sfi_set(netdev, sfi_handle, enable, &sficonf); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, ret); -+ return ret; -+ } -+ -+ ret = tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, 0); -+ -+ if (ret) -+ return ret; -+ return 0; -+} -+ -+static int tsn_qci_sfi_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmd_qci_sfi_set(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int cmd_qci_sfi_get(struct genl_info *info) -+{ -+ struct nlattr *na, *sfiattr; -+ struct nlattr *sfi[TSN_QCI_SFI_ATTR_MAX + 1]; -+ u32 sfi_handle; -+ struct sk_buff *rep_skb; -+ int ret, valid = 0; -+ struct net_device *netdev; -+ struct genlmsghdr *genlhdr; -+ struct tsn_qci_psfp_sfi_conf sficonf; -+ struct tsn_qci_psfp_sfi_counters sficount; -+ const struct tsn_ops *tsnops; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ genlhdr = info->genlhdr; -+ -+ if (!info->attrs[TSN_ATTR_QCI_SFI]) -+ return -EINVAL; -+ -+ na = info->attrs[TSN_ATTR_QCI_SFI]; -+ -+ ret = NLA_PARSE_NESTED(sfi, TSN_QCI_SFI_ATTR_MAX, -+ na, qci_sfi_policy); -+ if (ret) -+ return -EINVAL; -+ -+ if (!sfi[TSN_QCI_SFI_ATTR_INDEX]) -+ return -EINVAL; -+ -+ sfi_handle = nla_get_u32(sfi[TSN_QCI_SFI_ATTR_INDEX]); -+ -+ memset(&sficonf, 0, sizeof(struct tsn_qci_psfp_sfi_conf)); -+ memset(&sficount, 0, sizeof(struct tsn_qci_psfp_sfi_counters)); -+ -+ if (!tsnops->qci_sfi_get || !tsnops->qci_sfi_counters_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ ret = -EINVAL; -+ goto exit; -+ } else { -+ valid = tsnops->qci_sfi_get(netdev, sfi_handle, &sficonf); -+ if (valid < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, valid); -+ return valid; -+ } -+ -+ valid = tsnops->qci_sfi_counters_get(netdev, sfi_handle, -+ &sficount); -+ if (valid < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, valid); -+ return valid; -+ } -+ } -+ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, -+ &rep_skb, NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) -+ goto err; -+ -+ sfiattr = nla_nest_start_noflag(rep_skb, TSN_ATTR_QCI_SFI); -+ if (!sfiattr) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ if (nla_put_u32(rep_skb, TSN_QCI_SFI_ATTR_INDEX, sfi_handle)) -+ return -EMSGSIZE; -+ -+ if (valid) { -+ if (nla_put_flag(rep_skb, TSN_QCI_SFI_ATTR_ENABLE)) -+ return -EMSGSIZE; -+ } else { -+ if (nla_put_flag(rep_skb, TSN_QCI_SFI_ATTR_DISABLE)) -+ return -EMSGSIZE; -+ } -+ -+ if (nla_put_s32(rep_skb, TSN_QCI_SFI_ATTR_STREAM_HANDLE, -+ sficonf.stream_handle_spec) || -+ nla_put_s8(rep_skb, TSN_QCI_SFI_ATTR_PRIO_SPEC, -+ sficonf.priority_spec) || -+ nla_put_u32(rep_skb, TSN_QCI_SFI_ATTR_GATE_ID, -+ sficonf.stream_gate_instance_id)) -+ return -EMSGSIZE; -+ -+ if (sficonf.stream_filter.maximum_sdu_size) -+ if (nla_put_u16(rep_skb, TSN_QCI_SFI_ATTR_MAXSDU, -+ sficonf.stream_filter.maximum_sdu_size)) -+ return -EMSGSIZE; -+ -+ if (sficonf.stream_filter.flow_meter_instance_id >= 0) -+ if (nla_put_s32(rep_skb, TSN_QCI_SFI_ATTR_FLOW_ID, -+ sficonf.stream_filter.flow_meter_instance_id)) -+ return -EMSGSIZE; -+ -+ if (sficonf.block_oversize_enable) -+ if (nla_put_flag(rep_skb, TSN_QCI_SFI_ATTR_OVERSIZE_ENABLE)) -+ return -EMSGSIZE; -+ if (sficonf.block_oversize) -+ if (nla_put_flag(rep_skb, TSN_QCI_SFI_ATTR_OVERSIZE)) -+ return -EMSGSIZE; -+ -+ if (nla_put(rep_skb, TSN_QCI_SFI_ATTR_COUNTERS, -+ sizeof(struct tsn_qci_psfp_sfi_counters), &sficount)) -+ return -EMSGSIZE; -+ -+ nla_nest_end(rep_skb, sfiattr); -+ -+ return tsn_send_reply(rep_skb, info); -+err: -+ nlmsg_free(rep_skb); -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+exit: -+ return ret; -+} -+ -+static int tsn_qci_sfi_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmd_qci_sfi_get(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int cmd_qci_sfi_counters_get(struct genl_info *info) -+{ -+ struct nlattr *na, *sfiattr; -+ struct nlattr *sfi[TSN_QCI_SFI_ATTR_MAX + 1]; -+ u32 sfi_handle; -+ struct sk_buff *rep_skb; -+ int ret; -+ struct net_device *netdev; -+ struct genlmsghdr *genlhdr; -+ struct tsn_qci_psfp_sfi_counters sficount; -+ const struct tsn_ops *tsnops; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ genlhdr = info->genlhdr; -+ -+ if (!info->attrs[TSN_ATTR_QCI_SFI]) -+ return -EINVAL; -+ -+ na = info->attrs[TSN_ATTR_QCI_SFI]; -+ -+ ret = NLA_PARSE_NESTED(sfi, TSN_QCI_SFI_ATTR_MAX, -+ na, qci_sfi_policy); -+ if (ret) -+ return -EINVAL; -+ -+ if (!sfi[TSN_QCI_SFI_ATTR_INDEX]) -+ return -EINVAL; -+ -+ sfi_handle = nla_get_u32(sfi[TSN_QCI_SFI_ATTR_INDEX]); -+ -+ memset(&sficount, 0, sizeof(struct tsn_qci_psfp_sfi_counters)); -+ if (!tsnops->qci_sfi_counters_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ ret = tsnops->qci_sfi_counters_get(netdev, sfi_handle, &sficount); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, &rep_skb, -+ NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) -+ goto err; -+ -+ sfiattr = nla_nest_start_noflag(rep_skb, TSN_ATTR_QCI_SFI); -+ if (!sfiattr) { -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ if (nla_put_u32(rep_skb, TSN_QCI_SFI_ATTR_INDEX, sfi_handle)) -+ return -EMSGSIZE; -+ -+ ret = tsnops->qci_sfi_counters_get(netdev, sfi_handle, &sficount); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, ret); -+ return ret; -+ } -+ -+ if (nla_put(rep_skb, TSN_QCI_SFI_ATTR_COUNTERS, -+ sizeof(struct tsn_qci_psfp_sfi_counters), &sficount)) -+ return -EMSGSIZE; -+ -+ nla_nest_end(rep_skb, sfiattr); -+ -+ return tsn_send_reply(rep_skb, info); -+err: -+ nlmsg_free(rep_skb); -+ tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, -EINVAL); -+ return ret; -+} -+ -+static int tsn_qci_sfi_counters_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmd_qci_sfi_counters_get(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int cmd_qci_sgi_set(struct genl_info *info) -+{ -+ struct nlattr *na; -+ struct nlattr *sgia[TSN_QCI_SGI_ATTR_MAX + 1]; -+ struct nlattr *admin[TSN_SGI_ATTR_CTRL_MAX + 1]; -+ int ret = 0; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ struct tsn_qci_psfp_sgi_conf sgi; -+ struct tsn_qci_psfp_gcl *gcl = NULL; -+ u16 sgi_handle = 0; -+ u16 listcount = 0; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ memset(&sgi, 0, sizeof(struct tsn_qci_psfp_sgi_conf)); -+ -+ if (!info->attrs[TSN_ATTR_QCI_SGI]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ na = info->attrs[TSN_ATTR_QCI_SGI]; -+ -+ ret = NLA_PARSE_NESTED(sgia, TSN_QCI_SGI_ATTR_MAX, -+ na, qci_sgi_policy); -+ if (ret) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ if (sgia[TSN_QCI_SGI_ATTR_ENABLE] && sgia[TSN_QCI_SGI_ATTR_DISABLE]) { -+ pr_err("tsn: enable or disable?\n"); -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -1; -+ } -+ -+ if (sgia[TSN_QCI_SGI_ATTR_INDEX]) -+ sgi_handle = nla_get_u32(sgia[TSN_QCI_SGI_ATTR_INDEX]); -+ -+ if (sgia[TSN_QCI_SGI_ATTR_DISABLE]) { -+ sgi.gate_enabled = 0; -+ goto loaddev; -+ } else { -+ /* set default to be enable*/ -+ sgi.gate_enabled = 1; -+ } -+ -+ if (sgia[TSN_QCI_SGI_ATTR_CONFCHANGE]) -+ sgi.config_change = 1; -+ -+ if (sgia[TSN_QCI_SGI_ATTR_IRXEN]) -+ sgi.block_invalid_rx_enable = 1; -+ -+ if (sgia[TSN_QCI_SGI_ATTR_IRX]) -+ sgi.block_invalid_rx = 1; -+ -+ if (sgia[TSN_QCI_SGI_ATTR_OEXEN]) -+ sgi.block_octets_exceeded_enable = 1; -+ -+ if (sgia[TSN_QCI_SGI_ATTR_OEX]) -+ sgi.block_octets_exceeded = 1; -+ -+ if (sgia[TSN_QCI_SGI_ATTR_ADMINENTRY]) { -+ struct nlattr *entry; -+ int rem; -+ int count = 0; -+ -+ na = sgia[TSN_QCI_SGI_ATTR_ADMINENTRY]; -+ ret = NLA_PARSE_NESTED(admin, TSN_SGI_ATTR_CTRL_MAX, -+ na, qci_sgi_ctrl_policy); -+ -+ /* Other parameters in admin control */ -+ if (admin[TSN_SGI_ATTR_CTRL_INITSTATE]) -+ sgi.admin.gate_states = 1; -+ -+ if (admin[TSN_SGI_ATTR_CTRL_CYTIME]) -+ sgi.admin.cycle_time = -+ nla_get_u32(admin[TSN_SGI_ATTR_CTRL_CYTIME]); -+ -+ if (admin[TSN_SGI_ATTR_CTRL_CYTIMEEX]) -+ sgi.admin.cycle_time_extension = -+ nla_get_u32(admin[TSN_SGI_ATTR_CTRL_CYTIMEEX]); -+ -+ if (admin[TSN_SGI_ATTR_CTRL_BTIME]) -+ sgi.admin.base_time = -+ nla_get_u64(admin[TSN_SGI_ATTR_CTRL_BTIME]); -+ -+ if (admin[TSN_SGI_ATTR_CTRL_INITIPV]) -+ sgi.admin.init_ipv = -+ nla_get_s8(admin[TSN_SGI_ATTR_CTRL_INITIPV]); -+ else -+ sgi.admin.init_ipv = -1; -+ -+ if (admin[TSN_SGI_ATTR_CTRL_LEN]) { -+ sgi.admin.control_list_length = -+ nla_get_u8(admin[TSN_SGI_ATTR_CTRL_LEN]); -+ listcount = sgi.admin.control_list_length; -+ } -+ -+ if (!listcount) -+ goto loaddev; -+ -+ gcl = kmalloc_array(listcount, sizeof(*gcl), GFP_KERNEL); -+ -+ memset(gcl, 0, listcount * sizeof(struct tsn_qci_psfp_gcl)); -+ -+ /* Check the whole admin attrs, -+ * checkout the TSN_SGI_ATTR_CTRL_GCLENTRY attributes -+ */ -+ nla_for_each_nested(entry, na, rem) { -+ struct nlattr *gcl_entry[TSN_SGI_ATTR_GCL_MAX + 1]; -+ struct nlattr *ti, *om; -+ -+ if (nla_type(entry) != TSN_SGI_ATTR_CTRL_GCLENTRY) -+ continue; -+ -+ /* parse each TSN_SGI_ATTR_CTRL_GCLENTRY */ -+ ret = NLA_PARSE_NESTED(gcl_entry, TSN_SGI_ATTR_GCL_MAX, -+ entry, qci_sgi_gcl_policy); -+ /* Parse gate control list */ -+ if (gcl_entry[TSN_SGI_ATTR_GCL_GATESTATE]) -+ (gcl + count)->gate_state = 1; -+ -+ if (gcl_entry[TSN_SGI_ATTR_GCL_IPV]) -+ (gcl + count)->ipv = -+ nla_get_s8(gcl_entry[TSN_SGI_ATTR_GCL_IPV]); -+ -+ if (gcl_entry[TSN_SGI_ATTR_GCL_INTERVAL]) { -+ ti = gcl_entry[TSN_SGI_ATTR_GCL_INTERVAL]; -+ (gcl + count)->time_interval = nla_get_u32(ti); -+ } -+ -+ if (gcl_entry[TSN_SGI_ATTR_GCL_OCTMAX]) { -+ om = gcl_entry[TSN_SGI_ATTR_GCL_OCTMAX]; -+ (gcl + count)->octet_max = nla_get_u32(om); -+ } -+ -+ count++; -+ -+ if (count >= listcount) -+ break; -+ } -+ -+ if (count < listcount) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ pr_err("tsn: count less than TSN_SGI_ATTR_CTRL_LEN\n"); -+ kfree(gcl); -+ return -EINVAL; -+ } -+ -+ } else { -+ pr_info("tsn: no admin list parameters setting\n"); -+ } -+ -+loaddev: -+ if (!tsnops->qci_sgi_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ kfree(gcl); -+ return -EINVAL; -+ } -+ -+ sgi.admin.gcl = gcl; -+ -+ ret = tsnops->qci_sgi_set(netdev, sgi_handle, &sgi); -+ kfree(gcl); -+ if (!ret) -+ return tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, 0); -+ -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+} -+ -+static int tsn_qci_sgi_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmd_qci_sgi_set(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int cmd_qci_sgi_get(struct genl_info *info) -+{ -+ struct nlattr *na, *sgiattr, *adminattr, *sglattr; -+ struct nlattr *sgi[TSN_QCI_SGI_ATTR_MAX + 1]; -+ struct sk_buff *rep_skb; -+ int ret; -+ struct net_device *netdev; -+ struct genlmsghdr *genlhdr; -+ struct tsn_qci_psfp_sgi_conf sgiadmin; -+ struct tsn_qci_psfp_gcl *gcl = NULL; -+ const struct tsn_ops *tsnops; -+ u16 sgi_handle; -+ u8 listcount, i; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ if (!info->attrs[TSN_ATTR_QCI_SGI]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ pr_err("tsn: no sgi handle input\n"); -+ return -EINVAL; -+ } -+ -+ na = info->attrs[TSN_ATTR_QCI_SGI]; -+ -+ ret = NLA_PARSE_NESTED(sgi, TSN_QCI_SGI_ATTR_MAX, -+ na, qci_sgi_policy); -+ if (ret) -+ return -EINVAL; -+ -+ if (!sgi[TSN_QCI_SGI_ATTR_INDEX]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ pr_err("tsn: no sgi handle input\n"); -+ return -EINVAL; -+ } -+ -+ sgi_handle = nla_get_u32(sgi[TSN_QCI_SGI_ATTR_INDEX]); -+ -+ /* Get config data from device */ -+ genlhdr = info->genlhdr; -+ -+ memset(&sgiadmin, 0, sizeof(struct tsn_qci_psfp_sgi_conf)); -+ -+ if (!tsnops->qci_sgi_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ ret = tsnops->qci_sgi_get(netdev, sgi_handle, &sgiadmin); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ /* Form netlink reply data */ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, -+ &rep_skb, NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) -+ return -EMSGSIZE; -+ -+ sgiattr = nla_nest_start_noflag(rep_skb, TSN_ATTR_QCI_SGI); -+ if (!sgiattr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u32(rep_skb, TSN_QCI_SGI_ATTR_INDEX, sgi_handle)) -+ return -EMSGSIZE; -+ -+ /* Gate enable? sgiadmin.gate_enabled */ -+ if (sgiadmin.gate_enabled) { -+ if (nla_put_flag(rep_skb, TSN_QCI_SGI_ATTR_ENABLE)) -+ return -EMSGSIZE; -+ } else { -+ if (nla_put_flag(rep_skb, TSN_QCI_SGI_ATTR_DISABLE)) -+ return -EMSGSIZE; -+ } -+ -+ if (sgiadmin.config_change) -+ if (nla_put_flag(rep_skb, TSN_QCI_SGI_ATTR_CONFCHANGE)) -+ return -EMSGSIZE; -+ -+ if (sgiadmin.block_invalid_rx_enable) -+ if (nla_put_flag(rep_skb, TSN_QCI_SGI_ATTR_IRXEN)) -+ return -EMSGSIZE; -+ -+ if (sgiadmin.block_invalid_rx) -+ if (nla_put_flag(rep_skb, TSN_QCI_SGI_ATTR_IRX)) -+ return -EMSGSIZE; -+ -+ if (sgiadmin.block_octets_exceeded_enable) -+ if (nla_put_flag(rep_skb, TSN_QCI_SGI_ATTR_OEXEN)) -+ return -EMSGSIZE; -+ -+ if (sgiadmin.block_octets_exceeded) -+ if (nla_put_flag(rep_skb, TSN_QCI_SGI_ATTR_OEX)) -+ return -EMSGSIZE; -+ -+ /* Administration */ -+ adminattr = nla_nest_start_noflag(rep_skb, TSN_QCI_SGI_ATTR_ADMINENTRY); -+ if (!adminattr) -+ return -EMSGSIZE; -+ -+ if (sgiadmin.admin.gate_states) -+ if (nla_put_flag(rep_skb, TSN_SGI_ATTR_CTRL_INITSTATE)) -+ return -EMSGSIZE; -+ -+ if (nla_put_u32(rep_skb, TSN_SGI_ATTR_CTRL_CYTIME, -+ sgiadmin.admin.cycle_time) || -+ nla_put_u32(rep_skb, TSN_SGI_ATTR_CTRL_CYTIMEEX, -+ sgiadmin.admin.cycle_time_extension) || -+ NLA_PUT_U64(rep_skb, TSN_SGI_ATTR_CTRL_BTIME, -+ sgiadmin.admin.base_time) || -+ nla_put_u8(rep_skb, TSN_SGI_ATTR_CTRL_INITIPV, -+ sgiadmin.admin.init_ipv)) -+ return -EMSGSIZE; -+ -+ listcount = sgiadmin.admin.control_list_length; -+ if (!listcount) -+ goto out1; -+ -+ if (!sgiadmin.admin.gcl) { -+ pr_err("error: no gate control list\n"); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ gcl = sgiadmin.admin.gcl; -+ -+ /* loop list */ -+ for (i = 0; i < listcount; i++) { -+ s8 ipv; -+ u32 ti, omax; -+ -+ if (!(gcl + i)) { -+ pr_err("error: list count too big\n"); -+ ret = -EINVAL; -+ kfree(sgiadmin.admin.gcl); -+ goto err; -+ } -+ -+ /* Adminastration entry */ -+ sglattr = nla_nest_start_noflag(rep_skb, -+ TSN_SGI_ATTR_CTRL_GCLENTRY); -+ if (!sglattr) -+ return -EMSGSIZE; -+ ipv = (gcl + i)->ipv; -+ ti = (gcl + i)->time_interval; -+ omax = (gcl + i)->octet_max; -+ -+ if ((gcl + i)->gate_state) -+ if (nla_put_flag(rep_skb, TSN_SGI_ATTR_GCL_GATESTATE)) -+ return -EMSGSIZE; -+ -+ if (nla_put_s8(rep_skb, TSN_SGI_ATTR_GCL_IPV, ipv) || -+ nla_put_u32(rep_skb, TSN_SGI_ATTR_GCL_INTERVAL, ti) || -+ nla_put_u32(rep_skb, TSN_SGI_ATTR_GCL_OCTMAX, omax)) -+ return -EMSGSIZE; -+ -+ /* End administration entry */ -+ nla_nest_end(rep_skb, sglattr); -+ } -+ -+ kfree(sgiadmin.admin.gcl); -+ if (nla_put_u8(rep_skb, TSN_SGI_ATTR_CTRL_LEN, listcount)) -+ return -EMSGSIZE; -+ -+out1: -+ /* End adminastration */ -+ nla_nest_end(rep_skb, adminattr); -+ -+ nla_nest_end(rep_skb, sgiattr); -+ -+ return tsn_send_reply(rep_skb, info); -+err: -+ nlmsg_free(rep_skb); -+ tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, ret); -+ return ret; -+} -+ -+static int tsn_qci_sgi_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmd_qci_sgi_get(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int cmd_qci_sgi_status_get(struct genl_info *info) -+{ -+ struct nlattr *na, *sgiattr, *operattr, *sglattr; -+ struct nlattr *sgi[TSN_QCI_SGI_ATTR_MAX + 1]; -+ struct sk_buff *rep_skb; -+ int ret; -+ struct net_device *netdev; -+ struct genlmsghdr *genlhdr; -+ struct tsn_psfp_sgi_status sgistat; -+ struct tsn_qci_psfp_gcl *gcl = NULL; -+ const struct tsn_ops *tsnops; -+ u16 sgi_handle; -+ u8 listcount; -+ int valid, i; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ if (!info->attrs[TSN_ATTR_QCI_SGI]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ pr_err("tsn: no sgi handle input\n"); -+ return -EINVAL; -+ } -+ -+ na = info->attrs[TSN_ATTR_QCI_SGI]; -+ -+ ret = NLA_PARSE_NESTED(sgi, TSN_QCI_SGI_ATTR_MAX, -+ na, qci_sgi_policy); -+ if (ret) -+ return -EINVAL; -+ -+ if (!sgi[TSN_QCI_SGI_ATTR_INDEX]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ pr_err("tsn: no sgi handle input\n"); -+ return -EINVAL; -+ } -+ -+ sgi_handle = nla_get_u32(sgi[TSN_QCI_SGI_ATTR_INDEX]); -+ -+ /* Get status data from device */ -+ genlhdr = info->genlhdr; -+ -+ memset(&sgistat, 0, sizeof(struct tsn_psfp_sgi_status)); -+ -+ if (!tsnops->qci_sgi_status_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ valid = tsnops->qci_sgi_status_get(netdev, sgi_handle, &sgistat); -+ if (valid < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, valid); -+ return valid; -+ } -+ -+ /* Form netlink reply data */ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, -+ &rep_skb, NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) -+ return -EMSGSIZE; -+ -+ /* Down one netlink attribute level */ -+ sgiattr = nla_nest_start_noflag(rep_skb, TSN_ATTR_QCI_SGI); -+ if (!sgiattr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u32(rep_skb, TSN_QCI_SGI_ATTR_INDEX, sgi_handle)) -+ return -EMSGSIZE; -+ -+ /* Gate enable */ -+ if (valid == 1) { -+ if (nla_put_flag(rep_skb, TSN_QCI_SGI_ATTR_ENABLE)) -+ return -EMSGSIZE; -+ } else { -+ if (nla_put_flag(rep_skb, TSN_QCI_SGI_ATTR_DISABLE)) -+ return -EMSGSIZE; -+ } -+ -+ if (nla_put_u32(rep_skb, TSN_QCI_SGI_ATTR_TICKG, -+ sgistat.tick_granularity) || -+ NLA_PUT_U64(rep_skb, TSN_QCI_SGI_ATTR_CCTIME, -+ sgistat.config_change_time) || -+ NLA_PUT_U64(rep_skb, TSN_QCI_SGI_ATTR_CUTIME, -+ sgistat.current_time) || -+ NLA_PUT_U64(rep_skb, TSN_QCI_SGI_ATTR_CCERROR, -+ sgistat.config_change_error)) -+ return -EMSGSIZE; -+ -+ if (sgistat.config_pending) -+ if (nla_put_flag(rep_skb, TSN_QCI_SGI_ATTR_CPENDING)) -+ return -EMSGSIZE; -+ -+ /* operation data */ -+ operattr = nla_nest_start_noflag(rep_skb, TSN_QCI_SGI_ATTR_OPERENTRY); -+ if (!operattr) -+ return -EMSGSIZE; -+ -+ if (sgistat.oper.gate_states) -+ if (nla_put_flag(rep_skb, TSN_SGI_ATTR_CTRL_INITSTATE)) -+ return -EMSGSIZE; -+ -+ if (nla_put_u32(rep_skb, TSN_SGI_ATTR_CTRL_CYTIME, -+ sgistat.oper.cycle_time) || -+ nla_put_u32(rep_skb, TSN_SGI_ATTR_CTRL_CYTIMEEX, -+ sgistat.oper.cycle_time_extension) || -+ NLA_PUT_U64(rep_skb, TSN_SGI_ATTR_CTRL_BTIME, -+ sgistat.oper.base_time) || -+ nla_put_u8(rep_skb, TSN_SGI_ATTR_CTRL_INITIPV, -+ sgistat.oper.init_ipv)) -+ return -EMSGSIZE; -+ -+ /* Loop list */ -+ listcount = sgistat.oper.control_list_length; -+ if (!listcount) -+ goto out1; -+ -+ if (!sgistat.oper.gcl) { -+ pr_err("error: list lenghth is not zero!\n"); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ gcl = sgistat.oper.gcl; -+ -+ /* loop list */ -+ for (i = 0; i < listcount; i++) { -+ s8 ipv; -+ u32 ti, omax; -+ -+ if (!(gcl + i)) { -+ pr_err("error: list count too big\n"); -+ ret = -EINVAL; -+ kfree(sgistat.oper.gcl); -+ goto err; -+ } -+ -+ /* Operation entry */ -+ sglattr = nla_nest_start_noflag(rep_skb, -+ TSN_SGI_ATTR_CTRL_GCLENTRY); -+ if (!sglattr) -+ return -EMSGSIZE; -+ ipv = (gcl + i)->ipv; -+ ti = (gcl + i)->time_interval; -+ omax = (gcl + i)->octet_max; -+ -+ if ((gcl + i)->gate_state) -+ if (nla_put_flag(rep_skb, TSN_SGI_ATTR_GCL_GATESTATE)) -+ return -EMSGSIZE; -+ -+ if (nla_put_s8(rep_skb, TSN_SGI_ATTR_GCL_IPV, ipv) || -+ nla_put_u32(rep_skb, TSN_SGI_ATTR_GCL_INTERVAL, ti) || -+ nla_put_u32(rep_skb, TSN_SGI_ATTR_GCL_OCTMAX, omax)) -+ return -EMSGSIZE; -+ -+ /* End operation entry */ -+ nla_nest_end(rep_skb, sglattr); -+ } -+ -+ kfree(sgistat.oper.gcl); -+ if (nla_put_u8(rep_skb, TSN_SGI_ATTR_CTRL_LEN, listcount)) -+ return -EMSGSIZE; -+out1: -+ /* End operation */ -+ nla_nest_end(rep_skb, operattr); -+ -+ nla_nest_end(rep_skb, sgiattr); -+ -+ return tsn_send_reply(rep_skb, info); -+err: -+ nlmsg_free(rep_skb); -+ tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, ret); -+ return ret; -+} -+ -+static int tsn_qci_sgi_status_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmd_qci_sgi_status_get(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int cmd_qci_fmi_set(struct genl_info *info) -+{ -+ struct nlattr *na, *fmi[TSN_QCI_FMI_ATTR_MAX + 1]; -+ u32 index; -+ int ret; -+ struct net_device *netdev; -+ struct tsn_qci_psfp_fmi fmiconf; -+ const struct tsn_ops *tsnops; -+ bool enable = 0; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ memset(&fmiconf, 0, sizeof(struct tsn_qci_psfp_fmi)); -+ -+ if (!info->attrs[TSN_ATTR_QCI_FMI]) -+ return -EINVAL; -+ -+ na = info->attrs[TSN_ATTR_QCI_FMI]; -+ -+ ret = NLA_PARSE_NESTED(fmi, TSN_QCI_FMI_ATTR_MAX, na, qci_fmi_policy); -+ if (ret) { -+ pr_info("tsn: parse value TSN_QCI_FMI_ATTR_MAX error."); -+ return -EINVAL; -+ } -+ -+ if (!fmi[TSN_QCI_FMI_ATTR_INDEX]) -+ return -EINVAL; -+ -+ index = nla_get_u32(fmi[TSN_QCI_FMI_ATTR_INDEX]); -+ -+ if (fmi[TSN_QCI_FMI_ATTR_DISABLE]) -+ goto loaddev; -+ -+ enable = 1; -+ -+ if (fmi[TSN_QCI_FMI_ATTR_CIR]) -+ fmiconf.cir = nla_get_u32(fmi[TSN_QCI_FMI_ATTR_CIR]); -+ -+ if (fmi[TSN_QCI_FMI_ATTR_CBS]) -+ fmiconf.cbs = nla_get_u32(fmi[TSN_QCI_FMI_ATTR_CBS]); -+ -+ if (fmi[TSN_QCI_FMI_ATTR_EIR]) -+ fmiconf.eir = nla_get_u32(fmi[TSN_QCI_FMI_ATTR_EIR]); -+ -+ if (fmi[TSN_QCI_FMI_ATTR_EBS]) -+ fmiconf.ebs = nla_get_u32(fmi[TSN_QCI_FMI_ATTR_EBS]); -+ -+ if (fmi[TSN_QCI_FMI_ATTR_CF]) -+ fmiconf.cf = 1; -+ -+ if (fmi[TSN_QCI_FMI_ATTR_CM]) -+ fmiconf.cm = 1; -+ -+ if (fmi[TSN_QCI_FMI_ATTR_DROPYL]) -+ fmiconf.drop_on_yellow = 1; -+ -+ if (fmi[TSN_QCI_FMI_ATTR_MAREDEN]) -+ fmiconf.mark_red_enable = 1; -+ -+ if (fmi[TSN_QCI_FMI_ATTR_MARED]) -+ fmiconf.mark_red = 1; -+ -+loaddev: -+ -+ if (!tsnops->qci_fmi_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -EINVAL; -+ } -+ -+ ret = tsnops->qci_fmi_set(netdev, index, enable, &fmiconf); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, ret); -+ return ret; -+ } -+ -+ ret = tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, 0); -+ -+ if (ret) -+ return ret; -+ return 0; -+} -+ -+static int tsn_qci_fmi_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmd_qci_fmi_set(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int cmd_qci_fmi_get(struct genl_info *info) -+{ -+ struct nlattr *na, *fmi[TSN_QCI_FMI_ATTR_MAX + 1], *fmiattr; -+ u32 index; -+ struct sk_buff *rep_skb; -+ int ret; -+ struct net_device *netdev; -+ struct tsn_qci_psfp_fmi fmiconf; -+ struct tsn_qci_psfp_fmi_counters counters; -+ const struct tsn_ops *tsnops; -+ struct genlmsghdr *genlhdr; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ if (!info->attrs[TSN_ATTR_QCI_FMI]) -+ return -EINVAL; -+ -+ na = info->attrs[TSN_ATTR_QCI_FMI]; -+ -+ ret = NLA_PARSE_NESTED(fmi, TSN_QCI_FMI_ATTR_MAX, -+ na, qci_fmi_policy); -+ if (ret) { -+ pr_info("tsn: parse value TSN_QCI_FMI_ATTR_MAX error."); -+ return -EINVAL; -+ } -+ -+ if (!fmi[TSN_QCI_FMI_ATTR_INDEX]) -+ return -EINVAL; -+ -+ index = nla_get_u32(fmi[TSN_QCI_FMI_ATTR_INDEX]); -+ -+ /* Get data from device */ -+ memset(&fmiconf, 0, sizeof(struct tsn_qci_psfp_fmi)); -+ memset(&counters, 0, sizeof(struct tsn_qci_psfp_fmi_counters)); -+ -+ if (!tsnops->qci_fmi_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -EINVAL; -+ } -+ -+ ret = tsnops->qci_fmi_get(netdev, index, &fmiconf, &counters); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, netdev->name, ret); -+ return ret; -+ } -+ -+ genlhdr = info->genlhdr; -+ -+ /* Form netlink reply data */ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, -+ &rep_skb, NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) -+ return -EMSGSIZE; -+ -+ fmiattr = nla_nest_start_noflag(rep_skb, TSN_ATTR_QCI_FMI); -+ if (!fmiattr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u32(rep_skb, TSN_QCI_FMI_ATTR_INDEX, index) || -+ nla_put_u32(rep_skb, TSN_QCI_FMI_ATTR_CIR, fmiconf.cir) || -+ nla_put_u32(rep_skb, TSN_QCI_FMI_ATTR_CBS, fmiconf.cbs) || -+ nla_put_u32(rep_skb, TSN_QCI_FMI_ATTR_EIR, fmiconf.eir) || -+ nla_put_u32(rep_skb, TSN_QCI_FMI_ATTR_EBS, fmiconf.ebs)) -+ return -EMSGSIZE; -+ -+ if (fmiconf.cf) -+ if (nla_put_flag(rep_skb, TSN_QCI_FMI_ATTR_CF)) -+ return -EMSGSIZE; -+ -+ if (fmiconf.cm) -+ if (nla_put_flag(rep_skb, TSN_QCI_FMI_ATTR_CM)) -+ return -EMSGSIZE; -+ -+ if (fmiconf.drop_on_yellow) -+ if (nla_put_flag(rep_skb, TSN_QCI_FMI_ATTR_DROPYL)) -+ return -EMSGSIZE; -+ -+ if (fmiconf.mark_red_enable) -+ if (nla_put_flag(rep_skb, TSN_QCI_FMI_ATTR_MAREDEN)) -+ return -EMSGSIZE; -+ -+ if (fmiconf.mark_red) -+ if (nla_put_flag(rep_skb, TSN_QCI_FMI_ATTR_MAREDEN)) -+ return -EMSGSIZE; -+ -+ if (nla_put(rep_skb, TSN_QCI_FMI_ATTR_COUNTERS, -+ sizeof(struct tsn_qci_psfp_fmi_counters), &counters)) -+ return -EMSGSIZE; -+ -+ nla_nest_end(rep_skb, fmiattr); -+ -+ tsn_send_reply(rep_skb, info); -+ -+ return 0; -+} -+ -+static int tsn_qci_fmi_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmd_qci_fmi_get(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int cmd_qbv_set(struct genl_info *info) -+{ -+ struct nlattr *na, *na1; -+ struct nlattr *qbv_table; -+ struct nlattr *qbv[TSN_QBV_ATTR_MAX + 1]; -+ struct nlattr *qbvctrl[TSN_QBV_ATTR_CTRL_MAX + 1]; -+ int rem; -+ int ret = 0; -+ struct net_device *netdev; -+ struct tsn_qbv_conf qbvconfig; -+ const struct tsn_ops *tsnops; -+ struct tsn_qbv_entry *gatelist = NULL; -+ int count = 0; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ memset(&qbvconfig, 0, sizeof(struct tsn_qbv_conf)); -+ -+ if (!info->attrs[TSN_ATTR_QBV]) -+ return -EINVAL; -+ -+ na = info->attrs[TSN_ATTR_QBV]; -+ -+ ret = NLA_PARSE_NESTED(qbv, TSN_QBV_ATTR_MAX, na, qbv_policy); -+ if (ret) -+ return -EINVAL; -+ -+ if (qbv[TSN_QBV_ATTR_ENABLE]) -+ qbvconfig.gate_enabled = 1; -+ else -+ goto setdrive; -+ -+ if (qbv[TSN_QBV_ATTR_CONFIGCHANGE]) -+ qbvconfig.config_change = 1; -+ -+ if (!qbv[TSN_QBV_ATTR_ADMINENTRY]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -1; -+ } -+ -+ na1 = qbv[TSN_QBV_ATTR_ADMINENTRY]; -+ NLA_PARSE_NESTED(qbvctrl, TSN_QBV_ATTR_CTRL_MAX, -+ na1, qbv_ctrl_policy); -+ -+ if (qbvctrl[TSN_QBV_ATTR_CTRL_CYCLETIME]) { -+ qbvconfig.admin.cycle_time = -+ nla_get_u32(qbvctrl[TSN_QBV_ATTR_CTRL_CYCLETIME]); -+ } -+ -+ if (qbvctrl[TSN_QBV_ATTR_CTRL_CYCLETIMEEXT]) { -+ qbvconfig.admin.cycle_time_extension = -+ nla_get_u32(qbvctrl[TSN_QBV_ATTR_CTRL_CYCLETIMEEXT]); -+ } -+ -+ if (qbvctrl[TSN_QBV_ATTR_CTRL_BASETIME]) { -+ qbvconfig.admin.base_time = -+ nla_get_u64(qbvctrl[TSN_QBV_ATTR_CTRL_BASETIME]); -+ } -+ -+ if (qbvctrl[TSN_QBV_ATTR_CTRL_GATESTATE]) { -+ qbvconfig.admin.gate_states = -+ nla_get_u8(qbvctrl[TSN_QBV_ATTR_CTRL_GATESTATE]); -+ } -+ -+ if (qbvctrl[TSN_QBV_ATTR_CTRL_LISTCOUNT]) { -+ int listcount; -+ -+ listcount = nla_get_u32(qbvctrl[TSN_QBV_ATTR_CTRL_LISTCOUNT]); -+ -+ qbvconfig.admin.control_list_length = listcount; -+ -+ gatelist = kmalloc_array(listcount, -+ sizeof(*gatelist), -+ GFP_KERNEL); -+ -+ nla_for_each_nested(qbv_table, na1, rem) { -+ struct nlattr *qbv_entry[TSN_QBV_ATTR_ENTRY_MAX + 1]; -+ -+ if (nla_type(qbv_table) != TSN_QBV_ATTR_CTRL_LISTENTRY) -+ continue; -+ -+ ret = NLA_PARSE_NESTED(qbv_entry, -+ TSN_QBV_ATTR_ENTRY_MAX, -+ qbv_table, qbv_entry_policy); -+ if (ret) -+ return -EINVAL; -+ -+ (gatelist + count)->gate_state = -+ nla_get_u8(qbv_entry[TSN_QBV_ATTR_ENTRY_GC]); -+ (gatelist + count)->time_interval = -+ nla_get_u32(qbv_entry[TSN_QBV_ATTR_ENTRY_TM]); -+ count++; -+ if (count > listcount) -+ break; -+ } -+ } -+ -+ if (gatelist) -+ qbvconfig.admin.control_list = gatelist; -+ -+setdrive: -+ if (!tsnops->qbv_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ goto err; -+ } -+ -+ ret = tsnops->qbv_set(netdev, &qbvconfig); -+ -+ /* send back */ -+ if (ret < 0) -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ else -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, 0); -+ -+err: -+ kfree(gatelist); -+ return ret; -+} -+ -+static int tsn_qbv_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) { -+ cmd_qbv_set(info); -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int cmd_qbv_get(struct genl_info *info) -+{ -+ struct nlattr *qbv, *qbvadminattr; -+ struct sk_buff *rep_skb; -+ int ret; -+ int len = 0, i = 0; -+ struct net_device *netdev; -+ struct genlmsghdr *genlhdr; -+ struct tsn_qbv_conf qbvconf; -+ const struct tsn_ops *tsnops; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ genlhdr = info->genlhdr; -+ -+ memset(&qbvconf, 0, sizeof(struct tsn_qbv_conf)); -+ -+ if (!tsnops->qbv_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ ret = tsnops->qbv_get(netdev, &qbvconf); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, -+ &rep_skb, NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) -+ return -EMSGSIZE; -+ -+ qbv = nla_nest_start_noflag(rep_skb, TSN_ATTR_QBV); -+ if (!qbv) -+ return -EMSGSIZE; -+ -+ qbvadminattr = nla_nest_start_noflag(rep_skb, TSN_QBV_ATTR_ADMINENTRY); -+ if (!qbvadminattr) -+ return -EMSGSIZE; -+ -+ if (qbvconf.admin.control_list) { -+ len = qbvconf.admin.control_list_length; -+ if (nla_put_u32(rep_skb, TSN_QBV_ATTR_CTRL_LISTCOUNT, len)) -+ return -EMSGSIZE; -+ -+ for (i = 0; i < len; i++) { -+ struct nlattr *qbv_table; -+ u8 gs; -+ u32 tp; -+ int glisttype = TSN_QBV_ATTR_CTRL_LISTENTRY; -+ -+ gs = (qbvconf.admin.control_list + i)->gate_state; -+ tp = (qbvconf.admin.control_list + i)->time_interval; -+ -+ qbv_table = -+ nla_nest_start_noflag(rep_skb, glisttype); -+ if (!qbv_table) -+ return -EMSGSIZE; -+ -+ if (nla_put_u32(rep_skb, TSN_QBV_ATTR_ENTRY_ID, i) || -+ nla_put_u8(rep_skb, TSN_QBV_ATTR_ENTRY_GC, gs) || -+ nla_put_u32(rep_skb, TSN_QBV_ATTR_ENTRY_TM, tp)) -+ return -EMSGSIZE; -+ nla_nest_end(rep_skb, qbv_table); -+ } -+ -+ if (qbvconf.admin.gate_states) -+ if (nla_put_u8(rep_skb, TSN_QBV_ATTR_CTRL_GATESTATE, -+ qbvconf.admin.gate_states)) -+ return -EMSGSIZE; -+ -+ if (qbvconf.admin.cycle_time) -+ if (nla_put_u32(rep_skb, TSN_QBV_ATTR_CTRL_CYCLETIME, -+ qbvconf.admin.cycle_time)) -+ return -EMSGSIZE; -+ -+ if (qbvconf.admin.cycle_time_extension) -+ if (nla_put_u32(rep_skb, TSN_QBV_ATTR_CTRL_CYCLETIMEEXT, -+ qbvconf.admin.cycle_time_extension)) -+ return -EMSGSIZE; -+ -+ if (qbvconf.admin.base_time) -+ if (NLA_PUT_U64(rep_skb, TSN_QBV_ATTR_CTRL_BASETIME, -+ qbvconf.admin.base_time)) -+ return -EMSGSIZE; -+ -+ kfree(qbvconf.admin.control_list); -+ -+ } else { -+ pr_info("tsn: error get administrator data."); -+ } -+ -+ nla_nest_end(rep_skb, qbvadminattr); -+ -+ if (qbvconf.gate_enabled) { -+ if (nla_put_flag(rep_skb, TSN_QBV_ATTR_ENABLE)) -+ return -EMSGSIZE; -+ } else { -+ if (nla_put_flag(rep_skb, TSN_QBV_ATTR_DISABLE)) -+ return -EMSGSIZE; -+ } -+ -+ if (qbvconf.maxsdu) -+ if (nla_put_u32(rep_skb, TSN_QBV_ATTR_MAXSDU, qbvconf.maxsdu)) -+ return -EMSGSIZE; -+ -+ if (qbvconf.config_change) -+ if (nla_put_flag(rep_skb, TSN_QBV_ATTR_CONFIGCHANGE)) -+ return -EMSGSIZE; -+ -+ nla_nest_end(rep_skb, qbv); -+ -+ tsn_send_reply(rep_skb, info); -+ -+ return ret; -+} -+ -+static int cmd_qbv_status_get(struct genl_info *info) -+{ -+ struct nlattr *qbv, *qbvoperattr; -+ struct sk_buff *rep_skb; -+ int ret; -+ int len = 0, i = 0; -+ struct net_device *netdev; -+ struct genlmsghdr *genlhdr; -+ struct tsn_qbv_status qbvstatus; -+ const struct tsn_ops *tsnops; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ genlhdr = info->genlhdr; -+ -+ memset(&qbvstatus, 0, sizeof(struct tsn_qbv_status)); -+ -+ if (!tsnops->qbv_get_status) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ ret = tsnops->qbv_get_status(netdev, &qbvstatus); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, -+ &rep_skb, NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) -+ return -EMSGSIZE; -+ -+ qbv = nla_nest_start_noflag(rep_skb, TSN_ATTR_QBV); -+ if (!qbv) -+ return -EMSGSIZE; -+ -+ qbvoperattr = nla_nest_start_noflag(rep_skb, TSN_QBV_ATTR_OPERENTRY); -+ if (!qbvoperattr) -+ return -EMSGSIZE; -+ -+ if (qbvstatus.oper.control_list) { -+ len = qbvstatus.oper.control_list_length; -+ if (nla_put_u32(rep_skb, TSN_QBV_ATTR_CTRL_LISTCOUNT, len)) { -+ nla_nest_cancel(rep_skb, qbvoperattr); -+ return -EMSGSIZE; -+ } -+ -+ for (i = 0; i < len; i++) { -+ struct nlattr *qbv_table; -+ u8 gs; -+ u32 tp; -+ int glisttype = TSN_QBV_ATTR_CTRL_LISTENTRY; -+ -+ gs = (qbvstatus.oper.control_list + i)->gate_state; -+ tp = (qbvstatus.oper.control_list + i)->time_interval; -+ -+ qbv_table = nla_nest_start_noflag(rep_skb, glisttype); -+ if (!qbv_table) -+ return -EMSGSIZE; -+ -+ if (nla_put_u32(rep_skb, TSN_QBV_ATTR_ENTRY_ID, i) || -+ nla_put_u8(rep_skb, TSN_QBV_ATTR_ENTRY_GC, gs) || -+ nla_put_u32(rep_skb, TSN_QBV_ATTR_ENTRY_TM, tp)) { -+ nla_nest_cancel(rep_skb, qbv_table); -+ return -EMSGSIZE; -+ } -+ -+ nla_nest_end(rep_skb, qbv_table); -+ } -+ -+ if (qbvstatus.oper.gate_states) { -+ if (nla_put_u8(rep_skb, TSN_QBV_ATTR_CTRL_GATESTATE, -+ qbvstatus.oper.gate_states)) -+ return -EMSGSIZE; -+ } -+ -+ if (qbvstatus.oper.cycle_time) { -+ if (nla_put_u32(rep_skb, TSN_QBV_ATTR_CTRL_CYCLETIME, -+ qbvstatus.oper.cycle_time)) -+ return -EMSGSIZE; -+ } -+ -+ if (qbvstatus.oper.cycle_time_extension) { -+ if (nla_put_u32(rep_skb, TSN_QBV_ATTR_CTRL_CYCLETIMEEXT, -+ qbvstatus.oper.cycle_time_extension)) -+ return -EMSGSIZE; -+ } -+ -+ if (qbvstatus.oper.base_time) { -+ if (NLA_PUT_U64(rep_skb, TSN_QBV_ATTR_CTRL_BASETIME, -+ qbvstatus.oper.base_time)) -+ return -EMSGSIZE; -+ } -+ -+ kfree(qbvstatus.oper.control_list); -+ } else { -+ pr_info("tsn: error get operation list data."); -+ } -+ -+ nla_nest_end(rep_skb, qbvoperattr); -+ -+ if (qbvstatus.config_change_time) { -+ if (NLA_PUT_U64(rep_skb, TSN_QBV_ATTR_CONFIGCHANGETIME, -+ qbvstatus.config_change_time)) -+ return -EMSGSIZE; -+ } -+ -+ if (qbvstatus.tick_granularity) { -+ if (nla_put_u32(rep_skb, TSN_QBV_ATTR_GRANULARITY, -+ qbvstatus.tick_granularity)) -+ return -EMSGSIZE; -+ } -+ -+ if (qbvstatus.current_time) { -+ if (NLA_PUT_U64(rep_skb, TSN_QBV_ATTR_CURRENTTIME, -+ qbvstatus.current_time)) -+ return -EMSGSIZE; -+ } -+ -+ if (qbvstatus.config_pending) { -+ if (nla_put_flag(rep_skb, TSN_QBV_ATTR_CONFIGPENDING)) -+ return -EMSGSIZE; -+ } -+ -+ if (qbvstatus.config_change_error) { -+ if (NLA_PUT_U64(rep_skb, TSN_QBV_ATTR_CONFIGCHANGEERROR, -+ qbvstatus.config_change_error)) -+ return -EMSGSIZE; -+ } -+ -+ if (qbvstatus.supported_list_max) { -+ if (nla_put_u32(rep_skb, TSN_QBV_ATTR_LISTMAX, -+ qbvstatus.supported_list_max)) -+ return -EMSGSIZE; -+ } -+ -+ nla_nest_end(rep_skb, qbv); -+ -+ tsn_send_reply(rep_skb, info); -+ -+ return ret; -+} -+ -+static int tsn_qbv_status_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) -+ cmd_qbv_status_get(info); -+ -+ return 0; -+} -+ -+static int tsn_qbv_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) -+ cmd_qbv_get(info); -+ -+ return 0; -+} -+ -+static int tsn_cbs_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na; -+ struct nlattr *cbsa[TSN_CBS_ATTR_MAX + 1]; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ int ret; -+ u8 tc, bw; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ if (!info->attrs[TSN_ATTR_CBS]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ na = info->attrs[TSN_ATTR_CBS]; -+ -+ if (!tsnops->cbs_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ ret = NLA_PARSE_NESTED(cbsa, TSN_CBS_ATTR_MAX, na, cbs_policy); -+ if (ret) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ if (!cbsa[TSN_CBS_ATTR_TC_INDEX]) { -+ pr_err("tsn: no TSN_CBS_ATTR_TC_INDEX input\n"); -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ tc = nla_get_u8(cbsa[TSN_CBS_ATTR_TC_INDEX]); -+ -+ if (!cbsa[TSN_CBS_ATTR_BW]) { -+ pr_err("tsn: no TSN_CBS_ATTR_BW input\n"); -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ bw = nla_get_u8(cbsa[TSN_CBS_ATTR_BW]); -+ if (bw > 100) { -+ pr_err("tsn: TSN_CBS_ATTR_BW isn't in the range of 0~100\n"); -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ ret = tsnops->cbs_set(netdev, tc, bw); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, 0); -+ return 0; -+} -+ -+static int tsn_cbs_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na, *cbsattr; -+ struct nlattr *cbsa[TSN_CBS_ATTR_MAX + 1]; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ struct sk_buff *rep_skb; -+ int ret; -+ struct genlmsghdr *genlhdr; -+ u8 tc; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ if (!info->attrs[TSN_ATTR_CBS]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ if (!tsnops->cbs_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ na = info->attrs[TSN_ATTR_CBS]; -+ ret = NLA_PARSE_NESTED(cbsa, TSN_CBS_ATTR_MAX, na, cbs_policy); -+ if (ret) { -+ pr_err("tsn: parse value TSN_CBS_ATTR_MAX error."); -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ /* Get status data from device */ -+ genlhdr = info->genlhdr; -+ -+ /* Form netlink reply data */ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, &rep_skb, -+ NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) -+ return -EMSGSIZE; -+ -+ cbsattr = nla_nest_start_noflag(rep_skb, TSN_ATTR_CBS); -+ if (!cbsattr) -+ return -EMSGSIZE; -+ -+ if (!cbsa[TSN_CBS_ATTR_TC_INDEX]) { -+ pr_err("tsn: must to specify the TSN_CBS_ATTR_TC_INDEX\n"); -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ tc = nla_get_u8(cbsa[TSN_CBS_ATTR_TC_INDEX]); -+ -+ ret = tsnops->cbs_get(netdev, tc); -+ if (ret < 0) { -+ pr_err("tsn: cbs_get return error\n"); -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ if (nla_put_u8(rep_skb, TSN_CBS_ATTR_BW, ret & 0XF)) -+ return -EMSGSIZE; -+ -+ nla_nest_end(rep_skb, cbsattr); -+ return tsn_send_reply(rep_skb, info); -+} -+ -+static int cmd_qbu_set(struct genl_info *info) -+{ -+ struct nlattr *na; -+ struct nlattr *qbua[TSN_QBU_ATTR_MAX + 1]; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ int ret; -+ u8 preemptible = 0; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ if (!info->attrs[TSN_ATTR_QBU]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ na = info->attrs[TSN_ATTR_QBU]; -+ -+ ret = NLA_PARSE_NESTED(qbua, TSN_QBU_ATTR_MAX, na, qbu_policy); -+ if (ret) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ if (qbua[TSN_QBU_ATTR_ADMIN_STATE]) -+ preemptible = nla_get_u8(qbua[TSN_QBU_ATTR_ADMIN_STATE]); -+ else -+ pr_info("No preemptible TSN_QBU_ATTR_ADMIN_STATE config!\n"); -+ -+ if (!tsnops->qbu_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -EINVAL; -+ } -+ -+ ret = tsnops->qbu_set(netdev, preemptible); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, 0); -+ return 0; -+} -+ -+static int tsn_qbu_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) -+ return cmd_qbu_set(info); -+ -+ return -1; -+} -+ -+static int cmd_qbu_get_status(struct genl_info *info) -+{ -+ struct nlattr *qbuattr; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ struct sk_buff *rep_skb; -+ int ret; -+ struct genlmsghdr *genlhdr; -+ struct tsn_preempt_status pps; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ /* Get status data from device */ -+ genlhdr = info->genlhdr; -+ -+ memset(&pps, 0, sizeof(struct tsn_preempt_status)); -+ -+ if (!tsnops->qbu_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ ret = tsnops->qbu_get(netdev, &pps); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ /* Form netlink reply data */ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, -+ &rep_skb, NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) -+ return -EMSGSIZE; -+ -+ qbuattr = nla_nest_start_noflag(rep_skb, TSN_ATTR_QBU); -+ if (!qbuattr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u8(rep_skb, TSN_QBU_ATTR_ADMIN_STATE, pps.admin_state) || -+ nla_put_u32(rep_skb, -+ TSN_QBU_ATTR_HOLD_ADVANCE, pps.hold_advance) || -+ nla_put_u32(rep_skb, -+ TSN_QBU_ATTR_RELEASE_ADVANCE, pps.release_advance)) -+ return -EMSGSIZE; -+ -+ if (pps.preemption_active) { -+ if (nla_put_flag(rep_skb, TSN_QBU_ATTR_ACTIVE)) -+ return -EMSGSIZE; -+ } -+ -+ if (nla_put_u8(rep_skb, TSN_QBU_ATTR_HOLD_REQUEST, pps.hold_request)) -+ return -EMSGSIZE; -+ -+ nla_nest_end(rep_skb, qbuattr); -+ -+ return tsn_send_reply(rep_skb, info); -+} -+ -+static int tsn_qbu_get_status(struct sk_buff *skb, struct genl_info *info) -+{ -+ if (info->attrs[TSN_ATTR_IFNAME]) -+ return cmd_qbu_get_status(info); -+ -+ return -1; -+} -+ -+static int tsn_tsd_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na; -+ struct nlattr *ntsd[TSN_TSD_ATTR_MAX + 1]; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ struct tsn_tsd tsd; -+ int ret; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ memset(&tsd, 0, sizeof(struct tsn_tsd)); -+ -+ if (!info->attrs[TSN_ATTR_TSD]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ na = info->attrs[TSN_ATTR_TSD]; -+ -+ ret = NLA_PARSE_NESTED(ntsd, TSN_TSD_ATTR_MAX, na, tsd_policy); -+ if (ret) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ if (!tsnops->tsd_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -EINVAL; -+ } -+ -+ if (nla_get_flag(ntsd[TSN_TSD_ATTR_DISABLE])) { -+ tsd.enable = false; -+ } else { -+ if (ntsd[TSN_TSD_ATTR_PERIOD]) -+ tsd.period = nla_get_u32(ntsd[TSN_TSD_ATTR_PERIOD]); -+ -+ if (!tsd.period) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ if (ntsd[TSN_TSD_ATTR_MAX_FRM_NUM]) -+ tsd.maxFrameNum = -+ nla_get_u32(ntsd[TSN_TSD_ATTR_MAX_FRM_NUM]); -+ -+ if (ntsd[TSN_TSD_ATTR_SYN_IMME]) -+ tsd.syn_flag = 2; -+ else -+ tsd.syn_flag = 1; -+ -+ tsd.enable = true; -+ } -+ -+ ret = tsnops->tsd_set(netdev, &tsd); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, 0); -+ return 0; -+} -+ -+static int tsn_tsd_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na, *tsdattr; -+ struct nlattr *tsda[TSN_TSD_ATTR_MAX + 1]; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ struct sk_buff *rep_skb; -+ int ret; -+ struct genlmsghdr *genlhdr; -+ struct tsn_tsd_status tts; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ if (!info->attrs[TSN_ATTR_TSD]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ if (!tsnops->tsd_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ ret = tsnops->tsd_get(netdev, &tts); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ na = info->attrs[TSN_ATTR_TSD]; -+ -+ ret = NLA_PARSE_NESTED(tsda, TSN_TSD_ATTR_MAX, -+ na, tsd_policy); -+ if (ret) { -+ pr_err("tsn: parse value TSN_TSD_ATTR_MAX error."); -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ /* Get status data from device */ -+ genlhdr = info->genlhdr; -+ -+ /* Form netlink reply data */ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, &rep_skb, -+ NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) -+ return -EMSGSIZE; -+ -+ tsdattr = nla_nest_start_noflag(rep_skb, TSN_ATTR_TSD); -+ if (!tsdattr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u32(rep_skb, TSN_TSD_ATTR_PERIOD, tts.period) || -+ nla_put_u32(rep_skb, TSN_TSD_ATTR_MAX_FRM_NUM, tts.maxFrameNum) || -+ nla_put_u32(rep_skb, TSN_TSD_ATTR_CYCLE_NUM, tts.cycleNum) || -+ nla_put_u32(rep_skb, TSN_TSD_ATTR_LOSS_STEPS, tts.loss_steps) || -+ nla_put_u32(rep_skb, TSN_TSD_ATTR_MAX_FRM_NUM, tts.maxFrameNum)) -+ return -EMSGSIZE; -+ -+ if (!tts.enable) { -+ if (nla_put_flag(rep_skb, TSN_TSD_ATTR_DISABLE)) -+ return -EMSGSIZE; -+ } else { -+ if (nla_put_flag(rep_skb, TSN_TSD_ATTR_ENABLE)) -+ return -EMSGSIZE; -+ } -+ -+ if (tts.flag == 2) -+ if (nla_put_flag(rep_skb, TSN_TSD_ATTR_SYN_IMME)) -+ return -EMSGSIZE; -+ -+ nla_nest_end(rep_skb, tsdattr); -+ return tsn_send_reply(rep_skb, info); -+} -+ -+static int tsn_ct_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na; -+ struct nlattr *cta[TSN_CT_ATTR_MAX + 1]; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ int ret; -+ u8 queue_stat; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ if (!info->attrs[TSN_ATTR_CT]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ na = info->attrs[TSN_ATTR_CT]; -+ -+ if (!tsnops->ct_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ ret = NLA_PARSE_NESTED(cta, TSN_CT_ATTR_MAX, -+ na, ct_policy); -+ if (ret) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ queue_stat = nla_get_u8(cta[TSN_CT_ATTR_QUEUE_STATE]); -+ -+ ret = tsnops->ct_set(netdev, queue_stat); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, 0); -+ return 0; -+} -+ -+static int tsn_cbgen_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na; -+ struct nlattr *cbgena[TSN_CBGEN_ATTR_MAX + 1]; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ int ret; -+ u32 index; -+ struct tsn_seq_gen_conf sg_conf; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ if (!info->attrs[TSN_ATTR_CBGEN]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ na = info->attrs[TSN_ATTR_CBGEN]; -+ -+ if (!tsnops->cbgen_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ ret = NLA_PARSE_NESTED(cbgena, TSN_CBGEN_ATTR_MAX, -+ na, cbgen_policy); -+ if (ret) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ index = nla_get_u32(cbgena[TSN_CBGEN_ATTR_INDEX]); -+ -+ memset(&sg_conf, 0, sizeof(struct tsn_seq_gen_conf)); -+ sg_conf.iport_mask = nla_get_u8(cbgena[TSN_CBGEN_ATTR_PORT_MASK]); -+ sg_conf.split_mask = nla_get_u8(cbgena[TSN_CBGEN_ATTR_SPLIT_MASK]); -+ sg_conf.seq_len = nla_get_u8(cbgena[TSN_CBGEN_ATTR_SEQ_LEN]); -+ sg_conf.seq_num = nla_get_u32(cbgena[TSN_CBGEN_ATTR_SEQ_NUM]); -+ -+ ret = tsnops->cbgen_set(netdev, index, &sg_conf); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, 0); -+ return 0; -+} -+ -+static int tsn_cbrec_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na; -+ struct nlattr *cbreca[TSN_CBREC_ATTR_MAX + 1]; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ int ret; -+ u32 index; -+ struct tsn_seq_rec_conf sr_conf; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ if (!info->attrs[TSN_ATTR_CBREC]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ na = info->attrs[TSN_ATTR_CBREC]; -+ -+ if (!tsnops->cbrec_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ ret = NLA_PARSE_NESTED(cbreca, TSN_CBREC_ATTR_MAX, -+ na, cbrec_policy); -+ if (ret) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ index = nla_get_u32(cbreca[TSN_CBREC_ATTR_INDEX]); -+ -+ memset(&sr_conf, 0, sizeof(struct tsn_seq_rec_conf)); -+ sr_conf.seq_len = nla_get_u8(cbreca[TSN_CBREC_ATTR_SEQ_LEN]); -+ sr_conf.his_len = nla_get_u8(cbreca[TSN_CBREC_ATTR_HIS_LEN]); -+ sr_conf.rtag_pop_en = nla_get_flag(cbreca[TSN_CBREC_ATTR_TAG_POP_EN]); -+ -+ ret = tsnops->cbrec_set(netdev, index, &sr_conf); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, 0); -+ return 0; -+} -+ -+static int tsn_cbstatus_get(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na; -+ struct nlattr *cba[TSN_CBSTAT_ATTR_MAX + 1]; -+ struct nlattr *cbattr; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ struct sk_buff *rep_skb; -+ int ret; -+ unsigned int index; -+ struct genlmsghdr *genlhdr; -+ struct tsn_cb_status cbstat; -+ struct tsn_port *port; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ /* Get status data from device */ -+ genlhdr = info->genlhdr; -+ -+ memset(&cbstat, 0, sizeof(struct tsn_cb_status)); -+ -+ if (!tsnops->cb_get) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ na = info->attrs[TSN_ATTR_CBSTAT]; -+ ret = NLA_PARSE_NESTED(cba, TSN_CBSTAT_ATTR_MAX, -+ na, cbstat_policy); -+ if (ret) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ index = nla_get_u32(cba[TSN_CBSTAT_ATTR_INDEX]); -+ -+ ret = tsnops->cb_get(netdev, index, &cbstat); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ /* Form netlink reply data */ -+ ret = tsn_prepare_reply(info, genlhdr->cmd, -+ &rep_skb, NLMSG_ALIGN(MAX_ATTR_SIZE)); -+ if (ret < 0) -+ return ret; -+ -+ if (nla_put_string(rep_skb, TSN_ATTR_IFNAME, netdev->name)) -+ return -EMSGSIZE; -+ -+ cbattr = nla_nest_start_noflag(rep_skb, TSN_ATTR_CBSTAT); -+ if (!cbattr) -+ return -EMSGSIZE; -+ -+ if (nla_put_u8(rep_skb, TSN_CBSTAT_ATTR_GEN_REC, cbstat.gen_rec) || -+ nla_put_u8(rep_skb, TSN_CBSTAT_ATTR_ERR, cbstat.err) || -+ nla_put_u32(rep_skb, TSN_CBSTAT_ATTR_SEQ_NUM, -+ cbstat.seq_num) || -+ nla_put_u8(rep_skb, TSN_CBSTAT_ATTR_SEQ_LEN, cbstat.seq_len) || -+ nla_put_u8(rep_skb, TSN_CBSTAT_ATTR_SPLIT_MASK, -+ cbstat.split_mask) || -+ nla_put_u8(rep_skb, TSN_CBSTAT_ATTR_PORT_MASK, -+ cbstat.iport_mask) || -+ nla_put_u8(rep_skb, TSN_CBSTAT_ATTR_HIS_LEN, cbstat.his_len) || -+ nla_put_u32(rep_skb, TSN_CBSTAT_ATTR_SEQ_HIS, -+ cbstat.seq_his)) -+ return -EMSGSIZE; -+ -+ nla_nest_end(rep_skb, cbattr); -+ -+ return tsn_send_reply(rep_skb, info); -+} -+ -+static int tsn_dscp_set(struct sk_buff *skb, struct genl_info *info) -+{ -+ struct nlattr *na; -+ struct nlattr *dscpa[TSN_DSCP_ATTR_MAX + 1]; -+ struct net_device *netdev; -+ const struct tsn_ops *tsnops; -+ int ret; -+ bool enable = 0; -+ struct tsn_port *port; -+ int dscp_ix; -+ struct tsn_qos_switch_dscp_conf dscp_conf; -+ -+ port = tsn_init_check(info, &netdev); -+ if (!port) -+ return -ENODEV; -+ -+ tsnops = port->tsnops; -+ -+ if (!info->attrs[TSN_ATTR_DSCP]) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ na = info->attrs[TSN_ATTR_DSCP]; -+ -+ if (!tsnops->dscp_set) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EPERM); -+ return -1; -+ } -+ -+ ret = NLA_PARSE_NESTED(dscpa, TSN_DSCP_ATTR_MAX, -+ na, dscp_policy); -+ if (ret) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, -EINVAL); -+ return -EINVAL; -+ } -+ -+ enable = 1; -+ if (dscpa[TSN_DSCP_ATTR_DISABLE]) -+ enable = 0; -+ dscp_ix = nla_get_u32(dscpa[TSN_DSCP_ATTR_INDEX]); -+ dscp_conf.cos = nla_get_u32(dscpa[TSN_DSCP_ATTR_COS]); -+ dscp_conf.dpl = nla_get_u32(dscpa[TSN_DSCP_ATTR_DPL]); -+ ret = tsnops->dscp_set(netdev, enable, dscp_ix, &dscp_conf); -+ if (ret < 0) { -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, ret); -+ return ret; -+ } -+ -+ tsn_simple_reply(info, TSN_CMD_REPLY, -+ netdev->name, 0); -+ -+ return 0; -+} -+ -+static const struct genl_ops tsnnl_ops[] = { -+ { -+ .cmd = TSN_CMD_ECHO, -+ .doit = tsn_echo_cmd, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_CAP_GET, -+ .doit = tsn_cap_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QBV_SET, -+ .doit = tsn_qbv_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QBV_GET, -+ .doit = tsn_qbv_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QBV_GET_STATUS, -+ .doit = tsn_qbv_status_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_CB_STREAMID_SET, -+ .doit = tsn_cb_streamid_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_CB_STREAMID_GET, -+ .doit = tsn_cb_streamid_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_CB_STREAMID_GET_COUNTS, -+ .doit = tsn_cb_streamid_counters_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QCI_CAP_GET, -+ .doit = tsn_qci_cap_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QCI_SFI_SET, -+ .doit = tsn_qci_sfi_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QCI_SFI_GET, -+ .doit = tsn_qci_sfi_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QCI_SFI_GET_COUNTS, -+ .doit = tsn_qci_sfi_counters_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QCI_SGI_SET, -+ .doit = tsn_qci_sgi_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QCI_SGI_GET, -+ .doit = tsn_qci_sgi_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QCI_SGI_GET_STATUS, -+ .doit = tsn_qci_sgi_status_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QCI_FMI_SET, -+ .doit = tsn_qci_fmi_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QCI_FMI_GET, -+ .doit = tsn_qci_fmi_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_CBS_SET, -+ .doit = tsn_cbs_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_CBS_GET, -+ .doit = tsn_cbs_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QBU_SET, -+ .doit = tsn_qbu_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_QBU_GET_STATUS, -+ .doit = tsn_qbu_get_status, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_TSD_SET, -+ .doit = tsn_tsd_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_TSD_GET, -+ .doit = tsn_tsd_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_CT_SET, -+ .doit = tsn_ct_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_CBGEN_SET, -+ .doit = tsn_cbgen_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_CBREC_SET, -+ .doit = tsn_cbrec_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_CBSTAT_GET, -+ .doit = tsn_cbstatus_get, -+ .flags = GENL_ADMIN_PERM, -+ }, -+ { -+ .cmd = TSN_CMD_DSCP_SET, -+ .doit = tsn_dscp_set, -+ .flags = GENL_ADMIN_PERM, -+ }, -+}; -+ -+static const struct genl_multicast_group tsn_mcgrps[] = { -+ [TSN_MCGRP_QBV] = { .name = TSN_MULTICAST_GROUP_QBV}, -+ [TSN_MCGRP_QCI] = { .name = TSN_MULTICAST_GROUP_QCI}, -+}; -+ -+static struct genl_family tsn_family = { -+ .name = TSN_GENL_NAME, -+ .version = TSN_GENL_VERSION, -+ .maxattr = TSN_CMD_ATTR_MAX, -+ .module = THIS_MODULE, -+ .netnsok = true, -+ .ops = tsnnl_ops, -+ .n_ops = ARRAY_SIZE(tsnnl_ops), -+ .mcgrps = tsn_mcgrps, -+ .n_mcgrps = ARRAY_SIZE(tsn_mcgrps), -+}; -+ -+int tsn_port_register(struct net_device *netdev, -+ struct tsn_ops *tsnops, u16 groupid) -+{ -+ struct tsn_port *port; -+ -+ if (list_empty(&port_list)) { -+ INIT_LIST_HEAD(&port_list); -+ } else { -+ list_for_each_entry(port, &port_list, list) { -+ if (port->netdev == netdev) { -+ pr_info("TSN device already registered!\n"); -+ return -1; -+ } -+ } -+ } -+ -+ port = kzalloc(sizeof(*port), GFP_KERNEL); -+ if (!port) -+ return -1; -+ -+ port->netdev = netdev; -+ port->groupid = groupid; -+ port->tsnops = tsnops; -+ port->nd.dev = netdev; -+ -+ if (groupid < GROUP_OFFSET_SWITCH) -+ port->type = TSN_ENDPOINT; -+ else -+ port->type = TSN_SWITCH; -+ -+ list_add_tail(&port->list, &port_list); -+ -+ if (tsnops && tsnops->device_init) -+ port->tsnops->device_init(netdev); -+ -+ return 0; -+} -+EXPORT_SYMBOL(tsn_port_register); -+ -+void tsn_port_unregister(struct net_device *netdev) -+{ -+ struct tsn_port *p; -+ -+ list_for_each_entry(p, &port_list, list) { -+ if (!p || !p->netdev) -+ continue; -+ if (p->netdev == netdev) { -+ if (p->tsnops->device_deinit) -+ p->tsnops->device_deinit(netdev); -+ list_del(&p->list); -+ kfree(p); -+ break; -+ } -+ } -+} -+EXPORT_SYMBOL(tsn_port_unregister); -+ -+static int tsn_multicast_to_user(unsigned long event, -+ struct tsn_notifier_info *tsn_info) -+{ -+ struct sk_buff *skb; -+ struct genlmsghdr *nlh; -+ int res; -+ struct tsn_qbv_conf *qbvdata; -+ -+ /* If new attributes are added, please revisit this allocation */ -+ skb = genlmsg_new(sizeof(*tsn_info), GFP_KERNEL); -+ if (!skb) { -+ pr_err("Allocation failure.\n"); -+ return -ENOMEM; -+ } -+ -+ switch (event) { -+ case TSN_QBV_CONFIGCHANGETIME_ARRIVE: -+ nlh = genlmsg_put(skb, 0, 1, &tsn_family, -+ GFP_KERNEL, TSN_CMD_QBV_SET); -+ qbvdata = &tsn_info->ntdata.qbv_notify; -+ res = NLA_PUT_U64(skb, TSN_QBV_ATTR_CTRL_BASETIME, -+ qbvdata->admin.base_time); -+ -+ if (res) { -+ pr_err("put data failure!\n"); -+ goto done; -+ } -+ -+ res = nla_put_u32(skb, TSN_QBV_ATTR_CTRL_CYCLETIME, -+ qbvdata->admin.cycle_time); -+ if (res) { -+ pr_err("put data failure!\n"); -+ goto done; -+ } -+ -+ if (qbvdata->gate_enabled) -+ res = nla_put_flag(skb, TSN_QBV_ATTR_ENABLE + -+ TSN_QBV_ATTR_CTRL_MAX); -+ else -+ res = nla_put_flag(skb, TSN_QBV_ATTR_DISABLE + -+ TSN_QBV_ATTR_CTRL_MAX); -+ if (res) { -+ pr_err("put data failure!\n"); -+ goto done; -+ } -+ -+ res = nla_put_u32(skb, TSN_QBV_ATTR_CTRL_UNSPEC, -+ tsn_info->dev->ifindex); -+ if (res) { -+ pr_err("put data failure!\n"); -+ goto done; -+ } -+ -+ break; -+ default: -+ pr_info("event not supportted!\n"); -+ break; -+ } -+ -+ (void)genlmsg_end(skb, nlh); -+ -+ res = genlmsg_multicast_allns(&tsn_family, skb, 0, -+ TSN_MCGRP_QBV, GFP_KERNEL); -+ skb = NULL; -+ if (res && res != -ESRCH) { -+ pr_err("genlmsg_multicast_allns error: %d\n", res); -+ goto done; -+ } -+ -+ if (res == -ESRCH) -+ res = 0; -+ -+done: -+ if (skb) { -+ nlmsg_free(skb); -+ skb = NULL; -+ } -+ -+ return res; -+} -+ -+/* called with RTNL or RCU */ -+static int tsn_event(struct notifier_block *unused, -+ unsigned long event, void *ptr) -+{ -+ struct tsn_notifier_info *tsn_info; -+ int err = NOTIFY_DONE; -+ -+ switch (event) { -+ case TSN_QBV_CONFIGCHANGETIME_ARRIVE: -+ tsn_info = ptr; -+ err = tsn_multicast_to_user(event, tsn_info); -+ if (err) { -+ err = notifier_from_errno(err); -+ break; -+ } -+ break; -+ default: -+ pr_info("event not supportted!\n"); -+ break; -+ } -+ -+ return err; -+} -+ -+static struct notifier_block tsn_notifier = { -+ .notifier_call = tsn_event, -+}; -+ -+static int __init tsn_genetlink_init(void) -+{ -+ int ret; -+ -+ pr_info("tsn generic netlink module v%d init...\n", TSN_GENL_VERSION); -+ -+ ret = genl_register_family(&tsn_family); -+ -+ if (ret != 0) { -+ pr_info("failed to init tsn generic netlink example module\n"); -+ return ret; -+ } -+ -+ register_tsn_notifier(&tsn_notifier); -+ -+ return 0; -+} -+ -+static void __exit tsn_genetlink_exit(void) -+{ -+ int ret; -+ -+ ret = genl_unregister_family(&tsn_family); -+ if (ret != 0) -+ pr_info("failed to unregister family:%i\n", ret); -+ -+ unregister_tsn_notifier(&tsn_notifier); -+} -+ -+module_init(tsn_genetlink_init); -+module_exit(tsn_genetlink_exit); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0335-net-tsn-fix-headfile-voliates-the-new-rule.patch b/target/linux/layerscape/patches-5.4/701-net-0335-net-tsn-fix-headfile-voliates-the-new-rule.patch deleted file mode 100644 index e732f14476..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0335-net-tsn-fix-headfile-voliates-the-new-rule.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 6e9f130a3be14a92a16b2332f6c92f873ebb8af5 Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Tue, 3 Sep 2019 15:57:49 +0800 -Subject: [PATCH] net: tsn: fix headfile voliates the new rule - -After commit -622445541b75 ("kbuild: detect missing "WITH Linux-syscall-note" for uapi headers") -the headfile must explicitly include "WITH Linux-syscall-note". - -Signed-off-by: Dong Aisheng ---- - include/uapi/linux/tsn.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/include/uapi/linux/tsn.h -+++ b/include/uapi/linux/tsn.h -@@ -1,4 +1,4 @@ --/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ -+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) WITH Linux-syscall-note */ - /* Copyright 2017-2019 NXP */ - - #ifndef __UAPI_GENL_TSN_H diff --git a/target/linux/layerscape/patches-5.4/701-net-0336-enetc-add-support-Credit-Based-Shaper-CBS-for-hardwa.patch b/target/linux/layerscape/patches-5.4/701-net-0336-enetc-add-support-Credit-Based-Shaper-CBS-for-hardwa.patch deleted file mode 100644 index 8b59f994b2..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0336-enetc-add-support-Credit-Based-Shaper-CBS-for-hardwa.patch +++ /dev/null @@ -1,231 +0,0 @@ -From 3426e5e4339f124f00eef8815b56a80481364550 Mon Sep 17 00:00:00 2001 -From: Po Liu -Date: Mon, 25 Nov 2019 05:56:56 +0000 -Subject: [PATCH] enetc: add support Credit Based Shaper(CBS) for hardware - offload - -The ENETC hardware support the Credit Based Shaper(CBS) which part -of the IEEE-802.1Qav. The CBS driver was loaded by the sch_cbs -interface when set in the QOS in the kernel. - -Here is an example command to set 20Mbits bandwidth in 1Gbits port -for taffic class 7: - -tc qdisc add dev eth0 root handle 1: mqprio \ - num_tc 8 map 0 1 2 3 4 5 6 7 hw 1 - -tc qdisc replace dev eth0 parent 1:8 cbs \ - locredit -1470 hicredit 30 \ - sendslope -980000 idleslope 20000 offload 1 - -Signed-off-by: Po Liu -Reviewed-by: Claudiu Manoil -Reviewed-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/freescale/enetc/Kconfig | 4 +- - drivers/net/ethernet/freescale/enetc/enetc.c | 2 + - drivers/net/ethernet/freescale/enetc/enetc.h | 2 + - drivers/net/ethernet/freescale/enetc/enetc_hw.h | 4 + - drivers/net/ethernet/freescale/enetc/enetc_qos.c | 128 +++++++++++++++++++++++ - 5 files changed, 138 insertions(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/enetc/Kconfig -+++ b/drivers/net/ethernet/freescale/enetc/Kconfig -@@ -53,10 +53,10 @@ config FSL_ENETC_HW_TIMESTAMPING - - config FSL_ENETC_QOS - bool "ENETC hardware Time-sensitive Network support" -- depends on (FSL_ENETC || FSL_ENETC_VF) && NET_SCH_TAPRIO -+ depends on (FSL_ENETC || FSL_ENETC_VF) && (NET_SCH_TAPRIO || NET_SCH_CBS) - help - There are Time-Sensitive Network(TSN) capabilities(802.1Qbv/802.1Qci - /802.1Qbu etc.) supported by ENETC. These TSN capabilities can be set - enable/disable from user space via Qos commands(tc). In the kernel - side, it can be loaded by Qos driver. Currently, it is only support -- taprio(802.1Qbv). -+ taprio(802.1Qbv) and Credit Based Shaper(802.1Qbu). ---- a/drivers/net/ethernet/freescale/enetc/enetc.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc.c -@@ -1516,6 +1516,8 @@ int enetc_setup_tc(struct net_device *nd - return enetc_setup_tc_mqprio(ndev, type_data); - case TC_SETUP_QDISC_TAPRIO: - return enetc_setup_tc_taprio(ndev, type_data); -+ case TC_SETUP_QDISC_CBS: -+ return enetc_setup_tc_cbs(ndev, type_data); - default: - return -EOPNOTSUPP; - } ---- a/drivers/net/ethernet/freescale/enetc/enetc.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc.h -@@ -260,7 +260,9 @@ int enetc_send_cmd(struct enetc_si *si, - #ifdef CONFIG_FSL_ENETC_QOS - int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data); - void enetc_sched_speed_set(struct net_device *ndev); -+int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data); - #else - #define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP - #define enetc_sched_speed_set(ndev) (void)0 -+#define enetc_setup_tc_cbs(ndev, type_data) -EOPNOTSUPP - #endif ---- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h -@@ -185,6 +185,8 @@ enum enetc_bdr_type {TX, RX}; - #define ENETC_PSICFGR0_SIVC(bmp) (((bmp) & 0xff) << 24) /* VLAN_TYPE */ - - #define ENETC_PTCCBSR0(n) (0x1110 + (n) * 8) /* n = 0 to 7*/ -+#define ENETC_CBSE BIT(31) -+#define ENETC_CBS_BW_MASK GENMASK(6, 0) - #define ENETC_PTCCBSR1(n) (0x1114 + (n) * 8) /* n = 0 to 7*/ - #define ENETC_RSSHASH_KEY_SIZE 40 - #define ENETC_PRSSCAPR 0x1404 -@@ -679,6 +681,8 @@ struct enetc_cbd { - u8 status_flags; - }; - -+#define ENETC_CLK 400000000ULL -+ - /* port time gating control register */ - #define ENETC_QBV_PTGCR_OFFSET 0x11a00 - #define ENETC_QBV_TGE BIT(31) ---- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c -@@ -4,6 +4,7 @@ - #include "enetc.h" - - #include -+#include - - static u16 enetc_get_max_gcl_len(struct enetc_hw *hw) - { -@@ -170,3 +171,130 @@ int enetc_setup_tc_taprio(struct net_dev - - return err; - } -+ -+static u32 enetc_get_cbs_enable(struct enetc_hw *hw, u8 tc) -+{ -+ return enetc_port_rd(hw, ENETC_PTCCBSR0(tc)) & ENETC_CBSE; -+} -+ -+static u8 enetc_get_cbs_bw(struct enetc_hw *hw, u8 tc) -+{ -+ return enetc_port_rd(hw, ENETC_PTCCBSR0(tc)) & ENETC_CBS_BW_MASK; -+} -+ -+int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data) -+{ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ struct tc_cbs_qopt_offload *cbs = type_data; -+ u32 port_transmit_rate = priv->speed; -+ u8 tc_nums = netdev_get_num_tc(ndev); -+ struct enetc_si *si = priv->si; -+ u32 hi_credit_bit, hi_credit_reg; -+ u32 max_interference_size; -+ u32 port_frame_max_size; -+ u32 tc_max_sized_frame; -+ u8 tc = cbs->queue; -+ u8 prio_top, prio_next; -+ int bw_sum = 0; -+ u8 bw; -+ -+ prio_top = netdev_get_prio_tc_map(ndev, tc_nums - 1); -+ prio_next = netdev_get_prio_tc_map(ndev, tc_nums - 2); -+ -+ /* Support highest prio and second prio tc in cbs mode */ -+ if (tc != prio_top && tc != prio_next) -+ return -EOPNOTSUPP; -+ -+ if (!cbs->enable) { -+ /* Make sure the other TC that are numerically -+ * lower than this TC have been disabled. -+ */ -+ if (tc == prio_top && -+ enetc_get_cbs_enable(&si->hw, prio_next)) { -+ dev_err(&ndev->dev, -+ "Disable TC%d before disable TC%d\n", -+ prio_next, tc); -+ return -EINVAL; -+ } -+ -+ enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), 0); -+ enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), 0); -+ -+ return 0; -+ } -+ -+ if (cbs->idleslope - cbs->sendslope != port_transmit_rate * 1000L || -+ cbs->idleslope < 0 || cbs->sendslope > 0) -+ return -EOPNOTSUPP; -+ -+ port_frame_max_size = ndev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; -+ -+ bw = cbs->idleslope / (port_transmit_rate * 10UL); -+ -+ /* Make sure the other TC that are numerically -+ * higher than this TC have been enabled. -+ */ -+ if (tc == prio_next) { -+ if (!enetc_get_cbs_enable(&si->hw, prio_top)) { -+ dev_err(&ndev->dev, -+ "Enable TC%d first before enable TC%d\n", -+ prio_top, prio_next); -+ return -EINVAL; -+ } -+ bw_sum += enetc_get_cbs_bw(&si->hw, prio_top); -+ } -+ -+ if (bw_sum + bw >= 100) { -+ dev_err(&ndev->dev, -+ "The sum of all CBS Bandwidth can't exceed 100\n"); -+ return -EINVAL; -+ } -+ -+ tc_max_sized_frame = enetc_port_rd(&si->hw, ENETC_PTCMSDUR(tc)); -+ -+ /* For top prio TC, the max_interfrence_size is maxSizedFrame. -+ * -+ * For next prio TC, the max_interfrence_size is calculated as below: -+ * -+ * max_interference_size = M0 + Ma + Ra * M0 / (R0 - Ra) -+ * -+ * - RA: idleSlope for AVB Class A -+ * - R0: port transmit rate -+ * - M0: maximum sized frame for the port -+ * - MA: maximum sized frame for AVB Class A -+ */ -+ -+ if (tc == prio_top) { -+ max_interference_size = port_frame_max_size * 8; -+ } else { -+ u32 m0, ma, r0, ra; -+ -+ m0 = port_frame_max_size * 8; -+ ma = enetc_port_rd(&si->hw, ENETC_PTCMSDUR(prio_top)) * 8; -+ ra = enetc_get_cbs_bw(&si->hw, prio_top) * -+ port_transmit_rate * 10000ULL; -+ r0 = port_transmit_rate * 1000000ULL; -+ max_interference_size = m0 + ma + -+ (u32)div_u64((u64)ra * m0, r0 - ra); -+ } -+ -+ /* hiCredit bits calculate by: -+ * -+ * maxSizedFrame * (idleSlope/portTxRate) -+ */ -+ hi_credit_bit = max_interference_size * bw / 100; -+ -+ /* hiCredit bits to hiCredit register need to calculated as: -+ * -+ * (enetClockFrequency / portTransmitRate) * 100 -+ */ -+ hi_credit_reg = (u32)div_u64((ENETC_CLK * 100ULL) * hi_credit_bit, -+ port_transmit_rate * 1000000ULL); -+ -+ enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), hi_credit_reg); -+ -+ /* Set bw register and enable this traffic class */ -+ enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE); -+ -+ return 0; -+} diff --git a/target/linux/layerscape/patches-5.4/701-net-0337-enetc-add-support-tsn-capabilities-qbv-qci-qbu-cbs.patch b/target/linux/layerscape/patches-5.4/701-net-0337-enetc-add-support-tsn-capabilities-qbv-qci-qbu-cbs.patch deleted file mode 100644 index dddb32a55c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0337-enetc-add-support-tsn-capabilities-qbv-qci-qbu-cbs.patch +++ /dev/null @@ -1,2911 +0,0 @@ -From bf3f81f3773cc9f6b273d769aca96512780c6189 Mon Sep 17 00:00:00 2001 -From: Po Liu -Date: Tue, 3 Dec 2019 16:52:57 +0800 -Subject: [PATCH] enetc: add support tsn capabilities qbv/qci/qbu/cbs - -Support Qbv/Qci/Qbu/Credit Base Shaper etc. -This patch using the generic netlink adapt layer driver net/tsn/* -and include/net/tsn.h interface load by user space. The user space -refer the include/uapi/linux/tsn.h. - -Signed-off-by: Po Liu ---- - drivers/net/ethernet/freescale/enetc/Kconfig | 10 + - drivers/net/ethernet/freescale/enetc/Makefile | 1 + - drivers/net/ethernet/freescale/enetc/enetc.c | 13 +- - drivers/net/ethernet/freescale/enetc/enetc.h | 38 + - .../net/ethernet/freescale/enetc/enetc_ethtool.c | 59 + - drivers/net/ethernet/freescale/enetc/enetc_hw.h | 438 ++++- - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 15 +- - drivers/net/ethernet/freescale/enetc/enetc_tsn.c | 2049 ++++++++++++++++++++ - 8 files changed, 2614 insertions(+), 9 deletions(-) - create mode 100644 drivers/net/ethernet/freescale/enetc/enetc_tsn.c - ---- a/drivers/net/ethernet/freescale/enetc/Kconfig -+++ b/drivers/net/ethernet/freescale/enetc/Kconfig -@@ -60,3 +60,13 @@ config FSL_ENETC_QOS - enable/disable from user space via Qos commands(tc). In the kernel - side, it can be loaded by Qos driver. Currently, it is only support - taprio(802.1Qbv) and Credit Based Shaper(802.1Qbu). -+ -+config ENETC_TSN -+ bool "TSN Support for NXP ENETC driver" -+ default n -+ depends on TSN && FSL_ENETC -+ help -+ This driver supports TSN on Freescale ENETC driver. Provide -+ interface to config the tsn capabilities of ENETC. The interface link -+ to the /net/tsn/* and include/net/tsn.h. User space refer the -+ include/uapi/linux/tsn.h. ---- a/drivers/net/ethernet/freescale/enetc/Makefile -+++ b/drivers/net/ethernet/freescale/enetc/Makefile -@@ -6,6 +6,7 @@ obj-$(CONFIG_FSL_ENETC) += fsl-enetc.o - fsl-enetc-y := enetc_pf.o enetc_mdio.o $(common-objs) - fsl-enetc-$(CONFIG_PCI_IOV) += enetc_msg.o - fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o -+fsl-enetc-$(CONFIG_ENETC_TSN) += enetc_tsn.o - - obj-$(CONFIG_FSL_ENETC_VF) += fsl-enetc-vf.o - fsl-enetc-vf-y := enetc_vf.o $(common-objs) ---- a/drivers/net/ethernet/freescale/enetc/enetc.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc.c -@@ -145,7 +145,8 @@ static int enetc_map_tx_buffs(struct ene - do_tstamp = (active_offloads & ENETC_F_TX_TSTAMP) && - (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP); - tx_swbd->do_tstamp = do_tstamp; -- tx_swbd->check_wb = tx_swbd->do_tstamp; -+ tx_swbd->qbv_en = !!(active_offloads & ENETC_F_QBV); -+ tx_swbd->check_wb = tx_swbd->do_tstamp || tx_swbd->qbv_en; - - if (do_vlan || do_tstamp) - flags |= ENETC_TXBD_FLAGS_EX; -@@ -342,7 +343,7 @@ static void enetc_tstamp_tx(struct sk_bu - static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget) - { - struct net_device *ndev = tx_ring->ndev; -- int tx_frm_cnt = 0, tx_byte_cnt = 0; -+ int tx_frm_cnt = 0, tx_byte_cnt = 0, tx_win_drop = 0; - struct enetc_tx_swbd *tx_swbd; - int i, bds_to_clean; - bool do_tstamp; -@@ -372,6 +373,10 @@ static bool enetc_clean_tx_ring(struct e - &tstamp); - do_tstamp = true; - } -+ -+ if (tx_swbd->qbv_en && -+ txbd->wb.status & ENETC_TXBD_STATS_WIN) -+ tx_win_drop++; - } - - if (likely(tx_swbd->dma)) -@@ -415,6 +420,7 @@ static bool enetc_clean_tx_ring(struct e - tx_ring->next_to_clean = i; - tx_ring->stats.packets += tx_frm_cnt; - tx_ring->stats.bytes += tx_byte_cnt; -+ tx_ring->stats.win_drop += tx_win_drop; - - if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) && - __netif_subqueue_stopped(ndev, tx_ring->index) && -@@ -778,6 +784,9 @@ void enetc_get_si_caps(struct enetc_si * - - if (val & ENETC_SIPCAPR0_QBV) - si->hw_features |= ENETC_SI_F_QBV; -+ -+ if (val & ENETC_SIPCAPR0_QBU) -+ si->hw_features |= ENETC_SI_F_QBU; - } - - static int enetc_dma_alloc_bdr(struct enetc_bdr *r, size_t bd_size) ---- a/drivers/net/ethernet/freescale/enetc/enetc.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc.h -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #include "enetc_hw.h" - -@@ -24,6 +25,7 @@ struct enetc_tx_swbd { - u8 is_dma_page:1; - u8 check_wb:1; - u8 do_tstamp:1; -+ u8 qbv_en:1; - }; - - #define ENETC_RX_MAXFRM_SIZE ENETC_MAC_MAXFRM_SIZE -@@ -42,6 +44,7 @@ struct enetc_ring_stats { - unsigned int packets; - unsigned int bytes; - unsigned int rx_alloc_errs; -+ unsigned int win_drop; - }; - - #define ENETC_BDR_DEFAULT_SIZE 1024 -@@ -111,6 +114,28 @@ struct enetc_msg_swbd { - int size; - }; - -+#ifdef CONFIG_ENETC_TSN -+/* Credit-Based Shaper parameters */ -+struct cbs { -+ u8 tc; -+ bool enable; -+ u8 bw; -+ u32 hi_credit; -+ u32 lo_credit; -+ u32 idle_slope; -+ u32 send_slope; -+ u32 tc_max_sized_frame; -+ u32 max_interfrence_size; -+}; -+ -+struct enetc_cbs { -+ u32 port_transmit_rate; -+ u32 port_max_size_frame; -+ u8 tc_nums; -+ struct cbs cbs[0]; -+}; -+#endif -+ - #define ENETC_REV1 0x1 - enum enetc_errata { - ENETC_ERR_TXCSUM = BIT(0), -@@ -119,6 +144,7 @@ enum enetc_errata { - }; - - #define ENETC_SI_F_QBV BIT(0) -+#define ENETC_SI_F_QBU BIT(1) - - /* PCI IEP device data */ - struct enetc_si { -@@ -136,6 +162,10 @@ struct enetc_si { - int num_rss; /* number of RSS buckets */ - unsigned short pad; - int hw_features; -+#ifdef CONFIG_ENETC_TSN -+ struct enetc_cbs *ecbs; -+#endif -+ - }; - - #define ENETC_SI_ALIGN 32 -@@ -177,6 +207,7 @@ enum enetc_active_offloads { - ENETC_F_RX_TSTAMP = BIT(0), - ENETC_F_TX_TSTAMP = BIT(1), - ENETC_F_QBV = BIT(2), -+ ENETC_F_QBU = BIT(3), - }; - - struct enetc_ndev_priv { -@@ -266,3 +297,10 @@ int enetc_setup_tc_cbs(struct net_device - #define enetc_sched_speed_set(ndev) (void)0 - #define enetc_setup_tc_cbs(ndev, type_data) -EOPNOTSUPP - #endif -+#ifdef CONFIG_ENETC_TSN -+void enetc_tsn_pf_init(struct net_device *netdev, struct pci_dev *pdev); -+void enetc_tsn_pf_deinit(struct net_device *netdev); -+#else -+#define enetc_tsn_pf_init(netdev, pdev) (void)0 -+#define enetc_tsn_pf_deinit(netdev) (void)0 -+#endif ---- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c -@@ -187,6 +187,21 @@ static const struct { - { ENETC_PICDR(3), "ICM DR3 discarded frames" }, - }; - -+static const struct { -+ int reg; -+ char name[ETH_GSTRING_LEN]; -+} enetc_pmac_counters[] = { -+ { ENETC_PM1_RFRM, "PMAC rx frames" }, -+ { ENETC_PM1_RPKT, "PMAC rx packets" }, -+ { ENETC_PM1_RDRP, "PMAC rx dropped packets" }, -+ { ENETC_PM1_RFRG, "PMAC rx fragment packets" }, -+ { ENETC_PM1_TFRM, "PMAC tx frames" }, -+ { ENETC_PM1_TERR, "PMAC tx error frames" }, -+ { ENETC_PM1_TPKT, "PMAC tx packets" }, -+ { ENETC_MAC_MERGE_MMFCRXR, "MAC merge fragment rx counter" }, -+ { ENETC_MAC_MERGE_MMFCTXR, "MAC merge fragment tx counter"}, -+}; -+ - static const char rx_ring_stats[][ETH_GSTRING_LEN] = { - "Rx ring %2d frames", - "Rx ring %2d alloc errors", -@@ -196,6 +211,10 @@ static const char tx_ring_stats[][ETH_GS - "Tx ring %2d frames", - }; - -+static const char tx_windrop_stats[][ETH_GSTRING_LEN] = { -+ "Tx window drop %2d frames", -+}; -+ - static int enetc_get_sset_count(struct net_device *ndev, int sset) - { - struct enetc_ndev_priv *priv = netdev_priv(ndev); -@@ -213,6 +232,12 @@ static int enetc_get_sset_count(struct n - - len += ARRAY_SIZE(enetc_port_counters); - -+ if (priv->active_offloads & ENETC_F_QBU) -+ len += ARRAY_SIZE(enetc_pmac_counters); -+ -+ if (priv->active_offloads & ENETC_F_QBV) -+ len += ARRAY_SIZE(tx_windrop_stats) * priv->num_tx_rings; -+ - return len; - } - -@@ -251,6 +276,28 @@ static void enetc_get_strings(struct net - ETH_GSTRING_LEN); - p += ETH_GSTRING_LEN; - } -+ -+ if (!(priv->active_offloads & ENETC_F_QBU)) -+ break; -+ -+ for (i = 0; i < ARRAY_SIZE(enetc_pmac_counters); i++) { -+ strlcpy(p, enetc_pmac_counters[i].name, -+ ETH_GSTRING_LEN); -+ p += ETH_GSTRING_LEN; -+ } -+ -+ if (!((priv->active_offloads & ENETC_F_QBV))) -+ break; -+ -+ for (i = 0; i < priv->num_tx_rings; i++) { -+ for (j = 0; j < ARRAY_SIZE(tx_windrop_stats); j++) { -+ snprintf(p, ETH_GSTRING_LEN, -+ tx_windrop_stats[j], -+ i); -+ p += ETH_GSTRING_LEN; -+ } -+ } -+ - break; - } - } -@@ -278,6 +325,18 @@ static void enetc_get_ethtool_stats(stru - - for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++) - data[o++] = enetc_port_rd(hw, enetc_port_counters[i].reg); -+ -+ if (!(priv->active_offloads & ENETC_F_QBU)) -+ return; -+ -+ for (i = 0; i < ARRAY_SIZE(enetc_pmac_counters); i++) -+ data[o++] = enetc_port_rd(hw, enetc_pmac_counters[i].reg); -+ -+ if (!((priv->active_offloads & ENETC_F_QBV))) -+ return; -+ -+ for (i = 0; i < priv->num_tx_rings; i++) -+ data[o++] = priv->tx_ring[i]->stats.win_drop; - } - - #define ENETC_RSSHASH_L3 (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO | RXH_IP_SRC | \ ---- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h -@@ -19,6 +19,7 @@ - #define ENETC_SICTR1 0x1c - #define ENETC_SIPCAPR0 0x20 - #define ENETC_SIPCAPR0_QBV BIT(4) -+#define ENETC_SIPCAPR0_QBU BIT(3) - #define ENETC_SIPCAPR0_RSS BIT(8) - #define ENETC_SIPCAPR1 0x24 - #define ENETC_SITGTGR 0x30 -@@ -243,10 +244,20 @@ enum enetc_bdr_type {TX, RX}; - #define ENETC_PCS_IF_MODE_SGMII_AN 0x0003 - - #define ENETC_PM0_IF_MODE 0x8300 -+#define ENETC_PM1_IF_MODE 0x9300 - #define ENETC_PMO_IFM_RG BIT(2) - #define ENETC_PM0_IFM_RLP (BIT(5) | BIT(11)) - #define ENETC_PM0_IFM_RGAUTO (BIT(15) | ENETC_PMO_IFM_RG | BIT(1)) - #define ENETC_PM0_IFM_XGMII BIT(12) -+#define ENETC_PSIDCAPR 0x1b08 -+#define ENETC_PSIDCAPR_MSK GENMASK(15, 0) -+#define ENETC_PSFCAPR 0x1b18 -+#define ENETC_PSFCAPR_MSK GENMASK(15, 0) -+#define ENETC_PSGCAPR 0x1b28 -+#define ENETC_PSGCAPR_GCL_MSK GENMASK(18, 16) -+#define ENETC_PSGCAPR_SGIT_MSK GENMASK(15, 0) -+#define ENETC_PFMCAPR 0x1b38 -+#define ENETC_PFMCAPR_MSK GENMASK(15, 0) - - /* MAC counters */ - #define ENETC_PM0_REOCT 0x8100 -@@ -300,6 +311,15 @@ enum enetc_bdr_type {TX, RX}; - #define ENETC_PM0_TSCOL 0x82E0 - #define ENETC_PM0_TLCOL 0x82E8 - #define ENETC_PM0_TECOL 0x82F0 -+#define ENETC_PM1_RFRM 0x9120 -+#define ENETC_PM1_RDRP 0x9158 -+#define ENETC_PM1_RPKT 0x9160 -+#define ENETC_PM1_RFRG 0x91B8 -+#define ENETC_PM1_TFRM 0x9220 -+#define ENETC_PM1_TERR 0x9238 -+#define ENETC_PM1_TPKT 0x9260 -+#define ENETC_MAC_MERGE_MMFCRXR 0x1f14 -+#define ENETC_MAC_MERGE_MMFCTXR 0x1f18 - - /* Port counters */ - #define ENETC_PICDR(n) (0x0700 + (n) * 8) /* n = [0..3] */ -@@ -458,6 +478,7 @@ union enetc_tx_bd { - #define ENETC_TXBD_FLAGS_CSUM BIT(3) - #define ENETC_TXBD_FLAGS_EX BIT(6) - #define ENETC_TXBD_FLAGS_F BIT(7) -+#define ENETC_TXBD_STATS_WIN BIT(7) - - static inline void enetc_clear_tx_bd(union enetc_tx_bd *txbd) - { -@@ -485,6 +506,8 @@ static inline __le16 enetc_txbd_l3_csoff - #define ENETC_TXBD_L4_UDP BIT(5) - #define ENETC_TXBD_L4_TCP BIT(6) - -+#define enetc_tsn_is_enabled() IS_ENABLED(CONFIG_ENETC_TSN) -+ - union enetc_rx_bd { - struct { - __le64 addr; -@@ -631,21 +654,307 @@ enum bdcr_cmd_class { - BDCR_CMD_RFS, - BDCR_CMD_PORT_GCL, - BDCR_CMD_RECV_CLASSIFIER, -+ BDCR_CMD_STREAM_IDENTIFY, -+ BDCR_CMD_STREAM_FILTER, -+ BDCR_CMD_STREAM_GCL, -+ BDCR_CMD_FLOW_METER, - __BDCR_CMD_MAX_LEN, - BDCR_CMD_MAX_LEN = __BDCR_CMD_MAX_LEN - 1, - }; - -+/* class 7, command 0, Stream Identity Entry Configuration */ -+struct streamid_conf { -+ __le32 stream_handle; /* init gate value */ -+ __le32 iports; -+ u8 id_type; -+ u8 oui[3]; -+ u8 res[3]; -+ u8 en; -+}; -+ -+#define ENETC_CBDR_SID_VID_MASK 0xfff -+#define ENETC_CBDR_SID_VIDM BIT(12) -+#define ENETC_CBDR_SID_TG_MASK 0xc000 -+/* streamid_conf address point to this data space */ -+struct null_streamid_data { -+ u8 dmac[6]; -+ u16 vid_vidm_tg; -+}; -+ -+struct smac_streamid_data { -+ u8 smac[6]; -+ u16 vid_vidm_tg; -+}; -+ -+/* class 7, command 1, query config , long format */ -+/* No need structure define */ -+ -+#define ENETC_CDBR_SID_ENABLE BIT(7) -+/* Stream ID Query Response Data Buffer */ -+struct streamid_query_resp { -+ u32 stream_handle; -+ u32 input_ports; -+ u8 id_type; -+ u8 oui[3]; -+ u8 mac[6]; -+ u16 vid_vidm_tg; -+ u8 res[3]; -+ u8 en; -+}; -+ -+/* class 7, command 2, qeury status count, Stream ID query long format */ -+struct streamid_stat_query { -+ u8 res[12]; -+ __le32 input_ports; -+}; -+ -+/* Stream Identity Statistics Query */ -+struct streamid_stat_query_resp { -+ u32 psinl; -+ u32 psinh; -+ u64 pspi[32]; -+}; -+ -+#define ENETC_CBDR_SFI_PRI_MASK 0x7 -+#define ENETC_CBDR_SFI_PRIM BIT(3) -+#define ENETC_CBDR_SFI_BLOV BIT(4) -+#define ENETC_CBDR_SFI_BLEN BIT(5) -+#define ENETC_CBDR_SFI_MSDUEN BIT(6) -+#define ENETC_CBDR_SFI_FMITEN BIT(7) -+#define ENETC_CBDR_SFI_ENABLE BIT(7) -+/* class 8, command 0, Stream Filter Instance, Short Format */ -+struct sfi_conf { -+ __le32 stream_handle; -+ u8 multi; -+ u8 res[2]; -+ u8 sthm; -+ /* Max Service Data Unit or Flow Meter Instance Table index. -+ * Depending on the value of FLT this represents either Max -+ * Service Data Unit (max frame size) allowed by the filter -+ * entry or is an index into the Flow Meter Instance table -+ * index identifying the policer which will be used to police -+ * it. -+ */ -+ __le16 fm_inst_table_index; -+ __le16 msdu; -+ __le16 sg_inst_table_index; -+ u8 res1[2]; -+ __le32 input_ports; -+ u8 res2[3]; -+ u8 en; -+}; -+ -+/* class 8, command 1, Stream Filter Instance, write back, short Format */ -+struct sfi_query { -+ u32 stream_handle; -+ u8 multi; -+ u8 res[2]; -+ u8 sthm; -+ u16 fm_inst_table_index; -+ u16 msdu; -+ u16 sg_inst_table_index; -+ u8 res1[2]; -+ u32 input_ports; -+ u8 res2[3]; -+ u8 en; -+}; -+ -+/* class 8, command 2 stream Filter Instance status query short format -+ * command no need structure define -+ * Stream Filter Instance Query Statistics Response data -+ */ -+struct sfi_counter_data { -+ u32 matchl; -+ u32 matchh; -+ u32 msdu_dropl; -+ u32 msdu_droph; -+ u32 stream_gate_dropl; -+ u32 stream_gate_droph; -+ u32 flow_meter_dropl; -+ u32 flow_meter_droph; -+}; -+ -+#define ENETC_CBDR_SGI_OIPV_MASK 0x7 -+#define ENETC_CBDR_SGI_OIPV_EN BIT(3) -+#define ENETC_CBDR_SGI_CGTST BIT(6) -+#define ENETC_CBDR_SGI_OGTST BIT(7) -+#define ENETC_CBDR_SGI_CFG_CHG BIT(1) -+#define ENETC_CBDR_SGI_CFG_PND BIT(2) -+#define ENETC_CBDR_SGI_OEX BIT(4) -+#define ENETC_CBDR_SGI_OEXEN BIT(5) -+#define ENETC_CBDR_SGI_IRX BIT(6) -+#define ENETC_CBDR_SGI_IRXEN BIT(7) -+#define ENETC_CBDR_SGI_ACLLEN_MASK 0x3 -+#define ENETC_CBDR_SGI_OCLLEN_MASK 0xc -+#define ENETC_CBDR_SGI_EN BIT(7) -+/* class 9, command 0, Stream Gate Instance Table, Short Format -+ * class 9, command 2, Stream Gate Instance Table entry query write back -+ * Short Format -+ */ -+struct sgi_table { -+ u8 res[8]; -+ u8 oipv; -+ u8 res0[2]; -+ u8 ocgtst; -+ u8 res1[7]; -+ u8 gset; -+ u8 oacl_len; -+ u8 res2[2]; -+ u8 en; -+}; -+ -+#define ENETC_CBDR_SGI_AIPV_MASK 0x7 -+#define ENETC_CBDR_SGI_AIPV_EN BIT(3) -+#define ENETC_CBDR_SGI_AGTST BIT(7) -+ -+/* class 9, command 1, Stream Gate Control List, Long Format */ -+struct sgcl_conf { -+ u8 aipv; -+ u8 res[2]; -+ u8 agtst; -+ u8 res1[4]; -+ union { -+ struct { -+ u8 res2[4]; -+ u8 acl_len; -+ u8 res3[3]; -+ }; -+ u8 cct[8]; /* Config change time */ -+ }; -+}; -+ -+/* stream control list class 9 , cmd 1 data buffer */ -+struct sgcl_data { -+ u32 btl; -+ u32 bth; -+ u32 ct; -+ u32 cte; -+ /*struct sgce *sgcl;*/ -+}; -+ -+/* class 9, command 2, stream gate instant table enery query, short format -+ * write back see struct sgi_table. Do not need define. -+ * class 9, command 3 Stream Gate Control List Query Descriptor - Long Format -+ * ocl_len or acl_len to be 0, oper or admin would not show in the data space -+ * true len will be write back in the space. -+ */ -+struct sgcl_query { -+ u8 res[12]; -+ u8 oacl_len; -+ u8 res1[3]; -+}; -+ -+/* define for 'stat' */ -+#define ENETC_CBDR_SGIQ_AIPV_MASK 0x7 -+#define ENETC_CBDR_SGIQ_AIPV_EN BIT(3) -+#define ENETC_CBDR_SGIQ_AGTST BIT(4) -+#define ENETC_CBDR_SGIQ_ACL_LEN_MASK 0x60 -+#define ENETC_CBDR_SGIQ_OIPV_MASK 0x380 -+#define ENETC_CBDR_SGIQ_OIPV_EN BIT(10) -+#define ENETC_CBDR_SGIQ_OGTST BIT(11) -+#define ENETC_CBDR_SGIQ_OCL_LEN_MASK 0x3000 -+/* class 9, command 3 data space */ -+struct sgcl_query_resp { -+ u16 stat; -+ u16 res; -+ u32 abtl; -+ u32 abth; -+ u32 act; -+ u32 acte; -+ u32 cctl; -+ u32 ccth; -+ u32 obtl; -+ u32 obth; -+ u32 oct; -+ u32 octe; -+}; -+ -+/* class 9, command 4 Stream Gate Instance Table Query Statistics Response -+ * short command, write back, no command define -+ */ -+struct sgi_query_stat_resp { -+ u32 pgcl; -+ u32 pgch; -+ u32 dgcl; -+ u32 dgch; -+ u16 msdu_avail; -+ u8 res[6]; -+}; -+ -+#define ENETC_CBDR_FMI_MR BIT(0) -+#define ENETC_CBDR_FMI_MREN BIT(1) -+#define ENETC_CBDR_FMI_DOY BIT(2) -+#define ENETC_CBDR_FMI_CM BIT(3) -+#define ENETC_CBDR_FMI_CF BIT(4) -+#define ENETC_CBDR_FMI_NDOR BIT(5) -+#define ENETC_CBDR_FMI_OALEN BIT(6) -+#define ENETC_CBDR_FMI_IRFPP_MASK 0x1f -+/* class 10: command 0/1, Flow Meter Instance Set, short Format */ -+struct fmi_conf { -+ __le32 cir; -+ __le32 cbs; -+ __le32 eir; -+ __le32 ebs; -+ u8 conf; -+ u8 res1; -+ u8 ir_fpp; -+ u8 res2[4]; -+ u8 en; -+}; -+ -+/* class:10, command:2, Flow Meter Instance Statistics Query Response */ -+struct fmi_query_stat_resp { -+ u32 bcl; -+ u32 bch; -+ u32 dfl; -+ u32 dfh; -+ u32 d0gfl; -+ u32 d0gfh; -+ u32 d1gfl; -+ u32 d1gfh; -+ u32 dyfl; -+ u32 dyfh; -+ u32 ryfl; -+ u32 ryfh; -+ u32 drfl; -+ u32 drfh; -+ u32 rrfl; -+ u32 rrfh; -+ u32 lts; -+ u32 bci; -+ u32 bcf; -+ u32 bei; -+ u32 bef; -+}; -+ - /* class 5, command 0 */ - struct tgs_gcl_conf { - u8 atc; /* init gate value */ - u8 res[7]; -- struct { -- u8 res1[4]; -- __le16 acl_len; -- u8 res2[2]; -+ union { -+ struct { -+ u8 res1[4]; -+ __le16 acl_len; -+ u8 res2[2]; -+ }; -+ struct { -+ u32 cctl; -+ u32 ccth; -+ }; - }; - }; - -+#define ENETC_CBDR_SGL_IOMEN BIT(0) -+#define ENETC_CBDR_SGL_IPVEN BIT(3) -+#define ENETC_CBDR_SGL_GTST BIT(4) -+#define ENETC_CBDR_SGL_IPV_MASK 0xe -+/* Stream Gate Control List Entry */ -+struct sgce { -+ u32 interval; -+ u8 msdu[3]; -+ u8 multi; -+}; -+ - /* gate control list entry */ - struct gce { - __le32 period; -@@ -662,13 +971,55 @@ struct tgs_gcl_data { - struct gce entry[0]; - }; - -+/* class 5, command 1 */ -+struct tgs_gcl_query { -+ u8 res[12]; -+ union { -+ struct { -+ __le16 acl_len; /* admin list length */ -+ __le16 ocl_len; /* operation list length */ -+ }; -+ struct { -+ u16 admin_list_len; -+ u16 oper_list_len; -+ }; -+ }; -+ -+}; -+ -+/* tgs_gcl_query command response data format */ -+struct tgs_gcl_resp { -+ u32 abtl; /* base time */ -+ u32 abth; -+ u32 act; /* cycle time */ -+ u32 acte; /* cycle time extend */ -+ u32 cctl; /* config change time */ -+ u32 ccth; -+ u32 obtl; /* operation base time */ -+ u32 obth; -+ u32 oct; /* operation cycle time */ -+ u32 octe; /* operation cycle time extend */ -+ u32 ccel; /* config change error */ -+ u32 cceh; -+ /*struct gce *gcl;*/ -+}; -+ - struct enetc_cbd { - union{ -+ struct sfi_conf sfi_conf; -+ struct sgi_table sgi_table; -+ struct sgi_query_stat_resp sgi_query_stat_resp; -+ struct fmi_conf fmi_conf; - struct { - __le32 addr[2]; - union { - __le32 opt[4]; -- struct tgs_gcl_conf gcl_conf; -+ struct tgs_gcl_conf gcl_conf; -+ struct tgs_gcl_query gcl_query; -+ struct streamid_conf sid_set; -+ struct streamid_stat_query sid_stat; -+ struct sgcl_conf sgcl_conf; -+ struct sgcl_query sgcl_query; - }; - }; /* Long format */ - __le32 data[6]; -@@ -683,11 +1034,88 @@ struct enetc_cbd { - - #define ENETC_CLK 400000000ULL - -+#define ENETC_PTCFPR(n) (0x1910 + (n) * 4) /* n = [0 ..7] */ -+#define ENETC_FPE BIT(31) -+ -+/* Port capability register 0 */ -+#define ENETC_PCAPR0_PSFPM BIT(10) -+#define ENETC_PCAPR0_PSFP BIT(9) -+#define ENETC_PCAPR0_TSN BIT(4) -+#define ENETC_PCAPR0_QBU BIT(3) -+ - /* port time gating control register */ - #define ENETC_QBV_PTGCR_OFFSET 0x11a00 - #define ENETC_QBV_TGE BIT(31) - #define ENETC_QBV_TGPE BIT(30) -+#define ENETC_QBV_TGDROP_DISABLE BIT(29) - - /* Port time gating capability register */ - #define ENETC_QBV_PTGCAPR_OFFSET 0x11a08 - #define ENETC_QBV_MAX_GCL_LEN_MASK GENMASK(15, 0) -+ -+/* Port time gating tick granularity register */ -+#define ENETC_QBV_PTGTGR_OFFSET 0x11a0c -+#define ENETC_QBV_TICK_GRAN_MASK 0xffffffff -+ -+/* Port time gating admin gate list status register */ -+#define ENETC_QBV_PTGAGLSR_OFFSET 0x11a10 -+ -+#define ENETC_QBV_CFG_PEND_MASK 0x00000002 -+ -+/* Port time gating admin gate list length register */ -+#define ENETC_QBV_PTGAGLLR_OFFSET 0x11a14 -+#define ENETC_QBV_ADMIN_GATE_LIST_LENGTH_MASK 0xffff -+ -+/* Port time gating operational gate list status register */ -+#define ENETC_QBV_PTGOGLSR_OFFSET 0x11a18 -+#define ENETC_QBV_HTA_POS_MASK 0xffff0000 -+ -+#define ENETC_QBV_CURR_POS_MASK 0x0000ffff -+ -+/* Port time gating operational gate list length register */ -+#define ENETC_QBV_PTGOGLLR_OFFSET 0x11a1c -+#define ENETC_QBV_OPER_GATE_LIST_LENGTH_MASK 0xffff -+ -+/* Port time gating current time register */ -+#define ENETC_QBV_PTGCTR_OFFSET 0x11a20 -+#define ENETC_QBV_CURR_TIME_MASK 0xffffffffffffffff -+ -+/* Port traffic class a time gating control register */ -+#define ENETC_QBV_PTC0TGCR_OFFSET 0x11a40 -+#define ENETC_QBV_PTC1TGCR_OFFSET 0x11a50 -+#define ENETC_QBV_PTC2TGCR_OFFSET 0x11a60 -+#define ENETC_QBV_PTC3TGCR_OFFSET 0x11a70 -+#define ENETC_QBV_PTC4TGCR_OFFSET 0x11a80 -+#define ENETC_QBV_PTC5TGCR_OFFSET 0x11a90 -+#define ENETC_QBV_PTC6TGCR_OFFSET 0x11aa0 -+#define ENETC_QBV_PTC7TGCR_OFFSET 0x11ab0 -+ -+/* Maximum Service Data Unit. */ -+#define ENETC_PTC0MSDUR 0x12020 -+#define ENETC_PTC1MSDUR 0x12024 -+#define ENETC_PTC2MSDUR 0x12028 -+#define ENETC_PTC3MSDUR 0x1202c -+#define ENETC_PTC4MSDUR 0x12030 -+#define ENETC_PTC5MSDUR 0x12034 -+#define ENETC_PTC6MSDUR 0x12038 -+#define ENETC_PTC7MSDUR 0x1203c -+ -+#define ENETC_QBV_MAXSDU_MASK 0xffff -+ -+/* Port traffic class a time gating status register */ -+#define ENETC_QBV_PTC0TGSR_OFFSET 0x11a44 -+#define ENETC_QBV_HTA_STATE_MASK 0x10000 -+#define ENETC_QBV_CURR_STATE_MASK 0x1 -+ -+/* Port traffic class a time gating transmission overrun counter register*/ -+#define ENETC_QBV_PTC0TGTOCR_OFFSET 0x11a48 -+#define ENETC_QBV_TX_OVERRUN_MASK 0xffffffffffffffff -+#define ENETC_TGLSTR 0xa200 -+#define ENETC_TGS_MIN_DIS_MASK 0x80000000 -+#define ENETC_MIN_LOOKAHEAD_MASK 0xffff -+ -+#define ENETC_PPSFPMR 0x11b00 -+#define ENETC_PPSFPMR_PSFPEN BIT(0) -+#define ENETC_PPSFPMR_VS BIT(1) -+#define ENETC_PPSFPMR_PVC BIT(2) -+#define ENETC_PPSFPMR_PVZC BIT(3) ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -525,12 +525,16 @@ static void enetc_configure_port_mac(str - ENETC_PM0_TX_EN | ENETC_PM0_RX_EN); - /* set auto-speed for RGMII */ - if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG || -- phy_mode == PHY_INTERFACE_MODE_RGMII) -+ phy_mode == PHY_INTERFACE_MODE_RGMII) { - enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO); -+ enetc_port_wr(hw, ENETC_PM1_IF_MODE, ENETC_PM0_IFM_RGAUTO); -+ } - - if (phy_mode == PHY_INTERFACE_MODE_XGMII || -- phy_mode == PHY_INTERFACE_MODE_USXGMII) -+ phy_mode == PHY_INTERFACE_MODE_USXGMII) { - enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII); -+ enetc_port_wr(hw, ENETC_PM1_IF_MODE, ENETC_PM0_IFM_XGMII); -+ } - } - - static void enetc_configure_port_pmac(struct enetc_hw *hw) -@@ -749,6 +753,9 @@ static void enetc_pf_netdev_setup(struct - if (si->hw_features & ENETC_SI_F_QBV) - priv->active_offloads |= ENETC_F_QBV; - -+ if (enetc_tsn_is_enabled() && (si->hw_features & ENETC_SI_F_QBU)) -+ priv->active_offloads |= ENETC_F_QBU; -+ - /* pick up primary MAC address from SI */ - enetc_get_primary_mac_addr(&si->hw, ndev->dev_addr); - } -@@ -1027,6 +1034,8 @@ static int enetc_pf_probe(struct pci_dev - netif_info(priv, probe, ndev, "%s v%s\n", - enetc_drv_name, enetc_drv_ver); - -+ enetc_tsn_pf_init(ndev, pdev); -+ - return 0; - - err_reg_netdev: -@@ -1063,6 +1072,8 @@ static void enetc_pf_remove(struct pci_d - netif_info(priv, drv, si->ndev, "%s v%s remove\n", - enetc_drv_name, enetc_drv_ver); - -+ enetc_tsn_pf_deinit(si->ndev); -+ - unregister_netdev(si->ndev); - - enetc_mdio_remove(pf); ---- /dev/null -+++ b/drivers/net/ethernet/freescale/enetc/enetc_tsn.c -@@ -0,0 +1,2049 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* Copyright 2017-2019 NXP */ -+ -+#ifdef CONFIG_ENETC_TSN -+#include "enetc.h" -+ -+#include -+#include -+#include -+#include -+ -+static u32 get_ndev_speed(struct net_device *netdev); -+ -+static int alloc_cbdr(struct enetc_si *si, struct enetc_cbd **curr_cbd) -+{ -+ struct enetc_cbdr *ring = &si->cbd_ring; -+ int i; -+ -+ i = ring->next_to_use; -+ *curr_cbd = ENETC_CBD(*ring, i); -+ -+ memset(*curr_cbd, 0, sizeof(struct enetc_cbd)); -+ return i; -+} -+ -+/* Transmit the BD control ring by writing the pir register. -+ * Update the counters maintained by software. -+ */ -+static int xmit_cbdr(struct enetc_si *si, int i) -+{ -+ struct enetc_cbdr *ring = &si->cbd_ring; -+ struct enetc_cbd *dest_cbd; -+ int nc, timeout; -+ -+ i = (i + 1) % ring->bd_count; -+ -+ ring->next_to_use = i; -+ /* let H/W know BD ring has been updated */ -+ enetc_wr_reg(ring->pir, i); -+ -+ timeout = ENETC_CBDR_TIMEOUT; -+ -+ do { -+ if (enetc_rd_reg(ring->cir) == i) -+ break; -+ usleep_range(10, 20); -+ timeout -= 10; -+ } while (timeout); -+ -+ if (!timeout) -+ return -EBUSY; -+ -+ nc = ring->next_to_clean; -+ -+ while (enetc_rd_reg(ring->cir) != nc) { -+ dest_cbd = ENETC_CBD(*ring, nc); -+ if (dest_cbd->status_flags & ENETC_CBD_STATUS_MASK) -+ WARN_ON(1); -+ -+ nc = (nc + 1) % ring->bd_count; -+ } -+ -+ ring->next_to_clean = nc; -+ -+ return 0; -+} -+ -+static inline u64 get_current_time(struct enetc_si *si) -+{ -+ u64 tmp = 0; -+ -+ tmp = (u64)enetc_rd(&si->hw, ENETC_SICTR0); -+ return ((u64)enetc_rd(&si->hw, ENETC_SICTR1) << 32) + tmp; -+} -+ -+/* Class 10: Flow Meter Instance Statistics Query Descriptor - Long Format */ -+int enetc_qci_fmi_counters_get(struct net_device *ndev, u32 index, -+ struct fmi_query_stat_resp *counters) -+{ -+ struct enetc_cbd *cbdr; -+ struct fmi_query_stat_resp *fmi_data; -+ dma_addr_t dma; -+ u16 data_size, dma_size; -+ int curr_cbd; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ cbdr->index = cpu_to_le16((u16)index); -+ cbdr->cmd = 2; -+ cbdr->cls = BDCR_CMD_FLOW_METER; -+ cbdr->status_flags = 0; -+ -+ data_size = sizeof(struct fmi_query_stat_resp); -+ -+ fmi_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!fmi_data) -+ return -ENOMEM; -+ -+ dma_size = cpu_to_le16(data_size); -+ cbdr->length = dma_size; -+ -+ dma = dma_map_single(&priv->si->pdev->dev, fmi_data, -+ data_size, DMA_FROM_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ kfree(fmi_data); -+ return -ENOMEM; -+ } -+ cbdr->addr[0] = lower_32_bits(dma); -+ cbdr->addr[1] = upper_32_bits(dma); -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ memcpy(counters, fmi_data, sizeof(struct fmi_query_stat_resp)); -+ -+ memset(cbdr, 0, sizeof(*cbdr)); -+ kfree(fmi_data); -+ return 0; -+} -+ -+u16 enetc_get_max_gcl_len(struct enetc_hw *hw) -+{ -+ return (enetc_rd(hw, ENETC_QBV_PTGCAPR_OFFSET) -+ & ENETC_QBV_MAX_GCL_LEN_MASK); -+} -+ -+void enetc_pspeed_set(struct net_device *ndev) -+{ -+ u32 speed, pspeed; -+ u32 difflag = 0; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ -+ speed = get_ndev_speed(ndev); -+ pspeed = enetc_port_rd(&priv->si->hw, ENETC_PMR) -+ & ENETC_PMR_PSPEED_MASK; -+ switch (speed) { -+ case SPEED_1000: -+ if (pspeed != ENETC_PMR_PSPEED_1000M) { -+ difflag = 1; -+ pspeed = ENETC_PMR_PSPEED_1000M; -+ } -+ break; -+ case SPEED_2500: -+ if (pspeed != ENETC_PMR_PSPEED_2500M) { -+ difflag = 1; -+ pspeed = ENETC_PMR_PSPEED_2500M; -+ } -+ -+ break; -+ case SPEED_100: -+ if (pspeed != ENETC_PMR_PSPEED_100M) { -+ difflag = 1; -+ pspeed = ENETC_PMR_PSPEED_100M; -+ } -+ break; -+ case SPEED_10: -+ if (pspeed != ENETC_PMR_PSPEED_10M) { -+ difflag = 1; -+ pspeed = ENETC_PMR_PSPEED_10M; -+ } -+ break; -+ default: -+ netdev_err(ndev, "not support speed\n"); -+ } -+ -+ if (difflag) { -+ enetc_port_wr(&priv->si->hw, ENETC_PMR, -+ (enetc_port_rd(&priv->si->hw, ENETC_PMR) -+ & (~ENETC_PMR_PSPEED_MASK)) -+ | pspeed); -+ } -+} -+ -+/* CBD Class 5: Time Gated Scheduling Gate Control List configuration -+ * Descriptor - Long Format -+ */ -+int enetc_qbv_set(struct net_device *ndev, struct tsn_qbv_conf *admin_conf) -+{ -+ struct enetc_cbd *cbdr; -+ struct tgs_gcl_data *gcl_data; -+ struct tgs_gcl_conf *gcl_config; -+ struct gce *gce; -+ u16 gcl_len; -+ u16 data_size; -+ int i; -+ dma_addr_t dma; -+ int curr_cbd; -+ struct tsn_qbv_basic *admin_basic = &admin_conf->admin; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ u32 temp; -+ u64 tempclock; -+ struct tsn_port *port; -+ -+ port = tsn_get_port(ndev); -+ if (!port) { -+ netdev_err(priv->si->ndev, "TSN device not registered!\n"); -+ return -ENODEV; -+ } -+ -+ enetc_pspeed_set(ndev); -+ -+ gcl_len = admin_basic->control_list_length; -+ if (gcl_len > enetc_get_max_gcl_len(&priv->si->hw)) -+ return -EINVAL; -+ -+ temp = enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET); -+ if (admin_conf->gate_enabled && !(temp & ENETC_QBV_TGE)) { -+ enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET, -+ temp & (~ENETC_QBV_TGE)); -+ usleep_range(10, 20); -+ enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET, -+ temp | ENETC_QBV_TGE); -+ } else if (!admin_conf->gate_enabled) { -+ enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET, -+ temp & (~ENETC_QBV_TGE)); -+ memcpy(&port->nd.ntdata, admin_conf, sizeof(*admin_conf)); -+ call_tsn_notifiers(TSN_QBV_CONFIGCHANGETIME_ARRIVE, -+ ndev, &port->nd); -+ return 0; -+ } -+ -+ /* Set the maximum frame size for each traffic class index -+ * PTCaMSDUR[MAXSDU]. The maximum frame size cannot exceed -+ * 9,600 bytes (0x2580). Frames that exceed the limit are -+ * discarded. -+ */ -+ if (admin_conf->maxsdu) { -+ enetc_wr(&priv->si->hw, ENETC_PTC0MSDUR, admin_conf->maxsdu); -+ enetc_wr(&priv->si->hw, ENETC_PTC1MSDUR, admin_conf->maxsdu); -+ enetc_wr(&priv->si->hw, ENETC_PTC2MSDUR, admin_conf->maxsdu); -+ enetc_wr(&priv->si->hw, ENETC_PTC3MSDUR, admin_conf->maxsdu); -+ enetc_wr(&priv->si->hw, ENETC_PTC4MSDUR, admin_conf->maxsdu); -+ enetc_wr(&priv->si->hw, ENETC_PTC5MSDUR, admin_conf->maxsdu); -+ enetc_wr(&priv->si->hw, ENETC_PTC6MSDUR, admin_conf->maxsdu); -+ enetc_wr(&priv->si->hw, ENETC_PTC7MSDUR, admin_conf->maxsdu); -+ } -+ -+ /* Configure the (administrative) gate control list using the -+ * control BD descriptor. -+ */ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ gcl_config = &cbdr->gcl_conf; -+ -+ data_size = struct_size(gcl_data, entry, gcl_len); -+ -+ gcl_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!gcl_data) -+ return -ENOMEM; -+ -+ gce = &gcl_data->entry[0]; -+ -+ gcl_config->atc = admin_basic->gate_states; -+ gcl_config->acl_len = cpu_to_le16(gcl_len); -+ -+ if (!admin_basic->base_time) { -+ gcl_data->btl = -+ cpu_to_le32(enetc_rd(&priv->si->hw, ENETC_SICTR0)); -+ gcl_data->bth = -+ cpu_to_le32(enetc_rd(&priv->si->hw, ENETC_SICTR1)); -+ } else { -+ gcl_data->btl = -+ cpu_to_le32(lower_32_bits(admin_basic->base_time)); -+ gcl_data->bth = -+ cpu_to_le32(upper_32_bits(admin_basic->base_time)); -+ } -+ -+ gcl_data->ct = cpu_to_le32(admin_basic->cycle_time); -+ gcl_data->cte = cpu_to_le32(admin_basic->cycle_time_extension); -+ -+ for (i = 0; i < gcl_len; i++) { -+ struct gce *temp_gce = gce + i; -+ struct tsn_qbv_entry *temp_entry; -+ -+ temp_entry = admin_basic->control_list + i; -+ -+ temp_gce->gate = temp_entry->gate_state; -+ temp_gce->period = cpu_to_le32(temp_entry->time_interval); -+ } -+ -+ cbdr->length = cpu_to_le16(data_size); -+ cbdr->status_flags = 0; -+ -+ dma = dma_map_single(&priv->si->pdev->dev, gcl_data, -+ data_size, DMA_TO_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ kfree(gcl_data); -+ return -ENOMEM; -+ } -+ -+ cbdr->addr[0] = lower_32_bits(dma); -+ cbdr->addr[1] = upper_32_bits(dma); -+ cbdr->cmd = 0; -+ cbdr->cls = BDCR_CMD_PORT_GCL; -+ -+ /* Updated by ENETC on completion of the configuration -+ * command. A zero value indicates success. -+ */ -+ cbdr->status_flags = 0; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ memcpy(&port->nd.ntdata, admin_conf, sizeof(*admin_conf)); -+ -+ tempclock = ((u64)le32_to_cpu(gcl_config->ccth)) << 32; -+ port->nd.ntdata.qbv_notify.admin.base_time = -+ le32_to_cpu(gcl_config->cctl) + tempclock; -+ -+ memset(cbdr, 0, sizeof(struct enetc_cbd)); -+ dma_unmap_single(&priv->si->pdev->dev, dma, data_size, DMA_TO_DEVICE); -+ kfree(gcl_data); -+ -+ call_tsn_notifiers(TSN_QBV_CONFIGCHANGETIME_ARRIVE, -+ ndev, &port->nd); -+ -+ return 0; -+} -+ -+/* CBD Class 5: Time Gated Scheduling Gate Control List query -+ * Descriptor - Long Format -+ */ -+int enetc_qbv_get(struct net_device *ndev, struct tsn_qbv_conf *admin_conf) -+{ -+ struct enetc_cbd *cbdr; -+ struct tgs_gcl_resp *gcl_data; -+ struct tgs_gcl_query *gcl_query; -+ struct gce *gce; -+ struct tsn_qbv_basic *admin_basic = &admin_conf->admin; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ dma_addr_t dma; -+ int curr_cbd; -+ u16 maxlen; -+ u16 data_size, dma_size; -+ u16 admin_len; -+ u16 oper_len; -+ u64 temp; -+ int i; -+ -+ if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE) { -+ admin_conf->gate_enabled = true; -+ } else { -+ admin_conf->gate_enabled = false; -+ return 0; -+ } -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ gcl_query = &cbdr->gcl_query; -+ -+ maxlen = enetc_get_max_gcl_len(&priv->si->hw); -+ -+ data_size = sizeof(struct tgs_gcl_resp) -+ + sizeof(struct gce) * 2 * maxlen; -+ -+ gcl_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!gcl_data) -+ return -ENOMEM; -+ -+ gce = (struct gce *)(gcl_data + 1); -+ -+ gcl_query->acl_len = cpu_to_le16(maxlen); -+ -+ dma_size = cpu_to_le16(data_size); -+ cbdr->length = dma_size; -+ cbdr->status_flags = 0; -+ -+ dma = dma_map_single(&priv->si->pdev->dev, gcl_data, -+ data_size, DMA_FROM_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ kfree(gcl_data); -+ return -ENOMEM; -+ } -+ -+ cbdr->addr[0] = lower_32_bits(dma); -+ cbdr->addr[1] = upper_32_bits(dma); -+ cbdr->cmd = 1; -+ cbdr->cls = BDCR_CMD_PORT_GCL; -+ xmit_cbdr(priv->si, curr_cbd); -+ dma_unmap_single(&priv->si->pdev->dev, dma, data_size, DMA_FROM_DEVICE); -+ -+ /* since cbdr already passed to free, below could be get wrong */ -+ admin_len = le16_to_cpu(gcl_query->admin_list_len); -+ oper_len = le16_to_cpu(gcl_query->oper_list_len); -+ -+ admin_basic->control_list_length = admin_len; -+ -+ temp = ((u64)le32_to_cpu(gcl_data->abth)) << 32; -+ admin_basic->base_time = le32_to_cpu(gcl_data->abtl) + temp; -+ -+ admin_basic->cycle_time = le32_to_cpu(gcl_data->act); -+ admin_basic->cycle_time_extension = le32_to_cpu(gcl_data->acte); -+ -+ admin_basic->control_list = kcalloc(admin_len, -+ sizeof(admin_basic->control_list), -+ GFP_KERNEL); -+ if (!admin_basic->control_list) { -+ memset(cbdr, 0, sizeof(*cbdr)); -+ kfree(gcl_data); -+ return -ENOMEM; -+ } -+ -+ for (i = 0; i < admin_len; i++) { -+ struct gce *temp_gce = gce + i; -+ struct tsn_qbv_entry *temp_entry; -+ -+ temp_entry = admin_basic->control_list + i; -+ -+ temp_entry->gate_state = temp_gce->gate; -+ temp_entry->time_interval = le32_to_cpu(temp_gce->period); -+ } -+ -+ /* Updated by ENETC on completion of the configuration -+ * command. A zero value indicates success. -+ */ -+ admin_conf->config_change = true; -+ -+ memset(cbdr, 0, sizeof(*cbdr)); -+ kfree(gcl_data); -+ -+ return 0; -+} -+ -+int enetc_qbv_get_status(struct net_device *ndev, -+ struct tsn_qbv_status *status) -+{ -+ struct enetc_cbd *cbdr; -+ struct tgs_gcl_resp *gcl_data; -+ struct tgs_gcl_query *gcl_query; -+ struct gce *gce; -+ struct tsn_qbv_basic *oper_basic; -+ struct enetc_ndev_priv *priv; -+ dma_addr_t dma; -+ int curr_cbd; -+ u16 maxlen; -+ u16 data_size, dma_size; -+ u16 admin_len; -+ u16 oper_len; -+ u64 temp; -+ int i; -+ -+ if (!ndev) -+ return -EINVAL; -+ -+ if (!status) -+ return -EINVAL; -+ -+ oper_basic = &status->oper; -+ priv = netdev_priv(ndev); -+ -+ if (!(enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)) -+ return -EINVAL; -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ gcl_query = &cbdr->gcl_query; -+ -+ maxlen = enetc_get_max_gcl_len(&priv->si->hw); -+ -+ data_size = sizeof(struct tgs_gcl_resp) + -+ sizeof(struct gce) * 2 * maxlen; -+ -+ gcl_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!gcl_data) -+ return -ENOMEM; -+ -+ gce = (struct gce *)(gcl_data + 1); -+ -+ gcl_query->acl_len = cpu_to_le16(maxlen); -+ gcl_query->ocl_len = cpu_to_le16(maxlen); -+ -+ dma_size = cpu_to_le16(data_size); -+ cbdr->length = dma_size; -+ cbdr->status_flags = 0; /* long format command no ie */ -+ -+ dma = dma_map_single(&priv->si->pdev->dev, gcl_data, -+ data_size, DMA_FROM_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ kfree(gcl_data); -+ return -ENOMEM; -+ } -+ -+ cbdr->addr[0] = lower_32_bits(dma); -+ cbdr->addr[1] = upper_32_bits(dma); -+ cbdr->cmd = 1; -+ cbdr->cls = BDCR_CMD_PORT_GCL; -+ xmit_cbdr(priv->si, curr_cbd); -+ dma_unmap_single(&priv->si->pdev->dev, dma, data_size, DMA_FROM_DEVICE); -+ -+ /* since cbdr already passed to free, below could be get wrong */ -+ admin_len = le16_to_cpu(gcl_query->admin_list_len); -+ oper_len = le16_to_cpu(gcl_query->oper_list_len); -+ -+ if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGAGLSR_OFFSET) & -+ ENETC_QBV_CFG_PEND_MASK) { -+ status->config_pending = true; -+ goto exit; -+ } -+ -+ /* The Oper and Admin timing fields exist in the response buffer even -+ * if no valid corresponding lists exists. These fields are considered -+ * invalid if the corresponding list does not exist. -+ */ -+ status->config_pending = false; -+ temp = ((u64)le32_to_cpu(gcl_data->ccth)) << 32; -+ status->config_change_time = le32_to_cpu(gcl_data->cctl) + temp; -+ -+ temp = ((u64)le32_to_cpu(gcl_data->cceh)) << 32; -+ status->config_change_error = le32_to_cpu(gcl_data->ccel) + temp; -+ -+ /* changed to SITGTGR */ -+ status->tick_granularity = enetc_rd(&priv->si->hw, ENETC_SITGTGR); -+ -+ /* current time */ -+ status->current_time = get_current_time(priv->si); -+ -+ status->supported_list_max = maxlen; -+ -+ /* status->oper.gate_states , no init oper/admin gate state */ -+ status->oper.control_list_length = oper_len; -+ temp = ((u64)le32_to_cpu(gcl_data->obth)) << 32; -+ status->oper.base_time = le32_to_cpu(gcl_data->obtl) + temp; -+ status->oper.cycle_time = le32_to_cpu(gcl_data->oct); -+ status->oper.cycle_time_extension = le32_to_cpu(gcl_data->octe); -+ -+ oper_basic->control_list = -+ kcalloc(oper_len, sizeof(oper_basic->control_list), GFP_KERNEL); -+ if (!oper_basic->control_list) { -+ memset(cbdr, 0, sizeof(*cbdr)); -+ kfree(gcl_data); -+ return -ENOMEM; -+ } -+ -+ for (i = 0; i < oper_len; i++) { -+ struct gce *temp_gce = gce + maxlen + i; -+ struct tsn_qbv_entry *temp_entry = oper_basic->control_list + i; -+ -+ temp_entry->gate_state = temp_gce->gate; -+ temp_entry->time_interval = le32_to_cpu(temp_gce->period); -+ } -+ -+exit: -+ memset(cbdr, 0, sizeof(*cbdr)); -+ kfree(gcl_data); -+ return 0; -+} -+ -+/* CBD Class 7: Stream Identity Entry Set Descriptor - Long Format */ -+int enetc_cb_streamid_set(struct net_device *ndev, u32 index, -+ bool en, struct tsn_cb_streamid *streamid) -+{ -+ struct enetc_cbd *cbdr; -+ void *si_data; -+ struct null_streamid_data *si_data1; -+ struct smac_streamid_data *si_data2; -+ struct streamid_conf *si_conf; -+ struct enetc_ndev_priv *priv; -+ dma_addr_t dma; -+ u16 data_size, dma_size; -+ int curr_cbd; -+ -+ if (!ndev) -+ return -EINVAL; -+ -+ priv = netdev_priv(ndev); -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ cbdr->index = cpu_to_le16((u16)index); -+ cbdr->cmd = 0; -+ cbdr->cls = BDCR_CMD_STREAM_IDENTIFY; -+ cbdr->status_flags = 0; -+ -+ data_size = sizeof(struct null_streamid_data); -+ si_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ cbdr->length = cpu_to_le16(data_size); -+ -+ dma = dma_map_single(&priv->si->pdev->dev, si_data, -+ data_size, DMA_FROM_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ kfree(si_data); -+ return -ENOMEM; -+ } -+ -+ cbdr->addr[0] = lower_32_bits(dma); -+ cbdr->addr[1] = upper_32_bits(dma); -+ si_data1 = (struct null_streamid_data *)si_data; -+ si_data1->dmac[0] = 0xFF; -+ si_data1->dmac[1] = 0xFF; -+ si_data1->dmac[2] = 0xFF; -+ si_data1->dmac[3] = 0xFF; -+ si_data1->dmac[4] = 0xFF; -+ si_data1->dmac[5] = 0xFF; -+ si_data1->vid_vidm_tg = -+ cpu_to_le16(ENETC_CBDR_SID_VID_MASK -+ + ((0x3 << 14) | ENETC_CBDR_SID_VIDM)); -+ -+ si_conf = &cbdr->sid_set; -+ /* Only one port supported for one entry, set itself */ -+ si_conf->iports = 1 << (priv->si->pdev->devfn & 0x7); -+ si_conf->id_type = 1; -+ si_conf->oui[2] = 0x0; -+ si_conf->oui[1] = 0x80; -+ si_conf->oui[0] = 0xC2; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ memset(cbdr, 0, sizeof(*cbdr)); -+ kfree(si_data); -+ -+ if (!en) -+ return 0; -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ cbdr->index = cpu_to_le16((u16)index); -+ cbdr->cmd = 0; -+ cbdr->cls = BDCR_CMD_STREAM_IDENTIFY; -+ cbdr->status_flags = 0; -+ -+ si_conf = &cbdr->sid_set; -+ si_conf->en = 0x80; -+ si_conf->stream_handle = cpu_to_le32(streamid->handle); -+ si_conf->iports = 1 << (priv->si->pdev->devfn & 0x7); -+ si_conf->id_type = streamid->type; -+ si_conf->oui[2] = 0x0; -+ si_conf->oui[1] = 0x80; -+ si_conf->oui[0] = 0xC2; -+ -+ if (si_conf->id_type == 1) { -+ data_size = sizeof(struct null_streamid_data); -+ si_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ } else if (si_conf->id_type == 2) { -+ data_size = sizeof(struct smac_streamid_data); -+ si_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ } else { -+ return -EINVAL; -+ } -+ -+ if (!si_data) -+ return -ENOMEM; -+ -+ dma_size = cpu_to_le16(data_size); -+ cbdr->length = dma_size; -+ cbdr->status_flags = 0; -+ -+ dma = dma_map_single(&priv->si->pdev->dev, si_data, -+ data_size, DMA_FROM_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ memset(cbdr, 0, sizeof(*cbdr)); -+ kfree(si_data); -+ return -ENOMEM; -+ } -+ cbdr->addr[0] = lower_32_bits(dma); -+ cbdr->addr[1] = upper_32_bits(dma); -+ -+ /* VIDM default to be 1. -+ * VID Match. If set (b1) then the VID must match, otherwise -+ * any VID is considered a match. VIDM setting is only used -+ * when TG is set to b01. -+ */ -+ if (si_conf->id_type == 1) { -+ si_data1 = (struct null_streamid_data *)si_data; -+ si_data1->dmac[0] = streamid->para.nid.dmac & 0xFF; -+ si_data1->dmac[1] = (streamid->para.nid.dmac >> 8) & 0xFF; -+ si_data1->dmac[2] = (streamid->para.nid.dmac >> 16) & 0xFF; -+ si_data1->dmac[3] = (streamid->para.nid.dmac >> 24) & 0xFF; -+ si_data1->dmac[4] = (streamid->para.nid.dmac >> 32) & 0xFF; -+ si_data1->dmac[5] = (streamid->para.nid.dmac >> 40) & 0xFF; -+ si_data1->vid_vidm_tg = -+ cpu_to_le16((streamid->para.nid.vid & ENETC_CBDR_SID_VID_MASK) + -+ ((((u16)(streamid->para.nid.tagged) & 0x3) << 14) -+ | ENETC_CBDR_SID_VIDM)); -+ } else if (si_conf->id_type == 2) { -+ si_data2 = (struct smac_streamid_data *)si_data; -+ si_data2->smac[0] = streamid->para.sid.smac & 0xFF; -+ si_data2->smac[1] = (streamid->para.sid.smac >> 8) & 0xFF; -+ si_data2->smac[2] = (streamid->para.sid.smac >> 16) & 0xFF; -+ si_data2->smac[3] = (streamid->para.sid.smac >> 24) & 0xFF; -+ si_data2->smac[4] = (streamid->para.sid.smac >> 32) & 0xFF; -+ si_data2->smac[5] = (streamid->para.sid.smac >> 40) & 0xFF; -+ si_data2->vid_vidm_tg = -+ cpu_to_le16((streamid->para.sid.vid & ENETC_CBDR_SID_VID_MASK) + -+ ((((u16)(streamid->para.sid.tagged) & 0x3) << 14) -+ | ENETC_CBDR_SID_VIDM)); -+ } -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ memset(cbdr, 0, sizeof(*cbdr)); -+ kfree(si_data); -+ -+ return 0; -+} -+ -+/* CBD Class 7: Stream Identity Entry Query Descriptor - Long Format */ -+int enetc_cb_streamid_get(struct net_device *ndev, u32 index, -+ struct tsn_cb_streamid *streamid) -+{ -+ struct enetc_cbd *cbdr; -+ struct streamid_query_resp *si_data; -+ struct enetc_ndev_priv *priv; -+ dma_addr_t dma; -+ u16 data_size, dma_size; -+ int curr_cbd; -+ int valid; -+ -+ if (!ndev) -+ return -EINVAL; -+ -+ priv = netdev_priv(ndev); -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ cbdr->index = cpu_to_le32(index); -+ cbdr->cmd = 1; -+ cbdr->cls = BDCR_CMD_STREAM_IDENTIFY; -+ cbdr->status_flags = 0; -+ -+ data_size = sizeof(struct streamid_query_resp); -+ si_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!si_data) -+ return -ENOMEM; -+ -+ dma_size = cpu_to_le16(data_size); -+ cbdr->length = dma_size; -+ cbdr->status_flags = 0; /* long format command no ie */ -+ -+ dma = dma_map_single(&priv->si->pdev->dev, si_data, -+ data_size, DMA_FROM_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ kfree(si_data); -+ return -ENOMEM; -+ } -+ cbdr->addr[0] = lower_32_bits(dma); -+ cbdr->addr[1] = upper_32_bits(dma); -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ streamid->type = si_data->id_type; -+ -+ if (streamid->type == 1) { -+ streamid->para.nid.dmac = si_data->mac[0] -+ + ((u64)si_data->mac[1] << 8) -+ + ((u64)si_data->mac[2] << 16) -+ + ((u64)si_data->mac[3] << 24) -+ + ((u64)si_data->mac[4] << 32) -+ + ((u64)si_data->mac[5] << 40); -+ /* VID Match. If set (b1) then the VID must match, otherwise -+ * any VID is considered a match. -+ */ -+ streamid->para.nid.vid = -+ le16_to_cpu(si_data->vid_vidm_tg -+ & ENETC_CBDR_SID_VID_MASK); -+ streamid->para.nid.tagged = -+ le16_to_cpu(si_data->vid_vidm_tg >> 14 & 0x3); -+ } else if (streamid->type == 2) { -+ streamid->para.sid.smac = si_data->mac[0] -+ + ((u64)si_data->mac[1] << 8) -+ + ((u64)si_data->mac[2] << 16) -+ + ((u64)si_data->mac[3] << 24) -+ + ((u64)si_data->mac[4] << 32) -+ + ((u64)si_data->mac[5] << 40); -+ /* VID Match. If set (b1) then the VID must match, otherwise -+ * any VID is considered a match. -+ */ -+ streamid->para.sid.vid = -+ le16_to_cpu(si_data->vid_vidm_tg -+ & ENETC_CBDR_SID_VID_MASK); -+ streamid->para.sid.tagged = -+ le16_to_cpu(si_data->vid_vidm_tg >> 14 & 0x3); -+ } -+ -+ streamid->handle = le32_to_cpu(si_data->stream_handle); -+ streamid->ifac_iport = le32_to_cpu(si_data->input_ports); -+ valid = si_data->en ? 1 : 0; -+ -+ memset(cbdr, 0, sizeof(*cbdr)); -+ kfree(si_data); -+ -+ return valid; -+} -+ -+/* CBD Class 7: Stream Identity Statistics Query Descriptor - Long Format */ -+int enetc_cb_streamid_counters_get(struct net_device *ndev, u32 index, -+ struct tsn_cb_streamid_counters *counters) -+{ -+ return 0; -+} -+ -+void enetc_qci_enable(struct enetc_hw *hw) -+{ -+ enetc_wr(hw, ENETC_PPSFPMR, enetc_rd(hw, ENETC_PPSFPMR) -+ | ENETC_PPSFPMR_PSFPEN | ENETC_PPSFPMR_VS -+ | ENETC_PPSFPMR_PVC | ENETC_PPSFPMR_PVZC); -+} -+ -+void enetc_qci_disable(struct enetc_hw *hw) -+{ -+ enetc_wr(hw, ENETC_PPSFPMR, enetc_rd(hw, ENETC_PPSFPMR) -+ & ~ENETC_PPSFPMR_PSFPEN & ~ENETC_PPSFPMR_VS -+ & ~ENETC_PPSFPMR_PVC & ~ENETC_PPSFPMR_PVZC); -+} -+ -+/* CBD Class 8: Stream Filter Instance Set Descriptor - Short Format */ -+int enetc_qci_sfi_set(struct net_device *ndev, u32 index, bool en, -+ struct tsn_qci_psfp_sfi_conf *tsn_qci_sfi) -+{ -+ struct enetc_cbd *cbdr; -+ struct sfi_conf *sfi_config; -+ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ int curr_cbd; -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ cbdr->index = cpu_to_le16(index); -+ cbdr->cmd = 0; -+ cbdr->cls = BDCR_CMD_STREAM_FILTER; -+ cbdr->status_flags = 0x80; -+ cbdr->length = cpu_to_le16(1); -+ -+ sfi_config = &cbdr->sfi_conf; -+ if (en) -+ sfi_config->en = 0x80; -+ -+ if (tsn_qci_sfi->stream_handle_spec >= 0) { -+ sfi_config->stream_handle = -+ cpu_to_le32(tsn_qci_sfi->stream_handle_spec); -+ sfi_config->sthm |= 0x80; -+ } -+ -+ sfi_config->sg_inst_table_index = -+ cpu_to_le16(tsn_qci_sfi->stream_gate_instance_id); -+ sfi_config->input_ports = 1 << (priv->si->pdev->devfn & 0x7); -+ -+ /* The priority value which may be matched against the -+ * frame’s priority value to determine a match for this entry. -+ */ -+ if (tsn_qci_sfi->priority_spec >= 0) -+ sfi_config->multi |= (tsn_qci_sfi->priority_spec & 0x7) | 0x8; -+ -+ /* Filter Type. Identifies the contents of the MSDU/FM_INST_INDEX -+ * field as being either an MSDU value or an index into the Flow -+ * Meter Instance table. -+ */ -+ if (tsn_qci_sfi->stream_filter.maximum_sdu_size != 0) { -+ sfi_config->msdu = -+ cpu_to_le16(tsn_qci_sfi->stream_filter.maximum_sdu_size); -+ sfi_config->multi |= 0x40; -+ } -+ -+ if (tsn_qci_sfi->stream_filter.flow_meter_instance_id >= 0) { -+ sfi_config->fm_inst_table_index = -+ cpu_to_le16(tsn_qci_sfi->stream_filter.flow_meter_instance_id); -+ sfi_config->multi |= 0x80; -+ } -+ -+ /* Stream blocked due to oversized frame enable. TRUE or FALSE */ -+ if (tsn_qci_sfi->block_oversize_enable) -+ sfi_config->multi |= 0x20; -+ -+ /* Stream blocked due to oversized frame. TRUE or FALSE */ -+ if (tsn_qci_sfi->block_oversize) -+ sfi_config->multi |= 0x10; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ memset(cbdr, 0, sizeof(*cbdr)); -+ return 0; -+} -+ -+/* CBD Class 8: Stream Filter Instance Query Descriptor - Short Format */ -+int enetc_qci_sfi_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sfi_conf *tsn_qci_sfi) -+{ -+ struct enetc_cbd *cbdr; -+ struct sfi_conf *sfi_config; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ int curr_cbd; -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ cbdr->index = cpu_to_le16(index); -+ cbdr->cmd = 1; -+ cbdr->cls = BDCR_CMD_STREAM_FILTER; -+ cbdr->status_flags = 0x80; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ sfi_config = &cbdr->sfi_conf; -+ if (sfi_config->sthm & 0x80) -+ tsn_qci_sfi->stream_handle_spec = -+ le32_to_cpu(sfi_config->stream_handle); -+ else -+ tsn_qci_sfi->stream_handle_spec = -1; -+ -+ tsn_qci_sfi->stream_gate_instance_id = -+ le16_to_cpu(sfi_config->sg_inst_table_index); -+ -+ if (sfi_config->multi & 0x8) -+ tsn_qci_sfi->priority_spec = -+ le16_to_cpu(sfi_config->multi & 0x7); -+ else -+ tsn_qci_sfi->priority_spec = -1; -+ -+ /* Filter Type. Identifies the contents of the MSDU/FM_INST_INDEX -+ * field as being either an MSDU value or an index into the Flow -+ * Meter Instance table. -+ */ -+ if (sfi_config->multi & 0x80) -+ tsn_qci_sfi->stream_filter.flow_meter_instance_id = -+ le16_to_cpu(sfi_config->fm_inst_table_index); -+ else -+ tsn_qci_sfi->stream_filter.flow_meter_instance_id = -1; -+ -+ if (sfi_config->multi & 0x40) -+ tsn_qci_sfi->stream_filter.maximum_sdu_size = -+ le16_to_cpu(sfi_config->msdu); -+ -+ /* Stream blocked due to oversized frame enable. TRUE or FALSE */ -+ if (sfi_config->multi & 0x20) -+ tsn_qci_sfi->block_oversize_enable = true; -+ /* Stream blocked due to oversized frame. TRUE or FALSE */ -+ if (sfi_config->multi & 0x10) -+ tsn_qci_sfi->block_oversize = true; -+ -+ if (sfi_config->en & 0x80) { -+ memset(cbdr, 0, sizeof(*cbdr)); -+ return 1; -+ } -+ -+ memset(cbdr, 0, sizeof(*cbdr)); -+ return 0; -+} -+ -+/* CBD Class 8: Stream Filter Instance Query Statistics -+ * Descriptor - Long Format -+ */ -+int enetc_qci_sfi_counters_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sfi_counters *counters) -+{ -+ struct enetc_cbd *cbdr; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ int curr_cbd; -+ struct sfi_counter_data *sfi_counter_data; -+ dma_addr_t dma; -+ u16 data_size, dma_size; -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ cbdr->index = cpu_to_le16((u16)index); -+ cbdr->cmd = 2; -+ cbdr->cls = BDCR_CMD_STREAM_FILTER; -+ cbdr->status_flags = 0; -+ -+ data_size = sizeof(struct sfi_counter_data); -+ sfi_counter_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!sfi_counter_data) -+ return -ENOMEM; -+ -+ dma = dma_map_single(&priv->si->pdev->dev, sfi_counter_data, -+ data_size, DMA_FROM_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ kfree(sfi_counter_data); -+ return -ENOMEM; -+ } -+ cbdr->addr[0] = lower_32_bits(dma); -+ cbdr->addr[1] = upper_32_bits(dma); -+ -+ dma_size = cpu_to_le16(data_size); -+ cbdr->length = dma_size; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ counters->matching_frames_count = -+ ((u64)le32_to_cpu(sfi_counter_data->matchh) << 32) -+ + sfi_counter_data->matchl; -+ -+ counters->not_passing_sdu_count = -+ ((u64)le32_to_cpu(sfi_counter_data->msdu_droph) << 32) -+ + sfi_counter_data->msdu_dropl; -+ -+ counters->passing_sdu_count = counters->matching_frames_count -+ - counters->not_passing_sdu_count; -+ -+ counters->not_passing_frames_count = -+ ((u64)le32_to_cpu(sfi_counter_data->stream_gate_droph) << 32) -+ + le32_to_cpu(sfi_counter_data->stream_gate_dropl); -+ -+ counters->passing_frames_count = counters->matching_frames_count -+ - counters->not_passing_sdu_count -+ - counters->not_passing_frames_count; -+ -+ counters->red_frames_count = -+ ((u64)le32_to_cpu(sfi_counter_data->flow_meter_droph) << 32) -+ + le32_to_cpu(sfi_counter_data->flow_meter_dropl); -+ -+ memset(cbdr, 0, sizeof(*cbdr)); -+ return 0; -+} -+ -+/* CBD Class 9: Stream Gate Instance Table Entry Set -+ * Descriptor - Short Format -+ */ -+int enetc_qci_sgi_set(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sgi_conf *tsn_qci_sgi) -+{ -+ struct enetc_cbd *cbdr, *cbdr_sgcl; -+ struct sgi_table *sgi_config; -+ struct sgcl_conf *sgcl_config; -+ struct sgcl_data *sgcl_data; -+ struct sgce *sgce; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ -+ dma_addr_t dma; -+ u16 data_size, dma_size; -+ int curr_cbd, i; -+ -+ /* disable first */ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ memset(cbdr, 0, sizeof(*cbdr)); -+ -+ cbdr->index = cpu_to_le16(index); -+ cbdr->cmd = 0; -+ cbdr->cls = BDCR_CMD_STREAM_GCL; -+ cbdr->status_flags = 0x80; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ if (!tsn_qci_sgi->gate_enabled) { -+ memset(cbdr, 0, sizeof(*cbdr)); -+ return 0; -+ } -+ -+ /* Re-enable */ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ memset(cbdr, 0, sizeof(*cbdr)); -+ -+ cbdr->index = cpu_to_le16(index); -+ cbdr->cmd = 0; -+ cbdr->cls = BDCR_CMD_STREAM_GCL; -+ cbdr->status_flags = 0x80; -+ -+ sgi_config = &cbdr->sgi_table; -+ -+ sgi_config->ocgtst = tsn_qci_sgi->admin.control_list_length ? -+ 0x80 : (tsn_qci_sgi->admin.gate_states ? 0x80 : 0x0); -+ -+ sgi_config->oipv = -+ tsn_qci_sgi->admin.control_list_length ? -+ 0x0 : ((tsn_qci_sgi->admin.init_ipv < 0) ? -+ 0x0 : ((tsn_qci_sgi->admin.init_ipv & 0x7) | 0x8)); -+ -+ sgi_config->en = 0x80; -+ -+ if (tsn_qci_sgi->block_invalid_rx_enable) -+ sgi_config->gset |= 0x80; -+ if (tsn_qci_sgi->block_invalid_rx) -+ sgi_config->gset |= 0x40; -+ if (tsn_qci_sgi->block_octets_exceeded) -+ sgi_config->gset |= 0x10; -+ if (tsn_qci_sgi->block_octets_exceeded_enable) -+ sgi_config->gset |= 0x20; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ if (tsn_qci_sgi->admin.control_list_length == 0) -+ goto exit; -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr_sgcl); -+ memset(cbdr, 0, sizeof(*cbdr)); -+ -+ cbdr_sgcl->index = cpu_to_le16(index); -+ cbdr_sgcl->cmd = 1; -+ cbdr_sgcl->cls = BDCR_CMD_STREAM_GCL; -+ cbdr_sgcl->status_flags = 0; -+ -+ sgcl_config = &cbdr_sgcl->sgcl_conf; -+ -+ /* tsn_qci_sgi->admin.control_list_length is not zero now */ -+ if (tsn_qci_sgi->admin.control_list_length > 4) -+ return -EINVAL; -+ -+ sgcl_config->acl_len = -+ (tsn_qci_sgi->admin.control_list_length - 1) & 0x3; -+ -+ data_size = sizeof(struct sgcl_data) + -+ (sgcl_config->acl_len + 1) * sizeof(struct sgce); -+ -+ sgcl_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!sgcl_data) -+ return -ENOMEM; -+ -+ dma_size = cpu_to_le16(data_size); -+ cbdr_sgcl->length = dma_size; -+ -+ dma = dma_map_single(&priv->si->pdev->dev, -+ sgcl_data, data_size, -+ DMA_FROM_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ memset(cbdr, 0, sizeof(*cbdr)); -+ memset(cbdr_sgcl, 0, sizeof(*cbdr_sgcl)); -+ kfree(sgcl_data); -+ return -ENOMEM; -+ } -+ cbdr_sgcl->addr[0] = lower_32_bits(dma); -+ cbdr_sgcl->addr[1] = upper_32_bits(dma); -+ -+ sgce = (struct sgce *)(sgcl_data + 1); -+ -+ if (tsn_qci_sgi->admin.gate_states) -+ sgcl_config->agtst = 0x80; -+ -+ sgcl_data->ct = cpu_to_le32(tsn_qci_sgi->admin.cycle_time); -+ sgcl_data->cte = cpu_to_le32(tsn_qci_sgi->admin.cycle_time_extension); -+ -+ if (tsn_qci_sgi->admin.init_ipv >= 0) -+ sgcl_config->aipv = (tsn_qci_sgi->admin.init_ipv & 0x7) | 0x8; -+ -+ for (i = 0; i < tsn_qci_sgi->admin.control_list_length; i++) { -+ struct tsn_qci_psfp_gcl *temp_sgcl = tsn_qci_sgi->admin.gcl + i; -+ struct sgce *temp_entry = (struct sgce *)(sgce + i); -+ -+ if (temp_sgcl->gate_state) -+ temp_entry->multi |= 0x10; -+ -+ if (temp_sgcl->ipv >= 0) -+ temp_entry->multi |= ((temp_sgcl->ipv & 0x7) << 5) -+ | 0x08; -+ -+ if (temp_sgcl->octet_max) -+ temp_entry->multi |= 0x01; -+ -+ temp_entry->interval = cpu_to_le32(temp_sgcl->time_interval); -+ temp_entry->msdu[0] = temp_sgcl->octet_max & 0xFF; -+ temp_entry->msdu[1] = (temp_sgcl->octet_max >> 8) & 0xFF; -+ temp_entry->msdu[2] = (temp_sgcl->octet_max >> 16) & 0xFF; -+ } -+ -+ if (!tsn_qci_sgi->admin.base_time) { -+ sgcl_data->btl = -+ cpu_to_le32(enetc_rd(&priv->si->hw, ENETC_SICTR0)); -+ sgcl_data->bth = -+ cpu_to_le32(enetc_rd(&priv->si->hw, ENETC_SICTR1)); -+ } else { -+ u32 tempu, templ; -+ -+ tempu = upper_32_bits(tsn_qci_sgi->admin.base_time); -+ templ = lower_32_bits(tsn_qci_sgi->admin.base_time); -+ sgcl_data->bth = cpu_to_le32(tempu); -+ sgcl_data->btl = cpu_to_le32(templ); -+ } -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ memset(cbdr_sgcl, 0, sizeof(*cbdr_sgcl)); -+ kfree(sgcl_data); -+ -+exit: -+ memset(cbdr, 0, sizeof(*cbdr)); -+ return 0; -+} -+ -+/* CBD Class 9: Stream Gate Instance Table Entry Query -+ * Descriptor - Short Format -+ */ -+int enetc_qci_sgi_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_sgi_conf *tsn_qci_sgi) -+{ -+ struct enetc_cbd *cbdr, *cbdr_sgcl; -+ struct sgi_table *sgi_config; -+ struct sgcl_query *sgcl_query; -+ struct sgcl_query_resp *sgcl_data; -+ struct sgce *sgce; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ dma_addr_t dma; -+ u16 data_size, dma_size, gcl_data_stat = 0; -+ u8 admin_len = 0; -+ int curr_cbd, i; -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ cbdr->index = cpu_to_le16(index); -+ cbdr->cmd = 2; -+ cbdr->cls = BDCR_CMD_STREAM_GCL; -+ cbdr->status_flags = 0x80; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ sgi_config = &cbdr->sgi_table; -+ -+ tsn_qci_sgi->admin.gate_states = (sgi_config->ocgtst & 0x80) ? -+ true : false; -+ if (sgi_config->oipv & 0x08) -+ tsn_qci_sgi->admin.init_ipv = sgi_config->oipv & 0x7; -+ else -+ tsn_qci_sgi->admin.init_ipv = -1; -+ -+ if (sgi_config->en & 0x80) -+ tsn_qci_sgi->gate_enabled = true; -+ if (sgi_config->gset & 0x80) -+ tsn_qci_sgi->block_invalid_rx_enable = true; -+ if (sgi_config->gset & 0x40) -+ tsn_qci_sgi->block_invalid_rx = true; -+ if (sgi_config->gset & 0x20) -+ tsn_qci_sgi->block_octets_exceeded_enable = true; -+ if (sgi_config->gset & 0x10) -+ tsn_qci_sgi->block_octets_exceeded = true; -+ -+ /* Check gate list length is zero? */ -+ if (!(sgi_config->oacl_len & 0x30)) { -+ tsn_qci_sgi->admin.control_list_length = 0; -+ goto exit; -+ } -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr_sgcl); -+ -+ cbdr_sgcl->index = cpu_to_le16(index); -+ cbdr_sgcl->cmd = 3; -+ cbdr_sgcl->cls = BDCR_CMD_STREAM_GCL; -+ cbdr_sgcl->status_flags = 0; -+ -+ data_size = sizeof(struct sgcl_query_resp) + 4 * sizeof(struct sgce); -+ -+ sgcl_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!sgcl_data) -+ return -ENOMEM; -+ -+ dma_size = cpu_to_le16(data_size); -+ cbdr_sgcl->length = dma_size; -+ cbdr_sgcl->status_flags = 0; -+ -+ sgcl_query = &cbdr_sgcl->sgcl_query; -+ -+ sgcl_query->oacl_len = 0x10; -+ -+ dma = dma_map_single(&priv->si->pdev->dev, sgcl_data, -+ data_size, DMA_FROM_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ memset(cbdr, 0, sizeof(*cbdr)); -+ memset(cbdr_sgcl, 0, sizeof(*cbdr_sgcl)); -+ kfree(sgcl_data); -+ return -ENOMEM; -+ } -+ cbdr_sgcl->addr[0] = lower_32_bits(dma); -+ cbdr_sgcl->addr[1] = upper_32_bits(dma); -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ sgce = (struct sgce *)(sgcl_data + 1); -+ -+ gcl_data_stat = le16_to_cpu(sgcl_data->stat); -+ if (gcl_data_stat & 0x10) -+ tsn_qci_sgi->admin.gate_states = true; -+ -+ if (gcl_data_stat & 0x80) -+ tsn_qci_sgi->admin.init_ipv = gcl_data_stat & 0x7; -+ else -+ tsn_qci_sgi->admin.init_ipv = -1; -+ -+ /* admin_len can also get from gcl_data_stat bit 5,6 -+ * OR sgi_config->oacl_len -+ */ -+ admin_len = (sgcl_query->oacl_len & 0x3) + 1; -+ tsn_qci_sgi->admin.control_list_length = admin_len; -+ tsn_qci_sgi->admin.cycle_time = le32_to_cpu(sgcl_data->act); -+ tsn_qci_sgi->admin.cycle_time_extension = le32_to_cpu(sgcl_data->acte); -+ tsn_qci_sgi->admin.base_time = ((u64)(le32_to_cpu(sgcl_data->abth)) -+ << 32) -+ + le32_to_cpu(sgcl_data->abtl); -+ -+ tsn_qci_sgi->admin.gcl = kcalloc(admin_len, -+ sizeof(struct tsn_qci_psfp_gcl), -+ GFP_KERNEL); -+ if (!tsn_qci_sgi->admin.gcl) { -+ kfree(sgcl_data); -+ return -ENOMEM; -+ } -+ -+ for (i = 0; i < admin_len; i++) { -+ struct tsn_qci_psfp_gcl *temp_sgcl = tsn_qci_sgi->admin.gcl + i; -+ struct sgce *temp_entry = (struct sgce *)(sgce + i); -+ -+ if (temp_entry->multi & 0x10) -+ temp_sgcl->gate_state = true; -+ -+ if (temp_entry->multi & 0x08) -+ temp_sgcl->ipv = temp_entry->multi >> 5; -+ else -+ temp_sgcl->ipv = -1; -+ -+ temp_sgcl->time_interval = le32_to_cpu(temp_entry->interval); -+ -+ if (temp_entry->multi & 0x01) -+ temp_sgcl->octet_max = (temp_entry->msdu[0] & 0xff) -+ | (((u32)temp_entry->msdu[1] << 8) & 0xff00) -+ | (((u32)temp_entry->msdu[1] << 16) & 0xff0000); -+ else -+ temp_sgcl->octet_max = 0; -+ } -+ -+ memset(cbdr_sgcl, 0, sizeof(*cbdr_sgcl)); -+ kfree(sgcl_data); -+ -+exit: -+ memset(cbdr, 0, sizeof(*cbdr)); -+ return 0; -+} -+ -+/* CBD Class 9: Stream Gate Instance Table Entry Query Descriptor -+ * CBD Class 9: Stream Gate Control List Query Descriptor -+ */ -+int enetc_qci_sgi_status_get(struct net_device *ndev, u16 index, -+ struct tsn_psfp_sgi_status *status) -+{ -+ struct enetc_cbd *cbdr_sgi, *cbdr_sgcl; -+ struct sgi_table *sgi_config; -+ struct sgcl_query *sgcl_query; -+ struct sgcl_query_resp *sgcl_data; -+ struct sgce *sgce; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ dma_addr_t dma; -+ u16 data_size, dma_size, gcl_data_stat = 0; -+ u8 oper_len = 0; -+ int curr_cbd, i; -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr_sgi); -+ -+ cbdr_sgi->index = cpu_to_le16(index); -+ cbdr_sgi->cmd = 2; -+ cbdr_sgi->cls = BDCR_CMD_STREAM_GCL; -+ cbdr_sgi->status_flags = 0x80; -+ -+ sgi_config = &cbdr_sgi->sgi_table; -+ -+ if (sgi_config->gset & 0x4) -+ status->config_pending = true; -+ -+ status->oper.gate_states = ((sgi_config->ocgtst & 0x80) ? true : false); -+ -+ /* Check gate list length is zero */ -+ if (!(sgi_config->oacl_len & 0x30)) { -+ status->oper.control_list_length = 0; -+ goto cmd2quit; -+ } -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr_sgcl); -+ -+ cbdr_sgcl->index = cpu_to_le16(index); -+ cbdr_sgcl->cmd = 3; -+ cbdr_sgcl->cls = BDCR_CMD_STREAM_GCL; -+ cbdr_sgcl->status_flags = 0; -+ -+ /* Max size */ -+ data_size = sizeof(struct sgcl_query_resp) + 4 * sizeof(struct sgce); -+ -+ sgcl_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!sgcl_data) -+ return -ENOMEM; -+ -+ dma_size = cpu_to_le16(data_size); -+ cbdr_sgcl->length = dma_size; -+ cbdr_sgcl->status_flags = 0; -+ -+ sgcl_query = &cbdr_sgcl->sgcl_query; -+ -+ sgcl_query->oacl_len = 0x20; -+ -+ dma = dma_map_single(&priv->si->pdev->dev, sgcl_data, -+ data_size, DMA_FROM_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ memset(cbdr_sgi, 0, sizeof(*cbdr_sgi)); -+ memset(cbdr_sgcl, 0, sizeof(*cbdr_sgcl)); -+ kfree(sgcl_data); -+ return -ENOMEM; -+ } -+ cbdr_sgcl->addr[0] = lower_32_bits(dma); -+ cbdr_sgcl->addr[1] = upper_32_bits(dma); -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ sgce = (struct sgce *)(sgcl_data + 1); -+ -+ /* oper_len can also get from gcl_data_stat bit 5,6 -+ * OR sgi_config->oacl_len -+ */ -+ oper_len = ((sgcl_query->oacl_len & 0x0c) >> 2) + 1; -+ -+ /* Get Stream Gate Control List */ -+ status->oper.cycle_time = le32_to_cpu(sgcl_data->oct); -+ status->oper.cycle_time_extension = le32_to_cpu(sgcl_data->octe); -+ status->oper.base_time = le32_to_cpu(sgcl_data->obtl) -+ + ((u64)le32_to_cpu(sgcl_data->obth) << 32); -+ status->oper.control_list_length = oper_len; -+ -+ gcl_data_stat = le16_to_cpu(sgcl_data->stat); -+ if (gcl_data_stat & 0x400) -+ status->oper.init_ipv = gcl_data_stat & 0x38 >> 7; -+ else -+ status->oper.init_ipv = -1; -+ -+ if (gcl_data_stat & 0x800) -+ status->oper.gate_states = true; -+ -+ status->oper.gcl = kcalloc(oper_len, -+ sizeof(struct tsn_qci_psfp_gcl), -+ GFP_KERNEL); -+ if (!status->oper.gcl) { -+ memset(cbdr_sgi, 0, sizeof(*cbdr_sgi)); -+ memset(cbdr_sgcl, 0, sizeof(*cbdr_sgcl)); -+ kfree(sgcl_data); -+ return -ENOMEM; -+ } -+ -+ for (i = 0; i < oper_len; i++) { -+ struct tsn_qci_psfp_gcl *temp_sgcl = status->oper.gcl + i; -+ struct sgce *temp_entry = (struct sgce *)(sgce + i); -+ -+ if (temp_entry->multi & 0x10) -+ temp_sgcl->gate_state = true; -+ -+ if (temp_entry->multi & 0x08) -+ temp_sgcl->ipv = temp_entry->multi >> 5; -+ else -+ temp_sgcl->ipv = -1; -+ -+ temp_sgcl->time_interval = le32_to_cpu(temp_entry->interval); -+ -+ if (temp_entry->multi & 0x01) -+ temp_sgcl->octet_max = temp_entry->msdu[0] -+ | ((((u32)temp_entry->msdu[1]) << 8) -+ & 0xff00) -+ | ((((u32)temp_entry->msdu[2]) << 16) -+ & 0xff0000); -+ else -+ temp_sgcl->octet_max = 0; -+ } -+ -+ status->config_change_time = le32_to_cpu(sgcl_data->cctl) -+ + ((u64)le32_to_cpu(sgcl_data->ccth) << 32); -+ -+ memset(cbdr_sgcl, 0, sizeof(*cbdr_sgcl)); -+ kfree(sgcl_data); -+ -+cmd2quit: -+ /* changed to SITGTGR */ -+ status->tick_granularity = enetc_rd(&priv->si->hw, ENETC_SITGTGR); -+ -+ /* current time */ -+ status->current_time = get_current_time(priv->si); -+ -+ memset(cbdr_sgi, 0, sizeof(*cbdr_sgi)); -+ -+ return 0; -+} -+ -+/* CBD Class 10: Flow Meter Instance Set Descriptor - Short Format */ -+int enetc_qci_fmi_set(struct net_device *ndev, u32 index, bool enable, -+ struct tsn_qci_psfp_fmi *tsn_qci_fmi) -+{ -+ struct enetc_cbd *cbdr; -+ struct fmi_conf *fmi_config; -+ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ int curr_cbd; -+ u64 temp = 0; -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ cbdr->index = cpu_to_le16((u16)index); -+ cbdr->cmd = 0; -+ cbdr->cls = BDCR_CMD_FLOW_METER; -+ cbdr->status_flags = 0x80; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ if (!enable) { -+ memset(cbdr, 0, sizeof(*cbdr)); -+ return 0; -+ } -+ -+ /* Re-enable */ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ memset(cbdr, 0, sizeof(*cbdr)); -+ cbdr->index = cpu_to_le16((u16)index); -+ cbdr->cmd = 0; -+ cbdr->cls = BDCR_CMD_FLOW_METER; -+ cbdr->status_flags = 0x80; -+ -+ fmi_config = &cbdr->fmi_conf; -+ fmi_config->en = 0x80; -+ if (tsn_qci_fmi->cir) { -+ temp = (u64)1000 * tsn_qci_fmi->cir; -+ temp = temp / 3725; -+ } -+ fmi_config->cir = cpu_to_le32((u32)temp); -+ fmi_config->cbs = cpu_to_le32(tsn_qci_fmi->cbs); -+ temp = 0; -+ if (tsn_qci_fmi->eir) { -+ temp = (u64)1000 * tsn_qci_fmi->eir; -+ temp = temp / 3725; -+ } -+ fmi_config->eir = cpu_to_le32((u32)temp); -+ fmi_config->ebs = cpu_to_le32(tsn_qci_fmi->ebs); -+ -+ if (tsn_qci_fmi->mark_red) -+ fmi_config->conf |= 0x1; -+ -+ if (tsn_qci_fmi->mark_red_enable) -+ fmi_config->conf |= 0x2; -+ -+ if (tsn_qci_fmi->drop_on_yellow) -+ fmi_config->conf |= 0x4; -+ -+ if (tsn_qci_fmi->cm) -+ fmi_config->conf |= 0x8; -+ -+ if (tsn_qci_fmi->cf) -+ fmi_config->conf |= 0x10; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ memset(cbdr, 0, sizeof(*cbdr)); -+ return 0; -+} -+ -+/* CBD Class 10: Flow Meter Instance Query Descriptor - Short Format */ -+int enetc_qci_fmi_get(struct net_device *ndev, u32 index, -+ struct tsn_qci_psfp_fmi *tsn_qci_fmi, -+ struct tsn_qci_psfp_fmi_counters *counters) -+{ -+ struct enetc_cbd *cbdr; -+ struct fmi_conf *fmi_config; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ int curr_cbd; -+ u16 data_size, dma_size; -+ dma_addr_t dma; -+ struct fmi_query_stat_resp *fmi_counter_data; -+ u64 temp = 0; -+ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ cbdr->index = cpu_to_le16(index); -+ cbdr->cmd = 1; -+ cbdr->cls = BDCR_CMD_FLOW_METER; -+ cbdr->status_flags = 0x80; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ fmi_config = &cbdr->fmi_conf; -+ if (fmi_config->cir) { -+ temp = (u64)3725 * fmi_config->cir; -+ temp = temp / 1000; -+ } -+ tsn_qci_fmi->cir = le32_to_cpu((u32)temp); -+ tsn_qci_fmi->cbs = le32_to_cpu(fmi_config->cbs); -+ temp = 0; -+ if (fmi_config->eir) { -+ temp = (u64)3725 * fmi_config->eir; -+ temp = temp / 1000; -+ } -+ tsn_qci_fmi->eir = le32_to_cpu((u32)temp); -+ tsn_qci_fmi->ebs = le32_to_cpu(fmi_config->ebs); -+ -+ if (fmi_config->conf & 0x1) -+ tsn_qci_fmi->mark_red = true; -+ -+ if (fmi_config->conf & 0x2) -+ tsn_qci_fmi->mark_red_enable = true; -+ -+ if (fmi_config->conf & 0x4) -+ tsn_qci_fmi->drop_on_yellow = true; -+ -+ if (fmi_config->conf & 0x8) -+ tsn_qci_fmi->cm = true; -+ -+ if (fmi_config->conf & 0x10) -+ tsn_qci_fmi->cf = true; -+ -+ memset(cbdr, 0, sizeof(*cbdr)); -+ -+ /* Get counters */ -+ curr_cbd = alloc_cbdr(priv->si, &cbdr); -+ -+ cbdr->index = cpu_to_le16(index); -+ cbdr->cmd = 2; -+ cbdr->cls = BDCR_CMD_FLOW_METER; -+ cbdr->status_flags = 0x0; -+ -+ data_size = sizeof(struct fmi_query_stat_resp); -+ fmi_counter_data = kzalloc(data_size, __GFP_DMA | GFP_KERNEL); -+ if (!fmi_counter_data) -+ return -ENOMEM; -+ -+ dma = dma_map_single(&priv->si->pdev->dev, fmi_counter_data, -+ data_size, DMA_FROM_DEVICE); -+ if (dma_mapping_error(&priv->si->pdev->dev, dma)) { -+ netdev_err(priv->si->ndev, "DMA mapping failed!\n"); -+ kfree(fmi_counter_data); -+ return -ENOMEM; -+ } -+ cbdr->addr[0] = lower_32_bits(dma); -+ cbdr->addr[1] = upper_32_bits(dma); -+ -+ dma_size = cpu_to_le16(data_size); -+ cbdr->length = dma_size; -+ -+ xmit_cbdr(priv->si, curr_cbd); -+ -+ memcpy(counters, fmi_counter_data, sizeof(*counters)); -+ -+ return 0; -+} -+ -+int enetc_qbu_set(struct net_device *ndev, u8 ptvector) -+{ -+ u32 temp; -+ int i; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ -+ temp = enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET); -+ if (temp & ENETC_QBV_TGE) -+ enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET, -+ temp & (~ENETC_QBV_TGPE)); -+ -+ for (i = 0; i < 8; i++) { -+ /* 1 Enabled. Traffic is transmitted on the preemptive MAC. */ -+ temp = enetc_port_rd(&priv->si->hw, ENETC_PTCFPR(i)); -+ -+ if ((ptvector >> i) & 0x1) -+ enetc_port_wr(&priv->si->hw, -+ ENETC_PTCFPR(i), -+ temp | ENETC_FPE); -+ else -+ enetc_port_wr(&priv->si->hw, -+ ENETC_PTCFPR(i), -+ temp & ~ENETC_FPE); -+ } -+ -+ return 0; -+} -+ -+int enetc_qbu_get(struct net_device *ndev, -+ struct tsn_preempt_status *preemptstat) -+{ -+ int i; -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ -+ if (enetc_port_rd(&priv->si->hw, ENETC_PFPMR) & ENETC_PFPMR_PMACE) { -+ preemptstat->preemption_active = true; -+ if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) -+ & ENETC_QBV_TGE) -+ preemptstat->hold_request = 1; -+ else -+ preemptstat->hold_request = 2; -+ } else { -+ preemptstat->preemption_active = false; -+ return 0; -+ } -+ -+ for (i = 0; i < 8; i++) -+ if (enetc_port_rd(&priv->si->hw, ENETC_PTCFPR(i)) & 0x80000000) -+ preemptstat->admin_state |= 1 << i; -+ -+ preemptstat->hold_advance = -+ enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & 0xFFFF; -+ preemptstat->release_advance = -+ enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & 0xFFFF; -+ -+ return 0; -+} -+ -+u32 __enetc_tsn_get_cap(struct enetc_si *si) -+{ -+ u32 reg = 0; -+ u32 cap = 0; -+ -+ reg = enetc_port_rd(&si->hw, ENETC_PCAPR0); -+ -+ if (reg & ENETC_PCAPR0_PSFP) -+ cap |= TSN_CAP_QCI; -+ -+ if (reg & ENETC_PCAPR0_TSN) -+ cap |= TSN_CAP_QBV; -+ -+ if (reg & ENETC_PCAPR0_QBU) -+ cap |= TSN_CAP_QBU; -+ -+ cap |= TSN_CAP_CBS; -+ cap |= TSN_CAP_TBS; -+ -+ return cap; -+} -+ -+u32 enetc_tsn_get_capability(struct net_device *ndev) -+{ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ -+ return __enetc_tsn_get_cap(priv->si); -+} -+ -+static int __enetc_get_max_cap(struct enetc_si *si, -+ struct tsn_qci_psfp_stream_param *stream_para) -+{ -+ u32 reg = 0; -+ -+ /* Port stream filter capability */ -+ reg = enetc_port_rd(&si->hw, ENETC_PSFCAPR); -+ stream_para->max_sf_instance = reg & ENETC_PSFCAPR_MSK; -+ /* Port stream filter capability */ -+ reg = enetc_port_rd(&si->hw, ENETC_PSGCAPR); -+ stream_para->max_sg_instance = (reg & ENETC_PSGCAPR_SGIT_MSK); -+ stream_para->supported_list_max = (reg & ENETC_PSGCAPR_GCL_MSK) >> 16; -+ /* Port flow meter capability */ -+ reg = enetc_port_rd(&si->hw, ENETC_PFMCAPR); -+ stream_para->max_fm_instance = reg & ENETC_PFMCAPR_MSK; -+ -+ return 0; -+} -+ -+int enetc_get_max_cap(struct net_device *ndev, -+ struct tsn_qci_psfp_stream_param *stream_para) -+{ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ -+ return __enetc_get_max_cap(priv->si, stream_para); -+} -+ -+static int enetc_set_cbs(struct net_device *ndev, u8 tc, u8 bw) -+{ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ struct enetc_si *si = priv->si; -+ struct enetc_cbs *ecbs = si->ecbs; -+ struct cbs *cbs; -+ -+ int bw_sum = 0; -+ u32 port_transmit_rate; -+ u32 port_frame_max_size; -+ u8 tc_nums; -+ int i; -+ -+ u32 max_interfrence_size; -+ u32 send_slope; -+ u32 hi_credit; -+ -+ if (!ecbs) -+ return -ENOMEM; -+ -+ port_transmit_rate = get_ndev_speed(si->ndev); -+ if (port_transmit_rate != ecbs->port_transmit_rate) -+ ecbs->port_transmit_rate = port_transmit_rate; -+ port_frame_max_size = ecbs->port_max_size_frame; -+ tc_nums = ecbs->tc_nums; -+ cbs = ecbs->cbs; -+ -+ if (tc >= tc_nums) { -+ dev_err(&ndev->dev, "Make sure the TC less than %d\n", tc_nums); -+ return -EINVAL; -+ } -+ -+ if (!bw) { -+ if (cbs[tc].enable) { -+ /* Make sure the other TC that are numerically -+ * lower than this TC have been disabled. -+ */ -+ for (i = 0; i < tc; i++) { -+ if (cbs[i].enable) -+ break; -+ } -+ if (i < tc) { -+ dev_err(&ndev->dev, -+ "TC%d has been disabled first\n", i); -+ return -EINVAL; -+ } -+ memset(&cbs[tc], 0, sizeof(*cbs)); -+ cbs[tc].enable = false; -+ enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), 0); -+ enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), 0); -+ } -+ return 0; -+ } -+ -+ /* Make sure the other TC that are numerically -+ * higher than this TC have been enabled. -+ */ -+ for (i = tc_nums - 1; i > tc; i--) { -+ if (!cbs[i].enable) { -+ dev_err(&ndev->dev, -+ "TC%d has been enabled first\n", i); -+ return -EINVAL; -+ } -+ bw_sum += cbs[i].bw; -+ } -+ -+ if (bw_sum + bw >= 100) { -+ dev_err(&ndev->dev, -+ "The sum of all CBS Bandwidth cann't exceed 100\n"); -+ return -EINVAL; -+ } -+ -+ cbs[tc].bw = bw; -+ cbs[tc].tc_max_sized_frame = enetc_port_rd(&si->hw, ENETC_PTCMSDUR(tc)); -+ cbs[tc].idle_slope = port_transmit_rate / 100 * bw; -+ cbs[tc].send_slope = port_transmit_rate - cbs[tc].idle_slope; -+ -+ /* For TC7, the max_interfrence_size is ENETC_MAC_MAXFRM_SIZE. -+ * For TC6, the max_interfrence_size is calculated as below: -+ * -+ * max_interfrence_size = (M0 + Ma + Ra * M0 / (R0 - Ra)) -+ * -+ * For other traffic class, for example SR class Q: -+ * -+ * R0 * (M0 + Ma + ... + Mp) -+ * max_interfrence_size = ------------------------------ -+ * (R0 - Ra) + ... + (R0 - Rp) -+ * -+ */ -+ -+ if (tc == tc_nums - 1) { -+ cbs[tc].max_interfrence_size = port_frame_max_size * 8; -+ -+ } else if (tc == tc_nums - 2) { -+ cbs[tc].max_interfrence_size = (port_frame_max_size -+ + cbs[tc + 1].tc_max_sized_frame -+ + port_frame_max_size * (cbs[tc + 1].idle_slope -+ / cbs[tc + 1].send_slope)) * 8; -+ } else { -+ max_interfrence_size = port_frame_max_size; -+ send_slope = 0; -+ for (i = tc + 1; i < tc_nums; i++) { -+ send_slope += cbs[i].send_slope; -+ max_interfrence_size += cbs[i].tc_max_sized_frame; -+ } -+ max_interfrence_size = ((u64)port_transmit_rate -+ * max_interfrence_size) / send_slope; -+ cbs[tc].max_interfrence_size = max_interfrence_size * 8; -+ } -+ -+ cbs[tc].hi_credit = cbs[tc].max_interfrence_size * cbs[tc].bw / 100; -+ cbs[tc].lo_credit = cbs[tc].tc_max_sized_frame * (cbs[tc].send_slope -+ / port_transmit_rate); -+ cbs[tc].tc = tc; -+ -+ hi_credit = (ENETC_CLK * 100L) * (u64)cbs[tc].hi_credit -+ / port_transmit_rate; -+ enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), hi_credit); -+ -+ /* Set bw register and enable this traffic class*/ -+ enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), -+ (cbs[tc].bw & 0x7F) | (1 << 31)); -+ cbs[tc].enable = true; -+ -+ return 0; -+} -+ -+static int enetc_get_cbs(struct net_device *ndev, u8 tc) -+{ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ struct enetc_si *si = priv->si; -+ struct enetc_cbs *ecbs = si->ecbs; -+ struct cbs *cbs; -+ -+ if (!ecbs) -+ return -ENOMEM; -+ cbs = ecbs->cbs; -+ if (tc >= ecbs->tc_nums) { -+ dev_err(&ndev->dev, "The maximum of TC is %d\n", ecbs->tc_nums); -+ return -EINVAL; -+ } -+ -+ return cbs[tc].bw; -+} -+ -+static int enetc_set_tsd(struct net_device *ndev, struct tsn_tsd *ttsd) -+{ -+ return 0; -+} -+ -+static int enetc_get_tsd(struct net_device *ndev, struct tsn_tsd_status *tts) -+{ -+ return 0; -+} -+ -+static u32 get_ndev_speed(struct net_device *netdev) -+{ -+ struct ethtool_link_ksettings ksettings; -+ int rc = -1; -+ -+ if (netdev->ethtool_ops->get_link_ksettings) { -+ if (netdev->ethtool_ops->begin) { -+ rc = netdev->ethtool_ops->begin(netdev); -+ if (rc < 0) -+ return 0; -+ } -+ -+ memset(&ksettings, 0, sizeof(ksettings)); -+ -+ if (!netdev->ethtool_ops->get_link_ksettings) -+ return 0; -+ -+ rc = netdev->ethtool_ops->get_link_ksettings(netdev, -+ &ksettings); -+ -+ if (netdev->ethtool_ops->complete) -+ netdev->ethtool_ops->complete(netdev); -+ } -+ -+ return (rc < 0) ? 0 : ksettings.base.speed; -+} -+ -+static void enetc_cbs_init(struct enetc_si *si) -+{ -+ struct enetc_ndev_priv *priv = netdev_priv(si->ndev); -+ u8 tc_nums; -+ -+ tc_nums = priv->num_tx_rings; -+ si->ecbs = kzalloc(sizeof(*si->ecbs) + -+ sizeof(struct cbs) * tc_nums, GFP_KERNEL); -+ if (!si->ecbs) -+ return; -+ -+ si->ecbs->port_max_size_frame = si->ndev->mtu + ETH_HLEN -+ + VLAN_HLEN + ETH_FCS_LEN; -+ si->ecbs->tc_nums = tc_nums; -+ si->ecbs->port_transmit_rate = get_ndev_speed(si->ndev); -+ -+ /*This trick is used only for CFP*/ -+ if (!si->ecbs->port_transmit_rate) -+ si->ecbs->port_transmit_rate = 1000000000; -+ -+ if (!si->ecbs->port_transmit_rate) { -+ dev_err(&si->pdev->dev, "Failure to get port speed for CBS\n"); -+ kfree(si->ecbs); -+ si->ecbs = NULL; -+ } -+} -+ -+static void enetc_qbv_init(struct enetc_hw *hw) -+{ -+ /* Set PSPEED to be 1Gbps */ -+ enetc_port_wr(hw, ENETC_PMR, -+ (enetc_port_rd(hw, ENETC_PMR) -+ & (~ENETC_PMR_PSPEED_MASK)) -+ | ENETC_PMR_PSPEED_1000M); -+} -+ -+void enetc_tsn_init(struct net_device *ndev) -+{ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ struct enetc_si *si = priv->si; -+ u32 capability = 0; -+ -+ capability = __enetc_tsn_get_cap(si); -+ -+ if (capability & TSN_CAP_CBS) -+ enetc_cbs_init(si); -+ -+ if (capability & TSN_CAP_QBV) -+ enetc_qbv_init(&si->hw); -+ -+ if (capability & TSN_CAP_QCI) -+ enetc_qci_enable(&si->hw); -+ -+ dev_info(&si->pdev->dev, "%s: setup done\n", __func__); -+} -+ -+void enetc_tsn_deinit(struct net_device *ndev) -+{ -+ struct enetc_ndev_priv *priv = netdev_priv(ndev); -+ struct enetc_si *si = priv->si; -+ -+ dev_info(&si->pdev->dev, "%s: release\n", __func__); -+} -+ -+static struct tsn_ops enetc_tsn_ops_full = { -+ .device_init = enetc_tsn_init, -+ .device_deinit = enetc_tsn_deinit, -+ .get_capability = enetc_tsn_get_capability, -+ .qbv_set = enetc_qbv_set, -+ .qbv_get = enetc_qbv_get, -+ .qbv_get_status = enetc_qbv_get_status, -+ .cb_streamid_set = enetc_cb_streamid_set, -+ .cb_streamid_get = enetc_cb_streamid_get, -+ .cb_streamid_counters_get = enetc_cb_streamid_counters_get, -+ .qci_get_maxcap = enetc_get_max_cap, -+ .qci_sfi_set = enetc_qci_sfi_set, -+ .qci_sfi_get = enetc_qci_sfi_get, -+ .qci_sfi_counters_get = enetc_qci_sfi_counters_get, -+ .qci_sgi_set = enetc_qci_sgi_set, -+ .qci_sgi_get = enetc_qci_sgi_get, -+ .qci_sgi_status_get = enetc_qci_sgi_status_get, -+ .qci_fmi_set = enetc_qci_fmi_set, -+ .qci_fmi_get = enetc_qci_fmi_get, -+ .qbu_set = enetc_qbu_set, -+ .qbu_get = enetc_qbu_get, -+ .cbs_set = enetc_set_cbs, -+ .cbs_get = enetc_get_cbs, -+ .tsd_set = enetc_set_tsd, -+ .tsd_get = enetc_get_tsd, -+}; -+ -+static struct tsn_ops enetc_tsn_ops_part = { -+ .device_init = enetc_tsn_init, -+ .device_deinit = enetc_tsn_deinit, -+ .get_capability = enetc_tsn_get_capability, -+ .cb_streamid_set = enetc_cb_streamid_set, -+ .cb_streamid_get = enetc_cb_streamid_get, -+ .cb_streamid_counters_get = enetc_cb_streamid_counters_get, -+ .qci_get_maxcap = enetc_get_max_cap, -+ .qci_sfi_set = enetc_qci_sfi_set, -+ .qci_sfi_get = enetc_qci_sfi_get, -+ .qci_sfi_counters_get = enetc_qci_sfi_counters_get, -+ .qci_sgi_set = enetc_qci_sgi_set, -+ .qci_sgi_get = enetc_qci_sgi_get, -+ .qci_sgi_status_get = enetc_qci_sgi_status_get, -+ .qci_fmi_set = enetc_qci_fmi_set, -+ .qci_fmi_get = enetc_qci_fmi_get, -+}; -+ -+void enetc_tsn_pf_init(struct net_device *netdev, struct pci_dev *pdev) -+{ -+ int port = pdev->devfn & 0x7; -+ -+ if (port == 1 || port == 3) -+ tsn_port_register(netdev, &enetc_tsn_ops_part, -+ (u16)pdev->bus->number); -+ else -+ tsn_port_register(netdev, &enetc_tsn_ops_full, -+ (u16)pdev->bus->number); -+} -+ -+void enetc_tsn_pf_deinit(struct net_device *netdev) -+{ -+ tsn_port_unregister(netdev); -+} -+#endif /* #if IS_ENABLED(CONFIG_ENETC_TSN) */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0338-net-dsa-felix-Fix-probing-allocation-and-cleanup-pat.patch b/target/linux/layerscape/patches-5.4/701-net-0338-net-dsa-felix-Fix-probing-allocation-and-cleanup-pat.patch deleted file mode 100644 index ec4c62a7a5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0338-net-dsa-felix-Fix-probing-allocation-and-cleanup-pat.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 5ae4c4ac2d992afcf4087e5f33ad7e5f7d073fbf Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Wed, 4 Dec 2019 14:36:09 +0200 -Subject: [PATCH] net: dsa: felix: Fix probing allocation and cleanup path - -dsa_switch_alloc() uses managed (devm_alloc) allocation -to alloc 'ds'. kfree()-ing 'ds' results in memory corruption. -kfree(ds) seems harmless on the error path, however for this -particular device, dsa_register_swtich() deffers probing to -allow the enetc driver to probe the master port first. -This results in kfree(ds) being called during the first -probing attempt of felix, followed by a NULL poiter access -crash during enetc driver probing (when accessing its net_device). - -This patch fixes following crash (triggerred in the enetc driver by -the probing routine of the felix driver): - -[ 3.502254] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 -[ 3.511073] Mem abort info: -[ 3.513874] ESR = 0x96000044 -[ 3.516936] EC = 0x25: DABT (current EL), IL = 32 bits -[ 3.522266] SET = 0, FnV = 0 -[ 3.525327] EA = 0, S1PTW = 0 -[ 3.528476] Data abort info: -[ 3.531359] ISV = 0, ISS = 0x00000044 -[ 3.535205] CM = 0, WnR = 1 -[ 3.538182] user pgtable: 4k pages, 48-bit VAs, pgdp=00000020f612d000 -[ 3.544645] [0000000000000000] pgd=0000000000000000 -[ 3.549542] Internal error: Oops: 96000044 [#1] PREEMPT SMP -[ 3.555128] Modules linked in: -[ 3.558189] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.4.0-03552-gfa6e1cd69f80 #1 -[ 3.565781] Hardware name: LS1028A RDB Board (DT) -[ 3.570496] pstate: a0000005 (NzCv daif -PAN -UAO) -[ 3.575303] pc : enetc_pf_probe+0x784/0xba8 -[ 3.579495] lr : enetc_pf_probe+0x6e8/0xba8 -[ 3.583686] sp : ffff80001002ba90 -[ 3.587005] x29: ffff80001002ba90 x28: ffff002076130c08 -[ 3.592331] x27: 0000000000000002 x26: ffff002076130c80 -[ 3.597657] x25: ffff002076130c00 x24: ffff002076130c80 -[ 3.602982] x23: ffffb3f2ab0ec000 x22: ffff0020760d7840 -[ 3.608307] x21: ffff0020760d7000 x20: ffff002076130c00 -[ 3.613632] x19: ffff800010850000 x18: ffffffffffffffff -[ 3.618957] x17: 000000007dee1586 x16: 00000000cb746ba4 -[ 3.624282] x15: ffffb3f2abce9908 x14: 0000000000000000 -[ 3.629608] x13: 0000000000000101 x12: 0000000000010000 -[ 3.634933] x11: 00000000ffffffff x10: ffff4c2dd0136000 -[ 3.640257] x9 : 0000000000000000 x8 : ffff002076122000 -[ 3.645582] x7 : 0000000000000000 x6 : 000000000000003f -[ 3.650908] x5 : 0000000000000040 x4 : 0000000000000001 -[ 3.656234] x3 : ffff800010850000 x2 : ffffb3f2ab0ed868 -[ 3.661560] x1 : 0000000000000000 x0 : 00000000051ca556 -[ 3.666886] Call trace: -[ 3.669333] enetc_pf_probe+0x784/0xba8 -[ 3.673178] local_pci_probe+0x3c/0xa0 -[ 3.676935] pci_device_probe+0x128/0x1c0 -[ 3.680954] really_probe+0x108/0x348 -[ 3.684623] driver_probe_device+0x58/0x100 -[ 3.688815] device_driver_attach+0x6c/0x90 -[ 3.693006] __driver_attach+0x84/0xc8 -[ 3.696762] bus_for_each_dev+0x74/0xc8 -[ 3.700605] driver_attach+0x20/0x28 -[ 3.704186] bus_add_driver+0x148/0x1f0 -[ 3.708029] driver_register+0x60/0x110 -[ 3.711872] __pci_register_driver+0x40/0x48 -[ 3.716153] enetc_pf_driver_init+0x20/0x28 -[ 3.720346] do_one_initcall+0x5c/0x1b0 -[ 3.724189] kernel_init_freeable+0x1a4/0x24c -[ 3.728557] kernel_init+0x10/0x108 -[ 3.732052] ret_from_fork+0x10/0x18 -[ 3.735635] Code: f9400680 f9417ea1 91020000 b9400000 (b9000020) -[ 3.741749] ---[ end trace c8ab43e3d33fed3f ]--- -[ 3.746396] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b -[ 3.748522] ata1: SATA link down (SStatus 0 SControl 300) -[ 3.754077] SMP: stopping secondary CPUs -[ 3.754082] Kernel Offset: 0x33f299c00000 from 0xffff800010000000 -[ 3.754083] PHYS_OFFSET: 0xfffff019c0000000 -[ 3.754086] CPU features: 0x0002,21806008 -[ 3.754088] Memory Limit: none -[ 3.780794] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]--- - -As a result of the fix, struct felix allocation also needs to -be converted to managed allocation (devm_alloc). - -Fixes: bb849431a970 ("net: dsa: ocelot: alloc memory for dsa switch instance") - -Signed-off-by: Claudiu Manoil ---- - drivers/net/dsa/ocelot/felix.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - ---- a/drivers/net/dsa/ocelot/felix.c -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -485,7 +485,7 @@ static int felix_pci_probe(struct pci_de - } - } - -- felix = kzalloc(sizeof(struct felix), GFP_KERNEL); -+ felix = devm_kzalloc(&pdev->dev, sizeof(*felix), GFP_KERNEL); - if (!felix) { - err = -ENOMEM; - dev_err(&pdev->dev, "Failed to allocate driver memory\n"); -@@ -532,11 +532,9 @@ static int felix_pci_probe(struct pci_de - return 0; - - err_register_ds: -- kfree(ds); - err_alloc_ds: - err_alloc_irq: - err_alloc_felix: -- kfree(felix); - err_dma: - pci_disable_device(pdev); - err_pci_enable: -@@ -551,9 +549,6 @@ static void felix_pci_remove(struct pci_ - - dsa_unregister_switch(felix->ds); - -- kfree(felix->ds); -- kfree(felix); -- - pci_disable_device(pdev); - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0339-LF-368-net-mscc-ocelot-hard-code-VCAP_PORT_CNT-for-F.patch b/target/linux/layerscape/patches-5.4/701-net-0339-LF-368-net-mscc-ocelot-hard-code-VCAP_PORT_CNT-for-F.patch deleted file mode 100644 index 44d97baddb..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0339-LF-368-net-mscc-ocelot-hard-code-VCAP_PORT_CNT-for-F.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 17bde33ffe50be558520a063392dc73b319a7f20 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Thu, 28 Nov 2019 11:48:24 +0800 -Subject: [PATCH] LF-368 net: mscc: ocelot: hard code VCAP_PORT_CNT for Felix - temporarily - -The Felix switch supports different port number with Ocelot. -This makes the bits mapping in TCAM entry and Action entry -is different with Ocelot for VCAP function. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/mscc/ocelot_vcap.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/ethernet/mscc/ocelot_vcap.h -+++ b/drivers/net/ethernet/mscc/ocelot_vcap.h -@@ -25,7 +25,7 @@ - #define VCAP_IS2_CNT 64 - #define VCAP_IS2_ENTRY_WIDTH 376 - #define VCAP_IS2_ACTION_WIDTH 99 --#define VCAP_PORT_CNT 11 -+#define VCAP_PORT_CNT 6 - - /* IS2 half key types */ - #define IS2_TYPE_ETYPE 0 diff --git a/target/linux/layerscape/patches-5.4/701-net-0340-LF-368-net-mscc-ocelot-make-ocelot_ace_rule-support-.patch b/target/linux/layerscape/patches-5.4/701-net-0340-LF-368-net-mscc-ocelot-make-ocelot_ace_rule-support-.patch deleted file mode 100644 index 6628de5989..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0340-LF-368-net-mscc-ocelot-make-ocelot_ace_rule-support-.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 79fbcc73dd52acfe8b7aa20a793ce8d60c8d3f7b Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Thu, 28 Nov 2019 12:10:44 -0600 -Subject: [PATCH] LF-368 net: mscc: ocelot: make ocelot_ace_rule support - multiple ports - -The ocelot_ace_rule is port specific now. Make it flexible to -be able to support multiple ports too. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/mscc/ocelot_ace.c | 14 +++++++------- - drivers/net/ethernet/mscc/ocelot_ace.h | 4 ++-- - drivers/net/ethernet/mscc/ocelot_flower.c | 8 ++++---- - 3 files changed, 13 insertions(+), 13 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot_ace.c -+++ b/drivers/net/ethernet/mscc/ocelot_ace.c -@@ -352,7 +352,7 @@ static void is2_entry_set(struct ocelot - data.type = IS2_ACTION_TYPE_NORMAL; - - VCAP_KEY_ANY_SET(PAG); -- VCAP_KEY_SET(IGR_PORT_MASK, 0, ~BIT(ace->chip_port)); -+ VCAP_KEY_SET(IGR_PORT_MASK, 0, ~ace->ingress_port_mask); - VCAP_KEY_BIT_SET(FIRST, OCELOT_VCAP_BIT_1); - VCAP_KEY_BIT_SET(HOST_MATCH, OCELOT_VCAP_BIT_ANY); - VCAP_KEY_BIT_SET(L2_MC, ace->dmac_mc); -@@ -576,7 +576,7 @@ static void is2_entry_set(struct ocelot - - static void is2_entry_get(struct ocelot_ace_rule *rule, int ix) - { -- struct ocelot *op = rule->port->ocelot; -+ struct ocelot *op = rule->ocelot; - struct vcap_data data; - int row = (ix / 2); - u32 cnt; -@@ -655,11 +655,11 @@ int ocelot_ace_rule_offload_add(struct o - /* Move down the rules to make place for the new rule */ - for (i = acl_block->count - 1; i > index; i--) { - ace = ocelot_ace_rule_get_rule_index(acl_block, i); -- is2_entry_set(rule->port->ocelot, i, ace); -+ is2_entry_set(rule->ocelot, i, ace); - } - - /* Now insert the new rule */ -- is2_entry_set(rule->port->ocelot, index, rule); -+ is2_entry_set(rule->ocelot, index, rule); - return 0; - } - -@@ -697,11 +697,11 @@ int ocelot_ace_rule_offload_del(struct o - /* Move up all the blocks over the deleted rule */ - for (i = index; i < acl_block->count; i++) { - ace = ocelot_ace_rule_get_rule_index(acl_block, i); -- is2_entry_set(rule->port->ocelot, i, ace); -+ is2_entry_set(rule->ocelot, i, ace); - } - - /* Now delete the last rule, because it is duplicated */ -- is2_entry_set(rule->port->ocelot, acl_block->count, &del_ace); -+ is2_entry_set(rule->ocelot, acl_block->count, &del_ace); - - return 0; - } -@@ -717,7 +717,7 @@ int ocelot_ace_rule_stats_update(struct - /* After we get the result we need to clear the counters */ - tmp = ocelot_ace_rule_get_rule_index(acl_block, index); - tmp->stats.pkts = 0; -- is2_entry_set(rule->port->ocelot, index, tmp); -+ is2_entry_set(rule->ocelot, index, tmp); - - return 0; - } ---- a/drivers/net/ethernet/mscc/ocelot_ace.h -+++ b/drivers/net/ethernet/mscc/ocelot_ace.h -@@ -186,14 +186,14 @@ struct ocelot_ace_stats { - - struct ocelot_ace_rule { - struct list_head list; -- struct ocelot_port *port; -+ struct ocelot *ocelot; - - u16 prio; - u32 id; - - enum ocelot_ace_action action; - struct ocelot_ace_stats stats; -- int chip_port; -+ u16 ingress_port_mask; - - enum ocelot_vcap_bit dmac_mc; - enum ocelot_vcap_bit dmac_bc; ---- a/drivers/net/ethernet/mscc/ocelot_flower.c -+++ b/drivers/net/ethernet/mscc/ocelot_flower.c -@@ -177,8 +177,8 @@ struct ocelot_ace_rule *ocelot_ace_rule_ - if (!rule) - return NULL; - -- rule->port = &block->priv->port; -- rule->chip_port = block->priv->chip_port; -+ rule->ocelot = block->priv->port.ocelot; -+ rule->ingress_port_mask = BIT(block->priv->chip_port); - return rule; - } - -@@ -213,7 +213,7 @@ static int ocelot_flower_destroy(struct - int ret; - - rule.prio = f->common.prio; -- rule.port = &port_block->priv->port; -+ rule.ocelot = port_block->priv->port.ocelot; - rule.id = f->cookie; - - ret = ocelot_ace_rule_offload_del(&rule); -@@ -231,7 +231,7 @@ static int ocelot_flower_stats_update(st - int ret; - - rule.prio = f->common.prio; -- rule.port = &port_block->priv->port; -+ rule.ocelot = port_block->priv->port.ocelot; - rule.id = f->cookie; - ret = ocelot_ace_rule_stats_update(&rule); - if (ret) diff --git a/target/linux/layerscape/patches-5.4/701-net-0341-LF-368-net-mscc-ocelot-add-VCAP-IS2-rule-to-trap-PTP.patch b/target/linux/layerscape/patches-5.4/701-net-0341-LF-368-net-mscc-ocelot-add-VCAP-IS2-rule-to-trap-PTP.patch deleted file mode 100644 index 817d449e01..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0341-LF-368-net-mscc-ocelot-add-VCAP-IS2-rule-to-trap-PTP.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 67ca04147efac6cac3f7490c61c817a84daada57 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Thu, 28 Nov 2019 14:42:44 +0800 -Subject: [PATCH] LF-368 net: mscc: ocelot: add VCAP IS2 rule to trap PTP - Ethernet frames - -All the PTP messages over Ethernet have etype 0x88f7 on them. -Use etype as the key to trap PTP messages. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/mscc/ocelot.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -2337,6 +2337,20 @@ void ocelot_set_cpu_port(struct ocelot * - } - EXPORT_SYMBOL(ocelot_set_cpu_port); - -+/* Entry for PTP over Ethernet (etype 0x88f7) -+ * Action: trap to CPU port -+ */ -+static struct ocelot_ace_rule ptp_rule = { -+ .prio = 1, -+ .type = OCELOT_ACE_TYPE_ETYPE, -+ .dmac_mc = OCELOT_VCAP_BIT_1, -+ .action = OCELOT_ACL_ACTION_TRAP, -+ .frame.etype.etype.value[0] = 0x88, -+ .frame.etype.etype.value[1] = 0xf7, -+ .frame.etype.etype.mask[0] = 0xff, -+ .frame.etype.etype.mask[1] = 0xff, -+}; -+ - int ocelot_init(struct ocelot *ocelot) - { - char queue_name[32]; -@@ -2474,6 +2488,13 @@ int ocelot_init(struct ocelot *ocelot) - "Timestamp initialization failed\n"); - return ret; - } -+ -+ /* Available on all ingress port except CPU port */ -+ ptp_rule.ocelot = ocelot; -+ ptp_rule.ingress_port_mask = -+ GENMASK(ocelot->num_phys_ports - 1, 0); -+ ptp_rule.ingress_port_mask &= ~BIT(ocelot->cpu); -+ ocelot_ace_rule_offload_add(&ptp_rule); - } - - return 0; -@@ -2488,6 +2509,8 @@ void ocelot_deinit(struct ocelot *ocelot - cancel_delayed_work(&ocelot->stats_work); - destroy_workqueue(ocelot->stats_queue); - mutex_destroy(&ocelot->stats_lock); -+ if (ocelot->ptp) -+ ocelot_ace_rule_offload_del(&ptp_rule); - ocelot_ace_deinit(); - if (ocelot->ptp_clock) - ptp_clock_unregister(ocelot->ptp_clock); diff --git a/target/linux/layerscape/patches-5.4/701-net-0342-LF-376-enetc-disable-EEE-autoneg-by-default.patch b/target/linux/layerscape/patches-5.4/701-net-0342-LF-376-enetc-disable-EEE-autoneg-by-default.patch deleted file mode 100644 index f968080ab8..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0342-LF-376-enetc-disable-EEE-autoneg-by-default.patch +++ /dev/null @@ -1,38 +0,0 @@ -From cb87015e005f429bff6fc084a61281235ca83d51 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Fri, 6 Dec 2019 12:41:48 +0800 -Subject: [PATCH] LF-376 enetc: disable EEE autoneg by default - -The EEE support has not been enabled on ENETC, but it may connect -to a PHY which supports EEE and advertises EEE by default, while -its link partner also advertises EEE. If this happens, the PHY enters -low power mode when the traffic rate is low and causes packet loss. -This patch disables EEE advertisement by default for any PHY that -ENETC connects to, to prevent the above unwanted outcome. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/enetc/enetc.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/net/ethernet/freescale/enetc/enetc.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc.c -@@ -1361,6 +1361,7 @@ static int enetc_phy_connect(struct net_ - { - struct enetc_ndev_priv *priv = netdev_priv(ndev); - struct phy_device *phydev; -+ struct ethtool_eee edata; - - if (!priv->phy_node) - return 0; /* phy-less mode */ -@@ -1374,6 +1375,10 @@ static int enetc_phy_connect(struct net_ - - phy_attached_info(phydev); - -+ /* disable EEE autoneg, until ENETC driver supports it */ -+ memset(&edata, 0, sizeof(struct ethtool_eee)); -+ phy_ethtool_set_eee(phydev, &edata); -+ - return 0; - } - diff --git a/target/linux/layerscape/patches-5.4/701-net-0343-staging-dpaa2-ethsw-move-port-notifier-per-ethsw.patch b/target/linux/layerscape/patches-5.4/701-net-0343-staging-dpaa2-ethsw-move-port-notifier-per-ethsw.patch deleted file mode 100644 index 5024e98221..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0343-staging-dpaa2-ethsw-move-port-notifier-per-ethsw.patch +++ /dev/null @@ -1,80 +0,0 @@ -From daaa4e77f9bc9e67fa3fd973d4455631d59fb898 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Mon, 11 Nov 2019 18:50:55 +0200 -Subject: [PATCH] staging: dpaa2-ethsw: move port notifier per ethsw - -Register a different net_device notifier block per ethsw instance. -When probing multiple dpaa2-ethsw instances, without this the register -will fail. - -Signed-off-by: Ioana Ciornei -Link: https://lore.kernel.org/r/1573491058-24766-2-git-send-email-ioana.ciornei@nxp.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 13 ++++++------- - drivers/staging/fsl-dpaa2/ethsw/ethsw.h | 2 ++ - 2 files changed, 8 insertions(+), 7 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c -+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c -@@ -1174,10 +1174,6 @@ static int port_netdevice_event(struct n - return notifier_from_errno(err); - } - --static struct notifier_block port_nb __read_mostly = { -- .notifier_call = port_netdevice_event, --}; -- - struct ethsw_switchdev_event_work { - struct work_struct work; - struct switchdev_notifier_fdb_info fdb_info; -@@ -1328,9 +1324,11 @@ static struct notifier_block port_switch - - static int ethsw_register_notifier(struct device *dev) - { -+ struct ethsw_core *ethsw = dev_get_drvdata(dev); - int err; - -- err = register_netdevice_notifier(&port_nb); -+ ethsw->port_nb.notifier_call = port_netdevice_event; -+ err = register_netdevice_notifier(ðsw->port_nb); - if (err) { - dev_err(dev, "Failed to register netdev notifier\n"); - return err; -@@ -1353,7 +1351,7 @@ static int ethsw_register_notifier(struc - err_switchdev_blocking_nb: - unregister_switchdev_notifier(&port_switchdev_nb); - err_switchdev_nb: -- unregister_netdevice_notifier(&port_nb); -+ unregister_netdevice_notifier(ðsw->port_nb); - return err; - } - -@@ -1491,6 +1489,7 @@ static int ethsw_port_init(struct ethsw_ - - static void ethsw_unregister_notifier(struct device *dev) - { -+ struct ethsw_core *ethsw = dev_get_drvdata(dev); - struct notifier_block *nb; - int err; - -@@ -1505,7 +1504,7 @@ static void ethsw_unregister_notifier(st - dev_err(dev, - "Failed to unregister switchdev notifier (%d)\n", err); - -- err = unregister_netdevice_notifier(&port_nb); -+ err = unregister_netdevice_notifier(ðsw->port_nb); - if (err) - dev_err(dev, - "Failed to unregister netdev notifier (%d)\n", err); ---- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h -+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h -@@ -66,6 +66,8 @@ struct ethsw_core { - - u8 vlans[VLAN_VID_MASK + 1]; - bool learning; -+ -+ struct notifier_block port_nb; - }; - - #endif /* __ETHSW_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0344-staging-dpaa2-ethsw-move-port-switchdev-notifier-per.patch b/target/linux/layerscape/patches-5.4/701-net-0344-staging-dpaa2-ethsw-move-port-switchdev-notifier-per.patch deleted file mode 100644 index 459d145afc..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0344-staging-dpaa2-ethsw-move-port-switchdev-notifier-per.patch +++ /dev/null @@ -1,68 +0,0 @@ -From e35e9d1a3dd2cc4f06f03ec4c3fae781bb0c5075 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Mon, 11 Nov 2019 18:50:56 +0200 -Subject: [PATCH] staging: dpaa2-ethsw: move port switchdev notifier per ethsw - -Register a different switchdev notifier block per ethsw instance. -When probing multiple dpaa2-ethsw instances, without this the register -will fail. - -Signed-off-by: Ioana Ciornei -Link: https://lore.kernel.org/r/1573491058-24766-3-git-send-email-ioana.ciornei@nxp.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 11 ++++------- - drivers/staging/fsl-dpaa2/ethsw/ethsw.h | 1 + - 2 files changed, 5 insertions(+), 7 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c -+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c -@@ -1314,10 +1314,6 @@ static int port_switchdev_blocking_event - return NOTIFY_DONE; - } - --static struct notifier_block port_switchdev_nb = { -- .notifier_call = port_switchdev_event, --}; -- - static struct notifier_block port_switchdev_blocking_nb = { - .notifier_call = port_switchdev_blocking_event, - }; -@@ -1334,7 +1330,8 @@ static int ethsw_register_notifier(struc - return err; - } - -- err = register_switchdev_notifier(&port_switchdev_nb); -+ ethsw->port_switchdev_nb.notifier_call = port_switchdev_event; -+ err = register_switchdev_notifier(ðsw->port_switchdev_nb); - if (err) { - dev_err(dev, "Failed to register switchdev notifier\n"); - goto err_switchdev_nb; -@@ -1349,7 +1346,7 @@ static int ethsw_register_notifier(struc - return 0; - - err_switchdev_blocking_nb: -- unregister_switchdev_notifier(&port_switchdev_nb); -+ unregister_switchdev_notifier(ðsw->port_switchdev_nb); - err_switchdev_nb: - unregister_netdevice_notifier(ðsw->port_nb); - return err; -@@ -1499,7 +1496,7 @@ static void ethsw_unregister_notifier(st - dev_err(dev, - "Failed to unregister switchdev blocking notifier (%d)\n", err); - -- err = unregister_switchdev_notifier(&port_switchdev_nb); -+ err = unregister_switchdev_notifier(ðsw->port_switchdev_nb); - if (err) - dev_err(dev, - "Failed to unregister switchdev notifier (%d)\n", err); ---- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h -+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h -@@ -68,6 +68,7 @@ struct ethsw_core { - bool learning; - - struct notifier_block port_nb; -+ struct notifier_block port_switchdev_nb; - }; - - #endif /* __ETHSW_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0345-staging-dpaa2-ethsw-move-port-switchdev-blocking-not.patch b/target/linux/layerscape/patches-5.4/701-net-0345-staging-dpaa2-ethsw-move-port-switchdev-blocking-not.patch deleted file mode 100644 index ace7012f42..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0345-staging-dpaa2-ethsw-move-port-switchdev-blocking-not.patch +++ /dev/null @@ -1,60 +0,0 @@ -From e6987a7f7ebbde64eb679f10a6eb857b9e28d05d Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Mon, 11 Nov 2019 18:50:57 +0200 -Subject: [PATCH] staging: dpaa2-ethsw: move port switchdev blocking notifier - per ethsw - -Register a different switchdev blocking notifier block per ethsw -instance. When probing multiple dpaa2-ethsw instances, without this the -register will fail. - -Signed-off-by: Ioana Ciornei -Link: https://lore.kernel.org/r/1573491058-24766-4-git-send-email-ioana.ciornei@nxp.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 9 +++------ - drivers/staging/fsl-dpaa2/ethsw/ethsw.h | 1 + - 2 files changed, 4 insertions(+), 6 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c -+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c -@@ -1314,10 +1314,6 @@ static int port_switchdev_blocking_event - return NOTIFY_DONE; - } - --static struct notifier_block port_switchdev_blocking_nb = { -- .notifier_call = port_switchdev_blocking_event, --}; -- - static int ethsw_register_notifier(struct device *dev) - { - struct ethsw_core *ethsw = dev_get_drvdata(dev); -@@ -1337,7 +1333,8 @@ static int ethsw_register_notifier(struc - goto err_switchdev_nb; - } - -- err = register_switchdev_blocking_notifier(&port_switchdev_blocking_nb); -+ ethsw->port_switchdevb_nb.notifier_call = port_switchdev_blocking_event; -+ err = register_switchdev_blocking_notifier(ðsw->port_switchdevb_nb); - if (err) { - dev_err(dev, "Failed to register switchdev blocking notifier\n"); - goto err_switchdev_blocking_nb; -@@ -1490,7 +1487,7 @@ static void ethsw_unregister_notifier(st - struct notifier_block *nb; - int err; - -- nb = &port_switchdev_blocking_nb; -+ nb = ðsw->port_switchdevb_nb; - err = unregister_switchdev_blocking_notifier(nb); - if (err) - dev_err(dev, ---- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h -+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h -@@ -69,6 +69,7 @@ struct ethsw_core { - - struct notifier_block port_nb; - struct notifier_block port_switchdev_nb; -+ struct notifier_block port_switchdevb_nb; - }; - - #endif /* __ETHSW_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0346-staging-dpaa2-ethsw-ordered-workqueue-should-be-per-.patch b/target/linux/layerscape/patches-5.4/701-net-0346-staging-dpaa2-ethsw-ordered-workqueue-should-be-per-.patch deleted file mode 100644 index e8ef62951b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0346-staging-dpaa2-ethsw-ordered-workqueue-should-be-per-.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 6e0b1cafcfc1bf343cf4957a93850178ba9ea165 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Mon, 11 Nov 2019 18:50:58 +0200 -Subject: [PATCH] staging: dpaa2-ethsw: ordered workqueue should be per ethsw - -Create a different ordered workqueue per dpaa2-ethsw instance. Without -this change, we overwrite the global queue and leak memory when probing -multiple instances of the driver. - -Signed-off-by: Ioana Ciornei -Link: https://lore.kernel.org/r/1573491058-24766-5-git-send-email-ioana.ciornei@nxp.com -Signed-off-by: Greg Kroah-Hartman ---- - drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 17 +++++++++-------- - drivers/staging/fsl-dpaa2/ethsw/ethsw.h | 1 + - 2 files changed, 10 insertions(+), 8 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c -+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c -@@ -18,8 +18,6 @@ - - #include "ethsw.h" - --static struct workqueue_struct *ethsw_owq; -- - /* Minimal supported DPSW version */ - #define DPSW_MIN_VER_MAJOR 8 - #define DPSW_MIN_VER_MINOR 1 -@@ -1229,8 +1227,10 @@ static int port_switchdev_event(struct n - unsigned long event, void *ptr) - { - struct net_device *dev = switchdev_notifier_info_to_dev(ptr); -+ struct ethsw_port_priv *port_priv = netdev_priv(dev); - struct ethsw_switchdev_event_work *switchdev_work; - struct switchdev_notifier_fdb_info *fdb_info = ptr; -+ struct ethsw_core *ethsw = port_priv->ethsw_data; - - if (!ethsw_port_dev_check(dev)) - return NOTIFY_DONE; -@@ -1266,7 +1266,7 @@ static int port_switchdev_event(struct n - return NOTIFY_DONE; - } - -- queue_work(ethsw_owq, &switchdev_work->work); -+ queue_work(ethsw->workqueue, &switchdev_work->work); - - return NOTIFY_DONE; - -@@ -1427,9 +1427,10 @@ static int ethsw_init(struct fsl_mc_devi - } - } - -- ethsw_owq = alloc_ordered_workqueue("%s_ordered", WQ_MEM_RECLAIM, -- "ethsw"); -- if (!ethsw_owq) { -+ ethsw->workqueue = alloc_ordered_workqueue("%s_%d_ordered", -+ WQ_MEM_RECLAIM, "ethsw", -+ ethsw->sw_attr.id); -+ if (!ethsw->workqueue) { - err = -ENOMEM; - goto err_close; - } -@@ -1441,7 +1442,7 @@ static int ethsw_init(struct fsl_mc_devi - return 0; - - err_destroy_ordered_workqueue: -- destroy_workqueue(ethsw_owq); -+ destroy_workqueue(ethsw->workqueue); - - err_close: - dpsw_close(ethsw->mc_io, 0, ethsw->dpsw_handle); -@@ -1529,7 +1530,7 @@ static int ethsw_remove(struct fsl_mc_de - - ethsw_teardown_irqs(sw_dev); - -- destroy_workqueue(ethsw_owq); -+ destroy_workqueue(ethsw->workqueue); - - dpsw_disable(ethsw->mc_io, 0, ethsw->dpsw_handle); - ---- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.h -+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.h -@@ -70,6 +70,7 @@ struct ethsw_core { - struct notifier_block port_nb; - struct notifier_block port_switchdev_nb; - struct notifier_block port_switchdevb_nb; -+ struct workqueue_struct *workqueue; - }; - - #endif /* __ETHSW_H */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0347-staging-fsl-dpaa2-mac-do-not-call-dpmac_set_link_sta.patch b/target/linux/layerscape/patches-5.4/701-net-0347-staging-fsl-dpaa2-mac-do-not-call-dpmac_set_link_sta.patch deleted file mode 100644 index 69202375ee..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0347-staging-fsl-dpaa2-mac-do-not-call-dpmac_set_link_sta.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 978b13baa79b68f3471cc2c5110a2e45aab9ca61 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Tue, 10 Dec 2019 17:26:06 +0200 -Subject: [PATCH] staging: fsl-dpaa2/mac: do not call dpmac_set_link_state() - when nothing changed - -In case nothing changed in the link configuration do not call -dpmac_set_link_state(). -This is needed in case of the following sequence of commands. - -$ ip link set dev eth1 up; ip link set dev eth2 down - -Phylib brings the link down when the aneg is started on the phy which -translates in a link down from phy in MC and confuses the MC linkman. - -Signed-off-by: Ioana Ciornei ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 16 ++++++++++------ - 1 file changed, 10 insertions(+), 6 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -158,12 +158,16 @@ static void dpaa2_mac_link_changed(struc - netif_carrier_off(netdev); - } - -- if (priv->old_state.up != state.up || -- priv->old_state.rate != state.rate || -- priv->old_state.options != state.options) { -- priv->old_state = state; -- phy_print_status(phydev); -- } -+ /* Call the dpmac_set_link_state() only if there is a change in the -+ * link configuration -+ */ -+ if (priv->old_state.up == state.up && -+ priv->old_state.rate == state.rate && -+ priv->old_state.options == state.options) -+ return; -+ -+ priv->old_state = state; -+ phy_print_status(phydev); - - if (cmp_dpmac_ver(priv, DPMAC_LINK_AUTONEG_VER_MAJOR, - DPMAC_LINK_AUTONEG_VER_MINOR) < 0) { diff --git a/target/linux/layerscape/patches-5.4/701-net-0348-staging-fsl-dpaa2-mac-reverse-order-of-handling-stop.patch b/target/linux/layerscape/patches-5.4/701-net-0348-staging-fsl-dpaa2-mac-reverse-order-of-handling-stop.patch deleted file mode 100644 index 6788b8425b..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0348-staging-fsl-dpaa2-mac-reverse-order-of-handling-stop.patch +++ /dev/null @@ -1,37 +0,0 @@ -From c9db7ecdd08e38fb1af207c2a7e810b4bd0d1043 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Wed, 11 Dec 2019 17:06:40 +0200 -Subject: [PATCH] staging: fsl-dpaa2/mac: reverse order of handling stop/start - IRQs - -Both the LINK_UP_REQ and the LINK_DOWN_REQ IRQs can be received in the -same time when a reset is performed on the DPMAC's partner. -Handle first the link down and then the link up so that we do not -trigger a phylib WARNING like the following: - -[ 446.272011] called from state NOLINK -[ 446.275604] WARNING: CPU: 0 PID: 473 at drivers/net/phy/phy.c:874 -phy_start+0x44/0xa8 - -Signed-off-by: Ioana Ciornei ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -482,12 +482,11 @@ static irqreturn_t dpaa2_mac_irq_handler - configure_link(priv, &link_cfg); - } - -- if (status & DPMAC_IRQ_EVENT_LINK_UP_REQ) -- phy_start(ndev->phydev); -- - if (status & DPMAC_IRQ_EVENT_LINK_DOWN_REQ) - phy_stop(ndev->phydev); - -+ if (status & DPMAC_IRQ_EVENT_LINK_UP_REQ) -+ phy_start(ndev->phydev); - out: - dpmac_clear_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle, - DPMAC_IRQ_INDEX, status); diff --git a/target/linux/layerscape/patches-5.4/701-net-0349-fsl_qbman-add-dummy-functions-for-probe-deferal-APIs.patch b/target/linux/layerscape/patches-5.4/701-net-0349-fsl_qbman-add-dummy-functions-for-probe-deferal-APIs.patch deleted file mode 100644 index 7192ae79aa..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0349-fsl_qbman-add-dummy-functions-for-probe-deferal-APIs.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d7050fa7b0b0e88217ebfc09666eb08632dfe436 Mon Sep 17 00:00:00 2001 -From: Laurentiu Tudor -Date: Tue, 12 Mar 2019 17:57:26 +0200 -Subject: [PATCH] fsl_qbman: add dummy functions for probe deferal APIs - -Add missing definitions for probe deferal APIs for drivers -that use them with the SDK version of the qbman drivers. - -Signed-off-by: Laurentiu Tudor -Signed-off-by: Vlad Pelin -Acked-by: Madalin Bucur ---- - include/linux/fsl_qman.h | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/include/linux/fsl_qman.h -+++ b/include/linux/fsl_qman.h -@@ -3893,6 +3893,16 @@ int qman_p_enqueue_orp(struct qman_porta - int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq, - const struct qm_fd *fd, u32 flags, - qman_cb_precommit cb, void *cb_arg); -+ -+static inline int qman_is_probed(void) { -+ return 1; -+} -+ -+ -+static inline int qman_portals_probed(void) { -+ return 1; -+} -+ - #ifdef __cplusplus - } - #endif diff --git a/target/linux/layerscape/patches-5.4/701-net-0350-sdk_fman-fix-identation-causing-compilation-warnings.patch b/target/linux/layerscape/patches-5.4/701-net-0350-sdk_fman-fix-identation-causing-compilation-warnings.patch deleted file mode 100644 index 64eb72d3a5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0350-sdk_fman-fix-identation-causing-compilation-warnings.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 2152a79d81c23f21bedd9ea5934c6df266642f36 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Thu, 19 Dec 2019 14:33:11 +0200 -Subject: [PATCH] sdk_fman: fix identation causing compilation warnings - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c -@@ -460,8 +460,8 @@ uint8_t fman_get_num_of_tasks(struct fma - { - uint32_t tmp; - -- if ((port_id > 63) || (port_id < 1)) -- return 0; -+ if ((port_id > 63) || (port_id < 1)) -+ return 0; - - tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]); - return (uint8_t)(((tmp & BMI_NUM_OF_TASKS_MASK) >> -@@ -472,8 +472,8 @@ uint8_t fman_get_num_extra_tasks(struct - { - uint32_t tmp; - -- if ((port_id > 63) || (port_id < 1)) -- return 0; -+ if ((port_id > 63) || (port_id < 1)) -+ return 0; - - tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]); - return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_TASKS_MASK) >> diff --git a/target/linux/layerscape/patches-5.4/701-net-0351-sdk_fman-address-compilation-warning.patch b/target/linux/layerscape/patches-5.4/701-net-0351-sdk_fman-address-compilation-warning.patch deleted file mode 100644 index efcaccc41f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0351-sdk_fman-address-compilation-warning.patch +++ /dev/null @@ -1,32 +0,0 @@ -From dd20e6f1e67e50bfa557b3b4597dd76dc1589644 Mon Sep 17 00:00:00 2001 -From: Madalin Bucur -Date: Thu, 19 Dec 2019 14:41:09 +0200 -Subject: [PATCH] sdk_fman: address compilation warning - -Signed-off-by: Madalin Bucur ---- - drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c -@@ -642,6 +642,8 @@ t_Error FmHcPcdKgSetClsPlan(t_Handle h_F - t_DpaaFD fmFd; - uint8_t i, idx; - uint32_t seqNum; -+ const void *src; -+ void *dest; - t_Error err = E_OK; - - ASSERT_COND(p_FmHc); -@@ -659,7 +661,9 @@ t_Error FmHcPcdKgSetClsPlan(t_Handle h_F - - idx = (uint8_t)(i - p_Set->baseEntry); - ASSERT_COND(idx < FM_PCD_MAX_NUM_OF_CLS_PLANS); -- memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t)); -+ dest = (void *)&p_HcFrame->hcSpecificData.clsPlanEntries; -+ src = &p_Set->vectors[idx]; -+ memcpy(dest, src, CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t)); - p_HcFrame->commandSequence = seqNum; - - BUILD_FD(sizeof(t_HcFrame)); diff --git a/target/linux/layerscape/patches-5.4/701-net-0352-soc-fsl-dpio-Enable-ACP-port-in-Linux-QMAN-driver.patch b/target/linux/layerscape/patches-5.4/701-net-0352-soc-fsl-dpio-Enable-ACP-port-in-Linux-QMAN-driver.patch deleted file mode 100644 index ed1978b564..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0352-soc-fsl-dpio-Enable-ACP-port-in-Linux-QMAN-driver.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 462a65a13cff2e04122df6a770d91ef1e301b359 Mon Sep 17 00:00:00 2001 -From: Youri Querry -Date: Thu, 19 Dec 2019 09:44:33 -0500 -Subject: [PATCH] soc: fsl: dpio: Enable ACP port in Linux QMAN driver - -Setting the software portal configuration DE(dequeue stashing -enable) bit. This should enable the ACP (Accelerator Coherency -Port). - -During test this improved performance on the LS2088a slightly. No -effect on the LX2160a. - -Signed-off-by: Youri Querry ---- - drivers/soc/fsl/dpio/qbman-portal.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/soc/fsl/dpio/qbman-portal.c -+++ b/drivers/soc/fsl/dpio/qbman-portal.c -@@ -299,7 +299,7 @@ struct qbman_swp *qbman_swp_init(const s - 1, /* mem stashing priority enable */ - 1, /* mem stashing enable */ - 1, /* dequeue stashing priority enable */ -- 0, /* dequeue stashing enable enable */ -+ 1, /* dequeue stashing enable enable */ - 0); /* EQCR_CI stashing priority enable */ - } else { - memset(p->addr_cena, 0, 64 * 1024); -@@ -313,7 +313,7 @@ struct qbman_swp *qbman_swp_init(const s - 1, /* mem stashing priority enable */ - 1, /* mem stashing enable */ - 1, /* dequeue stashing priority enable */ -- 0, /* dequeue stashing enable */ -+ 1, /* dequeue stashing enable */ - 0); /* EQCR_CI stashing priority enable */ - reg |= 1 << SWP_CFG_CPBS_SHIFT | /* memory-backed mode */ - 1 << SWP_CFG_VPM_SHIFT | /* VDQCR read triggered mode */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0353-staging-fsl-dpaa2-mac-do-not-stop-MAC-when-the-net_d.patch b/target/linux/layerscape/patches-5.4/701-net-0353-staging-fsl-dpaa2-mac-do-not-stop-MAC-when-the-net_d.patch deleted file mode 100644 index 80bb697edf..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0353-staging-fsl-dpaa2-mac-do-not-stop-MAC-when-the-net_d.patch +++ /dev/null @@ -1,65 +0,0 @@ -From aae18d4ce3055e459855cc8661cf8f2a5e2cbe73 Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Fri, 13 Dec 2019 13:24:01 +0200 -Subject: [PATCH] staging: fsl-dpaa2/mac: do not stop MAC when the net_dev is - not up - -In case the net_device is not up, there is no need to call -dpmac_mac_stop(). Guard the call by checking the IFF_UP flag. -This patch will also solve the following warning generated by removing a -dpmac that is not up. - -[ 40.942937] called from state READY -[ 40.946442] WARNING: CPU: 0 PID: 755 at drivers/net/phy/phy.c:838 -phy_stop+0x6c/0x78 -[ 40.954171] Modules linked in: -[ 40.957214] CPU: 0 PID: 755 Comm: bash Tainted: G W -5.4.0-03629-gfd7102c32b2c-dirty #911 -[ 40.966592] Hardware name: NXP Layerscape LX2160ARDB (DT) -[ 40.971978] pstate: 40000005 (nZcv daif -PAN -UAO) -[ 40.976756] pc : phy_stop+0x6c/0x78 -[ 40.980232] lr : phy_stop+0x6c/0x78 -(..) -[ 41.066487] Call trace: -[ 41.068922] phy_stop+0x6c/0x78 -[ 41.072052] dpaa2_mac_stop.part.4+0x34/0x5c -[ 41.076309] dpaa2_mac_remove+0x9c/0xa8 - -Also, remove the IFF_UP flag from the mac netdev since the PHY is not -anymore started at probe time but is rather started/stopped on ifconfig -up/down. - -Signed-off-by: Ioana Ciornei ---- - drivers/staging/fsl-dpaa2/mac/mac.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - ---- a/drivers/staging/fsl-dpaa2/mac/mac.c -+++ b/drivers/staging/fsl-dpaa2/mac/mac.c -@@ -1,5 +1,5 @@ - /* Copyright 2015 Freescale Semiconductor Inc. -- * Copyright 2018 NXP -+ * Copyright 2018-2019 NXP - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: -@@ -664,9 +664,6 @@ static int dpaa2_mac_probe(struct fsl_mc - netdev->netdev_ops = &dpaa2_mac_ndo_ops; - netdev->ethtool_ops = &dpaa2_mac_ethtool_ops; - -- /* phy starts up enabled so netdev should be up too */ -- netdev->flags |= IFF_UP; -- - err = register_netdev(priv->netdev); - if (err < 0) { - dev_err(dev, "register_netdev error %d\n", err); -@@ -775,7 +772,8 @@ static int dpaa2_mac_remove(struct fsl_m - struct dpaa2_mac_priv *priv = dev_get_drvdata(dev); - struct net_device *netdev = priv->netdev; - -- dpaa2_mac_stop(netdev); -+ if (netdev->flags & IFF_UP) -+ dpaa2_mac_stop(netdev); - - if (phy_is_pseudo_fixed_link(netdev->phydev)) - fixed_phy_unregister(netdev->phydev); diff --git a/target/linux/layerscape/patches-5.4/701-net-0354-bus-fsl-mc-add-the-dpdbg-device-type.patch b/target/linux/layerscape/patches-5.4/701-net-0354-bus-fsl-mc-add-the-dpdbg-device-type.patch deleted file mode 100644 index 6a20704a6c..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0354-bus-fsl-mc-add-the-dpdbg-device-type.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 6f506965930f06a3c82ba46c5f095e7b1b6368af Mon Sep 17 00:00:00 2001 -From: Ioana Ciornei -Date: Fri, 20 Dec 2019 14:35:52 +0200 -Subject: [PATCH] bus: fsl-mc: add the dpdbg device type - -A new object type was recently added in MC. This has to be added in the -fsl-mc bus device type list so that it can be properly listed. - -Signed-off-by: Ioana Ciornei -Reviewed-by: Madalin Bucur ---- - drivers/bus/fsl-mc/fsl-mc-bus.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/bus/fsl-mc/fsl-mc-bus.c -+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c -@@ -369,6 +369,10 @@ struct device_type fsl_mc_bus_dpdmai_typ - .name = "fsl_mc_bus_dpdmai" - }; - -+struct device_type fsl_mc_bus_dpdbg_type = { -+ .name = "fsl_mc_bus_dpdbg" -+}; -+ - static struct device_type *fsl_mc_get_device_type(const char *type) - { - static const struct { -@@ -390,6 +394,7 @@ static struct device_type *fsl_mc_get_de - { &fsl_mc_bus_dpaiop_type, "dpaiop" }, - { &fsl_mc_bus_dpci_type, "dpci" }, - { &fsl_mc_bus_dpdmai_type, "dpdmai" }, -+ { &fsl_mc_bus_dpdbg_type, "dpdbg" }, - { NULL, NULL } - }; - int i; diff --git a/target/linux/layerscape/patches-5.4/701-net-0355-sdk_fman-decrease-log-severity-levels.patch b/target/linux/layerscape/patches-5.4/701-net-0355-sdk_fman-decrease-log-severity-levels.patch deleted file mode 100644 index 5bb3d7b8fa..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0355-sdk_fman-decrease-log-severity-levels.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 1cbcd6a80eb6bbea5747a5a8edc450d8fc48e976 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Thu, 19 Dec 2019 11:38:33 +0200 -Subject: [PATCH] sdk_fman: decrease log severity levels - -Decrease the severity of log messages from critical to appropriate -levels (warning and info). - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 2 +- - drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c | 4 ++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -@@ -2896,7 +2896,7 @@ static int __init __cold fm_load (void) - return -ENODEV; - } - -- printk(KERN_CRIT "Freescale FM module," \ -+ printk(KERN_INFO "Freescale FM module," \ - " FMD API version %d.%d.%d\n", - FMD_API_VERSION_MAJOR, - FMD_API_VERSION_MINOR, ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c -@@ -1494,11 +1494,11 @@ void LNXWRP_FM_Port_Free(void) - static int __init __cold fm_port_load(void) - { - if (LNXWRP_FM_Port_Init() != E_OK) { -- printk(KERN_CRIT "Failed to init FM Ports wrapper!\n"); -+ printk(KERN_ERR "Failed to init FM Ports wrapper!\n"); - return -ENODEV; - } - -- printk(KERN_CRIT "Freescale FM Ports module\n"); -+ printk(KERN_INFO "Freescale FM Ports module\n"); - - return 0; - } diff --git a/target/linux/layerscape/patches-5.4/701-net-0356-sdk_dpaa-ethtool-drop-unused-variable.patch b/target/linux/layerscape/patches-5.4/701-net-0356-sdk_dpaa-ethtool-drop-unused-variable.patch deleted file mode 100644 index 7d59d550fb..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0356-sdk_dpaa-ethtool-drop-unused-variable.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 77d8734e1870f842d1e62addec82e5c05c1a6630 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 29 Oct 2019 16:07:57 +0200 -Subject: [PATCH] sdk_dpaa: ethtool: drop unused variable - -Remove unused variable that was missed in past code refactorings. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c -@@ -90,7 +90,6 @@ static char dpa_stats_global[][ETH_GSTRI - static int __cold dpa_get_ksettings(struct net_device *net_dev, - struct ethtool_link_ksettings *cmd) - { -- int _errno; - struct dpa_priv_s *priv; - - priv = netdev_priv(net_dev); -@@ -106,7 +105,7 @@ static int __cold dpa_get_ksettings(stru - - phy_ethtool_ksettings_get(priv->mac_dev->phy_dev, cmd); - -- return _errno; -+ return 0; - } - - static int __cold dpa_set_ksettings(struct net_device *net_dev, diff --git a/target/linux/layerscape/patches-5.4/701-net-0357-sdk_dpaa-ls1043a-errata-memory-related-fixes.patch b/target/linux/layerscape/patches-5.4/701-net-0357-sdk_dpaa-ls1043a-errata-memory-related-fixes.patch deleted file mode 100644 index 6daee462bc..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0357-sdk_dpaa-ls1043a-errata-memory-related-fixes.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 26d3cc476c26832e1e05db182ac27906f6c81f2d Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 29 Oct 2019 16:12:18 +0200 -Subject: [PATCH] sdk_dpaa: ls1043a errata: memory related fixes - -Avoid a crash by verifying the allocation return status. - -Use the standard API for determining the page order needed for -allocating Jumbo sized skbs. - -Explicitly remove the old skb outside the w/a, for both successful and -unsuccessful realignments. Make sure the old skb's memory isn't leaked. - -Signed-off-by: Camelia Groza ---- - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 30 ++++++++++++++-------- - 1 file changed, 19 insertions(+), 11 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -809,8 +809,8 @@ static struct sk_buff *a010022_realign_s - { - int trans_offset = skb_transport_offset(skb); - int net_offset = skb_network_offset(skb); -- int nsize, headroom, npage_order; - struct sk_buff *nskb = NULL; -+ int nsize, headroom; - struct page *npage; - void *npage_addr; - -@@ -825,8 +825,7 @@ static struct sk_buff *a010022_realign_s - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); - - /* Reserve enough memory to accommodate Jumbo frames */ -- npage_order = (nsize - 1) / PAGE_SIZE; -- npage = alloc_pages(GFP_ATOMIC | __GFP_COMP, npage_order); -+ npage = alloc_pages(GFP_ATOMIC | __GFP_COMP, get_order(nsize)); - if (unlikely(!npage)) { - WARN_ONCE(1, "Memory allocation failure\n"); - return NULL; -@@ -869,7 +868,6 @@ static struct sk_buff *a010022_realign_s - /* We don't want the buffer to be recycled so we mark it accordingly */ - nskb->mark = NONREC_MARK; - -- dev_kfree_skb(skb); - return nskb; - - err: -@@ -911,8 +909,13 @@ int __hot skb_to_sg_fd(struct dpa_priv_s - * is in place and we need to avoid crossing a 4k boundary. - */ - #ifndef CONFIG_PPC -- if (unlikely(dpaa_errata_a010022)) -- sgt_buf = page_address(alloc_page(GFP_ATOMIC)); -+ if (unlikely(dpaa_errata_a010022)) { -+ struct page *new_page = alloc_page(GFP_ATOMIC); -+ -+ if (unlikely(!new_page)) -+ return -ENOMEM; -+ sgt_buf = page_address(new_page); -+ } - else - #endif - sgt_buf = netdev_alloc_frag(priv->tx_headroom + sgt_size); -@@ -1061,6 +1064,7 @@ int __hot dpa_tx_extended(struct sk_buff - int err = 0; - bool nonlinear; - int *countptr, offset = 0; -+ struct sk_buff *nskb; - - priv = netdev_priv(net_dev); - /* Non-migratable context, safe to use raw_cpu_ptr */ -@@ -1072,9 +1076,11 @@ int __hot dpa_tx_extended(struct sk_buff - - #ifndef CONFIG_PPC - if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) { -- skb = a010022_realign_skb(skb, priv); -- if (!skb) -+ nskb = a010022_realign_skb(skb, priv); -+ if (!nskb) - goto skb_to_fd_failed; -+ dev_kfree_skb(skb); -+ skb = nskb; - } - #endif - -@@ -1130,15 +1136,17 @@ int __hot dpa_tx_extended(struct sk_buff - - /* Code borrowed from skb_unshare(). */ - if (skb_cloned(skb)) { -- struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC); -+ nskb = skb_copy(skb, GFP_ATOMIC); - kfree_skb(skb); - skb = nskb; - #ifndef CONFIG_PPC - if (unlikely(dpaa_errata_a010022) && - a010022_check_skb(skb, priv)) { -- skb = a010022_realign_skb(skb, priv); -- if (!skb) -+ nskb = a010022_realign_skb(skb, priv); -+ if (!nskb) - goto skb_to_fd_failed; -+ dev_kfree_skb(skb); -+ skb = nskb; - } - #endif - /* skb_copy() has now linearized the skbuff. */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0358-sdk_dpaa-ls1043a-errata-update-and-optimize-the-rest.patch b/target/linux/layerscape/patches-5.4/701-net-0358-sdk_dpaa-ls1043a-errata-update-and-optimize-the-rest.patch deleted file mode 100644 index 684d04b256..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0358-sdk_dpaa-ls1043a-errata-update-and-optimize-the-rest.patch +++ /dev/null @@ -1,252 +0,0 @@ -From e89db675171a7a12f19b6ec0089a9cc62807cdf1 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 29 Oct 2019 16:34:08 +0200 -Subject: [PATCH] sdk_dpaa: ls1043a errata: update and optimize the - restrictions - -An skb is in no danger of triggering the errata under the following -conditions: -- the paged data doesn't cross a 4K page boundary OR the linear data -is aligned to 256 bytes when crossing a 4K page boundary -- the linear and the paged data are 16 byte aligned -- the paged data is a multiple of 16 bytes in size - -Optimize the detection for each skb that might trigger the errata. Parse -the skb twice, at most, and realign it only once. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 2 +- - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 147 +++++++++++++++------ - 2 files changed, 111 insertions(+), 38 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -662,7 +662,7 @@ static inline void _dpa_bp_free_pf(void - #ifndef CONFIG_PPC - extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */ - #define NONREC_MARK 0x01 --#define HAS_DMA_ISSUE(start, size) \ -+#define CROSS_4K(start, size) \ - (((uintptr_t)(start) + (size)) > \ - (((uintptr_t)(start) + 0x1000) & ~0xFFF)) - /* The headroom needs to accommodate our private data (64 bytes) but ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -771,32 +771,73 @@ int __hot skb_to_contig_fd(struct dpa_pr - EXPORT_SYMBOL(skb_to_contig_fd); - - #ifndef CONFIG_PPC --/* Verify the conditions that trigger the A010022 errata: data unaligned to -- * 16 bytes, 4K memory address crossings and S/G fragments. -+/* Verify the conditions that trigger the A010022 errata: -+ * - 4K memory address boundary crossings when the data/SG fragments aren't -+ * aligned to 256 bytes -+ * - data and SG fragments that aren't aligned to 16 bytes -+ * - SG fragments that aren't mod 16 bytes in size (except for the last -+ * fragment) - */ - static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv) - { -- /* Check if the headroom is aligned */ -- if (((uintptr_t)skb->data - priv->tx_headroom) % -- priv->buf_layout[TX].data_align != 0) -- return true; -+ skb_frag_t *frag; -+ int i, nr_frags; - -- /* Check for paged data in the skb. We do not support S/G fragments */ -- if (skb_is_nonlinear(skb)) -+ nr_frags = skb_shinfo(skb)->nr_frags; -+ -+ /* Check if the linear data is 16 byte aligned */ -+ if ((uintptr_t)skb->data % 16) - return true; - -- /* Check if the headroom crosses a boundary */ -- if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb))) -+ /* Check if the needed headroom crosses a 4K address boundary without -+ * being 256 byte aligned -+ */ -+ if (CROSS_4K(skb->data - priv->tx_headroom, priv->tx_headroom) && -+ (((uintptr_t)skb->data - priv->tx_headroom) % 256)) - return true; - -- /* Check if the non-paged data crosses a boundary */ -- if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb))) -+ /* Check if the linear data crosses a 4K address boundary without -+ * being 256 byte aligned -+ */ -+ if (CROSS_4K(skb->data, skb_headlen(skb)) && -+ ((uintptr_t)skb->data % 256)) - return true; - -- /* Check if the entire linear skb crosses a boundary */ -- if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb))) -+ /* When using Scatter/Gather, the linear data becomes the first -+ * fragment in the list and must follow the same restrictions as the -+ * other fragments. -+ * -+ * Check if the linear data is mod 16 bytes in size. -+ */ -+ if (nr_frags && (skb_headlen(skb) % 16)) - return true; - -+ /* Check the SG fragments. They must follow the same rules as the -+ * linear data with and additional restriction: they must be multiple -+ * of 16 bytes in size to account for the hardware carryover effect. -+ */ -+ for (i = 0; i < nr_frags; i++) { -+ frag = &skb_shinfo(skb)->frags[i]; -+ -+ /* Check if the fragment is a multiple of 16 bytes in size. -+ * The last fragment is exempt from this restriction. -+ */ -+ if ((i != (nr_frags - 1)) && (skb_frag_size(frag) % 16)) -+ return true; -+ -+ /* Check if the fragment is 16 byte aligned */ -+ if (skb_frag_off(frag) % 16) -+ return true; -+ -+ /* Check if the fragment crosses a 4K address boundary. Since -+ * the alignment of previous fragments can influence the -+ * current fragment, checking for the 256 byte alignment -+ * isn't relevant. -+ */ -+ if (CROSS_4K(skb_frag_off(frag), skb_frag_size(frag))) -+ return true; -+ } -+ - return false; - } - -@@ -1062,10 +1103,24 @@ int __hot dpa_tx_extended(struct sk_buff - struct dpa_percpu_priv_s *percpu_priv; - struct rtnl_link_stats64 *percpu_stats; - int err = 0; -- bool nonlinear; -+ bool nonlinear, skb_changed, skb_need_wa; - int *countptr, offset = 0; - struct sk_buff *nskb; - -+ /* Flags to help optimize the A010022 errata restriction checks. -+ * -+ * First flag marks if the skb changed between the first A010022 check -+ * and the moment it's converted to an FD. -+ * -+ * The second flag marks if the skb needs to be realigned in order to -+ * avoid the errata. -+ * -+ * The flags should have minimal impact on platforms not impacted by -+ * the errata. -+ */ -+ skb_changed = false; -+ skb_need_wa = false; -+ - priv = netdev_priv(net_dev); - /* Non-migratable context, safe to use raw_cpu_ptr */ - percpu_priv = raw_cpu_ptr(priv->percpu_priv); -@@ -1075,13 +1130,8 @@ int __hot dpa_tx_extended(struct sk_buff - clear_fd(&fd); - - #ifndef CONFIG_PPC -- if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) { -- nskb = a010022_realign_skb(skb, priv); -- if (!nskb) -- goto skb_to_fd_failed; -- dev_kfree_skb(skb); -- skb = nskb; -- } -+ if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) -+ skb_need_wa = true; - #endif - - nonlinear = skb_is_nonlinear(skb); -@@ -1102,8 +1152,8 @@ int __hot dpa_tx_extended(struct sk_buff - * Btw, we're using the first sgt entry to store the linear part of - * the skb, so we're one extra frag short. - */ -- if (nonlinear && -- likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) { -+ if (nonlinear && !skb_need_wa && -+ likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) { - /* Just create a S/G fd based on the skb */ - err = skb_to_sg_fd(priv, skb, &fd); - percpu_priv->tx_frag_skbuffs++; -@@ -1128,39 +1178,62 @@ int __hot dpa_tx_extended(struct sk_buff - - dev_kfree_skb(skb); - skb = skb_new; -+ skb_changed = true; - } - - /* We're going to store the skb backpointer at the beginning - * of the data buffer, so we need a privately owned skb -+ * -+ * Under the A010022 errata, we are going to have a privately -+ * owned skb after realigning the current one, so no point in -+ * copying it here in that case. - */ - - /* Code borrowed from skb_unshare(). */ -- if (skb_cloned(skb)) { -+ if (skb_cloned(skb) && !skb_need_wa) { - nskb = skb_copy(skb, GFP_ATOMIC); - kfree_skb(skb); - skb = nskb; --#ifndef CONFIG_PPC -- if (unlikely(dpaa_errata_a010022) && -- a010022_check_skb(skb, priv)) { -- nskb = a010022_realign_skb(skb, priv); -- if (!nskb) -- goto skb_to_fd_failed; -- dev_kfree_skb(skb); -- skb = nskb; -- } --#endif -+ skb_changed = true; -+ - /* skb_copy() has now linearized the skbuff. */ -- } else if (unlikely(nonlinear)) { -+ } else if (unlikely(nonlinear) && !skb_need_wa) { - /* We are here because the egress skb contains - * more fragments than we support. In this case, - * we have no choice but to linearize it ourselves. - */ -- err = __skb_linearize(skb); -+#ifndef CONFIG_PPC -+ /* No point in linearizing the skb now if we are going -+ * to realign and linearize it again further down due -+ * to the A010022 errata -+ */ -+ if (unlikely(dpaa_errata_a010022)) -+ skb_need_wa = true; -+ else -+#endif -+ err = __skb_linearize(skb); - } - if (unlikely(!skb || err < 0)) - /* Common out-of-memory error path */ - goto enomem; - -+#ifndef CONFIG_PPC -+ /* Verify the skb a second time if it has been updated since -+ * the previous check -+ */ -+ if (unlikely(dpaa_errata_a010022) && skb_changed && -+ a010022_check_skb(skb, priv)) -+ skb_need_wa = true; -+ -+ if (unlikely(dpaa_errata_a010022) && skb_need_wa) { -+ nskb = a010022_realign_skb(skb, priv); -+ if (!nskb) -+ goto skb_to_fd_failed; -+ dev_kfree_skb(skb); -+ skb = nskb; -+ } -+#endif -+ - err = skb_to_contig_fd(priv, skb, &fd, countptr, &offset); - } - if (unlikely(err < 0)) diff --git a/target/linux/layerscape/patches-5.4/701-net-0359-sdk_dpaa-ls1043a-errata-re-enable-SG-support-and-rec.patch b/target/linux/layerscape/patches-5.4/701-net-0359-sdk_dpaa-ls1043a-errata-re-enable-SG-support-and-rec.patch deleted file mode 100644 index d6bb4c45e9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0359-sdk_dpaa-ls1043a-errata-re-enable-SG-support-and-rec.patch +++ /dev/null @@ -1,71 +0,0 @@ -From fc7824df7022869a403c8a5122a55fe73a193466 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Tue, 29 Oct 2019 16:50:34 +0200 -Subject: [PATCH] sdk_dpaa: ls1043a errata: re-enable SG support and recycling - -With certain limitation, SG frames can be used safely without triggering -the errata. - -Buffers can be recycled, even after realigning the data. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 10 ---------- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 1 - - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 9 --------- - 3 files changed, 20 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -@@ -778,16 +778,6 @@ static int dpa_private_netdev_init(struc - /* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */ - net_dev->features |= NETIF_F_HW_ACCEL_MQ; - --#ifndef CONFIG_PPC -- /* Due to the A010022 FMan errata, we can not use S/G frames. We need -- * to stop advertising S/G and GSO support. -- */ -- if (unlikely(dpaa_errata_a010022)) { -- net_dev->hw_features &= ~NETIF_F_SG; -- net_dev->features &= ~NETIF_F_GSO; -- } --#endif -- - return dpa_netdev_init(net_dev, mac_addr, tx_timeout); - } - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -661,7 +661,6 @@ static inline void _dpa_bp_free_pf(void - - #ifndef CONFIG_PPC - extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */ --#define NONREC_MARK 0x01 - #define CROSS_4K(start, size) \ - (((uintptr_t)(start) + (size)) > \ - (((uintptr_t)(start) + 0x1000) & ~0xFFF)) ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -327,12 +327,6 @@ EXPORT_SYMBOL(_dpa_cleanup_tx_fd); - #ifndef CONFIG_FSL_DPAA_TS - bool dpa_skb_is_recyclable(struct sk_buff *skb) - { --#ifndef CONFIG_PPC -- /* Do no recycle skbs realigned by the errata workaround */ -- if (unlikely(dpaa_errata_a010022) && skb->mark == NONREC_MARK) -- return false; --#endif -- - /* No recycling possible if skb buffer is kmalloc'ed */ - if (skb->head_frag == 0) - return false; -@@ -906,9 +900,6 @@ static struct sk_buff *a010022_realign_s - skb_set_network_header(nskb, net_offset); - skb_set_transport_header(nskb, trans_offset); - -- /* We don't want the buffer to be recycled so we mark it accordingly */ -- nskb->mark = NONREC_MARK; -- - return nskb; - - err: diff --git a/target/linux/layerscape/patches-5.4/701-net-0360-sdk_dpaa-sdk_fman-ls1043a-errata-detect-based-on-DTB.patch b/target/linux/layerscape/patches-5.4/701-net-0360-sdk_dpaa-sdk_fman-ls1043a-errata-detect-based-on-DTB.patch deleted file mode 100644 index e9e5ae03dd..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0360-sdk_dpaa-sdk_fman-ls1043a-errata-detect-based-on-DTB.patch +++ /dev/null @@ -1,297 +0,0 @@ -From 6dbf409f09fd85d738652c7867a5822f682d5682 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Thu, 12 Dec 2019 14:15:05 +0200 -Subject: [PATCH] sdk_dpaa: sdk_fman: ls1043a errata: detect based on DTB - property - -Detect if the platform is vulnerable to the A010022 erratum based on device -tree properties instead of the SoC family. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 31 +--------------------- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 14 +++++----- - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 25 ++++++++--------- - .../inc/integrations/LS1043/dpaa_integration_ext.h | 3 +++ - .../sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h | 10 +++++++ - .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 17 ++++++++++++ - 6 files changed, 51 insertions(+), 49 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -@@ -1,4 +1,5 @@ - /* Copyright 2008-2013 Freescale Semiconductor Inc. -+ * Copyright 2019 NXP - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: -@@ -105,11 +106,6 @@ static const char rtx[][3] = { - [TX] = "TX" - }; - --#ifndef CONFIG_PPC --bool dpaa_errata_a010022; --EXPORT_SYMBOL(dpaa_errata_a010022); --#endif -- - /* BM */ - - #define DPAA_ETH_MAX_PAD (L1_CACHE_BYTES * 8) -@@ -1133,26 +1129,6 @@ static struct platform_driver dpa_driver - .remove = dpa_remove - }; - --#ifndef CONFIG_PPC --static bool __init __cold soc_has_errata_a010022(void) --{ --#ifdef CONFIG_SOC_BUS -- const struct soc_device_attribute soc_msi_matches[] = { -- { .family = "QorIQ LS1043A", -- .data = NULL }, -- { }, -- }; -- -- if (soc_device_match(soc_msi_matches)) -- return true; -- -- return false; --#else -- return true; /* cannot identify SoC */ --#endif --} --#endif -- - static int __init __cold dpa_load(void) - { - int _errno; -@@ -1168,11 +1144,6 @@ static int __init __cold dpa_load(void) - dpa_max_frm = fm_get_max_frm(); - dpa_num_cpus = num_possible_cpus(); - --#ifndef CONFIG_PPC -- /* Detect if the current SoC requires the 4K alignment workaround */ -- dpaa_errata_a010022 = soc_has_errata_a010022(); --#endif -- - #ifdef CONFIG_FSL_DPAA_DBG_LOOP - memset(dpa_loop_netdevs, 0, sizeof(dpa_loop_netdevs)); - #endif ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -1,4 +1,5 @@ - /* Copyright 2008-2012 Freescale Semiconductor Inc. -+ * Copyright 2019 NXP - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: -@@ -98,15 +99,15 @@ struct dpa_buffer_layout_s { - * space to account for further alignments. - */ - #define DPA_MAX_FRM_SIZE 9600 --#ifdef CONFIG_PPC -+#ifndef FM_ERRATUM_A010022 - #define DPA_BP_RAW_SIZE \ - ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \ - sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1)) --#else /* CONFIG_PPC */ --#define DPA_BP_RAW_SIZE ((unlikely(dpaa_errata_a010022)) ? 2048 : \ -+#else /* FM_ERRATUM_A010022 */ -+#define DPA_BP_RAW_SIZE ((unlikely(fm_has_errata_a010022())) ? 2048 : \ - ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \ - sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1))) --#endif /* CONFIG_PPC */ -+#endif /* FM_ERRATUM_A010022 */ - #endif /* CONFIG_FSL_DPAA_ETH_JUMBO_FRAME */ - - /* This is what FMan is ever allowed to use. -@@ -659,8 +660,7 @@ static inline void _dpa_bp_free_pf(void - * on egress. - */ - --#ifndef CONFIG_PPC --extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */ -+#ifdef FM_ERRATUM_A010022 - #define CROSS_4K(start, size) \ - (((uintptr_t)(start) + (size)) > \ - (((uintptr_t)(start) + 0x1000) & ~0xFFF)) -@@ -668,6 +668,6 @@ extern bool dpaa_errata_a010022; /* SoC - * we reserve 256 bytes instead to guarantee 256 data alignment. - */ - #define DPAA_A010022_HEADROOM 256 --#endif /* !CONFIG_PPC */ -+#endif /* FM_ERRATUM_A010022 */ - - #endif /* __DPA_H */ ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -1,4 +1,5 @@ - /* Copyright 2012 Freescale Semiconductor Inc. -+ * Copyright 2019 NXP - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: -@@ -100,8 +101,8 @@ static int _dpa_bp_add_8_bufs(const stru - * We only need enough space to store a pointer, but allocate - * an entire cacheline for performance reasons. - */ --#ifndef CONFIG_PPC -- if (unlikely(dpaa_errata_a010022)) { -+#ifdef FM_ERRATUM_A010022 -+ if (unlikely(fm_has_errata_a010022())) { - struct page *new_page = alloc_page(GFP_ATOMIC); - if (unlikely(!new_page)) - goto netdev_alloc_failed; -@@ -764,7 +765,7 @@ int __hot skb_to_contig_fd(struct dpa_pr - } - EXPORT_SYMBOL(skb_to_contig_fd); - --#ifndef CONFIG_PPC -+#ifdef FM_ERRATUM_A010022 - /* Verify the conditions that trigger the A010022 errata: - * - 4K memory address boundary crossings when the data/SG fragments aren't - * aligned to 256 bytes -@@ -940,8 +941,8 @@ int __hot skb_to_sg_fd(struct dpa_priv_s - /* Get a page frag to store the SGTable, or a full page if the errata - * is in place and we need to avoid crossing a 4k boundary. - */ --#ifndef CONFIG_PPC -- if (unlikely(dpaa_errata_a010022)) { -+#ifdef FM_ERRATUM_A010022 -+ if (unlikely(fm_has_errata_a010022())) { - struct page *new_page = alloc_page(GFP_ATOMIC); - - if (unlikely(!new_page)) -@@ -1120,8 +1121,8 @@ int __hot dpa_tx_extended(struct sk_buff - - clear_fd(&fd); - --#ifndef CONFIG_PPC -- if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) -+#ifdef FM_ERRATUM_A010022 -+ if (unlikely(fm_has_errata_a010022()) && a010022_check_skb(skb, priv)) - skb_need_wa = true; - #endif - -@@ -1193,12 +1194,12 @@ int __hot dpa_tx_extended(struct sk_buff - * more fragments than we support. In this case, - * we have no choice but to linearize it ourselves. - */ --#ifndef CONFIG_PPC -+#ifdef FM_ERRATUM_A010022 - /* No point in linearizing the skb now if we are going - * to realign and linearize it again further down due - * to the A010022 errata - */ -- if (unlikely(dpaa_errata_a010022)) -+ if (unlikely(fm_has_errata_a010022())) - skb_need_wa = true; - else - #endif -@@ -1208,15 +1209,15 @@ int __hot dpa_tx_extended(struct sk_buff - /* Common out-of-memory error path */ - goto enomem; - --#ifndef CONFIG_PPC -+#ifdef FM_ERRATUM_A010022 - /* Verify the skb a second time if it has been updated since - * the previous check - */ -- if (unlikely(dpaa_errata_a010022) && skb_changed && -+ if (unlikely(fm_has_errata_a010022()) && skb_changed && - a010022_check_skb(skb, priv)) - skb_need_wa = true; - -- if (unlikely(dpaa_errata_a010022) && skb_need_wa) { -+ if (unlikely(fm_has_errata_a010022()) && skb_need_wa) { - nskb = a010022_realign_skb(skb, priv); - if (!nskb) - goto skb_to_fd_failed; ---- a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h -@@ -1,5 +1,6 @@ - /* - * Copyright 2012 Freescale Semiconductor Inc. -+ * Copyright 2019 NXP - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: -@@ -270,6 +271,8 @@ typedef enum - #define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */ - #define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */ - -+#define FM_ERRATUM_A010022 -+ - /***************************************************************************** - RMan INTEGRATION-SPECIFIC DEFINITIONS - ******************************************************************************/ ---- a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h -@@ -1,5 +1,6 @@ - /* - * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * Copyright 2019 NXP - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: -@@ -489,6 +490,15 @@ int fm_get_max_frm(void); - int fm_get_rx_extra_headroom(void); - - /**************************************************************************//** -+ @Function fm_has_errata_a010022 -+ -+ @Description Detect if the SoC is vulnerable to the A010022 errata -+*//***************************************************************************/ -+#ifdef FM_ERRATUM_A010022 -+bool fm_has_errata_a010022(void); -+#endif -+ -+/**************************************************************************//** - @Function fm_port_set_rate_limit - - @Description Configure Shaper parameter on FM-port device (Tx port). ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -@@ -1,5 +1,6 @@ - /* - * Copyright 2008-2012 Freescale Semiconductor Inc. -+ * Copyright 2019 NXP - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: -@@ -155,6 +156,10 @@ static int fsl_fm_pfc_quanta[] = { - - static t_LnxWrpFm lnxWrpFm; - -+#ifdef FM_ERRATUM_A010022 -+static bool fm_has_err_a010022; -+#endif -+ - int fm_get_max_frm() - { - return fsl_fm_max_frm; -@@ -167,6 +172,14 @@ int fm_get_rx_extra_headroom() - } - EXPORT_SYMBOL(fm_get_rx_extra_headroom); - -+#ifdef FM_ERRATUM_A010022 -+bool fm_has_errata_a010022(void) -+{ -+ return fm_has_err_a010022; -+} -+EXPORT_SYMBOL(fm_has_errata_a010022); -+#endif -+ - static int __init fm_set_max_frm(char *str) - { - int ret = 0; -@@ -749,6 +762,10 @@ static t_LnxWrpFmDev * ReadFmDevTreeNode - p_LnxWrpFmDev->defPcd = e_NO_PCD; - } - -+#ifdef FM_ERRATUM_A010022 -+ fm_has_err_a010022 = of_property_read_bool(fm_node, "fsl,erratum-a010022"); -+#endif -+ - of_node_put(fm_node); - - p_LnxWrpFmDev->hcCh = diff --git a/target/linux/layerscape/patches-5.4/701-net-0361-sdk_dpaa-sdk_fman-ls1034a-errata-update-number-to-A0.patch b/target/linux/layerscape/patches-5.4/701-net-0361-sdk_dpaa-sdk_fman-ls1034a-errata-update-number-to-A0.patch deleted file mode 100644 index f9b0c70586..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0361-sdk_dpaa-sdk_fman-ls1034a-errata-update-number-to-A0.patch +++ /dev/null @@ -1,259 +0,0 @@ -From 512bb2bd0555a8e78713dfdc109d87723a9da5c1 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Fri, 13 Dec 2019 14:49:16 +0200 -Subject: [PATCH] sdk_dpaa: sdk_fman: ls1034a errata: update number to A050385 - -The A050385 erratum extends the A010022 erratum by defining additional -FMan lock-up conditions and suggests new w/a restrictions. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 14 +++---- - .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 44 +++++++++++----------- - .../inc/integrations/LS1043/dpaa_integration_ext.h | 2 +- - .../sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h | 8 ++-- - .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 16 ++++---- - 5 files changed, 42 insertions(+), 42 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h -@@ -99,15 +99,15 @@ struct dpa_buffer_layout_s { - * space to account for further alignments. - */ - #define DPA_MAX_FRM_SIZE 9600 --#ifndef FM_ERRATUM_A010022 -+#ifndef FM_ERRATUM_A050385 - #define DPA_BP_RAW_SIZE \ - ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \ - sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1)) --#else /* FM_ERRATUM_A010022 */ --#define DPA_BP_RAW_SIZE ((unlikely(fm_has_errata_a010022())) ? 2048 : \ -+#else /* FM_ERRATUM_A050385 */ -+#define DPA_BP_RAW_SIZE ((unlikely(fm_has_errata_a050385())) ? 2048 : \ - ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \ - sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1))) --#endif /* FM_ERRATUM_A010022 */ -+#endif /* FM_ERRATUM_A050385 */ - #endif /* CONFIG_FSL_DPAA_ETH_JUMBO_FRAME */ - - /* This is what FMan is ever allowed to use. -@@ -660,14 +660,14 @@ static inline void _dpa_bp_free_pf(void - * on egress. - */ - --#ifdef FM_ERRATUM_A010022 -+#ifdef FM_ERRATUM_A050385 - #define CROSS_4K(start, size) \ - (((uintptr_t)(start) + (size)) > \ - (((uintptr_t)(start) + 0x1000) & ~0xFFF)) - /* The headroom needs to accommodate our private data (64 bytes) but - * we reserve 256 bytes instead to guarantee 256 data alignment. - */ --#define DPAA_A010022_HEADROOM 256 --#endif /* FM_ERRATUM_A010022 */ -+#define DPAA_A050385_HEADROOM 256 -+#endif /* FM_ERRATUM_A050385 */ - - #endif /* __DPA_H */ ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c -@@ -101,8 +101,8 @@ static int _dpa_bp_add_8_bufs(const stru - * We only need enough space to store a pointer, but allocate - * an entire cacheline for performance reasons. - */ --#ifdef FM_ERRATUM_A010022 -- if (unlikely(fm_has_errata_a010022())) { -+#ifdef FM_ERRATUM_A050385 -+ if (unlikely(fm_has_errata_a050385())) { - struct page *new_page = alloc_page(GFP_ATOMIC); - if (unlikely(!new_page)) - goto netdev_alloc_failed; -@@ -765,15 +765,15 @@ int __hot skb_to_contig_fd(struct dpa_pr - } - EXPORT_SYMBOL(skb_to_contig_fd); - --#ifdef FM_ERRATUM_A010022 --/* Verify the conditions that trigger the A010022 errata: -+#ifdef FM_ERRATUM_A050385 -+/* Verify the conditions that trigger the A050385 errata: - * - 4K memory address boundary crossings when the data/SG fragments aren't - * aligned to 256 bytes - * - data and SG fragments that aren't aligned to 16 bytes - * - SG fragments that aren't mod 16 bytes in size (except for the last - * fragment) - */ --static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv) -+static bool a050385_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv) - { - skb_frag_t *frag; - int i, nr_frags; -@@ -840,7 +840,7 @@ static bool a010022_check_skb(struct sk_ - * page. Build a new skb around the new buffer and release the old one. - * A performance drop should be expected. - */ --static struct sk_buff *a010022_realign_skb(struct sk_buff *skb, -+static struct sk_buff *a050385_realign_skb(struct sk_buff *skb, - struct dpa_priv_s *priv) - { - int trans_offset = skb_transport_offset(skb); -@@ -850,7 +850,7 @@ static struct sk_buff *a010022_realign_s - struct page *npage; - void *npage_addr; - -- headroom = DPAA_A010022_HEADROOM; -+ headroom = DPAA_A050385_HEADROOM; - - /* For the new skb we only need the old one's data (both non-paged and - * paged). We can skip the old tailroom. -@@ -941,8 +941,8 @@ int __hot skb_to_sg_fd(struct dpa_priv_s - /* Get a page frag to store the SGTable, or a full page if the errata - * is in place and we need to avoid crossing a 4k boundary. - */ --#ifdef FM_ERRATUM_A010022 -- if (unlikely(fm_has_errata_a010022())) { -+#ifdef FM_ERRATUM_A050385 -+ if (unlikely(fm_has_errata_a050385())) { - struct page *new_page = alloc_page(GFP_ATOMIC); - - if (unlikely(!new_page)) -@@ -1099,9 +1099,9 @@ int __hot dpa_tx_extended(struct sk_buff - int *countptr, offset = 0; - struct sk_buff *nskb; - -- /* Flags to help optimize the A010022 errata restriction checks. -+ /* Flags to help optimize the A050385 errata restriction checks. - * -- * First flag marks if the skb changed between the first A010022 check -+ * First flag marks if the skb changed between the first A050385 check - * and the moment it's converted to an FD. - * - * The second flag marks if the skb needs to be realigned in order to -@@ -1121,8 +1121,8 @@ int __hot dpa_tx_extended(struct sk_buff - - clear_fd(&fd); - --#ifdef FM_ERRATUM_A010022 -- if (unlikely(fm_has_errata_a010022()) && a010022_check_skb(skb, priv)) -+#ifdef FM_ERRATUM_A050385 -+ if (unlikely(fm_has_errata_a050385()) && a050385_check_skb(skb, priv)) - skb_need_wa = true; - #endif - -@@ -1176,7 +1176,7 @@ int __hot dpa_tx_extended(struct sk_buff - /* We're going to store the skb backpointer at the beginning - * of the data buffer, so we need a privately owned skb - * -- * Under the A010022 errata, we are going to have a privately -+ * Under the A050385 errata, we are going to have a privately - * owned skb after realigning the current one, so no point in - * copying it here in that case. - */ -@@ -1194,12 +1194,12 @@ int __hot dpa_tx_extended(struct sk_buff - * more fragments than we support. In this case, - * we have no choice but to linearize it ourselves. - */ --#ifdef FM_ERRATUM_A010022 -+#ifdef FM_ERRATUM_A050385 - /* No point in linearizing the skb now if we are going - * to realign and linearize it again further down due -- * to the A010022 errata -+ * to the A050385 errata - */ -- if (unlikely(fm_has_errata_a010022())) -+ if (unlikely(fm_has_errata_a050385())) - skb_need_wa = true; - else - #endif -@@ -1209,16 +1209,16 @@ int __hot dpa_tx_extended(struct sk_buff - /* Common out-of-memory error path */ - goto enomem; - --#ifdef FM_ERRATUM_A010022 -+#ifdef FM_ERRATUM_A050385 - /* Verify the skb a second time if it has been updated since - * the previous check - */ -- if (unlikely(fm_has_errata_a010022()) && skb_changed && -- a010022_check_skb(skb, priv)) -+ if (unlikely(fm_has_errata_a050385()) && skb_changed && -+ a050385_check_skb(skb, priv)) - skb_need_wa = true; - -- if (unlikely(fm_has_errata_a010022()) && skb_need_wa) { -- nskb = a010022_realign_skb(skb, priv); -+ if (unlikely(fm_has_errata_a050385()) && skb_need_wa) { -+ nskb = a050385_realign_skb(skb, priv); - if (!nskb) - goto skb_to_fd_failed; - dev_kfree_skb(skb); ---- a/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h -+++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h -@@ -271,7 +271,7 @@ typedef enum - #define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */ - #define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */ - --#define FM_ERRATUM_A010022 -+#define FM_ERRATUM_A050385 - - /***************************************************************************** - RMan INTEGRATION-SPECIFIC DEFINITIONS ---- a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h -@@ -490,12 +490,12 @@ int fm_get_max_frm(void); - int fm_get_rx_extra_headroom(void); - - /**************************************************************************//** -- @Function fm_has_errata_a010022 -+ @Function fm_has_errata_a050385 - -- @Description Detect if the SoC is vulnerable to the A010022 errata -+ @Description Detect if the SoC is vulnerable to the A050385 errata - *//***************************************************************************/ --#ifdef FM_ERRATUM_A010022 --bool fm_has_errata_a010022(void); -+#ifdef FM_ERRATUM_A050385 -+bool fm_has_errata_a050385(void); - #endif - - /**************************************************************************//** ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -@@ -156,8 +156,8 @@ static int fsl_fm_pfc_quanta[] = { - - static t_LnxWrpFm lnxWrpFm; - --#ifdef FM_ERRATUM_A010022 --static bool fm_has_err_a010022; -+#ifdef FM_ERRATUM_A050385 -+static bool fm_has_err_a050385; - #endif - - int fm_get_max_frm() -@@ -172,12 +172,12 @@ int fm_get_rx_extra_headroom() - } - EXPORT_SYMBOL(fm_get_rx_extra_headroom); - --#ifdef FM_ERRATUM_A010022 --bool fm_has_errata_a010022(void) -+#ifdef FM_ERRATUM_A050385 -+bool fm_has_errata_a050385(void) - { -- return fm_has_err_a010022; -+ return fm_has_err_a050385; - } --EXPORT_SYMBOL(fm_has_errata_a010022); -+EXPORT_SYMBOL(fm_has_errata_a050385); - #endif - - static int __init fm_set_max_frm(char *str) -@@ -762,8 +762,8 @@ static t_LnxWrpFmDev * ReadFmDevTreeNode - p_LnxWrpFmDev->defPcd = e_NO_PCD; - } - --#ifdef FM_ERRATUM_A010022 -- fm_has_err_a010022 = of_property_read_bool(fm_node, "fsl,erratum-a010022"); -+#ifdef FM_ERRATUM_A050385 -+ fm_has_err_a050385 = of_property_read_bool(fm_node, "fsl,erratum-a050385"); - #endif - - of_node_put(fm_node); diff --git a/target/linux/layerscape/patches-5.4/701-net-0362-sdk_dpaa-ceetm-remove-references-to-qdisc_lookup.patch b/target/linux/layerscape/patches-5.4/701-net-0362-sdk_dpaa-ceetm-remove-references-to-qdisc_lookup.patch deleted file mode 100644 index 652ab89dd8..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0362-sdk_dpaa-ceetm-remove-references-to-qdisc_lookup.patch +++ /dev/null @@ -1,111 +0,0 @@ -From d6fc3dc5591ca4f0b2a5a77b210c622d8b709362 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Fri, 20 Dec 2019 15:56:53 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: remove references to qdisc_lookup - -In order to enable building the driver as a module, remove the -references to the undefined qdisc_lookup symbol. - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 49 ++++++++++++++++------ - 1 file changed, 36 insertions(+), 13 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -812,8 +812,8 @@ static int ceetm_init_prio(struct Qdisc - int err; - unsigned int i; - struct ceetm_class *parent_cl, *child_cl; -- struct Qdisc *parent_qdisc; - struct net_device *dev = qdisc_dev(sch); -+ struct Qdisc *root_qdisc = dev->qdisc; - - pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); - -@@ -822,14 +822,18 @@ static int ceetm_init_prio(struct Qdisc - return -EINVAL; - } - -- parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent)); -- if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) { -+ if (TC_H_MAJ(sch->parent) != TC_H_MAJ(root_qdisc->handle)) { -+ pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n"); -+ return -EINVAL; -+ } -+ -+ if (strcmp(root_qdisc->ops->id, ceetm_qdisc_ops.id)) { - pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n"); - return -EINVAL; - } - - /* Obtain the parent root ceetm_class */ -- parent_cl = ceetm_find(sch->parent, parent_qdisc); -+ parent_cl = ceetm_find(sch->parent, root_qdisc); - - if (!parent_cl || parent_cl->type != CEETM_ROOT) { - pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n"); -@@ -902,9 +906,9 @@ static int ceetm_init_wbfs(struct Qdisc - { - int err, group_b, small_group; - unsigned int i, id, prio_a, prio_b; -- struct ceetm_class *parent_cl, *child_cl, *root_cl; -- struct Qdisc *parent_qdisc; -- struct ceetm_qdisc *parent_priv; -+ struct ceetm_class *parent_cl, *child_cl, *tmp_cl, *root_cl = NULL; -+ struct Qdisc *root_qdisc, *parent_qdisc = NULL; -+ struct ceetm_qdisc *root_priv; - struct net_device *dev = qdisc_dev(sch); - - pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); -@@ -915,16 +919,37 @@ static int ceetm_init_wbfs(struct Qdisc - return -EINVAL; - } - -- /* Obtain the parent prio ceetm qdisc */ -- parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent)); -- if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) { -+ root_qdisc = dev->qdisc; -+ -+ if (strcmp(root_qdisc->ops->id, ceetm_qdisc_ops.id)) { - pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n"); - return -EINVAL; - } - -+ root_priv = qdisc_priv(root_qdisc); -+ -+ /* Obtain the root ceetm class and the parent prio ceetm qdisc */ -+ for (i = 0; i < root_priv->clhash.hashsize; i++) { -+ hlist_for_each_entry(tmp_cl, &root_priv->clhash.hash[i], -+ common.hnode) { -+ if (tmp_cl->root.child && -+ (TC_H_MAJ(tmp_cl->root.child->handle) == -+ TC_H_MAJ(sch->parent))) { -+ parent_qdisc = tmp_cl->root.child; -+ root_cl = tmp_cl; -+ break; -+ } -+ } -+ } -+ -+ if (!parent_qdisc || -+ strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) { -+ pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n"); -+ return -EINVAL; -+ } -+ - /* Obtain the parent prio ceetm class */ - parent_cl = ceetm_find(sch->parent, parent_qdisc); -- parent_priv = qdisc_priv(parent_qdisc); - - if (!parent_cl || parent_cl->type != CEETM_PRIO) { - pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n"); -@@ -948,8 +973,6 @@ static int ceetm_init_wbfs(struct Qdisc - return -EINVAL; - } - -- /* Obtain the parent root ceetm class */ -- root_cl = parent_priv->prio.parent; - if ((root_cl->root.wbfs_grp_a && root_cl->root.wbfs_grp_b) || - root_cl->root.wbfs_grp_large) { - pr_err("CEETM: no more wbfs classes are available\n"); diff --git a/target/linux/layerscape/patches-5.4/701-net-0363-sdk_dpaa-ceetm-export-the-ceetm_tx-symbol.patch b/target/linux/layerscape/patches-5.4/701-net-0363-sdk_dpaa-ceetm-export-the-ceetm_tx-symbol.patch deleted file mode 100644 index 0d82df49fa..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0363-sdk_dpaa-ceetm-export-the-ceetm_tx-symbol.patch +++ /dev/null @@ -1,23 +0,0 @@ -From c741a131f2fb267b5b3bb333aca2453a07536535 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Fri, 20 Dec 2019 16:00:07 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: export the ceetm_tx symbol - -In order to enable building the driver as a module, export the ceetm_tx -symbol for the DPAA Ethernet driver to use. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -2077,6 +2077,7 @@ drop: - dev_kfree_skb_any(skb); - return NET_XMIT_SUCCESS; - } -+EXPORT_SYMBOL(ceetm_tx); - - static int __init ceetm_register(void) - { diff --git a/target/linux/layerscape/patches-5.4/701-net-0364-sdk_dpaa-ceetm-enable-building-as-a-module.patch b/target/linux/layerscape/patches-5.4/701-net-0364-sdk_dpaa-ceetm-enable-building-as-a-module.patch deleted file mode 100644 index a1bc652be9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0364-sdk_dpaa-ceetm-enable-building-as-a-module.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 047bb6ca46d7cd8b2400bfbf062469ff84cec3d3 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Fri, 20 Dec 2019 16:01:23 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: enable building as a module - -Enable building the driver as a module by adding the required module -macros and creating the fsl_ceetm object file. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/Makefile | 4 +++- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 2 ++ - 2 files changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/Makefile -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile -@@ -17,9 +17,11 @@ endif - ifeq ($(CONFIG_FSL_DPAA_1588),y) - fsl_dpa-objs += dpaa_1588.o - endif -+ - ifeq ($(CONFIG_FSL_DPAA_CEETM),y) - ccflags-y += -I$(srctree)/drivers/net/ethernet/freescale/sdk_fman/src/wrapper --fsl_dpa-objs += dpaa_eth_ceetm.o -+obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_ceetm.o -+fsl_ceetm-objs += dpaa_eth_ceetm.o - endif - - fsl_mac-objs += mac.o mac-api.o ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -33,6 +33,8 @@ - #include "dpaa_eth_ceetm.h" - - #define DPA_CEETM_DESCRIPTION "FSL DPAA CEETM qdisc" -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION(DPA_CEETM_DESCRIPTION); - - const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1] = { - [TCA_CEETM_COPT] = { .len = sizeof(struct tc_ceetm_copt) }, diff --git a/target/linux/layerscape/patches-5.4/701-net-0365-sdk_dpaa-ceetm-coding-style-cleanup.patch b/target/linux/layerscape/patches-5.4/701-net-0365-sdk_dpaa-ceetm-coding-style-cleanup.patch deleted file mode 100644 index 13ae5e5321..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0365-sdk_dpaa-ceetm-coding-style-cleanup.patch +++ /dev/null @@ -1,431 +0,0 @@ -From fec484580477d93cd69e5355be68e6f5bf1a1e54 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Mon, 9 Dec 2019 18:20:05 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: coding style cleanup - -Fix checkpatch warnings and use reverse Christmas tree variable ordering -throughout the driver. - -Signed-off-by: Camelia Groza ---- - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 145 +++++++++++---------- - 1 file changed, 76 insertions(+), 69 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -1,4 +1,5 @@ - /* Copyright 2008-2016 Freescale Semiconductor Inc. -+ * Copyright 2019 NXP - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: -@@ -47,10 +48,10 @@ struct Qdisc_ops ceetm_qdisc_ops; - static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id, - unsigned int *sp_id) - { -- uint32_t channel; -- t_LnxWrpFmPortDev *port_dev; - struct dpa_priv_s *dpa_priv = netdev_priv(dev); - struct mac_device *mac_dev = dpa_priv->mac_dev; -+ t_LnxWrpFmPortDev *port_dev; -+ uint32_t channel; - - port_dev = (t_LnxWrpFmPortDev *)mac_dev->port_dev[TX]; - channel = port_dev->txCh; -@@ -75,7 +76,7 @@ static void dpaa_drain_fqs(struct net_de - struct qman_fq *fq; - int ret, i; - -- for (i = 0; i < DPAA_ETH_TX_QUEUES; i ++) { -+ for (i = 0; i < DPAA_ETH_TX_QUEUES; i++) { - fq = priv->egress_fqs[i]; - while (true) { - ret = qman_query_fq_np(fq, &np); -@@ -96,7 +97,7 @@ static void dpaa_drain_fqs(struct net_de - static void ceetm_drain_class(struct ceetm_class *cl) - { - struct qm_mcr_ceetm_cq_query cq_query; -- struct qm_ceetm_cq *cq; -+ struct qm_ceetm_cq *cq = NULL; - unsigned int idx; - int ret; - -@@ -108,10 +109,10 @@ static void ceetm_drain_class(struct cee - /* The ROOT classes aren't directly linked to CEETM CQs */ - return; - case CEETM_PRIO: -- cq = (struct qm_ceetm_cq*)cl->prio.cq; -+ cq = (struct qm_ceetm_cq *)cl->prio.cq; - break; - case CEETM_WBFS: -- cq = (struct qm_ceetm_cq*)cl->wbfs.cq; -+ cq = (struct qm_ceetm_cq *)cl->wbfs.cq; - break; - } - -@@ -190,10 +191,14 @@ static void ceetm_ern(struct qman_portal - /* Congestion State Change Notification callback */ - static void ceetm_cscn(struct qm_ceetm_ccg *ccg, void *cb_ctx, int congested) - { -- struct ceetm_fq *ceetm_fq = (struct ceetm_fq *)cb_ctx; -- struct dpa_priv_s *dpa_priv = netdev_priv(ceetm_fq->net_dev); -- struct ceetm_class *cls = ceetm_fq->ceetm_cls; - struct ceetm_class_stats *cstats = NULL; -+ struct dpa_priv_s *dpa_priv; -+ struct ceetm_fq *ceetm_fq; -+ struct ceetm_class *cls; -+ -+ ceetm_fq = (struct ceetm_fq *)cb_ctx; -+ dpa_priv = netdev_priv(ceetm_fq->net_dev); -+ cls = ceetm_fq->ceetm_cls; - - switch (cls->type) { - case CEETM_PRIO: -@@ -236,10 +241,10 @@ static int ceetm_config_ccg(struct qm_ce - struct qm_ceetm_channel *channel, unsigned int id, - struct ceetm_fq *fq, struct dpa_priv_s *dpa_priv) - { -- int err; -- u32 cs_th; -- u16 ccg_mask; - struct qm_ceetm_ccg_params ccg_params; -+ u16 ccg_mask; -+ u32 cs_th; -+ int err; - - err = qman_ceetm_ccg_claim(ccg, channel, id, ceetm_cscn, fq); - if (err) -@@ -284,9 +289,9 @@ static int ceetm_config_ccg(struct qm_ce - static int ceetm_config_lfq(struct qm_ceetm_cq *cq, struct ceetm_fq *fq, - struct qm_ceetm_lfq **lfq) - { -- int err; - u64 context_a; - u32 context_b; -+ int err; - - err = qman_ceetm_lfq_claim(lfq, cq); - if (err) -@@ -316,8 +321,8 @@ static int ceetm_config_prio_cls(struct - struct net_device *dev, - unsigned int id) - { -- int err; - struct dpa_priv_s *dpa_priv = netdev_priv(dev); -+ int err; - - err = ceetm_alloc_fq(&cls->prio.fq, dev, cls); - if (err) -@@ -357,8 +362,8 @@ static int ceetm_config_wbfs_cls(struct - struct net_device *dev, - unsigned int id, int type) - { -- int err; - struct dpa_priv_s *dpa_priv = netdev_priv(dev); -+ int err; - - err = ceetm_alloc_fq(&cls->wbfs.fq, dev, cls); - if (err) -@@ -517,11 +522,11 @@ static void ceetm_cls_destroy(struct Qdi - /* Destroy a ceetm qdisc */ - static void ceetm_destroy(struct Qdisc *sch) - { -- unsigned int ntx, i; -- struct hlist_node *next; -- struct ceetm_class *cl; - struct ceetm_qdisc *priv = qdisc_priv(sch); - struct net_device *dev = qdisc_dev(sch); -+ struct hlist_node *next; -+ struct ceetm_class *cl; -+ unsigned int ntx, i; - - pr_debug(KBUILD_BASENAME " : %s : destroy qdisc %X\n", - __func__, sch->handle); -@@ -592,13 +597,13 @@ static void ceetm_destroy(struct Qdisc * - - static int ceetm_dump(struct Qdisc *sch, struct sk_buff *skb) - { -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct net_device *dev = qdisc_dev(sch); -+ struct ceetm_qdisc_stats *qstats; -+ struct tc_ceetm_qopt qopt; - struct Qdisc *qdisc; - unsigned int ntx, i; - struct nlattr *nest; -- struct tc_ceetm_qopt qopt; -- struct ceetm_qdisc_stats *qstats; -- struct net_device *dev = qdisc_dev(sch); -- struct ceetm_qdisc *priv = qdisc_priv(sch); - - pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); - -@@ -673,17 +678,20 @@ static int ceetm_init_root(struct Qdisc - struct tc_ceetm_qopt *qopt, - struct netlink_ext_ack *extack) - { -+ struct net_device *dev = qdisc_dev(sch); -+ unsigned int i, sp_id, parent_id; - struct netdev_queue *dev_queue; -- struct Qdisc *qdisc; -+ struct dpa_priv_s *dpa_priv; -+ struct mac_device *mac_dev; - enum qm_dc_portal dcp_id; -- unsigned int i, sp_id, parent_id; -+ struct qm_ceetm_lni *lni; -+ struct qm_ceetm_sp *sp; -+ struct Qdisc *qdisc; - int err; - u64 bps; -- struct qm_ceetm_sp *sp; -- struct qm_ceetm_lni *lni; -- struct net_device *dev = qdisc_dev(sch); -- struct dpa_priv_s *dpa_priv = netdev_priv(dev); -- struct mac_device *mac_dev = dpa_priv->mac_dev; -+ -+ dpa_priv = netdev_priv(dev); -+ mac_dev = dpa_priv->mac_dev; - - pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); - -@@ -711,9 +719,8 @@ static int ceetm_init_root(struct Qdisc - priv->root.qdiscs = kcalloc(dev->num_tx_queues, - sizeof(priv->root.qdiscs[0]), - GFP_KERNEL); -- if (!priv->root.qdiscs) { -+ if (!priv->root.qdiscs) - return -ENOMEM; -- } - - for (i = 0; i < dev->num_tx_queues; i++) { - dev_queue = netdev_get_tx_queue(dev, i); -@@ -811,11 +818,11 @@ static int ceetm_init_root(struct Qdisc - static int ceetm_init_prio(struct Qdisc *sch, struct ceetm_qdisc *priv, - struct tc_ceetm_qopt *qopt) - { -- int err; -- unsigned int i; - struct ceetm_class *parent_cl, *child_cl; - struct net_device *dev = qdisc_dev(sch); - struct Qdisc *root_qdisc = dev->qdisc; -+ unsigned int i; -+ int err; - - pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); - -@@ -852,11 +859,8 @@ static int ceetm_init_prio(struct Qdisc - /* Create and configure qcount child classes */ - for (i = 0; i < priv->prio.qcount; i++) { - child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL); -- if (!child_cl) { -- pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n", -- __func__); -+ if (!child_cl) - return -ENOMEM; -- } - - child_cl->prio.cstats = alloc_percpu(struct ceetm_class_stats); - if (!child_cl->prio.cstats) { -@@ -906,12 +910,12 @@ err_init_prio_cls: - static int ceetm_init_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv, - struct tc_ceetm_qopt *qopt) - { -- int err, group_b, small_group; -- unsigned int i, id, prio_a, prio_b; - struct ceetm_class *parent_cl, *child_cl, *tmp_cl, *root_cl = NULL; - struct Qdisc *root_qdisc, *parent_qdisc = NULL; -- struct ceetm_qdisc *root_priv; - struct net_device *dev = qdisc_dev(sch); -+ unsigned int i, id, prio_a, prio_b; -+ int err, group_b, small_group; -+ struct ceetm_qdisc *root_priv; - - pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); - -@@ -1070,11 +1074,8 @@ static int ceetm_init_wbfs(struct Qdisc - /* Create qcount child classes */ - for (i = 0; i < priv->wbfs.qcount; i++) { - child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL); -- if (!child_cl) { -- pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n", -- __func__); -+ if (!child_cl) - return -ENOMEM; -- } - - child_cl->wbfs.cstats = alloc_percpu(struct ceetm_class_stats); - if (!child_cl->wbfs.cstats) { -@@ -1138,11 +1139,11 @@ err_init_wbfs_cls: - static int ceetm_init(struct Qdisc *sch, struct nlattr *opt, - struct netlink_ext_ack *extack) - { -- struct tc_ceetm_qopt *qopt; -- struct nlattr *tb[TCA_CEETM_QOPS + 1]; -- int ret; - struct ceetm_qdisc *priv = qdisc_priv(sch); - struct net_device *dev = qdisc_dev(sch); -+ struct nlattr *tb[TCA_CEETM_QOPS + 1]; -+ struct tc_ceetm_qopt *qopt; -+ int ret; - - pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); - -@@ -1158,7 +1159,8 @@ static int ceetm_init(struct Qdisc *sch, - if (ret) - return ret; - -- ret = nla_parse_nested_deprecated(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL); -+ ret = nla_parse_nested_deprecated(tb, TCA_CEETM_QOPS, opt, -+ ceetm_policy, NULL); - if (ret < 0) { - pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); - return ret; -@@ -1265,8 +1267,8 @@ change_err: - static int ceetm_change_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv, - struct tc_ceetm_qopt *qopt) - { -- int err; - bool group_b; -+ int err; - - if (qopt->qcount) { - pr_err("CEETM: the qcount can not be modified\n"); -@@ -1324,15 +1326,16 @@ change_err: - static int ceetm_change(struct Qdisc *sch, struct nlattr *opt, - struct netlink_ext_ack *extack) - { -- struct tc_ceetm_qopt *qopt; -- struct nlattr *tb[TCA_CEETM_QOPS + 1]; -- int ret; - struct ceetm_qdisc *priv = qdisc_priv(sch); - struct net_device *dev = qdisc_dev(sch); -+ struct nlattr *tb[TCA_CEETM_QOPS + 1]; -+ struct tc_ceetm_qopt *qopt; -+ int ret; - - pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle); - -- ret = nla_parse_nested_deprecated(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL); -+ ret = nla_parse_nested_deprecated(tb, TCA_CEETM_QOPS, opt, -+ ceetm_policy, NULL); - if (ret < 0) { - pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); - return ret; -@@ -1381,8 +1384,8 @@ static int ceetm_change(struct Qdisc *sc - */ - static void ceetm_attach(struct Qdisc *sch) - { -- struct net_device *dev = qdisc_dev(sch); - struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct net_device *dev = qdisc_dev(sch); - struct Qdisc *qdisc, *old_qdisc; - unsigned int i; - -@@ -1461,8 +1464,8 @@ static int ceetm_cls_change_prio(struct - } - - if (cl->prio.cr != (bool)copt->cr) { -- err = qman_ceetm_channel_set_cq_cr_eligibility( -- cl->prio.cq->parent, -+ err = qman_ceetm_channel_set_cq_cr_eligibility -+ (cl->prio.cq->parent, - cl->prio.cq->idx, - copt->cr); - if (err) -@@ -1471,8 +1474,8 @@ static int ceetm_cls_change_prio(struct - } - - if (cl->prio.er != (bool)copt->er) { -- err = qman_ceetm_channel_set_cq_er_eligibility( -- cl->prio.cq->parent, -+ err = qman_ceetm_channel_set_cq_er_eligibility -+ (cl->prio.cq->parent, - cl->prio.cq->idx, - copt->er); - if (err) -@@ -1517,15 +1520,15 @@ static int ceetm_cls_change(struct Qdisc - struct nlattr **tca, unsigned long *arg, - struct netlink_ext_ack *extack) - { -- int err; -- u64 bps; -- struct ceetm_qdisc *priv; - struct ceetm_class *cl = (struct ceetm_class *)*arg; -+ struct net_device *dev = qdisc_dev(sch); - struct nlattr *opt = tca[TCA_OPTIONS]; - struct nlattr *tb[__TCA_CEETM_MAX]; -- struct tc_ceetm_copt *copt; - struct qm_ceetm_channel *channel; -- struct net_device *dev = qdisc_dev(sch); -+ struct tc_ceetm_copt *copt; -+ struct ceetm_qdisc *priv; -+ int err; -+ u64 bps; - - pr_debug(KBUILD_BASENAME " : %s : classid %X under qdisc %X\n", - __func__, classid, sch->handle); -@@ -1552,7 +1555,8 @@ static int ceetm_cls_change(struct Qdisc - return -EINVAL; - } - -- err = nla_parse_nested_deprecated(tb, TCA_CEETM_COPT, opt, ceetm_policy, NULL); -+ err = nla_parse_nested_deprecated(tb, TCA_CEETM_COPT, opt, -+ ceetm_policy, NULL); - if (err < 0) { - pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__); - return -EINVAL; -@@ -1714,8 +1718,8 @@ static int ceetm_cls_dump(struct Qdisc * - struct sk_buff *skb, struct tcmsg *tcm) - { - struct ceetm_class *cl = (struct ceetm_class *)arg; -- struct nlattr *nest; - struct tc_ceetm_copt copt; -+ struct nlattr *nest; - - pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", - __func__, cl->common.classid, sch->handle); -@@ -1770,8 +1774,8 @@ nla_put_failure: - - static int ceetm_cls_delete(struct Qdisc *sch, unsigned long arg) - { -- struct ceetm_qdisc *priv = qdisc_priv(sch); - struct ceetm_class *cl = (struct ceetm_class *)arg; -+ struct ceetm_qdisc *priv = qdisc_priv(sch); - - pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", - __func__, cl->common.classid, sch->handle); -@@ -1818,12 +1822,12 @@ static int ceetm_cls_graft(struct Qdisc - static int ceetm_cls_dump_stats(struct Qdisc *sch, unsigned long arg, - struct gnet_dump *d) - { -- unsigned int i; - struct ceetm_class *cl = (struct ceetm_class *)arg; - struct gnet_stats_basic_packed tmp_bstats; - struct ceetm_class_stats *cstats = NULL; - struct qm_ceetm_cq *cq = NULL; - struct tc_ceetm_xstats xstats; -+ unsigned int i; - - memset(&xstats, 0, sizeof(xstats)); - memset(&tmp_bstats, 0, sizeof(tmp_bstats)); -@@ -1872,9 +1876,11 @@ static int ceetm_cls_dump_stats(struct Q - static struct tcf_block *ceetm_tcf_block(struct Qdisc *sch, unsigned long arg, - struct netlink_ext_ack *extack) - { -- struct ceetm_qdisc *priv = qdisc_priv(sch); - struct ceetm_class *cl = (struct ceetm_class *)arg; -- struct tcf_block *block = cl ? cl->block : priv->block; -+ struct ceetm_qdisc *priv = qdisc_priv(sch); -+ struct tcf_block *block; -+ -+ block = cl ? cl->block : priv->block; - - pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__, - cl ? cl->common.classid : 0, sch->handle); -@@ -1945,6 +1951,7 @@ static struct ceetm_class *ceetm_classif - case TC_ACT_STOLEN: - case TC_ACT_TRAP: - *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; -+ /* fall through */ - case TC_ACT_SHOT: - /* No valid class found due to action */ - *act_drop = true; diff --git a/target/linux/layerscape/patches-5.4/701-net-0366-LF-697-net-ethernet-freescale-sdk_fman-fix-the-build.patch b/target/linux/layerscape/patches-5.4/701-net-0366-LF-697-net-ethernet-freescale-sdk_fman-fix-the-build.patch deleted file mode 100644 index 9c38b485f5..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0366-LF-697-net-ethernet-freescale-sdk_fman-fix-the-build.patch +++ /dev/null @@ -1,280 +0,0 @@ -From 43be5f0f6c36e23d6f51c1f1f55ebcec920cc453 Mon Sep 17 00:00:00 2001 -From: Jason Liu -Date: Thu, 2 Jan 2020 12:46:37 +0800 -Subject: [PATCH] LF-697 net: ethernet: freescale: sdk_fman: fix the build - warnings -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The patch fixes the build warnings by adding the comments 'fall through' to avoid the build warnings -The patch also initializes the value pgid_val to avoid the warning: ‘pgid_val’ may be used uninitialized -The patch should not and will not have any function impact. - -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c: In function ‘ValidateNextEngineParams’: -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c:1681:51: warning: this statement may fall through [-Wimplicit-fallthrough=] -In file included from drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c:40: -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c: In function ‘GetGenHdrCode’: -drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h:446:12: warning: this statement may fall through [-Wimplicit-fallthrough=] -In file included from drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c:40: -drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h:446:12: warning: this statement may fall through [-Wimplicit-fallthrough=] -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c:255:13: note: here - 255 | case (HEADER_TYPE_ETH): - | ^~~~ -In file included from drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c:40: -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c:278:13: note: here - 278 | case (HEADER_TYPE_MINENCAP): - | ^~~~ -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c: In function ‘BuildHmct’: -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c:673:32: warning: this statement may fall through [-Wimplicit-fallthrough=] - 673 | tmpReg = HMCD_INSRT_UDP_LITE; -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c:674:21: note: here - 674 | case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP): - | ^~~~ -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c: In function ‘FM_PORT_Config’: -arch/arm64/include/asm/io.h:36:22: warning: this statement may fall through [-Wimplicit-fallthrough=] - 36 | #define __raw_writel __raw_writel -drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h:99:25: note: in expansion of macro ‘__raw_writel’ - 99 | #define out_be32(a, v) __raw_writel(__cpu_to_be32(v), a) - | ^~~~~~~~~~~~ -drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h:121:37: note: in expansion of macro ‘out_be32’ - 121 | #define WRITE_UINT32(arg, data) out_be32(&(arg), data)//*(volatile unsigned int *)(&(arg)) = (data) - | ^~~~~~~~ -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c:2404:13: note: in expansion of macro ‘WRITE_UINT32’ - 2404 | WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp, - | ^~~~~~~~~~~~ -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c:2407:9: note: here - 2407 | case (e_FM_PORT_TYPE_TX_10G): - | ^~~~ -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c:2435:60: warning: this statement may fall through [-Wimplicit-fallthrough=] - 2435 | p_FmPort->p_FmPortDriverParam->noScatherGather = -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c:2438:9: note: here - 2438 | case (e_FM_PORT_TYPE_OH_HOST_COMMAND): - | ^~~~ -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c: In function ‘FM_PORT_ModifyCounter’: -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c:4268:16: warning: this statement may fall through [-Wimplicit-fallthrough=] - 4268 | if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) - | ^ -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c:4273:9: note: here - 4273 | case (e_FM_PORT_COUNTERS_ENQ_TOTAL): - | ^~~~ -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c: In function ‘SetPcd’: -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c:1396:24: warning: this statement may fall through [-Wimplicit-fallthrough=] - 1396 | tmpReg = NIA_KG_CC_EN; -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c:1397:13: note: here - 1397 | case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): - | ^~~~ -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c: In function ‘FM_GetCounter’: -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c:4804:16: warning: this statement may fall through [-Wimplicit-fallthrough=] - 4804 | if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) || - | ^ -drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c:4810:9: note: here - 4810 | case (e_FM_COUNTERS_ENQ_TOTAL_FRAME): - | ^~~~ -drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c: In function ‘fm_get_counter’: -drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c:1803:6: warning: this statement may fall through [-Wimplicit-fallthrough=] - 1803 | if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6) - | ^ -drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c:1806:2: note: here - 1806 | case (e_FM_COUNTERS_ENQ_TOTAL_FRAME): - | ^~~~ -drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c: In function ‘compat_copy_fm_pcd_cc_next_engine’: -drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c:378:33: warning: this statement may fall through [-Wimplicit-fallthrough=] - 378 | param->manip_id = compat_pcd_id2ptr(compat_param->manip_id); - | ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c:379:13: note: here - 379 | default: - | ^~~~~~~ -drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c:405:40: warning: this statement may fall through [-Wimplicit-fallthrough=] - 405 | compat_param->manip_id = compat_pcd_ptr2id(param->manip_id); - | ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c:406:13: note: here - 406 | default: - | ^~~~~~~ -In file included from drivers/net/ethernet/mscc/ocelot.h:21, - from drivers/net/ethernet/mscc/ocelot_tsn.c:12: -drivers/net/ethernet/mscc/ocelot_tsn.c: In function ‘ocelot_seq_gen_set’: -include/soc/mscc/ocelot.h:499:48: warning: ‘pgid_val’ may be used uninitialized in this function [-Wmaybe-uninitialized] - 499 | #define ocelot_write_rix(ocelot, val, reg, ri) __ocelot_write_ix(ocelot, val, reg, reg##_RSZ * (ri)) - | ^~~~~~~~~~~~~~~~~ -drivers/net/ethernet/mscc/ocelot_tsn.c:755:5: note: ‘pgid_val’ was declared here - 755 | u8 pgid_val, fwdport; - -Signed-off-by: Jason Liu -Cc: Madalin Bucur -Reviewed-by: Fugang Duan ---- - drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c | 1 + - drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c | 4 ++++ - .../net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c | 1 + - .../net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c | 5 +++++ - drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c | 3 +++ - .../freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c | 2 ++ - .../net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c | 3 +++ - drivers/net/ethernet/mscc/ocelot_tsn.c | 2 +- - 8 files changed, 20 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c -@@ -1679,6 +1679,7 @@ t_Error ValidateNextEngineParams( - - case (e_FM_PCD_HASH): - p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC; -+ /* fall through */ - case (e_FM_PCD_CC): - if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode) - RETURN_ERROR(MAJOR, E_NULL_POINTER, ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c -@@ -198,6 +198,7 @@ static uint8_t GetGenHdrCode(e_NetHeader - { - case (HEADER_TYPE_NONE): - ASSERT_COND(FALSE); -+ /* Else fall through */ - case (HEADER_TYPE_ETH): - return KG_SCH_GEN_ETH; - case (HEADER_TYPE_LLC_SNAP): -@@ -252,6 +253,7 @@ static uint8_t GetGenHdrCode(e_NetHeader - { - case (HEADER_TYPE_NONE): - ASSERT_COND(FALSE); -+ /* Else fall through */ - case (HEADER_TYPE_ETH): - return KG_SCH_GEN_ETH_NO_V; - case (HEADER_TYPE_LLC_SNAP): -@@ -269,12 +271,14 @@ static uint8_t GetGenHdrCode(e_NetHeader - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index")); - return 0; - case (HEADER_TYPE_IPv4): -+ /* fall through */ - case (HEADER_TYPE_IPv6): - if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1)) - return KG_SCH_GEN_L3_NO_V; - if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)) - return KG_SCH_GEN_IP2_NO_V; - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index")); -+ /* fall through */ - case (HEADER_TYPE_MINENCAP): - return KG_SCH_GEN_IP2_NO_V; - case (HEADER_TYPE_USER_DEFINED_L3): ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c -@@ -671,6 +671,7 @@ static t_Error BuildHmct(t_FmPcdManip *p - break; - case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE): - tmpReg = HMCD_INSRT_UDP_LITE; -+ /* fall through */ - case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP): - tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT) - << HMCD_OC_SHIFT; ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c -@@ -1394,6 +1394,7 @@ static t_Error SetPcd(t_FmPort *p_FmPort - case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC): - case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR): - tmpReg = NIA_KG_CC_EN; -+ /* fall through */ - case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG): - case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR): - if (p_PcdParams->p_KgParams->directScheme) -@@ -2404,6 +2405,8 @@ t_Handle FM_PORT_Config(t_FmPortParams * - WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp, - tmpReg); - #endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */ -+ -+ /* fall through */ - case (e_FM_PORT_TYPE_TX_10G): - tmpReg = - GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp); -@@ -2435,6 +2438,7 @@ t_Handle FM_PORT_Config(t_FmPortParams * - p_FmPort->p_FmPortDriverParam->noScatherGather = - DEFAULT_PORT_noScatherGather; - #endif /* (DPAA_VERSION >= 11) */ -+ /* fall through */ - case (e_FM_PORT_TYPE_OH_HOST_COMMAND): - p_FmPort->p_FmPortDriverParam->deqPrefetchOption = - DEFAULT_PORT_deqPrefetchOption_HC; -@@ -4270,6 +4274,7 @@ t_Error FM_PORT_ModifyCounter(t_Handle h - RETURN_ERROR( - MINOR, E_INVALID_STATE, - ("Requested counter is not available for Rx ports")); -+ /* fall through */ - case (e_FM_PORT_COUNTERS_ENQ_TOTAL): - bmiCounter = FALSE; - break; ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c -@@ -4800,6 +4800,7 @@ uint32_t FM_GetCounter(t_Handle h_Fm, e_ - { - case (e_FM_COUNTERS_DEQ_1): - case (e_FM_COUNTERS_DEQ_2): -+ /* fall through */ - case (e_FM_COUNTERS_DEQ_3): - if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) || - (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)) -@@ -4807,12 +4808,14 @@ uint32_t FM_GetCounter(t_Handle h_Fm, e_ - REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported")); - return 0; - } -+ /* fall through */ - case (e_FM_COUNTERS_ENQ_TOTAL_FRAME): - case (e_FM_COUNTERS_DEQ_TOTAL_FRAME): - case (e_FM_COUNTERS_DEQ_0): - case (e_FM_COUNTERS_DEQ_FROM_DEFAULT): - case (e_FM_COUNTERS_DEQ_FROM_CONTEXT): - case (e_FM_COUNTERS_DEQ_FROM_FD): -+ /* fall through */ - case (e_FM_COUNTERS_DEQ_CONFIRM): - if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS)) - { ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c -@@ -376,6 +376,7 @@ static inline void compat_copy_fm_pcd_cc - case e_IOC_FM_PCD_DONE: - case e_IOC_FM_PCD_PLCR: - param->manip_id = compat_pcd_id2ptr(compat_param->manip_id); -+ /* fall through */ - default: - memcpy(¶m->params, &compat_param->params, sizeof(param->params)); - } -@@ -403,6 +404,7 @@ static inline void compat_copy_fm_pcd_cc - case e_IOC_FM_PCD_DONE: - case e_IOC_FM_PCD_PLCR: - compat_param->manip_id = compat_pcd_ptr2id(param->manip_id); -+ /* fall through */ - default: - memcpy(&compat_param->params, ¶m->params, sizeof(compat_param->params)); - } ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c -@@ -1799,16 +1799,19 @@ int fm_get_counter(void *h_fm, e_FmCount - switch (cnt_e) { - case (e_FM_COUNTERS_DEQ_1): - case (e_FM_COUNTERS_DEQ_2): -+ /* fall through */ - case (e_FM_COUNTERS_DEQ_3): - if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6) - return -EINVAL; /* counter not available */ - -+ /* Else fall through */ - case (e_FM_COUNTERS_ENQ_TOTAL_FRAME): - case (e_FM_COUNTERS_DEQ_TOTAL_FRAME): - case (e_FM_COUNTERS_DEQ_0): - case (e_FM_COUNTERS_DEQ_FROM_DEFAULT): - case (e_FM_COUNTERS_DEQ_FROM_CONTEXT): - case (e_FM_COUNTERS_DEQ_FROM_FD): -+ /* fall through */ - case (e_FM_COUNTERS_DEQ_CONFIRM): - if (!(ioread32be(&p_fm->p_FmQmiRegs->fmqm_gc) & - QMI_CFG_EN_COUNTERS)) ---- a/drivers/net/ethernet/mscc/ocelot_tsn.c -+++ b/drivers/net/ethernet/mscc/ocelot_tsn.c -@@ -752,7 +752,7 @@ static int streamid_multi_forward_set(st - u32 bucket; - u32 val; - int m, n, i; -- u8 pgid_val, fwdport; -+ u8 pgid_val = 0, fwdport; - u32 dst_idx; - - m_index = index / 4; diff --git a/target/linux/layerscape/patches-5.4/701-net-0367-net-mscc-ocelot-Workaround-to-allow-traffic-to-CPU-i.patch b/target/linux/layerscape/patches-5.4/701-net-0367-net-mscc-ocelot-Workaround-to-allow-traffic-to-CPU-i.patch deleted file mode 100644 index 8d10202ac9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0367-net-mscc-ocelot-Workaround-to-allow-traffic-to-CPU-i.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 937bf9496489cb4b491e75fe4436348bf3454dcd Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Sat, 21 Dec 2019 23:19:20 +0200 -Subject: [PATCH] net: mscc: ocelot: Workaround to allow traffic to CPU in - standalone mode - -The Ocelot switches have what is, in my opinion, a design flaw: their -DSA header is in front of the Ethernet header, which means that they -subvert the DSA master's RX filter, which for all practical purposes, -either needs to be in promiscuous mode, or the OCELOT_TAG_PREFIX_LONG -needs to be used for extraction, which makes the switch add a fake DMAC -of ff:ff:ff:ff:ff:ff so that the DSA master accepts the frame. - -The issue with this design, of course, is that the CPU will be spammed -with frames that it doesn't want to respond to, and there isn't any -hardware offload in place by default to drop them. - -What is being done in the VSC7514 Ocelot driver is a process of -selective whitelisting. The "MAC address" of each Ocelot switch net -device, with all VLANs installed on that port, is being added as a FDB -entry towards PGID_CPU. - -Some background first: Port Group IDs (PGIDs) are masks of destination -ports. The switch performs 3 lookups in the PGID table for each frame, -and forwards the frame to the ports that are present in the logical AND -of all 3 PGIDs (for the most part, see below). - -The first PGID lookup is for the destination masks and the PGID table is -indexed by the DEST_IDX field from the MAC table (FDB). -The PGID can be an unicast set: PGIDs 0-11 are the per-port PGIDs, and -by convention PGID i has only BIT(i) set, aka only this port is set in -the destination mask. -Or the PGID can be a multicast set: PGIDs 12-63 can (again, still by -convention) hold a richer destination mask comprised of multiple ports. - -[ Ignoring the second PGID lookup, for aggregation, since it doesn't - interfere. ] - -The third PGID lookup is for source masks: PGID entries 80-91 answer the -question: is port i allowed to forward traffic to port j? If yes, then -BIT(j) of PGID 80+i will be found set. - -What is interesting about the CPU port in this whole story is that, in -the way the driver sets up the PGIDs, its bit isn't set in any source -mask PGID of any other port (therefore, the third lookup would always -decide to exclude the CPU port from this list). So frames are never -_forwarded_ to the CPU. - -There is a loophole in this PGID mechanism which is described in the -VSC7514 manual: - - If an entry is found in the MAC table entry of ENTRY_TYPE 0 or 1 - and the CPU port is set in the PGID pointed to by the MAC table - entry, CPU extraction queue PGID.DST_PGID is added to the CPUQ. - -In other words, the CPU port is special, and frames are "copied" to the -CPU, disregarding the source masks (third PGID lookup), if BIT(cpu) is -found to be set in the destination masks (first PGID lookup). - -Now back to the story: what is PGID_CPU? It is a multicast set -containing only BIT(cpu). I don't know why it was chosen to be a -multicast PGID (59) and not simply the unicast one of this port, but it -doesn't matter. - -The point is that frames that match the FDB will go to PGID_CPU by -virtue of the DEST_IDX from the respective MAC table entry, and frames -that don't will go to PGID_UC or PGID_MC, by virtue of the FLD_UNICAST, -FLD_BROADCAST etc settings for flooding. And that is where the -distinction is made: flooded frames will be subject to the third PGID -lookup, while frames that are whitelisted to the PGID_CPU by the MAC -table aren't. - -So we can use this mechanism to simulate an RX filter, given that we are -subverting the DSA master's implicit one, as mentioned in the first -paragraph. But this has some limitations: - -- In Ocelot each net device has its own MAC address. When simulating - this with MAC table entries, it will practically result in having N - MAC addresses for each of the N front-panel ports (because FDB entries - are not per source port). A bit strange, I think. - -- In DSA we don't have the infrastructure in place to support this - whitelisting mechanism. Calling .port_fdb_add on the CPU port for each - slave net device dev_addr isn't, in itself, hard. The problem is with - the VLANs that this port is part of. We would need to keep a duplicate - list of the VLANs from the bridge, plus the ones added from 8021q, for - each port. And we would need reference counting on each MAC address, - such that when a front-panel port changes its MAC address and we need - to delete the old FDB entry, we don't actually delete it if the other - front-panel ports are still using it. Not to mention that this FDB - entry would have to be added on the whole net of upstream DSA switches. - -So... it's complicated. What this patch does is to simply allow frames -to be flooded to the CPU, which is anyway what the Ocelot driver is -doing after removing the bridge from the net devices, see this snippet -from ocelot_bridge_stp_state_set: - - /* Apply FWD mask. The loop is needed to add/remove the current port as - * a source for the other ports. - */ - for (p = 0; p < ocelot->num_phys_ports; p++) { - if (p == ocelot->cpu || (ocelot->bridge_fwd_mask & BIT(p))) { - (...) - } else { - /* Only the CPU port, this is compatible with link - * aggregation. - */ - ocelot_write_rix(ocelot, - BIT(ocelot->cpu), - ANA_PGID_PGID, PGID_SRC + p); - } - -Otherwise said, the ocelot driver itself is already not self-coherent, -since immediately after probe time, and immediately after removal from a -bridge, it behaves in different ways, although the front panel ports are -standalone in both cases. - -While standalone traffic _does_ work for the Felix DSA wrapper after -enslaving and removing the ports from a bridge, this patch makes -standalone traffic work at probe time too, with the caveat that even -irrelevant frames will get processed by software, making it more -susceptible to denial of service. - -Signed-off-by: Vladimir Oltean ---- - drivers/net/ethernet/mscc/ocelot.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -2291,6 +2291,18 @@ void ocelot_set_cpu_port(struct ocelot * - enum ocelot_tag_prefix injection, - enum ocelot_tag_prefix extraction) - { -+ int port; -+ -+ for (port = 0; port < ocelot->num_phys_ports; port++) { -+ /* Disable old CPU port and enable new one */ -+ ocelot_rmw_rix(ocelot, 0, BIT(ocelot->cpu), -+ ANA_PGID_PGID, PGID_SRC + port); -+ if (port == cpu) -+ continue; -+ ocelot_rmw_rix(ocelot, BIT(cpu), BIT(cpu), -+ ANA_PGID_PGID, PGID_SRC + port); -+ } -+ - /* Configure and enable the CPU port. */ - ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu); - ocelot_write_rix(ocelot, BIT(cpu), ANA_PGID_PGID, PGID_CPU); diff --git a/target/linux/layerscape/patches-5.4/701-net-0377-net-dsa-ocelot-add-NET_VENDOR_MICROSEMI-dependency.patch b/target/linux/layerscape/patches-5.4/701-net-0377-net-dsa-ocelot-add-NET_VENDOR_MICROSEMI-dependency.patch deleted file mode 100644 index 81db669882..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0377-net-dsa-ocelot-add-NET_VENDOR_MICROSEMI-dependency.patch +++ /dev/null @@ -1,41 +0,0 @@ -From ac2fb1a9879204825467eed7a138a3d77c1ecfe8 Mon Sep 17 00:00:00 2001 -From: Arnd Bergmann -Date: Mon, 16 Dec 2019 00:12:14 +0200 -Subject: [PATCH] net: dsa: ocelot: add NET_VENDOR_MICROSEMI dependency - -Selecting MSCC_OCELOT_SWITCH is not possible when NET_VENDOR_MICROSEMI -is disabled: - -WARNING: unmet direct dependencies detected for MSCC_OCELOT_SWITCH - Depends on [n]: NETDEVICES [=y] && ETHERNET [=n] && NET_VENDOR_MICROSEMI [=n] && NET_SWITCHDEV [=y] && HAS_IOMEM [=y] - Selected by [m]: - - NET_DSA_MSCC_FELIX [=m] && NETDEVICES [=y] && HAVE_NET_DSA [=y] && NET_DSA [=y] && PCI [=y] - -Add a Kconfig dependency on NET_VENDOR_MICROSEMI, which also implies -CONFIG_NETDEVICES. - -Depending on a vendor config violates menuconfig locality for the DSA -driver, but is the smallest compromise since all other solutions are -much more complicated (see [0]). - -https://www.spinics.net/lists/netdev/msg618808.html - -Fixes: 56051948773e ("net: dsa: ocelot: add driver for Felix switch family") -Signed-off-by: Arnd Bergmann -Signed-off-by: Mao Wenan -Signed-off-by: Vladimir Oltean -Signed-off-by: David S. Miller ---- - drivers/net/dsa/ocelot/Kconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/dsa/ocelot/Kconfig -+++ b/drivers/net/dsa/ocelot/Kconfig -@@ -2,6 +2,7 @@ - config NET_DSA_MSCC_FELIX - tristate "Ocelot / Felix Ethernet switch support" - depends on NET_DSA && PCI -+ depends on NET_VENDOR_MICROSEMI - select MSCC_OCELOT_SWITCH - select NET_DSA_TAG_OCELOT - help diff --git a/target/linux/layerscape/patches-5.4/701-net-0378-mii-Add-helpers-for-parsing-SGMII-auto-negotiation.patch b/target/linux/layerscape/patches-5.4/701-net-0378-mii-Add-helpers-for-parsing-SGMII-auto-negotiation.patch deleted file mode 100644 index 3aeda2a057..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0378-mii-Add-helpers-for-parsing-SGMII-auto-negotiation.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 4f3ba90c37ec5aedd2227beb013bab59035fbb57 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Mon, 30 Sep 2019 19:20:26 +0300 -Subject: [PATCH] mii: Add helpers for parsing SGMII auto-negotiation - -Typically a MAC PCS auto-configures itself after it receives the -negotiated copper-side link settings from the PHY, but some MAC devices -are more special and need manual interpretation of the SGMII AN result. - -In other cases, the PCS exposes the entire tx_config_reg base page as it -is transmitted on the wire during auto-negotiation, so it makes sense to -be able to decode the equivalent lp_advertised bit mask from the raw u16 -(of course, "lp" considering the PCS to be the local PHY). - -Therefore, add the bit definitions for the SGMII registers 4 and 5 -(local device ability, link partner ability), as well as a link_mode -conversion helper that can be used to feed the AN results into -phy_resolve_aneg_linkmode. - -Signed-off-by: Vladimir Oltean ---- - include/linux/mii.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ - include/uapi/linux/mii.h | 12 ++++++++++++ - 2 files changed, 62 insertions(+) - ---- a/include/linux/mii.h -+++ b/include/linux/mii.h -@@ -373,6 +373,56 @@ static inline u32 mii_lpa_to_ethtool_lpa - } - - /** -+ * mii_lpa_mod_linkmode_adv_sgmii -+ * @lp_advertising: pointer to destination link mode. -+ * @lpa: value of the MII_LPA register -+ * -+ * A small helper function that translates MII_LPA bits to -+ * linkmode advertisement settings for SGMII. -+ * Leaves other bits unchanged. -+ */ -+static inline void -+mii_lpa_mod_linkmode_lpa_sgmii(unsigned long *lp_advertising, u32 lpa) -+{ -+ u32 speed_duplex = lpa & LPA_SGMII_DPX_SPD_MASK; -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, lp_advertising, -+ speed_duplex == LPA_SGMII_1000HALF); -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, lp_advertising, -+ speed_duplex == LPA_SGMII_1000FULL); -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, lp_advertising, -+ speed_duplex == LPA_SGMII_100HALF); -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, lp_advertising, -+ speed_duplex == LPA_SGMII_100FULL); -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, lp_advertising, -+ speed_duplex == LPA_SGMII_10HALF); -+ -+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, lp_advertising, -+ speed_duplex == LPA_SGMII_10FULL); -+} -+ -+/** -+ * mii_lpa_to_linkmode_adv_sgmii -+ * @advertising: pointer to destination link mode. -+ * @lpa: value of the MII_LPA register -+ * -+ * A small helper function that translates MII_ADVERTISE bits -+ * to linkmode advertisement settings when in SGMII mode. -+ * Clears the old value of advertising. -+ */ -+static inline void mii_lpa_to_linkmode_lpa_sgmii(unsigned long *lp_advertising, -+ u32 lpa) -+{ -+ linkmode_zero(lp_advertising); -+ -+ mii_lpa_mod_linkmode_lpa_sgmii(lp_advertising, lpa); -+} -+ -+/** - * mii_adv_mod_linkmode_adv_t - * @advertising:pointer to destination link mode. - * @adv: value of the MII_ADVERTISE register ---- a/include/uapi/linux/mii.h -+++ b/include/uapi/linux/mii.h -@@ -131,6 +131,18 @@ - #define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */ - #define NWAYTEST_RESV2 0xfe00 /* Unused... */ - -+/* MAC and PHY tx_config_Reg[15:0] for SGMII in-band auto-negotiation.*/ -+#define ADVERTISE_SGMII 0x0001 /* MAC can do SGMII */ -+#define LPA_SGMII 0x0001 /* PHY can do SGMII */ -+#define LPA_SGMII_DPX_SPD_MASK 0x1C00 /* SGMII duplex and speed bits */ -+#define LPA_SGMII_10HALF 0x0000 /* Can do 10mbps half-duplex */ -+#define LPA_SGMII_10FULL 0x1000 /* Can do 10mbps full-duplex */ -+#define LPA_SGMII_100HALF 0x0400 /* Can do 100mbps half-duplex */ -+#define LPA_SGMII_100FULL 0x1400 /* Can do 100mbps full-duplex */ -+#define LPA_SGMII_1000HALF 0x0800 /* Can do 1000mbps half-duplex */ -+#define LPA_SGMII_1000FULL 0x1800 /* Can do 1000mbps full-duplex */ -+#define LPA_SGMII_LINK 0x8000 /* PHY link with copper-side partner */ -+ - /* 1000BASE-T Control register */ - #define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ - #define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0379-net-phylink-make-QSGMII-a-valid-PHY-mode-for-in-band.patch b/target/linux/layerscape/patches-5.4/701-net-0379-net-phylink-make-QSGMII-a-valid-PHY-mode-for-in-band.patch deleted file mode 100644 index 44c9a86970..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0379-net-phylink-make-QSGMII-a-valid-PHY-mode-for-in-band.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 5fdc065751ee25688f99da501123f7e7d4020751 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Fri, 22 Nov 2019 13:46:46 +0200 -Subject: [PATCH] net: phylink: make QSGMII a valid PHY mode for in-band AN - -QSGMII is a SerDes protocol clocked at 5 Gbaud (4 times higher than -SGMII which is clocked at 1.25 Gbaud), with the same 8b/10b encoding and -some extra symbols for synchronization. Logically it offers 4 SGMII -interfaces multiplexed onto the same physical lanes. Each MAC PCS has -its own in-band AN process with the system side of the QSGMII PHY, which -is identical to the regular SGMII AN process. - -So allow QSGMII as a valid in-band AN mode, since it is no different -from software perspective from regular SGMII. - -Signed-off-by: Vladimir Oltean ---- - drivers/net/phy/phylink.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -283,6 +283,7 @@ static int phylink_parse_mode(struct phy - - switch (pl->link_config.interface) { - case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_QSGMII: - phylink_set(pl->supported, 10baseT_Half); - phylink_set(pl->supported, 10baseT_Full); - phylink_set(pl->supported, 100baseT_Half); diff --git a/target/linux/layerscape/patches-5.4/701-net-0380-net-phylink-add-support-for-polling-MAC-PCS.patch b/target/linux/layerscape/patches-5.4/701-net-0380-net-phylink-add-support-for-polling-MAC-PCS.patch deleted file mode 100644 index f9b97b3f4e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0380-net-phylink-add-support-for-polling-MAC-PCS.patch +++ /dev/null @@ -1,74 +0,0 @@ -From c12db737cf62ca262c01ec6d4ba942b34db35d8b Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Fri, 27 Dec 2019 19:45:22 +0200 -Subject: [PATCH] net: phylink: add support for polling MAC PCS - -Some MAC PCS blocks are unable to provide interrupts when their status -changes. As we already have support in phylink for polling status, use -this to provide a hook for MACs to enable polling mode. - -The patch idea was picked up from Russell King's suggestion on the macb -phylink patch thread here [0] but the implementation was changed. -Instead of introducing a new phylink_start_poll() function, which would -make the implementation cumbersome for common PHYLINK implementations -for multiple types of devices, like DSA, just add a boolean property to -the phylink_config structure, which is just as backwards-compatible. - -https://lkml.org/lkml/2019/12/16/603 - -Suggested-by: Russell King -Signed-off-by: Vladimir Oltean -[rebase] -Signed-off-by: Yangbo Lu - -Conflicts: - drivers/net/phy/phylink.c - -with upstream commit 24cf0e693bb5 ("net: phylink: split link_an_mode -configured and current settings") submitted for net-next and merged -during v5.5-rc1. ---- - Documentation/networking/sfp-phylink.rst | 3 ++- - drivers/net/phy/phylink.c | 3 ++- - include/linux/phylink.h | 2 ++ - 3 files changed, 6 insertions(+), 2 deletions(-) - ---- a/Documentation/networking/sfp-phylink.rst -+++ b/Documentation/networking/sfp-phylink.rst -@@ -251,7 +251,8 @@ this documentation. - phylink_mac_change(priv->phylink, link_is_up); - - where ``link_is_up`` is true if the link is currently up or false -- otherwise. -+ otherwise. If a MAC is unable to provide these interrupts, then -+ it should set ``priv->phylink_config.pcs_poll = true;`` in step 9. - - 11. Verify that the driver does not call:: - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -1008,7 +1008,8 @@ void phylink_start(struct phylink *pl) - if (irq <= 0) - mod_timer(&pl->link_poll, jiffies + HZ); - } -- if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->get_fixed_state) -+ if ((pl->cfg_link_an_mode == MLO_AN_FIXED && pl->get_fixed_state) || -+ pl->config->pcs_poll) - mod_timer(&pl->link_poll, jiffies + HZ); - if (pl->phydev) - phy_start(pl->phydev); ---- a/include/linux/phylink.h -+++ b/include/linux/phylink.h -@@ -63,10 +63,12 @@ enum phylink_op_type { - * struct phylink_config - PHYLINK configuration structure - * @dev: a pointer to a struct device associated with the MAC - * @type: operation type of PHYLINK instance -+ * @pcs_poll: MAC PCS cannot provide link change interrupt - */ - struct phylink_config { - struct device *dev; - enum phylink_op_type type; -+ bool pcs_poll; - }; - - /** diff --git a/target/linux/layerscape/patches-5.4/701-net-0381-net-dsa-Pass-pcs_poll-flag-from-driver-to-PHYLINK.patch b/target/linux/layerscape/patches-5.4/701-net-0381-net-dsa-Pass-pcs_poll-flag-from-driver-to-PHYLINK.patch deleted file mode 100644 index fe2ceee8d4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0381-net-dsa-Pass-pcs_poll-flag-from-driver-to-PHYLINK.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 3f911800613a3417101563b488c51a9b310ba7fa Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Fri, 27 Dec 2019 20:14:57 +0200 -Subject: [PATCH] net: dsa: Pass pcs_poll flag from driver to PHYLINK - -The DSA drivers that implement .phylink_mac_link_state should normally -register an interrupt for the PCS, from which they should call -phylink_mac_change(). However not all switches implement this, and those -who don't should set this flag in dsa_switch in the .setup callback, so -that PHYLINK will poll for a few ms until the in-band AN link timer -expires and the PCS state settles. - -Signed-off-by: Vladimir Oltean - -Conflicts: - include/net/dsa.h - -trivially with upstream commit 05f294a85235 ("net: dsa: allocate ports -on touch") which was merged in v5.4-rc3. ---- - include/net/dsa.h | 5 +++++ - net/dsa/port.c | 1 + - 2 files changed, 6 insertions(+) - ---- a/include/net/dsa.h -+++ b/include/net/dsa.h -@@ -291,6 +291,11 @@ struct dsa_switch { - */ - bool vlan_filtering; - -+ /* MAC PCS does not provide link state change interrupt, and requires -+ * polling. Flag passed on to PHYLINK. -+ */ -+ bool pcs_poll; -+ - /* Dynamically allocated ports, keep last */ - size_t num_ports; - struct dsa_port ports[]; ---- a/net/dsa/port.c -+++ b/net/dsa/port.c -@@ -639,6 +639,7 @@ static int dsa_port_phylink_register(str - - dp->pl_config.dev = ds->dev; - dp->pl_config.type = PHYLINK_DEV; -+ dp->pl_config.pcs_poll = ds->pcs_poll; - - dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), - mode, &dsa_port_phylink_mac_ops); diff --git a/target/linux/layerscape/patches-5.4/701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch b/target/linux/layerscape/patches-5.4/701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch deleted file mode 100644 index c11f1a72ed..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0382-enetc-Make-MDIO-accessors-more-generic-and-export-to.patch +++ /dev/null @@ -1,446 +0,0 @@ -From 126e6f022c749ac1bf3a607269a106ccd87d0594 Mon Sep 17 00:00:00 2001 -From: Claudiu Manoil -Date: Mon, 12 Aug 2019 20:26:42 +0300 -Subject: [PATCH] enetc: Make MDIO accessors more generic and export to - include/linux/fsl - -Within the LS1028A SoC, the register map for the ENETC MDIO controller -is instantiated a few times: for the central (external) MDIO controller, -for the internal bus of each standalone ENETC port, and for the internal -bus of the Felix switch. - -Refactoring is needed to support multiple MDIO buses from multiple -drivers. The enetc_hw structure is made an opaque type and a smaller -enetc_mdio_priv is created. - -'mdio_base' - MDIO registers base address - is being parameterized, to -be able to work with different MDIO register bases. - -The ENETC MDIO bus operations are exported from the fsl-enetc-mdio -kernel object, the same that registers the central MDIO controller (the -dedicated PF). The ENETC main driver has been changed to select it, and -use its exported helpers to further register its private MDIO bus. The -DSA Felix driver will do the same. - -Signed-off-by: Claudiu Manoil -Signed-off-by: Vladimir Oltean - -Conflicts: - drivers/net/ethernet/freescale/enetc/enetc_mdio.c - drivers/net/ethernet/freescale/enetc/enetc_mdio.h - drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c - drivers/net/ethernet/freescale/enetc/enetc_pf.c - drivers/net/ethernet/freescale/enetc/enetc_pf.h - -mostly with the previous (downstream version of this commit) patch -572ee5d842da ("enetc: Make mdio accessors more generic"), which couldn't -be reverted cleanly due to the existing downstream workaround for the -MDIO erratum. ---- - drivers/net/ethernet/freescale/enetc/Kconfig | 1 + - drivers/net/ethernet/freescale/enetc/Makefile | 2 +- - drivers/net/ethernet/freescale/enetc/enetc_mdio.c | 76 ++++------------------ - drivers/net/ethernet/freescale/enetc/enetc_mdio.h | 12 ---- - .../net/ethernet/freescale/enetc/enetc_pci_mdio.c | 41 +++++++----- - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 71 ++++++++++++++++++++ - drivers/net/ethernet/freescale/enetc/enetc_pf.h | 5 -- - include/linux/fsl/enetc_mdio.h | 55 ++++++++++++++++ - 8 files changed, 163 insertions(+), 100 deletions(-) - delete mode 100644 drivers/net/ethernet/freescale/enetc/enetc_mdio.h - create mode 100644 include/linux/fsl/enetc_mdio.h - ---- a/drivers/net/ethernet/freescale/enetc/Kconfig -+++ b/drivers/net/ethernet/freescale/enetc/Kconfig -@@ -2,6 +2,7 @@ - config FSL_ENETC - tristate "ENETC PF driver" - depends on PCI && PCI_MSI && (ARCH_LAYERSCAPE || COMPILE_TEST) -+ select FSL_ENETC_MDIO - select PHYLIB - help - This driver supports NXP ENETC gigabit ethernet controller PCIe ---- a/drivers/net/ethernet/freescale/enetc/Makefile -+++ b/drivers/net/ethernet/freescale/enetc/Makefile -@@ -3,7 +3,7 @@ - common-objs := enetc.o enetc_cbdr.o enetc_ethtool.o - - obj-$(CONFIG_FSL_ENETC) += fsl-enetc.o --fsl-enetc-y := enetc_pf.o enetc_mdio.o $(common-objs) -+fsl-enetc-y := enetc_pf.o $(common-objs) - fsl-enetc-$(CONFIG_PCI_IOV) += enetc_msg.o - fsl-enetc-$(CONFIG_FSL_ENETC_QOS) += enetc_qos.o - fsl-enetc-$(CONFIG_ENETC_TSN) += enetc_tsn.o ---- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_mdio.c -@@ -1,13 +1,13 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) - /* Copyright 2019 NXP */ - -+#include - #include - #include - #include - #include - - #include "enetc_pf.h" --#include "enetc_mdio.h" - - #define ENETC_MDIO_CFG 0x0 /* MDIO configuration and status */ - #define ENETC_MDIO_CTL 0x4 /* MDIO control */ -@@ -99,6 +99,7 @@ int enetc_mdio_write(struct mii_bus *bus - - return 0; - } -+EXPORT_SYMBOL_GPL(enetc_mdio_write); - - int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum) - { -@@ -154,73 +155,18 @@ int enetc_mdio_read(struct mii_bus *bus, - - return value; - } -+EXPORT_SYMBOL_GPL(enetc_mdio_read); - --int enetc_mdio_probe(struct enetc_pf *pf) -+struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs) - { -- struct device *dev = &pf->si->pdev->dev; -- struct enetc_mdio_priv *mdio_priv; -- struct device_node *np; -- struct mii_bus *bus; -- int err; -- -- bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv)); -- if (!bus) -- return -ENOMEM; -- -- bus->name = "Freescale ENETC MDIO Bus"; -- bus->read = enetc_mdio_read; -- bus->write = enetc_mdio_write; -- bus->parent = dev; -- mdio_priv = bus->priv; -- mdio_priv->hw = &pf->si->hw; -- mdio_priv->mdio_base = ENETC_EMDIO_BASE; -- snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev)); -- -- np = of_get_child_by_name(dev->of_node, "mdio"); -- if (!np) { -- dev_err(dev, "MDIO node missing\n"); -- return -EINVAL; -- } -- -- err = of_mdiobus_register(bus, np); -- if (err) { -- of_node_put(np); -- dev_err(dev, "cannot register MDIO bus\n"); -- return err; -- } -- -- of_node_put(np); -- pf->mdio = bus; -- -- return 0; --} -+ struct enetc_hw *hw; - --void enetc_mdio_remove(struct enetc_pf *pf) --{ -- if (pf->mdio) -- mdiobus_unregister(pf->mdio); --} -- --int enetc_imdio_init(struct enetc_pf *pf) --{ -- struct device *dev = &pf->si->pdev->dev; -- struct enetc_mdio_priv *mdio_priv; -- struct mii_bus *bus; -+ hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); -+ if (!hw) -+ return ERR_PTR(-ENOMEM); - -- bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv)); -- if (!bus) -- return -ENOMEM; -+ hw->port = port_regs; - -- bus->name = "FSL ENETC internal MDIO Bus"; -- bus->read = enetc_mdio_read; -- bus->write = enetc_mdio_write; -- bus->parent = dev; -- mdio_priv = bus->priv; -- mdio_priv->hw = &pf->si->hw; -- mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE; -- snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev)); -- -- pf->imdio = bus; -- -- return 0; -+ return hw; - } -+EXPORT_SYMBOL_GPL(enetc_hw_alloc); ---- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.h -+++ /dev/null -@@ -1,12 +0,0 @@ --/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ --/* Copyright 2019 NXP */ -- --#include -- --struct enetc_mdio_priv { -- struct enetc_hw *hw; -- int mdio_base; --}; -- --int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value); --int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum); ---- a/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pci_mdio.c -@@ -1,8 +1,8 @@ - // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) - /* Copyright 2019 NXP */ -+#include - #include - #include "enetc_pf.h" --#include "enetc_mdio.h" - - #define ENETC_MDIO_DEV_ID 0xee01 - #define ENETC_MDIO_DEV_NAME "FSL PCIe IE Central MDIO" -@@ -14,17 +14,29 @@ static int enetc_pci_mdio_probe(struct p - { - struct enetc_mdio_priv *mdio_priv; - struct device *dev = &pdev->dev; -+ void __iomem *port_regs; - struct enetc_hw *hw; - struct mii_bus *bus; - int err; - -- hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); -- if (!hw) -- return -ENOMEM; -+ port_regs = pci_iomap(pdev, 0, 0); -+ if (!port_regs) { -+ dev_err(dev, "iomap failed\n"); -+ err = -ENXIO; -+ goto err_ioremap; -+ } -+ -+ hw = enetc_hw_alloc(dev, port_regs); -+ if (IS_ERR(enetc_hw_alloc)) { -+ err = PTR_ERR(hw); -+ goto err_hw_alloc; -+ } - - bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv)); -- if (!bus) -- return -ENOMEM; -+ if (!bus) { -+ err = -ENOMEM; -+ goto err_mdiobus_alloc; -+ } - - bus->name = ENETC_MDIO_BUS_NAME; - bus->read = enetc_mdio_read; -@@ -39,7 +51,7 @@ static int enetc_pci_mdio_probe(struct p - err = pci_enable_device_mem(pdev); - if (err) { - dev_err(dev, "device enable failed\n"); -- return err; -+ goto err_pci_enable; - } - - err = pci_request_region(pdev, 0, KBUILD_MODNAME); -@@ -48,13 +60,6 @@ static int enetc_pci_mdio_probe(struct p - goto err_pci_mem_reg; - } - -- hw->port = pci_iomap(pdev, 0, 0); -- if (!hw->port) { -- err = -ENXIO; -- dev_err(dev, "iomap failed\n"); -- goto err_ioremap; -- } -- - err = of_mdiobus_register(bus, dev->of_node); - if (err) - goto err_mdiobus_reg; -@@ -64,12 +69,14 @@ static int enetc_pci_mdio_probe(struct p - return 0; - - err_mdiobus_reg: -- iounmap(mdio_priv->hw->port); --err_ioremap: - pci_release_mem_regions(pdev); - err_pci_mem_reg: - pci_disable_device(pdev); -- -+err_pci_enable: -+err_mdiobus_alloc: -+ iounmap(port_regs); -+err_hw_alloc: -+err_ioremap: - return err; - } - ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -2,6 +2,7 @@ - /* Copyright 2017-2019 NXP */ - - #include -+#include - #include - #include - #include "enetc_pf.h" -@@ -760,6 +761,52 @@ static void enetc_pf_netdev_setup(struct - enetc_get_primary_mac_addr(&si->hw, ndev->dev_addr); - } - -+static int enetc_mdio_probe(struct enetc_pf *pf) -+{ -+ struct device *dev = &pf->si->pdev->dev; -+ struct enetc_mdio_priv *mdio_priv; -+ struct device_node *np; -+ struct mii_bus *bus; -+ int err; -+ -+ bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv)); -+ if (!bus) -+ return -ENOMEM; -+ -+ bus->name = "Freescale ENETC MDIO Bus"; -+ bus->read = enetc_mdio_read; -+ bus->write = enetc_mdio_write; -+ bus->parent = dev; -+ mdio_priv = bus->priv; -+ mdio_priv->hw = &pf->si->hw; -+ mdio_priv->mdio_base = ENETC_EMDIO_BASE; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev)); -+ -+ np = of_get_child_by_name(dev->of_node, "mdio"); -+ if (!np) { -+ dev_err(dev, "MDIO node missing\n"); -+ return -EINVAL; -+ } -+ -+ err = of_mdiobus_register(bus, np); -+ if (err) { -+ of_node_put(np); -+ dev_err(dev, "cannot register MDIO bus\n"); -+ return err; -+ } -+ -+ of_node_put(np); -+ pf->mdio = bus; -+ -+ return 0; -+} -+ -+static void enetc_mdio_remove(struct enetc_pf *pf) -+{ -+ if (pf->mdio) -+ mdiobus_unregister(pf->mdio); -+} -+ - static int enetc_of_get_phy(struct enetc_pf *pf) - { - struct device *dev = &pf->si->pdev->dev; -@@ -911,6 +958,30 @@ static void enetc_configure_sxgmii(struc - ENETC_PCS_CR_LANE_RESET | ENETC_PCS_CR_RESET_AN); - } - -+static int enetc_imdio_init(struct enetc_pf *pf) -+{ -+ struct device *dev = &pf->si->pdev->dev; -+ struct enetc_mdio_priv *mdio_priv; -+ struct mii_bus *bus; -+ -+ bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv)); -+ if (!bus) -+ return -ENOMEM; -+ -+ bus->name = "FSL ENETC internal MDIO Bus"; -+ bus->read = enetc_mdio_read; -+ bus->write = enetc_mdio_write; -+ bus->parent = dev; -+ mdio_priv = bus->priv; -+ mdio_priv->hw = &pf->si->hw; -+ mdio_priv->mdio_base = ENETC_PM_IMDIO_BASE; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev)); -+ -+ pf->imdio = bus; -+ -+ return 0; -+} -+ - static int enetc_configure_serdes(struct enetc_ndev_priv *priv) - { - struct enetc_pf *pf = enetc_si_priv(priv->si); ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h -@@ -53,8 +53,3 @@ struct enetc_pf { - int enetc_msg_psi_init(struct enetc_pf *pf); - void enetc_msg_psi_free(struct enetc_pf *pf); - void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int mbox_id, u16 *status); -- --/* MDIO */ --int enetc_mdio_probe(struct enetc_pf *pf); --void enetc_mdio_remove(struct enetc_pf *pf); --int enetc_imdio_init(struct enetc_pf *pf); ---- /dev/null -+++ b/include/linux/fsl/enetc_mdio.h -@@ -0,0 +1,55 @@ -+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ -+/* Copyright 2019 NXP */ -+ -+#ifndef _FSL_ENETC_MDIO_H_ -+#define _FSL_ENETC_MDIO_H_ -+ -+#include -+ -+/* PCS registers */ -+#define ENETC_PCS_LINK_TIMER1 0x12 -+#define ENETC_PCS_LINK_TIMER1_VAL 0x06a0 -+#define ENETC_PCS_LINK_TIMER2 0x13 -+#define ENETC_PCS_LINK_TIMER2_VAL 0x0003 -+#define ENETC_PCS_IF_MODE 0x14 -+#define ENETC_PCS_IF_MODE_SGMII_EN BIT(0) -+#define ENETC_PCS_IF_MODE_USE_SGMII_AN BIT(1) -+#define ENETC_PCS_IF_MODE_SGMII_SPEED(x) (((x) << 2) & GENMASK(3, 2)) -+ -+/* Not a mistake, the SerDes PLL needs to be set at 3.125 GHz by Reset -+ * Configuration Word (RCW, outside Linux control) for 2.5G SGMII mode. The PCS -+ * still thinks it's at gigabit. -+ */ -+enum enetc_pcs_speed { -+ ENETC_PCS_SPEED_10 = 0, -+ ENETC_PCS_SPEED_100 = 1, -+ ENETC_PCS_SPEED_1000 = 2, -+ ENETC_PCS_SPEED_2500 = 2, -+}; -+ -+struct enetc_hw; -+ -+struct enetc_mdio_priv { -+ struct enetc_hw *hw; -+ int mdio_base; -+}; -+ -+#if IS_REACHABLE(CONFIG_FSL_ENETC_MDIO) -+ -+int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum); -+int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value); -+struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs); -+ -+#else -+ -+static inline int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum) -+{ return -EINVAL; } -+static inline int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, -+ u16 value) -+{ return -EINVAL; } -+struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs) -+{ return ERR_PTR(-EINVAL); } -+ -+#endif -+ -+#endif diff --git a/target/linux/layerscape/patches-5.4/701-net-0383-enetc-Set-MDIO_CFG_HOLD-to-the-recommended-value-of-.patch b/target/linux/layerscape/patches-5.4/701-net-0383-enetc-Set-MDIO_CFG_HOLD-to-the-recommended-value-of-.patch deleted file mode 100644 index 50b34520e3..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0383-enetc-Set-MDIO_CFG_HOLD-to-the-recommended-value-of-.patch +++ /dev/null @@ -1,58 +0,0 @@ -From c0308743202449028d2b839d9b01d3d5ed2b210a Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Wed, 27 Nov 2019 19:21:13 +0200 -Subject: [PATCH] enetc: Set MDIO_CFG_HOLD to the recommended value of 2 - -This increases the MDIO hold time to 5 enet_clk cycles from the previous -value of 0. This is actually the out-of-reset value, that the driver was -previously overwriting with 0. Zero worked for the external MDIO, but -breaks communication with the internal MDIO buses on which the PCS of -ENETC SI's and Felix switch are found. - -Signed-off-by: Vladimir Oltean ---- - drivers/net/ethernet/freescale/enetc/enetc_mdio.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc_mdio.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_mdio.c -@@ -31,15 +31,19 @@ static inline void _enetc_mdio_wr(struct - _enetc_mdio_wr(mdio_priv, ENETC_##off, val) - #define enetc_mdio_rd_reg(off) enetc_mdio_rd(mdio_priv, off) - --#define ENETC_MDC_DIV 258 -- - #define MDIO_CFG_CLKDIV(x) ((((x) >> 1) & 0xff) << 8) - #define MDIO_CFG_BSY BIT(0) - #define MDIO_CFG_RD_ER BIT(1) -+#define MDIO_CFG_HOLD(x) (((x) << 2) & GENMASK(4, 2)) - #define MDIO_CFG_ENC45 BIT(6) - /* external MDIO only - driven on neg MDC edge */ - #define MDIO_CFG_NEG BIT(23) - -+#define ENETC_EMDIO_CFG \ -+ (MDIO_CFG_HOLD(2) | \ -+ MDIO_CFG_CLKDIV(258) | \ -+ MDIO_CFG_NEG) -+ - #define MDIO_CTL_DEV_ADDR(x) ((x) & 0x1f) - #define MDIO_CTL_PORT_ADDR(x) (((x) & 0x1f) << 5) - #define MDIO_CTL_READ BIT(15) -@@ -61,7 +65,7 @@ int enetc_mdio_write(struct mii_bus *bus - u16 dev_addr; - int ret; - -- mdio_cfg = MDIO_CFG_CLKDIV(ENETC_MDC_DIV) | MDIO_CFG_NEG; -+ mdio_cfg = ENETC_EMDIO_CFG; - if (regnum & MII_ADDR_C45) { - dev_addr = (regnum >> 16) & 0x1f; - mdio_cfg |= MDIO_CFG_ENC45; -@@ -108,7 +112,7 @@ int enetc_mdio_read(struct mii_bus *bus, - u16 dev_addr, value; - int ret; - -- mdio_cfg = MDIO_CFG_CLKDIV(ENETC_MDC_DIV) | MDIO_CFG_NEG; -+ mdio_cfg = ENETC_EMDIO_CFG; - if (regnum & MII_ADDR_C45) { - dev_addr = (regnum >> 16) & 0x1f; - mdio_cfg |= MDIO_CFG_ENC45; diff --git a/target/linux/layerscape/patches-5.4/701-net-0384-net-mscc-ocelot-make-phy_mode-a-member-of-the-common.patch b/target/linux/layerscape/patches-5.4/701-net-0384-net-mscc-ocelot-make-phy_mode-a-member-of-the-common.patch deleted file mode 100644 index 662ad103f9..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0384-net-mscc-ocelot-make-phy_mode-a-member-of-the-common.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 1737de8045838dcf3c7713c940eb1582810a319f Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Mon, 16 Dec 2019 15:07:20 +0200 -Subject: [PATCH] net: mscc: ocelot: make phy_mode a member of the common - struct ocelot_port - -The Ocelot switchdev driver and the Felix DSA one need it for different -reasons. Felix (or at least the VSC9959 instantiation in NXP LS1028A) is -integrated with the traditional NXP Layerscape PCS design which does not -support runtime configuration of SerDes protocol. So it needs to -pre-validate the phy-mode from the device tree and prevent PHYLINK from -attempting to change it. For this, it needs to cache it in a private -variable. - -Signed-off-by: Vladimir Oltean ---- - drivers/net/ethernet/mscc/ocelot.c | 7 ++++--- - drivers/net/ethernet/mscc/ocelot.h | 1 - - drivers/net/ethernet/mscc/ocelot_board.c | 4 ++-- - include/soc/mscc/ocelot.h | 2 ++ - 4 files changed, 8 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -500,13 +500,14 @@ EXPORT_SYMBOL(ocelot_port_enable); - static int ocelot_port_open(struct net_device *dev) - { - struct ocelot_port_private *priv = netdev_priv(dev); -- struct ocelot *ocelot = priv->port.ocelot; -+ struct ocelot_port *ocelot_port = &priv->port; -+ struct ocelot *ocelot = ocelot_port->ocelot; - int port = priv->chip_port; - int err; - - if (priv->serdes) { - err = phy_set_mode_ext(priv->serdes, PHY_MODE_ETHERNET, -- priv->phy_mode); -+ ocelot_port->phy_mode); - if (err) { - netdev_err(dev, "Could not set mode of SerDes\n"); - return err; -@@ -514,7 +515,7 @@ static int ocelot_port_open(struct net_d - } - - err = phy_connect_direct(dev, priv->phy, &ocelot_port_adjust_link, -- priv->phy_mode); -+ ocelot_port->phy_mode); - if (err) { - netdev_err(dev, "Could not attach to PHY\n"); - return err; ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -70,7 +70,6 @@ struct ocelot_port_private { - - u8 vlan_aware; - -- phy_interface_t phy_mode; - struct phy *serdes; - - struct ocelot_port_tc tc; ---- a/drivers/net/ethernet/mscc/ocelot_board.c -+++ b/drivers/net/ethernet/mscc/ocelot_board.c -@@ -412,9 +412,9 @@ static int mscc_ocelot_probe(struct plat - if (phy_mode < 0) - phy_mode = PHY_INTERFACE_MODE_NA; - -- priv->phy_mode = phy_mode; -+ ocelot_port->phy_mode = phy_mode; - -- switch (priv->phy_mode) { -+ switch (ocelot_port->phy_mode) { - case PHY_INTERFACE_MODE_NA: - continue; - case PHY_INTERFACE_MODE_SGMII: ---- a/include/soc/mscc/ocelot.h -+++ b/include/soc/mscc/ocelot.h -@@ -425,6 +425,8 @@ struct ocelot_port { - u8 ptp_cmd; - struct sk_buff_head tx_skbs; - u8 ts_id; -+ -+ phy_interface_t phy_mode; - }; - - struct ocelot { diff --git a/target/linux/layerscape/patches-5.4/701-net-0385-net-mscc-ocelot-export-ANA-DEV-and-QSYS-registers-to.patch b/target/linux/layerscape/patches-5.4/701-net-0385-net-mscc-ocelot-export-ANA-DEV-and-QSYS-registers-to.patch deleted file mode 100644 index b300ba9d76..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0385-net-mscc-ocelot-export-ANA-DEV-and-QSYS-registers-to.patch +++ /dev/null @@ -1,2457 +0,0 @@ -From 518d779810c0e4185f2d8a71fc112232df5be62e Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Mon, 16 Dec 2019 15:09:49 +0200 -Subject: [PATCH] net: mscc: ocelot: export ANA, DEV and QSYS registers to - include/soc/mscc - -Since the Felix DSA driver is implementing its own PHYLINK instance due -to SoC differences, it needs access to the few registers that are -common, mainly for flow control. - -Signed-off-by: Vladimir Oltean - -Conflicts: - drivers/net/ethernet/mscc/ocelot_tsn.c - -which has been added in downstream patch b5c05e3404a5 ("net: mscc: -ocelot: tsn configuration support") and also needs to be adapted to the -new location of the header files. ---- - drivers/net/ethernet/mscc/ocelot.h | 6 +- - drivers/net/ethernet/mscc/ocelot_ana.h | 642 -------------------------------- - drivers/net/ethernet/mscc/ocelot_dev.h | 275 -------------- - drivers/net/ethernet/mscc/ocelot_qsys.h | 270 -------------- - drivers/net/ethernet/mscc/ocelot_tsn.c | 4 +- - include/soc/mscc/ocelot_ana.h | 642 ++++++++++++++++++++++++++++++++ - include/soc/mscc/ocelot_dev.h | 275 ++++++++++++++ - include/soc/mscc/ocelot_qsys.h | 270 ++++++++++++++ - 8 files changed, 1192 insertions(+), 1192 deletions(-) - delete mode 100644 drivers/net/ethernet/mscc/ocelot_ana.h - delete mode 100644 drivers/net/ethernet/mscc/ocelot_dev.h - delete mode 100644 drivers/net/ethernet/mscc/ocelot_qsys.h - create mode 100644 include/soc/mscc/ocelot_ana.h - create mode 100644 include/soc/mscc/ocelot_dev.h - create mode 100644 include/soc/mscc/ocelot_qsys.h - ---- a/drivers/net/ethernet/mscc/ocelot.h -+++ b/drivers/net/ethernet/mscc/ocelot.h -@@ -18,11 +18,11 @@ - #include - #include - -+#include - #include -+#include -+#include - #include --#include "ocelot_ana.h" --#include "ocelot_dev.h" --#include "ocelot_qsys.h" - #include "ocelot_rew.h" - #include "ocelot_qs.h" - #include "ocelot_tc.h" ---- a/drivers/net/ethernet/mscc/ocelot_ana.h -+++ /dev/null -@@ -1,642 +0,0 @@ --/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ --/* -- * Microsemi Ocelot Switch driver -- * -- * Copyright (c) 2017 Microsemi Corporation -- */ -- --#ifndef _MSCC_OCELOT_ANA_H_ --#define _MSCC_OCELOT_ANA_H_ -- --#define ANA_ANAGEFIL_B_DOM_EN BIT(22) --#define ANA_ANAGEFIL_B_DOM_VAL BIT(21) --#define ANA_ANAGEFIL_AGE_LOCKED BIT(20) --#define ANA_ANAGEFIL_PID_EN BIT(19) --#define ANA_ANAGEFIL_PID_VAL(x) (((x) << 14) & GENMASK(18, 14)) --#define ANA_ANAGEFIL_PID_VAL_M GENMASK(18, 14) --#define ANA_ANAGEFIL_PID_VAL_X(x) (((x) & GENMASK(18, 14)) >> 14) --#define ANA_ANAGEFIL_VID_EN BIT(13) --#define ANA_ANAGEFIL_VID_VAL(x) ((x) & GENMASK(12, 0)) --#define ANA_ANAGEFIL_VID_VAL_M GENMASK(12, 0) -- --#define ANA_STORMLIMIT_CFG_RSZ 0x4 -- --#define ANA_STORMLIMIT_CFG_STORM_RATE(x) (((x) << 3) & GENMASK(6, 3)) --#define ANA_STORMLIMIT_CFG_STORM_RATE_M GENMASK(6, 3) --#define ANA_STORMLIMIT_CFG_STORM_RATE_X(x) (((x) & GENMASK(6, 3)) >> 3) --#define ANA_STORMLIMIT_CFG_STORM_UNIT BIT(2) --#define ANA_STORMLIMIT_CFG_STORM_MODE(x) ((x) & GENMASK(1, 0)) --#define ANA_STORMLIMIT_CFG_STORM_MODE_M GENMASK(1, 0) -- --#define ANA_AUTOAGE_AGE_FAST BIT(21) --#define ANA_AUTOAGE_AGE_PERIOD(x) (((x) << 1) & GENMASK(20, 1)) --#define ANA_AUTOAGE_AGE_PERIOD_M GENMASK(20, 1) --#define ANA_AUTOAGE_AGE_PERIOD_X(x) (((x) & GENMASK(20, 1)) >> 1) --#define ANA_AUTOAGE_AUTOAGE_LOCKED BIT(0) -- --#define ANA_MACTOPTIONS_REDUCED_TABLE BIT(1) --#define ANA_MACTOPTIONS_SHADOW BIT(0) -- --#define ANA_AGENCTRL_FID_MASK(x) (((x) << 12) & GENMASK(23, 12)) --#define ANA_AGENCTRL_FID_MASK_M GENMASK(23, 12) --#define ANA_AGENCTRL_FID_MASK_X(x) (((x) & GENMASK(23, 12)) >> 12) --#define ANA_AGENCTRL_IGNORE_DMAC_FLAGS BIT(11) --#define ANA_AGENCTRL_IGNORE_SMAC_FLAGS BIT(10) --#define ANA_AGENCTRL_FLOOD_SPECIAL BIT(9) --#define ANA_AGENCTRL_FLOOD_IGNORE_VLAN BIT(8) --#define ANA_AGENCTRL_MIRROR_CPU BIT(7) --#define ANA_AGENCTRL_LEARN_CPU_COPY BIT(6) --#define ANA_AGENCTRL_LEARN_FWD_KILL BIT(5) --#define ANA_AGENCTRL_LEARN_IGNORE_VLAN BIT(4) --#define ANA_AGENCTRL_CPU_CPU_KILL_ENA BIT(3) --#define ANA_AGENCTRL_GREEN_COUNT_MODE BIT(2) --#define ANA_AGENCTRL_YELLOW_COUNT_MODE BIT(1) --#define ANA_AGENCTRL_RED_COUNT_MODE BIT(0) -- --#define ANA_FLOODING_RSZ 0x4 -- --#define ANA_FLOODING_FLD_UNICAST(x) (((x) << 12) & GENMASK(17, 12)) --#define ANA_FLOODING_FLD_UNICAST_M GENMASK(17, 12) --#define ANA_FLOODING_FLD_UNICAST_X(x) (((x) & GENMASK(17, 12)) >> 12) --#define ANA_FLOODING_FLD_BROADCAST(x) (((x) << 6) & GENMASK(11, 6)) --#define ANA_FLOODING_FLD_BROADCAST_M GENMASK(11, 6) --#define ANA_FLOODING_FLD_BROADCAST_X(x) (((x) & GENMASK(11, 6)) >> 6) --#define ANA_FLOODING_FLD_MULTICAST(x) ((x) & GENMASK(5, 0)) --#define ANA_FLOODING_FLD_MULTICAST_M GENMASK(5, 0) -- --#define ANA_FLOODING_IPMC_FLD_MC4_CTRL(x) (((x) << 18) & GENMASK(23, 18)) --#define ANA_FLOODING_IPMC_FLD_MC4_CTRL_M GENMASK(23, 18) --#define ANA_FLOODING_IPMC_FLD_MC4_CTRL_X(x) (((x) & GENMASK(23, 18)) >> 18) --#define ANA_FLOODING_IPMC_FLD_MC4_DATA(x) (((x) << 12) & GENMASK(17, 12)) --#define ANA_FLOODING_IPMC_FLD_MC4_DATA_M GENMASK(17, 12) --#define ANA_FLOODING_IPMC_FLD_MC4_DATA_X(x) (((x) & GENMASK(17, 12)) >> 12) --#define ANA_FLOODING_IPMC_FLD_MC6_CTRL(x) (((x) << 6) & GENMASK(11, 6)) --#define ANA_FLOODING_IPMC_FLD_MC6_CTRL_M GENMASK(11, 6) --#define ANA_FLOODING_IPMC_FLD_MC6_CTRL_X(x) (((x) & GENMASK(11, 6)) >> 6) --#define ANA_FLOODING_IPMC_FLD_MC6_DATA(x) ((x) & GENMASK(5, 0)) --#define ANA_FLOODING_IPMC_FLD_MC6_DATA_M GENMASK(5, 0) -- --#define ANA_SFLOW_CFG_RSZ 0x4 -- --#define ANA_SFLOW_CFG_SF_RATE(x) (((x) << 2) & GENMASK(13, 2)) --#define ANA_SFLOW_CFG_SF_RATE_M GENMASK(13, 2) --#define ANA_SFLOW_CFG_SF_RATE_X(x) (((x) & GENMASK(13, 2)) >> 2) --#define ANA_SFLOW_CFG_SF_SAMPLE_RX BIT(1) --#define ANA_SFLOW_CFG_SF_SAMPLE_TX BIT(0) -- --#define ANA_PORT_MODE_RSZ 0x4 -- --#define ANA_PORT_MODE_REDTAG_PARSE_CFG BIT(3) --#define ANA_PORT_MODE_VLAN_PARSE_CFG(x) (((x) << 1) & GENMASK(2, 1)) --#define ANA_PORT_MODE_VLAN_PARSE_CFG_M GENMASK(2, 1) --#define ANA_PORT_MODE_VLAN_PARSE_CFG_X(x) (((x) & GENMASK(2, 1)) >> 1) --#define ANA_PORT_MODE_L3_PARSE_CFG BIT(0) -- --#define ANA_CUT_THRU_CFG_RSZ 0x4 -- --#define ANA_PGID_PGID_RSZ 0x4 -- --#define ANA_PGID_PGID_PGID(x) ((x) & GENMASK(11, 0)) --#define ANA_PGID_PGID_PGID_M GENMASK(11, 0) --#define ANA_PGID_PGID_CPUQ_DST_PGID(x) (((x) << 27) & GENMASK(29, 27)) --#define ANA_PGID_PGID_CPUQ_DST_PGID_M GENMASK(29, 27) --#define ANA_PGID_PGID_CPUQ_DST_PGID_X(x) (((x) & GENMASK(29, 27)) >> 27) -- --#define ANA_TABLES_MACHDATA_VID(x) (((x) << 16) & GENMASK(28, 16)) --#define ANA_TABLES_MACHDATA_VID_M GENMASK(28, 16) --#define ANA_TABLES_MACHDATA_VID_X(x) (((x) & GENMASK(28, 16)) >> 16) --#define ANA_TABLES_MACHDATA_MACHDATA(x) ((x) & GENMASK(15, 0)) --#define ANA_TABLES_MACHDATA_MACHDATA_M GENMASK(15, 0) -- --#define ANA_TABLES_STREAMDATA_SSID_VALID BIT(16) --#define ANA_TABLES_STREAMDATA_SSID(x) (((x) << 9) & GENMASK(15, 9)) --#define ANA_TABLES_STREAMDATA_SSID_M GENMASK(15, 9) --#define ANA_TABLES_STREAMDATA_SSID_X(x) (((x) & GENMASK(15, 9)) >> 9) --#define ANA_TABLES_STREAMDATA_SFID_VALID BIT(8) --#define ANA_TABLES_STREAMDATA_SFID(x) ((x) & GENMASK(7, 0)) --#define ANA_TABLES_STREAMDATA_SFID_M GENMASK(7, 0) -- --#define ANA_TABLES_MACACCESS_MAC_CPU_COPY BIT(15) --#define ANA_TABLES_MACACCESS_SRC_KILL BIT(14) --#define ANA_TABLES_MACACCESS_IGNORE_VLAN BIT(13) --#define ANA_TABLES_MACACCESS_AGED_FLAG BIT(12) --#define ANA_TABLES_MACACCESS_VALID BIT(11) --#define ANA_TABLES_MACACCESS_ENTRYTYPE(x) (((x) << 9) & GENMASK(10, 9)) --#define ANA_TABLES_MACACCESS_ENTRYTYPE_M GENMASK(10, 9) --#define ANA_TABLES_MACACCESS_ENTRYTYPE_X(x) (((x) & GENMASK(10, 9)) >> 9) --#define ANA_TABLES_MACACCESS_DEST_IDX(x) (((x) << 3) & GENMASK(8, 3)) --#define ANA_TABLES_MACACCESS_DEST_IDX_M GENMASK(8, 3) --#define ANA_TABLES_MACACCESS_DEST_IDX_X(x) (((x) & GENMASK(8, 3)) >> 3) --#define ANA_TABLES_MACACCESS_MAC_TABLE_CMD(x) ((x) & GENMASK(2, 0)) --#define ANA_TABLES_MACACCESS_MAC_TABLE_CMD_M GENMASK(2, 0) --#define MACACCESS_CMD_IDLE 0 --#define MACACCESS_CMD_LEARN 1 --#define MACACCESS_CMD_FORGET 2 --#define MACACCESS_CMD_AGE 3 --#define MACACCESS_CMD_GET_NEXT 4 --#define MACACCESS_CMD_INIT 5 --#define MACACCESS_CMD_READ 6 --#define MACACCESS_CMD_WRITE 7 -- --#define ANA_TABLES_VLANACCESS_VLAN_PORT_MASK(x) (((x) << 2) & GENMASK(13, 2)) --#define ANA_TABLES_VLANACCESS_VLAN_PORT_MASK_M GENMASK(13, 2) --#define ANA_TABLES_VLANACCESS_VLAN_PORT_MASK_X(x) (((x) & GENMASK(13, 2)) >> 2) --#define ANA_TABLES_VLANACCESS_VLAN_TBL_CMD(x) ((x) & GENMASK(1, 0)) --#define ANA_TABLES_VLANACCESS_VLAN_TBL_CMD_M GENMASK(1, 0) --#define ANA_TABLES_VLANACCESS_CMD_IDLE 0x0 --#define ANA_TABLES_VLANACCESS_CMD_WRITE 0x2 --#define ANA_TABLES_VLANACCESS_CMD_INIT 0x3 -- --#define ANA_TABLES_VLANTIDX_VLAN_SEC_FWD_ENA BIT(17) --#define ANA_TABLES_VLANTIDX_VLAN_FLOOD_DIS BIT(16) --#define ANA_TABLES_VLANTIDX_VLAN_PRIV_VLAN BIT(15) --#define ANA_TABLES_VLANTIDX_VLAN_LEARN_DISABLED BIT(14) --#define ANA_TABLES_VLANTIDX_VLAN_MIRROR BIT(13) --#define ANA_TABLES_VLANTIDX_VLAN_SRC_CHK BIT(12) --#define ANA_TABLES_VLANTIDX_V_INDEX(x) ((x) & GENMASK(11, 0)) --#define ANA_TABLES_VLANTIDX_V_INDEX_M GENMASK(11, 0) -- --#define ANA_TABLES_ISDXACCESS_ISDX_PORT_MASK(x) (((x) << 2) & GENMASK(8, 2)) --#define ANA_TABLES_ISDXACCESS_ISDX_PORT_MASK_M GENMASK(8, 2) --#define ANA_TABLES_ISDXACCESS_ISDX_PORT_MASK_X(x) (((x) & GENMASK(8, 2)) >> 2) --#define ANA_TABLES_ISDXACCESS_ISDX_TBL_CMD(x) ((x) & GENMASK(1, 0)) --#define ANA_TABLES_ISDXACCESS_ISDX_TBL_CMD_M GENMASK(1, 0) -- --#define ANA_TABLES_ISDXTIDX_ISDX_SDLBI(x) (((x) << 21) & GENMASK(28, 21)) --#define ANA_TABLES_ISDXTIDX_ISDX_SDLBI_M GENMASK(28, 21) --#define ANA_TABLES_ISDXTIDX_ISDX_SDLBI_X(x) (((x) & GENMASK(28, 21)) >> 21) --#define ANA_TABLES_ISDXTIDX_ISDX_MSTI(x) (((x) << 15) & GENMASK(20, 15)) --#define ANA_TABLES_ISDXTIDX_ISDX_MSTI_M GENMASK(20, 15) --#define ANA_TABLES_ISDXTIDX_ISDX_MSTI_X(x) (((x) & GENMASK(20, 15)) >> 15) --#define ANA_TABLES_ISDXTIDX_ISDX_ES0_KEY_ENA BIT(14) --#define ANA_TABLES_ISDXTIDX_ISDX_FORCE_ENA BIT(10) --#define ANA_TABLES_ISDXTIDX_ISDX_INDEX(x) ((x) & GENMASK(7, 0)) --#define ANA_TABLES_ISDXTIDX_ISDX_INDEX_M GENMASK(7, 0) -- --#define ANA_TABLES_ENTRYLIM_RSZ 0x4 -- --#define ANA_TABLES_ENTRYLIM_ENTRYLIM(x) (((x) << 14) & GENMASK(17, 14)) --#define ANA_TABLES_ENTRYLIM_ENTRYLIM_M GENMASK(17, 14) --#define ANA_TABLES_ENTRYLIM_ENTRYLIM_X(x) (((x) & GENMASK(17, 14)) >> 14) --#define ANA_TABLES_ENTRYLIM_ENTRYSTAT(x) ((x) & GENMASK(13, 0)) --#define ANA_TABLES_ENTRYLIM_ENTRYSTAT_M GENMASK(13, 0) -- --#define ANA_TABLES_STREAMACCESS_GEN_REC_SEQ_NUM(x) (((x) << 4) & GENMASK(31, 4)) --#define ANA_TABLES_STREAMACCESS_GEN_REC_SEQ_NUM_M GENMASK(31, 4) --#define ANA_TABLES_STREAMACCESS_GEN_REC_SEQ_NUM_X(x) (((x) & GENMASK(31, 4)) >> 4) --#define ANA_TABLES_STREAMACCESS_SEQ_GEN_REC_ENA BIT(3) --#define ANA_TABLES_STREAMACCESS_GEN_REC_TYPE BIT(2) --#define ANA_TABLES_STREAMACCESS_STREAM_TBL_CMD(x) ((x) & GENMASK(1, 0)) --#define ANA_TABLES_STREAMACCESS_STREAM_TBL_CMD_M GENMASK(1, 0) -- --#define ANA_TABLES_STREAMTIDX_SEQ_GEN_ERR_STATUS(x) (((x) << 30) & GENMASK(31, 30)) --#define ANA_TABLES_STREAMTIDX_SEQ_GEN_ERR_STATUS_M GENMASK(31, 30) --#define ANA_TABLES_STREAMTIDX_SEQ_GEN_ERR_STATUS_X(x) (((x) & GENMASK(31, 30)) >> 30) --#define ANA_TABLES_STREAMTIDX_S_INDEX(x) (((x) << 16) & GENMASK(22, 16)) --#define ANA_TABLES_STREAMTIDX_S_INDEX_M GENMASK(22, 16) --#define ANA_TABLES_STREAMTIDX_S_INDEX_X(x) (((x) & GENMASK(22, 16)) >> 16) --#define ANA_TABLES_STREAMTIDX_FORCE_SF_BEHAVIOUR BIT(14) --#define ANA_TABLES_STREAMTIDX_SEQ_HISTORY_LEN(x) (((x) << 8) & GENMASK(13, 8)) --#define ANA_TABLES_STREAMTIDX_SEQ_HISTORY_LEN_M GENMASK(13, 8) --#define ANA_TABLES_STREAMTIDX_SEQ_HISTORY_LEN_X(x) (((x) & GENMASK(13, 8)) >> 8) --#define ANA_TABLES_STREAMTIDX_RESET_ON_ROGUE BIT(7) --#define ANA_TABLES_STREAMTIDX_REDTAG_POP BIT(6) --#define ANA_TABLES_STREAMTIDX_STREAM_SPLIT BIT(5) --#define ANA_TABLES_STREAMTIDX_SEQ_SPACE_LOG2(x) ((x) & GENMASK(4, 0)) --#define ANA_TABLES_STREAMTIDX_SEQ_SPACE_LOG2_M GENMASK(4, 0) -- --#define ANA_TABLES_SEQ_MASK_SPLIT_MASK(x) (((x) << 16) & GENMASK(22, 16)) --#define ANA_TABLES_SEQ_MASK_SPLIT_MASK_M GENMASK(22, 16) --#define ANA_TABLES_SEQ_MASK_SPLIT_MASK_X(x) (((x) & GENMASK(22, 16)) >> 16) --#define ANA_TABLES_SEQ_MASK_INPUT_PORT_MASK(x) ((x) & GENMASK(6, 0)) --#define ANA_TABLES_SEQ_MASK_INPUT_PORT_MASK_M GENMASK(6, 0) -- --#define ANA_TABLES_SFID_MASK_IGR_PORT_MASK(x) (((x) << 1) & GENMASK(7, 1)) --#define ANA_TABLES_SFID_MASK_IGR_PORT_MASK_M GENMASK(7, 1) --#define ANA_TABLES_SFID_MASK_IGR_PORT_MASK_X(x) (((x) & GENMASK(7, 1)) >> 1) --#define ANA_TABLES_SFID_MASK_IGR_SRCPORT_MATCH_ENA BIT(0) -- --#define ANA_TABLES_SFIDACCESS_IGR_PRIO_MATCH_ENA BIT(22) --#define ANA_TABLES_SFIDACCESS_IGR_PRIO(x) (((x) << 19) & GENMASK(21, 19)) --#define ANA_TABLES_SFIDACCESS_IGR_PRIO_M GENMASK(21, 19) --#define ANA_TABLES_SFIDACCESS_IGR_PRIO_X(x) (((x) & GENMASK(21, 19)) >> 19) --#define ANA_TABLES_SFIDACCESS_FORCE_BLOCK BIT(18) --#define ANA_TABLES_SFIDACCESS_MAX_SDU_LEN(x) (((x) << 2) & GENMASK(17, 2)) --#define ANA_TABLES_SFIDACCESS_MAX_SDU_LEN_M GENMASK(17, 2) --#define ANA_TABLES_SFIDACCESS_MAX_SDU_LEN_X(x) (((x) & GENMASK(17, 2)) >> 2) --#define ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(x) ((x) & GENMASK(1, 0)) --#define ANA_TABLES_SFIDACCESS_SFID_TBL_CMD_M GENMASK(1, 0) -- --#define SFIDACCESS_CMD_IDLE 0 --#define SFIDACCESS_CMD_READ 1 --#define SFIDACCESS_CMD_WRITE 2 --#define SFIDACCESS_CMD_INIT 3 -- --#define ANA_TABLES_SFIDTIDX_SGID_VALID BIT(26) --#define ANA_TABLES_SFIDTIDX_SGID(x) (((x) << 18) & GENMASK(25, 18)) --#define ANA_TABLES_SFIDTIDX_SGID_M GENMASK(25, 18) --#define ANA_TABLES_SFIDTIDX_SGID_X(x) (((x) & GENMASK(25, 18)) >> 18) --#define ANA_TABLES_SFIDTIDX_POL_ENA BIT(17) --#define ANA_TABLES_SFIDTIDX_POL_IDX(x) (((x) << 8) & GENMASK(16, 8)) --#define ANA_TABLES_SFIDTIDX_POL_IDX_M GENMASK(16, 8) --#define ANA_TABLES_SFIDTIDX_POL_IDX_X(x) (((x) & GENMASK(16, 8)) >> 8) --#define ANA_TABLES_SFIDTIDX_SFID_INDEX(x) ((x) & GENMASK(7, 0)) --#define ANA_TABLES_SFIDTIDX_SFID_INDEX_M GENMASK(7, 0) -- --#define ANA_MSTI_STATE_RSZ 0x4 -- --#define ANA_OAM_UPM_LM_CNT_RSZ 0x4 -- --#define ANA_SG_ACCESS_CTRL_SGID(x) ((x) & GENMASK(7, 0)) --#define ANA_SG_ACCESS_CTRL_SGID_M GENMASK(7, 0) --#define ANA_SG_ACCESS_CTRL_CONFIG_CHANGE BIT(28) -- --#define ANA_SG_CONFIG_REG_3_BASE_TIME_SEC_MSB(x) ((x) & GENMASK(15, 0)) --#define ANA_SG_CONFIG_REG_3_BASE_TIME_SEC_MSB_M GENMASK(15, 0) --#define ANA_SG_CONFIG_REG_3_LIST_LENGTH(x) (((x) << 16) & GENMASK(18, 16)) --#define ANA_SG_CONFIG_REG_3_LIST_LENGTH_M GENMASK(18, 16) --#define ANA_SG_CONFIG_REG_3_LIST_LENGTH_X(x) (((x) & GENMASK(18, 16)) >> 16) --#define ANA_SG_CONFIG_REG_3_GATE_ENABLE BIT(20) --#define ANA_SG_CONFIG_REG_3_INIT_IPS(x) (((x) << 21) & GENMASK(24, 21)) --#define ANA_SG_CONFIG_REG_3_INIT_IPS_M GENMASK(24, 21) --#define ANA_SG_CONFIG_REG_3_INIT_IPS_X(x) (((x) & GENMASK(24, 21)) >> 21) --#define ANA_SG_CONFIG_REG_3_IPV_VALID BIT(24) --#define ANA_SG_CONFIG_REG_3_IPV_INVALID(x) (((x) << 24) & GENMASK(24, 24)) --#define ANA_SG_CONFIG_REG_3_INIT_IPV(x) (((x) << 21) & GENMASK(23, 21)) --#define ANA_SG_CONFIG_REG_3_INIT_IPV_M GENMASK(23, 21) --#define ANA_SG_CONFIG_REG_3_INIT_IPV_X(x) (((x) & GENMASK(23, 21)) >> 21) --#define ANA_SG_CONFIG_REG_3_INIT_GATE_STATE BIT(25) -- --#define ANA_SG_GCL_GS_CONFIG_RSZ 0x4 -- --#define ANA_SG_GCL_GS_CONFIG_IPS(x) ((x) & GENMASK(3, 0)) --#define ANA_SG_GCL_GS_CONFIG_IPS_M GENMASK(3, 0) --#define ANA_SG_GCL_GS_CONFIG_IPV_VALID BIT(3) --#define ANA_SG_GCL_GS_CONFIG_IPV(x) ((x) & GENMASK(2, 0)) --#define ANA_SG_GCL_GS_CONFIG_IPV_M GENMASK(2, 0) --#define ANA_SG_GCL_GS_CONFIG_GATE_STATE BIT(4) -- --#define ANA_SG_GCL_TI_CONFIG_RSZ 0x4 -- --#define ANA_SG_STATUS_REG_3_CFG_CHG_TIME_SEC_MSB(x) ((x) & GENMASK(15, 0)) --#define ANA_SG_STATUS_REG_3_CFG_CHG_TIME_SEC_MSB_M GENMASK(15, 0) --#define ANA_SG_STATUS_REG_3_GATE_STATE BIT(16) --#define ANA_SG_STATUS_REG_3_IPS(x) (((x) << 20) & GENMASK(23, 20)) --#define ANA_SG_STATUS_REG_3_IPS_M GENMASK(23, 20) --#define ANA_SG_STATUS_REG_3_IPS_X(x) (((x) & GENMASK(23, 20)) >> 20) --#define ANA_SG_STATUS_REG_3_IPV_VALID BIT(23) --#define ANA_SG_STATUS_REG_3_IPV(x) (((x) << 20) & GENMASK(22, 20)) --#define ANA_SG_STATUS_REG_3_IPV_M GENMASK(22, 20) --#define ANA_SG_STATUS_REG_3_IPV_X(x) (((x) & GENMASK(22, 20)) >> 20) --#define ANA_SG_STATUS_REG_3_CONFIG_PENDING BIT(24) -- --#define ANA_PORT_VLAN_CFG_GSZ 0x100 -- --#define ANA_PORT_VLAN_CFG_VLAN_VID_AS_ISDX BIT(21) --#define ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA BIT(20) --#define ANA_PORT_VLAN_CFG_VLAN_POP_CNT(x) (((x) << 18) & GENMASK(19, 18)) --#define ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M GENMASK(19, 18) --#define ANA_PORT_VLAN_CFG_VLAN_POP_CNT_X(x) (((x) & GENMASK(19, 18)) >> 18) --#define ANA_PORT_VLAN_CFG_VLAN_INNER_TAG_ENA BIT(17) --#define ANA_PORT_VLAN_CFG_VLAN_TAG_TYPE BIT(16) --#define ANA_PORT_VLAN_CFG_VLAN_DEI BIT(15) --#define ANA_PORT_VLAN_CFG_VLAN_PCP(x) (((x) << 12) & GENMASK(14, 12)) --#define ANA_PORT_VLAN_CFG_VLAN_PCP_M GENMASK(14, 12) --#define ANA_PORT_VLAN_CFG_VLAN_PCP_X(x) (((x) & GENMASK(14, 12)) >> 12) --#define ANA_PORT_VLAN_CFG_VLAN_VID(x) ((x) & GENMASK(11, 0)) --#define ANA_PORT_VLAN_CFG_VLAN_VID_M GENMASK(11, 0) -- --#define ANA_PORT_DROP_CFG_GSZ 0x100 -- --#define ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA BIT(6) --#define ANA_PORT_DROP_CFG_DROP_S_TAGGED_ENA BIT(5) --#define ANA_PORT_DROP_CFG_DROP_C_TAGGED_ENA BIT(4) --#define ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA BIT(3) --#define ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA BIT(2) --#define ANA_PORT_DROP_CFG_DROP_NULL_MAC_ENA BIT(1) --#define ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA BIT(0) -- --#define ANA_PORT_QOS_CFG_GSZ 0x100 -- --#define ANA_PORT_QOS_CFG_DP_DEFAULT_VAL BIT(8) --#define ANA_PORT_QOS_CFG_QOS_DEFAULT_VAL(x) (((x) << 5) & GENMASK(7, 5)) --#define ANA_PORT_QOS_CFG_QOS_DEFAULT_VAL_M GENMASK(7, 5) --#define ANA_PORT_QOS_CFG_QOS_DEFAULT_VAL_X(x) (((x) & GENMASK(7, 5)) >> 5) --#define ANA_PORT_QOS_CFG_QOS_DSCP_ENA BIT(4) --#define ANA_PORT_QOS_CFG_QOS_PCP_ENA BIT(3) --#define ANA_PORT_QOS_CFG_DSCP_TRANSLATE_ENA BIT(2) --#define ANA_PORT_QOS_CFG_DSCP_REWR_CFG(x) ((x) & GENMASK(1, 0)) --#define ANA_PORT_QOS_CFG_DSCP_REWR_CFG_M GENMASK(1, 0) -- --#define ANA_PORT_VCAP_CFG_GSZ 0x100 -- --#define ANA_PORT_VCAP_CFG_S1_ENA BIT(14) --#define ANA_PORT_VCAP_CFG_S1_DMAC_DIP_ENA(x) (((x) << 11) & GENMASK(13, 11)) --#define ANA_PORT_VCAP_CFG_S1_DMAC_DIP_ENA_M GENMASK(13, 11) --#define ANA_PORT_VCAP_CFG_S1_DMAC_DIP_ENA_X(x) (((x) & GENMASK(13, 11)) >> 11) --#define ANA_PORT_VCAP_CFG_S1_VLAN_INNER_TAG_ENA(x) (((x) << 8) & GENMASK(10, 8)) --#define ANA_PORT_VCAP_CFG_S1_VLAN_INNER_TAG_ENA_M GENMASK(10, 8) --#define ANA_PORT_VCAP_CFG_S1_VLAN_INNER_TAG_ENA_X(x) (((x) & GENMASK(10, 8)) >> 8) --#define ANA_PORT_VCAP_CFG_PAG_VAL(x) ((x) & GENMASK(7, 0)) --#define ANA_PORT_VCAP_CFG_PAG_VAL_M GENMASK(7, 0) -- --#define ANA_PORT_VCAP_S1_KEY_CFG_GSZ 0x100 --#define ANA_PORT_VCAP_S1_KEY_CFG_RSZ 0x4 -- --#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP6_CFG(x) (((x) << 4) & GENMASK(6, 4)) --#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP6_CFG_M GENMASK(6, 4) --#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP6_CFG_X(x) (((x) & GENMASK(6, 4)) >> 4) --#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP4_CFG(x) (((x) << 2) & GENMASK(3, 2)) --#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP4_CFG_M GENMASK(3, 2) --#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP4_CFG_X(x) (((x) & GENMASK(3, 2)) >> 2) --#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_OTHER_CFG(x) ((x) & GENMASK(1, 0)) --#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_OTHER_CFG_M GENMASK(1, 0) -- --#define ANA_PORT_VCAP_S2_CFG_GSZ 0x100 -- --#define ANA_PORT_VCAP_S2_CFG_S2_UDP_PAYLOAD_ENA(x) (((x) << 17) & GENMASK(18, 17)) --#define ANA_PORT_VCAP_S2_CFG_S2_UDP_PAYLOAD_ENA_M GENMASK(18, 17) --#define ANA_PORT_VCAP_S2_CFG_S2_UDP_PAYLOAD_ENA_X(x) (((x) & GENMASK(18, 17)) >> 17) --#define ANA_PORT_VCAP_S2_CFG_S2_ETYPE_PAYLOAD_ENA(x) (((x) << 15) & GENMASK(16, 15)) --#define ANA_PORT_VCAP_S2_CFG_S2_ETYPE_PAYLOAD_ENA_M GENMASK(16, 15) --#define ANA_PORT_VCAP_S2_CFG_S2_ETYPE_PAYLOAD_ENA_X(x) (((x) & GENMASK(16, 15)) >> 15) --#define ANA_PORT_VCAP_S2_CFG_S2_ENA BIT(14) --#define ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS(x) (((x) << 12) & GENMASK(13, 12)) --#define ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS_M GENMASK(13, 12) --#define ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS_X(x) (((x) & GENMASK(13, 12)) >> 12) --#define ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS(x) (((x) << 10) & GENMASK(11, 10)) --#define ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS_M GENMASK(11, 10) --#define ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS_X(x) (((x) & GENMASK(11, 10)) >> 10) --#define ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS(x) (((x) << 8) & GENMASK(9, 8)) --#define ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS_M GENMASK(9, 8) --#define ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS_X(x) (((x) & GENMASK(9, 8)) >> 8) --#define ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS(x) (((x) << 6) & GENMASK(7, 6)) --#define ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS_M GENMASK(7, 6) --#define ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS_X(x) (((x) & GENMASK(7, 6)) >> 6) --#define ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG(x) (((x) << 2) & GENMASK(5, 2)) --#define ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG_M GENMASK(5, 2) --#define ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG_X(x) (((x) & GENMASK(5, 2)) >> 2) --#define ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS(x) ((x) & GENMASK(1, 0)) --#define ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS_M GENMASK(1, 0) -- --#define ANA_PORT_PCP_DEI_MAP_GSZ 0x100 --#define ANA_PORT_PCP_DEI_MAP_RSZ 0x4 -- --#define ANA_PORT_PCP_DEI_MAP_DP_PCP_DEI_VAL BIT(3) --#define ANA_PORT_PCP_DEI_MAP_QOS_PCP_DEI_VAL(x) ((x) & GENMASK(2, 0)) --#define ANA_PORT_PCP_DEI_MAP_QOS_PCP_DEI_VAL_M GENMASK(2, 0) -- --#define ANA_PORT_CPU_FWD_CFG_GSZ 0x100 -- --#define ANA_PORT_CPU_FWD_CFG_CPU_VRAP_REDIR_ENA BIT(7) --#define ANA_PORT_CPU_FWD_CFG_CPU_MLD_REDIR_ENA BIT(6) --#define ANA_PORT_CPU_FWD_CFG_CPU_IGMP_REDIR_ENA BIT(5) --#define ANA_PORT_CPU_FWD_CFG_CPU_IPMC_CTRL_COPY_ENA BIT(4) --#define ANA_PORT_CPU_FWD_CFG_CPU_SRC_COPY_ENA BIT(3) --#define ANA_PORT_CPU_FWD_CFG_CPU_ALLBRIDGE_DROP_ENA BIT(2) --#define ANA_PORT_CPU_FWD_CFG_CPU_ALLBRIDGE_REDIR_ENA BIT(1) --#define ANA_PORT_CPU_FWD_CFG_CPU_OAM_ENA BIT(0) -- --#define ANA_PORT_CPU_FWD_BPDU_CFG_GSZ 0x100 -- --#define ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_DROP_ENA(x) (((x) << 16) & GENMASK(31, 16)) --#define ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_DROP_ENA_M GENMASK(31, 16) --#define ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_DROP_ENA_X(x) (((x) & GENMASK(31, 16)) >> 16) --#define ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(x) ((x) & GENMASK(15, 0)) --#define ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA_M GENMASK(15, 0) -- --#define ANA_PORT_CPU_FWD_GARP_CFG_GSZ 0x100 -- --#define ANA_PORT_CPU_FWD_GARP_CFG_GARP_DROP_ENA(x) (((x) << 16) & GENMASK(31, 16)) --#define ANA_PORT_CPU_FWD_GARP_CFG_GARP_DROP_ENA_M GENMASK(31, 16) --#define ANA_PORT_CPU_FWD_GARP_CFG_GARP_DROP_ENA_X(x) (((x) & GENMASK(31, 16)) >> 16) --#define ANA_PORT_CPU_FWD_GARP_CFG_GARP_REDIR_ENA(x) ((x) & GENMASK(15, 0)) --#define ANA_PORT_CPU_FWD_GARP_CFG_GARP_REDIR_ENA_M GENMASK(15, 0) -- --#define ANA_PORT_CPU_FWD_CCM_CFG_GSZ 0x100 -- --#define ANA_PORT_CPU_FWD_CCM_CFG_CCM_DROP_ENA(x) (((x) << 16) & GENMASK(31, 16)) --#define ANA_PORT_CPU_FWD_CCM_CFG_CCM_DROP_ENA_M GENMASK(31, 16) --#define ANA_PORT_CPU_FWD_CCM_CFG_CCM_DROP_ENA_X(x) (((x) & GENMASK(31, 16)) >> 16) --#define ANA_PORT_CPU_FWD_CCM_CFG_CCM_REDIR_ENA(x) ((x) & GENMASK(15, 0)) --#define ANA_PORT_CPU_FWD_CCM_CFG_CCM_REDIR_ENA_M GENMASK(15, 0) -- --#define ANA_PORT_PORT_CFG_GSZ 0x100 -- --#define ANA_PORT_PORT_CFG_SRC_MIRROR_ENA BIT(15) --#define ANA_PORT_PORT_CFG_LIMIT_DROP BIT(14) --#define ANA_PORT_PORT_CFG_LIMIT_CPU BIT(13) --#define ANA_PORT_PORT_CFG_LOCKED_PORTMOVE_DROP BIT(12) --#define ANA_PORT_PORT_CFG_LOCKED_PORTMOVE_CPU BIT(11) --#define ANA_PORT_PORT_CFG_LEARNDROP BIT(10) --#define ANA_PORT_PORT_CFG_LEARNCPU BIT(9) --#define ANA_PORT_PORT_CFG_LEARNAUTO BIT(8) --#define ANA_PORT_PORT_CFG_LEARN_ENA BIT(7) --#define ANA_PORT_PORT_CFG_RECV_ENA BIT(6) --#define ANA_PORT_PORT_CFG_PORTID_VAL(x) (((x) << 2) & GENMASK(5, 2)) --#define ANA_PORT_PORT_CFG_PORTID_VAL_M GENMASK(5, 2) --#define ANA_PORT_PORT_CFG_PORTID_VAL_X(x) (((x) & GENMASK(5, 2)) >> 2) --#define ANA_PORT_PORT_CFG_USE_B_DOM_TBL BIT(1) --#define ANA_PORT_PORT_CFG_LSR_MODE BIT(0) -- --#define ANA_PORT_POL_CFG_GSZ 0x100 -- --#define ANA_PORT_POL_CFG_POL_CPU_REDIR_8021 BIT(19) --#define ANA_PORT_POL_CFG_POL_CPU_REDIR_IP BIT(18) --#define ANA_PORT_POL_CFG_PORT_POL_ENA BIT(17) --#define ANA_PORT_POL_CFG_QUEUE_POL_ENA(x) (((x) << 9) & GENMASK(16, 9)) --#define ANA_PORT_POL_CFG_QUEUE_POL_ENA_M GENMASK(16, 9) --#define ANA_PORT_POL_CFG_QUEUE_POL_ENA_X(x) (((x) & GENMASK(16, 9)) >> 9) --#define ANA_PORT_POL_CFG_POL_ORDER(x) ((x) & GENMASK(8, 0)) --#define ANA_PORT_POL_CFG_POL_ORDER_M GENMASK(8, 0) -- --#define ANA_PORT_PTP_CFG_GSZ 0x100 -- --#define ANA_PORT_PTP_CFG_PTP_BACKPLANE_MODE BIT(0) -- --#define ANA_PORT_PTP_DLY1_CFG_GSZ 0x100 -- --#define ANA_PORT_PTP_DLY2_CFG_GSZ 0x100 -- --#define ANA_PORT_SFID_CFG_GSZ 0x100 --#define ANA_PORT_SFID_CFG_RSZ 0x4 -- --#define ANA_PORT_SFID_CFG_SFID_VALID BIT(8) --#define ANA_PORT_SFID_CFG_SFID(x) ((x) & GENMASK(7, 0)) --#define ANA_PORT_SFID_CFG_SFID_M GENMASK(7, 0) -- --#define ANA_PFC_PFC_CFG_GSZ 0x40 -- --#define ANA_PFC_PFC_CFG_RX_PFC_ENA(x) (((x) << 2) & GENMASK(9, 2)) --#define ANA_PFC_PFC_CFG_RX_PFC_ENA_M GENMASK(9, 2) --#define ANA_PFC_PFC_CFG_RX_PFC_ENA_X(x) (((x) & GENMASK(9, 2)) >> 2) --#define ANA_PFC_PFC_CFG_FC_LINK_SPEED(x) ((x) & GENMASK(1, 0)) --#define ANA_PFC_PFC_CFG_FC_LINK_SPEED_M GENMASK(1, 0) -- --#define ANA_PFC_PFC_TIMER_GSZ 0x40 --#define ANA_PFC_PFC_TIMER_RSZ 0x4 -- --#define ANA_IPT_OAM_MEP_CFG_GSZ 0x8 -- --#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_P(x) (((x) << 6) & GENMASK(10, 6)) --#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_P_M GENMASK(10, 6) --#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_P_X(x) (((x) & GENMASK(10, 6)) >> 6) --#define ANA_IPT_OAM_MEP_CFG_MEP_IDX(x) (((x) << 1) & GENMASK(5, 1)) --#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_M GENMASK(5, 1) --#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_X(x) (((x) & GENMASK(5, 1)) >> 1) --#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_ENA BIT(0) -- --#define ANA_IPT_IPT_GSZ 0x8 -- --#define ANA_IPT_IPT_IPT_CFG(x) (((x) << 15) & GENMASK(16, 15)) --#define ANA_IPT_IPT_IPT_CFG_M GENMASK(16, 15) --#define ANA_IPT_IPT_IPT_CFG_X(x) (((x) & GENMASK(16, 15)) >> 15) --#define ANA_IPT_IPT_ISDX_P(x) (((x) << 7) & GENMASK(14, 7)) --#define ANA_IPT_IPT_ISDX_P_M GENMASK(14, 7) --#define ANA_IPT_IPT_ISDX_P_X(x) (((x) & GENMASK(14, 7)) >> 7) --#define ANA_IPT_IPT_PPT_IDX(x) ((x) & GENMASK(6, 0)) --#define ANA_IPT_IPT_PPT_IDX_M GENMASK(6, 0) -- --#define ANA_PPT_PPT_RSZ 0x4 -- --#define ANA_FID_MAP_FID_MAP_RSZ 0x4 -- --#define ANA_FID_MAP_FID_MAP_FID_C_VAL(x) (((x) << 6) & GENMASK(11, 6)) --#define ANA_FID_MAP_FID_MAP_FID_C_VAL_M GENMASK(11, 6) --#define ANA_FID_MAP_FID_MAP_FID_C_VAL_X(x) (((x) & GENMASK(11, 6)) >> 6) --#define ANA_FID_MAP_FID_MAP_FID_B_VAL(x) ((x) & GENMASK(5, 0)) --#define ANA_FID_MAP_FID_MAP_FID_B_VAL_M GENMASK(5, 0) -- --#define ANA_AGGR_CFG_AC_RND_ENA BIT(7) --#define ANA_AGGR_CFG_AC_DMAC_ENA BIT(6) --#define ANA_AGGR_CFG_AC_SMAC_ENA BIT(5) --#define ANA_AGGR_CFG_AC_IP6_FLOW_LBL_ENA BIT(4) --#define ANA_AGGR_CFG_AC_IP6_TCPUDP_ENA BIT(3) --#define ANA_AGGR_CFG_AC_IP4_SIPDIP_ENA BIT(2) --#define ANA_AGGR_CFG_AC_IP4_TCPUDP_ENA BIT(1) --#define ANA_AGGR_CFG_AC_ISDX_ENA BIT(0) -- --#define ANA_CPUQ_CFG_CPUQ_MLD(x) (((x) << 27) & GENMASK(29, 27)) --#define ANA_CPUQ_CFG_CPUQ_MLD_M GENMASK(29, 27) --#define ANA_CPUQ_CFG_CPUQ_MLD_X(x) (((x) & GENMASK(29, 27)) >> 27) --#define ANA_CPUQ_CFG_CPUQ_IGMP(x) (((x) << 24) & GENMASK(26, 24)) --#define ANA_CPUQ_CFG_CPUQ_IGMP_M GENMASK(26, 24) --#define ANA_CPUQ_CFG_CPUQ_IGMP_X(x) (((x) & GENMASK(26, 24)) >> 24) --#define ANA_CPUQ_CFG_CPUQ_IPMC_CTRL(x) (((x) << 21) & GENMASK(23, 21)) --#define ANA_CPUQ_CFG_CPUQ_IPMC_CTRL_M GENMASK(23, 21) --#define ANA_CPUQ_CFG_CPUQ_IPMC_CTRL_X(x) (((x) & GENMASK(23, 21)) >> 21) --#define ANA_CPUQ_CFG_CPUQ_ALLBRIDGE(x) (((x) << 18) & GENMASK(20, 18)) --#define ANA_CPUQ_CFG_CPUQ_ALLBRIDGE_M GENMASK(20, 18) --#define ANA_CPUQ_CFG_CPUQ_ALLBRIDGE_X(x) (((x) & GENMASK(20, 18)) >> 18) --#define ANA_CPUQ_CFG_CPUQ_LOCKED_PORTMOVE(x) (((x) << 15) & GENMASK(17, 15)) --#define ANA_CPUQ_CFG_CPUQ_LOCKED_PORTMOVE_M GENMASK(17, 15) --#define ANA_CPUQ_CFG_CPUQ_LOCKED_PORTMOVE_X(x) (((x) & GENMASK(17, 15)) >> 15) --#define ANA_CPUQ_CFG_CPUQ_SRC_COPY(x) (((x) << 12) & GENMASK(14, 12)) --#define ANA_CPUQ_CFG_CPUQ_SRC_COPY_M GENMASK(14, 12) --#define ANA_CPUQ_CFG_CPUQ_SRC_COPY_X(x) (((x) & GENMASK(14, 12)) >> 12) --#define ANA_CPUQ_CFG_CPUQ_MAC_COPY(x) (((x) << 9) & GENMASK(11, 9)) --#define ANA_CPUQ_CFG_CPUQ_MAC_COPY_M GENMASK(11, 9) --#define ANA_CPUQ_CFG_CPUQ_MAC_COPY_X(x) (((x) & GENMASK(11, 9)) >> 9) --#define ANA_CPUQ_CFG_CPUQ_LRN(x) (((x) << 6) & GENMASK(8, 6)) --#define ANA_CPUQ_CFG_CPUQ_LRN_M GENMASK(8, 6) --#define ANA_CPUQ_CFG_CPUQ_LRN_X(x) (((x) & GENMASK(8, 6)) >> 6) --#define ANA_CPUQ_CFG_CPUQ_MIRROR(x) (((x) << 3) & GENMASK(5, 3)) --#define ANA_CPUQ_CFG_CPUQ_MIRROR_M GENMASK(5, 3) --#define ANA_CPUQ_CFG_CPUQ_MIRROR_X(x) (((x) & GENMASK(5, 3)) >> 3) --#define ANA_CPUQ_CFG_CPUQ_SFLOW(x) ((x) & GENMASK(2, 0)) --#define ANA_CPUQ_CFG_CPUQ_SFLOW_M GENMASK(2, 0) -- --#define ANA_CPUQ_8021_CFG_RSZ 0x4 -- --#define ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL(x) (((x) << 6) & GENMASK(8, 6)) --#define ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL_M GENMASK(8, 6) --#define ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL_X(x) (((x) & GENMASK(8, 6)) >> 6) --#define ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL(x) (((x) << 3) & GENMASK(5, 3)) --#define ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL_M GENMASK(5, 3) --#define ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL_X(x) (((x) & GENMASK(5, 3)) >> 3) --#define ANA_CPUQ_8021_CFG_CPUQ_CCM_VAL(x) ((x) & GENMASK(2, 0)) --#define ANA_CPUQ_8021_CFG_CPUQ_CCM_VAL_M GENMASK(2, 0) -- --#define ANA_DSCP_CFG_RSZ 0x4 -- --#define ANA_DSCP_CFG_DP_DSCP_VAL BIT(11) --#define ANA_DSCP_CFG_QOS_DSCP_VAL(x) (((x) << 8) & GENMASK(10, 8)) --#define ANA_DSCP_CFG_QOS_DSCP_VAL_M GENMASK(10, 8) --#define ANA_DSCP_CFG_QOS_DSCP_VAL_X(x) (((x) & GENMASK(10, 8)) >> 8) --#define ANA_DSCP_CFG_DSCP_TRANSLATE_VAL(x) (((x) << 2) & GENMASK(7, 2)) --#define ANA_DSCP_CFG_DSCP_TRANSLATE_VAL_M GENMASK(7, 2) --#define ANA_DSCP_CFG_DSCP_TRANSLATE_VAL_X(x) (((x) & GENMASK(7, 2)) >> 2) --#define ANA_DSCP_CFG_DSCP_TRUST_ENA BIT(1) --#define ANA_DSCP_CFG_DSCP_REWR_ENA BIT(0) -- --#define ANA_DSCP_REWR_CFG_RSZ 0x4 -- --#define ANA_VCAP_RNG_TYPE_CFG_RSZ 0x4 -- --#define ANA_VCAP_RNG_VAL_CFG_RSZ 0x4 -- --#define ANA_VCAP_RNG_VAL_CFG_VCAP_RNG_MIN_VAL(x) (((x) << 16) & GENMASK(31, 16)) --#define ANA_VCAP_RNG_VAL_CFG_VCAP_RNG_MIN_VAL_M GENMASK(31, 16) --#define ANA_VCAP_RNG_VAL_CFG_VCAP_RNG_MIN_VAL_X(x) (((x) & GENMASK(31, 16)) >> 16) --#define ANA_VCAP_RNG_VAL_CFG_VCAP_RNG_MAX_VAL(x) ((x) & GENMASK(15, 0)) --#define ANA_VCAP_RNG_VAL_CFG_VCAP_RNG_MAX_VAL_M GENMASK(15, 0) -- --#define ANA_VRAP_CFG_VRAP_VLAN_AWARE_ENA BIT(12) --#define ANA_VRAP_CFG_VRAP_VID(x) ((x) & GENMASK(11, 0)) --#define ANA_VRAP_CFG_VRAP_VID_M GENMASK(11, 0) -- --#define ANA_DISCARD_CFG_DROP_TAGGING_ISDX0 BIT(3) --#define ANA_DISCARD_CFG_DROP_CTRLPROT_ISDX0 BIT(2) --#define ANA_DISCARD_CFG_DROP_TAGGING_S2_ENA BIT(1) --#define ANA_DISCARD_CFG_DROP_CTRLPROT_S2_ENA BIT(0) -- --#define ANA_FID_CFG_VID_MC_ENA BIT(0) -- --#define ANA_POL_PIR_CFG_GSZ 0x20 -- --#define ANA_POL_PIR_CFG_PIR_RATE(x) (((x) << 6) & GENMASK(20, 6)) --#define ANA_POL_PIR_CFG_PIR_RATE_M GENMASK(20, 6) --#define ANA_POL_PIR_CFG_PIR_RATE_X(x) (((x) & GENMASK(20, 6)) >> 6) --#define ANA_POL_PIR_CFG_PIR_BURST(x) ((x) & GENMASK(5, 0)) --#define ANA_POL_PIR_CFG_PIR_BURST_M GENMASK(5, 0) -- --#define ANA_POL_CIR_CFG_GSZ 0x20 -- --#define ANA_POL_CIR_CFG_CIR_RATE(x) (((x) << 6) & GENMASK(20, 6)) --#define ANA_POL_CIR_CFG_CIR_RATE_M GENMASK(20, 6) --#define ANA_POL_CIR_CFG_CIR_RATE_X(x) (((x) & GENMASK(20, 6)) >> 6) --#define ANA_POL_CIR_CFG_CIR_BURST(x) ((x) & GENMASK(5, 0)) --#define ANA_POL_CIR_CFG_CIR_BURST_M GENMASK(5, 0) -- --#define ANA_POL_MODE_CFG_GSZ 0x20 -- --#define ANA_POL_MODE_CFG_IPG_SIZE(x) (((x) << 5) & GENMASK(9, 5)) --#define ANA_POL_MODE_CFG_IPG_SIZE_M GENMASK(9, 5) --#define ANA_POL_MODE_CFG_IPG_SIZE_X(x) (((x) & GENMASK(9, 5)) >> 5) --#define ANA_POL_MODE_CFG_FRM_MODE(x) (((x) << 3) & GENMASK(4, 3)) --#define ANA_POL_MODE_CFG_FRM_MODE_M GENMASK(4, 3) --#define ANA_POL_MODE_CFG_FRM_MODE_X(x) (((x) & GENMASK(4, 3)) >> 3) --#define ANA_POL_MODE_CFG_DLB_COUPLED BIT(2) --#define ANA_POL_MODE_CFG_CIR_ENA BIT(1) --#define ANA_POL_MODE_CFG_OVERSHOOT_ENA BIT(0) -- --#define ANA_POL_PIR_STATE_GSZ 0x20 -- --#define ANA_POL_CIR_STATE_GSZ 0x20 -- --#define ANA_POL_STATE_GSZ 0x20 -- --#define ANA_POL_FLOWC_RSZ 0x4 -- --#define ANA_POL_FLOWC_POL_FLOWC BIT(0) -- --#define ANA_POL_HYST_POL_FC_HYST(x) (((x) << 4) & GENMASK(9, 4)) --#define ANA_POL_HYST_POL_FC_HYST_M GENMASK(9, 4) --#define ANA_POL_HYST_POL_FC_HYST_X(x) (((x) & GENMASK(9, 4)) >> 4) --#define ANA_POL_HYST_POL_STOP_HYST(x) ((x) & GENMASK(3, 0)) --#define ANA_POL_HYST_POL_STOP_HYST_M GENMASK(3, 0) -- --#define ANA_POL_MISC_CFG_POL_CLOSE_ALL BIT(1) --#define ANA_POL_MISC_CFG_POL_LEAK_DIS BIT(0) -- --#endif ---- a/drivers/net/ethernet/mscc/ocelot_dev.h -+++ /dev/null -@@ -1,275 +0,0 @@ --/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ --/* -- * Microsemi Ocelot Switch driver -- * -- * Copyright (c) 2017 Microsemi Corporation -- */ -- --#ifndef _MSCC_OCELOT_DEV_H_ --#define _MSCC_OCELOT_DEV_H_ -- --#define DEV_CLOCK_CFG 0x0 -- --#define DEV_CLOCK_CFG_MAC_TX_RST BIT(7) --#define DEV_CLOCK_CFG_MAC_RX_RST BIT(6) --#define DEV_CLOCK_CFG_PCS_TX_RST BIT(5) --#define DEV_CLOCK_CFG_PCS_RX_RST BIT(4) --#define DEV_CLOCK_CFG_PORT_RST BIT(3) --#define DEV_CLOCK_CFG_PHY_RST BIT(2) --#define DEV_CLOCK_CFG_LINK_SPEED(x) ((x) & GENMASK(1, 0)) --#define DEV_CLOCK_CFG_LINK_SPEED_M GENMASK(1, 0) -- --#define DEV_PORT_MISC 0x4 -- --#define DEV_PORT_MISC_FWD_ERROR_ENA BIT(4) --#define DEV_PORT_MISC_FWD_PAUSE_ENA BIT(3) --#define DEV_PORT_MISC_FWD_CTRL_ENA BIT(2) --#define DEV_PORT_MISC_DEV_LOOP_ENA BIT(1) --#define DEV_PORT_MISC_HDX_FAST_DIS BIT(0) -- --#define DEV_EVENTS 0x8 -- --#define DEV_EEE_CFG 0xc -- --#define DEV_EEE_CFG_EEE_ENA BIT(22) --#define DEV_EEE_CFG_EEE_TIMER_AGE(x) (((x) << 15) & GENMASK(21, 15)) --#define DEV_EEE_CFG_EEE_TIMER_AGE_M GENMASK(21, 15) --#define DEV_EEE_CFG_EEE_TIMER_AGE_X(x) (((x) & GENMASK(21, 15)) >> 15) --#define DEV_EEE_CFG_EEE_TIMER_WAKEUP(x) (((x) << 8) & GENMASK(14, 8)) --#define DEV_EEE_CFG_EEE_TIMER_WAKEUP_M GENMASK(14, 8) --#define DEV_EEE_CFG_EEE_TIMER_WAKEUP_X(x) (((x) & GENMASK(14, 8)) >> 8) --#define DEV_EEE_CFG_EEE_TIMER_HOLDOFF(x) (((x) << 1) & GENMASK(7, 1)) --#define DEV_EEE_CFG_EEE_TIMER_HOLDOFF_M GENMASK(7, 1) --#define DEV_EEE_CFG_EEE_TIMER_HOLDOFF_X(x) (((x) & GENMASK(7, 1)) >> 1) --#define DEV_EEE_CFG_PORT_LPI BIT(0) -- --#define DEV_RX_PATH_DELAY 0x10 -- --#define DEV_TX_PATH_DELAY 0x14 -- --#define DEV_PTP_PREDICT_CFG 0x18 -- --#define DEV_PTP_PREDICT_CFG_PTP_PHY_PREDICT_CFG(x) (((x) << 4) & GENMASK(11, 4)) --#define DEV_PTP_PREDICT_CFG_PTP_PHY_PREDICT_CFG_M GENMASK(11, 4) --#define DEV_PTP_PREDICT_CFG_PTP_PHY_PREDICT_CFG_X(x) (((x) & GENMASK(11, 4)) >> 4) --#define DEV_PTP_PREDICT_CFG_PTP_PHASE_PREDICT_CFG(x) ((x) & GENMASK(3, 0)) --#define DEV_PTP_PREDICT_CFG_PTP_PHASE_PREDICT_CFG_M GENMASK(3, 0) -- --#define DEV_MAC_ENA_CFG 0x1c -- --#define DEV_MAC_ENA_CFG_RX_ENA BIT(4) --#define DEV_MAC_ENA_CFG_TX_ENA BIT(0) -- --#define DEV_MAC_MODE_CFG 0x20 -- --#define DEV_MAC_MODE_CFG_FC_WORD_SYNC_ENA BIT(8) --#define DEV_MAC_MODE_CFG_GIGA_MODE_ENA BIT(4) --#define DEV_MAC_MODE_CFG_FDX_ENA BIT(0) -- --#define DEV_MAC_MAXLEN_CFG 0x24 -- --#define DEV_MAC_TAGS_CFG 0x28 -- --#define DEV_MAC_TAGS_CFG_TAG_ID(x) (((x) << 16) & GENMASK(31, 16)) --#define DEV_MAC_TAGS_CFG_TAG_ID_M GENMASK(31, 16) --#define DEV_MAC_TAGS_CFG_TAG_ID_X(x) (((x) & GENMASK(31, 16)) >> 16) --#define DEV_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA BIT(2) --#define DEV_MAC_TAGS_CFG_PB_ENA BIT(1) --#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA BIT(0) -- --#define DEV_MAC_ADV_CHK_CFG 0x2c -- --#define DEV_MAC_ADV_CHK_CFG_LEN_DROP_ENA BIT(0) -- --#define DEV_MAC_IFG_CFG 0x30 -- --#define DEV_MAC_IFG_CFG_RESTORE_OLD_IPG_CHECK BIT(17) --#define DEV_MAC_IFG_CFG_REDUCED_TX_IFG BIT(16) --#define DEV_MAC_IFG_CFG_TX_IFG(x) (((x) << 8) & GENMASK(12, 8)) --#define DEV_MAC_IFG_CFG_TX_IFG_M GENMASK(12, 8) --#define DEV_MAC_IFG_CFG_TX_IFG_X(x) (((x) & GENMASK(12, 8)) >> 8) --#define DEV_MAC_IFG_CFG_RX_IFG2(x) (((x) << 4) & GENMASK(7, 4)) --#define DEV_MAC_IFG_CFG_RX_IFG2_M GENMASK(7, 4) --#define DEV_MAC_IFG_CFG_RX_IFG2_X(x) (((x) & GENMASK(7, 4)) >> 4) --#define DEV_MAC_IFG_CFG_RX_IFG1(x) ((x) & GENMASK(3, 0)) --#define DEV_MAC_IFG_CFG_RX_IFG1_M GENMASK(3, 0) -- --#define DEV_MAC_HDX_CFG 0x34 -- --#define DEV_MAC_HDX_CFG_BYPASS_COL_SYNC BIT(26) --#define DEV_MAC_HDX_CFG_OB_ENA BIT(25) --#define DEV_MAC_HDX_CFG_WEXC_DIS BIT(24) --#define DEV_MAC_HDX_CFG_SEED(x) (((x) << 16) & GENMASK(23, 16)) --#define DEV_MAC_HDX_CFG_SEED_M GENMASK(23, 16) --#define DEV_MAC_HDX_CFG_SEED_X(x) (((x) & GENMASK(23, 16)) >> 16) --#define DEV_MAC_HDX_CFG_SEED_LOAD BIT(12) --#define DEV_MAC_HDX_CFG_RETRY_AFTER_EXC_COL_ENA BIT(8) --#define DEV_MAC_HDX_CFG_LATE_COL_POS(x) ((x) & GENMASK(6, 0)) --#define DEV_MAC_HDX_CFG_LATE_COL_POS_M GENMASK(6, 0) -- --#define DEV_MAC_DBG_CFG 0x38 -- --#define DEV_MAC_DBG_CFG_TBI_MODE BIT(4) --#define DEV_MAC_DBG_CFG_IFG_CRS_EXT_CHK_ENA BIT(0) -- --#define DEV_MAC_FC_MAC_LOW_CFG 0x3c -- --#define DEV_MAC_FC_MAC_HIGH_CFG 0x40 -- --#define DEV_MAC_STICKY 0x44 -- --#define DEV_MAC_STICKY_RX_IPG_SHRINK_STICKY BIT(9) --#define DEV_MAC_STICKY_RX_PREAM_SHRINK_STICKY BIT(8) --#define DEV_MAC_STICKY_RX_CARRIER_EXT_STICKY BIT(7) --#define DEV_MAC_STICKY_RX_CARRIER_EXT_ERR_STICKY BIT(6) --#define DEV_MAC_STICKY_RX_JUNK_STICKY BIT(5) --#define DEV_MAC_STICKY_TX_RETRANSMIT_STICKY BIT(4) --#define DEV_MAC_STICKY_TX_JAM_STICKY BIT(3) --#define DEV_MAC_STICKY_TX_FIFO_OFLW_STICKY BIT(2) --#define DEV_MAC_STICKY_TX_FRM_LEN_OVR_STICKY BIT(1) --#define DEV_MAC_STICKY_TX_ABORT_STICKY BIT(0) -- --#define PCS1G_CFG 0x48 -- --#define PCS1G_CFG_LINK_STATUS_TYPE BIT(4) --#define PCS1G_CFG_AN_LINK_CTRL_ENA BIT(1) --#define PCS1G_CFG_PCS_ENA BIT(0) -- --#define PCS1G_MODE_CFG 0x4c -- --#define PCS1G_MODE_CFG_UNIDIR_MODE_ENA BIT(4) --#define PCS1G_MODE_CFG_SGMII_MODE_ENA BIT(0) -- --#define PCS1G_SD_CFG 0x50 -- --#define PCS1G_SD_CFG_SD_SEL BIT(8) --#define PCS1G_SD_CFG_SD_POL BIT(4) --#define PCS1G_SD_CFG_SD_ENA BIT(0) -- --#define PCS1G_ANEG_CFG 0x54 -- --#define PCS1G_ANEG_CFG_ADV_ABILITY(x) (((x) << 16) & GENMASK(31, 16)) --#define PCS1G_ANEG_CFG_ADV_ABILITY_M GENMASK(31, 16) --#define PCS1G_ANEG_CFG_ADV_ABILITY_X(x) (((x) & GENMASK(31, 16)) >> 16) --#define PCS1G_ANEG_CFG_SW_RESOLVE_ENA BIT(8) --#define PCS1G_ANEG_CFG_ANEG_RESTART_ONE_SHOT BIT(1) --#define PCS1G_ANEG_CFG_ANEG_ENA BIT(0) -- --#define PCS1G_ANEG_NP_CFG 0x58 -- --#define PCS1G_ANEG_NP_CFG_NP_TX(x) (((x) << 16) & GENMASK(31, 16)) --#define PCS1G_ANEG_NP_CFG_NP_TX_M GENMASK(31, 16) --#define PCS1G_ANEG_NP_CFG_NP_TX_X(x) (((x) & GENMASK(31, 16)) >> 16) --#define PCS1G_ANEG_NP_CFG_NP_LOADED_ONE_SHOT BIT(0) -- --#define PCS1G_LB_CFG 0x5c -- --#define PCS1G_LB_CFG_RA_ENA BIT(4) --#define PCS1G_LB_CFG_GMII_PHY_LB_ENA BIT(1) --#define PCS1G_LB_CFG_TBI_HOST_LB_ENA BIT(0) -- --#define PCS1G_DBG_CFG 0x60 -- --#define PCS1G_DBG_CFG_UDLT BIT(0) -- --#define PCS1G_CDET_CFG 0x64 -- --#define PCS1G_CDET_CFG_CDET_ENA BIT(0) -- --#define PCS1G_ANEG_STATUS 0x68 -- --#define PCS1G_ANEG_STATUS_LP_ADV_ABILITY(x) (((x) << 16) & GENMASK(31, 16)) --#define PCS1G_ANEG_STATUS_LP_ADV_ABILITY_M GENMASK(31, 16) --#define PCS1G_ANEG_STATUS_LP_ADV_ABILITY_X(x) (((x) & GENMASK(31, 16)) >> 16) --#define PCS1G_ANEG_STATUS_PR BIT(4) --#define PCS1G_ANEG_STATUS_PAGE_RX_STICKY BIT(3) --#define PCS1G_ANEG_STATUS_ANEG_COMPLETE BIT(0) -- --#define PCS1G_ANEG_NP_STATUS 0x6c -- --#define PCS1G_LINK_STATUS 0x70 -- --#define PCS1G_LINK_STATUS_DELAY_VAR(x) (((x) << 12) & GENMASK(15, 12)) --#define PCS1G_LINK_STATUS_DELAY_VAR_M GENMASK(15, 12) --#define PCS1G_LINK_STATUS_DELAY_VAR_X(x) (((x) & GENMASK(15, 12)) >> 12) --#define PCS1G_LINK_STATUS_SIGNAL_DETECT BIT(8) --#define PCS1G_LINK_STATUS_LINK_STATUS BIT(4) --#define PCS1G_LINK_STATUS_SYNC_STATUS BIT(0) -- --#define PCS1G_LINK_DOWN_CNT 0x74 -- --#define PCS1G_STICKY 0x78 -- --#define PCS1G_STICKY_LINK_DOWN_STICKY BIT(4) --#define PCS1G_STICKY_OUT_OF_SYNC_STICKY BIT(0) -- --#define PCS1G_DEBUG_STATUS 0x7c -- --#define PCS1G_LPI_CFG 0x80 -- --#define PCS1G_LPI_CFG_QSGMII_MS_SEL BIT(20) --#define PCS1G_LPI_CFG_RX_LPI_OUT_DIS BIT(17) --#define PCS1G_LPI_CFG_LPI_TESTMODE BIT(16) --#define PCS1G_LPI_CFG_LPI_RX_WTIM(x) (((x) << 4) & GENMASK(5, 4)) --#define PCS1G_LPI_CFG_LPI_RX_WTIM_M GENMASK(5, 4) --#define PCS1G_LPI_CFG_LPI_RX_WTIM_X(x) (((x) & GENMASK(5, 4)) >> 4) --#define PCS1G_LPI_CFG_TX_ASSERT_LPIDLE BIT(0) -- --#define PCS1G_LPI_WAKE_ERROR_CNT 0x84 -- --#define PCS1G_LPI_STATUS 0x88 -- --#define PCS1G_LPI_STATUS_RX_LPI_FAIL BIT(16) --#define PCS1G_LPI_STATUS_RX_LPI_EVENT_STICKY BIT(12) --#define PCS1G_LPI_STATUS_RX_QUIET BIT(9) --#define PCS1G_LPI_STATUS_RX_LPI_MODE BIT(8) --#define PCS1G_LPI_STATUS_TX_LPI_EVENT_STICKY BIT(4) --#define PCS1G_LPI_STATUS_TX_QUIET BIT(1) --#define PCS1G_LPI_STATUS_TX_LPI_MODE BIT(0) -- --#define PCS1G_TSTPAT_MODE_CFG 0x8c -- --#define PCS1G_TSTPAT_STATUS 0x90 -- --#define PCS1G_TSTPAT_STATUS_JTP_ERR_CNT(x) (((x) << 8) & GENMASK(15, 8)) --#define PCS1G_TSTPAT_STATUS_JTP_ERR_CNT_M GENMASK(15, 8) --#define PCS1G_TSTPAT_STATUS_JTP_ERR_CNT_X(x) (((x) & GENMASK(15, 8)) >> 8) --#define PCS1G_TSTPAT_STATUS_JTP_ERR BIT(4) --#define PCS1G_TSTPAT_STATUS_JTP_LOCK BIT(0) -- --#define DEV_PCS_FX100_CFG 0x94 -- --#define DEV_PCS_FX100_CFG_SD_SEL BIT(26) --#define DEV_PCS_FX100_CFG_SD_POL BIT(25) --#define DEV_PCS_FX100_CFG_SD_ENA BIT(24) --#define DEV_PCS_FX100_CFG_LOOPBACK_ENA BIT(20) --#define DEV_PCS_FX100_CFG_SWAP_MII_ENA BIT(16) --#define DEV_PCS_FX100_CFG_RXBITSEL(x) (((x) << 12) & GENMASK(15, 12)) --#define DEV_PCS_FX100_CFG_RXBITSEL_M GENMASK(15, 12) --#define DEV_PCS_FX100_CFG_RXBITSEL_X(x) (((x) & GENMASK(15, 12)) >> 12) --#define DEV_PCS_FX100_CFG_SIGDET_CFG(x) (((x) << 9) & GENMASK(10, 9)) --#define DEV_PCS_FX100_CFG_SIGDET_CFG_M GENMASK(10, 9) --#define DEV_PCS_FX100_CFG_SIGDET_CFG_X(x) (((x) & GENMASK(10, 9)) >> 9) --#define DEV_PCS_FX100_CFG_LINKHYST_TM_ENA BIT(8) --#define DEV_PCS_FX100_CFG_LINKHYSTTIMER(x) (((x) << 4) & GENMASK(7, 4)) --#define DEV_PCS_FX100_CFG_LINKHYSTTIMER_M GENMASK(7, 4) --#define DEV_PCS_FX100_CFG_LINKHYSTTIMER_X(x) (((x) & GENMASK(7, 4)) >> 4) --#define DEV_PCS_FX100_CFG_UNIDIR_MODE_ENA BIT(3) --#define DEV_PCS_FX100_CFG_FEFCHK_ENA BIT(2) --#define DEV_PCS_FX100_CFG_FEFGEN_ENA BIT(1) --#define DEV_PCS_FX100_CFG_PCS_ENA BIT(0) -- --#define DEV_PCS_FX100_STATUS 0x98 -- --#define DEV_PCS_FX100_STATUS_EDGE_POS_PTP(x) (((x) << 8) & GENMASK(11, 8)) --#define DEV_PCS_FX100_STATUS_EDGE_POS_PTP_M GENMASK(11, 8) --#define DEV_PCS_FX100_STATUS_EDGE_POS_PTP_X(x) (((x) & GENMASK(11, 8)) >> 8) --#define DEV_PCS_FX100_STATUS_PCS_ERROR_STICKY BIT(7) --#define DEV_PCS_FX100_STATUS_FEF_FOUND_STICKY BIT(6) --#define DEV_PCS_FX100_STATUS_SSD_ERROR_STICKY BIT(5) --#define DEV_PCS_FX100_STATUS_SYNC_LOST_STICKY BIT(4) --#define DEV_PCS_FX100_STATUS_FEF_STATUS BIT(2) --#define DEV_PCS_FX100_STATUS_SIGNAL_DETECT BIT(1) --#define DEV_PCS_FX100_STATUS_SYNC_STATUS BIT(0) -- --#endif ---- a/drivers/net/ethernet/mscc/ocelot_qsys.h -+++ /dev/null -@@ -1,270 +0,0 @@ --/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ --/* -- * Microsemi Ocelot Switch driver -- * -- * Copyright (c) 2017 Microsemi Corporation -- */ -- --#ifndef _MSCC_OCELOT_QSYS_H_ --#define _MSCC_OCELOT_QSYS_H_ -- --#define QSYS_PORT_MODE_RSZ 0x4 -- --#define QSYS_PORT_MODE_DEQUEUE_DIS BIT(1) --#define QSYS_PORT_MODE_DEQUEUE_LATE BIT(0) -- --#define QSYS_SWITCH_PORT_MODE_RSZ 0x4 -- --#define QSYS_SWITCH_PORT_MODE_PORT_ENA BIT(14) --#define QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(x) (((x) << 11) & GENMASK(13, 11)) --#define QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG_M GENMASK(13, 11) --#define QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG_X(x) (((x) & GENMASK(13, 11)) >> 11) --#define QSYS_SWITCH_PORT_MODE_YEL_RSRVD BIT(10) --#define QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE BIT(9) --#define QSYS_SWITCH_PORT_MODE_TX_PFC_ENA(x) (((x) << 1) & GENMASK(8, 1)) --#define QSYS_SWITCH_PORT_MODE_TX_PFC_ENA_M GENMASK(8, 1) --#define QSYS_SWITCH_PORT_MODE_TX_PFC_ENA_X(x) (((x) & GENMASK(8, 1)) >> 1) --#define QSYS_SWITCH_PORT_MODE_TX_PFC_MODE BIT(0) -- --#define QSYS_STAT_CNT_CFG_TX_GREEN_CNT_MODE BIT(5) --#define QSYS_STAT_CNT_CFG_TX_YELLOW_CNT_MODE BIT(4) --#define QSYS_STAT_CNT_CFG_DROP_GREEN_CNT_MODE BIT(3) --#define QSYS_STAT_CNT_CFG_DROP_YELLOW_CNT_MODE BIT(2) --#define QSYS_STAT_CNT_CFG_DROP_COUNT_ONCE BIT(1) --#define QSYS_STAT_CNT_CFG_DROP_COUNT_EGRESS BIT(0) -- --#define QSYS_EEE_CFG_RSZ 0x4 -- --#define QSYS_EEE_THRES_EEE_HIGH_BYTES(x) (((x) << 8) & GENMASK(15, 8)) --#define QSYS_EEE_THRES_EEE_HIGH_BYTES_M GENMASK(15, 8) --#define QSYS_EEE_THRES_EEE_HIGH_BYTES_X(x) (((x) & GENMASK(15, 8)) >> 8) --#define QSYS_EEE_THRES_EEE_HIGH_FRAMES(x) ((x) & GENMASK(7, 0)) --#define QSYS_EEE_THRES_EEE_HIGH_FRAMES_M GENMASK(7, 0) -- --#define QSYS_SW_STATUS_RSZ 0x4 -- --#define QSYS_EXT_CPU_CFG_EXT_CPU_PORT(x) (((x) << 8) & GENMASK(12, 8)) --#define QSYS_EXT_CPU_CFG_EXT_CPU_PORT_M GENMASK(12, 8) --#define QSYS_EXT_CPU_CFG_EXT_CPU_PORT_X(x) (((x) & GENMASK(12, 8)) >> 8) --#define QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK(x) ((x) & GENMASK(7, 0)) --#define QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M GENMASK(7, 0) -- --#define QSYS_QMAP_GSZ 0x4 -- --#define QSYS_QMAP_SE_BASE(x) (((x) << 5) & GENMASK(12, 5)) --#define QSYS_QMAP_SE_BASE_M GENMASK(12, 5) --#define QSYS_QMAP_SE_BASE_X(x) (((x) & GENMASK(12, 5)) >> 5) --#define QSYS_QMAP_SE_IDX_SEL(x) (((x) << 2) & GENMASK(4, 2)) --#define QSYS_QMAP_SE_IDX_SEL_M GENMASK(4, 2) --#define QSYS_QMAP_SE_IDX_SEL_X(x) (((x) & GENMASK(4, 2)) >> 2) --#define QSYS_QMAP_SE_INP_SEL(x) ((x) & GENMASK(1, 0)) --#define QSYS_QMAP_SE_INP_SEL_M GENMASK(1, 0) -- --#define QSYS_ISDX_SGRP_GSZ 0x4 -- --#define QSYS_TIMED_FRAME_ENTRY_GSZ 0x4 -- --#define QSYS_TFRM_MISC_TIMED_CANCEL_SLOT(x) (((x) << 9) & GENMASK(18, 9)) --#define QSYS_TFRM_MISC_TIMED_CANCEL_SLOT_M GENMASK(18, 9) --#define QSYS_TFRM_MISC_TIMED_CANCEL_SLOT_X(x) (((x) & GENMASK(18, 9)) >> 9) --#define QSYS_TFRM_MISC_TIMED_CANCEL_1SHOT BIT(8) --#define QSYS_TFRM_MISC_TIMED_SLOT_MODE_MC BIT(7) --#define QSYS_TFRM_MISC_TIMED_ENTRY_FAST_CNT(x) ((x) & GENMASK(6, 0)) --#define QSYS_TFRM_MISC_TIMED_ENTRY_FAST_CNT_M GENMASK(6, 0) -- --#define QSYS_RED_PROFILE_RSZ 0x4 -- --#define QSYS_RED_PROFILE_WM_RED_LOW(x) (((x) << 8) & GENMASK(15, 8)) --#define QSYS_RED_PROFILE_WM_RED_LOW_M GENMASK(15, 8) --#define QSYS_RED_PROFILE_WM_RED_LOW_X(x) (((x) & GENMASK(15, 8)) >> 8) --#define QSYS_RED_PROFILE_WM_RED_HIGH(x) ((x) & GENMASK(7, 0)) --#define QSYS_RED_PROFILE_WM_RED_HIGH_M GENMASK(7, 0) -- --#define QSYS_RES_CFG_GSZ 0x8 -- --#define QSYS_RES_STAT_GSZ 0x8 -- --#define QSYS_RES_STAT_INUSE(x) (((x) << 12) & GENMASK(23, 12)) --#define QSYS_RES_STAT_INUSE_M GENMASK(23, 12) --#define QSYS_RES_STAT_INUSE_X(x) (((x) & GENMASK(23, 12)) >> 12) --#define QSYS_RES_STAT_MAXUSE(x) ((x) & GENMASK(11, 0)) --#define QSYS_RES_STAT_MAXUSE_M GENMASK(11, 0) -- --#define QSYS_EVENTS_CORE_EV_FDC(x) (((x) << 2) & GENMASK(4, 2)) --#define QSYS_EVENTS_CORE_EV_FDC_M GENMASK(4, 2) --#define QSYS_EVENTS_CORE_EV_FDC_X(x) (((x) & GENMASK(4, 2)) >> 2) --#define QSYS_EVENTS_CORE_EV_FRD(x) ((x) & GENMASK(1, 0)) --#define QSYS_EVENTS_CORE_EV_FRD_M GENMASK(1, 0) -- --#define QSYS_QMAXSDU_CFG_0_RSZ 0x4 -- --#define QSYS_QMAXSDU_CFG_1_RSZ 0x4 -- --#define QSYS_QMAXSDU_CFG_2_RSZ 0x4 -- --#define QSYS_QMAXSDU_CFG_3_RSZ 0x4 -- --#define QSYS_QMAXSDU_CFG_4_RSZ 0x4 -- --#define QSYS_QMAXSDU_CFG_5_RSZ 0x4 -- --#define QSYS_QMAXSDU_CFG_6_RSZ 0x4 -- --#define QSYS_QMAXSDU_CFG_7_RSZ 0x4 -- --#define QSYS_PREEMPTION_CFG_RSZ 0x4 -- --#define QSYS_PREEMPTION_CFG_P_QUEUES(x) ((x) & GENMASK(7, 0)) --#define QSYS_PREEMPTION_CFG_P_QUEUES_M GENMASK(7, 0) --#define QSYS_PREEMPTION_CFG_MM_ADD_FRAG_SIZE(x) (((x) << 8) & GENMASK(9, 8)) --#define QSYS_PREEMPTION_CFG_MM_ADD_FRAG_SIZE_M GENMASK(9, 8) --#define QSYS_PREEMPTION_CFG_MM_ADD_FRAG_SIZE_X(x) (((x) & GENMASK(9, 8)) >> 8) --#define QSYS_PREEMPTION_CFG_STRICT_IPG(x) (((x) << 12) & GENMASK(13, 12)) --#define QSYS_PREEMPTION_CFG_STRICT_IPG_M GENMASK(13, 12) --#define QSYS_PREEMPTION_CFG_STRICT_IPG_X(x) (((x) & GENMASK(13, 12)) >> 12) --#define QSYS_PREEMPTION_CFG_HOLD_ADVANCE(x) (((x) << 16) & GENMASK(31, 16)) --#define QSYS_PREEMPTION_CFG_HOLD_ADVANCE_M GENMASK(31, 16) --#define QSYS_PREEMPTION_CFG_HOLD_ADVANCE_X(x) (((x) & GENMASK(31, 16)) >> 16) -- --#define QSYS_CIR_CFG_GSZ 0x80 -- --#define QSYS_CIR_CFG_CIR_RATE(x) (((x) << 6) & GENMASK(20, 6)) --#define QSYS_CIR_CFG_CIR_RATE_M GENMASK(20, 6) --#define QSYS_CIR_CFG_CIR_RATE_X(x) (((x) & GENMASK(20, 6)) >> 6) --#define QSYS_CIR_CFG_CIR_BURST(x) ((x) & GENMASK(5, 0)) --#define QSYS_CIR_CFG_CIR_BURST_M GENMASK(5, 0) -- --#define QSYS_EIR_CFG_GSZ 0x80 -- --#define QSYS_EIR_CFG_EIR_RATE(x) (((x) << 7) & GENMASK(21, 7)) --#define QSYS_EIR_CFG_EIR_RATE_M GENMASK(21, 7) --#define QSYS_EIR_CFG_EIR_RATE_X(x) (((x) & GENMASK(21, 7)) >> 7) --#define QSYS_EIR_CFG_EIR_BURST(x) (((x) << 1) & GENMASK(6, 1)) --#define QSYS_EIR_CFG_EIR_BURST_M GENMASK(6, 1) --#define QSYS_EIR_CFG_EIR_BURST_X(x) (((x) & GENMASK(6, 1)) >> 1) --#define QSYS_EIR_CFG_EIR_MARK_ENA BIT(0) -- --#define QSYS_SE_CFG_GSZ 0x80 -- --#define QSYS_SE_CFG_SE_DWRR_CNT(x) (((x) << 6) & GENMASK(9, 6)) --#define QSYS_SE_CFG_SE_DWRR_CNT_M GENMASK(9, 6) --#define QSYS_SE_CFG_SE_DWRR_CNT_X(x) (((x) & GENMASK(9, 6)) >> 6) --#define QSYS_SE_CFG_SE_RR_ENA BIT(5) --#define QSYS_SE_CFG_SE_AVB_ENA BIT(4) --#define QSYS_SE_CFG_SE_FRM_MODE(x) (((x) << 2) & GENMASK(3, 2)) --#define QSYS_SE_CFG_SE_FRM_MODE_M GENMASK(3, 2) --#define QSYS_SE_CFG_SE_FRM_MODE_X(x) (((x) & GENMASK(3, 2)) >> 2) --#define QSYS_SE_CFG_SE_EXC_ENA BIT(1) --#define QSYS_SE_CFG_SE_EXC_FWD BIT(0) -- --#define QSYS_SE_DWRR_CFG_GSZ 0x80 --#define QSYS_SE_DWRR_CFG_RSZ 0x4 -- --#define QSYS_SE_CONNECT_GSZ 0x80 -- --#define QSYS_SE_CONNECT_SE_OUTP_IDX(x) (((x) << 17) & GENMASK(24, 17)) --#define QSYS_SE_CONNECT_SE_OUTP_IDX_M GENMASK(24, 17) --#define QSYS_SE_CONNECT_SE_OUTP_IDX_X(x) (((x) & GENMASK(24, 17)) >> 17) --#define QSYS_SE_CONNECT_SE_INP_IDX(x) (((x) << 9) & GENMASK(16, 9)) --#define QSYS_SE_CONNECT_SE_INP_IDX_M GENMASK(16, 9) --#define QSYS_SE_CONNECT_SE_INP_IDX_X(x) (((x) & GENMASK(16, 9)) >> 9) --#define QSYS_SE_CONNECT_SE_OUTP_CON(x) (((x) << 5) & GENMASK(8, 5)) --#define QSYS_SE_CONNECT_SE_OUTP_CON_M GENMASK(8, 5) --#define QSYS_SE_CONNECT_SE_OUTP_CON_X(x) (((x) & GENMASK(8, 5)) >> 5) --#define QSYS_SE_CONNECT_SE_INP_CNT(x) (((x) << 1) & GENMASK(4, 1)) --#define QSYS_SE_CONNECT_SE_INP_CNT_M GENMASK(4, 1) --#define QSYS_SE_CONNECT_SE_INP_CNT_X(x) (((x) & GENMASK(4, 1)) >> 1) --#define QSYS_SE_CONNECT_SE_TERMINAL BIT(0) -- --#define QSYS_SE_DLB_SENSE_GSZ 0x80 -- --#define QSYS_SE_DLB_SENSE_SE_DLB_PRIO(x) (((x) << 11) & GENMASK(13, 11)) --#define QSYS_SE_DLB_SENSE_SE_DLB_PRIO_M GENMASK(13, 11) --#define QSYS_SE_DLB_SENSE_SE_DLB_PRIO_X(x) (((x) & GENMASK(13, 11)) >> 11) --#define QSYS_SE_DLB_SENSE_SE_DLB_SPORT(x) (((x) << 7) & GENMASK(10, 7)) --#define QSYS_SE_DLB_SENSE_SE_DLB_SPORT_M GENMASK(10, 7) --#define QSYS_SE_DLB_SENSE_SE_DLB_SPORT_X(x) (((x) & GENMASK(10, 7)) >> 7) --#define QSYS_SE_DLB_SENSE_SE_DLB_DPORT(x) (((x) << 3) & GENMASK(6, 3)) --#define QSYS_SE_DLB_SENSE_SE_DLB_DPORT_M GENMASK(6, 3) --#define QSYS_SE_DLB_SENSE_SE_DLB_DPORT_X(x) (((x) & GENMASK(6, 3)) >> 3) --#define QSYS_SE_DLB_SENSE_SE_DLB_PRIO_ENA BIT(2) --#define QSYS_SE_DLB_SENSE_SE_DLB_SPORT_ENA BIT(1) --#define QSYS_SE_DLB_SENSE_SE_DLB_DPORT_ENA BIT(0) -- --#define QSYS_CIR_STATE_GSZ 0x80 -- --#define QSYS_CIR_STATE_CIR_LVL(x) (((x) << 4) & GENMASK(25, 4)) --#define QSYS_CIR_STATE_CIR_LVL_M GENMASK(25, 4) --#define QSYS_CIR_STATE_CIR_LVL_X(x) (((x) & GENMASK(25, 4)) >> 4) --#define QSYS_CIR_STATE_SHP_TIME(x) ((x) & GENMASK(3, 0)) --#define QSYS_CIR_STATE_SHP_TIME_M GENMASK(3, 0) -- --#define QSYS_EIR_STATE_GSZ 0x80 -- --#define QSYS_SE_STATE_GSZ 0x80 -- --#define QSYS_SE_STATE_SE_OUTP_LVL(x) (((x) << 1) & GENMASK(2, 1)) --#define QSYS_SE_STATE_SE_OUTP_LVL_M GENMASK(2, 1) --#define QSYS_SE_STATE_SE_OUTP_LVL_X(x) (((x) & GENMASK(2, 1)) >> 1) --#define QSYS_SE_STATE_SE_WAS_YEL BIT(0) -- --#define QSYS_HSCH_MISC_CFG_SE_CONNECT_VLD BIT(8) --#define QSYS_HSCH_MISC_CFG_FRM_ADJ(x) (((x) << 3) & GENMASK(7, 3)) --#define QSYS_HSCH_MISC_CFG_FRM_ADJ_M GENMASK(7, 3) --#define QSYS_HSCH_MISC_CFG_FRM_ADJ_X(x) (((x) & GENMASK(7, 3)) >> 3) --#define QSYS_HSCH_MISC_CFG_LEAK_DIS BIT(2) --#define QSYS_HSCH_MISC_CFG_QSHP_EXC_ENA BIT(1) --#define QSYS_HSCH_MISC_CFG_PFC_BYP_UPD BIT(0) -- --#define QSYS_TAG_CONFIG_RSZ 0x4 -- --#define QSYS_TAG_CONFIG_ENABLE BIT(0) --#define QSYS_TAG_CONFIG_LINK_SPEED(x) (((x) << 4) & GENMASK(5, 4)) --#define QSYS_TAG_CONFIG_LINK_SPEED_M GENMASK(5, 4) --#define QSYS_TAG_CONFIG_LINK_SPEED_X(x) (((x) & GENMASK(5, 4)) >> 4) --#define QSYS_TAG_CONFIG_INIT_GATE_STATE(x) (((x) << 8) & GENMASK(15, 8)) --#define QSYS_TAG_CONFIG_INIT_GATE_STATE_M GENMASK(15, 8) --#define QSYS_TAG_CONFIG_INIT_GATE_STATE_X(x) (((x) & GENMASK(15, 8)) >> 8) --#define QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES(x) (((x) << 16) & GENMASK(23, 16)) --#define QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_M GENMASK(23, 16) --#define QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_X(x) (((x) & GENMASK(23, 16)) >> 16) -- --#define QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(x) ((x) & GENMASK(7, 0)) --#define QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M GENMASK(7, 0) --#define QSYS_TAS_PARAM_CFG_CTRL_ALWAYS_GUARD_BAND_SCH_Q BIT(8) --#define QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE BIT(16) -- --#define QSYS_PORT_MAX_SDU_RSZ 0x4 -- --#define QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB(x) ((x) & GENMASK(15, 0)) --#define QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB_M GENMASK(15, 0) --#define QSYS_PARAM_CFG_REG_3_LIST_LENGTH(x) (((x) << 16) & GENMASK(31, 16)) --#define QSYS_PARAM_CFG_REG_3_LIST_LENGTH_M GENMASK(31, 16) --#define QSYS_PARAM_CFG_REG_3_LIST_LENGTH_X(x) (((x) & GENMASK(31, 16)) >> 16) -- --#define QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM(x) ((x) & GENMASK(5, 0)) --#define QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM_M GENMASK(5, 0) --#define QSYS_GCL_CFG_REG_1_GATE_STATE(x) (((x) << 8) & GENMASK(15, 8)) --#define QSYS_GCL_CFG_REG_1_GATE_STATE_M GENMASK(15, 8) --#define QSYS_GCL_CFG_REG_1_GATE_STATE_X(x) (((x) & GENMASK(15, 8)) >> 8) -- --#define QSYS_PARAM_STATUS_REG_3_BASE_TIME_SEC_MSB(x) ((x) & GENMASK(15, 0)) --#define QSYS_PARAM_STATUS_REG_3_BASE_TIME_SEC_MSB_M GENMASK(15, 0) --#define QSYS_PARAM_STATUS_REG_3_LIST_LENGTH(x) (((x) << 16) & GENMASK(31, 16)) --#define QSYS_PARAM_STATUS_REG_3_LIST_LENGTH_M GENMASK(31, 16) --#define QSYS_PARAM_STATUS_REG_3_LIST_LENGTH_X(x) (((x) & GENMASK(31, 16)) >> 16) -- --#define QSYS_PARAM_STATUS_REG_8_CFG_CHG_TIME_SEC_MSB(x) ((x) & GENMASK(15, 0)) --#define QSYS_PARAM_STATUS_REG_8_CFG_CHG_TIME_SEC_MSB_M GENMASK(15, 0) --#define QSYS_PARAM_STATUS_REG_8_OPER_GATE_STATE(x) (((x) << 16) & GENMASK(23, 16)) --#define QSYS_PARAM_STATUS_REG_8_OPER_GATE_STATE_M GENMASK(23, 16) --#define QSYS_PARAM_STATUS_REG_8_OPER_GATE_STATE_X(x) (((x) & GENMASK(23, 16)) >> 16) --#define QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING BIT(24) -- --#define QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM(x) ((x) & GENMASK(5, 0)) --#define QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM_M GENMASK(5, 0) --#define QSYS_GCL_STATUS_REG_1_GATE_STATE(x) (((x) << 8) & GENMASK(15, 8)) --#define QSYS_GCL_STATUS_REG_1_GATE_STATE_M GENMASK(15, 8) --#define QSYS_GCL_STATUS_REG_1_GATE_STATE_X(x) (((x) & GENMASK(15, 8)) >> 8) -- --#endif ---- a/drivers/net/ethernet/mscc/ocelot_tsn.c -+++ b/drivers/net/ethernet/mscc/ocelot_tsn.c -@@ -11,8 +11,8 @@ - #include - #include "ocelot.h" - #include --#include "ocelot_ana.h" --#include "ocelot_qsys.h" -+#include -+#include - #include "ocelot_rew.h" - #include "ocelot_dev_gmii.h" - #include "ocelot_tsn.h" ---- /dev/null -+++ b/include/soc/mscc/ocelot_ana.h -@@ -0,0 +1,642 @@ -+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ -+/* -+ * Microsemi Ocelot Switch driver -+ * -+ * Copyright (c) 2017 Microsemi Corporation -+ */ -+ -+#ifndef _MSCC_OCELOT_ANA_H_ -+#define _MSCC_OCELOT_ANA_H_ -+ -+#define ANA_ANAGEFIL_B_DOM_EN BIT(22) -+#define ANA_ANAGEFIL_B_DOM_VAL BIT(21) -+#define ANA_ANAGEFIL_AGE_LOCKED BIT(20) -+#define ANA_ANAGEFIL_PID_EN BIT(19) -+#define ANA_ANAGEFIL_PID_VAL(x) (((x) << 14) & GENMASK(18, 14)) -+#define ANA_ANAGEFIL_PID_VAL_M GENMASK(18, 14) -+#define ANA_ANAGEFIL_PID_VAL_X(x) (((x) & GENMASK(18, 14)) >> 14) -+#define ANA_ANAGEFIL_VID_EN BIT(13) -+#define ANA_ANAGEFIL_VID_VAL(x) ((x) & GENMASK(12, 0)) -+#define ANA_ANAGEFIL_VID_VAL_M GENMASK(12, 0) -+ -+#define ANA_STORMLIMIT_CFG_RSZ 0x4 -+ -+#define ANA_STORMLIMIT_CFG_STORM_RATE(x) (((x) << 3) & GENMASK(6, 3)) -+#define ANA_STORMLIMIT_CFG_STORM_RATE_M GENMASK(6, 3) -+#define ANA_STORMLIMIT_CFG_STORM_RATE_X(x) (((x) & GENMASK(6, 3)) >> 3) -+#define ANA_STORMLIMIT_CFG_STORM_UNIT BIT(2) -+#define ANA_STORMLIMIT_CFG_STORM_MODE(x) ((x) & GENMASK(1, 0)) -+#define ANA_STORMLIMIT_CFG_STORM_MODE_M GENMASK(1, 0) -+ -+#define ANA_AUTOAGE_AGE_FAST BIT(21) -+#define ANA_AUTOAGE_AGE_PERIOD(x) (((x) << 1) & GENMASK(20, 1)) -+#define ANA_AUTOAGE_AGE_PERIOD_M GENMASK(20, 1) -+#define ANA_AUTOAGE_AGE_PERIOD_X(x) (((x) & GENMASK(20, 1)) >> 1) -+#define ANA_AUTOAGE_AUTOAGE_LOCKED BIT(0) -+ -+#define ANA_MACTOPTIONS_REDUCED_TABLE BIT(1) -+#define ANA_MACTOPTIONS_SHADOW BIT(0) -+ -+#define ANA_AGENCTRL_FID_MASK(x) (((x) << 12) & GENMASK(23, 12)) -+#define ANA_AGENCTRL_FID_MASK_M GENMASK(23, 12) -+#define ANA_AGENCTRL_FID_MASK_X(x) (((x) & GENMASK(23, 12)) >> 12) -+#define ANA_AGENCTRL_IGNORE_DMAC_FLAGS BIT(11) -+#define ANA_AGENCTRL_IGNORE_SMAC_FLAGS BIT(10) -+#define ANA_AGENCTRL_FLOOD_SPECIAL BIT(9) -+#define ANA_AGENCTRL_FLOOD_IGNORE_VLAN BIT(8) -+#define ANA_AGENCTRL_MIRROR_CPU BIT(7) -+#define ANA_AGENCTRL_LEARN_CPU_COPY BIT(6) -+#define ANA_AGENCTRL_LEARN_FWD_KILL BIT(5) -+#define ANA_AGENCTRL_LEARN_IGNORE_VLAN BIT(4) -+#define ANA_AGENCTRL_CPU_CPU_KILL_ENA BIT(3) -+#define ANA_AGENCTRL_GREEN_COUNT_MODE BIT(2) -+#define ANA_AGENCTRL_YELLOW_COUNT_MODE BIT(1) -+#define ANA_AGENCTRL_RED_COUNT_MODE BIT(0) -+ -+#define ANA_FLOODING_RSZ 0x4 -+ -+#define ANA_FLOODING_FLD_UNICAST(x) (((x) << 12) & GENMASK(17, 12)) -+#define ANA_FLOODING_FLD_UNICAST_M GENMASK(17, 12) -+#define ANA_FLOODING_FLD_UNICAST_X(x) (((x) & GENMASK(17, 12)) >> 12) -+#define ANA_FLOODING_FLD_BROADCAST(x) (((x) << 6) & GENMASK(11, 6)) -+#define ANA_FLOODING_FLD_BROADCAST_M GENMASK(11, 6) -+#define ANA_FLOODING_FLD_BROADCAST_X(x) (((x) & GENMASK(11, 6)) >> 6) -+#define ANA_FLOODING_FLD_MULTICAST(x) ((x) & GENMASK(5, 0)) -+#define ANA_FLOODING_FLD_MULTICAST_M GENMASK(5, 0) -+ -+#define ANA_FLOODING_IPMC_FLD_MC4_CTRL(x) (((x) << 18) & GENMASK(23, 18)) -+#define ANA_FLOODING_IPMC_FLD_MC4_CTRL_M GENMASK(23, 18) -+#define ANA_FLOODING_IPMC_FLD_MC4_CTRL_X(x) (((x) & GENMASK(23, 18)) >> 18) -+#define ANA_FLOODING_IPMC_FLD_MC4_DATA(x) (((x) << 12) & GENMASK(17, 12)) -+#define ANA_FLOODING_IPMC_FLD_MC4_DATA_M GENMASK(17, 12) -+#define ANA_FLOODING_IPMC_FLD_MC4_DATA_X(x) (((x) & GENMASK(17, 12)) >> 12) -+#define ANA_FLOODING_IPMC_FLD_MC6_CTRL(x) (((x) << 6) & GENMASK(11, 6)) -+#define ANA_FLOODING_IPMC_FLD_MC6_CTRL_M GENMASK(11, 6) -+#define ANA_FLOODING_IPMC_FLD_MC6_CTRL_X(x) (((x) & GENMASK(11, 6)) >> 6) -+#define ANA_FLOODING_IPMC_FLD_MC6_DATA(x) ((x) & GENMASK(5, 0)) -+#define ANA_FLOODING_IPMC_FLD_MC6_DATA_M GENMASK(5, 0) -+ -+#define ANA_SFLOW_CFG_RSZ 0x4 -+ -+#define ANA_SFLOW_CFG_SF_RATE(x) (((x) << 2) & GENMASK(13, 2)) -+#define ANA_SFLOW_CFG_SF_RATE_M GENMASK(13, 2) -+#define ANA_SFLOW_CFG_SF_RATE_X(x) (((x) & GENMASK(13, 2)) >> 2) -+#define ANA_SFLOW_CFG_SF_SAMPLE_RX BIT(1) -+#define ANA_SFLOW_CFG_SF_SAMPLE_TX BIT(0) -+ -+#define ANA_PORT_MODE_RSZ 0x4 -+ -+#define ANA_PORT_MODE_REDTAG_PARSE_CFG BIT(3) -+#define ANA_PORT_MODE_VLAN_PARSE_CFG(x) (((x) << 1) & GENMASK(2, 1)) -+#define ANA_PORT_MODE_VLAN_PARSE_CFG_M GENMASK(2, 1) -+#define ANA_PORT_MODE_VLAN_PARSE_CFG_X(x) (((x) & GENMASK(2, 1)) >> 1) -+#define ANA_PORT_MODE_L3_PARSE_CFG BIT(0) -+ -+#define ANA_CUT_THRU_CFG_RSZ 0x4 -+ -+#define ANA_PGID_PGID_RSZ 0x4 -+ -+#define ANA_PGID_PGID_PGID(x) ((x) & GENMASK(11, 0)) -+#define ANA_PGID_PGID_PGID_M GENMASK(11, 0) -+#define ANA_PGID_PGID_CPUQ_DST_PGID(x) (((x) << 27) & GENMASK(29, 27)) -+#define ANA_PGID_PGID_CPUQ_DST_PGID_M GENMASK(29, 27) -+#define ANA_PGID_PGID_CPUQ_DST_PGID_X(x) (((x) & GENMASK(29, 27)) >> 27) -+ -+#define ANA_TABLES_MACHDATA_VID(x) (((x) << 16) & GENMASK(28, 16)) -+#define ANA_TABLES_MACHDATA_VID_M GENMASK(28, 16) -+#define ANA_TABLES_MACHDATA_VID_X(x) (((x) & GENMASK(28, 16)) >> 16) -+#define ANA_TABLES_MACHDATA_MACHDATA(x) ((x) & GENMASK(15, 0)) -+#define ANA_TABLES_MACHDATA_MACHDATA_M GENMASK(15, 0) -+ -+#define ANA_TABLES_STREAMDATA_SSID_VALID BIT(16) -+#define ANA_TABLES_STREAMDATA_SSID(x) (((x) << 9) & GENMASK(15, 9)) -+#define ANA_TABLES_STREAMDATA_SSID_M GENMASK(15, 9) -+#define ANA_TABLES_STREAMDATA_SSID_X(x) (((x) & GENMASK(15, 9)) >> 9) -+#define ANA_TABLES_STREAMDATA_SFID_VALID BIT(8) -+#define ANA_TABLES_STREAMDATA_SFID(x) ((x) & GENMASK(7, 0)) -+#define ANA_TABLES_STREAMDATA_SFID_M GENMASK(7, 0) -+ -+#define ANA_TABLES_MACACCESS_MAC_CPU_COPY BIT(15) -+#define ANA_TABLES_MACACCESS_SRC_KILL BIT(14) -+#define ANA_TABLES_MACACCESS_IGNORE_VLAN BIT(13) -+#define ANA_TABLES_MACACCESS_AGED_FLAG BIT(12) -+#define ANA_TABLES_MACACCESS_VALID BIT(11) -+#define ANA_TABLES_MACACCESS_ENTRYTYPE(x) (((x) << 9) & GENMASK(10, 9)) -+#define ANA_TABLES_MACACCESS_ENTRYTYPE_M GENMASK(10, 9) -+#define ANA_TABLES_MACACCESS_ENTRYTYPE_X(x) (((x) & GENMASK(10, 9)) >> 9) -+#define ANA_TABLES_MACACCESS_DEST_IDX(x) (((x) << 3) & GENMASK(8, 3)) -+#define ANA_TABLES_MACACCESS_DEST_IDX_M GENMASK(8, 3) -+#define ANA_TABLES_MACACCESS_DEST_IDX_X(x) (((x) & GENMASK(8, 3)) >> 3) -+#define ANA_TABLES_MACACCESS_MAC_TABLE_CMD(x) ((x) & GENMASK(2, 0)) -+#define ANA_TABLES_MACACCESS_MAC_TABLE_CMD_M GENMASK(2, 0) -+#define MACACCESS_CMD_IDLE 0 -+#define MACACCESS_CMD_LEARN 1 -+#define MACACCESS_CMD_FORGET 2 -+#define MACACCESS_CMD_AGE 3 -+#define MACACCESS_CMD_GET_NEXT 4 -+#define MACACCESS_CMD_INIT 5 -+#define MACACCESS_CMD_READ 6 -+#define MACACCESS_CMD_WRITE 7 -+ -+#define ANA_TABLES_VLANACCESS_VLAN_PORT_MASK(x) (((x) << 2) & GENMASK(13, 2)) -+#define ANA_TABLES_VLANACCESS_VLAN_PORT_MASK_M GENMASK(13, 2) -+#define ANA_TABLES_VLANACCESS_VLAN_PORT_MASK_X(x) (((x) & GENMASK(13, 2)) >> 2) -+#define ANA_TABLES_VLANACCESS_VLAN_TBL_CMD(x) ((x) & GENMASK(1, 0)) -+#define ANA_TABLES_VLANACCESS_VLAN_TBL_CMD_M GENMASK(1, 0) -+#define ANA_TABLES_VLANACCESS_CMD_IDLE 0x0 -+#define ANA_TABLES_VLANACCESS_CMD_WRITE 0x2 -+#define ANA_TABLES_VLANACCESS_CMD_INIT 0x3 -+ -+#define ANA_TABLES_VLANTIDX_VLAN_SEC_FWD_ENA BIT(17) -+#define ANA_TABLES_VLANTIDX_VLAN_FLOOD_DIS BIT(16) -+#define ANA_TABLES_VLANTIDX_VLAN_PRIV_VLAN BIT(15) -+#define ANA_TABLES_VLANTIDX_VLAN_LEARN_DISABLED BIT(14) -+#define ANA_TABLES_VLANTIDX_VLAN_MIRROR BIT(13) -+#define ANA_TABLES_VLANTIDX_VLAN_SRC_CHK BIT(12) -+#define ANA_TABLES_VLANTIDX_V_INDEX(x) ((x) & GENMASK(11, 0)) -+#define ANA_TABLES_VLANTIDX_V_INDEX_M GENMASK(11, 0) -+ -+#define ANA_TABLES_ISDXACCESS_ISDX_PORT_MASK(x) (((x) << 2) & GENMASK(8, 2)) -+#define ANA_TABLES_ISDXACCESS_ISDX_PORT_MASK_M GENMASK(8, 2) -+#define ANA_TABLES_ISDXACCESS_ISDX_PORT_MASK_X(x) (((x) & GENMASK(8, 2)) >> 2) -+#define ANA_TABLES_ISDXACCESS_ISDX_TBL_CMD(x) ((x) & GENMASK(1, 0)) -+#define ANA_TABLES_ISDXACCESS_ISDX_TBL_CMD_M GENMASK(1, 0) -+ -+#define ANA_TABLES_ISDXTIDX_ISDX_SDLBI(x) (((x) << 21) & GENMASK(28, 21)) -+#define ANA_TABLES_ISDXTIDX_ISDX_SDLBI_M GENMASK(28, 21) -+#define ANA_TABLES_ISDXTIDX_ISDX_SDLBI_X(x) (((x) & GENMASK(28, 21)) >> 21) -+#define ANA_TABLES_ISDXTIDX_ISDX_MSTI(x) (((x) << 15) & GENMASK(20, 15)) -+#define ANA_TABLES_ISDXTIDX_ISDX_MSTI_M GENMASK(20, 15) -+#define ANA_TABLES_ISDXTIDX_ISDX_MSTI_X(x) (((x) & GENMASK(20, 15)) >> 15) -+#define ANA_TABLES_ISDXTIDX_ISDX_ES0_KEY_ENA BIT(14) -+#define ANA_TABLES_ISDXTIDX_ISDX_FORCE_ENA BIT(10) -+#define ANA_TABLES_ISDXTIDX_ISDX_INDEX(x) ((x) & GENMASK(7, 0)) -+#define ANA_TABLES_ISDXTIDX_ISDX_INDEX_M GENMASK(7, 0) -+ -+#define ANA_TABLES_ENTRYLIM_RSZ 0x4 -+ -+#define ANA_TABLES_ENTRYLIM_ENTRYLIM(x) (((x) << 14) & GENMASK(17, 14)) -+#define ANA_TABLES_ENTRYLIM_ENTRYLIM_M GENMASK(17, 14) -+#define ANA_TABLES_ENTRYLIM_ENTRYLIM_X(x) (((x) & GENMASK(17, 14)) >> 14) -+#define ANA_TABLES_ENTRYLIM_ENTRYSTAT(x) ((x) & GENMASK(13, 0)) -+#define ANA_TABLES_ENTRYLIM_ENTRYSTAT_M GENMASK(13, 0) -+ -+#define ANA_TABLES_STREAMACCESS_GEN_REC_SEQ_NUM(x) (((x) << 4) & GENMASK(31, 4)) -+#define ANA_TABLES_STREAMACCESS_GEN_REC_SEQ_NUM_M GENMASK(31, 4) -+#define ANA_TABLES_STREAMACCESS_GEN_REC_SEQ_NUM_X(x) (((x) & GENMASK(31, 4)) >> 4) -+#define ANA_TABLES_STREAMACCESS_SEQ_GEN_REC_ENA BIT(3) -+#define ANA_TABLES_STREAMACCESS_GEN_REC_TYPE BIT(2) -+#define ANA_TABLES_STREAMACCESS_STREAM_TBL_CMD(x) ((x) & GENMASK(1, 0)) -+#define ANA_TABLES_STREAMACCESS_STREAM_TBL_CMD_M GENMASK(1, 0) -+ -+#define ANA_TABLES_STREAMTIDX_SEQ_GEN_ERR_STATUS(x) (((x) << 30) & GENMASK(31, 30)) -+#define ANA_TABLES_STREAMTIDX_SEQ_GEN_ERR_STATUS_M GENMASK(31, 30) -+#define ANA_TABLES_STREAMTIDX_SEQ_GEN_ERR_STATUS_X(x) (((x) & GENMASK(31, 30)) >> 30) -+#define ANA_TABLES_STREAMTIDX_S_INDEX(x) (((x) << 16) & GENMASK(22, 16)) -+#define ANA_TABLES_STREAMTIDX_S_INDEX_M GENMASK(22, 16) -+#define ANA_TABLES_STREAMTIDX_S_INDEX_X(x) (((x) & GENMASK(22, 16)) >> 16) -+#define ANA_TABLES_STREAMTIDX_FORCE_SF_BEHAVIOUR BIT(14) -+#define ANA_TABLES_STREAMTIDX_SEQ_HISTORY_LEN(x) (((x) << 8) & GENMASK(13, 8)) -+#define ANA_TABLES_STREAMTIDX_SEQ_HISTORY_LEN_M GENMASK(13, 8) -+#define ANA_TABLES_STREAMTIDX_SEQ_HISTORY_LEN_X(x) (((x) & GENMASK(13, 8)) >> 8) -+#define ANA_TABLES_STREAMTIDX_RESET_ON_ROGUE BIT(7) -+#define ANA_TABLES_STREAMTIDX_REDTAG_POP BIT(6) -+#define ANA_TABLES_STREAMTIDX_STREAM_SPLIT BIT(5) -+#define ANA_TABLES_STREAMTIDX_SEQ_SPACE_LOG2(x) ((x) & GENMASK(4, 0)) -+#define ANA_TABLES_STREAMTIDX_SEQ_SPACE_LOG2_M GENMASK(4, 0) -+ -+#define ANA_TABLES_SEQ_MASK_SPLIT_MASK(x) (((x) << 16) & GENMASK(22, 16)) -+#define ANA_TABLES_SEQ_MASK_SPLIT_MASK_M GENMASK(22, 16) -+#define ANA_TABLES_SEQ_MASK_SPLIT_MASK_X(x) (((x) & GENMASK(22, 16)) >> 16) -+#define ANA_TABLES_SEQ_MASK_INPUT_PORT_MASK(x) ((x) & GENMASK(6, 0)) -+#define ANA_TABLES_SEQ_MASK_INPUT_PORT_MASK_M GENMASK(6, 0) -+ -+#define ANA_TABLES_SFID_MASK_IGR_PORT_MASK(x) (((x) << 1) & GENMASK(7, 1)) -+#define ANA_TABLES_SFID_MASK_IGR_PORT_MASK_M GENMASK(7, 1) -+#define ANA_TABLES_SFID_MASK_IGR_PORT_MASK_X(x) (((x) & GENMASK(7, 1)) >> 1) -+#define ANA_TABLES_SFID_MASK_IGR_SRCPORT_MATCH_ENA BIT(0) -+ -+#define ANA_TABLES_SFIDACCESS_IGR_PRIO_MATCH_ENA BIT(22) -+#define ANA_TABLES_SFIDACCESS_IGR_PRIO(x) (((x) << 19) & GENMASK(21, 19)) -+#define ANA_TABLES_SFIDACCESS_IGR_PRIO_M GENMASK(21, 19) -+#define ANA_TABLES_SFIDACCESS_IGR_PRIO_X(x) (((x) & GENMASK(21, 19)) >> 19) -+#define ANA_TABLES_SFIDACCESS_FORCE_BLOCK BIT(18) -+#define ANA_TABLES_SFIDACCESS_MAX_SDU_LEN(x) (((x) << 2) & GENMASK(17, 2)) -+#define ANA_TABLES_SFIDACCESS_MAX_SDU_LEN_M GENMASK(17, 2) -+#define ANA_TABLES_SFIDACCESS_MAX_SDU_LEN_X(x) (((x) & GENMASK(17, 2)) >> 2) -+#define ANA_TABLES_SFIDACCESS_SFID_TBL_CMD(x) ((x) & GENMASK(1, 0)) -+#define ANA_TABLES_SFIDACCESS_SFID_TBL_CMD_M GENMASK(1, 0) -+ -+#define SFIDACCESS_CMD_IDLE 0 -+#define SFIDACCESS_CMD_READ 1 -+#define SFIDACCESS_CMD_WRITE 2 -+#define SFIDACCESS_CMD_INIT 3 -+ -+#define ANA_TABLES_SFIDTIDX_SGID_VALID BIT(26) -+#define ANA_TABLES_SFIDTIDX_SGID(x) (((x) << 18) & GENMASK(25, 18)) -+#define ANA_TABLES_SFIDTIDX_SGID_M GENMASK(25, 18) -+#define ANA_TABLES_SFIDTIDX_SGID_X(x) (((x) & GENMASK(25, 18)) >> 18) -+#define ANA_TABLES_SFIDTIDX_POL_ENA BIT(17) -+#define ANA_TABLES_SFIDTIDX_POL_IDX(x) (((x) << 8) & GENMASK(16, 8)) -+#define ANA_TABLES_SFIDTIDX_POL_IDX_M GENMASK(16, 8) -+#define ANA_TABLES_SFIDTIDX_POL_IDX_X(x) (((x) & GENMASK(16, 8)) >> 8) -+#define ANA_TABLES_SFIDTIDX_SFID_INDEX(x) ((x) & GENMASK(7, 0)) -+#define ANA_TABLES_SFIDTIDX_SFID_INDEX_M GENMASK(7, 0) -+ -+#define ANA_MSTI_STATE_RSZ 0x4 -+ -+#define ANA_OAM_UPM_LM_CNT_RSZ 0x4 -+ -+#define ANA_SG_ACCESS_CTRL_SGID(x) ((x) & GENMASK(7, 0)) -+#define ANA_SG_ACCESS_CTRL_SGID_M GENMASK(7, 0) -+#define ANA_SG_ACCESS_CTRL_CONFIG_CHANGE BIT(28) -+ -+#define ANA_SG_CONFIG_REG_3_BASE_TIME_SEC_MSB(x) ((x) & GENMASK(15, 0)) -+#define ANA_SG_CONFIG_REG_3_BASE_TIME_SEC_MSB_M GENMASK(15, 0) -+#define ANA_SG_CONFIG_REG_3_LIST_LENGTH(x) (((x) << 16) & GENMASK(18, 16)) -+#define ANA_SG_CONFIG_REG_3_LIST_LENGTH_M GENMASK(18, 16) -+#define ANA_SG_CONFIG_REG_3_LIST_LENGTH_X(x) (((x) & GENMASK(18, 16)) >> 16) -+#define ANA_SG_CONFIG_REG_3_GATE_ENABLE BIT(20) -+#define ANA_SG_CONFIG_REG_3_INIT_IPS(x) (((x) << 21) & GENMASK(24, 21)) -+#define ANA_SG_CONFIG_REG_3_INIT_IPS_M GENMASK(24, 21) -+#define ANA_SG_CONFIG_REG_3_INIT_IPS_X(x) (((x) & GENMASK(24, 21)) >> 21) -+#define ANA_SG_CONFIG_REG_3_IPV_VALID BIT(24) -+#define ANA_SG_CONFIG_REG_3_IPV_INVALID(x) (((x) << 24) & GENMASK(24, 24)) -+#define ANA_SG_CONFIG_REG_3_INIT_IPV(x) (((x) << 21) & GENMASK(23, 21)) -+#define ANA_SG_CONFIG_REG_3_INIT_IPV_M GENMASK(23, 21) -+#define ANA_SG_CONFIG_REG_3_INIT_IPV_X(x) (((x) & GENMASK(23, 21)) >> 21) -+#define ANA_SG_CONFIG_REG_3_INIT_GATE_STATE BIT(25) -+ -+#define ANA_SG_GCL_GS_CONFIG_RSZ 0x4 -+ -+#define ANA_SG_GCL_GS_CONFIG_IPS(x) ((x) & GENMASK(3, 0)) -+#define ANA_SG_GCL_GS_CONFIG_IPS_M GENMASK(3, 0) -+#define ANA_SG_GCL_GS_CONFIG_IPV_VALID BIT(3) -+#define ANA_SG_GCL_GS_CONFIG_IPV(x) ((x) & GENMASK(2, 0)) -+#define ANA_SG_GCL_GS_CONFIG_IPV_M GENMASK(2, 0) -+#define ANA_SG_GCL_GS_CONFIG_GATE_STATE BIT(4) -+ -+#define ANA_SG_GCL_TI_CONFIG_RSZ 0x4 -+ -+#define ANA_SG_STATUS_REG_3_CFG_CHG_TIME_SEC_MSB(x) ((x) & GENMASK(15, 0)) -+#define ANA_SG_STATUS_REG_3_CFG_CHG_TIME_SEC_MSB_M GENMASK(15, 0) -+#define ANA_SG_STATUS_REG_3_GATE_STATE BIT(16) -+#define ANA_SG_STATUS_REG_3_IPS(x) (((x) << 20) & GENMASK(23, 20)) -+#define ANA_SG_STATUS_REG_3_IPS_M GENMASK(23, 20) -+#define ANA_SG_STATUS_REG_3_IPS_X(x) (((x) & GENMASK(23, 20)) >> 20) -+#define ANA_SG_STATUS_REG_3_IPV_VALID BIT(23) -+#define ANA_SG_STATUS_REG_3_IPV(x) (((x) << 20) & GENMASK(22, 20)) -+#define ANA_SG_STATUS_REG_3_IPV_M GENMASK(22, 20) -+#define ANA_SG_STATUS_REG_3_IPV_X(x) (((x) & GENMASK(22, 20)) >> 20) -+#define ANA_SG_STATUS_REG_3_CONFIG_PENDING BIT(24) -+ -+#define ANA_PORT_VLAN_CFG_GSZ 0x100 -+ -+#define ANA_PORT_VLAN_CFG_VLAN_VID_AS_ISDX BIT(21) -+#define ANA_PORT_VLAN_CFG_VLAN_AWARE_ENA BIT(20) -+#define ANA_PORT_VLAN_CFG_VLAN_POP_CNT(x) (((x) << 18) & GENMASK(19, 18)) -+#define ANA_PORT_VLAN_CFG_VLAN_POP_CNT_M GENMASK(19, 18) -+#define ANA_PORT_VLAN_CFG_VLAN_POP_CNT_X(x) (((x) & GENMASK(19, 18)) >> 18) -+#define ANA_PORT_VLAN_CFG_VLAN_INNER_TAG_ENA BIT(17) -+#define ANA_PORT_VLAN_CFG_VLAN_TAG_TYPE BIT(16) -+#define ANA_PORT_VLAN_CFG_VLAN_DEI BIT(15) -+#define ANA_PORT_VLAN_CFG_VLAN_PCP(x) (((x) << 12) & GENMASK(14, 12)) -+#define ANA_PORT_VLAN_CFG_VLAN_PCP_M GENMASK(14, 12) -+#define ANA_PORT_VLAN_CFG_VLAN_PCP_X(x) (((x) & GENMASK(14, 12)) >> 12) -+#define ANA_PORT_VLAN_CFG_VLAN_VID(x) ((x) & GENMASK(11, 0)) -+#define ANA_PORT_VLAN_CFG_VLAN_VID_M GENMASK(11, 0) -+ -+#define ANA_PORT_DROP_CFG_GSZ 0x100 -+ -+#define ANA_PORT_DROP_CFG_DROP_UNTAGGED_ENA BIT(6) -+#define ANA_PORT_DROP_CFG_DROP_S_TAGGED_ENA BIT(5) -+#define ANA_PORT_DROP_CFG_DROP_C_TAGGED_ENA BIT(4) -+#define ANA_PORT_DROP_CFG_DROP_PRIO_S_TAGGED_ENA BIT(3) -+#define ANA_PORT_DROP_CFG_DROP_PRIO_C_TAGGED_ENA BIT(2) -+#define ANA_PORT_DROP_CFG_DROP_NULL_MAC_ENA BIT(1) -+#define ANA_PORT_DROP_CFG_DROP_MC_SMAC_ENA BIT(0) -+ -+#define ANA_PORT_QOS_CFG_GSZ 0x100 -+ -+#define ANA_PORT_QOS_CFG_DP_DEFAULT_VAL BIT(8) -+#define ANA_PORT_QOS_CFG_QOS_DEFAULT_VAL(x) (((x) << 5) & GENMASK(7, 5)) -+#define ANA_PORT_QOS_CFG_QOS_DEFAULT_VAL_M GENMASK(7, 5) -+#define ANA_PORT_QOS_CFG_QOS_DEFAULT_VAL_X(x) (((x) & GENMASK(7, 5)) >> 5) -+#define ANA_PORT_QOS_CFG_QOS_DSCP_ENA BIT(4) -+#define ANA_PORT_QOS_CFG_QOS_PCP_ENA BIT(3) -+#define ANA_PORT_QOS_CFG_DSCP_TRANSLATE_ENA BIT(2) -+#define ANA_PORT_QOS_CFG_DSCP_REWR_CFG(x) ((x) & GENMASK(1, 0)) -+#define ANA_PORT_QOS_CFG_DSCP_REWR_CFG_M GENMASK(1, 0) -+ -+#define ANA_PORT_VCAP_CFG_GSZ 0x100 -+ -+#define ANA_PORT_VCAP_CFG_S1_ENA BIT(14) -+#define ANA_PORT_VCAP_CFG_S1_DMAC_DIP_ENA(x) (((x) << 11) & GENMASK(13, 11)) -+#define ANA_PORT_VCAP_CFG_S1_DMAC_DIP_ENA_M GENMASK(13, 11) -+#define ANA_PORT_VCAP_CFG_S1_DMAC_DIP_ENA_X(x) (((x) & GENMASK(13, 11)) >> 11) -+#define ANA_PORT_VCAP_CFG_S1_VLAN_INNER_TAG_ENA(x) (((x) << 8) & GENMASK(10, 8)) -+#define ANA_PORT_VCAP_CFG_S1_VLAN_INNER_TAG_ENA_M GENMASK(10, 8) -+#define ANA_PORT_VCAP_CFG_S1_VLAN_INNER_TAG_ENA_X(x) (((x) & GENMASK(10, 8)) >> 8) -+#define ANA_PORT_VCAP_CFG_PAG_VAL(x) ((x) & GENMASK(7, 0)) -+#define ANA_PORT_VCAP_CFG_PAG_VAL_M GENMASK(7, 0) -+ -+#define ANA_PORT_VCAP_S1_KEY_CFG_GSZ 0x100 -+#define ANA_PORT_VCAP_S1_KEY_CFG_RSZ 0x4 -+ -+#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP6_CFG(x) (((x) << 4) & GENMASK(6, 4)) -+#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP6_CFG_M GENMASK(6, 4) -+#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP6_CFG_X(x) (((x) & GENMASK(6, 4)) >> 4) -+#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP4_CFG(x) (((x) << 2) & GENMASK(3, 2)) -+#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP4_CFG_M GENMASK(3, 2) -+#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP4_CFG_X(x) (((x) & GENMASK(3, 2)) >> 2) -+#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_OTHER_CFG(x) ((x) & GENMASK(1, 0)) -+#define ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_OTHER_CFG_M GENMASK(1, 0) -+ -+#define ANA_PORT_VCAP_S2_CFG_GSZ 0x100 -+ -+#define ANA_PORT_VCAP_S2_CFG_S2_UDP_PAYLOAD_ENA(x) (((x) << 17) & GENMASK(18, 17)) -+#define ANA_PORT_VCAP_S2_CFG_S2_UDP_PAYLOAD_ENA_M GENMASK(18, 17) -+#define ANA_PORT_VCAP_S2_CFG_S2_UDP_PAYLOAD_ENA_X(x) (((x) & GENMASK(18, 17)) >> 17) -+#define ANA_PORT_VCAP_S2_CFG_S2_ETYPE_PAYLOAD_ENA(x) (((x) << 15) & GENMASK(16, 15)) -+#define ANA_PORT_VCAP_S2_CFG_S2_ETYPE_PAYLOAD_ENA_M GENMASK(16, 15) -+#define ANA_PORT_VCAP_S2_CFG_S2_ETYPE_PAYLOAD_ENA_X(x) (((x) & GENMASK(16, 15)) >> 15) -+#define ANA_PORT_VCAP_S2_CFG_S2_ENA BIT(14) -+#define ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS(x) (((x) << 12) & GENMASK(13, 12)) -+#define ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS_M GENMASK(13, 12) -+#define ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS_X(x) (((x) & GENMASK(13, 12)) >> 12) -+#define ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS(x) (((x) << 10) & GENMASK(11, 10)) -+#define ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS_M GENMASK(11, 10) -+#define ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS_X(x) (((x) & GENMASK(11, 10)) >> 10) -+#define ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS(x) (((x) << 8) & GENMASK(9, 8)) -+#define ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS_M GENMASK(9, 8) -+#define ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS_X(x) (((x) & GENMASK(9, 8)) >> 8) -+#define ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS(x) (((x) << 6) & GENMASK(7, 6)) -+#define ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS_M GENMASK(7, 6) -+#define ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS_X(x) (((x) & GENMASK(7, 6)) >> 6) -+#define ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG(x) (((x) << 2) & GENMASK(5, 2)) -+#define ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG_M GENMASK(5, 2) -+#define ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG_X(x) (((x) & GENMASK(5, 2)) >> 2) -+#define ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS(x) ((x) & GENMASK(1, 0)) -+#define ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS_M GENMASK(1, 0) -+ -+#define ANA_PORT_PCP_DEI_MAP_GSZ 0x100 -+#define ANA_PORT_PCP_DEI_MAP_RSZ 0x4 -+ -+#define ANA_PORT_PCP_DEI_MAP_DP_PCP_DEI_VAL BIT(3) -+#define ANA_PORT_PCP_DEI_MAP_QOS_PCP_DEI_VAL(x) ((x) & GENMASK(2, 0)) -+#define ANA_PORT_PCP_DEI_MAP_QOS_PCP_DEI_VAL_M GENMASK(2, 0) -+ -+#define ANA_PORT_CPU_FWD_CFG_GSZ 0x100 -+ -+#define ANA_PORT_CPU_FWD_CFG_CPU_VRAP_REDIR_ENA BIT(7) -+#define ANA_PORT_CPU_FWD_CFG_CPU_MLD_REDIR_ENA BIT(6) -+#define ANA_PORT_CPU_FWD_CFG_CPU_IGMP_REDIR_ENA BIT(5) -+#define ANA_PORT_CPU_FWD_CFG_CPU_IPMC_CTRL_COPY_ENA BIT(4) -+#define ANA_PORT_CPU_FWD_CFG_CPU_SRC_COPY_ENA BIT(3) -+#define ANA_PORT_CPU_FWD_CFG_CPU_ALLBRIDGE_DROP_ENA BIT(2) -+#define ANA_PORT_CPU_FWD_CFG_CPU_ALLBRIDGE_REDIR_ENA BIT(1) -+#define ANA_PORT_CPU_FWD_CFG_CPU_OAM_ENA BIT(0) -+ -+#define ANA_PORT_CPU_FWD_BPDU_CFG_GSZ 0x100 -+ -+#define ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_DROP_ENA(x) (((x) << 16) & GENMASK(31, 16)) -+#define ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_DROP_ENA_M GENMASK(31, 16) -+#define ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_DROP_ENA_X(x) (((x) & GENMASK(31, 16)) >> 16) -+#define ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA(x) ((x) & GENMASK(15, 0)) -+#define ANA_PORT_CPU_FWD_BPDU_CFG_BPDU_REDIR_ENA_M GENMASK(15, 0) -+ -+#define ANA_PORT_CPU_FWD_GARP_CFG_GSZ 0x100 -+ -+#define ANA_PORT_CPU_FWD_GARP_CFG_GARP_DROP_ENA(x) (((x) << 16) & GENMASK(31, 16)) -+#define ANA_PORT_CPU_FWD_GARP_CFG_GARP_DROP_ENA_M GENMASK(31, 16) -+#define ANA_PORT_CPU_FWD_GARP_CFG_GARP_DROP_ENA_X(x) (((x) & GENMASK(31, 16)) >> 16) -+#define ANA_PORT_CPU_FWD_GARP_CFG_GARP_REDIR_ENA(x) ((x) & GENMASK(15, 0)) -+#define ANA_PORT_CPU_FWD_GARP_CFG_GARP_REDIR_ENA_M GENMASK(15, 0) -+ -+#define ANA_PORT_CPU_FWD_CCM_CFG_GSZ 0x100 -+ -+#define ANA_PORT_CPU_FWD_CCM_CFG_CCM_DROP_ENA(x) (((x) << 16) & GENMASK(31, 16)) -+#define ANA_PORT_CPU_FWD_CCM_CFG_CCM_DROP_ENA_M GENMASK(31, 16) -+#define ANA_PORT_CPU_FWD_CCM_CFG_CCM_DROP_ENA_X(x) (((x) & GENMASK(31, 16)) >> 16) -+#define ANA_PORT_CPU_FWD_CCM_CFG_CCM_REDIR_ENA(x) ((x) & GENMASK(15, 0)) -+#define ANA_PORT_CPU_FWD_CCM_CFG_CCM_REDIR_ENA_M GENMASK(15, 0) -+ -+#define ANA_PORT_PORT_CFG_GSZ 0x100 -+ -+#define ANA_PORT_PORT_CFG_SRC_MIRROR_ENA BIT(15) -+#define ANA_PORT_PORT_CFG_LIMIT_DROP BIT(14) -+#define ANA_PORT_PORT_CFG_LIMIT_CPU BIT(13) -+#define ANA_PORT_PORT_CFG_LOCKED_PORTMOVE_DROP BIT(12) -+#define ANA_PORT_PORT_CFG_LOCKED_PORTMOVE_CPU BIT(11) -+#define ANA_PORT_PORT_CFG_LEARNDROP BIT(10) -+#define ANA_PORT_PORT_CFG_LEARNCPU BIT(9) -+#define ANA_PORT_PORT_CFG_LEARNAUTO BIT(8) -+#define ANA_PORT_PORT_CFG_LEARN_ENA BIT(7) -+#define ANA_PORT_PORT_CFG_RECV_ENA BIT(6) -+#define ANA_PORT_PORT_CFG_PORTID_VAL(x) (((x) << 2) & GENMASK(5, 2)) -+#define ANA_PORT_PORT_CFG_PORTID_VAL_M GENMASK(5, 2) -+#define ANA_PORT_PORT_CFG_PORTID_VAL_X(x) (((x) & GENMASK(5, 2)) >> 2) -+#define ANA_PORT_PORT_CFG_USE_B_DOM_TBL BIT(1) -+#define ANA_PORT_PORT_CFG_LSR_MODE BIT(0) -+ -+#define ANA_PORT_POL_CFG_GSZ 0x100 -+ -+#define ANA_PORT_POL_CFG_POL_CPU_REDIR_8021 BIT(19) -+#define ANA_PORT_POL_CFG_POL_CPU_REDIR_IP BIT(18) -+#define ANA_PORT_POL_CFG_PORT_POL_ENA BIT(17) -+#define ANA_PORT_POL_CFG_QUEUE_POL_ENA(x) (((x) << 9) & GENMASK(16, 9)) -+#define ANA_PORT_POL_CFG_QUEUE_POL_ENA_M GENMASK(16, 9) -+#define ANA_PORT_POL_CFG_QUEUE_POL_ENA_X(x) (((x) & GENMASK(16, 9)) >> 9) -+#define ANA_PORT_POL_CFG_POL_ORDER(x) ((x) & GENMASK(8, 0)) -+#define ANA_PORT_POL_CFG_POL_ORDER_M GENMASK(8, 0) -+ -+#define ANA_PORT_PTP_CFG_GSZ 0x100 -+ -+#define ANA_PORT_PTP_CFG_PTP_BACKPLANE_MODE BIT(0) -+ -+#define ANA_PORT_PTP_DLY1_CFG_GSZ 0x100 -+ -+#define ANA_PORT_PTP_DLY2_CFG_GSZ 0x100 -+ -+#define ANA_PORT_SFID_CFG_GSZ 0x100 -+#define ANA_PORT_SFID_CFG_RSZ 0x4 -+ -+#define ANA_PORT_SFID_CFG_SFID_VALID BIT(8) -+#define ANA_PORT_SFID_CFG_SFID(x) ((x) & GENMASK(7, 0)) -+#define ANA_PORT_SFID_CFG_SFID_M GENMASK(7, 0) -+ -+#define ANA_PFC_PFC_CFG_GSZ 0x40 -+ -+#define ANA_PFC_PFC_CFG_RX_PFC_ENA(x) (((x) << 2) & GENMASK(9, 2)) -+#define ANA_PFC_PFC_CFG_RX_PFC_ENA_M GENMASK(9, 2) -+#define ANA_PFC_PFC_CFG_RX_PFC_ENA_X(x) (((x) & GENMASK(9, 2)) >> 2) -+#define ANA_PFC_PFC_CFG_FC_LINK_SPEED(x) ((x) & GENMASK(1, 0)) -+#define ANA_PFC_PFC_CFG_FC_LINK_SPEED_M GENMASK(1, 0) -+ -+#define ANA_PFC_PFC_TIMER_GSZ 0x40 -+#define ANA_PFC_PFC_TIMER_RSZ 0x4 -+ -+#define ANA_IPT_OAM_MEP_CFG_GSZ 0x8 -+ -+#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_P(x) (((x) << 6) & GENMASK(10, 6)) -+#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_P_M GENMASK(10, 6) -+#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_P_X(x) (((x) & GENMASK(10, 6)) >> 6) -+#define ANA_IPT_OAM_MEP_CFG_MEP_IDX(x) (((x) << 1) & GENMASK(5, 1)) -+#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_M GENMASK(5, 1) -+#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_X(x) (((x) & GENMASK(5, 1)) >> 1) -+#define ANA_IPT_OAM_MEP_CFG_MEP_IDX_ENA BIT(0) -+ -+#define ANA_IPT_IPT_GSZ 0x8 -+ -+#define ANA_IPT_IPT_IPT_CFG(x) (((x) << 15) & GENMASK(16, 15)) -+#define ANA_IPT_IPT_IPT_CFG_M GENMASK(16, 15) -+#define ANA_IPT_IPT_IPT_CFG_X(x) (((x) & GENMASK(16, 15)) >> 15) -+#define ANA_IPT_IPT_ISDX_P(x) (((x) << 7) & GENMASK(14, 7)) -+#define ANA_IPT_IPT_ISDX_P_M GENMASK(14, 7) -+#define ANA_IPT_IPT_ISDX_P_X(x) (((x) & GENMASK(14, 7)) >> 7) -+#define ANA_IPT_IPT_PPT_IDX(x) ((x) & GENMASK(6, 0)) -+#define ANA_IPT_IPT_PPT_IDX_M GENMASK(6, 0) -+ -+#define ANA_PPT_PPT_RSZ 0x4 -+ -+#define ANA_FID_MAP_FID_MAP_RSZ 0x4 -+ -+#define ANA_FID_MAP_FID_MAP_FID_C_VAL(x) (((x) << 6) & GENMASK(11, 6)) -+#define ANA_FID_MAP_FID_MAP_FID_C_VAL_M GENMASK(11, 6) -+#define ANA_FID_MAP_FID_MAP_FID_C_VAL_X(x) (((x) & GENMASK(11, 6)) >> 6) -+#define ANA_FID_MAP_FID_MAP_FID_B_VAL(x) ((x) & GENMASK(5, 0)) -+#define ANA_FID_MAP_FID_MAP_FID_B_VAL_M GENMASK(5, 0) -+ -+#define ANA_AGGR_CFG_AC_RND_ENA BIT(7) -+#define ANA_AGGR_CFG_AC_DMAC_ENA BIT(6) -+#define ANA_AGGR_CFG_AC_SMAC_ENA BIT(5) -+#define ANA_AGGR_CFG_AC_IP6_FLOW_LBL_ENA BIT(4) -+#define ANA_AGGR_CFG_AC_IP6_TCPUDP_ENA BIT(3) -+#define ANA_AGGR_CFG_AC_IP4_SIPDIP_ENA BIT(2) -+#define ANA_AGGR_CFG_AC_IP4_TCPUDP_ENA BIT(1) -+#define ANA_AGGR_CFG_AC_ISDX_ENA BIT(0) -+ -+#define ANA_CPUQ_CFG_CPUQ_MLD(x) (((x) << 27) & GENMASK(29, 27)) -+#define ANA_CPUQ_CFG_CPUQ_MLD_M GENMASK(29, 27) -+#define ANA_CPUQ_CFG_CPUQ_MLD_X(x) (((x) & GENMASK(29, 27)) >> 27) -+#define ANA_CPUQ_CFG_CPUQ_IGMP(x) (((x) << 24) & GENMASK(26, 24)) -+#define ANA_CPUQ_CFG_CPUQ_IGMP_M GENMASK(26, 24) -+#define ANA_CPUQ_CFG_CPUQ_IGMP_X(x) (((x) & GENMASK(26, 24)) >> 24) -+#define ANA_CPUQ_CFG_CPUQ_IPMC_CTRL(x) (((x) << 21) & GENMASK(23, 21)) -+#define ANA_CPUQ_CFG_CPUQ_IPMC_CTRL_M GENMASK(23, 21) -+#define ANA_CPUQ_CFG_CPUQ_IPMC_CTRL_X(x) (((x) & GENMASK(23, 21)) >> 21) -+#define ANA_CPUQ_CFG_CPUQ_ALLBRIDGE(x) (((x) << 18) & GENMASK(20, 18)) -+#define ANA_CPUQ_CFG_CPUQ_ALLBRIDGE_M GENMASK(20, 18) -+#define ANA_CPUQ_CFG_CPUQ_ALLBRIDGE_X(x) (((x) & GENMASK(20, 18)) >> 18) -+#define ANA_CPUQ_CFG_CPUQ_LOCKED_PORTMOVE(x) (((x) << 15) & GENMASK(17, 15)) -+#define ANA_CPUQ_CFG_CPUQ_LOCKED_PORTMOVE_M GENMASK(17, 15) -+#define ANA_CPUQ_CFG_CPUQ_LOCKED_PORTMOVE_X(x) (((x) & GENMASK(17, 15)) >> 15) -+#define ANA_CPUQ_CFG_CPUQ_SRC_COPY(x) (((x) << 12) & GENMASK(14, 12)) -+#define ANA_CPUQ_CFG_CPUQ_SRC_COPY_M GENMASK(14, 12) -+#define ANA_CPUQ_CFG_CPUQ_SRC_COPY_X(x) (((x) & GENMASK(14, 12)) >> 12) -+#define ANA_CPUQ_CFG_CPUQ_MAC_COPY(x) (((x) << 9) & GENMASK(11, 9)) -+#define ANA_CPUQ_CFG_CPUQ_MAC_COPY_M GENMASK(11, 9) -+#define ANA_CPUQ_CFG_CPUQ_MAC_COPY_X(x) (((x) & GENMASK(11, 9)) >> 9) -+#define ANA_CPUQ_CFG_CPUQ_LRN(x) (((x) << 6) & GENMASK(8, 6)) -+#define ANA_CPUQ_CFG_CPUQ_LRN_M GENMASK(8, 6) -+#define ANA_CPUQ_CFG_CPUQ_LRN_X(x) (((x) & GENMASK(8, 6)) >> 6) -+#define ANA_CPUQ_CFG_CPUQ_MIRROR(x) (((x) << 3) & GENMASK(5, 3)) -+#define ANA_CPUQ_CFG_CPUQ_MIRROR_M GENMASK(5, 3) -+#define ANA_CPUQ_CFG_CPUQ_MIRROR_X(x) (((x) & GENMASK(5, 3)) >> 3) -+#define ANA_CPUQ_CFG_CPUQ_SFLOW(x) ((x) & GENMASK(2, 0)) -+#define ANA_CPUQ_CFG_CPUQ_SFLOW_M GENMASK(2, 0) -+ -+#define ANA_CPUQ_8021_CFG_RSZ 0x4 -+ -+#define ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL(x) (((x) << 6) & GENMASK(8, 6)) -+#define ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL_M GENMASK(8, 6) -+#define ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL_X(x) (((x) & GENMASK(8, 6)) >> 6) -+#define ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL(x) (((x) << 3) & GENMASK(5, 3)) -+#define ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL_M GENMASK(5, 3) -+#define ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL_X(x) (((x) & GENMASK(5, 3)) >> 3) -+#define ANA_CPUQ_8021_CFG_CPUQ_CCM_VAL(x) ((x) & GENMASK(2, 0)) -+#define ANA_CPUQ_8021_CFG_CPUQ_CCM_VAL_M GENMASK(2, 0) -+ -+#define ANA_DSCP_CFG_RSZ 0x4 -+ -+#define ANA_DSCP_CFG_DP_DSCP_VAL BIT(11) -+#define ANA_DSCP_CFG_QOS_DSCP_VAL(x) (((x) << 8) & GENMASK(10, 8)) -+#define ANA_DSCP_CFG_QOS_DSCP_VAL_M GENMASK(10, 8) -+#define ANA_DSCP_CFG_QOS_DSCP_VAL_X(x) (((x) & GENMASK(10, 8)) >> 8) -+#define ANA_DSCP_CFG_DSCP_TRANSLATE_VAL(x) (((x) << 2) & GENMASK(7, 2)) -+#define ANA_DSCP_CFG_DSCP_TRANSLATE_VAL_M GENMASK(7, 2) -+#define ANA_DSCP_CFG_DSCP_TRANSLATE_VAL_X(x) (((x) & GENMASK(7, 2)) >> 2) -+#define ANA_DSCP_CFG_DSCP_TRUST_ENA BIT(1) -+#define ANA_DSCP_CFG_DSCP_REWR_ENA BIT(0) -+ -+#define ANA_DSCP_REWR_CFG_RSZ 0x4 -+ -+#define ANA_VCAP_RNG_TYPE_CFG_RSZ 0x4 -+ -+#define ANA_VCAP_RNG_VAL_CFG_RSZ 0x4 -+ -+#define ANA_VCAP_RNG_VAL_CFG_VCAP_RNG_MIN_VAL(x) (((x) << 16) & GENMASK(31, 16)) -+#define ANA_VCAP_RNG_VAL_CFG_VCAP_RNG_MIN_VAL_M GENMASK(31, 16) -+#define ANA_VCAP_RNG_VAL_CFG_VCAP_RNG_MIN_VAL_X(x) (((x) & GENMASK(31, 16)) >> 16) -+#define ANA_VCAP_RNG_VAL_CFG_VCAP_RNG_MAX_VAL(x) ((x) & GENMASK(15, 0)) -+#define ANA_VCAP_RNG_VAL_CFG_VCAP_RNG_MAX_VAL_M GENMASK(15, 0) -+ -+#define ANA_VRAP_CFG_VRAP_VLAN_AWARE_ENA BIT(12) -+#define ANA_VRAP_CFG_VRAP_VID(x) ((x) & GENMASK(11, 0)) -+#define ANA_VRAP_CFG_VRAP_VID_M GENMASK(11, 0) -+ -+#define ANA_DISCARD_CFG_DROP_TAGGING_ISDX0 BIT(3) -+#define ANA_DISCARD_CFG_DROP_CTRLPROT_ISDX0 BIT(2) -+#define ANA_DISCARD_CFG_DROP_TAGGING_S2_ENA BIT(1) -+#define ANA_DISCARD_CFG_DROP_CTRLPROT_S2_ENA BIT(0) -+ -+#define ANA_FID_CFG_VID_MC_ENA BIT(0) -+ -+#define ANA_POL_PIR_CFG_GSZ 0x20 -+ -+#define ANA_POL_PIR_CFG_PIR_RATE(x) (((x) << 6) & GENMASK(20, 6)) -+#define ANA_POL_PIR_CFG_PIR_RATE_M GENMASK(20, 6) -+#define ANA_POL_PIR_CFG_PIR_RATE_X(x) (((x) & GENMASK(20, 6)) >> 6) -+#define ANA_POL_PIR_CFG_PIR_BURST(x) ((x) & GENMASK(5, 0)) -+#define ANA_POL_PIR_CFG_PIR_BURST_M GENMASK(5, 0) -+ -+#define ANA_POL_CIR_CFG_GSZ 0x20 -+ -+#define ANA_POL_CIR_CFG_CIR_RATE(x) (((x) << 6) & GENMASK(20, 6)) -+#define ANA_POL_CIR_CFG_CIR_RATE_M GENMASK(20, 6) -+#define ANA_POL_CIR_CFG_CIR_RATE_X(x) (((x) & GENMASK(20, 6)) >> 6) -+#define ANA_POL_CIR_CFG_CIR_BURST(x) ((x) & GENMASK(5, 0)) -+#define ANA_POL_CIR_CFG_CIR_BURST_M GENMASK(5, 0) -+ -+#define ANA_POL_MODE_CFG_GSZ 0x20 -+ -+#define ANA_POL_MODE_CFG_IPG_SIZE(x) (((x) << 5) & GENMASK(9, 5)) -+#define ANA_POL_MODE_CFG_IPG_SIZE_M GENMASK(9, 5) -+#define ANA_POL_MODE_CFG_IPG_SIZE_X(x) (((x) & GENMASK(9, 5)) >> 5) -+#define ANA_POL_MODE_CFG_FRM_MODE(x) (((x) << 3) & GENMASK(4, 3)) -+#define ANA_POL_MODE_CFG_FRM_MODE_M GENMASK(4, 3) -+#define ANA_POL_MODE_CFG_FRM_MODE_X(x) (((x) & GENMASK(4, 3)) >> 3) -+#define ANA_POL_MODE_CFG_DLB_COUPLED BIT(2) -+#define ANA_POL_MODE_CFG_CIR_ENA BIT(1) -+#define ANA_POL_MODE_CFG_OVERSHOOT_ENA BIT(0) -+ -+#define ANA_POL_PIR_STATE_GSZ 0x20 -+ -+#define ANA_POL_CIR_STATE_GSZ 0x20 -+ -+#define ANA_POL_STATE_GSZ 0x20 -+ -+#define ANA_POL_FLOWC_RSZ 0x4 -+ -+#define ANA_POL_FLOWC_POL_FLOWC BIT(0) -+ -+#define ANA_POL_HYST_POL_FC_HYST(x) (((x) << 4) & GENMASK(9, 4)) -+#define ANA_POL_HYST_POL_FC_HYST_M GENMASK(9, 4) -+#define ANA_POL_HYST_POL_FC_HYST_X(x) (((x) & GENMASK(9, 4)) >> 4) -+#define ANA_POL_HYST_POL_STOP_HYST(x) ((x) & GENMASK(3, 0)) -+#define ANA_POL_HYST_POL_STOP_HYST_M GENMASK(3, 0) -+ -+#define ANA_POL_MISC_CFG_POL_CLOSE_ALL BIT(1) -+#define ANA_POL_MISC_CFG_POL_LEAK_DIS BIT(0) -+ -+#endif ---- /dev/null -+++ b/include/soc/mscc/ocelot_dev.h -@@ -0,0 +1,275 @@ -+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ -+/* -+ * Microsemi Ocelot Switch driver -+ * -+ * Copyright (c) 2017 Microsemi Corporation -+ */ -+ -+#ifndef _MSCC_OCELOT_DEV_H_ -+#define _MSCC_OCELOT_DEV_H_ -+ -+#define DEV_CLOCK_CFG 0x0 -+ -+#define DEV_CLOCK_CFG_MAC_TX_RST BIT(7) -+#define DEV_CLOCK_CFG_MAC_RX_RST BIT(6) -+#define DEV_CLOCK_CFG_PCS_TX_RST BIT(5) -+#define DEV_CLOCK_CFG_PCS_RX_RST BIT(4) -+#define DEV_CLOCK_CFG_PORT_RST BIT(3) -+#define DEV_CLOCK_CFG_PHY_RST BIT(2) -+#define DEV_CLOCK_CFG_LINK_SPEED(x) ((x) & GENMASK(1, 0)) -+#define DEV_CLOCK_CFG_LINK_SPEED_M GENMASK(1, 0) -+ -+#define DEV_PORT_MISC 0x4 -+ -+#define DEV_PORT_MISC_FWD_ERROR_ENA BIT(4) -+#define DEV_PORT_MISC_FWD_PAUSE_ENA BIT(3) -+#define DEV_PORT_MISC_FWD_CTRL_ENA BIT(2) -+#define DEV_PORT_MISC_DEV_LOOP_ENA BIT(1) -+#define DEV_PORT_MISC_HDX_FAST_DIS BIT(0) -+ -+#define DEV_EVENTS 0x8 -+ -+#define DEV_EEE_CFG 0xc -+ -+#define DEV_EEE_CFG_EEE_ENA BIT(22) -+#define DEV_EEE_CFG_EEE_TIMER_AGE(x) (((x) << 15) & GENMASK(21, 15)) -+#define DEV_EEE_CFG_EEE_TIMER_AGE_M GENMASK(21, 15) -+#define DEV_EEE_CFG_EEE_TIMER_AGE_X(x) (((x) & GENMASK(21, 15)) >> 15) -+#define DEV_EEE_CFG_EEE_TIMER_WAKEUP(x) (((x) << 8) & GENMASK(14, 8)) -+#define DEV_EEE_CFG_EEE_TIMER_WAKEUP_M GENMASK(14, 8) -+#define DEV_EEE_CFG_EEE_TIMER_WAKEUP_X(x) (((x) & GENMASK(14, 8)) >> 8) -+#define DEV_EEE_CFG_EEE_TIMER_HOLDOFF(x) (((x) << 1) & GENMASK(7, 1)) -+#define DEV_EEE_CFG_EEE_TIMER_HOLDOFF_M GENMASK(7, 1) -+#define DEV_EEE_CFG_EEE_TIMER_HOLDOFF_X(x) (((x) & GENMASK(7, 1)) >> 1) -+#define DEV_EEE_CFG_PORT_LPI BIT(0) -+ -+#define DEV_RX_PATH_DELAY 0x10 -+ -+#define DEV_TX_PATH_DELAY 0x14 -+ -+#define DEV_PTP_PREDICT_CFG 0x18 -+ -+#define DEV_PTP_PREDICT_CFG_PTP_PHY_PREDICT_CFG(x) (((x) << 4) & GENMASK(11, 4)) -+#define DEV_PTP_PREDICT_CFG_PTP_PHY_PREDICT_CFG_M GENMASK(11, 4) -+#define DEV_PTP_PREDICT_CFG_PTP_PHY_PREDICT_CFG_X(x) (((x) & GENMASK(11, 4)) >> 4) -+#define DEV_PTP_PREDICT_CFG_PTP_PHASE_PREDICT_CFG(x) ((x) & GENMASK(3, 0)) -+#define DEV_PTP_PREDICT_CFG_PTP_PHASE_PREDICT_CFG_M GENMASK(3, 0) -+ -+#define DEV_MAC_ENA_CFG 0x1c -+ -+#define DEV_MAC_ENA_CFG_RX_ENA BIT(4) -+#define DEV_MAC_ENA_CFG_TX_ENA BIT(0) -+ -+#define DEV_MAC_MODE_CFG 0x20 -+ -+#define DEV_MAC_MODE_CFG_FC_WORD_SYNC_ENA BIT(8) -+#define DEV_MAC_MODE_CFG_GIGA_MODE_ENA BIT(4) -+#define DEV_MAC_MODE_CFG_FDX_ENA BIT(0) -+ -+#define DEV_MAC_MAXLEN_CFG 0x24 -+ -+#define DEV_MAC_TAGS_CFG 0x28 -+ -+#define DEV_MAC_TAGS_CFG_TAG_ID(x) (((x) << 16) & GENMASK(31, 16)) -+#define DEV_MAC_TAGS_CFG_TAG_ID_M GENMASK(31, 16) -+#define DEV_MAC_TAGS_CFG_TAG_ID_X(x) (((x) & GENMASK(31, 16)) >> 16) -+#define DEV_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA BIT(2) -+#define DEV_MAC_TAGS_CFG_PB_ENA BIT(1) -+#define DEV_MAC_TAGS_CFG_VLAN_AWR_ENA BIT(0) -+ -+#define DEV_MAC_ADV_CHK_CFG 0x2c -+ -+#define DEV_MAC_ADV_CHK_CFG_LEN_DROP_ENA BIT(0) -+ -+#define DEV_MAC_IFG_CFG 0x30 -+ -+#define DEV_MAC_IFG_CFG_RESTORE_OLD_IPG_CHECK BIT(17) -+#define DEV_MAC_IFG_CFG_REDUCED_TX_IFG BIT(16) -+#define DEV_MAC_IFG_CFG_TX_IFG(x) (((x) << 8) & GENMASK(12, 8)) -+#define DEV_MAC_IFG_CFG_TX_IFG_M GENMASK(12, 8) -+#define DEV_MAC_IFG_CFG_TX_IFG_X(x) (((x) & GENMASK(12, 8)) >> 8) -+#define DEV_MAC_IFG_CFG_RX_IFG2(x) (((x) << 4) & GENMASK(7, 4)) -+#define DEV_MAC_IFG_CFG_RX_IFG2_M GENMASK(7, 4) -+#define DEV_MAC_IFG_CFG_RX_IFG2_X(x) (((x) & GENMASK(7, 4)) >> 4) -+#define DEV_MAC_IFG_CFG_RX_IFG1(x) ((x) & GENMASK(3, 0)) -+#define DEV_MAC_IFG_CFG_RX_IFG1_M GENMASK(3, 0) -+ -+#define DEV_MAC_HDX_CFG 0x34 -+ -+#define DEV_MAC_HDX_CFG_BYPASS_COL_SYNC BIT(26) -+#define DEV_MAC_HDX_CFG_OB_ENA BIT(25) -+#define DEV_MAC_HDX_CFG_WEXC_DIS BIT(24) -+#define DEV_MAC_HDX_CFG_SEED(x) (((x) << 16) & GENMASK(23, 16)) -+#define DEV_MAC_HDX_CFG_SEED_M GENMASK(23, 16) -+#define DEV_MAC_HDX_CFG_SEED_X(x) (((x) & GENMASK(23, 16)) >> 16) -+#define DEV_MAC_HDX_CFG_SEED_LOAD BIT(12) -+#define DEV_MAC_HDX_CFG_RETRY_AFTER_EXC_COL_ENA BIT(8) -+#define DEV_MAC_HDX_CFG_LATE_COL_POS(x) ((x) & GENMASK(6, 0)) -+#define DEV_MAC_HDX_CFG_LATE_COL_POS_M GENMASK(6, 0) -+ -+#define DEV_MAC_DBG_CFG 0x38 -+ -+#define DEV_MAC_DBG_CFG_TBI_MODE BIT(4) -+#define DEV_MAC_DBG_CFG_IFG_CRS_EXT_CHK_ENA BIT(0) -+ -+#define DEV_MAC_FC_MAC_LOW_CFG 0x3c -+ -+#define DEV_MAC_FC_MAC_HIGH_CFG 0x40 -+ -+#define DEV_MAC_STICKY 0x44 -+ -+#define DEV_MAC_STICKY_RX_IPG_SHRINK_STICKY BIT(9) -+#define DEV_MAC_STICKY_RX_PREAM_SHRINK_STICKY BIT(8) -+#define DEV_MAC_STICKY_RX_CARRIER_EXT_STICKY BIT(7) -+#define DEV_MAC_STICKY_RX_CARRIER_EXT_ERR_STICKY BIT(6) -+#define DEV_MAC_STICKY_RX_JUNK_STICKY BIT(5) -+#define DEV_MAC_STICKY_TX_RETRANSMIT_STICKY BIT(4) -+#define DEV_MAC_STICKY_TX_JAM_STICKY BIT(3) -+#define DEV_MAC_STICKY_TX_FIFO_OFLW_STICKY BIT(2) -+#define DEV_MAC_STICKY_TX_FRM_LEN_OVR_STICKY BIT(1) -+#define DEV_MAC_STICKY_TX_ABORT_STICKY BIT(0) -+ -+#define PCS1G_CFG 0x48 -+ -+#define PCS1G_CFG_LINK_STATUS_TYPE BIT(4) -+#define PCS1G_CFG_AN_LINK_CTRL_ENA BIT(1) -+#define PCS1G_CFG_PCS_ENA BIT(0) -+ -+#define PCS1G_MODE_CFG 0x4c -+ -+#define PCS1G_MODE_CFG_UNIDIR_MODE_ENA BIT(4) -+#define PCS1G_MODE_CFG_SGMII_MODE_ENA BIT(0) -+ -+#define PCS1G_SD_CFG 0x50 -+ -+#define PCS1G_SD_CFG_SD_SEL BIT(8) -+#define PCS1G_SD_CFG_SD_POL BIT(4) -+#define PCS1G_SD_CFG_SD_ENA BIT(0) -+ -+#define PCS1G_ANEG_CFG 0x54 -+ -+#define PCS1G_ANEG_CFG_ADV_ABILITY(x) (((x) << 16) & GENMASK(31, 16)) -+#define PCS1G_ANEG_CFG_ADV_ABILITY_M GENMASK(31, 16) -+#define PCS1G_ANEG_CFG_ADV_ABILITY_X(x) (((x) & GENMASK(31, 16)) >> 16) -+#define PCS1G_ANEG_CFG_SW_RESOLVE_ENA BIT(8) -+#define PCS1G_ANEG_CFG_ANEG_RESTART_ONE_SHOT BIT(1) -+#define PCS1G_ANEG_CFG_ANEG_ENA BIT(0) -+ -+#define PCS1G_ANEG_NP_CFG 0x58 -+ -+#define PCS1G_ANEG_NP_CFG_NP_TX(x) (((x) << 16) & GENMASK(31, 16)) -+#define PCS1G_ANEG_NP_CFG_NP_TX_M GENMASK(31, 16) -+#define PCS1G_ANEG_NP_CFG_NP_TX_X(x) (((x) & GENMASK(31, 16)) >> 16) -+#define PCS1G_ANEG_NP_CFG_NP_LOADED_ONE_SHOT BIT(0) -+ -+#define PCS1G_LB_CFG 0x5c -+ -+#define PCS1G_LB_CFG_RA_ENA BIT(4) -+#define PCS1G_LB_CFG_GMII_PHY_LB_ENA BIT(1) -+#define PCS1G_LB_CFG_TBI_HOST_LB_ENA BIT(0) -+ -+#define PCS1G_DBG_CFG 0x60 -+ -+#define PCS1G_DBG_CFG_UDLT BIT(0) -+ -+#define PCS1G_CDET_CFG 0x64 -+ -+#define PCS1G_CDET_CFG_CDET_ENA BIT(0) -+ -+#define PCS1G_ANEG_STATUS 0x68 -+ -+#define PCS1G_ANEG_STATUS_LP_ADV_ABILITY(x) (((x) << 16) & GENMASK(31, 16)) -+#define PCS1G_ANEG_STATUS_LP_ADV_ABILITY_M GENMASK(31, 16) -+#define PCS1G_ANEG_STATUS_LP_ADV_ABILITY_X(x) (((x) & GENMASK(31, 16)) >> 16) -+#define PCS1G_ANEG_STATUS_PR BIT(4) -+#define PCS1G_ANEG_STATUS_PAGE_RX_STICKY BIT(3) -+#define PCS1G_ANEG_STATUS_ANEG_COMPLETE BIT(0) -+ -+#define PCS1G_ANEG_NP_STATUS 0x6c -+ -+#define PCS1G_LINK_STATUS 0x70 -+ -+#define PCS1G_LINK_STATUS_DELAY_VAR(x) (((x) << 12) & GENMASK(15, 12)) -+#define PCS1G_LINK_STATUS_DELAY_VAR_M GENMASK(15, 12) -+#define PCS1G_LINK_STATUS_DELAY_VAR_X(x) (((x) & GENMASK(15, 12)) >> 12) -+#define PCS1G_LINK_STATUS_SIGNAL_DETECT BIT(8) -+#define PCS1G_LINK_STATUS_LINK_STATUS BIT(4) -+#define PCS1G_LINK_STATUS_SYNC_STATUS BIT(0) -+ -+#define PCS1G_LINK_DOWN_CNT 0x74 -+ -+#define PCS1G_STICKY 0x78 -+ -+#define PCS1G_STICKY_LINK_DOWN_STICKY BIT(4) -+#define PCS1G_STICKY_OUT_OF_SYNC_STICKY BIT(0) -+ -+#define PCS1G_DEBUG_STATUS 0x7c -+ -+#define PCS1G_LPI_CFG 0x80 -+ -+#define PCS1G_LPI_CFG_QSGMII_MS_SEL BIT(20) -+#define PCS1G_LPI_CFG_RX_LPI_OUT_DIS BIT(17) -+#define PCS1G_LPI_CFG_LPI_TESTMODE BIT(16) -+#define PCS1G_LPI_CFG_LPI_RX_WTIM(x) (((x) << 4) & GENMASK(5, 4)) -+#define PCS1G_LPI_CFG_LPI_RX_WTIM_M GENMASK(5, 4) -+#define PCS1G_LPI_CFG_LPI_RX_WTIM_X(x) (((x) & GENMASK(5, 4)) >> 4) -+#define PCS1G_LPI_CFG_TX_ASSERT_LPIDLE BIT(0) -+ -+#define PCS1G_LPI_WAKE_ERROR_CNT 0x84 -+ -+#define PCS1G_LPI_STATUS 0x88 -+ -+#define PCS1G_LPI_STATUS_RX_LPI_FAIL BIT(16) -+#define PCS1G_LPI_STATUS_RX_LPI_EVENT_STICKY BIT(12) -+#define PCS1G_LPI_STATUS_RX_QUIET BIT(9) -+#define PCS1G_LPI_STATUS_RX_LPI_MODE BIT(8) -+#define PCS1G_LPI_STATUS_TX_LPI_EVENT_STICKY BIT(4) -+#define PCS1G_LPI_STATUS_TX_QUIET BIT(1) -+#define PCS1G_LPI_STATUS_TX_LPI_MODE BIT(0) -+ -+#define PCS1G_TSTPAT_MODE_CFG 0x8c -+ -+#define PCS1G_TSTPAT_STATUS 0x90 -+ -+#define PCS1G_TSTPAT_STATUS_JTP_ERR_CNT(x) (((x) << 8) & GENMASK(15, 8)) -+#define PCS1G_TSTPAT_STATUS_JTP_ERR_CNT_M GENMASK(15, 8) -+#define PCS1G_TSTPAT_STATUS_JTP_ERR_CNT_X(x) (((x) & GENMASK(15, 8)) >> 8) -+#define PCS1G_TSTPAT_STATUS_JTP_ERR BIT(4) -+#define PCS1G_TSTPAT_STATUS_JTP_LOCK BIT(0) -+ -+#define DEV_PCS_FX100_CFG 0x94 -+ -+#define DEV_PCS_FX100_CFG_SD_SEL BIT(26) -+#define DEV_PCS_FX100_CFG_SD_POL BIT(25) -+#define DEV_PCS_FX100_CFG_SD_ENA BIT(24) -+#define DEV_PCS_FX100_CFG_LOOPBACK_ENA BIT(20) -+#define DEV_PCS_FX100_CFG_SWAP_MII_ENA BIT(16) -+#define DEV_PCS_FX100_CFG_RXBITSEL(x) (((x) << 12) & GENMASK(15, 12)) -+#define DEV_PCS_FX100_CFG_RXBITSEL_M GENMASK(15, 12) -+#define DEV_PCS_FX100_CFG_RXBITSEL_X(x) (((x) & GENMASK(15, 12)) >> 12) -+#define DEV_PCS_FX100_CFG_SIGDET_CFG(x) (((x) << 9) & GENMASK(10, 9)) -+#define DEV_PCS_FX100_CFG_SIGDET_CFG_M GENMASK(10, 9) -+#define DEV_PCS_FX100_CFG_SIGDET_CFG_X(x) (((x) & GENMASK(10, 9)) >> 9) -+#define DEV_PCS_FX100_CFG_LINKHYST_TM_ENA BIT(8) -+#define DEV_PCS_FX100_CFG_LINKHYSTTIMER(x) (((x) << 4) & GENMASK(7, 4)) -+#define DEV_PCS_FX100_CFG_LINKHYSTTIMER_M GENMASK(7, 4) -+#define DEV_PCS_FX100_CFG_LINKHYSTTIMER_X(x) (((x) & GENMASK(7, 4)) >> 4) -+#define DEV_PCS_FX100_CFG_UNIDIR_MODE_ENA BIT(3) -+#define DEV_PCS_FX100_CFG_FEFCHK_ENA BIT(2) -+#define DEV_PCS_FX100_CFG_FEFGEN_ENA BIT(1) -+#define DEV_PCS_FX100_CFG_PCS_ENA BIT(0) -+ -+#define DEV_PCS_FX100_STATUS 0x98 -+ -+#define DEV_PCS_FX100_STATUS_EDGE_POS_PTP(x) (((x) << 8) & GENMASK(11, 8)) -+#define DEV_PCS_FX100_STATUS_EDGE_POS_PTP_M GENMASK(11, 8) -+#define DEV_PCS_FX100_STATUS_EDGE_POS_PTP_X(x) (((x) & GENMASK(11, 8)) >> 8) -+#define DEV_PCS_FX100_STATUS_PCS_ERROR_STICKY BIT(7) -+#define DEV_PCS_FX100_STATUS_FEF_FOUND_STICKY BIT(6) -+#define DEV_PCS_FX100_STATUS_SSD_ERROR_STICKY BIT(5) -+#define DEV_PCS_FX100_STATUS_SYNC_LOST_STICKY BIT(4) -+#define DEV_PCS_FX100_STATUS_FEF_STATUS BIT(2) -+#define DEV_PCS_FX100_STATUS_SIGNAL_DETECT BIT(1) -+#define DEV_PCS_FX100_STATUS_SYNC_STATUS BIT(0) -+ -+#endif ---- /dev/null -+++ b/include/soc/mscc/ocelot_qsys.h -@@ -0,0 +1,270 @@ -+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ -+/* -+ * Microsemi Ocelot Switch driver -+ * -+ * Copyright (c) 2017 Microsemi Corporation -+ */ -+ -+#ifndef _MSCC_OCELOT_QSYS_H_ -+#define _MSCC_OCELOT_QSYS_H_ -+ -+#define QSYS_PORT_MODE_RSZ 0x4 -+ -+#define QSYS_PORT_MODE_DEQUEUE_DIS BIT(1) -+#define QSYS_PORT_MODE_DEQUEUE_LATE BIT(0) -+ -+#define QSYS_SWITCH_PORT_MODE_RSZ 0x4 -+ -+#define QSYS_SWITCH_PORT_MODE_PORT_ENA BIT(14) -+#define QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(x) (((x) << 11) & GENMASK(13, 11)) -+#define QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG_M GENMASK(13, 11) -+#define QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG_X(x) (((x) & GENMASK(13, 11)) >> 11) -+#define QSYS_SWITCH_PORT_MODE_YEL_RSRVD BIT(10) -+#define QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE BIT(9) -+#define QSYS_SWITCH_PORT_MODE_TX_PFC_ENA(x) (((x) << 1) & GENMASK(8, 1)) -+#define QSYS_SWITCH_PORT_MODE_TX_PFC_ENA_M GENMASK(8, 1) -+#define QSYS_SWITCH_PORT_MODE_TX_PFC_ENA_X(x) (((x) & GENMASK(8, 1)) >> 1) -+#define QSYS_SWITCH_PORT_MODE_TX_PFC_MODE BIT(0) -+ -+#define QSYS_STAT_CNT_CFG_TX_GREEN_CNT_MODE BIT(5) -+#define QSYS_STAT_CNT_CFG_TX_YELLOW_CNT_MODE BIT(4) -+#define QSYS_STAT_CNT_CFG_DROP_GREEN_CNT_MODE BIT(3) -+#define QSYS_STAT_CNT_CFG_DROP_YELLOW_CNT_MODE BIT(2) -+#define QSYS_STAT_CNT_CFG_DROP_COUNT_ONCE BIT(1) -+#define QSYS_STAT_CNT_CFG_DROP_COUNT_EGRESS BIT(0) -+ -+#define QSYS_EEE_CFG_RSZ 0x4 -+ -+#define QSYS_EEE_THRES_EEE_HIGH_BYTES(x) (((x) << 8) & GENMASK(15, 8)) -+#define QSYS_EEE_THRES_EEE_HIGH_BYTES_M GENMASK(15, 8) -+#define QSYS_EEE_THRES_EEE_HIGH_BYTES_X(x) (((x) & GENMASK(15, 8)) >> 8) -+#define QSYS_EEE_THRES_EEE_HIGH_FRAMES(x) ((x) & GENMASK(7, 0)) -+#define QSYS_EEE_THRES_EEE_HIGH_FRAMES_M GENMASK(7, 0) -+ -+#define QSYS_SW_STATUS_RSZ 0x4 -+ -+#define QSYS_EXT_CPU_CFG_EXT_CPU_PORT(x) (((x) << 8) & GENMASK(12, 8)) -+#define QSYS_EXT_CPU_CFG_EXT_CPU_PORT_M GENMASK(12, 8) -+#define QSYS_EXT_CPU_CFG_EXT_CPU_PORT_X(x) (((x) & GENMASK(12, 8)) >> 8) -+#define QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK(x) ((x) & GENMASK(7, 0)) -+#define QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M GENMASK(7, 0) -+ -+#define QSYS_QMAP_GSZ 0x4 -+ -+#define QSYS_QMAP_SE_BASE(x) (((x) << 5) & GENMASK(12, 5)) -+#define QSYS_QMAP_SE_BASE_M GENMASK(12, 5) -+#define QSYS_QMAP_SE_BASE_X(x) (((x) & GENMASK(12, 5)) >> 5) -+#define QSYS_QMAP_SE_IDX_SEL(x) (((x) << 2) & GENMASK(4, 2)) -+#define QSYS_QMAP_SE_IDX_SEL_M GENMASK(4, 2) -+#define QSYS_QMAP_SE_IDX_SEL_X(x) (((x) & GENMASK(4, 2)) >> 2) -+#define QSYS_QMAP_SE_INP_SEL(x) ((x) & GENMASK(1, 0)) -+#define QSYS_QMAP_SE_INP_SEL_M GENMASK(1, 0) -+ -+#define QSYS_ISDX_SGRP_GSZ 0x4 -+ -+#define QSYS_TIMED_FRAME_ENTRY_GSZ 0x4 -+ -+#define QSYS_TFRM_MISC_TIMED_CANCEL_SLOT(x) (((x) << 9) & GENMASK(18, 9)) -+#define QSYS_TFRM_MISC_TIMED_CANCEL_SLOT_M GENMASK(18, 9) -+#define QSYS_TFRM_MISC_TIMED_CANCEL_SLOT_X(x) (((x) & GENMASK(18, 9)) >> 9) -+#define QSYS_TFRM_MISC_TIMED_CANCEL_1SHOT BIT(8) -+#define QSYS_TFRM_MISC_TIMED_SLOT_MODE_MC BIT(7) -+#define QSYS_TFRM_MISC_TIMED_ENTRY_FAST_CNT(x) ((x) & GENMASK(6, 0)) -+#define QSYS_TFRM_MISC_TIMED_ENTRY_FAST_CNT_M GENMASK(6, 0) -+ -+#define QSYS_RED_PROFILE_RSZ 0x4 -+ -+#define QSYS_RED_PROFILE_WM_RED_LOW(x) (((x) << 8) & GENMASK(15, 8)) -+#define QSYS_RED_PROFILE_WM_RED_LOW_M GENMASK(15, 8) -+#define QSYS_RED_PROFILE_WM_RED_LOW_X(x) (((x) & GENMASK(15, 8)) >> 8) -+#define QSYS_RED_PROFILE_WM_RED_HIGH(x) ((x) & GENMASK(7, 0)) -+#define QSYS_RED_PROFILE_WM_RED_HIGH_M GENMASK(7, 0) -+ -+#define QSYS_RES_CFG_GSZ 0x8 -+ -+#define QSYS_RES_STAT_GSZ 0x8 -+ -+#define QSYS_RES_STAT_INUSE(x) (((x) << 12) & GENMASK(23, 12)) -+#define QSYS_RES_STAT_INUSE_M GENMASK(23, 12) -+#define QSYS_RES_STAT_INUSE_X(x) (((x) & GENMASK(23, 12)) >> 12) -+#define QSYS_RES_STAT_MAXUSE(x) ((x) & GENMASK(11, 0)) -+#define QSYS_RES_STAT_MAXUSE_M GENMASK(11, 0) -+ -+#define QSYS_EVENTS_CORE_EV_FDC(x) (((x) << 2) & GENMASK(4, 2)) -+#define QSYS_EVENTS_CORE_EV_FDC_M GENMASK(4, 2) -+#define QSYS_EVENTS_CORE_EV_FDC_X(x) (((x) & GENMASK(4, 2)) >> 2) -+#define QSYS_EVENTS_CORE_EV_FRD(x) ((x) & GENMASK(1, 0)) -+#define QSYS_EVENTS_CORE_EV_FRD_M GENMASK(1, 0) -+ -+#define QSYS_QMAXSDU_CFG_0_RSZ 0x4 -+ -+#define QSYS_QMAXSDU_CFG_1_RSZ 0x4 -+ -+#define QSYS_QMAXSDU_CFG_2_RSZ 0x4 -+ -+#define QSYS_QMAXSDU_CFG_3_RSZ 0x4 -+ -+#define QSYS_QMAXSDU_CFG_4_RSZ 0x4 -+ -+#define QSYS_QMAXSDU_CFG_5_RSZ 0x4 -+ -+#define QSYS_QMAXSDU_CFG_6_RSZ 0x4 -+ -+#define QSYS_QMAXSDU_CFG_7_RSZ 0x4 -+ -+#define QSYS_PREEMPTION_CFG_RSZ 0x4 -+ -+#define QSYS_PREEMPTION_CFG_P_QUEUES(x) ((x) & GENMASK(7, 0)) -+#define QSYS_PREEMPTION_CFG_P_QUEUES_M GENMASK(7, 0) -+#define QSYS_PREEMPTION_CFG_MM_ADD_FRAG_SIZE(x) (((x) << 8) & GENMASK(9, 8)) -+#define QSYS_PREEMPTION_CFG_MM_ADD_FRAG_SIZE_M GENMASK(9, 8) -+#define QSYS_PREEMPTION_CFG_MM_ADD_FRAG_SIZE_X(x) (((x) & GENMASK(9, 8)) >> 8) -+#define QSYS_PREEMPTION_CFG_STRICT_IPG(x) (((x) << 12) & GENMASK(13, 12)) -+#define QSYS_PREEMPTION_CFG_STRICT_IPG_M GENMASK(13, 12) -+#define QSYS_PREEMPTION_CFG_STRICT_IPG_X(x) (((x) & GENMASK(13, 12)) >> 12) -+#define QSYS_PREEMPTION_CFG_HOLD_ADVANCE(x) (((x) << 16) & GENMASK(31, 16)) -+#define QSYS_PREEMPTION_CFG_HOLD_ADVANCE_M GENMASK(31, 16) -+#define QSYS_PREEMPTION_CFG_HOLD_ADVANCE_X(x) (((x) & GENMASK(31, 16)) >> 16) -+ -+#define QSYS_CIR_CFG_GSZ 0x80 -+ -+#define QSYS_CIR_CFG_CIR_RATE(x) (((x) << 6) & GENMASK(20, 6)) -+#define QSYS_CIR_CFG_CIR_RATE_M GENMASK(20, 6) -+#define QSYS_CIR_CFG_CIR_RATE_X(x) (((x) & GENMASK(20, 6)) >> 6) -+#define QSYS_CIR_CFG_CIR_BURST(x) ((x) & GENMASK(5, 0)) -+#define QSYS_CIR_CFG_CIR_BURST_M GENMASK(5, 0) -+ -+#define QSYS_EIR_CFG_GSZ 0x80 -+ -+#define QSYS_EIR_CFG_EIR_RATE(x) (((x) << 7) & GENMASK(21, 7)) -+#define QSYS_EIR_CFG_EIR_RATE_M GENMASK(21, 7) -+#define QSYS_EIR_CFG_EIR_RATE_X(x) (((x) & GENMASK(21, 7)) >> 7) -+#define QSYS_EIR_CFG_EIR_BURST(x) (((x) << 1) & GENMASK(6, 1)) -+#define QSYS_EIR_CFG_EIR_BURST_M GENMASK(6, 1) -+#define QSYS_EIR_CFG_EIR_BURST_X(x) (((x) & GENMASK(6, 1)) >> 1) -+#define QSYS_EIR_CFG_EIR_MARK_ENA BIT(0) -+ -+#define QSYS_SE_CFG_GSZ 0x80 -+ -+#define QSYS_SE_CFG_SE_DWRR_CNT(x) (((x) << 6) & GENMASK(9, 6)) -+#define QSYS_SE_CFG_SE_DWRR_CNT_M GENMASK(9, 6) -+#define QSYS_SE_CFG_SE_DWRR_CNT_X(x) (((x) & GENMASK(9, 6)) >> 6) -+#define QSYS_SE_CFG_SE_RR_ENA BIT(5) -+#define QSYS_SE_CFG_SE_AVB_ENA BIT(4) -+#define QSYS_SE_CFG_SE_FRM_MODE(x) (((x) << 2) & GENMASK(3, 2)) -+#define QSYS_SE_CFG_SE_FRM_MODE_M GENMASK(3, 2) -+#define QSYS_SE_CFG_SE_FRM_MODE_X(x) (((x) & GENMASK(3, 2)) >> 2) -+#define QSYS_SE_CFG_SE_EXC_ENA BIT(1) -+#define QSYS_SE_CFG_SE_EXC_FWD BIT(0) -+ -+#define QSYS_SE_DWRR_CFG_GSZ 0x80 -+#define QSYS_SE_DWRR_CFG_RSZ 0x4 -+ -+#define QSYS_SE_CONNECT_GSZ 0x80 -+ -+#define QSYS_SE_CONNECT_SE_OUTP_IDX(x) (((x) << 17) & GENMASK(24, 17)) -+#define QSYS_SE_CONNECT_SE_OUTP_IDX_M GENMASK(24, 17) -+#define QSYS_SE_CONNECT_SE_OUTP_IDX_X(x) (((x) & GENMASK(24, 17)) >> 17) -+#define QSYS_SE_CONNECT_SE_INP_IDX(x) (((x) << 9) & GENMASK(16, 9)) -+#define QSYS_SE_CONNECT_SE_INP_IDX_M GENMASK(16, 9) -+#define QSYS_SE_CONNECT_SE_INP_IDX_X(x) (((x) & GENMASK(16, 9)) >> 9) -+#define QSYS_SE_CONNECT_SE_OUTP_CON(x) (((x) << 5) & GENMASK(8, 5)) -+#define QSYS_SE_CONNECT_SE_OUTP_CON_M GENMASK(8, 5) -+#define QSYS_SE_CONNECT_SE_OUTP_CON_X(x) (((x) & GENMASK(8, 5)) >> 5) -+#define QSYS_SE_CONNECT_SE_INP_CNT(x) (((x) << 1) & GENMASK(4, 1)) -+#define QSYS_SE_CONNECT_SE_INP_CNT_M GENMASK(4, 1) -+#define QSYS_SE_CONNECT_SE_INP_CNT_X(x) (((x) & GENMASK(4, 1)) >> 1) -+#define QSYS_SE_CONNECT_SE_TERMINAL BIT(0) -+ -+#define QSYS_SE_DLB_SENSE_GSZ 0x80 -+ -+#define QSYS_SE_DLB_SENSE_SE_DLB_PRIO(x) (((x) << 11) & GENMASK(13, 11)) -+#define QSYS_SE_DLB_SENSE_SE_DLB_PRIO_M GENMASK(13, 11) -+#define QSYS_SE_DLB_SENSE_SE_DLB_PRIO_X(x) (((x) & GENMASK(13, 11)) >> 11) -+#define QSYS_SE_DLB_SENSE_SE_DLB_SPORT(x) (((x) << 7) & GENMASK(10, 7)) -+#define QSYS_SE_DLB_SENSE_SE_DLB_SPORT_M GENMASK(10, 7) -+#define QSYS_SE_DLB_SENSE_SE_DLB_SPORT_X(x) (((x) & GENMASK(10, 7)) >> 7) -+#define QSYS_SE_DLB_SENSE_SE_DLB_DPORT(x) (((x) << 3) & GENMASK(6, 3)) -+#define QSYS_SE_DLB_SENSE_SE_DLB_DPORT_M GENMASK(6, 3) -+#define QSYS_SE_DLB_SENSE_SE_DLB_DPORT_X(x) (((x) & GENMASK(6, 3)) >> 3) -+#define QSYS_SE_DLB_SENSE_SE_DLB_PRIO_ENA BIT(2) -+#define QSYS_SE_DLB_SENSE_SE_DLB_SPORT_ENA BIT(1) -+#define QSYS_SE_DLB_SENSE_SE_DLB_DPORT_ENA BIT(0) -+ -+#define QSYS_CIR_STATE_GSZ 0x80 -+ -+#define QSYS_CIR_STATE_CIR_LVL(x) (((x) << 4) & GENMASK(25, 4)) -+#define QSYS_CIR_STATE_CIR_LVL_M GENMASK(25, 4) -+#define QSYS_CIR_STATE_CIR_LVL_X(x) (((x) & GENMASK(25, 4)) >> 4) -+#define QSYS_CIR_STATE_SHP_TIME(x) ((x) & GENMASK(3, 0)) -+#define QSYS_CIR_STATE_SHP_TIME_M GENMASK(3, 0) -+ -+#define QSYS_EIR_STATE_GSZ 0x80 -+ -+#define QSYS_SE_STATE_GSZ 0x80 -+ -+#define QSYS_SE_STATE_SE_OUTP_LVL(x) (((x) << 1) & GENMASK(2, 1)) -+#define QSYS_SE_STATE_SE_OUTP_LVL_M GENMASK(2, 1) -+#define QSYS_SE_STATE_SE_OUTP_LVL_X(x) (((x) & GENMASK(2, 1)) >> 1) -+#define QSYS_SE_STATE_SE_WAS_YEL BIT(0) -+ -+#define QSYS_HSCH_MISC_CFG_SE_CONNECT_VLD BIT(8) -+#define QSYS_HSCH_MISC_CFG_FRM_ADJ(x) (((x) << 3) & GENMASK(7, 3)) -+#define QSYS_HSCH_MISC_CFG_FRM_ADJ_M GENMASK(7, 3) -+#define QSYS_HSCH_MISC_CFG_FRM_ADJ_X(x) (((x) & GENMASK(7, 3)) >> 3) -+#define QSYS_HSCH_MISC_CFG_LEAK_DIS BIT(2) -+#define QSYS_HSCH_MISC_CFG_QSHP_EXC_ENA BIT(1) -+#define QSYS_HSCH_MISC_CFG_PFC_BYP_UPD BIT(0) -+ -+#define QSYS_TAG_CONFIG_RSZ 0x4 -+ -+#define QSYS_TAG_CONFIG_ENABLE BIT(0) -+#define QSYS_TAG_CONFIG_LINK_SPEED(x) (((x) << 4) & GENMASK(5, 4)) -+#define QSYS_TAG_CONFIG_LINK_SPEED_M GENMASK(5, 4) -+#define QSYS_TAG_CONFIG_LINK_SPEED_X(x) (((x) & GENMASK(5, 4)) >> 4) -+#define QSYS_TAG_CONFIG_INIT_GATE_STATE(x) (((x) << 8) & GENMASK(15, 8)) -+#define QSYS_TAG_CONFIG_INIT_GATE_STATE_M GENMASK(15, 8) -+#define QSYS_TAG_CONFIG_INIT_GATE_STATE_X(x) (((x) & GENMASK(15, 8)) >> 8) -+#define QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES(x) (((x) << 16) & GENMASK(23, 16)) -+#define QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_M GENMASK(23, 16) -+#define QSYS_TAG_CONFIG_SCH_TRAFFIC_QUEUES_X(x) (((x) & GENMASK(23, 16)) >> 16) -+ -+#define QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM(x) ((x) & GENMASK(7, 0)) -+#define QSYS_TAS_PARAM_CFG_CTRL_PORT_NUM_M GENMASK(7, 0) -+#define QSYS_TAS_PARAM_CFG_CTRL_ALWAYS_GUARD_BAND_SCH_Q BIT(8) -+#define QSYS_TAS_PARAM_CFG_CTRL_CONFIG_CHANGE BIT(16) -+ -+#define QSYS_PORT_MAX_SDU_RSZ 0x4 -+ -+#define QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB(x) ((x) & GENMASK(15, 0)) -+#define QSYS_PARAM_CFG_REG_3_BASE_TIME_SEC_MSB_M GENMASK(15, 0) -+#define QSYS_PARAM_CFG_REG_3_LIST_LENGTH(x) (((x) << 16) & GENMASK(31, 16)) -+#define QSYS_PARAM_CFG_REG_3_LIST_LENGTH_M GENMASK(31, 16) -+#define QSYS_PARAM_CFG_REG_3_LIST_LENGTH_X(x) (((x) & GENMASK(31, 16)) >> 16) -+ -+#define QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM(x) ((x) & GENMASK(5, 0)) -+#define QSYS_GCL_CFG_REG_1_GCL_ENTRY_NUM_M GENMASK(5, 0) -+#define QSYS_GCL_CFG_REG_1_GATE_STATE(x) (((x) << 8) & GENMASK(15, 8)) -+#define QSYS_GCL_CFG_REG_1_GATE_STATE_M GENMASK(15, 8) -+#define QSYS_GCL_CFG_REG_1_GATE_STATE_X(x) (((x) & GENMASK(15, 8)) >> 8) -+ -+#define QSYS_PARAM_STATUS_REG_3_BASE_TIME_SEC_MSB(x) ((x) & GENMASK(15, 0)) -+#define QSYS_PARAM_STATUS_REG_3_BASE_TIME_SEC_MSB_M GENMASK(15, 0) -+#define QSYS_PARAM_STATUS_REG_3_LIST_LENGTH(x) (((x) << 16) & GENMASK(31, 16)) -+#define QSYS_PARAM_STATUS_REG_3_LIST_LENGTH_M GENMASK(31, 16) -+#define QSYS_PARAM_STATUS_REG_3_LIST_LENGTH_X(x) (((x) & GENMASK(31, 16)) >> 16) -+ -+#define QSYS_PARAM_STATUS_REG_8_CFG_CHG_TIME_SEC_MSB(x) ((x) & GENMASK(15, 0)) -+#define QSYS_PARAM_STATUS_REG_8_CFG_CHG_TIME_SEC_MSB_M GENMASK(15, 0) -+#define QSYS_PARAM_STATUS_REG_8_OPER_GATE_STATE(x) (((x) << 16) & GENMASK(23, 16)) -+#define QSYS_PARAM_STATUS_REG_8_OPER_GATE_STATE_M GENMASK(23, 16) -+#define QSYS_PARAM_STATUS_REG_8_OPER_GATE_STATE_X(x) (((x) & GENMASK(23, 16)) >> 16) -+#define QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING BIT(24) -+ -+#define QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM(x) ((x) & GENMASK(5, 0)) -+#define QSYS_GCL_STATUS_REG_1_GCL_ENTRY_NUM_M GENMASK(5, 0) -+#define QSYS_GCL_STATUS_REG_1_GATE_STATE(x) (((x) << 8) & GENMASK(15, 8)) -+#define QSYS_GCL_STATUS_REG_1_GATE_STATE_M GENMASK(15, 8) -+#define QSYS_GCL_STATUS_REG_1_GATE_STATE_X(x) (((x) & GENMASK(15, 8)) >> 8) -+ -+#endif diff --git a/target/linux/layerscape/patches-5.4/701-net-0386-net-dsa-felix-Add-PCS-operations-for-PHYLINK.patch b/target/linux/layerscape/patches-5.4/701-net-0386-net-dsa-felix-Add-PCS-operations-for-PHYLINK.patch deleted file mode 100644 index 4286c3b49a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0386-net-dsa-felix-Add-PCS-operations-for-PHYLINK.patch +++ /dev/null @@ -1,1087 +0,0 @@ -From 78d77114e35a491232c50e054f43c980bbf9d434 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Mon, 6 Jan 2020 03:34:17 +0200 -Subject: [PATCH] net: dsa: felix: Add PCS operations for PHYLINK - -Layerscape SoCs traditionally expose the SerDes configuration/status for -Ethernet protocols (PCS for SGMII/USXGMII/10GBase-R etc etc) in a register -format that is compatible with clause 22 or clause 45 (depending on -SerDes protocol). Each MAC has its own internal MDIO bus on which there -is one or more of these PCS's, responding to commands at a configurable -PHY address. The per-port internal MDIO bus (which is just for PCSs) is -totally separate and has nothing to do with the dedicated external MDIO -controller (which is just for PHYs), but the register map for the MDIO -controller is the same. - -The VSC9959 (Felix) switch instantiated in the LS1028A is integrated -in hardware with the ENETC PCS of its DSA master, and reuses its MDIO -controller driver, so Felix has been made to depend on it in Kconfig. - - +------------------------------------------------------------------------+ - | +--------+ GMII (typically disabled via RCW) | - | ENETC PCI | ENETC |--------------------------+ | - | Root Complex | port 3 |-----------------------+ | | - | Integrated +--------+ | | | - | Endpoint | | | - | +--------+ 2.5G GMII | | | - | | ENETC |--------------+ | | | - | | port 2 |-----------+ | | | | - | +--------+ | | | | | - | +--------+ +--------+ | - | | Felix | | Felix | | - | | port 4 | | port 5 | | - | +--------+ +--------+ | - | | - | +--------+ +--------+ +--------+ +--------+ +--------+ +--------+ | - | | ENETC | | ENETC | | Felix | | Felix | | Felix | | Felix | | - | | port 0 | | port 1 | | port 0 | | port 1 | | port 2 | | port 3 | | - +------------------------------------------------------------------------+ - | |||| SerDes | |||| |||| |||| |||| | - | +--------+block | +--------------------------------------------+ | - | | ENETC | | | ENETC port 2 internal MDIO bus | | - | | port 0 | | | PCS PCS PCS PCS | | - | | PCS | | | 0 1 2 3 | | - +-----------------|------------------------------------------------------+ - v v v v v v - SGMII/ RGMII QSGMII/QSXGMII/4xSGMII/4x1000Base-X/4x2500Base-X - USXGMII/ (bypasses - 1000Base-X/ SerDes) - 2500Base-X - -In the LS1028A SoC described above, the VSC9959 Felix switch is PF5 of -the ENETC root complex, and has 2 BARs: -- BAR 4: the switch's effective registers -- BAR 0: the MDIO controller register map lended from ENETC port 2 - (PF2), for accessing its associated PCS's. - -This explanation is necessary because the patch does some renaming -"pci_bar" -> "switch_pci_bar" for clarity, which would otherwise appear -a bit obtuse. - -The fact that the internal MDIO bus is "borrowed" is relevant because -the register map is found in PF5 (the switch) but it triggers an access -fault if PF2 (the ENETC DSA master) is not enabled. This is not treated -in any way (and I don't think it can be treated). - -All of this is so SoC-specific, that it was contained as much as -possible in the platform-integration file felix_vsc9959.c. - -We need to parse and pre-validate the device tree because of 2 reasons: -- The PHY mode (SerDes protocol) cannot change at runtime due to SoC - design. -- There is a circular dependency in that we need to know what clause the - PCS speaks in order to find it on the internal MDIO bus. But the - clause of the PCS depends on what phy-mode it is configured for. - -The goal of this patch is to make steps towards removing the bootloader -dependency for SGMII PCS pre-configuration, as well as to add support -for monitoring the in-band SGMII AN between the PCS and the system-side -link partner (PHY or other MAC). - -In practice the bootloader dependency is not completely removed. U-Boot -pre-programs the PHY address at which each PCS can be found on the -internal MDIO bus (MDEV_PORT). This is needed because the PCS of each -port has the same out-of-reset PHY address of zero. The SerDes register -for changing MDEV_PORT is pretty deep in the SoC (outside the addresses -of the ENETC PCI BARs) and therefore inaccessible to us from here. - -Felix VSC9959 and Ocelot VSC7514 are integrated very differently in -their respective SoCs, and for that reason Felix does not use the Ocelot -core library for PHYLINK. On one hand we don't want to impose the -fixed phy-mode limitation to Ocelot, and on the other hand Felix doesn't -need to force the MAC link speed the way Ocelot does, since the MAC is -connected to the PCS through a fixed GMII, and the PCS is the one who -does the rate adaptation at lower link speeds, which the MAC does not -even need to know about. In fact changing the GMII speed for Felix -irrecoverably breaks transmission through that port until a reset. - -The pair with ENETC port 3 and Felix port 5 is optional and doesn't -support tagging. When we enable it, swp5 is a regular slave port, albeit -an internal one. The trouble is that it doesn't work, and that is -because the DSA PHYLIB adaptation layer doesn't treat fixed-link slave -ports. So that is yet another reason for wanting to convert Felix to the -native PHYLINK API. - -Signed-off-by: Vladimir Oltean - -Conflicts: - drivers/net/dsa/ocelot/felix.c - -with the upstream API change for of_get_phy_mode() introduced in -0c65b2b90d13 ("net: of_get_phy_mode: Change API to solve int/unit -warnings") and merged in v5.4-rc5. ---- - drivers/net/dsa/ocelot/Kconfig | 2 + - drivers/net/dsa/ocelot/felix.c | 267 +++++++++++++++++- - drivers/net/dsa/ocelot/felix.h | 16 +- - drivers/net/dsa/ocelot/felix_vsc9959.c | 501 ++++++++++++++++++++++++++++++++- - 4 files changed, 769 insertions(+), 17 deletions(-) - ---- a/drivers/net/dsa/ocelot/Kconfig -+++ b/drivers/net/dsa/ocelot/Kconfig -@@ -3,8 +3,10 @@ config NET_DSA_MSCC_FELIX - tristate "Ocelot / Felix Ethernet switch support" - depends on NET_DSA && PCI - depends on NET_VENDOR_MICROSEMI -+ depends on NET_VENDOR_FREESCALE - select MSCC_OCELOT_SWITCH - select NET_DSA_TAG_OCELOT -+ select FSL_ENETC_MDIO - help - This driver supports the VSC9959 network switch, which is a member of - the Vitesse / Microsemi / Microchip Ocelot family of switching cores. ---- a/drivers/net/dsa/ocelot/felix.c -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -2,9 +2,14 @@ - /* Copyright 2019 NXP Semiconductors - */ - #include -+#include -+#include -+#include -+#include - #include - #include - #include -+#include - #include - #include - #include -@@ -58,14 +63,6 @@ static int felix_set_ageing_time(struct - return 0; - } - --static void felix_adjust_link(struct dsa_switch *ds, int port, -- struct phy_device *phydev) --{ -- struct ocelot *ocelot = ds->priv; -- -- ocelot_adjust_link(ocelot, port, phydev); --} -- - static int felix_fdb_dump(struct dsa_switch *ds, int port, - dsa_fdb_dump_cb_t *cb, void *data) - { -@@ -202,6 +199,138 @@ static void felix_port_disable(struct ds - return ocelot_port_disable(ocelot, port); - } - -+static void felix_phylink_validate(struct dsa_switch *ds, int port, -+ unsigned long *supported, -+ struct phylink_link_state *state) -+{ -+ struct ocelot *ocelot = ds->priv; -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; -+ -+ if (state->interface != PHY_INTERFACE_MODE_NA && -+ state->interface != ocelot_port->phy_mode) { -+ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); -+ return; -+ } -+ -+ /* No half-duplex. */ -+ phylink_set_port_modes(mask); -+ phylink_set(mask, Autoneg); -+ phylink_set(mask, Pause); -+ phylink_set(mask, Asym_Pause); -+ if (state->interface != PHY_INTERFACE_MODE_2500BASEX) { -+ phylink_set(mask, 10baseT_Full); -+ phylink_set(mask, 100baseT_Full); -+ phylink_set(mask, 1000baseT_Full); -+ } -+ /* The internal ports that run at 2.5G are overclocked GMII */ -+ if (state->interface == PHY_INTERFACE_MODE_GMII || -+ state->interface == PHY_INTERFACE_MODE_2500BASEX || -+ state->interface == PHY_INTERFACE_MODE_USXGMII) { -+ phylink_set(mask, 2500baseT_Full); -+ phylink_set(mask, 2500baseX_Full); -+ } -+ -+ bitmap_and(supported, supported, mask, -+ __ETHTOOL_LINK_MODE_MASK_NBITS); -+ bitmap_and(state->advertising, state->advertising, mask, -+ __ETHTOOL_LINK_MODE_MASK_NBITS); -+} -+ -+static int felix_phylink_mac_pcs_get_state(struct dsa_switch *ds, int port, -+ struct phylink_link_state *state) -+{ -+ struct ocelot *ocelot = ds->priv; -+ struct felix *felix = ocelot_to_felix(ocelot); -+ -+ if (felix->info->pcs_link_state) -+ felix->info->pcs_link_state(ocelot, port, state); -+ -+ return 0; -+} -+ -+static void felix_phylink_mac_config(struct dsa_switch *ds, int port, -+ unsigned int link_an_mode, -+ const struct phylink_link_state *state) -+{ -+ struct ocelot *ocelot = ds->priv; -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ struct felix *felix = ocelot_to_felix(ocelot); -+ u32 mac_fc_cfg; -+ -+ /* Take port out of reset by clearing the MAC_TX_RST, MAC_RX_RST and -+ * PORT_RST bits in CLOCK_CFG -+ */ -+ ocelot_port_writel(ocelot_port, DEV_CLOCK_CFG_LINK_SPEED(state->speed), -+ DEV_CLOCK_CFG); -+ -+ /* Flow control. Link speed is only used here to evaluate the time -+ * specification in incoming pause frames. -+ */ -+ mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(state->speed); -+ if (state->pause & MLO_PAUSE_RX) -+ mac_fc_cfg |= SYS_MAC_FC_CFG_RX_FC_ENA; -+ if (state->pause & MLO_PAUSE_TX) -+ mac_fc_cfg |= SYS_MAC_FC_CFG_TX_FC_ENA | -+ SYS_MAC_FC_CFG_PAUSE_VAL_CFG(0xffff) | -+ SYS_MAC_FC_CFG_FC_LATENCY_CFG(0x7) | -+ SYS_MAC_FC_CFG_ZERO_PAUSE_ENA; -+ ocelot_write_rix(ocelot, mac_fc_cfg, SYS_MAC_FC_CFG, port); -+ -+ ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port); -+ -+ if (felix->info->pcs_init) -+ felix->info->pcs_init(ocelot, port, link_an_mode, state); -+} -+ -+static void felix_phylink_mac_an_restart(struct dsa_switch *ds, int port) -+{ -+ struct ocelot *ocelot = ds->priv; -+ struct felix *felix = ocelot_to_felix(ocelot); -+ -+ if (felix->info->pcs_an_restart) -+ felix->info->pcs_an_restart(ocelot, port); -+} -+ -+static void felix_phylink_mac_link_down(struct dsa_switch *ds, int port, -+ unsigned int link_an_mode, -+ phy_interface_t interface) -+{ -+ struct ocelot *ocelot = ds->priv; -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ -+ ocelot_port_writel(ocelot_port, 0, DEV_MAC_ENA_CFG); -+ ocelot_rmw_rix(ocelot, 0, QSYS_SWITCH_PORT_MODE_PORT_ENA, -+ QSYS_SWITCH_PORT_MODE, port); -+} -+ -+static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port, -+ unsigned int link_an_mode, -+ phy_interface_t interface, -+ struct phy_device *phydev) -+{ -+ struct ocelot *ocelot = ds->priv; -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ -+ /* Enable MAC module */ -+ ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA | -+ DEV_MAC_ENA_CFG_TX_ENA, DEV_MAC_ENA_CFG); -+ -+ /* Enable receiving frames on the port, and activate auto-learning of -+ * MAC addresses. -+ */ -+ ocelot_write_gix(ocelot, ANA_PORT_PORT_CFG_LEARNAUTO | -+ ANA_PORT_PORT_CFG_RECV_ENA | -+ ANA_PORT_PORT_CFG_PORTID_VAL(port), -+ ANA_PORT_PORT_CFG, port); -+ -+ /* Core: Enable port for frame transfer */ -+ ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE | -+ QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG(1) | -+ QSYS_SWITCH_PORT_MODE_PORT_ENA, -+ QSYS_SWITCH_PORT_MODE, port); -+} -+ - static void felix_get_strings(struct dsa_switch *ds, int port, - u32 stringset, u8 *data) - { -@@ -232,10 +361,78 @@ static int felix_get_ts_info(struct dsa_ - return ocelot_get_ts_info(ocelot, port, info); - } - -+static int felix_parse_ports_node(struct felix *felix, -+ struct device_node *ports_node, -+ phy_interface_t *port_phy_modes) -+{ -+ struct ocelot *ocelot = &felix->ocelot; -+ struct device *dev = felix->ocelot.dev; -+ struct device_node *child; -+ -+ for_each_child_of_node(ports_node, child) { -+ phy_interface_t phy_mode; -+ u32 port; -+ int err; -+ -+ /* Get switch port number from DT */ -+ if (of_property_read_u32(child, "reg", &port) < 0) { -+ dev_err(dev, "Port number not defined in device tree " -+ "(property \"reg\")\n"); -+ of_node_put(child); -+ return -ENODEV; -+ } -+ -+ /* Get PHY mode from DT */ -+ err = of_get_phy_mode(child); -+ if (err < 0) { -+ dev_err(dev, "Failed to read phy-mode or " -+ "phy-interface-type property for port %d\n", -+ port); -+ of_node_put(child); -+ return -ENODEV; -+ } -+ -+ phy_mode = err; -+ -+ err = felix->info->prevalidate_phy_mode(ocelot, port, phy_mode); -+ if (err < 0) { -+ dev_err(dev, "Unsupported PHY mode %s on port %d\n", -+ phy_modes(phy_mode), port); -+ return err; -+ } -+ -+ port_phy_modes[port] = phy_mode; -+ } -+ -+ return 0; -+} -+ -+static int felix_parse_dt(struct felix *felix, phy_interface_t *port_phy_modes) -+{ -+ struct device *dev = felix->ocelot.dev; -+ struct device_node *switch_node; -+ struct device_node *ports_node; -+ int err; -+ -+ switch_node = dev->of_node; -+ -+ ports_node = of_get_child_by_name(switch_node, "ports"); -+ if (!ports_node) { -+ dev_err(dev, "Incorrect bindings: absent \"ports\" node\n"); -+ return -ENODEV; -+ } -+ -+ err = felix_parse_ports_node(felix, ports_node, port_phy_modes); -+ of_node_put(ports_node); -+ -+ return err; -+} -+ - static int felix_init_structs(struct felix *felix, int num_phys_ports) - { - struct ocelot *ocelot = &felix->ocelot; -- resource_size_t base; -+ phy_interface_t *port_phy_modes; -+ resource_size_t switch_base; - int port, i, err; - - ocelot->num_phys_ports = num_phys_ports; -@@ -250,7 +447,19 @@ static int felix_init_structs(struct fel - ocelot->shared_queue_sz = felix->info->shared_queue_sz; - ocelot->ops = felix->info->ops; - -- base = pci_resource_start(felix->pdev, felix->info->pci_bar); -+ port_phy_modes = kcalloc(num_phys_ports, sizeof(phy_interface_t), -+ GFP_KERNEL); -+ if (!port_phy_modes) -+ return -ENOMEM; -+ -+ err = felix_parse_dt(felix, port_phy_modes); -+ if (err) { -+ kfree(port_phy_modes); -+ return err; -+ } -+ -+ switch_base = pci_resource_start(felix->pdev, -+ felix->info->switch_pci_bar); - - for (i = 0; i < TARGET_MAX; i++) { - struct regmap *target; -@@ -261,13 +470,14 @@ static int felix_init_structs(struct fel - - res = &felix->info->target_io_res[i]; - res->flags = IORESOURCE_MEM; -- res->start += base; -- res->end += base; -+ res->start += switch_base; -+ res->end += switch_base; - - target = ocelot_regmap_init(ocelot, res); - if (IS_ERR(target)) { - dev_err(ocelot->dev, - "Failed to map device memory space\n"); -+ kfree(port_phy_modes); - return PTR_ERR(target); - } - -@@ -277,6 +487,7 @@ static int felix_init_structs(struct fel - err = ocelot_regfields_init(ocelot, felix->info->regfields); - if (err) { - dev_err(ocelot->dev, "failed to init reg fields map\n"); -+ kfree(port_phy_modes); - return err; - } - -@@ -291,26 +502,37 @@ static int felix_init_structs(struct fel - if (!ocelot_port) { - dev_err(ocelot->dev, - "failed to allocate port memory\n"); -+ kfree(port_phy_modes); - return -ENOMEM; - } - - res = &felix->info->port_io_res[port]; - res->flags = IORESOURCE_MEM; -- res->start += base; -- res->end += base; -+ res->start += switch_base; -+ res->end += switch_base; - - port_regs = devm_ioremap_resource(ocelot->dev, res); - if (IS_ERR(port_regs)) { - dev_err(ocelot->dev, - "failed to map registers for port %d\n", port); -+ kfree(port_phy_modes); - return PTR_ERR(port_regs); - } - -+ ocelot_port->phy_mode = port_phy_modes[port]; - ocelot_port->ocelot = ocelot; - ocelot_port->regs = port_regs; - ocelot->ports[port] = ocelot_port; - } - -+ kfree(port_phy_modes); -+ -+ if (felix->info->mdio_bus_alloc) { -+ err = felix->info->mdio_bus_alloc(ocelot); -+ if (err < 0) -+ return err; -+ } -+ - return 0; - } - -@@ -340,12 +562,22 @@ static int felix_setup(struct dsa_switch - OCELOT_TAG_PREFIX_LONG); - } - -+ /* It looks like the MAC/PCS interrupt register - PM0_IEVENT (0x8040) -+ * isn't instantiated for the Felix PF. -+ * In-band AN may take a few ms to complete, so we need to poll. -+ */ -+ ds->pcs_poll = true; -+ - return 0; - } - - static void felix_teardown(struct dsa_switch *ds) - { - struct ocelot *ocelot = ds->priv; -+ struct felix *felix = ocelot_to_felix(ocelot); -+ -+ if (felix->info->mdio_bus_free) -+ felix->info->mdio_bus_free(ocelot); - - /* stop workqueue thread */ - ocelot_deinit(ocelot); -@@ -416,7 +648,12 @@ static const struct dsa_switch_ops felix - .get_ethtool_stats = felix_get_ethtool_stats, - .get_sset_count = felix_get_sset_count, - .get_ts_info = felix_get_ts_info, -- .adjust_link = felix_adjust_link, -+ .phylink_validate = felix_phylink_validate, -+ .phylink_mac_link_state = felix_phylink_mac_pcs_get_state, -+ .phylink_mac_config = felix_phylink_mac_config, -+ .phylink_mac_an_restart = felix_phylink_mac_an_restart, -+ .phylink_mac_link_down = felix_phylink_mac_link_down, -+ .phylink_mac_link_up = felix_phylink_mac_link_up, - .port_enable = felix_port_enable, - .port_disable = felix_port_disable, - .port_fdb_dump = felix_fdb_dump, ---- a/drivers/net/dsa/ocelot/felix.h -+++ b/drivers/net/dsa/ocelot/felix.h -@@ -10,6 +10,7 @@ - struct felix_info { - struct resource *target_io_res; - struct resource *port_io_res; -+ struct resource *imdio_res; - const struct reg_field *regfields; - const u32 *const *map; - const struct ocelot_ops *ops; -@@ -17,7 +18,18 @@ struct felix_info { - const struct ocelot_stat_layout *stats_layout; - unsigned int num_stats; - int num_ports; -- int pci_bar; -+ int switch_pci_bar; -+ int imdio_pci_bar; -+ int (*mdio_bus_alloc)(struct ocelot *ocelot); -+ void (*mdio_bus_free)(struct ocelot *ocelot); -+ void (*pcs_init)(struct ocelot *ocelot, int port, -+ unsigned int link_an_mode, -+ const struct phylink_link_state *state); -+ void (*pcs_an_restart)(struct ocelot *ocelot, int port); -+ void (*pcs_link_state)(struct ocelot *ocelot, int port, -+ struct phylink_link_state *state); -+ int (*prevalidate_phy_mode)(struct ocelot *ocelot, int port, -+ phy_interface_t phy_mode); - }; - - extern struct felix_info felix_info_vsc9959; -@@ -32,6 +44,8 @@ struct felix { - struct pci_dev *pdev; - struct felix_info *info; - struct ocelot ocelot; -+ struct mii_bus *imdio; -+ struct phy_device **pcs; - }; - - #endif ---- a/drivers/net/dsa/ocelot/felix_vsc9959.c -+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c -@@ -2,12 +2,33 @@ - /* Copyright 2017 Microsemi Corporation - * Copyright 2018-2019 NXP Semiconductors - */ -+#include - #include - #include - #include - #include - #include "felix.h" - -+/* TODO: should find a better place for these */ -+#define USXGMII_BMCR_RESET BIT(15) -+#define USXGMII_BMCR_AN_EN BIT(12) -+#define USXGMII_BMCR_RST_AN BIT(9) -+#define USXGMII_BMSR_LNKS(status) (((status) & GENMASK(2, 2)) >> 2) -+#define USXGMII_BMSR_AN_CMPL(status) (((status) & GENMASK(5, 5)) >> 5) -+#define USXGMII_ADVERTISE_LNKS(x) (((x) << 15) & BIT(15)) -+#define USXGMII_ADVERTISE_FDX BIT(12) -+#define USXGMII_ADVERTISE_SPEED(x) (((x) << 9) & GENMASK(11, 9)) -+#define USXGMII_LPA_LNKS(lpa) ((lpa) >> 15) -+#define USXGMII_LPA_DUPLEX(lpa) (((lpa) & GENMASK(12, 12)) >> 12) -+#define USXGMII_LPA_SPEED(lpa) (((lpa) & GENMASK(11, 9)) >> 9) -+ -+enum usxgmii_speed { -+ USXGMII_SPEED_10 = 0, -+ USXGMII_SPEED_100 = 1, -+ USXGMII_SPEED_1000 = 2, -+ USXGMII_SPEED_2500 = 4, -+}; -+ - static const u32 vsc9959_ana_regmap[] = { - REG(ANA_ADVLEARN, 0x0089a0), - REG(ANA_VLANMASK, 0x0089a4), -@@ -390,6 +411,15 @@ static struct resource vsc9959_port_io_r - }, - }; - -+/* Port MAC 0 Internal MDIO bus through which the SerDes acting as an -+ * SGMII/QSGMII MAC PCS can be found. -+ */ -+static struct resource vsc9959_imdio_res = { -+ .start = 0x8030, -+ .end = 0x8040, -+ .name = "imdio", -+}; -+ - static const struct reg_field vsc9959_regfields[] = { - [ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 6, 6), - [ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 5), -@@ -569,13 +599,475 @@ static int vsc9959_reset(struct ocelot * - return 0; - } - -+static void vsc9959_pcs_an_restart_sgmii(struct phy_device *pcs) -+{ -+ phy_set_bits(pcs, MII_BMCR, BMCR_ANRESTART); -+} -+ -+static void vsc9959_pcs_an_restart_usxgmii(struct phy_device *pcs) -+{ -+ phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_BMCR, -+ USXGMII_BMCR_RESET | -+ USXGMII_BMCR_AN_EN | -+ USXGMII_BMCR_RST_AN); -+} -+ -+static void vsc9959_pcs_an_restart(struct ocelot *ocelot, int port) -+{ -+ struct felix *felix = ocelot_to_felix(ocelot); -+ struct phy_device *pcs = felix->pcs[port]; -+ -+ if (!pcs) -+ return; -+ -+ switch (pcs->interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_QSGMII: -+ vsc9959_pcs_an_restart_sgmii(pcs); -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ vsc9959_pcs_an_restart_usxgmii(pcs); -+ break; -+ default: -+ dev_err(ocelot->dev, "Invalid PCS interface type %s\n", -+ phy_modes(pcs->interface)); -+ break; -+ } -+} -+ -+/* We enable SGMII AN only when the PHY has managed = "in-band-status" in the -+ * device tree. If we are in MLO_AN_PHY mode, we program directly state->speed -+ * into the PCS, which is retrieved out-of-band over MDIO. This also has the -+ * benefit of working with SGMII fixed-links, like downstream switches, where -+ * both link partners attempt to operate as AN slaves and therefore AN never -+ * completes. But it also has the disadvantage that some PHY chips don't pass -+ * traffic if SGMII AN is enabled but not completed (acknowledged by us), so -+ * setting MLO_AN_INBAND is actually required for those. -+ */ -+static void vsc9959_pcs_init_sgmii(struct phy_device *pcs, -+ unsigned int link_an_mode, -+ const struct phylink_link_state *state) -+{ -+ if (link_an_mode == MLO_AN_INBAND) { -+ /* SGMII spec requires tx_config_Reg[15:0] to be exactly 0x4001 -+ * for the MAC PCS in order to acknowledge the AN. -+ */ -+ phy_write(pcs, MII_ADVERTISE, ADVERTISE_SGMII | -+ ADVERTISE_LPACK); -+ -+ phy_write(pcs, ENETC_PCS_IF_MODE, -+ ENETC_PCS_IF_MODE_SGMII_EN | -+ ENETC_PCS_IF_MODE_USE_SGMII_AN); -+ -+ /* Adjust link timer for SGMII */ -+ phy_write(pcs, ENETC_PCS_LINK_TIMER1, -+ ENETC_PCS_LINK_TIMER1_VAL); -+ phy_write(pcs, ENETC_PCS_LINK_TIMER2, -+ ENETC_PCS_LINK_TIMER2_VAL); -+ -+ phy_write(pcs, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE); -+ } else { -+ int speed; -+ -+ if (state->duplex == DUPLEX_HALF) { -+ phydev_err(pcs, "Half duplex not supported\n"); -+ return; -+ } -+ switch (state->speed) { -+ case SPEED_1000: -+ speed = ENETC_PCS_SPEED_1000; -+ break; -+ case SPEED_100: -+ speed = ENETC_PCS_SPEED_100; -+ break; -+ case SPEED_10: -+ speed = ENETC_PCS_SPEED_10; -+ break; -+ case SPEED_UNKNOWN: -+ /* Silently don't do anything */ -+ return; -+ default: -+ phydev_err(pcs, "Invalid PCS speed %d\n", state->speed); -+ return; -+ } -+ -+ phy_write(pcs, ENETC_PCS_IF_MODE, -+ ENETC_PCS_IF_MODE_SGMII_EN | -+ ENETC_PCS_IF_MODE_SGMII_SPEED(speed)); -+ -+ /* Yes, not a mistake: speed is given by IF_MODE. */ -+ phy_write(pcs, MII_BMCR, BMCR_RESET | -+ BMCR_SPEED1000 | -+ BMCR_FULLDPLX); -+ } -+} -+ -+/* 2500Base-X is SerDes protocol 7 on Felix and 6 on ENETC. It is a SerDes lane -+ * clocked at 3.125 GHz which encodes symbols with 8b/10b and does not have -+ * auto-negotiation of any link parameters. Electrically it is compatible with -+ * a single lane of XAUI. -+ * The hardware reference manual wants to call this mode SGMII, but it isn't -+ * really, since the fundamental features of SGMII: -+ * - Downgrading the link speed by duplicating symbols -+ * - Auto-negotiation -+ * are not there. -+ * The speed is configured at 1000 in the IF_MODE and BMCR MDIO registers -+ * because the clock frequency is actually given by a PLL configured in the -+ * Reset Configuration Word (RCW). -+ * Since there is no difference between fixed speed SGMII w/o AN and 802.3z w/o -+ * AN, we call this PHY interface type 2500Base-X. In case a PHY negotiates a -+ * lower link speed on line side, the system-side interface remains fixed at -+ * 2500 Mbps and we do rate adaptation through pause frames. -+ */ -+static void vsc9959_pcs_init_2500basex(struct phy_device *pcs, -+ unsigned int link_an_mode, -+ const struct phylink_link_state *state) -+{ -+ if (link_an_mode == MLO_AN_INBAND) { -+ phydev_err(pcs, "AN not supported on 3.125GHz SerDes lane\n"); -+ return; -+ } -+ -+ phy_write(pcs, ENETC_PCS_IF_MODE, -+ ENETC_PCS_IF_MODE_SGMII_EN | -+ ENETC_PCS_IF_MODE_SGMII_SPEED(ENETC_PCS_SPEED_2500)); -+ -+ phy_write(pcs, MII_BMCR, BMCR_SPEED1000 | -+ BMCR_FULLDPLX | -+ BMCR_RESET); -+} -+ -+static void vsc9959_pcs_init_usxgmii(struct phy_device *pcs, -+ unsigned int link_an_mode, -+ const struct phylink_link_state *state) -+{ -+ if (link_an_mode != MLO_AN_INBAND) { -+ phydev_err(pcs, "USXGMII only supports in-band AN for now\n"); -+ return; -+ } -+ -+ /* Configure device ability for the USXGMII Replicator */ -+ phy_write_mmd(pcs, MDIO_MMD_VEND2, MII_ADVERTISE, -+ USXGMII_ADVERTISE_SPEED(USXGMII_SPEED_2500) | -+ USXGMII_ADVERTISE_LNKS(1) | -+ ADVERTISE_SGMII | -+ ADVERTISE_LPACK | -+ USXGMII_ADVERTISE_FDX); -+} -+ -+static void vsc9959_pcs_init(struct ocelot *ocelot, int port, -+ unsigned int link_an_mode, -+ const struct phylink_link_state *state) -+{ -+ struct felix *felix = ocelot_to_felix(ocelot); -+ struct phy_device *pcs = felix->pcs[port]; -+ -+ if (!pcs) -+ return; -+ -+ /* The PCS does not implement the BMSR register fully, so capability -+ * detection via genphy_read_abilities does not work. Since we can get -+ * the PHY config word from the LPA register though, there is still -+ * value in using the generic phy_resolve_aneg_linkmode function. So -+ * populate the supported and advertising link modes manually here. -+ */ -+ linkmode_set_bit_array(phy_basic_ports_array, -+ ARRAY_SIZE(phy_basic_ports_array), -+ pcs->supported); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, pcs->supported); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, pcs->supported); -+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, pcs->supported); -+ if (pcs->interface == PHY_INTERFACE_MODE_2500BASEX || -+ pcs->interface == PHY_INTERFACE_MODE_USXGMII) -+ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, -+ pcs->supported); -+ if (pcs->interface != PHY_INTERFACE_MODE_2500BASEX) -+ linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, -+ pcs->supported); -+ phy_advertise_supported(pcs); -+ -+ switch (pcs->interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_QSGMII: -+ vsc9959_pcs_init_sgmii(pcs, link_an_mode, state); -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ vsc9959_pcs_init_2500basex(pcs, link_an_mode, state); -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ vsc9959_pcs_init_usxgmii(pcs, link_an_mode, state); -+ break; -+ default: -+ dev_err(ocelot->dev, "Unsupported link mode %s\n", -+ phy_modes(pcs->interface)); -+ } -+} -+ -+static void vsc9959_pcs_link_state_resolve(struct phy_device *pcs, -+ struct phylink_link_state *state) -+{ -+ state->an_complete = pcs->autoneg_complete; -+ state->an_enabled = pcs->autoneg; -+ state->link = pcs->link; -+ state->duplex = pcs->duplex; -+ state->speed = pcs->speed; -+ /* SGMII AN does not negotiate flow control, but that's ok, -+ * since phylink already knows that, and does: -+ * link_state.pause |= pl->phy_state.pause; -+ */ -+ state->pause = MLO_PAUSE_NONE; -+ -+ phydev_dbg(pcs, -+ "mode=%s/%s/%s adv=%*pb lpa=%*pb link=%u an_enabled=%u an_complete=%u\n", -+ phy_modes(pcs->interface), -+ phy_speed_to_str(pcs->speed), -+ phy_duplex_to_str(pcs->duplex), -+ __ETHTOOL_LINK_MODE_MASK_NBITS, pcs->advertising, -+ __ETHTOOL_LINK_MODE_MASK_NBITS, pcs->lp_advertising, -+ pcs->link, pcs->autoneg, pcs->autoneg_complete); -+} -+ -+static void vsc9959_pcs_link_state_sgmii(struct phy_device *pcs, -+ struct phylink_link_state *state) -+{ -+ int err; -+ -+ err = genphy_update_link(pcs); -+ if (err < 0) -+ return; -+ -+ if (pcs->autoneg_complete) { -+ u16 lpa = phy_read(pcs, MII_LPA); -+ -+ mii_lpa_to_linkmode_lpa_sgmii(pcs->lp_advertising, lpa); -+ -+ phy_resolve_aneg_linkmode(pcs); -+ } -+} -+ -+static void vsc9959_pcs_link_state_2500basex(struct phy_device *pcs, -+ struct phylink_link_state *state) -+{ -+ int err; -+ -+ err = genphy_update_link(pcs); -+ if (err < 0) -+ return; -+ -+ pcs->speed = SPEED_2500; -+ pcs->asym_pause = true; -+ pcs->pause = true; -+} -+ -+static void vsc9959_pcs_link_state_usxgmii(struct phy_device *pcs, -+ struct phylink_link_state *state) -+{ -+ int status, lpa; -+ -+ status = phy_read_mmd(pcs, MDIO_MMD_VEND2, MII_BMSR); -+ if (status < 0) -+ return; -+ -+ pcs->autoneg = true; -+ pcs->autoneg_complete = USXGMII_BMSR_AN_CMPL(status); -+ pcs->link = USXGMII_BMSR_LNKS(status); -+ -+ if (!pcs->link || !pcs->autoneg_complete) -+ return; -+ -+ lpa = phy_read_mmd(pcs, MDIO_MMD_VEND2, MII_LPA); -+ if (lpa < 0) -+ return; -+ -+ switch (USXGMII_LPA_SPEED(lpa)) { -+ case USXGMII_SPEED_10: -+ pcs->speed = SPEED_10; -+ break; -+ case USXGMII_SPEED_100: -+ pcs->speed = SPEED_100; -+ break; -+ case USXGMII_SPEED_1000: -+ pcs->speed = SPEED_1000; -+ break; -+ case USXGMII_SPEED_2500: -+ pcs->speed = SPEED_2500; -+ break; -+ default: -+ break; -+ } -+ -+ pcs->link = USXGMII_LPA_LNKS(lpa); -+ if (USXGMII_LPA_DUPLEX(lpa)) -+ pcs->duplex = DUPLEX_FULL; -+ else -+ pcs->duplex = DUPLEX_HALF; -+} -+ -+static void vsc9959_pcs_link_state(struct ocelot *ocelot, int port, -+ struct phylink_link_state *state) -+{ -+ struct felix *felix = ocelot_to_felix(ocelot); -+ struct phy_device *pcs = felix->pcs[port]; -+ -+ if (!pcs) -+ return; -+ -+ pcs->speed = SPEED_UNKNOWN; -+ pcs->duplex = DUPLEX_UNKNOWN; -+ pcs->pause = 0; -+ pcs->asym_pause = 0; -+ -+ switch (pcs->interface) { -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_QSGMII: -+ vsc9959_pcs_link_state_sgmii(pcs, state); -+ break; -+ case PHY_INTERFACE_MODE_2500BASEX: -+ vsc9959_pcs_link_state_2500basex(pcs, state); -+ break; -+ case PHY_INTERFACE_MODE_USXGMII: -+ vsc9959_pcs_link_state_usxgmii(pcs, state); -+ break; -+ default: -+ return; -+ } -+ -+ vsc9959_pcs_link_state_resolve(pcs, state); -+} -+ -+static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port, -+ phy_interface_t phy_mode) -+{ -+ switch (phy_mode) { -+ case PHY_INTERFACE_MODE_GMII: -+ /* Only supported on internal to-CPU ports */ -+ if (port != 4 && port != 5) -+ return -ENOTSUPP; -+ return 0; -+ case PHY_INTERFACE_MODE_SGMII: -+ case PHY_INTERFACE_MODE_QSGMII: -+ case PHY_INTERFACE_MODE_USXGMII: -+ case PHY_INTERFACE_MODE_2500BASEX: -+ /* Not supported on internal to-CPU ports */ -+ if (port == 4 || port == 5) -+ return -ENOTSUPP; -+ return 0; -+ default: -+ return -ENOTSUPP; -+ } -+} -+ - static const struct ocelot_ops vsc9959_ops = { - .reset = vsc9959_reset, - }; - -+static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot) -+{ -+ struct felix *felix = ocelot_to_felix(ocelot); -+ struct enetc_mdio_priv *mdio_priv; -+ struct device *dev = ocelot->dev; -+ resource_size_t imdio_base; -+ void __iomem *imdio_regs; -+ struct resource *res; -+ struct enetc_hw *hw; -+ struct mii_bus *bus; -+ int port; -+ int rc; -+ -+ felix->pcs = devm_kcalloc(dev, felix->info->num_ports, -+ sizeof(struct phy_device *), -+ GFP_KERNEL); -+ if (!felix->pcs) { -+ dev_err(dev, "failed to allocate array for PCS PHYs\n"); -+ return -ENOMEM; -+ } -+ -+ imdio_base = pci_resource_start(felix->pdev, -+ felix->info->imdio_pci_bar); -+ -+ res = felix->info->imdio_res; -+ res->flags = IORESOURCE_MEM; -+ res->start += imdio_base; -+ res->end += imdio_base; -+ -+ imdio_regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(imdio_regs)) { -+ dev_err(dev, "failed to map internal MDIO registers\n"); -+ return PTR_ERR(imdio_regs); -+ } -+ -+ hw = enetc_hw_alloc(dev, imdio_regs); -+ if (IS_ERR(hw)) { -+ dev_err(dev, "failed to allocate ENETC HW structure\n"); -+ return PTR_ERR(hw); -+ } -+ -+ bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv)); -+ if (!bus) -+ return -ENOMEM; -+ -+ bus->name = "VSC9959 internal MDIO bus"; -+ bus->read = enetc_mdio_read; -+ bus->write = enetc_mdio_write; -+ bus->parent = dev; -+ mdio_priv = bus->priv; -+ mdio_priv->hw = hw; -+ /* This gets added to imdio_regs, which already maps addresses -+ * starting with the proper offset. -+ */ -+ mdio_priv->mdio_base = 0; -+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-imdio", dev_name(dev)); -+ -+ /* Needed in order to initialize the bus mutex lock */ -+ rc = mdiobus_register(bus); -+ if (rc < 0) { -+ dev_err(dev, "failed to register MDIO bus\n"); -+ return rc; -+ } -+ -+ felix->imdio = bus; -+ -+ for (port = 0; port < felix->info->num_ports; port++) { -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ struct phy_device *pcs; -+ bool is_c45 = false; -+ -+ if (ocelot_port->phy_mode == PHY_INTERFACE_MODE_USXGMII) -+ is_c45 = true; -+ -+ pcs = get_phy_device(felix->imdio, port, is_c45); -+ if (IS_ERR(pcs)) -+ continue; -+ -+ pcs->interface = ocelot_port->phy_mode; -+ felix->pcs[port] = pcs; -+ -+ dev_info(dev, "Found PCS at internal MDIO address %d\n", port); -+ } -+ -+ return 0; -+} -+ -+static void vsc9959_mdio_bus_free(struct ocelot *ocelot) -+{ -+ struct felix *felix = ocelot_to_felix(ocelot); -+ int port; -+ -+ for (port = 0; port < ocelot->num_phys_ports; port++) { -+ struct phy_device *pcs = felix->pcs[port]; -+ -+ if (!pcs) -+ continue; -+ -+ put_device(&pcs->mdio.dev); -+ } -+ mdiobus_unregister(felix->imdio); -+} -+ - struct felix_info felix_info_vsc9959 = { - .target_io_res = vsc9959_target_io_res, - .port_io_res = vsc9959_port_io_res, -+ .imdio_res = &vsc9959_imdio_res, - .regfields = vsc9959_regfields, - .map = vsc9959_regmap, - .ops = &vsc9959_ops, -@@ -583,5 +1075,12 @@ struct felix_info felix_info_vsc9959 = { - .num_stats = ARRAY_SIZE(vsc9959_stats_layout), - .shared_queue_sz = 128 * 1024, - .num_ports = 6, -- .pci_bar = 4, -+ .switch_pci_bar = 4, -+ .imdio_pci_bar = 0, -+ .mdio_bus_alloc = vsc9959_mdio_bus_alloc, -+ .mdio_bus_free = vsc9959_mdio_bus_free, -+ .pcs_init = vsc9959_pcs_init, -+ .pcs_an_restart = vsc9959_pcs_an_restart, -+ .pcs_link_state = vsc9959_pcs_link_state, -+ .prevalidate_phy_mode = vsc9959_prevalidate_phy_mode, - }; diff --git a/target/linux/layerscape/patches-5.4/701-net-0387-net-phy-vsc8514-enable-in-band-SGMII-auto-negotiatio.patch b/target/linux/layerscape/patches-5.4/701-net-0387-net-phy-vsc8514-enable-in-band-SGMII-auto-negotiatio.patch deleted file mode 100644 index 8aaafe5dcc..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0387-net-phy-vsc8514-enable-in-band-SGMII-auto-negotiatio.patch +++ /dev/null @@ -1,56 +0,0 @@ -From ebfedac745f6d747df2214e11a89ba44742b3def Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Fri, 27 Dec 2019 21:44:46 +0200 -Subject: [PATCH] net: phy: vsc8514: enable in-band SGMII auto-negotiation - setting - -The default in-band AN setting for the VSC8514 PHY is not very reliable: -its out-of-reset state is with SerDes AN disabled, but certain boot -firmware (such as U-Boot) enables it during the boot process. - -So its final state as seen by Linux depends on whether the U-Boot PHY -driver has run or not. - -If SGMII auto-negotiation is enabled but not acknowledged by the MAC, -the PHY does not pass traffic. - -But otherwise, it is able to pass traffic both with AN disabled, and -with AN enabled. - -We would like to make this explicitly configurable rather than hardcoded -as "on" as we are doing right now, but we'd rather hardcode it in LSDK -and wait until a solution lands upstream, than invent a solution for -this here. - -Signed-off-by: Alex Marginean -Signed-off-by: Vladimir Oltean ---- - drivers/net/phy/mscc.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/net/phy/mscc.c -+++ b/drivers/net/phy/mscc.c -@@ -176,6 +176,8 @@ enum rgmii_rx_clock_delay { - #define SECURE_ON_PASSWD_LEN_4 0x4000 - - /* Extended Page 3 Registers */ -+#define MSCC_PHY_SERDES_CON 16 -+#define MSCC_PHY_SERDES_ANEG BIT(7) - #define MSCC_PHY_SERDES_TX_VALID_CNT 21 - #define MSCC_PHY_SERDES_TX_CRC_ERR_CNT 22 - #define MSCC_PHY_SERDES_RX_VALID_CNT 28 -@@ -2131,6 +2133,14 @@ static int vsc8514_config_init(struct ph - - mutex_unlock(&phydev->mdio.bus->mdio_lock); - -+ ret = phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXTENDED_3); -+ if (ret) -+ return ret; -+ -+ ret = phy_set_bits(phydev, MSCC_PHY_SERDES_CON, MSCC_PHY_SERDES_ANEG); -+ if (ret) -+ return ret; -+ - ret = phy_write(phydev, MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_STANDARD); - - if (ret) diff --git a/target/linux/layerscape/patches-5.4/701-net-0388-drivers-net-phy-aquantia-Add-XFI-counters.patch b/target/linux/layerscape/patches-5.4/701-net-0388-drivers-net-phy-aquantia-Add-XFI-counters.patch deleted file mode 100644 index 8c65e3a492..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0388-drivers-net-phy-aquantia-Add-XFI-counters.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 30da8769107ce2112f3dc356fd06f0fa5bed7742 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Mon, 6 Jan 2020 17:57:10 +0200 -Subject: [PATCH] drivers: net: phy: aquantia: Add XFI counters - -Adds XFI counters and enables counters for AQR112/412. These are gen 3 -PHYs, the register map is compatible with AQR107 which is gen 2. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/aquantia_main.c | 27 ++++++++++++++++++++++++--- - 1 file changed, 24 insertions(+), 3 deletions(-) - ---- a/drivers/net/phy/aquantia_main.c -+++ b/drivers/net/phy/aquantia_main.c -@@ -25,6 +25,12 @@ - #define PHY_ID_AQR112 0x03a1b662 - #define PHY_ID_AQR412 0x03a1b712 - -+/* PCS counters */ -+#define MDIO_C45_PCS_STAT_XFI_TX_GOOD_FRAMES 0xc860 -+#define MDIO_C45_PCS_STAT_XFI_TX_BAD_FRAMES 0xc862 -+#define MDIO_C45_PCS_STAT_XFI_RX_GOOD_FRAMES 0xe860 -+#define MDIO_C45_PCS_STAT_XFI_RX_BAD_FRAMES 0xe862 -+ - #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) - #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0 -@@ -153,9 +159,12 @@ struct aqr107_hw_stat { - const char *name; - int reg; - int size; -+ int devad; - }; - --#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s } -+#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s, \ -+ MDIO_MMD_C22EXT} -+#define C45_PCS_STAT(n, r, s) { n, MDIO_C45_PCS_STAT_ ## r, s, MDIO_MMD_PCS } - static const struct aqr107_hw_stat aqr107_hw_stats[] = { - SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26), - SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26), -@@ -167,6 +176,10 @@ static const struct aqr107_hw_stat aqr10 - SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8), - SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16), - SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22), -+ C45_PCS_STAT("xfi_rx_good_frames", XFI_RX_GOOD_FRAMES, 26), -+ C45_PCS_STAT("xfi_rx_bad_frames", XFI_RX_BAD_FRAMES, 26), -+ C45_PCS_STAT("xfi_tx_good_frames", XFI_TX_GOOD_FRAMES, 26), -+ C45_PCS_STAT("xfi_tx_bad_frames", XFI_TX_BAD_FRAMES, 26), - }; - #define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats) - -@@ -196,13 +209,13 @@ static u64 aqr107_get_stat(struct phy_de - u64 ret; - int val; - -- val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg); -+ val = phy_read_mmd(phydev, stat->devad, stat->reg); - if (val < 0) - return U64_MAX; - - ret = val & GENMASK(len_l - 1, 0); - if (len_h) { -- val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1); -+ val = phy_read_mmd(phydev, stat->devad, stat->reg + 1); - if (val < 0) - return U64_MAX; - -@@ -768,18 +781,26 @@ static struct phy_driver aqr_driver[] = - { - PHY_ID_MATCH_MODEL(PHY_ID_AQR112), - .name = "Aquantia AQR112", -+ .probe = aqr107_probe, - .config_aneg = aqr_config_aneg_set_prot, - .config_intr = aqr_config_intr, - .ack_interrupt = aqr_ack_interrupt, - .read_status = aqr_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, - }, - { - PHY_ID_MATCH_MODEL(PHY_ID_AQR412), - .name = "Aquantia AQR412", -+ .probe = aqr107_probe, - .config_aneg = aqr_config_aneg_set_prot, - .config_intr = aqr_config_intr, - .ack_interrupt = aqr_ack_interrupt, - .read_status = aqr_read_status, -+ .get_sset_count = aqr107_get_sset_count, -+ .get_strings = aqr107_get_strings, -+ .get_stats = aqr107_get_stats, - }, - }; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0389-drivers-net-felix-set-link-based-on-BMSR-not-LPA.patch b/target/linux/layerscape/patches-5.4/701-net-0389-drivers-net-felix-set-link-based-on-BMSR-not-LPA.patch deleted file mode 100644 index 1d8f1f4480..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0389-drivers-net-felix-set-link-based-on-BMSR-not-LPA.patch +++ /dev/null @@ -1,23 +0,0 @@ -From a40da00390f47fa698ef9ef9a2c82d427f6f8aa6 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 7 Jan 2020 16:44:20 +0200 -Subject: [PATCH] drivers: net: felix: set link based on BMSR, not LPA - -At least some PHYs don't advertise link up during system side AN, rely on -local indication from internal PHYs for link state. - -Signed-off-by: Alex Marginean ---- - drivers/net/dsa/ocelot/felix_vsc9959.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/net/dsa/ocelot/felix_vsc9959.c -+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c -@@ -896,7 +896,6 @@ static void vsc9959_pcs_link_state_usxgm - break; - } - -- pcs->link = USXGMII_LPA_LNKS(lpa); - if (USXGMII_LPA_DUPLEX(lpa)) - pcs->duplex = DUPLEX_FULL; - else diff --git a/target/linux/layerscape/patches-5.4/701-net-0390-drivers-net-phylink-in-band-AN-for-USXGMII.patch b/target/linux/layerscape/patches-5.4/701-net-0390-drivers-net-phylink-in-band-AN-for-USXGMII.patch deleted file mode 100644 index a805c35d58..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0390-drivers-net-phylink-in-band-AN-for-USXGMII.patch +++ /dev/null @@ -1,35 +0,0 @@ -From a1d37fce23d69a51a299b848d0a5700d64e6db4e Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 7 Jan 2020 16:48:05 +0200 -Subject: [PATCH] drivers: net: phylink: in-band AN for USXGMII - -USXGMII supports passing link information in-band between PHY and MAC PCS, -add it to the list of protocls that support in-band AN mode. - -TODO: -Add 2500baseT, 5GbaseT, 10GbaseT. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/phylink.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/drivers/net/phy/phylink.c -+++ b/drivers/net/phy/phylink.c -@@ -300,6 +300,16 @@ static int phylink_parse_mode(struct phy - phylink_set(pl->supported, 2500baseX_Full); - break; - -+ case PHY_INTERFACE_MODE_USXGMII: -+ phylink_set(pl->supported, 10baseT_Half); -+ phylink_set(pl->supported, 10baseT_Full); -+ phylink_set(pl->supported, 100baseT_Half); -+ phylink_set(pl->supported, 100baseT_Full); -+ phylink_set(pl->supported, 1000baseT_Half); -+ phylink_set(pl->supported, 1000baseT_Full); -+ phylink_set(pl->supported, 2500baseX_Full); -+ break; -+ - case PHY_INTERFACE_MODE_10GKR: - phylink_set(pl->supported, 10baseT_Half); - phylink_set(pl->supported, 10baseT_Full); diff --git a/target/linux/layerscape/patches-5.4/701-net-0391-drivers-net-phy-don-t-crash-in-phy_read-_write_mmd-w.patch b/target/linux/layerscape/patches-5.4/701-net-0391-drivers-net-phy-don-t-crash-in-phy_read-_write_mmd-w.patch deleted file mode 100644 index 532715d0bc..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0391-drivers-net-phy-don-t-crash-in-phy_read-_write_mmd-w.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 8e515a39805c013229698e1a142e16701f07edf9 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Tue, 7 Jan 2020 16:50:31 +0200 -Subject: [PATCH] drivers: net: phy: don't crash in phy_read/_write_mmd without - a PHY driver - -The APIs can be used by Ethernet drivers to configure internal PHYs -without actually loading a PHY driver. Check that drv is not NULL before -reading from it. - -Signed-off-by: Alex Marginean ---- - drivers/net/phy/phy-core.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/phy/phy-core.c -+++ b/drivers/net/phy/phy-core.c -@@ -379,7 +379,7 @@ int __phy_read_mmd(struct phy_device *ph - if (regnum > (u16)~0 || devad > 32) - return -EINVAL; - -- if (phydev->drv->read_mmd) { -+ if (phydev->drv && phydev->drv->read_mmd) { - val = phydev->drv->read_mmd(phydev, devad, regnum); - } else if (phydev->is_c45) { - u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff); -@@ -436,7 +436,7 @@ int __phy_write_mmd(struct phy_device *p - if (regnum > (u16)~0 || devad > 32) - return -EINVAL; - -- if (phydev->drv->write_mmd) { -+ if (phydev->drv && phydev->drv->write_mmd) { - ret = phydev->drv->write_mmd(phydev, devad, regnum, val); - } else if (phydev->is_c45) { - u32 addr = MII_ADDR_C45 | (devad << 16) | (regnum & 0xffff); diff --git a/target/linux/layerscape/patches-5.4/701-net-0392-drivers-net-dsa-felix-Allow-PHY-to-AN-10-100-1000-wi.patch b/target/linux/layerscape/patches-5.4/701-net-0392-drivers-net-dsa-felix-Allow-PHY-to-AN-10-100-1000-wi.patch deleted file mode 100644 index 68c21a2cd7..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0392-drivers-net-dsa-felix-Allow-PHY-to-AN-10-100-1000-wi.patch +++ /dev/null @@ -1,34 +0,0 @@ -From b3841e7de0be51ddb4e0d17ab0561a12c6db2753 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Wed, 8 Jan 2020 12:34:33 +0200 -Subject: [PATCH] drivers: net: dsa: felix: Allow PHY to AN 10/100/1000 with - 2500 serdes link - -If the serdes link is set to 2500 using interfce type 2500base-X, lower -link speeds over on the line side should still be supported. -Rate adaptation is done out of band, in our case using AQR PHYs this is -done using flow control. - -Signed-off-by: Alex Marginean ---- - drivers/net/dsa/ocelot/felix.c | 9 ++++----- - 1 file changed, 4 insertions(+), 5 deletions(-) - ---- a/drivers/net/dsa/ocelot/felix.c -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -218,11 +218,10 @@ static void felix_phylink_validate(struc - phylink_set(mask, Autoneg); - phylink_set(mask, Pause); - phylink_set(mask, Asym_Pause); -- if (state->interface != PHY_INTERFACE_MODE_2500BASEX) { -- phylink_set(mask, 10baseT_Full); -- phylink_set(mask, 100baseT_Full); -- phylink_set(mask, 1000baseT_Full); -- } -+ phylink_set(mask, 10baseT_Full); -+ phylink_set(mask, 100baseT_Full); -+ phylink_set(mask, 1000baseT_Full); -+ - /* The internal ports that run at 2.5G are overclocked GMII */ - if (state->interface == PHY_INTERFACE_MODE_GMII || - state->interface == PHY_INTERFACE_MODE_2500BASEX || diff --git a/target/linux/layerscape/patches-5.4/701-net-0393-drivers-net-dsa-felix-Handle-PAUSE-Rx-regardless-of-.patch b/target/linux/layerscape/patches-5.4/701-net-0393-drivers-net-dsa-felix-Handle-PAUSE-Rx-regardless-of-.patch deleted file mode 100644 index 887ca36e04..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0393-drivers-net-dsa-felix-Handle-PAUSE-Rx-regardless-of-.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 774408ea6a55b9d40b7bdc4ff4e33f1464c605c9 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Wed, 8 Jan 2020 13:15:07 +0200 -Subject: [PATCH] drivers: net: dsa: felix: Handle PAUSE Rx regardless of AN - result - -Flow control is used with 2500Base-X and AQR PHYs to do rate adapation -between line side 100/1000 links and MAC running at 2.5G. This is -independent of the flow control configuration settled on line side though -AN. In general allowing MAC to handle flow control even though AN did -not enable it explicitly should not be a problem, so the patch enables -it in all cases. - -Signed-off-by: Alex Marginean ---- - drivers/net/dsa/ocelot/felix.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - ---- a/drivers/net/dsa/ocelot/felix.c -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -267,8 +267,12 @@ static void felix_phylink_mac_config(str - * specification in incoming pause frames. - */ - mac_fc_cfg = SYS_MAC_FC_CFG_FC_LINK_SPEED(state->speed); -- if (state->pause & MLO_PAUSE_RX) -- mac_fc_cfg |= SYS_MAC_FC_CFG_RX_FC_ENA; -+ -+ /* handle Rx pause in all cases, with 2500base-X this is used for rate -+ * adaptation. -+ */ -+ mac_fc_cfg |= SYS_MAC_FC_CFG_RX_FC_ENA; -+ - if (state->pause & MLO_PAUSE_TX) - mac_fc_cfg |= SYS_MAC_FC_CFG_TX_FC_ENA | - SYS_MAC_FC_CFG_PAUSE_VAL_CFG(0xffff) | diff --git a/target/linux/layerscape/patches-5.4/701-net-0394-drivers-net-mscc_ocelot-don-t-flood-unicast-traffic-.patch b/target/linux/layerscape/patches-5.4/701-net-0394-drivers-net-mscc_ocelot-don-t-flood-unicast-traffic-.patch deleted file mode 100644 index a37cf66def..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0394-drivers-net-mscc_ocelot-don-t-flood-unicast-traffic-.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 714e8c634821b340c191a157e8c4e0b1afd53dfc Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Wed, 8 Jan 2020 15:21:53 +0200 -Subject: [PATCH] drivers: net: mscc_ocelot: don't flood unicast traffic to cpu - -Switch cpu port doesn't learn MAC addresses and the local bridge dev_addr -must be explicitly added to the bridge. -This is done whenever a port is added to a bridge, ports following the -1st one will just overwrite the same entry. - -Signed-off-by: Alex Marginean ---- - drivers/net/ethernet/mscc/ocelot.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/net/ethernet/mscc/ocelot.c -+++ b/drivers/net/ethernet/mscc/ocelot.c -@@ -1677,6 +1677,8 @@ static int ocelot_port_obj_del(struct ne - int ocelot_port_bridge_join(struct ocelot *ocelot, int port, - struct net_device *bridge) - { -+ struct ocelot_port *ocelot_port = ocelot->ports[port]; -+ - if (!ocelot->bridge_mask) { - ocelot->hw_bridge_dev = bridge; - } else { -@@ -1688,6 +1690,12 @@ int ocelot_port_bridge_join(struct ocelo - - ocelot->bridge_mask |= BIT(port); - -+ /* Direct CPU traffic to PCU port, this should override any existing -+ * entries -+ */ -+ ocelot_mact_learn(ocelot, PGID_CPU, bridge->dev_addr, ocelot_port->pvid, -+ ENTRYTYPE_LOCKED); -+ - return 0; - } - EXPORT_SYMBOL(ocelot_port_bridge_join); diff --git a/target/linux/layerscape/patches-5.4/701-net-0395-LF-183-sdk_fman-add-an-option-for-RTC-1588-timer-ini.patch b/target/linux/layerscape/patches-5.4/701-net-0395-LF-183-sdk_fman-add-an-option-for-RTC-1588-timer-ini.patch deleted file mode 100644 index 138d2b666f..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0395-LF-183-sdk_fman-add-an-option-for-RTC-1588-timer-ini.patch +++ /dev/null @@ -1,215 +0,0 @@ -From f7ed64503d5e27571833b76acee721d00448fdec Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Mon, 2 Sep 2019 15:33:16 +0800 -Subject: [PATCH] LF-183 sdk_fman: add an option for RTC (1588 timer) - initialization and APIs - -The RTC (1588 timer) could be managed by either ptp_qoriq driver -or sdk_fman RTC driver. So add an option for sdk_fman RTC -(1588 timer) initialization and APIs, so that user could select -it or not. - -Signed-off-by: Yangbo Lu ---- - drivers/net/ethernet/freescale/sdk_fman/Kconfig | 9 +++++++++ - .../freescale/sdk_fman/Peripherals/FM/Makefile | 3 ++- - .../freescale/sdk_fman/Peripherals/FM/fm.c | 4 ++++ - .../sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h | 22 ++++++++++++++++++++++ - .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 18 +++++++++++++----- - 5 files changed, 50 insertions(+), 6 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/Kconfig -+++ b/drivers/net/ethernet/freescale/sdk_fman/Kconfig -@@ -49,6 +49,15 @@ config FMAN_V3L - endchoice - endmenu - -+config FSL_SDK_FMAN_RTC_API -+ bool "FMan RTC (1588 timer) APIs" -+ default n -+ help -+ This option enables RTC (1588 timer) initialization and -+ APIs support. The ptp_qoriq driver is not available if -+ it is selected for RTC (1588 timer). Neither of them -+ were not able to be used together. -+ - config FMAN_MIB_CNT_OVF_IRQ_EN - bool "Enable the dTSEC MIB counters overflow interrupt" - default n ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile -@@ -19,5 +19,6 @@ obj-y += Pcd/ - obj-y += SP/ - obj-y += Port/ - obj-y += HC/ --obj-y += Rtc/ - obj-y += MACSEC/ -+ -+obj-$(CONFIG_FSL_SDK_FMAN_RTC_API) += Rtc/ ---- a/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c -@@ -602,8 +602,10 @@ do { - FM_G_CALL_10G_MAC_ISR(0); - if (pending & INTR_EN_10G_MAC1) - FM_G_CALL_10G_MAC_ISR(1); -+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API - if (pending & INTR_EN_TMR) - p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle); -+#endif - } - - #if (DPAA_VERSION >= 11) -@@ -4318,8 +4320,10 @@ void FM_EventIsr(t_Handle h_Fm) - p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle); - if (pending & INTR_EN_PLCR) - p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle); -+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API - if (pending & INTR_EN_TMR) - p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle); -+#endif - - /* MAC events may belong to different partitions */ - if (pending & INTR_EN_1G_MAC0) ---- a/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h -@@ -802,6 +802,7 @@ int fm_mac_set_rx_pause_frames( - int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev, - bool en); - -+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API - int fm_rtc_enable(struct fm *fm_dev); - - int fm_rtc_disable(struct fm *fm_dev); -@@ -819,6 +820,27 @@ int fm_rtc_set_alarm(struct fm *fm_dev, - - int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id, - uint64_t fiper); -+#else -+static inline int fm_rtc_enable(struct fm *fm_dev) { return 0; } -+ -+static inline int fm_rtc_disable(struct fm *fm_dev) { return 0; } -+ -+static inline int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts) { return 0; } -+ -+static inline int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts) { return 0; } -+ -+static inline int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift) -+{ return 0; } -+ -+static inline int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift) -+{ return 0; } -+ -+static inline int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id, -+ uint64_t time) { return 0; } -+ -+static inline int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id, -+ uint64_t fiper) { return 0; } -+#endif - - int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, - bool en); ---- a/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -+++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c -@@ -695,11 +695,7 @@ static t_LnxWrpFmDev * ReadFmDevTreeNode - } - } - --/* DPAA PTP timer was managed by ptp_qoriq driver in drivers/ptp/. -- * We will no longer manage it in sdk_fman driver and use related -- * APIs. -- */ --#if 0 -+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API - /* Get the RTC base address and size */ - memset(ids, 0, sizeof(ids)); - if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name))) -@@ -941,6 +937,7 @@ static t_Error ConfigureFmDev(t_LnxWrpFm - if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmMuramBaseAddr, (uint64_t)p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize) != E_OK) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM MURAM memory map")); - -+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API - if (p_LnxWrpFmDev->fmRtcPhysBaseAddr) - { - dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-ptp-timer"); -@@ -954,6 +951,7 @@ static t_Error ConfigureFmDev(t_LnxWrpFm - if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmRtcBaseAddr, (uint64_t)p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize) != E_OK) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC memory map")); - } -+#endif - - #if (DPAA_VERSION >= 11) - if (p_LnxWrpFmDev->fmVspPhysBaseAddr) { -@@ -1187,6 +1185,7 @@ static t_Error InitFmDev(t_LnxWrpFmDev - * FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_MURAM_ECC,FALSE);*/ - } - -+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API - if (p_LnxWrpFmDev->fmRtcBaseAddr) - { - t_FmRtcParams fmRtcParam; -@@ -1205,6 +1204,7 @@ static t_Error InitFmDev(t_LnxWrpFmDev - if (FM_RTC_Init(p_LnxWrpFmDev->h_RtcDev) != E_OK) - RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC")); - } -+#endif - - return E_OK; - } -@@ -1219,8 +1219,10 @@ static void FreeFmDev(t_LnxWrpFmDev *p_ - - FreeFmPcdDev(p_LnxWrpFmDev); - -+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API - if (p_LnxWrpFmDev->h_RtcDev) - FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev); -+#endif - - if (p_LnxWrpFmDev->h_Dev) - FM_Free(p_LnxWrpFmDev->h_Dev); -@@ -1228,12 +1230,14 @@ static void FreeFmDev(t_LnxWrpFmDev *p_ - if (p_LnxWrpFmDev->h_MuramDev) - FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev); - -+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API - if (p_LnxWrpFmDev->fmRtcBaseAddr) - { - SYS_UnregisterIoMap(p_LnxWrpFmDev->fmRtcBaseAddr); - devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmRtcBaseAddr)); - __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize); - } -+#endif - SYS_UnregisterIoMap(p_LnxWrpFmDev->fmMuramBaseAddr); - devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmMuramBaseAddr)); - __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize); -@@ -1463,6 +1467,7 @@ void * fm_get_handle(struct fm *fm) - } - EXPORT_SYMBOL(fm_get_handle); - -+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API - void * fm_get_rtc_handle(struct fm *fm) - { - t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm; -@@ -1470,6 +1475,7 @@ void * fm_get_rtc_handle(struct fm *fm) - return (void *)p_LnxWrpFmDev->h_RtcDev; - } - EXPORT_SYMBOL(fm_get_rtc_handle); -+#endif - - struct fm_port * fm_port_bind (struct device *fm_port_dev) - { -@@ -2053,6 +2059,7 @@ int fm_mac_set_tx_pause_frames(struct fm - #endif - EXPORT_SYMBOL(fm_mac_set_tx_pause_frames); - -+#ifdef CONFIG_FSL_SDK_FMAN_RTC_API - int fm_rtc_enable(struct fm *fm_dev) - { - int _errno; -@@ -2209,6 +2216,7 @@ int fm_rtc_disable_interrupt(struct fm * - } - EXPORT_SYMBOL(fm_rtc_disable_interrupt); - #endif -+#endif /* CONFIG_FSL_SDK_FMAN_RTC_API */ - - int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, bool en) - { diff --git a/target/linux/layerscape/patches-5.4/701-net-0396-LF-183-ptp-depend-on-FSL_SDK_FMAN_RTC_API-for-ptp_qo.patch b/target/linux/layerscape/patches-5.4/701-net-0396-LF-183-ptp-depend-on-FSL_SDK_FMAN_RTC_API-for-ptp_qo.patch deleted file mode 100644 index 09021db155..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0396-LF-183-ptp-depend-on-FSL_SDK_FMAN_RTC_API-for-ptp_qo.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 9dad88f61f7400939a4076b641b6cd80904358cf Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Thu, 5 Dec 2019 15:03:05 +0800 -Subject: [PATCH] LF-183 ptp: depend on !FSL_SDK_FMAN_RTC_API for ptp_qoriq - -When kernel uses SDK version DPAA/FMan drivers, user could -select to use ptp_qoriq driver, or FMan RTC driver to manage -1588 timer. But neither should not be enabled together. -This patch is to add dependency !FSL_SDK_FMAN_RTC_API for -ptp_qoriq driver. - -Signed-off-by: Yangbo Lu ---- - drivers/ptp/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/ptp/Kconfig -+++ b/drivers/ptp/Kconfig -@@ -44,7 +44,7 @@ config PTP_1588_CLOCK_DTE - - config PTP_1588_CLOCK_QORIQ - tristate "Freescale QorIQ 1588 timer as PTP clock" -- depends on GIANFAR || FSL_DPAA_ETH || FSL_SDK_DPAA_ETH || FSL_DPAA2_ETH || FSL_ENETC || FSL_ENETC_VF || COMPILE_TEST -+ depends on !FSL_SDK_FMAN_RTC_API && (GIANFAR || FSL_DPAA_ETH || FSL_SDK_DPAA_ETH || FSL_DPAA2_ETH || FSL_ENETC || FSL_ENETC_VF) || COMPILE_TEST - depends on PTP_1588_CLOCK - default y - help diff --git a/target/linux/layerscape/patches-5.4/701-net-0397-sdk_dpaa-ceetm-fix-recursive-dependencies.patch b/target/linux/layerscape/patches-5.4/701-net-0397-sdk_dpaa-ceetm-fix-recursive-dependencies.patch deleted file mode 100644 index dff27a4d35..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0397-sdk_dpaa-ceetm-fix-recursive-dependencies.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 03117a1e7db4cd3d745c663c697e446695ebb8e1 Mon Sep 17 00:00:00 2001 -From: Camelia Groza -Date: Wed, 8 Jan 2020 18:41:33 +0200 -Subject: [PATCH] sdk_dpaa: ceetm: fix recursive dependencies - -Due to dependencies between the fsl_ceetm and fsl_dpa modules, remove -the module support for the ceetm driver and integrate it into the main -DPAA Ethernet driver. - -The registration of the CEETM Qdisc was the only operation done at -module init. Pass the management of the Qdisc register and unregister -operations to the loading and unloading of the DPAA driver. - -Signed-off-by: Camelia Groza ---- - drivers/net/ethernet/freescale/sdk_dpaa/Makefile | 3 +- - drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 19 +++++++++++++ - .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 32 +--------------------- - 3 files changed, 21 insertions(+), 33 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_dpaa/Makefile -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile -@@ -20,8 +20,7 @@ endif - - ifeq ($(CONFIG_FSL_DPAA_CEETM),y) - ccflags-y += -I$(srctree)/drivers/net/ethernet/freescale/sdk_fman/src/wrapper --obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_ceetm.o --fsl_ceetm-objs += dpaa_eth_ceetm.o -+fsl_dpa-objs += dpaa_eth_ceetm.o - endif - - fsl_mac-objs += mac.o mac-api.o ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c -@@ -72,6 +72,9 @@ - #ifdef CONFIG_FSL_DPAA_DBG_LOOP - #include "dpaa_debugfs.h" - #endif /* CONFIG_FSL_DPAA_DBG_LOOP */ -+#ifdef CONFIG_FSL_DPAA_CEETM -+#include "dpaa_eth_ceetm.h" -+#endif - - /* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files - * using trace events only need to #include -@@ -116,6 +119,10 @@ static uint8_t dpa_priv_common_bpid; - struct net_device *dpa_loop_netdevs[20]; - #endif - -+#ifdef CONFIG_FSL_DPAA_CEETM -+extern struct Qdisc_ops ceetm_qdisc_ops; -+#endif -+ - #ifdef CONFIG_PM - - static int dpaa_suspend(struct device *dev) -@@ -1158,6 +1165,14 @@ static int __init __cold dpa_load(void) - pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", - KBUILD_BASENAME".c", __func__); - -+#ifdef CONFIG_FSL_DPAA_CEETM -+ _errno = register_qdisc(&ceetm_qdisc_ops); -+ if (unlikely(_errno)) -+ pr_err(KBUILD_MODNAME -+ ": %s:%hu:%s(): register_qdisc() = %d\n", -+ KBUILD_BASENAME ".c", __LINE__, __func__, _errno); -+#endif -+ - return _errno; - } - module_init(dpa_load); -@@ -1167,6 +1182,10 @@ static void __exit __cold dpa_unload(voi - pr_debug(KBUILD_MODNAME ": -> %s:%s()\n", - KBUILD_BASENAME".c", __func__); - -+#ifdef CONFIG_FSL_DPAA_CEETM -+ unregister_qdisc(&ceetm_qdisc_ops); -+#endif -+ - platform_driver_unregister(&dpa_driver); - - #ifdef CONFIG_FSL_DPAA_DBG_LOOP ---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c -@@ -33,16 +33,13 @@ - #include - #include "dpaa_eth_ceetm.h" - --#define DPA_CEETM_DESCRIPTION "FSL DPAA CEETM qdisc" --MODULE_LICENSE("Dual BSD/GPL"); --MODULE_DESCRIPTION(DPA_CEETM_DESCRIPTION); -- - const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1] = { - [TCA_CEETM_COPT] = { .len = sizeof(struct tc_ceetm_copt) }, - [TCA_CEETM_QOPS] = { .len = sizeof(struct tc_ceetm_qopt) }, - }; - - struct Qdisc_ops ceetm_qdisc_ops; -+EXPORT_SYMBOL(ceetm_qdisc_ops); - - /* Obtain the DCP and the SP ids from the FMan port */ - static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id, -@@ -2086,30 +2083,3 @@ drop: - dev_kfree_skb_any(skb); - return NET_XMIT_SUCCESS; - } --EXPORT_SYMBOL(ceetm_tx); -- --static int __init ceetm_register(void) --{ -- int _errno = 0; -- -- pr_info(KBUILD_MODNAME ": " DPA_CEETM_DESCRIPTION "\n"); -- -- _errno = register_qdisc(&ceetm_qdisc_ops); -- if (unlikely(_errno)) -- pr_err(KBUILD_MODNAME -- ": %s:%hu:%s(): register_qdisc() = %d\n", -- KBUILD_BASENAME ".c", __LINE__, __func__, _errno); -- -- return _errno; --} -- --static void __exit ceetm_unregister(void) --{ -- pr_debug(KBUILD_MODNAME ": %s:%s() ->\n", -- KBUILD_BASENAME ".c", __func__); -- -- unregister_qdisc(&ceetm_qdisc_ops); --} -- --module_init(ceetm_register); --module_exit(ceetm_unregister); diff --git a/target/linux/layerscape/patches-5.4/701-net-0398-enetc-add-ioctl-support-for-PHY-related-ops.patch b/target/linux/layerscape/patches-5.4/701-net-0398-enetc-add-ioctl-support-for-PHY-related-ops.patch deleted file mode 100644 index 6865f23169..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0398-enetc-add-ioctl-support-for-PHY-related-ops.patch +++ /dev/null @@ -1,30 +0,0 @@ -From d3fe9bfb9c854ce3acb7db099d9c9476e4fe2ea7 Mon Sep 17 00:00:00 2001 -From: Michael Walle -Date: Thu, 7 Nov 2019 09:39:37 +0100 -Subject: [PATCH] enetc: add ioctl() support for PHY-related ops - -If there is an attached PHY try to handle the requested ioctl with its -handler, which allows the userspace to access PHY registers, for -example. This will make mii-diag and similar tools work. - -Signed-off-by: Michael Walle -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/ethernet/freescale/enetc/enetc.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - ---- a/drivers/net/ethernet/freescale/enetc/enetc.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc.c -@@ -1653,7 +1653,10 @@ int enetc_ioctl(struct net_device *ndev, - if (cmd == SIOCGHWTSTAMP) - return enetc_hwtstamp_get(ndev, rq); - #endif -- return -EINVAL; -+ -+ if (!ndev->phydev) -+ return -EINVAL; -+ return phy_mii_ioctl(ndev->phydev, rq, cmd); - } - - int enetc_alloc_msix(struct enetc_ndev_priv *priv) diff --git a/target/linux/layerscape/patches-5.4/701-net-0399-staging-fsl_ppfe-eth-Enhance-error-checking-in-platf.patch b/target/linux/layerscape/patches-5.4/701-net-0399-staging-fsl_ppfe-eth-Enhance-error-checking-in-platf.patch deleted file mode 100644 index bcc67e869e..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0399-staging-fsl_ppfe-eth-Enhance-error-checking-in-platf.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 1ccc18ca96d8a824f2af45d1046d23ccdb90f3df Mon Sep 17 00:00:00 2001 -From: Anji Jagarlmudi -Date: Wed, 8 Jan 2020 12:18:40 +0530 -Subject: [PATCH] staging: fsl_ppfe/eth: Enhance error checking in platform - probe - -Fix the kernel crash when MAC addr is not passed in dtb. - -Signed-off-by: Anji Jagarlmudi ---- - drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - ---- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c -@@ -31,7 +31,11 @@ static int pfe_get_gemac_if_properties(s - const u32 *addr; - - addr = of_get_property(gem, "reg", &size); -- port = be32_to_cpup(addr); -+ if (addr) -+ port = be32_to_cpup(addr); -+ else -+ goto err; -+ - - pdata->ls1012a_eth_pdata[port].gem_id = port; - diff --git a/target/linux/layerscape/patches-5.4/701-net-0400-drivers-staging-fsl_qbman-Disable-Portal-Channel-IRQ.patch b/target/linux/layerscape/patches-5.4/701-net-0400-drivers-staging-fsl_qbman-Disable-Portal-Channel-IRQ.patch deleted file mode 100644 index d9e4b432c2..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0400-drivers-staging-fsl_qbman-Disable-Portal-Channel-IRQ.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 09269e71bfe9ff445ba42e2b88b17d323e434896 Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Mon, 16 Dec 2019 16:59:32 -0500 -Subject: [PATCH] drivers/staging/fsl_qbman: Disable Portal Channel IRQs - -Disable portal channel IRQs to avoid them stopping QBMan from -entering idle mode. Since push mode is used in this driver these -interrupts are not needed/used. - -Signed-off-by: Roy Pledge -(cherry picked from commit 977cf95ef173bf22b1816e7dbafcbb0f8a151133) ---- - drivers/staging/fsl_qbman/qman_high.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/staging/fsl_qbman/qman_high.c -+++ b/drivers/staging/fsl_qbman/qman_high.c -@@ -737,7 +737,12 @@ struct qman_portal *qman_create_portal( - } - /* Success */ - portal->config = config; -- qm_isr_disable_write(__p, 0); -+ /* -+ * Undisable all the IRQs except the dequeue available bits. -+ * If left enabled they cause problems with sleep mode. Since -+ * they are not used in push mode we can safely turn them off -+ */ -+ qm_isr_disable_write(__p, QM_DQAVAIL_MASK); - qm_isr_uninhibit(__p); - /* Write a sane SDQCR */ - qm_dqrr_sdqcr_set(__p, portal->sdqcr); diff --git a/target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch b/target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch deleted file mode 100644 index b4767511f4..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0401-fsl_qbman-Framework-for-enabling-Link-status-notific.patch +++ /dev/null @@ -1,385 +0,0 @@ -From 136d46d2fa27815cc4cc3a57d5e3d54523028768 Mon Sep 17 00:00:00 2001 -From: Sachin Saxena -Date: Thu, 19 Dec 2019 12:57:35 +0530 -Subject: [PATCH] fsl_qbman: Framework for enabling Link status notification - - - This will enable link update event notification for - user space USDPAA application. - -Signed-off-by: Sachin Saxena -DPDK-2128 -(cherry picked from commit fb53c813a779cc3fc28c8ed3fc8bc0dde24db0ea) ---- - drivers/staging/fsl_qbman/Makefile | 4 + - drivers/staging/fsl_qbman/fsl_usdpaa.c | 278 ++++++++++++++++++++++++++++++++- - include/linux/fsl_usdpaa.h | 32 ++++ - 3 files changed, 313 insertions(+), 1 deletion(-) - ---- a/drivers/staging/fsl_qbman/Makefile -+++ b/drivers/staging/fsl_qbman/Makefile -@@ -1,5 +1,9 @@ - subdir-ccflags-y := -Werror - -+# Include netcomm SW specific definitions -+include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+ccflags-y += -I$(NET_DPA) -+ - # Common - obj-$(CONFIG_FSL_SDK_DPA) += dpa_alloc.o - obj-$(CONFIG_FSL_SDK_DPA) += qbman_driver.o ---- a/drivers/staging/fsl_qbman/fsl_usdpaa.c -+++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c -@@ -18,6 +18,8 @@ - #include - #include - #include -+#include -+#include - - #if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64)) - #include -@@ -27,6 +29,26 @@ - #include - #include "bman_low.h" - #include "qman_low.h" -+/* Headers requires for -+ * Link status support -+ */ -+#include -+#include -+#include "mac.h" -+#include "dpaa_eth_common.h" -+ -+/* Private data for Proxy Interface */ -+struct dpa_proxy_priv_s { -+ struct mac_device *mac_dev; -+ struct eventfd_ctx *efd_ctx; -+}; -+/* Interface Helpers */ -+static inline struct device *get_dev_ptr(char *if_name); -+static void phy_link_updates(struct net_device *net_dev); -+/* IOCTL handlers */ -+static inline int ioctl_usdpaa_get_link_status(char *if_name); -+static int ioctl_en_if_link_status(struct usdpaa_ioctl_link_status *args); -+static int ioctl_disable_if_link_status(char *if_name); - - /* Physical address range of the memory reservation, exported for mm/mem.c */ - static u64 phys_start; -@@ -556,7 +578,6 @@ static bool check_portal_channel(void *c - - - -- - static int usdpaa_release(struct inode *inode, struct file *filp) - { - int err = 0; -@@ -1656,6 +1677,220 @@ found: - return 0; - } - -+ -+static inline struct device *get_dev_ptr(char *if_name) -+{ -+ struct device *dev; -+ char node[NODE_NAME_LEN]; -+ -+ sprintf(node, "soc:fsl,dpaa:%s",if_name); -+ dev = bus_find_device_by_name(&platform_bus_type, NULL, node); -+ if (dev == NULL) { -+ pr_err(KBUILD_MODNAME "IF %s not found\n", if_name); -+ return NULL; -+ } -+ pr_debug("%s: found dev 0x%lX for If %s ,dev->platform_data %p\n", -+ __func__, (unsigned long)dev, -+ if_name, dev->platform_data); -+ -+ return dev; -+} -+ -+/* This function will return Current link status of the device -+ * '1' if Link is UP, '0' otherwise. -+ * -+ * Input parameter: -+ * if_name: Interface node name -+ * -+ */ -+static inline int ioctl_usdpaa_get_link_status(char *if_name) -+{ -+ struct net_device *net_dev = NULL; -+ struct device *dev; -+ -+ dev = get_dev_ptr(if_name); -+ if (dev == NULL) -+ return -ENODEV; -+ net_dev = dev->platform_data; -+ if (net_dev == NULL) -+ return -ENODEV; -+ -+ if (test_bit(__LINK_STATE_NOCARRIER, &net_dev->state)) -+ return 0; /* Link is DOWN */ -+ else -+ return 1; /* Link is UP */ -+} -+ -+ -+/* Link Status Callback Function -+ * This function will be resgitered to PHY framework to get -+ * Link update notifications and should be responsible for waking up -+ * user space task when there is a link update notification. -+ */ -+static void phy_link_updates(struct net_device *net_dev) -+{ -+ struct dpa_proxy_priv_s *priv = NULL; -+ -+ pr_debug("%s: Link '%s': Speed '%d-Mbps': Autoneg '%d': Duplex '%d'\n", -+ net_dev->name, -+ ioctl_usdpaa_get_link_status(net_dev->name)?"UP":"DOWN", -+ net_dev->phydev->speed, -+ net_dev->phydev->autoneg, -+ net_dev->phydev->duplex); -+ -+ /* Wake up the user space context to notify PHY update */ -+ priv = netdev_priv(net_dev); -+ eventfd_signal(priv->efd_ctx, 1); -+} -+ -+ -+/* IOCTL handler for enabling Link status request for a given interface -+ * Input parameters: -+ * args->if_name: This the network interface node name as defind in -+ * device tree file. Currently, it has format of -+ * "ethernet@x" type for each interface. -+ * args->efd: The eventfd value which should be waked up when -+ * there is any link update received. -+ */ -+static int ioctl_en_if_link_status(struct usdpaa_ioctl_link_status *args) -+{ -+ struct net_device *net_dev = NULL; -+ struct dpa_proxy_priv_s *priv = NULL; -+ struct device *dev; -+ struct mac_device *mac_dev; -+ struct proxy_device *proxy_dev; -+ struct task_struct *userspace_task = NULL; -+ struct file *efd_file = NULL; -+ -+ dev = get_dev_ptr(args->if_name); -+ if (dev == NULL) -+ return -ENODEV; -+ /* Utilize dev->platform_data to save netdevice -+ pointer as it will not be registered */ -+ if (dev->platform_data) { -+ pr_debug("%s: IF %s already initialized\n", -+ __func__, args->if_name); -+ /* This will happen when application is not able to initiate -+ * cleanup in last run. We still need to save the new -+ * eventfd context. -+ */ -+ net_dev = dev->platform_data; -+ priv = netdev_priv(net_dev); -+ -+ /* Get current task context from which IOCTL was called */ -+ userspace_task = current; -+ -+ rcu_read_lock(); -+ efd_file = fcheck_files(userspace_task->files, args->efd); -+ rcu_read_unlock(); -+ -+ priv->efd_ctx = eventfd_ctx_fileget(efd_file); -+ if (!priv->efd_ctx) { -+ pr_err(KBUILD_MODNAME "get eventfd context failed\n"); -+ /* Free the allocated memory for net device */ -+ dev->platform_data = NULL; -+ free_netdev(net_dev); -+ return -EINVAL; -+ } -+ /* Since there will be NO PHY update as link is already setup, -+ * wake user context once so that current PHY status can -+ * be fetched. -+ */ -+ phy_link_updates(net_dev); -+ return 0; -+ } -+ -+ proxy_dev = dev_get_drvdata(dev); -+ mac_dev = proxy_dev->mac_dev; -+ /* Allocate an dummy net device for proxy interface */ -+ net_dev = alloc_etherdev(sizeof(*priv)); -+ if (!net_dev) { -+ pr_err(KBUILD_MODNAME "alloc_etherdev failed\n"); -+ return -ENOMEM; -+ } else { -+ SET_NETDEV_DEV(net_dev, dev); -+ priv = netdev_priv(net_dev); -+ priv->mac_dev = mac_dev; -+ /* Get current task context from which IOCTL was called */ -+ userspace_task = current; -+ -+ rcu_read_lock(); -+ efd_file = fcheck_files(userspace_task->files, args->efd); -+ rcu_read_unlock(); -+ -+ priv->efd_ctx = eventfd_ctx_fileget(efd_file); -+ -+ if (!priv->efd_ctx) { -+ pr_err(KBUILD_MODNAME "get eventfd context failed\n"); -+ /* Free the allocated memory for net device */ -+ free_netdev(net_dev); -+ return -EINVAL; -+ } -+ strncpy(net_dev->name, args->if_name, IF_NAME_MAX_LEN); -+ dev->platform_data = net_dev; -+ } -+ -+ pr_debug("%s: mac_dev %p cell_index %d\n", -+ __func__, mac_dev, mac_dev->cell_index); -+ mac_dev->phy_dev = of_phy_connect(net_dev, mac_dev->phy_node, -+ phy_link_updates, 0, mac_dev->phy_if); -+ if (unlikely(mac_dev->phy_dev == NULL) || IS_ERR(mac_dev->phy_dev)) { -+ pr_err("%s: --------Error in PHY Connect\n", __func__); -+ /* Free the allocated memory for net device */ -+ free_netdev(net_dev); -+ return -ENODEV; -+ } -+ net_dev->phydev = mac_dev->phy_dev; -+ mac_dev->start(mac_dev); -+ pr_debug("%s: --- PHY connected for %s\n", __func__, args->if_name); -+ -+ return 0; -+} -+ -+/* IOCTL handler for disabling Link status for a given interface -+ * Input parameters: -+ * if_name: This the network interface node name as defind in -+ * device tree file. Currently, it has format of -+ * "ethernet@x" type for each interface. -+ */ -+static int ioctl_disable_if_link_status(char *if_name) -+{ -+ struct net_device *net_dev = NULL; -+ struct device *dev; -+ struct mac_device *mac_dev; -+ struct proxy_device *proxy_dev; -+ struct dpa_proxy_priv_s *priv = NULL; -+ -+ dev = get_dev_ptr(if_name); -+ if (dev == NULL) -+ return -ENODEV; -+ /* Utilize dev->platform_data to save netdevice -+ pointer as it will not be registered */ -+ if (!dev->platform_data) { -+ pr_debug("%s: IF %s already Disabled for Link status\n", -+ __func__, if_name); -+ return 0; -+ } -+ -+ net_dev = dev->platform_data; -+ proxy_dev = dev_get_drvdata(dev); -+ mac_dev = proxy_dev->mac_dev; -+ mac_dev->stop(mac_dev); -+ -+ priv = netdev_priv(net_dev); -+ eventfd_ctx_put(priv->efd_ctx); -+ -+ /* This will also deregister the call back */ -+ phy_disconnect(mac_dev->phy_dev); -+ phy_resume(mac_dev->phy_dev); -+ -+ free_netdev(net_dev); -+ dev->platform_data = NULL; -+ -+ pr_debug("%s: Link status Disabled for %s\n", __func__, if_name); -+ return 0; -+} -+ - static long usdpaa_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) - { - struct ctx *ctx = fp->private_data; -@@ -1722,6 +1957,47 @@ static long usdpaa_ioctl(struct file *fp - return -EFAULT; - return ioctl_free_raw_portal(fp, ctx, &input); - } -+ case USDPAA_IOCTL_ENABLE_LINK_STATUS_INTERRUPT: -+ { -+ struct usdpaa_ioctl_link_status input; -+ int ret; -+ -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ ret = ioctl_en_if_link_status(&input); -+ if (ret) -+ pr_err("Error(%d) enable link interrupt:IF: %s\n", -+ ret, input.if_name); -+ return ret; -+ } -+ case USDPAA_IOCTL_DISABLE_LINK_STATUS_INTERRUPT: -+ { -+ char *input; -+ int ret; -+ -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ ret = ioctl_disable_if_link_status(input); -+ if (ret) -+ pr_err("Error(%d) Disabling link interrupt:IF: %s\n", -+ ret, input); -+ return ret; -+ } -+ case USDPAA_IOCTL_GET_LINK_STATUS: -+ { -+ struct usdpaa_ioctl_link_status_args input; -+ -+ if (copy_from_user(&input, a, sizeof(input))) -+ return -EFAULT; -+ -+ input.link_status = ioctl_usdpaa_get_link_status(input.if_name); -+ if (input.link_status < 0) -+ return input.link_status; -+ if (copy_to_user(a, &input, sizeof(input))) -+ return -EFAULT; -+ -+ return 0; -+ } - } - return -EINVAL; - } ---- a/include/linux/fsl_usdpaa.h -+++ b/include/linux/fsl_usdpaa.h -@@ -365,6 +365,38 @@ int dpa_alloc_pop(struct dpa_alloc *allo - int dpa_alloc_check(struct dpa_alloc *list, u32 id); - #endif /* __KERNEL__ */ - -+ -+/************************************ -+ * Link Status support for user space -+ * interface -+ ************************************/ -+#define IF_NAME_MAX_LEN 16 -+#define NODE_NAME_LEN 32 -+ -+struct usdpaa_ioctl_link_status { -+ /* network device node name */ -+ char if_name[IF_NAME_MAX_LEN]; -+ /* Eventfd value */ -+ uint32_t efd; -+}; -+ -+#define USDPAA_IOCTL_ENABLE_LINK_STATUS_INTERRUPT \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x0E, struct usdpaa_ioctl_link_status) -+ -+#define USDPAA_IOCTL_DISABLE_LINK_STATUS_INTERRUPT \ -+ _IOW(USDPAA_IOCTL_MAGIC, 0x0F, char *) -+ -+struct usdpaa_ioctl_link_status_args { -+ /* network device node name */ -+ char if_name[IF_NAME_MAX_LEN]; -+ /* link status(UP/DOWN) */ -+ int link_status; -+}; -+ -+#define USDPAA_IOCTL_GET_LINK_STATUS \ -+ _IOWR(USDPAA_IOCTL_MAGIC, 0x10, struct usdpaa_ioctl_link_status_args) -+ -+ - #ifdef __cplusplus - } - #endif diff --git a/target/linux/layerscape/patches-5.4/701-net-0402-drivers-net-dsa-felix-don-t-restart-PCS-SGMII-AN-if-.patch b/target/linux/layerscape/patches-5.4/701-net-0402-drivers-net-dsa-felix-don-t-restart-PCS-SGMII-AN-if-.patch deleted file mode 100644 index 5008ca5c77..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0402-drivers-net-dsa-felix-don-t-restart-PCS-SGMII-AN-if-.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 2a2ccfa44e56c45dfd1230f6efb3ec0a4a677f0a Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Wed, 15 Jan 2020 15:49:11 +0200 -Subject: [PATCH] drivers: net: dsa: felix: don't restart PCS SGMII AN if not - needed - -Some PHYs like VSC8234 don't like it when AN restarts on their system side -and they restart line side AN too, going into an endless link up/down loop. -Don't restart PCS AN if link is up already. - -Suggested-by: Vladimir Oltean -Signed-off-by: Alex Marginean ---- - drivers/net/dsa/ocelot/felix_vsc9959.c | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - ---- a/drivers/net/dsa/ocelot/felix_vsc9959.c -+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c -@@ -648,7 +648,22 @@ static void vsc9959_pcs_init_sgmii(struc - unsigned int link_an_mode, - const struct phylink_link_state *state) - { -+ int bmsr, bmcr; -+ - if (link_an_mode == MLO_AN_INBAND) { -+ /* Some PHYs like VSC8234 don't like it when AN restarts on -+ * their system side and they restart line side AN too, going -+ * into an endless link up/down loop. Don't restart PCS AN if -+ * link is up already. -+ * We do check that AN is enabled just in case this is the 1st -+ * call, PCS detects a carrier but AN is disabled from power on -+ * or by boot loader. -+ */ -+ bmcr = phy_read(pcs, MII_BMCR); -+ bmsr = phy_read(pcs, MII_BMSR); -+ if ((bmcr & BMCR_ANENABLE) && (bmsr & BMSR_LSTATUS)) -+ return; -+ - /* SGMII spec requires tx_config_Reg[15:0] to be exactly 0x4001 - * for the MAC PCS in order to acknowledge the AN. - */ diff --git a/target/linux/layerscape/patches-5.4/701-net-0403-net-dsa-felix-Don-t-error-out-on-disabled-ports-with.patch b/target/linux/layerscape/patches-5.4/701-net-0403-net-dsa-felix-Don-t-error-out-on-disabled-ports-with.patch deleted file mode 100644 index febb557cdd..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0403-net-dsa-felix-Don-t-error-out-on-disabled-ports-with.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 921af144d0022ae6036024ae4981e774711949a7 Mon Sep 17 00:00:00 2001 -From: Vladimir Oltean -Date: Thu, 16 Jan 2020 20:41:53 +0200 -Subject: [PATCH] net: dsa: felix: Don't error out on disabled ports with no - phy-mode - -The felix_parse_ports_node function was tested only on device trees -where all ports were enabled. Fix this check so that the driver -continues to probe only with the ports where status is not "disabled", -as expected. - -Fixes: bdeced75b13f ("net: dsa: felix: Add PCS operations for PHYLINK") -Signed-off-by: Vladimir Oltean -Reviewed-by: Florian Fainelli -Reviewed-by: Andrew Lunn -Signed-off-by: David S. Miller ---- - drivers/net/dsa/ocelot/felix.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/dsa/ocelot/felix.c -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -372,7 +372,7 @@ static int felix_parse_ports_node(struct - struct device *dev = felix->ocelot.dev; - struct device_node *child; - -- for_each_child_of_node(ports_node, child) { -+ for_each_available_child_of_node(ports_node, child) { - phy_interface_t phy_mode; - u32 port; - int err; diff --git a/target/linux/layerscape/patches-5.4/701-net-0404-LF-457-ocelot-tsn-clean-preempt-interrupt-status.patch b/target/linux/layerscape/patches-5.4/701-net-0404-LF-457-ocelot-tsn-clean-preempt-interrupt-status.patch deleted file mode 100644 index 96897b5e2a..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0404-LF-457-ocelot-tsn-clean-preempt-interrupt-status.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 5d246e343440ee4915109dac66543d02d71ca900 Mon Sep 17 00:00:00 2001 -From: Xiaoliang Yang -Date: Tue, 11 Feb 2020 15:33:46 +0800 -Subject: [PATCH] LF-457: ocelot: tsn: clean preempt interrupt status - -The INTB interrupt is used both for 1588 interrupt and preemption status -change interrupt on each port. So clean preempt status interrupt in IRQ -handle function. Without handling it, driver may get interrupt storm. - -Signed-off-by: Xiaoliang Yang -Reviewed-by: Po Liu ---- - drivers/net/dsa/ocelot/felix.c | 5 +---- - drivers/net/ethernet/mscc/ocelot_tsn.c | 14 ++++++++++++++ - include/soc/mscc/ocelot.h | 1 + - 3 files changed, 16 insertions(+), 4 deletions(-) - ---- a/drivers/net/dsa/ocelot/felix.c -+++ b/drivers/net/dsa/ocelot/felix.c -@@ -688,12 +688,9 @@ static irqreturn_t felix_irq_handler(int - - /* The INTB interrupt is used for both PTP TX timestamp interrupt - * and preemption status change interrupt on each port. -- * -- * - Get txtstamp if have -- * - TODO: handle preemption. Without handling it, driver may get -- * interrupt storm. - */ - -+ ocelot_preempt_irq_clean(ocelot); - ocelot_get_txtstamp(ocelot); - - return IRQ_HANDLED; ---- a/drivers/net/ethernet/mscc/ocelot_tsn.c -+++ b/drivers/net/ethernet/mscc/ocelot_tsn.c -@@ -1570,3 +1570,17 @@ int ocelot_dscp_set(struct ocelot *ocelo - - return 0; - } -+ -+void ocelot_preempt_irq_clean(struct ocelot *ocelot) -+{ -+ struct ocelot_port *ocelot_port; -+ int port; -+ u32 val; -+ -+ val = DEV_GMII_MM_STATISTICS_MM_STATUS_PRMPT_ACTIVE_STICKY; -+ for (port = 0; port < ocelot->num_phys_ports; port++) { -+ ocelot_port = ocelot->ports[port]; -+ ocelot_port_rmwl(ocelot_port, val, val, -+ DEV_GMII_MM_STATISTICS_MM_STATUS); -+ } -+} ---- a/include/soc/mscc/ocelot.h -+++ b/include/soc/mscc/ocelot.h -@@ -592,4 +592,5 @@ int ocelot_rtag_parse_enable(struct ocel - int ocelot_dscp_set(struct ocelot *ocelot, int port, - bool enable, const u8 dscp_ix, - struct tsn_qos_switch_dscp_conf *c); -+void ocelot_preempt_irq_clean(struct ocelot *ocelot); - #endif diff --git a/target/linux/layerscape/patches-5.4/701-net-0406-sdk_qbman-Only-create-debugfs-entries-when-QBMan-is-.patch b/target/linux/layerscape/patches-5.4/701-net-0406-sdk_qbman-Only-create-debugfs-entries-when-QBMan-is-.patch deleted file mode 100644 index 889aecc383..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0406-sdk_qbman-Only-create-debugfs-entries-when-QBMan-is-.patch +++ /dev/null @@ -1,69 +0,0 @@ -From f34c01773d5dbd2db04200079bb4d32ecb0cd847 Mon Sep 17 00:00:00 2001 -From: Roy Pledge -Date: Tue, 18 Feb 2020 14:02:21 -0500 -Subject: [PATCH] sdk_qbman: Only create debugfs entries when QBMan is part of - device tree - -Only create debugfs entries if the QBMan nodes exist in the device -tree. - -Signed-off-by: Roy Pledge -Acked-by: Madalin Bucur -Signed-off-by: Dong Aisheng ---- - drivers/staging/fsl_qbman/bman_debugfs.c | 8 +++++++- - drivers/staging/fsl_qbman/qman_debugfs.c | 17 ++++++++++------- - 2 files changed, 17 insertions(+), 8 deletions(-) - ---- a/drivers/staging/fsl_qbman/bman_debugfs.c -+++ b/drivers/staging/fsl_qbman/bman_debugfs.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - - static struct dentry *dfs_root; /* debugfs root directory */ - -@@ -83,9 +84,14 @@ static int __init bman_debugfs_module_in - { - int ret = 0; - struct dentry *d; -+ struct device_node *dn; - -+ dn = of_find_compatible_node(NULL, NULL, "fsl,bman"); -+ if (!dn) { -+ pr_debug("No fsl,bman node\n"); -+ return 0; -+ } - dfs_root = debugfs_create_dir("bman", NULL); -- - if (dfs_root == NULL) { - ret = -ENOMEM; - pr_err("Cannot create bman debugfs dir\n"); ---- a/drivers/staging/fsl_qbman/qman_debugfs.c -+++ b/drivers/staging/fsl_qbman/qman_debugfs.c -@@ -1457,13 +1457,16 @@ static int __init qman_debugfs_module_in - - fqid_max = 0; - init_ccsrmempeek(); -- if (qman_ccsr_start) { -- if (!qman_ccsrmempeek(®, QM_FQD_AR)) { -- /* extract the size of the FQD window */ -- reg = reg & 0x3f; -- /* calculate valid frame queue descriptor range */ -- fqid_max = (1 << (reg + 1)) / QM_FQD_BLOCK_SIZE; -- } -+ if (!qman_ccsr_start) { -+ /* No QMan node found in device tree */ -+ return 0; -+ } -+ -+ if (!qman_ccsrmempeek(®, QM_FQD_AR)) { -+ /* extract the size of the FQD window */ -+ reg = reg & 0x3f; -+ /* calculate valid frame queue descriptor range */ -+ fqid_max = (1 << (reg + 1)) / QM_FQD_BLOCK_SIZE; - } - dfs_root = debugfs_create_dir("qman", NULL); - fqd_root = debugfs_create_dir("fqd", dfs_root); diff --git a/target/linux/layerscape/patches-5.4/701-net-0407-LF-924-net-enetc-Set-MAC-Rx-FIFO-to-recommended-valu.patch b/target/linux/layerscape/patches-5.4/701-net-0407-LF-924-net-enetc-Set-MAC-Rx-FIFO-to-recommended-valu.patch deleted file mode 100644 index e381dda7cc..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0407-LF-924-net-enetc-Set-MAC-Rx-FIFO-to-recommended-valu.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 9507f517ac4080627515c31c937f45a4a58ccbe4 Mon Sep 17 00:00:00 2001 -From: Alex Marginean -Date: Fri, 14 Feb 2020 17:28:26 +0000 -Subject: [PATCH] LF-924: net/enetc: Set MAC Rx FIFO to recommended value - -On LS1028A the MAC Rx FIFO defaults to value 2, which is too high and may -lead to Rx lock-up under traffic. Set it to 1 instead, as recommended by -the hardware team. - -Signed-off-by: Alex Marginean -Reviewed-by: Claudiu Manoil -Acked-by: Jason Liu ---- - drivers/net/ethernet/freescale/enetc/enetc_hw.h | 2 ++ - drivers/net/ethernet/freescale/enetc/enetc_pf.c | 6 ++++++ - 2 files changed, 8 insertions(+) - ---- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h -+++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h -@@ -226,6 +226,8 @@ enum enetc_bdr_type {TX, RX}; - #define ENETC_PM0_MAXFRM 0x8014 - #define ENETC_SET_TX_MTU(val) ((val) << 16) - #define ENETC_SET_MAXFRM(val) ((val) & 0xffff) -+#define ENETC_PM0_RX_FIFO 0x801c -+#define ENETC_PM0_RX_FIFO_VAL 1 - - #define ENETC_PM_IMDIO_BASE 0x8030 - /* PCS registers */ ---- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c -+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c -@@ -536,6 +536,12 @@ static void enetc_configure_port_mac(str - enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII); - enetc_port_wr(hw, ENETC_PM1_IF_MODE, ENETC_PM0_IFM_XGMII); - } -+ -+ /* on LS1028A the MAC Rx FIFO defaults to value 2, which is too high and -+ * may lead to Rx lock-up under traffic. Set it to 1 instead, as -+ * recommended by the hardware team. -+ */ -+ enetc_port_wr(hw, ENETC_PM0_RX_FIFO, ENETC_PM0_RX_FIFO_VAL); - } - - static void enetc_configure_port_pmac(struct enetc_hw *hw) diff --git a/target/linux/layerscape/patches-5.4/701-net-0408-sdk_fman-fix-CONFIG_COMPAT-leak-during-headers-insta.patch b/target/linux/layerscape/patches-5.4/701-net-0408-sdk_fman-fix-CONFIG_COMPAT-leak-during-headers-insta.patch deleted file mode 100644 index bff431c52d..0000000000 --- a/target/linux/layerscape/patches-5.4/701-net-0408-sdk_fman-fix-CONFIG_COMPAT-leak-during-headers-insta.patch +++ /dev/null @@ -1,516 +0,0 @@ -From 7837219f354524f6c2c9332a6a5aa616c28f53a9 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Thu, 20 Aug 2020 18:38:49 +0800 -Subject: [PATCH] sdk_fman: fix CONFIG_COMPAT leak during headers installing - -This patch is to fix CONFIG_COMPAT leak during headers installing -by replacing CONFIG_COMPAT kernel option with FM_COMPAT instead. - -Signed-off-by: Yangbo Lu ---- - .../net/ethernet/freescale/sdk_fman/ncsw_config.mk | 5 ++ - include/uapi/linux/fmd/Peripherals/fm_ioctls.h | 16 ++--- - include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h | 72 +++++++++++----------- - .../uapi/linux/fmd/Peripherals/fm_port_ioctls.h | 14 ++--- - .../uapi/linux/fmd/Peripherals/fm_test_ioctls.h | 4 +- - 5 files changed, 58 insertions(+), 53 deletions(-) - ---- a/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -+++ b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk -@@ -44,6 +44,11 @@ ifdef CONFIG_FMAN_ARM - ccflags-y += -I$(FMAN)/inc/integrations/LS1043 - endif - -+# FM_COMPAT is used in kernel headers in case of kernel option leaking -+ifeq ("$(CONFIG_COMPAT)", "y") -+ccflags-y += -DFM_COMPAT -+endif -+ - ccflags-y += -I$(FMAN)/src/inc - ccflags-y += -I$(FMAN)/src/inc/system - ccflags-y += -I$(FMAN)/src/inc/wrapper ---- a/include/uapi/linux/fmd/Peripherals/fm_ioctls.h -+++ b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h -@@ -434,7 +434,7 @@ typedef struct ioc_fm_ctrl_mon_counters_ - - @Retval Handle to FM VSP object, or NULL for Failure. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_IOC_VSP_CONFIG_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_compat_fm_vsp_params_t) - #endif - #define FM_IOC_VSP_CONFIG _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_fm_vsp_params_t) -@@ -448,7 +448,7 @@ typedef struct ioc_fm_ctrl_mon_counters_ - - @Return E_OK on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_IOC_VSP_INIT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_compat_fm_obj_t) - #endif - #define FM_IOC_VSP_INIT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_fm_obj_t) -@@ -464,7 +464,7 @@ typedef struct ioc_fm_ctrl_mon_counters_ - - @Return E_OK on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_IOC_VSP_FREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_compat_fm_obj_t) - #endif - #define FM_IOC_VSP_FREE _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_fm_obj_t) -@@ -482,7 +482,7 @@ typedef struct ioc_fm_ctrl_mon_counters_ - - @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_compat_fm_buf_pool_depletion_params_t) - #endif - #define FM_IOC_VSP_CONFIG_POOL_DEPLETION _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_fm_buf_pool_depletion_params_t) -@@ -512,7 +512,7 @@ typedef struct ioc_fm_ctrl_mon_counters_ - - @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_compat_fm_buffer_prefix_content_params_t) - #endif - #define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_fm_buffer_prefix_content_params_t) -@@ -530,7 +530,7 @@ typedef struct ioc_fm_ctrl_mon_counters_ - - @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_IOC_VSP_CONFIG_NO_SG_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_compat_fm_vsp_config_no_sg_params_t) - #endif - #define FM_IOC_VSP_CONFIG_NO_SG _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_fm_vsp_config_no_sg_params_t) -@@ -554,7 +554,7 @@ typedef struct ioc_fm_ctrl_mon_counters_ - - @Cautions Allowed only following FM_VSP_Init(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_compat_fm_vsp_prs_result_params_t) - #endif - #define FM_IOC_VSP_GET_BUFFER_PRS_RESULT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_fm_vsp_prs_result_params_t) -@@ -612,7 +612,7 @@ typedef struct ioc_fm_ctrl_mon_counters_ - - @Cautions Allowed only following FM_Init(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_compat_fm_ctrl_mon_counters_params_t) - #endif - #define FM_IOC_CTRL_MON_GET_COUNTERS _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_fm_ctrl_mon_counters_params_t) ---- a/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h -+++ b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h -@@ -312,7 +312,7 @@ typedef struct ioc_fm_pcd_kg_dflt_value_ - - @Cautions Allowed only when PCD is disabled. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_PRS_LOAD_SW_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_compat_fm_pcd_prs_sw_params_t) - #endif - #define FM_PCD_IOC_PRS_LOAD_SW _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_fm_pcd_prs_sw_params_t) -@@ -385,7 +385,7 @@ typedef struct ioc_fm_pcd_kg_dflt_value_ - - @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT _IOR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(4), ioc_compat_fm_pcd_kg_scheme_spc_t) - #endif - #define FM_PCD_IOC_KG_SCHEME_GET_CNTR _IOR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(4), ioc_fm_pcd_kg_scheme_spc_t) -@@ -2413,7 +2413,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - @Cautions Allowed only following FM_PCD_MatchTableSet(). - *//***************************************************************************/ - --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(12), ioc_compat_fm_pcd_cc_tbl_get_stats_t) - #endif - #define FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(12), ioc_fm_pcd_cc_tbl_get_stats_t) -@@ -2439,7 +2439,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - @Cautions Allowed only following FM_PCD_MatchTableSet(). - *//***************************************************************************/ - --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(13), ioc_compat_fm_pcd_cc_tbl_get_stats_t) - #endif - #define FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(13), ioc_fm_pcd_cc_tbl_get_stats_t) -@@ -2463,7 +2463,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - @Cautions Allowed only following FM_PCD_HashTableSet(). - *//***************************************************************************/ - --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(14), ioc_compat_fm_pcd_cc_tbl_get_stats_t) - #endif - #define FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(14), ioc_fm_pcd_cc_tbl_get_stats_t) -@@ -2511,7 +2511,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return 0 on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(20), ioc_compat_fm_pcd_net_env_params_t) - #endif - #define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(20), ioc_fm_pcd_net_env_params_t) -@@ -2525,7 +2525,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return 0 on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_compat_fm_obj_t) - #endif - #define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_fm_obj_t) -@@ -2544,7 +2544,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return 0 on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_KG_SCHEME_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_compat_fm_pcd_kg_scheme_params_t) - #endif - #define FM_PCD_IOC_KG_SCHEME_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_fm_pcd_kg_scheme_params_t) -@@ -2558,7 +2558,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return 0 on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_compat_fm_obj_t) - #endif - #define FM_PCD_IOC_KG_SCHEME_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_fm_obj_t) -@@ -2575,7 +2575,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return 0 on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_CC_ROOT_BUILD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), compat_uptr_t) - #endif - #define FM_PCD_IOC_CC_ROOT_BUILD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), void *) /* workaround ...*/ -@@ -2587,7 +2587,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Param[in] ioc_fm_obj_t - The id of a CC tree. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_CC_ROOT_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_compat_fm_obj_t) - #endif - #define FM_PCD_IOC_CC_ROOT_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_fm_obj_t) -@@ -2604,7 +2604,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return 0 on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MATCH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), compat_uptr_t) - #endif - #define FM_PCD_IOC_MATCH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), void *) /* workaround ...*/ -@@ -2618,7 +2618,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return 0 on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_compat_fm_obj_t) - #endif - #define FM_PCD_IOC_MATCH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_fm_obj_t) -@@ -2634,7 +2634,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_CcRootBuild(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(30), ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t) - #endif - #define FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(30), ioc_fm_pcd_cc_tree_modify_next_engine_params_t) -@@ -2650,7 +2650,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_MatchTableSet(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(31), ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t) - #endif - #define FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(31), ioc_fm_pcd_cc_node_modify_next_engine_params_t) -@@ -2666,7 +2666,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_MatchTableSet(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(32), ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t) - #endif - #define FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(32), ioc_fm_pcd_cc_node_modify_next_engine_params_t) -@@ -2684,7 +2684,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this - node and for all of the nodes that lead to it. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(33), ioc_compat_fm_pcd_cc_node_remove_key_params_t) - #endif - #define FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(33), ioc_fm_pcd_cc_node_remove_key_params_t) -@@ -2705,7 +2705,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this - node and for all of the nodes that lead to it. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(34), ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t) - #endif - #define FM_PCD_IOC_MATCH_TABLE_ADD_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(34), ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t) -@@ -2722,7 +2722,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - @Cautions Allowed only following FM_PCD_MatchTableSet() not only of the relevnt node but also - the node that points to this node - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(35), ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t) - #endif - #define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(35), ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t) -@@ -2739,7 +2739,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this - node and for all of the nodes that lead to it. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(36), ioc_compat_fm_pcd_cc_node_modify_key_params_t) - #endif - #define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(36), ioc_fm_pcd_cc_node_modify_key_params_t) -@@ -2766,7 +2766,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return 0 on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_HASH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_pcd_hash_table_params_t) - #endif - #define FM_PCD_IOC_HASH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_pcd_hash_table_params_t) -@@ -2784,7 +2784,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_HashTableSet(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_obj_t) - #endif - #define FM_PCD_IOC_HASH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_obj_t) -@@ -2803,7 +2803,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_HashTableSet(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(39), ioc_compat_fm_pcd_hash_table_add_key_params_t) - #endif - #define FM_PCD_IOC_HASH_TABLE_ADD_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(39), ioc_fm_pcd_hash_table_add_key_params_t) -@@ -2820,7 +2820,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_HashTableSet(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(40), ioc_compat_fm_pcd_hash_table_remove_key_params_t) - #endif - #define FM_PCD_IOC_HASH_TABLE_REMOVE_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(40), ioc_fm_pcd_hash_table_remove_key_params_t) -@@ -2836,7 +2836,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return 0 on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_pcd_plcr_profile_params_t) - #endif - #define FM_PCD_IOC_PLCR_PROFILE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_pcd_plcr_profile_params_t) -@@ -2851,7 +2851,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return 0 on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_obj_t) - #endif - #define FM_PCD_IOC_PLCR_PROFILE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_obj_t) -@@ -2867,7 +2867,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return A handle to the initialized object on success; NULL code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MANIP_NODE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_compat_fm_pcd_manip_params_t) - #endif - #define FM_PCD_IOC_MANIP_NODE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_fm_pcd_manip_params_t) -@@ -2887,7 +2887,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_ManipNodeSet(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MANIP_NODE_REPLACE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT - #endif - #define FM_PCD_IOC_MANIP_NODE_REPLACE FM_PCD_IOC_MANIP_NODE_SET -@@ -2903,7 +2903,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_ManipNodeSet(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_compat_fm_obj_t) - #endif - #define FM_PCD_IOC_MANIP_NODE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_fm_obj_t) -@@ -2920,7 +2920,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_ManipNodeSet(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_MANIP_GET_STATS_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_compat_fm_pcd_manip_get_stats_t) - #endif - #define FM_PCD_IOC_MANIP_GET_STATS _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_fm_pcd_manip_get_stats_t) -@@ -2953,7 +2953,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_Init(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(46), ioc_compat_fm_pcd_frm_replic_group_params_t) - #endif - #define FM_PCD_IOC_FRM_REPLIC_GROUP_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(46), ioc_fm_pcd_frm_replic_group_params_t) -@@ -2969,7 +2969,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_FrmReplicSetGroup(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_compat_fm_obj_t) - #endif - #define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_fm_obj_t) -@@ -2987,7 +2987,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(48), ioc_compat_fm_pcd_frm_replic_member_params_t) - #endif - #define FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(48), ioc_fm_pcd_frm_replic_member_params_t) -@@ -3004,7 +3004,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(49), ioc_compat_fm_pcd_frm_replic_member_t) - #endif - #define FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(49), ioc_fm_pcd_frm_replic_member_t) -@@ -3021,7 +3021,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - - @Return 0 on success; Error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *) - #endif - #define FM_PCD_IOC_STATISTICS_SET_NODE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *) -@@ -3029,7 +3029,7 @@ typedef struct ioc_fm_pcd_cc_tbl_get_sta - #endif /* FM_CAPWAP_SUPPORT */ - - #ifdef NCSW_BACKWARD_COMPATIBLE_API --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS_COMPAT \ - FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT - #define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS_COMPAT \ ---- a/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h -+++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h -@@ -589,7 +589,7 @@ typedef struct ioc_fm_port_pcd_fqids_par - - @Return 0 on success; error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PORT_IOC_SET_PCD_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_compat_fm_port_pcd_params_t) - #endif - #define FM_PORT_IOC_SET_PCD _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_fm_port_pcd_params_t) -@@ -674,7 +674,7 @@ typedef struct ioc_fm_port_pcd_fqids_par - - @Return 0 on success; error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(26), ioc_compat_fm_pcd_kg_scheme_select_t) - #endif - #define FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(26), ioc_fm_pcd_kg_scheme_select_t) -@@ -691,7 +691,7 @@ typedef struct ioc_fm_port_pcd_fqids_par - - @Return 0 on success; error code otherwise. - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_compat_fm_obj_t) - #endif - #define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_fm_obj_t) -@@ -708,7 +708,7 @@ typedef struct ioc_fm_port_pcd_fqids_par - - @Cautions Allowed only following FM_PORT_SetPCD() and FM_PORT_DetachPCD() - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_compat_fm_obj_t) - #endif - #define FM_PORT_IOC_PCD_CC_MODIFY_TREE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_fm_obj_t) -@@ -726,7 +726,7 @@ typedef struct ioc_fm_port_pcd_fqids_par - - @Cautions Allowed only following FM_PORT_SetPCD(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(30), ioc_compat_fm_pcd_port_schemes_params_t) - #endif - #define FM_PORT_IOC_PCD_KG_BIND_SCHEMES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(30), ioc_fm_pcd_port_schemes_params_t) -@@ -744,7 +744,7 @@ typedef struct ioc_fm_port_pcd_fqids_par - - @Cautions Allowed only following FM_PORT_SetPCD(). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(31), ioc_compat_fm_pcd_port_schemes_params_t) - #endif - #define FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(31), ioc_fm_pcd_port_schemes_params_t) -@@ -917,7 +917,7 @@ typedef struct ioc_fm_port_vsp_alloc_par - @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD() - and also before FM_PORT_Enable() (i.e. the port should be disabled). - *//***************************************************************************/ --#if defined(CONFIG_COMPAT) -+#if defined(FM_COMPAT) - #define FM_PORT_IOC_VSP_ALLOC_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_compat_fm_port_vsp_alloc_params_t) - #endif - #define FM_PORT_IOC_VSP_ALLOC _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_fm_port_vsp_alloc_params_t) ---- a/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h -+++ b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h -@@ -90,7 +90,7 @@ typedef struct ioc_fmt_buff_context_t { - uint8_t fm_time_stamp[FM_TIME_STAMP_MAX]; - } ioc_fmt_buff_context_t; - --#if defined(__KERNEL__) && defined(CONFIG_COMPAT) -+#if defined(__KERNEL__) && defined(FM_COMPAT) - typedef struct ioc_fmt_compat_buff_context_t { - compat_uptr_t p_user_priv; - uint8_t fm_prs_res[FM_PRS_MAX]; -@@ -109,7 +109,7 @@ typedef struct ioc_fmt_buff_desc_t { - ioc_fmt_buff_context_t buff_context; - } ioc_fmt_buff_desc_t; - --#if defined(__KERNEL__) && defined(CONFIG_COMPAT) -+#if defined(__KERNEL__) && defined(FM_COMPAT) - typedef struct ioc_fmt_compat_buff_desc_t { - uint32_t qid; - compat_uptr_t p_data; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0001-Revert-ASoC-fsl_sai-Fix-noise-when-using-EDMA.patch b/target/linux/layerscape/patches-5.4/801-audio-0001-Revert-ASoC-fsl_sai-Fix-noise-when-using-EDMA.patch deleted file mode 100644 index 98c9214eaf..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0001-Revert-ASoC-fsl_sai-Fix-noise-when-using-EDMA.patch +++ /dev/null @@ -1,76 +0,0 @@ -From cf07127ea019b78f7ea5e009d494e2bd0bd475fa Mon Sep 17 00:00:00 2001 -From: Leonard Crestez -Date: Thu, 3 Oct 2019 20:44:56 +0300 -Subject: [PATCH] Revert "ASoC: fsl_sai: Fix noise when using EDMA" - -This reverts commit e75f4940e8ad0dd76527302a10c06b58bf7eb590. ---- - sound/soc/fsl/fsl_sai.c | 15 --------------- - sound/soc/fsl/fsl_sai.h | 1 - - 2 files changed, 16 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -628,16 +628,6 @@ static int fsl_sai_startup(struct snd_pc - FSL_SAI_CR3_TRCE_MASK, - FSL_SAI_CR3_TRCE); - -- /* -- * EDMA controller needs period size to be a multiple of -- * tx/rx maxburst -- */ -- if (sai->soc_data->use_edma) -- snd_pcm_hw_constraint_step(substream->runtime, 0, -- SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -- tx ? sai->dma_params_tx.maxburst : -- sai->dma_params_rx.maxburst); -- - ret = snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints); - -@@ -1052,35 +1042,30 @@ static int fsl_sai_remove(struct platfor - - static const struct fsl_sai_soc_data fsl_sai_vf610_data = { - .use_imx_pcm = false, -- .use_edma = false, - .fifo_depth = 32, - .reg_offset = 0, - }; - - static const struct fsl_sai_soc_data fsl_sai_imx6sx_data = { - .use_imx_pcm = true, -- .use_edma = false, - .fifo_depth = 32, - .reg_offset = 0, - }; - - static const struct fsl_sai_soc_data fsl_sai_imx7ulp_data = { - .use_imx_pcm = true, -- .use_edma = false, - .fifo_depth = 16, - .reg_offset = 8, - }; - - static const struct fsl_sai_soc_data fsl_sai_imx8mq_data = { - .use_imx_pcm = true, -- .use_edma = false, - .fifo_depth = 128, - .reg_offset = 8, - }; - - static const struct fsl_sai_soc_data fsl_sai_imx8qm_data = { - .use_imx_pcm = true, -- .use_edma = true, - .fifo_depth = 64, - .reg_offset = 0, - }; ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -157,7 +157,6 @@ - - struct fsl_sai_soc_data { - bool use_imx_pcm; -- bool use_edma; - unsigned int fifo_depth; - unsigned int reg_offset; - }; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0002-Revert-ASoC-fsl_sai-Implement-set_bclk_ratio.patch b/target/linux/layerscape/patches-5.4/801-audio-0002-Revert-ASoC-fsl_sai-Implement-set_bclk_ratio.patch deleted file mode 100644 index 60e3e3e853..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0002-Revert-ASoC-fsl_sai-Implement-set_bclk_ratio.patch +++ /dev/null @@ -1,65 +0,0 @@ -From aff2edb9c66a1188ed6554643e3cf76595c56846 Mon Sep 17 00:00:00 2001 -From: Leonard Crestez -Date: Thu, 3 Oct 2019 20:44:59 +0300 -Subject: [PATCH] Revert "ASoC: fsl_sai: Implement set_bclk_ratio" - -This reverts commit 63d1a3488ff58e094a7f517cf93c0250f0a3f6be. ---- - sound/soc/fsl/fsl_sai.c | 21 ++------------------- - sound/soc/fsl/fsl_sai.h | 1 - - 2 files changed, 2 insertions(+), 20 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -137,16 +137,6 @@ static int fsl_sai_set_dai_tdm_slot(stru - return 0; - } - --static int fsl_sai_set_dai_bclk_ratio(struct snd_soc_dai *dai, -- unsigned int ratio) --{ -- struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); -- -- sai->bclk_ratio = ratio; -- -- return 0; --} -- - static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int fsl_dir) - { -@@ -433,14 +423,8 @@ static int fsl_sai_hw_params(struct snd_ - slot_width = sai->slot_width; - - if (!sai->is_slave_mode) { -- if (sai->bclk_ratio) -- ret = fsl_sai_set_bclk(cpu_dai, tx, -- sai->bclk_ratio * -- params_rate(params)); -- else -- ret = fsl_sai_set_bclk(cpu_dai, tx, -- slots * slot_width * -- params_rate(params)); -+ ret = fsl_sai_set_bclk(cpu_dai, tx, -+ slots * slot_width * params_rate(params)); - if (ret) - return ret; - -@@ -646,7 +630,6 @@ static void fsl_sai_shutdown(struct snd_ - } - - static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { -- .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio, - .set_sysclk = fsl_sai_set_dai_sysclk, - .set_fmt = fsl_sai_set_dai_fmt, - .set_tdm_slot = fsl_sai_set_dai_tdm_slot, ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -176,7 +176,6 @@ struct fsl_sai { - unsigned int mclk_streams; - unsigned int slots; - unsigned int slot_width; -- unsigned int bclk_ratio; - - const struct fsl_sai_soc_data *soc_data; - struct snd_soc_dai_driver cpu_dai_drv; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0003-Revert-ASoC-fsl_sai-Add-support-for-imx8qm.patch b/target/linux/layerscape/patches-5.4/801-audio-0003-Revert-ASoC-fsl_sai-Add-support-for-imx8qm.patch deleted file mode 100644 index 1fe6c649dc..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0003-Revert-ASoC-fsl_sai-Add-support-for-imx8qm.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 841e80ea4dcfa52f6883ad5330aa7d2ab7d6229e Mon Sep 17 00:00:00 2001 -From: Leonard Crestez -Date: Thu, 3 Oct 2019 20:45:02 +0300 -Subject: [PATCH] Revert "ASoC: fsl_sai: Add support for imx8qm" - -This reverts commit 6eeb60be5ebb73b2e5911e26fb1aed02940b7d09. ---- - sound/soc/fsl/fsl_sai.c | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -1047,19 +1047,12 @@ static const struct fsl_sai_soc_data fsl - .reg_offset = 8, - }; - --static const struct fsl_sai_soc_data fsl_sai_imx8qm_data = { -- .use_imx_pcm = true, -- .fifo_depth = 64, -- .reg_offset = 0, --}; -- - static const struct of_device_id fsl_sai_ids[] = { - { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data }, - { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data }, - { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data }, - { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp_data }, - { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq_data }, -- { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm_data }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, fsl_sai_ids); diff --git a/target/linux/layerscape/patches-5.4/801-audio-0004-Revert-ASoC-fsl_sai-Add-support-for-imx7ulp-imx8mq.patch b/target/linux/layerscape/patches-5.4/801-audio-0004-Revert-ASoC-fsl_sai-Add-support-for-imx7ulp-imx8mq.patch deleted file mode 100644 index f08d8e0e38..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0004-Revert-ASoC-fsl_sai-Add-support-for-imx7ulp-imx8mq.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 6357cf1832f46d29f9756a34887af7fd96d48f18 Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Fri, 16 Aug 2019 18:01:12 +0800 -Subject: [PATCH] Revert "ASoC: fsl_sai: Add support for imx7ulp/imx8mq" - -This reverts commit a860fac420971c5a90d4f78959b44ead793aee4f. ---- - sound/soc/fsl/fsl_sai.c | 14 -------------- - 1 file changed, 14 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -1035,24 +1035,10 @@ static const struct fsl_sai_soc_data fsl - .reg_offset = 0, - }; - --static const struct fsl_sai_soc_data fsl_sai_imx7ulp_data = { -- .use_imx_pcm = true, -- .fifo_depth = 16, -- .reg_offset = 8, --}; -- --static const struct fsl_sai_soc_data fsl_sai_imx8mq_data = { -- .use_imx_pcm = true, -- .fifo_depth = 128, -- .reg_offset = 8, --}; -- - static const struct of_device_id fsl_sai_ids[] = { - { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data }, - { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data }, - { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data }, -- { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp_data }, -- { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq_data }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, fsl_sai_ids); diff --git a/target/linux/layerscape/patches-5.4/801-audio-0005-Revert-ASoC-fsl_sai-Add-support-for-SAI-new-version.patch b/target/linux/layerscape/patches-5.4/801-audio-0005-Revert-ASoC-fsl_sai-Add-support-for-SAI-new-version.patch deleted file mode 100644 index 86ea031740..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0005-Revert-ASoC-fsl_sai-Add-support-for-SAI-new-version.patch +++ /dev/null @@ -1,605 +0,0 @@ -From 2d6dfbd200d8de9bef8fb30bec90594acea9a145 Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Fri, 16 Aug 2019 18:01:26 +0800 -Subject: [PATCH] Revert "ASoC: fsl_sai: Add support for SAI new version" - -This reverts commit 4f7a0728b5305e2d865f543fbcffd617e03c7674. ---- - sound/soc/fsl/fsl_sai.c | 228 ++++++++++++++++++++---------------------------- - sound/soc/fsl/fsl_sai.h | 41 +++++---- - 2 files changed, 113 insertions(+), 156 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -40,7 +40,6 @@ static const struct snd_pcm_hw_constrain - static irqreturn_t fsl_sai_isr(int irq, void *devid) - { - struct fsl_sai *sai = (struct fsl_sai *)devid; -- unsigned int ofs = sai->soc_data->reg_offset; - struct device *dev = &sai->pdev->dev; - u32 flags, xcsr, mask; - bool irq_none = true; -@@ -53,7 +52,7 @@ static irqreturn_t fsl_sai_isr(int irq, - mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; - - /* Tx IRQ */ -- regmap_read(sai->regmap, FSL_SAI_TCSR(ofs), &xcsr); -+ regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr); - flags = xcsr & mask; - - if (flags) -@@ -83,11 +82,11 @@ static irqreturn_t fsl_sai_isr(int irq, - xcsr &= ~FSL_SAI_CSR_xF_MASK; - - if (flags) -- regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), flags | xcsr); -+ regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); - - irq_rx: - /* Rx IRQ */ -- regmap_read(sai->regmap, FSL_SAI_RCSR(ofs), &xcsr); -+ regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr); - flags = xcsr & mask; - - if (flags) -@@ -117,7 +116,7 @@ irq_rx: - xcsr &= ~FSL_SAI_CSR_xF_MASK; - - if (flags) -- regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), flags | xcsr); -+ regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr); - - out: - if (irq_none) -@@ -141,7 +140,6 @@ static int fsl_sai_set_dai_sysclk_tr(str - int clk_id, unsigned int freq, int fsl_dir) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -- unsigned int ofs = sai->soc_data->reg_offset; - bool tx = fsl_dir == FSL_FMT_TRANSMITTER; - u32 val_cr2 = 0; - -@@ -162,7 +160,7 @@ static int fsl_sai_set_dai_sysclk_tr(str - return -EINVAL; - } - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), - FSL_SAI_CR2_MSEL_MASK, val_cr2); - - return 0; -@@ -195,7 +193,6 @@ static int fsl_sai_set_dai_fmt_tr(struct - unsigned int fmt, int fsl_dir) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -- unsigned int ofs = sai->soc_data->reg_offset; - bool tx = fsl_dir == FSL_FMT_TRANSMITTER; - u32 val_cr2 = 0, val_cr4 = 0; - -@@ -290,9 +287,9 @@ static int fsl_sai_set_dai_fmt_tr(struct - return -EINVAL; - } - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), - FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2); -- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), - FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE | - FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4); - -@@ -319,7 +316,6 @@ static int fsl_sai_set_dai_fmt(struct sn - static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); -- unsigned int ofs = sai->soc_data->reg_offset; - unsigned long clk_rate; - u32 savediv = 0, ratio, savesub = freq; - u32 id; -@@ -382,17 +378,17 @@ static int fsl_sai_set_bclk(struct snd_s - */ - if ((sai->synchronous[TX] && !sai->synchronous[RX]) || - (!tx && !sai->synchronous[RX])) { -- regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR2, - FSL_SAI_CR2_MSEL_MASK, - FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); -- regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR2, - FSL_SAI_CR2_DIV_MASK, savediv - 1); - } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) || - (tx && !sai->synchronous[TX])) { -- regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR2, - FSL_SAI_CR2_MSEL_MASK, - FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); -- regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR2, - FSL_SAI_CR2_DIV_MASK, savediv - 1); - } - -@@ -407,7 +403,6 @@ static int fsl_sai_hw_params(struct snd_ - struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -- unsigned int ofs = sai->soc_data->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - unsigned int channels = params_channels(params); - u32 word_width = params_width(params); -@@ -460,19 +455,19 @@ static int fsl_sai_hw_params(struct snd_ - - if (!sai->is_slave_mode) { - if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { -- regmap_update_bits(sai->regmap, FSL_SAI_TCR4(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR4, - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, - val_cr4); -- regmap_update_bits(sai->regmap, FSL_SAI_TCR5(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR5, - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); - regmap_write(sai->regmap, FSL_SAI_TMR, - ~0UL - ((1 << channels) - 1)); - } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { -- regmap_update_bits(sai->regmap, FSL_SAI_RCR4(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR4, - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, - val_cr4); -- regmap_update_bits(sai->regmap, FSL_SAI_RCR5(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR5, - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); - regmap_write(sai->regmap, FSL_SAI_RMR, -@@ -480,10 +475,10 @@ static int fsl_sai_hw_params(struct snd_ - } - } - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, - val_cr4); -- regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx), - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); - regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1)); -@@ -511,8 +506,6 @@ static int fsl_sai_trigger(struct snd_pc - struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -- unsigned int ofs = sai->soc_data->reg_offset; -- - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - u32 xcsr, count = 100; - -@@ -521,9 +514,9 @@ static int fsl_sai_trigger(struct snd_pc - * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. - * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx. - */ -- regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), FSL_SAI_CR2_SYNC, -- sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); -- regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), FSL_SAI_CR2_SYNC, -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, -+ sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, - sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0); - - /* -@@ -534,44 +527,43 @@ static int fsl_sai_trigger(struct snd_pc - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), - FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); - -- regmap_update_bits(sai->regmap, FSL_SAI_RCSR(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_RCSR, - FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); -- regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_TCSR, - FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); - -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), - FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), - FSL_SAI_CSR_FRDE, 0); -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), - FSL_SAI_CSR_xIE_MASK, 0); - - /* Check if the opposite FRDE is also disabled */ -- regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, ofs), &xcsr); -+ regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr); - if (!(xcsr & FSL_SAI_CSR_FRDE)) { - /* Disable both directions and reset their FIFOs */ -- regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_TCSR, - FSL_SAI_CSR_TERE, 0); -- regmap_update_bits(sai->regmap, FSL_SAI_RCSR(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_RCSR, - FSL_SAI_CSR_TERE, 0); - - /* TERE will remain set till the end of current frame */ - do { - udelay(10); -- regmap_read(sai->regmap, -- FSL_SAI_xCSR(tx, ofs), &xcsr); -+ regmap_read(sai->regmap, FSL_SAI_xCSR(tx), &xcsr); - } while (--count && xcsr & FSL_SAI_CSR_TERE); - -- regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_TCSR, - FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); -- regmap_update_bits(sai->regmap, FSL_SAI_RCSR(ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_RCSR, - FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); - - /* -@@ -583,13 +575,13 @@ static int fsl_sai_trigger(struct snd_pc - */ - if (!sai->is_slave_mode) { - /* Software Reset for both Tx and Rx */ -- regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), -- FSL_SAI_CSR_SR); -- regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), -- FSL_SAI_CSR_SR); -+ regmap_write(sai->regmap, -+ FSL_SAI_TCSR, FSL_SAI_CSR_SR); -+ regmap_write(sai->regmap, -+ FSL_SAI_RCSR, FSL_SAI_CSR_SR); - /* Clear SR bit to finish the reset */ -- regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); -- regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); -+ regmap_write(sai->regmap, FSL_SAI_TCSR, 0); -+ regmap_write(sai->regmap, FSL_SAI_RCSR, 0); - } - } - break; -@@ -604,11 +596,10 @@ static int fsl_sai_startup(struct snd_pc - struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -- unsigned int ofs = sai->soc_data->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - int ret; - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), - FSL_SAI_CR3_TRCE_MASK, - FSL_SAI_CR3_TRCE); - -@@ -622,10 +613,9 @@ static void fsl_sai_shutdown(struct snd_ - struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -- unsigned int ofs = sai->soc_data->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), - FSL_SAI_CR3_TRCE_MASK, 0); - } - -@@ -643,20 +633,17 @@ static const struct snd_soc_dai_ops fsl_ - static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); -- unsigned int ofs = sai->soc_data->reg_offset; - - /* Software Reset for both Tx and Rx */ -- regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR); -- regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR); -+ regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); -+ regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); - /* Clear SR bit to finish the reset */ -- regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); -- regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); -+ regmap_write(sai->regmap, FSL_SAI_TCSR, 0); -+ regmap_write(sai->regmap, FSL_SAI_RCSR, 0); - -- regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs), -- FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth), -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, - sai->soc_data->fifo_depth - FSL_SAI_MAXBURST_TX); -- regmap_update_bits(sai->regmap, FSL_SAI_RCR1(ofs), -- FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth), -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, - FSL_SAI_MAXBURST_RX - 1); - - snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, -@@ -694,12 +681,12 @@ static const struct snd_soc_component_dr - .name = "fsl-sai", - }; - --static struct reg_default fsl_sai_reg_defaults_ofs0[] = { -- {FSL_SAI_TCR1(0), 0}, -- {FSL_SAI_TCR2(0), 0}, -- {FSL_SAI_TCR3(0), 0}, -- {FSL_SAI_TCR4(0), 0}, -- {FSL_SAI_TCR5(0), 0}, -+static struct reg_default fsl_sai_reg_defaults[] = { -+ {FSL_SAI_TCR1, 0}, -+ {FSL_SAI_TCR2, 0}, -+ {FSL_SAI_TCR3, 0}, -+ {FSL_SAI_TCR4, 0}, -+ {FSL_SAI_TCR5, 0}, - {FSL_SAI_TDR0, 0}, - {FSL_SAI_TDR1, 0}, - {FSL_SAI_TDR2, 0}, -@@ -708,50 +695,24 @@ static struct reg_default fsl_sai_reg_de - {FSL_SAI_TDR5, 0}, - {FSL_SAI_TDR6, 0}, - {FSL_SAI_TDR7, 0}, -- {FSL_SAI_TMR, 0}, -- {FSL_SAI_RCR1(0), 0}, -- {FSL_SAI_RCR2(0), 0}, -- {FSL_SAI_RCR3(0), 0}, -- {FSL_SAI_RCR4(0), 0}, -- {FSL_SAI_RCR5(0), 0}, -- {FSL_SAI_RMR, 0}, --}; -- --static struct reg_default fsl_sai_reg_defaults_ofs8[] = { -- {FSL_SAI_TCR1(8), 0}, -- {FSL_SAI_TCR2(8), 0}, -- {FSL_SAI_TCR3(8), 0}, -- {FSL_SAI_TCR4(8), 0}, -- {FSL_SAI_TCR5(8), 0}, -- {FSL_SAI_TDR0, 0}, -- {FSL_SAI_TDR1, 0}, -- {FSL_SAI_TDR2, 0}, -- {FSL_SAI_TDR3, 0}, -- {FSL_SAI_TDR4, 0}, -- {FSL_SAI_TDR5, 0}, -- {FSL_SAI_TDR6, 0}, -- {FSL_SAI_TDR7, 0}, -- {FSL_SAI_TMR, 0}, -- {FSL_SAI_RCR1(8), 0}, -- {FSL_SAI_RCR2(8), 0}, -- {FSL_SAI_RCR3(8), 0}, -- {FSL_SAI_RCR4(8), 0}, -- {FSL_SAI_RCR5(8), 0}, -- {FSL_SAI_RMR, 0}, -+ {FSL_SAI_TMR, 0}, -+ {FSL_SAI_RCR1, 0}, -+ {FSL_SAI_RCR2, 0}, -+ {FSL_SAI_RCR3, 0}, -+ {FSL_SAI_RCR4, 0}, -+ {FSL_SAI_RCR5, 0}, -+ {FSL_SAI_RMR, 0}, - }; - - static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) - { -- struct fsl_sai *sai = dev_get_drvdata(dev); -- unsigned int ofs = sai->soc_data->reg_offset; -- -- if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs)) -- return true; -- -- if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs)) -- return true; -- - switch (reg) { -+ case FSL_SAI_TCSR: -+ case FSL_SAI_TCR1: -+ case FSL_SAI_TCR2: -+ case FSL_SAI_TCR3: -+ case FSL_SAI_TCR4: -+ case FSL_SAI_TCR5: - case FSL_SAI_TFR0: - case FSL_SAI_TFR1: - case FSL_SAI_TFR2: -@@ -761,6 +722,12 @@ static bool fsl_sai_readable_reg(struct - case FSL_SAI_TFR6: - case FSL_SAI_TFR7: - case FSL_SAI_TMR: -+ case FSL_SAI_RCSR: -+ case FSL_SAI_RCR1: -+ case FSL_SAI_RCR2: -+ case FSL_SAI_RCR3: -+ case FSL_SAI_RCR4: -+ case FSL_SAI_RCR5: - case FSL_SAI_RDR0: - case FSL_SAI_RDR1: - case FSL_SAI_RDR2: -@@ -786,13 +753,9 @@ static bool fsl_sai_readable_reg(struct - - static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) - { -- struct fsl_sai *sai = dev_get_drvdata(dev); -- unsigned int ofs = sai->soc_data->reg_offset; -- -- if (reg == FSL_SAI_TCSR(ofs) || reg == FSL_SAI_RCSR(ofs)) -- return true; -- - switch (reg) { -+ case FSL_SAI_TCSR: -+ case FSL_SAI_RCSR: - case FSL_SAI_TFR0: - case FSL_SAI_TFR1: - case FSL_SAI_TFR2: -@@ -825,16 +788,13 @@ static bool fsl_sai_volatile_reg(struct - - static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg) - { -- struct fsl_sai *sai = dev_get_drvdata(dev); -- unsigned int ofs = sai->soc_data->reg_offset; -- -- if (reg >= FSL_SAI_TCSR(ofs) && reg <= FSL_SAI_TCR5(ofs)) -- return true; -- -- if (reg >= FSL_SAI_RCSR(ofs) && reg <= FSL_SAI_RCR5(ofs)) -- return true; -- - switch (reg) { -+ case FSL_SAI_TCSR: -+ case FSL_SAI_TCR1: -+ case FSL_SAI_TCR2: -+ case FSL_SAI_TCR3: -+ case FSL_SAI_TCR4: -+ case FSL_SAI_TCR5: - case FSL_SAI_TDR0: - case FSL_SAI_TDR1: - case FSL_SAI_TDR2: -@@ -844,6 +804,12 @@ static bool fsl_sai_writeable_reg(struct - case FSL_SAI_TDR6: - case FSL_SAI_TDR7: - case FSL_SAI_TMR: -+ case FSL_SAI_RCSR: -+ case FSL_SAI_RCR1: -+ case FSL_SAI_RCR2: -+ case FSL_SAI_RCR3: -+ case FSL_SAI_RCR4: -+ case FSL_SAI_RCR5: - case FSL_SAI_RMR: - return true; - default: -@@ -851,15 +817,15 @@ static bool fsl_sai_writeable_reg(struct - } - } - --static struct regmap_config fsl_sai_regmap_config = { -+static const struct regmap_config fsl_sai_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .fast_io = true, - - .max_register = FSL_SAI_RMR, -- .reg_defaults = fsl_sai_reg_defaults_ofs0, -- .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults_ofs0), -+ .reg_defaults = fsl_sai_reg_defaults, -+ .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults), - .readable_reg = fsl_sai_readable_reg, - .volatile_reg = fsl_sai_volatile_reg, - .writeable_reg = fsl_sai_writeable_reg, -@@ -891,12 +857,6 @@ static int fsl_sai_probe(struct platform - if (IS_ERR(base)) - return PTR_ERR(base); - -- if (sai->soc_data->reg_offset == 8) { -- fsl_sai_regmap_config.reg_defaults = fsl_sai_reg_defaults_ofs8; -- fsl_sai_regmap_config.num_reg_defaults = -- ARRAY_SIZE(fsl_sai_reg_defaults_ofs8); -- } -- - sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, - "bus", base, &fsl_sai_regmap_config); - -@@ -1026,13 +986,11 @@ static int fsl_sai_remove(struct platfor - static const struct fsl_sai_soc_data fsl_sai_vf610_data = { - .use_imx_pcm = false, - .fifo_depth = 32, -- .reg_offset = 0, - }; - - static const struct fsl_sai_soc_data fsl_sai_imx6sx_data = { - .use_imx_pcm = true, - .fifo_depth = 32, -- .reg_offset = 0, - }; - - static const struct of_device_id fsl_sai_ids[] = { -@@ -1065,7 +1023,6 @@ static int fsl_sai_runtime_suspend(struc - static int fsl_sai_runtime_resume(struct device *dev) - { - struct fsl_sai *sai = dev_get_drvdata(dev); -- unsigned int ofs = sai->soc_data->reg_offset; - int ret; - - ret = clk_prepare_enable(sai->bus_clk); -@@ -1087,11 +1044,11 @@ static int fsl_sai_runtime_resume(struct - } - - regcache_cache_only(sai->regmap, false); -- regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR); -- regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR); -+ regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); -+ regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); - usleep_range(1000, 2000); -- regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); -- regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); -+ regmap_write(sai->regmap, FSL_SAI_TCSR, 0); -+ regmap_write(sai->regmap, FSL_SAI_RCSR, 0); - - ret = regcache_sync(sai->regmap); - if (ret) ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -14,12 +14,12 @@ - SNDRV_PCM_FMTBIT_S32_LE) - - /* SAI Register Map Register */ --#define FSL_SAI_TCSR(ofs) (0x00 + ofs) /* SAI Transmit Control */ --#define FSL_SAI_TCR1(ofs) (0x04 + ofs) /* SAI Transmit Configuration 1 */ --#define FSL_SAI_TCR2(ofs) (0x08 + ofs) /* SAI Transmit Configuration 2 */ --#define FSL_SAI_TCR3(ofs) (0x0c + ofs) /* SAI Transmit Configuration 3 */ --#define FSL_SAI_TCR4(ofs) (0x10 + ofs) /* SAI Transmit Configuration 4 */ --#define FSL_SAI_TCR5(ofs) (0x14 + ofs) /* SAI Transmit Configuration 5 */ -+#define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */ -+#define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */ -+#define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */ -+#define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */ -+#define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */ -+#define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */ - #define FSL_SAI_TDR0 0x20 /* SAI Transmit Data 0 */ - #define FSL_SAI_TDR1 0x24 /* SAI Transmit Data 1 */ - #define FSL_SAI_TDR2 0x28 /* SAI Transmit Data 2 */ -@@ -37,12 +37,12 @@ - #define FSL_SAI_TFR6 0x58 /* SAI Transmit FIFO 6 */ - #define FSL_SAI_TFR7 0x5C /* SAI Transmit FIFO 7 */ - #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ --#define FSL_SAI_RCSR(ofs) (0x80 + ofs) /* SAI Receive Control */ --#define FSL_SAI_RCR1(ofs) (0x84 + ofs)/* SAI Receive Configuration 1 */ --#define FSL_SAI_RCR2(ofs) (0x88 + ofs) /* SAI Receive Configuration 2 */ --#define FSL_SAI_RCR3(ofs) (0x8c + ofs) /* SAI Receive Configuration 3 */ --#define FSL_SAI_RCR4(ofs) (0x90 + ofs) /* SAI Receive Configuration 4 */ --#define FSL_SAI_RCR5(ofs) (0x94 + ofs) /* SAI Receive Configuration 5 */ -+#define FSL_SAI_RCSR 0x80 /* SAI Receive Control */ -+#define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */ -+#define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */ -+#define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */ -+#define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */ -+#define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */ - #define FSL_SAI_RDR0 0xa0 /* SAI Receive Data 0 */ - #define FSL_SAI_RDR1 0xa4 /* SAI Receive Data 1 */ - #define FSL_SAI_RDR2 0xa8 /* SAI Receive Data 2 */ -@@ -61,14 +61,14 @@ - #define FSL_SAI_RFR7 0xdc /* SAI Receive FIFO 7 */ - #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ - --#define FSL_SAI_xCSR(tx, ofs) (tx ? FSL_SAI_TCSR(ofs) : FSL_SAI_RCSR(ofs)) --#define FSL_SAI_xCR1(tx, ofs) (tx ? FSL_SAI_TCR1(ofs) : FSL_SAI_RCR1(ofs)) --#define FSL_SAI_xCR2(tx, ofs) (tx ? FSL_SAI_TCR2(ofs) : FSL_SAI_RCR2(ofs)) --#define FSL_SAI_xCR3(tx, ofs) (tx ? FSL_SAI_TCR3(ofs) : FSL_SAI_RCR3(ofs)) --#define FSL_SAI_xCR4(tx, ofs) (tx ? FSL_SAI_TCR4(ofs) : FSL_SAI_RCR4(ofs)) --#define FSL_SAI_xCR5(tx, ofs) (tx ? FSL_SAI_TCR5(ofs) : FSL_SAI_RCR5(ofs)) --#define FSL_SAI_xDR(tx, ofs) (tx ? FSL_SAI_TDR(ofs) : FSL_SAI_RDR(ofs)) --#define FSL_SAI_xFR(tx, ofs) (tx ? FSL_SAI_TFR(ofs) : FSL_SAI_RFR(ofs)) -+#define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR) -+#define FSL_SAI_xCR1(tx) (tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1) -+#define FSL_SAI_xCR2(tx) (tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2) -+#define FSL_SAI_xCR3(tx) (tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3) -+#define FSL_SAI_xCR4(tx) (tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4) -+#define FSL_SAI_xCR5(tx) (tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5) -+#define FSL_SAI_xDR(tx) (tx ? FSL_SAI_TDR : FSL_SAI_RDR) -+#define FSL_SAI_xFR(tx) (tx ? FSL_SAI_TFR : FSL_SAI_RFR) - #define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR) - - /* SAI Transmit/Receive Control Register */ -@@ -158,7 +158,6 @@ - struct fsl_sai_soc_data { - bool use_imx_pcm; - unsigned int fifo_depth; -- unsigned int reg_offset; - }; - - struct fsl_sai { diff --git a/target/linux/layerscape/patches-5.4/801-audio-0006-Revert-ASoC-fsl_sai-Update-Tx-Rx-channel-enable-mask.patch b/target/linux/layerscape/patches-5.4/801-audio-0006-Revert-ASoC-fsl_sai-Update-Tx-Rx-channel-enable-mask.patch deleted file mode 100644 index e116389031..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0006-Revert-ASoC-fsl_sai-Update-Tx-Rx-channel-enable-mask.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 480565647b43c25ae86c635f88ae99f036f4e63a Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Fri, 16 Aug 2019 18:01:33 +0800 -Subject: [PATCH] Revert "ASoC: fsl_sai: Update Tx/Rx channel enable mask" - -This reverts commit b84f50b0fcb497a62068926fca793d2d213c7dbd. ---- - sound/soc/fsl/fsl_sai.c | 6 ++---- - sound/soc/fsl/fsl_sai.h | 1 - - 2 files changed, 2 insertions(+), 5 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -599,8 +599,7 @@ static int fsl_sai_startup(struct snd_pc - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - int ret; - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), -- FSL_SAI_CR3_TRCE_MASK, -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, - FSL_SAI_CR3_TRCE); - - ret = snd_pcm_hw_constraint_list(substream->runtime, 0, -@@ -615,8 +614,7 @@ static void fsl_sai_shutdown(struct snd_ - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), -- FSL_SAI_CR3_TRCE_MASK, 0); -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); - } - - static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -110,7 +110,6 @@ - - /* SAI Transmit and Receive Configuration 3 Register */ - #define FSL_SAI_CR3_TRCE BIT(16) --#define FSL_SAI_CR3_TRCE_MASK GENMASK(23, 16) - #define FSL_SAI_CR3_WDFL(x) (x) - #define FSL_SAI_CR3_WDFL_MASK 0x1f - diff --git a/target/linux/layerscape/patches-5.4/801-audio-0007-Revert-ASoC-fsl_sai-Add-registers-definition-for-mul.patch b/target/linux/layerscape/patches-5.4/801-audio-0007-Revert-ASoC-fsl_sai-Add-registers-definition-for-mul.patch deleted file mode 100644 index d73a4269d6..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0007-Revert-ASoC-fsl_sai-Add-registers-definition-for-mul.patch +++ /dev/null @@ -1,184 +0,0 @@ -From 56d254c9b7abf3e5632dd1b257927e23b4449019 Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Fri, 16 Aug 2019 18:01:43 +0800 -Subject: [PATCH] Revert "ASoC: fsl_sai: Add registers definition for multiple - datalines" - -This reverts commit 5f0ac20ed6db1d6da2eea8b862cf3d54fdfb5830. ---- - sound/soc/fsl/fsl_sai.c | 76 +++++++------------------------------------------ - sound/soc/fsl/fsl_sai.h | 36 +++-------------------- - 2 files changed, 14 insertions(+), 98 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -685,14 +685,7 @@ static struct reg_default fsl_sai_reg_de - {FSL_SAI_TCR3, 0}, - {FSL_SAI_TCR4, 0}, - {FSL_SAI_TCR5, 0}, -- {FSL_SAI_TDR0, 0}, -- {FSL_SAI_TDR1, 0}, -- {FSL_SAI_TDR2, 0}, -- {FSL_SAI_TDR3, 0}, -- {FSL_SAI_TDR4, 0}, -- {FSL_SAI_TDR5, 0}, -- {FSL_SAI_TDR6, 0}, -- {FSL_SAI_TDR7, 0}, -+ {FSL_SAI_TDR, 0}, - {FSL_SAI_TMR, 0}, - {FSL_SAI_RCR1, 0}, - {FSL_SAI_RCR2, 0}, -@@ -711,14 +704,7 @@ static bool fsl_sai_readable_reg(struct - case FSL_SAI_TCR3: - case FSL_SAI_TCR4: - case FSL_SAI_TCR5: -- case FSL_SAI_TFR0: -- case FSL_SAI_TFR1: -- case FSL_SAI_TFR2: -- case FSL_SAI_TFR3: -- case FSL_SAI_TFR4: -- case FSL_SAI_TFR5: -- case FSL_SAI_TFR6: -- case FSL_SAI_TFR7: -+ case FSL_SAI_TFR: - case FSL_SAI_TMR: - case FSL_SAI_RCSR: - case FSL_SAI_RCR1: -@@ -726,22 +712,8 @@ static bool fsl_sai_readable_reg(struct - case FSL_SAI_RCR3: - case FSL_SAI_RCR4: - case FSL_SAI_RCR5: -- case FSL_SAI_RDR0: -- case FSL_SAI_RDR1: -- case FSL_SAI_RDR2: -- case FSL_SAI_RDR3: -- case FSL_SAI_RDR4: -- case FSL_SAI_RDR5: -- case FSL_SAI_RDR6: -- case FSL_SAI_RDR7: -- case FSL_SAI_RFR0: -- case FSL_SAI_RFR1: -- case FSL_SAI_RFR2: -- case FSL_SAI_RFR3: -- case FSL_SAI_RFR4: -- case FSL_SAI_RFR5: -- case FSL_SAI_RFR6: -- case FSL_SAI_RFR7: -+ case FSL_SAI_RDR: -+ case FSL_SAI_RFR: - case FSL_SAI_RMR: - return true; - default: -@@ -754,30 +726,9 @@ static bool fsl_sai_volatile_reg(struct - switch (reg) { - case FSL_SAI_TCSR: - case FSL_SAI_RCSR: -- case FSL_SAI_TFR0: -- case FSL_SAI_TFR1: -- case FSL_SAI_TFR2: -- case FSL_SAI_TFR3: -- case FSL_SAI_TFR4: -- case FSL_SAI_TFR5: -- case FSL_SAI_TFR6: -- case FSL_SAI_TFR7: -- case FSL_SAI_RFR0: -- case FSL_SAI_RFR1: -- case FSL_SAI_RFR2: -- case FSL_SAI_RFR3: -- case FSL_SAI_RFR4: -- case FSL_SAI_RFR5: -- case FSL_SAI_RFR6: -- case FSL_SAI_RFR7: -- case FSL_SAI_RDR0: -- case FSL_SAI_RDR1: -- case FSL_SAI_RDR2: -- case FSL_SAI_RDR3: -- case FSL_SAI_RDR4: -- case FSL_SAI_RDR5: -- case FSL_SAI_RDR6: -- case FSL_SAI_RDR7: -+ case FSL_SAI_TFR: -+ case FSL_SAI_RFR: -+ case FSL_SAI_RDR: - return true; - default: - return false; -@@ -793,14 +744,7 @@ static bool fsl_sai_writeable_reg(struct - case FSL_SAI_TCR3: - case FSL_SAI_TCR4: - case FSL_SAI_TCR5: -- case FSL_SAI_TDR0: -- case FSL_SAI_TDR1: -- case FSL_SAI_TDR2: -- case FSL_SAI_TDR3: -- case FSL_SAI_TDR4: -- case FSL_SAI_TDR5: -- case FSL_SAI_TDR6: -- case FSL_SAI_TDR7: -+ case FSL_SAI_TDR: - case FSL_SAI_TMR: - case FSL_SAI_RCSR: - case FSL_SAI_RCR1: -@@ -942,8 +886,8 @@ static int fsl_sai_probe(struct platform - MCLK_DIR(index)); - } - -- sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0; -- sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0; -+ sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; -+ sai->dma_params_tx.addr = res->start + FSL_SAI_TDR; - sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; - sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; - ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -20,22 +20,8 @@ - #define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */ - #define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */ - #define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */ --#define FSL_SAI_TDR0 0x20 /* SAI Transmit Data 0 */ --#define FSL_SAI_TDR1 0x24 /* SAI Transmit Data 1 */ --#define FSL_SAI_TDR2 0x28 /* SAI Transmit Data 2 */ --#define FSL_SAI_TDR3 0x2C /* SAI Transmit Data 3 */ --#define FSL_SAI_TDR4 0x30 /* SAI Transmit Data 4 */ --#define FSL_SAI_TDR5 0x34 /* SAI Transmit Data 5 */ --#define FSL_SAI_TDR6 0x38 /* SAI Transmit Data 6 */ --#define FSL_SAI_TDR7 0x3C /* SAI Transmit Data 7 */ --#define FSL_SAI_TFR0 0x40 /* SAI Transmit FIFO 0 */ --#define FSL_SAI_TFR1 0x44 /* SAI Transmit FIFO 1 */ --#define FSL_SAI_TFR2 0x48 /* SAI Transmit FIFO 2 */ --#define FSL_SAI_TFR3 0x4C /* SAI Transmit FIFO 3 */ --#define FSL_SAI_TFR4 0x50 /* SAI Transmit FIFO 4 */ --#define FSL_SAI_TFR5 0x54 /* SAI Transmit FIFO 5 */ --#define FSL_SAI_TFR6 0x58 /* SAI Transmit FIFO 6 */ --#define FSL_SAI_TFR7 0x5C /* SAI Transmit FIFO 7 */ -+#define FSL_SAI_TDR 0x20 /* SAI Transmit Data */ -+#define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */ - #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ - #define FSL_SAI_RCSR 0x80 /* SAI Receive Control */ - #define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */ -@@ -43,22 +29,8 @@ - #define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */ - #define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */ - #define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */ --#define FSL_SAI_RDR0 0xa0 /* SAI Receive Data 0 */ --#define FSL_SAI_RDR1 0xa4 /* SAI Receive Data 1 */ --#define FSL_SAI_RDR2 0xa8 /* SAI Receive Data 2 */ --#define FSL_SAI_RDR3 0xac /* SAI Receive Data 3 */ --#define FSL_SAI_RDR4 0xb0 /* SAI Receive Data 4 */ --#define FSL_SAI_RDR5 0xb4 /* SAI Receive Data 5 */ --#define FSL_SAI_RDR6 0xb8 /* SAI Receive Data 6 */ --#define FSL_SAI_RDR7 0xbc /* SAI Receive Data 7 */ --#define FSL_SAI_RFR0 0xc0 /* SAI Receive FIFO 0 */ --#define FSL_SAI_RFR1 0xc4 /* SAI Receive FIFO 1 */ --#define FSL_SAI_RFR2 0xc8 /* SAI Receive FIFO 2 */ --#define FSL_SAI_RFR3 0xcc /* SAI Receive FIFO 3 */ --#define FSL_SAI_RFR4 0xd0 /* SAI Receive FIFO 4 */ --#define FSL_SAI_RFR5 0xd4 /* SAI Receive FIFO 5 */ --#define FSL_SAI_RFR6 0xd8 /* SAI Receive FIFO 6 */ --#define FSL_SAI_RFR7 0xdc /* SAI Receive FIFO 7 */ -+#define FSL_SAI_RDR 0xa0 /* SAI Receive Data */ -+#define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ - #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ - - #define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR) diff --git a/target/linux/layerscape/patches-5.4/801-audio-0008-Revert-ASoC-Remove-dev_err-usage-after-platform_get_.patch b/target/linux/layerscape/patches-5.4/801-audio-0008-Revert-ASoC-Remove-dev_err-usage-after-platform_get_.patch deleted file mode 100644 index 9e020c3c61..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0008-Revert-ASoC-Remove-dev_err-usage-after-platform_get_.patch +++ /dev/null @@ -1,467 +0,0 @@ -From b3aa9fe657c5e96659d64e6b008e025b433616ad Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Fri, 16 Aug 2019 18:01:53 +0800 -Subject: [PATCH] Revert "ASoC: Remove dev_err() usage after - platform_get_irq()" - -This reverts commit cf9441adb1a35506d7606866c382b9d8614169b5. ---- - sound/soc/atmel/atmel-classd.c | 7 +++++-- - sound/soc/atmel/atmel-pdmic.c | 7 +++++-- - sound/soc/bcm/cygnus-ssp.c | 7 +++++-- - sound/soc/codecs/msm8916-wcd-analog.c | 12 +++++++++--- - sound/soc/codecs/twl6040.c | 4 +++- - sound/soc/fsl/fsl_asrc.c | 4 +++- - sound/soc/fsl/fsl_esai.c | 4 +++- - sound/soc/fsl/fsl_sai.c | 4 +++- - sound/soc/fsl/fsl_spdif.c | 4 +++- - sound/soc/fsl/fsl_ssi.c | 4 +++- - sound/soc/fsl/imx-ssi.c | 4 +++- - sound/soc/kirkwood/kirkwood-i2s.c | 4 +++- - sound/soc/mediatek/common/mtk-btcvsd.c | 4 +++- - sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 4 +++- - sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | 4 +++- - sound/soc/mxs/mxs-saif.c | 8 ++++++-- - sound/soc/qcom/lpass-platform.c | 5 ++++- - sound/soc/sof/intel/bdw.c | 5 ++++- - sound/soc/sof/intel/byt.c | 5 ++++- - sound/soc/sprd/sprd-mcdt.c | 4 +++- - sound/soc/sti/sti_uniperif.c | 4 +++- - sound/soc/stm/stm32_i2s.c | 5 ++++- - sound/soc/stm/stm32_sai.c | 4 +++- - sound/soc/stm/stm32_spdifrx.c | 4 +++- - sound/soc/sunxi/sun4i-i2s.c | 4 +++- - sound/soc/uniphier/aio-dma.c | 4 +++- - sound/soc/xilinx/xlnx_formatter_pcm.c | 2 ++ - sound/soc/xtensa/xtfpga-i2s.c | 1 + - 28 files changed, 100 insertions(+), 32 deletions(-) - ---- a/sound/soc/atmel/atmel-classd.c -+++ b/sound/soc/atmel/atmel-classd.c -@@ -571,8 +571,11 @@ static int atmel_classd_probe(struct pla - dd->pdata = pdata; - - dd->irq = platform_get_irq(pdev, 0); -- if (dd->irq < 0) -- return dd->irq; -+ if (dd->irq < 0) { -+ ret = dd->irq; -+ dev_err(dev, "failed to could not get irq: %d\n", ret); -+ return ret; -+ } - - dd->pclk = devm_clk_get(dev, "pclk"); - if (IS_ERR(dd->pclk)) { ---- a/sound/soc/atmel/atmel-pdmic.c -+++ b/sound/soc/atmel/atmel-pdmic.c -@@ -612,8 +612,11 @@ static int atmel_pdmic_probe(struct plat - dd->dev = dev; - - dd->irq = platform_get_irq(pdev, 0); -- if (dd->irq < 0) -- return dd->irq; -+ if (dd->irq < 0) { -+ ret = dd->irq; -+ dev_err(dev, "failed to get irq: %d\n", ret); -+ return ret; -+ } - - dd->pclk = devm_clk_get(dev, "pclk"); - if (IS_ERR(dd->pclk)) { ---- a/sound/soc/bcm/cygnus-ssp.c -+++ b/sound/soc/bcm/cygnus-ssp.c -@@ -1342,8 +1342,11 @@ static int cygnus_ssp_probe(struct platf - } - - cygaud->irq_num = platform_get_irq(pdev, 0); -- if (cygaud->irq_num <= 0) -- return cygaud->irq_num; -+ if (cygaud->irq_num <= 0) { -+ dev_err(dev, "platform_get_irq failed\n"); -+ err = cygaud->irq_num; -+ return err; -+ } - - err = audio_clk_init(pdev, cygaud); - if (err) { ---- a/sound/soc/codecs/msm8916-wcd-analog.c -+++ b/sound/soc/codecs/msm8916-wcd-analog.c -@@ -1195,8 +1195,10 @@ static int pm8916_wcd_analog_spmi_probe( - } - - irq = platform_get_irq_byname(pdev, "mbhc_switch_int"); -- if (irq < 0) -+ if (irq < 0) { -+ dev_err(dev, "failed to get mbhc switch irq\n"); - return irq; -+ } - - ret = devm_request_threaded_irq(dev, irq, NULL, - pm8916_mbhc_switch_irq_handler, -@@ -1208,8 +1210,10 @@ static int pm8916_wcd_analog_spmi_probe( - - if (priv->mbhc_btn_enabled) { - irq = platform_get_irq_byname(pdev, "mbhc_but_press_det"); -- if (irq < 0) -+ if (irq < 0) { -+ dev_err(dev, "failed to get button press irq\n"); - return irq; -+ } - - ret = devm_request_threaded_irq(dev, irq, NULL, - mbhc_btn_press_irq_handler, -@@ -1220,8 +1224,10 @@ static int pm8916_wcd_analog_spmi_probe( - dev_err(dev, "cannot request mbhc button press irq\n"); - - irq = platform_get_irq_byname(pdev, "mbhc_but_rel_det"); -- if (irq < 0) -+ if (irq < 0) { -+ dev_err(dev, "failed to get button release irq\n"); - return irq; -+ } - - ret = devm_request_threaded_irq(dev, irq, NULL, - mbhc_btn_release_irq_handler, ---- a/sound/soc/codecs/twl6040.c -+++ b/sound/soc/codecs/twl6040.c -@@ -1108,8 +1108,10 @@ static int twl6040_probe(struct snd_soc_ - priv->component = component; - - priv->plug_irq = platform_get_irq(pdev, 0); -- if (priv->plug_irq < 0) -+ if (priv->plug_irq < 0) { -+ dev_err(component->dev, "invalid irq: %d\n", priv->plug_irq); - return priv->plug_irq; -+ } - - INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); - ---- a/sound/soc/fsl/fsl_asrc.c -+++ b/sound/soc/fsl/fsl_asrc.c -@@ -885,8 +885,10 @@ static int fsl_asrc_probe(struct platfor - } - - irq = platform_get_irq(pdev, 0); -- if (irq < 0) -+ if (irq < 0) { -+ dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); - return irq; -+ } - - ret = devm_request_irq(&pdev->dev, irq, fsl_asrc_isr, 0, - dev_name(&pdev->dev), asrc_priv); ---- a/sound/soc/fsl/fsl_esai.c -+++ b/sound/soc/fsl/fsl_esai.c -@@ -979,8 +979,10 @@ static int fsl_esai_probe(struct platfor - PTR_ERR(esai_priv->spbaclk)); - - irq = platform_get_irq(pdev, 0); -- if (irq < 0) -+ if (irq < 0) { -+ dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); - return irq; -+ } - - ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0, - esai_priv->name, esai_priv); ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -831,8 +831,10 @@ static int fsl_sai_probe(struct platform - } - - irq = platform_get_irq(pdev, 0); -- if (irq < 0) -+ if (irq < 0) { -+ dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); - return irq; -+ } - - ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai); - if (ret) { ---- a/sound/soc/fsl/fsl_spdif.c -+++ b/sound/soc/fsl/fsl_spdif.c -@@ -1248,8 +1248,10 @@ static int fsl_spdif_probe(struct platfo - } - - irq = platform_get_irq(pdev, 0); -- if (irq < 0) -+ if (irq < 0) { -+ dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); - return irq; -+ } - - ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0, - dev_name(&pdev->dev), spdif_priv); ---- a/sound/soc/fsl/fsl_ssi.c -+++ b/sound/soc/fsl/fsl_ssi.c -@@ -1517,8 +1517,10 @@ static int fsl_ssi_probe(struct platform - } - - ssi->irq = platform_get_irq(pdev, 0); -- if (ssi->irq < 0) -+ if (ssi->irq < 0) { -+ dev_err(dev, "no irq for node %s\n", pdev->name); - return ssi->irq; -+ } - - /* Set software limitations for synchronous mode except AC97 */ - if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) { ---- a/sound/soc/fsl/imx-ssi.c -+++ b/sound/soc/fsl/imx-ssi.c -@@ -520,8 +520,10 @@ static int imx_ssi_probe(struct platform - } - - ssi->irq = platform_get_irq(pdev, 0); -- if (ssi->irq < 0) -+ if (ssi->irq < 0) { -+ dev_err(&pdev->dev, "Failed to get IRQ: %d\n", ssi->irq); - return ssi->irq; -+ } - - ssi->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(ssi->clk)) { ---- a/sound/soc/kirkwood/kirkwood-i2s.c -+++ b/sound/soc/kirkwood/kirkwood-i2s.c -@@ -537,8 +537,10 @@ static int kirkwood_i2s_dev_probe(struct - return PTR_ERR(priv->io); - - priv->irq = platform_get_irq(pdev, 0); -- if (priv->irq < 0) -+ if (priv->irq < 0) { -+ dev_err(&pdev->dev, "platform_get_irq failed: %d\n", priv->irq); - return priv->irq; -+ } - - if (np) { - priv->burst = 128; /* might be 32 or 128 */ ---- a/sound/soc/mediatek/common/mtk-btcvsd.c -+++ b/sound/soc/mediatek/common/mtk-btcvsd.c -@@ -1335,8 +1335,10 @@ static int mtk_btcvsd_snd_probe(struct p - - /* irq */ - irq_id = platform_get_irq(pdev, 0); -- if (irq_id <= 0) -+ if (irq_id <= 0) { -+ dev_err(dev, "%pOFn no irq found\n", dev->of_node); - return irq_id < 0 ? irq_id : -ENXIO; -+ } - - ret = devm_request_irq(dev, irq_id, mtk_btcvsd_snd_irq_handler, - IRQF_TRIGGER_LOW, "BTCVSD_ISR_Handle", ---- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c -+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c -@@ -1350,8 +1350,10 @@ static int mt2701_afe_pcm_dev_probe(stru - return -ENOMEM; - - irq_id = platform_get_irq_byname(pdev, "asys"); -- if (irq_id < 0) -+ if (irq_id < 0) { -+ dev_err(dev, "unable to get ASYS IRQ\n"); - return irq_id; -+ } - - ret = devm_request_irq(dev, irq_id, mt2701_asys_isr, - IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); ---- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c -+++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c -@@ -1074,8 +1074,10 @@ static int mt8173_afe_pcm_dev_probe(stru - afe->dev = &pdev->dev; - - irq_id = platform_get_irq(pdev, 0); -- if (irq_id <= 0) -+ if (irq_id <= 0) { -+ dev_err(afe->dev, "np %pOFn no irq\n", afe->dev->of_node); - return irq_id < 0 ? irq_id : -ENXIO; -+ } - ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler, - 0, "Afe_ISR_Handle", (void *)afe); - if (ret) { ---- a/sound/soc/mxs/mxs-saif.c -+++ b/sound/soc/mxs/mxs-saif.c -@@ -790,8 +790,12 @@ static int mxs_saif_probe(struct platfor - return PTR_ERR(saif->base); - - irq = platform_get_irq(pdev, 0); -- if (irq < 0) -- return irq; -+ if (irq < 0) { -+ ret = irq; -+ dev_err(&pdev->dev, "failed to get irq resource: %d\n", -+ ret); -+ return ret; -+ } - - saif->dev = &pdev->dev; - ret = devm_request_irq(&pdev->dev, irq, mxs_saif_irq, 0, ---- a/sound/soc/qcom/lpass-platform.c -+++ b/sound/soc/qcom/lpass-platform.c -@@ -568,8 +568,11 @@ int asoc_qcom_lpass_platform_register(st - int ret; - - drvdata->lpaif_irq = platform_get_irq_byname(pdev, "lpass-irq-lpaif"); -- if (drvdata->lpaif_irq < 0) -+ if (drvdata->lpaif_irq < 0) { -+ dev_err(&pdev->dev, "error getting irq handle: %d\n", -+ drvdata->lpaif_irq); - return -ENODEV; -+ } - - /* ensure audio hardware is disabled */ - ret = regmap_write(drvdata->lpaif_map, ---- a/sound/soc/sof/intel/bdw.c -+++ b/sound/soc/sof/intel/bdw.c -@@ -483,8 +483,11 @@ static int bdw_probe(struct snd_sof_dev - - /* register our IRQ */ - sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc); -- if (sdev->ipc_irq < 0) -+ if (sdev->ipc_irq < 0) { -+ dev_err(sdev->dev, "error: failed to get IRQ at index %d\n", -+ desc->irqindex_host_ipc); - return sdev->ipc_irq; -+ } - - dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); - ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, ---- a/sound/soc/sof/intel/byt.c -+++ b/sound/soc/sof/intel/byt.c -@@ -600,8 +600,11 @@ static int byt_acpi_probe(struct snd_sof - irq: - /* register our IRQ */ - sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc); -- if (sdev->ipc_irq < 0) -+ if (sdev->ipc_irq < 0) { -+ dev_err(sdev->dev, "error: failed to get IRQ at index %d\n", -+ desc->irqindex_host_ipc); - return sdev->ipc_irq; -+ } - - dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); - ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, ---- a/sound/soc/sprd/sprd-mcdt.c -+++ b/sound/soc/sprd/sprd-mcdt.c -@@ -959,8 +959,10 @@ static int sprd_mcdt_probe(struct platfo - platform_set_drvdata(pdev, mcdt); - - irq = platform_get_irq(pdev, 0); -- if (irq < 0) -+ if (irq < 0) { -+ dev_err(&pdev->dev, "Failed to get MCDT interrupt\n"); - return irq; -+ } - - ret = devm_request_irq(&pdev->dev, irq, sprd_mcdt_irq_handler, - 0, "sprd-mcdt", mcdt); ---- a/sound/soc/sti/sti_uniperif.c -+++ b/sound/soc/sti/sti_uniperif.c -@@ -426,8 +426,10 @@ static int sti_uniperiph_cpu_dai_of(stru - UNIPERIF_FIFO_DATA_OFFSET(uni); - - uni->irq = platform_get_irq(priv->pdev, 0); -- if (uni->irq < 0) -+ if (uni->irq < 0) { -+ dev_err(dev, "Failed to get IRQ resource\n"); - return -ENXIO; -+ } - - uni->type = dev_data->type; - ---- a/sound/soc/stm/stm32_i2s.c -+++ b/sound/soc/stm/stm32_i2s.c -@@ -855,8 +855,11 @@ static int stm32_i2s_parse_dt(struct pla - - /* Get irqs */ - irq = platform_get_irq(pdev, 0); -- if (irq < 0) -+ if (irq < 0) { -+ if (irq != -EPROBE_DEFER) -+ dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); - return irq; -+ } - - ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, IRQF_ONESHOT, - dev_name(&pdev->dev), i2s); ---- a/sound/soc/stm/stm32_sai.c -+++ b/sound/soc/stm/stm32_sai.c -@@ -193,8 +193,10 @@ static int stm32_sai_probe(struct platfo - - /* init irqs */ - sai->irq = platform_get_irq(pdev, 0); -- if (sai->irq < 0) -+ if (sai->irq < 0) { -+ dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); - return sai->irq; -+ } - - /* reset */ - rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); ---- a/sound/soc/stm/stm32_spdifrx.c -+++ b/sound/soc/stm/stm32_spdifrx.c -@@ -920,8 +920,10 @@ static int stm32_spdifrx_parse_of(struct - } - - spdifrx->irq = platform_get_irq(pdev, 0); -- if (spdifrx->irq < 0) -+ if (spdifrx->irq < 0) { -+ dev_err(&pdev->dev, "No irq for node %s\n", pdev->name); - return spdifrx->irq; -+ } - - return 0; - } ---- a/sound/soc/sunxi/sun4i-i2s.c -+++ b/sound/soc/sunxi/sun4i-i2s.c -@@ -1198,8 +1198,10 @@ static int sun4i_i2s_probe(struct platfo - return PTR_ERR(regs); - - irq = platform_get_irq(pdev, 0); -- if (irq < 0) -+ if (irq < 0) { -+ dev_err(&pdev->dev, "Can't retrieve our interrupt\n"); - return irq; -+ } - - i2s->variant = of_device_get_match_data(&pdev->dev); - if (!i2s->variant) { ---- a/sound/soc/uniphier/aio-dma.c -+++ b/sound/soc/uniphier/aio-dma.c -@@ -289,8 +289,10 @@ int uniphier_aiodma_soc_register_platfor - return PTR_ERR(chip->regmap); - - irq = platform_get_irq(pdev, 0); -- if (irq < 0) -+ if (irq < 0) { -+ dev_err(dev, "Could not get irq.\n"); - return irq; -+ } - - ret = devm_request_irq(dev, irq, aiodma_irq, - IRQF_SHARED, dev_name(dev), pdev); ---- a/sound/soc/xilinx/xlnx_formatter_pcm.c -+++ b/sound/soc/xilinx/xlnx_formatter_pcm.c -@@ -613,6 +613,7 @@ static int xlnx_formatter_pcm_probe(stru - aud_drv_data->mm2s_irq = platform_get_irq_byname(pdev, - "irq_mm2s"); - if (aud_drv_data->mm2s_irq < 0) { -+ dev_err(dev, "xlnx audio mm2s irq resource failed\n"); - ret = aud_drv_data->mm2s_irq; - goto clk_err; - } -@@ -639,6 +640,7 @@ static int xlnx_formatter_pcm_probe(stru - aud_drv_data->s2mm_irq = platform_get_irq_byname(pdev, - "irq_s2mm"); - if (aud_drv_data->s2mm_irq < 0) { -+ dev_err(dev, "xlnx audio s2mm irq resource failed\n"); - ret = aud_drv_data->s2mm_irq; - goto clk_err; - } ---- a/sound/soc/xtensa/xtfpga-i2s.c -+++ b/sound/soc/xtensa/xtfpga-i2s.c -@@ -570,6 +570,7 @@ static int xtfpga_i2s_probe(struct platf - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { -+ dev_err(&pdev->dev, "No IRQ resource\n"); - err = irq; - goto err; - } diff --git a/target/linux/layerscape/patches-5.4/801-audio-0009-Revert-ASoC-fsl_sai-mark-regmap-as-fast_io.patch b/target/linux/layerscape/patches-5.4/801-audio-0009-Revert-ASoC-fsl_sai-mark-regmap-as-fast_io.patch deleted file mode 100644 index 454bfd5a18..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0009-Revert-ASoC-fsl_sai-mark-regmap-as-fast_io.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 6efe2223fa2de658d9017e2abd0ab4849430ef9c Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Wed, 31 Jul 2019 17:11:24 +0800 -Subject: [PATCH] Revert "ASoC: fsl_sai: mark regmap as fast_io" - -This reverts commit 6d19d8a3cec74a9680947ecb6abdeda38583110e. ---- - sound/soc/fsl/fsl_sai.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -763,7 +763,6 @@ static const struct regmap_config fsl_sa - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, -- .fast_io = true, - - .max_register = FSL_SAI_RMR, - .reg_defaults = fsl_sai_reg_defaults, diff --git a/target/linux/layerscape/patches-5.4/801-audio-0010-Revert-ASoC-fsl_sai-derive-TX-FIFO-watermark-from-FI.patch b/target/linux/layerscape/patches-5.4/801-audio-0010-Revert-ASoC-fsl_sai-derive-TX-FIFO-watermark-from-FI.patch deleted file mode 100644 index 07c3b87b04..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0010-Revert-ASoC-fsl_sai-derive-TX-FIFO-watermark-from-FI.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 33c1f03b9eca0c192708c9df295d2a30073cd121 Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Wed, 31 Jul 2019 17:11:32 +0800 -Subject: [PATCH] Revert "ASoC: fsl_sai: derive TX FIFO watermark from FIFO - depth" - -This reverts commit bd517707d85f19a7339ea8b882fcbf0fd9976bd6. ---- - sound/soc/fsl/fsl_sai.c | 4 +--- - sound/soc/fsl/fsl_sai.h | 1 - - 2 files changed, 1 insertion(+), 4 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -640,7 +640,7 @@ static int fsl_sai_dai_probe(struct snd_ - regmap_write(sai->regmap, FSL_SAI_RCSR, 0); - - regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, -- sai->soc_data->fifo_depth - FSL_SAI_MAXBURST_TX); -+ FSL_SAI_MAXBURST_TX * 2); - regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, - FSL_SAI_MAXBURST_RX - 1); - -@@ -928,12 +928,10 @@ static int fsl_sai_remove(struct platfor - - static const struct fsl_sai_soc_data fsl_sai_vf610_data = { - .use_imx_pcm = false, -- .fifo_depth = 32, - }; - - static const struct fsl_sai_soc_data fsl_sai_imx6sx_data = { - .use_imx_pcm = true, -- .fifo_depth = 32, - }; - - static const struct of_device_id fsl_sai_ids[] = { ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -128,7 +128,6 @@ - - struct fsl_sai_soc_data { - bool use_imx_pcm; -- unsigned int fifo_depth; - }; - - struct fsl_sai { diff --git a/target/linux/layerscape/patches-5.4/801-audio-0011-Revert-ASoC-fsl_sai-add-of_match-data.patch b/target/linux/layerscape/patches-5.4/801-audio-0011-Revert-ASoC-fsl_sai-add-of_match-data.patch deleted file mode 100644 index 12a32bc26b..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0011-Revert-ASoC-fsl_sai-add-of_match-data.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 6e0abca40338d5078be0e5947c7f9723b40bc7e7 Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Mon, 30 Mar 2020 16:17:52 +0800 -Subject: [PATCH] Revert "ASoC: fsl_sai: add of_match data" - -This reverts commit 89c9679f699d88986ce552738dc7c5c500c8fc67. - -[rebase] -Signed-off-by: Yangbo Lu ---- - sound/soc/fsl/fsl_sai.c | 22 ++++++++-------------- - sound/soc/fsl/fsl_sai.h | 6 +----- - 2 files changed, 9 insertions(+), 19 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -9,7 +9,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -789,7 +788,10 @@ static int fsl_sai_probe(struct platform - return -ENOMEM; - - sai->pdev = pdev; -- sai->soc_data = of_device_get_match_data(&pdev->dev); -+ -+ if (of_device_is_compatible(np, "fsl,imx6sx-sai") || -+ of_device_is_compatible(np, "fsl,imx6ul-sai")) -+ sai->sai_on_imx = true; - - sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); - -@@ -901,7 +903,7 @@ static int fsl_sai_probe(struct platform - if (ret) - goto err_pm_disable; - -- if (sai->soc_data->use_imx_pcm) { -+ if (sai->sai_on_imx) - ret = imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE); - if (ret) - goto err_pm_disable; -@@ -926,18 +928,10 @@ static int fsl_sai_remove(struct platfor - return 0; - } - --static const struct fsl_sai_soc_data fsl_sai_vf610_data = { -- .use_imx_pcm = false, --}; -- --static const struct fsl_sai_soc_data fsl_sai_imx6sx_data = { -- .use_imx_pcm = true, --}; -- - static const struct of_device_id fsl_sai_ids[] = { -- { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data }, -- { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data }, -- { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data }, -+ { .compatible = "fsl,vf610-sai", }, -+ { .compatible = "fsl,imx6sx-sai", }, -+ { .compatible = "fsl,imx6ul-sai", }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, fsl_sai_ids); ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -126,10 +126,6 @@ - #define FSL_SAI_MAXBURST_TX 6 - #define FSL_SAI_MAXBURST_RX 6 - --struct fsl_sai_soc_data { -- bool use_imx_pcm; --}; -- - struct fsl_sai { - struct platform_device *pdev; - struct regmap *regmap; -@@ -139,6 +135,7 @@ struct fsl_sai { - bool is_slave_mode; - bool is_lsb_first; - bool is_dsp_mode; -+ bool sai_on_imx; - bool synchronous[2]; - - unsigned int mclk_id[2]; -@@ -146,7 +143,6 @@ struct fsl_sai { - unsigned int slots; - unsigned int slot_width; - -- const struct fsl_sai_soc_data *soc_data; - struct snd_soc_dai_driver cpu_dai_drv; - struct snd_dmaengine_dai_dma_data dma_params_rx; - struct snd_dmaengine_dai_dma_data dma_params_tx; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0012-MLK-9974-ASoC-fsl_sai-There-is-underrun-detected-in-.patch b/target/linux/layerscape/patches-5.4/801-audio-0012-MLK-9974-ASoC-fsl_sai-There-is-underrun-detected-in-.patch deleted file mode 100644 index 3b7de3c98b..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0012-MLK-9974-ASoC-fsl_sai-There-is-underrun-detected-in-.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 2a7fa96feddb63d36d64336a994dc4132e8a5cd4 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Mon, 29 Dec 2014 13:40:08 +0800 -Subject: [PATCH] MLK-9974: ASoC: fsl_sai: There is underrun detected in the - beginning sometimes - -Write initial words to SAI FIFO to reduce underrun error - -Signed-off-by: Shengjiu Wang -(cherry picked from commit 7ba8ae883d84540fac5ed4147d124399537bc0b3) -(cherry picked from commit f4435f35aa2a97551d2c4a12ca316c354a880f85) ---- - sound/soc/fsl/fsl_sai.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -506,7 +506,9 @@ static int fsl_sai_trigger(struct snd_pc - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; -+ u8 channels = substream->runtime->channels; - u32 xcsr, count = 100; -+ int i; - - /* - * Asynchronous mode: Clear SYNC for both Tx and Rx. -@@ -529,6 +531,11 @@ static int fsl_sai_trigger(struct snd_pc - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), - FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); - -+ for (i = 0; tx && i < channels; i++) -+ regmap_write(sai->regmap, FSL_SAI_TDR, 0x0); -+ if (tx) -+ udelay(10); -+ - regmap_update_bits(sai->regmap, FSL_SAI_RCSR, - FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); - regmap_update_bits(sai->regmap, FSL_SAI_TCSR, diff --git a/target/linux/layerscape/patches-5.4/801-audio-0013-MLK-10611-1-ASoC-fsl-sai-Just-one-device-can-playbac.patch b/target/linux/layerscape/patches-5.4/801-audio-0013-MLK-10611-1-ASoC-fsl-sai-Just-one-device-can-playbac.patch deleted file mode 100644 index faff9786b7..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0013-MLK-10611-1-ASoC-fsl-sai-Just-one-device-can-playbac.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0ab3461b68ccc1d4ffb37dbc7f2e57adc8aed0fb Mon Sep 17 00:00:00 2001 -From: Zidan Wang -Date: Fri, 10 Apr 2015 09:52:36 +0800 -Subject: [PATCH] MLK-10611-1 ASoC: fsl-sai: Just one device can - playback(captrue) when using the same SAI - -Just one device can playback(captrue) when using the same SAI. - -Signed-off-by: Zidan Wang -(cherry picked from commit 7981a488c4da440db21f0544b519b44636a0cabb) ---- - sound/soc/fsl/fsl_sai.c | 10 ++++++++++ - sound/soc/fsl/fsl_sai.h | 1 + - 2 files changed, 11 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -605,6 +605,11 @@ static int fsl_sai_startup(struct snd_pc - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - int ret; - -+ if (sai->is_stream_opened[tx]) -+ return -EBUSY; -+ else -+ sai->is_stream_opened[tx] = true; -+ - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, - FSL_SAI_CR3_TRCE); - -@@ -621,6 +626,11 @@ static void fsl_sai_shutdown(struct snd_ - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); -+ -+ if (sai->is_stream_opened[tx]) { -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); -+ sai->is_stream_opened[tx] = false; -+ } - } - - static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -137,6 +137,7 @@ struct fsl_sai { - bool is_dsp_mode; - bool sai_on_imx; - bool synchronous[2]; -+ bool is_stream_opened[2]; - - unsigned int mclk_id[2]; - unsigned int mclk_streams; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0014-MLK-11628-ASoC-fsl_sai-add-initial-value-for-is_slav.patch b/target/linux/layerscape/patches-5.4/801-audio-0014-MLK-11628-ASoC-fsl_sai-add-initial-value-for-is_slav.patch deleted file mode 100644 index 0fe22451f1..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0014-MLK-11628-ASoC-fsl_sai-add-initial-value-for-is_slav.patch +++ /dev/null @@ -1,25 +0,0 @@ -From b40561fa263f3f9b06be0dd9b9e1665478d1def6 Mon Sep 17 00:00:00 2001 -From: Zidan Wang -Date: Fri, 25 Sep 2015 14:27:00 +0800 -Subject: [PATCH] MLK-11628 ASoC: fsl_sai: add initial value for is_slave_mode - -After playback audio with sai<->wm8960 sound card, is_slave_mode -will be set, but it will not be cleared. So playback audio with -sai<->sii902x sound card will have no voice. - -Signed-off-by: Zidan Wang ---- - sound/soc/fsl/fsl_sai.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -264,6 +264,8 @@ static int fsl_sai_set_dai_fmt_tr(struct - return -EINVAL; - } - -+ sai->is_slave_mode = false; -+ - /* DAI clock master masks */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: diff --git a/target/linux/layerscape/patches-5.4/801-audio-0015-ASoC-fsl-sai-set-xCR4-xCR5-xMR-for-SAI-master-mode.patch b/target/linux/layerscape/patches-5.4/801-audio-0015-ASoC-fsl-sai-set-xCR4-xCR5-xMR-for-SAI-master-mode.patch deleted file mode 100644 index 8dbc6d1551..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0015-ASoC-fsl-sai-set-xCR4-xCR5-xMR-for-SAI-master-mode.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0b33246dfb59df34b2b834eb00f7aea75cbd4366 Mon Sep 17 00:00:00 2001 -From: Zidan Wang -Date: Mon, 9 Nov 2015 19:03:13 +0800 -Subject: [PATCH] ASoC: fsl-sai: set xCR4/xCR5/xMR for SAI master mode - -For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will -generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4), -RCR5(TCR5) and RMR(TMR) for playback(capture), or there will be sync -error sometimes. - -Signed-off-by: Zidan Wang -Acked-by: Nicolin Chen -Signed-off-by: Mark Brown -(cherry picked from commit 51659ca069ce5bdf20675a7967a39ef8419e87f2) ---- - sound/soc/fsl/fsl_sai.c | 29 +++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -476,6 +476,35 @@ static int fsl_sai_hw_params(struct snd_ - } - } - -+ /* -+ * For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will -+ * generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4), -+ * RCR5(TCR5) and RMR(TMR) for playback(capture), or there will be sync -+ * error. -+ */ -+ -+ if (!sai->is_slave_mode) { -+ if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR4, -+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -+ val_cr4); -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR5, -+ FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | -+ FSL_SAI_CR5_FBT_MASK, val_cr5); -+ regmap_write(sai->regmap, FSL_SAI_TMR, -+ ~0UL - ((1 << channels) - 1)); -+ } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR4, -+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -+ val_cr4); -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR5, -+ FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | -+ FSL_SAI_CR5_FBT_MASK, val_cr5); -+ regmap_write(sai->regmap, FSL_SAI_RMR, -+ ~0UL - ((1 << channels) - 1)); -+ } -+ } -+ - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, - val_cr4); diff --git a/target/linux/layerscape/patches-5.4/801-audio-0016-MLK-12374-ASoC-fsl_sai-Change-the-dev_warn-to-dev_db.patch b/target/linux/layerscape/patches-5.4/801-audio-0016-MLK-12374-ASoC-fsl_sai-Change-the-dev_warn-to-dev_db.patch deleted file mode 100644 index 9772d7db7b..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0016-MLK-12374-ASoC-fsl_sai-Change-the-dev_warn-to-dev_db.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 81b0102ac649207dff14b265311e6b3d2724adc4 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Thu, 4 Feb 2016 15:07:57 +0800 -Subject: [PATCH] MLK-12374: ASoC: fsl_sai: Change the dev_warn to dev_dbg - -When audio stop, it will first stop dma, then stop cpu_dai. -If there is delay between dma stop and cpu dai stop, there -will be underrun error, the print will cost time, then will -cause another underrun error, it is a infinite loop. -Which will cause the cpu dai can't stop. - -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -2,7 +2,7 @@ - // - // Freescale ALSA SoC Digital Audio Interface (SAI) driver. - // --// Copyright 2012-2015 Freescale Semiconductor, Inc. -+// Copyright 2012-2016 Freescale Semiconductor, Inc. - - #include - #include diff --git a/target/linux/layerscape/patches-5.4/801-audio-0017-MLK-12786-2-ASoC-fsl_sai-correct-the-clock-source-fo.patch b/target/linux/layerscape/patches-5.4/801-audio-0017-MLK-12786-2-ASoC-fsl_sai-correct-the-clock-source-fo.patch deleted file mode 100644 index 470b1d02c4..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0017-MLK-12786-2-ASoC-fsl_sai-correct-the-clock-source-fo.patch +++ /dev/null @@ -1,25 +0,0 @@ -From ee6adaada426e3f04925f93b4372fa3534889775 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Thu, 12 May 2016 17:54:08 +0800 -Subject: [PATCH] MLK-12786-2: ASoC: fsl_sai: correct the clock source for - mclk0 - -mclk0 is assigned through the device tree. - -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -868,8 +868,7 @@ static int fsl_sai_probe(struct platform - sai->bus_clk = NULL; - } - -- sai->mclk_clk[0] = sai->bus_clk; -- for (i = 1; i < FSL_SAI_MCLK_MAX; i++) { -+ for (i = 0; i < FSL_SAI_MCLK_MAX; i++) { - sprintf(tmp, "mclk%d", i); - sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp); - if (IS_ERR(sai->mclk_clk[i])) { diff --git a/target/linux/layerscape/patches-5.4/801-audio-0018-MLK-13574-2-ASoC-fsl_sai-refine-driver-for-ip-upgrad.patch b/target/linux/layerscape/patches-5.4/801-audio-0018-MLK-13574-2-ASoC-fsl_sai-refine-driver-for-ip-upgrad.patch deleted file mode 100644 index 793936d376..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0018-MLK-13574-2-ASoC-fsl_sai-refine-driver-for-ip-upgrad.patch +++ /dev/null @@ -1,423 +0,0 @@ -From c516c261c49d0ce9509d6b9623dec6a4e9f919c3 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Mon, 30 Mar 2020 16:21:00 +0800 -Subject: [PATCH] MLK-13574-2: ASoC: fsl_sai: refine driver for ip upgrade - -In imx7ulp1, the sai can support two TX channel and two RX -channels, So the usage need to be updated. - -Signed-off-by: Shengjiu Wang -[rebase] -Signed-off-by: Yangbo Lu ---- - sound/soc/fsl/fsl_sai.c | 145 ++++++++++++++++++++++++++++++++++++++++-------- - sound/soc/fsl/fsl_sai.h | 37 ++++++++++-- - 2 files changed, 156 insertions(+), 26 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -8,16 +8,19 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - #include -+#include - #include - #include - #include - #include - #include -+#include - - #include "fsl_sai.h" - #include "imx-pcm.h" -@@ -25,6 +28,39 @@ - #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\ - FSL_SAI_CSR_FEIE) - -+static struct fsl_sai_soc_data fsl_sai_vf610 = { -+ .imx = false, -+ /*dataline is mask, not index*/ -+ .dataline = 0x1, -+ .fifos = 1, -+ .fifo_depth = 32, -+ .flags = 0, -+}; -+ -+static struct fsl_sai_soc_data fsl_sai_imx6sx = { -+ .imx = true, -+ .dataline = 0x1, -+ .fifos = 1, -+ .fifo_depth = 32, -+ .flags = 0, -+}; -+ -+static struct fsl_sai_soc_data fsl_sai_imx6ul = { -+ .imx = true, -+ .dataline = 0x1, -+ .fifos = 1, -+ .fifo_depth = 32, -+ .flags = 0, -+}; -+ -+static struct fsl_sai_soc_data fsl_sai_imx7ulp = { -+ .imx = true, -+ .dataline = 0x3, -+ .fifos = 2, -+ .fifo_depth = 16, -+ .flags = SAI_FLAG_PMQOS, -+}; -+ - static const unsigned int fsl_sai_rates[] = { - 8000, 11025, 12000, 16000, 22050, - 24000, 32000, 44100, 48000, 64000, -@@ -505,6 +541,29 @@ static int fsl_sai_hw_params(struct snd_ - } - } - -+ if (sai->soc->dataline != 0x1) { -+ switch (sai->dataline[tx]) { -+ case 0x0: -+ break; -+ case 0x1: -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), -+ FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT, 0); -+ break; -+ case 0x2: -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), -+ FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT, -+ FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT); -+ break; -+ case 0x3: -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), -+ FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT, -+ FSL_SAI_CR4_FCOMB_SOFT); -+ break; -+ default: -+ break; -+ } -+ } -+ - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, - val_cr4); -@@ -563,14 +622,16 @@ static int fsl_sai_trigger(struct snd_pc - FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); - - for (i = 0; tx && i < channels; i++) -- regmap_write(sai->regmap, FSL_SAI_TDR, 0x0); -+ regmap_write(sai->regmap, FSL_SAI_TDR0, 0x0); - if (tx) - udelay(10); - -- regmap_update_bits(sai->regmap, FSL_SAI_RCSR, -- FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); - regmap_update_bits(sai->regmap, FSL_SAI_TCSR, - FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); -+ regmap_update_bits(sai->regmap, FSL_SAI_RCSR, -+ FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), -+ FSL_SAI_CSR_SE, FSL_SAI_CSR_SE); - - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), - FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); -@@ -641,8 +702,8 @@ static int fsl_sai_startup(struct snd_pc - else - sai->is_stream_opened[tx] = true; - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, -- FSL_SAI_CR3_TRCE); -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE0|FSL_SAI_CR3_TRCE1, -+ FSL_SAI_CR3_TRCE(sai->dataline[tx])); - - ret = snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints); -@@ -659,7 +720,7 @@ static void fsl_sai_shutdown(struct snd_ - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); - - if (sai->is_stream_opened[tx]) { -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE0 | FSL_SAI_CR3_TRCE1, 0); - sai->is_stream_opened[tx] = false; - } - } -@@ -687,7 +748,7 @@ static int fsl_sai_dai_probe(struct snd_ - regmap_write(sai->regmap, FSL_SAI_RCSR, 0); - - regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, -- FSL_SAI_MAXBURST_TX * 2); -+ sai->soc->fifo_depth - FSL_SAI_MAXBURST_TX); - regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, - FSL_SAI_MAXBURST_RX - 1); - -@@ -732,7 +793,8 @@ static struct reg_default fsl_sai_reg_de - {FSL_SAI_TCR3, 0}, - {FSL_SAI_TCR4, 0}, - {FSL_SAI_TCR5, 0}, -- {FSL_SAI_TDR, 0}, -+ {FSL_SAI_TDR0, 0}, -+ {FSL_SAI_TDR1, 0}, - {FSL_SAI_TMR, 0}, - {FSL_SAI_RCR1, 0}, - {FSL_SAI_RCR2, 0}, -@@ -751,7 +813,8 @@ static bool fsl_sai_readable_reg(struct - case FSL_SAI_TCR3: - case FSL_SAI_TCR4: - case FSL_SAI_TCR5: -- case FSL_SAI_TFR: -+ case FSL_SAI_TFR0: -+ case FSL_SAI_TFR1: - case FSL_SAI_TMR: - case FSL_SAI_RCSR: - case FSL_SAI_RCR1: -@@ -759,8 +822,10 @@ static bool fsl_sai_readable_reg(struct - case FSL_SAI_RCR3: - case FSL_SAI_RCR4: - case FSL_SAI_RCR5: -- case FSL_SAI_RDR: -- case FSL_SAI_RFR: -+ case FSL_SAI_RDR0: -+ case FSL_SAI_RDR1: -+ case FSL_SAI_RFR0: -+ case FSL_SAI_RFR1: - case FSL_SAI_RMR: - return true; - default: -@@ -773,9 +838,12 @@ static bool fsl_sai_volatile_reg(struct - switch (reg) { - case FSL_SAI_TCSR: - case FSL_SAI_RCSR: -- case FSL_SAI_TFR: -- case FSL_SAI_RFR: -- case FSL_SAI_RDR: -+ case FSL_SAI_TFR0: -+ case FSL_SAI_TFR1: -+ case FSL_SAI_RFR0: -+ case FSL_SAI_RFR1: -+ case FSL_SAI_RDR0: -+ case FSL_SAI_RDR1: - return true; - default: - return false; -@@ -791,7 +859,8 @@ static bool fsl_sai_writeable_reg(struct - case FSL_SAI_TCR3: - case FSL_SAI_TCR4: - case FSL_SAI_TCR5: -- case FSL_SAI_TDR: -+ case FSL_SAI_TDR0: -+ case FSL_SAI_TDR1: - case FSL_SAI_TMR: - case FSL_SAI_RCSR: - case FSL_SAI_RCR1: -@@ -820,9 +889,19 @@ static const struct regmap_config fsl_sa - .cache_type = REGCACHE_FLAT, - }; - -+static const struct of_device_id fsl_sai_ids[] = { -+ { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610 }, -+ { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx }, -+ { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6ul }, -+ { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, fsl_sai_ids); -+ - static int fsl_sai_probe(struct platform_device *pdev) - { - struct device_node *np = pdev->dev.of_node; -+ const struct of_device_id *of_id; - struct fsl_sai *sai; - struct regmap *gpr; - struct resource *res; -@@ -837,11 +916,12 @@ static int fsl_sai_probe(struct platform - - sai->pdev = pdev; - -- if (of_device_is_compatible(np, "fsl,imx6sx-sai") || -- of_device_is_compatible(np, "fsl,imx6ul-sai")) -- sai->sai_on_imx = true; -+ of_id = of_match_device(fsl_sai_ids, &pdev->dev); -+ if (!of_id || !of_id->data) -+ return -EINVAL; - - sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); -+ sai->soc = of_id->data; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); -@@ -873,11 +953,25 @@ static int fsl_sai_probe(struct platform - sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp); - if (IS_ERR(sai->mclk_clk[i])) { - dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n", -- i + 1, PTR_ERR(sai->mclk_clk[i])); -+ i, PTR_ERR(sai->mclk_clk[i])); - sai->mclk_clk[i] = NULL; - } - } - -+ /*dataline mask for rx and tx*/ -+ ret = of_property_read_u32_index(np, "fsl,dataline", 0, &sai->dataline[0]); -+ if (ret) -+ sai->dataline[0] = 1; -+ -+ ret = of_property_read_u32_index(np, "fsl,dataline", 1, &sai->dataline[1]); -+ if (ret) -+ sai->dataline[1] = 1; -+ -+ if ((sai->dataline[0] & (~sai->soc->dataline)) || sai->dataline[1] & (~sai->soc->dataline)) { -+ dev_err(&pdev->dev, "dataline setting error, Mask is 0x%x\n", sai->soc->dataline); -+ return -EINVAL; -+ } -+ - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); -@@ -936,8 +1030,8 @@ static int fsl_sai_probe(struct platform - MCLK_DIR(index)); - } - -- sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; -- sai->dma_params_tx.addr = res->start + FSL_SAI_TDR; -+ sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0; -+ sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0; - sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; - sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; - -@@ -950,7 +1044,7 @@ static int fsl_sai_probe(struct platform - if (ret) - goto err_pm_disable; - -- if (sai->sai_on_imx) -+ if (sai->soc->imx) - ret = imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE); - if (ret) - goto err_pm_disable; -@@ -996,6 +1090,9 @@ static int fsl_sai_runtime_suspend(struc - - clk_disable_unprepare(sai->bus_clk); - -+ if (sai->soc->flags & SAI_FLAG_PMQOS) -+ pm_qos_remove_request(&sai->pm_qos_req); -+ - regcache_cache_only(sai->regmap, true); - regcache_mark_dirty(sai->regmap); - -@@ -1025,6 +1122,10 @@ static int fsl_sai_runtime_resume(struct - goto disable_tx_clk; - } - -+ if (sai->soc->flags & SAI_FLAG_PMQOS) -+ pm_qos_add_request(&sai->pm_qos_req, -+ PM_QOS_CPU_DMA_LATENCY, 0); -+ - regcache_cache_only(sai->regmap, false); - regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); - regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -1,11 +1,12 @@ - /* SPDX-License-Identifier: GPL-2.0 */ - /* -- * Copyright 2012-2013 Freescale Semiconductor, Inc. -+ * Copyright 2012-2016 Freescale Semiconductor, Inc. - */ - - #ifndef __FSL_SAI_H - #define __FSL_SAI_H - -+#include - #include - - #define FSL_SAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ -@@ -20,7 +21,10 @@ - #define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */ - #define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */ - #define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */ --#define FSL_SAI_TDR 0x20 /* SAI Transmit Data */ -+#define FSL_SAI_TDR0 0x20 /* SAI Transmit Data */ -+#define FSL_SAI_TDR1 0x24 /* SAI Transmit Data */ -+#define FSL_SAI_TFR0 0x40 /* SAI Transmit FIFO */ -+#define FSL_SAI_TFR1 0x44 /* SAI Transmit FIFO */ - #define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */ - #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ - #define FSL_SAI_RCSR 0x80 /* SAI Receive Control */ -@@ -29,7 +33,10 @@ - #define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */ - #define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */ - #define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */ --#define FSL_SAI_RDR 0xa0 /* SAI Receive Data */ -+#define FSL_SAI_RDR0 0xa0 /* SAI Receive Data */ -+#define FSL_SAI_RDR1 0xa4 /* SAI Receive Data */ -+#define FSL_SAI_RFR0 0xc0 /* SAI Receive FIFO */ -+#define FSL_SAI_RFR1 0xc4 /* SAI Receive FIFO */ - #define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ - #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ - -@@ -45,6 +52,7 @@ - - /* SAI Transmit/Receive Control Register */ - #define FSL_SAI_CSR_TERE BIT(31) -+#define FSL_SAI_CSR_SE BIT(30) - #define FSL_SAI_CSR_FR BIT(25) - #define FSL_SAI_CSR_SR BIT(24) - #define FSL_SAI_CSR_xF_SHIFT 16 -@@ -81,11 +89,19 @@ - #define FSL_SAI_CR2_DIV_MASK 0xff - - /* SAI Transmit and Receive Configuration 3 Register */ --#define FSL_SAI_CR3_TRCE BIT(16) -+#define FSL_SAI_CR3_TRCE0 BIT(16) -+#define FSL_SAI_CR3_TRCE1 BIT(17) -+#define FSL_SAI_CR3_TRCE(x) (x << 16) - #define FSL_SAI_CR3_WDFL(x) (x) - #define FSL_SAI_CR3_WDFL_MASK 0x1f - - /* SAI Transmit and Receive Configuration 4 Register */ -+ -+#define FSL_SAI_CR4_FCONT BIT(28) -+#define FSL_SAI_CR4_FCOMB_SHIFT BIT(26) -+#define FSL_SAI_CR4_FCOMB_SOFT BIT(27) -+#define FSL_SAI_CR4_FPACK_8 (0x2 << 24) -+#define FSL_SAI_CR4_FPACK_16 (0x3 << 24) - #define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16) - #define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16) - #define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8) -@@ -126,6 +142,16 @@ - #define FSL_SAI_MAXBURST_TX 6 - #define FSL_SAI_MAXBURST_RX 6 - -+#define SAI_FLAG_PMQOS BIT(0) -+ -+struct fsl_sai_soc_data { -+ unsigned int fifo_depth; -+ unsigned int fifos; -+ unsigned int dataline; -+ unsigned int flags; -+ bool imx; -+}; -+ - struct fsl_sai { - struct platform_device *pdev; - struct regmap *regmap; -@@ -138,6 +164,7 @@ struct fsl_sai { - bool sai_on_imx; - bool synchronous[2]; - bool is_stream_opened[2]; -+ unsigned int dataline[2]; - - unsigned int mclk_id[2]; - unsigned int mclk_streams; -@@ -147,6 +174,8 @@ struct fsl_sai { - struct snd_soc_dai_driver cpu_dai_drv; - struct snd_dmaengine_dai_dma_data dma_params_rx; - struct snd_dmaengine_dai_dma_data dma_params_tx; -+ const struct fsl_sai_soc_data *soc; -+ struct pm_qos_request pm_qos_req; - }; - - #define TX 1 diff --git a/target/linux/layerscape/patches-5.4/801-audio-0019-MLK-13609-ASoC-fsl_sai-fix-for-synchronize-mode.patch b/target/linux/layerscape/patches-5.4/801-audio-0019-MLK-13609-ASoC-fsl_sai-fix-for-synchronize-mode.patch deleted file mode 100644 index 2d7832744a..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0019-MLK-13609-ASoC-fsl_sai-fix-for-synchronize-mode.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 7b5c62dc6c1de58ee1d527059ae69152ed1380f2 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Mon, 12 Dec 2016 11:52:24 +0800 -Subject: [PATCH] MLK-13609: ASoC: fsl_sai: fix for synchronize mode - -TX synchronous with receiver: the RMR should not be changed and -the RCSR.RE should be set in playback. -RX synchronous with transmitter: the TMR should not be changed and -the TCSR.TE should be set in recording. - -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 15 ++++++++------- - 1 file changed, 8 insertions(+), 7 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -527,8 +527,6 @@ static int fsl_sai_hw_params(struct snd_ - regmap_update_bits(sai->regmap, FSL_SAI_TCR5, - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); -- regmap_write(sai->regmap, FSL_SAI_TMR, -- ~0UL - ((1 << channels) - 1)); - } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { - regmap_update_bits(sai->regmap, FSL_SAI_RCR4, - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -@@ -536,8 +534,6 @@ static int fsl_sai_hw_params(struct snd_ - regmap_update_bits(sai->regmap, FSL_SAI_RCR5, - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); -- regmap_write(sai->regmap, FSL_SAI_RMR, -- ~0UL - ((1 << channels) - 1)); - } - } - -@@ -626,12 +622,17 @@ static int fsl_sai_trigger(struct snd_pc - if (tx) - udelay(10); - -- regmap_update_bits(sai->regmap, FSL_SAI_TCSR, -- FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); -- regmap_update_bits(sai->regmap, FSL_SAI_RCSR, -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), - FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), - FSL_SAI_CSR_SE, FSL_SAI_CSR_SE); -+ if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx)), -+ FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); -+ } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx)), -+ FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); -+ } - - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), - FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); diff --git a/target/linux/layerscape/patches-5.4/801-audio-0020-ASoC-fsl_-e-sai-introduce-shared-interrupt-DT-flag-p.patch b/target/linux/layerscape/patches-5.4/801-audio-0020-ASoC-fsl_-e-sai-introduce-shared-interrupt-DT-flag-p.patch deleted file mode 100644 index 1184bce0e3..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0020-ASoC-fsl_-e-sai-introduce-shared-interrupt-DT-flag-p.patch +++ /dev/null @@ -1,42 +0,0 @@ -From a22b10e2c273308f547c5ad96e3820f312058ae7 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Sun, 30 Apr 2017 12:41:33 +0300 -Subject: [PATCH] ASoC: fsl_(e)sai: introduce "shared-interrupt" DT flag (part - 2) - -SAI & ESAI interfaces may share the same interrupt with EDMA, -so that we need a flag to trigger proper shared interrupt -handling. For compatibility the same DT flag, "shared-interrupt", -is introduced as the one used in drivers/dma/fsl-edma-v3.c. - -Signed-off-by: Viorel Suman -[ Aisheng: split easi changes ] -Signed-off-by: Dong Aisheng ---- - sound/soc/fsl/fsl_sai.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -910,6 +910,7 @@ static int fsl_sai_probe(struct platform - char tmp[8]; - int irq, ret, i; - int index; -+ unsigned long irqflag = 0; - - sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); - if (!sai) -@@ -979,7 +980,12 @@ static int fsl_sai_probe(struct platform - return irq; - } - -- ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai); -+ /* SAI shared interrupt */ -+ if (of_property_read_bool(np, "shared-interrupt")) -+ irqflag = IRQF_SHARED; -+ -+ ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, irqflag, -+ np->name, sai); - if (ret) { - dev_err(&pdev->dev, "failed to claim irq %u\n", irq); - return ret; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0021-ASoC-fsl_sai-handle-slave-mode-per-TX-RX-direction.patch b/target/linux/layerscape/patches-5.4/801-audio-0021-ASoC-fsl_sai-handle-slave-mode-per-TX-RX-direction.patch deleted file mode 100644 index 2fb5789ef3..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0021-ASoC-fsl_sai-handle-slave-mode-per-TX-RX-direction.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 06d8069b308a1655e0c248b6bd556e63d9b38099 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Wed, 3 May 2017 10:16:02 +0300 -Subject: [PATCH] ASoC: fsl_sai: handle slave mode per TX/RX direction - -The SAI interface can be a clock supplier or consummer -as function of stream direction, ie when interacting -with I2S XTOR. Removed FSL_SAI_RFR define as it is now -referred as FSL_SAI_RFR0. - -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 18 +++++++++--------- - sound/soc/fsl/fsl_sai.h | 3 +-- - 2 files changed, 10 insertions(+), 11 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -300,7 +300,7 @@ static int fsl_sai_set_dai_fmt_tr(struct - return -EINVAL; - } - -- sai->is_slave_mode = false; -+ sai->slave_mode[tx] = false; - - /* DAI clock master masks */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { -@@ -310,7 +310,7 @@ static int fsl_sai_set_dai_fmt_tr(struct - sai->is_slave_mode = false; - break; - case SND_SOC_DAIFMT_CBM_CFM: -- sai->is_slave_mode = true; -+ sai->slave_mode[tx] = true; - break; - case SND_SOC_DAIFMT_CBS_CFM: - val_cr2 |= FSL_SAI_CR2_BCD_MSTR; -@@ -318,7 +318,7 @@ static int fsl_sai_set_dai_fmt_tr(struct - break; - case SND_SOC_DAIFMT_CBM_CFS: - val_cr4 |= FSL_SAI_CR4_FSD_MSTR; -- sai->is_slave_mode = true; -+ sai->slave_mode[tx] = true; - break; - default: - return -EINVAL; -@@ -359,7 +359,7 @@ static int fsl_sai_set_bclk(struct snd_s - int ret = 0; - - /* Don't apply to slave mode */ -- if (sai->is_slave_mode) -+ if (sai->slave_mode[tx]) - return 0; - - for (id = 0; id < FSL_SAI_MCLK_MAX; id++) { -@@ -454,7 +454,7 @@ static int fsl_sai_hw_params(struct snd_ - if (sai->slot_width) - slot_width = sai->slot_width; - -- if (!sai->is_slave_mode) { -+ if (!sai->slave_mode[tx]) { - ret = fsl_sai_set_bclk(cpu_dai, tx, - slots * slot_width * params_rate(params)); - if (ret) -@@ -490,7 +490,7 @@ static int fsl_sai_hw_params(struct snd_ - * error. - */ - -- if (!sai->is_slave_mode) { -+ if (!sai->slave_mode[tx]) { - if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { - regmap_update_bits(sai->regmap, FSL_SAI_TCR4, - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -@@ -519,7 +519,7 @@ static int fsl_sai_hw_params(struct snd_ - * error. - */ - -- if (!sai->is_slave_mode) { -+ if (!sai->slave_mode[tx]) { - if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { - regmap_update_bits(sai->regmap, FSL_SAI_TCR4, - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -@@ -577,7 +577,7 @@ static int fsl_sai_hw_free(struct snd_pc - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - -- if (!sai->is_slave_mode && -+ if (!sai->slave_mode[tx] && - sai->mclk_streams & BIT(substream->stream)) { - clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]); - sai->mclk_streams &= ~BIT(substream->stream); -@@ -672,7 +672,7 @@ static int fsl_sai_trigger(struct snd_pc - * This is a hardware bug, and will be fix in the - * next sai version. - */ -- if (!sai->is_slave_mode) { -+ if (!sai->slave_mode[tx]) { - /* Software Reset for both Tx and Rx */ - regmap_write(sai->regmap, - FSL_SAI_TCSR, FSL_SAI_CSR_SR); ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -37,7 +37,6 @@ - #define FSL_SAI_RDR1 0xa4 /* SAI Receive Data */ - #define FSL_SAI_RFR0 0xc0 /* SAI Receive FIFO */ - #define FSL_SAI_RFR1 0xc4 /* SAI Receive FIFO */ --#define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ - #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ - - #define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR) -@@ -158,7 +157,7 @@ struct fsl_sai { - struct clk *bus_clk; - struct clk *mclk_clk[FSL_SAI_MCLK_MAX]; - -- bool is_slave_mode; -+ bool slave_mode[2]; - bool is_lsb_first; - bool is_dsp_mode; - bool sai_on_imx; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0022-ASoC-fsl_sai-set-specific-fmt-for-I2S-XTOR.patch b/target/linux/layerscape/patches-5.4/801-audio-0022-ASoC-fsl_sai-set-specific-fmt-for-I2S-XTOR.patch deleted file mode 100644 index 84bf81ae64..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0022-ASoC-fsl_sai-set-specific-fmt-for-I2S-XTOR.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 307e37122cc14b5b305639c18ea575ebe623da2f Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Sun, 30 Apr 2017 17:05:52 +0300 -Subject: [PATCH] ASoC: fsl_sai: set specific fmt for I2S XTOR - -Set specific fmt, for i2s xtor receiver is -in slave mode and i2s xtor transmitter is in master mode. - -Signed-off-by: Shengjiu Wang -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 12 ++++++++++++ - sound/soc/fsl/fsl_sai.h | 2 +- - 2 files changed, 13 insertions(+), 1 deletion(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -335,14 +335,23 @@ static int fsl_sai_set_dai_fmt_tr(struct - - static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) - { -+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - int ret; - -+ if (sai->i2s_xtor) -+ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS; -+ - ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER); - if (ret) { - dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret); - return ret; - } - -+ if (sai->i2s_xtor) -+ fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBM_CFM; -+ - ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER); - if (ret) - dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret); -@@ -974,6 +983,9 @@ static int fsl_sai_probe(struct platform - return -EINVAL; - } - -+ /* I2S XTOR mode */ -+ sai->i2s_xtor = (of_find_property(np, "fsl,i2s-xtor", NULL) != NULL); -+ - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -160,7 +160,7 @@ struct fsl_sai { - bool slave_mode[2]; - bool is_lsb_first; - bool is_dsp_mode; -- bool sai_on_imx; -+ bool i2s_xtor; - bool synchronous[2]; - bool is_stream_opened[2]; - unsigned int dataline[2]; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0024-MLK-14847-Revert-ASoC-fsl-sai-set-xCR4-xCR5-xMR-for-.patch b/target/linux/layerscape/patches-5.4/801-audio-0024-MLK-14847-Revert-ASoC-fsl-sai-set-xCR4-xCR5-xMR-for-.patch deleted file mode 100644 index 1edd4a35ea..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0024-MLK-14847-Revert-ASoC-fsl-sai-set-xCR4-xCR5-xMR-for-.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 060265cd3cec354804c0c944e42de83cec9f2f2a Mon Sep 17 00:00:00 2001 -From: Mihai Serban -Date: Fri, 21 Apr 2017 15:57:58 +0300 -Subject: [PATCH] MLK-14847: Revert "ASoC: fsl-sai: set xCR4/xCR5/xMR for SAI - master mode" - -This reverts commit c768ed336bba ("ASoC: fsl-sai: set xCR4/xCR5/xMR for -SAI master mode") - -This change was already introduced by commit 51659ca069ce ("ASoC: fsl-sai: -set xCR4/xCR5/xMR for SAI master mode") from upstream. - -Manually adjust the code to match the changes introduced by subsequent -commit b2936555bb38 ("MLK-13609: ASoC: fsl_sai: fix for synchronize mode") -by removing updates to FSL_SAI_TMR/FSL_SAI_RMR registers. - -Signed-off-by: Mihai Serban ---- - sound/soc/fsl/fsl_sai.c | 29 ----------------------------- - 1 file changed, 29 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -507,35 +507,6 @@ static int fsl_sai_hw_params(struct snd_ - regmap_update_bits(sai->regmap, FSL_SAI_TCR5, - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); -- regmap_write(sai->regmap, FSL_SAI_TMR, -- ~0UL - ((1 << channels) - 1)); -- } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { -- regmap_update_bits(sai->regmap, FSL_SAI_RCR4, -- FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -- val_cr4); -- regmap_update_bits(sai->regmap, FSL_SAI_RCR5, -- FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | -- FSL_SAI_CR5_FBT_MASK, val_cr5); -- regmap_write(sai->regmap, FSL_SAI_RMR, -- ~0UL - ((1 << channels) - 1)); -- } -- } -- -- /* -- * For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will -- * generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4), -- * RCR5(TCR5) and RMR(TMR) for playback(capture), or there will be sync -- * error. -- */ -- -- if (!sai->slave_mode[tx]) { -- if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { -- regmap_update_bits(sai->regmap, FSL_SAI_TCR4, -- FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -- val_cr4); -- regmap_update_bits(sai->regmap, FSL_SAI_TCR5, -- FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | -- FSL_SAI_CR5_FBT_MASK, val_cr5); - } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { - regmap_update_bits(sai->regmap, FSL_SAI_RCR4, - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, diff --git a/target/linux/layerscape/patches-5.4/801-audio-0025-MLK-14870-ASoC-fsl_sai-Remove-support-for-S20_3LE.patch b/target/linux/layerscape/patches-5.4/801-audio-0025-MLK-14870-ASoC-fsl_sai-Remove-support-for-S20_3LE.patch deleted file mode 100644 index e497705f8f..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0025-MLK-14870-ASoC-fsl_sai-Remove-support-for-S20_3LE.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 1a3b5fa78e710771c44450735439d5f5fd156141 Mon Sep 17 00:00:00 2001 -From: Daniel Baluta -Date: Wed, 10 May 2017 14:21:40 +0300 -Subject: [PATCH] MLK-14870: ASoC: fsl_sai: Remove support for S20_3LE - -With current clock configuration we cannot derive bitclk for S20_3LE -format in SAI master mode. There was an attempt to fix this in commit -65e6b5f1b4a7 ("MLK-14536: ASoC: wm8960: Fix playback in CPU DAI master mode") -but this broke codec-master mode, thus the patch was partially reverted in -96f0d36e420 ("MLK-14798: arm: dts: imx6ul: Fix wm8960 codec master mode") - -So, remove S20_3LE support for SAI master mode. Clients using this -feature should use codec master mode, which is the default one in the -dts anyway. - -Signed-off-by: Daniel Baluta ---- - sound/soc/fsl/fsl_sai.h | 1 - - 1 file changed, 1 deletion(-) - ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -10,7 +10,6 @@ - #include - - #define FSL_SAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ -- SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE |\ - SNDRV_PCM_FMTBIT_S32_LE) - diff --git a/target/linux/layerscape/patches-5.4/801-audio-0026-MLK-14935-ASoC-fsl_sai-Fix-mixing-initialization-dat.patch b/target/linux/layerscape/patches-5.4/801-audio-0026-MLK-14935-ASoC-fsl_sai-Fix-mixing-initialization-dat.patch deleted file mode 100644 index a68985fa02..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0026-MLK-14935-ASoC-fsl_sai-Fix-mixing-initialization-dat.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 96412158397ca0e41db1eb7cec4f51a2280d1bf1 Mon Sep 17 00:00:00 2001 -From: Mihai Serban -Date: Thu, 27 Apr 2017 18:47:42 +0300 -Subject: [PATCH] MLK-14935: ASoC: fsl_sai: Fix mixing initialization data with - actual audio samples - -When starting a playback the initialization data used to reduce underruns -was send to the transmit data register after the DMA requests were enabled. -This patch moves the initialization phase before enabling the DMA so the -data is transmitted in correct order. - -Signed-off-by: Mihai Serban ---- - sound/soc/fsl/fsl_sai.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -594,15 +594,14 @@ static int fsl_sai_trigger(struct snd_pc - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), -- FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); -- - for (i = 0; tx && i < channels; i++) - regmap_write(sai->regmap, FSL_SAI_TDR0, 0x0); - if (tx) - udelay(10); - - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), -+ FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), - FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), - FSL_SAI_CSR_SE, FSL_SAI_CSR_SE); diff --git a/target/linux/layerscape/patches-5.4/801-audio-0027-MLK-15140-1-ASoC-fsl_sai-support-latest-sai-module.patch b/target/linux/layerscape/patches-5.4/801-audio-0027-MLK-15140-1-ASoC-fsl_sai-support-latest-sai-module.patch deleted file mode 100644 index f0063453d5..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0027-MLK-15140-1-ASoC-fsl_sai-support-latest-sai-module.patch +++ /dev/null @@ -1,701 +0,0 @@ -From 21cf15cd000ba45bc02b8bfcf59df1e13bfdb803 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Thu, 22 Jun 2017 15:39:24 +0800 -Subject: [PATCH] MLK-15140-1: ASoC: fsl_sai: support latest sai module - -The version of sai is upgrate in imx8mq, which add two register -in beginning, there is VERID and PARAM. the driver need to be -update - -Signed-off-by: Mihai Serban -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 273 ++++++++++++++++++++++++++++-------------------- - sound/soc/fsl/fsl_sai.h | 43 ++++---- - 2 files changed, 180 insertions(+), 136 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -43,6 +43,7 @@ static struct fsl_sai_soc_data fsl_sai_i - .fifos = 1, - .fifo_depth = 32, - .flags = 0, -+ .reg_offset = 0, - }; - - static struct fsl_sai_soc_data fsl_sai_imx6ul = { -@@ -51,6 +52,7 @@ static struct fsl_sai_soc_data fsl_sai_i - .fifos = 1, - .fifo_depth = 32, - .flags = 0, -+ .reg_offset = 0, - }; - - static struct fsl_sai_soc_data fsl_sai_imx7ulp = { -@@ -59,6 +61,16 @@ static struct fsl_sai_soc_data fsl_sai_i - .fifos = 2, - .fifo_depth = 16, - .flags = SAI_FLAG_PMQOS, -+ .reg_offset = 0, -+}; -+ -+static struct fsl_sai_soc_data fsl_sai_imx8mq = { -+ .imx = true, -+ .dataline = 0xff, -+ .fifos = 8, -+ .fifo_depth = 32, -+ .flags = 0, -+ .reg_offset = 8, - }; - - static const unsigned int fsl_sai_rates[] = { -@@ -75,6 +87,7 @@ static const struct snd_pcm_hw_constrain - static irqreturn_t fsl_sai_isr(int irq, void *devid) - { - struct fsl_sai *sai = (struct fsl_sai *)devid; -+ unsigned char offset = sai->soc->reg_offset; - struct device *dev = &sai->pdev->dev; - u32 flags, xcsr, mask; - bool irq_none = true; -@@ -87,7 +100,7 @@ static irqreturn_t fsl_sai_isr(int irq, - mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; - - /* Tx IRQ */ -- regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr); -+ regmap_read(sai->regmap, FSL_SAI_TCSR(offset), &xcsr); - flags = xcsr & mask; - - if (flags) -@@ -117,11 +130,11 @@ static irqreturn_t fsl_sai_isr(int irq, - xcsr &= ~FSL_SAI_CSR_xF_MASK; - - if (flags) -- regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); -+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), flags | xcsr); - - irq_rx: - /* Rx IRQ */ -- regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr); -+ regmap_read(sai->regmap, FSL_SAI_RCSR(offset), &xcsr); - flags = xcsr & mask; - - if (flags) -@@ -151,7 +164,7 @@ irq_rx: - xcsr &= ~FSL_SAI_CSR_xF_MASK; - - if (flags) -- regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr); -+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), flags | xcsr); - - out: - if (irq_none) -@@ -175,6 +188,7 @@ static int fsl_sai_set_dai_sysclk_tr(str - int clk_id, unsigned int freq, int fsl_dir) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -+ unsigned char offset = sai->soc->reg_offset; - bool tx = fsl_dir == FSL_FMT_TRANSMITTER; - u32 val_cr2 = 0; - -@@ -195,7 +209,7 @@ static int fsl_sai_set_dai_sysclk_tr(str - return -EINVAL; - } - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, offset), - FSL_SAI_CR2_MSEL_MASK, val_cr2); - - return 0; -@@ -228,6 +242,7 @@ static int fsl_sai_set_dai_fmt_tr(struct - unsigned int fmt, int fsl_dir) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -+ unsigned char offset = sai->soc->reg_offset; - bool tx = fsl_dir == FSL_FMT_TRANSMITTER; - u32 val_cr2 = 0, val_cr4 = 0; - -@@ -324,9 +339,9 @@ static int fsl_sai_set_dai_fmt_tr(struct - return -EINVAL; - } - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, offset), - FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2); -- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE | - FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4); - -@@ -362,6 +377,7 @@ static int fsl_sai_set_dai_fmt(struct sn - static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); -+ unsigned char offset = sai->soc->reg_offset; - unsigned long clk_rate; - u32 savediv = 0, ratio, savesub = freq; - u32 id; -@@ -424,17 +440,17 @@ static int fsl_sai_set_bclk(struct snd_s - */ - if ((sai->synchronous[TX] && !sai->synchronous[RX]) || - (!tx && !sai->synchronous[RX])) { -- regmap_update_bits(sai->regmap, FSL_SAI_RCR2, -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset), - FSL_SAI_CR2_MSEL_MASK, - FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); -- regmap_update_bits(sai->regmap, FSL_SAI_RCR2, -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset), - FSL_SAI_CR2_DIV_MASK, savediv - 1); - } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) || - (tx && !sai->synchronous[TX])) { -- regmap_update_bits(sai->regmap, FSL_SAI_TCR2, -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset), - FSL_SAI_CR2_MSEL_MASK, - FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); -- regmap_update_bits(sai->regmap, FSL_SAI_TCR2, -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset), - FSL_SAI_CR2_DIV_MASK, savediv - 1); - } - -@@ -449,6 +465,7 @@ static int fsl_sai_hw_params(struct snd_ - struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -+ unsigned char offset = sai->soc->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - unsigned int channels = params_channels(params); - u32 word_width = params_width(params); -@@ -501,49 +518,35 @@ static int fsl_sai_hw_params(struct snd_ - - if (!sai->slave_mode[tx]) { - if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { -- regmap_update_bits(sai->regmap, FSL_SAI_TCR4, -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR4(offset), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, - val_cr4); -- regmap_update_bits(sai->regmap, FSL_SAI_TCR5, -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR5(offset), - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); - } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { -- regmap_update_bits(sai->regmap, FSL_SAI_RCR4, -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR4(offset), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, - val_cr4); -- regmap_update_bits(sai->regmap, FSL_SAI_RCR5, -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR5(offset), - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); - } - } - - if (sai->soc->dataline != 0x1) { -- switch (sai->dataline[tx]) { -- case 0x0: -- break; -- case 0x1: -- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), -- FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT, 0); -- break; -- case 0x2: -- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), -- FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT, -- FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT); -- break; -- case 0x3: -- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), -- FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT, -- FSL_SAI_CR4_FCOMB_SOFT); -- break; -- default: -- break; -- } -+ if (sai->dataline[tx] <= 1) -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), -+ FSL_SAI_CR4_FCOMB_MASK, 0); -+ else -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), -+ FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT); - } - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, - val_cr4); -- regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, offset), - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); - regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1)); -@@ -571,6 +574,7 @@ static int fsl_sai_trigger(struct snd_pc - struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -+ unsigned char offset = sai->soc->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - u8 channels = substream->runtime->channels; - u32 xcsr, count = 100; -@@ -581,9 +585,9 @@ static int fsl_sai_trigger(struct snd_pc - * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. - * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx. - */ -- regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset), FSL_SAI_CR2_SYNC, - sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); -- regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset), FSL_SAI_CR2_SYNC, - sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0); - - /* -@@ -599,49 +603,50 @@ static int fsl_sai_trigger(struct snd_pc - if (tx) - udelay(10); - -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset), - FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), -+ -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset), - FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset), - FSL_SAI_CSR_SE, FSL_SAI_CSR_SE); - if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx)), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), offset), - FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); - } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx)), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), offset), - FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); - } - -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset), - FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset), - FSL_SAI_CSR_FRDE, 0); -- regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), -+ regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset), - FSL_SAI_CSR_xIE_MASK, 0); - - /* Check if the opposite FRDE is also disabled */ -- regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr); -+ regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, offset), &xcsr); - if (!(xcsr & FSL_SAI_CSR_FRDE)) { - /* Disable both directions and reset their FIFOs */ -- regmap_update_bits(sai->regmap, FSL_SAI_TCSR, -+ regmap_update_bits(sai->regmap, FSL_SAI_TCSR(offset), - FSL_SAI_CSR_TERE, 0); -- regmap_update_bits(sai->regmap, FSL_SAI_RCSR, -+ regmap_update_bits(sai->regmap, FSL_SAI_RCSR(offset), - FSL_SAI_CSR_TERE, 0); - - /* TERE will remain set till the end of current frame */ - do { - udelay(10); -- regmap_read(sai->regmap, FSL_SAI_xCSR(tx), &xcsr); -+ regmap_read(sai->regmap, FSL_SAI_xCSR(tx, offset), &xcsr); - } while (--count && xcsr & FSL_SAI_CSR_TERE); - -- regmap_update_bits(sai->regmap, FSL_SAI_TCSR, -+ regmap_update_bits(sai->regmap, FSL_SAI_TCSR(offset), - FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); -- regmap_update_bits(sai->regmap, FSL_SAI_RCSR, -+ regmap_update_bits(sai->regmap, FSL_SAI_RCSR(offset), - FSL_SAI_CSR_FR, FSL_SAI_CSR_FR); - - /* -@@ -654,12 +659,12 @@ static int fsl_sai_trigger(struct snd_pc - if (!sai->slave_mode[tx]) { - /* Software Reset for both Tx and Rx */ - regmap_write(sai->regmap, -- FSL_SAI_TCSR, FSL_SAI_CSR_SR); -+ FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR); - regmap_write(sai->regmap, -- FSL_SAI_RCSR, FSL_SAI_CSR_SR); -+ FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR); - /* Clear SR bit to finish the reset */ -- regmap_write(sai->regmap, FSL_SAI_TCSR, 0); -- regmap_write(sai->regmap, FSL_SAI_RCSR, 0); -+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0); -+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0); - } - } - break; -@@ -674,6 +679,7 @@ static int fsl_sai_startup(struct snd_pc - struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -+ unsigned char offset = sai->soc->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - int ret; - -@@ -682,7 +688,8 @@ static int fsl_sai_startup(struct snd_pc - else - sai->is_stream_opened[tx] = true; - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE0|FSL_SAI_CR3_TRCE1, -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -+ FSL_SAI_CR3_TRCE_MASK, - FSL_SAI_CR3_TRCE(sai->dataline[tx])); - - ret = snd_pcm_hw_constraint_list(substream->runtime, 0, -@@ -695,12 +702,14 @@ static void fsl_sai_shutdown(struct snd_ - struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -+ unsigned char offset = sai->soc->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); - - if (sai->is_stream_opened[tx]) { -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE0 | FSL_SAI_CR3_TRCE1, 0); -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -+ FSL_SAI_CR3_TRCE_MASK, 0); - sai->is_stream_opened[tx] = false; - } - } -@@ -719,17 +728,18 @@ static const struct snd_soc_dai_ops fsl_ - static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); -+ unsigned char offset = sai->soc->reg_offset; - - /* Software Reset for both Tx and Rx */ -- regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); -- regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); -+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR); -+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR); - /* Clear SR bit to finish the reset */ -- regmap_write(sai->regmap, FSL_SAI_TCSR, 0); -- regmap_write(sai->regmap, FSL_SAI_RCSR, 0); -+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0); -+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0); - -- regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR1(offset), FSL_SAI_CR1_RFW_MASK, - sai->soc->fifo_depth - FSL_SAI_MAXBURST_TX); -- regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR1(offset), FSL_SAI_CR1_RFW_MASK, - FSL_SAI_MAXBURST_RX - 1); - - snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, -@@ -767,41 +777,55 @@ static const struct snd_soc_component_dr - .name = "fsl-sai", - }; - --static struct reg_default fsl_sai_reg_defaults[] = { -- {FSL_SAI_TCR1, 0}, -- {FSL_SAI_TCR2, 0}, -- {FSL_SAI_TCR3, 0}, -- {FSL_SAI_TCR4, 0}, -- {FSL_SAI_TCR5, 0}, -+static struct reg_default fsl_sai_v2_reg_defaults[] = { -+ {FSL_SAI_TCR1(0), 0}, -+ {FSL_SAI_TCR2(0), 0}, -+ {FSL_SAI_TCR3(0), 0}, -+ {FSL_SAI_TCR4(0), 0}, -+ {FSL_SAI_TCR5(0), 0}, -+ {FSL_SAI_TDR0, 0}, -+ {FSL_SAI_TDR1, 0}, -+ {FSL_SAI_TMR, 0}, -+ {FSL_SAI_RCR1(0), 0}, -+ {FSL_SAI_RCR2(0), 0}, -+ {FSL_SAI_RCR3(0), 0}, -+ {FSL_SAI_RCR4(0), 0}, -+ {FSL_SAI_RCR5(0), 0}, -+ {FSL_SAI_RMR, 0}, -+}; -+ -+static struct reg_default fsl_sai_v3_reg_defaults[] = { -+ {FSL_SAI_TCR1(8), 0}, -+ {FSL_SAI_TCR2(8), 0}, -+ {FSL_SAI_TCR3(8), 0}, -+ {FSL_SAI_TCR4(8), 0}, -+ {FSL_SAI_TCR5(8), 0}, - {FSL_SAI_TDR0, 0}, - {FSL_SAI_TDR1, 0}, - {FSL_SAI_TMR, 0}, -- {FSL_SAI_RCR1, 0}, -- {FSL_SAI_RCR2, 0}, -- {FSL_SAI_RCR3, 0}, -- {FSL_SAI_RCR4, 0}, -- {FSL_SAI_RCR5, 0}, -+ {FSL_SAI_RCR1(8), 0}, -+ {FSL_SAI_RCR2(8), 0}, -+ {FSL_SAI_RCR3(8), 0}, -+ {FSL_SAI_RCR4(8), 0}, -+ {FSL_SAI_RCR5(8), 0}, - {FSL_SAI_RMR, 0}, - }; - - static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) - { -+ struct fsl_sai *sai = dev_get_drvdata(dev); -+ unsigned char offset = sai->soc->reg_offset; -+ -+ if (reg >= FSL_SAI_TCSR(offset) && reg <= FSL_SAI_TCR5(offset)) -+ return true; -+ -+ if (reg >= FSL_SAI_RCSR(offset) && reg <= FSL_SAI_RCR5(offset)) -+ return true; -+ - switch (reg) { -- case FSL_SAI_TCSR: -- case FSL_SAI_TCR1: -- case FSL_SAI_TCR2: -- case FSL_SAI_TCR3: -- case FSL_SAI_TCR4: -- case FSL_SAI_TCR5: - case FSL_SAI_TFR0: - case FSL_SAI_TFR1: - case FSL_SAI_TMR: -- case FSL_SAI_RCSR: -- case FSL_SAI_RCR1: -- case FSL_SAI_RCR2: -- case FSL_SAI_RCR3: -- case FSL_SAI_RCR4: -- case FSL_SAI_RCR5: - case FSL_SAI_RDR0: - case FSL_SAI_RDR1: - case FSL_SAI_RFR0: -@@ -815,9 +839,13 @@ static bool fsl_sai_readable_reg(struct - - static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg) - { -+ struct fsl_sai *sai = dev_get_drvdata(dev); -+ unsigned char offset = sai->soc->reg_offset; -+ -+ if (reg == FSL_SAI_TCSR(offset) || reg == FSL_SAI_RCSR(offset)) -+ return true; -+ - switch (reg) { -- case FSL_SAI_TCSR: -- case FSL_SAI_RCSR: - case FSL_SAI_TFR0: - case FSL_SAI_TFR1: - case FSL_SAI_RFR0: -@@ -832,22 +860,19 @@ static bool fsl_sai_volatile_reg(struct - - static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg) - { -+ struct fsl_sai *sai = dev_get_drvdata(dev); -+ unsigned char offset = sai->soc->reg_offset; -+ -+ if (reg >= FSL_SAI_TCSR(offset) && reg <= FSL_SAI_TCR5(offset)) -+ return true; -+ -+ if (reg >= FSL_SAI_RCSR(offset) && reg <= FSL_SAI_RCR5(offset)) -+ return true; -+ - switch (reg) { -- case FSL_SAI_TCSR: -- case FSL_SAI_TCR1: -- case FSL_SAI_TCR2: -- case FSL_SAI_TCR3: -- case FSL_SAI_TCR4: -- case FSL_SAI_TCR5: - case FSL_SAI_TDR0: - case FSL_SAI_TDR1: - case FSL_SAI_TMR: -- case FSL_SAI_RCSR: -- case FSL_SAI_RCR1: -- case FSL_SAI_RCR2: -- case FSL_SAI_RCR3: -- case FSL_SAI_RCR4: -- case FSL_SAI_RCR5: - case FSL_SAI_RMR: - return true; - default: -@@ -855,14 +880,28 @@ static bool fsl_sai_writeable_reg(struct - } - } - --static const struct regmap_config fsl_sai_regmap_config = { -+static const struct regmap_config fsl_sai_v2_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - - .max_register = FSL_SAI_RMR, -- .reg_defaults = fsl_sai_reg_defaults, -- .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults), -+ .reg_defaults = fsl_sai_v2_reg_defaults, -+ .num_reg_defaults = ARRAY_SIZE(fsl_sai_v2_reg_defaults), -+ .readable_reg = fsl_sai_readable_reg, -+ .volatile_reg = fsl_sai_volatile_reg, -+ .writeable_reg = fsl_sai_writeable_reg, -+ .cache_type = REGCACHE_FLAT, -+}; -+ -+static const struct regmap_config fsl_sai_v3_regmap_config = { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ -+ .max_register = FSL_SAI_RMR, -+ .reg_defaults = fsl_sai_v3_reg_defaults, -+ .num_reg_defaults = ARRAY_SIZE(fsl_sai_v3_reg_defaults), - .readable_reg = fsl_sai_readable_reg, - .volatile_reg = fsl_sai_volatile_reg, - .writeable_reg = fsl_sai_writeable_reg, -@@ -874,6 +913,7 @@ static const struct of_device_id fsl_sai - { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx }, - { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6ul }, - { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp }, -+ { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, fsl_sai_ids); -@@ -889,7 +929,8 @@ static int fsl_sai_probe(struct platform - char tmp[8]; - int irq, ret, i; - int index; -- unsigned long irqflag = 0; -+ struct regmap_config fsl_sai_regmap_config = fsl_sai_v2_regmap_config; -+ unsigned long irqflags = 0; - - sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); - if (!sai) -@@ -909,6 +950,9 @@ static int fsl_sai_probe(struct platform - if (IS_ERR(base)) - return PTR_ERR(base); - -+ if (sai->soc->reg_offset == 8) -+ fsl_sai_regmap_config = fsl_sai_v3_regmap_config; -+ - sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, - "bus", base, &fsl_sai_regmap_config); - -@@ -963,11 +1007,11 @@ static int fsl_sai_probe(struct platform - } - - /* SAI shared interrupt */ -- if (of_property_read_bool(np, "shared-interrupt")) -- irqflag = IRQF_SHARED; -+ if (of_property_read_bool(np, "fsl,shared-interrupt")) -+ irqflags = IRQF_SHARED; - -- ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, irqflag, -- np->name, sai); -+ ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, irqflags, np->name, -+ sai); - if (ret) { - dev_err(&pdev->dev, "failed to claim irq %u\n", irq); - return ret; -@@ -1091,6 +1135,7 @@ static int fsl_sai_runtime_suspend(struc - static int fsl_sai_runtime_resume(struct device *dev) - { - struct fsl_sai *sai = dev_get_drvdata(dev); -+ unsigned char offset = sai->soc->reg_offset; - int ret; - - ret = clk_prepare_enable(sai->bus_clk); -@@ -1116,11 +1161,11 @@ static int fsl_sai_runtime_resume(struct - PM_QOS_CPU_DMA_LATENCY, 0); - - regcache_cache_only(sai->regmap, false); -- regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); -- regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); -+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR); -+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR); - usleep_range(1000, 2000); -- regmap_write(sai->regmap, FSL_SAI_TCSR, 0); -- regmap_write(sai->regmap, FSL_SAI_RCSR, 0); -+ regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0); -+ regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0); - - ret = regcache_sync(sai->regmap); - if (ret) ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -14,38 +14,36 @@ - SNDRV_PCM_FMTBIT_S32_LE) - - /* SAI Register Map Register */ --#define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */ --#define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */ --#define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */ --#define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */ --#define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */ --#define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */ -+#define FSL_SAI_TCSR(offset) (0x00 + offset) /* SAI Transmit Control */ -+#define FSL_SAI_TCR1(offset) (0x04 + offset) /* SAI Transmit Configuration 1 */ -+#define FSL_SAI_TCR2(offset) (0x08 + offset) /* SAI Transmit Configuration 2 */ -+#define FSL_SAI_TCR3(offset) (0x0c + offset) /* SAI Transmit Configuration 3 */ -+#define FSL_SAI_TCR4(offset) (0x10 + offset) /* SAI Transmit Configuration 4 */ -+#define FSL_SAI_TCR5(offset) (0x14 + offset) /* SAI Transmit Configuration 5 */ - #define FSL_SAI_TDR0 0x20 /* SAI Transmit Data */ - #define FSL_SAI_TDR1 0x24 /* SAI Transmit Data */ - #define FSL_SAI_TFR0 0x40 /* SAI Transmit FIFO */ - #define FSL_SAI_TFR1 0x44 /* SAI Transmit FIFO */ - #define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */ - #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ --#define FSL_SAI_RCSR 0x80 /* SAI Receive Control */ --#define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */ --#define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */ --#define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */ --#define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */ --#define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */ -+#define FSL_SAI_RCSR(offset) (0x80 + offset) /* SAI Receive Control */ -+#define FSL_SAI_RCR1(offset) (0x84 + offset) /* SAI Receive Configuration 1 */ -+#define FSL_SAI_RCR2(offset) (0x88 + offset) /* SAI Receive Configuration 2 */ -+#define FSL_SAI_RCR3(offset) (0x8c + offset) /* SAI Receive Configuration 3 */ -+#define FSL_SAI_RCR4(offset) (0x90 + offset) /* SAI Receive Configuration 4 */ -+#define FSL_SAI_RCR5(offset) (0x94 + offset) /* SAI Receive Configuration 5 */ - #define FSL_SAI_RDR0 0xa0 /* SAI Receive Data */ - #define FSL_SAI_RDR1 0xa4 /* SAI Receive Data */ - #define FSL_SAI_RFR0 0xc0 /* SAI Receive FIFO */ - #define FSL_SAI_RFR1 0xc4 /* SAI Receive FIFO */ - #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ - --#define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR) --#define FSL_SAI_xCR1(tx) (tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1) --#define FSL_SAI_xCR2(tx) (tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2) --#define FSL_SAI_xCR3(tx) (tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3) --#define FSL_SAI_xCR4(tx) (tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4) --#define FSL_SAI_xCR5(tx) (tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5) --#define FSL_SAI_xDR(tx) (tx ? FSL_SAI_TDR : FSL_SAI_RDR) --#define FSL_SAI_xFR(tx) (tx ? FSL_SAI_TFR : FSL_SAI_RFR) -+#define FSL_SAI_xCSR(tx, off) (tx ? FSL_SAI_TCSR(off) : FSL_SAI_RCSR(off)) -+#define FSL_SAI_xCR1(tx, off) (tx ? FSL_SAI_TCR1(off) : FSL_SAI_RCR1(off)) -+#define FSL_SAI_xCR2(tx, off) (tx ? FSL_SAI_TCR2(off) : FSL_SAI_RCR2(off)) -+#define FSL_SAI_xCR3(tx, off) (tx ? FSL_SAI_TCR3(off) : FSL_SAI_RCR3(off)) -+#define FSL_SAI_xCR4(tx, off) (tx ? FSL_SAI_TCR4(off) : FSL_SAI_RCR4(off)) -+#define FSL_SAI_xCR5(tx, off) (tx ? FSL_SAI_TCR5(off) : FSL_SAI_RCR5(off)) - #define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR) - - /* SAI Transmit/Receive Control Register */ -@@ -87,8 +85,7 @@ - #define FSL_SAI_CR2_DIV_MASK 0xff - - /* SAI Transmit and Receive Configuration 3 Register */ --#define FSL_SAI_CR3_TRCE0 BIT(16) --#define FSL_SAI_CR3_TRCE1 BIT(17) -+#define FSL_SAI_CR3_TRCE_MASK (0xff << 16) - #define FSL_SAI_CR3_TRCE(x) (x << 16) - #define FSL_SAI_CR3_WDFL(x) (x) - #define FSL_SAI_CR3_WDFL_MASK 0x1f -@@ -98,6 +95,7 @@ - #define FSL_SAI_CR4_FCONT BIT(28) - #define FSL_SAI_CR4_FCOMB_SHIFT BIT(26) - #define FSL_SAI_CR4_FCOMB_SOFT BIT(27) -+#define FSL_SAI_CR4_FCOMB_MASK (0x3 << 26) - #define FSL_SAI_CR4_FPACK_8 (0x2 << 24) - #define FSL_SAI_CR4_FPACK_16 (0x3 << 24) - #define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16) -@@ -147,6 +145,7 @@ struct fsl_sai_soc_data { - unsigned int fifos; - unsigned int dataline; - unsigned int flags; -+ unsigned char reg_offset; - bool imx; - }; - diff --git a/target/linux/layerscape/patches-5.4/801-audio-0028-MLK-15927-1-ASoC-fsl_sai-Fix-noise-when-using-EDMA.patch b/target/linux/layerscape/patches-5.4/801-audio-0028-MLK-15927-1-ASoC-fsl_sai-Fix-noise-when-using-EDMA.patch deleted file mode 100644 index 71554d295a..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0028-MLK-15927-1-ASoC-fsl_sai-Fix-noise-when-using-EDMA.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 3b671c297cff1ba5f5c3e089ffa82523eca3c598 Mon Sep 17 00:00:00 2001 -From: Mihai Serban -Date: Fri, 7 Jul 2017 15:09:51 +0300 -Subject: [PATCH] MLK-15927-1: ASoC: fsl_sai: Fix noise when using EDMA - -EDMA requires the period size to be multiple of maxburst. Otherwise the -remaining bytes are not transferred and thus noise is produced. - -We can handle this issue by adding a constraint on -SNDRV_PCM_HW_PARAM_PERIOD_SIZE to be multiple of tx/rx maxburst value. - -This is based on a similar patch we have for ESAI: -commit bd3f3eb2a37c -("MLK-15109-2: ASoC: fsl_esai: add constrain_period_size") - -Signed-off-by: Mihai Serban -Reviewed-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 23 +++++++++++++++++++++++ - sound/soc/fsl/fsl_sai.h | 2 ++ - 2 files changed, 25 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -35,6 +35,7 @@ static struct fsl_sai_soc_data fsl_sai_v - .fifos = 1, - .fifo_depth = 32, - .flags = 0, -+ .constrain_period_size = false, - }; - - static struct fsl_sai_soc_data fsl_sai_imx6sx = { -@@ -44,6 +45,7 @@ static struct fsl_sai_soc_data fsl_sai_i - .fifo_depth = 32, - .flags = 0, - .reg_offset = 0, -+ .constrain_period_size = false, - }; - - static struct fsl_sai_soc_data fsl_sai_imx6ul = { -@@ -53,6 +55,7 @@ static struct fsl_sai_soc_data fsl_sai_i - .fifo_depth = 32, - .flags = 0, - .reg_offset = 0, -+ .constrain_period_size = false, - }; - - static struct fsl_sai_soc_data fsl_sai_imx7ulp = { -@@ -62,6 +65,7 @@ static struct fsl_sai_soc_data fsl_sai_i - .fifo_depth = 16, - .flags = SAI_FLAG_PMQOS, - .reg_offset = 0, -+ .constrain_period_size = false, - }; - - static struct fsl_sai_soc_data fsl_sai_imx8mq = { -@@ -71,6 +75,17 @@ static struct fsl_sai_soc_data fsl_sai_i - .fifo_depth = 32, - .flags = 0, - .reg_offset = 8, -+ .constrain_period_size = false, -+}; -+ -+static struct fsl_sai_soc_data fsl_sai_imx8qm = { -+ .imx = true, -+ .dataline = 0x3, -+ .fifos = 1, -+ .fifo_depth = 32, -+ .flags = 0, -+ .reg_offset = 0, -+ .constrain_period_size = true, - }; - - static const unsigned int fsl_sai_rates[] = { -@@ -692,6 +707,13 @@ static int fsl_sai_startup(struct snd_pc - FSL_SAI_CR3_TRCE_MASK, - FSL_SAI_CR3_TRCE(sai->dataline[tx])); - -+ /* EDMA engine needs periods of size multiple of tx/rx maxburst */ -+ if (sai->soc->constrain_period_size) -+ snd_pcm_hw_constraint_step(substream->runtime, 0, -+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -+ tx ? sai->dma_params_tx.maxburst : -+ sai->dma_params_rx.maxburst); -+ - ret = snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints); - -@@ -914,6 +936,7 @@ static const struct of_device_id fsl_sai - { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6ul }, - { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp }, - { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq }, -+ { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm }, - { /* sentinel */ } - }; - MODULE_DEVICE_TABLE(of, fsl_sai_ids); ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -147,6 +147,8 @@ struct fsl_sai_soc_data { - unsigned int flags; - unsigned char reg_offset; - bool imx; -+ /* True for EDMA because it needs period size multiple of maxburst */ -+ bool constrain_period_size; - }; - - struct fsl_sai { diff --git a/target/linux/layerscape/patches-5.4/801-audio-0029-MLK-15960-1-ASoC-fsl_sai-update-fifo_depth-for-diffe.patch b/target/linux/layerscape/patches-5.4/801-audio-0029-MLK-15960-1-ASoC-fsl_sai-update-fifo_depth-for-diffe.patch deleted file mode 100644 index d2a7955cae..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0029-MLK-15960-1-ASoC-fsl_sai-update-fifo_depth-for-diffe.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 1640daf71d5230997e9b75a550d3800bede298db Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Wed, 12 Jul 2017 18:19:25 +0800 -Subject: [PATCH] MLK-15960-1: ASoC: fsl_sai: update fifo_depth for different - platform - -The fifo_depth is changed to 64 in imx8qm/imx8qxp, in imx8mq, the -fifo_depth is 128. which is mentioned in their ADD. - -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -72,7 +72,7 @@ static struct fsl_sai_soc_data fsl_sai_i - .imx = true, - .dataline = 0xff, - .fifos = 8, -- .fifo_depth = 32, -+ .fifo_depth = 128, - .flags = 0, - .reg_offset = 8, - .constrain_period_size = false, -@@ -82,7 +82,7 @@ static struct fsl_sai_soc_data fsl_sai_i - .imx = true, - .dataline = 0x3, - .fifos = 1, -- .fifo_depth = 32, -+ .fifo_depth = 64, - .flags = 0, - .reg_offset = 0, - .constrain_period_size = true, -@@ -759,10 +759,12 @@ static int fsl_sai_dai_probe(struct snd_ - regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0); - regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0); - -- regmap_update_bits(sai->regmap, FSL_SAI_TCR1(offset), FSL_SAI_CR1_RFW_MASK, -- sai->soc->fifo_depth - FSL_SAI_MAXBURST_TX); -- regmap_update_bits(sai->regmap, FSL_SAI_RCR1(offset), FSL_SAI_CR1_RFW_MASK, -- FSL_SAI_MAXBURST_RX - 1); -+ regmap_update_bits(sai->regmap, FSL_SAI_TCR1(offset), -+ sai->soc->fifo_depth - 1, -+ sai->soc->fifo_depth - FSL_SAI_MAXBURST_TX); -+ regmap_update_bits(sai->regmap, FSL_SAI_RCR1(offset), -+ sai->soc->fifo_depth - 1, -+ FSL_SAI_MAXBURST_RX - 1); - - snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, - &sai->dma_params_rx); diff --git a/target/linux/layerscape/patches-5.4/801-audio-0030-MLK-15960-2-ASoC-fsl_sai-refine-the-pm-runtime-funct.patch b/target/linux/layerscape/patches-5.4/801-audio-0030-MLK-15960-2-ASoC-fsl_sai-refine-the-pm-runtime-funct.patch deleted file mode 100644 index 03201fea90..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0030-MLK-15960-2-ASoC-fsl_sai-refine-the-pm-runtime-funct.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 136762e82a9c4974c15b0525245092d11a825cee Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Wed, 12 Jul 2017 18:00:58 +0800 -Subject: [PATCH] MLK-15960-2: ASoC: fsl_sai: refine the pm runtime function - -In imx8qm/imx8qxp, the power domain of IP is enabled when -pm_runtime_get_sync() is called, and disabled when pm_runtime -_put_sync() is called. when power domain is disabled, the value -of registers will lost, so we need to use the regcache_sync() -to restore the registers in fsl_sai_runtime_resume. - -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -1097,6 +1097,8 @@ static int fsl_sai_probe(struct platform - - pm_runtime_enable(&pdev->dev); - -+ regcache_cache_only(sai->regmap, true); -+ - ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, - &sai->cpu_dai_drv, 1); - if (ret) -@@ -1140,6 +1142,8 @@ static int fsl_sai_runtime_suspend(struc - { - struct fsl_sai *sai = dev_get_drvdata(dev); - -+ regcache_cache_only(sai->regmap, true); -+ - if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) - clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]); - diff --git a/target/linux/layerscape/patches-5.4/801-audio-0031-MLK-13975-ASoC-fsl_sai-Refine-master-flag-handling.patch b/target/linux/layerscape/patches-5.4/801-audio-0031-MLK-13975-ASoC-fsl_sai-Refine-master-flag-handling.patch deleted file mode 100644 index cc60638f2b..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0031-MLK-13975-ASoC-fsl_sai-Refine-master-flag-handling.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 45ef8360c3ce459342994cdcfbf140e876b5490b Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Tue, 11 Jul 2017 08:26:44 +0300 -Subject: [PATCH] MLK-13975: ASoC: fsl_sai: Refine master flag handling - -The patch introduces the master flag handling -as function of direction and the option to provide -the flag value from DTS. - -Signed-off-by: Shengjiu Wang -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 27 +++++++++++++++++++-------- - sound/soc/fsl/fsl_sai.h | 2 +- - 2 files changed, 20 insertions(+), 9 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -368,9 +368,9 @@ static int fsl_sai_set_dai_fmt(struct sn - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - int ret; - -- if (sai->i2s_xtor) -- fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -- SND_SOC_DAIFMT_CBS_CFS; -+ if (sai->masterflag[FSL_FMT_TRANSMITTER]) -+ fmt = (fmt & (~SND_SOC_DAIFMT_MASTER_MASK)) | -+ sai->masterflag[FSL_FMT_TRANSMITTER]; - - ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER); - if (ret) { -@@ -378,9 +378,9 @@ static int fsl_sai_set_dai_fmt(struct sn - return ret; - } - -- if (sai->i2s_xtor) -- fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -- SND_SOC_DAIFMT_CBM_CFM; -+ if (sai->masterflag[FSL_FMT_RECEIVER]) -+ fmt = (fmt & (~SND_SOC_DAIFMT_MASTER_MASK)) | -+ sai->masterflag[FSL_FMT_RECEIVER]; - - ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER); - if (ret) -@@ -1022,8 +1022,19 @@ static int fsl_sai_probe(struct platform - return -EINVAL; - } - -- /* I2S XTOR mode */ -- sai->i2s_xtor = (of_find_property(np, "fsl,i2s-xtor", NULL) != NULL); -+ if ((of_find_property(np, "fsl,i2s-xtor", NULL) != NULL) || -+ (of_find_property(np, "fsl,txm-rxs", NULL) != NULL)) -+ { -+ sai->masterflag[FSL_FMT_TRANSMITTER] = SND_SOC_DAIFMT_CBS_CFS; -+ sai->masterflag[FSL_FMT_RECEIVER] = SND_SOC_DAIFMT_CBM_CFM; -+ } else { -+ if (!of_property_read_u32(np, "fsl,txmasterflag", -+ &sai->masterflag[FSL_FMT_TRANSMITTER])) -+ sai->masterflag[FSL_FMT_TRANSMITTER] <<= 12; -+ if (!of_property_read_u32(np, "fsl,rxmasterflag", -+ &sai->masterflag[FSL_FMT_RECEIVER])) -+ sai->masterflag[FSL_FMT_RECEIVER] <<= 12; -+ } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -160,10 +160,10 @@ struct fsl_sai { - bool slave_mode[2]; - bool is_lsb_first; - bool is_dsp_mode; -- bool i2s_xtor; - bool synchronous[2]; - bool is_stream_opened[2]; - unsigned int dataline[2]; -+ unsigned int masterflag[2]; - - unsigned int mclk_id[2]; - unsigned int mclk_streams; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0032-MLK-16130-1-ASoC-fsl_sai-enable-TCE-RCE-according-to.patch b/target/linux/layerscape/patches-5.4/801-audio-0032-MLK-16130-1-ASoC-fsl_sai-enable-TCE-RCE-according-to.patch deleted file mode 100644 index 25275a27a2..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0032-MLK-16130-1-ASoC-fsl_sai-enable-TCE-RCE-according-to.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 1b4638a9fa32d8a786e71a2a8813b2e1a3c15830 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Tue, 1 Aug 2017 16:10:38 +0800 -Subject: [PATCH] MLK-16130-1: ASoC: fsl_sai: enable TCE/RCE according to input - channels - -If there is only two channels input and slots is 2, then enable one -port is enough for data transfer. so enable the TCE/RCE according to -the input channels and slots configuration. - -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -487,11 +487,14 @@ static int fsl_sai_hw_params(struct snd_ - u32 val_cr4 = 0, val_cr5 = 0; - u32 slots = (channels == 1) ? 2 : channels; - u32 slot_width = word_width; -+ u32 pins; - int ret; - - if (sai->slots) - slots = sai->slots; - -+ pins = DIV_ROUND_UP(channels, slots); -+ - if (sai->slot_width) - slot_width = sai->slot_width; - -@@ -558,6 +561,10 @@ static int fsl_sai_hw_params(struct snd_ - FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT); - } - -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -+ FSL_SAI_CR3_TRCE_MASK, -+ FSL_SAI_CR3_TRCE((sai->dataline[tx] & ((1 << pins) - 1)))); -+ - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, - val_cr4); -@@ -573,8 +580,12 @@ static int fsl_sai_hw_free(struct snd_pc - struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -+ unsigned char offset = sai->soc->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -+ FSL_SAI_CR3_TRCE_MASK, 0); -+ - if (!sai->slave_mode[tx] && - sai->mclk_streams & BIT(substream->stream)) { - clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]); -@@ -694,7 +705,6 @@ static int fsl_sai_startup(struct snd_pc - struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -- unsigned char offset = sai->soc->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - int ret; - -@@ -724,7 +734,6 @@ static void fsl_sai_shutdown(struct snd_ - struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -- unsigned char offset = sai->soc->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); diff --git a/target/linux/layerscape/patches-5.4/801-audio-0033-MLK-13946-3-ASoC-fsl_sai-fix-the-xMR-setting.patch b/target/linux/layerscape/patches-5.4/801-audio-0033-MLK-13946-3-ASoC-fsl_sai-fix-the-xMR-setting.patch deleted file mode 100644 index c353ba4ae4..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0033-MLK-13946-3-ASoC-fsl_sai-fix-the-xMR-setting.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 9d00118e0ac420d3bf6e266a0fbfd28135cbadb8 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Thu, 12 Oct 2017 14:01:19 +0800 -Subject: [PATCH] MLK-13946-3: ASoC: fsl_sai: fix the xMR setting - -When there is multi data line enabled, the xMR setting is -wrong if according to the channel number. which should -according to the slot number - -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 28 ++++++++++++++++++++++++++-- - sound/soc/fsl/fsl_sai.h | 12 ++++++++++++ - 2 files changed, 38 insertions(+), 2 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -80,7 +80,7 @@ static struct fsl_sai_soc_data fsl_sai_i - - static struct fsl_sai_soc_data fsl_sai_imx8qm = { - .imx = true, -- .dataline = 0x3, -+ .dataline = 0xf, - .fifos = 1, - .fifo_depth = 64, - .flags = 0, -@@ -571,7 +571,7 @@ static int fsl_sai_hw_params(struct snd_ - regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, offset), - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); -- regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1)); -+ regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << slots) - 1)); - - return 0; - } -@@ -858,11 +858,23 @@ static bool fsl_sai_readable_reg(struct - switch (reg) { - case FSL_SAI_TFR0: - case FSL_SAI_TFR1: -+ case FSL_SAI_TFR2: -+ case FSL_SAI_TFR3: -+ case FSL_SAI_TFR4: -+ case FSL_SAI_TFR5: -+ case FSL_SAI_TFR6: -+ case FSL_SAI_TFR7: - case FSL_SAI_TMR: - case FSL_SAI_RDR0: - case FSL_SAI_RDR1: - case FSL_SAI_RFR0: - case FSL_SAI_RFR1: -+ case FSL_SAI_RFR2: -+ case FSL_SAI_RFR3: -+ case FSL_SAI_RFR4: -+ case FSL_SAI_RFR5: -+ case FSL_SAI_RFR6: -+ case FSL_SAI_RFR7: - case FSL_SAI_RMR: - return true; - default: -@@ -881,8 +893,20 @@ static bool fsl_sai_volatile_reg(struct - switch (reg) { - case FSL_SAI_TFR0: - case FSL_SAI_TFR1: -+ case FSL_SAI_TFR2: -+ case FSL_SAI_TFR3: -+ case FSL_SAI_TFR4: -+ case FSL_SAI_TFR5: -+ case FSL_SAI_TFR6: -+ case FSL_SAI_TFR7: - case FSL_SAI_RFR0: - case FSL_SAI_RFR1: -+ case FSL_SAI_RFR2: -+ case FSL_SAI_RFR3: -+ case FSL_SAI_RFR4: -+ case FSL_SAI_RFR5: -+ case FSL_SAI_RFR6: -+ case FSL_SAI_RFR7: - case FSL_SAI_RDR0: - case FSL_SAI_RDR1: - return true; ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -24,6 +24,12 @@ - #define FSL_SAI_TDR1 0x24 /* SAI Transmit Data */ - #define FSL_SAI_TFR0 0x40 /* SAI Transmit FIFO */ - #define FSL_SAI_TFR1 0x44 /* SAI Transmit FIFO */ -+#define FSL_SAI_TFR2 0x48 /* SAI Transmit FIFO */ -+#define FSL_SAI_TFR3 0x4C /* SAI Transmit FIFO */ -+#define FSL_SAI_TFR4 0x50 /* SAI Transmit FIFO */ -+#define FSL_SAI_TFR5 0x54 /* SAI Transmit FIFO */ -+#define FSL_SAI_TFR6 0x58 /* SAI Transmit FIFO */ -+#define FSL_SAI_TFR7 0x5C /* SAI Transmit FIFO */ - #define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */ - #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ - #define FSL_SAI_RCSR(offset) (0x80 + offset) /* SAI Receive Control */ -@@ -36,6 +42,12 @@ - #define FSL_SAI_RDR1 0xa4 /* SAI Receive Data */ - #define FSL_SAI_RFR0 0xc0 /* SAI Receive FIFO */ - #define FSL_SAI_RFR1 0xc4 /* SAI Receive FIFO */ -+#define FSL_SAI_RFR2 0xc8 /* SAI Receive FIFO */ -+#define FSL_SAI_RFR3 0xcc /* SAI Receive FIFO */ -+#define FSL_SAI_RFR4 0xd0 /* SAI Receive FIFO */ -+#define FSL_SAI_RFR5 0xd4 /* SAI Receive FIFO */ -+#define FSL_SAI_RFR6 0xd8 /* SAI Receive FIFO */ -+#define FSL_SAI_RFR7 0xdc /* SAI Receive FIFO */ - #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ - - #define FSL_SAI_xCSR(tx, off) (tx ? FSL_SAI_TCSR(off) : FSL_SAI_RCSR(off)) diff --git a/target/linux/layerscape/patches-5.4/801-audio-0034-MLK-13946-8-ASoC-fsl_sai-use-min-channels-slots-for-.patch b/target/linux/layerscape/patches-5.4/801-audio-0034-MLK-13946-8-ASoC-fsl_sai-use-min-channels-slots-for-.patch deleted file mode 100644 index ab89291189..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0034-MLK-13946-8-ASoC-fsl_sai-use-min-channels-slots-for-.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 283d3a9e253d2cefd915ee7f891c24edc3e6d6d0 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Tue, 24 Oct 2017 13:09:27 +0300 -Subject: [PATCH] MLK-13946-8: ASoC: fsl_sai: use min(channels,slots) for xMR - setting - -xMR setting must be set as min(channels,slots) since -both "channels < slots" and "channels > slots" scenarios -are possible. - -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -571,8 +571,8 @@ static int fsl_sai_hw_params(struct snd_ - regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, offset), - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); -- regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << slots) - 1)); -- -+ regmap_write(sai->regmap, FSL_SAI_xMR(tx), -+ ~0UL - ((1 << min(channels, slots)) - 1)); - return 0; - } - diff --git a/target/linux/layerscape/patches-5.4/801-audio-0035-MLK-16929-1-ASoC-fsl_sai-add-bitclk_freq.patch b/target/linux/layerscape/patches-5.4/801-audio-0035-MLK-16929-1-ASoC-fsl_sai-add-bitclk_freq.patch deleted file mode 100644 index c095f5ff35..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0035-MLK-16929-1-ASoC-fsl_sai-add-bitclk_freq.patch +++ /dev/null @@ -1,55 +0,0 @@ -From d40566a2e9aa3c40be313b1fba9d5435c58ffd79 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Thu, 23 Nov 2017 13:32:13 +0800 -Subject: [PATCH] MLK-16929-1: ASoC: fsl_sai: add bitclk_freq - -Allow set SAI bit clock frequency trough snd_soc_dai_set_sysclk -function call on machine sound drivers. - -Signed-off-by: Shengjiu Wang -Signed-off-by: Adrian Alonso ---- - sound/soc/fsl/fsl_sai.c | 9 ++++++++- - sound/soc/fsl/fsl_sai.h | 1 + - 2 files changed, 9 insertions(+), 1 deletion(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -233,11 +233,14 @@ static int fsl_sai_set_dai_sysclk_tr(str - static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) - { -+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - int ret; - - if (dir == SND_SOC_CLOCK_IN) - return 0; - -+ sai->bitclk_freq = freq; -+ - ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, - FSL_FMT_TRANSMITTER); - if (ret) { -@@ -499,7 +502,11 @@ static int fsl_sai_hw_params(struct snd_ - slot_width = sai->slot_width; - - if (!sai->slave_mode[tx]) { -- ret = fsl_sai_set_bclk(cpu_dai, tx, -+ if (sai->bitclk_freq) -+ ret = fsl_sai_set_bclk(cpu_dai, tx, -+ sai->bitclk_freq); -+ else -+ ret = fsl_sai_set_bclk(cpu_dai, tx, - slots * slot_width * params_rate(params)); - if (ret) - return ret; ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -181,6 +181,7 @@ struct fsl_sai { - unsigned int mclk_streams; - unsigned int slots; - unsigned int slot_width; -+ unsigned int bitclk_freq; - - struct snd_soc_dai_driver cpu_dai_drv; - struct snd_dmaengine_dai_dma_data dma_params_rx; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0037-MLK-16224-4-ASoC-fsl_sai-support-multi-fifo-and-DSD.patch b/target/linux/layerscape/patches-5.4/801-audio-0037-MLK-16224-4-ASoC-fsl_sai-support-multi-fifo-and-DSD.patch deleted file mode 100644 index c2952deaab..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0037-MLK-16224-4-ASoC-fsl_sai-support-multi-fifo-and-DSD.patch +++ /dev/null @@ -1,326 +0,0 @@ -From 87f734fa8214b4ddbfdac9b7ac5dc75a3d86badb Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Tue, 23 Jan 2018 13:26:37 +0800 -Subject: [PATCH] MLK-16224-4: ASoC: fsl_sai: support multi fifo and DSD - -The codec always mux the LRCLK pin to DSD data line, so when -we want to support DSD, the pinmux is different. For two channel -DSD, the DSDL is mapped to TX0, but the DSDR is mapped to TX4, -there is address offset for the fifo address of TX0 and TX4, TX4's -fifo is not adjacent to TX0's. - -Usually, if mapping is TX0 and TX1, that will be easy for SAI -and SDMA to handle, that SAI can use the FIFO combine mode, SDMA -can use the normal script. - -so for DSD: -1. The SDMA should use the multi-fifo script, and SAI can't -use the FIFO combine mode. -2. driver should to check the dts configuration(fsl,dataline) for -which dataline is used corrently -3. maxburst is the multiply of datalines -4. each channel of DSD occupy one data lane -5. according to data lane, set TRCE bits - -Signed-off-by: Shengjiu Wang -Reviewed-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 162 +++++++++++++++++++++++++++++++++++++++++++++--- - sound/soc/fsl/fsl_sai.h | 12 +++- - 2 files changed, 164 insertions(+), 10 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -267,6 +267,7 @@ static int fsl_sai_set_dai_fmt_tr(struct - if (!sai->is_lsb_first) - val_cr4 |= FSL_SAI_CR4_MF; - -+ sai->is_dsp_mode = false; - /* DAI mode */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: -@@ -305,6 +306,11 @@ static int fsl_sai_set_dai_fmt_tr(struct - val_cr2 |= FSL_SAI_CR2_BCP; - sai->is_dsp_mode = true; - break; -+ case SND_SOC_DAIFMT_PDM: -+ val_cr2 |= FSL_SAI_CR2_BCP; -+ val_cr4 &= ~FSL_SAI_CR4_MF; -+ sai->is_dsp_mode = true; -+ break; - case SND_SOC_DAIFMT_RIGHT_J: - /* To be done */ - default: -@@ -492,12 +498,38 @@ static int fsl_sai_hw_params(struct snd_ - u32 slot_width = word_width; - u32 pins; - int ret; -+ int i; -+ int trce_mask = 0; -+ snd_pcm_format_t format = params_format(params); - - if (sai->slots) - slots = sai->slots; - - pins = DIV_ROUND_UP(channels, slots); - -+ if (format == SNDRV_PCM_FORMAT_DSD_U8 || -+ format == SNDRV_PCM_FORMAT_DSD_U16_LE || -+ format == SNDRV_PCM_FORMAT_DSD_U16_BE || -+ format == SNDRV_PCM_FORMAT_DSD_U32_LE || -+ format == SNDRV_PCM_FORMAT_DSD_U32_BE) { -+ sai->is_dsd = true; -+ -+ if (!IS_ERR_OR_NULL(sai->pins_dsd)) { -+ ret = pinctrl_select_state(sai->pinctrl, sai->pins_dsd); -+ if (ret) { -+ dev_err(cpu_dai->dev, -+ "failed to set proper pins state: %d\n", ret); -+ return ret; -+ } -+ } -+ } else { -+ pinctrl_pm_select_default_state(cpu_dai->dev); -+ sai->is_dsd = false; -+ } -+ -+ if (sai->is_dsd) -+ pins = channels; -+ - if (sai->slot_width) - slot_width = sai->slot_width; - -@@ -527,7 +559,7 @@ static int fsl_sai_hw_params(struct snd_ - val_cr5 |= FSL_SAI_CR5_WNW(slot_width); - val_cr5 |= FSL_SAI_CR5_W0W(slot_width); - -- if (sai->is_lsb_first) -+ if (sai->is_lsb_first || sai->is_dsd) - val_cr5 |= FSL_SAI_CR5_FBT(0); - else - val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); -@@ -560,17 +592,71 @@ static int fsl_sai_hw_params(struct snd_ - } - - if (sai->soc->dataline != 0x1) { -- if (sai->dataline[tx] <= 1) -+ -+ if (sai->dataline[tx] <= 1 || sai->is_multi_lane) - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_FCOMB_MASK, 0); - else - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT); -+ -+ if (sai->is_multi_lane) { -+ if (tx) { -+ sai->dma_params_tx.maxburst = -+ FSL_SAI_MAXBURST_TX * pins; -+ if (sai->is_dsd) -+ sai->dma_params_tx.fifo_num = pins + -+ (sai->dataline_off_dsd[tx] << 8); -+ else -+ sai->dma_params_tx.fifo_num = pins + -+ (sai->dataline_off[tx] << 8); -+ } else { -+ sai->dma_params_rx.maxburst = -+ FSL_SAI_MAXBURST_RX * pins; -+ if (sai->is_dsd) -+ sai->dma_params_rx.fifo_num = pins + -+ (sai->dataline_off_dsd[tx] << 8); -+ else -+ sai->dma_params_rx.fifo_num = pins + -+ (sai->dataline_off[tx] << 8); -+ } -+ } -+ -+ snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, -+ &sai->dma_params_rx); - } - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -+ if (sai->is_dsd) { -+ if (__sw_hweight8(sai->dataline_dsd[tx] & 0xFF) < pins) { -+ dev_err(cpu_dai->dev, "channel not supported\n"); -+ return -EINVAL; -+ } -+ /*find a proper tcre setting*/ -+ for (i = 0; i < 8; i++) { -+ trce_mask = (1 << (i + 1)) - 1; -+ if (__sw_hweight8(sai->dataline_dsd[tx] & trce_mask) == pins) -+ break; -+ } -+ -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), - FSL_SAI_CR3_TRCE_MASK, -- FSL_SAI_CR3_TRCE((sai->dataline[tx] & ((1 << pins) - 1)))); -+ FSL_SAI_CR3_TRCE((sai->dataline_dsd[tx] & trce_mask))); -+ } else { -+ if (__sw_hweight8(sai->dataline[tx] & 0xFF) < pins) { -+ dev_err(cpu_dai->dev, "channel not supported\n"); -+ return -EINVAL; -+ } -+ /*find a proper tcre setting*/ -+ for (i = 0; i < 8; i++) { -+ trce_mask = (1 << (i + 1)) - 1; -+ if (__sw_hweight8(sai->dataline[tx] & trce_mask) == pins) -+ break; -+ } -+ -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -+ FSL_SAI_CR3_TRCE_MASK, -+ FSL_SAI_CR3_TRCE((sai->dataline[tx] & trce_mask))); -+ } - - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -@@ -610,9 +696,18 @@ static int fsl_sai_trigger(struct snd_pc - unsigned char offset = sai->soc->reg_offset; - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - u8 channels = substream->runtime->channels; -+ u32 slots = (channels == 1) ? 2 : channels; - u32 xcsr, count = 100; -- int i; -+ u32 pins; -+ int i = 0, j = 0, k = 0; -+ -+ if (sai->slots) -+ slots = sai->slots; -+ -+ pins = DIV_ROUND_UP(channels, slots); - -+ if (sai->is_dsd) -+ pins = channels; - /* - * Asynchronous mode: Clear SYNC for both Tx and Rx. - * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. -@@ -631,10 +726,19 @@ static int fsl_sai_trigger(struct snd_pc - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -- for (i = 0; tx && i < channels; i++) -- regmap_write(sai->regmap, FSL_SAI_TDR0, 0x0); -- if (tx) -- udelay(10); -+ -+ for (i = 0; tx && i < channels; i++) { -+ while (tx && i < channels) -+ if (sai->dataline[tx] & (1 << j)) { -+ regmap_write(sai->regmap, FSL_SAI_TDR0 + j * 0x4, 0x0); -+ i++; -+ k++; -+ } -+ j++; -+ -+ if (k%pins == 0) -+ j = 0; -+ } - - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset), - FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); -@@ -994,6 +1098,7 @@ static int fsl_sai_probe(struct platform - char tmp[8]; - int irq, ret, i; - int index; -+ int firstbitidx, nextbitidx; - struct regmap_config fsl_sai_regmap_config = fsl_sai_v2_regmap_config; - unsigned long irqflags = 0; - -@@ -1048,6 +1153,9 @@ static int fsl_sai_probe(struct platform - } - } - -+ if (of_find_property(np, "fsl,sai-multi-lane", NULL)) -+ sai->is_multi_lane = true; -+ - /*dataline mask for rx and tx*/ - ret = of_property_read_u32_index(np, "fsl,dataline", 0, &sai->dataline[0]); - if (ret) -@@ -1062,6 +1170,37 @@ static int fsl_sai_probe(struct platform - return -EINVAL; - } - -+ for (i = 0; i < 2; i++) { -+ firstbitidx = find_first_bit((const unsigned long *)&sai->dataline[i], 8); -+ nextbitidx = find_next_bit((const unsigned long *)&sai->dataline[i], 8, firstbitidx+1); -+ sai->dataline_off[i] = nextbitidx - firstbitidx - 1; -+ -+ if (sai->dataline_off[i] < 0 || sai->dataline_off[i] >= 7) -+ sai->dataline_off[i] = 0; -+ } -+ -+ ret = of_property_read_u32_index(np, "fsl,dataline,dsd", 0, &sai->dataline_dsd[0]); -+ if (ret) -+ sai->dataline_dsd[0] = 1; -+ -+ ret = of_property_read_u32_index(np, "fsl,dataline,dsd", 1, &sai->dataline_dsd[1]); -+ if (ret) -+ sai->dataline_dsd[1] = 1; -+ -+ if ((sai->dataline_dsd[0] & (~sai->soc->dataline)) || sai->dataline_dsd[1] & (~sai->soc->dataline)) { -+ dev_err(&pdev->dev, "dataline setting error, Mask is 0x%x\n", sai->soc->dataline); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < 2; i++) { -+ firstbitidx = find_first_bit((const unsigned long *)&sai->dataline_dsd[i], 8); -+ nextbitidx = find_next_bit((const unsigned long *)&sai->dataline_dsd[i], 8, firstbitidx+1); -+ sai->dataline_off_dsd[i] = nextbitidx - firstbitidx - 1; -+ -+ if (sai->dataline_off_dsd[i] < 0 || sai->dataline_off_dsd[i] >= 7) -+ sai->dataline_off_dsd[i] = 0; -+ } -+ - if ((of_find_property(np, "fsl,i2s-xtor", NULL) != NULL) || - (of_find_property(np, "fsl,txm-rxs", NULL) != NULL)) - { -@@ -1144,6 +1283,11 @@ static int fsl_sai_probe(struct platform - sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; - sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; - -+ sai->pinctrl = devm_pinctrl_get(&pdev->dev); -+ -+ if (!IS_ERR_OR_NULL(sai->pinctrl)) -+ sai->pins_dsd = pinctrl_lookup_state(sai->pinctrl, "dsd"); -+ - platform_set_drvdata(pdev, sai); - - pm_runtime_enable(&pdev->dev); ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -11,7 +11,10 @@ - - #define FSL_SAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S24_LE |\ -- SNDRV_PCM_FMTBIT_S32_LE) -+ SNDRV_PCM_FMTBIT_S32_LE |\ -+ SNDRV_PCM_FMTBIT_DSD_U8 |\ -+ SNDRV_PCM_FMTBIT_DSD_U16_LE |\ -+ SNDRV_PCM_FMTBIT_DSD_U32_LE) - - /* SAI Register Map Register */ - #define FSL_SAI_TCSR(offset) (0x00 + offset) /* SAI Transmit Control */ -@@ -172,9 +175,14 @@ struct fsl_sai { - bool slave_mode[2]; - bool is_lsb_first; - bool is_dsp_mode; -+ bool is_multi_lane; - bool synchronous[2]; - bool is_stream_opened[2]; -+ bool is_dsd; - unsigned int dataline[2]; -+ unsigned int dataline_dsd[2]; -+ unsigned int dataline_off[2]; -+ unsigned int dataline_off_dsd[2]; - unsigned int masterflag[2]; - - unsigned int mclk_id[2]; -@@ -188,6 +196,8 @@ struct fsl_sai { - struct snd_dmaengine_dai_dma_data dma_params_tx; - const struct fsl_sai_soc_data *soc; - struct pm_qos_request pm_qos_req; -+ struct pinctrl *pinctrl; -+ struct pinctrl_state *pins_dsd; - }; - - #define TX 1 diff --git a/target/linux/layerscape/patches-5.4/801-audio-0038-MLK-17467-ASoC-fsl_sai-fix-typo-for-fsl_sai.patch b/target/linux/layerscape/patches-5.4/801-audio-0038-MLK-17467-ASoC-fsl_sai-fix-typo-for-fsl_sai.patch deleted file mode 100644 index 9499b54747..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0038-MLK-17467-ASoC-fsl_sai-fix-typo-for-fsl_sai.patch +++ /dev/null @@ -1,36 +0,0 @@ -From b22f55e1f41ebe218604f12c127d299a2c302393 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Fri, 26 Jan 2018 16:44:19 +0800 -Subject: [PATCH] MLK-17467: ASoC: fsl_sai: fix typo for fsl_sai -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fix build warning - -sound/soc/fsl/fsl_sai.c: In function ‘fsl_sai_trigger’: -sound/soc/fsl/fsl_sai.c:736:3: warning: this ‘while’ clause does not guard... [-Wmisleading-indentation] - while (tx && i < channels) - ^~~~~ -sound/soc/fsl/fsl_sai.c:742:4: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the ‘while’ - j++; - ^ -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -727,9 +727,8 @@ static int fsl_sai_trigger(struct snd_pc - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - -- for (i = 0; tx && i < channels; i++) { -- while (tx && i < channels) -- if (sai->dataline[tx] & (1 << j)) { -+ while (tx && i < channels) { -+ if ((sai->is_dsd ? sai->dataline_dsd[tx] : sai->dataline[tx]) & (1 << j)) { - regmap_write(sai->regmap, FSL_SAI_TDR0 + j * 0x4, 0x0); - i++; - k++; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0039-MLK-16224-6-ASoC-fsl_sai-fix-DSD-suspend-resume.patch b/target/linux/layerscape/patches-5.4/801-audio-0039-MLK-16224-6-ASoC-fsl_sai-fix-DSD-suspend-resume.patch deleted file mode 100644 index a01ac65180..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0039-MLK-16224-6-ASoC-fsl_sai-fix-DSD-suspend-resume.patch +++ /dev/null @@ -1,49 +0,0 @@ -From a115bf34468398647e7a8f380058bd597e44e1b3 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Mon, 29 Jan 2018 16:04:44 +0200 -Subject: [PATCH] MLK-16224-6: ASoC: fsl_sai: fix DSD suspend/resume - -With the existing implementation the SAI pinctrl state is restored to -default after resume - this breaks DSD playback after resume. -Restore DSD pinctrl state in snd_soc_dai_driver resume callback. - -Signed-off-by: Viorel Suman -Reviewed-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -893,6 +893,23 @@ static int fsl_sai_dai_probe(struct snd_ - return 0; - } - -+static int fsl_sai_dai_resume(struct snd_soc_dai *cpu_dai) -+{ -+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); -+ int ret; -+ -+ if (sai->is_dsd && !IS_ERR_OR_NULL(sai->pins_dsd)) { -+ ret = pinctrl_select_state(sai->pinctrl, sai->pins_dsd); -+ if (ret) { -+ dev_err(cpu_dai->dev, -+ "failed to set proper pins state: %d\n", ret); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+ - static struct snd_soc_dai_driver fsl_sai_dai_template = { - .probe = fsl_sai_dai_probe, - .playback = { -@@ -913,6 +930,7 @@ static struct snd_soc_dai_driver fsl_sai - .rates = SNDRV_PCM_RATE_KNOT, - .formats = FSL_SAI_FORMATS, - }, -+ .resume = fsl_sai_dai_resume, - .ops = &fsl_sai_pcm_dai_ops, - }; - diff --git a/target/linux/layerscape/patches-5.4/801-audio-0040-MLK-17428-8-ASoC-fsl_sai-support-768KHz-sample-rate.patch b/target/linux/layerscape/patches-5.4/801-audio-0040-MLK-17428-8-ASoC-fsl_sai-support-768KHz-sample-rate.patch deleted file mode 100644 index 63b38b65eb..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0040-MLK-17428-8-ASoC-fsl_sai-support-768KHz-sample-rate.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 2bc81e99f261aa6eafa900453b477dd46d568d73 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Fri, 19 Jan 2018 15:45:21 +0800 -Subject: [PATCH] MLK-17428-8: ASoC: fsl_sai: support 768KHz sample rate - -support 768Hz sample rate and 2.8MHz for DSD - -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -91,7 +91,8 @@ static struct fsl_sai_soc_data fsl_sai_i - static const unsigned int fsl_sai_rates[] = { - 8000, 11025, 12000, 16000, 22050, - 24000, 32000, 44100, 48000, 64000, -- 88200, 96000, 176400, 192000 -+ 88200, 96000, 176400, 192000, 352800, -+ 384000, 705600, 768000, 1411200, 2822400, - }; - - static const struct snd_pcm_hw_constraint_list fsl_sai_rate_constraints = { -@@ -916,8 +917,6 @@ static struct snd_soc_dai_driver fsl_sai - .stream_name = "CPU-Playback", - .channels_min = 1, - .channels_max = 32, -- .rate_min = 8000, -- .rate_max = 192000, - .rates = SNDRV_PCM_RATE_KNOT, - .formats = FSL_SAI_FORMATS, - }, -@@ -925,8 +924,6 @@ static struct snd_soc_dai_driver fsl_sai - .stream_name = "CPU-Capture", - .channels_min = 1, - .channels_max = 32, -- .rate_min = 8000, -- .rate_max = 192000, - .rates = SNDRV_PCM_RATE_KNOT, - .formats = FSL_SAI_FORMATS, - }, diff --git a/target/linux/layerscape/patches-5.4/801-audio-0041-MLK-17485-ASoC-fsl_sai-Specify-supported-rate_min-an.patch b/target/linux/layerscape/patches-5.4/801-audio-0041-MLK-17485-ASoC-fsl_sai-Specify-supported-rate_min-an.patch deleted file mode 100644 index 93588333ae..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0041-MLK-17485-ASoC-fsl_sai-Specify-supported-rate_min-an.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 4859edfca7fb2408b8b9f90bf03c62e484dadc79 Mon Sep 17 00:00:00 2001 -From: Daniel Baluta -Date: Fri, 2 Feb 2018 11:02:27 +0200 -Subject: [PATCH] MLK-17485: ASoC: fsl_sai: Specify supported rate_min and - rate_max - -Because fsl_sai_dai rates doesn't have a specific set of -rate values (.rates = SNDRV_PCM_RATE_KNOT) we need to provide -rate_min and rate_max otherwise functions trying to get -supported parameters will get confused and return an error. - -Fixes: 1b6f0496e013 ("MLK-17428-8: ASoC: fsl_sai: support 768KHz sample rate") -Reviewed-by: Viorel Suman -Signed-off-by: Daniel Baluta ---- - sound/soc/fsl/fsl_sai.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -917,6 +917,8 @@ static struct snd_soc_dai_driver fsl_sai - .stream_name = "CPU-Playback", - .channels_min = 1, - .channels_max = 32, -+ .rate_min = 8000, -+ .rate_max = 2822400, - .rates = SNDRV_PCM_RATE_KNOT, - .formats = FSL_SAI_FORMATS, - }, -@@ -924,6 +926,8 @@ static struct snd_soc_dai_driver fsl_sai - .stream_name = "CPU-Capture", - .channels_min = 1, - .channels_max = 32, -+ .rate_min = 8000, -+ .rate_max = 2822400, - .rates = SNDRV_PCM_RATE_KNOT, - .formats = FSL_SAI_FORMATS, - }, diff --git a/target/linux/layerscape/patches-5.4/801-audio-0042-MLK-17566-ASoC-fsl_sai-fix-register-definition.patch b/target/linux/layerscape/patches-5.4/801-audio-0042-MLK-17566-ASoC-fsl_sai-fix-register-definition.patch deleted file mode 100644 index bd6488a782..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0042-MLK-17566-ASoC-fsl_sai-fix-register-definition.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 8e28947dacb52352807fed71d70355a18bf416c5 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Thu, 8 Feb 2018 14:38:35 +0800 -Subject: [PATCH] MLK-17566: ASoC: fsl_sai: fix register definition - -The register definition is not completed for SAI support -8 transmit data register and 8 receive data register. - -Signed-off-by: Shengjiu Wang -Reviewed-by: Daniel Baluta ---- - sound/soc/fsl/fsl_sai.c | 24 ++++++++++++++++++++++++ - sound/soc/fsl/fsl_sai.h | 12 ++++++++++++ - 2 files changed, 36 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -964,6 +964,12 @@ static struct reg_default fsl_sai_v3_reg - {FSL_SAI_TCR5(8), 0}, - {FSL_SAI_TDR0, 0}, - {FSL_SAI_TDR1, 0}, -+ {FSL_SAI_TDR2, 0}, -+ {FSL_SAI_TDR3, 0}, -+ {FSL_SAI_TDR4, 0}, -+ {FSL_SAI_TDR5, 0}, -+ {FSL_SAI_TDR6, 0}, -+ {FSL_SAI_TDR7, 0}, - {FSL_SAI_TMR, 0}, - {FSL_SAI_RCR1(8), 0}, - {FSL_SAI_RCR2(8), 0}, -@@ -996,6 +1002,12 @@ static bool fsl_sai_readable_reg(struct - case FSL_SAI_TMR: - case FSL_SAI_RDR0: - case FSL_SAI_RDR1: -+ case FSL_SAI_RDR2: -+ case FSL_SAI_RDR3: -+ case FSL_SAI_RDR4: -+ case FSL_SAI_RDR5: -+ case FSL_SAI_RDR6: -+ case FSL_SAI_RDR7: - case FSL_SAI_RFR0: - case FSL_SAI_RFR1: - case FSL_SAI_RFR2: -@@ -1038,6 +1050,12 @@ static bool fsl_sai_volatile_reg(struct - case FSL_SAI_RFR7: - case FSL_SAI_RDR0: - case FSL_SAI_RDR1: -+ case FSL_SAI_RDR2: -+ case FSL_SAI_RDR3: -+ case FSL_SAI_RDR4: -+ case FSL_SAI_RDR5: -+ case FSL_SAI_RDR6: -+ case FSL_SAI_RDR7: - return true; - default: - return false; -@@ -1058,6 +1076,12 @@ static bool fsl_sai_writeable_reg(struct - switch (reg) { - case FSL_SAI_TDR0: - case FSL_SAI_TDR1: -+ case FSL_SAI_TDR2: -+ case FSL_SAI_TDR3: -+ case FSL_SAI_TDR4: -+ case FSL_SAI_TDR5: -+ case FSL_SAI_TDR6: -+ case FSL_SAI_TDR7: - case FSL_SAI_TMR: - case FSL_SAI_RMR: - return true; ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -25,6 +25,12 @@ - #define FSL_SAI_TCR5(offset) (0x14 + offset) /* SAI Transmit Configuration 5 */ - #define FSL_SAI_TDR0 0x20 /* SAI Transmit Data */ - #define FSL_SAI_TDR1 0x24 /* SAI Transmit Data */ -+#define FSL_SAI_TDR2 0x28 /* SAI Transmit Data */ -+#define FSL_SAI_TDR3 0x2C /* SAI Transmit Data */ -+#define FSL_SAI_TDR4 0x30 /* SAI Transmit Data */ -+#define FSL_SAI_TDR5 0x34 /* SAI Transmit Data */ -+#define FSL_SAI_TDR6 0x38 /* SAI Transmit Data */ -+#define FSL_SAI_TDR7 0x3C /* SAI Transmit Data */ - #define FSL_SAI_TFR0 0x40 /* SAI Transmit FIFO */ - #define FSL_SAI_TFR1 0x44 /* SAI Transmit FIFO */ - #define FSL_SAI_TFR2 0x48 /* SAI Transmit FIFO */ -@@ -43,6 +49,12 @@ - #define FSL_SAI_RCR5(offset) (0x94 + offset) /* SAI Receive Configuration 5 */ - #define FSL_SAI_RDR0 0xa0 /* SAI Receive Data */ - #define FSL_SAI_RDR1 0xa4 /* SAI Receive Data */ -+#define FSL_SAI_RDR2 0xa8 /* SAI Receive Data */ -+#define FSL_SAI_RDR3 0xac /* SAI Receive Data */ -+#define FSL_SAI_RDR4 0xb0 /* SAI Receive Data */ -+#define FSL_SAI_RDR5 0xb4 /* SAI Receive Data */ -+#define FSL_SAI_RDR6 0xb8 /* SAI Receive Data */ -+#define FSL_SAI_RDR7 0xbc /* SAI Receive Data */ - #define FSL_SAI_RFR0 0xc0 /* SAI Receive FIFO */ - #define FSL_SAI_RFR1 0xc4 /* SAI Receive FIFO */ - #define FSL_SAI_RFR2 0xc8 /* SAI Receive FIFO */ diff --git a/target/linux/layerscape/patches-5.4/801-audio-0043-MLK-17528-1-ASoC-fsl_sai-Introduce-FSL_SAI_CLK_BIT-c.patch b/target/linux/layerscape/patches-5.4/801-audio-0043-MLK-17528-1-ASoC-fsl_sai-Introduce-FSL_SAI_CLK_BIT-c.patch deleted file mode 100644 index a6ff55b3fb..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0043-MLK-17528-1-ASoC-fsl_sai-Introduce-FSL_SAI_CLK_BIT-c.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 8eb2c08d504ac0697285b08084487fd3869ea7b6 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Thu, 8 Feb 2018 12:47:24 +0200 -Subject: [PATCH] MLK-17528-1: ASoC: fsl_sai: Introduce FSL_SAI_CLK_BIT clock - id - -Introduce FSL_SAI_CLK_BIT clock id in order to distinguish -the bit clock and master clocks in "set_sysclk" API. - -Signed-off-by: Viorel Suman -Suggested-by: Shengjiu Wang -Reviewed-by: Shengjiu Wang -Reviewed-by: Daniel Baluta ---- - sound/soc/fsl/fsl_sai.c | 5 ++++- - sound/soc/fsl/fsl_sai.h | 1 + - 2 files changed, 5 insertions(+), 1 deletion(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -240,7 +240,10 @@ static int fsl_sai_set_dai_sysclk(struct - if (dir == SND_SOC_CLOCK_IN) - return 0; - -- sai->bitclk_freq = freq; -+ if (clk_id == FSL_SAI_CLK_BIT) { -+ sai->bitclk_freq = freq; -+ return 0; -+ } - - ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, - FSL_FMT_TRANSMITTER); ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -160,6 +160,7 @@ - #define FSL_SAI_CLK_MAST3 3 - - #define FSL_SAI_MCLK_MAX 4 -+#define FSL_SAI_CLK_BIT 5 - - /* SAI data transfer numbers per DMA request */ - #define FSL_SAI_MAXBURST_TX 6 diff --git a/target/linux/layerscape/patches-5.4/801-audio-0044-MLK-17528-3-ASoC-fsl_sai-Set-clock-rate-in-set_syscl.patch b/target/linux/layerscape/patches-5.4/801-audio-0044-MLK-17528-3-ASoC-fsl_sai-Set-clock-rate-in-set_syscl.patch deleted file mode 100644 index da3ec8d3d8..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0044-MLK-17528-3-ASoC-fsl_sai-Set-clock-rate-in-set_syscl.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0d9bc2f22dc418c4573ded86278e55f97d029dca Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Fri, 9 Feb 2018 11:39:58 +0200 -Subject: [PATCH] MLK-17528-3: ASoC: fsl_sai: Set clock rate in "set_sysclk" - API - -Set the requested clock rate in "set_sysclk" for specified clock id. - -Signed-off-by: Viorel Suman -Suggested-by: Shengjiu Wang -Reviewed-by: Shengjiu Wang -Reviewed-by: Daniel Baluta ---- - sound/soc/fsl/fsl_sai.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -245,6 +245,25 @@ static int fsl_sai_set_dai_sysclk(struct - return 0; - } - -+ if (freq > 0) { -+ if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) { -+ dev_err(cpu_dai->dev, "Unknown clock id: %d\n", clk_id); -+ return -EINVAL; -+ } -+ -+ if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) { -+ dev_err(cpu_dai->dev, "Unassigned clock: %d\n", clk_id); -+ return -EINVAL; -+ } -+ -+ ret = clk_set_rate(sai->mclk_clk[clk_id], freq); -+ if (ret < 0) { -+ dev_err(cpu_dai->dev, "failed to set clock rate (%u): %d\n", -+ freq, ret); -+ return ret; -+ } -+ } -+ - ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, - FSL_FMT_TRANSMITTER); - if (ret) { diff --git a/target/linux/layerscape/patches-5.4/801-audio-0045-MLK-17156-1-ASoC-fsl_sai-update-register-offset-for-.patch b/target/linux/layerscape/patches-5.4/801-audio-0045-MLK-17156-1-ASoC-fsl_sai-update-register-offset-for-.patch deleted file mode 100644 index 8189ec236d..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0045-MLK-17156-1-ASoC-fsl_sai-update-register-offset-for-.patch +++ /dev/null @@ -1,26 +0,0 @@ -From bed63eea982ba6d59995288a5deab94510a51994 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Tue, 6 Mar 2018 11:45:30 +0800 -Subject: [PATCH] MLK-17156-1: ASoC: fsl_sai: update register offset for ULP B0 - -ULP B0 integrate the latest SAI IP, there is version id and -parameter id register in the beginning, so update the offset -for ULP B0 - -Signed-off-by: Shengjiu Wang -Reviewed-by: Daniel Baluta ---- - sound/soc/fsl/fsl_sai.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -64,7 +64,7 @@ static struct fsl_sai_soc_data fsl_sai_i - .fifos = 2, - .fifo_depth = 16, - .flags = SAI_FLAG_PMQOS, -- .reg_offset = 0, -+ .reg_offset = 8, - .constrain_period_size = false, - }; - diff --git a/target/linux/layerscape/patches-5.4/801-audio-0046-Sound-Soc-fsl-Set-SAI-Channel-Mode-to-Output-Mode.patch b/target/linux/layerscape/patches-5.4/801-audio-0046-Sound-Soc-fsl-Set-SAI-Channel-Mode-to-Output-Mode.patch deleted file mode 100644 index 0d8fc165e9..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0046-Sound-Soc-fsl-Set-SAI-Channel-Mode-to-Output-Mode.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 494c1f9c5c86396d2974c6072f728e2325b72703 Mon Sep 17 00:00:00 2001 -From: Cosmin-Gabriel Samoila -Date: Wed, 7 Mar 2018 11:35:07 +0200 -Subject: [PATCH] Sound: Soc: fsl: Set SAI Channel Mode to Output Mode - -Transmit data pins will output zero when slots are masked or channels -are disabled. In CHMOD TDM mode, transmit data pins are tri-stated when -slots are masked or channels are disabled. When data pins are tri-stated, -there is noise on some channels when FS clock value is high and data is -read while fsclk is transitioning from high to low. - -Signed-off-by: Cosmin-Gabriel Samoila -Reviewed-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 14 +++++++++++--- - sound/soc/fsl/fsl_sai.h | 2 ++ - 2 files changed, 13 insertions(+), 3 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -589,6 +589,11 @@ static int fsl_sai_hw_params(struct snd_ - - val_cr4 |= FSL_SAI_CR4_FRSZ(slots); - -+ /* Output Mode - data pins transmit 0 when slots are masked -+ * or channels are disabled -+ */ -+ val_cr4 |= FSL_SAI_CR4_CHMOD; -+ - /* - * For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will - * generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4), -@@ -599,14 +604,16 @@ static int fsl_sai_hw_params(struct snd_ - if (!sai->slave_mode[tx]) { - if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) { - regmap_update_bits(sai->regmap, FSL_SAI_TCR4(offset), -- FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | -+ FSL_SAI_CR4_CHMOD_MASK, - val_cr4); - regmap_update_bits(sai->regmap, FSL_SAI_TCR5(offset), - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | - FSL_SAI_CR5_FBT_MASK, val_cr5); - } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) { - regmap_update_bits(sai->regmap, FSL_SAI_RCR4(offset), -- FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | -+ FSL_SAI_CR4_CHMOD_MASK, - val_cr4); - regmap_update_bits(sai->regmap, FSL_SAI_RCR5(offset), - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | -@@ -682,7 +689,8 @@ static int fsl_sai_hw_params(struct snd_ - } - - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), -- FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, -+ FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | -+ FSL_SAI_CR4_CHMOD_MASK, - val_cr4); - regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, offset), - FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -129,6 +129,8 @@ - #define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16) - #define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8) - #define FSL_SAI_CR4_SYWD_MASK (0x1f << 8) -+#define FSL_SAI_CR4_CHMOD (1 << 5) -+#define FSL_SAI_CR4_CHMOD_MASK (1 << 5) - #define FSL_SAI_CR4_MF BIT(4) - #define FSL_SAI_CR4_FSE BIT(3) - #define FSL_SAI_CR4_FSP BIT(1) diff --git a/target/linux/layerscape/patches-5.4/801-audio-0047-MLK-17580-ASoC-fsl-dsd-Add-DSD-utilities-helper.patch b/target/linux/layerscape/patches-5.4/801-audio-0047-MLK-17580-ASoC-fsl-dsd-Add-DSD-utilities-helper.patch deleted file mode 100644 index 9290b3b9cb..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0047-MLK-17580-ASoC-fsl-dsd-Add-DSD-utilities-helper.patch +++ /dev/null @@ -1,76 +0,0 @@ -From e28e3e0d01c0fcb628e841977b51c45189b43f47 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Thu, 8 Mar 2018 14:37:30 +0200 -Subject: [PATCH] MLK-17580: ASoC: fsl: dsd: Add DSD utilities helper - -Add DSD utilities helper. - -Signed-off-by: Viorel Suman -Reviewed-by: Shengjiu Wang -+#include -+#include -+ -+static bool fsl_is_dsd(struct snd_pcm_hw_params *params) -+{ -+ snd_pcm_format_t format = params_format(params); -+ -+ switch (format) { -+ case SNDRV_PCM_FORMAT_DSD_U8: -+ case SNDRV_PCM_FORMAT_DSD_U16_LE: -+ case SNDRV_PCM_FORMAT_DSD_U16_BE: -+ case SNDRV_PCM_FORMAT_DSD_U32_LE: -+ case SNDRV_PCM_FORMAT_DSD_U32_BE: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+static struct pinctrl_state *fsl_get_pins_state(struct pinctrl *pinctrl, -+ struct snd_pcm_hw_params *params) -+{ -+ int dsd_bclk; -+ struct pinctrl_state *state = 0; -+ -+ if (fsl_is_dsd(params)) { -+ dsd_bclk = params_rate(params) * params_physical_width(params); -+ -+ switch (dsd_bclk) { -+ case 22579200: /* DSD512 */ -+ state = pinctrl_lookup_state(pinctrl, "dsd512"); -+ break; -+ } -+ -+ /* Get default DSD state */ -+ if (IS_ERR_OR_NULL(state)) -+ state = pinctrl_lookup_state(pinctrl, "dsd"); -+ } -+ -+ /* Get default state */ -+ if (IS_ERR_OR_NULL(state)) -+ state = pinctrl_lookup_state(pinctrl, "default"); -+ -+ return state; -+} -+ -+#endif /* __FSL_DSD_H */ diff --git a/target/linux/layerscape/patches-5.4/801-audio-0048-MLK-17580-ASoC-fsl-sai-Use-DSD-helper.patch b/target/linux/layerscape/patches-5.4/801-audio-0048-MLK-17580-ASoC-fsl-sai-Use-DSD-helper.patch deleted file mode 100644 index edfbd57fb2..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0048-MLK-17580-ASoC-fsl-sai-Use-DSD-helper.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 0a71cfbd55ba50414bfcb4ecccf656a580930790 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Thu, 8 Mar 2018 14:43:34 +0200 -Subject: [PATCH] MLK-17580: ASoC: fsl: sai: Use DSD helper - -Replace DSD related code with calls to DSD helper functions. - -Signed-off-by: Viorel Suman -Reviewed-by: Shengjiu Wang - #include - -+#include "fsl_dsd.h" - #include "fsl_sai.h" - #include "imx-pcm.h" - -@@ -523,31 +524,21 @@ static int fsl_sai_hw_params(struct snd_ - int ret; - int i; - int trce_mask = 0; -- snd_pcm_format_t format = params_format(params); - - if (sai->slots) - slots = sai->slots; - - pins = DIV_ROUND_UP(channels, slots); -+ sai->is_dsd = fsl_is_dsd(params); -+ sai->pins_state = fsl_get_pins_state(sai->pinctrl, params); - -- if (format == SNDRV_PCM_FORMAT_DSD_U8 || -- format == SNDRV_PCM_FORMAT_DSD_U16_LE || -- format == SNDRV_PCM_FORMAT_DSD_U16_BE || -- format == SNDRV_PCM_FORMAT_DSD_U32_LE || -- format == SNDRV_PCM_FORMAT_DSD_U32_BE) { -- sai->is_dsd = true; -- -- if (!IS_ERR_OR_NULL(sai->pins_dsd)) { -- ret = pinctrl_select_state(sai->pinctrl, sai->pins_dsd); -- if (ret) { -- dev_err(cpu_dai->dev, -- "failed to set proper pins state: %d\n", ret); -- return ret; -- } -+ if (!IS_ERR_OR_NULL(sai->pins_state)) { -+ ret = pinctrl_select_state(sai->pinctrl, sai->pins_state); -+ if (ret) { -+ dev_err(cpu_dai->dev, -+ "failed to set proper pins state: %d\n", ret); -+ return ret; - } -- } else { -- pinctrl_pm_select_default_state(cpu_dai->dev); -- sai->is_dsd = false; - } - - if (sai->is_dsd) -@@ -929,8 +920,8 @@ static int fsl_sai_dai_resume(struct snd - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - int ret; - -- if (sai->is_dsd && !IS_ERR_OR_NULL(sai->pins_dsd)) { -- ret = pinctrl_select_state(sai->pinctrl, sai->pins_dsd); -+ if (!IS_ERR_OR_NULL(sai->pins_state)) { -+ ret = pinctrl_select_state(sai->pinctrl, sai->pins_state); - if (ret) { - dev_err(cpu_dai->dev, - "failed to set proper pins state: %d\n", ret); -@@ -1357,9 +1348,6 @@ static int fsl_sai_probe(struct platform - - sai->pinctrl = devm_pinctrl_get(&pdev->dev); - -- if (!IS_ERR_OR_NULL(sai->pinctrl)) -- sai->pins_dsd = pinctrl_lookup_state(sai->pinctrl, "dsd"); -- - platform_set_drvdata(pdev, sai); - - pm_runtime_enable(&pdev->dev); ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -212,7 +212,7 @@ struct fsl_sai { - const struct fsl_sai_soc_data *soc; - struct pm_qos_request pm_qos_req; - struct pinctrl *pinctrl; -- struct pinctrl_state *pins_dsd; -+ struct pinctrl_state *pins_state; - }; - - #define TX 1 diff --git a/target/linux/layerscape/patches-5.4/801-audio-0049-MLK-17580-ASoC-fsl-sai-check-for-pinctrl-status.patch b/target/linux/layerscape/patches-5.4/801-audio-0049-MLK-17580-ASoC-fsl-sai-check-for-pinctrl-status.patch deleted file mode 100644 index f93bdfe63e..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0049-MLK-17580-ASoC-fsl-sai-check-for-pinctrl-status.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 12b887445779c33285dac5279fc02fd80e0800d8 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Fri, 9 Mar 2018 12:41:42 +0200 -Subject: [PATCH] MLK-17580: ASoC: fsl: sai: check for pinctrl status - -For some cases (like AMIX) pinctrl may be null - this -breaks SAI functionality. Enforce pinctrl null pointer -checking prior calling any function which involves -pins state changes. - -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -530,14 +530,17 @@ static int fsl_sai_hw_params(struct snd_ - - pins = DIV_ROUND_UP(channels, slots); - sai->is_dsd = fsl_is_dsd(params); -- sai->pins_state = fsl_get_pins_state(sai->pinctrl, params); - -- if (!IS_ERR_OR_NULL(sai->pins_state)) { -- ret = pinctrl_select_state(sai->pinctrl, sai->pins_state); -- if (ret) { -- dev_err(cpu_dai->dev, -- "failed to set proper pins state: %d\n", ret); -- return ret; -+ if (!IS_ERR_OR_NULL(sai->pinctrl)) { -+ sai->pins_state = fsl_get_pins_state(sai->pinctrl, params); -+ -+ if (!IS_ERR_OR_NULL(sai->pins_state)) { -+ ret = pinctrl_select_state(sai->pinctrl, sai->pins_state); -+ if (ret) { -+ dev_err(cpu_dai->dev, -+ "failed to set proper pins state: %d\n", ret); -+ return ret; -+ } - } - } - -@@ -920,7 +923,7 @@ static int fsl_sai_dai_resume(struct snd - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - int ret; - -- if (!IS_ERR_OR_NULL(sai->pins_state)) { -+ if (!IS_ERR_OR_NULL(sai->pinctrl) && !IS_ERR_OR_NULL(sai->pins_state)) { - ret = pinctrl_select_state(sai->pinctrl, sai->pins_state); - if (ret) { - dev_err(cpu_dai->dev, -@@ -1346,7 +1349,7 @@ static int fsl_sai_probe(struct platform - sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; - sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX; - -- sai->pinctrl = devm_pinctrl_get(&pdev->dev); -+ sai->pinctrl = devm_pinctrl_get(&pdev->dev); - - platform_set_drvdata(pdev, sai); - diff --git a/target/linux/layerscape/patches-5.4/801-audio-0050-MLK-17531-1-ASoC-fsl-sai-add-support-for-SAI-v3.01.patch b/target/linux/layerscape/patches-5.4/801-audio-0050-MLK-17531-1-ASoC-fsl-sai-add-support-for-SAI-v3.01.patch deleted file mode 100644 index 0df0f2fa93..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0050-MLK-17531-1-ASoC-fsl-sai-add-support-for-SAI-v3.01.patch +++ /dev/null @@ -1,250 +0,0 @@ -From 63b81694ef7736849dcf7f7daf0becc6ebc02844 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Mon, 14 May 2018 16:28:48 +0300 -Subject: [PATCH] MLK-17531-1: ASoC: fsl: sai: add support for SAI v3.01 - -a) Add support for new SAI (VERID, PARAM, MCTL, MDIV) registers - available in i.MX 850d (SAI v3.00) and i.MX 845s (SAI v3.01). -b) Handle SAI MCLK register as function of SAI IP version. - -Signed-off-by: Viorel Suman -Reviewed-by: Daniel Baluta ---- - sound/soc/fsl/fsl_sai.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++- - sound/soc/fsl/fsl_sai.h | 59 +++++++++++++++++++++++++++++++++++++++++++- - 2 files changed, 122 insertions(+), 2 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -29,6 +29,8 @@ - #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\ - FSL_SAI_CSR_FEIE) - -+#define FSL_SAI_VERID_0301 0x0301 -+ - static struct fsl_sai_soc_data fsl_sai_vf610 = { - .imx = false, - /*dataline is mask, not index*/ -@@ -422,6 +424,48 @@ static int fsl_sai_set_dai_fmt(struct sn - return ret; - } - -+static int fsl_sai_check_ver(struct snd_soc_dai *cpu_dai) -+{ -+ struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); -+ unsigned char offset = sai->soc->reg_offset; -+ unsigned int val; -+ -+ if (FSL_SAI_TCSR(offset) == FSL_SAI_VERID) -+ return 0; -+ -+ if (sai->verid.loaded) -+ return 0; -+ -+ sai->verid.loaded = true; -+ regmap_read(sai->regmap, FSL_SAI_VERID, &val); -+ dev_dbg(cpu_dai->dev, "VERID: 0x%016X\n", val); -+ -+ sai->verid.id = (val & FSL_SAI_VER_ID_MASK) >> FSL_SAI_VER_ID_SHIFT; -+ sai->verid.extfifo_en = (val & FSL_SAI_VER_EFIFO_EN); -+ sai->verid.timestamp_en = (val & FSL_SAI_VER_TSTMP_EN); -+ -+ regmap_read(sai->regmap, FSL_SAI_PARAM, &val); -+ dev_dbg(cpu_dai->dev, "PARAM: 0x%016X\n", val); -+ -+ /* max slots per frame, power of 2 */ -+ sai->param.spf = 1 << -+ ((val & FSL_SAI_PAR_SPF_MASK) >> FSL_SAI_PAR_SPF_SHIFT); -+ -+ /* words per fifo, power of 2 */ -+ sai->param.wpf = 1 << -+ ((val & FSL_SAI_PAR_WPF_MASK) >> FSL_SAI_PAR_WPF_SHIFT); -+ -+ /* number of datalines implemented */ -+ sai->param.dln = val & FSL_SAI_PAR_DLN_MASK; -+ -+ dev_dbg(cpu_dai->dev, -+ "Version: 0x%08X, SPF: %u, WPF: %u, DLN: %u\n", -+ sai->verid.id, sai->param.spf, sai->param.wpf, sai->param.dln -+ ); -+ -+ return 0; -+} -+ - static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); -@@ -502,6 +546,15 @@ static int fsl_sai_set_bclk(struct snd_s - FSL_SAI_CR2_DIV_MASK, savediv - 1); - } - -+ fsl_sai_check_ver(dai); -+ switch (sai->verid.id) { -+ case FSL_SAI_VERID_0301: -+ /* SAI is in master mode at this point, so enable MCLK */ -+ regmap_update_bits(sai->regmap, FSL_SAI_MCTL, -+ FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN); -+ break; -+ } -+ - dev_dbg(dai->dev, "best fit: clock id=%d, div=%d, deviation =%d\n", - sai->mclk_id[tx], savediv, savesub); - -@@ -1001,6 +1054,8 @@ static struct reg_default fsl_sai_v3_reg - {FSL_SAI_RCR4(8), 0}, - {FSL_SAI_RCR5(8), 0}, - {FSL_SAI_RMR, 0}, -+ {FSL_SAI_MCTL, 0}, -+ {FSL_SAI_MDIV, 0}, - }; - - static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg) -@@ -1041,6 +1096,10 @@ static bool fsl_sai_readable_reg(struct - case FSL_SAI_RFR6: - case FSL_SAI_RFR7: - case FSL_SAI_RMR: -+ case FSL_SAI_MCTL: -+ case FSL_SAI_MDIV: -+ case FSL_SAI_VERID: -+ case FSL_SAI_PARAM: - return true; - default: - return false; -@@ -1056,6 +1115,8 @@ static bool fsl_sai_volatile_reg(struct - return true; - - switch (reg) { -+ case FSL_SAI_VERID: -+ case FSL_SAI_PARAM: - case FSL_SAI_TFR0: - case FSL_SAI_TFR1: - case FSL_SAI_TFR2: -@@ -1108,6 +1169,8 @@ static bool fsl_sai_writeable_reg(struct - case FSL_SAI_TDR7: - case FSL_SAI_TMR: - case FSL_SAI_RMR: -+ case FSL_SAI_MCTL: -+ case FSL_SAI_MDIV: - return true; - default: - return false; -@@ -1133,7 +1196,7 @@ static const struct regmap_config fsl_sa - .reg_stride = 4, - .val_bits = 32, - -- .max_register = FSL_SAI_RMR, -+ .max_register = FSL_SAI_MDIV, - .reg_defaults = fsl_sai_v3_reg_defaults, - .num_reg_defaults = ARRAY_SIZE(fsl_sai_v3_reg_defaults), - .readable_reg = fsl_sai_readable_reg, ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -17,6 +17,8 @@ - SNDRV_PCM_FMTBIT_DSD_U32_LE) - - /* SAI Register Map Register */ -+#define FSL_SAI_VERID 0x00 /* SAI Version ID Register */ -+#define FSL_SAI_PARAM 0x04 /* SAI Parameter Register */ - #define FSL_SAI_TCSR(offset) (0x00 + offset) /* SAI Transmit Control */ - #define FSL_SAI_TCR1(offset) (0x04 + offset) /* SAI Transmit Configuration 1 */ - #define FSL_SAI_TCR2(offset) (0x08 + offset) /* SAI Transmit Configuration 2 */ -@@ -39,8 +41,12 @@ - #define FSL_SAI_TFR5 0x54 /* SAI Transmit FIFO */ - #define FSL_SAI_TFR6 0x58 /* SAI Transmit FIFO */ - #define FSL_SAI_TFR7 0x5C /* SAI Transmit FIFO */ --#define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */ - #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */ -+#define FSL_SAI_TTCTL 0x70 /* SAI Transmit Timestamp Control Register */ -+#define FSL_SAI_TTCTN 0x74 /* SAI Transmit Timestamp Counter Register */ -+#define FSL_SAI_TBCTN 0x78 /* SAI Transmit Bit Counter Register */ -+#define FSL_SAI_TTCAP 0x7C /* SAI Transmit Timestamp Capture */ -+ - #define FSL_SAI_RCSR(offset) (0x80 + offset) /* SAI Receive Control */ - #define FSL_SAI_RCR1(offset) (0x84 + offset) /* SAI Receive Configuration 1 */ - #define FSL_SAI_RCR2(offset) (0x88 + offset) /* SAI Receive Configuration 2 */ -@@ -64,6 +70,13 @@ - #define FSL_SAI_RFR6 0xd8 /* SAI Receive FIFO */ - #define FSL_SAI_RFR7 0xdc /* SAI Receive FIFO */ - #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ -+#define FSL_SAI_RTCTL 0xf0 /* SAI Receive Timestamp Control Register */ -+#define FSL_SAI_RTCTN 0xf4 /* SAI Receive Timestamp Counter Register */ -+#define FSL_SAI_RBCTN 0xf8 /* SAI Receive Bit Counter Register */ -+#define FSL_SAI_RTCAP 0xfc /* SAI Receive Timestamp Capture */ -+ -+#define FSL_SAI_MCTL 0x100 /* SAI MCLK Control Register */ -+#define FSL_SAI_MDIV 0x104 /* SAI MCLK Divide Register */ - - #define FSL_SAI_xCSR(tx, off) (tx ? FSL_SAI_TCSR(off) : FSL_SAI_RCSR(off)) - #define FSL_SAI_xCR1(tx, off) (tx ? FSL_SAI_TCR1(off) : FSL_SAI_RCR1(off)) -@@ -109,6 +122,7 @@ - #define FSL_SAI_CR2_MSEL(ID) ((ID) << 26) - #define FSL_SAI_CR2_BCP BIT(25) - #define FSL_SAI_CR2_BCD_MSTR BIT(24) -+#define FSL_SAI_CR2_BCBP BIT(23) /* BCLK bypass */ - #define FSL_SAI_CR2_DIV_MASK 0xff - - /* SAI Transmit and Receive Configuration 3 Register */ -@@ -144,6 +158,33 @@ - #define FSL_SAI_CR5_FBT(x) ((x) << 8) - #define FSL_SAI_CR5_FBT_MASK (0x1f << 8) - -+/* SAI MCLK Control Register */ -+#define FSL_SAI_MCTL_MCLK_EN BIT(30) /* MCLK Enable */ -+#define FSL_SAI_MCTL_MSEL_MASK (0x3 << 24) -+#define FSL_SAI_MCTL_MSEL(ID) ((ID) << 24) -+#define FSL_SAI_MCTL_MSEL_BUS 0 -+#define FSL_SAI_MCTL_MSEL_MCLK1 BIT(24) -+#define FSL_SAI_MCTL_MSEL_MCLK2 BIT(25) -+#define FSL_SAI_MCTL_MSEL_MCLK3 (BIT(24) | BIT(25)) -+#define FSL_SAI_MCTL_DIV_EN BIT(23) -+#define FSL_SAI_MCTL_DIV_MASK 0xFF -+ -+/* SAI VERID Register */ -+#define FSL_SAI_VER_ID_SHIFT 16 -+#define FSL_SAI_VER_ID_MASK (0xFFFF << FSL_SAI_VER_ID_SHIFT) -+#define FSL_SAI_VER_EFIFO_EN BIT(0) -+#define FSL_SAI_VER_TSTMP_EN BIT(1) -+ -+/* SAI PARAM Register */ -+#define FSL_SAI_PAR_SPF_SHIFT 16 -+#define FSL_SAI_PAR_SPF_MASK (0x0F << FSL_SAI_PAR_SPF_SHIFT) -+#define FSL_SAI_PAR_WPF_SHIFT 8 -+#define FSL_SAI_PAR_WPF_MASK (0x0F << FSL_SAI_PAR_WPF_SHIFT) -+#define FSL_SAI_PAR_DLN_MASK (0x0F) -+ -+/* SAI MCLK Divide Register */ -+#define FSL_SAI_MDIV_MASK 0xFFFFF -+ - /* SAI type */ - #define FSL_SAI_DMA BIT(0) - #define FSL_SAI_USE_AC97 BIT(1) -@@ -181,6 +222,19 @@ struct fsl_sai_soc_data { - bool constrain_period_size; - }; - -+struct fsl_sai_verid { -+ u32 id; -+ bool timestamp_en; -+ bool extfifo_en; -+ bool loaded; -+}; -+ -+struct fsl_sai_param { -+ u32 spf; /* max slots per frame */ -+ u32 wpf; /* words in fifo */ -+ u32 dln; /* number of datalines implemented */ -+}; -+ - struct fsl_sai { - struct platform_device *pdev; - struct regmap *regmap; -@@ -213,6 +267,9 @@ struct fsl_sai { - struct pm_qos_request pm_qos_req; - struct pinctrl *pinctrl; - struct pinctrl_state *pins_state; -+ -+ struct fsl_sai_verid verid; -+ struct fsl_sai_param param; - }; - - #define TX 1 diff --git a/target/linux/layerscape/patches-5.4/801-audio-0051-MLK-18534-1-ASoC-fsl-sai-introduce-1-1-bclk-mclk-rat.patch b/target/linux/layerscape/patches-5.4/801-audio-0051-MLK-18534-1-ASoC-fsl-sai-introduce-1-1-bclk-mclk-rat.patch deleted file mode 100644 index 31033000c8..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0051-MLK-18534-1-ASoC-fsl-sai-introduce-1-1-bclk-mclk-rat.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 2e891d3d62f5fd51e33ae6e614198ce0b3b48e95 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Wed, 6 Jun 2018 13:36:20 +0300 -Subject: [PATCH] MLK-18534-1: ASoC: fsl: sai: introduce 1:1 bclk:mclk ratio - support - -Since IP version 3.01 (845s) SAI has support for 1:1 -bclk:mclk ratio. - -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 69 +++++++++++++++++++++++++------------------------ - sound/soc/fsl/fsl_sai.h | 2 +- - 2 files changed, 36 insertions(+), 35 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -471,7 +471,8 @@ static int fsl_sai_set_bclk(struct snd_s - struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); - unsigned char offset = sai->soc->reg_offset; - unsigned long clk_rate; -- u32 savediv = 0, ratio, savesub = freq; -+ unsigned int reg = 0; -+ u32 ratio, savesub = freq, saveratio = 0, savediv = 0; - u32 id; - int ret = 0; - -@@ -479,6 +480,8 @@ static int fsl_sai_set_bclk(struct snd_s - if (sai->slave_mode[tx]) - return 0; - -+ fsl_sai_check_ver(dai); -+ - for (id = 0; id < FSL_SAI_MCLK_MAX; id++) { - clk_rate = clk_get_rate(sai->mclk_clk[id]); - if (!clk_rate) -@@ -499,22 +502,21 @@ static int fsl_sai_set_bclk(struct snd_s - "ratio %d for freq %dHz based on clock %ldHz\n", - ratio, freq, clk_rate); - -- if (ratio % 2 == 0 && ratio >= 2 && ratio <= 512) -- ratio /= 2; -- else -- continue; -+ if ((ratio % 2 == 0 && ratio >= 2 && ratio <= 512) || -+ (ratio == 1 && sai->verid.id >= FSL_SAI_VERID_0301)) { - -- if (ret < savesub) { -- savediv = ratio; -- sai->mclk_id[tx] = id; -- savesub = ret; -- } -+ if (ret < savesub) { -+ saveratio = ratio; -+ sai->mclk_id[tx] = id; -+ savesub = ret; -+ } - -- if (ret == 0) -- break; -+ if (ret == 0) -+ break; -+ } - } - -- if (savediv == 0) { -+ if (saveratio == 0) { - dev_err(dai->dev, "failed to derive required %cx rate: %d\n", - tx ? 'T' : 'R', freq); - return -EINVAL; -@@ -530,33 +532,32 @@ static int fsl_sai_set_bclk(struct snd_s - * 4) For Tx and Rx are both Synchronous with another SAI, we just - * ignore it. - */ -- if ((sai->synchronous[TX] && !sai->synchronous[RX]) || -- (!tx && !sai->synchronous[RX])) { -- regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset), -- FSL_SAI_CR2_MSEL_MASK, -- FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); -- regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset), -- FSL_SAI_CR2_DIV_MASK, savediv - 1); -- } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) || -- (tx && !sai->synchronous[TX])) { -- regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset), -- FSL_SAI_CR2_MSEL_MASK, -- FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); -- regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset), -- FSL_SAI_CR2_DIV_MASK, savediv - 1); -+ if ((!tx || sai->synchronous[TX]) && !sai->synchronous[RX]) -+ reg = FSL_SAI_RCR2(offset); -+ else if ((tx || sai->synchronous[RX]) && !sai->synchronous[TX]) -+ reg = FSL_SAI_TCR2(offset); -+ -+ if (reg) { -+ regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_MSEL_MASK, -+ FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); -+ -+ savediv = (saveratio == 1 ? 0 : (saveratio >> 1) - 1); -+ regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_DIV_MASK, savediv); -+ -+ if (sai->verid.id >= FSL_SAI_VERID_0301) { -+ regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_BYP, -+ (saveratio == 1 ? FSL_SAI_CR2_BYP : 0)); -+ } - } - -- fsl_sai_check_ver(dai); -- switch (sai->verid.id) { -- case FSL_SAI_VERID_0301: -+ if (sai->verid.id >= FSL_SAI_VERID_0301) { - /* SAI is in master mode at this point, so enable MCLK */ - regmap_update_bits(sai->regmap, FSL_SAI_MCTL, -- FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN); -- break; -+ FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN); - } - -- dev_dbg(dai->dev, "best fit: clock id=%d, div=%d, deviation =%d\n", -- sai->mclk_id[tx], savediv, savesub); -+ dev_dbg(dai->dev, "best fit: clock id=%d, ratio=%d, deviation=%d\n", -+ sai->mclk_id[tx], saveratio, savesub); - - return 0; - } ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -122,7 +122,7 @@ - #define FSL_SAI_CR2_MSEL(ID) ((ID) << 26) - #define FSL_SAI_CR2_BCP BIT(25) - #define FSL_SAI_CR2_BCD_MSTR BIT(24) --#define FSL_SAI_CR2_BCBP BIT(23) /* BCLK bypass */ -+#define FSL_SAI_CR2_BYP BIT(23) /* BCLK bypass */ - #define FSL_SAI_CR2_DIV_MASK 0xff - - /* SAI Transmit and Receive Configuration 3 Register */ diff --git a/target/linux/layerscape/patches-5.4/801-audio-0052-MLK-18682-1-ASoC-fsl-sai-use-set_bclk_ratio-to-calcu.patch b/target/linux/layerscape/patches-5.4/801-audio-0052-MLK-18682-1-ASoC-fsl-sai-use-set_bclk_ratio-to-calcu.patch deleted file mode 100644 index 281974fc6b..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0052-MLK-18682-1-ASoC-fsl-sai-use-set_bclk_ratio-to-calcu.patch +++ /dev/null @@ -1,98 +0,0 @@ -From fc4146698489c4725c9ac86ea3e0484914d5285b Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Wed, 27 Jun 2018 10:31:02 +0300 -Subject: [PATCH] MLK-18682-1: ASoC: fsl: sai: use set_bclk_ratio to calculate - BCLK freq (part 1) - -ALSA API has a standard way to configure DAI BCLK by calling -"snd_soc_dai_set_bclk_ratio" function. So use it to set BCLK ratio -and calculate SAI BCLK frequency. - -Signed-off-by: Viorel Suman -[ Aisheng: split machine imx-pdm changes ] -Signed-off-by: Dong Aisheng ---- - sound/soc/fsl/fsl_sai.c | 21 +++++++++++++-------- - sound/soc/fsl/fsl_sai.h | 3 +-- - 2 files changed, 14 insertions(+), 10 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -234,6 +234,14 @@ static int fsl_sai_set_dai_sysclk_tr(str - return 0; - } - -+static int fsl_sai_set_dai_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) -+{ -+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); -+ -+ sai->bitclk_ratio = ratio; -+ return 0; -+} -+ - static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) - { -@@ -243,11 +251,6 @@ static int fsl_sai_set_dai_sysclk(struct - if (dir == SND_SOC_CLOCK_IN) - return 0; - -- if (clk_id == FSL_SAI_CLK_BIT) { -- sai->bitclk_freq = freq; -- return 0; -- } -- - if (freq > 0) { - if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) { - dev_err(cpu_dai->dev, "Unknown clock id: %d\n", clk_id); -@@ -571,6 +574,7 @@ static int fsl_sai_hw_params(struct snd_ - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - unsigned int channels = params_channels(params); - u32 word_width = params_width(params); -+ u32 rate = params_rate(params); - u32 val_cr4 = 0, val_cr5 = 0; - u32 slots = (channels == 1) ? 2 : channels; - u32 slot_width = word_width; -@@ -605,12 +609,12 @@ static int fsl_sai_hw_params(struct snd_ - slot_width = sai->slot_width; - - if (!sai->slave_mode[tx]) { -- if (sai->bitclk_freq) -+ if (sai->bitclk_ratio) - ret = fsl_sai_set_bclk(cpu_dai, tx, -- sai->bitclk_freq); -+ rate * sai->bitclk_ratio); - else - ret = fsl_sai_set_bclk(cpu_dai, tx, -- slots * slot_width * params_rate(params)); -+ rate * slots * slot_width); - if (ret) - return ret; - -@@ -935,6 +939,7 @@ static void fsl_sai_shutdown(struct snd_ - } - - static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { -+ .set_bclk_ratio = fsl_sai_set_dai_bclk_ratio, - .set_sysclk = fsl_sai_set_dai_sysclk, - .set_fmt = fsl_sai_set_dai_fmt, - .set_tdm_slot = fsl_sai_set_dai_tdm_slot, ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -203,7 +203,6 @@ - #define FSL_SAI_CLK_MAST3 3 - - #define FSL_SAI_MCLK_MAX 4 --#define FSL_SAI_CLK_BIT 5 - - /* SAI data transfer numbers per DMA request */ - #define FSL_SAI_MAXBURST_TX 6 -@@ -258,7 +257,7 @@ struct fsl_sai { - unsigned int mclk_streams; - unsigned int slots; - unsigned int slot_width; -- unsigned int bitclk_freq; -+ unsigned int bitclk_ratio; - - struct snd_soc_dai_driver cpu_dai_drv; - struct snd_dmaengine_dai_dma_data dma_params_rx; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0053-MLK-18682-2-ASoC-fsl-sai-allow-dynamic-pll-switching.patch b/target/linux/layerscape/patches-5.4/801-audio-0053-MLK-18682-2-ASoC-fsl-sai-allow-dynamic-pll-switching.patch deleted file mode 100644 index 373305d1c9..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0053-MLK-18682-2-ASoC-fsl-sai-allow-dynamic-pll-switching.patch +++ /dev/null @@ -1,121 +0,0 @@ -From b2dd96ec88b7eb4288ca39a1fc78176872c0683b Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Wed, 27 Jun 2018 10:59:12 +0300 -Subject: [PATCH] MLK-18682-2: ASoC: fsl: sai: allow dynamic pll switching - -Currently SAI master clock derives from an audio pll that cannot be -changed at runtime. iMX8 SoC has 2 audio plls usually configured to support -either 8000Hz (8k,16k,32k,48k,etc) or 11025Hz (11k,22k,44.1k,88.2k,etc) -ranges of rates - thus at runtime a SAI interface is able to play only one -range of rates. The patch allows dynamic SAI master clock reparenting to -the appropriate audio pll as function of the audio stream rate to be -played/recorded. - -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 60 ++++++++++++++++++++++++++++++++++++++++++++----- - sound/soc/fsl/fsl_sai.h | 2 ++ - 2 files changed, 57 insertions(+), 5 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -5,6 +5,7 @@ - // Copyright 2012-2016 Freescale Semiconductor, Inc. - - #include -+#include - #include - #include - #include -@@ -234,6 +235,50 @@ static int fsl_sai_set_dai_sysclk_tr(str - return 0; - } - -+static int fsl_sai_set_mclk_rate(struct snd_soc_dai *dai, int clk_id, -+ unsigned int freq) -+{ -+ struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); -+ struct clk *p = sai->mclk_clk[clk_id], *pll = 0, *npll = 0; -+ u64 ratio = freq; -+ int ret; -+ -+ while (p && sai->pll8k_clk && sai->pll11k_clk) { -+ struct clk *pp = clk_get_parent(p); -+ -+ if (clk_is_match(pp, sai->pll8k_clk) || -+ clk_is_match(pp, sai->pll11k_clk)) { -+ pll = pp; -+ break; -+ } -+ p = pp; -+ } -+ -+ if (pll) { -+ npll = (do_div(ratio, 8000) ? sai->pll11k_clk : sai->pll8k_clk); -+ if (!clk_is_match(pll, npll)) { -+ if (sai->mclk_streams == 0) { -+ ret = clk_set_parent(p, npll); -+ if (ret < 0) -+ dev_warn(dai->dev, -+ "failed to set parent %s: %d\n", -+ __clk_get_name(npll), ret); -+ } else { -+ dev_err(dai->dev, -+ "PLL %s is in use by a running stream.\n", -+ __clk_get_name(pll)); -+ return -EINVAL; -+ } -+ } -+ } -+ -+ ret = clk_set_rate(sai->mclk_clk[clk_id], freq); -+ if (ret < 0) -+ dev_err(dai->dev, "failed to set clock rate (%u): %d\n", -+ freq, ret); -+ return ret; -+} -+ - static int fsl_sai_set_dai_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) - { - struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); -@@ -262,12 +307,9 @@ static int fsl_sai_set_dai_sysclk(struct - return -EINVAL; - } - -- ret = clk_set_rate(sai->mclk_clk[clk_id], freq); -- if (ret < 0) { -- dev_err(cpu_dai->dev, "failed to set clock rate (%u): %d\n", -- freq, ret); -+ ret = fsl_sai_set_mclk_rate(cpu_dai, clk_id, freq); -+ if (ret < 0) - return ret; -- } - } - - ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, -@@ -1288,6 +1330,14 @@ static int fsl_sai_probe(struct platform - } - } - -+ sai->pll8k_clk = devm_clk_get(&pdev->dev, "pll8k"); -+ if (IS_ERR(sai->pll8k_clk)) -+ sai->pll8k_clk = NULL; -+ -+ sai->pll11k_clk = devm_clk_get(&pdev->dev, "pll11k"); -+ if (IS_ERR(sai->pll11k_clk)) -+ sai->pll11k_clk = NULL; -+ - if (of_find_property(np, "fsl,sai-multi-lane", NULL)) - sai->is_multi_lane = true; - ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -239,6 +239,8 @@ struct fsl_sai { - struct regmap *regmap; - struct clk *bus_clk; - struct clk *mclk_clk[FSL_SAI_MCLK_MAX]; -+ struct clk *pll8k_clk; -+ struct clk *pll11k_clk; - - bool slave_mode[2]; - bool is_lsb_first; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0054-MLK-18947-ASoC-fsl_sai-fix-volatile-function.patch b/target/linux/layerscape/patches-5.4/801-audio-0054-MLK-18947-ASoC-fsl_sai-fix-volatile-function.patch deleted file mode 100644 index 7004219803..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0054-MLK-18947-ASoC-fsl_sai-fix-volatile-function.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 84b1defe99a15b96d32f4c2fecb2c8e9149f696c Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Wed, 15 Aug 2018 09:53:07 +0800 -Subject: [PATCH] MLK-18947: ASoC: fsl_sai: fix volatile function - -The FSL_SAI_VERID and FSL_SAI_PARAM only available -when reg_offset is 8 - -Signed-off-by: Shengjiu Wang -(cherry picked from commit 0a0695672dc7ecf07a7642ff6f99f0b9d3a26b32) ---- - sound/soc/fsl/fsl_sai.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -1162,9 +1162,11 @@ static bool fsl_sai_volatile_reg(struct - if (reg == FSL_SAI_TCSR(offset) || reg == FSL_SAI_RCSR(offset)) - return true; - -+ if (sai->soc->reg_offset == 8 && (reg == FSL_SAI_VERID || -+ reg == FSL_SAI_PARAM)) -+ return true; -+ - switch (reg) { -- case FSL_SAI_VERID: -- case FSL_SAI_PARAM: - case FSL_SAI_TFR0: - case FSL_SAI_TFR1: - case FSL_SAI_TFR2: diff --git a/target/linux/layerscape/patches-5.4/801-audio-0055-MLK-18898-1-ASoC-fsl_sai-select-pinctrl-state-as-fun.patch b/target/linux/layerscape/patches-5.4/801-audio-0055-MLK-18898-1-ASoC-fsl_sai-select-pinctrl-state-as-fun.patch deleted file mode 100644 index 2912d7632d..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0055-MLK-18898-1-ASoC-fsl_sai-select-pinctrl-state-as-fun.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 001937cc21a05165530c0775c4646bd04e797658 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Mon, 27 Aug 2018 13:50:17 +0300 -Subject: [PATCH] MLK-18898-1: ASoC: fsl_sai: select pinctrl state as function - of bitclock rate - -Similar to DSD512 case we need a PCM pinctrl state option to map SAI BCLK -to codec MCLK pin. Given that bitclock rate is function of slots number and -slot width - pass bclk rate as parameter value from SAI driver. - -Signed-off-by: Viorel Suman -(cherry picked from commit 826caeae32713cff7ad50de8ebc9915de975edd9) ---- - sound/soc/fsl/fsl_dsd.h | 15 +++++++-------- - sound/soc/fsl/fsl_sai.c | 24 ++++++++++-------------- - 2 files changed, 17 insertions(+), 22 deletions(-) - ---- a/sound/soc/fsl/fsl_dsd.h -+++ b/sound/soc/fsl/fsl_dsd.h -@@ -30,23 +30,22 @@ static bool fsl_is_dsd(struct snd_pcm_hw - } - - static struct pinctrl_state *fsl_get_pins_state(struct pinctrl *pinctrl, -- struct snd_pcm_hw_params *params) -+ struct snd_pcm_hw_params *params, u32 bclk) - { -- int dsd_bclk; - struct pinctrl_state *state = 0; - - if (fsl_is_dsd(params)) { -- dsd_bclk = params_rate(params) * params_physical_width(params); -- -- switch (dsd_bclk) { -- case 22579200: /* DSD512 */ -+ /* DSD512@44.1kHz, DSD512@48kHz */ -+ if (bclk >= 22579200) - state = pinctrl_lookup_state(pinctrl, "dsd512"); -- break; -- } - - /* Get default DSD state */ - if (IS_ERR_OR_NULL(state)) - state = pinctrl_lookup_state(pinctrl, "dsd"); -+ } else { -+ /* 706k32b2c, 768k32b2c, etc */ -+ if (bclk >= 45158400) -+ state = pinctrl_lookup_state(pinctrl, "pcm_b2m"); - } - - /* Get default state */ ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -620,7 +620,7 @@ static int fsl_sai_hw_params(struct snd_ - u32 val_cr4 = 0, val_cr5 = 0; - u32 slots = (channels == 1) ? 2 : channels; - u32 slot_width = word_width; -- u32 pins; -+ u32 pins, bclk; - int ret; - int i; - int trce_mask = 0; -@@ -630,9 +630,16 @@ static int fsl_sai_hw_params(struct snd_ - - pins = DIV_ROUND_UP(channels, slots); - sai->is_dsd = fsl_is_dsd(params); -+ if (sai->is_dsd) -+ pins = channels; -+ -+ if (sai->slot_width) -+ slot_width = sai->slot_width; -+ -+ bclk = rate*(sai->bitclk_ratio ? sai->bitclk_ratio : slots * slot_width); - - if (!IS_ERR_OR_NULL(sai->pinctrl)) { -- sai->pins_state = fsl_get_pins_state(sai->pinctrl, params); -+ sai->pins_state = fsl_get_pins_state(sai->pinctrl, params, bclk); - - if (!IS_ERR_OR_NULL(sai->pins_state)) { - ret = pinctrl_select_state(sai->pinctrl, sai->pins_state); -@@ -644,19 +651,8 @@ static int fsl_sai_hw_params(struct snd_ - } - } - -- if (sai->is_dsd) -- pins = channels; -- -- if (sai->slot_width) -- slot_width = sai->slot_width; -- - if (!sai->slave_mode[tx]) { -- if (sai->bitclk_ratio) -- ret = fsl_sai_set_bclk(cpu_dai, tx, -- rate * sai->bitclk_ratio); -- else -- ret = fsl_sai_set_bclk(cpu_dai, tx, -- rate * slots * slot_width); -+ ret = fsl_sai_set_bclk(cpu_dai, tx, bclk); - if (ret) - return ret; - diff --git a/target/linux/layerscape/patches-5.4/801-audio-0056-MLK-19573-1-ASoC-fsl-dsd-make-fsl_get_pins_state-inl.patch b/target/linux/layerscape/patches-5.4/801-audio-0056-MLK-19573-1-ASoC-fsl-dsd-make-fsl_get_pins_state-inl.patch deleted file mode 100644 index aa405334c8..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0056-MLK-19573-1-ASoC-fsl-dsd-make-fsl_get_pins_state-inl.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 7d66ca1081c0626f03aa8f419ca253e88a10018e Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Mon, 17 Sep 2018 09:31:24 +0300 -Subject: [PATCH] MLK-19573-1: ASoC: fsl: dsd: make fsl_get_pins_state inline - -Make fsl_get_pins_state function inline. - -Signed-off-by: Viorel Suman -(cherry picked from commit badcb97ebd8c0aae89f76e979bcc801be35c7400) ---- - sound/soc/fsl/fsl_dsd.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sound/soc/fsl/fsl_dsd.h -+++ b/sound/soc/fsl/fsl_dsd.h -@@ -29,7 +29,7 @@ static bool fsl_is_dsd(struct snd_pcm_hw - } - } - --static struct pinctrl_state *fsl_get_pins_state(struct pinctrl *pinctrl, -+static inline struct pinctrl_state *fsl_get_pins_state(struct pinctrl *pinctrl, - struct snd_pcm_hw_params *params, u32 bclk) - { - struct pinctrl_state *state = 0; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0057-MLK-15975-3-ASoC-fsl_sai-The-offset-of-fifo_off-is-c.patch b/target/linux/layerscape/patches-5.4/801-audio-0057-MLK-15975-3-ASoC-fsl_sai-The-offset-of-fifo_off-is-c.patch deleted file mode 100644 index 8a01eaf878..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0057-MLK-15975-3-ASoC-fsl_sai-The-offset-of-fifo_off-is-c.patch +++ /dev/null @@ -1,41 +0,0 @@ -From af52be88c689521364e06924e26c8989a075e0e3 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Fri, 28 Sep 2018 15:33:34 +0800 -Subject: [PATCH] MLK-15975-3: ASoC: fsl_sai: The offset of fifo_off is changed - -Commit 786c8bd56324 ("MLK-19734-3: dmaengine: imx-sdma: change -fifo offset of fifo_num") change the offset of fifo_off, so -the sai driver need to be updated. - -Signed-off-by: Shengjiu Wang -(cherry picked from commit c94ce8776e01f1f40a866d4da89603ab042dde0f) ---- - sound/soc/fsl/fsl_sai.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -726,19 +726,19 @@ static int fsl_sai_hw_params(struct snd_ - FSL_SAI_MAXBURST_TX * pins; - if (sai->is_dsd) - sai->dma_params_tx.fifo_num = pins + -- (sai->dataline_off_dsd[tx] << 8); -+ (sai->dataline_off_dsd[tx] << 4); - else - sai->dma_params_tx.fifo_num = pins + -- (sai->dataline_off[tx] << 8); -+ (sai->dataline_off[tx] << 4); - } else { - sai->dma_params_rx.maxburst = - FSL_SAI_MAXBURST_RX * pins; - if (sai->is_dsd) - sai->dma_params_rx.fifo_num = pins + -- (sai->dataline_off_dsd[tx] << 8); -+ (sai->dataline_off_dsd[tx] << 4); - else - sai->dma_params_rx.fifo_num = pins + -- (sai->dataline_off[tx] << 8); -+ (sai->dataline_off[tx] << 4); - } - } - diff --git a/target/linux/layerscape/patches-5.4/801-audio-0058-MLK-20189-8-ASoC-fsl_sai-use-signed-offset-variable.patch b/target/linux/layerscape/patches-5.4/801-audio-0058-MLK-20189-8-ASoC-fsl_sai-use-signed-offset-variable.patch deleted file mode 100644 index 97f4cb0350..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0058-MLK-20189-8-ASoC-fsl_sai-use-signed-offset-variable.patch +++ /dev/null @@ -1,53 +0,0 @@ -From d8802def525b4f74f66fca02afe9c17a729a3201 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Tue, 13 Nov 2018 11:36:29 +0200 -Subject: [PATCH] MLK-20189-8: ASoC: fsl_sai: use signed offset variable - -Both dataline_off and dataline_off_dsd fields are unsigned, -thus checking negative values make no sense. Use a signed -variable to calculate offset instead. - -This fixes Coverity issue: CID1899299 - -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 14 +++++--------- - 1 file changed, 5 insertions(+), 9 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -1273,7 +1273,7 @@ static int fsl_sai_probe(struct platform - char tmp[8]; - int irq, ret, i; - int index; -- int firstbitidx, nextbitidx; -+ int firstbitidx, nextbitidx, offset; - struct regmap_config fsl_sai_regmap_config = fsl_sai_v2_regmap_config; - unsigned long irqflags = 0; - -@@ -1356,10 +1356,8 @@ static int fsl_sai_probe(struct platform - for (i = 0; i < 2; i++) { - firstbitidx = find_first_bit((const unsigned long *)&sai->dataline[i], 8); - nextbitidx = find_next_bit((const unsigned long *)&sai->dataline[i], 8, firstbitidx+1); -- sai->dataline_off[i] = nextbitidx - firstbitidx - 1; -- -- if (sai->dataline_off[i] < 0 || sai->dataline_off[i] >= 7) -- sai->dataline_off[i] = 0; -+ offset = nextbitidx - firstbitidx - 1; -+ sai->dataline_off[i] = (offset < 0 || offset >= 7 ? 0 : offset); - } - - ret = of_property_read_u32_index(np, "fsl,dataline,dsd", 0, &sai->dataline_dsd[0]); -@@ -1378,10 +1376,8 @@ static int fsl_sai_probe(struct platform - for (i = 0; i < 2; i++) { - firstbitidx = find_first_bit((const unsigned long *)&sai->dataline_dsd[i], 8); - nextbitidx = find_next_bit((const unsigned long *)&sai->dataline_dsd[i], 8, firstbitidx+1); -- sai->dataline_off_dsd[i] = nextbitidx - firstbitidx - 1; -- -- if (sai->dataline_off_dsd[i] < 0 || sai->dataline_off_dsd[i] >= 7) -- sai->dataline_off_dsd[i] = 0; -+ offset = nextbitidx - firstbitidx - 1; -+ sai->dataline_off_dsd[i] = (offset < 0 || offset >= 7 ? 0 : offset); - } - - if ((of_find_property(np, "fsl,i2s-xtor", NULL) != NULL) || diff --git a/target/linux/layerscape/patches-5.4/801-audio-0059-MLK-20328-1-ASoC-fsl_sai-map-number-of-pins-to-datal.patch b/target/linux/layerscape/patches-5.4/801-audio-0059-MLK-20328-1-ASoC-fsl_sai-map-number-of-pins-to-datal.patch deleted file mode 100644 index 4f1bcea90c..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0059-MLK-20328-1-ASoC-fsl_sai-map-number-of-pins-to-datal.patch +++ /dev/null @@ -1,373 +0,0 @@ -From e62741891f6901b5219eacdf60835cac9beb7bae Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Wed, 21 Nov 2018 16:09:44 +0200 -Subject: [PATCH] MLK-20328-1: ASoC: fsl_sai: map number of pins to dataline - masks - -The patch enable mapping the number of pins required to play or record -a specific number of channels to a specific dataline mask. - -Three consequent elements in "fsl,dataline" and "fsl,dataline,dsd" defines a -particular mapping, for instance for: fsl,dataline = "0 0xff 0xff 2 0x11 0x11" -there are two mappings defined: - -default (0 pins) "rx" and "tx" dataline masks: 0 0xff 0xff - 2 pins "rx" and "tx" dataline masks: 2 0x11 0x11 - -In case if property is missing, then default value "0 0x1 0x1" is considered. - -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 227 ++++++++++++++++++++++++++++++------------------ - sound/soc/fsl/fsl_sai.h | 16 +++- - 2 files changed, 153 insertions(+), 90 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -621,17 +621,35 @@ static int fsl_sai_hw_params(struct snd_ - u32 slots = (channels == 1) ? 2 : channels; - u32 slot_width = word_width; - u32 pins, bclk; -- int ret; -- int i; -- int trce_mask = 0; -+ int ret, i, trce_mask = 0, dl_cfg_cnt, dl_cfg_idx = 0; -+ struct fsl_sai_dl_cfg *dl_cfg; - - if (sai->slots) - slots = sai->slots; - - pins = DIV_ROUND_UP(channels, slots); - sai->is_dsd = fsl_is_dsd(params); -- if (sai->is_dsd) -+ if (sai->is_dsd) { - pins = channels; -+ dl_cfg = sai->dsd_dl_cfg; -+ dl_cfg_cnt = sai->dsd_dl_cfg_cnt; -+ } else { -+ dl_cfg = sai->pcm_dl_cfg; -+ dl_cfg_cnt = sai->pcm_dl_cfg_cnt; -+ } -+ -+ for (i = 0; i < dl_cfg_cnt; i++) { -+ if (dl_cfg[i].pins == pins) { -+ dl_cfg_idx = i; -+ break; -+ } -+ } -+ -+ if (dl_cfg_idx >= dl_cfg_cnt) { -+ dev_err(cpu_dai->dev, "fsl,dataline%s invalid or not provided.\n", -+ sai->is_dsd ? ",dsd" : ""); -+ return -EINVAL; -+ } - - if (sai->slot_width) - slot_width = sai->slot_width; -@@ -713,7 +731,7 @@ static int fsl_sai_hw_params(struct snd_ - - if (sai->soc->dataline != 0x1) { - -- if (sai->dataline[tx] <= 1 || sai->is_multi_lane) -+ if (dl_cfg[dl_cfg_idx].mask[tx] <= 1 || sai->is_multi_lane) - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_FCOMB_MASK, 0); - else -@@ -724,21 +742,13 @@ static int fsl_sai_hw_params(struct snd_ - if (tx) { - sai->dma_params_tx.maxburst = - FSL_SAI_MAXBURST_TX * pins; -- if (sai->is_dsd) -- sai->dma_params_tx.fifo_num = pins + -- (sai->dataline_off_dsd[tx] << 4); -- else -- sai->dma_params_tx.fifo_num = pins + -- (sai->dataline_off[tx] << 4); -+ sai->dma_params_tx.fifo_num = pins + -+ (dl_cfg[dl_cfg_idx].offset[tx] << 4); - } else { - sai->dma_params_rx.maxburst = - FSL_SAI_MAXBURST_RX * pins; -- if (sai->is_dsd) -- sai->dma_params_rx.fifo_num = pins + -- (sai->dataline_off_dsd[tx] << 4); -- else -- sai->dma_params_rx.fifo_num = pins + -- (sai->dataline_off[tx] << 4); -+ sai->dma_params_rx.fifo_num = pins + -+ (dl_cfg[dl_cfg_idx].offset[tx] << 4); - } - } - -@@ -746,38 +756,22 @@ static int fsl_sai_hw_params(struct snd_ - &sai->dma_params_rx); - } - -- if (sai->is_dsd) { -- if (__sw_hweight8(sai->dataline_dsd[tx] & 0xFF) < pins) { -- dev_err(cpu_dai->dev, "channel not supported\n"); -- return -EINVAL; -- } -- /*find a proper tcre setting*/ -- for (i = 0; i < 8; i++) { -- trce_mask = (1 << (i + 1)) - 1; -- if (__sw_hweight8(sai->dataline_dsd[tx] & trce_mask) == pins) -- break; -- } -- -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -- FSL_SAI_CR3_TRCE_MASK, -- FSL_SAI_CR3_TRCE((sai->dataline_dsd[tx] & trce_mask))); -- } else { -- if (__sw_hweight8(sai->dataline[tx] & 0xFF) < pins) { -- dev_err(cpu_dai->dev, "channel not supported\n"); -- return -EINVAL; -- } -- /*find a proper tcre setting*/ -- for (i = 0; i < 8; i++) { -- trce_mask = (1 << (i + 1)) - 1; -- if (__sw_hweight8(sai->dataline[tx] & trce_mask) == pins) -- break; -- } -+ if (__sw_hweight8(dl_cfg[dl_cfg_idx].mask[tx] & 0xFF) < pins) { -+ dev_err(cpu_dai->dev, "channel not supported\n"); -+ return -EINVAL; -+ } - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -- FSL_SAI_CR3_TRCE_MASK, -- FSL_SAI_CR3_TRCE((sai->dataline[tx] & trce_mask))); -+ /*find a proper tcre setting*/ -+ for (i = 0; i < 8; i++) { -+ trce_mask = (1 << (i + 1)) - 1; -+ if (__sw_hweight8(dl_cfg[dl_cfg_idx].mask[tx] & trce_mask) == pins) -+ break; - } - -+ regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -+ FSL_SAI_CR3_TRCE_MASK, -+ FSL_SAI_CR3_TRCE((dl_cfg[dl_cfg_idx].mask[tx] & trce_mask))); -+ - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset), - FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | - FSL_SAI_CR4_CHMOD_MASK, -@@ -820,15 +814,32 @@ static int fsl_sai_trigger(struct snd_pc - u32 slots = (channels == 1) ? 2 : channels; - u32 xcsr, count = 100; - u32 pins; -- int i = 0, j = 0, k = 0; -+ int i = 0, j = 0, k = 0, dl_cfg_cnt, dl_cfg_idx = 0; -+ struct fsl_sai_dl_cfg *dl_cfg; - - if (sai->slots) - slots = sai->slots; - - pins = DIV_ROUND_UP(channels, slots); - -- if (sai->is_dsd) -+ if (sai->is_dsd) { - pins = channels; -+ dl_cfg = sai->dsd_dl_cfg; -+ dl_cfg_cnt = sai->dsd_dl_cfg_cnt; -+ } else { -+ dl_cfg = sai->pcm_dl_cfg; -+ dl_cfg_cnt = sai->pcm_dl_cfg_cnt; -+ } -+ -+ for (i = 0; i < dl_cfg_cnt; i++) { -+ if (dl_cfg[i].pins == pins) { -+ dl_cfg_idx = i; -+ break; -+ } -+ } -+ -+ i = 0; -+ - /* - * Asynchronous mode: Clear SYNC for both Tx and Rx. - * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. -@@ -849,7 +860,7 @@ static int fsl_sai_trigger(struct snd_pc - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - - while (tx && i < channels) { -- if ((sai->is_dsd ? sai->dataline_dsd[tx] : sai->dataline[tx]) & (1 << j)) { -+ if (dl_cfg[dl_cfg_idx].mask[tx] & (1 << j)) { - regmap_write(sai->regmap, FSL_SAI_TDR0 + j * 0x4, 0x0); - i++; - k++; -@@ -1262,6 +1273,77 @@ static const struct of_device_id fsl_sai - }; - MODULE_DEVICE_TABLE(of, fsl_sai_ids); - -+static unsigned int fsl_sai_calc_dl_off(unsigned int* dl_mask) -+{ -+ int fbidx, nbidx, offset; -+ -+ fbidx = find_first_bit((const unsigned long *)dl_mask, 8); -+ nbidx = find_next_bit((const unsigned long *)dl_mask, 8, fbidx+1); -+ offset = nbidx - fbidx - 1; -+ -+ return (offset < 0 || offset >= 7 ? 0 : offset); -+} -+ -+static int fsl_sai_read_dlcfg(struct platform_device *pdev, char *pn, -+ struct fsl_sai_dl_cfg **rcfg, unsigned int soc_dl) -+{ -+ int ret, elems, i, index, num_cfg; -+ struct device_node *np = pdev->dev.of_node; -+ struct fsl_sai_dl_cfg *cfg; -+ u32 rx, tx, pins; -+ -+ *rcfg = NULL; -+ -+ elems = of_property_count_u32_elems(np, pn); -+ -+ /* consider default value "0 0x1 0x1" if property is missing */ -+ if (elems <= 0) -+ elems = 3; -+ -+ if (elems % 3) { -+ dev_err(&pdev->dev, -+ "Number of elements in %s must be divisible to 3.\n", pn); -+ return -EINVAL; -+ } -+ -+ num_cfg = elems / 3; -+ cfg = devm_kzalloc(&pdev->dev, num_cfg * sizeof(*cfg), GFP_KERNEL); -+ if (cfg == NULL) { -+ dev_err(&pdev->dev, "Cannot allocate memory for %s.\n", pn); -+ return -ENOMEM; -+ } -+ -+ for (i = 0, index = 0; i < num_cfg; i++) { -+ ret = of_property_read_u32_index(np, pn, index++, &pins); -+ if (ret) -+ pins = 0; -+ -+ ret = of_property_read_u32_index(np, pn, index++, &rx); -+ if (ret) -+ rx = 1; -+ -+ ret = of_property_read_u32_index(np, pn, index++, &tx); -+ if (ret) -+ tx = 1; -+ -+ if ((rx & ~soc_dl) || (tx & ~soc_dl)) { -+ dev_err(&pdev->dev, -+ "%s: dataline cfg[%d] setting error, mask is 0x%x\n", -+ pn, i, soc_dl); -+ return -EINVAL; -+ } -+ -+ cfg[i].pins = pins; -+ cfg[i].mask[0] = rx; -+ cfg[i].offset[0] = fsl_sai_calc_dl_off(&rx); -+ cfg[i].mask[1] = tx; -+ cfg[i].offset[1] = fsl_sai_calc_dl_off(&tx); -+ } -+ -+ *rcfg = cfg; -+ return num_cfg; -+} -+ - static int fsl_sai_probe(struct platform_device *pdev) - { - struct device_node *np = pdev->dev.of_node; -@@ -1273,7 +1355,6 @@ static int fsl_sai_probe(struct platform - char tmp[8]; - int irq, ret, i; - int index; -- int firstbitidx, nextbitidx, offset; - struct regmap_config fsl_sai_regmap_config = fsl_sai_v2_regmap_config; - unsigned long irqflags = 0; - -@@ -1340,45 +1421,19 @@ static int fsl_sai_probe(struct platform - sai->is_multi_lane = true; - - /*dataline mask for rx and tx*/ -- ret = of_property_read_u32_index(np, "fsl,dataline", 0, &sai->dataline[0]); -- if (ret) -- sai->dataline[0] = 1; -- -- ret = of_property_read_u32_index(np, "fsl,dataline", 1, &sai->dataline[1]); -- if (ret) -- sai->dataline[1] = 1; -- -- if ((sai->dataline[0] & (~sai->soc->dataline)) || sai->dataline[1] & (~sai->soc->dataline)) { -- dev_err(&pdev->dev, "dataline setting error, Mask is 0x%x\n", sai->soc->dataline); -- return -EINVAL; -- } -- -- for (i = 0; i < 2; i++) { -- firstbitidx = find_first_bit((const unsigned long *)&sai->dataline[i], 8); -- nextbitidx = find_next_bit((const unsigned long *)&sai->dataline[i], 8, firstbitidx+1); -- offset = nextbitidx - firstbitidx - 1; -- sai->dataline_off[i] = (offset < 0 || offset >= 7 ? 0 : offset); -- } -- -- ret = of_property_read_u32_index(np, "fsl,dataline,dsd", 0, &sai->dataline_dsd[0]); -- if (ret) -- sai->dataline_dsd[0] = 1; -- -- ret = of_property_read_u32_index(np, "fsl,dataline,dsd", 1, &sai->dataline_dsd[1]); -- if (ret) -- sai->dataline_dsd[1] = 1; -+ ret = fsl_sai_read_dlcfg(pdev, "fsl,dataline", &sai->pcm_dl_cfg, -+ sai->soc->dataline); -+ if (ret < 0) -+ return ret; -+ -+ sai->pcm_dl_cfg_cnt = ret; -+ -+ ret = fsl_sai_read_dlcfg(pdev, "fsl,dataline,dsd", &sai->dsd_dl_cfg, -+ sai->soc->dataline); -+ if (ret < 0) -+ return ret; - -- if ((sai->dataline_dsd[0] & (~sai->soc->dataline)) || sai->dataline_dsd[1] & (~sai->soc->dataline)) { -- dev_err(&pdev->dev, "dataline setting error, Mask is 0x%x\n", sai->soc->dataline); -- return -EINVAL; -- } -- -- for (i = 0; i < 2; i++) { -- firstbitidx = find_first_bit((const unsigned long *)&sai->dataline_dsd[i], 8); -- nextbitidx = find_next_bit((const unsigned long *)&sai->dataline_dsd[i], 8, firstbitidx+1); -- offset = nextbitidx - firstbitidx - 1; -- sai->dataline_off_dsd[i] = (offset < 0 || offset >= 7 ? 0 : offset); -- } -+ sai->dsd_dl_cfg_cnt = ret; - - if ((of_find_property(np, "fsl,i2s-xtor", NULL) != NULL) || - (of_find_property(np, "fsl,txm-rxs", NULL) != NULL)) ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -234,6 +234,12 @@ struct fsl_sai_param { - u32 dln; /* number of datalines implemented */ - }; - -+struct fsl_sai_dl_cfg { -+ unsigned int pins; -+ unsigned int mask[2]; -+ unsigned int offset[2]; -+}; -+ - struct fsl_sai { - struct platform_device *pdev; - struct regmap *regmap; -@@ -249,10 +255,12 @@ struct fsl_sai { - bool synchronous[2]; - bool is_stream_opened[2]; - bool is_dsd; -- unsigned int dataline[2]; -- unsigned int dataline_dsd[2]; -- unsigned int dataline_off[2]; -- unsigned int dataline_off_dsd[2]; -+ -+ int pcm_dl_cfg_cnt; -+ int dsd_dl_cfg_cnt; -+ struct fsl_sai_dl_cfg *pcm_dl_cfg; -+ struct fsl_sai_dl_cfg *dsd_dl_cfg; -+ - unsigned int masterflag[2]; - - unsigned int mclk_id[2]; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0060-ASoC-fsl_sai-Support-EPROBE_DEFER.patch b/target/linux/layerscape/patches-5.4/801-audio-0060-ASoC-fsl_sai-Support-EPROBE_DEFER.patch deleted file mode 100644 index 56d259af69..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0060-ASoC-fsl_sai-Support-EPROBE_DEFER.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 906ed2027fe62acf79be975c06fc297e77331191 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Tue, 29 Jan 2019 14:41:39 +0800 -Subject: [PATCH] ASoC: fsl_sai: Support -EPROBE_DEFER - -Support -EPROBE_DEFER for the resource is not ready in time - -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -1383,7 +1383,7 @@ static int fsl_sai_probe(struct platform - "bus", base, &fsl_sai_regmap_config); - - /* Compatible with old DTB cases */ -- if (IS_ERR(sai->regmap)) -+ if (IS_ERR(sai->regmap) && PTR_ERR(sai->regmap) != -EPROBE_DEFER) - sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, - "sai", base, &fsl_sai_regmap_config); - if (IS_ERR(sai->regmap)) { diff --git a/target/linux/layerscape/patches-5.4/801-audio-0061-ASoC-fsl_sai-support-multi-power-domain.patch b/target/linux/layerscape/patches-5.4/801-audio-0061-ASoC-fsl_sai-support-multi-power-domain.patch deleted file mode 100644 index 63c77db19d..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0061-ASoC-fsl_sai-support-multi-power-domain.patch +++ /dev/null @@ -1,55 +0,0 @@ -From f11933205182a3da44e7f99d899dd27adafcb6d5 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Tue, 29 Jan 2019 14:51:24 +0800 -Subject: [PATCH] ASoC: fsl_sai: support multi power domain - -support multi power domain - -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1357,6 +1358,7 @@ static int fsl_sai_probe(struct platform - int index; - struct regmap_config fsl_sai_regmap_config = fsl_sai_v2_regmap_config; - unsigned long irqflags = 0; -+ int num_domains = 0; - - sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); - if (!sai) -@@ -1409,6 +1411,24 @@ static int fsl_sai_probe(struct platform - } - } - -+ num_domains = of_count_phandle_with_args(np, "power-domains", -+ "#power-domain-cells"); -+ for (i = 0; i < num_domains; i++) { -+ struct device *pd_dev; -+ struct device_link *link; -+ -+ pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, i); -+ if (IS_ERR(pd_dev)) -+ return PTR_ERR(pd_dev); -+ -+ link = device_link_add(&pdev->dev, pd_dev, -+ DL_FLAG_STATELESS | -+ DL_FLAG_PM_RUNTIME | -+ DL_FLAG_RPM_ACTIVE); -+ if (IS_ERR(link)) -+ return PTR_ERR(link); -+ } -+ - sai->pll8k_clk = devm_clk_get(&pdev->dev, "pll8k"); - if (IS_ERR(sai->pll8k_clk)) - sai->pll8k_clk = NULL; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0062-ASoC-fsl-sai-fix-build-failture-due-to-5.1-RC7-upgra.patch b/target/linux/layerscape/patches-5.4/801-audio-0062-ASoC-fsl-sai-fix-build-failture-due-to-5.1-RC7-upgra.patch deleted file mode 100644 index 061b8e0342..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0062-ASoC-fsl-sai-fix-build-failture-due-to-5.1-RC7-upgra.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0e4fe4adfd9a9cd36220b79a8eecce4d24a9fd02 Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Tue, 7 May 2019 11:01:08 +0800 -Subject: [PATCH] ASoC: fsl: sai: fix build failture due to 5.1 RC7 upgrade - -Signed-off-by: Dong Aisheng ---- - sound/soc/fsl/fsl_sai.c | 10 ---------- - 1 file changed, 10 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -418,14 +418,12 @@ static int fsl_sai_set_dai_fmt_tr(struct - case SND_SOC_DAIFMT_CBS_CFS: - val_cr2 |= FSL_SAI_CR2_BCD_MSTR; - val_cr4 |= FSL_SAI_CR4_FSD_MSTR; -- sai->is_slave_mode = false; - break; - case SND_SOC_DAIFMT_CBM_CFM: - sai->slave_mode[tx] = true; - break; - case SND_SOC_DAIFMT_CBS_CFM: - val_cr2 |= FSL_SAI_CR2_BCD_MSTR; -- sai->is_slave_mode = false; - break; - case SND_SOC_DAIFMT_CBM_CFS: - val_cr4 |= FSL_SAI_CR4_FSD_MSTR; -@@ -1575,14 +1573,6 @@ static int fsl_sai_remove(struct platfor - return 0; - } - --static const struct of_device_id fsl_sai_ids[] = { -- { .compatible = "fsl,vf610-sai", }, -- { .compatible = "fsl,imx6sx-sai", }, -- { .compatible = "fsl,imx6ul-sai", }, -- { /* sentinel */ } --}; --MODULE_DEVICE_TABLE(of, fsl_sai_ids); -- - #ifdef CONFIG_PM - static int fsl_sai_runtime_suspend(struct device *dev) - { diff --git a/target/linux/layerscape/patches-5.4/801-audio-0063-MLK-21876-4-ASoC-fsl-sai-fix-build-for-next-20190524.patch b/target/linux/layerscape/patches-5.4/801-audio-0063-MLK-21876-4-ASoC-fsl-sai-fix-build-for-next-20190524.patch deleted file mode 100644 index 8ceb8bfa3b..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0063-MLK-21876-4-ASoC-fsl-sai-fix-build-for-next-20190524.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 23212c6c5fcee8c1a317b5beb73c89374751de7b Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Mon, 27 May 2019 17:00:54 +0800 -Subject: [PATCH] MLK-21876-4 ASoC: fsl: sai: fix build for next-20190524 - upgrade -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In file included from ../sound/soc/fsl/fsl_sai.c:15:0: -../sound/soc/fsl/fsl_sai.c: In function ‘fsl_sai_startup’: -../sound/soc/fsl/fsl_sai.c:957:51: error: ‘offset’ undeclared (first use in this function) - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), - ^ -../include/linux/regmap.h:77:31: note: in definition of macro ‘regmap_update_bits’ - regmap_update_bits_base(map, reg, mask, val, NULL, false, false) - ^ -../sound/soc/fsl/fsl_sai.h:84:37: note: in expansion of macro ‘FSL_SAI_TCR3’ - #define FSL_SAI_xCR3(tx, off) (tx ? FSL_SAI_TCR3(off) : FSL_SAI_RCR3(off)) - ^ -../sound/soc/fsl/fsl_sai.c:957:34: note: in expansion of macro ‘FSL_SAI_xCR3’ - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), - ^ -../sound/soc/fsl/fsl_sai.c:957:51: note: each undeclared identifier is reported only once for each function it appears in - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), - ^ -../include/linux/regmap.h:77:31: note: in definition of macro ‘regmap_update_bits’ - regmap_update_bits_base(map, reg, mask, val, NULL, false, false) - ^ -../sound/soc/fsl/fsl_sai.h:84:37: note: in expansion of macro ‘FSL_SAI_TCR3’ - #define FSL_SAI_xCR3(tx, off) (tx ? FSL_SAI_TCR3(off) : FSL_SAI_RCR3(off)) - ^ -../sound/soc/fsl/fsl_sai.c:957:34: note: in expansion of macro ‘FSL_SAI_xCR3’ - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), - -Signed-off-by: Dong Aisheng ---- - sound/soc/fsl/fsl_sai.c | 11 +---------- - 1 file changed, 1 insertion(+), 10 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -954,10 +954,6 @@ static int fsl_sai_startup(struct snd_pc - else - sai->is_stream_opened[tx] = true; - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -- FSL_SAI_CR3_TRCE_MASK, -- FSL_SAI_CR3_TRCE(sai->dataline[tx])); -- - /* EDMA engine needs periods of size multiple of tx/rx maxburst */ - if (sai->soc->constrain_period_size) - snd_pcm_hw_constraint_step(substream->runtime, 0, -@@ -977,13 +973,8 @@ static void fsl_sai_shutdown(struct snd_ - struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); -- -- if (sai->is_stream_opened[tx]) { -- regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset), -- FSL_SAI_CR3_TRCE_MASK, 0); -+ if (sai->is_stream_opened[tx]) - sai->is_stream_opened[tx] = false; -- } - } - - static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { diff --git a/target/linux/layerscape/patches-5.4/801-audio-0064-ASoC-fsl_sai-Mark-cache-dirty-at-resume.patch b/target/linux/layerscape/patches-5.4/801-audio-0064-ASoC-fsl_sai-Mark-cache-dirty-at-resume.patch deleted file mode 100644 index 9dcab4e3bc..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0064-ASoC-fsl_sai-Mark-cache-dirty-at-resume.patch +++ /dev/null @@ -1,28 +0,0 @@ -From e89355ed8ddefc68e33a754fe8be067cee54ce62 Mon Sep 17 00:00:00 2001 -From: Daniel Baluta -Date: Wed, 19 Jun 2019 19:50:31 +0300 -Subject: [PATCH] ASoC: fsl_sai: Mark cache dirty at resume - -This is needed so that at resume will restore the -correct SAI registers. - -Looks like the call to regcache_mark_dirty was missed when -porting commit 760bd6187413e37c8 ("MLK-15960-2: ASoC: fsl_sai: refine -the pm runtime function") - -Signed-off-by: Daniel Baluta ---- - sound/soc/fsl/fsl_sai.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -1617,6 +1617,8 @@ static int fsl_sai_runtime_resume(struct - PM_QOS_CPU_DMA_LATENCY, 0); - - regcache_cache_only(sai->regmap, false); -+ regcache_mark_dirty(sai->regmap); -+ - regmap_write(sai->regmap, FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR); - regmap_write(sai->regmap, FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR); - usleep_range(1000, 2000); diff --git a/target/linux/layerscape/patches-5.4/801-audio-0065-LF-106-ASoC-fsl_sai-request-BUS_FREQ_AUDIO.patch b/target/linux/layerscape/patches-5.4/801-audio-0065-LF-106-ASoC-fsl_sai-request-BUS_FREQ_AUDIO.patch deleted file mode 100644 index 76b7b607ed..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0065-LF-106-ASoC-fsl_sai-request-BUS_FREQ_AUDIO.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 702f662e21b9246348987a119e2a3ca16a31acb7 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Fri, 22 Nov 2019 15:36:31 +0800 -Subject: [PATCH] LF-106: ASoC: fsl_sai: request BUS_FREQ_AUDIO - -request BUS_FREQ_AUDIO - -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include "fsl_dsd.h" - #include "fsl_sai.h" -@@ -1571,6 +1572,8 @@ static int fsl_sai_runtime_suspend(struc - - regcache_cache_only(sai->regmap, true); - -+ release_bus_freq(BUS_FREQ_AUDIO); -+ - if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) - clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]); - -@@ -1612,6 +1615,8 @@ static int fsl_sai_runtime_resume(struct - goto disable_tx_clk; - } - -+ request_bus_freq(BUS_FREQ_AUDIO); -+ - if (sai->soc->flags & SAI_FLAG_PMQOS) - pm_qos_add_request(&sai->pm_qos_req, - PM_QOS_CPU_DMA_LATENCY, 0); diff --git a/target/linux/layerscape/patches-5.4/801-audio-0066-MLK-16224-2-ASoC-dmaengine_pcm-add-fifo_num-to-snd_d.patch b/target/linux/layerscape/patches-5.4/801-audio-0066-MLK-16224-2-ASoC-dmaengine_pcm-add-fifo_num-to-snd_d.patch deleted file mode 100644 index 6f4997f4e8..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0066-MLK-16224-2-ASoC-dmaengine_pcm-add-fifo_num-to-snd_d.patch +++ /dev/null @@ -1,28 +0,0 @@ -From fd343b5141e1128ab893f5370d2a05e4f09830b1 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Tue, 23 Jan 2018 13:27:10 +0800 -Subject: [PATCH] MLK-16224-2: ASoC: dmaengine_pcm: add fifo_num to - snd_dmaengine_dai_dma_data - -In order to support multi-fifo sdma script, the audio driver need to send -the fifo number to dma driver through dma_slave_config, and the cpu_dai -driver should config fifo_num for the audio platform driver, then platform -driver can config fifo_num to dma. -So add new variable fifo_num for struct snd_dmaengine_dai_dma_data. - -Signed-off-by: Shengjiu Wang -Reviewed-by: Robin Gong ---- - include/sound/dmaengine_pcm.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/sound/dmaengine_pcm.h -+++ b/include/sound/dmaengine_pcm.h -@@ -76,6 +76,7 @@ struct snd_dmaengine_dai_dma_data { - const char *chan_name; - unsigned int fifo_size; - unsigned int flags; -+ unsigned int fifo_num; - }; - - void snd_dmaengine_pcm_set_config_from_dai_data( diff --git a/target/linux/layerscape/patches-5.4/801-audio-0069-MLK-21484-4-ASoC-fsl_sai-ensure-clk-not-in-use-prior.patch b/target/linux/layerscape/patches-5.4/801-audio-0069-MLK-21484-4-ASoC-fsl_sai-ensure-clk-not-in-use-prior.patch deleted file mode 100644 index 87ecb07625..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0069-MLK-21484-4-ASoC-fsl_sai-ensure-clk-not-in-use-prior.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 5c4835e943dd31265770e7ca3c03307d5c725db6 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Thu, 25 Apr 2019 15:03:56 +0300 -Subject: [PATCH] MLK-21484-4: ASoC: fsl_sai: ensure clk not in use prior - set_mclk_rate - -On recent kernels clks which are marked with CLK_SET_RATE_GATE are -"protected" against further changes at clk_prepare time, including clk -set_parent and set_rate. See commit 9461f7b33d11 ("clk: fix -CLK_SET_RATE_GATE with clock rate protection"). The current fsl_sai -implementation ensures the clock is not in use prior set_parent, -extend this for set_rate also by moving if (sai->mclk_streams == 0) -outside fsl_sai_set_mclk_rate(). Aside of this avoid changing rate and -parent for BUS clk. - -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 30 +++++++++++++----------------- - 1 file changed, 13 insertions(+), 17 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -259,25 +259,19 @@ static int fsl_sai_set_mclk_rate(struct - if (pll) { - npll = (do_div(ratio, 8000) ? sai->pll11k_clk : sai->pll8k_clk); - if (!clk_is_match(pll, npll)) { -- if (sai->mclk_streams == 0) { -- ret = clk_set_parent(p, npll); -- if (ret < 0) -- dev_warn(dai->dev, -- "failed to set parent %s: %d\n", -- __clk_get_name(npll), ret); -- } else { -- dev_err(dai->dev, -- "PLL %s is in use by a running stream.\n", -- __clk_get_name(pll)); -- return -EINVAL; -- } -+ ret = clk_set_parent(p, npll); -+ if (ret < 0) -+ dev_warn(dai->dev, -+ "failed to set parent %s: %d\n", -+ __clk_get_name(npll), ret); - } - } - - ret = clk_set_rate(sai->mclk_clk[clk_id], freq); - if (ret < 0) - dev_err(dai->dev, "failed to set clock rate (%u): %d\n", -- freq, ret); -+ freq, ret); -+ - return ret; - } - -@@ -298,7 +292,7 @@ static int fsl_sai_set_dai_sysclk(struct - if (dir == SND_SOC_CLOCK_IN) - return 0; - -- if (freq > 0) { -+ if (freq > 0 && clk_id != FSL_SAI_CLK_BUS) { - if (clk_id < 0 || clk_id >= FSL_SAI_MCLK_MAX) { - dev_err(cpu_dai->dev, "Unknown clock id: %d\n", clk_id); - return -EINVAL; -@@ -309,9 +303,11 @@ static int fsl_sai_set_dai_sysclk(struct - return -EINVAL; - } - -- ret = fsl_sai_set_mclk_rate(cpu_dai, clk_id, freq); -- if (ret < 0) -- return ret; -+ if (sai->mclk_streams == 0) { -+ ret = fsl_sai_set_mclk_rate(cpu_dai, clk_id, freq); -+ if (ret < 0) -+ return ret; -+ } - } - - ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq, diff --git a/target/linux/layerscape/patches-5.4/801-audio-0070-MLK-21957-1-ASoC-fsl_sai-remove-reset-code-from-dai_.patch b/target/linux/layerscape/patches-5.4/801-audio-0070-MLK-21957-1-ASoC-fsl_sai-remove-reset-code-from-dai_.patch deleted file mode 100644 index e4c7fa00ba..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0070-MLK-21957-1-ASoC-fsl_sai-remove-reset-code-from-dai_.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 9bd468920e23649e1244c5d243215c04ff3e72e6 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Tue, 18 Jun 2019 16:16:19 +0300 -Subject: [PATCH] MLK-21957-1: ASoC: fsl_sai: remove reset code from dai_probe - -SAI software reset is done in runtime resume, -there is no need to do it in fsl_sai_dai_probe. - -Signed-off-by: Viorel Suman -Signed-off-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -991,13 +991,6 @@ static int fsl_sai_dai_probe(struct snd_ - struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); - unsigned char offset = sai->soc->reg_offset; - -- /* Software Reset for both Tx and Rx */ -- regmap_write(sai->regmap, FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR); -- regmap_write(sai->regmap, FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR); -- /* Clear SR bit to finish the reset */ -- regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0); -- regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0); -- - regmap_update_bits(sai->regmap, FSL_SAI_TCR1(offset), - sai->soc->fifo_depth - 1, - sai->soc->fifo_depth - FSL_SAI_MAXBURST_TX); diff --git a/target/linux/layerscape/patches-5.4/801-audio-0071-MLK-21957-2-ASoC-fsl_sai-read-SAI-version-and-params.patch b/target/linux/layerscape/patches-5.4/801-audio-0071-MLK-21957-2-ASoC-fsl_sai-read-SAI-version-and-params.patch deleted file mode 100644 index c400f7a5f6..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0071-MLK-21957-2-ASoC-fsl_sai-read-SAI-version-and-params.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 34a1cd97a2ef6f68a12ff2f2fd813548e867f72f Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Thu, 20 Jun 2019 13:25:15 +0300 -Subject: [PATCH] MLK-21957-2: ASoC: fsl_sai: read SAI version and params in - probe - -Read SAI IP version and parameters in probe function. - -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 30 ++++++++++++++++++++---------- - 1 file changed, 20 insertions(+), 10 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -465,11 +465,12 @@ static int fsl_sai_set_dai_fmt(struct sn - return ret; - } - --static int fsl_sai_check_ver(struct snd_soc_dai *cpu_dai) -+static int fsl_sai_check_ver(struct device *dev) - { -- struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); -+ struct fsl_sai *sai = dev_get_drvdata(dev); - unsigned char offset = sai->soc->reg_offset; - unsigned int val; -+ int ret; - - if (FSL_SAI_TCSR(offset) == FSL_SAI_VERID) - return 0; -@@ -477,16 +478,21 @@ static int fsl_sai_check_ver(struct snd_ - if (sai->verid.loaded) - return 0; - -- sai->verid.loaded = true; -- regmap_read(sai->regmap, FSL_SAI_VERID, &val); -- dev_dbg(cpu_dai->dev, "VERID: 0x%016X\n", val); -+ ret = regmap_read(sai->regmap, FSL_SAI_VERID, &val); -+ if (ret < 0) -+ return ret; -+ -+ dev_dbg(dev, "VERID: 0x%016X\n", val); - - sai->verid.id = (val & FSL_SAI_VER_ID_MASK) >> FSL_SAI_VER_ID_SHIFT; - sai->verid.extfifo_en = (val & FSL_SAI_VER_EFIFO_EN); - sai->verid.timestamp_en = (val & FSL_SAI_VER_TSTMP_EN); - -- regmap_read(sai->regmap, FSL_SAI_PARAM, &val); -- dev_dbg(cpu_dai->dev, "PARAM: 0x%016X\n", val); -+ ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val); -+ if (ret < 0) -+ return ret; -+ -+ dev_dbg(dev, "PARAM: 0x%016X\n", val); - - /* max slots per frame, power of 2 */ - sai->param.spf = 1 << -@@ -499,11 +505,13 @@ static int fsl_sai_check_ver(struct snd_ - /* number of datalines implemented */ - sai->param.dln = val & FSL_SAI_PAR_DLN_MASK; - -- dev_dbg(cpu_dai->dev, -+ dev_dbg(dev, - "Version: 0x%08X, SPF: %u, WPF: %u, DLN: %u\n", - sai->verid.id, sai->param.spf, sai->param.wpf, sai->param.dln - ); - -+ sai->verid.loaded = true; -+ - return 0; - } - -@@ -521,8 +529,6 @@ static int fsl_sai_set_bclk(struct snd_s - if (sai->slave_mode[tx]) - return 0; - -- fsl_sai_check_ver(dai); -- - for (id = 0; id < FSL_SAI_MCLK_MAX; id++) { - clk_rate = clk_get_rate(sai->mclk_clk[id]); - if (!clk_rate) -@@ -1520,6 +1526,10 @@ static int fsl_sai_probe(struct platform - - platform_set_drvdata(pdev, sai); - -+ ret = fsl_sai_check_ver(&pdev->dev); -+ if (ret < 0) -+ dev_warn(&pdev->dev, "Error reading SAI version: %d\n", ret); -+ - pm_runtime_enable(&pdev->dev); - - regcache_cache_only(sai->regmap, true); diff --git a/target/linux/layerscape/patches-5.4/801-audio-0072-MLK-22522-ASoC-fsl_sai-fix-stack-out-of-bounds-KASAN.patch b/target/linux/layerscape/patches-5.4/801-audio-0072-MLK-22522-ASoC-fsl_sai-fix-stack-out-of-bounds-KASAN.patch deleted file mode 100644 index 2fc52b8052..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0072-MLK-22522-ASoC-fsl_sai-fix-stack-out-of-bounds-KASAN.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 5d4e9c8371a2343c66123078dbde15438450b9a4 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Thu, 29 Aug 2019 13:17:33 +0300 -Subject: [PATCH] MLK-22522: ASoC: fsl_sai: fix stack-out-of-bounds KASAN - complain - -Fix the following KASAN reported issue: -================================================================== -[ 11.580278] BUG: KASAN: stack-out-of-bounds in find_next_bit+0x3c/0xc0 -[ 11.586815] Read of size 8 at addr ffffffc8c8d4f760 by task swapper/0/1 -[ 11.593440] -[ 11.594943] CPU: 4 PID: 1 Comm: swapper/0 Tainted: G W 4.19.35-05042-g. #157 -[ 11.604259] Hardware name: Freescale i.MX8QM MEK (DT) -[ 11.609323] Call trace: -[ 11.611785] dump_backtrace+0x0/0x230 -[ 11.615458] show_stack+0x14/0x20 -[ 11.618787] dump_stack+0xbc/0xf4 -[ 11.622118] print_address_description+0x60/0x270 -[ 11.626830] kasan_report+0x230/0x360 -[ 11.630505] __asan_load8+0x84/0xa8 -[ 11.634005] find_next_bit+0x3c/0xc0 -[ 11.637595] fsl_sai_calc_dl_off+0x1c/0x50 -[ 11.641703] fsl_sai_read_dlcfg+0x184/0x368 -[ 11.645898] fsl_sai_probe+0x3ec/0xb48 -[ 11.649663] platform_drv_probe+0x70/0xd8 -[ 11.653683] really_probe+0x24c/0x370 -[ 11.657358] driver_probe_device+0x70/0x138 -[ 11.661554] __driver_attach+0x124/0x128 -[ 11.665489] bus_for_each_dev+0xe8/0x158 -[ 11.669425] driver_attach+0x30/0x40 -[ 11.673012] bus_add_driver+0x290/0x308 -[ 11.676861] driver_register+0xbc/0x1d0 -[ 11.680711] __platform_driver_register+0x7c/0x88 -[ 11.685431] fsl_sai_driver_init+0x18/0x20 -[ 11.689537] do_one_initcall+0xe8/0x5a8 -[ 11.693387] kernel_init_freeable+0x6b0/0x760 -[ 11.697759] kernel_init+0x10/0x120 -[ 11.701255] ret_from_fork+0x10/0x18 -.... -================================================================== -[ 11.800186] Disabling lock debugging due to kernel taint - -Signed-off-by: Viorel Suman -Reviewed-by: Shengjiu Wang ---- - sound/soc/fsl/fsl_sai.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -1259,12 +1259,12 @@ static const struct of_device_id fsl_sai - }; - MODULE_DEVICE_TABLE(of, fsl_sai_ids); - --static unsigned int fsl_sai_calc_dl_off(unsigned int* dl_mask) -+static unsigned int fsl_sai_calc_dl_off(unsigned long dl_mask) - { - int fbidx, nbidx, offset; - -- fbidx = find_first_bit((const unsigned long *)dl_mask, 8); -- nbidx = find_next_bit((const unsigned long *)dl_mask, 8, fbidx+1); -+ fbidx = find_first_bit(&dl_mask, 8); -+ nbidx = find_next_bit(&dl_mask, 8, fbidx + 1); - offset = nbidx - fbidx - 1; - - return (offset < 0 || offset >= 7 ? 0 : offset); -@@ -1321,9 +1321,9 @@ static int fsl_sai_read_dlcfg(struct pla - - cfg[i].pins = pins; - cfg[i].mask[0] = rx; -- cfg[i].offset[0] = fsl_sai_calc_dl_off(&rx); -+ cfg[i].offset[0] = fsl_sai_calc_dl_off(rx); - cfg[i].mask[1] = tx; -- cfg[i].offset[1] = fsl_sai_calc_dl_off(&tx); -+ cfg[i].offset[1] = fsl_sai_calc_dl_off(tx); - } - - *rcfg = cfg; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0073-MLK-21957-3-ASoC-fsl_sai-add-bitcount-and-timestamp-.patch b/target/linux/layerscape/patches-5.4/801-audio-0073-MLK-21957-3-ASoC-fsl_sai-add-bitcount-and-timestamp-.patch deleted file mode 100644 index 92de8196ee..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0073-MLK-21957-3-ASoC-fsl_sai-add-bitcount-and-timestamp-.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 599235bd9d22c8cad90b0a7621b46d70cca94d31 Mon Sep 17 00:00:00 2001 -From: Viorel Suman -Date: Wed, 5 Jun 2019 13:46:32 +0000 -Subject: [PATCH] MLK-21957-3: ASoC: fsl_sai: add bitcount and timestamp - controls - -Bitcount and timestamp support added in SAI IP recently. -Add the related controls in SAI driver. - -Signed-off-by: Viorel Suman ---- - sound/soc/fsl/fsl_sai.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++- - sound/soc/fsl/fsl_sai.h | 6 +++ - 2 files changed, 102 insertions(+), 1 deletion(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -992,6 +992,90 @@ static const struct snd_soc_dai_ops fsl_ - .shutdown = fsl_sai_shutdown, - }; - -+static const char -+ *en_sl[] = { "Disabled", "Enabled", }, -+ *inc_sl[] = { "On enabled and bitcount increment", "On enabled", }; -+ -+static const struct soc_enum tstmp_enum[] = { -+SOC_ENUM_SINGLE(FSL_SAI_TTCTL, 0, ARRAY_SIZE(en_sl), en_sl), -+SOC_ENUM_SINGLE(FSL_SAI_RTCTL, 0, ARRAY_SIZE(en_sl), en_sl), -+SOC_ENUM_SINGLE(FSL_SAI_TTCTL, 1, ARRAY_SIZE(inc_sl), inc_sl), -+SOC_ENUM_SINGLE(FSL_SAI_RTCTL, 1, ARRAY_SIZE(inc_sl), inc_sl), -+}; -+ -+int fsl_sai_get_reg(struct snd_kcontrol *kcontrol, -+ struct snd_ctl_elem_value *ucontrol) -+{ -+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); -+ struct soc_mreg_control *mc = -+ (struct soc_mreg_control *)kcontrol->private_value; -+ bool pm_active = pm_runtime_active(component->dev); -+ unsigned int regval; -+ int ret; -+ -+ if (pm_active) -+ regcache_cache_bypass(component->regmap, true); -+ -+ ret = snd_soc_component_read(component, mc->regbase, ®val); -+ -+ if (pm_active) -+ regcache_cache_bypass(component->regmap, false); -+ -+ if (ret < 0) -+ return ret; -+ -+ ucontrol->value.integer.value[0] = regval; -+ -+ return 0; -+} -+ -+#define SOC_SINGLE_REG_RO(xname, xreg) \ -+{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = (xname), \ -+ .access = SNDRV_CTL_ELEM_ACCESS_READ | \ -+ SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ -+ .info = snd_soc_info_xr_sx, .get = fsl_sai_get_reg, \ -+ .private_value = (unsigned long)&(struct soc_mreg_control) \ -+ { .regbase = xreg, .regcount = 1, .nbits = 32, \ -+ .invert = 0, .min = 0, .max = 0xffffffff, } } -+ -+static const struct snd_kcontrol_new fsl_sai_pb_ctrls[] = { -+ SOC_ENUM("Playback Timestamp Control", tstmp_enum[0]), -+ SOC_ENUM("Playback Timestamp Increment", tstmp_enum[2]), -+ SOC_SINGLE("Playback Timestamp Reset", FSL_SAI_TTCTL, 8, 1, 0), -+ SOC_SINGLE("Playback Bit Counter Reset", FSL_SAI_TTCTL, 9, 1, 0), -+ SOC_SINGLE_REG_RO("Playback Timestamp Counter", FSL_SAI_TTCTN), -+ SOC_SINGLE_REG_RO("Playback Bit Counter", FSL_SAI_TBCTN), -+ SOC_SINGLE_REG_RO("Playback Latched Timestamp Counter", FSL_SAI_TTCAP), -+}; -+ -+static const struct snd_kcontrol_new fsl_sai_cp_ctrls[] = { -+ SOC_ENUM("Capture Timestamp Control", tstmp_enum[1]), -+ SOC_ENUM("Capture Timestamp Increment", tstmp_enum[3]), -+ SOC_SINGLE("Capture Timestamp Reset", FSL_SAI_RTCTL, 8, 1, 0), -+ SOC_SINGLE("Capture Bit Counter Reset", FSL_SAI_RTCTL, 9, 1, 0), -+ SOC_SINGLE_REG_RO("Capture Timestamp Counter", FSL_SAI_RTCTN), -+ SOC_SINGLE_REG_RO("Capture Bit Counter", FSL_SAI_RBCTN), -+ SOC_SINGLE_REG_RO("Capture Latched Timestamp Counter", FSL_SAI_RTCAP), -+}; -+ -+static int fsl_sai_pcm_new(struct snd_soc_pcm_runtime *rtd, -+ struct snd_soc_dai *dai) -+{ -+ struct fsl_sai *sai = dev_get_drvdata(dai->dev); -+ struct snd_pcm *pcm = rtd->pcm; -+ bool ts_enabled = sai->verid.timestamp_en; -+ struct snd_soc_component *comp = dai->component; -+ -+ if (ts_enabled && pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) -+ snd_soc_add_component_controls(comp, fsl_sai_pb_ctrls, -+ ARRAY_SIZE(fsl_sai_pb_ctrls)); -+ -+ if (ts_enabled && pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) -+ snd_soc_add_component_controls(comp, fsl_sai_cp_ctrls, -+ ARRAY_SIZE(fsl_sai_cp_ctrls)); -+ return 0; -+} -+ - static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) - { - struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); -@@ -1030,6 +1114,7 @@ static int fsl_sai_dai_resume(struct snd - } - - static struct snd_soc_dai_driver fsl_sai_dai_template = { -+ .pcm_new = fsl_sai_pcm_new, - .probe = fsl_sai_dai_probe, - .playback = { - .stream_name = "CPU-Playback", -@@ -1054,7 +1139,7 @@ static struct snd_soc_dai_driver fsl_sai - }; - - static const struct snd_soc_component_driver fsl_component = { -- .name = "fsl-sai", -+ .name = "fsl-sai", - }; - - static struct reg_default fsl_sai_v2_reg_defaults[] = { -@@ -1141,6 +1226,14 @@ static bool fsl_sai_readable_reg(struct - case FSL_SAI_MDIV: - case FSL_SAI_VERID: - case FSL_SAI_PARAM: -+ case FSL_SAI_TTCTN: -+ case FSL_SAI_RTCTN: -+ case FSL_SAI_TTCTL: -+ case FSL_SAI_TBCTN: -+ case FSL_SAI_TTCAP: -+ case FSL_SAI_RTCTL: -+ case FSL_SAI_RBCTN: -+ case FSL_SAI_RTCAP: - return true; - default: - return false; -@@ -1214,6 +1307,8 @@ static bool fsl_sai_writeable_reg(struct - case FSL_SAI_RMR: - case FSL_SAI_MCTL: - case FSL_SAI_MDIV: -+ case FSL_SAI_TTCTL: -+ case FSL_SAI_RTCTL: - return true; - default: - return false; ---- a/sound/soc/fsl/fsl_sai.h -+++ b/sound/soc/fsl/fsl_sai.h -@@ -210,6 +210,12 @@ - - #define SAI_FLAG_PMQOS BIT(0) - -+/* SAI timestamp and bitcounter */ -+#define FSL_SAI_xTCTL_TSEN BIT(0) -+#define FSL_SAI_xTCTL_TSINC BIT(1) -+#define FSL_SAI_xTCTL_RTSC BIT(8) -+#define FSL_SAI_xTCTL_RBC BIT(9) -+ - struct fsl_sai_soc_data { - unsigned int fifo_depth; - unsigned int fifos; diff --git a/target/linux/layerscape/patches-5.4/801-audio-0074-ASoC-fsl_sai-fix-build-issue-of-incomplete-parenthes.patch b/target/linux/layerscape/patches-5.4/801-audio-0074-ASoC-fsl_sai-fix-build-issue-of-incomplete-parenthes.patch deleted file mode 100644 index e9083294dd..0000000000 --- a/target/linux/layerscape/patches-5.4/801-audio-0074-ASoC-fsl_sai-fix-build-issue-of-incomplete-parenthes.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0524e0b15966f8cbb010d430ec3fdcf9faf876f4 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Wed, 1 Apr 2020 15:49:50 +0800 -Subject: [PATCH] ASoC: fsl_sai: fix build issue of incomplete parentheses - -Fix build issue of incomplete parentheses. - -Fixes: c516c26 (MLK-13574-2: ASoC: fsl_sai: refine driver for ip upgrade) -Signed-off-by: Yangbo Lu ---- - sound/soc/fsl/fsl_sai.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sound/soc/fsl/fsl_sai.c -+++ b/sound/soc/fsl/fsl_sai.c -@@ -1634,7 +1634,7 @@ static int fsl_sai_probe(struct platform - if (ret) - goto err_pm_disable; - -- if (sai->soc->imx) -+ if (sai->soc->imx) { - ret = imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE); - if (ret) - goto err_pm_disable; diff --git a/target/linux/layerscape/patches-5.4/802-can-0001-imx-busfreq-Add-API-header-file.patch b/target/linux/layerscape/patches-5.4/802-can-0001-imx-busfreq-Add-API-header-file.patch deleted file mode 100644 index e7a31c551e..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0001-imx-busfreq-Add-API-header-file.patch +++ /dev/null @@ -1,95 +0,0 @@ -From c8055614385c90accdea4e7a046c5560bccc84cf Mon Sep 17 00:00:00 2001 -From: Leonard Crestez -Date: Mon, 13 May 2019 15:06:37 +0300 -Subject: [PATCH] imx busfreq: Add API header file - -Add sufficient enough definitions so that drivers which call -request_bus_freq and release_bus_freq can compile even if -CONFIG_HAVE_IMX_BUSFREQ is missing. - -Signed-off-by: Leonard Crestez ---- - include/linux/busfreq-imx.h | 77 +++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 77 insertions(+) - create mode 100644 include/linux/busfreq-imx.h - ---- /dev/null -+++ b/include/linux/busfreq-imx.h -@@ -0,0 +1,77 @@ -+/* -+ * Copyright 2012-2016 Freescale Semiconductor, Inc. All Rights Reserved. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#ifndef __ASM_ARCH_MXC_BUSFREQ_H__ -+#define __ASM_ARCH_MXC_BUSFREQ_H__ -+ -+#include -+#include -+ -+/* -+ * This enumerates busfreq low power mode entry and exit. -+ */ -+enum busfreq_event { -+ LOW_BUSFREQ_ENTER, -+ LOW_BUSFREQ_EXIT, -+}; -+ -+/* -+ * This enumerates the system bus and ddr frequencies in various modes. -+ * BUS_FREQ_HIGH - DDR @ 528MHz, AHB @ 132MHz. -+ * BUS_FREQ_MED - DDR @ 400MHz, AHB @ 132MHz -+ * BUS_FREQ_AUDIO - DDR @ 50MHz/100MHz, AHB @ 24MHz. -+ * BUS_FREQ_LOW - DDR @ 24MHz, AHB @ 24MHz. -+ * BUS_FREQ_ULTRA_LOW - DDR @ 1MHz, AHB - 3MHz. -+ * -+ * Drivers need to request/release the bus/ddr frequencies based on -+ * their performance requirements. Drivers cannot request/release -+ * BUS_FREQ_ULTRA_LOW mode as this mode is automatically entered from -+ * either BUS_FREQ_AUDIO or BUS_FREQ_LOW -+ * modes. -+ */ -+enum bus_freq_mode { -+ BUS_FREQ_HIGH, -+ BUS_FREQ_MED, -+ BUS_FREQ_AUDIO, -+ BUS_FREQ_LOW, -+ BUS_FREQ_ULTRA_LOW, -+}; -+ -+#if defined(CONFIG_HAVE_IMX_BUSFREQ) && !defined(CONFIG_ARM64) -+extern struct regulator *arm_reg; -+extern struct regulator *soc_reg; -+void request_bus_freq(enum bus_freq_mode mode); -+void release_bus_freq(enum bus_freq_mode mode); -+int register_busfreq_notifier(struct notifier_block *nb); -+int unregister_busfreq_notifier(struct notifier_block *nb); -+int get_bus_freq_mode(void); -+#elif defined(CONFIG_HAVE_IMX_BUSFREQ) -+void request_bus_freq(enum bus_freq_mode mode); -+void release_bus_freq(enum bus_freq_mode mode); -+int get_bus_freq_mode(void); -+#else -+static inline void request_bus_freq(enum bus_freq_mode mode) -+{ -+} -+static inline void release_bus_freq(enum bus_freq_mode mode) -+{ -+} -+static inline int register_busfreq_notifier(struct notifier_block *nb) -+{ -+ return 0; -+} -+static inline int unregister_busfreq_notifier(struct notifier_block *nb) -+{ -+ return 0; -+} -+static inline int get_bus_freq_mode(void) -+{ -+ return BUS_FREQ_HIGH; -+} -+#endif -+#endif diff --git a/target/linux/layerscape/patches-5.4/802-can-0002-can-rx-offload-fix-long-lines.patch b/target/linux/layerscape/patches-5.4/802-can-0002-can-rx-offload-fix-long-lines.patch deleted file mode 100644 index 6f30ee2fea..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0002-can-rx-offload-fix-long-lines.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 47058e3bd5c13b9db796a81083c049cb1d0b7883 Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Mon, 7 Oct 2019 09:59:49 +0200 -Subject: [PATCH] can: rx-offload: fix long lines - -This patch fixes the checkpatch warnings about too long lines. - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/dev/rx-offload.c | 39 ++++++++++++++++++++++++++------------- - 1 file changed, 26 insertions(+), 13 deletions(-) - ---- a/drivers/net/can/dev/rx-offload.c -+++ b/drivers/net/can/dev/rx-offload.c -@@ -1,7 +1,8 @@ - // SPDX-License-Identifier: GPL-2.0-only --/* -- * Copyright (c) 2014 David Jander, Protonic Holland -- * Copyright (C) 2014-2017 Pengutronix, Marc Kleine-Budde -+/* Copyright (c) 2014 Protonic Holland, -+ * David Jander -+ * Copyright (C) 2014-2017 Pengutronix, -+ * Marc Kleine-Budde - */ - - #include -@@ -11,14 +12,17 @@ struct can_rx_offload_cb { - u32 timestamp; - }; - --static inline struct can_rx_offload_cb *can_rx_offload_get_cb(struct sk_buff *skb) -+static inline struct can_rx_offload_cb * -+can_rx_offload_get_cb(struct sk_buff *skb) - { - BUILD_BUG_ON(sizeof(struct can_rx_offload_cb) > sizeof(skb->cb)); - - return (struct can_rx_offload_cb *)skb->cb; - } - --static inline bool can_rx_offload_le(struct can_rx_offload *offload, unsigned int a, unsigned int b) -+static inline bool -+can_rx_offload_le(struct can_rx_offload *offload, -+ unsigned int a, unsigned int b) - { - if (offload->inc) - return a <= b; -@@ -26,7 +30,8 @@ static inline bool can_rx_offload_le(str - return a >= b; - } - --static inline unsigned int can_rx_offload_inc(struct can_rx_offload *offload, unsigned int *val) -+static inline unsigned int -+can_rx_offload_inc(struct can_rx_offload *offload, unsigned int *val) - { - if (offload->inc) - return (*val)++; -@@ -36,7 +41,9 @@ static inline unsigned int can_rx_offloa - - static int can_rx_offload_napi_poll(struct napi_struct *napi, int quota) - { -- struct can_rx_offload *offload = container_of(napi, struct can_rx_offload, napi); -+ struct can_rx_offload *offload = container_of(napi, -+ struct can_rx_offload, -+ napi); - struct net_device *dev = offload->dev; - struct net_device_stats *stats = &dev->stats; - struct sk_buff *skb; -@@ -65,8 +72,9 @@ static int can_rx_offload_napi_poll(stru - return work_done; - } - --static inline void __skb_queue_add_sort(struct sk_buff_head *head, struct sk_buff *new, -- int (*compare)(struct sk_buff *a, struct sk_buff *b)) -+static inline void -+__skb_queue_add_sort(struct sk_buff_head *head, struct sk_buff *new, -+ int (*compare)(struct sk_buff *a, struct sk_buff *b)) - { - struct sk_buff *pos, *insert = NULL; - -@@ -199,7 +207,8 @@ can_rx_offload_offload_one(struct can_rx - return skb; - } - --int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, u64 pending) -+int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, -+ u64 pending) - { - struct sk_buff_head skb_queue; - unsigned int i; -@@ -328,7 +337,9 @@ int can_rx_offload_queue_tail(struct can - } - EXPORT_SYMBOL_GPL(can_rx_offload_queue_tail); - --static int can_rx_offload_init_queue(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight) -+static int can_rx_offload_init_queue(struct net_device *dev, -+ struct can_rx_offload *offload, -+ unsigned int weight) - { - offload->dev = dev; - -@@ -346,7 +357,8 @@ static int can_rx_offload_init_queue(str - return 0; - } - --int can_rx_offload_add_timestamp(struct net_device *dev, struct can_rx_offload *offload) -+int can_rx_offload_add_timestamp(struct net_device *dev, -+ struct can_rx_offload *offload) - { - unsigned int weight; - -@@ -366,7 +378,8 @@ int can_rx_offload_add_timestamp(struct - } - EXPORT_SYMBOL_GPL(can_rx_offload_add_timestamp); - --int can_rx_offload_add_fifo(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight) -+int can_rx_offload_add_fifo(struct net_device *dev, -+ struct can_rx_offload *offload, unsigned int weight) - { - if (!offload->mailbox_read) - return -EINVAL; diff --git a/target/linux/layerscape/patches-5.4/802-can-0003-can-rx-offload-can_rx_offload_compare-fix-typo.patch b/target/linux/layerscape/patches-5.4/802-can-0003-can-rx-offload-can_rx_offload_compare-fix-typo.patch deleted file mode 100644 index 5861dbe0d3..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0003-can-rx-offload-can_rx_offload_compare-fix-typo.patch +++ /dev/null @@ -1,23 +0,0 @@ -From e1a24fd01ca938096aebe397a547aa2409368ab5 Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Mon, 7 Oct 2019 10:00:25 +0200 -Subject: [PATCH] can: rx-offload: can_rx_offload_compare(): fix typo - -This patch fixes a typo found by checkpatch. - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/dev/rx-offload.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/can/dev/rx-offload.c -+++ b/drivers/net/can/dev/rx-offload.c -@@ -109,7 +109,7 @@ static int can_rx_offload_compare(struct - cb_a = can_rx_offload_get_cb(a); - cb_b = can_rx_offload_get_cb(b); - -- /* Substract two u32 and return result as int, to keep -+ /* Subtract two u32 and return result as int, to keep - * difference steady around the u32 overflow. - */ - return cb_b->timestamp - cb_a->timestamp; diff --git a/target/linux/layerscape/patches-5.4/802-can-0004-can-rx-offload-can_rx_offload_irq_offload_timestamp-.patch b/target/linux/layerscape/patches-5.4/802-can-0004-can-rx-offload-can_rx_offload_irq_offload_timestamp-.patch deleted file mode 100644 index 4501020414..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0004-can-rx-offload-can_rx_offload_irq_offload_timestamp-.patch +++ /dev/null @@ -1,26 +0,0 @@ -From b95cae85e913fb13f4c8f1241be85725e4dffeed Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Mon, 7 Oct 2019 10:00:52 +0200 -Subject: [PATCH] can: rx-offload: can_rx_offload_irq_offload_timestamp(): - don't use assignment in if condition - -This patch moves the assignment of queue_len out of the if condition. - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/dev/rx-offload.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/can/dev/rx-offload.c -+++ b/drivers/net/can/dev/rx-offload.c -@@ -238,8 +238,8 @@ int can_rx_offload_irq_offload_timestamp - skb_queue_splice_tail(&skb_queue, &offload->skb_queue); - spin_unlock_irqrestore(&offload->skb_queue.lock, flags); - -- if ((queue_len = skb_queue_len(&offload->skb_queue)) > -- (offload->skb_queue_len_max / 8)) -+ queue_len = skb_queue_len(&offload->skb_queue); -+ if (queue_len > offload->skb_queue_len_max / 8) - netdev_dbg(offload->dev, "%s: queue_len=%d\n", - __func__, queue_len); - diff --git a/target/linux/layerscape/patches-5.4/802-can-0005-can-rx-offload-can_rx_offload_reset-remove-no-op-fun.patch b/target/linux/layerscape/patches-5.4/802-can-0005-can-rx-offload-can_rx_offload_reset-remove-no-op-fun.patch deleted file mode 100644 index 68e5c4c604..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0005-can-rx-offload-can_rx_offload_reset-remove-no-op-fun.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 88b21e30646ba263df647469c3af8c09e43a99d6 Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Mon, 7 Oct 2019 13:36:58 +0200 -Subject: [PATCH] can: rx-offload: can_rx_offload_reset(): remove no-op - function - -This patch removes the function can_rx_offload_reset(), as it does -nothing. If we ever need this function, add it back again. - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/dev/rx-offload.c | 7 ------- - include/linux/can/rx-offload.h | 1 - - 2 files changed, 8 deletions(-) - ---- a/drivers/net/can/dev/rx-offload.c -+++ b/drivers/net/can/dev/rx-offload.c -@@ -348,7 +348,6 @@ static int can_rx_offload_init_queue(str - offload->skb_queue_len_max *= 4; - skb_queue_head_init(&offload->skb_queue); - -- can_rx_offload_reset(offload); - netif_napi_add(dev, &offload->napi, can_rx_offload_napi_poll, weight); - - dev_dbg(dev->dev.parent, "%s: skb_queue_len_max=%d\n", -@@ -390,7 +389,6 @@ EXPORT_SYMBOL_GPL(can_rx_offload_add_fif - - void can_rx_offload_enable(struct can_rx_offload *offload) - { -- can_rx_offload_reset(offload); - napi_enable(&offload->napi); - } - EXPORT_SYMBOL_GPL(can_rx_offload_enable); -@@ -401,8 +399,3 @@ void can_rx_offload_del(struct can_rx_of - skb_queue_purge(&offload->skb_queue); - } - EXPORT_SYMBOL_GPL(can_rx_offload_del); -- --void can_rx_offload_reset(struct can_rx_offload *offload) --{ --} --EXPORT_SYMBOL_GPL(can_rx_offload_reset); ---- a/include/linux/can/rx-offload.h -+++ b/include/linux/can/rx-offload.h -@@ -44,7 +44,6 @@ unsigned int can_rx_offload_get_echo_skb - unsigned int idx, u32 timestamp); - int can_rx_offload_queue_tail(struct can_rx_offload *offload, - struct sk_buff *skb); --void can_rx_offload_reset(struct can_rx_offload *offload); - void can_rx_offload_del(struct can_rx_offload *offload); - void can_rx_offload_enable(struct can_rx_offload *offload); - diff --git a/target/linux/layerscape/patches-5.4/802-can-0006-can-rx-offload-Prepare-for-CAN-FD-support.patch b/target/linux/layerscape/patches-5.4/802-can-0006-can-rx-offload-Prepare-for-CAN-FD-support.patch deleted file mode 100644 index d5c88ac0c8..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0006-can-rx-offload-Prepare-for-CAN-FD-support.patch +++ /dev/null @@ -1,206 +0,0 @@ -From 42abc4a8a97a87734c759c02c5ba255ed5124a2c Mon Sep 17 00:00:00 2001 -From: Joakim Zhang -Date: Fri, 12 Jul 2019 08:02:38 +0000 -Subject: [PATCH] can: rx-offload: Prepare for CAN FD support - -The skbs for classic CAN and CAN FD frames are allocated with separate -functions: alloc_can_skb() and alloc_canfd_skb(). - -In order to support CAN FD frames via the rx-offload helper, the driver -itself has to allocate the skb (depending whether it received a classic -CAN or CAN FD frame), as the rx-offload helper cannot know which kind of -CAN frame the driver has received. - -This patch moves the allocation of the skb into the struct -can_rx_offload::mailbox_read callbacks of the the flexcan and ti_hecc -driver and adjusts the rx-offload helper accordingly. - -Signed-off-by: Joakim Zhang -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 27 +++++++++++----- - drivers/net/can/dev/rx-offload.c | 70 ++++++++++-------------------------------- - include/linux/can/rx-offload.h | 6 ++-- - 3 files changed, 40 insertions(+), 63 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -791,16 +791,23 @@ static inline struct flexcan_priv *rx_of - return container_of(offload, struct flexcan_priv, offload); - } - --static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload, -- struct can_frame *cf, -- u32 *timestamp, unsigned int n) -+static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload, -+ unsigned int n, u32 *timestamp, -+ bool drop) - { - struct flexcan_priv *priv = rx_offload_to_priv(offload); - struct flexcan_regs __iomem *regs = priv->regs; - struct flexcan_mb __iomem *mb; -+ struct sk_buff *skb; -+ struct can_frame *cf; - u32 reg_ctrl, reg_id, reg_iflag1; - int i; - -+ if (unlikely(drop)) { -+ skb = ERR_PTR(-ENOBUFS); -+ goto mark_as_read; -+ } -+ - mb = flexcan_get_mb(priv, n); - - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { -@@ -814,7 +821,7 @@ static unsigned int flexcan_mailbox_read - code = reg_ctrl & FLEXCAN_MB_CODE_MASK; - if ((code != FLEXCAN_MB_CODE_RX_FULL) && - (code != FLEXCAN_MB_CODE_RX_OVERRUN)) -- return 0; -+ return NULL; - - if (code == FLEXCAN_MB_CODE_RX_OVERRUN) { - /* This MB was overrun, we lost data */ -@@ -824,11 +831,17 @@ static unsigned int flexcan_mailbox_read - } else { - reg_iflag1 = priv->read(®s->iflag1); - if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE)) -- return 0; -+ return NULL; - - reg_ctrl = priv->read(&mb->can_ctrl); - } - -+ skb = alloc_can_skb(offload->dev, &cf); -+ if (!skb) { -+ skb = ERR_PTR(-ENOMEM); -+ goto mark_as_read; -+ } -+ - /* increase timstamp to full 32 bit */ - *timestamp = reg_ctrl << 16; - -@@ -847,7 +860,7 @@ static unsigned int flexcan_mailbox_read - *(__be32 *)(cf->data + i) = data; - } - -- /* mark as read */ -+ mark_as_read: - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { - /* Clear IRQ */ - if (n < 32) -@@ -864,7 +877,7 @@ static unsigned int flexcan_mailbox_read - */ - priv->read(®s->timer); - -- return 1; -+ return skb; - } - - ---- a/drivers/net/can/dev/rx-offload.c -+++ b/drivers/net/can/dev/rx-offload.c -@@ -139,71 +139,35 @@ static int can_rx_offload_compare(struct - static struct sk_buff * - can_rx_offload_offload_one(struct can_rx_offload *offload, unsigned int n) - { -- struct sk_buff *skb = NULL, *skb_error = NULL; -+ struct sk_buff *skb; - struct can_rx_offload_cb *cb; -- struct can_frame *cf; -- int ret; -+ bool drop = false; -+ u32 timestamp; - -- if (likely(skb_queue_len(&offload->skb_queue) < -- offload->skb_queue_len_max)) { -- skb = alloc_can_skb(offload->dev, &cf); -- if (unlikely(!skb)) -- skb_error = ERR_PTR(-ENOMEM); /* skb alloc failed */ -- } else { -- skb_error = ERR_PTR(-ENOBUFS); /* skb_queue is full */ -- } -- -- /* If queue is full or skb not available, drop by reading into -- * overflow buffer. -- */ -- if (unlikely(skb_error)) { -- struct can_frame cf_overflow; -- u32 timestamp; -- -- ret = offload->mailbox_read(offload, &cf_overflow, -- ×tamp, n); -- -- /* Mailbox was empty. */ -- if (unlikely(!ret)) -- return NULL; -- -- /* Mailbox has been read and we're dropping it or -- * there was a problem reading the mailbox. -- * -- * Increment error counters in any case. -- */ -- offload->dev->stats.rx_dropped++; -- offload->dev->stats.rx_fifo_errors++; -- -- /* There was a problem reading the mailbox, propagate -- * error value. -- */ -- if (unlikely(ret < 0)) -- return ERR_PTR(ret); -- -- return skb_error; -- } -- -- cb = can_rx_offload_get_cb(skb); -- ret = offload->mailbox_read(offload, cf, &cb->timestamp, n); -+ /* If queue is full drop frame */ -+ if (unlikely(skb_queue_len(&offload->skb_queue) > -+ offload->skb_queue_len_max)) -+ drop = true; - -+ skb = offload->mailbox_read(offload, n, ×tamp, drop); - /* Mailbox was empty. */ -- if (unlikely(!ret)) { -- kfree_skb(skb); -+ if (unlikely(!skb)) - return NULL; -- } -- -- /* There was a problem reading the mailbox, propagate error value. */ -- if (unlikely(ret < 0)) { -- kfree_skb(skb); - -+ /* There was a problem reading the mailbox, propagate -+ * error value. -+ */ -+ if (unlikely(IS_ERR(skb))) { - offload->dev->stats.rx_dropped++; - offload->dev->stats.rx_fifo_errors++; - -- return ERR_PTR(ret); -+ return skb; - } - - /* Mailbox was read. */ -+ cb = can_rx_offload_get_cb(skb); -+ cb->timestamp = timestamp; -+ - return skb; - } - ---- a/include/linux/can/rx-offload.h -+++ b/include/linux/can/rx-offload.h -@@ -15,9 +15,9 @@ - struct can_rx_offload { - struct net_device *dev; - -- unsigned int (*mailbox_read)(struct can_rx_offload *offload, -- struct can_frame *cf, -- u32 *timestamp, unsigned int mb); -+ struct sk_buff *(*mailbox_read)(struct can_rx_offload *offload, -+ unsigned int mb, u32 *timestamp, -+ bool drop); - - struct sk_buff_head skb_queue; - u32 skb_queue_len_max; diff --git a/target/linux/layerscape/patches-5.4/802-can-0007-can-flexcan-use-devm_platform_ioremap_resource-to-si.patch b/target/linux/layerscape/patches-5.4/802-can-0007-can-flexcan-use-devm_platform_ioremap_resource-to-si.patch deleted file mode 100644 index 35c35f67a2..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0007-can-flexcan-use-devm_platform_ioremap_resource-to-si.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 9198f241a7205bd85b89bda08fce5c2446a12e23 Mon Sep 17 00:00:00 2001 -From: Joakim Zhang -Date: Sun, 29 Sep 2019 08:32:09 +0000 -Subject: [PATCH] can: flexcan: use devm_platform_ioremap_resource() to - simplify code - -Use the new helper devm_platform_ioremap_resource() which wraps the -platform_get_resource() and devm_ioremap_resource() together to simplify -the code. - -Signed-off-by: Joakim Zhang -Reviewed-by: Sean Nyekjaer -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -1585,7 +1585,6 @@ static int flexcan_probe(struct platform - struct net_device *dev; - struct flexcan_priv *priv; - struct regulator *reg_xceiver; -- struct resource *mem; - struct clk *clk_ipg = NULL, *clk_per = NULL; - struct flexcan_regs __iomem *regs; - int err, irq; -@@ -1620,12 +1619,11 @@ static int flexcan_probe(struct platform - clock_freq = clk_get_rate(clk_per); - } - -- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (irq <= 0) - return -ENODEV; - -- regs = devm_ioremap_resource(&pdev->dev, mem); -+ regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(regs)) - return PTR_ERR(regs); - diff --git a/target/linux/layerscape/patches-5.4/802-can-0008-can-flexcan-flexcan_irq_state-only-read-timestamp-if.patch b/target/linux/layerscape/patches-5.4/802-can-0008-can-flexcan-flexcan_irq_state-only-read-timestamp-if.patch deleted file mode 100644 index 2f839fcfc0..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0008-can-flexcan-flexcan_irq_state-only-read-timestamp-if.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 1a92e5a9109963e2491eec111b84b35b4e2adc8f Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Wed, 9 Oct 2019 15:15:37 +0200 -Subject: [PATCH] can: flexcan: flexcan_irq_state(): only read timestamp if - needed - -The function flexcan_irq_state() checks the controller for CAN state -changes and pushes a skb with the new state and a timestamp into the -rx-offload framework. - -This patch optimizes the function by only reading the timestamp, if a -state change is detected. - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -751,8 +751,6 @@ static void flexcan_irq_state(struct net - u32 timestamp; - int err; - -- timestamp = priv->read(®s->timer) << 16; -- - flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; - if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { - tx_state = unlikely(reg_esr & FLEXCAN_ESR_TX_WRN) ? -@@ -772,6 +770,8 @@ static void flexcan_irq_state(struct net - if (likely(new_state == priv->can.state)) - return; - -+ timestamp = priv->read(®s->timer) << 16; -+ - skb = alloc_can_err_skb(dev, &cf); - if (unlikely(!skb)) - return; diff --git a/target/linux/layerscape/patches-5.4/802-can-0009-can-flexcan-rename-macro-FLEXCAN_IFLAG_MB-FLEXCAN_IF.patch b/target/linux/layerscape/patches-5.4/802-can-0009-can-flexcan-rename-macro-FLEXCAN_IFLAG_MB-FLEXCAN_IF.patch deleted file mode 100644 index 535fccaff6..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0009-can-flexcan-rename-macro-FLEXCAN_IFLAG_MB-FLEXCAN_IF.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 86608c5578b7a276e0edcedc976c604e283fd177 Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Fri, 1 Mar 2019 11:12:13 +0100 -Subject: [PATCH] can: flexcan: rename macro FLEXCAN_IFLAG_MB() -> - FLEXCAN_IFLAG2_MB() - -The macro FLEXCAN_IFLAG_MB() is always used for the iflag2 register, so -rename it to FLEXCAN_IFLAG2_MB() - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -142,7 +142,7 @@ - #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 - #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 - #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1) --#define FLEXCAN_IFLAG_MB(x) BIT((x) & 0x1f) -+#define FLEXCAN_IFLAG2_MB(x) BIT((x) & 0x1f) - #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) - #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) - #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) -@@ -887,7 +887,7 @@ static inline u64 flexcan_read_reg_iflag - u32 iflag1, iflag2; - - iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default & -- ~FLEXCAN_IFLAG_MB(priv->tx_mb_idx); -+ ~FLEXCAN_IFLAG2_MB(priv->tx_mb_idx); - iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default; - - return (u64)iflag2 << 32 | iflag1; -@@ -937,7 +937,7 @@ static irqreturn_t flexcan_irq(int irq, - reg_iflag2 = priv->read(®s->iflag2); - - /* transmission complete interrupt */ -- if (reg_iflag2 & FLEXCAN_IFLAG_MB(priv->tx_mb_idx)) { -+ if (reg_iflag2 & FLEXCAN_IFLAG2_MB(priv->tx_mb_idx)) { - u32 reg_ctrl = priv->read(&priv->tx_mb->can_ctrl); - - handled = IRQ_HANDLED; -@@ -949,7 +949,7 @@ static irqreturn_t flexcan_irq(int irq, - /* after sending a RTR frame MB is in RX mode */ - priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, - &priv->tx_mb->can_ctrl); -- priv->write(FLEXCAN_IFLAG_MB(priv->tx_mb_idx), ®s->iflag2); -+ priv->write(FLEXCAN_IFLAG2_MB(priv->tx_mb_idx), ®s->iflag2); - netif_wake_queue(dev); - } - -@@ -1329,7 +1329,7 @@ static int flexcan_open(struct net_devic - priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx); - - priv->reg_imask1_default = 0; -- priv->reg_imask2_default = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); -+ priv->reg_imask2_default = FLEXCAN_IFLAG2_MB(priv->tx_mb_idx); - - priv->offload.mailbox_read = flexcan_mailbox_read; - diff --git a/target/linux/layerscape/patches-5.4/802-can-0010-can-flexcan-flexcan_irq-rename-variable-reg_iflag-re.patch b/target/linux/layerscape/patches-5.4/802-can-0010-can-flexcan-flexcan_irq-rename-variable-reg_iflag-re.patch deleted file mode 100644 index d893dd6cd1..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0010-can-flexcan-flexcan_irq-rename-variable-reg_iflag-re.patch +++ /dev/null @@ -1,35 +0,0 @@ -From f7f3c7abdef9fb6c9668a3945ec791fb206b4ee8 Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Fri, 1 Mar 2019 16:29:47 +0100 -Subject: [PATCH] can: flexcan: flexcan_irq(): rename variable reg_iflag -> - reg_iflag_rx - -This patch renames the variable reg_iflag in the flexcan_irq() function -to reg_iflag_rx. This better reflects the contents of the varibale. It -does not hold the unmodified iflag registers, instead all non RX -interrupts have been masked. - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -905,13 +905,13 @@ static irqreturn_t flexcan_irq(int irq, - - /* reception interrupt */ - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { -- u64 reg_iflag; -+ u64 reg_iflag_rx; - int ret; - -- while ((reg_iflag = flexcan_read_reg_iflag_rx(priv))) { -+ while ((reg_iflag_rx = flexcan_read_reg_iflag_rx(priv))) { - handled = IRQ_HANDLED; - ret = can_rx_offload_irq_offload_timestamp(&priv->offload, -- reg_iflag); -+ reg_iflag_rx); - if (!ret) - break; - } diff --git a/target/linux/layerscape/patches-5.4/802-can-0011-can-flexcan-rename-struct-flexcan_priv-reg_imask-1-2.patch b/target/linux/layerscape/patches-5.4/802-can-0011-can-flexcan-rename-struct-flexcan_priv-reg_imask-1-2.patch deleted file mode 100644 index ce0102182f..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0011-can-flexcan-rename-struct-flexcan_priv-reg_imask-1-2.patch +++ /dev/null @@ -1,101 +0,0 @@ -From a1126887f068def0bc11f5260e55e25b9c03e3ea Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Fri, 1 Mar 2019 09:18:54 +0100 -Subject: [PATCH] can: flexcan: rename struct - flexcan_priv::reg_imask{1,2}_default to rx_mask{1,2} - -The flexcan IP core has up to 64 mailboxes, each one has a corresponding -interrupt bit in the iflag1 or iflag2 registers and a mask bit in the -imask1 or imask2 registers. - -In the timestamp (i.e. non FIFO) mode the driver needs to mask out all -non RX interrupt sources and uses the precomputed values -reg_imask1_default and reg_imask2_default of struct flexcan_priv for -this. - -However in the current driver the reg_imask{1,2}_default cannot be used -directly to get the pending RX interrupts. The TX interrupt is part of -these variables, so it needs to be masked out, too. - -This is a preparation patch to clean up calculation of the pending RX -interrupts, it only renames the variables from - - reg_imask{1,2}_default - -to - - rx_mask{1,2} - -To better reflect their meaning after the complete conversion. This -change is done with the following sed command: - - sed -i -e "s/reg_imask\(1\|2\)_default/rx_mask\1/" drivers/net/can/flexcan.c - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 22 +++++++++++----------- - 1 file changed, 11 insertions(+), 11 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -278,8 +278,8 @@ struct flexcan_priv { - u8 clk_src; /* clock source of CAN Protocol Engine */ - - u32 reg_ctrl_default; -- u32 reg_imask1_default; -- u32 reg_imask2_default; -+ u32 rx_mask1; -+ u32 rx_mask2; - - struct clk *clk_ipg; - struct clk *clk_per; -@@ -886,9 +886,9 @@ static inline u64 flexcan_read_reg_iflag - struct flexcan_regs __iomem *regs = priv->regs; - u32 iflag1, iflag2; - -- iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default & -+ iflag2 = priv->read(®s->iflag2) & priv->rx_mask2 & - ~FLEXCAN_IFLAG2_MB(priv->tx_mb_idx); -- iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default; -+ iflag1 = priv->read(®s->iflag1) & priv->rx_mask1; - - return (u64)iflag2 << 32 | iflag1; - } -@@ -1233,8 +1233,8 @@ static int flexcan_chip_start(struct net - /* enable interrupts atomically */ - disable_irq(dev->irq); - priv->write(priv->reg_ctrl_default, ®s->ctrl); -- priv->write(priv->reg_imask1_default, ®s->imask1); -- priv->write(priv->reg_imask2_default, ®s->imask2); -+ priv->write(priv->rx_mask1, ®s->imask1); -+ priv->write(priv->rx_mask2, ®s->imask2); - enable_irq(dev->irq); - - /* print chip status */ -@@ -1328,8 +1328,8 @@ static int flexcan_open(struct net_devic - priv->tx_mb_idx = priv->mb_count - 1; - priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx); - -- priv->reg_imask1_default = 0; -- priv->reg_imask2_default = FLEXCAN_IFLAG2_MB(priv->tx_mb_idx); -+ priv->rx_mask1 = 0; -+ priv->rx_mask2 = FLEXCAN_IFLAG2_MB(priv->tx_mb_idx); - - priv->offload.mailbox_read = flexcan_mailbox_read; - -@@ -1341,12 +1341,12 @@ static int flexcan_open(struct net_devic - - imask = GENMASK_ULL(priv->offload.mb_last, - priv->offload.mb_first); -- priv->reg_imask1_default |= imask; -- priv->reg_imask2_default |= imask >> 32; -+ priv->rx_mask1 |= imask; -+ priv->rx_mask2 |= imask >> 32; - - err = can_rx_offload_add_timestamp(dev, &priv->offload); - } else { -- priv->reg_imask1_default |= FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | -+ priv->rx_mask1 |= FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | - FLEXCAN_IFLAG_RX_FIFO_AVAILABLE; - err = can_rx_offload_add_fifo(dev, &priv->offload, - FLEXCAN_NAPI_WEIGHT); diff --git a/target/linux/layerscape/patches-5.4/802-can-0012-can-flexcan-remove-TX-mailbox-bit-from-struct-flexca.patch b/target/linux/layerscape/patches-5.4/802-can-0012-can-flexcan-remove-TX-mailbox-bit-from-struct-flexca.patch deleted file mode 100644 index 8ab8e29dbd..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0012-can-flexcan-remove-TX-mailbox-bit-from-struct-flexca.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 916df9ddac295df428a304fd03ed492ad10e900c Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Fri, 1 Mar 2019 10:22:26 +0100 -Subject: [PATCH] can: flexcan: remove TX mailbox bit from struct - flexcan_priv::rx_mask{1,2} - -The flexcan IP core has up to 64 mailboxes, each one has a corresponding -interrupt bit in the iflag1 or iflag2 registers and a mask bit in the -imask1 or imask2 registers. - -In the timestamp (i.e. non FIFO) mode the driver needs to mask out all -non RX interrupt sources and uses the precomputed values rx_mask1 and -rx_mask2 of struct flexcan_priv for this. - -Currently these values cannot be used directly, as they contain the TX -mailbox flag. This patch removes the TX flag from flexcan_priv::rx_mask1 -and flexcan_priv::rx_mask2, and sets the TX flag directly when writing -the regs->iflag1 and regs->iflag2 into the hardware. - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 14 +++++--------- - 1 file changed, 5 insertions(+), 9 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -886,8 +886,7 @@ static inline u64 flexcan_read_reg_iflag - struct flexcan_regs __iomem *regs = priv->regs; - u32 iflag1, iflag2; - -- iflag2 = priv->read(®s->iflag2) & priv->rx_mask2 & -- ~FLEXCAN_IFLAG2_MB(priv->tx_mb_idx); -+ iflag2 = priv->read(®s->iflag2) & priv->rx_mask2; - iflag1 = priv->read(®s->iflag1) & priv->rx_mask1; - - return (u64)iflag2 << 32 | iflag1; -@@ -1234,7 +1233,7 @@ static int flexcan_chip_start(struct net - disable_irq(dev->irq); - priv->write(priv->reg_ctrl_default, ®s->ctrl); - priv->write(priv->rx_mask1, ®s->imask1); -- priv->write(priv->rx_mask2, ®s->imask2); -+ priv->write(priv->rx_mask2 | FLEXCAN_IFLAG2_MB(priv->tx_mb_idx), ®s->imask2); - enable_irq(dev->irq); - - /* print chip status */ -@@ -1328,9 +1327,6 @@ static int flexcan_open(struct net_devic - priv->tx_mb_idx = priv->mb_count - 1; - priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx); - -- priv->rx_mask1 = 0; -- priv->rx_mask2 = FLEXCAN_IFLAG2_MB(priv->tx_mb_idx); -- - priv->offload.mailbox_read = flexcan_mailbox_read; - - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { -@@ -1341,12 +1337,12 @@ static int flexcan_open(struct net_devic - - imask = GENMASK_ULL(priv->offload.mb_last, - priv->offload.mb_first); -- priv->rx_mask1 |= imask; -- priv->rx_mask2 |= imask >> 32; -+ priv->rx_mask1 = imask; -+ priv->rx_mask2 = imask >> 32; - - err = can_rx_offload_add_timestamp(dev, &priv->offload); - } else { -- priv->rx_mask1 |= FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | -+ priv->rx_mask1 = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | - FLEXCAN_IFLAG_RX_FIFO_AVAILABLE; - err = can_rx_offload_add_fifo(dev, &priv->offload, - FLEXCAN_NAPI_WEIGHT); diff --git a/target/linux/layerscape/patches-5.4/802-can-0013-can-flexcan-convert-struct-flexcan_priv-rx_mask-1-2-.patch b/target/linux/layerscape/patches-5.4/802-can-0013-can-flexcan-convert-struct-flexcan_priv-rx_mask-1-2-.patch deleted file mode 100644 index 9533726472..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0013-can-flexcan-convert-struct-flexcan_priv-rx_mask-1-2-.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 6adf87956ee1043e6bf0ef83fa0eec1e755c0d48 Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Fri, 1 Mar 2019 12:17:30 +0100 -Subject: [PATCH] can: flexcan: convert struct flexcan_priv::rx_mask{1,2} to - rx_mask - -The flexcan IP core has up to 64 mailboxes, each one has a corresponding -interrupt bit in the iflag1 or iflag2 registers and a mask bit in the -imask1 or imask2 registers. - -In the timestamp (i.e. non FIFO) mode the driver needs to mask out all non RX -interrupt sources and uses the precomputed values rx_mask1 and rx_mask2 of -struct flexcan_priv for this. - -This patch merges the two u32 rx_mask1 and rx_mask2 to a single u64 rx_mask -variable, which simplifies the code a bit. - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 30 +++++++++++++----------------- - 1 file changed, 13 insertions(+), 17 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -142,6 +142,7 @@ - #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 - #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 - #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1) -+#define FLEXCAN_IFLAG_MB(x) BIT_ULL(x) - #define FLEXCAN_IFLAG2_MB(x) BIT((x) & 0x1f) - #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) - #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) -@@ -277,9 +278,8 @@ struct flexcan_priv { - u8 mb_size; - u8 clk_src; /* clock source of CAN Protocol Engine */ - -+ u64 rx_mask; - u32 reg_ctrl_default; -- u32 rx_mask1; -- u32 rx_mask2; - - struct clk *clk_ipg; - struct clk *clk_per; -@@ -880,16 +880,15 @@ static struct sk_buff *flexcan_mailbox_r - return skb; - } - -- - static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) - { - struct flexcan_regs __iomem *regs = priv->regs; -- u32 iflag1, iflag2; -+ u64 iflag; - -- iflag2 = priv->read(®s->iflag2) & priv->rx_mask2; -- iflag1 = priv->read(®s->iflag1) & priv->rx_mask1; -+ iflag = (u64)priv->read(®s->iflag2) << 32 | -+ priv->read(®s->iflag1); - -- return (u64)iflag2 << 32 | iflag1; -+ return iflag & priv->rx_mask; - } - - static irqreturn_t flexcan_irq(int irq, void *dev_id) -@@ -1060,6 +1059,7 @@ static int flexcan_chip_start(struct net - struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->regs; - u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr; -+ u64 reg_imask; - int err, i; - struct flexcan_mb __iomem *mb; - -@@ -1232,8 +1232,9 @@ static int flexcan_chip_start(struct net - /* enable interrupts atomically */ - disable_irq(dev->irq); - priv->write(priv->reg_ctrl_default, ®s->ctrl); -- priv->write(priv->rx_mask1, ®s->imask1); -- priv->write(priv->rx_mask2 | FLEXCAN_IFLAG2_MB(priv->tx_mb_idx), ®s->imask2); -+ reg_imask = priv->rx_mask | FLEXCAN_IFLAG_MB(priv->tx_mb_idx); -+ priv->write(upper_32_bits(reg_imask), ®s->imask2); -+ priv->write(lower_32_bits(reg_imask), ®s->imask1); - enable_irq(dev->irq); - - /* print chip status */ -@@ -1330,19 +1331,14 @@ static int flexcan_open(struct net_devic - priv->offload.mailbox_read = flexcan_mailbox_read; - - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { -- u64 imask; -- - priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST; - priv->offload.mb_last = priv->mb_count - 2; - -- imask = GENMASK_ULL(priv->offload.mb_last, -- priv->offload.mb_first); -- priv->rx_mask1 = imask; -- priv->rx_mask2 = imask >> 32; -- -+ priv->rx_mask = GENMASK_ULL(priv->offload.mb_last, -+ priv->offload.mb_first); - err = can_rx_offload_add_timestamp(dev, &priv->offload); - } else { -- priv->rx_mask1 = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | -+ priv->rx_mask = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | - FLEXCAN_IFLAG_RX_FIFO_AVAILABLE; - err = can_rx_offload_add_fifo(dev, &priv->offload, - FLEXCAN_NAPI_WEIGHT); diff --git a/target/linux/layerscape/patches-5.4/802-can-0014-can-flexcan-introduce-struct-flexcan_priv-tx_mask-an.patch b/target/linux/layerscape/patches-5.4/802-can-0014-can-flexcan-introduce-struct-flexcan_priv-tx_mask-an.patch deleted file mode 100644 index 336fcd684d..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0014-can-flexcan-introduce-struct-flexcan_priv-tx_mask-an.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 1693e5693b77f0d172aac8adcfaa4888d64f8996 Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Fri, 1 Mar 2019 13:54:19 +0100 -Subject: [PATCH] can: flexcan: introduce struct flexcan_priv::tx_mask and make - use of it - -The current driver uses FLEXCAN_IFLAG2_MB() to generate the mask to check for -the TX complete interrupt. This works well, as the driver will always use the -last mailbox for TX, which falls into the iflag2 register. - -To support CANFD the payload size has to increase to 64 bytes and the -number of mailboxes will decrease so much that the TX mailbox will be -handled in the iflag1 register. - -This patch introduces a tx_mask in the struct flexcan_priv (similar to rx_mask) -and makes use of it. The actual support to handle the TX mailbox in iflag1 will -be added in the next patches. - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -143,7 +143,6 @@ - #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 - #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1) - #define FLEXCAN_IFLAG_MB(x) BIT_ULL(x) --#define FLEXCAN_IFLAG2_MB(x) BIT((x) & 0x1f) - #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) - #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) - #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) -@@ -279,6 +278,7 @@ struct flexcan_priv { - u8 clk_src; /* clock source of CAN Protocol Engine */ - - u64 rx_mask; -+ u64 tx_mask; - u32 reg_ctrl_default; - - struct clk *clk_ipg; -@@ -898,7 +898,8 @@ static irqreturn_t flexcan_irq(int irq, - struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->regs; - irqreturn_t handled = IRQ_NONE; -- u32 reg_iflag2, reg_esr; -+ u64 reg_iflag_tx; -+ u32 reg_esr; - enum can_state last_state = priv->can.state; - - /* reception interrupt */ -@@ -932,10 +933,10 @@ static irqreturn_t flexcan_irq(int irq, - } - } - -- reg_iflag2 = priv->read(®s->iflag2); -+ reg_iflag_tx = (u64)priv->read(®s->iflag2) << 32; - - /* transmission complete interrupt */ -- if (reg_iflag2 & FLEXCAN_IFLAG2_MB(priv->tx_mb_idx)) { -+ if (reg_iflag_tx & priv->tx_mask) { - u32 reg_ctrl = priv->read(&priv->tx_mb->can_ctrl); - - handled = IRQ_HANDLED; -@@ -947,7 +948,7 @@ static irqreturn_t flexcan_irq(int irq, - /* after sending a RTR frame MB is in RX mode */ - priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, - &priv->tx_mb->can_ctrl); -- priv->write(FLEXCAN_IFLAG2_MB(priv->tx_mb_idx), ®s->iflag2); -+ priv->write(priv->tx_mask >> 32, ®s->iflag2); - netif_wake_queue(dev); - } - -@@ -1232,7 +1233,7 @@ static int flexcan_chip_start(struct net - /* enable interrupts atomically */ - disable_irq(dev->irq); - priv->write(priv->reg_ctrl_default, ®s->ctrl); -- reg_imask = priv->rx_mask | FLEXCAN_IFLAG_MB(priv->tx_mb_idx); -+ reg_imask = priv->rx_mask | priv->tx_mask; - priv->write(upper_32_bits(reg_imask), ®s->imask2); - priv->write(lower_32_bits(reg_imask), ®s->imask1); - enable_irq(dev->irq); -@@ -1327,6 +1328,7 @@ static int flexcan_open(struct net_devic - flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_FIFO); - priv->tx_mb_idx = priv->mb_count - 1; - priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx); -+ priv->tx_mask = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); - - priv->offload.mailbox_read = flexcan_mailbox_read; - diff --git a/target/linux/layerscape/patches-5.4/802-can-0015-can-flexcan-flexcan_read_reg_iflag_rx-optimize-readi.patch b/target/linux/layerscape/patches-5.4/802-can-0015-can-flexcan-flexcan_read_reg_iflag_rx-optimize-readi.patch deleted file mode 100644 index c7e5e4ec4f..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0015-can-flexcan-flexcan_read_reg_iflag_rx-optimize-readi.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 74920ba156136a58dd3411c02d429d4f31497dc0 Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Fri, 1 Mar 2019 15:38:05 +0100 -Subject: [PATCH] can: flexcan: flexcan_read_reg_iflag_rx(): optimize reading - -The flexcan IP core has up to 64 mailboxes, each one has a corresponding -interrupt bit in the iflag1 or iflag2 registers and a mask bit in the -imask1 or imask2 registers. - -In the timestamp (i.e. non FIFO) mode the driver needs to mask all non RX -interrupt sources, it uses the precomputed value rx_mask of struct flexcan_priv -for this. - -In certain use cases, for example the CANFD mode, the contents of the iflag2 -register is completely masked. - -This patch optimizes the flexcan_read_reg_iflag_rx() function by not reading -the iflag1 or iflag2 register if the contents is masked. - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 28 +++++++++++++++++----------- - 1 file changed, 17 insertions(+), 11 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -786,6 +786,23 @@ static void flexcan_irq_state(struct net - dev->stats.rx_fifo_errors++; - } - -+static inline u64 flexcan_read64_mask(struct flexcan_priv *priv, void __iomem *addr, u64 mask) -+{ -+ u64 reg = 0; -+ -+ if (upper_32_bits(mask)) -+ reg = (u64)priv->read(addr - 4) << 32; -+ if (lower_32_bits(mask)) -+ reg |= priv->read(addr); -+ -+ return reg & mask; -+} -+ -+static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) -+{ -+ return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->rx_mask); -+} -+ - static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload) - { - return container_of(offload, struct flexcan_priv, offload); -@@ -880,17 +897,6 @@ static struct sk_buff *flexcan_mailbox_r - return skb; - } - --static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) --{ -- struct flexcan_regs __iomem *regs = priv->regs; -- u64 iflag; -- -- iflag = (u64)priv->read(®s->iflag2) << 32 | -- priv->read(®s->iflag1); -- -- return iflag & priv->rx_mask; --} -- - static irqreturn_t flexcan_irq(int irq, void *dev_id) - { - struct net_device *dev = dev_id; diff --git a/target/linux/layerscape/patches-5.4/802-can-0016-can-flexcan-flexcan_irq-add-support-for-TX-mailbox-i.patch b/target/linux/layerscape/patches-5.4/802-can-0016-can-flexcan-flexcan_irq-add-support-for-TX-mailbox-i.patch deleted file mode 100644 index f67ae18763..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0016-can-flexcan-flexcan_irq-add-support-for-TX-mailbox-i.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 57d3edbdcfee9b677452744bba5c4f08b476872a Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Fri, 1 Mar 2019 15:38:05 +0100 -Subject: [PATCH] can: flexcan: flexcan_irq(): add support for TX mailbox in - iflag1 - -The flexcan IP core has up to 64 mailboxes, each one has a corresponding -interrupt bit in the iflag1 or iflag2 registers and a mask bit in the -imask1 or imask2 registers. - -The driver will always use the last mailbox for TX, which falls into the iflag2 -register. - -To support CANFD the payload size has to increase to 64 bytes and the number of -mailboxes will decrease so much that the TX mailbox will be handled in the -iflag1 register. - -This patch add support to handle the TX mailbox independent whether it's -in iflag1 or iflag2 by introducing th flexcan_read_reg_iflag_tx() -function, similar to flexcan_read_reg_iflag_rx(), for the read path. - -For the write path the function flexcan_write64() is added. - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -798,11 +798,24 @@ static inline u64 flexcan_read64_mask(st - return reg & mask; - } - -+static inline void flexcan_write64(struct flexcan_priv *priv, u64 val, void __iomem *addr) -+{ -+ if (upper_32_bits(val)) -+ priv->write(upper_32_bits(val), addr - 4); -+ if (lower_32_bits(val)) -+ priv->write(lower_32_bits(val), addr); -+} -+ - static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) - { - return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->rx_mask); - } - -+static inline u64 flexcan_read_reg_iflag_tx(struct flexcan_priv *priv) -+{ -+ return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->tx_mask); -+} -+ - static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload) - { - return container_of(offload, struct flexcan_priv, offload); -@@ -939,7 +952,7 @@ static irqreturn_t flexcan_irq(int irq, - } - } - -- reg_iflag_tx = (u64)priv->read(®s->iflag2) << 32; -+ reg_iflag_tx = flexcan_read_reg_iflag_tx(priv); - - /* transmission complete interrupt */ - if (reg_iflag_tx & priv->tx_mask) { -@@ -954,7 +967,7 @@ static irqreturn_t flexcan_irq(int irq, - /* after sending a RTR frame MB is in RX mode */ - priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, - &priv->tx_mb->can_ctrl); -- priv->write(priv->tx_mask >> 32, ®s->iflag2); -+ flexcan_write64(priv, priv->tx_mask, ®s->iflag1); - netif_wake_queue(dev); - } - diff --git a/target/linux/layerscape/patches-5.4/802-can-0017-can-flexcan-flexcan_mailbox_read-make-use-of-flexcan.patch b/target/linux/layerscape/patches-5.4/802-can-0017-can-flexcan-flexcan_mailbox_read-make-use-of-flexcan.patch deleted file mode 100644 index b94992fac5..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0017-can-flexcan-flexcan_mailbox_read-make-use-of-flexcan.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 6340760d0671e92b15ff92b7eda41bbdd9702437 Mon Sep 17 00:00:00 2001 -From: Marc Kleine-Budde -Date: Fri, 1 Mar 2019 16:27:59 +0100 -Subject: [PATCH] can: flexcan: flexcan_mailbox_read() make use of - flexcan_write64() to mark the mailbox as read - -In the previous patch the function flexcan_write64() was introduced. - -This patch replaces the open coded variant in flexcan_mailbox_read() -that marks a mailbox as read, by a single call to flexcan_write64(). - -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 11 +++-------- - 1 file changed, 3 insertions(+), 8 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -891,15 +891,10 @@ static struct sk_buff *flexcan_mailbox_r - } - - mark_as_read: -- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { -- /* Clear IRQ */ -- if (n < 32) -- priv->write(BIT(n), ®s->iflag1); -- else -- priv->write(BIT(n - 32), ®s->iflag2); -- } else { -+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) -+ flexcan_write64(priv, FLEXCAN_IFLAG_MB(n), ®s->iflag1); -+ else - priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); -- } - - /* Read the Free Running Timer. It is optional but recommended - * to unlock Mailbox as soon as possible and make it available diff --git a/target/linux/layerscape/patches-5.4/802-can-0018-can-flexcan-use-struct-canfd_frame-for-CAN-classic-f.patch b/target/linux/layerscape/patches-5.4/802-can-0018-can-flexcan-use-struct-canfd_frame-for-CAN-classic-f.patch deleted file mode 100644 index 1e2a89d913..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0018-can-flexcan-use-struct-canfd_frame-for-CAN-classic-f.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 03374d551c7fbb1b1ecc115df4f374bc5027b1f9 Mon Sep 17 00:00:00 2001 -From: Joakim Zhang -Date: Fri, 12 Jul 2019 08:02:41 +0000 -Subject: [PATCH] can: flexcan: use struct canfd_frame for CAN classic frame - -This patch prepares for CAN FD mode, using struct canfd_frame can both -for classic format frame and fd format frame. - -Signed-off-by: Joakim Zhang -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 34 +++++++++++++++++----------------- - drivers/net/can/dev/rx-offload.c | 4 ++-- - 2 files changed, 19 insertions(+), 19 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -635,10 +635,10 @@ static int flexcan_get_berr_counter(cons - static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) - { - const struct flexcan_priv *priv = netdev_priv(dev); -- struct can_frame *cf = (struct can_frame *)skb->data; -+ struct canfd_frame *cfd = (struct canfd_frame *)skb->data; - u32 can_id; - u32 data; -- u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (cf->can_dlc << 16); -+ u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (cfd->len << 16); - int i; - - if (can_dropped_invalid_skb(dev, skb)) -@@ -646,18 +646,18 @@ static netdev_tx_t flexcan_start_xmit(st - - netif_stop_queue(dev); - -- if (cf->can_id & CAN_EFF_FLAG) { -- can_id = cf->can_id & CAN_EFF_MASK; -+ if (cfd->can_id & CAN_EFF_FLAG) { -+ can_id = cfd->can_id & CAN_EFF_MASK; - ctrl |= FLEXCAN_MB_CNT_IDE | FLEXCAN_MB_CNT_SRR; - } else { -- can_id = (cf->can_id & CAN_SFF_MASK) << 18; -+ can_id = (cfd->can_id & CAN_SFF_MASK) << 18; - } - -- if (cf->can_id & CAN_RTR_FLAG) -+ if (cfd->can_id & CAN_RTR_FLAG) - ctrl |= FLEXCAN_MB_CNT_RTR; - -- for (i = 0; i < cf->can_dlc; i += sizeof(u32)) { -- data = be32_to_cpup((__be32 *)&cf->data[i]); -+ for (i = 0; i < cfd->len; i += sizeof(u32)) { -+ data = be32_to_cpup((__be32 *)&cfd->data[i]); - priv->write(data, &priv->tx_mb->data[i / sizeof(u32)]); - } - -@@ -829,7 +829,7 @@ static struct sk_buff *flexcan_mailbox_r - struct flexcan_regs __iomem *regs = priv->regs; - struct flexcan_mb __iomem *mb; - struct sk_buff *skb; -- struct can_frame *cf; -+ struct canfd_frame *cfd; - u32 reg_ctrl, reg_id, reg_iflag1; - int i; - -@@ -866,8 +866,8 @@ static struct sk_buff *flexcan_mailbox_r - reg_ctrl = priv->read(&mb->can_ctrl); - } - -- skb = alloc_can_skb(offload->dev, &cf); -- if (!skb) { -+ skb = alloc_can_skb(offload->dev, (struct can_frame **)&cfd); -+ if (unlikely(!skb)) { - skb = ERR_PTR(-ENOMEM); - goto mark_as_read; - } -@@ -877,17 +877,17 @@ static struct sk_buff *flexcan_mailbox_r - - reg_id = priv->read(&mb->can_id); - if (reg_ctrl & FLEXCAN_MB_CNT_IDE) -- cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; -+ cfd->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; - else -- cf->can_id = (reg_id >> 18) & CAN_SFF_MASK; -+ cfd->can_id = (reg_id >> 18) & CAN_SFF_MASK; - - if (reg_ctrl & FLEXCAN_MB_CNT_RTR) -- cf->can_id |= CAN_RTR_FLAG; -- cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf); -+ cfd->can_id |= CAN_RTR_FLAG; -+ cfd->len = get_can_dlc((reg_ctrl >> 16) & 0xf); - -- for (i = 0; i < cf->can_dlc; i += sizeof(u32)) { -+ for (i = 0; i < cfd->len; i += sizeof(u32)) { - __be32 data = cpu_to_be32(priv->read(&mb->data[i / sizeof(u32)])); -- *(__be32 *)(cf->data + i) = data; -+ *(__be32 *)(cfd->data + i) = data; - } - - mark_as_read: ---- a/drivers/net/can/dev/rx-offload.c -+++ b/drivers/net/can/dev/rx-offload.c -@@ -51,11 +51,11 @@ static int can_rx_offload_napi_poll(stru - - while ((work_done < quota) && - (skb = skb_dequeue(&offload->skb_queue))) { -- struct can_frame *cf = (struct can_frame *)skb->data; -+ struct canfd_frame *cfd = (struct canfd_frame *)skb->data; - - work_done++; - stats->rx_packets++; -- stats->rx_bytes += cf->can_dlc; -+ stats->rx_bytes += cfd->len; - netif_receive_skb(skb); - } - diff --git a/target/linux/layerscape/patches-5.4/802-can-0019-can-flexcan-add-CAN-FD-mode-support.patch b/target/linux/layerscape/patches-5.4/802-can-0019-can-flexcan-add-CAN-FD-mode-support.patch deleted file mode 100644 index ee0dbd179e..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0019-can-flexcan-add-CAN-FD-mode-support.patch +++ /dev/null @@ -1,397 +0,0 @@ -From 2aea13a107090d05e968d7d2aa3f72380a3f1b4c Mon Sep 17 00:00:00 2001 -From: Joakim Zhang -Date: Fri, 12 Jul 2019 08:02:44 +0000 -Subject: [PATCH] can: flexcan: add CAN FD mode support - -This patch intends to add CAN FD mode support in driver, it means that -payload size can extend up to 64 bytes. - -Bit timing always set in CBT register other than CTRL1 register when -CANFD supports BRS, it will extend the range of all CAN bit timing -variables (PRESDIV, PROPSEG, PSEG1, PSEG2 and RJW), which will improve -the bit timing accuracy. - -Signed-off-by: Joakim Zhang -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 247 ++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 218 insertions(+), 29 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -52,6 +52,7 @@ - #define FLEXCAN_MCR_IRMQ BIT(16) - #define FLEXCAN_MCR_LPRIO_EN BIT(13) - #define FLEXCAN_MCR_AEN BIT(12) -+#define FLEXCAN_MCR_FDEN BIT(11) - /* MCR_MAXMB: maximum used MBs is MAXMB + 1 */ - #define FLEXCAN_MCR_MAXMB(x) ((x) & 0x7f) - #define FLEXCAN_MCR_IDAM_A (0x0 << 8) -@@ -137,6 +138,26 @@ - FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT | \ - FLEXCAN_ESR_WAK_INT) - -+/* FLEXCAN Bit Timing register (CBT) bits */ -+#define FLEXCAN_CBT_BTF BIT(31) -+#define FLEXCAN_CBT_EPRESDIV(x) (((x) & 0x3ff) << 21) -+#define FLEXCAN_CBT_ERJW(x) (((x) & 0x0f) << 16) -+#define FLEXCAN_CBT_EPROPSEG(x) (((x) & 0x3f) << 10) -+#define FLEXCAN_CBT_EPSEG1(x) (((x) & 0x1f) << 5) -+#define FLEXCAN_CBT_EPSEG2(x) ((x) & 0x1f) -+ -+/* FLEXCAN FD control register (FDCTRL) bits */ -+#define FLEXCAN_FDCTRL_FDRATE BIT(31) -+#define FLEXCAN_FDCTRL_MBDSR1(x) (((x) & 0x3) << 19) -+#define FLEXCAN_FDCTRL_MBDSR0(x) (((x) & 0x3) << 16) -+ -+/* FLEXCAN FD Bit Timing register (FDCBT) bits */ -+#define FLEXCAN_FDCBT_FPRESDIV(x) (((x) & 0x3ff) << 20) -+#define FLEXCAN_FDCBT_FRJW(x) (((x) & 0x07) << 16) -+#define FLEXCAN_FDCBT_FPROPSEG(x) (((x) & 0x1f) << 10) -+#define FLEXCAN_FDCBT_FPSEG1(x) (((x) & 0x07) << 5) -+#define FLEXCAN_FDCBT_FPSEG2(x) ((x) & 0x07) -+ - /* FLEXCAN interrupt flag register (IFLAG) bits */ - /* Errata ERR005829 step7: Reserve first valid MB */ - #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 -@@ -161,6 +182,9 @@ - #define FLEXCAN_MB_CODE_TX_DATA (0xc << 24) - #define FLEXCAN_MB_CODE_TX_TANSWER (0xe << 24) - -+#define FLEXCAN_MB_CNT_EDL BIT(31) -+#define FLEXCAN_MB_CNT_BRS BIT(30) -+#define FLEXCAN_MB_CNT_ESI BIT(29) - #define FLEXCAN_MB_CNT_SRR BIT(22) - #define FLEXCAN_MB_CNT_IDE BIT(21) - #define FLEXCAN_MB_CNT_RTR BIT(20) -@@ -192,6 +216,7 @@ - #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */ - #define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) /* default to BE register access */ - #define FLEXCAN_QUIRK_SETUP_STOP_MODE BIT(8) /* Setup stop mode to support wakeup */ -+#define FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD BIT(9) /* Use timestamp then support can fd mode */ - - /* Structure of the message buffer */ - struct flexcan_mb { -@@ -225,7 +250,8 @@ struct flexcan_regs { - u32 crcr; /* 0x44 */ - u32 rxfgmask; /* 0x48 */ - u32 rxfir; /* 0x4c */ -- u32 _reserved3[12]; /* 0x50 */ -+ u32 cbt; /* 0x50 */ -+ u32 _reserved3[11]; /* 0x54 */ - u8 mb[2][512]; /* 0x80 */ - /* FIFO-mode: - * MB -@@ -250,6 +276,10 @@ struct flexcan_regs { - u32 rerrdr; /* 0xaf4 */ - u32 rerrsynr; /* 0xaf8 */ - u32 errsr; /* 0xafc */ -+ u32 _reserved7[64]; /* 0xb00 */ -+ u32 fdctrl; /* 0xc00 */ -+ u32 fdcbt; /* 0xc04 */ -+ u32 fdcrc; /* 0xc08 */ - }; - - struct flexcan_devtype_data { -@@ -336,6 +366,30 @@ static const struct can_bittiming_const - .brp_inc = 1, - }; - -+static const struct can_bittiming_const flexcan_fd_bittiming_const = { -+ .name = DRV_NAME, -+ .tseg1_min = 2, -+ .tseg1_max = 96, -+ .tseg2_min = 2, -+ .tseg2_max = 32, -+ .sjw_max = 16, -+ .brp_min = 1, -+ .brp_max = 1024, -+ .brp_inc = 1, -+}; -+ -+static const struct can_bittiming_const flexcan_fd_data_bittiming_const = { -+ .name = DRV_NAME, -+ .tseg1_min = 2, -+ .tseg1_max = 39, -+ .tseg2_min = 2, -+ .tseg2_max = 8, -+ .sjw_max = 4, -+ .brp_min = 1, -+ .brp_max = 1024, -+ .brp_inc = 1, -+}; -+ - /* FlexCAN module is essentially modelled as a little-endian IP in most - * SoCs, i.e the registers as well as the message buffer areas are - * implemented in a little-endian fashion. -@@ -638,7 +692,7 @@ static netdev_tx_t flexcan_start_xmit(st - struct canfd_frame *cfd = (struct canfd_frame *)skb->data; - u32 can_id; - u32 data; -- u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (cfd->len << 16); -+ u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | ((can_len2dlc(cfd->len)) << 16); - int i; - - if (can_dropped_invalid_skb(dev, skb)) -@@ -656,6 +710,9 @@ static netdev_tx_t flexcan_start_xmit(st - if (cfd->can_id & CAN_RTR_FLAG) - ctrl |= FLEXCAN_MB_CNT_RTR; - -+ if (can_is_canfd_skb(skb)) -+ ctrl |= FLEXCAN_MB_CNT_EDL; -+ - for (i = 0; i < cfd->len; i += sizeof(u32)) { - data = be32_to_cpup((__be32 *)&cfd->data[i]); - priv->write(data, &priv->tx_mb->data[i / sizeof(u32)]); -@@ -866,7 +923,10 @@ static struct sk_buff *flexcan_mailbox_r - reg_ctrl = priv->read(&mb->can_ctrl); - } - -- skb = alloc_can_skb(offload->dev, (struct can_frame **)&cfd); -+ if (reg_ctrl & FLEXCAN_MB_CNT_EDL) -+ skb = alloc_canfd_skb(offload->dev, &cfd); -+ else -+ skb = alloc_can_skb(offload->dev, (struct can_frame **)&cfd); - if (unlikely(!skb)) { - skb = ERR_PTR(-ENOMEM); - goto mark_as_read; -@@ -881,9 +941,17 @@ static struct sk_buff *flexcan_mailbox_r - else - cfd->can_id = (reg_id >> 18) & CAN_SFF_MASK; - -- if (reg_ctrl & FLEXCAN_MB_CNT_RTR) -- cfd->can_id |= CAN_RTR_FLAG; -- cfd->len = get_can_dlc((reg_ctrl >> 16) & 0xf); -+ if (reg_ctrl & FLEXCAN_MB_CNT_EDL) { -+ cfd->len = can_dlc2len(get_canfd_dlc((reg_ctrl >> 16) & 0xf)); -+ } else { -+ cfd->len = get_can_dlc((reg_ctrl >> 16) & 0xf); -+ -+ if (reg_ctrl & FLEXCAN_MB_CNT_RTR) -+ cfd->can_id |= CAN_RTR_FLAG; -+ } -+ -+ if (reg_ctrl & FLEXCAN_MB_CNT_ESI) -+ cfd->flags |= CANFD_ESI; - - for (i = 0; i < cfd->len; i += sizeof(u32)) { - __be32 data = cpu_to_be32(priv->read(&mb->data[i / sizeof(u32)])); -@@ -1028,27 +1096,14 @@ static irqreturn_t flexcan_irq(int irq, - - static void flexcan_set_bittiming(struct net_device *dev) - { -- const struct flexcan_priv *priv = netdev_priv(dev); -- const struct can_bittiming *bt = &priv->can.bittiming; -+ struct flexcan_priv *priv = netdev_priv(dev); -+ struct can_bittiming *bt = &priv->can.bittiming; -+ struct can_bittiming *dbt = &priv->can.data_bittiming; - struct flexcan_regs __iomem *regs = priv->regs; -- u32 reg; -+ u32 reg, reg_cbt, reg_fdcbt; - - reg = priv->read(®s->ctrl); -- reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) | -- FLEXCAN_CTRL_RJW(0x3) | -- FLEXCAN_CTRL_PSEG1(0x7) | -- FLEXCAN_CTRL_PSEG2(0x7) | -- FLEXCAN_CTRL_PROPSEG(0x7) | -- FLEXCAN_CTRL_LPB | -- FLEXCAN_CTRL_SMP | -- FLEXCAN_CTRL_LOM); -- -- reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) | -- FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) | -- FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) | -- FLEXCAN_CTRL_RJW(bt->sjw - 1) | -- FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1); -- -+ reg &= ~(FLEXCAN_CTRL_LPB | FLEXCAN_CTRL_SMP | FLEXCAN_CTRL_LOM); - if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) - reg |= FLEXCAN_CTRL_LPB; - if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) -@@ -1059,9 +1114,102 @@ static void flexcan_set_bittiming(struct - netdev_dbg(dev, "writing ctrl=0x%08x\n", reg); - priv->write(reg, ®s->ctrl); - -- /* print chip status */ -- netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, -- priv->read(®s->mcr), priv->read(®s->ctrl)); -+ if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { -+ reg_cbt = priv->read(®s->cbt); -+ reg_cbt &= ~(FLEXCAN_CBT_EPRESDIV(0x3ff) | -+ FLEXCAN_CBT_EPSEG1(0x1f) | -+ FLEXCAN_CBT_EPSEG2(0x1f) | -+ FLEXCAN_CBT_ERJW(0x1f) | -+ FLEXCAN_CBT_EPROPSEG(0x3f) | -+ FLEXCAN_CBT_BTF); -+ -+ /* CBT[EPSEG1] is 5 bit long and CBT[EPROPSEG] is 6 bit long. -+ * The can_calc_bittiming tries to divide the tseg1 equally -+ * between phase_seg1 and prop_seg, which may not fit in CBT -+ * register. Therefore, if phase_seg1 is more than possible -+ * value, increase prop_seg and decrease phase_seg1 -+ */ -+ if (bt->phase_seg1 > 0x20) { -+ bt->prop_seg += (bt->phase_seg1 - 0x20); -+ bt->phase_seg1 = 0x20; -+ } -+ -+ reg_cbt = FLEXCAN_CBT_EPRESDIV(bt->brp - 1) | -+ FLEXCAN_CBT_EPSEG1(bt->phase_seg1 - 1) | -+ FLEXCAN_CBT_EPSEG2(bt->phase_seg2 - 1) | -+ FLEXCAN_CBT_ERJW(bt->sjw - 1) | -+ FLEXCAN_CBT_EPROPSEG(bt->prop_seg - 1) | -+ FLEXCAN_CBT_BTF; -+ priv->write(reg_cbt, ®s->cbt); -+ -+ netdev_dbg(dev, "bt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n", -+ bt->brp - 1, bt->phase_seg1 - 1, bt->phase_seg2 - 1, -+ bt->sjw - 1, bt->prop_seg - 1); -+ -+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { -+ reg_fdcbt = priv->read(®s->fdcbt); -+ reg_fdcbt &= ~(FLEXCAN_FDCBT_FPRESDIV(0x3ff) | -+ FLEXCAN_FDCBT_FPSEG1(0x07) | -+ FLEXCAN_FDCBT_FPSEG2(0x07) | -+ FLEXCAN_FDCBT_FRJW(0x07) | -+ FLEXCAN_FDCBT_FPROPSEG(0x1f)); -+ -+ /* FDCBT[FPSEG1] is 3 bit long and FDCBT[FPROPSEG] is 5 bit long. -+ * The can_calc_bittiming tries to divide the tseg1 equally -+ * between phase_seg1 and prop_seg, which may not fit in FDCBT -+ * register. Therefore, if phase_seg1 is more than possible -+ * value, increase prop_seg and decrease phase_seg1 -+ */ -+ if (dbt->phase_seg1 > 0x8) { -+ dbt->prop_seg += (dbt->phase_seg1 - 0x8); -+ dbt->phase_seg1 = 0x8; -+ } -+ -+ reg_fdcbt = FLEXCAN_FDCBT_FPRESDIV(dbt->brp - 1) | -+ FLEXCAN_FDCBT_FPSEG1(dbt->phase_seg1 - 1) | -+ FLEXCAN_FDCBT_FPSEG2(dbt->phase_seg2 - 1) | -+ FLEXCAN_FDCBT_FRJW(dbt->sjw - 1) | -+ FLEXCAN_FDCBT_FPROPSEG(dbt->prop_seg); -+ priv->write(reg_fdcbt, ®s->fdcbt); -+ -+ if (bt->brp != dbt->brp) -+ netdev_warn(dev, "Warning!! data brp = %d and brp = %d don't match.\n" -+ "flexcan may not work. consider using different bitrate or data bitrate\n", -+ dbt->brp, bt->brp); -+ -+ netdev_dbg(dev, "fdbt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n", -+ dbt->brp - 1, dbt->phase_seg1 - 1, dbt->phase_seg2 - 1, -+ dbt->sjw - 1, dbt->prop_seg); -+ -+ netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x cbt=0x%08x fdcbt=0x%08x\n", -+ __func__, priv->read(®s->mcr), -+ priv->read(®s->ctrl), -+ priv->read(®s->cbt), -+ priv->read(®s->fdcbt)); -+ } -+ } else { -+ reg = priv->read(®s->ctrl); -+ reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) | -+ FLEXCAN_CTRL_RJW(0x3) | -+ FLEXCAN_CTRL_PSEG1(0x7) | -+ FLEXCAN_CTRL_PSEG2(0x7) | -+ FLEXCAN_CTRL_PROPSEG(0x7)); -+ -+ reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) | -+ FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) | -+ FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) | -+ FLEXCAN_CTRL_RJW(bt->sjw - 1) | -+ FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1); -+ priv->write(reg, ®s->ctrl); -+ -+ netdev_dbg(dev, "bt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n", -+ bt->brp - 1, bt->phase_seg1 - 1, bt->phase_seg2 - 1, -+ bt->sjw - 1, bt->prop_seg - 1); -+ -+ /* print chip status */ -+ netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, -+ priv->read(®s->mcr), priv->read(®s->ctrl)); -+ } - } - - /* flexcan_chip_start -@@ -1073,7 +1221,7 @@ static int flexcan_chip_start(struct net - { - struct flexcan_priv *priv = netdev_priv(dev); - struct flexcan_regs __iomem *regs = priv->regs; -- u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr; -+ u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr, reg_fdctrl; - u64 reg_imask; - int err, i; - struct flexcan_mb __iomem *mb; -@@ -1172,6 +1320,26 @@ static int flexcan_chip_start(struct net - netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); - priv->write(reg_ctrl, ®s->ctrl); - -+ /* FDCTRL */ -+ if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { -+ reg_fdctrl = priv->read(®s->fdctrl) & ~FLEXCAN_FDCTRL_FDRATE; -+ reg_fdctrl &= ~(FLEXCAN_FDCTRL_MBDSR1(0x3) | FLEXCAN_FDCTRL_MBDSR0(0x3)); -+ reg_mcr = priv->read(®s->mcr) & ~FLEXCAN_MCR_FDEN; -+ -+ /* support BRS when set CAN FD mode -+ * 64 bytes payload per MB and 7 MBs per RAM block by default -+ * enable CAN FD mode -+ */ -+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { -+ reg_fdctrl |= FLEXCAN_FDCTRL_FDRATE; -+ reg_fdctrl |= FLEXCAN_FDCTRL_MBDSR1(0x3) | FLEXCAN_FDCTRL_MBDSR0(0x3); -+ reg_mcr |= FLEXCAN_MCR_FDEN; -+ } -+ -+ priv->write(reg_fdctrl, ®s->fdctrl); -+ priv->write(reg_mcr, ®s->mcr); -+ } -+ - if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) { - reg_ctrl2 = priv->read(®s->ctrl2); - reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS; -@@ -1312,6 +1480,12 @@ static int flexcan_open(struct net_devic - struct flexcan_priv *priv = netdev_priv(dev); - int err; - -+ if ((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) && -+ (priv->can.ctrlmode & CAN_CTRLMODE_FD)) { -+ netdev_err(dev, "three samples mode and fd mode can't be used together\n"); -+ return -EINVAL; -+ } -+ - err = pm_runtime_get_sync(priv->dev); - if (err < 0) { - pm_runtime_put_noidle(priv->dev); -@@ -1330,7 +1504,10 @@ static int flexcan_open(struct net_devic - if (err) - goto out_transceiver_disable; - -- priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN; -+ if (priv->can.ctrlmode & CAN_CTRLMODE_FD) -+ priv->mb_size = sizeof(struct flexcan_mb) + CANFD_MAX_DLEN; -+ else -+ priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN; - priv->mb_count = (sizeof(priv->regs->mb[0]) / priv->mb_size) + - (sizeof(priv->regs->mb[1]) / priv->mb_size); - -@@ -1682,6 +1859,18 @@ static int flexcan_probe(struct platform - priv->devtype_data = devtype_data; - priv->reg_xceiver = reg_xceiver; - -+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) { -+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { -+ priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD; -+ priv->can.bittiming_const = &flexcan_fd_bittiming_const; -+ priv->can.data_bittiming_const = &flexcan_fd_data_bittiming_const; -+ } else { -+ dev_err(&pdev->dev, "can fd mode can't work on fifo mode\n"); -+ err = -EINVAL; -+ goto failed_register; -+ } -+ } -+ - pm_runtime_get_noresume(&pdev->dev); - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); diff --git a/target/linux/layerscape/patches-5.4/802-can-0020-can-flexcan-add-CAN-FD-BRS-support.patch b/target/linux/layerscape/patches-5.4/802-can-0020-can-flexcan-add-CAN-FD-BRS-support.patch deleted file mode 100644 index 28e58ade3f..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0020-can-flexcan-add-CAN-FD-BRS-support.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 4c26434ac773e37f30ee5a8fa6f7275fe7dabac2 Mon Sep 17 00:00:00 2001 -From: Joakim Zhang -Date: Fri, 12 Jul 2019 08:02:47 +0000 -Subject: [PATCH] can: flexcan: add CAN FD BRS support - -This patch adds CAN FD BitRate Switch (BRS) support to driver. - -Signed-off-by: Joakim Zhang -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -710,9 +710,13 @@ static netdev_tx_t flexcan_start_xmit(st - if (cfd->can_id & CAN_RTR_FLAG) - ctrl |= FLEXCAN_MB_CNT_RTR; - -- if (can_is_canfd_skb(skb)) -+ if (can_is_canfd_skb(skb)) { - ctrl |= FLEXCAN_MB_CNT_EDL; - -+ if (cfd->flags & CANFD_BRS) -+ ctrl |= FLEXCAN_MB_CNT_BRS; -+ } -+ - for (i = 0; i < cfd->len; i += sizeof(u32)) { - data = be32_to_cpup((__be32 *)&cfd->data[i]); - priv->write(data, &priv->tx_mb->data[i / sizeof(u32)]); -@@ -943,6 +947,9 @@ static struct sk_buff *flexcan_mailbox_r - - if (reg_ctrl & FLEXCAN_MB_CNT_EDL) { - cfd->len = can_dlc2len(get_canfd_dlc((reg_ctrl >> 16) & 0xf)); -+ -+ if (reg_ctrl & FLEXCAN_MB_CNT_BRS) -+ cfd->flags |= CANFD_BRS; - } else { - cfd->len = get_can_dlc((reg_ctrl >> 16) & 0xf); - diff --git a/target/linux/layerscape/patches-5.4/802-can-0021-can-flexcan-add-ISO-CAN-FD-feature-support.patch b/target/linux/layerscape/patches-5.4/802-can-0021-can-flexcan-add-ISO-CAN-FD-feature-support.patch deleted file mode 100644 index 33459923fa..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0021-can-flexcan-add-ISO-CAN-FD-feature-support.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 094a648bc2217a9624f35224059c3eac86196143 Mon Sep 17 00:00:00 2001 -From: Joakim Zhang -Date: Fri, 12 Jul 2019 08:02:51 +0000 -Subject: [PATCH] can: flexcan: add ISO CAN FD feature support - -ISO CAN FD is introduced to increase the failture detection capability -than non-ISO CAN FD. The non-ISO CAN FD is still supported by FlexCAN so -that it can be used mainly during an intermediate phase, for evaluation -and development purposes. - -Therefore, it is strongly recommended to configure FlexCAN to the ISO -CAN FD protocol by setting the ISOCANFDEN field in the CTRL2 register. - -NOTE: If you only set "fd on", driver will use ISO FD mode by default. -You should set "fd-non-iso on" after setting "fd on" if you want to use -NON ISO FD mode. - -Signed-off-by: Joakim Zhang -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -92,6 +92,7 @@ - #define FLEXCAN_CTRL2_MRP BIT(18) - #define FLEXCAN_CTRL2_RRS BIT(17) - #define FLEXCAN_CTRL2_EACEN BIT(16) -+#define FLEXCAN_CTRL2_ISOCANFDEN BIT(12) - - /* FLEXCAN memory error control register (MECR) bits */ - #define FLEXCAN_MECR_ECRWRDIS BIT(31) -@@ -1332,6 +1333,7 @@ static int flexcan_chip_start(struct net - reg_fdctrl = priv->read(®s->fdctrl) & ~FLEXCAN_FDCTRL_FDRATE; - reg_fdctrl &= ~(FLEXCAN_FDCTRL_MBDSR1(0x3) | FLEXCAN_FDCTRL_MBDSR0(0x3)); - reg_mcr = priv->read(®s->mcr) & ~FLEXCAN_MCR_FDEN; -+ reg_ctrl2 = priv->read(®s->ctrl2) & ~FLEXCAN_CTRL2_ISOCANFDEN; - - /* support BRS when set CAN FD mode - * 64 bytes payload per MB and 7 MBs per RAM block by default -@@ -1341,10 +1343,14 @@ static int flexcan_chip_start(struct net - reg_fdctrl |= FLEXCAN_FDCTRL_FDRATE; - reg_fdctrl |= FLEXCAN_FDCTRL_MBDSR1(0x3) | FLEXCAN_FDCTRL_MBDSR0(0x3); - reg_mcr |= FLEXCAN_MCR_FDEN; -+ -+ if (!(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)) -+ reg_ctrl2 |= FLEXCAN_CTRL2_ISOCANFDEN; - } - - priv->write(reg_fdctrl, ®s->fdctrl); - priv->write(reg_mcr, ®s->mcr); -+ priv->write(reg_ctrl2, ®s->ctrl2); - } - - if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) { -@@ -1868,7 +1874,7 @@ static int flexcan_probe(struct platform - - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) { - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { -- priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD; -+ priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO; - priv->can.bittiming_const = &flexcan_fd_bittiming_const; - priv->can.data_bittiming_const = &flexcan_fd_data_bittiming_const; - } else { diff --git a/target/linux/layerscape/patches-5.4/802-can-0022-can-flexcan-add-Transceiver-Delay-Compensation-suopp.patch b/target/linux/layerscape/patches-5.4/802-can-0022-can-flexcan-add-Transceiver-Delay-Compensation-suopp.patch deleted file mode 100644 index 26dbb02c79..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0022-can-flexcan-add-Transceiver-Delay-Compensation-suopp.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 7b294e0cd2f7fbfb548a17b8d68d161da19e6592 Mon Sep 17 00:00:00 2001 -From: Joakim Zhang -Date: Fri, 12 Jul 2019 08:02:56 +0000 -Subject: [PATCH] can: flexcan: add Transceiver Delay Compensation suopport - -The CAN FD protocol allows the transmission and reception of data at a higher -bit rate than the nominal rate used in the arbitration phase when the message's -BRS bit is set. - -The TDC mechanism is effective only during the data phase of FD frames -having BRS bit set. It has no effect either on non-FD frames, or on FD -frames transmitted at normal bit rate. - -Signed-off-by: Joakim Zhang -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 19 ++++++++++++++++++- - 1 file changed, 18 insertions(+), 1 deletion(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -149,8 +149,11 @@ - - /* FLEXCAN FD control register (FDCTRL) bits */ - #define FLEXCAN_FDCTRL_FDRATE BIT(31) -+#define FLEXCAN_FDCTRL_TDCEN BIT(15) -+#define FLEXCAN_FDCTRL_TDCFAIL BIT(14) - #define FLEXCAN_FDCTRL_MBDSR1(x) (((x) & 0x3) << 19) - #define FLEXCAN_FDCTRL_MBDSR0(x) (((x) & 0x3) << 16) -+#define FLEXCAN_FDCTRL_TDCOFF(x) (((x) & 0x1f) << 8) - - /* FLEXCAN FD Bit Timing register (FDCBT) bits */ - #define FLEXCAN_FDCBT_FPRESDIV(x) (((x) & 0x3ff) << 20) -@@ -1108,7 +1111,7 @@ static void flexcan_set_bittiming(struct - struct can_bittiming *bt = &priv->can.bittiming; - struct can_bittiming *dbt = &priv->can.data_bittiming; - struct flexcan_regs __iomem *regs = priv->regs; -- u32 reg, reg_cbt, reg_fdcbt; -+ u32 reg, reg_cbt, reg_fdcbt, reg_fdctrl; - - reg = priv->read(®s->ctrl); - reg &= ~(FLEXCAN_CTRL_LPB | FLEXCAN_CTRL_SMP | FLEXCAN_CTRL_LOM); -@@ -1180,6 +1183,19 @@ static void flexcan_set_bittiming(struct - FLEXCAN_FDCBT_FPROPSEG(dbt->prop_seg); - priv->write(reg_fdcbt, ®s->fdcbt); - -+ /* enable transceiver delay compensation(TDC) for fd frame. -+ * TDC must be disabled when Loop Back mode is enabled. -+ */ -+ reg_fdctrl = priv->read(®s->fdctrl); -+ if (!(reg & FLEXCAN_CTRL_LPB)) { -+ reg_fdctrl |= FLEXCAN_FDCTRL_TDCEN; -+ reg_fdctrl &= ~FLEXCAN_FDCTRL_TDCOFF(0x1f); -+ /* for the TDC to work reliably, the offset has to use optimal settings */ -+ reg_fdctrl |= FLEXCAN_FDCTRL_TDCOFF(((dbt->phase_seg1 - 1) + dbt->prop_seg + 2) * -+ ((dbt->brp -1) + 1)); -+ } -+ priv->write(reg_fdctrl, ®s->fdctrl); -+ - if (bt->brp != dbt->brp) - netdev_warn(dev, "Warning!! data brp = %d and brp = %d don't match.\n" - "flexcan may not work. consider using different bitrate or data bitrate\n", -@@ -1331,6 +1347,7 @@ static int flexcan_chip_start(struct net - /* FDCTRL */ - if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { - reg_fdctrl = priv->read(®s->fdctrl) & ~FLEXCAN_FDCTRL_FDRATE; -+ reg_fdctrl &= ~FLEXCAN_FDCTRL_TDCEN; - reg_fdctrl &= ~(FLEXCAN_FDCTRL_MBDSR1(0x3) | FLEXCAN_FDCTRL_MBDSR0(0x3)); - reg_mcr = priv->read(®s->mcr) & ~FLEXCAN_MCR_FDEN; - reg_ctrl2 = priv->read(®s->ctrl2) & ~FLEXCAN_CTRL2_ISOCANFDEN; diff --git a/target/linux/layerscape/patches-5.4/802-can-0023-can-flexcan-add-imx8qm-support.patch b/target/linux/layerscape/patches-5.4/802-can-0023-can-flexcan-add-imx8qm-support.patch deleted file mode 100644 index 16a224faf0..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0023-can-flexcan-add-imx8qm-support.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 7ff112c7b144fb084f28f944d7021cd04acabecd Mon Sep 17 00:00:00 2001 -From: Joakim Zhang -Date: Fri, 12 Jul 2019 08:02:59 +0000 -Subject: [PATCH] can: flexcan: add imx8qm support - -The Flexcan on i.MX8QM supports CAN FD protocol. - -Signed-off-by: Joakim Zhang -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 26 +++++++++++++++++--------- - 1 file changed, 17 insertions(+), 9 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -200,15 +200,16 @@ - /* FLEXCAN hardware feature flags - * - * Below is some version info we got: -- * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR re- -- * Filter? connected? Passive detection ception in MB -- * MX25 FlexCAN2 03.00.00.00 no no no no no -- * MX28 FlexCAN2 03.00.04.00 yes yes no no no -- * MX35 FlexCAN2 03.00.00.00 no no no no no -- * MX53 FlexCAN2 03.00.00.00 yes no no no no -- * MX6s FlexCAN3 10.00.12.00 yes yes no no yes -- * VF610 FlexCAN3 ? no yes no yes yes? -- * LS1021A FlexCAN2 03.00.04.00 no yes no no yes -+ * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode -+ * Filter? connected? Passive detection ption in MB Supported? -+ * MX25 FlexCAN2 03.00.00.00 no no no no no no -+ * MX28 FlexCAN2 03.00.04.00 yes yes no no no no -+ * MX35 FlexCAN2 03.00.00.00 no no no no no no -+ * MX53 FlexCAN2 03.00.00.00 yes no no no no no -+ * MX6s FlexCAN3 10.00.12.00 yes yes no no yes no -+ * MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes -+ * VF610 FlexCAN3 ? no yes no yes yes? no -+ * LS1021A FlexCAN2 03.00.04.00 no yes no no yes no - * - * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. - */ -@@ -347,6 +348,12 @@ static const struct flexcan_devtype_data - FLEXCAN_QUIRK_SETUP_STOP_MODE, - }; - -+static struct flexcan_devtype_data fsl_imx8qm_devtype_data = { -+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | -+ FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE | -+ FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD, -+}; -+ - static const struct flexcan_devtype_data fsl_vf610_devtype_data = { - .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | - FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | -@@ -1775,6 +1782,7 @@ out_put_node: - } - - static const struct of_device_id flexcan_of_match[] = { -+ { .compatible = "fsl,imx8qm-flexcan", .data = &fsl_imx8qm_devtype_data, }, - { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, - { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, - { .compatible = "fsl,imx53-flexcan", .data = &fsl_imx25_devtype_data, }, diff --git a/target/linux/layerscape/patches-5.4/802-can-0024-can-flexcan-add-lx2160ar1-support.patch b/target/linux/layerscape/patches-5.4/802-can-0024-can-flexcan-add-lx2160ar1-support.patch deleted file mode 100644 index c4737398bf..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0024-can-flexcan-add-lx2160ar1-support.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3e13fca177e84f94ce691fb90f36086812972eff Mon Sep 17 00:00:00 2001 -From: Pankaj Bansal -Date: Fri, 12 Jul 2019 08:03:01 +0000 -Subject: [PATCH] can: flexcan: add lx2160ar1 support - -The Flexcan on lx2160ar1 supports CAN FD protocol. - -signed-off-by: Pankaj Bansal -Signed-off-by: Joakim Zhang -Signed-off-by: Marc Kleine-Budde ---- - drivers/net/can/flexcan.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -210,6 +210,7 @@ - * MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes - * VF610 FlexCAN3 ? no yes no yes yes? no - * LS1021A FlexCAN2 03.00.04.00 no yes no no yes no -+ * LX2160A FlexCAN3 03.00.23.00 no yes no no yes yes - * - * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. - */ -@@ -360,6 +361,12 @@ static const struct flexcan_devtype_data - FLEXCAN_QUIRK_BROKEN_PERR_STATE, - }; - -+static const struct flexcan_devtype_data fsl_lx2160a_r1_devtype_data = { -+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | -+ FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_BROKEN_PERR_STATE | -+ FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD, -+}; -+ - static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = { - .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | - FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP, -@@ -1791,6 +1798,7 @@ static const struct of_device_id flexcan - { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, - { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, }, - { .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, }, -+ { .compatible = "fsl,lx2160ar1-flexcan", .data = &fsl_lx2160a_r1_devtype_data, }, - { /* sentinel */ }, - }; - MODULE_DEVICE_TABLE(of, flexcan_of_match); diff --git a/target/linux/layerscape/patches-5.4/802-can-0025-can-flexcan-add-LPSR-mode-support-for-i.MX7D.patch b/target/linux/layerscape/patches-5.4/802-can-0025-can-flexcan-add-LPSR-mode-support-for-i.MX7D.patch deleted file mode 100644 index b8349e6d6d..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0025-can-flexcan-add-LPSR-mode-support-for-i.MX7D.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 211c20a459a0fd4868ed22ecfc2b2186d9df6da0 Mon Sep 17 00:00:00 2001 -From: Joakim Zhang -Date: Tue, 30 Jul 2019 14:43:25 +0800 -Subject: [PATCH] can: flexcan: add LPSR mode support for i.MX7D - -For i.MX7D LPSR mode, the controller will lost power and got the -configuration state lost after system resume back. -So we need to set pinctrl state again and re-start chip to do -re-configuration after resume. - -For wakeup case, it should not set pinctrl to sleep state by -pinctrl_pm_select_sleep_state. -For interface is not up before suspend case, we don't need -re-configure as it will be configured by user later by interface up. - -Signed-off-by: Joakim Zhang ---- - drivers/net/can/flexcan.c | 21 ++++++++++++++------- - 1 file changed, 14 insertions(+), 7 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - - #define DRV_NAME "flexcan" -@@ -1971,9 +1972,7 @@ static int __maybe_unused flexcan_suspen - if (err) - return err; - } else { -- err = flexcan_chip_disable(priv); -- if (err) -- return err; -+ flexcan_chip_stop(dev); - } - netif_stop_queue(dev); - netif_device_detach(dev); -@@ -1999,7 +1998,9 @@ static int __maybe_unused flexcan_resume - if (err) - return err; - } else { -- err = flexcan_chip_enable(priv); -+ err = flexcan_chip_start(dev); -+ if (err) -+ return err; - } - } - diff --git a/target/linux/layerscape/patches-5.4/802-can-0026-can-flexcan-fix-deadlock-when-using-self-wakeup.patch b/target/linux/layerscape/patches-5.4/802-can-0026-can-flexcan-fix-deadlock-when-using-self-wakeup.patch deleted file mode 100644 index 2d55cb9401..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0026-can-flexcan-fix-deadlock-when-using-self-wakeup.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 59876225748221d7ebbdb9c892a2086420ddd80d Mon Sep 17 00:00:00 2001 -From: Sean Nyekjaer -Date: Thu, 14 Nov 2019 19:56:28 +0800 -Subject: [PATCH] can: flexcan: fix deadlock when using self wakeup - -When suspending, when there is still can traffic on the interfaces the -flexcan immediately wakes the platform again. As it should :-). But it -throws this error msg: -[ 3169.378661] PM: noirq suspend of devices failed - -On the way down to suspend the interface that throws the error message does -call flexcan_suspend but fails to call flexcan_noirq_suspend. That means the -flexcan_enter_stop_mode is called, but on the way out of suspend the driver -only calls flexcan_resume and skips flexcan_noirq_resume, thus it doesn't call -flexcan_exit_stop_mode. This leaves the flexcan in stop mode, and with the -current driver it can't recover from this even with a soft reboot, it requires -a hard reboot. - -This patch can fix deadlock when using self wakeup, it happenes to be -able to fix another issue that frames out-of-order in first IRQ handler -run after wakeup. - -In wakeup case, after system resume, frames received out-of-order,the -problem is wakeup latency from frame reception to IRQ handler is much -bigger than the counter overflow. This means it's impossible to sort the -CAN frames by timestamp. The reason is that controller exits stop mode -during noirq resume, then it can receive the frame immediately. If -noirq reusme stage consumes much time, it will extend interrupt response -time. - -Fixes: de3578c198c6 ("can: flexcan: add self wakeup support") -Signed-off-by: Sean Nyekjaer -Signed-off-by: Joakim Zhang ---- - drivers/net/can/flexcan.c | 9 +++++++-- - 1 file changed, 7 insertions(+), 2 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -137,8 +137,7 @@ - (FLEXCAN_ESR_ERR_BUS | FLEXCAN_ESR_ERR_STATE) - #define FLEXCAN_ESR_ALL_INT \ - (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \ -- FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT | \ -- FLEXCAN_ESR_WAK_INT) -+ FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT) - - /* FLEXCAN Bit Timing register (CBT) bits */ - #define FLEXCAN_CBT_BTF BIT(31) -@@ -1062,6 +1061,12 @@ static irqreturn_t flexcan_irq(int irq, - - reg_esr = priv->read(®s->esr); - -+ /* ACK wakeup interrupt */ -+ if (reg_esr & FLEXCAN_ESR_WAK_INT) { -+ handled = IRQ_HANDLED; -+ priv->write(reg_esr & FLEXCAN_ESR_WAK_INT, ®s->esr); -+ } -+ - /* ACK all bus error and state change IRQ sources */ - if (reg_esr & FLEXCAN_ESR_ALL_INT) { - handled = IRQ_HANDLED; diff --git a/target/linux/layerscape/patches-5.4/802-can-0027-can-flexcan-add-CAN-wakeup-function-for-i.MX8.patch b/target/linux/layerscape/patches-5.4/802-can-0027-can-flexcan-add-CAN-wakeup-function-for-i.MX8.patch deleted file mode 100644 index 29104bd14e..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0027-can-flexcan-add-CAN-wakeup-function-for-i.MX8.patch +++ /dev/null @@ -1,193 +0,0 @@ -From 140de383d9d26e8be300b7ba86d56b47898cd8c9 Mon Sep 17 00:00:00 2001 -From: Joakim Zhang -Date: Tue, 30 Jul 2019 18:01:11 +0800 -Subject: [PATCH] can: flexcan: add CAN wakeup function for i.MX8 - -The System Controller Firmware (SCFW) is a low-level system function -which runs on a dedicated Cortex-M core to provide power, clock, and -resource management. It exists on some i.MX8 processors. e.g. i.MX8QM -(QM, QP), and i.MX8QX (QXP, DX). - -SCU driver manages the IPC interface between host CPU and the -SCU firmware running on M4. - -For i.MX8, stop mode request is controlled by System Controller Unit(SCU) -firmware. - -Signed-off-by: Joakim Zhang ---- - drivers/net/can/flexcan.c | 99 ++++++++++++++++++++++++++++++++++++++++------- - 1 file changed, 86 insertions(+), 13 deletions(-) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -29,6 +29,11 @@ - #include - #include - -+#ifdef CONFIG_IMX_SCU_SOC -+#include -+#include -+#endif -+ - #define DRV_NAME "flexcan" - - /* 8 for RX fifo and 2 error handling */ -@@ -223,6 +228,7 @@ - #define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) /* default to BE register access */ - #define FLEXCAN_QUIRK_SETUP_STOP_MODE BIT(8) /* Setup stop mode to support wakeup */ - #define FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD BIT(9) /* Use timestamp then support can fd mode */ -+#define FLEXCAN_QUIRK_USE_SCFW BIT(10) /* Use System Controller Firmware */ - - /* Structure of the message buffer */ - struct flexcan_mb { -@@ -323,6 +329,11 @@ struct flexcan_priv { - struct regulator *reg_xceiver; - struct flexcan_stop_mode stm; - -+#ifdef CONFIG_IMX_SCU_SOC -+ /* IPC handle when enable stop mode by System Controller firmware(scfw) */ -+ struct imx_sc_ipc *sc_ipc_handle; -+#endif -+ - /* Read and Write APIs */ - u32 (*read)(void __iomem *addr); - void (*write)(u32 val, void __iomem *addr); -@@ -352,7 +363,8 @@ static const struct flexcan_devtype_data - static struct flexcan_devtype_data fsl_imx8qm_devtype_data = { - .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | - FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE | -- FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD, -+ FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD | FLEXCAN_QUIRK_SETUP_STOP_MODE | -+ FLEXCAN_QUIRK_USE_SCFW, - }; - - static const struct flexcan_devtype_data fsl_vf610_devtype_data = { -@@ -503,6 +515,32 @@ static void flexcan_enable_wakeup_irq(st - priv->write(reg_mcr, ®s->mcr); - } - -+#ifdef CONFIG_IMX_SCU_SOC -+static void flexcan_stop_mode_enable_scfw(struct flexcan_priv *priv, bool enabled) -+{ -+ struct device_node *np = priv->dev->of_node; -+ u32 rsrc_id, val; -+ int idx; -+ -+ idx = of_alias_get_id(np, "can"); -+ if (idx == 0) -+ rsrc_id = IMX_SC_R_CAN_0; -+ else if (idx == 1) -+ rsrc_id = IMX_SC_R_CAN_1; -+ else -+ rsrc_id = IMX_SC_R_CAN_2; -+ -+ val = enabled ? 1 : 0; -+ /* stop mode request */ -+ imx_sc_misc_set_control(priv->sc_ipc_handle, rsrc_id, IMX_SC_C_IPG_STOP, val); -+} -+#else -+static int flexcan_stop_mode_enable_scfw(struct flexcan_priv *priv, bool enabled) -+{ -+ return 0; -+} -+#endif -+ - static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv) - { - struct flexcan_regs __iomem *regs = priv->regs; -@@ -512,9 +550,12 @@ static inline int flexcan_enter_stop_mod - reg_mcr |= FLEXCAN_MCR_SLF_WAK; - priv->write(reg_mcr, ®s->mcr); - -- /* enable stop request */ -- regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, -- 1 << priv->stm.req_bit, 1 << priv->stm.req_bit); -+ /* enable stop request */ -+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_SCFW) -+ flexcan_stop_mode_enable_scfw(priv, true); -+ else -+ regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, -+ 1 << priv->stm.req_bit, 1 << priv->stm.req_bit); - - return flexcan_low_power_enter_ack(priv); - } -@@ -525,8 +566,11 @@ static inline int flexcan_exit_stop_mode - u32 reg_mcr; - - /* remove stop request */ -- regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, -- 1 << priv->stm.req_bit, 0); -+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_SCFW) -+ flexcan_stop_mode_enable_scfw(priv, false); -+ else -+ regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, -+ 1 << priv->stm.req_bit, 0); - - - reg_mcr = priv->read(®s->mcr); -@@ -1782,11 +1826,6 @@ static int flexcan_setup_stop_mode(struc - gpr_np->full_name, priv->stm.req_gpr, priv->stm.req_bit, - priv->stm.ack_gpr, priv->stm.ack_bit); - -- device_set_wakeup_capable(&pdev->dev, true); -- -- if (of_property_read_bool(np, "wakeup-source")) -- device_set_wakeup_enable(&pdev->dev, true); -- - return 0; - - out_put_node: -@@ -1794,6 +1833,30 @@ out_put_node: - return ret; - } - -+#ifdef CONFIG_IMX_SCU_SOC -+static int flexcan_setup_stop_mode_scfw(struct platform_device *pdev) -+{ -+ struct net_device *dev = platform_get_drvdata(pdev); -+ struct flexcan_priv *priv; -+ int ret; -+ -+ priv = netdev_priv(dev); -+ -+ ret = imx_scu_get_handle(&(priv->sc_ipc_handle)); -+ if (ret < 0) { -+ dev_err(&pdev->dev, "get ipc handle used by SCU failed\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+#else -+static int flexcan_setup_stop_mode_scfw(struct platform_device *pdev) -+{ -+ return 0; -+} -+#endif -+ - static const struct of_device_id flexcan_of_match[] = { - { .compatible = "fsl,imx8qm-flexcan", .data = &fsl_imx8qm_devtype_data, }, - { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, -@@ -1936,9 +1999,19 @@ static int flexcan_probe(struct platform - devm_can_led_init(dev); - - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE) { -- err = flexcan_setup_stop_mode(pdev); -- if (err) -+ if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_SCFW) -+ err = flexcan_setup_stop_mode_scfw(pdev); -+ else -+ err = flexcan_setup_stop_mode(pdev); -+ -+ if (err) { - dev_dbg(&pdev->dev, "failed to setup stop-mode\n"); -+ } else { -+ device_set_wakeup_capable(&pdev->dev, true); -+ -+ if (of_property_read_bool(pdev->dev.of_node, "wakeup-source")) -+ device_set_wakeup_enable(&pdev->dev, true); -+ } - } - - return 0; diff --git a/target/linux/layerscape/patches-5.4/802-can-0028-can-flexcan-Add-S32V234-support-to-FlexCAN-driver.patch b/target/linux/layerscape/patches-5.4/802-can-0028-can-flexcan-Add-S32V234-support-to-FlexCAN-driver.patch deleted file mode 100644 index b12534c8d3..0000000000 --- a/target/linux/layerscape/patches-5.4/802-can-0028-can-flexcan-Add-S32V234-support-to-FlexCAN-driver.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 6a892e9147ff5b6a21a752326841869427068f01 Mon Sep 17 00:00:00 2001 -From: Chircu-Mare Bogdan-Petru -Date: Tue, 3 Nov 2015 17:25:46 +0200 -Subject: [PATCH] can: flexcan: Add S32V234 support to FlexCAN driver - -The FlexCAN driver is compatible with the modules on S32V234 chips. - -Signed-off-by: Chircu-Mare Bogdan-Petru -Signed-off-by: Dan Nica -Signed-off-by: Stefan-Gabriel Mirea -Reviewed-by: Li Yang -Reviewed-by: Joakim Zhang -Reviewed-by: Leonard Crestez ---- - drivers/net/can/flexcan.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/net/can/flexcan.c -+++ b/drivers/net/can/flexcan.c -@@ -6,6 +6,7 @@ - // Copyright (c) 2009 Sascha Hauer, Pengutronix - // Copyright (c) 2010-2017 Pengutronix, Marc Kleine-Budde - // Copyright (c) 2014 David Jander, Protonic Holland -+// Copyright 2015, 2018 NXP - // - // Based on code originally by Andrey Volkov - -@@ -384,6 +385,10 @@ static const struct flexcan_devtype_data - FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP, - }; - -+static struct flexcan_devtype_data fsl_s32v234_devtype_data = { -+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_DISABLE_MECR, -+}; -+ - static const struct can_bittiming_const flexcan_bittiming_const = { - .name = DRV_NAME, - .tseg1_min = 4, -@@ -1868,6 +1873,8 @@ static const struct of_device_id flexcan - { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, }, - { .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, }, - { .compatible = "fsl,lx2160ar1-flexcan", .data = &fsl_lx2160a_r1_devtype_data, }, -+ { .compatible = "fsl,s32v234-flexcan", -+ .data = &fsl_s32v234_devtype_data, }, - { /* sentinel */ }, - }; - MODULE_DEVICE_TABLE(of, flexcan_of_match); diff --git a/target/linux/layerscape/patches-5.4/803-clock-0001-clk-ls1028a-Add-clock-driver-for-Display-output-inte.patch b/target/linux/layerscape/patches-5.4/803-clock-0001-clk-ls1028a-Add-clock-driver-for-Display-output-inte.patch deleted file mode 100644 index 9d548d5f8f..0000000000 --- a/target/linux/layerscape/patches-5.4/803-clock-0001-clk-ls1028a-Add-clock-driver-for-Display-output-inte.patch +++ /dev/null @@ -1,351 +0,0 @@ -From e9e60d44268e2cfba73efeb7c3e68c355940f2c3 Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Wed, 27 Nov 2019 11:19:26 +0800 -Subject: [PATCH] clk: ls1028a: Add clock driver for Display output interface - -Add clock driver for QorIQ LS1028A Display output interfaces(LCD, DPHY), -as implemented in TSMC CLN28HPM PLL, this PLL supports the programmable -integer division and range of the display output pixel clock's 27-594MHz. - -Signed-off-by: Wen He -Signed-off-by: Michael Walle ---- - drivers/clk/Kconfig | 10 ++ - drivers/clk/Makefile | 1 + - drivers/clk/clk-plldig.c | 301 +++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 312 insertions(+) - create mode 100644 drivers/clk/clk-plldig.c - ---- a/drivers/clk/Kconfig -+++ b/drivers/clk/Kconfig -@@ -218,6 +218,16 @@ config CLK_QORIQ - This adds the clock driver support for Freescale QorIQ platforms - using common clock framework. - -+config CLK_LS1028A_PLLDIG -+ tristate "Clock driver for LS1028A Display output" -+ depends on ARCH_LAYERSCAPE || COMPILE_TEST -+ default ARCH_LAYERSCAPE -+ help -+ This driver support the Display output interfaces(LCD, DPHY) pixel clocks -+ of the QorIQ Layerscape LS1028A, as implemented TSMC CLN28HPM PLL. Not all -+ features of the PLL are currently supported by the driver. By default, -+ configured bypass mode with this PLL. -+ - config COMMON_CLK_XGENE - bool "Clock driver for APM XGene SoC" - default ARCH_XGENE ---- a/drivers/clk/Makefile -+++ b/drivers/clk/Makefile -@@ -43,6 +43,7 @@ obj-$(CONFIG_ARCH_NPCM7XX) += clk-n - obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o - obj-$(CONFIG_COMMON_CLK_OXNAS) += clk-oxnas.o - obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o -+obj-$(CONFIG_CLK_LS1028A_PLLDIG) += clk-plldig.o - obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o - obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o - obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o ---- /dev/null -+++ b/drivers/clk/clk-plldig.c -@@ -0,0 +1,301 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright 2019 NXP -+ * -+ * Clock driver for LS1028A Display output interfaces(LCD, DPHY). -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* PLLDIG register offsets and bit masks */ -+#define PLLDIG_REG_PLLSR 0x24 -+#define PLLDIG_LOCK_MASK BIT(2) -+#define PLLDIG_REG_PLLDV 0x28 -+#define PLLDIG_MFD_MASK GENMASK(7, 0) -+#define PLLDIG_RFDPHI1_MASK GENMASK(30, 25) -+#define PLLDIG_REG_PLLFM 0x2c -+#define PLLDIG_SSCGBYP_ENABLE BIT(30) -+#define PLLDIG_REG_PLLFD 0x30 -+#define PLLDIG_FDEN BIT(30) -+#define PLLDIG_FRAC_MASK GENMASK(15, 0) -+#define PLLDIG_DTH_MASK GENMASK(17, 16) -+#define PLLDIG_DTH_DISABLE 3 -+#define PLLDIG_REG_PLLCAL1 0x38 -+#define PLLDIG_REG_PLLCAL2 0x3c -+ -+/* Range of the VCO frequencies, in Hz */ -+#define PLLDIG_MIN_VCO_FREQ 650000000 -+#define PLLDIG_MAX_VCO_FREQ 1300000000 -+ -+/* Range of the output frequencies, in Hz */ -+#define PHI1_MIN_FREQ 27000000 -+#define PHI1_MAX_FREQ 600000000 -+ -+/* Maximum value of the reduced frequency divider */ -+#define MAX_RFDPHI1 63UL -+ -+/* Best value of multiplication factor divider */ -+#define PLLDIG_DEFAULT_MFD 44 -+ -+/* -+ * Denominator part of the fractional part of the -+ * loop multiplication factor. -+ */ -+#define MFDEN 20480 -+ -+static const struct clk_parent_data parent_data[] = { -+ {.index = 0}, -+}; -+ -+struct clk_plldig { -+ struct clk_hw hw; -+ void __iomem *regs; -+ unsigned int vco_freq; -+}; -+ -+#define to_clk_plldig(_hw) container_of(_hw, struct clk_plldig, hw) -+ -+static int plldig_enable(struct clk_hw *hw) -+{ -+ struct clk_plldig *data = to_clk_plldig(hw); -+ u32 val; -+ -+ val = readl(data->regs + PLLDIG_REG_PLLFM); -+ /* -+ * Use Bypass mode with PLL off by default, the frequency overshoot -+ * detector output was disable. SSCG Bypass mode should be enable. -+ */ -+ val |= PLLDIG_SSCGBYP_ENABLE; -+ writel(val, data->regs + PLLDIG_REG_PLLFM); -+ -+ return 0; -+} -+ -+static void plldig_disable(struct clk_hw *hw) -+{ -+ struct clk_plldig *data = to_clk_plldig(hw); -+ u32 val; -+ -+ val = readl(data->regs + PLLDIG_REG_PLLFM); -+ -+ val &= ~PLLDIG_SSCGBYP_ENABLE; -+ val |= FIELD_PREP(PLLDIG_SSCGBYP_ENABLE, 0x0); -+ -+ writel(val, data->regs + PLLDIG_REG_PLLFM); -+} -+ -+static int plldig_is_enabled(struct clk_hw *hw) -+{ -+ struct clk_plldig *data = to_clk_plldig(hw); -+ -+ return (readl(data->regs + PLLDIG_REG_PLLFM) & -+ PLLDIG_SSCGBYP_ENABLE); -+} -+ -+static unsigned long plldig_recalc_rate(struct clk_hw *hw, -+ unsigned long parent_rate) -+{ -+ struct clk_plldig *data = to_clk_plldig(hw); -+ u32 val, rfdphi1; -+ -+ val = readl(data->regs + PLLDIG_REG_PLLDV); -+ -+ /* Check if PLL is bypassed */ -+ if (val & PLLDIG_SSCGBYP_ENABLE) -+ return parent_rate; -+ -+ rfdphi1 = FIELD_GET(PLLDIG_RFDPHI1_MASK, val); -+ -+ /* -+ * If RFDPHI1 has a value of 1 the VCO frequency is also divided by -+ * one. -+ */ -+ if (!rfdphi1) -+ rfdphi1 = 1; -+ -+ return DIV_ROUND_UP(data->vco_freq, rfdphi1); -+} -+ -+static unsigned long plldig_calc_target_div(unsigned long vco_freq, -+ unsigned long target_rate) -+{ -+ unsigned long div; -+ -+ div = DIV_ROUND_CLOSEST(vco_freq, target_rate); -+ div = max(1UL, div); -+ div = min(div, MAX_RFDPHI1); -+ -+ return div; -+} -+ -+static int plldig_determine_rate(struct clk_hw *hw, -+ struct clk_rate_request *req) -+{ -+ struct clk_plldig *data = to_clk_plldig(hw); -+ unsigned int div; -+ -+ if (req->rate < PHI1_MIN_FREQ) -+ req->rate = PHI1_MIN_FREQ; -+ if (req->rate > PHI1_MAX_FREQ) -+ req->rate = PHI1_MAX_FREQ; -+ -+ div = plldig_calc_target_div(data->vco_freq, req->rate); -+ req->rate = DIV_ROUND_UP(data->vco_freq, div); -+ -+ return 0; -+} -+ -+static int plldig_set_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long parent_rate) -+{ -+ struct clk_plldig *data = to_clk_plldig(hw); -+ unsigned int val, cond; -+ unsigned int rfdphi1; -+ -+ if (rate < PHI1_MIN_FREQ) -+ rate = PHI1_MIN_FREQ; -+ if (rate > PHI1_MAX_FREQ) -+ rate = PHI1_MAX_FREQ; -+ -+ rfdphi1 = plldig_calc_target_div(data->vco_freq, rate); -+ -+ /* update the divider value */ -+ val = readl(data->regs + PLLDIG_REG_PLLDV); -+ val &= ~PLLDIG_RFDPHI1_MASK; -+ val |= FIELD_PREP(PLLDIG_RFDPHI1_MASK, rfdphi1); -+ writel(val, data->regs + PLLDIG_REG_PLLDV); -+ -+ /* delay 200us make sure that old lock state is cleared */ -+ udelay(200); -+ -+ /* Wait until PLL is locked or timeout (maximum 1000 usecs) */ -+ return readl_poll_timeout_atomic(data->regs + PLLDIG_REG_PLLSR, cond, -+ cond & PLLDIG_LOCK_MASK, 0, -+ USEC_PER_MSEC); -+} -+ -+static const struct clk_ops plldig_clk_ops = { -+ .enable = plldig_enable, -+ .disable = plldig_disable, -+ .is_enabled = plldig_is_enabled, -+ .recalc_rate = plldig_recalc_rate, -+ .determine_rate = plldig_determine_rate, -+ .set_rate = plldig_set_rate, -+}; -+ -+static int plldig_init(struct clk_hw *hw) -+{ -+ struct clk_plldig *data = to_clk_plldig(hw); -+ struct clk_hw *parent = clk_hw_get_parent(hw); -+ unsigned long parent_rate = clk_hw_get_rate(parent); -+ unsigned long val; -+ unsigned long long lltmp; -+ unsigned int mfd, fracdiv = 0; -+ -+ if (!parent) -+ return -EINVAL; -+ -+ if (data->vco_freq) { -+ mfd = data->vco_freq / parent_rate; -+ lltmp = data->vco_freq % parent_rate; -+ lltmp *= MFDEN; -+ do_div(lltmp, parent_rate); -+ fracdiv = lltmp; -+ } else { -+ mfd = PLLDIG_DEFAULT_MFD; -+ data->vco_freq = parent_rate * mfd; -+ } -+ -+ val = FIELD_PREP(PLLDIG_MFD_MASK, mfd); -+ writel(val, data->regs + PLLDIG_REG_PLLDV); -+ -+ if (fracdiv) { -+ val = FIELD_PREP(PLLDIG_FRAC_MASK, fracdiv); -+ /* Enable fractional divider */ -+ val |= PLLDIG_FDEN; -+ /* Disable dither */ -+ val |= FIELD_PREP(PLLDIG_DTH_MASK, PLLDIG_DTH_DISABLE); -+ writel(val, data->regs + PLLDIG_REG_PLLFD); -+ } -+ -+ return 0; -+} -+ -+static int plldig_clk_probe(struct platform_device *pdev) -+{ -+ struct clk_plldig *data; -+ struct resource *mem; -+ struct device *dev = &pdev->dev; -+ int ret; -+ -+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ data->regs = devm_ioremap_resource(dev, mem); -+ if (IS_ERR(data->regs)) -+ return PTR_ERR(data->regs); -+ -+ data->hw.init = CLK_HW_INIT_PARENTS_DATA("dpclk", -+ parent_data, -+ &plldig_clk_ops, -+ 0); -+ -+ ret = devm_clk_hw_register(dev, &data->hw); -+ if (ret) { -+ dev_err(dev, "failed to register %s clock\n", -+ dev->of_node->name); -+ return ret; -+ } -+ -+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, -+ &data->hw); -+ if (ret) { -+ dev_err(dev, "unable to add clk provider\n"); -+ return ret; -+ } -+ -+ /* -+ * The frequency of the VCO cannot be changed during runtime. -+ * Therefore, let the user specify a desired frequency. -+ */ -+ if (!of_property_read_u32(dev->of_node, "vco-frequency", -+ &data->vco_freq)) { -+ if (data->vco_freq < PLLDIG_MIN_VCO_FREQ || -+ data->vco_freq > PLLDIG_MAX_VCO_FREQ) -+ return -EINVAL; -+ } -+ -+ return plldig_init(&data->hw); -+} -+ -+static const struct of_device_id plldig_clk_id[] = { -+ { .compatible = "fsl,ls1028a-plldig"}, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, plldig_clk_id); -+ -+static struct platform_driver plldig_clk_driver = { -+ .driver = { -+ .name = "plldig-clock", -+ .of_match_table = plldig_clk_id, -+ }, -+ .probe = plldig_clk_probe, -+}; -+module_platform_driver(plldig_clk_driver); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Wen He "); -+MODULE_DESCRIPTION("LS1028A Display output interface pixel clock driver"); diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0001-crypto-add-support-for-TLS-1.0-record-encryption.patch b/target/linux/layerscape/patches-5.4/804-crypto-0001-crypto-add-support-for-TLS-1.0-record-encryption.patch deleted file mode 100644 index c73baa42ea..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0001-crypto-add-support-for-TLS-1.0-record-encryption.patch +++ /dev/null @@ -1,1205 +0,0 @@ -From 223db480c54de8ec47b3b0b4c6066b58342a5ad4 Mon Sep 17 00:00:00 2001 -From: Radu Alexe -Date: Wed, 3 May 2017 16:17:13 +0300 -Subject: [PATCH] crypto: add support for TLS 1.0 record encryption -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch adds kernel support for encryption/decryption of TLS 1.0 -records using block ciphers. Implementation is similar to authenc in the -sense that the base algorithms (AES, SHA1) are combined in a template to -produce TLS encapsulation frames. The composite algorithm will be called -"tls10(hmac(),cbc())". The cipher and hmac keys are -wrapped in the same format used by authenc.c. - -Signed-off-by: Radu Alexe -Signed-off-by: Cristian Stoica -Signed-off-by: Horia Geantă ---- - crypto/Kconfig | 20 ++ - crypto/Makefile | 1 + - crypto/tcrypt.c | 3 + - crypto/testmgr.c | 238 ++++++++++++++++++++++ - crypto/testmgr.h | 224 ++++++++++++++++++++ - crypto/tls.c | 607 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 6 files changed, 1093 insertions(+) - create mode 100644 crypto/tls.c - ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -349,6 +349,26 @@ config CRYPTO_ECHAINIV - a sequence number xored with a salt. This is the default - algorithm for CBC. - -+config CRYPTO_TLS -+ tristate "TLS support" -+ select CRYPTO_AEAD -+ select CRYPTO_BLKCIPHER -+ select CRYPTO_MANAGER -+ select CRYPTO_HASH -+ select CRYPTO_NULL -+ select CRYPTO_AUTHENC -+ help -+ Support for TLS 1.0 record encryption and decryption -+ -+ This module adds support for encryption/decryption of TLS 1.0 frames -+ using blockcipher algorithms. The name of the resulting algorithm is -+ "tls10(hmac(),cbc())". By default, the generic base -+ algorithms are used (e.g. aes-generic, sha1-generic), but hardware -+ accelerated versions will be used automatically if available. -+ -+ User-space applications (OpenSSL, GnuTLS) can offload TLS 1.0 -+ operations through AF_ALG or cryptodev interfaces -+ - comment "Block modes" - - config CRYPTO_CBC ---- a/crypto/Makefile -+++ b/crypto/Makefile -@@ -144,6 +144,7 @@ obj-$(CONFIG_CRYPTO_CRC32) += crc32_gene - obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o - obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o - obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o -+obj-$(CONFIG_CRYPTO_TLS) += tls.o - obj-$(CONFIG_CRYPTO_LZ4) += lz4.o - obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o - obj-$(CONFIG_CRYPTO_XXHASH) += xxhash_generic.o ---- a/crypto/tcrypt.c -+++ b/crypto/tcrypt.c -@@ -2049,6 +2049,9 @@ static int do_test(const char *alg, u32 - ret += tcrypt_test("cbc(sm4)"); - ret += tcrypt_test("ctr(sm4)"); - break; -+ case 192: -+ ret += tcrypt_test("tls10(hmac(sha1),cbc(aes))"); -+ break; - case 200: - test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, - speed_template_16_24_32); ---- a/crypto/testmgr.c -+++ b/crypto/testmgr.c -@@ -111,6 +111,13 @@ struct drbg_test_suite { - unsigned int count; - }; - -+struct tls_test_suite { -+ struct { -+ struct tls_testvec *vecs; -+ unsigned int count; -+ } enc, dec; -+}; -+ - struct akcipher_test_suite { - const struct akcipher_testvec *vecs; - unsigned int count; -@@ -135,6 +142,7 @@ struct alg_test_desc { - struct hash_test_suite hash; - struct cprng_test_suite cprng; - struct drbg_test_suite drbg; -+ struct tls_test_suite tls; - struct akcipher_test_suite akcipher; - struct kpp_test_suite kpp; - } suite; -@@ -2294,6 +2302,227 @@ static int test_aead(const char *driver, - return 0; - } - -+static int __test_tls(struct crypto_aead *tfm, int enc, -+ struct tls_testvec *template, unsigned int tcount, -+ const bool diff_dst) -+{ -+ const char *algo = crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)); -+ unsigned int i, k, authsize; -+ char *q; -+ struct aead_request *req; -+ struct scatterlist *sg; -+ struct scatterlist *sgout; -+ const char *e, *d; -+ struct crypto_wait wait; -+ void *input; -+ void *output; -+ void *assoc; -+ char *iv; -+ char *key; -+ char *xbuf[XBUFSIZE]; -+ char *xoutbuf[XBUFSIZE]; -+ char *axbuf[XBUFSIZE]; -+ int ret = -ENOMEM; -+ -+ if (testmgr_alloc_buf(xbuf)) -+ goto out_noxbuf; -+ -+ if (diff_dst && testmgr_alloc_buf(xoutbuf)) -+ goto out_nooutbuf; -+ -+ if (testmgr_alloc_buf(axbuf)) -+ goto out_noaxbuf; -+ -+ iv = kzalloc(MAX_IVLEN, GFP_KERNEL); -+ if (!iv) -+ goto out_noiv; -+ -+ key = kzalloc(MAX_KEYLEN, GFP_KERNEL); -+ if (!key) -+ goto out_nokey; -+ -+ sg = kmalloc(sizeof(*sg) * 8 * (diff_dst ? 2 : 1), GFP_KERNEL); -+ if (!sg) -+ goto out_nosg; -+ -+ sgout = sg + 8; -+ -+ d = diff_dst ? "-ddst" : ""; -+ e = enc ? "encryption" : "decryption"; -+ -+ crypto_init_wait(&wait); -+ -+ req = aead_request_alloc(tfm, GFP_KERNEL); -+ if (!req) { -+ pr_err("alg: tls%s: Failed to allocate request for %s\n", -+ d, algo); -+ goto out; -+ } -+ -+ aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, -+ crypto_req_done, &wait); -+ -+ for (i = 0; i < tcount; i++) { -+ input = xbuf[0]; -+ assoc = axbuf[0]; -+ -+ ret = -EINVAL; -+ if (WARN_ON(template[i].ilen > PAGE_SIZE || -+ template[i].alen > PAGE_SIZE)) -+ goto out; -+ -+ memcpy(assoc, template[i].assoc, template[i].alen); -+ memcpy(input, template[i].input, template[i].ilen); -+ -+ if (template[i].iv) -+ memcpy(iv, template[i].iv, MAX_IVLEN); -+ else -+ memset(iv, 0, MAX_IVLEN); -+ -+ crypto_aead_clear_flags(tfm, ~0); -+ -+ if (template[i].klen > MAX_KEYLEN) { -+ pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n", -+ d, i, algo, template[i].klen, MAX_KEYLEN); -+ ret = -EINVAL; -+ goto out; -+ } -+ memcpy(key, template[i].key, template[i].klen); -+ -+ ret = crypto_aead_setkey(tfm, key, template[i].klen); -+ if (!ret == template[i].fail) { -+ pr_err("alg: tls%s: setkey failed on test %d for %s: flags=%x\n", -+ d, i, algo, crypto_aead_get_flags(tfm)); -+ goto out; -+ } else if (ret) -+ continue; -+ -+ authsize = 20; -+ ret = crypto_aead_setauthsize(tfm, authsize); -+ if (ret) { -+ pr_err("alg: aead%s: Failed to set authsize to %u on test %d for %s\n", -+ d, authsize, i, algo); -+ goto out; -+ } -+ -+ k = !!template[i].alen; -+ sg_init_table(sg, k + 1); -+ sg_set_buf(&sg[0], assoc, template[i].alen); -+ sg_set_buf(&sg[k], input, (enc ? template[i].rlen : -+ template[i].ilen)); -+ output = input; -+ -+ if (diff_dst) { -+ sg_init_table(sgout, k + 1); -+ sg_set_buf(&sgout[0], assoc, template[i].alen); -+ -+ output = xoutbuf[0]; -+ sg_set_buf(&sgout[k], output, -+ (enc ? template[i].rlen : template[i].ilen)); -+ } -+ -+ aead_request_set_crypt(req, sg, (diff_dst) ? sgout : sg, -+ template[i].ilen, iv); -+ -+ aead_request_set_ad(req, template[i].alen); -+ -+ ret = crypto_wait_req(enc ? crypto_aead_encrypt(req) -+ : crypto_aead_decrypt(req), &wait); -+ -+ switch (ret) { -+ case 0: -+ if (template[i].novrfy) { -+ /* verification was supposed to fail */ -+ pr_err("alg: tls%s: %s failed on test %d for %s: ret was 0, expected -EBADMSG\n", -+ d, e, i, algo); -+ /* so really, we got a bad message */ -+ ret = -EBADMSG; -+ goto out; -+ } -+ break; -+ case -EBADMSG: -+ /* verification failure was expected */ -+ if (template[i].novrfy) -+ continue; -+ /* fall through */ -+ default: -+ pr_err("alg: tls%s: %s failed on test %d for %s: ret=%d\n", -+ d, e, i, algo, -ret); -+ goto out; -+ } -+ -+ q = output; -+ if (memcmp(q, template[i].result, template[i].rlen)) { -+ pr_err("alg: tls%s: Test %d failed on %s for %s\n", -+ d, i, e, algo); -+ hexdump(q, template[i].rlen); -+ pr_err("should be:\n"); -+ hexdump(template[i].result, template[i].rlen); -+ ret = -EINVAL; -+ goto out; -+ } -+ } -+ -+out: -+ aead_request_free(req); -+ -+ kfree(sg); -+out_nosg: -+ kfree(key); -+out_nokey: -+ kfree(iv); -+out_noiv: -+ testmgr_free_buf(axbuf); -+out_noaxbuf: -+ if (diff_dst) -+ testmgr_free_buf(xoutbuf); -+out_nooutbuf: -+ testmgr_free_buf(xbuf); -+out_noxbuf: -+ return ret; -+} -+ -+static int test_tls(struct crypto_aead *tfm, int enc, -+ struct tls_testvec *template, unsigned int tcount) -+{ -+ int ret; -+ /* test 'dst == src' case */ -+ ret = __test_tls(tfm, enc, template, tcount, false); -+ if (ret) -+ return ret; -+ /* test 'dst != src' case */ -+ return __test_tls(tfm, enc, template, tcount, true); -+} -+ -+static int alg_test_tls(const struct alg_test_desc *desc, const char *driver, -+ u32 type, u32 mask) -+{ -+ struct crypto_aead *tfm; -+ int err = 0; -+ -+ tfm = crypto_alloc_aead(driver, type, mask); -+ if (IS_ERR(tfm)) { -+ pr_err("alg: aead: Failed to load transform for %s: %ld\n", -+ driver, PTR_ERR(tfm)); -+ return PTR_ERR(tfm); -+ } -+ -+ if (desc->suite.tls.enc.vecs) { -+ err = test_tls(tfm, ENCRYPT, desc->suite.tls.enc.vecs, -+ desc->suite.tls.enc.count); -+ if (err) -+ goto out; -+ } -+ -+ if (!err && desc->suite.tls.dec.vecs) -+ err = test_tls(tfm, DECRYPT, desc->suite.tls.dec.vecs, -+ desc->suite.tls.dec.count); -+ -+out: -+ crypto_free_aead(tfm); -+ return err; -+} -+ - static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, - u32 type, u32 mask) - { -@@ -5042,6 +5271,15 @@ static const struct alg_test_desc alg_te - .hash = __VECS(tgr192_tv_template) - } - }, { -+ .alg = "tls10(hmac(sha1),cbc(aes))", -+ .test = alg_test_tls, -+ .suite = { -+ .tls = { -+ .enc = __VECS(tls_enc_tv_template), -+ .dec = __VECS(tls_dec_tv_template) -+ } -+ } -+ }, { - .alg = "vmac64(aes)", - .test = alg_test_hash, - .suite = { ---- a/crypto/testmgr.h -+++ b/crypto/testmgr.h -@@ -21,7 +21,12 @@ - #define _CRYPTO_TESTMGR_H - - #include -+#include - -+#define MAX_DIGEST_SIZE 64 -+#define MAX_TAP 8 -+ -+#define MAX_KEYLEN 160 - #define MAX_IVLEN 32 - - /* -@@ -140,6 +145,20 @@ struct drbg_testvec { - size_t expectedlen; - }; - -+struct tls_testvec { -+ char *key; /* wrapped keys for encryption and authentication */ -+ char *iv; /* initialization vector */ -+ char *input; /* input data */ -+ char *assoc; /* associated data: seq num, type, version, input len */ -+ char *result; /* result data */ -+ unsigned char fail; /* the test failure is expected */ -+ unsigned char novrfy; /* dec verification failure expected */ -+ unsigned char klen; /* key length */ -+ unsigned short ilen; /* input data length */ -+ unsigned short alen; /* associated data length */ -+ unsigned short rlen; /* result length */ -+}; -+ - struct akcipher_testvec { - const unsigned char *key; - const unsigned char *params; -@@ -171,6 +190,211 @@ struct kpp_testvec { - static const char zeroed_string[48]; - - /* -+ * TLS1.0 synthetic test vectors -+ */ -+static struct tls_testvec tls_enc_tv_template[] = { -+ { -+#ifdef __LITTLE_ENDIAN -+ .key = "\x08\x00" /* rta length */ -+ "\x01\x00" /* rta type */ -+#else -+ .key = "\x00\x08" /* rta length */ -+ "\x00\x01" /* rta type */ -+#endif -+ "\x00\x00\x00\x10" /* enc key length */ -+ "authenticationkey20benckeyis16_bytes", -+ .klen = 8 + 20 + 16, -+ .iv = "iv0123456789abcd", -+ .input = "Single block msg", -+ .ilen = 16, -+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07" -+ "\x00\x03\x01\x00\x10", -+ .alen = 13, -+ .result = "\xd5\xac\xb\xd2\xac\xad\x3f\xb1" -+ "\x59\x79\x1e\x91\x5f\x52\x14\x9c" -+ "\xc0\x75\xd8\x4c\x97\x0f\x07\x73" -+ "\xdc\x89\x47\x49\x49\xcb\x30\x6b" -+ "\x1b\x45\x23\xa1\xd0\x51\xcf\x02" -+ "\x2e\xa8\x5d\xa0\xfe\xca\x82\x61", -+ .rlen = 16 + 20 + 12, -+ }, { -+#ifdef __LITTLE_ENDIAN -+ .key = "\x08\x00" /* rta length */ -+ "\x01\x00" /* rta type */ -+#else -+ .key = "\x00\x08" /* rta length */ -+ "\x00\x01" /* rta type */ -+#endif -+ "\x00\x00\x00\x10" /* enc key length */ -+ "authenticationkey20benckeyis16_bytes", -+ .klen = 8 + 20 + 16, -+ .iv = "iv0123456789abcd", -+ .input = "", -+ .ilen = 0, -+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07" -+ "\x00\x03\x01\x00\x00", -+ .alen = 13, -+ .result = "\x58\x2a\x11\xc\x86\x8e\x4b\x67" -+ "\x2d\x16\x26\x1a\xac\x4b\xe2\x1a" -+ "\xe9\x6a\xcc\x4d\x6f\x79\x8a\x45" -+ "\x1f\x4e\x27\xf2\xa7\x59\xb4\x5a", -+ .rlen = 20 + 12, -+ }, { -+#ifdef __LITTLE_ENDIAN -+ .key = "\x08\x00" /* rta length */ -+ "\x01\x00" /* rta type */ -+#else -+ .key = "\x00\x08" /* rta length */ -+ "\x00\x01" /* rta type */ -+#endif -+ "\x00\x00\x00\x10" /* enc key length */ -+ "authenticationkey20benckeyis16_bytes", -+ .klen = 8 + 20 + 16, -+ .iv = "iv0123456789abcd", -+ .input = "285 bytes plaintext285 bytes plaintext285 bytes" -+ " plaintext285 bytes plaintext285 bytes plaintext285" -+ " bytes plaintext285 bytes plaintext285 bytes" -+ " plaintext285 bytes plaintext285 bytes plaintext285" -+ " bytes plaintext285 bytes plaintext285 bytes" -+ " plaintext285 bytes plaintext285 bytes plaintext285" -+ " bytes plaintext285 bytes plaintext", -+ .ilen = 285, -+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07" -+ "\x00\x03\x01\x01\x1d", -+ .alen = 13, -+ .result = "\x80\x23\x82\x44\x14\x2a\x1d\x94\xc\xc2\x1d\xd" -+ "\x3a\x32\x89\x4c\x57\x30\xa8\x89\x76\x46\xcc\x90" -+ "\x1d\x88\xb8\xa6\x1a\x58\xe\x2d\xeb\x2c\xc7\x3a" -+ "\x52\x4e\xdb\xb3\x1e\x83\x11\xf5\x3c\xce\x6e\x94" -+ "\xd3\x26\x6a\x9a\xd\xbd\xc7\x98\xb9\xb3\x3a\x51" -+ "\x1e\x4\x84\x8a\x8f\x54\x9a\x51\x69\x9c\xce\x31" -+ "\x8d\x5d\x8b\xee\x5f\x70\xc\xc9\xb8\x50\x54\xf8" -+ "\xb2\x4a\x7a\xcd\xeb\x7a\x82\x81\xc6\x41\xc8\x50" -+ "\x91\x8d\xc8\xed\xcd\x40\x8f\x55\xd1\xec\xc9\xac" -+ "\x15\x18\xf9\x20\xa0\xed\x18\xa1\xe3\x56\xe3\x14" -+ "\xe5\xe8\x66\x63\x20\xed\xe4\x62\x9d\xa3\xa4\x1d" -+ "\x81\x89\x18\xf2\x36\xae\xc8\x8a\x2b\xbc\xc3\xb8" -+ "\x80\xf\x97\x21\x36\x39\x8\x84\x23\x18\x9e\x9c" -+ "\x72\x32\x75\x2d\x2e\xf9\x60\xb\xe8\xcc\xd9\x74" -+ "\x4\x1b\x8e\x99\xc1\x94\xee\xd0\xac\x4e\xfc\x7e" -+ "\xf1\x96\xb3\xe7\x14\xb8\xf2\xc\x25\x97\x82\x6b" -+ "\xbd\x0\x65\xab\x5c\xe3\x16\xfb\x68\xef\xea\x9d" -+ "\xff\x44\x1d\x2a\x44\xf5\xc8\x56\x77\xb7\xbf\x13" -+ "\xc8\x54\xdb\x92\xfe\x16\x4c\xbe\x18\xe9\xb\x8d" -+ "\xb\xd4\x43\x58\x43\xaa\xf4\x3\x80\x97\x62\xd5" -+ "\xdf\x3c\x28\xaa\xee\x48\x4b\x55\x41\x1b\x31\x2" -+ "\xbe\xa0\x1c\xbd\xb7\x22\x2a\xe5\x53\x72\x73\x20" -+ "\x44\x4f\xe6\x1\x2b\x34\x33\x11\x7d\xfb\x10\xc1" -+ "\x66\x7c\xa6\xf4\x48\x36\x5e\x2\xda\x41\x4b\x3e" -+ "\xe7\x80\x17\x17\xce\xf1\x3e\x6a\x8e\x26\xf3\xb7" -+ "\x2b\x85\xd\x31\x8d\xba\x6c\x22\xb4\x28\x55\x7e" -+ "\x2a\x9e\x26\xf1\x3d\x21\xac\x65", -+ .rlen = 285 + 20 + 15, -+ } -+}; -+ -+static struct tls_testvec tls_dec_tv_template[] = { -+ { -+#ifdef __LITTLE_ENDIAN -+ .key = "\x08\x00" /* rta length */ -+ "\x01\x00" /* rta type */ -+#else -+ .key = "\x00\x08" /* rta length */ -+ "\x00\x01" /* rta type */ -+#endif -+ "\x00\x00\x00\x10" /* enc key length */ -+ "authenticationkey20benckeyis16_bytes", -+ .klen = 8 + 20 + 16, -+ .iv = "iv0123456789abcd", -+ .input = "\xd5\xac\xb\xd2\xac\xad\x3f\xb1" -+ "\x59\x79\x1e\x91\x5f\x52\x14\x9c" -+ "\xc0\x75\xd8\x4c\x97\x0f\x07\x73" -+ "\xdc\x89\x47\x49\x49\xcb\x30\x6b" -+ "\x1b\x45\x23\xa1\xd0\x51\xcf\x02" -+ "\x2e\xa8\x5d\xa0\xfe\xca\x82\x61", -+ .ilen = 16 + 20 + 12, -+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07" -+ "\x00\x03\x01\x00\x30", -+ .alen = 13, -+ .result = "Single block msg", -+ .rlen = 16, -+ }, { -+#ifdef __LITTLE_ENDIAN -+ .key = "\x08\x00" /* rta length */ -+ "\x01\x00" /* rta type */ -+#else -+ .key = "\x00\x08" /* rta length */ -+ "\x00\x01" /* rta type */ -+#endif -+ "\x00\x00\x00\x10" /* enc key length */ -+ "authenticationkey20benckeyis16_bytes", -+ .klen = 8 + 20 + 16, -+ .iv = "iv0123456789abcd", -+ .input = "\x58\x2a\x11\xc\x86\x8e\x4b\x67" -+ "\x2d\x16\x26\x1a\xac\x4b\xe2\x1a" -+ "\xe9\x6a\xcc\x4d\x6f\x79\x8a\x45" -+ "\x1f\x4e\x27\xf2\xa7\x59\xb4\x5a", -+ .ilen = 20 + 12, -+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07" -+ "\x00\x03\x01\x00\x20", -+ .alen = 13, -+ .result = "", -+ .rlen = 0, -+ }, { -+#ifdef __LITTLE_ENDIAN -+ .key = "\x08\x00" /* rta length */ -+ "\x01\x00" /* rta type */ -+#else -+ .key = "\x00\x08" /* rta length */ -+ "\x00\x01" /* rta type */ -+#endif -+ "\x00\x00\x00\x10" /* enc key length */ -+ "authenticationkey20benckeyis16_bytes", -+ .klen = 8 + 20 + 16, -+ .iv = "iv0123456789abcd", -+ .input = "\x80\x23\x82\x44\x14\x2a\x1d\x94\xc\xc2\x1d\xd" -+ "\x3a\x32\x89\x4c\x57\x30\xa8\x89\x76\x46\xcc\x90" -+ "\x1d\x88\xb8\xa6\x1a\x58\xe\x2d\xeb\x2c\xc7\x3a" -+ "\x52\x4e\xdb\xb3\x1e\x83\x11\xf5\x3c\xce\x6e\x94" -+ "\xd3\x26\x6a\x9a\xd\xbd\xc7\x98\xb9\xb3\x3a\x51" -+ "\x1e\x4\x84\x8a\x8f\x54\x9a\x51\x69\x9c\xce\x31" -+ "\x8d\x5d\x8b\xee\x5f\x70\xc\xc9\xb8\x50\x54\xf8" -+ "\xb2\x4a\x7a\xcd\xeb\x7a\x82\x81\xc6\x41\xc8\x50" -+ "\x91\x8d\xc8\xed\xcd\x40\x8f\x55\xd1\xec\xc9\xac" -+ "\x15\x18\xf9\x20\xa0\xed\x18\xa1\xe3\x56\xe3\x14" -+ "\xe5\xe8\x66\x63\x20\xed\xe4\x62\x9d\xa3\xa4\x1d" -+ "\x81\x89\x18\xf2\x36\xae\xc8\x8a\x2b\xbc\xc3\xb8" -+ "\x80\xf\x97\x21\x36\x39\x8\x84\x23\x18\x9e\x9c" -+ "\x72\x32\x75\x2d\x2e\xf9\x60\xb\xe8\xcc\xd9\x74" -+ "\x4\x1b\x8e\x99\xc1\x94\xee\xd0\xac\x4e\xfc\x7e" -+ "\xf1\x96\xb3\xe7\x14\xb8\xf2\xc\x25\x97\x82\x6b" -+ "\xbd\x0\x65\xab\x5c\xe3\x16\xfb\x68\xef\xea\x9d" -+ "\xff\x44\x1d\x2a\x44\xf5\xc8\x56\x77\xb7\xbf\x13" -+ "\xc8\x54\xdb\x92\xfe\x16\x4c\xbe\x18\xe9\xb\x8d" -+ "\xb\xd4\x43\x58\x43\xaa\xf4\x3\x80\x97\x62\xd5" -+ "\xdf\x3c\x28\xaa\xee\x48\x4b\x55\x41\x1b\x31\x2" -+ "\xbe\xa0\x1c\xbd\xb7\x22\x2a\xe5\x53\x72\x73\x20" -+ "\x44\x4f\xe6\x1\x2b\x34\x33\x11\x7d\xfb\x10\xc1" -+ "\x66\x7c\xa6\xf4\x48\x36\x5e\x2\xda\x41\x4b\x3e" -+ "\xe7\x80\x17\x17\xce\xf1\x3e\x6a\x8e\x26\xf3\xb7" -+ "\x2b\x85\xd\x31\x8d\xba\x6c\x22\xb4\x28\x55\x7e" -+ "\x2a\x9e\x26\xf1\x3d\x21\xac\x65", -+ -+ .ilen = 285 + 20 + 15, -+ .assoc = "\x00\x01\x02\x03\x04\x05\x06\x07" -+ "\x00\x03\x01\x01\x40", -+ .alen = 13, -+ .result = "285 bytes plaintext285 bytes plaintext285 bytes" -+ " plaintext285 bytes plaintext285 bytes plaintext285" -+ " bytes plaintext285 bytes plaintext285 bytes" -+ " plaintext285 bytes plaintext285 bytes plaintext285" -+ " bytes plaintext285 bytes plaintext285 bytes" -+ " plaintext285 bytes plaintext285 bytes plaintext", -+ .rlen = 285, -+ } -+}; -+ -+/* - * RSA test vectors. Borrowed from openSSL. - */ - static const struct akcipher_testvec rsa_tv_template[] = { ---- /dev/null -+++ b/crypto/tls.c -@@ -0,0 +1,607 @@ -+/* -+ * Copyright 2013 Freescale Semiconductor, Inc. -+ * Copyright 2017 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the Free -+ * Software Foundation; either version 2 of the License, or (at your option) -+ * any later version. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct tls_instance_ctx { -+ struct crypto_ahash_spawn auth; -+ struct crypto_skcipher_spawn enc; -+}; -+ -+struct crypto_tls_ctx { -+ unsigned int reqoff; -+ struct crypto_ahash *auth; -+ struct crypto_skcipher *enc; -+ struct crypto_sync_skcipher *null; -+}; -+ -+struct tls_request_ctx { -+ /* -+ * cryptlen holds the payload length in the case of encryption or -+ * payload_len + icv_len + padding_len in case of decryption -+ */ -+ unsigned int cryptlen; -+ /* working space for partial results */ -+ struct scatterlist tmp[2]; -+ struct scatterlist cipher[2]; -+ struct scatterlist dst[2]; -+ char tail[]; -+}; -+ -+struct async_op { -+ struct completion completion; -+ int err; -+}; -+ -+static void tls_async_op_done(struct crypto_async_request *req, int err) -+{ -+ struct async_op *areq = req->data; -+ -+ if (err == -EINPROGRESS) -+ return; -+ -+ areq->err = err; -+ complete(&areq->completion); -+} -+ -+static int crypto_tls_setkey(struct crypto_aead *tls, const u8 *key, -+ unsigned int keylen) -+{ -+ struct crypto_tls_ctx *ctx = crypto_aead_ctx(tls); -+ struct crypto_ahash *auth = ctx->auth; -+ struct crypto_skcipher *enc = ctx->enc; -+ struct crypto_authenc_keys keys; -+ int err = -EINVAL; -+ -+ if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) -+ goto badkey; -+ -+ crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK); -+ crypto_ahash_set_flags(auth, crypto_aead_get_flags(tls) & -+ CRYPTO_TFM_REQ_MASK); -+ err = crypto_ahash_setkey(auth, keys.authkey, keys.authkeylen); -+ crypto_aead_set_flags(tls, crypto_ahash_get_flags(auth) & -+ CRYPTO_TFM_RES_MASK); -+ -+ if (err) -+ goto out; -+ -+ crypto_skcipher_clear_flags(enc, CRYPTO_TFM_REQ_MASK); -+ crypto_skcipher_set_flags(enc, crypto_aead_get_flags(tls) & -+ CRYPTO_TFM_REQ_MASK); -+ err = crypto_skcipher_setkey(enc, keys.enckey, keys.enckeylen); -+ crypto_aead_set_flags(tls, crypto_skcipher_get_flags(enc) & -+ CRYPTO_TFM_RES_MASK); -+ -+out: -+ return err; -+ -+badkey: -+ crypto_aead_set_flags(tls, CRYPTO_TFM_RES_BAD_KEY_LEN); -+ goto out; -+} -+ -+/** -+ * crypto_tls_genicv - Calculate hmac digest for a TLS record -+ * @hash: (output) buffer to save the digest into -+ * @src: (input) scatterlist with the assoc and payload data -+ * @srclen: (input) size of the source buffer (assoclen + cryptlen) -+ * @req: (input) aead request -+ **/ -+static int crypto_tls_genicv(u8 *hash, struct scatterlist *src, -+ unsigned int srclen, struct aead_request *req) -+{ -+ struct crypto_aead *tls = crypto_aead_reqtfm(req); -+ struct crypto_tls_ctx *ctx = crypto_aead_ctx(tls); -+ struct tls_request_ctx *treq_ctx = aead_request_ctx(req); -+ struct async_op ahash_op; -+ struct ahash_request *ahreq = (void *)(treq_ctx->tail + ctx->reqoff); -+ unsigned int flags = CRYPTO_TFM_REQ_MAY_SLEEP; -+ int err = -EBADMSG; -+ -+ /* Bail out if the request assoc len is 0 */ -+ if (!req->assoclen) -+ return err; -+ -+ init_completion(&ahash_op.completion); -+ -+ /* the hash transform to be executed comes from the original request */ -+ ahash_request_set_tfm(ahreq, ctx->auth); -+ /* prepare the hash request with input data and result pointer */ -+ ahash_request_set_crypt(ahreq, src, hash, srclen); -+ /* set the notifier for when the async hash function returns */ -+ ahash_request_set_callback(ahreq, aead_request_flags(req) & flags, -+ tls_async_op_done, &ahash_op); -+ -+ /* Calculate the digest on the given data. The result is put in hash */ -+ err = crypto_ahash_digest(ahreq); -+ if (err == -EINPROGRESS) { -+ err = wait_for_completion_interruptible(&ahash_op.completion); -+ if (!err) -+ err = ahash_op.err; -+ } -+ -+ return err; -+} -+ -+/** -+ * crypto_tls_gen_padicv - Calculate and pad hmac digest for a TLS record -+ * @hash: (output) buffer to save the digest and padding into -+ * @phashlen: (output) the size of digest + padding -+ * @req: (input) aead request -+ **/ -+static int crypto_tls_gen_padicv(u8 *hash, unsigned int *phashlen, -+ struct aead_request *req) -+{ -+ struct crypto_aead *tls = crypto_aead_reqtfm(req); -+ unsigned int hash_size = crypto_aead_authsize(tls); -+ unsigned int block_size = crypto_aead_blocksize(tls); -+ unsigned int srclen = req->cryptlen + hash_size; -+ unsigned int icvlen = req->cryptlen + req->assoclen; -+ unsigned int padlen; -+ int err; -+ -+ err = crypto_tls_genicv(hash, req->src, icvlen, req); -+ if (err) -+ goto out; -+ -+ /* add padding after digest */ -+ padlen = block_size - (srclen % block_size); -+ memset(hash + hash_size, padlen - 1, padlen); -+ -+ *phashlen = hash_size + padlen; -+out: -+ return err; -+} -+ -+static int crypto_tls_copy_data(struct aead_request *req, -+ struct scatterlist *src, -+ struct scatterlist *dst, -+ unsigned int len) -+{ -+ struct crypto_aead *tls = crypto_aead_reqtfm(req); -+ struct crypto_tls_ctx *ctx = crypto_aead_ctx(tls); -+ SYNC_SKCIPHER_REQUEST_ON_STACK(skreq, ctx->null); -+ -+ skcipher_request_set_sync_tfm(skreq, ctx->null); -+ skcipher_request_set_callback(skreq, aead_request_flags(req), -+ NULL, NULL); -+ skcipher_request_set_crypt(skreq, src, dst, len, NULL); -+ -+ return crypto_skcipher_encrypt(skreq); -+} -+ -+static int crypto_tls_encrypt(struct aead_request *req) -+{ -+ struct crypto_aead *tls = crypto_aead_reqtfm(req); -+ struct crypto_tls_ctx *ctx = crypto_aead_ctx(tls); -+ struct tls_request_ctx *treq_ctx = aead_request_ctx(req); -+ struct skcipher_request *skreq; -+ struct scatterlist *cipher = treq_ctx->cipher; -+ struct scatterlist *tmp = treq_ctx->tmp; -+ struct scatterlist *sg, *src, *dst; -+ unsigned int cryptlen, phashlen; -+ u8 *hash = treq_ctx->tail; -+ int err; -+ -+ /* -+ * The hash result is saved at the beginning of the tls request ctx -+ * and is aligned as required by the hash transform. Enough space was -+ * allocated in crypto_tls_init_tfm to accommodate the difference. The -+ * requests themselves start later at treq_ctx->tail + ctx->reqoff so -+ * the result is not overwritten by the second (cipher) request. -+ */ -+ hash = (u8 *)ALIGN((unsigned long)hash + -+ crypto_ahash_alignmask(ctx->auth), -+ crypto_ahash_alignmask(ctx->auth) + 1); -+ -+ /* -+ * STEP 1: create ICV together with necessary padding -+ */ -+ err = crypto_tls_gen_padicv(hash, &phashlen, req); -+ if (err) -+ return err; -+ -+ /* -+ * STEP 2: Hash and padding are combined with the payload -+ * depending on the form it arrives. Scatter tables must have at least -+ * one page of data before chaining with another table and can't have -+ * an empty data page. The following code addresses these requirements. -+ * -+ * If the payload is empty, only the hash is encrypted, otherwise the -+ * payload scatterlist is merged with the hash. A special merging case -+ * is when the payload has only one page of data. In that case the -+ * payload page is moved to another scatterlist and prepared there for -+ * encryption. -+ */ -+ if (req->cryptlen) { -+ src = scatterwalk_ffwd(tmp, req->src, req->assoclen); -+ -+ sg_init_table(cipher, 2); -+ sg_set_buf(cipher + 1, hash, phashlen); -+ -+ if (sg_is_last(src)) { -+ sg_set_page(cipher, sg_page(src), req->cryptlen, -+ src->offset); -+ src = cipher; -+ } else { -+ unsigned int rem_len = req->cryptlen; -+ -+ for (sg = src; rem_len > sg->length; sg = sg_next(sg)) -+ rem_len -= min(rem_len, sg->length); -+ -+ sg_set_page(cipher, sg_page(sg), rem_len, sg->offset); -+ sg_chain(sg, 1, cipher); -+ } -+ } else { -+ sg_init_one(cipher, hash, phashlen); -+ src = cipher; -+ } -+ -+ /** -+ * If src != dst copy the associated data from source to destination. -+ * In both cases fast-forward passed the associated data in the dest. -+ */ -+ if (req->src != req->dst) { -+ err = crypto_tls_copy_data(req, req->src, req->dst, -+ req->assoclen); -+ if (err) -+ return err; -+ } -+ dst = scatterwalk_ffwd(treq_ctx->dst, req->dst, req->assoclen); -+ -+ /* -+ * STEP 3: encrypt the frame and return the result -+ */ -+ cryptlen = req->cryptlen + phashlen; -+ -+ /* -+ * The hash and the cipher are applied at different times and their -+ * requests can use the same memory space without interference -+ */ -+ skreq = (void *)(treq_ctx->tail + ctx->reqoff); -+ skcipher_request_set_tfm(skreq, ctx->enc); -+ skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv); -+ skcipher_request_set_callback(skreq, aead_request_flags(req), -+ req->base.complete, req->base.data); -+ /* -+ * Apply the cipher transform. The result will be in req->dst when the -+ * asynchronuous call terminates -+ */ -+ err = crypto_skcipher_encrypt(skreq); -+ -+ return err; -+} -+ -+static int crypto_tls_decrypt(struct aead_request *req) -+{ -+ struct crypto_aead *tls = crypto_aead_reqtfm(req); -+ struct crypto_tls_ctx *ctx = crypto_aead_ctx(tls); -+ struct tls_request_ctx *treq_ctx = aead_request_ctx(req); -+ unsigned int cryptlen = req->cryptlen; -+ unsigned int hash_size = crypto_aead_authsize(tls); -+ unsigned int block_size = crypto_aead_blocksize(tls); -+ struct skcipher_request *skreq = (void *)(treq_ctx->tail + ctx->reqoff); -+ struct scatterlist *tmp = treq_ctx->tmp; -+ struct scatterlist *src, *dst; -+ -+ u8 padding[255]; /* padding can be 0-255 bytes */ -+ u8 pad_size; -+ u16 *len_field; -+ u8 *ihash, *hash = treq_ctx->tail; -+ -+ int paderr = 0; -+ int err = -EINVAL; -+ int i; -+ struct async_op ciph_op; -+ -+ /* -+ * Rule out bad packets. The input packet length must be at least one -+ * byte more than the hash_size -+ */ -+ if (cryptlen <= hash_size || cryptlen % block_size) -+ goto out; -+ -+ /* -+ * Step 1 - Decrypt the source. Fast-forward past the associated data -+ * to the encrypted data. The result will be overwritten in place so -+ * that the decrypted data will be adjacent to the associated data. The -+ * last step (computing the hash) will have it's input data already -+ * prepared and ready to be accessed at req->src. -+ */ -+ src = scatterwalk_ffwd(tmp, req->src, req->assoclen); -+ dst = src; -+ -+ init_completion(&ciph_op.completion); -+ skcipher_request_set_tfm(skreq, ctx->enc); -+ skcipher_request_set_callback(skreq, aead_request_flags(req), -+ tls_async_op_done, &ciph_op); -+ skcipher_request_set_crypt(skreq, src, dst, cryptlen, req->iv); -+ err = crypto_skcipher_decrypt(skreq); -+ if (err == -EINPROGRESS) { -+ err = wait_for_completion_interruptible(&ciph_op.completion); -+ if (!err) -+ err = ciph_op.err; -+ } -+ if (err) -+ goto out; -+ -+ /* -+ * Step 2 - Verify padding -+ * Retrieve the last byte of the payload; this is the padding size. -+ */ -+ cryptlen -= 1; -+ scatterwalk_map_and_copy(&pad_size, dst, cryptlen, 1, 0); -+ -+ /* RFC recommendation for invalid padding size. */ -+ if (cryptlen < pad_size + hash_size) { -+ pad_size = 0; -+ paderr = -EBADMSG; -+ } -+ cryptlen -= pad_size; -+ scatterwalk_map_and_copy(padding, dst, cryptlen, pad_size, 0); -+ -+ /* Padding content must be equal with pad_size. We verify it all */ -+ for (i = 0; i < pad_size; i++) -+ if (padding[i] != pad_size) -+ paderr = -EBADMSG; -+ -+ /* -+ * Step 3 - Verify hash -+ * Align the digest result as required by the hash transform. Enough -+ * space was allocated in crypto_tls_init_tfm -+ */ -+ hash = (u8 *)ALIGN((unsigned long)hash + -+ crypto_ahash_alignmask(ctx->auth), -+ crypto_ahash_alignmask(ctx->auth) + 1); -+ /* -+ * Two bytes at the end of the associated data make the length field. -+ * It must be updated with the length of the cleartext message before -+ * the hash is calculated. -+ */ -+ len_field = sg_virt(req->src) + req->assoclen - 2; -+ cryptlen -= hash_size; -+ *len_field = htons(cryptlen); -+ -+ /* This is the hash from the decrypted packet. Save it for later */ -+ ihash = hash + hash_size; -+ scatterwalk_map_and_copy(ihash, dst, cryptlen, hash_size, 0); -+ -+ /* Now compute and compare our ICV with the one from the packet */ -+ err = crypto_tls_genicv(hash, req->src, cryptlen + req->assoclen, req); -+ if (!err) -+ err = memcmp(hash, ihash, hash_size) ? -EBADMSG : 0; -+ -+ if (req->src != req->dst) { -+ err = crypto_tls_copy_data(req, req->src, req->dst, cryptlen + -+ req->assoclen); -+ if (err) -+ goto out; -+ } -+ -+ /* return the first found error */ -+ if (paderr) -+ err = paderr; -+ -+out: -+ aead_request_complete(req, err); -+ return err; -+} -+ -+static int crypto_tls_init_tfm(struct crypto_aead *tfm) -+{ -+ struct aead_instance *inst = aead_alg_instance(tfm); -+ struct tls_instance_ctx *ictx = aead_instance_ctx(inst); -+ struct crypto_tls_ctx *ctx = crypto_aead_ctx(tfm); -+ struct crypto_ahash *auth; -+ struct crypto_skcipher *enc; -+ struct crypto_sync_skcipher *null; -+ int err; -+ -+ auth = crypto_spawn_ahash(&ictx->auth); -+ if (IS_ERR(auth)) -+ return PTR_ERR(auth); -+ -+ enc = crypto_spawn_skcipher(&ictx->enc); -+ err = PTR_ERR(enc); -+ if (IS_ERR(enc)) -+ goto err_free_ahash; -+ -+ null = crypto_get_default_null_skcipher(); -+ err = PTR_ERR(null); -+ if (IS_ERR(null)) -+ goto err_free_skcipher; -+ -+ ctx->auth = auth; -+ ctx->enc = enc; -+ ctx->null = null; -+ -+ /* -+ * Allow enough space for two digests. The two digests will be compared -+ * during the decryption phase. One will come from the decrypted packet -+ * and the other will be calculated. For encryption, one digest is -+ * padded (up to a cipher blocksize) and chained with the payload -+ */ -+ ctx->reqoff = ALIGN(crypto_ahash_digestsize(auth) + -+ crypto_ahash_alignmask(auth), -+ crypto_ahash_alignmask(auth) + 1) + -+ max(crypto_ahash_digestsize(auth), -+ crypto_skcipher_blocksize(enc)); -+ -+ crypto_aead_set_reqsize(tfm, -+ sizeof(struct tls_request_ctx) + -+ ctx->reqoff + -+ max_t(unsigned int, -+ crypto_ahash_reqsize(auth) + -+ sizeof(struct ahash_request), -+ crypto_skcipher_reqsize(enc) + -+ sizeof(struct skcipher_request))); -+ -+ return 0; -+ -+err_free_skcipher: -+ crypto_free_skcipher(enc); -+err_free_ahash: -+ crypto_free_ahash(auth); -+ return err; -+} -+ -+static void crypto_tls_exit_tfm(struct crypto_aead *tfm) -+{ -+ struct crypto_tls_ctx *ctx = crypto_aead_ctx(tfm); -+ -+ crypto_free_ahash(ctx->auth); -+ crypto_free_skcipher(ctx->enc); -+ crypto_put_default_null_skcipher(); -+} -+ -+static void crypto_tls_free(struct aead_instance *inst) -+{ -+ struct tls_instance_ctx *ctx = aead_instance_ctx(inst); -+ -+ crypto_drop_skcipher(&ctx->enc); -+ crypto_drop_ahash(&ctx->auth); -+ kfree(inst); -+} -+ -+static int crypto_tls_create(struct crypto_template *tmpl, struct rtattr **tb) -+{ -+ struct crypto_attr_type *algt; -+ struct aead_instance *inst; -+ struct hash_alg_common *auth; -+ struct crypto_alg *auth_base; -+ struct skcipher_alg *enc; -+ struct tls_instance_ctx *ctx; -+ const char *enc_name; -+ int err; -+ -+ algt = crypto_get_attr_type(tb); -+ if (IS_ERR(algt)) -+ return PTR_ERR(algt); -+ -+ if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) -+ return -EINVAL; -+ -+ auth = ahash_attr_alg(tb[1], CRYPTO_ALG_TYPE_HASH, -+ CRYPTO_ALG_TYPE_AHASH_MASK | -+ crypto_requires_sync(algt->type, algt->mask)); -+ if (IS_ERR(auth)) -+ return PTR_ERR(auth); -+ -+ auth_base = &auth->base; -+ -+ enc_name = crypto_attr_alg_name(tb[2]); -+ err = PTR_ERR(enc_name); -+ if (IS_ERR(enc_name)) -+ goto out_put_auth; -+ -+ inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); -+ err = -ENOMEM; -+ if (!inst) -+ goto out_put_auth; -+ -+ ctx = aead_instance_ctx(inst); -+ -+ err = crypto_init_ahash_spawn(&ctx->auth, auth, -+ aead_crypto_instance(inst)); -+ if (err) -+ goto err_free_inst; -+ -+ crypto_set_skcipher_spawn(&ctx->enc, aead_crypto_instance(inst)); -+ err = crypto_grab_skcipher(&ctx->enc, enc_name, 0, -+ crypto_requires_sync(algt->type, -+ algt->mask)); -+ if (err) -+ goto err_drop_auth; -+ -+ enc = crypto_spawn_skcipher_alg(&ctx->enc); -+ -+ err = -ENAMETOOLONG; -+ if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, -+ "tls10(%s,%s)", auth_base->cra_name, -+ enc->base.cra_name) >= CRYPTO_MAX_ALG_NAME) -+ goto err_drop_enc; -+ -+ if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, -+ "tls10(%s,%s)", auth_base->cra_driver_name, -+ enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME) -+ goto err_drop_enc; -+ -+ inst->alg.base.cra_flags = (auth_base->cra_flags | -+ enc->base.cra_flags) & CRYPTO_ALG_ASYNC; -+ inst->alg.base.cra_priority = enc->base.cra_priority * 10 + -+ auth_base->cra_priority; -+ inst->alg.base.cra_blocksize = enc->base.cra_blocksize; -+ inst->alg.base.cra_alignmask = auth_base->cra_alignmask | -+ enc->base.cra_alignmask; -+ inst->alg.base.cra_ctxsize = sizeof(struct crypto_tls_ctx); -+ -+ inst->alg.ivsize = crypto_skcipher_alg_ivsize(enc); -+ inst->alg.chunksize = crypto_skcipher_alg_chunksize(enc); -+ inst->alg.maxauthsize = auth->digestsize; -+ -+ inst->alg.init = crypto_tls_init_tfm; -+ inst->alg.exit = crypto_tls_exit_tfm; -+ -+ inst->alg.setkey = crypto_tls_setkey; -+ inst->alg.encrypt = crypto_tls_encrypt; -+ inst->alg.decrypt = crypto_tls_decrypt; -+ -+ inst->free = crypto_tls_free; -+ -+ err = aead_register_instance(tmpl, inst); -+ if (err) -+ goto err_drop_enc; -+ -+out: -+ crypto_mod_put(auth_base); -+ return err; -+ -+err_drop_enc: -+ crypto_drop_skcipher(&ctx->enc); -+err_drop_auth: -+ crypto_drop_ahash(&ctx->auth); -+err_free_inst: -+ kfree(inst); -+out_put_auth: -+ goto out; -+} -+ -+static struct crypto_template crypto_tls_tmpl = { -+ .name = "tls10", -+ .create = crypto_tls_create, -+ .module = THIS_MODULE, -+}; -+ -+static int __init crypto_tls_module_init(void) -+{ -+ return crypto_register_template(&crypto_tls_tmpl); -+} -+ -+static void __exit crypto_tls_module_exit(void) -+{ -+ crypto_unregister_template(&crypto_tls_tmpl); -+} -+ -+module_init(crypto_tls_module_init); -+module_exit(crypto_tls_module_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("TLS 1.0 record encryption"); diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0002-crypto-tcrypt-include-rsa-test.patch b/target/linux/layerscape/patches-5.4/804-crypto-0002-crypto-tcrypt-include-rsa-test.patch deleted file mode 100644 index 5be1e051a9..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0002-crypto-tcrypt-include-rsa-test.patch +++ /dev/null @@ -1,36 +0,0 @@ -From c579c23d57c0ef7c832cf0844c86c7be42c197d3 Mon Sep 17 00:00:00 2001 -From: Radu Alexe -Date: Thu, 13 Apr 2017 09:36:32 +0300 -Subject: [PATCH] crypto: tcrypt - include rsa test - -Signed-off-by: Radu Alexe -Signed-off-by: Tudor Ambarus ---- - crypto/tcrypt.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - ---- a/crypto/tcrypt.c -+++ b/crypto/tcrypt.c -@@ -71,9 +71,8 @@ static char *check[] = { - "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", - "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", - "camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320", -- "lzo", "lzo-rle", "cts", "sha3-224", "sha3-256", "sha3-384", -- "sha3-512", "streebog256", "streebog512", -- NULL -+ "lzo", "lzo-rle", "cts", "zlib", "sha3-224", "sha3-256", "sha3-384", -+ "sha3-512", "streebog256", "streebog512", "rsa", NULL - }; - - static u32 block_sizes[] = { 16, 64, 256, 1024, 1472, 8192, 0 }; -@@ -1983,6 +1982,10 @@ static int do_test(const char *alg, u32 - ret += tcrypt_test("hmac(streebog512)"); - break; - -+ case 117: -+ ret += tcrypt_test("rsa"); -+ break; -+ - case 150: - ret += tcrypt_test("ansi_cprng"); - break; diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0003-crypto-caam-use-mapped_-src-dst-_nents-for-descripto.patch b/target/linux/layerscape/patches-5.4/804-crypto-0003-crypto-caam-use-mapped_-src-dst-_nents-for-descripto.patch deleted file mode 100644 index 4e1efc858b..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0003-crypto-caam-use-mapped_-src-dst-_nents-for-descripto.patch +++ /dev/null @@ -1,227 +0,0 @@ -From e640f4bcfa0088ff696bc5da6063a1ea8d782189 Mon Sep 17 00:00:00 2001 -From: Iuliana Prodan -Date: Thu, 26 Sep 2019 15:26:29 +0300 -Subject: [PATCH] crypto: caam - use mapped_{src,dst}_nents for descriptor -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The mapped_{src,dst}_nents _returned_ from the dma_map_sg -call (which could be less than src/dst_nents) have to be -used to generate the job descriptors. - -Signed-off-by: Iuliana Prodan -Reviewed-by: Horia Geantă -Signed-off-by: Herbert Xu -(cherry picked from commit eff9771d51529acf7f6f58a60b2923b98da28f0e) ---- - drivers/crypto/caam/caampkc.c | 72 +++++++++++++++++++++++-------------------- - drivers/crypto/caam/caampkc.h | 8 +++-- - 2 files changed, 45 insertions(+), 35 deletions(-) - ---- a/drivers/crypto/caam/caampkc.c -+++ b/drivers/crypto/caam/caampkc.c -@@ -252,9 +252,9 @@ static struct rsa_edesc *rsa_edesc_alloc - gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? - GFP_KERNEL : GFP_ATOMIC; - int sg_flags = (flags == GFP_ATOMIC) ? SG_MITER_ATOMIC : 0; -- int sgc; - int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes; - int src_nents, dst_nents; -+ int mapped_src_nents, mapped_dst_nents; - unsigned int diff_size = 0; - int lzeros; - -@@ -285,13 +285,27 @@ static struct rsa_edesc *rsa_edesc_alloc - req_ctx->fixup_src_len); - dst_nents = sg_nents_for_len(req->dst, req->dst_len); - -- if (!diff_size && src_nents == 1) -+ mapped_src_nents = dma_map_sg(dev, req_ctx->fixup_src, src_nents, -+ DMA_TO_DEVICE); -+ if (unlikely(!mapped_src_nents)) { -+ dev_err(dev, "unable to map source\n"); -+ return ERR_PTR(-ENOMEM); -+ } -+ mapped_dst_nents = dma_map_sg(dev, req->dst, dst_nents, -+ DMA_FROM_DEVICE); -+ if (unlikely(!mapped_dst_nents)) { -+ dev_err(dev, "unable to map destination\n"); -+ goto src_fail; -+ } -+ -+ if (!diff_size && mapped_src_nents == 1) - sec4_sg_len = 0; /* no need for an input hw s/g table */ - else -- sec4_sg_len = src_nents + !!diff_size; -+ sec4_sg_len = mapped_src_nents + !!diff_size; - sec4_sg_index = sec4_sg_len; -- if (dst_nents > 1) -- sec4_sg_len += pad_sg_nents(dst_nents); -+ -+ if (mapped_dst_nents > 1) -+ sec4_sg_len += pad_sg_nents(mapped_dst_nents); - else - sec4_sg_len = pad_sg_nents(sec4_sg_len); - -@@ -301,19 +315,7 @@ static struct rsa_edesc *rsa_edesc_alloc - edesc = kzalloc(sizeof(*edesc) + desclen + sec4_sg_bytes, - GFP_DMA | flags); - if (!edesc) -- return ERR_PTR(-ENOMEM); -- -- sgc = dma_map_sg(dev, req_ctx->fixup_src, src_nents, DMA_TO_DEVICE); -- if (unlikely(!sgc)) { -- dev_err(dev, "unable to map source\n"); -- goto src_fail; -- } -- -- sgc = dma_map_sg(dev, req->dst, dst_nents, DMA_FROM_DEVICE); -- if (unlikely(!sgc)) { -- dev_err(dev, "unable to map destination\n"); - goto dst_fail; -- } - - edesc->sec4_sg = (void *)edesc + sizeof(*edesc) + desclen; - if (diff_size) -@@ -324,7 +326,7 @@ static struct rsa_edesc *rsa_edesc_alloc - sg_to_sec4_sg_last(req_ctx->fixup_src, req_ctx->fixup_src_len, - edesc->sec4_sg + !!diff_size, 0); - -- if (dst_nents > 1) -+ if (mapped_dst_nents > 1) - sg_to_sec4_sg_last(req->dst, req->dst_len, - edesc->sec4_sg + sec4_sg_index, 0); - -@@ -335,6 +337,9 @@ static struct rsa_edesc *rsa_edesc_alloc - if (!sec4_sg_bytes) - return edesc; - -+ edesc->mapped_src_nents = mapped_src_nents; -+ edesc->mapped_dst_nents = mapped_dst_nents; -+ - edesc->sec4_sg_dma = dma_map_single(dev, edesc->sec4_sg, - sec4_sg_bytes, DMA_TO_DEVICE); - if (dma_mapping_error(dev, edesc->sec4_sg_dma)) { -@@ -351,11 +356,11 @@ static struct rsa_edesc *rsa_edesc_alloc - return edesc; - - sec4_sg_fail: -- dma_unmap_sg(dev, req->dst, dst_nents, DMA_FROM_DEVICE); -+ kfree(edesc); - dst_fail: -- dma_unmap_sg(dev, req_ctx->fixup_src, src_nents, DMA_TO_DEVICE); -+ dma_unmap_sg(dev, req->dst, dst_nents, DMA_FROM_DEVICE); - src_fail: -- kfree(edesc); -+ dma_unmap_sg(dev, req_ctx->fixup_src, src_nents, DMA_TO_DEVICE); - return ERR_PTR(-ENOMEM); - } - -@@ -383,15 +388,15 @@ static int set_rsa_pub_pdb(struct akciph - return -ENOMEM; - } - -- if (edesc->src_nents > 1) { -+ if (edesc->mapped_src_nents > 1) { - pdb->sgf |= RSA_PDB_SGF_F; - pdb->f_dma = edesc->sec4_sg_dma; -- sec4_sg_index += edesc->src_nents; -+ sec4_sg_index += edesc->mapped_src_nents; - } else { - pdb->f_dma = sg_dma_address(req_ctx->fixup_src); - } - -- if (edesc->dst_nents > 1) { -+ if (edesc->mapped_dst_nents > 1) { - pdb->sgf |= RSA_PDB_SGF_G; - pdb->g_dma = edesc->sec4_sg_dma + - sec4_sg_index * sizeof(struct sec4_sg_entry); -@@ -428,17 +433,18 @@ static int set_rsa_priv_f1_pdb(struct ak - return -ENOMEM; - } - -- if (edesc->src_nents > 1) { -+ if (edesc->mapped_src_nents > 1) { - pdb->sgf |= RSA_PRIV_PDB_SGF_G; - pdb->g_dma = edesc->sec4_sg_dma; -- sec4_sg_index += edesc->src_nents; -+ sec4_sg_index += edesc->mapped_src_nents; -+ - } else { - struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); - - pdb->g_dma = sg_dma_address(req_ctx->fixup_src); - } - -- if (edesc->dst_nents > 1) { -+ if (edesc->mapped_dst_nents > 1) { - pdb->sgf |= RSA_PRIV_PDB_SGF_F; - pdb->f_dma = edesc->sec4_sg_dma + - sec4_sg_index * sizeof(struct sec4_sg_entry); -@@ -493,17 +499,17 @@ static int set_rsa_priv_f2_pdb(struct ak - goto unmap_tmp1; - } - -- if (edesc->src_nents > 1) { -+ if (edesc->mapped_src_nents > 1) { - pdb->sgf |= RSA_PRIV_PDB_SGF_G; - pdb->g_dma = edesc->sec4_sg_dma; -- sec4_sg_index += edesc->src_nents; -+ sec4_sg_index += edesc->mapped_src_nents; - } else { - struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); - - pdb->g_dma = sg_dma_address(req_ctx->fixup_src); - } - -- if (edesc->dst_nents > 1) { -+ if (edesc->mapped_dst_nents > 1) { - pdb->sgf |= RSA_PRIV_PDB_SGF_F; - pdb->f_dma = edesc->sec4_sg_dma + - sec4_sg_index * sizeof(struct sec4_sg_entry); -@@ -582,17 +588,17 @@ static int set_rsa_priv_f3_pdb(struct ak - goto unmap_tmp1; - } - -- if (edesc->src_nents > 1) { -+ if (edesc->mapped_src_nents > 1) { - pdb->sgf |= RSA_PRIV_PDB_SGF_G; - pdb->g_dma = edesc->sec4_sg_dma; -- sec4_sg_index += edesc->src_nents; -+ sec4_sg_index += edesc->mapped_src_nents; - } else { - struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); - - pdb->g_dma = sg_dma_address(req_ctx->fixup_src); - } - -- if (edesc->dst_nents > 1) { -+ if (edesc->mapped_dst_nents > 1) { - pdb->sgf |= RSA_PRIV_PDB_SGF_F; - pdb->f_dma = edesc->sec4_sg_dma + - sec4_sg_index * sizeof(struct sec4_sg_entry); ---- a/drivers/crypto/caam/caampkc.h -+++ b/drivers/crypto/caam/caampkc.h -@@ -112,8 +112,10 @@ struct caam_rsa_req_ctx { - - /** - * rsa_edesc - s/w-extended rsa descriptor -- * @src_nents : number of segments in input scatterlist -- * @dst_nents : number of segments in output scatterlist -+ * @src_nents : number of segments in input s/w scatterlist -+ * @dst_nents : number of segments in output s/w scatterlist -+ * @mapped_src_nents: number of segments in input h/w link table -+ * @mapped_dst_nents: number of segments in output h/w link table - * @sec4_sg_bytes : length of h/w link table - * @sec4_sg_dma : dma address of h/w link table - * @sec4_sg : pointer to h/w link table -@@ -123,6 +125,8 @@ struct caam_rsa_req_ctx { - struct rsa_edesc { - int src_nents; - int dst_nents; -+ int mapped_src_nents; -+ int mapped_dst_nents; - int sec4_sg_bytes; - dma_addr_t sec4_sg_dma; - struct sec4_sg_entry *sec4_sg; diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0004-crypto-caam-use-devres-to-unmap-memory.patch b/target/linux/layerscape/patches-5.4/804-crypto-0004-crypto-caam-use-devres-to-unmap-memory.patch deleted file mode 100644 index d85280ceb0..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0004-crypto-caam-use-devres-to-unmap-memory.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 76087c548649ea0fae04a0538f9de12546c5c680 Mon Sep 17 00:00:00 2001 -From: Andrey Smirnov -Date: Tue, 22 Oct 2019 08:30:08 -0700 -Subject: [PATCH] crypto: caam - use devres to unmap memory -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use devres to unmap memory and drop corresponding iounmap() call. - -Signed-off-by: Andrey Smirnov -Reviewed-by: Horia Geantă -Cc: Chris Healy -Cc: Lucas Stach -Cc: Horia Geantă -Cc: Herbert Xu -Cc: Iuliana Prodan -Cc: linux-crypto@vger.kernel.org -Cc: linux-kernel@vger.kernel.org -Signed-off-by: Herbert Xu -(cherry picked from commit 66e93b28075d3cae568ed97ef78789afa5a6eb36) ---- - drivers/crypto/caam/ctrl.c | 28 +++++++++------------------- - 1 file changed, 9 insertions(+), 19 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -308,11 +308,9 @@ static int caam_remove(struct platform_d - { - struct device *ctrldev; - struct caam_drv_private *ctrlpriv; -- struct caam_ctrl __iomem *ctrl; - - ctrldev = &pdev->dev; - ctrlpriv = dev_get_drvdata(ctrldev); -- ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl; - - /* Remove platform devices under the crypto node */ - of_platform_depopulate(ctrldev); -@@ -334,9 +332,6 @@ static int caam_remove(struct platform_d - debugfs_remove_recursive(ctrlpriv->dfs_root); - #endif - -- /* Unmap controller region */ -- iounmap(ctrl); -- - return 0; - } - -@@ -611,10 +606,11 @@ static int caam_probe(struct platform_de - - /* Get configuration properties from device tree */ - /* First, get register page */ -- ctrl = of_iomap(nprop, 0); -- if (!ctrl) { -+ ctrl = devm_of_iomap(dev, nprop, 0, NULL); -+ ret = PTR_ERR_OR_ZERO(ctrl); -+ if (ret) { - dev_err(dev, "caam: of_iomap() failed\n"); -- return -ENOMEM; -+ return ret; - } - - caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) & -@@ -632,22 +628,18 @@ static int caam_probe(struct platform_de - if (ctrlpriv->qi_present && !caam_dpaa2) { - ret = qman_is_probed(); - if (!ret) { -- ret = -EPROBE_DEFER; -- goto iounmap_ctrl; -+ return -EPROBE_DEFER; - } else if (ret < 0) { - dev_err(dev, "failing probe due to qman probe error\n"); -- ret = -ENODEV; -- goto iounmap_ctrl; -+ return -ENODEV; - } - - ret = qman_portals_probed(); - if (!ret) { -- ret = -EPROBE_DEFER; -- goto iounmap_ctrl; -+ return -EPROBE_DEFER; - } else if (ret < 0) { - dev_err(dev, "failing probe due to qman portals probe error\n"); -- ret = -ENODEV; -- goto iounmap_ctrl; -+ return -ENODEV; - } - } - #endif -@@ -720,7 +712,7 @@ static int caam_probe(struct platform_de - ret = dma_set_mask_and_coherent(dev, caam_get_dma_mask(dev)); - if (ret) { - dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret); -- goto iounmap_ctrl; -+ return ret; - } - - ctrlpriv->era = caam_get_era(ctrl); -@@ -925,8 +917,6 @@ shutdown_qi: - if (ctrlpriv->qi_init) - caam_qi_shutdown(dev); - #endif --iounmap_ctrl: -- iounmap(ctrl); - return ret; - } - diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0005-crypto-caam-use-devres-to-remove-debugfs.patch b/target/linux/layerscape/patches-5.4/804-crypto-0005-crypto-caam-use-devres-to-remove-debugfs.patch deleted file mode 100644 index ff15d95d08..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0005-crypto-caam-use-devres-to-remove-debugfs.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 93fbe7c21a64d22ac057fc9e8eed5967f5d0bd88 Mon Sep 17 00:00:00 2001 -From: Andrey Smirnov -Date: Tue, 22 Oct 2019 08:30:09 -0700 -Subject: [PATCH] crypto: caam - use devres to remove debugfs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use devres to remove debugfs and drop corresponding -debugfs_remove_recursive() call. - -Signed-off-by: Andrey Smirnov -Reviewed-by: Horia Geantă -Cc: Chris Healy -Cc: Lucas Stach -Cc: Horia Geantă -Cc: Herbert Xu -Cc: Iuliana Prodan -Cc: linux-crypto@vger.kernel.org -Cc: linux-kernel@vger.kernel.org -Signed-off-by: Herbert Xu -(cherry picked from commit eceb5daf9ebaa564a65eb2d9d5a4682a33747300) ---- - drivers/crypto/caam/ctrl.c | 21 ++++++++++++++------- - drivers/crypto/caam/intern.h | 1 - - 2 files changed, 14 insertions(+), 8 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -327,11 +327,6 @@ static int caam_remove(struct platform_d - if (!ctrlpriv->mc_en && ctrlpriv->rng4_sh_init) - deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init); - -- /* Shut down debug views */ --#ifdef CONFIG_DEBUG_FS -- debugfs_remove_recursive(ctrlpriv->dfs_root); --#endif -- - return 0; - } - -@@ -563,6 +558,13 @@ static int init_clocks(struct device *de - return devm_add_action_or_reset(dev, disable_clocks, ctrlpriv); - } - -+#ifdef CONFIG_DEBUG_FS -+static void caam_remove_debugfs(void *root) -+{ -+ debugfs_remove_recursive(root); -+} -+#endif -+ - /* Probe routine for CAAM top (controller) level */ - static int caam_probe(struct platform_device *pdev) - { -@@ -575,6 +577,7 @@ static int caam_probe(struct platform_de - struct caam_drv_private *ctrlpriv; - #ifdef CONFIG_DEBUG_FS - struct caam_perfmon *perfmon; -+ struct dentry *dfs_root; - #endif - u32 scfgr, comp_params; - u8 rng_vid; -@@ -726,8 +729,12 @@ static int caam_probe(struct platform_de - */ - perfmon = (struct caam_perfmon __force *)&ctrl->perfmon; - -- ctrlpriv->dfs_root = debugfs_create_dir(dev_name(dev), NULL); -- ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root); -+ dfs_root = debugfs_create_dir(dev_name(dev), NULL); -+ ret = devm_add_action_or_reset(dev, caam_remove_debugfs, dfs_root); -+ if (ret) -+ return ret; -+ -+ ctrlpriv->ctl = debugfs_create_dir("ctl", dfs_root); - #endif - - /* Check to see if (DPAA 1.x) QI present. If so, enable */ ---- a/drivers/crypto/caam/intern.h -+++ b/drivers/crypto/caam/intern.h -@@ -102,7 +102,6 @@ struct caam_drv_private { - * variables at runtime. - */ - #ifdef CONFIG_DEBUG_FS -- struct dentry *dfs_root; - struct dentry *ctl; /* controller dir */ - struct debugfs_blob_wrapper ctl_kek_wrap, ctl_tkek_wrap, ctl_tdsk_wrap; - #endif diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0006-crypto-caam-use-devres-to-de-initialize-the-RNG.patch b/target/linux/layerscape/patches-5.4/804-crypto-0006-crypto-caam-use-devres-to-de-initialize-the-RNG.patch deleted file mode 100644 index 6e3cd24ac0..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0006-crypto-caam-use-devres-to-de-initialize-the-RNG.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 4719469bf1e6d5bac8bb0426be4dd6a124471b69 Mon Sep 17 00:00:00 2001 -From: Andrey Smirnov -Date: Tue, 22 Oct 2019 08:30:10 -0700 -Subject: [PATCH] crypto: caam - use devres to de-initialize the RNG -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use devres to de-initialize the RNG and drop explicit de-initialization -code in caam_remove(). - -Signed-off-by: Andrey Smirnov -Cc: Chris Healy -Cc: Lucas Stach -Cc: Horia Geantă -Cc: Herbert Xu -Cc: Iuliana Prodan -Cc: linux-crypto@vger.kernel.org -Cc: linux-kernel@vger.kernel.org -Reviewed-by: Horia Geantă -Signed-off-by: Herbert Xu -(cherry picked from commit e57acaf0dfe0c8f63411d43cf7c689e43f6810c0) ---- - drivers/crypto/caam/ctrl.c | 130 ++++++++++++++++++++++++--------------------- - 1 file changed, 70 insertions(+), 60 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -176,6 +176,73 @@ static inline int run_descriptor_deco0(s - } - - /* -+ * deinstantiate_rng - builds and executes a descriptor on DECO0, -+ * which deinitializes the RNG block. -+ * @ctrldev - pointer to device -+ * @state_handle_mask - bitmask containing the instantiation status -+ * for the RNG4 state handles which exist in -+ * the RNG4 block: 1 if it's been instantiated -+ * -+ * Return: - 0 if no error occurred -+ * - -ENOMEM if there isn't enough memory to allocate the descriptor -+ * - -ENODEV if DECO0 couldn't be acquired -+ * - -EAGAIN if an error occurred when executing the descriptor -+ */ -+static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask) -+{ -+ u32 *desc, status; -+ int sh_idx, ret = 0; -+ -+ desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL); -+ if (!desc) -+ return -ENOMEM; -+ -+ for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) { -+ /* -+ * If the corresponding bit is set, then it means the state -+ * handle was initialized by us, and thus it needs to be -+ * deinitialized as well -+ */ -+ if ((1 << sh_idx) & state_handle_mask) { -+ /* -+ * Create the descriptor for deinstantating this state -+ * handle -+ */ -+ build_deinstantiation_desc(desc, sh_idx); -+ -+ /* Try to run it through DECO0 */ -+ ret = run_descriptor_deco0(ctrldev, desc, &status); -+ -+ if (ret || -+ (status && status != JRSTA_SSRC_JUMP_HALT_CC)) { -+ dev_err(ctrldev, -+ "Failed to deinstantiate RNG4 SH%d\n", -+ sh_idx); -+ break; -+ } -+ dev_info(ctrldev, "Deinstantiated RNG4 SH%d\n", sh_idx); -+ } -+ } -+ -+ kfree(desc); -+ -+ return ret; -+} -+ -+static void devm_deinstantiate_rng(void *data) -+{ -+ struct device *ctrldev = data; -+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); -+ -+ /* -+ * De-initialize RNG state handles initialized by this driver. -+ * In case of SoCs with Management Complex, RNG is managed by MC f/w. -+ */ -+ if (ctrlpriv->rng4_sh_init) -+ deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init); -+} -+ -+/* - * instantiate_rng - builds and executes a descriptor on DECO0, - * which initializes the RNG block. - * @ctrldev - pointer to device -@@ -247,59 +314,9 @@ static int instantiate_rng(struct device - - kfree(desc); - -- return ret; --} -- --/* -- * deinstantiate_rng - builds and executes a descriptor on DECO0, -- * which deinitializes the RNG block. -- * @ctrldev - pointer to device -- * @state_handle_mask - bitmask containing the instantiation status -- * for the RNG4 state handles which exist in -- * the RNG4 block: 1 if it's been instantiated -- * -- * Return: - 0 if no error occurred -- * - -ENOMEM if there isn't enough memory to allocate the descriptor -- * - -ENODEV if DECO0 couldn't be acquired -- * - -EAGAIN if an error occurred when executing the descriptor -- */ --static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask) --{ -- u32 *desc, status; -- int sh_idx, ret = 0; -- -- desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL); -- if (!desc) -- return -ENOMEM; -- -- for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) { -- /* -- * If the corresponding bit is set, then it means the state -- * handle was initialized by us, and thus it needs to be -- * deinitialized as well -- */ -- if ((1 << sh_idx) & state_handle_mask) { -- /* -- * Create the descriptor for deinstantating this state -- * handle -- */ -- build_deinstantiation_desc(desc, sh_idx); -- -- /* Try to run it through DECO0 */ -- ret = run_descriptor_deco0(ctrldev, desc, &status); -- -- if (ret || -- (status && status != JRSTA_SSRC_JUMP_HALT_CC)) { -- dev_err(ctrldev, -- "Failed to deinstantiate RNG4 SH%d\n", -- sh_idx); -- break; -- } -- dev_info(ctrldev, "Deinstantiated RNG4 SH%d\n", sh_idx); -- } -- } -- -- kfree(desc); -+ if (!ret) -+ ret = devm_add_action_or_reset(ctrldev, devm_deinstantiate_rng, -+ ctrldev); - - return ret; - } -@@ -320,13 +337,6 @@ static int caam_remove(struct platform_d - caam_qi_shutdown(ctrldev); - #endif - -- /* -- * De-initialize RNG state handles initialized by this driver. -- * In case of SoCs with Management Complex, RNG is managed by MC f/w. -- */ -- if (!ctrlpriv->mc_en && ctrlpriv->rng4_sh_init) -- deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init); -- - return 0; - } - diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0007-crypto-caam-use-devres-to-de-initialize-QI.patch b/target/linux/layerscape/patches-5.4/804-crypto-0007-crypto-caam-use-devres-to-de-initialize-QI.patch deleted file mode 100644 index f9e7940fa8..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0007-crypto-caam-use-devres-to-de-initialize-QI.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 5a359d189f9938d30046aedfc94c9cd7fe383e34 Mon Sep 17 00:00:00 2001 -From: Andrey Smirnov -Date: Tue, 22 Oct 2019 08:30:11 -0700 -Subject: [PATCH] crypto: caam - use devres to de-initialize QI -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use devres to de-initialize the QI and drop explicit de-initialization -code in caam_remove(). - -Signed-off-by: Andrey Smirnov -Reviewed-by: Horia Geantă -Cc: Chris Healy -Cc: Lucas Stach -Cc: Horia Geantă -Cc: Herbert Xu -Cc: Iuliana Prodan -Cc: linux-crypto@vger.kernel.org -Cc: linux-kernel@vger.kernel.org -Signed-off-by: Herbert Xu -(cherry picked from commit f414de2e2fffd89c8a4e5b5e06b0eba5f9d8b1eb) ---- - drivers/crypto/caam/ctrl.c | 14 +------------- - drivers/crypto/caam/intern.h | 3 --- - drivers/crypto/caam/qi.c | 8 ++++++-- - drivers/crypto/caam/qi.h | 1 - - 4 files changed, 7 insertions(+), 19 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -332,11 +332,6 @@ static int caam_remove(struct platform_d - /* Remove platform devices under the crypto node */ - of_platform_depopulate(ctrldev); - --#ifdef CONFIG_CAAM_QI -- if (ctrlpriv->qi_init) -- caam_qi_shutdown(ctrldev); --#endif -- - return 0; - } - -@@ -767,7 +762,7 @@ static int caam_probe(struct platform_de - ret = of_platform_populate(nprop, caam_match, NULL, dev); - if (ret) { - dev_err(dev, "JR platform devices creation error\n"); -- goto shutdown_qi; -+ return ret; - } - - ring = 0; -@@ -928,13 +923,6 @@ static int caam_probe(struct platform_de - caam_remove: - caam_remove(pdev); - return ret; -- --shutdown_qi: --#ifdef CONFIG_CAAM_QI -- if (ctrlpriv->qi_init) -- caam_qi_shutdown(dev); --#endif -- return ret; - } - - static struct platform_driver caam_driver = { ---- a/drivers/crypto/caam/intern.h -+++ b/drivers/crypto/caam/intern.h -@@ -81,9 +81,6 @@ struct caam_drv_private { - */ - u8 total_jobrs; /* Total Job Rings in device */ - u8 qi_present; /* Nonzero if QI present in device */ --#ifdef CONFIG_CAAM_QI -- u8 qi_init; /* Nonzero if QI has been initialized */ --#endif - u8 mc_en; /* Nonzero if MC f/w is active */ - int secvio_irq; /* Security violation interrupt number */ - int virt_en; /* Virtualization enabled in CAAM */ ---- a/drivers/crypto/caam/qi.c -+++ b/drivers/crypto/caam/qi.c -@@ -500,9 +500,10 @@ void caam_drv_ctx_rel(struct caam_drv_ct - } - EXPORT_SYMBOL(caam_drv_ctx_rel); - --void caam_qi_shutdown(struct device *qidev) -+static void caam_qi_shutdown(void *data) - { - int i; -+ struct device *qidev = data; - struct caam_qi_priv *priv = &qipriv; - const cpumask_t *cpus = qman_affine_cpus(); - -@@ -761,7 +762,10 @@ int caam_qi_init(struct platform_device - ×_congested, &caam_fops_u64_ro); - #endif - -- ctrlpriv->qi_init = 1; -+ err = devm_add_action_or_reset(qidev, caam_qi_shutdown, ctrlpriv); -+ if (err) -+ return err; -+ - dev_info(qidev, "Linux CAAM Queue I/F driver initialised\n"); - return 0; - } ---- a/drivers/crypto/caam/qi.h -+++ b/drivers/crypto/caam/qi.h -@@ -147,7 +147,6 @@ int caam_drv_ctx_update(struct caam_drv_ - void caam_drv_ctx_rel(struct caam_drv_ctx *drv_ctx); - - int caam_qi_init(struct platform_device *pdev); --void caam_qi_shutdown(struct device *dev); - - /** - * qi_cache_alloc - Allocate buffers from CAAM-QI cache diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0008-crypto-caam-use-devres-to-populate-platform-devices.patch b/target/linux/layerscape/patches-5.4/804-crypto-0008-crypto-caam-use-devres-to-populate-platform-devices.patch deleted file mode 100644 index c3a8ba2fd8..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0008-crypto-caam-use-devres-to-populate-platform-devices.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 7200bc3a88315a59e7094bf111c7816f0298923f Mon Sep 17 00:00:00 2001 -From: Andrey Smirnov -Date: Tue, 22 Oct 2019 08:30:12 -0700 -Subject: [PATCH] crypto: caam - use devres to populate platform devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use devres to de-initialize the RNG and drop explicit de-initialization -code in caam_remove(). - -Signed-off-by: Andrey Smirnov -Reviewed-by: Horia Geantă -Cc: Chris Healy -Cc: Lucas Stach -Cc: Horia Geantă -Cc: Herbert Xu -Cc: Iuliana Prodan -Cc: linux-crypto@vger.kernel.org -Cc: linux-kernel@vger.kernel.org -Signed-off-by: Herbert Xu -(cherry picked from commit 1a1c4f004444ebb962a02b7fc6d534e0f2ed9acb) ---- - drivers/crypto/caam/ctrl.c | 26 +++----------------------- - 1 file changed, 3 insertions(+), 23 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -321,20 +321,6 @@ static int instantiate_rng(struct device - return ret; - } - --static int caam_remove(struct platform_device *pdev) --{ -- struct device *ctrldev; -- struct caam_drv_private *ctrlpriv; -- -- ctrldev = &pdev->dev; -- ctrlpriv = dev_get_drvdata(ctrldev); -- -- /* Remove platform devices under the crypto node */ -- of_platform_depopulate(ctrldev); -- -- return 0; --} -- - /* - * kick_trng - sets the various parameters for enabling the initialization - * of the RNG4 block in CAAM -@@ -759,7 +745,7 @@ static int caam_probe(struct platform_de - #endif - } - -- ret = of_platform_populate(nprop, caam_match, NULL, dev); -+ ret = devm_of_platform_populate(dev); - if (ret) { - dev_err(dev, "JR platform devices creation error\n"); - return ret; -@@ -781,8 +767,7 @@ static int caam_probe(struct platform_de - /* If no QI and no rings specified, quit and go home */ - if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) { - dev_err(dev, "no queues configured, terminating\n"); -- ret = -ENOMEM; -- goto caam_remove; -+ return -ENOMEM; - } - - if (ctrlpriv->era < 10) -@@ -845,7 +830,7 @@ static int caam_probe(struct platform_de - } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX)); - if (ret) { - dev_err(dev, "failed to instantiate RNG"); -- goto caam_remove; -+ return ret; - } - /* - * Set handles init'ed by this module as the complement of the -@@ -919,10 +904,6 @@ static int caam_probe(struct platform_de - &ctrlpriv->ctl_tdsk_wrap); - #endif - return 0; -- --caam_remove: -- caam_remove(pdev); -- return ret; - } - - static struct platform_driver caam_driver = { -@@ -931,7 +912,6 @@ static struct platform_driver caam_drive - .of_match_table = caam_match, - }, - .probe = caam_probe, -- .remove = caam_remove, - }; - - module_platform_driver(caam_driver); diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0009-crypto-caam-populate-platform-devices-last.patch b/target/linux/layerscape/patches-5.4/804-crypto-0009-crypto-caam-populate-platform-devices-last.patch deleted file mode 100644 index 8ab1199e9d..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0009-crypto-caam-populate-platform-devices-last.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 6d186bceac74dd7fcabac860295cfb7b893168cd Mon Sep 17 00:00:00 2001 -From: Andrey Smirnov -Date: Tue, 22 Oct 2019 08:30:13 -0700 -Subject: [PATCH] crypto: caam - populate platform devices last -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Move the call to devm_of_platform_populate() at the end of -caam_probe(), so we won't try to add any child devices until all of -the initialization is finished successfully. - -Signed-off-by: Andrey Smirnov -Cc: Chris Healy -Cc: Lucas Stach -Cc: Horia Geantă -Cc: Herbert Xu -Cc: Iuliana Prodan -Cc: linux-crypto@vger.kernel.org -Cc: linux-kernel@vger.kernel.org -Reviewed-by: Horia Geantă -Signed-off-by: Herbert Xu -(cherry picked from commit 51d13aaf59779ff4d13f1def2c72ae102a1aad40) ---- - drivers/crypto/caam/ctrl.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -745,12 +745,6 @@ static int caam_probe(struct platform_de - #endif - } - -- ret = devm_of_platform_populate(dev); -- if (ret) { -- dev_err(dev, "JR platform devices creation error\n"); -- return ret; -- } -- - ring = 0; - for_each_available_child_of_node(nprop, np) - if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") || -@@ -903,7 +897,12 @@ static int caam_probe(struct platform_de - debugfs_create_blob("tdsk", S_IRUSR | S_IRGRP | S_IROTH, ctrlpriv->ctl, - &ctrlpriv->ctl_tdsk_wrap); - #endif -- return 0; -+ -+ ret = devm_of_platform_populate(dev); -+ if (ret) -+ dev_err(dev, "JR platform devices creation error\n"); -+ -+ return ret; - } - - static struct platform_driver caam_driver = { diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0010-MLK-9769-1-crypto-caam-jr-remove-incorrect-comment-f.patch b/target/linux/layerscape/patches-5.4/804-crypto-0010-MLK-9769-1-crypto-caam-jr-remove-incorrect-comment-f.patch deleted file mode 100644 index a9221cc0fc..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0010-MLK-9769-1-crypto-caam-jr-remove-incorrect-comment-f.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 7bf33e375e1b260d2ef3c414852a2131ce11d113 Mon Sep 17 00:00:00 2001 -From: Victoria Milhoan -Date: Wed, 29 Oct 2014 11:23:05 -0700 -Subject: [PATCH] MLK-9769-1 crypto: caam/jr - remove incorrect comment from - job ring module -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -caam_jr_register() function is no longer part of the driver since -commit 6dad41158db6 ("crypto: caam - Remove unused functions from Job Ring") - -This patch removes a comment referencing the function. - -Signed-off-by: Victoria Milhoan -Signed-off-by: Dan Douglass -Signed-off-by: Vipul Kumar -(cherry picked from commit 96c125b8962ba5bcbb625b0b162644c16fb33685) - --changed commit headline prefix --added details about commit removing caam_jr_register() - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/jr.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/drivers/crypto/caam/jr.c -+++ b/drivers/crypto/caam/jr.c -@@ -327,8 +327,7 @@ EXPORT_SYMBOL(caam_jr_free); - * caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK, - * -EBUSY if the queue is full, -EIO if it cannot map the caller's - * descriptor. -- * @dev: device of the job ring to be used. This device should have -- * been assigned prior by caam_jr_register(). -+ * @dev: struct device of the job ring to be used - * @desc: points to a job descriptor that execute our request. All - * descriptors (and all referenced data) must be in a DMAable - * region, and all data references must be physical addresses diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0011-MLK-20204-crypto-caam-remove-deadcode-on-32-bit-plat.patch b/target/linux/layerscape/patches-5.4/804-crypto-0011-MLK-20204-crypto-caam-remove-deadcode-on-32-bit-plat.patch deleted file mode 100644 index 1adf63456d..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0011-MLK-20204-crypto-caam-remove-deadcode-on-32-bit-plat.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 4269eb560ac34c5974559fe256811c1ac5d764ed Mon Sep 17 00:00:00 2001 -From: Franck LENORMAND -Date: Fri, 23 Nov 2018 16:06:45 +0100 -Subject: [PATCH] MLK-20204 crypto: caam - remove deadcode on 32-bit platforms -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When building on a platform with a 32bit DMA address, taking the -upper 32 bits makes no sense. - -Signed-off-by: Franck LENORMAND -(cherry picked from commit d3346aaa3fbfaf9b7f827d8554f076e3fc82c35b) - --replace ifdeffery with IS_ENABLED() macro --change commit headline prefix - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/regs.h | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - ---- a/drivers/crypto/caam/regs.h -+++ b/drivers/crypto/caam/regs.h -@@ -173,9 +173,14 @@ static inline u64 rd_reg64(void __iomem - - static inline u64 cpu_to_caam_dma64(dma_addr_t value) - { -- if (caam_imx) -- return (((u64)cpu_to_caam32(lower_32_bits(value)) << 32) | -- (u64)cpu_to_caam32(upper_32_bits(value))); -+ if (caam_imx) { -+ u64 ret_val = (u64)cpu_to_caam32(lower_32_bits(value)) << 32; -+ -+ if (IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT)) -+ ret_val |= (u64)cpu_to_caam32(upper_32_bits(value)); -+ -+ return ret_val; -+ } - - return cpu_to_caam64(value); - } diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0012-MLK-19053-crypto-caam-RNG4-TRNG-errata.patch b/target/linux/layerscape/patches-5.4/804-crypto-0012-MLK-19053-crypto-caam-RNG4-TRNG-errata.patch deleted file mode 100644 index 761652ab71..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0012-MLK-19053-crypto-caam-RNG4-TRNG-errata.patch +++ /dev/null @@ -1,63 +0,0 @@ -From e1a89cdf6fa6b04806eb24b939738bb89ab62914 Mon Sep 17 00:00:00 2001 -From: Aymen Sghaier -Date: Thu, 13 Sep 2018 16:41:03 +0200 -Subject: [PATCH] MLK-19053 crypto: caam - RNG4 TRNG errata -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - - The TRNG as used in RNG4, used in CAAM has a documentation issue. The -effect is that it is possible that the entropy used to instantiate the -DRBG may be old entropy, rather than newly generated entropy. There is -proper programming guidance, but it is not in the documentation. - -Signed-off-by: Aymen Sghaier -Signed-off-by: Vipul Kumar -(cherry picked from commit ea2b30c8171acf7624e3d44276737c3878ca900d) - --ported to RNG initialization in ctrl.c --changed commit headline - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/ctrl.c | 9 +++++++-- - drivers/crypto/caam/regs.h | 3 ++- - 2 files changed, 9 insertions(+), 3 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -339,7 +339,11 @@ static void kick_trng(struct platform_de - r4tst = &ctrl->r4tst[0]; - - /* put RNG4 into program mode */ -- clrsetbits_32(&r4tst->rtmctl, 0, RTMCTL_PRGM); -+ /* Setting both RTMCTL:PRGM and RTMCTL:TRNG_ACC causes TRNG to -+ * properly invalidate the entropy in the entropy register and -+ * force re-generation. -+ */ -+ clrsetbits_32(&r4tst->rtmctl, 0, RTMCTL_PRGM | RTMCTL_ACC); - - /* - * Performance-wise, it does not make sense to -@@ -369,7 +373,8 @@ start_rng: - * select raw sampling in both entropy shifter - * and statistical checker; ; put RNG4 into run mode - */ -- clrsetbits_32(&r4tst->rtmctl, RTMCTL_PRGM, RTMCTL_SAMP_MODE_RAW_ES_SC); -+ clrsetbits_32(&r4tst->rtmctl, RTMCTL_PRGM | RTMCTL_ACC, -+ RTMCTL_SAMP_MODE_RAW_ES_SC); - } - - static int caam_get_era_from_hw(struct caam_ctrl __iomem *ctrl) ---- a/drivers/crypto/caam/regs.h -+++ b/drivers/crypto/caam/regs.h -@@ -495,7 +495,8 @@ struct rngtst { - - /* RNG4 TRNG test registers */ - struct rng4tst { --#define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */ -+#define RTMCTL_ACC BIT(5) /* TRNG access mode */ -+#define RTMCTL_PRGM BIT(16) /* 1 -> program mode, 0 -> run mode */ - #define RTMCTL_SAMP_MODE_VON_NEUMANN_ES_SC 0 /* use von Neumann data in - both entropy shifter and - statistical checker */ diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0013-MLK-9769-9-crypto-caam-adjust-RNG-timing-to-support-.patch b/target/linux/layerscape/patches-5.4/804-crypto-0013-MLK-9769-9-crypto-caam-adjust-RNG-timing-to-support-.patch deleted file mode 100644 index 5c30e1d287..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0013-MLK-9769-9-crypto-caam-adjust-RNG-timing-to-support-.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 5bc830089553a445952d69a73e0a9f5fdf9d0f19 Mon Sep 17 00:00:00 2001 -From: Victoria Milhoan -Date: Wed, 12 Nov 2014 09:58:24 -0700 -Subject: [PATCH] MLK-9769-9 crypto: caam - adjust RNG timing to support more - devices -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adjust RNG timing parameters to support more i.MX6 devices. - -Signed-off-by: Victoria Milhoan -Signed-off-by: Dan Douglass -Signed-off-by: Vipul Kumar -(cherry picked from commit 57eabb638430ec68490d192738640b95a3507b1d) - -Changed commit headline prefix. - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/ctrl.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -364,8 +364,8 @@ static void kick_trng(struct platform_de - wr_reg32(&r4tst->rtsdctl, val); - /* min. freq. count, equal to 1/4 of the entropy sample length */ - wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2); -- /* disable maximum frequency count */ -- wr_reg32(&r4tst->rtfrqmax, RTFRQMAX_DISABLE); -+ /* max. freq. count, equal to 16 times the entropy sample length */ -+ wr_reg32(&r4tst->rtfrqmax, ent_delay << 4); - /* read the control register */ - val = rd_reg32(&r4tst->rtmctl); - start_rng: diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0014-MLK-9769-8-crypto-caam-add-a-test-for-the-RNG.patch b/target/linux/layerscape/patches-5.4/804-crypto-0014-MLK-9769-8-crypto-caam-add-a-test-for-the-RNG.patch deleted file mode 100644 index 3a9174557e..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0014-MLK-9769-8-crypto-caam-add-a-test-for-the-RNG.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 387a26c56933fbfd0fa211ad5347d48d08695ea0 Mon Sep 17 00:00:00 2001 -From: "Victoria Milhoan (b42089)" -Date: Fri, 17 Oct 2014 16:30:56 -0700 -Subject: [PATCH] MLK-9769-8 crypto: caam - add a test for the RNG -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Freescale's CAAM includes a Random Number Generator. This change adds -a kernel configuration option to test the RNG's capabilities via the -hw_random framework. - -Signed-off-by: Victoria Milhoan -Signed-off-by: Dan Douglass -Signed-off-by: Vipul Kumar -(cherry picked from commit 05fba1bb857d5329fdcf79e736643fce0944a86d) - --fixed compilation warning: -drivers/crypto/caam/caamrng.c:271:2: warning: format '%d' expects argument of type 'int', but argument 2 has type 'size_t' [-Wformat=] - --changed commit headline - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/Kconfig | 8 ++++++++ - drivers/crypto/caam/caamrng.c | 47 +++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 55 insertions(+) - ---- a/drivers/crypto/caam/Kconfig -+++ b/drivers/crypto/caam/Kconfig -@@ -148,6 +148,14 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API - Selecting this will register the SEC4 hardware rng to - the hw_random API for suppying the kernel entropy pool. - -+config CRYPTO_DEV_FSL_CAAM_RNG_TEST -+ bool "Test caam rng" -+ depends on CRYPTO_DEV_FSL_CAAM_RNG_API -+ help -+ Selecting this will enable a self-test to run for the -+ caam RNG. This test is several minutes long and executes -+ just before the RNG is registered with the hw_random API. -+ - endif # CRYPTO_DEV_FSL_CAAM_JR - - endif # CRYPTO_DEV_FSL_CAAM ---- a/drivers/crypto/caam/caamrng.c -+++ b/drivers/crypto/caam/caamrng.c -@@ -258,6 +258,49 @@ static void caam_cleanup(struct hwrng *r - rng_unmap_ctx(rng_ctx); - } - -+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST -+static inline void test_len(struct hwrng *rng, size_t len, bool wait) -+{ -+ u8 *buf; -+ int real_len; -+ -+ buf = kzalloc(sizeof(u8) * len, GFP_KERNEL); -+ real_len = rng->read(rng, buf, len, wait); -+ if (real_len == 0 && wait) -+ pr_err("WAITING FAILED\n"); -+ pr_info("wanted %zu bytes, got %d\n", len, real_len); -+ print_hex_dump(KERN_INFO, "random bytes@: ", DUMP_PREFIX_ADDRESS, -+ 16, 4, buf, real_len, 1); -+ kfree(buf); -+} -+ -+static inline void test_mode_once(struct hwrng *rng, bool wait) -+{ -+#define TEST_CHUNK (RN_BUF_SIZE / 4) -+ -+ test_len(rng, TEST_CHUNK, wait); -+ test_len(rng, RN_BUF_SIZE * 2, wait); -+ test_len(rng, RN_BUF_SIZE * 2 - TEST_CHUNK, wait); -+} -+ -+static inline void test_mode(struct hwrng *rng, bool wait) -+{ -+#define TEST_PASS 1 -+ int i; -+ -+ for (i = 0; i < TEST_PASS; i++) -+ test_mode_once(rng, wait); -+} -+ -+static void self_test(struct hwrng *rng) -+{ -+ pr_info("testing without waiting\n"); -+ test_mode(rng, false); -+ pr_info("testing with waiting\n"); -+ test_mode(rng, true); -+} -+#endif -+ - static int caam_init_buf(struct caam_rng_ctx *ctx, int buf_id) - { - struct buf_data *bd = &ctx->bufs[buf_id]; -@@ -342,6 +385,10 @@ int caam_rng_init(struct device *ctrldev - if (err) - goto free_rng_ctx; - -+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST -+ self_test(&caam_rng); -+#endif -+ - dev_info(dev, "registering rng-caam\n"); - - err = hwrng_register(&caam_rng); diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0015-MLKU-123-1-crypto-caam-add-support-for-i.mx8mm-mn.patch b/target/linux/layerscape/patches-5.4/804-crypto-0015-MLKU-123-1-crypto-caam-add-support-for-i.mx8mm-mn.patch deleted file mode 100644 index def910aaab..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0015-MLKU-123-1-crypto-caam-add-support-for-i.mx8mm-mn.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 866aab825ad10675b1e98004aec19127ec16b2b3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Mon, 23 Sep 2019 14:28:42 +0300 -Subject: [PATCH] MLKU-123-1 crypto: caam - add support for i.mx8mm, mn -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -TODO: - -1. clarify logic wrt. virtualization and DECORSR - see e-mail thread: -"Register-based interface - DECORSR with virtualization disabled" - -2. check whether the clocks are identical for all mScale parts, -and if they do use a single "i.MX8M*" entry in clocks array. - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/ctrl.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -99,10 +99,12 @@ static inline int run_descriptor_deco0(s - - if (ctrlpriv->virt_en == 1 || - /* -- * Apparently on i.MX8MQ it doesn't matter if virt_en == 1 -+ * Apparently on i.MX8MQ, 8MM, 8MN it doesn't matter if virt_en == 1 - * and the following steps should be performed regardless - */ -- of_machine_is_compatible("fsl,imx8mq")) { -+ of_machine_is_compatible("fsl,imx8mq") || -+ of_machine_is_compatible("fsl,imx8mm") || -+ of_machine_is_compatible("fsl,imx8mn")) { - clrsetbits_32(&ctrl->deco_rsr, 0, DECORSR_JR0); - - while (!(rd_reg32(&ctrl->deco_rsr) & DECORSR_VALID) && -@@ -514,6 +516,8 @@ static const struct soc_device_attribute - { .soc_id = "i.MX6*", .data = &caam_imx6_data }, - { .soc_id = "i.MX7*", .data = &caam_imx7_data }, - { .soc_id = "i.MX8MQ", .data = &caam_imx7_data }, -+ { .soc_id = "i.MX8MM", .data = &caam_imx7_data }, -+ { .soc_id = "i.MX8MN", .data = &caam_imx7_data }, - { .family = "Freescale i.MX" }, - { /* sentinel */ } - }; diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0016-MLKU-114-1-crypto-caam-reduce-page-0-regs-access-to-.patch b/target/linux/layerscape/patches-5.4/804-crypto-0016-MLKU-114-1-crypto-caam-reduce-page-0-regs-access-to-.patch deleted file mode 100644 index 106255449c..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0016-MLKU-114-1-crypto-caam-reduce-page-0-regs-access-to-.patch +++ /dev/null @@ -1,294 +0,0 @@ -From 3d21ebe0b870b9b65b3be0c1473e7148256c4d16 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Tue, 24 Sep 2019 14:56:48 +0300 -Subject: [PATCH] MLKU-114-1 crypto: caam - reduce page 0 regs access to - minimum -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -TODO: - -1. if of_property_read_u32_index(,,index=0,) is to be used, -DT bindings (fsl-sec4.txt) should be updated to mandate for --checked that all existing DTs are configured like this --this might create problems in the future, if DTs are needed where -JR DT nodes would exist without the controller DT node -(directly on simple bus etc.) - -2. MCFGR (ctrl->mcr) -How to determine caam_ptr_sz if MCFGR is not accesible? - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/caamalg.c | 21 ++++++------ - drivers/crypto/caam/caamhash.c | 8 +++-- - drivers/crypto/caam/caampkc.c | 4 +-- - drivers/crypto/caam/caamrng.c | 4 +-- - drivers/crypto/caam/ctrl.c | 78 ++++++++++++++++++++++++++---------------- - 5 files changed, 68 insertions(+), 47 deletions(-) - ---- a/drivers/crypto/caam/caamalg.c -+++ b/drivers/crypto/caam/caamalg.c -@@ -3520,13 +3520,14 @@ int caam_algapi_init(struct device *ctrl - * First, detect presence and attributes of DES, AES, and MD blocks. - */ - if (priv->era < 10) { -+ struct caam_perfmon __iomem *perfmon = &priv->jr[0]->perfmon; - u32 cha_vid, cha_inst, aes_rn; - -- cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls); -+ cha_vid = rd_reg32(&perfmon->cha_id_ls); - aes_vid = cha_vid & CHA_ID_LS_AES_MASK; - md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; - -- cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls); -+ cha_inst = rd_reg32(&perfmon->cha_num_ls); - des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> - CHA_ID_LS_DES_SHIFT; - aes_inst = cha_inst & CHA_ID_LS_AES_MASK; -@@ -3534,23 +3535,23 @@ int caam_algapi_init(struct device *ctrl - ccha_inst = 0; - ptha_inst = 0; - -- aes_rn = rd_reg32(&priv->ctrl->perfmon.cha_rev_ls) & -- CHA_ID_LS_AES_MASK; -+ aes_rn = rd_reg32(&perfmon->cha_rev_ls) & CHA_ID_LS_AES_MASK; - gcm_support = !(aes_vid == CHA_VER_VID_AES_LP && aes_rn < 8); - } else { -+ struct version_regs __iomem *vreg = &priv->jr[0]->vreg; - u32 aesa, mdha; - -- aesa = rd_reg32(&priv->ctrl->vreg.aesa); -- mdha = rd_reg32(&priv->ctrl->vreg.mdha); -+ aesa = rd_reg32(&vreg->aesa); -+ mdha = rd_reg32(&vreg->mdha); - - aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT; - md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT; - -- des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK; -+ des_inst = rd_reg32(&vreg->desa) & CHA_VER_NUM_MASK; - aes_inst = aesa & CHA_VER_NUM_MASK; - md_inst = mdha & CHA_VER_NUM_MASK; -- ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK; -- ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK; -+ ccha_inst = rd_reg32(&vreg->ccha) & CHA_VER_NUM_MASK; -+ ptha_inst = rd_reg32(&vreg->ptha) & CHA_VER_NUM_MASK; - - gcm_support = aesa & CHA_VER_MISC_AES_GCM; - } ---- a/drivers/crypto/caam/caamhash.c -+++ b/drivers/crypto/caam/caamhash.c -@@ -1991,12 +1991,14 @@ int caam_algapi_hash_init(struct device - * presence and attributes of MD block. - */ - if (priv->era < 10) { -- md_vid = (rd_reg32(&priv->ctrl->perfmon.cha_id_ls) & -+ struct caam_perfmon __iomem *perfmon = &priv->jr[0]->perfmon; -+ -+ md_vid = (rd_reg32(&perfmon->cha_id_ls) & - CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; -- md_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & -+ md_inst = (rd_reg32(&perfmon->cha_num_ls) & - CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; - } else { -- u32 mdha = rd_reg32(&priv->ctrl->vreg.mdha); -+ u32 mdha = rd_reg32(&priv->jr[0]->vreg.mdha); - - md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT; - md_inst = mdha & CHA_VER_NUM_MASK; ---- a/drivers/crypto/caam/caampkc.c -+++ b/drivers/crypto/caam/caampkc.c -@@ -1099,10 +1099,10 @@ int caam_pkc_init(struct device *ctrldev - - /* Determine public key hardware accelerator presence. */ - if (priv->era < 10) { -- pk_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & -+ pk_inst = (rd_reg32(&priv->jr[0]->perfmon.cha_num_ls) & - CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT; - } else { -- pkha = rd_reg32(&priv->ctrl->vreg.pkha); -+ pkha = rd_reg32(&priv->jr[0]->vreg.pkha); - pk_inst = pkha & CHA_VER_NUM_MASK; - - /* ---- a/drivers/crypto/caam/caamrng.c -+++ b/drivers/crypto/caam/caamrng.c -@@ -363,10 +363,10 @@ int caam_rng_init(struct device *ctrldev - - /* Check for an instantiated RNG before registration */ - if (priv->era < 10) -- rng_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & -+ rng_inst = (rd_reg32(&priv->jr[0]->perfmon.cha_num_ls) & - CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT; - else -- rng_inst = rd_reg32(&priv->ctrl->vreg.rng) & CHA_VER_NUM_MASK; -+ rng_inst = rd_reg32(&priv->jr[0]->vreg.rng) & CHA_VER_NUM_MASK; - - if (!rng_inst) - return 0; ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -379,7 +379,7 @@ start_rng: - RTMCTL_SAMP_MODE_RAW_ES_SC); - } - --static int caam_get_era_from_hw(struct caam_ctrl __iomem *ctrl) -+static int caam_get_era_from_hw(struct caam_perfmon __iomem *perfmon) - { - static const struct { - u16 ip_id; -@@ -405,12 +405,12 @@ static int caam_get_era_from_hw(struct c - u16 ip_id; - int i; - -- ccbvid = rd_reg32(&ctrl->perfmon.ccb_id); -+ ccbvid = rd_reg32(&perfmon->ccb_id); - era = (ccbvid & CCBVID_ERA_MASK) >> CCBVID_ERA_SHIFT; - if (era) /* This is '0' prior to CAAM ERA-6 */ - return era; - -- id_ms = rd_reg32(&ctrl->perfmon.caam_id_ms); -+ id_ms = rd_reg32(&perfmon->caam_id_ms); - ip_id = (id_ms & SECVID_MS_IPID_MASK) >> SECVID_MS_IPID_SHIFT; - maj_rev = (id_ms & SECVID_MS_MAJ_REV_MASK) >> SECVID_MS_MAJ_REV_SHIFT; - -@@ -428,7 +428,7 @@ static int caam_get_era_from_hw(struct c - * In case this property is not passed an attempt to retrieve the CAAM - * era via register reads will be made. - **/ --static int caam_get_era(struct caam_ctrl __iomem *ctrl) -+static int caam_get_era(struct caam_perfmon __iomem *perfmon) - { - struct device_node *caam_node; - int ret; -@@ -441,7 +441,7 @@ static int caam_get_era(struct caam_ctrl - if (!ret) - return prop; - else -- return caam_get_era_from_hw(ctrl); -+ return caam_get_era_from_hw(perfmon); - } - - /* -@@ -575,8 +575,8 @@ static int caam_probe(struct platform_de - struct device_node *nprop, *np; - struct caam_ctrl __iomem *ctrl; - struct caam_drv_private *ctrlpriv; -+ struct caam_perfmon __iomem *perfmon; - #ifdef CONFIG_DEBUG_FS -- struct caam_perfmon *perfmon; - struct dentry *dfs_root; - #endif - u32 scfgr, comp_params; -@@ -616,9 +616,36 @@ static int caam_probe(struct platform_de - return ret; - } - -- caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) & -+ ring = 0; -+ for_each_available_child_of_node(nprop, np) -+ if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") || -+ of_device_is_compatible(np, "fsl,sec4.0-job-ring")) { -+ u32 reg; -+ -+ if (of_property_read_u32_index(np, "reg", 0, ®)) { -+ dev_err(dev, "%s read reg property error\n", -+ np->full_name); -+ continue; -+ } -+ -+ ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *) -+ ((__force uint8_t *)ctrl + reg); -+ -+ ctrlpriv->total_jobrs++; -+ ring++; -+ } -+ -+ /* -+ * Wherever possible, instead of accessing registers from the global page, -+ * use the alias registers in the first (cf. DT nodes order) -+ * job ring's page. -+ */ -+ perfmon = ring ? (struct caam_perfmon *)&ctrlpriv->jr[0]->perfmon : -+ (struct caam_perfmon *)&ctrl->perfmon; -+ -+ caam_little_end = !(bool)(rd_reg32(&perfmon->status) & - (CSTA_PLEND | CSTA_ALT_PLEND)); -- comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ms); -+ comp_params = rd_reg32(&perfmon->comp_parms_ms); - if (comp_params & CTPR_MS_PS && rd_reg32(&ctrl->mcr) & MCFGR_LONG_PTR) - caam_ptr_sz = sizeof(u64); - else -@@ -718,7 +745,7 @@ static int caam_probe(struct platform_de - return ret; - } - -- ctrlpriv->era = caam_get_era(ctrl); -+ ctrlpriv->era = caam_get_era(perfmon); - ctrlpriv->domain = iommu_get_domain_for_dev(dev); - - #ifdef CONFIG_DEBUG_FS -@@ -727,8 +754,6 @@ static int caam_probe(struct platform_de - * "caam" and nprop->full_name. The OF name isn't distinctive, - * but does separate instances - */ -- perfmon = (struct caam_perfmon __force *)&ctrl->perfmon; -- - dfs_root = debugfs_create_dir(dev_name(dev), NULL); - ret = devm_add_action_or_reset(dev, caam_remove_debugfs, dfs_root); - if (ret) -@@ -754,31 +779,24 @@ static int caam_probe(struct platform_de - #endif - } - -- ring = 0; -- for_each_available_child_of_node(nprop, np) -- if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") || -- of_device_is_compatible(np, "fsl,sec4.0-job-ring")) { -- ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *) -- ((__force uint8_t *)ctrl + -- (ring + JR_BLOCK_NUMBER) * -- BLOCK_OFFSET -- ); -- ctrlpriv->total_jobrs++; -- ring++; -- } -- - /* If no QI and no rings specified, quit and go home */ - if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) { - dev_err(dev, "no queues configured, terminating\n"); - return -ENOMEM; - } - -- if (ctrlpriv->era < 10) -- rng_vid = (rd_reg32(&ctrl->perfmon.cha_id_ls) & -+ if (ctrlpriv->era < 10) { -+ rng_vid = (rd_reg32(&perfmon->cha_id_ls) & - CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT; -- else -- rng_vid = (rd_reg32(&ctrl->vreg.rng) & CHA_VER_VID_MASK) >> -+ } else { -+ struct version_regs __iomem *vreg; -+ -+ vreg = ring ? (struct version_regs *)&ctrlpriv->jr[0]->vreg : -+ (struct version_regs *)&ctrl->vreg; -+ -+ rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >> - CHA_VER_VID_SHIFT; -+ } - - /* - * If SEC has RNG version >= 4 and RNG state handle has not been -@@ -847,8 +865,8 @@ static int caam_probe(struct platform_de - - /* NOTE: RTIC detection ought to go here, around Si time */ - -- caam_id = (u64)rd_reg32(&ctrl->perfmon.caam_id_ms) << 32 | -- (u64)rd_reg32(&ctrl->perfmon.caam_id_ls); -+ caam_id = (u64)rd_reg32(&perfmon->caam_id_ms) << 32 | -+ (u64)rd_reg32(&perfmon->caam_id_ls); - - /* Report "alive" for developer to see */ - dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id, diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0017-MLKU-114-2-crypto-caam-SCU-firmware-support.patch b/target/linux/layerscape/patches-5.4/804-crypto-0017-MLKU-114-2-crypto-caam-SCU-firmware-support.patch deleted file mode 100644 index 9ff30d82a5..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0017-MLKU-114-2-crypto-caam-SCU-firmware-support.patch +++ /dev/null @@ -1,137 +0,0 @@ -From b752c8ed4ab83d47a585c363056d64fb978ef481 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Fri, 27 Sep 2019 20:05:26 +0300 -Subject: [PATCH] MLKU-114-2 crypto: caam - SCU firmware support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some i.MX8 processors, e.g. i.MX8QM (QM, QP), i.MX8QX (QXP, DX) have a -System Controller Firmware (SCFW) running on a dedicated Cortex-M core -that provides power, clock, and resource management. - -caam driver needs to be aware of SCU f/w presence, since some things -are done differently: - -1. clocks are under SCU f/w control and are turned on automatically - -2. there is no access to controller's register page (note however that -some registers are aliased in job rings' register pages) - -It's worth mentioning that due to this, MCFGR[PS] cannot be read -and driver assumes MCFGR[PS] = b'0 - engine using 32-bit address pointers. -This is in sync with the limitation imposed by the -SECO (Security Controller) ROM and f/w running on a dedicated Cortex-M. - -3. as a consequence of "2.", part of the initialization is moved in -other f/w (SCU, TF-A etc.), e.g. RNG initialization - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/ctrl.c | 28 ++++++++++++++++++++++++++-- - drivers/crypto/caam/intern.h | 1 + - 2 files changed, 27 insertions(+), 2 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -596,6 +596,17 @@ static int caam_probe(struct platform_de - caam_imx = (bool)imx_soc_match; - - if (imx_soc_match) { -+ np = of_find_compatible_node(NULL, NULL, "fsl,imx-scu"); -+ ctrlpriv->scu_en = !!np; -+ of_node_put(np); -+ -+ /* -+ * CAAM clocks cannot be controlled from kernel. -+ * They are automatically turned on by SCU f/w. -+ */ -+ if (ctrlpriv->scu_en) -+ goto iomap_ctrl; -+ - if (!imx_soc_match->data) { - dev_err(dev, "No clock data provided for i.MX SoC"); - return -EINVAL; -@@ -606,7 +617,7 @@ static int caam_probe(struct platform_de - return ret; - } - -- -+iomap_ctrl: - /* Get configuration properties from device tree */ - /* First, get register page */ - ctrl = devm_of_iomap(dev, nprop, 0, NULL); -@@ -646,7 +657,8 @@ static int caam_probe(struct platform_de - caam_little_end = !(bool)(rd_reg32(&perfmon->status) & - (CSTA_PLEND | CSTA_ALT_PLEND)); - comp_params = rd_reg32(&perfmon->comp_parms_ms); -- if (comp_params & CTPR_MS_PS && rd_reg32(&ctrl->mcr) & MCFGR_LONG_PTR) -+ if (!ctrlpriv->scu_en && comp_params & CTPR_MS_PS && -+ rd_reg32(&ctrl->mcr) & MCFGR_LONG_PTR) - caam_ptr_sz = sizeof(u64); - else - caam_ptr_sz = sizeof(u32); -@@ -696,6 +708,9 @@ static int caam_probe(struct platform_de - /* Get the IRQ of the controller (for security violations only) */ - ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0); - -+ if (ctrlpriv->scu_en) -+ goto set_dma_mask; -+ - /* - * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, - * long pointers in master configuration register. -@@ -739,6 +754,7 @@ static int caam_probe(struct platform_de - JRSTART_JR1_START | JRSTART_JR2_START | - JRSTART_JR3_START); - -+set_dma_mask: - ret = dma_set_mask_and_coherent(dev, caam_get_dma_mask(dev)); - if (ret) { - dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret); -@@ -785,6 +801,9 @@ static int caam_probe(struct platform_de - return -ENOMEM; - } - -+ if (ctrlpriv->scu_en) -+ goto report_live; -+ - if (ctrlpriv->era < 10) { - rng_vid = (rd_reg32(&perfmon->cha_id_ls) & - CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT; -@@ -865,6 +884,7 @@ static int caam_probe(struct platform_de - - /* NOTE: RTIC detection ought to go here, around Si time */ - -+report_live: - caam_id = (u64)rd_reg32(&perfmon->caam_id_ms) << 32 | - (u64)rd_reg32(&perfmon->caam_id_ls); - -@@ -908,6 +928,9 @@ static int caam_probe(struct platform_de - ctrlpriv->ctl, &perfmon->status, - &caam_fops_u32_ro); - -+ if (ctrlpriv->scu_en) -+ goto probe_jrs; -+ - /* Internal covering keys (useful in non-secure mode only) */ - ctrlpriv->ctl_kek_wrap.data = (__force void *)&ctrlpriv->ctrl->kek[0]; - ctrlpriv->ctl_kek_wrap.size = KEK_KEY_SIZE * sizeof(u32); -@@ -925,6 +948,7 @@ static int caam_probe(struct platform_de - &ctrlpriv->ctl_tdsk_wrap); - #endif - -+probe_jrs: - ret = devm_of_platform_populate(dev); - if (ret) - dev_err(dev, "JR platform devices creation error\n"); ---- a/drivers/crypto/caam/intern.h -+++ b/drivers/crypto/caam/intern.h -@@ -82,6 +82,7 @@ struct caam_drv_private { - u8 total_jobrs; /* Total Job Rings in device */ - u8 qi_present; /* Nonzero if QI present in device */ - u8 mc_en; /* Nonzero if MC f/w is active */ -+ u8 scu_en; /* Nonzero if SCU f/w is active */ - int secvio_irq; /* Security violation interrupt number */ - int virt_en; /* Virtualization enabled in CAAM */ - int era; /* CAAM Era (internal HW revision) */ diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0018-MLKU-114-3-crypto-caam-OP-TEE-firmware-support.patch b/target/linux/layerscape/patches-5.4/804-crypto-0018-MLKU-114-3-crypto-caam-OP-TEE-firmware-support.patch deleted file mode 100644 index 7e71fdc955..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0018-MLKU-114-3-crypto-caam-OP-TEE-firmware-support.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 8a0bf079f870379a1e392819ac1116d74500ec01 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Fri, 4 Oct 2019 15:07:41 +0300 -Subject: [PATCH] MLKU-114-3 crypto: caam - OP-TEE firmware support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -caam driver needs to be aware of OP-TEE f/w presence, since some things -are done differently: - -1. there is no access to controller's register page (note however that -some registers are aliased in job rings' register pages) - -It's worth mentioning that due to this, MCFGR[PS] cannot be read -and driver assumes MCFGR[PS] = b'0 - engine using 32-bit address pointers. - -This is in sync with the fact that: --all i.MX SoCs currently use MCFGR[PS] = b'0 --only i.MX OP-TEE use cases don't allow access to controller register page - -Note: When DN OP-TEE will start enforcing the same policy, -this solution will stop working and information about caam configuration -will have to deduced in some other way. - -2. as a consequence of "1.", part of the initialization is moved in -other f/w (TF-A etc.), e.g. RNG initialization - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/ctrl.c | 22 ++++++++++++++++++---- - drivers/crypto/caam/intern.h | 1 + - 2 files changed, 19 insertions(+), 4 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -583,6 +583,7 @@ static int caam_probe(struct platform_de - u8 rng_vid; - int pg_size; - int BLOCK_OFFSET = 0; -+ bool reg_access = true; - - ctrlpriv = devm_kzalloc(&pdev->dev, sizeof(*ctrlpriv), GFP_KERNEL); - if (!ctrlpriv) -@@ -600,6 +601,8 @@ static int caam_probe(struct platform_de - ctrlpriv->scu_en = !!np; - of_node_put(np); - -+ reg_access = !ctrlpriv->scu_en; -+ - /* - * CAAM clocks cannot be controlled from kernel. - * They are automatically turned on by SCU f/w. -@@ -607,6 +610,17 @@ static int caam_probe(struct platform_de - if (ctrlpriv->scu_en) - goto iomap_ctrl; - -+ /* -+ * Until Layerscape and i.MX OP-TEE get in sync, -+ * only i.MX OP-TEE use cases disallow access to -+ * caam page 0 (controller) registers. -+ */ -+ np = of_find_compatible_node(NULL, NULL, "linaro,optee-tz"); -+ ctrlpriv->optee_en = !!np; -+ of_node_put(np); -+ -+ reg_access = reg_access && !ctrlpriv->optee_en; -+ - if (!imx_soc_match->data) { - dev_err(dev, "No clock data provided for i.MX SoC"); - return -EINVAL; -@@ -657,7 +671,7 @@ iomap_ctrl: - caam_little_end = !(bool)(rd_reg32(&perfmon->status) & - (CSTA_PLEND | CSTA_ALT_PLEND)); - comp_params = rd_reg32(&perfmon->comp_parms_ms); -- if (!ctrlpriv->scu_en && comp_params & CTPR_MS_PS && -+ if (reg_access && comp_params & CTPR_MS_PS && - rd_reg32(&ctrl->mcr) & MCFGR_LONG_PTR) - caam_ptr_sz = sizeof(u64); - else -@@ -708,7 +722,7 @@ iomap_ctrl: - /* Get the IRQ of the controller (for security violations only) */ - ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0); - -- if (ctrlpriv->scu_en) -+ if (!reg_access) - goto set_dma_mask; - - /* -@@ -801,7 +815,7 @@ set_dma_mask: - return -ENOMEM; - } - -- if (ctrlpriv->scu_en) -+ if (!reg_access) - goto report_live; - - if (ctrlpriv->era < 10) { -@@ -928,7 +942,7 @@ report_live: - ctrlpriv->ctl, &perfmon->status, - &caam_fops_u32_ro); - -- if (ctrlpriv->scu_en) -+ if (!reg_access) - goto probe_jrs; - - /* Internal covering keys (useful in non-secure mode only) */ ---- a/drivers/crypto/caam/intern.h -+++ b/drivers/crypto/caam/intern.h -@@ -83,6 +83,7 @@ struct caam_drv_private { - u8 qi_present; /* Nonzero if QI present in device */ - u8 mc_en; /* Nonzero if MC f/w is active */ - u8 scu_en; /* Nonzero if SCU f/w is active */ -++ u8 optee_en; /* Nonzero if OP-TEE f/w is active */ - int secvio_irq; /* Security violation interrupt number */ - int virt_en; /* Virtualization enabled in CAAM */ - int era; /* CAAM Era (internal HW revision) */ diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0019-MLKU-38-3-crypto-caam-add-SNVS-SECVIO-support.patch b/target/linux/layerscape/patches-5.4/804-crypto-0019-MLKU-38-3-crypto-caam-add-SNVS-SECVIO-support.patch deleted file mode 100644 index fc48884cd1..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0019-MLKU-38-3-crypto-caam-add-SNVS-SECVIO-support.patch +++ /dev/null @@ -1,784 +0,0 @@ -From 03ec635be0eb1c1b63b1f631938d41b379dad637 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Mon, 30 Sep 2019 00:22:09 +0300 -Subject: [PATCH] MLKU-38-3 crypto: caam - add SNVS / SECVIO support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is a squash of the following i.MX BSP commits -(rel_imx_4.19.35_1.1.0_rc2) - -1. 8f6a17b41917 ("ENGR00289885 [iMX6Q] Add Secure Memory and SECVIO support.") -2. 8433c811e97a ("MLK-9710-18 snvs - make SECVIO module device tree correct") -3. 35bbc34e996b ("MLK-9769-23 Replace SECVIO of_irq_to_resource() with irq_of_parse_and_map()") -4. 3ac6edcd92d4 ("MLK-11360-01 crypto: caam_snvs: add snvs clock management") -5. 9d9ca7a03e3b ("MLK-11922 i.mx6: Linux 3.14.28 CAAM & SNVS enabled by default. JTAG, DS-5 attachment causes exceptions") -6. fcdaabf1bba2 ("MLK-17412-01: Fix secvio driver to have same driver name as DTS") - -Signed-off-by: Dan Douglass -Signed-off-by: Victoria Milhoan -Signed-off-by: Steve Cornelius -Signed-off-by: Fugang Duan -Signed-off-by: Franck LENORMAND - -that have been reworked: - -1. --make SM depend on JR --enable SM, SECVIO only on i.MX SoCs --fix resource leak - add off_node_put() where needed - -Split commit in three: -- SNVS/SECVIO driver -- Secure Memory driver -- DT changes - -3. -JR changes dropped - no longer needed, already upstream in -commit 549077d7d86a1 ("crypto: caam - check irq_of_parse_and_map for errors") - -4. -Split the patch in two: --DT bindings changes --driver changes - -5. -Fixed conflicts in imx7d.dtsi - added caam_sm and irq_sec_vio nodes. - -Split commit in 3: --SECVIO/SNVS driver changes --SECVIO/SNVS DT changes --Secure Memory DT changes - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/Kconfig | 7 + - drivers/crypto/caam/Makefile | 1 + - drivers/crypto/caam/ctrl.c | 3 - - drivers/crypto/caam/intern.h | 4 +- - drivers/crypto/caam/secvio.c | 342 +++++++++++++++++++++++++++++++++++++++++ - drivers/crypto/caam/secvio.h | 69 +++++++++ - drivers/crypto/caam/snvsregs.h | 239 ++++++++++++++++++++++++++++ - 7 files changed, 660 insertions(+), 5 deletions(-) - create mode 100644 drivers/crypto/caam/secvio.c - create mode 100644 drivers/crypto/caam/secvio.h - create mode 100644 drivers/crypto/caam/snvsregs.h - ---- a/drivers/crypto/caam/Kconfig -+++ b/drivers/crypto/caam/Kconfig -@@ -156,6 +156,13 @@ config CRYPTO_DEV_FSL_CAAM_RNG_TEST - caam RNG. This test is several minutes long and executes - just before the RNG is registered with the hw_random API. - -+config CRYPTO_DEV_FSL_CAAM_SECVIO -+ tristate "CAAM/SNVS Security Violation Handler (EXPERIMENTAL)" -+ help -+ Enables installation of an interrupt handler with registrable -+ handler functions which can be specified to act on the consequences -+ of a security violation. -+ - endif # CRYPTO_DEV_FSL_CAAM_JR - - endif # CRYPTO_DEV_FSL_CAAM ---- a/drivers/crypto/caam/Makefile -+++ b/drivers/crypto/caam/Makefile -@@ -21,6 +21,7 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRY - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o -+caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o - - caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o - ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),) ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -719,9 +719,6 @@ iomap_ctrl: - BLOCK_OFFSET * DECO_BLOCK_NUMBER - ); - -- /* Get the IRQ of the controller (for security violations only) */ -- ctrlpriv->secvio_irq = irq_of_parse_and_map(nprop, 0); -- - if (!reg_access) - goto set_dma_mask; - ---- a/drivers/crypto/caam/intern.h -+++ b/drivers/crypto/caam/intern.h -@@ -66,6 +66,7 @@ struct caam_drv_private_jr { - * Driver-private storage for a single CAAM block instance - */ - struct caam_drv_private { -+ - /* Physical-presence section */ - struct caam_ctrl __iomem *ctrl; /* controller region */ - struct caam_deco __iomem *deco; /* DECO/CCB views */ -@@ -83,8 +84,7 @@ struct caam_drv_private { - u8 qi_present; /* Nonzero if QI present in device */ - u8 mc_en; /* Nonzero if MC f/w is active */ - u8 scu_en; /* Nonzero if SCU f/w is active */ --+ u8 optee_en; /* Nonzero if OP-TEE f/w is active */ -- int secvio_irq; /* Security violation interrupt number */ -+ u8 optee_en; /* Nonzero if OP-TEE f/w is active */ - int virt_en; /* Virtualization enabled in CAAM */ - int era; /* CAAM Era (internal HW revision) */ - ---- /dev/null -+++ b/drivers/crypto/caam/secvio.c -@@ -0,0 +1,342 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * SNVS Security Violation Handler -+ * -+ * Copyright 2012-2016 Freescale Semiconductor, Inc. -+ * Copyright 2017-2019 NXP -+ */ -+ -+#include "compat.h" -+#include "secvio.h" -+#include "regs.h" -+#include "intern.h" -+#include -+#include -+#include -+ -+/* The driver is matched with node caam_snvs to get regmap -+ * It will then retrieve interruption and tamper alarm configuration from -+ * node caam-secvio searching for the compat string "fsl,imx6q-caam-secvio" -+ */ -+#define DRIVER_NAME "caam-snvs" -+ -+/* -+ * These names are associated with each violation handler. -+ * The source names were taken from MX6, and are based on recommendations -+ * for most common SoCs. -+ */ -+static const u8 *violation_src_name[] = { -+ "CAAM Internal Security Violation", -+ "JTAG Alarm", -+ "Watchdog", -+ "(reserved)", -+ "External Boot", -+ "External Tamper Detect", -+}; -+ -+/* These names help describe security monitor state for the console */ -+static const u8 *snvs_ssm_state_name[] = { -+ "init", -+ "hard fail", -+ "(undef:2)", -+ "soft fail", -+ "(undef:4)", -+ "(undef:5)", -+ "(undef:6)", -+ "(undef:7)", -+ "transition", -+ "check", -+ "(undef:10)", -+ "non-secure", -+ "(undef:12)", -+ "trusted", -+ "(undef:14)", -+ "secure", -+}; -+ -+/* Top-level security violation interrupt */ -+static irqreturn_t snvs_secvio_interrupt(int irq, void *snvsdev) -+{ -+ struct device *dev = snvsdev; -+ struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev); -+ -+ clk_enable(svpriv->clk); -+ /* Check the HP secvio status register */ -+ svpriv->irqcause = rd_reg32(&svpriv->svregs->hp.secvio_status) & -+ HP_SECVIOST_SECVIOMASK; -+ -+ if (!svpriv->irqcause) { -+ clk_disable(svpriv->clk); -+ return IRQ_NONE; -+ } -+ -+ /* Now ACK cause */ -+ clrsetbits_32(&svpriv->svregs->hp.secvio_status, 0, svpriv->irqcause); -+ -+ /* And run deferred service */ -+ preempt_disable(); -+ tasklet_schedule(&svpriv->irqtask[smp_processor_id()]); -+ preempt_enable(); -+ -+ clk_disable(svpriv->clk); -+ -+ return IRQ_HANDLED; -+} -+ -+/* Deferred service handler. Tasklet arg is simply the SNVS dev */ -+static void snvs_secvio_dispatch(unsigned long indev) -+{ -+ struct device *dev = (struct device *)indev; -+ struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev); -+ unsigned long flags; -+ int i; -+ -+ -+ /* Look through stored causes, call each handler if exists */ -+ for (i = 0; i < MAX_SECVIO_SOURCES; i++) -+ if (svpriv->irqcause & (1 << i)) { -+ spin_lock_irqsave(&svpriv->svlock, flags); -+ svpriv->intsrc[i].handler(dev, i, -+ svpriv->intsrc[i].ext); -+ spin_unlock_irqrestore(&svpriv->svlock, flags); -+ }; -+ -+ /* Re-enable now-serviced interrupts */ -+ clrsetbits_32(&svpriv->svregs->hp.secvio_intcfg, 0, svpriv->irqcause); -+} -+ -+/* -+ * Default cause handler, used in lieu of an application-defined handler. -+ * All it does at this time is print a console message. It could force a halt. -+ */ -+static void snvs_secvio_default(struct device *dev, u32 cause, void *ext) -+{ -+ struct snvs_secvio_drv_private *svpriv = dev_get_drvdata(dev); -+ -+ dev_err(dev, "Unhandled Security Violation Interrupt %d = %s\n", -+ cause, svpriv->intsrc[cause].intname); -+} -+ -+/* -+ * Install an application-defined handler for a specified cause -+ * Arguments: -+ * - dev points to SNVS-owning device -+ * - cause interrupt source cause -+ * - handler application-defined handler, gets called with dev -+ * source cause, and locally-defined handler argument -+ * - cause_description points to a string to override the default cause -+ * name, this can be used as an alternate for error -+ * messages and such. If left NULL, the default -+ * description string is used. -+ * - ext pointer to any extra data needed by the handler. -+ */ -+int snvs_secvio_install_handler(struct device *dev, enum secvio_cause cause, -+ void (*handler)(struct device *dev, u32 cause, -+ void *ext), -+ u8 *cause_description, void *ext) -+{ -+ unsigned long flags; -+ struct snvs_secvio_drv_private *svpriv; -+ -+ svpriv = dev_get_drvdata(dev); -+ -+ if ((handler == NULL) || (cause > SECVIO_CAUSE_SOURCE_5)) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&svpriv->svlock, flags); -+ svpriv->intsrc[cause].handler = handler; -+ if (cause_description != NULL) -+ svpriv->intsrc[cause].intname = cause_description; -+ if (ext != NULL) -+ svpriv->intsrc[cause].ext = ext; -+ spin_unlock_irqrestore(&svpriv->svlock, flags); -+ -+ return 0; -+} -+EXPORT_SYMBOL(snvs_secvio_install_handler); -+ -+/* -+ * Remove an application-defined handler for a specified cause (and, by -+ * implication, restore the "default". -+ * Arguments: -+ * - dev points to SNVS-owning device -+ * - cause interrupt source cause -+ */ -+int snvs_secvio_remove_handler(struct device *dev, enum secvio_cause cause) -+{ -+ unsigned long flags; -+ struct snvs_secvio_drv_private *svpriv; -+ -+ svpriv = dev_get_drvdata(dev); -+ -+ if (cause > SECVIO_CAUSE_SOURCE_5) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&svpriv->svlock, flags); -+ svpriv->intsrc[cause].intname = violation_src_name[cause]; -+ svpriv->intsrc[cause].handler = snvs_secvio_default; -+ svpriv->intsrc[cause].ext = NULL; -+ spin_unlock_irqrestore(&svpriv->svlock, flags); -+ return 0; -+} -+EXPORT_SYMBOL(snvs_secvio_remove_handler); -+ -+static int snvs_secvio_remove(struct platform_device *pdev) -+{ -+ struct device *svdev; -+ struct snvs_secvio_drv_private *svpriv; -+ int i; -+ -+ svdev = &pdev->dev; -+ svpriv = dev_get_drvdata(svdev); -+ -+ clk_enable(svpriv->clk); -+ /* Set all sources to nonfatal */ -+ wr_reg32(&svpriv->svregs->hp.secvio_intcfg, 0); -+ -+ /* Remove tasklets and release interrupt */ -+ for_each_possible_cpu(i) -+ tasklet_kill(&svpriv->irqtask[i]); -+ -+ clk_disable_unprepare(svpriv->clk); -+ free_irq(svpriv->irq, svdev); -+ iounmap(svpriv->svregs); -+ kfree(svpriv); -+ -+ return 0; -+} -+ -+static int snvs_secvio_probe(struct platform_device *pdev) -+{ -+ struct device *svdev; -+ struct snvs_secvio_drv_private *svpriv; -+ struct device_node *np, *npirq; -+ struct snvs_full __iomem *snvsregs; -+ int i, error; -+ u32 hpstate; -+ const void *jtd, *wtd, *itd, *etd; -+ u32 td_en; -+ -+ svpriv = kzalloc(sizeof(struct snvs_secvio_drv_private), GFP_KERNEL); -+ if (!svpriv) -+ return -ENOMEM; -+ -+ svdev = &pdev->dev; -+ dev_set_drvdata(svdev, svpriv); -+ svpriv->pdev = pdev; -+ np = pdev->dev.of_node; -+ -+ npirq = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-secvio"); -+ if (!npirq) { -+ dev_err(svdev, "can't find secvio node\n"); -+ kfree(svpriv); -+ return -EINVAL; -+ } -+ svpriv->irq = irq_of_parse_and_map(npirq, 0); -+ if (svpriv->irq <= 0) { -+ dev_err(svdev, "can't identify secvio interrupt\n"); -+ kfree(svpriv); -+ return -EINVAL; -+ } -+ -+ jtd = of_get_property(npirq, "jtag-tamper", NULL); -+ wtd = of_get_property(npirq, "watchdog-tamper", NULL); -+ itd = of_get_property(npirq, "internal-boot-tamper", NULL); -+ etd = of_get_property(npirq, "external-pin-tamper", NULL); -+ if (!jtd | !wtd | !itd | !etd ) { -+ dev_err(svdev, "can't identify all tamper alarm configuration\n"); -+ kfree(svpriv); -+ return -EINVAL; -+ } -+ -+ /* -+ * Configure all sources according to device tree property. -+ * If the property is enabled then the source is ser as -+ * fatal violations except LP section, -+ * source #5 (typically used as an external tamper detect), and -+ * source #3 (typically unused). Whenever the transition to -+ * secure mode has occurred, these will now be "fatal" violations -+ */ -+ td_en = HP_SECVIO_INTEN_SRC0; -+ if (!strcmp(jtd, "enabled")) -+ td_en |= HP_SECVIO_INTEN_SRC1; -+ if (!strcmp(wtd, "enabled")) -+ td_en |= HP_SECVIO_INTEN_SRC2; -+ if (!strcmp(itd, "enabled")) -+ td_en |= HP_SECVIO_INTEN_SRC4; -+ if (!strcmp(etd, "enabled")) -+ td_en |= HP_SECVIO_INTEN_SRC5; -+ -+ snvsregs = of_iomap(np, 0); -+ if (!snvsregs) { -+ dev_err(svdev, "register mapping failed\n"); -+ return -ENOMEM; -+ } -+ svpriv->svregs = (struct snvs_full __force *)snvsregs; -+ -+ svpriv->clk = devm_clk_get(&pdev->dev, NULL); -+ if (IS_ERR(svpriv->clk)) { -+ dev_err(&pdev->dev, "can't get snvs clock\n"); -+ svpriv->clk = NULL; -+ } -+ -+ /* Write the Secvio Enable Config the SVCR */ -+ wr_reg32(&svpriv->svregs->hp.secvio_ctl, td_en); -+ wr_reg32(&svpriv->svregs->hp.secvio_intcfg, td_en); -+ -+ /* Device data set up. Now init interrupt source descriptions */ -+ for (i = 0; i < MAX_SECVIO_SOURCES; i++) { -+ svpriv->intsrc[i].intname = violation_src_name[i]; -+ svpriv->intsrc[i].handler = snvs_secvio_default; -+ } -+ /* Connect main handler */ -+ for_each_possible_cpu(i) -+ tasklet_init(&svpriv->irqtask[i], snvs_secvio_dispatch, -+ (unsigned long)svdev); -+ -+ error = request_irq(svpriv->irq, snvs_secvio_interrupt, -+ IRQF_SHARED, DRIVER_NAME, svdev); -+ if (error) { -+ dev_err(svdev, "can't connect secvio interrupt\n"); -+ irq_dispose_mapping(svpriv->irq); -+ svpriv->irq = 0; -+ iounmap(svpriv->svregs); -+ kfree(svpriv); -+ return -EINVAL; -+ } -+ -+ clk_prepare_enable(svpriv->clk); -+ -+ hpstate = (rd_reg32(&svpriv->svregs->hp.status) & -+ HP_STATUS_SSM_ST_MASK) >> HP_STATUS_SSM_ST_SHIFT; -+ dev_info(svdev, "violation handlers armed - %s state\n", -+ snvs_ssm_state_name[hpstate]); -+ -+ clk_disable(svpriv->clk); -+ -+ return 0; -+} -+ -+static struct of_device_id snvs_secvio_match[] = { -+ { -+ .compatible = "fsl,imx6q-caam-snvs", -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snvs_secvio_match); -+ -+static struct platform_driver snvs_secvio_driver = { -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = snvs_secvio_match, -+ }, -+ .probe = snvs_secvio_probe, -+ .remove = snvs_secvio_remove, -+}; -+ -+module_platform_driver(snvs_secvio_driver); -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("FSL SNVS Security Violation Handler"); -+MODULE_AUTHOR("Freescale Semiconductor - MCU"); ---- /dev/null -+++ b/drivers/crypto/caam/secvio.h -@@ -0,0 +1,69 @@ -+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ -+/* -+ * CAAM Security Violation Handler -+ * -+ * Copyright 2012-2015 Freescale Semiconductor, Inc. -+ * Copyright 2016-2019 NXP -+ */ -+ -+#ifndef SECVIO_H -+#define SECVIO_H -+ -+#include "snvsregs.h" -+ -+ -+/* -+ * Defines the published interfaces to install/remove application-specified -+ * handlers for catching violations -+ */ -+ -+#define MAX_SECVIO_SOURCES 6 -+ -+/* these are the untranslated causes */ -+enum secvio_cause { -+ SECVIO_CAUSE_SOURCE_0, -+ SECVIO_CAUSE_SOURCE_1, -+ SECVIO_CAUSE_SOURCE_2, -+ SECVIO_CAUSE_SOURCE_3, -+ SECVIO_CAUSE_SOURCE_4, -+ SECVIO_CAUSE_SOURCE_5 -+}; -+ -+/* These are common "recommended" cause definitions for most devices */ -+#define SECVIO_CAUSE_CAAM_VIOLATION SECVIO_CAUSE_SOURCE_0 -+#define SECVIO_CAUSE_JTAG_ALARM SECVIO_CAUSE_SOURCE_1 -+#define SECVIO_CAUSE_WATCHDOG SECVIO_CAUSE_SOURCE_2 -+#define SECVIO_CAUSE_EXTERNAL_BOOT SECVIO_CAUSE_SOURCE_4 -+#define SECVIO_CAUSE_TAMPER_DETECT SECVIO_CAUSE_SOURCE_5 -+ -+int snvs_secvio_install_handler(struct device *dev, enum secvio_cause cause, -+ void (*handler)(struct device *dev, u32 cause, -+ void *ext), -+ u8 *cause_description, void *ext); -+int snvs_secvio_remove_handler(struct device *dev, enum secvio_cause cause); -+ -+/* -+ * Private data definitions for the secvio "driver" -+ */ -+ -+struct secvio_int_src { -+ const u8 *intname; /* Points to a descriptive name for source */ -+ void *ext; /* Extended data to pass to the handler */ -+ void (*handler)(struct device *dev, u32 cause, void *ext); -+}; -+ -+struct snvs_secvio_drv_private { -+ struct platform_device *pdev; -+ spinlock_t svlock ____cacheline_aligned; -+ struct tasklet_struct irqtask[NR_CPUS]; -+ struct snvs_full __iomem *svregs; /* both HP and LP domains */ -+ struct clk *clk; -+ int irq; -+ u32 irqcause; /* stashed cause of violation interrupt */ -+ -+ /* Registered handlers for each violation */ -+ struct secvio_int_src intsrc[MAX_SECVIO_SOURCES]; -+ -+}; -+ -+#endif /* SECVIO_H */ ---- /dev/null -+++ b/drivers/crypto/caam/snvsregs.h -@@ -0,0 +1,239 @@ -+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ -+/* -+ * SNVS hardware register-level view -+ * -+ * Copyright 2012-2015 Freescale Semiconductor, Inc. -+ * Copyright 2016-2019 NXP -+ */ -+ -+#ifndef SNVSREGS_H -+#define SNVSREGS_H -+ -+#include -+#include -+ -+/* -+ * SNVS High Power Domain -+ * Includes security violations, HA counter, RTC, alarm -+ */ -+struct snvs_hp { -+ u32 lock; /* HPLR - HP Lock */ -+ u32 cmd; /* HPCOMR - HP Command */ -+ u32 ctl; /* HPCR - HP Control */ -+ u32 secvio_intcfg; /* HPSICR - Security Violation Int Config */ -+ u32 secvio_ctl; /* HPSVCR - Security Violation Control */ -+ u32 status; /* HPSR - HP Status */ -+ u32 secvio_status; /* HPSVSR - Security Violation Status */ -+ u32 ha_counteriv; /* High Assurance Counter IV */ -+ u32 ha_counter; /* High Assurance Counter */ -+ u32 rtc_msb; /* Real Time Clock/Counter MSB */ -+ u32 rtc_lsb; /* Real Time Counter LSB */ -+ u32 time_alarm_msb; /* Time Alarm MSB */ -+ u32 time_alarm_lsb; /* Time Alarm LSB */ -+}; -+ -+#define HP_LOCK_HAC_LCK 0x00040000 -+#define HP_LOCK_HPSICR_LCK 0x00020000 -+#define HP_LOCK_HPSVCR_LCK 0x00010000 -+#define HP_LOCK_MKEYSEL_LCK 0x00000200 -+#define HP_LOCK_TAMPCFG_LCK 0x00000100 -+#define HP_LOCK_TAMPFLT_LCK 0x00000080 -+#define HP_LOCK_SECVIO_LCK 0x00000040 -+#define HP_LOCK_GENP_LCK 0x00000020 -+#define HP_LOCK_MONOCTR_LCK 0x00000010 -+#define HP_LOCK_CALIB_LCK 0x00000008 -+#define HP_LOCK_SRTC_LCK 0x00000004 -+#define HP_LOCK_ZMK_RD_LCK 0x00000002 -+#define HP_LOCK_ZMK_WT_LCK 0x00000001 -+ -+#define HP_CMD_NONPRIV_AXS 0x80000000 -+#define HP_CMD_HAC_STOP 0x00080000 -+#define HP_CMD_HAC_CLEAR 0x00040000 -+#define HP_CMD_HAC_LOAD 0x00020000 -+#define HP_CMD_HAC_CFG_EN 0x00010000 -+#define HP_CMD_SNVS_MSTR_KEY 0x00002000 -+#define HP_CMD_PROG_ZMK 0x00001000 -+#define HP_CMD_SW_LPSV 0x00000400 -+#define HP_CMD_SW_FSV 0x00000200 -+#define HP_CMD_SW_SV 0x00000100 -+#define HP_CMD_LP_SWR_DIS 0x00000020 -+#define HP_CMD_LP_SWR 0x00000010 -+#define HP_CMD_SSM_SFNS_DIS 0x00000004 -+#define HP_CMD_SSM_ST_DIS 0x00000002 -+#define HP_CMD_SMM_ST 0x00000001 -+ -+#define HP_CTL_TIME_SYNC 0x00010000 -+#define HP_CTL_CAL_VAL_SHIFT 10 -+#define HP_CTL_CAL_VAL_MASK (0x1f << HP_CTL_CALIB_SHIFT) -+#define HP_CTL_CALIB_EN 0x00000100 -+#define HP_CTL_PI_FREQ_SHIFT 4 -+#define HP_CTL_PI_FREQ_MASK (0xf << HP_CTL_PI_FREQ_SHIFT) -+#define HP_CTL_PI_EN 0x00000008 -+#define HP_CTL_TIMEALARM_EN 0x00000002 -+#define HP_CTL_RTC_EN 0x00000001 -+ -+#define HP_SECVIO_INTEN_EN 0x10000000 -+#define HP_SECVIO_INTEN_SRC5 0x00000020 -+#define HP_SECVIO_INTEN_SRC4 0x00000010 -+#define HP_SECVIO_INTEN_SRC3 0x00000008 -+#define HP_SECVIO_INTEN_SRC2 0x00000004 -+#define HP_SECVIO_INTEN_SRC1 0x00000002 -+#define HP_SECVIO_INTEN_SRC0 0x00000001 -+#define HP_SECVIO_INTEN_ALL 0x8000003f -+ -+#define HP_SECVIO_ICTL_CFG_SHIFT 30 -+#define HP_SECVIO_ICTL_CFG_MASK (0x3 << HP_SECVIO_ICTL_CFG_SHIFT) -+#define HP_SECVIO_ICTL_CFG5_SHIFT 5 -+#define HP_SECVIO_ICTL_CFG5_MASK (0x3 << HP_SECVIO_ICTL_CFG5_SHIFT) -+#define HP_SECVIO_ICTL_CFG_DISABLE 0 -+#define HP_SECVIO_ICTL_CFG_NONFATAL 1 -+#define HP_SECVIO_ICTL_CFG_FATAL 2 -+#define HP_SECVIO_ICTL_CFG4_FATAL 0x00000010 -+#define HP_SECVIO_ICTL_CFG3_FATAL 0x00000008 -+#define HP_SECVIO_ICTL_CFG2_FATAL 0x00000004 -+#define HP_SECVIO_ICTL_CFG1_FATAL 0x00000002 -+#define HP_SECVIO_ICTL_CFG0_FATAL 0x00000001 -+ -+#define HP_STATUS_ZMK_ZERO 0x80000000 -+#define HP_STATUS_OTPMK_ZERO 0x08000000 -+#define HP_STATUS_OTPMK_SYN_SHIFT 16 -+#define HP_STATUS_OTPMK_SYN_MASK (0x1ff << HP_STATUS_OTPMK_SYN_SHIFT) -+#define HP_STATUS_SSM_ST_SHIFT 8 -+#define HP_STATUS_SSM_ST_MASK (0xf << HP_STATUS_SSM_ST_SHIFT) -+#define HP_STATUS_SSM_ST_INIT 0 -+#define HP_STATUS_SSM_ST_HARDFAIL 1 -+#define HP_STATUS_SSM_ST_SOFTFAIL 3 -+#define HP_STATUS_SSM_ST_INITINT 8 -+#define HP_STATUS_SSM_ST_CHECK 9 -+#define HP_STATUS_SSM_ST_NONSECURE 11 -+#define HP_STATUS_SSM_ST_TRUSTED 13 -+#define HP_STATUS_SSM_ST_SECURE 15 -+ -+#define HP_SECVIOST_ZMK_ECC_FAIL 0x08000000 /* write to clear */ -+#define HP_SECVIOST_ZMK_SYN_SHIFT 16 -+#define HP_SECVIOST_ZMK_SYN_MASK (0x1ff << HP_SECVIOST_ZMK_SYN_SHIFT) -+#define HP_SECVIOST_SECVIO5 0x00000020 -+#define HP_SECVIOST_SECVIO4 0x00000010 -+#define HP_SECVIOST_SECVIO3 0x00000008 -+#define HP_SECVIOST_SECVIO2 0x00000004 -+#define HP_SECVIOST_SECVIO1 0x00000002 -+#define HP_SECVIOST_SECVIO0 0x00000001 -+#define HP_SECVIOST_SECVIOMASK 0x0000003f -+ -+/* -+ * SNVS Low Power Domain -+ * Includes glitch detector, SRTC, alarm, monotonic counter, ZMK -+ */ -+struct snvs_lp { -+ u32 lock; -+ u32 ctl; -+ u32 mstr_key_ctl; /* Master Key Control */ -+ u32 secvio_ctl; /* Security Violation Control */ -+ u32 tamper_filt_cfg; /* Tamper Glitch Filters Configuration */ -+ u32 tamper_det_cfg; /* Tamper Detectors Configuration */ -+ u32 status; -+ u32 srtc_msb; /* Secure Real Time Clock/Counter MSB */ -+ u32 srtc_lsb; /* Secure Real Time Clock/Counter LSB */ -+ u32 time_alarm; /* Time Alarm */ -+ u32 smc_msb; /* Secure Monotonic Counter MSB */ -+ u32 smc_lsb; /* Secure Monotonic Counter LSB */ -+ u32 pwr_glitch_det; /* Power Glitch Detector */ -+ u32 gen_purpose; -+ u32 zmk[8]; /* Zeroizable Master Key */ -+}; -+ -+#define LP_LOCK_MKEYSEL_LCK 0x00000200 -+#define LP_LOCK_TAMPDET_LCK 0x00000100 -+#define LP_LOCK_TAMPFLT_LCK 0x00000080 -+#define LP_LOCK_SECVIO_LCK 0x00000040 -+#define LP_LOCK_GENP_LCK 0x00000020 -+#define LP_LOCK_MONOCTR_LCK 0x00000010 -+#define LP_LOCK_CALIB_LCK 0x00000008 -+#define LP_LOCK_SRTC_LCK 0x00000004 -+#define LP_LOCK_ZMK_RD_LCK 0x00000002 -+#define LP_LOCK_ZMK_WT_LCK 0x00000001 -+ -+#define LP_CTL_CAL_VAL_SHIFT 10 -+#define LP_CTL_CAL_VAL_MASK (0x1f << LP_CTL_CAL_VAL_SHIFT) -+#define LP_CTL_CALIB_EN 0x00000100 -+#define LP_CTL_SRTC_INVAL_EN 0x00000010 -+#define LP_CTL_WAKE_INT_EN 0x00000008 -+#define LP_CTL_MONOCTR_EN 0x00000004 -+#define LP_CTL_TIMEALARM_EN 0x00000002 -+#define LP_CTL_SRTC_EN 0x00000001 -+ -+#define LP_MKEYCTL_ZMKECC_SHIFT 8 -+#define LP_MKEYCTL_ZMKECC_MASK (0xff << LP_MKEYCTL_ZMKECC_SHIFT) -+#define LP_MKEYCTL_ZMKECC_EN 0x00000010 -+#define LP_MKEYCTL_ZMKECC_VAL 0x00000008 -+#define LP_MKEYCTL_ZMKECC_PROG 0x00000004 -+#define LP_MKEYCTL_MKSEL_SHIFT 0 -+#define LP_MKEYCTL_MKSEL_MASK (3 << LP_MKEYCTL_MKSEL_SHIFT) -+#define LP_MKEYCTL_MK_OTP 0 -+#define LP_MKEYCTL_MK_ZMK 2 -+#define LP_MKEYCTL_MK_COMB 3 -+ -+#define LP_SECVIO_CTL_SRC5 0x20 -+#define LP_SECVIO_CTL_SRC4 0x10 -+#define LP_SECVIO_CTL_SRC3 0x08 -+#define LP_SECVIO_CTL_SRC2 0x04 -+#define LP_SECVIO_CTL_SRC1 0x02 -+#define LP_SECVIO_CTL_SRC0 0x01 -+ -+#define LP_TAMPFILT_EXT2_EN 0x80000000 -+#define LP_TAMPFILT_EXT2_SHIFT 24 -+#define LP_TAMPFILT_EXT2_MASK (0x1f << LP_TAMPFILT_EXT2_SHIFT) -+#define LP_TAMPFILT_EXT1_EN 0x00800000 -+#define LP_TAMPFILT_EXT1_SHIFT 16 -+#define LP_TAMPFILT_EXT1_MASK (0x1f << LP_TAMPFILT_EXT1_SHIFT) -+#define LP_TAMPFILT_WM_EN 0x00000080 -+#define LP_TAMPFILT_WM_SHIFT 0 -+#define LP_TAMPFILT_WM_MASK (0x1f << LP_TAMPFILT_WM_SHIFT) -+ -+#define LP_TAMPDET_OSC_BPS 0x10000000 -+#define LP_TAMPDET_VRC_SHIFT 24 -+#define LP_TAMPDET_VRC_MASK (3 << LP_TAMPFILT_VRC_SHIFT) -+#define LP_TAMPDET_HTDC_SHIFT 20 -+#define LP_TAMPDET_HTDC_MASK (3 << LP_TAMPFILT_HTDC_SHIFT) -+#define LP_TAMPDET_LTDC_SHIFT 16 -+#define LP_TAMPDET_LTDC_MASK (3 << LP_TAMPFILT_LTDC_SHIFT) -+#define LP_TAMPDET_POR_OBS 0x00008000 -+#define LP_TAMPDET_PFD_OBS 0x00004000 -+#define LP_TAMPDET_ET2_EN 0x00000400 -+#define LP_TAMPDET_ET1_EN 0x00000200 -+#define LP_TAMPDET_WMT2_EN 0x00000100 -+#define LP_TAMPDET_WMT1_EN 0x00000080 -+#define LP_TAMPDET_VT_EN 0x00000040 -+#define LP_TAMPDET_TT_EN 0x00000020 -+#define LP_TAMPDET_CT_EN 0x00000010 -+#define LP_TAMPDET_MCR_EN 0x00000004 -+#define LP_TAMPDET_SRTCR_EN 0x00000002 -+ -+#define LP_STATUS_SECURE -+#define LP_STATUS_NONSECURE -+#define LP_STATUS_SCANEXIT 0x00100000 /* all write 1 clear here on */ -+#define LP_STATUS_EXT_SECVIO 0x00010000 -+#define LP_STATUS_ET2 0x00000400 -+#define LP_STATUS_ET1 0x00000200 -+#define LP_STATUS_WMT2 0x00000100 -+#define LP_STATUS_WMT1 0x00000080 -+#define LP_STATUS_VTD 0x00000040 -+#define LP_STATUS_TTD 0x00000020 -+#define LP_STATUS_CTD 0x00000010 -+#define LP_STATUS_PGD 0x00000008 -+#define LP_STATUS_MCR 0x00000004 -+#define LP_STATUS_SRTCR 0x00000002 -+#define LP_STATUS_LPTA 0x00000001 -+ -+/* Full SNVS register page, including version/options */ -+struct snvs_full { -+ struct snvs_hp hp; -+ struct snvs_lp lp; -+ u32 rsvd[731]; /* deadspace 0x08c-0xbf7 */ -+ -+ /* Version / Revision / Option ID space - end of register page */ -+ u32 vid; /* 0xbf8 HP Version ID (VID 1) */ -+ u32 opt_rev; /* 0xbfc HP Options / Revision (VID 2) */ -+}; -+ -+#endif /* SNVSREGS_H */ diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0020-MLKU-25-3-crypto-caam-add-Secure-Memory-support.patch b/target/linux/layerscape/patches-5.4/804-crypto-0020-MLKU-25-3-crypto-caam-add-Secure-Memory-support.patch deleted file mode 100644 index db0e256ded..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0020-MLKU-25-3-crypto-caam-add-Secure-Memory-support.patch +++ /dev/null @@ -1,2503 +0,0 @@ -From 32221046a302245a63d5e00d16cf3008b5b31255 Mon Sep 17 00:00:00 2001 -From: Steve Cornelius -Date: Tue, 23 Jul 2013 20:47:32 -0700 -Subject: [PATCH] MLKU-25-3 crypto: caam - add Secure Memory support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is a squash of the following i.MX BSP commits -(rel_imx_4.19.35_1.1.0_rc2) - -1. ae8175a3f1be ("MLK-9710-10 Add CCM defs for FIFO_STORE instruction") -2. 9512280d066b ("MLK-9769-11 Add SM register defs, and expanded driver-private storage.") -3. a9dc44de8150 ("MLK-9769-10 Add Blob command bitdefs.") -4. 8f6a17b41917 ("ENGR00289885 [iMX6Q] Add Secure Memory and SECVIO support.") -5. c7d4f9db1077 ("MLK-9710-11 Add internal key cover and external blob export/import to prototype SM-API") -6. 568e449edfca ("MLK-9710-12 Adapt sm_test as a black-key handling example") -7. f42f12d9cb19 ("MLK-9710-13 Correct size in BLOB_OVERHEAD definition") -8. 022fc2b33f57 ("MLK-9710-14 Un-pad cache sizes for blob export/import") -9. 8d3e8c3c4dc1 ("MLK-9710-15 Correct size of padded key buffers") -10. 997fb2ff88ec ("MLK-9710-5 Unregister Secure Memory platform device upon shutdown") -11. 5316249198ee ("MLK-10897-1 ARM: imx7d: Add CAAM support for i.mx7d") -12. 07566f42a4ec ("MLK-11103 Missing register in Secure memory configuration v1") -13. 3004636304e1 ("MLK-12302 caam: Secure Memory platform device creation crashes") -14. 0e6ed5a819f7 ("MLK-13779 crypto: caam - initialize kslock spinlock") -15. b1254b6b5f52 ("Add missing NULL checks in CAAM sm") -16. 61f57509bc9a ("MLK-17992: caam: sm: Fix compilation warnings") -17. 41cf3d4c580c ("MLK-15473-1: crypto: caam: Add CAAM driver support for iMX8 soc family") -18. bb8742481209 ("MLK-17253-1: crypto: caam: Fix computation of SM pages addresses") -19. 308796dfae3b ("MLK-17253-2: crypto: caam: Use correct memory function for Secure Memory") -20. ba2cb6b5fb10 ("MLK-17732-2: SM store: Support iMX8QX and iMX8QM") -21. de710d376af6 ("MLK-17674-1: sm_store remove CONFIG_OF") -22. cfcae647434e ("MLK-17674-2: CAAM SM : get base address from device tree") -23. f49ebbd5eefa ("MLK-17992: caam: sm: Fix compilation warnings") -24. 345ead4338b9 ("MLK-17841: crypto: caam: Correct bugs in Secure Memory") -25. c17811f3fffc ("MLK-18082: crypto: caam: sm: Fix encap/decap function to handle errors") -26. 41bcba1d4c9b ("MLK-18082: crypto: caam: sm: Fix descriptor running functions") -27. b7385ab94784 ("MLK-20204: drivers: crypto: caam: sm: Remove deadcode") -28. 1d749430cb63 ("MLK-20204: drivers: crypto: caam: sm: test: Dealloc keyslot properly") -29. 6a5c2d9d358f ("crypto: caam - lower SM test verbosity") -30. 1a6bc92c0c87 ("MLK-21617: crypto: caam - update SM test error handling") - -Signed-off-by: Dan Douglass -Signed-off-by: Victoria Milhoan -Signed-off-by: Steve Cornelius -Signed-off-by: Octavian Purdila -Signed-off-by: Radu Solea -Signed-off-by: Franck LENORMAND -Signed-off-by: Aymen Sghaier -Signed-off-by: Silvano di Ninno - -that have been reworked: - -4. --make SM depend on JR --enable SM, SECVIO only on i.MX SoCs --fix resource leak - add off_node_put() where needed - -Split commit in three: -1 - SNVS/SECVIO driver -2 - Secure Memory driver -3 - DT changes - -11. -Clock handling dropped - logic already upstream. - -17. -Keep only Secure Memory related changes. -Changes related to page 0 registers have been added previously. -Other changes are dropped. - -21. -Always use first jr in ctrlpriv->jr[] array to access registers -in page 0 (aliased in jr page), irrespective of SCU presence. - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/Kconfig | 30 + - drivers/crypto/caam/Makefile | 2 + - drivers/crypto/caam/ctrl.c | 37 ++ - drivers/crypto/caam/desc.h | 21 + - drivers/crypto/caam/intern.h | 4 + - drivers/crypto/caam/regs.h | 158 ++++- - drivers/crypto/caam/sm.h | 127 ++++ - drivers/crypto/caam/sm_store.c | 1332 ++++++++++++++++++++++++++++++++++++++++ - drivers/crypto/caam/sm_test.c | 571 +++++++++++++++++ - 9 files changed, 2279 insertions(+), 3 deletions(-) - create mode 100644 drivers/crypto/caam/sm.h - create mode 100644 drivers/crypto/caam/sm_store.c - create mode 100644 drivers/crypto/caam/sm_test.c - ---- a/drivers/crypto/caam/Kconfig -+++ b/drivers/crypto/caam/Kconfig -@@ -156,6 +156,36 @@ config CRYPTO_DEV_FSL_CAAM_RNG_TEST - caam RNG. This test is several minutes long and executes - just before the RNG is registered with the hw_random API. - -+config CRYPTO_DEV_FSL_CAAM_SM -+ tristate "CAAM Secure Memory / Keystore API (EXPERIMENTAL)" -+ help -+ Enables use of a prototype kernel-level Keystore API with CAAM -+ Secure Memory for insertion/extraction of bus-protected secrets. -+ -+config CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE -+ int "Size of each keystore slot in Secure Memory" -+ depends on CRYPTO_DEV_FSL_CAAM_SM -+ range 5 9 -+ default 7 -+ help -+ Select size of allocation units to divide Secure Memory pages into -+ (the size of a "slot" as referenced inside the API code). -+ Established as powers of two. -+ Examples: -+ 5 => 32 bytes -+ 6 => 64 bytes -+ 7 => 128 bytes -+ 8 => 256 bytes -+ 9 => 512 bytes -+ -+config CRYPTO_DEV_FSL_CAAM_SM_TEST -+ tristate "CAAM Secure Memory - Keystore Test/Example (EXPERIMENTAL)" -+ depends on CRYPTO_DEV_FSL_CAAM_SM -+ help -+ Example thread to exercise the Keystore API and to verify that -+ stored and recovered secrets can be used for general purpose -+ encryption/decryption. -+ - config CRYPTO_DEV_FSL_CAAM_SECVIO - tristate "CAAM/SNVS Security Violation Handler (EXPERIMENTAL)" - help ---- a/drivers/crypto/caam/Makefile -+++ b/drivers/crypto/caam/Makefile -@@ -21,6 +21,8 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRY - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o -+caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM) += sm_store.o -+caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST) += sm_test.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o - - caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -17,6 +17,7 @@ - #include "jr.h" - #include "desc_constr.h" - #include "ctrl.h" -+#include "sm.h" - - bool caam_dpaa2; - EXPORT_SYMBOL(caam_dpaa2); -@@ -573,6 +574,7 @@ static int caam_probe(struct platform_de - const struct soc_device_attribute *imx_soc_match; - struct device *dev; - struct device_node *nprop, *np; -+ struct resource res_regs; - struct caam_ctrl __iomem *ctrl; - struct caam_drv_private *ctrlpriv; - struct caam_perfmon __iomem *perfmon; -@@ -719,9 +721,44 @@ iomap_ctrl: - BLOCK_OFFSET * DECO_BLOCK_NUMBER - ); - -+ /* Only i.MX SoCs have sm */ -+ if (!imx_soc_match) -+ goto mc_fw; -+ -+ /* Get CAAM-SM node and of_iomap() and save */ -+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm"); -+ if (!np) -+ return -ENODEV; -+ -+ /* Get CAAM SM registers base address from device tree */ -+ ret = of_address_to_resource(np, 0, &res_regs); -+ if (ret) { -+ dev_err(dev, "failed to retrieve registers base from device tree\n"); -+ of_node_put(np); -+ return -ENODEV; -+ } -+ -+ ctrlpriv->sm_phy = res_regs.start; -+ ctrlpriv->sm_base = devm_ioremap_resource(dev, &res_regs); -+ if (IS_ERR(ctrlpriv->sm_base)) { -+ of_node_put(np); -+ return PTR_ERR(ctrlpriv->sm_base); -+ } -+ -+ if (!of_machine_is_compatible("fsl,imx8mn") && -+ !of_machine_is_compatible("fsl,imx8mm") && -+ !of_machine_is_compatible("fsl,imx8mq") && -+ !of_machine_is_compatible("fsl,imx8qm") && -+ !of_machine_is_compatible("fsl,imx8qxp")) -+ ctrlpriv->sm_size = resource_size(&res_regs); -+ else -+ ctrlpriv->sm_size = PG_SIZE_64K; -+ of_node_put(np); -+ - if (!reg_access) - goto set_dma_mask; - -+mc_fw: - /* - * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, - * long pointers in master configuration register. ---- a/drivers/crypto/caam/desc.h -+++ b/drivers/crypto/caam/desc.h -@@ -403,6 +403,10 @@ - #define FIFOST_TYPE_PKHA_N (0x08 << FIFOST_TYPE_SHIFT) - #define FIFOST_TYPE_PKHA_A (0x0c << FIFOST_TYPE_SHIFT) - #define FIFOST_TYPE_PKHA_B (0x0d << FIFOST_TYPE_SHIFT) -+#define FIFOST_TYPE_AF_SBOX_CCM_JKEK (0x10 << FIFOST_TYPE_SHIFT) -+#define FIFOST_TYPE_AF_SBOX_CCM_TKEK (0x11 << FIFOST_TYPE_SHIFT) -+#define FIFOST_TYPE_KEY_CCM_JKEK (0x14 << FIFOST_TYPE_SHIFT) -+#define FIFOST_TYPE_KEY_CCM_TKEK (0x15 << FIFOST_TYPE_SHIFT) - #define FIFOST_TYPE_AF_SBOX_JKEK (0x20 << FIFOST_TYPE_SHIFT) - #define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT) - #define FIFOST_TYPE_PKHA_E_JKEK (0x22 << FIFOST_TYPE_SHIFT) -@@ -1136,6 +1140,23 @@ - #define OP_PCL_PKPROT_ECC 0x0002 - #define OP_PCL_PKPROT_F2M 0x0001 - -+/* Blob protocol protinfo bits */ -+#define OP_PCL_BLOB_TK 0x0200 -+#define OP_PCL_BLOB_EKT 0x0100 -+ -+#define OP_PCL_BLOB_K2KR_MEM 0x0000 -+#define OP_PCL_BLOB_K2KR_C1KR 0x0010 -+#define OP_PCL_BLOB_K2KR_C2KR 0x0030 -+#define OP_PCL_BLOB_K2KR_AFHAS 0x0050 -+#define OP_PCL_BLOB_K2KR_C2KR_SPLIT 0x0070 -+ -+#define OP_PCL_BLOB_PTXT_SECMEM 0x0008 -+#define OP_PCL_BLOB_BLACK 0x0004 -+ -+#define OP_PCL_BLOB_FMT_NORMAL 0x0000 -+#define OP_PCL_BLOB_FMT_MSTR 0x0002 -+#define OP_PCL_BLOB_FMT_TEST 0x0003 -+ - /* For non-protocol/alg-only op commands */ - #define OP_ALG_TYPE_SHIFT 24 - #define OP_ALG_TYPE_MASK (0x7 << OP_ALG_TYPE_SHIFT) ---- a/drivers/crypto/caam/intern.h -+++ b/drivers/crypto/caam/intern.h -@@ -66,6 +66,7 @@ struct caam_drv_private_jr { - * Driver-private storage for a single CAAM block instance - */ - struct caam_drv_private { -+ struct device *smdev; - - /* Physical-presence section */ - struct caam_ctrl __iomem *ctrl; /* controller region */ -@@ -73,6 +74,9 @@ struct caam_drv_private { - struct caam_assurance __iomem *assure; - struct caam_queue_if __iomem *qi; /* QI control region */ - struct caam_job_ring __iomem *jr[4]; /* JobR's register space */ -+ dma_addr_t __iomem *sm_base; /* Secure memory storage base */ -+ phys_addr_t sm_phy; /* Secure memory storage physical */ -+ u32 sm_size; - - struct iommu_domain *domain; - ---- a/drivers/crypto/caam/regs.h -+++ b/drivers/crypto/caam/regs.h -@@ -385,6 +385,12 @@ struct version_regs { - #define CHA_VER_VID_MD_LP512 0x1ull - #define CHA_VER_VID_MD_HP 0x2ull - -+/* -+ * caam_perfmon - Performance Monitor/Secure Memory Status/ -+ * CAAM Global Status/Component Version IDs -+ * -+ * Spans f00-fff wherever instantiated -+ */ - struct sec_vid { - u16 ip_id; - u8 maj_rev; -@@ -415,17 +421,22 @@ struct caam_perfmon { - #define CTPR_MS_PG_SZ_SHIFT 4 - u32 comp_parms_ms; /* CTPR - Compile Parameters Register */ - u32 comp_parms_ls; /* CTPR - Compile Parameters Register */ -- u64 rsvd1[2]; -+ /* Secure Memory State Visibility */ -+ u32 rsvd1; -+ u32 smstatus; /* Secure memory status */ -+ u32 rsvd2; -+ u32 smpartown; /* Secure memory partition owner */ - - /* CAAM Global Status fc0-fdf */ - u64 faultaddr; /* FAR - Fault Address */ - u32 faultliodn; /* FALR - Fault Address LIODN */ - u32 faultdetail; /* FADR - Fault Addr Detail */ -- u32 rsvd2; - #define CSTA_PLEND BIT(10) - #define CSTA_ALT_PLEND BIT(18) -+ u32 rsvd3; - u32 status; /* CSTA - CAAM Status */ -- u64 rsvd3; -+ u32 smpart; /* Secure Memory Partition Parameters */ -+ u32 smvid; /* Secure Memory Version ID */ - - /* Component Instantiation Parameters fe0-fff */ - u32 rtic_id; /* RVID - RTIC Version ID */ -@@ -444,6 +455,62 @@ struct caam_perfmon { - u32 caam_id_ls; /* CAAMVID - CAAM Version ID LS */ - }; - -+#define SMSTATUS_PART_SHIFT 28 -+#define SMSTATUS_PART_MASK (0xf << SMSTATUS_PART_SHIFT) -+#define SMSTATUS_PAGE_SHIFT 16 -+#define SMSTATUS_PAGE_MASK (0x7ff << SMSTATUS_PAGE_SHIFT) -+#define SMSTATUS_MID_SHIFT 8 -+#define SMSTATUS_MID_MASK (0x3f << SMSTATUS_MID_SHIFT) -+#define SMSTATUS_ACCERR_SHIFT 4 -+#define SMSTATUS_ACCERR_MASK (0xf << SMSTATUS_ACCERR_SHIFT) -+#define SMSTATUS_ACCERR_NONE 0 -+#define SMSTATUS_ACCERR_ALLOC 1 /* Page not allocated */ -+#define SMSTATUS_ACCESS_ID 2 /* Not granted by ID */ -+#define SMSTATUS_ACCESS_WRITE 3 /* Writes not allowed */ -+#define SMSTATUS_ACCESS_READ 4 /* Reads not allowed */ -+#define SMSTATUS_ACCESS_NONKEY 6 /* Non-key reads not allowed */ -+#define SMSTATUS_ACCESS_BLOB 9 /* Blob access not allowed */ -+#define SMSTATUS_ACCESS_DESCB 10 /* Descriptor Blob access spans pages */ -+#define SMSTATUS_ACCESS_NON_SM 11 /* Outside Secure Memory range */ -+#define SMSTATUS_ACCESS_XPAGE 12 /* Access crosses pages */ -+#define SMSTATUS_ACCESS_INITPG 13 /* Page still initializing */ -+#define SMSTATUS_STATE_SHIFT 0 -+#define SMSTATUS_STATE_MASK (0xf << SMSTATUS_STATE_SHIFT) -+#define SMSTATUS_STATE_RESET 0 -+#define SMSTATUS_STATE_INIT 1 -+#define SMSTATUS_STATE_NORMAL 2 -+#define SMSTATUS_STATE_FAIL 3 -+ -+/* up to 15 rings, 2 bits shifted by ring number */ -+#define SMPARTOWN_RING_SHIFT 2 -+#define SMPARTOWN_RING_MASK 3 -+#define SMPARTOWN_AVAILABLE 0 -+#define SMPARTOWN_NOEXIST 1 -+#define SMPARTOWN_UNAVAILABLE 2 -+#define SMPARTOWN_OURS 3 -+ -+/* Maximum number of pages possible */ -+#define SMPART_MAX_NUMPG_SHIFT 16 -+#define SMPART_MAX_NUMPG_MASK (0x3f << SMPART_MAX_NUMPG_SHIFT) -+ -+/* Maximum partition number */ -+#define SMPART_MAX_PNUM_SHIFT 12 -+#define SMPART_MAX_PNUM_MASK (0xf << SMPART_MAX_PNUM_SHIFT) -+ -+/* Highest possible page number */ -+#define SMPART_MAX_PG_SHIFT 0 -+#define SMPART_MAX_PG_MASK (0x3f << SMPART_MAX_PG_SHIFT) -+ -+/* Max size of a page */ -+#define SMVID_PG_SIZE_SHIFT 16 -+#define SMVID_PG_SIZE_MASK (0x7 << SMVID_PG_SIZE_SHIFT) -+ -+/* Major/Minor Version ID */ -+#define SMVID_MAJ_VERS_SHIFT 8 -+#define SMVID_MAJ_VERS (0xf << SMVID_MAJ_VERS_SHIFT) -+#define SMVID_MIN_VERS_SHIFT 0 -+#define SMVID_MIN_VERS (0xf << SMVID_MIN_VERS_SHIFT) -+ - /* LIODN programming for DMA configuration */ - #define MSTRID_LOCK_LIODN 0x80000000 - #define MSTRID_LOCK_MAKETRUSTED 0x00010000 /* only for JR masterid */ -@@ -648,6 +715,35 @@ struct caam_ctrl { - #define JRSTART_JR2_START 0x00000004 /* Start Job ring 2 */ - #define JRSTART_JR3_START 0x00000008 /* Start Job ring 3 */ - -+/* Secure Memory Configuration - if you have it */ -+/* Secure Memory Register Offset from JR Base Reg*/ -+#define SM_V1_OFFSET 0x0f4 -+#define SM_V2_OFFSET 0xa00 -+ -+/* Minimum SM Version ID requiring v2 SM register mapping */ -+#define SMVID_V2 0x20105 -+ -+struct caam_secure_mem_v1 { -+ u32 sm_cmd; /* SMCJRx - Secure memory command */ -+ u32 rsvd1; -+ u32 sm_status; /* SMCSJRx - Secure memory status */ -+ u32 rsvd2; -+ -+ u32 sm_perm; /* SMAPJRx - Secure memory access perms */ -+ u32 sm_group2; /* SMAP2JRx - Secure memory access group 2 */ -+ u32 sm_group1; /* SMAP1JRx - Secure memory access group 1 */ -+}; -+ -+struct caam_secure_mem_v2 { -+ u32 sm_perm; /* SMAPJRx - Secure memory access perms */ -+ u32 sm_group2; /* SMAP2JRx - Secure memory access group 2 */ -+ u32 sm_group1; /* SMAP1JRx - Secure memory access group 1 */ -+ u32 rsvd1[118]; -+ u32 sm_cmd; /* SMCJRx - Secure memory command */ -+ u32 rsvd2; -+ u32 sm_status; /* SMCSJRx - Secure memory status */ -+}; -+ - /* - * caam_job_ring - direct job ring setup - * 1-4 possible per instantiation, base + 1000/2000/3000/4000 -@@ -818,6 +914,62 @@ struct caam_job_ring { - - #define JRCR_RESET 0x01 - -+/* secure memory command */ -+#define SMC_PAGE_SHIFT 16 -+#define SMC_PAGE_MASK (0xffff << SMC_PAGE_SHIFT) -+#define SMC_PART_SHIFT 8 -+#define SMC_PART_MASK (0x0f << SMC_PART_SHIFT) -+#define SMC_CMD_SHIFT 0 -+#define SMC_CMD_MASK (0x0f << SMC_CMD_SHIFT) -+ -+#define SMC_CMD_ALLOC_PAGE 0x01 /* allocate page to this partition */ -+#define SMC_CMD_DEALLOC_PAGE 0x02 /* deallocate page from partition */ -+#define SMC_CMD_DEALLOC_PART 0x03 /* deallocate partition */ -+#define SMC_CMD_PAGE_INQUIRY 0x05 /* find partition associate with page */ -+ -+/* secure memory (command) status */ -+#define SMCS_PAGE_SHIFT 16 -+#define SMCS_PAGE_MASK (0x0fff << SMCS_PAGE_SHIFT) -+#define SMCS_CMDERR_SHIFT 14 -+#define SMCS_CMDERR_MASK (3 << SMCS_CMDERR_SHIFT) -+#define SMCS_ALCERR_SHIFT 12 -+#define SMCS_ALCERR_MASK (3 << SMCS_ALCERR_SHIFT) -+#define SMCS_PGOWN_SHIFT 6 -+#define SMCS_PGWON_MASK (3 << SMCS_PGOWN_SHIFT) -+#define SMCS_PART_SHIFT 0 -+#define SMCS_PART_MASK (0xf << SMCS_PART_SHIFT) -+ -+#define SMCS_CMDERR_NONE 0 -+#define SMCS_CMDERR_INCOMP 1 /* Command not yet complete */ -+#define SMCS_CMDERR_SECFAIL 2 /* Security failure occurred */ -+#define SMCS_CMDERR_OVERFLOW 3 /* Command overflow */ -+ -+#define SMCS_ALCERR_NONE 0 -+#define SMCS_ALCERR_PSPERR 1 /* Partion marked PSP (dealloc only) */ -+#define SMCS_ALCERR_PAGEAVAIL 2 /* Page not available */ -+#define SMCS_ALCERR_PARTOWN 3 /* Partition ownership error */ -+ -+#define SMCS_PGOWN_AVAIL 0 /* Page is available */ -+#define SMCS_PGOWN_NOEXIST 1 /* Page initializing or nonexistent */ -+#define SMCS_PGOWN_NOOWN 2 /* Page owned by another processor */ -+#define SMCS_PGOWN_OWNED 3 /* Page belongs to this processor */ -+ -+/* secure memory access permissions */ -+#define SMCS_PERM_KEYMOD_SHIFT 16 -+#define SMCA_PERM_KEYMOD_MASK (0xff << SMCS_PERM_KEYMOD_SHIFT) -+#define SMCA_PERM_CSP_ZERO 0x8000 /* Zero when deallocated or released */ -+#define SMCA_PERM_PSP_LOCK 0x4000 /* Part./pages can't be deallocated */ -+#define SMCA_PERM_PERM_LOCK 0x2000 /* Lock permissions */ -+#define SMCA_PERM_GRP_LOCK 0x1000 /* Lock access groups */ -+#define SMCA_PERM_RINGID_SHIFT 10 -+#define SMCA_PERM_RINGID_MASK (3 << SMCA_PERM_RINGID_SHIFT) -+#define SMCA_PERM_G2_BLOB 0x0080 /* Group 2 blob import/export */ -+#define SMCA_PERM_G2_WRITE 0x0020 /* Group 2 write */ -+#define SMCA_PERM_G2_READ 0x0010 /* Group 2 read */ -+#define SMCA_PERM_G1_BLOB 0x0008 /* Group 1... */ -+#define SMCA_PERM_G1_WRITE 0x0002 -+#define SMCA_PERM_G1_READ 0x0001 -+ - /* - * caam_assurance - Assurance Controller View - * base + 0x6000 padded out to 0x1000 ---- /dev/null -+++ b/drivers/crypto/caam/sm.h -@@ -0,0 +1,127 @@ -+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ -+/* -+ * CAAM Secure Memory/Keywrap API Definitions -+ * -+ * Copyright 2008-2015 Freescale Semiconductor, Inc. -+ * Copyright 2016-2019 NXP -+ */ -+ -+#ifndef SM_H -+#define SM_H -+ -+ -+/* Storage access permissions */ -+#define SM_PERM_READ 0x01 -+#define SM_PERM_WRITE 0x02 -+#define SM_PERM_BLOB 0x03 -+ -+/* Define treatment of secure memory vs. general memory blobs */ -+#define SM_SECMEM 0 -+#define SM_GENMEM 1 -+ -+/* Define treatment of red/black keys */ -+#define RED_KEY 0 -+#define BLACK_KEY 1 -+ -+/* Define key encryption/covering options */ -+#define KEY_COVER_ECB 0 /* cover key in AES-ECB */ -+#define KEY_COVER_CCM 1 /* cover key with AES-CCM */ -+ -+/* -+ * Round a key size up to an AES blocksize boundary so to allow for -+ * padding out to a full block -+ */ -+#define AES_BLOCK_PAD(x) ((x % 16) ? ((x >> 4) + 1) << 4 : x) -+ -+/* Define space required for BKEK + MAC tag storage in any blob */ -+#define BLOB_OVERHEAD (32 + 16) -+ -+/* Keystore maintenance functions */ -+void sm_init_keystore(struct device *dev); -+u32 sm_detect_keystore_units(struct device *dev); -+int sm_establish_keystore(struct device *dev, u32 unit); -+void sm_release_keystore(struct device *dev, u32 unit); -+void caam_sm_shutdown(struct platform_device *pdev); -+int caam_sm_example_init(struct platform_device *pdev); -+ -+/* Keystore accessor functions */ -+extern int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size, -+ u32 *slot); -+extern int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot); -+extern int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot, -+ const u8 *key_data, u32 key_length); -+extern int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot, -+ u32 key_length, u8 *key_data); -+extern int sm_keystore_cover_key(struct device *dev, u32 unit, u32 slot, -+ u16 key_length, u8 keyauth); -+extern int sm_keystore_slot_export(struct device *dev, u32 unit, u32 slot, -+ u8 keycolor, u8 keyauth, u8 *outbuf, -+ u16 keylen, u8 *keymod); -+extern int sm_keystore_slot_import(struct device *dev, u32 unit, u32 slot, -+ u8 keycolor, u8 keyauth, u8 *inbuf, -+ u16 keylen, u8 *keymod); -+ -+/* Prior functions from legacy API, deprecated */ -+extern int sm_keystore_slot_encapsulate(struct device *dev, u32 unit, -+ u32 inslot, u32 outslot, u16 secretlen, -+ u8 *keymod, u16 keymodlen); -+extern int sm_keystore_slot_decapsulate(struct device *dev, u32 unit, -+ u32 inslot, u32 outslot, u16 secretlen, -+ u8 *keymod, u16 keymodlen); -+ -+/* Data structure to hold per-slot information */ -+struct keystore_data_slot_info { -+ u8 allocated; /* Track slot assignments */ -+ u32 key_length; /* Size of the key */ -+}; -+ -+/* Data structure to hold keystore information */ -+struct keystore_data { -+ void *base_address; /* Virtual base of secure memory pages */ -+ void *phys_address; /* Physical base of secure memory pages */ -+ u32 slot_count; /* Number of slots in the keystore */ -+ struct keystore_data_slot_info *slot; /* Per-slot information */ -+}; -+ -+/* store the detected attributes of a secure memory page */ -+struct sm_page_descriptor { -+ u16 phys_pagenum; /* may be discontiguous */ -+ u16 own_part; /* Owning partition */ -+ void *pg_base; /* Calculated virtual address */ -+ void *pg_phys; /* Calculated physical address */ -+ struct keystore_data *ksdata; -+}; -+ -+struct caam_drv_private_sm { -+ struct device *parentdev; /* this ends up as the controller */ -+ struct device *smringdev; /* ring that owns this instance */ -+ struct platform_device *sm_pdev; /* Secure Memory platform device */ -+ spinlock_t kslock ____cacheline_aligned; -+ -+ /* SM Register offset from JR base address */ -+ u32 sm_reg_offset; -+ -+ /* Default parameters for geometry */ -+ u32 max_pages; /* maximum pages this instance can support */ -+ u32 top_partition; /* highest partition number in this instance */ -+ u32 top_page; /* highest page number in this instance */ -+ u32 page_size; /* page size */ -+ u32 slot_size; /* selected size of each storage block */ -+ -+ /* Partition/Page Allocation Map */ -+ u32 localpages; /* Number of pages we can access */ -+ struct sm_page_descriptor *pagedesc; /* Allocated per-page */ -+ -+ /* Installed handlers for keystore access */ -+ int (*data_init)(struct device *dev, u32 unit); -+ void (*data_cleanup)(struct device *dev, u32 unit); -+ int (*slot_alloc)(struct device *dev, u32 unit, u32 size, u32 *slot); -+ int (*slot_dealloc)(struct device *dev, u32 unit, u32 slot); -+ void *(*slot_get_address)(struct device *dev, u32 unit, u32 handle); -+ void *(*slot_get_physical)(struct device *dev, u32 unit, u32 handle); -+ u32 (*slot_get_base)(struct device *dev, u32 unit, u32 handle); -+ u32 (*slot_get_offset)(struct device *dev, u32 unit, u32 handle); -+ u32 (*slot_get_slot_size)(struct device *dev, u32 unit, u32 handle); -+}; -+ -+#endif /* SM_H */ ---- /dev/null -+++ b/drivers/crypto/caam/sm_store.c -@@ -0,0 +1,1332 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * CAAM Secure Memory Storage Interface -+ * -+ * Copyright 2008-2015 Freescale Semiconductor, Inc. -+ * Copyright 2016-2019 NXP -+ * -+ * Loosely based on the SHW Keystore API for SCC/SCC2 -+ * Experimental implementation and NOT intended for upstream use. Expect -+ * this interface to be amended significantly in the future once it becomes -+ * integrated into live applications. -+ * -+ * Known issues: -+ * -+ * - Executes one instance of an secure memory "driver". This is tied to the -+ * fact that job rings can't run as standalone instances in the present -+ * configuration. -+ * -+ * - It does not expose a userspace interface. The value of a userspace -+ * interface for access to secrets is a point for further architectural -+ * discussion. -+ * -+ * - Partition/permission management is not part of this interface. It -+ * depends on some level of "knowledge" agreed upon between bootloader, -+ * provisioning applications, and OS-hosted software (which uses this -+ * driver). -+ * -+ * - No means of identifying the location or purpose of secrets managed by -+ * this interface exists; "slot location" and format of a given secret -+ * needs to be agreed upon between bootloader, provisioner, and OS-hosted -+ * application. -+ */ -+ -+#include "compat.h" -+#include "regs.h" -+#include "jr.h" -+#include "desc.h" -+#include "intern.h" -+#include "error.h" -+#include "sm.h" -+#include -+ -+#define SECMEM_KEYMOD_LEN 8 -+#define GENMEM_KEYMOD_LEN 16 -+ -+#ifdef SM_DEBUG_CONT -+void sm_show_page(struct device *dev, struct sm_page_descriptor *pgdesc) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ u32 i, *smdata; -+ -+ dev_info(dev, "physical page %d content at 0x%08x\n", -+ pgdesc->phys_pagenum, pgdesc->pg_base); -+ smdata = pgdesc->pg_base; -+ for (i = 0; i < (smpriv->page_size / sizeof(u32)); i += 4) -+ dev_info(dev, "[0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ (u32)&smdata[i], smdata[i], smdata[i+1], smdata[i+2], -+ smdata[i+3]); -+} -+#endif -+ -+#define INITIAL_DESCSZ 16 /* size of tmp buffer for descriptor const. */ -+ -+static __always_inline u32 sm_send_cmd(struct caam_drv_private_sm *smpriv, -+ struct caam_drv_private_jr *jrpriv, -+ u32 cmd, u32 *status) -+{ -+ void __iomem *write_address; -+ void __iomem *read_address; -+ -+ if (smpriv->sm_reg_offset == SM_V1_OFFSET) { -+ struct caam_secure_mem_v1 *sm_regs_v1; -+ -+ sm_regs_v1 = (struct caam_secure_mem_v1 *) -+ ((void *)jrpriv->rregs + SM_V1_OFFSET); -+ write_address = &sm_regs_v1->sm_cmd; -+ read_address = &sm_regs_v1->sm_status; -+ -+ } else if (smpriv->sm_reg_offset == SM_V2_OFFSET) { -+ struct caam_secure_mem_v2 *sm_regs_v2; -+ -+ sm_regs_v2 = (struct caam_secure_mem_v2 *) -+ ((void *)jrpriv->rregs + SM_V2_OFFSET); -+ write_address = &sm_regs_v2->sm_cmd; -+ read_address = &sm_regs_v2->sm_status; -+ -+ } else { -+ return -EINVAL; -+ } -+ -+ wr_reg32(write_address, cmd); -+ -+ udelay(10); -+ -+ /* Read until the command has terminated and the status is correct */ -+ do { -+ *status = rd_reg32(read_address); -+ } while (((*status & SMCS_CMDERR_MASK) >> SMCS_CMDERR_SHIFT) -+ == SMCS_CMDERR_INCOMP); -+ -+ return 0; -+} -+ -+/* -+ * Construct a black key conversion job descriptor -+ * -+ * This function constructs a job descriptor capable of performing -+ * a key blackening operation on a plaintext secure memory resident object. -+ * -+ * - desc pointer to a pointer to the descriptor generated by this -+ * function. Caller will be responsible to kfree() this -+ * descriptor after execution. -+ * - key physical pointer to the plaintext, which will also hold -+ * the result. Since encryption occurs in place, caller must -+ * ensure that the space is large enough to accommodate the -+ * blackened key -+ * - keysz size of the plaintext -+ * - auth if a CCM-covered key is required, use KEY_COVER_CCM, else -+ * use KEY_COVER_ECB. -+ * -+ * KEY to key1 from @key_addr LENGTH 16 BYTES; -+ * FIFO STORE from key1[ecb] TO @key_addr LENGTH 16 BYTES; -+ * -+ * Note that this variant uses the JDKEK only; it does not accommodate the -+ * trusted key encryption key at this time. -+ * -+ */ -+static int blacken_key_jobdesc(u32 **desc, void *key, u16 keysz, bool auth) -+{ -+ u32 *tdesc, tmpdesc[INITIAL_DESCSZ]; -+ u16 dsize, idx; -+ -+ memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32)); -+ idx = 1; -+ -+ /* Load key to class 1 key register */ -+ tmpdesc[idx++] = CMD_KEY | CLASS_1 | (keysz & KEY_LENGTH_MASK); -+ tmpdesc[idx++] = (uintptr_t)key; -+ -+ /* ...and write back out via FIFO store*/ -+ tmpdesc[idx] = CMD_FIFO_STORE | CLASS_1 | (keysz & KEY_LENGTH_MASK); -+ -+ /* plus account for ECB/CCM option in FIFO_STORE */ -+ if (auth == KEY_COVER_ECB) -+ tmpdesc[idx] |= FIFOST_TYPE_KEY_KEK; -+ else -+ tmpdesc[idx] |= FIFOST_TYPE_KEY_CCM_JKEK; -+ -+ idx++; -+ tmpdesc[idx++] = (uintptr_t)key; -+ -+ /* finish off the job header */ -+ tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK); -+ dsize = idx * sizeof(u32); -+ -+ /* now allocate execution buffer and coat it with executable */ -+ tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA); -+ if (tdesc == NULL) -+ return 0; -+ -+ memcpy(tdesc, tmpdesc, dsize); -+ *desc = tdesc; -+ -+ return dsize; -+} -+ -+/* -+ * Construct a blob encapsulation job descriptor -+ * -+ * This function dynamically constructs a blob encapsulation job descriptor -+ * from the following arguments: -+ * -+ * - desc pointer to a pointer to the descriptor generated by this -+ * function. Caller will be responsible to kfree() this -+ * descriptor after execution. -+ * - keymod Physical pointer to a key modifier, which must reside in a -+ * contiguous piece of memory. Modifier will be assumed to be -+ * 8 bytes long for a blob of type SM_SECMEM, or 16 bytes long -+ * for a blob of type SM_GENMEM (see blobtype argument). -+ * - secretbuf Physical pointer to a secret, normally a black or red key, -+ * possibly residing within an accessible secure memory page, -+ * of the secret to be encapsulated to an output blob. -+ * - outbuf Physical pointer to the destination buffer to receive the -+ * encapsulated output. This buffer will need to be 48 bytes -+ * larger than the input because of the added encapsulation data. -+ * The generated descriptor will account for the increase in size, -+ * but the caller must also account for this increase in the -+ * buffer allocator. -+ * - secretsz Size of input secret, in bytes. This is limited to 65536 -+ * less the size of blob overhead, since the length embeds into -+ * DECO pointer in/out instructions. -+ * - keycolor Determines if the source data is covered (black key) or -+ * plaintext (red key). RED_KEY or BLACK_KEY are defined in -+ * for this purpose. -+ * - blobtype Determine if encapsulated blob should be a secure memory -+ * blob (SM_SECMEM), with partition data embedded with key -+ * material, or a general memory blob (SM_GENMEM). -+ * - auth If BLACK_KEY source is covered via AES-CCM, specify -+ * KEY_COVER_CCM, else uses AES-ECB (KEY_COVER_ECB). -+ * -+ * Upon completion, desc points to a buffer containing a CAAM job -+ * descriptor which encapsulates data into an externally-storable blob -+ * suitable for use across power cycles. -+ * -+ * This is an example of a black key encapsulation job into a general memory -+ * blob. Notice the 16-byte key modifier in the LOAD instruction. Also note -+ * the output 48 bytes longer than the input: -+ * -+ * [00] B0800008 jobhdr: stidx=0 len=8 -+ * [01] 14400010 ld: ccb2-key len=16 offs=0 -+ * [02] 08144891 ptr->@0x08144891 -+ * [03] F800003A seqoutptr: len=58 -+ * [04] 01000000 out_ptr->@0x01000000 -+ * [05] F000000A seqinptr: len=10 -+ * [06] 09745090 in_ptr->@0x09745090 -+ * [07] 870D0004 operation: encap blob reg=memory, black, format=normal -+ * -+ * This is an example of a red key encapsulation job for storing a red key -+ * into a secure memory blob. Note the 8 byte modifier on the 12 byte offset -+ * in the LOAD instruction; this accounts for blob permission storage: -+ * -+ * [00] B0800008 jobhdr: stidx=0 len=8 -+ * [01] 14400C08 ld: ccb2-key len=8 offs=12 -+ * [02] 087D0784 ptr->@0x087d0784 -+ * [03] F8000050 seqoutptr: len=80 -+ * [04] 09251BB2 out_ptr->@0x09251bb2 -+ * [05] F0000020 seqinptr: len=32 -+ * [06] 40000F31 in_ptr->@0x40000f31 -+ * [07] 870D0008 operation: encap blob reg=memory, red, sec_mem, -+ * format=normal -+ * -+ * Note: this function only generates 32-bit pointers at present, and should -+ * be refactored using a scheme that allows both 32 and 64 bit addressing -+ */ -+ -+static int blob_encap_jobdesc(u32 **desc, dma_addr_t keymod, -+ void *secretbuf, dma_addr_t outbuf, -+ u16 secretsz, u8 keycolor, u8 blobtype, u8 auth) -+{ -+ u32 *tdesc, tmpdesc[INITIAL_DESCSZ]; -+ u16 dsize, idx; -+ -+ memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32)); -+ idx = 1; -+ -+ /* -+ * Key modifier works differently for secure/general memory blobs -+ * This accounts for the permission/protection data encapsulated -+ * within the blob if a secure memory blob is requested -+ */ -+ if (blobtype == SM_SECMEM) -+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | -+ LDST_SRCDST_BYTE_KEY | -+ ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK) -+ | (8 & LDST_LEN_MASK); -+ else /* is general memory blob */ -+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | -+ LDST_SRCDST_BYTE_KEY | (16 & LDST_LEN_MASK); -+ -+ tmpdesc[idx++] = (u32)keymod; -+ -+ /* -+ * Encapsulation output must include space for blob key encryption -+ * key and MAC tag -+ */ -+ tmpdesc[idx++] = CMD_SEQ_OUT_PTR | (secretsz + BLOB_OVERHEAD); -+ tmpdesc[idx++] = (u32)outbuf; -+ -+ /* Input data, should be somewhere in secure memory */ -+ tmpdesc[idx++] = CMD_SEQ_IN_PTR | secretsz; -+ tmpdesc[idx++] = (uintptr_t)secretbuf; -+ -+ /* Set blob encap, then color */ -+ tmpdesc[idx] = CMD_OPERATION | OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB; -+ -+ if (blobtype == SM_SECMEM) -+ tmpdesc[idx] |= OP_PCL_BLOB_PTXT_SECMEM; -+ -+ if (auth == KEY_COVER_CCM) -+ tmpdesc[idx] |= OP_PCL_BLOB_EKT; -+ -+ if (keycolor == BLACK_KEY) -+ tmpdesc[idx] |= OP_PCL_BLOB_BLACK; -+ -+ idx++; -+ tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK); -+ dsize = idx * sizeof(u32); -+ -+ tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA); -+ if (tdesc == NULL) -+ return 0; -+ -+ memcpy(tdesc, tmpdesc, dsize); -+ *desc = tdesc; -+ return dsize; -+} -+ -+/* -+ * Construct a blob decapsulation job descriptor -+ * -+ * This function dynamically constructs a blob decapsulation job descriptor -+ * from the following arguments: -+ * -+ * - desc pointer to a pointer to the descriptor generated by this -+ * function. Caller will be responsible to kfree() this -+ * descriptor after execution. -+ * - keymod Physical pointer to a key modifier, which must reside in a -+ * contiguous piece of memory. Modifier will be assumed to be -+ * 8 bytes long for a blob of type SM_SECMEM, or 16 bytes long -+ * for a blob of type SM_GENMEM (see blobtype argument). -+ * - blobbuf Physical pointer (into external memory) of the blob to -+ * be decapsulated. Blob must reside in a contiguous memory -+ * segment. -+ * - outbuf Physical pointer of the decapsulated output, possibly into -+ * a location within a secure memory page. Must be contiguous. -+ * - secretsz Size of encapsulated secret in bytes (not the size of the -+ * input blob). -+ * - keycolor Determines if decapsulated content is encrypted (BLACK_KEY) -+ * or left as plaintext (RED_KEY). -+ * - blobtype Determine if encapsulated blob should be a secure memory -+ * blob (SM_SECMEM), with partition data embedded with key -+ * material, or a general memory blob (SM_GENMEM). -+ * - auth If decapsulation path is specified by BLACK_KEY, then if -+ * AES-CCM is requested for key covering use KEY_COVER_CCM, else -+ * use AES-ECB (KEY_COVER_ECB). -+ * -+ * Upon completion, desc points to a buffer containing a CAAM job descriptor -+ * that decapsulates a key blob from external memory into a black (encrypted) -+ * key or red (plaintext) content. -+ * -+ * This is an example of a black key decapsulation job from a general memory -+ * blob. Notice the 16-byte key modifier in the LOAD instruction. -+ * -+ * [00] B0800008 jobhdr: stidx=0 len=8 -+ * [01] 14400010 ld: ccb2-key len=16 offs=0 -+ * [02] 08A63B7F ptr->@0x08a63b7f -+ * [03] F8000010 seqoutptr: len=16 -+ * [04] 01000000 out_ptr->@0x01000000 -+ * [05] F000003A seqinptr: len=58 -+ * [06] 01000010 in_ptr->@0x01000010 -+ * [07] 860D0004 operation: decap blob reg=memory, black, format=normal -+ * -+ * This is an example of a red key decapsulation job for restoring a red key -+ * from a secure memory blob. Note the 8 byte modifier on the 12 byte offset -+ * in the LOAD instruction: -+ * -+ * [00] B0800008 jobhdr: stidx=0 len=8 -+ * [01] 14400C08 ld: ccb2-key len=8 offs=12 -+ * [02] 01000000 ptr->@0x01000000 -+ * [03] F8000020 seqoutptr: len=32 -+ * [04] 400000E6 out_ptr->@0x400000e6 -+ * [05] F0000050 seqinptr: len=80 -+ * [06] 08F0C0EA in_ptr->@0x08f0c0ea -+ * [07] 860D0008 operation: decap blob reg=memory, red, sec_mem, -+ * format=normal -+ * -+ * Note: this function only generates 32-bit pointers at present, and should -+ * be refactored using a scheme that allows both 32 and 64 bit addressing -+ */ -+ -+static int blob_decap_jobdesc(u32 **desc, dma_addr_t keymod, dma_addr_t blobbuf, -+ u8 *outbuf, u16 secretsz, u8 keycolor, -+ u8 blobtype, u8 auth) -+{ -+ u32 *tdesc, tmpdesc[INITIAL_DESCSZ]; -+ u16 dsize, idx; -+ -+ memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32)); -+ idx = 1; -+ -+ /* Load key modifier */ -+ if (blobtype == SM_SECMEM) -+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | -+ LDST_SRCDST_BYTE_KEY | -+ ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK) -+ | (8 & LDST_LEN_MASK); -+ else /* is general memory blob */ -+ tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | -+ LDST_SRCDST_BYTE_KEY | (16 & LDST_LEN_MASK); -+ -+ tmpdesc[idx++] = (u32)keymod; -+ -+ /* Compensate BKEK + MAC tag over size of encapsulated secret */ -+ tmpdesc[idx++] = CMD_SEQ_IN_PTR | (secretsz + BLOB_OVERHEAD); -+ tmpdesc[idx++] = (u32)blobbuf; -+ tmpdesc[idx++] = CMD_SEQ_OUT_PTR | secretsz; -+ tmpdesc[idx++] = (uintptr_t)outbuf; -+ -+ /* Decapsulate from secure memory partition to black blob */ -+ tmpdesc[idx] = CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB; -+ -+ if (blobtype == SM_SECMEM) -+ tmpdesc[idx] |= OP_PCL_BLOB_PTXT_SECMEM; -+ -+ if (auth == KEY_COVER_CCM) -+ tmpdesc[idx] |= OP_PCL_BLOB_EKT; -+ -+ if (keycolor == BLACK_KEY) -+ tmpdesc[idx] |= OP_PCL_BLOB_BLACK; -+ -+ idx++; -+ tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK); -+ dsize = idx * sizeof(u32); -+ -+ tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA); -+ if (tdesc == NULL) -+ return 0; -+ -+ memcpy(tdesc, tmpdesc, dsize); -+ *desc = tdesc; -+ return dsize; -+} -+ -+/* -+ * Pseudo-synchronous ring access functions for carrying out key -+ * encapsulation and decapsulation -+ */ -+ -+struct sm_key_job_result { -+ int error; -+ struct completion completion; -+}; -+ -+void sm_key_job_done(struct device *dev, u32 *desc, u32 err, void *context) -+{ -+ struct sm_key_job_result *res = context; -+ -+ if (err) -+ caam_jr_strstatus(dev, err); -+ -+ res->error = err; /* save off the error for postprocessing */ -+ -+ complete(&res->completion); /* mark us complete */ -+} -+ -+static int sm_key_job(struct device *ksdev, u32 *jobdesc) -+{ -+ struct sm_key_job_result testres = {0}; -+ struct caam_drv_private_sm *kspriv; -+ int rtn = 0; -+ -+ kspriv = dev_get_drvdata(ksdev); -+ -+ init_completion(&testres.completion); -+ -+ rtn = caam_jr_enqueue(kspriv->smringdev, jobdesc, sm_key_job_done, -+ &testres); -+ if (rtn) -+ goto exit; -+ -+ wait_for_completion_interruptible(&testres.completion); -+ rtn = testres.error; -+ -+exit: -+ return rtn; -+} -+ -+/* -+ * Following section establishes the default methods for keystore access -+ * They are NOT intended for use external to this module -+ * -+ * In the present version, these are the only means for the higher-level -+ * interface to deal with the mechanics of accessing the phyiscal keystore -+ */ -+ -+ -+int slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata; -+ u32 i; -+#ifdef SM_DEBUG -+ dev_info(dev, "slot_alloc(): requesting slot for %d bytes\n", size); -+#endif -+ -+ if (size > smpriv->slot_size) -+ return -EKEYREJECTED; -+ -+ for (i = 0; i < ksdata->slot_count; i++) { -+ if (ksdata->slot[i].allocated == 0) { -+ ksdata->slot[i].allocated = 1; -+ (*slot) = i; -+#ifdef SM_DEBUG -+ dev_info(dev, "slot_alloc(): new slot %d allocated\n", -+ *slot); -+#endif -+ return 0; -+ } -+ } -+ -+ return -ENOSPC; -+} -+EXPORT_SYMBOL(slot_alloc); -+ -+int slot_dealloc(struct device *dev, u32 unit, u32 slot) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata; -+ u8 __iomem *slotdata; -+ -+#ifdef SM_DEBUG -+ dev_info(dev, "slot_dealloc(): releasing slot %d\n", slot); -+#endif -+ if (slot >= ksdata->slot_count) -+ return -EINVAL; -+ slotdata = ksdata->base_address + slot * smpriv->slot_size; -+ -+ if (ksdata->slot[slot].allocated == 1) { -+ /* Forcibly overwrite the data from the keystore */ -+ memset_io(ksdata->base_address + slot * smpriv->slot_size, 0, -+ smpriv->slot_size); -+ -+ ksdata->slot[slot].allocated = 0; -+#ifdef SM_DEBUG -+ dev_info(dev, "slot_dealloc(): slot %d released\n", slot); -+#endif -+ return 0; -+ } -+ -+ return -EINVAL; -+} -+EXPORT_SYMBOL(slot_dealloc); -+ -+void *slot_get_address(struct device *dev, u32 unit, u32 slot) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata; -+ -+ if (slot >= ksdata->slot_count) -+ return NULL; -+ -+#ifdef SM_DEBUG -+ dev_info(dev, "slot_get_address(): slot %d is 0x%08x\n", slot, -+ (u32)ksdata->base_address + slot * smpriv->slot_size); -+#endif -+ -+ return ksdata->base_address + slot * smpriv->slot_size; -+} -+ -+void *slot_get_physical(struct device *dev, u32 unit, u32 slot) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata; -+ -+ if (slot >= ksdata->slot_count) -+ return NULL; -+ -+#ifdef SM_DEBUG -+ dev_info(dev, "%s: slot %d is 0x%08x\n", __func__, slot, -+ (u32)ksdata->phys_address + slot * smpriv->slot_size); -+#endif -+ -+ return ksdata->phys_address + slot * smpriv->slot_size; -+} -+ -+u32 slot_get_base(struct device *dev, u32 unit, u32 slot) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata; -+ -+ /* -+ * There could potentially be more than one secure partition object -+ * associated with this keystore. For now, there is just one. -+ */ -+ -+ (void)slot; -+ -+#ifdef SM_DEBUG -+ dev_info(dev, "slot_get_base(): slot %d = 0x%08x\n", -+ slot, (u32)ksdata->base_address); -+#endif -+ -+ return (uintptr_t)(ksdata->base_address); -+} -+ -+u32 slot_get_offset(struct device *dev, u32 unit, u32 slot) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ struct keystore_data *ksdata = smpriv->pagedesc[unit].ksdata; -+ -+ if (slot >= ksdata->slot_count) -+ return -EINVAL; -+ -+#ifdef SM_DEBUG -+ dev_info(dev, "slot_get_offset(): slot %d = %d\n", slot, -+ slot * smpriv->slot_size); -+#endif -+ -+ return slot * smpriv->slot_size; -+} -+ -+u32 slot_get_slot_size(struct device *dev, u32 unit, u32 slot) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ -+ -+#ifdef SM_DEBUG -+ dev_info(dev, "slot_get_slot_size(): slot %d = %d\n", slot, -+ smpriv->slot_size); -+#endif -+ /* All slots are the same size in the default implementation */ -+ return smpriv->slot_size; -+} -+ -+ -+ -+int kso_init_data(struct device *dev, u32 unit) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ struct keystore_data *keystore_data = NULL; -+ u32 slot_count; -+ u32 keystore_data_size; -+ -+ /* -+ * Calculate the required size of the keystore data structure, based -+ * on the number of keys that can fit in the partition. -+ */ -+ slot_count = smpriv->page_size / smpriv->slot_size; -+#ifdef SM_DEBUG -+ dev_info(dev, "kso_init_data: %d slots initializing\n", slot_count); -+#endif -+ -+ keystore_data_size = sizeof(struct keystore_data) + -+ slot_count * -+ sizeof(struct keystore_data_slot_info); -+ -+ keystore_data = kzalloc(keystore_data_size, GFP_KERNEL); -+ -+ if (!keystore_data) -+ return -ENOMEM; -+ -+#ifdef SM_DEBUG -+ dev_info(dev, "kso_init_data: keystore data size = %d\n", -+ keystore_data_size); -+#endif -+ -+ /* -+ * Place the slot information structure directly after the keystore data -+ * structure. -+ */ -+ keystore_data->slot = (struct keystore_data_slot_info *) -+ (keystore_data + 1); -+ keystore_data->slot_count = slot_count; -+ -+ smpriv->pagedesc[unit].ksdata = keystore_data; -+ smpriv->pagedesc[unit].ksdata->base_address = -+ smpriv->pagedesc[unit].pg_base; -+ smpriv->pagedesc[unit].ksdata->phys_address = -+ smpriv->pagedesc[unit].pg_phys; -+ -+ return 0; -+} -+ -+void kso_cleanup_data(struct device *dev, u32 unit) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ struct keystore_data *keystore_data = NULL; -+ -+ if (smpriv->pagedesc[unit].ksdata != NULL) -+ keystore_data = smpriv->pagedesc[unit].ksdata; -+ -+ /* Release the allocated keystore management data */ -+ kfree(smpriv->pagedesc[unit].ksdata); -+ -+ return; -+} -+ -+ -+ -+/* -+ * Keystore management section -+ */ -+ -+void sm_init_keystore(struct device *dev) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ -+ smpriv->data_init = kso_init_data; -+ smpriv->data_cleanup = kso_cleanup_data; -+ smpriv->slot_alloc = slot_alloc; -+ smpriv->slot_dealloc = slot_dealloc; -+ smpriv->slot_get_address = slot_get_address; -+ smpriv->slot_get_physical = slot_get_physical; -+ smpriv->slot_get_base = slot_get_base; -+ smpriv->slot_get_offset = slot_get_offset; -+ smpriv->slot_get_slot_size = slot_get_slot_size; -+#ifdef SM_DEBUG -+ dev_info(dev, "sm_init_keystore(): handlers installed\n"); -+#endif -+} -+EXPORT_SYMBOL(sm_init_keystore); -+ -+/* Return available pages/units */ -+u32 sm_detect_keystore_units(struct device *dev) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ -+ return smpriv->localpages; -+} -+EXPORT_SYMBOL(sm_detect_keystore_units); -+ -+/* -+ * Do any keystore specific initializations -+ */ -+int sm_establish_keystore(struct device *dev, u32 unit) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ -+#ifdef SM_DEBUG -+ dev_info(dev, "sm_establish_keystore(): unit %d initializing\n", unit); -+#endif -+ -+ if (smpriv->data_init == NULL) -+ return -EINVAL; -+ -+ /* Call the data_init function for any user setup */ -+ return smpriv->data_init(dev, unit); -+} -+EXPORT_SYMBOL(sm_establish_keystore); -+ -+void sm_release_keystore(struct device *dev, u32 unit) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ -+#ifdef SM_DEBUG -+ dev_info(dev, "sm_establish_keystore(): unit %d releasing\n", unit); -+#endif -+ if ((smpriv != NULL) && (smpriv->data_cleanup != NULL)) -+ smpriv->data_cleanup(dev, unit); -+ -+ return; -+} -+EXPORT_SYMBOL(sm_release_keystore); -+ -+/* -+ * Subsequent interfacce (sm_keystore_*) forms the accessor interfacce to -+ * the keystore -+ */ -+int sm_keystore_slot_alloc(struct device *dev, u32 unit, u32 size, u32 *slot) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ int retval = -EINVAL; -+ -+ spin_lock(&smpriv->kslock); -+ -+ if ((smpriv->slot_alloc == NULL) || -+ (smpriv->pagedesc[unit].ksdata == NULL)) -+ goto out; -+ -+ retval = smpriv->slot_alloc(dev, unit, size, slot); -+ -+out: -+ spin_unlock(&smpriv->kslock); -+ return retval; -+} -+EXPORT_SYMBOL(sm_keystore_slot_alloc); -+ -+int sm_keystore_slot_dealloc(struct device *dev, u32 unit, u32 slot) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ int retval = -EINVAL; -+ -+ spin_lock(&smpriv->kslock); -+ -+ if ((smpriv->slot_alloc == NULL) || -+ (smpriv->pagedesc[unit].ksdata == NULL)) -+ goto out; -+ -+ retval = smpriv->slot_dealloc(dev, unit, slot); -+out: -+ spin_unlock(&smpriv->kslock); -+ return retval; -+} -+EXPORT_SYMBOL(sm_keystore_slot_dealloc); -+ -+int sm_keystore_slot_load(struct device *dev, u32 unit, u32 slot, -+ const u8 *key_data, u32 key_length) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ int retval = -EINVAL; -+ u32 slot_size; -+ u8 __iomem *slot_location; -+ -+ spin_lock(&smpriv->kslock); -+ -+ slot_size = smpriv->slot_get_slot_size(dev, unit, slot); -+ -+ if (key_length > slot_size) { -+ retval = -EFBIG; -+ goto out; -+ } -+ -+ slot_location = smpriv->slot_get_address(dev, unit, slot); -+ -+ memcpy_toio(slot_location, key_data, key_length); -+ -+ retval = 0; -+ -+out: -+ spin_unlock(&smpriv->kslock); -+ return retval; -+} -+EXPORT_SYMBOL(sm_keystore_slot_load); -+ -+int sm_keystore_slot_read(struct device *dev, u32 unit, u32 slot, -+ u32 key_length, u8 *key_data) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ int retval = -EINVAL; -+ u8 __iomem *slot_addr; -+ u32 slot_size; -+ -+ spin_lock(&smpriv->kslock); -+ -+ slot_addr = smpriv->slot_get_address(dev, unit, slot); -+ slot_size = smpriv->slot_get_slot_size(dev, unit, slot); -+ -+ if (key_length > slot_size) { -+ retval = -EKEYREJECTED; -+ goto out; -+ } -+ -+ memcpy_fromio(key_data, slot_addr, key_length); -+ retval = 0; -+ -+out: -+ spin_unlock(&smpriv->kslock); -+ return retval; -+} -+EXPORT_SYMBOL(sm_keystore_slot_read); -+ -+/* -+ * Blacken a clear key in a slot. Operates "in place". -+ * Limited to class 1 keys at the present time -+ */ -+int sm_keystore_cover_key(struct device *dev, u32 unit, u32 slot, -+ u16 key_length, u8 keyauth) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ int retval = 0; -+ u8 __iomem *slotaddr; -+ void *slotphys; -+ u32 dsize, jstat; -+ u32 __iomem *coverdesc = NULL; -+ -+ /* Get the address of the object in the slot */ -+ slotaddr = (u8 *)smpriv->slot_get_address(dev, unit, slot); -+ slotphys = (u8 *)smpriv->slot_get_physical(dev, unit, slot); -+ -+ dsize = blacken_key_jobdesc(&coverdesc, slotphys, key_length, keyauth); -+ if (!dsize) -+ return -ENOMEM; -+ jstat = sm_key_job(dev, coverdesc); -+ if (jstat) -+ retval = -EIO; -+ -+ kfree(coverdesc); -+ return retval; -+} -+EXPORT_SYMBOL(sm_keystore_cover_key); -+ -+/* Export a black/red key to a blob in external memory */ -+int sm_keystore_slot_export(struct device *dev, u32 unit, u32 slot, u8 keycolor, -+ u8 keyauth, u8 *outbuf, u16 keylen, u8 *keymod) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ int retval = 0; -+ u8 __iomem *slotaddr, *lkeymod; -+ u8 __iomem *slotphys; -+ dma_addr_t keymod_dma, outbuf_dma; -+ u32 dsize, jstat; -+ u32 __iomem *encapdesc = NULL; -+ struct device *dev_for_dma_op; -+ -+ /* Use the ring as device for DMA operations */ -+ dev_for_dma_op = smpriv->smringdev; -+ -+ /* Get the base address(es) of the specified slot */ -+ slotaddr = (u8 *)smpriv->slot_get_address(dev, unit, slot); -+ slotphys = smpriv->slot_get_physical(dev, unit, slot); -+ -+ /* Allocate memory for key modifier compatible with DMA */ -+ lkeymod = kmalloc(SECMEM_KEYMOD_LEN, GFP_KERNEL | GFP_DMA); -+ if (!lkeymod) { -+ retval = (-ENOMEM); -+ goto exit; -+ } -+ -+ /* Get DMA address for the key modifier */ -+ keymod_dma = dma_map_single(dev_for_dma_op, lkeymod, -+ SECMEM_KEYMOD_LEN, DMA_TO_DEVICE); -+ if (dma_mapping_error(dev_for_dma_op, keymod_dma)) { -+ dev_err(dev, "unable to map keymod: %p\n", lkeymod); -+ retval = (-ENOMEM); -+ goto free_keymod; -+ } -+ -+ /* Copy the keymod and synchronize the DMA */ -+ memcpy(lkeymod, keymod, SECMEM_KEYMOD_LEN); -+ dma_sync_single_for_device(dev_for_dma_op, keymod_dma, -+ SECMEM_KEYMOD_LEN, DMA_TO_DEVICE); -+ -+ /* Get DMA address for the destination */ -+ outbuf_dma = dma_map_single(dev_for_dma_op, outbuf, -+ keylen + BLOB_OVERHEAD, DMA_FROM_DEVICE); -+ if (dma_mapping_error(dev_for_dma_op, outbuf_dma)) { -+ dev_err(dev, "unable to map outbuf: %p\n", outbuf); -+ retval = (-ENOMEM); -+ goto unmap_keymod; -+ } -+ -+ /* Build the encapsulation job descriptor */ -+ dsize = blob_encap_jobdesc(&encapdesc, keymod_dma, slotphys, outbuf_dma, -+ keylen, keycolor, SM_SECMEM, keyauth); -+ if (!dsize) { -+ dev_err(dev, "can't alloc an encapsulation descriptor\n"); -+ retval = -ENOMEM; -+ goto unmap_outbuf; -+ } -+ -+ /* Run the job */ -+ jstat = sm_key_job(dev, encapdesc); -+ if (jstat) { -+ retval = (-EIO); -+ goto free_desc; -+ } -+ -+ /* Synchronize the data received */ -+ dma_sync_single_for_cpu(dev_for_dma_op, outbuf_dma, -+ keylen + BLOB_OVERHEAD, DMA_FROM_DEVICE); -+ -+free_desc: -+ kfree(encapdesc); -+ -+unmap_outbuf: -+ dma_unmap_single(dev_for_dma_op, outbuf_dma, keylen + BLOB_OVERHEAD, -+ DMA_FROM_DEVICE); -+ -+unmap_keymod: -+ dma_unmap_single(dev_for_dma_op, keymod_dma, SECMEM_KEYMOD_LEN, -+ DMA_TO_DEVICE); -+ -+free_keymod: -+ kfree(lkeymod); -+ -+exit: -+ return retval; -+} -+EXPORT_SYMBOL(sm_keystore_slot_export); -+ -+/* Import a black/red key from a blob residing in external memory */ -+int sm_keystore_slot_import(struct device *dev, u32 unit, u32 slot, u8 keycolor, -+ u8 keyauth, u8 *inbuf, u16 keylen, u8 *keymod) -+{ -+ struct caam_drv_private_sm *smpriv = dev_get_drvdata(dev); -+ int retval = 0; -+ u8 __iomem *slotaddr, *lkeymod; -+ u8 __iomem *slotphys; -+ dma_addr_t keymod_dma, inbuf_dma; -+ u32 dsize, jstat; -+ u32 __iomem *decapdesc = NULL; -+ struct device *dev_for_dma_op; -+ -+ /* Use the ring as device for DMA operations */ -+ dev_for_dma_op = smpriv->smringdev; -+ -+ /* Get the base address(es) of the specified slot */ -+ slotaddr = (u8 *)smpriv->slot_get_address(dev, unit, slot); -+ slotphys = smpriv->slot_get_physical(dev, unit, slot); -+ -+ /* Allocate memory for key modifier compatible with DMA */ -+ lkeymod = kmalloc(SECMEM_KEYMOD_LEN, GFP_KERNEL | GFP_DMA); -+ if (!lkeymod) { -+ retval = (-ENOMEM); -+ goto exit; -+ } -+ -+ /* Get DMA address for the key modifier */ -+ keymod_dma = dma_map_single(dev_for_dma_op, lkeymod, -+ SECMEM_KEYMOD_LEN, DMA_TO_DEVICE); -+ if (dma_mapping_error(dev_for_dma_op, keymod_dma)) { -+ dev_err(dev, "unable to map keymod: %p\n", lkeymod); -+ retval = (-ENOMEM); -+ goto free_keymod; -+ } -+ -+ /* Copy the keymod and synchronize the DMA */ -+ memcpy(lkeymod, keymod, SECMEM_KEYMOD_LEN); -+ dma_sync_single_for_device(dev_for_dma_op, keymod_dma, -+ SECMEM_KEYMOD_LEN, DMA_TO_DEVICE); -+ -+ /* Get DMA address for the input */ -+ inbuf_dma = dma_map_single(dev_for_dma_op, inbuf, -+ keylen + BLOB_OVERHEAD, DMA_TO_DEVICE); -+ if (dma_mapping_error(dev_for_dma_op, inbuf_dma)) { -+ dev_err(dev, "unable to map inbuf: %p\n", (void *)inbuf_dma); -+ retval = (-ENOMEM); -+ goto unmap_keymod; -+ } -+ -+ /* synchronize the DMA */ -+ dma_sync_single_for_device(dev_for_dma_op, inbuf_dma, -+ keylen + BLOB_OVERHEAD, DMA_TO_DEVICE); -+ -+ /* Build the encapsulation job descriptor */ -+ dsize = blob_decap_jobdesc(&decapdesc, keymod_dma, inbuf_dma, slotphys, -+ keylen, keycolor, SM_SECMEM, keyauth); -+ if (!dsize) { -+ dev_err(dev, "can't alloc a decapsulation descriptor\n"); -+ retval = -ENOMEM; -+ goto unmap_inbuf; -+ } -+ -+ /* Run the job */ -+ jstat = sm_key_job(dev, decapdesc); -+ -+ /* -+ * May want to expand upon error meanings a bit. Any CAAM status -+ * is reported as EIO, but we might want to look for something more -+ * meaningful for something like an ICV error on restore, otherwise -+ * the caller is left guessing. -+ */ -+ if (jstat) { -+ retval = (-EIO); -+ goto free_desc; -+ } -+ -+free_desc: -+ kfree(decapdesc); -+ -+unmap_inbuf: -+ dma_unmap_single(dev_for_dma_op, inbuf_dma, keylen + BLOB_OVERHEAD, -+ DMA_TO_DEVICE); -+ -+unmap_keymod: -+ dma_unmap_single(dev_for_dma_op, keymod_dma, SECMEM_KEYMOD_LEN, -+ DMA_TO_DEVICE); -+ -+free_keymod: -+ kfree(lkeymod); -+ -+exit: -+ return retval; -+} -+EXPORT_SYMBOL(sm_keystore_slot_import); -+ -+/* -+ * Initialization/shutdown subsystem -+ * Assumes statically-invoked startup/shutdown from the controller driver -+ * for the present time, to be reworked when a device tree becomes -+ * available. This code will not modularize in present form. -+ * -+ * Also, simply uses ring 0 for execution at the present -+ */ -+ -+int caam_sm_startup(struct platform_device *pdev) -+{ -+ struct device *ctrldev, *smdev; -+ struct caam_drv_private *ctrlpriv; -+ struct caam_drv_private_sm *smpriv; -+ struct caam_drv_private_jr *jrpriv; /* need this for reg page */ -+ struct platform_device *sm_pdev; -+ struct sm_page_descriptor *lpagedesc; -+ u32 page, pgstat, lpagect, detectedpage, smvid, smpart; -+ int ret = 0; -+ -+ struct device_node *np; -+ ctrldev = &pdev->dev; -+ ctrlpriv = dev_get_drvdata(ctrldev); -+ -+ /* -+ * If ctrlpriv is NULL, it's probably because the caam driver wasn't -+ * properly initialized (e.g. RNG4 init failed). Thus, bail out here. -+ */ -+ if (!ctrlpriv) { -+ ret = -ENODEV; -+ goto exit; -+ } -+ -+ /* -+ * Set up the private block for secure memory -+ * Only one instance is possible -+ */ -+ smpriv = kzalloc(sizeof(struct caam_drv_private_sm), GFP_KERNEL); -+ if (smpriv == NULL) { -+ dev_err(ctrldev, "can't alloc private mem for secure memory\n"); -+ ret = -ENOMEM; -+ goto exit; -+ } -+ smpriv->parentdev = ctrldev; /* copy of parent dev is handy */ -+ spin_lock_init(&smpriv->kslock); -+ -+ /* Create the dev */ -+ np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-caam-sm"); -+ if (np) -+ of_node_clear_flag(np, OF_POPULATED); -+ sm_pdev = of_platform_device_create(np, "caam_sm", ctrldev); -+ -+ if (sm_pdev == NULL) { -+ ret = -EINVAL; -+ goto free_smpriv; -+ } -+ -+ /* Save a pointer to the platform device for Secure Memory */ -+ smpriv->sm_pdev = sm_pdev; -+ smdev = &sm_pdev->dev; -+ dev_set_drvdata(smdev, smpriv); -+ ctrlpriv->smdev = smdev; -+ -+ /* Set the Secure Memory Register Map Version */ -+ smvid = rd_reg32(&ctrlpriv->jr[0]->perfmon.smvid); -+ smpart = rd_reg32(&ctrlpriv->jr[0]->perfmon.smpart); -+ -+ if (smvid < SMVID_V2) -+ smpriv->sm_reg_offset = SM_V1_OFFSET; -+ else -+ smpriv->sm_reg_offset = SM_V2_OFFSET; -+ -+ /* -+ * Collect configuration limit data for reference -+ * This batch comes from the partition data/vid registers in perfmon -+ */ -+ smpriv->max_pages = ((smpart & SMPART_MAX_NUMPG_MASK) >> -+ SMPART_MAX_NUMPG_SHIFT) + 1; -+ smpriv->top_partition = ((smpart & SMPART_MAX_PNUM_MASK) >> -+ SMPART_MAX_PNUM_SHIFT) + 1; -+ smpriv->top_page = ((smpart & SMPART_MAX_PG_MASK) >> -+ SMPART_MAX_PG_SHIFT) + 1; -+ smpriv->page_size = 1024 << ((smvid & SMVID_PG_SIZE_MASK) >> -+ SMVID_PG_SIZE_SHIFT); -+ smpriv->slot_size = 1 << CONFIG_CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE; -+ -+#ifdef SM_DEBUG -+ dev_info(smdev, "max pages = %d, top partition = %d\n", -+ smpriv->max_pages, smpriv->top_partition); -+ dev_info(smdev, "top page = %d, page size = %d (total = %d)\n", -+ smpriv->top_page, smpriv->page_size, -+ smpriv->top_page * smpriv->page_size); -+ dev_info(smdev, "selected slot size = %d\n", smpriv->slot_size); -+#endif -+ -+ /* -+ * Now probe for partitions/pages to which we have access. Note that -+ * these have likely been set up by a bootloader or platform -+ * provisioning application, so we have to assume that we "inherit" -+ * a configuration and work within the constraints of what it might be. -+ * -+ * Assume use of the zeroth ring in the present iteration (until -+ * we can divorce the controller and ring drivers, and then assign -+ * an SM instance to any ring instance). -+ */ -+ smpriv->smringdev = caam_jr_alloc(); -+ if (!smpriv->smringdev) { -+ dev_err(smdev, "Device for job ring not created\n"); -+ ret = -ENODEV; -+ goto unregister_smpdev; -+ } -+ -+ jrpriv = dev_get_drvdata(smpriv->smringdev); -+ lpagect = 0; -+ pgstat = 0; -+ lpagedesc = kzalloc(sizeof(struct sm_page_descriptor) -+ * smpriv->max_pages, GFP_KERNEL); -+ if (lpagedesc == NULL) { -+ ret = -ENOMEM; -+ goto free_smringdev; -+ } -+ -+ for (page = 0; page < smpriv->max_pages; page++) { -+ u32 page_ownership; -+ -+ if (sm_send_cmd(smpriv, jrpriv, -+ ((page << SMC_PAGE_SHIFT) & SMC_PAGE_MASK) | -+ (SMC_CMD_PAGE_INQUIRY & SMC_CMD_MASK), -+ &pgstat)) { -+ ret = -EINVAL; -+ goto free_lpagedesc; -+ } -+ -+ page_ownership = (pgstat & SMCS_PGWON_MASK) >> SMCS_PGOWN_SHIFT; -+ if ((page_ownership == SMCS_PGOWN_OWNED) -+ || (page_ownership == SMCS_PGOWN_NOOWN)) { -+ /* page allocated */ -+ lpagedesc[page].phys_pagenum = -+ (pgstat & SMCS_PAGE_MASK) >> SMCS_PAGE_SHIFT; -+ lpagedesc[page].own_part = -+ (pgstat & SMCS_PART_SHIFT) >> SMCS_PART_MASK; -+ lpagedesc[page].pg_base = (u8 *)ctrlpriv->sm_base + -+ (smpriv->page_size * page); -+ if (ctrlpriv->scu_en) { -+/* FIXME: get different addresses viewed by CPU and CAAM from -+ * platform property -+ */ -+ lpagedesc[page].pg_phys = (u8 *)0x20800000 + -+ (smpriv->page_size * page); -+ } else { -+ lpagedesc[page].pg_phys = -+ (u8 *) ctrlpriv->sm_phy + -+ (smpriv->page_size * page); -+ } -+ lpagect++; -+#ifdef SM_DEBUG -+ dev_info(smdev, -+ "physical page %d, owning partition = %d\n", -+ lpagedesc[page].phys_pagenum, -+ lpagedesc[page].own_part); -+#endif -+ } -+ } -+ -+ smpriv->pagedesc = kzalloc(sizeof(struct sm_page_descriptor) * lpagect, -+ GFP_KERNEL); -+ if (smpriv->pagedesc == NULL) { -+ ret = -ENOMEM; -+ goto free_lpagedesc; -+ } -+ smpriv->localpages = lpagect; -+ -+ detectedpage = 0; -+ for (page = 0; page < smpriv->max_pages; page++) { -+ if (lpagedesc[page].pg_base != NULL) { /* e.g. live entry */ -+ memcpy(&smpriv->pagedesc[detectedpage], -+ &lpagedesc[page], -+ sizeof(struct sm_page_descriptor)); -+#ifdef SM_DEBUG_CONT -+ sm_show_page(smdev, &smpriv->pagedesc[detectedpage]); -+#endif -+ detectedpage++; -+ } -+ } -+ -+ kfree(lpagedesc); -+ -+ sm_init_keystore(smdev); -+ -+ goto exit; -+ -+free_lpagedesc: -+ kfree(lpagedesc); -+free_smringdev: -+ caam_jr_free(smpriv->smringdev); -+unregister_smpdev: -+ of_device_unregister(smpriv->sm_pdev); -+free_smpriv: -+ kfree(smpriv); -+ -+exit: -+ return ret; -+} -+ -+void caam_sm_shutdown(struct platform_device *pdev) -+{ -+ struct device *ctrldev, *smdev; -+ struct caam_drv_private *priv; -+ struct caam_drv_private_sm *smpriv; -+ -+ ctrldev = &pdev->dev; -+ priv = dev_get_drvdata(ctrldev); -+ smdev = priv->smdev; -+ -+ /* Return if resource not initialized by startup */ -+ if (smdev == NULL) -+ return; -+ -+ smpriv = dev_get_drvdata(smdev); -+ -+ caam_jr_free(smpriv->smringdev); -+ -+ /* Remove Secure Memory Platform Device */ -+ of_device_unregister(smpriv->sm_pdev); -+ -+ kfree(smpriv->pagedesc); -+ kfree(smpriv); -+} -+EXPORT_SYMBOL(caam_sm_shutdown); -+ -+static void __exit caam_sm_exit(void) -+{ -+ struct device_node *dev_node; -+ struct platform_device *pdev; -+ -+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); -+ if (!dev_node) { -+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); -+ if (!dev_node) -+ return; -+ } -+ -+ pdev = of_find_device_by_node(dev_node); -+ if (!pdev) -+ return; -+ -+ of_node_put(dev_node); -+ -+ caam_sm_shutdown(pdev); -+ -+ return; -+} -+ -+static int __init caam_sm_init(void) -+{ -+ struct device_node *dev_node; -+ struct platform_device *pdev; -+ -+ /* -+ * Do of_find_compatible_node() then of_find_device_by_node() -+ * once a functional device tree is available -+ */ -+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); -+ if (!dev_node) { -+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); -+ if (!dev_node) -+ return -ENODEV; -+ } -+ -+ pdev = of_find_device_by_node(dev_node); -+ if (!pdev) -+ return -ENODEV; -+ -+ of_node_get(dev_node); -+ -+ caam_sm_startup(pdev); -+ -+ return 0; -+} -+ -+module_init(caam_sm_init); -+module_exit(caam_sm_exit); -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("FSL CAAM Secure Memory / Keystore"); -+MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD"); ---- /dev/null -+++ b/drivers/crypto/caam/sm_test.c -@@ -0,0 +1,571 @@ -+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) -+/* -+ * Secure Memory / Keystore Exemplification Module -+ * -+ * Copyright 2012-2015 Freescale Semiconductor, Inc. -+ * Copyright 2016-2019 NXP -+ * -+ * This module has been overloaded as an example to show: -+ * - Secure memory subsystem initialization/shutdown -+ * - Allocation/deallocation of "slots" in a secure memory page -+ * - Loading and unloading of key material into slots -+ * - Covering of secure memory objects into "black keys" (ECB only at present) -+ * - Verification of key covering (by differentiation only) -+ * - Exportation of keys into secure memory blobs (with display of result) -+ * - Importation of keys from secure memory blobs (with display of result) -+ * - Verification of re-imported keys where possible. -+ * -+ * The module does not show the use of key objects as working key register -+ * source material at this time. -+ * -+ * This module can use a substantial amount of refactoring, which may occur -+ * after the API gets some mileage. Furthermore, expect this module to -+ * eventually disappear once the API is integrated into "real" software. -+ */ -+ -+#include "compat.h" -+#include "regs.h" -+#include "intern.h" -+#include "desc.h" -+#include "error.h" -+#include "jr.h" -+#include "sm.h" -+ -+/* Fixed known pattern for a key modifier */ -+static u8 skeymod[] = { -+ 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, -+ 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 -+}; -+ -+/* Fixed known pattern for a key */ -+static u8 clrkey[] = { -+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x0f, 0x06, 0x07, -+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, -+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, -+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, -+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, -+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, -+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, -+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, -+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, -+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, -+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, -+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, -+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, -+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, -+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, -+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, -+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, -+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, -+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, -+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, -+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, -+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, -+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, -+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, -+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, -+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, -+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, -+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, -+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, -+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, -+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, -+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -+}; -+ -+static void key_display(struct device *dev, const char *label, u16 size, -+ u8 *key) -+{ -+ unsigned i; -+ -+ dev_dbg(dev, "%s", label); -+ for (i = 0; i < size; i += 8) -+ dev_dbg(dev, -+ "[%04d] %02x %02x %02x %02x %02x %02x %02x %02x\n", -+ i, key[i], key[i + 1], key[i + 2], key[i + 3], -+ key[i + 4], key[i + 5], key[i + 6], key[i + 7]); -+} -+ -+int caam_sm_example_init(struct platform_device *pdev) -+{ -+ struct device *ctrldev, *ksdev; -+ struct caam_drv_private *ctrlpriv; -+ struct caam_drv_private_sm *kspriv; -+ u32 unit, units; -+ int rtnval; -+ u8 clrkey8[8], clrkey16[16], clrkey24[24], clrkey32[32]; -+ u8 blkkey8[AES_BLOCK_PAD(8)], blkkey16[AES_BLOCK_PAD(16)]; -+ u8 blkkey24[AES_BLOCK_PAD(24)], blkkey32[AES_BLOCK_PAD(32)]; -+ u8 rstkey8[AES_BLOCK_PAD(8)], rstkey16[AES_BLOCK_PAD(16)]; -+ u8 rstkey24[AES_BLOCK_PAD(24)], rstkey32[AES_BLOCK_PAD(32)]; -+ u8 __iomem *blob8, *blob16, *blob24, *blob32; -+ u32 keyslot8, keyslot16, keyslot24, keyslot32 = 0; -+ -+ blob8 = blob16 = blob24 = blob32 = NULL; -+ -+ /* -+ * 3.5.x and later revs for MX6 should be able to ditch this -+ * and detect via dts property -+ */ -+ ctrldev = &pdev->dev; -+ ctrlpriv = dev_get_drvdata(ctrldev); -+ -+ /* -+ * If ctrlpriv is NULL, it's probably because the caam driver wasn't -+ * properly initialized (e.g. RNG4 init failed). Thus, bail out here. -+ */ -+ if (!ctrlpriv) -+ return -ENODEV; -+ -+ ksdev = ctrlpriv->smdev; -+ kspriv = dev_get_drvdata(ksdev); -+ if (kspriv == NULL) -+ return -ENODEV; -+ -+ /* What keystores are available ? */ -+ units = sm_detect_keystore_units(ksdev); -+ if (!units) -+ dev_err(ksdev, "blkkey_ex: no keystore units available\n"); -+ -+ /* -+ * MX6 bootloader stores some stuff in unit 0, so let's -+ * use 1 or above -+ */ -+ if (units < 2) { -+ dev_err(ksdev, "blkkey_ex: insufficient keystore units\n"); -+ return -ENODEV; -+ } -+ unit = 1; -+ -+ dev_info(ksdev, "blkkey_ex: %d keystore units available\n", units); -+ -+ /* Initialize/Establish Keystore */ -+ sm_establish_keystore(ksdev, unit); /* Initalize store in #1 */ -+ -+ /* -+ * Now let's set up buffers for blobs in DMA-able memory. All are -+ * larger than need to be so that blob size can be seen. -+ */ -+ blob8 = kzalloc(128, GFP_KERNEL | GFP_DMA); -+ blob16 = kzalloc(128, GFP_KERNEL | GFP_DMA); -+ blob24 = kzalloc(128, GFP_KERNEL | GFP_DMA); -+ blob32 = kzalloc(128, GFP_KERNEL | GFP_DMA); -+ -+ if ((blob8 == NULL) || (blob16 == NULL) || (blob24 == NULL) || -+ (blob32 == NULL)) { -+ rtnval = -ENOMEM; -+ dev_err(ksdev, "blkkey_ex: can't get blob buffers\n"); -+ goto freemem; -+ } -+ -+ /* Initialize clear keys with a known and recognizable pattern */ -+ memcpy(clrkey8, clrkey, 8); -+ memcpy(clrkey16, clrkey, 16); -+ memcpy(clrkey24, clrkey, 24); -+ memcpy(clrkey32, clrkey, 32); -+ -+ memset(blkkey8, 0, AES_BLOCK_PAD(8)); -+ memset(blkkey16, 0, AES_BLOCK_PAD(16)); -+ memset(blkkey24, 0, AES_BLOCK_PAD(24)); -+ memset(blkkey32, 0, AES_BLOCK_PAD(32)); -+ -+ memset(rstkey8, 0, AES_BLOCK_PAD(8)); -+ memset(rstkey16, 0, AES_BLOCK_PAD(16)); -+ memset(rstkey24, 0, AES_BLOCK_PAD(24)); -+ memset(rstkey32, 0, AES_BLOCK_PAD(32)); -+ -+ /* -+ * Allocate keyslots. Since we're going to blacken keys in-place, -+ * we want slots big enough to pad out to the next larger AES blocksize -+ * so pad them out. -+ */ -+ rtnval = sm_keystore_slot_alloc(ksdev, unit, AES_BLOCK_PAD(8), -+ &keyslot8); -+ if (rtnval) -+ goto freemem; -+ -+ rtnval = sm_keystore_slot_alloc(ksdev, unit, AES_BLOCK_PAD(16), -+ &keyslot16); -+ if (rtnval) -+ goto dealloc_slot8; -+ -+ rtnval = sm_keystore_slot_alloc(ksdev, unit, AES_BLOCK_PAD(24), -+ &keyslot24); -+ if (rtnval) -+ goto dealloc_slot16; -+ -+ rtnval = sm_keystore_slot_alloc(ksdev, unit, AES_BLOCK_PAD(32), -+ &keyslot32); -+ if (rtnval) -+ goto dealloc_slot24; -+ -+ -+ /* Now load clear key data into the newly allocated slots */ -+ rtnval = sm_keystore_slot_load(ksdev, unit, keyslot8, clrkey8, 8); -+ if (rtnval) -+ goto dealloc; -+ -+ rtnval = sm_keystore_slot_load(ksdev, unit, keyslot16, clrkey16, 16); -+ if (rtnval) -+ goto dealloc; -+ -+ rtnval = sm_keystore_slot_load(ksdev, unit, keyslot24, clrkey24, 24); -+ if (rtnval) -+ goto dealloc; -+ -+ rtnval = sm_keystore_slot_load(ksdev, unit, keyslot32, clrkey32, 32); -+ if (rtnval) -+ goto dealloc; -+ -+ /* -+ * All cleartext keys are loaded into slots (in an unprotected -+ * partition at this time) -+ * -+ * Cover keys in-place -+ */ -+ rtnval = sm_keystore_cover_key(ksdev, unit, keyslot8, 8, KEY_COVER_ECB); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't cover 64-bit key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_cover_key(ksdev, unit, keyslot16, 16, -+ KEY_COVER_ECB); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't cover 128-bit key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_cover_key(ksdev, unit, keyslot24, 24, -+ KEY_COVER_ECB); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't cover 192-bit key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_cover_key(ksdev, unit, keyslot32, 32, -+ KEY_COVER_ECB); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't cover 256-bit key\n"); -+ goto dealloc; -+ } -+ -+ /* -+ * Keys should be covered and appear sufficiently "random" -+ * as a result of the covering (blackening) process. Assuming -+ * non-secure mode, read them back out for examination; they should -+ * appear as random data, completely differing from the clear -+ * inputs. So, this will read them back from secure memory and -+ * compare them. If they match the clear key, then the covering -+ * operation didn't occur. -+ */ -+ -+ rtnval = sm_keystore_slot_read(ksdev, unit, keyslot8, AES_BLOCK_PAD(8), -+ blkkey8); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't read 64-bit black key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_read(ksdev, unit, keyslot16, -+ AES_BLOCK_PAD(16), blkkey16); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't read 128-bit black key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_read(ksdev, unit, keyslot24, -+ AES_BLOCK_PAD(24), blkkey24); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't read 192-bit black key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_read(ksdev, unit, keyslot32, -+ AES_BLOCK_PAD(32), blkkey32); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't read 256-bit black key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = -EINVAL; -+ if (!memcmp(blkkey8, clrkey8, 8)) { -+ dev_err(ksdev, "blkkey_ex: 64-bit key cover failed\n"); -+ goto dealloc; -+ } -+ -+ if (!memcmp(blkkey16, clrkey16, 16)) { -+ dev_err(ksdev, "blkkey_ex: 128-bit key cover failed\n"); -+ goto dealloc; -+ } -+ -+ if (!memcmp(blkkey24, clrkey24, 24)) { -+ dev_err(ksdev, "blkkey_ex: 192-bit key cover failed\n"); -+ goto dealloc; -+ } -+ -+ if (!memcmp(blkkey32, clrkey32, 32)) { -+ dev_err(ksdev, "blkkey_ex: 256-bit key cover failed\n"); -+ goto dealloc; -+ } -+ -+ -+ key_display(ksdev, "64-bit clear key:", 8, clrkey8); -+ key_display(ksdev, "64-bit black key:", AES_BLOCK_PAD(8), blkkey8); -+ -+ key_display(ksdev, "128-bit clear key:", 16, clrkey16); -+ key_display(ksdev, "128-bit black key:", AES_BLOCK_PAD(16), blkkey16); -+ -+ key_display(ksdev, "192-bit clear key:", 24, clrkey24); -+ key_display(ksdev, "192-bit black key:", AES_BLOCK_PAD(24), blkkey24); -+ -+ key_display(ksdev, "256-bit clear key:", 32, clrkey32); -+ key_display(ksdev, "256-bit black key:", AES_BLOCK_PAD(32), blkkey32); -+ -+ /* -+ * Now encapsulate all keys as SM blobs out to external memory -+ * Blobs will appear as random-looking blocks of data different -+ * from the original source key, and 48 bytes longer than the -+ * original key, to account for the extra data encapsulated within. -+ */ -+ key_display(ksdev, "64-bit unwritten blob:", 96, blob8); -+ key_display(ksdev, "128-bit unwritten blob:", 96, blob16); -+ key_display(ksdev, "196-bit unwritten blob:", 96, blob24); -+ key_display(ksdev, "256-bit unwritten blob:", 96, blob32); -+ -+ rtnval = sm_keystore_slot_export(ksdev, unit, keyslot8, BLACK_KEY, -+ KEY_COVER_ECB, blob8, 8, skeymod); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't encapsulate 64-bit key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_export(ksdev, unit, keyslot16, BLACK_KEY, -+ KEY_COVER_ECB, blob16, 16, skeymod); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't encapsulate 128-bit key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_export(ksdev, unit, keyslot24, BLACK_KEY, -+ KEY_COVER_ECB, blob24, 24, skeymod); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't encapsulate 192-bit key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_export(ksdev, unit, keyslot32, BLACK_KEY, -+ KEY_COVER_ECB, blob32, 32, skeymod); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't encapsulate 256-bit key\n"); -+ goto dealloc; -+ } -+ -+ key_display(ksdev, "64-bit black key in blob:", 96, blob8); -+ key_display(ksdev, "128-bit black key in blob:", 96, blob16); -+ key_display(ksdev, "192-bit black key in blob:", 96, blob24); -+ key_display(ksdev, "256-bit black key in blob:", 96, blob32); -+ -+ /* -+ * Now re-import black keys from secure-memory blobs stored -+ * in general memory from the previous operation. Since we are -+ * working with black keys, and since power has not cycled, the -+ * restored black keys should match the original blackened keys -+ * (this would not be true if the blobs were save in some non-volatile -+ * store, and power was cycled between the save and restore) -+ */ -+ rtnval = sm_keystore_slot_import(ksdev, unit, keyslot8, BLACK_KEY, -+ KEY_COVER_ECB, blob8, 8, skeymod); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't decapsulate 64-bit blob\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_import(ksdev, unit, keyslot16, BLACK_KEY, -+ KEY_COVER_ECB, blob16, 16, skeymod); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't decapsulate 128-bit blob\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_import(ksdev, unit, keyslot24, BLACK_KEY, -+ KEY_COVER_ECB, blob24, 24, skeymod); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't decapsulate 196-bit blob\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_import(ksdev, unit, keyslot32, BLACK_KEY, -+ KEY_COVER_ECB, blob32, 32, skeymod); -+ if (rtnval) { -+ dev_err(ksdev, "blkkey_ex: can't decapsulate 256-bit blob\n"); -+ goto dealloc; -+ } -+ -+ -+ /* -+ * Blobs are now restored as black keys. Read those black keys back -+ * for a comparison with the original black key, they should match -+ */ -+ rtnval = sm_keystore_slot_read(ksdev, unit, keyslot8, AES_BLOCK_PAD(8), -+ rstkey8); -+ if (rtnval) { -+ dev_err(ksdev, -+ "blkkey_ex: can't read restored 64-bit black key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_read(ksdev, unit, keyslot16, -+ AES_BLOCK_PAD(16), rstkey16); -+ if (rtnval) { -+ dev_err(ksdev, -+ "blkkey_ex: can't read restored 128-bit black key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_read(ksdev, unit, keyslot24, -+ AES_BLOCK_PAD(24), rstkey24); -+ if (rtnval) { -+ dev_err(ksdev, -+ "blkkey_ex: can't read restored 196-bit black key\n"); -+ goto dealloc; -+ } -+ -+ rtnval = sm_keystore_slot_read(ksdev, unit, keyslot32, -+ AES_BLOCK_PAD(32), rstkey32); -+ if (rtnval) { -+ dev_err(ksdev, -+ "blkkey_ex: can't read restored 256-bit black key\n"); -+ goto dealloc; -+ } -+ -+ key_display(ksdev, "restored 64-bit black key:", AES_BLOCK_PAD(8), -+ rstkey8); -+ key_display(ksdev, "restored 128-bit black key:", AES_BLOCK_PAD(16), -+ rstkey16); -+ key_display(ksdev, "restored 192-bit black key:", AES_BLOCK_PAD(24), -+ rstkey24); -+ key_display(ksdev, "restored 256-bit black key:", AES_BLOCK_PAD(32), -+ rstkey32); -+ -+ /* -+ * Compare the restored black keys with the original blackened keys -+ * As long as we're operating within the same power cycle, a black key -+ * restored from a blob should match the original black key IF the -+ * key happens to be of a size that matches a multiple of the AES -+ * blocksize. Any key that is padded to fill the block size will not -+ * match, excepting a key that exceeds a block; only the first full -+ * blocks will match (assuming ECB). -+ * -+ * Therefore, compare the 16 and 32 bit keys, they should match. -+ * The 24 bit key can only match within the first 16 byte block. -+ */ -+ -+ if (memcmp(rstkey16, blkkey16, AES_BLOCK_PAD(16))) { -+ dev_err(ksdev, "blkkey_ex: 128-bit restored key mismatch\n"); -+ rtnval = -EINVAL; -+ } -+ -+ /* Only first AES block will match, remainder subject to padding */ -+ if (memcmp(rstkey24, blkkey24, 16)) { -+ dev_err(ksdev, "blkkey_ex: 192-bit restored key mismatch\n"); -+ rtnval = -EINVAL; -+ } -+ -+ if (memcmp(rstkey32, blkkey32, AES_BLOCK_PAD(32))) { -+ dev_err(ksdev, "blkkey_ex: 256-bit restored key mismatch\n"); -+ rtnval = -EINVAL; -+ } -+ -+ -+ /* Remove keys from keystore */ -+dealloc: -+ sm_keystore_slot_dealloc(ksdev, unit, keyslot32); -+dealloc_slot24: -+ sm_keystore_slot_dealloc(ksdev, unit, keyslot24); -+dealloc_slot16: -+ sm_keystore_slot_dealloc(ksdev, unit, keyslot16); -+dealloc_slot8: -+ sm_keystore_slot_dealloc(ksdev, unit, keyslot8); -+ -+ /* Free resources */ -+freemem: -+ kfree(blob8); -+ kfree(blob16); -+ kfree(blob24); -+ kfree(blob32); -+ -+ /* Disconnect from keystore and leave */ -+ sm_release_keystore(ksdev, unit); -+ -+ return rtnval; -+} -+EXPORT_SYMBOL(caam_sm_example_init); -+ -+void caam_sm_example_shutdown(void) -+{ -+ /* unused in present version */ -+ struct device_node *dev_node; -+ struct platform_device *pdev; -+ -+ /* -+ * Do of_find_compatible_node() then of_find_device_by_node() -+ * once a functional device tree is available -+ */ -+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); -+ if (!dev_node) { -+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); -+ if (!dev_node) -+ return; -+ } -+ -+ pdev = of_find_device_by_node(dev_node); -+ if (!pdev) -+ return; -+ -+ of_node_get(dev_node); -+ -+} -+ -+static int __init caam_sm_test_init(void) -+{ -+ struct device_node *dev_node; -+ struct platform_device *pdev; -+ int ret; -+ -+ /* -+ * Do of_find_compatible_node() then of_find_device_by_node() -+ * once a functional device tree is available -+ */ -+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); -+ if (!dev_node) { -+ dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); -+ if (!dev_node) -+ return -ENODEV; -+ } -+ -+ pdev = of_find_device_by_node(dev_node); -+ if (!pdev) -+ return -ENODEV; -+ -+ of_node_put(dev_node); -+ -+ ret = caam_sm_example_init(pdev); -+ if (ret) -+ dev_err(&pdev->dev, "SM test failed: %d\n", ret); -+ else -+ dev_info(&pdev->dev, "SM test passed\n"); -+ -+ return ret; -+} -+ -+ -+/* Module-based initialization needs to wait for dev tree */ -+#ifdef CONFIG_OF -+module_init(caam_sm_test_init); -+module_exit(caam_sm_example_shutdown); -+ -+MODULE_LICENSE("Dual BSD/GPL"); -+MODULE_DESCRIPTION("FSL CAAM Black Key Usage Example"); -+MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD"); -+#endif diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0021-MLK-19801-1-crypto-caam-add-tag-functionality.patch b/target/linux/layerscape/patches-5.4/804-crypto-0021-MLK-19801-1-crypto-caam-add-tag-functionality.patch deleted file mode 100644 index 11d267354d..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0021-MLK-19801-1-crypto-caam-add-tag-functionality.patch +++ /dev/null @@ -1,439 +0,0 @@ -From b2fb5441c4613465e0c8f9203cdec4f8083d2fdd Mon Sep 17 00:00:00 2001 -From: Franck LENORMAND -Date: Fri, 5 Oct 2018 16:08:25 +0200 -Subject: [PATCH] MLK-19801-1 crypto: caam - add tag functionality -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add functions to tag an object with metadata(configuration). - -It is possible to: - - create metadata: - - init_tag_object_header - - init_blackey_conf - - set_tag_object_conf - - retrieve metadata: - - get_tag_object_conf - - get_blackey_conf - -The API expects an object to be a space a memory -with an address and a size. - -The implementation of the tag is currently exposed -but users shouldn't access it directly, they should -use the functions provided. - -Signed-off-by: Franck LENORMAND -(cherry picked from commit ebbb132da8e7f9de7f3d375eff8d87f684feb1eb) -Signed-off-by: Vipul Kumar -(cherry picked from commit 8b6f6b4474be33ee271dfe2cce79f9f6335733aa) - --make tag functionality depend on JR --change commit headline prefix - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/Kconfig | 10 ++ - drivers/crypto/caam/Makefile | 1 + - drivers/crypto/caam/tag_object.c | 260 +++++++++++++++++++++++++++++++++++++++ - drivers/crypto/caam/tag_object.h | 100 +++++++++++++++ - 4 files changed, 371 insertions(+) - create mode 100644 drivers/crypto/caam/tag_object.c - create mode 100644 drivers/crypto/caam/tag_object.h - ---- a/drivers/crypto/caam/Kconfig -+++ b/drivers/crypto/caam/Kconfig -@@ -148,6 +148,16 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API - Selecting this will register the SEC4 hardware rng to - the hw_random API for suppying the kernel entropy pool. - -+config CRYPTO_DEV_FSL_CAAM_TK_API -+ bool "Register tagged key cryptography implementations with Crypto API" -+ depends on CRYPTO_DEV_FSL_CAAM_CRYPTO_API -+ help -+ Selecting this will register algorithms supporting tagged -+ key. -+ -+ Tagged key are keys that contains metadata indicating what -+ they are and how to handle them. -+ - config CRYPTO_DEV_FSL_CAAM_RNG_TEST - bool "Test caam rng" - depends on CRYPTO_DEV_FSL_CAAM_RNG_API ---- a/drivers/crypto/caam/Makefile -+++ b/drivers/crypto/caam/Makefile -@@ -24,6 +24,7 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM) += sm_store.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST) += sm_test.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o -+caam-jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o - - caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o - ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),) ---- /dev/null -+++ b/drivers/crypto/caam/tag_object.c -@@ -0,0 +1,260 @@ -+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -+/* -+ * Copyright 2018-2019 NXP -+ */ -+ -+#include -+#include -+#include -+ -+#include "tag_object.h" -+#include "desc.h" -+ -+/* -+ * Magic number to clearly identify the structure is for us -+ * 0x54 = 'T' -+ * 0x61 = 'a' -+ * 0x67 = 'g' -+ * 0x4f = 'O' -+ */ -+#define TAG_OBJECT_MAGIC 0x5461674f -+ -+/** -+ * struct tagged_object - Structure representing a tagged object -+ * @tag : The configuration of the data -+ * @object : The object -+ */ -+struct tagged_object { -+ struct tag_object_conf tag; -+ char object; -+}; -+ -+/** -+ * is_bk_type() - Determines if black key type. -+ * @type: The type -+ * -+ * Return: True if black key type, False otherwise. -+ */ -+static bool is_bk_type(enum tag_type type) -+{ -+ return (type == TAG_TYPE_BLACK_KEY_ECB) || -+ (type == TAG_TYPE_BLACK_KEY_ECB_TRUSTED) || -+ (type == TAG_TYPE_BLACK_KEY_CCM) || -+ (type == TAG_TYPE_BLACK_KEY_CCM_TRUSTED); -+} -+ -+/** -+ * is_bk_conf() - Determines if black key conf. -+ * @tag_obj_conf : The tag object conf -+ * -+ * Return: True if black key conf, False otherwise. -+ */ -+bool is_bk_conf(const struct tag_object_conf *tag_obj_conf) -+{ -+ return is_bk_type(tag_obj_conf->header.type); -+} -+EXPORT_SYMBOL(is_bk_conf); -+ -+/** -+ * get_bk_conf() - Gets the block conf. -+ * @tag_obj_conf : The tag object conf -+ * -+ * Return: The block conf. -+ */ -+const struct blackey_conf *get_bk_conf(const struct tag_object_conf *tag_obj_conf) -+{ -+ return &tag_obj_conf->conf.bk_conf; -+} -+ -+/** -+ * get_tag_object_overhead() - Gets the tag object overhead. -+ * -+ * Return: The tag object overhead. -+ */ -+size_t get_tag_object_overhead(void) -+{ -+ return TAG_OVERHEAD; -+} -+EXPORT_SYMBOL(get_tag_object_overhead); -+ -+/** -+ * is_valid_type() - Determines if valid type. -+ * @type : The type -+ * -+ * Return: True if valid type, False otherwise. -+ */ -+bool is_valid_type(enum tag_type type) -+{ -+ return (type > TAG_TYPE_NOT_SUPPORTED) && (type < NB_TAG_TYPE); -+} -+EXPORT_SYMBOL(is_valid_type); -+ -+/** -+ * is_valid_header() - Determines if valid header. -+ * @header : The header -+ * -+ * Return: True if valid tag object conf, False otherwise. -+ */ -+static bool is_valid_header(const struct conf_header *header) -+{ -+ bool valid = header->_magic_number == TAG_OBJECT_MAGIC; -+ -+ valid = valid && is_valid_type(header->type); -+ -+ return valid; -+} -+ -+/** -+ * is_valid_tag_object_conf() - Determines if valid tag object conf. -+ * @tag_obj_conf : The tag object conf -+ * -+ * Return: True if valid header, False otherwise. -+ */ -+bool is_valid_tag_object_conf(const struct tag_object_conf *tag_obj_conf) -+{ -+ bool valid = true; -+ -+ valid = is_valid_header(&tag_obj_conf->header); -+ -+ return valid; -+} -+EXPORT_SYMBOL(is_valid_tag_object_conf); -+ -+/** -+ * get_tag_object_conf() - Gets a pointer on the tag object conf. -+ * @tag_obj_conf : The tag object conf -+ * @buffer : The buffer -+ * @size : The size -+ * -+ * Return: 0 if success, else error code -+ */ -+int get_tag_object_conf(void *buffer, size_t size, -+ struct tag_object_conf **tag_obj_conf) -+{ -+ bool is_valid; -+ struct tagged_object *tago = (struct tagged_object *)buffer; -+ size_t conf_size = get_tag_object_overhead(); -+ -+ /* Check we can retrieve the conf */ -+ if (size < conf_size) -+ return -EINVAL; -+ -+ is_valid = is_valid_tag_object_conf(&tago->tag); -+ -+ *tag_obj_conf = &tago->tag; -+ -+ return (is_valid) ? 0 : -EINVAL; -+} -+EXPORT_SYMBOL(get_tag_object_conf); -+ -+/** -+ * init_tag_object_header() - Initialize the tag object header -+ * @conf_header : The configuration header -+ * @type : The type -+ * -+ * It initialize the header structure -+ */ -+void init_tag_object_header(struct conf_header *conf_header, -+ enum tag_type type) -+{ -+ conf_header->_magic_number = TAG_OBJECT_MAGIC; -+ conf_header->type = type; -+} -+EXPORT_SYMBOL(init_tag_object_header); -+ -+/** -+ * set_tag_object_conf() - Sets the tag object conf. -+ * @tag_obj_conf : The tag object conf -+ * @buffer : The buffer -+ * @obj_size : The object size -+ * @to_size : The tagged object size -+ * -+ * Return: 0 if success, else error code -+ */ -+int set_tag_object_conf(const struct tag_object_conf *tag_obj_conf, -+ void *buffer, size_t obj_size, u32 *to_size) -+{ -+ struct tagged_object *tago = buffer; -+ size_t conf_size = get_tag_object_overhead(); -+ size_t req_size = obj_size + conf_size; -+ -+ /* Check we can set the conf */ -+ if (*to_size < req_size) { -+ *to_size = req_size; -+ return -EINVAL; -+ } -+ -+ /* Move the object */ -+ memmove(&tago->object, buffer, obj_size); -+ -+ /* Copy the tag */ -+ memcpy(&tago->tag, tag_obj_conf, conf_size); -+ -+ *to_size = req_size; -+ -+ return 0; -+} -+EXPORT_SYMBOL(set_tag_object_conf); -+ -+/** -+ * init_blackey_conf() - Initialize the black key configuration -+ * @blackey_conf : The blackey conf -+ * @len : The length -+ * @ccm : The ccm -+ * @tk : The trusted key -+ * -+ * It initialize the black key configuration structure -+ */ -+void init_blackey_conf(struct blackey_conf *blackey_conf, -+ size_t len, bool ccm, bool tk) -+{ -+ blackey_conf->real_len = len; -+ blackey_conf->load = KEY_ENC -+ | ((ccm) ? KEY_EKT : 0) -+ | ((tk) ? KEY_TK : 0); -+} -+EXPORT_SYMBOL(init_blackey_conf); -+ -+/** -+ * get_blackey_conf() - Get the black key configuration -+ * @blackey_conf : The blackey conf -+ * @real_len : The real length -+ * @load_param : The load parameter -+ * -+ * It retrieve the black key configuration -+ */ -+void get_blackey_conf(const struct blackey_conf *blackey_conf, -+ u32 *real_len, u32 *load_param) -+{ -+ *real_len = blackey_conf->real_len; -+ *load_param = blackey_conf->load; -+} -+EXPORT_SYMBOL(get_blackey_conf); -+ -+/** -+ * get_tagged_data() - Get a pointer on the data and the size -+ * @tagged_object : Pointer on the tagged object -+ * @tagged_object_size : tagged object size in bytes -+ * @data : Pointer on the data -+ * @data_size : data size in bytes -+ * -+ * Return: 0 if success, else error code -+ */ -+int get_tagged_data(void *tagged_object, size_t tagged_object_size, -+ void **data, u32 *data_size) -+{ -+ struct tagged_object *tago = -+ (struct tagged_object *)tagged_object; -+ size_t conf_size = get_tag_object_overhead(); -+ -+ /* Check we can retrieve the object */ -+ if (tagged_object_size < conf_size) -+ return -EINVAL; -+ -+ /* Retrieve the object */ -+ *data = &tago->object; -+ *data_size = tagged_object_size - conf_size; -+ -+ return 0; -+} -+EXPORT_SYMBOL(get_tagged_data); ---- /dev/null -+++ b/drivers/crypto/caam/tag_object.h -@@ -0,0 +1,100 @@ -+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -+/* -+ * Copyright 2018-2019 NXP -+ */ -+ -+#ifndef _TAG_OBJECT_H_ -+#define _TAG_OBJECT_H_ -+ -+#include -+ -+#define TAG_MIN_SIZE (2 * sizeof(struct conf_header)) -+#define TAG_OVERHEAD sizeof(struct tag_object_conf) -+ -+/** -+ * enum tag_type - Type of data represented by the tag -+ */ -+enum tag_type { -+ /** @TAG_TYPE_NOT_SUPPORTED: The type is not supported */ -+ TAG_TYPE_NOT_SUPPORTED = 0, -+ -+ /* Type that passes is_tag_type_valid() */ -+ /** @TAG_TYPE_BLACK_KEY_ECB: Black key encrypted with ECB */ -+ TAG_TYPE_BLACK_KEY_ECB, -+ /** -+ * @TAG_TYPE_BLACK_KEY_ECB_TRUSTED: ECB Black key created by trusted -+ * descriptor -+ */ -+ TAG_TYPE_BLACK_KEY_ECB_TRUSTED, -+ /** @TAG_TYPE_BLACK_KEY_CCM: Black key encrypted with CCM */ -+ TAG_TYPE_BLACK_KEY_CCM, -+ /** -+ * @TAG_TYPE_BLACK_KEY_CCM_TRUSTED: CCM Black key created by trusted -+ * descriptor -+ */ -+ TAG_TYPE_BLACK_KEY_CCM_TRUSTED, -+ -+ /** @NB_TAG_TYPE: Number of type of tag */ -+ NB_TAG_TYPE, -+}; -+ -+/** -+ * struct conf_header - Common struture holding the type of data and the magic -+ * number -+ * @_magic_number : A magic number to identify the structure -+ * @type : The type of data contained -+ */ -+struct conf_header { -+ u32 _magic_number; -+ u32 type; -+}; -+ -+/** -+ * struct blackey_conf - Configuration for a black key -+ * @load : Load parameter for CAAM -+ * @real_len : Length of the key before encryption -+ */ -+struct blackey_conf { -+ u32 load; -+ u32 real_len; -+}; -+ -+/** -+ * struct tag_object_conf - Common structure which is the tag applied to data -+ * @header : Part of the data initialized with common function -+ * :c:func:`init_tag_object_header` -+ * @conf : Configuration data about the object tagged, initialized with -+ * specific function -+ */ -+struct tag_object_conf { -+ struct conf_header header; -+ union { -+ struct blackey_conf bk_conf; -+ } conf; -+}; -+ -+bool is_bk_conf(const struct tag_object_conf *tag_obj_conf); -+ -+bool is_valid_tag_object_conf(const struct tag_object_conf *tag_obj_conf); -+ -+void init_tag_object_header(struct conf_header *conf_header, -+ enum tag_type type); -+ -+int get_tag_object_conf(void *buffer, size_t buffer_size, -+ struct tag_object_conf **tag_obj_conf); -+ -+int set_tag_object_conf(const struct tag_object_conf *tag_obj_conf, -+ void *buffer, size_t obj_size, u32 *to_size); -+ -+size_t get_tag_object_overhead(void); -+ -+void get_blackey_conf(const struct blackey_conf *blackey_conf, -+ u32 *real_len, u32 *load_param); -+ -+void init_blackey_conf(struct blackey_conf *blackey_conf, -+ size_t len, bool ccm, bool tk); -+ -+int get_tagged_data(void *buffer, size_t buffer_size, -+ void **data, u32 *data_size); -+ -+#endif /* _TAG_OBJECT_H_ */ diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0022-MLK-19801-2-crypto-caam-add-support-of-tagged-keys-i.patch b/target/linux/layerscape/patches-5.4/804-crypto-0022-MLK-19801-2-crypto-caam-add-support-of-tagged-keys-i.patch deleted file mode 100644 index 81f2010aba..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0022-MLK-19801-2-crypto-caam-add-support-of-tagged-keys-i.patch +++ /dev/null @@ -1,304 +0,0 @@ -From df1b397d7c5e79052fa56d1b256ededcd301a27a Mon Sep 17 00:00:00 2001 -From: Franck LENORMAND -Date: Fri, 5 Oct 2018 16:41:54 +0200 -Subject: [PATCH] MLK-19801-2 crypto: caam - add support of tagged keys in - caamalg -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -A tagged key is a key which has been tagged with metadata -using tag_object.h API. - -We add the support for these keys to caamalg. - -For each algo of caamalg which supports tagged keys , it is done by: - - Creating a modified version of the algo - - Registering the modified version - - When the modified transform is used, it gets - the load parameter of the key. - -Signed-off-by: Franck LENORMAND -(cherry picked from commit 88dee97d985890dbf37cafa7934c476d0ecfd0b3) -(Vipul: Fixed merge conflicts) -Conflicts: - drivers/crypto/caam/caamalg.c -Signed-off-by: Vipul Kumar -(cherry picked from commit 5adebac40a7a8065c074f4a69f4ad760c67233f5) - --port from ablkcipher to current skcipher implementation --since in linux-imx true key_inline was always true: a. simplify -the descriptors and b. use key_cmd_opt to differentiate b/w tk and non-tk -cases --change commit headline prefix - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/Makefile | 3 +- - drivers/crypto/caam/caamalg.c | 91 +++++++++++++++++++++++++++++++++++++- - drivers/crypto/caam/caamalg_desc.c | 20 +++++++-- - drivers/crypto/caam/desc_constr.h | 4 ++ - drivers/crypto/caam/tag_object.c | 6 +-- - drivers/crypto/caam/tag_object.h | 6 +-- - 6 files changed, 118 insertions(+), 12 deletions(-) - ---- a/drivers/crypto/caam/Makefile -+++ b/drivers/crypto/caam/Makefile -@@ -15,6 +15,7 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_ - obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o - - caam-y := ctrl.o -+caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o - caam_jr-y := jr.o key_gen.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o -@@ -24,7 +25,7 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM) += sm_store.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST) += sm_test.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o --caam-jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o -+#caam-jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o - - caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o - ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),) ---- a/drivers/crypto/caam/caamalg.c -+++ b/drivers/crypto/caam/caamalg.c -@@ -57,6 +57,10 @@ - #include "key_gen.h" - #include "caamalg_desc.h" - -+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API -+#include "tag_object.h" -+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */ -+ - /* - * crypto alg - */ -@@ -83,6 +87,7 @@ struct caam_alg_entry { - bool rfc3686; - bool geniv; - bool nodkp; -+ bool support_tagged_key; - }; - - struct caam_aead_alg { -@@ -739,6 +744,44 @@ static int skcipher_setkey(struct crypto - ctx->cdata.key_virt = key; - ctx->cdata.key_inline = true; - -+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API -+ /* -+ * Check if the key is not in plaintext format -+ */ -+ if (alg->caam.support_tagged_key) { -+ struct tag_object_conf *tagged_key_conf; -+ int ret; -+ -+ /* Get the configuration */ -+ ret = get_tag_object_conf(ctx->cdata.key_virt, -+ ctx->cdata.keylen, &tagged_key_conf); -+ if (ret) { -+ dev_err(jrdev, -+ "caam algorithms can't process tagged key\n"); -+ return ret; -+ } -+ -+ /* Only support black key */ -+ if (!is_bk_conf(tagged_key_conf)) { -+ dev_err(jrdev, -+ "The tagged key provided is not a black key\n"); -+ return -EINVAL; -+ } -+ -+ get_blackey_conf(&tagged_key_conf->conf.bk_conf, -+ &ctx->cdata.key_real_len, -+ &ctx->cdata.key_cmd_opt); -+ -+ ret = get_tagged_data(ctx->cdata.key_virt, ctx->cdata.keylen, -+ &ctx->cdata.key_virt, &ctx->cdata.keylen); -+ if (ret) { -+ dev_err(jrdev, -+ "caam algorithms wrong data from tagged key\n"); -+ return ret; -+ } -+ } -+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */ -+ - /* skcipher_encrypt shared descriptor */ - desc = ctx->sh_desc_enc; - cnstr_shdsc_skcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686, -@@ -818,6 +861,14 @@ static int ctr_skcipher_setkey(struct cr - return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off); - } - -+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API -+static int tk_skcipher_setkey(struct crypto_skcipher *skcipher, -+ const u8 *key, unsigned int keylen) -+{ -+ return skcipher_setkey(skcipher, key, keylen, 0); -+} -+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */ -+ - static int des_skcipher_setkey(struct crypto_skcipher *skcipher, - const u8 *key, unsigned int keylen) - { -@@ -1918,6 +1969,25 @@ static struct caam_skcipher_alg driver_a - }, - .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, - }, -+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API -+ { -+ .skcipher = { -+ .base = { -+ .cra_name = "tk(cbc(aes))", -+ .cra_driver_name = "tk-cbc-aes-caam", -+ .cra_blocksize = AES_BLOCK_SIZE, -+ }, -+ .setkey = tk_skcipher_setkey, -+ .encrypt = skcipher_encrypt, -+ .decrypt = skcipher_decrypt, -+ .min_keysize = TAG_MIN_SIZE, -+ .max_keysize = CAAM_MAX_KEY_SIZE, -+ .ivsize = AES_BLOCK_SIZE, -+ }, -+ .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, -+ .caam.support_tagged_key = true, -+ }, -+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */ - { - .skcipher = { - .base = { -@@ -2037,6 +2107,24 @@ static struct caam_skcipher_alg driver_a - }, - .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_ECB, - }, -+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API -+ { -+ .skcipher = { -+ .base = { -+ .cra_name = "tk(ecb(aes))", -+ .cra_driver_name = "tk-ecb-aes-caam", -+ .cra_blocksize = AES_BLOCK_SIZE, -+ }, -+ .setkey = tk_skcipher_setkey, -+ .encrypt = skcipher_encrypt, -+ .decrypt = skcipher_decrypt, -+ .min_keysize = TAG_MIN_SIZE, -+ .max_keysize = CAAM_MAX_KEY_SIZE, -+ }, -+ .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_ECB, -+ .caam.support_tagged_key = true, -+ }, -+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API */ - { - .skcipher = { - .base = { -@@ -3486,7 +3574,8 @@ static void caam_skcipher_alg_init(struc - struct skcipher_alg *alg = &t_alg->skcipher; - - alg->base.cra_module = THIS_MODULE; -- alg->base.cra_priority = CAAM_CRA_PRIORITY; -+ alg->base.cra_priority = -+ t_alg->caam.support_tagged_key ? 1 : CAAM_CRA_PRIORITY; - alg->base.cra_ctxsize = sizeof(struct caam_ctx); - alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY; - ---- a/drivers/crypto/caam/caamalg_desc.c -+++ b/drivers/crypto/caam/caamalg_desc.c -@@ -1389,8 +1389,14 @@ void cnstr_shdsc_skcipher_encap(u32 * co - JUMP_COND_SHRD); - - /* Load class1 key only */ -- append_key_as_imm(desc, cdata->key_virt, cdata->keylen, -- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); -+ if (IS_ENABLED(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) && -+ cdata->key_cmd_opt) -+ append_key_as_imm(desc, cdata->key_virt, cdata->keylen, -+ cdata->key_real_len, CLASS_1 | -+ KEY_DEST_CLASS_REG | cdata->key_cmd_opt); -+ else -+ append_key_as_imm(desc, cdata->key_virt, cdata->keylen, -+ cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); - - /* Load nonce into CONTEXT1 reg */ - if (is_rfc3686) { -@@ -1464,8 +1470,14 @@ void cnstr_shdsc_skcipher_decap(u32 * co - JUMP_COND_SHRD); - - /* Load class1 key only */ -- append_key_as_imm(desc, cdata->key_virt, cdata->keylen, -- cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); -+ if (IS_ENABLED(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) && -+ cdata->key_cmd_opt) -+ append_key_as_imm(desc, cdata->key_virt, cdata->keylen, -+ cdata->key_real_len, CLASS_1 | -+ KEY_DEST_CLASS_REG | cdata->key_cmd_opt); -+ else -+ append_key_as_imm(desc, cdata->key_virt, cdata->keylen, -+ cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); - - /* Load nonce into CONTEXT1 reg */ - if (is_rfc3686) { ---- a/drivers/crypto/caam/desc_constr.h -+++ b/drivers/crypto/caam/desc_constr.h -@@ -500,6 +500,8 @@ do { \ - * @key_virt: virtual address where algorithm key resides - * @key_inline: true - key can be inlined in the descriptor; false - key is - * referenced by the descriptor -+ * @key_real_len: size of the key to be loaded by the CAAM -+ * @key_cmd_opt: optional parameters for KEY command - */ - struct alginfo { - u32 algtype; -@@ -508,6 +510,8 @@ struct alginfo { - dma_addr_t key_dma; - const void *key_virt; - bool key_inline; -+ u32 key_real_len; -+ u32 key_cmd_opt; - }; - - /** ---- a/drivers/crypto/caam/tag_object.c -+++ b/drivers/crypto/caam/tag_object.c -@@ -128,7 +128,7 @@ EXPORT_SYMBOL(is_valid_tag_object_conf); - * - * Return: 0 if success, else error code - */ --int get_tag_object_conf(void *buffer, size_t size, -+int get_tag_object_conf(const void *buffer, size_t size, - struct tag_object_conf **tag_obj_conf) - { - bool is_valid; -@@ -240,8 +240,8 @@ EXPORT_SYMBOL(get_blackey_conf); - * - * Return: 0 if success, else error code - */ --int get_tagged_data(void *tagged_object, size_t tagged_object_size, -- void **data, u32 *data_size) -+int get_tagged_data(const void *tagged_object, size_t tagged_object_size, -+ const void **data, u32 *data_size) - { - struct tagged_object *tago = - (struct tagged_object *)tagged_object; ---- a/drivers/crypto/caam/tag_object.h -+++ b/drivers/crypto/caam/tag_object.h -@@ -80,7 +80,7 @@ bool is_valid_tag_object_conf(const stru - void init_tag_object_header(struct conf_header *conf_header, - enum tag_type type); - --int get_tag_object_conf(void *buffer, size_t buffer_size, -+int get_tag_object_conf(const void *buffer, size_t buffer_size, - struct tag_object_conf **tag_obj_conf); - - int set_tag_object_conf(const struct tag_object_conf *tag_obj_conf, -@@ -94,7 +94,7 @@ void get_blackey_conf(const struct black - void init_blackey_conf(struct blackey_conf *blackey_conf, - size_t len, bool ccm, bool tk); - --int get_tagged_data(void *buffer, size_t buffer_size, -- void **data, u32 *data_size); -+int get_tagged_data(const void *buffer, size_t buffer_size, -+ const void **data, u32 *data_size); - - #endif /* _TAG_OBJECT_H_ */ diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0023-MLK-10036-crypto-caam-add-support-for-DSM-with-Mega-.patch b/target/linux/layerscape/patches-5.4/804-crypto-0023-MLK-10036-crypto-caam-add-support-for-DSM-with-Mega-.patch deleted file mode 100644 index 883cd42d09..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0023-MLK-10036-crypto-caam-add-support-for-DSM-with-Mega-.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 1ffdfbcd42dbb87f2841e45c0719a3fbcb2fe926 Mon Sep 17 00:00:00 2001 -From: Victoria Milhoan -Date: Thu, 18 Dec 2014 14:06:50 -0700 -Subject: [PATCH] MLK-10036 crypto: caam - add support for DSM with Mega/Fast - mix on -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch allows CAAM to be enabled as a wakeup source for the -Mega/Fast mix domain. If CAAM is enabled as a wakeup source, it -will continue to be powered on across Deep Sleep Mode (DSM). This -allows CAAM to be functional after the system resumes from DSM. - -Signed-off-by: Victoria Milhoan -(cherry picked from commit 290744e3b40a563319324e234fa5a65b49fd4d82) -Signed-off-by: Dan Douglass -Signed-off-by: Vipul Kumar -(cherry picked from commit 0bf9c6f84f1d74d9e6d9384c4b11bbdf9301c94e) - -Changed commit headline prefix. - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/jr.c | 33 +++++++++++++++++++++++++++++++++ - 1 file changed, 33 insertions(+) - ---- a/drivers/crypto/caam/jr.c -+++ b/drivers/crypto/caam/jr.c -@@ -561,11 +561,41 @@ static int caam_jr_probe(struct platform - - atomic_set(&jrpriv->tfm_count, 0); - -+ device_init_wakeup(&pdev->dev, 1); -+ device_set_wakeup_enable(&pdev->dev, false); -+ - register_algs(jrdev->parent); - - return 0; - } - -+#ifdef CONFIG_PM -+static int caam_jr_suspend(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct caam_drv_private_jr *jrpriv = platform_get_drvdata(pdev); -+ -+ if (device_may_wakeup(&pdev->dev)) -+ enable_irq_wake(jrpriv->irq); -+ -+ return 0; -+} -+ -+static int caam_jr_resume(struct device *dev) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ struct caam_drv_private_jr *jrpriv = platform_get_drvdata(pdev); -+ -+ if (device_may_wakeup(&pdev->dev)) -+ disable_irq_wake(jrpriv->irq); -+ -+ return 0; -+} -+ -+static SIMPLE_DEV_PM_OPS(caam_jr_pm_ops, caam_jr_suspend, -+ caam_jr_resume); -+#endif -+ - static const struct of_device_id caam_jr_match[] = { - { - .compatible = "fsl,sec-v4.0-job-ring", -@@ -581,6 +611,9 @@ static struct platform_driver caam_jr_dr - .driver = { - .name = "caam_jr", - .of_match_table = caam_jr_match, -+#ifdef CONFIG_PM -+ .pm = &caam_jr_pm_ops, -+#endif - }, - .probe = caam_jr_probe, - .remove = caam_jr_remove, diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0024-MLK-19449-crypto-caam-Change-structure-type-represen.patch b/target/linux/layerscape/patches-5.4/804-crypto-0024-MLK-19449-crypto-caam-Change-structure-type-represen.patch deleted file mode 100644 index 2914f010a4..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0024-MLK-19449-crypto-caam-Change-structure-type-represen.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 18c56f8bced33c4d3d18dd10d2648def4291e6ea Mon Sep 17 00:00:00 2001 -From: Franck LENORMAND -Date: Tue, 5 Mar 2019 14:20:34 +0100 -Subject: [PATCH] MLK-19449 crypto: caam - Change structure type representing - DECO MID -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The structure partid is not suitable to represent the DECO MID register. - -This patch replace partid by masterid which is more appropriate. - -Reviewed-by: Horia Geantă -Signed-off-by: Franck LENORMAND -(cherry picked from commit 2d8dab735757dae8efb35bb0371970a7d27e98be) -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/regs.h | 8 +------- - 1 file changed, 1 insertion(+), 7 deletions(-) - ---- a/drivers/crypto/caam/regs.h -+++ b/drivers/crypto/caam/regs.h -@@ -521,12 +521,6 @@ struct masterid { - u32 liodn_ls; /* LIODN for non-sequence and seq access */ - }; - --/* Partition ID for DMA configuration */ --struct partid { -- u32 rsvd1; -- u32 pidr; /* partition ID, DECO */ --}; -- - /* RNGB test mode (replicated twice in some configurations) */ - /* Padded out to 0x100 */ - struct rngtst { -@@ -640,7 +634,7 @@ struct caam_ctrl { - u32 deco_rsr; /* DECORSR - Deco Request Source */ - u32 rsvd11; - u32 deco_rq; /* DECORR - DECO Request */ -- struct partid deco_mid[5]; /* DECOxLIODNR - 1 per DECO */ -+ struct masterid deco_mid[5]; /* DECOxLIODNR - 1 per DECO */ - u32 rsvd5[22]; - - /* DECO Availability/Reset Section 120-3ff */ diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0025-crypto-caam-qi2-add-unused-dpseci-API.patch b/target/linux/layerscape/patches-5.4/804-crypto-0025-crypto-caam-qi2-add-unused-dpseci-API.patch deleted file mode 100644 index 269d723524..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0025-crypto-caam-qi2-add-unused-dpseci-API.patch +++ /dev/null @@ -1,561 +0,0 @@ -From f79915995e8fe4f2d11043fe4cab4b579e5cf1de Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Wed, 10 Oct 2018 16:06:11 +0300 -Subject: [PATCH] crypto: caam/qi2 - add (unused) dpseci API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -During driver upstreaming all unused dpseci API was trimmed down. -Add the API back to be in sync with files provided by MC f/w release. - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/dpseci.c | 330 ++++++++++++++++++++++++++++++++++++++- - drivers/crypto/caam/dpseci.h | 50 ++++++ - drivers/crypto/caam/dpseci_cmd.h | 59 +++++++ - 3 files changed, 437 insertions(+), 2 deletions(-) - ---- a/drivers/crypto/caam/dpseci.c -+++ b/drivers/crypto/caam/dpseci.c -@@ -16,8 +16,8 @@ - * @token: Returned token; use in subsequent API calls - * - * This function can be used to open a control session for an already created -- * object; an object may have been declared statically in the DPL -- * or created dynamically. -+ * object; an object may have been declared in the DPL or by calling the -+ * dpseci_create() function. - * This function returns a unique authentication token, associated with the - * specific object ID and the specific MC portal; this token must be used in all - * subsequent commands for this specific object. -@@ -67,6 +67,85 @@ int dpseci_close(struct fsl_mc_io *mc_io - } - - /** -+ * dpseci_create() - Create the DPSECI object -+ * @mc_io: Pointer to MC portal's I/O object -+ * @dprc_token: Parent container token; '0' for default container -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @cfg: Configuration structure -+ * @obj_id: returned object id -+ * -+ * Create the DPSECI object, allocate required resources and perform required -+ * initialization. -+ * -+ * The object can be created either by declaring it in the DPL file, or by -+ * calling this function. -+ * -+ * The function accepts an authentication token of a parent container that this -+ * object should be assigned to. The token can be '0' so the object will be -+ * assigned to the default container. -+ * The newly created object can be opened with the returned object id and using -+ * the container's associated tokens and MC portals. -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_create(struct fsl_mc_io *mc_io, u16 dprc_token, u32 cmd_flags, -+ const struct dpseci_cfg *cfg, u32 *obj_id) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpseci_cmd_create *cmd_params; -+ int i, err; -+ -+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CREATE, -+ cmd_flags, -+ dprc_token); -+ cmd_params = (struct dpseci_cmd_create *)cmd.params; -+ for (i = 0; i < 8; i++) -+ cmd_params->priorities[i] = cfg->priorities[i]; -+ for (i = 0; i < 8; i++) -+ cmd_params->priorities2[i] = cfg->priorities[8 + i]; -+ cmd_params->num_tx_queues = cfg->num_tx_queues; -+ cmd_params->num_rx_queues = cfg->num_rx_queues; -+ cmd_params->options = cpu_to_le32(cfg->options); -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ *obj_id = mc_cmd_read_object_id(&cmd); -+ -+ return 0; -+} -+ -+/** -+ * dpseci_destroy() - Destroy the DPSECI object and release all its resources -+ * @mc_io: Pointer to MC portal's I/O object -+ * @dprc_token: Parent container token; '0' for default container -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @object_id: The object id; it must be a valid id within the container that -+ * created this object -+ * -+ * The function accepts the authentication token of the parent container that -+ * created the object (not the one that currently owns the object). The object -+ * is searched within parent using the provided 'object_id'. -+ * All tokens to the object must be closed before calling destroy. -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_destroy(struct fsl_mc_io *mc_io, u16 dprc_token, u32 cmd_flags, -+ u32 object_id) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpseci_cmd_destroy *cmd_params; -+ -+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_DESTROY, -+ cmd_flags, -+ dprc_token); -+ cmd_params = (struct dpseci_cmd_destroy *)cmd.params; -+ cmd_params->object_id = cpu_to_le32(object_id); -+ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** - * dpseci_enable() - Enable the DPSECI, allow sending and receiving frames - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -@@ -133,6 +212,217 @@ int dpseci_is_enabled(struct fsl_mc_io * - } - - /** -+ * dpseci_reset() - Reset the DPSECI, returns the object to initial state. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSECI object -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ -+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_RESET, -+ cmd_flags, -+ token); -+ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpseci_get_irq_enable() - Get overall interrupt state -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSECI object -+ * @irq_index: The interrupt index to configure -+ * @en: Returned Interrupt state - enable = 1, disable = 0 -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_get_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u8 *en) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpseci_cmd_irq_enable *cmd_params; -+ struct dpseci_rsp_get_irq_enable *rsp_params; -+ int err; -+ -+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_ENABLE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpseci_cmd_irq_enable *)cmd.params; -+ cmd_params->irq_index = irq_index; -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ rsp_params = (struct dpseci_rsp_get_irq_enable *)cmd.params; -+ *en = rsp_params->enable_state; -+ -+ return 0; -+} -+ -+/** -+ * dpseci_set_irq_enable() - Set overall interrupt state. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSECI object -+ * @irq_index: The interrupt index to configure -+ * @en: Interrupt state - enable = 1, disable = 0 -+ * -+ * Allows GPP software to control when interrupts are generated. -+ * Each interrupt can have up to 32 causes. The enable/disable control's the -+ * overall interrupt state. If the interrupt is disabled no causes will cause -+ * an interrupt. -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_set_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u8 en) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpseci_cmd_irq_enable *cmd_params; -+ -+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ_ENABLE, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpseci_cmd_irq_enable *)cmd.params; -+ cmd_params->irq_index = irq_index; -+ cmd_params->enable_state = en; -+ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpseci_get_irq_mask() - Get interrupt mask. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSECI object -+ * @irq_index: The interrupt index to configure -+ * @mask: Returned event mask to trigger interrupt -+ * -+ * Every interrupt can have up to 32 causes and the interrupt model supports -+ * masking/unmasking each cause independently. -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_get_irq_mask(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u32 *mask) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpseci_cmd_irq_mask *cmd_params; -+ int err; -+ -+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_MASK, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpseci_cmd_irq_mask *)cmd.params; -+ cmd_params->irq_index = irq_index; -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ *mask = le32_to_cpu(cmd_params->mask); -+ -+ return 0; -+} -+ -+/** -+ * dpseci_set_irq_mask() - Set interrupt mask. -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSECI object -+ * @irq_index: The interrupt index to configure -+ * @mask: event mask to trigger interrupt; -+ * each bit: -+ * 0 = ignore event -+ * 1 = consider event for asserting IRQ -+ * -+ * Every interrupt can have up to 32 causes and the interrupt model supports -+ * masking/unmasking each cause independently -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_set_irq_mask(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u32 mask) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpseci_cmd_irq_mask *cmd_params; -+ -+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_SET_IRQ_MASK, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpseci_cmd_irq_mask *)cmd.params; -+ cmd_params->mask = cpu_to_le32(mask); -+ cmd_params->irq_index = irq_index; -+ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpseci_get_irq_status() - Get the current status of any pending interrupts -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSECI object -+ * @irq_index: The interrupt index to configure -+ * @status: Returned interrupts status - one bit per cause: -+ * 0 = no interrupt pending -+ * 1 = interrupt pending -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_get_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u32 *status) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpseci_cmd_irq_status *cmd_params; -+ int err; -+ -+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_IRQ_STATUS, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpseci_cmd_irq_status *)cmd.params; -+ cmd_params->status = cpu_to_le32(*status); -+ cmd_params->irq_index = irq_index; -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ *status = le32_to_cpu(cmd_params->status); -+ -+ return 0; -+} -+ -+/** -+ * dpseci_clear_irq_status() - Clear a pending interrupt's status -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSECI object -+ * @irq_index: The interrupt index to configure -+ * @status: bits to clear (W1C) - one bit per cause: -+ * 0 = don't change -+ * 1 = clear status bit -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_clear_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u32 status) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpseci_cmd_irq_status *cmd_params; -+ -+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_CLEAR_IRQ_STATUS, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpseci_cmd_irq_status *)cmd.params; -+ cmd_params->status = cpu_to_le32(status); -+ cmd_params->irq_index = irq_index; -+ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** - * dpseci_get_attributes() - Retrieve DPSECI attributes - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -@@ -320,6 +610,42 @@ int dpseci_get_sec_attr(struct fsl_mc_io - - return 0; - } -+ -+/** -+ * dpseci_get_sec_counters() - Retrieve SEC accelerator counters -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSECI object -+ * @counters: Returned SEC counters -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_get_sec_counters(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ struct dpseci_sec_counters *counters) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpseci_rsp_get_sec_counters *rsp_params; -+ int err; -+ -+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_SEC_COUNTERS, -+ cmd_flags, -+ token); -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ rsp_params = (struct dpseci_rsp_get_sec_counters *)cmd.params; -+ counters->dequeued_requests = -+ le64_to_cpu(rsp_params->dequeued_requests); -+ counters->ob_enc_requests = le64_to_cpu(rsp_params->ob_enc_requests); -+ counters->ib_dec_requests = le64_to_cpu(rsp_params->ib_dec_requests); -+ counters->ob_enc_bytes = le64_to_cpu(rsp_params->ob_enc_bytes); -+ counters->ob_prot_bytes = le64_to_cpu(rsp_params->ob_prot_bytes); -+ counters->ib_dec_bytes = le64_to_cpu(rsp_params->ib_dec_bytes); -+ counters->ib_valid_bytes = le64_to_cpu(rsp_params->ib_valid_bytes); -+ -+ return 0; -+} - - /** - * dpseci_get_api_version() - Get Data Path SEC Interface API version ---- a/drivers/crypto/caam/dpseci.h -+++ b/drivers/crypto/caam/dpseci.h -@@ -55,6 +55,12 @@ struct dpseci_cfg { - u8 priorities[DPSECI_MAX_QUEUE_NUM]; - }; - -+int dpseci_create(struct fsl_mc_io *mc_io, u16 dprc_token, u32 cmd_flags, -+ const struct dpseci_cfg *cfg, u32 *obj_id); -+ -+int dpseci_destroy(struct fsl_mc_io *mc_io, u16 dprc_token, u32 cmd_flags, -+ u32 object_id); -+ - int dpseci_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); - - int dpseci_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); -@@ -62,6 +68,26 @@ int dpseci_disable(struct fsl_mc_io *mc_ - int dpseci_is_enabled(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, - int *en); - -+int dpseci_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); -+ -+int dpseci_get_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u8 *en); -+ -+int dpseci_set_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u8 en); -+ -+int dpseci_get_irq_mask(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u32 *mask); -+ -+int dpseci_set_irq_mask(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u32 mask); -+ -+int dpseci_get_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u32 *status); -+ -+int dpseci_clear_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ u8 irq_index, u32 status); -+ - /** - * struct dpseci_attr - Structure representing DPSECI attributes - * @id: DPSECI object ID -@@ -248,6 +274,30 @@ struct dpseci_sec_attr { - int dpseci_get_sec_attr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, - struct dpseci_sec_attr *attr); - -+/** -+ * struct dpseci_sec_counters - Structure representing global SEC counters and -+ * not per dpseci counters -+ * @dequeued_requests: Number of Requests Dequeued -+ * @ob_enc_requests: Number of Outbound Encrypt Requests -+ * @ib_dec_requests: Number of Inbound Decrypt Requests -+ * @ob_enc_bytes: Number of Outbound Bytes Encrypted -+ * @ob_prot_bytes: Number of Outbound Bytes Protected -+ * @ib_dec_bytes: Number of Inbound Bytes Decrypted -+ * @ib_valid_bytes: Number of Inbound Bytes Validated -+ */ -+struct dpseci_sec_counters { -+ u64 dequeued_requests; -+ u64 ob_enc_requests; -+ u64 ib_dec_requests; -+ u64 ob_enc_bytes; -+ u64 ob_prot_bytes; -+ u64 ib_dec_bytes; -+ u64 ib_valid_bytes; -+}; -+ -+int dpseci_get_sec_counters(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, -+ struct dpseci_sec_counters *counters); -+ - int dpseci_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags, - u16 *major_ver, u16 *minor_ver); - ---- a/drivers/crypto/caam/dpseci_cmd.h -+++ b/drivers/crypto/caam/dpseci_cmd.h -@@ -17,6 +17,7 @@ - /* Command versioning */ - #define DPSECI_CMD_BASE_VERSION 1 - #define DPSECI_CMD_BASE_VERSION_V2 2 -+#define DPSECI_CMD_BASE_VERSION_V3 3 - #define DPSECI_CMD_ID_OFFSET 4 - - #define DPSECI_CMD_V1(id) (((id) << DPSECI_CMD_ID_OFFSET) | \ -@@ -25,20 +26,34 @@ - #define DPSECI_CMD_V2(id) (((id) << DPSECI_CMD_ID_OFFSET) | \ - DPSECI_CMD_BASE_VERSION_V2) - -+#define DPSECI_CMD_V3(id) (((id) << DPSECI_CMD_ID_OFFSET) | \ -+ DPSECI_CMD_BASE_VERSION_V3) -+ - /* Command IDs */ - #define DPSECI_CMDID_CLOSE DPSECI_CMD_V1(0x800) - #define DPSECI_CMDID_OPEN DPSECI_CMD_V1(0x809) -+#define DPSECI_CMDID_CREATE DPSECI_CMD_V3(0x909) -+#define DPSECI_CMDID_DESTROY DPSECI_CMD_V1(0x989) - #define DPSECI_CMDID_GET_API_VERSION DPSECI_CMD_V1(0xa09) - - #define DPSECI_CMDID_ENABLE DPSECI_CMD_V1(0x002) - #define DPSECI_CMDID_DISABLE DPSECI_CMD_V1(0x003) - #define DPSECI_CMDID_GET_ATTR DPSECI_CMD_V1(0x004) -+#define DPSECI_CMDID_RESET DPSECI_CMD_V1(0x005) - #define DPSECI_CMDID_IS_ENABLED DPSECI_CMD_V1(0x006) - -+#define DPSECI_CMDID_SET_IRQ_ENABLE DPSECI_CMD_V1(0x012) -+#define DPSECI_CMDID_GET_IRQ_ENABLE DPSECI_CMD_V1(0x013) -+#define DPSECI_CMDID_SET_IRQ_MASK DPSECI_CMD_V1(0x014) -+#define DPSECI_CMDID_GET_IRQ_MASK DPSECI_CMD_V1(0x015) -+#define DPSECI_CMDID_GET_IRQ_STATUS DPSECI_CMD_V1(0x016) -+#define DPSECI_CMDID_CLEAR_IRQ_STATUS DPSECI_CMD_V1(0x017) -+ - #define DPSECI_CMDID_SET_RX_QUEUE DPSECI_CMD_V1(0x194) - #define DPSECI_CMDID_GET_RX_QUEUE DPSECI_CMD_V1(0x196) - #define DPSECI_CMDID_GET_TX_QUEUE DPSECI_CMD_V1(0x197) - #define DPSECI_CMDID_GET_SEC_ATTR DPSECI_CMD_V2(0x198) -+#define DPSECI_CMDID_GET_SEC_COUNTERS DPSECI_CMD_V1(0x199) - #define DPSECI_CMDID_SET_CONGESTION_NOTIFICATION DPSECI_CMD_V1(0x170) - #define DPSECI_CMDID_GET_CONGESTION_NOTIFICATION DPSECI_CMD_V1(0x171) - -@@ -57,6 +72,20 @@ struct dpseci_cmd_open { - __le32 dpseci_id; - }; - -+struct dpseci_cmd_create { -+ u8 priorities[8]; -+ u8 num_tx_queues; -+ u8 num_rx_queues; -+ u8 pad0[6]; -+ __le32 options; -+ __le32 pad1; -+ u8 priorities2[8]; -+}; -+ -+struct dpseci_cmd_destroy { -+ __le32 object_id; -+}; -+ - #define DPSECI_ENABLE_SHIFT 0 - #define DPSECI_ENABLE_SIZE 1 - -@@ -64,6 +93,26 @@ struct dpseci_rsp_is_enabled { - u8 is_enabled; - }; - -+struct dpseci_cmd_irq_enable { -+ u8 enable_state; -+ u8 pad[3]; -+ u8 irq_index; -+}; -+ -+struct dpseci_rsp_get_irq_enable { -+ u8 enable_state; -+}; -+ -+struct dpseci_cmd_irq_mask { -+ __le32 mask; -+ u8 irq_index; -+}; -+ -+struct dpseci_cmd_irq_status { -+ __le32 status; -+ u8 irq_index; -+}; -+ - struct dpseci_rsp_get_attributes { - __le32 id; - __le32 pad0; -@@ -125,6 +174,16 @@ struct dpseci_rsp_get_sec_attr { - u8 ptha_acc_num; - }; - -+struct dpseci_rsp_get_sec_counters { -+ __le64 dequeued_requests; -+ __le64 ob_enc_requests; -+ __le64 ib_dec_requests; -+ __le64 ob_enc_bytes; -+ __le64 ob_prot_bytes; -+ __le64 ib_dec_bytes; -+ __le64 ib_valid_bytes; -+}; -+ - struct dpseci_rsp_get_api_version { - __le16 major; - __le16 minor; diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0026-crypto-caam-qi2-add-OPR-Order-Preservation-support.patch b/target/linux/layerscape/patches-5.4/804-crypto-0026-crypto-caam-qi2-add-OPR-Order-Preservation-support.patch deleted file mode 100644 index c6975adf47..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0026-crypto-caam-qi2-add-OPR-Order-Preservation-support.patch +++ /dev/null @@ -1,246 +0,0 @@ -From 70eb620ed6d38e171e5619313e99d31688d25010 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Wed, 10 Oct 2018 16:07:50 +0300 -Subject: [PATCH] crypto: caam/qi2 - add OPR (Order Preservation) support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -During driver upstreaming OPR was removed due to lacking users. -Add OPR back, since in LSDK / LSDK-based ADKs there is at least -one user (ASF / VortiQa IPsec). - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/dpseci.c | 85 ++++++++++++++++++++++++++++++++++++++++ - drivers/crypto/caam/dpseci.h | 26 +++++++++++- - drivers/crypto/caam/dpseci_cmd.h | 51 ++++++++++++++++++++++++ - 3 files changed, 160 insertions(+), 2 deletions(-) - ---- a/drivers/crypto/caam/dpseci.c -+++ b/drivers/crypto/caam/dpseci.c -@@ -5,6 +5,7 @@ - */ - - #include -+#include - #include "dpseci.h" - #include "dpseci_cmd.h" - -@@ -675,6 +676,90 @@ int dpseci_get_api_version(struct fsl_mc - - return 0; - } -+ -+/** -+ * dpseci_set_opr() - Set Order Restoration configuration -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSECI object -+ * @index: The queue index -+ * @options: Configuration mode options; can be OPR_OPT_CREATE or -+ * OPR_OPT_RETIRE -+ * @cfg: Configuration options for the OPR -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_set_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index, -+ u8 options, struct opr_cfg *cfg) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpseci_cmd_opr *cmd_params; -+ -+ cmd.header = mc_encode_cmd_header( -+ DPSECI_CMDID_SET_OPR, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpseci_cmd_opr *)cmd.params; -+ cmd_params->index = index; -+ cmd_params->options = options; -+ cmd_params->oloe = cfg->oloe; -+ cmd_params->oeane = cfg->oeane; -+ cmd_params->olws = cfg->olws; -+ cmd_params->oa = cfg->oa; -+ cmd_params->oprrws = cfg->oprrws; -+ -+ return mc_send_command(mc_io, &cmd); -+} -+ -+/** -+ * dpseci_get_opr() - Retrieve Order Restoration config and query -+ * @mc_io: Pointer to MC portal's I/O object -+ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' -+ * @token: Token of DPSECI object -+ * @index: The queue index -+ * @cfg: Returned OPR configuration -+ * @qry: Returned OPR query -+ * -+ * Return: '0' on success, error code otherwise -+ */ -+int dpseci_get_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index, -+ struct opr_cfg *cfg, struct opr_qry *qry) -+{ -+ struct fsl_mc_command cmd = { 0 }; -+ struct dpseci_cmd_opr *cmd_params; -+ struct dpseci_rsp_get_opr *rsp_params; -+ int err; -+ -+ cmd.header = mc_encode_cmd_header(DPSECI_CMDID_GET_OPR, -+ cmd_flags, -+ token); -+ cmd_params = (struct dpseci_cmd_opr *)cmd.params; -+ cmd_params->index = index; -+ err = mc_send_command(mc_io, &cmd); -+ if (err) -+ return err; -+ -+ rsp_params = (struct dpseci_rsp_get_opr *)cmd.params; -+ qry->rip = dpseci_get_field(rsp_params->flags, OPR_RIP); -+ qry->enable = dpseci_get_field(rsp_params->flags, OPR_ENABLE); -+ cfg->oloe = rsp_params->oloe; -+ cfg->oeane = rsp_params->oeane; -+ cfg->olws = rsp_params->olws; -+ cfg->oa = rsp_params->oa; -+ cfg->oprrws = rsp_params->oprrws; -+ qry->nesn = le16_to_cpu(rsp_params->nesn); -+ qry->ndsn = le16_to_cpu(rsp_params->ndsn); -+ qry->ea_tseq = le16_to_cpu(rsp_params->ea_tseq); -+ qry->tseq_nlis = dpseci_get_field(rsp_params->tseq_nlis, OPR_TSEQ_NLIS); -+ qry->ea_hseq = le16_to_cpu(rsp_params->ea_hseq); -+ qry->hseq_nlis = dpseci_get_field(rsp_params->hseq_nlis, OPR_HSEQ_NLIS); -+ qry->ea_hptr = le16_to_cpu(rsp_params->ea_hptr); -+ qry->ea_tptr = le16_to_cpu(rsp_params->ea_tptr); -+ qry->opr_vid = le16_to_cpu(rsp_params->opr_vid); -+ qry->opr_id = le16_to_cpu(rsp_params->opr_id); -+ -+ return 0; -+} - - /** - * dpseci_set_congestion_notification() - Set congestion group ---- a/drivers/crypto/caam/dpseci.h -+++ b/drivers/crypto/caam/dpseci.h -@@ -12,6 +12,8 @@ - */ - - struct fsl_mc_io; -+struct opr_cfg; -+struct opr_qry; - - /** - * General DPSECI macros -@@ -38,9 +40,21 @@ int dpseci_close(struct fsl_mc_io *mc_io - #define DPSECI_OPT_HAS_CG 0x000020 - - /** -+ * Enable the Order Restoration support -+ */ -+#define DPSECI_OPT_HAS_OPR 0x000040 -+ -+/** -+ * Order Point Records are shared for the entire DPSECI -+ */ -+#define DPSECI_OPT_OPR_SHARED 0x000080 -+ -+/** - * struct dpseci_cfg - Structure representing DPSECI configuration -- * @options: Any combination of the following flags: -+ * @options: Any combination of the following options: - * DPSECI_OPT_HAS_CG -+ * DPSECI_OPT_HAS_OPR -+ * DPSECI_OPT_OPR_SHARED - * @num_tx_queues: num of queues towards the SEC - * @num_rx_queues: num of queues back from the SEC - * @priorities: Priorities for the SEC hardware processing; -@@ -93,8 +107,10 @@ int dpseci_clear_irq_status(struct fsl_m - * @id: DPSECI object ID - * @num_tx_queues: number of queues towards the SEC - * @num_rx_queues: number of queues back from the SEC -- * @options: any combination of the following flags: -+ * @options: any combination of the following options: - * DPSECI_OPT_HAS_CG -+ * DPSECI_OPT_HAS_OPR -+ * DPSECI_OPT_OPR_SHARED - */ - struct dpseci_attr { - int id; -@@ -301,6 +317,12 @@ int dpseci_get_sec_counters(struct fsl_m - int dpseci_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags, - u16 *major_ver, u16 *minor_ver); - -+int dpseci_set_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index, -+ u8 options, struct opr_cfg *cfg); -+ -+int dpseci_get_opr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u8 index, -+ struct opr_cfg *cfg, struct opr_qry *qry); -+ - /** - * enum dpseci_congestion_unit - DPSECI congestion units - * @DPSECI_CONGESTION_UNIT_BYTES: bytes units ---- a/drivers/crypto/caam/dpseci_cmd.h -+++ b/drivers/crypto/caam/dpseci_cmd.h -@@ -54,6 +54,8 @@ - #define DPSECI_CMDID_GET_TX_QUEUE DPSECI_CMD_V1(0x197) - #define DPSECI_CMDID_GET_SEC_ATTR DPSECI_CMD_V2(0x198) - #define DPSECI_CMDID_GET_SEC_COUNTERS DPSECI_CMD_V1(0x199) -+#define DPSECI_CMDID_SET_OPR DPSECI_CMD_V1(0x19A) -+#define DPSECI_CMDID_GET_OPR DPSECI_CMD_V1(0x19B) - #define DPSECI_CMDID_SET_CONGESTION_NOTIFICATION DPSECI_CMD_V1(0x170) - #define DPSECI_CMDID_GET_CONGESTION_NOTIFICATION DPSECI_CMD_V1(0x171) - -@@ -189,6 +191,55 @@ struct dpseci_rsp_get_api_version { - __le16 minor; - }; - -+struct dpseci_cmd_opr { -+ __le16 pad; -+ u8 index; -+ u8 options; -+ u8 pad1[7]; -+ u8 oloe; -+ u8 oeane; -+ u8 olws; -+ u8 oa; -+ u8 oprrws; -+}; -+ -+#define DPSECI_OPR_RIP_SHIFT 0 -+#define DPSECI_OPR_RIP_SIZE 1 -+#define DPSECI_OPR_ENABLE_SHIFT 1 -+#define DPSECI_OPR_ENABLE_SIZE 1 -+#define DPSECI_OPR_TSEQ_NLIS_SHIFT 0 -+#define DPSECI_OPR_TSEQ_NLIS_SIZE 1 -+#define DPSECI_OPR_HSEQ_NLIS_SHIFT 0 -+#define DPSECI_OPR_HSEQ_NLIS_SIZE 1 -+ -+struct dpseci_rsp_get_opr { -+ __le64 pad; -+ u8 flags; -+ u8 pad0[2]; -+ u8 oloe; -+ u8 oeane; -+ u8 olws; -+ u8 oa; -+ u8 oprrws; -+ __le16 nesn; -+ __le16 pad1; -+ __le16 ndsn; -+ __le16 pad2; -+ __le16 ea_tseq; -+ u8 tseq_nlis; -+ u8 pad3; -+ __le16 ea_hseq; -+ u8 hseq_nlis; -+ u8 pad4; -+ __le16 ea_hptr; -+ __le16 pad5; -+ __le16 ea_tptr; -+ __le16 pad6; -+ __le16 opr_vid; -+ __le16 pad7; -+ __le16 opr_id; -+}; -+ - #define DPSECI_CGN_DEST_TYPE_SHIFT 0 - #define DPSECI_CGN_DEST_TYPE_SIZE 4 - #define DPSECI_CGN_UNITS_SHIFT 4 diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0027-crypto-caam-add-support-for-MOVEB-command.patch b/target/linux/layerscape/patches-5.4/804-crypto-0027-crypto-caam-add-support-for-MOVEB-command.patch deleted file mode 100644 index 551be94f3f..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0027-crypto-caam-add-support-for-MOVEB-command.patch +++ /dev/null @@ -1,38 +0,0 @@ -From fafd87f0b6bc388b811e342ff83c88212041b119 Mon Sep 17 00:00:00 2001 -From: Radu Alexe -Date: Tue, 6 Jun 2017 12:23:56 +0300 -Subject: [PATCH] crypto: caam - add support for MOVEB command - -CHAs of SEC work natively in BE mode. When moving -data to the alignment blocks, swapping is needed -for LE platforms. This is done by means of the MOVEB -command. This patch adds support -to DCL for this command. - -Signed-off-by: Alex Porosanu -Signed-off-by: Radu Alexe ---- - drivers/crypto/caam/desc.h | 1 + - drivers/crypto/caam/desc_constr.h | 1 + - 2 files changed, 2 insertions(+) - ---- a/drivers/crypto/caam/desc.h -+++ b/drivers/crypto/caam/desc.h -@@ -43,6 +43,7 @@ - #define CMD_SEQ_LOAD (0x03 << CMD_SHIFT) - #define CMD_FIFO_LOAD (0x04 << CMD_SHIFT) - #define CMD_SEQ_FIFO_LOAD (0x05 << CMD_SHIFT) -+#define CMD_MOVEB (0x07 << CMD_SHIFT) - #define CMD_STORE (0x0a << CMD_SHIFT) - #define CMD_SEQ_STORE (0x0b << CMD_SHIFT) - #define CMD_FIFO_STORE (0x0c << CMD_SHIFT) ---- a/drivers/crypto/caam/desc_constr.h -+++ b/drivers/crypto/caam/desc_constr.h -@@ -240,6 +240,7 @@ static inline u32 *append_##cmd(u32 * co - APPEND_CMD_RET(jump, JUMP) - APPEND_CMD_RET(move, MOVE) - APPEND_CMD_RET(move_len, MOVE_LEN) -+APPEND_CMD_RET(moveb, MOVEB) - - static inline void set_jump_tgt_here(u32 * const desc, u32 *jump_cmd) - { diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0028-crypto-caam-qi-add-support-for-TLS-1.0-record.patch b/target/linux/layerscape/patches-5.4/804-crypto-0028-crypto-caam-qi-add-support-for-TLS-1.0-record.patch deleted file mode 100644 index 967266ea4a..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0028-crypto-caam-qi-add-support-for-TLS-1.0-record.patch +++ /dev/null @@ -1,1048 +0,0 @@ -From 47824cc9417946b49b80e88c74ab5ee69eacc2a7 Mon Sep 17 00:00:00 2001 -From: Radu Alexe -Date: Thu, 25 May 2017 15:51:50 +0300 -Subject: [PATCH] crypto: caam/qi - add support for TLS 1.0 record -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -TLS 1.0 descriptors run on SEC 4.x or higher. -For now, only tls10(hmac(sha1),cbc(aes)) algorithm -is registered by the driver. - -Known limitations: - - when src == dst - there should be no element in the src scatterlist array - that contains both associated data and message data. - - when src != dst - associated data is not copied from source into - destination. - - for decryption when src != dst the size of the destination should be - large enough so that the buffer may contain the decrypted authenc and - padded data. - -Signed-off-by: Tudor Ambarus -Signed-off-by: Cristian Stoica -Signed-off-by: Alex Porosanu -Signed-off-by: Horia Geantă -Signed-off-by: Radu Alexe ---- - drivers/crypto/caam/caamalg_desc.c | 414 ++++++++++++++++++++++++++++++++ - drivers/crypto/caam/caamalg_desc.h | 13 + - drivers/crypto/caam/caamalg_qi.c | 478 +++++++++++++++++++++++++++++++++++++ - drivers/crypto/caam/desc.h | 27 +++ - 4 files changed, 932 insertions(+) - ---- a/drivers/crypto/caam/caamalg_desc.c -+++ b/drivers/crypto/caam/caamalg_desc.c -@@ -622,6 +622,420 @@ copy_iv: - EXPORT_SYMBOL(cnstr_shdsc_aead_givencap); - - /** -+ * cnstr_shdsc_tls_encap - tls encapsulation shared descriptor -+ * @desc: pointer to buffer used for descriptor construction -+ * @cdata: pointer to block cipher transform definitions -+ * Valid algorithm values - one of OP_ALG_ALGSEL_AES ANDed -+ * with OP_ALG_AAI_CBC -+ * @adata: pointer to authentication transform definitions. -+ * A split key is required for SEC Era < 6; the size of the split key -+ * is specified in this case. Valid algorithm values OP_ALG_ALGSEL_SHA1 -+ * ANDed with OP_ALG_AAI_HMAC_PRECOMP. -+ * @assoclen: associated data length -+ * @ivsize: initialization vector size -+ * @authsize: authentication data size -+ * @blocksize: block cipher size -+ * @era: SEC Era -+ */ -+void cnstr_shdsc_tls_encap(u32 * const desc, struct alginfo *cdata, -+ struct alginfo *adata, unsigned int assoclen, -+ unsigned int ivsize, unsigned int authsize, -+ unsigned int blocksize, int era) -+{ -+ u32 *key_jump_cmd, *zero_payload_jump_cmd; -+ u32 genpad, idx_ld_datasz, idx_ld_pad, stidx; -+ -+ /* -+ * Compute the index (in bytes) for the LOAD with destination of -+ * Class 1 Data Size Register and for the LOAD that generates padding -+ */ -+ if (adata->key_inline) { -+ idx_ld_datasz = DESC_TLS10_ENC_LEN + adata->keylen_pad + -+ cdata->keylen - 4 * CAAM_CMD_SZ; -+ idx_ld_pad = DESC_TLS10_ENC_LEN + adata->keylen_pad + -+ cdata->keylen - 2 * CAAM_CMD_SZ; -+ } else { -+ idx_ld_datasz = DESC_TLS10_ENC_LEN + 2 * CAAM_PTR_SZ - -+ 4 * CAAM_CMD_SZ; -+ idx_ld_pad = DESC_TLS10_ENC_LEN + 2 * CAAM_PTR_SZ - -+ 2 * CAAM_CMD_SZ; -+ } -+ -+ stidx = 1 << HDR_START_IDX_SHIFT; -+ init_sh_desc(desc, HDR_SHARE_SERIAL | stidx); -+ -+ /* skip key loading if they are loaded due to sharing */ -+ key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | -+ JUMP_COND_SHRD); -+ -+ if (era < 6) { -+ if (adata->key_inline) -+ append_key_as_imm(desc, adata->key_virt, -+ adata->keylen_pad, adata->keylen, -+ CLASS_2 | KEY_DEST_MDHA_SPLIT | -+ KEY_ENC); -+ else -+ append_key(desc, adata->key_dma, adata->keylen, -+ CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC); -+ } else { -+ append_proto_dkp(desc, adata); -+ } -+ -+ if (cdata->key_inline) -+ append_key_as_imm(desc, cdata->key_virt, cdata->keylen, -+ cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); -+ else -+ append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 | -+ KEY_DEST_CLASS_REG); -+ -+ set_jump_tgt_here(desc, key_jump_cmd); -+ -+ /* class 2 operation */ -+ append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL | -+ OP_ALG_ENCRYPT); -+ /* class 1 operation */ -+ append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL | -+ OP_ALG_ENCRYPT); -+ -+ /* payloadlen = input data length - (assoclen + ivlen) */ -+ append_math_sub_imm_u32(desc, REG0, SEQINLEN, IMM, assoclen + ivsize); -+ -+ /* math1 = payloadlen + icvlen */ -+ append_math_add_imm_u32(desc, REG1, REG0, IMM, authsize); -+ -+ /* padlen = block_size - math1 % block_size */ -+ append_math_and_imm_u32(desc, REG3, REG1, IMM, blocksize - 1); -+ append_math_sub_imm_u32(desc, REG2, IMM, REG3, blocksize); -+ -+ /* cryptlen = payloadlen + icvlen + padlen */ -+ append_math_add(desc, VARSEQOUTLEN, REG1, REG2, 4); -+ -+ /* -+ * update immediate data with the padding length value -+ * for the LOAD in the class 1 data size register. -+ */ -+ append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH2 | -+ (idx_ld_datasz << MOVE_OFFSET_SHIFT) | 7); -+ append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH2 | MOVE_DEST_DESCBUF | -+ (idx_ld_datasz << MOVE_OFFSET_SHIFT) | 8); -+ -+ /* overwrite PL field for the padding iNFO FIFO entry */ -+ append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH2 | -+ (idx_ld_pad << MOVE_OFFSET_SHIFT) | 7); -+ append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH2 | MOVE_DEST_DESCBUF | -+ (idx_ld_pad << MOVE_OFFSET_SHIFT) | 8); -+ -+ /* store encrypted payload, icv and padding */ -+ append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF); -+ -+ /* if payload length is zero, jump to zero-payload commands */ -+ append_math_add(desc, VARSEQINLEN, ZERO, REG0, 4); -+ zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL | -+ JUMP_COND_MATH_Z); -+ -+ /* load iv in context1 */ -+ append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_WORD_CLASS_CTX | -+ LDST_CLASS_1_CCB | ivsize); -+ -+ /* read assoc for authentication */ -+ append_seq_fifo_load(desc, assoclen, FIFOLD_CLASS_CLASS2 | -+ FIFOLD_TYPE_MSG); -+ /* insnoop payload */ -+ append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG | -+ FIFOLD_TYPE_LAST2 | FIFOLDST_VLF); -+ -+ /* jump the zero-payload commands */ -+ append_jump(desc, JUMP_TEST_ALL | 3); -+ -+ /* zero-payload commands */ -+ set_jump_tgt_here(desc, zero_payload_jump_cmd); -+ -+ /* load iv in context1 */ -+ append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_WORD_CLASS_CTX | -+ LDST_CLASS_1_CCB | ivsize); -+ -+ /* assoc data is the only data for authentication */ -+ append_seq_fifo_load(desc, assoclen, FIFOLD_CLASS_CLASS2 | -+ FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2); -+ -+ /* send icv to encryption */ -+ append_move(desc, MOVE_SRC_CLASS2CTX | MOVE_DEST_CLASS1INFIFO | -+ authsize); -+ -+ /* update class 1 data size register with padding length */ -+ append_load_imm_u32(desc, 0, LDST_CLASS_1_CCB | -+ LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM); -+ -+ /* generate padding and send it to encryption */ -+ genpad = NFIFOENTRY_DEST_CLASS1 | NFIFOENTRY_LC1 | NFIFOENTRY_FC1 | -+ NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_PTYPE_N; -+ append_load_imm_u32(desc, genpad, LDST_CLASS_IND_CCB | -+ LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM); -+ -+#ifdef DEBUG -+ print_hex_dump(KERN_ERR, "tls enc shdesc@" __stringify(__LINE__) ": ", -+ DUMP_PREFIX_ADDRESS, 16, 4, desc, -+ desc_bytes(desc), 1); -+#endif -+} -+EXPORT_SYMBOL(cnstr_shdsc_tls_encap); -+ -+/** -+ * cnstr_shdsc_tls_decap - tls decapsulation shared descriptor -+ * @desc: pointer to buffer used for descriptor construction -+ * @cdata: pointer to block cipher transform definitions -+ * Valid algorithm values - one of OP_ALG_ALGSEL_AES ANDed -+ * with OP_ALG_AAI_CBC -+ * @adata: pointer to authentication transform definitions. -+ * A split key is required for SEC Era < 6; the size of the split key -+ * is specified in this case. Valid algorithm values OP_ALG_ALGSEL_SHA1 -+ * ANDed with OP_ALG_AAI_HMAC_PRECOMP. -+ * @assoclen: associated data length -+ * @ivsize: initialization vector size -+ * @authsize: authentication data size -+ * @blocksize: block cipher size -+ * @era: SEC Era -+ */ -+void cnstr_shdsc_tls_decap(u32 * const desc, struct alginfo *cdata, -+ struct alginfo *adata, unsigned int assoclen, -+ unsigned int ivsize, unsigned int authsize, -+ unsigned int blocksize, int era) -+{ -+ u32 stidx, jumpback; -+ u32 *key_jump_cmd, *zero_payload_jump_cmd, *skip_zero_jump_cmd; -+ /* -+ * Pointer Size bool determines the size of address pointers. -+ * false - Pointers fit in one 32-bit word. -+ * true - Pointers fit in two 32-bit words. -+ */ -+ bool ps = (CAAM_PTR_SZ != CAAM_CMD_SZ); -+ -+ stidx = 1 << HDR_START_IDX_SHIFT; -+ init_sh_desc(desc, HDR_SHARE_SERIAL | stidx); -+ -+ /* skip key loading if they are loaded due to sharing */ -+ key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | -+ JUMP_COND_SHRD); -+ -+ if (era < 6) -+ append_key(desc, adata->key_dma, adata->keylen, CLASS_2 | -+ KEY_DEST_MDHA_SPLIT | KEY_ENC); -+ else -+ append_proto_dkp(desc, adata); -+ -+ append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 | -+ KEY_DEST_CLASS_REG); -+ -+ set_jump_tgt_here(desc, key_jump_cmd); -+ -+ /* class 2 operation */ -+ append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL | -+ OP_ALG_DECRYPT | OP_ALG_ICV_ON); -+ /* class 1 operation */ -+ append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL | -+ OP_ALG_DECRYPT); -+ -+ /* VSIL = input data length - 2 * block_size */ -+ append_math_sub_imm_u32(desc, VARSEQINLEN, SEQINLEN, IMM, 2 * -+ blocksize); -+ -+ /* -+ * payloadlen + icvlen + padlen = input data length - (assoclen + -+ * ivsize) -+ */ -+ append_math_sub_imm_u32(desc, REG3, SEQINLEN, IMM, assoclen + ivsize); -+ -+ /* skip data to the last but one cipher block */ -+ append_seq_fifo_load(desc, 0, FIFOLD_CLASS_SKIP | LDST_VLF); -+ -+ /* load iv for the last cipher block */ -+ append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_WORD_CLASS_CTX | -+ LDST_CLASS_1_CCB | ivsize); -+ -+ /* read last cipher block */ -+ append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG | -+ FIFOLD_TYPE_LAST1 | blocksize); -+ -+ /* move decrypted block into math0 and math1 */ -+ append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO | MOVE_DEST_MATH0 | -+ blocksize); -+ -+ /* reset AES CHA */ -+ append_load_imm_u32(desc, CCTRL_RESET_CHA_AESA, LDST_CLASS_IND_CCB | -+ LDST_SRCDST_WORD_CHACTRL | LDST_IMM); -+ -+ /* rewind input sequence */ -+ append_seq_in_ptr_intlen(desc, 0, 65535, SQIN_RTO); -+ -+ /* key1 is in decryption form */ -+ append_operation(desc, cdata->algtype | OP_ALG_AAI_DK | -+ OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT); -+ -+ /* load iv in context1 */ -+ append_cmd(desc, CMD_SEQ_LOAD | LDST_CLASS_1_CCB | -+ LDST_SRCDST_WORD_CLASS_CTX | ivsize); -+ -+ /* read sequence number */ -+ append_seq_fifo_load(desc, 8, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG); -+ /* load Type, Version and Len fields in math0 */ -+ append_cmd(desc, CMD_SEQ_LOAD | LDST_CLASS_DECO | -+ LDST_SRCDST_WORD_DECO_MATH0 | (3 << LDST_OFFSET_SHIFT) | 5); -+ -+ /* compute (padlen - 1) */ -+ append_math_and_imm_u64(desc, REG1, REG1, IMM, 255); -+ -+ /* math2 = icvlen + (padlen - 1) + 1 */ -+ append_math_add_imm_u32(desc, REG2, REG1, IMM, authsize + 1); -+ -+ append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | 1); -+ -+ /* VSOL = payloadlen + icvlen + padlen */ -+ append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, 4); -+ -+ if (caam_little_end) -+ append_moveb(desc, MOVE_WAITCOMP | -+ MOVE_SRC_MATH0 | MOVE_DEST_MATH0 | 8); -+ -+ /* update Len field */ -+ append_math_sub(desc, REG0, REG0, REG2, 8); -+ -+ /* store decrypted payload, icv and padding */ -+ append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF); -+ -+ /* VSIL = (payloadlen + icvlen + padlen) - (icvlen + padlen)*/ -+ append_math_sub(desc, VARSEQINLEN, REG3, REG2, 4); -+ -+ zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL | -+ JUMP_COND_MATH_Z); -+ -+ /* send Type, Version and Len(pre ICV) fields to authentication */ -+ append_move(desc, MOVE_WAITCOMP | -+ MOVE_SRC_MATH0 | MOVE_DEST_CLASS2INFIFO | -+ (3 << MOVE_OFFSET_SHIFT) | 5); -+ -+ /* outsnooping payload */ -+ append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | -+ FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LAST2 | -+ FIFOLDST_VLF); -+ skip_zero_jump_cmd = append_jump(desc, JUMP_TEST_ALL | 2); -+ -+ set_jump_tgt_here(desc, zero_payload_jump_cmd); -+ /* send Type, Version and Len(pre ICV) fields to authentication */ -+ append_move(desc, MOVE_WAITCOMP | MOVE_AUX_LS | -+ MOVE_SRC_MATH0 | MOVE_DEST_CLASS2INFIFO | -+ (3 << MOVE_OFFSET_SHIFT) | 5); -+ -+ set_jump_tgt_here(desc, skip_zero_jump_cmd); -+ append_math_add(desc, VARSEQINLEN, ZERO, REG2, 4); -+ -+ /* load icvlen and padlen */ -+ append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG | -+ FIFOLD_TYPE_LAST1 | FIFOLDST_VLF); -+ -+ /* VSIL = (payloadlen + icvlen + padlen) - icvlen + padlen */ -+ append_math_sub(desc, VARSEQINLEN, REG3, REG2, 4); -+ -+ /* -+ * Start a new input sequence using the SEQ OUT PTR command options, -+ * pointer and length used when the current output sequence was defined. -+ */ -+ if (ps) { -+ /* -+ * Move the lower 32 bits of Shared Descriptor address, the -+ * SEQ OUT PTR command, Output Pointer (2 words) and -+ * Output Length into math registers. -+ */ -+ if (caam_little_end) -+ append_move(desc, MOVE_WAITCOMP | MOVE_SRC_DESCBUF | -+ MOVE_DEST_MATH0 | -+ (55 * 4 << MOVE_OFFSET_SHIFT) | 20); -+ else -+ append_move(desc, MOVE_WAITCOMP | MOVE_SRC_DESCBUF | -+ MOVE_DEST_MATH0 | -+ (54 * 4 << MOVE_OFFSET_SHIFT) | 20); -+ -+ /* Transform SEQ OUT PTR command in SEQ IN PTR command */ -+ append_math_and_imm_u32(desc, REG0, REG0, IMM, -+ ~(CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR)); -+ /* Append a JUMP command after the copied fields */ -+ jumpback = CMD_JUMP | (char)-9; -+ append_load_imm_u32(desc, jumpback, LDST_CLASS_DECO | LDST_IMM | -+ LDST_SRCDST_WORD_DECO_MATH2 | -+ (4 << LDST_OFFSET_SHIFT)); -+ append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | 1); -+ /* Move the updated fields back to the Job Descriptor */ -+ if (caam_little_end) -+ append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH0 | -+ MOVE_DEST_DESCBUF | -+ (55 * 4 << MOVE_OFFSET_SHIFT) | 24); -+ else -+ append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH0 | -+ MOVE_DEST_DESCBUF | -+ (54 * 4 << MOVE_OFFSET_SHIFT) | 24); -+ -+ /* -+ * Read the new SEQ IN PTR command, Input Pointer, Input Length -+ * and then jump back to the next command from the -+ * Shared Descriptor. -+ */ -+ append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | 6); -+ } else { -+ /* -+ * Move the SEQ OUT PTR command, Output Pointer (1 word) and -+ * Output Length into math registers. -+ */ -+ if (caam_little_end) -+ append_move(desc, MOVE_WAITCOMP | MOVE_SRC_DESCBUF | -+ MOVE_DEST_MATH0 | -+ (54 * 4 << MOVE_OFFSET_SHIFT) | 12); -+ else -+ append_move(desc, MOVE_WAITCOMP | MOVE_SRC_DESCBUF | -+ MOVE_DEST_MATH0 | -+ (53 * 4 << MOVE_OFFSET_SHIFT) | 12); -+ -+ /* Transform SEQ OUT PTR command in SEQ IN PTR command */ -+ append_math_and_imm_u64(desc, REG0, REG0, IMM, -+ ~(((u64)(CMD_SEQ_IN_PTR ^ -+ CMD_SEQ_OUT_PTR)) << 32)); -+ /* Append a JUMP command after the copied fields */ -+ jumpback = CMD_JUMP | (char)-7; -+ append_load_imm_u32(desc, jumpback, LDST_CLASS_DECO | LDST_IMM | -+ LDST_SRCDST_WORD_DECO_MATH1 | -+ (4 << LDST_OFFSET_SHIFT)); -+ append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | 1); -+ /* Move the updated fields back to the Job Descriptor */ -+ if (caam_little_end) -+ append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH0 | -+ MOVE_DEST_DESCBUF | -+ (54 * 4 << MOVE_OFFSET_SHIFT) | 16); -+ else -+ append_move(desc, MOVE_WAITCOMP | MOVE_SRC_MATH0 | -+ MOVE_DEST_DESCBUF | -+ (53 * 4 << MOVE_OFFSET_SHIFT) | 16); -+ -+ /* -+ * Read the new SEQ IN PTR command, Input Pointer, Input Length -+ * and then jump back to the next command from the -+ * Shared Descriptor. -+ */ -+ append_jump(desc, JUMP_TEST_ALL | JUMP_COND_CALM | 5); -+ } -+ -+ /* skip payload */ -+ append_seq_fifo_load(desc, 0, FIFOLD_CLASS_SKIP | FIFOLDST_VLF); -+ /* check icv */ -+ append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_ICV | -+ FIFOLD_TYPE_LAST2 | authsize); -+ -+#ifdef DEBUG -+ print_hex_dump(KERN_ERR, "tls dec shdesc@" __stringify(__LINE__) ": ", -+ DUMP_PREFIX_ADDRESS, 16, 4, desc, -+ desc_bytes(desc), 1); -+#endif -+} -+EXPORT_SYMBOL(cnstr_shdsc_tls_decap); -+ -+/** - * cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor - * @desc: pointer to buffer used for descriptor construction - * @cdata: pointer to block cipher transform definitions ---- a/drivers/crypto/caam/caamalg_desc.h -+++ b/drivers/crypto/caam/caamalg_desc.h -@@ -17,6 +17,9 @@ - #define DESC_QI_AEAD_DEC_LEN (DESC_AEAD_DEC_LEN + 3 * CAAM_CMD_SZ) - #define DESC_QI_AEAD_GIVENC_LEN (DESC_AEAD_GIVENC_LEN + 3 * CAAM_CMD_SZ) - -+#define DESC_TLS_BASE (4 * CAAM_CMD_SZ) -+#define DESC_TLS10_ENC_LEN (DESC_TLS_BASE + 29 * CAAM_CMD_SZ) -+ - /* Note: Nonce is counted in cdata.keylen */ - #define DESC_AEAD_CTR_RFC3686_LEN (4 * CAAM_CMD_SZ) - -@@ -72,6 +75,16 @@ void cnstr_shdsc_aead_givencap(u32 * con - u32 *nonce, const u32 ctx1_iv_off, - const bool is_qi, int era); - -+void cnstr_shdsc_tls_encap(u32 *const desc, struct alginfo *cdata, -+ struct alginfo *adata, unsigned int assoclen, -+ unsigned int ivsize, unsigned int authsize, -+ unsigned int blocksize, int era); -+ -+void cnstr_shdsc_tls_decap(u32 *const desc, struct alginfo *cdata, -+ struct alginfo *adata, unsigned int assoclen, -+ unsigned int ivsize, unsigned int authsize, -+ unsigned int blocksize, int era); -+ - void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata, - unsigned int ivsize, unsigned int icvsize, - const bool is_qi); ---- a/drivers/crypto/caam/caamalg_qi.c -+++ b/drivers/crypto/caam/caamalg_qi.c -@@ -296,6 +296,167 @@ static int des3_aead_setkey(struct crypt - return err; - } - -+static int tls_set_sh_desc(struct crypto_aead *tls) -+{ -+ struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ unsigned int ivsize = crypto_aead_ivsize(tls); -+ unsigned int blocksize = crypto_aead_blocksize(tls); -+ unsigned int assoclen = 13; /* always 13 bytes for TLS */ -+ unsigned int data_len[2]; -+ u32 inl_mask; -+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent); -+ -+ if (!ctx->cdata.keylen || !ctx->authsize) -+ return 0; -+ -+ /* -+ * TLS 1.0 encrypt shared descriptor -+ * Job Descriptor and Shared Descriptor -+ * must fit into the 64-word Descriptor h/w Buffer -+ */ -+ data_len[0] = ctx->adata.keylen_pad; -+ data_len[1] = ctx->cdata.keylen; -+ -+ if (desc_inline_query(DESC_TLS10_ENC_LEN, DESC_JOB_IO_LEN, data_len, -+ &inl_mask, ARRAY_SIZE(data_len)) < 0) -+ return -EINVAL; -+ -+ if (inl_mask & 1) -+ ctx->adata.key_virt = ctx->key; -+ else -+ ctx->adata.key_dma = ctx->key_dma; -+ -+ if (inl_mask & 2) -+ ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad; -+ else -+ ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad; -+ -+ ctx->adata.key_inline = !!(inl_mask & 1); -+ ctx->cdata.key_inline = !!(inl_mask & 2); -+ -+ cnstr_shdsc_tls_encap(ctx->sh_desc_enc, &ctx->cdata, &ctx->adata, -+ assoclen, ivsize, ctx->authsize, blocksize, -+ ctrlpriv->era); -+ -+ /* -+ * TLS 1.0 decrypt shared descriptor -+ * Keys do not fit inline, regardless of algorithms used -+ */ -+ ctx->adata.key_inline = false; -+ ctx->adata.key_dma = ctx->key_dma; -+ ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad; -+ -+ cnstr_shdsc_tls_decap(ctx->sh_desc_dec, &ctx->cdata, &ctx->adata, -+ assoclen, ivsize, ctx->authsize, blocksize, -+ ctrlpriv->era); -+ -+ return 0; -+} -+ -+static int tls_setauthsize(struct crypto_aead *tls, unsigned int authsize) -+{ -+ struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ -+ ctx->authsize = authsize; -+ tls_set_sh_desc(tls); -+ -+ return 0; -+} -+ -+static int tls_setkey(struct crypto_aead *tls, const u8 *key, -+ unsigned int keylen) -+{ -+ struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ struct device *jrdev = ctx->jrdev; -+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent); -+ struct crypto_authenc_keys keys; -+ int ret = 0; -+ -+ if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) -+ goto badkey; -+ -+#ifdef DEBUG -+ dev_err(jrdev, "keylen %d enckeylen %d authkeylen %d\n", -+ keys.authkeylen + keys.enckeylen, keys.enckeylen, -+ keys.authkeylen); -+ print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ", -+ DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); -+#endif -+ -+ /* -+ * If DKP is supported, use it in the shared descriptor to generate -+ * the split key. -+ */ -+ if (ctrlpriv->era >= 6) { -+ ctx->adata.keylen = keys.authkeylen; -+ ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype & -+ OP_ALG_ALGSEL_MASK); -+ -+ if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE) -+ goto badkey; -+ -+ memcpy(ctx->key, keys.authkey, keys.authkeylen); -+ memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, -+ keys.enckeylen); -+ dma_sync_single_for_device(jrdev, ctx->key_dma, -+ ctx->adata.keylen_pad + -+ keys.enckeylen, ctx->dir); -+ goto skip_split_key; -+ } -+ -+ ret = gen_split_key(jrdev, ctx->key, &ctx->adata, keys.authkey, -+ keys.authkeylen, CAAM_MAX_KEY_SIZE - -+ keys.enckeylen); -+ if (ret) -+ goto badkey; -+ -+ /* postpend encryption key to auth split key */ -+ memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen); -+ dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad + -+ keys.enckeylen, ctx->dir); -+ -+#ifdef DEBUG -+ dev_err(jrdev, "split keylen %d split keylen padded %d\n", -+ ctx->adata.keylen, ctx->adata.keylen_pad); -+ print_hex_dump(KERN_ERR, "ctx.key@" __stringify(__LINE__)": ", -+ DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, -+ ctx->adata.keylen_pad + keys.enckeylen, 1); -+#endif -+ -+skip_split_key: -+ ctx->cdata.keylen = keys.enckeylen; -+ -+ ret = tls_set_sh_desc(tls); -+ if (ret) -+ goto badkey; -+ -+ /* Now update the driver contexts with the new shared descriptor */ -+ if (ctx->drv_ctx[ENCRYPT]) { -+ ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT], -+ ctx->sh_desc_enc); -+ if (ret) { -+ dev_err(jrdev, "driver enc context update failed\n"); -+ goto badkey; -+ } -+ } -+ -+ if (ctx->drv_ctx[DECRYPT]) { -+ ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT], -+ ctx->sh_desc_dec); -+ if (ret) { -+ dev_err(jrdev, "driver dec context update failed\n"); -+ goto badkey; -+ } -+ } -+ -+ memzero_explicit(&keys, sizeof(keys)); -+ return ret; -+badkey: -+ crypto_aead_set_flags(tls, CRYPTO_TFM_RES_BAD_KEY_LEN); -+ memzero_explicit(&keys, sizeof(keys)); -+ return -EINVAL; -+} -+ - static int gcm_set_sh_desc(struct crypto_aead *aead) - { - struct caam_ctx *ctx = crypto_aead_ctx(aead); -@@ -820,6 +981,29 @@ struct aead_edesc { - }; - - /* -+ * tls_edesc - s/w-extended tls descriptor -+ * @src_nents: number of segments in input scatterlist -+ * @dst_nents: number of segments in output scatterlist -+ * @iv_dma: dma address of iv for checking continuity and link table -+ * @qm_sg_bytes: length of dma mapped h/w link table -+ * @tmp: array of scatterlists used by 'scatterwalk_ffwd' -+ * @qm_sg_dma: bus physical mapped address of h/w link table -+ * @drv_req: driver-specific request structure -+ * @sgt: the h/w link table, followed by IV -+ */ -+struct tls_edesc { -+ int src_nents; -+ int dst_nents; -+ dma_addr_t iv_dma; -+ int qm_sg_bytes; -+ dma_addr_t qm_sg_dma; -+ struct scatterlist tmp[2]; -+ struct scatterlist *dst; -+ struct caam_drv_req drv_req; -+ struct qm_sg_entry sgt[0]; -+}; -+ -+/* - * skcipher_edesc - s/w-extended skcipher descriptor - * @src_nents: number of segments in input scatterlist - * @dst_nents: number of segments in output scatterlist -@@ -911,6 +1095,18 @@ static void aead_unmap(struct device *de - dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE); - } - -+static void tls_unmap(struct device *dev, -+ struct tls_edesc *edesc, -+ struct aead_request *req) -+{ -+ struct crypto_aead *aead = crypto_aead_reqtfm(req); -+ int ivsize = crypto_aead_ivsize(aead); -+ -+ caam_unmap(dev, req->src, edesc->dst, edesc->src_nents, -+ edesc->dst_nents, edesc->iv_dma, ivsize, DMA_TO_DEVICE, -+ edesc->qm_sg_dma, edesc->qm_sg_bytes); -+} -+ - static void skcipher_unmap(struct device *dev, struct skcipher_edesc *edesc, - struct skcipher_request *req) - { -@@ -1203,6 +1399,243 @@ static int aead_decrypt(struct aead_requ - return aead_crypt(req, false); - } - -+static void tls_done(struct caam_drv_req *drv_req, u32 status) -+{ -+ struct device *qidev; -+ struct tls_edesc *edesc; -+ struct aead_request *aead_req = drv_req->app_ctx; -+ struct crypto_aead *aead = crypto_aead_reqtfm(aead_req); -+ struct caam_ctx *caam_ctx = crypto_aead_ctx(aead); -+ int ecode = 0; -+ -+ qidev = caam_ctx->qidev; -+ -+ if (unlikely(status)) { -+ caam_jr_strstatus(qidev, status); -+ ecode = -EIO; -+ } -+ -+ edesc = container_of(drv_req, typeof(*edesc), drv_req); -+ tls_unmap(qidev, edesc, aead_req); -+ -+ aead_request_complete(aead_req, ecode); -+ qi_cache_free(edesc); -+} -+ -+/* -+ * allocate and map the tls extended descriptor -+ */ -+static struct tls_edesc *tls_edesc_alloc(struct aead_request *req, bool encrypt) -+{ -+ struct crypto_aead *aead = crypto_aead_reqtfm(req); -+ struct caam_ctx *ctx = crypto_aead_ctx(aead); -+ unsigned int blocksize = crypto_aead_blocksize(aead); -+ unsigned int padsize, authsize; -+ struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead), -+ typeof(*alg), aead); -+ struct device *qidev = ctx->qidev; -+ gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? -+ GFP_KERNEL : GFP_ATOMIC; -+ int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0; -+ struct tls_edesc *edesc; -+ dma_addr_t qm_sg_dma, iv_dma = 0; -+ int ivsize = 0; -+ u8 *iv; -+ int qm_sg_index, qm_sg_ents = 0, qm_sg_bytes; -+ int in_len, out_len; -+ struct qm_sg_entry *sg_table, *fd_sgt; -+ struct caam_drv_ctx *drv_ctx; -+ struct scatterlist *dst; -+ -+ if (encrypt) { -+ padsize = blocksize - ((req->cryptlen + ctx->authsize) % -+ blocksize); -+ authsize = ctx->authsize + padsize; -+ } else { -+ authsize = ctx->authsize; -+ } -+ -+ drv_ctx = get_drv_ctx(ctx, encrypt ? ENCRYPT : DECRYPT); -+ if (unlikely(IS_ERR_OR_NULL(drv_ctx))) -+ return (struct tls_edesc *)drv_ctx; -+ -+ /* allocate space for base edesc, link tables and IV */ -+ edesc = qi_cache_alloc(GFP_DMA | flags); -+ if (unlikely(!edesc)) { -+ dev_err(qidev, "could not allocate extended descriptor\n"); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ if (likely(req->src == req->dst)) { -+ src_nents = sg_nents_for_len(req->src, req->assoclen + -+ req->cryptlen + -+ (encrypt ? authsize : 0)); -+ if (unlikely(src_nents < 0)) { -+ dev_err(qidev, "Insufficient bytes (%d) in src S/G\n", -+ req->assoclen + req->cryptlen + -+ (encrypt ? authsize : 0)); -+ qi_cache_free(edesc); -+ return ERR_PTR(src_nents); -+ } -+ -+ mapped_src_nents = dma_map_sg(qidev, req->src, src_nents, -+ DMA_BIDIRECTIONAL); -+ if (unlikely(!mapped_src_nents)) { -+ dev_err(qidev, "unable to map source\n"); -+ qi_cache_free(edesc); -+ return ERR_PTR(-ENOMEM); -+ } -+ dst = req->dst; -+ } else { -+ src_nents = sg_nents_for_len(req->src, req->assoclen + -+ req->cryptlen); -+ if (unlikely(src_nents < 0)) { -+ dev_err(qidev, "Insufficient bytes (%d) in src S/G\n", -+ req->assoclen + req->cryptlen); -+ qi_cache_free(edesc); -+ return ERR_PTR(src_nents); -+ } -+ -+ dst = scatterwalk_ffwd(edesc->tmp, req->dst, req->assoclen); -+ dst_nents = sg_nents_for_len(dst, req->cryptlen + -+ (encrypt ? authsize : 0)); -+ if (unlikely(dst_nents < 0)) { -+ dev_err(qidev, "Insufficient bytes (%d) in dst S/G\n", -+ req->cryptlen + -+ (encrypt ? authsize : 0)); -+ qi_cache_free(edesc); -+ return ERR_PTR(dst_nents); -+ } -+ -+ if (src_nents) { -+ mapped_src_nents = dma_map_sg(qidev, req->src, -+ src_nents, DMA_TO_DEVICE); -+ if (unlikely(!mapped_src_nents)) { -+ dev_err(qidev, "unable to map source\n"); -+ qi_cache_free(edesc); -+ return ERR_PTR(-ENOMEM); -+ } -+ } else { -+ mapped_src_nents = 0; -+ } -+ -+ mapped_dst_nents = dma_map_sg(qidev, dst, dst_nents, -+ DMA_FROM_DEVICE); -+ if (unlikely(!mapped_dst_nents)) { -+ dev_err(qidev, "unable to map destination\n"); -+ dma_unmap_sg(qidev, req->src, src_nents, DMA_TO_DEVICE); -+ qi_cache_free(edesc); -+ return ERR_PTR(-ENOMEM); -+ } -+ } -+ -+ /* -+ * Create S/G table: IV, src, dst. -+ * Input is not contiguous. -+ */ -+ qm_sg_ents = 1 + mapped_src_nents + -+ (mapped_dst_nents > 1 ? mapped_dst_nents : 0); -+ sg_table = &edesc->sgt[0]; -+ qm_sg_bytes = qm_sg_ents * sizeof(*sg_table); -+ -+ ivsize = crypto_aead_ivsize(aead); -+ iv = (u8 *)(sg_table + qm_sg_ents); -+ /* Make sure IV is located in a DMAable area */ -+ memcpy(iv, req->iv, ivsize); -+ iv_dma = dma_map_single(qidev, iv, ivsize, DMA_TO_DEVICE); -+ if (dma_mapping_error(qidev, iv_dma)) { -+ dev_err(qidev, "unable to map IV\n"); -+ caam_unmap(qidev, req->src, dst, src_nents, dst_nents, 0, 0, -+ DMA_NONE, 0, 0); -+ qi_cache_free(edesc); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ edesc->src_nents = src_nents; -+ edesc->dst_nents = dst_nents; -+ edesc->dst = dst; -+ edesc->iv_dma = iv_dma; -+ edesc->drv_req.app_ctx = req; -+ edesc->drv_req.cbk = tls_done; -+ edesc->drv_req.drv_ctx = drv_ctx; -+ -+ dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0); -+ qm_sg_index = 1; -+ -+ sg_to_qm_sg_last(req->src, mapped_src_nents, sg_table + qm_sg_index, 0); -+ qm_sg_index += mapped_src_nents; -+ -+ if (mapped_dst_nents > 1) -+ sg_to_qm_sg_last(dst, mapped_dst_nents, sg_table + -+ qm_sg_index, 0); -+ -+ qm_sg_dma = dma_map_single(qidev, sg_table, qm_sg_bytes, DMA_TO_DEVICE); -+ if (dma_mapping_error(qidev, qm_sg_dma)) { -+ dev_err(qidev, "unable to map S/G table\n"); -+ caam_unmap(qidev, req->src, dst, src_nents, dst_nents, iv_dma, -+ ivsize, DMA_TO_DEVICE, 0, 0); -+ qi_cache_free(edesc); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ edesc->qm_sg_dma = qm_sg_dma; -+ edesc->qm_sg_bytes = qm_sg_bytes; -+ -+ out_len = req->cryptlen + (encrypt ? authsize : 0); -+ in_len = ivsize + req->assoclen + req->cryptlen; -+ -+ fd_sgt = &edesc->drv_req.fd_sgt[0]; -+ -+ dma_to_qm_sg_one_last_ext(&fd_sgt[1], qm_sg_dma, in_len, 0); -+ -+ if (req->dst == req->src) -+ dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma + -+ (sg_nents_for_len(req->src, req->assoclen) + -+ 1) * sizeof(*sg_table), out_len, 0); -+ else if (mapped_dst_nents == 1) -+ dma_to_qm_sg_one(&fd_sgt[0], sg_dma_address(dst), out_len, 0); -+ else -+ dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma + sizeof(*sg_table) * -+ qm_sg_index, out_len, 0); -+ -+ return edesc; -+} -+ -+static int tls_crypt(struct aead_request *req, bool encrypt) -+{ -+ struct tls_edesc *edesc; -+ struct crypto_aead *aead = crypto_aead_reqtfm(req); -+ struct caam_ctx *ctx = crypto_aead_ctx(aead); -+ int ret; -+ -+ if (unlikely(caam_congested)) -+ return -EAGAIN; -+ -+ edesc = tls_edesc_alloc(req, encrypt); -+ if (IS_ERR_OR_NULL(edesc)) -+ return PTR_ERR(edesc); -+ -+ ret = caam_qi_enqueue(ctx->qidev, &edesc->drv_req); -+ if (!ret) { -+ ret = -EINPROGRESS; -+ } else { -+ tls_unmap(ctx->qidev, edesc, req); -+ qi_cache_free(edesc); -+ } -+ -+ return ret; -+} -+ -+static int tls_encrypt(struct aead_request *req) -+{ -+ return tls_crypt(req, true); -+} -+ -+static int tls_decrypt(struct aead_request *req) -+{ -+ return tls_crypt(req, false); -+} -+ - static int ipsec_gcm_encrypt(struct aead_request *req) - { - return crypto_ipsec_check_assoclen(req->assoclen) ? : aead_crypt(req, -@@ -2446,6 +2879,26 @@ static struct caam_aead_alg driver_aeads - .geniv = true, - } - }, -+ { -+ .aead = { -+ .base = { -+ .cra_name = "tls10(hmac(sha1),cbc(aes))", -+ .cra_driver_name = "tls10-hmac-sha1-cbc-aes-caam-qi", -+ .cra_blocksize = AES_BLOCK_SIZE, -+ }, -+ .setkey = tls_setkey, -+ .setauthsize = tls_setauthsize, -+ .encrypt = tls_encrypt, -+ .decrypt = tls_decrypt, -+ .ivsize = AES_BLOCK_SIZE, -+ .maxauthsize = SHA1_DIGEST_SIZE, -+ }, -+ .caam = { -+ .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, -+ .class2_alg_type = OP_ALG_ALGSEL_SHA1 | -+ OP_ALG_AAI_HMAC_PRECOMP, -+ } -+ } - }; - - static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam, -@@ -2453,6 +2906,16 @@ static int caam_init_common(struct caam_ - { - struct caam_drv_private *priv; - struct device *dev; -+ /* Digest sizes for MD5, SHA1, SHA-224, SHA-256, SHA-384, SHA-512 */ -+ static const u8 digest_size[] = { -+ MD5_DIGEST_SIZE, -+ SHA1_DIGEST_SIZE, -+ SHA224_DIGEST_SIZE, -+ SHA256_DIGEST_SIZE, -+ SHA384_DIGEST_SIZE, -+ SHA512_DIGEST_SIZE -+ }; -+ u8 op_id; - - /* - * distribute tfms across job rings to ensure in-order -@@ -2484,6 +2947,21 @@ static int caam_init_common(struct caam_ - ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type; - - ctx->qidev = dev; -+ if (ctx->adata.algtype) { -+ op_id = (ctx->adata.algtype & OP_ALG_ALGSEL_SUBMASK) -+ >> OP_ALG_ALGSEL_SHIFT; -+ if (op_id < ARRAY_SIZE(digest_size)) { -+ ctx->authsize = digest_size[op_id]; -+ } else { -+ dev_err(ctx->jrdev, -+ "incorrect op_id %d; must be less than %zu\n", -+ op_id, ARRAY_SIZE(digest_size)); -+ caam_jr_free(ctx->jrdev); -+ return -EINVAL; -+ } -+ } else { -+ ctx->authsize = 0; -+ } - - spin_lock_init(&ctx->lock); - ctx->drv_ctx[ENCRYPT] = NULL; ---- a/drivers/crypto/caam/desc.h -+++ b/drivers/crypto/caam/desc.h -@@ -1704,4 +1704,31 @@ - /* Frame Descriptor Command for Replacement Job Descriptor */ - #define FD_CMD_REPLACE_JOB_DESC 0x20000000 - -+/* CHA Control Register bits */ -+#define CCTRL_RESET_CHA_ALL 0x1 -+#define CCTRL_RESET_CHA_AESA 0x2 -+#define CCTRL_RESET_CHA_DESA 0x4 -+#define CCTRL_RESET_CHA_AFHA 0x8 -+#define CCTRL_RESET_CHA_KFHA 0x10 -+#define CCTRL_RESET_CHA_SF8A 0x20 -+#define CCTRL_RESET_CHA_PKHA 0x40 -+#define CCTRL_RESET_CHA_MDHA 0x80 -+#define CCTRL_RESET_CHA_CRCA 0x100 -+#define CCTRL_RESET_CHA_RNG 0x200 -+#define CCTRL_RESET_CHA_SF9A 0x400 -+#define CCTRL_RESET_CHA_ZUCE 0x800 -+#define CCTRL_RESET_CHA_ZUCA 0x1000 -+#define CCTRL_UNLOAD_PK_A0 0x10000 -+#define CCTRL_UNLOAD_PK_A1 0x20000 -+#define CCTRL_UNLOAD_PK_A2 0x40000 -+#define CCTRL_UNLOAD_PK_A3 0x80000 -+#define CCTRL_UNLOAD_PK_B0 0x100000 -+#define CCTRL_UNLOAD_PK_B1 0x200000 -+#define CCTRL_UNLOAD_PK_B2 0x400000 -+#define CCTRL_UNLOAD_PK_B3 0x800000 -+#define CCTRL_UNLOAD_PK_N 0x1000000 -+#define CCTRL_UNLOAD_PK_A 0x4000000 -+#define CCTRL_UNLOAD_PK_B 0x8000000 -+#define CCTRL_UNLOAD_SBOX 0x10000000 -+ - #endif /* DESC_H */ diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0029-crypto-caam-qi2-add-support-for-TLS-1.0-record.patch b/target/linux/layerscape/patches-5.4/804-crypto-0029-crypto-caam-qi2-add-support-for-TLS-1.0-record.patch deleted file mode 100644 index 034c623b34..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0029-crypto-caam-qi2-add-support-for-TLS-1.0-record.patch +++ /dev/null @@ -1,545 +0,0 @@ -From a97159ba48984bfec10abcea3a0215cf3deff153 Mon Sep 17 00:00:00 2001 -From: Radu Alexe -Date: Fri, 9 Jun 2017 14:49:17 +0300 -Subject: [PATCH] crypto: caam/qi2 - add support for TLS 1.0 record -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -TLS 1.0 descriptors run on SEC 4.x or higher. For now, only -tls10(hmac(sha1),cbc(aes)) algorithm is registered by the driver. - -Known limitations: - - when src == dst - there should be no element in the src scatterlist - array that contains both associated data and message data. - - when src != dst - associated data is not copied from source into - destination. - - for decryption when src != dst the size of the destination should be - large enough so that the buffer may contain the decrypted authenc and -padded data. - -Signed-off-by: Radu Alexe -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/caamalg_qi2.c | 450 ++++++++++++++++++++++++++++++++++++++ - drivers/crypto/caam/caamalg_qi2.h | 22 ++ - 2 files changed, 472 insertions(+) - ---- a/drivers/crypto/caam/caamalg_qi2.c -+++ b/drivers/crypto/caam/caamalg_qi2.c -@@ -583,6 +583,257 @@ skip_out_fle: - return edesc; - } - -+static struct tls_edesc *tls_edesc_alloc(struct aead_request *req, -+ bool encrypt) -+{ -+ struct crypto_aead *tls = crypto_aead_reqtfm(req); -+ unsigned int blocksize = crypto_aead_blocksize(tls); -+ unsigned int padsize, authsize; -+ struct caam_request *req_ctx = aead_request_ctx(req); -+ struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; -+ struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; -+ struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ struct caam_aead_alg *alg = container_of(crypto_aead_alg(tls), -+ typeof(*alg), aead); -+ struct device *dev = ctx->dev; -+ gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? -+ GFP_KERNEL : GFP_ATOMIC; -+ int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0; -+ struct tls_edesc *edesc; -+ dma_addr_t qm_sg_dma, iv_dma = 0; -+ int ivsize = 0; -+ u8 *iv; -+ int qm_sg_index, qm_sg_ents = 0, qm_sg_bytes; -+ int in_len, out_len; -+ struct dpaa2_sg_entry *sg_table; -+ struct scatterlist *dst; -+ -+ if (encrypt) { -+ padsize = blocksize - ((req->cryptlen + ctx->authsize) % -+ blocksize); -+ authsize = ctx->authsize + padsize; -+ } else { -+ authsize = ctx->authsize; -+ } -+ -+ /* allocate space for base edesc, link tables and IV */ -+ edesc = qi_cache_zalloc(GFP_DMA | flags); -+ if (unlikely(!edesc)) { -+ dev_err(dev, "could not allocate extended descriptor\n"); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ if (likely(req->src == req->dst)) { -+ src_nents = sg_nents_for_len(req->src, req->assoclen + -+ req->cryptlen + -+ (encrypt ? authsize : 0)); -+ if (unlikely(src_nents < 0)) { -+ dev_err(dev, "Insufficient bytes (%d) in src S/G\n", -+ req->assoclen + req->cryptlen + -+ (encrypt ? authsize : 0)); -+ qi_cache_free(edesc); -+ return ERR_PTR(src_nents); -+ } -+ -+ mapped_src_nents = dma_map_sg(dev, req->src, src_nents, -+ DMA_BIDIRECTIONAL); -+ if (unlikely(!mapped_src_nents)) { -+ dev_err(dev, "unable to map source\n"); -+ qi_cache_free(edesc); -+ return ERR_PTR(-ENOMEM); -+ } -+ dst = req->dst; -+ } else { -+ src_nents = sg_nents_for_len(req->src, req->assoclen + -+ req->cryptlen); -+ if (unlikely(src_nents < 0)) { -+ dev_err(dev, "Insufficient bytes (%d) in src S/G\n", -+ req->assoclen + req->cryptlen); -+ qi_cache_free(edesc); -+ return ERR_PTR(src_nents); -+ } -+ -+ dst = scatterwalk_ffwd(edesc->tmp, req->dst, req->assoclen); -+ dst_nents = sg_nents_for_len(dst, req->cryptlen + -+ (encrypt ? authsize : 0)); -+ if (unlikely(dst_nents < 0)) { -+ dev_err(dev, "Insufficient bytes (%d) in dst S/G\n", -+ req->cryptlen + -+ (encrypt ? authsize : 0)); -+ qi_cache_free(edesc); -+ return ERR_PTR(dst_nents); -+ } -+ -+ if (src_nents) { -+ mapped_src_nents = dma_map_sg(dev, req->src, -+ src_nents, DMA_TO_DEVICE); -+ if (unlikely(!mapped_src_nents)) { -+ dev_err(dev, "unable to map source\n"); -+ qi_cache_free(edesc); -+ return ERR_PTR(-ENOMEM); -+ } -+ } else { -+ mapped_src_nents = 0; -+ } -+ -+ mapped_dst_nents = dma_map_sg(dev, dst, dst_nents, -+ DMA_FROM_DEVICE); -+ if (unlikely(!mapped_dst_nents)) { -+ dev_err(dev, "unable to map destination\n"); -+ dma_unmap_sg(dev, req->src, src_nents, DMA_TO_DEVICE); -+ qi_cache_free(edesc); -+ return ERR_PTR(-ENOMEM); -+ } -+ } -+ -+ /* -+ * Create S/G table: IV, src, dst. -+ * Input is not contiguous. -+ */ -+ qm_sg_ents = 1 + mapped_src_nents + -+ (mapped_dst_nents > 1 ? mapped_dst_nents : 0); -+ sg_table = &edesc->sgt[0]; -+ qm_sg_bytes = qm_sg_ents * sizeof(*sg_table); -+ -+ ivsize = crypto_aead_ivsize(tls); -+ iv = (u8 *)(sg_table + qm_sg_ents); -+ /* Make sure IV is located in a DMAable area */ -+ memcpy(iv, req->iv, ivsize); -+ iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE); -+ if (dma_mapping_error(dev, iv_dma)) { -+ dev_err(dev, "unable to map IV\n"); -+ caam_unmap(dev, req->src, dst, src_nents, dst_nents, 0, 0, -+ DMA_NONE, 0, 0); -+ qi_cache_free(edesc); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ edesc->src_nents = src_nents; -+ edesc->dst_nents = dst_nents; -+ edesc->dst = dst; -+ edesc->iv_dma = iv_dma; -+ -+ dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0); -+ qm_sg_index = 1; -+ -+ sg_to_qm_sg_last(req->src, mapped_src_nents, sg_table + qm_sg_index, 0); -+ qm_sg_index += mapped_src_nents; -+ -+ if (mapped_dst_nents > 1) -+ sg_to_qm_sg_last(dst, mapped_dst_nents, sg_table + -+ qm_sg_index, 0); -+ -+ qm_sg_dma = dma_map_single(dev, sg_table, qm_sg_bytes, DMA_TO_DEVICE); -+ if (dma_mapping_error(dev, qm_sg_dma)) { -+ dev_err(dev, "unable to map S/G table\n"); -+ caam_unmap(dev, req->src, dst, src_nents, dst_nents, iv_dma, -+ ivsize, DMA_TO_DEVICE, 0, 0); -+ qi_cache_free(edesc); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ edesc->qm_sg_dma = qm_sg_dma; -+ edesc->qm_sg_bytes = qm_sg_bytes; -+ -+ out_len = req->cryptlen + (encrypt ? authsize : 0); -+ in_len = ivsize + req->assoclen + req->cryptlen; -+ -+ memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); -+ dpaa2_fl_set_final(in_fle, true); -+ dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); -+ dpaa2_fl_set_addr(in_fle, qm_sg_dma); -+ dpaa2_fl_set_len(in_fle, in_len); -+ -+ if (req->dst == req->src) { -+ dpaa2_fl_set_format(out_fle, dpaa2_fl_sg); -+ dpaa2_fl_set_addr(out_fle, qm_sg_dma + -+ (sg_nents_for_len(req->src, req->assoclen) + -+ 1) * sizeof(*sg_table)); -+ } else if (mapped_dst_nents == 1) { -+ dpaa2_fl_set_format(out_fle, dpaa2_fl_single); -+ dpaa2_fl_set_addr(out_fle, sg_dma_address(dst)); -+ } else { -+ dpaa2_fl_set_format(out_fle, dpaa2_fl_sg); -+ dpaa2_fl_set_addr(out_fle, qm_sg_dma + qm_sg_index * -+ sizeof(*sg_table)); -+ } -+ -+ dpaa2_fl_set_len(out_fle, out_len); -+ -+ return edesc; -+} -+ -+static int tls_set_sh_desc(struct crypto_aead *tls) -+{ -+ struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ unsigned int ivsize = crypto_aead_ivsize(tls); -+ unsigned int blocksize = crypto_aead_blocksize(tls); -+ struct device *dev = ctx->dev; -+ struct dpaa2_caam_priv *priv = dev_get_drvdata(dev); -+ struct caam_flc *flc; -+ u32 *desc; -+ unsigned int assoclen = 13; /* always 13 bytes for TLS */ -+ unsigned int data_len[2]; -+ u32 inl_mask; -+ -+ if (!ctx->cdata.keylen || !ctx->authsize) -+ return 0; -+ -+ /* -+ * TLS 1.0 encrypt shared descriptor -+ * Job Descriptor and Shared Descriptor -+ * must fit into the 64-word Descriptor h/w Buffer -+ */ -+ data_len[0] = ctx->adata.keylen_pad; -+ data_len[1] = ctx->cdata.keylen; -+ -+ if (desc_inline_query(DESC_TLS10_ENC_LEN, DESC_JOB_IO_LEN, data_len, -+ &inl_mask, ARRAY_SIZE(data_len)) < 0) -+ return -EINVAL; -+ -+ if (inl_mask & 1) -+ ctx->adata.key_virt = ctx->key; -+ else -+ ctx->adata.key_dma = ctx->key_dma; -+ -+ if (inl_mask & 2) -+ ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad; -+ else -+ ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad; -+ -+ ctx->adata.key_inline = !!(inl_mask & 1); -+ ctx->cdata.key_inline = !!(inl_mask & 2); -+ -+ flc = &ctx->flc[ENCRYPT]; -+ desc = flc->sh_desc; -+ cnstr_shdsc_tls_encap(desc, &ctx->cdata, &ctx->adata, -+ assoclen, ivsize, ctx->authsize, blocksize, -+ priv->sec_attr.era); -+ flc->flc[1] = cpu_to_caam32(desc_len(desc)); -+ dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT], -+ sizeof(flc->flc) + desc_bytes(desc), -+ ctx->dir); -+ -+ /* -+ * TLS 1.0 decrypt shared descriptor -+ * Keys do not fit inline, regardless of algorithms used -+ */ -+ ctx->adata.key_inline = false; -+ ctx->adata.key_dma = ctx->key_dma; -+ ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad; -+ -+ flc = &ctx->flc[DECRYPT]; -+ desc = flc->sh_desc; -+ cnstr_shdsc_tls_decap(desc, &ctx->cdata, &ctx->adata, assoclen, ivsize, -+ ctx->authsize, blocksize, priv->sec_attr.era); -+ flc->flc[1] = cpu_to_caam32(desc_len(desc)); -+ dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT], -+ sizeof(flc->flc) + desc_bytes(desc), -+ ctx->dir); -+ -+ return 0; -+} -+ - static int chachapoly_set_sh_desc(struct crypto_aead *aead) - { - struct caam_ctx *ctx = crypto_aead_ctx(aead); -@@ -627,6 +878,61 @@ static int chachapoly_setauthsize(struct - return chachapoly_set_sh_desc(aead); - } - -+static int tls_setkey(struct crypto_aead *tls, const u8 *key, -+ unsigned int keylen) -+{ -+ struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ struct device *dev = ctx->dev; -+ struct crypto_authenc_keys keys; -+ -+ if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) -+ goto badkey; -+ -+#ifdef DEBUG -+ dev_err(dev, "keylen %d enckeylen %d authkeylen %d\n", -+ keys.authkeylen + keys.enckeylen, keys.enckeylen, -+ keys.authkeylen); -+ print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ", -+ DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); -+#endif -+ -+ ctx->adata.keylen = keys.authkeylen; -+ ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype & -+ OP_ALG_ALGSEL_MASK); -+ -+ if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE) -+ goto badkey; -+ -+ memcpy(ctx->key, keys.authkey, keys.authkeylen); -+ memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen); -+ dma_sync_single_for_device(dev, ctx->key_dma, ctx->adata.keylen_pad + -+ keys.enckeylen, ctx->dir); -+#ifdef DEBUG -+ print_hex_dump(KERN_ERR, "ctx.key@" __stringify(__LINE__)": ", -+ DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, -+ ctx->adata.keylen_pad + keys.enckeylen, 1); -+#endif -+ -+ ctx->cdata.keylen = keys.enckeylen; -+ -+ memzero_explicit(&keys, sizeof(keys)); -+ return tls_set_sh_desc(tls); -+badkey: -+ crypto_aead_set_flags(tls, CRYPTO_TFM_RES_BAD_KEY_LEN); -+ memzero_explicit(&keys, sizeof(keys)); -+ return -EINVAL; -+} -+ -+static int tls_setauthsize(struct crypto_aead *tls, unsigned int authsize) -+{ -+ struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ -+ ctx->authsize = authsize; -+ tls_set_sh_desc(tls); -+ -+ return 0; -+} -+ - static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key, - unsigned int keylen) - { -@@ -1274,6 +1580,17 @@ static void aead_unmap(struct device *de - dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE); - } - -+static void tls_unmap(struct device *dev, struct tls_edesc *edesc, -+ struct aead_request *req) -+{ -+ struct crypto_aead *tls = crypto_aead_reqtfm(req); -+ int ivsize = crypto_aead_ivsize(tls); -+ -+ caam_unmap(dev, req->src, edesc->dst, edesc->src_nents, -+ edesc->dst_nents, edesc->iv_dma, ivsize, DMA_TO_DEVICE, -+ edesc->qm_sg_dma, edesc->qm_sg_bytes); -+} -+ - static void skcipher_unmap(struct device *dev, struct skcipher_edesc *edesc, - struct skcipher_request *req) - { -@@ -1383,6 +1700,119 @@ static int aead_decrypt(struct aead_requ - return ret; - } - -+static void tls_encrypt_done(void *cbk_ctx, u32 status) -+{ -+ struct crypto_async_request *areq = cbk_ctx; -+ struct aead_request *req = container_of(areq, struct aead_request, -+ base); -+ struct caam_request *req_ctx = to_caam_req(areq); -+ struct tls_edesc *edesc = req_ctx->edesc; -+ struct crypto_aead *tls = crypto_aead_reqtfm(req); -+ struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ int ecode = 0; -+ -+#ifdef DEBUG -+ dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status); -+#endif -+ -+ if (unlikely(status)) { -+ caam_qi2_strstatus(ctx->dev, status); -+ ecode = -EIO; -+ } -+ -+ tls_unmap(ctx->dev, edesc, req); -+ qi_cache_free(edesc); -+ aead_request_complete(req, ecode); -+} -+ -+static void tls_decrypt_done(void *cbk_ctx, u32 status) -+{ -+ struct crypto_async_request *areq = cbk_ctx; -+ struct aead_request *req = container_of(areq, struct aead_request, -+ base); -+ struct caam_request *req_ctx = to_caam_req(areq); -+ struct tls_edesc *edesc = req_ctx->edesc; -+ struct crypto_aead *tls = crypto_aead_reqtfm(req); -+ struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ int ecode = 0; -+ -+#ifdef DEBUG -+ dev_err(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status); -+#endif -+ -+ if (unlikely(status)) { -+ caam_qi2_strstatus(ctx->dev, status); -+ /* -+ * verify hw auth check passed else return -EBADMSG -+ */ -+ if ((status & JRSTA_CCBERR_ERRID_MASK) == -+ JRSTA_CCBERR_ERRID_ICVCHK) -+ ecode = -EBADMSG; -+ else -+ ecode = -EIO; -+ } -+ -+ tls_unmap(ctx->dev, edesc, req); -+ qi_cache_free(edesc); -+ aead_request_complete(req, ecode); -+} -+ -+static int tls_encrypt(struct aead_request *req) -+{ -+ struct tls_edesc *edesc; -+ struct crypto_aead *tls = crypto_aead_reqtfm(req); -+ struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ struct caam_request *caam_req = aead_request_ctx(req); -+ int ret; -+ -+ /* allocate extended descriptor */ -+ edesc = tls_edesc_alloc(req, true); -+ if (IS_ERR(edesc)) -+ return PTR_ERR(edesc); -+ -+ caam_req->flc = &ctx->flc[ENCRYPT]; -+ caam_req->flc_dma = ctx->flc_dma[ENCRYPT]; -+ caam_req->cbk = tls_encrypt_done; -+ caam_req->ctx = &req->base; -+ caam_req->edesc = edesc; -+ ret = dpaa2_caam_enqueue(ctx->dev, caam_req); -+ if (ret != -EINPROGRESS && -+ !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { -+ tls_unmap(ctx->dev, edesc, req); -+ qi_cache_free(edesc); -+ } -+ -+ return ret; -+} -+ -+static int tls_decrypt(struct aead_request *req) -+{ -+ struct tls_edesc *edesc; -+ struct crypto_aead *tls = crypto_aead_reqtfm(req); -+ struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ struct caam_request *caam_req = aead_request_ctx(req); -+ int ret; -+ -+ /* allocate extended descriptor */ -+ edesc = tls_edesc_alloc(req, false); -+ if (IS_ERR(edesc)) -+ return PTR_ERR(edesc); -+ -+ caam_req->flc = &ctx->flc[DECRYPT]; -+ caam_req->flc_dma = ctx->flc_dma[DECRYPT]; -+ caam_req->cbk = tls_decrypt_done; -+ caam_req->ctx = &req->base; -+ caam_req->edesc = edesc; -+ ret = dpaa2_caam_enqueue(ctx->dev, caam_req); -+ if (ret != -EINPROGRESS && -+ !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { -+ tls_unmap(ctx->dev, edesc, req); -+ qi_cache_free(edesc); -+ } -+ -+ return ret; -+} -+ - static int ipsec_gcm_encrypt(struct aead_request *req) - { - return crypto_ipsec_check_assoclen(req->assoclen) ? : aead_encrypt(req); -@@ -2929,6 +3359,26 @@ static struct caam_aead_alg driver_aeads - .geniv = true, - }, - }, -+ { -+ .aead = { -+ .base = { -+ .cra_name = "tls10(hmac(sha1),cbc(aes))", -+ .cra_driver_name = "tls10-hmac-sha1-cbc-aes-caam-qi2", -+ .cra_blocksize = AES_BLOCK_SIZE, -+ }, -+ .setkey = tls_setkey, -+ .setauthsize = tls_setauthsize, -+ .encrypt = tls_encrypt, -+ .decrypt = tls_decrypt, -+ .ivsize = AES_BLOCK_SIZE, -+ .maxauthsize = SHA1_DIGEST_SIZE, -+ }, -+ .caam = { -+ .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, -+ .class2_alg_type = OP_ALG_ALGSEL_SHA1 | -+ OP_ALG_AAI_HMAC_PRECOMP, -+ }, -+ }, - }; - - static void caam_skcipher_alg_init(struct caam_skcipher_alg *t_alg) ---- a/drivers/crypto/caam/caamalg_qi2.h -+++ b/drivers/crypto/caam/caamalg_qi2.h -@@ -118,6 +118,28 @@ struct aead_edesc { - }; - - /* -+ * tls_edesc - s/w-extended tls descriptor -+ * @src_nents: number of segments in input scatterlist -+ * @dst_nents: number of segments in output scatterlist -+ * @iv_dma: dma address of iv for checking continuity and link table -+ * @qm_sg_bytes: length of dma mapped h/w link table -+ * @qm_sg_dma: bus physical mapped address of h/w link table -+ * @tmp: array of scatterlists used by 'scatterwalk_ffwd' -+ * @dst: pointer to output scatterlist, usefull for unmapping -+ * @sgt: the h/w link table, followed by IV -+ */ -+struct tls_edesc { -+ int src_nents; -+ int dst_nents; -+ dma_addr_t iv_dma; -+ int qm_sg_bytes; -+ dma_addr_t qm_sg_dma; -+ struct scatterlist tmp[2]; -+ struct scatterlist *dst; -+ struct dpaa2_sg_entry sgt[0]; -+}; -+ -+/* - * skcipher_edesc - s/w-extended skcipher descriptor - * @src_nents: number of segments in input scatterlist - * @dst_nents: number of segments in output scatterlist diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0030-crypto-caam-add-functionality-used-by-the-caam_dma-d.patch b/target/linux/layerscape/patches-5.4/804-crypto-0030-crypto-caam-add-functionality-used-by-the-caam_dma-d.patch deleted file mode 100644 index 6e4323987a..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0030-crypto-caam-add-functionality-used-by-the-caam_dma-d.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 20f552cafd7dda6f5d25128bbc04ea2c91d9f5d1 Mon Sep 17 00:00:00 2001 -From: Radu Alexe -Date: Thu, 26 Oct 2017 10:45:14 +0300 -Subject: [PATCH] crypto: caam - add functionality used by the caam_dma driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The caam_dma is a memcpy DMA driver based on the DMA functionality of -the CAAM hardware block. It creates a DMA channel for each JR of the -CAAM. This patch adds functionality that is used by the caam_dma that is -not yet part of the JR driver. - -Signed-off-by: Radu Alexe -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/desc.h | 2 ++ - drivers/crypto/caam/jr.c | 41 +++++++++++++++++++++++++++++++++++++++++ - drivers/crypto/caam/jr.h | 2 ++ - 3 files changed, 45 insertions(+) - ---- a/drivers/crypto/caam/desc.h -+++ b/drivers/crypto/caam/desc.h -@@ -364,6 +364,7 @@ - #define FIFOLD_TYPE_PK_N (0x08 << FIFOLD_TYPE_SHIFT) - #define FIFOLD_TYPE_PK_A (0x0c << FIFOLD_TYPE_SHIFT) - #define FIFOLD_TYPE_PK_B (0x0d << FIFOLD_TYPE_SHIFT) -+#define FIFOLD_TYPE_IFIFO (0x0f << FIFOLD_TYPE_SHIFT) - - /* Other types. Need to OR in last/flush bits as desired */ - #define FIFOLD_TYPE_MSG_MASK (0x38 << FIFOLD_TYPE_SHIFT) -@@ -1522,6 +1523,7 @@ - #define MATH_SRC1_INFIFO (0x0a << MATH_SRC1_SHIFT) - #define MATH_SRC1_OUTFIFO (0x0b << MATH_SRC1_SHIFT) - #define MATH_SRC1_ONE (0x0c << MATH_SRC1_SHIFT) -+#define MATH_SRC1_ZERO (0x0f << MATH_SRC1_SHIFT) - - /* Destination selectors */ - #define MATH_DEST_SHIFT 8 ---- a/drivers/crypto/caam/jr.c -+++ b/drivers/crypto/caam/jr.c -@@ -62,6 +62,14 @@ algs_unlock: - mutex_unlock(&algs_lock); - } - -+static int jr_driver_probed; -+ -+int caam_jr_driver_probed(void) -+{ -+ return jr_driver_probed; -+} -+EXPORT_SYMBOL(caam_jr_driver_probed); -+ - static int caam_reset_hw_jr(struct device *dev) - { - struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); -@@ -147,6 +155,8 @@ static int caam_jr_remove(struct platfor - if (ret) - dev_err(jrdev, "Failed to shut down job ring\n"); - -+ jr_driver_probed--; -+ - return ret; - } - -@@ -311,6 +321,36 @@ struct device *caam_jr_alloc(void) - EXPORT_SYMBOL(caam_jr_alloc); - - /** -+ * caam_jridx_alloc() - Alloc a specific job ring based on its index. -+ * -+ * returns : pointer to the newly allocated physical -+ * JobR dev can be written to if successful. -+ **/ -+struct device *caam_jridx_alloc(int idx) -+{ -+ struct caam_drv_private_jr *jrpriv; -+ struct device *dev = ERR_PTR(-ENODEV); -+ -+ spin_lock(&driver_data.jr_alloc_lock); -+ -+ if (list_empty(&driver_data.jr_list)) -+ goto end; -+ -+ list_for_each_entry(jrpriv, &driver_data.jr_list, list_node) { -+ if (jrpriv->ridx == idx) { -+ atomic_inc(&jrpriv->tfm_count); -+ dev = jrpriv->dev; -+ break; -+ } -+ } -+ -+end: -+ spin_unlock(&driver_data.jr_alloc_lock); -+ return dev; -+} -+EXPORT_SYMBOL(caam_jridx_alloc); -+ -+/** - * caam_jr_free() - Free the Job Ring - * @rdev - points to the dev that identifies the Job ring to - * be released. -@@ -565,6 +605,7 @@ static int caam_jr_probe(struct platform - device_set_wakeup_enable(&pdev->dev, false); - - register_algs(jrdev->parent); -+ jr_driver_probed++; - - return 0; - } ---- a/drivers/crypto/caam/jr.h -+++ b/drivers/crypto/caam/jr.h -@@ -9,7 +9,9 @@ - #define JR_H - - /* Prototypes for backend-level services exposed to APIs */ -+int caam_jr_driver_probed(void); - struct device *caam_jr_alloc(void); -+struct device *caam_jridx_alloc(int idx); - void caam_jr_free(struct device *rdev); - int caam_jr_enqueue(struct device *dev, u32 *desc, - void (*cbk)(struct device *dev, u32 *desc, u32 status, diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0031-crypto-caam-add-caam_dma-device-on-caam_probe.patch b/target/linux/layerscape/patches-5.4/804-crypto-0031-crypto-caam-add-caam_dma-device-on-caam_probe.patch deleted file mode 100644 index 1dca71c064..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0031-crypto-caam-add-caam_dma-device-on-caam_probe.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 0547020c73ab7a457f3e1601ef822b61f0b963b9 Mon Sep 17 00:00:00 2001 -From: Radu Alexe -Date: Wed, 8 Nov 2017 17:22:12 +0200 -Subject: [PATCH] crypto: caam - add caam_dma device on caam_probe -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Dynamically create a platform device for the caam_dma driver -at caam_probe() time. - -Signed-off-by: Radu Alexe -Signed-off-by: Horia Geantă - -Use devres for caam_dma platform device unregistering. - -Signed-off-by: Horia Geantă ---- - drivers/crypto/caam/ctrl.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -566,12 +566,22 @@ static void caam_remove_debugfs(void *ro - } - #endif - -+static void caam_dma_dev_unregister(void *data) -+{ -+ platform_device_unregister(data); -+} -+ - /* Probe routine for CAAM top (controller) level */ - static int caam_probe(struct platform_device *pdev) - { - int ret, ring, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN; - u64 caam_id; - const struct soc_device_attribute *imx_soc_match; -+ static struct platform_device_info caam_dma_pdev_info = { -+ .name = "caam-dma", -+ .id = PLATFORM_DEVID_NONE -+ }; -+ static struct platform_device *caam_dma_dev; - struct device *dev; - struct device_node *nprop, *np; - struct resource res_regs; -@@ -849,6 +859,20 @@ set_dma_mask: - return -ENOMEM; - } - -+ caam_dma_pdev_info.parent = dev; -+ caam_dma_pdev_info.dma_mask = dma_get_mask(dev); -+ caam_dma_dev = platform_device_register_full(&caam_dma_pdev_info); -+ if (IS_ERR(caam_dma_dev)) { -+ dev_err(dev, "Unable to create and register caam-dma dev\n"); -+ return PTR_ERR(caam_dma_dev); -+ } else { -+ set_dma_ops(&caam_dma_dev->dev, get_dma_ops(dev)); -+ ret = devm_add_action_or_reset(dev, caam_dma_dev_unregister, -+ caam_dma_dev); -+ if (ret) -+ return ret; -+ } -+ - if (!reg_access) - goto report_live; - diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0032-crypto-caam-add-CAAM-job-ring-UIO-support.patch b/target/linux/layerscape/patches-5.4/804-crypto-0032-crypto-caam-add-CAAM-job-ring-UIO-support.patch deleted file mode 100644 index 56566ffad9..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0032-crypto-caam-add-CAAM-job-ring-UIO-support.patch +++ /dev/null @@ -1,337 +0,0 @@ -From 8b60a441202cb5c6b5264dbee633fcb24414bab4 Mon Sep 17 00:00:00 2001 -From: Sandeep Malik -Date: Wed, 15 Nov 2017 17:16:13 +0530 -Subject: [PATCH] crypto: caam - add CAAM job ring UIO support - -This patch add the support for job ring UIO so -that userspace drivers can have access to the -caam job rings - -Signed-off-by: Sandeep Malik -Signed-off-by: Gagandeep Singh ---- - drivers/crypto/caam/Kconfig | 11 ++ - drivers/crypto/caam/Makefile | 1 + - drivers/crypto/caam/fsl_jr_uio.c | 256 +++++++++++++++++++++++++++++++++++++++ - drivers/crypto/caam/fsl_jr_uio.h | 25 ++++ - 4 files changed, 293 insertions(+) - create mode 100644 drivers/crypto/caam/fsl_jr_uio.c - create mode 100644 drivers/crypto/caam/fsl_jr_uio.h - ---- a/drivers/crypto/caam/Kconfig -+++ b/drivers/crypto/caam/Kconfig -@@ -203,6 +203,17 @@ config CRYPTO_DEV_FSL_CAAM_SECVIO - handler functions which can be specified to act on the consequences - of a security violation. - -+config CRYPTO_DEV_FSL_CAAM_JR_UIO -+ tristate "Freescale Job Ring UIO support" -+ depends on UIO -+ default y -+ help -+ Selecting this will allow job ring UIO support for -+ Userspace drivers -+ -+ To compile this as a module, choose M here: the module -+ will be called fsl_jr_uio. -+ - endif # CRYPTO_DEV_FSL_CAAM_JR - - endif # CRYPTO_DEV_FSL_CAAM ---- a/drivers/crypto/caam/Makefile -+++ b/drivers/crypto/caam/Makefile -@@ -13,6 +13,7 @@ obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caa - obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o - obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC) += caamalg_desc.o - obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o -+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR_UIO) += fsl_jr_uio.o - - caam-y := ctrl.o - caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o ---- /dev/null -+++ b/drivers/crypto/caam/fsl_jr_uio.c -@@ -0,0 +1,256 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright 2013 Freescale Semiconductor, Inc. -+ * Copyright 2018 NXP -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "regs.h" -+#include "fsl_jr_uio.h" -+ -+static const char jr_uio_version[] = "fsl JR UIO driver v1.0"; -+ -+#define NAME_LENGTH 30 -+#define JR_INDEX_OFFSET 12 -+ -+static const char uio_device_name[] = "fsl-jr"; -+static LIST_HEAD(jr_list); -+ -+struct jr_uio_info { -+ atomic_t ref; /* exclusive, only one open() at a time */ -+ struct uio_info uio; -+ char name[NAME_LENGTH]; -+}; -+ -+struct jr_dev { -+ u32 revision; -+ u32 index; -+ u32 irq; -+ struct caam_job_ring __iomem *global_regs; -+ struct device *dev; -+ struct resource *res; -+ struct jr_uio_info info; -+ struct list_head node; -+ struct list_head jr_list; -+}; -+ -+static int jr_uio_open(struct uio_info *info, struct inode *inode) -+{ -+ struct jr_uio_info *uio_info = container_of(info, -+ struct jr_uio_info, uio); -+ -+ if (!atomic_dec_and_test(&uio_info->ref)) { -+ pr_err("%s: failing non-exclusive open()\n", uio_info->name); -+ atomic_inc(&uio_info->ref); -+ return -EBUSY; -+ } -+ -+ return 0; -+} -+ -+static int jr_uio_release(struct uio_info *info, struct inode *inode) -+{ -+ struct jr_uio_info *uio_info = container_of(info, -+ struct jr_uio_info, uio); -+ atomic_inc(&uio_info->ref); -+ -+ return 0; -+} -+ -+static irqreturn_t jr_uio_irq_handler(int irq, struct uio_info *dev_info) -+{ -+ struct jr_dev *jrdev = dev_info->priv; -+ u32 irqstate; -+ -+ irqstate = rd_reg32(&jrdev->global_regs->jrintstatus); -+ -+ if (!irqstate) -+ return IRQ_NONE; -+ -+ if (irqstate & JRINT_JR_ERROR) -+ dev_info(jrdev->dev, "uio job ring error - irqstate: %08x\n", -+ irqstate); -+ -+ /*mask valid interrupts */ -+ clrsetbits_32(&jrdev->global_regs->rconfig_lo, 0, JRCFG_IMSK); -+ -+ /* Have valid interrupt at this point, just ACK and trigger */ -+ wr_reg32(&jrdev->global_regs->jrintstatus, irqstate); -+ -+ return IRQ_HANDLED; -+} -+ -+static int jr_uio_irqcontrol(struct uio_info *dev_info, int irqon) -+{ -+ struct jr_dev *jrdev = dev_info->priv; -+ -+ switch (irqon) { -+ case SEC_UIO_SIMULATE_IRQ_CMD: -+ uio_event_notify(dev_info); -+ break; -+ case SEC_UIO_ENABLE_IRQ_CMD: -+ /* Enable Job Ring interrupt */ -+ clrsetbits_32(&jrdev->global_regs->rconfig_lo, JRCFG_IMSK, 0); -+ break; -+ case SEC_UIO_DISABLE_IRQ_CMD: -+ /* Disable Job Ring interrupt */ -+ clrsetbits_32(&jrdev->global_regs->rconfig_lo, 0, JRCFG_IMSK); -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+static int __init jr_uio_init(struct jr_dev *uio_dev) -+{ -+ int ret; -+ struct jr_uio_info *info; -+ -+ info = &uio_dev->info; -+ atomic_set(&info->ref, 1); -+ info->uio.version = jr_uio_version; -+ info->uio.name = uio_dev->info.name; -+ info->uio.mem[0].name = "JR config space"; -+ info->uio.mem[0].addr = uio_dev->res->start; -+ info->uio.mem[0].size = uio_dev->res->end - uio_dev->res->start + 1; -+ info->uio.mem[0].internal_addr = uio_dev->global_regs; -+ info->uio.mem[0].memtype = UIO_MEM_PHYS; -+ info->uio.irq = uio_dev->irq; -+ info->uio.irq_flags = IRQF_SHARED; -+ info->uio.handler = jr_uio_irq_handler; -+ info->uio.irqcontrol = jr_uio_irqcontrol; -+ info->uio.open = jr_uio_open; -+ info->uio.release = jr_uio_release; -+ info->uio.priv = uio_dev; -+ -+ ret = uio_register_device(uio_dev->dev, &info->uio); -+ if (ret) { -+ dev_err(uio_dev->dev, "jr_uio: UIO registration failed\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static const struct of_device_id jr_ids[] = { -+ { .compatible = "fsl,sec-v4.0-job-ring", }, -+ { .compatible = "fsl,sec-v4.4-job-ring", }, -+ { .compatible = "fsl,sec-v5.0-job-ring", }, -+ { .compatible = "fsl,sec-v6.0-job-ring", }, -+ {}, -+}; -+ -+static int fsl_jr_probe(struct platform_device *dev) -+{ -+ struct resource regs; -+ struct jr_dev *jr_dev; -+ struct device_node *jr_node; -+ int ret, count = 0; -+ struct list_head *p; -+ -+ jr_node = dev->dev.of_node; -+ if (!jr_node) { -+ dev_err(&dev->dev, "Device OF-Node is NULL\n"); -+ return -EFAULT; -+ } -+ -+ jr_dev = devm_kzalloc(&dev->dev, sizeof(*jr_dev), GFP_KERNEL); -+ if (!jr_dev) -+ return -ENOMEM; -+ -+ /* Creat name and index */ -+ list_for_each(p, &jr_list) { -+ count++; -+ } -+ jr_dev->index = count; -+ -+ snprintf(jr_dev->info.name, sizeof(jr_dev->info.name) - 1, -+ "%s%d", uio_device_name, jr_dev->index); -+ -+ jr_dev->dev = &dev->dev; -+ platform_set_drvdata(dev, jr_dev); -+ -+ /* Get the resource from dtb node */ -+ ret = of_address_to_resource(jr_node, 0, ®s); -+ if (unlikely(ret < 0)) { -+ dev_err(&dev->dev, "OF-Address-to-resource Failed\n"); -+ ret = -EFAULT; -+ goto abort; -+ } -+ -+ jr_dev->res = devm_request_mem_region(&dev->dev, regs.start, -+ regs.end - regs.start + 1, -+ jr_dev->info.name); -+ if (unlikely(!jr_dev->res)) { -+ dev_err(jr_dev->dev, "devm_request_mem_region failed\n"); -+ ret = -ENOMEM; -+ goto abort; -+ } -+ -+ jr_dev->global_regs = -+ devm_ioremap(&dev->dev, jr_dev->res->start, -+ jr_dev->res->end - jr_dev->res->start + 1); -+ if (unlikely(jr_dev->global_regs == 0)) { -+ dev_err(jr_dev->dev, "devm_ioremap failed\n"); -+ ret = -EIO; -+ goto abort; -+ } -+ jr_dev->irq = irq_of_parse_and_map(jr_node, 0); -+ dev_dbg(jr_dev->dev, "errirq: %d\n", jr_dev->irq); -+ -+ /* Register UIO */ -+ ret = jr_uio_init(jr_dev); -+ if (ret) { -+ dev_err(&dev->dev, "UIO init Failed\n"); -+ goto abort; -+ } -+ -+ list_add_tail(&jr_dev->node, &jr_list); -+ -+ dev_info(jr_dev->dev, "UIO device full name %s initialized\n", -+ jr_dev->info.name); -+ -+ return 0; -+ -+abort: -+ return ret; -+} -+ -+static int fsl_jr_remove(struct platform_device *dev) -+{ -+ struct jr_dev *jr_dev = platform_get_drvdata(dev); -+ -+ if (!jr_dev) -+ return 0; -+ -+ list_del(&jr_dev->node); -+ uio_unregister_device(&jr_dev->info.uio); -+ -+ return 0; -+} -+ -+MODULE_DEVICE_TABLE(of, jr_ids); -+ -+static struct platform_driver fsl_jr_driver = { -+ .driver = { -+ .name = "fsl-jr-uio", -+ .of_match_table = jr_ids, -+ }, -+ .probe = fsl_jr_probe, -+ .remove = fsl_jr_remove, -+}; -+ -+module_platform_driver(fsl_jr_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("NXP"); -+MODULE_DESCRIPTION("FSL SEC UIO Driver"); ---- /dev/null -+++ b/drivers/crypto/caam/fsl_jr_uio.h -@@ -0,0 +1,25 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * CAAM Job RING UIO support header file -+ * -+ * Copyright 2013 Freescale Semiconductor, Inc -+ * Copyright 2018 NXP -+ */ -+ -+#ifndef FSL_JR_UIO_H -+#define FSL_JR_UIO_H -+ -+/** UIO command used by user-space driver to request -+ * disabling IRQs on a certain job ring -+ */ -+#define SEC_UIO_DISABLE_IRQ_CMD 0 -+/** UIO command used by user-space driver to request -+ * enabling IRQs on a certain job ring -+ */ -+#define SEC_UIO_ENABLE_IRQ_CMD 1 -+/** UIO command used by user-space driver to request SEC kernel driver -+ * to simulate that an IRQ is generated on a certain job ring -+ */ -+#define SEC_UIO_SIMULATE_IRQ_CMD 2 -+ -+#endif diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0033-LFV-26-crypto-caam-fix-Secure-Memory-driver-init.patch b/target/linux/layerscape/patches-5.4/804-crypto-0033-LFV-26-crypto-caam-fix-Secure-Memory-driver-init.patch deleted file mode 100644 index 53de880d75..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0033-LFV-26-crypto-caam-fix-Secure-Memory-driver-init.patch +++ /dev/null @@ -1,274 +0,0 @@ -From 1286c9b10f76b122ad1b328cc1bec17ac4d5908e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Wed, 13 Nov 2019 09:42:34 +0200 -Subject: [PATCH] LFV-26 crypto: caam - fix Secure Memory driver init -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -SM driver is buggy, since it runs irrespective of the presence of -the caam-sm DT node. -This causes issues on SoCs that have caam HW, but without support -for secure memory. - -Let's transform the module in a library, in the same way (and for -the same reasons) we did for the other job ring-dependent drivers -(caamalg, caamhash etc.) in -commit 1b46c90c8e00 ("crypto: caam - convert top level drivers to libraries") - -SM test module is also updated, to run only when needed. - -Fixes: 54e3fcf89f97 ("MLKU-25-3 crypto: caam - add Secure Memory support") -Signed-off-by: Horia Geantă -Reviewed-by: Iuliana Prodan ---- - drivers/crypto/caam/Kconfig | 2 +- - drivers/crypto/caam/ctrl.c | 2 ++ - drivers/crypto/caam/intern.h | 19 ++++++++++ - drivers/crypto/caam/jr.c | 6 ++-- - drivers/crypto/caam/sm.h | 1 - - drivers/crypto/caam/sm_store.c | 80 +++++------------------------------------- - drivers/crypto/caam/sm_test.c | 7 ++++ - 7 files changed, 42 insertions(+), 75 deletions(-) - ---- a/drivers/crypto/caam/Kconfig -+++ b/drivers/crypto/caam/Kconfig -@@ -167,7 +167,7 @@ config CRYPTO_DEV_FSL_CAAM_RNG_TEST - just before the RNG is registered with the hw_random API. - - config CRYPTO_DEV_FSL_CAAM_SM -- tristate "CAAM Secure Memory / Keystore API (EXPERIMENTAL)" -+ bool "CAAM Secure Memory / Keystore API (EXPERIMENTAL)" - help - Enables use of a prototype kernel-level Keystore API with CAAM - Secure Memory for insertion/extraction of bus-protected secrets. ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -763,6 +763,8 @@ iomap_ctrl: - ctrlpriv->sm_size = resource_size(&res_regs); - else - ctrlpriv->sm_size = PG_SIZE_64K; -+ -+ ctrlpriv->sm_present = 1; - of_node_put(np); - - if (!reg_access) ---- a/drivers/crypto/caam/intern.h -+++ b/drivers/crypto/caam/intern.h -@@ -86,6 +86,7 @@ struct caam_drv_private { - */ - u8 total_jobrs; /* Total Job Rings in device */ - u8 qi_present; /* Nonzero if QI present in device */ -+ u8 sm_present; /* Nonzero if Secure Memory is supported */ - u8 mc_en; /* Nonzero if MC f/w is active */ - u8 scu_en; /* Nonzero if SCU f/w is active */ - u8 optee_en; /* Nonzero if OP-TEE f/w is active */ -@@ -200,6 +201,24 @@ static inline void caam_qi_algapi_exit(v - - #endif /* CONFIG_CAAM_QI */ - -+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_SM -+ -+int caam_sm_startup(struct device *dev); -+void caam_sm_shutdown(struct device *dev); -+ -+#else -+ -+static inline int caam_sm_startup(struct device *dev) -+{ -+ return 0; -+} -+ -+static inline void caam_sm_shutdown(struct device *dev) -+{ -+} -+ -+#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_SM */ -+ - #ifdef CONFIG_DEBUG_FS - static int caam_debugfs_u64_get(void *data, u64 *val) - { ---- a/drivers/crypto/caam/jr.c -+++ b/drivers/crypto/caam/jr.c -@@ -34,6 +34,7 @@ static void register_algs(struct device - if (++active_devs != 1) - goto algs_unlock; - -+ caam_sm_startup(dev); - caam_algapi_init(dev); - caam_algapi_hash_init(dev); - caam_pkc_init(dev); -@@ -44,7 +45,7 @@ algs_unlock: - mutex_unlock(&algs_lock); - } - --static void unregister_algs(void) -+static void unregister_algs(struct device *dev) - { - mutex_lock(&algs_lock); - -@@ -57,6 +58,7 @@ static void unregister_algs(void) - caam_pkc_exit(); - caam_algapi_hash_exit(); - caam_algapi_exit(); -+ caam_sm_shutdown(dev); - - algs_unlock: - mutex_unlock(&algs_lock); -@@ -143,7 +145,7 @@ static int caam_jr_remove(struct platfor - } - - /* Unregister JR-based RNG & crypto algorithms */ -- unregister_algs(); -+ unregister_algs(jrdev->parent); - - /* Remove the node from Physical JobR list maintained by driver */ - spin_lock(&driver_data.jr_alloc_lock); ---- a/drivers/crypto/caam/sm.h -+++ b/drivers/crypto/caam/sm.h -@@ -41,7 +41,6 @@ void sm_init_keystore(struct device *dev - u32 sm_detect_keystore_units(struct device *dev); - int sm_establish_keystore(struct device *dev, u32 unit); - void sm_release_keystore(struct device *dev, u32 unit); --void caam_sm_shutdown(struct platform_device *pdev); - int caam_sm_example_init(struct platform_device *pdev); - - /* Keystore accessor functions */ ---- a/drivers/crypto/caam/sm_store.c -+++ b/drivers/crypto/caam/sm_store.c -@@ -1053,9 +1053,9 @@ EXPORT_SYMBOL(sm_keystore_slot_import); - * Also, simply uses ring 0 for execution at the present - */ - --int caam_sm_startup(struct platform_device *pdev) -+int caam_sm_startup(struct device *ctrldev) - { -- struct device *ctrldev, *smdev; -+ struct device *smdev; - struct caam_drv_private *ctrlpriv; - struct caam_drv_private_sm *smpriv; - struct caam_drv_private_jr *jrpriv; /* need this for reg page */ -@@ -1065,17 +1065,10 @@ int caam_sm_startup(struct platform_devi - int ret = 0; - - struct device_node *np; -- ctrldev = &pdev->dev; - ctrlpriv = dev_get_drvdata(ctrldev); - -- /* -- * If ctrlpriv is NULL, it's probably because the caam driver wasn't -- * properly initialized (e.g. RNG4 init failed). Thus, bail out here. -- */ -- if (!ctrlpriv) { -- ret = -ENODEV; -- goto exit; -- } -+ if (!ctrlpriv->sm_present) -+ return 0; - - /* - * Set up the private block for secure memory -@@ -1248,14 +1241,16 @@ exit: - return ret; - } - --void caam_sm_shutdown(struct platform_device *pdev) -+void caam_sm_shutdown(struct device *ctrldev) - { -- struct device *ctrldev, *smdev; -+ struct device *smdev; - struct caam_drv_private *priv; - struct caam_drv_private_sm *smpriv; - -- ctrldev = &pdev->dev; - priv = dev_get_drvdata(ctrldev); -+ if (!priv->sm_present) -+ return; -+ - smdev = priv->smdev; - - /* Return if resource not initialized by startup */ -@@ -1273,60 +1268,3 @@ void caam_sm_shutdown(struct platform_de - kfree(smpriv); - } - EXPORT_SYMBOL(caam_sm_shutdown); -- --static void __exit caam_sm_exit(void) --{ -- struct device_node *dev_node; -- struct platform_device *pdev; -- -- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); -- if (!dev_node) { -- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); -- if (!dev_node) -- return; -- } -- -- pdev = of_find_device_by_node(dev_node); -- if (!pdev) -- return; -- -- of_node_put(dev_node); -- -- caam_sm_shutdown(pdev); -- -- return; --} -- --static int __init caam_sm_init(void) --{ -- struct device_node *dev_node; -- struct platform_device *pdev; -- -- /* -- * Do of_find_compatible_node() then of_find_device_by_node() -- * once a functional device tree is available -- */ -- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); -- if (!dev_node) { -- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); -- if (!dev_node) -- return -ENODEV; -- } -- -- pdev = of_find_device_by_node(dev_node); -- if (!pdev) -- return -ENODEV; -- -- of_node_get(dev_node); -- -- caam_sm_startup(pdev); -- -- return 0; --} -- --module_init(caam_sm_init); --module_exit(caam_sm_exit); -- --MODULE_LICENSE("Dual BSD/GPL"); --MODULE_DESCRIPTION("FSL CAAM Secure Memory / Keystore"); --MODULE_AUTHOR("Freescale Semiconductor - NMSG/MAD"); ---- a/drivers/crypto/caam/sm_test.c -+++ b/drivers/crypto/caam/sm_test.c -@@ -531,6 +531,7 @@ static int __init caam_sm_test_init(void - { - struct device_node *dev_node; - struct platform_device *pdev; -+ struct caam_drv_private *priv; - int ret; - - /* -@@ -550,6 +551,12 @@ static int __init caam_sm_test_init(void - - of_node_put(dev_node); - -+ priv = dev_get_drvdata(&pdev->dev); -+ if (!priv->sm_present) { -+ dev_info(&pdev->dev, "No SM support, skipping tests\n"); -+ return -ENODEV; -+ } -+ - ret = caam_sm_example_init(pdev); - if (ret) - dev_err(&pdev->dev, "SM test failed: %d\n", ret); diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0034-LF-63-1-crypto-caam-fix-SM-test-init.patch b/target/linux/layerscape/patches-5.4/804-crypto-0034-LF-63-1-crypto-caam-fix-SM-test-init.patch deleted file mode 100644 index 7e3299ec94..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0034-LF-63-1-crypto-caam-fix-SM-test-init.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 79aa6ebf9d0b982c859a0c1bec1d879ff3d9ad29 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Wed, 27 Nov 2019 12:30:41 +0200 -Subject: [PATCH] LF-63-1 crypto: caam - fix SM test init -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit 77debf316c44 ("LFV-26 crypto: caam - fix Secure Memory driver init") -addressed SM driver initialization and also update SM test. - -However, the fix for SM test is insufficient. -There are cases when SM test runs before SM driver, causing a crash -due to uninitialized "priv" pointer being dereferenced. - -The fix consists in the following: - -1. Since SM test is a "bare" device driver (doesn't sit on any bus), -there is no deferred probing support. -Thus we have no choice (*) but to abort SM tests with a notification. - -(*) We don't want to force SM driver running first by means of -init levels etc. Just KISS. - -2. SM test driver forced to being built only as a module -Since SM test driver's only goal is to run SM tests, it doesn't make -any sense to be built-in. -Building the driver as a module allows for running the tests -several times if needed (multiple modprobe & rmmod cycles). - -Note: from the perspective of wanting to test repetitively, it would -make sense to force module unloading by returning an error code -in the module_init function. -However, this might affect test scripts (due to error code and/or -message output by unsuccessful module loading), so we postpone -this change for now. - -Fixes: d02fe599d7d5 ("MLKU-25-3 crypto: caam - add Secure Memory support") -Signed-off-by: Horia Geantă -Acked-by: Leonard Crestez ---- - drivers/crypto/caam/Kconfig | 1 + - drivers/crypto/caam/Makefile | 2 +- - drivers/crypto/caam/sm_test.c | 4 ++++ - 3 files changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/crypto/caam/Kconfig -+++ b/drivers/crypto/caam/Kconfig -@@ -191,6 +191,7 @@ config CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE - config CRYPTO_DEV_FSL_CAAM_SM_TEST - tristate "CAAM Secure Memory - Keystore Test/Example (EXPERIMENTAL)" - depends on CRYPTO_DEV_FSL_CAAM_SM -+ depends on m - help - Example thread to exercise the Keystore API and to verify that - stored and recovered secrets can be used for general purpose ---- a/drivers/crypto/caam/Makefile -+++ b/drivers/crypto/caam/Makefile -@@ -24,7 +24,7 @@ caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHA - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM) += sm_store.o --caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST) += sm_test.o -+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST) += sm_test.o - caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO) += secvio.o - #caam-jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_TK_API) += tag_object.o - ---- a/drivers/crypto/caam/sm_test.c -+++ b/drivers/crypto/caam/sm_test.c -@@ -552,6 +552,10 @@ static int __init caam_sm_test_init(void - of_node_put(dev_node); - - priv = dev_get_drvdata(&pdev->dev); -+ if (!priv) { -+ dev_info(&pdev->dev, "SM driver not ready, aborting tests\n"); -+ return -ENODEV; -+ } - if (!priv->sm_present) { - dev_info(&pdev->dev, "No SM support, skipping tests\n"); - return -ENODEV; diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0035-crypto-caam-qi-use-QBMan-NXP-SDK-driver.patch b/target/linux/layerscape/patches-5.4/804-crypto-0035-crypto-caam-qi-use-QBMan-NXP-SDK-driver.patch deleted file mode 100644 index 524ac40692..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0035-crypto-caam-qi-use-QBMan-NXP-SDK-driver.patch +++ /dev/null @@ -1,342 +0,0 @@ -From 28ef279c55a914372bf41587f6264e8e3e61e7d5 Mon Sep 17 00:00:00 2001 -From: Horia Geanta -Date: Mon, 12 Jun 2017 19:42:34 +0300 -Subject: [PATCH] crypto: caam/qi - use QBMan (NXP) SDK driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Update caam/qi to work with QBMan from NXP SDK. - -Signed-off-by: Horia Geantă - -Squashed "crypto: caam/qi - fix FD congestion weight" fix. - -Solved rebase conflicts: - -drivers/crypto/caam/qi.c:579 - kept call to dev_err_ratelimited, but changed to fd->status -drivers/crypto/caam/sg_sw_qm.h:96 - kept changes from patch, but changed sg_count to len - -Signed-off-by: Vlad Pelin -Acked-by: Horia Geanta ---- - drivers/crypto/caam/Kconfig | 2 +- - drivers/crypto/caam/qi.c | 82 +++++++++++++++++++++--------------------- - drivers/crypto/caam/qi.h | 2 +- - drivers/crypto/caam/sg_sw_qm.h | 46 ++++++++++++++++-------- - 4 files changed, 74 insertions(+), 58 deletions(-) - ---- a/drivers/crypto/caam/Kconfig -+++ b/drivers/crypto/caam/Kconfig -@@ -106,7 +106,7 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API - - config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI - bool "Queue Interface as Crypto API backend" -- depends on FSL_DPAA && NET -+ depends on FSL_SDK_DPA && NET - default y - select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC - select CRYPTO_AUTHENC ---- a/drivers/crypto/caam/qi.c -+++ b/drivers/crypto/caam/qi.c -@@ -9,7 +9,7 @@ - - #include - #include --#include -+#include - - #include "regs.h" - #include "qi.h" -@@ -107,23 +107,21 @@ static void *caam_iova_to_virt(struct io - int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req) - { - struct qm_fd fd; -- dma_addr_t addr; - int ret; - int num_retries = 0; - -- qm_fd_clear_fd(&fd); -- qm_fd_set_compound(&fd, qm_sg_entry_get_len(&req->fd_sgt[1])); -- -- addr = dma_map_single(qidev, req->fd_sgt, sizeof(req->fd_sgt), -+ fd.cmd = 0; -+ fd.format = qm_fd_compound; -+ fd.cong_weight = caam32_to_cpu(req->fd_sgt[1].length); -+ fd.addr = dma_map_single(qidev, req->fd_sgt, sizeof(req->fd_sgt), - DMA_BIDIRECTIONAL); -- if (dma_mapping_error(qidev, addr)) { -+ if (dma_mapping_error(qidev, fd.addr)) { - dev_err(qidev, "DMA mapping error for QI enqueue request\n"); - return -EIO; - } -- qm_fd_addr_set64(&fd, addr); - - do { -- ret = qman_enqueue(req->drv_ctx->req_fq, &fd); -+ ret = qman_enqueue(req->drv_ctx->req_fq, &fd, 0); - if (likely(!ret)) - return 0; - -@@ -139,7 +137,7 @@ int caam_qi_enqueue(struct device *qidev - EXPORT_SYMBOL(caam_qi_enqueue); - - static void caam_fq_ern_cb(struct qman_portal *qm, struct qman_fq *fq, -- const union qm_mr_entry *msg) -+ const struct qm_mr_entry *msg) - { - const struct qm_fd *fd; - struct caam_drv_req *drv_req; -@@ -148,7 +146,7 @@ static void caam_fq_ern_cb(struct qman_p - - fd = &msg->ern.fd; - -- if (qm_fd_get_format(fd) != qm_fd_compound) { -+ if (fd->format != qm_fd_compound) { - dev_err(qidev, "Non-compound FD from CAAM\n"); - return; - } -@@ -186,20 +184,22 @@ static struct qman_fq *create_caam_req_f - req_fq->cb.fqs = NULL; - - ret = qman_create_fq(0, QMAN_FQ_FLAG_DYNAMIC_FQID | -- QMAN_FQ_FLAG_TO_DCPORTAL, req_fq); -+ QMAN_FQ_FLAG_TO_DCPORTAL | QMAN_FQ_FLAG_LOCKED, -+ req_fq); - if (ret) { - dev_err(qidev, "Failed to create session req FQ\n"); - goto create_req_fq_fail; - } - -- memset(&opts, 0, sizeof(opts)); -- opts.we_mask = cpu_to_be16(QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_DESTWQ | -- QM_INITFQ_WE_CONTEXTB | -- QM_INITFQ_WE_CONTEXTA | QM_INITFQ_WE_CGID); -- opts.fqd.fq_ctrl = cpu_to_be16(QM_FQCTRL_CPCSTASH | QM_FQCTRL_CGE); -- qm_fqd_set_destwq(&opts.fqd, qm_channel_caam, 2); -- opts.fqd.context_b = cpu_to_be32(qman_fq_fqid(rsp_fq)); -- qm_fqd_context_a_set64(&opts.fqd, hwdesc); -+ opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_DESTWQ | -+ QM_INITFQ_WE_CONTEXTB | QM_INITFQ_WE_CONTEXTA | -+ QM_INITFQ_WE_CGID; -+ opts.fqd.fq_ctrl = QM_FQCTRL_CPCSTASH | QM_FQCTRL_CGE; -+ opts.fqd.dest.channel = qm_channel_caam; -+ opts.fqd.dest.wq = 2; -+ opts.fqd.context_b = qman_fq_fqid(rsp_fq); -+ opts.fqd.context_a.hi = upper_32_bits(hwdesc); -+ opts.fqd.context_a.lo = lower_32_bits(hwdesc); - opts.fqd.cgid = qipriv.cgr.cgrid; - - ret = qman_init_fq(req_fq, fq_sched_flag, &opts); -@@ -213,7 +213,7 @@ static struct qman_fq *create_caam_req_f - return req_fq; - - init_req_fq_fail: -- qman_destroy_fq(req_fq); -+ qman_destroy_fq(req_fq, 0); - create_req_fq_fail: - kfree(req_fq); - return ERR_PTR(ret); -@@ -281,7 +281,7 @@ empty_fq: - if (ret) - dev_err(qidev, "OOS of FQID: %u failed\n", fq->fqid); - -- qman_destroy_fq(fq); -+ qman_destroy_fq(fq, 0); - kfree(fq); - - return ret; -@@ -298,7 +298,7 @@ static int empty_caam_fq(struct qman_fq - if (ret) - return ret; - -- if (!qm_mcr_np_get(&np, frm_cnt)) -+ if (!np.frm_cnt) - break; - - msleep(20); -@@ -565,30 +565,28 @@ static enum qman_cb_dqrr_result caam_rsp - const struct qm_fd *fd; - struct device *qidev = &(raw_cpu_ptr(&pcpu_qipriv)->net_dev.dev); - struct caam_drv_private *priv = dev_get_drvdata(qidev); -- u32 status; - - if (caam_qi_napi_schedule(p, caam_napi)) - return qman_cb_dqrr_stop; - - fd = &dqrr->fd; -- status = be32_to_cpu(fd->status); -- if (unlikely(status)) { -- u32 ssrc = status & JRSTA_SSRC_MASK; -- u8 err_id = status & JRSTA_CCBERR_ERRID_MASK; -+ if (unlikely(fd->status)) { -+ u32 ssrc = fd->status & JRSTA_SSRC_MASK; -+ u8 err_id = fd->status & JRSTA_CCBERR_ERRID_MASK; - - if (ssrc != JRSTA_SSRC_CCB_ERROR || - err_id != JRSTA_CCBERR_ERRID_ICVCHK) - dev_err_ratelimited(qidev, - "Error: %#x in CAAM response FD\n", -- status); -+ fd->status); - } - -- if (unlikely(qm_fd_get_format(fd) != qm_fd_compound)) { -+ if (unlikely(fd->format != qm_fd_compound)) { - dev_err(qidev, "Non-compound FD from CAAM\n"); - return qman_cb_dqrr_consume; - } - -- drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd)); -+ drv_req = caam_iova_to_virt(priv->domain, fd->addr); - if (unlikely(!drv_req)) { - dev_err(qidev, - "Can't find original request for caam response\n"); -@@ -598,7 +596,7 @@ static enum qman_cb_dqrr_result caam_rsp - dma_unmap_single(drv_req->drv_ctx->qidev, qm_fd_addr(fd), - sizeof(drv_req->fd_sgt), DMA_BIDIRECTIONAL); - -- drv_req->cbk(drv_req, status); -+ drv_req->cbk(drv_req, fd->status); - return qman_cb_dqrr_consume; - } - -@@ -622,17 +620,18 @@ static int alloc_rsp_fq_cpu(struct devic - return -ENODEV; - } - -- memset(&opts, 0, sizeof(opts)); -- opts.we_mask = cpu_to_be16(QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_DESTWQ | -- QM_INITFQ_WE_CONTEXTB | -- QM_INITFQ_WE_CONTEXTA | QM_INITFQ_WE_CGID); -- opts.fqd.fq_ctrl = cpu_to_be16(QM_FQCTRL_CTXASTASHING | -- QM_FQCTRL_CPCSTASH | QM_FQCTRL_CGE); -- qm_fqd_set_destwq(&opts.fqd, qman_affine_channel(cpu), 3); -+ opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_DESTWQ | -+ QM_INITFQ_WE_CONTEXTB | QM_INITFQ_WE_CONTEXTA | -+ QM_INITFQ_WE_CGID; -+ opts.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING | QM_FQCTRL_CPCSTASH | -+ QM_FQCTRL_CGE; -+ opts.fqd.dest.channel = qman_affine_channel(cpu); -+ opts.fqd.dest.wq = 3; - opts.fqd.cgid = qipriv.cgr.cgrid; - opts.fqd.context_a.stashing.exclusive = QM_STASHING_EXCL_CTX | - QM_STASHING_EXCL_DATA; -- qm_fqd_set_stashing(&opts.fqd, 0, 1, 1); -+ opts.fqd.context_a.stashing.data_cl = 1; -+ opts.fqd.context_a.stashing.context_cl = 1; - - ret = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &opts); - if (ret) { -@@ -662,8 +661,7 @@ static int init_cgr(struct device *qidev - - qipriv.cgr.cb = cgr_cb; - memset(&opts, 0, sizeof(opts)); -- opts.we_mask = cpu_to_be16(QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES | -- QM_CGR_WE_MODE); -+ opts.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES | QM_CGR_WE_MODE; - opts.cgr.cscn_en = QM_CGR_EN; - opts.cgr.mode = QMAN_CGR_MODE_FRAME; - qm_cgr_cs_thres_set64(&opts.cgr.cs_thres, val, 1); ---- a/drivers/crypto/caam/qi.h -+++ b/drivers/crypto/caam/qi.h -@@ -9,7 +9,7 @@ - #ifndef __QI_H__ - #define __QI_H__ - --#include -+#include - #include "compat.h" - #include "desc.h" - #include "desc_constr.h" ---- a/drivers/crypto/caam/sg_sw_qm.h -+++ b/drivers/crypto/caam/sg_sw_qm.h -@@ -7,46 +7,61 @@ - #ifndef __SG_SW_QM_H - #define __SG_SW_QM_H - --#include -+#include - #include "regs.h" - -+static inline void cpu_to_hw_sg(struct qm_sg_entry *qm_sg_ptr) -+{ -+ dma_addr_t addr = qm_sg_ptr->opaque; -+ -+ qm_sg_ptr->opaque = cpu_to_caam64(addr); -+ qm_sg_ptr->sgt_efl = cpu_to_caam32(qm_sg_ptr->sgt_efl); -+} -+ - static inline void __dma_to_qm_sg(struct qm_sg_entry *qm_sg_ptr, dma_addr_t dma, -- u16 offset) -+ u32 len, u16 offset) - { -- qm_sg_entry_set64(qm_sg_ptr, dma); -+ qm_sg_ptr->addr = dma; -+ qm_sg_ptr->length = len; - qm_sg_ptr->__reserved2 = 0; - qm_sg_ptr->bpid = 0; -- qm_sg_ptr->offset = cpu_to_be16(offset & QM_SG_OFF_MASK); -+ qm_sg_ptr->__reserved3 = 0; -+ qm_sg_ptr->offset = offset & QM_SG_OFFSET_MASK; -+ -+ cpu_to_hw_sg(qm_sg_ptr); - } - - static inline void dma_to_qm_sg_one(struct qm_sg_entry *qm_sg_ptr, - dma_addr_t dma, u32 len, u16 offset) - { -- __dma_to_qm_sg(qm_sg_ptr, dma, offset); -- qm_sg_entry_set_len(qm_sg_ptr, len); -+ qm_sg_ptr->extension = 0; -+ qm_sg_ptr->final = 0; -+ __dma_to_qm_sg(qm_sg_ptr, dma, len, offset); - } - - static inline void dma_to_qm_sg_one_last(struct qm_sg_entry *qm_sg_ptr, - dma_addr_t dma, u32 len, u16 offset) - { -- __dma_to_qm_sg(qm_sg_ptr, dma, offset); -- qm_sg_entry_set_f(qm_sg_ptr, len); -+ qm_sg_ptr->extension = 0; -+ qm_sg_ptr->final = 1; -+ __dma_to_qm_sg(qm_sg_ptr, dma, len, offset); - } - - static inline void dma_to_qm_sg_one_ext(struct qm_sg_entry *qm_sg_ptr, - dma_addr_t dma, u32 len, u16 offset) - { -- __dma_to_qm_sg(qm_sg_ptr, dma, offset); -- qm_sg_ptr->cfg = cpu_to_be32(QM_SG_EXT | (len & QM_SG_LEN_MASK)); -+ qm_sg_ptr->extension = 1; -+ qm_sg_ptr->final = 0; -+ __dma_to_qm_sg(qm_sg_ptr, dma, len, offset); - } - - static inline void dma_to_qm_sg_one_last_ext(struct qm_sg_entry *qm_sg_ptr, - dma_addr_t dma, u32 len, - u16 offset) - { -- __dma_to_qm_sg(qm_sg_ptr, dma, offset); -- qm_sg_ptr->cfg = cpu_to_be32(QM_SG_EXT | QM_SG_FIN | -- (len & QM_SG_LEN_MASK)); -+ qm_sg_ptr->extension = 1; -+ qm_sg_ptr->final = 1; -+ __dma_to_qm_sg(qm_sg_ptr, dma, len, offset); - } - - /* -@@ -79,7 +94,10 @@ static inline void sg_to_qm_sg_last(stru - struct qm_sg_entry *qm_sg_ptr, u16 offset) - { - qm_sg_ptr = sg_to_qm_sg(sg, len, qm_sg_ptr, offset); -- qm_sg_entry_set_f(qm_sg_ptr, qm_sg_entry_get_len(qm_sg_ptr)); -+ -+ qm_sg_ptr->sgt_efl = caam32_to_cpu(qm_sg_ptr->sgt_efl); -+ qm_sg_ptr->final = 1; -+ qm_sg_ptr->sgt_efl = cpu_to_caam32(qm_sg_ptr->sgt_efl); - } - - #endif /* __SG_SW_QM_H */ diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0036-LF-933-crypto-caam-fix-iosource-busy-issue.patch b/target/linux/layerscape/patches-5.4/804-crypto-0036-LF-933-crypto-caam-fix-iosource-busy-issue.patch deleted file mode 100644 index f142a67569..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0036-LF-933-crypto-caam-fix-iosource-busy-issue.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 4f59ceff69a20d28881848140ef5fc2888042e62 Mon Sep 17 00:00:00 2001 -From: Gagandeep Singh -Date: Mon, 17 Feb 2020 16:41:01 +0000 -Subject: [PATCH] LF-933: crypto: caam: fix iosource busy issue - -The caam controller driver claims the ownership of the -whole caam register space due to which while binding the -Job Ring to fsl-jr-uio driver, it returns IOSOURCE_BUSY -error. - -This patch replaces devm_request_mem_region() API with -platform_get_resource() to avoid this issue. - -Fixes: eb5e94d4624a ("crypto: caam - use devres to unmap memory") - -Signed-off-by: Gagandeep Singh -Acked-by: Horia Geanta ---- - drivers/crypto/caam/fsl_jr_uio.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - ---- a/drivers/crypto/caam/fsl_jr_uio.c -+++ b/drivers/crypto/caam/fsl_jr_uio.c -@@ -187,11 +187,10 @@ static int fsl_jr_probe(struct platform_ - goto abort; - } - -- jr_dev->res = devm_request_mem_region(&dev->dev, regs.start, -- regs.end - regs.start + 1, -- jr_dev->info.name); -+ -+ jr_dev->res = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (unlikely(!jr_dev->res)) { -- dev_err(jr_dev->dev, "devm_request_mem_region failed\n"); -+ dev_err(jr_dev->dev, "platform_get_resource() failed\n"); - ret = -ENOMEM; - goto abort; - } diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0038-LF-838-crypto-caam-increase-the-domain-of-write-memo.patch b/target/linux/layerscape/patches-5.4/804-crypto-0038-LF-838-crypto-caam-increase-the-domain-of-write-memo.patch deleted file mode 100644 index 7cc8c5f244..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0038-LF-838-crypto-caam-increase-the-domain-of-write-memo.patch +++ /dev/null @@ -1,44 +0,0 @@ -From ada13fea4dcc8419e0523614b108635d8f689000 Mon Sep 17 00:00:00 2001 -From: Iuliana Prodan -Date: Mon, 17 Feb 2020 03:05:10 +0200 -Subject: [PATCH] LF-838: crypto: caam - increase the domain of write memory - barrier to full system -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In caam_jr_enqueue, under heavy DDR load, smp_wmb() or dma_wmb() -fail to make the input ring be updated before the CAAM starts -reading it. So, CAAM will process, again, an old descriptor address -and will put it in the output ring. This will make caam_jr_dequeue() -to fail, since this old descriptor is not in the software ring. -To fix this, use wmb() which works on the full system instead of -inner/outer shareable domains. - -Signed-off-by: Iuliana Prodan -Reviewed-by: Horia Geantă -Signed-off-by: Leonard Crestez ---- - drivers/crypto/caam/jr.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - ---- a/drivers/crypto/caam/jr.c -+++ b/drivers/crypto/caam/jr.c -@@ -434,8 +434,16 @@ int caam_jr_enqueue(struct device *dev, - * Guarantee that the descriptor's DMA address has been written to - * the next slot in the ring before the write index is updated, since - * other cores may update this index independently. -+ * -+ * Under heavy DDR load, smp_wmb() or dma_wmb() fail to make the input -+ * ring be updated before the CAAM starts reading it. So, CAAM will -+ * process, again, an old descriptor address and will put it in the -+ * output ring. This will make caam_jr_dequeue() to fail, since this -+ * old descriptor is not in the software ring. -+ * To fix this, use wmb() which works on the full system instead of -+ * inner/outer shareable domains. - */ -- smp_wmb(); -+ wmb(); - - jrp->head = (head + 1) & (JOBR_DEPTH - 1); - diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0040-LF-292-1-crypto-caam-refactor-RNG-initialization.patch b/target/linux/layerscape/patches-5.4/804-crypto-0040-LF-292-1-crypto-caam-refactor-RNG-initialization.patch deleted file mode 100644 index c4c22a1cd5..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0040-LF-292-1-crypto-caam-refactor-RNG-initialization.patch +++ /dev/null @@ -1,248 +0,0 @@ -From 43f8f404e2e8cd81baa4d89706e40901c466c7bb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Fri, 21 Feb 2020 11:48:39 +0100 -Subject: [PATCH] LF-292-1 crypto: caam - refactor RNG initialization -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RNG (re-)initialization will be needed on pm resume path, -thus refactor the corresponding code out of the probe callback. - -Signed-off-by: Horia Geantă -Reviewed-by: Valentin Ciocoi Radulescu -Signed-off-by: Franck LENORMAND -Signed-off-by: Leonard Crestez -Signed-off-by: Dong Aisheng ---- - drivers/crypto/caam/ctrl.c | 189 ++++++++++++++++++++++++--------------------- - 1 file changed, 102 insertions(+), 87 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -327,13 +327,12 @@ static int instantiate_rng(struct device - /* - * kick_trng - sets the various parameters for enabling the initialization - * of the RNG4 block in CAAM -- * @pdev - pointer to the platform device -+ * @dev - pointer to the controller device - * @ent_delay - Defines the length (in system clocks) of each entropy sample. - */ --static void kick_trng(struct platform_device *pdev, int ent_delay) -+static void kick_trng(struct device *dev, int ent_delay) - { -- struct device *ctrldev = &pdev->dev; -- struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); -+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev); - struct caam_ctrl __iomem *ctrl; - struct rng4tst __iomem *r4tst; - u32 val; -@@ -571,10 +570,105 @@ static void caam_dma_dev_unregister(void - platform_device_unregister(data); - } - -+static int caam_ctrl_rng_init(struct device *dev) -+{ -+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev); -+ struct caam_ctrl __iomem *ctrl = ctrlpriv->ctrl; -+ int ret, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN; -+ u8 rng_vid; -+ -+ if (ctrlpriv->era < 10) { -+ struct caam_perfmon __iomem *perfmon; -+ -+ perfmon = ctrlpriv->total_jobrs ? -+ (struct caam_perfmon *)&ctrlpriv->jr[0]->perfmon : -+ (struct caam_perfmon *)&ctrl->perfmon; -+ -+ rng_vid = (rd_reg32(&perfmon->cha_id_ls) & -+ CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT; -+ } else { -+ struct version_regs __iomem *vreg; -+ -+ vreg = ctrlpriv->total_jobrs ? -+ (struct version_regs *)&ctrlpriv->jr[0]->vreg : -+ (struct version_regs *)&ctrl->vreg; -+ -+ rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >> -+ CHA_VER_VID_SHIFT; -+ } -+ -+ /* -+ * If SEC has RNG version >= 4 and RNG state handle has not been -+ * already instantiated, do RNG instantiation -+ * In case of SoCs with Management Complex, RNG is managed by MC f/w. -+ */ -+ if (!ctrlpriv->mc_en && rng_vid >= 4) { -+ ctrlpriv->rng4_sh_init = -+ rd_reg32(&ctrl->r4tst[0].rdsta); -+ /* -+ * If the secure keys (TDKEK, JDKEK, TDSK), were already -+ * generated, signal this to the function that is instantiating -+ * the state handles. An error would occur if RNG4 attempts -+ * to regenerate these keys before the next POR. -+ */ -+ gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1; -+ ctrlpriv->rng4_sh_init &= RDSTA_IFMASK; -+ do { -+ int inst_handles = -+ rd_reg32(&ctrl->r4tst[0].rdsta) & -+ RDSTA_IFMASK; -+ /* -+ * If either SH were instantiated by somebody else -+ * (e.g. u-boot) then it is assumed that the entropy -+ * parameters are properly set and thus the function -+ * setting these (kick_trng(...)) is skipped. -+ * Also, if a handle was instantiated, do not change -+ * the TRNG parameters. -+ */ -+ if (!(ctrlpriv->rng4_sh_init || inst_handles)) { -+ dev_info(dev, -+ "Entropy delay = %u\n", -+ ent_delay); -+ kick_trng(dev, ent_delay); -+ ent_delay += 400; -+ } -+ /* -+ * if instantiate_rng(...) fails, the loop will rerun -+ * and the kick_trng(...) function will modify the -+ * upper and lower limits of the entropy sampling -+ * interval, leading to a sucessful initialization of -+ * the RNG. -+ */ -+ ret = instantiate_rng(dev, inst_handles, -+ gen_sk); -+ if (ret == -EAGAIN) -+ /* -+ * if here, the loop will rerun, -+ * so don't hog the CPU -+ */ -+ cpu_relax(); -+ } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX)); -+ if (ret) { -+ dev_err(dev, "failed to instantiate RNG"); -+ return ret; -+ } -+ /* -+ * Set handles init'ed by this module as the complement of the -+ * already initialized ones -+ */ -+ ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK; -+ -+ /* Enable RDB bit so that RNG works faster */ -+ clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE); -+ } -+ -+ return 0; -+} -+ - /* Probe routine for CAAM top (controller) level */ - static int caam_probe(struct platform_device *pdev) - { -- int ret, ring, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN; -+ int ret, ring; - u64 caam_id; - const struct soc_device_attribute *imx_soc_match; - static struct platform_device_info caam_dma_pdev_info = { -@@ -592,7 +686,6 @@ static int caam_probe(struct platform_de - struct dentry *dfs_root; - #endif - u32 scfgr, comp_params; -- u8 rng_vid; - int pg_size; - int BLOCK_OFFSET = 0; - bool reg_access = true; -@@ -875,90 +968,12 @@ set_dma_mask: - return ret; - } - -- if (!reg_access) -- goto report_live; -- -- if (ctrlpriv->era < 10) { -- rng_vid = (rd_reg32(&perfmon->cha_id_ls) & -- CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT; -- } else { -- struct version_regs __iomem *vreg; -- -- vreg = ring ? (struct version_regs *)&ctrlpriv->jr[0]->vreg : -- (struct version_regs *)&ctrl->vreg; -- -- rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >> -- CHA_VER_VID_SHIFT; -- } -- -- /* -- * If SEC has RNG version >= 4 and RNG state handle has not been -- * already instantiated, do RNG instantiation -- * In case of SoCs with Management Complex, RNG is managed by MC f/w. -- */ -- if (!ctrlpriv->mc_en && rng_vid >= 4) { -- ctrlpriv->rng4_sh_init = -- rd_reg32(&ctrl->r4tst[0].rdsta); -- /* -- * If the secure keys (TDKEK, JDKEK, TDSK), were already -- * generated, signal this to the function that is instantiating -- * the state handles. An error would occur if RNG4 attempts -- * to regenerate these keys before the next POR. -- */ -- gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1; -- ctrlpriv->rng4_sh_init &= RDSTA_IFMASK; -- do { -- int inst_handles = -- rd_reg32(&ctrl->r4tst[0].rdsta) & -- RDSTA_IFMASK; -- /* -- * If either SH were instantiated by somebody else -- * (e.g. u-boot) then it is assumed that the entropy -- * parameters are properly set and thus the function -- * setting these (kick_trng(...)) is skipped. -- * Also, if a handle was instantiated, do not change -- * the TRNG parameters. -- */ -- if (!(ctrlpriv->rng4_sh_init || inst_handles)) { -- dev_info(dev, -- "Entropy delay = %u\n", -- ent_delay); -- kick_trng(pdev, ent_delay); -- ent_delay += 400; -- } -- /* -- * if instantiate_rng(...) fails, the loop will rerun -- * and the kick_trng(...) function will modfiy the -- * upper and lower limits of the entropy sampling -- * interval, leading to a sucessful initialization of -- * the RNG. -- */ -- ret = instantiate_rng(dev, inst_handles, -- gen_sk); -- if (ret == -EAGAIN) -- /* -- * if here, the loop will rerun, -- * so don't hog the CPU -- */ -- cpu_relax(); -- } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX)); -- if (ret) { -- dev_err(dev, "failed to instantiate RNG"); -+ if (reg_access) { -+ ret = caam_ctrl_rng_init(dev); -+ if (ret) - return ret; -- } -- /* -- * Set handles init'ed by this module as the complement of the -- * already initialized ones -- */ -- ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK; -- -- /* Enable RDB bit so that RNG works faster */ -- clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE); - } - -- /* NOTE: RTIC detection ought to go here, around Si time */ -- --report_live: - caam_id = (u64)rd_reg32(&perfmon->caam_id_ms) << 32 | - (u64)rd_reg32(&perfmon->caam_id_ls); - diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0041-LF-292-2-crypto-caam-add-power-management.patch b/target/linux/layerscape/patches-5.4/804-crypto-0041-LF-292-2-crypto-caam-add-power-management.patch deleted file mode 100644 index 2a518790ed..0000000000 --- a/target/linux/layerscape/patches-5.4/804-crypto-0041-LF-292-2-crypto-caam-add-power-management.patch +++ /dev/null @@ -1,570 +0,0 @@ -From e8aeb8bbd925b50555c70ad4be86cf7d8e8767a6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Horia=20Geant=C4=83?= -Date: Fri, 21 Feb 2020 11:48:40 +0100 -Subject: [PATCH] LF-292-2 crypto: caam - add power management -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add support for suspend and resume operation for PM in CAAM driver. - -When the CAAM goes in suspend, the hardware is considered to do nothing. - -On some platforms, the power of the CAAM is not turned off so it keeps -its configuration. - -On other platforms, it doesn't so it is necessary to save the state of -the CAAM: - - JRs MID - - Address of input and output rings - -Limitation: -When the CAAM is powered OFF, it is resetted so the JDKEK and TDKEK -changes. This impacts crypto transforms using MDHA split-keys -which are kept over suspend as they are encrypted with the JDKEK: - - hmac(*) from caamhash.c - - authenc(hmac(*),*) from caamalg.c - - echainiv(authenc(hmac(*),*)) from caamalg.c -The issue was already present in current code so this patch does not -add a regression in this regard. - -Reviewed-by: Horia Geantă -Signed-off-by: Franck LENORMAND -(cherry picked from commit c151af80cfda82eae533a80fb2bb0158dffe556d) - -Differences vs. i.MX BSP: --RNG re-initialization done in ctrl, not in jr - -The fix for MLK-22518 (drivers: crypto: caam: jr: Allow quiesce when quiesced) -is integrated in this patch. - -Signed-off-by: Horia Geantă -Signed-off-by: Franck LENORMAND -Signed-off-by: Leonard Crestez -Signed-off-by: Dong Aisheng ---- - drivers/crypto/caam/ctrl.c | 116 +++++++++++++++++++++++ - drivers/crypto/caam/intern.h | 31 ++++++ - drivers/crypto/caam/jr.c | 219 ++++++++++++++++++++++++++++++++++++------- - drivers/crypto/caam/regs.h | 3 +- - 4 files changed, 333 insertions(+), 36 deletions(-) - ---- a/drivers/crypto/caam/ctrl.c -+++ b/drivers/crypto/caam/ctrl.c -@@ -665,6 +665,115 @@ static int caam_ctrl_rng_init(struct dev - return 0; - } - -+#ifdef CONFIG_PM_SLEEP -+ -+/* Indicate if the internal state of the CAAM is lost during PM */ -+static int caam_off_during_pm(void) -+{ -+ bool not_off_during_pm = of_machine_is_compatible("fsl,imx6q") || -+ of_machine_is_compatible("fsl,imx6qp") || -+ of_machine_is_compatible("fsl,imx6dl"); -+ -+ return not_off_during_pm ? 0 : 1; -+} -+ -+static void caam_state_save(struct device *dev) -+{ -+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev); -+ struct caam_ctl_state *state = &ctrlpriv->state; -+ struct caam_ctrl __iomem *ctrl = ctrlpriv->ctrl; -+ u32 deco_inst, jr_inst; -+ int i; -+ -+ state->mcr = rd_reg32(&ctrl->mcr); -+ state->scfgr = rd_reg32(&ctrl->scfgr); -+ -+ deco_inst = (rd_reg32(&ctrl->perfmon.cha_num_ms) & -+ CHA_ID_MS_DECO_MASK) >> CHA_ID_MS_DECO_SHIFT; -+ for (i = 0; i < deco_inst; i++) { -+ state->deco_mid[i].liodn_ms = -+ rd_reg32(&ctrl->deco_mid[i].liodn_ms); -+ state->deco_mid[i].liodn_ls = -+ rd_reg32(&ctrl->deco_mid[i].liodn_ls); -+ } -+ -+ jr_inst = (rd_reg32(&ctrl->perfmon.cha_num_ms) & -+ CHA_ID_MS_JR_MASK) >> CHA_ID_MS_JR_SHIFT; -+ for (i = 0; i < jr_inst; i++) { -+ state->jr_mid[i].liodn_ms = -+ rd_reg32(&ctrl->jr_mid[i].liodn_ms); -+ state->jr_mid[i].liodn_ls = -+ rd_reg32(&ctrl->jr_mid[i].liodn_ls); -+ } -+} -+ -+static void caam_state_restore(const struct device *dev) -+{ -+ const struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev); -+ const struct caam_ctl_state *state = &ctrlpriv->state; -+ struct caam_ctrl __iomem *ctrl = ctrlpriv->ctrl; -+ u32 deco_inst, jr_inst; -+ int i; -+ -+ wr_reg32(&ctrl->mcr, state->mcr); -+ wr_reg32(&ctrl->scfgr, state->scfgr); -+ -+ deco_inst = (rd_reg32(&ctrl->perfmon.cha_num_ms) & -+ CHA_ID_MS_DECO_MASK) >> CHA_ID_MS_DECO_SHIFT; -+ for (i = 0; i < deco_inst; i++) { -+ wr_reg32(&ctrl->deco_mid[i].liodn_ms, -+ state->deco_mid[i].liodn_ms); -+ wr_reg32(&ctrl->deco_mid[i].liodn_ls, -+ state->deco_mid[i].liodn_ls); -+ } -+ -+ jr_inst = (rd_reg32(&ctrl->perfmon.cha_num_ms) & -+ CHA_ID_MS_JR_MASK) >> CHA_ID_MS_JR_SHIFT; -+ for (i = 0; i < ctrlpriv->total_jobrs; i++) { -+ wr_reg32(&ctrl->jr_mid[i].liodn_ms, -+ state->jr_mid[i].liodn_ms); -+ wr_reg32(&ctrl->jr_mid[i].liodn_ls, -+ state->jr_mid[i].liodn_ls); -+ } -+ -+ if (ctrlpriv->virt_en == 1) -+ clrsetbits_32(&ctrl->jrstart, 0, JRSTART_JR0_START | -+ JRSTART_JR1_START | JRSTART_JR2_START | -+ JRSTART_JR3_START); -+} -+ -+static int caam_ctrl_suspend(struct device *dev) -+{ -+ const struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev); -+ -+ if (ctrlpriv->caam_off_during_pm && !ctrlpriv->scu_en && -+ !ctrlpriv->optee_en) -+ caam_state_save(dev); -+ -+ return 0; -+} -+ -+static int caam_ctrl_resume(struct device *dev) -+{ -+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev); -+ int ret = 0; -+ -+ if (ctrlpriv->caam_off_during_pm && !ctrlpriv->scu_en && -+ !ctrlpriv->optee_en) { -+ caam_state_restore(dev); -+ -+ /* HW and rng will be reset so deinstantiation can be removed */ -+ devm_remove_action(dev, devm_deinstantiate_rng, dev); -+ ret = caam_ctrl_rng_init(dev); -+ } -+ -+ return ret; -+} -+ -+SIMPLE_DEV_PM_OPS(caam_ctrl_pm_ops, caam_ctrl_suspend, caam_ctrl_resume); -+ -+#endif /* CONFIG_PM_SLEEP */ -+ - /* Probe routine for CAAM top (controller) level */ - static int caam_probe(struct platform_device *pdev) - { -@@ -701,6 +810,10 @@ static int caam_probe(struct platform_de - imx_soc_match = soc_device_match(caam_imx_soc_table); - caam_imx = (bool)imx_soc_match; - -+#ifdef CONFIG_PM_SLEEP -+ ctrlpriv->caam_off_during_pm = caam_imx && caam_off_during_pm(); -+#endif -+ - if (imx_soc_match) { - np = of_find_compatible_node(NULL, NULL, "fsl,imx-scu"); - ctrlpriv->scu_en = !!np; -@@ -1049,6 +1162,9 @@ static struct platform_driver caam_drive - .driver = { - .name = "caam", - .of_match_table = caam_match, -+#ifdef CONFIG_PM_SLEEP -+ .pm = &caam_ctrl_pm_ops, -+#endif - }, - .probe = caam_probe, - }; ---- a/drivers/crypto/caam/intern.h -+++ b/drivers/crypto/caam/intern.h -@@ -38,6 +38,18 @@ struct caam_jrentry_info { - u32 desc_size; /* Stored size for postprocessing, header derived */ - }; - -+#ifdef CONFIG_PM_SLEEP -+struct caam_jr_state { -+ dma_addr_t inpbusaddr; -+ dma_addr_t outbusaddr; -+}; -+#endif -+ -+struct caam_jr_dequeue_params { -+ struct device *dev; -+ int enable_itr; -+}; -+ - /* Private sub-storage for a single JobR */ - struct caam_drv_private_jr { - struct list_head list_node; /* Job Ring device list */ -@@ -45,6 +57,7 @@ struct caam_drv_private_jr { - int ridx; - struct caam_job_ring __iomem *rregs; /* JobR's register space */ - struct tasklet_struct irqtask; -+ struct caam_jr_dequeue_params tasklet_params; - int irq; /* One per queue */ - - /* Number of scatterlist crypt transforms active on the JobR */ -@@ -60,7 +73,20 @@ struct caam_drv_private_jr { - int out_ring_read_index; /* Output index "tail" */ - int tail; /* entinfo (s/w ring) tail index */ - void *outring; /* Base of output ring, DMA-safe */ -+ -+#ifdef CONFIG_PM_SLEEP -+ struct caam_jr_state state; /* State of the JR during PM */ -+#endif -+}; -+ -+#ifdef CONFIG_PM_SLEEP -+struct caam_ctl_state { -+ struct masterid deco_mid[16]; -+ struct masterid jr_mid[4]; -+ u32 mcr; -+ u32 scfgr; - }; -+#endif - - /* - * Driver-private storage for a single CAAM block instance -@@ -109,6 +135,11 @@ struct caam_drv_private { - struct dentry *ctl; /* controller dir */ - struct debugfs_blob_wrapper ctl_kek_wrap, ctl_tkek_wrap, ctl_tdsk_wrap; - #endif -+ -+#ifdef CONFIG_PM_SLEEP -+ int caam_off_during_pm; /* If the CAAM is reset after suspend */ -+ struct caam_ctl_state state; /* State of the CTL during PM */ -+#endif - }; - - #ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API ---- a/drivers/crypto/caam/jr.c -+++ b/drivers/crypto/caam/jr.c -@@ -72,19 +72,27 @@ int caam_jr_driver_probed(void) - } - EXPORT_SYMBOL(caam_jr_driver_probed); - --static int caam_reset_hw_jr(struct device *dev) -+/* -+ * Put the CAAM in quiesce, ie stop -+ * -+ * Must be called with itr disabled -+ */ -+static int caam_jr_stop_processing(struct device *dev, u32 jrcr_bits) - { - struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); - unsigned int timeout = 100000; - -- /* -- * mask interrupts since we are going to poll -- * for reset completion status -- */ -- clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JRCFG_IMSK); -+ /* Check the current status */ -+ if (rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_INPROGRESS) -+ goto wait_quiesce_completion; - -- /* initiate flush (required prior to reset) */ -- wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET); -+ /* Reset the field */ -+ clrsetbits_32(&jrp->rregs->jrintstatus, JRINT_ERR_HALT_MASK, 0); -+ -+ /* initiate flush / park (required prior to reset) */ -+ wr_reg32(&jrp->rregs->jrcommand, jrcr_bits); -+ -+wait_quiesce_completion: - while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) == - JRINT_ERR_HALT_INPROGRESS) && --timeout) - cpu_relax(); -@@ -95,8 +103,56 @@ static int caam_reset_hw_jr(struct devic - return -EIO; - } - -+ return 0; -+} -+ -+/* -+ * Flush the job ring, so the jobs running will be stopped, jobs queued will be -+ * invalidated and the CAAM will no longer fetch fron input ring. -+ * -+ * Must be called with itr disabled -+ */ -+static int caam_jr_flush(struct device *dev) -+{ -+ return caam_jr_stop_processing(dev, JRCR_RESET); -+} -+ -+#ifdef CONFIG_PM_SLEEP -+/* The resume can be used after a park or a flush if CAAM has not been reset */ -+static int caam_jr_restart_processing(struct device *dev) -+{ -+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); -+ u32 halt_status = rd_reg32(&jrp->rregs->jrintstatus) & -+ JRINT_ERR_HALT_MASK; -+ -+ /* Check that the flush/park is completed */ -+ if (halt_status != JRINT_ERR_HALT_COMPLETE) -+ return -1; -+ -+ /* Resume processing of jobs */ -+ clrsetbits_32(&jrp->rregs->jrintstatus, 0, JRINT_ERR_HALT_COMPLETE); -+ -+ return 0; -+} -+#endif /* CONFIG_PM_SLEEP */ -+ -+static int caam_reset_hw_jr(struct device *dev) -+{ -+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); -+ unsigned int timeout = 100000; -+ int err; -+ -+ /* -+ * mask interrupts since we are going to poll -+ * for reset completion status -+ */ -+ clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JRCFG_IMSK); -+ -+ err = caam_jr_flush(dev); -+ if (err) -+ return err; -+ - /* initiate reset */ -- timeout = 100000; - wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET); - while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout) - cpu_relax(); -@@ -204,7 +260,8 @@ static irqreturn_t caam_jr_interrupt(int - static void caam_jr_dequeue(unsigned long devarg) - { - int hw_idx, sw_idx, i, head, tail; -- struct device *dev = (struct device *)devarg; -+ struct caam_jr_dequeue_params *params = (void *)devarg; -+ struct device *dev = params->dev; - struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); - void (*usercall)(struct device *dev, u32 *desc, u32 status, void *arg); - u32 *userdesc, userstatus; -@@ -278,8 +335,9 @@ static void caam_jr_dequeue(unsigned lon - outring_used--; - } - -- /* reenable / unmask IRQs */ -- clrsetbits_32(&jrp->rregs->rconfig_lo, JRCFG_IMSK, 0); -+ if (params->enable_itr) -+ /* reenable / unmask IRQs */ -+ clrsetbits_32(&jrp->rregs->rconfig_lo, JRCFG_IMSK, 0); - } - - /** -@@ -467,6 +525,29 @@ int caam_jr_enqueue(struct device *dev, - } - EXPORT_SYMBOL(caam_jr_enqueue); - -+static void caam_jr_init_hw(struct device *dev, dma_addr_t inpbusaddr, -+ dma_addr_t outbusaddr) -+{ -+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); -+ -+ wr_reg64(&jrp->rregs->inpring_base, inpbusaddr); -+ wr_reg64(&jrp->rregs->outring_base, outbusaddr); -+ wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH); -+ wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH); -+ -+ /* Select interrupt coalescing parameters */ -+ clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JOBR_INTC | -+ (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) | -+ (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT)); -+} -+ -+static void caam_jr_reset_index(struct caam_drv_private_jr *jrp) -+{ -+ jrp->out_ring_read_index = 0; -+ jrp->head = 0; -+ jrp->tail = 0; -+} -+ - /* - * Init JobR independent of platform property detection - */ -@@ -503,25 +584,16 @@ static int caam_jr_init(struct device *d - jrp->entinfo[i].desc_addr_dma = !0; - - /* Setup rings */ -- jrp->out_ring_read_index = 0; -- jrp->head = 0; -- jrp->tail = 0; -- -- wr_reg64(&jrp->rregs->inpring_base, inpbusaddr); -- wr_reg64(&jrp->rregs->outring_base, outbusaddr); -- wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH); -- wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH); -- -+ caam_jr_reset_index(jrp); - jrp->inpring_avail = JOBR_DEPTH; -+ caam_jr_init_hw(dev, inpbusaddr, outbusaddr); - - spin_lock_init(&jrp->inplock); - -- /* Select interrupt coalescing parameters */ -- clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JOBR_INTC | -- (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) | -- (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT)); -- -- tasklet_init(&jrp->irqtask, caam_jr_dequeue, (unsigned long)dev); -+ jrp->tasklet_params.dev = dev; -+ jrp->tasklet_params.enable_itr = 1; -+ tasklet_init(&jrp->irqtask, caam_jr_dequeue, -+ (unsigned long)&jrp->tasklet_params); - - /* Connect job ring interrupt handler. */ - error = devm_request_irq(dev, jrp->irq, caam_jr_interrupt, IRQF_SHARED, -@@ -620,14 +692,48 @@ static int caam_jr_probe(struct platform - return 0; - } - --#ifdef CONFIG_PM -+#ifdef CONFIG_PM_SLEEP -+static void caam_jr_get_hw_state(struct device *dev) -+{ -+ struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); -+ -+ jrp->state.inpbusaddr = rd_reg64(&jrp->rregs->inpring_base); -+ jrp->state.outbusaddr = rd_reg64(&jrp->rregs->outring_base); -+} -+ - static int caam_jr_suspend(struct device *dev) - { - struct platform_device *pdev = to_platform_device(dev); - struct caam_drv_private_jr *jrpriv = platform_get_drvdata(pdev); -+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev->parent); -+ struct caam_jr_dequeue_params suspend_params = { -+ .dev = dev, -+ .enable_itr = 0, -+ }; -+ -+ if (ctrlpriv->caam_off_during_pm) { -+ int err; -+ -+ tasklet_disable(&jrpriv->irqtask); -+ -+ /* mask itr to call flush */ -+ clrsetbits_32(&jrpriv->rregs->rconfig_lo, 0, JRCFG_IMSK); -+ -+ /* Invalid job in process */ -+ err = caam_jr_flush(dev); -+ if (err) { -+ dev_err(dev, "Failed to flush\n"); -+ return err; -+ } -+ -+ /* Dequeing jobs flushed */ -+ caam_jr_dequeue((unsigned long)&suspend_params); - -- if (device_may_wakeup(&pdev->dev)) -+ /* Save state */ -+ caam_jr_get_hw_state(dev); -+ } else if (device_may_wakeup(&pdev->dev)) { - enable_irq_wake(jrpriv->irq); -+ } - - return 0; - } -@@ -636,16 +742,61 @@ static int caam_jr_resume(struct device - { - struct platform_device *pdev = to_platform_device(dev); - struct caam_drv_private_jr *jrpriv = platform_get_drvdata(pdev); -+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev->parent); - -- if (device_may_wakeup(&pdev->dev)) -+ if (ctrlpriv->caam_off_during_pm) { -+ u64 inp_addr; -+ int err; -+ -+ /* -+ * Check if the CAAM has been resetted checking the address of -+ * the input ring -+ */ -+ inp_addr = rd_reg64(&jrpriv->rregs->inpring_base); -+ if (inp_addr != 0) { -+ /* JR still has some configuration */ -+ if (inp_addr == jrpriv->state.inpbusaddr) { -+ /* JR has not been resetted */ -+ err = caam_jr_restart_processing(dev); -+ if (err) { -+ dev_err(dev, -+ "Restart processing failed\n"); -+ return err; -+ } -+ -+ tasklet_enable(&jrpriv->irqtask); -+ -+ clrsetbits_32(&jrpriv->rregs->rconfig_lo, -+ JRCFG_IMSK, 0); -+ -+ return 0; -+ } else if (ctrlpriv->optee_en) { -+ /* JR has been used by OPTEE, reset it */ -+ err = caam_reset_hw_jr(dev); -+ if (err) { -+ dev_err(dev, "Failed to reset JR\n"); -+ return err; -+ } -+ } else { -+ /* No explanation, return error */ -+ return -EIO; -+ } -+ } -+ -+ caam_jr_reset_index(jrpriv); -+ caam_jr_init_hw(dev, jrpriv->state.inpbusaddr, -+ jrpriv->state.outbusaddr); -+ -+ tasklet_enable(&jrpriv->irqtask); -+ } else if (device_may_wakeup(&pdev->dev)) { - disable_irq_wake(jrpriv->irq); -+ } - - return 0; - } - --static SIMPLE_DEV_PM_OPS(caam_jr_pm_ops, caam_jr_suspend, -- caam_jr_resume); --#endif -+SIMPLE_DEV_PM_OPS(caam_jr_pm_ops, caam_jr_suspend, caam_jr_resume); -+#endif /* CONFIG_PM_SLEEP */ - - static const struct of_device_id caam_jr_match[] = { - { -@@ -662,7 +813,7 @@ static struct platform_driver caam_jr_dr - .driver = { - .name = "caam_jr", - .of_match_table = caam_jr_match, --#ifdef CONFIG_PM -+#ifdef CONFIG_PM_SLEEP - .pm = &caam_jr_pm_ops, - #endif - }, ---- a/drivers/crypto/caam/regs.h -+++ b/drivers/crypto/caam/regs.h -@@ -634,8 +634,7 @@ struct caam_ctrl { - u32 deco_rsr; /* DECORSR - Deco Request Source */ - u32 rsvd11; - u32 deco_rq; /* DECORR - DECO Request */ -- struct masterid deco_mid[5]; /* DECOxLIODNR - 1 per DECO */ -- u32 rsvd5[22]; -+ struct masterid deco_mid[16]; /* DECOxLIODNR - 1 per DECO */ - - /* DECO Availability/Reset Section 120-3ff */ - u32 deco_avail; /* DAR - DECO availability */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0001-drm-arm-mali-dp-Add-display-QoS-interface-configurat.patch b/target/linux/layerscape/patches-5.4/805-display-0001-drm-arm-mali-dp-Add-display-QoS-interface-configurat.patch deleted file mode 100644 index c27e34fc0b..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0001-drm-arm-mali-dp-Add-display-QoS-interface-configurat.patch +++ /dev/null @@ -1,85 +0,0 @@ -From dae2475df84cd77c6f7245984869897c0eb0f84e Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Tue, 10 Sep 2019 15:01:00 +0800 -Subject: [PATCH] drm/arm/mali-dp: Add display QoS interface configuration for - Mali DP500 - -Configure the display Quality of service (QoS) levels priority if the -optional property node "arm,malidp-aqros-value" is defined in DTS file. - -QoS signaling using AQROS and AWQOS AXI interface signals, the AQROS is -driven from the "RQOS" register, so needed to program the RQOS register -to avoid the high resolutions flicker issue on the LS1028A platform. - -Signed-off-by: Wen He ---- - drivers/gpu/drm/arm/malidp_drv.c | 6 ++++++ - drivers/gpu/drm/arm/malidp_hw.c | 9 +++++++++ - drivers/gpu/drm/arm/malidp_hw.h | 3 +++ - drivers/gpu/drm/arm/malidp_regs.h | 10 ++++++++++ - 4 files changed, 28 insertions(+) - ---- a/drivers/gpu/drm/arm/malidp_drv.c -+++ b/drivers/gpu/drm/arm/malidp_drv.c -@@ -817,6 +817,12 @@ static int malidp_bind(struct device *de - - malidp->core_id = version; - -+ ret = of_property_read_u32(dev->of_node, -+ "arm,malidp-arqos-value", -+ &hwdev->arqos_value); -+ if (ret) -+ hwdev->arqos_value = 0x0; -+ - /* set the number of lines used for output of RGB data */ - ret = of_property_read_u8_array(dev->of_node, - "arm,malidp-output-port-lines", ---- a/drivers/gpu/drm/arm/malidp_hw.c -+++ b/drivers/gpu/drm/arm/malidp_hw.c -@@ -379,6 +379,15 @@ static void malidp500_modeset(struct mal - malidp_hw_setbits(hwdev, MALIDP_DISP_FUNC_ILACED, MALIDP_DE_DISPLAY_FUNC); - else - malidp_hw_clearbits(hwdev, MALIDP_DISP_FUNC_ILACED, MALIDP_DE_DISPLAY_FUNC); -+ -+ /* -+ * Program the RQoS register to avoid high resolutions flicker -+ * issue on the LS1028A. -+ */ -+ if (hwdev->arqos_value) { -+ val = hwdev->arqos_value; -+ malidp_hw_setbits(hwdev, val, MALIDP500_RQOS_QUALITY); -+ } - } - - int malidp_format_get_bpp(u32 fmt) ---- a/drivers/gpu/drm/arm/malidp_hw.h -+++ b/drivers/gpu/drm/arm/malidp_hw.h -@@ -251,6 +251,9 @@ struct malidp_hw_device { - - /* size of memory used for rotating layers, up to two banks available */ - u32 rotation_memory[2]; -+ -+ /* priority level of RQOS register used for driven the ARQOS signal */ -+ u32 arqos_value; - }; - - static inline u32 malidp_hw_read(struct malidp_hw_device *hwdev, u32 reg) ---- a/drivers/gpu/drm/arm/malidp_regs.h -+++ b/drivers/gpu/drm/arm/malidp_regs.h -@@ -210,6 +210,16 @@ - #define MALIDP500_CONFIG_VALID 0x00f00 - #define MALIDP500_CONFIG_ID 0x00fd4 - -+/* -+ * The quality of service (QoS) register on the DP500. RQOS register values -+ * are driven by the ARQOS signal, using AXI transacations, dependent on the -+ * FIFO input level. -+ * The RQOS register can also set QoS levels for: -+ * - RED_ARQOS @ A 4-bit signal value for close to underflow conditions -+ * - GREEN_ARQOS @ A 4-bit signal value for normal conditions -+ */ -+#define MALIDP500_RQOS_QUALITY 0x00500 -+ - /* register offsets and bits specific to DP550/DP650 */ - #define MALIDP550_ADDR_SPACE_SIZE 0x10000 - #define MALIDP550_DE_CONTROL 0x00010 diff --git a/target/linux/layerscape/patches-5.4/805-display-0002-drm-rockchip-prepare-common-code-for-cdns-and-rk-dpi.patch b/target/linux/layerscape/patches-5.4/805-display-0002-drm-rockchip-prepare-common-code-for-cdns-and-rk-dpi.patch deleted file mode 100644 index 8ce4380664..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0002-drm-rockchip-prepare-common-code-for-cdns-and-rk-dpi.patch +++ /dev/null @@ -1,1943 +0,0 @@ -From 2a77bbf7f6494d4d618fc6ff70b1a21f04cb8a22 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Wed, 10 Jul 2019 10:50:25 +0800 -Subject: [PATCH] drm/rockchip: prepare common code for cdns and rk dpi/dp - driver - -- Extracted common fields from cdn_dp_device to a new cdns_mhdp_device - structure which will be used by two separate drivers later on. -- Moved some datatypes (audio_format, audio_info, - vic_pxl_encoding_format, video_info) from cdn-dp-core.c to cdn-dp-reg.h. -- Changed prefixes from cdn_dp to cdns_mhdp cdn -> cdns to match the other Cadence's drivers - dp -> mhdp to distinguish it from a "just a DP" as the IP underneath this registers map can be a HDMI (which is - internally different, but the interface for commands, events is pretty much the same). -- Modified cdn-dp-core.c to use the new driver structure and new function names. - -Signed-off-by: Damian Kos -Reviewed-by: Andrzej Hajda -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/rockchip/cdn-dp-core.c | 220 +++++++++-------- - drivers/gpu/drm/rockchip/cdn-dp-core.h | 40 +--- - drivers/gpu/drm/rockchip/cdn-dp-reg.c | 415 +++++++++++++++++---------------- - drivers/gpu/drm/rockchip/cdn-dp-reg.h | 114 +++++++-- - 4 files changed, 423 insertions(+), 366 deletions(-) - ---- a/drivers/gpu/drm/rockchip/cdn-dp-core.c -+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c -@@ -22,11 +22,10 @@ - #include - - #include "cdn-dp-core.h" --#include "cdn-dp-reg.h" - #include "rockchip_drm_vop.h" - - #define connector_to_dp(c) \ -- container_of(c, struct cdn_dp_device, connector) -+ container_of(c, struct cdn_dp_device, mhdp.connector) - - #define encoder_to_dp(c) \ - container_of(c, struct cdn_dp_device, encoder) -@@ -61,17 +60,18 @@ MODULE_DEVICE_TABLE(of, cdn_dp_dt_ids); - static int cdn_dp_grf_write(struct cdn_dp_device *dp, - unsigned int reg, unsigned int val) - { -+ struct device *dev = dp->mhdp.dev; - int ret; - - ret = clk_prepare_enable(dp->grf_clk); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed to prepare_enable grf clock\n"); -+ DRM_DEV_ERROR(dev, "Failed to prepare_enable grf clock\n"); - return ret; - } - - ret = regmap_write(dp->grf, reg, val); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret); -+ DRM_DEV_ERROR(dev, "Could not write to GRF: %d\n", ret); - clk_disable_unprepare(dp->grf_clk); - return ret; - } -@@ -83,24 +83,25 @@ static int cdn_dp_grf_write(struct cdn_d - - static int cdn_dp_clk_enable(struct cdn_dp_device *dp) - { -+ struct device *dev = dp->mhdp.dev; - int ret; - unsigned long rate; - - ret = clk_prepare_enable(dp->pclk); - if (ret < 0) { -- DRM_DEV_ERROR(dp->dev, "cannot enable dp pclk %d\n", ret); -+ DRM_DEV_ERROR(dev, "cannot enable dp pclk %d\n", ret); - goto err_pclk; - } - - ret = clk_prepare_enable(dp->core_clk); - if (ret < 0) { -- DRM_DEV_ERROR(dp->dev, "cannot enable core_clk %d\n", ret); -+ DRM_DEV_ERROR(dev, "cannot enable core_clk %d\n", ret); - goto err_core_clk; - } - -- ret = pm_runtime_get_sync(dp->dev); -+ ret = pm_runtime_get_sync(dev); - if (ret < 0) { -- DRM_DEV_ERROR(dp->dev, "cannot get pm runtime %d\n", ret); -+ DRM_DEV_ERROR(dev, "cannot get pm runtime %d\n", ret); - goto err_pm_runtime_get; - } - -@@ -113,18 +114,18 @@ static int cdn_dp_clk_enable(struct cdn_ - - rate = clk_get_rate(dp->core_clk); - if (!rate) { -- DRM_DEV_ERROR(dp->dev, "get clk rate failed\n"); -+ DRM_DEV_ERROR(dev, "get clk rate failed\n"); - ret = -EINVAL; - goto err_set_rate; - } - -- cdn_dp_set_fw_clk(dp, rate); -- cdn_dp_clock_reset(dp); -+ cdns_mhdp_set_fw_clk(&dp->mhdp, rate); -+ cdns_mhdp_clock_reset(&dp->mhdp); - - return 0; - - err_set_rate: -- pm_runtime_put(dp->dev); -+ pm_runtime_put(dev); - err_pm_runtime_get: - clk_disable_unprepare(dp->core_clk); - err_core_clk: -@@ -135,7 +136,7 @@ err_pclk: - - static void cdn_dp_clk_disable(struct cdn_dp_device *dp) - { -- pm_runtime_put_sync(dp->dev); -+ pm_runtime_put_sync(dp->mhdp.dev); - clk_disable_unprepare(dp->pclk); - clk_disable_unprepare(dp->core_clk); - } -@@ -168,7 +169,7 @@ static int cdn_dp_get_sink_count(struct - u8 value; - - *sink_count = 0; -- ret = cdn_dp_dpcd_read(dp, DP_SINK_COUNT, &value, 1); -+ ret = cdns_mhdp_dpcd_read(&dp->mhdp, DP_SINK_COUNT, &value, 1); - if (ret) - return ret; - -@@ -192,12 +193,13 @@ static struct cdn_dp_port *cdn_dp_connec - - static bool cdn_dp_check_sink_connection(struct cdn_dp_device *dp) - { -+ struct device *dev = dp->mhdp.dev; - unsigned long timeout = jiffies + msecs_to_jiffies(CDN_DPCD_TIMEOUT_MS); - struct cdn_dp_port *port; - u8 sink_count = 0; - - if (dp->active_port < 0 || dp->active_port >= dp->ports) { -- DRM_DEV_ERROR(dp->dev, "active_port is wrong!\n"); -+ DRM_DEV_ERROR(dev, "active_port is wrong!\n"); - return false; - } - -@@ -219,7 +221,7 @@ static bool cdn_dp_check_sink_connection - usleep_range(5000, 10000); - } - -- DRM_DEV_ERROR(dp->dev, "Get sink capability timed out\n"); -+ DRM_DEV_ERROR(dev, "Get sink capability timed out\n"); - return false; - } - -@@ -261,7 +263,8 @@ static int cdn_dp_connector_get_modes(st - mutex_lock(&dp->lock); - edid = dp->edid; - if (edid) { -- DRM_DEV_DEBUG_KMS(dp->dev, "got edid: width[%d] x height[%d]\n", -+ DRM_DEV_DEBUG_KMS(dp->mhdp.dev, -+ "got edid: width[%d] x height[%d]\n", - edid->width_cm, edid->height_cm); - - dp->sink_has_audio = drm_detect_monitor_audio(edid); -@@ -279,7 +282,8 @@ static int cdn_dp_connector_mode_valid(s - struct drm_display_mode *mode) - { - struct cdn_dp_device *dp = connector_to_dp(connector); -- struct drm_display_info *display_info = &dp->connector.display_info; -+ struct drm_display_info *display_info = -+ &dp->mhdp.connector.display_info; - u32 requested, actual, rate, sink_max, source_max = 0; - u8 lanes, bpc; - -@@ -305,7 +309,7 @@ static int cdn_dp_connector_mode_valid(s - sink_max = drm_dp_max_lane_count(dp->dpcd); - lanes = min(source_max, sink_max); - -- source_max = drm_dp_bw_code_to_link_rate(CDN_DP_MAX_LINK_RATE); -+ source_max = drm_dp_bw_code_to_link_rate(CDNS_DP_MAX_LINK_RATE); - sink_max = drm_dp_max_link_rate(dp->dpcd); - rate = min(source_max, sink_max); - -@@ -315,7 +319,7 @@ static int cdn_dp_connector_mode_valid(s - actual = actual * 8 / 10; - - if (requested > actual) { -- DRM_DEV_DEBUG_KMS(dp->dev, -+ DRM_DEV_DEBUG_KMS(dp->mhdp.dev, - "requested=%d, actual=%d, clock=%d\n", - requested, actual, mode->clock); - return MODE_CLOCK_HIGH; -@@ -335,28 +339,29 @@ static int cdn_dp_firmware_init(struct c - const u32 *iram_data, *dram_data; - const struct firmware *fw = dp->fw; - const struct cdn_firmware_header *hdr; -+ struct device *dev = dp->mhdp.dev; - - hdr = (struct cdn_firmware_header *)fw->data; - if (fw->size != le32_to_cpu(hdr->size_bytes)) { -- DRM_DEV_ERROR(dp->dev, "firmware is invalid\n"); -+ DRM_DEV_ERROR(dev, "firmware is invalid\n"); - return -EINVAL; - } - - iram_data = (const u32 *)(fw->data + hdr->header_size); - dram_data = (const u32 *)(fw->data + hdr->header_size + hdr->iram_size); - -- ret = cdn_dp_load_firmware(dp, iram_data, hdr->iram_size, -- dram_data, hdr->dram_size); -+ ret = cdns_mhdp_load_firmware(&dp->mhdp, iram_data, hdr->iram_size, -+ dram_data, hdr->dram_size); - if (ret) - return ret; - -- ret = cdn_dp_set_firmware_active(dp, true); -+ ret = cdns_mhdp_set_firmware_active(&dp->mhdp, true); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "active ucpu failed: %d\n", ret); -+ DRM_DEV_ERROR(dev, "active ucpu failed: %d\n", ret); - return ret; - } - -- return cdn_dp_event_config(dp); -+ return cdns_mhdp_event_config(&dp->mhdp); - } - - static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp) -@@ -366,28 +371,29 @@ static int cdn_dp_get_sink_capability(st - if (!cdn_dp_check_sink_connection(dp)) - return -ENODEV; - -- ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd, -- DP_RECEIVER_CAP_SIZE); -+ ret = cdns_mhdp_dpcd_read(&dp->mhdp, DP_DPCD_REV, dp->dpcd, -+ DP_RECEIVER_CAP_SIZE); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret); -+ DRM_DEV_ERROR(dp->mhdp.dev, "Failed to get caps %d\n", ret); - return ret; - } - - kfree(dp->edid); -- dp->edid = drm_do_get_edid(&dp->connector, -- cdn_dp_get_edid_block, dp); -+ dp->edid = drm_do_get_edid(&dp->mhdp.connector, -+ cdns_mhdp_get_edid_block, &dp->mhdp); - return 0; - } - - static int cdn_dp_enable_phy(struct cdn_dp_device *dp, struct cdn_dp_port *port) - { -+ struct device *dev = dp->mhdp.dev; - union extcon_property_value property; - int ret; - - if (!port->phy_enabled) { - ret = phy_power_on(port->phy); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "phy power on failed: %d\n", -+ DRM_DEV_ERROR(dev, "phy power on failed: %d\n", - ret); - goto err_phy; - } -@@ -397,28 +403,28 @@ static int cdn_dp_enable_phy(struct cdn_ - ret = cdn_dp_grf_write(dp, GRF_SOC_CON26, - DPTX_HPD_SEL_MASK | DPTX_HPD_SEL); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed to write HPD_SEL %d\n", ret); -+ DRM_DEV_ERROR(dev, "Failed to write HPD_SEL %d\n", ret); - goto err_power_on; - } - -- ret = cdn_dp_get_hpd_status(dp); -+ ret = cdns_mhdp_get_hpd_status(&dp->mhdp); - if (ret <= 0) { - if (!ret) -- DRM_DEV_ERROR(dp->dev, "hpd does not exist\n"); -+ DRM_DEV_ERROR(dev, "hpd does not exist\n"); - goto err_power_on; - } - - ret = extcon_get_property(port->extcon, EXTCON_DISP_DP, - EXTCON_PROP_USB_TYPEC_POLARITY, &property); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "get property failed\n"); -+ DRM_DEV_ERROR(dev, "get property failed\n"); - goto err_power_on; - } - - port->lanes = cdn_dp_get_port_lanes(port); -- ret = cdn_dp_set_host_cap(dp, port->lanes, property.intval); -+ ret = cdns_mhdp_set_host_cap(&dp->mhdp, port->lanes, property.intval); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "set host capabilities failed: %d\n", -+ DRM_DEV_ERROR(dev, "set host capabilities failed: %d\n", - ret); - goto err_power_on; - } -@@ -428,7 +434,7 @@ static int cdn_dp_enable_phy(struct cdn_ - - err_power_on: - if (phy_power_off(port->phy)) -- DRM_DEV_ERROR(dp->dev, "phy power off failed: %d", ret); -+ DRM_DEV_ERROR(dev, "phy power off failed: %d", ret); - else - port->phy_enabled = false; - -@@ -446,7 +452,8 @@ static int cdn_dp_disable_phy(struct cdn - if (port->phy_enabled) { - ret = phy_power_off(port->phy); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "phy power off failed: %d", ret); -+ DRM_DEV_ERROR(dp->mhdp.dev, -+ "phy power off failed: %d", ret); - return ret; - } - } -@@ -470,16 +477,16 @@ static int cdn_dp_disable(struct cdn_dp_ - ret = cdn_dp_grf_write(dp, GRF_SOC_CON26, - DPTX_HPD_SEL_MASK | DPTX_HPD_DEL); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed to clear hpd sel %d\n", -+ DRM_DEV_ERROR(dp->mhdp.dev, "Failed to clear hpd sel %d\n", - ret); - return ret; - } - -- cdn_dp_set_firmware_active(dp, false); -+ cdns_mhdp_set_firmware_active(&dp->mhdp, false); - cdn_dp_clk_disable(dp); - dp->active = false; -- dp->link.rate = 0; -- dp->link.num_lanes = 0; -+ dp->mhdp.link.rate = 0; -+ dp->mhdp.link.num_lanes = 0; - if (!dp->connected) { - kfree(dp->edid); - dp->edid = NULL; -@@ -492,11 +499,11 @@ static int cdn_dp_enable(struct cdn_dp_d - { - int ret, i, lanes; - struct cdn_dp_port *port; -+ struct device *dev = dp->mhdp.dev; - - port = cdn_dp_connected_port(dp); - if (!port) { -- DRM_DEV_ERROR(dp->dev, -- "Can't enable without connection\n"); -+ DRM_DEV_ERROR(dev, "Can't enable without connection\n"); - return -ENODEV; - } - -@@ -509,7 +516,7 @@ static int cdn_dp_enable(struct cdn_dp_d - - ret = cdn_dp_firmware_init(dp); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "firmware init failed: %d", ret); -+ DRM_DEV_ERROR(dp->mhdp.dev, "firmware init failed: %d", ret); - goto err_clk_disable; - } - -@@ -543,8 +550,9 @@ static void cdn_dp_encoder_mode_set(stru - struct drm_display_mode *adjusted) - { - struct cdn_dp_device *dp = encoder_to_dp(encoder); -- struct drm_display_info *display_info = &dp->connector.display_info; -- struct video_info *video = &dp->video_info; -+ struct drm_display_info *display_info = -+ &dp->mhdp.connector.display_info; -+ struct video_info *video = &dp->mhdp.video_info; - - switch (display_info->bpc) { - case 10: -@@ -562,7 +570,7 @@ static void cdn_dp_encoder_mode_set(stru - video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); - video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); - -- memcpy(&dp->mode, adjusted, sizeof(*mode)); -+ memcpy(&dp->mhdp.mode, adjusted, sizeof(*mode)); - } - - static bool cdn_dp_check_link_status(struct cdn_dp_device *dp) -@@ -571,11 +579,11 @@ static bool cdn_dp_check_link_status(str - struct cdn_dp_port *port = cdn_dp_connected_port(dp); - u8 sink_lanes = drm_dp_max_lane_count(dp->dpcd); - -- if (!port || !dp->link.rate || !dp->link.num_lanes) -+ if (!port || !dp->mhdp.link.rate || !dp->mhdp.link.num_lanes) - return false; - -- if (cdn_dp_dpcd_read(dp, DP_LANE0_1_STATUS, link_status, -- DP_LINK_STATUS_SIZE)) { -+ if (cdns_mhdp_dpcd_read(&dp->mhdp, DP_LANE0_1_STATUS, link_status, -+ DP_LINK_STATUS_SIZE)) { - DRM_ERROR("Failed to get link status\n"); - return false; - } -@@ -587,15 +595,16 @@ static bool cdn_dp_check_link_status(str - static void cdn_dp_encoder_enable(struct drm_encoder *encoder) - { - struct cdn_dp_device *dp = encoder_to_dp(encoder); -+ struct device *dev = dp->mhdp.dev; - int ret, val; - -- ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder); -+ ret = drm_of_encoder_active_endpoint_id(dev->of_node, encoder); - if (ret < 0) { -- DRM_DEV_ERROR(dp->dev, "Could not get vop id, %d", ret); -+ DRM_DEV_ERROR(dev, "Could not get vop id, %d", ret); - return; - } - -- DRM_DEV_DEBUG_KMS(dp->dev, "vop %s output to cdn-dp\n", -+ DRM_DEV_DEBUG_KMS(dev, "vop %s output to cdn-dp\n", - (ret) ? "LIT" : "BIG"); - if (ret) - val = DP_SEL_VOP_LIT | (DP_SEL_VOP_LIT << 16); -@@ -610,33 +619,33 @@ static void cdn_dp_encoder_enable(struct - - ret = cdn_dp_enable(dp); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed to enable encoder %d\n", -+ DRM_DEV_ERROR(dev, "Failed to enable encoder %d\n", - ret); - goto out; - } - if (!cdn_dp_check_link_status(dp)) { -- ret = cdn_dp_train_link(dp); -+ ret = cdns_mhdp_train_link(&dp->mhdp); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed link train %d\n", ret); -+ DRM_DEV_ERROR(dev, "Failed link train %d\n", ret); - goto out; - } - } - -- ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE); -+ ret = cdns_mhdp_set_video_status(&dp->mhdp, CONTROL_VIDEO_IDLE); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret); -+ DRM_DEV_ERROR(dev, "Failed to idle video %d\n", ret); - goto out; - } - -- ret = cdn_dp_config_video(dp); -+ ret = cdns_mhdp_config_video(&dp->mhdp); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed to config video %d\n", ret); -+ DRM_DEV_ERROR(dev, "Failed to config video %d\n", ret); - goto out; - } - -- ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID); -+ ret = cdns_mhdp_set_video_status(&dp->mhdp, CONTROL_VIDEO_VALID); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret); -+ DRM_DEV_ERROR(dev, "Failed to valid video %d\n", ret); - goto out; - } - out: -@@ -652,7 +661,8 @@ static void cdn_dp_encoder_disable(struc - if (dp->active) { - ret = cdn_dp_disable(dp); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed to disable encoder %d\n", -+ DRM_DEV_ERROR(dp->mhdp.dev, -+ "Failed to disable encoder %d\n", - ret); - } - } -@@ -696,7 +706,7 @@ static const struct drm_encoder_funcs cd - - static int cdn_dp_parse_dt(struct cdn_dp_device *dp) - { -- struct device *dev = dp->dev; -+ struct device *dev = dp->mhdp.dev; - struct device_node *np = dev->of_node; - struct platform_device *pdev = to_platform_device(dev); - struct resource *res; -@@ -708,10 +718,10 @@ static int cdn_dp_parse_dt(struct cdn_dp - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- dp->regs = devm_ioremap_resource(dev, res); -- if (IS_ERR(dp->regs)) { -+ dp->mhdp.regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(dp->mhdp.regs)) { - DRM_DEV_ERROR(dev, "ioremap reg failed\n"); -- return PTR_ERR(dp->regs); -+ return PTR_ERR(dp->mhdp.regs); - } - - dp->core_clk = devm_clk_get(dev, "core-clk"); -@@ -726,10 +736,10 @@ static int cdn_dp_parse_dt(struct cdn_dp - return PTR_ERR(dp->pclk); - } - -- dp->spdif_clk = devm_clk_get(dev, "spdif"); -- if (IS_ERR(dp->spdif_clk)) { -+ dp->mhdp.spdif_clk = devm_clk_get(dev, "spdif"); -+ if (IS_ERR(dp->mhdp.spdif_clk)) { - DRM_DEV_ERROR(dev, "cannot get spdif_clk\n"); -- return PTR_ERR(dp->spdif_clk); -+ return PTR_ERR(dp->mhdp.spdif_clk); - } - - dp->grf_clk = devm_clk_get(dev, "grf"); -@@ -738,10 +748,10 @@ static int cdn_dp_parse_dt(struct cdn_dp - return PTR_ERR(dp->grf_clk); - } - -- dp->spdif_rst = devm_reset_control_get(dev, "spdif"); -- if (IS_ERR(dp->spdif_rst)) { -+ dp->mhdp.spdif_rst = devm_reset_control_get(dev, "spdif"); -+ if (IS_ERR(dp->mhdp.spdif_rst)) { - DRM_DEV_ERROR(dev, "no spdif reset control found\n"); -- return PTR_ERR(dp->spdif_rst); -+ return PTR_ERR(dp->mhdp.spdif_rst); - } - - dp->dptx_rst = devm_reset_control_get(dev, "dptx"); -@@ -796,7 +806,7 @@ static int cdn_dp_audio_hw_params(struct - goto out; - } - -- ret = cdn_dp_audio_config(dp, &audio); -+ ret = cdns_mhdp_audio_config(&dp->mhdp, &audio); - if (!ret) - dp->audio_info = audio; - -@@ -814,7 +824,7 @@ static void cdn_dp_audio_shutdown(struct - if (!dp->active) - goto out; - -- ret = cdn_dp_audio_stop(dp, &dp->audio_info); -+ ret = cdns_mhdp_audio_stop(&dp->mhdp, &dp->audio_info); - if (!ret) - dp->audio_info.format = AFMT_UNUSED; - out: -@@ -833,7 +843,7 @@ static int cdn_dp_audio_digital_mute(str - goto out; - } - -- ret = cdn_dp_audio_mute(dp, enable); -+ ret = cdns_mhdp_audio_mute(&dp->mhdp, enable); - - out: - mutex_unlock(&dp->lock); -@@ -845,7 +855,8 @@ static int cdn_dp_audio_get_eld(struct d - { - struct cdn_dp_device *dp = dev_get_drvdata(dev); - -- memcpy(buf, dp->connector.eld, min(sizeof(dp->connector.eld), len)); -+ memcpy(buf, dp->mhdp.connector.eld, -+ min(sizeof(dp->mhdp.connector.eld), len)); - - return 0; - } -@@ -879,6 +890,7 @@ static int cdn_dp_request_firmware(struc - int ret; - unsigned long timeout = jiffies + msecs_to_jiffies(CDN_FW_TIMEOUT_MS); - unsigned long sleep = 1000; -+ struct device *dev = dp->mhdp.dev; - - WARN_ON(!mutex_is_locked(&dp->lock)); - -@@ -889,13 +901,13 @@ static int cdn_dp_request_firmware(struc - mutex_unlock(&dp->lock); - - while (time_before(jiffies, timeout)) { -- ret = request_firmware(&dp->fw, CDN_DP_FIRMWARE, dp->dev); -+ ret = request_firmware(&dp->fw, CDN_DP_FIRMWARE, dev); - if (ret == -ENOENT) { - msleep(sleep); - sleep *= 2; - continue; - } else if (ret) { -- DRM_DEV_ERROR(dp->dev, -+ DRM_DEV_ERROR(dev, - "failed to request firmware: %d\n", ret); - goto out; - } -@@ -905,7 +917,7 @@ static int cdn_dp_request_firmware(struc - goto out; - } - -- DRM_DEV_ERROR(dp->dev, "Timed out trying to load firmware\n"); -+ DRM_DEV_ERROR(dev, "Timed out trying to load firmware\n"); - ret = -ETIMEDOUT; - out: - mutex_lock(&dp->lock); -@@ -916,8 +928,9 @@ static void cdn_dp_pd_event_work(struct - { - struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device, - event_work); -- struct drm_connector *connector = &dp->connector; -+ struct drm_connector *connector = &dp->mhdp.connector; - enum drm_connector_status old_status; -+ struct device *dev = dp->mhdp.dev; - - int ret; - -@@ -934,44 +947,45 @@ static void cdn_dp_pd_event_work(struct - - /* Not connected, notify userspace to disable the block */ - if (!cdn_dp_connected_port(dp)) { -- DRM_DEV_INFO(dp->dev, "Not connected. Disabling cdn\n"); -+ DRM_DEV_INFO(dev, "Not connected. Disabling cdn\n"); - dp->connected = false; - - /* Connected but not enabled, enable the block */ - } else if (!dp->active) { -- DRM_DEV_INFO(dp->dev, "Connected, not enabled. Enabling cdn\n"); -+ DRM_DEV_INFO(dev, "Connected, not enabled. Enabling cdn\n"); - ret = cdn_dp_enable(dp); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Enable dp failed %d\n", ret); -+ DRM_DEV_ERROR(dev, "Enable dp failed %d\n", ret); - dp->connected = false; - } - - /* Enabled and connected to a dongle without a sink, notify userspace */ - } else if (!cdn_dp_check_sink_connection(dp)) { -- DRM_DEV_INFO(dp->dev, "Connected without sink. Assert hpd\n"); -+ DRM_DEV_INFO(dev, "Connected without sink. Assert hpd\n"); - dp->connected = false; - - /* Enabled and connected with a sink, re-train if requested */ - } else if (!cdn_dp_check_link_status(dp)) { -- unsigned int rate = dp->link.rate; -- unsigned int lanes = dp->link.num_lanes; -- struct drm_display_mode *mode = &dp->mode; -+ unsigned int rate = dp->mhdp.link.rate; -+ unsigned int lanes = dp->mhdp.link.num_lanes; -+ struct drm_display_mode *mode = &dp->mhdp.mode; - -- DRM_DEV_INFO(dp->dev, "Connected with sink. Re-train link\n"); -- ret = cdn_dp_train_link(dp); -+ DRM_DEV_INFO(dev, "Connected with sink. Re-train link\n"); -+ ret = cdns_mhdp_train_link(&dp->mhdp); - if (ret) { - dp->connected = false; -- DRM_DEV_ERROR(dp->dev, "Train link failed %d\n", ret); -+ DRM_DEV_ERROR(dev, "Train link failed %d\n", ret); - goto out; - } - - /* If training result is changed, update the video config */ - if (mode->clock && -- (rate != dp->link.rate || lanes != dp->link.num_lanes)) { -- ret = cdn_dp_config_video(dp); -+ (rate != dp->mhdp.link.rate || -+ lanes != dp->mhdp.link.num_lanes)) { -+ ret = cdns_mhdp_config_video(&dp->mhdp); - if (ret) { - dp->connected = false; -- DRM_DEV_ERROR(dp->dev, -+ DRM_DEV_ERROR(dev, - "Failed to config video %d\n", - ret); - } -@@ -1040,7 +1054,7 @@ static int cdn_dp_bind(struct device *de - - drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs); - -- connector = &dp->connector; -+ connector = &dp->mhdp.connector; - connector->polled = DRM_CONNECTOR_POLL_HPD; - connector->dpms = DRM_MODE_DPMS_OFF; - -@@ -1064,7 +1078,7 @@ static int cdn_dp_bind(struct device *de - port = dp->port[i]; - - port->event_nb.notifier_call = cdn_dp_pd_event; -- ret = devm_extcon_register_notifier(dp->dev, port->extcon, -+ ret = devm_extcon_register_notifier(dp->mhdp.dev, port->extcon, - EXTCON_DISP_DP, - &port->event_nb); - if (ret) { -@@ -1091,7 +1105,7 @@ static void cdn_dp_unbind(struct device - { - struct cdn_dp_device *dp = dev_get_drvdata(dev); - struct drm_encoder *encoder = &dp->encoder; -- struct drm_connector *connector = &dp->connector; -+ struct drm_connector *connector = &dp->mhdp.connector; - - cancel_work_sync(&dp->event_work); - cdn_dp_encoder_disable(encoder); -@@ -1151,7 +1165,7 @@ static int cdn_dp_probe(struct platform_ - dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); - if (!dp) - return -ENOMEM; -- dp->dev = dev; -+ dp->mhdp.dev = dev; - - match = of_match_node(cdn_dp_dt_ids, pdev->dev.of_node); - dp_data = (struct cdn_dp_data *)match->data; -@@ -1196,7 +1210,7 @@ static int cdn_dp_remove(struct platform - struct cdn_dp_device *dp = platform_get_drvdata(pdev); - - platform_device_unregister(dp->audio_pdev); -- cdn_dp_suspend(dp->dev); -+ cdn_dp_suspend(dp->mhdp.dev); - component_del(&pdev->dev, &cdn_dp_component_ops); - - return 0; -@@ -1206,7 +1220,7 @@ static void cdn_dp_shutdown(struct platf - { - struct cdn_dp_device *dp = platform_get_drvdata(pdev); - -- cdn_dp_suspend(dp->dev); -+ cdn_dp_suspend(dp->mhdp.dev); - } - - static const struct dev_pm_ops cdn_dp_pm_ops = { ---- a/drivers/gpu/drm/rockchip/cdn-dp-core.h -+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h -@@ -12,38 +12,10 @@ - #include - - #include "rockchip_drm_drv.h" -+#include "cdn-dp-reg.h" - - #define MAX_PHY 2 - --enum audio_format { -- AFMT_I2S = 0, -- AFMT_SPDIF = 1, -- AFMT_UNUSED, --}; -- --struct audio_info { -- enum audio_format format; -- int sample_rate; -- int channels; -- int sample_width; --}; -- --enum vic_pxl_encoding_format { -- PXL_RGB = 0x1, -- YCBCR_4_4_4 = 0x2, -- YCBCR_4_2_2 = 0x4, -- YCBCR_4_2_0 = 0x8, -- Y_ONLY = 0x10, --}; -- --struct video_info { -- bool h_sync_polarity; -- bool v_sync_polarity; -- bool interlaced; -- int color_depth; -- enum vic_pxl_encoding_format color_fmt; --}; -- - struct cdn_firmware_header { - u32 size_bytes; /* size of the entire header+image(s) in bytes */ - u32 header_size; /* size of just the header in bytes */ -@@ -62,11 +34,9 @@ struct cdn_dp_port { - }; - - struct cdn_dp_device { -- struct device *dev; -+ struct cdns_mhdp_device mhdp; - struct drm_device *drm_dev; -- struct drm_connector connector; - struct drm_encoder encoder; -- struct drm_display_mode mode; - struct platform_device *audio_pdev; - struct work_struct event_work; - struct edid *edid; -@@ -77,22 +47,16 @@ struct cdn_dp_device { - bool suspended; - - const struct firmware *fw; /* cdn dp firmware */ -- unsigned int fw_version; /* cdn fw version */ - bool fw_loaded; - -- void __iomem *regs; - struct regmap *grf; - struct clk *core_clk; - struct clk *pclk; -- struct clk *spdif_clk; - struct clk *grf_clk; -- struct reset_control *spdif_rst; - struct reset_control *dptx_rst; - struct reset_control *apb_rst; - struct reset_control *core_rst; - struct audio_info audio_info; -- struct video_info video_info; -- struct drm_dp_link link; - struct cdn_dp_port *port[MAX_PHY]; - u8 ports; - u8 lanes; ---- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c -+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c -@@ -14,19 +14,19 @@ - #include "cdn-dp-core.h" - #include "cdn-dp-reg.h" - --#define CDN_DP_SPDIF_CLK 200000000 -+#define CDNS_DP_SPDIF_CLK 200000000 - #define FW_ALIVE_TIMEOUT_US 1000000 - #define MAILBOX_RETRY_US 1000 - #define MAILBOX_TIMEOUT_US 5000000 - #define LINK_TRAINING_RETRY_MS 20 - #define LINK_TRAINING_TIMEOUT_MS 500 - --void cdn_dp_set_fw_clk(struct cdn_dp_device *dp, unsigned long clk) -+void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk) - { -- writel(clk / 1000000, dp->regs + SW_CLK_H); -+ writel(clk / 1000000, mhdp->regs + SW_CLK_H); - } - --void cdn_dp_clock_reset(struct cdn_dp_device *dp) -+void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp) - { - u32 val; - -@@ -42,16 +42,16 @@ void cdn_dp_clock_reset(struct cdn_dp_de - DPTX_SYS_CLK_EN | - CFG_DPTX_VIF_CLK_RSTN_EN | - CFG_DPTX_VIF_CLK_EN; -- writel(val, dp->regs + SOURCE_DPTX_CAR); -+ writel(val, mhdp->regs + SOURCE_DPTX_CAR); - - val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN; -- writel(val, dp->regs + SOURCE_PHY_CAR); -+ writel(val, mhdp->regs + SOURCE_PHY_CAR); - - val = SOURCE_PKT_SYS_RSTN_EN | - SOURCE_PKT_SYS_CLK_EN | - SOURCE_PKT_DATA_RSTN_EN | - SOURCE_PKT_DATA_CLK_EN; -- writel(val, dp->regs + SOURCE_PKT_CAR); -+ writel(val, mhdp->regs + SOURCE_PKT_CAR); - - val = SPDIF_CDR_CLK_RSTN_EN | - SPDIF_CDR_CLK_EN | -@@ -59,53 +59,53 @@ void cdn_dp_clock_reset(struct cdn_dp_de - SOURCE_AIF_SYS_CLK_EN | - SOURCE_AIF_CLK_RSTN_EN | - SOURCE_AIF_CLK_EN; -- writel(val, dp->regs + SOURCE_AIF_CAR); -+ writel(val, mhdp->regs + SOURCE_AIF_CAR); - - val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN | - SOURCE_CIPHER_SYS_CLK_EN | - SOURCE_CIPHER_CHAR_CLK_RSTN_EN | - SOURCE_CIPHER_CHAR_CLK_EN; -- writel(val, dp->regs + SOURCE_CIPHER_CAR); -+ writel(val, mhdp->regs + SOURCE_CIPHER_CAR); - - val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN | - SOURCE_CRYPTO_SYS_CLK_EN; -- writel(val, dp->regs + SOURCE_CRYPTO_CAR); -+ writel(val, mhdp->regs + SOURCE_CRYPTO_CAR); - - /* enable Mailbox and PIF interrupt */ -- writel(0, dp->regs + APB_INT_MASK); -+ writel(0, mhdp->regs + APB_INT_MASK); - } - --static int cdn_dp_mailbox_read(struct cdn_dp_device *dp) -+static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp) - { - int val, ret; - -- ret = readx_poll_timeout(readl, dp->regs + MAILBOX_EMPTY_ADDR, -+ ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_EMPTY_ADDR, - val, !val, MAILBOX_RETRY_US, - MAILBOX_TIMEOUT_US); - if (ret < 0) - return ret; - -- return readl(dp->regs + MAILBOX0_RD_DATA) & 0xff; -+ return readl(mhdp->regs + MAILBOX0_RD_DATA) & 0xff; - } - --static int cdp_dp_mailbox_write(struct cdn_dp_device *dp, u8 val) -+static int cdp_dp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val) - { - int ret, full; - -- ret = readx_poll_timeout(readl, dp->regs + MAILBOX_FULL_ADDR, -+ ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_FULL_ADDR, - full, !full, MAILBOX_RETRY_US, - MAILBOX_TIMEOUT_US); - if (ret < 0) - return ret; - -- writel(val, dp->regs + MAILBOX0_WR_DATA); -+ writel(val, mhdp->regs + MAILBOX0_WR_DATA); - - return 0; - } - --static int cdn_dp_mailbox_validate_receive(struct cdn_dp_device *dp, -- u8 module_id, u8 opcode, -- u16 req_size) -+static int cdns_mhdp_mailbox_validate_receive(struct cdns_mhdp_device *mhdp, -+ u8 module_id, u8 opcode, -+ u16 req_size) - { - u32 mbox_size, i; - u8 header[4]; -@@ -113,7 +113,7 @@ static int cdn_dp_mailbox_validate_recei - - /* read the header of the message */ - for (i = 0; i < 4; i++) { -- ret = cdn_dp_mailbox_read(dp); -+ ret = cdns_mhdp_mailbox_read(mhdp); - if (ret < 0) - return ret; - -@@ -129,7 +129,7 @@ static int cdn_dp_mailbox_validate_recei - * clear the mailbox by reading its contents. - */ - for (i = 0; i < mbox_size; i++) -- if (cdn_dp_mailbox_read(dp) < 0) -+ if (cdns_mhdp_mailbox_read(mhdp) < 0) - break; - - return -EINVAL; -@@ -138,14 +138,14 @@ static int cdn_dp_mailbox_validate_recei - return 0; - } - --static int cdn_dp_mailbox_read_receive(struct cdn_dp_device *dp, -- u8 *buff, u16 buff_size) -+static int cdns_mhdp_mailbox_read_receive(struct cdns_mhdp_device *mhdp, -+ u8 *buff, u16 buff_size) - { - u32 i; - int ret; - - for (i = 0; i < buff_size; i++) { -- ret = cdn_dp_mailbox_read(dp); -+ ret = cdns_mhdp_mailbox_read(mhdp); - if (ret < 0) - return ret; - -@@ -155,8 +155,8 @@ static int cdn_dp_mailbox_read_receive(s - return 0; - } - --static int cdn_dp_mailbox_send(struct cdn_dp_device *dp, u8 module_id, -- u8 opcode, u16 size, u8 *message) -+static int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id, -+ u8 opcode, u16 size, u8 *message) - { - u8 header[4]; - int ret, i; -@@ -167,13 +167,13 @@ static int cdn_dp_mailbox_send(struct cd - header[3] = size & 0xff; - - for (i = 0; i < 4; i++) { -- ret = cdp_dp_mailbox_write(dp, header[i]); -+ ret = cdp_dp_mailbox_write(mhdp, header[i]); - if (ret) - return ret; - } - - for (i = 0; i < size; i++) { -- ret = cdp_dp_mailbox_write(dp, message[i]); -+ ret = cdp_dp_mailbox_write(mhdp, message[i]); - if (ret) - return ret; - } -@@ -181,7 +181,7 @@ static int cdn_dp_mailbox_send(struct cd - return 0; - } - --static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val) -+static int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u16 addr, u32 val) - { - u8 msg[6]; - -@@ -191,12 +191,12 @@ static int cdn_dp_reg_write(struct cdn_d - msg[3] = (val >> 16) & 0xff; - msg[4] = (val >> 8) & 0xff; - msg[5] = val & 0xff; -- return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_REGISTER, -- sizeof(msg), msg); -+ return cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_REGISTER, sizeof(msg), msg); - } - --static int cdn_dp_reg_write_bit(struct cdn_dp_device *dp, u16 addr, -- u8 start_bit, u8 bits_no, u32 val) -+static int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr, -+ u8 start_bit, u8 bits_no, u32 val) - { - u8 field[8]; - -@@ -209,11 +209,12 @@ static int cdn_dp_reg_write_bit(struct c - field[6] = (val >> 8) & 0xff; - field[7] = val & 0xff; - -- return cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_FIELD, -- sizeof(field), field); -+ return cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_FIELD, sizeof(field), field); - } - --int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len) -+int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp, -+ u32 addr, u8 *data, u16 len) - { - u8 msg[5], reg[5]; - int ret; -@@ -223,28 +224,28 @@ int cdn_dp_dpcd_read(struct cdn_dp_devic - msg[2] = (addr >> 16) & 0xff; - msg[3] = (addr >> 8) & 0xff; - msg[4] = addr & 0xff; -- ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_DPCD, -- sizeof(msg), msg); -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_DPCD, sizeof(msg), msg); - if (ret) - goto err_dpcd_read; - -- ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX, -- DPTX_READ_DPCD, -- sizeof(reg) + len); -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_DPCD, -+ sizeof(reg) + len); - if (ret) - goto err_dpcd_read; - -- ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg)); -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); - if (ret) - goto err_dpcd_read; - -- ret = cdn_dp_mailbox_read_receive(dp, data, len); -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, data, len); - - err_dpcd_read: - return ret; - } - --int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value) -+int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value) - { - u8 msg[6], reg[5]; - int ret; -@@ -255,17 +256,17 @@ int cdn_dp_dpcd_write(struct cdn_dp_devi - msg[3] = (addr >> 8) & 0xff; - msg[4] = addr & 0xff; - msg[5] = value; -- ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_WRITE_DPCD, -- sizeof(msg), msg); -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_DPCD, sizeof(msg), msg); - if (ret) - goto err_dpcd_write; - -- ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_DPCD, sizeof(reg)); -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_DPCD, sizeof(reg)); - if (ret) - goto err_dpcd_write; - -- ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg)); -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); - if (ret) - goto err_dpcd_write; - -@@ -274,53 +275,53 @@ int cdn_dp_dpcd_write(struct cdn_dp_devi - - err_dpcd_write: - if (ret) -- DRM_DEV_ERROR(dp->dev, "dpcd write failed: %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "dpcd write failed: %d\n", ret); - return ret; - } - --int cdn_dp_load_firmware(struct cdn_dp_device *dp, const u32 *i_mem, -- u32 i_size, const u32 *d_mem, u32 d_size) -+int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, -+ u32 i_size, const u32 *d_mem, u32 d_size) - { - u32 reg; - int i, ret; - - /* reset ucpu before load firmware*/ - writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET, -- dp->regs + APB_CTRL); -+ mhdp->regs + APB_CTRL); - - for (i = 0; i < i_size; i += 4) -- writel(*i_mem++, dp->regs + ADDR_IMEM + i); -+ writel(*i_mem++, mhdp->regs + ADDR_IMEM + i); - - for (i = 0; i < d_size; i += 4) -- writel(*d_mem++, dp->regs + ADDR_DMEM + i); -+ writel(*d_mem++, mhdp->regs + ADDR_DMEM + i); - - /* un-reset ucpu */ -- writel(0, dp->regs + APB_CTRL); -+ writel(0, mhdp->regs + APB_CTRL); - - /* check the keep alive register to make sure fw working */ -- ret = readx_poll_timeout(readl, dp->regs + KEEP_ALIVE, -+ ret = readx_poll_timeout(readl, mhdp->regs + KEEP_ALIVE, - reg, reg, 2000, FW_ALIVE_TIMEOUT_US); - if (ret < 0) { -- DRM_DEV_ERROR(dp->dev, "failed to loaded the FW reg = %x\n", -+ DRM_DEV_ERROR(mhdp->dev, "failed to loaded the FW reg = %x\n", - reg); - return -EINVAL; - } - -- reg = readl(dp->regs + VER_L) & 0xff; -- dp->fw_version = reg; -- reg = readl(dp->regs + VER_H) & 0xff; -- dp->fw_version |= reg << 8; -- reg = readl(dp->regs + VER_LIB_L_ADDR) & 0xff; -- dp->fw_version |= reg << 16; -- reg = readl(dp->regs + VER_LIB_H_ADDR) & 0xff; -- dp->fw_version |= reg << 24; -+ reg = readl(mhdp->regs + VER_L) & 0xff; -+ mhdp->fw_version = reg; -+ reg = readl(mhdp->regs + VER_H) & 0xff; -+ mhdp->fw_version |= reg << 8; -+ reg = readl(mhdp->regs + VER_LIB_L_ADDR) & 0xff; -+ mhdp->fw_version |= reg << 16; -+ reg = readl(mhdp->regs + VER_LIB_H_ADDR) & 0xff; -+ mhdp->fw_version |= reg << 24; - -- DRM_DEV_DEBUG(dp->dev, "firmware version: %x\n", dp->fw_version); -+ DRM_DEV_DEBUG(mhdp->dev, "firmware version: %x\n", mhdp->fw_version); - - return 0; - } - --int cdn_dp_set_firmware_active(struct cdn_dp_device *dp, bool enable) -+int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable) - { - u8 msg[5]; - int ret, i; -@@ -332,14 +333,14 @@ int cdn_dp_set_firmware_active(struct cd - msg[4] = enable ? FW_ACTIVE : FW_STANDBY; - - for (i = 0; i < sizeof(msg); i++) { -- ret = cdp_dp_mailbox_write(dp, msg[i]); -+ ret = cdp_dp_mailbox_write(mhdp, msg[i]); - if (ret) - goto err_set_firmware_active; - } - - /* read the firmware state */ - for (i = 0; i < sizeof(msg); i++) { -- ret = cdn_dp_mailbox_read(dp); -+ ret = cdns_mhdp_mailbox_read(mhdp); - if (ret < 0) - goto err_set_firmware_active; - -@@ -350,16 +351,16 @@ int cdn_dp_set_firmware_active(struct cd - - err_set_firmware_active: - if (ret < 0) -- DRM_DEV_ERROR(dp->dev, "set firmware active failed\n"); -+ DRM_DEV_ERROR(mhdp->dev, "set firmware active failed\n"); - return ret; - } - --int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip) -+int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip) - { - u8 msg[8]; - int ret; - -- msg[0] = CDN_DP_MAX_LINK_RATE; -+ msg[0] = CDNS_DP_MAX_LINK_RATE; - msg[1] = lanes | SCRAMBLER_EN; - msg[2] = VOLTAGE_LEVEL_2; - msg[3] = PRE_EMPHASIS_LEVEL_3; -@@ -368,22 +369,22 @@ int cdn_dp_set_host_cap(struct cdn_dp_de - msg[6] = flip ? LANE_MAPPING_FLIPPED : LANE_MAPPING_NORMAL; - msg[7] = ENHANCED; - -- ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, -- DPTX_SET_HOST_CAPABILITIES, -- sizeof(msg), msg); -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_SET_HOST_CAPABILITIES, -+ sizeof(msg), msg); - if (ret) - goto err_set_host_cap; - -- ret = cdn_dp_reg_write(dp, DP_AUX_SWAP_INVERSION_CONTROL, -- AUX_HOST_INVERT); -+ ret = cdns_mhdp_reg_write(mhdp, DP_AUX_SWAP_INVERSION_CONTROL, -+ AUX_HOST_INVERT); - - err_set_host_cap: - if (ret) -- DRM_DEV_ERROR(dp->dev, "set host cap failed: %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "set host cap failed: %d\n", ret); - return ret; - } - --int cdn_dp_event_config(struct cdn_dp_device *dp) -+int cdns_mhdp_event_config(struct cdns_mhdp_device *mhdp) - { - u8 msg[5]; - int ret; -@@ -392,49 +393,50 @@ int cdn_dp_event_config(struct cdn_dp_de - - msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING; - -- ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_ENABLE_EVENT, -- sizeof(msg), msg); -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_ENABLE_EVENT, sizeof(msg), msg); - if (ret) -- DRM_DEV_ERROR(dp->dev, "set event config failed: %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "set event config failed: %d\n", ret); - - return ret; - } - --u32 cdn_dp_get_event(struct cdn_dp_device *dp) -+u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp) - { -- return readl(dp->regs + SW_EVENTS0); -+ return readl(mhdp->regs + SW_EVENTS0); - } - --int cdn_dp_get_hpd_status(struct cdn_dp_device *dp) -+int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp) - { - u8 status; - int ret; - -- ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_HPD_STATE, -- 0, NULL); -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_HPD_STATE, 0, NULL); - if (ret) - goto err_get_hpd; - -- ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX, -- DPTX_HPD_STATE, sizeof(status)); -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_HPD_STATE, -+ sizeof(status)); - if (ret) - goto err_get_hpd; - -- ret = cdn_dp_mailbox_read_receive(dp, &status, sizeof(status)); -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, &status, sizeof(status)); - if (ret) - goto err_get_hpd; - - return status; - - err_get_hpd: -- DRM_DEV_ERROR(dp->dev, "get hpd status failed: %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "get hpd status failed: %d\n", ret); - return ret; - } - --int cdn_dp_get_edid_block(void *data, u8 *edid, -+int cdns_mhdp_get_edid_block(void *data, u8 *edid, - unsigned int block, size_t length) - { -- struct cdn_dp_device *dp = data; -+ struct cdns_mhdp_device *mhdp = data; - u8 msg[2], reg[2], i; - int ret; - -@@ -442,22 +444,23 @@ int cdn_dp_get_edid_block(void *data, u8 - msg[0] = block / 2; - msg[1] = block % 2; - -- ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_GET_EDID, -- sizeof(msg), msg); -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_GET_EDID, sizeof(msg), msg); - if (ret) - continue; - -- ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX, -- DPTX_GET_EDID, -- sizeof(reg) + length); -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, -+ MB_MODULE_ID_DP_TX, -+ DPTX_GET_EDID, -+ sizeof(reg) + length); - if (ret) - continue; - -- ret = cdn_dp_mailbox_read_receive(dp, reg, sizeof(reg)); -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); - if (ret) - continue; - -- ret = cdn_dp_mailbox_read_receive(dp, edid, length); -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, edid, length); - if (ret) - continue; - -@@ -466,13 +469,13 @@ int cdn_dp_get_edid_block(void *data, u8 - } - - if (ret) -- DRM_DEV_ERROR(dp->dev, "get block[%d] edid failed: %d\n", block, -- ret); -+ DRM_DEV_ERROR(mhdp->dev, "get block[%d] edid failed: %d\n", -+ block, ret); - - return ret; - } - --static int cdn_dp_training_start(struct cdn_dp_device *dp) -+static int cdns_mhdp_training_start(struct cdns_mhdp_device *mhdp) - { - unsigned long timeout; - u8 msg, event[2]; -@@ -481,26 +484,28 @@ static int cdn_dp_training_start(struct - msg = LINK_TRAINING_RUN; - - /* start training */ -- ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_TRAINING_CONTROL, -- sizeof(msg), &msg); -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_TRAINING_CONTROL, sizeof(msg), &msg); - if (ret) - goto err_training_start; - - timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS); - while (time_before(jiffies, timeout)) { - msleep(LINK_TRAINING_RETRY_MS); -- ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, -- DPTX_READ_EVENT, 0, NULL); -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_EVENT, 0, NULL); - if (ret) - goto err_training_start; - -- ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX, -- DPTX_READ_EVENT, -- sizeof(event)); -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, -+ MB_MODULE_ID_DP_TX, -+ DPTX_READ_EVENT, -+ sizeof(event)); - if (ret) - goto err_training_start; - -- ret = cdn_dp_mailbox_read_receive(dp, event, sizeof(event)); -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, event, -+ sizeof(event)); - if (ret) - goto err_training_start; - -@@ -511,76 +516,76 @@ static int cdn_dp_training_start(struct - ret = -ETIMEDOUT; - - err_training_start: -- DRM_DEV_ERROR(dp->dev, "training failed: %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "training failed: %d\n", ret); - return ret; - } - --static int cdn_dp_get_training_status(struct cdn_dp_device *dp) -+static int cdns_mhdp_get_training_status(struct cdns_mhdp_device *mhdp) - { - u8 status[10]; - int ret; - -- ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_READ_LINK_STAT, -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, DPTX_READ_LINK_STAT, - 0, NULL); - if (ret) - goto err_get_training_status; - -- ret = cdn_dp_mailbox_validate_receive(dp, MB_MODULE_ID_DP_TX, -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, - DPTX_READ_LINK_STAT, - sizeof(status)); - if (ret) - goto err_get_training_status; - -- ret = cdn_dp_mailbox_read_receive(dp, status, sizeof(status)); -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, status, sizeof(status)); - if (ret) - goto err_get_training_status; - -- dp->link.rate = drm_dp_bw_code_to_link_rate(status[0]); -- dp->link.num_lanes = status[1]; -+ mhdp->link.rate = drm_dp_bw_code_to_link_rate(status[0]); -+ mhdp->link.num_lanes = status[1]; - - err_get_training_status: - if (ret) -- DRM_DEV_ERROR(dp->dev, "get training status failed: %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "get training status failed: %d\n", ret); - return ret; - } - --int cdn_dp_train_link(struct cdn_dp_device *dp) -+int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp) - { - int ret; - -- ret = cdn_dp_training_start(dp); -+ ret = cdns_mhdp_training_start(mhdp); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "Failed to start training %d\n", ret); - return ret; - } - -- ret = cdn_dp_get_training_status(dp); -+ ret = cdns_mhdp_get_training_status(mhdp); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "Failed to get training stat %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "Failed to get training stat %d\n", ret); - return ret; - } - -- DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->link.rate, -- dp->link.num_lanes); -+ DRM_DEV_DEBUG_KMS(mhdp->dev, "rate:0x%x, lanes:%d\n", mhdp->link.rate, -+ mhdp->link.num_lanes); - return ret; - } - --int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active) -+int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active) - { - u8 msg; - int ret; - - msg = !!active; - -- ret = cdn_dp_mailbox_send(dp, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO, -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO, - sizeof(msg), &msg); - if (ret) -- DRM_DEV_ERROR(dp->dev, "set video status failed: %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "set video status failed: %d\n", ret); - - return ret; - } - --static int cdn_dp_get_msa_misc(struct video_info *video, -+static int cdns_mhdp_get_msa_misc(struct video_info *video, - struct drm_display_mode *mode) - { - u32 msa_misc; -@@ -627,10 +632,10 @@ static int cdn_dp_get_msa_misc(struct vi - return msa_misc; - } - --int cdn_dp_config_video(struct cdn_dp_device *dp) -+int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp) - { -- struct video_info *video = &dp->video_info; -- struct drm_display_mode *mode = &dp->mode; -+ struct video_info *video = &mhdp->video_info; -+ struct drm_display_mode *mode = &mhdp->mode; - u64 symbol; - u32 val, link_rate, rem; - u8 bit_per_pix, tu_size_reg = TU_SIZE; -@@ -639,13 +644,13 @@ int cdn_dp_config_video(struct cdn_dp_de - bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ? - (video->color_depth * 2) : (video->color_depth * 3); - -- link_rate = dp->link.rate / 1000; -+ link_rate = mhdp->link.rate / 1000; - -- ret = cdn_dp_reg_write(dp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE); -+ ret = cdns_mhdp_reg_write(mhdp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE); - if (ret) - goto err_config_video; - -- ret = cdn_dp_reg_write(dp, HSYNC2VSYNC_POL_CTRL, 0); -+ ret = cdns_mhdp_reg_write(mhdp, HSYNC2VSYNC_POL_CTRL, 0); - if (ret) - goto err_config_video; - -@@ -659,13 +664,13 @@ int cdn_dp_config_video(struct cdn_dp_de - do { - tu_size_reg += 2; - symbol = tu_size_reg * mode->clock * bit_per_pix; -- do_div(symbol, dp->link.num_lanes * link_rate * 8); -+ do_div(symbol, mhdp->link.num_lanes * link_rate * 8); - rem = do_div(symbol, 1000); - if (tu_size_reg > 64) { - ret = -EINVAL; -- DRM_DEV_ERROR(dp->dev, -+ DRM_DEV_ERROR(mhdp->dev, - "tu error, clk:%d, lanes:%d, rate:%d\n", -- mode->clock, dp->link.num_lanes, -+ mode->clock, mhdp->link.num_lanes, - link_rate); - goto err_config_video; - } -@@ -674,16 +679,16 @@ int cdn_dp_config_video(struct cdn_dp_de - - val = symbol + (tu_size_reg << 8); - val |= TU_CNT_RST_EN; -- ret = cdn_dp_reg_write(dp, DP_FRAMER_TU, val); -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_TU, val); - if (ret) - goto err_config_video; - - /* set the FIFO Buffer size */ - val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate; -- val /= (dp->link.num_lanes * link_rate); -+ val /= (mhdp->link.num_lanes * link_rate); - val = div_u64(8 * (symbol + 1), bit_per_pix) - val; - val += 2; -- ret = cdn_dp_reg_write(dp, DP_VC_TABLE(15), val); -+ ret = cdns_mhdp_reg_write(mhdp, DP_VC_TABLE(15), val); - - switch (video->color_depth) { - case 6: -@@ -704,136 +709,137 @@ int cdn_dp_config_video(struct cdn_dp_de - }; - - val += video->color_fmt << 8; -- ret = cdn_dp_reg_write(dp, DP_FRAMER_PXL_REPR, val); -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_PXL_REPR, val); - if (ret) - goto err_config_video; - - val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0; - val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0; -- ret = cdn_dp_reg_write(dp, DP_FRAMER_SP, val); -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_SP, val); - if (ret) - goto err_config_video; - - val = (mode->hsync_start - mode->hdisplay) << 16; - val |= mode->htotal - mode->hsync_end; -- ret = cdn_dp_reg_write(dp, DP_FRONT_BACK_PORCH, val); -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRONT_BACK_PORCH, val); - if (ret) - goto err_config_video; - - val = mode->hdisplay * bit_per_pix / 8; -- ret = cdn_dp_reg_write(dp, DP_BYTE_COUNT, val); -+ ret = cdns_mhdp_reg_write(mhdp, DP_BYTE_COUNT, val); - if (ret) - goto err_config_video; - - val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16); -- ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_0, val); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_HORIZONTAL_0, val); - if (ret) - goto err_config_video; - - val = mode->hsync_end - mode->hsync_start; - val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15); -- ret = cdn_dp_reg_write(dp, MSA_HORIZONTAL_1, val); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_HORIZONTAL_1, val); - if (ret) - goto err_config_video; - - val = mode->vtotal; - val |= (mode->vtotal - mode->vsync_start) << 16; -- ret = cdn_dp_reg_write(dp, MSA_VERTICAL_0, val); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_VERTICAL_0, val); - if (ret) - goto err_config_video; - - val = mode->vsync_end - mode->vsync_start; - val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15); -- ret = cdn_dp_reg_write(dp, MSA_VERTICAL_1, val); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_VERTICAL_1, val); - if (ret) - goto err_config_video; - -- val = cdn_dp_get_msa_misc(video, mode); -- ret = cdn_dp_reg_write(dp, MSA_MISC, val); -+ val = cdns_mhdp_get_msa_misc(video, mode); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_MISC, val); - if (ret) - goto err_config_video; - -- ret = cdn_dp_reg_write(dp, STREAM_CONFIG, 1); -+ ret = cdns_mhdp_reg_write(mhdp, STREAM_CONFIG, 1); - if (ret) - goto err_config_video; - - val = mode->hsync_end - mode->hsync_start; - val |= mode->hdisplay << 16; -- ret = cdn_dp_reg_write(dp, DP_HORIZONTAL, val); -+ ret = cdns_mhdp_reg_write(mhdp, DP_HORIZONTAL, val); - if (ret) - goto err_config_video; - - val = mode->vdisplay; - val |= (mode->vtotal - mode->vsync_start) << 16; -- ret = cdn_dp_reg_write(dp, DP_VERTICAL_0, val); -+ ret = cdns_mhdp_reg_write(mhdp, DP_VERTICAL_0, val); - if (ret) - goto err_config_video; - - val = mode->vtotal; -- ret = cdn_dp_reg_write(dp, DP_VERTICAL_1, val); -+ ret = cdns_mhdp_reg_write(mhdp, DP_VERTICAL_1, val); - if (ret) - goto err_config_video; - -- ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 2, 1, 0); -+ ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 2, 1, 0); - - err_config_video: - if (ret) -- DRM_DEV_ERROR(dp->dev, "config video failed: %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "config video failed: %d\n", ret); - return ret; - } - --int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio) -+int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) - { - int ret; - -- ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, 0); -+ ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, 0); - if (ret) { -- DRM_DEV_ERROR(dp->dev, "audio stop failed: %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "audio stop failed: %d\n", ret); - return ret; - } - -- writel(0, dp->regs + SPDIF_CTRL_ADDR); -+ writel(0, mhdp->regs + SPDIF_CTRL_ADDR); - - /* clearn the audio config and reset */ -- writel(0, dp->regs + AUDIO_SRC_CNTL); -- writel(0, dp->regs + AUDIO_SRC_CNFG); -- writel(AUDIO_SW_RST, dp->regs + AUDIO_SRC_CNTL); -- writel(0, dp->regs + AUDIO_SRC_CNTL); -+ writel(0, mhdp->regs + AUDIO_SRC_CNTL); -+ writel(0, mhdp->regs + AUDIO_SRC_CNFG); -+ writel(AUDIO_SW_RST, mhdp->regs + AUDIO_SRC_CNTL); -+ writel(0, mhdp->regs + AUDIO_SRC_CNTL); - - /* reset smpl2pckt component */ -- writel(0, dp->regs + SMPL2PKT_CNTL); -- writel(AUDIO_SW_RST, dp->regs + SMPL2PKT_CNTL); -- writel(0, dp->regs + SMPL2PKT_CNTL); -+ writel(0, mhdp->regs + SMPL2PKT_CNTL); -+ writel(AUDIO_SW_RST, mhdp->regs + SMPL2PKT_CNTL); -+ writel(0, mhdp->regs + SMPL2PKT_CNTL); - - /* reset FIFO */ -- writel(AUDIO_SW_RST, dp->regs + FIFO_CNTL); -- writel(0, dp->regs + FIFO_CNTL); -+ writel(AUDIO_SW_RST, mhdp->regs + FIFO_CNTL); -+ writel(0, mhdp->regs + FIFO_CNTL); - - if (audio->format == AFMT_SPDIF) -- clk_disable_unprepare(dp->spdif_clk); -+ clk_disable_unprepare(mhdp->spdif_clk); - - return 0; - } - --int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable) -+int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable) - { - int ret; - -- ret = cdn_dp_reg_write_bit(dp, DP_VB_ID, 4, 1, enable); -+ ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 4, 1, enable); - if (ret) -- DRM_DEV_ERROR(dp->dev, "audio mute failed: %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "audio mute failed: %d\n", ret); - - return ret; - } - --static void cdn_dp_audio_config_i2s(struct cdn_dp_device *dp, -- struct audio_info *audio) -+static void cdns_mhdp_audio_config_i2s(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) - { - int sub_pckt_num = 1, i2s_port_en_val = 0xf, i; - u32 val; - - if (audio->channels == 2) { -- if (dp->link.num_lanes == 1) -+ if (mhdp->link.num_lanes == 1) - sub_pckt_num = 2; - else - sub_pckt_num = 4; -@@ -843,15 +849,15 @@ static void cdn_dp_audio_config_i2s(stru - i2s_port_en_val = 3; - } - -- writel(0x0, dp->regs + SPDIF_CTRL_ADDR); -+ writel(0x0, mhdp->regs + SPDIF_CTRL_ADDR); - -- writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL); -+ writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); - - val = MAX_NUM_CH(audio->channels); - val |= NUM_OF_I2S_PORTS(audio->channels); - val |= AUDIO_TYPE_LPCM; - val |= CFG_SUB_PCKT_NUM(sub_pckt_num); -- writel(val, dp->regs + SMPL2PKT_CNFG); -+ writel(val, mhdp->regs + SMPL2PKT_CNFG); - - if (audio->sample_width == 16) - val = 0; -@@ -863,7 +869,7 @@ static void cdn_dp_audio_config_i2s(stru - val |= AUDIO_CH_NUM(audio->channels); - val |= I2S_DEC_PORT_EN(i2s_port_en_val); - val |= TRANS_SMPL_WIDTH_32; -- writel(val, dp->regs + AUDIO_SRC_CNFG); -+ writel(val, mhdp->regs + AUDIO_SRC_CNFG); - - for (i = 0; i < (audio->channels + 1) / 2; i++) { - if (audio->sample_width == 16) -@@ -872,7 +878,7 @@ static void cdn_dp_audio_config_i2s(stru - val = (0x0b << 8) | (0x0b << 20); - - val |= ((2 * i) << 4) | ((2 * i + 1) << 16); -- writel(val, dp->regs + STTS_BIT_CH(i)); -+ writel(val, mhdp->regs + STTS_BIT_CH(i)); - } - - switch (audio->sample_rate) { -@@ -906,56 +912,57 @@ static void cdn_dp_audio_config_i2s(stru - break; - } - val |= 4; -- writel(val, dp->regs + COM_CH_STTS_BITS); -+ writel(val, mhdp->regs + COM_CH_STTS_BITS); - -- writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL); -- writel(I2S_DEC_START, dp->regs + AUDIO_SRC_CNTL); -+ writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); -+ writel(I2S_DEC_START, mhdp->regs + AUDIO_SRC_CNTL); - } - --static void cdn_dp_audio_config_spdif(struct cdn_dp_device *dp) -+static void cdns_mhdp_audio_config_spdif(struct cdns_mhdp_device *mhdp) - { - u32 val; - -- writel(SYNC_WR_TO_CH_ZERO, dp->regs + FIFO_CNTL); -+ writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); - - val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4); -- writel(val, dp->regs + SMPL2PKT_CNFG); -- writel(SMPL2PKT_EN, dp->regs + SMPL2PKT_CNTL); -+ writel(val, mhdp->regs + SMPL2PKT_CNFG); -+ writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); - - val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS; -- writel(val, dp->regs + SPDIF_CTRL_ADDR); -+ writel(val, mhdp->regs + SPDIF_CTRL_ADDR); - -- clk_prepare_enable(dp->spdif_clk); -- clk_set_rate(dp->spdif_clk, CDN_DP_SPDIF_CLK); -+ clk_prepare_enable(mhdp->spdif_clk); -+ clk_set_rate(mhdp->spdif_clk, CDNS_DP_SPDIF_CLK); - } - --int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio) -+int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) - { - int ret; - - /* reset the spdif clk before config */ - if (audio->format == AFMT_SPDIF) { -- reset_control_assert(dp->spdif_rst); -- reset_control_deassert(dp->spdif_rst); -+ reset_control_assert(mhdp->spdif_rst); -+ reset_control_deassert(mhdp->spdif_rst); - } - -- ret = cdn_dp_reg_write(dp, CM_LANE_CTRL, LANE_REF_CYC); -+ ret = cdns_mhdp_reg_write(mhdp, CM_LANE_CTRL, LANE_REF_CYC); - if (ret) - goto err_audio_config; - -- ret = cdn_dp_reg_write(dp, CM_CTRL, 0); -+ ret = cdns_mhdp_reg_write(mhdp, CM_CTRL, 0); - if (ret) - goto err_audio_config; - - if (audio->format == AFMT_I2S) -- cdn_dp_audio_config_i2s(dp, audio); -+ cdns_mhdp_audio_config_i2s(mhdp, audio); - else if (audio->format == AFMT_SPDIF) -- cdn_dp_audio_config_spdif(dp); -+ cdns_mhdp_audio_config_spdif(mhdp); - -- ret = cdn_dp_reg_write(dp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN); -+ ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN); - - err_audio_config: - if (ret) -- DRM_DEV_ERROR(dp->dev, "audio config failed: %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "audio config failed: %d\n", ret); - return ret; - } ---- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h -+++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.h -@@ -387,7 +387,7 @@ - #define HDCP_TX_IS_RECEIVER_ID_VALID_EVENT BIT(7) - - #define TU_SIZE 30 --#define CDN_DP_MAX_LINK_RATE DP_LINK_BW_5_4 -+#define CDNS_DP_MAX_LINK_RATE DP_LINK_BW_5_4 - - /* audio */ - #define AUDIO_PACK_EN BIT(8) -@@ -451,24 +451,96 @@ enum vic_bt_type { - BT_709 = 0x1, - }; - --void cdn_dp_clock_reset(struct cdn_dp_device *dp); -+enum audio_format { -+ AFMT_I2S = 0, -+ AFMT_SPDIF = 1, -+ AFMT_UNUSED, -+}; -+ -+struct audio_info { -+ enum audio_format format; -+ int sample_rate; -+ int channels; -+ int sample_width; -+}; -+ -+enum vic_pxl_encoding_format { -+ PXL_RGB = 0x1, -+ YCBCR_4_4_4 = 0x2, -+ YCBCR_4_2_2 = 0x4, -+ YCBCR_4_2_0 = 0x8, -+ Y_ONLY = 0x10, -+}; -+ -+struct video_info { -+ bool h_sync_polarity; -+ bool v_sync_polarity; -+ bool interlaced; -+ int color_depth; -+ enum vic_pxl_encoding_format color_fmt; -+}; -+ -+struct cdns_mhdp_host { -+ unsigned int link_rate; -+ u8 lanes_cnt; -+ u8 volt_swing; -+ u8 pre_emphasis; -+ u8 pattern_supp; -+ u8 fast_link; -+ u8 lane_mapping; -+ u8 enhanced; -+}; -+ -+struct cdns_mhdp_sink { -+ unsigned int link_rate; -+ u8 lanes_cnt; -+ u8 pattern_supp; -+ u8 fast_link; -+ u8 enhanced; -+}; -+ -+struct cdns_mhdp_device { -+ void __iomem *regs; -+ -+ struct device *dev; -+ -+ struct drm_dp_link link; -+ struct drm_connector connector; -+ struct clk *spdif_clk; -+ struct reset_control *spdif_rst; -+ -+ struct drm_dp_aux aux; -+ struct cdns_mhdp_host host; -+ struct cdns_mhdp_sink sink; -+ struct drm_bridge bridge; -+ struct phy *phy; -+ void __iomem *dbg_regs; -+ -+ struct video_info video_info; -+ struct drm_display_mode mode; -+ unsigned int fw_version; -+}; - --void cdn_dp_set_fw_clk(struct cdn_dp_device *dp, unsigned long clk); --int cdn_dp_load_firmware(struct cdn_dp_device *dp, const u32 *i_mem, -- u32 i_size, const u32 *d_mem, u32 d_size); --int cdn_dp_set_firmware_active(struct cdn_dp_device *dp, bool enable); --int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip); --int cdn_dp_event_config(struct cdn_dp_device *dp); --u32 cdn_dp_get_event(struct cdn_dp_device *dp); --int cdn_dp_get_hpd_status(struct cdn_dp_device *dp); --int cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr, u8 value); --int cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr, u8 *data, u16 len); --int cdn_dp_get_edid_block(void *dp, u8 *edid, -- unsigned int block, size_t length); --int cdn_dp_train_link(struct cdn_dp_device *dp); --int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active); --int cdn_dp_config_video(struct cdn_dp_device *dp); --int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio); --int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable); --int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio); -+void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp); -+void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk); -+int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, -+ u32 i_size, const u32 *d_mem, u32 d_size); -+int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable); -+int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip); -+int cdns_mhdp_event_config(struct cdns_mhdp_device *mhdp); -+u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value); -+int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp, -+ u32 addr, u8 *data, u16 len); -+int cdns_mhdp_get_edid_block(void *mhdp, u8 *edid, -+ unsigned int block, size_t length); -+int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active); -+int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio); -+int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable); -+int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio); - #endif /* _CDN_DP_REG_H */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0003-drm-bridge-add-Cadence-MHDP-HDMI-DP-API.patch b/target/linux/layerscape/patches-5.4/805-display-0003-drm-bridge-add-Cadence-MHDP-HDMI-DP-API.patch deleted file mode 100644 index 14089a7b36..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0003-drm-bridge-add-Cadence-MHDP-HDMI-DP-API.patch +++ /dev/null @@ -1,4241 +0,0 @@ -From d94a1a8c31cab273b3409c9c380a8089a794f592 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Wed, 10 Jul 2019 14:22:12 +0800 -Subject: [PATCH] drm: bridge: add Cadence MHDP HDMI/DP API - -Changes made in the low level driver (cdn-dp-reg.*): -- moved it to from drivers/gpu/drm/rockchip to - drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c and - include/drm/bridge/cdns-mhdp-common.h -- functions for sending/receiving commands are now public -- added functions for reading registers and link training adjustment - -Changes made in RK's driver (cdn-dp-core.*): -- Moved audio_info and audio_pdev fields from cdn_dp_device to - cdns_mhdp_device structure. - -Signed-off-by: Quentin Schulz -Signed-off-by: Piotr Sroka -Signed-off-by: Damian Kos -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/Kconfig | 2 + - drivers/gpu/drm/bridge/Makefile | 1 + - drivers/gpu/drm/bridge/cadence/Kconfig | 7 + - drivers/gpu/drm/bridge/cadence/Makefile | 3 + - drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 1165 +++++++++++++++++++++ - drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c | 296 ++++++ - drivers/gpu/drm/bridge/cadence/cdns-mhdp.h | 209 ++++ - drivers/gpu/drm/rockchip/Kconfig | 4 +- - drivers/gpu/drm/rockchip/Makefile | 2 +- - drivers/gpu/drm/rockchip/cdn-dp-core.c | 48 +- - drivers/gpu/drm/rockchip/cdn-dp-core.h | 5 +- - drivers/gpu/drm/rockchip/cdn-dp-reg.c | 968 ----------------- - drivers/gpu/drm/rockchip/cdn-dp-reg.h | 546 ---------- - include/drm/bridge/cdns-mhdp-cbs.h | 29 + - include/drm/bridge/cdns-mhdp-common.h | 704 +++++++++++++ - 15 files changed, 2446 insertions(+), 1543 deletions(-) - create mode 100644 drivers/gpu/drm/bridge/cadence/Kconfig - create mode 100644 drivers/gpu/drm/bridge/cadence/Makefile - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp.h - delete mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.c - delete mode 100644 drivers/gpu/drm/rockchip/cdn-dp-reg.h - create mode 100644 include/drm/bridge/cdns-mhdp-cbs.h - create mode 100644 include/drm/bridge/cdns-mhdp-common.h - ---- a/drivers/gpu/drm/bridge/Kconfig -+++ b/drivers/gpu/drm/bridge/Kconfig -@@ -154,6 +154,8 @@ source "drivers/gpu/drm/bridge/analogix/ - - source "drivers/gpu/drm/bridge/adv7511/Kconfig" - -+source "drivers/gpu/drm/bridge/cadence/Kconfig" -+ - source "drivers/gpu/drm/bridge/synopsys/Kconfig" - - endmenu ---- a/drivers/gpu/drm/bridge/Makefile -+++ b/drivers/gpu/drm/bridge/Makefile -@@ -16,4 +16,5 @@ obj-$(CONFIG_DRM_ANALOGIX_DP) += analogi - obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ - obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o - obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o -+obj-y += cadence/ - obj-y += synopsys/ ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/Kconfig -@@ -0,0 +1,7 @@ -+config DRM_CDNS_MHDP -+ tristate "Cadence MHDP COMMON API driver" -+ select DRM_KMS_HELPER -+ select DRM_PANEL_BRIDGE -+ depends on OF -+ help -+ Support Cadence MHDP API library. ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/Makefile -@@ -0,0 +1,3 @@ -+#ccflags-y := -Iinclude/drm -+ -+obj-$(CONFIG_DRM_CDNS_MHDP) += cdns-mhdp-common.o cdns-mhdp-hdmi.o ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -@@ -0,0 +1,1165 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd -+ * Author: Chris Zhong -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+ -+#define CDNS_DP_SPDIF_CLK 200000000 -+#define FW_ALIVE_TIMEOUT_US 1000000 -+#define MAILBOX_RETRY_US 1000 -+#define MAILBOX_TIMEOUT_US 5000000 -+#define LINK_TRAINING_RETRY_MS 20 -+#define LINK_TRAINING_TIMEOUT_MS 500 -+ -+static inline u32 get_unaligned_be24(const void *p) -+{ -+ const u8 *_p = p; -+ -+ return _p[0] << 16 | _p[1] << 8 | _p[2]; -+} -+ -+static inline void put_unaligned_be24(u32 val, void *p) -+{ -+ u8 *_p = p; -+ -+ _p[0] = val >> 16; -+ _p[1] = val >> 8; -+ _p[2] = val; -+} -+ -+void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk) -+{ -+ writel(clk / 1000000, mhdp->regs + SW_CLK_H); -+} -+EXPORT_SYMBOL(cdns_mhdp_set_fw_clk); -+ -+void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val; -+ -+ val = DPTX_FRMR_DATA_CLK_RSTN_EN | -+ DPTX_FRMR_DATA_CLK_EN | -+ DPTX_PHY_DATA_RSTN_EN | -+ DPTX_PHY_DATA_CLK_EN | -+ DPTX_PHY_CHAR_RSTN_EN | -+ DPTX_PHY_CHAR_CLK_EN | -+ SOURCE_AUX_SYS_CLK_RSTN_EN | -+ SOURCE_AUX_SYS_CLK_EN | -+ DPTX_SYS_CLK_RSTN_EN | -+ DPTX_SYS_CLK_EN | -+ CFG_DPTX_VIF_CLK_RSTN_EN | -+ CFG_DPTX_VIF_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_DPTX_CAR); -+ -+ val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_PHY_CAR); -+ -+ val = SOURCE_PKT_SYS_RSTN_EN | -+ SOURCE_PKT_SYS_CLK_EN | -+ SOURCE_PKT_DATA_RSTN_EN | -+ SOURCE_PKT_DATA_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_PKT_CAR); -+ -+ val = SPDIF_CDR_CLK_RSTN_EN | -+ SPDIF_CDR_CLK_EN | -+ SOURCE_AIF_SYS_RSTN_EN | -+ SOURCE_AIF_SYS_CLK_EN | -+ SOURCE_AIF_CLK_RSTN_EN | -+ SOURCE_AIF_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_AIF_CAR); -+ -+ val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN | -+ SOURCE_CIPHER_SYS_CLK_EN | -+ SOURCE_CIPHER_CHAR_CLK_RSTN_EN | -+ SOURCE_CIPHER_CHAR_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_CIPHER_CAR); -+ -+ val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN | -+ SOURCE_CRYPTO_SYS_CLK_EN; -+ writel(val, mhdp->regs + SOURCE_CRYPTO_CAR); -+ -+ /* enable Mailbox and PIF interrupt */ -+ writel(0, mhdp->regs + APB_INT_MASK); -+} -+EXPORT_SYMBOL(cdns_mhdp_clock_reset); -+ -+int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp) -+{ -+ int val, ret; -+ -+ ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_EMPTY_ADDR, -+ val, !val, MAILBOX_RETRY_US, -+ MAILBOX_TIMEOUT_US); -+ if (ret < 0) -+ return ret; -+ -+ return readl(mhdp->regs + MAILBOX0_RD_DATA) & 0xff; -+} -+EXPORT_SYMBOL(cdns_mhdp_mailbox_read); -+ -+static int cdp_dp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val) -+{ -+ int ret, full; -+ -+ ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_FULL_ADDR, -+ full, !full, MAILBOX_RETRY_US, -+ MAILBOX_TIMEOUT_US); -+ if (ret < 0) -+ return ret; -+ -+ writel(val, mhdp->regs + MAILBOX0_WR_DATA); -+ -+ return 0; -+} -+ -+int cdns_mhdp_mailbox_validate_receive(struct cdns_mhdp_device *mhdp, -+ u8 module_id, u8 opcode, -+ u16 req_size) -+{ -+ u32 mbox_size, i; -+ u8 header[4]; -+ int ret; -+ -+ /* read the header of the message */ -+ for (i = 0; i < 4; i++) { -+ ret = cdns_mhdp_mailbox_read(mhdp); -+ if (ret < 0) -+ return ret; -+ -+ header[i] = ret; -+ } -+ -+ mbox_size = get_unaligned_be16(header + 2); -+ -+ if (opcode != header[0] || module_id != header[1] || -+ req_size != mbox_size) { -+ /* -+ * If the message in mailbox is not what we want, we need to -+ * clear the mailbox by reading its contents. -+ */ -+ for (i = 0; i < mbox_size; i++) -+ if (cdns_mhdp_mailbox_read(mhdp) < 0) -+ break; -+ -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(cdns_mhdp_mailbox_validate_receive); -+ -+int cdns_mhdp_mailbox_read_receive(struct cdns_mhdp_device *mhdp, -+ u8 *buff, u16 buff_size) -+{ -+ u32 i; -+ int ret; -+ -+ for (i = 0; i < buff_size; i++) { -+ ret = cdns_mhdp_mailbox_read(mhdp); -+ if (ret < 0) -+ return ret; -+ -+ buff[i] = ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(cdns_mhdp_mailbox_read_receive); -+ -+int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id, -+ u8 opcode, u16 size, u8 *message) -+{ -+ u8 header[4]; -+ int ret, i; -+ -+ header[0] = opcode; -+ header[1] = module_id; -+ put_unaligned_be16(size, header + 2); -+ -+ for (i = 0; i < 4; i++) { -+ ret = cdp_dp_mailbox_write(mhdp, header[i]); -+ if (ret) -+ return ret; -+ } -+ -+ for (i = 0; i < size; i++) { -+ ret = cdp_dp_mailbox_write(mhdp, message[i]); -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL(cdns_mhdp_mailbox_send); -+ -+int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr) -+{ -+ u8 msg[4], resp[8]; -+ u32 val; -+ int ret; -+ -+ if (addr == 0) { -+ ret = -EINVAL; -+ goto err_reg_read; -+ } -+ -+ put_unaligned_be32(addr, msg); -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL, -+ GENERAL_READ_REGISTER, -+ sizeof(msg), msg); -+ if (ret) -+ goto err_reg_read; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_GENERAL, -+ GENERAL_READ_REGISTER, -+ sizeof(resp)); -+ if (ret) -+ goto err_reg_read; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, resp, sizeof(resp)); -+ if (ret) -+ goto err_reg_read; -+ -+ /* Returned address value should be the same as requested */ -+ if (memcmp(msg, resp, sizeof(msg))) { -+ ret = -EINVAL; -+ goto err_reg_read; -+ } -+ -+ val = get_unaligned_be32(resp + 4); -+ -+ return val; -+err_reg_read: -+ DRM_DEV_ERROR(mhdp->dev, "Failed to read register.\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_reg_read); -+ -+int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u32 addr, u32 val) -+{ -+ u8 msg[8]; -+ -+ put_unaligned_be32(addr, msg); -+ put_unaligned_be32(val, msg + 4); -+ -+ return cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL, -+ GENERAL_WRITE_REGISTER, sizeof(msg), msg); -+} -+EXPORT_SYMBOL(cdns_mhdp_reg_write); -+ -+int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr, -+ u8 start_bit, u8 bits_no, u32 val) -+{ -+ u8 field[8]; -+ -+ put_unaligned_be16(addr, field); -+ field[2] = start_bit; -+ field[3] = bits_no; -+ put_unaligned_be32(val, field + 4); -+ -+ return cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_FIELD, sizeof(field), field); -+} -+EXPORT_SYMBOL(cdns_mhdp_reg_write_bit); -+ -+int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp, -+ u32 addr, u8 *data, u16 len) -+{ -+ u8 msg[5], reg[5]; -+ int ret; -+ -+ put_unaligned_be16(len, msg); -+ put_unaligned_be24(addr, msg + 2); -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_DPCD, sizeof(msg), msg); -+ if (ret) -+ goto err_dpcd_read; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_DPCD, -+ sizeof(reg) + len); -+ if (ret) -+ goto err_dpcd_read; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ goto err_dpcd_read; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, data, len); -+ -+err_dpcd_read: -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_dpcd_read); -+ -+int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value) -+{ -+ u8 msg[6], reg[5]; -+ int ret; -+ -+ put_unaligned_be16(1, msg); -+ put_unaligned_be24(addr, msg + 2); -+ msg[5] = value; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_DPCD, sizeof(msg), msg); -+ if (ret) -+ goto err_dpcd_write; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_WRITE_DPCD, sizeof(reg)); -+ if (ret) -+ goto err_dpcd_write; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ goto err_dpcd_write; -+ -+ if (addr != get_unaligned_be24(reg + 2)) -+ ret = -EINVAL; -+ -+err_dpcd_write: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "dpcd write failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_dpcd_write); -+ -+int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, -+ u32 i_size, const u32 *d_mem, u32 d_size) -+{ -+ u32 reg; -+ int i, ret; -+ -+ /* reset ucpu before load firmware*/ -+ writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET, -+ mhdp->regs + APB_CTRL); -+ -+ for (i = 0; i < i_size; i += 4) -+ writel(*i_mem++, mhdp->regs + ADDR_IMEM + i); -+ -+ for (i = 0; i < d_size; i += 4) -+ writel(*d_mem++, mhdp->regs + ADDR_DMEM + i); -+ -+ /* un-reset ucpu */ -+ writel(0, mhdp->regs + APB_CTRL); -+ -+ /* check the keep alive register to make sure fw working */ -+ ret = readx_poll_timeout(readl, mhdp->regs + KEEP_ALIVE, -+ reg, reg, 2000, FW_ALIVE_TIMEOUT_US); -+ if (ret < 0) { -+ DRM_DEV_ERROR(mhdp->dev, "failed to loaded the FW reg = %x\n", -+ reg); -+ return -EINVAL; -+ } -+ -+ reg = readl(mhdp->regs + VER_L) & 0xff; -+ mhdp->fw_version = reg; -+ reg = readl(mhdp->regs + VER_H) & 0xff; -+ mhdp->fw_version |= reg << 8; -+ reg = readl(mhdp->regs + VER_LIB_L_ADDR) & 0xff; -+ mhdp->fw_version |= reg << 16; -+ reg = readl(mhdp->regs + VER_LIB_H_ADDR) & 0xff; -+ mhdp->fw_version |= reg << 24; -+ -+ DRM_DEV_DEBUG(mhdp->dev, "firmware version: %x\n", mhdp->fw_version); -+ -+ return 0; -+} -+EXPORT_SYMBOL(cdns_mhdp_load_firmware); -+ -+int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable) -+{ -+ u8 msg[5]; -+ int ret, i; -+ -+ msg[0] = GENERAL_MAIN_CONTROL; -+ msg[1] = MB_MODULE_ID_GENERAL; -+ msg[2] = 0; -+ msg[3] = 1; -+ msg[4] = enable ? FW_ACTIVE : FW_STANDBY; -+ -+ for (i = 0; i < sizeof(msg); i++) { -+ ret = cdp_dp_mailbox_write(mhdp, msg[i]); -+ if (ret) -+ goto err_set_firmware_active; -+ } -+ -+ /* read the firmware state */ -+ for (i = 0; i < sizeof(msg); i++) { -+ ret = cdns_mhdp_mailbox_read(mhdp); -+ if (ret < 0) -+ goto err_set_firmware_active; -+ -+ msg[i] = ret; -+ } -+ -+ ret = 0; -+ -+err_set_firmware_active: -+ if (ret < 0) -+ DRM_DEV_ERROR(mhdp->dev, "set firmware active failed\n"); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_set_firmware_active); -+ -+int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip) -+{ -+ u8 msg[8]; -+ int ret; -+ -+ msg[0] = CDNS_DP_MAX_LINK_RATE; -+ msg[1] = lanes | SCRAMBLER_EN; -+ msg[2] = VOLTAGE_LEVEL_2; -+ msg[3] = PRE_EMPHASIS_LEVEL_3; -+ msg[4] = PTS1 | PTS2 | PTS3 | PTS4; -+ msg[5] = FAST_LT_NOT_SUPPORT; -+ msg[6] = flip ? LANE_MAPPING_FLIPPED : LANE_MAPPING_NORMAL; -+ msg[7] = ENHANCED; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_SET_HOST_CAPABILITIES, -+ sizeof(msg), msg); -+ if (ret) -+ goto err_set_host_cap; -+ -+/* TODO Sandor */ -+// ret = cdns_mhdp_reg_write(mhdp, DP_AUX_SWAP_INVERSION_CONTROL, -+// AUX_HOST_INVERT); -+ -+err_set_host_cap: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "set host cap failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_set_host_cap); -+ -+int cdns_mhdp_event_config(struct cdns_mhdp_device *mhdp) -+{ -+ u8 msg[5]; -+ int ret; -+ -+ memset(msg, 0, sizeof(msg)); -+ -+ msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_ENABLE_EVENT, sizeof(msg), msg); -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "set event config failed: %d\n", ret); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_event_config); -+ -+u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp) -+{ -+ return readl(mhdp->regs + SW_EVENTS0); -+} -+EXPORT_SYMBOL(cdns_mhdp_get_event); -+ -+int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp) -+{ -+ u8 status; -+ int ret; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_HPD_STATE, 0, NULL); -+ if (ret) -+ goto err_get_hpd; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_HPD_STATE, -+ sizeof(status)); -+ if (ret) -+ goto err_get_hpd; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, &status, sizeof(status)); -+ if (ret) -+ goto err_get_hpd; -+ -+ return status; -+ -+err_get_hpd: -+ DRM_DEV_ERROR(mhdp->dev, "get hpd status failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_get_hpd_status); -+ -+int cdns_mhdp_get_edid_block(void *data, u8 *edid, -+ unsigned int block, size_t length) -+{ -+ struct cdns_mhdp_device *mhdp = data; -+ u8 msg[2], reg[2], i; -+ int ret; -+ -+ for (i = 0; i < 4; i++) { -+ msg[0] = block / 2; -+ msg[1] = block % 2; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_GET_EDID, sizeof(msg), msg); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, -+ MB_MODULE_ID_DP_TX, -+ DPTX_GET_EDID, -+ sizeof(reg) + length); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, edid, length); -+ if (ret) -+ continue; -+ -+ if (reg[0] == length && reg[1] == block / 2) -+ break; -+ } -+ -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "get block[%d] edid failed: %d\n", -+ block, ret); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_get_edid_block); -+ -+static int cdns_mhdp_training_start(struct cdns_mhdp_device *mhdp) -+{ -+ unsigned long timeout; -+ u8 msg, event[2]; -+ int ret; -+ -+ msg = LINK_TRAINING_RUN; -+ -+ /* start training */ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_TRAINING_CONTROL, sizeof(msg), &msg); -+ if (ret) -+ goto err_training_start; -+ -+ timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS); -+ while (time_before(jiffies, timeout)) { -+ msleep(LINK_TRAINING_RETRY_MS); -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_EVENT, 0, NULL); -+ if (ret) -+ goto err_training_start; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, -+ MB_MODULE_ID_DP_TX, -+ DPTX_READ_EVENT, -+ sizeof(event)); -+ if (ret) -+ goto err_training_start; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, event, -+ sizeof(event)); -+ if (ret) -+ goto err_training_start; -+ -+ if (event[1] & EQ_PHASE_FINISHED) -+ return 0; -+ } -+ -+ ret = -ETIMEDOUT; -+ -+err_training_start: -+ DRM_DEV_ERROR(mhdp->dev, "training failed: %d\n", ret); -+ return ret; -+} -+ -+static int cdns_mhdp_get_training_status(struct cdns_mhdp_device *mhdp) -+{ -+ u8 status[10]; -+ int ret; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_LINK_STAT, 0, NULL); -+ if (ret) -+ goto err_get_training_status; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_LINK_STAT, -+ sizeof(status)); -+ if (ret) -+ goto err_get_training_status; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, status, sizeof(status)); -+ if (ret) -+ goto err_get_training_status; -+ -+ mhdp->dp.link.rate = drm_dp_bw_code_to_link_rate(status[0]); -+ mhdp->dp.link.num_lanes = status[1]; -+ -+err_get_training_status: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "get training status failed: %d\n", -+ ret); -+ return ret; -+} -+ -+int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp) -+{ -+ int ret; -+ -+ ret = cdns_mhdp_training_start(mhdp); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "Failed to start training %d\n", -+ ret); -+ return ret; -+ } -+ -+ ret = cdns_mhdp_get_training_status(mhdp); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "Failed to get training stat %d\n", -+ ret); -+ return ret; -+ } -+ -+ DRM_DEV_DEBUG_KMS(mhdp->dev, "rate:0x%x, lanes:%d\n", mhdp->dp.link.rate, -+ mhdp->dp.link.num_lanes); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_train_link); -+ -+int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active) -+{ -+ u8 msg; -+ int ret; -+ -+ msg = !!active; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_SET_VIDEO, sizeof(msg), &msg); -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "set video status failed: %d\n", ret); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_set_video_status); -+ -+static int cdns_mhdp_get_msa_misc(struct video_info *video, -+ struct drm_display_mode *mode) -+{ -+ u32 msa_misc; -+ u8 val[2] = {0}; -+ -+ switch (video->color_fmt) { -+ case PXL_RGB: -+ case Y_ONLY: -+ val[0] = 0; -+ break; -+ /* set YUV default color space conversion to BT601 */ -+ case YCBCR_4_4_4: -+ val[0] = 6 + BT_601 * 8; -+ break; -+ case YCBCR_4_2_2: -+ val[0] = 5 + BT_601 * 8; -+ break; -+ case YCBCR_4_2_0: -+ val[0] = 5; -+ break; -+ }; -+ -+ switch (video->color_depth) { -+ case 6: -+ val[1] = 0; -+ break; -+ case 8: -+ val[1] = 1; -+ break; -+ case 10: -+ val[1] = 2; -+ break; -+ case 12: -+ val[1] = 3; -+ break; -+ case 16: -+ val[1] = 4; -+ break; -+ }; -+ -+ msa_misc = 2 * val[0] + 32 * val[1] + -+ ((video->color_fmt == Y_ONLY) ? (1 << 14) : 0); -+ -+ return msa_misc; -+} -+ -+int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp) -+{ -+ struct video_info *video = &mhdp->video_info; -+ struct drm_display_mode *mode = &mhdp->mode; -+ u64 symbol; -+ u32 val, link_rate, rem; -+ u8 bit_per_pix, tu_size_reg = TU_SIZE; -+ int ret; -+ -+ bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ? -+ (video->color_depth * 2) : (video->color_depth * 3); -+ -+ link_rate = mhdp->dp.link.rate / 1000; -+ -+ ret = cdns_mhdp_reg_write(mhdp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE); -+ if (ret) -+ goto err_config_video; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HSYNC2VSYNC_POL_CTRL, 0); -+ if (ret) -+ goto err_config_video; -+ -+ /* -+ * get a best tu_size and valid symbol: -+ * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32 -+ * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes) -+ * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set -+ * TU += 2 and repeat 2nd step. -+ */ -+ do { -+ tu_size_reg += 2; -+ symbol = tu_size_reg * mode->clock * bit_per_pix; -+ do_div(symbol, mhdp->dp.link.num_lanes * link_rate * 8); -+ rem = do_div(symbol, 1000); -+ if (tu_size_reg > 64) { -+ ret = -EINVAL; -+ DRM_DEV_ERROR(mhdp->dev, -+ "tu error, clk:%d, lanes:%d, rate:%d\n", -+ mode->clock, mhdp->dp.link.num_lanes, -+ link_rate); -+ goto err_config_video; -+ } -+ } while ((symbol <= 1) || (tu_size_reg - symbol < 4) || -+ (rem > 850) || (rem < 100)); -+ -+ val = symbol + (tu_size_reg << 8); -+ val |= TU_CNT_RST_EN; -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_TU, val); -+ if (ret) -+ goto err_config_video; -+ -+ /* set the FIFO Buffer size */ -+ val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate; -+ val /= (mhdp->dp.link.num_lanes * link_rate); -+ val = div_u64(8 * (symbol + 1), bit_per_pix) - val; -+ val += 2; -+ ret = cdns_mhdp_reg_write(mhdp, DP_VC_TABLE(15), val); -+ -+ switch (video->color_depth) { -+ case 6: -+ val = BCS_6; -+ break; -+ case 8: -+ val = BCS_8; -+ break; -+ case 10: -+ val = BCS_10; -+ break; -+ case 12: -+ val = BCS_12; -+ break; -+ case 16: -+ val = BCS_16; -+ break; -+ }; -+ -+ val += video->color_fmt << 8; -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_PXL_REPR, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0; -+ val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0; -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_SP, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = (mode->hsync_start - mode->hdisplay) << 16; -+ val |= mode->htotal - mode->hsync_end; -+ ret = cdns_mhdp_reg_write(mhdp, DP_FRONT_BACK_PORCH, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->hdisplay * bit_per_pix / 8; -+ ret = cdns_mhdp_reg_write(mhdp, DP_BYTE_COUNT, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_HORIZONTAL_0, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->hsync_end - mode->hsync_start; -+ val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_HORIZONTAL_1, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vtotal; -+ val |= (mode->vtotal - mode->vsync_start) << 16; -+ ret = cdns_mhdp_reg_write(mhdp, MSA_VERTICAL_0, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vsync_end - mode->vsync_start; -+ val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_VERTICAL_1, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = cdns_mhdp_get_msa_misc(video, mode); -+ ret = cdns_mhdp_reg_write(mhdp, MSA_MISC, val); -+ if (ret) -+ goto err_config_video; -+ -+ ret = cdns_mhdp_reg_write(mhdp, STREAM_CONFIG, 1); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->hsync_end - mode->hsync_start; -+ val |= mode->hdisplay << 16; -+ ret = cdns_mhdp_reg_write(mhdp, DP_HORIZONTAL, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vdisplay; -+ val |= (mode->vtotal - mode->vsync_start) << 16; -+ ret = cdns_mhdp_reg_write(mhdp, DP_VERTICAL_0, val); -+ if (ret) -+ goto err_config_video; -+ -+ val = mode->vtotal; -+ ret = cdns_mhdp_reg_write(mhdp, DP_VERTICAL_1, val); -+ if (ret) -+ goto err_config_video; -+ -+ ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 2, 1, 0); -+ -+err_config_video: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "config video failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_config_video); -+ -+int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) -+{ -+ int ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, 0); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "audio stop failed: %d\n", ret); -+ return ret; -+ } -+ -+ writel(0, mhdp->regs + SPDIF_CTRL_ADDR); -+ -+ /* clearn the audio config and reset */ -+ writel(0, mhdp->regs + AUDIO_SRC_CNTL); -+ writel(0, mhdp->regs + AUDIO_SRC_CNFG); -+ writel(AUDIO_SW_RST, mhdp->regs + AUDIO_SRC_CNTL); -+ writel(0, mhdp->regs + AUDIO_SRC_CNTL); -+ -+ /* reset smpl2pckt component */ -+ writel(0, mhdp->regs + SMPL2PKT_CNTL); -+ writel(AUDIO_SW_RST, mhdp->regs + SMPL2PKT_CNTL); -+ writel(0, mhdp->regs + SMPL2PKT_CNTL); -+ -+ /* reset FIFO */ -+ writel(AUDIO_SW_RST, mhdp->regs + FIFO_CNTL); -+ writel(0, mhdp->regs + FIFO_CNTL); -+ -+ if (audio->format == AFMT_SPDIF) -+ clk_disable_unprepare(mhdp->spdif_clk); -+ -+ return 0; -+} -+EXPORT_SYMBOL(cdns_mhdp_audio_stop); -+ -+int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable) -+{ -+ int ret; -+ -+ ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 4, 1, enable); -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "audio mute failed: %d\n", ret); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_audio_mute); -+ -+static void cdns_mhdp_audio_config_i2s(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) -+{ -+ int sub_pckt_num = 1, i2s_port_en_val = 0xf, i; -+ u32 val; -+ -+ if (audio->channels == 2) { -+ if (mhdp->dp.link.num_lanes == 1) -+ sub_pckt_num = 2; -+ else -+ sub_pckt_num = 4; -+ -+ i2s_port_en_val = 1; -+ } else if (audio->channels == 4) { -+ i2s_port_en_val = 3; -+ } -+ -+ writel(0x0, mhdp->regs + SPDIF_CTRL_ADDR); -+ -+ writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); -+ -+ val = MAX_NUM_CH(audio->channels); -+ val |= NUM_OF_I2S_PORTS(audio->channels); -+ val |= AUDIO_TYPE_LPCM; -+ val |= CFG_SUB_PCKT_NUM(sub_pckt_num); -+ writel(val, mhdp->regs + SMPL2PKT_CNFG); -+ -+ if (audio->sample_width == 16) -+ val = 0; -+ else if (audio->sample_width == 24) -+ val = 1 << 9; -+ else -+ val = 2 << 9; -+ -+ val |= AUDIO_CH_NUM(audio->channels); -+ val |= I2S_DEC_PORT_EN(i2s_port_en_val); -+ val |= TRANS_SMPL_WIDTH_32; -+ writel(val, mhdp->regs + AUDIO_SRC_CNFG); -+ -+ for (i = 0; i < (audio->channels + 1) / 2; i++) { -+ if (audio->sample_width == 16) -+ val = (0x02 << 8) | (0x02 << 20); -+ else if (audio->sample_width == 24) -+ val = (0x0b << 8) | (0x0b << 20); -+ -+ val |= ((2 * i) << 4) | ((2 * i + 1) << 16); -+ writel(val, mhdp->regs + STTS_BIT_CH(i)); -+ } -+ -+ switch (audio->sample_rate) { -+ case 32000: -+ val = SAMPLING_FREQ(3) | -+ ORIGINAL_SAMP_FREQ(0xc); -+ break; -+ case 44100: -+ val = SAMPLING_FREQ(0) | -+ ORIGINAL_SAMP_FREQ(0xf); -+ break; -+ case 48000: -+ val = SAMPLING_FREQ(2) | -+ ORIGINAL_SAMP_FREQ(0xd); -+ break; -+ case 88200: -+ val = SAMPLING_FREQ(8) | -+ ORIGINAL_SAMP_FREQ(0x7); -+ break; -+ case 96000: -+ val = SAMPLING_FREQ(0xa) | -+ ORIGINAL_SAMP_FREQ(5); -+ break; -+ case 176400: -+ val = SAMPLING_FREQ(0xc) | -+ ORIGINAL_SAMP_FREQ(3); -+ break; -+ case 192000: -+ val = SAMPLING_FREQ(0xe) | -+ ORIGINAL_SAMP_FREQ(1); -+ break; -+ } -+ val |= 4; -+ writel(val, mhdp->regs + COM_CH_STTS_BITS); -+ -+ writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); -+ writel(I2S_DEC_START, mhdp->regs + AUDIO_SRC_CNTL); -+} -+ -+static void cdns_mhdp_audio_config_spdif(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val; -+ -+ writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); -+ -+ val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4); -+ writel(val, mhdp->regs + SMPL2PKT_CNFG); -+ writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); -+ -+ val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS; -+ writel(val, mhdp->regs + SPDIF_CTRL_ADDR); -+ -+ clk_prepare_enable(mhdp->spdif_clk); -+ clk_set_rate(mhdp->spdif_clk, CDNS_DP_SPDIF_CLK); -+} -+ -+int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) -+{ -+ int ret; -+ -+ /* reset the spdif clk before config */ -+ if (audio->format == AFMT_SPDIF) { -+ reset_control_assert(mhdp->spdif_rst); -+ reset_control_deassert(mhdp->spdif_rst); -+ } -+ -+ ret = cdns_mhdp_reg_write(mhdp, CM_LANE_CTRL, LANE_REF_CYC); -+ if (ret) -+ goto err_audio_config; -+ -+ ret = cdns_mhdp_reg_write(mhdp, CM_CTRL, 0); -+ if (ret) -+ goto err_audio_config; -+ -+ if (audio->format == AFMT_I2S) -+ cdns_mhdp_audio_config_i2s(mhdp, audio); -+ else if (audio->format == AFMT_SPDIF) -+ cdns_mhdp_audio_config_spdif(mhdp); -+ -+ ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN); -+ -+err_audio_config: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "audio config failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_audio_config); -+ -+int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, -+ u8 nlanes, u16 udelay, u8 *lanes_data, u8 *dpcd) -+{ -+ u8 payload[7]; -+ u8 hdr[5]; /* For DPCD read response header */ -+ u32 addr; -+ u8 const nregs = 6; /* Registers 0x202-0x207 */ -+ int ret; -+ -+ if (nlanes != 4 && nlanes != 2 && nlanes != 1) { -+ DRM_DEV_ERROR(mhdp->dev, "invalid number of lanes: %d\n", -+ nlanes); -+ ret = -EINVAL; -+ goto err_adjust_lt; -+ } -+ -+ payload[0] = nlanes; -+ put_unaligned_be16(udelay, payload + 1); -+ memcpy(payload + 3, lanes_data, nlanes); -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_ADJUST_LT, -+ sizeof(payload), payload); -+ if (ret) -+ goto err_adjust_lt; -+ -+ /* Yes, read the DPCD read command response */ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -+ DPTX_READ_DPCD, -+ sizeof(hdr) + nregs); -+ if (ret) -+ goto err_adjust_lt; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, hdr, sizeof(hdr)); -+ if (ret) -+ goto err_adjust_lt; -+ -+ addr = get_unaligned_be24(hdr + 2); -+ if (addr != DP_LANE0_1_STATUS) -+ goto err_adjust_lt; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, dpcd, nregs); -+ -+err_adjust_lt: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "Failed to adjust Link Training.\n"); -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_adjust_lt); -+ -+int cdns_phy_reg_write(struct cdns_mhdp_device *mhdp, u32 addr, u32 val) -+{ -+ return cdns_mhdp_reg_write(mhdp, ADDR_PHY_AFE + (addr << 2), val); -+} -+EXPORT_SYMBOL(cdns_phy_reg_write); -+ -+u32 cdns_phy_reg_read(struct cdns_mhdp_device *mhdp, u32 addr) -+{ -+ return cdns_mhdp_reg_read(mhdp, ADDR_PHY_AFE + (addr << 2)); -+} -+EXPORT_SYMBOL(cdns_phy_reg_read); -+ -+int cdns_mhdp_read_hpd(struct cdns_mhdp_device *mhdp) -+{ -+ u8 status; -+ int ret; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL, GENERAL_GET_HPD_STATE, -+ 0, NULL); -+ if (ret) -+ goto err_get_hpd; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_GENERAL, -+ GENERAL_GET_HPD_STATE, sizeof(status)); -+ if (ret) -+ goto err_get_hpd; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, &status, sizeof(status)); -+ if (ret) -+ goto err_get_hpd; -+ -+ return status; -+ -+err_get_hpd: -+ DRM_ERROR("read hpd failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_read_hpd); -+ -+bool cdns_mhdp_check_alive(struct cdns_mhdp_device *mhdp) -+{ -+ u32 alive, newalive; -+ u8 retries_left = 10; -+ -+ alive = readl(mhdp->regs + KEEP_ALIVE); -+ -+ while (retries_left--) { -+ udelay(2); -+ -+ newalive = readl(mhdp->regs + KEEP_ALIVE); -+ if (alive == newalive) -+ continue; -+ return true; -+ } -+ return false; -+} -+EXPORT_SYMBOL(cdns_mhdp_check_alive); ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c -@@ -0,0 +1,296 @@ -+/* -+ * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#include -+#include -+#include -+ -+int cdns_hdmi_get_edid_block(void *data, u8 *edid, -+ u32 block, size_t length) -+{ -+ struct cdns_mhdp_device *mhdp = data; -+ u8 msg[2], reg[5], i; -+ int ret; -+ -+ for (i = 0; i < 4; i++) { -+ msg[0] = block / 2; -+ msg[1] = block % 2; -+ -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX, HDMI_TX_EDID, -+ sizeof(msg), msg); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_HDMI_TX, -+ HDMI_TX_EDID, sizeof(reg) + length); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ continue; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, edid, length); -+ if (ret) -+ continue; -+ -+ if ((reg[3] << 8 | reg[4]) == length) -+ break; -+ } -+ -+ if (ret) -+ DRM_ERROR("get block[%d] edid failed: %d\n", block, ret); -+ return ret; -+} -+ -+int cdns_hdmi_scdc_read(struct cdns_mhdp_device *mhdp, u8 addr, u8 *data) -+{ -+ u8 msg[4], reg[6]; -+ int ret; -+ -+ msg[0] = 0x54; -+ msg[1] = addr; -+ msg[2] = 0; -+ msg[3] = 1; -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX, HDMI_TX_READ, -+ sizeof(msg), msg); -+ if (ret) -+ goto err_scdc_read; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_HDMI_TX, -+ HDMI_TX_READ, sizeof(reg)); -+ if (ret) -+ goto err_scdc_read; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ goto err_scdc_read; -+ -+ *data = reg[5]; -+ -+err_scdc_read: -+ if (ret) -+ DRM_ERROR("scdc read failed: %d\n", ret); -+ return ret; -+} -+ -+int cdns_hdmi_scdc_write(struct cdns_mhdp_device *mhdp, u8 addr, u8 value) -+{ -+ u8 msg[5], reg[5]; -+ int ret; -+ -+ msg[0] = 0x54; -+ msg[1] = addr; -+ msg[2] = 0; -+ msg[3] = 1; -+ msg[4] = value; -+ ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX, HDMI_TX_WRITE, -+ sizeof(msg), msg); -+ if (ret) -+ goto err_scdc_write; -+ -+ ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_HDMI_TX, -+ HDMI_TX_WRITE, sizeof(reg)); -+ if (ret) -+ goto err_scdc_write; -+ -+ ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -+ if (ret) -+ goto err_scdc_write; -+ -+ if (reg[0] != 0) -+ ret = -EINVAL; -+ -+err_scdc_write: -+ if (ret) -+ DRM_ERROR("scdc write failed: %d\n", ret); -+ return ret; -+} -+ -+int cdns_hdmi_ctrl_init(struct cdns_mhdp_device *mhdp, -+ int protocol, -+ u32 char_rate) -+{ -+ u32 reg0; -+ u32 reg1; -+ u32 val; -+ int ret; -+ -+ /* Set PHY to HDMI data */ -+ ret = cdns_mhdp_reg_write(mhdp, PHY_DATA_SEL, F_SOURCE_PHY_MHDP_SEL(1)); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_HPD, -+ F_HPD_VALID_WIDTH(4) | F_HPD_GLITCH_WIDTH(0)); -+ if (ret < 0) -+ return ret; -+ -+ /* open CARS */ -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_PHY_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_HDTX_CAR, 0xFF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_PKT_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_AIF_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_CIPHER_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_CRYPTO_CAR, 0xF); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, SOURCE_CEC_CAR, 3); -+ if (ret < 0) -+ return ret; -+ -+ reg0 = reg1 = 0x7c1f; -+ if (protocol == MODE_HDMI_2_0 && char_rate >= 340000) { -+ reg0 = 0; -+ reg1 = 0xFFFFF; -+ } -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CLOCK_REG_0, reg0); -+ if (ret < 0) -+ return ret; -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CLOCK_REG_1, reg1); -+ if (ret < 0) -+ return ret; -+ -+ /* set hdmi mode and preemble mode data enable */ -+ val = F_HDMI_MODE(protocol) | F_HDMI2_PREAMBLE_EN(1) | F_DATA_EN(1) | -+ F_HDMI2_CTRL_IL_MODE(1) | F_BCH_EN(1) | F_PIC_3D(0XF); -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+ -+ return ret; -+} -+ -+int cdns_hdmi_mode_config(struct cdns_mhdp_device *mhdp, -+ struct drm_display_mode *mode, -+ struct video_info *video_info) -+{ -+ int ret; -+ u32 val; -+ u32 vsync_lines = mode->vsync_end - mode->vsync_start; -+ u32 eof_lines = mode->vsync_start - mode->vdisplay; -+ u32 sof_lines = mode->vtotal - mode->vsync_end; -+ u32 hblank = mode->htotal - mode->hdisplay; -+ u32 hactive = mode->hdisplay; -+ u32 vblank = mode->vtotal - mode->vdisplay; -+ u32 vactive = mode->vdisplay; -+ u32 hfront = mode->hsync_start - mode->hdisplay; -+ u32 hback = mode->htotal - mode->hsync_end; -+ u32 vfront = eof_lines; -+ u32 hsync = hblank - hfront - hback; -+ u32 vsync = vsync_lines; -+ u32 vback = sof_lines; -+ u32 v_h_polarity = ((mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1) + -+ ((mode->flags & DRM_MODE_FLAG_NVSYNC) ? 0 : 2); -+ -+ ret = cdns_mhdp_reg_write(mhdp, SCHEDULER_H_SIZE, (hactive << 16) + hblank); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, SCHEDULER_V_SIZE, (vactive << 16) + vblank); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_FRONT_WIDTH, (vfront << 16) + hfront); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_SYNC_WIDTH, (vsync << 16) + hsync); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_BACK_WIDTH, (vback << 16) + hback); -+ if (ret < 0) -+ return ret; -+ -+ ret = cdns_mhdp_reg_write(mhdp, HSYNC2VSYNC_POL_CTRL, v_h_polarity); -+ if (ret < 0) -+ return ret; -+ -+ /* Reset Data Enable */ -+ val = cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER); -+ val &= ~F_DATA_EN(1); -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+ if (ret < 0) -+ return ret; -+ -+ /* Set bpc */ -+ val &= ~F_VIF_DATA_WIDTH(3); -+ switch (video_info->color_depth) { -+ case 10: -+ val |= F_VIF_DATA_WIDTH(1); -+ break; -+ case 12: -+ val |= F_VIF_DATA_WIDTH(2); -+ break; -+ case 16: -+ val |= F_VIF_DATA_WIDTH(3); -+ break; -+ case 8: -+ default: -+ val |= F_VIF_DATA_WIDTH(0); -+ break; -+ } -+ -+ /* select color encoding */ -+ val &= ~F_HDMI_ENCODING(3); -+ switch (video_info->color_fmt) { -+ case YCBCR_4_4_4: -+ val |= F_HDMI_ENCODING(2); -+ break; -+ case YCBCR_4_2_2: -+ val |= F_HDMI_ENCODING(1); -+ break; -+ case YCBCR_4_2_0: -+ val |= F_HDMI_ENCODING(3); -+ break; -+ case PXL_RGB: -+ default: -+ val |= F_HDMI_ENCODING(0); -+ break; -+ } -+ -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+ if (ret < 0) -+ return ret; -+ -+ /* set data enable */ -+ val |= F_DATA_EN(1); -+ ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+ -+ return ret; -+} -+ -+int cdns_hdmi_disable_gcp(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val; -+ -+ val = cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER); -+ val &= ~F_GCP_EN(1); -+ -+ return cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+} -+ -+int cdns_hdmi_enable_gcp(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val; -+ -+ val = cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER); -+ val |= F_GCP_EN(1); -+ -+ return cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); -+} ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp.h -@@ -0,0 +1,209 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Cadence MHDP DP MST bridge driver. -+ * -+ * Copyright: 2018 Cadence Design Systems, Inc. -+ * -+ * Author: Quentin Schulz -+ */ -+ -+ -+#ifndef CDNS_MHDP_H -+#define CDNS_MHDP_H -+ -+#include -+ -+#define CDNS_APB_CFG 0x00000 -+#define CDNS_APB_CTRL (CDNS_APB_CFG + 0x00) -+#define CDNS_MAILBOX_FULL (CDNS_APB_CFG + 0x08) -+#define CDNS_MAILBOX_EMPTY (CDNS_APB_CFG + 0x0c) -+#define CDNS_MAILBOX_TX_DATA (CDNS_APB_CFG + 0x10) -+#define CDNS_MAILBOX_RX_DATA (CDNS_APB_CFG + 0x14) -+#define CDNS_KEEP_ALIVE (CDNS_APB_CFG + 0x18) -+#define CDNS_KEEP_ALIVE_MASK GENMASK(7, 0) -+ -+#define CDNS_MB_INT_MASK (CDNS_APB_CFG + 0x34) -+ -+#define CDNS_SW_CLK_L (CDNS_APB_CFG + 0x3c) -+#define CDNS_SW_CLK_H (CDNS_APB_CFG + 0x40) -+#define CDNS_SW_EVENT0 (CDNS_APB_CFG + 0x44) -+#define CDNS_DPTX_HPD BIT(0) -+ -+#define CDNS_SW_EVENT1 (CDNS_APB_CFG + 0x48) -+#define CDNS_SW_EVENT2 (CDNS_APB_CFG + 0x4c) -+#define CDNS_SW_EVENT3 (CDNS_APB_CFG + 0x50) -+ -+#define CDNS_APB_INT_MASK (CDNS_APB_CFG + 0x6C) -+#define CDNS_APB_INT_MASK_MAILBOX_INT BIT(0) -+#define CDNS_APB_INT_MASK_SW_EVENT_INT BIT(1) -+ -+#define CDNS_DPTX_CAR (CDNS_APB_CFG + 0x904) -+#define CDNS_VIF_CLK_EN BIT(0) -+#define CDNS_VIF_CLK_RSTN BIT(1) -+ -+#define CDNS_SOURCE_VIDEO_IF(s) (0x00b00 + (s * 0x20)) -+#define CDNS_BND_HSYNC2VSYNC(s) (CDNS_SOURCE_VIDEO_IF(s) + \ -+ 0x00) -+#define CDNS_IP_DTCT_WIN GENMASK(11, 0) -+#define CDNS_IP_DET_INTERLACE_FORMAT BIT(12) -+#define CDNS_IP_BYPASS_V_INTERFACE BIT(13) -+ -+#define CDNS_HSYNC2VSYNC_POL_CTRL(s) (CDNS_SOURCE_VIDEO_IF(s) + \ -+ 0x10) -+#define CDNS_H2V_HSYNC_POL_ACTIVE_LOW BIT(1) -+#define CDNS_H2V_VSYNC_POL_ACTIVE_LOW BIT(2) -+ -+#define CDNS_DPTX_PHY_CONFIG 0x02000 -+#define CDNS_PHY_TRAINING_EN BIT(0) -+#define CDNS_PHY_TRAINING_TYPE(x) (((x) & GENMASK(3, 0)) << 1) -+#define CDNS_PHY_SCRAMBLER_BYPASS BIT(5) -+#define CDNS_PHY_ENCODER_BYPASS BIT(6) -+#define CDNS_PHY_SKEW_BYPASS BIT(7) -+#define CDNS_PHY_TRAINING_AUTO BIT(8) -+#define CDNS_PHY_LANE0_SKEW(x) (((x) & GENMASK(2, 0)) << 9) -+#define CDNS_PHY_LANE1_SKEW(x) (((x) & GENMASK(2, 0)) << 12) -+#define CDNS_PHY_LANE2_SKEW(x) (((x) & GENMASK(2, 0)) << 15) -+#define CDNS_PHY_LANE3_SKEW(x) (((x) & GENMASK(2, 0)) << 18) -+#define CDNS_PHY_COMMON_CONFIG (CDNS_PHY_LANE1_SKEW(1) | \ -+ CDNS_PHY_LANE2_SKEW(2) | \ -+ CDNS_PHY_LANE3_SKEW(3)) -+#define CDNS_PHY_10BIT_EN BIT(21) -+ -+#define CDNS_DPTX_FRAMER 0x02200 -+#define CDNS_DP_FRAMER_GLOBAL_CONFIG (CDNS_DPTX_FRAMER + 0x00) -+#define CDNS_DP_NUM_LANES(x) (x - 1) -+#define CDNS_DP_MST_EN BIT(2) -+#define CDNS_DP_FRAMER_EN BIT(3) -+#define CDNS_DP_RATE_GOVERNOR_EN BIT(4) -+#define CDNS_DP_NO_VIDEO_MODE BIT(5) -+#define CDNS_DP_DISABLE_PHY_RST BIT(6) -+#define CDNS_DP_WR_FAILING_EDGE_VSYNC BIT(7) -+ -+#define CDNS_DP_SW_RESET (CDNS_DPTX_FRAMER + 0x04) -+#define CDNS_DP_FRAMER_TU (CDNS_DPTX_FRAMER + 0x08) -+#define CDNS_DP_FRAMER_TU_SIZE(x) (((x) & GENMASK(6, 0)) << 8) -+#define CDNS_DP_FRAMER_TU_VS(x) ((x) & GENMASK(5, 0)) -+#define CDNS_DP_FRAMER_TU_CNT_RST_EN BIT(15) -+ -+#define CDNS_DPTX_STREAM(s) (0x03000 + s * 0x80) -+#define CDNS_DP_MSA_HORIZONTAL_0(s) (CDNS_DPTX_STREAM(s) + 0x00) -+#define CDNS_DP_MSAH0_H_TOTAL(x) (x) -+#define CDNS_DP_MSAH0_HSYNC_START(x) ((x) << 16) -+ -+#define CDNS_DP_MSA_HORIZONTAL_1(s) (CDNS_DPTX_STREAM(s) + 0x04) -+#define CDNS_DP_MSAH1_HSYNC_WIDTH(x) (x) -+#define CDNS_DP_MSAH1_HSYNC_POL_LOW BIT(15) -+#define CDNS_DP_MSAH1_HDISP_WIDTH(x) ((x) << 16) -+ -+#define CDNS_DP_MSA_VERTICAL_0(s) (CDNS_DPTX_STREAM(s) + 0x08) -+#define CDNS_DP_MSAV0_V_TOTAL(x) (x) -+#define CDNS_DP_MSAV0_VSYNC_START(x) ((x) << 16) -+ -+#define CDNS_DP_MSA_VERTICAL_1(s) (CDNS_DPTX_STREAM(s) + 0x0c) -+#define CDNS_DP_MSAV1_VSYNC_WIDTH(x) (x) -+#define CDNS_DP_MSAV1_VSYNC_POL_LOW BIT(15) -+#define CDNS_DP_MSAV1_VDISP_WIDTH(x) ((x) << 16) -+ -+#define CDNS_DP_MSA_MISC(s) (CDNS_DPTX_STREAM(s) + 0x10) -+#define CDNS_DP_STREAM_CONFIGs(s) (CDNS_DPTX_STREAM(s) + 0x14) -+#define CDNS_DP_STREAM_CONFIG_2(s) (CDNS_DPTX_STREAM(s) + 0x2c) -+#define CDNS_DP_SC2_TU_VS_DIFF(x) ((x) << 8) -+ -+#define CDNS_DP_HORIZONTAL(s) (CDNS_DPTX_STREAM(s) + 0x30) -+#define CDNS_DP_H_HSYNC_WIDTH(x) (x) -+#define CDNS_DP_H_H_TOTAL(x) ((x) << 16) -+ -+#define CDNS_DP_VERTICAL_0(s) (CDNS_DPTX_STREAM(s) + 0x34) -+#define CDNS_DP_V0_VHEIGHT(x) (x) -+#define CDNS_DP_V0_VSTART(x) ((x) << 16) -+ -+#define CDNS_DP_VERTICAL_1(s) (CDNS_DPTX_STREAM(s) + 0x38) -+#define CDNS_DP_V1_VTOTAL(x) (x) -+#define CDNS_DP_V1_VTOTAL_EVEN BIT(16) -+ -+#define CDNS_DP_FRAMER_PXL_REPR(s) (CDNS_DPTX_STREAM(s) + 0x4c) -+#define CDNS_DP_FRAMER_6_BPC BIT(0) -+#define CDNS_DP_FRAMER_8_BPC BIT(1) -+#define CDNS_DP_FRAMER_10_BPC BIT(2) -+#define CDNS_DP_FRAMER_12_BPC BIT(3) -+#define CDNS_DP_FRAMER_16_BPC BIT(4) -+#define CDNS_DP_FRAMER_PXL_FORMAT 0x8 -+#define CDNS_DP_FRAMER_RGB BIT(0) -+#define CDNS_DP_FRAMER_YCBCR444 BIT(1) -+#define CDNS_DP_FRAMER_YCBCR422 BIT(2) -+#define CDNS_DP_FRAMER_YCBCR420 BIT(3) -+#define CDNS_DP_FRAMER_Y_ONLY BIT(4) -+ -+#define CDNS_DP_FRAMER_SP(s) (CDNS_DPTX_STREAM(s) + 0x10) -+#define CDNS_DP_FRAMER_VSYNC_POL_LOW BIT(0) -+#define CDNS_DP_FRAMER_HSYNC_POL_LOW BIT(1) -+#define CDNS_DP_FRAMER_INTERLACE BIT(2) -+ -+#define CDNS_DP_LINE_THRESH(s) (CDNS_DPTX_STREAM(s) + 0x64) -+#define CDNS_DP_ACTIVE_LINE_THRESH(x) (x) -+ -+#define CDNS_DP_VB_ID(s) (CDNS_DPTX_STREAM(s) + 0x68) -+#define CDNS_DP_VB_ID_INTERLACED BIT(2) -+#define CDNS_DP_VB_ID_COMPRESSED BIT(6) -+ -+#define CDNS_DP_FRONT_BACK_PORCH(s) (CDNS_DPTX_STREAM(s) + 0x78) -+#define CDNS_DP_BACK_PORCH(x) (x) -+#define CDNS_DP_FRONT_PORCH(x) ((x) << 16) -+ -+#define CDNS_DP_BYTE_COUNT(s) (CDNS_DPTX_STREAM(s) + 0x7c) -+#define CDNS_DP_BYTE_COUNT_BYTES_IN_CHUNK_SHIFT 16 -+ -+#define CDNS_DP_MST_STREAM_CONFIG(s) (CDNS_DPTX_STREAM(s) + 0x14) -+#define CDNS_DP_MST_STRM_CFG_STREAM_EN BIT(0) -+#define CDNS_DP_MST_STRM_CFG_NO_VIDEO BIT(1) -+ -+#define CDNS_DP_MST_SLOT_ALLOCATE(s) (CDNS_DPTX_STREAM(s) + 0x44) -+#define CDNS_DP_S_ALLOC_START_SLOT(x) (x) -+#define CDNS_DP_S_ALLOC_END_SLOT(x) ((x) << 8) -+ -+#define CDNS_DP_RATE_GOVERNING(s) (CDNS_DPTX_STREAM(s) + 0x48) -+#define CDNS_DP_RG_TARG_AV_SLOTS_Y(x) (x) -+#define CDNS_DP_RG_TARG_AV_SLOTS_X(x) (x << 4) -+#define CDNS_DP_RG_ENABLE BIT(10) -+ -+#define CDNS_DP_MTPH_CONTROL 0x2264 -+#define CDNS_DP_MTPH_ECF_EN BIT(0) -+#define CDNS_DP_MTPH_ACT_EN BIT(1) -+#define CDNS_DP_MTPH_LVP_EN BIT(2) -+ -+#define CDNS_DP_MTPH_STATUS 0x226C -+#define CDNS_DP_MTPH_ACT_STATUS BIT(0) -+ -+ -+#define CDNS_DPTX_GLOBAL 0x02300 -+#define CDNS_DP_LANE_EN (CDNS_DPTX_GLOBAL + 0x00) -+#define CDNS_DP_LANE_EN_LANES(x) GENMASK(x - 1, 0) -+#define CDNS_DP_ENHNCD (CDNS_DPTX_GLOBAL + 0x04) -+ -+ -+#define to_mhdp_connector(x) container_of(x, struct cdns_mhdp_connector, base) -+#define to_mhdp_bridge(x) container_of(x, struct cdns_mhdp_bridge, base) -+#define mgr_to_mhdp(x) container_of(x, struct cdns_mhdp_device, mst_mgr) -+ -+#define CDNS_MHDP_MAX_STREAMS 4 -+ -+enum pixel_format { -+ PIXEL_FORMAT_RGB = 1, -+ PIXEL_FORMAT_YCBCR_444 = 2, -+ PIXEL_FORMAT_YCBCR_422 = 4, -+ PIXEL_FORMAT_YCBCR_420 = 8, -+ PIXEL_FORMAT_Y_ONLY = 16, -+}; -+ -+ -+int cdns_mhdp_mst_init(struct cdns_mhdp_device *mhdp); -+void cdns_mhdp_mst_deinit(struct cdns_mhdp_device *mhdp); -+bool cdns_mhdp_mst_probe(struct cdns_mhdp_device *mhdp); -+enum pixel_format cdns_mhdp_get_pxlfmt(u32 color_formats); -+u32 cdns_mhdp_get_bpp(u32 bpc, u32 color_formats); -+void cdns_mhdp_configure_video(struct drm_bridge *bridge); -+void cdns_mhdp_mst_enable(struct drm_bridge *bridge); -+void cdns_mhdp_mst_disable(struct drm_bridge *bridge); -+void cdns_mhdp_enable(struct drm_bridge *bridge); -+ -+#endif ---- a/drivers/gpu/drm/rockchip/Kconfig -+++ b/drivers/gpu/drm/rockchip/Kconfig -@@ -29,7 +29,9 @@ config ROCKCHIP_ANALOGIX_DP - - config ROCKCHIP_CDN_DP - bool "Rockchip cdn DP" -- depends on EXTCON=y || (EXTCON=m && DRM_ROCKCHIP=m) -+ depends on DRM_ROCKCHIP -+ select EXTCON -+ select DRM_CDNS_MHDP - help - This selects support for Rockchip SoC specific extensions - for the cdn DP driver. If you want to enable Dp on ---- a/drivers/gpu/drm/rockchip/Makefile -+++ b/drivers/gpu/drm/rockchip/Makefile -@@ -8,7 +8,7 @@ rockchipdrm-y := rockchip_drm_drv.o rock - rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o - - rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o --rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o -+rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o - rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o - rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o - rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o ---- a/drivers/gpu/drm/rockchip/cdn-dp-core.c -+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c -@@ -25,7 +25,7 @@ - #include "rockchip_drm_vop.h" - - #define connector_to_dp(c) \ -- container_of(c, struct cdn_dp_device, mhdp.connector) -+ container_of(c, struct cdn_dp_device, mhdp.connector.base) - - #define encoder_to_dp(c) \ - container_of(c, struct cdn_dp_device, encoder) -@@ -283,7 +283,7 @@ static int cdn_dp_connector_mode_valid(s - { - struct cdn_dp_device *dp = connector_to_dp(connector); - struct drm_display_info *display_info = -- &dp->mhdp.connector.display_info; -+ &dp->mhdp.connector.base.display_info; - u32 requested, actual, rate, sink_max, source_max = 0; - u8 lanes, bpc; - -@@ -379,7 +379,7 @@ static int cdn_dp_get_sink_capability(st - } - - kfree(dp->edid); -- dp->edid = drm_do_get_edid(&dp->mhdp.connector, -+ dp->edid = drm_do_get_edid(&dp->mhdp.connector.base, - cdns_mhdp_get_edid_block, &dp->mhdp); - return 0; - } -@@ -485,8 +485,8 @@ static int cdn_dp_disable(struct cdn_dp_ - cdns_mhdp_set_firmware_active(&dp->mhdp, false); - cdn_dp_clk_disable(dp); - dp->active = false; -- dp->mhdp.link.rate = 0; -- dp->mhdp.link.num_lanes = 0; -+ dp->mhdp.dp.link.rate = 0; -+ dp->mhdp.dp.link.num_lanes = 0; - if (!dp->connected) { - kfree(dp->edid); - dp->edid = NULL; -@@ -551,7 +551,7 @@ static void cdn_dp_encoder_mode_set(stru - { - struct cdn_dp_device *dp = encoder_to_dp(encoder); - struct drm_display_info *display_info = -- &dp->mhdp.connector.display_info; -+ &dp->mhdp.connector.base.display_info; - struct video_info *video = &dp->mhdp.video_info; - - switch (display_info->bpc) { -@@ -579,7 +579,7 @@ static bool cdn_dp_check_link_status(str - struct cdn_dp_port *port = cdn_dp_connected_port(dp); - u8 sink_lanes = drm_dp_max_lane_count(dp->dpcd); - -- if (!port || !dp->mhdp.link.rate || !dp->mhdp.link.num_lanes) -+ if (!port || !dp->mhdp.dp.link.rate || !dp->mhdp.dp.link.num_lanes) - return false; - - if (cdns_mhdp_dpcd_read(&dp->mhdp, DP_LANE0_1_STATUS, link_status, -@@ -808,7 +808,7 @@ static int cdn_dp_audio_hw_params(struct - - ret = cdns_mhdp_audio_config(&dp->mhdp, &audio); - if (!ret) -- dp->audio_info = audio; -+ dp->mhdp.audio_info = audio; - - out: - mutex_unlock(&dp->lock); -@@ -824,9 +824,9 @@ static void cdn_dp_audio_shutdown(struct - if (!dp->active) - goto out; - -- ret = cdns_mhdp_audio_stop(&dp->mhdp, &dp->audio_info); -+ ret = cdns_mhdp_audio_stop(&dp->mhdp, &dp->mhdp.audio_info); - if (!ret) -- dp->audio_info.format = AFMT_UNUSED; -+ dp->mhdp.audio_info.format = AFMT_UNUSED; - out: - mutex_unlock(&dp->lock); - } -@@ -855,8 +855,8 @@ static int cdn_dp_audio_get_eld(struct d - { - struct cdn_dp_device *dp = dev_get_drvdata(dev); - -- memcpy(buf, dp->mhdp.connector.eld, -- min(sizeof(dp->mhdp.connector.eld), len)); -+ memcpy(buf, dp->mhdp.connector.base.eld, -+ min(sizeof(dp->mhdp.connector.base.eld), len)); - - return 0; - } -@@ -878,11 +878,11 @@ static int cdn_dp_audio_codec_init(struc - .max_i2s_channels = 8, - }; - -- dp->audio_pdev = platform_device_register_data( -- dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, -- &codec_data, sizeof(codec_data)); -+ dp->mhdp.audio_pdev = platform_device_register_data( -+ dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, -+ &codec_data, sizeof(codec_data)); - -- return PTR_ERR_OR_ZERO(dp->audio_pdev); -+ return PTR_ERR_OR_ZERO(dp->mhdp.audio_pdev); - } - - static int cdn_dp_request_firmware(struct cdn_dp_device *dp) -@@ -928,7 +928,7 @@ static void cdn_dp_pd_event_work(struct - { - struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device, - event_work); -- struct drm_connector *connector = &dp->mhdp.connector; -+ struct drm_connector *connector = &dp->mhdp.connector.base; - enum drm_connector_status old_status; - struct device *dev = dp->mhdp.dev; - -@@ -966,8 +966,8 @@ static void cdn_dp_pd_event_work(struct - - /* Enabled and connected with a sink, re-train if requested */ - } else if (!cdn_dp_check_link_status(dp)) { -- unsigned int rate = dp->mhdp.link.rate; -- unsigned int lanes = dp->mhdp.link.num_lanes; -+ unsigned int rate = dp->mhdp.dp.link.rate; -+ unsigned int lanes = dp->mhdp.dp.link.num_lanes; - struct drm_display_mode *mode = &dp->mhdp.mode; - - DRM_DEV_INFO(dev, "Connected with sink. Re-train link\n"); -@@ -980,8 +980,8 @@ static void cdn_dp_pd_event_work(struct - - /* If training result is changed, update the video config */ - if (mode->clock && -- (rate != dp->mhdp.link.rate || -- lanes != dp->mhdp.link.num_lanes)) { -+ (rate != dp->mhdp.dp.link.rate || -+ lanes != dp->mhdp.dp.link.num_lanes)) { - ret = cdns_mhdp_config_video(&dp->mhdp); - if (ret) { - dp->connected = false; -@@ -1054,7 +1054,7 @@ static int cdn_dp_bind(struct device *de - - drm_encoder_helper_add(encoder, &cdn_dp_encoder_helper_funcs); - -- connector = &dp->mhdp.connector; -+ connector = &dp->mhdp.connector.base; - connector->polled = DRM_CONNECTOR_POLL_HPD; - connector->dpms = DRM_MODE_DPMS_OFF; - -@@ -1105,7 +1105,7 @@ static void cdn_dp_unbind(struct device - { - struct cdn_dp_device *dp = dev_get_drvdata(dev); - struct drm_encoder *encoder = &dp->encoder; -- struct drm_connector *connector = &dp->mhdp.connector; -+ struct drm_connector *connector = &dp->mhdp.connector.base; - - cancel_work_sync(&dp->event_work); - cdn_dp_encoder_disable(encoder); -@@ -1209,7 +1209,7 @@ static int cdn_dp_remove(struct platform - { - struct cdn_dp_device *dp = platform_get_drvdata(pdev); - -- platform_device_unregister(dp->audio_pdev); -+ platform_device_unregister(dp->mhdp.audio_pdev); - cdn_dp_suspend(dp->mhdp.dev); - component_del(&pdev->dev, &cdn_dp_component_ops); - ---- a/drivers/gpu/drm/rockchip/cdn-dp-core.h -+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h -@@ -7,12 +7,13 @@ - #ifndef _CDN_DP_CORE_H - #define _CDN_DP_CORE_H - -+#include -+#include - #include - #include - #include - - #include "rockchip_drm_drv.h" --#include "cdn-dp-reg.h" - - #define MAX_PHY 2 - -@@ -37,7 +38,6 @@ struct cdn_dp_device { - struct cdns_mhdp_device mhdp; - struct drm_device *drm_dev; - struct drm_encoder encoder; -- struct platform_device *audio_pdev; - struct work_struct event_work; - struct edid *edid; - -@@ -56,7 +56,6 @@ struct cdn_dp_device { - struct reset_control *dptx_rst; - struct reset_control *apb_rst; - struct reset_control *core_rst; -- struct audio_info audio_info; - struct cdn_dp_port *port[MAX_PHY]; - u8 ports; - u8 lanes; ---- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c -+++ /dev/null -@@ -1,968 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-only --/* -- * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd -- * Author: Chris Zhong -- */ -- --#include --#include --#include --#include --#include --#include -- --#include "cdn-dp-core.h" --#include "cdn-dp-reg.h" -- --#define CDNS_DP_SPDIF_CLK 200000000 --#define FW_ALIVE_TIMEOUT_US 1000000 --#define MAILBOX_RETRY_US 1000 --#define MAILBOX_TIMEOUT_US 5000000 --#define LINK_TRAINING_RETRY_MS 20 --#define LINK_TRAINING_TIMEOUT_MS 500 -- --void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk) --{ -- writel(clk / 1000000, mhdp->regs + SW_CLK_H); --} -- --void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp) --{ -- u32 val; -- -- val = DPTX_FRMR_DATA_CLK_RSTN_EN | -- DPTX_FRMR_DATA_CLK_EN | -- DPTX_PHY_DATA_RSTN_EN | -- DPTX_PHY_DATA_CLK_EN | -- DPTX_PHY_CHAR_RSTN_EN | -- DPTX_PHY_CHAR_CLK_EN | -- SOURCE_AUX_SYS_CLK_RSTN_EN | -- SOURCE_AUX_SYS_CLK_EN | -- DPTX_SYS_CLK_RSTN_EN | -- DPTX_SYS_CLK_EN | -- CFG_DPTX_VIF_CLK_RSTN_EN | -- CFG_DPTX_VIF_CLK_EN; -- writel(val, mhdp->regs + SOURCE_DPTX_CAR); -- -- val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN; -- writel(val, mhdp->regs + SOURCE_PHY_CAR); -- -- val = SOURCE_PKT_SYS_RSTN_EN | -- SOURCE_PKT_SYS_CLK_EN | -- SOURCE_PKT_DATA_RSTN_EN | -- SOURCE_PKT_DATA_CLK_EN; -- writel(val, mhdp->regs + SOURCE_PKT_CAR); -- -- val = SPDIF_CDR_CLK_RSTN_EN | -- SPDIF_CDR_CLK_EN | -- SOURCE_AIF_SYS_RSTN_EN | -- SOURCE_AIF_SYS_CLK_EN | -- SOURCE_AIF_CLK_RSTN_EN | -- SOURCE_AIF_CLK_EN; -- writel(val, mhdp->regs + SOURCE_AIF_CAR); -- -- val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN | -- SOURCE_CIPHER_SYS_CLK_EN | -- SOURCE_CIPHER_CHAR_CLK_RSTN_EN | -- SOURCE_CIPHER_CHAR_CLK_EN; -- writel(val, mhdp->regs + SOURCE_CIPHER_CAR); -- -- val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN | -- SOURCE_CRYPTO_SYS_CLK_EN; -- writel(val, mhdp->regs + SOURCE_CRYPTO_CAR); -- -- /* enable Mailbox and PIF interrupt */ -- writel(0, mhdp->regs + APB_INT_MASK); --} -- --static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp) --{ -- int val, ret; -- -- ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_EMPTY_ADDR, -- val, !val, MAILBOX_RETRY_US, -- MAILBOX_TIMEOUT_US); -- if (ret < 0) -- return ret; -- -- return readl(mhdp->regs + MAILBOX0_RD_DATA) & 0xff; --} -- --static int cdp_dp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val) --{ -- int ret, full; -- -- ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_FULL_ADDR, -- full, !full, MAILBOX_RETRY_US, -- MAILBOX_TIMEOUT_US); -- if (ret < 0) -- return ret; -- -- writel(val, mhdp->regs + MAILBOX0_WR_DATA); -- -- return 0; --} -- --static int cdns_mhdp_mailbox_validate_receive(struct cdns_mhdp_device *mhdp, -- u8 module_id, u8 opcode, -- u16 req_size) --{ -- u32 mbox_size, i; -- u8 header[4]; -- int ret; -- -- /* read the header of the message */ -- for (i = 0; i < 4; i++) { -- ret = cdns_mhdp_mailbox_read(mhdp); -- if (ret < 0) -- return ret; -- -- header[i] = ret; -- } -- -- mbox_size = (header[2] << 8) | header[3]; -- -- if (opcode != header[0] || module_id != header[1] || -- req_size != mbox_size) { -- /* -- * If the message in mailbox is not what we want, we need to -- * clear the mailbox by reading its contents. -- */ -- for (i = 0; i < mbox_size; i++) -- if (cdns_mhdp_mailbox_read(mhdp) < 0) -- break; -- -- return -EINVAL; -- } -- -- return 0; --} -- --static int cdns_mhdp_mailbox_read_receive(struct cdns_mhdp_device *mhdp, -- u8 *buff, u16 buff_size) --{ -- u32 i; -- int ret; -- -- for (i = 0; i < buff_size; i++) { -- ret = cdns_mhdp_mailbox_read(mhdp); -- if (ret < 0) -- return ret; -- -- buff[i] = ret; -- } -- -- return 0; --} -- --static int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id, -- u8 opcode, u16 size, u8 *message) --{ -- u8 header[4]; -- int ret, i; -- -- header[0] = opcode; -- header[1] = module_id; -- header[2] = (size >> 8) & 0xff; -- header[3] = size & 0xff; -- -- for (i = 0; i < 4; i++) { -- ret = cdp_dp_mailbox_write(mhdp, header[i]); -- if (ret) -- return ret; -- } -- -- for (i = 0; i < size; i++) { -- ret = cdp_dp_mailbox_write(mhdp, message[i]); -- if (ret) -- return ret; -- } -- -- return 0; --} -- --static int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u16 addr, u32 val) --{ -- u8 msg[6]; -- -- msg[0] = (addr >> 8) & 0xff; -- msg[1] = addr & 0xff; -- msg[2] = (val >> 24) & 0xff; -- msg[3] = (val >> 16) & 0xff; -- msg[4] = (val >> 8) & 0xff; -- msg[5] = val & 0xff; -- return cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_REGISTER, sizeof(msg), msg); --} -- --static int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr, -- u8 start_bit, u8 bits_no, u32 val) --{ -- u8 field[8]; -- -- field[0] = (addr >> 8) & 0xff; -- field[1] = addr & 0xff; -- field[2] = start_bit; -- field[3] = bits_no; -- field[4] = (val >> 24) & 0xff; -- field[5] = (val >> 16) & 0xff; -- field[6] = (val >> 8) & 0xff; -- field[7] = val & 0xff; -- -- return cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_FIELD, sizeof(field), field); --} -- --int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp, -- u32 addr, u8 *data, u16 len) --{ -- u8 msg[5], reg[5]; -- int ret; -- -- msg[0] = (len >> 8) & 0xff; -- msg[1] = len & 0xff; -- msg[2] = (addr >> 16) & 0xff; -- msg[3] = (addr >> 8) & 0xff; -- msg[4] = addr & 0xff; -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_DPCD, sizeof(msg), msg); -- if (ret) -- goto err_dpcd_read; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_DPCD, -- sizeof(reg) + len); -- if (ret) -- goto err_dpcd_read; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -- if (ret) -- goto err_dpcd_read; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, data, len); -- --err_dpcd_read: -- return ret; --} -- --int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value) --{ -- u8 msg[6], reg[5]; -- int ret; -- -- msg[0] = 0; -- msg[1] = 1; -- msg[2] = (addr >> 16) & 0xff; -- msg[3] = (addr >> 8) & 0xff; -- msg[4] = addr & 0xff; -- msg[5] = value; -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_DPCD, sizeof(msg), msg); -- if (ret) -- goto err_dpcd_write; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_WRITE_DPCD, sizeof(reg)); -- if (ret) -- goto err_dpcd_write; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -- if (ret) -- goto err_dpcd_write; -- -- if (addr != (reg[2] << 16 | reg[3] << 8 | reg[4])) -- ret = -EINVAL; -- --err_dpcd_write: -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "dpcd write failed: %d\n", ret); -- return ret; --} -- --int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, -- u32 i_size, const u32 *d_mem, u32 d_size) --{ -- u32 reg; -- int i, ret; -- -- /* reset ucpu before load firmware*/ -- writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET, -- mhdp->regs + APB_CTRL); -- -- for (i = 0; i < i_size; i += 4) -- writel(*i_mem++, mhdp->regs + ADDR_IMEM + i); -- -- for (i = 0; i < d_size; i += 4) -- writel(*d_mem++, mhdp->regs + ADDR_DMEM + i); -- -- /* un-reset ucpu */ -- writel(0, mhdp->regs + APB_CTRL); -- -- /* check the keep alive register to make sure fw working */ -- ret = readx_poll_timeout(readl, mhdp->regs + KEEP_ALIVE, -- reg, reg, 2000, FW_ALIVE_TIMEOUT_US); -- if (ret < 0) { -- DRM_DEV_ERROR(mhdp->dev, "failed to loaded the FW reg = %x\n", -- reg); -- return -EINVAL; -- } -- -- reg = readl(mhdp->regs + VER_L) & 0xff; -- mhdp->fw_version = reg; -- reg = readl(mhdp->regs + VER_H) & 0xff; -- mhdp->fw_version |= reg << 8; -- reg = readl(mhdp->regs + VER_LIB_L_ADDR) & 0xff; -- mhdp->fw_version |= reg << 16; -- reg = readl(mhdp->regs + VER_LIB_H_ADDR) & 0xff; -- mhdp->fw_version |= reg << 24; -- -- DRM_DEV_DEBUG(mhdp->dev, "firmware version: %x\n", mhdp->fw_version); -- -- return 0; --} -- --int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable) --{ -- u8 msg[5]; -- int ret, i; -- -- msg[0] = GENERAL_MAIN_CONTROL; -- msg[1] = MB_MODULE_ID_GENERAL; -- msg[2] = 0; -- msg[3] = 1; -- msg[4] = enable ? FW_ACTIVE : FW_STANDBY; -- -- for (i = 0; i < sizeof(msg); i++) { -- ret = cdp_dp_mailbox_write(mhdp, msg[i]); -- if (ret) -- goto err_set_firmware_active; -- } -- -- /* read the firmware state */ -- for (i = 0; i < sizeof(msg); i++) { -- ret = cdns_mhdp_mailbox_read(mhdp); -- if (ret < 0) -- goto err_set_firmware_active; -- -- msg[i] = ret; -- } -- -- ret = 0; -- --err_set_firmware_active: -- if (ret < 0) -- DRM_DEV_ERROR(mhdp->dev, "set firmware active failed\n"); -- return ret; --} -- --int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip) --{ -- u8 msg[8]; -- int ret; -- -- msg[0] = CDNS_DP_MAX_LINK_RATE; -- msg[1] = lanes | SCRAMBLER_EN; -- msg[2] = VOLTAGE_LEVEL_2; -- msg[3] = PRE_EMPHASIS_LEVEL_3; -- msg[4] = PTS1 | PTS2 | PTS3 | PTS4; -- msg[5] = FAST_LT_NOT_SUPPORT; -- msg[6] = flip ? LANE_MAPPING_FLIPPED : LANE_MAPPING_NORMAL; -- msg[7] = ENHANCED; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_SET_HOST_CAPABILITIES, -- sizeof(msg), msg); -- if (ret) -- goto err_set_host_cap; -- -- ret = cdns_mhdp_reg_write(mhdp, DP_AUX_SWAP_INVERSION_CONTROL, -- AUX_HOST_INVERT); -- --err_set_host_cap: -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "set host cap failed: %d\n", ret); -- return ret; --} -- --int cdns_mhdp_event_config(struct cdns_mhdp_device *mhdp) --{ -- u8 msg[5]; -- int ret; -- -- memset(msg, 0, sizeof(msg)); -- -- msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_ENABLE_EVENT, sizeof(msg), msg); -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "set event config failed: %d\n", ret); -- -- return ret; --} -- --u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp) --{ -- return readl(mhdp->regs + SW_EVENTS0); --} -- --int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp) --{ -- u8 status; -- int ret; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_HPD_STATE, 0, NULL); -- if (ret) -- goto err_get_hpd; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_HPD_STATE, -- sizeof(status)); -- if (ret) -- goto err_get_hpd; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, &status, sizeof(status)); -- if (ret) -- goto err_get_hpd; -- -- return status; -- --err_get_hpd: -- DRM_DEV_ERROR(mhdp->dev, "get hpd status failed: %d\n", ret); -- return ret; --} -- --int cdns_mhdp_get_edid_block(void *data, u8 *edid, -- unsigned int block, size_t length) --{ -- struct cdns_mhdp_device *mhdp = data; -- u8 msg[2], reg[2], i; -- int ret; -- -- for (i = 0; i < 4; i++) { -- msg[0] = block / 2; -- msg[1] = block % 2; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_GET_EDID, sizeof(msg), msg); -- if (ret) -- continue; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, -- MB_MODULE_ID_DP_TX, -- DPTX_GET_EDID, -- sizeof(reg) + length); -- if (ret) -- continue; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, reg, sizeof(reg)); -- if (ret) -- continue; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, edid, length); -- if (ret) -- continue; -- -- if (reg[0] == length && reg[1] == block / 2) -- break; -- } -- -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "get block[%d] edid failed: %d\n", -- block, ret); -- -- return ret; --} -- --static int cdns_mhdp_training_start(struct cdns_mhdp_device *mhdp) --{ -- unsigned long timeout; -- u8 msg, event[2]; -- int ret; -- -- msg = LINK_TRAINING_RUN; -- -- /* start training */ -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_TRAINING_CONTROL, sizeof(msg), &msg); -- if (ret) -- goto err_training_start; -- -- timeout = jiffies + msecs_to_jiffies(LINK_TRAINING_TIMEOUT_MS); -- while (time_before(jiffies, timeout)) { -- msleep(LINK_TRAINING_RETRY_MS); -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_EVENT, 0, NULL); -- if (ret) -- goto err_training_start; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, -- MB_MODULE_ID_DP_TX, -- DPTX_READ_EVENT, -- sizeof(event)); -- if (ret) -- goto err_training_start; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, event, -- sizeof(event)); -- if (ret) -- goto err_training_start; -- -- if (event[1] & EQ_PHASE_FINISHED) -- return 0; -- } -- -- ret = -ETIMEDOUT; -- --err_training_start: -- DRM_DEV_ERROR(mhdp->dev, "training failed: %d\n", ret); -- return ret; --} -- --static int cdns_mhdp_get_training_status(struct cdns_mhdp_device *mhdp) --{ -- u8 status[10]; -- int ret; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, DPTX_READ_LINK_STAT, -- 0, NULL); -- if (ret) -- goto err_get_training_status; -- -- ret = cdns_mhdp_mailbox_validate_receive(mhdp, MB_MODULE_ID_DP_TX, -- DPTX_READ_LINK_STAT, -- sizeof(status)); -- if (ret) -- goto err_get_training_status; -- -- ret = cdns_mhdp_mailbox_read_receive(mhdp, status, sizeof(status)); -- if (ret) -- goto err_get_training_status; -- -- mhdp->link.rate = drm_dp_bw_code_to_link_rate(status[0]); -- mhdp->link.num_lanes = status[1]; -- --err_get_training_status: -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "get training status failed: %d\n", ret); -- return ret; --} -- --int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp) --{ -- int ret; -- -- ret = cdns_mhdp_training_start(mhdp); -- if (ret) { -- DRM_DEV_ERROR(mhdp->dev, "Failed to start training %d\n", ret); -- return ret; -- } -- -- ret = cdns_mhdp_get_training_status(mhdp); -- if (ret) { -- DRM_DEV_ERROR(mhdp->dev, "Failed to get training stat %d\n", ret); -- return ret; -- } -- -- DRM_DEV_DEBUG_KMS(mhdp->dev, "rate:0x%x, lanes:%d\n", mhdp->link.rate, -- mhdp->link.num_lanes); -- return ret; --} -- --int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active) --{ -- u8 msg; -- int ret; -- -- msg = !!active; -- -- ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, DPTX_SET_VIDEO, -- sizeof(msg), &msg); -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "set video status failed: %d\n", ret); -- -- return ret; --} -- --static int cdns_mhdp_get_msa_misc(struct video_info *video, -- struct drm_display_mode *mode) --{ -- u32 msa_misc; -- u8 val[2] = {0}; -- -- switch (video->color_fmt) { -- case PXL_RGB: -- case Y_ONLY: -- val[0] = 0; -- break; -- /* set YUV default color space conversion to BT601 */ -- case YCBCR_4_4_4: -- val[0] = 6 + BT_601 * 8; -- break; -- case YCBCR_4_2_2: -- val[0] = 5 + BT_601 * 8; -- break; -- case YCBCR_4_2_0: -- val[0] = 5; -- break; -- }; -- -- switch (video->color_depth) { -- case 6: -- val[1] = 0; -- break; -- case 8: -- val[1] = 1; -- break; -- case 10: -- val[1] = 2; -- break; -- case 12: -- val[1] = 3; -- break; -- case 16: -- val[1] = 4; -- break; -- }; -- -- msa_misc = 2 * val[0] + 32 * val[1] + -- ((video->color_fmt == Y_ONLY) ? (1 << 14) : 0); -- -- return msa_misc; --} -- --int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp) --{ -- struct video_info *video = &mhdp->video_info; -- struct drm_display_mode *mode = &mhdp->mode; -- u64 symbol; -- u32 val, link_rate, rem; -- u8 bit_per_pix, tu_size_reg = TU_SIZE; -- int ret; -- -- bit_per_pix = (video->color_fmt == YCBCR_4_2_2) ? -- (video->color_depth * 2) : (video->color_depth * 3); -- -- link_rate = mhdp->link.rate / 1000; -- -- ret = cdns_mhdp_reg_write(mhdp, BND_HSYNC2VSYNC, VIF_BYPASS_INTERLACE); -- if (ret) -- goto err_config_video; -- -- ret = cdns_mhdp_reg_write(mhdp, HSYNC2VSYNC_POL_CTRL, 0); -- if (ret) -- goto err_config_video; -- -- /* -- * get a best tu_size and valid symbol: -- * 1. chose Lclk freq(162Mhz, 270Mhz, 540Mhz), set TU to 32 -- * 2. calculate VS(valid symbol) = TU * Pclk * Bpp / (Lclk * Lanes) -- * 3. if VS > *.85 or VS < *.1 or VS < 2 or TU < VS + 4, then set -- * TU += 2 and repeat 2nd step. -- */ -- do { -- tu_size_reg += 2; -- symbol = tu_size_reg * mode->clock * bit_per_pix; -- do_div(symbol, mhdp->link.num_lanes * link_rate * 8); -- rem = do_div(symbol, 1000); -- if (tu_size_reg > 64) { -- ret = -EINVAL; -- DRM_DEV_ERROR(mhdp->dev, -- "tu error, clk:%d, lanes:%d, rate:%d\n", -- mode->clock, mhdp->link.num_lanes, -- link_rate); -- goto err_config_video; -- } -- } while ((symbol <= 1) || (tu_size_reg - symbol < 4) || -- (rem > 850) || (rem < 100)); -- -- val = symbol + (tu_size_reg << 8); -- val |= TU_CNT_RST_EN; -- ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_TU, val); -- if (ret) -- goto err_config_video; -- -- /* set the FIFO Buffer size */ -- val = div_u64(mode->clock * (symbol + 1), 1000) + link_rate; -- val /= (mhdp->link.num_lanes * link_rate); -- val = div_u64(8 * (symbol + 1), bit_per_pix) - val; -- val += 2; -- ret = cdns_mhdp_reg_write(mhdp, DP_VC_TABLE(15), val); -- -- switch (video->color_depth) { -- case 6: -- val = BCS_6; -- break; -- case 8: -- val = BCS_8; -- break; -- case 10: -- val = BCS_10; -- break; -- case 12: -- val = BCS_12; -- break; -- case 16: -- val = BCS_16; -- break; -- }; -- -- val += video->color_fmt << 8; -- ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_PXL_REPR, val); -- if (ret) -- goto err_config_video; -- -- val = video->h_sync_polarity ? DP_FRAMER_SP_HSP : 0; -- val |= video->v_sync_polarity ? DP_FRAMER_SP_VSP : 0; -- ret = cdns_mhdp_reg_write(mhdp, DP_FRAMER_SP, val); -- if (ret) -- goto err_config_video; -- -- val = (mode->hsync_start - mode->hdisplay) << 16; -- val |= mode->htotal - mode->hsync_end; -- ret = cdns_mhdp_reg_write(mhdp, DP_FRONT_BACK_PORCH, val); -- if (ret) -- goto err_config_video; -- -- val = mode->hdisplay * bit_per_pix / 8; -- ret = cdns_mhdp_reg_write(mhdp, DP_BYTE_COUNT, val); -- if (ret) -- goto err_config_video; -- -- val = mode->htotal | ((mode->htotal - mode->hsync_start) << 16); -- ret = cdns_mhdp_reg_write(mhdp, MSA_HORIZONTAL_0, val); -- if (ret) -- goto err_config_video; -- -- val = mode->hsync_end - mode->hsync_start; -- val |= (mode->hdisplay << 16) | (video->h_sync_polarity << 15); -- ret = cdns_mhdp_reg_write(mhdp, MSA_HORIZONTAL_1, val); -- if (ret) -- goto err_config_video; -- -- val = mode->vtotal; -- val |= (mode->vtotal - mode->vsync_start) << 16; -- ret = cdns_mhdp_reg_write(mhdp, MSA_VERTICAL_0, val); -- if (ret) -- goto err_config_video; -- -- val = mode->vsync_end - mode->vsync_start; -- val |= (mode->vdisplay << 16) | (video->v_sync_polarity << 15); -- ret = cdns_mhdp_reg_write(mhdp, MSA_VERTICAL_1, val); -- if (ret) -- goto err_config_video; -- -- val = cdns_mhdp_get_msa_misc(video, mode); -- ret = cdns_mhdp_reg_write(mhdp, MSA_MISC, val); -- if (ret) -- goto err_config_video; -- -- ret = cdns_mhdp_reg_write(mhdp, STREAM_CONFIG, 1); -- if (ret) -- goto err_config_video; -- -- val = mode->hsync_end - mode->hsync_start; -- val |= mode->hdisplay << 16; -- ret = cdns_mhdp_reg_write(mhdp, DP_HORIZONTAL, val); -- if (ret) -- goto err_config_video; -- -- val = mode->vdisplay; -- val |= (mode->vtotal - mode->vsync_start) << 16; -- ret = cdns_mhdp_reg_write(mhdp, DP_VERTICAL_0, val); -- if (ret) -- goto err_config_video; -- -- val = mode->vtotal; -- ret = cdns_mhdp_reg_write(mhdp, DP_VERTICAL_1, val); -- if (ret) -- goto err_config_video; -- -- ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 2, 1, 0); -- --err_config_video: -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "config video failed: %d\n", ret); -- return ret; --} -- --int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio) --{ -- int ret; -- -- ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, 0); -- if (ret) { -- DRM_DEV_ERROR(mhdp->dev, "audio stop failed: %d\n", ret); -- return ret; -- } -- -- writel(0, mhdp->regs + SPDIF_CTRL_ADDR); -- -- /* clearn the audio config and reset */ -- writel(0, mhdp->regs + AUDIO_SRC_CNTL); -- writel(0, mhdp->regs + AUDIO_SRC_CNFG); -- writel(AUDIO_SW_RST, mhdp->regs + AUDIO_SRC_CNTL); -- writel(0, mhdp->regs + AUDIO_SRC_CNTL); -- -- /* reset smpl2pckt component */ -- writel(0, mhdp->regs + SMPL2PKT_CNTL); -- writel(AUDIO_SW_RST, mhdp->regs + SMPL2PKT_CNTL); -- writel(0, mhdp->regs + SMPL2PKT_CNTL); -- -- /* reset FIFO */ -- writel(AUDIO_SW_RST, mhdp->regs + FIFO_CNTL); -- writel(0, mhdp->regs + FIFO_CNTL); -- -- if (audio->format == AFMT_SPDIF) -- clk_disable_unprepare(mhdp->spdif_clk); -- -- return 0; --} -- --int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable) --{ -- int ret; -- -- ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 4, 1, enable); -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "audio mute failed: %d\n", ret); -- -- return ret; --} -- --static void cdns_mhdp_audio_config_i2s(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio) --{ -- int sub_pckt_num = 1, i2s_port_en_val = 0xf, i; -- u32 val; -- -- if (audio->channels == 2) { -- if (mhdp->link.num_lanes == 1) -- sub_pckt_num = 2; -- else -- sub_pckt_num = 4; -- -- i2s_port_en_val = 1; -- } else if (audio->channels == 4) { -- i2s_port_en_val = 3; -- } -- -- writel(0x0, mhdp->regs + SPDIF_CTRL_ADDR); -- -- writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); -- -- val = MAX_NUM_CH(audio->channels); -- val |= NUM_OF_I2S_PORTS(audio->channels); -- val |= AUDIO_TYPE_LPCM; -- val |= CFG_SUB_PCKT_NUM(sub_pckt_num); -- writel(val, mhdp->regs + SMPL2PKT_CNFG); -- -- if (audio->sample_width == 16) -- val = 0; -- else if (audio->sample_width == 24) -- val = 1 << 9; -- else -- val = 2 << 9; -- -- val |= AUDIO_CH_NUM(audio->channels); -- val |= I2S_DEC_PORT_EN(i2s_port_en_val); -- val |= TRANS_SMPL_WIDTH_32; -- writel(val, mhdp->regs + AUDIO_SRC_CNFG); -- -- for (i = 0; i < (audio->channels + 1) / 2; i++) { -- if (audio->sample_width == 16) -- val = (0x02 << 8) | (0x02 << 20); -- else if (audio->sample_width == 24) -- val = (0x0b << 8) | (0x0b << 20); -- -- val |= ((2 * i) << 4) | ((2 * i + 1) << 16); -- writel(val, mhdp->regs + STTS_BIT_CH(i)); -- } -- -- switch (audio->sample_rate) { -- case 32000: -- val = SAMPLING_FREQ(3) | -- ORIGINAL_SAMP_FREQ(0xc); -- break; -- case 44100: -- val = SAMPLING_FREQ(0) | -- ORIGINAL_SAMP_FREQ(0xf); -- break; -- case 48000: -- val = SAMPLING_FREQ(2) | -- ORIGINAL_SAMP_FREQ(0xd); -- break; -- case 88200: -- val = SAMPLING_FREQ(8) | -- ORIGINAL_SAMP_FREQ(0x7); -- break; -- case 96000: -- val = SAMPLING_FREQ(0xa) | -- ORIGINAL_SAMP_FREQ(5); -- break; -- case 176400: -- val = SAMPLING_FREQ(0xc) | -- ORIGINAL_SAMP_FREQ(3); -- break; -- case 192000: -- val = SAMPLING_FREQ(0xe) | -- ORIGINAL_SAMP_FREQ(1); -- break; -- } -- val |= 4; -- writel(val, mhdp->regs + COM_CH_STTS_BITS); -- -- writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); -- writel(I2S_DEC_START, mhdp->regs + AUDIO_SRC_CNTL); --} -- --static void cdns_mhdp_audio_config_spdif(struct cdns_mhdp_device *mhdp) --{ -- u32 val; -- -- writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); -- -- val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4); -- writel(val, mhdp->regs + SMPL2PKT_CNFG); -- writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); -- -- val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS; -- writel(val, mhdp->regs + SPDIF_CTRL_ADDR); -- -- clk_prepare_enable(mhdp->spdif_clk); -- clk_set_rate(mhdp->spdif_clk, CDNS_DP_SPDIF_CLK); --} -- --int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio) --{ -- int ret; -- -- /* reset the spdif clk before config */ -- if (audio->format == AFMT_SPDIF) { -- reset_control_assert(mhdp->spdif_rst); -- reset_control_deassert(mhdp->spdif_rst); -- } -- -- ret = cdns_mhdp_reg_write(mhdp, CM_LANE_CTRL, LANE_REF_CYC); -- if (ret) -- goto err_audio_config; -- -- ret = cdns_mhdp_reg_write(mhdp, CM_CTRL, 0); -- if (ret) -- goto err_audio_config; -- -- if (audio->format == AFMT_I2S) -- cdns_mhdp_audio_config_i2s(mhdp, audio); -- else if (audio->format == AFMT_SPDIF) -- cdns_mhdp_audio_config_spdif(mhdp); -- -- ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN); -- --err_audio_config: -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "audio config failed: %d\n", ret); -- return ret; --} ---- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h -+++ /dev/null -@@ -1,546 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-only */ --/* -- * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd -- * Author: Chris Zhong -- */ -- --#ifndef _CDN_DP_REG_H --#define _CDN_DP_REG_H -- --#include -- --#define ADDR_IMEM 0x10000 --#define ADDR_DMEM 0x20000 -- --/* APB CFG addr */ --#define APB_CTRL 0 --#define XT_INT_CTRL 0x04 --#define MAILBOX_FULL_ADDR 0x08 --#define MAILBOX_EMPTY_ADDR 0x0c --#define MAILBOX0_WR_DATA 0x10 --#define MAILBOX0_RD_DATA 0x14 --#define KEEP_ALIVE 0x18 --#define VER_L 0x1c --#define VER_H 0x20 --#define VER_LIB_L_ADDR 0x24 --#define VER_LIB_H_ADDR 0x28 --#define SW_DEBUG_L 0x2c --#define SW_DEBUG_H 0x30 --#define MAILBOX_INT_MASK 0x34 --#define MAILBOX_INT_STATUS 0x38 --#define SW_CLK_L 0x3c --#define SW_CLK_H 0x40 --#define SW_EVENTS0 0x44 --#define SW_EVENTS1 0x48 --#define SW_EVENTS2 0x4c --#define SW_EVENTS3 0x50 --#define XT_OCD_CTRL 0x60 --#define APB_INT_MASK 0x6c --#define APB_STATUS_MASK 0x70 -- --/* audio decoder addr */ --#define AUDIO_SRC_CNTL 0x30000 --#define AUDIO_SRC_CNFG 0x30004 --#define COM_CH_STTS_BITS 0x30008 --#define STTS_BIT_CH(x) (0x3000c + ((x) << 2)) --#define SPDIF_CTRL_ADDR 0x3004c --#define SPDIF_CH1_CS_3100_ADDR 0x30050 --#define SPDIF_CH1_CS_6332_ADDR 0x30054 --#define SPDIF_CH1_CS_9564_ADDR 0x30058 --#define SPDIF_CH1_CS_12796_ADDR 0x3005c --#define SPDIF_CH1_CS_159128_ADDR 0x30060 --#define SPDIF_CH1_CS_191160_ADDR 0x30064 --#define SPDIF_CH2_CS_3100_ADDR 0x30068 --#define SPDIF_CH2_CS_6332_ADDR 0x3006c --#define SPDIF_CH2_CS_9564_ADDR 0x30070 --#define SPDIF_CH2_CS_12796_ADDR 0x30074 --#define SPDIF_CH2_CS_159128_ADDR 0x30078 --#define SPDIF_CH2_CS_191160_ADDR 0x3007c --#define SMPL2PKT_CNTL 0x30080 --#define SMPL2PKT_CNFG 0x30084 --#define FIFO_CNTL 0x30088 --#define FIFO_STTS 0x3008c -- --/* source pif addr */ --#define SOURCE_PIF_WR_ADDR 0x30800 --#define SOURCE_PIF_WR_REQ 0x30804 --#define SOURCE_PIF_RD_ADDR 0x30808 --#define SOURCE_PIF_RD_REQ 0x3080c --#define SOURCE_PIF_DATA_WR 0x30810 --#define SOURCE_PIF_DATA_RD 0x30814 --#define SOURCE_PIF_FIFO1_FLUSH 0x30818 --#define SOURCE_PIF_FIFO2_FLUSH 0x3081c --#define SOURCE_PIF_STATUS 0x30820 --#define SOURCE_PIF_INTERRUPT_SOURCE 0x30824 --#define SOURCE_PIF_INTERRUPT_MASK 0x30828 --#define SOURCE_PIF_PKT_ALLOC_REG 0x3082c --#define SOURCE_PIF_PKT_ALLOC_WR_EN 0x30830 --#define SOURCE_PIF_SW_RESET 0x30834 -- --/* bellow registers need access by mailbox */ --/* source car addr */ --#define SOURCE_HDTX_CAR 0x0900 --#define SOURCE_DPTX_CAR 0x0904 --#define SOURCE_PHY_CAR 0x0908 --#define SOURCE_CEC_CAR 0x090c --#define SOURCE_CBUS_CAR 0x0910 --#define SOURCE_PKT_CAR 0x0918 --#define SOURCE_AIF_CAR 0x091c --#define SOURCE_CIPHER_CAR 0x0920 --#define SOURCE_CRYPTO_CAR 0x0924 -- --/* clock meters addr */ --#define CM_CTRL 0x0a00 --#define CM_I2S_CTRL 0x0a04 --#define CM_SPDIF_CTRL 0x0a08 --#define CM_VID_CTRL 0x0a0c --#define CM_LANE_CTRL 0x0a10 --#define I2S_NM_STABLE 0x0a14 --#define I2S_NCTS_STABLE 0x0a18 --#define SPDIF_NM_STABLE 0x0a1c --#define SPDIF_NCTS_STABLE 0x0a20 --#define NMVID_MEAS_STABLE 0x0a24 --#define I2S_MEAS 0x0a40 --#define SPDIF_MEAS 0x0a80 --#define NMVID_MEAS 0x0ac0 -- --/* source vif addr */ --#define BND_HSYNC2VSYNC 0x0b00 --#define HSYNC2VSYNC_F1_L1 0x0b04 --#define HSYNC2VSYNC_F2_L1 0x0b08 --#define HSYNC2VSYNC_STATUS 0x0b0c --#define HSYNC2VSYNC_POL_CTRL 0x0b10 -- --/* dptx phy addr */ --#define DP_TX_PHY_CONFIG_REG 0x2000 --#define DP_TX_PHY_SW_RESET 0x2004 --#define DP_TX_PHY_SCRAMBLER_SEED 0x2008 --#define DP_TX_PHY_TRAINING_01_04 0x200c --#define DP_TX_PHY_TRAINING_05_08 0x2010 --#define DP_TX_PHY_TRAINING_09_10 0x2014 --#define TEST_COR 0x23fc -- --/* dptx hpd addr */ --#define HPD_IRQ_DET_MIN_TIMER 0x2100 --#define HPD_IRQ_DET_MAX_TIMER 0x2104 --#define HPD_UNPLGED_DET_MIN_TIMER 0x2108 --#define HPD_STABLE_TIMER 0x210c --#define HPD_FILTER_TIMER 0x2110 --#define HPD_EVENT_MASK 0x211c --#define HPD_EVENT_DET 0x2120 -- --/* dpyx framer addr */ --#define DP_FRAMER_GLOBAL_CONFIG 0x2200 --#define DP_SW_RESET 0x2204 --#define DP_FRAMER_TU 0x2208 --#define DP_FRAMER_PXL_REPR 0x220c --#define DP_FRAMER_SP 0x2210 --#define AUDIO_PACK_CONTROL 0x2214 --#define DP_VC_TABLE(x) (0x2218 + ((x) << 2)) --#define DP_VB_ID 0x2258 --#define DP_MTPH_LVP_CONTROL 0x225c --#define DP_MTPH_SYMBOL_VALUES 0x2260 --#define DP_MTPH_ECF_CONTROL 0x2264 --#define DP_MTPH_ACT_CONTROL 0x2268 --#define DP_MTPH_STATUS 0x226c --#define DP_INTERRUPT_SOURCE 0x2270 --#define DP_INTERRUPT_MASK 0x2274 --#define DP_FRONT_BACK_PORCH 0x2278 --#define DP_BYTE_COUNT 0x227c -- --/* dptx stream addr */ --#define MSA_HORIZONTAL_0 0x2280 --#define MSA_HORIZONTAL_1 0x2284 --#define MSA_VERTICAL_0 0x2288 --#define MSA_VERTICAL_1 0x228c --#define MSA_MISC 0x2290 --#define STREAM_CONFIG 0x2294 --#define AUDIO_PACK_STATUS 0x2298 --#define VIF_STATUS 0x229c --#define PCK_STUFF_STATUS_0 0x22a0 --#define PCK_STUFF_STATUS_1 0x22a4 --#define INFO_PACK_STATUS 0x22a8 --#define RATE_GOVERNOR_STATUS 0x22ac --#define DP_HORIZONTAL 0x22b0 --#define DP_VERTICAL_0 0x22b4 --#define DP_VERTICAL_1 0x22b8 --#define DP_BLOCK_SDP 0x22bc -- --/* dptx glbl addr */ --#define DPTX_LANE_EN 0x2300 --#define DPTX_ENHNCD 0x2304 --#define DPTX_INT_MASK 0x2308 --#define DPTX_INT_STATUS 0x230c -- --/* dp aux addr */ --#define DP_AUX_HOST_CONTROL 0x2800 --#define DP_AUX_INTERRUPT_SOURCE 0x2804 --#define DP_AUX_INTERRUPT_MASK 0x2808 --#define DP_AUX_SWAP_INVERSION_CONTROL 0x280c --#define DP_AUX_SEND_NACK_TRANSACTION 0x2810 --#define DP_AUX_CLEAR_RX 0x2814 --#define DP_AUX_CLEAR_TX 0x2818 --#define DP_AUX_TIMER_STOP 0x281c --#define DP_AUX_TIMER_CLEAR 0x2820 --#define DP_AUX_RESET_SW 0x2824 --#define DP_AUX_DIVIDE_2M 0x2828 --#define DP_AUX_TX_PREACHARGE_LENGTH 0x282c --#define DP_AUX_FREQUENCY_1M_MAX 0x2830 --#define DP_AUX_FREQUENCY_1M_MIN 0x2834 --#define DP_AUX_RX_PRE_MIN 0x2838 --#define DP_AUX_RX_PRE_MAX 0x283c --#define DP_AUX_TIMER_PRESET 0x2840 --#define DP_AUX_NACK_FORMAT 0x2844 --#define DP_AUX_TX_DATA 0x2848 --#define DP_AUX_RX_DATA 0x284c --#define DP_AUX_TX_STATUS 0x2850 --#define DP_AUX_RX_STATUS 0x2854 --#define DP_AUX_RX_CYCLE_COUNTER 0x2858 --#define DP_AUX_MAIN_STATES 0x285c --#define DP_AUX_MAIN_TIMER 0x2860 --#define DP_AUX_AFE_OUT 0x2864 -- --/* crypto addr */ --#define CRYPTO_HDCP_REVISION 0x5800 --#define HDCP_CRYPTO_CONFIG 0x5804 --#define CRYPTO_INTERRUPT_SOURCE 0x5808 --#define CRYPTO_INTERRUPT_MASK 0x580c --#define CRYPTO22_CONFIG 0x5818 --#define CRYPTO22_STATUS 0x581c --#define SHA_256_DATA_IN 0x583c --#define SHA_256_DATA_OUT_(x) (0x5850 + ((x) << 2)) --#define AES_32_KEY_(x) (0x5870 + ((x) << 2)) --#define AES_32_DATA_IN 0x5880 --#define AES_32_DATA_OUT_(x) (0x5884 + ((x) << 2)) --#define CRYPTO14_CONFIG 0x58a0 --#define CRYPTO14_STATUS 0x58a4 --#define CRYPTO14_PRNM_OUT 0x58a8 --#define CRYPTO14_KM_0 0x58ac --#define CRYPTO14_KM_1 0x58b0 --#define CRYPTO14_AN_0 0x58b4 --#define CRYPTO14_AN_1 0x58b8 --#define CRYPTO14_YOUR_KSV_0 0x58bc --#define CRYPTO14_YOUR_KSV_1 0x58c0 --#define CRYPTO14_MI_0 0x58c4 --#define CRYPTO14_MI_1 0x58c8 --#define CRYPTO14_TI_0 0x58cc --#define CRYPTO14_KI_0 0x58d0 --#define CRYPTO14_KI_1 0x58d4 --#define CRYPTO14_BLOCKS_NUM 0x58d8 --#define CRYPTO14_KEY_MEM_DATA_0 0x58dc --#define CRYPTO14_KEY_MEM_DATA_1 0x58e0 --#define CRYPTO14_SHA1_MSG_DATA 0x58e4 --#define CRYPTO14_SHA1_V_VALUE_(x) (0x58e8 + ((x) << 2)) --#define TRNG_CTRL 0x58fc --#define TRNG_DATA_RDY 0x5900 --#define TRNG_DATA 0x5904 -- --/* cipher addr */ --#define HDCP_REVISION 0x60000 --#define INTERRUPT_SOURCE 0x60004 --#define INTERRUPT_MASK 0x60008 --#define HDCP_CIPHER_CONFIG 0x6000c --#define AES_128_KEY_0 0x60010 --#define AES_128_KEY_1 0x60014 --#define AES_128_KEY_2 0x60018 --#define AES_128_KEY_3 0x6001c --#define AES_128_RANDOM_0 0x60020 --#define AES_128_RANDOM_1 0x60024 --#define CIPHER14_KM_0 0x60028 --#define CIPHER14_KM_1 0x6002c --#define CIPHER14_STATUS 0x60030 --#define CIPHER14_RI_PJ_STATUS 0x60034 --#define CIPHER_MODE 0x60038 --#define CIPHER14_AN_0 0x6003c --#define CIPHER14_AN_1 0x60040 --#define CIPHER22_AUTH 0x60044 --#define CIPHER14_R0_DP_STATUS 0x60048 --#define CIPHER14_BOOTSTRAP 0x6004c -- --#define DPTX_FRMR_DATA_CLK_RSTN_EN BIT(11) --#define DPTX_FRMR_DATA_CLK_EN BIT(10) --#define DPTX_PHY_DATA_RSTN_EN BIT(9) --#define DPTX_PHY_DATA_CLK_EN BIT(8) --#define DPTX_PHY_CHAR_RSTN_EN BIT(7) --#define DPTX_PHY_CHAR_CLK_EN BIT(6) --#define SOURCE_AUX_SYS_CLK_RSTN_EN BIT(5) --#define SOURCE_AUX_SYS_CLK_EN BIT(4) --#define DPTX_SYS_CLK_RSTN_EN BIT(3) --#define DPTX_SYS_CLK_EN BIT(2) --#define CFG_DPTX_VIF_CLK_RSTN_EN BIT(1) --#define CFG_DPTX_VIF_CLK_EN BIT(0) -- --#define SOURCE_PHY_RSTN_EN BIT(1) --#define SOURCE_PHY_CLK_EN BIT(0) -- --#define SOURCE_PKT_SYS_RSTN_EN BIT(3) --#define SOURCE_PKT_SYS_CLK_EN BIT(2) --#define SOURCE_PKT_DATA_RSTN_EN BIT(1) --#define SOURCE_PKT_DATA_CLK_EN BIT(0) -- --#define SPDIF_CDR_CLK_RSTN_EN BIT(5) --#define SPDIF_CDR_CLK_EN BIT(4) --#define SOURCE_AIF_SYS_RSTN_EN BIT(3) --#define SOURCE_AIF_SYS_CLK_EN BIT(2) --#define SOURCE_AIF_CLK_RSTN_EN BIT(1) --#define SOURCE_AIF_CLK_EN BIT(0) -- --#define SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN BIT(3) --#define SOURCE_CIPHER_SYS_CLK_EN BIT(2) --#define SOURCE_CIPHER_CHAR_CLK_RSTN_EN BIT(1) --#define SOURCE_CIPHER_CHAR_CLK_EN BIT(0) -- --#define SOURCE_CRYPTO_SYS_CLK_RSTN_EN BIT(1) --#define SOURCE_CRYPTO_SYS_CLK_EN BIT(0) -- --#define APB_IRAM_PATH BIT(2) --#define APB_DRAM_PATH BIT(1) --#define APB_XT_RESET BIT(0) -- --#define MAILBOX_INT_MASK_BIT BIT(1) --#define PIF_INT_MASK_BIT BIT(0) --#define ALL_INT_MASK 3 -- --/* mailbox */ --#define MB_OPCODE_ID 0 --#define MB_MODULE_ID 1 --#define MB_SIZE_MSB_ID 2 --#define MB_SIZE_LSB_ID 3 --#define MB_DATA_ID 4 -- --#define MB_MODULE_ID_DP_TX 0x01 --#define MB_MODULE_ID_HDCP_TX 0x07 --#define MB_MODULE_ID_HDCP_RX 0x08 --#define MB_MODULE_ID_HDCP_GENERAL 0x09 --#define MB_MODULE_ID_GENERAL 0x0a -- --/* general opcode */ --#define GENERAL_MAIN_CONTROL 0x01 --#define GENERAL_TEST_ECHO 0x02 --#define GENERAL_BUS_SETTINGS 0x03 --#define GENERAL_TEST_ACCESS 0x04 -- --#define DPTX_SET_POWER_MNG 0x00 --#define DPTX_SET_HOST_CAPABILITIES 0x01 --#define DPTX_GET_EDID 0x02 --#define DPTX_READ_DPCD 0x03 --#define DPTX_WRITE_DPCD 0x04 --#define DPTX_ENABLE_EVENT 0x05 --#define DPTX_WRITE_REGISTER 0x06 --#define DPTX_READ_REGISTER 0x07 --#define DPTX_WRITE_FIELD 0x08 --#define DPTX_TRAINING_CONTROL 0x09 --#define DPTX_READ_EVENT 0x0a --#define DPTX_READ_LINK_STAT 0x0b --#define DPTX_SET_VIDEO 0x0c --#define DPTX_SET_AUDIO 0x0d --#define DPTX_GET_LAST_AUX_STAUS 0x0e --#define DPTX_SET_LINK_BREAK_POINT 0x0f --#define DPTX_FORCE_LANES 0x10 --#define DPTX_HPD_STATE 0x11 -- --#define FW_STANDBY 0 --#define FW_ACTIVE 1 -- --#define DPTX_EVENT_ENABLE_HPD BIT(0) --#define DPTX_EVENT_ENABLE_TRAINING BIT(1) -- --#define LINK_TRAINING_NOT_ACTIVE 0 --#define LINK_TRAINING_RUN 1 --#define LINK_TRAINING_RESTART 2 -- --#define CONTROL_VIDEO_IDLE 0 --#define CONTROL_VIDEO_VALID 1 -- --#define TU_CNT_RST_EN BIT(15) --#define VIF_BYPASS_INTERLACE BIT(13) --#define INTERLACE_FMT_DET BIT(12) --#define INTERLACE_DTCT_WIN 0x20 -- --#define DP_FRAMER_SP_INTERLACE_EN BIT(2) --#define DP_FRAMER_SP_HSP BIT(1) --#define DP_FRAMER_SP_VSP BIT(0) -- --/* capability */ --#define AUX_HOST_INVERT 3 --#define FAST_LT_SUPPORT 1 --#define FAST_LT_NOT_SUPPORT 0 --#define LANE_MAPPING_NORMAL 0x1b --#define LANE_MAPPING_FLIPPED 0xe4 --#define ENHANCED 1 --#define SCRAMBLER_EN BIT(4) -- --#define FULL_LT_STARTED BIT(0) --#define FASE_LT_STARTED BIT(1) --#define CLK_RECOVERY_FINISHED BIT(2) --#define EQ_PHASE_FINISHED BIT(3) --#define FASE_LT_START_FINISHED BIT(4) --#define CLK_RECOVERY_FAILED BIT(5) --#define EQ_PHASE_FAILED BIT(6) --#define FASE_LT_FAILED BIT(7) -- --#define DPTX_HPD_EVENT BIT(0) --#define DPTX_TRAINING_EVENT BIT(1) --#define HDCP_TX_STATUS_EVENT BIT(4) --#define HDCP2_TX_IS_KM_STORED_EVENT BIT(5) --#define HDCP2_TX_STORE_KM_EVENT BIT(6) --#define HDCP_TX_IS_RECEIVER_ID_VALID_EVENT BIT(7) -- --#define TU_SIZE 30 --#define CDNS_DP_MAX_LINK_RATE DP_LINK_BW_5_4 -- --/* audio */ --#define AUDIO_PACK_EN BIT(8) --#define SAMPLING_FREQ(x) (((x) & 0xf) << 16) --#define ORIGINAL_SAMP_FREQ(x) (((x) & 0xf) << 24) --#define SYNC_WR_TO_CH_ZERO BIT(1) --#define I2S_DEC_START BIT(1) --#define AUDIO_SW_RST BIT(0) --#define SMPL2PKT_EN BIT(1) --#define MAX_NUM_CH(x) (((x) & 0x1f) - 1) --#define NUM_OF_I2S_PORTS(x) ((((x) / 2 - 1) & 0x3) << 5) --#define AUDIO_TYPE_LPCM (2 << 7) --#define CFG_SUB_PCKT_NUM(x) ((((x) - 1) & 0x7) << 11) --#define AUDIO_CH_NUM(x) ((((x) - 1) & 0x1f) << 2) --#define TRANS_SMPL_WIDTH_16 0 --#define TRANS_SMPL_WIDTH_24 BIT(11) --#define TRANS_SMPL_WIDTH_32 (2 << 11) --#define I2S_DEC_PORT_EN(x) (((x) & 0xf) << 17) --#define SPDIF_ENABLE BIT(21) --#define SPDIF_AVG_SEL BIT(20) --#define SPDIF_JITTER_BYPASS BIT(19) --#define SPDIF_FIFO_MID_RANGE(x) (((x) & 0xff) << 11) --#define SPDIF_JITTER_THRSH(x) (((x) & 0xff) << 3) --#define SPDIF_JITTER_AVG_WIN(x) ((x) & 0x7) -- --/* Reference cycles when using lane clock as reference */ --#define LANE_REF_CYC 0x8000 -- --enum voltage_swing_level { -- VOLTAGE_LEVEL_0, -- VOLTAGE_LEVEL_1, -- VOLTAGE_LEVEL_2, -- VOLTAGE_LEVEL_3, --}; -- --enum pre_emphasis_level { -- PRE_EMPHASIS_LEVEL_0, -- PRE_EMPHASIS_LEVEL_1, -- PRE_EMPHASIS_LEVEL_2, -- PRE_EMPHASIS_LEVEL_3, --}; -- --enum pattern_set { -- PTS1 = BIT(0), -- PTS2 = BIT(1), -- PTS3 = BIT(2), -- PTS4 = BIT(3), -- DP_NONE = BIT(4) --}; -- --enum vic_color_depth { -- BCS_6 = 0x1, -- BCS_8 = 0x2, -- BCS_10 = 0x4, -- BCS_12 = 0x8, -- BCS_16 = 0x10, --}; -- --enum vic_bt_type { -- BT_601 = 0x0, -- BT_709 = 0x1, --}; -- --enum audio_format { -- AFMT_I2S = 0, -- AFMT_SPDIF = 1, -- AFMT_UNUSED, --}; -- --struct audio_info { -- enum audio_format format; -- int sample_rate; -- int channels; -- int sample_width; --}; -- --enum vic_pxl_encoding_format { -- PXL_RGB = 0x1, -- YCBCR_4_4_4 = 0x2, -- YCBCR_4_2_2 = 0x4, -- YCBCR_4_2_0 = 0x8, -- Y_ONLY = 0x10, --}; -- --struct video_info { -- bool h_sync_polarity; -- bool v_sync_polarity; -- bool interlaced; -- int color_depth; -- enum vic_pxl_encoding_format color_fmt; --}; -- --struct cdns_mhdp_host { -- unsigned int link_rate; -- u8 lanes_cnt; -- u8 volt_swing; -- u8 pre_emphasis; -- u8 pattern_supp; -- u8 fast_link; -- u8 lane_mapping; -- u8 enhanced; --}; -- --struct cdns_mhdp_sink { -- unsigned int link_rate; -- u8 lanes_cnt; -- u8 pattern_supp; -- u8 fast_link; -- u8 enhanced; --}; -- --struct cdns_mhdp_device { -- void __iomem *regs; -- -- struct device *dev; -- -- struct drm_dp_link link; -- struct drm_connector connector; -- struct clk *spdif_clk; -- struct reset_control *spdif_rst; -- -- struct drm_dp_aux aux; -- struct cdns_mhdp_host host; -- struct cdns_mhdp_sink sink; -- struct drm_bridge bridge; -- struct phy *phy; -- void __iomem *dbg_regs; -- -- struct video_info video_info; -- struct drm_display_mode mode; -- unsigned int fw_version; --}; -- --void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp); --void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk); --int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, -- u32 i_size, const u32 *d_mem, u32 d_size); --int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable); --int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip); --int cdns_mhdp_event_config(struct cdns_mhdp_device *mhdp); --u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp); --int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp); --int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value); --int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp, -- u32 addr, u8 *data, u16 len); --int cdns_mhdp_get_edid_block(void *mhdp, u8 *edid, -- unsigned int block, size_t length); --int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp); --int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active); --int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp); --int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio); --int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable); --int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio); --#endif /* _CDN_DP_REG_H */ ---- /dev/null -+++ b/include/drm/bridge/cdns-mhdp-cbs.h -@@ -0,0 +1,29 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Cadence MHDP DP bridge callbacks. -+ * -+ * Copyright: 2018 Cadence Design Systems, Inc. -+ * -+ * Author: Piotr Sroka -+ */ -+ -+#ifndef CDNS_MHDP_CBS_H -+#define CDNS_MHDP_CBS_H -+ -+#include -+ -+struct cdns_mhdp_mst_cbs_funcs { -+ struct drm_encoder *(*create_mst_encoder)(void *priv_data, -+ struct drm_bridge *bridge); -+ void (*destroy_mst_encoder)(void *priv_data, struct drm_bridge *bridge); -+}; -+ -+struct cdns_mhdp_mst_cbs { -+ struct cdns_mhdp_mst_cbs_funcs funcs; -+ void *priv_data; -+}; -+ -+int mhdp_bridge_attach_mst_cbs(struct drm_bridge *bridge, -+ struct cdns_mhdp_mst_cbs *cbs); -+ -+#endif ---- /dev/null -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -0,0 +1,704 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd -+ * Author: Chris Zhong -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef CDNS_MHDP_COMMON_H_ -+#define CDNS_MHDP_COMMON_H_ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define ADDR_IMEM 0x10000 -+#define ADDR_DMEM 0x20000 -+#define ADDR_PHY_AFE 0x80000 -+ -+/* APB CFG addr */ -+#define APB_CTRL 0 -+#define XT_INT_CTRL 0x04 -+#define MAILBOX_FULL_ADDR 0x08 -+#define MAILBOX_EMPTY_ADDR 0x0c -+#define MAILBOX0_WR_DATA 0x10 -+#define MAILBOX0_RD_DATA 0x14 -+#define KEEP_ALIVE 0x18 -+#define VER_L 0x1c -+#define VER_H 0x20 -+#define VER_LIB_L_ADDR 0x24 -+#define VER_LIB_H_ADDR 0x28 -+#define SW_DEBUG_L 0x2c -+#define SW_DEBUG_H 0x30 -+#define MAILBOX_INT_MASK 0x34 -+#define MAILBOX_INT_STATUS 0x38 -+#define SW_CLK_L 0x3c -+#define SW_CLK_H 0x40 -+#define SW_EVENTS0 0x44 -+#define SW_EVENTS1 0x48 -+#define SW_EVENTS2 0x4c -+#define SW_EVENTS3 0x50 -+#define XT_OCD_CTRL 0x60 -+#define APB_INT_MASK 0x6c -+#define APB_STATUS_MASK 0x70 -+ -+/* audio decoder addr */ -+#define AUDIO_SRC_CNTL 0x30000 -+#define AUDIO_SRC_CNFG 0x30004 -+#define COM_CH_STTS_BITS 0x30008 -+#define STTS_BIT_CH(x) (0x3000c + ((x) << 2)) -+#define SPDIF_CTRL_ADDR 0x3004c -+#define SPDIF_CH1_CS_3100_ADDR 0x30050 -+#define SPDIF_CH1_CS_6332_ADDR 0x30054 -+#define SPDIF_CH1_CS_9564_ADDR 0x30058 -+#define SPDIF_CH1_CS_12796_ADDR 0x3005c -+#define SPDIF_CH1_CS_159128_ADDR 0x30060 -+#define SPDIF_CH1_CS_191160_ADDR 0x30064 -+#define SPDIF_CH2_CS_3100_ADDR 0x30068 -+#define SPDIF_CH2_CS_6332_ADDR 0x3006c -+#define SPDIF_CH2_CS_9564_ADDR 0x30070 -+#define SPDIF_CH2_CS_12796_ADDR 0x30074 -+#define SPDIF_CH2_CS_159128_ADDR 0x30078 -+#define SPDIF_CH2_CS_191160_ADDR 0x3007c -+#define SMPL2PKT_CNTL 0x30080 -+#define SMPL2PKT_CNFG 0x30084 -+#define FIFO_CNTL 0x30088 -+#define FIFO_STTS 0x3008c -+ -+/* source pif addr */ -+#define SOURCE_PIF_WR_ADDR 0x30800 -+#define SOURCE_PIF_WR_REQ 0x30804 -+#define SOURCE_PIF_RD_ADDR 0x30808 -+#define SOURCE_PIF_RD_REQ 0x3080c -+#define SOURCE_PIF_DATA_WR 0x30810 -+#define SOURCE_PIF_DATA_RD 0x30814 -+#define SOURCE_PIF_FIFO1_FLUSH 0x30818 -+#define SOURCE_PIF_FIFO2_FLUSH 0x3081c -+#define SOURCE_PIF_STATUS 0x30820 -+#define SOURCE_PIF_INTERRUPT_SOURCE 0x30824 -+#define SOURCE_PIF_INTERRUPT_MASK 0x30828 -+#define SOURCE_PIF_PKT_ALLOC_REG 0x3082c -+#define SOURCE_PIF_PKT_ALLOC_WR_EN 0x30830 -+#define SOURCE_PIF_SW_RESET 0x30834 -+ -+/* bellow registers need access by mailbox */ -+/* source phy comp */ -+#define PHY_DATA_SEL 0x0818 -+#define LANES_CONFIG 0x0814 -+ -+/* source car addr */ -+#define SOURCE_HDTX_CAR 0x0900 -+#define SOURCE_DPTX_CAR 0x0904 -+#define SOURCE_PHY_CAR 0x0908 -+#define SOURCE_CEC_CAR 0x090c -+#define SOURCE_CBUS_CAR 0x0910 -+#define SOURCE_PKT_CAR 0x0918 -+#define SOURCE_AIF_CAR 0x091c -+#define SOURCE_CIPHER_CAR 0x0920 -+#define SOURCE_CRYPTO_CAR 0x0924 -+ -+/* mhdp tx_top_comp */ -+#define SCHEDULER_H_SIZE 0x1000 -+#define SCHEDULER_V_SIZE 0x1004 -+#define HDTX_SIGNAL_FRONT_WIDTH 0x100c -+#define HDTX_SIGNAL_SYNC_WIDTH 0x1010 -+#define HDTX_SIGNAL_BACK_WIDTH 0x1014 -+#define HDTX_CONTROLLER 0x1018 -+#define HDTX_HPD 0x1020 -+#define HDTX_CLOCK_REG_0 0x1024 -+#define HDTX_CLOCK_REG_1 0x1028 -+ -+/* clock meters addr */ -+#define CM_CTRL 0x0a00 -+#define CM_I2S_CTRL 0x0a04 -+#define CM_SPDIF_CTRL 0x0a08 -+#define CM_VID_CTRL 0x0a0c -+#define CM_LANE_CTRL 0x0a10 -+#define I2S_NM_STABLE 0x0a14 -+#define I2S_NCTS_STABLE 0x0a18 -+#define SPDIF_NM_STABLE 0x0a1c -+#define SPDIF_NCTS_STABLE 0x0a20 -+#define NMVID_MEAS_STABLE 0x0a24 -+#define I2S_MEAS 0x0a40 -+#define SPDIF_MEAS 0x0a80 -+#define NMVID_MEAS 0x0ac0 -+ -+/* source vif addr */ -+#define BND_HSYNC2VSYNC 0x0b00 -+#define HSYNC2VSYNC_F1_L1 0x0b04 -+#define HSYNC2VSYNC_F2_L1 0x0b08 -+#define HSYNC2VSYNC_STATUS 0x0b0c -+#define HSYNC2VSYNC_POL_CTRL 0x0b10 -+ -+/* dptx phy addr */ -+#define DP_TX_PHY_CONFIG_REG 0x2000 -+#define DP_TX_PHY_SW_RESET 0x2004 -+#define DP_TX_PHY_SCRAMBLER_SEED 0x2008 -+#define DP_TX_PHY_TRAINING_01_04 0x200c -+#define DP_TX_PHY_TRAINING_05_08 0x2010 -+#define DP_TX_PHY_TRAINING_09_10 0x2014 -+#define TEST_COR 0x23fc -+ -+/* dptx hpd addr */ -+#define HPD_IRQ_DET_MIN_TIMER 0x2100 -+#define HPD_IRQ_DET_MAX_TIMER 0x2104 -+#define HPD_UNPLGED_DET_MIN_TIMER 0x2108 -+#define HPD_STABLE_TIMER 0x210c -+#define HPD_FILTER_TIMER 0x2110 -+#define HPD_EVENT_MASK 0x211c -+#define HPD_EVENT_DET 0x2120 -+ -+/* dpyx framer addr */ -+#define DP_FRAMER_GLOBAL_CONFIG 0x2200 -+#define DP_SW_RESET 0x2204 -+#define DP_FRAMER_TU 0x2208 -+#define DP_FRAMER_PXL_REPR 0x220c -+#define DP_FRAMER_SP 0x2210 -+#define AUDIO_PACK_CONTROL 0x2214 -+#define DP_VC_TABLE(x) (0x2218 + ((x) << 2)) -+#define DP_VB_ID 0x2258 -+#define DP_MTPH_LVP_CONTROL 0x225c -+#define DP_MTPH_SYMBOL_VALUES 0x2260 -+#define DP_MTPH_ECF_CONTROL 0x2264 -+#define DP_MTPH_ACT_CONTROL 0x2268 -+#define DP_MTPH_STATUS 0x226c -+#define DP_INTERRUPT_SOURCE 0x2270 -+#define DP_INTERRUPT_MASK 0x2274 -+#define DP_FRONT_BACK_PORCH 0x2278 -+#define DP_BYTE_COUNT 0x227c -+ -+/* dptx stream addr */ -+#define MSA_HORIZONTAL_0 0x2280 -+#define MSA_HORIZONTAL_1 0x2284 -+#define MSA_VERTICAL_0 0x2288 -+#define MSA_VERTICAL_1 0x228c -+#define MSA_MISC 0x2290 -+#define STREAM_CONFIG 0x2294 -+#define AUDIO_PACK_STATUS 0x2298 -+#define VIF_STATUS 0x229c -+#define PCK_STUFF_STATUS_0 0x22a0 -+#define PCK_STUFF_STATUS_1 0x22a4 -+#define INFO_PACK_STATUS 0x22a8 -+#define RATE_GOVERNOR_STATUS 0x22ac -+#define DP_HORIZONTAL 0x22b0 -+#define DP_VERTICAL_0 0x22b4 -+#define DP_VERTICAL_1 0x22b8 -+#define DP_BLOCK_SDP 0x22bc -+ -+/* dptx glbl addr */ -+#define DPTX_LANE_EN 0x2300 -+#define DPTX_ENHNCD 0x2304 -+#define DPTX_INT_MASK 0x2308 -+#define DPTX_INT_STATUS 0x230c -+ -+/* dp aux addr */ -+#define DP_AUX_HOST_CONTROL 0x2800 -+#define DP_AUX_INTERRUPT_SOURCE 0x2804 -+#define DP_AUX_INTERRUPT_MASK 0x2808 -+#define DP_AUX_SWAP_INVERSION_CONTROL 0x280c -+#define DP_AUX_SEND_NACK_TRANSACTION 0x2810 -+#define DP_AUX_CLEAR_RX 0x2814 -+#define DP_AUX_CLEAR_TX 0x2818 -+#define DP_AUX_TIMER_STOP 0x281c -+#define DP_AUX_TIMER_CLEAR 0x2820 -+#define DP_AUX_RESET_SW 0x2824 -+#define DP_AUX_DIVIDE_2M 0x2828 -+#define DP_AUX_TX_PREACHARGE_LENGTH 0x282c -+#define DP_AUX_FREQUENCY_1M_MAX 0x2830 -+#define DP_AUX_FREQUENCY_1M_MIN 0x2834 -+#define DP_AUX_RX_PRE_MIN 0x2838 -+#define DP_AUX_RX_PRE_MAX 0x283c -+#define DP_AUX_TIMER_PRESET 0x2840 -+#define DP_AUX_NACK_FORMAT 0x2844 -+#define DP_AUX_TX_DATA 0x2848 -+#define DP_AUX_RX_DATA 0x284c -+#define DP_AUX_TX_STATUS 0x2850 -+#define DP_AUX_RX_STATUS 0x2854 -+#define DP_AUX_RX_CYCLE_COUNTER 0x2858 -+#define DP_AUX_MAIN_STATES 0x285c -+#define DP_AUX_MAIN_TIMER 0x2860 -+#define DP_AUX_AFE_OUT 0x2864 -+ -+/* crypto addr */ -+#define CRYPTO_HDCP_REVISION 0x5800 -+#define HDCP_CRYPTO_CONFIG 0x5804 -+#define CRYPTO_INTERRUPT_SOURCE 0x5808 -+#define CRYPTO_INTERRUPT_MASK 0x580c -+#define CRYPTO22_CONFIG 0x5818 -+#define CRYPTO22_STATUS 0x581c -+#define SHA_256_DATA_IN 0x583c -+#define SHA_256_DATA_OUT_(x) (0x5850 + ((x) << 2)) -+#define AES_32_KEY_(x) (0x5870 + ((x) << 2)) -+#define AES_32_DATA_IN 0x5880 -+#define AES_32_DATA_OUT_(x) (0x5884 + ((x) << 2)) -+#define CRYPTO14_CONFIG 0x58a0 -+#define CRYPTO14_STATUS 0x58a4 -+#define CRYPTO14_PRNM_OUT 0x58a8 -+#define CRYPTO14_KM_0 0x58ac -+#define CRYPTO14_KM_1 0x58b0 -+#define CRYPTO14_AN_0 0x58b4 -+#define CRYPTO14_AN_1 0x58b8 -+#define CRYPTO14_YOUR_KSV_0 0x58bc -+#define CRYPTO14_YOUR_KSV_1 0x58c0 -+#define CRYPTO14_MI_0 0x58c4 -+#define CRYPTO14_MI_1 0x58c8 -+#define CRYPTO14_TI_0 0x58cc -+#define CRYPTO14_KI_0 0x58d0 -+#define CRYPTO14_KI_1 0x58d4 -+#define CRYPTO14_BLOCKS_NUM 0x58d8 -+#define CRYPTO14_KEY_MEM_DATA_0 0x58dc -+#define CRYPTO14_KEY_MEM_DATA_1 0x58e0 -+#define CRYPTO14_SHA1_MSG_DATA 0x58e4 -+#define CRYPTO14_SHA1_V_VALUE_(x) (0x58e8 + ((x) << 2)) -+#define TRNG_CTRL 0x58fc -+#define TRNG_DATA_RDY 0x5900 -+#define TRNG_DATA 0x5904 -+ -+/* cipher addr */ -+#define HDCP_REVISION 0x60000 -+#define INTERRUPT_SOURCE 0x60004 -+#define INTERRUPT_MASK 0x60008 -+#define HDCP_CIPHER_CONFIG 0x6000c -+#define AES_128_KEY_0 0x60010 -+#define AES_128_KEY_1 0x60014 -+#define AES_128_KEY_2 0x60018 -+#define AES_128_KEY_3 0x6001c -+#define AES_128_RANDOM_0 0x60020 -+#define AES_128_RANDOM_1 0x60024 -+#define CIPHER14_KM_0 0x60028 -+#define CIPHER14_KM_1 0x6002c -+#define CIPHER14_STATUS 0x60030 -+#define CIPHER14_RI_PJ_STATUS 0x60034 -+#define CIPHER_MODE 0x60038 -+#define CIPHER14_AN_0 0x6003c -+#define CIPHER14_AN_1 0x60040 -+#define CIPHER22_AUTH 0x60044 -+#define CIPHER14_R0_DP_STATUS 0x60048 -+#define CIPHER14_BOOTSTRAP 0x6004c -+ -+#define DPTX_FRMR_DATA_CLK_RSTN_EN BIT(11) -+#define DPTX_FRMR_DATA_CLK_EN BIT(10) -+#define DPTX_PHY_DATA_RSTN_EN BIT(9) -+#define DPTX_PHY_DATA_CLK_EN BIT(8) -+#define DPTX_PHY_CHAR_RSTN_EN BIT(7) -+#define DPTX_PHY_CHAR_CLK_EN BIT(6) -+#define SOURCE_AUX_SYS_CLK_RSTN_EN BIT(5) -+#define SOURCE_AUX_SYS_CLK_EN BIT(4) -+#define DPTX_SYS_CLK_RSTN_EN BIT(3) -+#define DPTX_SYS_CLK_EN BIT(2) -+#define CFG_DPTX_VIF_CLK_RSTN_EN BIT(1) -+#define CFG_DPTX_VIF_CLK_EN BIT(0) -+ -+#define SOURCE_PHY_RSTN_EN BIT(1) -+#define SOURCE_PHY_CLK_EN BIT(0) -+ -+#define SOURCE_PKT_SYS_RSTN_EN BIT(3) -+#define SOURCE_PKT_SYS_CLK_EN BIT(2) -+#define SOURCE_PKT_DATA_RSTN_EN BIT(1) -+#define SOURCE_PKT_DATA_CLK_EN BIT(0) -+ -+#define SPDIF_CDR_CLK_RSTN_EN BIT(5) -+#define SPDIF_CDR_CLK_EN BIT(4) -+#define SOURCE_AIF_SYS_RSTN_EN BIT(3) -+#define SOURCE_AIF_SYS_CLK_EN BIT(2) -+#define SOURCE_AIF_CLK_RSTN_EN BIT(1) -+#define SOURCE_AIF_CLK_EN BIT(0) -+ -+#define SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN BIT(3) -+#define SOURCE_CIPHER_SYS_CLK_EN BIT(2) -+#define SOURCE_CIPHER_CHAR_CLK_RSTN_EN BIT(1) -+#define SOURCE_CIPHER_CHAR_CLK_EN BIT(0) -+ -+#define SOURCE_CRYPTO_SYS_CLK_RSTN_EN BIT(1) -+#define SOURCE_CRYPTO_SYS_CLK_EN BIT(0) -+ -+#define APB_IRAM_PATH BIT(2) -+#define APB_DRAM_PATH BIT(1) -+#define APB_XT_RESET BIT(0) -+ -+#define MAILBOX_INT_MASK_BIT BIT(1) -+#define PIF_INT_MASK_BIT BIT(0) -+#define ALL_INT_MASK 3 -+ -+/* mailbox */ -+#define MB_OPCODE_ID 0 -+#define MB_MODULE_ID 1 -+#define MB_SIZE_MSB_ID 2 -+#define MB_SIZE_LSB_ID 3 -+#define MB_DATA_ID 4 -+ -+#define MB_MODULE_ID_DP_TX 0x01 -+#define MB_MODULE_ID_HDMI_TX 0x03 -+#define MB_MODULE_ID_HDCP_TX 0x07 -+#define MB_MODULE_ID_HDCP_RX 0x08 -+#define MB_MODULE_ID_HDCP_GENERAL 0x09 -+#define MB_MODULE_ID_GENERAL 0x0A -+ -+/* general opcode */ -+#define GENERAL_MAIN_CONTROL 0x01 -+#define GENERAL_TEST_ECHO 0x02 -+#define GENERAL_BUS_SETTINGS 0x03 -+#define GENERAL_TEST_ACCESS 0x04 -+#define GENERAL_WRITE_REGISTER 0x05 -+#define GENERAL_WRITE_FIELD 0x06 -+#define GENERAL_READ_REGISTER 0x07 -+#define GENERAL_GET_HPD_STATE 0x11 -+ -+/* DPTX opcode */ -+#define DPTX_SET_POWER_MNG 0x00 -+#define DPTX_SET_HOST_CAPABILITIES 0x01 -+#define DPTX_GET_EDID 0x02 -+#define DPTX_READ_DPCD 0x03 -+#define DPTX_WRITE_DPCD 0x04 -+#define DPTX_ENABLE_EVENT 0x05 -+#define DPTX_WRITE_REGISTER 0x06 -+#define DPTX_READ_REGISTER 0x07 -+#define DPTX_WRITE_FIELD 0x08 -+#define DPTX_TRAINING_CONTROL 0x09 -+#define DPTX_READ_EVENT 0x0a -+#define DPTX_READ_LINK_STAT 0x0b -+#define DPTX_SET_VIDEO 0x0c -+#define DPTX_SET_AUDIO 0x0d -+#define DPTX_GET_LAST_AUX_STAUS 0x0e -+#define DPTX_SET_LINK_BREAK_POINT 0x0f -+#define DPTX_FORCE_LANES 0x10 -+#define DPTX_HPD_STATE 0x11 -+#define DPTX_ADJUST_LT 0x12 -+ -+/* HDMI TX opcode */ -+#define HDMI_TX_READ 0x00 -+#define HDMI_TX_WRITE 0x01 -+#define HDMI_TX_UPDATE_READ 0x02 -+#define HDMI_TX_EDID 0x03 -+#define HDMI_TX_EVENTS 0x04 -+#define HDMI_TX_HPD_STATUS 0x05 -+#define HDMI_TX_DEBUG_ECHO 0xAA -+#define HDMI_TX_TEST 0xBB -+#define HDMI_TX_EDID_INTERNAL 0xF0 -+ -+#define FW_STANDBY 0 -+#define FW_ACTIVE 1 -+ -+#define DPTX_EVENT_ENABLE_HPD BIT(0) -+#define DPTX_EVENT_ENABLE_TRAINING BIT(1) -+ -+#define LINK_TRAINING_NOT_ACTIVE 0 -+#define LINK_TRAINING_RUN 1 -+#define LINK_TRAINING_RESTART 2 -+ -+#define CONTROL_VIDEO_IDLE 0 -+#define CONTROL_VIDEO_VALID 1 -+ -+#define TU_CNT_RST_EN BIT(15) -+#define VIF_BYPASS_INTERLACE BIT(13) -+#define INTERLACE_FMT_DET BIT(12) -+#define INTERLACE_DTCT_WIN 0x20 -+ -+#define DP_FRAMER_SP_INTERLACE_EN BIT(2) -+#define DP_FRAMER_SP_HSP BIT(1) -+#define DP_FRAMER_SP_VSP BIT(0) -+ -+/* capability */ -+#define AUX_HOST_INVERT 3 -+#define FAST_LT_SUPPORT 1 -+#define FAST_LT_NOT_SUPPORT 0 -+#define LANE_MAPPING_NORMAL 0x1b -+#define LANE_MAPPING_FLIPPED 0xe4 -+#define ENHANCED 1 -+#define SCRAMBLER_EN BIT(4) -+ -+#define FULL_LT_STARTED BIT(0) -+#define FASE_LT_STARTED BIT(1) -+#define CLK_RECOVERY_FINISHED BIT(2) -+#define EQ_PHASE_FINISHED BIT(3) -+#define FASE_LT_START_FINISHED BIT(4) -+#define CLK_RECOVERY_FAILED BIT(5) -+#define EQ_PHASE_FAILED BIT(6) -+#define FASE_LT_FAILED BIT(7) -+ -+#define DPTX_HPD_EVENT BIT(0) -+#define DPTX_TRAINING_EVENT BIT(1) -+#define HDCP_TX_STATUS_EVENT BIT(4) -+#define HDCP2_TX_IS_KM_STORED_EVENT BIT(5) -+#define HDCP2_TX_STORE_KM_EVENT BIT(6) -+#define HDCP_TX_IS_RECEIVER_ID_VALID_EVENT BIT(7) -+ -+#define TU_SIZE 30 -+#define CDNS_DP_MAX_LINK_RATE DP_LINK_BW_5_4 -+ -+#define F_HDMI_ENCODING(x) (((x) & ((1 << 2) - 1)) << 16) -+#define F_VIF_DATA_WIDTH(x) (((x) & ((1 << 2) - 1)) << 2) -+#define F_HDMI_MODE(x) (((x) & ((1 << 2) - 1)) << 0) -+#define F_GCP_EN(x) (((x) & ((1 << 1) - 1)) << 12) -+#define F_DATA_EN(x) (((x) & ((1 << 1) - 1)) << 15) -+#define F_HDMI2_PREAMBLE_EN(x) (((x) & ((1 << 1) - 1)) << 18) -+#define F_PIC_3D(x) (((x) & ((1 << 4) - 1)) << 7) -+#define F_BCH_EN(x) (((x) & ((1 << 1) - 1)) << 11) -+#define F_SOURCE_PHY_MHDP_SEL(x) (((x) & ((1 << 2) - 1)) << 3) -+#define F_HPD_VALID_WIDTH(x) (((x) & ((1 << 12) - 1)) << 0) -+#define F_HPD_GLITCH_WIDTH(x) (((x) & ((1 << 8) - 1)) << 12) -+#define F_HDMI2_CTRL_IL_MODE(x) (((x) & ((1 << 1) - 1)) << 19) -+#define F_SOURCE_PHY_LANE0_SWAP(x) (((x) & ((1 << 2) - 1)) << 0) -+#define F_SOURCE_PHY_LANE1_SWAP(x) (((x) & ((1 << 2) - 1)) << 2) -+#define F_SOURCE_PHY_LANE2_SWAP(x) (((x) & ((1 << 2) - 1)) << 4) -+#define F_SOURCE_PHY_LANE3_SWAP(x) (((x) & ((1 << 2) - 1)) << 6) -+#define F_SOURCE_PHY_COMB_BYPASS(x) (((x) & ((1 << 1) - 1)) << 21) -+#define F_SOURCE_PHY_20_10(x) (((x) & ((1 << 1) - 1)) << 22) -+#define F_PKT_ALLOC_ADDRESS(x) (((x) & ((1 << 4) - 1)) << 0) -+#define F_ACTIVE_IDLE_TYPE(x) (((x) & ((1 << 1) - 1)) << 17) -+#define F_FIFO1_FLUSH(x) (((x) & ((1 << 1) - 1)) << 0) -+#define F_PKT_ALLOC_WR_EN(x) (((x) & ((1 << 1) - 1)) << 0) -+#define F_DATA_WR(x) (x) -+#define F_WR_ADDR(x) (((x) & ((1 << 4) - 1)) << 0) -+#define F_HOST_WR(x) (((x) & ((1 << 1) - 1)) << 0) -+#define F_TYPE_VALID(x) (((x) & ((1 << 1) - 1)) << 16) -+#define F_PACKET_TYPE(x) (((x) & ((1 << 8) - 1)) << 8) -+ -+/* audio */ -+#define AUDIO_PACK_EN BIT(8) -+#define SAMPLING_FREQ(x) (((x) & 0xf) << 16) -+#define ORIGINAL_SAMP_FREQ(x) (((x) & 0xf) << 24) -+#define SYNC_WR_TO_CH_ZERO BIT(1) -+#define I2S_DEC_START BIT(1) -+#define AUDIO_SW_RST BIT(0) -+#define SMPL2PKT_EN BIT(1) -+#define MAX_NUM_CH(x) (((x) & 0x1f) - 1) -+#define NUM_OF_I2S_PORTS(x) ((((x) / 2 - 1) & 0x3) << 5) -+#define AUDIO_TYPE_LPCM (2 << 7) -+#define CFG_SUB_PCKT_NUM(x) ((((x) - 1) & 0x7) << 11) -+#define AUDIO_CH_NUM(x) ((((x) - 1) & 0x1f) << 2) -+#define TRANS_SMPL_WIDTH_16 0 -+#define TRANS_SMPL_WIDTH_24 BIT(11) -+#define TRANS_SMPL_WIDTH_32 (2 << 11) -+#define I2S_DEC_PORT_EN(x) (((x) & 0xf) << 17) -+#define SPDIF_ENABLE BIT(21) -+#define SPDIF_AVG_SEL BIT(20) -+#define SPDIF_JITTER_BYPASS BIT(19) -+#define SPDIF_FIFO_MID_RANGE(x) (((x) & 0xff) << 11) -+#define SPDIF_JITTER_THRSH(x) (((x) & 0xff) << 3) -+#define SPDIF_JITTER_AVG_WIN(x) ((x) & 0x7) -+ -+/* Reference cycles when using lane clock as reference */ -+#define LANE_REF_CYC 0x8000 -+ -+#define HOTPLUG_DEBOUNCE_MS 200 -+ -+enum voltage_swing_level { -+ VOLTAGE_LEVEL_0, -+ VOLTAGE_LEVEL_1, -+ VOLTAGE_LEVEL_2, -+ VOLTAGE_LEVEL_3, -+}; -+ -+enum pre_emphasis_level { -+ PRE_EMPHASIS_LEVEL_0, -+ PRE_EMPHASIS_LEVEL_1, -+ PRE_EMPHASIS_LEVEL_2, -+ PRE_EMPHASIS_LEVEL_3, -+}; -+ -+enum pattern_set { -+ PTS1 = BIT(0), -+ PTS2 = BIT(1), -+ PTS3 = BIT(2), -+ PTS4 = BIT(3), -+ DP_NONE = BIT(4) -+}; -+ -+enum vic_color_depth { -+ BCS_6 = 0x1, -+ BCS_8 = 0x2, -+ BCS_10 = 0x4, -+ BCS_12 = 0x8, -+ BCS_16 = 0x10, -+}; -+ -+enum vic_bt_type { -+ BT_601 = 0x0, -+ BT_709 = 0x1, -+}; -+ -+enum audio_format { -+ AFMT_I2S = 0, -+ AFMT_SPDIF = 1, -+ AFMT_UNUSED, -+}; -+ -+enum { -+ MODE_DVI, -+ MODE_HDMI_1_4, -+ MODE_HDMI_2_0, -+}; -+ -+struct audio_info { -+ enum audio_format format; -+ int sample_rate; -+ int channels; -+ int sample_width; -+}; -+ -+enum vic_pxl_encoding_format { -+ PXL_RGB = 0x1, -+ YCBCR_4_4_4 = 0x2, -+ YCBCR_4_2_2 = 0x4, -+ YCBCR_4_2_0 = 0x8, -+ Y_ONLY = 0x10, -+}; -+ -+struct video_info { -+ bool h_sync_polarity; -+ bool v_sync_polarity; -+ bool interlaced; -+ int color_depth; -+ enum vic_pxl_encoding_format color_fmt; -+}; -+ -+struct cdns_mhdp_host { -+ unsigned int link_rate; -+ u8 lanes_cnt; -+ u8 volt_swing; -+ u8 pre_emphasis; -+ u8 pattern_supp; -+ u8 fast_link; -+ u8 lane_mapping; -+ u8 enhanced; -+}; -+ -+struct cdns_mhdp_sink { -+ unsigned int link_rate; -+ u8 lanes_cnt; -+ u8 pattern_supp; -+ u8 fast_link; -+ u8 enhanced; -+}; -+ -+struct cdns_mhdp_bridge; -+struct cdns_mhdp_connector; -+ -+struct cdns_mhdp_bridge { -+ struct cdns_mhdp_device *mhdp; -+ struct drm_bridge base; -+ int pbn; -+ int8_t stream_id; -+ struct cdns_mhdp_connector *connector; -+ bool is_active; -+}; -+ -+struct cdns_mhdp_connector { -+ struct drm_connector base; -+ bool is_mst_connector; -+ struct drm_dp_mst_port *port; -+ struct cdns_mhdp_bridge *bridge; -+}; -+ -+struct cdns_mhdp_device { -+ void __iomem *regs; -+ -+ struct device *dev; -+ -+ struct cdns_mhdp_connector connector; -+ struct clk *spdif_clk; -+ struct reset_control *spdif_rst; -+ -+ struct platform_device *audio_pdev; -+ struct audio_info audio_info; -+ -+ struct cdns_mhdp_bridge bridge; -+ struct phy *phy; -+ -+ struct video_info video_info; -+ struct drm_display_mode mode; -+ unsigned int fw_version; -+ -+ struct drm_dp_mst_topology_mgr mst_mgr; -+ struct delayed_work hotplug_work; -+ -+ bool link_up; -+ bool power_up; -+ bool plugged; -+ -+ union { -+ struct _dp_data { -+ struct drm_dp_link link; -+ struct drm_dp_aux aux; -+ struct cdns_mhdp_host host; -+ struct cdns_mhdp_sink sink; -+ struct cdns_mhdp_mst_cbs cbs; -+ bool is_mst; -+ bool can_mst; -+ u32 lane_mapping; -+ u32 link_rate; -+ u32 num_lanes; -+ } dp; -+ struct _hdmi_data { -+ u32 char_rate; -+ u32 hdmi_type; -+ } hdmi; -+ }; -+}; -+ -+void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp); -+void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk); -+int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, -+ u32 i_size, const u32 *d_mem, u32 d_size); -+int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable); -+int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip); -+int cdns_mhdp_event_config(struct cdns_mhdp_device *mhdp); -+u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_dpcd_write(struct cdns_mhdp_device *mhdp, u32 addr, u8 value); -+int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp, -+ u32 addr, u8 *data, u16 len); -+int cdns_mhdp_get_edid_block(void *mhdp, u8 *edid, -+ unsigned int block, size_t length); -+int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active); -+int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio); -+int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable); -+int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio); -+int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr); -+int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u32 addr, u32 val); -+int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr, -+ u8 start_bit, u8 bits_no, u32 val); -+int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, u8 nlanes, -+ u16 udelay, u8 *lanes_data, -+ u8 *dpcd); -+ -+int cdns_mhdp_read_hpd(struct cdns_mhdp_device *mhdp); -+u32 cdns_phy_reg_read(struct cdns_mhdp_device *mhdp, u32 addr); -+int cdns_phy_reg_write(struct cdns_mhdp_device *mhdp, u32 addr, u32 val); -+int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id, -+ u8 opcode, u16 size, u8 *message); -+int cdns_mhdp_mailbox_read_receive(struct cdns_mhdp_device *mhdp, -+ u8 *buff, u16 buff_size); -+int cdns_mhdp_mailbox_validate_receive(struct cdns_mhdp_device *mhdp, -+ u8 module_id, u8 opcode, -+ u16 req_size); -+int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp); -+ -+int cdns_hdmi_get_edid_block(void *data, u8 *edid, u32 block, size_t length); -+int cdns_hdmi_scdc_read(struct cdns_mhdp_device *mhdp, u8 addr, u8 *data); -+int cdns_hdmi_scdc_write(struct cdns_mhdp_device *mhdp, u8 addr, u8 value); -+int cdns_hdmi_ctrl_init(struct cdns_mhdp_device *mhdp, int protocol, u32 char_rate); -+int cdns_hdmi_mode_config(struct cdns_mhdp_device *mhdp, struct drm_display_mode *mode, -+ struct video_info *video_info); -+int cdns_hdmi_disable_gcp(struct cdns_mhdp_device *mhdp); -+int cdns_hdmi_enable_gcp(struct cdns_mhdp_device *mhdp); -+ -+bool cdns_mhdp_check_alive(struct cdns_mhdp_device *mhdp); -+#endif /* CDNS_MHDP_COMMON_H_ */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0004-drm-bridge-Add-Cadence-DP-HDMI-core-driver.patch b/target/linux/layerscape/patches-5.4/805-display-0004-drm-bridge-Add-Cadence-DP-HDMI-core-driver.patch deleted file mode 100644 index 3c0daf7daf..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0004-drm-bridge-Add-Cadence-DP-HDMI-core-driver.patch +++ /dev/null @@ -1,1417 +0,0 @@ -From 9d6e1670f14a77c092ce32b559de52d7ddea3748 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Fri, 23 Aug 2019 13:57:49 +0800 -Subject: [PATCH] drm: bridge: Add Cadence DP/HDMI core driver - -Add HDMI and DP core driver. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/Kconfig | 6 + - drivers/gpu/drm/bridge/cadence/Makefile | 2 + - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 605 ++++++++++++++++++++++ - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 643 ++++++++++++++++++++++++ - include/drm/bridge/cdns-mhdp-imx.h | 121 +++++ - 5 files changed, 1377 insertions(+) - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c - create mode 100644 include/drm/bridge/cdns-mhdp-imx.h - ---- a/drivers/gpu/drm/bridge/cadence/Kconfig -+++ b/drivers/gpu/drm/bridge/cadence/Kconfig -@@ -5,3 +5,9 @@ config DRM_CDNS_MHDP - depends on OF - help - Support Cadence MHDP API library. -+ -+config DRM_CDNS_HDMI -+ tristate "Cadence HDMI DRM driver" -+ -+config DRM_CDNS_DP -+ tristate "Cadence DP DRM driver" ---- a/drivers/gpu/drm/bridge/cadence/Makefile -+++ b/drivers/gpu/drm/bridge/cadence/Makefile -@@ -1,3 +1,5 @@ - #ccflags-y := -Iinclude/drm - - obj-$(CONFIG_DRM_CDNS_MHDP) += cdns-mhdp-common.o cdns-mhdp-hdmi.o -+obj-$(CONFIG_DRM_CDNS_HDMI) += cdns-hdmi-core.o -+obj-$(CONFIG_DRM_CDNS_DP) += cdns-dp-core.o ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -0,0 +1,605 @@ -+/* -+ * Cadence Display Port Interface (DP) driver -+ * -+ * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define aux_to_hdp(x) container_of(x, struct imx_mhdp_device, aux) -+ -+/* -+ * This function only implements native DPDC reads and writes -+ */ -+static ssize_t dp_aux_transfer(struct drm_dp_aux *aux, -+ struct drm_dp_aux_msg *msg) -+{ -+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(aux->dev); -+ bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ); -+ int ret; -+ -+ /* Ignore address only message */ -+ if ((msg->size == 0) || (msg->buffer == NULL)) { -+ msg->reply = native ? -+ DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK; -+ return msg->size; -+ } -+ -+ if (!native) { -+ dev_err(mhdp->dev, "%s: only native messages supported\n", __func__); -+ return -EINVAL; -+ } -+ -+ /* msg sanity check */ -+ if (msg->size > DP_AUX_MAX_PAYLOAD_BYTES) { -+ dev_err(mhdp->dev, "%s: invalid msg: size(%zu), request(%x)\n", -+ __func__, msg->size, (unsigned int)msg->request); -+ return -EINVAL; -+ } -+ -+ if (msg->request == DP_AUX_NATIVE_WRITE) { -+ const u8 *buf = msg->buffer; -+ int i; -+ for (i = 0; i < msg->size; ++i) { -+ ret = cdns_mhdp_dpcd_write(mhdp, -+ msg->address + i, buf[i]); -+ if (!ret) -+ continue; -+ -+ DRM_DEV_ERROR(mhdp->dev, "Failed to write DPCD\n"); -+ -+ return ret; -+ } -+ } -+ -+ if (msg->request == DP_AUX_NATIVE_READ) { -+ ret = cdns_mhdp_dpcd_read(mhdp, msg->address, msg->buffer, msg->size); -+ if (ret < 0) -+ return -EIO; -+ msg->reply = DP_AUX_NATIVE_REPLY_ACK; -+ return msg->size; -+ } -+ return 0; -+} -+ -+static int dp_aux_init(struct cdns_mhdp_device *mhdp, -+ struct device *dev) -+{ -+ int ret; -+ -+ mhdp->dp.aux.name = "imx_dp_aux"; -+ mhdp->dp.aux.dev = dev; -+ mhdp->dp.aux.transfer = dp_aux_transfer; -+ -+ ret = drm_dp_aux_register(&mhdp->dp.aux); -+ -+ return ret; -+} -+ -+static int dp_aux_destroy(struct cdns_mhdp_device *mhdp) -+{ -+ drm_dp_aux_unregister(&mhdp->dp.aux); -+ return 0; -+} -+ -+static void dp_pixel_clk_reset(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val; -+ -+ /* reset pixel clk */ -+ val = cdns_mhdp_reg_read(mhdp, SOURCE_HDTX_CAR); -+ cdns_mhdp_reg_write(mhdp, SOURCE_HDTX_CAR, val & 0xFD); -+ cdns_mhdp_reg_write(mhdp, SOURCE_HDTX_CAR, val); -+} -+ -+static void cdns_dp_mode_set(struct imx_mhdp_device *dp, -+ const struct drm_display_mode *mode) -+{ -+ struct drm_dp_link link; -+ struct cdns_mhdp_device *mhdp = &dp->mhdp; -+ u32 lane_mapping = mhdp->dp.lane_mapping; -+ int ret; -+ char linkid[6]; -+ -+ memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode)); -+ -+ dp->dual_mode = video_is_dual_mode(mode); -+ -+ dp_pixel_clk_reset(mhdp); -+ -+ hdp_plat_call(dp, pclock_change); -+ -+ hdp_plat_call(dp, phy_init); -+ -+ ret = drm_dp_downstream_id(&mhdp->dp.aux, linkid); -+ if (ret < 0) { -+ DRM_INFO("Failed to Get DP link ID: %d\n", ret); -+ return; -+ } -+ DRM_INFO("DP link id: %s, 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ linkid, linkid[0], linkid[1], linkid[2], linkid[3], linkid[4], -+ linkid[5]); -+ -+ /* Check dp link */ -+ ret = drm_dp_link_probe(&mhdp->dp.aux, &link); -+ if (ret < 0) { -+ DRM_INFO("Failed to probe DP link: %d\n", ret); -+ return; -+ } -+ DRM_INFO("DP revision: 0x%x\n", link.revision); -+ DRM_INFO("DP rate: %d Mbps\n", link.rate); -+ DRM_INFO("DP number of lanes: %d\n", link.num_lanes); -+ DRM_INFO("DP capabilities: 0x%lx\n", link.capabilities); -+ -+ drm_dp_link_power_up(&mhdp->dp.aux, &mhdp->dp.link); -+ if (ret < 0) { -+ DRM_INFO("Failed to power DP link: %d\n", ret); -+ return; -+ } -+ -+ /* always use the number of lanes from the display*/ -+ mhdp->dp.link.num_lanes = link.num_lanes; -+ -+ /* Use the lower link rate */ -+ if (mhdp->dp.link_rate != 0) { -+ mhdp->dp.link.rate = min(mhdp->dp.link_rate, (u32)link.rate); -+ DRM_DEBUG("DP actual link rate: 0x%x\n", link.rate); -+ } -+ -+ /* initialize phy if lanes or link rate differnt */ -+ if (mhdp->dp.link.num_lanes != mhdp->dp.num_lanes || -+ mhdp->dp.link.rate != mhdp->dp.link_rate) -+ hdp_plat_call(dp, phy_init); -+ -+ /* Video off */ -+ ret = cdns_mhdp_set_video_status(mhdp, CONTROL_VIDEO_IDLE); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "Failed to valid video %d\n", ret); -+ return; -+ } -+ -+ /* Line swaping */ -+ cdns_mhdp_reg_write(mhdp, LANES_CONFIG, 0x00400000 | lane_mapping); -+ -+ /* Set DP host capability */ -+ ret = cdns_mhdp_set_host_cap(mhdp, mhdp->dp.link.num_lanes, false); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "Failed to set host cap %d\n", ret); -+ return; -+ } -+ -+ ret = cdns_mhdp_config_video(mhdp); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "Failed to config video %d\n", ret); -+ return; -+ } -+ -+ /* Link trainning */ -+ ret = cdns_mhdp_train_link(mhdp); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "Failed link train %d\n", ret); -+ return; -+ } -+ -+ ret = cdns_mhdp_set_video_status(mhdp, CONTROL_VIDEO_VALID); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "Failed to valid video %d\n", ret); -+ return; -+ } -+ -+ return; -+} -+ -+/* ----------------------------------------------------------------------------- -+ * dp TX Setup -+ */ -+static enum drm_connector_status -+cdns_dp_connector_detect(struct drm_connector *connector, bool force) -+{ -+ struct imx_mhdp_device *dp = container_of(connector, -+ struct imx_mhdp_device, mhdp.connector.base); -+ u8 hpd = 0xf; -+ -+ hpd = cdns_mhdp_read_hpd(&dp->mhdp); -+ if (hpd == 1) -+ /* Cable Connected */ -+ return connector_status_connected; -+ else if (hpd == 0) -+ /* Cable Disconnedted */ -+ return connector_status_disconnected; -+ else { -+ /* Cable status unknown */ -+ DRM_INFO("Unknow cable status, hdp=%u\n", hpd); -+ return connector_status_unknown; -+ } -+} -+ -+static int cdns_dp_connector_get_modes(struct drm_connector *connector) -+{ -+ struct imx_mhdp_device *dp = container_of(connector, -+ struct imx_mhdp_device, mhdp.connector.base); -+ int num_modes = 0; -+ struct edid *edid; -+ -+ edid = drm_do_get_edid(&dp->mhdp.connector.base, -+ cdns_mhdp_get_edid_block, &dp->mhdp); -+ if (edid) { -+ dev_info(dp->mhdp.dev, "%x,%x,%x,%x,%x,%x,%x,%x\n", -+ edid->header[0], edid->header[1], -+ edid->header[2], edid->header[3], -+ edid->header[4], edid->header[5], -+ edid->header[6], edid->header[7]); -+ drm_connector_update_edid_property(connector, edid); -+ num_modes = drm_add_edid_modes(connector, edid); -+ kfree(edid); -+ } -+ -+ if (num_modes == 0) -+ DRM_ERROR("Invalid edid\n"); -+ return num_modes; -+} -+ -+static const struct drm_connector_funcs cdns_dp_connector_funcs = { -+ .fill_modes = drm_helper_probe_single_connector_modes, -+ .detect = cdns_dp_connector_detect, -+ .destroy = drm_connector_cleanup, -+ .reset = drm_atomic_helper_connector_reset, -+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, -+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -+}; -+ -+static const struct drm_connector_helper_funcs cdns_dp_connector_helper_funcs = { -+ .get_modes = cdns_dp_connector_get_modes, -+}; -+ -+static int cdns_dp_bridge_attach(struct drm_bridge *bridge) -+{ -+ struct imx_mhdp_device *dp = bridge->driver_private; -+ struct drm_encoder *encoder = bridge->encoder; -+ struct drm_connector *connector = &dp->mhdp.connector.base; -+ -+ connector->interlace_allowed = 1; -+ connector->polled = DRM_CONNECTOR_POLL_HPD; -+ -+ drm_connector_helper_add(connector, &cdns_dp_connector_helper_funcs); -+ -+ drm_connector_init(bridge->dev, connector, &cdns_dp_connector_funcs, -+ DRM_MODE_CONNECTOR_DisplayPort); -+ -+ drm_connector_attach_encoder(connector, encoder); -+ -+ return 0; -+} -+ -+static enum drm_mode_status -+cdns_dp_bridge_mode_valid(struct drm_bridge *bridge, -+ const struct drm_display_mode *mode) -+{ -+ enum drm_mode_status mode_status = MODE_OK; -+ -+ /* We don't support double-clocked modes */ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK || -+ mode->flags & DRM_MODE_FLAG_INTERLACE) -+ return MODE_BAD; -+ -+ /* MAX support pixel clock rate 594MHz */ -+ if (mode->clock > 594000) -+ return MODE_CLOCK_HIGH; -+ -+ /* 4096x2160 is not supported now */ -+ if (mode->hdisplay > 3840) -+ return MODE_BAD_HVALUE; -+ -+ if (mode->vdisplay > 2160) -+ return MODE_BAD_VVALUE; -+ -+ return mode_status; -+} -+ -+static void cdns_dp_bridge_mode_set(struct drm_bridge *bridge, -+ const struct drm_display_mode *orig_mode, -+ const struct drm_display_mode *mode) -+{ -+ struct imx_mhdp_device *dp = bridge->driver_private; -+ struct drm_display_info *display_info = &dp->mhdp.connector.base.display_info; -+ struct video_info *video = &dp->mhdp.video_info; -+ -+ switch (display_info->bpc) { -+ case 10: -+ video->color_depth = 10; -+ break; -+ case 6: -+ video->color_depth = 6; -+ break; -+ default: -+ video->color_depth = 8; -+ break; -+ } -+ -+ video->color_fmt = PXL_RGB; -+ video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); -+ video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); -+ -+ DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay, mode->vdisplay, mode->clock); -+ -+ mutex_lock(&dp->lock); -+ -+ cdns_dp_mode_set(dp, mode); -+ -+ mutex_unlock(&dp->lock); -+} -+ -+static void cdn_hdp_bridge_enable(struct drm_bridge *bridge) -+{ -+} -+ -+static void cdn_hdp_bridge_disable(struct drm_bridge *bridge) -+{ -+ struct imx_mhdp_device *dp = bridge->driver_private; -+ struct cdns_mhdp_device *mhdp = &dp->mhdp; -+ -+ cdns_mhdp_set_video_status(mhdp, CONTROL_VIDEO_IDLE); -+ drm_dp_link_power_down(&mhdp->dp.aux, &mhdp->dp.link); -+} -+ -+static const struct drm_bridge_funcs cdns_dp_bridge_funcs = { -+ .attach = cdns_dp_bridge_attach, -+ .enable = cdn_hdp_bridge_enable, -+ .disable = cdn_hdp_bridge_disable, -+ .mode_set = cdns_dp_bridge_mode_set, -+ .mode_valid = cdns_dp_bridge_mode_valid, -+}; -+ -+static void hotplug_work_func(struct work_struct *work) -+{ -+ struct imx_mhdp_device *dp = container_of(work, -+ struct imx_mhdp_device, hotplug_work.work); -+ struct drm_connector *connector = &dp->mhdp.connector.base; -+ -+ drm_helper_hpd_irq_event(connector->dev); -+ -+ if (connector->status == connector_status_connected) { -+ DRM_INFO("HDMI/DP Cable Plug In\n"); -+ enable_irq(dp->irq[IRQ_OUT]); -+ } else if (connector->status == connector_status_disconnected) { -+ /* Cable Disconnedted */ -+ DRM_INFO("HDMI/DP Cable Plug Out\n"); -+ enable_irq(dp->irq[IRQ_IN]); -+ } -+} -+ -+static irqreturn_t cdns_dp_irq_thread(int irq, void *data) -+{ -+ struct imx_mhdp_device *dp = data; -+ -+ disable_irq_nosync(irq); -+ -+ mod_delayed_work(system_wq, &dp->hotplug_work, -+ msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS)); -+ -+ return IRQ_HANDLED; -+} -+ -+static void cdns_dp_parse_dt(struct cdns_mhdp_device *mhdp) -+{ -+ struct device_node *of_node = mhdp->dev->of_node; -+ int ret; -+ -+ ret = of_property_read_u32(of_node, "lane-mapping", -+ &mhdp->dp.lane_mapping); -+ if (ret) { -+ mhdp->dp.lane_mapping = 0xc6; -+ dev_warn(mhdp->dev, "Failed to get lane_mapping - using default 0xc6\n"); -+ } -+ dev_info(mhdp->dev, "lane-mapping 0x%02x\n", mhdp->dp.lane_mapping); -+ -+ ret = of_property_read_u32(of_node, "link-rate", &mhdp->dp.link_rate); -+ if (ret) { -+ mhdp->dp.link_rate = 162000 ; -+ dev_warn(mhdp->dev, "Failed to get link-rate, use default 1620MHz\n"); -+ } -+ dev_info(mhdp->dev, "link-rate %d\n", mhdp->dp.link_rate); -+ -+ ret = of_property_read_u32(of_node, "num-lanes", &mhdp->dp.num_lanes); -+ if (ret) { -+ mhdp->dp.num_lanes = 4; -+ dev_warn(mhdp->dev, "Failed to get num_lanes - using default\n"); -+ } -+ dev_info(mhdp->dev, "dp_num_lanes 0x%02x\n", mhdp->dp.num_lanes); -+ -+ mhdp->dp.link.num_lanes = mhdp->dp.num_lanes; -+ mhdp->dp.link.rate= mhdp->dp.link_rate; -+} -+ -+static struct imx_mhdp_device * -+__cdns_dp_probe(struct platform_device *pdev, -+ const struct cdn_plat_data *plat_data) -+{ -+ struct device *dev = &pdev->dev; -+ struct imx_mhdp_device *dp; -+ struct resource *iores = NULL; -+ int ret; -+ -+ dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); -+ if (!dp) -+ return ERR_PTR(-ENOMEM); -+ -+ dp->plat_data = plat_data; -+ dp->mhdp.dev = dev; -+ -+ mutex_init(&dp->lock); -+ mutex_init(&dp->audio_mutex); -+ spin_lock_init(&dp->audio_lock); -+ -+ INIT_DELAYED_WORK(&dp->hotplug_work, hotplug_work_func); -+ -+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ dp->mhdp.regs = devm_ioremap(dev, iores->start, resource_size(iores)); -+ if (IS_ERR(dp->mhdp.regs)) { -+ ret = PTR_ERR(dp->mhdp.regs); -+ goto err_out; -+ } -+ -+#if 0 -+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ dp->regs_ss = devm_ioremap(dev, iores->start, resource_size(iores)); -+ if (IS_ERR(dp->regs_ss)) { -+ ret = PTR_ERR(dp->regs_ss); -+ goto err_out; -+ } -+#endif -+ -+ dp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in"); -+ if (dp->irq[IRQ_IN] < 0) -+ dev_info(&pdev->dev, "No plug_in irq number\n"); -+ -+ dp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out"); -+ if (dp->irq[IRQ_OUT] < 0) -+ dev_info(&pdev->dev, "No plug_out irq number\n"); -+ -+ cdns_dp_parse_dt(&dp->mhdp); -+ -+ dp->dual_mode = false; -+ hdp_plat_call(dp, fw_init); -+ -+ /* DP FW alive check */ -+ ret = cdns_mhdp_check_alive(&dp->mhdp); -+ if (ret == false) { -+ DRM_ERROR("NO dp FW running\n"); -+ return ERR_PTR(-ENXIO); -+ } -+ -+ /* DP PHY init before AUX init */ -+ hdp_plat_call(dp, phy_init); -+ -+ /* Enable Hotplug Detect IRQ thread */ -+ irq_set_status_flags(dp->irq[IRQ_IN], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, dp->irq[IRQ_IN], -+ NULL, cdns_dp_irq_thread, -+ IRQF_ONESHOT, dev_name(dev), -+ dp); -+ if (ret) { -+ dev_err(&pdev->dev, "can't claim irq %d\n", -+ dp->irq[IRQ_IN]); -+ goto err_out; -+ } -+ -+ irq_set_status_flags(dp->irq[IRQ_OUT], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, dp->irq[IRQ_OUT], -+ NULL, cdns_dp_irq_thread, -+ IRQF_ONESHOT, dev_name(dev), -+ dp); -+ if (ret) { -+ dev_err(&pdev->dev, "can't claim irq %d\n", -+ dp->irq[IRQ_OUT]); -+ goto err_out; -+ } -+ if (cdns_mhdp_read_hpd(&dp->mhdp)) -+ enable_irq(dp->irq[IRQ_OUT]); -+ else -+ enable_irq(dp->irq[IRQ_IN]); -+ -+ dp->mhdp.bridge.base.driver_private = dp; -+ dp->mhdp.bridge.base.funcs = &cdns_dp_bridge_funcs; -+#ifdef CONFIG_OF -+ dp->mhdp.bridge.base.of_node = pdev->dev.of_node; -+#endif -+ -+ platform_set_drvdata(pdev, dp); -+ -+ dp_aux_init(&dp->mhdp, dev); -+ -+ return dp; -+ -+err_out: -+ return ERR_PTR(ret); -+} -+ -+static void __cdns_dp_remove(struct imx_mhdp_device *dp) -+{ -+ dp_aux_destroy(&dp->mhdp); -+} -+ -+/* ----------------------------------------------------------------------------- -+ * Probe/remove API, used from platforms based on the DRM bridge API. -+ */ -+int cdns_dp_probe(struct platform_device *pdev, -+ const struct cdn_plat_data *plat_data) -+{ -+ struct imx_mhdp_device *dp; -+ -+ dp = __cdns_dp_probe(pdev, plat_data); -+ if (IS_ERR(dp)) -+ return PTR_ERR(dp); -+ -+ drm_bridge_add(&dp->mhdp.bridge.base); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(cdns_dp_probe); -+ -+void cdns_dp_remove(struct platform_device *pdev) -+{ -+ struct imx_mhdp_device *dp = platform_get_drvdata(pdev); -+ -+ drm_bridge_remove(&dp->mhdp.bridge.base); -+ -+ __cdns_dp_remove(dp); -+} -+EXPORT_SYMBOL_GPL(cdns_dp_remove); -+ -+/* ----------------------------------------------------------------------------- -+ * Bind/unbind API, used from platforms based on the component framework. -+ */ -+int cdns_dp_bind(struct platform_device *pdev, struct drm_encoder *encoder, -+ const struct cdn_plat_data *plat_data) -+{ -+ struct imx_mhdp_device *dp; -+ int ret; -+ -+ dp = __cdns_dp_probe(pdev, plat_data); -+ if (IS_ERR(dp)) -+ return PTR_ERR(dp); -+ -+ ret = drm_bridge_attach(encoder, &dp->mhdp.bridge.base, NULL); -+ if (ret) { -+ cdns_dp_remove(pdev); -+ DRM_ERROR("Failed to initialize bridge with drm\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(cdns_dp_bind); -+ -+void cdns_dp_unbind(struct device *dev) -+{ -+ struct imx_mhdp_device *dp = dev_get_drvdata(dev); -+ -+ __cdns_dp_remove(dp); -+} -+EXPORT_SYMBOL_GPL(cdns_dp_unbind); -+ -+MODULE_AUTHOR("Sandor Yu "); -+MODULE_DESCRIPTION("Cadence Display Port transmitter driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:cdn-dp"); ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -0,0 +1,643 @@ -+/* -+ * Cadence High-Definition Multimedia Interface (HDMI) driver -+ * -+ * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static void hdmi_writel(struct cdns_mhdp_device *mhdp, u32 val, u32 offset) -+{ -+ struct imx_mhdp_device *hdmi = container_of(mhdp, struct imx_mhdp_device, mhdp); -+ -+ /* TODO */ -+ if (offset >= 0x1000 && hdmi->regmap_csr) { -+ /* Remap address to low 4K memory */ -+ regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, offset >> 12); -+ writel(val, (offset & 0xfff) + mhdp->regs); -+ /* Restore address mapping */ -+ regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, 0); -+ -+ } else -+ writel(val, mhdp->regs + offset); -+} -+ -+static int hdmi_sink_config(struct cdns_mhdp_device *mhdp) -+{ -+ struct drm_scdc *scdc = &mhdp->connector.base.display_info.hdmi.scdc; -+ u8 buff; -+ int ret; -+ -+ if (mhdp->hdmi.char_rate > 340000) { -+ /* -+ * TMDS Character Rate above 340MHz should working in HDMI2.0 -+ * Enable scrambling and TMDS_Bit_Clock_Ratio -+ */ -+ buff = 3; -+ mhdp->hdmi.hdmi_type = MODE_HDMI_2_0; -+ } else if (scdc->scrambling.low_rates) { -+ /* -+ * Enable scrambling and HDMI2.0 when scrambling capability of sink -+ * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit -+ */ -+ buff = 1; -+ mhdp->hdmi.hdmi_type = MODE_HDMI_2_0; -+ } else { -+ /* Default work in HDMI1.4 */ -+ buff = 0; -+ mhdp->hdmi.hdmi_type = MODE_HDMI_1_4; -+ } -+ -+ /* TMDS config */ -+ ret = cdns_hdmi_scdc_write(mhdp, 0x20, buff); -+ return ret; -+} -+ -+static int hdmi_lanes_config(struct cdns_mhdp_device *mhdp) -+{ -+ int ret; -+ -+ /* TODO */ -+ /* Set the lane swapping */ -+// if (cpu_is_imx8qm()) -+ ret = cdns_mhdp_reg_write(mhdp, LANES_CONFIG, -+ F_SOURCE_PHY_LANE0_SWAP(3) | -+ F_SOURCE_PHY_LANE1_SWAP(0) | -+ F_SOURCE_PHY_LANE2_SWAP(1) | -+ F_SOURCE_PHY_LANE3_SWAP(2) | -+ F_SOURCE_PHY_COMB_BYPASS(0) | -+ F_SOURCE_PHY_20_10(1)); -+#if 0 -+ else -+ ret = cdns_mhdp_reg_write(mhdp, LANES_CONFIG, -+ F_SOURCE_PHY_LANE0_SWAP(0) | -+ F_SOURCE_PHY_LANE1_SWAP(1) | -+ F_SOURCE_PHY_LANE2_SWAP(2) | -+ F_SOURCE_PHY_LANE3_SWAP(3) | -+ F_SOURCE_PHY_COMB_BYPASS(0) | -+ F_SOURCE_PHY_20_10(1)); -+#endif -+ return ret; -+} -+ -+static void hdmi_info_frame_set(struct cdns_mhdp_device *mhdp, -+ u8 entry_id, u8 packet_len, u8 *packet, u8 packet_type) -+{ -+ u32 *packet32, len32; -+ u32 val, i; -+ -+ /* invalidate entry */ -+ val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id); -+ hdmi_writel(mhdp, val, SOURCE_PIF_PKT_ALLOC_REG); -+ hdmi_writel(mhdp, F_PKT_ALLOC_WR_EN(1), SOURCE_PIF_PKT_ALLOC_WR_EN); -+ -+ /* flush fifo 1 */ -+ hdmi_writel(mhdp, F_FIFO1_FLUSH(1), SOURCE_PIF_FIFO1_FLUSH); -+ -+ /* write packet into memory */ -+ packet32 = (u32 *)packet; -+ len32 = packet_len / 4; -+ for (i = 0; i < len32; i++) -+ hdmi_writel(mhdp, F_DATA_WR(packet32[i]), SOURCE_PIF_DATA_WR); -+ -+ /* write entry id */ -+ hdmi_writel(mhdp, F_WR_ADDR(entry_id), SOURCE_PIF_WR_ADDR); -+ -+ /* write request */ -+ hdmi_writel(mhdp, F_HOST_WR(1), SOURCE_PIF_WR_REQ); -+ -+ /* update entry */ -+ val = F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) | -+ F_PACKET_TYPE(packet_type) | F_PKT_ALLOC_ADDRESS(entry_id); -+ hdmi_writel(mhdp, val, SOURCE_PIF_PKT_ALLOC_REG); -+ -+ hdmi_writel(mhdp, F_PKT_ALLOC_WR_EN(1), SOURCE_PIF_PKT_ALLOC_WR_EN); -+} -+ -+#define RGB_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\ -+ BIT(HDMI_EXTENDED_COLORIMETRY_OPRGB)) -+#define YCC_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\ -+ BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM) |\ -+ BIT(HDMI_EXTENDED_COLORIMETRY_OPYCC_601) |\ -+ BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601) |\ -+ BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709) |\ -+ BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601)) -+static int hdmi_avi_info_set(struct cdns_mhdp_device *mhdp, -+ struct drm_display_mode *mode) -+{ -+ struct hdmi_avi_infoframe frame; -+// struct drm_display_info *di = &mhdp->connector.base.display_info; -+// enum hdmi_extended_colorimetry ext_col; -+// u32 sink_col, allowed_col; -+ int format = mhdp->video_info.color_fmt; -+ u8 buf[32]; -+ int ret; -+ -+ /* Initialise info frame from DRM mode */ -+ drm_hdmi_avi_infoframe_from_display_mode(&frame, &mhdp->connector.base, mode); -+ -+#if 0 //TODO to DCSS -+ /* Set up colorimetry */ -+ allowed_col = format == PXL_RGB ? RGB_ALLOWED_COLORIMETRY : -+ YCC_ALLOWED_COLORIMETRY; -+ -+ sink_col = di->hdmi.colorimetry & allowed_col; -+ -+ if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020)) -+ ext_col = HDMI_EXTENDED_COLORIMETRY_BT2020; -+ else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM)) -+ ext_col = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM; -+ else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_OPRGB)) -+ ext_col = HDMI_EXTENDED_COLORIMETRY_OPRGB; -+ else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709)) -+ ext_col = HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; -+ else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_OPYCC_601)) -+ ext_col = HDMI_EXTENDED_COLORIMETRY_OPYCC_601; -+ else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601)) -+ ext_col = HDMI_EXTENDED_COLORIMETRY_S_YCC_601; -+ else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601)) -+ ext_col = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -+ else -+ ext_col = 0; -+ -+ frame.colorimetry = sink_col ? HDMI_COLORIMETRY_EXTENDED : -+ HDMI_COLORIMETRY_NONE; -+ frame.extended_colorimetry = ext_col; -+#endif -+ -+ switch (format) { -+ case YCBCR_4_4_4: -+ frame.colorspace = HDMI_COLORSPACE_YUV444; -+ break; -+ case YCBCR_4_2_2: -+ frame.colorspace = HDMI_COLORSPACE_YUV422; -+ break; -+ case YCBCR_4_2_0: -+ frame.colorspace = HDMI_COLORSPACE_YUV420; -+ break; -+ default: -+ frame.colorspace = HDMI_COLORSPACE_RGB; -+ break; -+ } -+ -+ ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1); -+ if (ret < 0) { -+ DRM_ERROR("failed to pack AVI infoframe: %d\n", ret); -+ return -1; -+ } -+ -+ buf[0] = 0; -+ hdmi_info_frame_set(mhdp, 0, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_AVI); -+ return 0; -+} -+ -+static int hdmi_vendor_info_set(struct cdns_mhdp_device *mhdp, -+ struct drm_display_mode *mode) -+{ -+ struct hdmi_vendor_infoframe frame; -+ u8 buf[32]; -+ int ret; -+ -+ /* Initialise vendor frame from DRM mode */ -+ ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, &mhdp->connector.base, mode); -+ if (ret < 0) { -+ DRM_WARN("Unable to init vendor infoframe: %d\n", ret); -+ return -1; -+ } -+ -+ ret = hdmi_vendor_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1); -+ if (ret < 0) { -+ DRM_WARN("Unable to pack vendor infoframe: %d\n", ret); -+ return -1; -+ } -+ -+ buf[0] = 0; -+ hdmi_info_frame_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_VENDOR); -+ return 0; -+} -+ -+void cdns_hdmi_mode_set(struct cdns_mhdp_device *mhdp) -+{ -+ struct drm_display_mode *mode = &mhdp->mode; -+ int ret; -+ -+ ret = hdmi_sink_config(mhdp); -+ if (ret < 0) { -+ DRM_ERROR("%s failed\n", __func__); -+ return; -+ } -+ -+ ret = cdns_hdmi_ctrl_init(mhdp, mhdp->hdmi.hdmi_type, mhdp->hdmi.char_rate); -+ if (ret < 0) { -+ DRM_ERROR("%s, ret = %d\n", __func__, ret); -+ return; -+ } -+ -+ /* Config GCP */ -+ if (mhdp->video_info.color_depth == 8) -+ cdns_hdmi_disable_gcp(mhdp); -+ else -+ cdns_hdmi_enable_gcp(mhdp); -+ -+ ret = hdmi_avi_info_set(mhdp, mode); -+ if (ret < 0) { -+ DRM_ERROR("%s ret = %d\n", __func__, ret); -+ return; -+ } -+ -+ /* vendor info frame is enable only when HDMI1.4 4K mode */ -+ ret = hdmi_vendor_info_set(mhdp, mode); -+ if (ret < 0) -+ DRM_WARN("Unable to configure Vendor infoframe\n"); -+ -+ ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info); -+ if (ret < 0) { -+ DRM_ERROR("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret); -+ return; -+ } -+ -+ /* wait HDMI PHY pixel clock stable */ -+ msleep(50); -+} -+ -+static enum drm_connector_status -+cdns_hdmi_connector_detect(struct drm_connector *connector, bool force) -+{ -+ struct imx_mhdp_device *hdmi = -+ container_of(connector, struct imx_mhdp_device, mhdp.connector.base); -+ -+ u8 hpd = 0xf; -+ -+ hpd = cdns_mhdp_read_hpd(&hdmi->mhdp); -+ -+ if (hpd == 1) -+ /* Cable Connected */ -+ return connector_status_connected; -+ else if (hpd == 0) -+ /* Cable Disconnedted */ -+ return connector_status_disconnected; -+ else { -+ /* Cable status unknown */ -+ DRM_INFO("Unknow cable status, hdp=%u\n", hpd); -+ return connector_status_unknown; -+ } -+} -+ -+static int cdns_hdmi_connector_get_modes(struct drm_connector *connector) -+{ -+ struct imx_mhdp_device *hdmi = container_of(connector, struct imx_mhdp_device, -+ mhdp.connector.base); -+ int num_modes = 0; -+ struct edid *edid; -+ -+ edid = drm_do_get_edid(&hdmi->mhdp.connector.base, -+ cdns_hdmi_get_edid_block, &hdmi->mhdp); -+ if (edid) { -+ dev_info(hdmi->mhdp.dev, "%x,%x,%x,%x,%x,%x,%x,%x\n", -+ edid->header[0], edid->header[1], -+ edid->header[2], edid->header[3], -+ edid->header[4], edid->header[5], -+ edid->header[6], edid->header[7]); -+ drm_connector_update_edid_property(connector, edid); -+ num_modes = drm_add_edid_modes(connector, edid); -+ kfree(edid); -+ } -+ -+ if (num_modes == 0) -+ DRM_ERROR("Invalid edid\n"); -+ return num_modes; -+} -+ -+static const struct drm_connector_funcs cdns_hdmi_connector_funcs = { -+ .fill_modes = drm_helper_probe_single_connector_modes, -+ .detect = cdns_hdmi_connector_detect, -+ .destroy = drm_connector_cleanup, -+ .reset = drm_atomic_helper_connector_reset, -+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, -+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -+}; -+ -+static const struct drm_connector_helper_funcs cdns_hdmi_connector_helper_funcs = { -+ .get_modes = cdns_hdmi_connector_get_modes, -+}; -+ -+static int cdns_hdmi_bridge_attach(struct drm_bridge *bridge) -+{ -+ struct imx_mhdp_device *hdmi = bridge->driver_private; -+ struct drm_encoder *encoder = bridge->encoder; -+ struct drm_connector *connector = &hdmi->mhdp.connector.base; -+ -+ connector->interlace_allowed = 1; -+ connector->polled = DRM_CONNECTOR_POLL_HPD; -+ -+ drm_connector_helper_add(connector, &cdns_hdmi_connector_helper_funcs); -+ -+ drm_connector_init(bridge->dev, connector, &cdns_hdmi_connector_funcs, -+ DRM_MODE_CONNECTOR_HDMIA); -+ -+ drm_connector_attach_encoder(connector, encoder); -+ -+ return 0; -+} -+ -+static enum drm_mode_status -+cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge, -+ const struct drm_display_mode *mode) -+{ -+ enum drm_mode_status mode_status = MODE_OK; -+ -+ /* We don't support double-clocked and Interlaced modes */ -+ if (mode->flags & DRM_MODE_FLAG_DBLCLK || -+ mode->flags & DRM_MODE_FLAG_INTERLACE) -+ return MODE_BAD; -+ -+ /* MAX support pixel clock rate 148.5MHz */ -+ if (mode->clock > 148500) -+ return MODE_CLOCK_HIGH; -+ -+ /* 4096x2160 is not supported */ -+ if (mode->hdisplay > 3840 || mode->vdisplay > 2160) -+ return MODE_BAD_HVALUE; -+ -+ return mode_status; -+} -+ -+static void cdns_hdmi_bridge_mode_set(struct drm_bridge *bridge, -+ const struct drm_display_mode *orig_mode, -+ const struct drm_display_mode *mode) -+{ -+ struct imx_mhdp_device *hdmi = bridge->driver_private; -+ struct drm_display_info *display_info = &hdmi->mhdp.connector.base.display_info; -+ struct video_info *video = &hdmi->mhdp.video_info; -+ -+ switch (display_info->bpc) { -+ case 10: -+ video->color_depth = 10; -+ break; -+ case 6: -+ video->color_depth = 6; -+ break; -+ default: -+ video->color_depth = 8; -+ break; -+ } -+ -+ video->color_fmt = PXL_RGB; -+ video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); -+ video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); -+ -+ mutex_lock(&hdmi->lock); -+ -+ DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay, mode->vdisplay, mode->clock); -+ -+ memcpy(&hdmi->mhdp.mode, mode, sizeof(struct drm_display_mode)); -+ -+ hdmi->dual_mode = video_is_dual_mode(mode); -+ -+ hdmi_lanes_config(&hdmi->mhdp); -+ -+ hdp_plat_call(hdmi, pclock_change); -+ -+ hdp_plat_call(hdmi, phy_init); -+ -+ cdns_hdmi_mode_set(&hdmi->mhdp); -+ -+ mutex_unlock(&hdmi->lock); -+} -+ -+static const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = { -+ .attach = cdns_hdmi_bridge_attach, -+ .mode_set = cdns_hdmi_bridge_mode_set, -+ .mode_valid = cdns_hdmi_bridge_mode_valid, -+}; -+ -+static void hotplug_work_func(struct work_struct *work) -+{ -+ struct imx_mhdp_device *hdmi = container_of(work, -+ struct imx_mhdp_device, hotplug_work.work); -+ struct drm_connector *connector = &hdmi->mhdp.connector.base; -+ -+ drm_helper_hpd_irq_event(connector->dev); -+ -+ if (connector->status == connector_status_connected) { -+ /* Cable Connected */ -+ DRM_INFO("HDMI Cable Plug In\n"); -+ enable_irq(hdmi->irq[IRQ_OUT]); -+ } else if (connector->status == connector_status_disconnected) { -+ /* Cable Disconnedted */ -+ DRM_INFO("HDMI Cable Plug Out\n"); -+ enable_irq(hdmi->irq[IRQ_IN]); -+ } -+} -+ -+static irqreturn_t cdns_hdmi_irq_thread(int irq, void *data) -+{ -+ struct imx_mhdp_device *hdmi = data; -+ -+ disable_irq_nosync(irq); -+ -+ mod_delayed_work(system_wq, &hdmi->hotplug_work, -+ msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS)); -+ -+ return IRQ_HANDLED; -+} -+ -+static struct imx_mhdp_device * -+__cdns_hdmi_probe(struct platform_device *pdev, -+ const struct cdn_plat_data *plat_data) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *np = dev->of_node; -+ struct platform_device_info pdevinfo; -+ struct imx_mhdp_device *hdmi; -+ struct resource *iores = NULL; -+ int ret; -+ -+ hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); -+ if (!hdmi) -+ return ERR_PTR(-ENOMEM); -+ -+ hdmi->plat_data = plat_data; -+ hdmi->mhdp.dev = dev; -+ -+ mutex_init(&hdmi->lock); -+ mutex_init(&hdmi->audio_mutex); -+ spin_lock_init(&hdmi->audio_lock); -+ -+ INIT_DELAYED_WORK(&hdmi->hotplug_work, hotplug_work_func); -+ -+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ hdmi->mhdp.regs = devm_ioremap(dev, iores->start, resource_size(iores)); -+ if (IS_ERR(hdmi->mhdp.regs)) { -+ ret = PTR_ERR(hdmi->mhdp.regs); -+ goto err_out; -+ } -+ -+ /* csr register base */ -+ hdmi->regmap_csr = syscon_regmap_lookup_by_phandle(np, "csr"); -+ if (IS_ERR(hdmi->regmap_csr)) { -+ dev_info(dev, "No csr regmap\n"); -+ } -+ -+ hdmi->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in"); -+ if (hdmi->irq[IRQ_IN] < 0) { -+ dev_info(&pdev->dev, "No plug_in irq number\n"); -+ return ERR_PTR(-EPROBE_DEFER); -+ } -+ -+ hdmi->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out"); -+ if (hdmi->irq[IRQ_OUT] < 0) { -+ dev_info(&pdev->dev, "No plug_out irq number\n"); -+ return ERR_PTR(-EPROBE_DEFER); -+ } -+ -+ /* Initialize dual_mode to false */ -+ hdmi->dual_mode = false; -+ -+ /* Initialize FW */ -+ hdp_plat_call(hdmi, fw_init); -+ -+ /* HDMI FW alive check */ -+ ret = cdns_mhdp_check_alive(&hdmi->mhdp); -+ if (ret == false) { -+ DRM_ERROR("NO HDMI FW running\n"); -+ return ERR_PTR(-ENXIO); -+ } -+ -+ /* Enable Hotplug Detect thread */ -+ irq_set_status_flags(hdmi->irq[IRQ_IN], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, hdmi->irq[IRQ_IN], -+ NULL, cdns_hdmi_irq_thread, -+ IRQF_ONESHOT, dev_name(dev), -+ hdmi); -+ if (ret) { -+ dev_err(&pdev->dev, "can't claim irq %d\n", -+ hdmi->irq[IRQ_IN]); -+ goto err_out; -+ } -+ -+ irq_set_status_flags(hdmi->irq[IRQ_OUT], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, hdmi->irq[IRQ_OUT], -+ NULL, cdns_hdmi_irq_thread, -+ IRQF_ONESHOT, dev_name(dev), -+ hdmi); -+ if (ret) { -+ dev_err(&pdev->dev, "can't claim irq %d\n", -+ hdmi->irq[IRQ_OUT]); -+ goto err_out; -+ } -+ -+ if (cdns_mhdp_read_hpd(&hdmi->mhdp)) -+ enable_irq(hdmi->irq[IRQ_OUT]); -+ else -+ enable_irq(hdmi->irq[IRQ_IN]); -+ -+ hdmi->mhdp.bridge.base.driver_private = hdmi; -+ hdmi->mhdp.bridge.base.funcs = &cdns_hdmi_bridge_funcs; -+#ifdef CONFIG_OF -+ hdmi->mhdp.bridge.base.of_node = pdev->dev.of_node; -+#endif -+ -+ memset(&pdevinfo, 0, sizeof(pdevinfo)); -+ pdevinfo.parent = dev; -+ pdevinfo.id = PLATFORM_DEVID_AUTO; -+ -+ platform_set_drvdata(pdev, hdmi); -+ -+ return hdmi; -+ -+err_out: -+ -+ return ERR_PTR(ret); -+} -+ -+static void __cdns_hdmi_remove(struct imx_mhdp_device *hdmi) -+{ -+} -+ -+/* ----------------------------------------------------------------------------- -+ * Probe/remove API, used from platforms based on the DRM bridge API. -+ */ -+int cdns_hdmi_probe(struct platform_device *pdev, -+ const struct cdn_plat_data *plat_data) -+{ -+ struct imx_mhdp_device *hdmi; -+ -+ hdmi = __cdns_hdmi_probe(pdev, plat_data); -+ if (IS_ERR(hdmi)) -+ return PTR_ERR(hdmi); -+ -+ drm_bridge_add(&hdmi->mhdp.bridge.base); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(cdns_hdmi_probe); -+ -+void cdns_hdmi_remove(struct platform_device *pdev) -+{ -+ struct imx_mhdp_device *hdmi = platform_get_drvdata(pdev); -+ -+ drm_bridge_remove(&hdmi->mhdp.bridge.base); -+ -+ __cdns_hdmi_remove(hdmi); -+} -+EXPORT_SYMBOL_GPL(cdns_hdmi_remove); -+ -+/* ----------------------------------------------------------------------------- -+ * Bind/unbind API, used from platforms based on the component framework. -+ */ -+int cdns_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, -+ const struct cdn_plat_data *plat_data) -+{ -+ struct imx_mhdp_device *hdmi; -+ int ret; -+ -+ hdmi = __cdns_hdmi_probe(pdev, plat_data); -+ if (IS_ERR(hdmi)) -+ return PTR_ERR(hdmi); -+ -+ ret = drm_bridge_attach(encoder, &hdmi->mhdp.bridge.base, NULL); -+ if (ret) { -+ cdns_hdmi_remove(pdev); -+ DRM_ERROR("Failed to initialize bridge with drm\n"); -+ return ret; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(cdns_hdmi_bind); -+ -+void cdns_hdmi_unbind(struct device *dev) -+{ -+ struct imx_mhdp_device *hdmi = dev_get_drvdata(dev); -+ -+ __cdns_hdmi_remove(hdmi); -+} -+EXPORT_SYMBOL_GPL(cdns_hdmi_unbind); -+ -+MODULE_AUTHOR("Sandor Yu "); -+MODULE_DESCRIPTION("Cadence HDMI transmitter driver"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:cdn-hdmi"); ---- /dev/null -+++ b/include/drm/bridge/cdns-mhdp-imx.h -@@ -0,0 +1,121 @@ -+/* -+ * Cadence High-Definition Multimedia Interface (HDMI) driver -+ * -+ * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+#ifndef CDNS_MHDP_IMX_H_ -+#define CDNS_MHDP_IMX_H_ -+ -+#include -+ -+#define IRQ_IN 0 -+#define IRQ_OUT 1 -+#define IRQ_NUM 2 -+ -+#define hdp_plat_call(hdp, operation) \ -+ (!(hdp) ? -ENODEV : (((hdp)->plat_data && (hdp)->plat_data->operation) ? \ -+ (hdp)->plat_data->operation(hdp) : ENOIOCTLCMD)) -+ -+#define HDP_DUAL_MODE_MIN_PCLK_RATE 300000 /* KHz */ -+#define HDP_SINGLE_MODE_MAX_WIDTH 1920 -+ -+static inline bool video_is_dual_mode(const struct drm_display_mode *mode) -+{ -+ return (mode->clock > HDP_DUAL_MODE_MIN_PCLK_RATE || -+ mode->hdisplay > HDP_SINGLE_MODE_MAX_WIDTH) ? true : false; -+} -+ -+struct imx_mhdp_device; -+ -+struct imx_hdp_clks { -+ struct clk *av_pll; -+ struct clk *dig_pll; -+ struct clk *clk_ipg; -+ struct clk *clk_core; -+ struct clk *clk_pxl; -+ struct clk *clk_pxl_mux; -+ struct clk *clk_pxl_link; -+ -+ struct clk *lpcg_hdp; -+ struct clk *lpcg_msi; -+ struct clk *lpcg_pxl; -+ struct clk *lpcg_vif; -+ struct clk *lpcg_lis; -+ struct clk *lpcg_apb; -+ struct clk *lpcg_apb_csr; -+ struct clk *lpcg_apb_ctrl; -+ -+ struct clk *lpcg_i2s; -+ struct clk *clk_i2s_bypass; -+}; -+ -+struct cdn_plat_data { -+ /* Vendor PHY support */ -+ int (*phy_init)(struct imx_mhdp_device *hdmi); -+ int (*bind)(struct platform_device *pdev, -+ struct drm_encoder *encoder, -+ const struct cdn_plat_data *plat_data); -+ void (*unbind)(struct device *dev); -+ int (*fw_init)(struct imx_mhdp_device *hdp); -+ void (*pclock_change)(struct imx_mhdp_device *hdp); -+ char is_dp; -+}; -+ -+struct imx_mhdp_device { -+ struct cdns_mhdp_device mhdp; -+ -+ struct mutex lock; -+ struct mutex audio_mutex; -+ spinlock_t audio_lock; -+ bool connected; -+ bool active; -+ bool suspended; -+ struct imx_hdp_clks clks; -+ -+ const struct cdn_plat_data *plat_data; -+ -+ int irq[IRQ_NUM]; -+ struct delayed_work hotplug_work; -+ //void __iomem *regmap_csr; -+ struct regmap *regmap_csr; -+ u32 csr_pxl_mux_reg; -+ u32 csr_ctrl0_reg; -+ u32 csr_ctrl0_sec; -+ -+ struct audio_info audio_info; -+ bool sink_has_audio; -+ u32 dual_mode; -+ -+ struct device *pd_mhdp_dev; -+ struct device *pd_pll0_dev; -+ struct device *pd_pll1_dev; -+ struct device_link *pd_mhdp_link; -+ struct device_link *pd_pll0_link; -+ struct device_link *pd_pll1_link; -+ -+ u32 phy_init; -+}; -+ -+int cdns_hdmi_probe(struct platform_device *pdev, -+ const struct cdn_plat_data *plat_data); -+void cdns_hdmi_remove(struct platform_device *pdev); -+void cdns_hdmi_unbind(struct device *dev); -+int cdns_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, -+ const struct cdn_plat_data *plat_data); -+void cdns_hdmi_set_sample_rate(struct imx_mhdp_device *hdmi, unsigned int rate); -+void cdns_hdmi_audio_enable(struct imx_mhdp_device *hdmi); -+void cdns_hdmi_audio_disable(struct imx_mhdp_device *hdmi); -+int cdns_dp_probe(struct platform_device *pdev, -+ const struct cdn_plat_data *plat_data); -+void cdns_dp_remove(struct platform_device *pdev); -+void cdns_dp_unbind(struct device *dev); -+int cdns_dp_bind(struct platform_device *pdev, struct drm_encoder *encoder, -+ const struct cdn_plat_data *plat_data); -+ -+#endif /* CDNS_MHDP_IMX_H_ */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0005-gpu-drm-Add-imx8qm-mq-DP-HDMI-driver.patch b/target/linux/layerscape/patches-5.4/805-display-0005-gpu-drm-Add-imx8qm-mq-DP-HDMI-driver.patch deleted file mode 100644 index f4e428bee0..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0005-gpu-drm-Add-imx8qm-mq-DP-HDMI-driver.patch +++ /dev/null @@ -1,2307 +0,0 @@ -From 1433ad0f114ec80b524768af8ec96e09a5bba9b2 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Fri, 23 Aug 2019 14:05:16 +0800 -Subject: [PATCH] gpu: drm: Add imx8qm/mq DP/HDMI driver - -Add imx8qm/mq DP/hdmi driver - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/imx/Kconfig | 9 + - drivers/gpu/drm/imx/Makefile | 1 + - drivers/gpu/drm/imx/cdn-mhdp-dp-phy.c | 533 ++++++++++++++++++++++++ - drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c | 684 ++++++++++++++++++++++++++++++ - drivers/gpu/drm/imx/cdn-mhdp-imx8mq.c | 163 ++++++++ - drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c | 714 ++++++++++++++++++++++++++++++++ - drivers/gpu/drm/imx/cdn-mhdp-phy.h | 153 +++++++ - 7 files changed, 2257 insertions(+) - create mode 100644 drivers/gpu/drm/imx/cdn-mhdp-dp-phy.c - create mode 100644 drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c - create mode 100644 drivers/gpu/drm/imx/cdn-mhdp-imx8mq.c - create mode 100644 drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c - create mode 100644 drivers/gpu/drm/imx/cdn-mhdp-phy.h - ---- a/drivers/gpu/drm/imx/Kconfig -+++ b/drivers/gpu/drm/imx/Kconfig -@@ -39,3 +39,12 @@ config DRM_IMX_HDMI - depends on DRM_IMX - help - Choose this if you want to use HDMI on i.MX6. -+ -+config DRM_IMX_CDNS_MHDP -+ tristate "NXP i.MX MX8 DRM HDMI/DP" -+ select DRM_CDNS_MHDP -+ select DRM_CDNS_DP -+ select DRM_CDNS_HDMI -+ depends on DRM_IMX -+ help -+ Choose this if you want to use HDMI on i.MX8. ---- a/drivers/gpu/drm/imx/Makefile -+++ b/drivers/gpu/drm/imx/Makefile -@@ -9,3 +9,4 @@ obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o - obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o - - obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o -+obj-$(CONFIG_DRM_IMX_CDNS_MHDP) += cdn-mhdp-imx8qm.o cdn-mhdp-imx8mq.o cdn-mhdp-dp-phy.o cdn-mhdp-hdmi-phy.o ---- /dev/null -+++ b/drivers/gpu/drm/imx/cdn-mhdp-dp-phy.c -@@ -0,0 +1,533 @@ -+/* -+ * Cadence Display Port Interface (DP) PHY driver -+ * -+ * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+#include -+#include -+#include -+ -+#include -+#include "cdn-mhdp-phy.h" -+ -+enum dp_link_rate { -+ RATE_1_6 = 162000, -+ RATE_2_1 = 216000, -+ RATE_2_4 = 243000, -+ RATE_2_7 = 270000, -+ RATE_3_2 = 324000, -+ RATE_4_3 = 432000, -+ RATE_5_4 = 540000, -+ RATE_8_1 = 810000, -+}; -+ -+struct phy_pll_reg { -+ u16 val[7]; -+ u32 addr; -+}; -+ -+static const struct phy_pll_reg phy_pll_27m_cfg[] = { -+ /* 1.62 2.16 2.43 2.7 3.24 4.32 5.4 register address */ -+ {{ 0x010E, 0x010E, 0x010E, 0x010E, 0x010E, 0x010E, 0x010E }, CMN_PLL0_VCOCAL_INIT_TMR }, -+ {{ 0x001B, 0x001B, 0x001B, 0x001B, 0x001B, 0x001B, 0x001B }, CMN_PLL0_VCOCAL_ITER_TMR }, -+ {{ 0x30B9, 0x3087, 0x3096, 0x30B4, 0x30B9, 0x3087, 0x30B4 }, CMN_PLL0_VCOCAL_START }, -+ {{ 0x0077, 0x009F, 0x00B3, 0x00C7, 0x0077, 0x009F, 0x00C7 }, CMN_PLL0_INTDIV }, -+ {{ 0xF9DA, 0xF7CD, 0xF6C7, 0xF5C1, 0xF9DA, 0xF7CD, 0xF5C1 }, CMN_PLL0_FRACDIV }, -+ {{ 0x001E, 0x0028, 0x002D, 0x0032, 0x001E, 0x0028, 0x0032 }, CMN_PLL0_HIGH_THR }, -+ {{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_PLL0_DSM_DIAG }, -+ {{ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000 }, CMN_PLLSM0_USER_DEF_CTRL }, -+ {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_OVRD }, -+ {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBH_OVRD }, -+ {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBL_OVRD }, -+ {{ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007 }, CMN_DIAG_PLL0_V2I_TUNE }, -+ {{ 0x0043, 0x0043, 0x0043, 0x0042, 0x0043, 0x0043, 0x0042 }, CMN_DIAG_PLL0_CP_TUNE }, -+ {{ 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008 }, CMN_DIAG_PLL0_LF_PROG }, -+ {{ 0x0100, 0x0001, 0x0001, 0x0001, 0x0100, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE1 }, -+ {{ 0x0007, 0x0001, 0x0001, 0x0001, 0x0007, 0x0001, 0x0001 }, CMN_DIAG_PLL0_PTATIS_TUNE2 }, -+ {{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_DIAG_PLL0_TEST_MODE}, -+ {{ 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016 }, CMN_PSM_CLK_CTRL } -+}; -+ -+static const struct phy_pll_reg phy_pll_24m_cfg[] = { -+ /* 1.62 2.16 2.43 2.7 3.24 4.32 5.4 register address */ -+ {{ 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0 }, CMN_PLL0_VCOCAL_INIT_TMR }, -+ {{ 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018 }, CMN_PLL0_VCOCAL_ITER_TMR }, -+ {{ 0x3061, 0x3092, 0x30B3, 0x30D0, 0x3061, 0x3092, 0x30D0 }, CMN_PLL0_VCOCAL_START }, -+ {{ 0x0086, 0x00B3, 0x00CA, 0x00E0, 0x0086, 0x00B3, 0x00E0 }, CMN_PLL0_INTDIV }, -+ {{ 0xF917, 0xF6C7, 0x75A1, 0xF479, 0xF917, 0xF6C7, 0xF479 }, CMN_PLL0_FRACDIV }, -+ {{ 0x0022, 0x002D, 0x0033, 0x0038, 0x0022, 0x002D, 0x0038 }, CMN_PLL0_HIGH_THR }, -+ {{ 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020 }, CMN_PLL0_DSM_DIAG }, -+ {{ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000 }, CMN_PLLSM0_USER_DEF_CTRL }, -+ {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_OVRD }, -+ {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBH_OVRD }, -+ {{ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, CMN_DIAG_PLL0_FBL_OVRD }, -+ {{ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007 }, CMN_DIAG_PLL0_V2I_TUNE }, -+ {{ 0x0026, 0x0029, 0x0029, 0x0029, 0x0026, 0x0029, 0x0029 }, CMN_DIAG_PLL0_CP_TUNE }, -+ {{ 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008 }, CMN_DIAG_PLL0_LF_PROG }, -+ {{ 0x008C, 0x008C, 0x008C, 0x008C, 0x008C, 0x008C, 0x008C }, CMN_DIAG_PLL0_PTATIS_TUNE1 }, -+ {{ 0x002E, 0x002E, 0x002E, 0x002E, 0x002E, 0x002E, 0x002E }, CMN_DIAG_PLL0_PTATIS_TUNE2 }, -+ {{ 0x0022, 0x0022, 0x0022, 0x0022, 0x0022, 0x0022, 0x0022 }, CMN_DIAG_PLL0_TEST_MODE}, -+ {{ 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016, 0x0016 }, CMN_PSM_CLK_CTRL } -+}; -+ -+static int link_rate_index(u32 rate) -+{ -+ switch (rate) { -+ case RATE_1_6: -+ return 0; -+ case RATE_2_1: -+ return 1; -+ case RATE_2_4: -+ return 2; -+ case RATE_2_7: -+ return 3; -+ case RATE_3_2: -+ return 4; -+ case RATE_4_3: -+ return 5; -+ case RATE_5_4: -+ return 6; -+ default: -+ return -1; -+ } -+} -+ -+static void dp_aux_cfg(struct cdns_mhdp_device *mhdp) -+{ -+ /* Power up Aux */ -+ cdns_phy_reg_write(mhdp, TXDA_CYA_AUXDA_CYA, 1); -+ -+ cdns_phy_reg_write(mhdp, TX_DIG_CTRL_REG_2, 36); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_2, 0x0100); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_2, 0x0300); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_3, 0x0000); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_1, 0x2008); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_1, 0x2018); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_1, 0xA018); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_2, 0x030C); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_5, 0x0000); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_4, 0x1001); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_1, 0xA098); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_1, 0xA198); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_2, 0x030d); -+ ndelay(150); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_2, 0x030f); -+} -+ -+/* PMA common configuration for 24MHz */ -+static void dp_phy_pma_cmn_cfg_24mhz(struct cdns_mhdp_device *mhdp) -+{ -+ int k; -+ u32 num_lanes = mhdp->dp.link.num_lanes; -+ u16 val; -+ -+ val = cdns_phy_reg_read(mhdp, PHY_PMA_CMN_CTRL1); -+ val &= 0xFFF7; -+ val |= 0x0008; -+ cdns_phy_reg_write(mhdp, PHY_PMA_CMN_CTRL1, val); -+ -+ for (k = 0; k < num_lanes; k++) { -+ /* Transceiver control and diagnostic registers */ -+ cdns_phy_reg_write(mhdp, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9), 0x0090); -+ /* Transmitter receiver detect registers */ -+ cdns_phy_reg_write(mhdp, TX_RCVDET_EN_TMR | (k << 9), 0x0960); -+ cdns_phy_reg_write(mhdp, TX_RCVDET_ST_TMR | (k << 9), 0x0030); -+ } -+} -+ -+/* Valid for 24 MHz only */ -+static void dp_phy_pma_cmn_pll0_24mhz(struct cdns_mhdp_device *mhdp) -+{ -+ u32 num_lanes = mhdp->dp.link.num_lanes; -+ u32 link_rate = mhdp->dp.link.rate; -+ u16 val; -+ int index, i, k; -+ -+ /* -+ * PLL reference clock source select -+ * for single ended reference clock val |= 0x0030; -+ * for differential clock val |= 0x0000; -+ */ -+ val = cdns_phy_reg_read(mhdp, PHY_PMA_CMN_CTRL1); -+ val = val & 0xFF8F; -+ val = val | 0x0030; -+ cdns_phy_reg_write(mhdp, PHY_PMA_CMN_CTRL1, val); -+ -+ /* DP PLL data rate 0/1 clock divider value */ -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_CLK_CTL); -+ val &= 0x00FF; -+ if (link_rate <= RATE_2_7) -+ val |= 0x2400; -+ else -+ val |= 0x1200; -+ cdns_phy_reg_write(mhdp, PHY_HDP_CLK_CTL, val); -+ -+ /* High speed clock 0/1 div */ -+ val = cdns_phy_reg_read(mhdp, CMN_DIAG_HSCLK_SEL); -+ val &= 0xFFCC; -+ if (link_rate <= RATE_2_7) -+ val |= 0x0011; -+ cdns_phy_reg_write(mhdp, CMN_DIAG_HSCLK_SEL, val); -+ -+ for (k = 0; k < num_lanes; k = k + 1) { -+ val = cdns_phy_reg_read(mhdp, (XCVR_DIAG_HSCLK_SEL | (k << 9))); -+ val &= 0xCFFF; -+ if (link_rate <= RATE_2_7) -+ val |= 0x1000; -+ cdns_phy_reg_write(mhdp, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val); -+ } -+ -+ /* DP PHY PLL 24MHz configuration */ -+ index = link_rate_index(link_rate); -+ for (i = 0; i < ARRAY_SIZE(phy_pll_24m_cfg); i++) -+ cdns_phy_reg_write(mhdp, phy_pll_24m_cfg[i].addr, phy_pll_24m_cfg[i].val[index]); -+ -+ /* Transceiver control and diagnostic registers */ -+ for (k = 0; k < num_lanes; k = k + 1) { -+ val = cdns_phy_reg_read(mhdp, (XCVR_DIAG_PLLDRC_CTRL | (k << 9))); -+ val &= 0x8FFF; -+ if (link_rate <= RATE_2_7) -+ val |= 0x2000; -+ else -+ val |= 0x1000; -+ cdns_phy_reg_write(mhdp, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val); -+ } -+ -+ for (k = 0; k < num_lanes; k = k + 1) { -+ cdns_phy_reg_write(mhdp, (XCVR_PSM_RCTRL | (k << 9)), 0xBEFC); -+ cdns_phy_reg_write(mhdp, (TX_PSC_A0 | (k << 9)), 0x6799); -+ cdns_phy_reg_write(mhdp, (TX_PSC_A1 | (k << 9)), 0x6798); -+ cdns_phy_reg_write(mhdp, (TX_PSC_A2 | (k << 9)), 0x0098); -+ cdns_phy_reg_write(mhdp, (TX_PSC_A3 | (k << 9)), 0x0098); -+ } -+} -+ -+/* PMA common configuration for 27MHz */ -+static void dp_phy_pma_cmn_cfg_27mhz(struct cdns_mhdp_device *mhdp) -+{ -+ u32 num_lanes = mhdp->dp.link.num_lanes; -+ u16 val; -+ int k; -+ -+ val = cdns_phy_reg_read(mhdp, PHY_PMA_CMN_CTRL1); -+ val &= 0xFFF7; -+ val |= 0x0008; -+ cdns_phy_reg_write(mhdp, PHY_PMA_CMN_CTRL1, val); -+ -+ /* Startup state machine registers */ -+ cdns_phy_reg_write(mhdp, CMN_SSM_BIAS_TMR, 0x0087); -+ cdns_phy_reg_write(mhdp, CMN_PLLSM0_PLLEN_TMR, 0x001B); -+ cdns_phy_reg_write(mhdp, CMN_PLLSM0_PLLPRE_TMR, 0x0036); -+ cdns_phy_reg_write(mhdp, CMN_PLLSM0_PLLVREF_TMR, 0x001B); -+ cdns_phy_reg_write(mhdp, CMN_PLLSM0_PLLLOCK_TMR, 0x006C); -+ -+ /* Current calibration registers */ -+ cdns_phy_reg_write(mhdp, CMN_ICAL_INIT_TMR, 0x0044); -+ cdns_phy_reg_write(mhdp, CMN_ICAL_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(mhdp, CMN_ICAL_ADJ_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(mhdp, CMN_ICAL_ADJ_ITER_TMR, 0x0006); -+ -+ /* Resistor calibration registers */ -+ cdns_phy_reg_write(mhdp, CMN_TXPUCAL_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(mhdp, CMN_TXPUCAL_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(mhdp, CMN_TXPU_ADJ_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(mhdp, CMN_TXPU_ADJ_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(mhdp, CMN_TXPDCAL_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(mhdp, CMN_TXPDCAL_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(mhdp, CMN_TXPD_ADJ_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(mhdp, CMN_TXPD_ADJ_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(mhdp, CMN_RXCAL_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(mhdp, CMN_RXCAL_ITER_TMR, 0x0006); -+ cdns_phy_reg_write(mhdp, CMN_RX_ADJ_INIT_TMR, 0x0022); -+ cdns_phy_reg_write(mhdp, CMN_RX_ADJ_ITER_TMR, 0x0006); -+ -+ for (k = 0; k < num_lanes; k = k + 1) { -+ /* Power state machine registers */ -+ cdns_phy_reg_write(mhdp, XCVR_PSM_CAL_TMR | (k << 9), 0x016D); -+ cdns_phy_reg_write(mhdp, XCVR_PSM_A0IN_TMR | (k << 9), 0x016D); -+ /* Transceiver control and diagnostic registers */ -+ cdns_phy_reg_write(mhdp, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9), 0x00A2); -+ cdns_phy_reg_write(mhdp, TX_DIAG_BGREF_PREDRV_DELAY | (k << 9), 0x0097); -+ /* Transmitter receiver detect registers */ -+ cdns_phy_reg_write(mhdp, TX_RCVDET_EN_TMR | (k << 9), 0x0A8C); -+ cdns_phy_reg_write(mhdp, TX_RCVDET_ST_TMR | (k << 9), 0x0036); -+ } -+} -+ -+static void dp_phy_pma_cmn_pll0_27mhz(struct cdns_mhdp_device *mhdp) -+{ -+ u32 num_lanes = mhdp->dp.link.num_lanes; -+ u32 link_rate = mhdp->dp.link.rate; -+ u16 val; -+ int index, i, k; -+ -+ /* -+ * PLL reference clock source select -+ * for single ended reference clock val |= 0x0030; -+ * for differential clock val |= 0x0000; -+ */ -+ val = cdns_phy_reg_read(mhdp, PHY_PMA_CMN_CTRL1); -+ val &= 0xFF8F; -+ cdns_phy_reg_write(mhdp, PHY_PMA_CMN_CTRL1, val); -+ -+ /* for differential clock on the refclk_p and refclk_m off chip pins: -+ * CMN_DIAG_ACYA[8]=1'b1 -+ */ -+ cdns_phy_reg_write(mhdp, CMN_DIAG_ACYA, 0x0100); -+ -+ /* DP PLL data rate 0/1 clock divider value */ -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_CLK_CTL); -+ val &= 0x00FF; -+ if (link_rate <= RATE_2_7) -+ val |= 0x2400; -+ else -+ val |= 0x1200; -+ cdns_phy_reg_write(mhdp, PHY_HDP_CLK_CTL, val); -+ -+ /* High speed clock 0/1 div */ -+ val = cdns_phy_reg_read(mhdp, CMN_DIAG_HSCLK_SEL); -+ val &= 0xFFCC; -+ if (link_rate <= RATE_2_7) -+ val |= 0x0011; -+ cdns_phy_reg_write(mhdp, CMN_DIAG_HSCLK_SEL, val); -+ -+ for (k = 0; k < num_lanes; k++) { -+ val = cdns_phy_reg_read(mhdp, (XCVR_DIAG_HSCLK_SEL | (k << 9))); -+ val = val & 0xCFFF; -+ if (link_rate <= RATE_2_7) -+ val |= 0x1000; -+ cdns_phy_reg_write(mhdp, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val); -+ } -+ -+ /* DP PHY PLL 27MHz configuration */ -+ index = link_rate_index(link_rate); -+ for (i = 0; i < ARRAY_SIZE(phy_pll_27m_cfg); i++) -+ cdns_phy_reg_write(mhdp, phy_pll_27m_cfg[i].addr, phy_pll_27m_cfg[i].val[index]); -+ -+ /* Transceiver control and diagnostic registers */ -+ for (k = 0; k < num_lanes; k++) { -+ val = cdns_phy_reg_read(mhdp, (XCVR_DIAG_PLLDRC_CTRL | (k << 9))); -+ val = val & 0x8FFF; -+ if (link_rate <= RATE_2_7) -+ val |= 0x2000; -+ else -+ val |= 0x1000; -+ cdns_phy_reg_write(mhdp, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val); -+ } -+ -+ for (k = 0; k < num_lanes; k = k + 1) { -+ /* Power state machine registers */ -+ cdns_phy_reg_write(mhdp, (XCVR_PSM_RCTRL | (k << 9)), 0xBEFC); -+ cdns_phy_reg_write(mhdp, (TX_PSC_A0 | (k << 9)), 0x6799); -+ cdns_phy_reg_write(mhdp, (TX_PSC_A1 | (k << 9)), 0x6798); -+ cdns_phy_reg_write(mhdp, (TX_PSC_A2 | (k << 9)), 0x0098); -+ cdns_phy_reg_write(mhdp, (TX_PSC_A3 | (k << 9)), 0x0098); -+ /* Receiver calibration power state definition register */ -+ val = cdns_phy_reg_read(mhdp, RX_PSC_CAL | (k << 9)); -+ val &= 0xFFBB; -+ cdns_phy_reg_write(mhdp, (RX_PSC_CAL | (k << 9)), val); -+ val = cdns_phy_reg_read(mhdp, RX_PSC_A0 | (k << 9)); -+ val &= 0xFFBB; -+ cdns_phy_reg_write(mhdp, (RX_PSC_A0 | (k << 9)), val); -+ } -+} -+ -+static void dp_phy_power_down(struct cdns_mhdp_device *mhdp) -+{ -+ u16 val; -+ int i; -+ -+ if (!mhdp->power_up) -+ return; -+ -+ /* Place the PHY lanes in the A3 power state. */ -+ cdns_phy_reg_write(mhdp, PHY_HDP_MODE_CTRL, 0x8); -+ /* Wait for Power State A3 Ack */ -+ for (i = 0; i < 10; i++) { -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_MODE_CTRL); -+ if (val & (1 << 7)) -+ break; -+ msleep(20); -+ } -+ if (i == 10) { -+ dev_err(mhdp->dev, "Wait A3 Ack failed\n"); -+ return; -+ } -+ -+ /* Disable HDP PLL’s data rate and full rate clocks out of PMA. */ -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_CLK_CTL); -+ val &= ~(1 << 2); -+ cdns_phy_reg_write(mhdp, PHY_HDP_CLK_CTL, val); -+ /* Wait for PLL clock gate ACK */ -+ for (i = 0; i < 10; i++) { -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_CLK_CTL); -+ if (!(val & (1 << 3))) -+ break; -+ msleep(20); -+ } -+ if (i == 10) { -+ dev_err(mhdp->dev, "Wait PLL clock gate Ack failed\n"); -+ return; -+ } -+ -+ /* Disable HDP PLL’s for high speed clocks */ -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_CLK_CTL); -+ val &= ~(1 << 0); -+ cdns_phy_reg_write(mhdp, PHY_HDP_CLK_CTL, val); -+ /* Wait for PLL disable ACK */ -+ for (i = 0; i < 10; i++) { -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_CLK_CTL); -+ if (!(val & (1 << 1))) -+ break; -+ msleep(20); -+ } -+ if (i == 10) { -+ dev_err(mhdp->dev, "Wait PLL disable Ack failed\n"); -+ return; -+ } -+} -+ -+static int dp_phy_power_up(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val, i; -+ -+ /* Enable HDP PLL’s for high speed clocks */ -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_CLK_CTL); -+ val |= (1 << 0); -+ cdns_phy_reg_write(mhdp, PHY_HDP_CLK_CTL, val); -+ /* Wait for PLL ready ACK */ -+ for (i = 0; i < 10; i++) { -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_CLK_CTL); -+ if (val & (1 << 1)) -+ break; -+ msleep(20); -+ } -+ if (i == 10) { -+ dev_err(mhdp->dev, "Wait PLL Ack failed\n"); -+ return -1; -+ } -+ -+ /* Enable HDP PLL’s data rate and full rate clocks out of PMA. */ -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_CLK_CTL); -+ val |= (1 << 2); -+ cdns_phy_reg_write(mhdp, PHY_HDP_CLK_CTL, val); -+ /* Wait for PLL clock enable ACK */ -+ for (i = 0; i < 10; i++) { -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_CLK_CTL); -+ if (val & (1 << 3)) -+ break; -+ msleep(20); -+ } -+ if (i == 10) { -+ dev_err(mhdp->dev, "Wait PLL clock enable ACk failed\n"); -+ return -1; -+ } -+ -+ /* Configure PHY in A2 Mode */ -+ cdns_phy_reg_write(mhdp, PHY_HDP_MODE_CTRL, 0x0004); -+ /* Wait for Power State A2 Ack */ -+ for (i = 0; i < 10; i++) { -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_MODE_CTRL); -+ if (val & (1 << 6)) -+ break; -+ msleep(20); -+ } -+ if (i == 10) { -+ dev_err(mhdp->dev, "Wait A2 Ack failed\n"); -+ return -1; -+ } -+ -+ /* Configure PHY in A0 mode (PHY must be in the A0 power -+ * state in order to transmit data) -+ */ -+ cdns_phy_reg_write(mhdp, PHY_HDP_MODE_CTRL, 0x0101); -+ -+ /* Wait for Power State A0 Ack */ -+ for (i = 0; i < 10; i++) { -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_MODE_CTRL); -+ if (val & (1 << 4)) -+ break; -+ msleep(20); -+ } -+ if (i == 10) { -+ dev_err(mhdp->dev, "Wait A0 Ack failed\n"); -+ return -1; -+ } -+ -+ mhdp->power_up = true; -+ -+ return 0; -+} -+ -+int cdns_dp_phy_init_imx8mq(struct imx_mhdp_device *hdp) -+{ -+ struct cdns_mhdp_device *mhdp = &hdp->mhdp; -+ int ret; -+ -+ /* Disable phy clock if PHY in power up state */ -+ dp_phy_power_down(mhdp); -+ -+ dp_phy_pma_cmn_cfg_27mhz(mhdp); -+ -+ dp_phy_pma_cmn_pll0_27mhz(mhdp); -+ -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_0, 1); -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_1, 1); -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_2, 1); -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_3, 1); -+ -+ /* PHY power up */ -+ ret = dp_phy_power_up(mhdp); -+ if (ret < 0) -+ return ret; -+ -+ dp_aux_cfg(mhdp); -+ -+ return ret; -+} -+ -+ -+int cdns_dp_phy_init_imx8qm(struct imx_mhdp_device *hdp) -+{ -+ struct cdns_mhdp_device *mhdp = &hdp->mhdp; -+ int ret; -+ -+ /* Disable phy clock if PHY in power up state */ -+ dp_phy_power_down(mhdp); -+ -+ dp_phy_pma_cmn_cfg_24mhz(mhdp); -+ -+ dp_phy_pma_cmn_pll0_24mhz(mhdp); -+ -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_0, 1); -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_1, 1); -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_2, 1); -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_3, 1); -+ -+ /* PHY power up */ -+ ret = dp_phy_power_up(mhdp); -+ if (ret < 0) -+ return ret; -+ -+ dp_aux_cfg(mhdp); -+ -+ return true; -+} ---- /dev/null -+++ b/drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c -@@ -0,0 +1,684 @@ -+/* -+ * Cadence High-Definition Multimedia Interface (HDMI) driver -+ * -+ * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include "cdn-mhdp-phy.h" -+ -+/* HDMI TX clock control settings */ -+struct hdmi_ctrl { -+ u32 pixel_clk_freq_min; -+ u32 pixel_clk_freq_max; -+ u32 feedback_factor; -+ u32 data_range_kbps_min; -+ u32 data_range_kbps_max; -+ u32 cmnda_pll0_ip_div; -+ u32 cmn_ref_clk_dig_div; -+ u32 ref_clk_divider_scaler; -+ u32 pll_fb_div_total; -+ u32 cmnda_pll0_fb_div_low; -+ u32 cmnda_pll0_fb_div_high; -+ u32 pixel_div_total; -+ u32 cmnda_pll0_pxdiv_low; -+ u32 cmnda_pll0_pxdiv_high; -+ u32 vco_freq_min; -+ u32 vco_freq_max; -+ u32 vco_ring_select; -+ u32 cmnda_hs_clk_0_sel; -+ u32 cmnda_hs_clk_1_sel; -+ u32 hsclk_div_at_xcvr; -+ u32 hsclk_div_tx_sub_rate; -+ u32 cmnda_pll0_hs_sym_div_sel; -+ u32 cmnda_pll0_clk_freq_min; -+ u32 cmnda_pll0_clk_freq_max; -+}; -+ -+/* HDMI TX clock control settings, pixel clock is output */ -+static const struct hdmi_ctrl imx8mq_ctrl_table[] = { -+/*Minclk Maxclk Fdbak DR_min DR_max ip_d dig DS Totl */ -+{ 27000, 27000, 1000, 270000, 270000, 0x03, 0x1, 0x1, 240, 0x0BC, 0x030, 80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x3, 27000, 27000}, -+{ 27000, 27000, 1250, 337500, 337500, 0x03, 0x1, 0x1, 300, 0x0EC, 0x03C, 100, 0x030, 0x030, 2700000, 2700000, 0, 2, 2, 2, 4, 0x3, 33750, 33750}, -+{ 27000, 27000, 1500, 405000, 405000, 0x03, 0x1, 0x1, 360, 0x11C, 0x048, 120, 0x03A, 0x03A, 3240000, 3240000, 0, 2, 2, 2, 4, 0x3, 40500, 40500}, -+{ 27000, 27000, 2000, 540000, 540000, 0x03, 0x1, 0x1, 240, 0x0BC, 0x030, 80, 0x026, 0x026, 2160000, 2160000, 0, 2, 2, 2, 4, 0x2, 54000, 54000}, -+{ 54000, 54000, 1000, 540000, 540000, 0x03, 0x1, 0x1, 480, 0x17C, 0x060, 80, 0x026, 0x026, 4320000, 4320000, 1, 2, 2, 2, 4, 0x3, 54000, 54000}, -+{ 54000, 54000, 1250, 675000, 675000, 0x04, 0x1, 0x1, 400, 0x13C, 0x050, 50, 0x017, 0x017, 2700000, 2700000, 0, 1, 1, 2, 4, 0x2, 67500, 67500}, -+{ 54000, 54000, 1500, 810000, 810000, 0x04, 0x1, 0x1, 480, 0x17C, 0x060, 60, 0x01C, 0x01C, 3240000, 3240000, 0, 2, 2, 2, 2, 0x2, 81000, 81000}, -+{ 54000, 54000, 2000, 1080000, 1080000, 0x03, 0x1, 0x1, 240, 0x0BC, 0x030, 40, 0x012, 0x012, 2160000, 2160000, 0, 2, 2, 2, 1, 0x1, 108000, 108000}, -+{ 74250, 74250, 1000, 742500, 742500, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 80, 0x026, 0x026, 5940000, 5940000, 1, 2, 2, 2, 4, 0x3, 74250, 74250}, -+{ 74250, 74250, 1250, 928125, 928125, 0x04, 0x1, 0x1, 550, 0x1B4, 0x06E, 50, 0x017, 0x017, 3712500, 3712500, 1, 1, 1, 2, 4, 0x2, 92812, 92812}, -+{ 74250, 74250, 1500, 1113750, 1113750, 0x04, 0x1, 0x1, 660, 0x20C, 0x084, 60, 0x01C, 0x01C, 4455000, 4455000, 1, 2, 2, 2, 2, 0x2, 111375, 111375}, -+{ 74250, 74250, 2000, 1485000, 1485000, 0x03, 0x1, 0x1, 330, 0x104, 0x042, 40, 0x012, 0x012, 2970000, 2970000, 0, 2, 2, 2, 1, 0x1, 148500, 148500}, -+{ 99000, 99000, 1000, 990000, 990000, 0x03, 0x1, 0x1, 440, 0x15C, 0x058, 40, 0x012, 0x012, 3960000, 3960000, 1, 2, 2, 2, 2, 0x2, 99000, 99000}, -+{ 99000, 99000, 1250, 1237500, 1237500, 0x03, 0x1, 0x1, 275, 0x0D8, 0x037, 25, 0x00B, 0x00A, 2475000, 2475000, 0, 1, 1, 2, 2, 0x1, 123750, 123750}, -+{ 99000, 99000, 1500, 1485000, 1485000, 0x03, 0x1, 0x1, 330, 0x104, 0x042, 30, 0x00D, 0x00D, 2970000, 2970000, 0, 2, 2, 2, 1, 0x1, 148500, 148500}, -+{ 99000, 99000, 2000, 1980000, 1980000, 0x03, 0x1, 0x1, 440, 0x15C, 0x058, 40, 0x012, 0x012, 3960000, 3960000, 1, 2, 2, 2, 1, 0x1, 198000, 198000}, -+{148500, 148500, 1000, 1485000, 1485000, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 40, 0x012, 0x012, 5940000, 5940000, 1, 2, 2, 2, 2, 0x2, 148500, 148500}, -+{148500, 148500, 1250, 1856250, 1856250, 0x04, 0x1, 0x1, 550, 0x1B4, 0x06E, 25, 0x00B, 0x00A, 3712500, 3712500, 1, 1, 1, 2, 2, 0x1, 185625, 185625}, -+{148500, 148500, 1500, 2227500, 2227500, 0x03, 0x1, 0x1, 495, 0x188, 0x063, 30, 0x00D, 0x00D, 4455000, 4455000, 1, 1, 1, 2, 2, 0x1, 222750, 222750}, -+{148500, 148500, 2000, 2970000, 2970000, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 40, 0x012, 0x012, 5940000, 5940000, 1, 2, 2, 2, 1, 0x1, 297000, 297000}, -+{198000, 198000, 1000, 1980000, 1980000, 0x03, 0x1, 0x1, 220, 0x0AC, 0x02C, 10, 0x003, 0x003, 1980000, 1980000, 0, 1, 1, 2, 1, 0x0, 198000, 198000}, -+{198000, 198000, 1250, 2475000, 2475000, 0x03, 0x1, 0x1, 550, 0x1B4, 0x06E, 25, 0x00B, 0x00A, 4950000, 4950000, 1, 1, 1, 2, 2, 0x1, 247500, 247500}, -+{198000, 198000, 1500, 2970000, 2970000, 0x03, 0x1, 0x1, 330, 0x104, 0x042, 15, 0x006, 0x005, 2970000, 2970000, 0, 1, 1, 2, 1, 0x0, 297000, 297000}, -+{198000, 198000, 2000, 3960000, 3960000, 0x03, 0x1, 0x1, 440, 0x15C, 0x058, 20, 0x008, 0x008, 3960000, 3960000, 1, 1, 1, 2, 1, 0x0, 396000, 396000}, -+{297000, 297000, 1000, 2970000, 2970000, 0x03, 0x1, 0x1, 330, 0x104, 0x042, 10, 0x003, 0x003, 2970000, 2970000, 0, 1, 1, 2, 1, 0x0, 297000, 297000}, -+{297000, 297000, 1500, 4455000, 4455000, 0x03, 0x1, 0x1, 495, 0x188, 0x063, 15, 0x006, 0x005, 4455000, 4455000, 1, 1, 1, 2, 1, 0x0, 445500, 445500}, -+{297000, 297000, 2000, 5940000, 5940000, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 20, 0x008, 0x008, 5940000, 5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000}, -+{594000, 594000, 1000, 5940000, 5940000, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 10, 0x003, 0x003, 5940000, 5940000, 1, 1, 1, 2, 1, 0x0, 594000, 594000}, -+{594000, 594000, 750, 4455000, 4455000, 0x03, 0x1, 0x1, 495, 0x188, 0x063, 10, 0x003, 0x003, 4455000, 4455000, 1, 1, 1, 2, 1, 0x0, 445500, 445500}, -+{594000, 594000, 625, 3712500, 3712500, 0x04, 0x1, 0x1, 550, 0x1B4, 0x06E, 10, 0x003, 0x003, 3712500, 3712500, 1, 1, 1, 2, 1, 0x0, 371250, 371250}, -+{594000, 594000, 500, 2970000, 2970000, 0x03, 0x1, 0x1, 660, 0x20C, 0x084, 10, 0x003, 0x003, 5940000, 5940000, 1, 1, 1, 2, 2, 0x1, 297000, 297000}, -+}; -+ -+/* HDMI TX clock control settings, pixel clock is input */ -+static const struct hdmi_ctrl imx8qm_ctrl_table[] = { -+/*pclk_l pclk_h fd DRR_L DRR_H PLLD */ -+{ 25000, 42500, 1000, 250000, 425000, 0x05, 0x01, 0x01, 400, 0x182, 0x00A, 0, 0, 0, 2000000, 3400000, 0, 2, 2, 2, 4, 0x03, 25000, 42500}, -+{ 42500, 85000, 1000, 425000, 850000, 0x08, 0x03, 0x01, 320, 0x132, 0x00A, 0, 0, 0, 1700000, 3400000, 0, 1, 1, 2, 4, 0x02, 42500, 85000}, -+{ 85000, 170000, 1000, 850000, 1700000, 0x11, 0x00, 0x07, 340, 0x146, 0x00A, 0, 0, 0, 1700000, 3400000, 0, 1, 1, 2, 2, 0x01, 85000, 170000}, -+{170000, 340000, 1000, 1700000, 3400000, 0x22, 0x01, 0x07, 340, 0x146, 0x00A, 0, 0, 0, 1700000, 3400000, 0, 1, 1, 2, 1, 0x00, 170000, 340000}, -+{340000, 600000, 1000, 3400000, 6000000, 0x3C, 0x03, 0x06, 600, 0x24A, 0x00A, 0, 0, 0, 3400000, 6000000, 1, 1, 1, 2, 1, 0x00, 340000, 600000}, -+{ 25000, 34000, 1205, 312500, 425000, 0x04, 0x01, 0x01, 400, 0x182, 0x00A, 0, 0, 0, 2500000, 3400000, 0, 2, 2, 2, 4, 0x03, 31250, 42500}, -+{ 34000, 68000, 1205, 425000, 850000, 0x06, 0x02, 0x01, 300, 0x11E, 0x00A, 0, 0, 0, 1700000, 3400000, 0, 1, 1, 2, 4, 0x02, 42500, 85000}, -+{ 68000, 136000, 1205, 850000, 1700000, 0x0D, 0x02, 0x02, 325, 0x137, 0x00A, 0, 0, 0, 1700000, 3400000, 0, 1, 1, 2, 2, 0x01, 85000, 170000}, -+{136000, 272000, 1205, 1700000, 3400000, 0x1A, 0x02, 0x04, 325, 0x137, 0x00A, 0, 0, 0, 1700000, 3400000, 0, 1, 1, 2, 1, 0x00, 170000, 340000}, -+{272000, 480000, 1205, 3400000, 6000000, 0x30, 0x03, 0x05, 600, 0x24A, 0x00A, 0, 0, 0, 3400000, 6000000, 1, 1, 1, 2, 1, 0x00, 340000, 600000}, -+{ 25000, 28000, 1500, 375000, 420000, 0x03, 0x01, 0x01, 360, 0x15A, 0x00A, 0, 0, 0, 3000000, 3360000, 0, 2, 2, 2, 4, 0x03, 37500, 42000}, -+{ 28000, 56000, 1500, 420000, 840000, 0x06, 0x02, 0x01, 360, 0x15A, 0x00A, 0, 0, 0, 1680000, 3360000, 0, 1, 1, 2, 4, 0x02, 42000, 84000}, -+{ 56000, 113000, 1500, 840000, 1695000, 0x0B, 0x00, 0x05, 330, 0x13C, 0x00A, 0, 0, 0, 1680000, 3390000, 0, 1, 1, 2, 2, 0x01, 84000, 169500}, -+{113000, 226000, 1500, 1695000, 3390000, 0x16, 0x01, 0x05, 330, 0x13C, 0x00A, 0, 0, 0, 1695000, 3390000, 0, 1, 1, 2, 1, 0x00, 169500, 339000}, -+{226000, 400000, 1500, 3390000, 6000000, 0x28, 0x03, 0x04, 600, 0x24A, 0x00A, 0, 0, 0, 3390000, 6000000, 1, 1, 1, 2, 1, 0x00, 339000, 600000}, -+{ 25000, 42500, 2000, 500000, 850000, 0x05, 0x01, 0x01, 400, 0x182, 0x00A, 0, 0, 0, 2000000, 3400000, 0, 1, 1, 2, 4, 0x02, 50000, 85000}, -+{ 42500, 85000, 2000, 850000, 1700000, 0x08, 0x03, 0x01, 320, 0x132, 0x00A, 0, 0, 0, 1700000, 3400000, 0, 1, 1, 2, 2, 0x01, 85000, 170000}, -+{ 85000, 170000, 2000, 1700000, 3400000, 0x11, 0x00, 0x07, 340, 0x146, 0x00A, 0, 0, 0, 1700000, 3400000, 0, 1, 1, 2, 1, 0x00, 170000, 340000}, -+{170000, 300000, 2000, 3400000, 6000000, 0x22, 0x01, 0x06, 680, 0x29A, 0x00A, 0, 0, 0, 3400000, 6000000, 1, 1, 1, 2, 1, 0x00, 340000, 600000}, -+{594000, 594000, 5000, 2970000, 2970000, 0x3C, 0x03, 0x06, 600, 0x24A, 0x00A, 0, 0, 0, 5940000, 5940000, 1, 1, 1, 2, 2, 0x01, 297000, 297000}, -+{594000, 594000, 6250, 3712500, 3712500, 0x3C, 0x03, 0x06, 375, 0x169, 0x00A, 0, 0, 0, 3712500, 3712500, 1, 1, 1, 2, 1, 0x00, 371250, 371250}, -+{594000, 594000, 7500, 4455000, 4455000, 0x3C, 0x03, 0x06, 450, 0x1B4, 0x00A, 0, 0, 0, 4455000, 4455000, 1, 1, 1, 2, 1, 0x00, 445500, 445500}, -+}; -+ -+/* HDMI TX PLL tuning settings */ -+struct hdmi_pll_tuning { -+ u32 vco_freq_bin; -+ u32 vco_freq_min; -+ u32 vco_freq_max; -+ u32 volt_to_current_coarse; -+ u32 volt_to_current; -+ u32 ndac_ctrl; -+ u32 pmos_ctrl; -+ u32 ptat_ndac_ctrl; -+ u32 feedback_div_total; -+ u32 charge_pump_gain; -+ u32 coarse_code; -+ u32 v2i_code; -+ u32 vco_cal_code; -+}; -+ -+/* HDMI TX PLL tuning settings, pixel clock is output */ -+static const struct hdmi_pll_tuning imx8mq_pll_table[] = { -+/* bin VCO_freq min/max coar cod NDAC PMOS PTAT div-T P-Gain Coa V2I CAL */ -+ { 1, 1980000, 1980000, 0x4, 0x3, 0x0, 0x09, 0x09, 220, 0x42, 160, 5, 183 }, -+ { 2, 2160000, 2160000, 0x4, 0x3, 0x0, 0x09, 0x09, 240, 0x42, 166, 6, 208 }, -+ { 3, 2475000, 2475000, 0x5, 0x3, 0x1, 0x00, 0x07, 275, 0x42, 167, 6, 209 }, -+ { 4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 300, 0x42, 188, 6, 230 }, -+ { 4, 2700000, 2700000, 0x5, 0x3, 0x1, 0x00, 0x07, 400, 0x4C, 188, 6, 230 }, -+ { 5, 2970000, 2970000, 0x6, 0x3, 0x1, 0x00, 0x07, 330, 0x42, 183, 6, 225 }, -+ { 6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 360, 0x42, 203, 7, 256 }, -+ { 6, 3240000, 3240000, 0x6, 0x3, 0x1, 0x00, 0x07, 480, 0x4C, 203, 7, 256 }, -+ { 7, 3712500, 3712500, 0x4, 0x3, 0x0, 0x07, 0x0F, 550, 0x4C, 212, 7, 257 }, -+ { 8, 3960000, 3960000, 0x5, 0x3, 0x0, 0x07, 0x0F, 440, 0x42, 184, 6, 226 }, -+ { 9, 4320000, 4320000, 0x5, 0x3, 0x1, 0x07, 0x0F, 480, 0x42, 205, 7, 258 }, -+ { 10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 495, 0x42, 219, 7, 272 }, -+ { 10, 4455000, 4455000, 0x5, 0x3, 0x0, 0x07, 0x0F, 660, 0x4C, 219, 7, 272 }, -+ { 11, 4950000, 4950000, 0x6, 0x3, 0x1, 0x00, 0x07, 550, 0x42, 213, 7, 258 }, -+ { 12, 5940000, 5940000, 0x7, 0x3, 0x1, 0x00, 0x07, 660, 0x42, 244, 8, 292 }, -+}; -+ -+/* HDMI TX PLL tuning settings, pixel clock is input */ -+static const struct hdmi_pll_tuning imx8qm_pll_table[] = { -+/* bin VCO_freq min/max coar cod NDAC PMOS PTAT div-T P-Gain pad only */ -+ { 0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 300, 0x08D, 0, 0, 0 }, -+ { 0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 320, 0x08E, 0, 0, 0 }, -+ { 0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 325, 0x08E, 0, 0, 0 }, -+ { 0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 330, 0x08E, 0, 0, 0 }, -+ { 0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 340, 0x08F, 0, 0, 0 }, -+ { 0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 360, 0x0A7, 0, 0, 0 }, -+ { 0, 1700000, 2000000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 400, 0x0C5, 0, 0, 0 }, -+ { 1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 300, 0x086, 0, 0, 0 }, -+ { 1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 320, 0x087, 0, 0, 0 }, -+ { 1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 325, 0x087, 0, 0, 0 }, -+ { 1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 330, 0x104, 0, 0, 0 }, -+ { 1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 340, 0x08B, 0, 0, 0 }, -+ { 1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 360, 0x08D, 0, 0, 0 }, -+ { 1, 2000000, 2400000, 0x3, 0x1, 0x0, 0x8C, 0x2E, 400, 0x0A6, 0, 0, 0 }, -+ { 2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 300, 0x04E, 0, 0, 0 }, -+ { 2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 320, 0x04F, 0, 0, 0 }, -+ { 2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 325, 0x04F, 0, 0, 0 }, -+ { 2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 330, 0x085, 0, 0, 0 }, -+ { 2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 340, 0x085, 0, 0, 0 }, -+ { 2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 360, 0x086, 0, 0, 0 }, -+ { 2, 2400000, 2800000, 0x3, 0x1, 0x0, 0x04, 0x0D, 400, 0x08B, 0, 0, 0 }, -+ { 3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 300, 0x047, 0, 0, 0 }, -+ { 3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 320, 0x04B, 0, 0, 0 }, -+ { 3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 325, 0x04B, 0, 0, 0 }, -+ { 3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 330, 0x04B, 0, 0, 0 }, -+ { 3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 340, 0x04D, 0, 0, 0 }, -+ { 3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 360, 0x04E, 0, 0, 0 }, -+ { 3, 2800000, 3400000, 0x3, 0x1, 0x0, 0x04, 0x0D, 400, 0x085, 0, 0, 0 }, -+ { 4, 3400000, 3900000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 375, 0x041, 0, 0, 0 }, -+ { 4, 3400000, 3900000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 600, 0x08D, 0, 0, 0 }, -+ { 4, 3400000, 3900000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 680, 0x0A6, 0, 0, 0 }, -+ { 5, 3900000, 4500000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 450, 0x041, 0, 0, 0 }, -+ { 5, 3900000, 4500000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 600, 0x087, 0, 0, 0 }, -+ { 5, 3900000, 4500000, 0x7, 0x1, 0x0, 0x8E, 0x2F, 680, 0x0A4, 0, 0, 0 }, -+ { 6, 4500000, 5200000, 0x7, 0x1, 0x0, 0x04, 0x0D, 600, 0x04F, 0, 0, 0 }, -+ { 6, 4500000, 5200000, 0x7, 0x1, 0x0, 0x04, 0x0D, 680, 0x086, 0, 0, 0 }, -+ { 7, 5200000, 6000000, 0x7, 0x1, 0x0, 0x04, 0x0D, 600, 0x04D, 0, 0, 0 }, -+ { 7, 5200000, 6000000, 0x7, 0x1, 0x0, 0x04, 0x0D, 680, 0x04F, 0, 0, 0 } -+}; -+ -+static void hdmi_phy_set_vswing(struct cdns_mhdp_device *mhdp) -+{ -+ const u32 num_lanes = 4; -+ u32 k; -+ -+ for (k = 0; k < num_lanes; k++) { -+ cdns_phy_reg_write(mhdp, (TX_DIAG_TX_DRV | (k << 9)), 0x7c0); -+ cdns_phy_reg_write(mhdp, (TX_TXCC_CPOST_MULT_00_0 | (k << 9)), 0x0); -+ cdns_phy_reg_write(mhdp, (TX_TXCC_CAL_SCLR_MULT_0 | (k << 9)), 0x120); -+ } -+} -+ -+static int hdmi_feedback_factor(struct cdns_mhdp_device *mhdp) -+{ -+ u32 feedback_factor; -+ -+ switch (mhdp->video_info.color_fmt) { -+ case YCBCR_4_2_2: -+ feedback_factor = 1000; -+ break; -+ case YCBCR_4_2_0: -+ switch (mhdp->video_info.color_depth) { -+ case 8: -+ feedback_factor = 500; -+ break; -+ case 10: -+ feedback_factor = 625; -+ break; -+ case 12: -+ feedback_factor = 750; -+ break; -+ case 16: -+ feedback_factor = 1000; -+ break; -+ default: -+ DRM_ERROR("Invalid ColorDepth\n"); -+ return 0; -+ } -+ break; -+ default: -+ /* Assume RGB/YUV444 */ -+ switch (mhdp->video_info.color_depth) { -+ case 10: -+ feedback_factor = 1250; -+ break; -+ case 12: -+ feedback_factor = 1500; -+ break; -+ case 16: -+ feedback_factor = 2000; -+ break; -+ default: -+ feedback_factor = 1000; -+ } -+ } -+ return feedback_factor; -+} -+ -+static int hdmi_phy_config(struct cdns_mhdp_device *mhdp, -+ const struct hdmi_ctrl *p_ctrl_table, -+ const struct hdmi_pll_tuning *p_pll_table, -+ char pclk_in) -+{ -+ const u32 num_lanes = 4; -+ u32 val, i, k; -+ -+ /* enable PHY isolation mode only for CMN */ -+ cdns_phy_reg_write(mhdp, PHY_PMA_ISOLATION_CTRL, 0xD000); -+ -+ /* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div dividers */ -+ val = cdns_phy_reg_read(mhdp, PHY_PMA_ISO_PLL_CTRL1); -+ val &= 0xFF00; -+ val |= 0x0012; -+ cdns_phy_reg_write(mhdp, PHY_PMA_ISO_PLL_CTRL1, val); -+ -+ /* assert PHY reset from isolation register */ -+ cdns_phy_reg_write(mhdp, PHY_ISO_CMN_CTRL, 0x0000); -+ /* assert PMA CMN reset */ -+ cdns_phy_reg_write(mhdp, PHY_PMA_ISO_CMN_CTRL, 0x0000); -+ -+ /* register XCVR_DIAG_BIDI_CTRL */ -+ for (k = 0; k < num_lanes; k++) -+ cdns_phy_reg_write(mhdp, XCVR_DIAG_BIDI_CTRL | (k << 9), 0x00FF); -+ -+ /* Describing Task phy_cfg_hdp */ -+ -+ val = cdns_phy_reg_read(mhdp, PHY_PMA_CMN_CTRL1); -+ val &= 0xFFF7; -+ val |= 0x0008; -+ cdns_phy_reg_write(mhdp, PHY_PMA_CMN_CTRL1, val); -+ -+ /* PHY Registers */ -+ val = cdns_phy_reg_read(mhdp, PHY_PMA_CMN_CTRL1); -+ val &= 0xCFFF; -+ val |= p_ctrl_table->cmn_ref_clk_dig_div << 12; -+ cdns_phy_reg_write(mhdp, PHY_PMA_CMN_CTRL1, val); -+ -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_CLK_CTL); -+ val &= 0x00FF; -+ val |= 0x1200; -+ cdns_phy_reg_write(mhdp, PHY_HDP_CLK_CTL, val); -+ -+ /* Common control module control and diagnostic registers */ -+ val = cdns_phy_reg_read(mhdp, CMN_CDIAG_REFCLK_CTRL); -+ val &= 0x8FFF; -+ val |= p_ctrl_table->ref_clk_divider_scaler << 12; -+ val |= 0x00C0; -+ cdns_phy_reg_write(mhdp, CMN_CDIAG_REFCLK_CTRL, val); -+ -+ /* High speed clock used */ -+ val = cdns_phy_reg_read(mhdp, CMN_DIAG_HSCLK_SEL); -+ val &= 0xFF00; -+ val |= (p_ctrl_table->cmnda_hs_clk_0_sel >> 1) << 0; -+ val |= (p_ctrl_table->cmnda_hs_clk_1_sel >> 1) << 4; -+ cdns_phy_reg_write(mhdp, CMN_DIAG_HSCLK_SEL, val); -+ -+ for (k = 0; k < num_lanes; k++) { -+ val = cdns_phy_reg_read(mhdp, (XCVR_DIAG_HSCLK_SEL | (k << 9))); -+ val &= 0xCFFF; -+ val |= (p_ctrl_table->cmnda_hs_clk_0_sel >> 1) << 12; -+ cdns_phy_reg_write(mhdp, (XCVR_DIAG_HSCLK_SEL | (k << 9)), val); -+ } -+ -+ /* PLL 0 control state machine registers */ -+ val = p_ctrl_table->vco_ring_select << 12; -+ cdns_phy_reg_write(mhdp, CMN_PLLSM0_USER_DEF_CTRL, val); -+ -+ if (pclk_in == true) -+ val = 0x30A0; -+ else { -+ val = cdns_phy_reg_read(mhdp, CMN_PLL0_VCOCAL_START); -+ val &= 0xFE00; -+ val |= p_pll_table->vco_cal_code; -+ } -+ cdns_phy_reg_write(mhdp, CMN_PLL0_VCOCAL_START, val); -+ -+ cdns_phy_reg_write(mhdp, CMN_PLL0_VCOCAL_INIT_TMR, 0x0064); -+ cdns_phy_reg_write(mhdp, CMN_PLL0_VCOCAL_ITER_TMR, 0x000A); -+ -+ /* Common functions control and diagnostics registers */ -+ val = p_ctrl_table->cmnda_pll0_hs_sym_div_sel << 8; -+ val |= p_ctrl_table->cmnda_pll0_ip_div; -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_INCLK_CTRL, val); -+ -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_OVRD, 0x0000); -+ -+ val = p_ctrl_table->cmnda_pll0_fb_div_high; -+ val |= (1 << 15); -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_FBH_OVRD, val); -+ -+ val = p_ctrl_table->cmnda_pll0_fb_div_low; -+ val |= (1 << 15); -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_FBL_OVRD, val); -+ -+ if (pclk_in == false) { -+ val = p_ctrl_table->cmnda_pll0_pxdiv_low; -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_PXL_DIVL, val); -+ -+ val = p_ctrl_table->cmnda_pll0_pxdiv_high; -+ val |= (1 << 15); -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_PXL_DIVH, val); -+ } -+ -+ val = p_pll_table->volt_to_current_coarse; -+ val |= (p_pll_table->volt_to_current) << 4; -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_V2I_TUNE, val); -+ -+ val = p_pll_table->charge_pump_gain; -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_CP_TUNE, val); -+ -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_LF_PROG, 0x0008); -+ -+ val = p_pll_table->pmos_ctrl; -+ val |= (p_pll_table->ndac_ctrl) << 8; -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_PTATIS_TUNE1, val); -+ -+ val = p_pll_table->ptat_ndac_ctrl; -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_PTATIS_TUNE2, val); -+ -+ if (pclk_in == true) -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_TEST_MODE, 0x0022); -+ else -+ cdns_phy_reg_write(mhdp, CMN_DIAG_PLL0_TEST_MODE, 0x0020); -+ cdns_phy_reg_write(mhdp, CMN_PSM_CLK_CTRL, 0x0016); -+ -+ /* Transceiver control and diagnostic registers */ -+ for (k = 0; k < num_lanes; k++) { -+ val = cdns_phy_reg_read(mhdp, (XCVR_DIAG_PLLDRC_CTRL | (k << 9))); -+ val &= 0xBFFF; -+ cdns_phy_reg_write(mhdp, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), val); -+ } -+ -+ for (k = 0; k < num_lanes; k++) { -+ val = cdns_phy_reg_read(mhdp, (TX_DIAG_TX_CTRL | (k << 9))); -+ val &= 0xFF3F; -+ val |= (p_ctrl_table->hsclk_div_tx_sub_rate >> 1) << 6; -+ cdns_phy_reg_write(mhdp, (TX_DIAG_TX_CTRL | (k << 9)), val); -+ } -+ -+ /* -+ * for single ended reference clock val |= 0x0030; -+ * for differential clock val |= 0x0000; -+ */ -+ val = cdns_phy_reg_read(mhdp, PHY_PMA_CMN_CTRL1); -+ val &= 0xFF8F; -+ if (pclk_in == true) -+ val |= 0x0030; -+ cdns_phy_reg_write(mhdp, PHY_PMA_CMN_CTRL1, val); -+ -+ /* for differential clock on the refclk_p and -+ * refclk_m off chip pins: CMN_DIAG_ACYA[8]=1'b1 */ -+ cdns_phy_reg_write(mhdp, CMN_DIAG_ACYA, 0x0100); -+ -+ /* Deassert PHY reset */ -+ cdns_phy_reg_write(mhdp, PHY_ISO_CMN_CTRL, 0x0001); -+ cdns_phy_reg_write(mhdp, PHY_PMA_ISO_CMN_CTRL, 0x0003); -+ -+ /* Power state machine registers */ -+ for (k = 0; k < num_lanes; k++) -+ cdns_phy_reg_write(mhdp, XCVR_PSM_RCTRL | (k << 9), 0xFEFC); -+ -+ /* Assert cmn_macro_pwr_en */ -+ cdns_phy_reg_write(mhdp, PHY_PMA_ISO_CMN_CTRL, 0x0013); -+ -+ /* wait for cmn_macro_pwr_en_ack */ -+ for (i = 0; i < 10; i++) { -+ val = cdns_phy_reg_read(mhdp, PHY_PMA_ISO_CMN_CTRL); -+ if (val & (1 << 5)) -+ break; -+ msleep(20); -+ } -+ if (i == 10) { -+ DRM_ERROR("PMA ouput macro power up failed\n"); -+ return false; -+ } -+ -+ /* wait for cmn_ready */ -+ for (i = 0; i < 10; i++) { -+ val = cdns_phy_reg_read(mhdp, PHY_PMA_CMN_CTRL1); -+ if (val & (1 << 0)) -+ break; -+ msleep(20); -+ } -+ if (i == 10) { -+ DRM_ERROR("PMA output ready failed\n"); -+ return false; -+ } -+ -+ for (k = 0; k < num_lanes; k++) { -+ cdns_phy_reg_write(mhdp, TX_PSC_A0 | (k << 9), 0x6791); -+ cdns_phy_reg_write(mhdp, TX_PSC_A1 | (k << 9), 0x6790); -+ cdns_phy_reg_write(mhdp, TX_PSC_A2 | (k << 9), 0x0090); -+ cdns_phy_reg_write(mhdp, TX_PSC_A3 | (k << 9), 0x0090); -+ -+ val = cdns_phy_reg_read(mhdp, RX_PSC_CAL | (k << 9)); -+ val &= 0xFFBB; -+ cdns_phy_reg_write(mhdp, RX_PSC_CAL | (k << 9), val); -+ -+ val = cdns_phy_reg_read(mhdp, RX_PSC_A0 | (k << 9)); -+ val &= 0xFFBB; -+ cdns_phy_reg_write(mhdp, RX_PSC_A0 | (k << 9), val); -+ } -+ return true; -+} -+ -+static int hdmi_phy_cfg_t28hpc(struct cdns_mhdp_device *mhdp, -+ struct drm_display_mode *mode) -+{ -+ const struct hdmi_ctrl *p_ctrl_table; -+ const struct hdmi_pll_tuning *p_pll_table; -+ const u32 refclk_freq_khz = 27000; -+ const u8 pclk_in = false; -+ u32 pixel_freq = mode->clock; -+ u32 vco_freq, char_freq; -+ u32 div_total, feedback_factor; -+ u32 i, ret; -+ -+ feedback_factor = hdmi_feedback_factor(mhdp); -+ -+ char_freq = pixel_freq * feedback_factor / 1000; -+ -+ DRM_INFO("Pixel clock: %d KHz, character clock: %d, bpc is %0d-bit.\n", -+ pixel_freq, char_freq, mhdp->video_info.color_depth); -+ -+ /* Get right row from the ctrl_table table. -+ * Check if 'pixel_freq_khz' value matches the PIXEL_CLK_FREQ column. -+ * Consider only the rows with FEEDBACK_FACTOR column matching feedback_factor. */ -+ for (i = 0; i < ARRAY_SIZE(imx8mq_ctrl_table); i++) { -+ if (feedback_factor == imx8mq_ctrl_table[i].feedback_factor && -+ pixel_freq == imx8mq_ctrl_table[i].pixel_clk_freq_min) { -+ p_ctrl_table = &imx8mq_ctrl_table[i]; -+ break; -+ } -+ } -+ if (i == ARRAY_SIZE(imx8mq_ctrl_table)) { -+ DRM_WARN("Pixel clk (%d KHz) not supported, color depth (%0d-bit)\n", -+ pixel_freq, mhdp->video_info.color_depth); -+ return 0; -+ } -+ -+ div_total = p_ctrl_table->pll_fb_div_total; -+ vco_freq = refclk_freq_khz * div_total / p_ctrl_table->cmnda_pll0_ip_div; -+ -+ /* Get right row from the imx8mq_pll_table table. -+ * Check if vco_freq_khz and feedback_div_total -+ * column matching with imx8mq_pll_table. */ -+ for (i = 0; i < ARRAY_SIZE(imx8mq_pll_table); i++) { -+ if (vco_freq == imx8mq_pll_table[i].vco_freq_min && -+ div_total == imx8mq_pll_table[i].feedback_div_total) { -+ p_pll_table = &imx8mq_pll_table[i]; -+ break; -+ } -+ } -+ if (i == ARRAY_SIZE(imx8mq_pll_table)) { -+ DRM_WARN("VCO (%d KHz) not supported\n", vco_freq); -+ return 0; -+ } -+ DRM_INFO("VCO frequency is %d KHz\n", vco_freq); -+ -+ ret = hdmi_phy_config(mhdp, p_ctrl_table, p_pll_table, pclk_in); -+ if (ret == false) -+ return 0; -+ -+ return char_freq; -+} -+ -+static int hdmi_phy_cfg_ss28fdsoi(struct cdns_mhdp_device *mhdp, -+ struct drm_display_mode *mode) -+{ -+ const struct hdmi_ctrl *p_ctrl_table; -+ const struct hdmi_pll_tuning *p_pll_table; -+ const u8 pclk_in = true; -+ u32 pixel_freq = mode->clock; -+ u32 vco_freq, char_freq; -+ u32 div_total, feedback_factor; -+ u32 ret, i; -+ -+ feedback_factor = hdmi_feedback_factor(mhdp); -+ -+ char_freq = pixel_freq * feedback_factor / 1000; -+ -+ DRM_INFO("Pixel clock: %d KHz, character clock: %d, bpc is %0d-bit.\n", -+ pixel_freq, char_freq, mhdp->video_info.color_depth); -+ -+ /* Get right row from the ctrl_table table. -+ * Check if 'pixel_freq_khz' value matches the PIXEL_CLK_FREQ column. -+ * Consider only the rows with FEEDBACK_FACTOR column matching feedback_factor. */ -+ for (i = 0; i < ARRAY_SIZE(imx8qm_ctrl_table); i++) { -+ if (feedback_factor == imx8qm_ctrl_table[i].feedback_factor && -+ pixel_freq >= imx8qm_ctrl_table[i].pixel_clk_freq_min && -+ pixel_freq <= imx8qm_ctrl_table[i].pixel_clk_freq_max) { -+ p_ctrl_table = &imx8qm_ctrl_table[i]; -+ break; -+ } -+ } -+ if (i == ARRAY_SIZE(imx8qm_ctrl_table)) { -+ DRM_WARN("Pixel clk (%d KHz) not supported, color depth (%0d-bit)\n", -+ pixel_freq, mhdp->video_info.color_depth); -+ return 0; -+ } -+ -+ div_total = p_ctrl_table->pll_fb_div_total; -+ vco_freq = pixel_freq * div_total / p_ctrl_table->cmnda_pll0_ip_div; -+ -+ /* Get right row from the imx8mq_pll_table table. -+ * Check if vco_freq_khz and feedback_div_total -+ * column matching with imx8mq_pll_table. */ -+ for (i = 0; i < ARRAY_SIZE(imx8qm_pll_table); i++) { -+ if (vco_freq >= imx8qm_pll_table[i].vco_freq_min && -+ vco_freq < imx8qm_pll_table[i].vco_freq_max && -+ div_total == imx8qm_pll_table[i].feedback_div_total) { -+ p_pll_table = &imx8qm_pll_table[i]; -+ break; -+ } -+ } -+ if (i == ARRAY_SIZE(imx8qm_pll_table)) { -+ DRM_WARN("VCO (%d KHz) not supported\n", vco_freq); -+ return 0; -+ } -+ DRM_INFO("VCO frequency is %d KHz\n", vco_freq); -+ -+ ret = hdmi_phy_config(mhdp, p_ctrl_table, p_pll_table, pclk_in); -+ if (ret == false) -+ return 0; -+ -+ return char_freq; -+} -+ -+static int hdmi_phy_power_up(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val, i; -+ -+ /* set Power State to A2 */ -+ cdns_phy_reg_write(mhdp, PHY_HDP_MODE_CTRL, 0x0004); -+ -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_0, 1); -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_1, 1); -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_2, 1); -+ cdns_phy_reg_write(mhdp, TX_DIAG_ACYA_3, 1); -+ -+ /* Wait for Power State A2 Ack */ -+ for (i = 0; i < 10; i++) { -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_MODE_CTRL); -+ if (val & (1 << 6)) -+ break; -+ msleep(20); -+ } -+ if (i == 10) { -+ dev_err(mhdp->dev, "Wait A2 Ack failed\n"); -+ return -1; -+ } -+ -+ /* Configure PHY in A0 mode (PHY must be in the A0 power -+ * state in order to transmit data) -+ */ -+ //cdns_phy_reg_write(mhdp, PHY_HDP_MODE_CTRL, 0x0101); //imx8mq -+ cdns_phy_reg_write(mhdp, PHY_HDP_MODE_CTRL, 0x0001); -+ -+ /* Wait for Power State A0 Ack */ -+ for (i = 0; i < 10; i++) { -+ val = cdns_phy_reg_read(mhdp, PHY_HDP_MODE_CTRL); -+ if (val & (1 << 4)) -+ break; -+ msleep(20); -+ } -+ if (i == 10) { -+ dev_err(mhdp->dev, "Wait A0 Ack failed\n"); -+ return -1; -+ } -+ return 0; -+} -+ -+int cdns_hdmi_phy_set_imx8mq(struct imx_mhdp_device *hdp) -+{ -+ struct cdns_mhdp_device *mhdp = &hdp->mhdp; -+ struct drm_display_mode *mode = &mhdp->mode; -+ int ret; -+ -+ /* Check HDMI FW alive before HDMI PHY init */ -+ ret = cdns_mhdp_check_alive(mhdp); -+ if (ret == false) { -+ DRM_ERROR("NO HDMI FW running\n"); -+ return -ENXIO; -+ } -+ -+ /* Configure PHY */ -+ mhdp->hdmi.char_rate = hdmi_phy_cfg_t28hpc(mhdp, mode); -+ if (mhdp->hdmi.char_rate == 0) { -+ DRM_ERROR("failed to set phy pclock\n"); -+ return -EINVAL; -+ } -+ -+ ret = hdmi_phy_power_up(mhdp); -+ if (ret < 0) -+ return ret; -+ -+ hdmi_phy_set_vswing(mhdp); -+ -+ return true; -+} -+ -+int cdns_hdmi_phy_set_imx8qm(struct imx_mhdp_device *hdp) -+{ -+ struct cdns_mhdp_device *mhdp = &hdp->mhdp; -+ struct drm_display_mode *mode = &mhdp->mode; -+ int ret; -+ -+ /* Check HDMI FW alive before HDMI PHY init */ -+ ret = cdns_mhdp_check_alive(mhdp); -+ if (ret == false) { -+ DRM_ERROR("NO HDMI FW running\n"); -+ return -ENXIO; -+ } -+ -+ /* Configure PHY */ -+ mhdp->hdmi.char_rate = hdmi_phy_cfg_ss28fdsoi(mhdp, mode); -+ if (mhdp->hdmi.char_rate == 0) { -+ DRM_ERROR("failed to set phy pclock\n"); -+ return -EINVAL; -+ } -+ -+ ret = hdmi_phy_power_up(mhdp); -+ if (ret < 0) -+ return ret; -+ -+ hdmi_phy_set_vswing(mhdp); -+ -+ return true; -+} -+ ---- /dev/null -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imx8mq.c -@@ -0,0 +1,163 @@ -+/* -+ * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include "cdn-mhdp-phy.h" -+#include "imx-drm.h" -+ -+struct imx_hdmi { -+ struct device *dev; -+ struct drm_encoder encoder; -+}; -+ -+static void cdns_hdmi_imx_encoder_disable(struct drm_encoder *encoder) -+{ -+} -+ -+static void cdns_hdmi_imx_encoder_enable(struct drm_encoder *encoder) -+{ -+} -+ -+static int cdns_hdmi_imx_atomic_check(struct drm_encoder *encoder, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state) -+{ -+ return 0; -+} -+ -+static const struct drm_encoder_helper_funcs cdns_hdmi_imx_encoder_helper_funcs = { -+ .enable = cdns_hdmi_imx_encoder_enable, -+ .disable = cdns_hdmi_imx_encoder_disable, -+ .atomic_check = cdns_hdmi_imx_atomic_check, -+}; -+ -+static const struct drm_encoder_funcs cdns_hdmi_imx_encoder_funcs = { -+ .destroy = drm_encoder_cleanup, -+}; -+ -+static struct cdn_plat_data imx8mq_hdmi_drv_data = { -+ .bind = cdns_hdmi_bind, -+ .unbind = cdns_hdmi_unbind, -+ .phy_init = cdns_hdmi_phy_set_imx8mq, -+}; -+ -+static struct cdn_plat_data imx8mq_dp_drv_data = { -+ .bind = cdns_dp_bind, -+ .unbind = cdns_dp_unbind, -+ .phy_init = cdns_dp_phy_init_imx8mq, -+}; -+ -+static const struct of_device_id cdns_hdmi_imx_dt_ids[] = { -+ { .compatible = "cdn,imx8mq-hdmi", -+ .data = &imx8mq_hdmi_drv_data -+ }, -+ { .compatible = "cdn,imx8mq-dp", -+ .data = &imx8mq_dp_drv_data -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, cdns_hdmi_imx_dt_ids); -+ -+static int cdns_hdmi_imx_bind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ const struct cdn_plat_data *plat_data; -+ const struct of_device_id *match; -+ struct drm_device *drm = data; -+ struct drm_encoder *encoder; -+ struct imx_hdmi *hdmi; -+ int ret; -+ -+ if (!pdev->dev.of_node) -+ return -ENODEV; -+ -+ hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); -+ if (!hdmi) -+ return -ENOMEM; -+ -+ match = of_match_node(cdns_hdmi_imx_dt_ids, pdev->dev.of_node); -+ plat_data = match->data; -+ hdmi->dev = &pdev->dev; -+ encoder = &hdmi->encoder; -+ -+ encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); -+ /* -+ * If we failed to find the CRTC(s) which this encoder is -+ * supposed to be connected to, it's because the CRTC has -+ * not been registered yet. Defer probing, and hope that -+ * the required CRTC is added later. -+ */ -+ if (encoder->possible_crtcs == 0) -+ return -EPROBE_DEFER; -+ -+ drm_encoder_helper_add(encoder, &cdns_hdmi_imx_encoder_helper_funcs); -+ drm_encoder_init(drm, encoder, &cdns_hdmi_imx_encoder_funcs, -+ DRM_MODE_ENCODER_TMDS, NULL); -+ -+ ret = plat_data->bind(pdev, encoder, plat_data); -+ -+ /* -+ * If cdns_hdmi_bind() fails we'll never call cdns_hdmi_unbind(), -+ * which would have called the encoder cleanup. Do it manually. -+ */ -+ if (ret) -+ drm_encoder_cleanup(encoder); -+ -+ return ret; -+} -+ -+static void cdns_hdmi_imx_unbind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct imx_mhdp_device *hdp = dev_get_drvdata(dev); -+ -+ hdp->plat_data->unbind(dev); -+} -+ -+static const struct component_ops cdns_hdmi_imx_ops = { -+ .bind = cdns_hdmi_imx_bind, -+ .unbind = cdns_hdmi_imx_unbind, -+}; -+ -+static int cdns_hdmi_imx_probe(struct platform_device *pdev) -+{ -+ return component_add(&pdev->dev, &cdns_hdmi_imx_ops); -+} -+ -+static int cdns_hdmi_imx_remove(struct platform_device *pdev) -+{ -+ component_del(&pdev->dev, &cdns_hdmi_imx_ops); -+ -+ return 0; -+} -+ -+static struct platform_driver cdns_hdmi_imx_platform_driver = { -+ .probe = cdns_hdmi_imx_probe, -+ .remove = cdns_hdmi_imx_remove, -+ .driver = { -+ .name = "cdn-hdp-imx8mq", -+ .of_match_table = cdns_hdmi_imx_dt_ids, -+ }, -+}; -+ -+module_platform_driver(cdns_hdmi_imx_platform_driver); -+ -+MODULE_AUTHOR("Sandor YU "); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:cdnhdmi-imx"); ---- /dev/null -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c -@@ -0,0 +1,714 @@ -+/* -+ * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include "cdn-mhdp-phy.h" -+#include "imx-drm.h" -+ -+#define CSR_PIXEL_LINK_MUX_CTL 0x00 -+#define PL_MUX_CTL_VCP_OFFSET 5 -+#define PL_MUX_CTL_HCP_OFFSET 4 -+ -+#define PLL_800MHZ (800000000) -+ -+struct imx_hdmi { -+ struct device *dev; -+ struct drm_encoder encoder; -+}; -+ -+static void imx8qm_pixel_link_mux(struct imx_mhdp_device *hdp) -+{ -+ struct drm_display_mode *mode = &hdp->mhdp.mode; -+ u32 val; -+ -+ val = 0x4; /* RGB */ -+ if (hdp->dual_mode) -+ val |= 0x2; /* pixel link 0 and 1 are active */ -+ if (mode->flags & DRM_MODE_FLAG_PVSYNC) -+ val |= 1 << PL_MUX_CTL_VCP_OFFSET; -+ if (mode->flags & DRM_MODE_FLAG_PHSYNC) -+ val |= 1 << PL_MUX_CTL_HCP_OFFSET; -+ if (mode->flags & DRM_MODE_FLAG_INTERLACE) -+ val |= 0x2; -+ -+ regmap_write(hdp->regmap_csr, hdp->csr_pxl_mux_reg, val); -+} -+ -+static void imx8qm_pixel_link_valid(u32 dual_mode) -+{ -+ struct imx_sc_ipc *handle; -+ -+ imx_scu_get_handle(&handle); -+ -+ imx_sc_misc_set_control(handle, IMX_SC_R_DC_0, IMX_SC_C_PXL_LINK_MST1_VLD, 1); -+ if (dual_mode) -+ imx_sc_misc_set_control(handle, IMX_SC_R_DC_0, IMX_SC_C_PXL_LINK_MST2_VLD, 1); -+} -+ -+static void imx8qm_pixel_link_invalid(u32 dual_mode) -+{ -+ struct imx_sc_ipc *handle; -+ -+ imx_scu_get_handle(&handle); -+ -+ imx_sc_misc_set_control(handle, IMX_SC_R_DC_0, IMX_SC_C_PXL_LINK_MST1_VLD, 0); -+ if (dual_mode) -+ imx_sc_misc_set_control(handle, IMX_SC_R_DC_0, IMX_SC_C_PXL_LINK_MST2_VLD, 0); -+} -+ -+static void imx8qm_pixel_link_sync_enable(u32 dual_mode) -+{ -+ struct imx_sc_ipc *handle; -+ -+ imx_scu_get_handle(&handle); -+ -+ if (dual_mode) -+ imx_sc_misc_set_control(handle, IMX_SC_R_DC_0, IMX_SC_C_SYNC_CTRL, 3); -+ else -+ imx_sc_misc_set_control(handle, IMX_SC_R_DC_0, IMX_SC_C_SYNC_CTRL0, 1); -+} -+ -+static void imx8qm_pixel_link_sync_disable(u32 dual_mode) -+{ -+ struct imx_sc_ipc *handle; -+ -+ imx_scu_get_handle(&handle); -+ -+ if (dual_mode) -+ imx_sc_misc_set_control(handle, IMX_SC_R_DC_0, IMX_SC_C_SYNC_CTRL, 0); -+ else -+ imx_sc_misc_set_control(handle, IMX_SC_R_DC_0, IMX_SC_C_SYNC_CTRL0, 0); -+} -+ -+static void imx8qm_phy_reset(u8 reset) -+{ -+ struct imx_sc_ipc *handle; -+ -+ imx_scu_get_handle(&handle); -+ -+ /* set the pixel link mode and pixel type */ -+ imx_sc_misc_set_control(handle, IMX_SC_R_HDMI, IMX_SC_C_PHY_RESET, reset); -+} -+ -+static void imx8qm_clk_mux(u8 is_dp) -+{ -+ struct imx_sc_ipc *handle; -+ -+ imx_scu_get_handle(&handle); -+ -+ if (is_dp) -+ /* Enable the 24MHz for HDP PHY */ -+ imx_sc_misc_set_control(handle, IMX_SC_R_HDMI, IMX_SC_C_MODE, 1); -+ else -+ imx_sc_misc_set_control(handle, IMX_SC_R_HDMI, IMX_SC_C_MODE, 0); -+} -+ -+int imx8qm_clocks_init(struct imx_mhdp_device *hdp) -+{ -+ struct device *dev = hdp->mhdp.dev; -+ struct imx_hdp_clks *clks = &hdp->clks; -+ -+ clks->dig_pll = devm_clk_get(dev, "dig_pll"); -+ if (IS_ERR(clks->dig_pll)) { -+ dev_warn(dev, "failed to get dig pll clk\n"); -+ return PTR_ERR(clks->dig_pll); -+ } -+ -+ clks->av_pll = devm_clk_get(dev, "av_pll"); -+ if (IS_ERR(clks->av_pll)) { -+ dev_warn(dev, "failed to get av pll clk\n"); -+ return PTR_ERR(clks->av_pll); -+ } -+ -+ clks->clk_ipg = devm_clk_get(dev, "clk_ipg"); -+ if (IS_ERR(clks->clk_ipg)) { -+ dev_warn(dev, "failed to get dp ipg clk\n"); -+ return PTR_ERR(clks->clk_ipg); -+ } -+ -+ clks->clk_core = devm_clk_get(dev, "clk_core"); -+ if (IS_ERR(clks->clk_core)) { -+ dev_warn(dev, "failed to get hdp core clk\n"); -+ return PTR_ERR(clks->clk_core); -+ } -+ -+ clks->clk_pxl = devm_clk_get(dev, "clk_pxl"); -+ if (IS_ERR(clks->clk_pxl)) { -+ dev_warn(dev, "failed to get pxl clk\n"); -+ return PTR_ERR(clks->clk_pxl); -+ } -+ -+ clks->clk_pxl_mux = devm_clk_get(dev, "clk_pxl_mux"); -+ if (IS_ERR(clks->clk_pxl_mux)) { -+ dev_warn(dev, "failed to get pxl mux clk\n"); -+ return PTR_ERR(clks->clk_pxl_mux); -+ } -+ -+ clks->clk_pxl_link = devm_clk_get(dev, "clk_pxl_link"); -+ if (IS_ERR(clks->clk_pxl_mux)) { -+ dev_warn(dev, "failed to get pxl link clk\n"); -+ return PTR_ERR(clks->clk_pxl_link); -+ } -+ -+ clks->lpcg_hdp = devm_clk_get(dev, "lpcg_hdp"); -+ if (IS_ERR(clks->lpcg_hdp)) { -+ dev_warn(dev, "failed to get lpcg hdp clk\n"); -+ return PTR_ERR(clks->lpcg_hdp); -+ } -+ -+ clks->lpcg_msi = devm_clk_get(dev, "lpcg_msi"); -+ if (IS_ERR(clks->lpcg_msi)) { -+ dev_warn(dev, "failed to get lpcg msi clk\n"); -+ return PTR_ERR(clks->lpcg_msi); -+ } -+ -+ clks->lpcg_pxl = devm_clk_get(dev, "lpcg_pxl"); -+ if (IS_ERR(clks->lpcg_pxl)) { -+ dev_warn(dev, "failed to get lpcg pxl clk\n"); -+ return PTR_ERR(clks->lpcg_pxl); -+ } -+ -+ clks->lpcg_vif = devm_clk_get(dev, "lpcg_vif"); -+ if (IS_ERR(clks->lpcg_vif)) { -+ dev_warn(dev, "failed to get lpcg vif clk\n"); -+ return PTR_ERR(clks->lpcg_vif); -+ } -+ -+ clks->lpcg_lis = devm_clk_get(dev, "lpcg_lis"); -+ if (IS_ERR(clks->lpcg_lis)) { -+ dev_warn(dev, "failed to get lpcg lis clk\n"); -+ return PTR_ERR(clks->lpcg_lis); -+ } -+ -+ clks->lpcg_apb = devm_clk_get(dev, "lpcg_apb"); -+ if (IS_ERR(clks->lpcg_apb)) { -+ dev_warn(dev, "failed to get lpcg apb clk\n"); -+ return PTR_ERR(clks->lpcg_apb); -+ } -+ -+ clks->lpcg_apb_csr = devm_clk_get(dev, "lpcg_apb_csr"); -+ if (IS_ERR(clks->lpcg_apb_csr)) { -+ dev_warn(dev, "failed to get apb csr clk\n"); -+ return PTR_ERR(clks->lpcg_apb_csr); -+ } -+ -+ clks->lpcg_apb_ctrl = devm_clk_get(dev, "lpcg_apb_ctrl"); -+ if (IS_ERR(clks->lpcg_apb_ctrl)) { -+ dev_warn(dev, "failed to get lpcg apb ctrl clk\n"); -+ return PTR_ERR(clks->lpcg_apb_ctrl); -+ } -+ -+ clks->clk_i2s_bypass = devm_clk_get(dev, "clk_i2s_bypass"); -+ if (IS_ERR(clks->clk_i2s_bypass)) { -+ dev_err(dev, "failed to get i2s bypass clk\n"); -+ return PTR_ERR(clks->clk_i2s_bypass); -+ } -+ -+ clks->lpcg_i2s = devm_clk_get(dev, "lpcg_i2s"); -+ if (IS_ERR(clks->lpcg_i2s)) { -+ dev_err(dev, "failed to get lpcg i2s clk\n"); -+ return PTR_ERR(clks->lpcg_i2s); -+ } -+ return true; -+} -+ -+static int imx8qm_pixel_clk_enable(struct imx_mhdp_device *hdp) -+{ -+ struct imx_hdp_clks *clks = &hdp->clks; -+ struct device *dev = hdp->mhdp.dev; -+ int ret; -+ -+ ret = clk_prepare_enable(clks->av_pll); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre av pll error\n", __func__); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(clks->clk_pxl); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk pxl error\n", __func__); -+ return ret; -+ } -+ ret = clk_prepare_enable(clks->clk_pxl_mux); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk pxl mux error\n", __func__); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(clks->clk_pxl_link); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk pxl link error\n", __func__); -+ return ret; -+ } -+ ret = clk_prepare_enable(clks->lpcg_vif); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk vif error\n", __func__); -+ return ret; -+ } -+ ret = clk_prepare_enable(clks->lpcg_pxl); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre lpcg pxl error\n", __func__); -+ return ret; -+ } -+ ret = clk_prepare_enable(clks->lpcg_hdp); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre lpcg hdp error\n", __func__); -+ return ret; -+ } -+ return ret; -+ -+} -+ -+static void imx8qm_pixel_clk_disable(struct imx_mhdp_device *hdp) -+{ -+ struct imx_hdp_clks *clks = &hdp->clks; -+ -+ clk_disable_unprepare(clks->lpcg_pxl); -+ clk_disable_unprepare(clks->lpcg_hdp); -+ clk_disable_unprepare(clks->lpcg_vif); -+ clk_disable_unprepare(clks->clk_pxl); -+ clk_disable_unprepare(clks->clk_pxl_link); -+ clk_disable_unprepare(clks->clk_pxl_mux); -+ clk_disable_unprepare(clks->av_pll); -+} -+ -+static void imx8qm_pixel_clk_set_rate(struct imx_mhdp_device *hdp, u32 pclock) -+{ -+ struct imx_hdp_clks *clks = &hdp->clks; -+ -+ /* pixel clock for HDMI */ -+ clk_set_rate(clks->av_pll, pclock); -+ -+ if (hdp->dual_mode == true) { -+ clk_set_rate(clks->clk_pxl, pclock/2); -+ clk_set_rate(clks->clk_pxl_link, pclock/2); -+ } else { -+ clk_set_rate(clks->clk_pxl_link, pclock); -+ clk_set_rate(clks->clk_pxl, pclock); -+ } -+ clk_set_rate(clks->clk_pxl_mux, pclock); -+} -+ -+static void imx8qm_pixel_clk_rate_change(struct imx_mhdp_device *hdp) -+{ -+ /* set pixel clock before video mode setup */ -+ imx8qm_pixel_clk_disable(hdp); -+ -+ imx8qm_pixel_clk_set_rate(hdp, hdp->mhdp.mode.clock * 1000); -+ -+ imx8qm_pixel_clk_enable(hdp); -+ -+ /* Config pixel link mux */ -+ imx8qm_pixel_link_mux(hdp); -+} -+ -+static int imx8qm_ipg_clk_enable(struct imx_mhdp_device *hdp) -+{ -+ int ret; -+ struct imx_hdp_clks *clks = &hdp->clks; -+ struct device *dev = hdp->mhdp.dev; -+ -+ ret = clk_prepare_enable(clks->dig_pll); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre dig pll error\n", __func__); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(clks->clk_ipg); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk_ipg error\n", __func__); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(clks->clk_core); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk core error\n", __func__); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(clks->lpcg_apb); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk apb error\n", __func__); -+ return ret; -+ } -+ ret = clk_prepare_enable(clks->lpcg_lis); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk lis error\n", __func__); -+ return ret; -+ } -+ ret = clk_prepare_enable(clks->lpcg_msi); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk msierror\n", __func__); -+ return ret; -+ } -+ ret = clk_prepare_enable(clks->lpcg_apb_csr); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk apb csr error\n", __func__); -+ return ret; -+ } -+ ret = clk_prepare_enable(clks->lpcg_apb_ctrl); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk apb ctrl error\n", __func__); -+ return ret; -+ } -+ ret = clk_prepare_enable(clks->lpcg_i2s); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk i2s error\n", __func__); -+ return ret; -+ } -+ ret = clk_prepare_enable(clks->clk_i2s_bypass); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk i2s bypass error\n", __func__); -+ return ret; -+ } -+ return ret; -+} -+ -+static void imx8qm_ipg_clk_disable(struct imx_mhdp_device *hdp) -+{ -+ struct imx_hdp_clks *clks = &hdp->clks; -+ -+ clk_disable_unprepare(clks->clk_i2s_bypass); -+ clk_disable_unprepare(clks->lpcg_i2s); -+ clk_disable_unprepare(clks->lpcg_apb_ctrl); -+ clk_disable_unprepare(clks->lpcg_apb_csr); -+ clk_disable_unprepare(clks->lpcg_msi); -+ clk_disable_unprepare(clks->lpcg_lis); -+ clk_disable_unprepare(clks->lpcg_apb); -+ clk_disable_unprepare(clks->clk_core); -+ clk_disable_unprepare(clks->clk_ipg); -+ clk_disable_unprepare(clks->dig_pll); -+} -+ -+static void imx8qm_ipg_clk_set_rate(struct imx_mhdp_device *hdp) -+{ -+ struct imx_hdp_clks *clks = &hdp->clks; -+ -+ /* ipg/core clock */ -+ clk_set_rate(clks->dig_pll, PLL_800MHZ); -+ clk_set_rate(clks->clk_core, PLL_800MHZ/4); -+ clk_set_rate(clks->clk_ipg, PLL_800MHZ/8); -+} -+ -+static void imx8qm_detach_pm_domains(struct imx_mhdp_device *hdp) -+{ -+ if (hdp->pd_pll1_link && !IS_ERR(hdp->pd_pll1_link)) -+ device_link_del(hdp->pd_pll1_link); -+ if (hdp->pd_pll1_dev && !IS_ERR(hdp->pd_pll1_dev)) -+ dev_pm_domain_detach(hdp->pd_pll1_dev, true); -+ -+ if (hdp->pd_pll0_link && !IS_ERR(hdp->pd_pll0_link)) -+ device_link_del(hdp->pd_pll0_link); -+ if (hdp->pd_pll0_dev && !IS_ERR(hdp->pd_pll0_dev)) -+ dev_pm_domain_detach(hdp->pd_pll0_dev, true); -+ -+ if (hdp->pd_mhdp_link && !IS_ERR(hdp->pd_mhdp_link)) -+ device_link_del(hdp->pd_mhdp_link); -+ if (hdp->pd_mhdp_dev && !IS_ERR(hdp->pd_mhdp_dev)) -+ dev_pm_domain_detach(hdp->pd_mhdp_dev, true); -+ -+ hdp->pd_mhdp_dev = NULL; -+ hdp->pd_mhdp_link = NULL; -+ hdp->pd_pll0_dev = NULL; -+ hdp->pd_pll0_link = NULL; -+ hdp->pd_pll1_dev = NULL; -+ hdp->pd_pll1_link = NULL; -+} -+ -+static int imx8qm_attach_pm_domains(struct imx_mhdp_device *hdp) -+{ -+ struct device *dev = hdp->mhdp.dev; -+ u32 flags = DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE; -+ int ret = 0; -+ -+ hdp->pd_mhdp_dev = dev_pm_domain_attach_by_name(dev, "hdmi"); -+ if (IS_ERR(hdp->pd_mhdp_dev)) { -+ ret = PTR_ERR(hdp->pd_mhdp_dev); -+ dev_err(dev, "Failed to attach dc pd dev: %d\n", ret); -+ goto fail; -+ } -+ hdp->pd_mhdp_link = device_link_add(dev, hdp->pd_mhdp_dev, flags); -+ if (IS_ERR(hdp->pd_mhdp_link)) { -+ ret = PTR_ERR(hdp->pd_mhdp_link); -+ dev_err(dev, "Failed to add device link to dc pd dev: %d\n", -+ ret); -+ goto fail; -+ } -+ -+ hdp->pd_pll0_dev = dev_pm_domain_attach_by_name(dev, "pll0"); -+ if (IS_ERR(hdp->pd_pll0_dev)) { -+ ret = PTR_ERR(hdp->pd_pll0_dev); -+ dev_err(dev, "Failed to attach pll0 pd dev: %d\n", ret); -+ goto fail; -+ } -+ hdp->pd_pll0_link = device_link_add(dev, hdp->pd_pll0_dev, flags); -+ if (IS_ERR(hdp->pd_pll0_link)) { -+ ret = PTR_ERR(hdp->pd_pll0_link); -+ dev_err(dev, "Failed to add device link to pll0 pd dev: %d\n", -+ ret); -+ goto fail; -+ } -+ -+ hdp->pd_pll1_dev = dev_pm_domain_attach_by_name(dev, "pll1"); -+ if (IS_ERR(hdp->pd_pll1_dev)) { -+ ret = PTR_ERR(hdp->pd_pll1_dev); -+ dev_err(dev, "Failed to attach pll0 pd dev: %d\n", ret); -+ goto fail; -+ } -+ hdp->pd_pll1_link = device_link_add(dev, hdp->pd_pll1_dev, flags); -+ if (IS_ERR(hdp->pd_pll1_link)) { -+ ret = PTR_ERR(hdp->pd_pll1_link); -+ dev_err(dev, "Failed to add device link to pll1 pd dev: %d\n", -+ ret); -+ goto fail; -+ } -+fail: -+ imx8qm_detach_pm_domains(hdp); -+ return ret; -+} -+ -+static int imx8qm_firmware_init(struct imx_mhdp_device *hdp) -+{ -+ u32 rate; -+ int ret; -+ -+ /* Power on PM Domains */ -+ imx8qm_attach_pm_domains(hdp); -+ -+ /* clock init and rate set */ -+ imx8qm_clocks_init(hdp); -+ -+ imx8qm_ipg_clk_set_rate(hdp); -+ -+ /* Init pixel clock with 148.5MHz before FW init */ -+ imx8qm_pixel_clk_set_rate(hdp, 148500000); -+ -+ imx8qm_ipg_clk_enable(hdp); -+ -+ imx8qm_clk_mux(hdp->plat_data->is_dp); -+ -+ imx8qm_pixel_clk_enable(hdp); -+ -+ imx8qm_phy_reset(1); -+ -+ hdp->csr_pxl_mux_reg = 0; -+ hdp->csr_ctrl0_reg = 0x8; -+ hdp->csr_ctrl0_sec = 0xc; -+ /* iMX8QM HDP register, Remap HPD memory address to low 4K */ -+ regmap_write(hdp->regmap_csr, hdp->csr_ctrl0_reg, 0); -+ -+ /* configure HDMI/DP core clock */ -+ rate = clk_get_rate(hdp->clks.clk_core); -+ cdns_mhdp_set_fw_clk(&hdp->mhdp, rate); -+ -+ /* un-reset ucpu */ -+ writel(0, (APB_CTRL << 2) + hdp->mhdp.regs); -+ DRM_INFO("Started firmware!\n"); -+ -+ ret = cdns_mhdp_check_alive(&hdp->mhdp); -+ if (ret == false) { -+ DRM_ERROR("NO HDMI FW running\n"); -+ return -ENXIO; -+ } -+ -+ /* turn on IP activity */ -+ cdns_mhdp_set_firmware_active(&hdp->mhdp, 1); -+ -+ DRM_INFO("HDP FW Version - ver %d verlib %d\n", -+ __raw_readb(VER_L + hdp->mhdp.regs) + (__raw_readb(VER_H + hdp->mhdp.regs) << 8), -+ __raw_readb(VER_LIB_L_ADDR + hdp->mhdp.regs) + (__raw_readb(VER_LIB_H_ADDR + hdp->mhdp.regs) << 8)); -+ -+ return 0; -+} -+ -+static void cdns_hdmi_imx_encoder_disable(struct drm_encoder *encoder) -+{ -+ struct imx_mhdp_device *hdp = encoder->bridge->driver_private; -+ -+ imx8qm_pixel_link_sync_disable(hdp->dual_mode); -+ imx8qm_pixel_link_invalid(hdp->dual_mode); -+} -+ -+static void cdns_hdmi_imx_encoder_enable(struct drm_encoder *encoder) -+{ -+ struct imx_mhdp_device *hdp = encoder->bridge->driver_private; -+ -+ imx8qm_pixel_link_valid(hdp->dual_mode); -+ imx8qm_pixel_link_sync_enable(hdp->dual_mode); -+} -+ -+static int cdns_hdmi_imx_encoder_atomic_check(struct drm_encoder *encoder, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state) -+{ -+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); -+ -+ imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB101010_1X30; -+ return 0; -+} -+ -+static const struct drm_encoder_helper_funcs cdns_hdmi_imx_encoder_helper_funcs = { -+ .enable = cdns_hdmi_imx_encoder_enable, -+ .disable = cdns_hdmi_imx_encoder_disable, -+ .atomic_check = cdns_hdmi_imx_encoder_atomic_check, -+}; -+ -+static const struct drm_encoder_funcs cdns_hdmi_imx_encoder_funcs = { -+ .destroy = drm_encoder_cleanup, -+}; -+ -+#if 0 -+static struct cdn_plat_data imx8mq_hdmi_drv_data = { -+ .bind = cdns_hdmi_bind, -+ .unbind = cdns_hdmi_unbind, -+ .phy_init = cdns_hdmi_phy_set_imx8mq, -+}; -+ -+static struct cdn_plat_data imx8mq_dp_drv_data = { -+ .bind = cdns_dp_bind, -+ .unbind = cdns_dp_unbind, -+ .phy_init = cdns_dp_phy_init_imx8mq, -+}; -+#endif -+ -+static struct cdn_plat_data imx8qm_hdmi_drv_data = { -+ .bind = cdns_hdmi_bind, -+ .unbind = cdns_hdmi_unbind, -+ .phy_init = cdns_hdmi_phy_set_imx8qm, -+ .fw_init = imx8qm_firmware_init, -+ .pclock_change = imx8qm_pixel_clk_rate_change, -+}; -+ -+static struct cdn_plat_data imx8qm_dp_drv_data = { -+ .bind = cdns_dp_bind, -+ .unbind = cdns_dp_unbind, -+ .phy_init = cdns_dp_phy_init_imx8qm, -+ .fw_init = imx8qm_firmware_init, -+ .pclock_change = imx8qm_pixel_clk_rate_change, -+ .is_dp = true, -+}; -+ -+static const struct of_device_id cdns_hdmi_imx_dt_ids[] = { -+#if 0 -+ { .compatible = "cdn,imx8mq-hdmi", -+ .data = &imx8mq_hdmi_drv_data -+ }, -+ { .compatible = "cdn,imx8mq-dp", -+ .data = &imx8mq_dp_drv_data -+ }, -+#endif -+ { .compatible = "cdn,imx8qm-hdmi", -+ .data = &imx8qm_hdmi_drv_data -+ }, -+ { .compatible = "cdn,imx8qm-dp", -+ .data = &imx8qm_dp_drv_data -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, cdns_hdmi_imx_dt_ids); -+ -+static int cdns_hdmi_imx_bind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ const struct cdn_plat_data *plat_data; -+ const struct of_device_id *match; -+ struct drm_device *drm = data; -+ struct drm_encoder *encoder; -+ struct imx_hdmi *hdmi; -+ int ret; -+ -+ if (!pdev->dev.of_node) -+ return -ENODEV; -+ -+ hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); -+ if (!hdmi) -+ return -ENOMEM; -+ -+ match = of_match_node(cdns_hdmi_imx_dt_ids, pdev->dev.of_node); -+ plat_data = match->data; -+ hdmi->dev = &pdev->dev; -+ encoder = &hdmi->encoder; -+ -+ encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); -+ /* -+ * If we failed to find the CRTC(s) which this encoder is -+ * supposed to be connected to, it's because the CRTC has -+ * not been registered yet. Defer probing, and hope that -+ * the required CRTC is added later. -+ */ -+ if (encoder->possible_crtcs == 0) -+ return -EPROBE_DEFER; -+ -+ drm_encoder_helper_add(encoder, &cdns_hdmi_imx_encoder_helper_funcs); -+ drm_encoder_init(drm, encoder, &cdns_hdmi_imx_encoder_funcs, -+ DRM_MODE_ENCODER_TMDS, NULL); -+ -+ ret = plat_data->bind(pdev, encoder, plat_data); -+ -+ /* -+ * If cdns_hdmi_bind() fails we'll never call cdns_hdmi_unbind(), -+ * which would have called the encoder cleanup. Do it manually. -+ */ -+ if (ret) -+ drm_encoder_cleanup(encoder); -+ -+ return ret; -+} -+ -+static void cdns_hdmi_imx_unbind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct imx_mhdp_device *hdp = dev_get_drvdata(dev); -+ -+ hdp->plat_data->unbind(dev); -+} -+ -+static const struct component_ops cdns_hdmi_imx8qm_ops = { -+ .bind = cdns_hdmi_imx_bind, -+ .unbind = cdns_hdmi_imx_unbind, -+}; -+ -+static int cdns_hdmi_imx_probe(struct platform_device *pdev) -+{ -+ return component_add(&pdev->dev, &cdns_hdmi_imx8qm_ops); -+} -+ -+static int cdns_hdmi_imx_remove(struct platform_device *pdev) -+{ -+ component_del(&pdev->dev, &cdns_hdmi_imx8qm_ops); -+ -+ return 0; -+} -+ -+static struct platform_driver cdns_hdmi_imx_platform_driver = { -+ .probe = cdns_hdmi_imx_probe, -+ .remove = cdns_hdmi_imx_remove, -+ .driver = { -+ .name = "cdn-hdp-imx8qm", -+ .of_match_table = cdns_hdmi_imx_dt_ids, -+ }, -+}; -+ -+module_platform_driver(cdns_hdmi_imx_platform_driver); -+ -+MODULE_AUTHOR("Sandor YU "); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:cdnhdmi-imx"); ---- /dev/null -+++ b/drivers/gpu/drm/imx/cdn-mhdp-phy.h -@@ -0,0 +1,153 @@ -+/* -+ * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ */ -+ -+#ifndef _CDN_DP_PHY_H -+#define _CDN_DP_PHY_H -+ -+#include -+ -+#define CMN_SSM_BIAS_TMR 0x0022 -+#define CMN_PLLSM0_PLLEN_TMR 0x0029 -+#define CMN_PLLSM0_PLLPRE_TMR 0x002A -+#define CMN_PLLSM0_PLLVREF_TMR 0x002B -+#define CMN_PLLSM0_PLLLOCK_TMR 0x002C -+#define CMN_PLLSM0_USER_DEF_CTRL 0x002F -+#define CMN_PSM_CLK_CTRL 0x0061 -+#define CMN_CDIAG_REFCLK_CTRL 0x0062 -+#define CMN_PLL0_VCOCAL_START 0x0081 -+#define CMN_PLL0_VCOCAL_INIT_TMR 0x0084 -+#define CMN_PLL0_VCOCAL_ITER_TMR 0x0085 -+#define CMN_PLL0_INTDIV 0x0094 -+#define CMN_PLL0_FRACDIV 0x0095 -+#define CMN_PLL0_HIGH_THR 0x0096 -+#define CMN_PLL0_DSM_DIAG 0x0097 -+#define CMN_PLL0_SS_CTRL1 0x0098 -+#define CMN_PLL0_SS_CTRL2 0x0099 -+#define CMN_ICAL_INIT_TMR 0x00C4 -+#define CMN_ICAL_ITER_TMR 0x00C5 -+#define CMN_RXCAL_INIT_TMR 0x00D4 -+#define CMN_RXCAL_ITER_TMR 0x00D5 -+#define CMN_TXPUCAL_CTRL 0x00E0 -+#define CMN_TXPUCAL_INIT_TMR 0x00E4 -+#define CMN_TXPUCAL_ITER_TMR 0x00E5 -+#define CMN_TXPDCAL_CTRL 0x00F0 -+#define CMN_TXPDCAL_INIT_TMR 0x00F4 -+#define CMN_TXPDCAL_ITER_TMR 0x00F5 -+#define CMN_ICAL_ADJ_INIT_TMR 0x0102 -+#define CMN_ICAL_ADJ_ITER_TMR 0x0103 -+#define CMN_RX_ADJ_INIT_TMR 0x0106 -+#define CMN_RX_ADJ_ITER_TMR 0x0107 -+#define CMN_TXPU_ADJ_CTRL 0x0108 -+#define CMN_TXPU_ADJ_INIT_TMR 0x010A -+#define CMN_TXPU_ADJ_ITER_TMR 0x010B -+#define CMN_TXPD_ADJ_CTRL 0x010c -+#define CMN_TXPD_ADJ_INIT_TMR 0x010E -+#define CMN_TXPD_ADJ_ITER_TMR 0x010F -+#define CMN_DIAG_PLL0_FBH_OVRD 0x01C0 -+#define CMN_DIAG_PLL0_FBL_OVRD 0x01C1 -+#define CMN_DIAG_PLL0_OVRD 0x01C2 -+#define CMN_DIAG_PLL0_TEST_MODE 0x01C4 -+#define CMN_DIAG_PLL0_V2I_TUNE 0x01C5 -+#define CMN_DIAG_PLL0_CP_TUNE 0x01C6 -+#define CMN_DIAG_PLL0_LF_PROG 0x01C7 -+#define CMN_DIAG_PLL0_PTATIS_TUNE1 0x01C8 -+#define CMN_DIAG_PLL0_PTATIS_TUNE2 0x01C9 -+#define CMN_DIAG_PLL0_INCLK_CTRL 0x01CA -+#define CMN_DIAG_PLL0_PXL_DIVH 0x01CB -+#define CMN_DIAG_PLL0_PXL_DIVL 0x01CC -+#define CMN_DIAG_HSCLK_SEL 0x01E0 -+#define CMN_DIAG_PER_CAL_ADJ 0x01EC -+#define CMN_DIAG_CAL_CTRL 0x01ED -+#define CMN_DIAG_ACYA 0x01FF -+#define XCVR_PSM_RCTRL 0x4001 -+#define XCVR_PSM_CAL_TMR 0x4002 -+#define XCVR_PSM_A0IN_TMR 0x4003 -+#define TX_TXCC_CAL_SCLR_MULT_0 0x4047 -+#define TX_TXCC_CPOST_MULT_00_0 0x404C -+#define TX_TXCC_MGNFS_MULT_000_0 0x4050 -+#define XCVR_DIAG_PLLDRC_CTRL 0x40E0 -+#define XCVR_DIAG_PLLDRC_CTRL 0x40E0 -+#define XCVR_DIAG_HSCLK_SEL 0x40E1 -+#define XCVR_DIAG_BIDI_CTRL 0x40E8 -+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR 0x40F2 -+#define XCVR_DIAG_LANE_FCM_EN_MGN 0x40F2 -+#define TX_PSC_A0 0x4100 -+#define TX_PSC_A1 0x4101 -+#define TX_PSC_A2 0x4102 -+#define TX_PSC_A3 0x4103 -+#define TX_RCVDET_CTRL 0x4120 -+#define TX_RCVDET_EN_TMR 0x4122 -+#define TX_RCVDET_EN_TMR 0x4122 -+#define TX_RCVDET_ST_TMR 0x4123 -+#define TX_RCVDET_ST_TMR 0x4123 -+#define TX_BIST_CTRL 0x4140 -+#define TX_BIST_UDDWR 0x4141 -+#define TX_DIAG_TX_CTRL 0x41E0 -+#define TX_DIAG_TX_DRV 0x41E1 -+#define TX_DIAG_BGREF_PREDRV_DELAY 0x41E7 -+#define TX_DIAG_BGREF_PREDRV_DELAY 0x41E7 -+#define XCVR_PSM_RCTRL_1 0x4201 -+#define TX_TXCC_CAL_SCLR_MULT_1 0x4247 -+#define TX_TXCC_CPOST_MULT_00_1 0x424C -+#define TX_TXCC_MGNFS_MULT_000_1 0x4250 -+#define XCVR_DIAG_PLLDRC_CTRL_1 0x42E0 -+#define XCVR_DIAG_HSCLK_SEL_1 0x42E1 -+#define XCVR_DIAG_LANE_FCM_EN_MGN_TMR_1 0x42F2 -+#define TX_RCVDET_EN_TMR_1 0x4322 -+#define TX_RCVDET_ST_TMR_1 0x4323 -+#define TX_DIAG_ACYA_0 0x41FF -+#define TX_DIAG_ACYA_1 0x43FF -+#define TX_DIAG_ACYA_2 0x45FF -+#define TX_DIAG_ACYA_3 0x47FF -+#define TX_ANA_CTRL_REG_1 0x5020 -+#define TX_ANA_CTRL_REG_2 0x5021 -+#define TXDA_COEFF_CALC 0x5022 -+#define TX_DIG_CTRL_REG_1 0x5023 -+#define TX_DIG_CTRL_REG_2 0x5024 -+#define TXDA_CYA_AUXDA_CYA 0x5025 -+#define TX_ANA_CTRL_REG_3 0x5026 -+#define TX_ANA_CTRL_REG_4 0x5027 -+#define TX_ANA_CTRL_REG_5 0x5029 -+#define RX_PSC_A0 0x8000 -+#define RX_PSC_CAL 0x8006 -+#define PMA_LANE_CFG 0xC000 -+#define PIPE_CMN_CTRL1 0xC001 -+#define PIPE_CMN_CTRL2 0xC002 -+#define PIPE_COM_LOCK_CFG1 0xC003 -+#define PIPE_COM_LOCK_CFG2 0xC004 -+#define PIPE_RCV_DET_INH 0xC005 -+#define PHY_HDP_MODE_CTRL 0xC008 -+#define PHY_HDP_CLK_CTL 0xC009 -+#define STS 0xC00F -+#define PHY_ISO_CMN_CTRL 0xC010 -+#define PHY_ISO_CMN_CTRL 0xC010 -+#define PHY_HDP_TX_CTL_L0 0xC408 -+#define PHY_DP_TX_CTL 0xC408 -+#define PHY_HDP_TX_CTL_L1 0xC448 -+#define PHY_HDP_TX_CTL_L2 0xC488 -+#define PHY_HDP_TX_CTL_L3 0xC4C8 -+#define PHY_PMA_CMN_CTRL1 0xC800 -+#define PMA_CMN_CTRL1 0xC800 -+#define PHY_PMA_ISO_CMN_CTRL 0xC810 -+#define PHY_PMA_ISO_PLL_CTRL1 0xC812 -+#define PHY_PMA_ISOLATION_CTRL 0xC81F -+#define PHY_ISOLATION_CTRL 0xC81F -+#define PHY_PMA_ISO_XCVR_CTRL 0xCC11 -+#define PHY_PMA_ISO_LINK_MODE 0xCC12 -+#define PHY_PMA_ISO_PWRST_CTRL 0xCC13 -+#define PHY_PMA_ISO_TX_DATA_LO 0xCC14 -+#define PHY_PMA_ISO_TX_DATA_HI 0xCC15 -+#define PHY_PMA_ISO_RX_DATA_LO 0xCC16 -+#define PHY_PMA_ISO_RX_DATA_HI 0xCC17 -+ -+int cdns_dp_phy_init_imx8mq(struct imx_mhdp_device *hdp); -+int cdns_dp_phy_init_imx8qm(struct imx_mhdp_device *hdp); -+int cdns_hdmi_phy_set_imx8mq(struct imx_mhdp_device *hdp); -+int cdns_hdmi_phy_set_imx8qm(struct imx_mhdp_device *hdp); -+#endif /* _CDN_DP_PHY_H */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0006-drm-bridge-cadence-Add-new-api-functions.patch b/target/linux/layerscape/patches-5.4/805-display-0006-drm-bridge-cadence-Add-new-api-functions.patch deleted file mode 100644 index d41acfed2c..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0006-drm-bridge-cadence-Add-new-api-functions.patch +++ /dev/null @@ -1,864 +0,0 @@ -From ae4d4a1aa913eaafe72b252cfe93f6fad68b39f2 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Fri, 30 Aug 2019 15:02:13 +0800 -Subject: [PATCH] drm: bridge: cadence: Add new api functions - -Add variable lane_mapping for hdmi. -Add new API function cdns_mhdp_bus_read/cdns_mhdp_bus_write, -cdns_mhdp_get_fw_clk and cdns_mhdp_infoframe_set. -Adjust some API function interface. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 34 ++--- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 131 +++++------------ - drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 167 +++++++++++++++------- - drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c | 36 +++++ - include/drm/bridge/cdns-mhdp-common.h | 16 ++- - 5 files changed, 219 insertions(+), 165 deletions(-) - mode change 100644 => 100755 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c - mode change 100644 => 100755 drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c - mode change 100644 => 100755 drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c - mode change 100644 => 100755 drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c - mode change 100644 => 100755 include/drm/bridge/cdns-mhdp-common.h - ---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -116,7 +116,7 @@ static void cdns_dp_mode_set(struct imx_ - { - struct drm_dp_link link; - struct cdns_mhdp_device *mhdp = &dp->mhdp; -- u32 lane_mapping = mhdp->dp.lane_mapping; -+ u32 lane_mapping = mhdp->lane_mapping; - int ret; - char linkid[6]; - -@@ -405,12 +405,12 @@ static void cdns_dp_parse_dt(struct cdns - int ret; - - ret = of_property_read_u32(of_node, "lane-mapping", -- &mhdp->dp.lane_mapping); -+ &mhdp->lane_mapping); - if (ret) { -- mhdp->dp.lane_mapping = 0xc6; -+ mhdp->lane_mapping = 0xc6; - dev_warn(mhdp->dev, "Failed to get lane_mapping - using default 0xc6\n"); - } -- dev_info(mhdp->dev, "lane-mapping 0x%02x\n", mhdp->dp.lane_mapping); -+ dev_info(mhdp->dev, "lane-mapping 0x%02x\n", mhdp->lane_mapping); - - ret = of_property_read_u32(of_node, "link-rate", &mhdp->dp.link_rate); - if (ret) { -@@ -470,11 +470,11 @@ __cdns_dp_probe(struct platform_device * - - dp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in"); - if (dp->irq[IRQ_IN] < 0) -- dev_info(&pdev->dev, "No plug_in irq number\n"); -+ dev_info(dev, "No plug_in irq number\n"); - - dp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out"); - if (dp->irq[IRQ_OUT] < 0) -- dev_info(&pdev->dev, "No plug_out irq number\n"); -+ dev_info(dev, "No plug_out irq number\n"); - - cdns_dp_parse_dt(&dp->mhdp); - -@@ -498,7 +498,7 @@ __cdns_dp_probe(struct platform_device * - IRQF_ONESHOT, dev_name(dev), - dp); - if (ret) { -- dev_err(&pdev->dev, "can't claim irq %d\n", -+ dev_err(dev, "can't claim irq %d\n", - dp->irq[IRQ_IN]); - goto err_out; - } -@@ -509,7 +509,7 @@ __cdns_dp_probe(struct platform_device * - IRQF_ONESHOT, dev_name(dev), - dp); - if (ret) { -- dev_err(&pdev->dev, "can't claim irq %d\n", -+ dev_err(dev, "can't claim irq %d\n", - dp->irq[IRQ_OUT]); - goto err_out; - } -@@ -521,10 +521,10 @@ __cdns_dp_probe(struct platform_device * - dp->mhdp.bridge.base.driver_private = dp; - dp->mhdp.bridge.base.funcs = &cdns_dp_bridge_funcs; - #ifdef CONFIG_OF -- dp->mhdp.bridge.base.of_node = pdev->dev.of_node; -+ dp->mhdp.bridge.base.of_node = dev->of_node; - #endif - -- platform_set_drvdata(pdev, dp); -+ dev_set_drvdata(dev, &dp->mhdp); - - dp_aux_init(&dp->mhdp, dev); - -@@ -534,9 +534,9 @@ err_out: - return ERR_PTR(ret); - } - --static void __cdns_dp_remove(struct imx_mhdp_device *dp) -+static void __cdns_dp_remove(struct cdns_mhdp_device *mhdp) - { -- dp_aux_destroy(&dp->mhdp); -+ dp_aux_destroy(mhdp); - } - - /* ----------------------------------------------------------------------------- -@@ -559,11 +559,11 @@ EXPORT_SYMBOL_GPL(cdns_dp_probe); - - void cdns_dp_remove(struct platform_device *pdev) - { -- struct imx_mhdp_device *dp = platform_get_drvdata(pdev); -+ struct cdns_mhdp_device *mhdp = platform_get_drvdata(pdev); - -- drm_bridge_remove(&dp->mhdp.bridge.base); -+ drm_bridge_remove(&mhdp->bridge.base); - -- __cdns_dp_remove(dp); -+ __cdns_dp_remove(mhdp); - } - EXPORT_SYMBOL_GPL(cdns_dp_remove); - -@@ -593,9 +593,9 @@ EXPORT_SYMBOL_GPL(cdns_dp_bind); - - void cdns_dp_unbind(struct device *dev) - { -- struct imx_mhdp_device *dp = dev_get_drvdata(dev); -+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); - -- __cdns_dp_remove(dp); -+ __cdns_dp_remove(mhdp); - } - EXPORT_SYMBOL_GPL(cdns_dp_unbind); - ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -25,25 +25,8 @@ - #include - #include - #include --#include - #include - --static void hdmi_writel(struct cdns_mhdp_device *mhdp, u32 val, u32 offset) --{ -- struct imx_mhdp_device *hdmi = container_of(mhdp, struct imx_mhdp_device, mhdp); -- -- /* TODO */ -- if (offset >= 0x1000 && hdmi->regmap_csr) { -- /* Remap address to low 4K memory */ -- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, offset >> 12); -- writel(val, (offset & 0xfff) + mhdp->regs); -- /* Restore address mapping */ -- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, 0); -- -- } else -- writel(val, mhdp->regs + offset); --} -- - static int hdmi_sink_config(struct cdns_mhdp_device *mhdp) - { - struct drm_scdc *scdc = &mhdp->connector.base.display_info.hdmi.scdc; -@@ -75,65 +58,12 @@ static int hdmi_sink_config(struct cdns_ - return ret; - } - --static int hdmi_lanes_config(struct cdns_mhdp_device *mhdp) --{ -- int ret; -- -- /* TODO */ -- /* Set the lane swapping */ --// if (cpu_is_imx8qm()) -- ret = cdns_mhdp_reg_write(mhdp, LANES_CONFIG, -- F_SOURCE_PHY_LANE0_SWAP(3) | -- F_SOURCE_PHY_LANE1_SWAP(0) | -- F_SOURCE_PHY_LANE2_SWAP(1) | -- F_SOURCE_PHY_LANE3_SWAP(2) | -- F_SOURCE_PHY_COMB_BYPASS(0) | -- F_SOURCE_PHY_20_10(1)); --#if 0 -- else -- ret = cdns_mhdp_reg_write(mhdp, LANES_CONFIG, -- F_SOURCE_PHY_LANE0_SWAP(0) | -- F_SOURCE_PHY_LANE1_SWAP(1) | -- F_SOURCE_PHY_LANE2_SWAP(2) | -- F_SOURCE_PHY_LANE3_SWAP(3) | -- F_SOURCE_PHY_COMB_BYPASS(0) | -- F_SOURCE_PHY_20_10(1)); --#endif -- return ret; --} -- --static void hdmi_info_frame_set(struct cdns_mhdp_device *mhdp, -- u8 entry_id, u8 packet_len, u8 *packet, u8 packet_type) -+static void hdmi_lanes_config(struct cdns_mhdp_device *mhdp) - { -- u32 *packet32, len32; -- u32 val, i; -- -- /* invalidate entry */ -- val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id); -- hdmi_writel(mhdp, val, SOURCE_PIF_PKT_ALLOC_REG); -- hdmi_writel(mhdp, F_PKT_ALLOC_WR_EN(1), SOURCE_PIF_PKT_ALLOC_WR_EN); -- -- /* flush fifo 1 */ -- hdmi_writel(mhdp, F_FIFO1_FLUSH(1), SOURCE_PIF_FIFO1_FLUSH); -- -- /* write packet into memory */ -- packet32 = (u32 *)packet; -- len32 = packet_len / 4; -- for (i = 0; i < len32; i++) -- hdmi_writel(mhdp, F_DATA_WR(packet32[i]), SOURCE_PIF_DATA_WR); -- -- /* write entry id */ -- hdmi_writel(mhdp, F_WR_ADDR(entry_id), SOURCE_PIF_WR_ADDR); -- -- /* write request */ -- hdmi_writel(mhdp, F_HOST_WR(1), SOURCE_PIF_WR_REQ); -- -- /* update entry */ -- val = F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) | -- F_PACKET_TYPE(packet_type) | F_PKT_ALLOC_ADDRESS(entry_id); -- hdmi_writel(mhdp, val, SOURCE_PIF_PKT_ALLOC_REG); -- -- hdmi_writel(mhdp, F_PKT_ALLOC_WR_EN(1), SOURCE_PIF_PKT_ALLOC_WR_EN); -+ /* Line swaping */ -+ /* For imx8qm lane_mapping = 0x93 -+ * For imx8mq lane_mapping = 0xe4*/ -+ cdns_mhdp_reg_write(mhdp, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping); - } - - #define RGB_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\ -@@ -148,9 +78,11 @@ static int hdmi_avi_info_set(struct cdns - struct drm_display_mode *mode) - { - struct hdmi_avi_infoframe frame; --// struct drm_display_info *di = &mhdp->connector.base.display_info; --// enum hdmi_extended_colorimetry ext_col; --// u32 sink_col, allowed_col; -+#if 0 -+ struct drm_display_info *di = &mhdp->connector.base.display_info; -+ enum hdmi_extended_colorimetry ext_col; -+ u32 sink_col, allowed_col; -+#endif - int format = mhdp->video_info.color_fmt; - u8 buf[32]; - int ret; -@@ -209,7 +141,7 @@ static int hdmi_avi_info_set(struct cdns - } - - buf[0] = 0; -- hdmi_info_frame_set(mhdp, 0, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_AVI); -+ cdns_mhdp_infoframe_set(mhdp, 0, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_AVI); - return 0; - } - -@@ -234,7 +166,7 @@ static int hdmi_vendor_info_set(struct c - } - - buf[0] = 0; -- hdmi_info_frame_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_VENDOR); -+ cdns_mhdp_infoframe_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_VENDOR); - return 0; - } - -@@ -464,6 +396,19 @@ static irqreturn_t cdns_hdmi_irq_thread( - return IRQ_HANDLED; - } - -+static void cdns_hdmi_parse_dt(struct cdns_mhdp_device *mhdp) -+{ -+ struct device_node *of_node = mhdp->dev->of_node; -+ int ret; -+ -+ ret = of_property_read_u32(of_node, "lane-mapping", &mhdp->lane_mapping); -+ if (ret) { -+ mhdp->lane_mapping = 0xc6; -+ dev_warn(mhdp->dev, "Failed to get lane_mapping - using default 0xc6\n"); -+ } -+ dev_info(mhdp->dev, "lane-mapping 0x%02x\n", mhdp->lane_mapping); -+} -+ - static struct imx_mhdp_device * - __cdns_hdmi_probe(struct platform_device *pdev, - const struct cdn_plat_data *plat_data) -@@ -503,13 +448,13 @@ __cdns_hdmi_probe(struct platform_device - - hdmi->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in"); - if (hdmi->irq[IRQ_IN] < 0) { -- dev_info(&pdev->dev, "No plug_in irq number\n"); -+ dev_info(dev, "No plug_in irq number\n"); - return ERR_PTR(-EPROBE_DEFER); - } - - hdmi->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out"); - if (hdmi->irq[IRQ_OUT] < 0) { -- dev_info(&pdev->dev, "No plug_out irq number\n"); -+ dev_info(dev, "No plug_out irq number\n"); - return ERR_PTR(-EPROBE_DEFER); - } - -@@ -533,7 +478,7 @@ __cdns_hdmi_probe(struct platform_device - IRQF_ONESHOT, dev_name(dev), - hdmi); - if (ret) { -- dev_err(&pdev->dev, "can't claim irq %d\n", -+ dev_err(dev, "can't claim irq %d\n", - hdmi->irq[IRQ_IN]); - goto err_out; - } -@@ -544,11 +489,13 @@ __cdns_hdmi_probe(struct platform_device - IRQF_ONESHOT, dev_name(dev), - hdmi); - if (ret) { -- dev_err(&pdev->dev, "can't claim irq %d\n", -+ dev_err(dev, "can't claim irq %d\n", - hdmi->irq[IRQ_OUT]); - goto err_out; - } - -+ cdns_hdmi_parse_dt(&hdmi->mhdp); -+ - if (cdns_mhdp_read_hpd(&hdmi->mhdp)) - enable_irq(hdmi->irq[IRQ_OUT]); - else -@@ -557,14 +504,14 @@ __cdns_hdmi_probe(struct platform_device - hdmi->mhdp.bridge.base.driver_private = hdmi; - hdmi->mhdp.bridge.base.funcs = &cdns_hdmi_bridge_funcs; - #ifdef CONFIG_OF -- hdmi->mhdp.bridge.base.of_node = pdev->dev.of_node; -+ hdmi->mhdp.bridge.base.of_node = dev->of_node; - #endif - - memset(&pdevinfo, 0, sizeof(pdevinfo)); - pdevinfo.parent = dev; - pdevinfo.id = PLATFORM_DEVID_AUTO; - -- platform_set_drvdata(pdev, hdmi); -+ dev_set_drvdata(dev, &hdmi->mhdp); - - return hdmi; - -@@ -573,7 +520,7 @@ err_out: - return ERR_PTR(ret); - } - --static void __cdns_hdmi_remove(struct imx_mhdp_device *hdmi) -+static void __cdns_hdmi_remove(struct cdns_mhdp_device *mhdp) - { - } - -@@ -597,11 +544,11 @@ EXPORT_SYMBOL_GPL(cdns_hdmi_probe); - - void cdns_hdmi_remove(struct platform_device *pdev) - { -- struct imx_mhdp_device *hdmi = platform_get_drvdata(pdev); -+ struct cdns_mhdp_device *mhdp = platform_get_drvdata(pdev); - -- drm_bridge_remove(&hdmi->mhdp.bridge.base); -+ drm_bridge_remove(&mhdp->bridge.base); - -- __cdns_hdmi_remove(hdmi); -+ __cdns_hdmi_remove(mhdp); - } - EXPORT_SYMBOL_GPL(cdns_hdmi_remove); - -@@ -631,9 +578,9 @@ EXPORT_SYMBOL_GPL(cdns_hdmi_bind); - - void cdns_hdmi_unbind(struct device *dev) - { -- struct imx_mhdp_device *hdmi = dev_get_drvdata(dev); -+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); - -- __cdns_hdmi_remove(hdmi); -+ __cdns_hdmi_remove(mhdp); - } - EXPORT_SYMBOL_GPL(cdns_hdmi_unbind); - ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -@@ -23,8 +23,10 @@ - #include - - #include -+#include - #include - #include -+#include - - #define CDNS_DP_SPDIF_CLK 200000000 - #define FW_ALIVE_TIMEOUT_US 1000000 -@@ -33,6 +35,27 @@ - #define LINK_TRAINING_RETRY_MS 20 - #define LINK_TRAINING_TIMEOUT_MS 500 - -+#define mhdp_readx_poll_timeout(op, addr, offset, val, cond, sleep_us, timeout_us) \ -+({ \ -+ u64 __timeout_us = (timeout_us); \ -+ unsigned long __sleep_us = (sleep_us); \ -+ ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ -+ might_sleep_if((__sleep_us) != 0); \ -+ for (;;) { \ -+ (val) = op(addr, offset); \ -+ if (cond) \ -+ break; \ -+ if (__timeout_us && \ -+ ktime_compare(ktime_get(), __timeout) > 0) { \ -+ (val) = op(addr, offset); \ -+ break; \ -+ } \ -+ if (__sleep_us) \ -+ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ -+ } \ -+ (cond) ? 0 : -ETIMEDOUT; \ -+}) -+ - static inline u32 get_unaligned_be24(const void *p) - { - const u8 *_p = p; -@@ -49,9 +72,51 @@ static inline void put_unaligned_be24(u3 - _p[2] = val; - } - -+u32 cdns_mhdp_bus_read(struct cdns_mhdp_device *mhdp, u32 offset) -+{ -+ struct imx_mhdp_device *hdmi = container_of(mhdp, struct imx_mhdp_device, mhdp); -+ u32 val; -+ -+ /* TODO */ -+ if (offset >= 0x1000 && hdmi->regmap_csr) { -+ /* Remap address to low 4K memory */ -+ regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, offset >> 12); -+ val = readl((offset & 0xfff) + mhdp->regs); -+ /* Restore address mapping */ -+ regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, 0); -+ } else -+ val = readl(mhdp->regs + offset); -+ -+ return val; -+} -+EXPORT_SYMBOL(cdns_mhdp_bus_read); -+ -+void cdns_mhdp_bus_write(u32 val, struct cdns_mhdp_device *mhdp, u32 offset) -+{ -+ struct imx_mhdp_device *hdmi = container_of(mhdp, struct imx_mhdp_device, mhdp); -+ -+ /* TODO */ -+ if (offset >= 0x1000 && hdmi->regmap_csr) { -+ /* Remap address to low 4K memory */ -+ regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, offset >> 12); -+ writel(val, (offset & 0xfff) + mhdp->regs); -+ /* Restore address mapping */ -+ regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, 0); -+ -+ } else -+ writel(val, mhdp->regs + offset); -+} -+EXPORT_SYMBOL(cdns_mhdp_bus_write); -+ -+u32 cdns_mhdp_get_fw_clk(struct cdns_mhdp_device *mhdp) -+{ -+ return cdns_mhdp_bus_read(mhdp, SW_CLK_H); -+} -+EXPORT_SYMBOL(cdns_mhdp_get_fw_clk); -+ - void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk) - { -- writel(clk / 1000000, mhdp->regs + SW_CLK_H); -+ cdns_mhdp_bus_write(clk / 1000000, mhdp, SW_CLK_H); - } - EXPORT_SYMBOL(cdns_mhdp_set_fw_clk); - -@@ -71,16 +136,16 @@ void cdns_mhdp_clock_reset(struct cdns_m - DPTX_SYS_CLK_EN | - CFG_DPTX_VIF_CLK_RSTN_EN | - CFG_DPTX_VIF_CLK_EN; -- writel(val, mhdp->regs + SOURCE_DPTX_CAR); -+ cdns_mhdp_bus_write(val, mhdp, SOURCE_DPTX_CAR); - - val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN; -- writel(val, mhdp->regs + SOURCE_PHY_CAR); -+ cdns_mhdp_bus_write(val, mhdp, SOURCE_PHY_CAR); - - val = SOURCE_PKT_SYS_RSTN_EN | - SOURCE_PKT_SYS_CLK_EN | - SOURCE_PKT_DATA_RSTN_EN | - SOURCE_PKT_DATA_CLK_EN; -- writel(val, mhdp->regs + SOURCE_PKT_CAR); -+ cdns_mhdp_bus_write(val, mhdp, SOURCE_PKT_CAR); - - val = SPDIF_CDR_CLK_RSTN_EN | - SPDIF_CDR_CLK_EN | -@@ -88,20 +153,20 @@ void cdns_mhdp_clock_reset(struct cdns_m - SOURCE_AIF_SYS_CLK_EN | - SOURCE_AIF_CLK_RSTN_EN | - SOURCE_AIF_CLK_EN; -- writel(val, mhdp->regs + SOURCE_AIF_CAR); -+ cdns_mhdp_bus_write(val, mhdp, SOURCE_AIF_CAR); - - val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN | - SOURCE_CIPHER_SYS_CLK_EN | - SOURCE_CIPHER_CHAR_CLK_RSTN_EN | - SOURCE_CIPHER_CHAR_CLK_EN; -- writel(val, mhdp->regs + SOURCE_CIPHER_CAR); -+ cdns_mhdp_bus_write(val, mhdp, SOURCE_CIPHER_CAR); - - val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN | - SOURCE_CRYPTO_SYS_CLK_EN; -- writel(val, mhdp->regs + SOURCE_CRYPTO_CAR); -+ cdns_mhdp_bus_write(val, mhdp, SOURCE_CRYPTO_CAR); - - /* enable Mailbox and PIF interrupt */ -- writel(0, mhdp->regs + APB_INT_MASK); -+ cdns_mhdp_bus_write(0, mhdp, APB_INT_MASK); - } - EXPORT_SYMBOL(cdns_mhdp_clock_reset); - -@@ -109,13 +174,13 @@ int cdns_mhdp_mailbox_read(struct cdns_m - { - int val, ret; - -- ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_EMPTY_ADDR, -+ ret = mhdp_readx_poll_timeout(cdns_mhdp_bus_read, mhdp, MAILBOX_EMPTY_ADDR, - val, !val, MAILBOX_RETRY_US, - MAILBOX_TIMEOUT_US); - if (ret < 0) - return ret; - -- return readl(mhdp->regs + MAILBOX0_RD_DATA) & 0xff; -+ return cdns_mhdp_bus_read(mhdp, MAILBOX0_RD_DATA) & 0xff; - } - EXPORT_SYMBOL(cdns_mhdp_mailbox_read); - -@@ -123,13 +188,13 @@ static int cdp_dp_mailbox_write(struct c - { - int ret, full; - -- ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_FULL_ADDR, -+ ret = mhdp_readx_poll_timeout(cdns_mhdp_bus_read, mhdp, MAILBOX_FULL_ADDR, - full, !full, MAILBOX_RETRY_US, - MAILBOX_TIMEOUT_US); - if (ret < 0) - return ret; - -- writel(val, mhdp->regs + MAILBOX0_WR_DATA); -+ cdns_mhdp_bus_write(val, mhdp, MAILBOX0_WR_DATA); - - return 0; - } -@@ -357,20 +422,20 @@ int cdns_mhdp_load_firmware(struct cdns_ - int i, ret; - - /* reset ucpu before load firmware*/ -- writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET, -- mhdp->regs + APB_CTRL); -+ cdns_mhdp_bus_write(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET, -+ mhdp, APB_CTRL); - - for (i = 0; i < i_size; i += 4) -- writel(*i_mem++, mhdp->regs + ADDR_IMEM + i); -+ cdns_mhdp_bus_write(*i_mem++, mhdp, ADDR_IMEM + i); - - for (i = 0; i < d_size; i += 4) -- writel(*d_mem++, mhdp->regs + ADDR_DMEM + i); -+ cdns_mhdp_bus_write(*d_mem++, mhdp, ADDR_DMEM + i); - - /* un-reset ucpu */ -- writel(0, mhdp->regs + APB_CTRL); -+ cdns_mhdp_bus_write(0, mhdp, APB_CTRL); - - /* check the keep alive register to make sure fw working */ -- ret = readx_poll_timeout(readl, mhdp->regs + KEEP_ALIVE, -+ ret = mhdp_readx_poll_timeout(cdns_mhdp_bus_read, mhdp, KEEP_ALIVE, - reg, reg, 2000, FW_ALIVE_TIMEOUT_US); - if (ret < 0) { - DRM_DEV_ERROR(mhdp->dev, "failed to loaded the FW reg = %x\n", -@@ -378,13 +443,13 @@ int cdns_mhdp_load_firmware(struct cdns_ - return -EINVAL; - } - -- reg = readl(mhdp->regs + VER_L) & 0xff; -+ reg = cdns_mhdp_bus_read(mhdp, VER_L) & 0xff; - mhdp->fw_version = reg; -- reg = readl(mhdp->regs + VER_H) & 0xff; -+ reg = cdns_mhdp_bus_read(mhdp, VER_H) & 0xff; - mhdp->fw_version |= reg << 8; -- reg = readl(mhdp->regs + VER_LIB_L_ADDR) & 0xff; -+ reg = cdns_mhdp_bus_read(mhdp, VER_LIB_L_ADDR) & 0xff; - mhdp->fw_version |= reg << 16; -- reg = readl(mhdp->regs + VER_LIB_H_ADDR) & 0xff; -+ reg = cdns_mhdp_bus_read(mhdp, VER_LIB_H_ADDR) & 0xff; - mhdp->fw_version |= reg << 24; - - DRM_DEV_DEBUG(mhdp->dev, "firmware version: %x\n", mhdp->fw_version); -@@ -466,7 +531,7 @@ int cdns_mhdp_event_config(struct cdns_m - - memset(msg, 0, sizeof(msg)); - -- msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING; -+ msg[0] = MHDP_EVENT_ENABLE_HPD | MHDP_EVENT_ENABLE_TRAINING; - - ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX, - DPTX_ENABLE_EVENT, sizeof(msg), msg); -@@ -479,7 +544,7 @@ EXPORT_SYMBOL(cdns_mhdp_event_config); - - u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp) - { -- return readl(mhdp->regs + SW_EVENTS0); -+ return cdns_mhdp_bus_read(mhdp, SW_EVENTS0); - } - EXPORT_SYMBOL(cdns_mhdp_get_event); - -@@ -883,24 +948,24 @@ int cdns_mhdp_audio_stop(struct cdns_mhd - return ret; - } - -- writel(0, mhdp->regs + SPDIF_CTRL_ADDR); -+ cdns_mhdp_bus_write(0, mhdp, SPDIF_CTRL_ADDR); - - /* clearn the audio config and reset */ -- writel(0, mhdp->regs + AUDIO_SRC_CNTL); -- writel(0, mhdp->regs + AUDIO_SRC_CNFG); -- writel(AUDIO_SW_RST, mhdp->regs + AUDIO_SRC_CNTL); -- writel(0, mhdp->regs + AUDIO_SRC_CNTL); -+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL); -+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNFG); -+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, AUDIO_SRC_CNTL); -+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL); - - /* reset smpl2pckt component */ -- writel(0, mhdp->regs + SMPL2PKT_CNTL); -- writel(AUDIO_SW_RST, mhdp->regs + SMPL2PKT_CNTL); -- writel(0, mhdp->regs + SMPL2PKT_CNTL); -+ cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL); -+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, SMPL2PKT_CNTL); -+ cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL); - - /* reset FIFO */ -- writel(AUDIO_SW_RST, mhdp->regs + FIFO_CNTL); -- writel(0, mhdp->regs + FIFO_CNTL); -+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, FIFO_CNTL); -+ cdns_mhdp_bus_write(0, mhdp, FIFO_CNTL); - -- if (audio->format == AFMT_SPDIF) -+ if (audio->format == AFMT_SPDIF_INT) - clk_disable_unprepare(mhdp->spdif_clk); - - return 0; -@@ -936,15 +1001,15 @@ static void cdns_mhdp_audio_config_i2s(s - i2s_port_en_val = 3; - } - -- writel(0x0, mhdp->regs + SPDIF_CTRL_ADDR); -+ cdns_mhdp_bus_write(0x0, mhdp, SPDIF_CTRL_ADDR); - -- writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); -+ cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL); - - val = MAX_NUM_CH(audio->channels); - val |= NUM_OF_I2S_PORTS(audio->channels); - val |= AUDIO_TYPE_LPCM; - val |= CFG_SUB_PCKT_NUM(sub_pckt_num); -- writel(val, mhdp->regs + SMPL2PKT_CNFG); -+ cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG); - - if (audio->sample_width == 16) - val = 0; -@@ -956,7 +1021,7 @@ static void cdns_mhdp_audio_config_i2s(s - val |= AUDIO_CH_NUM(audio->channels); - val |= I2S_DEC_PORT_EN(i2s_port_en_val); - val |= TRANS_SMPL_WIDTH_32; -- writel(val, mhdp->regs + AUDIO_SRC_CNFG); -+ cdns_mhdp_bus_write(val, mhdp, AUDIO_SRC_CNFG); - - for (i = 0; i < (audio->channels + 1) / 2; i++) { - if (audio->sample_width == 16) -@@ -965,7 +1030,7 @@ static void cdns_mhdp_audio_config_i2s(s - val = (0x0b << 8) | (0x0b << 20); - - val |= ((2 * i) << 4) | ((2 * i + 1) << 16); -- writel(val, mhdp->regs + STTS_BIT_CH(i)); -+ cdns_mhdp_bus_write(val, mhdp, STTS_BIT_CH(i)); - } - - switch (audio->sample_rate) { -@@ -999,24 +1064,24 @@ static void cdns_mhdp_audio_config_i2s(s - break; - } - val |= 4; -- writel(val, mhdp->regs + COM_CH_STTS_BITS); -+ cdns_mhdp_bus_write(val, mhdp, COM_CH_STTS_BITS); - -- writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); -- writel(I2S_DEC_START, mhdp->regs + AUDIO_SRC_CNTL); -+ cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL); -+ cdns_mhdp_bus_write(I2S_DEC_START, mhdp, AUDIO_SRC_CNTL); - } - - static void cdns_mhdp_audio_config_spdif(struct cdns_mhdp_device *mhdp) - { - u32 val; - -- writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL); -+ cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL); - - val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4); -- writel(val, mhdp->regs + SMPL2PKT_CNFG); -- writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL); -+ cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG); -+ cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL); - - val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS; -- writel(val, mhdp->regs + SPDIF_CTRL_ADDR); -+ cdns_mhdp_bus_write(val, mhdp, SPDIF_CTRL_ADDR); - - clk_prepare_enable(mhdp->spdif_clk); - clk_set_rate(mhdp->spdif_clk, CDNS_DP_SPDIF_CLK); -@@ -1028,7 +1093,7 @@ int cdns_mhdp_audio_config(struct cdns_m - int ret; - - /* reset the spdif clk before config */ -- if (audio->format == AFMT_SPDIF) { -+ if (audio->format == AFMT_SPDIF_INT) { - reset_control_assert(mhdp->spdif_rst); - reset_control_deassert(mhdp->spdif_rst); - } -@@ -1043,7 +1108,7 @@ int cdns_mhdp_audio_config(struct cdns_m - - if (audio->format == AFMT_I2S) - cdns_mhdp_audio_config_i2s(mhdp, audio); -- else if (audio->format == AFMT_SPDIF) -+ else if (audio->format == AFMT_SPDIF_INT) - cdns_mhdp_audio_config_spdif(mhdp); - - ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN); -@@ -1150,12 +1215,12 @@ bool cdns_mhdp_check_alive(struct cdns_m - u32 alive, newalive; - u8 retries_left = 10; - -- alive = readl(mhdp->regs + KEEP_ALIVE); -+ alive = cdns_mhdp_bus_read(mhdp, KEEP_ALIVE); - - while (retries_left--) { - udelay(2); - -- newalive = readl(mhdp->regs + KEEP_ALIVE); -+ newalive = cdns_mhdp_bus_read(mhdp, KEEP_ALIVE); - if (alive == newalive) - continue; - return true; ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c -@@ -10,6 +10,42 @@ - #include - #include - #include -+#include -+#include -+ -+void cdns_mhdp_infoframe_set(struct cdns_mhdp_device *mhdp, -+ u8 entry_id, u8 packet_len, u8 *packet, u8 packet_type) -+{ -+ u32 *packet32, len32; -+ u32 val, i; -+ -+ /* invalidate entry */ -+ val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id); -+ cdns_mhdp_bus_write(val, mhdp, SOURCE_PIF_PKT_ALLOC_REG); -+ cdns_mhdp_bus_write(F_PKT_ALLOC_WR_EN(1), mhdp, SOURCE_PIF_PKT_ALLOC_WR_EN); -+ -+ /* flush fifo 1 */ -+ cdns_mhdp_bus_write(F_FIFO1_FLUSH(1), mhdp, SOURCE_PIF_FIFO1_FLUSH); -+ -+ /* write packet into memory */ -+ packet32 = (u32 *)packet; -+ len32 = packet_len / 4; -+ for (i = 0; i < len32; i++) -+ cdns_mhdp_bus_write(F_DATA_WR(packet32[i]), mhdp, SOURCE_PIF_DATA_WR); -+ -+ /* write entry id */ -+ cdns_mhdp_bus_write(F_WR_ADDR(entry_id), mhdp, SOURCE_PIF_WR_ADDR); -+ -+ /* write request */ -+ cdns_mhdp_bus_write(F_HOST_WR(1), mhdp, SOURCE_PIF_WR_REQ); -+ -+ /* update entry */ -+ val = F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) | -+ F_PACKET_TYPE(packet_type) | F_PKT_ALLOC_ADDRESS(entry_id); -+ cdns_mhdp_bus_write(val, mhdp, SOURCE_PIF_PKT_ALLOC_REG); -+ -+ cdns_mhdp_bus_write(F_PKT_ALLOC_WR_EN(1), mhdp, SOURCE_PIF_PKT_ALLOC_WR_EN); -+} - - int cdns_hdmi_get_edid_block(void *data, u8 *edid, - u32 block, size_t length) ---- a/include/drm/bridge/cdns-mhdp-common.h -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -391,8 +391,8 @@ - #define FW_STANDBY 0 - #define FW_ACTIVE 1 - --#define DPTX_EVENT_ENABLE_HPD BIT(0) --#define DPTX_EVENT_ENABLE_TRAINING BIT(1) -+#define MHDP_EVENT_ENABLE_HPD BIT(0) -+#define MHDP_EVENT_ENABLE_TRAINING BIT(1) - - #define LINK_TRAINING_NOT_ACTIVE 0 - #define LINK_TRAINING_RUN 1 -@@ -532,7 +532,8 @@ enum vic_bt_type { - - enum audio_format { - AFMT_I2S = 0, -- AFMT_SPDIF = 1, -+ AFMT_SPDIF_INT = 1, -+ AFMT_SPDIF_EXT = 2, - AFMT_UNUSED, - }; - -@@ -625,12 +626,13 @@ struct cdns_mhdp_device { - struct drm_dp_mst_topology_mgr mst_mgr; - struct delayed_work hotplug_work; - -+ u32 lane_mapping; - bool link_up; - bool power_up; - bool plugged; - - union { -- struct _dp_data { -+ struct cdn_dp_data { - struct drm_dp_link link; - struct drm_dp_aux aux; - struct cdns_mhdp_host host; -@@ -638,7 +640,6 @@ struct cdns_mhdp_device { - struct cdns_mhdp_mst_cbs cbs; - bool is_mst; - bool can_mst; -- u32 lane_mapping; - u32 link_rate; - u32 num_lanes; - } dp; -@@ -649,8 +650,11 @@ struct cdns_mhdp_device { - }; - }; - -+u32 cdns_mhdp_bus_read(struct cdns_mhdp_device *mhdp, u32 offset); -+void cdns_mhdp_bus_write(u32 val, struct cdns_mhdp_device *mhdp, u32 offset); - void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp); - void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk); -+u32 cdns_mhdp_get_fw_clk(struct cdns_mhdp_device *mhdp); - int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, - u32 i_size, const u32 *d_mem, u32 d_size); - int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable); -@@ -691,6 +695,8 @@ int cdns_mhdp_mailbox_validate_receive(s - u16 req_size); - int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp); - -+void cdns_mhdp_infoframe_set(struct cdns_mhdp_device *mhdp, -+ u8 entry_id, u8 packet_len, u8 *packet, u8 packet_type); - int cdns_hdmi_get_edid_block(void *data, u8 *edid, u32 block, size_t length); - int cdns_hdmi_scdc_read(struct cdns_mhdp_device *mhdp, u8 addr, u8 *data); - int cdns_hdmi_scdc_write(struct cdns_mhdp_device *mhdp, u8 addr, u8 value); diff --git a/target/linux/layerscape/patches-5.4/805-display-0007-drm-bridge-cadence-Add-mhdp-audio-driver.patch b/target/linux/layerscape/patches-5.4/805-display-0007-drm-bridge-cadence-Add-mhdp-audio-driver.patch deleted file mode 100644 index f0a1414b03..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0007-drm-bridge-cadence-Add-mhdp-audio-driver.patch +++ /dev/null @@ -1,715 +0,0 @@ -From 3cd4b3cfc651c4d54897c72fbbaa9cd583ee6208 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Fri, 30 Aug 2019 17:51:43 +0800 -Subject: [PATCH] drm: bridge: cadence: Add mhdp audio driver - -Move mhdp audio driver to cadence folder. -Add audio info-frame set function for hdmi tx audio. -The driver suppoer both HDMI and DP audio. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/Kconfig | 3 + - drivers/gpu/drm/bridge/cadence/Makefile | 3 +- - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 4 + - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 5 +- - drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c | 395 ++++++++++++++++++++++ - drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 183 ---------- - drivers/gpu/drm/imx/Kconfig | 1 + - include/drm/bridge/cdns-mhdp-common.h | 6 + - 8 files changed, 414 insertions(+), 186 deletions(-) - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c - ---- a/drivers/gpu/drm/bridge/cadence/Kconfig -+++ b/drivers/gpu/drm/bridge/cadence/Kconfig -@@ -11,3 +11,6 @@ config DRM_CDNS_HDMI - - config DRM_CDNS_DP - tristate "Cadence DP DRM driver" -+ -+config DRM_CDNS_AUDIO -+ tristate "Cadence MHDP Audio driver" ---- a/drivers/gpu/drm/bridge/cadence/Makefile -+++ b/drivers/gpu/drm/bridge/cadence/Makefile -@@ -1,5 +1,4 @@ --#ccflags-y := -Iinclude/drm -- - obj-$(CONFIG_DRM_CDNS_MHDP) += cdns-mhdp-common.o cdns-mhdp-hdmi.o - obj-$(CONFIG_DRM_CDNS_HDMI) += cdns-hdmi-core.o - obj-$(CONFIG_DRM_CDNS_DP) += cdns-dp-core.o -+obj-$(CONFIG_DRM_CDNS_AUDIO) += cdns-mhdp-audio.o ---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -526,6 +526,9 @@ __cdns_dp_probe(struct platform_device * - - dev_set_drvdata(dev, &dp->mhdp); - -+ /* register audio driver */ -+ cdns_mhdp_register_audio_driver(dev); -+ - dp_aux_init(&dp->mhdp, dev); - - return dp; -@@ -537,6 +540,7 @@ err_out: - static void __cdns_dp_remove(struct cdns_mhdp_device *mhdp) - { - dp_aux_destroy(mhdp); -+ cdns_mhdp_unregister_audio_driver(mhdp->dev); - } - - /* ----------------------------------------------------------------------------- ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -9,7 +9,6 @@ - * (at your option) any later version. - * - */ -- - #include - #include - #include -@@ -513,6 +512,9 @@ __cdns_hdmi_probe(struct platform_device - - dev_set_drvdata(dev, &hdmi->mhdp); - -+ /* register audio driver */ -+ cdns_mhdp_register_audio_driver(dev); -+ - return hdmi; - - err_out: -@@ -522,6 +524,7 @@ err_out: - - static void __cdns_hdmi_remove(struct cdns_mhdp_device *mhdp) - { -+ cdns_mhdp_unregister_audio_driver(mhdp->dev); - } - - /* ----------------------------------------------------------------------------- ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c -@@ -0,0 +1,395 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd -+ * Author: Chris Zhong -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define CDNS_DP_SPDIF_CLK 200000000 -+ -+static u32 TMDS_rate_table[7] = { -+ 25200, 27000, 54000, 74250, 148500, 297000, 594000, -+}; -+ -+static u32 N_table_32k[7] = { -+/* 25200/27000/54000/74250/148500/297000/594000 */ -+ 4096, 4096, 4096, 4096, 4096, 3072, 3072, -+}; -+ -+static u32 N_table_44k[7] = { -+ 6272, 6272, 6272, 6272, 6272, 4704, 9408, -+}; -+ -+static u32 N_table_48k[7] = { -+ 6144, 6144, 6144, 6144, 6144, 5120, 6144, -+}; -+ -+static int select_N_index(u32 pclk) -+{ -+ int num = sizeof(TMDS_rate_table)/sizeof(int); -+ int i = 0; -+ -+ for (i = 0; i < num ; i++) -+ if (pclk == TMDS_rate_table[i]) -+ break; -+ -+ if (i == num) { -+ DRM_WARN("pclkc %d is not supported!\n", pclk); -+ return num-1; -+ } -+ -+ return i; -+} -+ -+static void hdmi_audio_avi_set(struct cdns_mhdp_device *mhdp, -+ u32 channels) -+{ -+ struct hdmi_audio_infoframe frame; -+ u8 buf[32]; -+ int ret; -+ -+ hdmi_audio_infoframe_init(&frame); -+ -+ frame.channels = channels; -+ frame.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; -+ -+ if (channels == 2) -+ frame.channel_allocation = 0; -+ else if (channels == 4) -+ frame.channel_allocation = 0x3; -+ else if (channels == 8) -+ frame.channel_allocation = 0x13; -+ -+ ret = hdmi_audio_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1); -+ if (ret < 0) { -+ DRM_ERROR("failed to pack audio infoframe: %d\n", ret); -+ return; -+ } -+ -+ buf[0] = 0; -+ -+ cdns_mhdp_infoframe_set(mhdp, 1, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_AUDIO); -+} -+ -+int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) -+{ -+ int ret; -+ -+ if (audio->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { -+ ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, 0); -+ if (ret) { -+ DRM_DEV_ERROR(mhdp->dev, "audio stop failed: %d\n", ret); -+ return ret; -+ } -+ } -+ -+ cdns_mhdp_bus_write(0, mhdp, SPDIF_CTRL_ADDR); -+ -+ /* clearn the audio config and reset */ -+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL); -+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNFG); -+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, AUDIO_SRC_CNTL); -+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL); -+ -+ /* reset smpl2pckt component */ -+ cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL); -+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, SMPL2PKT_CNTL); -+ cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL); -+ -+ /* reset FIFO */ -+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, FIFO_CNTL); -+ cdns_mhdp_bus_write(0, mhdp, FIFO_CNTL); -+ -+ if (audio->format == AFMT_SPDIF_INT) -+ clk_disable_unprepare(mhdp->spdif_clk); -+ -+ return 0; -+} -+EXPORT_SYMBOL(cdns_mhdp_audio_stop); -+ -+int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable) -+{ -+ struct audio_info *audio = &mhdp->audio_info; -+ int ret = true; -+ -+ if (audio->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { -+ ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 4, 1, enable); -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "audio mute failed: %d\n", ret); -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_audio_mute); -+ -+static void cdns_mhdp_audio_config_i2s(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) -+{ -+ int sub_pckt_num = 1, i2s_port_en_val = 0xf, i; -+ int idx = select_N_index(mhdp->mode.clock); -+ u32 val, ncts; -+ -+ if (audio->channels == 2) { -+ if (mhdp->dp.link.num_lanes == 1) -+ sub_pckt_num = 2; -+ else -+ sub_pckt_num = 4; -+ -+ i2s_port_en_val = 1; -+ } else if (audio->channels == 4) { -+ i2s_port_en_val = 3; -+ } -+ -+ cdns_mhdp_bus_write(0x0, mhdp, SPDIF_CTRL_ADDR); -+ -+ cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL); -+ -+ val = MAX_NUM_CH(audio->channels); -+ val |= NUM_OF_I2S_PORTS(audio->channels); -+ val |= AUDIO_TYPE_LPCM; -+ val |= CFG_SUB_PCKT_NUM(sub_pckt_num); -+ cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG); -+ -+ if (audio->sample_width == 16) -+ val = 0; -+ else if (audio->sample_width == 24) -+ val = 1 << 9; -+ else -+ val = 2 << 9; -+ -+ val |= AUDIO_CH_NUM(audio->channels); -+ val |= I2S_DEC_PORT_EN(i2s_port_en_val); -+ val |= TRANS_SMPL_WIDTH_32; -+ cdns_mhdp_bus_write(val, mhdp, AUDIO_SRC_CNFG); -+ -+ for (i = 0; i < (audio->channels + 1) / 2; i++) { -+ if (audio->sample_width == 16) -+ val = (0x02 << 8) | (0x02 << 20); -+ else if (audio->sample_width == 24) -+ val = (0x0b << 8) | (0x0b << 20); -+ -+ val |= ((2 * i) << 4) | ((2 * i + 1) << 16); -+ cdns_mhdp_bus_write(val, mhdp, STTS_BIT_CH(i)); -+ } -+ -+ switch (audio->sample_rate) { -+ case 32000: -+ val = SAMPLING_FREQ(3) | -+ ORIGINAL_SAMP_FREQ(0xc); -+ ncts = N_table_32k[idx]; -+ break; -+ case 44100: -+ val = SAMPLING_FREQ(0) | -+ ORIGINAL_SAMP_FREQ(0xf); -+ ncts = N_table_44k[idx]; -+ break; -+ case 48000: -+ val = SAMPLING_FREQ(2) | -+ ORIGINAL_SAMP_FREQ(0xd); -+ ncts = N_table_48k[idx]; -+ break; -+ case 88200: -+ val = SAMPLING_FREQ(8) | -+ ORIGINAL_SAMP_FREQ(0x7); -+ ncts = N_table_44k[idx] * 2; -+ break; -+ case 96000: -+ val = SAMPLING_FREQ(0xa) | -+ ORIGINAL_SAMP_FREQ(5); -+ ncts = N_table_48k[idx] * 2; -+ break; -+ case 176400: -+ val = SAMPLING_FREQ(0xc) | -+ ORIGINAL_SAMP_FREQ(3); -+ ncts = N_table_44k[idx] * 4; -+ break; -+ case 192000: -+ default: -+ val = SAMPLING_FREQ(0xe) | -+ ORIGINAL_SAMP_FREQ(1); -+ ncts = N_table_48k[idx] * 4; -+ break; -+ } -+ val |= 4; -+ cdns_mhdp_bus_write(val, mhdp, COM_CH_STTS_BITS); -+ -+ if (audio->connector_type == DRM_MODE_CONNECTOR_HDMIA) -+ cdns_mhdp_reg_write(mhdp, CM_I2S_CTRL, ncts | 0x4000000); -+ -+ cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL); -+ cdns_mhdp_bus_write(I2S_DEC_START, mhdp, AUDIO_SRC_CNTL); -+} -+ -+static void cdns_mhdp_audio_config_spdif(struct cdns_mhdp_device *mhdp) -+{ -+ u32 val; -+ -+ cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL); -+ -+ val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4); -+ cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG); -+ cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL); -+ -+ val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS; -+ cdns_mhdp_bus_write(val, mhdp, SPDIF_CTRL_ADDR); -+ -+ clk_prepare_enable(mhdp->spdif_clk); -+ clk_set_rate(mhdp->spdif_clk, CDNS_DP_SPDIF_CLK); -+} -+ -+int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -+ struct audio_info *audio) -+{ -+ int ret; -+ -+ /* reset the spdif clk before config */ -+ if (audio->format == AFMT_SPDIF_INT) { -+ reset_control_assert(mhdp->spdif_rst); -+ reset_control_deassert(mhdp->spdif_rst); -+ } -+ -+ if (audio->connector_type == DRM_MODE_CONNECTOR_DisplayPort) { -+ ret = cdns_mhdp_reg_write(mhdp, CM_LANE_CTRL, LANE_REF_CYC); -+ if (ret) -+ goto err_audio_config; -+ -+ ret = cdns_mhdp_reg_write(mhdp, CM_CTRL, 0); -+ if (ret) -+ goto err_audio_config; -+ } else { -+ /* HDMI Mode */ -+ ret = cdns_mhdp_reg_write(mhdp, CM_CTRL, 8); -+ if (ret) -+ goto err_audio_config; -+ } -+ -+ if (audio->format == AFMT_I2S) -+ cdns_mhdp_audio_config_i2s(mhdp, audio); -+ else if (audio->format == AFMT_SPDIF_INT) -+ cdns_mhdp_audio_config_spdif(mhdp); -+ -+ if (audio->connector_type == DRM_MODE_CONNECTOR_DisplayPort) -+ ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN); -+ -+ if (audio->connector_type == DRM_MODE_CONNECTOR_HDMIA) -+ hdmi_audio_avi_set(mhdp, audio->channels); -+ -+err_audio_config: -+ if (ret) -+ DRM_DEV_ERROR(mhdp->dev, "audio config failed: %d\n", ret); -+ return ret; -+} -+EXPORT_SYMBOL(cdns_mhdp_audio_config); -+ -+static int audio_hw_params(struct device *dev, void *data, -+ struct hdmi_codec_daifmt *daifmt, -+ struct hdmi_codec_params *params) -+{ -+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); -+ struct audio_info audio = { -+ .sample_width = params->sample_width, -+ .sample_rate = params->sample_rate, -+ .channels = params->channels, -+ .connector_type = mhdp->connector.base.connector_type, -+ }; -+ int ret; -+ -+ switch (daifmt->fmt) { -+ case HDMI_I2S: -+ audio.format = AFMT_I2S; -+ break; -+ case HDMI_SPDIF: -+ audio.format = AFMT_SPDIF_EXT; -+ break; -+ default: -+ DRM_DEV_ERROR(dev, "Invalid format %d\n", daifmt->fmt); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ ret = cdns_mhdp_audio_config(mhdp, &audio); -+ if (!ret) -+ mhdp->audio_info = audio; -+ -+out: -+ return ret; -+} -+ -+static void audio_shutdown(struct device *dev, void *data) -+{ -+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); -+ int ret; -+ -+ ret = cdns_mhdp_audio_stop(mhdp, &mhdp->audio_info); -+ if (!ret) -+ mhdp->audio_info.format = AFMT_UNUSED; -+} -+ -+static int audio_digital_mute(struct device *dev, void *data, -+ bool enable) -+{ -+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); -+ int ret; -+ -+ ret = cdns_mhdp_audio_mute(mhdp, enable); -+ -+ return ret; -+} -+ -+static int audio_get_eld(struct device *dev, void *data, -+ u8 *buf, size_t len) -+{ -+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); -+ -+ memcpy(buf, mhdp->connector.base.eld, -+ min(sizeof(mhdp->connector.base.eld), len)); -+ -+ return 0; -+} -+ -+static const struct hdmi_codec_ops audio_codec_ops = { -+ .hw_params = audio_hw_params, -+ .audio_shutdown = audio_shutdown, -+ .digital_mute = audio_digital_mute, -+ .get_eld = audio_get_eld, -+}; -+ -+int cdns_mhdp_register_audio_driver(struct device *dev) -+{ -+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); -+ struct hdmi_codec_pdata codec_data = { -+ .i2s = 1, -+ .spdif = 1, -+ .ops = &audio_codec_ops, -+ .max_i2s_channels = 8, -+ }; -+ -+ mhdp->audio_pdev = platform_device_register_data( -+ dev, HDMI_CODEC_DRV_NAME, 1, -+ &codec_data, sizeof(codec_data)); -+ -+ return PTR_ERR_OR_ZERO(mhdp->audio_pdev); -+} -+ -+void cdns_mhdp_unregister_audio_driver(struct device *dev) -+{ -+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); -+ -+ platform_device_unregister(mhdp->audio_pdev); -+} ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -@@ -937,189 +937,6 @@ err_config_video: - } - EXPORT_SYMBOL(cdns_mhdp_config_video); - --int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio) --{ -- int ret; -- -- ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, 0); -- if (ret) { -- DRM_DEV_ERROR(mhdp->dev, "audio stop failed: %d\n", ret); -- return ret; -- } -- -- cdns_mhdp_bus_write(0, mhdp, SPDIF_CTRL_ADDR); -- -- /* clearn the audio config and reset */ -- cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL); -- cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNFG); -- cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, AUDIO_SRC_CNTL); -- cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL); -- -- /* reset smpl2pckt component */ -- cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL); -- cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, SMPL2PKT_CNTL); -- cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL); -- -- /* reset FIFO */ -- cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, FIFO_CNTL); -- cdns_mhdp_bus_write(0, mhdp, FIFO_CNTL); -- -- if (audio->format == AFMT_SPDIF_INT) -- clk_disable_unprepare(mhdp->spdif_clk); -- -- return 0; --} --EXPORT_SYMBOL(cdns_mhdp_audio_stop); -- --int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable) --{ -- int ret; -- -- ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 4, 1, enable); -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "audio mute failed: %d\n", ret); -- -- return ret; --} --EXPORT_SYMBOL(cdns_mhdp_audio_mute); -- --static void cdns_mhdp_audio_config_i2s(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio) --{ -- int sub_pckt_num = 1, i2s_port_en_val = 0xf, i; -- u32 val; -- -- if (audio->channels == 2) { -- if (mhdp->dp.link.num_lanes == 1) -- sub_pckt_num = 2; -- else -- sub_pckt_num = 4; -- -- i2s_port_en_val = 1; -- } else if (audio->channels == 4) { -- i2s_port_en_val = 3; -- } -- -- cdns_mhdp_bus_write(0x0, mhdp, SPDIF_CTRL_ADDR); -- -- cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL); -- -- val = MAX_NUM_CH(audio->channels); -- val |= NUM_OF_I2S_PORTS(audio->channels); -- val |= AUDIO_TYPE_LPCM; -- val |= CFG_SUB_PCKT_NUM(sub_pckt_num); -- cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG); -- -- if (audio->sample_width == 16) -- val = 0; -- else if (audio->sample_width == 24) -- val = 1 << 9; -- else -- val = 2 << 9; -- -- val |= AUDIO_CH_NUM(audio->channels); -- val |= I2S_DEC_PORT_EN(i2s_port_en_val); -- val |= TRANS_SMPL_WIDTH_32; -- cdns_mhdp_bus_write(val, mhdp, AUDIO_SRC_CNFG); -- -- for (i = 0; i < (audio->channels + 1) / 2; i++) { -- if (audio->sample_width == 16) -- val = (0x02 << 8) | (0x02 << 20); -- else if (audio->sample_width == 24) -- val = (0x0b << 8) | (0x0b << 20); -- -- val |= ((2 * i) << 4) | ((2 * i + 1) << 16); -- cdns_mhdp_bus_write(val, mhdp, STTS_BIT_CH(i)); -- } -- -- switch (audio->sample_rate) { -- case 32000: -- val = SAMPLING_FREQ(3) | -- ORIGINAL_SAMP_FREQ(0xc); -- break; -- case 44100: -- val = SAMPLING_FREQ(0) | -- ORIGINAL_SAMP_FREQ(0xf); -- break; -- case 48000: -- val = SAMPLING_FREQ(2) | -- ORIGINAL_SAMP_FREQ(0xd); -- break; -- case 88200: -- val = SAMPLING_FREQ(8) | -- ORIGINAL_SAMP_FREQ(0x7); -- break; -- case 96000: -- val = SAMPLING_FREQ(0xa) | -- ORIGINAL_SAMP_FREQ(5); -- break; -- case 176400: -- val = SAMPLING_FREQ(0xc) | -- ORIGINAL_SAMP_FREQ(3); -- break; -- case 192000: -- val = SAMPLING_FREQ(0xe) | -- ORIGINAL_SAMP_FREQ(1); -- break; -- } -- val |= 4; -- cdns_mhdp_bus_write(val, mhdp, COM_CH_STTS_BITS); -- -- cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL); -- cdns_mhdp_bus_write(I2S_DEC_START, mhdp, AUDIO_SRC_CNTL); --} -- --static void cdns_mhdp_audio_config_spdif(struct cdns_mhdp_device *mhdp) --{ -- u32 val; -- -- cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL); -- -- val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4); -- cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG); -- cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL); -- -- val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS; -- cdns_mhdp_bus_write(val, mhdp, SPDIF_CTRL_ADDR); -- -- clk_prepare_enable(mhdp->spdif_clk); -- clk_set_rate(mhdp->spdif_clk, CDNS_DP_SPDIF_CLK); --} -- --int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, -- struct audio_info *audio) --{ -- int ret; -- -- /* reset the spdif clk before config */ -- if (audio->format == AFMT_SPDIF_INT) { -- reset_control_assert(mhdp->spdif_rst); -- reset_control_deassert(mhdp->spdif_rst); -- } -- -- ret = cdns_mhdp_reg_write(mhdp, CM_LANE_CTRL, LANE_REF_CYC); -- if (ret) -- goto err_audio_config; -- -- ret = cdns_mhdp_reg_write(mhdp, CM_CTRL, 0); -- if (ret) -- goto err_audio_config; -- -- if (audio->format == AFMT_I2S) -- cdns_mhdp_audio_config_i2s(mhdp, audio); -- else if (audio->format == AFMT_SPDIF_INT) -- cdns_mhdp_audio_config_spdif(mhdp); -- -- ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN); -- --err_audio_config: -- if (ret) -- DRM_DEV_ERROR(mhdp->dev, "audio config failed: %d\n", ret); -- return ret; --} --EXPORT_SYMBOL(cdns_mhdp_audio_config); -- - int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, - u8 nlanes, u16 udelay, u8 *lanes_data, u8 *dpcd) - { ---- a/drivers/gpu/drm/imx/Kconfig -+++ b/drivers/gpu/drm/imx/Kconfig -@@ -45,6 +45,7 @@ config DRM_IMX_CDNS_MHDP - select DRM_CDNS_MHDP - select DRM_CDNS_DP - select DRM_CDNS_HDMI -+ select DRM_CDNS_AUDIO - depends on DRM_IMX - help - Choose this if you want to use HDMI on i.MX8. ---- a/include/drm/bridge/cdns-mhdp-common.h -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -548,6 +548,7 @@ struct audio_info { - int sample_rate; - int channels; - int sample_width; -+ int connector_type; - }; - - enum vic_pxl_encoding_format { -@@ -670,11 +671,16 @@ int cdns_mhdp_get_edid_block(void *mhdp, - int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp); - int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active); - int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp); -+ -+/* Audio */ - int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp, - struct audio_info *audio); - int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable); - int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp, - struct audio_info *audio); -+int cdns_mhdp_register_audio_driver(struct device *dev); -+void cdns_mhdp_unregister_audio_driver(struct device *dev); -+ - int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr); - int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u32 addr, u32 val); - int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr, diff --git a/target/linux/layerscape/patches-5.4/805-display-0008-drm-bridge-cadence-Add-CEC-driver-for-cdns-mhdp-hdmi.patch b/target/linux/layerscape/patches-5.4/805-display-0008-drm-bridge-cadence-Add-CEC-driver-for-cdns-mhdp-hdmi.patch deleted file mode 100644 index 742928e71a..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0008-drm-bridge-cadence-Add-CEC-driver-for-cdns-mhdp-hdmi.patch +++ /dev/null @@ -1,474 +0,0 @@ -From ed9e7a6b3346b186a7bd22d9b62072e55ff7b9c5 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Mon, 2 Sep 2019 14:57:05 +0800 -Subject: [PATCH] drm: bridge: cadence: Add CEC driver for cdns mhdp hdmi - -Add cec driver for cdns mhdp hdmi. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/Kconfig | 3 + - drivers/gpu/drm/bridge/cadence/Makefile | 1 + - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 0 - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 9 + - drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c | 347 ++++++++++++++++++++++ - drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 0 - drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c | 0 - include/drm/bridge/cdns-mhdp-common.h | 24 +- - 8 files changed, 382 insertions(+), 2 deletions(-) - mode change 100755 => 100644 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c - mode change 100755 => 100644 drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c - create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c - mode change 100755 => 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c - mode change 100755 => 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c - ---- a/drivers/gpu/drm/bridge/cadence/Kconfig -+++ b/drivers/gpu/drm/bridge/cadence/Kconfig -@@ -14,3 +14,6 @@ config DRM_CDNS_DP - - config DRM_CDNS_AUDIO - tristate "Cadence MHDP Audio driver" -+ -+config DRM_CDNS_HDMI_CEC -+ tristate "Cadence MHDP HDMI CEC driver" ---- a/drivers/gpu/drm/bridge/cadence/Makefile -+++ b/drivers/gpu/drm/bridge/cadence/Makefile -@@ -2,3 +2,4 @@ obj-$(CONFIG_DRM_CDNS_MHDP) += cdns-mhdp - obj-$(CONFIG_DRM_CDNS_HDMI) += cdns-hdmi-core.o - obj-$(CONFIG_DRM_CDNS_DP) += cdns-dp-core.o - obj-$(CONFIG_DRM_CDNS_AUDIO) += cdns-mhdp-audio.o -+obj-$(CONFIG_DRM_CDNS_HDMI_CEC) += cdns-mhdp-cec.o ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -515,6 +515,11 @@ __cdns_hdmi_probe(struct platform_device - /* register audio driver */ - cdns_mhdp_register_audio_driver(dev); - -+ /* register cec driver */ -+#ifdef CONFIG_DRM_CDNS_HDMI_CEC -+ cdns_mhdp_register_cec_driver(dev); -+#endif -+ - return hdmi; - - err_out: -@@ -524,6 +529,10 @@ err_out: - - static void __cdns_hdmi_remove(struct cdns_mhdp_device *mhdp) - { -+ /* unregister cec driver */ -+#ifdef CONFIG_DRM_CDNS_HDMI_CEC -+ cdns_mhdp_unregister_cec_driver(mhdp->dev); -+#endif - cdns_mhdp_unregister_audio_driver(mhdp->dev); - } - ---- /dev/null -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c -@@ -0,0 +1,347 @@ -+/* -+ * Copyright 2019 NXP -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2 -+ * of the License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#define CEC_NAME "cdns-mhdp-cec" -+ -+#define REG_ADDR_OFF 4 -+#define MAX_LA_IDX 4 -+#define MAX_LA_VAL 15 -+ -+/* regsiter define */ -+#define TX_MSG_HEADER 0x33800 -+#define TX_MSG_LENGTH 0x33840 -+#define TX_MSG_CMD 0x33844 -+#define RX_MSG_CMD 0x33850 -+#define RX_CLEAR_BUF 0x33854 -+#define LOGICAL_ADDRESS_LA0 0x33858 -+ -+#define CLK_DIV_MSB 0x3386c -+#define CLK_DIV_LSB 0x33870 -+#define RX_MSG_DATA1 0x33900 -+#define RX_MSG_LENGTH 0x33940 -+#define RX_MSG_STATUS 0x33944 -+#define NUM_OF_MSG_RX_BUF 0x33948 -+#define TX_MSG_STATUS 0x3394c -+#define DB_L_TIMER 0x33980 -+ -+/** -+ * CEC Transceiver operation. -+ */ -+enum { -+ CEC_TX_STOP, -+ CEC_TX_TRANSMIT, -+ CEC_TX_ABORT, -+ CEC_TX_ABORT_AND_TRANSMIT -+}; -+ -+/** -+ * CEC Transceiver status. -+ */ -+enum { -+ CEC_STS_IDLE, -+ CEC_STS_BUSY, -+ CEC_STS_SUCCESS, -+ CEC_STS_ERROR -+}; -+ -+/** -+ * CEC Receiver operation. -+ */ -+enum { -+ CEC_RX_STOP, -+ CEC_RX_READ, -+ CEC_RX_DISABLE, -+ CEC_RX_ABORT_AND_CLR_FIFO -+}; -+/** -+ * Maximum number of Messages in the RX Buffers. -+ */ -+#define CEC_MAX_RX_MSGS 2 -+ -+static u32 mhdp_cec_read(struct cdns_mhdp_cec *cec, u32 offset) -+{ -+ struct cdns_mhdp_device *mhdp = -+ container_of(cec, struct cdns_mhdp_device, hdmi.cec); -+ return cdns_mhdp_bus_read(mhdp, offset); -+} -+ -+static void mhdp_cec_write(struct cdns_mhdp_cec *cec, u32 offset, u32 val) -+{ -+ struct cdns_mhdp_device *mhdp = -+ container_of(cec, struct cdns_mhdp_device, hdmi.cec); -+ cdns_mhdp_bus_write(val, mhdp, offset); -+} -+ -+static void mhdp_cec_clear_rx_buffer(struct cdns_mhdp_cec *cec) -+{ -+ mhdp_cec_write(cec, RX_CLEAR_BUF, 1); -+ mhdp_cec_write(cec, RX_CLEAR_BUF, 0); -+} -+ -+static void mhdp_cec_set_divider(struct cdns_mhdp_cec *cec) -+{ -+ struct cdns_mhdp_device *mhdp = -+ container_of(cec, struct cdns_mhdp_device, hdmi.cec); -+ u32 clk_div; -+ -+ /* Set clock divider */ -+ clk_div = cdns_mhdp_get_fw_clk(mhdp) * 10; -+ -+ mhdp_cec_write(cec, CLK_DIV_MSB, -+ (clk_div >> 8) & 0xFF); -+ mhdp_cec_write(cec, CLK_DIV_LSB, clk_div & 0xFF); -+} -+ -+static u32 mhdp_cec_read_message(struct cdns_mhdp_cec *cec) -+{ -+ struct cec_msg *msg = &cec->msg; -+ int len; -+ int i; -+ -+ mhdp_cec_write(cec, RX_MSG_CMD, CEC_RX_READ); -+ -+ len = mhdp_cec_read(cec, RX_MSG_LENGTH); -+ msg->len = len + 1; -+ dev_dbg(cec->dev, "RX MSG len =%d\n", len); -+ -+ /* Read RX MSG bytes */ -+ for (i = 0; i < msg->len; ++i) { -+ msg->msg[i] = (u8) mhdp_cec_read(cec, RX_MSG_DATA1 + (i * REG_ADDR_OFF)); -+ dev_dbg(cec->dev, "RX MSG[%d]=0x%x\n", i, msg->msg[i]); -+ } -+ -+ mhdp_cec_write(cec, RX_MSG_CMD, CEC_RX_STOP); -+ -+ return true; -+} -+ -+static u32 mhdp_cec_write_message(struct cdns_mhdp_cec *cec, struct cec_msg *msg) -+{ -+ u8 i; -+ -+ mhdp_cec_write(cec, TX_MSG_CMD, CEC_TX_STOP); -+ -+ if (msg->len > CEC_MAX_MSG_SIZE) { -+ dev_err(cec->dev, "Invalid MSG size!\n"); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < msg->len; ++i) -+ printk("msg[%d]=0x%x\n",i, msg->msg[i]); -+ -+ /* Write Message to register */ -+ for (i = 0; i < msg->len; ++i) { -+ mhdp_cec_write(cec, TX_MSG_HEADER + (i * REG_ADDR_OFF), -+ msg->msg[i]); -+ } -+ /* Write Message Length (payload + opcode) */ -+ mhdp_cec_write(cec, TX_MSG_LENGTH, msg->len - 1); -+ -+ mhdp_cec_write(cec, TX_MSG_CMD, CEC_TX_TRANSMIT); -+ -+ return true; -+} -+ -+//static void cec_abort_tx_transfer(struct cdns_mhdp_cec *cec) -+//{ -+// cec_write(cec, TX_MSG_CMD, CEC_TX_ABORT); -+// cec_write(cec, TX_MSG_CMD, CEC_TX_STOP); -+//} -+ -+static int mhdp_cec_set_logical_addr(struct cdns_mhdp_cec *cec, u32 la) -+{ -+ u8 i; -+ u8 la_reg; -+ -+ if (la >= MAX_LA_VAL) { -+ dev_err(cec->dev, "Error logical Addr\n"); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < MAX_LA_IDX; ++i) { -+ la_reg = -+ mhdp_cec_read(cec, LOGICAL_ADDRESS_LA0 + (i * REG_ADDR_OFF)); -+ -+ if (la_reg & 0x10) -+ continue; -+ -+ if ((la_reg & 0xF) == la) { -+ dev_warn(cec->dev, "Warning. LA already in use.\n"); -+ return true; -+ } -+ -+ la = (la & 0xF) | (1 << 4); -+ -+ mhdp_cec_write(cec, LOGICAL_ADDRESS_LA0 + (i * REG_ADDR_OFF), la); -+ return true; -+ } -+ -+ dev_warn(cec->dev, "All LA in use\n"); -+ -+ return false; -+} -+ -+static int mhdp_cec_poll_worker(void *_cec) -+{ -+ struct cdns_mhdp_cec *cec = (struct cdns_mhdp_cec *)_cec; -+ int num_rx_msgs, i; -+ int sts; -+ -+ set_freezable(); -+ -+ for (;;) { -+ if (kthread_freezable_should_stop(NULL)) -+ break; -+ -+ /* Check TX State */ -+ sts = mhdp_cec_read(cec, TX_MSG_STATUS); -+ switch (sts) { -+ case CEC_STS_SUCCESS: -+ cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, -+ 0); -+ mhdp_cec_write(cec, TX_MSG_CMD, CEC_TX_STOP); -+ break; -+ case CEC_STS_ERROR: -+ mhdp_cec_write(cec, TX_MSG_CMD, CEC_TX_STOP); -+ cec_transmit_done(cec->adap, -+ CEC_TX_STATUS_MAX_RETRIES | -+ CEC_TX_STATUS_NACK, 0, 1, 0, 0); -+ break; -+ case CEC_STS_BUSY: -+ default: -+ break; -+ } -+ -+ /* Check RX State */ -+ sts = mhdp_cec_read(cec, RX_MSG_STATUS); -+ num_rx_msgs = mhdp_cec_read(cec, NUM_OF_MSG_RX_BUF); -+ switch (sts) { -+ case CEC_STS_SUCCESS: -+ if (num_rx_msgs == 0xf) -+ num_rx_msgs = CEC_MAX_RX_MSGS; -+ -+ if (num_rx_msgs > CEC_MAX_RX_MSGS) { -+ dev_err(cec->dev, "Error rx msg num %d\n", -+ num_rx_msgs); -+ mhdp_cec_clear_rx_buffer(cec); -+ break; -+ } -+ -+ /* Rx FIFO Depth 2 RX MSG */ -+ for (i = 0; i < num_rx_msgs; i++) { -+ mhdp_cec_read_message(cec); -+ cec->msg.rx_status = CEC_RX_STATUS_OK; -+ cec_received_msg(cec->adap, &cec->msg); -+ } -+ break; -+ default: -+ break; -+ } -+ -+ if (!kthread_should_stop()) -+ schedule_timeout_idle(20); -+ } -+ -+ return 0; -+} -+ -+static int mhdp_cec_adap_enable(struct cec_adapter *adap, bool enable) -+{ -+ struct cdns_mhdp_cec *cec = adap->priv; -+ -+ if (enable) { -+ mhdp_cec_write(cec, DB_L_TIMER, 0x10); -+ mhdp_cec_set_divider(cec); -+ } else -+ mhdp_cec_set_divider(cec); -+ -+ return 0; -+} -+ -+static int mhdp_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) -+{ -+ struct cdns_mhdp_cec *cec = adap->priv; -+ -+ return mhdp_cec_set_logical_addr(cec, addr); -+} -+ -+static int mhdp_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, -+ u32 signal_free_time, struct cec_msg *msg) -+{ -+ struct cdns_mhdp_cec *cec = adap->priv; -+ -+ mhdp_cec_write_message(cec, msg); -+ -+ return 0; -+} -+ -+static const struct cec_adap_ops cdns_mhdp_cec_adap_ops = { -+ .adap_enable = mhdp_cec_adap_enable, -+ .adap_log_addr = mhdp_cec_adap_log_addr, -+ .adap_transmit = mhdp_cec_adap_transmit, -+}; -+ -+int cdns_mhdp_register_cec_driver(struct device *dev) -+{ -+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); -+ struct cdns_mhdp_cec *cec = &mhdp->hdmi.cec; -+ int ret; -+ -+ cec->adap = cec_allocate_adapter(&cdns_mhdp_cec_adap_ops, cec, -+ CEC_NAME, -+ CEC_CAP_PHYS_ADDR | CEC_CAP_LOG_ADDRS | -+ CEC_CAP_TRANSMIT | CEC_CAP_PASSTHROUGH -+ | CEC_CAP_RC, 1); -+ ret = PTR_ERR_OR_ZERO(cec->adap); -+ if (ret) -+ return ret; -+ ret = cec_register_adapter(cec->adap, dev); -+ if (ret) { -+ cec_delete_adapter(cec->adap); -+ return ret; -+ } -+ -+ cec->dev = dev; -+ -+ cec->cec_worker = kthread_create(mhdp_cec_poll_worker, cec, "cdns-mhdp-cec"); -+ if (IS_ERR(cec->cec_worker)) -+ dev_err(cec->dev, "failed create hdp cec thread\n"); -+ -+ wake_up_process(cec->cec_worker); -+ -+ dev_dbg(dev, "CEC successfuly probed\n"); -+ return 0; -+} -+ -+int cdns_mhdp_unregister_cec_driver(struct device *dev) -+{ -+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev); -+ struct cdns_mhdp_cec *cec = &mhdp->hdmi.cec; -+ -+ if (cec->cec_worker) { -+ kthread_stop(cec->cec_worker); -+ cec->cec_worker = NULL; -+ } -+ cec_unregister_adapter(cec->adap); -+ return 0; -+} -+ -+MODULE_AUTHOR("Sandor.Yu@NXP.com"); -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("NXP CDNS MHDP CEC driver"); ---- a/include/drm/bridge/cdns-mhdp-common.h -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -21,7 +21,7 @@ - #include - #include - #include -- -+#include - #include - - #define ADDR_IMEM 0x10000 -@@ -605,6 +605,17 @@ struct cdns_mhdp_connector { - struct cdns_mhdp_bridge *bridge; - }; - -+#ifdef CONFIG_DRM_CDNS_HDMI_CEC -+struct cdns_mhdp_cec { -+ struct cec_adapter *adap; -+ struct device *dev; -+ struct mutex lock; -+ -+ struct cec_msg msg; -+ struct task_struct *cec_worker; -+}; -+#endif -+ - struct cdns_mhdp_device { - void __iomem *regs; - -@@ -633,7 +644,7 @@ struct cdns_mhdp_device { - bool plugged; - - union { -- struct cdn_dp_data { -+ struct _dp_data { - struct drm_dp_link link; - struct drm_dp_aux aux; - struct cdns_mhdp_host host; -@@ -645,6 +656,9 @@ struct cdns_mhdp_device { - u32 num_lanes; - } dp; - struct _hdmi_data { -+#ifdef CONFIG_DRM_CDNS_HDMI_CEC -+ struct cdns_mhdp_cec cec; -+#endif - u32 char_rate; - u32 hdmi_type; - } hdmi; -@@ -713,4 +727,10 @@ int cdns_hdmi_disable_gcp(struct cdns_mh - int cdns_hdmi_enable_gcp(struct cdns_mhdp_device *mhdp); - - bool cdns_mhdp_check_alive(struct cdns_mhdp_device *mhdp); -+/* CEC */ -+#ifdef CONFIG_DRM_CDNS_HDMI_CEC -+int cdns_mhdp_register_cec_driver(struct device *dev); -+int cdns_mhdp_unregister_cec_driver(struct device *dev); -+#endif -+ - #endif /* CDNS_MHDP_COMMON_H_ */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0009-drm-rockchip-Fix-build-failed-issue.patch b/target/linux/layerscape/patches-5.4/805-display-0009-drm-rockchip-Fix-build-failed-issue.patch deleted file mode 100644 index 6f44ce2219..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0009-drm-rockchip-Fix-build-failed-issue.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 9ab73f9efe983f2f9b6887150a2e7a48d7a57ded Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Mon, 2 Sep 2019 15:58:34 +0800 -Subject: [PATCH] drm: rockchip: Fix build failed issue - -Macro variable AFMT_SPDIF have renamed to AFMT_SPDIF_INT in headfile. -use the correct variable to fix build issue. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/rockchip/cdn-dp-core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/gpu/drm/rockchip/cdn-dp-core.c -+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c -@@ -798,7 +798,7 @@ static int cdn_dp_audio_hw_params(struct - audio.format = AFMT_I2S; - break; - case HDMI_SPDIF: -- audio.format = AFMT_SPDIF; -+ audio.format = AFMT_SPDIF_INT; - break; - default: - DRM_DEV_ERROR(dev, "Invalid format %d\n", daifmt->fmt); diff --git a/target/linux/layerscape/patches-5.4/805-display-0010-drm-bridge-cadence-move-struct-imx_mhdp_device-to-dr.patch b/target/linux/layerscape/patches-5.4/805-display-0010-drm-bridge-cadence-move-struct-imx_mhdp_device-to-dr.patch deleted file mode 100644 index 74e5a58364..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0010-drm-bridge-cadence-move-struct-imx_mhdp_device-to-dr.patch +++ /dev/null @@ -1,1096 +0,0 @@ -From fe1824851dd6f7d3ee6d5411edba4102dacea873 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Wed, 11 Sep 2019 17:16:47 +0800 -Subject: [PATCH] drm: bridge: cadence: move struct imx_mhdp_device to drm/imx - -move struct imx_mhdp_device to drm/imx folder. -change the base address name from regs to regs_base. -add mhdp bus access function. -uniform variable name. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 188 ++++++++++----------- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 190 ++++++++++------------ - drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c | 1 - - drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c | 2 +- - drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 43 ++--- - drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c | 1 - - include/drm/bridge/cdns-mhdp-common.h | 67 +++++++- - include/drm/bridge/cdns-mhdp-imx.h | 121 -------------- - 8 files changed, 258 insertions(+), 355 deletions(-) - delete mode 100644 include/drm/bridge/cdns-mhdp-imx.h - ---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -9,8 +9,7 @@ - * (at your option) any later version. - * - */ -- --#include -+#include - #include - #include - #include -@@ -25,8 +24,6 @@ - #include - #include - --#define aux_to_hdp(x) container_of(x, struct imx_mhdp_device, aux) -- - /* - * This function only implements native DPDC reads and writes - */ -@@ -111,24 +108,24 @@ static void dp_pixel_clk_reset(struct cd - cdns_mhdp_reg_write(mhdp, SOURCE_HDTX_CAR, val); - } - --static void cdns_dp_mode_set(struct imx_mhdp_device *dp, -+static void cdns_dp_mode_set(struct cdns_mhdp_device *mhdp, - const struct drm_display_mode *mode) - { - struct drm_dp_link link; -- struct cdns_mhdp_device *mhdp = &dp->mhdp; - u32 lane_mapping = mhdp->lane_mapping; - int ret; - char linkid[6]; - - memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode)); - -- dp->dual_mode = video_is_dual_mode(mode); -+ //Sandor TODO -+// mhdp->dual_mode = video_is_dual_mode(mode); - - dp_pixel_clk_reset(mhdp); - -- hdp_plat_call(dp, pclock_change); -+ cdns_mhdp_plat_call(mhdp, pclk_rate); - -- hdp_plat_call(dp, phy_init); -+ cdns_mhdp_plat_call(mhdp, phy_set); - - ret = drm_dp_downstream_id(&mhdp->dp.aux, linkid); - if (ret < 0) { -@@ -168,7 +165,7 @@ static void cdns_dp_mode_set(struct imx_ - /* initialize phy if lanes or link rate differnt */ - if (mhdp->dp.link.num_lanes != mhdp->dp.num_lanes || - mhdp->dp.link.rate != mhdp->dp.link_rate) -- hdp_plat_call(dp, phy_init); -+ cdns_mhdp_plat_call(mhdp, phy_set); - - /* Video off */ - ret = cdns_mhdp_set_video_status(mhdp, CONTROL_VIDEO_IDLE); -@@ -215,11 +212,11 @@ static void cdns_dp_mode_set(struct imx_ - static enum drm_connector_status - cdns_dp_connector_detect(struct drm_connector *connector, bool force) - { -- struct imx_mhdp_device *dp = container_of(connector, -- struct imx_mhdp_device, mhdp.connector.base); -+ struct cdns_mhdp_device *mhdp = container_of(connector, -+ struct cdns_mhdp_device, connector.base); - u8 hpd = 0xf; - -- hpd = cdns_mhdp_read_hpd(&dp->mhdp); -+ hpd = cdns_mhdp_read_hpd(mhdp); - if (hpd == 1) - /* Cable Connected */ - return connector_status_connected; -@@ -235,15 +232,15 @@ cdns_dp_connector_detect(struct drm_conn - - static int cdns_dp_connector_get_modes(struct drm_connector *connector) - { -- struct imx_mhdp_device *dp = container_of(connector, -- struct imx_mhdp_device, mhdp.connector.base); -+ struct cdns_mhdp_device *mhdp = container_of(connector, -+ struct cdns_mhdp_device, connector.base); - int num_modes = 0; - struct edid *edid; - -- edid = drm_do_get_edid(&dp->mhdp.connector.base, -- cdns_mhdp_get_edid_block, &dp->mhdp); -+ edid = drm_do_get_edid(&mhdp->connector.base, -+ cdns_mhdp_get_edid_block, mhdp); - if (edid) { -- dev_info(dp->mhdp.dev, "%x,%x,%x,%x,%x,%x,%x,%x\n", -+ dev_info(mhdp->dev, "%x,%x,%x,%x,%x,%x,%x,%x\n", - edid->header[0], edid->header[1], - edid->header[2], edid->header[3], - edid->header[4], edid->header[5], -@@ -273,9 +270,9 @@ static const struct drm_connector_helper - - static int cdns_dp_bridge_attach(struct drm_bridge *bridge) - { -- struct imx_mhdp_device *dp = bridge->driver_private; -+ struct cdns_mhdp_device *mhdp = bridge->driver_private; - struct drm_encoder *encoder = bridge->encoder; -- struct drm_connector *connector = &dp->mhdp.connector.base; -+ struct drm_connector *connector = &mhdp->connector.base; - - connector->interlace_allowed = 1; - connector->polled = DRM_CONNECTOR_POLL_HPD; -@@ -319,9 +316,9 @@ static void cdns_dp_bridge_mode_set(stru - const struct drm_display_mode *orig_mode, - const struct drm_display_mode *mode) - { -- struct imx_mhdp_device *dp = bridge->driver_private; -- struct drm_display_info *display_info = &dp->mhdp.connector.base.display_info; -- struct video_info *video = &dp->mhdp.video_info; -+ struct cdns_mhdp_device *mhdp = bridge->driver_private; -+ struct drm_display_info *display_info = &mhdp->connector.base.display_info; -+ struct video_info *video = &mhdp->video_info; - - switch (display_info->bpc) { - case 10: -@@ -341,11 +338,11 @@ static void cdns_dp_bridge_mode_set(stru - - DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay, mode->vdisplay, mode->clock); - -- mutex_lock(&dp->lock); -+ mutex_lock(&mhdp->lock); - -- cdns_dp_mode_set(dp, mode); -+ cdns_dp_mode_set(mhdp, mode); - -- mutex_unlock(&dp->lock); -+ mutex_unlock(&mhdp->lock); - } - - static void cdn_hdp_bridge_enable(struct drm_bridge *bridge) -@@ -354,8 +351,7 @@ static void cdn_hdp_bridge_enable(struct - - static void cdn_hdp_bridge_disable(struct drm_bridge *bridge) - { -- struct imx_mhdp_device *dp = bridge->driver_private; -- struct cdns_mhdp_device *mhdp = &dp->mhdp; -+ struct cdns_mhdp_device *mhdp = bridge->driver_private; - - cdns_mhdp_set_video_status(mhdp, CONTROL_VIDEO_IDLE); - drm_dp_link_power_down(&mhdp->dp.aux, &mhdp->dp.link); -@@ -371,29 +367,29 @@ static const struct drm_bridge_funcs cdn - - static void hotplug_work_func(struct work_struct *work) - { -- struct imx_mhdp_device *dp = container_of(work, -- struct imx_mhdp_device, hotplug_work.work); -- struct drm_connector *connector = &dp->mhdp.connector.base; -+ struct cdns_mhdp_device *mhdp = container_of(work, -+ struct cdns_mhdp_device, hotplug_work.work); -+ struct drm_connector *connector = &mhdp->connector.base; - - drm_helper_hpd_irq_event(connector->dev); - - if (connector->status == connector_status_connected) { - DRM_INFO("HDMI/DP Cable Plug In\n"); -- enable_irq(dp->irq[IRQ_OUT]); -+ enable_irq(mhdp->irq[IRQ_OUT]); - } else if (connector->status == connector_status_disconnected) { - /* Cable Disconnedted */ - DRM_INFO("HDMI/DP Cable Plug Out\n"); -- enable_irq(dp->irq[IRQ_IN]); -+ enable_irq(mhdp->irq[IRQ_IN]); - } - } - - static irqreturn_t cdns_dp_irq_thread(int irq, void *data) - { -- struct imx_mhdp_device *dp = data; -+ struct cdns_mhdp_device *mhdp = data; - - disable_irq_nosync(irq); - -- mod_delayed_work(system_wq, &dp->hotplug_work, -+ mod_delayed_work(system_wq, &mhdp->hotplug_work, - msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS)); - - return IRQ_HANDLED; -@@ -430,111 +426,92 @@ static void cdns_dp_parse_dt(struct cdns - mhdp->dp.link.rate= mhdp->dp.link_rate; - } - --static struct imx_mhdp_device * --__cdns_dp_probe(struct platform_device *pdev, -- const struct cdn_plat_data *plat_data) -+static int __cdns_dp_probe(struct platform_device *pdev, -+ struct cdns_mhdp_device *mhdp) - { - struct device *dev = &pdev->dev; -- struct imx_mhdp_device *dp; - struct resource *iores = NULL; - int ret; - -- dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); -- if (!dp) -- return ERR_PTR(-ENOMEM); -- -- dp->plat_data = plat_data; -- dp->mhdp.dev = dev; -- -- mutex_init(&dp->lock); -- mutex_init(&dp->audio_mutex); -- spin_lock_init(&dp->audio_lock); -+ mutex_init(&mhdp->lock); - -- INIT_DELAYED_WORK(&dp->hotplug_work, hotplug_work_func); -+ INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func); - - iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- dp->mhdp.regs = devm_ioremap(dev, iores->start, resource_size(iores)); -- if (IS_ERR(dp->mhdp.regs)) { -- ret = PTR_ERR(dp->mhdp.regs); -- goto err_out; -- } -+ mhdp->regs_base = devm_ioremap(dev, iores->start, resource_size(iores)); -+ if (IS_ERR(mhdp->regs_base)) -+ return -ENOMEM; - --#if 0 - iores = platform_get_resource(pdev, IORESOURCE_MEM, 1); -- dp->regs_ss = devm_ioremap(dev, iores->start, resource_size(iores)); -- if (IS_ERR(dp->regs_ss)) { -- ret = PTR_ERR(dp->regs_ss); -- goto err_out; -- } --#endif -+ mhdp->regs_sec = devm_ioremap(dev, iores->start, resource_size(iores)); -+ if (IS_ERR(mhdp->regs_sec)) -+ return -ENOMEM; - -- dp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in"); -- if (dp->irq[IRQ_IN] < 0) -+ mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in"); -+ if (mhdp->irq[IRQ_IN] < 0) - dev_info(dev, "No plug_in irq number\n"); - -- dp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out"); -- if (dp->irq[IRQ_OUT] < 0) -+ mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out"); -+ if (mhdp->irq[IRQ_OUT] < 0) - dev_info(dev, "No plug_out irq number\n"); - -- cdns_dp_parse_dt(&dp->mhdp); -+ cdns_dp_parse_dt(mhdp); - -- dp->dual_mode = false; -- hdp_plat_call(dp, fw_init); -+// mhdp->dual_mode = false; -+ cdns_mhdp_plat_call(mhdp, firmware_init); - - /* DP FW alive check */ -- ret = cdns_mhdp_check_alive(&dp->mhdp); -+ ret = cdns_mhdp_check_alive(mhdp); - if (ret == false) { - DRM_ERROR("NO dp FW running\n"); -- return ERR_PTR(-ENXIO); -+ return -ENXIO; - } - - /* DP PHY init before AUX init */ -- hdp_plat_call(dp, phy_init); -+ cdns_mhdp_plat_call(mhdp, phy_set); - - /* Enable Hotplug Detect IRQ thread */ -- irq_set_status_flags(dp->irq[IRQ_IN], IRQ_NOAUTOEN); -- ret = devm_request_threaded_irq(dev, dp->irq[IRQ_IN], -+ irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN], - NULL, cdns_dp_irq_thread, - IRQF_ONESHOT, dev_name(dev), -- dp); -+ mhdp); - if (ret) { - dev_err(dev, "can't claim irq %d\n", -- dp->irq[IRQ_IN]); -- goto err_out; -+ mhdp->irq[IRQ_IN]); -+ return -EINVAL; - } - -- irq_set_status_flags(dp->irq[IRQ_OUT], IRQ_NOAUTOEN); -- ret = devm_request_threaded_irq(dev, dp->irq[IRQ_OUT], -+ irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT], - NULL, cdns_dp_irq_thread, - IRQF_ONESHOT, dev_name(dev), -- dp); -+ mhdp); - if (ret) { - dev_err(dev, "can't claim irq %d\n", -- dp->irq[IRQ_OUT]); -- goto err_out; -+ mhdp->irq[IRQ_OUT]); -+ return -EINVAL; - } -- if (cdns_mhdp_read_hpd(&dp->mhdp)) -- enable_irq(dp->irq[IRQ_OUT]); -+ -+ if (cdns_mhdp_read_hpd(mhdp)) -+ enable_irq(mhdp->irq[IRQ_OUT]); - else -- enable_irq(dp->irq[IRQ_IN]); -+ enable_irq(mhdp->irq[IRQ_IN]); - -- dp->mhdp.bridge.base.driver_private = dp; -- dp->mhdp.bridge.base.funcs = &cdns_dp_bridge_funcs; -+ mhdp->bridge.base.driver_private = mhdp; -+ mhdp->bridge.base.funcs = &cdns_dp_bridge_funcs; - #ifdef CONFIG_OF -- dp->mhdp.bridge.base.of_node = dev->of_node; -+ mhdp->bridge.base.of_node = dev->of_node; - #endif - -- dev_set_drvdata(dev, &dp->mhdp); -+ dev_set_drvdata(dev, mhdp); - - /* register audio driver */ - cdns_mhdp_register_audio_driver(dev); - -- dp_aux_init(&dp->mhdp, dev); -- -- return dp; -+ dp_aux_init(mhdp, dev); - --err_out: -- return ERR_PTR(ret); -+ return 0; - } - - static void __cdns_dp_remove(struct cdns_mhdp_device *mhdp) -@@ -547,15 +524,15 @@ static void __cdns_dp_remove(struct cdns - * Probe/remove API, used from platforms based on the DRM bridge API. - */ - int cdns_dp_probe(struct platform_device *pdev, -- const struct cdn_plat_data *plat_data) -+ struct cdns_mhdp_device *mhdp) - { -- struct imx_mhdp_device *dp; -+ int ret; - -- dp = __cdns_dp_probe(pdev, plat_data); -- if (IS_ERR(dp)) -- return PTR_ERR(dp); -+ ret = __cdns_dp_probe(pdev, mhdp); -+ if (ret) -+ return ret; - -- drm_bridge_add(&dp->mhdp.bridge.base); -+ drm_bridge_add(&mhdp->bridge.base); - - return 0; - } -@@ -575,16 +552,15 @@ EXPORT_SYMBOL_GPL(cdns_dp_remove); - * Bind/unbind API, used from platforms based on the component framework. - */ - int cdns_dp_bind(struct platform_device *pdev, struct drm_encoder *encoder, -- const struct cdn_plat_data *plat_data) -+ struct cdns_mhdp_device *mhdp) - { -- struct imx_mhdp_device *dp; - int ret; - -- dp = __cdns_dp_probe(pdev, plat_data); -- if (IS_ERR(dp)) -- return PTR_ERR(dp); -+ ret = __cdns_dp_probe(pdev, mhdp); -+ if (ret < 0) -+ return ret; - -- ret = drm_bridge_attach(encoder, &dp->mhdp.bridge.base, NULL); -+ ret = drm_bridge_attach(encoder, &mhdp->bridge.base, NULL); - if (ret) { - cdns_dp_remove(pdev); - DRM_ERROR("Failed to initialize bridge with drm\n"); ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -9,7 +9,7 @@ - * (at your option) any later version. - * - */ --#include -+#include - #include - #include - #include -@@ -60,8 +60,6 @@ static int hdmi_sink_config(struct cdns_ - static void hdmi_lanes_config(struct cdns_mhdp_device *mhdp) - { - /* Line swaping */ -- /* For imx8qm lane_mapping = 0x93 -- * For imx8mq lane_mapping = 0xe4*/ - cdns_mhdp_reg_write(mhdp, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping); - } - -@@ -216,12 +214,12 @@ void cdns_hdmi_mode_set(struct cdns_mhdp - static enum drm_connector_status - cdns_hdmi_connector_detect(struct drm_connector *connector, bool force) - { -- struct imx_mhdp_device *hdmi = -- container_of(connector, struct imx_mhdp_device, mhdp.connector.base); -+ struct cdns_mhdp_device *mhdp = -+ container_of(connector, struct cdns_mhdp_device, connector.base); - - u8 hpd = 0xf; - -- hpd = cdns_mhdp_read_hpd(&hdmi->mhdp); -+ hpd = cdns_mhdp_read_hpd(mhdp); - - if (hpd == 1) - /* Cable Connected */ -@@ -238,15 +236,15 @@ cdns_hdmi_connector_detect(struct drm_co - - static int cdns_hdmi_connector_get_modes(struct drm_connector *connector) - { -- struct imx_mhdp_device *hdmi = container_of(connector, struct imx_mhdp_device, -- mhdp.connector.base); -+ struct cdns_mhdp_device *mhdp = -+ container_of(connector, struct cdns_mhdp_device, connector.base); - int num_modes = 0; - struct edid *edid; - -- edid = drm_do_get_edid(&hdmi->mhdp.connector.base, -- cdns_hdmi_get_edid_block, &hdmi->mhdp); -+ edid = drm_do_get_edid(&mhdp->connector.base, -+ cdns_hdmi_get_edid_block, mhdp); - if (edid) { -- dev_info(hdmi->mhdp.dev, "%x,%x,%x,%x,%x,%x,%x,%x\n", -+ dev_info(mhdp->dev, "%x,%x,%x,%x,%x,%x,%x,%x\n", - edid->header[0], edid->header[1], - edid->header[2], edid->header[3], - edid->header[4], edid->header[5], -@@ -276,9 +274,9 @@ static const struct drm_connector_helper - - static int cdns_hdmi_bridge_attach(struct drm_bridge *bridge) - { -- struct imx_mhdp_device *hdmi = bridge->driver_private; -+ struct cdns_mhdp_device *mhdp = bridge->driver_private; - struct drm_encoder *encoder = bridge->encoder; -- struct drm_connector *connector = &hdmi->mhdp.connector.base; -+ struct drm_connector *connector = &mhdp->connector.base; - - connector->interlace_allowed = 1; - connector->polled = DRM_CONNECTOR_POLL_HPD; -@@ -319,9 +317,9 @@ static void cdns_hdmi_bridge_mode_set(st - const struct drm_display_mode *orig_mode, - const struct drm_display_mode *mode) - { -- struct imx_mhdp_device *hdmi = bridge->driver_private; -- struct drm_display_info *display_info = &hdmi->mhdp.connector.base.display_info; -- struct video_info *video = &hdmi->mhdp.video_info; -+ struct cdns_mhdp_device *mhdp = bridge->driver_private; -+ struct drm_display_info *display_info = &mhdp->connector.base.display_info; -+ struct video_info *video = &mhdp->video_info; - - switch (display_info->bpc) { - case 10: -@@ -339,23 +337,24 @@ static void cdns_hdmi_bridge_mode_set(st - video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); - video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); - -- mutex_lock(&hdmi->lock); -+ mutex_lock(&mhdp->lock); - - DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay, mode->vdisplay, mode->clock); - -- memcpy(&hdmi->mhdp.mode, mode, sizeof(struct drm_display_mode)); -+ memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode)); - -- hdmi->dual_mode = video_is_dual_mode(mode); -+ //Sandor TODO -+// hdmi->dual_mode = video_is_dual_mode(mode); - -- hdmi_lanes_config(&hdmi->mhdp); -+ hdmi_lanes_config(mhdp); - -- hdp_plat_call(hdmi, pclock_change); -+ cdns_mhdp_plat_call(mhdp, pclk_rate); - -- hdp_plat_call(hdmi, phy_init); -+ cdns_mhdp_plat_call(mhdp, phy_set); - -- cdns_hdmi_mode_set(&hdmi->mhdp); -+ cdns_hdmi_mode_set(mhdp); - -- mutex_unlock(&hdmi->lock); -+ mutex_unlock(&mhdp->lock); - } - - static const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = { -@@ -366,30 +365,30 @@ static const struct drm_bridge_funcs cdn - - static void hotplug_work_func(struct work_struct *work) - { -- struct imx_mhdp_device *hdmi = container_of(work, -- struct imx_mhdp_device, hotplug_work.work); -- struct drm_connector *connector = &hdmi->mhdp.connector.base; -+ struct cdns_mhdp_device *mhdp = container_of(work, -+ struct cdns_mhdp_device, hotplug_work.work); -+ struct drm_connector *connector = &mhdp->connector.base; - - drm_helper_hpd_irq_event(connector->dev); - - if (connector->status == connector_status_connected) { - /* Cable Connected */ - DRM_INFO("HDMI Cable Plug In\n"); -- enable_irq(hdmi->irq[IRQ_OUT]); -+ enable_irq(mhdp->irq[IRQ_OUT]); - } else if (connector->status == connector_status_disconnected) { - /* Cable Disconnedted */ - DRM_INFO("HDMI Cable Plug Out\n"); -- enable_irq(hdmi->irq[IRQ_IN]); -+ enable_irq(mhdp->irq[IRQ_IN]); - } - } - - static irqreturn_t cdns_hdmi_irq_thread(int irq, void *data) - { -- struct imx_mhdp_device *hdmi = data; -+ struct cdns_mhdp_device *mhdp = data; - - disable_irq_nosync(irq); - -- mod_delayed_work(system_wq, &hdmi->hotplug_work, -+ mod_delayed_work(system_wq, &mhdp->hotplug_work, - msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS)); - - return IRQ_HANDLED; -@@ -408,109 +407,99 @@ static void cdns_hdmi_parse_dt(struct cd - dev_info(mhdp->dev, "lane-mapping 0x%02x\n", mhdp->lane_mapping); - } - --static struct imx_mhdp_device * --__cdns_hdmi_probe(struct platform_device *pdev, -- const struct cdn_plat_data *plat_data) -+static int __cdns_hdmi_probe(struct platform_device *pdev, -+ struct cdns_mhdp_device *mhdp) - { - struct device *dev = &pdev->dev; -- struct device_node *np = dev->of_node; - struct platform_device_info pdevinfo; -- struct imx_mhdp_device *hdmi; - struct resource *iores = NULL; - int ret; - -- hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); -- if (!hdmi) -- return ERR_PTR(-ENOMEM); -- -- hdmi->plat_data = plat_data; -- hdmi->mhdp.dev = dev; -- -- mutex_init(&hdmi->lock); -- mutex_init(&hdmi->audio_mutex); -- spin_lock_init(&hdmi->audio_lock); -+ mutex_init(&mhdp->lock); - -- INIT_DELAYED_WORK(&hdmi->hotplug_work, hotplug_work_func); -+ INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func); - - iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- hdmi->mhdp.regs = devm_ioremap(dev, iores->start, resource_size(iores)); -- if (IS_ERR(hdmi->mhdp.regs)) { -- ret = PTR_ERR(hdmi->mhdp.regs); -- goto err_out; -+ mhdp->regs_base = devm_ioremap(dev, iores->start, resource_size(iores)); -+ if (IS_ERR(mhdp->regs_base)) { -+ dev_err(dev, "No regs_base memory\n"); -+ return -ENOMEM; -+ } -+ -+ /* sec register base */ -+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ mhdp->regs_sec = devm_ioremap(dev, iores->start, resource_size(iores)); -+ if (IS_ERR(mhdp->regs_sec)) { -+ dev_err(dev, "No regs_sec memory\n"); -+ return -ENOMEM; - } - -- /* csr register base */ -- hdmi->regmap_csr = syscon_regmap_lookup_by_phandle(np, "csr"); -- if (IS_ERR(hdmi->regmap_csr)) { -- dev_info(dev, "No csr regmap\n"); -- } -- -- hdmi->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in"); -- if (hdmi->irq[IRQ_IN] < 0) { -+ mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in"); -+ if (mhdp->irq[IRQ_IN] < 0) { - dev_info(dev, "No plug_in irq number\n"); -- return ERR_PTR(-EPROBE_DEFER); -+ return -EPROBE_DEFER; - } - -- hdmi->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out"); -- if (hdmi->irq[IRQ_OUT] < 0) { -+ mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out"); -+ if (mhdp->irq[IRQ_OUT] < 0) { - dev_info(dev, "No plug_out irq number\n"); -- return ERR_PTR(-EPROBE_DEFER); -+ return -EPROBE_DEFER; - } - - /* Initialize dual_mode to false */ -- hdmi->dual_mode = false; -+// hdmi->dual_mode = false; - - /* Initialize FW */ -- hdp_plat_call(hdmi, fw_init); -+ cdns_mhdp_plat_call(mhdp, firmware_init); - - /* HDMI FW alive check */ -- ret = cdns_mhdp_check_alive(&hdmi->mhdp); -+ ret = cdns_mhdp_check_alive(mhdp); - if (ret == false) { -- DRM_ERROR("NO HDMI FW running\n"); -- return ERR_PTR(-ENXIO); -+ dev_err(dev, "NO HDMI FW running\n"); -+ return -ENXIO; - } - - /* Enable Hotplug Detect thread */ -- irq_set_status_flags(hdmi->irq[IRQ_IN], IRQ_NOAUTOEN); -- ret = devm_request_threaded_irq(dev, hdmi->irq[IRQ_IN], -+ irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN], - NULL, cdns_hdmi_irq_thread, - IRQF_ONESHOT, dev_name(dev), -- hdmi); -- if (ret) { -+ mhdp); -+ if (ret < 0) { - dev_err(dev, "can't claim irq %d\n", -- hdmi->irq[IRQ_IN]); -- goto err_out; -+ mhdp->irq[IRQ_IN]); -+ return -EINVAL; - } - -- irq_set_status_flags(hdmi->irq[IRQ_OUT], IRQ_NOAUTOEN); -- ret = devm_request_threaded_irq(dev, hdmi->irq[IRQ_OUT], -+ irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT], - NULL, cdns_hdmi_irq_thread, - IRQF_ONESHOT, dev_name(dev), -- hdmi); -- if (ret) { -+ mhdp); -+ if (ret < 0) { - dev_err(dev, "can't claim irq %d\n", -- hdmi->irq[IRQ_OUT]); -- goto err_out; -+ mhdp->irq[IRQ_OUT]); -+ return -EINVAL; - } - -- cdns_hdmi_parse_dt(&hdmi->mhdp); -+ cdns_hdmi_parse_dt(mhdp); - -- if (cdns_mhdp_read_hpd(&hdmi->mhdp)) -- enable_irq(hdmi->irq[IRQ_OUT]); -+ if (cdns_mhdp_read_hpd(mhdp)) -+ enable_irq(mhdp->irq[IRQ_OUT]); - else -- enable_irq(hdmi->irq[IRQ_IN]); -+ enable_irq(mhdp->irq[IRQ_IN]); - -- hdmi->mhdp.bridge.base.driver_private = hdmi; -- hdmi->mhdp.bridge.base.funcs = &cdns_hdmi_bridge_funcs; -+ mhdp->bridge.base.driver_private = mhdp; -+ mhdp->bridge.base.funcs = &cdns_hdmi_bridge_funcs; - #ifdef CONFIG_OF -- hdmi->mhdp.bridge.base.of_node = dev->of_node; -+ mhdp->bridge.base.of_node = dev->of_node; - #endif - - memset(&pdevinfo, 0, sizeof(pdevinfo)); - pdevinfo.parent = dev; - pdevinfo.id = PLATFORM_DEVID_AUTO; - -- dev_set_drvdata(dev, &hdmi->mhdp); -+ dev_set_drvdata(dev, mhdp); - - /* register audio driver */ - cdns_mhdp_register_audio_driver(dev); -@@ -520,11 +509,7 @@ __cdns_hdmi_probe(struct platform_device - cdns_mhdp_register_cec_driver(dev); - #endif - -- return hdmi; -- --err_out: -- -- return ERR_PTR(ret); -+ return 0; - } - - static void __cdns_hdmi_remove(struct cdns_mhdp_device *mhdp) -@@ -540,15 +525,15 @@ static void __cdns_hdmi_remove(struct cd - * Probe/remove API, used from platforms based on the DRM bridge API. - */ - int cdns_hdmi_probe(struct platform_device *pdev, -- const struct cdn_plat_data *plat_data) -+ struct cdns_mhdp_device *mhdp) - { -- struct imx_mhdp_device *hdmi; -+ int ret; - -- hdmi = __cdns_hdmi_probe(pdev, plat_data); -- if (IS_ERR(hdmi)) -- return PTR_ERR(hdmi); -+ ret = __cdns_hdmi_probe(pdev, mhdp); -+ if (ret < 0) -+ return ret; - -- drm_bridge_add(&hdmi->mhdp.bridge.base); -+ drm_bridge_add(&mhdp->bridge.base); - - return 0; - } -@@ -568,16 +553,15 @@ EXPORT_SYMBOL_GPL(cdns_hdmi_remove); - * Bind/unbind API, used from platforms based on the component framework. - */ - int cdns_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, -- const struct cdn_plat_data *plat_data) -+ struct cdns_mhdp_device *mhdp) - { -- struct imx_mhdp_device *hdmi; - int ret; - -- hdmi = __cdns_hdmi_probe(pdev, plat_data); -- if (IS_ERR(hdmi)) -- return PTR_ERR(hdmi); -+ ret = __cdns_hdmi_probe(pdev, mhdp); -+ if (ret) -+ return ret; - -- ret = drm_bridge_attach(encoder, &hdmi->mhdp.bridge.base, NULL); -+ ret = drm_bridge_attach(encoder, &mhdp->bridge.base, NULL); - if (ret) { - cdns_hdmi_remove(pdev); - DRM_ERROR("Failed to initialize bridge with drm\n"); ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c -@@ -16,7 +16,6 @@ - #include - #include - #include --#include - #include - #include - ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c -@@ -344,4 +344,4 @@ int cdns_mhdp_unregister_cec_driver(stru - - MODULE_AUTHOR("Sandor.Yu@NXP.com"); - MODULE_LICENSE("GPL"); --MODULE_DESCRIPTION("NXP CDNS MHDP CEC driver"); -+MODULE_DESCRIPTION("NXP CDNS MHDP HDMI CEC driver"); ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -@@ -23,7 +23,6 @@ - #include - - #include --#include - #include - #include - #include -@@ -74,18 +73,20 @@ static inline void put_unaligned_be24(u3 - - u32 cdns_mhdp_bus_read(struct cdns_mhdp_device *mhdp, u32 offset) - { -- struct imx_mhdp_device *hdmi = container_of(mhdp, struct imx_mhdp_device, mhdp); - u32 val; - -- /* TODO */ -- if (offset >= 0x1000 && hdmi->regmap_csr) { -+ if (mhdp->bus_type == BUS_TYPE_LOW4K_SAPB) { -+ /* Remap address to low 4K SAPB bus */ -+ writel(offset >> 12, mhdp->regs_sec + 0xc); -+ val = readl((offset & 0xfff) + mhdp->regs_base); -+ } else if (mhdp->bus_type == BUS_TYPE_LOW4K_APB) { - /* Remap address to low 4K memory */ -- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, offset >> 12); -- val = readl((offset & 0xfff) + mhdp->regs); -- /* Restore address mapping */ -- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, 0); -- } else -- val = readl(mhdp->regs + offset); -+ writel(offset >> 12, mhdp->regs_sec + 8); -+ val = readl((offset & 0xfff) + mhdp->regs_base); -+ } else if (mhdp->bus_type == BUS_TYPE_NORMAL_SAPB) -+ val = readl(mhdp->regs_sec + offset); -+ else -+ val = readl(mhdp->regs_base + offset); - - return val; - } -@@ -93,18 +94,18 @@ EXPORT_SYMBOL(cdns_mhdp_bus_read); - - void cdns_mhdp_bus_write(u32 val, struct cdns_mhdp_device *mhdp, u32 offset) - { -- struct imx_mhdp_device *hdmi = container_of(mhdp, struct imx_mhdp_device, mhdp); -- -- /* TODO */ -- if (offset >= 0x1000 && hdmi->regmap_csr) { -+ if (mhdp->bus_type == BUS_TYPE_LOW4K_SAPB) { -+ /* Remap address to low 4K SAPB bus */ -+ writel(offset >> 12, mhdp->regs_sec + 0xc); -+ writel(val, (offset & 0xfff) + mhdp->regs_base); -+ } else if (mhdp->bus_type == BUS_TYPE_LOW4K_APB) { - /* Remap address to low 4K memory */ -- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, offset >> 12); -- writel(val, (offset & 0xfff) + mhdp->regs); -- /* Restore address mapping */ -- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, 0); -- -- } else -- writel(val, mhdp->regs + offset); -+ writel(offset >> 12, mhdp->regs_sec + 8); -+ writel(val, (offset & 0xfff) + mhdp->regs_base); -+ } else if (mhdp->bus_type == BUS_TYPE_NORMAL_SAPB) -+ writel(val, mhdp->regs_sec + offset); -+ else -+ writel(val, mhdp->regs_base + offset); - } - EXPORT_SYMBOL(cdns_mhdp_bus_write); - ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c -@@ -10,7 +10,6 @@ - #include - #include - #include --#include - #include - - void cdns_mhdp_infoframe_set(struct cdns_mhdp_device *mhdp, ---- a/include/drm/bridge/cdns-mhdp-common.h -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -495,6 +495,22 @@ - - #define HOTPLUG_DEBOUNCE_MS 200 - -+#define IRQ_IN 0 -+#define IRQ_OUT 1 -+#define IRQ_NUM 2 -+ -+#define cdns_mhdp_plat_call(mhdp, operation) \ -+ (!(mhdp) ? -ENODEV : (((mhdp)->plat_data && (mhdp)->plat_data->operation) ? \ -+ (mhdp)->plat_data->operation(mhdp) : ENOIOCTLCMD)) -+ -+/* bus access type */ -+enum { -+ BUS_TYPE_NORMAL_APB = 0, -+ BUS_TYPE_NORMAL_SAPB = 1, -+ BUS_TYPE_LOW4K_APB = 2, -+ BUS_TYPE_LOW4K_SAPB = 3, -+}; -+ - enum voltage_swing_level { - VOLTAGE_LEVEL_0, - VOLTAGE_LEVEL_1, -@@ -616,8 +632,33 @@ struct cdns_mhdp_cec { - }; - #endif - -+struct cdns_plat_data { -+ /* Vendor PHY support */ -+ int (*bind)(struct platform_device *pdev, -+ struct drm_encoder *encoder, -+ struct cdns_mhdp_device *mhdp); -+ void (*unbind)(struct device *dev); -+ -+ void (*plat_init)(struct cdns_mhdp_device *mhdp); -+ void (*plat_deinit)(struct cdns_mhdp_device *mhdp); -+ -+ int (*phy_set)(struct cdns_mhdp_device *mhdp); -+ int (*firmware_init)(struct cdns_mhdp_device *mhdp); -+ void (*pclk_rate)(struct cdns_mhdp_device *mhdp); -+ -+ int (*power_on)(struct cdns_mhdp_device *mhdp); -+ int (*power_off)(struct cdns_mhdp_device *mhdp); -+ -+ int bus_type; -+ int video_format; -+ char is_dp; -+}; -+ - struct cdns_mhdp_device { -- void __iomem *regs; -+ void __iomem *regs_base; -+ void __iomem *regs_sec; -+ -+ int bus_type; - - struct device *dev; - -@@ -642,6 +683,9 @@ struct cdns_mhdp_device { - bool link_up; - bool power_up; - bool plugged; -+ struct mutex lock; -+ -+ int irq[IRQ_NUM]; - - union { - struct _dp_data { -@@ -663,6 +707,8 @@ struct cdns_mhdp_device { - u32 hdmi_type; - } hdmi; - }; -+ const struct cdns_plat_data *plat_data; -+ - }; - - u32 cdns_mhdp_bus_read(struct cdns_mhdp_device *mhdp, u32 offset); -@@ -727,6 +773,25 @@ int cdns_hdmi_disable_gcp(struct cdns_mh - int cdns_hdmi_enable_gcp(struct cdns_mhdp_device *mhdp); - - bool cdns_mhdp_check_alive(struct cdns_mhdp_device *mhdp); -+ -+/* HDMI */ -+int cdns_hdmi_probe(struct platform_device *pdev, -+ struct cdns_mhdp_device *mhdp); -+void cdns_hdmi_remove(struct platform_device *pdev); -+void cdns_hdmi_unbind(struct device *dev); -+int cdns_hdmi_bind(struct platform_device *pdev, -+ struct drm_encoder *encoder, struct cdns_mhdp_device *mhdp); -+void cdns_hdmi_set_sample_rate(struct cdns_mhdp_device *mhdp, unsigned int rate); -+void cdns_hdmi_audio_enable(struct cdns_mhdp_device *mhdp); -+void cdns_hdmi_audio_disable(struct cdns_mhdp_device *mhdp); -+/* DP */ -+int cdns_dp_probe(struct platform_device *pdev, -+ struct cdns_mhdp_device *mhdp); -+void cdns_dp_remove(struct platform_device *pdev); -+void cdns_dp_unbind(struct device *dev); -+int cdns_dp_bind(struct platform_device *pdev, -+ struct drm_encoder *encoder, struct cdns_mhdp_device *mhdp); -+ - /* CEC */ - #ifdef CONFIG_DRM_CDNS_HDMI_CEC - int cdns_mhdp_register_cec_driver(struct device *dev); ---- a/include/drm/bridge/cdns-mhdp-imx.h -+++ /dev/null -@@ -1,121 +0,0 @@ --/* -- * Cadence High-Definition Multimedia Interface (HDMI) driver -- * -- * Copyright (C) 2019 NXP Semiconductor, Inc. -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- */ --#ifndef CDNS_MHDP_IMX_H_ --#define CDNS_MHDP_IMX_H_ -- --#include -- --#define IRQ_IN 0 --#define IRQ_OUT 1 --#define IRQ_NUM 2 -- --#define hdp_plat_call(hdp, operation) \ -- (!(hdp) ? -ENODEV : (((hdp)->plat_data && (hdp)->plat_data->operation) ? \ -- (hdp)->plat_data->operation(hdp) : ENOIOCTLCMD)) -- --#define HDP_DUAL_MODE_MIN_PCLK_RATE 300000 /* KHz */ --#define HDP_SINGLE_MODE_MAX_WIDTH 1920 -- --static inline bool video_is_dual_mode(const struct drm_display_mode *mode) --{ -- return (mode->clock > HDP_DUAL_MODE_MIN_PCLK_RATE || -- mode->hdisplay > HDP_SINGLE_MODE_MAX_WIDTH) ? true : false; --} -- --struct imx_mhdp_device; -- --struct imx_hdp_clks { -- struct clk *av_pll; -- struct clk *dig_pll; -- struct clk *clk_ipg; -- struct clk *clk_core; -- struct clk *clk_pxl; -- struct clk *clk_pxl_mux; -- struct clk *clk_pxl_link; -- -- struct clk *lpcg_hdp; -- struct clk *lpcg_msi; -- struct clk *lpcg_pxl; -- struct clk *lpcg_vif; -- struct clk *lpcg_lis; -- struct clk *lpcg_apb; -- struct clk *lpcg_apb_csr; -- struct clk *lpcg_apb_ctrl; -- -- struct clk *lpcg_i2s; -- struct clk *clk_i2s_bypass; --}; -- --struct cdn_plat_data { -- /* Vendor PHY support */ -- int (*phy_init)(struct imx_mhdp_device *hdmi); -- int (*bind)(struct platform_device *pdev, -- struct drm_encoder *encoder, -- const struct cdn_plat_data *plat_data); -- void (*unbind)(struct device *dev); -- int (*fw_init)(struct imx_mhdp_device *hdp); -- void (*pclock_change)(struct imx_mhdp_device *hdp); -- char is_dp; --}; -- --struct imx_mhdp_device { -- struct cdns_mhdp_device mhdp; -- -- struct mutex lock; -- struct mutex audio_mutex; -- spinlock_t audio_lock; -- bool connected; -- bool active; -- bool suspended; -- struct imx_hdp_clks clks; -- -- const struct cdn_plat_data *plat_data; -- -- int irq[IRQ_NUM]; -- struct delayed_work hotplug_work; -- //void __iomem *regmap_csr; -- struct regmap *regmap_csr; -- u32 csr_pxl_mux_reg; -- u32 csr_ctrl0_reg; -- u32 csr_ctrl0_sec; -- -- struct audio_info audio_info; -- bool sink_has_audio; -- u32 dual_mode; -- -- struct device *pd_mhdp_dev; -- struct device *pd_pll0_dev; -- struct device *pd_pll1_dev; -- struct device_link *pd_mhdp_link; -- struct device_link *pd_pll0_link; -- struct device_link *pd_pll1_link; -- -- u32 phy_init; --}; -- --int cdns_hdmi_probe(struct platform_device *pdev, -- const struct cdn_plat_data *plat_data); --void cdns_hdmi_remove(struct platform_device *pdev); --void cdns_hdmi_unbind(struct device *dev); --int cdns_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder, -- const struct cdn_plat_data *plat_data); --void cdns_hdmi_set_sample_rate(struct imx_mhdp_device *hdmi, unsigned int rate); --void cdns_hdmi_audio_enable(struct imx_mhdp_device *hdmi); --void cdns_hdmi_audio_disable(struct imx_mhdp_device *hdmi); --int cdns_dp_probe(struct platform_device *pdev, -- const struct cdn_plat_data *plat_data); --void cdns_dp_remove(struct platform_device *pdev); --void cdns_dp_unbind(struct device *dev); --int cdns_dp_bind(struct platform_device *pdev, struct drm_encoder *encoder, -- const struct cdn_plat_data *plat_data); -- --#endif /* CDNS_MHDP_IMX_H_ */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0011-drm-imx-add-imx8mq-hdmi-support.patch b/target/linux/layerscape/patches-5.4/805-display-0011-drm-imx-add-imx8mq-hdmi-support.patch deleted file mode 100644 index 8a6f5ddeee..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0011-drm-imx-add-imx8mq-hdmi-support.patch +++ /dev/null @@ -1,1169 +0,0 @@ -From 7095b3b3b28031708ab74a65c32e84e231bc9d27 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Wed, 11 Sep 2019 17:18:29 +0800 -Subject: [PATCH] drm: imx: add imx8mq hdmi support - -add struct imx_mhdp_device for imx specific. -add imx8mq hdmi support. -move imx8qm specific functions to plat_data -uniform variable name. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/imx/Makefile | 2 +- - drivers/gpu/drm/imx/cdn-mhdp-dp-phy.c | 8 +- - drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c | 7 +- - drivers/gpu/drm/imx/cdn-mhdp-imx8mq.c | 163 ------------ - drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c | 437 ++++++++++---------------------- - drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c | 202 +++++++++++++++ - drivers/gpu/drm/imx/cdn-mhdp-phy.h | 12 +- - drivers/gpu/drm/imx/cdns-mhdp-imx.h | 80 ++++++ - 8 files changed, 421 insertions(+), 490 deletions(-) - delete mode 100644 drivers/gpu/drm/imx/cdn-mhdp-imx8mq.c - create mode 100644 drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c - create mode 100644 drivers/gpu/drm/imx/cdns-mhdp-imx.h - ---- a/drivers/gpu/drm/imx/Makefile -+++ b/drivers/gpu/drm/imx/Makefile -@@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o - obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o - - obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o --obj-$(CONFIG_DRM_IMX_CDNS_MHDP) += cdn-mhdp-imx8qm.o cdn-mhdp-imx8mq.o cdn-mhdp-dp-phy.o cdn-mhdp-hdmi-phy.o -+obj-$(CONFIG_DRM_IMX_CDNS_MHDP) += cdn-mhdp-imxdrv.o cdn-mhdp-dp-phy.o cdn-mhdp-hdmi-phy.o cdn-mhdp-imx8qm.o ---- a/drivers/gpu/drm/imx/cdn-mhdp-dp-phy.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-dp-phy.c -@@ -12,7 +12,6 @@ - #include - #include - #include -- - #include - #include "cdn-mhdp-phy.h" - -@@ -477,9 +476,8 @@ static int dp_phy_power_up(struct cdns_m - return 0; - } - --int cdns_dp_phy_init_imx8mq(struct imx_mhdp_device *hdp) -+int cdns_dp_phy_set_imx8mq(struct cdns_mhdp_device *mhdp) - { -- struct cdns_mhdp_device *mhdp = &hdp->mhdp; - int ret; - - /* Disable phy clock if PHY in power up state */ -@@ -504,10 +502,8 @@ int cdns_dp_phy_init_imx8mq(struct imx_m - return ret; - } - -- --int cdns_dp_phy_init_imx8qm(struct imx_mhdp_device *hdp) -+int cdns_dp_phy_set_imx8qm(struct cdns_mhdp_device *mhdp) - { -- struct cdns_mhdp_device *mhdp = &hdp->mhdp; - int ret; - - /* Disable phy clock if PHY in power up state */ ---- a/drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c -@@ -624,9 +624,8 @@ static int hdmi_phy_power_up(struct cdns - return 0; - } - --int cdns_hdmi_phy_set_imx8mq(struct imx_mhdp_device *hdp) -+int cdns_hdmi_phy_set_imx8mq(struct cdns_mhdp_device *mhdp) - { -- struct cdns_mhdp_device *mhdp = &hdp->mhdp; - struct drm_display_mode *mode = &mhdp->mode; - int ret; - -@@ -653,9 +652,8 @@ int cdns_hdmi_phy_set_imx8mq(struct imx_ - return true; - } - --int cdns_hdmi_phy_set_imx8qm(struct imx_mhdp_device *hdp) -+int cdns_hdmi_phy_set_imx8qm(struct cdns_mhdp_device *mhdp) - { -- struct cdns_mhdp_device *mhdp = &hdp->mhdp; - struct drm_display_mode *mode = &mhdp->mode; - int ret; - -@@ -681,4 +679,3 @@ int cdns_hdmi_phy_set_imx8qm(struct imx_ - - return true; - } -- ---- a/drivers/gpu/drm/imx/cdn-mhdp-imx8mq.c -+++ /dev/null -@@ -1,163 +0,0 @@ --/* -- * Copyright (C) 2019 NXP Semiconductor, Inc. -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- */ --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include "cdn-mhdp-phy.h" --#include "imx-drm.h" -- --struct imx_hdmi { -- struct device *dev; -- struct drm_encoder encoder; --}; -- --static void cdns_hdmi_imx_encoder_disable(struct drm_encoder *encoder) --{ --} -- --static void cdns_hdmi_imx_encoder_enable(struct drm_encoder *encoder) --{ --} -- --static int cdns_hdmi_imx_atomic_check(struct drm_encoder *encoder, -- struct drm_crtc_state *crtc_state, -- struct drm_connector_state *conn_state) --{ -- return 0; --} -- --static const struct drm_encoder_helper_funcs cdns_hdmi_imx_encoder_helper_funcs = { -- .enable = cdns_hdmi_imx_encoder_enable, -- .disable = cdns_hdmi_imx_encoder_disable, -- .atomic_check = cdns_hdmi_imx_atomic_check, --}; -- --static const struct drm_encoder_funcs cdns_hdmi_imx_encoder_funcs = { -- .destroy = drm_encoder_cleanup, --}; -- --static struct cdn_plat_data imx8mq_hdmi_drv_data = { -- .bind = cdns_hdmi_bind, -- .unbind = cdns_hdmi_unbind, -- .phy_init = cdns_hdmi_phy_set_imx8mq, --}; -- --static struct cdn_plat_data imx8mq_dp_drv_data = { -- .bind = cdns_dp_bind, -- .unbind = cdns_dp_unbind, -- .phy_init = cdns_dp_phy_init_imx8mq, --}; -- --static const struct of_device_id cdns_hdmi_imx_dt_ids[] = { -- { .compatible = "cdn,imx8mq-hdmi", -- .data = &imx8mq_hdmi_drv_data -- }, -- { .compatible = "cdn,imx8mq-dp", -- .data = &imx8mq_dp_drv_data -- }, -- {}, --}; --MODULE_DEVICE_TABLE(of, cdns_hdmi_imx_dt_ids); -- --static int cdns_hdmi_imx_bind(struct device *dev, struct device *master, -- void *data) --{ -- struct platform_device *pdev = to_platform_device(dev); -- const struct cdn_plat_data *plat_data; -- const struct of_device_id *match; -- struct drm_device *drm = data; -- struct drm_encoder *encoder; -- struct imx_hdmi *hdmi; -- int ret; -- -- if (!pdev->dev.of_node) -- return -ENODEV; -- -- hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); -- if (!hdmi) -- return -ENOMEM; -- -- match = of_match_node(cdns_hdmi_imx_dt_ids, pdev->dev.of_node); -- plat_data = match->data; -- hdmi->dev = &pdev->dev; -- encoder = &hdmi->encoder; -- -- encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); -- /* -- * If we failed to find the CRTC(s) which this encoder is -- * supposed to be connected to, it's because the CRTC has -- * not been registered yet. Defer probing, and hope that -- * the required CRTC is added later. -- */ -- if (encoder->possible_crtcs == 0) -- return -EPROBE_DEFER; -- -- drm_encoder_helper_add(encoder, &cdns_hdmi_imx_encoder_helper_funcs); -- drm_encoder_init(drm, encoder, &cdns_hdmi_imx_encoder_funcs, -- DRM_MODE_ENCODER_TMDS, NULL); -- -- ret = plat_data->bind(pdev, encoder, plat_data); -- -- /* -- * If cdns_hdmi_bind() fails we'll never call cdns_hdmi_unbind(), -- * which would have called the encoder cleanup. Do it manually. -- */ -- if (ret) -- drm_encoder_cleanup(encoder); -- -- return ret; --} -- --static void cdns_hdmi_imx_unbind(struct device *dev, struct device *master, -- void *data) --{ -- struct imx_mhdp_device *hdp = dev_get_drvdata(dev); -- -- hdp->plat_data->unbind(dev); --} -- --static const struct component_ops cdns_hdmi_imx_ops = { -- .bind = cdns_hdmi_imx_bind, -- .unbind = cdns_hdmi_imx_unbind, --}; -- --static int cdns_hdmi_imx_probe(struct platform_device *pdev) --{ -- return component_add(&pdev->dev, &cdns_hdmi_imx_ops); --} -- --static int cdns_hdmi_imx_remove(struct platform_device *pdev) --{ -- component_del(&pdev->dev, &cdns_hdmi_imx_ops); -- -- return 0; --} -- --static struct platform_driver cdns_hdmi_imx_platform_driver = { -- .probe = cdns_hdmi_imx_probe, -- .remove = cdns_hdmi_imx_remove, -- .driver = { -- .name = "cdn-hdp-imx8mq", -- .of_match_table = cdns_hdmi_imx_dt_ids, -- }, --}; -- --module_platform_driver(cdns_hdmi_imx_platform_driver); -- --MODULE_AUTHOR("Sandor YU "); --MODULE_LICENSE("GPL"); --MODULE_ALIAS("platform:cdnhdmi-imx"); ---- a/drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c -@@ -1,54 +1,40 @@ - /* -- * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * copyright (c) 2019 nxp semiconductor, inc. - * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -+ * this program is free software; you can redistribute it and/or modify -+ * it under the terms of the gnu general public license version 2 as -+ * published by the free software foundation. - */ - #include --#include --#include --#include --#include --#include --#include --#include --#include - #include --#include - #include -+#include -+#include - --#include --#include "cdn-mhdp-phy.h" --#include "imx-drm.h" -+#include "cdns-mhdp-imx.h" - - #define CSR_PIXEL_LINK_MUX_CTL 0x00 --#define PL_MUX_CTL_VCP_OFFSET 5 --#define PL_MUX_CTL_HCP_OFFSET 4 -+#define CSR_PIXEL_LINK_MUX_VCP_OFFSET 5 -+#define CSR_PIXEL_LINK_MUX_HCP_OFFSET 4 - - #define PLL_800MHZ (800000000) - --struct imx_hdmi { -- struct device *dev; -- struct drm_encoder encoder; --}; -- --static void imx8qm_pixel_link_mux(struct imx_mhdp_device *hdp) -+static void imx8qm_pixel_link_mux(struct imx_mhdp_device *imx_mhdp) - { -- struct drm_display_mode *mode = &hdp->mhdp.mode; -+ struct drm_display_mode *mode = &imx_mhdp->mhdp.mode; - u32 val; - - val = 0x4; /* RGB */ -- if (hdp->dual_mode) -+ if (imx_mhdp->dual_mode) - val |= 0x2; /* pixel link 0 and 1 are active */ - if (mode->flags & DRM_MODE_FLAG_PVSYNC) -- val |= 1 << PL_MUX_CTL_VCP_OFFSET; -+ val |= 1 << CSR_PIXEL_LINK_MUX_VCP_OFFSET; - if (mode->flags & DRM_MODE_FLAG_PHSYNC) -- val |= 1 << PL_MUX_CTL_HCP_OFFSET; -+ val |= 1 << CSR_PIXEL_LINK_MUX_HCP_OFFSET; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - val |= 0x2; - -- regmap_write(hdp->regmap_csr, hdp->csr_pxl_mux_reg, val); -+ writel(val, imx_mhdp->mhdp.regs_sec); - } - - static void imx8qm_pixel_link_valid(u32 dual_mode) -@@ -120,10 +106,10 @@ static void imx8qm_clk_mux(u8 is_dp) - imx_sc_misc_set_control(handle, IMX_SC_R_HDMI, IMX_SC_C_MODE, 0); - } - --int imx8qm_clocks_init(struct imx_mhdp_device *hdp) -+int imx8qm_clocks_init(struct imx_mhdp_device *imx_mhdp) - { -- struct device *dev = hdp->mhdp.dev; -- struct imx_hdp_clks *clks = &hdp->clks; -+ struct device *dev = imx_mhdp->mhdp.dev; -+ struct imx_hdp_clks *clks = &imx_mhdp->clks; - - clks->dig_pll = devm_clk_get(dev, "dig_pll"); - if (IS_ERR(clks->dig_pll)) { -@@ -229,10 +215,10 @@ int imx8qm_clocks_init(struct imx_mhdp_d - return true; - } - --static int imx8qm_pixel_clk_enable(struct imx_mhdp_device *hdp) -+static int imx8qm_pixel_clk_enable(struct imx_mhdp_device *imx_mhdp) - { -- struct imx_hdp_clks *clks = &hdp->clks; -- struct device *dev = hdp->mhdp.dev; -+ struct imx_hdp_clks *clks = &imx_mhdp->clks; -+ struct device *dev = imx_mhdp->mhdp.dev; - int ret; - - ret = clk_prepare_enable(clks->av_pll); -@@ -273,12 +259,11 @@ static int imx8qm_pixel_clk_enable(struc - return ret; - } - return ret; -- - } - --static void imx8qm_pixel_clk_disable(struct imx_mhdp_device *hdp) -+static void imx8qm_pixel_clk_disable(struct imx_mhdp_device *imx_mhdp) - { -- struct imx_hdp_clks *clks = &hdp->clks; -+ struct imx_hdp_clks *clks = &imx_mhdp->clks; - - clk_disable_unprepare(clks->lpcg_pxl); - clk_disable_unprepare(clks->lpcg_hdp); -@@ -289,14 +274,14 @@ static void imx8qm_pixel_clk_disable(str - clk_disable_unprepare(clks->av_pll); - } - --static void imx8qm_pixel_clk_set_rate(struct imx_mhdp_device *hdp, u32 pclock) -+static void imx8qm_pixel_clk_set_rate(struct imx_mhdp_device *imx_mhdp, u32 pclock) - { -- struct imx_hdp_clks *clks = &hdp->clks; -+ struct imx_hdp_clks *clks = &imx_mhdp->clks; - - /* pixel clock for HDMI */ - clk_set_rate(clks->av_pll, pclock); - -- if (hdp->dual_mode == true) { -+ if (imx_mhdp->dual_mode == true) { - clk_set_rate(clks->clk_pxl, pclock/2); - clk_set_rate(clks->clk_pxl_link, pclock/2); - } else { -@@ -306,24 +291,11 @@ static void imx8qm_pixel_clk_set_rate(st - clk_set_rate(clks->clk_pxl_mux, pclock); - } - --static void imx8qm_pixel_clk_rate_change(struct imx_mhdp_device *hdp) --{ -- /* set pixel clock before video mode setup */ -- imx8qm_pixel_clk_disable(hdp); -- -- imx8qm_pixel_clk_set_rate(hdp, hdp->mhdp.mode.clock * 1000); -- -- imx8qm_pixel_clk_enable(hdp); -- -- /* Config pixel link mux */ -- imx8qm_pixel_link_mux(hdp); --} -- --static int imx8qm_ipg_clk_enable(struct imx_mhdp_device *hdp) -+static int imx8qm_ipg_clk_enable(struct imx_mhdp_device *imx_mhdp) - { - int ret; -- struct imx_hdp_clks *clks = &hdp->clks; -- struct device *dev = hdp->mhdp.dev; -+ struct imx_hdp_clks *clks = &imx_mhdp->clks; -+ struct device *dev = imx_mhdp->mhdp.dev; - - ret = clk_prepare_enable(clks->dig_pll); - if (ret < 0) { -@@ -381,25 +353,9 @@ static int imx8qm_ipg_clk_enable(struct - return ret; - } - --static void imx8qm_ipg_clk_disable(struct imx_mhdp_device *hdp) --{ -- struct imx_hdp_clks *clks = &hdp->clks; -- -- clk_disable_unprepare(clks->clk_i2s_bypass); -- clk_disable_unprepare(clks->lpcg_i2s); -- clk_disable_unprepare(clks->lpcg_apb_ctrl); -- clk_disable_unprepare(clks->lpcg_apb_csr); -- clk_disable_unprepare(clks->lpcg_msi); -- clk_disable_unprepare(clks->lpcg_lis); -- clk_disable_unprepare(clks->lpcg_apb); -- clk_disable_unprepare(clks->clk_core); -- clk_disable_unprepare(clks->clk_ipg); -- clk_disable_unprepare(clks->dig_pll); --} -- --static void imx8qm_ipg_clk_set_rate(struct imx_mhdp_device *hdp) -+static void imx8qm_ipg_clk_set_rate(struct imx_mhdp_device *imx_mhdp) - { -- struct imx_hdp_clks *clks = &hdp->clks; -+ struct imx_hdp_clks *clks = &imx_mhdp->clks; - - /* ipg/core clock */ - clk_set_rate(clks->dig_pll, PLL_800MHZ); -@@ -407,308 +363,171 @@ static void imx8qm_ipg_clk_set_rate(stru - clk_set_rate(clks->clk_ipg, PLL_800MHZ/8); - } - --static void imx8qm_detach_pm_domains(struct imx_mhdp_device *hdp) -+static void imx8qm_detach_pm_domains(struct imx_mhdp_device *imx_mhdp) - { -- if (hdp->pd_pll1_link && !IS_ERR(hdp->pd_pll1_link)) -- device_link_del(hdp->pd_pll1_link); -- if (hdp->pd_pll1_dev && !IS_ERR(hdp->pd_pll1_dev)) -- dev_pm_domain_detach(hdp->pd_pll1_dev, true); -- -- if (hdp->pd_pll0_link && !IS_ERR(hdp->pd_pll0_link)) -- device_link_del(hdp->pd_pll0_link); -- if (hdp->pd_pll0_dev && !IS_ERR(hdp->pd_pll0_dev)) -- dev_pm_domain_detach(hdp->pd_pll0_dev, true); -- -- if (hdp->pd_mhdp_link && !IS_ERR(hdp->pd_mhdp_link)) -- device_link_del(hdp->pd_mhdp_link); -- if (hdp->pd_mhdp_dev && !IS_ERR(hdp->pd_mhdp_dev)) -- dev_pm_domain_detach(hdp->pd_mhdp_dev, true); -- -- hdp->pd_mhdp_dev = NULL; -- hdp->pd_mhdp_link = NULL; -- hdp->pd_pll0_dev = NULL; -- hdp->pd_pll0_link = NULL; -- hdp->pd_pll1_dev = NULL; -- hdp->pd_pll1_link = NULL; -+ if (imx_mhdp->pd_pll1_link && !IS_ERR(imx_mhdp->pd_pll1_link)) -+ device_link_del(imx_mhdp->pd_pll1_link); -+ if (imx_mhdp->pd_pll1_dev && !IS_ERR(imx_mhdp->pd_pll1_dev)) -+ dev_pm_domain_detach(imx_mhdp->pd_pll1_dev, true); -+ -+ if (imx_mhdp->pd_pll0_link && !IS_ERR(imx_mhdp->pd_pll0_link)) -+ device_link_del(imx_mhdp->pd_pll0_link); -+ if (imx_mhdp->pd_pll0_dev && !IS_ERR(imx_mhdp->pd_pll0_dev)) -+ dev_pm_domain_detach(imx_mhdp->pd_pll0_dev, true); -+ -+ if (imx_mhdp->pd_mhdp_link && !IS_ERR(imx_mhdp->pd_mhdp_link)) -+ device_link_del(imx_mhdp->pd_mhdp_link); -+ if (imx_mhdp->pd_mhdp_dev && !IS_ERR(imx_mhdp->pd_mhdp_dev)) -+ dev_pm_domain_detach(imx_mhdp->pd_mhdp_dev, true); -+ -+ imx_mhdp->pd_mhdp_dev = NULL; -+ imx_mhdp->pd_mhdp_link = NULL; -+ imx_mhdp->pd_pll0_dev = NULL; -+ imx_mhdp->pd_pll0_link = NULL; -+ imx_mhdp->pd_pll1_dev = NULL; -+ imx_mhdp->pd_pll1_link = NULL; - } - --static int imx8qm_attach_pm_domains(struct imx_mhdp_device *hdp) -+static int imx8qm_attach_pm_domains(struct imx_mhdp_device *imx_mhdp) - { -- struct device *dev = hdp->mhdp.dev; -+ struct device *dev = imx_mhdp->mhdp.dev; - u32 flags = DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE; - int ret = 0; - -- hdp->pd_mhdp_dev = dev_pm_domain_attach_by_name(dev, "hdmi"); -- if (IS_ERR(hdp->pd_mhdp_dev)) { -- ret = PTR_ERR(hdp->pd_mhdp_dev); -+ imx_mhdp->pd_mhdp_dev = dev_pm_domain_attach_by_name(dev, "hdmi"); -+ if (IS_ERR(imx_mhdp->pd_mhdp_dev)) { -+ ret = PTR_ERR(imx_mhdp->pd_mhdp_dev); - dev_err(dev, "Failed to attach dc pd dev: %d\n", ret); - goto fail; - } -- hdp->pd_mhdp_link = device_link_add(dev, hdp->pd_mhdp_dev, flags); -- if (IS_ERR(hdp->pd_mhdp_link)) { -- ret = PTR_ERR(hdp->pd_mhdp_link); -+ imx_mhdp->pd_mhdp_link = device_link_add(dev, imx_mhdp->pd_mhdp_dev, flags); -+ if (IS_ERR(imx_mhdp->pd_mhdp_link)) { -+ ret = PTR_ERR(imx_mhdp->pd_mhdp_link); - dev_err(dev, "Failed to add device link to dc pd dev: %d\n", - ret); - goto fail; - } - -- hdp->pd_pll0_dev = dev_pm_domain_attach_by_name(dev, "pll0"); -- if (IS_ERR(hdp->pd_pll0_dev)) { -- ret = PTR_ERR(hdp->pd_pll0_dev); -+ imx_mhdp->pd_pll0_dev = dev_pm_domain_attach_by_name(dev, "pll0"); -+ if (IS_ERR(imx_mhdp->pd_pll0_dev)) { -+ ret = PTR_ERR(imx_mhdp->pd_pll0_dev); - dev_err(dev, "Failed to attach pll0 pd dev: %d\n", ret); - goto fail; - } -- hdp->pd_pll0_link = device_link_add(dev, hdp->pd_pll0_dev, flags); -- if (IS_ERR(hdp->pd_pll0_link)) { -- ret = PTR_ERR(hdp->pd_pll0_link); -+ imx_mhdp->pd_pll0_link = device_link_add(dev, imx_mhdp->pd_pll0_dev, flags); -+ if (IS_ERR(imx_mhdp->pd_pll0_link)) { -+ ret = PTR_ERR(imx_mhdp->pd_pll0_link); - dev_err(dev, "Failed to add device link to pll0 pd dev: %d\n", - ret); - goto fail; - } - -- hdp->pd_pll1_dev = dev_pm_domain_attach_by_name(dev, "pll1"); -- if (IS_ERR(hdp->pd_pll1_dev)) { -- ret = PTR_ERR(hdp->pd_pll1_dev); -+ imx_mhdp->pd_pll1_dev = dev_pm_domain_attach_by_name(dev, "pll1"); -+ if (IS_ERR(imx_mhdp->pd_pll1_dev)) { -+ ret = PTR_ERR(imx_mhdp->pd_pll1_dev); - dev_err(dev, "Failed to attach pll0 pd dev: %d\n", ret); - goto fail; - } -- hdp->pd_pll1_link = device_link_add(dev, hdp->pd_pll1_dev, flags); -- if (IS_ERR(hdp->pd_pll1_link)) { -- ret = PTR_ERR(hdp->pd_pll1_link); -+ imx_mhdp->pd_pll1_link = device_link_add(dev, imx_mhdp->pd_pll1_dev, flags); -+ if (IS_ERR(imx_mhdp->pd_pll1_link)) { -+ ret = PTR_ERR(imx_mhdp->pd_pll1_link); - dev_err(dev, "Failed to add device link to pll1 pd dev: %d\n", - ret); - goto fail; - } - fail: -- imx8qm_detach_pm_domains(hdp); -+ imx8qm_detach_pm_domains(imx_mhdp); - return ret; - } - --static int imx8qm_firmware_init(struct imx_mhdp_device *hdp) -+static void imx8qm_mhdp_power_on(struct cdns_mhdp_device *mhdp) - { -- u32 rate; -- int ret; -- -+ struct imx_mhdp_device *imx_mhdp = -+ container_of(mhdp, struct imx_mhdp_device, mhdp); - /* Power on PM Domains */ -- imx8qm_attach_pm_domains(hdp); -+ -+ imx8qm_attach_pm_domains(imx_mhdp); - - /* clock init and rate set */ -- imx8qm_clocks_init(hdp); -+ imx8qm_clocks_init(imx_mhdp); - -- imx8qm_ipg_clk_set_rate(hdp); -+ imx8qm_ipg_clk_set_rate(imx_mhdp); - - /* Init pixel clock with 148.5MHz before FW init */ -- imx8qm_pixel_clk_set_rate(hdp, 148500000); -+ imx8qm_pixel_clk_set_rate(imx_mhdp, 148500000); - -- imx8qm_ipg_clk_enable(hdp); -+ imx8qm_ipg_clk_enable(imx_mhdp); - -- imx8qm_clk_mux(hdp->plat_data->is_dp); -+ imx8qm_clk_mux(imx_mhdp->mhdp.plat_data->is_dp); - -- imx8qm_pixel_clk_enable(hdp); -+ imx8qm_pixel_clk_enable(imx_mhdp); - - imx8qm_phy_reset(1); -- -- hdp->csr_pxl_mux_reg = 0; -- hdp->csr_ctrl0_reg = 0x8; -- hdp->csr_ctrl0_sec = 0xc; -- /* iMX8QM HDP register, Remap HPD memory address to low 4K */ -- regmap_write(hdp->regmap_csr, hdp->csr_ctrl0_reg, 0); -- -- /* configure HDMI/DP core clock */ -- rate = clk_get_rate(hdp->clks.clk_core); -- cdns_mhdp_set_fw_clk(&hdp->mhdp, rate); -- -- /* un-reset ucpu */ -- writel(0, (APB_CTRL << 2) + hdp->mhdp.regs); -- DRM_INFO("Started firmware!\n"); -- -- ret = cdns_mhdp_check_alive(&hdp->mhdp); -- if (ret == false) { -- DRM_ERROR("NO HDMI FW running\n"); -- return -ENXIO; -- } -- -- /* turn on IP activity */ -- cdns_mhdp_set_firmware_active(&hdp->mhdp, 1); -- -- DRM_INFO("HDP FW Version - ver %d verlib %d\n", -- __raw_readb(VER_L + hdp->mhdp.regs) + (__raw_readb(VER_H + hdp->mhdp.regs) << 8), -- __raw_readb(VER_LIB_L_ADDR + hdp->mhdp.regs) + (__raw_readb(VER_LIB_H_ADDR + hdp->mhdp.regs) << 8)); -- -- return 0; - } - --static void cdns_hdmi_imx_encoder_disable(struct drm_encoder *encoder) -+void cdns_mhdp_plat_init_imx8qm(struct cdns_mhdp_device *mhdp) - { -- struct imx_mhdp_device *hdp = encoder->bridge->driver_private; -+ struct imx_mhdp_device *imx_mhdp = -+ container_of(mhdp, struct imx_mhdp_device, mhdp); - -- imx8qm_pixel_link_sync_disable(hdp->dual_mode); -- imx8qm_pixel_link_invalid(hdp->dual_mode); -+ imx8qm_pixel_link_sync_disable(imx_mhdp->dual_mode); -+ imx8qm_pixel_link_invalid(imx_mhdp->dual_mode); - } - --static void cdns_hdmi_imx_encoder_enable(struct drm_encoder *encoder) -+void cdns_mhdp_plat_deinit_imx8qm(struct cdns_mhdp_device *mhdp) - { -- struct imx_mhdp_device *hdp = encoder->bridge->driver_private; -+ struct imx_mhdp_device *imx_mhdp = -+ container_of(mhdp, struct imx_mhdp_device, mhdp); - -- imx8qm_pixel_link_valid(hdp->dual_mode); -- imx8qm_pixel_link_sync_enable(hdp->dual_mode); -+ imx8qm_pixel_link_valid(imx_mhdp->dual_mode); -+ imx8qm_pixel_link_sync_enable(imx_mhdp->dual_mode); - } - --static int cdns_hdmi_imx_encoder_atomic_check(struct drm_encoder *encoder, -- struct drm_crtc_state *crtc_state, -- struct drm_connector_state *conn_state) -+void cdns_mhdp_pclk_rate_imx8qm(struct cdns_mhdp_device *mhdp) - { -- struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); -- -- imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB101010_1X30; -- return 0; --} -+ struct imx_mhdp_device *imx_mhdp = -+ container_of(mhdp, struct imx_mhdp_device, mhdp); - --static const struct drm_encoder_helper_funcs cdns_hdmi_imx_encoder_helper_funcs = { -- .enable = cdns_hdmi_imx_encoder_enable, -- .disable = cdns_hdmi_imx_encoder_disable, -- .atomic_check = cdns_hdmi_imx_encoder_atomic_check, --}; -- --static const struct drm_encoder_funcs cdns_hdmi_imx_encoder_funcs = { -- .destroy = drm_encoder_cleanup, --}; -- --#if 0 --static struct cdn_plat_data imx8mq_hdmi_drv_data = { -- .bind = cdns_hdmi_bind, -- .unbind = cdns_hdmi_unbind, -- .phy_init = cdns_hdmi_phy_set_imx8mq, --}; -- --static struct cdn_plat_data imx8mq_dp_drv_data = { -- .bind = cdns_dp_bind, -- .unbind = cdns_dp_unbind, -- .phy_init = cdns_dp_phy_init_imx8mq, --}; --#endif -- --static struct cdn_plat_data imx8qm_hdmi_drv_data = { -- .bind = cdns_hdmi_bind, -- .unbind = cdns_hdmi_unbind, -- .phy_init = cdns_hdmi_phy_set_imx8qm, -- .fw_init = imx8qm_firmware_init, -- .pclock_change = imx8qm_pixel_clk_rate_change, --}; -- --static struct cdn_plat_data imx8qm_dp_drv_data = { -- .bind = cdns_dp_bind, -- .unbind = cdns_dp_unbind, -- .phy_init = cdns_dp_phy_init_imx8qm, -- .fw_init = imx8qm_firmware_init, -- .pclock_change = imx8qm_pixel_clk_rate_change, -- .is_dp = true, --}; -- --static const struct of_device_id cdns_hdmi_imx_dt_ids[] = { --#if 0 -- { .compatible = "cdn,imx8mq-hdmi", -- .data = &imx8mq_hdmi_drv_data -- }, -- { .compatible = "cdn,imx8mq-dp", -- .data = &imx8mq_dp_drv_data -- }, --#endif -- { .compatible = "cdn,imx8qm-hdmi", -- .data = &imx8qm_hdmi_drv_data -- }, -- { .compatible = "cdn,imx8qm-dp", -- .data = &imx8qm_dp_drv_data -- }, -- {}, --}; --MODULE_DEVICE_TABLE(of, cdns_hdmi_imx_dt_ids); -- --static int cdns_hdmi_imx_bind(struct device *dev, struct device *master, -- void *data) --{ -- struct platform_device *pdev = to_platform_device(dev); -- const struct cdn_plat_data *plat_data; -- const struct of_device_id *match; -- struct drm_device *drm = data; -- struct drm_encoder *encoder; -- struct imx_hdmi *hdmi; -- int ret; -+ /* set pixel clock before video mode setup */ -+ imx8qm_pixel_clk_disable(imx_mhdp); - -- if (!pdev->dev.of_node) -- return -ENODEV; -+ imx8qm_pixel_clk_set_rate(imx_mhdp, imx_mhdp->mhdp.mode.clock * 1000); - -- hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); -- if (!hdmi) -- return -ENOMEM; -- -- match = of_match_node(cdns_hdmi_imx_dt_ids, pdev->dev.of_node); -- plat_data = match->data; -- hdmi->dev = &pdev->dev; -- encoder = &hdmi->encoder; -- -- encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); -- /* -- * If we failed to find the CRTC(s) which this encoder is -- * supposed to be connected to, it's because the CRTC has -- * not been registered yet. Defer probing, and hope that -- * the required CRTC is added later. -- */ -- if (encoder->possible_crtcs == 0) -- return -EPROBE_DEFER; -- -- drm_encoder_helper_add(encoder, &cdns_hdmi_imx_encoder_helper_funcs); -- drm_encoder_init(drm, encoder, &cdns_hdmi_imx_encoder_funcs, -- DRM_MODE_ENCODER_TMDS, NULL); -- -- ret = plat_data->bind(pdev, encoder, plat_data); -- -- /* -- * If cdns_hdmi_bind() fails we'll never call cdns_hdmi_unbind(), -- * which would have called the encoder cleanup. Do it manually. -- */ -- if (ret) -- drm_encoder_cleanup(encoder); -+ imx8qm_pixel_clk_enable(imx_mhdp); - -- return ret; -+ /* Config pixel link mux */ -+ imx8qm_pixel_link_mux(imx_mhdp); - } - --static void cdns_hdmi_imx_unbind(struct device *dev, struct device *master, -- void *data) -+int cdns_mhdp_firmware_init_imx8qm(struct cdns_mhdp_device *mhdp) - { -- struct imx_mhdp_device *hdp = dev_get_drvdata(dev); -+ struct imx_mhdp_device *imx_mhdp = -+ container_of(mhdp, struct imx_mhdp_device, mhdp); -+ u32 rate; -+ int ret; - -- hdp->plat_data->unbind(dev); --} -+ imx8qm_mhdp_power_on(mhdp); - --static const struct component_ops cdns_hdmi_imx8qm_ops = { -- .bind = cdns_hdmi_imx_bind, -- .unbind = cdns_hdmi_imx_unbind, --}; -+ /* configure HDMI/DP core clock */ -+ rate = clk_get_rate(imx_mhdp->clks.clk_core); -+ cdns_mhdp_set_fw_clk(&imx_mhdp->mhdp, rate); - --static int cdns_hdmi_imx_probe(struct platform_device *pdev) --{ -- return component_add(&pdev->dev, &cdns_hdmi_imx8qm_ops); --} -+ /* un-reset ucpu */ -+ cdns_mhdp_bus_write(0, &imx_mhdp->mhdp, APB_CTRL); -+ DRM_INFO("Started firmware!\n"); - --static int cdns_hdmi_imx_remove(struct platform_device *pdev) --{ -- component_del(&pdev->dev, &cdns_hdmi_imx8qm_ops); -+ ret = cdns_mhdp_check_alive(&imx_mhdp->mhdp); -+ if (ret == false) { -+ DRM_ERROR("NO HDMI FW running\n"); -+ return -ENXIO; -+ } -+ -+ /* turn on IP activity */ -+ cdns_mhdp_set_firmware_active(&imx_mhdp->mhdp, 1); -+ -+ DRM_INFO("HDP FW Version - ver %d verlib %d\n", -+ cdns_mhdp_bus_read(mhdp, VER_L) + (cdns_mhdp_bus_read(mhdp, VER_H) << 8), -+ cdns_mhdp_bus_read(mhdp, VER_LIB_H_ADDR) + (cdns_mhdp_bus_read(mhdp, VER_LIB_H_ADDR) << 8)); - - return 0; - } -- --static struct platform_driver cdns_hdmi_imx_platform_driver = { -- .probe = cdns_hdmi_imx_probe, -- .remove = cdns_hdmi_imx_remove, -- .driver = { -- .name = "cdn-hdp-imx8qm", -- .of_match_table = cdns_hdmi_imx_dt_ids, -- }, --}; -- --module_platform_driver(cdns_hdmi_imx_platform_driver); -- --MODULE_AUTHOR("Sandor YU "); --MODULE_LICENSE("GPL"); --MODULE_ALIAS("platform:cdnhdmi-imx"); ---- /dev/null -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -@@ -0,0 +1,202 @@ -+/* -+ * copyright (c) 2019 nxp semiconductor, inc. -+ * -+ * this program is free software; you can redistribute it and/or modify -+ * it under the terms of the gnu general public license version 2 as -+ * published by the free software foundation. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "cdns-mhdp-imx.h" -+#include "cdn-mhdp-phy.h" -+#include "imx-drm.h" -+ -+static void cdns_mhdp_imx_encoder_disable(struct drm_encoder *encoder) -+{ -+ struct cdns_mhdp_device *mhdp = encoder->bridge->driver_private; -+ -+ cdns_mhdp_plat_call(mhdp, plat_init); -+} -+ -+static void cdns_mhdp_imx_encoder_enable(struct drm_encoder *encoder) -+{ -+ struct cdns_mhdp_device *mhdp = encoder->bridge->driver_private; -+ -+ cdns_mhdp_plat_call(mhdp, plat_deinit); -+} -+ -+static int cdns_mhdp_imx_encoder_atomic_check(struct drm_encoder *encoder, -+ struct drm_crtc_state *crtc_state, -+ struct drm_connector_state *conn_state) -+{ -+ struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); -+ struct cdns_mhdp_device *mhdp = encoder->bridge->driver_private; -+ -+ if (mhdp->plat_data->video_format != 0) -+ imx_crtc_state->bus_format = mhdp->plat_data->video_format; -+ return 0; -+} -+ -+static const struct drm_encoder_helper_funcs cdns_mhdp_imx_encoder_helper_funcs = { -+ .enable = cdns_mhdp_imx_encoder_enable, -+ .disable = cdns_mhdp_imx_encoder_disable, -+ .atomic_check = cdns_mhdp_imx_encoder_atomic_check, -+}; -+ -+static const struct drm_encoder_funcs cdns_mhdp_imx_encoder_funcs = { -+ .destroy = drm_encoder_cleanup, -+}; -+ -+static struct cdns_plat_data imx8mq_hdmi_drv_data = { -+ .bind = cdns_hdmi_bind, -+ .unbind = cdns_hdmi_unbind, -+ .phy_set = cdns_hdmi_phy_set_imx8mq, -+ .bus_type = BUS_TYPE_NORMAL_APB, -+}; -+ -+static struct cdns_plat_data imx8mq_dp_drv_data = { -+ .bind = cdns_dp_bind, -+ .unbind = cdns_dp_unbind, -+ .phy_set = cdns_dp_phy_set_imx8mq, -+ .bus_type = BUS_TYPE_NORMAL_APB, -+}; -+ -+static struct cdns_plat_data imx8qm_hdmi_drv_data = { -+ .bind = cdns_hdmi_bind, -+ .unbind = cdns_hdmi_unbind, -+ .phy_set = cdns_hdmi_phy_set_imx8qm, -+ .firmware_init = cdns_mhdp_firmware_init_imx8qm, -+ .pclk_rate = cdns_mhdp_pclk_rate_imx8qm, -+ .plat_init = cdns_mhdp_plat_init_imx8qm, -+ .plat_deinit = cdns_mhdp_plat_deinit_imx8qm, -+ .bus_type = BUS_TYPE_LOW4K_APB, -+ .video_format = MEDIA_BUS_FMT_RGB101010_1X30, -+}; -+ -+static struct cdns_plat_data imx8qm_dp_drv_data = { -+ .bind = cdns_dp_bind, -+ .unbind = cdns_dp_unbind, -+ .phy_set = cdns_dp_phy_set_imx8qm, -+ .firmware_init = cdns_mhdp_firmware_init_imx8qm, -+ .pclk_rate = cdns_mhdp_pclk_rate_imx8qm, -+ .plat_init = cdns_mhdp_plat_init_imx8qm, -+ .plat_deinit = cdns_mhdp_plat_deinit_imx8qm, -+ .bus_type = BUS_TYPE_LOW4K_APB, -+ .video_format = MEDIA_BUS_FMT_RGB101010_1X30, -+ .is_dp = true, -+}; -+ -+static const struct of_device_id cdns_mhdp_imx_dt_ids[] = { -+ { .compatible = "cdn,imx8mq-hdmi", -+ .data = &imx8mq_hdmi_drv_data -+ }, -+ { .compatible = "cdn,imx8mq-dp", -+ .data = &imx8mq_dp_drv_data -+ }, -+ { .compatible = "cdn,imx8qm-hdmi", -+ .data = &imx8qm_hdmi_drv_data -+ }, -+ { .compatible = "cdn,imx8qm-dp", -+ .data = &imx8qm_dp_drv_data -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, cdns_mhdp_imx_dt_ids); -+ -+static int cdns_mhdp_imx_bind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct platform_device *pdev = to_platform_device(dev); -+ const struct cdns_plat_data *plat_data; -+ const struct of_device_id *match; -+ struct drm_device *drm = data; -+ struct drm_encoder *encoder; -+ struct imx_mhdp_device *imx_mhdp; -+ int ret; -+ -+ if (!pdev->dev.of_node) -+ return -ENODEV; -+ -+ imx_mhdp = devm_kzalloc(&pdev->dev, sizeof(*imx_mhdp), GFP_KERNEL); -+ if (!imx_mhdp) -+ return -ENOMEM; -+ -+ match = of_match_node(cdns_mhdp_imx_dt_ids, pdev->dev.of_node); -+ plat_data = match->data; -+ encoder = &imx_mhdp->encoder; -+ -+ encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node); -+ /* -+ * If we failed to find the CRTC(s) which this encoder is -+ * supposed to be connected to, it's because the CRTC has -+ * not been registered yet. Defer probing, and hope that -+ * the required CRTC is added later. -+ */ -+ if (encoder->possible_crtcs == 0) -+ return -EPROBE_DEFER; -+ -+ drm_encoder_helper_add(encoder, &cdns_mhdp_imx_encoder_helper_funcs); -+ drm_encoder_init(drm, encoder, &cdns_mhdp_imx_encoder_funcs, -+ DRM_MODE_ENCODER_TMDS, NULL); -+ -+ -+ imx_mhdp->mhdp.plat_data = plat_data; -+ imx_mhdp->mhdp.dev = dev; -+ imx_mhdp->mhdp.bus_type = plat_data->bus_type; -+ ret = plat_data->bind(pdev, encoder, &imx_mhdp->mhdp); -+ /* -+ * If cdns_mhdp_bind() fails we'll never call cdns_mhdp_unbind(), -+ * which would have called the encoder cleanup. Do it manually. -+ */ -+ if (ret < 0) -+ drm_encoder_cleanup(encoder); -+ -+ imx_mhdp->dual_mode = false; -+ return ret; -+} -+ -+static void cdns_mhdp_imx_unbind(struct device *dev, struct device *master, -+ void *data) -+{ -+ struct imx_mhdp_device *imx_mhdp = dev_get_drvdata(dev); -+ -+ imx_mhdp->mhdp.plat_data->unbind(dev); -+} -+ -+static const struct component_ops cdns_mhdp_imx_ops = { -+ .bind = cdns_mhdp_imx_bind, -+ .unbind = cdns_mhdp_imx_unbind, -+}; -+ -+static int cdns_mhdp_imx_probe(struct platform_device *pdev) -+{ -+ return component_add(&pdev->dev, &cdns_mhdp_imx_ops); -+} -+ -+static int cdns_mhdp_imx_remove(struct platform_device *pdev) -+{ -+ component_del(&pdev->dev, &cdns_mhdp_imx_ops); -+ -+ return 0; -+} -+ -+static struct platform_driver cdns_mhdp_imx_platform_driver = { -+ .probe = cdns_mhdp_imx_probe, -+ .remove = cdns_mhdp_imx_remove, -+ .driver = { -+ .name = "cdn-hdp-imx8qm", -+ .of_match_table = cdns_mhdp_imx_dt_ids, -+ }, -+}; -+ -+module_platform_driver(cdns_mhdp_imx_platform_driver); -+ -+MODULE_AUTHOR("Sandor YU "); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:cdnhdmi-imx"); ---- a/drivers/gpu/drm/imx/cdn-mhdp-phy.h -+++ b/drivers/gpu/drm/imx/cdn-mhdp-phy.h -@@ -10,7 +10,7 @@ - #ifndef _CDN_DP_PHY_H - #define _CDN_DP_PHY_H - --#include -+#include - - #define CMN_SSM_BIAS_TMR 0x0022 - #define CMN_PLLSM0_PLLEN_TMR 0x0029 -@@ -146,8 +146,8 @@ - #define PHY_PMA_ISO_RX_DATA_LO 0xCC16 - #define PHY_PMA_ISO_RX_DATA_HI 0xCC17 - --int cdns_dp_phy_init_imx8mq(struct imx_mhdp_device *hdp); --int cdns_dp_phy_init_imx8qm(struct imx_mhdp_device *hdp); --int cdns_hdmi_phy_set_imx8mq(struct imx_mhdp_device *hdp); --int cdns_hdmi_phy_set_imx8qm(struct imx_mhdp_device *hdp); --#endif /* _CDN_DP_PHY_H */ -+int cdns_dp_phy_set_imx8mq(struct cdns_mhdp_device *hdp); -+int cdns_dp_phy_set_imx8qm(struct cdns_mhdp_device *hdp); -+int cdns_hdmi_phy_set_imx8mq(struct cdns_mhdp_device *hdp); -+int cdns_hdmi_phy_set_imx8qm(struct cdns_mhdp_device *hdp); -+#endif /* _CDNS_MHDP_PHY_H */ ---- /dev/null -+++ b/drivers/gpu/drm/imx/cdns-mhdp-imx.h -@@ -0,0 +1,80 @@ -+/* -+ * Cadence High-Definition Multimedia Interface (HDMI) driver -+ * -+ * Copyright (C) 2019 NXP Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+#ifndef CDNS_MHDP_IMX_H_ -+#define CDNS_MHDP_IMX_H_ -+ -+#include -+#include -+ -+ -+#define HDP_DUAL_MODE_MIN_PCLK_RATE 300000 /* KHz */ -+#define HDP_SINGLE_MODE_MAX_WIDTH 1920 -+ -+static inline bool video_is_dual_mode(const struct drm_display_mode *mode) -+{ -+ return (mode->clock > HDP_DUAL_MODE_MIN_PCLK_RATE || -+ mode->hdisplay > HDP_SINGLE_MODE_MAX_WIDTH) ? true : false; -+} -+ -+struct imx_mhdp_device; -+ -+struct imx_hdp_clks { -+ struct clk *av_pll; -+ struct clk *dig_pll; -+ struct clk *clk_ipg; -+ struct clk *clk_core; -+ struct clk *clk_pxl; -+ struct clk *clk_pxl_mux; -+ struct clk *clk_pxl_link; -+ -+ struct clk *lpcg_hdp; -+ struct clk *lpcg_msi; -+ struct clk *lpcg_pxl; -+ struct clk *lpcg_vif; -+ struct clk *lpcg_lis; -+ struct clk *lpcg_apb; -+ struct clk *lpcg_apb_csr; -+ struct clk *lpcg_apb_ctrl; -+ -+ struct clk *lpcg_i2s; -+ struct clk *clk_i2s_bypass; -+}; -+ -+struct imx_mhdp_device { -+ struct cdns_mhdp_device mhdp; -+ struct drm_encoder encoder; -+ -+ struct mutex audio_mutex; -+ spinlock_t audio_lock; -+ bool connected; -+ bool active; -+ bool suspended; -+ struct imx_hdp_clks clks; -+ -+ int bus_type; -+ -+ u32 dual_mode; -+ -+ struct device *pd_mhdp_dev; -+ struct device *pd_pll0_dev; -+ struct device *pd_pll1_dev; -+ struct device_link *pd_mhdp_link; -+ struct device_link *pd_pll0_link; -+ struct device_link *pd_pll1_link; -+ -+// u32 phy_init; -+}; -+void cdns_mhdp_plat_init_imx8qm(struct cdns_mhdp_device *mhdp); -+void cdns_mhdp_plat_deinit_imx8qm(struct cdns_mhdp_device *mhdp); -+void cdns_mhdp_pclk_rate_imx8qm(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_firmware_init_imx8qm(struct cdns_mhdp_device *mhdp); -+#endif /* CDNS_MHDP_IMX_H_ */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0012-drm-rockchip-change-base-address-name-from-regs-to-r.patch b/target/linux/layerscape/patches-5.4/805-display-0012-drm-rockchip-change-base-address-name-from-regs-to-r.patch deleted file mode 100644 index bb87fbcfbd..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0012-drm-rockchip-change-base-address-name-from-regs-to-r.patch +++ /dev/null @@ -1,29 +0,0 @@ -From ef19c896ef02d33d5236ef70a53e5ca1ad06b9c9 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Wed, 11 Sep 2019 17:36:25 +0800 -Subject: [PATCH] drm: rockchip: change base address name from regs to - regs_base - -change the regs name to regs_base according the bridge druver. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/rockchip/cdn-dp-core.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/rockchip/cdn-dp-core.c -+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c -@@ -718,10 +718,10 @@ static int cdn_dp_parse_dt(struct cdn_dp - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- dp->mhdp.regs = devm_ioremap_resource(dev, res); -- if (IS_ERR(dp->mhdp.regs)) { -+ dp->mhdp.regs_base = devm_ioremap_resource(dev, res); -+ if (IS_ERR(dp->mhdp.regs_base)) { - DRM_DEV_ERROR(dev, "ioremap reg failed\n"); -- return PTR_ERR(dp->mhdp.regs); -+ return PTR_ERR(dp->mhdp.regs_base); - } - - dp->core_clk = devm_clk_get(dev, "core-clk"); diff --git a/target/linux/layerscape/patches-5.4/805-display-0013-drm-bridge-cadence-Add-power_on-to-__cdns_dp_probe.patch b/target/linux/layerscape/patches-5.4/805-display-0013-drm-bridge-cadence-Add-power_on-to-__cdns_dp_probe.patch deleted file mode 100644 index a58e75c499..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0013-drm-bridge-cadence-Add-power_on-to-__cdns_dp_probe.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 9737dd813b872f5671d40685d2174a928da809a3 Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Tue, 17 Sep 2019 15:23:51 +0800 -Subject: [PATCH] drm: bridge: cadence: Add power_on to __cdns_dp_probe - -Add power_on of the cnds_plat_data to __cdns_dp_probe as to update -Board related configuration initalization. - -Signed-off-by: Wen He ---- - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 2 ++ - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 2 ++ - drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c | 6 +++--- - drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c | 2 ++ - drivers/gpu/drm/imx/cdns-mhdp-imx.h | 1 + - 5 files changed, 10 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -457,6 +457,8 @@ static int __cdns_dp_probe(struct platfo - - cdns_dp_parse_dt(mhdp); - -+ cdns_mhdp_plat_call(mhdp, power_on); -+ - // mhdp->dual_mode = false; - cdns_mhdp_plat_call(mhdp, firmware_init); - ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -449,6 +449,8 @@ static int __cdns_hdmi_probe(struct plat - /* Initialize dual_mode to false */ - // hdmi->dual_mode = false; - -+ cdns_mhdp_plat_call(mhdp, power_on); -+ - /* Initialize FW */ - cdns_mhdp_plat_call(mhdp, firmware_init); - ---- a/drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c -@@ -440,7 +440,7 @@ fail: - return ret; - } - --static void imx8qm_mhdp_power_on(struct cdns_mhdp_device *mhdp) -+int cdns_mhdp_power_on_imx8qm(struct cdns_mhdp_device *mhdp) - { - struct imx_mhdp_device *imx_mhdp = - container_of(mhdp, struct imx_mhdp_device, mhdp); -@@ -463,6 +463,8 @@ static void imx8qm_mhdp_power_on(struct - imx8qm_pixel_clk_enable(imx_mhdp); - - imx8qm_phy_reset(1); -+ -+ return 0; - } - - void cdns_mhdp_plat_init_imx8qm(struct cdns_mhdp_device *mhdp) -@@ -506,8 +508,6 @@ int cdns_mhdp_firmware_init_imx8qm(struc - u32 rate; - int ret; - -- imx8qm_mhdp_power_on(mhdp); -- - /* configure HDMI/DP core clock */ - rate = clk_get_rate(imx_mhdp->clks.clk_core); - cdns_mhdp_set_fw_clk(&imx_mhdp->mhdp, rate); ---- a/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -@@ -71,6 +71,7 @@ static struct cdns_plat_data imx8qm_hdmi - .bind = cdns_hdmi_bind, - .unbind = cdns_hdmi_unbind, - .phy_set = cdns_hdmi_phy_set_imx8qm, -+ .power_on = cdns_mhdp_power_on_imx8qm, - .firmware_init = cdns_mhdp_firmware_init_imx8qm, - .pclk_rate = cdns_mhdp_pclk_rate_imx8qm, - .plat_init = cdns_mhdp_plat_init_imx8qm, -@@ -83,6 +84,7 @@ static struct cdns_plat_data imx8qm_dp_d - .bind = cdns_dp_bind, - .unbind = cdns_dp_unbind, - .phy_set = cdns_dp_phy_set_imx8qm, -+ .power_on = cdns_mhdp_power_on_imx8qm, - .firmware_init = cdns_mhdp_firmware_init_imx8qm, - .pclk_rate = cdns_mhdp_pclk_rate_imx8qm, - .plat_init = cdns_mhdp_plat_init_imx8qm, ---- a/drivers/gpu/drm/imx/cdns-mhdp-imx.h -+++ b/drivers/gpu/drm/imx/cdns-mhdp-imx.h -@@ -77,4 +77,5 @@ void cdns_mhdp_plat_init_imx8qm(struct c - void cdns_mhdp_plat_deinit_imx8qm(struct cdns_mhdp_device *mhdp); - void cdns_mhdp_pclk_rate_imx8qm(struct cdns_mhdp_device *mhdp); - int cdns_mhdp_firmware_init_imx8qm(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_power_on_imx8qm(struct cdns_mhdp_device *mhdp); - #endif /* CDNS_MHDP_IMX_H_ */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0014-drm-ls1028a-Add-DP-driver-support-for-LS1028A.patch b/target/linux/layerscape/patches-5.4/805-display-0014-drm-ls1028a-Add-DP-driver-support-for-LS1028A.patch deleted file mode 100644 index c84b119a4f..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0014-drm-ls1028a-Add-DP-driver-support-for-LS1028A.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 06e912bd821b21d9360a75cde2d78b03f17a5872 Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Tue, 17 Sep 2019 15:35:52 +0800 -Subject: [PATCH] drm: ls1028a: Add DP driver support for LS1028A - -Add Display Port driver support for NXP Layerscape LS1028A platform. - -Signed-off-by: Wen He ---- - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 1 + - drivers/gpu/drm/imx/Makefile | 2 +- - drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c | 13 +++ - drivers/gpu/drm/imx/cdn-mhdp-ls1028a.c | 110 ++++++++++++++++++++++++++ - drivers/gpu/drm/imx/cdns-mhdp-imx.h | 2 + - 5 files changed, 127 insertions(+), 1 deletion(-) - create mode 100644 drivers/gpu/drm/imx/cdn-mhdp-ls1028a.c - ---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -275,6 +275,7 @@ static int cdns_dp_bridge_attach(struct - struct drm_connector *connector = &mhdp->connector.base; - - connector->interlace_allowed = 1; -+ - connector->polled = DRM_CONNECTOR_POLL_HPD; - - drm_connector_helper_add(connector, &cdns_dp_connector_helper_funcs); ---- a/drivers/gpu/drm/imx/Makefile -+++ b/drivers/gpu/drm/imx/Makefile -@@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o - obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o - - obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o --obj-$(CONFIG_DRM_IMX_CDNS_MHDP) += cdn-mhdp-imxdrv.o cdn-mhdp-dp-phy.o cdn-mhdp-hdmi-phy.o cdn-mhdp-imx8qm.o -+obj-$(CONFIG_DRM_IMX_CDNS_MHDP) += cdn-mhdp-imxdrv.o cdn-mhdp-dp-phy.o cdn-mhdp-hdmi-phy.o cdn-mhdp-imx8qm.o cdn-mhdp-ls1028a.o ---- a/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -@@ -94,6 +94,16 @@ static struct cdns_plat_data imx8qm_dp_d - .is_dp = true, - }; - -+static struct cdns_plat_data ls1028a_dp_drv_data = { -+ .bind = cdns_dp_bind, -+ .unbind = cdns_dp_unbind, -+ .phy_set = cdns_dp_phy_set_imx8mq, -+ .power_on = cdns_mhdp_power_on_ls1028a, -+ .firmware_init = cdns_mhdp_firmware_init_imx8qm, -+ .pclk_rate = cdns_mhdp_pclk_rate_ls1028a, -+ .bus_type = BUS_TYPE_NORMAL_APB, -+}; -+ - static const struct of_device_id cdns_mhdp_imx_dt_ids[] = { - { .compatible = "cdn,imx8mq-hdmi", - .data = &imx8mq_hdmi_drv_data -@@ -107,6 +117,9 @@ static const struct of_device_id cdns_mh - { .compatible = "cdn,imx8qm-dp", - .data = &imx8qm_dp_drv_data - }, -+ { .compatible = "cdn,ls1028a-dp", -+ .data = &ls1028a_dp_drv_data -+ }, - {}, - }; - MODULE_DEVICE_TABLE(of, cdns_mhdp_imx_dt_ids); ---- /dev/null -+++ b/drivers/gpu/drm/imx/cdn-mhdp-ls1028a.c -@@ -0,0 +1,110 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * Copyright 2019 NXP -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include "cdns-mhdp-imx.h" -+ -+static const struct of_device_id scfg_device_ids[] = { -+ { .compatible = "fsl,ls1028a-scfg", }, -+ {} -+}; -+ -+static void ls1028a_phy_reset(u8 reset) -+{ -+ struct device_node *scfg_node; -+ void __iomem *scfg_base = NULL; -+ -+ scfg_node = of_find_matching_node(NULL, scfg_device_ids); -+ if (scfg_node) -+ scfg_base = of_iomap(scfg_node, 0); -+ -+ iowrite32(reset, scfg_base + 0x230); -+} -+ -+int ls1028a_clocks_init(struct imx_mhdp_device *imx_mhdp) -+{ -+ struct device *dev = imx_mhdp->mhdp.dev; -+ struct imx_hdp_clks *clks = &imx_mhdp->clks; -+ -+ clks->clk_core = devm_clk_get(dev, "clk_core"); -+ if (IS_ERR(clks->clk_core)) { -+ dev_warn(dev, "failed to get hdp core clk\n"); -+ return PTR_ERR(clks->clk_core); -+ } -+ -+ clks->clk_pxl = devm_clk_get(dev, "clk_pxl"); -+ if (IS_ERR(clks->clk_pxl)) { -+ dev_warn(dev, "failed to get pxl clk\n"); -+ return PTR_ERR(clks->clk_pxl); -+ } -+ -+ return true; -+} -+ -+static int ls1028a_pixel_clk_enable(struct imx_mhdp_device *imx_mhdp) -+{ -+ struct imx_hdp_clks *clks = &imx_mhdp->clks; -+ struct device *dev = imx_mhdp->mhdp.dev; -+ int ret; -+ -+ ret = clk_prepare_enable(clks->clk_pxl); -+ if (ret < 0) { -+ dev_err(dev, "%s, pre clk pxl error\n", __func__); -+ return ret; -+ } -+ -+ return ret; -+} -+ -+static void ls1028a_pixel_clk_disable(struct imx_mhdp_device *imx_mhdp) -+{ -+ struct imx_hdp_clks *clks = &imx_mhdp->clks; -+ -+ clk_disable_unprepare(clks->clk_pxl); -+} -+ -+static void ls1028a_pixel_clk_set_rate(struct imx_mhdp_device *imx_mhdp, -+ u32 pclock) -+{ -+ struct imx_hdp_clks *clks = &imx_mhdp->clks; -+ -+ clk_set_rate(clks->clk_pxl, pclock); -+} -+ -+int cdns_mhdp_power_on_ls1028a(struct cdns_mhdp_device *mhdp) -+{ -+ struct imx_mhdp_device *imx_mhdp = container_of -+ (mhdp, struct imx_mhdp_device, mhdp); -+ -+ /* clock init and rate set */ -+ ls1028a_clocks_init(imx_mhdp); -+ -+ ls1028a_pixel_clk_enable(imx_mhdp); -+ -+ /* Init pixel clock with 148.5MHz before FW init */ -+ ls1028a_pixel_clk_set_rate(imx_mhdp, 148500000); -+ -+ ls1028a_phy_reset(1); -+ -+ return 0; -+} -+ -+void cdns_mhdp_pclk_rate_ls1028a(struct cdns_mhdp_device *mhdp) -+{ -+ struct imx_mhdp_device *imx_mhdp = container_of -+ (mhdp, struct imx_mhdp_device, mhdp); -+ -+ /* set pixel clock before video mode setup */ -+ ls1028a_pixel_clk_disable(imx_mhdp); -+ -+ ls1028a_pixel_clk_set_rate(imx_mhdp, imx_mhdp->mhdp.mode.clock * 1000); -+ -+ ls1028a_pixel_clk_enable(imx_mhdp); -+} ---- a/drivers/gpu/drm/imx/cdns-mhdp-imx.h -+++ b/drivers/gpu/drm/imx/cdns-mhdp-imx.h -@@ -78,4 +78,6 @@ void cdns_mhdp_plat_deinit_imx8qm(struct - void cdns_mhdp_pclk_rate_imx8qm(struct cdns_mhdp_device *mhdp); - int cdns_mhdp_firmware_init_imx8qm(struct cdns_mhdp_device *mhdp); - int cdns_mhdp_power_on_imx8qm(struct cdns_mhdp_device *mhdp); -+int cdns_mhdp_power_on_ls1028a(struct cdns_mhdp_device *mhdp); -+void cdns_mhdp_pclk_rate_ls1028a(struct cdns_mhdp_device *mhdp); - #endif /* CDNS_MHDP_IMX_H_ */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0015-drm-bridge-cadence-Add-support-for-periodically-poll.patch b/target/linux/layerscape/patches-5.4/805-display-0015-drm-bridge-cadence-Add-support-for-periodically-poll.patch deleted file mode 100644 index 80dc0cc3e5..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0015-drm-bridge-cadence-Add-support-for-periodically-poll.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 35e2ec234646f04eb0e17e4c3a4cf21faed3655a Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Wed, 18 Sep 2019 11:05:31 +0800 -Subject: [PATCH] drm: bridge: cadence: Add support for periodically poll the - connector - -Normally, DP/HDMI PHY use HPD_IRQ to monitor the connector connection -status, but LS1028A doesn't support HPD_IRQ signals response. - -This patch allows periodically poll the connector for connection and -disconnection. - -Signed-off-by: Wen He ---- - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 86 +++++++++++++++++---------- - include/drm/bridge/cdns-mhdp-common.h | 1 + - 2 files changed, 54 insertions(+), 33 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -276,7 +276,11 @@ static int cdns_dp_bridge_attach(struct - - connector->interlace_allowed = 1; - -- connector->polled = DRM_CONNECTOR_POLL_HPD; -+ if (mhdp->is_hpd) -+ connector->polled = DRM_CONNECTOR_POLL_HPD; -+ else -+ connector->polled = DRM_CONNECTOR_POLL_CONNECT | -+ DRM_CONNECTOR_POLL_DISCONNECT; - - drm_connector_helper_add(connector, &cdns_dp_connector_helper_funcs); - -@@ -439,22 +443,34 @@ static int __cdns_dp_probe(struct platfo - INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func); - - iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- mhdp->regs_base = devm_ioremap(dev, iores->start, resource_size(iores)); -- if (IS_ERR(mhdp->regs_base)) -- return -ENOMEM; -+ if (iores) { -+ mhdp->regs_base = devm_ioremap(dev, iores->start, -+ resource_size(iores)); -+ if (IS_ERR(mhdp->regs_base)) -+ return -ENOMEM; -+ } - - iores = platform_get_resource(pdev, IORESOURCE_MEM, 1); -- mhdp->regs_sec = devm_ioremap(dev, iores->start, resource_size(iores)); -- if (IS_ERR(mhdp->regs_sec)) -- return -ENOMEM; -+ if (iores) { -+ mhdp->regs_sec = devm_ioremap(dev, iores->start, -+ resource_size(iores)); -+ if (IS_ERR(mhdp->regs_sec)) -+ return -ENOMEM; -+ } -+ -+ mhdp->is_hpd = true; - - mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in"); -- if (mhdp->irq[IRQ_IN] < 0) -+ if (mhdp->irq[IRQ_IN] < 0) { -+ mhdp->is_hpd = false; - dev_info(dev, "No plug_in irq number\n"); -+ } - - mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out"); -- if (mhdp->irq[IRQ_OUT] < 0) -+ if (mhdp->irq[IRQ_OUT] < 0) { -+ mhdp->is_hpd = false; - dev_info(dev, "No plug_out irq number\n"); -+ } - - cdns_dp_parse_dt(mhdp); - -@@ -474,33 +490,37 @@ static int __cdns_dp_probe(struct platfo - cdns_mhdp_plat_call(mhdp, phy_set); - - /* Enable Hotplug Detect IRQ thread */ -- irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN); -- ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN], -- NULL, cdns_dp_irq_thread, -- IRQF_ONESHOT, dev_name(dev), -- mhdp); -- if (ret) { -- dev_err(dev, "can't claim irq %d\n", -- mhdp->irq[IRQ_IN]); -- return -EINVAL; -- } -+ if (mhdp->is_hpd) { -+ irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN], -+ NULL, cdns_dp_irq_thread, -+ IRQF_ONESHOT, dev_name(dev), -+ mhdp); - -- irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN); -- ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT], -- NULL, cdns_dp_irq_thread, -- IRQF_ONESHOT, dev_name(dev), -- mhdp); -- if (ret) { -- dev_err(dev, "can't claim irq %d\n", -- mhdp->irq[IRQ_OUT]); -- return -EINVAL; -+ if (ret) { -+ dev_err(dev, "can't claim irq %d\n", -+ mhdp->irq[IRQ_IN]); -+ return -EINVAL; -+ } -+ -+ irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN); -+ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT], -+ NULL, cdns_dp_irq_thread, -+ IRQF_ONESHOT, dev_name(dev), -+ mhdp); -+ -+ if (ret) { -+ dev_err(dev, "can't claim irq %d\n", -+ mhdp->irq[IRQ_OUT]); -+ return -EINVAL; -+ } -+ -+ if (cdns_mhdp_read_hpd(mhdp)) -+ enable_irq(mhdp->irq[IRQ_OUT]); -+ else -+ enable_irq(mhdp->irq[IRQ_IN]); - } - -- if (cdns_mhdp_read_hpd(mhdp)) -- enable_irq(mhdp->irq[IRQ_OUT]); -- else -- enable_irq(mhdp->irq[IRQ_IN]); -- - mhdp->bridge.base.driver_private = mhdp; - mhdp->bridge.base.funcs = &cdns_dp_bridge_funcs; - #ifdef CONFIG_OF ---- a/include/drm/bridge/cdns-mhdp-common.h -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -683,6 +683,7 @@ struct cdns_mhdp_device { - bool link_up; - bool power_up; - bool plugged; -+ bool is_hpd; - struct mutex lock; - - int irq[IRQ_NUM]; diff --git a/target/linux/layerscape/patches-5.4/805-display-0016-drm-imx-hdmi-support-arc-function.patch b/target/linux/layerscape/patches-5.4/805-display-0016-drm-imx-hdmi-support-arc-function.patch deleted file mode 100644 index a8876d0126..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0016-drm-imx-hdmi-support-arc-function.patch +++ /dev/null @@ -1,87 +0,0 @@ -From a10d0b8516bc3f48f0c1005f8e69efce12cea8f9 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Mon, 23 Sep 2019 09:09:38 +0800 -Subject: [PATCH] drm: imx: hdmi: support arc function - -Add HDMI ARC configurate function. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c | 59 +++++++++++++++++++++++++++++++++ - 1 file changed, 59 insertions(+) - ---- a/drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c -@@ -192,6 +192,62 @@ static const struct hdmi_pll_tuning imx8 - { 7, 5200000, 6000000, 0x7, 0x1, 0x0, 0x04, 0x0D, 680, 0x04F, 0, 0, 0 } - }; - -+static void hdmi_arc_config(struct cdns_mhdp_device *mhdp) -+{ -+ u16 txpu_calib_code; -+ u16 txpd_calib_code; -+ u16 txpu_adj_calib_code; -+ u16 txpd_adj_calib_code; -+ u16 prev_calib_code; -+ u16 new_calib_code; -+ u16 rdata; -+ -+ /* Power ARC */ -+ cdns_phy_reg_write(mhdp, TXDA_CYA_AUXDA_CYA, 0x0001); -+ -+ prev_calib_code = cdns_phy_reg_read(mhdp, TX_DIG_CTRL_REG_2); -+ txpu_calib_code = cdns_phy_reg_read(mhdp, CMN_TXPUCAL_CTRL); -+ txpd_calib_code = cdns_phy_reg_read(mhdp, CMN_TXPDCAL_CTRL); -+ txpu_adj_calib_code = cdns_phy_reg_read(mhdp, CMN_TXPU_ADJ_CTRL); -+ txpd_adj_calib_code = cdns_phy_reg_read(mhdp, CMN_TXPD_ADJ_CTRL); -+ -+ new_calib_code = ((txpu_calib_code + txpd_calib_code) / 2) -+ + txpu_adj_calib_code + txpd_adj_calib_code; -+ -+ if (new_calib_code != prev_calib_code) { -+ rdata = cdns_phy_reg_read(mhdp, TX_ANA_CTRL_REG_1); -+ rdata &= 0xDFFF; -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_1, rdata); -+ cdns_phy_reg_write(mhdp, TX_DIG_CTRL_REG_2, new_calib_code); -+ mdelay(10); -+ rdata |= 0x2000; -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_1, rdata); -+ udelay(150); -+ } -+ -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_2, 0x0100); -+ udelay(100); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_2, 0x0300); -+ udelay(100); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_3, 0x0000); -+ udelay(100); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_1, 0x2008); -+ udelay(100); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_1, 0x2018); -+ udelay(100); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_1, 0x2098); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_2, 0x030C); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_5, 0x0010); -+ udelay(100); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_4, 0x4001); -+ mdelay(5); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_1, 0x2198); -+ mdelay(5); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_2, 0x030D); -+ udelay(100); -+ cdns_phy_reg_write(mhdp, TX_ANA_CTRL_REG_2, 0x030F); -+} -+ - static void hdmi_phy_set_vswing(struct cdns_mhdp_device *mhdp) - { - const u32 num_lanes = 4; -@@ -604,6 +660,9 @@ static int hdmi_phy_power_up(struct cdns - return -1; - } - -+ /* Power up ARC */ -+ hdmi_arc_config(mhdp); -+ - /* Configure PHY in A0 mode (PHY must be in the A0 power - * state in order to transmit data) - */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0017-drm-bridge-cadence-Fix-return-value-for-set-log-addr.patch b/target/linux/layerscape/patches-5.4/805-display-0017-drm-bridge-cadence-Fix-return-value-for-set-log-addr.patch deleted file mode 100644 index 19e14bd392..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0017-drm-bridge-cadence-Fix-return-value-for-set-log-addr.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ce1e8ad4a303526026e56822a105ed45a19e6572 Mon Sep 17 00:00:00 2001 -From: Shengjiu Wang -Date: Thu, 26 Sep 2019 17:46:04 +0800 -Subject: [PATCH] drm: bridge: cadence: Fix return value for set log addr - -Fix return value for set log addr with cec - -Signed-off-by: Shengjiu Wang ---- - drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c -@@ -183,18 +183,18 @@ static int mhdp_cec_set_logical_addr(str - - if ((la_reg & 0xF) == la) { - dev_warn(cec->dev, "Warning. LA already in use.\n"); -- return true; -+ return 0; - } - - la = (la & 0xF) | (1 << 4); - - mhdp_cec_write(cec, LOGICAL_ADDRESS_LA0 + (i * REG_ADDR_OFF), la); -- return true; -+ return 0; - } - - dev_warn(cec->dev, "All LA in use\n"); - -- return false; -+ return -EINVAL; - } - - static int mhdp_cec_poll_worker(void *_cec) diff --git a/target/linux/layerscape/patches-5.4/805-display-0018-drm-bridge-cdns-dp-Remove-link-rate-lanes-set-by-dev.patch b/target/linux/layerscape/patches-5.4/805-display-0018-drm-bridge-cdns-dp-Remove-link-rate-lanes-set-by-dev.patch deleted file mode 100644 index fba2ac4f02..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0018-drm-bridge-cdns-dp-Remove-link-rate-lanes-set-by-dev.patch +++ /dev/null @@ -1,251 +0,0 @@ -From 79d32025a54899fe7d82c88906c1e3ad911c498d Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Thu, 26 Sep 2019 15:46:43 +0800 -Subject: [PATCH] drm: bridge: cdns dp: Remove link rate/lanes set by device - tree - -Get the link rate and lanes from sink device. -Remove user specific set by device tree. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 56 ++++++----------------- - drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 6 +-- - drivers/gpu/drm/rockchip/cdn-dp-core.c | 27 ++++++----- - drivers/gpu/drm/rockchip/cdn-dp-core.h | 1 - - include/drm/bridge/cdns-mhdp-common.h | 6 +-- - 5 files changed, 35 insertions(+), 61 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -111,10 +111,10 @@ static void dp_pixel_clk_reset(struct cd - static void cdns_dp_mode_set(struct cdns_mhdp_device *mhdp, - const struct drm_display_mode *mode) - { -- struct drm_dp_link link; - u32 lane_mapping = mhdp->lane_mapping; -- int ret; -+ struct drm_dp_link *link = &mhdp->dp.link; - char linkid[6]; -+ int ret; - - memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode)); - -@@ -125,8 +125,6 @@ static void cdns_dp_mode_set(struct cdns - - cdns_mhdp_plat_call(mhdp, pclk_rate); - -- cdns_mhdp_plat_call(mhdp, phy_set); -- - ret = drm_dp_downstream_id(&mhdp->dp.aux, linkid); - if (ret < 0) { - DRM_INFO("Failed to Get DP link ID: %d\n", ret); -@@ -137,35 +135,28 @@ static void cdns_dp_mode_set(struct cdns - linkid[5]); - - /* Check dp link */ -- ret = drm_dp_link_probe(&mhdp->dp.aux, &link); -+ ret = drm_dp_link_probe(&mhdp->dp.aux, link); - if (ret < 0) { - DRM_INFO("Failed to probe DP link: %d\n", ret); - return; - } -- DRM_INFO("DP revision: 0x%x\n", link.revision); -- DRM_INFO("DP rate: %d Mbps\n", link.rate); -- DRM_INFO("DP number of lanes: %d\n", link.num_lanes); -- DRM_INFO("DP capabilities: 0x%lx\n", link.capabilities); -+ DRM_INFO("DP revision: 0x%x\n", link->revision); -+ DRM_INFO("DP rate: %d Mbps\n", link->rate); -+ DRM_INFO("DP number of lanes: %d\n", link->num_lanes); -+ DRM_INFO("DP capabilities: 0x%lx\n", link->capabilities); -+ -+ /* check the max link rate */ -+ if (link->rate > CDNS_DP_MAX_LINK_RATE) -+ link->rate = CDNS_DP_MAX_LINK_RATE; - -- drm_dp_link_power_up(&mhdp->dp.aux, &mhdp->dp.link); -+ drm_dp_link_power_up(&mhdp->dp.aux, link); - if (ret < 0) { - DRM_INFO("Failed to power DP link: %d\n", ret); - return; - } - -- /* always use the number of lanes from the display*/ -- mhdp->dp.link.num_lanes = link.num_lanes; -- -- /* Use the lower link rate */ -- if (mhdp->dp.link_rate != 0) { -- mhdp->dp.link.rate = min(mhdp->dp.link_rate, (u32)link.rate); -- DRM_DEBUG("DP actual link rate: 0x%x\n", link.rate); -- } -- -- /* initialize phy if lanes or link rate differnt */ -- if (mhdp->dp.link.num_lanes != mhdp->dp.num_lanes || -- mhdp->dp.link.rate != mhdp->dp.link_rate) -- cdns_mhdp_plat_call(mhdp, phy_set); -+ /* Initialize link rate/num_lanes as panel max link rate/max_num_lanes */ -+ cdns_mhdp_plat_call(mhdp, phy_set); - - /* Video off */ - ret = cdns_mhdp_set_video_status(mhdp, CONTROL_VIDEO_IDLE); -@@ -178,7 +169,7 @@ static void cdns_dp_mode_set(struct cdns - cdns_mhdp_reg_write(mhdp, LANES_CONFIG, 0x00400000 | lane_mapping); - - /* Set DP host capability */ -- ret = cdns_mhdp_set_host_cap(mhdp, mhdp->dp.link.num_lanes, false); -+ ret = cdns_mhdp_set_host_cap(mhdp, false); - if (ret) { - DRM_DEV_ERROR(mhdp->dev, "Failed to set host cap %d\n", ret); - return; -@@ -412,23 +403,6 @@ static void cdns_dp_parse_dt(struct cdns - dev_warn(mhdp->dev, "Failed to get lane_mapping - using default 0xc6\n"); - } - dev_info(mhdp->dev, "lane-mapping 0x%02x\n", mhdp->lane_mapping); -- -- ret = of_property_read_u32(of_node, "link-rate", &mhdp->dp.link_rate); -- if (ret) { -- mhdp->dp.link_rate = 162000 ; -- dev_warn(mhdp->dev, "Failed to get link-rate, use default 1620MHz\n"); -- } -- dev_info(mhdp->dev, "link-rate %d\n", mhdp->dp.link_rate); -- -- ret = of_property_read_u32(of_node, "num-lanes", &mhdp->dp.num_lanes); -- if (ret) { -- mhdp->dp.num_lanes = 4; -- dev_warn(mhdp->dev, "Failed to get num_lanes - using default\n"); -- } -- dev_info(mhdp->dev, "dp_num_lanes 0x%02x\n", mhdp->dp.num_lanes); -- -- mhdp->dp.link.num_lanes = mhdp->dp.num_lanes; -- mhdp->dp.link.rate= mhdp->dp.link_rate; - } - - static int __cdns_dp_probe(struct platform_device *pdev, ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -@@ -494,13 +494,13 @@ err_set_firmware_active: - } - EXPORT_SYMBOL(cdns_mhdp_set_firmware_active); - --int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip) -+int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, bool flip) - { - u8 msg[8]; - int ret; - -- msg[0] = CDNS_DP_MAX_LINK_RATE; -- msg[1] = lanes | SCRAMBLER_EN; -+ msg[0] = drm_dp_link_rate_to_bw_code(mhdp->dp.link.rate); -+ msg[1] = mhdp->dp.link.num_lanes | SCRAMBLER_EN; - msg[2] = VOLTAGE_LEVEL_2; - msg[3] = PRE_EMPHASIS_LEVEL_3; - msg[4] = PTS1 | PTS2 | PTS3 | PTS4; ---- a/drivers/gpu/drm/rockchip/cdn-dp-core.c -+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c -@@ -306,12 +306,10 @@ static int cdn_dp_connector_mode_valid(s - requested = mode->clock * bpc * 3 / 1000; - - source_max = dp->lanes; -- sink_max = drm_dp_max_lane_count(dp->dpcd); -+ sink_max = dp->mhdp.dp.link.num_lanes; - lanes = min(source_max, sink_max); - -- source_max = drm_dp_bw_code_to_link_rate(CDNS_DP_MAX_LINK_RATE); -- sink_max = drm_dp_max_link_rate(dp->dpcd); -- rate = min(source_max, sink_max); -+ rate = dp->mhdp.dp.link.rate; - - actual = rate * lanes / 100; - -@@ -366,21 +364,25 @@ static int cdn_dp_firmware_init(struct c - - static int cdn_dp_get_sink_capability(struct cdn_dp_device *dp) - { -+ struct cdns_mhdp_device *mhdp = &dp->mhdp; -+ struct drm_dp_link *link = &mhdp->dp.link; - int ret; - - if (!cdn_dp_check_sink_connection(dp)) - return -ENODEV; - -- ret = cdns_mhdp_dpcd_read(&dp->mhdp, DP_DPCD_REV, dp->dpcd, -- DP_RECEIVER_CAP_SIZE); -+ ret = drm_dp_link_probe(&mhdp->dp.aux, link); - if (ret) { -- DRM_DEV_ERROR(dp->mhdp.dev, "Failed to get caps %d\n", ret); -+ DRM_DEV_ERROR(mhdp->dev, "Failed to get caps %d\n", ret); - return ret; - } - -+ if (link->rate > CDNS_DP_MAX_LINK_RATE) -+ link->rate = CDNS_DP_MAX_LINK_RATE; -+ - kfree(dp->edid); -- dp->edid = drm_do_get_edid(&dp->mhdp.connector.base, -- cdns_mhdp_get_edid_block, &dp->mhdp); -+ dp->edid = drm_do_get_edid(&mhdp->connector.base, -+ cdns_mhdp_get_edid_block, mhdp); - return 0; - } - -@@ -422,7 +424,8 @@ static int cdn_dp_enable_phy(struct cdn_ - } - - port->lanes = cdn_dp_get_port_lanes(port); -- ret = cdns_mhdp_set_host_cap(&dp->mhdp, port->lanes, property.intval); -+ dp->mhdp.dp.link.num_lanes = port->lanes; -+ ret = cdns_mhdp_set_host_cap(&dp->mhdp, property.intval); - if (ret) { - DRM_DEV_ERROR(dev, "set host capabilities failed: %d\n", - ret); -@@ -577,9 +580,9 @@ static bool cdn_dp_check_link_status(str - { - u8 link_status[DP_LINK_STATUS_SIZE]; - struct cdn_dp_port *port = cdn_dp_connected_port(dp); -- u8 sink_lanes = drm_dp_max_lane_count(dp->dpcd); -+ u8 sink_lanes = dp->mhdp.dp.link.num_lanes; - -- if (!port || !dp->mhdp.dp.link.rate || !dp->mhdp.dp.link.num_lanes) -+ if (!port || !dp->mhdp.dp.link.rate || !sink_lanes) - return false; - - if (cdns_mhdp_dpcd_read(&dp->mhdp, DP_LANE0_1_STATUS, link_status, ---- a/drivers/gpu/drm/rockchip/cdn-dp-core.h -+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h -@@ -61,7 +61,6 @@ struct cdn_dp_device { - u8 lanes; - int active_port; - -- u8 dpcd[DP_RECEIVER_CAP_SIZE]; - bool sink_has_audio; - }; - #endif /* _CDN_DP_CORE_H */ ---- a/include/drm/bridge/cdns-mhdp-common.h -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -436,7 +436,7 @@ - #define HDCP_TX_IS_RECEIVER_ID_VALID_EVENT BIT(7) - - #define TU_SIZE 30 --#define CDNS_DP_MAX_LINK_RATE DP_LINK_BW_5_4 -+#define CDNS_DP_MAX_LINK_RATE 540000 - - #define F_HDMI_ENCODING(x) (((x) & ((1 << 2) - 1)) << 16) - #define F_VIF_DATA_WIDTH(x) (((x) & ((1 << 2) - 1)) << 2) -@@ -697,8 +697,6 @@ struct cdns_mhdp_device { - struct cdns_mhdp_mst_cbs cbs; - bool is_mst; - bool can_mst; -- u32 link_rate; -- u32 num_lanes; - } dp; - struct _hdmi_data { - #ifdef CONFIG_DRM_CDNS_HDMI_CEC -@@ -720,7 +718,7 @@ u32 cdns_mhdp_get_fw_clk(struct cdns_mhd - int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem, - u32 i_size, const u32 *d_mem, u32 d_size); - int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable); --int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, u8 lanes, bool flip); -+int cdns_mhdp_set_host_cap(struct cdns_mhdp_device *mhdp, bool flip); - int cdns_mhdp_event_config(struct cdns_mhdp_device *mhdp); - u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp); - int cdns_mhdp_get_hpd_status(struct cdns_mhdp_device *mhdp); diff --git a/target/linux/layerscape/patches-5.4/805-display-0019-drm-imx-mhdp-add-dual-mode-support-for-imx8qm.patch b/target/linux/layerscape/patches-5.4/805-display-0019-drm-imx-mhdp-add-dual-mode-support-for-imx8qm.patch deleted file mode 100644 index 689e573a9a..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0019-drm-imx-mhdp-add-dual-mode-support-for-imx8qm.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 8e4cbfc8b1b86479a4bc64d6034449096d0af3a1 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Thu, 26 Sep 2019 17:00:26 +0800 -Subject: [PATCH] drm: imx: mhdp: add dual mode support for imx8qm - -Add dual mode support for imx8qm. -imx8qm hdmi/dp driver are ready to support 4K. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 4 ---- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 6 ----- - drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c | 30 +++++++++++++++++++------ - drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c | 3 +-- - drivers/gpu/drm/imx/cdns-mhdp-imx.h | 14 +----------- - 5 files changed, 25 insertions(+), 32 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -118,9 +118,6 @@ static void cdns_dp_mode_set(struct cdns - - memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode)); - -- //Sandor TODO --// mhdp->dual_mode = video_is_dual_mode(mode); -- - dp_pixel_clk_reset(mhdp); - - cdns_mhdp_plat_call(mhdp, pclk_rate); -@@ -450,7 +447,6 @@ static int __cdns_dp_probe(struct platfo - - cdns_mhdp_plat_call(mhdp, power_on); - --// mhdp->dual_mode = false; - cdns_mhdp_plat_call(mhdp, firmware_init); - - /* DP FW alive check */ ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -343,9 +343,6 @@ static void cdns_hdmi_bridge_mode_set(st - - memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode)); - -- //Sandor TODO --// hdmi->dual_mode = video_is_dual_mode(mode); -- - hdmi_lanes_config(mhdp); - - cdns_mhdp_plat_call(mhdp, pclk_rate); -@@ -446,9 +443,6 @@ static int __cdns_hdmi_probe(struct plat - return -EPROBE_DEFER; - } - -- /* Initialize dual_mode to false */ --// hdmi->dual_mode = false; -- - cdns_mhdp_plat_call(mhdp, power_on); - - /* Initialize FW */ ---- a/drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c -@@ -13,19 +13,32 @@ - - #include "cdns-mhdp-imx.h" - -+#define PLL_800MHZ (800000000) -+ -+#define HDP_DUAL_MODE_MIN_PCLK_RATE 300000 /* KHz */ -+#define HDP_SINGLE_MODE_MAX_WIDTH 1920 -+ - #define CSR_PIXEL_LINK_MUX_CTL 0x00 - #define CSR_PIXEL_LINK_MUX_VCP_OFFSET 5 - #define CSR_PIXEL_LINK_MUX_HCP_OFFSET 4 - --#define PLL_800MHZ (800000000) -+static bool imx8qm_video_dual_mode(struct cdns_mhdp_device *mhdp) -+{ -+ struct drm_display_mode *mode = &mhdp->mode; -+ return (mode->clock > HDP_DUAL_MODE_MIN_PCLK_RATE || -+ mode->hdisplay > HDP_SINGLE_MODE_MAX_WIDTH) ? true : false; -+} - - static void imx8qm_pixel_link_mux(struct imx_mhdp_device *imx_mhdp) - { - struct drm_display_mode *mode = &imx_mhdp->mhdp.mode; -+ bool dual_mode; - u32 val; - -+ dual_mode = imx8qm_video_dual_mode(&imx_mhdp->mhdp); -+ - val = 0x4; /* RGB */ -- if (imx_mhdp->dual_mode) -+ if (dual_mode) - val |= 0x2; /* pixel link 0 and 1 are active */ - if (mode->flags & DRM_MODE_FLAG_PVSYNC) - val |= 1 << CSR_PIXEL_LINK_MUX_VCP_OFFSET; -@@ -276,12 +289,13 @@ static void imx8qm_pixel_clk_disable(str - - static void imx8qm_pixel_clk_set_rate(struct imx_mhdp_device *imx_mhdp, u32 pclock) - { -+ bool dual_mode = imx8qm_video_dual_mode(&imx_mhdp->mhdp); - struct imx_hdp_clks *clks = &imx_mhdp->clks; - - /* pixel clock for HDMI */ - clk_set_rate(clks->av_pll, pclock); - -- if (imx_mhdp->dual_mode == true) { -+ if (dual_mode == true) { - clk_set_rate(clks->clk_pxl, pclock/2); - clk_set_rate(clks->clk_pxl_link, pclock/2); - } else { -@@ -471,18 +485,20 @@ void cdns_mhdp_plat_init_imx8qm(struct c - { - struct imx_mhdp_device *imx_mhdp = - container_of(mhdp, struct imx_mhdp_device, mhdp); -+ bool dual_mode = imx8qm_video_dual_mode(&imx_mhdp->mhdp); - -- imx8qm_pixel_link_sync_disable(imx_mhdp->dual_mode); -- imx8qm_pixel_link_invalid(imx_mhdp->dual_mode); -+ imx8qm_pixel_link_sync_disable(dual_mode); -+ imx8qm_pixel_link_invalid(dual_mode); - } - - void cdns_mhdp_plat_deinit_imx8qm(struct cdns_mhdp_device *mhdp) - { - struct imx_mhdp_device *imx_mhdp = - container_of(mhdp, struct imx_mhdp_device, mhdp); -+ bool dual_mode = imx8qm_video_dual_mode(&imx_mhdp->mhdp); - -- imx8qm_pixel_link_valid(imx_mhdp->dual_mode); -- imx8qm_pixel_link_sync_enable(imx_mhdp->dual_mode); -+ imx8qm_pixel_link_valid(dual_mode); -+ imx8qm_pixel_link_sync_enable(dual_mode); - } - - void cdns_mhdp_pclk_rate_imx8qm(struct cdns_mhdp_device *mhdp) ---- a/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -@@ -172,7 +172,6 @@ static int cdns_mhdp_imx_bind(struct dev - if (ret < 0) - drm_encoder_cleanup(encoder); - -- imx_mhdp->dual_mode = false; - return ret; - } - -@@ -205,7 +204,7 @@ static struct platform_driver cdns_mhdp_ - .probe = cdns_mhdp_imx_probe, - .remove = cdns_mhdp_imx_remove, - .driver = { -- .name = "cdn-hdp-imx8qm", -+ .name = "cdns-mhdp-imx", - .of_match_table = cdns_mhdp_imx_dt_ids, - }, - }; ---- a/drivers/gpu/drm/imx/cdns-mhdp-imx.h -+++ b/drivers/gpu/drm/imx/cdns-mhdp-imx.h -@@ -16,15 +16,6 @@ - #include - - --#define HDP_DUAL_MODE_MIN_PCLK_RATE 300000 /* KHz */ --#define HDP_SINGLE_MODE_MAX_WIDTH 1920 -- --static inline bool video_is_dual_mode(const struct drm_display_mode *mode) --{ -- return (mode->clock > HDP_DUAL_MODE_MIN_PCLK_RATE || -- mode->hdisplay > HDP_SINGLE_MODE_MAX_WIDTH) ? true : false; --} -- - struct imx_mhdp_device; - - struct imx_hdp_clks { -@@ -62,17 +53,14 @@ struct imx_mhdp_device { - - int bus_type; - -- u32 dual_mode; -- - struct device *pd_mhdp_dev; - struct device *pd_pll0_dev; - struct device *pd_pll1_dev; - struct device_link *pd_mhdp_link; - struct device_link *pd_pll0_link; - struct device_link *pd_pll1_link; -- --// u32 phy_init; - }; -+ - void cdns_mhdp_plat_init_imx8qm(struct cdns_mhdp_device *mhdp); - void cdns_mhdp_plat_deinit_imx8qm(struct cdns_mhdp_device *mhdp); - void cdns_mhdp_pclk_rate_imx8qm(struct cdns_mhdp_device *mhdp); diff --git a/target/linux/layerscape/patches-5.4/805-display-0020-drm-bridge-cdns-cec-fix-LA-failed-set-issue.patch b/target/linux/layerscape/patches-5.4/805-display-0020-drm-bridge-cdns-cec-fix-LA-failed-set-issue.patch deleted file mode 100644 index ec36c571da..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0020-drm-bridge-cdns-cec-fix-LA-failed-set-issue.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 4e8d26c363c6e4b8b89d21feeb8c6dc57085b27d Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Fri, 27 Sep 2019 17:15:34 +0800 -Subject: [PATCH] drm: bridge: cdns cec: fix LA failed set issue - -improved function set_logical_addr() function. -Fix LA set failed issue in some case. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/Kconfig | 6 ++++ - drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c | 38 +++++++++++--------------- - 2 files changed, 22 insertions(+), 22 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/Kconfig -+++ b/drivers/gpu/drm/bridge/cadence/Kconfig -@@ -8,12 +8,18 @@ config DRM_CDNS_MHDP - - config DRM_CDNS_HDMI - tristate "Cadence HDMI DRM driver" -+ depends on DRM_CDNS_MHDP - - config DRM_CDNS_DP - tristate "Cadence DP DRM driver" -+ depends on DRM_CDNS_MHDP - - config DRM_CDNS_AUDIO - tristate "Cadence MHDP Audio driver" -+ depends on DRM_CDNS_MHDP - - config DRM_CDNS_HDMI_CEC - tristate "Cadence MHDP HDMI CEC driver" -+ depends on DRM_CDNS_HDMI -+ select CEC_CORE -+ select CEC_NOTIFIER ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-cec.c -@@ -20,8 +20,6 @@ - #define CEC_NAME "cdns-mhdp-cec" - - #define REG_ADDR_OFF 4 --#define MAX_LA_IDX 4 --#define MAX_LA_VAL 15 - - /* regsiter define */ - #define TX_MSG_HEADER 0x33800 -@@ -158,26 +156,22 @@ static u32 mhdp_cec_write_message(struct - return true; - } - --//static void cec_abort_tx_transfer(struct cdns_mhdp_cec *cec) --//{ --// cec_write(cec, TX_MSG_CMD, CEC_TX_ABORT); --// cec_write(cec, TX_MSG_CMD, CEC_TX_STOP); --//} -- - static int mhdp_cec_set_logical_addr(struct cdns_mhdp_cec *cec, u32 la) - { -- u8 i; - u8 la_reg; -+ u8 i; - -- if (la >= MAX_LA_VAL) { -- dev_err(cec->dev, "Error logical Addr\n"); -- return -EINVAL; -- } -- -- for (i = 0; i < MAX_LA_IDX; ++i) { -- la_reg = -- mhdp_cec_read(cec, LOGICAL_ADDRESS_LA0 + (i * REG_ADDR_OFF)); -+ if (la == CEC_LOG_ADDR_INVALID) -+ /* invalid all LA address */ -+ for (i = 0; i < CEC_MAX_LOG_ADDRS; ++i) { -+ mhdp_cec_write(cec, LOGICAL_ADDRESS_LA0 + (i * REG_ADDR_OFF), 0); -+ return 0; -+ } - -+ /* In fact cdns mhdp cec could support max 5 La address */ -+ for (i = 0; i < CEC_MAX_LOG_ADDRS; ++i) { -+ la_reg = mhdp_cec_read(cec, LOGICAL_ADDRESS_LA0 + (i * REG_ADDR_OFF)); -+ /* Check LA already used */ - if (la_reg & 0x10) - continue; - -@@ -194,7 +188,7 @@ static int mhdp_cec_set_logical_addr(str - - dev_warn(cec->dev, "All LA in use\n"); - -- return -EINVAL; -+ return -ENXIO; - } - - static int mhdp_cec_poll_worker(void *_cec) -@@ -263,7 +257,7 @@ static int mhdp_cec_poll_worker(void *_c - - static int mhdp_cec_adap_enable(struct cec_adapter *adap, bool enable) - { -- struct cdns_mhdp_cec *cec = adap->priv; -+ struct cdns_mhdp_cec *cec = cec_get_drvdata(adap); - - if (enable) { - mhdp_cec_write(cec, DB_L_TIMER, 0x10); -@@ -276,7 +270,7 @@ static int mhdp_cec_adap_enable(struct c - - static int mhdp_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) - { -- struct cdns_mhdp_cec *cec = adap->priv; -+ struct cdns_mhdp_cec *cec = cec_get_drvdata(adap); - - return mhdp_cec_set_logical_addr(cec, addr); - } -@@ -284,7 +278,7 @@ static int mhdp_cec_adap_log_addr(struct - static int mhdp_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, - u32 signal_free_time, struct cec_msg *msg) - { -- struct cdns_mhdp_cec *cec = adap->priv; -+ struct cdns_mhdp_cec *cec = cec_get_drvdata(adap); - - mhdp_cec_write_message(cec, msg); - -@@ -307,7 +301,7 @@ int cdns_mhdp_register_cec_driver(struct - CEC_NAME, - CEC_CAP_PHYS_ADDR | CEC_CAP_LOG_ADDRS | - CEC_CAP_TRANSMIT | CEC_CAP_PASSTHROUGH -- | CEC_CAP_RC, 1); -+ | CEC_CAP_RC, CEC_MAX_LOG_ADDRS); - ret = PTR_ERR_OR_ZERO(cec->adap); - if (ret) - return ret; diff --git a/target/linux/layerscape/patches-5.4/805-display-0021-DRM-mhdp-HDMI-skip-scdc-write-return-check.patch b/target/linux/layerscape/patches-5.4/805-display-0021-DRM-mhdp-HDMI-skip-scdc-write-return-check.patch deleted file mode 100644 index a41beea29e..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0021-DRM-mhdp-HDMI-skip-scdc-write-return-check.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 74c383e7da3e20c201e3b0c847a3d2f6fa0dbdc6 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Sun, 29 Sep 2019 14:48:28 +0800 -Subject: [PATCH] DRM: mhdp: HDMI: skip scdc write return check - -HDMI sink that only support HDMI1.4 is not support -SCDC read/write. Skip the SCDC write check and continue -HDMI initialize process. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -173,10 +173,8 @@ void cdns_hdmi_mode_set(struct cdns_mhdp - int ret; - - ret = hdmi_sink_config(mhdp); -- if (ret < 0) { -- DRM_ERROR("%s failed\n", __func__); -- return; -- } -+ if (ret < 0) -+ DRM_DEBUG("%s failed\n", __func__); - - ret = cdns_hdmi_ctrl_init(mhdp, mhdp->hdmi.hdmi_type, mhdp->hdmi.char_rate); - if (ret < 0) { diff --git a/target/linux/layerscape/patches-5.4/805-display-0022-drm-mhdp-add-mutex-lock-to-mhdp-register-access-func.patch b/target/linux/layerscape/patches-5.4/805-display-0022-drm-mhdp-add-mutex-lock-to-mhdp-register-access-func.patch deleted file mode 100644 index 0fc3d13758..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0022-drm-mhdp-add-mutex-lock-to-mhdp-register-access-func.patch +++ /dev/null @@ -1,83 +0,0 @@ -From ef8be75663178c0720d0944d9305f624776fc91c Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Thu, 17 Oct 2019 16:29:49 +0800 -Subject: [PATCH] drm: mhdp: add mutex lock to mhdp register access function - -Add muxtex lock to mhdp registers access functions -that could avoid race condition between cec thread and hdmi video. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 1 + - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 1 + - drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 8 ++++++++ - include/drm/bridge/cdns-mhdp-common.h | 1 + - 4 files changed, 11 insertions(+) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -410,6 +410,7 @@ static int __cdns_dp_probe(struct platfo - int ret; - - mutex_init(&mhdp->lock); -+ mutex_init(&mhdp->iolock); - - INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func); - ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -411,6 +411,7 @@ static int __cdns_hdmi_probe(struct plat - int ret; - - mutex_init(&mhdp->lock); -+ mutex_init(&mhdp->iolock); - - INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func); - ---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c -@@ -75,6 +75,8 @@ u32 cdns_mhdp_bus_read(struct cdns_mhdp_ - { - u32 val; - -+ mutex_lock(&mhdp->iolock); -+ - if (mhdp->bus_type == BUS_TYPE_LOW4K_SAPB) { - /* Remap address to low 4K SAPB bus */ - writel(offset >> 12, mhdp->regs_sec + 0xc); -@@ -88,12 +90,16 @@ u32 cdns_mhdp_bus_read(struct cdns_mhdp_ - else - val = readl(mhdp->regs_base + offset); - -+ mutex_unlock(&mhdp->iolock); -+ - return val; - } - EXPORT_SYMBOL(cdns_mhdp_bus_read); - - void cdns_mhdp_bus_write(u32 val, struct cdns_mhdp_device *mhdp, u32 offset) - { -+ mutex_lock(&mhdp->iolock); -+ - if (mhdp->bus_type == BUS_TYPE_LOW4K_SAPB) { - /* Remap address to low 4K SAPB bus */ - writel(offset >> 12, mhdp->regs_sec + 0xc); -@@ -106,6 +112,8 @@ void cdns_mhdp_bus_write(u32 val, struct - writel(val, mhdp->regs_sec + offset); - else - writel(val, mhdp->regs_base + offset); -+ -+ mutex_unlock(&mhdp->iolock); - } - EXPORT_SYMBOL(cdns_mhdp_bus_write); - ---- a/include/drm/bridge/cdns-mhdp-common.h -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -685,6 +685,7 @@ struct cdns_mhdp_device { - bool plugged; - bool is_hpd; - struct mutex lock; -+ struct mutex iolock; - - int irq[IRQ_NUM]; - diff --git a/target/linux/layerscape/patches-5.4/805-display-0023-drm-mhdp-reset-video-mode-after-hdmi-dp-cable-plugin.patch b/target/linux/layerscape/patches-5.4/805-display-0023-drm-mhdp-reset-video-mode-after-hdmi-dp-cable-plugin.patch deleted file mode 100644 index 9e90f7d73c..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0023-drm-mhdp-reset-video-mode-after-hdmi-dp-cable-plugin.patch +++ /dev/null @@ -1,236 +0,0 @@ -From 9ff3c9d6063c6464e243b85bbbbd03e2096a57c0 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Mon, 28 Oct 2019 17:07:06 +0800 -Subject: [PATCH] drm: mhdp: reset video mode after hdmi/dp cable plugin - -DP need setup link training, and HDMI need reset hdmi sink SCDC -status after cable reconnected. -Add video mode_set function when cable plugin. -Add 20ms/50ms delay for hdmi/dp to waite FW stable. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 20 ++++---- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 63 ++++++++++++------------- - 2 files changed, 43 insertions(+), 40 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -108,19 +108,19 @@ static void dp_pixel_clk_reset(struct cd - cdns_mhdp_reg_write(mhdp, SOURCE_HDTX_CAR, val); - } - --static void cdns_dp_mode_set(struct cdns_mhdp_device *mhdp, -- const struct drm_display_mode *mode) -+static void cdns_dp_mode_set(struct cdns_mhdp_device *mhdp) - { - u32 lane_mapping = mhdp->lane_mapping; - struct drm_dp_link *link = &mhdp->dp.link; - char linkid[6]; - int ret; - -- memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode)); -+ cdns_mhdp_plat_call(mhdp, pclk_rate); - -- dp_pixel_clk_reset(mhdp); -+ /* delay for DP FW stable after pixel clock relock */ -+ msleep(50); - -- cdns_mhdp_plat_call(mhdp, pclk_rate); -+ dp_pixel_clk_reset(mhdp); - - ret = drm_dp_downstream_id(&mhdp->dp.aux, linkid); - if (ret < 0) { -@@ -330,11 +330,10 @@ static void cdns_dp_bridge_mode_set(stru - video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); - - DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay, mode->vdisplay, mode->clock); -+ memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode)); - - mutex_lock(&mhdp->lock); -- -- cdns_dp_mode_set(mhdp, mode); -- -+ cdns_dp_mode_set(mhdp); - mutex_unlock(&mhdp->lock); - } - -@@ -367,6 +366,11 @@ static void hotplug_work_func(struct wor - drm_helper_hpd_irq_event(connector->dev); - - if (connector->status == connector_status_connected) { -+ /* reset video mode after cable plugin */ -+ mutex_lock(&mhdp->lock); -+ cdns_dp_mode_set(mhdp); -+ mutex_unlock(&mhdp->lock); -+ - DRM_INFO("HDMI/DP Cable Plug In\n"); - enable_irq(mhdp->irq[IRQ_OUT]); - } else if (connector->status == connector_status_disconnected) { ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -11,11 +11,11 @@ - */ - #include - #include --#include - #include - #include - #include - #include -+#include - #include - #include - #include -@@ -26,25 +26,30 @@ - #include - #include - --static int hdmi_sink_config(struct cdns_mhdp_device *mhdp) -+static void hdmi_sink_config(struct cdns_mhdp_device *mhdp) - { - struct drm_scdc *scdc = &mhdp->connector.base.display_info.hdmi.scdc; - u8 buff; -- int ret; -+ -+ /* check sink support SCDC or not */ -+ if (scdc->supported != true) { -+ DRM_INFO("Sink Not Support SCDC\n"); -+ return; -+ } - - if (mhdp->hdmi.char_rate > 340000) { - /* - * TMDS Character Rate above 340MHz should working in HDMI2.0 - * Enable scrambling and TMDS_Bit_Clock_Ratio - */ -- buff = 3; -+ buff = SCDC_TMDS_BIT_CLOCK_RATIO_BY_40 | SCDC_SCRAMBLING_ENABLE; - mhdp->hdmi.hdmi_type = MODE_HDMI_2_0; - } else if (scdc->scrambling.low_rates) { - /* - * Enable scrambling and HDMI2.0 when scrambling capability of sink - * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit - */ -- buff = 1; -+ buff = SCDC_SCRAMBLING_ENABLE; - mhdp->hdmi.hdmi_type = MODE_HDMI_2_0; - } else { - /* Default work in HDMI1.4 */ -@@ -53,8 +58,7 @@ static int hdmi_sink_config(struct cdns_ - } - - /* TMDS config */ -- ret = cdns_hdmi_scdc_write(mhdp, 0x20, buff); -- return ret; -+ cdns_hdmi_scdc_write(mhdp, 0x20, buff); - } - - static void hdmi_lanes_config(struct cdns_mhdp_device *mhdp) -@@ -142,7 +146,7 @@ static int hdmi_avi_info_set(struct cdns - return 0; - } - --static int hdmi_vendor_info_set(struct cdns_mhdp_device *mhdp, -+static void hdmi_vendor_info_set(struct cdns_mhdp_device *mhdp, - struct drm_display_mode *mode) - { - struct hdmi_vendor_infoframe frame; -@@ -152,19 +156,18 @@ static int hdmi_vendor_info_set(struct c - /* Initialise vendor frame from DRM mode */ - ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, &mhdp->connector.base, mode); - if (ret < 0) { -- DRM_WARN("Unable to init vendor infoframe: %d\n", ret); -- return -1; -+ DRM_INFO("No vendor infoframe\n"); -+ return; - } - - ret = hdmi_vendor_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1); - if (ret < 0) { - DRM_WARN("Unable to pack vendor infoframe: %d\n", ret); -- return -1; -+ return; - } - - buf[0] = 0; - cdns_mhdp_infoframe_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_VENDOR); -- return 0; - } - - void cdns_hdmi_mode_set(struct cdns_mhdp_device *mhdp) -@@ -172,9 +175,16 @@ void cdns_hdmi_mode_set(struct cdns_mhdp - struct drm_display_mode *mode = &mhdp->mode; - int ret; - -- ret = hdmi_sink_config(mhdp); -- if (ret < 0) -- DRM_DEBUG("%s failed\n", __func__); -+ hdmi_lanes_config(mhdp); -+ -+ cdns_mhdp_plat_call(mhdp, pclk_rate); -+ -+ /* delay for HDMI FW stable after pixel clock relock */ -+ msleep(20); -+ -+ cdns_mhdp_plat_call(mhdp, phy_set); -+ -+ hdmi_sink_config(mhdp); - - ret = cdns_hdmi_ctrl_init(mhdp, mhdp->hdmi.hdmi_type, mhdp->hdmi.char_rate); - if (ret < 0) { -@@ -195,18 +205,13 @@ void cdns_hdmi_mode_set(struct cdns_mhdp - } - - /* vendor info frame is enable only when HDMI1.4 4K mode */ -- ret = hdmi_vendor_info_set(mhdp, mode); -- if (ret < 0) -- DRM_WARN("Unable to configure Vendor infoframe\n"); -+ hdmi_vendor_info_set(mhdp, mode); - - ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info); - if (ret < 0) { - DRM_ERROR("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret); - return; - } -- -- /* wait HDMI PHY pixel clock stable */ -- msleep(50); - } - - static enum drm_connector_status -@@ -335,20 +340,11 @@ static void cdns_hdmi_bridge_mode_set(st - video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); - video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); - -- mutex_lock(&mhdp->lock); -- - DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay, mode->vdisplay, mode->clock); -- - memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode)); - -- hdmi_lanes_config(mhdp); -- -- cdns_mhdp_plat_call(mhdp, pclk_rate); -- -- cdns_mhdp_plat_call(mhdp, phy_set); -- -+ mutex_lock(&mhdp->lock); - cdns_hdmi_mode_set(mhdp); -- - mutex_unlock(&mhdp->lock); - } - -@@ -367,8 +363,11 @@ static void hotplug_work_func(struct wor - drm_helper_hpd_irq_event(connector->dev); - - if (connector->status == connector_status_connected) { -- /* Cable Connected */ - DRM_INFO("HDMI Cable Plug In\n"); -+ /* reset video mode after cable plugin */ -+ mutex_lock(&mhdp->lock); -+ cdns_hdmi_mode_set(mhdp); -+ mutex_unlock(&mhdp->lock); - enable_irq(mhdp->irq[IRQ_OUT]); - } else if (connector->status == connector_status_disconnected) { - /* Cable Disconnedted */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0024-drm-bridge-cadence-hdmi-remove-video-mode-limition.patch b/target/linux/layerscape/patches-5.4/805-display-0024-drm-bridge-cadence-hdmi-remove-video-mode-limition.patch deleted file mode 100644 index 1e06680187..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0024-drm-bridge-cadence-hdmi-remove-video-mode-limition.patch +++ /dev/null @@ -1,27 +0,0 @@ -From e3ebc237397387251828e52f4c21509d977e7797 Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Wed, 13 Nov 2019 16:47:47 +0800 -Subject: [PATCH] drm: bridge: cadence: hdmi: remove video mode limition - -combine mode is supported by imx8qm DPU. -imx8qm HDMI could support full feature. -Remove the 1080p60 limition. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -305,8 +305,8 @@ cdns_hdmi_bridge_mode_valid(struct drm_b - mode->flags & DRM_MODE_FLAG_INTERLACE) - return MODE_BAD; - -- /* MAX support pixel clock rate 148.5MHz */ -- if (mode->clock > 148500) -+ /* MAX support pixel clock rate 594MHz */ -+ if (mode->clock > 594000) - return MODE_CLOCK_HIGH; - - /* 4096x2160 is not supported */ diff --git a/target/linux/layerscape/patches-5.4/805-display-0025-drm-imx-hdp-add-hdr10-metadata-property.patch b/target/linux/layerscape/patches-5.4/805-display-0025-drm-imx-hdp-add-hdr10-metadata-property.patch deleted file mode 100644 index 6ce4263a3f..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0025-drm-imx-hdp-add-hdr10-metadata-property.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 7c5c4f891ce4746b52d95d9340c7cae063a48350 Mon Sep 17 00:00:00 2001 -From: Laurentiu Palcu -Date: Mon, 4 Nov 2019 13:18:48 +0200 -Subject: [PATCH] drm/imx/hdp: add hdr10 metadata property - -The HDR_OUTPUT_METADATA property is needed in order for userspace to instruct -the sink to switch to HDR10 mode. - -Signed-off-by: Laurentiu Palcu ---- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 72 +++++++++++++++++++++++++ - drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c | 4 ++ - include/drm/bridge/cdns-mhdp-common.h | 1 + - 3 files changed, 77 insertions(+) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -170,6 +170,35 @@ static void hdmi_vendor_info_set(struct - cdns_mhdp_infoframe_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_VENDOR); - } - -+static void hdmi_drm_info_set(struct cdns_mhdp_device *mhdp) -+{ -+ struct drm_connector_state *conn_state; -+ struct hdmi_drm_infoframe frame; -+ u8 buf[32]; -+ int ret; -+ -+ conn_state = mhdp->connector.base.state; -+ -+ if (!conn_state->hdr_output_metadata) -+ return; -+ -+ ret = drm_hdmi_infoframe_set_hdr_metadata(&frame, conn_state); -+ if (ret < 0) { -+ DRM_DEBUG_KMS("couldn't set HDR metadata in infoframe\n"); -+ return; -+ } -+ -+ ret = hdmi_drm_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1); -+ if (ret < 0) { -+ DRM_DEBUG_KMS("couldn't pack HDR infoframe\n"); -+ return; -+ } -+ -+ buf[0] = 0; -+ cdns_mhdp_infoframe_set(mhdp, 3, sizeof(buf), -+ buf, HDMI_INFOFRAME_TYPE_DRM); -+} -+ - void cdns_hdmi_mode_set(struct cdns_mhdp_device *mhdp) - { - struct drm_display_mode *mode = &mhdp->mode; -@@ -207,6 +236,8 @@ void cdns_hdmi_mode_set(struct cdns_mhdp - /* vendor info frame is enable only when HDMI1.4 4K mode */ - hdmi_vendor_info_set(mhdp, mode); - -+ hdmi_drm_info_set(mhdp); -+ - ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info); - if (ret < 0) { - DRM_ERROR("CDN_API_HDMITX_SetVic_blocking ret = %d\n", ret); -@@ -262,6 +293,40 @@ static int cdns_hdmi_connector_get_modes - return num_modes; - } - -+static bool blob_equal(const struct drm_property_blob *a, -+ const struct drm_property_blob *b) -+{ -+ if (a && b) -+ return a->length == b->length && -+ !memcmp(a->data, b->data, a->length); -+ -+ return !a == !b; -+} -+ -+static int cdns_hdmi_connector_atomic_check(struct drm_connector *connector, -+ struct drm_atomic_state *state) -+{ -+ struct drm_connector_state *new_con_state = -+ drm_atomic_get_new_connector_state(state, connector); -+ struct drm_connector_state *old_con_state = -+ drm_atomic_get_old_connector_state(state, connector); -+ struct drm_crtc *crtc = new_con_state->crtc; -+ struct drm_crtc_state *new_crtc_state; -+ -+ if (!blob_equal(new_con_state->hdr_output_metadata, -+ old_con_state->hdr_output_metadata)) { -+ new_crtc_state = drm_atomic_get_crtc_state(state, crtc); -+ if (IS_ERR(new_crtc_state)) -+ return PTR_ERR(new_crtc_state); -+ -+ new_crtc_state->mode_changed = -+ !new_con_state->hdr_output_metadata || -+ !old_con_state->hdr_output_metadata; -+ } -+ -+ return 0; -+} -+ - static const struct drm_connector_funcs cdns_hdmi_connector_funcs = { - .fill_modes = drm_helper_probe_single_connector_modes, - .detect = cdns_hdmi_connector_detect, -@@ -273,11 +338,13 @@ static const struct drm_connector_funcs - - static const struct drm_connector_helper_funcs cdns_hdmi_connector_helper_funcs = { - .get_modes = cdns_hdmi_connector_get_modes, -+ .atomic_check = cdns_hdmi_connector_atomic_check, - }; - - static int cdns_hdmi_bridge_attach(struct drm_bridge *bridge) - { - struct cdns_mhdp_device *mhdp = bridge->driver_private; -+ struct drm_mode_config *config = &bridge->dev->mode_config; - struct drm_encoder *encoder = bridge->encoder; - struct drm_connector *connector = &mhdp->connector.base; - -@@ -289,6 +356,11 @@ static int cdns_hdmi_bridge_attach(struc - drm_connector_init(bridge->dev, connector, &cdns_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA); - -+ if (!strncmp("imx8mq-hdmi", mhdp->plat_data->plat_name, 11)) -+ drm_object_attach_property(&connector->base, -+ config->hdr_output_metadata_property, -+ 0); -+ - drm_connector_attach_encoder(connector, encoder); - - return 0; ---- a/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -@@ -54,6 +54,7 @@ static const struct drm_encoder_funcs cd - }; - - static struct cdns_plat_data imx8mq_hdmi_drv_data = { -+ .plat_name = "imx8mq-hdmi", - .bind = cdns_hdmi_bind, - .unbind = cdns_hdmi_unbind, - .phy_set = cdns_hdmi_phy_set_imx8mq, -@@ -61,6 +62,7 @@ static struct cdns_plat_data imx8mq_hdmi - }; - - static struct cdns_plat_data imx8mq_dp_drv_data = { -+ .plat_name = "imx8mq-dp", - .bind = cdns_dp_bind, - .unbind = cdns_dp_unbind, - .phy_set = cdns_dp_phy_set_imx8mq, -@@ -68,6 +70,7 @@ static struct cdns_plat_data imx8mq_dp_d - }; - - static struct cdns_plat_data imx8qm_hdmi_drv_data = { -+ .plat_name = "imx8qm-hdmi", - .bind = cdns_hdmi_bind, - .unbind = cdns_hdmi_unbind, - .phy_set = cdns_hdmi_phy_set_imx8qm, -@@ -81,6 +84,7 @@ static struct cdns_plat_data imx8qm_hdmi - }; - - static struct cdns_plat_data imx8qm_dp_drv_data = { -+ .plat_name = "imx8qm-dp", - .bind = cdns_dp_bind, - .unbind = cdns_dp_unbind, - .phy_set = cdns_dp_phy_set_imx8qm, ---- a/include/drm/bridge/cdns-mhdp-common.h -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -652,6 +652,7 @@ struct cdns_plat_data { - int bus_type; - int video_format; - char is_dp; -+ char *plat_name; - }; - - struct cdns_mhdp_device { diff --git a/target/linux/layerscape/patches-5.4/805-display-0026-drm-imx-hdp-add-colorspace-property.patch b/target/linux/layerscape/patches-5.4/805-display-0026-drm-imx-hdp-add-colorspace-property.patch deleted file mode 100644 index 40d956ccc3..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0026-drm-imx-hdp-add-colorspace-property.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 55ebf12c54a53319d6a890eb499b68565242c3c4 Mon Sep 17 00:00:00 2001 -From: Laurentiu Palcu -Date: Thu, 7 Nov 2019 15:09:11 +0200 -Subject: [PATCH] drm/imx/hdp: add colorspace property - -iMX8MQ has the ability to adjust the DCSS output pipe gamut and nonlinearity -depending on the HDMI connector capability. Userspace can explicitly set this -property if it decides, based on EDID parsing, that the sink supports REC.2020 -and it wants to switch when it plays HDR10 content. - -Otherwise, the kernel will use the default settings specified in the HDMI -specifications. - -Signed-off-by: Laurentiu Palcu ---- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -356,11 +356,17 @@ static int cdns_hdmi_bridge_attach(struc - drm_connector_init(bridge->dev, connector, &cdns_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA); - -- if (!strncmp("imx8mq-hdmi", mhdp->plat_data->plat_name, 11)) -+ if (!strncmp("imx8mq-hdmi", mhdp->plat_data->plat_name, 11)) { - drm_object_attach_property(&connector->base, - config->hdr_output_metadata_property, - 0); - -+ if (!drm_mode_create_colorspace_property(connector)) -+ drm_object_attach_property(&connector->base, -+ connector->colorspace_property, -+ 0); -+ } -+ - drm_connector_attach_encoder(connector, encoder); - - return 0; diff --git a/target/linux/layerscape/patches-5.4/805-display-0027-drm-imx-hdp-force-a-mode-set-when-colorspace-is-chan.patch b/target/linux/layerscape/patches-5.4/805-display-0027-drm-imx-hdp-force-a-mode-set-when-colorspace-is-chan.patch deleted file mode 100644 index c63ae91683..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0027-drm-imx-hdp-force-a-mode-set-when-colorspace-is-chan.patch +++ /dev/null @@ -1,34 +0,0 @@ -From da02a33c186db04986166659caafb0c2da5bf7f0 Mon Sep 17 00:00:00 2001 -From: Laurentiu Palcu -Date: Fri, 15 Nov 2019 10:00:55 +0200 -Subject: [PATCH] drm/imx/hdp: force a mode set when colorspace is changed - -If the userspace changes the connector Colorspace property, we need to force a -modeset, so that the entire pipeline is properly configured. - -Signed-off-by: Laurentiu Palcu ---- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -314,14 +314,16 @@ static int cdns_hdmi_connector_atomic_ch - struct drm_crtc_state *new_crtc_state; - - if (!blob_equal(new_con_state->hdr_output_metadata, -- old_con_state->hdr_output_metadata)) { -+ old_con_state->hdr_output_metadata) || -+ new_con_state->colorspace != old_con_state->colorspace) { - new_crtc_state = drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(new_crtc_state)) - return PTR_ERR(new_crtc_state); - - new_crtc_state->mode_changed = - !new_con_state->hdr_output_metadata || -- !old_con_state->hdr_output_metadata; -+ !old_con_state->hdr_output_metadata || -+ new_con_state->colorspace != old_con_state->colorspace; - } - - return 0; diff --git a/target/linux/layerscape/patches-5.4/805-display-0028-drm-imx-hdp-handle-the-various-deep-color-settings.patch b/target/linux/layerscape/patches-5.4/805-display-0028-drm-imx-hdp-handle-the-various-deep-color-settings.patch deleted file mode 100644 index 14c95579ab..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0028-drm-imx-hdp-handle-the-various-deep-color-settings.patch +++ /dev/null @@ -1,187 +0,0 @@ -From 1a8c7e6db6898ea62820bdd4fc9ef70b04ea528a Mon Sep 17 00:00:00 2001 -From: Laurentiu Palcu -Date: Thu, 7 Nov 2019 15:23:41 +0200 -Subject: [PATCH] drm/imx/hdp: handle the various deep-color settings - -iMX8MQ has the ability to handle color depths up to 12bpc. This patch adds -support for higher color depths for various modes. - -Signed-off-by: Laurentiu Palcu ---- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 132 ++++++++++++++---------- - 1 file changed, 75 insertions(+), 57 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -67,58 +67,20 @@ static void hdmi_lanes_config(struct cdn - cdns_mhdp_reg_write(mhdp, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping); - } - --#define RGB_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\ -- BIT(HDMI_EXTENDED_COLORIMETRY_OPRGB)) --#define YCC_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\ -- BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM) |\ -- BIT(HDMI_EXTENDED_COLORIMETRY_OPYCC_601) |\ -- BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601) |\ -- BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709) |\ -- BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601)) - static int hdmi_avi_info_set(struct cdns_mhdp_device *mhdp, -- struct drm_display_mode *mode) -+ struct drm_display_mode *mode) - { - struct hdmi_avi_infoframe frame; --#if 0 -- struct drm_display_info *di = &mhdp->connector.base.display_info; -- enum hdmi_extended_colorimetry ext_col; -- u32 sink_col, allowed_col; --#endif - int format = mhdp->video_info.color_fmt; -+ struct drm_connector_state *conn_state = mhdp->connector.base.state; -+ struct drm_display_mode *adj_mode; -+ enum hdmi_quantization_range qr; - u8 buf[32]; - int ret; - - /* Initialise info frame from DRM mode */ -- drm_hdmi_avi_infoframe_from_display_mode(&frame, &mhdp->connector.base, mode); -- --#if 0 //TODO to DCSS -- /* Set up colorimetry */ -- allowed_col = format == PXL_RGB ? RGB_ALLOWED_COLORIMETRY : -- YCC_ALLOWED_COLORIMETRY; -- -- sink_col = di->hdmi.colorimetry & allowed_col; -- -- if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020)) -- ext_col = HDMI_EXTENDED_COLORIMETRY_BT2020; -- else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM)) -- ext_col = HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM; -- else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_OPRGB)) -- ext_col = HDMI_EXTENDED_COLORIMETRY_OPRGB; -- else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_709)) -- ext_col = HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; -- else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_OPYCC_601)) -- ext_col = HDMI_EXTENDED_COLORIMETRY_OPYCC_601; -- else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_S_YCC_601)) -- ext_col = HDMI_EXTENDED_COLORIMETRY_S_YCC_601; -- else if (sink_col & BIT(HDMI_EXTENDED_COLORIMETRY_XV_YCC_601)) -- ext_col = HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; -- else -- ext_col = 0; -- -- frame.colorimetry = sink_col ? HDMI_COLORIMETRY_EXTENDED : -- HDMI_COLORIMETRY_NONE; -- frame.extended_colorimetry = ext_col; --#endif -+ drm_hdmi_avi_infoframe_from_display_mode(&frame, &mhdp->connector.base, -+ mode); - - switch (format) { - case YCBCR_4_4_4: -@@ -135,6 +97,19 @@ static int hdmi_avi_info_set(struct cdns - break; - } - -+ drm_hdmi_avi_infoframe_colorspace(&frame, conn_state); -+ -+ adj_mode = &mhdp->bridge.base.encoder->crtc->state->adjusted_mode; -+ -+ qr = drm_default_rgb_quant_range(adj_mode); -+ -+ drm_hdmi_avi_infoframe_quant_range(&frame, &mhdp->connector.base, -+ adj_mode, qr); -+ -+ ret = hdmi_avi_infoframe_check(&frame); -+ if (WARN_ON(ret)) -+ return false; -+ - ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1); - if (ret < 0) { - DRM_ERROR("failed to pack AVI infoframe: %d\n", ret); -@@ -404,19 +379,6 @@ static void cdns_hdmi_bridge_mode_set(st - struct drm_display_info *display_info = &mhdp->connector.base.display_info; - struct video_info *video = &mhdp->video_info; - -- switch (display_info->bpc) { -- case 10: -- video->color_depth = 10; -- break; -- case 6: -- video->color_depth = 6; -- break; -- default: -- video->color_depth = 8; -- break; -- } -- -- video->color_fmt = PXL_RGB; - video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); - video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); - -@@ -428,10 +390,66 @@ static void cdns_hdmi_bridge_mode_set(st - mutex_unlock(&mhdp->lock); - } - -+bool cdns_hdmi_bridge_mode_fixup(struct drm_bridge *bridge, -+ const struct drm_display_mode *mode, -+ struct drm_display_mode *adjusted_mode) -+{ -+ struct cdns_mhdp_device *mhdp = bridge->driver_private; -+ struct drm_display_info *di = &mhdp->connector.base.display_info; -+ struct video_info *video = &mhdp->video_info; -+ int vic = drm_match_cea_mode(mode); -+ -+ video->color_depth = 8; -+ video->color_fmt = PXL_RGB; -+ -+ /* for all other platforms, other than imx8mq */ -+ if (strncmp("imx8mq-hdmi", mhdp->plat_data->plat_name, 11)) { -+ if (di->bpc == 10 || di->bpc == 6) -+ video->color_depth = di->bpc; -+ -+ return true; -+ } -+ -+ /* imx8mq */ -+ if (vic == 97 || vic == 96) { -+ if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_36) -+ video->color_depth = 12; -+ else if (di->hdmi.y420_dc_modes & DRM_EDID_YCBCR420_DC_30) -+ video->color_depth = 10; -+ -+ if (drm_mode_is_420_only(di, mode) || -+ (drm_mode_is_420_also(di, mode) && -+ video->color_depth > 8)) { -+ video->color_fmt = YCBCR_4_2_0; -+ -+ adjusted_mode->private_flags = 1; -+ return true; -+ } -+ -+ video->color_depth = 8; -+ return true; -+ } -+ -+ /* Any defined maximum tmds clock limit we must not exceed*/ -+ if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_36) && -+ (mode->clock * 3 / 2 <= di->max_tmds_clock)) -+ video->color_depth = 12; -+ else if ((di->edid_hdmi_dc_modes & DRM_EDID_HDMI_DC_30) && -+ (mode->clock * 5 / 4 <= di->max_tmds_clock)) -+ video->color_depth = 10; -+ -+ /* 10-bit color depth for the following modes is not supported */ -+ if ((vic == 95 || vic == 94 || vic == 93) && video->color_depth == 10) -+ video->color_depth = 8; -+ -+ return true; -+} -+ - static const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = { - .attach = cdns_hdmi_bridge_attach, - .mode_set = cdns_hdmi_bridge_mode_set, - .mode_valid = cdns_hdmi_bridge_mode_valid, -+ .mode_fixup = cdns_hdmi_bridge_mode_fixup, - }; - - static void hotplug_work_func(struct work_struct *work) diff --git a/target/linux/layerscape/patches-5.4/805-display-0029-drm-imx-mhdp-Adjustment-core-rate-of-DP-TX-CTRL-for-.patch b/target/linux/layerscape/patches-5.4/805-display-0029-drm-imx-mhdp-Adjustment-core-rate-of-DP-TX-CTRL-for-.patch deleted file mode 100644 index 443351fd52..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0029-drm-imx-mhdp-Adjustment-core-rate-of-DP-TX-CTRL-for-.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 4d5ce89b5a6faa347464221e4b674be46b951245 Mon Sep 17 00:00:00 2001 -From: Wen He -Date: Wed, 27 Nov 2019 18:24:11 +0800 -Subject: [PATCH] drm: imx: mhdp: Adjustment core rate of DP TX CTRL for - LS1028A - -This Display TX CTRL clock should be ACLK/4, update it to align with -the specification. - -Signed-off-by: Wen He -Reviewed-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 4 ++++ - drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c | 3 +++ - include/drm/bridge/cdns-mhdp-common.h | 1 + - 3 files changed, 8 insertions(+) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c -@@ -435,6 +435,7 @@ static int __cdns_dp_probe(struct platfo - } - - mhdp->is_hpd = true; -+ mhdp->is_ls1028a = false; - - mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in"); - if (mhdp->irq[IRQ_IN] < 0) { -@@ -450,6 +451,9 @@ static int __cdns_dp_probe(struct platfo - - cdns_dp_parse_dt(mhdp); - -+ if (of_device_is_compatible(dev->of_node, "cdn,ls1028a-dp")) -+ mhdp->is_ls1028a = true; -+ - cdns_mhdp_plat_call(mhdp, power_on); - - cdns_mhdp_plat_call(mhdp, firmware_init); ---- a/drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imx8qm.c -@@ -526,6 +526,9 @@ int cdns_mhdp_firmware_init_imx8qm(struc - - /* configure HDMI/DP core clock */ - rate = clk_get_rate(imx_mhdp->clks.clk_core); -+ if (mhdp->is_ls1028a) -+ rate = rate / 4; -+ - cdns_mhdp_set_fw_clk(&imx_mhdp->mhdp, rate); - - /* un-reset ucpu */ ---- a/include/drm/bridge/cdns-mhdp-common.h -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -685,6 +685,7 @@ struct cdns_mhdp_device { - bool power_up; - bool plugged; - bool is_hpd; -+ bool is_ls1028a; - struct mutex lock; - struct mutex iolock; - diff --git a/target/linux/layerscape/patches-5.4/805-display-0032-drm-hdmi-imx8-fix-wrong-hdmi-type-with-non-SCDC-HDMI.patch b/target/linux/layerscape/patches-5.4/805-display-0032-drm-hdmi-imx8-fix-wrong-hdmi-type-with-non-SCDC-HDMI.patch deleted file mode 100644 index 43b590da5e..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0032-drm-hdmi-imx8-fix-wrong-hdmi-type-with-non-SCDC-HDMI.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 94f34486d678f01378f539dee843a74eb476320e Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Fri, 29 Nov 2019 15:00:59 +0800 -Subject: [PATCH] drm: hdmi: imx8: fix wrong hdmi type with non-SCDC HDMI sinks - -hdmi type is uninitialized with non-SCDC HDMI sinks. -And hdmi ctrl will work in DVI mode that is not ecpected. -Set hdmi type to HDMI1.4 before SCDC support check to fix it. - -Signed-off-by: Sandor Yu ---- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -29,7 +29,10 @@ - static void hdmi_sink_config(struct cdns_mhdp_device *mhdp) - { - struct drm_scdc *scdc = &mhdp->connector.base.display_info.hdmi.scdc; -- u8 buff; -+ u8 buff = 0; -+ -+ /* Default work in HDMI1.4 */ -+ mhdp->hdmi.hdmi_type = MODE_HDMI_1_4; - - /* check sink support SCDC or not */ - if (scdc->supported != true) { -@@ -51,11 +54,7 @@ static void hdmi_sink_config(struct cdns - */ - buff = SCDC_SCRAMBLING_ENABLE; - mhdp->hdmi.hdmi_type = MODE_HDMI_2_0; -- } else { -- /* Default work in HDMI1.4 */ -- buff = 0; -- mhdp->hdmi.hdmi_type = MODE_HDMI_1_4; -- } -+ } - - /* TMDS config */ - cdns_hdmi_scdc_write(mhdp, 0x20, buff); diff --git a/target/linux/layerscape/patches-5.4/805-display-0033-LF-94-drm-hdmi-imx-Add-hdmi-phy-video-mode-valid-fun.patch b/target/linux/layerscape/patches-5.4/805-display-0033-LF-94-drm-hdmi-imx-Add-hdmi-phy-video-mode-valid-fun.patch deleted file mode 100644 index e3e555e486..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0033-LF-94-drm-hdmi-imx-Add-hdmi-phy-video-mode-valid-fun.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 6f23cfed09dc50e532a5d6a535bb992102d03cab Mon Sep 17 00:00:00 2001 -From: Sandor Yu -Date: Wed, 27 Nov 2019 19:08:42 +0800 -Subject: [PATCH] LF-94: drm: hdmi: imx: Add hdmi phy video mode valid function - -Add hdmi phy video mode valid function to filter the video modes. - -Signed-off-by: Sandor Yu -Reviewed-by: Robby Cai ---- - drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 8 +++++++- - drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c | 23 +++++++++++++++++++++++ - drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c | 2 ++ - drivers/gpu/drm/imx/cdn-mhdp-phy.h | 2 ++ - include/drm/bridge/cdns-mhdp-common.h | 2 ++ - 5 files changed, 36 insertions(+), 1 deletion(-) - ---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c -@@ -352,7 +352,9 @@ static enum drm_mode_status - cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge, - const struct drm_display_mode *mode) - { -+ struct cdns_mhdp_device *mhdp = bridge->driver_private; - enum drm_mode_status mode_status = MODE_OK; -+ int ret; - - /* We don't support double-clocked and Interlaced modes */ - if (mode->flags & DRM_MODE_FLAG_DBLCLK || -@@ -367,6 +369,11 @@ cdns_hdmi_bridge_mode_valid(struct drm_b - if (mode->hdisplay > 3840 || mode->vdisplay > 2160) - return MODE_BAD_HVALUE; - -+ mhdp->valid_mode = mode; -+ ret = cdns_mhdp_plat_call(mhdp, phy_video_valid); -+ if (ret == false) -+ return MODE_CLOCK_RANGE; -+ - return mode_status; - } - -@@ -375,7 +382,6 @@ static void cdns_hdmi_bridge_mode_set(st - const struct drm_display_mode *mode) - { - struct cdns_mhdp_device *mhdp = bridge->driver_private; -- struct drm_display_info *display_info = &mhdp->connector.base.display_info; - struct video_info *video = &mhdp->video_info; - - video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); ---- a/drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-hdmi-phy.c -@@ -683,6 +683,17 @@ static int hdmi_phy_power_up(struct cdns - return 0; - } - -+bool cdns_hdmi_phy_video_valid_imx8mq(struct cdns_mhdp_device *mhdp) -+{ -+ u32 rate = mhdp->valid_mode->clock; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(imx8mq_ctrl_table); i++) -+ if(rate == imx8mq_ctrl_table[i].pixel_clk_freq_min) -+ return true; -+ return false; -+} -+ - int cdns_hdmi_phy_set_imx8mq(struct cdns_mhdp_device *mhdp) - { - struct drm_display_mode *mode = &mhdp->mode; -@@ -711,6 +722,18 @@ int cdns_hdmi_phy_set_imx8mq(struct cdns - return true; - } - -+bool cdns_hdmi_phy_video_valid_imx8qm(struct cdns_mhdp_device *mhdp) -+{ -+ u32 rate = mhdp->valid_mode->clock; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(imx8qm_ctrl_table); i++) -+ if(rate >= imx8qm_ctrl_table[i].pixel_clk_freq_min && -+ rate <= imx8qm_ctrl_table[i].pixel_clk_freq_max) -+ return true; -+ return false; -+} -+ - int cdns_hdmi_phy_set_imx8qm(struct cdns_mhdp_device *mhdp) - { - struct drm_display_mode *mode = &mhdp->mode; ---- a/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -+++ b/drivers/gpu/drm/imx/cdn-mhdp-imxdrv.c -@@ -58,6 +58,7 @@ static struct cdns_plat_data imx8mq_hdmi - .bind = cdns_hdmi_bind, - .unbind = cdns_hdmi_unbind, - .phy_set = cdns_hdmi_phy_set_imx8mq, -+ .phy_video_valid = cdns_hdmi_phy_video_valid_imx8mq, - .bus_type = BUS_TYPE_NORMAL_APB, - }; - -@@ -74,6 +75,7 @@ static struct cdns_plat_data imx8qm_hdmi - .bind = cdns_hdmi_bind, - .unbind = cdns_hdmi_unbind, - .phy_set = cdns_hdmi_phy_set_imx8qm, -+ .phy_video_valid = cdns_hdmi_phy_video_valid_imx8qm, - .power_on = cdns_mhdp_power_on_imx8qm, - .firmware_init = cdns_mhdp_firmware_init_imx8qm, - .pclk_rate = cdns_mhdp_pclk_rate_imx8qm, ---- a/drivers/gpu/drm/imx/cdn-mhdp-phy.h -+++ b/drivers/gpu/drm/imx/cdn-mhdp-phy.h -@@ -148,6 +148,8 @@ - - int cdns_dp_phy_set_imx8mq(struct cdns_mhdp_device *hdp); - int cdns_dp_phy_set_imx8qm(struct cdns_mhdp_device *hdp); -+bool cdns_hdmi_phy_video_valid_imx8mq(struct cdns_mhdp_device *hdp); -+bool cdns_hdmi_phy_video_valid_imx8qm(struct cdns_mhdp_device *hdp); - int cdns_hdmi_phy_set_imx8mq(struct cdns_mhdp_device *hdp); - int cdns_hdmi_phy_set_imx8qm(struct cdns_mhdp_device *hdp); - #endif /* _CDNS_MHDP_PHY_H */ ---- a/include/drm/bridge/cdns-mhdp-common.h -+++ b/include/drm/bridge/cdns-mhdp-common.h -@@ -643,6 +643,7 @@ struct cdns_plat_data { - void (*plat_deinit)(struct cdns_mhdp_device *mhdp); - - int (*phy_set)(struct cdns_mhdp_device *mhdp); -+ bool (*phy_video_valid)(struct cdns_mhdp_device *mhdp); - int (*firmware_init)(struct cdns_mhdp_device *mhdp); - void (*pclk_rate)(struct cdns_mhdp_device *mhdp); - -@@ -675,6 +676,7 @@ struct cdns_mhdp_device { - - struct video_info video_info; - struct drm_display_mode mode; -+ const struct drm_display_mode *valid_mode; - unsigned int fw_version; - - struct drm_dp_mst_topology_mgr mst_mgr; diff --git a/target/linux/layerscape/patches-5.4/805-display-0034-media-bus-format-Add-RGB888_1X30_PADLO-support.patch b/target/linux/layerscape/patches-5.4/805-display-0034-media-bus-format-Add-RGB888_1X30_PADLO-support.patch deleted file mode 100644 index 1bdcaedb04..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0034-media-bus-format-Add-RGB888_1X30_PADLO-support.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 5df87202c0b8524a5eed58b86842219df42d6013 Mon Sep 17 00:00:00 2001 -From: Liu Ying -Date: Tue, 9 May 2017 17:16:27 +0800 -Subject: [PATCH] media: bus format: Add RGB888_1X30_PADLO support - -This patch adds 30bit RGB888 with low padding support. - -Signed-off-by: Liu Ying ---- - include/uapi/linux/media-bus-format.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/uapi/linux/media-bus-format.h -+++ b/include/uapi/linux/media-bus-format.h -@@ -63,6 +63,7 @@ - #define MEDIA_BUS_FMT_RGB101010_1X30 0x1018 - #define MEDIA_BUS_FMT_RGB121212_1X36 0x1019 - #define MEDIA_BUS_FMT_RGB161616_1X48 0x101a -+#define MEDIA_BUS_FMT_RGB888_1X30_PADLO 0x101b - - /* YUV (including grey) - next is 0x202d */ - #define MEDIA_BUS_FMT_Y8_1X8 0x2001 diff --git a/target/linux/layerscape/patches-5.4/805-display-0035-media-bus-format-Add-RGB666_1X30_PADLO-support.patch b/target/linux/layerscape/patches-5.4/805-display-0035-media-bus-format-Add-RGB666_1X30_PADLO-support.patch deleted file mode 100644 index 0e821ec230..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0035-media-bus-format-Add-RGB666_1X30_PADLO-support.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0792ee462890fa96cf84dce7ca05634316b64c49 Mon Sep 17 00:00:00 2001 -From: Liu Ying -Date: Tue, 9 May 2017 17:38:37 +0800 -Subject: [PATCH] media: bus format: Add RGB666_1X30_PADLO support - -This patch adds 30bit RGB666 with low padding support. - -Signed-off-by: Liu Ying ---- - include/uapi/linux/media-bus-format.h | 1 + - 1 file changed, 1 insertion(+) - ---- a/include/uapi/linux/media-bus-format.h -+++ b/include/uapi/linux/media-bus-format.h -@@ -64,6 +64,7 @@ - #define MEDIA_BUS_FMT_RGB121212_1X36 0x1019 - #define MEDIA_BUS_FMT_RGB161616_1X48 0x101a - #define MEDIA_BUS_FMT_RGB888_1X30_PADLO 0x101b -+#define MEDIA_BUS_FMT_RGB666_1X30_PADLO 0x101c - - /* YUV (including grey) - next is 0x202d */ - #define MEDIA_BUS_FMT_Y8_1X8 0x2001 diff --git a/target/linux/layerscape/patches-5.4/805-display-0036-media-bus-format-Add-RGB101010_1X7X5_SPWG-JEIDA-supp.patch b/target/linux/layerscape/patches-5.4/805-display-0036-media-bus-format-Add-RGB101010_1X7X5_SPWG-JEIDA-supp.patch deleted file mode 100644 index 2d07206b00..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0036-media-bus-format-Add-RGB101010_1X7X5_SPWG-JEIDA-supp.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 5cc582f5609f947d9692eef5489388c61cfbcc88 Mon Sep 17 00:00:00 2001 -From: Liu Ying -Date: Tue, 9 May 2017 17:39:41 +0800 -Subject: [PATCH] media: bus format: Add RGB101010_1X7X5_SPWG/JEIDA support - -This patch adds 30bit RGB101010 LVDS pixel formats support for -the SPWG and JEIDA LVDS mapping standards. Each pixel is transferred -on 5 lanes with 7bit respectively. - -Signed-off-by: Liu Ying ---- - include/uapi/linux/media-bus-format.h | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/include/uapi/linux/media-bus-format.h -+++ b/include/uapi/linux/media-bus-format.h -@@ -34,7 +34,7 @@ - - #define MEDIA_BUS_FMT_FIXED 0x0001 - --/* RGB - next is 0x101d */ -+/* RGB - next is 0x101f */ - #define MEDIA_BUS_FMT_RGB444_1X12 0x1016 - #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE 0x1001 - #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE 0x1002 -@@ -65,6 +65,8 @@ - #define MEDIA_BUS_FMT_RGB161616_1X48 0x101a - #define MEDIA_BUS_FMT_RGB888_1X30_PADLO 0x101b - #define MEDIA_BUS_FMT_RGB666_1X30_PADLO 0x101c -+#define MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG 0x101d -+#define MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA 0x101e - - /* YUV (including grey) - next is 0x202d */ - #define MEDIA_BUS_FMT_Y8_1X8 0x2001 diff --git a/target/linux/layerscape/patches-5.4/805-display-0037-MLK-15110-1-drm-fourcc-Add-Amphion-tiled-layout-form.patch b/target/linux/layerscape/patches-5.4/805-display-0037-MLK-15110-1-drm-fourcc-Add-Amphion-tiled-layout-form.patch deleted file mode 100644 index 5edec5400a..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0037-MLK-15110-1-drm-fourcc-Add-Amphion-tiled-layout-form.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 57a12a90496eb310d56ab45f105819d6103b472e Mon Sep 17 00:00:00 2001 -From: Liu Ying -Date: Thu, 3 Aug 2017 16:00:46 +0800 -Subject: [PATCH] MLK-15110-1 drm/fourcc: Add Amphion tiled layout format - modifier - -Amphion VPU has a tiled layout using 8x128 pixel vertical strips, -where each strip contains 1x16 groups of 8x8 pixels in a row-major layout. - -Signed-off-by: Song Bing -Signed-off-by: Liu Ying -[ Aisheng : AMPHION changed to 0xf1 ] -Signed-off-by: Dong Aisheng ---- - include/uapi/drm/drm_fourcc.h | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/include/uapi/drm/drm_fourcc.h -+++ b/include/uapi/drm/drm_fourcc.h -@@ -309,6 +309,7 @@ extern "C" { - #define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07 - #define DRM_FORMAT_MOD_VENDOR_ARM 0x08 - #define DRM_FORMAT_MOD_VENDOR_ALLWINNER 0x09 -+#define DRM_FORMAT_MOD_VENDOR_AMPHION 0xf0 - - /* add more to the end as needed */ - -@@ -756,6 +757,16 @@ extern "C" { - */ - #define DRM_FORMAT_MOD_ALLWINNER_TILED fourcc_mod_code(ALLWINNER, 1) - -+/* Amphion tiled layout */ -+ -+/* -+ * Amphion 8x128 tiling layout -+ * -+ * This is a tiled layout using 8x128 pixel vertical strips, where each strip -+ * contains 1x16 groups of 8x8 pixels in a row-major layout. -+ */ -+#define DRM_FORMAT_MOD_AMPHION_TILED fourcc_mod_code(AMPHION, 1) -+ - #if defined(__cplusplus) - } - #endif diff --git a/target/linux/layerscape/patches-5.4/805-display-0038-MLK-16290-drm-Add-drm_of_component_probe_with_match-.patch b/target/linux/layerscape/patches-5.4/805-display-0038-MLK-16290-drm-Add-drm_of_component_probe_with_match-.patch deleted file mode 100644 index 40977336a2..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0038-MLK-16290-drm-Add-drm_of_component_probe_with_match-.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 43265ca8cc62395e1750686daa8b7007b617e53b Mon Sep 17 00:00:00 2001 -From: Liu Ying -Date: Tue, 29 Aug 2017 16:58:58 +0800 -Subject: [PATCH] MLK-16290 drm: Add drm_of_component_probe_with_match() helper - -A component master may have both OF based and non-OF based components to be -bound with. This patch adds a helper drm_of_component_probe_with_match() -similar to drm_of_component_probe() so that the new helper may get an -additional provided match pointer(contains match entries for non-OF based -components) to support this case. - -Tested-by: Meng Mingming -Signed-off-by: Liu Ying -(cherry picked from commit c3cad7223488638ab56c20b2c29345487857bc5f) ---- - drivers/gpu/drm/drm_of.c | 31 ++++++++++++++++++++++++++++--- - include/drm/drm_of.h | 13 +++++++++++++ - 2 files changed, 41 insertions(+), 3 deletions(-) - ---- a/drivers/gpu/drm/drm_of.c -+++ b/drivers/gpu/drm/drm_of.c -@@ -100,8 +100,10 @@ void drm_of_component_match_add(struct d - EXPORT_SYMBOL_GPL(drm_of_component_match_add); - - /** -- * drm_of_component_probe - Generic probe function for a component based master -+ * drm_of_component_probe_with_match - Generic probe function with match -+ * entries for a component based master - * @dev: master device containing the OF node -+ * @match: component match pointer provided to store matches - * @compare_of: compare function used for matching components - * @m_ops: component master ops to be used - * -@@ -112,12 +114,12 @@ EXPORT_SYMBOL_GPL(drm_of_component_match - * - * Returns zero if successful, or one of the standard error codes if it fails. - */ --int drm_of_component_probe(struct device *dev, -+int drm_of_component_probe_with_match(struct device *dev, -+ struct component_match *match, - int (*compare_of)(struct device *, void *), - const struct component_master_ops *m_ops) - { - struct device_node *ep, *port, *remote; -- struct component_match *match = NULL; - int i; - - if (!dev->of_node) -@@ -183,6 +185,29 @@ int drm_of_component_probe(struct device - - return component_master_add_with_match(dev, m_ops, match); - } -+EXPORT_SYMBOL(drm_of_component_probe_with_match); -+ -+/** -+ * drm_of_component_probe - Generic probe function for a component based master -+ * @dev: master device containing the OF node -+ * @compare_of: compare function used for matching components -+ * @master_ops: component master ops to be used -+ * -+ * Parse the platform device OF node and bind all the components associated -+ * with the master. Interface ports are added before the encoders in order to -+ * satisfy their .bind requirements -+ * See Documentation/devicetree/bindings/graph.txt for the bindings. -+ * -+ * Returns zero if successful, or one of the standard error codes if it fails. -+ */ -+int drm_of_component_probe(struct device *dev, -+ int (*compare_of)(struct device *, void *), -+ const struct component_master_ops *m_ops) -+{ -+ struct component_match *match = NULL; -+ -+ return drm_of_component_probe_with_match(dev, match, compare_of, m_ops); -+} - EXPORT_SYMBOL(drm_of_component_probe); - - /* ---- a/include/drm/drm_of.h -+++ b/include/drm/drm_of.h -@@ -7,6 +7,7 @@ - #include - #endif - -+struct component_match; - struct component_master_ops; - struct component_match; - struct device; -@@ -25,6 +26,10 @@ void drm_of_component_match_add(struct d - struct component_match **matchptr, - int (*compare)(struct device *, void *), - struct device_node *node); -+extern int drm_of_component_probe_with_match(struct device *dev, -+ struct component_match *match, -+ int (*compare_of)(struct device *, void *), -+ const struct component_master_ops *m_ops); - int drm_of_component_probe(struct device *dev, - int (*compare_of)(struct device *, void *), - const struct component_master_ops *m_ops); -@@ -56,6 +61,14 @@ drm_of_component_match_add(struct device - { - } - -+static int drm_of_component_probe_with_match(struct device *dev, -+ struct component_match *match, -+ int (*compare_of)(struct device *, void *), -+ const struct component_master_ops *m_ops) -+{ -+ return -EINVAL; -+} -+ - static inline int - drm_of_component_probe(struct device *dev, - int (*compare_of)(struct device *, void *), diff --git a/target/linux/layerscape/patches-5.4/805-display-0039-MLK-17368-1-drm-add-fourcc-codes-for-Verisilicon-til.patch b/target/linux/layerscape/patches-5.4/805-display-0039-MLK-17368-1-drm-add-fourcc-codes-for-Verisilicon-til.patch deleted file mode 100644 index 842ca64645..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0039-MLK-17368-1-drm-add-fourcc-codes-for-Verisilicon-til.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 7d11e6c1669b9134b11a48cdf47e5b7ab1b2396c Mon Sep 17 00:00:00 2001 -From: Bing Song -Date: Fri, 5 Jan 2018 08:33:51 +0200 -Subject: [PATCH] MLK-17368-1 drm: add fourcc codes for Verisilicon tiled - formats - -These formats will be used by VPU and DCSS. - -Signed-off-by: Laurentiu Palcu -[ Aisheng : VENDOR_VSI changed to 0xf1 ] -Signed-off-by: Dong Aisheng ---- - include/uapi/drm/drm_fourcc.h | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - ---- a/include/uapi/drm/drm_fourcc.h -+++ b/include/uapi/drm/drm_fourcc.h -@@ -310,6 +310,7 @@ extern "C" { - #define DRM_FORMAT_MOD_VENDOR_ARM 0x08 - #define DRM_FORMAT_MOD_VENDOR_ALLWINNER 0x09 - #define DRM_FORMAT_MOD_VENDOR_AMPHION 0xf0 -+#define DRM_FORMAT_MOD_VENDOR_VSI 0xf1 - - /* add more to the end as needed */ - -@@ -767,6 +768,32 @@ extern "C" { - */ - #define DRM_FORMAT_MOD_AMPHION_TILED fourcc_mod_code(AMPHION, 1) - -+/* Verisilicon framebuffer modifiers */ -+ -+/* -+ * Verisilicon 8x4 tiling layout -+ * -+ * This is G1 VPU tiled layout using tiles of 8x4 pixels in a row-major -+ * layout. -+ */ -+#define DRM_FORMAT_MOD_VSI_G1_TILED fourcc_mod_code(VSI, 1) -+ -+/* -+ * Verisilicon 4x4 tiling layout -+ * -+ * This is G2 VPU tiled layout using tiles of 4x4 pixels in a row-major -+ * layout. -+ */ -+#define DRM_FORMAT_MOD_VSI_G2_TILED fourcc_mod_code(VSI, 2) -+ -+/* -+ * Verisilicon 4x4 tiling with compression layout -+ * -+ * This is G2 VPU tiled layout using tiles of 4x4 pixels in a row-major -+ * layout with compression. -+ */ -+#define DRM_FORMAT_MOD_VSI_G2_TILED_COMPRESSED fourcc_mod_code(VSI, 3) -+ - #if defined(__cplusplus) - } - #endif diff --git a/target/linux/layerscape/patches-5.4/805-display-0040-drm-fourcc-add-modifier-for-vivante-compressed-tiled.patch b/target/linux/layerscape/patches-5.4/805-display-0040-drm-fourcc-add-modifier-for-vivante-compressed-tiled.patch deleted file mode 100644 index b4eae5c86d..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0040-drm-fourcc-add-modifier-for-vivante-compressed-tiled.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 8894f4411bee347f7f392823805e77391dcaf305 Mon Sep 17 00:00:00 2001 -From: Fancy Fang -Date: Thu, 10 Oct 2019 17:06:15 +0300 -Subject: [PATCH] drm/fourcc: add modifier for vivante compressed tiled layout - -Add a new fb modifier for Vivante compressed and tiled -pixle layout which can be decompressed by DEC400D module -in DCSS. - -Signed-off-by: Fancy Fang -Signed-off-by: Laurentiu Palcu ---- - include/uapi/drm/drm_fourcc.h | 9 +++++++++ - 1 file changed, 9 insertions(+) - ---- a/include/uapi/drm/drm_fourcc.h -+++ b/include/uapi/drm/drm_fourcc.h -@@ -489,6 +489,15 @@ extern "C" { - */ - #define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4) - -+ /* -+ * Vivante 64x64 super-tiling with compression layout -+ * -+ * This is a tiled layout using 64x64 pixel super-tiles, where each super-tile -+ * contains 8x4 groups of 2x4 tiles of 4x4 pixels each, all in row-major layout -+ * with compression. -+ */ -+#define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED_FC fourcc_mod_code(VIVANTE, 5) -+ - /* NVIDIA frame buffer modifiers */ - - /* diff --git a/target/linux/layerscape/patches-5.4/805-display-0041-drm-fourcc-add-a-10bits-fully-packed-variant-of-NV12.patch b/target/linux/layerscape/patches-5.4/805-display-0041-drm-fourcc-add-a-10bits-fully-packed-variant-of-NV12.patch deleted file mode 100644 index 3bccbbd138..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0041-drm-fourcc-add-a-10bits-fully-packed-variant-of-NV12.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3ef66853a02133244bde79b165d8e5063def5ef4 Mon Sep 17 00:00:00 2001 -From: Randy Li -Date: Thu, 10 Jan 2019 03:57:10 +0800 -Subject: [PATCH] drm/fourcc: add a 10bits fully packed variant of NV12 - -This pixel format is a fully packed and 10bits variant of NV12. -A luma pixel would take 10bits in memory, without any -filled bits between pixels in a stride. - -Signed-off-by: Randy Li -Signed-off-by: Laurentiu Palcu ---- - drivers/gpu/drm/drm_fourcc.c | 3 +++ - include/uapi/drm/drm_fourcc.h | 8 ++++++++ - 2 files changed, 11 insertions(+) - ---- a/drivers/gpu/drm/drm_fourcc.c -+++ b/drivers/gpu/drm/drm_fourcc.c -@@ -261,6 +261,9 @@ const struct drm_format_info *__drm_form - { .format = DRM_FORMAT_P016, .depth = 0, .num_planes = 2, - .char_per_block = { 2, 4, 0 }, .block_w = { 1, 0, 0 }, .block_h = { 1, 0, 0 }, - .hsub = 2, .vsub = 2, .is_yuv = true}, -+ { .format = DRM_FORMAT_NV12_10LE40, .depth = 0, .num_planes = 2, -+ .char_per_block = { 5, 5, 0 }, .block_w = { 4, 2, 0 }, .block_h = { 1, 1, 0 }, -+ .hsub = 2, .vsub = 2, .is_yuv = true }, - { .format = DRM_FORMAT_P210, .depth = 0, - .num_planes = 2, .char_per_block = { 2, 4, 0 }, - .block_w = { 1, 0, 0 }, .block_h = { 1, 0, 0 }, .hsub = 2, ---- a/include/uapi/drm/drm_fourcc.h -+++ b/include/uapi/drm/drm_fourcc.h -@@ -236,6 +236,14 @@ extern "C" { - #define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */ - #define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */ - #define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */ -+/* -+ * A fully packed 2 plane YCbCr -+ * Y1 0-9, Y2 10-19, Y3 20-29, Y4 20-39 -+ * .... -+ * U1V1: 0-19, U2V2: 20-39 -+ */ -+#define DRM_FORMAT_NV12_10LE40 fourcc_code('R', 'K', '2', '0') /* 2x2 subsampled Cr:Cb plane */ -+ - - /* - * 2 plane YCbCr MSB aligned diff --git a/target/linux/layerscape/patches-5.4/805-display-0045-drm-imx-Add-DPU-KMS-support-part-2.patch b/target/linux/layerscape/patches-5.4/805-display-0045-drm-imx-Add-DPU-KMS-support-part-2.patch deleted file mode 100644 index ae32cf596f..0000000000 --- a/target/linux/layerscape/patches-5.4/805-display-0045-drm-imx-Add-DPU-KMS-support-part-2.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 2e4fbc789ef2743a6e425b9ca8bf40e40e236d22 Mon Sep 17 00:00:00 2001 -From: Dong Aisheng -Date: Mon, 5 Aug 2019 19:08:35 +0800 -Subject: [PATCH] drm/imx: Add DPU KMS support (part 2) - -This patch adds i.MX DPU KMS support. - -Signed-off-by: Liu Ying -Signed-off-by: Dong Aisheng ---- - drivers/gpu/drm/imx/imx-drm-core.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/drivers/gpu/drm/imx/imx-drm-core.c -+++ b/drivers/gpu/drm/imx/imx-drm-core.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include